support read-only tables (#577)

This commit is contained in:
Sidney Alcantara
2021-12-17 18:02:52 +11:00
parent c1694e3d6f
commit c6629dc4c7
11 changed files with 132 additions and 39 deletions

View File

@@ -15,6 +15,7 @@ import {
import ArrowRightIcon from "@mui/icons-material/ChevronRight";
import InfoIcon from "@mui/icons-material/InfoOutlined";
import CloseIcon from "@mui/icons-material/Close";
import ReadOnlyIcon from "@mui/icons-material/EditOffOutlined";
import { useProjectContext } from "@src/contexts/ProjectContext";
import useRouter from "@src/hooks/useRouter";
@@ -90,6 +91,11 @@ export default function Breadcrumbs({ sx = [], ...props }: BreadcrumbsProps) {
<Typography {...crumbProps}>
{getLabel(crumb) || crumb.replace(/([A-Z])/g, " $1")}
</Typography>
{crumb === table?.id && table?.readOnly && (
<Tooltip title="Table is read-only">
<ReadOnlyIcon fontSize="small" sx={{ ml: 0.5 }} />
</Tooltip>
)}
{crumb === table?.id && table?.description && (
<Tooltip
title={

View File

@@ -72,7 +72,8 @@ export interface IMenuModalProps {
export default function ColumnMenu() {
const [modal, setModal] = useState(INITIAL_MODAL);
const { tableState, tableActions, columnMenuRef } = useProjectContext();
const { table, tableState, tableActions, columnMenuRef } =
useProjectContext();
const { requestConfirmation } = useConfirmation();
const [selectedColumnHeader, setSelectedColumnHeader] = useState<any>(null);
@@ -135,17 +136,26 @@ export default function ColumnMenu() {
};
const menuItems = [
{ type: "subheader" },
{
label: "Lock",
activeLabel: "Unlock",
icon: <LockOpenIcon />,
activeIcon: <LockIcon />,
onClick: () => {
actions.update(column.key, { editable: !column.editable });
handleClose();
},
active: !column.editable,
},
table?.readOnly
? {
label: "Locked  read-only table",
activeLabel: "Locked  read-only table",
icon: <LockIcon />,
activeIcon: <LockIcon />,
active: true,
disabled: true,
}
: {
label: "Lock",
activeLabel: "Unlock",
icon: <LockOpenIcon />,
activeIcon: <LockIcon />,
onClick: () => {
actions.update(column.key, { editable: !column.editable });
handleClose();
},
active: !column.editable,
},
{
label: "Freeze",
activeLabel: "Unfreeze",

View File

@@ -1,7 +1,7 @@
import { Column } from "react-data-grid";
import { makeStyles, createStyles } from "@mui/styles";
import { Grid, Button } from "@mui/material";
import { Grid, Button, Tooltip } from "@mui/material";
import AddColumnIcon from "@src/assets/icons/AddColumn";
import { useProjectContext } from "@src/contexts/ProjectContext";
@@ -44,7 +44,7 @@ const useStyles = makeStyles((theme) =>
const FinalColumnHeader: Column<any>["headerRenderer"] = ({ column }) => {
const classes = useStyles();
const { columnMenuRef } = useProjectContext();
const { columnMenuRef, table } = useProjectContext();
if (!columnMenuRef) return null;
const handleClick = (
@@ -62,15 +62,30 @@ const FinalColumnHeader: Column<any>["headerRenderer"] = ({ column }) => {
justifyContent="center"
className={classes.root}
>
<Button
onClick={handleClick}
variant="contained"
color="primary"
className={classes.button}
startIcon={<AddColumnIcon />}
>
Add column
</Button>
{table?.readOnly ? (
<Tooltip title="Table is read-only">
<div>
<Button
disabled
variant="contained"
color="primary"
startIcon={<AddColumnIcon />}
>
Add column
</Button>
</div>
</Tooltip>
) : (
<Button
onClick={handleClick}
variant="contained"
color="primary"
className={classes.button}
startIcon={<AddColumnIcon />}
>
Add column
</Button>
)}
</Grid>
);
};

View File

@@ -28,11 +28,15 @@ export default function FinalColumn({ row }: FormatterProps<any, any>) {
useStyles();
const { requestConfirmation } = useConfirmation();
const { deleteRow, addRow } = useProjectContext();
const { deleteRow, addRow, table } = useProjectContext();
const altPress = useKeyPress("Alt");
const handleDelete = () => {
if (deleteRow) deleteRow(row.id);
};
if (table?.readOnly) return null;
return (
<Stack direction="row" spacing={0.5}>
<Tooltip title="Duplicate row">

View File

@@ -43,8 +43,14 @@ const rowClass = (row: any) => (row._rowy_outOfOrder ? "out-of-order" : "");
//const SelectColumn = { ..._SelectColumn, width: 42, maxWidth: 42 };
export default function Table() {
const { tableState, tableActions, dataGridRef, sideDrawerRef, updateCell } =
useProjectContext();
const {
table,
tableState,
tableActions,
dataGridRef,
sideDrawerRef,
updateCell,
} = useProjectContext();
const { userDoc } = useAppContext();
const userDocHiddenFields =
@@ -63,7 +69,6 @@ export default function Table() {
)
.map((column: any) => ({
draggable: true,
editable: true,
resizable: true,
frozen: column.fixed,
headerRenderer: ColumnHeader,
@@ -84,6 +89,7 @@ export default function Table() {
return null;
},
...column,
editable: table?.readOnly ? false : column.editable ?? true,
width: (column.width as number)
? (column.width as number) > 380
? 380

View File

@@ -8,6 +8,7 @@ import {
Select,
MenuItem,
ListItemText,
Tooltip,
} from "@mui/material";
import AddRowIcon from "@src/assets/icons/AddRow";
import ArrowDropDownIcon from "@mui/icons-material/ArrowDropDown";
@@ -19,7 +20,7 @@ import { db } from "@src/firebase";
const useIdTypeState = createPersistedState("__ROWY__ADD_ROW_ID_TYPE");
export default function AddRow() {
const { addRow, tableState } = useProjectContext();
const { addRow, table, tableState } = useProjectContext();
const anchorEl = useRef<HTMLDivElement>(null);
const [open, setOpen] = useState(false);
@@ -38,6 +39,37 @@ export default function AddRow() {
}
};
if (table?.readOnly)
return (
<Tooltip title="Table is read-only">
<div>
<ButtonGroup
variant="contained"
color="primary"
aria-label="Split button"
disabled
>
<Button
variant="contained"
color="primary"
startIcon={<AddRowIcon />}
>
Add row
</Button>
<Button
variant="contained"
color="primary"
aria-label="Select row add position"
style={{ padding: 0 }}
>
<ArrowDropDownIcon />
</Button>
</ButtonGroup>
</div>
</Tooltip>
);
return (
<>
<ButtonGroup

View File

@@ -29,6 +29,7 @@ import CheckIcon from "@mui/icons-material/CheckCircle";
import ImportCsvWizard, {
IImportCsvWizardProps,
} from "@src/components/Wizards/ImportCsvWizard";
import { useProjectContext } from "@src/contexts/ProjectContext";
const useStyles = makeStyles((theme) =>
createStyles({
@@ -85,6 +86,7 @@ export interface IImportCsvProps {
export default function ImportCsv({ render, PopoverProps }: IImportCsvProps) {
const classes = useStyles();
const { table } = useProjectContext();
const [open, setOpen] = useState<HTMLButtonElement | null>(null);
const [tab, setTab] = useState("upload");
@@ -157,6 +159,11 @@ export default function ImportCsv({ render, PopoverProps }: IImportCsvProps) {
const [openWizard, setOpenWizard] = useState(false);
if (table?.readOnly)
return (
<TableHeaderButton title="Import CSV" icon={<ImportIcon />} disabled />
);
return (
<>
{render ? (

View File

@@ -12,17 +12,19 @@ export const TableHeaderButton = forwardRef(function TableHeaderButton_(
) {
return (
<Tooltip title={title}>
<Button
variant="outlined"
color="secondary"
size="small"
style={{ minWidth: 40, height: 32, padding: 0 }}
aria-label={title}
{...props}
ref={ref}
>
{icon}
</Button>
<div>
<Button
variant="outlined"
color="secondary"
size="small"
style={{ minWidth: 40, height: 32, padding: 0 }}
aria-label={title}
{...props}
ref={ref}
>
{icon}
</Button>
</div>
</Tooltip>
);
});

View File

@@ -207,6 +207,15 @@ export const tableSettings = (
required: true,
freeText: true,
},
{
step: "accessControls",
type: FieldType.checkbox,
name: "readOnly",
label: "Read-only table",
assistiveText:
"Disable all editing functionality. Locks all columns and disables adding and deleting rows and columns.",
defaultValue: false,
},
{
step: "accessControls",
type: FieldType.contentParagraph,

View File

@@ -32,6 +32,7 @@ export type Table = {
audit?: boolean;
auditFieldCreatedBy?: string;
auditFieldUpdatedBy?: string;
readOnly?: boolean;
};
interface IRowyRun

View File

@@ -108,6 +108,7 @@ export const colorsLight = (
MuiTooltip: {
styleOverrides: {
tooltip: { backgroundColor: tooltip.toHslString() },
arrow: { color: tooltip.toHslString() },
},
},
MuiSlider: {