diff --git a/packages/constants/src/analytics.ts b/packages/constants/src/analytics.ts new file mode 100644 index 000000000..710ac412b --- /dev/null +++ b/packages/constants/src/analytics.ts @@ -0,0 +1,78 @@ +// types +import { TXAxisValues, TYAxisValues } from "@plane/types"; + +export const ANALYTICS_TABS = [ + { key: "scope_and_demand", title: "Scope and Demand" }, + { key: "custom", title: "Custom Analytics" }, +]; + +export const ANALYTICS_X_AXIS_VALUES: { value: TXAxisValues; label: string }[] = + [ + { + value: "state_id", + label: "State name", + }, + { + value: "state__group", + label: "State group", + }, + { + value: "priority", + label: "Priority", + }, + { + value: "labels__id", + label: "Label", + }, + { + value: "assignees__id", + label: "Assignee", + }, + { + value: "estimate_point__value", + label: "Estimate point", + }, + { + value: "issue_cycle__cycle_id", + label: "Cycle", + }, + { + value: "issue_module__module_id", + label: "Module", + }, + { + value: "completed_at", + label: "Completed date", + }, + { + value: "target_date", + label: "Due date", + }, + { + value: "start_date", + label: "Start date", + }, + { + value: "created_at", + label: "Created date", + }, + ]; + +export const ANALYTICS_Y_AXIS_VALUES: { value: TYAxisValues; label: string }[] = + [ + { + value: "issue_count", + label: "Issue Count", + }, + { + value: "estimate", + label: "Estimate", + }, + ]; + +export const ANALYTICS_DATE_KEYS = [ + "completed_at", + "target_date", + "start_date", + "created_at", +]; diff --git a/packages/constants/src/emoji.ts b/packages/constants/src/emoji.ts new file mode 100644 index 000000000..48be02b01 --- /dev/null +++ b/packages/constants/src/emoji.ts @@ -0,0 +1,10 @@ +export const ISSUE_REACTION_EMOJI_CODES = [ + "128077", + "128078", + "128516", + "128165", + "128533", + "129505", + "9992", + "128064", +]; diff --git a/packages/constants/src/endpoints.ts b/packages/constants/src/endpoints.ts index b17f7c1a0..cd1c08d7a 100644 --- a/packages/constants/src/endpoints.ts +++ b/packages/constants/src/endpoints.ts @@ -23,3 +23,7 @@ export const WEBSITE_URL = // support email export const SUPPORT_EMAIL = process.env.NEXT_PUBLIC_SUPPORT_EMAIL || "support@plane.so"; +// marketing links +export const MARKETING_PRICING_PAGE_LINK = "https://plane.so/pricing"; +export const MARKETING_CONTACT_US_PAGE_LINK = "https://plane.so/contact"; +export const MARKETING_PLANE_ONE_PAGE_LINK = "https://plane.so/one"; diff --git a/packages/constants/src/error.ts b/packages/constants/src/error.ts new file mode 100644 index 000000000..46277abf7 --- /dev/null +++ b/packages/constants/src/error.ts @@ -0,0 +1,5 @@ +export enum E_ARCHIVE_ERROR_CODES { + "INVALID_ARCHIVE_STATE_GROUP" = 4091, + "INVALID_ISSUE_START_DATE" = 4101, + "INVALID_ISSUE_TARGET_DATE" = 4102, +} diff --git a/packages/constants/src/filter.ts b/packages/constants/src/filter.ts new file mode 100644 index 000000000..20de817a2 --- /dev/null +++ b/packages/constants/src/filter.ts @@ -0,0 +1,4 @@ +export enum E_SORT_ORDER { + ASC = "asc", + DESC = "desc", +} diff --git a/web/core/constants/graph.ts b/packages/constants/src/graph.ts similarity index 83% rename from web/core/constants/graph.ts rename to packages/constants/src/graph.ts index 0376a7f9f..1ed7e4f9d 100644 --- a/web/core/constants/graph.ts +++ b/packages/constants/src/graph.ts @@ -1,7 +1,4 @@ -// nivo -import { Theme } from "@nivo/core"; - -export const CHARTS_THEME: Theme = { +export const CHARTS_THEME = { background: "transparent", text: { color: "rgb(var(--color-text-200))", @@ -29,7 +26,7 @@ export const CHARTS_THEME: Theme = { }, }; -export const DEFAULT_MARGIN = { +export const CHART_DEFAULT_MARGIN = { top: 50, right: 50, bottom: 50, diff --git a/packages/constants/src/index.ts b/packages/constants/src/index.ts index eeab193bb..09f038c33 100644 --- a/packages/constants/src/index.ts +++ b/packages/constants/src/index.ts @@ -1,8 +1,11 @@ export * from "./ai"; +export * from "./analytics"; export * from "./auth"; export * from "./endpoints"; export * from "./event"; export * from "./file"; +export * from "./filter"; +export * from "./graph"; export * from "./instance"; export * from "./issue"; export * from "./metadata"; diff --git a/packages/constants/src/state.ts b/packages/constants/src/state.ts index c51728bf9..790f78286 100644 --- a/packages/constants/src/state.ts +++ b/packages/constants/src/state.ts @@ -43,3 +43,26 @@ export const ARCHIVABLE_STATE_GROUPS = [ STATE_GROUPS.completed.key, STATE_GROUPS.cancelled.key, ]; + +export const PROGRESS_STATE_GROUPS_DETAILS = [ + { + key: "completed_issues", + title: "Completed", + color: "#16A34A", + }, + { + key: "started_issues", + title: "Started", + color: "#F59E0B", + }, + { + key: "unstarted_issues", + title: "Unstarted", + color: "#3A3A3A", + }, + { + key: "backlog_issues", + title: "Backlog", + color: "#A3A3A3", + }, +]; diff --git a/web/app/[workspaceSlug]/(projects)/analytics/page.tsx b/web/app/[workspaceSlug]/(projects)/analytics/page.tsx index b66c0d19e..3193efa03 100644 --- a/web/app/[workspaceSlug]/(projects)/analytics/page.tsx +++ b/web/app/[workspaceSlug]/(projects)/analytics/page.tsx @@ -4,13 +4,14 @@ import React, { Fragment } from "react"; import { observer } from "mobx-react"; import { useSearchParams } from "next/navigation"; import { Tab } from "@headlessui/react"; -// components +// plane package imports +import { ANALYTICS_TABS } from "@plane/constants"; import { Header, EHeaderVariant } from "@plane/ui"; +// components import { CustomAnalytics, ScopeAndDemand } from "@/components/analytics"; import { PageHead } from "@/components/core"; import { EmptyState } from "@/components/empty-state"; // constants -import { ANALYTICS_TABS } from "@/constants/analytics"; import { EmptyStateType } from "@/constants/empty-state"; // hooks import { useCommandPalette, useEventTracker, useProject, useWorkspace } from "@/hooks/store"; diff --git a/web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/archives/header.tsx b/web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/archives/header.tsx index 76167703a..639da9a96 100644 --- a/web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/archives/header.tsx +++ b/web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/archives/header.tsx @@ -5,11 +5,9 @@ import { observer } from "mobx-react"; import { useParams } from "next/navigation"; import { EIssuesStoreType } from "@plane/constants"; // ui -import { ArchiveIcon, Breadcrumbs, Tooltip, Header } from "@plane/ui"; +import { ArchiveIcon, Breadcrumbs, Tooltip, Header, ContrastIcon, DiceIcon, LayersIcon } from "@plane/ui"; // components import { BreadcrumbLink } from "@/components/common"; -// constants -import { PROJECT_ARCHIVES_BREADCRUMB_LIST } from "@/constants/archives"; // hooks import { useIssues, useProject } from "@/hooks/store"; import { useAppRouter } from "@/hooks/use-app-router"; @@ -21,6 +19,30 @@ type TProps = { activeTab: "issues" | "cycles" | "modules"; }; +const PROJECT_ARCHIVES_BREADCRUMB_LIST: { + [key: string]: { + label: string; + href: string; + icon: React.FC & { className?: string }>; + }; +} = { + issues: { + label: "Issues", + href: "/issues", + icon: LayersIcon, + }, + cycles: { + label: "Cycles", + href: "/cycles", + icon: ContrastIcon, + }, + modules: { + label: "Modules", + href: "/modules", + icon: DiceIcon, + }, +}; + export const ProjectArchivesHeader: FC = observer((props: TProps) => { const { activeTab } = props; // router diff --git a/web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/cycles/(list)/mobile-header.tsx b/web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/cycles/(list)/mobile-header.tsx index ecb1d5b90..eb65d928b 100644 --- a/web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/cycles/(list)/mobile-header.tsx +++ b/web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/cycles/(list)/mobile-header.tsx @@ -2,14 +2,35 @@ import { observer } from "mobx-react"; // ui -import { List } from "lucide-react"; +import { GanttChartSquare, LayoutGrid, List } from "lucide-react"; +// plane package imports +import { TCycleLayoutOptions } from "@plane/types"; import { CustomMenu } from "@plane/ui"; -// icon -// constants -import { CYCLE_VIEW_LAYOUTS } from "@/constants/cycle"; // hooks import { useCycleFilter, useProject } from "@/hooks/store"; +const CYCLE_VIEW_LAYOUTS: { + key: TCycleLayoutOptions; + icon: any; + title: string; +}[] = [ + { + key: "list", + icon: List, + title: "List layout", + }, + { + key: "board", + icon: LayoutGrid, + title: "Gallery layout", + }, + { + key: "gantt", + icon: GanttChartSquare, + title: "Timeline layout", + }, +]; + export const CyclesListMobileHeader = observer(() => { const { currentProjectDetails } = useProject(); // hooks diff --git a/web/ce/components/active-cycles/workspace-active-cycles-upgrade.tsx b/web/ce/components/active-cycles/workspace-active-cycles-upgrade.tsx index f214876e9..b832aa595 100644 --- a/web/ce/components/active-cycles/workspace-active-cycles-upgrade.tsx +++ b/web/ce/components/active-cycles/workspace-active-cycles-upgrade.tsx @@ -3,19 +3,61 @@ import React from "react"; import { observer } from "mobx-react"; import Image from "next/image"; +import { AlertOctagon, BarChart4, CircleDashed, Folder, Microscope, Search } from "lucide-react"; +// plane imports +import { MARKETING_PRICING_PAGE_LINK } from "@plane/constants"; import { useTranslation } from "@plane/i18n"; -// ui import { ContentWrapper, getButtonStyling } from "@plane/ui"; // components import { ProIcon } from "@/components/common"; -// constants -import { MARKETING_PRICING_PAGE_LINK } from "@/constants/common"; -import { WORKSPACE_ACTIVE_CYCLES_DETAILS } from "@/constants/cycle"; // helper import { cn } from "@/helpers/common.helper"; // hooks import { useUser } from "@/hooks/store"; +export const WORKSPACE_ACTIVE_CYCLES_DETAILS = [ + { + key: "10000_feet_view", + title: "10,000-feet view of all active cycles.", + description: + "Zoom out to see running cycles across all your projects at once instead of going from Cycle to Cycle in each project.", + icon: Folder, + }, + { + key: "get_snapshot_of_each_active_cycle", + title: "Get a snapshot of each active cycle.", + description: + "Track high-level metrics for all active cycles, see their state of progress, and get a sense of scope against deadlines.", + icon: CircleDashed, + }, + { + key: "compare_burndowns", + title: "Compare burndowns.", + description: "Monitor how each of your teams are performing with a peek into each cycle’s burndown report.", + icon: BarChart4, + }, + { + key: "quickly_see_make_or_break_issues", + title: "Quickly see make-or-break issues. ", + description: + "Preview high-priority issues for each cycle against due dates. See all of them per cycle in one click.", + icon: AlertOctagon, + }, + { + key: "zoom_into_cycles_that_need_attention", + title: "Zoom into cycles that need attention. ", + description: "Investigate the state of any cycle that doesn’t conform to expectations in one click.", + icon: Search, + }, + { + key: "stay_ahead_of_blockers", + title: "Stay ahead of blockers.", + description: + "Spot challenges from one project to another and see inter-cycle dependencies that aren’t obvious from any other view.", + icon: Microscope, + }, +]; + export const WorkspaceActiveCyclesUpgrade = observer(() => { const { t } = useTranslation(); // store hooks diff --git a/web/ce/components/workspace/billing/root.tsx b/web/ce/components/workspace/billing/root.tsx index 3a6d6c45c..4acba0af0 100644 --- a/web/ce/components/workspace/billing/root.tsx +++ b/web/ce/components/workspace/billing/root.tsx @@ -1,7 +1,5 @@ -// ui +import { MARKETING_PRICING_PAGE_LINK } from "@plane/constants"; import { Button } from "@plane/ui"; -// constants -import { MARKETING_PRICING_PAGE_LINK } from "@/constants/common"; export const BillingRoot = () => (
diff --git a/web/ce/store/issue/issue-details/activity.store.ts b/web/ce/store/issue/issue-details/activity.store.ts index cf180eebf..72c725010 100644 --- a/web/ce/store/issue/issue-details/activity.store.ts +++ b/web/ce/store/issue/issue-details/activity.store.ts @@ -7,7 +7,8 @@ import uniq from "lodash/uniq"; import update from "lodash/update"; import { action, makeObservable, observable, runInAction } from "mobx"; import { computedFn } from "mobx-utils"; -import { EIssueServiceType } from "@plane/constants"; +// plane package imports +import { EIssueServiceType, E_SORT_ORDER } from "@plane/constants"; import { TIssueActivityComment, TIssueActivity, @@ -16,7 +17,6 @@ import { TIssueServiceType, } from "@plane/types"; // plane web constants -import { TSORT_ORDER } from "@/constants/common"; import { EActivityFilterType } from "@/plane-web/constants/issues"; // services import { IssueActivityService } from "@/services/issue"; @@ -43,7 +43,7 @@ export interface IIssueActivityStore extends IIssueActivityStoreActions { // helper methods getActivitiesByIssueId: (issueId: string) => string[] | undefined; getActivityById: (activityId: string) => TIssueActivity | undefined; - getActivityCommentByIssueId: (issueId: string, sortOrder: TSORT_ORDER) => TIssueActivityComment[] | undefined; + getActivityCommentByIssueId: (issueId: string, sortOrder: E_SORT_ORDER) => TIssueActivityComment[] | undefined; } export class IssueActivityStore implements IIssueActivityStore { @@ -84,7 +84,7 @@ export class IssueActivityStore implements IIssueActivityStore { return this.activityMap[activityId] ?? undefined; }; - getActivityCommentByIssueId = computedFn((issueId: string, sortOrder: TSORT_ORDER) => { + getActivityCommentByIssueId = computedFn((issueId: string, sortOrder: E_SORT_ORDER) => { if (!issueId) return undefined; let activityComments: TIssueActivityComment[] = []; diff --git a/web/core/components/analytics/custom-analytics/graph/custom-tooltip.tsx b/web/core/components/analytics/custom-analytics/graph/custom-tooltip.tsx index 9101f1cf2..10b63df3d 100644 --- a/web/core/components/analytics/custom-analytics/graph/custom-tooltip.tsx +++ b/web/core/components/analytics/custom-analytics/graph/custom-tooltip.tsx @@ -1,9 +1,10 @@ // nivo import { BarTooltipProps } from "@nivo/bar"; +// plane imports +import { ANALYTICS_DATE_KEYS } from "@plane/constants"; import { IAnalyticsParams, IAnalyticsResponse } from "@plane/types"; -import { DATE_KEYS } from "@/constants/analytics"; +// helpers import { renderMonthAndYear } from "@/helpers/analytics.helper"; -// types type Props = { datum: BarTooltipProps; @@ -23,7 +24,7 @@ export const CustomTooltip: React.FC = ({ datum, analytics, params }) => }; if (params.segment) { - if (DATE_KEYS.includes(params.segment)) tooltipValue = renderMonthAndYear(datum.id); + if (ANALYTICS_DATE_KEYS.includes(params.segment)) tooltipValue = renderMonthAndYear(datum.id); else if (params.segment === "labels__id") { const label = analytics.extras.label_details.find((l) => l.labels__id === datum.id); tooltipValue = label && label.labels__name ? label.labels__name : "None"; @@ -41,7 +42,7 @@ export const CustomTooltip: React.FC = ({ datum, analytics, params }) => : "None"; } else tooltipValue = datum.id; } else { - if (DATE_KEYS.includes(params.x_axis)) tooltipValue = datum.indexValue; + if (ANALYTICS_DATE_KEYS.includes(params.x_axis)) tooltipValue = datum.indexValue; else tooltipValue = datum.id === "count" ? "Issue count" : "Estimate"; } diff --git a/web/core/components/analytics/custom-analytics/select-bar.tsx b/web/core/components/analytics/custom-analytics/select-bar.tsx index 8df1e71e1..27cfad236 100644 --- a/web/core/components/analytics/custom-analytics/select-bar.tsx +++ b/web/core/components/analytics/custom-analytics/select-bar.tsx @@ -1,12 +1,11 @@ import { observer } from "mobx-react"; import { Control, Controller, UseFormSetValue } from "react-hook-form"; -// types +// plane imports +import { ANALYTICS_X_AXIS_VALUES } from "@plane/constants"; import { IAnalyticsParams } from "@plane/types"; -// ui import { Row } from "@plane/ui"; // components import { SelectProject, SelectSegment, SelectXAxis, SelectYAxis } from "@/components/analytics"; -import { ANALYTICS_X_AXIS_VALUES } from "@/constants/analytics"; // hooks import { useProject } from "@/hooks/store"; diff --git a/web/core/components/analytics/custom-analytics/select/y-axis.tsx b/web/core/components/analytics/custom-analytics/select/y-axis.tsx index c97521c36..42c9145e8 100644 --- a/web/core/components/analytics/custom-analytics/select/y-axis.tsx +++ b/web/core/components/analytics/custom-analytics/select/y-axis.tsx @@ -2,10 +2,10 @@ import { observer } from "mobx-react"; import { useParams } from "next/navigation"; +// plane imports +import { ANALYTICS_Y_AXIS_VALUES } from "@plane/constants"; import { TYAxisValues } from "@plane/types"; import { CustomSelect } from "@plane/ui"; -// constants -import { ANALYTICS_Y_AXIS_VALUES } from "@/constants/analytics"; // hooks import { useProjectEstimates } from "@/hooks/store"; // plane web constants diff --git a/web/core/components/analytics/custom-analytics/table.tsx b/web/core/components/analytics/custom-analytics/table.tsx index 49039ed02..fd580d727 100644 --- a/web/core/components/analytics/custom-analytics/table.tsx +++ b/web/core/components/analytics/custom-analytics/table.tsx @@ -1,10 +1,11 @@ "use client"; import { BarDatum } from "@nivo/bar"; +// plane package imports +import { ANALYTICS_X_AXIS_VALUES, ANALYTICS_Y_AXIS_VALUES } from "@plane/constants"; import { IAnalyticsParams, IAnalyticsResponse, TIssuePriorities } from "@plane/types"; import { PriorityIcon, Tooltip } from "@plane/ui"; // helpers -import { ANALYTICS_X_AXIS_VALUES, ANALYTICS_Y_AXIS_VALUES } from "@/constants/analytics"; import { generateBarColor, generateDisplayName, renderChartDynamicLabel } from "@/helpers/analytics.helper"; import { cn } from "@/helpers/common.helper"; diff --git a/web/core/components/analytics/project-modal/main-content.tsx b/web/core/components/analytics/project-modal/main-content.tsx index e91282801..b572efdcb 100644 --- a/web/core/components/analytics/project-modal/main-content.tsx +++ b/web/core/components/analytics/project-modal/main-content.tsx @@ -1,12 +1,11 @@ import React, { Fragment } from "react"; import { observer } from "mobx-react"; import { Tab } from "@headlessui/react"; +// plane package imports +import { ANALYTICS_TABS } from "@plane/constants"; import { ICycle, IModule, IProject } from "@plane/types"; // components import { CustomAnalytics, ScopeAndDemand } from "@/components/analytics"; -// types -import { ANALYTICS_TABS } from "@/constants/analytics"; -// constants type Props = { fullScreen: boolean; diff --git a/web/core/components/archives/archive-tabs-list.tsx b/web/core/components/archives/archive-tabs-list.tsx index d1daeb77f..2e750219f 100644 --- a/web/core/components/archives/archive-tabs-list.tsx +++ b/web/core/components/archives/archive-tabs-list.tsx @@ -2,11 +2,33 @@ import { FC } from "react"; import { observer } from "mobx-react"; import Link from "next/link"; import { useParams, usePathname } from "next/navigation"; -// constants -import { ARCHIVES_TAB_LIST } from "@/constants/archives"; +// types +import { IProject } from "@plane/types"; // hooks import { useProject } from "@/hooks/store"; +const ARCHIVES_TAB_LIST: { + key: string; + label: string; + shouldRender: (projectDetails: IProject) => boolean; +}[] = [ + { + key: "issues", + label: "Issues", + shouldRender: () => true, + }, + { + key: "cycles", + label: "Cycles", + shouldRender: (projectDetails) => projectDetails.cycle_view, + }, + { + key: "modules", + label: "Modules", + shouldRender: (projectDetails) => projectDetails.module_view, + }, +]; + export const ArchiveTabsList: FC = observer(() => { // router const { workspaceSlug, projectId } = useParams(); diff --git a/web/core/components/cycles/active-cycle/progress.tsx b/web/core/components/cycles/active-cycle/progress.tsx index f75c51526..0dffff5c7 100644 --- a/web/core/components/cycles/active-cycle/progress.tsx +++ b/web/core/components/cycles/active-cycle/progress.tsx @@ -2,14 +2,13 @@ import { FC } from "react"; import { observer } from "mobx-react"; -// types +// plane package imports +import { PROGRESS_STATE_GROUPS_DETAILS } from "@plane/constants"; import { ICycle, IIssueFilterOptions } from "@plane/types"; -// ui import { LinearProgressIndicator, Loader } from "@plane/ui"; // components import { EmptyState } from "@/components/empty-state"; // constants -import { PROGRESS_STATE_GROUPS_DETAILS } from "@/constants/common"; import { EmptyStateType } from "@/constants/empty-state"; // hooks import { useProjectState } from "@/hooks/store"; diff --git a/web/core/components/issues/bulk-operations/upgrade-banner.tsx b/web/core/components/issues/bulk-operations/upgrade-banner.tsx index f6657c29e..7a1fa84f9 100644 --- a/web/core/components/issues/bulk-operations/upgrade-banner.tsx +++ b/web/core/components/issues/bulk-operations/upgrade-banner.tsx @@ -1,10 +1,7 @@ "use client"; -// ui +import { MARKETING_PLANE_ONE_PAGE_LINK } from "@plane/constants"; import { getButtonStyling } from "@plane/ui"; -// constants -import { MARKETING_PLANE_ONE_PAGE_LINK } from "@/constants/common"; -// helpers import { cn } from "@/helpers/common.helper"; type Props = { diff --git a/web/core/components/issues/issue-detail/issue-activity/activity-comment-root.tsx b/web/core/components/issues/issue-detail/issue-activity/activity-comment-root.tsx index 4ad46e92b..c2b813102 100644 --- a/web/core/components/issues/issue-detail/issue-activity/activity-comment-root.tsx +++ b/web/core/components/issues/issue-detail/issue-activity/activity-comment-root.tsx @@ -1,7 +1,7 @@ import { FC } from "react"; import { observer } from "mobx-react"; // constants -import { TSORT_ORDER } from "@/constants/common"; +import { E_SORT_ORDER } from "@plane/constants"; // hooks import { useIssueDetail } from "@/hooks/store"; // plane web components @@ -23,7 +23,7 @@ type TIssueActivityCommentRoot = { activityOperations: TActivityOperations; showAccessSpecifier?: boolean; disabled?: boolean; - sortOrder: TSORT_ORDER; + sortOrder: E_SORT_ORDER; }; export const IssueActivityCommentRoot: FC = observer((props) => { diff --git a/web/core/components/issues/issue-detail/issue-activity/root.tsx b/web/core/components/issues/issue-detail/issue-activity/root.tsx index 102fc3c16..90bc93f1c 100644 --- a/web/core/components/issues/issue-detail/issue-activity/root.tsx +++ b/web/core/components/issues/issue-detail/issue-activity/root.tsx @@ -2,17 +2,16 @@ import { FC, useMemo } from "react"; import { observer } from "mobx-react"; +// plane package imports +import { E_SORT_ORDER } from "@plane/constants"; import { useLocalStorage } from "@plane/hooks"; -// types import { TFileSignedURLResponse, TIssueComment } from "@plane/types"; import { EFileAssetType } from "@plane/types/src/enums"; -// ui import { TOAST_TYPE, setToast } from "@plane/ui"; // components import { IssueCommentCreate } from "@/components/issues"; import { ActivitySortRoot, IssueActivityCommentRoot } from "@/components/issues/issue-detail"; // constants -import { TSORT_ORDER } from "@/constants/common"; // hooks import { useIssueDetail, useProject, useUser, useUserPermissions } from "@/hooks/store"; // plane web components @@ -46,7 +45,7 @@ export const IssueActivity: FC = observer((props) => { "issue_activity_filters", defaultActivityFilters ); - const { setValue: setSortOrder, storedValue: sortOrder } = useLocalStorage("activity_sort_order", TSORT_ORDER.ASC); + const { setValue: setSortOrder, storedValue: sortOrder } = useLocalStorage("activity_sort_order", E_SORT_ORDER.ASC); const { issue: { getIssueById }, createComment, @@ -78,7 +77,7 @@ export const IssueActivity: FC = observer((props) => { }; const toggleSortOrder = () => { - setSortOrder(sortOrder === TSORT_ORDER.ASC ? TSORT_ORDER.DESC : TSORT_ORDER.ASC); + setSortOrder(sortOrder === E_SORT_ORDER.ASC ? E_SORT_ORDER.DESC : E_SORT_ORDER.ASC); }; const activityOperations: TActivityOperations = useMemo( @@ -174,7 +173,7 @@ export const IssueActivity: FC = observer((props) => { disabled={disabled} /> )} - + = observer((props) => { activityOperations={activityOperations} showAccessSpecifier={!!project.anchor} disabled={disabled} - sortOrder={sortOrder || TSORT_ORDER.ASC} + sortOrder={sortOrder || E_SORT_ORDER.ASC} /> {!disabled && ( void; className?: string; iconClassName?: string; diff --git a/web/core/components/modules/module-card-item.tsx b/web/core/components/modules/module-card-item.tsx index ac556d4a4..10086cfe2 100644 --- a/web/core/components/modules/module-card-item.tsx +++ b/web/core/components/modules/module-card-item.tsx @@ -5,7 +5,8 @@ import { observer } from "mobx-react"; import Link from "next/link"; import { useParams, usePathname, useSearchParams } from "next/navigation"; import { Info, SquareUser } from "lucide-react"; -// ui +// plane package imports +import { PROGRESS_STATE_GROUPS_DETAILS } from "@plane/constants"; import { IModule } from "@plane/types"; import { Card, @@ -23,7 +24,6 @@ import { ButtonAvatars } from "@/components/dropdowns/member/avatar"; import { ModuleQuickActions } from "@/components/modules"; import { ModuleStatusDropdown } from "@/components/modules/module-status-dropdown"; // constants -import { PROGRESS_STATE_GROUPS_DETAILS } from "@/constants/common"; import { MODULE_FAVORITED, MODULE_UNFAVORITED } from "@/constants/event-tracker"; import { MODULE_STATUS } from "@/constants/module"; // helpers diff --git a/web/core/components/ui/graphs/bar-graph.tsx b/web/core/components/ui/graphs/bar-graph.tsx index 5aac757a0..1a724322e 100644 --- a/web/core/components/ui/graphs/bar-graph.tsx +++ b/web/core/components/ui/graphs/bar-graph.tsx @@ -1,7 +1,7 @@ // nivo import { ResponsiveBar, BarSvgProps } from "@nivo/bar"; +import { CHARTS_THEME, CHART_DEFAULT_MARGIN } from "@plane/constants"; // helpers -import { CHARTS_THEME, DEFAULT_MARGIN } from "@/constants/graph"; import { generateYAxisTickValues } from "@/helpers/graph.helper"; // types import { TGraph } from "./types"; @@ -27,8 +27,8 @@ export const BarGraph: React.FC, "height" 7 ? 0.8 : 0.9} + margin={{ ...CHART_DEFAULT_MARGIN, ...(margin ?? {}) }} + padding={(rest.padding ?? rest.data.length > 7) ? 0.8 : 0.9} axisLeft={{ tickSize: 0, tickPadding: 10, diff --git a/web/core/components/ui/graphs/calendar-graph.tsx b/web/core/components/ui/graphs/calendar-graph.tsx index d6726a249..5a63dd640 100644 --- a/web/core/components/ui/graphs/calendar-graph.tsx +++ b/web/core/components/ui/graphs/calendar-graph.tsx @@ -1,7 +1,7 @@ // nivo import { ResponsiveCalendar, CalendarSvgProps } from "@nivo/calendar"; // types -import { CHARTS_THEME, DEFAULT_MARGIN } from "@/constants/graph"; +import { CHARTS_THEME, CHART_DEFAULT_MARGIN } from "@plane/constants"; import { TGraph } from "./types"; // constants @@ -14,7 +14,7 @@ export const CalendarGraph: React.FC (
= ({ }) => (
, "height" | "widt }) => (
, }) => (
boolean; -}[] = [ - { - key: "issues", - label: "Issues", - shouldRender: () => true, - }, - { - key: "cycles", - label: "Cycles", - shouldRender: (projectDetails) => projectDetails.cycle_view, - }, - { - key: "modules", - label: "Modules", - shouldRender: (projectDetails) => projectDetails.module_view, - }, -]; - -export const PROJECT_ARCHIVES_BREADCRUMB_LIST: { - [key: string]: { - label: string; - href: string; - icon: React.FC & { className?: string }>; - }; -} = { - issues: { - label: "Issues", - href: "/issues", - icon: LayersIcon, - }, - cycles: { - label: "Cycles", - href: "/cycles", - icon: ContrastIcon, - }, - modules: { - label: "Modules", - href: "/modules", - icon: DiceIcon, - }, -}; diff --git a/web/core/constants/common.ts b/web/core/constants/common.ts index 8358d0e64..37c270407 100644 --- a/web/core/constants/common.ts +++ b/web/core/constants/common.ts @@ -1,35 +1 @@ export const MAX_STATIC_FILE_SIZE = 5 * 1024 * 1024; // 5MB - -export const MARKETING_PRICING_PAGE_LINK = "https://plane.so/pricing"; - -export const MARKETING_CONTACT_US_PAGE_LINK = "https://plane.so/contact"; - -export const MARKETING_PLANE_ONE_PAGE_LINK = "https://plane.so/one"; - -export const PROGRESS_STATE_GROUPS_DETAILS = [ - { - key: "completed_issues", - title: "Completed", - color: "#16A34A", - }, - { - key: "started_issues", - title: "Started", - color: "#F59E0B", - }, - { - key: "unstarted_issues", - title: "Unstarted", - color: "#3A3A3A", - }, - { - key: "backlog_issues", - title: "Backlog", - color: "#A3A3A3", - }, -]; - -export enum TSORT_ORDER { - ASC = "asc", - DESC = "desc", -} diff --git a/web/core/constants/cycle.ts b/web/core/constants/cycle.ts index cbaafc3b6..025e26c9b 100644 --- a/web/core/constants/cycle.ts +++ b/web/core/constants/cycle.ts @@ -1,15 +1,3 @@ -import { - GanttChartSquare, - LayoutGrid, - List, - AlertOctagon, - BarChart4, - CircleDashed, - Folder, - Microscope, - Search, -} from "lucide-react"; - // types import { TCycleLayoutOptions, TCycleTabOptions } from "@plane/types"; @@ -27,28 +15,6 @@ export const CYCLE_TABS_LIST: { }, ]; -export const CYCLE_VIEW_LAYOUTS: { - key: TCycleLayoutOptions; - icon: any; - title: string; -}[] = [ - { - key: "list", - icon: List, - title: "List layout", - }, - { - key: "board", - icon: LayoutGrid, - title: "Gallery layout", - }, - { - key: "gantt", - icon: GanttChartSquare, - title: "Timeline layout", - }, -]; - export const CYCLE_STATUS: { label: string; value: "current" | "upcoming" | "completed" | "draft"; @@ -90,46 +56,3 @@ export const CYCLE_STATUS: { bgColor: "bg-custom-background-90", }, ]; - -export const WORKSPACE_ACTIVE_CYCLES_DETAILS = [ - { - key: "10000_feet_view", - title: "10,000-feet view of all active cycles.", - description: - "Zoom out to see running cycles across all your projects at once instead of going from Cycle to Cycle in each project.", - icon: Folder, - }, - { - key: "get_snapshot_of_each_active_cycle", - title: "Get a snapshot of each active cycle.", - description: - "Track high-level metrics for all active cycles, see their state of progress, and get a sense of scope against deadlines.", - icon: CircleDashed, - }, - { - key: "compare_burndowns", - title: "Compare burndowns.", - description: "Monitor how each of your teams are performing with a peek into each cycle’s burndown report.", - icon: BarChart4, - }, - { - key: "quickly_see_make_or_break_issues", - title: "Quickly see make-or-break issues. ", - description: - "Preview high-priority issues for each cycle against due dates. See all of them per cycle in one click.", - icon: AlertOctagon, - }, - { - key: "zoom_into_cycles_that_need_attention", - title: "Zoom into cycles that need attention. ", - description: "Investigate the state of any cycle that doesn’t conform to expectations in one click.", - icon: Search, - }, - { - key: "stay_ahead_of_blockers", - title: "Stay ahead of blockers.", - description: - "Spot challenges from one project to another and see inter-cycle dependencies that aren’t obvious from any other view.", - icon: Microscope, - }, -]; diff --git a/web/helpers/analytics.helper.ts b/web/helpers/analytics.helper.ts index 5576dadad..c8c2b91b4 100644 --- a/web/helpers/analytics.helper.ts +++ b/web/helpers/analytics.helper.ts @@ -1,13 +1,13 @@ // nivo import { BarDatum } from "@nivo/bar"; +// plane imports +import { ANALYTICS_DATE_KEYS } from "@plane/constants"; import { IAnalyticsData, IAnalyticsParams, IAnalyticsResponse, TStateGroups } from "@plane/types"; -// helpers -import { DATE_KEYS } from "@/constants/analytics"; +// constants import { MONTHS_LIST } from "@/constants/calendar"; import { STATE_GROUPS } from "@/constants/state"; +// helpers import { addSpaceIfCamelCase, capitalizeFirstLetter, generateRandomColor } from "@/helpers/string.helper"; -// types -// constants export const convertResponseToBarGraphData = ( response: IAnalyticsData | undefined, @@ -33,7 +33,7 @@ export const convertResponseToBarGraphData = ( }); data.push({ - name: DATE_KEYS.includes(params.x_axis) + name: ANALYTICS_DATE_KEYS.includes(params.x_axis) ? renderMonthAndYear(key) : params.x_axis === "priority" || params.x_axis === "state__group" ? capitalizeFirstLetter(key) @@ -46,7 +46,7 @@ export const convertResponseToBarGraphData = ( const item = response[key][0]; data.push({ - name: DATE_KEYS.includes(params.x_axis) + name: ANALYTICS_DATE_KEYS.includes(params.x_axis) ? renderMonthAndYear(item.dimension) : params.x_axis === "priority" || params.x_axis === "state__group" ? capitalizeFirstLetter(item.dimension ?? "None") @@ -126,7 +126,7 @@ export const generateDisplayName = ( if (params[type] === "state_id") displayName = analytics?.extras.state_details.find((s) => s.state_id === value)?.state__name ?? "None"; - if (DATE_KEYS.includes(params.segment ?? "")) displayName = renderMonthAndYear(value); + if (ANALYTICS_DATE_KEYS.includes(params.segment ?? "")) displayName = renderMonthAndYear(value); return displayName; };