-
-
0 ? (
+ <>
+
+
+
+
+
+
+ setSearch(e.target.value)}
+ placeholder="Search"
+ displayValue={(assigned: any) => assigned?.name}
/>
-
{selectedOption?.title}
+
+ {search && search.length > 0 && (
+
setSearch("")}
+ className="flex-shrink-0 flex justify-center items-center w-[16px] h-[16px] rounded-sm cursor-pointer hover:bg-custom-background-80"
+ >
+
+
+ )}
-
- ) : (
- Select option
- )}
- {dropdownArrow && !disabled && (
-
-
-
- )}
-
-
-
-
- {options && options.length > 0 ? (
- <>
-
-
-
-
-
-
- setSearch(e.target.value)}
- placeholder="Search"
- displayValue={(assigned: any) => assigned?.name}
- />
-
-
- {search && search.length > 0 && (
-
setSearch("")}
- className="flex-shrink-0 flex justify-center items-center w-[16px] h-[16px] rounded-sm cursor-pointer hover:bg-custom-background-80"
- >
-
-
- )}
-
-
-
- {filteredOptions ? (
- filteredOptions.length > 0 ? (
- filteredOptions.map((option) => (
-
- `cursor-pointer select-none truncate rounded px-1 py-1.5 ${
- active || selected ? "bg-custom-background-80" : ""
- } ${selected ? "text-custom-text-100" : "text-custom-text-200"}`
- }
- >
- {({ selected }) => (
-
-
-
-
-
{option.title}
- {selected && (
-
-
-
- )}
+
+ {filteredOptions ? (
+ filteredOptions.length > 0 ? (
+ filteredOptions.map((option) => (
+
+ `cursor-pointer select-none truncate rounded px-1 py-1.5 ${
+ active || selected ? "bg-custom-background-80" : ""
+ } ${selected ? "text-custom-text-100" : "text-custom-text-200"}`
+ }
+ >
+ {({ selected }) => (
+
+
+
- )}
-
- ))
- ) : (
-
- No matching results
-
- )
+
{option.title}
+ {selected && (
+
+
+
+ )}
+
+ )}
+
+ ))
) : (
-
Loading...
- )}
-
- >
- ) : (
-
No options available.
- )}
-
-
- >
- );
- }}
-
- );
- }
-);
+
+ No matching results
+
+ )
+ ) : (
+ Loading...
+ )}
+
+ >
+ ) : (
+ No options available.
+ )}
+
+
+ >
+ );
+ }}
+
+ );
+});
diff --git a/web/components/profile/index.ts b/web/components/profile/index.ts
index 382994a38..247a10dc6 100644
--- a/web/components/profile/index.ts
+++ b/web/components/profile/index.ts
@@ -3,3 +3,5 @@ export * from "./navbar";
export * from "./profile-issues-view-options";
export * from "./profile-issues-view";
export * from "./sidebar";
+
+export * from "./profile-issues-filter";
diff --git a/web/components/profile/navbar.tsx b/web/components/profile/navbar.tsx
index e8988d670..cd43cc974 100644
--- a/web/components/profile/navbar.tsx
+++ b/web/components/profile/navbar.tsx
@@ -4,7 +4,7 @@ import { useRouter } from "next/router";
import Link from "next/link";
// components
-import { ProfileIssuesViewOptions } from "components/profile";
+import { ProfileIssuesFilter } from "components/profile";
// types
import { UserAuth } from "types";
@@ -43,9 +43,7 @@ export const ProfileNavbar: React.FC = ({ memberRole }) => {
const { workspaceSlug, userId } = router.query;
const tabsList =
- memberRole.isOwner || memberRole.isMember || memberRole.isViewer
- ? [...viewerTabs, ...adminTabs]
- : viewerTabs;
+ memberRole.isOwner || memberRole.isMember || memberRole.isViewer ? [...viewerTabs, ...adminTabs] : viewerTabs;
return (
@@ -64,7 +62,7 @@ export const ProfileNavbar: React.FC
= ({ memberRole }) => {
))}
-
+
);
};
diff --git a/web/components/profile/profile-issues-filter.tsx b/web/components/profile/profile-issues-filter.tsx
new file mode 100644
index 000000000..ad02673c4
--- /dev/null
+++ b/web/components/profile/profile-issues-filter.tsx
@@ -0,0 +1,70 @@
+import { observer } from "mobx-react-lite";
+// components
+import { DisplayFiltersSelection, FilterSelection, FiltersDropdown, LayoutSelection } from "components/issues";
+// hooks
+import { useMobxStore } from "lib/mobx/store-provider";
+import { RootStore } from "store/root";
+// constants
+import { ISSUE_DISPLAY_FILTERS_BY_LAYOUT } from "constants/issue";
+
+export const ProfileIssuesFilter = observer(() => {
+ const { workspace: workspaceStore, profileIssueFilters: profileIssueFiltersStore }: RootStore = useMobxStore();
+
+ const handleLayoutChange = (_layout: string) =>
+ profileIssueFiltersStore.handleIssueFilters("userDisplayFilters", { layout: _layout });
+
+ const handleFilters = (key: any, value: any) => {
+ let updatesFilters: any = profileIssueFiltersStore?.userFilters;
+ updatesFilters = updatesFilters[key] || [];
+ if (updatesFilters && updatesFilters.length > 0 && updatesFilters.includes(value))
+ updatesFilters = updatesFilters.filter((item: any) => item !== value);
+ else updatesFilters.push(value);
+ profileIssueFiltersStore.handleIssueFilters("userFilters", { [key]: updatesFilters });
+ };
+
+ const handleDisplayFilters = (value: any) => profileIssueFiltersStore.handleIssueFilters("userDisplayFilters", value);
+
+ const handleDisplayProperties = (value: any) =>
+ profileIssueFiltersStore.handleIssueFilters("userDisplayProperties", value);
+
+ const states = undefined;
+ const labels = workspaceStore.workspaceLabels || undefined;
+ const members = undefined;
+
+ const activeLayout = profileIssueFiltersStore?.userDisplayFilters?.layout;
+
+ return (
+
+ handleLayoutChange(layout)}
+ selectedLayout={activeLayout}
+ />
+
+
+
+
+
+
+
+
+
+ );
+});
diff --git a/web/constants/issue.ts b/web/constants/issue.ts
index 246fc20f5..188ac4b5b 100644
--- a/web/constants/issue.ts
+++ b/web/constants/issue.ts
@@ -220,6 +220,90 @@ export interface ILayoutDisplayFiltersOptions {
export const ISSUE_DISPLAY_FILTERS_BY_LAYOUT: {
[pageType: string]: { [layoutType: string]: ILayoutDisplayFiltersOptions };
} = {
+ profile_issues: {
+ list: {
+ filters: ["priority", "state_group", "labels", "start_date", "target_date"],
+ display_properties: true,
+ display_filters: {
+ group_by: ["state_detail.group", "priority", "project", "labels", null],
+ order_by: ["sort_order", "-created_at", "-updated_at", "start_date", "priority"],
+ type: [null, "active", "backlog"],
+ },
+ extra_options: {
+ access: true,
+ values: ["show_empty_groups"],
+ },
+ },
+ kanban: {
+ filters: ["priority", "state_group", "labels", "start_date", "target_date"],
+ display_properties: true,
+ display_filters: {
+ group_by: ["state_detail.group", "priority", "project", "labels", null],
+ order_by: ["sort_order", "-created_at", "-updated_at", "start_date", "priority"],
+ type: [null, "active", "backlog"],
+ },
+ extra_options: {
+ access: true,
+ values: ["show_empty_groups"],
+ },
+ },
+ },
+ archived_issues: {
+ list: {
+ filters: ["priority", "state_group", "labels", "start_date", "target_date"],
+ display_properties: true,
+ display_filters: {
+ group_by: ["state_detail.group", "priority", "project", "labels", null],
+ order_by: ["sort_order", "-created_at", "-updated_at", "start_date", "priority"],
+ type: [null, "active", "backlog"],
+ },
+ extra_options: {
+ access: true,
+ values: ["show_empty_groups"],
+ },
+ },
+ kanban: {
+ filters: ["priority", "state_group", "labels", "start_date", "target_date"],
+ display_properties: true,
+ display_filters: {
+ group_by: ["state_detail.group", "priority", "project", "labels", null],
+ order_by: ["sort_order", "-created_at", "-updated_at", "start_date", "priority"],
+ type: [null, "active", "backlog"],
+ },
+ extra_options: {
+ access: true,
+ values: ["show_empty_groups"],
+ },
+ },
+ },
+ draft_issues: {
+ list: {
+ filters: ["priority", "state_group", "labels", "start_date", "target_date"],
+ display_properties: true,
+ display_filters: {
+ group_by: ["state_detail.group", "priority", "project", "labels", null],
+ order_by: ["sort_order", "-created_at", "-updated_at", "start_date", "priority"],
+ type: [null, "active", "backlog"],
+ },
+ extra_options: {
+ access: true,
+ values: ["show_empty_groups"],
+ },
+ },
+ kanban: {
+ filters: ["priority", "state_group", "labels", "start_date", "target_date"],
+ display_properties: true,
+ display_filters: {
+ group_by: ["state_detail.group", "priority", "project", "labels", null],
+ order_by: ["sort_order", "-created_at", "-updated_at", "start_date", "priority"],
+ type: [null, "active", "backlog"],
+ },
+ extra_options: {
+ access: true,
+ values: ["show_empty_groups"],
+ },
+ },
+ },
my_issues: {
spreadsheet: {
filters: ["priority", "state_group", "labels", "assignees", "created_by", "project", "start_date", "target_date"],
diff --git a/web/helpers/issue.helper.ts b/web/helpers/issue.helper.ts
index d0066c0e6..919699d69 100644
--- a/web/helpers/issue.helper.ts
+++ b/web/helpers/issue.helper.ts
@@ -83,7 +83,7 @@ export const handleIssuesMutation: THandleIssuesMutation = (
export const handleIssueQueryParamsByLayout = (
layout: TIssueLayouts | undefined,
- viewType: "my_issues" | "issues"
+ viewType: "my_issues" | "issues" | "profile_issues" | "archived_issues" | "draft_issues"
): TIssueParams[] | null => {
const queryParams: TIssueParams[] = [];
diff --git a/web/pages/[workspaceSlug]/profile/[userId]/assigned.tsx b/web/pages/[workspaceSlug]/profile/[userId]/assigned.tsx
index a60116503..267679a89 100644
--- a/web/pages/[workspaceSlug]/profile/[userId]/assigned.tsx
+++ b/web/pages/[workspaceSlug]/profile/[userId]/assigned.tsx
@@ -1,19 +1,66 @@
import React from "react";
-
+import type { NextPage } from "next";
+import { useRouter } from "next/router";
+import useSWR from "swr";
+import { observer } from "mobx-react-lite";
// contexts
import { ProfileIssuesContextProvider } from "contexts/profile-issues-context";
+// layouts
import { ProfileAuthWrapper } from "layouts/profile-layout";
// components
-import { ProfileIssuesView } from "components/profile";
-// types
-import type { NextPage } from "next";
+import { ProfileIssuesListLayout } from "components/issues/issue-layouts/list/profile-issues-root";
+import { ProfileIssuesKanBanLayout } from "components/issues/issue-layouts/kanban/profile-issues-root";
+// hooks
+import { useMobxStore } from "lib/mobx/store-provider";
+import { RootStore } from "store/root";
-const ProfileAssignedIssues: NextPage = () => (
-
-
-
-
-
-);
+// types
+
+const ProfileAssignedIssues: NextPage = observer(() => {
+ const {
+ workspace: workspaceStore,
+ project: projectStore,
+ profileIssueFilters: profileIssueFiltersStore,
+ profileIssues: profileIssuesStore,
+ }: RootStore = useMobxStore();
+
+ const router = useRouter();
+ const { workspaceSlug, userId } = router.query as {
+ workspaceSlug: string;
+ userId: string;
+ };
+
+ useSWR(`PROFILE_ISSUES_${workspaceSlug}_${userId}`, async () => {
+ if (workspaceSlug && userId) {
+ // workspace labels
+ workspaceStore.setWorkspaceSlug(workspaceSlug);
+ await workspaceStore.fetchWorkspaceLabels(workspaceSlug);
+ await projectStore.fetchProjects(workspaceSlug);
+
+ //profile issues
+ await profileIssuesStore.fetchIssues(workspaceSlug, userId, "assigned");
+ }
+ });
+
+ const activeLayout = profileIssueFiltersStore.userDisplayFilters.layout;
+
+ return (
+
+
+ {profileIssuesStore.loader ? (
+ Loading...
+ ) : (
+
+ {activeLayout === "list" ? (
+
+ ) : activeLayout === "kanban" ? (
+
+ ) : null}
+
+ )}
+
+
+ );
+});
export default ProfileAssignedIssues;
diff --git a/web/store/archived-issues/index.ts b/web/store/archived-issues/index.ts
new file mode 100644
index 000000000..abfd52768
--- /dev/null
+++ b/web/store/archived-issues/index.ts
@@ -0,0 +1,2 @@
+export * from "./issue.store";
+export * from "./issue_filters.store";
diff --git a/web/store/archived-issues/issue.store.ts b/web/store/archived-issues/issue.store.ts
new file mode 100644
index 000000000..141805e23
--- /dev/null
+++ b/web/store/archived-issues/issue.store.ts
@@ -0,0 +1,187 @@
+import { observable, action, computed, makeObservable, runInAction } from "mobx";
+// store
+import { RootStore } from "../root";
+// types
+import { IIssue } from "types";
+// services
+import { IssueService } from "services/issue";
+import { sortArrayByDate, sortArrayByPriority } from "constants/kanban-helpers";
+
+export type IIssueType = "grouped" | "groupWithSubGroups" | "ungrouped";
+export type IIssueGroupedStructure = { [group_id: string]: IIssue[] };
+export type IIssueGroupWithSubGroupsStructure = {
+ [group_id: string]: {
+ [sub_group_id: string]: IIssue[];
+ };
+};
+export type IIssueUnGroupedStructure = IIssue[];
+
+export interface IArchivedIssueStore {
+ loader: boolean;
+ error: any | null;
+ // issues
+ issues: {
+ [project_id: string]: {
+ grouped: IIssueGroupedStructure;
+ groupWithSubGroups: IIssueGroupWithSubGroupsStructure;
+ ungrouped: IIssueUnGroupedStructure;
+ };
+ };
+ // computed
+ getIssueType: IIssueType | null;
+ getIssues: IIssueGroupedStructure | IIssueGroupWithSubGroupsStructure | IIssueUnGroupedStructure | null;
+ // action
+ fetchIssues: (workspaceSlug: string, projectId: string) => Promise
;
+ updateIssueStructure: (group_id: string | null, sub_group_id: string | null, issue: IIssue) => void;
+}
+
+export class ArchivedIssueStore implements IArchivedIssueStore {
+ loader: boolean = false;
+ error: any | null = null;
+ issues: {
+ [project_id: string]: {
+ grouped: {
+ [group_id: string]: IIssue[];
+ };
+ groupWithSubGroups: {
+ [group_id: string]: {
+ [sub_group_id: string]: IIssue[];
+ };
+ };
+ ungrouped: IIssue[];
+ };
+ } = {};
+ // service
+ issueService;
+ rootStore;
+
+ constructor(_rootStore: RootStore) {
+ makeObservable(this, {
+ // observable
+ loader: observable.ref,
+ error: observable.ref,
+ issues: observable.ref,
+ // computed
+ getIssueType: computed,
+ getIssues: computed,
+ // actions
+ fetchIssues: action,
+ updateIssueStructure: action,
+ });
+ this.rootStore = _rootStore;
+ this.issueService = new IssueService();
+ }
+
+ get getIssueType() {
+ const groupedLayouts = ["kanban", "list", "calendar"];
+ const ungroupedLayouts = ["spreadsheet", "gantt_chart"];
+
+ const issueLayout = this.rootStore?.issueFilter?.userDisplayFilters?.layout || null;
+ const issueSubGroup = this.rootStore?.issueFilter?.userDisplayFilters?.sub_group_by || null;
+ if (!issueLayout) return null;
+
+ const _issueState = groupedLayouts.includes(issueLayout)
+ ? issueSubGroup
+ ? "groupWithSubGroups"
+ : "grouped"
+ : ungroupedLayouts.includes(issueLayout)
+ ? "ungrouped"
+ : null;
+
+ return _issueState || null;
+ }
+
+ get getIssues() {
+ const projectId: string | null = this.rootStore?.project?.projectId;
+ const issueType = this.getIssueType;
+ if (!projectId || !issueType) return null;
+
+ return this.issues?.[projectId]?.[issueType] || null;
+ }
+
+ updateIssueStructure = async (group_id: string | null, sub_group_id: string | null, issue: IIssue) => {
+ const projectId: string | null = issue?.project;
+ const issueType = this.getIssueType;
+ if (!projectId || !issueType) return null;
+
+ let issues: IIssueGroupedStructure | IIssueGroupWithSubGroupsStructure | IIssueUnGroupedStructure | null =
+ this.getIssues;
+ if (!issues) return null;
+
+ if (issueType === "grouped" && group_id) {
+ issues = issues as IIssueGroupedStructure;
+ issues = {
+ ...issues,
+ [group_id]: issues[group_id].map((i: IIssue) => (i?.id === issue?.id ? { ...i, ...issue } : i)),
+ };
+ }
+ if (issueType === "groupWithSubGroups" && group_id && sub_group_id) {
+ issues = issues as IIssueGroupWithSubGroupsStructure;
+ issues = {
+ ...issues,
+ [sub_group_id]: {
+ ...issues[sub_group_id],
+ [group_id]: issues[sub_group_id][group_id].map((i: IIssue) => (i?.id === issue?.id ? { ...i, ...issue } : i)),
+ },
+ };
+ }
+ if (issueType === "ungrouped") {
+ issues = issues as IIssueUnGroupedStructure;
+ issues = issues.map((i: IIssue) => (i?.id === issue?.id ? { ...i, ...issue } : i));
+ }
+
+ const orderBy = this.rootStore?.issueFilter?.userDisplayFilters?.order_by || "";
+ if (orderBy === "-created_at") {
+ issues = sortArrayByDate(issues as any, "created_at");
+ }
+ if (orderBy === "-updated_at") {
+ issues = sortArrayByDate(issues as any, "updated_at");
+ }
+ if (orderBy === "start_date") {
+ issues = sortArrayByDate(issues as any, "updated_at");
+ }
+ if (orderBy === "priority") {
+ issues = sortArrayByPriority(issues as any, "priority");
+ }
+
+ runInAction(() => {
+ this.issues = { ...this.issues, [projectId]: { ...this.issues[projectId], [issueType]: issues } };
+ });
+ };
+
+ fetchIssues = async (workspaceSlug: string, projectId: string) => {
+ try {
+ this.loader = true;
+ this.error = null;
+
+ this.rootStore.workspace.setWorkspaceSlug(workspaceSlug);
+ this.rootStore.project.setProjectId(projectId);
+
+ const params = this.rootStore?.issueFilter?.appliedFilters;
+ const issueResponse = await this.issueService.getIssuesWithParams(workspaceSlug, projectId, params);
+
+ const issueType = this.getIssueType;
+ if (issueType != null) {
+ const _issues = {
+ ...this.issues,
+ [projectId]: {
+ ...this.issues[projectId],
+ [issueType]: issueResponse,
+ },
+ };
+ runInAction(() => {
+ this.issues = _issues;
+ this.loader = false;
+ this.error = null;
+ });
+ }
+
+ return issueResponse;
+ } catch (error) {
+ console.error("Error: Fetching error in issues", error);
+ this.loader = false;
+ this.error = error;
+ return error;
+ }
+ };
+}
diff --git a/web/store/archived-issues/issue_filters.store.ts b/web/store/archived-issues/issue_filters.store.ts
new file mode 100644
index 000000000..04a0da9bd
--- /dev/null
+++ b/web/store/archived-issues/issue_filters.store.ts
@@ -0,0 +1,109 @@
+import { observable, computed, makeObservable } from "mobx";
+// helpers
+import { handleIssueQueryParamsByLayout } from "helpers/issue.helper";
+// types
+import { RootStore } from "../root";
+import { IIssueDisplayFilterOptions, IIssueDisplayProperties, IIssueFilterOptions, TIssueParams } from "types";
+
+export interface IArchivedIssueFilterStore {
+ userDisplayProperties: IIssueDisplayProperties;
+ userDisplayFilters: IIssueDisplayFilterOptions;
+ userFilters: IIssueFilterOptions;
+
+ // computed
+ appliedFilters: TIssueParams[] | null;
+}
+
+export class ArchivedIssueFilterStore implements IArchivedIssueFilterStore {
+ // observables
+ userFilters: IIssueFilterOptions = {
+ priority: null,
+ state_group: null,
+ labels: null,
+ start_date: null,
+ target_date: null,
+ assignees: null,
+ created_by: null,
+ subscriber: null,
+ };
+ userDisplayFilters: IIssueDisplayFilterOptions = {
+ group_by: null,
+ order_by: "sort_order",
+ show_empty_groups: true,
+ type: null,
+ layout: "list",
+ };
+ userDisplayProperties: any = {
+ assignee: true,
+ start_date: true,
+ due_date: true,
+ labels: true,
+ key: true,
+ priority: true,
+ state: true,
+ sub_issue_count: true,
+ link: true,
+ attachment_count: true,
+ estimate: true,
+ created_on: true,
+ updated_on: true,
+ };
+
+ // root store
+ rootStore;
+
+ constructor(_rootStore: RootStore) {
+ makeObservable(this, {
+ // observables
+ userFilters: observable.ref,
+ userDisplayFilters: observable.ref,
+ userDisplayProperties: observable.ref,
+
+ // computed
+ appliedFilters: computed,
+ });
+
+ this.rootStore = _rootStore;
+ }
+
+ 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;
+ };
+
+ get appliedFilters(): TIssueParams[] | null {
+ if (!this.userFilters || !this.userDisplayFilters) return null;
+
+ let filteredRouteParams: any = {
+ priority: this.userFilters?.priority || undefined,
+ state_group: this.userFilters?.state_group || undefined,
+ state: this.userFilters?.state || undefined,
+ assignees: this.userFilters?.assignees || undefined,
+ created_by: this.userFilters?.created_by || undefined,
+ labels: this.userFilters?.labels || undefined,
+ start_date: this.userFilters?.start_date || undefined,
+ target_date: this.userFilters?.target_date || undefined,
+ group_by: this.userDisplayFilters?.group_by || "state",
+ order_by: this.userDisplayFilters?.order_by || "-created_at",
+ sub_group_by: this.userDisplayFilters?.sub_group_by || undefined,
+ type: this.userDisplayFilters?.type || undefined,
+ sub_issue: this.userDisplayFilters?.sub_issue || true,
+ show_empty_groups: this.userDisplayFilters?.show_empty_groups || true,
+ start_target_date: this.userDisplayFilters?.start_target_date || true,
+ };
+
+ const filteredParams = handleIssueQueryParamsByLayout(this.userDisplayFilters.layout, "issues");
+ if (filteredParams) filteredRouteParams = this.computedFilter(filteredRouteParams, filteredParams);
+
+ if (this.userDisplayFilters.layout === "calendar") filteredRouteParams.group_by = "target_date";
+ if (this.userDisplayFilters.layout === "gantt_chart") filteredRouteParams.start_target_date = true;
+
+ return filteredRouteParams;
+ }
+}
diff --git a/web/store/draft-issues/index.ts b/web/store/draft-issues/index.ts
new file mode 100644
index 000000000..abfd52768
--- /dev/null
+++ b/web/store/draft-issues/index.ts
@@ -0,0 +1,2 @@
+export * from "./issue.store";
+export * from "./issue_filters.store";
diff --git a/web/store/draft-issues/issue.store.ts b/web/store/draft-issues/issue.store.ts
new file mode 100644
index 000000000..c8afece07
--- /dev/null
+++ b/web/store/draft-issues/issue.store.ts
@@ -0,0 +1,187 @@
+import { observable, action, computed, makeObservable, runInAction } from "mobx";
+// store
+import { RootStore } from "../root";
+// types
+import { IIssue } from "types";
+// services
+import { IssueService } from "services/issue";
+import { sortArrayByDate, sortArrayByPriority } from "constants/kanban-helpers";
+
+export type IIssueType = "grouped" | "groupWithSubGroups" | "ungrouped";
+export type IIssueGroupedStructure = { [group_id: string]: IIssue[] };
+export type IIssueGroupWithSubGroupsStructure = {
+ [group_id: string]: {
+ [sub_group_id: string]: IIssue[];
+ };
+};
+export type IIssueUnGroupedStructure = IIssue[];
+
+export interface IDraftIssueStore {
+ loader: boolean;
+ error: any | null;
+ // issues
+ issues: {
+ [project_id: string]: {
+ grouped: IIssueGroupedStructure;
+ groupWithSubGroups: IIssueGroupWithSubGroupsStructure;
+ ungrouped: IIssueUnGroupedStructure;
+ };
+ };
+ // computed
+ getIssueType: IIssueType | null;
+ getIssues: IIssueGroupedStructure | IIssueGroupWithSubGroupsStructure | IIssueUnGroupedStructure | null;
+ // action
+ fetchIssues: (workspaceSlug: string, projectId: string) => Promise;
+ updateIssueStructure: (group_id: string | null, sub_group_id: string | null, issue: IIssue) => void;
+}
+
+export class DraftIssueStore implements IDraftIssueStore {
+ loader: boolean = false;
+ error: any | null = null;
+ issues: {
+ [project_id: string]: {
+ grouped: {
+ [group_id: string]: IIssue[];
+ };
+ groupWithSubGroups: {
+ [group_id: string]: {
+ [sub_group_id: string]: IIssue[];
+ };
+ };
+ ungrouped: IIssue[];
+ };
+ } = {};
+ // service
+ issueService;
+ rootStore;
+
+ constructor(_rootStore: RootStore) {
+ makeObservable(this, {
+ // observable
+ loader: observable.ref,
+ error: observable.ref,
+ issues: observable.ref,
+ // computed
+ getIssueType: computed,
+ getIssues: computed,
+ // actions
+ fetchIssues: action,
+ updateIssueStructure: action,
+ });
+ this.rootStore = _rootStore;
+ this.issueService = new IssueService();
+ }
+
+ get getIssueType() {
+ const groupedLayouts = ["kanban", "list", "calendar"];
+ const ungroupedLayouts = ["spreadsheet", "gantt_chart"];
+
+ const issueLayout = this.rootStore?.issueFilter?.userDisplayFilters?.layout || null;
+ const issueSubGroup = this.rootStore?.issueFilter?.userDisplayFilters?.sub_group_by || null;
+ if (!issueLayout) return null;
+
+ const _issueState = groupedLayouts.includes(issueLayout)
+ ? issueSubGroup
+ ? "groupWithSubGroups"
+ : "grouped"
+ : ungroupedLayouts.includes(issueLayout)
+ ? "ungrouped"
+ : null;
+
+ return _issueState || null;
+ }
+
+ get getIssues() {
+ const projectId: string | null = this.rootStore?.project?.projectId;
+ const issueType = this.getIssueType;
+ if (!projectId || !issueType) return null;
+
+ return this.issues?.[projectId]?.[issueType] || null;
+ }
+
+ updateIssueStructure = async (group_id: string | null, sub_group_id: string | null, issue: IIssue) => {
+ const projectId: string | null = issue?.project;
+ const issueType = this.getIssueType;
+ if (!projectId || !issueType) return null;
+
+ let issues: IIssueGroupedStructure | IIssueGroupWithSubGroupsStructure | IIssueUnGroupedStructure | null =
+ this.getIssues;
+ if (!issues) return null;
+
+ if (issueType === "grouped" && group_id) {
+ issues = issues as IIssueGroupedStructure;
+ issues = {
+ ...issues,
+ [group_id]: issues[group_id].map((i: IIssue) => (i?.id === issue?.id ? { ...i, ...issue } : i)),
+ };
+ }
+ if (issueType === "groupWithSubGroups" && group_id && sub_group_id) {
+ issues = issues as IIssueGroupWithSubGroupsStructure;
+ issues = {
+ ...issues,
+ [sub_group_id]: {
+ ...issues[sub_group_id],
+ [group_id]: issues[sub_group_id][group_id].map((i: IIssue) => (i?.id === issue?.id ? { ...i, ...issue } : i)),
+ },
+ };
+ }
+ if (issueType === "ungrouped") {
+ issues = issues as IIssueUnGroupedStructure;
+ issues = issues.map((i: IIssue) => (i?.id === issue?.id ? { ...i, ...issue } : i));
+ }
+
+ const orderBy = this.rootStore?.issueFilter?.userDisplayFilters?.order_by || "";
+ if (orderBy === "-created_at") {
+ issues = sortArrayByDate(issues as any, "created_at");
+ }
+ if (orderBy === "-updated_at") {
+ issues = sortArrayByDate(issues as any, "updated_at");
+ }
+ if (orderBy === "start_date") {
+ issues = sortArrayByDate(issues as any, "updated_at");
+ }
+ if (orderBy === "priority") {
+ issues = sortArrayByPriority(issues as any, "priority");
+ }
+
+ runInAction(() => {
+ this.issues = { ...this.issues, [projectId]: { ...this.issues[projectId], [issueType]: issues } };
+ });
+ };
+
+ fetchIssues = async (workspaceSlug: string, projectId: string) => {
+ try {
+ this.loader = true;
+ this.error = null;
+
+ this.rootStore.workspace.setWorkspaceSlug(workspaceSlug);
+ this.rootStore.project.setProjectId(projectId);
+
+ const params = this.rootStore?.issueFilter?.appliedFilters;
+ const issueResponse = await this.issueService.getIssuesWithParams(workspaceSlug, projectId, params);
+
+ const issueType = this.getIssueType;
+ if (issueType != null) {
+ const _issues = {
+ ...this.issues,
+ [projectId]: {
+ ...this.issues[projectId],
+ [issueType]: issueResponse,
+ },
+ };
+ runInAction(() => {
+ this.issues = _issues;
+ this.loader = false;
+ this.error = null;
+ });
+ }
+
+ return issueResponse;
+ } catch (error) {
+ console.error("Error: Fetching error in issues", error);
+ this.loader = false;
+ this.error = error;
+ return error;
+ }
+ };
+}
diff --git a/web/store/draft-issues/issue_filters.store.ts b/web/store/draft-issues/issue_filters.store.ts
new file mode 100644
index 000000000..2560c011b
--- /dev/null
+++ b/web/store/draft-issues/issue_filters.store.ts
@@ -0,0 +1,109 @@
+import { observable, computed, makeObservable } from "mobx";
+// helpers
+import { handleIssueQueryParamsByLayout } from "helpers/issue.helper";
+// types
+import { RootStore } from "../root";
+import { IIssueDisplayFilterOptions, IIssueDisplayProperties, IIssueFilterOptions, TIssueParams } from "types";
+
+export interface IDraftIssueFilterStore {
+ userDisplayProperties: IIssueDisplayProperties;
+ userDisplayFilters: IIssueDisplayFilterOptions;
+ userFilters: IIssueFilterOptions;
+
+ // computed
+ appliedFilters: TIssueParams[] | null;
+}
+
+export class DraftIssueFilterStore implements IDraftIssueFilterStore {
+ // observables
+ userFilters: IIssueFilterOptions = {
+ priority: null,
+ state_group: null,
+ labels: null,
+ start_date: null,
+ target_date: null,
+ assignees: null,
+ created_by: null,
+ subscriber: null,
+ };
+ userDisplayFilters: IIssueDisplayFilterOptions = {
+ group_by: null,
+ order_by: "sort_order",
+ show_empty_groups: true,
+ type: null,
+ layout: "list",
+ };
+ userDisplayProperties: any = {
+ assignee: true,
+ start_date: true,
+ due_date: true,
+ labels: true,
+ key: true,
+ priority: true,
+ state: true,
+ sub_issue_count: true,
+ link: true,
+ attachment_count: true,
+ estimate: true,
+ created_on: true,
+ updated_on: true,
+ };
+
+ // root store
+ rootStore;
+
+ constructor(_rootStore: RootStore) {
+ makeObservable(this, {
+ // observables
+ userFilters: observable.ref,
+ userDisplayFilters: observable.ref,
+ userDisplayProperties: observable.ref,
+
+ // computed
+ appliedFilters: computed,
+ });
+
+ this.rootStore = _rootStore;
+ }
+
+ 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;
+ };
+
+ get appliedFilters(): TIssueParams[] | null {
+ if (!this.userFilters || !this.userDisplayFilters) return null;
+
+ let filteredRouteParams: any = {
+ priority: this.userFilters?.priority || undefined,
+ state_group: this.userFilters?.state_group || undefined,
+ state: this.userFilters?.state || undefined,
+ assignees: this.userFilters?.assignees || undefined,
+ created_by: this.userFilters?.created_by || undefined,
+ labels: this.userFilters?.labels || undefined,
+ start_date: this.userFilters?.start_date || undefined,
+ target_date: this.userFilters?.target_date || undefined,
+ group_by: this.userDisplayFilters?.group_by || "state",
+ order_by: this.userDisplayFilters?.order_by || "-created_at",
+ sub_group_by: this.userDisplayFilters?.sub_group_by || undefined,
+ type: this.userDisplayFilters?.type || undefined,
+ sub_issue: this.userDisplayFilters?.sub_issue || true,
+ show_empty_groups: this.userDisplayFilters?.show_empty_groups || true,
+ start_target_date: this.userDisplayFilters?.start_target_date || true,
+ };
+
+ const filteredParams = handleIssueQueryParamsByLayout(this.userDisplayFilters.layout, "issues");
+ if (filteredParams) filteredRouteParams = this.computedFilter(filteredRouteParams, filteredParams);
+
+ if (this.userDisplayFilters.layout === "calendar") filteredRouteParams.group_by = "target_date";
+ if (this.userDisplayFilters.layout === "gantt_chart") filteredRouteParams.start_target_date = true;
+
+ return filteredRouteParams;
+ }
+}
diff --git a/web/store/profile-issues/index.ts b/web/store/profile-issues/index.ts
new file mode 100644
index 000000000..abfd52768
--- /dev/null
+++ b/web/store/profile-issues/index.ts
@@ -0,0 +1,2 @@
+export * from "./issue.store";
+export * from "./issue_filters.store";
diff --git a/web/store/profile-issues/issue.store.ts b/web/store/profile-issues/issue.store.ts
new file mode 100644
index 000000000..75898c1b4
--- /dev/null
+++ b/web/store/profile-issues/issue.store.ts
@@ -0,0 +1,231 @@
+import { observable, action, computed, makeObservable, runInAction } from "mobx";
+// store
+import { RootStore } from "../root";
+// types
+import { IIssue } from "types";
+// services
+import { UserService } from "services/user.service";
+import { sortArrayByDate, sortArrayByPriority } from "constants/kanban-helpers";
+
+export type IIssueType = "grouped" | "groupWithSubGroups" | "ungrouped";
+export type IIssueGroupedStructure = { [group_id: string]: IIssue[] };
+export type IIssueGroupWithSubGroupsStructure = {
+ [group_id: string]: {
+ [sub_group_id: string]: IIssue[];
+ };
+};
+export type IIssueUnGroupedStructure = IIssue[];
+
+export interface IProfileIssueStore {
+ loader: boolean;
+ error: any | null;
+ userId: string | null;
+ currentProfileTab: "assigned" | "created" | "subscribed" | null;
+ issues: {
+ [workspace_slug: string]: {
+ [user_id: string]: {
+ grouped: IIssueGroupedStructure;
+ groupWithSubGroups: IIssueGroupWithSubGroupsStructure;
+ ungrouped: IIssueUnGroupedStructure;
+ };
+ };
+ };
+ // computed
+ getIssueType: IIssueType | null;
+ getIssues: IIssueGroupedStructure | IIssueGroupWithSubGroupsStructure | IIssueUnGroupedStructure | null;
+ // action
+ fetchIssues: (workspaceSlug: string, userId: string, type: "assigned" | "created" | "subscribed") => Promise;
+ updateIssueStructure: (group_id: string | null, sub_group_id: string | null, issue: IIssue) => void;
+}
+
+export class ProfileIssueStore implements IProfileIssueStore {
+ loader: boolean = true;
+ error: any | null = null;
+ userId: string | null = null;
+ currentProfileTab: "assigned" | "created" | "subscribed" | null = null;
+ issues: {
+ [workspace_slug: string]: {
+ [user_id: string]: {
+ grouped: {
+ [group_id: string]: IIssue[];
+ };
+ groupWithSubGroups: {
+ [group_id: string]: {
+ [sub_group_id: string]: IIssue[];
+ };
+ };
+ ungrouped: IIssue[];
+ };
+ };
+ } = {};
+ // service
+ userService;
+ rootStore;
+
+ constructor(_rootStore: RootStore) {
+ makeObservable(this, {
+ // observable
+ loader: observable.ref,
+ error: observable.ref,
+ currentProfileTab: observable.ref,
+ userId: observable.ref,
+ issues: observable.ref,
+ // computed
+ getIssueType: computed,
+ getIssues: computed,
+ // actions
+ fetchIssues: action,
+ updateIssueStructure: action,
+ });
+ this.rootStore = _rootStore;
+ this.userService = new UserService();
+ }
+
+ get getIssueType() {
+ const groupedLayouts = ["kanban", "list", "calendar"];
+ const ungroupedLayouts = ["spreadsheet", "gantt_chart"];
+
+ const issueLayout = this.rootStore?.profileIssueFilters?.userDisplayFilters?.layout || null;
+ const issueGroup = this.rootStore?.profileIssueFilters?.userDisplayFilters?.group_by || null;
+ const issueSubGroup = this.rootStore?.profileIssueFilters?.userDisplayFilters?.sub_group_by || null;
+ if (!issueLayout) return null;
+
+ const _issueState = groupedLayouts.includes(issueLayout)
+ ? issueGroup
+ ? issueSubGroup
+ ? "groupWithSubGroups"
+ : "grouped"
+ : "ungrouped"
+ : ungroupedLayouts.includes(issueLayout)
+ ? "ungrouped"
+ : null;
+
+ return _issueState || null;
+ }
+
+ get getIssues() {
+ const workspaceSlug: string | null = this.rootStore?.workspace?.workspaceSlug;
+ const userId: string | null = this.userId;
+ const issueType = this.getIssueType;
+ if (!workspaceSlug || !userId || !issueType) return null;
+
+ return this.issues?.[workspaceSlug]?.[userId]?.[issueType] || null;
+ }
+
+ updateIssueStructure = async (group_id: string | null, sub_group_id: string | null, issue: IIssue) => {
+ const workspaceSlug: string | null = this.rootStore?.workspace?.workspaceSlug;
+ const userId: string | null = this.userId;
+
+ const issueType = this.getIssueType;
+ if (!workspaceSlug || !userId || !issueType) return null;
+
+ let issues: IIssueGroupedStructure | IIssueGroupWithSubGroupsStructure | IIssueUnGroupedStructure | null =
+ this.getIssues;
+ if (!issues) return null;
+
+ if (issueType === "grouped" && group_id) {
+ issues = issues as IIssueGroupedStructure;
+ issues = {
+ ...issues,
+ [group_id]: issues[group_id].map((i: IIssue) => (i?.id === issue?.id ? { ...i, ...issue } : i)),
+ };
+ }
+
+ if (issueType === "groupWithSubGroups" && group_id && sub_group_id) {
+ issues = issues as IIssueGroupWithSubGroupsStructure;
+ issues = {
+ ...issues,
+ [sub_group_id]: {
+ ...issues[sub_group_id],
+ [group_id]: issues[sub_group_id][group_id].map((i: IIssue) => (i?.id === issue?.id ? { ...i, ...issue } : i)),
+ },
+ };
+ }
+ if (issueType === "ungrouped") {
+ issues = issues as IIssueUnGroupedStructure;
+ issues = issues.map((i: IIssue) => (i?.id === issue?.id ? { ...i, ...issue } : i));
+ }
+
+ const orderBy = this.rootStore?.profileIssueFilters?.userDisplayFilters?.order_by || "";
+ if (orderBy === "-created_at") {
+ issues = sortArrayByDate(issues as any, "created_at");
+ }
+ if (orderBy === "-updated_at") {
+ issues = sortArrayByDate(issues as any, "updated_at");
+ }
+ if (orderBy === "start_date") {
+ issues = sortArrayByDate(issues as any, "updated_at");
+ }
+ if (orderBy === "priority") {
+ issues = sortArrayByPriority(issues as any, "priority");
+ }
+
+ runInAction(() => {
+ this.issues = {
+ ...this.issues,
+ [workspaceSlug]: {
+ ...this.issues?.[workspaceSlug],
+ [userId]: {
+ ...this.issues?.[workspaceSlug]?.[userId],
+ [issueType]: issues,
+ },
+ },
+ };
+ });
+ };
+
+ fetchIssues = async (
+ workspaceSlug: string,
+ userId: string,
+ type: "assigned" | "created" | "subscribed" = "assigned"
+ ) => {
+ try {
+ this.loader = true;
+ this.error = null;
+
+ this.currentProfileTab = type;
+ this.userId = userId;
+
+ const issueType = this.getIssueType;
+
+ let params: any = this.rootStore?.profileIssueFilters?.appliedFilters;
+ params = {
+ ...params,
+ assignees: undefined,
+ created_by: undefined,
+ subscriber: undefined,
+ };
+ if (type === "assigned") params = params ? { ...params, assignees: userId } : { assignees: userId };
+ else if (type === "created") params = params ? { ...params, created_by: userId } : { created_by: userId };
+ else if (type === "subscribed") params = params ? { ...params, subscriber: userId } : { subscriber: userId };
+
+ const issueResponse = await this.userService.getUserProfileIssues(workspaceSlug, userId, params);
+
+ if (issueType != null) {
+ const _issues = {
+ ...this.issues,
+ [workspaceSlug]: {
+ ...this.issues?.[workspaceSlug],
+ [userId]: {
+ ...this.issues?.[workspaceSlug]?.[userId],
+ [issueType]: issueResponse,
+ },
+ },
+ };
+
+ runInAction(() => {
+ this.issues = _issues;
+ this.loader = false;
+ this.error = null;
+ });
+ }
+
+ return issueResponse;
+ } catch (error) {
+ console.error("Error: Fetching error in issues", error);
+ this.loader = false;
+ this.error = error;
+ return error;
+ }
+ };
+}
diff --git a/web/store/profile-issues/issue_filters.store.ts b/web/store/profile-issues/issue_filters.store.ts
new file mode 100644
index 000000000..c1d352564
--- /dev/null
+++ b/web/store/profile-issues/issue_filters.store.ts
@@ -0,0 +1,137 @@
+import { observable, computed, makeObservable, action, autorun, runInAction } from "mobx";
+// helpers
+import { handleIssueQueryParamsByLayout } from "helpers/issue.helper";
+// types
+import { RootStore } from "../root";
+import { IIssueDisplayFilterOptions, IIssueDisplayProperties, IIssueFilterOptions, TIssueParams } from "types";
+
+export interface IProfileIssueFilterStore {
+ userDisplayProperties: IIssueDisplayProperties;
+ userDisplayFilters: IIssueDisplayFilterOptions;
+ userFilters: IIssueFilterOptions;
+ // computed
+ appliedFilters: TIssueParams[] | null;
+ // action
+ handleIssueFilters: (type: "userFilters" | "userDisplayFilters" | "userDisplayProperties", params: any) => void;
+}
+
+export class ProfileIssueFilterStore implements IProfileIssueFilterStore {
+ // observables
+ userFilters: IIssueFilterOptions = {
+ priority: null,
+ state_group: null,
+ labels: null,
+ start_date: null,
+ target_date: null,
+ };
+ userDisplayFilters: IIssueDisplayFilterOptions = {
+ group_by: null,
+ order_by: "sort_order",
+ show_empty_groups: true,
+ type: null,
+ layout: "list",
+ };
+ userDisplayProperties: any = {
+ assignee: true,
+ start_date: true,
+ due_date: true,
+ labels: true,
+ key: true,
+ priority: true,
+ state: true,
+ sub_issue_count: true,
+ link: true,
+ attachment_count: true,
+ estimate: true,
+ created_on: true,
+ updated_on: true,
+ };
+ // root store
+ rootStore;
+
+ constructor(_rootStore: RootStore) {
+ makeObservable(this, {
+ // observables
+ userFilters: observable.ref,
+ userDisplayFilters: observable.ref,
+ userDisplayProperties: observable.ref,
+ // computed
+ appliedFilters: computed,
+ // actions
+ handleIssueFilters: action,
+ });
+
+ this.rootStore = _rootStore;
+
+ autorun(() => {
+ if (this.userFilters || this.userDisplayFilters || this.userDisplayProperties) {
+ const workspaceSlug = this.rootStore.workspace.workspaceSlug;
+ const userId = this.rootStore.profileIssues?.userId;
+ if (workspaceSlug && userId && this.rootStore.profileIssues.currentProfileTab) {
+ console.log("autorun triggered");
+ this.rootStore.profileIssues.fetchIssues(
+ workspaceSlug,
+ userId,
+ this.rootStore.profileIssues.currentProfileTab
+ );
+ }
+ }
+ });
+ }
+
+ 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;
+ };
+
+ get appliedFilters(): TIssueParams[] | null {
+ if (!this.userFilters || !this.userDisplayFilters) return null;
+
+ let filteredRouteParams: any = {
+ priority: this.userFilters?.priority || undefined,
+ state_group: this.userFilters?.state_group || undefined,
+ labels: this.userFilters?.labels || undefined,
+ start_date: this.userFilters?.start_date || undefined,
+ target_date: this.userFilters?.target_date || undefined,
+ group_by: this.userDisplayFilters?.group_by || undefined,
+ order_by: this.userDisplayFilters?.order_by || "-created_at",
+ show_empty_groups: this.userDisplayFilters?.show_empty_groups || true,
+ type: this.userDisplayFilters?.type || undefined,
+ assignees: undefined,
+ created_by: undefined,
+ subscriber: undefined,
+ };
+
+ const filteredParams = handleIssueQueryParamsByLayout(this.userDisplayFilters.layout, "profile_issues");
+ if (filteredParams) filteredRouteParams = this.computedFilter(filteredRouteParams, filteredParams);
+
+ return filteredRouteParams;
+ }
+
+ handleIssueFilters = (type: "userFilters" | "userDisplayFilters" | "userDisplayProperties", params: any) => {
+ if (type === "userFilters") {
+ const updatedFilters = { ...this.userFilters, ...params };
+ runInAction(() => {
+ this.userFilters = updatedFilters;
+ });
+ }
+ if (type === "userDisplayFilters") {
+ const updatedFilters = { ...this.userDisplayFilters, ...params };
+ runInAction(() => {
+ this.userDisplayFilters = updatedFilters;
+ });
+ }
+ if (type === "userDisplayProperties") {
+ const updatedFilters = { ...this.userDisplayProperties, ...params };
+ runInAction(() => {
+ this.userDisplayProperties = updatedFilters;
+ });
+ }
+ };
+}
diff --git a/web/store/project/project.store.ts b/web/store/project/project.store.ts
index 48535993a..7761ec5aa 100644
--- a/web/store/project/project.store.ts
+++ b/web/store/project/project.store.ts
@@ -31,6 +31,7 @@ export interface IProjectStore {
// computed
searchedProjects: IProject[];
+ workspaceProjects: IProject[];
projectStatesByGroups: IStateResponse | null;
projectStates: IState[] | null;
projectLabels: IIssueLabels[] | null;
@@ -119,6 +120,7 @@ export class ProjectStore implements IProjectStore {
// computed
searchedProjects: computed,
+ workspaceProjects: computed,
projectStatesByGroups: computed,
projectStates: computed,
projectLabels: computed,
@@ -176,6 +178,11 @@ export class ProjectStore implements IProjectStore {
);
}
+ get workspaceProjects() {
+ if (!this.rootStore.workspace.workspaceSlug) return [];
+ return this.projects?.[this.rootStore.workspace.workspaceSlug];
+ }
+
get joinedProjects() {
if (!this.rootStore.workspace.workspaceSlug) return [];
return this.projects?.[this.rootStore.workspace.workspaceSlug]?.filter((p) => p.is_member);
diff --git a/web/store/root.ts b/web/store/root.ts
index 827c1a1ee..803fa3894 100644
--- a/web/store/root.ts
+++ b/web/store/root.ts
@@ -1,4 +1,3 @@
-// mobx lite
import { enableStaticRendering } from "mobx-react-lite";
// store imports
import UserStore from "store/user.store";
@@ -53,6 +52,19 @@ import {
IGlobalViewIssuesStore,
IGlobalViewsStore,
} from "store/global-view";
+import {
+ ProfileIssueStore,
+ IProfileIssueStore,
+ ProfileIssueFilterStore,
+ IProfileIssueFilterStore,
+} from "store/profile-issues";
+import {
+ ArchivedIssueStore,
+ IArchivedIssueStore,
+ ArchivedIssueFilterStore,
+ IArchivedIssueFilterStore,
+} from "store/archived-issues";
+import { DraftIssueStore, IDraftIssueStore, DraftIssueFilterStore, IDraftIssueFilterStore } from "store/draft-issues";
import {
IInboxFiltersStore,
IInboxIssueDetailsStore,
@@ -102,6 +114,15 @@ export class RootStore {
globalViewIssues: IGlobalViewIssuesStore;
globalViewFilters: IGlobalViewFiltersStore;
+ profileIssues: IProfileIssueStore;
+ profileIssueFilters: IProfileIssueFilterStore;
+
+ archivedIssues: IArchivedIssueStore;
+ archivedIssueFilters: IArchivedIssueFilterStore;
+
+ draftIssues: IDraftIssueStore;
+ draftIssueFilters: IDraftIssueFilterStore;
+
inbox: IInboxStore;
inboxIssues: IInboxIssuesStore;
inboxIssueDetails: IInboxIssueDetailsStore;
@@ -143,6 +164,15 @@ export class RootStore {
this.globalViewIssues = new GlobalViewIssuesStore(this);
this.globalViewFilters = new GlobalViewFiltersStore(this);
+ this.profileIssues = new ProfileIssueStore(this);
+ this.profileIssueFilters = new ProfileIssueFilterStore(this);
+
+ this.archivedIssues = new ArchivedIssueStore(this);
+ this.archivedIssueFilters = new ArchivedIssueFilterStore(this);
+
+ this.draftIssues = new DraftIssueStore(this);
+ this.draftIssueFilters = new DraftIssueFilterStore(this);
+
this.inbox = new InboxStore(this);
this.inboxIssues = new InboxIssuesStore(this);
this.inboxIssueDetails = new InboxIssueDetailsStore(this);
diff --git a/yarn.lock b/yarn.lock
index 8b32e5390..6a05e0fde 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2835,7 +2835,7 @@
dependencies:
"@types/react" "*"
-"@types/react@*", "@types/react@18.2.0":
+"@types/react@*", "@types/react@18.0.15", "@types/react@18.0.28", "@types/react@18.2.0", "@types/react@^18.2.5":
version "18.2.0"
resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.0.tgz#15cda145354accfc09a18d2f2305f9fc099ada21"
integrity sha512-0FLj93y5USLHdnhIhABk83rm8XEGA7kH3cr+YUlvxoUGp1xNt/DINUMvqPxLyOQMzLmZe8i4RTHbvb8MC7NmrA==
@@ -2844,33 +2844,6 @@
"@types/scheduler" "*"
csstype "^3.0.2"
-"@types/react@18.0.15":
- version "18.0.15"
- resolved "https://registry.yarnpkg.com/@types/react/-/react-18.0.15.tgz#d355644c26832dc27f3e6cbf0c4f4603fc4ab7fe"
- integrity sha512-iz3BtLuIYH1uWdsv6wXYdhozhqj20oD4/Hk2DNXIn1kFsmp9x8d9QB6FnPhfkbhd2PgEONt9Q1x/ebkwjfFLow==
- dependencies:
- "@types/prop-types" "*"
- "@types/scheduler" "*"
- csstype "^3.0.2"
-
-"@types/react@18.0.28":
- version "18.0.28"
- resolved "https://registry.yarnpkg.com/@types/react/-/react-18.0.28.tgz#accaeb8b86f4908057ad629a26635fe641480065"
- integrity sha512-RD0ivG1kEztNBdoAK7lekI9M+azSnitIn85h4iOiaLjaTrMjzslhaqCGaI4IyCJ1RljWiLCEu4jyrLLgqxBTew==
- dependencies:
- "@types/prop-types" "*"
- "@types/scheduler" "*"
- csstype "^3.0.2"
-
-"@types/react@^18.2.5":
- version "18.2.28"
- resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.28.tgz#86877465c0fcf751659a36c769ecedfcfacee332"
- integrity sha512-ad4aa/RaaJS3hyGz0BGegdnSRXQBkd1CCYDCdNjBPg90UUpLgo+WlJqb9fMYUxtehmzF3PJaTWqRZjko6BRzBg==
- dependencies:
- "@types/prop-types" "*"
- "@types/scheduler" "*"
- csstype "^3.0.2"
-
"@types/reactcss@*":
version "1.2.6"
resolved "https://registry.yarnpkg.com/@types/reactcss/-/reactcss-1.2.6.tgz#133c1e7e896f2726370d1d5a26bf06a30a038bcc"