diff --git a/web/components/issue-layouts/display-filters/extra-options.tsx b/web/components/issue-layouts/display-filters/extra-options.tsx index 58cbf193f..e4f127627 100644 --- a/web/components/issue-layouts/display-filters/extra-options.tsx +++ b/web/components/issue-layouts/display-filters/extra-options.tsx @@ -8,7 +8,7 @@ import { observer } from "mobx-react-lite"; import { useMobxStore } from "lib/mobx/store-provider"; import { RootStore } from "store/root"; // default data -import { issueFilterVisibilityData } from "store/issue-views/issue_data"; +import { issueFilterVisibilityData } from "store/helpers/issue-data"; export const FilterExtraOptions = observer(() => { const store: RootStore = useMobxStore(); diff --git a/web/components/issue-layouts/display-filters/index.tsx b/web/components/issue-layouts/display-filters/index.tsx index c4a81bc3c..b8de6e513 100644 --- a/web/components/issue-layouts/display-filters/index.tsx +++ b/web/components/issue-layouts/display-filters/index.tsx @@ -11,7 +11,7 @@ import { observer } from "mobx-react-lite"; import { useMobxStore } from "lib/mobx/store-provider"; import { RootStore } from "store/root"; // default data -import { issueFilterVisibilityData } from "store/issue-views/issue_data"; +import { issueFilterVisibilityData } from "store/helpers/issue-data"; export const DisplayFiltersSelection = observer(() => { const store: RootStore = useMobxStore(); diff --git a/web/components/issue-layouts/filters-preview/index.tsx b/web/components/issue-layouts/filters-preview/index.tsx index 03aac5b66..2ecdc5909 100644 --- a/web/components/issue-layouts/filters-preview/index.tsx +++ b/web/components/issue-layouts/filters-preview/index.tsx @@ -14,7 +14,7 @@ import { observer } from "mobx-react-lite"; import { useMobxStore } from "lib/mobx/store-provider"; import { RootStore } from "store/root"; // default data -import { issueFilterVisibilityData } from "store/issue-views/issue_data"; +import { issueFilterVisibilityData } from "store/helpers/issue-data"; export const FilterPreview = observer(() => { const store: RootStore = useMobxStore(); diff --git a/web/components/issue-layouts/filters-preview/state.tsx b/web/components/issue-layouts/filters-preview/state.tsx index f81e6e29f..dd0652e78 100644 --- a/web/components/issue-layouts/filters-preview/state.tsx +++ b/web/components/issue-layouts/filters-preview/state.tsx @@ -10,7 +10,7 @@ import { observer } from "mobx-react-lite"; import { useMobxStore } from "lib/mobx/store-provider"; import { RootStore } from "store/root"; // store default data -import { stateGroups } from "store/issue-views/issue_data"; +import { stateGroups } from "store/helpers/issue-data"; export const FilterState = observer(() => { const store: RootStore = useMobxStore(); diff --git a/web/components/issue-layouts/filters/index.tsx b/web/components/issue-layouts/filters/index.tsx index 2512ae042..c52cf5be1 100644 --- a/web/components/issue-layouts/filters/index.tsx +++ b/web/components/issue-layouts/filters/index.tsx @@ -14,7 +14,7 @@ import { observer } from "mobx-react-lite"; import { useMobxStore } from "lib/mobx/store-provider"; import { RootStore } from "store/root"; // default data -import { issueFilterVisibilityData } from "store/issue-views/issue_data"; +import { issueFilterVisibilityData } from "store/helpers/issue-data"; export const FilterSelection = observer(() => { const store: RootStore = useMobxStore(); diff --git a/web/components/issue-layouts/filters/state.tsx b/web/components/issue-layouts/filters/state.tsx index 02c1d745e..ef59fa0ca 100644 --- a/web/components/issue-layouts/filters/state.tsx +++ b/web/components/issue-layouts/filters/state.tsx @@ -9,7 +9,7 @@ import { observer } from "mobx-react-lite"; import { useMobxStore } from "lib/mobx/store-provider"; import { RootStore } from "store/root"; // store default data -import { stateGroups } from "store/issue-views/issue_data"; +import { stateGroups } from "store/helpers/issue-data"; export const FilterState = observer(() => { const store: RootStore = useMobxStore(); diff --git a/web/components/issue-layouts/layout-selection.tsx b/web/components/issue-layouts/layout-selection.tsx index 5e1890851..32ae742d8 100644 --- a/web/components/issue-layouts/layout-selection.tsx +++ b/web/components/issue-layouts/layout-selection.tsx @@ -7,8 +7,8 @@ import { observer } from "mobx-react-lite"; import { RootStore } from "store/root"; import { useMobxStore } from "lib/mobx/store-provider"; // types and default data -import { TIssueLayouts } from "store/issue-views/issue_filters"; -import { issueFilterVisibilityData } from "store/issue-views/issue_data"; +import { TIssueLayouts } from "store/issue-filters"; +import { issueFilterVisibilityData } from "store/helpers/issue-data"; export const LayoutSelection = observer(() => { const store: RootStore = useMobxStore(); diff --git a/web/components/issue-layouts/root.tsx b/web/components/issue-layouts/root.tsx index 92cbf5493..1db144bd9 100644 --- a/web/components/issue-layouts/root.tsx +++ b/web/components/issue-layouts/root.tsx @@ -19,7 +19,42 @@ import { useMobxStore } from "lib/mobx/store-provider"; import { RootStore } from "store/root"; export const IssuesRoot = observer(() => { - const { issueFilters: issueFilterStore }: RootStore = useMobxStore(); + const { + workspace: workspaceStore, + project: projectStore, + issue: issueStore, + issueFilter: issueFilterStore, + }: RootStore = useMobxStore(); + + // console.log("---"); + // console.log("--- workspace store"); + // console.log("workspaces", workspaceStore?.workspaces); + // console.log("workspace id", workspaceStore?.workspaceId); + // console.log("current workspace", workspaceStore?.currentWorkspace); + // console.log("workspace by id", workspaceStore?.workspaceById("plane")); + // console.log("workspace labels", workspaceStore?.workspaceLabels); + // console.log("workspace label by id", workspaceStore?.workspaceLabelById("1fe1031b-8986-4e6a-86cc-0d2fe3ac272f")); + + // console.log("--- project store"); + // console.log("workspace projects", projectStore?.workspaceProjects); + // console.log("project id", projectStore?.projectId); + // console.log("project state by groups", projectStore?.projectStatesByGroups); + // console.log("project states", projectStore?.projectStates); + // console.log("project labels", projectStore?.projectLabels); + // console.log("project members", projectStore?.projectMembers); + // projectStore?.projectStates && + // console.log("project state by id", projectStore?.projectStateById(projectStore?.projectStates?.[0]?.id)); + // projectStore?.projectLabels && + // console.log("project label by id", projectStore?.projectLabelById(projectStore?.projectLabels?.[0]?.id)); + // projectStore?.projectMembers && + // console.log("project member by id", projectStore?.projectMemberById(projectStore?.projectMembers?.[0]?.id)); + + // console.log("--- issue filter store"); + // console.log("issues filters", issueFilterStore?.issueFilters); + + // console.log("--- issue store"); + // console.log("issues", issueStore?.issues); + // console.log("---"); return (
diff --git a/web/layouts/auth-layout/workspace-authorization-wrapper.tsx b/web/layouts/auth-layout/workspace-authorization-wrapper.tsx index 9d74c9135..6dbb0cde9 100644 --- a/web/layouts/auth-layout/workspace-authorization-wrapper.tsx +++ b/web/layouts/auth-layout/workspace-authorization-wrapper.tsx @@ -115,9 +115,7 @@ export const WorkspaceAuthorizationLayout: React.FC = ({ noHeader={noHeader} />
-
- {children} -
+
{children}
)} 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 c068f14f6..44f143b22 100644 --- a/web/pages/m-store/[workspace_slug]/[project_slug]/issues.tsx +++ b/web/pages/m-store/[workspace_slug]/[project_slug]/issues.tsx @@ -14,15 +14,26 @@ const KanBanViewRoot = () => { project_slug: string; }; - const store: RootStore = useMobxStore(); - const { issueView: issueViewStore } = store; + const { issue: issueViewStore, workspace: workspaceStore, project: projectStore }: RootStore = useMobxStore(); React.useEffect(() => { console.log("request init--->"); - const init = async () => await issueViewStore.getProjectIssuesAsync(workspace_slug, project_slug); + const init = async () => { + workspaceStore.setWorkspaceId(workspace_slug); + await workspaceStore.getWorkspaces(); + await workspaceStore.getWorkspaceLabels(workspace_slug); + + projectStore.setProject(project_slug); + await projectStore.getWorkspaceProjects(workspace_slug); + await projectStore.getProjectStates(workspace_slug, project_slug); + await projectStore.getProjectLabels(workspace_slug, project_slug); + await projectStore.getProjectMembers(workspace_slug, project_slug); + + await issueViewStore.getProjectIssuesAsync(workspace_slug, project_slug); + }; if (workspace_slug && project_slug) init(); console.log("request completed--->"); - }, [workspace_slug, project_slug, issueViewStore]); + }, [workspace_slug, project_slug, issueViewStore, workspaceStore, projectStore]); return (
diff --git a/web/services/project.service.ts b/web/services/project.service.ts index 8f2508b74..e61545704 100644 --- a/web/services/project.service.ts +++ b/web/services/project.service.ts @@ -87,11 +87,7 @@ export class ProjectServices extends APIService { }); } - async deleteProject( - workspaceSlug: string, - projectId: string, - user: ICurrentUserResponse | undefined - ): Promise { + async deleteProject(workspaceSlug: string, projectId: string, user: ICurrentUserResponse | undefined): Promise { return this.delete(`/api/workspaces/${workspaceSlug}/projects/${projectId}/`) .then((response) => { trackEventServices.trackProjectEvent({ projectId }, "DELETE_PROJECT", user); @@ -136,11 +132,7 @@ export class ProjectServices extends APIService { }); } - async leaveProject( - workspaceSlug: string, - projectId: string, - user: ICurrentUserResponse - ): Promise { + async leaveProject(workspaceSlug: string, projectId: string, user: ICurrentUserResponse): Promise { return this.delete(`/api/workspaces/${workspaceSlug}/projects/${projectId}/members/leave/`) .then((response) => { trackEventServices.trackProjectEvent( @@ -175,10 +167,7 @@ export class ProjectServices extends APIService { }); } - async projectMembersWithEmail( - workspaceSlug: string, - projectId: string - ): Promise { + async projectMembersWithEmail(workspaceSlug: string, projectId: string): Promise { return this.get(`/api/workspaces/${workspaceSlug}/projects/${projectId}/members/`) .then((response) => response?.data) .catch((error) => { @@ -194,11 +183,7 @@ export class ProjectServices extends APIService { }); } - async getProjectMember( - workspaceSlug: string, - projectId: string, - memberId: string - ): Promise { + async getProjectMember(workspaceSlug: string, projectId: string, memberId: string): Promise { return this.get(`/api/workspaces/${workspaceSlug}/projects/${projectId}/members/${memberId}/`) .then((response) => response?.data) .catch((error) => { @@ -212,34 +197,22 @@ export class ProjectServices extends APIService { memberId: string, data: Partial ): Promise { - return this.patch( - `/api/workspaces/${workspaceSlug}/projects/${projectId}/members/${memberId}/`, - data - ) + return this.patch(`/api/workspaces/${workspaceSlug}/projects/${projectId}/members/${memberId}/`, data) .then((response) => response?.data) .catch((error) => { throw error?.response?.data; }); } - async deleteProjectMember( - workspaceSlug: string, - projectId: string, - memberId: string - ): Promise { - return this.delete( - `/api/workspaces/${workspaceSlug}/projects/${projectId}/members/${memberId}/` - ) + async deleteProjectMember(workspaceSlug: string, projectId: string, memberId: string): Promise { + return this.delete(`/api/workspaces/${workspaceSlug}/projects/${projectId}/members/${memberId}/`) .then((response) => response?.data) .catch((error) => { throw error?.response?.data; }); } - async projectInvitations( - workspaceSlug: string, - projectId: string - ): Promise { + async projectInvitations(workspaceSlug: string, projectId: string): Promise { return this.get(`/api/workspaces/${workspaceSlug}/projects/${projectId}/invitations/`) .then((response) => response?.data) .catch((error) => { @@ -247,10 +220,7 @@ export class ProjectServices extends APIService { }); } - async projectInvitationsWithEmail( - workspaceSlug: string, - projectId: string - ): Promise { + async projectInvitationsWithEmail(workspaceSlug: string, projectId: string): Promise { return this.get(`/api/workspaces/${workspaceSlug}/projects/${projectId}/invitations/`) .then((response) => response?.data) .catch((error) => { @@ -258,28 +228,16 @@ export class ProjectServices extends APIService { }); } - async updateProjectInvitation( - workspaceSlug: string, - projectId: string, - invitationId: string - ): Promise { - return this.put( - `/api/workspaces/${workspaceSlug}/projects/${projectId}/invitations/${invitationId}/` - ) + async updateProjectInvitation(workspaceSlug: string, projectId: string, invitationId: string): Promise { + return this.put(`/api/workspaces/${workspaceSlug}/projects/${projectId}/invitations/${invitationId}/`) .then((response) => response?.data) .catch((error) => { throw error?.response?.data; }); } - async deleteProjectInvitation( - workspaceSlug: string, - projectId: string, - invitationId: string - ): Promise { - return this.delete( - `/api/workspaces/${workspaceSlug}/projects/${projectId}/invitations/${invitationId}/` - ) + async deleteProjectInvitation(workspaceSlug: string, projectId: string, invitationId: string): Promise { + return this.delete(`/api/workspaces/${workspaceSlug}/projects/${projectId}/invitations/${invitationId}/`) .then((response) => response?.data) .catch((error) => { throw error?.response?.data; @@ -332,11 +290,7 @@ export class ProjectServices extends APIService { }); } - async getProjectGithubRepository( - workspaceSlug: string, - projectId: string, - integrationId: string - ): Promise { + async getProjectGithubRepository(workspaceSlug: string, projectId: string, integrationId: string): Promise { return this.get( `/api/workspaces/${workspaceSlug}/projects/${projectId}/workspace-integrations/${integrationId}/github-repository-sync/` ) diff --git a/web/services/workspace.service.ts b/web/services/workspace.service.ts index a07345522..a9a8c4595 100644 --- a/web/services/workspace.service.ts +++ b/web/services/workspace.service.ts @@ -37,10 +37,7 @@ export class WorkspaceService extends APIService { }); } - async createWorkspace( - data: Partial, - user: ICurrentUserResponse | undefined - ): Promise { + async createWorkspace(data: Partial, user: ICurrentUserResponse | undefined): Promise { return this.post("/api/workspaces/", data) .then((response) => { trackEventServices.trackWorkspaceEvent(response.data, "CREATE_WORKSPACE", user); @@ -66,10 +63,7 @@ export class WorkspaceService extends APIService { }); } - async deleteWorkspace( - workspaceSlug: string, - user: ICurrentUserResponse | undefined - ): Promise { + async deleteWorkspace(workspaceSlug: string, user: ICurrentUserResponse | undefined): Promise { return this.delete(`/api/workspaces/${workspaceSlug}/`) .then((response) => { trackEventServices.trackWorkspaceEvent({ workspaceSlug }, "DELETE_WORKSPACE", user); @@ -101,13 +95,9 @@ export class WorkspaceService extends APIService { data: any, user: ICurrentUserResponse | undefined ): Promise { - return this.post( - `/api/users/me/invitations/workspaces/${workspaceSlug}/${invitationId}/join/`, - data, - { - headers: {}, - } - ) + return this.post(`/api/users/me/invitations/workspaces/${workspaceSlug}/${invitationId}/join/`, data, { + headers: {}, + }) .then((response) => { trackEventServices.trackWorkspaceEvent(response.data, "WORKSPACE_USER_INVITE_ACCEPT", user); return response?.data; @@ -165,10 +155,7 @@ export class WorkspaceService extends APIService { }); } - async updateWorkspaceView( - workspaceSlug: string, - data: { view_props: IWorkspaceViewProps } - ): Promise { + async updateWorkspaceView(workspaceSlug: string, data: { view_props: IWorkspaceViewProps }): Promise { return this.post(`/api/workspaces/${workspaceSlug}/workspace-views/`, data) .then((response) => response?.data) .catch((error) => { @@ -204,9 +191,7 @@ export class WorkspaceService extends APIService { }); } - async workspaceInvitationsWithEmail( - workspaceSlug: string - ): Promise { + async workspaceInvitationsWithEmail(workspaceSlug: string): Promise { return this.get(`/api/workspaces/${workspaceSlug}/invitations/`) .then((response) => response?.data) .catch((error) => { diff --git a/web/store/cycles.ts b/web/store/cycles.ts new file mode 100644 index 000000000..90f139578 --- /dev/null +++ b/web/store/cycles.ts @@ -0,0 +1,55 @@ +import { action, computed, observable, makeObservable, runInAction } from "mobx"; +// types +import { RootStore } from "./root"; +// services +import { ProjectServices } from "services/project.service"; +import { ProjectIssuesServices as IssueServices } from "services/issues.service"; + +export interface ICycleStore { + loader: boolean; + error: any | null; + + cycleId: string | null; + + setCycleId: (cycleSlug: string) => void; +} + +class CycleStore implements ICycleStore { + loader: boolean = false; + error: any | null = null; + + cycleId: string | null = null; + + // root store + rootStore; + // services + projectService; + issueService; + + constructor(_rootStore: RootStore) { + makeObservable(this, { + loader: observable, + error: observable.ref, + + cycleId: observable.ref, + + // computed + + // actions + setCycleId: action, + }); + + this.rootStore = _rootStore; + this.projectService = new ProjectServices(); + this.issueService = new IssueServices(); + } + + // computed + + // actions + setCycleId = (cycleSlug: string) => { + this.cycleId = cycleSlug ?? null; + }; +} + +export default CycleStore; diff --git a/web/store/issue-views/issue_data.ts b/web/store/helpers/issue-data.ts similarity index 99% rename from web/store/issue-views/issue_data.ts rename to web/store/helpers/issue-data.ts index 3b127a272..cd84b5c17 100644 --- a/web/store/issue-views/issue_data.ts +++ b/web/store/helpers/issue-data.ts @@ -1,6 +1,6 @@ import { renderDateFormat } from "helpers/date-time.helper"; // types -import { TIssueLayouts, TIssueParams } from "./issue_filters"; +import { TIssueLayouts, TIssueParams } from "../issue-filters"; export type TStateGroup = "backlog" | "unstarted" | "started" | "completed" | "cancelled"; diff --git a/web/store/issue-filters.ts b/web/store/issue-filters.ts new file mode 100644 index 000000000..203e83646 --- /dev/null +++ b/web/store/issue-filters.ts @@ -0,0 +1,1085 @@ +import { observable, action, computed, makeObservable, runInAction } from "mobx"; +// types +import { RootStore } from "./root"; +// services +import { WorkspaceService } from "services/workspace.service"; +import { ProjectIssuesServices } from "services/issues.service"; +import { ProjectStateServices } from "services/state.service"; +import { ProjectServices } from "services/project.service"; +import { ProjectIssuesServices as ProjectModuleServices } from "services/modules.service"; +import { ProjectCycleServices } from "services/cycles.service"; +import { ViewServices as ProjectViewServices } from "services/views.service"; +// default data +import { + priorities, + stateGroups, + startDateOptions, + dueDateOptions, + groupByOptions, + orderByOptions, + issueTypes, + displayProperties, + extraProperties, + handleIssueQueryParamsByLayout, +} from "./helpers/issue-data"; + +export type TIssueViews = "issues" | "modules" | "views" | "cycles"; +export type TIssueLayouts = "list" | "kanban" | "calendar" | "spreadsheet" | "gantt_chart"; +export type TIssueParams = + | "priority" + | "state_group" + | "state" + | "assignees" + | "created_by" + | "labels" + | "start_date" + | "target_date" + | "group_by" + | "order_by" + | "type" + | "sub_issue" + | "show_empty_groups" + | "calendar_date_range" + | "start_target_date"; + +export interface IIssueFilter { + priority: string[] | undefined; + state_group: string[] | undefined; + state: string[] | undefined; + assignees: string[] | undefined; + created_by: string[] | undefined; + labels: string[] | undefined; + start_date: string[] | undefined; + target_date: string[] | undefined; + [key: string]: any; +} + +export interface IIssueDisplayFilters { + group_by: undefined | string; + order_by: undefined | string; + type: string | undefined; + sub_issue: boolean; + show_empty_groups: boolean; + layout: TIssueLayouts; + calendar_date_range: string | undefined; // only for calendar + start_target_date: boolean; + [key: string]: any; +} + +export interface IIssueDisplayProperties { + assignee: boolean; + attachment_count: boolean; + created_on: boolean; + due_date: boolean; + estimate: boolean; + key: boolean; + labels: boolean; + link: boolean; + priority: boolean; + start_date: boolean; + state: boolean; + sub_issue_count: boolean; + updated_on: boolean; + [key: string]: any; +} + +export interface IIssueFilters { + // project_id + [key: string]: { + issues: { + // project_id + [key: string]: { + filters: IIssueFilter; + }; + }; + cycles: { + // cycle_id + [key: string]: { + filters: IIssueFilter; + }; + }; + modules: { + // module_id + [key: string]: { + filters: IIssueFilter; + }; + }; + views: { + // view_id + [key: string]: { + filters: IIssueFilter; + }; + }; + display_filters: IIssueDisplayFilters; + display_properties_id: string; + display_properties: IIssueDisplayProperties; + }; +} + +export interface IIssueFilterStore { + // static data + priorities: { key: string; title: string }[]; + stateGroups: { key: string; title: string }[]; + startDateOptions: { key: string; title: string }[]; + dueDateOptions: { key: string; title: string }[]; + groupByOptions: { key: string; title: string }[]; + orderByOptions: { key: string; title: string }[]; + issueTypes: { key: string; title: string }[]; + displayProperties: { key: string; title: string }[]; + extraProperties: { key: string; title: string }[]; + + loader: boolean; + error: any | null; + + // current workspace and project id + issueView: TIssueViews | null; + issueFilters: IIssueFilters; + + // actions + // getWorkspaceMyIssuesFilters: (workspaceId: string) => Promise; + // updateWorkspaceMyIssuesFilters: (workspaceId: string, data: any) => Promise; + + getProjectDisplayProperties: (workspaceId: string, projectId: string) => Promise; + updateProjectDisplayProperties: ( + workspaceId: string, + projectId: string, + display_properties_id: string, + data: any + ) => Promise; + getProjectDisplayFilters: (workspaceId: string, projectId: string) => Promise; + updateProjectDisplayFilters: (workspaceId: string, projectId: string, data: any) => Promise; + + getProjectIssueFilters: (workspaceId: string, projectId: 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; +} + +class IssueFilterStore implements IIssueFilterStore { + // static data + priorities: { key: string; title: string }[] = priorities; + stateGroups: { key: string; title: string }[] = stateGroups; + startDateOptions: { key: string; title: string }[] = startDateOptions; + dueDateOptions: { key: string; title: string }[] = dueDateOptions; + groupByOptions: { key: string; title: string }[] = groupByOptions; + orderByOptions: { key: string; title: string }[] = orderByOptions; + issueTypes: { key: string; title: string }[] = issueTypes; + displayProperties: { key: string; title: string }[] = displayProperties; + extraProperties: { key: string; title: string }[] = extraProperties; + + loader: boolean = false; + error: any | null = null; + + // workspaceId: string | null = null; + // projectId: string | null = null; + // moduleId: string | null = null; + // cycleId: string | null = null; + // viewId: string | null = null; + + issueView: TIssueViews | null = null; + + issueFilters: IIssueFilters = {}; + + // root store + rootStore; + // service + workspaceService; + issueService; + stateService; + projectService; + moduleService; + cycleService; + viewService; + + constructor(_rootStore: RootStore) { + makeObservable(this, { + // observable + loader: observable, + error: observable, + + issueView: observable, + + issueFilters: observable.ref, + + // computed + issueLayout: computed, + projectDisplayProperties: computed, + userFilters: computed, + + // actions + getComputedFilters: action, + + handleUserFilter: action, + + // getWorkspaceMyIssuesFilters: action, + // updateWorkspaceMyIssuesFilters: action, + + getProjectDisplayFilters: action, + updateProjectDisplayFilters: action, + + getProjectDisplayProperties: action, + updateProjectDisplayProperties: action, + + getProjectIssueFilters: action, + + getProjectIssueModuleFilters: action, + updateProjectIssueModuleFilters: action, + + getProjectIssueCyclesFilters: action, + updateProjectIssueCyclesFilters: action, + + getProjectIssueViewsFilters: action, + updateProjectIssueViewsFilters: action, + }); + + this.rootStore = _rootStore; + this.workspaceService = new WorkspaceService(); + this.issueService = new ProjectIssuesServices(); + this.stateService = new ProjectStateServices(); + this.projectService = new ProjectServices(); + this.moduleService = new ProjectModuleServices(); + this.cycleService = new ProjectCycleServices(); + this.viewService = new ProjectViewServices(); + } + + // computed + get issueLayout() { + // if (!this.projectId) return null; + // if (!this.projectId) + // return this.issueFilters?.[this.workspaceId]?.my_issue_properties?.display_filters?.layout || null; + // if (this.projectId) + // return ( + // this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]?.issues?.display_filters + // ?.layout || null + // ); + + return null; + } + + get projectDisplayProperties() { + // if (!this.workspaceId || !this.projectId) return null; + // return this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]?.display_properties as any; + + return null; + } + + get userFilters() { + if (!this.projectId) return null; + if (this.issueView === "my_issues") + return { + ...this.issueFilters?.[this.workspaceId]?.my_issue_properties, + display_properties_id: null, + }; + + if (!this.projectId) return null; + let _issueFilters: { + filters: IIssueFilter | null; + display_filters: IIssueDisplayFilters; + display_properties_id: string; + display_properties: IIssueDisplayProperties; + } = { + filters: null, + 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, + 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, + }; + return _issueFilters; + } + + if (this.issueView === "modules" && this.moduleId) { + _issueFilters = { + ..._issueFilters, + filters: + this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]?.modules?.[this.moduleId] + ?.filters, + }; + return _issueFilters; + } + + if (this.issueView === "cycles" && this.cycleId) { + _issueFilters = { + ..._issueFilters, + filters: + this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]?.cycles?.[this.cycleId] + ?.filters, + }; + return _issueFilters; + } + + if (this.issueView === "views" && this.viewId) { + _issueFilters = { + ..._issueFilters, + filters: + this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]?.views?.[this.viewId] + ?.filters, + }; + return _issueFilters; + } + + return null; + } + handleUserFilter = ( + filter_type: "filters" | "display_filters" | "display_properties", + filter_key: string, + value: any + ) => { + // if (!this.workspaceId) return null; + // if (this.issueView === "my_issues") { + // this.issueFilters = { + // ...this.issueFilters, + // [this.workspaceId]: { + // ...this.issueFilters?.[this.workspaceId], + // my_issue_properties: { + // ...this.issueFilters?.[this.workspaceId]?.my_issue_properties, + // [filter_type]: { + // ...this.issueFilters?.[this.workspaceId]?.my_issue_properties?.[filter_type], + // [filter_key]: value, + // }, + // }, + // }, + // }; + // this.updateWorkspaceMyIssuesFilters(this.workspaceId, this.userFilters); + // } + // if (!this.projectId) return null; + // if (filter_type === "display_properties") { + // this.issueFilters = { + // ...this.issueFilters, + // [this.workspaceId]: { + // ...this.issueFilters?.[this.workspaceId], + // project_issue_properties: { + // ...this.issueFilters?.[this.workspaceId]?.project_issue_properties, + // [this.projectId]: { + // ...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId], + // display_properties: { + // ...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId] + // ?.display_properties, + // [filter_key]: value, + // }, + // }, + // }, + // }, + // }; + // if (this.userFilters?.display_properties_id) { + // this.updateProjectDisplayProperties( + // this.workspaceId, + // this.projectId, + // this.userFilters?.display_properties_id, + // this.userFilters?.display_properties + // ); + // } + // } + // if (filter_type === "display_filters") { + // this.issueFilters = { + // ...this.issueFilters, + // [this.workspaceId]: { + // ...this.issueFilters?.[this.workspaceId], + // project_issue_properties: { + // ...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, + // [filter_type]: { + // ...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]?.issues?.[ + // filter_type + // ], + // [filter_key]: value, + // }, + // }, + // }, + // }, + // }, + // }; + // this.updateProjectDisplayFilters(this.workspaceId, this.projectId, { + // filters: this.userFilters?.filters, + // display_filters: this.userFilters?.display_filters, + // }); + // } + // if (filter_type === "filters") { + // if (this.issueView === "issues") { + // this.issueFilters = { + // ...this.issueFilters, + // [this.workspaceId]: { + // ...this.issueFilters?.[this.workspaceId], + // project_issue_properties: { + // ...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, + // [filter_type]: { + // ...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]?.issues?.[ + // filter_type + // ], + // [filter_key]: value, + // }, + // }, + // }, + // }, + // }, + // }; + // this.updateProjectDisplayFilters(this.workspaceId, this.projectId, { + // filters: this.userFilters?.filters, + // display_filters: this.userFilters?.display_filters, + // }); + // } + // if (this.issueView === "modules" && this.moduleId) { + // this.issueFilters = { + // ...this.issueFilters, + // [this.workspaceId]: { + // ...this.issueFilters?.[this.workspaceId], + // project_issue_properties: { + // ...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.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], + // [filter_key]: value, + // }, + // }, + // }, + // }, + // }, + // }, + // }; + // this.updateProjectIssueModuleFilters( + // this.workspaceId, + // this.projectId, + // this.moduleId, + // this.userFilters?.filters + // ); + // } + // if (this.issueView === "cycles" && this.cycleId) { + // this.issueFilters = { + // ...this.issueFilters, + // [this.workspaceId]: { + // ...this.issueFilters?.[this.workspaceId], + // project_issue_properties: { + // ...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.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], + // [filter_key]: value, + // }, + // }, + // }, + // }, + // }, + // }, + // }; + // this.updateProjectIssueCyclesFilters(this.workspaceId, this.projectId, this.cycleId, this.userFilters?.filters); + // } + // if (this.issueView === "views" && this.viewId) { + // this.issueFilters = { + // ...this.issueFilters, + // [this.workspaceId]: { + // ...this.issueFilters?.[this.workspaceId], + // project_issue_properties: { + // ...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.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], + // [filter_key]: value, + // }, + // }, + // }, + // }, + // }, + // }, + // }; + // this.updateProjectIssueViewsFilters(this.workspaceId, this.projectId, this.viewId, this.userFilters?.filters); + // } + // } + // if (this.issueView === "my_issues") + // this.rootStore?.issueView?.getProjectIssuesAsync(this.workspaceId, this.projectId, false); + // 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); + // if (this.issueView === "cycles" && this.cycleId) + // 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); + }; + + computedFilter = (filters: any, filteredParams: any) => { + const computedFilters: any = {}; + 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(","); + }); + + return computedFilters; + }; + getComputedFilters = ( + _workspaceId: string | null, + _projectId: string | null, + _moduleId: string | null, + _cycleId: string | null, + _viewId: string | null, + _issueView: TIssueViews + ) => { + this.issueView = _issueView; + + // const _layout = this.userFilters?.display_filters?.layout; + const _layout = ""; + + let filteredRouteParams: any = { + // priority: this.userFilters?.filters?.priority || undefined, + // state_group: this.userFilters?.filters?.state_group || undefined, + // state: this.userFilters?.filters?.state || undefined, + // assignees: this.userFilters?.filters?.assignees || undefined, + // created_by: this.userFilters?.filters?.created_by || undefined, + // labels: this.userFilters?.filters?.labels || undefined, + // start_date: this.userFilters?.filters?.start_date || undefined, + // target_date: this.userFilters?.filters?.target_date || undefined, + // group_by: this.userFilters?.display_filters?.group_by || "state", + // order_by: this.userFilters?.display_filters?.order_by || "-created_at", + // type: this.userFilters?.display_filters?.type || undefined, + // sub_issue: this.userFilters?.display_filters?.sub_issue || true, + // show_empty_groups: this.userFilters?.display_filters?.show_empty_groups || true, + // calendar_date_range: this.userFilters?.display_filters?.calendar_date_range || undefined, + // start_target_date: this.userFilters?.display_filters?.start_target_date || true, + }; + + // start date and target date we have to construct the format here + // in calendar view calendar_date_range send as target_date + // in spreadsheet sub issue is false for sure + // in gantt start_target_date is true for sure + + const filteredParams: TIssueParams[] | null = handleIssueQueryParamsByLayout(_layout); + if (filteredParams) filteredRouteParams = this.computedFilter(filteredRouteParams, filteredParams); + + return filteredRouteParams; + }; + + handleIssueFilter = ( + filter_type: "filters" | "display_filters" | "display_properties" | "display_properties_id", + value: any + ) => { + const projectId = this.rootStore?.project?.projectId || null; + const moduleId = this.rootStore?.module?.moduleId || null; + const cycleId = this.rootStore?.cycle?.cycleId || null; + const viewId = this.rootStore?.view?.viewId || null; + const currentView = this.issueView || null; + + console.log("filter_type", filter_type); + console.log("value", value); + + if (!currentView || !projectId || !moduleId || !cycleId || !viewId) return null; + + // let _issueFilters: IIssueFilters = { + // ...this.issueFilters, + // [workspaceId]: { + // ...this.issueFilters?.[workspaceId], + // }, + // }; + + // console.log("_issueFilters", _issueFilters); + }; + + // services + // getWorkspaceMyIssuesFilters = async (workspaceId: string) => { + // try { + // this.loader = true; + // this.error = null; + + // const issuesFiltersResponse = await this.workspaceService.workspaceMemberMe(workspaceId); + // if (issuesFiltersResponse) { + // const _issuesFiltersResponse: any = { + // ...this.issueFilters, + // [workspaceId]: { + // ...this?.issueFilters?.[workspaceId], + // my_issue_properties: { + // ...this?.issueFilters?.[workspaceId]?.my_issue_properties, + // filters: { + // priority: issuesFiltersResponse?.view_props?.filters?.priority ?? null, + // state: issuesFiltersResponse?.view_props?.filters?.state ?? null, + // state_group: issuesFiltersResponse?.view_props?.filters?.state_group ?? null, + // assignees: issuesFiltersResponse?.view_props?.filters?.assignees ?? null, + // created_by: issuesFiltersResponse?.view_props?.filters?.created_by ?? null, + // labels: issuesFiltersResponse?.view_props?.filters?.labels ?? null, + // start_date: issuesFiltersResponse?.view_props?.filters?.start_date ?? null, + // target_date: issuesFiltersResponse?.view_props?.filters?.target_date ?? null, + // subscriber: issuesFiltersResponse?.view_props?.filters?.subscriber ?? null, + // }, + // display_filters: { + // group_by: issuesFiltersResponse?.view_props?.display_filters?.group_by ?? null, + // 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, + // 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, + // }, + // 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, + // 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, + // 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, + // }, + // }, + // }, + // }; + // runInAction(() => { + // this.issueFilters = _issuesFiltersResponse; + // this.loader = false; + // this.error = null; + // }); + // } + // return issuesFiltersResponse; + // } catch (error) { + // console.warn("error in fetching workspace level filters", error); + // this.loader = false; + // this.error = null; + // + // } + // }; + // updateWorkspaceMyIssuesFilters = async (workspaceId: string, data: any) => { + // try { + // this.loader = true; + // this.error = null; + + // const payload = { + // view_props: data, + // }; + // const issuesFiltersResponse = await this.workspaceService.updateWorkspaceView(workspaceId, payload); + + // if (issuesFiltersResponse) { + // runInAction(() => { + // this.loader = false; + // this.error = null; + // }); + // } + // } catch (error) { + // console.warn("error in fetching workspace level issue filters", error); + // this.loader = false; + // this.error = null; + // + // } + // }; + + getProjectDisplayProperties = async (workspaceId: string, projectId: string) => { + try { + this.loader = true; + this.error = null; + + await this.rootStore.user.setCurrentUser(); + const issuesDisplayPropertiesResponse = await this.issueService.getIssueProperties(workspaceId, projectId); + + if (issuesDisplayPropertiesResponse) { + const _issuesDisplayPropertiesResponse: any = { + ...this.issueFilters, + [projectId]: { + ...this?.issueFilters?.[projectId], + display_properties_id: issuesDisplayPropertiesResponse?.id, + display_properties: { + ...issuesDisplayPropertiesResponse?.properties, + }, + }, + }; + + runInAction(() => { + this.issueFilters = _issuesDisplayPropertiesResponse; + this.loader = false; + this.error = null; + }); + } + + return issuesDisplayPropertiesResponse; + } catch (error) { + console.warn("error in fetching project level display properties", error); + this.loader = false; + this.error = null; + } + }; + updateProjectDisplayProperties = async ( + workspaceId: string, + projectId: string, + display_properties_id: string, + data: any + ) => { + try { + this.loader = true; + this.error = null; + + const payload = { + properties: data, + user: this.rootStore?.user?.currentUser?.id, + }; + const issuesDisplayPropertiesResponse = await this.issueService.patchIssueProperties( + workspaceId, + projectId, + display_properties_id, + payload + ); + + if (issuesDisplayPropertiesResponse) { + runInAction(() => { + this.loader = false; + this.error = null; + }); + } + + return issuesDisplayPropertiesResponse; + } catch (error) { + console.warn("error in fetching project level display properties", error); + this.loader = false; + this.error = null; + } + }; + + getProjectDisplayFilters = async (workspaceId: string, projectId: string) => { + try { + this.loader = true; + this.error = null; + + const issuesDisplayFiltersResponse = await this.projectService.projectMemberMe(workspaceId, projectId); + + if (issuesDisplayFiltersResponse) { + const _filters = { ...issuesDisplayFiltersResponse?.view_props?.filters }; + const _displayFilters = { ...issuesDisplayFiltersResponse?.view_props?.display_filters }; + + const _issuesDisplayFiltersResponse: any = { + ...this.issueFilters, + [projectId]: { + ...this?.issueFilters?.[projectId], + issues: { + ...this?.issueFilters?.[projectId]?.issues, + filters: _filters, + }, + display_filters: _displayFilters, + }, + }; + + console.log("_issuesDisplayFiltersResponse", _issuesDisplayFiltersResponse); + + runInAction(() => { + this.issueFilters = _issuesDisplayFiltersResponse; + this.loader = false; + this.error = null; + }); + } + + return issuesDisplayFiltersResponse; + } catch (error) { + console.warn("error in fetching workspace level issue filters", error); + this.loader = false; + this.error = null; + } + }; + updateProjectDisplayFilters = async (workspaceId: string, projectId: string, data: any) => { + try { + this.loader = true; + this.error = null; + + const payload: any = { + view_props: data, + }; + const issuesFiltersResponse = await this.projectService.setProjectView(workspaceId, projectId, payload); + + if (issuesFiltersResponse) { + runInAction(() => { + this.loader = false; + this.error = null; + }); + } + + return issuesFiltersResponse; + } catch (error) { + this.getProjectDisplayFilters(workspaceId, projectId); + console.warn("error in fetching workspace level issue filters", error); + this.loader = false; + this.error = null; + } + }; + + getProjectIssueFilters = async (workspaceId: string, projectId: string) => { + try { + await this.getProjectDisplayProperties(workspaceId, projectId); + await this.getProjectDisplayFilters(workspaceId, projectId); + } catch (error) { + console.warn("error in fetching workspace level issue filters", error); + } + }; + + 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); + if (issuesFiltersModuleResponse) { + const _filters = { ...issuesFiltersModuleResponse?.view_props?.filters }; + const _issuesFiltersModuleResponse = { + ...this.issueFilters, + [projectId]: { + ...this?.issueFilters?.[projectId], + modules: { + ...this?.issueFilters?.[projectId]?.modules, + [moduleId]: { + ...this?.issueFilters?.[projectId]?.modules?.[moduleId], + filters: { + priority: _filters?.priority ?? undefined, + state: _filters?.state ?? undefined, + state_group: _filters?.state_group ?? undefined, + assignees: _filters?.assignees ?? undefined, + created_by: _filters?.created_by ?? undefined, + labels: _filters?.labels ?? undefined, + start_date: _filters?.start_date ?? undefined, + target_date: _filters?.target_date ?? undefined, + }, + }, + }, + }, + }; + + runInAction(() => { + this.issueFilters = _issuesFiltersModuleResponse as any; + this.loader = false; + this.error = null; + }); + } + } catch (error) { + console.warn("error in fetching workspace level issue filters", error); + this.loader = false; + this.error = null; + } + }; + updateProjectIssueModuleFilters = async (workspaceId: string, projectId: string, moduleId: string, data: any) => { + try { + this.loader = true; + this.error = null; + + const payload = { + view_props: { filters: data }, + }; + const issuesFiltersModuleResponse = await this.moduleService.patchModule( + workspaceId, + projectId, + moduleId, + payload, + undefined // TODO: replace this with user + ); + + if (issuesFiltersModuleResponse) { + runInAction(() => { + this.loader = false; + this.error = null; + }); + } + } catch (error) { + this.getProjectIssueModuleFilters(workspaceId, projectId, moduleId); + console.warn("error in fetching workspace level issue filters", error); + this.loader = false; + this.error = null; + } + }; + + 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); + if (issuesFiltersCycleResponse) { + const _filters = { ...issuesFiltersCycleResponse?.view_props?.filters }; + const _issuesFiltersCycleResponse = { + ...this.issueFilters, + [projectId]: { + ...this?.issueFilters?.[projectId], + cycles: { + ...this?.issueFilters?.[projectId]?.cycles, + [cycleId]: { + ...this?.issueFilters?.[projectId]?.modules?.[cycleId], + filters: { + priority: _filters?.priority ?? undefined, + state: _filters?.state ?? undefined, + state_group: _filters?.state_group ?? undefined, + assignees: _filters?.assignees ?? undefined, + created_by: _filters?.created_by ?? undefined, + labels: _filters?.labels ?? undefined, + start_date: _filters?.start_date ?? undefined, + target_date: _filters?.target_date ?? undefined, + }, + }, + }, + }, + }; + + runInAction(() => { + this.issueFilters = _issuesFiltersCycleResponse as any; + this.loader = false; + this.error = null; + }); + } + } catch (error) { + console.warn("error in fetching workspace level issue filters", error); + this.loader = false; + this.error = null; + } + }; + updateProjectIssueCyclesFilters = async (workspaceId: string, projectId: string, cycleId: string, data: any) => { + try { + this.loader = true; + this.error = null; + + const payload = { + view_props: { filters: data }, + }; + const issuesFiltersCycleResponse = await this.cycleService.patchCycle( + workspaceId, + projectId, + cycleId, + payload, + undefined // TODO: replace this with user + ); + + if (issuesFiltersCycleResponse) { + runInAction(() => { + this.loader = false; + this.error = null; + }); + } + } catch (error) { + this.getProjectIssueCyclesFilters(workspaceId, projectId, cycleId); + console.warn("error in fetching workspace level issue filters", error); + this.loader = false; + this.error = null; + } + }; + + getProjectIssueViewsFilters = async (workspaceId: string, projectId: string, viewId: string) => { + try { + this.loader = true; + this.error = null; + + await this.getProjectIssueFilters(workspaceId, projectId); + const issuesFiltersViewResponse = await this.viewService.getViewDetails(workspaceId, projectId, viewId); + if (issuesFiltersViewResponse) { + const _filters = { ...issuesFiltersViewResponse?.query_data } as any; + const _issuesFiltersViewResponse = { + ...this.issueFilters, + [projectId]: { + ...this?.issueFilters?.[projectId], + views: { + ...this?.issueFilters?.[projectId]?.views, + [viewId]: { + ...this?.issueFilters?.[projectId]?.modules?.[viewId], + filters: { + priority: _filters?.priority ?? undefined, + state: _filters?.state ?? undefined, + state_group: _filters?.state_group ?? undefined, + assignees: _filters?.assignees ?? undefined, + created_by: _filters?.created_by ?? undefined, + labels: _filters?.labels ?? undefined, + start_date: _filters?.start_date ?? undefined, + target_date: _filters?.target_date ?? undefined, + }, + }, + }, + }, + }; + + runInAction(() => { + this.issueFilters = _issuesFiltersViewResponse as any; + this.loader = false; + this.error = null; + }); + } + } catch (error) { + console.warn("error in fetching workspace level issue filters", error); + this.loader = false; + this.error = null; + } + }; + updateProjectIssueViewsFilters = async (workspaceId: string, projectId: string, viewId: string, data: any) => { + try { + this.loader = true; + this.error = null; + + const payload = { + query_data: data, + }; + const issuesFiltersViewResponse = await this.viewService.patchView( + workspaceId, + projectId, + viewId, + payload, + undefined // TODO: replace this with user + ); + + if (issuesFiltersViewResponse) { + runInAction(() => { + this.loader = false; + this.error = null; + }); + } + + return issuesFiltersViewResponse; + } catch (error) { + console.warn("error in fetching workspace level issue filters", error); + this.loader = false; + this.error = null; + } + }; +} + +export default IssueFilterStore; diff --git a/web/store/issue-store.ts b/web/store/issue-store.ts new file mode 100644 index 000000000..e28d748f9 --- /dev/null +++ b/web/store/issue-store.ts @@ -0,0 +1,417 @@ +import { observable, action, computed, makeObservable, runInAction } from "mobx"; +// types +import { RootStore } from "./root"; +// services +import { UserService } from "services/user.service"; +import { ProjectIssuesServices } from "services/issues.service"; +import { ProjectIssuesServices as ProjectModuleServices } from "services/modules.service"; +import { ProjectCycleServices } from "services/cycles.service"; +// types +import { TIssueLayouts, TIssueViews } from "./issue-filters"; + +export interface IIssues { + [key: string]: any; +} + +export interface IIssuesLayout { + list: IIssues[]; + kanban: IIssues[]; + calendar: IIssues[]; + spreadsheet: IIssues[]; + gantt_chart: IIssues[]; +} + +export interface IIssueState { + [key: string]: { + // project_id: layout_view + issues: { + [key: string]: IIssuesLayout; // project_id: layout_key: ...issues, It's always one project id here + }; + cycles: { + [key: string]: IIssuesLayout; // cycle_id: layout_key: ...issues + }; + modules: { + [key: string]: IIssuesLayout; // module_id: layout_key: ...issues + }; + views: { + [key: string]: IIssuesLayout; // view_id: layout_key: ...issues + }; + }; +} + +export interface IIssueStore { + loader: boolean; + error: any | null; + issues: IIssueState; + // computed + getIssues: IIssues | null | undefined; + // actions + updateIssues: (data: any) => void; + getProjectIssuesAsync: (workspaceId: string, projectId: string, fetchFilterToggle?: boolean) => null | Promise; + getIssuesForModulesAsync: ( + workspaceId: string, + projectId: string, + moduleId: string, + fetchFilterToggle: boolean + ) => null | Promise; + getIssuesForCyclesAsync: ( + workspaceId: string, + projectId: string, + cycleId: string, + fetchFilterToggle: boolean + ) => null | Promise; + getIssuesForViewsAsync: ( + workspaceId: string, + projectId: string, + viewId: string, + fetchFilterToggle: boolean + ) => null | Promise; +} + +class IssueStore implements IIssueStore { + loader: boolean = false; + error: any | null = null; + issues: IIssueState = {}; + // root store + rootStore; + // service + issueService; + userService; + modulesService; + cyclesService; + + constructor(_rootStore: RootStore) { + makeObservable(this, { + // observable + loader: observable, + error: observable, + issues: observable.ref, + // computed + getIssues: computed, + // action + updateIssues: action, + getProjectIssuesAsync: action, + getIssuesForModulesAsync: action, + getIssuesForCyclesAsync: action, + getIssuesForViewsAsync: action, + }); + + this.rootStore = _rootStore; + this.issueService = new ProjectIssuesServices(); + this.userService = new UserService(); + this.modulesService = new ProjectModuleServices(); + this.cyclesService = new ProjectCycleServices(); + } + + // computed + get getIssues() { + if (this.issues != null) { + const issueView: TIssueViews | null = this.rootStore.issueFilter.issueView; + const projectId: string | null = this.rootStore.project.projectId; + const moduleId: string | null = this.rootStore.module.moduleId; + const cycleId: string | null = this.rootStore.cycle.cycleId; + const viewId: string | null = this.rootStore.view.viewId; + const issueLayout: TIssueLayouts | null = this.rootStore.issueFilter.issueLayout; + + if (!issueView || !projectId) return null; + + const currentViewIdIndex: string | null = + issueView === "issues" && projectId + ? projectId + : issueView === "modules" && moduleId + ? moduleId + : issueView === "cycles" && cycleId + ? cycleId + : issueView === "cycles" && viewId + ? viewId + : null; + + if (!issueLayout || !currentViewIdIndex) return null; + return this.issues[projectId][issueView][currentViewIdIndex][issueLayout]; + } + + return null; + } + + updateIssues = (data: any) => { + const issueView: TIssueViews | null = this.rootStore.issueFilter.issueView; + const projectId: string | null = this.rootStore.project.projectId; + const moduleId: string | null = this.rootStore.module.moduleId; + const cycleId: string | null = this.rootStore.cycle.cycleId; + const viewId: string | null = this.rootStore.view.viewId; + const issueLayout: TIssueLayouts | null = this.rootStore.issueFilter.issueLayout; + + const { groupId, issueId, issueData } = data as { + groupId?: any; + issueId: string | null; + issueData: any; + }; + + if (!issueView || !projectId) return null; + + const currentViewIdIndex: string | null = + issueView === "issues" && projectId + ? projectId + : issueView === "modules" && moduleId + ? moduleId + : issueView === "cycles" && cycleId + ? cycleId + : issueView === "cycles" && viewId + ? viewId + : null; + + if (!issueLayout || !currentViewIdIndex) return null; + + let _issues = this?.issues?.[projectId]?.[issueView]?.[currentViewIdIndex]?.[issueLayout]; + if (groupId && groupId != null && ["list", "kanban"].includes(issueLayout)) { + _issues = { + ..._issues, + [groupId]: + _issues?.[groupId] && _issues?.[groupId].length > 0 + ? _issues?.[groupId]?.map((item: any) => (item.id === issueId ? { ...item, ...issueData } : { ...item })) + : [], + }; + } else { + _issues = { + ..._issues, + ..._issues.map((item: any) => (item.id === issueId ? { ...item, ...issueData } : { ...item })), + }; + } + + this.issues = { + ...this.issues, + [projectId]: { + ...this?.issues?.[projectId], + [issueView]: { + ...this?.issues?.[projectId]?.[issueView], + [currentViewIdIndex]: { + ...this?.issues?.[projectId]?.[issueView]?.[currentViewIdIndex], + [issueLayout]: { + ...this?.issues?.[projectId]?.[issueView]?.[currentViewIdIndex]?.[issueLayout], + ..._issues, + }, + }, + }, + }, + }; + }; + + // fetching project issues + getProjectIssuesAsync = async (workspaceId: string, projectId: string, fetchFilterToggle: boolean = true) => { + try { + this.loader = true; + this.error = null; + + if (fetchFilterToggle) await this.rootStore.issueFilter.getProjectIssueFilters(workspaceId, projectId); + // const filteredParams = this.rootStore.issueFilter.getComputedFilters( + // workspaceId, + // projectId, + // null, + // null, + // null, + // "issues" + // ); + // const issuesResponse = await this.issueService.getIssuesWithParams(workspaceId, projectId, filteredParams); + + // if (issuesResponse) { + // const _issueResponse: any = { + // ...this.issues, + // [projectId]: { + // ...this?.issues?.[projectId], + // issues: { + // ...this?.issues?.[projectId]?.issues, + // [this.rootStore?.issueFilter?.userFilters?.display_filters?.layout as string]: issuesResponse, + // }, + // }, + // }; + + // runInAction(() => { + // this.issues = _issueResponse; + // this.loader = false; + // this.error = null; + // }); + // } + + // return issuesResponse; + } catch (error) { + console.warn("error in fetching the project issues", error); + this.loader = false; + this.error = null; + return error; + } + }; + + // fetching project issues for modules + getIssuesForModulesAsync = async ( + workspaceId: string, + projectId: string, + moduleId: string, + fetchFilterToggle: boolean = true + ) => { + try { + this.loader = true; + this.error = null; + + if (fetchFilterToggle) + await this.rootStore.issueFilter.getProjectIssueModuleFilters(workspaceId, projectId, moduleId); + const filteredParams = this.rootStore.issueFilter.getComputedFilters( + workspaceId, + projectId, + moduleId, + null, + null, + "modules" + ); + const issuesResponse = await this.modulesService.getModuleIssuesWithParams( + workspaceId, + projectId, + moduleId, + filteredParams + ); + + if (issuesResponse) { + const _issueResponse: any = { + ...this.issues, + [projectId]: { + ...this?.issues?.[projectId], + modules: { + ...this?.issues?.[projectId]?.modules, + [moduleId]: { + ...this?.issues?.[projectId]?.modules?.[moduleId], + [this.rootStore?.issueFilter?.userFilters?.display_filters?.layout as string]: issuesResponse, + }, + }, + }, + }; + + runInAction(() => { + this.issues = _issueResponse; + this.loader = false; + this.error = null; + }); + } + + return issuesResponse; + } catch (error) { + console.warn("error in fetching the project module issues", error); + this.loader = false; + this.error = null; + return error; + } + }; + + // fetching project issues for cycles + getIssuesForCyclesAsync = async ( + workspaceId: string, + projectId: string, + cycleId: string, + fetchFilterToggle: boolean = true + ) => { + try { + this.loader = true; + this.error = null; + + if (fetchFilterToggle) + await this.rootStore.issueFilter.getProjectIssueCyclesFilters(workspaceId, projectId, cycleId); + const filteredParams = this.rootStore.issueFilter.getComputedFilters( + workspaceId, + projectId, + null, + cycleId, + null, + "cycles" + ); + const issuesResponse = await this.cyclesService.getCycleIssuesWithParams( + workspaceId, + projectId, + cycleId, + filteredParams + ); + + if (issuesResponse) { + const _issueResponse: any = { + ...this.issues, + [projectId]: { + ...this?.issues?.[projectId], + cycles: { + ...this?.issues?.[projectId]?.cycles, + [cycleId]: { + ...this?.issues?.[projectId]?.cycles?.[cycleId], + [this.rootStore?.issueFilter?.userFilters?.display_filters?.layout as string]: issuesResponse, + }, + }, + }, + }; + + runInAction(() => { + this.issues = _issueResponse; + this.loader = false; + this.error = null; + }); + } + + return issuesResponse; + } catch (error) { + console.warn("error in fetching the project cycles issues", error); + this.loader = false; + this.error = null; + return error; + } + }; + + // fetching project issues for views + getIssuesForViewsAsync = async ( + workspaceId: string, + projectId: string, + viewId: string, + fetchFilterToggle: boolean = true + ) => { + try { + this.loader = true; + this.error = null; + + if (fetchFilterToggle) + await this.rootStore.issueFilter.getProjectIssueViewsFilters(workspaceId, projectId, viewId); + const filteredParams = this.rootStore.issueFilter.getComputedFilters( + workspaceId, + projectId, + null, + null, + viewId, + "views" + ); + const issuesResponse = await this.issueService.getIssuesWithParams(workspaceId, projectId, filteredParams); + + if (issuesResponse) { + const _issueResponse: any = { + ...this.issues, + [projectId]: { + ...this?.issues?.[projectId], + views: { + ...this?.issues?.[projectId]?.views, + [viewId]: { + ...this?.issues?.[projectId]?.views?.[viewId], + [this.rootStore?.issueFilter?.userFilters?.display_filters?.layout as string]: issuesResponse, + }, + }, + }, + }; + + runInAction(() => { + this.issues = _issueResponse; + this.loader = false; + this.error = null; + }); + } + + return issuesResponse; + } catch (error) { + console.warn("error in fetching the project view issues", error); + this.loader = false; + this.error = null; + return error; + } + }; +} + +export default IssueStore; diff --git a/web/store/issue-views/Issues.ts b/web/store/issue-views/Issues.ts deleted file mode 100644 index 7303245fc..000000000 --- a/web/store/issue-views/Issues.ts +++ /dev/null @@ -1,524 +0,0 @@ -import { observable, action, computed, makeObservable, runInAction } from "mobx"; -// types -import { RootStore } from "../root"; -// services -import { UserService } from "services/user.service"; -import { ProjectIssuesServices } from "services/issues.service"; -import { ProjectIssuesServices as ProjectModuleServices } from "services/modules.service"; -import { ProjectCycleServices } from "services/cycles.service"; -// types -import { TIssueLayouts, TIssueViews } from "./issue_filters"; - -export interface IIssues { - [key: string]: any; -} - -export interface IIssuesLayout { - list: IIssues[]; - kanban: IIssues[]; - calendar: IIssues[]; - spreadsheet: IIssues[]; - gantt_chart: IIssues[]; -} - -export interface IIssueState { - [key: string]: { - my_issues: IIssuesLayout; - project_issues: { - [key: string]: { - issues: IIssuesLayout; - cycles: { - [key: string]: IIssuesLayout; - }; - modules: { - [key: string]: IIssuesLayout; - }; - views: { - [key: string]: IIssuesLayout; - }; - }; - }; - }; -} - -export interface IIssueViewStore { - loader: boolean; - error: any | null; - issues: IIssueState; - // computed - getIssues: IIssues | null | undefined; - // actions - getMyIssuesAsync: (workspaceId: string, fetchFilterToggle: boolean) => null | Promise; - getProjectIssuesAsync: (workspaceId: string, projectId: string, fetchFilterToggle: boolean) => null | Promise; - getIssuesForModulesAsync: ( - workspaceId: string, - projectId: string, - moduleId: string, - fetchFilterToggle: boolean - ) => null | Promise; - getIssuesForCyclesAsync: ( - workspaceId: string, - projectId: string, - cycleId: string, - fetchFilterToggle: boolean - ) => null | Promise; - getIssuesForViewsAsync: ( - workspaceId: string, - projectId: string, - viewId: string, - fetchFilterToggle: boolean - ) => null | Promise; -} - -class IssueViewStore implements IIssueViewStore { - loader: boolean = false; - error: any | null = null; - issues: IIssueState = {}; - // root store - rootStore; - // service - issueService; - userService; - modulesService; - cyclesService; - - constructor(_rootStore: RootStore) { - makeObservable(this, { - // observable - loader: observable, - error: observable, - issues: observable.ref, - // action - getMyIssuesAsync: action, - getProjectIssuesAsync: action, - getIssuesForModulesAsync: action, - getIssuesForCyclesAsync: action, - getIssuesForViewsAsync: action, - updateIssues: action, - // computed - getIssues: computed, - }); - - this.rootStore = _rootStore; - this.issueService = new ProjectIssuesServices(); - this.userService = new UserService(); - this.modulesService = new ProjectModuleServices(); - this.cyclesService = new ProjectCycleServices(); - } - - // computed - get getIssues() { - if (this.issues != null) { - const currentView: TIssueViews | null = this.rootStore.issueFilters.issueView; - const currentWorkspaceId: string | null = this.rootStore.issueFilters.workspaceId; - const currentProjectId: string | null = this.rootStore.issueFilters.projectId; - const currentModuleId: string | null = this.rootStore.issueFilters.moduleId; - const currentCycleId: string | null = this.rootStore.issueFilters.cycleId; - const currentViewId: string | null = this.rootStore.issueFilters.viewId; - - 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; - - if (currentView === "my_issues") return this.issues?.[currentWorkspaceId]?.my_issues?.[currentLayout]; - else if (currentView === "issues" && currentProjectId) - 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 === "cycles" && currentProjectId && currentCycleId) - 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 null; - } - - updateIssues = (group_id: any = null, issue_id: string | null, data: any) => { - const currentWorkspaceId: string | null = this.rootStore.issueFilters.workspaceId; - const currentProjectId: string | null = this.rootStore.issueFilters.projectId; - // const currentModuleId: string | null = this.rootStore.issueFilters.moduleId; - // const currentCycleId: string | null = this.rootStore.issueFilters.cycleId; - // const currentViewId: string | null = this.rootStore.issueFilters.viewId; - const currentView: TIssueViews | null = this.rootStore.issueFilters.issueView; - const currentLayout: TIssueLayouts | null = this.rootStore.issueFilters.issueLayout; - - if (!currentView || !currentWorkspaceId || !currentLayout || !issue_id) return null; - - if (currentView === "my_issues") { - if (group_id) { - this.issues = { - ...this.issues, - [currentWorkspaceId]: { - ...this?.issues?.[currentWorkspaceId], - my_issues: { - ...this?.issues?.[currentWorkspaceId]?.my_issues, - [currentLayout]: { - ...this?.issues?.[currentWorkspaceId]?.my_issues?.[currentLayout], - [group_id]: this?.issues?.[currentWorkspaceId]?.my_issues?.[currentLayout]?.[group_id].map( - (item: any) => (item.id === issue_id ? { ...item, ...data } : { ...item }) - ), - }, - }, - }, - } as any; - } else { - this.issues = { - ...this.issues, - [currentWorkspaceId]: { - ...this?.issues?.[currentWorkspaceId], - my_issues: { - ...this?.issues?.[currentWorkspaceId]?.my_issues, - [currentLayout]: this?.issues?.[currentWorkspaceId]?.my_issues?.[currentLayout].map((item: any) => - item.id === issue_id ? { ...item, ...data } : { ...item } - ), - }, - }, - } as any; - } - } - - if (!currentProjectId) return null; - if (currentView) { - if (group_id) { - this.issues = { - ...this.issues, - [currentWorkspaceId]: { - ...this?.issues?.[currentWorkspaceId], - project_issues: { - ...this?.issues?.[currentWorkspaceId]?.project_issues, - [currentProjectId]: { - ...this?.issues?.[currentWorkspaceId]?.project_issues?.[currentProjectId], - [currentView]: { - ...this?.issues?.[currentWorkspaceId]?.project_issues?.[currentProjectId]?.issues, - [currentLayout]: { - ...this?.issues?.[currentWorkspaceId]?.project_issues?.[currentProjectId]?.issues?.[currentLayout], - [group_id]: this?.issues?.[currentWorkspaceId]?.project_issues?.[currentProjectId]?.issues?.[ - currentLayout - ]?.[group_id].map((item: any) => (item.id === issue_id ? { ...item, ...data } : { ...item })), - }, - }, - }, - }, - }, - } as any; - } else { - this.issues = { - ...this.issues, - [currentWorkspaceId]: { - ...this?.issues?.[currentWorkspaceId], - project_issues: { - ...this?.issues?.[currentWorkspaceId]?.project_issues, - [currentProjectId]: { - ...this?.issues?.[currentWorkspaceId]?.project_issues?.[currentProjectId], - [currentView]: { - ...this?.issues?.[currentWorkspaceId]?.project_issues?.[currentProjectId]?.issues, - [currentLayout]: this?.issues?.[currentWorkspaceId]?.project_issues?.[currentProjectId]?.issues?.[ - currentLayout - ].map((item: any) => (item.id === issue_id ? { ...item, ...data } : { ...item })), - }, - }, - }, - }, - } as any; - } - } - }; - - // fetching my issues - getMyIssuesAsync = async (workspaceId: string, fetchFilterToggle: boolean = true) => { - try { - this.loader = true; - this.error = null; - - if (fetchFilterToggle) await this.rootStore.issueFilters.getWorkspaceMyIssuesFilters(workspaceId); - const filteredParams = this.rootStore.issueFilters.getComputedFilters( - workspaceId, - null, - null, - null, - null, - "my_issues" - ); - const issuesResponse = await this.userService.userIssues(workspaceId, filteredParams); - - if (issuesResponse) { - const _issueResponse: any = { - ...this.issues, - [workspaceId]: { - ...this?.issues[workspaceId], - my_issues: { - ...this?.issues[workspaceId]?.my_issues, - [this.rootStore?.issueFilters?.userFilters?.display_filters?.layout as string]: issuesResponse, - }, - }, - }; - - runInAction(() => { - this.issues = _issueResponse; - this.loader = false; - this.error = null; - }); - } - - return issuesResponse; - } catch (error) { - console.warn("error in fetching the my issues", error); - this.loader = false; - this.error = null; - return error; - } - }; - - // fetching project issues - 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); - const filteredParams = this.rootStore.issueFilters.getComputedFilters( - workspaceId, - projectId, - null, - null, - null, - "issues" - ); - const issuesResponse = await this.issueService.getIssuesWithParams(workspaceId, projectId, filteredParams); - - if (issuesResponse) { - const _issueResponse: any = { - ...this.issues, - [workspaceId]: { - ...this?.issues?.[workspaceId], - project_issues: { - ...this?.issues?.[workspaceId]?.project_issues, - [projectId]: { - ...this?.issues?.[workspaceId]?.project_issues?.[projectId], - issues: { - ...this?.issues[workspaceId]?.project_issues?.[projectId]?.issues, - [this.rootStore?.issueFilters?.userFilters?.display_filters?.layout as string]: issuesResponse, - }, - }, - }, - }, - }; - - runInAction(() => { - this.issues = _issueResponse; - this.loader = false; - this.error = null; - }); - } - - return issuesResponse; - } catch (error) { - console.warn("error in fetching the project issues", error); - this.loader = false; - this.error = null; - return error; - } - }; - - // fetching project issues for modules - getIssuesForModulesAsync = async ( - workspaceId: string, - projectId: string, - moduleId: string, - fetchFilterToggle: boolean = true - ) => { - try { - this.loader = true; - this.error = null; - - if (fetchFilterToggle) - await this.rootStore.issueFilters.getProjectIssueModuleFilters(workspaceId, projectId, moduleId); - const filteredParams = this.rootStore.issueFilters.getComputedFilters( - workspaceId, - projectId, - moduleId, - null, - null, - "modules" - ); - const issuesResponse = await this.modulesService.getModuleIssuesWithParams( - workspaceId, - projectId, - moduleId, - filteredParams - ); - - if (issuesResponse) { - const _issueResponse: any = { - ...this.issues, - [workspaceId]: { - ...this?.issues?.[workspaceId], - project_issues: { - ...this?.issues?.[workspaceId]?.project_issues, - [projectId]: { - ...this?.issues?.[workspaceId]?.project_issues?.[projectId], - modules: { - ...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, - }, - }, - }, - }, - }, - }; - - runInAction(() => { - this.issues = _issueResponse; - this.loader = false; - this.error = null; - }); - } - - return issuesResponse; - } catch (error) { - console.warn("error in fetching the project module issues", error); - this.loader = false; - this.error = null; - return error; - } - }; - - // fetching project issues for cycles - getIssuesForCyclesAsync = async ( - workspaceId: string, - projectId: string, - cycleId: string, - fetchFilterToggle: boolean = true - ) => { - try { - this.loader = true; - this.error = null; - - if (fetchFilterToggle) - await this.rootStore.issueFilters.getProjectIssueCyclesFilters(workspaceId, projectId, cycleId); - const filteredParams = this.rootStore.issueFilters.getComputedFilters( - workspaceId, - projectId, - null, - cycleId, - null, - "cycles" - ); - const issuesResponse = await this.cyclesService.getCycleIssuesWithParams( - workspaceId, - projectId, - cycleId, - filteredParams - ); - - if (issuesResponse) { - const _issueResponse: any = { - ...this.issues, - [workspaceId]: { - ...this?.issues?.[workspaceId], - project_issues: { - ...this?.issues?.[workspaceId]?.project_issues, - [projectId]: { - ...this?.issues?.[workspaceId]?.project_issues?.[projectId], - cycles: { - ...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, - }, - }, - }, - }, - }, - }; - - runInAction(() => { - this.issues = _issueResponse; - this.loader = false; - this.error = null; - }); - } - - return issuesResponse; - } catch (error) { - console.warn("error in fetching the project cycles issues", error); - this.loader = false; - this.error = null; - return error; - } - }; - - // fetching project issues for views - getIssuesForViewsAsync = async ( - workspaceId: string, - projectId: string, - viewId: string, - fetchFilterToggle: boolean = true - ) => { - try { - this.loader = true; - this.error = null; - - if (fetchFilterToggle) - await this.rootStore.issueFilters.getProjectIssueViewsFilters(workspaceId, projectId, viewId); - const filteredParams = this.rootStore.issueFilters.getComputedFilters( - workspaceId, - projectId, - null, - null, - viewId, - "views" - ); - const issuesResponse = await this.issueService.getIssuesWithParams(workspaceId, projectId, filteredParams); - - if (issuesResponse) { - const _issueResponse: any = { - ...this.issues, - [workspaceId]: { - ...this?.issues?.[workspaceId], - project_issues: { - ...this?.issues?.[workspaceId]?.project_issues, - [projectId]: { - ...this?.issues?.[workspaceId]?.project_issues?.[projectId], - views: { - ...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, - }, - }, - }, - }, - }, - }; - - runInAction(() => { - this.issues = _issueResponse; - this.loader = false; - this.error = null; - }); - } - - return issuesResponse; - } catch (error) { - console.warn("error in fetching the project view issues", error); - this.loader = false; - this.error = null; - return error; - } - }; -} - -export default IssueViewStore; diff --git a/web/store/issue-views/issue_filters.ts b/web/store/issue-views/issue_filters.ts deleted file mode 100644 index bfe971b27..000000000 --- a/web/store/issue-views/issue_filters.ts +++ /dev/null @@ -1,1408 +0,0 @@ -import { observable, action, computed, makeObservable, runInAction } from "mobx"; -// types -import { RootStore } from "../root"; -// services -import { WorkspaceService } from "services/workspace.service"; -import { ProjectIssuesServices } from "services/issues.service"; -import { ProjectStateServices } from "services/state.service"; -import { ProjectServices } from "services/project.service"; -import { ProjectIssuesServices as ProjectModuleServices } from "services/modules.service"; -import { ProjectCycleServices } from "services/cycles.service"; -import { ViewServices as ProjectViewServices } from "services/views.service"; -// default data -import { - priorities, - stateGroups, - startDateOptions, - dueDateOptions, - groupByOptions, - orderByOptions, - issueTypes, - displayProperties, - extraProperties, - handleIssueQueryParamsByLayout, -} from "./issue_data"; - -export type TIssueViews = "my_issues" | "issues" | "modules" | "views" | "cycles"; - -export type TIssueLayouts = "list" | "kanban" | "calendar" | "spreadsheet" | "gantt_chart"; - -export type TIssueParams = - | "priority" - | "state_group" - | "state" - | "assignees" - | "created_by" - | "labels" - | "start_date" - | "target_date" - | "group_by" - | "order_by" - | "type" - | "sub_issue" - | "show_empty_groups" - | "calendar_date_range" - | "start_target_date"; - -export interface IIssueFilter { - priority: string[] | undefined; - state: string[] | undefined; - state_group: string[] | undefined; - assignees: string[] | undefined; - created_by: string[] | undefined; - labels: string[] | undefined; - start_date: string[] | undefined; - target_date: string[] | undefined; - [key: string]: any; -} - -export interface IIssueDisplayFilters { - group_by: undefined | string; - order_by: undefined | string; - type: string | undefined; - sub_issue: boolean; - show_empty_groups: boolean; - layout: TIssueLayouts; - calendar_date_range: string | undefined; // only for calendar - start_target_date: boolean; - [key: string]: any; -} - -export interface IIssueDisplayProperties { - assignee: boolean; - attachment_count: boolean; - created_on: boolean; - due_date: boolean; - estimate: boolean; - key: boolean; - labels: boolean; - link: boolean; - priority: boolean; - start_date: boolean; - state: boolean; - sub_issue_count: boolean; - updated_on: boolean; - [key: string]: any; -} - -export interface IIssueRenderFilters { - priority: { key: string; title: string }[]; - state_group: { key: string; title: string }[]; - start_date: { key: string; title: string }[]; - due_date: { key: string; title: string }[]; - group_by: { key: string; title: string }[]; - order_by: { key: string; title: string }[]; - issue_type: { key: string; title: string }[]; - display_properties: { key: string; title: string }[]; - extra_properties: { key: string; title: string }[]; - workspace_properties: { - [key: string]: { - projects: any[]; - labels: any[]; - project_properties: { - [key: string]: { - states: any | null; - labels: any[] | null; - members: any[] | null; - }; - }; - }; - }; -} - -export interface IIssueFilters { - [key: string]: { - my_issue_properties: { - filters: IIssueFilter; - display_filters: IIssueDisplayFilters; - display_properties_id: null; - display_properties: IIssueDisplayProperties; - }; - project_issue_properties: { - [key: string]: { - issues: { - filters: IIssueFilter; - display_filters: IIssueDisplayFilters; - }; - cycles: { - [key: string]: { - filters: IIssueFilter; - }; - }; - modules: { - [key: string]: { - filters: IIssueFilter; - }; - }; - views: { - [key: string]: { - filters: IIssueFilter; - }; - }; - display_properties_id: string; - display_properties: IIssueDisplayProperties; - }; - }; - }; -} - -export interface IIssueFilterStore { - loader: boolean; - error: any | null; - - // current workspace and project id - workspaceId: string | null; - projectId: string | null; - moduleId: string | null; - cycleId: string | null; - viewId: string | null; - issueView: TIssueViews | null; - - issueRenderFilters: IIssueRenderFilters; - issueFilters: IIssueFilters; - - // actions - getWorkspaceMyIssuesFilters: (workspaceId: string) => Promise; - updateWorkspaceMyIssuesFilters: (workspaceId: string, data: any) => Promise; - - getProjectLevelMembers: (workspaceId: string, projectId: string) => Promise; - getProjectLevelStates: (workspaceId: string, projectId: string) => Promise; - getProjectLevelLabels: (workspaceId: string, projectId: string) => Promise; - getProjectDisplayProperties: (workspaceId: string, projectId: string) => Promise; - updateProjectDisplayProperties: ( - workspaceId: string, - projectId: string, - display_properties_id: string, - data: any - ) => Promise; - getProjectDisplayFilters: (workspaceId: string, projectId: string) => Promise; - updateProjectDisplayFilters: (workspaceId: string, projectId: string, data: any) => Promise; - - getProjectIssueFilters: (workspaceId: string, projectId: 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; -} - -class IssueFilterStore implements IIssueFilterStore { - loader: boolean = false; - error: any | null = null; - - workspaceId: string | null = null; - projectId: string | null = null; - moduleId: string | null = null; - cycleId: string | null = null; - viewId: string | null = null; - - issueView: TIssueViews | null = null; - - issueRenderFilters: IIssueRenderFilters = { - priority: priorities, - state_group: stateGroups, - start_date: startDateOptions, - due_date: dueDateOptions, - group_by: groupByOptions, - order_by: orderByOptions, - issue_type: issueTypes, - display_properties: displayProperties, - extra_properties: extraProperties, - workspace_properties: {}, - }; - issueFilters: IIssueFilters = {}; - - // root store - rootStore; - // service - workspaceService; - issueService; - stateService; - projectService; - moduleService; - cycleService; - viewService; - - constructor(_rootStore: RootStore) { - makeObservable(this, { - // observable - loader: observable, - error: observable, - - workspaceId: observable, - projectId: observable, - moduleId: observable, - cycleId: observable, - viewId: observable, - - issueView: observable, - - issueRenderFilters: observable.ref, - issueFilters: observable.ref, - - // computed - issueLayout: computed, - workspaceProjects: computed, - workspaceLabels: computed, - projectStates: computed, - projectLabels: computed, - projectMembers: computed, - projectDisplayProperties: computed, - - userFilters: computed, - - // actions - - getProjectStateById: action, - - getComputedFilters: action, - - handleUserFilter: action, - - getWorkspaceMyIssuesFilters: action, - updateWorkspaceMyIssuesFilters: action, - - getProjectLevelMembers: action, - getProjectLevelStates: action, - getProjectLevelLabels: action, - - getProjectDisplayFilters: action, - updateProjectDisplayFilters: action, - - getProjectDisplayProperties: action, - updateProjectDisplayProperties: action, - - getProjectIssueFilters: action, - - getProjectIssueModuleFilters: action, - updateProjectIssueModuleFilters: action, - - getProjectIssueCyclesFilters: action, - updateProjectIssueCyclesFilters: action, - - getProjectIssueViewsFilters: action, - updateProjectIssueViewsFilters: action, - }); - - this.rootStore = _rootStore; - this.workspaceService = new WorkspaceService(); - this.issueService = new ProjectIssuesServices(); - this.stateService = new ProjectStateServices(); - this.projectService = new ProjectServices(); - this.moduleService = new ProjectModuleServices(); - this.cycleService = new ProjectCycleServices(); - this.viewService = new ProjectViewServices(); - } - - // computed - get issueLayout() { - if (!this.workspaceId) return null; - if (!this.projectId) - return this.issueFilters?.[this.workspaceId]?.my_issue_properties?.display_filters?.layout || null; - if (this.projectId) - return ( - this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]?.issues?.display_filters - ?.layout || null - ); - - return null; - } - - get workspaceProjects() { - if (!this.workspaceId) return null; - return this.issueRenderFilters?.workspace_properties?.[this.workspaceId]?.projects || null; - } - get workspaceLabels() { - if (!this.workspaceId) return null; - return this.issueRenderFilters?.workspace_properties?.[this.workspaceId]?.labels || null; - } - - get projectStates() { - if (!this.workspaceId || !this.projectId) return null; - return ( - this.issueRenderFilters?.workspace_properties?.[this.workspaceId]?.project_properties?.[this.projectId]?.states || - null - ); - } - - getProjectStateById = (stateId: string) => { - if (!this.workspaceId || !this.projectId) return null; - const states = - this.issueRenderFilters?.workspace_properties?.[this.workspaceId]?.project_properties?.[this.projectId]?.states; - - let stateInfo: any = null; - Object.keys(states).forEach((stateGroupName) => { - if (states[stateGroupName].find((state: any) => state.id === stateId)) { - stateInfo = states[stateGroupName].find((state: any) => state.id === stateId); - } - }); - return stateInfo; - }; - - get projectLabels() { - if (!this.workspaceId || !this.projectId) return null; - 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; - } - get projectDisplayProperties() { - if (!this.workspaceId || !this.projectId) return null; - return this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]?.display_properties as any; - } - - get userFilters() { - if (!this.workspaceId) return null; - if (this.issueView === "my_issues") - return { - ...this.issueFilters?.[this.workspaceId]?.my_issue_properties, - display_properties_id: null, - }; - - if (!this.projectId) return null; - let _issueFilters: { - filters: IIssueFilter | null; - display_filters: IIssueDisplayFilters; - display_properties_id: string; - display_properties: IIssueDisplayProperties; - } = { - filters: null, - 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, - 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, - }; - return _issueFilters; - } - - if (this.issueView === "modules" && this.moduleId) { - _issueFilters = { - ..._issueFilters, - filters: - this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]?.modules?.[this.moduleId] - ?.filters, - }; - return _issueFilters; - } - - if (this.issueView === "cycles" && this.cycleId) { - _issueFilters = { - ..._issueFilters, - filters: - this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]?.cycles?.[this.cycleId] - ?.filters, - }; - return _issueFilters; - } - - if (this.issueView === "views" && this.viewId) { - _issueFilters = { - ..._issueFilters, - filters: - this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]?.views?.[this.viewId] - ?.filters, - }; - return _issueFilters; - } - - return null; - } - handleUserFilter = ( - filter_type: "filters" | "display_filters" | "display_properties", - filter_key: string, - value: any - ) => { - if (!this.workspaceId) return null; - - if (this.issueView === "my_issues") { - this.issueFilters = { - ...this.issueFilters, - [this.workspaceId]: { - ...this.issueFilters?.[this.workspaceId], - my_issue_properties: { - ...this.issueFilters?.[this.workspaceId]?.my_issue_properties, - [filter_type]: { - ...this.issueFilters?.[this.workspaceId]?.my_issue_properties?.[filter_type], - [filter_key]: value, - }, - }, - }, - }; - this.updateWorkspaceMyIssuesFilters(this.workspaceId, this.userFilters); - } - - if (!this.projectId) return null; - if (filter_type === "display_properties") { - this.issueFilters = { - ...this.issueFilters, - [this.workspaceId]: { - ...this.issueFilters?.[this.workspaceId], - project_issue_properties: { - ...this.issueFilters?.[this.workspaceId]?.project_issue_properties, - [this.projectId]: { - ...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId], - display_properties: { - ...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId] - ?.display_properties, - [filter_key]: value, - }, - }, - }, - }, - }; - - if (this.userFilters?.display_properties_id) { - this.updateProjectDisplayProperties( - this.workspaceId, - this.projectId, - this.userFilters?.display_properties_id, - this.userFilters?.display_properties - ); - } - } - - if (filter_type === "display_filters") { - this.issueFilters = { - ...this.issueFilters, - [this.workspaceId]: { - ...this.issueFilters?.[this.workspaceId], - project_issue_properties: { - ...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, - [filter_type]: { - ...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]?.issues?.[ - filter_type - ], - [filter_key]: value, - }, - }, - }, - }, - }, - }; - this.updateProjectDisplayFilters(this.workspaceId, this.projectId, { - filters: this.userFilters?.filters, - display_filters: this.userFilters?.display_filters, - }); - } - - if (filter_type === "filters") { - if (this.issueView === "issues") { - this.issueFilters = { - ...this.issueFilters, - [this.workspaceId]: { - ...this.issueFilters?.[this.workspaceId], - project_issue_properties: { - ...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, - [filter_type]: { - ...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]?.issues?.[ - filter_type - ], - [filter_key]: value, - }, - }, - }, - }, - }, - }; - this.updateProjectDisplayFilters(this.workspaceId, this.projectId, { - filters: this.userFilters?.filters, - display_filters: this.userFilters?.display_filters, - }); - } - - if (this.issueView === "modules" && this.moduleId) { - this.issueFilters = { - ...this.issueFilters, - [this.workspaceId]: { - ...this.issueFilters?.[this.workspaceId], - project_issue_properties: { - ...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.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], - [filter_key]: value, - }, - }, - }, - }, - }, - }, - }; - this.updateProjectIssueModuleFilters( - this.workspaceId, - this.projectId, - this.moduleId, - this.userFilters?.filters - ); - } - - if (this.issueView === "cycles" && this.cycleId) { - this.issueFilters = { - ...this.issueFilters, - [this.workspaceId]: { - ...this.issueFilters?.[this.workspaceId], - project_issue_properties: { - ...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.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], - [filter_key]: value, - }, - }, - }, - }, - }, - }, - }; - this.updateProjectIssueCyclesFilters(this.workspaceId, this.projectId, this.cycleId, this.userFilters?.filters); - } - - if (this.issueView === "views" && this.viewId) { - this.issueFilters = { - ...this.issueFilters, - [this.workspaceId]: { - ...this.issueFilters?.[this.workspaceId], - project_issue_properties: { - ...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.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], - [filter_key]: value, - }, - }, - }, - }, - }, - }, - }; - this.updateProjectIssueViewsFilters(this.workspaceId, this.projectId, this.viewId, this.userFilters?.filters); - } - } - - if (this.issueView === "my_issues") - this.rootStore?.issueView?.getProjectIssuesAsync(this.workspaceId, this.projectId, false); - 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); - if (this.issueView === "cycles" && this.cycleId) - 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); - }; - - computedFilter = (filters: any, filteredParams: any) => { - const computedFilters: any = {}; - 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(","); - }); - - return computedFilters; - }; - getComputedFilters = ( - _workspaceId: string | null, - _projectId: string | null, - _moduleId: string | null, - _cycleId: string | null, - _viewId: string | null, - _issueView: TIssueViews - ) => { - this.workspaceId = _workspaceId; - this.projectId = _projectId; - this.moduleId = _moduleId; - this.cycleId = _cycleId; - this.viewId = _viewId; - this.issueView = _issueView; - - const _layout = this.userFilters?.display_filters?.layout; - - let filteredRouteParams: any = { - priority: this.userFilters?.filters?.priority || undefined, - state_group: this.userFilters?.filters?.state_group || undefined, - state: this.userFilters?.filters?.state || undefined, - assignees: this.userFilters?.filters?.assignees || undefined, - created_by: this.userFilters?.filters?.created_by || undefined, - labels: this.userFilters?.filters?.labels || undefined, - start_date: this.userFilters?.filters?.start_date || undefined, - target_date: this.userFilters?.filters?.target_date || undefined, - group_by: this.userFilters?.display_filters?.group_by || "state", - order_by: this.userFilters?.display_filters?.order_by || "-created_at", - type: this.userFilters?.display_filters?.type || undefined, - sub_issue: this.userFilters?.display_filters?.sub_issue || true, - show_empty_groups: this.userFilters?.display_filters?.show_empty_groups || true, - calendar_date_range: this.userFilters?.display_filters?.calendar_date_range || undefined, - start_target_date: this.userFilters?.display_filters?.start_target_date || true, - }; - - // start date and target date we have to construct the format here - // in calendar view calendar_date_range send as target_date - // in spreadsheet sub issue is false for sure - // in gantt start_target_date is true for sure - - const filteredParams: TIssueParams[] | null = handleIssueQueryParamsByLayout(_layout); - if (filteredParams) filteredRouteParams = this.computedFilter(filteredRouteParams, filteredParams); - - return filteredRouteParams; - }; - - // services - getWorkspaceMyIssuesProjects = async (workspaceId: string) => { - try { - this.loader = true; - this.error = null; - - const params = { is_favorite: false }; - const issuesProjectsResponse = await this.projectService.getProjects(workspaceId, params); - - if (issuesProjectsResponse) { - const _issuesProjectsResponse = { - ...this.issueRenderFilters, - workspace_properties: { - ...this.issueRenderFilters?.workspace_properties, - [workspaceId]: { - ...this.issueRenderFilters?.workspace_properties?.[workspaceId], - projects: issuesProjectsResponse, - }, - }, - }; - - runInAction(() => { - this.issueRenderFilters = _issuesProjectsResponse; - this.loader = false; - this.error = null; - }); - } - return issuesProjectsResponse; - } catch (error) { - console.warn("error in fetching workspace level projects", error); - this.loader = false; - this.error = null; - return error; - } - }; - getWorkspaceMyIssuesLabels = async (workspaceId: string) => { - try { - this.loader = true; - this.error = null; - - const issuesLabelsResponse = await this.issueService.getWorkspaceLabels(workspaceId); - - if (issuesLabelsResponse) { - const _issuesLabelsResponse = { - ...this.issueRenderFilters, - workspace_properties: { - ...this.issueRenderFilters?.workspace_properties, - [workspaceId]: { - ...this.issueRenderFilters?.workspace_properties?.[workspaceId], - labels: issuesLabelsResponse, - }, - }, - }; - - runInAction(() => { - this.issueRenderFilters = _issuesLabelsResponse; - this.loader = false; - this.error = null; - }); - } - return issuesLabelsResponse; - } catch (error) { - console.warn("error in fetching workspace level labels", error); - this.loader = false; - this.error = null; - return error; - } - }; - - getWorkspaceMyIssuesFilters = async (workspaceId: string) => { - try { - this.loader = true; - this.error = null; - - // fetching workspace level issue filters - await this.getWorkspaceMyIssuesProjects(workspaceId); - await this.getWorkspaceMyIssuesLabels(workspaceId); - - const issuesFiltersResponse = await this.workspaceService.workspaceMemberMe(workspaceId); - if (issuesFiltersResponse) { - const _issuesFiltersResponse: any = { - ...this.issueFilters, - [workspaceId]: { - ...this?.issueFilters?.[workspaceId], - my_issue_properties: { - ...this?.issueFilters?.[workspaceId]?.my_issue_properties, - filters: { - priority: issuesFiltersResponse?.view_props?.filters?.priority ?? null, - state: issuesFiltersResponse?.view_props?.filters?.state ?? null, - state_group: issuesFiltersResponse?.view_props?.filters?.state_group ?? null, - assignees: issuesFiltersResponse?.view_props?.filters?.assignees ?? null, - created_by: issuesFiltersResponse?.view_props?.filters?.created_by ?? null, - labels: issuesFiltersResponse?.view_props?.filters?.labels ?? null, - start_date: issuesFiltersResponse?.view_props?.filters?.start_date ?? null, - target_date: issuesFiltersResponse?.view_props?.filters?.target_date ?? null, - subscriber: issuesFiltersResponse?.view_props?.filters?.subscriber ?? null, - }, - display_filters: { - group_by: issuesFiltersResponse?.view_props?.display_filters?.group_by ?? null, - 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, - 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, - }, - 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, - 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, - 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, - }, - }, - }, - }; - runInAction(() => { - this.issueFilters = _issuesFiltersResponse; - this.loader = false; - this.error = null; - }); - } - return issuesFiltersResponse; - } catch (error) { - console.warn("error in fetching workspace level filters", error); - this.loader = false; - this.error = null; - return error; - } - }; - updateWorkspaceMyIssuesFilters = async (workspaceId: string, data: any) => { - try { - this.loader = true; - this.error = null; - - const payload = { - view_props: data, - }; - const issuesFiltersResponse = await this.workspaceService.updateWorkspaceView(workspaceId, payload); - - if (issuesFiltersResponse) { - runInAction(() => { - this.loader = false; - this.error = null; - }); - } - } catch (error) { - console.warn("error in fetching workspace level issue filters", error); - this.loader = false; - this.error = null; - return error; - } - }; - - getProjectLevelStates = async (workspaceId: string, projectId: string) => { - try { - this.loader = true; - this.error = null; - - const issuesStateResponse = await this.stateService.getStates(workspaceId, projectId); - if (issuesStateResponse) { - const _issuesStateResponse = { - ...this.issueRenderFilters, - workspace_properties: { - ...this.issueRenderFilters?.workspace_properties, - [workspaceId]: { - ...this.issueRenderFilters?.workspace_properties?.[workspaceId], - project_properties: { - ...this.issueRenderFilters?.workspace_properties?.[workspaceId]?.project_properties, - [projectId]: { - ...this.issueRenderFilters?.workspace_properties?.[workspaceId]?.project_properties?.[projectId], - states: issuesStateResponse, - }, - }, - }, - }, - }; - - runInAction(() => { - this.issueRenderFilters = _issuesStateResponse; - this.loader = false; - this.error = null; - }); - } - return issuesStateResponse; - } catch (error) { - console.warn("error in fetching project level states", error); - this.loader = false; - this.error = null; - return error; - } - }; - getProjectLevelLabels = async (workspaceId: string, projectId: string) => { - try { - this.loader = true; - this.error = null; - - const issuesLabelsResponse = await this.issueService.getIssueLabels(workspaceId, projectId); - if (issuesLabelsResponse) { - const _issuesLabelsResponse = { - ...this.issueRenderFilters, - workspace_properties: { - ...this.issueRenderFilters?.workspace_properties, - [workspaceId]: { - ...this.issueRenderFilters?.workspace_properties?.[workspaceId], - project_properties: { - ...this.issueRenderFilters?.workspace_properties?.[workspaceId]?.project_properties, - [projectId]: { - ...this.issueRenderFilters?.workspace_properties?.[workspaceId]?.project_properties?.[projectId], - labels: issuesLabelsResponse, - }, - }, - }, - }, - }; - - runInAction(() => { - this.issueRenderFilters = _issuesLabelsResponse; - this.loader = false; - this.error = null; - }); - } - return issuesLabelsResponse; - } catch (error) { - console.warn("error in fetching project level labels", error); - this.loader = false; - this.error = null; - return error; - } - }; - getProjectLevelMembers = async (workspaceId: string, projectId: string) => { - try { - this.loader = true; - this.error = null; - - const issuesMembersResponse = await this.projectService.projectMembers(workspaceId, projectId); - if (issuesMembersResponse) { - const _issuesMembersResponse = { - ...this.issueRenderFilters, - workspace_properties: { - ...this.issueRenderFilters?.workspace_properties, - [workspaceId]: { - ...this.issueRenderFilters?.workspace_properties?.[workspaceId], - project_properties: { - ...this.issueRenderFilters?.workspace_properties?.[workspaceId]?.project_properties, - [projectId]: { - ...this.issueRenderFilters?.workspace_properties?.[workspaceId]?.project_properties?.[projectId], - members: issuesMembersResponse, - }, - }, - }, - }, - }; - - runInAction(() => { - this.issueRenderFilters = _issuesMembersResponse; - this.loader = false; - this.error = null; - }); - } - return issuesMembersResponse; - } catch (error) { - console.warn("error in fetching project level members", error); - this.loader = false; - this.error = null; - return error; - } - }; - - getProjectDisplayProperties = async (workspaceId: string, projectId: string) => { - try { - this.loader = true; - this.error = null; - - await this.rootStore.user.setCurrentUser(); - const issuesDisplayPropertiesResponse = await this.issueService.getIssueProperties(workspaceId, projectId); - - if (issuesDisplayPropertiesResponse) { - const _issuesDisplayPropertiesResponse: any = { - ...this.issueFilters, - [workspaceId]: { - ...this?.issueFilters[workspaceId], - project_issue_properties: { - ...this?.issueFilters[workspaceId]?.project_issue_properties, - [projectId]: { - ...this?.issueFilters[workspaceId]?.project_issue_properties?.[projectId], - display_properties_id: issuesDisplayPropertiesResponse?.id, - display_properties: { - ...issuesDisplayPropertiesResponse?.properties, - }, - }, - }, - }, - }; - - runInAction(() => { - this.issueFilters = _issuesDisplayPropertiesResponse; - this.loader = false; - this.error = null; - }); - } - - return issuesDisplayPropertiesResponse; - } catch (error) { - console.warn("error in fetching project level display properties", error); - this.loader = false; - this.error = null; - return error; - } - }; - updateProjectDisplayProperties = async ( - workspaceId: string, - projectId: string, - display_properties_id: string, - data: any - ) => { - try { - this.loader = true; - this.error = null; - - const payload = { - properties: data, - user: this.rootStore?.user?.currentUser?.id, - }; - const issuesDisplayPropertiesResponse = await this.issueService.patchIssueProperties( - workspaceId, - projectId, - display_properties_id, - payload - ); - - if (issuesDisplayPropertiesResponse) { - runInAction(() => { - this.loader = false; - this.error = null; - }); - } - - return issuesDisplayPropertiesResponse; - } catch (error) { - console.warn("error in fetching project level display properties", error); - this.loader = false; - this.error = null; - return error; - } - }; - - getProjectDisplayFilters = async (workspaceId: string, projectId: string) => { - try { - this.loader = true; - this.error = null; - - const issuesDisplayFiltersResponse = await this.projectService.projectMemberMe(workspaceId, projectId); - - if (issuesDisplayFiltersResponse) { - const _filters = { ...issuesDisplayFiltersResponse?.view_props?.filters }; - const _displayFilters = { ...issuesDisplayFiltersResponse?.view_props?.display_filters }; - - const _issuesDisplayFiltersResponse: any = { - ...this.issueFilters, - [workspaceId]: { - ...this?.issueFilters[workspaceId], - project_issue_properties: { - ...this?.issueFilters[workspaceId]?.project_issue_properties, - [projectId]: { - ...this?.issueFilters[workspaceId]?.project_issue_properties?.[projectId], - issues: { - ...this?.issueFilters[workspaceId]?.project_issue_properties?.[projectId]?.issues, - filters: _filters, - display_filters: _displayFilters, - }, - }, - }, - }, - }; - - runInAction(() => { - this.issueFilters = _issuesDisplayFiltersResponse; - this.loader = false; - this.error = null; - }); - } - - return issuesDisplayFiltersResponse; - } catch (error) { - console.warn("error in fetching workspace level issue filters", error); - this.loader = false; - this.error = null; - return error; - } - }; - updateProjectDisplayFilters = async (workspaceId: string, projectId: string, data: any) => { - try { - this.loader = true; - this.error = null; - - const payload: any = { - view_props: data, - }; - const issuesFiltersResponse = await this.projectService.setProjectView(workspaceId, projectId, payload); - - if (issuesFiltersResponse) { - runInAction(() => { - this.loader = false; - this.error = null; - }); - } - - return issuesFiltersResponse; - } catch (error) { - this.getProjectDisplayFilters(workspaceId, projectId); - console.warn("error in fetching workspace level issue filters", error); - this.loader = false; - this.error = null; - return error; - } - }; - - getProjectIssueFilters = async (workspaceId: string, projectId: string) => { - try { - this.loader = true; - this.error = null; - - await this.getProjectLevelStates(workspaceId, projectId); - await this.getProjectLevelLabels(workspaceId, projectId); - await this.getProjectLevelMembers(workspaceId, projectId); - await this.getProjectDisplayProperties(workspaceId, projectId); - await this.getProjectDisplayFilters(workspaceId, projectId); - - runInAction(() => { - this.loader = false; - this.error = null; - }); - } catch (error) { - console.warn("error in fetching workspace level issue filters", error); - this.loader = false; - this.error = null; - return error; - } - }; - - 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); - - if (issuesFiltersModuleResponse) { - const _filters = { ...issuesFiltersModuleResponse?.view_props?.filters }; - const _issuesFiltersModuleResponse = { - ...this.issueFilters, - [workspaceId]: { - ...this?.issueFilters[workspaceId], - project_issue_properties: { - ...this?.issueFilters[workspaceId]?.project_issue_properties, - [projectId]: { - ...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], - filters: { - priority: _filters?.priority ?? undefined, - state: _filters?.state ?? undefined, - state_group: _filters?.state_group ?? undefined, - assignees: _filters?.assignees ?? undefined, - created_by: _filters?.created_by ?? undefined, - labels: _filters?.labels ?? undefined, - start_date: _filters?.start_date ?? undefined, - target_date: _filters?.target_date ?? undefined, - }, - }, - }, - }, - }, - }, - }; - - runInAction(() => { - this.issueFilters = _issuesFiltersModuleResponse as any; - this.loader = false; - this.error = null; - }); - } - } catch (error) { - console.warn("error in fetching workspace level issue filters", error); - this.loader = false; - this.error = null; - return error; - } - }; - updateProjectIssueModuleFilters = async (workspaceId: string, projectId: string, moduleId: string, data: any) => { - try { - this.loader = true; - this.error = null; - - const payload = { - view_props: { filters: data }, - }; - const issuesFiltersModuleResponse = await this.moduleService.patchModule( - workspaceId, - projectId, - moduleId, - payload, - undefined // TODO: replace this with user - ); - - if (issuesFiltersModuleResponse) { - runInAction(() => { - this.loader = false; - this.error = null; - }); - } - } catch (error) { - this.getProjectIssueModuleFilters(workspaceId, projectId, moduleId); - console.warn("error in fetching workspace level issue filters", error); - this.loader = false; - this.error = null; - return error; - } - }; - - 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); - - if (issuesFiltersCycleResponse) { - const _filters = { ...issuesFiltersCycleResponse?.view_props?.filters }; - const _issuesFiltersCycleResponse = { - ...this.issueFilters, - [workspaceId]: { - ...this?.issueFilters[workspaceId], - project_issue_properties: { - ...this?.issueFilters[workspaceId]?.project_issue_properties, - [projectId]: { - ...this?.issueFilters[workspaceId]?.project_issue_properties?.[projectId], - cycles: { - ...this?.issueFilters[workspaceId]?.project_issue_properties?.[projectId]?.cycles, - [cycleId]: { - ...this?.issueFilters[workspaceId]?.project_issue_properties?.[projectId]?.modules?.[cycleId], - filters: { - priority: _filters?.priority ?? undefined, - state: _filters?.state ?? undefined, - state_group: _filters?.state_group ?? undefined, - assignees: _filters?.assignees ?? undefined, - created_by: _filters?.created_by ?? undefined, - labels: _filters?.labels ?? undefined, - start_date: _filters?.start_date ?? undefined, - target_date: _filters?.target_date ?? undefined, - }, - }, - }, - }, - }, - }, - }; - - runInAction(() => { - this.issueFilters = _issuesFiltersCycleResponse as any; - this.loader = false; - this.error = null; - }); - } - } catch (error) { - console.warn("error in fetching workspace level issue filters", error); - this.loader = false; - this.error = null; - return error; - } - }; - updateProjectIssueCyclesFilters = async (workspaceId: string, projectId: string, cycleId: string, data: any) => { - try { - this.loader = true; - this.error = null; - - const payload = { - view_props: { filters: data }, - }; - const issuesFiltersCycleResponse = await this.cycleService.patchCycle( - workspaceId, - projectId, - cycleId, - payload, - undefined // TODO: replace this with user - ); - - if (issuesFiltersCycleResponse) { - runInAction(() => { - this.loader = false; - this.error = null; - }); - } - } catch (error) { - this.getProjectIssueCyclesFilters(workspaceId, projectId, cycleId); - console.warn("error in fetching workspace level issue filters", error); - this.loader = false; - this.error = null; - return error; - } - }; - - getProjectIssueViewsFilters = async (workspaceId: string, projectId: string, viewId: string) => { - try { - this.loader = true; - this.error = null; - - await this.getProjectIssueFilters(workspaceId, projectId); - - const issuesFiltersViewResponse = await this.viewService.getViewDetails(workspaceId, projectId, viewId); - - if (issuesFiltersViewResponse) { - const _filters = { ...issuesFiltersViewResponse?.query_data } as any; - const _issuesFiltersViewResponse = { - ...this.issueFilters, - [workspaceId]: { - ...this?.issueFilters[workspaceId], - project_issue_properties: { - ...this?.issueFilters[workspaceId]?.project_issue_properties, - [projectId]: { - ...this?.issueFilters[workspaceId]?.project_issue_properties?.[projectId], - views: { - ...this?.issueFilters[workspaceId]?.project_issue_properties?.[projectId]?.cycles, - [viewId]: { - ...this?.issueFilters[workspaceId]?.project_issue_properties?.[projectId]?.modules?.[viewId], - filters: { - priority: _filters?.priority ?? undefined, - state: _filters?.state ?? undefined, - state_group: _filters?.state_group ?? undefined, - assignees: _filters?.assignees ?? undefined, - created_by: _filters?.created_by ?? undefined, - labels: _filters?.labels ?? undefined, - start_date: _filters?.start_date ?? undefined, - target_date: _filters?.target_date ?? undefined, - }, - }, - }, - }, - }, - }, - }; - - runInAction(() => { - this.issueFilters = _issuesFiltersViewResponse as any; - this.loader = false; - this.error = null; - }); - } - } catch (error) { - console.warn("error in fetching workspace level issue filters", error); - this.loader = false; - this.error = null; - return error; - } - }; - updateProjectIssueViewsFilters = async (workspaceId: string, projectId: string, viewId: string, data: any) => { - try { - this.loader = true; - this.error = null; - - const payload = { - query_data: data, - }; - const issuesFiltersViewResponse = await this.viewService.patchView( - workspaceId, - projectId, - viewId, - payload, - undefined // TODO: replace this with user - ); - - if (issuesFiltersViewResponse) { - runInAction(() => { - this.loader = false; - this.error = null; - }); - } - - return issuesFiltersViewResponse; - } catch (error) { - this.getProjectIssueViewsFilters(projectId, workspaceId, viewId); - console.warn("error in fetching workspace level issue filters", error); - this.loader = false; - this.error = null; - return error; - } - }; -} - -export default IssueFilterStore; diff --git a/web/store/issue-views/project.ts b/web/store/issue-views/project.ts deleted file mode 100644 index ad7c72b84..000000000 --- a/web/store/issue-views/project.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { action, computed, makeObservable } from "mobx"; -// types -import { RootStore } from "../root"; - -export interface IIssueProject {} - -class IssueProject implements IIssueProject { - // root store - rootStore; - - constructor(_rootStore: RootStore) { - makeObservable(this, { - // computed - // actions - }); - - this.rootStore = _rootStore; - } -} - -export default IssueProject; diff --git a/web/store/issue-views/workspace.ts b/web/store/issue-views/workspace.ts deleted file mode 100644 index 0203e6cfd..000000000 --- a/web/store/issue-views/workspace.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { action, computed, makeObservable } from "mobx"; -// types -import { RootStore } from "../root"; - -export interface IIssueWorkspace {} - -class IssueWorkspace implements IIssueWorkspace { - // root store - rootStore; - - constructor(_rootStore: RootStore) { - makeObservable(this, { - // computed - // actions - }); - - this.rootStore = _rootStore; - } -} - -export default IssueWorkspace; diff --git a/web/store/issue-views/issue_detail.ts b/web/store/issue_detail.ts similarity index 99% rename from web/store/issue-views/issue_detail.ts rename to web/store/issue_detail.ts index c1dae8222..04fa1fa4d 100644 --- a/web/store/issue-views/issue_detail.ts +++ b/web/store/issue_detail.ts @@ -1,6 +1,6 @@ import { observable, action, makeObservable, runInAction } from "mobx"; // types -import { RootStore } from "../root"; +import { RootStore } from "./root"; // services import { ProjectIssuesServices } from "services/issues.service"; diff --git a/web/store/issues.ts b/web/store/issues.ts index 286d98534..2c0eaeff4 100644 --- a/web/store/issues.ts +++ b/web/store/issues.ts @@ -31,10 +31,7 @@ class IssuesStore { loadIssues = async (workspaceSlug: string, projectId: string) => { this.isIssuesLoading = true; try { - const issuesResponse: IIssue[] = (await issueService.getIssuesWithParams( - workspaceSlug, - projectId - )) as IIssue[]; + const issuesResponse: IIssue[] = (await issueService.getIssuesWithParams(workspaceSlug, projectId)) as IIssue[]; const issues: { [kye: string]: IIssue } = {}; issuesResponse.forEach((issue) => { @@ -51,11 +48,7 @@ class IssuesStore { } }; - getIssueById = async ( - workspaceSlug: string, - projectId: string, - issueId: string - ): Promise => { + getIssueById = async (workspaceSlug: string, projectId: string, issueId: string): Promise => { if (this.issues[issueId]) return this.issues[issueId]; try { @@ -83,12 +76,7 @@ class IssuesStore { user: ICurrentUserResponse ): Promise => { try { - const issueResponse = await issueService.createIssues( - workspaceSlug, - projectId, - issueForm, - user - ); + const issueResponse = await issueService.createIssues(workspaceSlug, projectId, issueForm, user); const issues = { ...this.issues, @@ -125,13 +113,7 @@ class IssuesStore { }); // make a patch request to update the issue - const issueResponse: IIssue = await issueService.patchIssue( - workspaceSlug, - projectId, - issueId, - issueForm, - user - ); + const issueResponse: IIssue = await issueService.patchIssue(workspaceSlug, projectId, issueId, issueForm, user); const updatedIssues = { ...this.issues }; updatedIssues[issueId] = { ...issueResponse }; @@ -149,12 +131,7 @@ class IssuesStore { } }; - deleteIssue = async ( - workspaceSlug: string, - projectId: string, - issueId: string, - user: ICurrentUserResponse - ) => { + deleteIssue = async (workspaceSlug: string, projectId: string, issueId: string, user: ICurrentUserResponse) => { const issues = { ...this.issues }; delete issues[issueId]; diff --git a/web/store/modules.ts b/web/store/modules.ts new file mode 100644 index 000000000..612702700 --- /dev/null +++ b/web/store/modules.ts @@ -0,0 +1,55 @@ +import { action, computed, observable, makeObservable, runInAction } from "mobx"; +// types +import { RootStore } from "./root"; +// services +import { ProjectServices } from "services/project.service"; +import { ProjectIssuesServices as IssueServices } from "services/issues.service"; + +export interface IModuleStore { + loader: boolean; + error: any | null; + + moduleId: string | null; + + setModuleId: (moduleSlug: string) => void; +} + +class ModuleStore implements IModuleStore { + loader: boolean = false; + error: any | null = null; + + moduleId: string | null = null; + + // root store + rootStore; + // services + projectService; + issueService; + + constructor(_rootStore: RootStore) { + makeObservable(this, { + loader: observable, + error: observable.ref, + + moduleId: observable.ref, + + // computed + + // actions + setModuleId: action, + }); + + this.rootStore = _rootStore; + this.projectService = new ProjectServices(); + this.issueService = new IssueServices(); + } + + // computed + + // actions + setModuleId = (moduleSlug: string) => { + this.moduleId = moduleSlug ?? null; + }; +} + +export default ModuleStore; diff --git a/web/store/project.ts b/web/store/project.ts deleted file mode 100644 index 0fe842dad..000000000 --- a/web/store/project.ts +++ /dev/null @@ -1,86 +0,0 @@ -import { observable, action, computed, makeObservable, runInAction } from "mobx"; -// types -import { RootStore } from "./root"; -// services -import { ProjectServices } from "services/project.service"; - -export interface IProject { - id: string; - name: string; - workspaceSlug: string; -} - -export interface IProjectStore { - loader: boolean; - error: any | null; - - projectLeaveModal: boolean; - projectLeaveDetails: IProject | any; - - handleProjectLeaveModal: (project: IProject | null) => void; - - leaveProject: (workspace_slug: string, project_slug: string, user: any) => Promise; -} - -class ProjectStore implements IProjectStore { - loader: boolean = false; - error: any | null = null; - - projectLeaveModal: boolean = false; - projectLeaveDetails: IProject | null = null; - - // root store - rootStore; - // service - projectService; - - constructor(_rootStore: RootStore) { - makeObservable(this, { - // observable - loader: observable, - error: observable, - - projectLeaveModal: observable, - projectLeaveDetails: observable.ref, - // action - handleProjectLeaveModal: action, - leaveProject: action, - // computed - }); - - this.rootStore = _rootStore; - this.projectService = new ProjectServices(); - } - - handleProjectLeaveModal = (project: IProject | null = null) => { - if (project && project?.id) { - this.projectLeaveModal = !this.projectLeaveModal; - this.projectLeaveDetails = project; - } else { - this.projectLeaveModal = !this.projectLeaveModal; - this.projectLeaveDetails = null; - } - }; - - leaveProject = async (workspace_slug: string, project_slug: string, user: any) => { - try { - this.loader = true; - this.error = null; - - const response = await this.projectService.leaveProject(workspace_slug, project_slug, user); - - runInAction(() => { - this.loader = false; - this.error = null; - }); - - return response; - } catch (error) { - this.loader = false; - this.error = error; - return error; - } - }; -} - -export default ProjectStore; diff --git a/web/store/projects.ts b/web/store/projects.ts new file mode 100644 index 000000000..36c2c9268 --- /dev/null +++ b/web/store/projects.ts @@ -0,0 +1,309 @@ +import { observable, action, computed, makeObservable, runInAction } from "mobx"; +// types +import { RootStore } from "./root"; +import { IProject, IIssueLabels, IProjectMember, IStateResponse, IState } from "types"; +// services +import { ProjectServices } from "services/project.service"; +import { ProjectIssuesServices } from "services/issues.service"; +import { ProjectStateServices } from "services/state.service"; + +export interface IProjectStore { + loader: boolean; + error: any | null; + + projectLeaveModal: boolean; + projectLeaveDetails: IProject | any; + + projectId: string | null; + projects: { + [key: string]: { [key: string]: IProject }; // workspace_id: project_id: projects + } | null; + states: { + [key: string]: IStateResponse; // project_id: states + } | null; + labels: { + [key: string]: IIssueLabels[]; // project_id: labels + } | null; + members: { + [key: string]: IProjectMember[]; // project_id: members + } | null; + + // computed + projectStatesByGroups: IStateResponse | null; + projectStates: IState[] | null; + projectLabels: IIssueLabels[] | null; + projectMembers: IProjectMember[] | null; + workspaceProjects: { [key: string]: IProject } | null; + + // actions + projectStateById: (stateId: string) => IState | null; + projectLabelById: (labelId: string) => IIssueLabels | null; + projectMemberById: (memberId: string) => IProjectMember | null; + + setProject: (projectSlug: string) => void; + + getWorkspaceProjects: (workspaceSlug: string, is_favorite?: "all" | boolean) => Promise; + getProjectStates: (workspaceSlug: string, projectSlug: string) => Promise; + getProjectLabels: (workspaceSlug: string, projectSlug: string) => Promise; + getProjectMembers: (workspaceSlug: string, projectSlug: string) => Promise; + + handleProjectLeaveModal: (project: IProject | null) => void; + + leaveProject: (workspaceSlug: string, projectSlug: string, user: any) => Promise; +} + +class ProjectStore implements IProjectStore { + loader: boolean = false; + error: any | null = null; + + projectLeaveModal: boolean = false; + projectLeaveDetails: IProject | null = null; + + projectId: string | null = null; + projects: { + [key: string]: { [key: string]: IProject }; // workspace_id: project_id: projects + } | null = null; + states: { + [key: string]: IStateResponse; // project_id: states + } | null = null; + labels: { + [key: string]: IIssueLabels[]; // project_id: labels + } | null = null; + members: { + [key: string]: IProjectMember[]; // project_id: members + } | null = null; + + // root store + rootStore; + // service + projectService; + issueService; + stateService; + + constructor(_rootStore: RootStore) { + makeObservable(this, { + // observable + loader: observable, + error: observable, + + projectId: observable.ref, + projects: observable.ref, + states: observable.ref, + labels: observable.ref, + members: observable.ref, + + projectLeaveModal: observable, + projectLeaveDetails: observable.ref, + + // computed + workspaceProjects: computed, + projectStatesByGroups: computed, + projectStates: computed, + projectLabels: computed, + projectMembers: computed, + + // action + setProject: action, + + projectStateById: action, + projectLabelById: action, + projectMemberById: action, + + getWorkspaceProjects: action, + getProjectStates: action, + getProjectLabels: action, + getProjectMembers: action, + + handleProjectLeaveModal: action, + leaveProject: action, + }); + + this.rootStore = _rootStore; + this.projectService = new ProjectServices(); + this.issueService = new ProjectIssuesServices(); + this.stateService = new ProjectStateServices(); + } + + // computed + get workspaceProjects() { + if (!this.rootStore.workspace.workspaceId) return null; + return this.projects?.[this.rootStore.workspace.workspaceId] || null; + } + get projectStatesByGroups() { + if (!this.projectId) return null; + return this.states?.[this.projectId] || null; + } + get projectStates() { + if (!this.projectId) return null; + const stateByGroups: IStateResponse | null = this.projectStatesByGroups; + if (!stateByGroups) return null; + const _states: IState[] = []; + Object.keys(stateByGroups).forEach((_stateGroup: string) => { + stateByGroups[_stateGroup].map((state) => { + _states.push(state); + }); + }); + return _states && _states.length > 0 ? _states : null; + } + get projectLabels() { + if (!this.projectId) return null; + return this.labels?.[this.projectId] || null; + } + get projectMembers() { + if (!this.projectId) return null; + return this.members?.[this.projectId] || null; + } + + // actions + projectStateById = (stateId: string) => { + if (!this.projectId) return null; + const states = this.projectStates; + if (!states) return null; + const stateInfo: IState | null = states.find((state) => state.id === stateId) || null; + return stateInfo; + }; + projectLabelById = (labelId: string) => { + if (!this.projectId) return null; + const labels = this.projectLabels; + if (!labels) return null; + const labelInfo: IIssueLabels | null = labels.find((label) => label.id === labelId) || null; + return labelInfo; + }; + projectMemberById = (memberId: string) => { + if (!this.projectId) return null; + const members = this.projectMembers; + if (!members) return null; + const memberInfo: IProjectMember | null = members.find((member) => member.id === memberId) || null; + return memberInfo; + }; + + setProject = (projectSlug: string) => { + this.projectId = projectSlug ?? null; + }; + + getWorkspaceProjects = async (workspaceSlug: string, is_favorite: "all" | boolean = "all") => { + try { + this.loader = true; + this.error = null; + + const params: { is_favorite: "all" | boolean } = { is_favorite: is_favorite }; + const projectsResponse = await this.projectService.getProjects(workspaceSlug, params); + + let _projects: { [key: string]: IProject } = {}; + projectsResponse.map((project) => { + _projects = { ..._projects, [project.id]: project }; + }); + + runInAction(() => { + this.projects = { + ...this.projects, + [workspaceSlug]: _projects, + }; + this.loader = false; + this.error = null; + }); + } catch (error) { + console.error(error); + this.loader = false; + this.error = error; + } + }; + getProjectStates = async (workspaceSlug: string, projectSlug: string) => { + try { + this.loader = true; + this.error = null; + + const stateResponse = await this.stateService.getStates(workspaceSlug, projectSlug); + const _states = { + ...this.states, + [projectSlug]: stateResponse, + }; + + runInAction(() => { + this.states = _states; + this.loader = false; + this.error = null; + }); + } catch (error) { + console.error(error); + this.loader = false; + this.error = error; + } + }; + getProjectLabels = async (workspaceSlug: string, projectSlug: string) => { + try { + this.loader = true; + this.error = null; + + const labelResponse = await this.issueService.getIssueLabels(workspaceSlug, projectSlug); + const _labels = { + ...this.labels, + [projectSlug]: labelResponse, + }; + + runInAction(() => { + this.labels = _labels; + this.loader = false; + this.error = null; + }); + } catch (error) { + console.error(error); + this.loader = false; + this.error = error; + } + }; + getProjectMembers = async (workspaceSlug: string, projectSlug: string) => { + try { + this.loader = true; + this.error = null; + + const membersResponse = await this.projectService.projectMembers(workspaceSlug, projectSlug); + const _members = { + ...this.members, + [projectSlug]: membersResponse, + }; + + runInAction(() => { + this.members = _members; + this.loader = false; + this.error = null; + }); + } catch (error) { + console.error(error); + this.loader = false; + this.error = error; + } + }; + + handleProjectLeaveModal = (project: IProject | null = null) => { + if (project && project?.id) { + this.projectLeaveModal = !this.projectLeaveModal; + this.projectLeaveDetails = project; + } else { + this.projectLeaveModal = !this.projectLeaveModal; + this.projectLeaveDetails = null; + } + }; + + leaveProject = async (workspaceSlug: string, projectSlug: string, user: any) => { + try { + this.loader = true; + this.error = null; + + const response = await this.projectService.leaveProject(workspaceSlug, projectSlug, user); + + runInAction(() => { + this.loader = false; + this.error = null; + }); + + return response; + } catch (error) { + this.loader = false; + this.error = error; + return error; + } + }; +} + +export default ProjectStore; diff --git a/web/store/root.ts b/web/store/root.ts index 763ac5e31..70f092231 100644 --- a/web/store/root.ts +++ b/web/store/root.ts @@ -3,15 +3,18 @@ import { enableStaticRendering } from "mobx-react-lite"; // store imports import UserStore from "./user"; import ThemeStore from "./theme"; -import ProjectStore, { IProjectStore } from "./project"; import ProjectPublishStore, { IProjectPublishStore } from "./project-publish"; import IssuesStore from "./issues"; -// issues views and filters -import IssueWorkspace from "./issue-views/workspace"; -import IssueProject from "./issue-views/project"; -import IssueFilterStore from "./issue-views/issue_filters"; -import IssueViewStore from "./issue-views/Issues"; -import IssueViewDetailStore from "./issue-views/issue_detail"; + +import WorkspaceStore, { IWorkspaceStore } from "./workspaces"; +import ProjectStore, { IProjectStore } from "./projects"; +import IssueStore, { IIssueStore } from "./issue-store"; +import ModuleStore, { IModuleStore } from "./modules"; +import CycleStore, { ICycleStore } from "./cycles"; +import ViewStore, { IViewStore } from "./views"; +import IssueFilterStore, { IIssueFilterStore } from "./issue-filters"; + +import IssueViewDetailStore from "./issue_detail"; import IssueKanBanViewStore from "./issue-views/kanban-view"; enableStaticRendering(typeof window === "undefined"); @@ -19,28 +22,33 @@ enableStaticRendering(typeof window === "undefined"); export class RootStore { user; theme; - project: IProjectStore; projectPublish: IProjectPublishStore; issues: IssuesStore; - // issues views and filters - issueWorkspace: IssueWorkspace; - issueProject: IssueProject; - issueFilters: IssueFilterStore; - issueView: IssueViewStore; + + workspace: IWorkspaceStore; + project: IProjectStore; + issue: IIssueStore; + module: IModuleStore; + cycle: ICycleStore; + view: IViewStore; + issueFilter: IIssueFilterStore; issueDetail: IssueViewDetailStore; issueKanBanView: IssueKanBanViewStore; constructor() { this.user = new UserStore(this); this.theme = new ThemeStore(this); - this.project = new ProjectStore(this); this.projectPublish = new ProjectPublishStore(this); this.issues = new IssuesStore(this); - // issues views and filters - this.issueWorkspace = new IssueWorkspace(this); - this.issueProject = new IssueProject(this); - this.issueFilters = new IssueFilterStore(this); - this.issueView = new IssueViewStore(this); + + this.workspace = new WorkspaceStore(this); + this.project = new ProjectStore(this); + this.issue = new IssueStore(this); + this.module = new ModuleStore(this); + this.cycle = new CycleStore(this); + this.view = new ViewStore(this); + this.issueFilter = new IssueFilterStore(this); + this.issueDetail = new IssueViewDetailStore(this); this.issueKanBanView = new IssueKanBanViewStore(this); } diff --git a/web/store/views.ts b/web/store/views.ts new file mode 100644 index 000000000..c29d88864 --- /dev/null +++ b/web/store/views.ts @@ -0,0 +1,55 @@ +import { action, computed, observable, makeObservable, runInAction } from "mobx"; +// types +import { RootStore } from "./root"; +// services +import { ProjectServices } from "services/project.service"; +import { ProjectIssuesServices as IssueServices } from "services/issues.service"; + +export interface IViewStore { + loader: boolean; + error: any | null; + + viewId: string | null; + + setViewId: (viewSlug: string) => void; +} + +class ViewStore implements IViewStore { + loader: boolean = false; + error: any | null = null; + + viewId: string | null = null; + + // root store + rootStore; + // services + projectService; + issueService; + + constructor(_rootStore: RootStore) { + makeObservable(this, { + loader: observable, + error: observable.ref, + + viewId: observable.ref, + + // computed + + // actions + setViewId: action, + }); + + this.rootStore = _rootStore; + this.projectService = new ProjectServices(); + this.issueService = new IssueServices(); + } + + // computed + + // actions + setViewId = (viewSlug: string) => { + this.viewId = viewSlug ?? null; + }; +} + +export default ViewStore; diff --git a/web/store/workspaces.ts b/web/store/workspaces.ts new file mode 100644 index 000000000..60c2cb3e6 --- /dev/null +++ b/web/store/workspaces.ts @@ -0,0 +1,198 @@ +import { action, computed, observable, makeObservable, runInAction } from "mobx"; +// types +import { RootStore } from "./root"; +import { IIssueLabels, IWorkspace } from "types"; +// services +import { WorkspaceService } from "services/workspace.service"; +import { ProjectServices } from "services/project.service"; +import { ProjectIssuesServices as IssueServices } from "services/issues.service"; + +export interface IWorkspaceStore { + loader: boolean; + error: any | null; + + workspaces: { + [key: string]: IWorkspace; // workspace_id: workspace + } | null; + labels: { [key: string]: { [key: string]: IIssueLabels } } | null; // workspace_id: label_id: labels + workspaceId: string | null; + + // computed + currentWorkspace: IWorkspace | null; + workspaceLabels: { [key: string]: IIssueLabels } | null; + + // actions + setWorkspaceId: (workspaceSlug: string) => void; + + workspaceById: (workspaceId: string) => IWorkspace | null; + workspaceLabelById: (labelId: string) => IIssueLabels | null; + + getWorkspaces: () => Promise; + getWorkspaceLabels: (workspaceSlug: string) => Promise; +} + +class WorkspaceStore implements IWorkspaceStore { + loader: boolean = false; + error: any | null = null; + + workspaces: { + [key: string]: IWorkspace; + } | null = null; + labels: { + [key: string]: { [key: string]: IIssueLabels }; + } | null = null; + workspaceId: string | null = null; + + // root store + rootStore; + // services + workspaceService; + projectService; + issueService; + + constructor(_rootStore: RootStore) { + makeObservable(this, { + loader: observable, + error: observable.ref, + + workspaces: observable.ref, + labels: observable.ref, + workspaceId: observable.ref, + + // computed + currentWorkspace: computed, + workspaceLabels: computed, + + // actions + setWorkspaceId: action, + workspaceById: action, + workspaceLabelById: action, + + getWorkspaces: action, + getWorkspaceLabels: action, + }); + + this.rootStore = _rootStore; + this.workspaceService = new WorkspaceService(); + this.projectService = new ProjectServices(); + this.issueService = new IssueServices(); + } + + // computed + get currentWorkspace() { + if (!this.workspaceId) return null; + return this.workspaces?.[this.workspaceId] || null; + } + get workspaceLabels() { + if (!this.workspaceId) return null; + const _labels = this.labels?.[this.workspaceId]; + return _labels && Object.keys(_labels).length > 0 ? _labels : null; + } + + // actions + workspaceById = (workspaceId: string) => this.workspaces?.[workspaceId] || null; + workspaceLabelById = (labelId: string) => { + if (!this.workspaceId) return null; + return this.labels?.[this.workspaceId]?.[labelId] || null; + }; + + setWorkspaceId = (workspaceSlug: string) => { + this.workspaceId = workspaceSlug ?? null; + }; + + getWorkspaces = async () => { + try { + this.loader = true; + this.error = null; + + const workspaceResponse = await this.workspaceService.userWorkspaces(); + + let _workspaces: { [key: string]: IWorkspace } = {}; + workspaceResponse.map((_workspace) => { + _workspaces = { ..._workspaces, [_workspace.slug]: _workspace }; + }); + + runInAction(() => { + this.workspaces = _workspaces; + this.loader = false; + this.error = null; + }); + } catch (error) { + console.log(error); + this.loader = false; + this.error = error; + } + }; + + getWorkspaceLabels = async (workspaceSlug: string) => { + try { + this.loader = true; + this.error = null; + + const labelsResponse = await this.issueService.getWorkspaceLabels(workspaceSlug); + let _labels: { [key: string]: IIssueLabels } = {}; + labelsResponse.map((_label) => { + _labels = { ..._labels, [_label.id]: _label }; + }); + + runInAction(() => { + this.labels = { + ...this.labels, + [workspaceSlug]: _labels, + }; + this.loader = false; + this.error = null; + }); + } catch (error) { + console.log(error); + this.loader = false; + this.error = error; + } + }; + + // getMyIssuesAsync = async (workspaceId: string, fetchFilterToggle: boolean = true) => { + // try { + // this.loader = true; + // this.error = null; + + // if (fetchFilterToggle) await this.rootStore.issueFilters.getWorkspaceMyIssuesFilters(workspaceId); + // const filteredParams = this.rootStore.issueFilters.getComputedFilters( + // workspaceId, + // null, + // null, + // null, + // null, + // "my_issues" + // ); + // const issuesResponse = await this.userService.userIssues(workspaceId, filteredParams); + + // if (issuesResponse) { + // const _issueResponse: any = { + // ...this.issues, + // [workspaceId]: { + // ...this?.issues[workspaceId], + // my_issues: { + // ...this?.issues[workspaceId]?.my_issues, + // [this.rootStore?.issueFilters?.userFilters?.display_filters?.layout as string]: issuesResponse, + // }, + // }, + // }; + + // runInAction(() => { + // this.issues = _issueResponse; + // this.loader = false; + // this.error = null; + // }); + // } + + // return issuesResponse; + // } catch (error) { + // console.warn("error in fetching the my issues", error); + // this.loader = false; + // this.error = null; + // return error; + // } + // }; +} + +export default WorkspaceStore;