@aglyn/shared-ui-jsx 1.0.0-beta.285 → 1.0.0-beta.288
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aglyn/shared-ui-jsx",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.288",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"homepage": "https://aglyn.com",
|
|
6
6
|
"repository": {
|
|
@@ -25,11 +25,11 @@
|
|
|
25
25
|
"./package.json": "./package.json"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@aglyn/shared-data-mdi": "1.0.0-beta.
|
|
29
|
-
"@aglyn/shared-ui-snackstack": "1.0.0-beta.
|
|
30
|
-
"@aglyn/shared-ui-theme": "1.0.0-beta.
|
|
31
|
-
"@aglyn/shared-util-tools": "1.0.0-beta.
|
|
32
|
-
"@aglyn/shared-util-vendor": "1.0.0-beta.
|
|
28
|
+
"@aglyn/shared-data-mdi": "1.0.0-beta.288",
|
|
29
|
+
"@aglyn/shared-ui-snackstack": "1.0.0-beta.288",
|
|
30
|
+
"@aglyn/shared-ui-theme": "1.0.0-beta.288",
|
|
31
|
+
"@aglyn/shared-util-tools": "1.0.0-beta.288",
|
|
32
|
+
"@aglyn/shared-util-vendor": "1.0.0-beta.288",
|
|
33
33
|
"@mdi/js": "^7.4.47",
|
|
34
34
|
"@swc/helpers": "0.5.23",
|
|
35
35
|
"change-case": "^5.4.4",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"lodash-es": "^4.18.1",
|
|
41
41
|
"mobx": "^7.0.5",
|
|
42
42
|
"react-frame-component": "^5.3.2",
|
|
43
|
-
"react-is": "^19.3.
|
|
43
|
+
"react-is": "^19.3.1",
|
|
44
44
|
"react-use": "^17.6.1",
|
|
45
45
|
"react-virtuoso": "^4.18.16",
|
|
46
46
|
"rxjs": "^7.8.2",
|
|
@@ -27,6 +27,13 @@ import { type ReactNode } from 'react';
|
|
|
27
27
|
* (`@aglyn/shared-ui-jsx/components/permission-choice-list.component`).
|
|
28
28
|
*/
|
|
29
29
|
export type PermissionChoiceValue = 'inherit' | 'grant' | 'deny';
|
|
30
|
+
/**
|
|
31
|
+
* A key a site can narrow (AGL-4047) carries a second choice: on a site where
|
|
32
|
+
* the member's access is narrower than their workspace role, does it follow
|
|
33
|
+
* that site role (`narrow`) or do they keep it (`keep`)? `inherit`: the layer
|
|
34
|
+
* below decides.
|
|
35
|
+
*/
|
|
36
|
+
export type PermissionNarrowingValue = 'inherit' | 'narrow' | 'keep';
|
|
30
37
|
export interface PermissionChoiceItem {
|
|
31
38
|
key: string;
|
|
32
39
|
label: string;
|
|
@@ -44,6 +51,16 @@ export interface PermissionChoiceItem {
|
|
|
44
51
|
inheritHint?: string;
|
|
45
52
|
/** A reason the row cannot change, shown as the toggle's tooltip. */
|
|
46
53
|
lockedReason?: string;
|
|
54
|
+
/**
|
|
55
|
+
* The narrowing choice, for a key a site can narrow; absent, the row has
|
|
56
|
+
* none. `effective` is the verdict and where it came from ("Follows the
|
|
57
|
+
* site role · from the Editor role"); `inheritHint` what inherit resolves to.
|
|
58
|
+
*/
|
|
59
|
+
narrowing?: {
|
|
60
|
+
choice: PermissionNarrowingValue;
|
|
61
|
+
effective?: string;
|
|
62
|
+
inheritHint?: string;
|
|
63
|
+
};
|
|
47
64
|
}
|
|
48
65
|
export interface PermissionChoiceSection {
|
|
49
66
|
id: string;
|
|
@@ -64,6 +81,10 @@ export interface PermissionChoiceListProps {
|
|
|
64
81
|
emptyMessage?: ReactNode;
|
|
65
82
|
/** Offer "set the whole group" on each heading. */
|
|
66
83
|
groupActions?: boolean;
|
|
84
|
+
/** Sets one key's narrowing choice; absent, the narrowing rows are read-only. */
|
|
85
|
+
onNarrowingChange?: (key: string, choice: PermissionNarrowingValue) => void;
|
|
86
|
+
/** The words before the narrowing choice. */
|
|
87
|
+
narrowingLabel?: string;
|
|
67
88
|
}
|
|
68
89
|
export declare function PermissionChoiceList(props: PermissionChoiceListProps): import("react").JSX.Element;
|
|
69
90
|
export declare namespace PermissionChoiceList {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { _ as _extends } from "@swc/helpers/_/_extends";
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
3
|
/**
|
|
4
4
|
* @license
|
|
5
5
|
* Copyright 2026 Aglyn LLC
|
|
@@ -52,6 +52,63 @@ function ChoiceToggle(props) {
|
|
|
52
52
|
}, choice))
|
|
53
53
|
});
|
|
54
54
|
}
|
|
55
|
+
const NARROWING_CHOICES = [
|
|
56
|
+
'inherit',
|
|
57
|
+
'narrow',
|
|
58
|
+
'keep'
|
|
59
|
+
];
|
|
60
|
+
const NARROWING_LABELS = {
|
|
61
|
+
inherit: 'Inherit',
|
|
62
|
+
narrow: 'Follow the site role',
|
|
63
|
+
keep: 'Keep this permission'
|
|
64
|
+
};
|
|
65
|
+
function NarrowingToggle(props) {
|
|
66
|
+
return /*#__PURE__*/ _jsxs(Stack, {
|
|
67
|
+
direction: {
|
|
68
|
+
xs: 'column',
|
|
69
|
+
sm: 'row'
|
|
70
|
+
},
|
|
71
|
+
spacing: 1,
|
|
72
|
+
sx: {
|
|
73
|
+
alignItems: {
|
|
74
|
+
xs: 'flex-start',
|
|
75
|
+
sm: 'center'
|
|
76
|
+
},
|
|
77
|
+
mt: 0.5
|
|
78
|
+
},
|
|
79
|
+
children: [
|
|
80
|
+
/*#__PURE__*/ _jsx(Typography, {
|
|
81
|
+
variant: "caption",
|
|
82
|
+
color: "text.secondary",
|
|
83
|
+
children: props.label
|
|
84
|
+
}),
|
|
85
|
+
/*#__PURE__*/ _jsx(ToggleButtonGroup, {
|
|
86
|
+
size: "small",
|
|
87
|
+
exclusive: true,
|
|
88
|
+
value: props.value,
|
|
89
|
+
disabled: props.disabled,
|
|
90
|
+
"aria-label": props.ariaLabel,
|
|
91
|
+
onChange: (_event, next)=>{
|
|
92
|
+
if (next) props.onChange(next);
|
|
93
|
+
},
|
|
94
|
+
sx: {
|
|
95
|
+
flexWrap: 'wrap'
|
|
96
|
+
},
|
|
97
|
+
children: NARROWING_CHOICES.map((choice)=>/*#__PURE__*/ _jsx(ToggleButton, {
|
|
98
|
+
value: choice,
|
|
99
|
+
color: choice === 'keep' ? 'success' : choice === 'narrow' ? 'warning' : 'standard',
|
|
100
|
+
sx: {
|
|
101
|
+
px: 1,
|
|
102
|
+
py: 0,
|
|
103
|
+
textTransform: 'none',
|
|
104
|
+
typography: 'caption'
|
|
105
|
+
},
|
|
106
|
+
children: NARROWING_LABELS[choice]
|
|
107
|
+
}, choice))
|
|
108
|
+
})
|
|
109
|
+
]
|
|
110
|
+
});
|
|
111
|
+
}
|
|
55
112
|
export function PermissionChoiceList(props) {
|
|
56
113
|
var _props_search, _props_emptyMessage;
|
|
57
114
|
const labels = _extends({}, DEFAULT_LABELS, props.labels);
|
|
@@ -149,6 +206,7 @@ export function PermissionChoiceList(props) {
|
|
|
149
206
|
borderRadius: 1
|
|
150
207
|
},
|
|
151
208
|
children: section.items.map((item)=>{
|
|
209
|
+
var _props_narrowingLabel;
|
|
152
210
|
const toggle = /*#__PURE__*/ _jsx("span", {
|
|
153
211
|
children: /*#__PURE__*/ _jsx(ChoiceToggle, {
|
|
154
212
|
value: item.choice,
|
|
@@ -202,6 +260,29 @@ export function PermissionChoiceList(props) {
|
|
|
202
260
|
color: "text.secondary",
|
|
203
261
|
component: "p",
|
|
204
262
|
children: item.inheritHint
|
|
263
|
+
}) : null,
|
|
264
|
+
item.narrowing ? /*#__PURE__*/ _jsxs(_Fragment, {
|
|
265
|
+
children: [
|
|
266
|
+
/*#__PURE__*/ _jsx(NarrowingToggle, {
|
|
267
|
+
label: (_props_narrowingLabel = props.narrowingLabel) != null ? _props_narrowingLabel : 'On sites where their role is narrower:',
|
|
268
|
+
value: item.narrowing.choice,
|
|
269
|
+
disabled: props.disabled || Boolean(item.lockedReason) || !props.onNarrowingChange,
|
|
270
|
+
ariaLabel: `${item.label}: on sites where their role is narrower`,
|
|
271
|
+
onChange: (choice)=>props.onNarrowingChange == null ? void 0 : props.onNarrowingChange.call(props, item.key, choice)
|
|
272
|
+
}),
|
|
273
|
+
item.narrowing.effective ? /*#__PURE__*/ _jsx(Typography, {
|
|
274
|
+
variant: "caption",
|
|
275
|
+
color: "text.secondary",
|
|
276
|
+
component: "p",
|
|
277
|
+
children: item.narrowing.effective
|
|
278
|
+
}) : null,
|
|
279
|
+
item.narrowing.choice === 'inherit' && item.narrowing.inheritHint ? /*#__PURE__*/ _jsx(Typography, {
|
|
280
|
+
variant: "caption",
|
|
281
|
+
color: "text.secondary",
|
|
282
|
+
component: "p",
|
|
283
|
+
children: item.narrowing.inheritHint
|
|
284
|
+
}) : null
|
|
285
|
+
]
|
|
205
286
|
}) : null
|
|
206
287
|
]
|
|
207
288
|
}),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../../../libs/shared/ui/jsx/src/lib/components/permission-choice-list.component.tsx"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n Box,\n Chip,\n Divider,\n Stack,\n TextField,\n ToggleButton,\n ToggleButtonGroup,\n Tooltip,\n Typography,\n} from '@mui/material'\nimport { useId, type ReactNode } from 'react'\n\n/**\n * A grouped, searchable list of permissions with three states each (AGL-4047):\n * inherit (the layer below decides), allow, or deny. Drawn by every editor of\n * a permission map — a custom role, one member's overrides, one collaborator's\n * per-site toggles — so they look and behave alike.\n *\n * Presentation only: the caller decides which keys are offered, how they are\n * grouped, what a search keeps and what \"inherit\" resolves to, and hands the\n * words in. NOT in the `@aglyn/shared-ui-jsx` barrel; subpath-import it\n * (`@aglyn/shared-ui-jsx/components/permission-choice-list.component`).\n */\n\nexport type PermissionChoiceValue = 'inherit' | 'grant' | 'deny'\n\nexport interface PermissionChoiceItem {\n key: string\n label: string\n description?: string\n choice: PermissionChoiceValue\n /**\n * The verdict the member ends up with and where it came from\n * (\"Allowed by the Editor role\"), shown under the description.\n */\n effective?: { granted: boolean; source: string }\n /** What inherit resolves to here, when there is one answer (\"Editor default: allowed\"). */\n inheritHint?: string\n /** A reason the row cannot change, shown as the toggle's tooltip. */\n lockedReason?: string\n}\n\nexport interface PermissionChoiceSection {\n id: string\n label: string\n items: PermissionChoiceItem[]\n}\n\nexport interface PermissionChoiceListProps {\n sections: readonly PermissionChoiceSection[]\n /** Sets one key (or, from a group heading, every key of the group) to a choice. */\n onChange: (keys: string[], choice: PermissionChoiceValue) => void\n /** The search box; absent hides it. */\n search?: string\n onSearchChange?: (value: string) => void\n disabled?: boolean\n /** The words for the three states. */\n labels?: Partial<Record<PermissionChoiceValue, string>>\n /** Shown when a search keeps nothing. */\n emptyMessage?: ReactNode\n /** Offer \"set the whole group\" on each heading. */\n groupActions?: boolean\n}\n\nconst CHOICES: readonly PermissionChoiceValue[] = ['inherit', 'grant', 'deny']\n\nconst DEFAULT_LABELS: Record<PermissionChoiceValue, string> = {\n inherit: 'Inherit',\n grant: 'Allow',\n deny: 'Deny',\n}\n\nfunction ChoiceToggle(props: {\n value: PermissionChoiceValue | null\n onChange: (choice: PermissionChoiceValue) => void\n disabled?: boolean\n labels: Record<PermissionChoiceValue, string>\n ariaLabel: string\n}) {\n return (\n <ToggleButtonGroup\n size=\"small\"\n exclusive\n value={props.value}\n disabled={props.disabled}\n aria-label={props.ariaLabel}\n onChange={(_event, next: PermissionChoiceValue | null) => {\n if (next) props.onChange(next)\n }}\n sx={{ flexShrink: 0 }}\n >\n {CHOICES.map((choice) => (\n <ToggleButton\n key={choice}\n value={choice}\n color={choice === 'grant' ? 'success' : choice === 'deny' ? 'error' : 'standard'}\n sx={{ px: 1.25, py: 0.25, textTransform: 'none' }}\n >\n {props.labels[choice]}\n </ToggleButton>\n ))}\n </ToggleButtonGroup>\n )\n}\n\nexport function PermissionChoiceList(props: PermissionChoiceListProps) {\n const labels = { ...DEFAULT_LABELS, ...props.labels }\n const searchId = useId()\n const visible = props.sections.filter((section) => section.items.length > 0)\n return (\n <Stack spacing={2}>\n {props.onSearchChange ? (\n <TextField\n id={searchId}\n size=\"small\"\n type=\"search\"\n label=\"Search permissions\"\n value={props.search ?? ''}\n onChange={(event) => props.onSearchChange?.(event.target.value)}\n />\n ) : null}\n {visible.length === 0 ? (\n <Typography variant=\"body2\" color=\"text.secondary\">\n {props.emptyMessage ?? 'No permission matches your search.'}\n </Typography>\n ) : null}\n {visible.map((section) => {\n const granted = section.items.filter((item) => item.choice === 'grant').length\n const denied = section.items.filter((item) => item.choice === 'deny').length\n const shared = section.items.every((item) => item.choice === section.items[0]?.choice)\n ? (section.items[0]?.choice ?? null)\n : null\n const changeable = section.items.filter((item) => !item.lockedReason).map((item) => item.key)\n return (\n <Box key={section.id} component=\"section\" aria-label={section.label}>\n <Stack\n direction={{ xs: 'column', sm: 'row' }}\n spacing={1}\n sx={{ alignItems: { xs: 'flex-start', sm: 'center' }, justifyContent: 'space-between', mb: 1 }}\n >\n <Stack direction=\"row\" spacing={1} sx={{ alignItems: 'center', flexWrap: 'wrap', rowGap: 0.5 }}>\n <Typography variant=\"subtitle2\" component=\"h3\">\n {section.label}\n </Typography>\n {granted ? <Chip size=\"small\" color=\"success\" variant=\"outlined\" label={`${granted} allowed`} /> : null}\n {denied ? <Chip size=\"small\" color=\"error\" variant=\"outlined\" label={`${denied} denied`} /> : null}\n </Stack>\n {props.groupActions && changeable.length > 1 ? (\n <ChoiceToggle\n value={shared}\n labels={labels}\n disabled={props.disabled}\n ariaLabel={`Set every ${section.label} permission`}\n onChange={(choice) => props.onChange(changeable, choice)}\n />\n ) : null}\n </Stack>\n <Stack divider={<Divider flexItem />} sx={{ border: 1, borderColor: 'divider', borderRadius: 1 }}>\n {section.items.map((item) => {\n const toggle = (\n <span>\n <ChoiceToggle\n value={item.choice}\n labels={labels}\n disabled={props.disabled || Boolean(item.lockedReason)}\n ariaLabel={item.label}\n onChange={(choice) => props.onChange([item.key], choice)}\n />\n </span>\n )\n return (\n <Stack\n key={item.key}\n direction={{ xs: 'column', sm: 'row' }}\n spacing={1.5}\n sx={{ px: 1.5, py: 1, alignItems: { xs: 'stretch', sm: 'center' }, justifyContent: 'space-between' }}\n >\n <Box sx={{ minWidth: 0 }}>\n <Typography variant=\"body2\">{item.label}</Typography>\n {item.description ? (\n <Typography variant=\"caption\" color=\"text.secondary\" component=\"p\">\n {item.description}\n </Typography>\n ) : null}\n {item.effective ? (\n <Typography\n variant=\"caption\"\n component=\"p\"\n color={item.effective.granted ? 'success.main' : 'text.secondary'}\n >\n {`${item.effective.granted ? 'Allowed' : 'Not allowed'} · ${item.effective.source}`}\n </Typography>\n ) : null}\n {item.choice === 'inherit' && item.inheritHint ? (\n <Typography variant=\"caption\" color=\"text.secondary\" component=\"p\">\n {item.inheritHint}\n </Typography>\n ) : null}\n </Box>\n {item.lockedReason ? <Tooltip title={item.lockedReason}>{toggle}</Tooltip> : toggle}\n </Stack>\n )\n })}\n </Stack>\n </Box>\n )\n })}\n </Stack>\n )\n}\nPermissionChoiceList.displayName = 'PermissionChoiceList'\n\nexport default PermissionChoiceList\n"],"names":["Box","Chip","Divider","Stack","TextField","ToggleButton","ToggleButtonGroup","Tooltip","Typography","useId","CHOICES","DEFAULT_LABELS","inherit","grant","deny","ChoiceToggle","props","size","exclusive","value","disabled","aria-label","ariaLabel","onChange","_event","next","sx","flexShrink","map","choice","color","px","py","textTransform","labels","PermissionChoiceList","searchId","visible","sections","filter","section","items","length","spacing","onSearchChange","id","type","label","search","event","target","variant","emptyMessage","granted","item","denied","shared","every","changeable","lockedReason","key","component","direction","xs","sm","alignItems","justifyContent","mb","flexWrap","rowGap","groupActions","divider","flexItem","border","borderColor","borderRadius","toggle","span","Boolean","minWidth","description","effective","source","inheritHint","title","displayName"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../../../../libs/shared/ui/jsx/src/lib/components/permission-choice-list.component.tsx"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n Box,\n Chip,\n Divider,\n Stack,\n TextField,\n ToggleButton,\n ToggleButtonGroup,\n Tooltip,\n Typography,\n} from '@mui/material'\nimport { useId, type ReactNode } from 'react'\n\n/**\n * A grouped, searchable list of permissions with three states each (AGL-4047):\n * inherit (the layer below decides), allow, or deny. Drawn by every editor of\n * a permission map — a custom role, one member's overrides, one collaborator's\n * per-site toggles — so they look and behave alike.\n *\n * Presentation only: the caller decides which keys are offered, how they are\n * grouped, what a search keeps and what \"inherit\" resolves to, and hands the\n * words in. NOT in the `@aglyn/shared-ui-jsx` barrel; subpath-import it\n * (`@aglyn/shared-ui-jsx/components/permission-choice-list.component`).\n */\n\nexport type PermissionChoiceValue = 'inherit' | 'grant' | 'deny'\n\n/**\n * A key a site can narrow (AGL-4047) carries a second choice: on a site where\n * the member's access is narrower than their workspace role, does it follow\n * that site role (`narrow`) or do they keep it (`keep`)? `inherit`: the layer\n * below decides.\n */\nexport type PermissionNarrowingValue = 'inherit' | 'narrow' | 'keep'\n\nexport interface PermissionChoiceItem {\n key: string\n label: string\n description?: string\n choice: PermissionChoiceValue\n /**\n * The verdict the member ends up with and where it came from\n * (\"Allowed by the Editor role\"), shown under the description.\n */\n effective?: { granted: boolean; source: string }\n /** What inherit resolves to here, when there is one answer (\"Editor default: allowed\"). */\n inheritHint?: string\n /** A reason the row cannot change, shown as the toggle's tooltip. */\n lockedReason?: string\n /**\n * The narrowing choice, for a key a site can narrow; absent, the row has\n * none. `effective` is the verdict and where it came from (\"Follows the\n * site role · from the Editor role\"); `inheritHint` what inherit resolves to.\n */\n narrowing?: { choice: PermissionNarrowingValue; effective?: string; inheritHint?: string }\n}\n\nexport interface PermissionChoiceSection {\n id: string\n label: string\n items: PermissionChoiceItem[]\n}\n\nexport interface PermissionChoiceListProps {\n sections: readonly PermissionChoiceSection[]\n /** Sets one key (or, from a group heading, every key of the group) to a choice. */\n onChange: (keys: string[], choice: PermissionChoiceValue) => void\n /** The search box; absent hides it. */\n search?: string\n onSearchChange?: (value: string) => void\n disabled?: boolean\n /** The words for the three states. */\n labels?: Partial<Record<PermissionChoiceValue, string>>\n /** Shown when a search keeps nothing. */\n emptyMessage?: ReactNode\n /** Offer \"set the whole group\" on each heading. */\n groupActions?: boolean\n /** Sets one key's narrowing choice; absent, the narrowing rows are read-only. */\n onNarrowingChange?: (key: string, choice: PermissionNarrowingValue) => void\n /** The words before the narrowing choice. */\n narrowingLabel?: string\n}\n\nconst CHOICES: readonly PermissionChoiceValue[] = ['inherit', 'grant', 'deny']\n\nconst DEFAULT_LABELS: Record<PermissionChoiceValue, string> = {\n inherit: 'Inherit',\n grant: 'Allow',\n deny: 'Deny',\n}\n\nfunction ChoiceToggle(props: {\n value: PermissionChoiceValue | null\n onChange: (choice: PermissionChoiceValue) => void\n disabled?: boolean\n labels: Record<PermissionChoiceValue, string>\n ariaLabel: string\n}) {\n return (\n <ToggleButtonGroup\n size=\"small\"\n exclusive\n value={props.value}\n disabled={props.disabled}\n aria-label={props.ariaLabel}\n onChange={(_event, next: PermissionChoiceValue | null) => {\n if (next) props.onChange(next)\n }}\n sx={{ flexShrink: 0 }}\n >\n {CHOICES.map((choice) => (\n <ToggleButton\n key={choice}\n value={choice}\n color={choice === 'grant' ? 'success' : choice === 'deny' ? 'error' : 'standard'}\n sx={{ px: 1.25, py: 0.25, textTransform: 'none' }}\n >\n {props.labels[choice]}\n </ToggleButton>\n ))}\n </ToggleButtonGroup>\n )\n}\n\nconst NARROWING_CHOICES: readonly PermissionNarrowingValue[] = ['inherit', 'narrow', 'keep']\n\nconst NARROWING_LABELS: Record<PermissionNarrowingValue, string> = {\n inherit: 'Inherit',\n narrow: 'Follow the site role',\n keep: 'Keep this permission',\n}\n\nfunction NarrowingToggle(props: {\n label: string\n value: PermissionNarrowingValue\n onChange: (choice: PermissionNarrowingValue) => void\n disabled?: boolean\n ariaLabel: string\n}) {\n return (\n <Stack\n direction={{ xs: 'column', sm: 'row' }}\n spacing={1}\n sx={{ alignItems: { xs: 'flex-start', sm: 'center' }, mt: 0.5 }}\n >\n <Typography variant=\"caption\" color=\"text.secondary\">\n {props.label}\n </Typography>\n <ToggleButtonGroup\n size=\"small\"\n exclusive\n value={props.value}\n disabled={props.disabled}\n aria-label={props.ariaLabel}\n onChange={(_event, next: PermissionNarrowingValue | null) => {\n if (next) props.onChange(next)\n }}\n sx={{ flexWrap: 'wrap' }}\n >\n {NARROWING_CHOICES.map((choice) => (\n <ToggleButton\n key={choice}\n value={choice}\n color={choice === 'keep' ? 'success' : choice === 'narrow' ? 'warning' : 'standard'}\n sx={{ px: 1, py: 0, textTransform: 'none', typography: 'caption' }}\n >\n {NARROWING_LABELS[choice]}\n </ToggleButton>\n ))}\n </ToggleButtonGroup>\n </Stack>\n )\n}\n\nexport function PermissionChoiceList(props: PermissionChoiceListProps) {\n const labels = { ...DEFAULT_LABELS, ...props.labels }\n const searchId = useId()\n const visible = props.sections.filter((section) => section.items.length > 0)\n return (\n <Stack spacing={2}>\n {props.onSearchChange ? (\n <TextField\n id={searchId}\n size=\"small\"\n type=\"search\"\n label=\"Search permissions\"\n value={props.search ?? ''}\n onChange={(event) => props.onSearchChange?.(event.target.value)}\n />\n ) : null}\n {visible.length === 0 ? (\n <Typography variant=\"body2\" color=\"text.secondary\">\n {props.emptyMessage ?? 'No permission matches your search.'}\n </Typography>\n ) : null}\n {visible.map((section) => {\n const granted = section.items.filter((item) => item.choice === 'grant').length\n const denied = section.items.filter((item) => item.choice === 'deny').length\n const shared = section.items.every((item) => item.choice === section.items[0]?.choice)\n ? (section.items[0]?.choice ?? null)\n : null\n const changeable = section.items.filter((item) => !item.lockedReason).map((item) => item.key)\n return (\n <Box key={section.id} component=\"section\" aria-label={section.label}>\n <Stack\n direction={{ xs: 'column', sm: 'row' }}\n spacing={1}\n sx={{ alignItems: { xs: 'flex-start', sm: 'center' }, justifyContent: 'space-between', mb: 1 }}\n >\n <Stack direction=\"row\" spacing={1} sx={{ alignItems: 'center', flexWrap: 'wrap', rowGap: 0.5 }}>\n <Typography variant=\"subtitle2\" component=\"h3\">\n {section.label}\n </Typography>\n {granted ? <Chip size=\"small\" color=\"success\" variant=\"outlined\" label={`${granted} allowed`} /> : null}\n {denied ? <Chip size=\"small\" color=\"error\" variant=\"outlined\" label={`${denied} denied`} /> : null}\n </Stack>\n {props.groupActions && changeable.length > 1 ? (\n <ChoiceToggle\n value={shared}\n labels={labels}\n disabled={props.disabled}\n ariaLabel={`Set every ${section.label} permission`}\n onChange={(choice) => props.onChange(changeable, choice)}\n />\n ) : null}\n </Stack>\n <Stack divider={<Divider flexItem />} sx={{ border: 1, borderColor: 'divider', borderRadius: 1 }}>\n {section.items.map((item) => {\n const toggle = (\n <span>\n <ChoiceToggle\n value={item.choice}\n labels={labels}\n disabled={props.disabled || Boolean(item.lockedReason)}\n ariaLabel={item.label}\n onChange={(choice) => props.onChange([item.key], choice)}\n />\n </span>\n )\n return (\n <Stack\n key={item.key}\n direction={{ xs: 'column', sm: 'row' }}\n spacing={1.5}\n sx={{ px: 1.5, py: 1, alignItems: { xs: 'stretch', sm: 'center' }, justifyContent: 'space-between' }}\n >\n <Box sx={{ minWidth: 0 }}>\n <Typography variant=\"body2\">{item.label}</Typography>\n {item.description ? (\n <Typography variant=\"caption\" color=\"text.secondary\" component=\"p\">\n {item.description}\n </Typography>\n ) : null}\n {item.effective ? (\n <Typography\n variant=\"caption\"\n component=\"p\"\n color={item.effective.granted ? 'success.main' : 'text.secondary'}\n >\n {`${item.effective.granted ? 'Allowed' : 'Not allowed'} · ${item.effective.source}`}\n </Typography>\n ) : null}\n {item.choice === 'inherit' && item.inheritHint ? (\n <Typography variant=\"caption\" color=\"text.secondary\" component=\"p\">\n {item.inheritHint}\n </Typography>\n ) : null}\n {item.narrowing ? (\n <>\n <NarrowingToggle\n label={props.narrowingLabel ?? 'On sites where their role is narrower:'}\n value={item.narrowing.choice}\n disabled={props.disabled || Boolean(item.lockedReason) || !props.onNarrowingChange}\n ariaLabel={`${item.label}: on sites where their role is narrower`}\n onChange={(choice) => props.onNarrowingChange?.(item.key, choice)}\n />\n {item.narrowing.effective ? (\n <Typography variant=\"caption\" color=\"text.secondary\" component=\"p\">\n {item.narrowing.effective}\n </Typography>\n ) : null}\n {item.narrowing.choice === 'inherit' && item.narrowing.inheritHint ? (\n <Typography variant=\"caption\" color=\"text.secondary\" component=\"p\">\n {item.narrowing.inheritHint}\n </Typography>\n ) : null}\n </>\n ) : null}\n </Box>\n {item.lockedReason ? <Tooltip title={item.lockedReason}>{toggle}</Tooltip> : toggle}\n </Stack>\n )\n })}\n </Stack>\n </Box>\n )\n })}\n </Stack>\n )\n}\nPermissionChoiceList.displayName = 'PermissionChoiceList'\n\nexport default PermissionChoiceList\n"],"names":["Box","Chip","Divider","Stack","TextField","ToggleButton","ToggleButtonGroup","Tooltip","Typography","useId","CHOICES","DEFAULT_LABELS","inherit","grant","deny","ChoiceToggle","props","size","exclusive","value","disabled","aria-label","ariaLabel","onChange","_event","next","sx","flexShrink","map","choice","color","px","py","textTransform","labels","NARROWING_CHOICES","NARROWING_LABELS","narrow","keep","NarrowingToggle","direction","xs","sm","spacing","alignItems","mt","variant","label","flexWrap","typography","PermissionChoiceList","searchId","visible","sections","filter","section","items","length","onSearchChange","id","type","search","event","target","emptyMessage","granted","item","denied","shared","every","changeable","lockedReason","key","component","justifyContent","mb","rowGap","groupActions","divider","flexItem","border","borderColor","borderRadius","toggle","span","Boolean","minWidth","description","effective","source","inheritHint","narrowing","narrowingLabel","onNarrowingChange","title","displayName"],"mappings":"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"}
|