chore: edit/delete option

This commit is contained in:
Aaryan Khandelwal 2023-09-20 18:52:38 +05:30
parent cd4d56d071
commit 3c3f0f7581
3 changed files with 100 additions and 33 deletions

View File

@ -1,4 +1,4 @@
import React, { useState } from "react"; import React, { useEffect, useState } from "react";
import { useRouter } from "next/router"; import { useRouter } from "next/router";
@ -13,13 +13,20 @@ import { PrimaryButton } from "components/ui";
import { ICustomAttribute } from "types"; import { ICustomAttribute } from "types";
type Props = { type Props = {
data: ICustomAttribute | null;
objectId: string; objectId: string;
onSubmit?: () => void;
parentId: string; parentId: string;
}; };
export const OptionForm: React.FC<Props> = observer(({ objectId, parentId }) => { export const OptionForm: React.FC<Props> = observer((props) => {
const [optionName, setOptionName] = useState(""); const { data, objectId, onSubmit, parentId } = props;
const [optionColor, setOptionColor] = useState("#000000");
const [option, setOption] = useState<Partial<ICustomAttribute>>({
display_name: "",
color: "#000000",
});
const [isEditing, setIsEditing] = useState(false);
const router = useRouter(); const router = useRouter();
const { workspaceSlug } = router.query; const { workspaceSlug } = router.query;
@ -29,47 +36,90 @@ export const OptionForm: React.FC<Props> = observer(({ objectId, parentId }) =>
const handleCreateOption = async () => { const handleCreateOption = async () => {
if (!workspaceSlug) return; if (!workspaceSlug) return;
if (!optionName || optionName === "") return; if (option.display_name === "") return;
const payload: Partial<ICustomAttribute> = { const payload: Partial<ICustomAttribute> = {
color: optionColor, color: option.color,
display_name: optionName, display_name: option.display_name,
type: "option", type: "option",
}; };
await customAttributes await customAttributes.createAttributeOption(workspaceSlug.toString(), objectId, {
.createAttributeOption(workspaceSlug.toString(), objectId, { ...payload,
...payload, parent: parentId,
parent: parentId, });
})
.then(() => {
setOptionName("");
setOptionColor("#000000");
});
}; };
const handleUpdateOption = async () => {
if (!workspaceSlug) return;
if (option.display_name === "" || !option.parent || !option.id) return;
setIsEditing(true);
const payload: Partial<ICustomAttribute> = {
color: option.color,
display_name: option.display_name,
};
await customAttributes
.updateAttributeOption(workspaceSlug.toString(), objectId, option.parent, option.id, payload)
.finally(() => setIsEditing(false));
};
const handleFormSubmit = async () => {
if (data) await handleUpdateOption();
else await handleCreateOption();
setOption({
display_name: "",
color: "#000000",
});
if (onSubmit) onSubmit();
};
useEffect(() => {
if (!data) return;
setOption({ ...data });
}, [data]);
return ( return (
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<div className="bg-custom-background-100 rounded border border-custom-border-200 flex items-center gap-2 px-3 py-2 flex-grow"> <div className="bg-custom-background-100 rounded border border-custom-border-200 flex items-center gap-2 px-3 py-2 flex-grow">
{/* <span className="flex-shrink-0 text-xs grid place-items-center">🚀</span> */}
<input <input
type="text" type="text"
className="flex-grow border-none outline-none placeholder:text-custom-text-400 text-xs" className="flex-grow border-none outline-none placeholder:text-custom-text-400 text-xs"
value={optionName} value={option.display_name}
onChange={(e) => setOptionName(e.target.value)} onChange={(e) => setOption((prev) => ({ ...prev, display_name: e.target.value }))}
placeholder="Enter new option" placeholder="Enter new option"
/> />
<ColorPicker onChange={(val) => setOptionColor(val)} selectedColor={optionColor} /> <ColorPicker
onChange={(val) => setOption((prev) => ({ ...prev, color: val }))}
selectedColor={option.color ?? "#000000"}
/>
</div> </div>
<div className="flex-shrink-0"> <div className="flex-shrink-0">
<PrimaryButton {data ? (
onClick={handleCreateOption} <PrimaryButton
size="sm" onClick={handleFormSubmit}
className="!py-1.5 !px-2" size="sm"
loading={customAttributes.createAttributeOptionLoader} className="!py-1.5 !px-2"
> loading={isEditing}
{customAttributes.createAttributeOptionLoader ? "Adding..." : "Add"} >
</PrimaryButton> {isEditing ? "Updating..." : "Update"}
</PrimaryButton>
) : (
<PrimaryButton
onClick={handleFormSubmit}
size="sm"
className="!py-1.5 !px-2"
loading={customAttributes.createAttributeOptionLoader}
>
{customAttributes.createAttributeOptionLoader ? "Adding..." : "Add"}
</PrimaryButton>
)}
</div> </div>
</div> </div>
); );

View File

@ -1,4 +1,4 @@
import React from "react"; import React, { useState } from "react";
// mobx // mobx
import { observer } from "mobx-react-lite"; import { observer } from "mobx-react-lite";
@ -7,9 +7,13 @@ import { useMobxStore } from "lib/mobx/store-provider";
import { Controller } from "react-hook-form"; import { Controller } from "react-hook-form";
// components // components
import { FormComponentProps, Input, OptionForm, SelectOption } from "components/custom-attributes"; import { FormComponentProps, Input, OptionForm, SelectOption } from "components/custom-attributes";
// types
import { ICustomAttribute } from "types";
export const SelectAttributeForm: React.FC<FormComponentProps & { multiple?: boolean }> = observer( export const SelectAttributeForm: React.FC<FormComponentProps & { multiple?: boolean }> = observer(
({ control, multiple = false, objectId = "", watch }) => { ({ control, multiple = false, objectId = "", watch }) => {
const [optionToEdit, setOptionToEdit] = useState<ICustomAttribute | null>(null);
const { customAttributes: customAttributesStore } = useMobxStore(); const { customAttributes: customAttributesStore } = useMobxStore();
const { entityAttributes } = customAttributesStore; const { entityAttributes } = customAttributesStore;
@ -28,11 +32,21 @@ export const SelectAttributeForm: React.FC<FormComponentProps & { multiple?: boo
<p className="text-xs">Options</p> <p className="text-xs">Options</p>
<div className="mt-3 space-y-2 w-3/5"> <div className="mt-3 space-y-2 w-3/5">
{options?.map((option) => ( {options?.map((option) => (
<SelectOption key={option.id} objectId={objectId} option={option} /> <SelectOption
key={option.id}
handleEditOption={() => setOptionToEdit(option)}
objectId={objectId}
option={option}
/>
))} ))}
</div> </div>
<div className="mt-2 w-3/5"> <div className="mt-2 w-3/5">
<OptionForm objectId={objectId} parentId={watch("id") ?? ""} /> <OptionForm
data={optionToEdit}
objectId={objectId}
onSubmit={() => setOptionToEdit(null)}
parentId={watch("id") ?? ""}
/>
</div> </div>
</div> </div>
</div> </div>

View File

@ -11,11 +11,14 @@ import { MoreHorizontal } from "lucide-react";
import { ICustomAttribute } from "types"; import { ICustomAttribute } from "types";
type Props = { type Props = {
handleEditOption: () => void;
objectId: string; objectId: string;
option: ICustomAttribute; option: ICustomAttribute;
}; };
export const SelectOption: React.FC<Props> = observer(({ objectId, option }) => { export const SelectOption: React.FC<Props> = observer((props) => {
const { handleEditOption, objectId, option } = props;
const router = useRouter(); const router = useRouter();
const { workspaceSlug } = router.query; const { workspaceSlug } = router.query;
@ -82,7 +85,7 @@ export const SelectOption: React.FC<Props> = observer(({ objectId, option }) =>
</div> </div>
} }
> >
<CustomMenu.MenuItem>Edit</CustomMenu.MenuItem> <CustomMenu.MenuItem onClick={handleEditOption}>Edit</CustomMenu.MenuItem>
<CustomMenu.MenuItem onClick={handleDeleteOption}>Delete</CustomMenu.MenuItem> <CustomMenu.MenuItem onClick={handleDeleteOption}>Delete</CustomMenu.MenuItem>
</CustomMenu> </CustomMenu>
</div> </div>