mirror of
https://github.com/rowyio/rowy.git
synced 2025-12-29 00:16:39 +01:00
support read-only tables (#577)
This commit is contained in:
@@ -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={
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 ? (
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
});
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -32,6 +32,7 @@ export type Table = {
|
||||
audit?: boolean;
|
||||
auditFieldCreatedBy?: string;
|
||||
auditFieldUpdatedBy?: string;
|
||||
readOnly?: boolean;
|
||||
};
|
||||
|
||||
interface IRowyRun
|
||||
|
||||
@@ -108,6 +108,7 @@ export const colorsLight = (
|
||||
MuiTooltip: {
|
||||
styleOverrides: {
|
||||
tooltip: { backgroundColor: tooltip.toHslString() },
|
||||
arrow: { color: tooltip.toHslString() },
|
||||
},
|
||||
},
|
||||
MuiSlider: {
|
||||
|
||||
Reference in New Issue
Block a user