+ {row._rowy_ref.path}
+
+ >
+ ),
+ confirm: "Duplicate",
+ handleConfirm: _duplicate,
+ });
+ }
+ };
+ const handleDelete = () => {
+ const _delete = () =>
+ deleteRow({
+ path: row._rowy_ref.path,
+ options: row._rowy_arrayTableData,
+ });
+
+ if (altPress || row._rowy_arrayTableData !== undefined) {
+ _delete();
+ } else {
+ confirm({
+ title: "Delete row?",
+ body: (
+ <>
+ Row path:
+
+ {row._rowy_ref.path}
+
+ >
+ ),
+ confirm: "Delete",
+ confirmColor: "error",
+ handleConfirm: _delete,
+ });
+ }
};
- const handleDelete = () => deleteRow(row._rowy_ref.path);
const rowActions: IContextMenuItem[] = [
{
label: "Copy ID",
@@ -112,51 +178,14 @@ export default function MenuContents({ onClose }: IMenuContentsProps) {
disabled:
tableSettings.tableType === "collectionGroup" ||
(!userRoles.includes("ADMIN") && tableSettings.readOnly),
- onClick: altPress
- ? handleDuplicate
- : () => {
- confirm({
- title: "Duplicate row?",
- body: (
- <>
- Row path:
-
- {row._rowy_ref.path}
-
- >
- ),
- confirm: "Duplicate",
- handleConfirm: handleDuplicate,
- });
- onClose();
- },
+ onClick: handleDuplicate,
},
{
label: altPress ? "Delete" : "Delete…",
color: "error",
icon:
- {row._rowy_ref.path}
-
- >
- ),
- confirm: "Delete",
- confirmColor: "error",
- handleConfirm: handleDelete,
- });
- onClose();
- },
+ onClick: handleDelete,
},
];
diff --git a/src/components/Table/EmptyTable.tsx b/src/components/Table/EmptyTable.tsx
index f07839b3..1f14e2db 100644
--- a/src/components/Table/EmptyTable.tsx
+++ b/src/components/Table/EmptyTable.tsx
@@ -34,7 +34,7 @@ export default function EmptyTable() {
: false;
let contents = <>>;
- if (hasData) {
+ if (!tableSettings.isNotACollection && hasData) {
contents = (
<>
{tableSettings.collection}
+
+ {tableSettings.collection}
+ {tableSettings.subTableKey?.length &&
+ `.${tableSettings.subTableKey}`}
+
+ {row.original._rowy_ref.path}
+
+ >
+ ),
+ confirm: "Delete",
+ confirmColor: "error",
+ handleConfirm: _delete,
+ });
+ }
+ };
+
const handleDuplicate = () => {
- addRow({
- row: row.original,
- setId: addRowIdType === "custom" ? "decrement" : addRowIdType,
- });
+ const _duplicate = () => {
+ if (row.original._rowy_arrayTableData !== undefined) {
+ if (!updateRowDb) return;
+
+ return updateRowDb("", {}, undefined, {
+ index: row.original._rowy_arrayTableData.index,
+ operation: {
+ addRow: "bottom",
+ base: row.original,
+ },
+ });
+ }
+ return addRow({
+ row: row.original,
+ setId: addRowIdType === "custom" ? "decrement" : addRowIdType,
+ });
+ };
+ if (altPress || row.original._rowy_arrayTableData !== undefined) {
+ _duplicate();
+ } else {
+ confirm({
+ title: "Duplicate row?",
+ body: (
+ <>
+ Row path:
+
+ {row.original._rowy_ref.path}
+
+ >
+ ),
+ confirm: "Duplicate",
+ handleConfirm: _duplicate,
+ });
+ }
};
if (!userRoles.includes("ADMIN") && tableSettings.readOnly === true)
@@ -73,28 +133,7 @@ export const FinalColumn = memo(function FinalColumn({
size="small"
color="inherit"
disabled={tableSettings.tableType === "collectionGroup"}
- onClick={
- altPress
- ? handleDuplicate
- : () => {
- confirm({
- title: "Duplicate row?",
- body: (
- <>
- Row path:
-
- {row.original._rowy_ref.path}
-
- >
- ),
- confirm: "Duplicate",
- handleConfirm: handleDuplicate,
- });
- }
- }
+ onClick={handleDuplicate}
className="row-hover-iconButton"
tabIndex={focusInsideCell ? 0 : -1}
>
@@ -106,29 +145,7 @@ export const FinalColumn = memo(function FinalColumn({
- {row.original._rowy_ref.path}
-
- >
- ),
- confirm: "Delete",
- confirmColor: "error",
- handleConfirm: handleDelete,
- });
- }
- }
+ onClick={handleDelete}
className="row-hover-iconButton"
tabIndex={focusInsideCell ? 0 : -1}
sx={{
diff --git a/src/components/Table/TableBody.tsx b/src/components/Table/TableBody.tsx
index 8dd53d73..edaed491 100644
--- a/src/components/Table/TableBody.tsx
+++ b/src/components/Table/TableBody.tsx
@@ -102,7 +102,10 @@ export const TableBody = memo(function TableBody({
const isSelectedCell =
selectedCell?.path === row.original._rowy_ref.path &&
- selectedCell?.columnKey === cell.column.id;
+ selectedCell?.columnKey === cell.column.id &&
+ // if the table is an array sub table, we need to check the array index as well
+ selectedCell?.arrayIndex ===
+ row.original._rowy_arrayTableData?.index;
const fieldTypeGroup = getFieldProp(
"group",
diff --git a/src/components/Table/TableCell/EditorCellController.tsx b/src/components/Table/TableCell/EditorCellController.tsx
index c80380d4..cacc8946 100644
--- a/src/components/Table/TableCell/EditorCellController.tsx
+++ b/src/components/Table/TableCell/EditorCellController.tsx
@@ -66,6 +66,7 @@ export default function EditorCellController({
fieldName: props.column.fieldName,
value: localValueRef.current,
deleteField: localValueRef.current === undefined,
+ arrayTableData: props.row?._rowy_arrayTableData,
});
} catch (e) {
enqueueSnackbar((e as Error).message, { variant: "error" });
diff --git a/src/components/Table/TableCell/TableCell.tsx b/src/components/Table/TableCell/TableCell.tsx
index 4ea51433..5c664b35 100644
--- a/src/components/Table/TableCell/TableCell.tsx
+++ b/src/components/Table/TableCell/TableCell.tsx
@@ -123,6 +123,7 @@ export const TableCell = memo(function TableCell({
focusInsideCell,
setFocusInsideCell: (focusInside: boolean) =>
setSelectedCell({
+ arrayIndex: row.original._rowy_arrayTableData?.index,
path: row.original._rowy_ref.path,
columnKey: cell.column.id,
focusInside,
@@ -166,6 +167,7 @@ export const TableCell = memo(function TableCell({
}}
onClick={(e) => {
setSelectedCell({
+ arrayIndex: row.original._rowy_arrayTableData?.index,
path: row.original._rowy_ref.path,
columnKey: cell.column.id,
focusInside: false,
@@ -174,6 +176,7 @@ export const TableCell = memo(function TableCell({
}}
onDoubleClick={(e) => {
setSelectedCell({
+ arrayIndex: row.original._rowy_arrayTableData?.index,
path: row.original._rowy_ref.path,
columnKey: cell.column.id,
focusInside: true,
@@ -183,6 +186,7 @@ export const TableCell = memo(function TableCell({
onContextMenu={(e) => {
e.preventDefault();
setSelectedCell({
+ arrayIndex: row.original._rowy_arrayTableData?.index,
path: row.original._rowy_ref.path,
columnKey: cell.column.id,
focusInside: false,
diff --git a/src/components/Table/useKeyboardNavigation.tsx b/src/components/Table/useKeyboardNavigation.tsx
index 3353d23f..81141a77 100644
--- a/src/components/Table/useKeyboardNavigation.tsx
+++ b/src/components/Table/useKeyboardNavigation.tsx
@@ -128,6 +128,11 @@ export function useKeyboardNavigation({
? tableRows[newRowIndex]._rowy_ref.path
: "_rowy_header",
columnKey: leafColumns[newColIndex].id! || leafColumns[0].id!,
+ arrayIndex:
+ newRowIndex > -1
+ ? tableRows[newRowIndex]._rowy_arrayTableData?.index
+ : undefined,
+
// When selected cell changes, exit current cell
focusInside: false,
};
diff --git a/src/components/Table/useMenuAction.tsx b/src/components/Table/useMenuAction.tsx
index 516124d3..49cdc2d8 100644
--- a/src/components/Table/useMenuAction.tsx
+++ b/src/components/Table/useMenuAction.tsx
@@ -71,6 +71,9 @@ export function useMenuAction(
fieldName: selectedCol.fieldName,
value: undefined,
deleteField: true,
+ arrayTableData: {
+ index: selectedCell.arrayIndex ?? 0,
+ },
});
} catch (error) {
enqueueSnackbar(`Failed to cut: ${error}`, { variant: "error" });
@@ -115,6 +118,9 @@ export function useMenuAction(
path: selectedCell.path,
fieldName: selectedCol.fieldName,
value: parsed,
+ arrayTableData: {
+ index: selectedCell.arrayIndex ?? 0,
+ },
});
} catch (error) {
enqueueSnackbar(
@@ -130,7 +136,14 @@ export function useMenuAction(
const selectedCol = tableSchema.columns?.[selectedCell.columnKey];
if (!selectedCol) return setCellValue("");
setSelectedCol(selectedCol);
- const selectedRow = find(tableRows, ["_rowy_ref.path", selectedCell.path]);
+
+ const selectedRow = find(
+ tableRows,
+ selectedCell.arrayIndex === undefined
+ ? ["_rowy_ref.path", selectedCell.path]
+ : // if the table is an array table, we need to use the array index to find the row
+ ["_rowy_arrayTableData.index", selectedCell.arrayIndex]
+ );
setCellValue(get(selectedRow, selectedCol.fieldName));
}, [selectedCell, tableSchema, tableRows]);
@@ -149,7 +162,7 @@ export function useMenuAction(
}
};
},
- [selectedCol]
+ [enqueueSnackbar, selectedCol?.type]
);
return {
diff --git a/src/components/TableToolbar/AddRow.tsx b/src/components/TableToolbar/AddRow.tsx
index c6372865..13e24cd5 100644
--- a/src/components/TableToolbar/AddRow.tsx
+++ b/src/components/TableToolbar/AddRow.tsx
@@ -27,6 +27,7 @@ import {
tableFiltersAtom,
tableSortsAtom,
addRowAtom,
+ _updateRowDbAtom,
} from "@src/atoms/tableScope";
export default function AddRow() {
@@ -207,3 +208,88 @@ export default function AddRow() {
>
);
}
+
+export function AddRowArraySubTable() {
+ const [updateRowDb] = useAtom(_updateRowDbAtom, tableScope);
+ const [open, setOpen] = useState(false);
+
+ const anchorEl = useRef