- {group_by && group_by === "state" && (
-
- )}
+ const { project: projectStore, issueKanBanView: issueKanBanViewStore }: RootStore = useMobxStore();
- {group_by && group_by === "state_detail.group" && (
-
- )}
+ return (
+
+ {group_by && group_by === "state" && (
+
+ )}
- {group_by && group_by === "priority" && (
-
- )}
+ {group_by && group_by === "state_detail.group" && (
+
+ )}
- {group_by && group_by === "labels" && (
-
- )}
+ {group_by && group_by === "priority" && (
+
+ )}
- {group_by && group_by === "assignees" && (
-
- )}
+ {group_by && group_by === "labels" && (
+
+ )}
- {group_by && group_by === "created_by" && (
-
- )}
-
- );
- }
-);
+ {group_by && group_by === "assignees" && (
+
+ )}
+
+ {group_by && group_by === "created_by" && (
+
+ )}
+
+ );
+});
diff --git a/web/components/issues/issue-layouts/kanban/module-root.tsx b/web/components/issues/issue-layouts/kanban/module-root.tsx
index 5bdc09706..9e42bfe05 100644
--- a/web/components/issues/issue-layouts/kanban/module-root.tsx
+++ b/web/components/issues/issue-layouts/kanban/module-root.tsx
@@ -9,11 +9,14 @@ import { KanBan } from "./default";
// store
import { useMobxStore } from "lib/mobx/store-provider";
import { RootStore } from "store/root";
+// constants
+import { ISSUE_STATE_GROUPS, ISSUE_PRIORITIES } from "constants/issue";
export interface IModuleKanBanLayout {}
export const ModuleKanBanLayout: React.FC = observer(() => {
const {
+ project: projectStore,
moduleIssue: moduleIssueStore,
issueFilter: issueFilterStore,
moduleIssueKanBanView: moduleIssueKanBanViewStore,
@@ -55,6 +58,14 @@ export const ModuleKanBanLayout: React.FC = observer(() => {
moduleIssueKanBanViewStore.handleKanBanToggle(toggle, value);
};
+ const states = projectStore?.projectStates || null;
+ const priorities = ISSUE_PRIORITIES || null;
+ const labels = projectStore?.projectLabels || null;
+ const members = projectStore?.projectMembers || null;
+ const stateGroups = ISSUE_STATE_GROUPS || null;
+ const projects = projectStore?.projectStates || null;
+ const estimates = null;
+
return (
@@ -67,6 +78,13 @@ export const ModuleKanBanLayout: React.FC = observer(() => {
display_properties={display_properties}
kanBanToggle={moduleIssueKanBanViewStore?.kanBanToggle}
handleKanBanToggle={handleKanBanToggle}
+ states={states}
+ stateGroups={stateGroups}
+ priorities={priorities}
+ labels={labels}
+ members={members}
+ projects={projects}
+ estimates={estimates}
/>
) : (
{
display_properties={display_properties}
kanBanToggle={moduleIssueKanBanViewStore?.kanBanToggle}
handleKanBanToggle={handleKanBanToggle}
+ states={states}
+ stateGroups={stateGroups}
+ priorities={priorities}
+ labels={labels}
+ members={members}
+ projects={projects}
+ estimates={estimates}
/>
)}
diff --git a/web/components/issues/issue-layouts/kanban/profile-issues-root.tsx b/web/components/issues/issue-layouts/kanban/profile-issues-root.tsx
index 3efebfd8e..68089c78f 100644
--- a/web/components/issues/issue-layouts/kanban/profile-issues-root.tsx
+++ b/web/components/issues/issue-layouts/kanban/profile-issues-root.tsx
@@ -1,5 +1,4 @@
-import React from "react";
-// react beautiful dnd
+import { FC } from "react";
import { DragDropContext } from "@hello-pangea/dnd";
// mobx
import { observer } from "mobx-react-lite";
@@ -9,11 +8,15 @@ import { KanBan } from "./default";
// store
import { useMobxStore } from "lib/mobx/store-provider";
import { RootStore } from "store/root";
+// constants
+import { ISSUE_STATE_GROUPS, ISSUE_PRIORITIES } from "constants/issue";
export interface IProfileIssuesKanBanLayout {}
-export const ProfileIssuesKanBanLayout: React.FC = observer(() => {
+export const ProfileIssuesKanBanLayout: FC = observer(() => {
const {
+ workspace: workspaceStore,
+ project: projectStore,
profileIssues: profileIssuesStore,
profileIssueFilters: profileIssueFiltersStore,
issueKanBanView: issueKanBanViewStore,
@@ -55,6 +58,14 @@ export const ProfileIssuesKanBanLayout: React.FC = observer(() => {
issueKanBanViewStore.handleKanBanToggle(toggle, value);
};
+ const states = projectStore?.projectStates || null;
+ const priorities = ISSUE_PRIORITIES || null;
+ const labels = workspaceStore.workspaceLabels || null;
+ const members = projectStore?.projectMembers || null;
+ const stateGroups = ISSUE_STATE_GROUPS || null;
+ const projects = projectStore?.workspaceProjects || null;
+ const estimates = null;
+
return (
@@ -67,6 +78,13 @@ export const ProfileIssuesKanBanLayout: React.FC = observer(() => {
display_properties={display_properties}
kanBanToggle={issueKanBanViewStore?.kanBanToggle}
handleKanBanToggle={handleKanBanToggle}
+ states={states}
+ stateGroups={stateGroups}
+ priorities={priorities}
+ labels={labels}
+ members={members}
+ projects={projects}
+ estimates={estimates}
/>
) : (
{
display_properties={display_properties}
kanBanToggle={issueKanBanViewStore?.kanBanToggle}
handleKanBanToggle={handleKanBanToggle}
+ states={states}
+ stateGroups={stateGroups}
+ priorities={priorities}
+ labels={labels}
+ members={members}
+ projects={projects}
+ estimates={estimates}
/>
)}
diff --git a/web/components/issues/issue-layouts/kanban/root.tsx b/web/components/issues/issue-layouts/kanban/root.tsx
index d3aa148f8..d6d4e1625 100644
--- a/web/components/issues/issue-layouts/kanban/root.tsx
+++ b/web/components/issues/issue-layouts/kanban/root.tsx
@@ -76,13 +76,13 @@ export const KanBanLayout: FC = observer(() => {
display_properties={display_properties}
kanBanToggle={issueKanBanViewStore?.kanBanToggle}
handleKanBanToggle={handleKanBanToggle}
- // states={states}
- // stateGroups={stateGroups}
- // priorities={priorities}
- // labels={labels}
- // members={members}
- // projects={projects}
- // estimates={estimates}
+ states={states}
+ stateGroups={stateGroups}
+ priorities={priorities}
+ labels={labels}
+ members={members}
+ projects={projects}
+ estimates={estimates}
/>
) : (
{
display_properties={display_properties}
kanBanToggle={issueKanBanViewStore?.kanBanToggle}
handleKanBanToggle={handleKanBanToggle}
- // states={states}
- // stateGroups={stateGroups}
- // priorities={priorities}
- // labels={labels}
- // members={members}
- // projects={projects}
- // estimates={estimates}
+ states={states}
+ stateGroups={stateGroups}
+ priorities={priorities}
+ labels={labels}
+ members={members}
+ projects={projects}
+ estimates={estimates}
/>
)}
diff --git a/web/components/issues/issue-layouts/kanban/swimlanes.tsx b/web/components/issues/issue-layouts/kanban/swimlanes.tsx
index baf8b36b2..161b53ecb 100644
--- a/web/components/issues/issue-layouts/kanban/swimlanes.tsx
+++ b/web/components/issues/issue-layouts/kanban/swimlanes.tsx
@@ -64,9 +64,16 @@ interface ISubGroupSwimlane extends ISubGroupSwimlaneHeader {
display_properties: any;
kanBanToggle: any;
handleKanBanToggle: any;
+ states: any;
+ stateGroups: any;
+ priorities: any;
+ labels: any;
+ members: any;
+ projects: any;
+ estimates: any;
}
-const SubGroupSwimlane: React.FC = observer(
- ({
+const SubGroupSwimlane: React.FC = observer((props) => {
+ const {
issues,
sub_group_by,
group_by,
@@ -76,55 +83,69 @@ const SubGroupSwimlane: React.FC = observer(
display_properties,
kanBanToggle,
handleKanBanToggle,
- }) => {
- const calculateIssueCount = (column_id: string) => {
- let issueCount = 0;
- issues?.[column_id] &&
- Object.keys(issues?.[column_id])?.forEach((_list: any) => {
- issueCount += issues?.[column_id]?.[_list]?.length || 0;
- });
- return issueCount;
- };
+ states,
+ stateGroups,
+ priorities,
+ labels,
+ members,
+ projects,
+ estimates,
+ } = props;
- return (
-
- {list &&
- list.length > 0 &&
- list.map((_list: any) => (
-
-
-
-
-
-
+ const calculateIssueCount = (column_id: string) => {
+ let issueCount = 0;
+ issues?.[column_id] &&
+ Object.keys(issues?.[column_id])?.forEach((_list: any) => {
+ issueCount += issues?.[column_id]?.[_list]?.length || 0;
+ });
+ return issueCount;
+ };
+
+ return (
+
+ {list &&
+ list.length > 0 &&
+ list.map((_list: any) => (
+
+
+
+
- {!kanBanToggle?.subgroupByIssuesVisibility.includes(getValueFromObject(_list, listKey) as string) && (
-
-
-
- )}
+
- ))}
-
- );
- }
-);
+ {!kanBanToggle?.subgroupByIssuesVisibility.includes(getValueFromObject(_list, listKey) as string) && (
+
+
+
+ )}
+
+ ))}
+
+ );
+});
export interface IKanBanSwimLanes {
issues: any;
@@ -134,172 +155,236 @@ export interface IKanBanSwimLanes {
display_properties: any;
kanBanToggle: any;
handleKanBanToggle: any;
+ states: any;
+ stateGroups: any;
+ priorities: any;
+ labels: any;
+ members: any;
+ projects: any;
+ estimates: any;
}
-export const KanBanSwimLanes: React.FC
= observer(
- ({ issues, sub_group_by, group_by, handleIssues, display_properties, kanBanToggle, handleKanBanToggle }) => {
- const { project: projectStore }: RootStore = useMobxStore();
+export const KanBanSwimLanes: React.FC = observer((props) => {
+ const {
+ issues,
+ sub_group_by,
+ group_by,
+ handleIssues,
+ display_properties,
+ kanBanToggle,
+ handleKanBanToggle,
+ states,
+ stateGroups,
+ priorities,
+ labels,
+ members,
+ projects,
+ estimates,
+ } = props;
- return (
-
-
- {group_by && group_by === "state" && (
-
- )}
+ const { project: projectStore }: RootStore = useMobxStore();
- {group_by && group_by === "state_detail.group" && (
-
- )}
-
- {group_by && group_by === "priority" && (
-
- )}
-
- {group_by && group_by === "labels" && (
-
- )}
-
- {group_by && group_by === "assignees" && (
-
- )}
-
- {group_by && group_by === "created_by" && (
-
- )}
-
-
- {sub_group_by && sub_group_by === "state" && (
-
+
+ {group_by && group_by === "state" && (
+
)}
- {sub_group_by && sub_group_by === "state_detail.group" && (
-
)}
- {sub_group_by && sub_group_by === "priority" && (
-
)}
- {sub_group_by && sub_group_by === "labels" && (
-
)}
- {sub_group_by && sub_group_by === "assignees" && (
-
)}
- {sub_group_by && sub_group_by === "created_by" && (
-
)}
- );
- }
-);
+
+ {sub_group_by && sub_group_by === "state" && (
+
+ )}
+
+ {sub_group_by && sub_group_by === "state_detail.group" && (
+
+ )}
+
+ {sub_group_by && sub_group_by === "priority" && (
+
+ )}
+
+ {sub_group_by && sub_group_by === "labels" && (
+
+ )}
+
+ {sub_group_by && sub_group_by === "assignees" && (
+
+ )}
+
+ {sub_group_by && sub_group_by === "created_by" && (
+
+ )}
+
+ );
+});
diff --git a/web/components/issues/issue-layouts/kanban/view-root.tsx b/web/components/issues/issue-layouts/kanban/view-root.tsx
index 0f5e690d0..bdc10f1a1 100644
--- a/web/components/issues/issue-layouts/kanban/view-root.tsx
+++ b/web/components/issues/issue-layouts/kanban/view-root.tsx
@@ -9,11 +9,14 @@ import { KanBan } from "./default";
// store
import { useMobxStore } from "lib/mobx/store-provider";
import { RootStore } from "store/root";
+// constants
+import { ISSUE_STATE_GROUPS, ISSUE_PRIORITIES } from "constants/issue";
export interface IViewKanBanLayout {}
export const ViewKanBanLayout: React.FC = observer(() => {
const {
+ project: projectStore,
issue: issueStore,
issueFilter: issueFilterStore,
issueKanBanView: issueKanBanViewStore,
@@ -51,6 +54,14 @@ export const ViewKanBanLayout: React.FC = observer(() => {
issueStore.updateIssueStructure(group_by, sub_group_by, issue);
};
+ const states = projectStore?.projectStates || null;
+ const priorities = ISSUE_PRIORITIES || null;
+ const labels = projectStore?.projectLabels || null;
+ const members = projectStore?.projectMembers || null;
+ const stateGroups = ISSUE_STATE_GROUPS || null;
+ const projects = projectStore?.projectStates || null;
+ const estimates = null;
+
return (
@@ -63,6 +74,13 @@ export const ViewKanBanLayout: React.FC = observer(() => {
display_properties={display_properties}
kanBanToggle={() => {}}
handleKanBanToggle={() => {}}
+ states={states}
+ stateGroups={stateGroups}
+ priorities={priorities}
+ labels={labels}
+ members={members}
+ projects={projects}
+ estimates={estimates}
/>
) : (
{
display_properties={display_properties}
kanBanToggle={() => {}}
handleKanBanToggle={() => {}}
+ states={states}
+ stateGroups={stateGroups}
+ priorities={priorities}
+ labels={labels}
+ members={members}
+ projects={projects}
+ estimates={estimates}
/>
)}
diff --git a/web/components/issues/issue-layouts/list/block.tsx b/web/components/issues/issue-layouts/list/block.tsx
index 8c5cbb473..a542f5983 100644
--- a/web/components/issues/issue-layouts/list/block.tsx
+++ b/web/components/issues/issue-layouts/list/block.tsx
@@ -1,6 +1,7 @@
import { FC } from "react";
// components
import { KanBanProperties } from "./properties";
+import { IssuePeekOverview } from "components/issues/issue-peek-overview";
// ui
import { Tooltip } from "@plane/ui";
@@ -18,6 +19,10 @@ interface IssueBlockProps {
export const IssueBlock: FC
= (props) => {
const { columnId, issues, handleIssues, display_properties, states, labels, members, priorities } = props;
+ const handleIssue = (_issue: any) => {
+ if (_issue && handleIssues) handleIssues(!columnId && columnId === "null" ? null : columnId, _issue);
+ };
+
return (
<>
{issues &&
@@ -25,14 +30,25 @@ export const IssueBlock: FC = (props) => {
issues.map((issue: any, index: any) => (
{display_properties && display_properties?.key && (
-
ONE-{issue.sequence_id}
+
+ {issue?.project_detail?.identifier}-{issue.sequence_id}
+
)}
-
- {issue.name}
-
+
+
+
+ {issue.name}
+
+
+
) => void;
+}
+
+export const PeekOverviewIssueDetails: FC = (props) => {
+ const { workspaceSlug, issue, issueUpdate } = props;
+
+ const debouncedIssueDescription = useDebouncedCallback(async (_data: any) => {
+ issueUpdate({ ...issue, description_html: _data });
+ }, 1500);
+
+ return (
+
+
+ {issue?.project_detail?.identifier}-{issue?.sequence_id}
+
+
+
{issue?.name}
+
+
{
+ debouncedIssueDescription(description_html);
+ }}
+ />
+
+ );
+};
diff --git a/web/components/issues/issue-peek-overview/properties.tsx b/web/components/issues/issue-peek-overview/properties.tsx
new file mode 100644
index 000000000..f24a58302
--- /dev/null
+++ b/web/components/issues/issue-peek-overview/properties.tsx
@@ -0,0 +1,141 @@
+import { FC } from "react";
+// ui icons
+import { DoubleCircleIcon, UserGroupIcon } from "@plane/ui";
+import { CalendarDays, Signal } from "lucide-react";
+// components
+import { IssuePropertyState } from "components/issues/issue-layouts/properties/state";
+import { IssuePropertyPriority } from "components/issues/issue-layouts/properties/priority";
+import { IssuePropertyAssignee } from "components/issues/issue-layouts/properties/assignee";
+import { IssuePropertyDate } from "components/issues/issue-layouts/properties/date";
+// types
+import { IIssue } from "types";
+
+interface IPeekOverviewProperties {
+ issue: IIssue;
+ issueUpdate: (issue: Partial) => void;
+
+ states: any;
+ members: any;
+ priorities: any;
+}
+
+export const PeekOverviewProperties: FC = (props) => {
+ const { issue, issueUpdate, states, members, priorities } = props;
+
+ const handleState = (_state: string) => {
+ if (issueUpdate) issueUpdate({ ...issue, state: _state });
+ };
+
+ const handlePriority = (_priority: any) => {
+ if (issueUpdate) issueUpdate({ ...issue, priority: _priority });
+ };
+
+ const handleAssignee = (_assignees: string[]) => {
+ if (issueUpdate) issueUpdate({ ...issue, assignees: _assignees });
+ };
+
+ const handleStartDate = (_startDate: string) => {
+ if (issueUpdate) issueUpdate({ ...issue, start_date: _startDate });
+ };
+
+ const handleTargetDate = (_targetDate: string) => {
+ if (issueUpdate) issueUpdate({ ...issue, target_date: _targetDate });
+ };
+
+ return (
+
+ {/* state */}
+
+
+
+ handleState(id)}
+ disabled={false}
+ list={states}
+ />
+
+
+
+ {/* assignees */}
+
+
+
+ handleAssignee(ids)}
+ disabled={false}
+ list={members}
+ />
+
+
+
+ {/* priority */}
+
+
+
+ handlePriority(id)}
+ disabled={false}
+ list={priorities}
+ />
+
+
+
+ {/* start_date */}
+
+
+
+ handleStartDate(date)}
+ disabled={false}
+ placeHolder={`Start date`}
+ />
+
+
+
+ {/* target_date */}
+
+
+
+ handleTargetDate(date)}
+ disabled={false}
+ placeHolder={`Target date`}
+ />
+
+
+
+ );
+};
diff --git a/web/components/issues/issue-peek-overview/root.tsx b/web/components/issues/issue-peek-overview/root.tsx
new file mode 100644
index 000000000..c8ab92bdb
--- /dev/null
+++ b/web/components/issues/issue-peek-overview/root.tsx
@@ -0,0 +1,50 @@
+import { FC, ReactNode } from "react";
+import { observer } from "mobx-react-lite";
+// components
+import { IssueView } from "./view";
+// hooks
+import { useMobxStore } from "lib/mobx/store-provider";
+// types
+import { IIssue } from "types";
+import { RootStore } from "store/root";
+// constants
+import { ISSUE_PRIORITIES } from "constants/issue";
+
+interface IIssuePeekOverview {
+ workspaceSlug: string;
+ projectId: string;
+ issueId: string;
+ handleIssue: (issue: Partial) => void;
+ children: ReactNode;
+}
+
+export const IssuePeekOverview: FC = observer((props) => {
+ const { workspaceSlug, projectId, issueId, handleIssue, children } = props;
+
+ const { project: projectStore, issueDetail: issueDetailStore }: RootStore = useMobxStore();
+
+ const states = projectStore?.projectStates || undefined;
+ const members = projectStore?.projectMembers || undefined;
+ const priorities = ISSUE_PRIORITIES || undefined;
+
+ const issueUpdate = (_data: Partial) => {
+ if (handleIssue) {
+ handleIssue(_data);
+ issueDetailStore.updateIssue(workspaceSlug, projectId, issueId, _data, undefined);
+ }
+ };
+
+ return (
+
+ {children}
+
+ );
+});
diff --git a/web/components/issues/issue-peek-overview/view.tsx b/web/components/issues/issue-peek-overview/view.tsx
new file mode 100644
index 000000000..d3974a56b
--- /dev/null
+++ b/web/components/issues/issue-peek-overview/view.tsx
@@ -0,0 +1,206 @@
+import { FC, ReactNode, useEffect, useState } from "react";
+import { useRouter } from "next/router";
+import { Maximize2, ArrowRight, Link, Trash, PanelRightOpen, Square, SquareCode } from "lucide-react";
+import { observer } from "mobx-react-lite";
+// components
+import { PeekOverviewIssueDetails } from "./issue-detail";
+import { PeekOverviewProperties } from "./properties";
+// types
+import { IIssue } from "types";
+import { RootStore } from "store/root";
+// hooks
+import { useMobxStore } from "lib/mobx/store-provider";
+
+interface IIssueView {
+ workspaceSlug: string;
+ projectId: string;
+ issueId: string;
+ issueUpdate: (issue: Partial) => void;
+ states: any;
+ members: any;
+ priorities: any;
+ children: ReactNode;
+}
+
+type TPeekModes = "side-peek" | "modal" | "full-screen";
+
+const peekOptions: { key: TPeekModes; icon: any; title: string }[] = [
+ {
+ key: "side-peek",
+ icon: PanelRightOpen,
+ title: "Side Peek",
+ },
+ {
+ key: "modal",
+ icon: Square,
+ title: "Modal",
+ },
+ {
+ key: "full-screen",
+ icon: SquareCode,
+ title: "Full Screen",
+ },
+];
+
+export const IssueView: FC = observer((props) => {
+ const { workspaceSlug, projectId, issueId, issueUpdate, states, members, priorities, children } = props;
+
+ const router = useRouter();
+ const { peekIssueId } = router.query as { peekIssueId: string };
+
+ const { issueDetail: issueDetailStore }: RootStore = useMobxStore();
+
+ const [peekMode, setPeekMode] = useState("side-peek");
+ const handlePeekMode = (_peek: TPeekModes) => {
+ if (peekMode != _peek) setPeekMode(_peek);
+ };
+
+ const updateRoutePeekId = () => {
+ if (issueId != peekIssueId) {
+ const { query } = router;
+ router.push({
+ pathname: router.pathname,
+ query: { ...query, peekIssueId: issueId },
+ });
+ }
+ };
+ const removeRoutePeekId = () => {
+ const { query } = router;
+ if (query.peekIssueId) {
+ delete query.peekIssueId;
+ router.push({
+ pathname: router.pathname,
+ query: { ...query },
+ });
+ }
+ };
+
+ const redirectToIssueDetail = () => {
+ router.push({
+ pathname: `/${workspaceSlug}/projects/${projectId}/issues/${issueId}`,
+ });
+ };
+
+ useEffect(() => {
+ if (workspaceSlug && projectId && issueId && peekIssueId && issueId === peekIssueId)
+ issueDetailStore.fetchIssueDetails(workspaceSlug, projectId, issueId);
+ }, [workspaceSlug, projectId, issueId, peekIssueId, issueDetailStore]);
+
+ const issue = issueDetailStore.getIssue;
+
+ return (
+
+
+ {children}
+
+
+ {issueId === peekIssueId && (
+
+ {/* header */}
+
+
+
+
+
+
+
+
+ {peekOptions.map((_option) => (
+
handlePeekMode(_option?.key)}
+ >
+ <_option.icon width={14} strokeWidth={2} />
+
{_option?.title}
+
+ ))}
+
+
+
+
+ Subscribe
+
+
+
+
+
+
+
+
+
+
+
+
+ {/* content */}
+
+ {issueDetailStore?.loader && !issue ? (
+
Loading...
+ ) : (
+ issue && (
+ <>
+ {["side-peek", "modal"].includes(peekMode) ? (
+
+
+
+ {/* reactions */}
+
+
+
+ {/* activity */}
+
+ ) : (
+
+
+
+
+ {/* reactions */}
+
+ {/* activity */}
+
+
+
+ )}
+ >
+ )
+ )}
+
+
+ )}
+
+ );
+});
diff --git a/web/store/issue/issue_detail.store.ts b/web/store/issue/issue_detail.store.ts
index a88f9f14b..a1886012d 100644
--- a/web/store/issue/issue_detail.store.ts
+++ b/web/store/issue/issue_detail.store.ts
@@ -1,4 +1,4 @@
-import { observable, action, makeObservable, runInAction } from "mobx";
+import { observable, action, makeObservable, runInAction, computed } from "mobx";
// services
import { IssueService } from "services/issue";
// types
@@ -20,12 +20,22 @@ export interface IIssueDetailStore {
setPeekId: (issueId: string | null) => void;
setPeekMode: (issueId: IPeekMode | null) => void;
+
+ // computed
+ getIssue: IIssue | null;
+
// fetch issue details
fetchIssueDetails: (workspaceSlug: string, projectId: string, issueId: string) => void;
// creating issue
createIssue: (workspaceSlug: string, projectId: string, data: Partial, user: IUser) => void;
// updating issue
- updateIssue: (workspaceSlug: string, projectId: string, issueId: string, data: Partial, user: IUser) => void;
+ updateIssue: (
+ workspaceId: string,
+ projectId: string,
+ issueId: string,
+ data: Partial,
+ user: IUser | undefined
+ ) => void;
// deleting issue
deleteIssue: (workspaceSlug: string, projectId: string, issueId: string, user: IUser) => void;
}
@@ -57,6 +67,8 @@ export class IssueDetailStore implements IIssueDetailStore {
issues: observable.ref,
+ getIssue: computed,
+
setPeekId: action,
setPeekMode: action,
@@ -70,6 +82,12 @@ export class IssueDetailStore implements IIssueDetailStore {
this.issueService = new IssueService();
}
+ get getIssue() {
+ if (!this.peekId) return null;
+ const _issue = this.issues[this.peekId];
+ return _issue || null;
+ }
+
setPeekId = (issueId: string | null) => (this.peekId = issueId);
setPeekMode = (mode: IPeekMode | null) => (this.peekMode = mode);
@@ -78,6 +96,7 @@ export class IssueDetailStore implements IIssueDetailStore {
try {
this.loader = true;
this.error = null;
+ this.peekId = issueId;
const issueDetailsResponse = await this.issueService.retrieve(workspaceSlug, projectId, issueId);