From 050406b8a402576c24715137c85cac3dbb995209 Mon Sep 17 00:00:00 2001 From: Aaryan Khandelwal <65252264+aaryan610@users.noreply.github.com> Date: Mon, 30 Oct 2023 20:09:04 +0530 Subject: [PATCH] chore: add empty state for list and spreadsheet layouts (#2531) * chore: add empty state for list and spreadsheet layouts * fix: build errors --- .../issue-layouts/empty-states/cycle.tsx | 25 +++++++++ .../empty-states/global-view.tsx | 25 +++++++++ .../issue-layouts/empty-states/index.ts | 5 ++ .../issue-layouts/empty-states/module.tsx | 25 +++++++++ .../empty-states/project-view.tsx | 25 +++++++++ .../issue-layouts/empty-states/project.tsx | 25 +++++++++ web/components/issues/issue-layouts/index.ts | 1 + .../issues/issue-layouts/list/index.ts | 1 + .../issue-layouts/list/roots/module-root.tsx | 2 +- .../issue-layouts/roots/cycle-layout-root.tsx | 33 ++++++----- .../roots/global-view-layout-root.tsx | 32 ++++++----- .../roots/module-layout-root.tsx | 33 ++++++----- .../roots/project-layout-root.tsx | 33 ++++++----- .../roots/project-view-layout-root.tsx | 33 ++++++----- web/store/archived-issues/issue.store.ts | 15 ++--- web/store/cycle/cycle_issue.store.ts | 55 ++++++++++++++++--- .../cycle/cycle_issue_calendar_view.store.ts | 2 +- web/store/draft-issues/issue.store.ts | 15 ++--- web/store/issue/issue.store.ts | 40 ++++++++++++++ web/store/module/module_issue.store.ts | 55 ++++++++++++++++--- .../module_issue_calendar_view.store.ts | 2 +- .../project-view/project_view_issues.store.ts | 40 ++++++++++++++ 22 files changed, 417 insertions(+), 105 deletions(-) create mode 100644 web/components/issues/issue-layouts/empty-states/cycle.tsx create mode 100644 web/components/issues/issue-layouts/empty-states/global-view.tsx create mode 100644 web/components/issues/issue-layouts/empty-states/index.ts create mode 100644 web/components/issues/issue-layouts/empty-states/module.tsx create mode 100644 web/components/issues/issue-layouts/empty-states/project-view.tsx create mode 100644 web/components/issues/issue-layouts/empty-states/project.tsx diff --git a/web/components/issues/issue-layouts/empty-states/cycle.tsx b/web/components/issues/issue-layouts/empty-states/cycle.tsx new file mode 100644 index 000000000..e7fb0833f --- /dev/null +++ b/web/components/issues/issue-layouts/empty-states/cycle.tsx @@ -0,0 +1,25 @@ +import { PlusIcon } from "lucide-react"; +// components +import { EmptyState } from "components/common"; +// assets +import emptyIssue from "public/empty-state/issue.svg"; + +export const CycleEmptyState: React.FC = () => ( +
+ , + onClick: () => { + const e = new KeyboardEvent("keydown", { + key: "c", + }); + document.dispatchEvent(e); + }, + }} + /> +
+); diff --git a/web/components/issues/issue-layouts/empty-states/global-view.tsx b/web/components/issues/issue-layouts/empty-states/global-view.tsx new file mode 100644 index 000000000..dc7829127 --- /dev/null +++ b/web/components/issues/issue-layouts/empty-states/global-view.tsx @@ -0,0 +1,25 @@ +import { PlusIcon } from "lucide-react"; +// components +import { EmptyState } from "components/common"; +// assets +import emptyIssue from "public/empty-state/issue.svg"; + +export const GlobalViewEmptyState: React.FC = () => ( +
+ , + onClick: () => { + const e = new KeyboardEvent("keydown", { + key: "c", + }); + document.dispatchEvent(e); + }, + }} + /> +
+); diff --git a/web/components/issues/issue-layouts/empty-states/index.ts b/web/components/issues/issue-layouts/empty-states/index.ts new file mode 100644 index 000000000..0373709d2 --- /dev/null +++ b/web/components/issues/issue-layouts/empty-states/index.ts @@ -0,0 +1,5 @@ +export * from "./cycle"; +export * from "./global-view"; +export * from "./module"; +export * from "./project-view"; +export * from "./project"; diff --git a/web/components/issues/issue-layouts/empty-states/module.tsx b/web/components/issues/issue-layouts/empty-states/module.tsx new file mode 100644 index 000000000..830fde1ff --- /dev/null +++ b/web/components/issues/issue-layouts/empty-states/module.tsx @@ -0,0 +1,25 @@ +import { PlusIcon } from "lucide-react"; +// components +import { EmptyState } from "components/common"; +// assets +import emptyIssue from "public/empty-state/issue.svg"; + +export const ModuleEmptyState: React.FC = () => ( +
+ , + onClick: () => { + const e = new KeyboardEvent("keydown", { + key: "c", + }); + document.dispatchEvent(e); + }, + }} + /> +
+); diff --git a/web/components/issues/issue-layouts/empty-states/project-view.tsx b/web/components/issues/issue-layouts/empty-states/project-view.tsx new file mode 100644 index 000000000..2b046a14f --- /dev/null +++ b/web/components/issues/issue-layouts/empty-states/project-view.tsx @@ -0,0 +1,25 @@ +import { PlusIcon } from "lucide-react"; +// components +import { EmptyState } from "components/common"; +// assets +import emptyIssue from "public/empty-state/issue.svg"; + +export const ProjectViewEmptyState: React.FC = () => ( +
+ , + onClick: () => { + const e = new KeyboardEvent("keydown", { + key: "c", + }); + document.dispatchEvent(e); + }, + }} + /> +
+); diff --git a/web/components/issues/issue-layouts/empty-states/project.tsx b/web/components/issues/issue-layouts/empty-states/project.tsx new file mode 100644 index 000000000..03c4522c0 --- /dev/null +++ b/web/components/issues/issue-layouts/empty-states/project.tsx @@ -0,0 +1,25 @@ +import { PlusIcon } from "lucide-react"; +// components +import { EmptyState } from "components/common"; +// assets +import emptyIssue from "public/empty-state/issue.svg"; + +export const ProjectEmptyState: React.FC = () => ( +
+ , + onClick: () => { + const e = new KeyboardEvent("keydown", { + key: "c", + }); + document.dispatchEvent(e); + }, + }} + /> +
+); diff --git a/web/components/issues/issue-layouts/index.ts b/web/components/issues/issue-layouts/index.ts index 5e6b51931..066febb94 100644 --- a/web/components/issues/issue-layouts/index.ts +++ b/web/components/issues/issue-layouts/index.ts @@ -1,5 +1,6 @@ // filters export * from "./filters"; +export * from "./empty-states"; export * from "./quick-action-dropdowns"; // layouts diff --git a/web/components/issues/issue-layouts/list/index.ts b/web/components/issues/issue-layouts/list/index.ts index e557fe022..be3968fdd 100644 --- a/web/components/issues/issue-layouts/list/index.ts +++ b/web/components/issues/issue-layouts/list/index.ts @@ -1,4 +1,5 @@ export * from "./roots"; export * from "./block"; +export * from "./roots"; export * from "./blocks-list"; export * from "./inline-create-issue-form"; diff --git a/web/components/issues/issue-layouts/list/roots/module-root.tsx b/web/components/issues/issue-layouts/list/roots/module-root.tsx index daa12e64a..b32d303e1 100644 --- a/web/components/issues/issue-layouts/list/roots/module-root.tsx +++ b/web/components/issues/issue-layouts/list/roots/module-root.tsx @@ -68,7 +68,7 @@ export const ModuleListLayout: React.FC = observer(() => { : null; return ( -
+
{ ? getDateRangeStatus(cycleDetails?.start_date, cycleDetails?.end_date) : "draft"; + const issueCount = cycleIssueStore.getIssuesCount; + return ( <> setTransferIssuesModal(false)} isOpen={transferIssuesModal} />
{cycleStatus === "completed" && setTransferIssuesModal(true)} />} -
- {activeLayout === "list" ? ( - - ) : activeLayout === "kanban" ? ( - - ) : activeLayout === "calendar" ? ( - - ) : activeLayout === "gantt_chart" ? ( - - ) : activeLayout === "spreadsheet" ? ( - - ) : null} -
+ {(activeLayout === "list" || activeLayout === "spreadsheet") && issueCount === 0 ? ( + + ) : ( +
+ {activeLayout === "list" ? ( + + ) : activeLayout === "kanban" ? ( + + ) : activeLayout === "calendar" ? ( + + ) : activeLayout === "gantt_chart" ? ( + + ) : activeLayout === "spreadsheet" ? ( + + ) : null} +
+ )}
); diff --git a/web/components/issues/issue-layouts/roots/global-view-layout-root.tsx b/web/components/issues/issue-layouts/roots/global-view-layout-root.tsx index c88c821f4..e7adcf0e9 100644 --- a/web/components/issues/issue-layouts/roots/global-view-layout-root.tsx +++ b/web/components/issues/issue-layouts/roots/global-view-layout-root.tsx @@ -5,7 +5,7 @@ import useSWR from "swr"; // mobx store import { useMobxStore } from "lib/mobx/store-provider"; // components -import { GlobalViewsAppliedFiltersRoot, SpreadsheetView } from "components/issues"; +import { GlobalViewEmptyState, GlobalViewsAppliedFiltersRoot, SpreadsheetView } from "components/issues"; // types import { IIssue, IIssueDisplayFilterOptions, TStaticViewTypes } from "types"; @@ -81,19 +81,23 @@ export const GlobalViewLayoutRoot: React.FC = observer((props) => { return (
-
- m.member) : undefined} - labels={workspaceStore.workspaceLabels ? workspaceStore.workspaceLabels : undefined} - handleIssueAction={() => {}} - handleUpdateIssue={handleUpdateIssue} - disableUserActions={false} - /> -
+ {issues?.length === 0 ? ( + + ) : ( +
+ m.member) : undefined} + labels={workspaceStore.workspaceLabels ? workspaceStore.workspaceLabels : undefined} + handleIssueAction={() => {}} + handleUpdateIssue={handleUpdateIssue} + disableUserActions={false} + /> +
+ )}
); }); diff --git a/web/components/issues/issue-layouts/roots/module-layout-root.tsx b/web/components/issues/issue-layouts/roots/module-layout-root.tsx index f01fd1fc2..ff7867c3d 100644 --- a/web/components/issues/issue-layouts/roots/module-layout-root.tsx +++ b/web/components/issues/issue-layouts/roots/module-layout-root.tsx @@ -9,6 +9,7 @@ import { useMobxStore } from "lib/mobx/store-provider"; import { ModuleAppliedFiltersRoot, ModuleCalendarLayout, + ModuleEmptyState, ModuleGanttLayout, ModuleKanBanLayout, ModuleListLayout, @@ -46,22 +47,28 @@ export const ModuleLayoutRoot: React.FC = observer(() => { const activeLayout = issueFilterStore.userDisplayFilters.layout; + const issueCount = moduleIssueStore.getIssuesCount; + return (
-
- {activeLayout === "list" ? ( - - ) : activeLayout === "kanban" ? ( - - ) : activeLayout === "calendar" ? ( - - ) : activeLayout === "gantt_chart" ? ( - - ) : activeLayout === "spreadsheet" ? ( - - ) : null} -
+ {(activeLayout === "list" || activeLayout === "spreadsheet") && issueCount === 0 ? ( + + ) : ( +
+ {activeLayout === "list" ? ( + + ) : activeLayout === "kanban" ? ( + + ) : activeLayout === "calendar" ? ( + + ) : activeLayout === "gantt_chart" ? ( + + ) : activeLayout === "spreadsheet" ? ( + + ) : null} +
+ )}
); }); diff --git a/web/components/issues/issue-layouts/roots/project-layout-root.tsx b/web/components/issues/issue-layouts/roots/project-layout-root.tsx index f76d2a3e3..0cd5911a5 100644 --- a/web/components/issues/issue-layouts/roots/project-layout-root.tsx +++ b/web/components/issues/issue-layouts/roots/project-layout-root.tsx @@ -12,6 +12,7 @@ import { KanBanLayout, ProjectAppliedFiltersRoot, ProjectSpreadsheetLayout, + ProjectEmptyState, } from "components/issues"; export const ProjectLayoutRoot: React.FC = observer(() => { @@ -30,22 +31,28 @@ export const ProjectLayoutRoot: React.FC = observer(() => { const activeLayout = issueFilterStore.userDisplayFilters.layout; + const issueCount = issueStore.getIssuesCount; + return (
-
- {activeLayout === "list" ? ( - - ) : activeLayout === "kanban" ? ( - - ) : activeLayout === "calendar" ? ( - - ) : activeLayout === "gantt_chart" ? ( - - ) : activeLayout === "spreadsheet" ? ( - - ) : null} -
+ {(activeLayout === "list" || activeLayout === "spreadsheet") && issueCount === 0 ? ( + + ) : ( +
+ {activeLayout === "list" ? ( + + ) : activeLayout === "kanban" ? ( + + ) : activeLayout === "calendar" ? ( + + ) : activeLayout === "gantt_chart" ? ( + + ) : activeLayout === "spreadsheet" ? ( + + ) : null} +
+ )}
); }); diff --git a/web/components/issues/issue-layouts/roots/project-view-layout-root.tsx b/web/components/issues/issue-layouts/roots/project-view-layout-root.tsx index 7d5dad9e2..dfb69e63a 100644 --- a/web/components/issues/issue-layouts/roots/project-view-layout-root.tsx +++ b/web/components/issues/issue-layouts/roots/project-view-layout-root.tsx @@ -11,6 +11,7 @@ import { ModuleListLayout, ProjectViewAppliedFiltersRoot, ProjectViewCalendarLayout, + ProjectViewEmptyState, ProjectViewGanttLayout, ProjectViewSpreadsheetLayout, } from "components/issues"; @@ -48,22 +49,28 @@ export const ProjectViewLayoutRoot: React.FC = observer(() => { const activeLayout = issueFilterStore.userDisplayFilters.layout; + const issueCount = projectViewIssuesStore.getIssuesCount; + return (
-
- {activeLayout === "list" ? ( - - ) : activeLayout === "kanban" ? ( - - ) : activeLayout === "calendar" ? ( - - ) : activeLayout === "gantt_chart" ? ( - - ) : activeLayout === "spreadsheet" ? ( - - ) : null} -
+ {(activeLayout === "list" || activeLayout === "spreadsheet") && issueCount === 0 ? ( + + ) : ( +
+ {activeLayout === "list" ? ( + + ) : activeLayout === "kanban" ? ( + + ) : activeLayout === "calendar" ? ( + + ) : activeLayout === "gantt_chart" ? ( + + ) : activeLayout === "spreadsheet" ? ( + + ) : null} +
+ )}
); }); diff --git a/web/store/archived-issues/issue.store.ts b/web/store/archived-issues/issue.store.ts index 141805e23..11c29f25c 100644 --- a/web/store/archived-issues/issue.store.ts +++ b/web/store/archived-issues/issue.store.ts @@ -6,15 +6,12 @@ import { IIssue } from "types"; // services import { IssueService } from "services/issue"; import { sortArrayByDate, sortArrayByPriority } from "constants/kanban-helpers"; - -export type IIssueType = "grouped" | "groupWithSubGroups" | "ungrouped"; -export type IIssueGroupedStructure = { [group_id: string]: IIssue[] }; -export type IIssueGroupWithSubGroupsStructure = { - [group_id: string]: { - [sub_group_id: string]: IIssue[]; - }; -}; -export type IIssueUnGroupedStructure = IIssue[]; +import { + IIssueGroupWithSubGroupsStructure, + IIssueGroupedStructure, + IIssueType, + IIssueUnGroupedStructure, +} from "store/issue"; export interface IArchivedIssueStore { loader: boolean; diff --git a/web/store/cycle/cycle_issue.store.ts b/web/store/cycle/cycle_issue.store.ts index e343a733d..333218060 100644 --- a/web/store/cycle/cycle_issue.store.ts +++ b/web/store/cycle/cycle_issue.store.ts @@ -9,15 +9,12 @@ import { sortArrayByDate, sortArrayByPriority } from "constants/kanban-helpers"; // types import { IIssue } from "types"; import { IBlockUpdateData } from "components/gantt-chart"; - -export type IIssueType = "grouped" | "groupWithSubGroups" | "ungrouped"; -export type IIssueGroupedStructure = { [group_id: string]: IIssue[] }; -export type IIssueGroupWithSubGroupsStructure = { - [group_id: string]: { - [sub_group_id: string]: IIssue[]; - }; -}; -export type IIssueUnGroupedStructure = IIssue[]; +import { + IIssueGroupWithSubGroupsStructure, + IIssueGroupedStructure, + IIssueType, + IIssueUnGroupedStructure, +} from "store/issue"; export interface ICycleIssueStore { loader: boolean; @@ -33,6 +30,7 @@ export interface ICycleIssueStore { // computed getIssueType: IIssueType | null; getIssues: IIssueGroupedStructure | IIssueGroupWithSubGroupsStructure | IIssueUnGroupedStructure | null; + getIssuesCount: number; // action fetchIssues: (workspaceSlug: string, projectId: string, cycleId: string) => Promise; updateIssueStructure: (group_id: string | null, sub_group_id: string | null, issue: IIssue) => void; @@ -73,6 +71,7 @@ export class CycleIssueStore implements ICycleIssueStore { // computed getIssueType: computed, getIssues: computed, + getIssuesCount: computed, // actions fetchIssues: action, updateIssueStructure: action, @@ -130,6 +129,44 @@ export class CycleIssueStore implements ICycleIssueStore { return this.issues?.[cycleId]?.[issueType] || null; } + get getIssuesCount() { + const issueType = this.getIssueType; + + let issuesCount = 0; + + if (issueType === "grouped") { + const issues = this.getIssues as IIssueGroupedStructure; + + if (!issues) return 0; + + Object.keys(issues).map((group_id) => { + issuesCount += issues[group_id].length; + }); + } + + if (issueType === "groupWithSubGroups") { + const issues = this.getIssues as IIssueGroupWithSubGroupsStructure; + + if (!issues) return 0; + + Object.keys(issues).map((sub_group_id) => { + Object.keys(issues[sub_group_id]).map((group_id) => { + issuesCount += issues[sub_group_id][group_id].length; + }); + }); + } + + if (issueType === "ungrouped") { + const issues = this.getIssues as IIssueUnGroupedStructure; + + if (!issues) return 0; + + issuesCount = issues.length; + } + + return issuesCount; + } + updateIssueStructure = async (group_id: string | null, sub_group_id: string | null, issue: IIssue) => { const cycleId: string | null = this.rootStore?.cycle?.cycleId || null; const issueType = this.getIssueType; diff --git a/web/store/cycle/cycle_issue_calendar_view.store.ts b/web/store/cycle/cycle_issue_calendar_view.store.ts index 0ebb38c37..fa80f39ac 100644 --- a/web/store/cycle/cycle_issue_calendar_view.store.ts +++ b/web/store/cycle/cycle_issue_calendar_view.store.ts @@ -1,7 +1,7 @@ import { action, makeObservable, runInAction } from "mobx"; // types import { RootStore } from "../root"; -import { IIssueType } from "./cycle_issue.store"; +import { IIssueType } from "store/issue"; export interface ICycleIssueCalendarViewStore { // actions diff --git a/web/store/draft-issues/issue.store.ts b/web/store/draft-issues/issue.store.ts index c8afece07..f31a0bbb4 100644 --- a/web/store/draft-issues/issue.store.ts +++ b/web/store/draft-issues/issue.store.ts @@ -6,15 +6,12 @@ import { IIssue } from "types"; // services import { IssueService } from "services/issue"; import { sortArrayByDate, sortArrayByPriority } from "constants/kanban-helpers"; - -export type IIssueType = "grouped" | "groupWithSubGroups" | "ungrouped"; -export type IIssueGroupedStructure = { [group_id: string]: IIssue[] }; -export type IIssueGroupWithSubGroupsStructure = { - [group_id: string]: { - [sub_group_id: string]: IIssue[]; - }; -}; -export type IIssueUnGroupedStructure = IIssue[]; +import { + IIssueGroupWithSubGroupsStructure, + IIssueGroupedStructure, + IIssueType, + IIssueUnGroupedStructure, +} from "store/issue"; export interface IDraftIssueStore { loader: boolean; diff --git a/web/store/issue/issue.store.ts b/web/store/issue/issue.store.ts index 85d726f78..924c91eb1 100644 --- a/web/store/issue/issue.store.ts +++ b/web/store/issue/issue.store.ts @@ -31,6 +31,7 @@ export interface IIssueStore { // computed getIssueType: IIssueType | null; getIssues: IIssueGroupedStructure | IIssueGroupWithSubGroupsStructure | IIssueUnGroupedStructure | null; + getIssuesCount: number; // action fetchIssues: (workspaceSlug: string, projectId: string) => Promise; updateIssueStructure: (group_id: string | null, sub_group_id: string | null, issue: IIssue) => void; @@ -68,6 +69,7 @@ export class IssueStore implements IIssueStore { // computed getIssueType: computed, getIssues: computed, + getIssuesCount: computed, // actions fetchIssues: action, updateIssueStructure: action, @@ -120,6 +122,44 @@ export class IssueStore implements IIssueStore { return this.issues?.[projectId]?.[issueType] || null; } + get getIssuesCount() { + const issueType = this.getIssueType; + + let issuesCount = 0; + + if (issueType === "grouped") { + const issues = this.getIssues as IIssueGroupedStructure; + + if (!issues) return 0; + + Object.keys(issues).map((group_id) => { + issuesCount += issues[group_id].length; + }); + } + + if (issueType === "groupWithSubGroups") { + const issues = this.getIssues as IIssueGroupWithSubGroupsStructure; + + if (!issues) return 0; + + Object.keys(issues).map((sub_group_id) => { + Object.keys(issues[sub_group_id]).map((group_id) => { + issuesCount += issues[sub_group_id][group_id].length; + }); + }); + } + + if (issueType === "ungrouped") { + const issues = this.getIssues as IIssueUnGroupedStructure; + + if (!issues) return 0; + + issuesCount = issues.length; + } + + return issuesCount; + } + updateIssueStructure = async (group_id: string | null, sub_group_id: string | null, issue: IIssue) => { const projectId: string | null = issue?.project; const issueType = this.getIssueType; diff --git a/web/store/module/module_issue.store.ts b/web/store/module/module_issue.store.ts index 9751ef708..5b5893b0d 100644 --- a/web/store/module/module_issue.store.ts +++ b/web/store/module/module_issue.store.ts @@ -8,15 +8,12 @@ import { sortArrayByDate, sortArrayByPriority } from "constants/kanban-helpers"; // types import { IIssue } from "types"; import { IBlockUpdateData } from "components/gantt-chart"; - -export type IIssueType = "grouped" | "groupWithSubGroups" | "ungrouped"; -export type IIssueGroupedStructure = { [group_id: string]: IIssue[] }; -export type IIssueGroupWithSubGroupsStructure = { - [group_id: string]: { - [sub_group_id: string]: IIssue[]; - }; -}; -export type IIssueUnGroupedStructure = IIssue[]; +import { + IIssueGroupWithSubGroupsStructure, + IIssueGroupedStructure, + IIssueType, + IIssueUnGroupedStructure, +} from "store/issue"; export interface IModuleIssueStore { loader: boolean; @@ -32,6 +29,7 @@ export interface IModuleIssueStore { // computed getIssueType: IIssueType | null; getIssues: IIssueGroupedStructure | IIssueGroupWithSubGroupsStructure | IIssueUnGroupedStructure | null; + getIssuesCount: number; // action fetchIssues: (workspaceSlug: string, projectId: string, moduleId: string) => Promise; updateIssueStructure: (group_id: string | null, sub_group_id: string | null, issue: IIssue) => void; @@ -76,6 +74,7 @@ export class ModuleIssueStore implements IModuleIssueStore { // computed getIssueType: computed, getIssues: computed, + getIssuesCount: computed, // actions fetchIssues: action, updateIssueStructure: action, @@ -132,6 +131,44 @@ export class ModuleIssueStore implements IModuleIssueStore { return this.issues?.[moduleId]?.[issueType] || null; } + get getIssuesCount() { + const issueType = this.getIssueType; + + let issuesCount = 0; + + if (issueType === "grouped") { + const issues = this.getIssues as IIssueGroupedStructure; + + if (!issues) return 0; + + Object.keys(issues).map((group_id) => { + issuesCount += issues[group_id].length; + }); + } + + if (issueType === "groupWithSubGroups") { + const issues = this.getIssues as IIssueGroupWithSubGroupsStructure; + + if (!issues) return 0; + + Object.keys(issues).map((sub_group_id) => { + Object.keys(issues[sub_group_id]).map((group_id) => { + issuesCount += issues[sub_group_id][group_id].length; + }); + }); + } + + if (issueType === "ungrouped") { + const issues = this.getIssues as IIssueUnGroupedStructure; + + if (!issues) return 0; + + issuesCount = issues.length; + } + + return issuesCount; + } + updateIssueStructure = async (group_id: string | null, sub_group_id: string | null, issue: IIssue) => { const moduleId: string | null = this.rootStore?.module?.moduleId; const issueType = this.getIssueType; diff --git a/web/store/module/module_issue_calendar_view.store.ts b/web/store/module/module_issue_calendar_view.store.ts index 95a866040..313745a18 100644 --- a/web/store/module/module_issue_calendar_view.store.ts +++ b/web/store/module/module_issue_calendar_view.store.ts @@ -1,7 +1,7 @@ import { action, makeObservable, runInAction } from "mobx"; // types import { RootStore } from "../root"; -import { IIssueType } from "./module_issue.store"; +import { IIssueType } from "store/issue"; export interface IModuleIssueCalendarViewStore { // actions diff --git a/web/store/project-view/project_view_issues.store.ts b/web/store/project-view/project_view_issues.store.ts index 1c6374942..1e699c270 100644 --- a/web/store/project-view/project_view_issues.store.ts +++ b/web/store/project-view/project_view_issues.store.ts @@ -45,6 +45,7 @@ export interface IProjectViewIssuesStore { // computed getIssues: IIssueGroupedStructure | IIssueGroupWithSubGroupsStructure | IIssueUnGroupedStructure | null; + getIssuesCount: number; getIssueType: IIssueType | null; } @@ -86,6 +87,7 @@ export class ProjectViewIssuesStore implements IProjectViewIssuesStore { // computed getIssueType: computed, getIssues: computed, + getIssuesCount: computed, }); this.rootStore = _rootStore; @@ -147,6 +149,44 @@ export class ProjectViewIssuesStore implements IProjectViewIssuesStore { return this.viewIssues?.[viewId]?.[issueType] || null; } + get getIssuesCount() { + const issueType = this.rootStore.issue.getIssueType; + + let issuesCount = 0; + + if (issueType === "grouped") { + const issues = this.getIssues as IIssueGroupedStructure; + + if (!issues) return 0; + + Object.keys(issues).map((group_id) => { + issuesCount += issues[group_id].length; + }); + } + + if (issueType === "groupWithSubGroups") { + const issues = this.getIssues as IIssueGroupWithSubGroupsStructure; + + if (!issues) return 0; + + Object.keys(issues).map((sub_group_id) => { + Object.keys(issues[sub_group_id]).map((group_id) => { + issuesCount += issues[sub_group_id][group_id].length; + }); + }); + } + + if (issueType === "ungrouped") { + const issues = this.getIssues as IIssueUnGroupedStructure; + + if (!issues) return 0; + + issuesCount = issues.length; + } + + return issuesCount; + } + updateIssueStructure = async (group_id: string | null, sub_group_id: string | null, issue: IIssue) => { const viewId: string | null = this.rootStore.projectViews.viewId; const issueType = this.rootStore.issue.getIssueType;