@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,149 @@
1
+ import React from 'react';
2
+ import { IconButton } from '@material-ui/core';
3
+ import RemoveIcon from '@mui/icons-material/Remove';
4
+ import { isSimpleRule, getRowStyle, getRowKey, getSimpleRuleErrors, getNestedRuleErrors } from '../../utils/conditional-access-utils.esm.js';
5
+ import { ConditionsFormRowFields } from './ConditionsFormRowFields.esm.js';
6
+ import { criterias } from './const.esm.js';
7
+
8
+ const ComplexConditionRow = ({
9
+ conditionRow,
10
+ nestedConditionRow,
11
+ criteria,
12
+ onRuleChange,
13
+ updateRules,
14
+ setErrors,
15
+ setRemoveAllClicked,
16
+ conditionRulesData,
17
+ notConditionType,
18
+ classes,
19
+ currentCondition,
20
+ ruleIndex,
21
+ activeCriteria,
22
+ isNestedCondition = false,
23
+ nestedConditionIndex,
24
+ activeNestedCriteria
25
+ }) => {
26
+ const handleRemoveSimpleConditionRule = (index, ruleList2) => {
27
+ if (!activeCriteria) {
28
+ return;
29
+ }
30
+ const updatedSimpleRules = ruleList2.filter(
31
+ (_r, rindex) => index !== rindex
32
+ );
33
+ const nestedConditions = conditionRow[criteria]?.filter(
34
+ (con) => criterias.allOf in con || criterias.anyOf in con || criterias.not in con
35
+ ) || [];
36
+ onRuleChange({
37
+ [activeCriteria]: [
38
+ ...updatedSimpleRules,
39
+ ...nestedConditions
40
+ ]
41
+ });
42
+ setErrors((prevErrors) => {
43
+ const updatedErrors = { ...prevErrors };
44
+ if (updatedErrors[activeCriteria]) {
45
+ const criteriaErrors = updatedErrors[activeCriteria];
46
+ const simpleRuleErrors = getSimpleRuleErrors(criteriaErrors);
47
+ if (Array.isArray(simpleRuleErrors) && simpleRuleErrors.length > 0) {
48
+ const updatedCriteriaErrors = [
49
+ ...simpleRuleErrors.filter((_, rindex) => rindex !== index),
50
+ ...getNestedRuleErrors(criteriaErrors)
51
+ ];
52
+ updatedErrors[activeCriteria] = updatedCriteriaErrors.length > 0 ? updatedCriteriaErrors : [];
53
+ } else {
54
+ delete updatedErrors[activeCriteria];
55
+ }
56
+ }
57
+ return updatedErrors;
58
+ });
59
+ };
60
+ const handleRemoveNestedConditionRule = (nestedConditionCriteria) => {
61
+ const updatedNestedConditionRow = [];
62
+ nestedConditionRow.forEach((c, index) => {
63
+ if (index === nestedConditionIndex) {
64
+ const updatedRules = (c[nestedConditionCriteria] || []).filter((_r, rindex) => rindex !== ruleIndex);
65
+ updatedNestedConditionRow.push({
66
+ [nestedConditionCriteria]: updatedRules
67
+ });
68
+ } else {
69
+ updatedNestedConditionRow.push(c);
70
+ }
71
+ });
72
+ updateRules(
73
+ criteria === criterias.not ? updatedNestedConditionRow[0] : updatedNestedConditionRow
74
+ );
75
+ setErrors((prevErrors) => {
76
+ const updatedErrors = { ...prevErrors };
77
+ if (updatedErrors[criteria] !== void 0) {
78
+ const criteriaErrors = updatedErrors[criteria];
79
+ if (criteria === criterias.not && notConditionType === "nested-condition") {
80
+ updatedErrors[criteria][nestedConditionCriteria].splice(ruleIndex, 1);
81
+ return updatedErrors;
82
+ }
83
+ const nestedConditionErrors = getNestedRuleErrors(criteriaErrors);
84
+ if (Array.isArray(nestedConditionErrors) && nestedConditionIndex !== void 0) {
85
+ const nestedErrors = nestedConditionErrors[nestedConditionIndex];
86
+ if (nestedErrors[nestedConditionCriteria]) {
87
+ const updatedNestedErrors = nestedErrors[nestedConditionCriteria].filter((_error, index) => index !== ruleIndex);
88
+ if (updatedNestedErrors.length > 0) {
89
+ nestedErrors[nestedConditionCriteria] = updatedNestedErrors;
90
+ } else {
91
+ delete nestedErrors[nestedConditionCriteria];
92
+ }
93
+ nestedConditionErrors[nestedConditionIndex] = nestedErrors;
94
+ }
95
+ updatedErrors[criteria] = [
96
+ ...getSimpleRuleErrors(criteriaErrors),
97
+ ...nestedConditionErrors
98
+ ];
99
+ }
100
+ }
101
+ return updatedErrors;
102
+ });
103
+ };
104
+ const ruleList = isNestedCondition ? currentCondition[activeCriteria] : conditionRow[activeCriteria].filter(
105
+ (r) => isSimpleRule(r)
106
+ );
107
+ const disabled = !isNestedCondition && conditionRow[criteria].length === 1 && nestedConditionRow.length === 0 && ruleIndex === 0;
108
+ const nestedDisabled = isNestedCondition && nestedConditionRow[nestedConditionIndex ?? 0][activeNestedCriteria].length === 1 && ruleIndex === 0;
109
+ return currentCondition.resourceType && /* @__PURE__ */ React.createElement(
110
+ "div",
111
+ {
112
+ style: getRowStyle(currentCondition, isNestedCondition),
113
+ key: getRowKey(isNestedCondition, ruleIndex)
114
+ },
115
+ /* @__PURE__ */ React.createElement(
116
+ ConditionsFormRowFields,
117
+ {
118
+ oldCondition: currentCondition,
119
+ index: isNestedCondition ? void 0 : ruleIndex,
120
+ onRuleChange,
121
+ conditionRow,
122
+ criteria,
123
+ conditionRulesData,
124
+ setErrors,
125
+ setRemoveAllClicked,
126
+ nestedConditionRow: isNestedCondition ? nestedConditionRow : void 0,
127
+ nestedConditionCriteria: isNestedCondition ? activeNestedCriteria : void 0,
128
+ nestedConditionIndex: isNestedCondition ? nestedConditionIndex : void 0,
129
+ nestedConditionRuleIndex: isNestedCondition ? ruleIndex : void 0,
130
+ updateRules: isNestedCondition ? updateRules : void 0
131
+ }
132
+ ),
133
+ /* @__PURE__ */ React.createElement(
134
+ IconButton,
135
+ {
136
+ title: "Remove",
137
+ className: classes.removeRuleButton,
138
+ disabled: isNestedCondition ? nestedDisabled : disabled,
139
+ onClick: isNestedCondition && activeNestedCriteria && nestedConditionIndex !== void 0 ? () => handleRemoveNestedConditionRule(activeNestedCriteria) : () => {
140
+ handleRemoveSimpleConditionRule(ruleIndex, ruleList);
141
+ }
142
+ },
143
+ /* @__PURE__ */ React.createElement(RemoveIcon, null)
144
+ )
145
+ );
146
+ };
147
+
148
+ export { ComplexConditionRow };
149
+ //# sourceMappingURL=ComplexConditionRow.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ComplexConditionRow.esm.js","sources":["../../../src/components/ConditionalAccess/ComplexConditionRow.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 { IconButton } from '@material-ui/core';\nimport RemoveIcon from '@mui/icons-material/Remove';\n\nimport {\n getNestedRuleErrors,\n getRowKey,\n getRowStyle,\n getSimpleRuleErrors,\n isSimpleRule,\n} from '../../utils/conditional-access-utils';\nimport { ConditionsFormRowFields } from './ConditionsFormRowFields';\nimport { criterias } from './const';\nimport {\n AccessConditionsErrors,\n ComplexErrors,\n Condition,\n ConditionsData,\n NestedCriteriaErrors,\n NotConditionType,\n RulesData,\n} from './types';\n\ntype ComplexConditionRowProps = {\n conditionRow: ConditionsData;\n nestedConditionRow: Condition[];\n criteria: keyof ConditionsData;\n onRuleChange: (newCondition: ConditionsData) => void;\n updateRules: (updatedNestedConditionRow: Condition[] | Condition) => void;\n setErrors: React.Dispatch<\n React.SetStateAction<AccessConditionsErrors | undefined>\n >;\n setRemoveAllClicked: React.Dispatch<React.SetStateAction<boolean>>;\n conditionRulesData?: RulesData;\n notConditionType?: NotConditionType;\n classes: any;\n currentCondition: Condition;\n ruleIndex: number;\n activeCriteria?: 'allOf' | 'anyOf';\n isNestedCondition?: boolean;\n nestedConditionIndex?: number;\n activeNestedCriteria?: 'allOf' | 'anyOf';\n};\n\nexport const ComplexConditionRow = ({\n conditionRow,\n nestedConditionRow,\n criteria,\n onRuleChange,\n updateRules,\n setErrors,\n setRemoveAllClicked,\n conditionRulesData,\n notConditionType,\n classes,\n currentCondition,\n ruleIndex,\n activeCriteria,\n isNestedCondition = false,\n nestedConditionIndex,\n activeNestedCriteria,\n}: ComplexConditionRowProps) => {\n const handleRemoveSimpleConditionRule = (\n index: number,\n ruleList: PermissionCondition[],\n ) => {\n if (!activeCriteria) {\n return;\n }\n const updatedSimpleRules = ruleList.filter(\n (_r, rindex) => index !== rindex,\n );\n const nestedConditions =\n (conditionRow[criteria] as PermissionCondition[])?.filter(\n (con: PermissionCondition) =>\n criterias.allOf in con ||\n criterias.anyOf in con ||\n criterias.not in con,\n ) || [];\n\n onRuleChange({\n [activeCriteria as keyof ConditionsData]: [\n ...updatedSimpleRules,\n ...nestedConditions,\n ],\n });\n\n setErrors(prevErrors => {\n const updatedErrors = { ...prevErrors };\n\n if (updatedErrors[activeCriteria]) {\n const criteriaErrors = updatedErrors[activeCriteria] as ComplexErrors[];\n const simpleRuleErrors = getSimpleRuleErrors(criteriaErrors);\n\n if (Array.isArray(simpleRuleErrors) && simpleRuleErrors.length > 0) {\n const updatedCriteriaErrors = [\n ...simpleRuleErrors.filter((_, rindex) => rindex !== index),\n ...getNestedRuleErrors(criteriaErrors),\n ];\n\n updatedErrors[activeCriteria] =\n updatedCriteriaErrors.length > 0 ? updatedCriteriaErrors : [];\n } else {\n delete updatedErrors[activeCriteria];\n }\n }\n\n return updatedErrors;\n });\n };\n\n const handleRemoveNestedConditionRule = (nestedConditionCriteria: string) => {\n const updatedNestedConditionRow: Condition[] = [];\n\n nestedConditionRow.forEach((c, index) => {\n if (index === nestedConditionIndex) {\n const updatedRules = (\n (c[\n nestedConditionCriteria as keyof Condition\n ] as PermissionCondition[]) || []\n ).filter((_r, rindex) => rindex !== ruleIndex);\n updatedNestedConditionRow.push({\n [nestedConditionCriteria as keyof Condition]: updatedRules,\n });\n } else {\n updatedNestedConditionRow.push(c);\n }\n });\n\n updateRules(\n criteria === criterias.not\n ? updatedNestedConditionRow[0]\n : updatedNestedConditionRow,\n );\n\n setErrors(prevErrors => {\n const updatedErrors = { ...prevErrors };\n\n if (updatedErrors[criteria] !== undefined) {\n const criteriaErrors = updatedErrors[criteria] as ComplexErrors[];\n\n if (\n criteria === criterias.not &&\n notConditionType === 'nested-condition'\n ) {\n (\n (updatedErrors[criteria] as NestedCriteriaErrors)[\n nestedConditionCriteria\n ] as string[]\n ).splice(ruleIndex, 1);\n return updatedErrors;\n }\n\n const nestedConditionErrors = getNestedRuleErrors(criteriaErrors);\n\n if (\n Array.isArray(nestedConditionErrors) &&\n nestedConditionIndex !== undefined\n ) {\n const nestedErrors = nestedConditionErrors[nestedConditionIndex];\n if (nestedErrors[nestedConditionCriteria]) {\n const updatedNestedErrors = (\n nestedErrors[nestedConditionCriteria] as string[]\n ).filter((_error, index) => index !== ruleIndex);\n\n if (updatedNestedErrors.length > 0) {\n nestedErrors[nestedConditionCriteria] = updatedNestedErrors;\n } else {\n delete nestedErrors[nestedConditionCriteria];\n }\n\n nestedConditionErrors[nestedConditionIndex] = nestedErrors;\n }\n\n updatedErrors[criteria] = [\n ...getSimpleRuleErrors(criteriaErrors),\n ...nestedConditionErrors,\n ];\n }\n }\n\n return updatedErrors;\n });\n };\n\n const ruleList = isNestedCondition\n ? (currentCondition[\n activeCriteria as keyof Condition\n ] as PermissionCondition[])\n : ((conditionRow[activeCriteria as keyof Condition] as Condition[]).filter(\n r => isSimpleRule(r),\n ) as PermissionCondition[]);\n\n const disabled =\n !isNestedCondition &&\n (conditionRow[criteria as keyof Condition] as Condition[]).length === 1 &&\n nestedConditionRow.length === 0 &&\n ruleIndex === 0;\n const nestedDisabled =\n isNestedCondition &&\n (\n nestedConditionRow[nestedConditionIndex ?? 0][\n activeNestedCriteria as keyof Condition\n ] as Condition[]\n ).length === 1 &&\n ruleIndex === 0;\n\n return (\n (currentCondition as PermissionCondition).resourceType && (\n <div\n style={getRowStyle(currentCondition, isNestedCondition)}\n key={getRowKey(isNestedCondition, ruleIndex)}\n >\n <ConditionsFormRowFields\n oldCondition={currentCondition}\n index={isNestedCondition ? undefined : ruleIndex}\n onRuleChange={onRuleChange}\n conditionRow={conditionRow}\n criteria={criteria}\n conditionRulesData={conditionRulesData}\n setErrors={setErrors}\n setRemoveAllClicked={setRemoveAllClicked}\n nestedConditionRow={\n isNestedCondition ? nestedConditionRow : undefined\n }\n nestedConditionCriteria={\n isNestedCondition ? activeNestedCriteria : undefined\n }\n nestedConditionIndex={\n isNestedCondition ? nestedConditionIndex : undefined\n }\n nestedConditionRuleIndex={isNestedCondition ? ruleIndex : undefined}\n updateRules={isNestedCondition ? updateRules : undefined}\n />\n <IconButton\n title=\"Remove\"\n className={classes.removeRuleButton}\n disabled={isNestedCondition ? nestedDisabled : disabled}\n onClick={\n isNestedCondition &&\n activeNestedCriteria &&\n nestedConditionIndex !== undefined\n ? () => handleRemoveNestedConditionRule(activeNestedCriteria)\n : () => {\n handleRemoveSimpleConditionRule(ruleIndex, ruleList);\n }\n }\n >\n <RemoveIcon />\n </IconButton>\n </div>\n )\n );\n};\n"],"names":["ruleList"],"mappings":"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"}
@@ -0,0 +1,62 @@
1
+ import React from 'react';
2
+ import AddIcon from '@mui/icons-material/Add';
3
+ import Box from '@mui/material/Box';
4
+ import Button from '@mui/material/Button';
5
+ import { getDefaultRule } from '../../utils/conditional-access-utils.esm.js';
6
+ import { AddNestedConditionButton } from './AddNestedConditionButton.esm.js';
7
+ import { criterias } from './const.esm.js';
8
+
9
+ const ComplexConditionRowButtons = ({
10
+ conditionRow,
11
+ onRuleChange,
12
+ criteria,
13
+ classes,
14
+ selPluginResourceType,
15
+ updateErrors,
16
+ isNestedConditionRule,
17
+ handleAddNestedCondition
18
+ }) => {
19
+ const findFirstNestedConditionIndex = (rules) => {
20
+ return rules.findIndex((e) => isNestedConditionRule(e)) || 0;
21
+ };
22
+ const handleAddRule = () => {
23
+ const updatedRules = [
24
+ ...conditionRow.allOf ?? [],
25
+ ...conditionRow.anyOf ?? []
26
+ ];
27
+ const firstNestedConditionIndex = findFirstNestedConditionIndex(updatedRules);
28
+ if (firstNestedConditionIndex !== -1) {
29
+ updatedRules.splice(
30
+ firstNestedConditionIndex,
31
+ 0,
32
+ getDefaultRule(selPluginResourceType)
33
+ );
34
+ } else {
35
+ updatedRules.push(getDefaultRule(selPluginResourceType));
36
+ }
37
+ onRuleChange({ [criteria]: [...updatedRules] });
38
+ updateErrors(firstNestedConditionIndex);
39
+ };
40
+ return (criteria === criterias.allOf || criteria === criterias.anyOf) && /* @__PURE__ */ React.createElement(Box, { mt: 1, mb: 1 }, /* @__PURE__ */ React.createElement(
41
+ Button,
42
+ {
43
+ className: classes.addRuleButton,
44
+ size: "small",
45
+ onClick: handleAddRule
46
+ },
47
+ /* @__PURE__ */ React.createElement(AddIcon, { fontSize: "small" }),
48
+ "Add rule"
49
+ ), /* @__PURE__ */ React.createElement(
50
+ Button,
51
+ {
52
+ className: classes.addNestedConditionButton,
53
+ size: "small",
54
+ onClick: () => handleAddNestedCondition(criteria)
55
+ },
56
+ /* @__PURE__ */ React.createElement(AddIcon, { fontSize: "small" }),
57
+ /* @__PURE__ */ React.createElement(AddNestedConditionButton, null)
58
+ ));
59
+ };
60
+
61
+ export { ComplexConditionRowButtons };
62
+ //# sourceMappingURL=ComplexConditionRowButtons.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ComplexConditionRowButtons.esm.js","sources":["../../../src/components/ConditionalAccess/ComplexConditionRowButtons.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 AddIcon from '@mui/icons-material/Add';\nimport Box from '@mui/material/Box';\nimport Button from '@mui/material/Button';\n\nimport { getDefaultRule } from '../../utils/conditional-access-utils';\nimport { AddNestedConditionButton } from './AddNestedConditionButton';\nimport { criterias } from './const';\nimport { Condition, ConditionsData } from './types';\n\ntype ComplexConditionRowButtonsProps = {\n conditionRow: ConditionsData;\n onRuleChange: (newCondition: ConditionsData) => void;\n criteria: string;\n classes: any;\n selPluginResourceType: string;\n updateErrors: (_index: number) => void;\n isNestedConditionRule: (condition: Condition) => boolean;\n handleAddNestedCondition: (criteria: string) => void;\n};\n\nexport const ComplexConditionRowButtons = ({\n conditionRow,\n onRuleChange,\n criteria,\n classes,\n selPluginResourceType,\n updateErrors,\n isNestedConditionRule,\n handleAddNestedCondition,\n}: ComplexConditionRowButtonsProps) => {\n const findFirstNestedConditionIndex = (rules: Condition[]): number => {\n return rules.findIndex(e => isNestedConditionRule(e)) || 0;\n };\n const handleAddRule = () => {\n const updatedRules = [\n ...(conditionRow.allOf ?? []),\n ...(conditionRow.anyOf ?? []),\n ];\n\n const firstNestedConditionIndex =\n findFirstNestedConditionIndex(updatedRules);\n if (firstNestedConditionIndex !== -1) {\n updatedRules.splice(\n firstNestedConditionIndex,\n 0,\n getDefaultRule(selPluginResourceType),\n );\n } else {\n updatedRules.push(getDefaultRule(selPluginResourceType));\n }\n\n onRuleChange({ [criteria]: [...updatedRules] });\n updateErrors(firstNestedConditionIndex);\n };\n\n return (\n (criteria === criterias.allOf || criteria === criterias.anyOf) && (\n <Box mt={1} mb={1}>\n <Button\n className={classes.addRuleButton}\n size=\"small\"\n onClick={handleAddRule}\n >\n <AddIcon fontSize=\"small\" />\n Add rule\n </Button>\n <Button\n className={classes.addNestedConditionButton}\n size=\"small\"\n onClick={() => handleAddNestedCondition(criteria)}\n >\n <AddIcon fontSize=\"small\" />\n <AddNestedConditionButton />\n </Button>\n </Box>\n )\n );\n};\n"],"names":[],"mappings":";;;;;;;;AAqCO,MAAM,6BAA6B,CAAC;AAAA,EACzC,YAAA;AAAA,EACA,YAAA;AAAA,EACA,QAAA;AAAA,EACA,OAAA;AAAA,EACA,qBAAA;AAAA,EACA,YAAA;AAAA,EACA,qBAAA;AAAA,EACA,wBAAA;AACF,CAAuC,KAAA;AACrC,EAAM,MAAA,6BAAA,GAAgC,CAAC,KAA+B,KAAA;AACpE,IAAA,OAAO,MAAM,SAAU,CAAA,CAAA,CAAA,KAAK,qBAAsB,CAAA,CAAC,CAAC,CAAK,IAAA,CAAA,CAAA;AAAA,GAC3D,CAAA;AACA,EAAA,MAAM,gBAAgB,MAAM;AAC1B,IAAA,MAAM,YAAe,GAAA;AAAA,MACnB,GAAI,YAAa,CAAA,KAAA,IAAS,EAAC;AAAA,MAC3B,GAAI,YAAa,CAAA,KAAA,IAAS,EAAC;AAAA,KAC7B,CAAA;AAEA,IAAM,MAAA,yBAAA,GACJ,8BAA8B,YAAY,CAAA,CAAA;AAC5C,IAAA,IAAI,8BAA8B,CAAI,CAAA,EAAA;AACpC,MAAa,YAAA,CAAA,MAAA;AAAA,QACX,yBAAA;AAAA,QACA,CAAA;AAAA,QACA,eAAe,qBAAqB,CAAA;AAAA,OACtC,CAAA;AAAA,KACK,MAAA;AACL,MAAa,YAAA,CAAA,IAAA,CAAK,cAAe,CAAA,qBAAqB,CAAC,CAAA,CAAA;AAAA,KACzD;AAEA,IAAa,YAAA,CAAA,EAAE,CAAC,QAAQ,GAAG,CAAC,GAAG,YAAY,GAAG,CAAA,CAAA;AAC9C,IAAA,YAAA,CAAa,yBAAyB,CAAA,CAAA;AAAA,GACxC,CAAA;AAEA,EACG,OAAA,CAAA,QAAA,KAAa,SAAU,CAAA,KAAA,IAAS,QAAa,KAAA,SAAA,CAAU,KACtD,qBAAA,KAAA,CAAA,aAAA,CAAC,GAAI,EAAA,EAAA,EAAA,EAAI,CAAG,EAAA,EAAA,EAAI,CACd,EAAA,kBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,WAAW,OAAQ,CAAA,aAAA;AAAA,MACnB,IAAK,EAAA,OAAA;AAAA,MACL,OAAS,EAAA,aAAA;AAAA,KAAA;AAAA,oBAET,KAAA,CAAA,aAAA,CAAC,OAAQ,EAAA,EAAA,QAAA,EAAS,OAAQ,EAAA,CAAA;AAAA,IAAE,UAAA;AAAA,GAG9B,kBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,WAAW,OAAQ,CAAA,wBAAA;AAAA,MACnB,IAAK,EAAA,OAAA;AAAA,MACL,OAAA,EAAS,MAAM,wBAAA,CAAyB,QAAQ,CAAA;AAAA,KAAA;AAAA,oBAEhD,KAAA,CAAA,aAAA,CAAC,OAAQ,EAAA,EAAA,QAAA,EAAS,OAAQ,EAAA,CAAA;AAAA,wCACzB,wBAAyB,EAAA,IAAA,CAAA;AAAA,GAE9B,CAAA,CAAA;AAGN;;;;"}
@@ -0,0 +1,34 @@
1
+ import React from 'react';
2
+ import { getDefaultRule, ruleOptionDisabled } from '../../utils/conditional-access-utils.esm.js';
3
+ import { ConditionsFormRowFields } from './ConditionsFormRowFields.esm.js';
4
+ import { criterias } from './const.esm.js';
5
+
6
+ const ConditionRule = ({
7
+ conditionRow,
8
+ selPluginResourceType,
9
+ onRuleChange,
10
+ criteria,
11
+ conditionRulesData,
12
+ setErrors,
13
+ setRemoveAllClicked
14
+ }) => {
15
+ return criteria === criterias.condition && /* @__PURE__ */ React.createElement(
16
+ ConditionsFormRowFields,
17
+ {
18
+ oldCondition: conditionRow.condition ?? getDefaultRule(selPluginResourceType),
19
+ onRuleChange,
20
+ conditionRow,
21
+ criteria,
22
+ conditionRulesData,
23
+ setErrors,
24
+ optionDisabled: (ruleOption) => ruleOptionDisabled(
25
+ ruleOption,
26
+ conditionRow.condition ? [conditionRow.condition] : void 0
27
+ ),
28
+ setRemoveAllClicked
29
+ }
30
+ );
31
+ };
32
+
33
+ export { ConditionRule };
34
+ //# sourceMappingURL=ConditionRule.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConditionRule.esm.js","sources":["../../../src/components/ConditionalAccess/ConditionRule.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 {\n getDefaultRule,\n ruleOptionDisabled,\n} from '../../utils/conditional-access-utils';\nimport { ConditionsFormRowFields } from './ConditionsFormRowFields';\nimport { criterias } from './const';\nimport { AccessConditionsErrors, ConditionsData, RulesData } from './types';\n\ntype ConditionRuleProps = {\n conditionRow: ConditionsData;\n selPluginResourceType: string;\n onRuleChange: (newCondition: ConditionsData) => void;\n criteria: string;\n conditionRulesData?: RulesData;\n setErrors: React.Dispatch<\n React.SetStateAction<AccessConditionsErrors | undefined>\n >;\n setRemoveAllClicked: React.Dispatch<React.SetStateAction<boolean>>;\n};\n\nexport const ConditionRule = ({\n conditionRow,\n selPluginResourceType,\n onRuleChange,\n criteria,\n conditionRulesData,\n setErrors,\n setRemoveAllClicked,\n}: ConditionRuleProps) => {\n return (\n criteria === criterias.condition && (\n <ConditionsFormRowFields\n oldCondition={\n conditionRow.condition ?? getDefaultRule(selPluginResourceType)\n }\n onRuleChange={onRuleChange}\n conditionRow={conditionRow}\n criteria={criteria}\n conditionRulesData={conditionRulesData}\n setErrors={setErrors}\n optionDisabled={ruleOption =>\n ruleOptionDisabled(\n ruleOption,\n conditionRow.condition ? [conditionRow.condition] : undefined,\n )\n }\n setRemoveAllClicked={setRemoveAllClicked}\n />\n )\n );\n};\n"],"names":[],"mappings":";;;;;AAqCO,MAAM,gBAAgB,CAAC;AAAA,EAC5B,YAAA;AAAA,EACA,qBAAA;AAAA,EACA,YAAA;AAAA,EACA,QAAA;AAAA,EACA,kBAAA;AAAA,EACA,SAAA;AAAA,EACA,mBAAA;AACF,CAA0B,KAAA;AACxB,EACE,OAAA,QAAA,KAAa,UAAU,SACrB,oBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,uBAAA;AAAA,IAAA;AAAA,MACC,YACE,EAAA,YAAA,CAAa,SAAa,IAAA,cAAA,CAAe,qBAAqB,CAAA;AAAA,MAEhE,YAAA;AAAA,MACA,YAAA;AAAA,MACA,QAAA;AAAA,MACA,kBAAA;AAAA,MACA,SAAA;AAAA,MACA,gBAAgB,CACd,UAAA,KAAA,kBAAA;AAAA,QACE,UAAA;AAAA,QACA,YAAa,CAAA,SAAA,GAAY,CAAC,YAAA,CAAa,SAAS,CAAI,GAAA,KAAA,CAAA;AAAA,OACtD;AAAA,MAEF,mBAAA;AAAA,KAAA;AAAA,GACF,CAAA;AAGN;;;;"}
@@ -0,0 +1,93 @@
1
+ import React from 'react';
2
+ import { makeStyles } from '@material-ui/core';
3
+ import Drawer from '@material-ui/core/Drawer';
4
+ import CloseIcon from '@mui/icons-material/Close';
5
+ import Box from '@mui/material/Box';
6
+ import IconButton from '@mui/material/IconButton';
7
+ import Typography from '@mui/material/Typography';
8
+ import { ConditionsForm } from './ConditionsForm.esm.js';
9
+
10
+ const useDrawerStyles = makeStyles(() => ({
11
+ paper: {
12
+ ["@media (max-width: 960px)"]: {
13
+ width: "-webkit-fill-available"
14
+ },
15
+ width: "50vw",
16
+ height: "100vh",
17
+ gap: "3%",
18
+ display: "-webkit-inline-box"
19
+ }
20
+ }));
21
+ const useDrawerContentStyles = makeStyles((theme) => ({
22
+ sidebar: {
23
+ display: "flex",
24
+ flexFlow: "column",
25
+ justifyContent: "space-between",
26
+ backgroundColor: `${theme.palette.background.default} !important`
27
+ },
28
+ header: {
29
+ display: "flex",
30
+ flexDirection: "row",
31
+ justifyContent: "space-between",
32
+ alignItems: "baseline",
33
+ padding: theme.spacing(2.5),
34
+ fontFamily: theme.typography.fontFamily
35
+ },
36
+ headerSubtitle: {
37
+ fontWeight: 400,
38
+ fontFamily: theme.typography.fontFamily,
39
+ paddingTop: theme.spacing(1)
40
+ }
41
+ }));
42
+ const ConditionalAccessSidebar = ({
43
+ open,
44
+ onClose,
45
+ onSave,
46
+ selPluginResourceType,
47
+ conditionRulesData,
48
+ conditionsFormVal
49
+ }) => {
50
+ const classes = useDrawerStyles();
51
+ const contentClasses = useDrawerContentStyles();
52
+ return /* @__PURE__ */ React.createElement(
53
+ Drawer,
54
+ {
55
+ anchor: "right",
56
+ open,
57
+ "data-testid": "rules-sidebar",
58
+ classes: {
59
+ paper: classes.paper
60
+ }
61
+ },
62
+ /* @__PURE__ */ React.createElement(Box, { className: contentClasses.sidebar }, /* @__PURE__ */ React.createElement(Box, { className: contentClasses.header }, /* @__PURE__ */ React.createElement(Typography, { variant: "h5" }, /* @__PURE__ */ React.createElement(Typography, { component: "span", sx: { fontWeight: 500 } }, "Configure access for the"), " ", selPluginResourceType, /* @__PURE__ */ React.createElement(
63
+ Typography,
64
+ {
65
+ variant: "body2",
66
+ className: contentClasses.headerSubtitle,
67
+ align: "left"
68
+ },
69
+ "By default, the selected resource type will be visible to the chosen users in step two. If you want to restrict or grant permission to specific plugin resource type rule, select it and add the required parameters."
70
+ )), /* @__PURE__ */ React.createElement(
71
+ IconButton,
72
+ {
73
+ key: "dismiss",
74
+ title: "Close the drawer",
75
+ onClick: onClose,
76
+ color: "inherit"
77
+ },
78
+ /* @__PURE__ */ React.createElement(CloseIcon, { fontSize: "small" })
79
+ )), /* @__PURE__ */ React.createElement(
80
+ ConditionsForm,
81
+ {
82
+ conditionRulesData,
83
+ selPluginResourceType,
84
+ conditionsFormVal,
85
+ onClose,
86
+ onSave
87
+ }
88
+ ))
89
+ );
90
+ };
91
+
92
+ export { ConditionalAccessSidebar };
93
+ //# sourceMappingURL=ConditionalAccessSidebar.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConditionalAccessSidebar.esm.js","sources":["../../../src/components/ConditionalAccess/ConditionalAccessSidebar.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 } from '@material-ui/core';\nimport Drawer from '@material-ui/core/Drawer';\nimport CloseIcon from '@mui/icons-material/Close';\nimport Box from '@mui/material/Box';\nimport IconButton from '@mui/material/IconButton';\nimport Typography from '@mui/material/Typography';\n\nimport { ConditionsForm } from './ConditionsForm';\nimport { ConditionsData, RulesData } from './types';\n\nconst useDrawerStyles = makeStyles(() => ({\n paper: {\n ['@media (max-width: 960px)']: {\n width: '-webkit-fill-available',\n },\n width: '50vw',\n height: '100vh',\n gap: '3%',\n display: '-webkit-inline-box',\n },\n}));\n\nconst useDrawerContentStyles = makeStyles(theme => ({\n sidebar: {\n display: 'flex',\n flexFlow: 'column',\n justifyContent: 'space-between',\n backgroundColor: `${theme.palette.background.default} !important`,\n },\n header: {\n display: 'flex',\n flexDirection: 'row',\n justifyContent: 'space-between',\n alignItems: 'baseline',\n padding: theme.spacing(2.5),\n fontFamily: theme.typography.fontFamily,\n },\n headerSubtitle: {\n fontWeight: 400,\n fontFamily: theme.typography.fontFamily,\n paddingTop: theme.spacing(1),\n },\n}));\n\ntype ConditionalAccessSidebarProps = {\n open: boolean;\n onClose: () => void;\n onSave: (conditions?: ConditionsData) => void;\n selPluginResourceType: string;\n conditionRulesData?: RulesData;\n conditionsFormVal?: ConditionsData;\n};\n\nexport const ConditionalAccessSidebar = ({\n open,\n onClose,\n onSave,\n selPluginResourceType,\n conditionRulesData,\n conditionsFormVal,\n}: ConditionalAccessSidebarProps) => {\n const classes = useDrawerStyles();\n const contentClasses = useDrawerContentStyles();\n return (\n <Drawer\n anchor=\"right\"\n open={open}\n data-testid=\"rules-sidebar\"\n classes={{\n paper: classes.paper,\n }}\n >\n <Box className={contentClasses.sidebar}>\n <Box className={contentClasses.header}>\n <Typography variant=\"h5\">\n <Typography component=\"span\" sx={{ fontWeight: 500 }}>\n Configure access for the\n </Typography>{' '}\n {selPluginResourceType}\n <Typography\n variant=\"body2\"\n className={contentClasses.headerSubtitle}\n align=\"left\"\n >\n By default, the selected resource type will be visible to the\n chosen users in step two. If you want to restrict or grant\n permission to specific plugin resource type rule, select it and\n add the required parameters.\n </Typography>\n </Typography>\n <IconButton\n key=\"dismiss\"\n title=\"Close the drawer\"\n onClick={onClose}\n color=\"inherit\"\n >\n <CloseIcon fontSize=\"small\" />\n </IconButton>\n </Box>\n <ConditionsForm\n conditionRulesData={conditionRulesData}\n selPluginResourceType={selPluginResourceType}\n conditionsFormVal={conditionsFormVal}\n onClose={onClose}\n onSave={onSave}\n />\n </Box>\n </Drawer>\n );\n};\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,204 @@
1
+ import React from 'react';
2
+ import { makeStyles, Box, Button } from '@material-ui/core';
3
+ import { Alert, AlertTitle } from '@material-ui/lab';
4
+ import WarningIcon from '@mui/icons-material/Warning';
5
+ import { initializeErrors, resetErrors, isSimpleRule, hasSimpleConditionOrNotErrors, hasNestedNotErrors, hasAllOfOrAnyOfErrors } from '../../utils/conditional-access-utils.esm.js';
6
+ import { ConditionsFormRow } from './ConditionsFormRow.esm.js';
7
+ import { criterias } from './const.esm.js';
8
+
9
+ const useStyles = makeStyles((theme) => ({
10
+ form: {
11
+ padding: theme.spacing(2.5),
12
+ paddingTop: 0,
13
+ flexGrow: 1,
14
+ overflow: "auto"
15
+ },
16
+ addConditionButton: {
17
+ color: theme.palette.primary.light
18
+ },
19
+ footer: {
20
+ display: "flex",
21
+ flexDirection: "row",
22
+ gap: "15px",
23
+ alignItems: "baseline",
24
+ borderTop: `2px solid ${theme.palette.border}`,
25
+ padding: theme.spacing(2.5),
26
+ "& button": {
27
+ textTransform: "none"
28
+ }
29
+ }
30
+ }));
31
+ const ConditionsForm = ({
32
+ conditionRulesData,
33
+ selPluginResourceType,
34
+ conditionsFormVal,
35
+ onClose,
36
+ onSave
37
+ }) => {
38
+ const classes = useStyles();
39
+ const [conditions, setConditions] = React.useState(
40
+ conditionsFormVal ?? {
41
+ condition: {
42
+ rule: "",
43
+ resourceType: selPluginResourceType,
44
+ params: {}
45
+ }
46
+ }
47
+ );
48
+ const [criteria, setCriteria] = React.useState(
49
+ Object.keys(conditions)[0] ?? criterias.condition
50
+ );
51
+ const [errors, setErrors] = React.useState(initializeErrors(criteria, conditions));
52
+ const [removeAllClicked, setRemoveAllClicked] = React.useState(false);
53
+ const flattenConditions = (conditionData) => {
54
+ const flatConditions = [];
55
+ const processCondition = (condition) => {
56
+ if ("rule" in condition) {
57
+ flatConditions.push(condition);
58
+ } else {
59
+ if (condition.allOf) {
60
+ condition.allOf.forEach(processCondition);
61
+ }
62
+ if (condition.anyOf) {
63
+ condition.anyOf.forEach(processCondition);
64
+ }
65
+ if (condition.not) {
66
+ if ("rule" in condition.not) {
67
+ flatConditions.push(condition.not);
68
+ } else {
69
+ processCondition(condition.not);
70
+ }
71
+ }
72
+ }
73
+ };
74
+ conditionData.forEach(processCondition);
75
+ return flatConditions;
76
+ };
77
+ const isNoRuleSelected = () => {
78
+ switch (criteria) {
79
+ case criterias.condition:
80
+ return !conditions.condition?.rule;
81
+ case criterias.not: {
82
+ const flatConditions = flattenConditions([
83
+ conditions.not
84
+ ]);
85
+ return flatConditions.some((c) => !c.rule);
86
+ }
87
+ case criterias.allOf: {
88
+ const flatConditions = flattenConditions(conditions.allOf || []);
89
+ return flatConditions.some((c) => !c.rule);
90
+ }
91
+ case criterias.anyOf: {
92
+ const flatConditions = flattenConditions(conditions.anyOf || []);
93
+ return flatConditions.some((c) => !c.rule);
94
+ }
95
+ default:
96
+ return true;
97
+ }
98
+ };
99
+ const hasAnyErrors = () => {
100
+ if (!errors) return false;
101
+ if (criteria === criterias.condition || criteria === criterias.not && isSimpleRule(conditions[criteria])) {
102
+ return hasSimpleConditionOrNotErrors(errors, criteria);
103
+ }
104
+ if (criteria === criterias.not && !isSimpleRule(conditions[criteria])) {
105
+ return hasNestedNotErrors(errors, conditions, criteria);
106
+ }
107
+ if (criteria === criterias.allOf || criteria === criterias.anyOf) {
108
+ return hasAllOfOrAnyOfErrors(errors, criteria);
109
+ }
110
+ return false;
111
+ };
112
+ const isSaveDisabled = () => {
113
+ if (removeAllClicked) return false;
114
+ return hasAnyErrors() || isNoRuleSelected() || Object.is(conditionsFormVal, conditions);
115
+ };
116
+ const hasMultiLevelNestedConditions = () => {
117
+ if (!Array.isArray(conditions[criteria])) {
118
+ return false;
119
+ }
120
+ return conditions[criteria].filter((condition) => !("rule" in condition)).some((firstLevelNestedCondition) => {
121
+ const nestedConditionCriteria = Object.keys(
122
+ firstLevelNestedCondition
123
+ )[0];
124
+ if (Array.isArray(
125
+ firstLevelNestedCondition[nestedConditionCriteria]
126
+ )) {
127
+ return firstLevelNestedCondition[nestedConditionCriteria].some((con) => !("rule" in con));
128
+ }
129
+ return !Object.keys(
130
+ firstLevelNestedCondition[nestedConditionCriteria]
131
+ ).includes("rule");
132
+ });
133
+ };
134
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Box, { className: classes.form }, /* @__PURE__ */ React.createElement(
135
+ ConditionsFormRow,
136
+ {
137
+ conditionRulesData,
138
+ conditionRow: conditions,
139
+ criteria,
140
+ selPluginResourceType,
141
+ onRuleChange: (newCondition) => setConditions(newCondition),
142
+ setCriteria,
143
+ setErrors,
144
+ setRemoveAllClicked
145
+ }
146
+ ), hasMultiLevelNestedConditions() && /* @__PURE__ */ React.createElement(
147
+ Alert,
148
+ {
149
+ icon: /* @__PURE__ */ React.createElement(WarningIcon, null),
150
+ style: { margin: "1.5rem 0 1rem 0" },
151
+ severity: "warning",
152
+ "data-testid": "multi-level-nested-conditions-warning"
153
+ },
154
+ /* @__PURE__ */ React.createElement(AlertTitle, { "data-testid": "multi-level-nested-conditions-warning-title" }, "Multiple levels of nested conditions are not supported"),
155
+ "Only one level is displayed. Please use the CLI to view all nested conditions."
156
+ )), /* @__PURE__ */ React.createElement(Box, { className: classes.footer }, /* @__PURE__ */ React.createElement(
157
+ Button,
158
+ {
159
+ variant: "contained",
160
+ color: "primary",
161
+ "data-testid": "save-conditions",
162
+ disabled: isSaveDisabled(),
163
+ onClick: () => {
164
+ if (removeAllClicked) {
165
+ onSave(void 0);
166
+ } else onSave(conditions);
167
+ }
168
+ },
169
+ "Save"
170
+ ), /* @__PURE__ */ React.createElement(
171
+ Button,
172
+ {
173
+ variant: "outlined",
174
+ color: "primary",
175
+ onClick: onClose,
176
+ "data-testid": "cancel-conditions"
177
+ },
178
+ "Cancel"
179
+ ), /* @__PURE__ */ React.createElement(
180
+ Button,
181
+ {
182
+ variant: "text",
183
+ color: "primary",
184
+ disabled: removeAllClicked || isNoRuleSelected(),
185
+ onClick: () => {
186
+ setRemoveAllClicked(true);
187
+ setCriteria(criterias.condition);
188
+ setConditions({
189
+ condition: {
190
+ rule: "",
191
+ resourceType: selPluginResourceType,
192
+ params: {}
193
+ }
194
+ });
195
+ setErrors(resetErrors(criterias.condition));
196
+ },
197
+ "data-testid": "remove-conditions"
198
+ },
199
+ "Remove all"
200
+ )));
201
+ };
202
+
203
+ export { ConditionsForm };
204
+ //# sourceMappingURL=ConditionsForm.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConditionsForm.esm.js","sources":["../../../src/components/ConditionalAccess/ConditionsForm.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, Button, makeStyles } from '@material-ui/core';\nimport { Alert, AlertTitle } from '@material-ui/lab';\nimport WarningIcon from '@mui/icons-material/Warning';\n\nimport {\n hasAllOfOrAnyOfErrors,\n hasNestedNotErrors,\n hasSimpleConditionOrNotErrors,\n initializeErrors,\n isSimpleRule,\n resetErrors,\n} from '../../utils/conditional-access-utils';\nimport { ConditionsFormRow } from './ConditionsFormRow';\nimport { criterias } from './const';\nimport {\n AccessConditionsErrors,\n Condition,\n ConditionsData,\n RulesData,\n} from './types';\n\nconst useStyles = makeStyles(theme => ({\n form: {\n padding: theme.spacing(2.5),\n paddingTop: 0,\n flexGrow: 1,\n overflow: 'auto',\n },\n addConditionButton: {\n color: theme.palette.primary.light,\n },\n footer: {\n display: 'flex',\n flexDirection: 'row',\n gap: '15px',\n alignItems: 'baseline',\n borderTop: `2px solid ${theme.palette.border}`,\n padding: theme.spacing(2.5),\n '& button': {\n textTransform: 'none',\n },\n },\n}));\n\ntype ConditionFormProps = {\n conditionRulesData?: RulesData;\n conditionsFormVal?: ConditionsData;\n selPluginResourceType: string;\n onClose: () => void;\n onSave: (conditions?: ConditionsData) => void;\n};\n\nexport const ConditionsForm = ({\n conditionRulesData,\n selPluginResourceType,\n conditionsFormVal,\n onClose,\n onSave,\n}: ConditionFormProps) => {\n const classes = useStyles();\n const [conditions, setConditions] = React.useState<ConditionsData>(\n conditionsFormVal ?? {\n condition: {\n rule: '',\n resourceType: selPluginResourceType,\n params: {},\n },\n },\n );\n const [criteria, setCriteria] = React.useState<keyof ConditionsData>(\n (Object.keys(conditions)[0] as keyof ConditionsData) ?? criterias.condition,\n );\n const [errors, setErrors] = React.useState<\n AccessConditionsErrors | undefined\n >(initializeErrors(criteria, conditions));\n\n const [removeAllClicked, setRemoveAllClicked] =\n React.useState<boolean>(false);\n\n const flattenConditions = (\n conditionData: Condition[],\n ): PermissionCondition[] => {\n const flatConditions: PermissionCondition[] = [];\n\n const processCondition = (condition: Condition) => {\n if ('rule' in condition) {\n flatConditions.push(condition);\n } else {\n if (condition.allOf) {\n condition.allOf.forEach(processCondition);\n }\n if (condition.anyOf) {\n condition.anyOf.forEach(processCondition);\n }\n if (condition.not) {\n if ('rule' in condition.not) {\n flatConditions.push(condition.not);\n } else {\n processCondition(condition.not);\n }\n }\n }\n };\n conditionData.forEach(processCondition);\n return flatConditions;\n };\n\n const isNoRuleSelected = () => {\n switch (criteria) {\n case criterias.condition:\n return !conditions.condition?.rule;\n case criterias.not: {\n const flatConditions = flattenConditions([\n conditions.not as PermissionCondition,\n ]);\n return flatConditions.some(c => !c.rule);\n }\n case criterias.allOf: {\n const flatConditions = flattenConditions(conditions.allOf || []);\n return flatConditions.some(c => !c.rule);\n }\n case criterias.anyOf: {\n const flatConditions = flattenConditions(conditions.anyOf || []);\n return flatConditions.some(c => !c.rule);\n }\n default:\n return true;\n }\n };\n\n const hasAnyErrors = (): boolean => {\n if (!errors) return false;\n\n if (\n criteria === criterias.condition ||\n (criteria === criterias.not &&\n isSimpleRule(conditions[criteria] as Condition))\n ) {\n return hasSimpleConditionOrNotErrors(errors, criteria);\n }\n\n if (\n criteria === criterias.not &&\n !isSimpleRule(conditions[criteria] as Condition)\n ) {\n return hasNestedNotErrors(errors, conditions, criteria);\n }\n\n if (criteria === criterias.allOf || criteria === criterias.anyOf) {\n return hasAllOfOrAnyOfErrors(errors, criteria);\n }\n\n return false;\n };\n\n const isSaveDisabled = () => {\n if (removeAllClicked) return false;\n\n return (\n hasAnyErrors() ||\n isNoRuleSelected() ||\n Object.is(conditionsFormVal, conditions)\n );\n };\n\n const hasMultiLevelNestedConditions = (): boolean => {\n if (!Array.isArray(conditions[criteria])) {\n return false;\n }\n\n return (conditions[criteria] as Condition[])\n .filter(condition => !('rule' in condition))\n .some((firstLevelNestedCondition: Condition) => {\n const nestedConditionCriteria = Object.keys(\n firstLevelNestedCondition,\n )[0];\n if (\n Array.isArray(\n firstLevelNestedCondition[\n nestedConditionCriteria as keyof Condition\n ],\n )\n ) {\n return (\n firstLevelNestedCondition[\n nestedConditionCriteria as keyof Condition\n ] as Condition[]\n ).some((con: Condition) => !('rule' in con));\n }\n\n return !Object.keys(\n firstLevelNestedCondition[\n nestedConditionCriteria as keyof Condition\n ] as Condition[],\n ).includes('rule');\n });\n };\n\n return (\n <>\n <Box className={classes.form}>\n <ConditionsFormRow\n conditionRulesData={conditionRulesData}\n conditionRow={conditions}\n criteria={criteria}\n selPluginResourceType={selPluginResourceType}\n onRuleChange={newCondition => setConditions(newCondition)}\n setCriteria={setCriteria}\n setErrors={setErrors}\n setRemoveAllClicked={setRemoveAllClicked}\n />\n {hasMultiLevelNestedConditions() && (\n <Alert\n icon={<WarningIcon />}\n style={{ margin: '1.5rem 0 1rem 0' }}\n severity=\"warning\"\n data-testid=\"multi-level-nested-conditions-warning\"\n >\n <AlertTitle data-testid=\"multi-level-nested-conditions-warning-title\">\n Multiple levels of nested conditions are not supported\n </AlertTitle>\n Only one level is displayed. Please use the CLI to view all nested\n conditions.\n </Alert>\n )}\n </Box>\n <Box className={classes.footer}>\n <Button\n variant=\"contained\"\n color=\"primary\"\n data-testid=\"save-conditions\"\n disabled={isSaveDisabled()}\n onClick={() => {\n if (removeAllClicked) {\n onSave(undefined);\n } else onSave(conditions);\n }}\n >\n Save\n </Button>\n <Button\n variant=\"outlined\"\n color=\"primary\"\n onClick={onClose}\n data-testid=\"cancel-conditions\"\n >\n Cancel\n </Button>\n <Button\n variant=\"text\"\n color=\"primary\"\n disabled={removeAllClicked || isNoRuleSelected()}\n onClick={() => {\n setRemoveAllClicked(true);\n setCriteria(criterias.condition);\n setConditions({\n condition: {\n rule: '',\n resourceType: selPluginResourceType,\n params: {},\n },\n });\n setErrors(resetErrors(criterias.condition));\n }}\n data-testid=\"remove-conditions\"\n >\n Remove all\n </Button>\n </Box>\n </>\n );\n};\n"],"names":[],"mappings":"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"}