forked from github/plane
chore: issue action added and code refactor
This commit is contained in:
parent
3b8a8cdfa4
commit
06722408b8
@ -20,6 +20,7 @@ import {
|
|||||||
// hooks
|
// hooks
|
||||||
import useSpreadsheetIssuesView from "hooks/use-spreadsheet-issues-view";
|
import useSpreadsheetIssuesView from "hooks/use-spreadsheet-issues-view";
|
||||||
import useToast from "hooks/use-toast";
|
import useToast from "hooks/use-toast";
|
||||||
|
import useWorkspaceIssuesFilters from "hooks/use-worskpace-issue-filter";
|
||||||
// services
|
// services
|
||||||
import issuesService from "services/issues.service";
|
import issuesService from "services/issues.service";
|
||||||
import trackEventServices from "services/track-event.service";
|
import trackEventServices from "services/track-event.service";
|
||||||
@ -32,6 +33,7 @@ import {
|
|||||||
PROJECT_ISSUES_LIST_WITH_PARAMS,
|
PROJECT_ISSUES_LIST_WITH_PARAMS,
|
||||||
SUB_ISSUES,
|
SUB_ISSUES,
|
||||||
VIEW_ISSUES,
|
VIEW_ISSUES,
|
||||||
|
WORKSPACE_VIEW_ISSUES,
|
||||||
} from "constants/fetch-keys";
|
} from "constants/fetch-keys";
|
||||||
// types
|
// types
|
||||||
import {
|
import {
|
||||||
@ -82,12 +84,51 @@ export const SingleSpreadsheetIssue: React.FC<Props> = ({
|
|||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
const { workspaceSlug, cycleId, moduleId, viewId } = router.query;
|
const { workspaceSlug, cycleId, moduleId, viewId, workspaceViewId } = router.query;
|
||||||
|
|
||||||
const { params } = useSpreadsheetIssuesView();
|
const { params } = useSpreadsheetIssuesView();
|
||||||
|
|
||||||
const { setToastAlert } = useToast();
|
const { setToastAlert } = useToast();
|
||||||
|
|
||||||
|
const workspaceIssuesPath = [
|
||||||
|
{
|
||||||
|
params: {
|
||||||
|
sub_issue: false,
|
||||||
|
},
|
||||||
|
path: "workspace-views/all-issues",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
params: {
|
||||||
|
assignees: user?.id ?? undefined,
|
||||||
|
sub_issue: false,
|
||||||
|
},
|
||||||
|
path: "workspace-views/assigned",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
params: {
|
||||||
|
created_by: user?.id ?? undefined,
|
||||||
|
sub_issue: false,
|
||||||
|
},
|
||||||
|
path: "workspace-views/created",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
params: {
|
||||||
|
subscriber: user?.id ?? undefined,
|
||||||
|
sub_issue: false,
|
||||||
|
},
|
||||||
|
path: "workspace-views/subscribed",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const currentWorkspaceIssuePath = workspaceIssuesPath.find((path) =>
|
||||||
|
router.pathname.includes(path.path)
|
||||||
|
);
|
||||||
|
|
||||||
|
const { params: workspaceViewParams } = useWorkspaceIssuesFilters(
|
||||||
|
workspaceSlug?.toString(),
|
||||||
|
workspaceViewId?.toString()
|
||||||
|
);
|
||||||
|
|
||||||
const partialUpdateIssue = useCallback(
|
const partialUpdateIssue = useCallback(
|
||||||
(formData: Partial<IIssue>, issue: IIssue) => {
|
(formData: Partial<IIssue>, issue: IIssue) => {
|
||||||
if (!workspaceSlug || !projectId) return;
|
if (!workspaceSlug || !projectId) return;
|
||||||
@ -98,6 +139,10 @@ export const SingleSpreadsheetIssue: React.FC<Props> = ({
|
|||||||
? MODULE_ISSUES_WITH_PARAMS(moduleId.toString(), params)
|
? MODULE_ISSUES_WITH_PARAMS(moduleId.toString(), params)
|
||||||
: viewId
|
: viewId
|
||||||
? VIEW_ISSUES(viewId.toString(), params)
|
? VIEW_ISSUES(viewId.toString(), params)
|
||||||
|
: workspaceViewId
|
||||||
|
? WORKSPACE_VIEW_ISSUES(workspaceSlug.toString(), workspaceViewParams)
|
||||||
|
: currentWorkspaceIssuePath
|
||||||
|
? WORKSPACE_VIEW_ISSUES(workspaceSlug.toString(), currentWorkspaceIssuePath?.params)
|
||||||
: PROJECT_ISSUES_LIST_WITH_PARAMS(projectId, params);
|
: PROJECT_ISSUES_LIST_WITH_PARAMS(projectId, params);
|
||||||
|
|
||||||
if (issue.parent)
|
if (issue.parent)
|
||||||
@ -153,7 +198,18 @@ export const SingleSpreadsheetIssue: React.FC<Props> = ({
|
|||||||
console.log(error);
|
console.log(error);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
[workspaceSlug, projectId, cycleId, moduleId, viewId, params, user]
|
[
|
||||||
|
workspaceSlug,
|
||||||
|
projectId,
|
||||||
|
cycleId,
|
||||||
|
moduleId,
|
||||||
|
viewId,
|
||||||
|
workspaceViewId,
|
||||||
|
currentWorkspaceIssuePath,
|
||||||
|
workspaceViewParams,
|
||||||
|
params,
|
||||||
|
user,
|
||||||
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
const openPeekOverview = () => {
|
const openPeekOverview = () => {
|
||||||
|
@ -9,6 +9,7 @@ import { ICurrentUserResponse, IIssue, Properties, UserAuth } from "types";
|
|||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
issue: IIssue;
|
issue: IIssue;
|
||||||
|
projectId: string;
|
||||||
index: number;
|
index: number;
|
||||||
expandedIssues: string[];
|
expandedIssues: string[];
|
||||||
setExpandedIssues: React.Dispatch<React.SetStateAction<string[]>>;
|
setExpandedIssues: React.Dispatch<React.SetStateAction<string[]>>;
|
||||||
@ -24,6 +25,7 @@ type Props = {
|
|||||||
export const SpreadsheetIssues: React.FC<Props> = ({
|
export const SpreadsheetIssues: React.FC<Props> = ({
|
||||||
index,
|
index,
|
||||||
issue,
|
issue,
|
||||||
|
projectId,
|
||||||
expandedIssues,
|
expandedIssues,
|
||||||
setExpandedIssues,
|
setExpandedIssues,
|
||||||
gridTemplateColumns,
|
gridTemplateColumns,
|
||||||
@ -55,7 +57,7 @@ export const SpreadsheetIssues: React.FC<Props> = ({
|
|||||||
<div>
|
<div>
|
||||||
<SingleSpreadsheetIssue
|
<SingleSpreadsheetIssue
|
||||||
issue={issue}
|
issue={issue}
|
||||||
projectId={issue.project_detail.id}
|
projectId={projectId}
|
||||||
index={index}
|
index={index}
|
||||||
expanded={isExpanded}
|
expanded={isExpanded}
|
||||||
handleToggleExpand={handleToggleExpand}
|
handleToggleExpand={handleToggleExpand}
|
||||||
@ -77,6 +79,7 @@ export const SpreadsheetIssues: React.FC<Props> = ({
|
|||||||
<SpreadsheetIssues
|
<SpreadsheetIssues
|
||||||
key={subIssue.id}
|
key={subIssue.id}
|
||||||
issue={subIssue}
|
issue={subIssue}
|
||||||
|
projectId={subIssue.project_detail.id}
|
||||||
index={index}
|
index={index}
|
||||||
expandedIssues={expandedIssues}
|
expandedIssues={expandedIssues}
|
||||||
setExpandedIssues={setExpandedIssues}
|
setExpandedIssues={setExpandedIssues}
|
||||||
|
@ -86,6 +86,7 @@ export const SpreadsheetView: React.FC<Props> = ({
|
|||||||
key={`${issue.id}_${index}`}
|
key={`${issue.id}_${index}`}
|
||||||
index={index}
|
index={index}
|
||||||
issue={issue}
|
issue={issue}
|
||||||
|
projectId={issue.project_detail.id}
|
||||||
expandedIssues={expandedIssues}
|
expandedIssues={expandedIssues}
|
||||||
setExpandedIssues={setExpandedIssues}
|
setExpandedIssues={setExpandedIssues}
|
||||||
gridTemplateColumns={gridTemplateColumns}
|
gridTemplateColumns={gridTemplateColumns}
|
||||||
|
@ -161,6 +161,7 @@ export const IssueProperty: React.FC<IIssueProperty> = ({
|
|||||||
<div className="flex-shrink-0">
|
<div className="flex-shrink-0">
|
||||||
<StateSelect
|
<StateSelect
|
||||||
value={issue.state_detail}
|
value={issue.state_detail}
|
||||||
|
projectId={issue.project_detail.id}
|
||||||
onChange={handleStateChange}
|
onChange={handleStateChange}
|
||||||
hideDropdownArrow
|
hideDropdownArrow
|
||||||
disabled={!editable}
|
disabled={!editable}
|
||||||
@ -194,6 +195,7 @@ export const IssueProperty: React.FC<IIssueProperty> = ({
|
|||||||
<div className="flex-shrink-0">
|
<div className="flex-shrink-0">
|
||||||
<MembersSelect
|
<MembersSelect
|
||||||
value={issue.assignees}
|
value={issue.assignees}
|
||||||
|
projectId={issue.project_detail.id}
|
||||||
onChange={handleAssigneeChange}
|
onChange={handleAssigneeChange}
|
||||||
membersDetails={issue.assignee_details}
|
membersDetails={issue.assignee_details}
|
||||||
hideDropdownArrow
|
hideDropdownArrow
|
||||||
|
@ -17,7 +17,6 @@ import { DangerButton, SecondaryButton } from "components/ui";
|
|||||||
import { ExclamationTriangleIcon } from "@heroicons/react/24/outline";
|
import { ExclamationTriangleIcon } from "@heroicons/react/24/outline";
|
||||||
// types
|
// types
|
||||||
import type { ICurrentUserResponse, IView } from "types";
|
import type { ICurrentUserResponse, IView } from "types";
|
||||||
import { IWorkspaceView } from "types/workspace-view";
|
|
||||||
// fetch-keys
|
// fetch-keys
|
||||||
import { VIEWS_LIST, WORKSPACE_VIEWS_LIST } from "constants/fetch-keys";
|
import { VIEWS_LIST, WORKSPACE_VIEWS_LIST } from "constants/fetch-keys";
|
||||||
|
|
||||||
@ -25,7 +24,7 @@ type Props = {
|
|||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
viewType: "project" | "workspace";
|
viewType: "project" | "workspace";
|
||||||
setIsOpen: React.Dispatch<React.SetStateAction<boolean>>;
|
setIsOpen: React.Dispatch<React.SetStateAction<boolean>>;
|
||||||
data: IView | IWorkspaceView | null;
|
data: IView | null;
|
||||||
user: ICurrentUserResponse | undefined;
|
user: ICurrentUserResponse | undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -12,7 +12,6 @@ import { CustomMenu } from "components/ui";
|
|||||||
import viewsService from "services/views.service";
|
import viewsService from "services/views.service";
|
||||||
// types
|
// types
|
||||||
import { IView } from "types";
|
import { IView } from "types";
|
||||||
import { IWorkspaceView } from "types/workspace-view";
|
|
||||||
// fetch keys
|
// fetch keys
|
||||||
import { VIEWS_LIST } from "constants/fetch-keys";
|
import { VIEWS_LIST } from "constants/fetch-keys";
|
||||||
// hooks
|
// hooks
|
||||||
@ -21,7 +20,7 @@ import useToast from "hooks/use-toast";
|
|||||||
import { truncateText } from "helpers/string.helper";
|
import { truncateText } from "helpers/string.helper";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
view: IView | IWorkspaceView;
|
view: IView;
|
||||||
viewType: "project" | "workspace";
|
viewType: "project" | "workspace";
|
||||||
handleEditView: () => void;
|
handleEditView: () => void;
|
||||||
handleDeleteView: () => void;
|
handleDeleteView: () => void;
|
||||||
|
@ -159,7 +159,7 @@ export const WORKSPACE_VIEWS_LIST = (workspaceSlug: string) =>
|
|||||||
`WORKSPACE_VIEWS_LIST_${workspaceSlug.toUpperCase()}`;
|
`WORKSPACE_VIEWS_LIST_${workspaceSlug.toUpperCase()}`;
|
||||||
export const WORKSPACE_VIEW_DETAILS = (workspaceViewId: string) =>
|
export const WORKSPACE_VIEW_DETAILS = (workspaceViewId: string) =>
|
||||||
`WORKSPACE_VIEW_DETAILS_${workspaceViewId.toUpperCase()}`;
|
`WORKSPACE_VIEW_DETAILS_${workspaceViewId.toUpperCase()}`;
|
||||||
export const WORKSPACE_VIEW_ISSUES = (workspaceViewId: string, params: any) => {
|
export const WORKSPACE_VIEW_ISSUES = (workspaceViewId: string, params?: any) => {
|
||||||
if (!params) return `WORKSPACE_VIEW_ISSUES_${workspaceViewId.toUpperCase()}`;
|
if (!params) return `WORKSPACE_VIEW_ISSUES_${workspaceViewId.toUpperCase()}`;
|
||||||
|
|
||||||
const paramsKey = paramsToKey(params);
|
const paramsKey = paramsToKey(params);
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { useCallback, useState } from "react";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
|
|
||||||
import useSWR from "swr";
|
import useSWR from "swr";
|
||||||
@ -9,12 +10,12 @@ import useMyIssuesFilters from "hooks/my-issues/use-my-issues-filter";
|
|||||||
import workspaceService from "services/workspace.service";
|
import workspaceService from "services/workspace.service";
|
||||||
// layouts
|
// layouts
|
||||||
import { WorkspaceAuthorizationLayout } from "layouts/auth-layout";
|
import { WorkspaceAuthorizationLayout } from "layouts/auth-layout";
|
||||||
// contexts
|
|
||||||
import { IssueViewContextProvider } from "contexts/issue-view.context";
|
|
||||||
// components
|
// components
|
||||||
import { SpreadsheetView } from "components/core";
|
import { SpreadsheetView } from "components/core";
|
||||||
import { WorkspaceViewsNavigation } from "components/workspace/views/workpace-view-navigation";
|
import { WorkspaceViewsNavigation } from "components/workspace/views/workpace-view-navigation";
|
||||||
import { WorkspaceIssuesViewOptions } from "components/issues/workspace-views/workspace-issue-view-option";
|
import { WorkspaceIssuesViewOptions } from "components/issues/workspace-views/workspace-issue-view-option";
|
||||||
|
import { CreateUpdateViewModal } from "components/views";
|
||||||
|
import { CreateUpdateIssueModal, DeleteIssueModal } from "components/issues";
|
||||||
// ui
|
// ui
|
||||||
import { EmptyState, PrimaryButton } from "components/ui";
|
import { EmptyState, PrimaryButton } from "components/ui";
|
||||||
// icons
|
// icons
|
||||||
@ -24,8 +25,28 @@ import { CheckCircle } from "lucide-react";
|
|||||||
import emptyView from "public/empty-state/view.svg";
|
import emptyView from "public/empty-state/view.svg";
|
||||||
// fetch-keys
|
// fetch-keys
|
||||||
import { WORKSPACE_VIEW_DETAILS, WORKSPACE_VIEW_ISSUES } from "constants/fetch-keys";
|
import { WORKSPACE_VIEW_DETAILS, WORKSPACE_VIEW_ISSUES } from "constants/fetch-keys";
|
||||||
|
// types
|
||||||
|
import { IIssue } from "types";
|
||||||
|
|
||||||
const WorkspaceViewAllIssue: React.FC = () => {
|
const WorkspaceViewAllIssue: React.FC = () => {
|
||||||
|
const [createViewModal, setCreateViewModal] = useState<any>(null);
|
||||||
|
|
||||||
|
// create issue modal
|
||||||
|
const [createIssueModal, setCreateIssueModal] = useState(false);
|
||||||
|
const [preloadedData, setPreloadedData] = useState<
|
||||||
|
(Partial<IIssue> & { actionType: "createIssue" | "edit" | "delete" }) | undefined
|
||||||
|
>(undefined);
|
||||||
|
|
||||||
|
// update issue modal
|
||||||
|
const [editIssueModal, setEditIssueModal] = useState(false);
|
||||||
|
const [issueToEdit, setIssueToEdit] = useState<
|
||||||
|
(IIssue & { actionType: "edit" | "delete" }) | undefined
|
||||||
|
>(undefined);
|
||||||
|
|
||||||
|
// delete issue modal
|
||||||
|
const [deleteIssueModal, setDeleteIssueModal] = useState(false);
|
||||||
|
const [issueToDelete, setIssueToDelete] = useState<IIssue | null>(null);
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceSlug, workspaceViewId } = router.query;
|
const { workspaceSlug, workspaceViewId } = router.query;
|
||||||
|
|
||||||
@ -58,8 +79,46 @@ const WorkspaceViewAllIssue: React.FC = () => {
|
|||||||
workspaceSlug ? () => workspaceService.getViewIssues(workspaceSlug.toString(), params) : null
|
workspaceSlug ? () => workspaceService.getViewIssues(workspaceSlug.toString(), params) : null
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const makeIssueCopy = useCallback(
|
||||||
|
(issue: IIssue) => {
|
||||||
|
setCreateIssueModal(true);
|
||||||
|
|
||||||
|
setPreloadedData({ ...issue, name: `${issue.name} (Copy)`, actionType: "createIssue" });
|
||||||
|
},
|
||||||
|
[setCreateIssueModal, setPreloadedData]
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleEditIssue = useCallback(
|
||||||
|
(issue: IIssue) => {
|
||||||
|
setEditIssueModal(true);
|
||||||
|
setIssueToEdit({
|
||||||
|
...issue,
|
||||||
|
actionType: "edit",
|
||||||
|
cycle: issue.issue_cycle ? issue.issue_cycle.cycle : null,
|
||||||
|
module: issue.issue_module ? issue.issue_module.module : null,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
[setEditIssueModal, setIssueToEdit]
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleDeleteIssue = useCallback(
|
||||||
|
(issue: IIssue) => {
|
||||||
|
setDeleteIssueModal(true);
|
||||||
|
setIssueToDelete(issue);
|
||||||
|
},
|
||||||
|
[setDeleteIssueModal, setIssueToDelete]
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleIssueAction = useCallback(
|
||||||
|
(issue: IIssue, action: "copy" | "edit" | "delete" | "updateDraft") => {
|
||||||
|
if (action === "copy") makeIssueCopy(issue);
|
||||||
|
else if (action === "edit") handleEditIssue(issue);
|
||||||
|
else if (action === "delete") handleDeleteIssue(issue);
|
||||||
|
},
|
||||||
|
[makeIssueCopy, handleEditIssue, handleDeleteIssue]
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<IssueViewContextProvider>
|
|
||||||
<WorkspaceAuthorizationLayout
|
<WorkspaceAuthorizationLayout
|
||||||
breadcrumbs={
|
breadcrumbs={
|
||||||
<div className="flex gap-2 items-center">
|
<div className="flex gap-2 items-center">
|
||||||
@ -85,9 +144,43 @@ const WorkspaceViewAllIssue: React.FC = () => {
|
|||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
<CreateUpdateIssueModal
|
||||||
|
isOpen={createIssueModal && preloadedData?.actionType === "createIssue"}
|
||||||
|
handleClose={() => setCreateIssueModal(false)}
|
||||||
|
prePopulateData={{
|
||||||
|
...preloadedData,
|
||||||
|
}}
|
||||||
|
onSubmit={async () => {
|
||||||
|
mutateIssues();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<CreateUpdateIssueModal
|
||||||
|
isOpen={editIssueModal && issueToEdit?.actionType !== "delete"}
|
||||||
|
handleClose={() => setEditIssueModal(false)}
|
||||||
|
data={issueToEdit}
|
||||||
|
onSubmit={async () => {
|
||||||
|
mutateIssues();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<DeleteIssueModal
|
||||||
|
handleClose={() => setDeleteIssueModal(false)}
|
||||||
|
isOpen={deleteIssueModal}
|
||||||
|
data={issueToDelete}
|
||||||
|
user={user}
|
||||||
|
onSubmit={async () => {
|
||||||
|
mutateIssues();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<CreateUpdateViewModal
|
||||||
|
isOpen={createViewModal !== null}
|
||||||
|
handleClose={() => setCreateViewModal(null)}
|
||||||
|
viewType="workspace"
|
||||||
|
preLoadedData={createViewModal}
|
||||||
|
user={user}
|
||||||
|
/>
|
||||||
<div className="h-full flex flex-col overflow-hidden bg-custom-background-100">
|
<div className="h-full flex flex-col overflow-hidden bg-custom-background-100">
|
||||||
<div className="h-full w-full border-b border-custom-border-300">
|
<div className="h-full w-full border-b border-custom-border-300">
|
||||||
<WorkspaceViewsNavigation user={user} />
|
<WorkspaceViewsNavigation handleAddView={() => setCreateViewModal(true)} />
|
||||||
{error ? (
|
{error ? (
|
||||||
<EmptyState
|
<EmptyState
|
||||||
image={emptyView}
|
image={emptyView}
|
||||||
@ -103,7 +196,7 @@ const WorkspaceViewAllIssue: React.FC = () => {
|
|||||||
<SpreadsheetView
|
<SpreadsheetView
|
||||||
spreadsheetIssues={viewIssues}
|
spreadsheetIssues={viewIssues}
|
||||||
mutateIssues={mutateIssues}
|
mutateIssues={mutateIssues}
|
||||||
handleIssueAction={(...args) => {}}
|
handleIssueAction={handleIssueAction}
|
||||||
disableUserActions={false}
|
disableUserActions={false}
|
||||||
user={user}
|
user={user}
|
||||||
userAuth={{
|
userAuth={{
|
||||||
@ -118,7 +211,6 @@ const WorkspaceViewAllIssue: React.FC = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</WorkspaceAuthorizationLayout>
|
</WorkspaceAuthorizationLayout>
|
||||||
</IssueViewContextProvider>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { useCallback, useState } from "react";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
|
|
||||||
import useSWR from "swr";
|
import useSWR from "swr";
|
||||||
@ -9,12 +10,12 @@ import useMyIssuesFilters from "hooks/my-issues/use-my-issues-filter";
|
|||||||
import workspaceService from "services/workspace.service";
|
import workspaceService from "services/workspace.service";
|
||||||
// layouts
|
// layouts
|
||||||
import { WorkspaceAuthorizationLayout } from "layouts/auth-layout";
|
import { WorkspaceAuthorizationLayout } from "layouts/auth-layout";
|
||||||
// contexts
|
|
||||||
import { IssueViewContextProvider } from "contexts/issue-view.context";
|
|
||||||
// components
|
// components
|
||||||
import { SpreadsheetView } from "components/core";
|
import { SpreadsheetView } from "components/core";
|
||||||
import { WorkspaceViewsNavigation } from "components/workspace/views/workpace-view-navigation";
|
import { WorkspaceViewsNavigation } from "components/workspace/views/workpace-view-navigation";
|
||||||
import { WorkspaceIssuesViewOptions } from "components/issues/workspace-views/workspace-issue-view-option";
|
import { WorkspaceIssuesViewOptions } from "components/issues/workspace-views/workspace-issue-view-option";
|
||||||
|
import { CreateUpdateViewModal } from "components/views";
|
||||||
|
import { CreateUpdateIssueModal, DeleteIssueModal } from "components/issues";
|
||||||
// ui
|
// ui
|
||||||
import { EmptyState, PrimaryButton } from "components/ui";
|
import { EmptyState, PrimaryButton } from "components/ui";
|
||||||
// icons
|
// icons
|
||||||
@ -24,8 +25,28 @@ import { CheckCircle } from "lucide-react";
|
|||||||
import emptyView from "public/empty-state/view.svg";
|
import emptyView from "public/empty-state/view.svg";
|
||||||
// fetch-keys
|
// fetch-keys
|
||||||
import { WORKSPACE_VIEW_DETAILS, WORKSPACE_VIEW_ISSUES } from "constants/fetch-keys";
|
import { WORKSPACE_VIEW_DETAILS, WORKSPACE_VIEW_ISSUES } from "constants/fetch-keys";
|
||||||
|
// types
|
||||||
|
import { IIssue } from "types";
|
||||||
|
|
||||||
const WorkspaceViewAssignedIssue: React.FC = () => {
|
const WorkspaceViewAssignedIssue: React.FC = () => {
|
||||||
|
const [createViewModal, setCreateViewModal] = useState<any>(null);
|
||||||
|
|
||||||
|
// create issue modal
|
||||||
|
const [createIssueModal, setCreateIssueModal] = useState(false);
|
||||||
|
const [preloadedData, setPreloadedData] = useState<
|
||||||
|
(Partial<IIssue> & { actionType: "createIssue" | "edit" | "delete" }) | undefined
|
||||||
|
>(undefined);
|
||||||
|
|
||||||
|
// update issue modal
|
||||||
|
const [editIssueModal, setEditIssueModal] = useState(false);
|
||||||
|
const [issueToEdit, setIssueToEdit] = useState<
|
||||||
|
(IIssue & { actionType: "edit" | "delete" }) | undefined
|
||||||
|
>(undefined);
|
||||||
|
|
||||||
|
// delete issue modal
|
||||||
|
const [deleteIssueModal, setDeleteIssueModal] = useState(false);
|
||||||
|
const [issueToDelete, setIssueToDelete] = useState<IIssue | null>(null);
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceSlug, workspaceViewId } = router.query;
|
const { workspaceSlug, workspaceViewId } = router.query;
|
||||||
|
|
||||||
@ -58,8 +79,46 @@ const WorkspaceViewAssignedIssue: React.FC = () => {
|
|||||||
workspaceSlug ? () => workspaceService.getViewIssues(workspaceSlug.toString(), params) : null
|
workspaceSlug ? () => workspaceService.getViewIssues(workspaceSlug.toString(), params) : null
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const makeIssueCopy = useCallback(
|
||||||
|
(issue: IIssue) => {
|
||||||
|
setCreateIssueModal(true);
|
||||||
|
|
||||||
|
setPreloadedData({ ...issue, name: `${issue.name} (Copy)`, actionType: "createIssue" });
|
||||||
|
},
|
||||||
|
[setCreateIssueModal, setPreloadedData]
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleEditIssue = useCallback(
|
||||||
|
(issue: IIssue) => {
|
||||||
|
setEditIssueModal(true);
|
||||||
|
setIssueToEdit({
|
||||||
|
...issue,
|
||||||
|
actionType: "edit",
|
||||||
|
cycle: issue.issue_cycle ? issue.issue_cycle.cycle : null,
|
||||||
|
module: issue.issue_module ? issue.issue_module.module : null,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
[setEditIssueModal, setIssueToEdit]
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleDeleteIssue = useCallback(
|
||||||
|
(issue: IIssue) => {
|
||||||
|
setDeleteIssueModal(true);
|
||||||
|
setIssueToDelete(issue);
|
||||||
|
},
|
||||||
|
[setDeleteIssueModal, setIssueToDelete]
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleIssueAction = useCallback(
|
||||||
|
(issue: IIssue, action: "copy" | "edit" | "delete" | "updateDraft") => {
|
||||||
|
if (action === "copy") makeIssueCopy(issue);
|
||||||
|
else if (action === "edit") handleEditIssue(issue);
|
||||||
|
else if (action === "delete") handleDeleteIssue(issue);
|
||||||
|
},
|
||||||
|
[makeIssueCopy, handleEditIssue, handleDeleteIssue]
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<IssueViewContextProvider>
|
|
||||||
<WorkspaceAuthorizationLayout
|
<WorkspaceAuthorizationLayout
|
||||||
breadcrumbs={
|
breadcrumbs={
|
||||||
<div className="flex gap-2 items-center">
|
<div className="flex gap-2 items-center">
|
||||||
@ -85,9 +144,43 @@ const WorkspaceViewAssignedIssue: React.FC = () => {
|
|||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
<CreateUpdateIssueModal
|
||||||
|
isOpen={createIssueModal && preloadedData?.actionType === "createIssue"}
|
||||||
|
handleClose={() => setCreateIssueModal(false)}
|
||||||
|
prePopulateData={{
|
||||||
|
...preloadedData,
|
||||||
|
}}
|
||||||
|
onSubmit={async () => {
|
||||||
|
mutateIssues();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<CreateUpdateIssueModal
|
||||||
|
isOpen={editIssueModal && issueToEdit?.actionType !== "delete"}
|
||||||
|
handleClose={() => setEditIssueModal(false)}
|
||||||
|
data={issueToEdit}
|
||||||
|
onSubmit={async () => {
|
||||||
|
mutateIssues();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<DeleteIssueModal
|
||||||
|
handleClose={() => setDeleteIssueModal(false)}
|
||||||
|
isOpen={deleteIssueModal}
|
||||||
|
data={issueToDelete}
|
||||||
|
user={user}
|
||||||
|
onSubmit={async () => {
|
||||||
|
mutateIssues();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<CreateUpdateViewModal
|
||||||
|
isOpen={createViewModal !== null}
|
||||||
|
handleClose={() => setCreateViewModal(null)}
|
||||||
|
viewType="workspace"
|
||||||
|
preLoadedData={createViewModal}
|
||||||
|
user={user}
|
||||||
|
/>
|
||||||
<div className="h-full flex flex-col overflow-hidden bg-custom-background-100">
|
<div className="h-full flex flex-col overflow-hidden bg-custom-background-100">
|
||||||
<div className="h-full w-full border-b border-custom-border-300">
|
<div className="h-full w-full border-b border-custom-border-300">
|
||||||
<WorkspaceViewsNavigation user={user} />
|
<WorkspaceViewsNavigation handleAddView={() => setCreateViewModal(true)} />
|
||||||
{error ? (
|
{error ? (
|
||||||
<EmptyState
|
<EmptyState
|
||||||
image={emptyView}
|
image={emptyView}
|
||||||
@ -103,7 +196,7 @@ const WorkspaceViewAssignedIssue: React.FC = () => {
|
|||||||
<SpreadsheetView
|
<SpreadsheetView
|
||||||
spreadsheetIssues={viewIssues}
|
spreadsheetIssues={viewIssues}
|
||||||
mutateIssues={mutateIssues}
|
mutateIssues={mutateIssues}
|
||||||
handleIssueAction={(...args) => {}}
|
handleIssueAction={handleIssueAction}
|
||||||
disableUserActions={false}
|
disableUserActions={false}
|
||||||
user={user}
|
user={user}
|
||||||
userAuth={{
|
userAuth={{
|
||||||
@ -118,7 +211,6 @@ const WorkspaceViewAssignedIssue: React.FC = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</WorkspaceAuthorizationLayout>
|
</WorkspaceAuthorizationLayout>
|
||||||
</IssueViewContextProvider>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import { useCallback, useState } from "react";
|
||||||
|
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
|
|
||||||
import useSWR from "swr";
|
import useSWR from "swr";
|
||||||
@ -9,12 +11,12 @@ import useMyIssuesFilters from "hooks/my-issues/use-my-issues-filter";
|
|||||||
import workspaceService from "services/workspace.service";
|
import workspaceService from "services/workspace.service";
|
||||||
// layouts
|
// layouts
|
||||||
import { WorkspaceAuthorizationLayout } from "layouts/auth-layout";
|
import { WorkspaceAuthorizationLayout } from "layouts/auth-layout";
|
||||||
// contexts
|
|
||||||
import { IssueViewContextProvider } from "contexts/issue-view.context";
|
|
||||||
// components
|
// components
|
||||||
import { SpreadsheetView } from "components/core";
|
import { SpreadsheetView } from "components/core";
|
||||||
import { WorkspaceViewsNavigation } from "components/workspace/views/workpace-view-navigation";
|
import { WorkspaceViewsNavigation } from "components/workspace/views/workpace-view-navigation";
|
||||||
import { WorkspaceIssuesViewOptions } from "components/issues/workspace-views/workspace-issue-view-option";
|
import { WorkspaceIssuesViewOptions } from "components/issues/workspace-views/workspace-issue-view-option";
|
||||||
|
import { CreateUpdateViewModal } from "components/views";
|
||||||
|
import { CreateUpdateIssueModal, DeleteIssueModal } from "components/issues";
|
||||||
// ui
|
// ui
|
||||||
import { EmptyState, PrimaryButton } from "components/ui";
|
import { EmptyState, PrimaryButton } from "components/ui";
|
||||||
// icons
|
// icons
|
||||||
@ -24,8 +26,28 @@ import { CheckCircle } from "lucide-react";
|
|||||||
import emptyView from "public/empty-state/view.svg";
|
import emptyView from "public/empty-state/view.svg";
|
||||||
// fetch-keys
|
// fetch-keys
|
||||||
import { WORKSPACE_VIEW_DETAILS, WORKSPACE_VIEW_ISSUES } from "constants/fetch-keys";
|
import { WORKSPACE_VIEW_DETAILS, WORKSPACE_VIEW_ISSUES } from "constants/fetch-keys";
|
||||||
|
// types
|
||||||
|
import { IIssue } from "types";
|
||||||
|
|
||||||
const WorkspaceViewCreatedIssue: React.FC = () => {
|
const WorkspaceViewCreatedIssue: React.FC = () => {
|
||||||
|
const [createViewModal, setCreateViewModal] = useState<any>(null);
|
||||||
|
|
||||||
|
// create issue modal
|
||||||
|
const [createIssueModal, setCreateIssueModal] = useState(false);
|
||||||
|
const [preloadedData, setPreloadedData] = useState<
|
||||||
|
(Partial<IIssue> & { actionType: "createIssue" | "edit" | "delete" }) | undefined
|
||||||
|
>(undefined);
|
||||||
|
|
||||||
|
// update issue modal
|
||||||
|
const [editIssueModal, setEditIssueModal] = useState(false);
|
||||||
|
const [issueToEdit, setIssueToEdit] = useState<
|
||||||
|
(IIssue & { actionType: "edit" | "delete" }) | undefined
|
||||||
|
>(undefined);
|
||||||
|
|
||||||
|
// delete issue modal
|
||||||
|
const [deleteIssueModal, setDeleteIssueModal] = useState(false);
|
||||||
|
const [issueToDelete, setIssueToDelete] = useState<IIssue | null>(null);
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceSlug, workspaceViewId } = router.query;
|
const { workspaceSlug, workspaceViewId } = router.query;
|
||||||
|
|
||||||
@ -58,8 +80,46 @@ const WorkspaceViewCreatedIssue: React.FC = () => {
|
|||||||
workspaceSlug ? () => workspaceService.getViewIssues(workspaceSlug.toString(), params) : null
|
workspaceSlug ? () => workspaceService.getViewIssues(workspaceSlug.toString(), params) : null
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const makeIssueCopy = useCallback(
|
||||||
|
(issue: IIssue) => {
|
||||||
|
setCreateIssueModal(true);
|
||||||
|
|
||||||
|
setPreloadedData({ ...issue, name: `${issue.name} (Copy)`, actionType: "createIssue" });
|
||||||
|
},
|
||||||
|
[setCreateIssueModal, setPreloadedData]
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleEditIssue = useCallback(
|
||||||
|
(issue: IIssue) => {
|
||||||
|
setEditIssueModal(true);
|
||||||
|
setIssueToEdit({
|
||||||
|
...issue,
|
||||||
|
actionType: "edit",
|
||||||
|
cycle: issue.issue_cycle ? issue.issue_cycle.cycle : null,
|
||||||
|
module: issue.issue_module ? issue.issue_module.module : null,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
[setEditIssueModal, setIssueToEdit]
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleDeleteIssue = useCallback(
|
||||||
|
(issue: IIssue) => {
|
||||||
|
setDeleteIssueModal(true);
|
||||||
|
setIssueToDelete(issue);
|
||||||
|
},
|
||||||
|
[setDeleteIssueModal, setIssueToDelete]
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleIssueAction = useCallback(
|
||||||
|
(issue: IIssue, action: "copy" | "edit" | "delete" | "updateDraft") => {
|
||||||
|
if (action === "copy") makeIssueCopy(issue);
|
||||||
|
else if (action === "edit") handleEditIssue(issue);
|
||||||
|
else if (action === "delete") handleDeleteIssue(issue);
|
||||||
|
},
|
||||||
|
[makeIssueCopy, handleEditIssue, handleDeleteIssue]
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<IssueViewContextProvider>
|
|
||||||
<WorkspaceAuthorizationLayout
|
<WorkspaceAuthorizationLayout
|
||||||
breadcrumbs={
|
breadcrumbs={
|
||||||
<div className="flex gap-2 items-center">
|
<div className="flex gap-2 items-center">
|
||||||
@ -85,9 +145,43 @@ const WorkspaceViewCreatedIssue: React.FC = () => {
|
|||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
<CreateUpdateIssueModal
|
||||||
|
isOpen={createIssueModal && preloadedData?.actionType === "createIssue"}
|
||||||
|
handleClose={() => setCreateIssueModal(false)}
|
||||||
|
prePopulateData={{
|
||||||
|
...preloadedData,
|
||||||
|
}}
|
||||||
|
onSubmit={async () => {
|
||||||
|
mutateIssues();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<CreateUpdateIssueModal
|
||||||
|
isOpen={editIssueModal && issueToEdit?.actionType !== "delete"}
|
||||||
|
handleClose={() => setEditIssueModal(false)}
|
||||||
|
data={issueToEdit}
|
||||||
|
onSubmit={async () => {
|
||||||
|
mutateIssues();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<DeleteIssueModal
|
||||||
|
handleClose={() => setDeleteIssueModal(false)}
|
||||||
|
isOpen={deleteIssueModal}
|
||||||
|
data={issueToDelete}
|
||||||
|
user={user}
|
||||||
|
onSubmit={async () => {
|
||||||
|
mutateIssues();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<CreateUpdateViewModal
|
||||||
|
isOpen={createViewModal !== null}
|
||||||
|
handleClose={() => setCreateViewModal(null)}
|
||||||
|
viewType="workspace"
|
||||||
|
preLoadedData={createViewModal}
|
||||||
|
user={user}
|
||||||
|
/>
|
||||||
<div className="h-full flex flex-col overflow-hidden bg-custom-background-100">
|
<div className="h-full flex flex-col overflow-hidden bg-custom-background-100">
|
||||||
<div className="h-full w-full border-b border-custom-border-300">
|
<div className="h-full w-full border-b border-custom-border-300">
|
||||||
<WorkspaceViewsNavigation user={user} />
|
<WorkspaceViewsNavigation handleAddView={() => setCreateViewModal(true)} />
|
||||||
{error ? (
|
{error ? (
|
||||||
<EmptyState
|
<EmptyState
|
||||||
image={emptyView}
|
image={emptyView}
|
||||||
@ -103,7 +197,7 @@ const WorkspaceViewCreatedIssue: React.FC = () => {
|
|||||||
<SpreadsheetView
|
<SpreadsheetView
|
||||||
spreadsheetIssues={viewIssues}
|
spreadsheetIssues={viewIssues}
|
||||||
mutateIssues={mutateIssues}
|
mutateIssues={mutateIssues}
|
||||||
handleIssueAction={(...args) => {}}
|
handleIssueAction={handleIssueAction}
|
||||||
disableUserActions={false}
|
disableUserActions={false}
|
||||||
user={user}
|
user={user}
|
||||||
userAuth={{
|
userAuth={{
|
||||||
@ -118,7 +212,6 @@ const WorkspaceViewCreatedIssue: React.FC = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</WorkspaceAuthorizationLayout>
|
</WorkspaceAuthorizationLayout>
|
||||||
</IssueViewContextProvider>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ import { PhotoFilterOutlined } from "@mui/icons-material";
|
|||||||
import emptyView from "public/empty-state/view.svg";
|
import emptyView from "public/empty-state/view.svg";
|
||||||
// types
|
// types
|
||||||
import type { NextPage } from "next";
|
import type { NextPage } from "next";
|
||||||
import { IWorkspaceView } from "types/workspace-view";
|
import { IView } from "types";
|
||||||
// constants
|
// constants
|
||||||
import { WORKSPACE_VIEWS_LIST } from "constants/fetch-keys";
|
import { WORKSPACE_VIEWS_LIST } from "constants/fetch-keys";
|
||||||
// helper
|
// helper
|
||||||
@ -33,17 +33,17 @@ import { truncateText } from "helpers/string.helper";
|
|||||||
|
|
||||||
const WorkspaceViews: NextPage = () => {
|
const WorkspaceViews: NextPage = () => {
|
||||||
const [createUpdateViewModal, setCreateUpdateViewModal] = useState(false);
|
const [createUpdateViewModal, setCreateUpdateViewModal] = useState(false);
|
||||||
const [selectedViewToUpdate, setSelectedViewToUpdate] = useState<IWorkspaceView | null>(null);
|
const [selectedViewToUpdate, setSelectedViewToUpdate] = useState<IView | null>(null);
|
||||||
|
|
||||||
const [deleteViewModal, setDeleteViewModal] = useState(false);
|
const [deleteViewModal, setDeleteViewModal] = useState(false);
|
||||||
const [selectedViewToDelete, setSelectedViewToDelete] = useState<IWorkspaceView | null>(null);
|
const [selectedViewToDelete, setSelectedViewToDelete] = useState<IView | null>(null);
|
||||||
|
|
||||||
const handleEditView = (view: IWorkspaceView) => {
|
const handleEditView = (view: IView) => {
|
||||||
setSelectedViewToUpdate(view);
|
setSelectedViewToUpdate(view);
|
||||||
setCreateUpdateViewModal(true);
|
setCreateUpdateViewModal(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleDeleteView = (view: IWorkspaceView) => {
|
const handleDeleteView = (view: IView) => {
|
||||||
setSelectedViewToDelete(view);
|
setSelectedViewToDelete(view);
|
||||||
setDeleteViewModal(true);
|
setDeleteViewModal(true);
|
||||||
};
|
};
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import { useCallback, useState } from "react";
|
||||||
|
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
|
|
||||||
import useSWR from "swr";
|
import useSWR from "swr";
|
||||||
@ -9,12 +11,12 @@ import useMyIssuesFilters from "hooks/my-issues/use-my-issues-filter";
|
|||||||
import workspaceService from "services/workspace.service";
|
import workspaceService from "services/workspace.service";
|
||||||
// layouts
|
// layouts
|
||||||
import { WorkspaceAuthorizationLayout } from "layouts/auth-layout";
|
import { WorkspaceAuthorizationLayout } from "layouts/auth-layout";
|
||||||
// contexts
|
|
||||||
import { IssueViewContextProvider } from "contexts/issue-view.context";
|
|
||||||
// components
|
// components
|
||||||
import { SpreadsheetView } from "components/core";
|
import { SpreadsheetView } from "components/core";
|
||||||
import { WorkspaceViewsNavigation } from "components/workspace/views/workpace-view-navigation";
|
import { WorkspaceViewsNavigation } from "components/workspace/views/workpace-view-navigation";
|
||||||
import { WorkspaceIssuesViewOptions } from "components/issues/workspace-views/workspace-issue-view-option";
|
import { WorkspaceIssuesViewOptions } from "components/issues/workspace-views/workspace-issue-view-option";
|
||||||
|
import { CreateUpdateViewModal } from "components/views";
|
||||||
|
import { CreateUpdateIssueModal, DeleteIssueModal } from "components/issues";
|
||||||
// ui
|
// ui
|
||||||
import { EmptyState, PrimaryButton } from "components/ui";
|
import { EmptyState, PrimaryButton } from "components/ui";
|
||||||
// icons
|
// icons
|
||||||
@ -24,8 +26,28 @@ import { CheckCircle } from "lucide-react";
|
|||||||
import emptyView from "public/empty-state/view.svg";
|
import emptyView from "public/empty-state/view.svg";
|
||||||
// fetch-keys
|
// fetch-keys
|
||||||
import { WORKSPACE_VIEW_DETAILS, WORKSPACE_VIEW_ISSUES } from "constants/fetch-keys";
|
import { WORKSPACE_VIEW_DETAILS, WORKSPACE_VIEW_ISSUES } from "constants/fetch-keys";
|
||||||
|
// types
|
||||||
|
import { IIssue } from "types";
|
||||||
|
|
||||||
const WorkspaceViewSubscribedIssue: React.FC = () => {
|
const WorkspaceViewSubscribedIssue: React.FC = () => {
|
||||||
|
const [createViewModal, setCreateViewModal] = useState<any>(null);
|
||||||
|
|
||||||
|
// create issue modal
|
||||||
|
const [createIssueModal, setCreateIssueModal] = useState(false);
|
||||||
|
const [preloadedData, setPreloadedData] = useState<
|
||||||
|
(Partial<IIssue> & { actionType: "createIssue" | "edit" | "delete" }) | undefined
|
||||||
|
>(undefined);
|
||||||
|
|
||||||
|
// update issue modal
|
||||||
|
const [editIssueModal, setEditIssueModal] = useState(false);
|
||||||
|
const [issueToEdit, setIssueToEdit] = useState<
|
||||||
|
(IIssue & { actionType: "edit" | "delete" }) | undefined
|
||||||
|
>(undefined);
|
||||||
|
|
||||||
|
// delete issue modal
|
||||||
|
const [deleteIssueModal, setDeleteIssueModal] = useState(false);
|
||||||
|
const [issueToDelete, setIssueToDelete] = useState<IIssue | null>(null);
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceSlug, workspaceViewId } = router.query;
|
const { workspaceSlug, workspaceViewId } = router.query;
|
||||||
|
|
||||||
@ -58,8 +80,46 @@ const WorkspaceViewSubscribedIssue: React.FC = () => {
|
|||||||
workspaceSlug ? () => workspaceService.getViewIssues(workspaceSlug.toString(), params) : null
|
workspaceSlug ? () => workspaceService.getViewIssues(workspaceSlug.toString(), params) : null
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const makeIssueCopy = useCallback(
|
||||||
|
(issue: IIssue) => {
|
||||||
|
setCreateIssueModal(true);
|
||||||
|
|
||||||
|
setPreloadedData({ ...issue, name: `${issue.name} (Copy)`, actionType: "createIssue" });
|
||||||
|
},
|
||||||
|
[setCreateIssueModal, setPreloadedData]
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleEditIssue = useCallback(
|
||||||
|
(issue: IIssue) => {
|
||||||
|
setEditIssueModal(true);
|
||||||
|
setIssueToEdit({
|
||||||
|
...issue,
|
||||||
|
actionType: "edit",
|
||||||
|
cycle: issue.issue_cycle ? issue.issue_cycle.cycle : null,
|
||||||
|
module: issue.issue_module ? issue.issue_module.module : null,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
[setEditIssueModal, setIssueToEdit]
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleDeleteIssue = useCallback(
|
||||||
|
(issue: IIssue) => {
|
||||||
|
setDeleteIssueModal(true);
|
||||||
|
setIssueToDelete(issue);
|
||||||
|
},
|
||||||
|
[setDeleteIssueModal, setIssueToDelete]
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleIssueAction = useCallback(
|
||||||
|
(issue: IIssue, action: "copy" | "edit" | "delete" | "updateDraft") => {
|
||||||
|
if (action === "copy") makeIssueCopy(issue);
|
||||||
|
else if (action === "edit") handleEditIssue(issue);
|
||||||
|
else if (action === "delete") handleDeleteIssue(issue);
|
||||||
|
},
|
||||||
|
[makeIssueCopy, handleEditIssue, handleDeleteIssue]
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<IssueViewContextProvider>
|
|
||||||
<WorkspaceAuthorizationLayout
|
<WorkspaceAuthorizationLayout
|
||||||
breadcrumbs={
|
breadcrumbs={
|
||||||
<div className="flex gap-2 items-center">
|
<div className="flex gap-2 items-center">
|
||||||
@ -85,9 +145,43 @@ const WorkspaceViewSubscribedIssue: React.FC = () => {
|
|||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
<CreateUpdateIssueModal
|
||||||
|
isOpen={createIssueModal && preloadedData?.actionType === "createIssue"}
|
||||||
|
handleClose={() => setCreateIssueModal(false)}
|
||||||
|
prePopulateData={{
|
||||||
|
...preloadedData,
|
||||||
|
}}
|
||||||
|
onSubmit={async () => {
|
||||||
|
mutateIssues();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<CreateUpdateIssueModal
|
||||||
|
isOpen={editIssueModal && issueToEdit?.actionType !== "delete"}
|
||||||
|
handleClose={() => setEditIssueModal(false)}
|
||||||
|
data={issueToEdit}
|
||||||
|
onSubmit={async () => {
|
||||||
|
mutateIssues();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<DeleteIssueModal
|
||||||
|
handleClose={() => setDeleteIssueModal(false)}
|
||||||
|
isOpen={deleteIssueModal}
|
||||||
|
data={issueToDelete}
|
||||||
|
user={user}
|
||||||
|
onSubmit={async () => {
|
||||||
|
mutateIssues();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<CreateUpdateViewModal
|
||||||
|
isOpen={createViewModal !== null}
|
||||||
|
handleClose={() => setCreateViewModal(null)}
|
||||||
|
viewType="workspace"
|
||||||
|
preLoadedData={createViewModal}
|
||||||
|
user={user}
|
||||||
|
/>
|
||||||
<div className="h-full flex flex-col overflow-hidden bg-custom-background-100">
|
<div className="h-full flex flex-col overflow-hidden bg-custom-background-100">
|
||||||
<div className="h-full w-full border-b border-custom-border-300">
|
<div className="h-full w-full border-b border-custom-border-300">
|
||||||
<WorkspaceViewsNavigation user={user} />
|
<WorkspaceViewsNavigation handleAddView={() => setCreateViewModal(true)} />
|
||||||
{error ? (
|
{error ? (
|
||||||
<EmptyState
|
<EmptyState
|
||||||
image={emptyView}
|
image={emptyView}
|
||||||
@ -103,7 +197,7 @@ const WorkspaceViewSubscribedIssue: React.FC = () => {
|
|||||||
<SpreadsheetView
|
<SpreadsheetView
|
||||||
spreadsheetIssues={viewIssues}
|
spreadsheetIssues={viewIssues}
|
||||||
mutateIssues={mutateIssues}
|
mutateIssues={mutateIssues}
|
||||||
handleIssueAction={(...args) => {}}
|
handleIssueAction={handleIssueAction}
|
||||||
disableUserActions={false}
|
disableUserActions={false}
|
||||||
user={user}
|
user={user}
|
||||||
userAuth={{
|
userAuth={{
|
||||||
@ -118,7 +212,6 @@ const WorkspaceViewSubscribedIssue: React.FC = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</WorkspaceAuthorizationLayout>
|
</WorkspaceAuthorizationLayout>
|
||||||
</IssueViewContextProvider>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -14,9 +14,9 @@ import {
|
|||||||
ICurrentUserResponse,
|
ICurrentUserResponse,
|
||||||
IWorkspaceBulkInviteFormData,
|
IWorkspaceBulkInviteFormData,
|
||||||
IWorkspaceViewProps,
|
IWorkspaceViewProps,
|
||||||
|
IView,
|
||||||
IIssueFilterOptions,
|
IIssueFilterOptions,
|
||||||
} from "types";
|
} from "types";
|
||||||
import { IWorkspaceView } from "types/workspace-view";
|
|
||||||
|
|
||||||
class WorkspaceService extends APIService {
|
class WorkspaceService extends APIService {
|
||||||
constructor() {
|
constructor() {
|
||||||
@ -264,7 +264,7 @@ class WorkspaceService extends APIService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async createView(workspaceSlug: string, data: IWorkspaceView): Promise<any> {
|
async createView(workspaceSlug: string, data: IView): Promise<any> {
|
||||||
return this.post(`/api/workspaces/${workspaceSlug}/views/`, data)
|
return this.post(`/api/workspaces/${workspaceSlug}/views/`, data)
|
||||||
.then((response) => response?.data)
|
.then((response) => response?.data)
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
@ -272,11 +272,7 @@ class WorkspaceService extends APIService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async updateView(
|
async updateView(workspaceSlug: string, viewId: string, data: Partial<IView>): Promise<any> {
|
||||||
workspaceSlug: string,
|
|
||||||
viewId: string,
|
|
||||||
data: Partial<IWorkspaceView>
|
|
||||||
): Promise<any> {
|
|
||||||
return this.patch(`/api/workspaces/${workspaceSlug}/views/${viewId}/`, data)
|
return this.patch(`/api/workspaces/${workspaceSlug}/views/${viewId}/`, data)
|
||||||
.then((response) => response?.data)
|
.then((response) => response?.data)
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
@ -292,7 +288,7 @@ class WorkspaceService extends APIService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async getAllViews(workspaceSlug: string): Promise<IWorkspaceView[]> {
|
async getAllViews(workspaceSlug: string): Promise<IView[]> {
|
||||||
return this.get(`/api/workspaces/${workspaceSlug}/views/`)
|
return this.get(`/api/workspaces/${workspaceSlug}/views/`)
|
||||||
.then((response) => response?.data)
|
.then((response) => response?.data)
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
@ -300,7 +296,7 @@ class WorkspaceService extends APIService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async getViewDetails(workspaceSlug: string, viewId: string): Promise<IWorkspaceView> {
|
async getViewDetails(workspaceSlug: string, viewId: string): Promise<IView> {
|
||||||
return this.get(`/api/workspaces/${workspaceSlug}/views/${viewId}/`)
|
return this.get(`/api/workspaces/${workspaceSlug}/views/${viewId}/`)
|
||||||
.then((response) => response?.data)
|
.then((response) => response?.data)
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
|
6
web/types/views.d.ts
vendored
6
web/types/views.d.ts
vendored
@ -14,6 +14,11 @@ export interface IView {
|
|||||||
query_data: IIssueFilterOptions;
|
query_data: IIssueFilterOptions;
|
||||||
project: string;
|
project: string;
|
||||||
workspace: string;
|
workspace: string;
|
||||||
|
workspace_detail: {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
slug: string;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IQuery {
|
export interface IQuery {
|
||||||
@ -25,4 +30,5 @@ export interface IQuery {
|
|||||||
start_date: string[] | null;
|
start_date: string[] | null;
|
||||||
target_date: string[] | null;
|
target_date: string[] | null;
|
||||||
type: "active" | "backlog" | null;
|
type: "active" | "backlog" | null;
|
||||||
|
projects: string[] | null;
|
||||||
}
|
}
|
||||||
|
21
web/types/workspace-view.d.ts
vendored
21
web/types/workspace-view.d.ts
vendored
@ -1,21 +0,0 @@
|
|||||||
import { IIssueFilterOptions } from "./view-props";
|
|
||||||
|
|
||||||
export interface IWorkspaceView {
|
|
||||||
access: string;
|
|
||||||
created_at: Date;
|
|
||||||
created_by: string;
|
|
||||||
description: string;
|
|
||||||
id: string;
|
|
||||||
name: string;
|
|
||||||
query: IIssueFilterOptions;
|
|
||||||
query_data: IIssueFilterOptions;
|
|
||||||
updated_at: Date;
|
|
||||||
updated_by: string;
|
|
||||||
is_favorite: boolean;
|
|
||||||
workspace: string;
|
|
||||||
workspace_detail: {
|
|
||||||
id: string;
|
|
||||||
name: string;
|
|
||||||
slug: string;
|
|
||||||
};
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user