Implement local state editting when creating new element

This commit is contained in:
pmoharana-cmd 2025-01-04 13:16:23 -05:00
parent 1f1658c708
commit 78170f7553
3 changed files with 100 additions and 42 deletions

View File

@ -10,7 +10,7 @@ import { Details } from "./Drawer";
type CreateDrawerProps = {
details: Details[];
onCreate: (newItem: any) => void;
onCreate: (newItem: any) => boolean;
};
const CreateDrawer: FunctionComponent<CreateDrawerProps> = ({
@ -31,10 +31,20 @@ const CreateDrawer: FunctionComponent<CreateDrawerProps> = ({
}));
};
const initializeSelectField = (key: string) => {
if (!newItemContent[key]) {
setNewItemContent((prev: any) => ({
...prev,
[key]: [],
}));
}
};
const handleCreate = () => {
onCreate(newItemContent);
setNewItemContent({});
setIsOpen(false);
if (onCreate(newItemContent)) {
setNewItemContent({});
setIsOpen(false);
}
};
const toggleDrawer = () => {
@ -93,6 +103,7 @@ const CreateDrawer: FunctionComponent<CreateDrawerProps> = ({
switch (detail.inputType) {
case "select-one":
case "select-multiple":
initializeSelectField(detail.key);
inputField = (
<TagsInput
presetValue={[]}
@ -103,6 +114,17 @@ const CreateDrawer: FunctionComponent<CreateDrawerProps> = ({
detail.presetOptionsSetter ||
(() => {})
}
onTagsChange={(
tags: Set<string>
) => {
setNewItemContent(
(prev: any) => ({
...prev,
[detail.key]:
Array.from(tags),
})
);
}}
/>
);
break;

View File

@ -29,6 +29,25 @@ type TableProps<T extends DataPoint> = {
details: Details[];
};
/** Validates that all required fields in a new item have values */
const validateNewItem = (newItem: any, details: Details[]): boolean => {
const hasEmptyFields = details.some((detail) => {
const value = newItem[detail.key];
return (
value === undefined ||
value === null ||
value === "" ||
(Array.isArray(value) && value.length === 0)
);
});
if (hasEmptyFields) {
alert("Please fill in all fields before creating a new item");
return false;
}
return true;
};
/** Fuzzy search function */
const fuzzyFilter = (
row: Row<any>,
@ -60,39 +79,39 @@ export default function Table<T extends DataPoint>({
}: TableProps<T>) {
const columnHelper = createColumnHelper<T>();
/** Sorting function based on visibility */
const visibilitySort = (a: T, b: T) =>
a.visible === b.visible ? 0 : a.visible ? -1 : 1;
// /** Sorting function based on visibility */
// const visibilitySort = (a: T, b: T) =>
// a.visible === b.visible ? 0 : a.visible ? -1 : 1;
// Sort data on load
useEffect(() => {
setData((prevData) => prevData.sort(visibilitySort));
}, [setData]);
// // Sort data on load
// useEffect(() => {
// setData((prevData) => prevData.sort(visibilitySort));
// }, [setData]);
// Data manipulation methods
// TODO: Connect data manipulation methods to the database (deleteData, hideData, addData)
const deleteData = (dataId: number) => {
console.log(data);
setData((currentData) =>
currentData.filter((data) => data.id !== dataId)
);
};
// // Data manipulation methods
// // TODO: Connect data manipulation methods to the database (deleteData, hideData, addData)
// const deleteData = (dataId: number) => {
// console.log(data);
// setData((currentData) =>
// currentData.filter((data) => data.id !== dataId)
// );
// };
const hideData = (dataId: number) => {
console.log(`Toggling visibility for data with ID: ${dataId}`);
setData((currentData) => {
const newData = currentData
.map((data) =>
data.id === dataId
? { ...data, visible: !data.visible }
: data
)
.sort(visibilitySort);
// const hideData = (dataId: number) => {
// console.log(`Toggling visibility for data with ID: ${dataId}`);
// setData((currentData) => {
// const newData = currentData
// .map((data) =>
// data.id === dataId
// ? { ...data, visible: !data.visible }
// : data
// )
// .sort(visibilitySort);
console.log(newData);
return newData;
});
};
// console.log(newData);
// return newData;
// });
// };
const addData = () => {
setData([...data]);
@ -104,8 +123,10 @@ export default function Table<T extends DataPoint>({
id: "options",
cell: (props) => (
<RowOptionMenu
onDelete={() => deleteData(props.row.original.id)}
onHide={() => hideData(props.row.original.id)}
onDelete={() => {}}
onHide={() => {}}
// onDelete={() => deleteData(props.row.original.id)}
// onHide={() => hideData(props.row.original.id)}
/>
),
})
@ -217,7 +238,15 @@ export default function Table<T extends DataPoint>({
>
<CreateDrawer
details={details}
onCreate={(newItem) => {}}
onCreate={(newItem) => {
if (!validateNewItem(newItem, details)) {
return false;
}
newItem.visible = true;
setData((prev) => [...prev, newItem]);
return true;
}}
/>
</td>
</tr>

View File

@ -8,12 +8,14 @@ interface TagsInputProps {
presetOptions: string[];
presetValue: string[];
setPresetOptions: Dispatch<SetStateAction<string[]>>;
onTagsChange?: (tags: Set<string>) => void;
}
const TagsInput: React.FC<TagsInputProps> = ({
presetValue,
presetOptions,
setPresetOptions,
onTagsChange,
}) => {
const [inputValue, setInputValue] = useState("");
const [cellSelected, setCellSelected] = useState(false);
@ -70,23 +72,28 @@ const TagsInput: React.FC<TagsInputProps> = ({
const addTag = (e?: React.KeyboardEvent<HTMLInputElement>) => {
e?.stopPropagation();
const newTags = new Set(Array.from(tags).concat(inputValue));
setOptions(new Set(Array.from(options).concat(inputValue)));
setTags(new Set(Array.from(tags).concat(inputValue)));
setTags(newTags);
setFilteredOptions(new Set(Array.from(options).concat(inputValue)));
setInputValue("");
onTagsChange?.(newTags);
};
const handleSelectTag = (tagToAdd: string) => {
console.log(tagToAdd);
console.log(tags);
if (!tags.has(tagToAdd)) {
setTags(new Set(Array.from(tags).concat(tagToAdd)));
const newTags = new Set(Array.from(tags).concat(tagToAdd));
setTags(newTags);
onTagsChange?.(newTags);
}
};
const handleDeleteTag = (tagToDelete: string) => {
setTags(new Set(Array.from(tags).filter((tag) => tag !== tagToDelete)));
const newTags = new Set(
Array.from(tags).filter((tag) => tag !== tagToDelete)
);
setTags(newTags);
onTagsChange?.(newTags);
};
const handleDeleteTagOption = (tagToDelete: string) => {