@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,209 @@
1
+ import React from 'react';
2
+ import { Box, TextField } from '@material-ui/core';
3
+ import { Autocomplete } from '@material-ui/lab';
4
+ import Form from '@rjsf/mui';
5
+ import validator from '@rjsf/validator-ajv8';
6
+ import { makeConditionsFormRowFieldsStyles, isSimpleRule, setErrorMessage, getSimpleRuleErrors, getNestedRuleErrors } from '../../utils/conditional-access-utils.esm.js';
7
+ import { criterias } from './const.esm.js';
8
+ import { CustomArrayField } from './CustomArrayField.esm.js';
9
+ import { RulesDropdownOption } from './RulesDropdownOption.esm.js';
10
+
11
+ const ConditionsFormRowFields = ({
12
+ oldCondition,
13
+ index,
14
+ criteria,
15
+ onRuleChange,
16
+ conditionRow,
17
+ conditionRulesData,
18
+ setErrors,
19
+ optionDisabled,
20
+ setRemoveAllClicked,
21
+ nestedConditionRow,
22
+ nestedConditionCriteria,
23
+ nestedConditionIndex,
24
+ nestedConditionRuleIndex,
25
+ updateRules
26
+ }) => {
27
+ const classes = makeConditionsFormRowFieldsStyles({
28
+ isNotSimpleCondition: criteria === criterias.not && !nestedConditionCriteria
29
+ });
30
+ const rules = conditionRulesData?.rules ?? [];
31
+ const paramsSchema = conditionRulesData?.[oldCondition.rule]?.schema;
32
+ const schema = paramsSchema;
33
+ const uiSchema = {
34
+ "ui:submitButtonOptions": {
35
+ norender: true
36
+ },
37
+ "ui:classNames": `${classes.params}`,
38
+ "ui:field": "array"
39
+ };
40
+ const customFields = { ArrayField: CustomArrayField };
41
+ const handleConditionChange = (newCondition) => {
42
+ setRemoveAllClicked(false);
43
+ switch (criteria) {
44
+ case criterias.condition: {
45
+ onRuleChange({ condition: newCondition });
46
+ break;
47
+ }
48
+ case criterias.allOf: {
49
+ const updatedCriteria = conditionRow.allOf ?? [];
50
+ updatedCriteria[index ?? 0] = newCondition;
51
+ onRuleChange({ allOf: updatedCriteria });
52
+ break;
53
+ }
54
+ case criterias.anyOf: {
55
+ const updatedCriteria = conditionRow.anyOf ?? [];
56
+ updatedCriteria[index ?? 0] = newCondition;
57
+ onRuleChange({ anyOf: updatedCriteria });
58
+ break;
59
+ }
60
+ case criterias.not: {
61
+ onRuleChange({ not: newCondition });
62
+ break;
63
+ }
64
+ }
65
+ };
66
+ const handleNestedConditionChange = (newCondition) => {
67
+ if (!nestedConditionRow || !nestedConditionCriteria || nestedConditionIndex === void 0 || !updateRules) {
68
+ return;
69
+ }
70
+ const updatedNestedConditionRow = nestedConditionRow.map(
71
+ (c, i) => {
72
+ if (i === nestedConditionIndex) {
73
+ if (nestedConditionCriteria === criterias.not) {
74
+ return {
75
+ [nestedConditionCriteria]: newCondition
76
+ };
77
+ }
78
+ const updatedNestedConditionRules = (c[nestedConditionCriteria] || []).map((rule, rindex) => {
79
+ return rindex === nestedConditionRuleIndex ? newCondition : rule;
80
+ });
81
+ return {
82
+ [nestedConditionCriteria]: updatedNestedConditionRules
83
+ };
84
+ }
85
+ return c;
86
+ }
87
+ );
88
+ updateRules(
89
+ criteria === criterias.not ? updatedNestedConditionRow[0] : updatedNestedConditionRow
90
+ );
91
+ };
92
+ const handleTransformErrors = (errors) => {
93
+ if (criteria === criterias.condition || criteria === criterias.not && isSimpleRule(conditionRow[criteria])) {
94
+ setErrors((prevErrors) => {
95
+ const updatedErrors = { ...prevErrors };
96
+ updatedErrors[criteria] = setErrorMessage(errors);
97
+ return updatedErrors;
98
+ });
99
+ }
100
+ if (criteria === criterias.not && nestedConditionCriteria && !isSimpleRule(conditionRow[criteria])) {
101
+ setErrors((prevErrors) => {
102
+ const updatedErrors = { ...prevErrors };
103
+ const nestedErrors = updatedErrors[criteria][nestedConditionCriteria];
104
+ if (Array.isArray(nestedErrors) && nestedConditionRuleIndex !== void 0) {
105
+ nestedErrors[nestedConditionRuleIndex] = setErrorMessage(errors);
106
+ } else {
107
+ updatedErrors[criteria] = {
108
+ [nestedConditionCriteria]: setErrorMessage(errors)
109
+ };
110
+ }
111
+ return updatedErrors;
112
+ });
113
+ }
114
+ if (criteria === criterias.allOf || criteria === criterias.anyOf) {
115
+ setErrors((prevErrors) => {
116
+ const updatedErrors = { ...prevErrors };
117
+ const simpleRuleErrors = getSimpleRuleErrors(
118
+ updatedErrors[criteria]
119
+ );
120
+ if (Array.isArray(simpleRuleErrors) && simpleRuleErrors.length > 0 && index !== void 0) {
121
+ simpleRuleErrors[index] = setErrorMessage(errors);
122
+ }
123
+ const nestedRuleErrors = getNestedRuleErrors(
124
+ updatedErrors[criteria]
125
+ );
126
+ if (nestedConditionCriteria && nestedConditionIndex !== void 0 && nestedConditionRuleIndex !== void 0) {
127
+ const nestedConditionRuleList = nestedRuleErrors[nestedConditionIndex][nestedConditionCriteria];
128
+ if (Array.isArray(nestedConditionRuleList)) {
129
+ nestedConditionRuleList[nestedConditionRuleIndex] = setErrorMessage(errors);
130
+ }
131
+ }
132
+ if (Array.isArray(nestedRuleErrors) && nestedRuleErrors.length > 0 && nestedConditionCriteria === criterias.not && nestedConditionIndex !== void 0) {
133
+ nestedRuleErrors[nestedConditionIndex][nestedConditionCriteria] = setErrorMessage(errors);
134
+ }
135
+ updatedErrors[criteria] = [...simpleRuleErrors, ...nestedRuleErrors];
136
+ return updatedErrors;
137
+ });
138
+ }
139
+ return errors;
140
+ };
141
+ const onConditionChange = (newCondition) => {
142
+ if (nestedConditionRow) {
143
+ handleNestedConditionChange(newCondition);
144
+ } else {
145
+ handleConditionChange(newCondition);
146
+ }
147
+ };
148
+ return /* @__PURE__ */ React.createElement(Box, { className: classes.inputFieldContainer }, /* @__PURE__ */ React.createElement(
149
+ Autocomplete,
150
+ {
151
+ style: { width: "50%", marginTop: "26px" },
152
+ className: classes.params,
153
+ options: rules ?? [],
154
+ value: oldCondition?.rule || null,
155
+ getOptionDisabled: (option) => optionDisabled ? optionDisabled(option) : false,
156
+ onChange: (_event, ruleVal) => onConditionChange({
157
+ ...oldCondition,
158
+ rule: ruleVal ?? "",
159
+ params: {}
160
+ }),
161
+ renderOption: (option) => /* @__PURE__ */ React.createElement(
162
+ RulesDropdownOption,
163
+ {
164
+ label: option ?? "",
165
+ rulesData: conditionRulesData
166
+ }
167
+ ),
168
+ renderInput: (params) => /* @__PURE__ */ React.createElement(
169
+ TextField,
170
+ {
171
+ ...params,
172
+ label: "Rule",
173
+ variant: "outlined",
174
+ placeholder: "Select a rule",
175
+ required: true
176
+ }
177
+ )
178
+ }
179
+ ), /* @__PURE__ */ React.createElement(Box, { style: { width: "50%" } }, schema ? /* @__PURE__ */ React.createElement(
180
+ Form,
181
+ {
182
+ schema: paramsSchema,
183
+ formData: oldCondition?.params || {},
184
+ validator,
185
+ uiSchema,
186
+ fields: customFields,
187
+ onChange: (data) => onConditionChange({
188
+ ...oldCondition,
189
+ params: data.formData || {}
190
+ }),
191
+ transformErrors: handleTransformErrors,
192
+ showErrorList: false,
193
+ liveValidate: true
194
+ }
195
+ ) : /* @__PURE__ */ React.createElement(
196
+ TextField,
197
+ {
198
+ style: { width: "100%", marginTop: "26px" },
199
+ className: classes.params,
200
+ disabled: true,
201
+ label: "string, string",
202
+ required: true,
203
+ variant: "outlined"
204
+ }
205
+ )));
206
+ };
207
+
208
+ export { ConditionsFormRowFields };
209
+ //# sourceMappingURL=ConditionsFormRowFields.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConditionsFormRowFields.esm.js","sources":["../../../src/components/ConditionalAccess/ConditionsFormRowFields.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 { PermissionCondition } from '@backstage/plugin-permission-common';\n\nimport { Box, TextField } from '@material-ui/core';\nimport { Autocomplete } from '@material-ui/lab';\nimport Form from '@rjsf/mui';\nimport {\n RegistryFieldsType,\n RJSFSchema,\n RJSFValidationError,\n UiSchema,\n} from '@rjsf/utils';\nimport validator from '@rjsf/validator-ajv8';\n\nimport {\n getNestedRuleErrors,\n getSimpleRuleErrors,\n isSimpleRule,\n makeConditionsFormRowFieldsStyles,\n setErrorMessage,\n} from '../../utils/conditional-access-utils';\nimport { criterias } from './const';\nimport { CustomArrayField } from './CustomArrayField';\nimport { RulesDropdownOption } from './RulesDropdownOption';\nimport {\n AccessConditionsErrors,\n ComplexErrors,\n Condition,\n ConditionsData,\n NestedCriteriaErrors,\n RulesData,\n} from './types';\n\ntype ConditionFormRowFieldsProps = {\n oldCondition: Condition;\n index?: number;\n criteria: string;\n onRuleChange: (newCondition: ConditionsData) => void;\n conditionRow: ConditionsData | Condition;\n conditionRulesData?: RulesData;\n setErrors: React.Dispatch<\n React.SetStateAction<AccessConditionsErrors | undefined>\n >;\n optionDisabled?: (ruleOption: string) => boolean;\n setRemoveAllClicked: React.Dispatch<React.SetStateAction<boolean>>;\n nestedConditionRow?: Condition[];\n nestedConditionCriteria?: string;\n nestedConditionIndex?: number;\n nestedConditionRuleIndex?: number;\n updateRules?: (newCondition: Condition[] | Condition) => void;\n};\n\nexport const ConditionsFormRowFields = ({\n oldCondition,\n index,\n criteria,\n onRuleChange,\n conditionRow,\n conditionRulesData,\n setErrors,\n optionDisabled,\n setRemoveAllClicked,\n nestedConditionRow,\n nestedConditionCriteria,\n nestedConditionIndex,\n nestedConditionRuleIndex,\n updateRules,\n}: ConditionFormRowFieldsProps) => {\n const classes = makeConditionsFormRowFieldsStyles({\n isNotSimpleCondition:\n criteria === criterias.not && !nestedConditionCriteria,\n });\n const rules = conditionRulesData?.rules ?? [];\n const paramsSchema =\n conditionRulesData?.[(oldCondition as PermissionCondition).rule]?.schema;\n\n const schema: RJSFSchema = paramsSchema;\n\n const uiSchema: UiSchema = {\n 'ui:submitButtonOptions': {\n norender: true,\n },\n 'ui:classNames': `${classes.params}`,\n 'ui:field': 'array',\n };\n\n const customFields: RegistryFieldsType = { ArrayField: CustomArrayField };\n\n const handleConditionChange = (newCondition: PermissionCondition) => {\n setRemoveAllClicked(false);\n switch (criteria) {\n case criterias.condition: {\n onRuleChange({ condition: newCondition });\n break;\n }\n case criterias.allOf: {\n const updatedCriteria = (conditionRow as ConditionsData).allOf ?? [];\n updatedCriteria[index ?? 0] = newCondition;\n onRuleChange({ allOf: updatedCriteria });\n break;\n }\n case criterias.anyOf: {\n const updatedCriteria = (conditionRow as ConditionsData).anyOf ?? [];\n updatedCriteria[index ?? 0] = newCondition;\n onRuleChange({ anyOf: updatedCriteria });\n break;\n }\n case criterias.not: {\n onRuleChange({ not: newCondition });\n break;\n }\n default:\n }\n };\n\n const handleNestedConditionChange = (newCondition: PermissionCondition) => {\n if (\n !nestedConditionRow ||\n !nestedConditionCriteria ||\n nestedConditionIndex === undefined ||\n !updateRules\n ) {\n return;\n }\n const updatedNestedConditionRow: Condition[] = nestedConditionRow.map(\n (c, i) => {\n if (i === nestedConditionIndex) {\n if (nestedConditionCriteria === criterias.not) {\n return {\n [nestedConditionCriteria]: newCondition,\n };\n }\n const updatedNestedConditionRules = (\n (c[\n nestedConditionCriteria as keyof Condition\n ] as PermissionCondition[]) || []\n ).map((rule, rindex) => {\n return rindex === nestedConditionRuleIndex ? newCondition : rule;\n });\n\n return {\n [nestedConditionCriteria]: updatedNestedConditionRules,\n };\n }\n return c;\n },\n );\n\n updateRules(\n criteria === criterias.not\n ? updatedNestedConditionRow[0]\n : updatedNestedConditionRow,\n );\n };\n\n const handleTransformErrors = (errors: RJSFValidationError[]) => {\n // criteria: condition or not simple-condition\n if (\n criteria === criterias.condition ||\n (criteria === criterias.not &&\n isSimpleRule(conditionRow[criteria as keyof Condition]))\n ) {\n setErrors(prevErrors => {\n const updatedErrors = { ...prevErrors };\n updatedErrors[criteria] = setErrorMessage(errors);\n\n return updatedErrors;\n });\n }\n\n // criteria: not nested-condition\n if (\n criteria === criterias.not &&\n nestedConditionCriteria &&\n !isSimpleRule(conditionRow[criteria as keyof Condition])\n ) {\n setErrors(prevErrors => {\n const updatedErrors = { ...prevErrors };\n const nestedErrors = (updatedErrors[criteria] as ComplexErrors)[\n nestedConditionCriteria as keyof Condition\n ] as NestedCriteriaErrors;\n\n // nestedCriteria: allOf or anyOf\n if (\n Array.isArray(nestedErrors) &&\n nestedConditionRuleIndex !== undefined\n ) {\n nestedErrors[nestedConditionRuleIndex] = setErrorMessage(errors);\n } else {\n // nestedCriteria: not\n updatedErrors[criteria] = {\n [nestedConditionCriteria]: setErrorMessage(errors),\n };\n }\n\n return updatedErrors;\n });\n }\n\n // criteria: allOf or anyOf\n if (criteria === criterias.allOf || criteria === criterias.anyOf) {\n setErrors(prevErrors => {\n const updatedErrors = { ...prevErrors };\n const simpleRuleErrors = getSimpleRuleErrors(\n updatedErrors[\n criteria as keyof AccessConditionsErrors\n ] as ComplexErrors[],\n );\n if (\n Array.isArray(simpleRuleErrors) &&\n simpleRuleErrors.length > 0 &&\n index !== undefined\n ) {\n simpleRuleErrors[index] = setErrorMessage(errors);\n }\n\n const nestedRuleErrors = getNestedRuleErrors(\n updatedErrors[\n criteria as keyof AccessConditionsErrors\n ] as ComplexErrors[],\n );\n\n // nestedCriteria: allOf or anyOf\n if (\n nestedConditionCriteria &&\n nestedConditionIndex !== undefined &&\n nestedConditionRuleIndex !== undefined\n ) {\n const nestedConditionRuleList =\n nestedRuleErrors[nestedConditionIndex][nestedConditionCriteria];\n\n if (Array.isArray(nestedConditionRuleList)) {\n nestedConditionRuleList[nestedConditionRuleIndex] =\n setErrorMessage(errors);\n }\n }\n\n // nestedCriteria: not\n if (\n Array.isArray(nestedRuleErrors) &&\n nestedRuleErrors.length > 0 &&\n nestedConditionCriteria === criterias.not &&\n nestedConditionIndex !== undefined\n ) {\n nestedRuleErrors[nestedConditionIndex][nestedConditionCriteria] =\n setErrorMessage(errors);\n }\n\n updatedErrors[criteria] = [...simpleRuleErrors, ...nestedRuleErrors];\n return updatedErrors;\n });\n }\n\n return errors;\n };\n\n const onConditionChange = (newCondition: PermissionCondition) => {\n if (nestedConditionRow) {\n handleNestedConditionChange(newCondition);\n } else {\n handleConditionChange(newCondition);\n }\n };\n\n return (\n <Box className={classes.inputFieldContainer}>\n <Autocomplete\n style={{ width: '50%', marginTop: '26px' }}\n className={classes.params}\n options={rules ?? []}\n value={(oldCondition as PermissionCondition)?.rule || null}\n getOptionDisabled={option =>\n optionDisabled ? optionDisabled(option) : false\n }\n onChange={(_event, ruleVal?: string | null) =>\n onConditionChange({\n ...oldCondition,\n rule: ruleVal ?? '',\n params: {},\n } as PermissionCondition)\n }\n renderOption={option => (\n <RulesDropdownOption\n label={option ?? ''}\n rulesData={conditionRulesData}\n />\n )}\n renderInput={(params: any) => (\n <TextField\n {...params}\n label=\"Rule\"\n variant=\"outlined\"\n placeholder=\"Select a rule\"\n required\n />\n )}\n />\n <Box style={{ width: '50%' }}>\n {schema ? (\n <Form\n schema={paramsSchema}\n formData={(oldCondition as PermissionCondition)?.params || {}}\n validator={validator}\n uiSchema={uiSchema}\n fields={customFields}\n onChange={data =>\n onConditionChange({\n ...oldCondition,\n params: data.formData || {},\n } as PermissionCondition)\n }\n transformErrors={handleTransformErrors}\n showErrorList={false}\n liveValidate\n />\n ) : (\n <TextField\n style={{ width: '100%', marginTop: '26px' }}\n className={classes.params}\n disabled\n label=\"string, string\"\n required\n variant=\"outlined\"\n />\n )}\n </Box>\n </Box>\n );\n};\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ import React from 'react';
2
+ import ToggleButton from '@mui/material/ToggleButton';
3
+
4
+ const CriteriaToggleButton = ({
5
+ val,
6
+ label,
7
+ selectedCriteria,
8
+ theme
9
+ }) => {
10
+ const isSelected = val === selectedCriteria;
11
+ const buttonStyle = {
12
+ color: isSelected ? theme.palette.infoText : theme.palette.textSubtle,
13
+ backgroundColor: isSelected ? theme.palette.infoBackground : "",
14
+ border: `1px solid ${theme.palette.border}`,
15
+ width: "100%",
16
+ textTransform: "none",
17
+ padding: theme.spacing(1)
18
+ };
19
+ return /* @__PURE__ */ React.createElement(
20
+ ToggleButton,
21
+ {
22
+ key: val,
23
+ value: val,
24
+ style: buttonStyle,
25
+ size: "large",
26
+ disabled: isSelected
27
+ },
28
+ label
29
+ );
30
+ };
31
+
32
+ export { CriteriaToggleButton };
33
+ //# sourceMappingURL=CriteriaToggleButton.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CriteriaToggleButton.esm.js","sources":["../../../src/components/ConditionalAccess/CriteriaToggleButton.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, { CSSProperties } from 'react';\n\nimport { Theme } from '@material-ui/core';\nimport ToggleButton from '@mui/material/ToggleButton';\n\ntype CriteriaToggleButtonProps = {\n val: string;\n label: string;\n selectedCriteria: string;\n theme: Theme;\n};\n\nexport const CriteriaToggleButton = ({\n val,\n label,\n selectedCriteria,\n theme,\n}: CriteriaToggleButtonProps) => {\n const isSelected = val === selectedCriteria;\n const buttonStyle: CSSProperties = {\n color: isSelected ? theme.palette.infoText : theme.palette.textSubtle,\n backgroundColor: isSelected ? theme.palette.infoBackground : '',\n border: `1px solid ${theme.palette.border}`,\n width: '100%',\n textTransform: 'none',\n padding: theme.spacing(1),\n };\n\n return (\n <ToggleButton\n key={val}\n value={val}\n style={buttonStyle}\n size=\"large\"\n disabled={isSelected}\n >\n {label}\n </ToggleButton>\n );\n};\n"],"names":[],"mappings":";;;AA2BO,MAAM,uBAAuB,CAAC;AAAA,EACnC,GAAA;AAAA,EACA,KAAA;AAAA,EACA,gBAAA;AAAA,EACA,KAAA;AACF,CAAiC,KAAA;AAC/B,EAAA,MAAM,aAAa,GAAQ,KAAA,gBAAA,CAAA;AAC3B,EAAA,MAAM,WAA6B,GAAA;AAAA,IACjC,OAAO,UAAa,GAAA,KAAA,CAAM,OAAQ,CAAA,QAAA,GAAW,MAAM,OAAQ,CAAA,UAAA;AAAA,IAC3D,eAAiB,EAAA,UAAA,GAAa,KAAM,CAAA,OAAA,CAAQ,cAAiB,GAAA,EAAA;AAAA,IAC7D,MAAQ,EAAA,CAAA,UAAA,EAAa,KAAM,CAAA,OAAA,CAAQ,MAAM,CAAA,CAAA;AAAA,IACzC,KAAO,EAAA,MAAA;AAAA,IACP,aAAe,EAAA,MAAA;AAAA,IACf,OAAA,EAAS,KAAM,CAAA,OAAA,CAAQ,CAAC,CAAA;AAAA,GAC1B,CAAA;AAEA,EACE,uBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,YAAA;AAAA,IAAA;AAAA,MACC,GAAK,EAAA,GAAA;AAAA,MACL,KAAO,EAAA,GAAA;AAAA,MACP,KAAO,EAAA,WAAA;AAAA,MACP,IAAK,EAAA,OAAA;AAAA,MACL,QAAU,EAAA,UAAA;AAAA,KAAA;AAAA,IAET,KAAA;AAAA,GACH,CAAA;AAEJ;;;;"}
@@ -0,0 +1,47 @@
1
+ import React from 'react';
2
+ import { makeStyles, TextField, Typography } from '@material-ui/core';
3
+ import { getDefaultRegistry } from '@rjsf/core';
4
+ import { getInnerSchemaForArrayItem } from '@rjsf/utils/lib/schema/getDefaultFormState';
5
+
6
+ const useStyles = makeStyles((theme) => ({
7
+ arrayFieldDescription: {
8
+ marginTop: "5px",
9
+ fontWeight: 500,
10
+ color: `${theme.palette.grey[500]} !important`
11
+ }
12
+ }));
13
+ const CustomArrayField = (props) => {
14
+ const { name, required, schema: sch, formData, onChange } = props;
15
+ const classes = useStyles();
16
+ const [fieldVal, setFieldVal] = React.useState(
17
+ formData?.toString() ?? ""
18
+ );
19
+ const arrayItemsType = getInnerSchemaForArrayItem(sch).type;
20
+ const DefaultArrayField = getDefaultRegistry().fields.ArrayField;
21
+ return arrayItemsType === "string" ? /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(
22
+ TextField,
23
+ {
24
+ name,
25
+ variant: "outlined",
26
+ label: name,
27
+ value: fieldVal,
28
+ onChange: (e) => {
29
+ const value = e.target.value;
30
+ setFieldVal(value);
31
+ onChange(value ? value.split(",").map((val) => val.trim()) : []);
32
+ },
33
+ required,
34
+ placeholder: "string, string"
35
+ }
36
+ ), /* @__PURE__ */ React.createElement(Typography, { variant: "caption" }, /* @__PURE__ */ React.createElement(
37
+ Typography,
38
+ {
39
+ variant: "subtitle2",
40
+ className: classes.arrayFieldDescription
41
+ },
42
+ sch.description ?? ""
43
+ ))) : /* @__PURE__ */ React.createElement(DefaultArrayField, { ...props });
44
+ };
45
+
46
+ export { CustomArrayField };
47
+ //# sourceMappingURL=CustomArrayField.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CustomArrayField.esm.js","sources":["../../../src/components/ConditionalAccess/CustomArrayField.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 { makeStyles, TextField, Typography } from '@material-ui/core';\nimport { getDefaultRegistry } from '@rjsf/core';\nimport { FieldProps } from '@rjsf/utils';\nimport { getInnerSchemaForArrayItem } from '@rjsf/utils/lib/schema/getDefaultFormState';\n\nconst useStyles = makeStyles(theme => ({\n arrayFieldDescription: {\n marginTop: '5px',\n fontWeight: 500,\n color: `${theme.palette.grey[500]} !important`,\n },\n}));\n\nexport const CustomArrayField = (props: FieldProps) => {\n const { name, required, schema: sch, formData, onChange } = props;\n const classes = useStyles();\n const [fieldVal, setFieldVal] = React.useState<string>(\n formData?.toString() ?? '',\n );\n\n const arrayItemsType = getInnerSchemaForArrayItem(sch).type;\n\n const DefaultArrayField = getDefaultRegistry().fields.ArrayField;\n\n return arrayItemsType === 'string' ? (\n <>\n <TextField\n name={name}\n variant=\"outlined\"\n label={name}\n value={fieldVal}\n onChange={e => {\n const value = e.target.value;\n setFieldVal(value);\n onChange(value ? value.split(',').map(val => val.trim()) : []);\n }}\n required={required}\n placeholder=\"string, string\"\n />\n <Typography variant=\"caption\">\n <Typography\n variant=\"subtitle2\"\n className={classes.arrayFieldDescription}\n >\n {sch.description ?? ''}\n </Typography>\n </Typography>\n </>\n ) : (\n <DefaultArrayField {...props} />\n );\n};\n"],"names":[],"mappings":";;;;;AAsBA,MAAM,SAAA,GAAY,WAAW,CAAU,KAAA,MAAA;AAAA,EACrC,qBAAuB,EAAA;AAAA,IACrB,SAAW,EAAA,KAAA;AAAA,IACX,UAAY,EAAA,GAAA;AAAA,IACZ,OAAO,CAAG,EAAA,KAAA,CAAM,OAAQ,CAAA,IAAA,CAAK,GAAG,CAAC,CAAA,WAAA,CAAA;AAAA,GACnC;AACF,CAAE,CAAA,CAAA,CAAA;AAEW,MAAA,gBAAA,GAAmB,CAAC,KAAsB,KAAA;AACrD,EAAA,MAAM,EAAE,IAAM,EAAA,QAAA,EAAU,QAAQ,GAAK,EAAA,QAAA,EAAU,UAAa,GAAA,KAAA,CAAA;AAC5D,EAAA,MAAM,UAAU,SAAU,EAAA,CAAA;AAC1B,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAI,KAAM,CAAA,QAAA;AAAA,IACpC,QAAA,EAAU,UAAc,IAAA,EAAA;AAAA,GAC1B,CAAA;AAEA,EAAM,MAAA,cAAA,GAAiB,0BAA2B,CAAA,GAAG,CAAE,CAAA,IAAA,CAAA;AAEvD,EAAM,MAAA,iBAAA,GAAoB,kBAAmB,EAAA,CAAE,MAAO,CAAA,UAAA,CAAA;AAEtD,EAAO,OAAA,cAAA,KAAmB,2BAEtB,KAAA,CAAA,aAAA,CAAA,KAAA,CAAA,QAAA,EAAA,IAAA,kBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,SAAA;AAAA,IAAA;AAAA,MACC,IAAA;AAAA,MACA,OAAQ,EAAA,UAAA;AAAA,MACR,KAAO,EAAA,IAAA;AAAA,MACP,KAAO,EAAA,QAAA;AAAA,MACP,UAAU,CAAK,CAAA,KAAA;AACb,QAAM,MAAA,KAAA,GAAQ,EAAE,MAAO,CAAA,KAAA,CAAA;AACvB,QAAA,WAAA,CAAY,KAAK,CAAA,CAAA;AACjB,QAAA,QAAA,CAAS,KAAQ,GAAA,KAAA,CAAM,KAAM,CAAA,GAAG,CAAE,CAAA,GAAA,CAAI,CAAO,GAAA,KAAA,GAAA,CAAI,IAAK,EAAC,CAAI,GAAA,EAAE,CAAA,CAAA;AAAA,OAC/D;AAAA,MACA,QAAA;AAAA,MACA,WAAY,EAAA,gBAAA;AAAA,KAAA;AAAA,GAEd,kBAAA,KAAA,CAAA,aAAA,CAAC,UAAW,EAAA,EAAA,OAAA,EAAQ,SAClB,EAAA,kBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,UAAA;AAAA,IAAA;AAAA,MACC,OAAQ,EAAA,WAAA;AAAA,MACR,WAAW,OAAQ,CAAA,qBAAA;AAAA,KAAA;AAAA,IAElB,IAAI,WAAe,IAAA,EAAA;AAAA,GAExB,CACF,CAAA,mBAEC,KAAA,CAAA,aAAA,CAAA,iBAAA,EAAA,EAAmB,GAAG,KAAO,EAAA,CAAA,CAAA;AAElC;;;;"}
@@ -0,0 +1,24 @@
1
+ import React from 'react';
2
+ import { makeStyles, Typography } from '@material-ui/core';
3
+ import Box from '@mui/material/Box';
4
+
5
+ const useStyles = makeStyles((theme) => ({
6
+ optionLabel: {
7
+ color: theme.palette.text.primary
8
+ },
9
+ optionDescription: {
10
+ color: theme.palette.text.secondary,
11
+ fontSize: "14px"
12
+ }
13
+ }));
14
+ const RulesDropdownOption = ({
15
+ label,
16
+ rulesData
17
+ }) => {
18
+ const classes = useStyles();
19
+ const description = rulesData?.[label]?.description ?? "";
20
+ return /* @__PURE__ */ React.createElement(Box, { style: { display: "flex", flexFlow: "column" } }, /* @__PURE__ */ React.createElement(Typography, { className: classes.optionLabel }, label), /* @__PURE__ */ React.createElement(Typography, { className: classes.optionDescription }, description));
21
+ };
22
+
23
+ export { RulesDropdownOption };
24
+ //# sourceMappingURL=RulesDropdownOption.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RulesDropdownOption.esm.js","sources":["../../../src/components/ConditionalAccess/RulesDropdownOption.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 { makeStyles, Typography } from '@material-ui/core';\nimport Box from '@mui/material/Box';\n\nimport { RulesData } from './types';\n\nconst useStyles = makeStyles(theme => ({\n optionLabel: {\n color: theme.palette.text.primary,\n },\n optionDescription: {\n color: theme.palette.text.secondary,\n fontSize: '14px',\n },\n}));\n\ntype RulesDropdownOptionProps = {\n label: string;\n rulesData?: RulesData;\n};\n\nexport const RulesDropdownOption = ({\n label,\n rulesData,\n}: RulesDropdownOptionProps) => {\n const classes = useStyles();\n const description = rulesData?.[label]?.description ?? '';\n return (\n <Box style={{ display: 'flex', flexFlow: 'column' }}>\n <Typography className={classes.optionLabel}>{label}</Typography>\n <Typography className={classes.optionDescription}>\n {description}\n </Typography>\n </Box>\n );\n};\n"],"names":[],"mappings":";;;;AAsBA,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,IAC1B,QAAU,EAAA,MAAA;AAAA,GACZ;AACF,CAAE,CAAA,CAAA,CAAA;AAOK,MAAM,sBAAsB,CAAC;AAAA,EAClC,KAAA;AAAA,EACA,SAAA;AACF,CAAgC,KAAA;AAC9B,EAAA,MAAM,UAAU,SAAU,EAAA,CAAA;AAC1B,EAAA,MAAM,WAAc,GAAA,SAAA,GAAY,KAAK,CAAA,EAAG,WAAe,IAAA,EAAA,CAAA;AACvD,EACE,uBAAA,KAAA,CAAA,aAAA,CAAC,OAAI,KAAO,EAAA,EAAE,SAAS,MAAQ,EAAA,QAAA,EAAU,QAAS,EAAA,EAAA,kBAC/C,KAAA,CAAA,aAAA,CAAA,UAAA,EAAA,EAAW,WAAW,OAAQ,CAAA,WAAA,EAAA,EAAc,KAAM,CACnD,kBAAA,KAAA,CAAA,aAAA,CAAC,cAAW,SAAW,EAAA,OAAA,CAAQ,iBAC5B,EAAA,EAAA,WACH,CACF,CAAA,CAAA;AAEJ;;;;"}
@@ -0,0 +1,21 @@
1
+ const criterias = {
2
+ condition: "condition",
3
+ anyOf: "anyOf",
4
+ allOf: "allOf",
5
+ not: "not"
6
+ };
7
+ const criteriasLabels = {
8
+ [criterias.condition]: "Condition",
9
+ [criterias.allOf]: "AllOf",
10
+ [criterias.anyOf]: "AnyOf",
11
+ [criterias.not]: "Not"
12
+ };
13
+ const conditionButtons = [
14
+ { val: criterias.condition, label: criteriasLabels[criterias.condition] },
15
+ { val: criterias.allOf, label: criteriasLabels[criterias.allOf] },
16
+ { val: criterias.anyOf, label: criteriasLabels[criterias.anyOf] },
17
+ { val: criterias.not, label: criteriasLabels[criterias.not] }
18
+ ];
19
+
20
+ export { conditionButtons, criterias, criteriasLabels };
21
+ //# sourceMappingURL=const.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"const.esm.js","sources":["../../../src/components/ConditionalAccess/const.ts"],"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 { ConditionsData } from './types';\n\nexport const criterias = {\n condition: 'condition' as keyof ConditionsData,\n anyOf: 'anyOf' as keyof ConditionsData,\n allOf: 'allOf' as keyof ConditionsData,\n not: 'not' as keyof ConditionsData,\n};\n\nexport const criteriasLabels = {\n [criterias.condition]: 'Condition',\n [criterias.allOf]: 'AllOf',\n [criterias.anyOf]: 'AnyOf',\n [criterias.not]: 'Not',\n};\n\nexport const conditionButtons = [\n { val: criterias.condition, label: criteriasLabels[criterias.condition] },\n { val: criterias.allOf, label: criteriasLabels[criterias.allOf] },\n { val: criterias.anyOf, label: criteriasLabels[criterias.anyOf] },\n { val: criterias.not, label: criteriasLabels[criterias.not] },\n];\n"],"names":[],"mappings":"AAiBO,MAAM,SAAY,GAAA;AAAA,EACvB,SAAW,EAAA,WAAA;AAAA,EACX,KAAO,EAAA,OAAA;AAAA,EACP,KAAO,EAAA,OAAA;AAAA,EACP,GAAK,EAAA,KAAA;AACP,EAAA;AAEO,MAAM,eAAkB,GAAA;AAAA,EAC7B,CAAC,SAAU,CAAA,SAAS,GAAG,WAAA;AAAA,EACvB,CAAC,SAAU,CAAA,KAAK,GAAG,OAAA;AAAA,EACnB,CAAC,SAAU,CAAA,KAAK,GAAG,OAAA;AAAA,EACnB,CAAC,SAAU,CAAA,GAAG,GAAG,KAAA;AACnB,EAAA;AAEO,MAAM,gBAAmB,GAAA;AAAA,EAC9B,EAAE,KAAK,SAAU,CAAA,SAAA,EAAW,OAAO,eAAgB,CAAA,SAAA,CAAU,SAAS,CAAE,EAAA;AAAA,EACxE,EAAE,KAAK,SAAU,CAAA,KAAA,EAAO,OAAO,eAAgB,CAAA,SAAA,CAAU,KAAK,CAAE,EAAA;AAAA,EAChE,EAAE,KAAK,SAAU,CAAA,KAAA,EAAO,OAAO,eAAgB,CAAA,SAAA,CAAU,KAAK,CAAE,EAAA;AAAA,EAChE,EAAE,KAAK,SAAU,CAAA,GAAA,EAAK,OAAO,eAAgB,CAAA,SAAA,CAAU,GAAG,CAAE,EAAA;AAC9D;;;;"}
@@ -0,0 +1,8 @@
1
+ var NotConditionType = /* @__PURE__ */ ((NotConditionType2) => {
2
+ NotConditionType2["SimpleCondition"] = "simple-condition";
3
+ NotConditionType2["NestedCondition"] = "nested-condition";
4
+ return NotConditionType2;
5
+ })(NotConditionType || {});
6
+
7
+ export { NotConditionType };
8
+ //# sourceMappingURL=types.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.esm.js","sources":["../../../src/components/ConditionalAccess/types.ts"],"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 { PermissionCondition } from '@backstage/plugin-permission-common';\n\nexport type RulesData = {\n rules: string[];\n [rule: string]: {\n [key: string]: any;\n };\n};\n\nexport type ResourceTypeRuleData = {\n [resourceType: string]: RulesData;\n};\n\nexport type ConditionRulesData = {\n [plugin: string]: ResourceTypeRuleData;\n};\n\nexport type ConditionRules = {\n data?: ConditionRulesData;\n error?: Error;\n};\n\nexport type ConditionsData = {\n allOf?: Condition[];\n anyOf?: Condition[];\n not?: Condition;\n condition?: PermissionCondition;\n};\n\nexport type Condition = PermissionCondition | ConditionsData;\n\nexport type ComplexErrors = string | NestedCriteriaErrors;\n\nexport type NestedCriteriaErrors = {\n [nestedCriteria: string]: string[] | string;\n};\n\nexport type AccessConditionsErrors = {\n [criteria: string]: ComplexErrors[] | NestedCriteriaErrors | string;\n};\n\nexport type ConditionFormRowProps = {\n conditionRulesData?: RulesData;\n conditionRow: ConditionsData;\n onRuleChange: (newCondition: ConditionsData) => void;\n selPluginResourceType: string;\n criteria: keyof ConditionsData;\n setCriteria: React.Dispatch<React.SetStateAction<keyof ConditionsData>>;\n setErrors: React.Dispatch<\n React.SetStateAction<AccessConditionsErrors | undefined>\n >;\n setRemoveAllClicked: React.Dispatch<React.SetStateAction<boolean>>;\n};\n\nexport enum NotConditionType {\n SimpleCondition = 'simple-condition',\n NestedCondition = 'nested-condition',\n}\n"],"names":["NotConditionType"],"mappings":"AAqEY,IAAA,gBAAA,qBAAAA,iBAAL,KAAA;AACL,EAAAA,kBAAA,iBAAkB,CAAA,GAAA,kBAAA,CAAA;AAClB,EAAAA,kBAAA,iBAAkB,CAAA,GAAA,kBAAA,CAAA;AAFR,EAAAA,OAAAA,iBAAAA,CAAAA;AAAA,CAAA,EAAA,gBAAA,IAAA,EAAA;;;;"}
@@ -0,0 +1,94 @@
1
+ import React from 'react';
2
+ import { stringifyEntityRef } from '@backstage/catalog-model';
3
+ import { LinearProgress, TextField } from '@material-ui/core';
4
+ import FormHelperText from '@material-ui/core/FormHelperText';
5
+ import Autocomplete from '@material-ui/lab/Autocomplete';
6
+ import { getMembersCount, getParentGroupsCount, getChildGroupsCount } from '../../utils/create-role-utils.esm.js';
7
+ import { MembersDropdownOption } from './MembersDropdownOption.esm.js';
8
+
9
+ const AddMembersForm = ({
10
+ selectedMembers,
11
+ selectedMembersError,
12
+ setFieldValue,
13
+ membersData
14
+ }) => {
15
+ const [search, setSearch] = React.useState("");
16
+ const [selectedMember, setSelectedMember] = React.useState({
17
+ label: "",
18
+ etag: "",
19
+ type: "",
20
+ ref: ""
21
+ });
22
+ const getDescription = (member) => {
23
+ const memberCount = getMembersCount(member);
24
+ const parentCount = getParentGroupsCount(member);
25
+ const childCount = getChildGroupsCount(member);
26
+ return member.kind === "Group" ? `${memberCount} members, ${parentCount} parent group, ${childCount} child groups` : void 0;
27
+ };
28
+ const membersOptions = React.useMemo(() => {
29
+ return membersData.members ? membersData.members.map((member, index) => {
30
+ const tag = member.metadata.etag ?? `${member.metadata.name}-${member.kind}-${index}`;
31
+ return {
32
+ id: tag,
33
+ label: member.spec?.profile?.displayName ?? member.metadata.name,
34
+ description: getDescription(member),
35
+ etag: tag,
36
+ type: member.kind,
37
+ namespace: member.metadata.namespace,
38
+ members: getMembersCount(member),
39
+ ref: stringifyEntityRef(member)
40
+ };
41
+ }) : [];
42
+ }, [membersData.members]);
43
+ const filteredMembers = React.useMemo(() => {
44
+ if (search) {
45
+ return membersOptions.filter(
46
+ (m) => m.label.toLocaleLowerCase("en-US").includes(search.toLocaleLowerCase("en-US"))
47
+ ).slice(0, 99);
48
+ }
49
+ return membersOptions.slice(0, 99);
50
+ }, [membersOptions, search]);
51
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(FormHelperText, null, "Search and select users and groups to be added. Selected users and groups will appear in the members table."), /* @__PURE__ */ React.createElement("br", null), /* @__PURE__ */ React.createElement(
52
+ Autocomplete,
53
+ {
54
+ options: filteredMembers || [],
55
+ getOptionLabel: (option) => option.label ?? "",
56
+ getOptionSelected: (option, value) => value.etag ? option.etag === value.etag : selectedMember.etag === value.etag,
57
+ loading: membersData.loading,
58
+ loadingText: /* @__PURE__ */ React.createElement(LinearProgress, null),
59
+ disableClearable: true,
60
+ value: selectedMember,
61
+ onChange: (_e, value) => {
62
+ setSelectedMember(value);
63
+ if (value) {
64
+ setSearch(value.label);
65
+ setFieldValue("selectedMembers", [...selectedMembers, value]);
66
+ }
67
+ },
68
+ inputValue: search,
69
+ onInputChange: (_e, newSearch, reason) => reason === "input" && setSearch(newSearch),
70
+ getOptionDisabled: (option) => !!selectedMembers.find(
71
+ (sm) => sm.etag === option.etag
72
+ ),
73
+ renderOption: (option, state) => /* @__PURE__ */ React.createElement(MembersDropdownOption, { option, state }),
74
+ noOptionsText: "No users and groups found.",
75
+ clearOnEscape: true,
76
+ renderInput: (params) => /* @__PURE__ */ React.createElement(
77
+ TextField,
78
+ {
79
+ ...params,
80
+ name: "add-users-and-groups",
81
+ variant: "outlined",
82
+ label: "Users and groups",
83
+ placeholder: "Search by user name or group name",
84
+ error: !!selectedMembersError,
85
+ helperText: selectedMembersError ?? "",
86
+ required: true
87
+ }
88
+ )
89
+ }
90
+ ), /* @__PURE__ */ React.createElement("br", null), membersData.error?.message && /* @__PURE__ */ React.createElement(FormHelperText, { error: !!membersData.error }, `Error fetching user and groups: ${membersData.error.message}`));
91
+ };
92
+
93
+ export { AddMembersForm };
94
+ //# sourceMappingURL=AddMembersForm.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AddMembersForm.esm.js","sources":["../../../src/components/CreateRole/AddMembersForm.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 { stringifyEntityRef } from '@backstage/catalog-model';\n\nimport { LinearProgress, TextField } from '@material-ui/core';\nimport FormHelperText from '@material-ui/core/FormHelperText';\nimport Autocomplete from '@material-ui/lab/Autocomplete';\nimport { FormikErrors } from 'formik';\n\nimport { MemberEntity } from '../../types';\nimport {\n getChildGroupsCount,\n getMembersCount,\n getParentGroupsCount,\n} from '../../utils/create-role-utils';\nimport { MembersDropdownOption } from './MembersDropdownOption';\nimport { RoleFormValues, SelectedMember } from './types';\n\ntype AddMembersFormProps = {\n selectedMembers: SelectedMember[];\n selectedMembersError?: string;\n membersData: { members: MemberEntity[]; loading: boolean; error: Error };\n setFieldValue: (\n field: string,\n value: any,\n shouldValidate?: boolean,\n ) => Promise<FormikErrors<RoleFormValues>> | Promise<void>;\n};\n\nexport const AddMembersForm = ({\n selectedMembers,\n selectedMembersError,\n setFieldValue,\n membersData,\n}: AddMembersFormProps) => {\n const [search, setSearch] = React.useState<string>('');\n const [selectedMember, setSelectedMember] = React.useState<SelectedMember>({\n label: '',\n etag: '',\n type: '',\n ref: '',\n } as SelectedMember);\n\n const getDescription = (member: MemberEntity) => {\n const memberCount = getMembersCount(member);\n const parentCount = getParentGroupsCount(member);\n const childCount = getChildGroupsCount(member);\n\n return member.kind === 'Group'\n ? `${memberCount} members, ${parentCount} parent group, ${childCount} child groups`\n : undefined;\n };\n\n const membersOptions: SelectedMember[] = React.useMemo(() => {\n return membersData.members\n ? membersData.members.map((member: MemberEntity, index: number) => {\n const tag =\n member.metadata.etag ??\n `${member.metadata.name}-${member.kind}-${index}`;\n return {\n id: tag,\n label: member.spec?.profile?.displayName ?? member.metadata.name,\n description: getDescription(member),\n etag: tag,\n type: member.kind,\n namespace: member.metadata.namespace,\n members: getMembersCount(member),\n ref: stringifyEntityRef(member),\n };\n })\n : ([] as SelectedMember[]);\n }, [membersData.members]);\n\n const filteredMembers = React.useMemo(() => {\n if (search) {\n return membersOptions\n .filter(m =>\n m.label\n .toLocaleLowerCase('en-US')\n .includes(search.toLocaleLowerCase('en-US')),\n )\n .slice(0, 99);\n }\n\n return membersOptions.slice(0, 99);\n }, [membersOptions, search]);\n\n return (\n <>\n <FormHelperText>\n Search and select users and groups to be added. Selected users and\n groups will appear in the members table.\n </FormHelperText>\n <br />\n <Autocomplete\n options={filteredMembers || []}\n getOptionLabel={(option: SelectedMember) => option.label ?? ''}\n getOptionSelected={(option: SelectedMember, value: SelectedMember) =>\n value.etag\n ? option.etag === value.etag\n : selectedMember.etag === value.etag\n }\n loading={membersData.loading}\n loadingText={<LinearProgress />}\n disableClearable\n value={selectedMember}\n onChange={(_e, value: SelectedMember) => {\n setSelectedMember(value);\n if (value) {\n setSearch(value.label);\n setFieldValue('selectedMembers', [...selectedMembers, value]);\n }\n }}\n inputValue={search}\n onInputChange={(_e, newSearch: string, reason) =>\n reason === 'input' && setSearch(newSearch)\n }\n getOptionDisabled={(option: SelectedMember) =>\n !!selectedMembers.find(\n (sm: SelectedMember) => sm.etag === option.etag,\n )\n }\n renderOption={(option: SelectedMember, state) => (\n <MembersDropdownOption option={option} state={state} />\n )}\n noOptionsText=\"No users and groups found.\"\n clearOnEscape\n renderInput={params => (\n <TextField\n {...params}\n name=\"add-users-and-groups\"\n variant=\"outlined\"\n label=\"Users and groups\"\n placeholder=\"Search by user name or group name\"\n error={!!selectedMembersError}\n helperText={selectedMembersError ?? ''}\n required\n />\n )}\n />\n <br />\n {membersData.error?.message && (\n <FormHelperText error={!!membersData.error}>\n {`Error fetching user and groups: ${membersData.error.message}`}\n </FormHelperText>\n )}\n </>\n );\n};\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ import React from 'react';
2
+ import { Table } from '@backstage/core-components';
3
+ import { makeStyles } from '@material-ui/core';
4
+ import { getMembers } from '../../utils/rbac-utils.esm.js';
5
+ import { selectedMembersColumns } from './AddedMembersTableColumn.esm.js';
6
+
7
+ const useStyles = makeStyles((theme) => ({
8
+ empty: {
9
+ padding: theme.spacing(2),
10
+ display: "flex",
11
+ justifyContent: "center"
12
+ }
13
+ }));
14
+ const AddedMembersTable = ({
15
+ selectedMembers,
16
+ setFieldValue
17
+ }) => {
18
+ const classes = useStyles();
19
+ return /* @__PURE__ */ React.createElement(
20
+ Table,
21
+ {
22
+ title: selectedMembers.length > 0 ? `Users and groups (${getMembers(selectedMembers)})` : "Users and groups",
23
+ data: selectedMembers,
24
+ columns: selectedMembersColumns(selectedMembers, setFieldValue),
25
+ emptyContent: /* @__PURE__ */ React.createElement("div", { className: classes.empty }, "No records. Selected users and groups appear here.")
26
+ }
27
+ );
28
+ };
29
+
30
+ export { AddedMembersTable };
31
+ //# sourceMappingURL=AddedMembersTable.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AddedMembersTable.esm.js","sources":["../../../src/components/CreateRole/AddedMembersTable.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 { Table } from '@backstage/core-components';\n\nimport { makeStyles } from '@material-ui/core';\nimport { FormikErrors } from 'formik';\n\nimport { getMembers } from '../../utils/rbac-utils';\nimport { selectedMembersColumns } from './AddedMembersTableColumn';\nimport { RoleFormValues, SelectedMember } from './types';\n\nconst useStyles = makeStyles(theme => ({\n empty: {\n padding: theme.spacing(2),\n display: 'flex',\n justifyContent: 'center',\n },\n}));\n\ntype AddedMembersTableProps = {\n selectedMembers: SelectedMember[];\n setFieldValue: (\n field: string,\n value: any,\n shouldValidate?: boolean,\n ) => Promise<FormikErrors<RoleFormValues>> | Promise<void>;\n};\n\nexport const AddedMembersTable = ({\n selectedMembers,\n setFieldValue,\n}: AddedMembersTableProps) => {\n const classes = useStyles();\n return (\n <Table\n title={\n selectedMembers.length > 0\n ? `Users and groups (${getMembers(selectedMembers)})`\n : 'Users and groups'\n }\n data={selectedMembers}\n columns={selectedMembersColumns(selectedMembers, setFieldValue)}\n emptyContent={\n <div className={classes.empty}>\n No records. Selected users and groups appear here.\n </div>\n }\n />\n );\n};\n"],"names":[],"mappings":";;;;;;AA0BA,MAAM,SAAA,GAAY,WAAW,CAAU,KAAA,MAAA;AAAA,EACrC,KAAO,EAAA;AAAA,IACL,OAAA,EAAS,KAAM,CAAA,OAAA,CAAQ,CAAC,CAAA;AAAA,IACxB,OAAS,EAAA,MAAA;AAAA,IACT,cAAgB,EAAA,QAAA;AAAA,GAClB;AACF,CAAE,CAAA,CAAA,CAAA;AAWK,MAAM,oBAAoB,CAAC;AAAA,EAChC,eAAA;AAAA,EACA,aAAA;AACF,CAA8B,KAAA;AAC5B,EAAA,MAAM,UAAU,SAAU,EAAA,CAAA;AAC1B,EACE,uBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,KAAA,EACE,gBAAgB,MAAS,GAAA,CAAA,GACrB,qBAAqB,UAAW,CAAA,eAAe,CAAC,CAChD,CAAA,CAAA,GAAA,kBAAA;AAAA,MAEN,IAAM,EAAA,eAAA;AAAA,MACN,OAAA,EAAS,sBAAuB,CAAA,eAAA,EAAiB,aAAa,CAAA;AAAA,MAC9D,8BACG,KAAA,CAAA,aAAA,CAAA,KAAA,EAAA,EAAI,SAAW,EAAA,OAAA,CAAQ,SAAO,oDAE/B,CAAA;AAAA,KAAA;AAAA,GAEJ,CAAA;AAEJ;;;;"}