chore: state delete validation (#930)

This commit is contained in:
Aaryan Khandelwal 2023-04-22 18:19:35 +05:30 committed by GitHub
parent 48e77ea81b
commit 99dd1b9f0c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 113 additions and 103 deletions

View File

@ -14,7 +14,7 @@ import stateService from "services/state.service";
// types // types
import { IIssue } from "types"; import { IIssue } from "types";
// fetch keys // fetch keys
import { ISSUE_DETAILS, PROJECT_ISSUES_ACTIVITY, STATE_LIST } from "constants/fetch-keys"; import { ISSUE_DETAILS, PROJECT_ISSUES_ACTIVITY, STATES_LIST } from "constants/fetch-keys";
// icons // icons
import { CheckIcon, getStateGroupIcon } from "components/icons"; import { CheckIcon, getStateGroupIcon } from "components/icons";
@ -28,7 +28,7 @@ export const ChangeIssueState: React.FC<Props> = ({ setIsPaletteOpen, issue }) =
const { workspaceSlug, projectId, issueId } = router.query; const { workspaceSlug, projectId, issueId } = router.query;
const { data: stateGroups, mutate: mutateIssueDetails } = useSWR( const { data: stateGroups, mutate: mutateIssueDetails } = useSWR(
workspaceSlug && projectId ? STATE_LIST(projectId as string) : null, workspaceSlug && projectId ? STATES_LIST(projectId as string) : null,
workspaceSlug && projectId workspaceSlug && projectId
? () => stateService.getStates(workspaceSlug as string, projectId as string) ? () => stateService.getStates(workspaceSlug as string, projectId as string)
: null : null

View File

@ -15,7 +15,7 @@ import issuesService from "services/issues.service";
import projectService from "services/project.service"; import projectService from "services/project.service";
import stateService from "services/state.service"; import stateService from "services/state.service";
// types // types
import { PROJECT_ISSUE_LABELS, PROJECT_MEMBERS, STATE_LIST } from "constants/fetch-keys"; import { PROJECT_ISSUE_LABELS, PROJECT_MEMBERS, STATES_LIST } from "constants/fetch-keys";
import { IIssueFilterOptions } from "types"; import { IIssueFilterOptions } from "types";
export const FilterList: React.FC<any> = ({ filters, setFilters }) => { export const FilterList: React.FC<any> = ({ filters, setFilters }) => {
@ -37,7 +37,7 @@ export const FilterList: React.FC<any> = ({ filters, setFilters }) => {
); );
const { data: stateGroups } = useSWR( const { data: stateGroups } = useSWR(
workspaceSlug && projectId ? STATE_LIST(projectId as string) : null, workspaceSlug && projectId ? STATES_LIST(projectId as string) : null,
workspaceSlug workspaceSlug
? () => stateService.getStates(workspaceSlug as string, projectId as string) ? () => stateService.getStates(workspaceSlug as string, projectId as string)
: null : null

View File

@ -46,7 +46,7 @@ import {
MODULE_DETAILS, MODULE_DETAILS,
MODULE_ISSUES_WITH_PARAMS, MODULE_ISSUES_WITH_PARAMS,
PROJECT_ISSUES_LIST_WITH_PARAMS, PROJECT_ISSUES_LIST_WITH_PARAMS,
STATE_LIST, STATES_LIST,
} from "constants/fetch-keys"; } from "constants/fetch-keys";
// image // image
@ -103,7 +103,7 @@ export const IssuesView: React.FC<Props> = ({
} = useIssuesView(); } = useIssuesView();
const { data: stateGroups } = useSWR( const { data: stateGroups } = useSWR(
workspaceSlug && projectId ? STATE_LIST(projectId as string) : null, workspaceSlug && projectId ? STATES_LIST(projectId as string) : null,
workspaceSlug workspaceSlug
? () => stateService.getStates(workspaceSlug as string, projectId as string) ? () => stateService.getStates(workspaceSlug as string, projectId as string)
: null : null

View File

@ -14,7 +14,7 @@ import { getStateGroupIcon } from "components/icons";
// helpers // helpers
import { getStatesList } from "helpers/state.helper"; import { getStatesList } from "helpers/state.helper";
// fetch keys // fetch keys
import { STATE_LIST } from "constants/fetch-keys"; import { STATES_LIST } from "constants/fetch-keys";
type Props = { type Props = {
setIsOpen: React.Dispatch<React.SetStateAction<boolean>>; setIsOpen: React.Dispatch<React.SetStateAction<boolean>>;
@ -29,7 +29,7 @@ export const IssueStateSelect: React.FC<Props> = ({ setIsOpen, value, onChange,
const { workspaceSlug } = router.query; const { workspaceSlug } = router.query;
const { data: stateGroups } = useSWR( const { data: stateGroups } = useSWR(
workspaceSlug && projectId ? STATE_LIST(projectId) : null, workspaceSlug && projectId ? STATES_LIST(projectId) : null,
workspaceSlug && projectId workspaceSlug && projectId
? () => stateService.getStates(workspaceSlug as string, projectId) ? () => stateService.getStates(workspaceSlug as string, projectId)
: null : null

View File

@ -17,7 +17,7 @@ import { addSpaceIfCamelCase } from "helpers/string.helper";
// types // types
import { UserAuth } from "types"; import { UserAuth } from "types";
// constants // constants
import { STATE_LIST } from "constants/fetch-keys"; import { STATES_LIST } from "constants/fetch-keys";
type Props = { type Props = {
value: string; value: string;
@ -30,7 +30,7 @@ export const SidebarStateSelect: React.FC<Props> = ({ value, onChange, userAuth
const { workspaceSlug, projectId } = router.query; const { workspaceSlug, projectId } = router.query;
const { data: stateGroups } = useSWR( const { data: stateGroups } = useSWR(
workspaceSlug && projectId ? STATE_LIST(projectId as string) : null, workspaceSlug && projectId ? STATES_LIST(projectId as string) : null,
workspaceSlug && projectId workspaceSlug && projectId
? () => stateService.getStates(workspaceSlug as string, projectId as string) ? () => stateService.getStates(workspaceSlug as string, projectId as string)
: null : null

View File

@ -15,7 +15,7 @@ import { getStatesList } from "helpers/state.helper";
// types // types
import { IIssue } from "types"; import { IIssue } from "types";
// fetch-keys // fetch-keys
import { STATE_LIST } from "constants/fetch-keys"; import { STATES_LIST } from "constants/fetch-keys";
type Props = { type Props = {
issue: IIssue; issue: IIssue;
@ -36,7 +36,7 @@ export const ViewStateSelect: React.FC<Props> = ({
const { workspaceSlug } = router.query; const { workspaceSlug } = router.query;
const { data: stateGroups } = useSWR( const { data: stateGroups } = useSWR(
workspaceSlug && issue ? STATE_LIST(issue.project) : null, workspaceSlug && issue ? STATES_LIST(issue.project) : null,
workspaceSlug && issue workspaceSlug && issue
? () => stateService.getStates(workspaceSlug as string, issue.project) ? () => stateService.getStates(workspaceSlug as string, issue.project)
: null : null

View File

@ -19,9 +19,9 @@ import { CustomSelect, Input, PrimaryButton, SecondaryButton, TextArea } from "c
// icons // icons
import { ChevronDownIcon } from "@heroicons/react/24/outline"; import { ChevronDownIcon } from "@heroicons/react/24/outline";
// types // types
import type { IState } from "types"; import type { IState, IStateResponse } from "types";
// fetch keys // fetch keys
import { STATE_LIST } from "constants/fetch-keys"; import { STATES_LIST } from "constants/fetch-keys";
// constants // constants
import { GROUP_CHOICES } from "constants/project"; import { GROUP_CHOICES } from "constants/project";
@ -35,7 +35,7 @@ type Props = {
const defaultValues: Partial<IState> = { const defaultValues: Partial<IState> = {
name: "", name: "",
description: "", description: "",
color: "#000000", color: "#858e96",
group: "backlog", group: "backlog",
}; };
@ -70,8 +70,19 @@ export const CreateStateModal: React.FC<Props> = ({ isOpen, projectId, handleClo
await stateService await stateService
.createState(workspaceSlug as string, projectId, payload) .createState(workspaceSlug as string, projectId, payload)
.then(() => { .then((res) => {
mutate(STATE_LIST(projectId)); mutate<IStateResponse>(
STATES_LIST(projectId.toString()),
(prevData) => {
if (!prevData) return prevData;
return {
...prevData,
[res.group]: [...prevData[res.group], res],
};
},
false
);
onClose(); onClose();
}) })
.catch((err) => { .catch((err) => {

View File

@ -17,9 +17,9 @@ import useToast from "hooks/use-toast";
// ui // ui
import { CustomSelect, Input, PrimaryButton, SecondaryButton } from "components/ui"; import { CustomSelect, Input, PrimaryButton, SecondaryButton } from "components/ui";
// types // types
import type { IState } from "types"; import type { IState, IStateResponse } from "types";
// fetch-keys // fetch-keys
import { STATE_LIST } from "constants/fetch-keys"; import { STATES_LIST } from "constants/fetch-keys";
// constants // constants
import { GROUP_CHOICES } from "constants/project"; import { GROUP_CHOICES } from "constants/project";
@ -33,7 +33,7 @@ export type StateGroup = "backlog" | "unstarted" | "started" | "completed" | "ca
const defaultValues: Partial<IState> = { const defaultValues: Partial<IState> = {
name: "", name: "",
color: "#000000", color: "#858e96",
group: "backlog", group: "backlog",
}; };
@ -80,11 +80,23 @@ export const CreateUpdateStateInline: React.FC<Props> = ({ data, onClose, select
const payload: IState = { const payload: IState = {
...formData, ...formData,
}; };
if (!data) { if (!data) {
await stateService await stateService
.createState(workspaceSlug as string, projectId as string, { ...payload }) .createState(workspaceSlug.toString(), projectId.toString(), { ...payload })
.then((res) => { .then((res) => {
mutate(STATE_LIST(projectId as string)); mutate<IStateResponse>(
STATES_LIST(projectId.toString()),
(prevData) => {
if (!prevData) return prevData;
return {
...prevData,
[res.group]: [...prevData[res.group], res],
};
},
false
);
handleClose(); handleClose();
setToastAlert({ setToastAlert({
@ -109,11 +121,11 @@ export const CreateUpdateStateInline: React.FC<Props> = ({ data, onClose, select
}); });
} else { } else {
await stateService await stateService
.updateState(workspaceSlug as string, projectId as string, data.id, { .updateState(workspaceSlug.toString(), projectId.toString(), data.id, {
...payload, ...payload,
}) })
.then(() => { .then(() => {
mutate(STATE_LIST(projectId as string)); mutate(STATES_LIST(projectId.toString()));
handleClose(); handleClose();
setToastAlert({ setToastAlert({

View File

@ -1,8 +1,8 @@
import React, { useEffect, useState } from "react"; import React, { useState } from "react";
import { useRouter } from "next/router"; import { useRouter } from "next/router";
import useSWR, { mutate } from "swr"; import { mutate } from "swr";
// headless ui // headless ui
import { Dialog, Transition } from "@headlessui/react"; import { Dialog, Transition } from "@headlessui/react";
@ -10,17 +10,14 @@ import { Dialog, Transition } from "@headlessui/react";
import { ExclamationTriangleIcon } from "@heroicons/react/24/outline"; import { ExclamationTriangleIcon } from "@heroicons/react/24/outline";
// services // services
import stateServices from "services/state.service"; import stateServices from "services/state.service";
import issuesServices from "services/issues.service";
// hooks // hooks
import useToast from "hooks/use-toast"; import useToast from "hooks/use-toast";
// ui // ui
import { DangerButton, SecondaryButton } from "components/ui"; import { DangerButton, SecondaryButton } from "components/ui";
// helpers
import { groupBy } from "helpers/array.helper";
// types // types
import type { IState } from "types"; import type { IState, IStateResponse } from "types";
// fetch-keys // fetch-keys
import { STATE_LIST, PROJECT_ISSUES_LIST } from "constants/fetch-keys"; import { STATES_LIST } from "constants/fetch-keys";
type Props = { type Props = {
isOpen: boolean; isOpen: boolean;
@ -30,54 +27,60 @@ type Props = {
export const DeleteStateModal: React.FC<Props> = ({ isOpen, onClose, data }) => { export const DeleteStateModal: React.FC<Props> = ({ isOpen, onClose, data }) => {
const [isDeleteLoading, setIsDeleteLoading] = useState(false); const [isDeleteLoading, setIsDeleteLoading] = useState(false);
const [issuesWithThisStateExist, setIssuesWithThisStateExist] = useState(true);
const router = useRouter(); const router = useRouter();
const { workspaceSlug, projectId } = router.query; const { workspaceSlug } = router.query;
const { setToastAlert } = useToast(); const { setToastAlert } = useToast();
const { data: issues } = useSWR(
workspaceSlug && projectId
? PROJECT_ISSUES_LIST(workspaceSlug as string, projectId as string)
: null,
workspaceSlug && projectId
? () => issuesServices.getIssues(workspaceSlug as string, projectId as string)
: null
);
const handleClose = () => { const handleClose = () => {
onClose(); onClose();
setIsDeleteLoading(false); setIsDeleteLoading(false);
}; };
const handleDeletion = async () => { const handleDeletion = async () => {
if (!workspaceSlug || !data) return;
setIsDeleteLoading(true); setIsDeleteLoading(true);
if (!data || !workspaceSlug || issuesWithThisStateExist) return;
await stateServices await stateServices
.deleteState(workspaceSlug as string, data.project, data.id) .deleteState(workspaceSlug as string, data.project, data.id)
.then(() => { .then(() => {
mutate(STATE_LIST(data.project)); mutate<IStateResponse>(
handleClose(); STATES_LIST(data.project),
(prevData) => {
if (!prevData) return prevData;
setToastAlert({ const stateGroup = [...prevData[data.group]].filter((s) => s.id !== data.id);
title: "Success",
type: "success", return {
message: "State deleted successfully", ...prevData,
}); [data.group]: stateGroup,
};
},
false
);
handleClose();
}) })
.catch((error) => { .catch((err) => {
console.log(error);
setIsDeleteLoading(false); setIsDeleteLoading(false);
if (err.status === 400)
setToastAlert({
type: "error",
title: "Error!",
message:
"This state contains some issues within it, please move them to some other state to delete this state.",
});
else
setToastAlert({
type: "error",
title: "Error!",
message: "State could not be deleted. Please try again.",
});
}); });
}; };
const groupedIssues = groupBy(issues ?? [], "state");
useEffect(() => {
if (data) setIssuesWithThisStateExist(!!groupedIssues[data.id]);
}, [groupedIssues, data]);
return ( return (
<Transition.Root show={isOpen} as={React.Fragment}> <Transition.Root show={isOpen} as={React.Fragment}>
<Dialog as="div" className="relative z-20" onClose={handleClose}> <Dialog as="div" className="relative z-20" onClose={handleClose}>
@ -127,24 +130,12 @@ export const DeleteStateModal: React.FC<Props> = ({ isOpen, onClose, data }) =>
the state will be permanently removed. This action cannot be undone. the state will be permanently removed. This action cannot be undone.
</p> </p>
</div> </div>
<div className="mt-2">
{issuesWithThisStateExist && (
<p className="text-sm text-red-500">
There are issues with this state. Please move them to another state
before deleting this state.
</p>
)}
</div>
</div> </div>
</div> </div>
</div> </div>
<div className="flex justify-end gap-2 bg-gray-50 p-4 sm:px-6"> <div className="flex justify-end gap-2 p-4 sm:px-6">
<SecondaryButton onClick={handleClose}>Cancel</SecondaryButton> <SecondaryButton onClick={handleClose}>Cancel</SecondaryButton>
<DangerButton <DangerButton onClick={handleDeletion} loading={isDeleteLoading}>
onClick={handleDeletion}
disabled={issuesWithThisStateExist}
loading={isDeleteLoading}
>
{isDeleteLoading ? "Deleting..." : "Delete"} {isDeleteLoading ? "Deleting..." : "Delete"}
</DangerButton> </DangerButton>
</div> </div>

View File

@ -15,6 +15,7 @@ import {
PencilSquareIcon, PencilSquareIcon,
TrashIcon, TrashIcon,
} from "@heroicons/react/24/outline"; } from "@heroicons/react/24/outline";
import { getStateGroupIcon } from "components/icons";
// helpers // helpers
import { addSpaceIfCamelCase } from "helpers/string.helper"; import { addSpaceIfCamelCase } from "helpers/string.helper";
import { groupBy, orderArrayBy } from "helpers/array.helper"; import { groupBy, orderArrayBy } from "helpers/array.helper";
@ -22,8 +23,7 @@ import { orderStateGroups } from "helpers/state.helper";
// types // types
import { IState } from "types"; import { IState } from "types";
// fetch-keys // fetch-keys
import { STATE_LIST } from "constants/fetch-keys"; import { STATES_LIST } from "constants/fetch-keys";
import { getStateGroupIcon } from "components/icons";
type Props = { type Props = {
index: number; index: number;
@ -60,7 +60,7 @@ export const SingleState: React.FC<Props> = ({
newStatesList = orderArrayBy(newStatesList, "sequence", "ascending"); newStatesList = orderArrayBy(newStatesList, "sequence", "ascending");
mutate( mutate(
STATE_LIST(projectId as string), STATES_LIST(projectId as string),
orderStateGroups(groupBy(newStatesList, "group")), orderStateGroups(groupBy(newStatesList, "group")),
false false
); );
@ -76,7 +76,7 @@ export const SingleState: React.FC<Props> = ({
default: true, default: true,
}) })
.then(() => { .then(() => {
mutate(STATE_LIST(projectId as string)); mutate(STATES_LIST(projectId as string));
setIsSubmitting(false); setIsSubmitting(false);
}) })
.catch(() => { .catch(() => {
@ -89,7 +89,7 @@ export const SingleState: React.FC<Props> = ({
default: true, default: true,
}) })
.then(() => { .then(() => {
mutate(STATE_LIST(projectId as string)); mutate(STATES_LIST(projectId as string));
setIsSubmitting(false); setIsSubmitting(false);
}) })
.catch(() => { .catch(() => {
@ -115,7 +115,7 @@ export const SingleState: React.FC<Props> = ({
newStatesList = orderArrayBy(newStatesList, "sequence", "ascending"); newStatesList = orderArrayBy(newStatesList, "sequence", "ascending");
mutate( mutate(
STATE_LIST(projectId as string), STATES_LIST(projectId as string),
orderStateGroups(groupBy(newStatesList, "group")), orderStateGroups(groupBy(newStatesList, "group")),
false false
); );
@ -126,7 +126,7 @@ export const SingleState: React.FC<Props> = ({
}) })
.then((res) => { .then((res) => {
console.log(res); console.log(res);
mutate(STATE_LIST(projectId as string)); mutate(STATES_LIST(projectId as string));
}) })
.catch((err) => { .catch((err) => {
console.error(err); console.error(err);
@ -140,7 +140,7 @@ export const SingleState: React.FC<Props> = ({
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">
{getStateGroupIcon(state.group, "20", "20", state.color)} {getStateGroupIcon(state.group, "20", "20", state.color)}
<div> <div>
<h6 className="font-medium text-brand-muted-1">{addSpaceIfCamelCase(state.name)}</h6> <h6 className="text-brand-muted-1 font-medium">{addSpaceIfCamelCase(state.name)}</h6>
<p className="text-xs text-gray-400">{state.description}</p> <p className="text-xs text-gray-400">{state.description}</p>
</div> </div>
</div> </div>

View File

@ -15,7 +15,7 @@ import { getStatesList } from "helpers/state.helper";
// types // types
import { IIssueFilterOptions, IQuery } from "types"; import { IIssueFilterOptions, IQuery } from "types";
// fetch-keys // fetch-keys
import { PROJECT_ISSUE_LABELS, PROJECT_MEMBERS, STATE_LIST } from "constants/fetch-keys"; import { PROJECT_ISSUE_LABELS, PROJECT_MEMBERS, STATES_LIST } from "constants/fetch-keys";
// constants // constants
import { PRIORITIES } from "constants/project"; import { PRIORITIES } from "constants/project";
@ -36,7 +36,7 @@ export const SelectFilters: React.FC<Props> = ({
const { workspaceSlug, projectId } = router.query; const { workspaceSlug, projectId } = router.query;
const { data: states } = useSWR( const { data: states } = useSWR(
workspaceSlug && projectId ? STATE_LIST(projectId as string) : null, workspaceSlug && projectId ? STATES_LIST(projectId as string) : null,
workspaceSlug && projectId workspaceSlug && projectId
? () => stateService.getStates(workspaceSlug as string, projectId as string) ? () => stateService.getStates(workspaceSlug as string, projectId as string)
: null : null

View File

@ -89,8 +89,8 @@ export const CYCLE_DRAFT_LIST = (projectId: string) =>
export const CYCLE_COMPLETE_LIST = (projectId: string) => export const CYCLE_COMPLETE_LIST = (projectId: string) =>
`CYCLE_COMPLETE_LIST_${projectId.toUpperCase()}`; `CYCLE_COMPLETE_LIST_${projectId.toUpperCase()}`;
export const STATE_LIST = (projectId: string) => `STATE_LIST_${projectId.toUpperCase()}`; export const STATES_LIST = (projectId: string) => `STATES_LIST_${projectId.toUpperCase()}`;
export const STATE_DETAIL = "STATE_DETAILS"; export const STATE_DETAILS = "STATE_DETAILS";
export const USER_ISSUE = (workspaceSlug: string) => `USER_ISSUE_${workspaceSlug.toUpperCase()}`; export const USER_ISSUE = (workspaceSlug: string) => `USER_ISSUE_${workspaceSlug.toUpperCase()}`;
export const USER_ACTIVITY = "USER_ACTIVITY"; export const USER_ACTIVITY = "USER_ACTIVITY";

View File

@ -1,7 +1,7 @@
// types // types
import { IState, StateResponse } from "types"; import { IState, IStateResponse } from "types";
export const orderStateGroups = (unorderedStateGroups: StateResponse) => export const orderStateGroups = (unorderedStateGroups: IStateResponse) =>
Object.assign( Object.assign(
{ backlog: [], unstarted: [], started: [], completed: [], cancelled: [] }, { backlog: [], unstarted: [], started: [], completed: [], cancelled: [] },
unorderedStateGroups unorderedStateGroups

View File

@ -20,7 +20,7 @@ import {
CYCLE_ISSUES_WITH_PARAMS, CYCLE_ISSUES_WITH_PARAMS,
MODULE_ISSUES_WITH_PARAMS, MODULE_ISSUES_WITH_PARAMS,
PROJECT_ISSUES_LIST_WITH_PARAMS, PROJECT_ISSUES_LIST_WITH_PARAMS,
STATE_LIST, STATES_LIST,
} from "constants/fetch-keys"; } from "constants/fetch-keys";
const useIssuesView = () => { const useIssuesView = () => {
@ -100,7 +100,7 @@ const useIssuesView = () => {
); );
const { data: states } = useSWR( const { data: states } = useSWR(
workspaceSlug && projectId ? STATE_LIST(projectId as string) : null, workspaceSlug && projectId ? STATES_LIST(projectId as string) : null,
workspaceSlug && projectId workspaceSlug && projectId
? () => stateService.getStates(workspaceSlug as string, projectId as string) ? () => stateService.getStates(workspaceSlug as string, projectId as string)
: null : null

View File

@ -12,7 +12,7 @@ import { getStatesList } from "helpers/state.helper";
// types // types
import { Properties, NestedKeyOf, IIssue } from "types"; import { Properties, NestedKeyOf, IIssue } from "types";
// fetch-keys // fetch-keys
import { STATE_LIST } from "constants/fetch-keys"; import { STATES_LIST } from "constants/fetch-keys";
// constants // constants
import { PRIORITIES } from "constants/project"; import { PRIORITIES } from "constants/project";
@ -41,7 +41,7 @@ const useMyIssuesProperties = (issues?: IIssue[]) => {
const { user } = useUser(); const { user } = useUser();
const { data: stateGroups } = useSWR( const { data: stateGroups } = useSWR(
workspaceSlug && projectId ? STATE_LIST(projectId as string) : null, workspaceSlug && projectId ? STATES_LIST(projectId as string) : null,
workspaceSlug && projectId workspaceSlug && projectId
? () => stateService.getStates(workspaceSlug as string, projectId as string) ? () => stateService.getStates(workspaceSlug as string, projectId as string)
: null : null

View File

@ -6,7 +6,8 @@ import useSWR from "swr";
// services // services
import stateService from "services/state.service"; import stateService from "services/state.service";
import projectService from "services/project.service"; // hooks
import useProjectDetails from "hooks/use-project-details";
// layouts // layouts
import { ProjectAuthorizationWrapper } from "layouts/auth-layout"; import { ProjectAuthorizationWrapper } from "layouts/auth-layout";
// components // components
@ -26,7 +27,7 @@ import { getStatesList, orderStateGroups } from "helpers/state.helper";
// types // types
import type { NextPage } from "next"; import type { NextPage } from "next";
// fetch-keys // fetch-keys
import { PROJECT_DETAILS, STATE_LIST } from "constants/fetch-keys"; import { STATES_LIST } from "constants/fetch-keys";
const StatesSettings: NextPage = () => { const StatesSettings: NextPage = () => {
const [activeGroup, setActiveGroup] = useState<StateGroup>(null); const [activeGroup, setActiveGroup] = useState<StateGroup>(null);
@ -36,15 +37,10 @@ const StatesSettings: NextPage = () => {
const router = useRouter(); const router = useRouter();
const { workspaceSlug, projectId } = router.query; const { workspaceSlug, projectId } = router.query;
const { data: projectDetails } = useSWR( const { projectDetails } = useProjectDetails();
workspaceSlug && projectId ? PROJECT_DETAILS(projectId as string) : null,
workspaceSlug && projectId
? () => projectService.getProject(workspaceSlug as string, projectId as string)
: null
);
const { data: states } = useSWR( const { data: states } = useSWR(
workspaceSlug && projectId ? STATE_LIST(projectId as string) : null, workspaceSlug && projectId ? STATES_LIST(projectId as string) : null,
workspaceSlug && projectId workspaceSlug && projectId
? () => stateService.getStates(workspaceSlug as string, projectId as string) ? () => stateService.getStates(workspaceSlug as string, projectId as string)
: null : null

View File

@ -8,7 +8,7 @@ const trackEvent =
process.env.NEXT_PUBLIC_TRACK_EVENTS === "true" || process.env.NEXT_PUBLIC_TRACK_EVENTS === "1"; process.env.NEXT_PUBLIC_TRACK_EVENTS === "true" || process.env.NEXT_PUBLIC_TRACK_EVENTS === "1";
// types // types
import type { IState, StateResponse } from "types"; import type { IState, IStateResponse } from "types";
class ProjectStateServices extends APIService { class ProjectStateServices extends APIService {
constructor() { constructor() {
@ -26,7 +26,7 @@ class ProjectStateServices extends APIService {
}); });
} }
async getStates(workspaceSlug: string, projectId: string): Promise<StateResponse> { async getStates(workspaceSlug: string, projectId: string): Promise<IStateResponse> {
return this.get(`/api/workspaces/${workspaceSlug}/projects/${projectId}/states/`) return this.get(`/api/workspaces/${workspaceSlug}/projects/${projectId}/states/`)
.then((response) => response?.data) .then((response) => response?.data)
.catch((error) => { .catch((error) => {
@ -96,7 +96,7 @@ class ProjectStateServices extends APIService {
return response?.data; return response?.data;
}) })
.catch((error) => { .catch((error) => {
throw error?.response?.data; throw error?.response;
}); });
} }
} }

View File

@ -19,6 +19,6 @@ export interface IState {
workspace_detail: IWorkspaceLite; workspace_detail: IWorkspaceLite;
} }
export interface StateResponse { export interface IStateResponse {
[key: string]: IState[]; [key: string]: IState[];
} }