From a6d741e7846e0896aeb988087f8f4a24821d1a8a Mon Sep 17 00:00:00 2001 From: guru_sainath Date: Wed, 25 Oct 2023 16:09:50 +0530 Subject: [PATCH] chore: implemented drag and drop between dates for project issues, cycle, module, and project views for calendar layout (#2535) --- .../issue-layouts/calendar/day-tile.tsx | 61 +++++++------ .../issue-layouts/calendar/issue-blocks.tsx | 58 ++++++------ .../calendar/roots/cycle-root.tsx | 10 ++- .../calendar/roots/module-root.tsx | 4 +- .../calendar/roots/project-root.tsx | 10 ++- .../calendar/roots/project-view-root.tsx | 4 +- .../cycle/cycle_issue_calendar_view.store.ts | 89 +++++++++++++++++++ web/store/cycle/index.ts | 1 + web/store/issue/index.ts | 1 + web/store/issue/issue_calendar_view.store.ts | 88 ++++++++++++++++++ web/store/module/index.ts | 1 + .../module_issue_calendar_view.store.ts | 89 +++++++++++++++++++ web/store/project-view/index.ts | 2 + .../project_view_issue_calendar_view.store.ts | 89 +++++++++++++++++++ .../project-view/project_view_issues.store.ts | 32 ++++++- web/store/root.ts | 16 ++++ 16 files changed, 492 insertions(+), 63 deletions(-) create mode 100644 web/store/cycle/cycle_issue_calendar_view.store.ts create mode 100644 web/store/issue/issue_calendar_view.store.ts create mode 100644 web/store/module/module_issue_calendar_view.store.ts create mode 100644 web/store/project-view/project_view_issue_calendar_view.store.ts diff --git a/web/components/issues/issue-layouts/calendar/day-tile.tsx b/web/components/issues/issue-layouts/calendar/day-tile.tsx index 7d07ce7f4..03d797522 100644 --- a/web/components/issues/issue-layouts/calendar/day-tile.tsx +++ b/web/components/issues/issue-layouts/calendar/day-tile.tsx @@ -29,35 +29,46 @@ export const CalendarDayTile: React.FC = observer((props) => { const issuesList = issues ? (issues as IIssueGroupedStructure)[renderDateFormat(date.date)] : null; return ( - - {(provided, snapshot) => ( + <> +
+ {/* header */}
- <> -
- {date.date.getDate() === 1 && MONTHS_LIST[date.date.getMonth() + 1].shortTitle + " "} - {date.date.getDate()} -
- - {provided.placeholder} - + {date.date.getDate() === 1 && MONTHS_LIST[date.date.getMonth() + 1].shortTitle + " "} + {date.date.getDate()}
- )} - + + {/* content */} +
+ + {(provided, snapshot) => ( +
+ + {provided.placeholder} +
+ )} +
+
+
+ ); }); diff --git a/web/components/issues/issue-layouts/calendar/issue-blocks.tsx b/web/components/issues/issue-layouts/calendar/issue-blocks.tsx index de58b8622..eac2ef43d 100644 --- a/web/components/issues/issue-layouts/calendar/issue-blocks.tsx +++ b/web/components/issues/issue-layouts/calendar/issue-blocks.tsx @@ -17,42 +17,46 @@ export const CalendarIssueBlocks: React.FC = observer((props) => { const { workspaceSlug } = router.query; return ( -
+ <> {issues?.map((issue, index) => ( {(provided, snapshot) => ( - - - -
- {issue.project_detail.identifier}-{issue.sequence_id} -
-
{issue.name}
-
{quickActions(issue)}
- {/* + +
+ +
+ {issue.project_detail.identifier}-{issue.sequence_id} +
+
{issue.name}
+
{quickActions(issue)}
+ {/* handleIssues(issue.target_date ?? "", issue, "delete")} handleUpdate={async (data) => handleIssues(issue.target_date ?? "", data, "update")} /> */} -
- + + +
)} ))} - + ); }); diff --git a/web/components/issues/issue-layouts/calendar/roots/cycle-root.tsx b/web/components/issues/issue-layouts/calendar/roots/cycle-root.tsx index 0f0c19f06..ec9e6b94f 100644 --- a/web/components/issues/issue-layouts/calendar/roots/cycle-root.tsx +++ b/web/components/issues/issue-layouts/calendar/roots/cycle-root.tsx @@ -11,12 +11,16 @@ import { IIssueGroupedStructure } from "store/issue"; import { IIssue } from "types"; export const CycleCalendarLayout: React.FC = observer(() => { - const { cycleIssue: cycleIssueStore, issueFilter: issueFilterStore, issueDetail: issueDetailStore } = useMobxStore(); + const { + cycleIssue: cycleIssueStore, + issueFilter: issueFilterStore, + issueDetail: issueDetailStore, + cycleIssueCalendarView: cycleIssueCalendarViewStore, + } = useMobxStore(); const router = useRouter(); const { workspaceSlug, cycleId } = router.query; - // TODO: add drag and drop functionality const onDragEnd = (result: DropResult) => { if (!result) return; @@ -26,7 +30,7 @@ export const CycleCalendarLayout: React.FC = observer(() => { // return if dropped on the same date if (result.destination.droppableId === result.source.droppableId) return; - // issueKanBanViewStore?.handleDragDrop(result.source, result.destination); + cycleIssueCalendarViewStore?.handleDragDrop(result.source, result.destination); }; const issues = cycleIssueStore.getIssues; diff --git a/web/components/issues/issue-layouts/calendar/roots/module-root.tsx b/web/components/issues/issue-layouts/calendar/roots/module-root.tsx index c0afd5a0a..1f0219d55 100644 --- a/web/components/issues/issue-layouts/calendar/roots/module-root.tsx +++ b/web/components/issues/issue-layouts/calendar/roots/module-root.tsx @@ -15,12 +15,12 @@ export const ModuleCalendarLayout: React.FC = observer(() => { moduleIssue: moduleIssueStore, issueFilter: issueFilterStore, issueDetail: issueDetailStore, + moduleIssueCalendarView: moduleIssueCalendarViewStore, } = useMobxStore(); const router = useRouter(); const { workspaceSlug, moduleId } = router.query; - // TODO: add drag and drop functionality const onDragEnd = (result: DropResult) => { if (!result) return; @@ -30,7 +30,7 @@ export const ModuleCalendarLayout: React.FC = observer(() => { // return if dropped on the same date if (result.destination.droppableId === result.source.droppableId) return; - // issueKanBanViewStore?.handleDragDrop(result.source, result.destination); + moduleIssueCalendarViewStore?.handleDragDrop(result.source, result.destination); }; const issues = moduleIssueStore.getIssues; diff --git a/web/components/issues/issue-layouts/calendar/roots/project-root.tsx b/web/components/issues/issue-layouts/calendar/roots/project-root.tsx index 1d7c1cea3..96459a350 100644 --- a/web/components/issues/issue-layouts/calendar/roots/project-root.tsx +++ b/web/components/issues/issue-layouts/calendar/roots/project-root.tsx @@ -11,12 +11,16 @@ import { IIssueGroupedStructure } from "store/issue"; import { IIssue } from "types"; export const CalendarLayout: React.FC = observer(() => { - const { issue: issueStore, issueFilter: issueFilterStore, issueDetail: issueDetailStore } = useMobxStore(); + const { + issue: issueStore, + issueFilter: issueFilterStore, + issueDetail: issueDetailStore, + issueCalendarView: issueCalendarViewStore, + } = useMobxStore(); const router = useRouter(); const { workspaceSlug } = router.query; - // TODO: add drag and drop functionality const onDragEnd = (result: DropResult) => { if (!result) return; @@ -26,7 +30,7 @@ export const CalendarLayout: React.FC = observer(() => { // return if dropped on the same date if (result.destination.droppableId === result.source.droppableId) return; - // issueKanBanViewStore?.handleDragDrop(result.source, result.destination); + issueCalendarViewStore?.handleDragDrop(result.source, result.destination); }; const issues = issueStore.getIssues; diff --git a/web/components/issues/issue-layouts/calendar/roots/project-view-root.tsx b/web/components/issues/issue-layouts/calendar/roots/project-view-root.tsx index 5aa9e1545..6ea847609 100644 --- a/web/components/issues/issue-layouts/calendar/roots/project-view-root.tsx +++ b/web/components/issues/issue-layouts/calendar/roots/project-view-root.tsx @@ -15,12 +15,12 @@ export const ProjectViewCalendarLayout: React.FC = observer(() => { projectViewIssues: projectViewIssuesStore, issueFilter: issueFilterStore, issueDetail: issueDetailStore, + projectViewIssueCalendarView: projectViewIssueCalendarViewStore, } = useMobxStore(); const router = useRouter(); const { workspaceSlug } = router.query; - // TODO: add drag and drop functionality const onDragEnd = (result: DropResult) => { if (!result) return; @@ -30,7 +30,7 @@ export const ProjectViewCalendarLayout: React.FC = observer(() => { // return if dropped on the same date if (result.destination.droppableId === result.source.droppableId) return; - // issueKanBanViewStore?.handleDragDrop(result.source, result.destination); + projectViewIssueCalendarViewStore?.handleDragDrop(result.source, result.destination); }; const issues = projectViewIssuesStore.getIssues; diff --git a/web/store/cycle/cycle_issue_calendar_view.store.ts b/web/store/cycle/cycle_issue_calendar_view.store.ts new file mode 100644 index 000000000..0ebb38c37 --- /dev/null +++ b/web/store/cycle/cycle_issue_calendar_view.store.ts @@ -0,0 +1,89 @@ +import { action, makeObservable, runInAction } from "mobx"; +// types +import { RootStore } from "../root"; +import { IIssueType } from "./cycle_issue.store"; + +export interface ICycleIssueCalendarViewStore { + // actions + handleDragDrop: (source: any, destination: any) => void; +} + +export class CycleIssueCalendarViewStore implements ICycleIssueCalendarViewStore { + // root store + rootStore; + + constructor(_rootStore: RootStore) { + makeObservable(this, { + // actions + handleDragDrop: action, + }); + + this.rootStore = _rootStore; + } + + handleDragDrop = async (source: any, destination: any) => { + const workspaceSlug = this.rootStore?.workspace?.workspaceSlug; + const projectId = this.rootStore?.project?.projectId; + const cycleId = this.rootStore?.cycle?.cycleId; + const issueType: IIssueType | null = this.rootStore?.cycleIssue?.getIssueType; + const issueLayout = this.rootStore?.issueFilter?.userDisplayFilters?.layout || null; + const currentIssues: any = this.rootStore.cycleIssue.getIssues; + + if (workspaceSlug && projectId && cycleId && issueType && issueLayout === "calendar" && currentIssues) { + // update issue payload + let updateIssue: any = { + workspaceSlug: workspaceSlug, + projectId: projectId, + }; + + const droppableSourceColumnId = source.droppableId; + const droppableDestinationColumnId = destination.droppableId; + + if (droppableSourceColumnId === droppableDestinationColumnId) return; + + if (droppableSourceColumnId != droppableDestinationColumnId) { + // horizontal + const _sourceIssues = currentIssues[droppableSourceColumnId]; + let _destinationIssues = currentIssues[droppableDestinationColumnId] || []; + + const [removed] = _sourceIssues.splice(source.index, 1); + + if (_destinationIssues && _destinationIssues.length > 0) + _destinationIssues.splice(destination.index, 0, { + ...removed, + target_date: droppableDestinationColumnId, + }); + else _destinationIssues = [..._destinationIssues, { ...removed, target_date: droppableDestinationColumnId }]; + + updateIssue = { ...updateIssue, issueId: removed?.id, target_date: droppableDestinationColumnId }; + + currentIssues[droppableSourceColumnId] = _sourceIssues; + currentIssues[droppableDestinationColumnId] = _destinationIssues; + } + + const reorderedIssues = { + ...this.rootStore?.cycleIssue.issues, + [cycleId]: { + ...this.rootStore?.cycleIssue.issues?.[cycleId], + [issueType]: { + ...this.rootStore?.cycleIssue.issues?.[cycleId]?.[issueType], + [issueType]: currentIssues, + }, + }, + }; + + runInAction(() => { + this.rootStore.cycleIssue.issues = { ...reorderedIssues }; + }); + + this.rootStore.issueDetail?.updateIssue( + updateIssue.workspaceSlug, + updateIssue.projectId, + updateIssue.issueId, + updateIssue + ); + } + + return; + }; +} diff --git a/web/store/cycle/index.ts b/web/store/cycle/index.ts index b8fb17576..ae854f978 100644 --- a/web/store/cycle/index.ts +++ b/web/store/cycle/index.ts @@ -1,4 +1,5 @@ export * from "./cycle_issue_filters.store"; export * from "./cycle_issue_kanban_view.store"; +export * from "./cycle_issue_calendar_view.store"; export * from "./cycle_issue.store"; export * from "./cycles.store"; diff --git a/web/store/issue/index.ts b/web/store/issue/index.ts index 27c613eb8..7b6cb4f34 100644 --- a/web/store/issue/index.ts +++ b/web/store/issue/index.ts @@ -2,4 +2,5 @@ export * from "./issue_detail.store"; export * from "./issue_draft.store"; export * from "./issue_filters.store"; export * from "./issue_kanban_view.store"; +export * from "./issue_calendar_view.store"; export * from "./issue.store"; diff --git a/web/store/issue/issue_calendar_view.store.ts b/web/store/issue/issue_calendar_view.store.ts new file mode 100644 index 000000000..5f9cc89bf --- /dev/null +++ b/web/store/issue/issue_calendar_view.store.ts @@ -0,0 +1,88 @@ +import { action, makeObservable, runInAction } from "mobx"; +// types +import { RootStore } from "../root"; +import { IIssueType } from "./issue.store"; + +export interface IIssueCalendarViewStore { + // actions + handleDragDrop: (source: any, destination: any) => void; +} + +export class IssueCalendarViewStore implements IIssueCalendarViewStore { + // root store + rootStore; + + constructor(_rootStore: RootStore) { + makeObservable(this, { + // actions + handleDragDrop: action, + }); + + this.rootStore = _rootStore; + } + + handleDragDrop = async (source: any, destination: any) => { + const workspaceSlug = this.rootStore?.workspace?.workspaceSlug; + const projectId = this.rootStore?.project?.projectId; + const issueType: IIssueType | null = this.rootStore?.issue?.getIssueType; + const issueLayout = this.rootStore?.issueFilter?.userDisplayFilters?.layout || null; + const currentIssues: any = this.rootStore.issue.getIssues; + + if (workspaceSlug && projectId && issueType && issueLayout === "calendar" && currentIssues) { + // update issue payload + let updateIssue: any = { + workspaceSlug: workspaceSlug, + projectId: projectId, + }; + + const droppableSourceColumnId = source.droppableId; + const droppableDestinationColumnId = destination.droppableId; + + if (droppableSourceColumnId === droppableDestinationColumnId) return; + + // horizontal + if (droppableSourceColumnId != droppableDestinationColumnId) { + const _sourceIssues = currentIssues[droppableSourceColumnId]; + let _destinationIssues = currentIssues[droppableDestinationColumnId] || []; + + const [removed] = _sourceIssues.splice(source.index, 1); + + if (_destinationIssues && _destinationIssues.length > 0) + _destinationIssues.splice(destination.index, 0, { + ...removed, + target_date: droppableDestinationColumnId, + }); + else _destinationIssues = [..._destinationIssues, { ...removed, target_date: droppableDestinationColumnId }]; + + updateIssue = { ...updateIssue, issueId: removed?.id, target_date: droppableDestinationColumnId }; + + currentIssues[droppableSourceColumnId] = _sourceIssues; + currentIssues[droppableDestinationColumnId] = _destinationIssues; + } + + const reorderedIssues = { + ...this.rootStore?.issue.issues, + [projectId]: { + ...this.rootStore?.issue.issues?.[projectId], + [issueType]: { + ...this.rootStore?.issue.issues?.[projectId]?.[issueType], + [issueType]: currentIssues, + }, + }, + }; + + runInAction(() => { + this.rootStore.issue.issues = { ...reorderedIssues }; + }); + + this.rootStore.issueDetail?.updateIssue( + updateIssue.workspaceSlug, + updateIssue.projectId, + updateIssue.issueId, + updateIssue + ); + } + + return; + }; +} diff --git a/web/store/module/index.ts b/web/store/module/index.ts index 4f2bc1027..3d62d3de8 100644 --- a/web/store/module/index.ts +++ b/web/store/module/index.ts @@ -1,4 +1,5 @@ export * from "./module_filters.store"; export * from "./module_issue_kanban_view.store"; +export * from "./module_issue_calendar_view.store"; export * from "./module_issue.store"; export * from "./modules.store"; diff --git a/web/store/module/module_issue_calendar_view.store.ts b/web/store/module/module_issue_calendar_view.store.ts new file mode 100644 index 000000000..95a866040 --- /dev/null +++ b/web/store/module/module_issue_calendar_view.store.ts @@ -0,0 +1,89 @@ +import { action, makeObservable, runInAction } from "mobx"; +// types +import { RootStore } from "../root"; +import { IIssueType } from "./module_issue.store"; + +export interface IModuleIssueCalendarViewStore { + // actions + handleDragDrop: (source: any, destination: any) => void; +} + +export class ModuleIssueCalendarViewStore implements IModuleIssueCalendarViewStore { + // root store + rootStore; + + constructor(_rootStore: RootStore) { + makeObservable(this, { + // actions + handleDragDrop: action, + }); + + this.rootStore = _rootStore; + } + + handleDragDrop = async (source: any, destination: any) => { + const workspaceSlug = this.rootStore?.workspace?.workspaceSlug; + const projectId = this.rootStore?.project?.projectId; + const moduleId = this.rootStore?.module?.moduleId; + const issueType: IIssueType | null = this.rootStore?.moduleIssue?.getIssueType; + const issueLayout = this.rootStore?.issueFilter?.userDisplayFilters?.layout || null; + const currentIssues: any = this.rootStore.moduleIssue.getIssues; + + if (workspaceSlug && projectId && moduleId && issueType && issueLayout === "calendar" && currentIssues) { + // update issue payload + let updateIssue: any = { + workspaceSlug: workspaceSlug, + projectId: projectId, + }; + + const droppableSourceColumnId = source.droppableId; + const droppableDestinationColumnId = destination.droppableId; + + if (droppableSourceColumnId === droppableDestinationColumnId) return; + + if (droppableSourceColumnId != droppableDestinationColumnId) { + // horizontal + const _sourceIssues = currentIssues[droppableSourceColumnId]; + let _destinationIssues = currentIssues[droppableDestinationColumnId] || []; + + const [removed] = _sourceIssues.splice(source.index, 1); + + if (_destinationIssues && _destinationIssues.length > 0) + _destinationIssues.splice(destination.index, 0, { + ...removed, + target_date: droppableDestinationColumnId, + }); + else _destinationIssues = [..._destinationIssues, { ...removed, target_date: droppableDestinationColumnId }]; + + updateIssue = { ...updateIssue, issueId: removed?.id, target_date: droppableDestinationColumnId }; + + currentIssues[droppableSourceColumnId] = _sourceIssues; + currentIssues[droppableDestinationColumnId] = _destinationIssues; + } + + const reorderedIssues = { + ...this.rootStore?.moduleIssue.issues, + [moduleId]: { + ...this.rootStore?.moduleIssue.issues?.[moduleId], + [issueType]: { + ...this.rootStore?.moduleIssue.issues?.[moduleId]?.[issueType], + [issueType]: currentIssues, + }, + }, + }; + + runInAction(() => { + this.rootStore.moduleIssue.issues = { ...reorderedIssues }; + }); + + this.rootStore.issueDetail?.updateIssue( + updateIssue.workspaceSlug, + updateIssue.projectId, + updateIssue.issueId, + updateIssue + ); + } + + return; + }; +} diff --git a/web/store/project-view/index.ts b/web/store/project-view/index.ts index 8fd611bab..39a4c2fac 100644 --- a/web/store/project-view/index.ts +++ b/web/store/project-view/index.ts @@ -1,3 +1,5 @@ export * from "./project_view_filters.store"; export * from "./project_view_issues.store"; export * from "./project_views.store"; + +export * from "./project_view_issue_calendar_view.store"; diff --git a/web/store/project-view/project_view_issue_calendar_view.store.ts b/web/store/project-view/project_view_issue_calendar_view.store.ts new file mode 100644 index 000000000..2f70df136 --- /dev/null +++ b/web/store/project-view/project_view_issue_calendar_view.store.ts @@ -0,0 +1,89 @@ +import { action, makeObservable, runInAction } from "mobx"; +// types +import { RootStore } from "../root"; +import { IIssueType } from "./project_view_issues.store"; + +export interface IProjectViewIssueCalendarViewStore { + // actions + handleDragDrop: (source: any, destination: any) => void; +} + +export class ProjectViewIssueCalendarViewStore implements IProjectViewIssueCalendarViewStore { + // root store + rootStore; + + constructor(_rootStore: RootStore) { + makeObservable(this, { + // actions + handleDragDrop: action, + }); + + this.rootStore = _rootStore; + } + + handleDragDrop = async (source: any, destination: any) => { + const workspaceSlug = this.rootStore?.workspace?.workspaceSlug; + const projectId = this.rootStore?.project?.projectId; + const viewId = this.rootStore?.projectViews?.viewId; + const issueType: IIssueType | null = this.rootStore?.projectViewIssues?.getIssueType; + const issueLayout = this.rootStore?.issueFilter?.userDisplayFilters?.layout || null; + const currentIssues: any = this.rootStore.projectViewIssues.getIssues; + + if (workspaceSlug && projectId && viewId && issueType && issueLayout === "calendar" && currentIssues) { + // update issue payload + let updateIssue: any = { + workspaceSlug: workspaceSlug, + projectId: projectId, + }; + + const droppableSourceColumnId = source.droppableId; + const droppableDestinationColumnId = destination.droppableId; + + if (droppableSourceColumnId === droppableDestinationColumnId) return; + + if (droppableSourceColumnId != droppableDestinationColumnId) { + // horizontal + const _sourceIssues = currentIssues[droppableSourceColumnId]; + let _destinationIssues = currentIssues[droppableDestinationColumnId] || []; + + const [removed] = _sourceIssues.splice(source.index, 1); + + if (_destinationIssues && _destinationIssues.length > 0) + _destinationIssues.splice(destination.index, 0, { + ...removed, + target_date: droppableDestinationColumnId, + }); + else _destinationIssues = [..._destinationIssues, { ...removed, target_date: droppableDestinationColumnId }]; + + updateIssue = { ...updateIssue, issueId: removed?.id, target_date: droppableDestinationColumnId }; + + currentIssues[droppableSourceColumnId] = _sourceIssues; + currentIssues[droppableDestinationColumnId] = _destinationIssues; + } + + const reorderedIssues = { + ...this.rootStore?.projectViewIssues.viewIssues, + [viewId]: { + ...this.rootStore?.projectViewIssues.viewIssues?.[viewId], + [issueType]: { + ...this.rootStore?.projectViewIssues.viewIssues?.[viewId]?.[issueType], + [issueType]: currentIssues, + }, + }, + }; + + runInAction(() => { + this.rootStore.projectViewIssues.viewIssues = { ...reorderedIssues }; + }); + + this.rootStore.issueDetail?.updateIssue( + updateIssue.workspaceSlug, + updateIssue.projectId, + updateIssue.issueId, + updateIssue + ); + } + + return; + }; +} diff --git a/web/store/project-view/project_view_issues.store.ts b/web/store/project-view/project_view_issues.store.ts index 9588237fe..1c6374942 100644 --- a/web/store/project-view/project_view_issues.store.ts +++ b/web/store/project-view/project_view_issues.store.ts @@ -6,10 +6,18 @@ import { handleIssueQueryParamsByLayout } from "helpers/issue.helper"; import { sortArrayByDate, sortArrayByPriority } from "constants/kanban-helpers"; // types import { RootStore } from "../root"; -import { IIssueGroupWithSubGroupsStructure, IIssueGroupedStructure, IIssueUnGroupedStructure } from "store/issue"; import { IIssue, IIssueFilterOptions } 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[]; + export interface IProjectViewIssuesStore { // states loader: boolean; @@ -37,6 +45,7 @@ export interface IProjectViewIssuesStore { // computed getIssues: IIssueGroupedStructure | IIssueGroupWithSubGroupsStructure | IIssueUnGroupedStructure | null; + getIssueType: IIssueType | null; } export class ProjectViewIssuesStore implements IProjectViewIssuesStore { @@ -75,6 +84,7 @@ export class ProjectViewIssuesStore implements IProjectViewIssuesStore { fetchViewIssues: action, // computed + getIssueType: computed, getIssues: computed, }); @@ -108,6 +118,26 @@ export class ProjectViewIssuesStore implements IProjectViewIssuesStore { return computedFilters; }; + get getIssueType() { + const groupedLayouts = ["kanban", "list", "calendar"]; + const ungroupedLayouts = ["spreadsheet", "gantt_chart"]; + + const issueLayout = this.rootStore?.issueFilter?.userDisplayFilters?.layout || null; + const issueSubGroup = this.rootStore?.issueFilter?.userDisplayFilters?.sub_group_by || null; + + if (!issueLayout) return null; + + const _issueState = groupedLayouts.includes(issueLayout) + ? issueSubGroup + ? "groupWithSubGroups" + : "grouped" + : ungroupedLayouts.includes(issueLayout) + ? "ungrouped" + : null; + + return _issueState || null; + } + get getIssues() { const viewId: string | null = this.rootStore.projectViews.viewId; const issueType = this.rootStore.issue.getIssueType; diff --git a/web/store/root.ts b/web/store/root.ts index 4a830435a..1a85185d6 100644 --- a/web/store/root.ts +++ b/web/store/root.ts @@ -12,6 +12,8 @@ import { IssueDetailStore, IssueFilterStore, IssueKanBanViewStore, + IIssueCalendarViewStore, + IssueCalendarViewStore, IssueStore, } from "store/issue"; import { IWorkspaceFilterStore, IWorkspaceStore, WorkspaceFilterStore, WorkspaceStore } from "store/workspace"; @@ -24,6 +26,8 @@ import { ModuleFilterStore, ModuleIssueKanBanViewStore, ModuleIssueStore, + IModuleIssueCalendarViewStore, + ModuleIssueCalendarViewStore, ModuleStore, } from "store/module"; import { @@ -33,6 +37,8 @@ import { CycleStore, ICycleIssueFilterStore, ICycleIssueKanBanViewStore, + ICycleIssueCalendarViewStore, + CycleIssueCalendarViewStore, ICycleIssueStore, ICycleStore, } from "store/cycle"; @@ -43,6 +49,8 @@ import { ProjectViewFiltersStore, ProjectViewIssuesStore, ProjectViewsStore, + IProjectViewIssueCalendarViewStore, + ProjectViewIssueCalendarViewStore, } from "store/project-view"; import CalendarStore, { ICalendarStore } from "store/calendar.store"; import { @@ -95,19 +103,23 @@ export class RootStore { moduleIssue: IModuleIssueStore; moduleFilter: IModuleFilterStore; moduleIssueKanBanView: IModuleIssueKanBanViewStore; + moduleIssueCalendarView: IModuleIssueCalendarViewStore; cycle: ICycleStore; cycleIssue: ICycleIssueStore; cycleIssueFilter: ICycleIssueFilterStore; cycleIssueKanBanView: ICycleIssueKanBanViewStore; + cycleIssueCalendarView: ICycleIssueCalendarViewStore; projectViews: IProjectViewsStore; projectViewIssues: IProjectViewIssuesStore; projectViewFilters: IProjectViewFiltersStore; + projectViewIssueCalendarView: IProjectViewIssueCalendarViewStore; issueFilter: IIssueFilterStore; issueDetail: IIssueDetailStore; issueKanBanView: IIssueKanBanViewStore; + issueCalendarView: IIssueCalendarViewStore; draftIssuesStore: DraftIssuesStore; calendar: ICalendarStore; @@ -145,20 +157,24 @@ export class RootStore { this.moduleIssue = new ModuleIssueStore(this); this.moduleFilter = new ModuleFilterStore(this); this.moduleIssueKanBanView = new ModuleIssueKanBanViewStore(this); + this.moduleIssueCalendarView = new ModuleIssueCalendarViewStore(this); this.cycle = new CycleStore(this); this.cycleIssue = new CycleIssueStore(this); this.cycleIssueFilter = new CycleIssueFilterStore(this); this.cycleIssueKanBanView = new CycleIssueKanBanViewStore(this); + this.cycleIssueCalendarView = new CycleIssueCalendarViewStore(this); this.projectViews = new ProjectViewsStore(this); this.projectViewIssues = new ProjectViewIssuesStore(this); this.projectViewFilters = new ProjectViewFiltersStore(this); + this.projectViewIssueCalendarView = new ProjectViewIssueCalendarViewStore(this); this.issue = new IssueStore(this); this.issueFilter = new IssueFilterStore(this); this.issueDetail = new IssueDetailStore(this); this.issueKanBanView = new IssueKanBanViewStore(this); + this.issueCalendarView = new IssueCalendarViewStore(this); this.draftIssuesStore = new DraftIssuesStore(this); this.calendar = new CalendarStore(this);