refactor: project settings (#2575)
* refactor: project setting estimate * refactor: project setting label * refactor: project setting state * refactor: project setting integration * refactor: project settings member * fix: estimate not updating * fix: estimate not in observable * fix: build error
This commit is contained in:
parent
80e6d7e1ea
commit
2d64caef90
44 changed files with 2308 additions and 1929 deletions
|
|
@ -1,23 +1,20 @@
|
|||
import React, { useEffect } from "react";
|
||||
|
||||
import { useRouter } from "next/router";
|
||||
|
||||
import { mutate } from "swr";
|
||||
|
||||
// react-hook-form
|
||||
import { useForm, Controller } from "react-hook-form";
|
||||
// react-color
|
||||
import { TwitterPicker } from "react-color";
|
||||
// headless ui
|
||||
import { Popover, Transition } from "@headlessui/react";
|
||||
// services
|
||||
import { ProjectStateService } from "services/project";
|
||||
|
||||
// store
|
||||
import { observer } from "mobx-react-lite";
|
||||
import { useMobxStore } from "lib/mobx/store-provider";
|
||||
// hooks
|
||||
import useToast from "hooks/use-toast";
|
||||
// ui
|
||||
import { Button, CustomSelect, Input, Tooltip } from "@plane/ui";
|
||||
import { CustomSelect } from "components/ui";
|
||||
import { Button, Input, Tooltip } from "@plane/ui";
|
||||
// types
|
||||
import type { IUser, IState, IStateResponse } from "types";
|
||||
import type { IState } from "types";
|
||||
// fetch-keys
|
||||
import { STATES_LIST } from "constants/fetch-keys";
|
||||
// constants
|
||||
|
|
@ -26,25 +23,30 @@ import { GROUP_CHOICES } from "constants/project";
|
|||
type Props = {
|
||||
data: IState | null;
|
||||
onClose: () => void;
|
||||
selectedGroup: StateGroup | null;
|
||||
user: IUser | undefined;
|
||||
groupLength: number;
|
||||
selectedGroup: StateGroup | null;
|
||||
};
|
||||
|
||||
export type StateGroup = "backlog" | "unstarted" | "started" | "completed" | "cancelled" | null;
|
||||
|
||||
const defaultValues: Partial<IState> = {
|
||||
name: "",
|
||||
description: "",
|
||||
color: "rgb(var(--color-text-200))",
|
||||
group: "backlog",
|
||||
};
|
||||
|
||||
const projectStateService = new ProjectStateService();
|
||||
export const CreateUpdateStateInline: React.FC<Props> = observer((props) => {
|
||||
const { data, onClose, selectedGroup, groupLength } = props;
|
||||
|
||||
export const CreateUpdateStateInline: React.FC<Props> = ({ data, onClose, selectedGroup, user, groupLength }) => {
|
||||
// router
|
||||
const router = useRouter();
|
||||
const { workspaceSlug, projectId } = router.query;
|
||||
|
||||
// store
|
||||
const { projectState: projectStateStore } = useMobxStore();
|
||||
|
||||
// hooks
|
||||
const { setToastAlert } = useToast();
|
||||
|
||||
const {
|
||||
|
|
@ -57,15 +59,19 @@ export const CreateUpdateStateInline: React.FC<Props> = ({ data, onClose, select
|
|||
defaultValues,
|
||||
});
|
||||
|
||||
/**
|
||||
* @description pre-populate form with data if data is present
|
||||
*/
|
||||
useEffect(() => {
|
||||
if (!data) return;
|
||||
|
||||
reset(data);
|
||||
}, [data, reset]);
|
||||
|
||||
/**
|
||||
* @description pre-populate form with default values if data is not present
|
||||
*/
|
||||
useEffect(() => {
|
||||
if (data) return;
|
||||
|
||||
reset({
|
||||
...defaultValues,
|
||||
group: selectedGroup ?? "backlog",
|
||||
|
|
@ -77,87 +83,73 @@ export const CreateUpdateStateInline: React.FC<Props> = ({ data, onClose, select
|
|||
reset({ name: "", color: "#000000", group: "backlog" });
|
||||
};
|
||||
|
||||
const onSubmit = async (formData: IState) => {
|
||||
const handleCreate = async (formData: IState) => {
|
||||
if (!workspaceSlug || !projectId || isSubmitting) return;
|
||||
|
||||
await projectStateStore
|
||||
.createState(workspaceSlug.toString(), projectId.toString(), formData)
|
||||
.then(() => {
|
||||
handleClose();
|
||||
setToastAlert({
|
||||
type: "success",
|
||||
title: "Success!",
|
||||
message: "State created successfully.",
|
||||
});
|
||||
})
|
||||
.catch((error) => {
|
||||
if (error.status === 400)
|
||||
setToastAlert({
|
||||
type: "error",
|
||||
title: "Error!",
|
||||
message: "State with that name already exists. Please try again with another name.",
|
||||
});
|
||||
else
|
||||
setToastAlert({
|
||||
type: "error",
|
||||
title: "Error!",
|
||||
message: "State could not be created. Please try again.",
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
const handleUpdate = async (formData: IState) => {
|
||||
if (!workspaceSlug || !projectId || !data || isSubmitting) return;
|
||||
|
||||
await projectStateStore
|
||||
.updateState(workspaceSlug.toString(), projectId.toString(), data.id, formData)
|
||||
.then(() => {
|
||||
mutate(STATES_LIST(projectId.toString()));
|
||||
handleClose();
|
||||
|
||||
setToastAlert({
|
||||
type: "success",
|
||||
title: "Success!",
|
||||
message: "State updated successfully.",
|
||||
});
|
||||
})
|
||||
.catch((error) => {
|
||||
if (error.status === 400)
|
||||
setToastAlert({
|
||||
type: "error",
|
||||
title: "Error!",
|
||||
message: "Another state exists with the same name. Please try again with another name.",
|
||||
});
|
||||
else
|
||||
setToastAlert({
|
||||
type: "error",
|
||||
title: "Error!",
|
||||
message: "State could not be updated. Please try again.",
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
const onSubmit = async (formData: IState) => {
|
||||
const payload: IState = {
|
||||
...formData,
|
||||
};
|
||||
|
||||
if (!data) {
|
||||
await projectStateService
|
||||
.createState(workspaceSlug.toString(), projectId.toString(), { ...payload }, user)
|
||||
.then((res) => {
|
||||
mutate<IStateResponse>(
|
||||
STATES_LIST(projectId.toString()),
|
||||
(prevData) => {
|
||||
if (!prevData) return prevData;
|
||||
|
||||
return {
|
||||
...prevData,
|
||||
[res.group]: [...prevData[res.group], res],
|
||||
};
|
||||
},
|
||||
false
|
||||
);
|
||||
handleClose();
|
||||
|
||||
setToastAlert({
|
||||
type: "success",
|
||||
title: "Success!",
|
||||
message: "State created successfully.",
|
||||
});
|
||||
})
|
||||
.catch((err) => {
|
||||
if (err.status === 400)
|
||||
setToastAlert({
|
||||
type: "error",
|
||||
title: "Error!",
|
||||
message: "State with that name already exists. Please try again with another name.",
|
||||
});
|
||||
else
|
||||
setToastAlert({
|
||||
type: "error",
|
||||
title: "Error!",
|
||||
message: "State could not be created. Please try again.",
|
||||
});
|
||||
});
|
||||
} else {
|
||||
await projectStateService
|
||||
.updateState(
|
||||
workspaceSlug.toString(),
|
||||
projectId.toString(),
|
||||
data.id,
|
||||
{
|
||||
...payload,
|
||||
},
|
||||
user
|
||||
)
|
||||
.then(() => {
|
||||
mutate(STATES_LIST(projectId.toString()));
|
||||
handleClose();
|
||||
|
||||
setToastAlert({
|
||||
type: "success",
|
||||
title: "Success!",
|
||||
message: "State updated successfully.",
|
||||
});
|
||||
})
|
||||
.catch((err) => {
|
||||
if (err.status === 400)
|
||||
setToastAlert({
|
||||
type: "error",
|
||||
title: "Error!",
|
||||
message: "Another state exists with the same name. Please try again with another name.",
|
||||
});
|
||||
else
|
||||
setToastAlert({
|
||||
type: "error",
|
||||
title: "Error!",
|
||||
message: "State could not be updated. Please try again.",
|
||||
});
|
||||
});
|
||||
}
|
||||
if (data) await handleUpdate(payload);
|
||||
else await handleCreate(payload);
|
||||
};
|
||||
|
||||
return (
|
||||
|
|
@ -281,4 +273,4 @@ export const CreateUpdateStateInline: React.FC<Props> = ({ data, onClose, select
|
|||
</Button>
|
||||
</form>
|
||||
);
|
||||
};
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue