diff --git a/apps/app/components/project/issues/BoardView/state/create-update-state-inline.tsx b/apps/app/components/project/issues/BoardView/state/create-update-state-inline.tsx new file mode 100644 index 000000000..84312a404 --- /dev/null +++ b/apps/app/components/project/issues/BoardView/state/create-update-state-inline.tsx @@ -0,0 +1,184 @@ +import React, { useEffect } from "react"; +// swr +import { mutate } from "swr"; +// react hook form +import { useForm, Controller } from "react-hook-form"; +// react color +import { TwitterPicker } from "react-color"; +// headless +import { Popover, Transition } from "@headlessui/react"; +// constants +import { STATE_LIST } from "constants/fetch-keys"; +// services +import stateService from "lib/services/state.service"; +// ui +import { Button, Input } from "ui"; +// types +import type { IState } from "types"; + +type Props = { + workspaceSlug?: string; + projectId?: string; + data: IState | null; + onClose: () => void; + selectedGroup: StateGroup | null; +}; + +export type StateGroup = "backlog" | "unstarted" | "started" | "completed" | "cancelled" | null; + +export const CreateUpdateStateInline: React.FC = ({ + workspaceSlug, + projectId, + data, + onClose, + selectedGroup, +}) => { + const { + register, + handleSubmit, + formState: { errors }, + setError, + watch, + reset, + control, + } = useForm({ + defaultValues: { + name: "", + color: "#000000", + group: "backlog", + }, + }); + + const handleClose = () => { + onClose(); + reset({ name: "", color: "#000000", group: "backlog" }); + }; + + const onSubmit = async (formData: IState) => { + if (!workspaceSlug || !projectId) return; + const payload: IState = { + ...formData, + }; + if (!data) { + await stateService + .createState(workspaceSlug, projectId, { ...payload, group: selectedGroup }) + .then((res) => { + mutate(STATE_LIST(projectId), (prevData) => [...(prevData ?? []), res], false); + handleClose(); + }) + .catch((err) => { + Object.keys(err).map((key) => { + setError(key as keyof IState, { + message: err[key].join(", "), + }); + }); + }); + } else { + await stateService + .updateState(workspaceSlug, projectId, data.id, { + ...payload, + group: selectedGroup ?? "backlog", + }) + .then((res) => { + mutate( + STATE_LIST(projectId), + (prevData) => { + const newData = prevData?.map((item) => { + if (item.id === res.id) { + return res; + } + return item; + }); + return newData; + }, + false + ); + handleClose(); + }) + .catch((err) => { + Object.keys(err).map((key) => { + setError(key as keyof IState, { + message: err[key].join(", "), + }); + }); + }); + } + }; + + useEffect(() => { + if (data === null) return; + reset(data); + }, [data]); + + return ( +
+
+ + {({ open }) => ( + <> + + {watch("color") && watch("color") !== "" && ( + + )} + + + + + ( + onChange(value.hex)} /> + )} + /> + + + + )} + +
+ + + + +
+ ); +}; diff --git a/apps/app/components/project/settings/StatesSettings.tsx b/apps/app/components/project/settings/StatesSettings.tsx index f793046d4..cfb642c69 100644 --- a/apps/app/components/project/settings/StatesSettings.tsx +++ b/apps/app/components/project/settings/StatesSettings.tsx @@ -1,22 +1,12 @@ -import React, { useEffect, useState } from "react"; -// swr -import { mutate } from "swr"; -// react hook form -import { useForm, Controller } from "react-hook-form"; -// react color -import { TwitterPicker } from "react-color"; -// headless -import { Popover, Transition } from "@headlessui/react"; +import React, { useState } from "react"; // hooks import useUser from "lib/hooks/useUser"; -// constants -import { STATE_LIST } from "constants/fetch-keys"; -// services -import stateService from "lib/services/state.service"; // components +import { + StateGroup, + CreateUpdateStateInline, +} from "components/project/issues/BoardView/state/create-update-state-inline"; import ConfirmStateDeletion from "components/project/issues/BoardView/state/confirm-state-delete"; -// ui -import { Button, Input } from "ui"; // icons import { PencilSquareIcon, PlusIcon, TrashIcon } from "@heroicons/react/24/outline"; // constants @@ -28,173 +18,6 @@ type Props = { projectId: string | string[] | undefined; }; -type CreateUpdateStateProps = { - workspaceSlug?: string; - projectId?: string; - data: IState | null; - onClose: () => void; - selectedGroup: StateGroup | null; -}; - -type StateGroup = "backlog" | "unstarted" | "started" | "completed" | "cancelled" | null; - -const CreateUpdateState: React.FC = ({ - workspaceSlug, - projectId, - data, - onClose, - selectedGroup, -}) => { - const { - register, - handleSubmit, - formState: { errors }, - setError, - watch, - reset, - control, - } = useForm({ - defaultValues: { - name: "", - color: "#000000", - group: "backlog", - }, - }); - - const handleClose = () => { - onClose(); - reset({ name: "", color: "#000000", group: "backlog" }); - }; - - const onSubmit = async (formData: IState) => { - if (!workspaceSlug || !projectId) return; - const payload: IState = { - ...formData, - }; - if (!data) { - await stateService - .createState(workspaceSlug, projectId, { ...payload, group: selectedGroup }) - .then((res) => { - mutate(STATE_LIST(projectId), (prevData) => [...(prevData ?? []), res], false); - handleClose(); - }) - .catch((err) => { - Object.keys(err).map((key) => { - setError(key as keyof IState, { - message: err[key].join(", "), - }); - }); - }); - } else { - await stateService - .updateState(workspaceSlug, projectId, data.id, { - ...payload, - group: selectedGroup ?? "backlog", - }) - .then((res) => { - mutate( - STATE_LIST(projectId), - (prevData) => { - const newData = prevData?.map((item) => { - if (item.id === res.id) { - return res; - } - return item; - }); - return newData; - }, - false - ); - handleClose(); - }) - .catch((err) => { - Object.keys(err).map((key) => { - setError(key as keyof IState, { - message: err[key].join(", "), - }); - }); - }); - } - }; - - useEffect(() => { - if (data === null) return; - reset(data); - }, [data]); - - return ( -
-
- - {({ open }) => ( - <> - - {watch("color") && watch("color") !== "" && ( - - )} - - - - - ( - onChange(value.hex)} /> - )} - /> - - - - )} - -
- - - - -
- ); -}; - const StatesSettings: React.FC = ({ projectId }) => { const [activeGroup, setActiveGroup] = useState(null); const [selectedState, setSelectedState] = useState(null); @@ -221,64 +44,76 @@ const StatesSettings: React.FC = ({ projectId }) => {
{Object.keys(groupedStates).map((key) => ( -
-
+ +

{key} states

-
- {groupedStates[key]?.map((state) => - state.id !== selectedState ? ( -
-
+
+
+ {groupedStates[key]?.map((state) => + state.id !== selectedState ? (
-

{addSpaceIfCamelCase(state.name)}

-
-
- - -
-
- ) : ( - +
+
+

{addSpaceIfCamelCase(state.name)}

+
+
+ + +
+
+ ) : ( +
+ { + setActiveGroup(null); + setSelectedState(null); + }} + workspaceSlug={activeWorkspace?.slug} + data={states?.find((state) => state.id === selectedState) ?? null} + selectedGroup={key as keyof StateGroup} + /> +
+ ) + )} +
+ {key === activeGroup && ( + { setActiveGroup(null); setSelectedState(null); }} workspaceSlug={activeWorkspace?.slug} - data={states?.find((state) => state.id === selectedState) ?? null} + data={null} selectedGroup={key as keyof StateGroup} /> - ) - )} - {key === activeGroup && ( - { - setActiveGroup(null); - setSelectedState(null); - }} - workspaceSlug={activeWorkspace?.slug} - data={null} - selectedGroup={key as keyof StateGroup} - /> - )} -
+ )} +
+ ))}