@backstage-community/plugin-rbac 1.34.0 → 1.36.0
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/CHANGELOG.md +18 -0
- package/dist/components/Administration.esm.js +2 -2
- package/dist/components/Administration.esm.js.map +1 -1
- package/dist/components/ConditionalAccess/AddNestedConditionButton.esm.js +5 -5
- package/dist/components/ConditionalAccess/AddNestedConditionButton.esm.js.map +1 -1
- package/dist/components/ConditionalAccess/ComplexConditionRow.esm.js +14 -14
- package/dist/components/ConditionalAccess/ComplexConditionRow.esm.js.map +1 -1
- package/dist/components/ConditionalAccess/ComplexConditionRowButtons.esm.js +7 -7
- package/dist/components/ConditionalAccess/ComplexConditionRowButtons.esm.js.map +1 -1
- package/dist/components/ConditionalAccess/ConditionRule.esm.js +3 -3
- package/dist/components/ConditionalAccess/ConditionRule.esm.js.map +1 -1
- package/dist/components/ConditionalAccess/ConditionalAccessSidebar.esm.js +9 -9
- package/dist/components/ConditionalAccess/ConditionalAccessSidebar.esm.js.map +1 -1
- package/dist/components/ConditionalAccess/ConditionsForm.esm.js +15 -15
- package/dist/components/ConditionalAccess/ConditionsForm.esm.js.map +1 -1
- package/dist/components/ConditionalAccess/ConditionsFormRow.esm.js +32 -32
- package/dist/components/ConditionalAccess/ConditionsFormRow.esm.js.map +1 -1
- package/dist/components/ConditionalAccess/ConditionsFormRowFields.esm.js +11 -11
- package/dist/components/ConditionalAccess/ConditionsFormRowFields.esm.js.map +1 -1
- package/dist/components/ConditionalAccess/CriteriaToggleButton.esm.js +2 -2
- package/dist/components/ConditionalAccess/CriteriaToggleButton.esm.js.map +1 -1
- package/dist/components/ConditionalAccess/CustomArrayField.esm.js +5 -5
- package/dist/components/ConditionalAccess/CustomArrayField.esm.js.map +1 -1
- package/dist/components/ConditionalAccess/RulesDropdownOption.esm.js +4 -4
- package/dist/components/ConditionalAccess/RulesDropdownOption.esm.js.map +1 -1
- package/dist/components/CreateRole/AddMembersForm.esm.js +14 -14
- package/dist/components/CreateRole/AddMembersForm.esm.js.map +1 -1
- package/dist/components/CreateRole/AddedMembersTable.esm.js +3 -3
- package/dist/components/CreateRole/AddedMembersTable.esm.js.map +1 -1
- package/dist/components/CreateRole/AddedMembersTableColumn.esm.js +4 -4
- package/dist/components/CreateRole/AddedMembersTableColumn.esm.js.map +1 -1
- package/dist/components/CreateRole/CreateRolePage.esm.js +6 -6
- package/dist/components/CreateRole/CreateRolePage.esm.js.map +1 -1
- package/dist/components/CreateRole/EditRolePage.esm.js +9 -5
- package/dist/components/CreateRole/EditRolePage.esm.js.map +1 -1
- package/dist/components/CreateRole/MembersDropdownOption.esm.js +4 -4
- package/dist/components/CreateRole/MembersDropdownOption.esm.js.map +1 -1
- package/dist/components/CreateRole/PermissionPoliciesForm.esm.js +100 -106
- package/dist/components/CreateRole/PermissionPoliciesForm.esm.js.map +1 -1
- package/dist/components/CreateRole/PermissionPoliciesFormNestedRow.esm.js +125 -0
- package/dist/components/CreateRole/PermissionPoliciesFormNestedRow.esm.js.map +1 -0
- package/dist/components/CreateRole/PermissionPoliciesFormRow.esm.js +104 -153
- package/dist/components/CreateRole/PermissionPoliciesFormRow.esm.js.map +1 -1
- package/dist/components/CreateRole/PermissionPoliciesFormTable.esm.js +174 -0
- package/dist/components/CreateRole/PermissionPoliciesFormTable.esm.js.map +1 -0
- package/dist/components/CreateRole/PluginsDropdown.esm.js +66 -0
- package/dist/components/CreateRole/PluginsDropdown.esm.js.map +1 -0
- package/dist/components/CreateRole/PluginsDropdownOption.esm.js +52 -0
- package/dist/components/CreateRole/PluginsDropdownOption.esm.js.map +1 -0
- package/dist/components/CreateRole/ReviewStep.esm.js +5 -5
- package/dist/components/CreateRole/ReviewStep.esm.js.map +1 -1
- package/dist/components/CreateRole/ReviewStepTable.esm.js +4 -4
- package/dist/components/CreateRole/ReviewStepTable.esm.js.map +1 -1
- package/dist/components/CreateRole/RoleDetailsForm.esm.js +4 -4
- package/dist/components/CreateRole/RoleDetailsForm.esm.js.map +1 -1
- package/dist/components/CreateRole/RoleForm.esm.js +18 -17
- package/dist/components/CreateRole/RoleForm.esm.js.map +1 -1
- package/dist/components/DownloadUserStatistics.esm.js +2 -2
- package/dist/components/DownloadUserStatistics.esm.js.map +1 -1
- package/dist/components/EditRole.esm.js +3 -3
- package/dist/components/EditRole.esm.js.map +1 -1
- package/dist/components/RbacPage.esm.js +3 -3
- package/dist/components/RbacPage.esm.js.map +1 -1
- package/dist/components/RoleOverview/AboutCard.esm.js +9 -9
- package/dist/components/RoleOverview/AboutCard.esm.js.map +1 -1
- package/dist/components/RoleOverview/MembersCard.esm.js +8 -8
- package/dist/components/RoleOverview/MembersCard.esm.js.map +1 -1
- package/dist/components/RoleOverview/MembersListColumns.esm.js +2 -2
- package/dist/components/RoleOverview/MembersListColumns.esm.js.map +1 -1
- package/dist/components/RoleOverview/PermissionsCard.esm.js +8 -8
- package/dist/components/RoleOverview/PermissionsCard.esm.js.map +1 -1
- package/dist/components/RoleOverview/PermissionsListColumns.esm.js.map +1 -1
- package/dist/components/RoleOverview/RoleOverviewPage.esm.js +5 -5
- package/dist/components/RoleOverview/RoleOverviewPage.esm.js.map +1 -1
- package/dist/components/RolesList/DeleteRole.esm.js +3 -3
- package/dist/components/RolesList/DeleteRole.esm.js.map +1 -1
- package/dist/components/RolesList/DeleteRoleDialog.esm.js +15 -15
- package/dist/components/RolesList/DeleteRoleDialog.esm.js.map +1 -1
- package/dist/components/RolesList/RolesList.esm.js +9 -9
- package/dist/components/RolesList/RolesList.esm.js.map +1 -1
- package/dist/components/RolesList/RolesListColumns.esm.js +5 -5
- package/dist/components/RolesList/RolesListColumns.esm.js.map +1 -1
- package/dist/components/RolesList/RolesListToolbar.esm.js +5 -5
- package/dist/components/RolesList/RolesListToolbar.esm.js.map +1 -1
- package/dist/components/Router.esm.js +8 -8
- package/dist/components/Router.esm.js.map +1 -1
- package/dist/components/SnackbarAlert.esm.js +3 -3
- package/dist/components/SnackbarAlert.esm.js.map +1 -1
- package/dist/components/ToastContext.esm.js +4 -4
- package/dist/components/ToastContext.esm.js.map +1 -1
- package/dist/hooks/useConditionRules.esm.js +1 -1
- package/dist/hooks/useConditionRules.esm.js.map +1 -1
- package/dist/hooks/useMembers.esm.js +4 -4
- package/dist/hooks/useMembers.esm.js.map +1 -1
- package/dist/hooks/usePermissionPolicies.esm.js +11 -7
- package/dist/hooks/usePermissionPolicies.esm.js.map +1 -1
- package/dist/hooks/useRole.esm.js +1 -1
- package/dist/hooks/useRole.esm.js.map +1 -1
- package/dist/hooks/useRoles.esm.js +7 -9
- package/dist/hooks/useRoles.esm.js.map +1 -1
- package/dist/hooks/useSelectedMembers.esm.js +1 -1
- package/dist/hooks/useSelectedMembers.esm.js.map +1 -1
- package/dist/utils/conditional-access-utils.esm.js +2 -2
- package/dist/utils/conditional-access-utils.esm.js.map +1 -1
- package/dist/utils/create-role-utils.esm.js +17 -12
- package/dist/utils/create-role-utils.esm.js.map +1 -1
- package/dist/utils/rbac-utils.esm.js +22 -11
- package/dist/utils/rbac-utils.esm.js.map +1 -1
- package/package.json +21 -14
- package/dist/components/CreateRole/PoliciesCheckboxGroup.esm.js +0 -76
- package/dist/components/CreateRole/PoliciesCheckboxGroup.esm.js.map +0 -1
- package/dist/components/CreateRole/const.esm.js +0 -14
- package/dist/components/CreateRole/const.esm.js.map +0 -1
|
@@ -1,174 +1,125 @@
|
|
|
1
|
-
import
|
|
2
|
-
import ChecklistRtlIcon from '@mui/icons-material/ChecklistRtl';
|
|
3
|
-
import HelpOutlineIcon from '@mui/icons-material/HelpOutline';
|
|
4
|
-
import RemoveIcon from '@mui/icons-material/Remove';
|
|
5
|
-
import Autocomplete from '@mui/material/Autocomplete';
|
|
6
|
-
import FormLabel from '@mui/material/FormLabel';
|
|
1
|
+
import React__default from 'react';
|
|
7
2
|
import IconButton from '@mui/material/IconButton';
|
|
8
|
-
import TextField from '@mui/material/TextField';
|
|
9
|
-
import Tooltip from '@mui/material/Tooltip';
|
|
10
|
-
import Typography from '@mui/material/Typography';
|
|
11
3
|
import { getRulesNumber } from '../../utils/create-role-utils.esm.js';
|
|
12
|
-
import
|
|
13
|
-
import
|
|
4
|
+
import TableRow from '@mui/material/TableRow';
|
|
5
|
+
import TableCell from '@mui/material/TableCell';
|
|
6
|
+
import Collapse from '@mui/material/Collapse';
|
|
7
|
+
import Box from '@mui/material/Box';
|
|
8
|
+
import Table from '@mui/material/Table';
|
|
9
|
+
import TableBody from '@mui/material/TableBody';
|
|
10
|
+
import Delete from '@mui/icons-material/Delete';
|
|
11
|
+
import ArrowRightIcon from '@mui/icons-material/KeyboardArrowRight';
|
|
12
|
+
import ArrowDownIcon from '@mui/icons-material/KeyboardArrowDown';
|
|
13
|
+
import PermissionPoliciesFormNestedRow from './PermissionPoliciesFormNestedRow.esm.js';
|
|
14
|
+
import Link from '@mui/material/Link';
|
|
14
15
|
|
|
15
16
|
const PermissionPoliciesFormRow = ({
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
onChangePolicy,
|
|
25
|
-
onChangePlugin,
|
|
26
|
-
handleBlur,
|
|
27
|
-
getPermissionDisabled,
|
|
17
|
+
rowData,
|
|
18
|
+
permissionPoliciesRows,
|
|
19
|
+
conditionRulesData,
|
|
20
|
+
open,
|
|
21
|
+
onSelectPermission,
|
|
22
|
+
onSelectPolicy,
|
|
23
|
+
onRemovePermission,
|
|
24
|
+
onRemovePlugin,
|
|
28
25
|
onAddConditions
|
|
29
26
|
}) => {
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
27
|
+
const [currentOpen, setCurrentOpen] = React__default.useState(false);
|
|
28
|
+
React__default.useEffect(() => {
|
|
29
|
+
setCurrentOpen(open);
|
|
30
|
+
}, [open]);
|
|
31
|
+
const getTotalRules = (conditions) => {
|
|
32
|
+
const totalRules = getRulesNumber(conditions);
|
|
33
|
+
return totalRules;
|
|
34
|
+
};
|
|
35
|
+
const getPprIndex = (plugin, permission) => {
|
|
36
|
+
return permissionPoliciesRows.findIndex((ppr) => {
|
|
37
|
+
return ppr.plugin === plugin && ppr.permission === permission;
|
|
38
|
+
});
|
|
39
|
+
};
|
|
40
|
+
const getPolicies = (plugin, pp) => {
|
|
41
|
+
const pprIndex = getPprIndex(plugin, pp.permission);
|
|
42
|
+
return permissionPoliciesRows?.[pprIndex]?.policies || pp.actions.map((ac) => ({ policy: ac, effect: "deny" }));
|
|
43
|
+
};
|
|
44
|
+
const getPermissionCellLabel = (plugin) => {
|
|
45
|
+
if (permissionPoliciesRows.find((ppr) => ppr.plugin === plugin)) {
|
|
46
|
+
return "Edit...";
|
|
39
47
|
}
|
|
40
|
-
return
|
|
48
|
+
return "Select...";
|
|
41
49
|
};
|
|
42
|
-
return /* @__PURE__ */
|
|
43
|
-
|
|
50
|
+
return /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, /* @__PURE__ */ React__default.createElement(TableRow, null, /* @__PURE__ */ React__default.createElement(
|
|
51
|
+
TableCell,
|
|
44
52
|
{
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
}
|
|
49
|
-
},
|
|
50
|
-
"What can users/groups access?"
|
|
51
|
-
), /* @__PURE__ */ React.createElement(
|
|
52
|
-
"div",
|
|
53
|
-
{
|
|
54
|
-
style: {
|
|
53
|
+
align: "left",
|
|
54
|
+
sx: {
|
|
55
|
+
borderBottom: "none",
|
|
55
56
|
display: "flex",
|
|
56
|
-
|
|
57
|
-
|
|
57
|
+
alignItems: "center",
|
|
58
|
+
fontWeight: (theme) => theme.typography.fontWeightMedium
|
|
58
59
|
}
|
|
59
60
|
},
|
|
60
|
-
/* @__PURE__ */
|
|
61
|
-
Autocomplete,
|
|
62
|
-
{
|
|
63
|
-
options: permissionPoliciesData?.plugins ?? [],
|
|
64
|
-
style: { width: "35%", flexGrow: "1" },
|
|
65
|
-
value: permissionPoliciesRowData.plugin || null,
|
|
66
|
-
onChange: (_e, value) => {
|
|
67
|
-
onChangePlugin(value ?? "");
|
|
68
|
-
},
|
|
69
|
-
renderInput: (params) => /* @__PURE__ */ React.createElement(
|
|
70
|
-
TextField,
|
|
71
|
-
{
|
|
72
|
-
...params,
|
|
73
|
-
label: "Plugin",
|
|
74
|
-
name: `${rowName}.plugin`,
|
|
75
|
-
variant: "outlined",
|
|
76
|
-
placeholder: "Select a plugin",
|
|
77
|
-
error: !!pluginError,
|
|
78
|
-
helperText: pluginError ?? "",
|
|
79
|
-
onBlur: handleBlur,
|
|
80
|
-
required: true
|
|
81
|
-
}
|
|
82
|
-
)
|
|
83
|
-
}
|
|
84
|
-
),
|
|
85
|
-
/* @__PURE__ */ React.createElement(
|
|
86
|
-
Autocomplete,
|
|
87
|
-
{
|
|
88
|
-
disabled: !permissionPoliciesRowData.plugin,
|
|
89
|
-
options: permissionPoliciesData?.pluginsPermissions?.[permissionPoliciesRowData.plugin]?.permissions ?? [],
|
|
90
|
-
style: { width: "35%", flexGrow: "1" },
|
|
91
|
-
value: permissionPoliciesRowData.permission || null,
|
|
92
|
-
onChange: (_e, value) => onChangePermission(
|
|
93
|
-
value ?? "",
|
|
94
|
-
permissionPoliciesData?.pluginsPermissions?.[permissionPoliciesRowData.plugin]?.policies[value ?? ""]?.isResourced ?? false,
|
|
95
|
-
value ? permissionPoliciesData?.pluginsPermissions?.[permissionPoliciesRowData.plugin]?.policies?.[value].policies : void 0
|
|
96
|
-
),
|
|
97
|
-
getOptionDisabled: getPermissionDisabled,
|
|
98
|
-
getOptionLabel: (option) => option || "",
|
|
99
|
-
renderInput: (params) => /* @__PURE__ */ React.createElement(
|
|
100
|
-
TextField,
|
|
101
|
-
{
|
|
102
|
-
...params,
|
|
103
|
-
label: "Resource type",
|
|
104
|
-
name: `${rowName}.permission`,
|
|
105
|
-
variant: "outlined",
|
|
106
|
-
placeholder: "Select a resource type",
|
|
107
|
-
error: !!permissionError,
|
|
108
|
-
helperText: permissionError ?? "",
|
|
109
|
-
onBlur: handleBlur,
|
|
110
|
-
required: true
|
|
111
|
-
}
|
|
112
|
-
)
|
|
113
|
-
}
|
|
114
|
-
),
|
|
115
|
-
/* @__PURE__ */ React.createElement("div", { style: { width: "23%", alignSelf: "center", flexGrow: 1 } }, permissionPoliciesRowData.isResourced && !!conditionRulesData?.[`${permissionPoliciesRowData.plugin}`]?.[`${permissionPoliciesRowData.permission}`]?.rules.length && /* @__PURE__ */ React.createElement(
|
|
61
|
+
/* @__PURE__ */ React__default.createElement(
|
|
116
62
|
IconButton,
|
|
117
63
|
{
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
"
|
|
122
|
-
sx: {
|
|
123
|
-
fontSize: (theme) => theme.typography.fontSize
|
|
124
|
-
},
|
|
125
|
-
onClick: () => setSidebarOpen(true),
|
|
126
|
-
disabled: !!conditionRulesError
|
|
64
|
+
"aria-label": "expand-row",
|
|
65
|
+
size: "small",
|
|
66
|
+
onClick: () => setCurrentOpen(!currentOpen),
|
|
67
|
+
"data-testid": `expand-row-${rowData.plugin}`
|
|
127
68
|
},
|
|
128
|
-
/* @__PURE__ */
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
color: (theme) => theme.palette.grey[500],
|
|
139
|
-
flexGrow: 0,
|
|
140
|
-
alignSelf: "center"
|
|
141
|
-
},
|
|
142
|
-
onClick: () => onRemove(),
|
|
143
|
-
disabled: rowCount === 1,
|
|
144
|
-
"data-testid": `${rowName}-remove`
|
|
69
|
+
currentOpen ? /* @__PURE__ */ React__default.createElement(ArrowDownIcon, null) : /* @__PURE__ */ React__default.createElement(ArrowRightIcon, null)
|
|
70
|
+
),
|
|
71
|
+
rowData.name
|
|
72
|
+
), /* @__PURE__ */ React__default.createElement(TableCell, { align: "left", sx: { borderBottom: "none" } }, /* @__PURE__ */ React__default.createElement(
|
|
73
|
+
Link,
|
|
74
|
+
{
|
|
75
|
+
sx: {
|
|
76
|
+
cursor: "pointer",
|
|
77
|
+
textDecoration: "none",
|
|
78
|
+
color: (theme) => theme.palette.primary.main
|
|
145
79
|
},
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
80
|
+
onClick: () => setCurrentOpen(true)
|
|
81
|
+
},
|
|
82
|
+
getPermissionCellLabel(rowData.plugin)
|
|
83
|
+
)), /* @__PURE__ */ React__default.createElement(TableCell, { align: "right", sx: { borderBottom: "none" } }, /* @__PURE__ */ React__default.createElement(
|
|
84
|
+
IconButton,
|
|
150
85
|
{
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
|
|
86
|
+
"aria-label": "remove",
|
|
87
|
+
size: "small",
|
|
88
|
+
onClick: () => onRemovePlugin(rowData.plugin)
|
|
89
|
+
},
|
|
90
|
+
/* @__PURE__ */ React__default.createElement(Delete, null)
|
|
91
|
+
))), /* @__PURE__ */ React__default.createElement(TableRow, null, /* @__PURE__ */ React__default.createElement(
|
|
92
|
+
TableCell,
|
|
157
93
|
{
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
94
|
+
sx: { p: 0 },
|
|
95
|
+
colSpan: 6,
|
|
96
|
+
"data-testid": `nested-row-${rowData.plugin}`
|
|
97
|
+
},
|
|
98
|
+
/* @__PURE__ */ React__default.createElement(Collapse, { in: currentOpen, timeout: "auto", unmountOnExit: true }, /* @__PURE__ */ React__default.createElement(Box, null, /* @__PURE__ */ React__default.createElement(Table, { size: "small", "aria-label": "permission-policies" }, /* @__PURE__ */ React__default.createElement(TableBody, null, rowData.permissionPolicies.map((pp) => /* @__PURE__ */ React__default.createElement(
|
|
99
|
+
PermissionPoliciesFormNestedRow,
|
|
100
|
+
{
|
|
101
|
+
key: pp.permission,
|
|
102
|
+
plugin: rowData.plugin,
|
|
103
|
+
permissionPolicy: pp,
|
|
104
|
+
permissionPolicyRowIndex: getPprIndex(
|
|
105
|
+
rowData.plugin,
|
|
106
|
+
pp.permission
|
|
107
|
+
),
|
|
108
|
+
policies: getPolicies(rowData.plugin, pp),
|
|
109
|
+
conditionRulesLength: conditionRulesData?.[`${rowData.plugin}`]?.[`${pp.resourceType}`]?.rules.length,
|
|
110
|
+
totalRulesCount: getTotalRules(
|
|
111
|
+
permissionPoliciesRows[getPprIndex(rowData.plugin, pp.permission)]?.conditions
|
|
112
|
+
),
|
|
113
|
+
conditionsData: permissionPoliciesRows[getPprIndex(rowData.plugin, pp.permission)]?.conditions,
|
|
114
|
+
conditionRulesData,
|
|
115
|
+
onSelectPermission,
|
|
116
|
+
onSelectPolicy,
|
|
117
|
+
onRemovePermission,
|
|
118
|
+
onAddConditions
|
|
119
|
+
}
|
|
120
|
+
))))))
|
|
121
|
+
)));
|
|
171
122
|
};
|
|
172
123
|
|
|
173
|
-
export { PermissionPoliciesFormRow };
|
|
124
|
+
export { PermissionPoliciesFormRow as default };
|
|
174
125
|
//# sourceMappingURL=PermissionPoliciesFormRow.esm.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PermissionPoliciesFormRow.esm.js","sources":["../../../src/components/CreateRole/PermissionPoliciesFormRow.tsx"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\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 */\nimport React from 'react';\n\nimport ChecklistRtlIcon from '@mui/icons-material/ChecklistRtl';\nimport HelpOutlineIcon from '@mui/icons-material/HelpOutline';\nimport RemoveIcon from '@mui/icons-material/Remove';\nimport Autocomplete from '@mui/material/Autocomplete';\nimport FormLabel from '@mui/material/FormLabel';\nimport IconButton from '@mui/material/IconButton';\nimport TextField from '@mui/material/TextField';\nimport Tooltip from '@mui/material/Tooltip';\nimport Typography from '@mui/material/Typography';\nimport { FormikErrors } from 'formik';\n\nimport { PermissionsData } from '../../types';\nimport { getRulesNumber } from '../../utils/create-role-utils';\nimport { ConditionalAccessSidebar } from '../ConditionalAccess/ConditionalAccessSidebar';\nimport { ConditionRules, ConditionsData } from '../ConditionalAccess/types';\nimport { PoliciesCheckboxGroup } from './PoliciesCheckboxGroup';\nimport { PluginsPermissionPoliciesData } from './types';\n\ntype PermissionPoliciesFormRowProps = {\n permissionPoliciesRowData: PermissionsData;\n permissionPoliciesData?: PluginsPermissionPoliciesData;\n permissionPoliciesRowError: FormikErrors<PermissionsData>;\n rowCount: number;\n rowName: string;\n conditionRules: ConditionRules;\n onRemove: () => void;\n onChangePlugin: (plugin: string) => void;\n onChangePermission: (\n permission: string,\n isResourced: boolean,\n policies?: string[],\n ) => void;\n onChangePolicy: (isChecked: boolean, policyIndex: number) => void;\n handleBlur: React.FocusEventHandler<HTMLInputElement | HTMLTextAreaElement>;\n getPermissionDisabled: (permission: string) => boolean;\n onAddConditions: (conditions?: ConditionsData) => void;\n};\n\nexport const PermissionPoliciesFormRow = ({\n permissionPoliciesRowData,\n permissionPoliciesData,\n permissionPoliciesRowError,\n rowCount,\n rowName,\n conditionRules,\n onRemove,\n onChangePermission,\n onChangePolicy,\n onChangePlugin,\n handleBlur,\n getPermissionDisabled,\n onAddConditions,\n}: PermissionPoliciesFormRowProps) => {\n const { plugin: pluginError, permission: permissionError } =\n permissionPoliciesRowError;\n const { data: conditionRulesData, error: conditionRulesError } =\n conditionRules;\n const totalRules = getRulesNumber(permissionPoliciesRowData.conditions);\n\n const [sidebarOpen, setSidebarOpen] = React.useState<boolean>(false);\n\n const tooltipTitle = () => (\n <div>\n <Typography component=\"p\" align=\"center\">\n Define access conditions for the selected resource type using Rules.\n Rules vary by resource type.{' '}\n <b>Users have access to the resource type content by default</b> unless\n configured otherwise.\n </Typography>\n </div>\n );\n\n const getTotalRules = (): string => {\n let accessMessage = 'Configure access';\n\n if (totalRules > 0) {\n accessMessage += ` (${totalRules} ${totalRules > 1 ? 'rules' : 'rule'})`;\n }\n return accessMessage;\n };\n\n return (\n <div>\n <div style={{ display: 'flex', flexFlow: 'column', gap: '15px' }}>\n <FormLabel\n style={{\n fontWeight: 800,\n fontSize: '0.8rem',\n }}\n >\n What can users/groups access?\n </FormLabel>\n <div\n style={{\n display: 'flex',\n gap: '20px',\n marginBottom: '15px',\n }}\n >\n <Autocomplete\n options={permissionPoliciesData?.plugins ?? []}\n style={{ width: '35%', flexGrow: '1' }}\n value={permissionPoliciesRowData.plugin || null}\n onChange={(_e, value) => {\n onChangePlugin(value ?? '');\n }}\n renderInput={(params: any) => (\n <TextField\n {...params}\n label=\"Plugin\"\n name={`${rowName}.plugin`}\n variant=\"outlined\"\n placeholder=\"Select a plugin\"\n error={!!pluginError}\n helperText={pluginError ?? ''}\n onBlur={handleBlur}\n required\n />\n )}\n />\n <Autocomplete\n disabled={!permissionPoliciesRowData.plugin}\n options={\n permissionPoliciesData?.pluginsPermissions?.[\n permissionPoliciesRowData.plugin\n ]?.permissions ?? []\n }\n style={{ width: '35%', flexGrow: '1' }}\n value={permissionPoliciesRowData.permission || null}\n onChange={(_e, value) =>\n onChangePermission(\n value ?? '',\n permissionPoliciesData?.pluginsPermissions?.[\n permissionPoliciesRowData.plugin\n ]?.policies[value ?? '']?.isResourced ?? false,\n value\n ? permissionPoliciesData?.pluginsPermissions?.[\n permissionPoliciesRowData.plugin\n ]?.policies?.[value].policies\n : undefined,\n )\n }\n getOptionDisabled={getPermissionDisabled}\n getOptionLabel={option => option || ''}\n renderInput={(params: any) => (\n <TextField\n {...params}\n label=\"Resource type\"\n name={`${rowName}.permission`}\n variant=\"outlined\"\n placeholder=\"Select a resource type\"\n error={!!permissionError}\n helperText={permissionError ?? ''}\n onBlur={handleBlur}\n required\n />\n )}\n />\n <div style={{ width: '23%', alignSelf: 'center', flexGrow: 1 }}>\n {permissionPoliciesRowData.isResourced &&\n !!conditionRulesData?.[`${permissionPoliciesRowData.plugin}`]?.[\n `${permissionPoliciesRowData.permission}`\n ]?.rules.length && (\n <IconButton\n title=\"\"\n color=\"primary\"\n hidden={\n !permissionPoliciesData?.pluginsPermissions[\n permissionPoliciesRowData.plugin\n ]?.policies[permissionPoliciesRowData.permission]\n ?.isResourced\n }\n aria-label=\"configure-access\"\n sx={{\n fontSize: theme => theme.typography.fontSize,\n }}\n onClick={() => setSidebarOpen(true)}\n disabled={!!conditionRulesError}\n >\n <ChecklistRtlIcon fontSize=\"small\" />\n {getTotalRules()}\n \n <Tooltip title={tooltipTitle()} placement=\"top\">\n <HelpOutlineIcon fontSize=\"inherit\" />\n </Tooltip>\n </IconButton>\n )}\n </div>\n <IconButton\n title=\"Remove\"\n sx={{\n color: theme => theme.palette.grey[500],\n flexGrow: 0,\n alignSelf: 'center',\n }}\n onClick={() => onRemove()}\n disabled={rowCount === 1}\n data-testid={`${rowName}-remove`}\n >\n <RemoveIcon id={`${rowName}-remove`} />\n </IconButton>\n </div>\n </div>\n <PoliciesCheckboxGroup\n permissionPoliciesRowData={permissionPoliciesRowData}\n onChangePolicy={onChangePolicy}\n rowName={rowName}\n />\n <ConditionalAccessSidebar\n open={sidebarOpen}\n onClose={() => {\n setSidebarOpen(false);\n }}\n onSave={(conditions?: ConditionsData) => {\n onAddConditions(conditions);\n setSidebarOpen(false);\n }}\n conditionsFormVal={permissionPoliciesRowData.conditions}\n selPluginResourceType={permissionPoliciesRowData.permission}\n conditionRulesData={\n conditionRulesData?.[`${permissionPoliciesRowData.plugin}`]?.[\n `${permissionPoliciesRowData.permission}`\n ]\n }\n />\n </div>\n );\n};\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"PermissionPoliciesFormRow.esm.js","sources":["../../../src/components/CreateRole/PermissionPoliciesFormRow.tsx"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\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 */\nimport React from 'react';\n\nimport IconButton from '@mui/material/IconButton';\nimport { PermissionsData } from '../../types';\nimport { getRulesNumber } from '../../utils/create-role-utils';\nimport { ConditionRulesData, ConditionsData } from '../ConditionalAccess/types';\nimport TableRow from '@mui/material/TableRow';\nimport TableCell from '@mui/material/TableCell';\nimport Collapse from '@mui/material/Collapse';\nimport Box from '@mui/material/Box';\nimport Table from '@mui/material/Table';\nimport TableBody from '@mui/material/TableBody';\nimport DeleteIcon from '@mui/icons-material/Delete';\nimport ArrowRightIcon from '@mui/icons-material/KeyboardArrowRight';\nimport ArrowDownIcon from '@mui/icons-material/KeyboardArrowDown';\nimport PermissionPoliciesFormNestedRow from './PermissionPoliciesFormNestedRow';\nimport Link from '@mui/material/Link';\n\ntype PermissionPoliciesFormRowProps = {\n rowData: any;\n conditionRulesData?: ConditionRulesData;\n permissionPoliciesRows: PermissionsData[];\n open: boolean;\n onSelectPermission: (\n plugin: string,\n permission: string,\n isResourced: boolean,\n policies: string[],\n resourceType?: string,\n ) => void;\n onSelectPolicy: (\n isChecked: boolean,\n policyIndex: number,\n pIndex: number,\n ) => void;\n onRemovePermission: (index: number) => void;\n onRemovePlugin: (plugin: string) => void;\n setOpen: React.Dispatch<React.SetStateAction<boolean>>;\n onAddConditions: (index: number, conditions?: ConditionsData) => void;\n};\n\nconst PermissionPoliciesFormRow = ({\n rowData,\n permissionPoliciesRows,\n conditionRulesData,\n open,\n onSelectPermission,\n onSelectPolicy,\n onRemovePermission,\n onRemovePlugin,\n onAddConditions,\n}: PermissionPoliciesFormRowProps) => {\n const [currentOpen, setCurrentOpen] = React.useState<boolean>(false);\n\n React.useEffect(() => {\n setCurrentOpen(open);\n }, [open]);\n\n const getTotalRules = (conditions?: ConditionsData): number => {\n const totalRules = getRulesNumber(conditions);\n return totalRules;\n };\n\n const getPprIndex = (plugin: string, permission: string) => {\n return permissionPoliciesRows.findIndex(ppr => {\n return ppr.plugin === plugin && ppr.permission === permission;\n });\n };\n\n const getPolicies = (plugin: string, pp: any) => {\n const pprIndex = getPprIndex(plugin, pp.permission);\n return (\n permissionPoliciesRows?.[pprIndex]?.policies ||\n pp.actions.map((ac: string) => ({ policy: ac, effect: 'deny' }))\n );\n };\n\n const getPermissionCellLabel = (plugin: string) => {\n if (permissionPoliciesRows.find(ppr => ppr.plugin === plugin)) {\n return 'Edit...';\n }\n\n return 'Select...';\n };\n\n return (\n <>\n <TableRow>\n <TableCell\n align=\"left\"\n sx={{\n borderBottom: 'none',\n display: 'flex',\n alignItems: 'center',\n fontWeight: theme => theme.typography.fontWeightMedium,\n }}\n >\n <IconButton\n aria-label=\"expand-row\"\n size=\"small\"\n onClick={() => setCurrentOpen(!currentOpen)}\n data-testid={`expand-row-${rowData.plugin}`}\n >\n {currentOpen ? <ArrowDownIcon /> : <ArrowRightIcon />}\n </IconButton>\n {rowData.name}\n </TableCell>\n <TableCell align=\"left\" sx={{ borderBottom: 'none' }}>\n <Link\n sx={{\n cursor: 'pointer',\n textDecoration: 'none',\n color: theme => theme.palette.primary.main,\n }}\n onClick={() => setCurrentOpen(true)}\n >\n {getPermissionCellLabel(rowData.plugin)}\n </Link>\n </TableCell>\n <TableCell align=\"right\" sx={{ borderBottom: 'none' }}>\n <IconButton\n aria-label=\"remove\"\n size=\"small\"\n onClick={() => onRemovePlugin(rowData.plugin)}\n >\n <DeleteIcon />\n </IconButton>\n </TableCell>\n </TableRow>\n <TableRow>\n <TableCell\n sx={{ p: 0 }}\n colSpan={6}\n data-testid={`nested-row-${rowData.plugin}`}\n >\n <Collapse in={currentOpen} timeout=\"auto\" unmountOnExit>\n <Box>\n <Table size=\"small\" aria-label=\"permission-policies\">\n <TableBody>\n {rowData.permissionPolicies.map((pp: any) => (\n <PermissionPoliciesFormNestedRow\n key={pp.permission}\n plugin={rowData.plugin}\n permissionPolicy={pp}\n permissionPolicyRowIndex={getPprIndex(\n rowData.plugin,\n pp.permission,\n )}\n policies={getPolicies(rowData.plugin, pp)}\n conditionRulesLength={\n conditionRulesData?.[`${rowData.plugin}`]?.[\n `${pp.resourceType}`\n ]?.rules.length\n }\n totalRulesCount={getTotalRules(\n permissionPoliciesRows[\n getPprIndex(rowData.plugin, pp.permission)\n ]?.conditions,\n )}\n conditionsData={\n permissionPoliciesRows[\n getPprIndex(rowData.plugin, pp.permission)\n ]?.conditions\n }\n conditionRulesData={conditionRulesData}\n onSelectPermission={onSelectPermission}\n onSelectPolicy={onSelectPolicy}\n onRemovePermission={onRemovePermission}\n onAddConditions={onAddConditions}\n />\n ))}\n </TableBody>\n </Table>\n </Box>\n </Collapse>\n </TableCell>\n </TableRow>\n </>\n );\n};\n\nexport default PermissionPoliciesFormRow;\n"],"names":["React","DeleteIcon"],"mappings":"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"}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import Table from '@mui/material/Table';
|
|
3
|
+
import TableBody from '@mui/material/TableBody';
|
|
4
|
+
import TableCell from '@mui/material/TableCell';
|
|
5
|
+
import TableContainer from '@mui/material/TableContainer';
|
|
6
|
+
import TableHead from '@mui/material/TableHead';
|
|
7
|
+
import TablePagination from '@mui/material/TablePagination';
|
|
8
|
+
import TableRow from '@mui/material/TableRow';
|
|
9
|
+
import Toolbar from '@mui/material/Toolbar';
|
|
10
|
+
import Typography from '@mui/material/Typography';
|
|
11
|
+
import Paper from '@mui/material/Paper';
|
|
12
|
+
import IconButton from '@mui/material/IconButton';
|
|
13
|
+
import SearchIcon from '@mui/icons-material/Search';
|
|
14
|
+
import ClearIcon from '@mui/icons-material/Clear';
|
|
15
|
+
import ArrowRightIcon from '@mui/icons-material/KeyboardArrowRight';
|
|
16
|
+
import ArrowDownIcon from '@mui/icons-material/KeyboardArrowDown';
|
|
17
|
+
import PermissionPoliciesFormRow from './PermissionPoliciesFormRow.esm.js';
|
|
18
|
+
import Box from '@mui/material/Box';
|
|
19
|
+
import TextField from '@mui/material/TextField';
|
|
20
|
+
import InputAdornment from '@mui/material/InputAdornment';
|
|
21
|
+
|
|
22
|
+
const PermissionPoliciesFormTableToolbar = ({
|
|
23
|
+
numSelected,
|
|
24
|
+
search,
|
|
25
|
+
setSearch
|
|
26
|
+
}) => {
|
|
27
|
+
return /* @__PURE__ */ React.createElement(
|
|
28
|
+
Toolbar,
|
|
29
|
+
{
|
|
30
|
+
sx: {
|
|
31
|
+
p: [4, 0, 2, 2]
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
/* @__PURE__ */ React.createElement(
|
|
35
|
+
Typography,
|
|
36
|
+
{
|
|
37
|
+
sx: {
|
|
38
|
+
flex: "1 1 100%",
|
|
39
|
+
fontWeight: (theme) => theme.typography.fontWeightBold
|
|
40
|
+
},
|
|
41
|
+
variant: "h5",
|
|
42
|
+
id: "tableTitle",
|
|
43
|
+
component: "div"
|
|
44
|
+
},
|
|
45
|
+
numSelected > 0 ? `${numSelected} plugins` : "No plugins selected"
|
|
46
|
+
),
|
|
47
|
+
/* @__PURE__ */ React.createElement(
|
|
48
|
+
TextField,
|
|
49
|
+
{
|
|
50
|
+
sx: { width: "30%" },
|
|
51
|
+
id: "input-with-icon-textfield",
|
|
52
|
+
placeholder: "Search",
|
|
53
|
+
value: search,
|
|
54
|
+
onChange: (e) => setSearch(e.target.value),
|
|
55
|
+
InputProps: {
|
|
56
|
+
startAdornment: /* @__PURE__ */ React.createElement(InputAdornment, { position: "start" }, /* @__PURE__ */ React.createElement(SearchIcon, null)),
|
|
57
|
+
endAdornment: /* @__PURE__ */ React.createElement(InputAdornment, { position: "start" }, /* @__PURE__ */ React.createElement(IconButton, { onClick: () => setSearch("") }, /* @__PURE__ */ React.createElement(ClearIcon, null)))
|
|
58
|
+
},
|
|
59
|
+
variant: "standard"
|
|
60
|
+
}
|
|
61
|
+
)
|
|
62
|
+
);
|
|
63
|
+
};
|
|
64
|
+
const PermissionPoliciesFormTable = ({
|
|
65
|
+
selectedPluginsCount,
|
|
66
|
+
data,
|
|
67
|
+
permissionPoliciesRows,
|
|
68
|
+
conditionRulesData,
|
|
69
|
+
onSelectPermission,
|
|
70
|
+
onSelectPolicy,
|
|
71
|
+
onRemovePermission,
|
|
72
|
+
onRemovePlugin,
|
|
73
|
+
onAddConditions
|
|
74
|
+
}) => {
|
|
75
|
+
const [page, setPage] = React.useState(0);
|
|
76
|
+
const [rowsPerPage, setRowsPerPage] = React.useState(5);
|
|
77
|
+
const [open, setOpen] = React.useState(false);
|
|
78
|
+
const [search, setSearch] = React.useState("");
|
|
79
|
+
const [filteredData, setFilteredData] = React.useState([]);
|
|
80
|
+
React.useEffect(() => {
|
|
81
|
+
if (search)
|
|
82
|
+
setFilteredData(
|
|
83
|
+
data?.filter((row) => row.plugin.includes(search)) ?? []
|
|
84
|
+
);
|
|
85
|
+
else setFilteredData(data);
|
|
86
|
+
}, [search, data]);
|
|
87
|
+
const handleChangePage = (_event, newPage) => {
|
|
88
|
+
setPage(newPage);
|
|
89
|
+
};
|
|
90
|
+
const handleChangeRowsPerPage = (event) => {
|
|
91
|
+
setRowsPerPage(+event.target.value);
|
|
92
|
+
setPage(0);
|
|
93
|
+
};
|
|
94
|
+
return /* @__PURE__ */ React.createElement(Paper, { sx: { width: "100%", mb: 2, p: 2 } }, /* @__PURE__ */ React.createElement(
|
|
95
|
+
PermissionPoliciesFormTableToolbar,
|
|
96
|
+
{
|
|
97
|
+
numSelected: selectedPluginsCount,
|
|
98
|
+
search,
|
|
99
|
+
setSearch
|
|
100
|
+
}
|
|
101
|
+
), /* @__PURE__ */ React.createElement(TableContainer, { component: Paper, sx: { outline: "0" } }, /* @__PURE__ */ React.createElement(Table, { "aria-label": "collapsible table" }, /* @__PURE__ */ React.createElement(TableHead, null, /* @__PURE__ */ React.createElement(TableRow, null, /* @__PURE__ */ React.createElement(
|
|
102
|
+
TableCell,
|
|
103
|
+
{
|
|
104
|
+
align: "left",
|
|
105
|
+
sx: {
|
|
106
|
+
display: "flex",
|
|
107
|
+
alignItems: "center",
|
|
108
|
+
width: "100%",
|
|
109
|
+
fontWeight: (theme) => theme.typography.fontWeightBold
|
|
110
|
+
}
|
|
111
|
+
},
|
|
112
|
+
/* @__PURE__ */ React.createElement(
|
|
113
|
+
IconButton,
|
|
114
|
+
{
|
|
115
|
+
"aria-label": "expand row",
|
|
116
|
+
size: "small",
|
|
117
|
+
onClick: () => setOpen(!open)
|
|
118
|
+
},
|
|
119
|
+
open ? /* @__PURE__ */ React.createElement(ArrowDownIcon, null) : /* @__PURE__ */ React.createElement(ArrowRightIcon, null)
|
|
120
|
+
),
|
|
121
|
+
"Name"
|
|
122
|
+
), /* @__PURE__ */ React.createElement(
|
|
123
|
+
TableCell,
|
|
124
|
+
{
|
|
125
|
+
align: "left",
|
|
126
|
+
sx: {
|
|
127
|
+
width: "60%",
|
|
128
|
+
fontWeight: (theme) => theme.typography.fontWeightBold
|
|
129
|
+
}
|
|
130
|
+
},
|
|
131
|
+
"Permission"
|
|
132
|
+
), /* @__PURE__ */ React.createElement(
|
|
133
|
+
TableCell,
|
|
134
|
+
{
|
|
135
|
+
align: "right",
|
|
136
|
+
sx: {
|
|
137
|
+
width: "10%",
|
|
138
|
+
fontWeight: (theme) => theme.typography.fontWeightBold
|
|
139
|
+
}
|
|
140
|
+
},
|
|
141
|
+
"Actions"
|
|
142
|
+
))), /* @__PURE__ */ React.createElement(TableBody, null, filteredData.length > 0 ? filteredData.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage).map((row) => /* @__PURE__ */ React.createElement(
|
|
143
|
+
PermissionPoliciesFormRow,
|
|
144
|
+
{
|
|
145
|
+
key: row.plugin,
|
|
146
|
+
rowData: row,
|
|
147
|
+
conditionRulesData,
|
|
148
|
+
permissionPoliciesRows,
|
|
149
|
+
open,
|
|
150
|
+
onSelectPermission,
|
|
151
|
+
onSelectPolicy,
|
|
152
|
+
onRemovePermission,
|
|
153
|
+
onRemovePlugin,
|
|
154
|
+
setOpen,
|
|
155
|
+
onAddConditions
|
|
156
|
+
}
|
|
157
|
+
)) : /* @__PURE__ */ React.createElement(TableRow, null, /* @__PURE__ */ React.createElement(TableCell, { colSpan: 4 }, /* @__PURE__ */ React.createElement(Box, { sx: { display: "flex", justifyContent: "center", p: 2 } }, search && !filteredData.length ? "No records to display." : "Selected plugins appear here.")))))), /* @__PURE__ */ React.createElement(
|
|
158
|
+
TablePagination,
|
|
159
|
+
{
|
|
160
|
+
rowsPerPageOptions: [5, 10, 20],
|
|
161
|
+
component: "div",
|
|
162
|
+
count: data.length,
|
|
163
|
+
rowsPerPage,
|
|
164
|
+
page,
|
|
165
|
+
showFirstButton: true,
|
|
166
|
+
showLastButton: true,
|
|
167
|
+
onPageChange: handleChangePage,
|
|
168
|
+
onRowsPerPageChange: handleChangeRowsPerPage
|
|
169
|
+
}
|
|
170
|
+
));
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
export { PermissionPoliciesFormTable as default };
|
|
174
|
+
//# sourceMappingURL=PermissionPoliciesFormTable.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PermissionPoliciesFormTable.esm.js","sources":["../../../src/components/CreateRole/PermissionPoliciesFormTable.tsx"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\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 */\nimport * as React from 'react';\nimport Table from '@mui/material/Table';\nimport TableBody from '@mui/material/TableBody';\nimport TableCell from '@mui/material/TableCell';\nimport TableContainer from '@mui/material/TableContainer';\nimport TableHead from '@mui/material/TableHead';\nimport TablePagination from '@mui/material/TablePagination';\nimport TableRow from '@mui/material/TableRow';\nimport Toolbar from '@mui/material/Toolbar';\nimport Typography from '@mui/material/Typography';\nimport Paper from '@mui/material/Paper';\nimport IconButton from '@mui/material/IconButton';\nimport SearchIcon from '@mui/icons-material/Search';\nimport ClearIcon from '@mui/icons-material/Clear';\nimport ArrowRightIcon from '@mui/icons-material/KeyboardArrowRight';\nimport ArrowDownIcon from '@mui/icons-material/KeyboardArrowDown';\nimport { PermissionsData } from '../../types';\nimport { ConditionRulesData, ConditionsData } from '../ConditionalAccess/types';\nimport PermissionPoliciesFormRow from './PermissionPoliciesFormRow';\nimport Box from '@mui/material/Box';\nimport TextField from '@mui/material/TextField';\nimport InputAdornment from '@mui/material/InputAdornment';\n\ninterface PermissionPoliciesTableToolbarProps {\n numSelected: number;\n search: string;\n setSearch: React.Dispatch<React.SetStateAction<string>>;\n}\n\nconst PermissionPoliciesFormTableToolbar = ({\n numSelected,\n search,\n setSearch,\n}: PermissionPoliciesTableToolbarProps) => {\n return (\n <Toolbar\n sx={{\n p: [4, 0, 2, 2],\n }}\n >\n <Typography\n sx={{\n flex: '1 1 100%',\n fontWeight: theme => theme.typography.fontWeightBold,\n }}\n variant=\"h5\"\n id=\"tableTitle\"\n component=\"div\"\n >\n {numSelected > 0 ? `${numSelected} plugins` : 'No plugins selected'}\n </Typography>\n\n <TextField\n sx={{ width: '30%' }}\n id=\"input-with-icon-textfield\"\n placeholder=\"Search\"\n value={search}\n onChange={e => setSearch(e.target.value)}\n InputProps={{\n startAdornment: (\n <InputAdornment position=\"start\">\n <SearchIcon />\n </InputAdornment>\n ),\n endAdornment: (\n <InputAdornment position=\"start\">\n <IconButton onClick={() => setSearch('')}>\n <ClearIcon />\n </IconButton>\n </InputAdornment>\n ),\n }}\n variant=\"standard\"\n />\n </Toolbar>\n );\n};\n\nconst PermissionPoliciesFormTable = ({\n selectedPluginsCount,\n data,\n permissionPoliciesRows,\n conditionRulesData,\n onSelectPermission,\n onSelectPolicy,\n onRemovePermission,\n onRemovePlugin,\n onAddConditions,\n}: {\n selectedPluginsCount: number;\n data: any;\n permissionPoliciesRows: PermissionsData[];\n conditionRulesData?: ConditionRulesData;\n onRemovePermission: (index: number) => void;\n onSelectPermission: (\n plugin: string,\n permission: string,\n isResourced: boolean,\n policies: string[],\n resourceType?: string,\n ) => void;\n onSelectPolicy: (\n isChecked: boolean,\n policyIndex: number,\n pIndex: number,\n ) => void;\n onRemovePlugin: (plugin: string) => void;\n onAddConditions: (index: number, conditions?: ConditionsData) => void;\n}) => {\n const [page, setPage] = React.useState(0);\n const [rowsPerPage, setRowsPerPage] = React.useState(5);\n const [open, setOpen] = React.useState<boolean>(false);\n const [search, setSearch] = React.useState<string>('');\n const [filteredData, setFilteredData] = React.useState<any>([]);\n\n React.useEffect(() => {\n if (search)\n setFilteredData(\n data?.filter((row: any) => row.plugin.includes(search)) ?? [],\n );\n else setFilteredData(data);\n }, [search, data]);\n\n const handleChangePage = (_event: unknown, newPage: number) => {\n setPage(newPage);\n };\n\n const handleChangeRowsPerPage = (\n event: React.ChangeEvent<HTMLInputElement>,\n ) => {\n setRowsPerPage(+event.target.value);\n setPage(0);\n };\n\n return (\n <Paper sx={{ width: '100%', mb: 2, p: 2 }}>\n <PermissionPoliciesFormTableToolbar\n numSelected={selectedPluginsCount}\n search={search}\n setSearch={setSearch}\n />\n <TableContainer component={Paper} sx={{ outline: '0' }}>\n <Table aria-label=\"collapsible table\">\n <TableHead>\n <TableRow>\n <TableCell\n align=\"left\"\n sx={{\n display: 'flex',\n alignItems: 'center',\n width: '100%',\n fontWeight: theme => theme.typography.fontWeightBold,\n }}\n >\n <IconButton\n aria-label=\"expand row\"\n size=\"small\"\n onClick={() => setOpen(!open)}\n >\n {open ? <ArrowDownIcon /> : <ArrowRightIcon />}\n </IconButton>\n Name\n </TableCell>\n <TableCell\n align=\"left\"\n sx={{\n width: '60%',\n fontWeight: theme => theme.typography.fontWeightBold,\n }}\n >\n Permission\n </TableCell>\n <TableCell\n align=\"right\"\n sx={{\n width: '10%',\n fontWeight: theme => theme.typography.fontWeightBold,\n }}\n >\n Actions\n </TableCell>\n </TableRow>\n </TableHead>\n <TableBody>\n {filteredData.length > 0 ? (\n filteredData\n .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)\n .map((row: any) => (\n <PermissionPoliciesFormRow\n key={row.plugin}\n rowData={row}\n conditionRulesData={conditionRulesData}\n permissionPoliciesRows={permissionPoliciesRows}\n open={open}\n onSelectPermission={onSelectPermission}\n onSelectPolicy={onSelectPolicy}\n onRemovePermission={onRemovePermission}\n onRemovePlugin={onRemovePlugin}\n setOpen={setOpen}\n onAddConditions={onAddConditions}\n />\n ))\n ) : (\n <TableRow>\n <TableCell colSpan={4}>\n <Box sx={{ display: 'flex', justifyContent: 'center', p: 2 }}>\n {search && !filteredData.length\n ? 'No records to display.'\n : 'Selected plugins appear here.'}\n </Box>\n </TableCell>\n </TableRow>\n )}\n </TableBody>\n </Table>\n </TableContainer>\n <TablePagination\n rowsPerPageOptions={[5, 10, 20]}\n component=\"div\"\n count={data.length}\n rowsPerPage={rowsPerPage}\n page={page}\n showFirstButton\n showLastButton\n onPageChange={handleChangePage}\n onRowsPerPageChange={handleChangeRowsPerPage}\n />\n </Paper>\n );\n};\n\nexport default PermissionPoliciesFormTable;\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import Autocomplete from '@mui/material/Autocomplete';
|
|
2
|
+
import React__default from 'react';
|
|
3
|
+
import { PluginsDropdownOption } from './PluginsDropdownOption.esm.js';
|
|
4
|
+
import TextField from '@mui/material/TextField';
|
|
5
|
+
|
|
6
|
+
const PluginsDropdown = ({
|
|
7
|
+
allPlugins,
|
|
8
|
+
selectedPlugins,
|
|
9
|
+
setFieldValue,
|
|
10
|
+
handleBlur,
|
|
11
|
+
onRemovePlugin,
|
|
12
|
+
onRemoveAllPlugins,
|
|
13
|
+
selectedPluginsError
|
|
14
|
+
}) => {
|
|
15
|
+
React__default.useEffect(() => {
|
|
16
|
+
if (selectedPlugins.length === allPlugins.length - 1)
|
|
17
|
+
setFieldValue(`selectedPlugins`, allPlugins, true);
|
|
18
|
+
}, []);
|
|
19
|
+
return /* @__PURE__ */ React__default.createElement(
|
|
20
|
+
Autocomplete,
|
|
21
|
+
{
|
|
22
|
+
options: allPlugins,
|
|
23
|
+
renderTags: () => "",
|
|
24
|
+
isOptionEqualToValue: (option, value) => option.label === value.label,
|
|
25
|
+
multiple: true,
|
|
26
|
+
disableCloseOnSelect: true,
|
|
27
|
+
getOptionLabel: (option) => option.label,
|
|
28
|
+
style: { width: "30%", flexGrow: "1" },
|
|
29
|
+
value: selectedPlugins || null,
|
|
30
|
+
onChange: (_e, selPlugins, reason, selOption) => {
|
|
31
|
+
const pVal = selOption?.option.value;
|
|
32
|
+
if (pVal === "") {
|
|
33
|
+
if (reason === "selectOption") {
|
|
34
|
+
setFieldValue(`selectedPlugins`, allPlugins, true);
|
|
35
|
+
} else if (reason === "removeOption") {
|
|
36
|
+
onRemoveAllPlugins();
|
|
37
|
+
}
|
|
38
|
+
} else if (pVal) {
|
|
39
|
+
if (reason === "removeOption") {
|
|
40
|
+
onRemovePlugin(pVal);
|
|
41
|
+
} else if (reason === "selectOption") {
|
|
42
|
+
if (selPlugins.length === allPlugins.length - 1)
|
|
43
|
+
setFieldValue(`selectedPlugins`, allPlugins, true);
|
|
44
|
+
else setFieldValue(`selectedPlugins`, selPlugins, true);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
renderOption: (props, option, state) => /* @__PURE__ */ React__default.createElement(PluginsDropdownOption, { props, option, state }),
|
|
49
|
+
renderInput: (params) => /* @__PURE__ */ React__default.createElement(
|
|
50
|
+
TextField,
|
|
51
|
+
{
|
|
52
|
+
...params,
|
|
53
|
+
label: "Select plugins",
|
|
54
|
+
variant: "outlined",
|
|
55
|
+
error: !!selectedPluginsError,
|
|
56
|
+
helperText: selectedPluginsError ?? "",
|
|
57
|
+
onBlur: handleBlur,
|
|
58
|
+
required: true
|
|
59
|
+
}
|
|
60
|
+
)
|
|
61
|
+
}
|
|
62
|
+
);
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
export { PluginsDropdown as default };
|
|
66
|
+
//# sourceMappingURL=PluginsDropdown.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PluginsDropdown.esm.js","sources":["../../../src/components/CreateRole/PluginsDropdown.tsx"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\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 */\nimport Autocomplete from '@mui/material/Autocomplete';\nimport React from 'react';\nimport { SelectedPlugin } from '../../types';\nimport { PluginsDropdownOption } from './PluginsDropdownOption';\nimport TextField from '@mui/material/TextField';\nimport { FormikErrors } from 'formik';\nimport { RoleFormValues } from './types';\n\ntype PluginsDropdownProps = {\n allPlugins: SelectedPlugin[];\n selectedPlugins: SelectedPlugin[];\n setFieldValue: (\n field: string,\n value: any,\n shouldValidate?: boolean,\n ) => Promise<FormikErrors<RoleFormValues>> | Promise<void>;\n handleBlur: React.FocusEventHandler<HTMLInputElement | HTMLTextAreaElement>;\n onRemoveAllPlugins: () => void;\n onRemovePlugin: (plugin: string) => void;\n selectedPluginsError: string;\n};\n\nconst PluginsDropdown = ({\n allPlugins,\n selectedPlugins,\n setFieldValue,\n handleBlur,\n onRemovePlugin,\n onRemoveAllPlugins,\n selectedPluginsError,\n}: PluginsDropdownProps) => {\n React.useEffect(() => {\n if (selectedPlugins.length === allPlugins.length - 1)\n setFieldValue(`selectedPlugins`, allPlugins, true);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n return (\n <Autocomplete\n options={allPlugins}\n renderTags={() => ''}\n isOptionEqualToValue={(option, value) => option.label === value.label}\n multiple\n disableCloseOnSelect\n getOptionLabel={option => option.label}\n style={{ width: '30%', flexGrow: '1' }}\n value={selectedPlugins || null}\n onChange={(_e, selPlugins, reason, selOption) => {\n const pVal = selOption?.option.value;\n if (pVal === '') {\n if (reason === 'selectOption') {\n setFieldValue(`selectedPlugins`, allPlugins, true);\n } else if (reason === 'removeOption') {\n onRemoveAllPlugins();\n }\n } else if (pVal) {\n if (reason === 'removeOption') {\n onRemovePlugin(pVal);\n } else if (reason === 'selectOption') {\n if (selPlugins.length === allPlugins.length - 1)\n setFieldValue(`selectedPlugins`, allPlugins, true);\n else setFieldValue(`selectedPlugins`, selPlugins, true);\n }\n }\n }}\n renderOption={(props, option: SelectedPlugin, state) => (\n <PluginsDropdownOption props={props} option={option} state={state} />\n )}\n renderInput={(params: any) => (\n <TextField\n {...params}\n label=\"Select plugins\"\n variant=\"outlined\"\n error={!!selectedPluginsError}\n helperText={selectedPluginsError ?? ''}\n onBlur={handleBlur}\n required\n />\n )}\n />\n );\n};\n\nexport default PluginsDropdown;\n"],"names":["React"],"mappings":";;;;;AAqCA,MAAM,kBAAkB,CAAC;AAAA,EACvB,UAAA;AAAA,EACA,eAAA;AAAA,EACA,aAAA;AAAA,EACA,UAAA;AAAA,EACA,cAAA;AAAA,EACA,kBAAA;AAAA,EACA;AACF,CAA4B,KAAA;AAC1B,EAAAA,cAAA,CAAM,UAAU,MAAM;AACpB,IAAI,IAAA,eAAA,CAAgB,MAAW,KAAA,UAAA,CAAW,MAAS,GAAA,CAAA;AACjD,MAAc,aAAA,CAAA,CAAA,eAAA,CAAA,EAAmB,YAAY,IAAI,CAAA;AAAA,GAErD,EAAG,EAAE,CAAA;AACL,EACE,uBAAAA,cAAA,CAAA,aAAA;AAAA,IAAC,YAAA;AAAA,IAAA;AAAA,MACC,OAAS,EAAA,UAAA;AAAA,MACT,YAAY,MAAM,EAAA;AAAA,MAClB,sBAAsB,CAAC,MAAA,EAAQ,KAAU,KAAA,MAAA,CAAO,UAAU,KAAM,CAAA,KAAA;AAAA,MAChE,QAAQ,EAAA,IAAA;AAAA,MACR,oBAAoB,EAAA,IAAA;AAAA,MACpB,cAAA,EAAgB,YAAU,MAAO,CAAA,KAAA;AAAA,MACjC,KAAO,EAAA,EAAE,KAAO,EAAA,KAAA,EAAO,UAAU,GAAI,EAAA;AAAA,MACrC,OAAO,eAAmB,IAAA,IAAA;AAAA,MAC1B,QAAU,EAAA,CAAC,EAAI,EAAA,UAAA,EAAY,QAAQ,SAAc,KAAA;AAC/C,QAAM,MAAA,IAAA,GAAO,WAAW,MAAO,CAAA,KAAA;AAC/B,QAAA,IAAI,SAAS,EAAI,EAAA;AACf,UAAA,IAAI,WAAW,cAAgB,EAAA;AAC7B,YAAc,aAAA,CAAA,CAAA,eAAA,CAAA,EAAmB,YAAY,IAAI,CAAA;AAAA,WACnD,MAAA,IAAW,WAAW,cAAgB,EAAA;AACpC,YAAmB,kBAAA,EAAA;AAAA;AACrB,mBACS,IAAM,EAAA;AACf,UAAA,IAAI,WAAW,cAAgB,EAAA;AAC7B,YAAA,cAAA,CAAe,IAAI,CAAA;AAAA,WACrB,MAAA,IAAW,WAAW,cAAgB,EAAA;AACpC,YAAI,IAAA,UAAA,CAAW,MAAW,KAAA,UAAA,CAAW,MAAS,GAAA,CAAA;AAC5C,cAAc,aAAA,CAAA,CAAA,eAAA,CAAA,EAAmB,YAAY,IAAI,CAAA;AAAA,iBAC9C,aAAA,CAAc,CAAmB,eAAA,CAAA,EAAA,UAAA,EAAY,IAAI,CAAA;AAAA;AACxD;AACF,OACF;AAAA,MACA,YAAA,EAAc,CAAC,KAAO,EAAA,MAAA,EAAwB,0BAC3CA,cAAA,CAAA,aAAA,CAAA,qBAAA,EAAA,EAAsB,KAAc,EAAA,MAAA,EAAgB,KAAc,EAAA,CAAA;AAAA,MAErE,WAAA,EAAa,CAAC,MACZ,qBAAAA,cAAA,CAAA,aAAA;AAAA,QAAC,SAAA;AAAA,QAAA;AAAA,UACE,GAAG,MAAA;AAAA,UACJ,KAAM,EAAA,gBAAA;AAAA,UACN,OAAQ,EAAA,UAAA;AAAA,UACR,KAAA,EAAO,CAAC,CAAC,oBAAA;AAAA,UACT,YAAY,oBAAwB,IAAA,EAAA;AAAA,UACpC,MAAQ,EAAA,UAAA;AAAA,UACR,QAAQ,EAAA;AAAA;AAAA;AACV;AAAA,GAEJ;AAEJ;;;;"}
|