@backstage-community/plugin-rbac 1.32.2

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.
Files changed (133) hide show
  1. package/CHANGELOG.md +761 -0
  2. package/README.md +106 -0
  3. package/app-config.yaml +19 -0
  4. package/dist/api/LicensedUsersClient.esm.js +45 -0
  5. package/dist/api/LicensedUsersClient.esm.js.map +1 -0
  6. package/dist/api/RBACBackendClient.esm.js +337 -0
  7. package/dist/api/RBACBackendClient.esm.js.map +1 -0
  8. package/dist/components/Administration.esm.js +23 -0
  9. package/dist/components/Administration.esm.js.map +1 -0
  10. package/dist/components/ConditionalAccess/AddNestedConditionButton.esm.js +23 -0
  11. package/dist/components/ConditionalAccess/AddNestedConditionButton.esm.js.map +1 -0
  12. package/dist/components/ConditionalAccess/ComplexConditionRow.esm.js +149 -0
  13. package/dist/components/ConditionalAccess/ComplexConditionRow.esm.js.map +1 -0
  14. package/dist/components/ConditionalAccess/ComplexConditionRowButtons.esm.js +62 -0
  15. package/dist/components/ConditionalAccess/ComplexConditionRowButtons.esm.js.map +1 -0
  16. package/dist/components/ConditionalAccess/ConditionRule.esm.js +34 -0
  17. package/dist/components/ConditionalAccess/ConditionRule.esm.js.map +1 -0
  18. package/dist/components/ConditionalAccess/ConditionalAccessSidebar.esm.js +93 -0
  19. package/dist/components/ConditionalAccess/ConditionalAccessSidebar.esm.js.map +1 -0
  20. package/dist/components/ConditionalAccess/ConditionsForm.esm.js +204 -0
  21. package/dist/components/ConditionalAccess/ConditionsForm.esm.js.map +1 -0
  22. package/dist/components/ConditionalAccess/ConditionsFormRow.esm.js +459 -0
  23. package/dist/components/ConditionalAccess/ConditionsFormRow.esm.js.map +1 -0
  24. package/dist/components/ConditionalAccess/ConditionsFormRowFields.esm.js +209 -0
  25. package/dist/components/ConditionalAccess/ConditionsFormRowFields.esm.js.map +1 -0
  26. package/dist/components/ConditionalAccess/CriteriaToggleButton.esm.js +33 -0
  27. package/dist/components/ConditionalAccess/CriteriaToggleButton.esm.js.map +1 -0
  28. package/dist/components/ConditionalAccess/CustomArrayField.esm.js +47 -0
  29. package/dist/components/ConditionalAccess/CustomArrayField.esm.js.map +1 -0
  30. package/dist/components/ConditionalAccess/RulesDropdownOption.esm.js +24 -0
  31. package/dist/components/ConditionalAccess/RulesDropdownOption.esm.js.map +1 -0
  32. package/dist/components/ConditionalAccess/const.esm.js +21 -0
  33. package/dist/components/ConditionalAccess/const.esm.js.map +1 -0
  34. package/dist/components/ConditionalAccess/types.esm.js +8 -0
  35. package/dist/components/ConditionalAccess/types.esm.js.map +1 -0
  36. package/dist/components/CreateRole/AddMembersForm.esm.js +94 -0
  37. package/dist/components/CreateRole/AddMembersForm.esm.js.map +1 -0
  38. package/dist/components/CreateRole/AddedMembersTable.esm.js +31 -0
  39. package/dist/components/CreateRole/AddedMembersTable.esm.js.map +1 -0
  40. package/dist/components/CreateRole/AddedMembersTableColumn.esm.js +77 -0
  41. package/dist/components/CreateRole/AddedMembersTableColumn.esm.js.map +1 -0
  42. package/dist/components/CreateRole/CreateRolePage.esm.js +53 -0
  43. package/dist/components/CreateRole/CreateRolePage.esm.js.map +1 -0
  44. package/dist/components/CreateRole/EditRolePage.esm.js +65 -0
  45. package/dist/components/CreateRole/EditRolePage.esm.js.map +1 -0
  46. package/dist/components/CreateRole/MembersDropdownOption.esm.js +40 -0
  47. package/dist/components/CreateRole/MembersDropdownOption.esm.js.map +1 -0
  48. package/dist/components/CreateRole/PermissionPoliciesForm.esm.js +144 -0
  49. package/dist/components/CreateRole/PermissionPoliciesForm.esm.js.map +1 -0
  50. package/dist/components/CreateRole/PermissionPoliciesFormRow.esm.js +179 -0
  51. package/dist/components/CreateRole/PermissionPoliciesFormRow.esm.js.map +1 -0
  52. package/dist/components/CreateRole/PoliciesCheckboxGroup.esm.js +76 -0
  53. package/dist/components/CreateRole/PoliciesCheckboxGroup.esm.js.map +1 -0
  54. package/dist/components/CreateRole/ReviewStep.esm.js +50 -0
  55. package/dist/components/CreateRole/ReviewStep.esm.js.map +1 -0
  56. package/dist/components/CreateRole/ReviewStepTable.esm.js +29 -0
  57. package/dist/components/CreateRole/ReviewStepTable.esm.js.map +1 -0
  58. package/dist/components/CreateRole/RoleDetailsForm.esm.js +57 -0
  59. package/dist/components/CreateRole/RoleDetailsForm.esm.js.map +1 -0
  60. package/dist/components/CreateRole/RoleForm.esm.js +271 -0
  61. package/dist/components/CreateRole/RoleForm.esm.js.map +1 -0
  62. package/dist/components/CreateRole/SelectedPermissionPoliciesColumn.esm.js +34 -0
  63. package/dist/components/CreateRole/SelectedPermissionPoliciesColumn.esm.js.map +1 -0
  64. package/dist/components/CreateRole/const.esm.js +14 -0
  65. package/dist/components/CreateRole/const.esm.js.map +1 -0
  66. package/dist/components/DownloadUserStatistics.esm.js +51 -0
  67. package/dist/components/DownloadUserStatistics.esm.js.map +1 -0
  68. package/dist/components/EditRole.esm.js +30 -0
  69. package/dist/components/EditRole.esm.js.map +1 -0
  70. package/dist/components/RbacPage.esm.js +18 -0
  71. package/dist/components/RbacPage.esm.js.map +1 -0
  72. package/dist/components/RoleOverview/AboutCard.esm.js +89 -0
  73. package/dist/components/RoleOverview/AboutCard.esm.js.map +1 -0
  74. package/dist/components/RoleOverview/MembersCard.esm.js +87 -0
  75. package/dist/components/RoleOverview/MembersCard.esm.js.map +1 -0
  76. package/dist/components/RoleOverview/MembersListColumns.esm.js +48 -0
  77. package/dist/components/RoleOverview/MembersListColumns.esm.js.map +1 -0
  78. package/dist/components/RoleOverview/PermissionsCard.esm.js +99 -0
  79. package/dist/components/RoleOverview/PermissionsCard.esm.js.map +1 -0
  80. package/dist/components/RoleOverview/PermissionsListColumns.esm.js +43 -0
  81. package/dist/components/RoleOverview/PermissionsListColumns.esm.js.map +1 -0
  82. package/dist/components/RoleOverview/RoleOverviewPage.esm.js +49 -0
  83. package/dist/components/RoleOverview/RoleOverviewPage.esm.js.map +1 -0
  84. package/dist/components/RolesList/DeleteRole.esm.js +32 -0
  85. package/dist/components/RolesList/DeleteRole.esm.js.map +1 -0
  86. package/dist/components/RolesList/DeleteRoleDialog.esm.js +142 -0
  87. package/dist/components/RolesList/DeleteRoleDialog.esm.js.map +1 -0
  88. package/dist/components/RolesList/RolesList.esm.js +102 -0
  89. package/dist/components/RolesList/RolesList.esm.js.map +1 -0
  90. package/dist/components/RolesList/RolesListColumns.esm.js +76 -0
  91. package/dist/components/RolesList/RolesListColumns.esm.js.map +1 -0
  92. package/dist/components/RolesList/RolesListToolbar.esm.js +48 -0
  93. package/dist/components/RolesList/RolesListToolbar.esm.js.map +1 -0
  94. package/dist/components/Router.esm.js +57 -0
  95. package/dist/components/Router.esm.js.map +1 -0
  96. package/dist/components/SnackbarAlert.esm.js +23 -0
  97. package/dist/components/SnackbarAlert.esm.js.map +1 -0
  98. package/dist/components/ToastContext.esm.js +19 -0
  99. package/dist/components/ToastContext.esm.js.map +1 -0
  100. package/dist/components/index.esm.js +5 -0
  101. package/dist/components/index.esm.js.map +1 -0
  102. package/dist/hooks/useCheckIfLicensePluginEnabled.esm.js +20 -0
  103. package/dist/hooks/useCheckIfLicensePluginEnabled.esm.js.map +1 -0
  104. package/dist/hooks/useConditionRules.esm.js +64 -0
  105. package/dist/hooks/useConditionRules.esm.js.map +1 -0
  106. package/dist/hooks/useLocationToast.esm.js +15 -0
  107. package/dist/hooks/useLocationToast.esm.js.map +1 -0
  108. package/dist/hooks/useMembers.esm.js +92 -0
  109. package/dist/hooks/useMembers.esm.js.map +1 -0
  110. package/dist/hooks/usePermissionPolicies.esm.js +80 -0
  111. package/dist/hooks/usePermissionPolicies.esm.js.map +1 -0
  112. package/dist/hooks/useRole.esm.js +23 -0
  113. package/dist/hooks/useRole.esm.js.map +1 -0
  114. package/dist/hooks/useRoles.esm.js +169 -0
  115. package/dist/hooks/useRoles.esm.js.map +1 -0
  116. package/dist/hooks/useSelectedMembers.esm.js +39 -0
  117. package/dist/hooks/useSelectedMembers.esm.js.map +1 -0
  118. package/dist/index.d.ts +17 -0
  119. package/dist/index.esm.js +4 -0
  120. package/dist/index.esm.js.map +1 -0
  121. package/dist/plugin.esm.js +49 -0
  122. package/dist/plugin.esm.js.map +1 -0
  123. package/dist/routes.esm.js +23 -0
  124. package/dist/routes.esm.js.map +1 -0
  125. package/dist/utils/conditional-access-utils.esm.js +268 -0
  126. package/dist/utils/conditional-access-utils.esm.js.map +1 -0
  127. package/dist/utils/create-role-utils.esm.js +231 -0
  128. package/dist/utils/create-role-utils.esm.js.map +1 -0
  129. package/dist/utils/rbac-utils.esm.js +256 -0
  130. package/dist/utils/rbac-utils.esm.js.map +1 -0
  131. package/dist/utils/role-form-utils.esm.js +66 -0
  132. package/dist/utils/role-form-utils.esm.js.map +1 -0
  133. package/package.json +120 -0
@@ -0,0 +1,77 @@
1
+ import React from 'react';
2
+ import { parseEntityRef } from '@backstage/catalog-model';
3
+ import { Link } from '@backstage/core-components';
4
+ import { Box, IconButton } from '@material-ui/core';
5
+ import Delete from '@mui/icons-material/Delete';
6
+
7
+ const reviewStepMemebersTableColumns = () => [
8
+ {
9
+ title: "Name",
10
+ field: "label",
11
+ type: "string"
12
+ },
13
+ {
14
+ title: "Type",
15
+ field: "type",
16
+ type: "string"
17
+ },
18
+ {
19
+ title: "Members",
20
+ field: "members",
21
+ type: "numeric",
22
+ align: "left",
23
+ render: (mem) => {
24
+ if (mem || mem === 0) return mem;
25
+ return "-";
26
+ }
27
+ }
28
+ ];
29
+ const selectedMembersColumns = (selectedMembers, setFieldValue) => {
30
+ const onRemove = (etag) => {
31
+ const updatedMembers = selectedMembers.filter(
32
+ (mem) => mem.etag !== etag
33
+ );
34
+ setFieldValue("selectedMembers", updatedMembers);
35
+ };
36
+ return [
37
+ {
38
+ title: "Name",
39
+ field: "label",
40
+ type: "string",
41
+ render: (props) => {
42
+ const { kind, namespace, name } = parseEntityRef(props.ref);
43
+ return /* @__PURE__ */ React.createElement(Link, { to: `/catalog/${namespace}/${kind}/${name}`, target: "blank" }, props.label);
44
+ }
45
+ },
46
+ {
47
+ title: "Type",
48
+ field: "type",
49
+ type: "string"
50
+ },
51
+ {
52
+ title: "Members",
53
+ field: "members",
54
+ type: "numeric",
55
+ align: "left",
56
+ emptyValue: "-"
57
+ },
58
+ {
59
+ title: "Actions",
60
+ sorting: false,
61
+ render: (mem) => {
62
+ return /* @__PURE__ */ React.createElement(Box, { key: mem.etag }, /* @__PURE__ */ React.createElement(
63
+ IconButton,
64
+ {
65
+ onClick: () => onRemove(mem.etag),
66
+ "aria-label": "Remove",
67
+ title: "Remove member"
68
+ },
69
+ /* @__PURE__ */ React.createElement(Delete, null)
70
+ ));
71
+ }
72
+ }
73
+ ];
74
+ };
75
+
76
+ export { reviewStepMemebersTableColumns, selectedMembersColumns };
77
+ //# sourceMappingURL=AddedMembersTableColumn.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AddedMembersTableColumn.esm.js","sources":["../../../src/components/CreateRole/AddedMembersTableColumn.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 { parseEntityRef } from '@backstage/catalog-model';\nimport { Link, TableColumn } from '@backstage/core-components';\n\nimport { Box, IconButton } from '@material-ui/core';\nimport Delete from '@mui/icons-material/Delete';\nimport { FormikErrors } from 'formik';\n\nimport { RoleFormValues, SelectedMember } from './types';\n\nexport const reviewStepMemebersTableColumns = () => [\n {\n title: 'Name',\n field: 'label',\n type: 'string',\n },\n {\n title: 'Type',\n field: 'type',\n type: 'string',\n },\n {\n title: 'Members',\n field: 'members',\n type: 'numeric',\n align: 'left',\n render: (mem: number) => {\n if (mem || mem === 0) return mem;\n return '-';\n },\n },\n];\n\nexport const selectedMembersColumns = (\n selectedMembers: SelectedMember[],\n setFieldValue: (\n field: string,\n value: any,\n shouldValidate?: boolean,\n ) => Promise<FormikErrors<RoleFormValues>> | Promise<void>,\n): TableColumn<SelectedMember>[] => {\n const onRemove = (etag: string) => {\n const updatedMembers = selectedMembers.filter(\n (mem: SelectedMember) => mem.etag !== etag,\n );\n setFieldValue('selectedMembers', updatedMembers);\n };\n\n return [\n {\n title: 'Name',\n field: 'label',\n type: 'string',\n render: props => {\n const { kind, namespace, name } = parseEntityRef(props.ref);\n return (\n <Link to={`/catalog/${namespace}/${kind}/${name}`} target=\"blank\">\n {props.label}\n </Link>\n );\n },\n },\n {\n title: 'Type',\n field: 'type',\n type: 'string',\n },\n {\n title: 'Members',\n field: 'members',\n type: 'numeric',\n align: 'left',\n emptyValue: '-',\n },\n {\n title: 'Actions',\n sorting: false,\n render: (mem: SelectedMember) => {\n return (\n <Box key={mem.etag}>\n <IconButton\n onClick={() => onRemove(mem.etag)}\n aria-label=\"Remove\"\n title=\"Remove member\"\n >\n <Delete />\n </IconButton>\n </Box>\n );\n },\n },\n ];\n};\n"],"names":[],"mappings":";;;;;;AA0BO,MAAM,iCAAiC,MAAM;AAAA,EAClD;AAAA,IACE,KAAO,EAAA,MAAA;AAAA,IACP,KAAO,EAAA,OAAA;AAAA,IACP,IAAM,EAAA,QAAA;AAAA,GACR;AAAA,EACA;AAAA,IACE,KAAO,EAAA,MAAA;AAAA,IACP,KAAO,EAAA,MAAA;AAAA,IACP,IAAM,EAAA,QAAA;AAAA,GACR;AAAA,EACA;AAAA,IACE,KAAO,EAAA,SAAA;AAAA,IACP,KAAO,EAAA,SAAA;AAAA,IACP,IAAM,EAAA,SAAA;AAAA,IACN,KAAO,EAAA,MAAA;AAAA,IACP,MAAA,EAAQ,CAAC,GAAgB,KAAA;AACvB,MAAI,IAAA,GAAA,IAAO,GAAQ,KAAA,CAAA,EAAU,OAAA,GAAA,CAAA;AAC7B,MAAO,OAAA,GAAA,CAAA;AAAA,KACT;AAAA,GACF;AACF,EAAA;AAEa,MAAA,sBAAA,GAAyB,CACpC,eAAA,EACA,aAKkC,KAAA;AAClC,EAAM,MAAA,QAAA,GAAW,CAAC,IAAiB,KAAA;AACjC,IAAA,MAAM,iBAAiB,eAAgB,CAAA,MAAA;AAAA,MACrC,CAAC,GAAwB,KAAA,GAAA,CAAI,IAAS,KAAA,IAAA;AAAA,KACxC,CAAA;AACA,IAAA,aAAA,CAAc,mBAAmB,cAAc,CAAA,CAAA;AAAA,GACjD,CAAA;AAEA,EAAO,OAAA;AAAA,IACL;AAAA,MACE,KAAO,EAAA,MAAA;AAAA,MACP,KAAO,EAAA,OAAA;AAAA,MACP,IAAM,EAAA,QAAA;AAAA,MACN,QAAQ,CAAS,KAAA,KAAA;AACf,QAAA,MAAM,EAAE,IAAM,EAAA,SAAA,EAAW,MAAS,GAAA,cAAA,CAAe,MAAM,GAAG,CAAA,CAAA;AAC1D,QAAA,uBACG,KAAA,CAAA,aAAA,CAAA,IAAA,EAAA,EAAK,EAAI,EAAA,CAAA,SAAA,EAAY,SAAS,CAAA,CAAA,EAAI,IAAI,CAAA,CAAA,EAAI,IAAI,CAAA,CAAA,EAAI,MAAO,EAAA,OAAA,EAAA,EACvD,MAAM,KACT,CAAA,CAAA;AAAA,OAEJ;AAAA,KACF;AAAA,IACA;AAAA,MACE,KAAO,EAAA,MAAA;AAAA,MACP,KAAO,EAAA,MAAA;AAAA,MACP,IAAM,EAAA,QAAA;AAAA,KACR;AAAA,IACA;AAAA,MACE,KAAO,EAAA,SAAA;AAAA,MACP,KAAO,EAAA,SAAA;AAAA,MACP,IAAM,EAAA,SAAA;AAAA,MACN,KAAO,EAAA,MAAA;AAAA,MACP,UAAY,EAAA,GAAA;AAAA,KACd;AAAA,IACA;AAAA,MACE,KAAO,EAAA,SAAA;AAAA,MACP,OAAS,EAAA,KAAA;AAAA,MACT,MAAA,EAAQ,CAAC,GAAwB,KAAA;AAC/B,QAAA,uBACG,KAAA,CAAA,aAAA,CAAA,GAAA,EAAA,EAAI,GAAK,EAAA,GAAA,CAAI,IACZ,EAAA,kBAAA,KAAA,CAAA,aAAA;AAAA,UAAC,UAAA;AAAA,UAAA;AAAA,YACC,OAAS,EAAA,MAAM,QAAS,CAAA,GAAA,CAAI,IAAI,CAAA;AAAA,YAChC,YAAW,EAAA,QAAA;AAAA,YACX,KAAM,EAAA,eAAA;AAAA,WAAA;AAAA,8CAEL,MAAO,EAAA,IAAA,CAAA;AAAA,SAEZ,CAAA,CAAA;AAAA,OAEJ;AAAA,KACF;AAAA,GACF,CAAA;AACF;;;;"}
@@ -0,0 +1,53 @@
1
+ import React from 'react';
2
+ import { useAsync } from 'react-use';
3
+ import { Progress, Page, Header, Content, ErrorPage } from '@backstage/core-components';
4
+ import { useApi } from '@backstage/core-plugin-api';
5
+ import { rbacApiRef } from '../../api/RBACBackendClient.esm.js';
6
+ import { initialPermissionPolicyRowValue } from './const.esm.js';
7
+ import { RoleForm } from './RoleForm.esm.js';
8
+
9
+ const CreateRolePage = () => {
10
+ const rbacApi = useApi(rbacApiRef);
11
+ const {
12
+ loading: membersLoading,
13
+ value: members,
14
+ error: membersError
15
+ } = useAsync(async () => {
16
+ return await rbacApi.getMembers();
17
+ });
18
+ const canReadUsersAndGroups = !membersLoading && !membersError && Array.isArray(members) && members.length > 0;
19
+ const initialValues = {
20
+ name: "",
21
+ namespace: "default",
22
+ kind: "role",
23
+ description: "",
24
+ selectedMembers: [],
25
+ permissionPoliciesRows: [initialPermissionPolicyRowValue]
26
+ };
27
+ if (membersLoading) {
28
+ return /* @__PURE__ */ React.createElement(Progress, null);
29
+ }
30
+ return canReadUsersAndGroups ? /* @__PURE__ */ React.createElement(Page, { themeId: "tool" }, /* @__PURE__ */ React.createElement(Header, { title: "Create role", type: "RBAC", typeLink: ".." }), /* @__PURE__ */ React.createElement(Content, null, /* @__PURE__ */ React.createElement(
31
+ RoleForm,
32
+ {
33
+ initialValues,
34
+ titles: {
35
+ formTitle: "Create Role",
36
+ nameAndDescriptionTitle: "Enter name and description of role ",
37
+ usersAndGroupsTitle: "Add users and groups",
38
+ permissionPoliciesTitle: "Add permission policies"
39
+ },
40
+ membersData: {
41
+ members: Array.isArray(members) ? members : [],
42
+ loading: membersLoading,
43
+ error: membersError || {
44
+ name: members?.status,
45
+ message: members?.statusText
46
+ }
47
+ }
48
+ }
49
+ ))) : /* @__PURE__ */ React.createElement(ErrorPage, { statusMessage: "Unauthorized to create role" });
50
+ };
51
+
52
+ export { CreateRolePage };
53
+ //# sourceMappingURL=CreateRolePage.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CreateRolePage.esm.js","sources":["../../../src/components/CreateRole/CreateRolePage.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';\nimport { useAsync } from 'react-use';\n\nimport {\n Content,\n ErrorPage,\n Header,\n Page,\n Progress,\n} from '@backstage/core-components';\nimport { useApi } from '@backstage/core-plugin-api';\n\nimport { rbacApiRef } from '../../api/RBACBackendClient';\nimport { MemberEntity } from '../../types';\nimport { initialPermissionPolicyRowValue } from './const';\nimport { RoleForm } from './RoleForm';\nimport { RoleFormValues } from './types';\n\nexport const CreateRolePage = () => {\n const rbacApi = useApi(rbacApiRef);\n const {\n loading: membersLoading,\n value: members,\n error: membersError,\n } = useAsync(async () => {\n return await rbacApi.getMembers();\n });\n\n const canReadUsersAndGroups =\n !membersLoading &&\n !membersError &&\n Array.isArray(members) &&\n members.length > 0;\n\n const initialValues: RoleFormValues = {\n name: '',\n namespace: 'default',\n kind: 'role',\n description: '',\n selectedMembers: [],\n permissionPoliciesRows: [initialPermissionPolicyRowValue],\n };\n\n if (membersLoading) {\n return <Progress />;\n }\n\n return canReadUsersAndGroups ? (\n <Page themeId=\"tool\">\n <Header title=\"Create role\" type=\"RBAC\" typeLink=\"..\" />\n <Content>\n <RoleForm\n initialValues={initialValues}\n titles={{\n formTitle: 'Create Role',\n nameAndDescriptionTitle: 'Enter name and description of role ',\n usersAndGroupsTitle: 'Add users and groups',\n permissionPoliciesTitle: 'Add permission policies',\n }}\n membersData={{\n members: Array.isArray(members) ? members : ([] as MemberEntity[]),\n loading: membersLoading,\n error: (membersError as unknown as Error) || {\n name: (members as unknown as Response)?.status,\n message: (members as unknown as Response)?.statusText,\n },\n }}\n />\n </Content>\n </Page>\n ) : (\n <ErrorPage statusMessage=\"Unauthorized to create role\" />\n );\n};\n"],"names":[],"mappings":";;;;;;;;AAiCO,MAAM,iBAAiB,MAAM;AAClC,EAAM,MAAA,OAAA,GAAU,OAAO,UAAU,CAAA,CAAA;AACjC,EAAM,MAAA;AAAA,IACJ,OAAS,EAAA,cAAA;AAAA,IACT,KAAO,EAAA,OAAA;AAAA,IACP,KAAO,EAAA,YAAA;AAAA,GACT,GAAI,SAAS,YAAY;AACvB,IAAO,OAAA,MAAM,QAAQ,UAAW,EAAA,CAAA;AAAA,GACjC,CAAA,CAAA;AAED,EAAM,MAAA,qBAAA,GACJ,CAAC,cAAA,IACD,CAAC,YAAA,IACD,MAAM,OAAQ,CAAA,OAAO,CACrB,IAAA,OAAA,CAAQ,MAAS,GAAA,CAAA,CAAA;AAEnB,EAAA,MAAM,aAAgC,GAAA;AAAA,IACpC,IAAM,EAAA,EAAA;AAAA,IACN,SAAW,EAAA,SAAA;AAAA,IACX,IAAM,EAAA,MAAA;AAAA,IACN,WAAa,EAAA,EAAA;AAAA,IACb,iBAAiB,EAAC;AAAA,IAClB,sBAAA,EAAwB,CAAC,+BAA+B,CAAA;AAAA,GAC1D,CAAA;AAEA,EAAA,IAAI,cAAgB,EAAA;AAClB,IAAA,2CAAQ,QAAS,EAAA,IAAA,CAAA,CAAA;AAAA,GACnB;AAEA,EAAA,OAAO,qBACL,mBAAA,KAAA,CAAA,aAAA,CAAC,IAAK,EAAA,EAAA,OAAA,EAAQ,0BACX,KAAA,CAAA,aAAA,CAAA,MAAA,EAAA,EAAO,KAAM,EAAA,aAAA,EAAc,MAAK,MAAO,EAAA,QAAA,EAAS,IAAK,EAAA,CAAA,sCACrD,OACC,EAAA,IAAA,kBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACC,aAAA;AAAA,MACA,MAAQ,EAAA;AAAA,QACN,SAAW,EAAA,aAAA;AAAA,QACX,uBAAyB,EAAA,qCAAA;AAAA,QACzB,mBAAqB,EAAA,sBAAA;AAAA,QACrB,uBAAyB,EAAA,yBAAA;AAAA,OAC3B;AAAA,MACA,WAAa,EAAA;AAAA,QACX,SAAS,KAAM,CAAA,OAAA,CAAQ,OAAO,CAAA,GAAI,UAAW,EAAC;AAAA,QAC9C,OAAS,EAAA,cAAA;AAAA,QACT,OAAQ,YAAqC,IAAA;AAAA,UAC3C,MAAO,OAAiC,EAAA,MAAA;AAAA,UACxC,SAAU,OAAiC,EAAA,UAAA;AAAA,SAC7C;AAAA,OACF;AAAA,KAAA;AAAA,GAEJ,CACF,CAAA,mBAEC,KAAA,CAAA,aAAA,CAAA,SAAA,EAAA,EAAU,eAAc,6BAA8B,EAAA,CAAA,CAAA;AAE3D;;;;"}
@@ -0,0 +1,65 @@
1
+ import React from 'react';
2
+ import { useParams } from 'react-router-dom';
3
+ import { useQueryParamState, Progress, ErrorPage, Page, Header, Content } from '@backstage/core-components';
4
+ import { usePermissionPolicies } from '../../hooks/usePermissionPolicies.esm.js';
5
+ import { useSelectedMembers } from '../../hooks/useSelectedMembers.esm.js';
6
+ import { RoleForm } from './RoleForm.esm.js';
7
+
8
+ const EditRolePage = () => {
9
+ const { roleName, roleNamespace, roleKind } = useParams();
10
+ const [queryParamState] = useQueryParamState("activeStep");
11
+ const {
12
+ selectedMembers,
13
+ members,
14
+ role,
15
+ loading: loadingMembers,
16
+ roleError,
17
+ membersError,
18
+ canReadUsersAndGroups
19
+ } = useSelectedMembers(
20
+ roleName ? `${roleKind}:${roleNamespace}/${roleName}` : ""
21
+ );
22
+ const { data, loading: loadingPolicies } = usePermissionPolicies(
23
+ `${roleKind}:${roleNamespace}/${roleName}`
24
+ );
25
+ const initialValues = {
26
+ name: roleName || "",
27
+ namespace: roleNamespace || "default",
28
+ kind: roleKind || "role",
29
+ description: role?.metadata?.description ?? "",
30
+ selectedMembers,
31
+ permissionPoliciesRows: data
32
+ };
33
+ if (loadingMembers || loadingPolicies) {
34
+ return /* @__PURE__ */ React.createElement(Progress, null);
35
+ }
36
+ if (roleError.name) {
37
+ return /* @__PURE__ */ React.createElement(ErrorPage, { status: roleError.name, statusMessage: roleError.message });
38
+ }
39
+ if (!canReadUsersAndGroups) {
40
+ return /* @__PURE__ */ React.createElement(ErrorPage, { statusMessage: "Unauthorized to edit role" });
41
+ }
42
+ return /* @__PURE__ */ React.createElement(Page, { themeId: "tool" }, /* @__PURE__ */ React.createElement(Header, { title: "Edit role", type: "RBAC", typeLink: ".." }), /* @__PURE__ */ React.createElement(Content, null, /* @__PURE__ */ React.createElement(
43
+ RoleForm,
44
+ {
45
+ initialValues,
46
+ titles: {
47
+ formTitle: "Edit Role",
48
+ nameAndDescriptionTitle: "Edit name and description of role ",
49
+ usersAndGroupsTitle: "Edit users and groups",
50
+ permissionPoliciesTitle: "Edit permission policies"
51
+ },
52
+ roleName: roleName ? `${roleKind}:${roleNamespace}/${roleName}` : "",
53
+ step: Number(queryParamState),
54
+ membersData: {
55
+ members,
56
+ loading: loadingMembers,
57
+ error: membersError
58
+ },
59
+ submitLabel: "Save"
60
+ }
61
+ )));
62
+ };
63
+
64
+ export { EditRolePage };
65
+ //# sourceMappingURL=EditRolePage.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EditRolePage.esm.js","sources":["../../../src/components/CreateRole/EditRolePage.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';\nimport { useParams } from 'react-router-dom';\n\nimport {\n Content,\n ErrorPage,\n Header,\n Page,\n Progress,\n useQueryParamState,\n} from '@backstage/core-components';\n\nimport { usePermissionPolicies } from '../../hooks/usePermissionPolicies';\nimport { useSelectedMembers } from '../../hooks/useSelectedMembers';\nimport { RoleForm } from './RoleForm';\nimport { RoleFormValues } from './types';\n\nexport const EditRolePage = () => {\n const { roleName, roleNamespace, roleKind } = useParams();\n const [queryParamState] = useQueryParamState<number>('activeStep');\n const {\n selectedMembers,\n members,\n role,\n loading: loadingMembers,\n roleError,\n membersError,\n canReadUsersAndGroups,\n } = useSelectedMembers(\n roleName ? `${roleKind}:${roleNamespace}/${roleName}` : '',\n );\n\n const { data, loading: loadingPolicies } = usePermissionPolicies(\n `${roleKind}:${roleNamespace}/${roleName}`,\n );\n\n const initialValues: RoleFormValues = {\n name: roleName || '',\n namespace: roleNamespace || 'default',\n kind: roleKind || 'role',\n description: role?.metadata?.description ?? '',\n selectedMembers,\n permissionPoliciesRows: data,\n };\n\n if (loadingMembers || loadingPolicies) {\n return <Progress />;\n }\n if (roleError.name) {\n return (\n <ErrorPage status={roleError.name} statusMessage={roleError.message} />\n );\n }\n if (!canReadUsersAndGroups) {\n return <ErrorPage statusMessage=\"Unauthorized to edit role\" />;\n }\n\n return (\n <Page themeId=\"tool\">\n <Header title=\"Edit role\" type=\"RBAC\" typeLink=\"..\" />\n <Content>\n <RoleForm\n initialValues={initialValues}\n titles={{\n formTitle: 'Edit Role',\n nameAndDescriptionTitle: 'Edit name and description of role ',\n usersAndGroupsTitle: 'Edit users and groups',\n permissionPoliciesTitle: 'Edit permission policies',\n }}\n roleName={roleName ? `${roleKind}:${roleNamespace}/${roleName}` : ''}\n step={Number(queryParamState)}\n membersData={{\n members,\n loading: loadingMembers,\n error: membersError,\n }}\n submitLabel=\"Save\"\n />\n </Content>\n </Page>\n );\n};\n"],"names":[],"mappings":";;;;;;;AAgCO,MAAM,eAAe,MAAM;AAChC,EAAA,MAAM,EAAE,QAAA,EAAU,aAAe,EAAA,QAAA,KAAa,SAAU,EAAA,CAAA;AACxD,EAAA,MAAM,CAAC,eAAe,CAAI,GAAA,kBAAA,CAA2B,YAAY,CAAA,CAAA;AACjE,EAAM,MAAA;AAAA,IACJ,eAAA;AAAA,IACA,OAAA;AAAA,IACA,IAAA;AAAA,IACA,OAAS,EAAA,cAAA;AAAA,IACT,SAAA;AAAA,IACA,YAAA;AAAA,IACA,qBAAA;AAAA,GACE,GAAA,kBAAA;AAAA,IACF,WAAW,CAAG,EAAA,QAAQ,IAAI,aAAa,CAAA,CAAA,EAAI,QAAQ,CAAK,CAAA,GAAA,EAAA;AAAA,GAC1D,CAAA;AAEA,EAAA,MAAM,EAAE,IAAA,EAAM,OAAS,EAAA,eAAA,EAAoB,GAAA,qBAAA;AAAA,IACzC,CAAG,EAAA,QAAQ,CAAI,CAAA,EAAA,aAAa,IAAI,QAAQ,CAAA,CAAA;AAAA,GAC1C,CAAA;AAEA,EAAA,MAAM,aAAgC,GAAA;AAAA,IACpC,MAAM,QAAY,IAAA,EAAA;AAAA,IAClB,WAAW,aAAiB,IAAA,SAAA;AAAA,IAC5B,MAAM,QAAY,IAAA,MAAA;AAAA,IAClB,WAAA,EAAa,IAAM,EAAA,QAAA,EAAU,WAAe,IAAA,EAAA;AAAA,IAC5C,eAAA;AAAA,IACA,sBAAwB,EAAA,IAAA;AAAA,GAC1B,CAAA;AAEA,EAAA,IAAI,kBAAkB,eAAiB,EAAA;AACrC,IAAA,2CAAQ,QAAS,EAAA,IAAA,CAAA,CAAA;AAAA,GACnB;AACA,EAAA,IAAI,UAAU,IAAM,EAAA;AAClB,IAAA,2CACG,SAAU,EAAA,EAAA,MAAA,EAAQ,UAAU,IAAM,EAAA,aAAA,EAAe,UAAU,OAAS,EAAA,CAAA,CAAA;AAAA,GAEzE;AACA,EAAA,IAAI,CAAC,qBAAuB,EAAA;AAC1B,IAAO,uBAAA,KAAA,CAAA,aAAA,CAAC,SAAU,EAAA,EAAA,aAAA,EAAc,2BAA4B,EAAA,CAAA,CAAA;AAAA,GAC9D;AAEA,EAAA,uBACG,KAAA,CAAA,aAAA,CAAA,IAAA,EAAA,EAAK,OAAQ,EAAA,MAAA,EAAA,sCACX,MAAO,EAAA,EAAA,KAAA,EAAM,WAAY,EAAA,IAAA,EAAK,MAAO,EAAA,QAAA,EAAS,IAAK,EAAA,CAAA,sCACnD,OACC,EAAA,IAAA,kBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACC,aAAA;AAAA,MACA,MAAQ,EAAA;AAAA,QACN,SAAW,EAAA,WAAA;AAAA,QACX,uBAAyB,EAAA,oCAAA;AAAA,QACzB,mBAAqB,EAAA,uBAAA;AAAA,QACrB,uBAAyB,EAAA,0BAAA;AAAA,OAC3B;AAAA,MACA,QAAA,EAAU,WAAW,CAAG,EAAA,QAAQ,IAAI,aAAa,CAAA,CAAA,EAAI,QAAQ,CAAK,CAAA,GAAA,EAAA;AAAA,MAClE,IAAA,EAAM,OAAO,eAAe,CAAA;AAAA,MAC5B,WAAa,EAAA;AAAA,QACX,OAAA;AAAA,QACA,OAAS,EAAA,cAAA;AAAA,QACT,KAAO,EAAA,YAAA;AAAA,OACT;AAAA,MACA,WAAY,EAAA,MAAA;AAAA,KAAA;AAAA,GAEhB,CACF,CAAA,CAAA;AAEJ;;;;"}
@@ -0,0 +1,40 @@
1
+ import React from 'react';
2
+ import { makeStyles, Box } from '@material-ui/core';
3
+ import Typography from '@mui/material/Typography';
4
+ import match from 'autosuggest-highlight/match';
5
+ import parse from 'autosuggest-highlight/parse';
6
+
7
+ const useStyles = makeStyles((theme) => ({
8
+ optionLabel: {
9
+ color: theme.palette.text.primary
10
+ },
11
+ optionDescription: {
12
+ color: theme.palette.text.secondary
13
+ }
14
+ }));
15
+ const MembersDropdownOption = ({
16
+ option,
17
+ state
18
+ }) => {
19
+ const classes = useStyles();
20
+ const { inputValue } = state;
21
+ const { label, etag } = option;
22
+ const matches = match(label, inputValue, { insideWords: true });
23
+ const parts = parse(label, matches);
24
+ return /* @__PURE__ */ React.createElement(Box, { key: `${etag}` }, parts.map((part) => /* @__PURE__ */ React.createElement(
25
+ Typography,
26
+ {
27
+ key: `${part.text}-${etag}`,
28
+ component: "span",
29
+ className: classes.optionLabel,
30
+ sx: {
31
+ fontWeight: part.highlight ? 400 : 700
32
+ },
33
+ "data-testid": option.label
34
+ },
35
+ part.text
36
+ )), /* @__PURE__ */ React.createElement("br", null), /* @__PURE__ */ React.createElement(Typography, { className: classes.optionDescription }, option.description), " ");
37
+ };
38
+
39
+ export { MembersDropdownOption };
40
+ //# sourceMappingURL=MembersDropdownOption.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MembersDropdownOption.esm.js","sources":["../../../src/components/CreateRole/MembersDropdownOption.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 { Box, makeStyles } from '@material-ui/core';\nimport { AutocompleteRenderOptionState } from '@material-ui/lab/Autocomplete';\nimport Typography from '@mui/material/Typography';\nimport match from 'autosuggest-highlight/match';\nimport parse from 'autosuggest-highlight/parse';\n\nimport { SelectedMember } from './types';\n\ntype MembersDropdownOptionProps = {\n option: SelectedMember;\n state: AutocompleteRenderOptionState;\n};\n\nconst useStyles = makeStyles(theme => ({\n optionLabel: {\n color: theme.palette.text.primary,\n },\n optionDescription: {\n color: theme.palette.text.secondary,\n },\n}));\n\nexport const MembersDropdownOption = ({\n option,\n state,\n}: MembersDropdownOptionProps) => {\n const classes = useStyles();\n const { inputValue } = state;\n const { label, etag } = option;\n const matches = match(label, inputValue, { insideWords: true });\n const parts = parse(label, matches);\n\n return (\n <Box key={`${etag}`}>\n {parts.map(part => (\n <Typography\n key={`${part.text}-${etag}`}\n component=\"span\"\n className={classes.optionLabel}\n sx={{\n fontWeight: part.highlight ? 400 : 700,\n }}\n data-testid={option.label}\n >\n {part.text}\n </Typography>\n ))}\n <br />\n <Typography className={classes.optionDescription}>\n {option.description}\n </Typography>{' '}\n </Box>\n );\n};\n"],"names":[],"mappings":";;;;;;AA8BA,MAAM,SAAA,GAAY,WAAW,CAAU,KAAA,MAAA;AAAA,EACrC,WAAa,EAAA;AAAA,IACX,KAAA,EAAO,KAAM,CAAA,OAAA,CAAQ,IAAK,CAAA,OAAA;AAAA,GAC5B;AAAA,EACA,iBAAmB,EAAA;AAAA,IACjB,KAAA,EAAO,KAAM,CAAA,OAAA,CAAQ,IAAK,CAAA,SAAA;AAAA,GAC5B;AACF,CAAE,CAAA,CAAA,CAAA;AAEK,MAAM,wBAAwB,CAAC;AAAA,EACpC,MAAA;AAAA,EACA,KAAA;AACF,CAAkC,KAAA;AAChC,EAAA,MAAM,UAAU,SAAU,EAAA,CAAA;AAC1B,EAAM,MAAA,EAAE,YAAe,GAAA,KAAA,CAAA;AACvB,EAAM,MAAA,EAAE,KAAO,EAAA,IAAA,EAAS,GAAA,MAAA,CAAA;AACxB,EAAA,MAAM,UAAU,KAAM,CAAA,KAAA,EAAO,YAAY,EAAE,WAAA,EAAa,MAAM,CAAA,CAAA;AAC9D,EAAM,MAAA,KAAA,GAAQ,KAAM,CAAA,KAAA,EAAO,OAAO,CAAA,CAAA;AAElC,EACE,uBAAA,KAAA,CAAA,aAAA,CAAC,OAAI,GAAK,EAAA,CAAA,EAAG,IAAI,CACd,CAAA,EAAA,EAAA,KAAA,CAAM,IAAI,CACT,IAAA,qBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,UAAA;AAAA,IAAA;AAAA,MACC,GAAK,EAAA,CAAA,EAAG,IAAK,CAAA,IAAI,IAAI,IAAI,CAAA,CAAA;AAAA,MACzB,SAAU,EAAA,MAAA;AAAA,MACV,WAAW,OAAQ,CAAA,WAAA;AAAA,MACnB,EAAI,EAAA;AAAA,QACF,UAAA,EAAY,IAAK,CAAA,SAAA,GAAY,GAAM,GAAA,GAAA;AAAA,OACrC;AAAA,MACA,eAAa,MAAO,CAAA,KAAA;AAAA,KAAA;AAAA,IAEnB,IAAK,CAAA,IAAA;AAAA,GAET,CAAA,kBACA,KAAA,CAAA,aAAA,CAAA,IAAA,EAAA,IAAG,CACJ,kBAAA,KAAA,CAAA,aAAA,CAAC,UAAW,EAAA,EAAA,SAAA,EAAW,OAAQ,CAAA,iBAAA,EAAA,EAC5B,MAAO,CAAA,WACV,GAAc,GAChB,CAAA,CAAA;AAEJ;;;;"}
@@ -0,0 +1,144 @@
1
+ import React from 'react';
2
+ import { useAsync } from 'react-use';
3
+ import { Progress } from '@backstage/core-components';
4
+ import { useApi } from '@backstage/core-plugin-api';
5
+ import { makeStyles } from '@material-ui/core';
6
+ import Button from '@material-ui/core/Button';
7
+ import FormHelperText from '@material-ui/core/FormHelperText';
8
+ import AddIcon from '@mui/icons-material/Add';
9
+ import { rbacApiRef } from '../../api/RBACBackendClient.esm.js';
10
+ import { useConditionRules } from '../../hooks/useConditionRules.esm.js';
11
+ import { getPluginsPermissionPoliciesData } from '../../utils/create-role-utils.esm.js';
12
+ import { initialPermissionPolicyRowValue } from './const.esm.js';
13
+ import { PermissionPoliciesFormRow } from './PermissionPoliciesFormRow.esm.js';
14
+
15
+ const useStyles = makeStyles((theme) => ({
16
+ permissionPoliciesForm: {
17
+ padding: "20px",
18
+ border: `2px solid ${theme.palette.border}`,
19
+ borderRadius: "5px"
20
+ },
21
+ addButton: {
22
+ color: theme.palette.primary.light
23
+ }
24
+ }));
25
+ const PermissionPoliciesForm = ({
26
+ permissionPoliciesRows,
27
+ permissionPoliciesRowsError,
28
+ setFieldValue,
29
+ setFieldError,
30
+ handleBlur
31
+ }) => {
32
+ const classes = useStyles();
33
+ const rbacApi = useApi(rbacApiRef);
34
+ const conditionRules = useConditionRules();
35
+ const {
36
+ value: permissionPolicies,
37
+ loading: permissionPoliciesLoading,
38
+ error: permissionPoliciesErr
39
+ } = useAsync(async () => {
40
+ return await rbacApi.listPermissions();
41
+ });
42
+ const permissionPoliciesData = !permissionPoliciesLoading && Array.isArray(permissionPolicies) ? getPluginsPermissionPoliciesData(permissionPolicies) : void 0;
43
+ const onChangePlugin = (plugin, index) => {
44
+ setFieldValue(`permissionPoliciesRows[${index}].plugin`, plugin, true);
45
+ setFieldValue(`permissionPoliciesRows[${index}].permission`, "", false);
46
+ setFieldValue(`permissionPoliciesRows[${index}].isResourced`, false, false);
47
+ setFieldValue(
48
+ `permissionPoliciesRows[${index}].conditions`,
49
+ void 0,
50
+ false
51
+ );
52
+ setFieldValue(
53
+ `permissionPoliciesRows[${index}].policies`,
54
+ initialPermissionPolicyRowValue.policies,
55
+ false
56
+ );
57
+ };
58
+ const onChangePermission = (permission, index, isResourced, policies) => {
59
+ setFieldValue(
60
+ `permissionPoliciesRows[${index}].permission`,
61
+ permission,
62
+ true
63
+ );
64
+ setFieldValue(
65
+ `permissionPoliciesRows[${index}].isResourced`,
66
+ isResourced,
67
+ false
68
+ );
69
+ setFieldValue(
70
+ `permissionPoliciesRows[${index}].conditions`,
71
+ void 0,
72
+ false
73
+ );
74
+ setFieldValue(
75
+ `permissionPoliciesRows[${index}].policies`,
76
+ policies ? policies.map((p) => ({ policy: p, effect: "allow" })) : initialPermissionPolicyRowValue.policies,
77
+ false
78
+ );
79
+ };
80
+ const onChangePolicy = (isChecked, policyIndex, index) => {
81
+ setFieldValue(
82
+ `permissionPoliciesRows[${index}].policies[${policyIndex}].effect`,
83
+ isChecked ? "allow" : "deny",
84
+ true
85
+ );
86
+ };
87
+ const onAddConditions = (index, conditions) => {
88
+ setFieldValue(`permissionPoliciesRows[${index}].conditions`, conditions);
89
+ if (!conditions)
90
+ setFieldValue(`permissionPoliciesRows[${index}].id`, void 0);
91
+ };
92
+ const onRowRemove = (index) => {
93
+ const finalPps = permissionPoliciesRows.filter(
94
+ (_pp, ppIndex) => index !== ppIndex
95
+ );
96
+ setFieldError(`permissionPoliciesRows[${index}]`, void 0);
97
+ setFieldValue("permissionPoliciesRows", finalPps, false);
98
+ };
99
+ const onRowAdd = () => setFieldValue(
100
+ "permissionPoliciesRows",
101
+ [...permissionPoliciesRows, initialPermissionPolicyRowValue],
102
+ false
103
+ );
104
+ return /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement(FormHelperText, null, "Permission policies can be selected for each plugin. You can add multiple permission policies using +Add option."), /* @__PURE__ */ React.createElement("br", null), permissionPoliciesLoading ? /* @__PURE__ */ React.createElement(Progress, null) : /* @__PURE__ */ React.createElement("div", { className: classes.permissionPoliciesForm }, permissionPoliciesRows.map((pp, index) => /* @__PURE__ */ React.createElement(
105
+ PermissionPoliciesFormRow,
106
+ {
107
+ key: index,
108
+ permissionPoliciesRowError: permissionPoliciesRowsError?.[index] ?? {},
109
+ rowName: `permissionPoliciesRows[${index}]`,
110
+ permissionPoliciesRowData: pp,
111
+ permissionPoliciesData,
112
+ rowCount: permissionPoliciesRows.length,
113
+ conditionRules,
114
+ onChangePlugin: (plugin) => onChangePlugin(plugin, index),
115
+ onChangePermission: (permission, isResourced, policies) => onChangePermission(permission, index, isResourced, policies),
116
+ onChangePolicy: (isChecked, policyIndex) => onChangePolicy(isChecked, policyIndex, index),
117
+ onAddConditions: (conditions) => onAddConditions(index, conditions),
118
+ onRemove: () => onRowRemove(index),
119
+ handleBlur,
120
+ getPermissionDisabled: (permission) => {
121
+ const pluginPermissionPolicies = permissionPoliciesRows.filter(
122
+ (ppr) => ppr.plugin === pp.plugin
123
+ );
124
+ const previouslySelectedPermission = !!pluginPermissionPolicies.find(
125
+ (ppp) => ppp.permission === permission
126
+ );
127
+ return previouslySelectedPermission && !permissionPoliciesData?.pluginsPermissions[pp.plugin]?.policies[permission ?? ""]?.isResourced;
128
+ }
129
+ }
130
+ )), /* @__PURE__ */ React.createElement(
131
+ Button,
132
+ {
133
+ className: classes.addButton,
134
+ size: "small",
135
+ onClick: onRowAdd,
136
+ name: "add-permission-policy"
137
+ },
138
+ /* @__PURE__ */ React.createElement(AddIcon, null),
139
+ "Add"
140
+ )), !permissionPoliciesLoading && (permissionPoliciesErr?.message || !Array.isArray(permissionPolicies)) && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("br", null), /* @__PURE__ */ React.createElement(FormHelperText, { error: true }, `Error fetching the permission policies: ${permissionPoliciesErr?.message || permissionPolicies?.statusText}`)));
141
+ };
142
+
143
+ export { PermissionPoliciesForm };
144
+ //# sourceMappingURL=PermissionPoliciesForm.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PermissionPoliciesForm.esm.js","sources":["../../../src/components/CreateRole/PermissionPoliciesForm.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';\nimport { useAsync } from 'react-use';\n\nimport { Progress } from '@backstage/core-components';\nimport { useApi } from '@backstage/core-plugin-api';\n\nimport { makeStyles } from '@material-ui/core';\nimport Button from '@material-ui/core/Button';\nimport FormHelperText from '@material-ui/core/FormHelperText';\nimport AddIcon from '@mui/icons-material/Add';\nimport { FormikErrors } from 'formik';\n\nimport { rbacApiRef } from '../../api/RBACBackendClient';\nimport { useConditionRules } from '../../hooks/useConditionRules';\nimport { PermissionsData } from '../../types';\nimport { getPluginsPermissionPoliciesData } from '../../utils/create-role-utils';\nimport { ConditionsData } from '../ConditionalAccess/types';\nimport { initialPermissionPolicyRowValue } from './const';\nimport { PermissionPoliciesFormRow } from './PermissionPoliciesFormRow';\nimport { RoleFormValues } from './types';\n\nconst useStyles = makeStyles(theme => ({\n permissionPoliciesForm: {\n padding: '20px',\n border: `2px solid ${theme.palette.border}`,\n borderRadius: '5px',\n },\n addButton: {\n color: theme.palette.primary.light,\n },\n}));\n\ntype PermissionPoliciesFormProps = {\n permissionPoliciesRows: PermissionsData[];\n permissionPoliciesRowsError: FormikErrors<PermissionsData>[];\n setFieldValue: (\n field: string,\n value: any,\n shouldValidate?: boolean,\n ) => Promise<FormikErrors<RoleFormValues>> | Promise<void>;\n setFieldError: (field: string, value: string | undefined) => void;\n handleBlur: React.FocusEventHandler<HTMLInputElement | HTMLTextAreaElement>;\n};\n\nexport const PermissionPoliciesForm = ({\n permissionPoliciesRows,\n permissionPoliciesRowsError,\n setFieldValue,\n setFieldError,\n handleBlur,\n}: PermissionPoliciesFormProps) => {\n const classes = useStyles();\n const rbacApi = useApi(rbacApiRef);\n const conditionRules = useConditionRules();\n\n const {\n value: permissionPolicies,\n loading: permissionPoliciesLoading,\n error: permissionPoliciesErr,\n } = useAsync(async () => {\n return await rbacApi.listPermissions();\n });\n\n const permissionPoliciesData =\n !permissionPoliciesLoading && Array.isArray(permissionPolicies)\n ? getPluginsPermissionPoliciesData(permissionPolicies)\n : undefined;\n\n const onChangePlugin = (plugin: string, index: number) => {\n setFieldValue(`permissionPoliciesRows[${index}].plugin`, plugin, true);\n setFieldValue(`permissionPoliciesRows[${index}].permission`, '', false);\n setFieldValue(`permissionPoliciesRows[${index}].isResourced`, false, false);\n setFieldValue(\n `permissionPoliciesRows[${index}].conditions`,\n undefined,\n false,\n );\n setFieldValue(\n `permissionPoliciesRows[${index}].policies`,\n initialPermissionPolicyRowValue.policies,\n false,\n );\n };\n\n const onChangePermission = (\n permission: string,\n index: number,\n isResourced: boolean,\n policies?: string[],\n ) => {\n setFieldValue(\n `permissionPoliciesRows[${index}].permission`,\n permission,\n true,\n );\n setFieldValue(\n `permissionPoliciesRows[${index}].isResourced`,\n isResourced,\n false,\n );\n setFieldValue(\n `permissionPoliciesRows[${index}].conditions`,\n undefined,\n false,\n );\n setFieldValue(\n `permissionPoliciesRows[${index}].policies`,\n policies\n ? policies.map(p => ({ policy: p, effect: 'allow' }))\n : initialPermissionPolicyRowValue.policies,\n false,\n );\n };\n\n const onChangePolicy = (\n isChecked: boolean,\n policyIndex: number,\n index: number,\n ) => {\n setFieldValue(\n `permissionPoliciesRows[${index}].policies[${policyIndex}].effect`,\n isChecked ? 'allow' : 'deny',\n true,\n );\n };\n\n const onAddConditions = (index: number, conditions?: ConditionsData) => {\n setFieldValue(`permissionPoliciesRows[${index}].conditions`, conditions);\n if (!conditions)\n setFieldValue(`permissionPoliciesRows[${index}].id`, undefined);\n };\n\n const onRowRemove = (index: number) => {\n const finalPps = permissionPoliciesRows.filter(\n (_pp, ppIndex) => index !== ppIndex,\n );\n setFieldError(`permissionPoliciesRows[${index}]`, undefined);\n setFieldValue('permissionPoliciesRows', finalPps, false);\n };\n\n const onRowAdd = () =>\n setFieldValue(\n 'permissionPoliciesRows',\n [...permissionPoliciesRows, initialPermissionPolicyRowValue],\n false,\n );\n\n return (\n <div>\n <FormHelperText>\n Permission policies can be selected for each plugin. You can add\n multiple permission policies using +Add option.\n </FormHelperText>\n <br />\n {permissionPoliciesLoading ? (\n <Progress />\n ) : (\n <div className={classes.permissionPoliciesForm}>\n {permissionPoliciesRows.map((pp, index) => (\n <PermissionPoliciesFormRow\n key={index}\n permissionPoliciesRowError={\n permissionPoliciesRowsError?.[index] ?? {}\n }\n rowName={`permissionPoliciesRows[${index}]`}\n permissionPoliciesRowData={pp}\n permissionPoliciesData={permissionPoliciesData}\n rowCount={permissionPoliciesRows.length}\n conditionRules={conditionRules}\n onChangePlugin={(plugin: string) => onChangePlugin(plugin, index)}\n onChangePermission={(\n permission: string,\n isResourced: boolean,\n policies?: string[],\n ) => onChangePermission(permission, index, isResourced, policies)}\n onChangePolicy={(isChecked: boolean, policyIndex: number) =>\n onChangePolicy(isChecked, policyIndex, index)\n }\n onAddConditions={(conditions?: ConditionsData) =>\n onAddConditions(index, conditions)\n }\n onRemove={() => onRowRemove(index)}\n handleBlur={handleBlur}\n getPermissionDisabled={(permission: string) => {\n const pluginPermissionPolicies = permissionPoliciesRows.filter(\n ppr => ppr.plugin === pp.plugin,\n );\n const previouslySelectedPermission =\n !!pluginPermissionPolicies.find(\n ppp => ppp.permission === permission,\n );\n return (\n previouslySelectedPermission &&\n !permissionPoliciesData?.pluginsPermissions[pp.plugin]\n ?.policies[permission ?? '']?.isResourced\n );\n }}\n />\n ))}\n <Button\n className={classes.addButton}\n size=\"small\"\n onClick={onRowAdd}\n name=\"add-permission-policy\"\n >\n <AddIcon />\n Add\n </Button>\n </div>\n )}\n {!permissionPoliciesLoading &&\n (permissionPoliciesErr?.message ||\n !Array.isArray(permissionPolicies)) && (\n <>\n <br />\n <FormHelperText error>\n {`Error fetching the permission policies: ${\n permissionPoliciesErr?.message ||\n (permissionPolicies as Response)?.statusText\n }`}\n </FormHelperText>\n </>\n )}\n </div>\n );\n};\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,179 @@
1
+ import React from 'react';
2
+ import { makeStyles, FormLabel } from '@material-ui/core';
3
+ import IconButton from '@material-ui/core/IconButton';
4
+ import TextField from '@material-ui/core/TextField';
5
+ import Autocomplete from '@material-ui/lab/Autocomplete';
6
+ import ChecklistRtlIcon from '@mui/icons-material/ChecklistRtl';
7
+ import HelpOutlineIcon from '@mui/icons-material/HelpOutline';
8
+ import RemoveIcon from '@mui/icons-material/Remove';
9
+ import Tooltip from '@mui/material/Tooltip';
10
+ import Typography from '@mui/material/Typography';
11
+ import { getRulesNumber } from '../../utils/create-role-utils.esm.js';
12
+ import { ConditionalAccessSidebar } from '../ConditionalAccess/ConditionalAccessSidebar.esm.js';
13
+ import { PoliciesCheckboxGroup } from './PoliciesCheckboxGroup.esm.js';
14
+
15
+ const useStyles = makeStyles((theme) => ({
16
+ removeButton: {
17
+ color: theme.palette.grey[500],
18
+ flexGrow: 0,
19
+ alignSelf: "center"
20
+ },
21
+ conditionalAccessButton: {
22
+ fontSize: theme.typography.fontSize
23
+ }
24
+ }));
25
+ const PermissionPoliciesFormRow = ({
26
+ permissionPoliciesRowData,
27
+ permissionPoliciesData,
28
+ permissionPoliciesRowError,
29
+ rowCount,
30
+ rowName,
31
+ conditionRules,
32
+ onRemove,
33
+ onChangePermission,
34
+ onChangePolicy,
35
+ onChangePlugin,
36
+ handleBlur,
37
+ getPermissionDisabled,
38
+ onAddConditions
39
+ }) => {
40
+ const classes = useStyles();
41
+ const { plugin: pluginError, permission: permissionError } = permissionPoliciesRowError;
42
+ const { data: conditionRulesData, error: conditionRulesError } = conditionRules;
43
+ const totalRules = getRulesNumber(permissionPoliciesRowData.conditions);
44
+ const [sidebarOpen, setSidebarOpen] = React.useState(false);
45
+ const tooltipTitle = () => /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement(Typography, { component: "p", align: "center" }, "Define access conditions for the selected resource type using Rules. Rules vary by resource type.", " ", /* @__PURE__ */ React.createElement("b", null, "Users have access to the resource type content by default"), " unless configured otherwise."));
46
+ const getTotalRules = () => {
47
+ let accessMessage = "Configure access";
48
+ if (totalRules > 0) {
49
+ accessMessage += ` (${totalRules} ${totalRules > 1 ? "rules" : "rule"})`;
50
+ }
51
+ return accessMessage;
52
+ };
53
+ return /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", { style: { display: "flex", flexFlow: "column", gap: "15px" } }, /* @__PURE__ */ React.createElement(
54
+ FormLabel,
55
+ {
56
+ style: {
57
+ fontWeight: 800,
58
+ fontSize: "0.8rem"
59
+ }
60
+ },
61
+ "What can users/groups access?"
62
+ ), /* @__PURE__ */ React.createElement(
63
+ "div",
64
+ {
65
+ style: {
66
+ display: "flex",
67
+ gap: "20px",
68
+ marginBottom: "15px"
69
+ }
70
+ },
71
+ /* @__PURE__ */ React.createElement(
72
+ Autocomplete,
73
+ {
74
+ options: permissionPoliciesData?.plugins ?? [],
75
+ style: { width: "35%", flexGrow: "1" },
76
+ value: permissionPoliciesRowData.plugin || null,
77
+ onChange: (_e, value) => {
78
+ onChangePlugin(value ?? "");
79
+ },
80
+ renderInput: (params) => /* @__PURE__ */ React.createElement(
81
+ TextField,
82
+ {
83
+ ...params,
84
+ label: "Plugin",
85
+ name: `${rowName}.plugin`,
86
+ variant: "outlined",
87
+ placeholder: "Select a plugin",
88
+ error: !!pluginError,
89
+ helperText: pluginError ?? "",
90
+ onBlur: handleBlur,
91
+ required: true
92
+ }
93
+ )
94
+ }
95
+ ),
96
+ /* @__PURE__ */ React.createElement(
97
+ Autocomplete,
98
+ {
99
+ disabled: !permissionPoliciesRowData.plugin,
100
+ options: permissionPoliciesData?.pluginsPermissions?.[permissionPoliciesRowData.plugin]?.permissions ?? [],
101
+ style: { width: "35%", flexGrow: "1" },
102
+ value: permissionPoliciesRowData.permission || null,
103
+ onChange: (_e, value) => onChangePermission(
104
+ value ?? "",
105
+ permissionPoliciesData?.pluginsPermissions?.[permissionPoliciesRowData.plugin]?.policies[value ?? ""]?.isResourced ?? false,
106
+ value ? permissionPoliciesData?.pluginsPermissions?.[permissionPoliciesRowData.plugin]?.policies?.[value].policies : void 0
107
+ ),
108
+ getOptionDisabled: getPermissionDisabled,
109
+ getOptionLabel: (option) => option || "",
110
+ renderInput: (params) => /* @__PURE__ */ React.createElement(
111
+ TextField,
112
+ {
113
+ ...params,
114
+ label: "Resource type",
115
+ name: `${rowName}.permission`,
116
+ variant: "outlined",
117
+ placeholder: "Select a resource type",
118
+ error: !!permissionError,
119
+ helperText: permissionError ?? "",
120
+ onBlur: handleBlur,
121
+ required: true
122
+ }
123
+ )
124
+ }
125
+ ),
126
+ /* @__PURE__ */ React.createElement("div", { style: { width: "23%", alignSelf: "center", flexGrow: 1 } }, permissionPoliciesRowData.isResourced && !!conditionRulesData?.[`${permissionPoliciesRowData.plugin}`]?.[`${permissionPoliciesRowData.permission}`]?.rules.length && /* @__PURE__ */ React.createElement(
127
+ IconButton,
128
+ {
129
+ title: "",
130
+ color: "primary",
131
+ hidden: !permissionPoliciesData?.pluginsPermissions[permissionPoliciesRowData.plugin]?.policies[permissionPoliciesRowData.permission]?.isResourced,
132
+ "aria-label": "configure-access",
133
+ className: classes.conditionalAccessButton,
134
+ onClick: () => setSidebarOpen(true),
135
+ disabled: !!conditionRulesError
136
+ },
137
+ /* @__PURE__ */ React.createElement(ChecklistRtlIcon, { fontSize: "small" }),
138
+ getTotalRules(),
139
+ "\xA0",
140
+ /* @__PURE__ */ React.createElement(Tooltip, { title: tooltipTitle(), placement: "top" }, /* @__PURE__ */ React.createElement(HelpOutlineIcon, { fontSize: "inherit" }))
141
+ )),
142
+ /* @__PURE__ */ React.createElement(
143
+ IconButton,
144
+ {
145
+ title: "Remove",
146
+ className: classes.removeButton,
147
+ onClick: () => onRemove(),
148
+ disabled: rowCount === 1,
149
+ "data-testid": `${rowName}-remove`
150
+ },
151
+ /* @__PURE__ */ React.createElement(RemoveIcon, { id: `${rowName}-remove` })
152
+ )
153
+ )), /* @__PURE__ */ React.createElement(
154
+ PoliciesCheckboxGroup,
155
+ {
156
+ permissionPoliciesRowData,
157
+ onChangePolicy,
158
+ rowName
159
+ }
160
+ ), /* @__PURE__ */ React.createElement(
161
+ ConditionalAccessSidebar,
162
+ {
163
+ open: sidebarOpen,
164
+ onClose: () => {
165
+ setSidebarOpen(false);
166
+ },
167
+ onSave: (conditions) => {
168
+ onAddConditions(conditions);
169
+ setSidebarOpen(false);
170
+ },
171
+ conditionsFormVal: permissionPoliciesRowData.conditions,
172
+ selPluginResourceType: permissionPoliciesRowData.permission,
173
+ conditionRulesData: conditionRulesData?.[`${permissionPoliciesRowData.plugin}`]?.[`${permissionPoliciesRowData.permission}`]
174
+ }
175
+ ));
176
+ };
177
+
178
+ export { PermissionPoliciesFormRow };
179
+ //# sourceMappingURL=PermissionPoliciesFormRow.esm.js.map