mirror of
https://github.com/makeplane/plane
synced 2025-08-07 19:59:33 +00:00
Compare commits
5 Commits
fix-home-m
...
chore-web-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7f1b35e751 | ||
|
|
6f1230145e | ||
|
|
692e13039c | ||
|
|
bfd4aa1001 | ||
|
|
a20b5051d4 |
78
packages/constants/src/analytics.ts
Normal file
78
packages/constants/src/analytics.ts
Normal file
@@ -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",
|
||||
];
|
||||
10
packages/constants/src/emoji.ts
Normal file
10
packages/constants/src/emoji.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
export const ISSUE_REACTION_EMOJI_CODES = [
|
||||
"128077",
|
||||
"128078",
|
||||
"128516",
|
||||
"128165",
|
||||
"128533",
|
||||
"129505",
|
||||
"9992",
|
||||
"128064",
|
||||
];
|
||||
@@ -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";
|
||||
|
||||
5
packages/constants/src/error.ts
Normal file
5
packages/constants/src/error.ts
Normal file
@@ -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,
|
||||
}
|
||||
4
packages/constants/src/filter.ts
Normal file
4
packages/constants/src/filter.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export enum E_SORT_ORDER {
|
||||
ASC = "asc",
|
||||
DESC = "desc",
|
||||
}
|
||||
@@ -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,
|
||||
@@ -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";
|
||||
|
||||
@@ -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",
|
||||
},
|
||||
];
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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<React.SVGAttributes<SVGElement> & { 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<TProps> = observer((props: TProps) => {
|
||||
const { activeTab } = props;
|
||||
// router
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 = () => (
|
||||
<section className="w-full overflow-y-auto">
|
||||
|
||||
@@ -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[] = [];
|
||||
|
||||
@@ -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<any>;
|
||||
@@ -23,7 +24,7 @@ export const CustomTooltip: React.FC<Props> = ({ 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<Props> = ({ 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";
|
||||
}
|
||||
|
||||
|
||||
@@ -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";
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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";
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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<TIssueActivityCommentRoot> = observer((props) => {
|
||||
|
||||
@@ -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<TIssueActivity> = 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<TIssueActivity> = 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<TIssueActivity> = observer((props) => {
|
||||
disabled={disabled}
|
||||
/>
|
||||
)}
|
||||
<ActivitySortRoot sortOrder={sortOrder || TSORT_ORDER.ASC} toggleSort={toggleSortOrder} />
|
||||
<ActivitySortRoot sortOrder={sortOrder || E_SORT_ORDER.ASC} toggleSort={toggleSortOrder} />
|
||||
<ActivityFilterRoot
|
||||
selectedFilters={selectedFilters || defaultActivityFilters}
|
||||
toggleFilter={toggleFilter}
|
||||
@@ -196,7 +195,7 @@ export const IssueActivity: FC<TIssueActivity> = observer((props) => {
|
||||
activityOperations={activityOperations}
|
||||
showAccessSpecifier={!!project.anchor}
|
||||
disabled={disabled}
|
||||
sortOrder={sortOrder || TSORT_ORDER.ASC}
|
||||
sortOrder={sortOrder || E_SORT_ORDER.ASC}
|
||||
/>
|
||||
{!disabled && (
|
||||
<IssueCommentCreate
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
|
||||
import { FC, memo } from "react";
|
||||
import { ArrowUpWideNarrow, ArrowDownWideNarrow } from "lucide-react";
|
||||
// plane package imports
|
||||
import { E_SORT_ORDER } from "@plane/constants";
|
||||
import { getButtonStyling } from "@plane/ui";
|
||||
import { TSORT_ORDER } from "@/constants/common";
|
||||
// helpers
|
||||
import { cn } from "@/helpers/common.helper";
|
||||
import { cn } from "@plane/utils";
|
||||
|
||||
export type TActivitySortRoot = {
|
||||
sortOrder: TSORT_ORDER;
|
||||
sortOrder: E_SORT_ORDER;
|
||||
toggleSort: () => void;
|
||||
className?: string;
|
||||
iconClassName?: string;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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<Props & TGraph & Omit<BarSvgProps<any>, "height"
|
||||
<ResponsiveBar
|
||||
indexBy={indexBy}
|
||||
keys={keys}
|
||||
margin={{ ...DEFAULT_MARGIN, ...(margin ?? {}) }}
|
||||
padding={rest.padding ?? rest.data.length > 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,
|
||||
|
||||
@@ -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<TGraph & Omit<CalendarSvgProps, "height" |
|
||||
}) => (
|
||||
<div style={{ height, width }}>
|
||||
<ResponsiveCalendar
|
||||
margin={{ ...DEFAULT_MARGIN, ...(margin ?? {}) }}
|
||||
margin={{ ...CHART_DEFAULT_MARGIN, ...(margin ?? {}) }}
|
||||
colors={
|
||||
rest.colors ?? [
|
||||
"rgba(var(--color-primary-100), 0.2)",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// nivo
|
||||
import { ResponsiveLine, LineSvgProps } from "@nivo/line";
|
||||
// helpers
|
||||
import { CHARTS_THEME, DEFAULT_MARGIN } from "@/constants/graph";
|
||||
import { CHARTS_THEME, CHART_DEFAULT_MARGIN } from "@plane/constants";
|
||||
import { generateYAxisTickValues } from "@/helpers/graph.helper";
|
||||
// types
|
||||
import { TGraph } from "./types";
|
||||
@@ -21,7 +21,7 @@ export const LineGraph: React.FC<Props & TGraph & LineSvgProps> = ({
|
||||
}) => (
|
||||
<div style={{ height, width }}>
|
||||
<ResponsiveLine
|
||||
margin={{ ...DEFAULT_MARGIN, ...(margin ?? {}) }}
|
||||
margin={{ ...CHART_DEFAULT_MARGIN, ...(margin ?? {}) }}
|
||||
axisLeft={{
|
||||
tickSize: 0,
|
||||
tickPadding: 10,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// nivo
|
||||
import { PieSvgProps, ResponsivePie } from "@nivo/pie";
|
||||
// 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 PieGraph: React.FC<TGraph & Omit<PieSvgProps<any>, "height" | "widt
|
||||
}) => (
|
||||
<div style={{ height, width }}>
|
||||
<ResponsivePie
|
||||
margin={{ ...DEFAULT_MARGIN, ...(margin ?? {}) }}
|
||||
margin={{ ...CHART_DEFAULT_MARGIN, ...(margin ?? {}) }}
|
||||
theme={{ ...CHARTS_THEME, ...(theme ?? {}) }}
|
||||
animate
|
||||
{...rest}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// nivo
|
||||
import { ResponsiveScatterPlot, ScatterPlotSvgProps } from "@nivo/scatterplot";
|
||||
// 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 ScatterPlotGraph: React.FC<TGraph & Omit<ScatterPlotSvgProps<any>,
|
||||
}) => (
|
||||
<div style={{ height, width }}>
|
||||
<ResponsiveScatterPlot
|
||||
margin={{ ...DEFAULT_MARGIN, ...(margin ?? {}) }}
|
||||
margin={{ ...CHART_DEFAULT_MARGIN, ...(margin ?? {}) }}
|
||||
animate
|
||||
theme={{ ...CHARTS_THEME, ...(theme ?? {}) }}
|
||||
{...rest}
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
// 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 DATE_KEYS = ["completed_at", "target_date", "start_date", "created_at"];
|
||||
@@ -1,52 +0,0 @@
|
||||
"use client";
|
||||
|
||||
// types
|
||||
import { IProject } from "@plane/types";
|
||||
// icons
|
||||
import { ContrastIcon, DiceIcon, LayersIcon } from "@plane/ui";
|
||||
|
||||
export 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 PROJECT_ARCHIVES_BREADCRUMB_LIST: {
|
||||
[key: string]: {
|
||||
label: string;
|
||||
href: string;
|
||||
icon: React.FC<React.SVGAttributes<SVGElement> & { className?: string }>;
|
||||
};
|
||||
} = {
|
||||
issues: {
|
||||
label: "Issues",
|
||||
href: "/issues",
|
||||
icon: LayersIcon,
|
||||
},
|
||||
cycles: {
|
||||
label: "Cycles",
|
||||
href: "/cycles",
|
||||
icon: ContrastIcon,
|
||||
},
|
||||
modules: {
|
||||
label: "Modules",
|
||||
href: "/modules",
|
||||
icon: DiceIcon,
|
||||
},
|
||||
};
|
||||
@@ -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",
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
},
|
||||
];
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user