allow all users to override table filters

This commit is contained in:
Sidney Alcantara
2022-01-28 19:08:35 +11:00
parent f5c0f5a541
commit 8b8bf83d36

View File

@@ -43,6 +43,7 @@ export default function Filters() {
const userDocData = userDoc.state.doc;
const tableSchemaDoc = tableState?.config?.tableConfig?.doc;
const tableFilters = tableSchemaDoc?.filters;
const tableFiltersOverridable = Boolean(tableSchemaDoc?.filtersOverridable);
const userFilters = tableId
? userDocData.tables?.[tableId]?.filters
: undefined;
@@ -64,17 +65,15 @@ export default function Filters() {
? userFilters[0]
: INITIAL_QUERY
);
setCanOverrideCheckbox(tableFiltersOverridable);
if (!tableActions) return;
let filtersToApply: TableFilter[] = [];
// Allow admin to override table-level filters with their own
// Set to null to show all filters for the admin user
if (
userClaims?.roles.includes("ADMIN") &&
(hasUserFilters || userFilters === null)
) {
// Allow override table-level filters with their own
// Set to null to completely ignore table filters
if (tableFiltersOverridable && (hasUserFilters || userFilters === null)) {
filtersToApply = userFilters ?? [];
} else if (hasTableFilters) {
filtersToApply = tableFilters;
@@ -85,7 +84,7 @@ export default function Filters() {
tableActions.table.filter(filtersToApply);
// Reset order so we dont have to make a new index
tableActions.table.orderBy();
}, [tableFilters, userFilters, userClaims?.roles]);
}, [tableFilters, tableFiltersOverridable, userFilters, userClaims?.roles]);
// Helper booleans for local table filter state
const appliedFilters = tableState?.filters || [];
@@ -93,11 +92,14 @@ export default function Filters() {
appliedFilters && appliedFilters.length > 0
);
const tableFiltersOverridden =
userClaims?.roles.includes("ADMIN") &&
(tableFiltersOverridable || userClaims?.roles.includes("ADMIN")) &&
(hasUserFilters || userFilters === null) &&
hasTableFilters;
// ADMIN overrides
// Override table filters
const [canOverrideCheckbox, setCanOverrideCheckbox] = useState(
tableFiltersOverridable
);
const [tab, setTab] = useState<"user" | "table">(
hasTableFilters && !tableFiltersOverridden ? "table" : "user"
);
@@ -108,9 +110,10 @@ export default function Filters() {
// Save table filters to table schema document
const setTableFilters = (filters: TableFilter[]) => {
tableActions?.table.updateConfig("filters", filters);
tableActions?.table.updateConfig("filtersOverridable", canOverrideCheckbox);
};
// Save user filters to user document
// null overrides table filters - only available to ADMINs
// null overrides table filters
const setUserFilters = (filters: TableFilter[] | null) => {
userDoc.dispatch({
action: DocActions.update,
@@ -129,79 +132,225 @@ export default function Filters() {
availableFilters={availableFilters}
setUserFilters={setUserFilters}
>
{({ handleClose }) =>
{({ handleClose }) => {
// ADMIN
userClaims?.roles.includes("ADMIN") ? (
<TabContext value={tab}>
<TabList
onChange={(_, v) => setTab(v)}
variant="fullWidth"
aria-label="Filter tabs"
>
<Tab
label={
<>
Your filter
{tableFiltersOverridden && (
<Badge
aria-label="(overrides table filters)"
color="primary"
variant="inlineDot"
invisible={false}
/>
)}
</>
}
value="user"
style={{ flexDirection: "row" }}
/>
<Tab
label={
<>
Table filter
{tableFiltersOverridden ? (
<Badge
aria-label="(overridden by your filters)"
color="primary"
variant="inlineDot"
invisible={false}
sx={{
"& .MuiBadge-badge": {
bgcolor: "transparent",
border: "1px solid currentColor",
color: "inherit",
},
}}
/>
) : hasTableFilters ? (
<Badge
aria-label="(active)"
color="primary"
variant="inlineDot"
invisible={false}
/>
) : null}
</>
}
value="table"
style={{ flexDirection: "row" }}
/>
</TabList>
<Divider style={{ marginTop: -1 }} />
if (userClaims?.roles.includes("ADMIN")) {
return (
<TabContext value={tab}>
<TabList
onChange={(_, v) => setTab(v)}
variant="fullWidth"
aria-label="Filter tabs"
>
<Tab
label={
<>
Your filter
{tableFiltersOverridden && (
<Badge
aria-label="(overrides table filters)"
color="primary"
variant="inlineDot"
invisible={false}
/>
)}
</>
}
value="user"
style={{ flexDirection: "row" }}
/>
<Tab
label={
<>
Table filter
{tableFiltersOverridden ? (
<Badge
aria-label="(overridden by your filters)"
color="primary"
variant="inlineDot"
invisible={false}
sx={{
"& .MuiBadge-badge": {
bgcolor: "transparent",
border: "1px solid currentColor",
color: "inherit",
},
}}
/>
) : hasTableFilters ? (
<Badge
aria-label="(active)"
color="primary"
variant="inlineDot"
invisible={false}
/>
) : null}
</>
}
value="table"
style={{ flexDirection: "row" }}
/>
</TabList>
<Divider style={{ marginTop: -1 }} />
<TabPanel value="user" className="content">
<TabPanel value="user" className="content">
<FilterInputs {...userFilterInputs} />
{hasTableFilters && (
<FormControlLabel
control={
<Checkbox
checked={overrideTableFilters}
onChange={(e) =>
setOverrideTableFilters(e.target.checked)
}
/>
}
label="Override table filters"
sx={{ justifyContent: "center", mb: 1, mr: 0 }}
/>
)}
<Stack
direction="row"
sx={{ "& .MuiButton-root": { minWidth: 100 } }}
justifyContent="center"
spacing={1}
>
<Button
disabled={
!overrideTableFilters &&
!tableFiltersOverridden &&
userFilterInputs.query.key === ""
}
onClick={() => {
setUserFilters(overrideTableFilters ? null : []);
userFilterInputs.resetQuery();
}}
>
Clear
{overrideTableFilters
? " (ignore table filter)"
: " (use table filter)"}
</Button>
<Button
disabled={
(!overrideTableFilters && hasTableFilters) ||
shouldDisableApplyButton(userFilterInputs.query.value)
}
color="primary"
variant="contained"
onClick={() => {
setUserFilters([userFilterInputs.query]);
handleClose();
}}
>
Apply
</Button>
</Stack>
</TabPanel>
<TabPanel value="table" className="content">
<FilterInputs {...tableFilterInputs} />
<FormControlLabel
control={
<Checkbox
checked={canOverrideCheckbox}
onChange={(e) => setCanOverrideCheckbox(e.target.checked)}
/>
}
label="All users can override table filters"
sx={{ justifyContent: "center", mb: 1, mr: 0 }}
/>
<Alert severity="info" style={{ width: "auto" }} sx={{ mb: 3 }}>
<ul style={{ margin: 0, paddingLeft: "1.5em" }}>
<li>
The filter above will be set
{canOverrideCheckbox && " by default"} for all users who
view this table.
</li>
{canOverrideCheckbox ? (
<>
<li>All users can override this.</li>
<li>Only ADMIN users can edit table filters.</li>
</>
) : (
<li>Only ADMIN users can override or edit this.</li>
)}
</ul>
</Alert>
<Stack
direction="row"
sx={{ "& .MuiButton-root": { minWidth: 100 } }}
justifyContent="center"
spacing={1}
>
<Button
disabled={tableFilterInputs.query.key === ""}
onClick={() => {
setTableFilters([]);
tableFilterInputs.resetQuery();
}}
>
Clear
</Button>
<Button
disabled={shouldDisableApplyButton(
tableFilterInputs.query.value
)}
color="primary"
variant="contained"
onClick={() => {
setTableFilters([tableFilterInputs.query]);
handleClose();
}}
>
Apply
</Button>
</Stack>
</TabPanel>
</TabContext>
);
}
// Non-ADMIN, override disabled
if (hasTableFilters && !tableFiltersOverridable) {
return (
<div className="content">
<FilterInputs {...tableFilterInputs} disabled />
<Alert severity="info" style={{ width: "auto" }}>
An ADMIN user has set the filter for this table
</Alert>
</div>
);
}
// Non-ADMIN, override enabled
if (hasTableFilters && tableFiltersOverridable) {
return (
<div className="content">
<FilterInputs {...userFilterInputs} />
<FormControlLabel
control={
<Checkbox
checked={overrideTableFilters}
onChange={(e) => setOverrideTableFilters(e.target.checked)}
/>
}
label="Override table filters"
sx={{ justifyContent: "center", mb: 1, mr: 0 }}
/>
{hasTableFilters && (
<FormControlLabel
control={
<Checkbox
checked={overrideTableFilters}
onChange={(e) =>
setOverrideTableFilters(e.target.checked)
}
/>
}
label="Override table filters"
sx={{ justifyContent: "center", mb: 1, mr: 0 }}
/>
)}
<Stack
direction="row"
@@ -241,59 +390,12 @@ export default function Filters() {
Apply
</Button>
</Stack>
</TabPanel>
</div>
);
}
<TabPanel value="table" className="content">
<FilterInputs {...tableFilterInputs} />
<Alert severity="info" style={{ width: "auto" }} sx={{ mb: 3 }}>
The filter above will be set for all users who view this table.
Only ADMIN users can override or edit this.
</Alert>
<Stack
direction="row"
sx={{ "& .MuiButton-root": { minWidth: 100 } }}
justifyContent="center"
spacing={1}
>
<Button
disabled={tableFilterInputs.query.key === ""}
onClick={() => {
setTableFilters([]);
tableFilterInputs.resetQuery();
}}
>
Clear
</Button>
<Button
disabled={shouldDisableApplyButton(
tableFilterInputs.query.value
)}
color="primary"
variant="contained"
onClick={() => {
setTableFilters([tableFilterInputs.query]);
handleClose();
}}
>
Apply
</Button>
</Stack>
</TabPanel>
</TabContext>
) : // Non-ADMIN cannot override table filters
hasTableFilters ? (
<div className="content">
<FilterInputs {...tableFilterInputs} disabled />
<Alert severity="info" style={{ width: "auto" }}>
An ADMIN user has set the filter for this table
</Alert>
</div>
) : (
// Non-ADMIN can set own filters, since there are no table filters
// Non-ADMIN, no table filters
return (
<div className="content">
<FilterInputs {...userFilterInputs} />
@@ -328,8 +430,8 @@ export default function Filters() {
</Button>
</Stack>
</div>
)
}
);
}}
</FiltersPopover>
);
}