mirror of
https://github.com/makeplane/plane
synced 2024-06-14 14:31:34 +00:00
fix:mobx fixes
This commit is contained in:
parent
0deed77f1d
commit
579347c991
@ -1,7 +1,7 @@
|
||||
"use client";
|
||||
|
||||
// types
|
||||
import { TIssuePriorityKey } from "store/types/issue";
|
||||
import { TIssuePriorityKey } from "types/issue";
|
||||
// constants
|
||||
import { issuePriorityFilter } from "constants/data";
|
||||
|
||||
|
@ -10,7 +10,7 @@ import { IssueBlockState } from "components/issues/board-views/block-state";
|
||||
import { IssueBlockLabels } from "components/issues/board-views/block-labels";
|
||||
import { IssueBlockDueDate } from "components/issues/board-views/block-due-date";
|
||||
// interfaces
|
||||
import { IIssue } from "store/types/issue";
|
||||
import { IIssue } from "types/issue";
|
||||
import { RootStore } from "store/root";
|
||||
|
||||
export const IssueListBlock = observer(({ issue }: { issue: IIssue }) => {
|
||||
|
@ -3,7 +3,7 @@
|
||||
// mobx react lite
|
||||
import { observer } from "mobx-react-lite";
|
||||
// interfaces
|
||||
import { IIssueState } from "store/types/issue";
|
||||
import { IIssueState } from "types/issue";
|
||||
// constants
|
||||
import { issueGroupFilter } from "constants/data";
|
||||
// mobx hook
|
||||
@ -24,7 +24,7 @@ export const IssueListHeader = observer(({ state }: { state: IIssueState }) => {
|
||||
</div>
|
||||
<div className="font-semibold text-base capitalize ml-2 mr-3">{state?.name}</div>
|
||||
<div className="text-gray-700 w-full max-w-[26px] h-[20px] flex justify-center items-center rounded-full">
|
||||
{store.issue.getCountOfIssuesByState(state.id)}
|
||||
{/* {store.issue.getCountOfIssuesByState(state.id)} */}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
@ -6,7 +6,7 @@ import { observer } from "mobx-react-lite";
|
||||
import { IssueListHeader } from "components/issues/board-views/kanban/header";
|
||||
import { IssueListBlock } from "components/issues/board-views/kanban/block";
|
||||
// interfaces
|
||||
import { IIssueState, IIssue } from "store/types/issue";
|
||||
import { IIssueState, IIssue } from "types/issue";
|
||||
// mobx hook
|
||||
import { useMobxStore } from "lib/mobx/store-provider";
|
||||
import { RootStore } from "store/root";
|
||||
|
@ -10,24 +10,24 @@ import { IssueBlockDueDate } from "components/issues/board-views/block-due-date"
|
||||
// mobx hook
|
||||
import { useMobxStore } from "lib/mobx/store-provider";
|
||||
// interfaces
|
||||
import { IIssue } from "store/types/issue";
|
||||
import { IIssue } from "types/issue";
|
||||
import { RootStore } from "store/root";
|
||||
|
||||
export const IssueListBlock = observer(({ issue }: { issue: IIssue }) => {
|
||||
const store: RootStore = useMobxStore();
|
||||
const { issue: issueStore, project: projectStore }: RootStore = useMobxStore();
|
||||
|
||||
return (
|
||||
<div className="flex items-center px-9 py-3.5 relative gap-10 border-b border-custom-border-200 bg-custom-background-100 last:border-b-0">
|
||||
<div className="relative flex items-center gap-6 w-full flex-grow overflow-hidden">
|
||||
{/* id */}
|
||||
<div className="flex-shrink-0 text-sm w-[60px] text-custom-text-200">
|
||||
{store?.project?.project?.identifier}-{issue?.sequence_id}
|
||||
<div className="flex-shrink-0 text-sm w-auto text-custom-text-200">
|
||||
{projectStore?.project?.identifier}-{issue?.sequence_id}
|
||||
</div>
|
||||
{/* name */}
|
||||
<div className="h-full line-clamp-1 w-full overflow-ellipsis cursor-pointer">
|
||||
<p
|
||||
onClick={() => {
|
||||
store.issue.setActivePeekOverviewIssueId(issue.id);
|
||||
issueStore.setPeekId(issue.id);
|
||||
}}
|
||||
className="text-[0.825rem] font-medium text-sm truncate text-custom-text-100"
|
||||
>
|
||||
|
@ -3,7 +3,7 @@
|
||||
// mobx react lite
|
||||
import { observer } from "mobx-react-lite";
|
||||
// interfaces
|
||||
import { IIssueState } from "store/types/issue";
|
||||
import { IIssueState } from "types/issue";
|
||||
// constants
|
||||
import { issueGroupFilter } from "constants/data";
|
||||
// mobx hook
|
||||
@ -23,7 +23,7 @@ export const IssueListHeader = observer(({ state }: { state: IIssueState }) => {
|
||||
<stateGroup.icon />
|
||||
</div>
|
||||
<div className="font-semibold leading-6 text-base capitalize ml-2 mr-3">{state?.name}</div>
|
||||
<div className="text-gray-700 font-normal text-base">{store.issue.getCountOfIssuesByState(state.id)}</div>
|
||||
{/* <div className="text-gray-700 font-normal text-base">{store.issue.getCountOfIssuesByState(state.id)}</div> */}
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
@ -6,25 +6,25 @@ import { observer } from "mobx-react-lite";
|
||||
import { IssueListHeader } from "components/issues/board-views/list/header";
|
||||
import { IssueListBlock } from "components/issues/board-views/list/block";
|
||||
// interfaces
|
||||
import { IIssueState, IIssue } from "store/types/issue";
|
||||
import { IIssueState, IIssue } from "types/issue";
|
||||
// mobx hook
|
||||
import { useMobxStore } from "lib/mobx/store-provider";
|
||||
import { RootStore } from "store/root";
|
||||
|
||||
export const IssueListView = observer(() => {
|
||||
const store: RootStore = useMobxStore();
|
||||
|
||||
const { issue: issueStore }: RootStore = useMobxStore();
|
||||
console.log("issueStore", issueStore.states);
|
||||
return (
|
||||
<>
|
||||
{store?.issue?.states &&
|
||||
store?.issue?.states.length > 0 &&
|
||||
store?.issue?.states.map((_state: IIssueState) => (
|
||||
{issueStore?.states &&
|
||||
issueStore?.states.length > 0 &&
|
||||
issueStore?.states.map((_state: IIssueState) => (
|
||||
<div key={_state.id} className="relative w-full">
|
||||
<IssueListHeader state={_state} />
|
||||
{store.issue.getFilteredIssuesByState(_state.id) &&
|
||||
store.issue.getFilteredIssuesByState(_state.id).length > 0 ? (
|
||||
{issueStore.getFilteredIssuesByState(_state.id) &&
|
||||
issueStore.getFilteredIssuesByState(_state.id).length > 0 ? (
|
||||
<div className="divide-y">
|
||||
{store.issue.getFilteredIssuesByState(_state.id).map((_issue: IIssue) => (
|
||||
{issueStore.getFilteredIssuesByState(_state.id).map((_issue: IIssue) => (
|
||||
<IssueListBlock key={_issue.id} issue={_issue} />
|
||||
))}
|
||||
</div>
|
||||
|
@ -4,7 +4,7 @@ import { observer } from "mobx-react-lite";
|
||||
// mobx hook
|
||||
import { useMobxStore } from "lib/mobx/store-provider";
|
||||
// interfaces
|
||||
import { IIssueLabel } from "store/types/issue";
|
||||
import { IIssueLabel } from "types/issue";
|
||||
|
||||
export const RenderIssueLabel = observer(({ label }: { label: IIssueLabel }) => {
|
||||
const store = useMobxStore();
|
||||
|
@ -4,7 +4,7 @@ import { observer } from "mobx-react-lite";
|
||||
// components
|
||||
import { RenderIssueLabel } from "./filter-label-block";
|
||||
// interfaces
|
||||
import { IIssueLabel } from "store/types/issue";
|
||||
import { IIssueLabel } from "types/issue";
|
||||
// mobx hook
|
||||
import { useMobxStore } from "lib/mobx/store-provider";
|
||||
import { RootStore } from "store/root";
|
||||
|
@ -4,7 +4,7 @@ import { observer } from "mobx-react-lite";
|
||||
// mobx hook
|
||||
import { useMobxStore } from "lib/mobx/store-provider";
|
||||
// interfaces
|
||||
import { IIssuePriorityFilters } from "store/types/issue";
|
||||
import { IIssuePriorityFilters } from "types/issue";
|
||||
|
||||
export const RenderIssuePriority = observer(({ priority }: { priority: IIssuePriorityFilters }) => {
|
||||
const store = useMobxStore();
|
||||
|
@ -6,7 +6,7 @@ import { useMobxStore } from "lib/mobx/store-provider";
|
||||
// components
|
||||
import { RenderIssuePriority } from "./filter-priority-block";
|
||||
// interfaces
|
||||
import { IIssuePriorityFilters } from "store/types/issue";
|
||||
import { IIssuePriorityFilters } from "types/issue";
|
||||
// constants
|
||||
import { issuePriorityFilters } from "constants/data";
|
||||
|
||||
|
@ -4,7 +4,7 @@ import { observer } from "mobx-react-lite";
|
||||
// mobx hook
|
||||
import { useMobxStore } from "lib/mobx/store-provider";
|
||||
// interfaces
|
||||
import { IIssueState } from "store/types/issue";
|
||||
import { IIssueState } from "types/issue";
|
||||
// constants
|
||||
import { issueGroupFilter } from "constants/data";
|
||||
|
||||
|
@ -4,7 +4,7 @@ import { observer } from "mobx-react-lite";
|
||||
// components
|
||||
import { RenderIssueState } from "./filter-state-block";
|
||||
// interfaces
|
||||
import { IIssueState } from "store/types/issue";
|
||||
import { IIssueState } from "types/issue";
|
||||
// mobx hook
|
||||
import { useMobxStore } from "lib/mobx/store-provider";
|
||||
import { RootStore } from "store/root";
|
||||
|
@ -39,9 +39,11 @@ const IssueNavbar = observer(() => {
|
||||
useEffect(() => {
|
||||
if (workspace_slug && projectStore) {
|
||||
if (board) {
|
||||
console.log("setting");
|
||||
projectStore.setActiveBoard(board.toString());
|
||||
} else {
|
||||
router.push(`/${workspace_slug}/${project_slug}?board=list`);
|
||||
projectStore.setActiveBoard("list");
|
||||
}
|
||||
}
|
||||
}, [board, router, projectStore, workspace_slug, project_slug]);
|
||||
|
@ -3,7 +3,7 @@ import { observer } from "mobx-react-lite";
|
||||
// constants
|
||||
import { issueViews } from "constants/data";
|
||||
// interfaces
|
||||
import { TIssueBoardKeys } from "store/types";
|
||||
import { TIssueBoardKeys } from "types";
|
||||
// mobx
|
||||
import { useMobxStore } from "lib/mobx/store-provider";
|
||||
import { RootStore } from "store/root";
|
||||
@ -16,18 +16,18 @@ export const NavbarIssueBoardView = observer(() => {
|
||||
|
||||
const handleCurrentBoardView = (boardView: string) => {
|
||||
projectStore.setActiveBoard(boardView);
|
||||
router.replace(
|
||||
router.push(
|
||||
`/${workspace_slug}/${project_slug}?board=${boardView}${
|
||||
issueStore?.userSelectedLabels && issueStore?.userSelectedLabels.length > 0
|
||||
? `&labels=${issueStore?.userSelectedLabels.join(",")}`
|
||||
issueStore?.filteredLabels && issueStore?.filteredLabels.length > 0
|
||||
? `&labels=${issueStore?.filteredLabels.join(",")}`
|
||||
: ""
|
||||
}${
|
||||
issueStore?.userSelectedPriorities && issueStore?.userSelectedPriorities.length > 0
|
||||
? `&priorities=${issueStore?.userSelectedPriorities.join(",")}`
|
||||
issueStore?.filteredPriorities && issueStore?.filteredPriorities.length > 0
|
||||
? `&priorities=${issueStore?.filteredPriorities.join(",")}`
|
||||
: ""
|
||||
}${
|
||||
issueStore?.userSelectedStates && issueStore?.userSelectedStates.length > 0
|
||||
? `&states=${issueStore?.userSelectedStates.join(",")}`
|
||||
issueStore?.filteredStates && issueStore?.filteredStates.length > 0
|
||||
? `&states=${issueStore?.filteredStates.join(",")}`
|
||||
: ""
|
||||
}`
|
||||
);
|
||||
@ -37,8 +37,6 @@ export const NavbarIssueBoardView = observer(() => {
|
||||
<>
|
||||
{projectStore?.viewOptions &&
|
||||
Object.keys(projectStore?.viewOptions).map((viewKey: string) => {
|
||||
console.log("projectStore?.activeBoard", projectStore?.activeBoard);
|
||||
console.log("viewKey", viewKey);
|
||||
if (projectStore?.viewOptions[viewKey]) {
|
||||
return (
|
||||
<div
|
||||
|
@ -19,27 +19,25 @@ export const NavbarIssueFilter = observer(() => {
|
||||
const pathName = router.asPath;
|
||||
|
||||
const handleOnSelect = (key: "states" | "labels" | "priorities", value: string) => {
|
||||
if (key === "states") {
|
||||
store.issue.userSelectedStates = store.issue.userSelectedStates.includes(value)
|
||||
? store.issue.userSelectedStates.filter((s) => s !== value)
|
||||
: [...store.issue.userSelectedStates, value];
|
||||
} else if (key === "labels") {
|
||||
store.issue.userSelectedLabels = store.issue.userSelectedLabels.includes(value)
|
||||
? store.issue.userSelectedLabels.filter((l) => l !== value)
|
||||
: [...store.issue.userSelectedLabels, value];
|
||||
} else if (key === "priorities") {
|
||||
store.issue.userSelectedPriorities = store.issue.userSelectedPriorities.includes(value)
|
||||
? store.issue.userSelectedPriorities.filter((p) => p !== value)
|
||||
: [...store.issue.userSelectedPriorities, value];
|
||||
}
|
||||
|
||||
const paramsCommaSeparated = `${`board=${store.issue.currentIssueBoardView || "list"}`}${
|
||||
store.issue.userSelectedPriorities.length > 0 ? `&priorities=${store.issue.userSelectedPriorities.join(",")}` : ""
|
||||
}${store.issue.userSelectedStates.length > 0 ? `&states=${store.issue.userSelectedStates.join(",")}` : ""}${
|
||||
store.issue.userSelectedLabels.length > 0 ? `&labels=${store.issue.userSelectedLabels.join(",")}` : ""
|
||||
}`;
|
||||
|
||||
router.replace(`${pathName}?${paramsCommaSeparated}`);
|
||||
// if (key === "states") {
|
||||
// store.issue.userSelectedStates = store.issue.userSelectedStates.includes(value)
|
||||
// ? store.issue.userSelectedStates.filter((s) => s !== value)
|
||||
// : [...store.issue.userSelectedStates, value];
|
||||
// } else if (key === "labels") {
|
||||
// store.issue.userSelectedLabels = store.issue.userSelectedLabels.includes(value)
|
||||
// ? store.issue.userSelectedLabels.filter((l) => l !== value)
|
||||
// : [...store.issue.userSelectedLabels, value];
|
||||
// } else if (key === "priorities") {
|
||||
// store.issue.userSelectedPriorities = store.issue.userSelectedPriorities.includes(value)
|
||||
// ? store.issue.userSelectedPriorities.filter((p) => p !== value)
|
||||
// : [...store.issue.userSelectedPriorities, value];
|
||||
// }
|
||||
// const paramsCommaSeparated = `${`board=${store.issue.currentIssueBoardView || "list"}`}${
|
||||
// store.issue.userSelectedPriorities.length > 0 ? `&priorities=${store.issue.userSelectedPriorities.join(",")}` : ""
|
||||
// }${store.issue.userSelectedStates.length > 0 ? `&states=${store.issue.userSelectedStates.join(",")}` : ""}${
|
||||
// store.issue.userSelectedLabels.length > 0 ? `&labels=${store.issue.userSelectedLabels.join(",")}` : ""
|
||||
// }`;
|
||||
// router.replace(`${pathName}?${paramsCommaSeparated}`);
|
||||
};
|
||||
|
||||
return (
|
||||
@ -69,7 +67,7 @@ export const NavbarIssueFilter = observer(() => {
|
||||
</span>
|
||||
),
|
||||
onClick: () => handleOnSelect("priorities", priority),
|
||||
isSelected: store.issue.userSelectedPriorities.includes(priority),
|
||||
isSelected: store.issue.filteredPriorities.includes(priority),
|
||||
})),
|
||||
},
|
||||
{
|
||||
@ -85,7 +83,7 @@ export const NavbarIssueFilter = observer(() => {
|
||||
</span>
|
||||
),
|
||||
onClick: () => handleOnSelect("states", state.id),
|
||||
isSelected: store.issue.userSelectedStates.includes(state.id),
|
||||
isSelected: store.issue.filteredStates.includes(state.id),
|
||||
};
|
||||
}),
|
||||
},
|
||||
@ -104,7 +102,7 @@ export const NavbarIssueFilter = observer(() => {
|
||||
</span>
|
||||
),
|
||||
onClick: () => handleOnSelect("labels", label.id),
|
||||
isSelected: store.issue.userSelectedLabels.includes(label.id),
|
||||
isSelected: store.issue.filteredLabels.includes(label.id),
|
||||
})),
|
||||
},
|
||||
]}
|
||||
|
@ -9,7 +9,7 @@ import useToast from "hooks/use-toast";
|
||||
// ui
|
||||
import { SecondaryButton } from "components/ui";
|
||||
// types
|
||||
import { Comment } from "store/types";
|
||||
import { Comment } from "types";
|
||||
// components
|
||||
import Tiptap, { ITiptapRichTextEditor } from "components/tiptap";
|
||||
|
||||
|
@ -16,7 +16,7 @@ import { ChatBubbleLeftEllipsisIcon, CheckIcon, XMarkIcon, EllipsisVerticalIcon
|
||||
// helpers
|
||||
import { timeAgo } from "helpers/date-time.helper";
|
||||
// types
|
||||
import { Comment } from "store/types";
|
||||
import { Comment } from "types";
|
||||
import Tiptap, { ITiptapRichTextEditor } from "components/tiptap";
|
||||
|
||||
const TiptapEditor = React.forwardRef<ITiptapRichTextEditor, ITiptapRichTextEditor>((props, ref) => (
|
||||
|
@ -1,7 +1,7 @@
|
||||
// components
|
||||
import { IssueReactions } from "components/issues/peek-overview";
|
||||
// types
|
||||
import { IIssue } from "store/types";
|
||||
import { IIssue } from "types";
|
||||
|
||||
type Props = {
|
||||
issue: IIssue;
|
||||
|
@ -10,7 +10,7 @@ import { Icon } from "components/ui";
|
||||
import { copyTextToClipboard, addSpaceIfCamelCase } from "helpers/string.helper";
|
||||
|
||||
// types
|
||||
import { IIssue } from "store/types";
|
||||
import { IIssue } from "types";
|
||||
|
||||
// constants
|
||||
import { issueGroupFilter, issuePriorityFilter } from "constants/data";
|
||||
|
@ -5,7 +5,7 @@ import { Dialog, Transition } from "@headlessui/react";
|
||||
import { FullScreenPeekView, SidePeekView } from "components/issues/peek-overview";
|
||||
|
||||
// types
|
||||
import type { IIssue } from "store/types";
|
||||
import type { IIssue } from "types";
|
||||
|
||||
type Props = {
|
||||
issue: IIssue | null;
|
||||
@ -16,12 +16,7 @@ type Props = {
|
||||
|
||||
export type TPeekOverviewModes = "side" | "modal" | "full";
|
||||
|
||||
export const IssuePeekOverview: React.FC<Props> = ({
|
||||
issue,
|
||||
isOpen,
|
||||
onClose,
|
||||
workspaceSlug,
|
||||
}) => {
|
||||
export const IssuePeekOverview: React.FC<Props> = ({ issue, isOpen, onClose, workspaceSlug }) => {
|
||||
const [peekOverviewMode, setPeekOverviewMode] = useState<TPeekOverviewModes>("side");
|
||||
|
||||
const handleClose = () => {
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { useEffect } from "react";
|
||||
import { useRouter } from "next/router";
|
||||
import { observer } from "mobx-react-lite";
|
||||
// components
|
||||
@ -10,15 +11,16 @@ import { IssuePeekOverview } from "components/issues/peek-overview";
|
||||
// mobx store
|
||||
import { RootStore } from "store/root";
|
||||
import { useMobxStore } from "lib/mobx/store-provider";
|
||||
import { useEffect } from "react";
|
||||
|
||||
export const ProjectDetailsView = () => {
|
||||
export const ProjectDetailsView = observer(() => {
|
||||
const router = useRouter();
|
||||
const { workspace_slug, project_slug, states, labels, priorities } = router.query;
|
||||
|
||||
const { issue: issueStore }: RootStore = useMobxStore();
|
||||
const { issue: issueStore, project: projectStore }: RootStore = useMobxStore();
|
||||
|
||||
const activeIssueId = issueStore.activePeekOverviewIssueId;
|
||||
console.log("projectStore?.activeBoard", projectStore?.activeBoard);
|
||||
|
||||
const activeIssueId = issueStore.peekId;
|
||||
|
||||
useEffect(() => {
|
||||
if (workspace_slug && project_slug) {
|
||||
@ -33,14 +35,14 @@ export const ProjectDetailsView = () => {
|
||||
|
||||
return (
|
||||
<div className="relative w-full h-full overflow-hidden">
|
||||
{workspace_slug && (
|
||||
{/* {workspace_slug && (
|
||||
<IssuePeekOverview
|
||||
isOpen={Boolean(activeIssueId)}
|
||||
onClose={() => issueStore.setActivePeekOverviewIssueId(null)}
|
||||
issue={issueStore?.issues?.find((_issue) => _issue.id === activeIssueId) || null}
|
||||
workspaceSlug={workspace_slug.toString()}
|
||||
/>
|
||||
)}
|
||||
)} */}
|
||||
|
||||
{issueStore?.loader && !issueStore.issues ? (
|
||||
<div className="text-sm text-center py-10 text-custom-text-100">Loading...</div>
|
||||
@ -51,23 +53,23 @@ export const ProjectDetailsView = () => {
|
||||
Something went wrong.
|
||||
</div>
|
||||
) : (
|
||||
issueStore?.currentIssueBoardView && (
|
||||
projectStore?.activeBoard && (
|
||||
<>
|
||||
{issueStore?.currentIssueBoardView === "list" && (
|
||||
{projectStore?.activeBoard === "list" && (
|
||||
<div className="relative w-full h-full overflow-y-auto">
|
||||
<div className="mx-auto px-4">
|
||||
<IssueListView />
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{issueStore?.currentIssueBoardView === "kanban" && (
|
||||
{projectStore?.activeBoard === "kanban" && (
|
||||
<div className="relative w-full h-full mx-auto px-9 py-5">
|
||||
<IssueKanbanView />
|
||||
</div>
|
||||
)}
|
||||
{issueStore?.currentIssueBoardView === "calendar" && <IssueCalendarView />}
|
||||
{issueStore?.currentIssueBoardView === "spreadsheet" && <IssueSpreadsheetView />}
|
||||
{issueStore?.currentIssueBoardView === "gantt" && <IssueGanttView />}
|
||||
{projectStore?.activeBoard === "calendar" && <IssueCalendarView />}
|
||||
{projectStore?.activeBoard === "spreadsheet" && <IssueSpreadsheetView />}
|
||||
{projectStore?.activeBoard === "gantt" && <IssueGanttView />}
|
||||
</>
|
||||
)
|
||||
)}
|
||||
@ -75,4 +77,4 @@ export const ProjectDetailsView = () => {
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
});
|
||||
|
@ -7,7 +7,7 @@ import {
|
||||
TIssueGroupKey,
|
||||
IIssuePriorityFilters,
|
||||
IIssueGroup,
|
||||
} from "store/types/issue";
|
||||
} from "types/issue";
|
||||
// icons
|
||||
import {
|
||||
BacklogStateIcon,
|
||||
|
@ -3,7 +3,7 @@ import type { GetServerSideProps } from "next";
|
||||
import { useRouter } from "next/router";
|
||||
import Head from "next/head";
|
||||
// types
|
||||
import { TIssueBoardKeys } from "store/types";
|
||||
import { TIssueBoardKeys } from "types";
|
||||
import ProjectLayout from "layouts/project-layout";
|
||||
import { ProjectDetailsView } from "components/views/project-details";
|
||||
|
||||
|
@ -1,204 +1,79 @@
|
||||
// mobx
|
||||
import { observable, action, computed, makeObservable, runInAction, reaction } from "mobx";
|
||||
// service
|
||||
// services
|
||||
import IssueService from "services/issue.service";
|
||||
// store
|
||||
import { RootStore } from "./root";
|
||||
// types
|
||||
import { IssueDetailType, TIssueBoardKeys } from "store/types/issue";
|
||||
import { IIssue, IIssueState, IIssueLabel } from "./types";
|
||||
// import { IssueDetailType, TIssueBoardKeys } from "types/issue";
|
||||
import { IIssue, IIssueState, IIssueLabel } from "types/issue";
|
||||
|
||||
export interface IIssueStore {
|
||||
currentIssueBoardView: TIssueBoardKeys | null;
|
||||
loader: boolean;
|
||||
error: any | null;
|
||||
error: any;
|
||||
// issue options
|
||||
issues: IIssue[] | null;
|
||||
states: IIssueState[] | null;
|
||||
labels: IIssueLabel[] | null;
|
||||
issues: IIssue[] | null;
|
||||
issue_detail: IssueDetailType;
|
||||
userSelectedStates: string[];
|
||||
userSelectedLabels: string[];
|
||||
userSelectedPriorities: string[];
|
||||
activePeekOverviewIssueId: string | null;
|
||||
getCountOfIssuesByState: (state: string) => number;
|
||||
// filtering
|
||||
filteredStates: string[];
|
||||
filteredLabels: string[];
|
||||
filteredPriorities: string[];
|
||||
// peek info
|
||||
peekId: string | null;
|
||||
// service
|
||||
issueService: any;
|
||||
// actions
|
||||
fetchPublicIssues: (workspace_slug: string, project_slug: string, params: any) => void;
|
||||
setPeekId: (issueId: string) => void;
|
||||
getFilteredIssuesByState: (state: string) => IIssue[];
|
||||
getUserSelectedFilter: (key: "state" | "priority" | "label", value: string) => boolean;
|
||||
checkIfFilterExistsForKey: (key: "state" | "priority" | "label") => boolean;
|
||||
clearUserSelectedFilter: (key: "state" | "priority" | "label" | "all") => void;
|
||||
getIfFiltersIsEmpty: () => boolean;
|
||||
getURLDefinition: (
|
||||
workspaceSlug: string,
|
||||
projectId: string,
|
||||
action?: {
|
||||
key: "state" | "priority" | "label" | "all";
|
||||
value?: string;
|
||||
removeAll?: boolean;
|
||||
}
|
||||
) => string;
|
||||
setActivePeekOverviewIssueId: (value: any) => void;
|
||||
setCurrentIssueBoardView: (view: TIssueBoardKeys) => void;
|
||||
fetchPublicIssues: (workspaceSlug: string, projectId: string, params: any) => Promise<void>;
|
||||
getIssueByIdAsync: (workspaceSlug: string, projectId: string, issueId: string) => Promise<IssueDetailType>;
|
||||
}
|
||||
|
||||
class IssueStore {
|
||||
currentIssueBoardView: TIssueBoardKeys | null = null;
|
||||
|
||||
class IssueStore implements IIssueStore {
|
||||
loader: boolean = false;
|
||||
error: any | null = null;
|
||||
|
||||
states: IIssueState[] | null = null;
|
||||
labels: IIssueLabel[] | null = null;
|
||||
issues: IIssue[] | null = null;
|
||||
states: IIssueState[] | null = [];
|
||||
labels: IIssueLabel[] | null = [];
|
||||
|
||||
issue_detail: IssueDetailType = {};
|
||||
filteredStates: string[] = [];
|
||||
filteredLabels: string[] = [];
|
||||
filteredPriorities: string[] = [];
|
||||
|
||||
activePeekOverviewIssueId: string | null = null;
|
||||
issues: IIssue[] | null = [];
|
||||
issue_detail: any = {};
|
||||
|
||||
userSelectedStates: string[] = [];
|
||||
userSelectedLabels: string[] = [];
|
||||
userSelectedPriorities: string[] = [];
|
||||
// root store
|
||||
rootStore;
|
||||
// service
|
||||
issueService;
|
||||
peekId: string | null = null;
|
||||
|
||||
rootStore: RootStore;
|
||||
issueService: any;
|
||||
|
||||
constructor(_rootStore: any) {
|
||||
makeObservable(this, {
|
||||
// observable
|
||||
currentIssueBoardView: observable,
|
||||
|
||||
loader: observable,
|
||||
error: observable,
|
||||
|
||||
// issue options
|
||||
states: observable.ref,
|
||||
labels: observable.ref,
|
||||
// filtering
|
||||
filteredStates: observable.ref,
|
||||
filteredLabels: observable.ref,
|
||||
filteredPriorities: observable.ref,
|
||||
// issues
|
||||
issues: observable.ref,
|
||||
issue_detail: observable.ref,
|
||||
|
||||
activePeekOverviewIssueId: observable.ref,
|
||||
|
||||
userSelectedStates: observable.ref,
|
||||
userSelectedLabels: observable.ref,
|
||||
userSelectedPriorities: observable.ref,
|
||||
// action
|
||||
setCurrentIssueBoardView: action,
|
||||
// peek
|
||||
peekId: observable.ref,
|
||||
// actions
|
||||
fetchPublicIssues: action,
|
||||
// computed
|
||||
setPeekId: action,
|
||||
getFilteredIssuesByState: action,
|
||||
});
|
||||
|
||||
this.rootStore = _rootStore;
|
||||
this.issueService = new IssueService();
|
||||
}
|
||||
|
||||
// computed
|
||||
getCountOfIssuesByState(state_id: string): number {
|
||||
return this.issues?.filter((issue) => issue.state == state_id).length || 0;
|
||||
}
|
||||
|
||||
getFilteredIssuesByState(state_id: string): IIssue[] | [] {
|
||||
return this.issues?.filter((issue) => issue.state == state_id) || [];
|
||||
}
|
||||
|
||||
setActivePeekOverviewIssueId = (issueId: string | null) => (this.activePeekOverviewIssueId = issueId);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param key Is the key of the filter, i.e. state, label, priority
|
||||
* @param value Is the value of the filter, i.e. state_id, label_id, priority
|
||||
* @returns boolean
|
||||
*/
|
||||
|
||||
getUserSelectedFilter(key: "state" | "priority" | "label", value: string): boolean {
|
||||
if (key == "state") {
|
||||
return this.userSelectedStates.includes(value);
|
||||
} else if (key == "label") {
|
||||
return this.userSelectedLabels.includes(value);
|
||||
} else if (key == "priority") {
|
||||
return this.userSelectedPriorities.includes(value);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
checkIfFilterExistsForKey: (key: "state" | "priority" | "label") => boolean = (key) => {
|
||||
if (key == "state") {
|
||||
return this.userSelectedStates.length > 0;
|
||||
} else if (key == "label") {
|
||||
return this.userSelectedLabels.length > 0;
|
||||
} else if (key == "priority") {
|
||||
return this.userSelectedPriorities.length > 0;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
clearUserSelectedFilter(key: "state" | "priority" | "label" | "all") {
|
||||
if (key == "state") {
|
||||
this.userSelectedStates = [];
|
||||
} else if (key == "label") {
|
||||
this.userSelectedLabels = [];
|
||||
} else if (key == "priority") {
|
||||
this.userSelectedPriorities = [];
|
||||
} else if (key == "all") {
|
||||
this.userSelectedStates = [];
|
||||
this.userSelectedLabels = [];
|
||||
this.userSelectedPriorities = [];
|
||||
}
|
||||
}
|
||||
|
||||
getIfFiltersIsEmpty: () => boolean = () =>
|
||||
this.userSelectedStates.length === 0 &&
|
||||
this.userSelectedLabels.length === 0 &&
|
||||
this.userSelectedPriorities.length === 0;
|
||||
|
||||
getURLDefinition = (
|
||||
workspaceSlug: string,
|
||||
projectId: string,
|
||||
action?: {
|
||||
key: "state" | "priority" | "label" | "all";
|
||||
value?: string;
|
||||
removeAll?: boolean;
|
||||
}
|
||||
) => {
|
||||
let url = `/${workspaceSlug}/${projectId}?board=${this.currentIssueBoardView}`;
|
||||
|
||||
if (action) {
|
||||
if (action.key === "state")
|
||||
this.userSelectedStates = action.removeAll
|
||||
? []
|
||||
: [...this.userSelectedStates].filter((state) => state !== action.value);
|
||||
if (action.key === "label")
|
||||
this.userSelectedLabels = action.removeAll
|
||||
? []
|
||||
: [...this.userSelectedLabels].filter((label) => label !== action.value);
|
||||
if (action.key === "priority")
|
||||
this.userSelectedPriorities = action.removeAll
|
||||
? []
|
||||
: [...this.userSelectedPriorities].filter((priority) => priority !== action.value);
|
||||
if (action.key === "all") {
|
||||
this.userSelectedStates = [];
|
||||
this.userSelectedLabels = [];
|
||||
this.userSelectedPriorities = [];
|
||||
}
|
||||
}
|
||||
|
||||
if (this.checkIfFilterExistsForKey("state")) {
|
||||
url += `&states=${this.userSelectedStates.join(",")}`;
|
||||
}
|
||||
if (this.checkIfFilterExistsForKey("label")) {
|
||||
url += `&labels=${this.userSelectedLabels.join(",")}`;
|
||||
}
|
||||
if (this.checkIfFilterExistsForKey("priority")) {
|
||||
url += `&priorities=${this.userSelectedPriorities.join(",")}`;
|
||||
}
|
||||
|
||||
return url;
|
||||
};
|
||||
|
||||
// action
|
||||
setCurrentIssueBoardView = async (view: TIssueBoardKeys) => {
|
||||
this.currentIssueBoardView = view;
|
||||
};
|
||||
|
||||
fetchPublicIssues = async (workspaceSlug: string, projectId: string, params: any) => {
|
||||
try {
|
||||
this.loader = true;
|
||||
@ -216,352 +91,19 @@ class IssueStore {
|
||||
this.issues = _issues;
|
||||
this.loader = false;
|
||||
});
|
||||
return response;
|
||||
}
|
||||
} catch (error) {
|
||||
this.loader = false;
|
||||
this.error = error;
|
||||
return error;
|
||||
}
|
||||
};
|
||||
|
||||
getIssueByIdAsync = async (workspaceSlug: string, projectId: string, issueId: string): Promise<IssueDetailType> => {
|
||||
try {
|
||||
const response = this.issues?.find((issue) => issue.id === issueId);
|
||||
|
||||
if (response) {
|
||||
const _issue_detail = {
|
||||
...this.issue_detail,
|
||||
[issueId]: {
|
||||
issue: response,
|
||||
comments: [],
|
||||
reactions: [],
|
||||
votes: [],
|
||||
},
|
||||
};
|
||||
runInAction(() => {
|
||||
this.issue_detail = _issue_detail;
|
||||
});
|
||||
|
||||
this.getIssueReactionsAsync(workspaceSlug, projectId, issueId);
|
||||
this.getIssueVotesAsync(workspaceSlug, projectId, issueId);
|
||||
this.getIssueCommentsAsync(workspaceSlug, projectId, issueId);
|
||||
}
|
||||
|
||||
return this.issue_detail[issueId] as any;
|
||||
} catch (error) {
|
||||
this.loader = false;
|
||||
this.error = error;
|
||||
throw error;
|
||||
}
|
||||
setPeekId = (issueId: string) => {
|
||||
this.peekId = issueId;
|
||||
};
|
||||
|
||||
getIssueVotesAsync = async (workspaceSlug: string, projectId: string, issueId: string) => {
|
||||
try {
|
||||
const response = await this.issueService.getIssueVotes(workspaceSlug, projectId, issueId);
|
||||
|
||||
if (response) {
|
||||
const _issue_detail = {
|
||||
...this.issue_detail,
|
||||
[issueId]: {
|
||||
...this.issue_detail[issueId],
|
||||
votes: response,
|
||||
},
|
||||
};
|
||||
runInAction(() => {
|
||||
this.issue_detail = _issue_detail;
|
||||
});
|
||||
}
|
||||
|
||||
return response;
|
||||
} catch (error) {
|
||||
this.loader = false;
|
||||
this.error = error;
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
createIssueVoteAsync = async (
|
||||
workspaceSlug: string,
|
||||
projectId: string,
|
||||
issueId: string,
|
||||
data: {
|
||||
vote: 1 | -1;
|
||||
}
|
||||
) => {
|
||||
try {
|
||||
const response = await this.issueService.createIssueVote(workspaceSlug, projectId, issueId, data);
|
||||
|
||||
if (response) {
|
||||
const _issue_detail = {
|
||||
...this.issue_detail,
|
||||
[issueId]: {
|
||||
...this.issue_detail[issueId],
|
||||
votes: [
|
||||
...{ ...this.issue_detail }[issueId].votes.filter(
|
||||
(vote) => vote.actor !== this.rootStore?.user?.currentUser?.id
|
||||
),
|
||||
response,
|
||||
],
|
||||
},
|
||||
};
|
||||
runInAction(() => {
|
||||
this.issue_detail = _issue_detail;
|
||||
});
|
||||
}
|
||||
|
||||
return response;
|
||||
} catch (error) {
|
||||
this.loader = false;
|
||||
this.error = error;
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
deleteIssueVoteAsync = async (workspaceSlug: string, projectId: string, issueId: string) => {
|
||||
try {
|
||||
const _votes = (this.issue_detail[issueId].votes = this.issue_detail[issueId].votes.filter(
|
||||
(vote) => vote.actor !== this.rootStore?.user?.user?.id
|
||||
));
|
||||
|
||||
runInAction(() => {
|
||||
this.issue_detail[issueId].votes = _votes;
|
||||
});
|
||||
|
||||
const response = await this.issueService.deleteIssueVote(workspaceSlug, projectId, issueId);
|
||||
|
||||
const votesAfterCall = await this.issueService.getIssueVotes(workspaceSlug, projectId, issueId);
|
||||
|
||||
if (votesAfterCall)
|
||||
runInAction(() => {
|
||||
this.issue_detail[issueId].votes = votesAfterCall;
|
||||
});
|
||||
|
||||
return response;
|
||||
} catch (error) {
|
||||
this.loader = false;
|
||||
this.error = error;
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
getIssueReactionsAsync = async (workspaceSlug: string, projectId: string, issueId: string) => {
|
||||
try {
|
||||
const response = await this.issueService.getIssueReactions(workspaceSlug, projectId, issueId);
|
||||
|
||||
if (response) {
|
||||
const _issue_detail = {
|
||||
...this.issue_detail,
|
||||
[issueId]: {
|
||||
...this.issue_detail[issueId],
|
||||
reactions: response,
|
||||
},
|
||||
};
|
||||
runInAction(() => {
|
||||
this.issue_detail = _issue_detail;
|
||||
});
|
||||
}
|
||||
|
||||
return response;
|
||||
} catch (error) {
|
||||
this.loader = false;
|
||||
this.error = error;
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
createIssueReactionAsync = async (workspaceSlug: string, projectId: string, issueId: string, data: any) => {
|
||||
try {
|
||||
const response = await this.issueService.createIssueReaction(workspaceSlug, projectId, issueId, data);
|
||||
|
||||
if (response) {
|
||||
const _issue_detail = {
|
||||
...this.issue_detail,
|
||||
[issueId]: {
|
||||
...this.issue_detail[issueId],
|
||||
reactions: [...this.issue_detail[issueId].reactions, response],
|
||||
},
|
||||
};
|
||||
runInAction(() => {
|
||||
this.issue_detail = _issue_detail;
|
||||
});
|
||||
}
|
||||
|
||||
return response;
|
||||
} catch (error) {
|
||||
this.loader = false;
|
||||
this.error = error;
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
deleteIssueReactionAsync = async (workspaceSlug: string, projectId: string, issueId: string, reactionHex: string) => {
|
||||
try {
|
||||
const newReactionsList = this.issue_detail[issueId].reactions.filter(
|
||||
(reaction) => reaction.reaction !== reactionHex
|
||||
);
|
||||
|
||||
const _issue_detail = {
|
||||
...this.issue_detail,
|
||||
[issueId]: {
|
||||
...this.issue_detail[issueId],
|
||||
reactions: newReactionsList,
|
||||
},
|
||||
};
|
||||
|
||||
runInAction(() => {
|
||||
this.issue_detail = _issue_detail;
|
||||
});
|
||||
|
||||
const response = await this.issueService.deleteIssueReaction(workspaceSlug, projectId, issueId, reactionHex);
|
||||
|
||||
const reactionsAfterCall = await this.issueService.getIssueReactions(workspaceSlug, projectId, issueId);
|
||||
|
||||
if (reactionsAfterCall) {
|
||||
const _issue_detail = {
|
||||
...this.issue_detail,
|
||||
[issueId]: {
|
||||
...this.issue_detail[issueId],
|
||||
reactions: reactionsAfterCall,
|
||||
},
|
||||
};
|
||||
runInAction(() => {
|
||||
this.issue_detail = _issue_detail;
|
||||
});
|
||||
}
|
||||
|
||||
return response;
|
||||
} catch (error) {
|
||||
this.loader = false;
|
||||
this.error = error;
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
getIssueCommentsAsync = async (workspaceSlug: string, projectId: string, issueId: string) => {
|
||||
try {
|
||||
const response = await this.issueService.getIssueComments(workspaceSlug, projectId, issueId);
|
||||
|
||||
if (response) {
|
||||
const _issue_detail = {
|
||||
...this.issue_detail,
|
||||
[issueId]: {
|
||||
...this.issue_detail[issueId],
|
||||
comments: response,
|
||||
},
|
||||
};
|
||||
runInAction(() => {
|
||||
this.issue_detail = _issue_detail;
|
||||
});
|
||||
}
|
||||
|
||||
return response;
|
||||
} catch (error) {
|
||||
this.loader = false;
|
||||
this.error = error;
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
createIssueCommentAsync = async (workspaceSlug: string, projectId: string, issueId: string, data: any) => {
|
||||
try {
|
||||
const response = await this.issueService.createIssueComment(workspaceSlug, projectId, issueId, data);
|
||||
|
||||
if (response) {
|
||||
const _issue_detail = {
|
||||
...this.issue_detail,
|
||||
[issueId]: {
|
||||
...this.issue_detail[issueId],
|
||||
comments: [...this.issue_detail[issueId].comments, response],
|
||||
},
|
||||
};
|
||||
runInAction(() => {
|
||||
this.issue_detail = _issue_detail;
|
||||
});
|
||||
}
|
||||
|
||||
return response;
|
||||
} catch (error) {
|
||||
this.loader = false;
|
||||
this.error = error;
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
updateIssueCommentAsync = async (
|
||||
workspaceSlug: string,
|
||||
projectId: string,
|
||||
issueId: string,
|
||||
commentId: string,
|
||||
data: any
|
||||
) => {
|
||||
try {
|
||||
const response = await this.issueService.updateIssueComment(workspaceSlug, projectId, issueId, commentId, data);
|
||||
|
||||
if (response) {
|
||||
const _issue_detail = {
|
||||
...this.issue_detail,
|
||||
[issueId]: {
|
||||
...this.issue_detail[issueId],
|
||||
comments: [
|
||||
...this.issue_detail[issueId].comments.filter((comment) => comment.id !== response.id),
|
||||
response,
|
||||
],
|
||||
},
|
||||
};
|
||||
runInAction(() => {
|
||||
this.issue_detail = _issue_detail;
|
||||
});
|
||||
}
|
||||
|
||||
return response;
|
||||
} catch (error) {
|
||||
this.loader = false;
|
||||
this.error = error;
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
deleteIssueCommentAsync = async (workspaceSlug: string, projectId: string, issueId: string, commentId: string) => {
|
||||
try {
|
||||
const newCommentsList = this.issue_detail[issueId].comments.filter((comment) => comment.id !== commentId);
|
||||
|
||||
const _issue_detail = {
|
||||
...this.issue_detail,
|
||||
[issueId]: {
|
||||
...this.issue_detail[issueId],
|
||||
comments: newCommentsList,
|
||||
},
|
||||
};
|
||||
|
||||
runInAction(() => {
|
||||
this.issue_detail = _issue_detail;
|
||||
});
|
||||
|
||||
const response = await this.issueService.deleteIssueComment(workspaceSlug, projectId, issueId, commentId);
|
||||
|
||||
const commentsAfterCall = await this.issueService.getIssueComments(workspaceSlug, projectId, issueId);
|
||||
|
||||
if (commentsAfterCall) {
|
||||
const _issue_detail = {
|
||||
...this.issue_detail,
|
||||
[issueId]: {
|
||||
...this.issue_detail[issueId],
|
||||
comments: commentsAfterCall,
|
||||
},
|
||||
};
|
||||
runInAction(() => {
|
||||
this.issue_detail = _issue_detail;
|
||||
});
|
||||
}
|
||||
|
||||
return response;
|
||||
} catch (error) {
|
||||
this.loader = false;
|
||||
this.error = error;
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
getFilteredIssuesByState = (state_id: string): IIssue[] | [] =>
|
||||
this.issues?.filter((issue) => issue.state == state_id) || [];
|
||||
}
|
||||
|
||||
export default IssueStore;
|
||||
|
567
apps/space/store/issue_legacy.ts
Normal file
567
apps/space/store/issue_legacy.ts
Normal file
@ -0,0 +1,567 @@
|
||||
// mobx
|
||||
import { observable, action, computed, makeObservable, runInAction, reaction } from "mobx";
|
||||
// service
|
||||
import IssueService from "services/issue.service";
|
||||
// types
|
||||
import { IssueDetailType, TIssueBoardKeys } from "types/issue";
|
||||
import { IIssue, IIssueState, IIssueLabel } from "../types";
|
||||
|
||||
export interface IIssueStore {
|
||||
currentIssueBoardView: TIssueBoardKeys | null;
|
||||
loader: boolean;
|
||||
error: any | null;
|
||||
states: IIssueState[] | null;
|
||||
labels: IIssueLabel[] | null;
|
||||
issues: IIssue[] | null;
|
||||
issue_detail: IssueDetailType;
|
||||
userSelectedStates: string[];
|
||||
userSelectedLabels: string[];
|
||||
userSelectedPriorities: string[];
|
||||
activePeekOverviewIssueId: string | null;
|
||||
getCountOfIssuesByState: (state: string) => number;
|
||||
getFilteredIssuesByState: (state: string) => IIssue[];
|
||||
getUserSelectedFilter: (key: "state" | "priority" | "label", value: string) => boolean;
|
||||
checkIfFilterExistsForKey: (key: "state" | "priority" | "label") => boolean;
|
||||
clearUserSelectedFilter: (key: "state" | "priority" | "label" | "all") => void;
|
||||
getIfFiltersIsEmpty: () => boolean;
|
||||
getURLDefinition: (
|
||||
workspaceSlug: string,
|
||||
projectId: string,
|
||||
action?: {
|
||||
key: "state" | "priority" | "label" | "all";
|
||||
value?: string;
|
||||
removeAll?: boolean;
|
||||
}
|
||||
) => string;
|
||||
setActivePeekOverviewIssueId: (value: any) => void;
|
||||
setCurrentIssueBoardView: (view: TIssueBoardKeys) => void;
|
||||
fetchPublicIssues: (workspaceSlug: string, projectId: string, params: any) => Promise<void>;
|
||||
getIssueByIdAsync: (workspaceSlug: string, projectId: string, issueId: string) => Promise<IssueDetailType>;
|
||||
}
|
||||
|
||||
class IssueLegacyStore {
|
||||
currentIssueBoardView: TIssueBoardKeys | null = null;
|
||||
|
||||
loader: boolean = false;
|
||||
error: any | null = null;
|
||||
|
||||
states: IIssueState[] | null = null;
|
||||
labels: IIssueLabel[] | null = null;
|
||||
issues: IIssue[] | null = null;
|
||||
|
||||
issue_detail: IssueDetailType = {};
|
||||
|
||||
activePeekOverviewIssueId: string | null = null;
|
||||
|
||||
userSelectedStates: string[] = [];
|
||||
userSelectedLabels: string[] = [];
|
||||
userSelectedPriorities: string[] = [];
|
||||
// root store
|
||||
rootStore;
|
||||
// service
|
||||
issueService;
|
||||
|
||||
constructor(_rootStore: any) {
|
||||
makeObservable(this, {
|
||||
// observable
|
||||
currentIssueBoardView: observable,
|
||||
|
||||
loader: observable,
|
||||
error: observable,
|
||||
|
||||
states: observable.ref,
|
||||
labels: observable.ref,
|
||||
issues: observable.ref,
|
||||
issue_detail: observable.ref,
|
||||
|
||||
activePeekOverviewIssueId: observable.ref,
|
||||
|
||||
userSelectedStates: observable.ref,
|
||||
userSelectedLabels: observable.ref,
|
||||
userSelectedPriorities: observable.ref,
|
||||
// action
|
||||
setCurrentIssueBoardView: action,
|
||||
fetchPublicIssues: action,
|
||||
// computed
|
||||
});
|
||||
|
||||
this.rootStore = _rootStore;
|
||||
this.issueService = new IssueService();
|
||||
}
|
||||
|
||||
// computed
|
||||
getCountOfIssuesByState(state_id: string): number {
|
||||
return this.issues?.filter((issue) => issue.state == state_id).length || 0;
|
||||
}
|
||||
|
||||
getFilteredIssuesByState(state_id: string): IIssue[] | [] {
|
||||
return this.issues?.filter((issue) => issue.state == state_id) || [];
|
||||
}
|
||||
|
||||
setActivePeekOverviewIssueId = (issueId: string | null) => (this.activePeekOverviewIssueId = issueId);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param key Is the key of the filter, i.e. state, label, priority
|
||||
* @param value Is the value of the filter, i.e. state_id, label_id, priority
|
||||
* @returns boolean
|
||||
*/
|
||||
|
||||
getUserSelectedFilter(key: "state" | "priority" | "label", value: string): boolean {
|
||||
if (key == "state") {
|
||||
return this.userSelectedStates.includes(value);
|
||||
} else if (key == "label") {
|
||||
return this.userSelectedLabels.includes(value);
|
||||
} else if (key == "priority") {
|
||||
return this.userSelectedPriorities.includes(value);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
checkIfFilterExistsForKey: (key: "state" | "priority" | "label") => boolean = (key) => {
|
||||
if (key == "state") {
|
||||
return this.userSelectedStates.length > 0;
|
||||
} else if (key == "label") {
|
||||
return this.userSelectedLabels.length > 0;
|
||||
} else if (key == "priority") {
|
||||
return this.userSelectedPriorities.length > 0;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
clearUserSelectedFilter(key: "state" | "priority" | "label" | "all") {
|
||||
if (key == "state") {
|
||||
this.userSelectedStates = [];
|
||||
} else if (key == "label") {
|
||||
this.userSelectedLabels = [];
|
||||
} else if (key == "priority") {
|
||||
this.userSelectedPriorities = [];
|
||||
} else if (key == "all") {
|
||||
this.userSelectedStates = [];
|
||||
this.userSelectedLabels = [];
|
||||
this.userSelectedPriorities = [];
|
||||
}
|
||||
}
|
||||
|
||||
getIfFiltersIsEmpty: () => boolean = () =>
|
||||
this.userSelectedStates.length === 0 &&
|
||||
this.userSelectedLabels.length === 0 &&
|
||||
this.userSelectedPriorities.length === 0;
|
||||
|
||||
getURLDefinition = (
|
||||
workspaceSlug: string,
|
||||
projectId: string,
|
||||
action?: {
|
||||
key: "state" | "priority" | "label" | "all";
|
||||
value?: string;
|
||||
removeAll?: boolean;
|
||||
}
|
||||
) => {
|
||||
let url = `/${workspaceSlug}/${projectId}?board=${this.currentIssueBoardView}`;
|
||||
|
||||
if (action) {
|
||||
if (action.key === "state")
|
||||
this.userSelectedStates = action.removeAll
|
||||
? []
|
||||
: [...this.userSelectedStates].filter((state) => state !== action.value);
|
||||
if (action.key === "label")
|
||||
this.userSelectedLabels = action.removeAll
|
||||
? []
|
||||
: [...this.userSelectedLabels].filter((label) => label !== action.value);
|
||||
if (action.key === "priority")
|
||||
this.userSelectedPriorities = action.removeAll
|
||||
? []
|
||||
: [...this.userSelectedPriorities].filter((priority) => priority !== action.value);
|
||||
if (action.key === "all") {
|
||||
this.userSelectedStates = [];
|
||||
this.userSelectedLabels = [];
|
||||
this.userSelectedPriorities = [];
|
||||
}
|
||||
}
|
||||
|
||||
if (this.checkIfFilterExistsForKey("state")) {
|
||||
url += `&states=${this.userSelectedStates.join(",")}`;
|
||||
}
|
||||
if (this.checkIfFilterExistsForKey("label")) {
|
||||
url += `&labels=${this.userSelectedLabels.join(",")}`;
|
||||
}
|
||||
if (this.checkIfFilterExistsForKey("priority")) {
|
||||
url += `&priorities=${this.userSelectedPriorities.join(",")}`;
|
||||
}
|
||||
|
||||
return url;
|
||||
};
|
||||
|
||||
// action
|
||||
setCurrentIssueBoardView = async (view: TIssueBoardKeys) => {
|
||||
this.currentIssueBoardView = view;
|
||||
};
|
||||
|
||||
fetchPublicIssues = async (workspaceSlug: string, projectId: string, params: any) => {
|
||||
try {
|
||||
this.loader = true;
|
||||
this.error = null;
|
||||
|
||||
const response = await this.issueService.getPublicIssues(workspaceSlug, projectId, params);
|
||||
|
||||
if (response) {
|
||||
const _states: IIssueState[] = [...response?.states];
|
||||
const _labels: IIssueLabel[] = [...response?.labels];
|
||||
const _issues: IIssue[] = [...response?.issues];
|
||||
runInAction(() => {
|
||||
this.states = _states;
|
||||
this.labels = _labels;
|
||||
this.issues = _issues;
|
||||
this.loader = false;
|
||||
});
|
||||
return response;
|
||||
}
|
||||
} catch (error) {
|
||||
this.loader = false;
|
||||
this.error = error;
|
||||
return error;
|
||||
}
|
||||
};
|
||||
|
||||
getIssueByIdAsync = async (workspaceSlug: string, projectId: string, issueId: string): Promise<IssueDetailType> => {
|
||||
try {
|
||||
const response = this.issues?.find((issue) => issue.id === issueId);
|
||||
|
||||
if (response) {
|
||||
const _issue_detail = {
|
||||
...this.issue_detail,
|
||||
[issueId]: {
|
||||
issue: response,
|
||||
comments: [],
|
||||
reactions: [],
|
||||
votes: [],
|
||||
},
|
||||
};
|
||||
runInAction(() => {
|
||||
this.issue_detail = _issue_detail;
|
||||
});
|
||||
|
||||
this.getIssueReactionsAsync(workspaceSlug, projectId, issueId);
|
||||
this.getIssueVotesAsync(workspaceSlug, projectId, issueId);
|
||||
this.getIssueCommentsAsync(workspaceSlug, projectId, issueId);
|
||||
}
|
||||
|
||||
return this.issue_detail[issueId] as any;
|
||||
} catch (error) {
|
||||
this.loader = false;
|
||||
this.error = error;
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
getIssueVotesAsync = async (workspaceSlug: string, projectId: string, issueId: string) => {
|
||||
try {
|
||||
const response = await this.issueService.getIssueVotes(workspaceSlug, projectId, issueId);
|
||||
|
||||
if (response) {
|
||||
const _issue_detail = {
|
||||
...this.issue_detail,
|
||||
[issueId]: {
|
||||
...this.issue_detail[issueId],
|
||||
votes: response,
|
||||
},
|
||||
};
|
||||
runInAction(() => {
|
||||
this.issue_detail = _issue_detail;
|
||||
});
|
||||
}
|
||||
|
||||
return response;
|
||||
} catch (error) {
|
||||
this.loader = false;
|
||||
this.error = error;
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
createIssueVoteAsync = async (
|
||||
workspaceSlug: string,
|
||||
projectId: string,
|
||||
issueId: string,
|
||||
data: {
|
||||
vote: 1 | -1;
|
||||
}
|
||||
) => {
|
||||
try {
|
||||
const response = await this.issueService.createIssueVote(workspaceSlug, projectId, issueId, data);
|
||||
|
||||
if (response) {
|
||||
const _issue_detail = {
|
||||
...this.issue_detail,
|
||||
[issueId]: {
|
||||
...this.issue_detail[issueId],
|
||||
votes: [
|
||||
...{ ...this.issue_detail }[issueId].votes.filter(
|
||||
(vote) => vote.actor !== this.rootStore?.user?.currentUser?.id
|
||||
),
|
||||
response,
|
||||
],
|
||||
},
|
||||
};
|
||||
runInAction(() => {
|
||||
this.issue_detail = _issue_detail;
|
||||
});
|
||||
}
|
||||
|
||||
return response;
|
||||
} catch (error) {
|
||||
this.loader = false;
|
||||
this.error = error;
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
deleteIssueVoteAsync = async (workspaceSlug: string, projectId: string, issueId: string) => {
|
||||
try {
|
||||
const _votes = (this.issue_detail[issueId].votes = this.issue_detail[issueId].votes.filter(
|
||||
(vote) => vote.actor !== this.rootStore?.user?.user?.id
|
||||
));
|
||||
|
||||
runInAction(() => {
|
||||
this.issue_detail[issueId].votes = _votes;
|
||||
});
|
||||
|
||||
const response = await this.issueService.deleteIssueVote(workspaceSlug, projectId, issueId);
|
||||
|
||||
const votesAfterCall = await this.issueService.getIssueVotes(workspaceSlug, projectId, issueId);
|
||||
|
||||
if (votesAfterCall)
|
||||
runInAction(() => {
|
||||
this.issue_detail[issueId].votes = votesAfterCall;
|
||||
});
|
||||
|
||||
return response;
|
||||
} catch (error) {
|
||||
this.loader = false;
|
||||
this.error = error;
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
getIssueReactionsAsync = async (workspaceSlug: string, projectId: string, issueId: string) => {
|
||||
try {
|
||||
const response = await this.issueService.getIssueReactions(workspaceSlug, projectId, issueId);
|
||||
|
||||
if (response) {
|
||||
const _issue_detail = {
|
||||
...this.issue_detail,
|
||||
[issueId]: {
|
||||
...this.issue_detail[issueId],
|
||||
reactions: response,
|
||||
},
|
||||
};
|
||||
runInAction(() => {
|
||||
this.issue_detail = _issue_detail;
|
||||
});
|
||||
}
|
||||
|
||||
return response;
|
||||
} catch (error) {
|
||||
this.loader = false;
|
||||
this.error = error;
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
createIssueReactionAsync = async (workspaceSlug: string, projectId: string, issueId: string, data: any) => {
|
||||
try {
|
||||
const response = await this.issueService.createIssueReaction(workspaceSlug, projectId, issueId, data);
|
||||
|
||||
if (response) {
|
||||
const _issue_detail = {
|
||||
...this.issue_detail,
|
||||
[issueId]: {
|
||||
...this.issue_detail[issueId],
|
||||
reactions: [...this.issue_detail[issueId].reactions, response],
|
||||
},
|
||||
};
|
||||
runInAction(() => {
|
||||
this.issue_detail = _issue_detail;
|
||||
});
|
||||
}
|
||||
|
||||
return response;
|
||||
} catch (error) {
|
||||
this.loader = false;
|
||||
this.error = error;
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
deleteIssueReactionAsync = async (workspaceSlug: string, projectId: string, issueId: string, reactionHex: string) => {
|
||||
try {
|
||||
const newReactionsList = this.issue_detail[issueId].reactions.filter(
|
||||
(reaction) => reaction.reaction !== reactionHex
|
||||
);
|
||||
|
||||
const _issue_detail = {
|
||||
...this.issue_detail,
|
||||
[issueId]: {
|
||||
...this.issue_detail[issueId],
|
||||
reactions: newReactionsList,
|
||||
},
|
||||
};
|
||||
|
||||
runInAction(() => {
|
||||
this.issue_detail = _issue_detail;
|
||||
});
|
||||
|
||||
const response = await this.issueService.deleteIssueReaction(workspaceSlug, projectId, issueId, reactionHex);
|
||||
|
||||
const reactionsAfterCall = await this.issueService.getIssueReactions(workspaceSlug, projectId, issueId);
|
||||
|
||||
if (reactionsAfterCall) {
|
||||
const _issue_detail = {
|
||||
...this.issue_detail,
|
||||
[issueId]: {
|
||||
...this.issue_detail[issueId],
|
||||
reactions: reactionsAfterCall,
|
||||
},
|
||||
};
|
||||
runInAction(() => {
|
||||
this.issue_detail = _issue_detail;
|
||||
});
|
||||
}
|
||||
|
||||
return response;
|
||||
} catch (error) {
|
||||
this.loader = false;
|
||||
this.error = error;
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
getIssueCommentsAsync = async (workspaceSlug: string, projectId: string, issueId: string) => {
|
||||
try {
|
||||
const response = await this.issueService.getIssueComments(workspaceSlug, projectId, issueId);
|
||||
|
||||
if (response) {
|
||||
const _issue_detail = {
|
||||
...this.issue_detail,
|
||||
[issueId]: {
|
||||
...this.issue_detail[issueId],
|
||||
comments: response,
|
||||
},
|
||||
};
|
||||
runInAction(() => {
|
||||
this.issue_detail = _issue_detail;
|
||||
});
|
||||
}
|
||||
|
||||
return response;
|
||||
} catch (error) {
|
||||
this.loader = false;
|
||||
this.error = error;
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
createIssueCommentAsync = async (workspaceSlug: string, projectId: string, issueId: string, data: any) => {
|
||||
try {
|
||||
const response = await this.issueService.createIssueComment(workspaceSlug, projectId, issueId, data);
|
||||
|
||||
if (response) {
|
||||
const _issue_detail = {
|
||||
...this.issue_detail,
|
||||
[issueId]: {
|
||||
...this.issue_detail[issueId],
|
||||
comments: [...this.issue_detail[issueId].comments, response],
|
||||
},
|
||||
};
|
||||
runInAction(() => {
|
||||
this.issue_detail = _issue_detail;
|
||||
});
|
||||
}
|
||||
|
||||
return response;
|
||||
} catch (error) {
|
||||
this.loader = false;
|
||||
this.error = error;
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
updateIssueCommentAsync = async (
|
||||
workspaceSlug: string,
|
||||
projectId: string,
|
||||
issueId: string,
|
||||
commentId: string,
|
||||
data: any
|
||||
) => {
|
||||
try {
|
||||
const response = await this.issueService.updateIssueComment(workspaceSlug, projectId, issueId, commentId, data);
|
||||
|
||||
if (response) {
|
||||
const _issue_detail = {
|
||||
...this.issue_detail,
|
||||
[issueId]: {
|
||||
...this.issue_detail[issueId],
|
||||
comments: [
|
||||
...this.issue_detail[issueId].comments.filter((comment) => comment.id !== response.id),
|
||||
response,
|
||||
],
|
||||
},
|
||||
};
|
||||
runInAction(() => {
|
||||
this.issue_detail = _issue_detail;
|
||||
});
|
||||
}
|
||||
|
||||
return response;
|
||||
} catch (error) {
|
||||
this.loader = false;
|
||||
this.error = error;
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
deleteIssueCommentAsync = async (workspaceSlug: string, projectId: string, issueId: string, commentId: string) => {
|
||||
try {
|
||||
const newCommentsList = this.issue_detail[issueId].comments.filter((comment) => comment.id !== commentId);
|
||||
|
||||
const _issue_detail = {
|
||||
...this.issue_detail,
|
||||
[issueId]: {
|
||||
...this.issue_detail[issueId],
|
||||
comments: newCommentsList,
|
||||
},
|
||||
};
|
||||
|
||||
runInAction(() => {
|
||||
this.issue_detail = _issue_detail;
|
||||
});
|
||||
|
||||
const response = await this.issueService.deleteIssueComment(workspaceSlug, projectId, issueId, commentId);
|
||||
|
||||
const commentsAfterCall = await this.issueService.getIssueComments(workspaceSlug, projectId, issueId);
|
||||
|
||||
if (commentsAfterCall) {
|
||||
const _issue_detail = {
|
||||
...this.issue_detail,
|
||||
[issueId]: {
|
||||
...this.issue_detail[issueId],
|
||||
comments: commentsAfterCall,
|
||||
},
|
||||
};
|
||||
runInAction(() => {
|
||||
this.issue_detail = _issue_detail;
|
||||
});
|
||||
}
|
||||
|
||||
return response;
|
||||
} catch (error) {
|
||||
this.loader = false;
|
||||
this.error = error;
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export default IssueLegacyStore;
|
@ -3,7 +3,7 @@ import { observable, action, makeObservable, runInAction } from "mobx";
|
||||
// service
|
||||
import ProjectService from "services/project.service";
|
||||
// types
|
||||
import { IWorkspace, IProject, IProjectSettings } from "./types";
|
||||
import { IWorkspace, IProject, IProjectSettings } from "../types";
|
||||
|
||||
export interface IProjectStore {
|
||||
loader: boolean;
|
||||
|
@ -6,7 +6,7 @@ import ThemeStore from "./theme";
|
||||
import IssueStore, { IIssueStore } from "./issue";
|
||||
import ProjectStore, { IProjectStore } from "./project";
|
||||
// types
|
||||
import { IThemeStore } from "./types";
|
||||
import { IThemeStore } from "../types";
|
||||
|
||||
enableStaticRendering(typeof window === "undefined");
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
// mobx
|
||||
import { observable, action, computed, makeObservable, runInAction } from "mobx";
|
||||
// types
|
||||
import { IThemeStore } from "./types";
|
||||
import { IThemeStore } from "../types";
|
||||
|
||||
class ThemeStore implements IThemeStore {
|
||||
theme: "light" | "dark" = "light";
|
||||
|
@ -3,7 +3,7 @@ import { observable, action, computed, makeObservable, runInAction } from "mobx"
|
||||
// service
|
||||
import UserService from "services/user.service";
|
||||
// types
|
||||
import { IUserStore } from "./types";
|
||||
import { IUserStore } from "../types";
|
||||
|
||||
class UserStore implements IUserStore {
|
||||
currentUser: any | null = null;
|
||||
|
Loading…
Reference in New Issue
Block a user