2022-05-19 16:37:56 +10:00
|
|
|
import { useState, useRef } from "react";
|
|
|
|
|
import { useAtom, useSetAtom } from "jotai";
|
|
|
|
|
import { FieldType, FormDialog } from "@rowy/form-builder";
|
|
|
|
|
|
|
|
|
|
import {
|
|
|
|
|
Button,
|
|
|
|
|
ButtonGroup,
|
|
|
|
|
Select,
|
|
|
|
|
MenuItem,
|
|
|
|
|
ListItemText,
|
|
|
|
|
Box,
|
|
|
|
|
} from "@mui/material";
|
2022-06-13 18:24:20 +10:00
|
|
|
import {
|
|
|
|
|
AddRow as AddRowIcon,
|
|
|
|
|
AddRowTop as AddRowTopIcon,
|
|
|
|
|
ChevronDown as ArrowDropDownIcon,
|
|
|
|
|
} from "@src/assets/icons";
|
2022-05-19 16:37:56 +10:00
|
|
|
|
|
|
|
|
import {
|
|
|
|
|
globalScope,
|
|
|
|
|
userRolesAtom,
|
|
|
|
|
tableAddRowIdTypeAtom,
|
|
|
|
|
} from "@src/atoms/globalScope";
|
|
|
|
|
import {
|
|
|
|
|
tableScope,
|
|
|
|
|
tableSettingsAtom,
|
2022-06-13 18:24:20 +10:00
|
|
|
tableFiltersAtom,
|
2022-06-13 23:10:15 +10:00
|
|
|
tableSortsAtom,
|
2022-05-19 16:37:56 +10:00
|
|
|
addRowAtom,
|
|
|
|
|
} from "@src/atoms/tableScope";
|
|
|
|
|
|
|
|
|
|
export default function AddRow() {
|
|
|
|
|
const [userRoles] = useAtom(userRolesAtom, globalScope);
|
|
|
|
|
const [tableSettings] = useAtom(tableSettingsAtom, tableScope);
|
2022-06-13 18:24:20 +10:00
|
|
|
const [tableFilters] = useAtom(tableFiltersAtom, tableScope);
|
2022-06-13 23:10:15 +10:00
|
|
|
const [tableSorts] = useAtom(tableSortsAtom, tableScope);
|
2022-05-19 16:37:56 +10:00
|
|
|
const addRow = useSetAtom(addRowAtom, tableScope);
|
|
|
|
|
const [idType, setIdType] = useAtom(tableAddRowIdTypeAtom, globalScope);
|
|
|
|
|
|
|
|
|
|
const anchorEl = useRef<HTMLDivElement>(null);
|
|
|
|
|
const [open, setOpen] = useState(false);
|
|
|
|
|
const [openIdModal, setOpenIdModal] = useState(false);
|
|
|
|
|
|
2022-06-13 23:10:15 +10:00
|
|
|
const forceRandomId = tableFilters.length > 0 || tableSorts.length > 0;
|
2022-06-13 18:24:20 +10:00
|
|
|
|
2022-05-19 16:37:56 +10:00
|
|
|
const handleClick = () => {
|
2022-06-13 18:24:20 +10:00
|
|
|
if (idType === "random" || (forceRandomId && idType === "decrement")) {
|
2022-05-19 16:37:56 +10:00
|
|
|
addRow({
|
|
|
|
|
row: {
|
|
|
|
|
_rowy_ref: {
|
2022-06-13 18:24:20 +10:00
|
|
|
id: "random",
|
|
|
|
|
path: tableSettings.collection + "/random",
|
2022-05-19 16:37:56 +10:00
|
|
|
},
|
|
|
|
|
},
|
2022-06-13 18:24:20 +10:00
|
|
|
setId: "random",
|
2022-05-19 16:37:56 +10:00
|
|
|
});
|
2022-06-13 18:24:20 +10:00
|
|
|
} else if (idType === "decrement") {
|
2022-05-19 16:37:56 +10:00
|
|
|
addRow({
|
|
|
|
|
row: {
|
|
|
|
|
_rowy_ref: {
|
2022-06-13 18:24:20 +10:00
|
|
|
id: "decrement",
|
|
|
|
|
path: tableSettings.collection + "/decrement",
|
2022-05-19 16:37:56 +10:00
|
|
|
},
|
|
|
|
|
},
|
2022-06-13 18:24:20 +10:00
|
|
|
setId: "decrement",
|
2022-05-19 16:37:56 +10:00
|
|
|
});
|
|
|
|
|
} else if (idType === "custom") {
|
|
|
|
|
setOpenIdModal(true);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if (tableSettings.readOnly && !userRoles.includes("ADMIN"))
|
|
|
|
|
return <Box sx={{ mr: -2 }} />;
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<>
|
|
|
|
|
<ButtonGroup
|
|
|
|
|
variant="contained"
|
|
|
|
|
color="primary"
|
|
|
|
|
aria-label="Split button"
|
|
|
|
|
ref={anchorEl}
|
|
|
|
|
disabled={tableSettings.tableType === "collectionGroup" || !addRow}
|
|
|
|
|
>
|
|
|
|
|
<Button
|
|
|
|
|
variant="contained"
|
|
|
|
|
color="primary"
|
|
|
|
|
onClick={handleClick}
|
2022-06-13 18:24:20 +10:00
|
|
|
startIcon={
|
|
|
|
|
idType === "decrement" && !forceRandomId ? (
|
|
|
|
|
<AddRowTopIcon />
|
|
|
|
|
) : (
|
|
|
|
|
<AddRowIcon />
|
|
|
|
|
)
|
|
|
|
|
}
|
2022-05-19 16:37:56 +10:00
|
|
|
>
|
|
|
|
|
Add row{idType === "custom" ? "…" : ""}
|
|
|
|
|
</Button>
|
|
|
|
|
|
|
|
|
|
<Button
|
|
|
|
|
variant="contained"
|
|
|
|
|
color="primary"
|
|
|
|
|
aria-label="Select row add position"
|
|
|
|
|
aria-haspopup="menu"
|
|
|
|
|
style={{ padding: 0 }}
|
|
|
|
|
onClick={() => setOpen(true)}
|
|
|
|
|
id="add-row-menu-button"
|
|
|
|
|
aria-controls={open ? "add-row-menu" : undefined}
|
|
|
|
|
aria-expanded={open ? "true" : "false"}
|
|
|
|
|
>
|
|
|
|
|
<ArrowDropDownIcon />
|
|
|
|
|
</Button>
|
|
|
|
|
</ButtonGroup>
|
|
|
|
|
|
|
|
|
|
<Select
|
|
|
|
|
id="add-row-menu"
|
|
|
|
|
open={open}
|
|
|
|
|
onClose={() => setOpen(false)}
|
|
|
|
|
label="Row add position"
|
|
|
|
|
style={{ display: "none" }}
|
2022-06-13 18:24:20 +10:00
|
|
|
value={forceRandomId && idType === "decrement" ? "random" : idType}
|
2022-05-19 16:37:56 +10:00
|
|
|
onChange={(e) => setIdType(e.target.value as typeof idType)}
|
|
|
|
|
MenuProps={{
|
|
|
|
|
anchorEl: anchorEl.current,
|
|
|
|
|
MenuListProps: { "aria-labelledby": "add-row-menu-button" },
|
2022-06-13 18:24:20 +10:00
|
|
|
anchorOrigin: { horizontal: "left", vertical: "bottom" },
|
|
|
|
|
transformOrigin: { horizontal: "left", vertical: "top" },
|
2022-05-19 16:37:56 +10:00
|
|
|
}}
|
|
|
|
|
>
|
2022-06-13 18:24:20 +10:00
|
|
|
<MenuItem value="decrement" disabled={forceRandomId}>
|
2022-05-19 16:37:56 +10:00
|
|
|
<ListItemText
|
2022-06-13 18:24:20 +10:00
|
|
|
primary="To top"
|
2022-05-19 16:37:56 +10:00
|
|
|
secondary="Generates a smaller ID so the new row will appear on the top"
|
|
|
|
|
secondaryTypographyProps={{ variant: "caption" }}
|
|
|
|
|
/>
|
|
|
|
|
</MenuItem>
|
2022-06-13 18:24:20 +10:00
|
|
|
<MenuItem value="random">
|
|
|
|
|
<ListItemText
|
|
|
|
|
primary="With random ID"
|
|
|
|
|
secondary={
|
|
|
|
|
"Temporarily displays the new row on the top for editing,\nbut will appear in a different position afterwards"
|
|
|
|
|
}
|
|
|
|
|
secondaryTypographyProps={{
|
|
|
|
|
variant: "caption",
|
|
|
|
|
whiteSpace: "pre-line",
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
</MenuItem>
|
2022-05-19 16:37:56 +10:00
|
|
|
<MenuItem value="custom">
|
|
|
|
|
<ListItemText
|
2022-06-13 18:24:20 +10:00
|
|
|
primary="With custom ID…"
|
2022-05-19 16:37:56 +10:00
|
|
|
secondary={
|
|
|
|
|
"Temporarily displays the new row on the top for editing,\nbut will appear in a different position afterwards"
|
|
|
|
|
}
|
|
|
|
|
secondaryTypographyProps={{
|
|
|
|
|
variant: "caption",
|
|
|
|
|
whiteSpace: "pre-line",
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
</MenuItem>
|
|
|
|
|
</Select>
|
|
|
|
|
|
|
|
|
|
{openIdModal && (
|
|
|
|
|
<FormDialog
|
|
|
|
|
title="Add row with custom ID"
|
|
|
|
|
fields={[
|
|
|
|
|
{
|
|
|
|
|
type: FieldType.shortText,
|
|
|
|
|
name: "id",
|
|
|
|
|
label: "Custom ID",
|
|
|
|
|
required: true,
|
|
|
|
|
autoFocus: true,
|
|
|
|
|
// Disable validation to make it compatible with non-Firestore
|
|
|
|
|
// databases. If a user adds a row with an existing ID, it will
|
|
|
|
|
// update that document.
|
|
|
|
|
// validation: [
|
|
|
|
|
// [
|
|
|
|
|
// "test",
|
|
|
|
|
// "existing-id",
|
|
|
|
|
// "A row with this ID already exists",
|
|
|
|
|
// async (value) =>
|
|
|
|
|
// value &&
|
|
|
|
|
// (
|
|
|
|
|
// await db
|
|
|
|
|
// .collection(tableState!.tablePath!)
|
|
|
|
|
// .doc(value)
|
|
|
|
|
// .get()
|
|
|
|
|
// ).exists === false,
|
|
|
|
|
// ],
|
|
|
|
|
// ],
|
|
|
|
|
},
|
|
|
|
|
]}
|
|
|
|
|
onSubmit={(v) =>
|
|
|
|
|
addRow({
|
|
|
|
|
row: {
|
|
|
|
|
_rowy_ref: {
|
|
|
|
|
id: v.id,
|
|
|
|
|
path: tableSettings.collection + "/" + v.id,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
onClose={() => setOpenIdModal(false)}
|
|
|
|
|
DialogProps={{ maxWidth: "xs" }}
|
|
|
|
|
SubmitButtonProps={{ children: "Add row" }}
|
|
|
|
|
/>
|
|
|
|
|
)}
|
|
|
|
|
</>
|
|
|
|
|
);
|
|
|
|
|
}
|