fix: added save button to table component to improve consistency (#6663)
* Added onSave and onCancel to tableModal, in order for it to preserve state
* Changed TableNodeComponent to handle temp values and only change value when saved
* 🔧 (tableModal/index.tsx): refactor handleSetOpen and handleOnEscapeKeyDown functions to improve code readability and maintainability
* Fix test that use tableInput
---------
Co-authored-by: cristhianzl <cristhian.lousa@gmail.com>
This commit is contained in:
parent
b8346a0afa
commit
70bb897a85
3 changed files with 62 additions and 14 deletions
|
|
@ -65,10 +65,12 @@ export default function TableNodeComponent({
|
|||
};
|
||||
}, []);
|
||||
const [selectedNodes, setSelectedNodes] = useState<Array<any>>([]);
|
||||
const [tempValue, setTempValue] = useState<any[]>(cloneDeep(value));
|
||||
const [isModalOpen, setIsModalOpen] = useState(false);
|
||||
const agGrid = useRef<AgGridReact>(null);
|
||||
const componentColumns = columns
|
||||
? columns
|
||||
: generateBackendColumnsFromValue(value ?? [], table_options);
|
||||
: generateBackendColumnsFromValue(tempValue ?? [], table_options);
|
||||
let AgColumns = FormatColumns(componentColumns);
|
||||
// add info to each column
|
||||
AgColumns = AgColumns.map((col) => {
|
||||
|
|
@ -93,7 +95,7 @@ export default function TableNodeComponent({
|
|||
if (agGrid.current && !agGrid.current.api.isDestroyed()) {
|
||||
const rows: any = [];
|
||||
agGrid.current.api.forEachNode((node) => rows.push(node.data));
|
||||
handleOnNewValue({ value: rows });
|
||||
setTempValue(rows);
|
||||
}
|
||||
}
|
||||
function deleteRow() {
|
||||
|
|
@ -109,8 +111,7 @@ export default function TableNodeComponent({
|
|||
if (agGrid.current && selectedNodes.length > 0) {
|
||||
const toDuplicate = selectedNodes.map((node) => cloneDeep(node.data));
|
||||
setSelectedNodes([]);
|
||||
const rows: any = [];
|
||||
handleOnNewValue({ value: [...value, ...toDuplicate] });
|
||||
setTempValue([...tempValue, ...toDuplicate]);
|
||||
}
|
||||
}
|
||||
function addRow() {
|
||||
|
|
@ -118,12 +119,23 @@ export default function TableNodeComponent({
|
|||
componentColumns.forEach((column) => {
|
||||
newRow[column.name] = column.default ?? null; // Use the default value if available
|
||||
});
|
||||
handleOnNewValue({ value: [...value, newRow] });
|
||||
setTempValue([...tempValue, newRow]);
|
||||
}
|
||||
|
||||
function updateComponent() {
|
||||
setAllRows();
|
||||
}
|
||||
|
||||
function handleSave() {
|
||||
handleOnNewValue({ value: tempValue });
|
||||
setIsModalOpen(false);
|
||||
}
|
||||
|
||||
function handleCancel() {
|
||||
setTempValue(cloneDeep(value));
|
||||
setIsModalOpen(false);
|
||||
}
|
||||
|
||||
const editable = componentColumns
|
||||
.map((column) => {
|
||||
const isCustomEdit =
|
||||
|
|
@ -149,6 +161,8 @@ export default function TableNodeComponent({
|
|||
>
|
||||
<div className="flex w-full items-center gap-3" data-testid={"div-" + id}>
|
||||
<TableModal
|
||||
open={isModalOpen}
|
||||
setOpen={setIsModalOpen}
|
||||
stopEditingWhenCellsLoseFocus={true}
|
||||
tableIcon={table_icon}
|
||||
tableOptions={table_options}
|
||||
|
|
@ -169,8 +183,10 @@ export default function TableNodeComponent({
|
|||
displayEmptyAlert={false}
|
||||
className="h-full w-full"
|
||||
columnDefs={AgColumns}
|
||||
rowData={value}
|
||||
rowData={tempValue}
|
||||
context={{ field_parsers: table_options?.field_parsers }}
|
||||
onSave={handleSave}
|
||||
onCancel={handleCancel}
|
||||
>
|
||||
<Button
|
||||
disabled={disabled}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,10 @@ interface TableModalProps extends TableComponentProps {
|
|||
tableOptions?: TableOptionsTypeAPI;
|
||||
hideColumns?: boolean | string[];
|
||||
tableIcon?: string;
|
||||
open?: boolean;
|
||||
setOpen?: (open: boolean) => void;
|
||||
onSave?: () => void;
|
||||
onCancel?: () => void;
|
||||
}
|
||||
|
||||
const TableModal = forwardRef<AgGridReact, TableModalProps>(
|
||||
|
|
@ -25,22 +29,43 @@ const TableModal = forwardRef<AgGridReact, TableModalProps>(
|
|||
children,
|
||||
disabled,
|
||||
tableIcon,
|
||||
open,
|
||||
setOpen,
|
||||
onSave,
|
||||
onCancel,
|
||||
...props
|
||||
}: TableModalProps,
|
||||
ref: ForwardedRef<AgGridReact>,
|
||||
) => {
|
||||
const handleSetOpen = (newOpen: boolean) => {
|
||||
if (!newOpen && onCancel) {
|
||||
onCancel();
|
||||
}
|
||||
if (setOpen) {
|
||||
setOpen(newOpen);
|
||||
}
|
||||
};
|
||||
|
||||
const handleOnEscapeKeyDown = (e: KeyboardEvent) => {
|
||||
const editingCells = (
|
||||
ref as React.RefObject<AgGridReact>
|
||||
)?.current?.api?.getEditingCells();
|
||||
|
||||
if (editingCells && editingCells.length > 0) {
|
||||
e.preventDefault();
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<BaseModal
|
||||
onEscapeKeyDown={(e) => {
|
||||
if (
|
||||
(
|
||||
ref as React.RefObject<AgGridReact>
|
||||
)?.current?.api.getEditingCells().length
|
||||
) {
|
||||
e.preventDefault();
|
||||
}
|
||||
handleOnEscapeKeyDown(e);
|
||||
}}
|
||||
disable={disabled}
|
||||
open={open}
|
||||
setOpen={(newOpen) => {
|
||||
handleSetOpen(newOpen);
|
||||
}}
|
||||
>
|
||||
<BaseModal.Trigger asChild>{children}</BaseModal.Trigger>
|
||||
<BaseModal.Header
|
||||
|
|
@ -59,6 +84,9 @@ const TableModal = forwardRef<AgGridReact, TableModalProps>(
|
|||
{...props}
|
||||
></TableComponent>
|
||||
</BaseModal.Content>
|
||||
<BaseModal.Footer
|
||||
submit={onSave ? { label: "Save", onClick: onSave } : undefined}
|
||||
></BaseModal.Footer>
|
||||
</BaseModal>
|
||||
);
|
||||
},
|
||||
|
|
|
|||
|
|
@ -25,6 +25,10 @@ test(
|
|||
},
|
||||
);
|
||||
|
||||
await page.waitForSelector('[data-testid="zoom_out"]', {
|
||||
timeout: 3000,
|
||||
});
|
||||
|
||||
await page.getByTestId("sidebar-custom-component-button").click();
|
||||
|
||||
await page.getByTestId("zoom_out").click();
|
||||
|
|
@ -164,7 +168,7 @@ class CustomComponent(Component):
|
|||
numberOfCopiedRows = await page.getByText(thirdRandomText).count();
|
||||
expect(numberOfCopiedRows).toBe(0);
|
||||
|
||||
await page.getByText("Close").last().click();
|
||||
await page.getByText("Save").last().click();
|
||||
|
||||
await page.waitForSelector("text=Open table", {
|
||||
timeout: 3000,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue