diff --git a/web/components/cycles/active-cycle/cycle-stats.tsx b/web/components/cycles/active-cycle/cycle-stats.tsx index e27c99500..fd4bc9318 100644 --- a/web/components/cycles/active-cycle/cycle-stats.tsx +++ b/web/components/cycles/active-cycle/cycle-stats.tsx @@ -11,7 +11,9 @@ import { Tooltip, Loader, PriorityIcon, Avatar } from "@plane/ui"; // components import { SingleProgressStats } from "@/components/core"; import { StateDropdown } from "@/components/dropdowns"; +import { EmptyState } from "@/components/empty-state"; // constants +import { EmptyStateType } from "@/constants/empty-state"; import { CYCLE_ISSUES_WITH_PARAMS } from "@/constants/fetch-keys"; import { EIssuesStoreType } from "@/constants/issue"; // helper @@ -177,8 +179,12 @@ export const ActiveCycleStats: FC = observer((props) => { )) ) : ( -
- There are no high priority issues present in this cycle. +
+
) ) : ( @@ -195,63 +201,75 @@ export const ActiveCycleStats: FC = observer((props) => { as="div" className="flex h-52 w-full flex-col gap-1 overflow-y-auto text-custom-text-200 vertical-scrollbar scrollbar-sm" > - {cycle.distribution?.assignees?.map((assignee, index) => { - if (assignee.assignee_id) - return ( - - + {cycleIssues.length > 0 ? ( + cycle.distribution?.assignees?.map((assignee, index) => { + if (assignee.assignee_id) + return ( + + - {assignee.display_name} -
- } - completed={assignee.completed_issues} - total={assignee.total_issues} - /> - ); - else - return ( - -
- User + {assignee.display_name}
- No assignee - - } - completed={assignee.completed_issues} - total={assignee.total_issues} - /> - ); - })} + } + completed={assignee.completed_issues} + total={assignee.total_issues} + /> + ); + else + return ( + +
+ User +
+ No assignee + + } + completed={assignee.completed_issues} + total={assignee.total_issues} + /> + ); + }) + ) : ( +
+ +
+ )} - {cycle.distribution?.labels?.map((label, index) => ( - - - {label.label_name ?? "No labels"} - - } - completed={label.completed_issues} - total={label.total_issues} - /> - ))} + {cycleIssues.length > 0 ? ( + cycle.distribution?.labels?.map((label, index) => ( + + + {label.label_name ?? "No labels"} + + } + completed={label.completed_issues} + total={label.total_issues} + /> + )) + ) : ( +
+ +
+ )}
diff --git a/web/components/cycles/active-cycle/productivity.tsx b/web/components/cycles/active-cycle/productivity.tsx index 59c2ac3c9..a3366d934 100644 --- a/web/components/cycles/active-cycle/productivity.tsx +++ b/web/components/cycles/active-cycle/productivity.tsx @@ -3,6 +3,9 @@ import { FC } from "react"; import { ICycle } from "@plane/types"; // components import ProgressChart from "@/components/core/sidebar/progress-chart"; +import { EmptyState } from "@/components/empty-state"; +// constants +import { EmptyStateType } from "@/constants/empty-state"; export type ActiveCycleProductivityProps = { cycle: ICycle; @@ -16,31 +19,40 @@ export const ActiveCycleProductivity: FC = (props)

Issue burndown

- -
-
-
-
- - Ideal + {cycle.total_issues > 0 ? ( + <> +
+
+
+
+ + Ideal +
+
+ + Current +
+
+ {`Pending issues - ${cycle.backlog_issues + cycle.unstarted_issues + cycle.started_issues}`}
-
- - Current +
+
- {`Pending issues - ${cycle.backlog_issues + cycle.unstarted_issues + cycle.started_issues}`} -
-
- -
-
+ + ) : ( + <> +
+ +
+ + )}
); }; diff --git a/web/components/cycles/active-cycle/progress.tsx b/web/components/cycles/active-cycle/progress.tsx index dea3b496a..752f72bcc 100644 --- a/web/components/cycles/active-cycle/progress.tsx +++ b/web/components/cycles/active-cycle/progress.tsx @@ -3,8 +3,11 @@ import { FC } from "react"; import { ICycle } from "@plane/types"; // ui import { LinearProgressIndicator } from "@plane/ui"; +// components +import { EmptyState } from "@/components/empty-state"; // constants import { CYCLE_STATE_GROUPS_DETAILS } from "@/constants/cycle"; +import { EmptyStateType } from "@/constants/empty-state"; export type ActiveCycleProgressProps = { cycle: ICycle; @@ -32,48 +35,56 @@ export const ActiveCycleProgress: FC = (props) => {

Progress

- - {`${cycle.completed_issues + cycle.cancelled_issues}/${cycle.total_issues - cycle.cancelled_issues} ${ - cycle.completed_issues + cycle.cancelled_issues > 1 ? "Issues" : "Issue" - } closed`} - + {cycle.total_issues > 0 && ( + + {`${cycle.completed_issues + cycle.cancelled_issues}/${cycle.total_issues - cycle.cancelled_issues} ${ + cycle.completed_issues + cycle.cancelled_issues > 1 ? "Issues" : "Issue" + } closed`} + + )}
- + {cycle.total_issues > 0 && }
-
- {Object.keys(groupedIssues).map((group, index) => ( - <> - {groupedIssues[group] > 0 && ( -
-
-
- - {group} + {cycle.total_issues > 0 ? ( +
+ {Object.keys(groupedIssues).map((group, index) => ( + <> + {groupedIssues[group] > 0 && ( +
+
+
+ + {group} +
+ {`${groupedIssues[group]} ${ + groupedIssues[group] > 1 ? "Issues" : "Issue" + }`}
- {`${groupedIssues[group]} ${ - groupedIssues[group] > 1 ? "Issues" : "Issue" - }`}
-
- )} - - ))} - {cycle.cancelled_issues > 0 && ( - - - {`${cycle.cancelled_issues} cancelled ${ - cycle.cancelled_issues > 1 ? "issues are" : "issue is" - } excluded from this report.`}{" "} + )} + + ))} + {cycle.cancelled_issues > 0 && ( + + + {`${cycle.cancelled_issues} cancelled ${ + cycle.cancelled_issues > 1 ? "issues are" : "issue is" + } excluded from this report.`}{" "} + - - )} -
+ )} +
+ ) : ( +
+ +
+ )}
); }; diff --git a/web/components/cycles/active-cycle/upcoming-cycles-list.tsx b/web/components/cycles/active-cycle/upcoming-cycles-list.tsx index f4156f341..221ffab0b 100644 --- a/web/components/cycles/active-cycle/upcoming-cycles-list.tsx +++ b/web/components/cycles/active-cycle/upcoming-cycles-list.tsx @@ -1,5 +1,7 @@ import { FC } from "react"; import { observer } from "mobx-react"; +import Image from "next/image"; +import { useTheme } from "next-themes"; // components import { UpcomingCycleListItem } from "@/components/cycles"; // hooks @@ -14,6 +16,11 @@ export const UpcomingCyclesList: FC = observer((props) => { // store hooks const { currentProjectUpcomingCycleIds } = useCycle(); + // theme + const { resolvedTheme } = useTheme(); + + const resolvedEmptyStatePath = `/empty-state/active-cycle/cycle-${resolvedTheme === "light" ? "light" : "dark"}.webp`; + if (!currentProjectUpcomingCycleIds) return null; return ( @@ -28,8 +35,18 @@ export const UpcomingCyclesList: FC = observer((props) => { ))}
) : ( -
-
+
+
+
+ button image +
No upcoming cycles

Create new cycles to find them here or check diff --git a/web/components/empty-state/empty-state.tsx b/web/components/empty-state/empty-state.tsx index 88fe21612..790bd5aec 100644 --- a/web/components/empty-state/empty-state.tsx +++ b/web/components/empty-state/empty-state.tsx @@ -151,12 +151,12 @@ export const EmptyState: React.FC = (props) => { )} {layout === "screen-simple" && (

-
+
{key diff --git a/web/constants/empty-state.ts b/web/constants/empty-state.ts index 6705021a5..363147775 100644 --- a/web/constants/empty-state.ts +++ b/web/constants/empty-state.ts @@ -84,6 +84,12 @@ export enum EmptyStateType { NOTIFICATION_ARCHIVED_EMPTY_STATE = "notification-archived-empty-state", NOTIFICATION_SNOOZED_EMPTY_STATE = "notification-snoozed-empty-state", NOTIFICATION_UNREAD_EMPTY_STATE = "notification-unread-empty-state", + + ACTIVE_CYCLE_PROGRESS_EMPTY_STATE = "active-cycle-progress-empty-state", + ACTIVE_CYCLE_CHART_EMPTY_STATE = "active-cycle-chart-empty-state", + ACTIVE_CYCLE_PRIORITY_ISSUE_EMPTY_STATE = "active-cycle-priority-issue-empty-state", + ACTIVE_CYCLE_ASSIGNEE_EMPTY_STATE = "active-cycle-assignee-empty-state", + ACTIVE_CYCLE_LABEL_EMPTY_STATE = "active-cycle-label-empty-state", } const emptyStateDetails = { @@ -584,6 +590,31 @@ const emptyStateDetails = { description: "Any notification you archive will be \n available here to help you focus", path: "/empty-state/search/archive", }, + [EmptyStateType.ACTIVE_CYCLE_PROGRESS_EMPTY_STATE]: { + key: EmptyStateType.ACTIVE_CYCLE_PROGRESS_EMPTY_STATE, + title: "Add issues to the cycle to view it's \n progress", + path: "/empty-state/active-cycle/progress", + }, + [EmptyStateType.ACTIVE_CYCLE_CHART_EMPTY_STATE]: { + key: EmptyStateType.ACTIVE_CYCLE_CHART_EMPTY_STATE, + title: "Add issues to the cycle to view the \n burndown chart.", + path: "/empty-state/active-cycle/chart", + }, + [EmptyStateType.ACTIVE_CYCLE_PRIORITY_ISSUE_EMPTY_STATE]: { + key: EmptyStateType.ACTIVE_CYCLE_PRIORITY_ISSUE_EMPTY_STATE, + title: "Observe high priority issues tackled in \n the cycle at a glance.", + path: "/empty-state/active-cycle/priority", + }, + [EmptyStateType.ACTIVE_CYCLE_ASSIGNEE_EMPTY_STATE]: { + key: EmptyStateType.ACTIVE_CYCLE_ASSIGNEE_EMPTY_STATE, + title: "Add assignees to issues to see a \n breakdown of work by assignees.", + path: "/empty-state/active-cycle/assignee", + }, + [EmptyStateType.ACTIVE_CYCLE_LABEL_EMPTY_STATE]: { + key: EmptyStateType.ACTIVE_CYCLE_LABEL_EMPTY_STATE, + title: "Add labels to issues to see the \n breakdown of work by labels.", + path: "/empty-state/active-cycle/label", + }, } as const; export const EMPTY_STATE_DETAILS: Record = emptyStateDetails; diff --git a/web/public/empty-state/active-cycle/assignee-dark.webp b/web/public/empty-state/active-cycle/assignee-dark.webp new file mode 100644 index 000000000..259062767 Binary files /dev/null and b/web/public/empty-state/active-cycle/assignee-dark.webp differ diff --git a/web/public/empty-state/active-cycle/assignee-light.webp b/web/public/empty-state/active-cycle/assignee-light.webp new file mode 100644 index 000000000..b8ae5c010 Binary files /dev/null and b/web/public/empty-state/active-cycle/assignee-light.webp differ diff --git a/web/public/empty-state/active-cycle/chart-dark.webp b/web/public/empty-state/active-cycle/chart-dark.webp new file mode 100644 index 000000000..033d6fe3c Binary files /dev/null and b/web/public/empty-state/active-cycle/chart-dark.webp differ diff --git a/web/public/empty-state/active-cycle/chart-light.webp b/web/public/empty-state/active-cycle/chart-light.webp new file mode 100644 index 000000000..587906fba Binary files /dev/null and b/web/public/empty-state/active-cycle/chart-light.webp differ diff --git a/web/public/empty-state/active-cycle/cycle-dark.webp b/web/public/empty-state/active-cycle/cycle-dark.webp new file mode 100644 index 000000000..d09230804 Binary files /dev/null and b/web/public/empty-state/active-cycle/cycle-dark.webp differ diff --git a/web/public/empty-state/active-cycle/cycle-light.webp b/web/public/empty-state/active-cycle/cycle-light.webp new file mode 100644 index 000000000..a218d4d26 Binary files /dev/null and b/web/public/empty-state/active-cycle/cycle-light.webp differ diff --git a/web/public/empty-state/active-cycle/label-dark.webp b/web/public/empty-state/active-cycle/label-dark.webp new file mode 100644 index 000000000..c15d3be26 Binary files /dev/null and b/web/public/empty-state/active-cycle/label-dark.webp differ diff --git a/web/public/empty-state/active-cycle/label-light.webp b/web/public/empty-state/active-cycle/label-light.webp new file mode 100644 index 000000000..e5ccc6994 Binary files /dev/null and b/web/public/empty-state/active-cycle/label-light.webp differ diff --git a/web/public/empty-state/active-cycle/priority-dark.webp b/web/public/empty-state/active-cycle/priority-dark.webp new file mode 100644 index 000000000..f662e92ee Binary files /dev/null and b/web/public/empty-state/active-cycle/priority-dark.webp differ diff --git a/web/public/empty-state/active-cycle/priority-light.webp b/web/public/empty-state/active-cycle/priority-light.webp new file mode 100644 index 000000000..fde814c6a Binary files /dev/null and b/web/public/empty-state/active-cycle/priority-light.webp differ diff --git a/web/public/empty-state/active-cycle/progress-dark.webp b/web/public/empty-state/active-cycle/progress-dark.webp new file mode 100644 index 000000000..4beda66ea Binary files /dev/null and b/web/public/empty-state/active-cycle/progress-dark.webp differ diff --git a/web/public/empty-state/active-cycle/progress-light.webp b/web/public/empty-state/active-cycle/progress-light.webp new file mode 100644 index 000000000..ae30cf76a Binary files /dev/null and b/web/public/empty-state/active-cycle/progress-light.webp differ