diff --git a/web/.prettierrc b/web/.prettierrc index d5cb26e54..87d988f1b 100644 --- a/web/.prettierrc +++ b/web/.prettierrc @@ -1,5 +1,5 @@ { - "printWidth": 100, + "printWidth": 120, "tabWidth": 2, "trailingComma": "es5" } diff --git a/web/components/issue-layouts/filters/index.tsx b/web/components/issue-layouts/filters/index.tsx index d83f3f725..89fbcdd91 100644 --- a/web/components/issue-layouts/filters/index.tsx +++ b/web/components/issue-layouts/filters/index.tsx @@ -23,9 +23,9 @@ export const FilterSelection = observer(() => { const handleFilterSectionVisibility = (section_key: string) => issueFilterStore?.issueView && issueFilterStore?.issueLayout && - issueFilterVisibilityData[ - issueFilterStore?.issueView === "my_issues" ? "my_issues" : "others" - ]?.filters?.[issueFilterStore?.issueLayout]?.includes(section_key); + issueFilterVisibilityData[issueFilterStore?.issueView === "my_issues" ? "my_issues" : "others"]?.filters?.[ + issueFilterStore?.issueLayout + ]?.includes(section_key); return (
diff --git a/web/components/issue-layouts/kanban/content.tsx b/web/components/issue-layouts/kanban/content.tsx index 6f297fcf6..ad83c2960 100644 --- a/web/components/issue-layouts/kanban/content.tsx +++ b/web/components/issue-layouts/kanban/content.tsx @@ -14,11 +14,7 @@ export const IssueContent = ({ columnId, issues }: IssueContentProps) => { {issues && issues.length > 0 ? ( <> {issues.map((issue: any, index: any) => ( - + {(provided: any, snapshot: any) => (
{ >
-
- ONE-{issue.sequence_id}-{issue.sort_order} -
+
ONE-{issue.sequence_id}
{issue.name}
Footer
diff --git a/web/components/issue-layouts/kanban/header.tsx b/web/components/issue-layouts/kanban/header.tsx index 8c04dc20d..c9a308a27 100644 --- a/web/components/issue-layouts/kanban/header.tsx +++ b/web/components/issue-layouts/kanban/header.tsx @@ -4,18 +4,14 @@ import { Plus } from "lucide-react"; export const IssueHeader = () => (
{/* default layout */} -
- I -
-
Kanban Issue Heading
-
- 0 -
+
I
+
Kanban Issue Heading
+
0
-
+
M
-
+
diff --git a/web/components/issue-layouts/kanban/index.tsx b/web/components/issue-layouts/kanban/index.tsx index b517484dc..33b72c4b4 100644 --- a/web/components/issue-layouts/kanban/index.tsx +++ b/web/components/issue-layouts/kanban/index.tsx @@ -11,8 +11,7 @@ import { useMobxStore } from "lib/mobx/store-provider"; import { RootStore } from "store/root"; export const IssueKanBanViewRoot = observer(() => { - const store: RootStore = useMobxStore(); - const { issueView: issueViewStore } = store; + const { issueView: issueViewStore, issueKanBanView: issueKanBanViewStore }: RootStore = useMobxStore(); const onDragEnd = (result: any) => { if (!result) return; @@ -25,7 +24,7 @@ export const IssueKanBanViewRoot = observer(() => { ) return; - console.log("result", result); + issueKanBanViewStore?.handleDragDrop(result.source, result.destination); }; return ( @@ -38,10 +37,7 @@ export const IssueKanBanViewRoot = observer(() => {
{Object.keys(issueViewStore?.getIssues).map((_issueStateKey: any) => ( -
+
diff --git a/web/pages/m-store/[workspace_slug]/[project_slug]/issues.tsx b/web/pages/m-store/[workspace_slug]/[project_slug]/issues.tsx index c6319bcaa..c068f14f6 100644 --- a/web/pages/m-store/[workspace_slug]/[project_slug]/issues.tsx +++ b/web/pages/m-store/[workspace_slug]/[project_slug]/issues.tsx @@ -19,8 +19,7 @@ const KanBanViewRoot = () => { React.useEffect(() => { console.log("request init--->"); - const init = async () => - await issueViewStore.getProjectIssuesAsync(workspace_slug, project_slug); + const init = async () => await issueViewStore.getProjectIssuesAsync(workspace_slug, project_slug); if (workspace_slug && project_slug) init(); console.log("request completed--->"); }, [workspace_slug, project_slug, issueViewStore]); diff --git a/web/services/issues.service.ts b/web/services/issues.service.ts index a62d26d3c..e5ec55784 100644 --- a/web/services/issues.service.ts +++ b/web/services/issues.service.ts @@ -63,14 +63,8 @@ export class ProjectIssuesServices extends APIService { }); } - async getIssueActivities( - workspaceSlug: string, - projectId: string, - issueId: string - ): Promise { - return this.get( - `/api/workspaces/${workspaceSlug}/projects/${projectId}/issues/${issueId}/history/` - ) + async getIssueActivities(workspaceSlug: string, projectId: string, issueId: string): Promise { + return this.get(`/api/workspaces/${workspaceSlug}/projects/${projectId}/issues/${issueId}/history/`) .then((response) => response?.data) .catch((error) => { throw error?.response?.data; @@ -78,9 +72,7 @@ export class ProjectIssuesServices extends APIService { } async getIssueComments(workspaceSlug: string, projectId: string, issueId: string): Promise { - return this.get( - `/api/workspaces/${workspaceSlug}/projects/${projectId}/issues/${issueId}/comments/` - ) + return this.get(`/api/workspaces/${workspaceSlug}/projects/${projectId}/issues/${issueId}/comments/`) .then((response) => response?.data) .catch((error) => { throw error?.response?.data; @@ -104,10 +96,7 @@ export class ProjectIssuesServices extends APIService { }, user: ICurrentUserResponse | undefined ) { - return this.post( - `/api/workspaces/${workspaceSlug}/projects/${projectId}/cycles/${cycleId}/cycle-issues/`, - data - ) + return this.post(`/api/workspaces/${workspaceSlug}/projects/${projectId}/cycles/${cycleId}/cycle-issues/`, data) .then((response) => { trackEventServices.trackIssueMovedToCycleOrModuleEvent( { @@ -129,12 +118,7 @@ export class ProjectIssuesServices extends APIService { }); } - async removeIssueFromCycle( - workspaceSlug: string, - projectId: string, - cycleId: string, - bridgeId: string - ) { + async removeIssueFromCycle(workspaceSlug: string, projectId: string, cycleId: string, bridgeId: string) { return this.delete( `/api/workspaces/${workspaceSlug}/projects/${projectId}/cycles/${cycleId}/cycle-issues/${bridgeId}/` ) @@ -156,10 +140,7 @@ export class ProjectIssuesServices extends APIService { }>; } ) { - return this.post( - `/api/workspaces/${workspaceSlug}/projects/${projectId}/issues/${issueId}/issue-relation/`, - data - ) + return this.post(`/api/workspaces/${workspaceSlug}/projects/${projectId}/issues/${issueId}/issue-relation/`, data) .then((response) => { trackEventServices.trackIssueRelationEvent(response.data, "ISSUE_RELATION_CREATE", user); return response?.data; @@ -189,10 +170,7 @@ export class ProjectIssuesServices extends APIService { } async createIssueProperties(workspaceSlug: string, projectId: string, data: any): Promise { - return this.post( - `/api/workspaces/${workspaceSlug}/projects/${projectId}/issue-properties/`, - data - ) + return this.post(`/api/workspaces/${workspaceSlug}/projects/${projectId}/issue-properties/`, data) .then((response) => response?.data) .catch((error) => { throw error?.response?.data; @@ -206,8 +184,7 @@ export class ProjectIssuesServices extends APIService { data: any ): Promise { return this.patch( - `/api/workspaces/${workspaceSlug}/projects/${projectId}/issue-properties/` + - `${issuePropertyId}/`, + `/api/workspaces/${workspaceSlug}/projects/${projectId}/issue-properties/` + `${issuePropertyId}/`, data ) .then((response) => response?.data) @@ -223,10 +200,7 @@ export class ProjectIssuesServices extends APIService { data: Partial, user: ICurrentUserResponse | undefined ): Promise { - return this.post( - `/api/workspaces/${workspaceSlug}/projects/${projectId}/issues/${issueId}/comments/`, - data - ) + return this.post(`/api/workspaces/${workspaceSlug}/projects/${projectId}/issues/${issueId}/comments/`, data) .then((response) => { trackEventServices.trackIssueCommentEvent(response.data, "ISSUE_COMMENT_CREATE", user); return response?.data; @@ -335,10 +309,7 @@ export class ProjectIssuesServices extends APIService { data: any, user: ICurrentUserResponse | undefined ): Promise { - return this.patch( - `/api/workspaces/${workspaceSlug}/projects/${projectId}/issue-labels/${labelId}/`, - data - ) + return this.patch(`/api/workspaces/${workspaceSlug}/projects/${projectId}/issue-labels/${labelId}/`, data) .then((response) => { trackEventServices.trackIssueLabelEvent( { @@ -367,9 +338,7 @@ export class ProjectIssuesServices extends APIService { labelId: string, user: ICurrentUserResponse | undefined ): Promise { - return this.delete( - `/api/workspaces/${workspaceSlug}/projects/${projectId}/issue-labels/${labelId}/` - ) + return this.delete(`/api/workspaces/${workspaceSlug}/projects/${projectId}/issue-labels/${labelId}/`) .then((response) => { trackEventServices.trackIssueLabelEvent( { @@ -393,10 +362,7 @@ export class ProjectIssuesServices extends APIService { data: Partial, user: ICurrentUserResponse | undefined ): Promise { - return this.patch( - `/api/workspaces/${workspaceSlug}/projects/${projectId}/issues/${issueId}/`, - data - ) + return this.patch(`/api/workspaces/${workspaceSlug}/projects/${projectId}/issues/${issueId}/`, data) .then((response) => { trackEventServices.trackIssueEvent(response.data, "ISSUE_UPDATE", user); return response?.data; @@ -428,10 +394,7 @@ export class ProjectIssuesServices extends APIService { data: any, user: ICurrentUserResponse | undefined ): Promise { - return this.delete( - `/api/workspaces/${workspaceSlug}/projects/${projectId}/bulk-delete-issues/`, - data - ) + return this.delete(`/api/workspaces/${workspaceSlug}/projects/${projectId}/bulk-delete-issues/`, data) .then((response) => { trackEventServices.trackIssueBulkDeleteEvent(data, user); return response?.data; @@ -441,14 +404,8 @@ export class ProjectIssuesServices extends APIService { }); } - async subIssues( - workspaceSlug: string, - projectId: string, - issueId: string - ): Promise { - return this.get( - `/api/workspaces/${workspaceSlug}/projects/${projectId}/issues/${issueId}/sub-issues/` - ) + async subIssues(workspaceSlug: string, projectId: string, issueId: string): Promise { + return this.get(`/api/workspaces/${workspaceSlug}/projects/${projectId}/issues/${issueId}/sub-issues/`) .then((response) => response?.data) .catch((error) => { throw error?.response?.data; @@ -461,10 +418,7 @@ export class ProjectIssuesServices extends APIService { issueId: string, data: { sub_issue_ids: string[] } ): Promise { - return this.post( - `/api/workspaces/${workspaceSlug}/projects/${projectId}/issues/${issueId}/sub-issues/`, - data - ) + return this.post(`/api/workspaces/${workspaceSlug}/projects/${projectId}/issues/${issueId}/sub-issues/`, data) .then((response) => response?.data) .catch((error) => { throw error?.response?.data; @@ -481,10 +435,7 @@ export class ProjectIssuesServices extends APIService { url: string; } ): Promise { - return this.post( - `/api/workspaces/${workspaceSlug}/projects/${projectId}/issues/${issueId}/issue-links/`, - data - ) + return this.post(`/api/workspaces/${workspaceSlug}/projects/${projectId}/issues/${issueId}/issue-links/`, data) .then((response) => response?.data) .catch((error) => { throw error?.response; @@ -512,12 +463,7 @@ export class ProjectIssuesServices extends APIService { }); } - async deleteIssueLink( - workspaceSlug: string, - projectId: string, - issueId: string, - linkId: string - ): Promise { + async deleteIssueLink(workspaceSlug: string, projectId: string, issueId: string, linkId: string): Promise { return this.delete( `/api/workspaces/${workspaceSlug}/projects/${projectId}/issues/${issueId}/issue-links/${linkId}/` ) @@ -527,12 +473,7 @@ export class ProjectIssuesServices extends APIService { }); } - async uploadIssueAttachment( - workspaceSlug: string, - projectId: string, - issueId: string, - file: FormData - ): Promise { + async uploadIssueAttachment(workspaceSlug: string, projectId: string, issueId: string, file: FormData): Promise { return this.mediaUpload( `/api/workspaces/${workspaceSlug}/projects/${projectId}/issues/${issueId}/issue-attachments/`, file @@ -543,14 +484,8 @@ export class ProjectIssuesServices extends APIService { }); } - async getIssueAttachment( - workspaceSlug: string, - projectId: string, - issueId: string - ): Promise { - return this.get( - `/api/workspaces/${workspaceSlug}/projects/${projectId}/issues/${issueId}/issue-attachments/` - ) + async getIssueAttachment(workspaceSlug: string, projectId: string, issueId: string): Promise { + return this.get(`/api/workspaces/${workspaceSlug}/projects/${projectId}/issues/${issueId}/issue-attachments/`) .then((response) => response?.data) .catch((error) => { throw error?.response?.data; @@ -590,28 +525,16 @@ export class ProjectIssuesServices extends APIService { }); } - async retrieveArchivedIssue( - workspaceSlug: string, - projectId: string, - issueId: string - ): Promise { - return this.get( - `/api/workspaces/${workspaceSlug}/projects/${projectId}/archived-issues/${issueId}/` - ) + async retrieveArchivedIssue(workspaceSlug: string, projectId: string, issueId: string): Promise { + return this.get(`/api/workspaces/${workspaceSlug}/projects/${projectId}/archived-issues/${issueId}/`) .then((response) => response?.data) .catch((error) => { throw error?.response?.data; }); } - async deleteArchivedIssue( - workspaceSlug: string, - projectId: string, - issuesId: string - ): Promise { - return this.delete( - `/api/workspaces/${workspaceSlug}/projects/${projectId}/archived-issues/${issuesId}/` - ) + async deleteArchivedIssue(workspaceSlug: string, projectId: string, issuesId: string): Promise { + return this.delete(`/api/workspaces/${workspaceSlug}/projects/${projectId}/archived-issues/${issuesId}/`) .then((response) => response?.data) .catch((error) => { throw error?.response?.data; @@ -648,10 +571,7 @@ export class ProjectIssuesServices extends APIService { data: any, user: ICurrentUserResponse ): Promise { - return this.patch( - `/api/workspaces/${workspaceSlug}/projects/${projectId}/issue-drafts/${issueId}/`, - data - ) + return this.patch(`/api/workspaces/${workspaceSlug}/projects/${projectId}/issue-drafts/${issueId}/`, data) .then((response) => response?.data) .catch((error) => { throw error?.response; @@ -659,9 +579,7 @@ export class ProjectIssuesServices extends APIService { } async deleteDraftIssue(workspaceSlug: string, projectId: string, issueId: string): Promise { - return this.delete( - `/api/workspaces/${workspaceSlug}/projects/${projectId}/issue-drafts/${issueId}/` - ) + return this.delete(`/api/workspaces/${workspaceSlug}/projects/${projectId}/issue-drafts/${issueId}/`) .then((response) => response?.data) .catch((error) => { throw error?.response; @@ -669,9 +587,7 @@ export class ProjectIssuesServices extends APIService { } async getDraftIssueById(workspaceSlug: string, projectId: string, issueId: string): Promise { - return this.get( - `/api/workspaces/${workspaceSlug}/projects/${projectId}/issue-drafts/${issueId}/` - ) + return this.get(`/api/workspaces/${workspaceSlug}/projects/${projectId}/issue-drafts/${issueId}/`) .then((response) => response?.data) .catch((error) => { throw error?.response; diff --git a/web/store/issue-views/Issue_details.ts b/web/store/issue-views/Issue_details.ts deleted file mode 100644 index b6da85b1b..000000000 --- a/web/store/issue-views/Issue_details.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { observable, action, computed, makeObservable, runInAction } from "mobx"; -// types -import { RootStore } from "../root"; - -export interface IIssueViewStore { - loader: boolean; - error: any | null; -} - -class IssueViewStore implements IIssueViewStore { - loader: boolean = false; - error: any | null = null; - - // root store - rootStore; - // service - - constructor(_rootStore: RootStore) { - makeObservable(this, { - // observable - loader: observable, - error: observable, - }); - - this.rootStore = _rootStore; - } -} - -export default IssueViewStore; diff --git a/web/store/issue-views/Issues.ts b/web/store/issue-views/Issues.ts index 1eb29188d..d8dacc1f5 100644 --- a/web/store/issue-views/Issues.ts +++ b/web/store/issue-views/Issues.ts @@ -49,11 +49,7 @@ export interface IIssueViewStore { getIssues: IIssues | null | undefined; // actions getMyIssuesAsync: (workspaceId: string, fetchFilterToggle: boolean) => null | Promise; - getProjectIssuesAsync: ( - workspaceId: string, - projectId: string, - fetchFilterToggle: boolean - ) => null | Promise; + getProjectIssuesAsync: (workspaceId: string, projectId: string, fetchFilterToggle: boolean) => null | Promise; getIssuesForModulesAsync: ( workspaceId: string, projectId: string, @@ -122,29 +118,25 @@ class IssueViewStore implements IIssueViewStore { if (!currentView || !currentWorkspaceId) return null; const currentLayout: TIssueLayouts = currentProjectId - ? this.rootStore.issueFilters.issueFilters?.[currentWorkspaceId] - ?.project_issue_properties?.[currentProjectId]?.issues?.display_filters?.layout - : this.rootStore.issueFilters.issueFilters?.[currentWorkspaceId]?.my_issue_properties - ?.display_filters?.layout; + ? this.rootStore.issueFilters.issueFilters?.[currentWorkspaceId]?.project_issue_properties?.[currentProjectId] + ?.issues?.display_filters?.layout + : this.rootStore.issueFilters.issueFilters?.[currentWorkspaceId]?.my_issue_properties?.display_filters?.layout; - if (currentView === "my_issues") - return this.issues?.[currentWorkspaceId]?.my_issues?.[currentLayout]; + if (currentView === "my_issues") return this.issues?.[currentWorkspaceId]?.my_issues?.[currentLayout]; else if (currentView === "issues" && currentProjectId) - return this.issues?.[currentWorkspaceId]?.project_issues?.[currentProjectId]?.issues?.[ + return this.issues?.[currentWorkspaceId]?.project_issues?.[currentProjectId]?.issues?.[currentLayout]; + else if (currentView === "modules" && currentProjectId && currentModuleId) + return this.issues?.[currentWorkspaceId]?.project_issues?.[currentProjectId]?.modules?.[currentModuleId]?.[ currentLayout ]; - else if (currentView === "modules" && currentProjectId && currentModuleId) - return this.issues?.[currentWorkspaceId]?.project_issues?.[currentProjectId]?.modules?.[ - currentModuleId - ]?.[currentLayout]; else if (currentView === "cycles" && currentProjectId && currentCycleId) - return this.issues?.[currentWorkspaceId]?.project_issues?.[currentProjectId]?.cycles?.[ - currentCycleId - ]?.[currentLayout]; + return this.issues?.[currentWorkspaceId]?.project_issues?.[currentProjectId]?.cycles?.[currentCycleId]?.[ + currentLayout + ]; else if (currentView === "views" && currentProjectId && currentViewId) - return this.issues?.[currentWorkspaceId]?.project_issues?.[currentProjectId]?.views?.[ - currentViewId - ]?.[currentLayout]; + return this.issues?.[currentWorkspaceId]?.project_issues?.[currentProjectId]?.views?.[currentViewId]?.[ + currentLayout + ]; } return null; @@ -156,8 +148,7 @@ class IssueViewStore implements IIssueViewStore { this.loader = true; this.error = null; - if (fetchFilterToggle) - await this.rootStore.issueFilters.getWorkspaceMyIssuesFilters(workspaceId); + if (fetchFilterToggle) await this.rootStore.issueFilters.getWorkspaceMyIssuesFilters(workspaceId); const filteredParams = this.rootStore.issueFilters.getComputedFilters( workspaceId, null, @@ -175,8 +166,7 @@ class IssueViewStore implements IIssueViewStore { ...this?.issues[workspaceId], my_issues: { ...this?.issues[workspaceId]?.my_issues, - [this.rootStore?.issueFilters?.userFilters?.display_filters?.layout as string]: - issuesResponse, + [this.rootStore?.issueFilters?.userFilters?.display_filters?.layout as string]: issuesResponse, }, }, }; @@ -198,17 +188,12 @@ class IssueViewStore implements IIssueViewStore { }; // fetching project issues - getProjectIssuesAsync = async ( - workspaceId: string, - projectId: string, - fetchFilterToggle: boolean = true - ) => { + getProjectIssuesAsync = async (workspaceId: string, projectId: string, fetchFilterToggle: boolean = true) => { try { this.loader = true; this.error = null; - if (fetchFilterToggle) - await this.rootStore.issueFilters.getProjectIssueFilters(workspaceId, projectId); + if (fetchFilterToggle) await this.rootStore.issueFilters.getProjectIssueFilters(workspaceId, projectId); const filteredParams = this.rootStore.issueFilters.getComputedFilters( workspaceId, projectId, @@ -217,11 +202,7 @@ class IssueViewStore implements IIssueViewStore { null, "issues" ); - const issuesResponse = await this.issueService.getIssuesWithParams( - workspaceId, - projectId, - filteredParams - ); + const issuesResponse = await this.issueService.getIssuesWithParams(workspaceId, projectId, filteredParams); if (issuesResponse) { const _issueResponse: any = { @@ -234,8 +215,7 @@ class IssueViewStore implements IIssueViewStore { ...this?.issues?.[workspaceId]?.project_issues?.[projectId], issues: { ...this?.issues[workspaceId]?.project_issues?.[projectId]?.issues, - [this.rootStore?.issueFilters?.userFilters?.display_filters?.layout as string]: - issuesResponse, + [this.rootStore?.issueFilters?.userFilters?.display_filters?.layout as string]: issuesResponse, }, }, }, @@ -270,11 +250,7 @@ class IssueViewStore implements IIssueViewStore { this.error = null; if (fetchFilterToggle) - await this.rootStore.issueFilters.getProjectIssueModuleFilters( - workspaceId, - projectId, - moduleId - ); + await this.rootStore.issueFilters.getProjectIssueModuleFilters(workspaceId, projectId, moduleId); const filteredParams = this.rootStore.issueFilters.getComputedFilters( workspaceId, projectId, @@ -303,8 +279,7 @@ class IssueViewStore implements IIssueViewStore { ...this?.issues[workspaceId]?.project_issues?.[projectId]?.modules, [moduleId]: { ...this?.issues[workspaceId]?.project_issues?.[projectId]?.modules?.[moduleId], - [this.rootStore?.issueFilters?.userFilters?.display_filters?.layout as string]: - issuesResponse, + [this.rootStore?.issueFilters?.userFilters?.display_filters?.layout as string]: issuesResponse, }, }, }, @@ -340,11 +315,7 @@ class IssueViewStore implements IIssueViewStore { this.error = null; if (fetchFilterToggle) - await this.rootStore.issueFilters.getProjectIssueCyclesFilters( - workspaceId, - projectId, - cycleId - ); + await this.rootStore.issueFilters.getProjectIssueCyclesFilters(workspaceId, projectId, cycleId); const filteredParams = this.rootStore.issueFilters.getComputedFilters( workspaceId, projectId, @@ -373,8 +344,7 @@ class IssueViewStore implements IIssueViewStore { ...this?.issues[workspaceId]?.project_issues?.[projectId]?.cycles, [cycleId]: { ...this?.issues[workspaceId]?.project_issues?.[projectId]?.cycles?.[cycleId], - [this.rootStore?.issueFilters?.userFilters?.display_filters?.layout as string]: - issuesResponse, + [this.rootStore?.issueFilters?.userFilters?.display_filters?.layout as string]: issuesResponse, }, }, }, @@ -410,11 +380,7 @@ class IssueViewStore implements IIssueViewStore { this.error = null; if (fetchFilterToggle) - await this.rootStore.issueFilters.getProjectIssueViewsFilters( - workspaceId, - projectId, - viewId - ); + await this.rootStore.issueFilters.getProjectIssueViewsFilters(workspaceId, projectId, viewId); const filteredParams = this.rootStore.issueFilters.getComputedFilters( workspaceId, projectId, @@ -423,11 +389,7 @@ class IssueViewStore implements IIssueViewStore { viewId, "views" ); - const issuesResponse = await this.issueService.getIssuesWithParams( - workspaceId, - projectId, - filteredParams - ); + const issuesResponse = await this.issueService.getIssuesWithParams(workspaceId, projectId, filteredParams); if (issuesResponse) { const _issueResponse: any = { @@ -442,8 +404,7 @@ class IssueViewStore implements IIssueViewStore { ...this?.issues[workspaceId]?.project_issues?.[projectId]?.views, [viewId]: { ...this?.issues[workspaceId]?.project_issues?.[projectId]?.views?.[viewId], - [this.rootStore?.issueFilters?.userFilters?.display_filters?.layout as string]: - issuesResponse, + [this.rootStore?.issueFilters?.userFilters?.display_filters?.layout as string]: issuesResponse, }, }, }, diff --git a/web/store/issue-views/issue_data.ts b/web/store/issue-views/issue_data.ts index 7c870e5b5..d6d12743a 100644 --- a/web/store/issue-views/issue_data.ts +++ b/web/store/issue-views/issue_data.ts @@ -45,7 +45,7 @@ export const displayPropertyGroupBy: { key: string; title: string }[] = [ { key: "state", title: "States" }, { key: "state_detail.group", title: "State Groups" }, { key: "priority", title: "Priority" }, - { key: "Project", title: "Project" }, // required this on my issues + { key: "project", title: "Project" }, // required this on my issues { key: "labels", title: "Labels" }, { key: "assignees", title: "Assignees" }, { key: "created_by", title: "Created By" }, diff --git a/web/store/issue-views/issue_detail.ts b/web/store/issue-views/issue_detail.ts new file mode 100644 index 000000000..224b16ac8 --- /dev/null +++ b/web/store/issue-views/issue_detail.ts @@ -0,0 +1,175 @@ +import { observable, action, makeObservable, runInAction } from "mobx"; +// types +import { RootStore } from "../root"; +// services +import { ProjectIssuesServices } from "services/issues.service"; + +export type IPeekMode = "side" | "modal" | "full"; + +export interface IIssueViewDetailStore { + loader: boolean; + error: any | null; + + peekId: string | null; + peekMode: IPeekMode | null; + + issue_detail: { + workspace: { + [key: string]: { + issues: { + [key: string]: any; + }; + }; + }; + }; + + setPeekId: (issueId: string | null) => void; + setPeekMode: (issueId: IPeekMode | null) => void; + + // fetch issue details + fetchIssueDetailsAsync: (workspaceId: string, projectId: string, issueId: string) => void; + // creating issue + createIssueAsync: (workspaceId: string, projectId: string, issueId: string, data: any) => void; + // updating issue + updateIssueAsync: (workspaceId: string, projectId: string, issueId: string, data: any) => void; + // deleting issue + deleteIssueAsync: (workspaceId: string, projectId: string, issueId: string) => void; +} + +class IssueViewDetailStore implements IIssueViewDetailStore { + loader: boolean = false; + error: any | null = null; + + peekId: string | null = null; + peekMode: IPeekMode | null = null; + + issue_detail: { + workspace: { + [key: string]: { + issues: { + [key: string]: any; + }; + }; + }; + } = { + workspace: {}, + }; + + // root store + rootStore; + // service + issueService; + + constructor(_rootStore: RootStore) { + makeObservable(this, { + // observable + loader: observable, + error: observable, + + peekId: observable, + peekMode: observable, + issue_detail: observable, + + setPeekId: action, + setPeekMode: action, + + fetchIssueDetailsAsync: action, + createIssueAsync: action, + updateIssueAsync: action, + deleteIssueAsync: action, + }); + + this.rootStore = _rootStore; + this.issueService = new ProjectIssuesServices(); + } + + setPeekId = (issueId: string | null) => (this.peekId = issueId); + setPeekMode = (mode: IPeekMode | null) => (this.peekMode = mode); + + fetchIssueDetailsAsync = async (workspaceId: string, projectId: string, issueId: string) => { + try { + this.loader = true; + this.error = null; + + console.log("workspaceId", workspaceId); + console.log("projectId", projectId); + console.log("issueId", issueId); + + runInAction(() => { + this.loader = false; + this.error = null; + }); + } catch (error) { + console.log("error in fetching issue details", error); + this.loader = false; + this.error = error; + return error; + } + }; + + createIssueAsync = async (workspaceId: string, projectId: string, issueId: string, data: any) => { + try { + this.loader = true; + this.error = null; + + console.log("workspaceId", workspaceId); + console.log("projectId", projectId); + console.log("issueId", issueId); + console.log("data", data); + + runInAction(() => { + this.loader = false; + this.error = null; + }); + } catch (error) { + console.log("error in fetching issue details", error); + this.loader = false; + this.error = error; + return error; + } + }; + + updateIssueAsync = async (workspaceId: string, projectId: string, issueId: string, data: any) => { + try { + this.loader = true; + this.error = null; + + const issueResponse = await this.issueService.patchIssue(workspaceId, projectId, issueId, data, undefined); + + if (issueResponse) { + runInAction(() => { + this.loader = false; + this.error = null; + }); + } + } catch (error) { + console.log("error in fetching issue details", error); + this.loader = false; + this.error = error; + return error; + } + }; + + deleteIssueAsync = async (workspaceId: string, projectId: string, issueId: string) => { + try { + this.loader = true; + this.error = null; + + console.log("workspaceId", workspaceId); + console.log("projectId", projectId); + console.log("issueId", issueId); + + runInAction(() => { + this.loader = false; + this.error = null; + }); + } catch (error) { + console.log("error in fetching issue details", error); + this.loader = false; + this.error = error; + return error; + } + }; +} + +export default IssueViewDetailStore; diff --git a/web/store/issue-views/issue_filters.ts b/web/store/issue-views/issue_filters.ts index dda2f0dac..e24dae0e1 100644 --- a/web/store/issue-views/issue_filters.ts +++ b/web/store/issue-views/issue_filters.ts @@ -178,39 +178,17 @@ export interface IIssueFilterStore { getProjectIssueFilters: (workspaceId: string, projectId: string) => Promise; - getProjectIssueModuleFilters: ( - workspaceId: string, - projectId: string, - moduleId: string - ) => Promise; + getProjectIssueModuleFilters: (workspaceId: string, projectId: string, moduleId: string) => Promise; updateProjectIssueModuleFilters: ( workspaceId: string, projectId: string, moduleId: string, data: any ) => Promise; - getProjectIssueCyclesFilters: ( - workspaceId: string, - projectId: string, - cycleId: string - ) => Promise; - updateProjectIssueCyclesFilters: ( - workspaceId: string, - projectId: string, - cycleId: string, - data: any - ) => Promise; - getProjectIssueViewsFilters: ( - workspaceId: string, - projectId: string, - viewId: string - ) => Promise; - updateProjectIssueViewsFilters: ( - workspaceId: string, - projectId: string, - viewId: string, - data: any - ) => Promise; + getProjectIssueCyclesFilters: (workspaceId: string, projectId: string, cycleId: string) => Promise; + updateProjectIssueCyclesFilters: (workspaceId: string, projectId: string, cycleId: string, data: any) => Promise; + getProjectIssueViewsFilters: (workspaceId: string, projectId: string, viewId: string) => Promise; + updateProjectIssueViewsFilters: (workspaceId: string, projectId: string, viewId: string, data: any) => Promise; } class IssueFilterStore implements IIssueFilterStore { @@ -323,11 +301,10 @@ class IssueFilterStore implements IIssueFilterStore { // computed get issueLayout() { if (!this.workspaceId) return null; - if (!this.projectId) - return this.issueFilters?.[this.workspaceId]?.my_issue_properties?.display_filters?.layout; + if (!this.projectId) return this.issueFilters?.[this.workspaceId]?.my_issue_properties?.display_filters?.layout; if (this.projectId) - return this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId] - ?.issues?.display_filters?.layout; + return this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]?.issues?.display_filters + ?.layout; } get workspaceProjects() { @@ -341,26 +318,22 @@ class IssueFilterStore implements IIssueFilterStore { get projectStates() { if (!this.workspaceId || !this.projectId) return null; - return this.issueRenderFilters?.workspace_properties?.[this.workspaceId]?.project_properties?.[ - this.projectId - ]?.states; + return this.issueRenderFilters?.workspace_properties?.[this.workspaceId]?.project_properties?.[this.projectId] + ?.states; } get projectLabels() { if (!this.workspaceId || !this.projectId) return null; - return this.issueRenderFilters?.workspace_properties?.[this.workspaceId]?.project_properties?.[ - this.projectId - ]?.labels; + return this.issueRenderFilters?.workspace_properties?.[this.workspaceId]?.project_properties?.[this.projectId] + ?.labels; } get projectMembers() { if (!this.workspaceId || !this.projectId) return null; - return this.issueRenderFilters?.workspace_properties?.[this.workspaceId]?.project_properties?.[ - this.projectId - ]?.members; + return this.issueRenderFilters?.workspace_properties?.[this.workspaceId]?.project_properties?.[this.projectId] + ?.members; } get projectDisplayProperties() { if (!this.workspaceId || !this.projectId) return null; - return this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId] - ?.display_properties as any; + return this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]?.display_properties as any; } get userFilters() { @@ -380,22 +353,17 @@ class IssueFilterStore implements IIssueFilterStore { } = { filters: null, display_filters: - this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]?.issues - ?.display_filters, + this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]?.issues?.display_filters, display_properties_id: - this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId] - ?.display_properties_id, + this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]?.display_properties_id, display_properties: - this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId] - ?.display_properties, + this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]?.display_properties, }; if (this.issueView === "issues") { _issueFilters = { ..._issueFilters, - filters: - this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]?.issues - ?.filters, + filters: this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]?.issues?.filters, }; return _issueFilters; } @@ -404,8 +372,8 @@ class IssueFilterStore implements IIssueFilterStore { _issueFilters = { ..._issueFilters, filters: - this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId] - ?.modules?.[this.moduleId]?.filters, + this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]?.modules?.[this.moduleId] + ?.filters, }; return _issueFilters; } @@ -414,8 +382,8 @@ class IssueFilterStore implements IIssueFilterStore { _issueFilters = { ..._issueFilters, filters: - this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId] - ?.cycles?.[this.cycleId]?.filters, + this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]?.cycles?.[this.cycleId] + ?.filters, }; return _issueFilters; } @@ -424,8 +392,8 @@ class IssueFilterStore implements IIssueFilterStore { _issueFilters = { ..._issueFilters, filters: - this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId] - ?.views?.[this.viewId]?.filters, + this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]?.views?.[this.viewId] + ?.filters, }; return _issueFilters; } @@ -496,12 +464,11 @@ class IssueFilterStore implements IIssueFilterStore { [this.projectId]: { ...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId], issues: { - ...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId] - ?.issues, + ...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]?.issues, [filter_type]: { - ...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[ - this.projectId - ]?.issues?.[filter_type], + ...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]?.issues?.[ + filter_type + ], [filter_key]: value, }, }, @@ -524,17 +491,13 @@ class IssueFilterStore implements IIssueFilterStore { project_issue_properties: { ...this.issueFilters?.[this.workspaceId]?.project_issue_properties, [this.projectId]: { - ...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[ - this.projectId - ], + ...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId], issues: { - ...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[ - this.projectId - ]?.issues, + ...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]?.issues, [filter_type]: { - ...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[ - this.projectId - ]?.issues?.[filter_type], + ...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]?.issues?.[ + filter_type + ], [filter_key]: value, }, }, @@ -556,21 +519,17 @@ class IssueFilterStore implements IIssueFilterStore { project_issue_properties: { ...this.issueFilters?.[this.workspaceId]?.project_issue_properties, [this.projectId]: { - ...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[ - this.projectId - ], + ...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId], modules: { - ...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[ - this.projectId - ]?.modules, + ...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]?.modules, [this.moduleId]: { - ...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[ - this.projectId - ]?.modules?.[this.moduleId], + ...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]?.modules?.[ + this.moduleId + ], [filter_type]: { - ...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[ - this.projectId - ]?.modules?.[this.moduleId]?.[filter_type], + ...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]?.modules?.[ + this.moduleId + ]?.[filter_type], [filter_key]: value, }, }, @@ -595,21 +554,17 @@ class IssueFilterStore implements IIssueFilterStore { project_issue_properties: { ...this.issueFilters?.[this.workspaceId]?.project_issue_properties, [this.projectId]: { - ...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[ - this.projectId - ], + ...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId], cycles: { - ...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[ - this.projectId - ]?.cycles, + ...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]?.cycles, [this.cycleId]: { - ...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[ - this.projectId - ]?.cycles?.[this.cycleId], + ...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]?.cycles?.[ + this.cycleId + ], [filter_type]: { - ...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[ - this.projectId - ]?.cycles?.[this.cycleId]?.[filter_type], + ...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]?.cycles?.[ + this.cycleId + ]?.[filter_type], [filter_key]: value, }, }, @@ -618,12 +573,7 @@ class IssueFilterStore implements IIssueFilterStore { }, }, }; - this.updateProjectIssueCyclesFilters( - this.workspaceId, - this.projectId, - this.cycleId, - this.userFilters?.filters - ); + this.updateProjectIssueCyclesFilters(this.workspaceId, this.projectId, this.cycleId, this.userFilters?.filters); } if (this.issueView === "views" && this.viewId) { @@ -634,21 +584,17 @@ class IssueFilterStore implements IIssueFilterStore { project_issue_properties: { ...this.issueFilters?.[this.workspaceId]?.project_issue_properties, [this.projectId]: { - ...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[ - this.projectId - ], + ...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId], views: { - ...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[ - this.projectId - ]?.views, + ...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]?.views, [this.viewId]: { - ...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[ - this.projectId - ]?.views?.[this.viewId], + ...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]?.views?.[ + this.viewId + ], [filter_type]: { - ...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[ - this.projectId - ]?.views?.[this.viewId]?.[filter_type], + ...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]?.views?.[ + this.viewId + ]?.[filter_type], [filter_key]: value, }, }, @@ -657,12 +603,7 @@ class IssueFilterStore implements IIssueFilterStore { }, }, }; - this.updateProjectIssueViewsFilters( - this.workspaceId, - this.projectId, - this.viewId, - this.userFilters?.filters - ); + this.updateProjectIssueViewsFilters(this.workspaceId, this.projectId, this.viewId, this.userFilters?.filters); } } @@ -671,26 +612,11 @@ class IssueFilterStore implements IIssueFilterStore { if (this.issueView === "issues") this.rootStore?.issueView?.getProjectIssuesAsync(this.workspaceId, this.projectId, false); if (this.issueView === "modules" && this.moduleId) - this.rootStore?.issueView?.getIssuesForModulesAsync( - this.workspaceId, - this.projectId, - this.moduleId, - false - ); + this.rootStore?.issueView?.getIssuesForModulesAsync(this.workspaceId, this.projectId, this.moduleId, false); if (this.issueView === "cycles" && this.cycleId) - this.rootStore?.issueView?.getIssuesForCyclesAsync( - this.workspaceId, - this.projectId, - this.cycleId, - false - ); + this.rootStore?.issueView?.getIssuesForCyclesAsync(this.workspaceId, this.projectId, this.cycleId, false); if (this.issueView === "views" && this.viewId) - this.rootStore?.issueView?.getIssuesForViewsAsync( - this.workspaceId, - this.projectId, - this.viewId, - false - ); + this.rootStore?.issueView?.getIssuesForViewsAsync(this.workspaceId, this.projectId, this.viewId, false); }; computedFilter = (filters: any, filteredParams: any) => { @@ -698,9 +624,7 @@ class IssueFilterStore implements IIssueFilterStore { Object.keys(filters).map((key) => { if (filters[key] != undefined && filteredParams.includes(key)) computedFilters[key] = - typeof filters[key] === "string" || typeof filters[key] === "boolean" - ? filters[key] - : filters[key].join(","); + typeof filters[key] === "string" || typeof filters[key] === "boolean" ? filters[key] : filters[key].join(","); }); return computedFilters; @@ -926,33 +850,25 @@ class IssueFilterStore implements IIssueFilterStore { order_by: issuesFiltersResponse?.view_props?.display_filters?.order_by ?? null, type: issuesFiltersResponse?.view_props?.display_filters?.type ?? null, sub_issue: issuesFiltersResponse?.view_props?.display_filters?.sub_issue ?? false, - show_empty_groups: - issuesFiltersResponse?.view_props?.display_filters?.show_empty_groups ?? false, + show_empty_groups: issuesFiltersResponse?.view_props?.display_filters?.show_empty_groups ?? false, layout: issuesFiltersResponse?.view_props?.display_filters?.layout ?? "list", - calendar_date_range: - issuesFiltersResponse?.view_props?.display_filters?.calendar_date_range ?? false, - start_target_date: - issuesFiltersResponse?.view_props?.display_filters?.start_target_date ?? true, + calendar_date_range: issuesFiltersResponse?.view_props?.display_filters?.calendar_date_range ?? false, + start_target_date: issuesFiltersResponse?.view_props?.display_filters?.start_target_date ?? true, }, display_properties: { assignee: issuesFiltersResponse?.view_props?.display_properties?.assignee ?? false, - attachment_count: - issuesFiltersResponse?.view_props?.display_properties?.attachment_count ?? false, - created_on: - issuesFiltersResponse?.view_props?.display_properties?.created_on ?? false, + attachment_count: issuesFiltersResponse?.view_props?.display_properties?.attachment_count ?? false, + created_on: issuesFiltersResponse?.view_props?.display_properties?.created_on ?? false, due_date: issuesFiltersResponse?.view_props?.display_properties?.due_date ?? false, estimate: issuesFiltersResponse?.view_props?.display_properties?.estimate ?? false, key: issuesFiltersResponse?.view_props?.display_properties?.key ?? false, labels: issuesFiltersResponse?.view_props?.display_properties?.labels ?? false, link: issuesFiltersResponse?.view_props?.display_properties?.link ?? false, priority: issuesFiltersResponse?.view_props?.display_properties?.priority ?? false, - start_date: - issuesFiltersResponse?.view_props?.display_properties?.start_date ?? false, + start_date: issuesFiltersResponse?.view_props?.display_properties?.start_date ?? false, state: issuesFiltersResponse?.view_props?.display_properties?.state ?? false, - sub_issue_count: - issuesFiltersResponse?.view_props?.display_properties?.sub_issue_count ?? false, - updated_on: - issuesFiltersResponse?.view_props?.display_properties?.updated_on ?? false, + sub_issue_count: issuesFiltersResponse?.view_props?.display_properties?.sub_issue_count ?? false, + updated_on: issuesFiltersResponse?.view_props?.display_properties?.updated_on ?? false, }, }, }, @@ -979,10 +895,7 @@ class IssueFilterStore implements IIssueFilterStore { const payload = { view_props: data, }; - const issuesFiltersResponse = await this.workspaceService.updateWorkspaceView( - workspaceId, - payload - ); + const issuesFiltersResponse = await this.workspaceService.updateWorkspaceView(workspaceId, payload); if (issuesFiltersResponse) { runInAction(() => { @@ -1014,8 +927,7 @@ class IssueFilterStore implements IIssueFilterStore { project_properties: { ...this.issueRenderFilters?.workspace_properties?.[workspaceId]?.project_properties, [projectId]: { - ...this.issueRenderFilters?.workspace_properties?.[workspaceId] - ?.project_properties?.[projectId], + ...this.issueRenderFilters?.workspace_properties?.[workspaceId]?.project_properties?.[projectId], states: issuesStateResponse, }, }, @@ -1053,8 +965,7 @@ class IssueFilterStore implements IIssueFilterStore { project_properties: { ...this.issueRenderFilters?.workspace_properties?.[workspaceId]?.project_properties, [projectId]: { - ...this.issueRenderFilters?.workspace_properties?.[workspaceId] - ?.project_properties?.[projectId], + ...this.issueRenderFilters?.workspace_properties?.[workspaceId]?.project_properties?.[projectId], labels: issuesLabelsResponse, }, }, @@ -1081,10 +992,7 @@ class IssueFilterStore implements IIssueFilterStore { this.loader = true; this.error = null; - const issuesMembersResponse = await this.projectService.projectMembers( - workspaceId, - projectId - ); + const issuesMembersResponse = await this.projectService.projectMembers(workspaceId, projectId); if (issuesMembersResponse) { const _issuesMembersResponse = { ...this.issueRenderFilters, @@ -1095,8 +1003,7 @@ class IssueFilterStore implements IIssueFilterStore { project_properties: { ...this.issueRenderFilters?.workspace_properties?.[workspaceId]?.project_properties, [projectId]: { - ...this.issueRenderFilters?.workspace_properties?.[workspaceId] - ?.project_properties?.[projectId], + ...this.issueRenderFilters?.workspace_properties?.[workspaceId]?.project_properties?.[projectId], members: issuesMembersResponse, }, }, @@ -1124,10 +1031,7 @@ class IssueFilterStore implements IIssueFilterStore { this.loader = true; this.error = null; - const issuesDisplayPropertiesResponse = await this.issueService.getIssueProperties( - workspaceId, - projectId - ); + const issuesDisplayPropertiesResponse = await this.issueService.getIssueProperties(workspaceId, projectId); if (issuesDisplayPropertiesResponse) { const _myUserId: string = issuesDisplayPropertiesResponse?.user; @@ -1206,10 +1110,7 @@ class IssueFilterStore implements IIssueFilterStore { this.loader = true; this.error = null; - const issuesDisplayFiltersResponse = await this.projectService.projectMemberMe( - workspaceId, - projectId - ); + const issuesDisplayFiltersResponse = await this.projectService.projectMemberMe(workspaceId, projectId); if (issuesDisplayFiltersResponse) { const _filters = { ...issuesDisplayFiltersResponse?.view_props?.filters }; @@ -1256,11 +1157,7 @@ class IssueFilterStore implements IIssueFilterStore { const payload: any = { view_props: data, }; - const issuesFiltersResponse = await this.projectService.setProjectView( - workspaceId, - projectId, - payload - ); + const issuesFiltersResponse = await this.projectService.setProjectView(workspaceId, projectId, payload); if (issuesFiltersResponse) { runInAction(() => { @@ -1302,22 +1199,14 @@ class IssueFilterStore implements IIssueFilterStore { } }; - getProjectIssueModuleFilters = async ( - workspaceId: string, - projectId: string, - moduleId: string - ) => { + getProjectIssueModuleFilters = async (workspaceId: string, projectId: string, moduleId: string) => { try { this.loader = true; this.error = null; await this.getProjectIssueFilters(workspaceId, projectId); - const issuesFiltersModuleResponse = await this.moduleService.getModuleDetails( - workspaceId, - projectId, - moduleId - ); + const issuesFiltersModuleResponse = await this.moduleService.getModuleDetails(workspaceId, projectId, moduleId); if (issuesFiltersModuleResponse) { const _filters = { ...issuesFiltersModuleResponse?.view_props?.filters }; @@ -1330,11 +1219,9 @@ class IssueFilterStore implements IIssueFilterStore { [projectId]: { ...this?.issueFilters[workspaceId]?.project_issue_properties?.[projectId], modules: { - ...this?.issueFilters[workspaceId]?.project_issue_properties?.[projectId] - ?.modules, + ...this?.issueFilters[workspaceId]?.project_issue_properties?.[projectId]?.modules, [moduleId]: { - ...this?.issueFilters[workspaceId]?.project_issue_properties?.[projectId] - ?.modules?.[moduleId], + ...this?.issueFilters[workspaceId]?.project_issue_properties?.[projectId]?.modules?.[moduleId], filters: { priority: _filters?.priority ?? undefined, state: _filters?.state ?? undefined, @@ -1365,12 +1252,7 @@ class IssueFilterStore implements IIssueFilterStore { return error; } }; - updateProjectIssueModuleFilters = async ( - workspaceId: string, - projectId: string, - moduleId: string, - data: any - ) => { + updateProjectIssueModuleFilters = async (workspaceId: string, projectId: string, moduleId: string, data: any) => { try { this.loader = true; this.error = null; @@ -1401,22 +1283,14 @@ class IssueFilterStore implements IIssueFilterStore { } }; - getProjectIssueCyclesFilters = async ( - workspaceId: string, - projectId: string, - cycleId: string - ) => { + getProjectIssueCyclesFilters = async (workspaceId: string, projectId: string, cycleId: string) => { try { this.loader = true; this.error = null; await this.getProjectIssueFilters(workspaceId, projectId); - const issuesFiltersCycleResponse = await this.cycleService.getCycleDetails( - workspaceId, - projectId, - cycleId - ); + const issuesFiltersCycleResponse = await this.cycleService.getCycleDetails(workspaceId, projectId, cycleId); if (issuesFiltersCycleResponse) { const _filters = { ...issuesFiltersCycleResponse?.view_props?.filters }; @@ -1431,8 +1305,7 @@ class IssueFilterStore implements IIssueFilterStore { cycles: { ...this?.issueFilters[workspaceId]?.project_issue_properties?.[projectId]?.cycles, [cycleId]: { - ...this?.issueFilters[workspaceId]?.project_issue_properties?.[projectId] - ?.modules?.[cycleId], + ...this?.issueFilters[workspaceId]?.project_issue_properties?.[projectId]?.modules?.[cycleId], filters: { priority: _filters?.priority ?? undefined, state: _filters?.state ?? undefined, @@ -1463,12 +1336,7 @@ class IssueFilterStore implements IIssueFilterStore { return error; } }; - updateProjectIssueCyclesFilters = async ( - workspaceId: string, - projectId: string, - cycleId: string, - data: any - ) => { + updateProjectIssueCyclesFilters = async (workspaceId: string, projectId: string, cycleId: string, data: any) => { try { this.loader = true; this.error = null; @@ -1506,11 +1374,7 @@ class IssueFilterStore implements IIssueFilterStore { await this.getProjectIssueFilters(workspaceId, projectId); - const issuesFiltersViewResponse = await this.viewService.getViewDetails( - workspaceId, - projectId, - viewId - ); + const issuesFiltersViewResponse = await this.viewService.getViewDetails(workspaceId, projectId, viewId); if (issuesFiltersViewResponse) { const _filters = { ...issuesFiltersViewResponse?.query_data } as any; @@ -1525,8 +1389,7 @@ class IssueFilterStore implements IIssueFilterStore { views: { ...this?.issueFilters[workspaceId]?.project_issue_properties?.[projectId]?.cycles, [viewId]: { - ...this?.issueFilters[workspaceId]?.project_issue_properties?.[projectId] - ?.modules?.[viewId], + ...this?.issueFilters[workspaceId]?.project_issue_properties?.[projectId]?.modules?.[viewId], filters: { priority: _filters?.priority ?? undefined, state: _filters?.state ?? undefined, @@ -1557,12 +1420,7 @@ class IssueFilterStore implements IIssueFilterStore { return error; } }; - updateProjectIssueViewsFilters = async ( - workspaceId: string, - projectId: string, - viewId: string, - data: any - ) => { + updateProjectIssueViewsFilters = async (workspaceId: string, projectId: string, viewId: string, data: any) => { try { this.loader = true; this.error = null; diff --git a/web/store/issue-views/kanban-view.ts b/web/store/issue-views/kanban-view.ts new file mode 100644 index 000000000..2f8f14e26 --- /dev/null +++ b/web/store/issue-views/kanban-view.ts @@ -0,0 +1,185 @@ +import { action, computed, makeObservable } from "mobx"; +// types +import { RootStore } from "../root"; + +export interface IIssueKanBanViewStore { + handleDragDrop: (source: any, destination: any) => void; +} + +class IssueKanBanViewStore implements IIssueKanBanViewStore { + // root store + rootStore; + + constructor(_rootStore: RootStore) { + makeObservable(this, { + // computed + canUserDragDrop: computed, + canUserDragDropVertically: computed, + canUserDragDropHorizontally: computed, + + // actions + handleDragDrop: action, + }); + + this.rootStore = _rootStore; + } + + get canUserDragDrop() { + if ( + this.rootStore?.issueFilters?.issueView && + this.rootStore?.issueFilters?.userFilters?.display_filters?.group_by && + this.rootStore?.issueFilters?.userFilters?.display_filters?.order_by && + !["my_issues"].includes(this.rootStore?.issueFilters?.issueView) && + ["state", "priority"].includes(this.rootStore?.issueFilters?.userFilters?.display_filters?.group_by) && + this.rootStore?.issueFilters?.userFilters?.display_filters?.order_by === "sort_order" + ) { + return true; + } + return false; + } + get canUserDragDropVertically() { + return true; + } + get canUserDragDropHorizontally() { + return true; + } + + handleDragDrop = async (source: any, destination: any) => { + const workspaceId = this.rootStore?.issueFilters?.workspaceId; + const projectId = this.rootStore?.issueFilters?.projectId; + const issueView = this.rootStore?.issueFilters?.issueView; + const issueLayout = this.rootStore?.issueFilters?.userFilters?.display_filters?.layout; + + const sortOrderDefaultValue = 10000; + + if ( + this.rootStore?.issueView?.getIssues && + workspaceId && + projectId && + issueView && + issueLayout && + issueView != "my_issues" + ) { + const projectSortedIssues: any = + this.rootStore?.issueView.issues?.[workspaceId]?.project_issues?.[projectId]?.[issueView]?.[issueLayout]; + + let updateIssue: any = { + workspaceId: workspaceId, + projectId: projectId, + }; + + // user can drag the issues from any direction + if (this.canUserDragDrop) { + // vertical + if (source.droppableId === destination.droppableId) { + const _columnId = source.droppableId; + const _issues = projectSortedIssues[_columnId]; + + // update the sort order + if (destination.index === 0) { + updateIssue = { ...updateIssue, sort_order: _issues[destination.index].sort_order - sortOrderDefaultValue }; + } else if (destination.index === _issues.length - 1) { + updateIssue = { ...updateIssue, sort_order: _issues[destination.index].sort_order + sortOrderDefaultValue }; + } else { + updateIssue = { + ...updateIssue, + sort_order: (_issues[destination.index - 1].sort_order + _issues[destination.index].sort_order) / 2, + }; + } + + // update the mobx state array + const [removed] = _issues.splice(source.index, 1); + _issues.splice(destination.index, 0, { ...removed, sort_order: updateIssue.sort_order }); + updateIssue = { ...updateIssue, issueId: removed?.id }; + + projectSortedIssues[_columnId] = _issues; + } + + // horizontal + if (source.droppableId != destination.droppableId) { + const _sourceColumnId = source.droppableId; + const _destinationColumnId = destination.droppableId; + + const _sourceIssues = projectSortedIssues[_sourceColumnId]; + const _destinationIssues = projectSortedIssues[_destinationColumnId]; + + if (_destinationIssues.length > 0) { + if (destination.index === 0) { + updateIssue = { + ...updateIssue, + sort_order: _destinationIssues[destination.index].sort_order - sortOrderDefaultValue, + state: destination?.droppableId, + }; + } else if (destination.index === _destinationIssues.length - 1) { + updateIssue = { + ...updateIssue, + sort_order: _destinationIssues[destination.index].sort_order + sortOrderDefaultValue, + state: destination?.droppableId, + }; + } else { + updateIssue = { + ...updateIssue, + sort_order: + (_destinationIssues[destination.index - 1].sort_order + + _destinationIssues[destination.index].sort_order) / + 2, + state: destination?.droppableId, + }; + } + } else { + updateIssue = { + ...updateIssue, + sort_order: sortOrderDefaultValue, + state: destination?.droppableId, + }; + } + + const [removed] = _sourceIssues.splice(source.index, 1); + _destinationIssues.splice(destination.index, 0, { + ...removed, + state: destination?.droppableId, + sort_order: updateIssue.sort_order, + }); + updateIssue = { ...updateIssue, issueId: removed?.id }; + + projectSortedIssues[_sourceColumnId] = _sourceIssues; + projectSortedIssues[_destinationColumnId] = _destinationIssues; + } + } + + // user can drag the issues only vertically + if (this.canUserDragDropVertically && source.droppableId === destination.droppableId) { + } + + // user can drag the issues only horizontally + if (this.canUserDragDropHorizontally && source.droppableId != destination.droppableId) { + } + + this.rootStore.issueView.issues = { + ...this.rootStore?.issueView.issues, + [workspaceId]: { + ...this.rootStore?.issueView.issues?.[workspaceId], + project_issues: { + ...this.rootStore?.issueView.issues?.[workspaceId]?.project_issues, + [projectId]: { + ...this.rootStore?.issueView.issues?.[workspaceId]?.project_issues?.[projectId], + [issueView]: { + ...this.rootStore?.issueView.issues?.[workspaceId]?.project_issues?.[projectId]?.[issueView], + [issueLayout]: projectSortedIssues, + }, + }, + }, + }, + }; + + this.rootStore.issueDetail?.updateIssueAsync( + updateIssue.workspaceId, + updateIssue.projectId, + updateIssue.issueId, + updateIssue + ); + } + }; +} + +export default IssueKanBanViewStore; diff --git a/web/store/root.ts b/web/store/root.ts index 9f4fd1d83..90a9ef870 100644 --- a/web/store/root.ts +++ b/web/store/root.ts @@ -9,6 +9,8 @@ import IssuesStore from "./issues"; // issues views and filters import IssueFilterStore from "./issue-views/issue_filters"; import IssueViewStore from "./issue-views/Issues"; +import IssueViewDetailStore from "./issue-views/issue_detail"; +import IssueKanBanViewStore from "./issue-views/kanban-view"; enableStaticRendering(typeof window === "undefined"); @@ -20,6 +22,8 @@ export class RootStore { issues: IssuesStore; issueFilters: IssueFilterStore; issueView: IssueViewStore; + issueDetail: IssueViewDetailStore; + issueKanBanView: IssueKanBanViewStore; constructor() { this.user = new UserStore(this); @@ -29,5 +33,7 @@ export class RootStore { this.issues = new IssuesStore(this); this.issueFilters = new IssueFilterStore(this); this.issueView = new IssueViewStore(this); + this.issueDetail = new IssueViewDetailStore(this); + this.issueKanBanView = new IssueKanBanViewStore(this); } }