@backstage-community/plugin-rbac 1.43.0 → 1.45.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (115) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/dist/alpha.d.ts +179 -0
  3. package/dist/alpha.esm.js +3 -0
  4. package/dist/alpha.esm.js.map +1 -0
  5. package/dist/components/ConditionalAccess/AddNestedConditionButton.esm.js +13 -9
  6. package/dist/components/ConditionalAccess/AddNestedConditionButton.esm.js.map +1 -1
  7. package/dist/components/ConditionalAccess/ComplexConditionRow.esm.js +3 -1
  8. package/dist/components/ConditionalAccess/ComplexConditionRow.esm.js.map +1 -1
  9. package/dist/components/ConditionalAccess/ComplexConditionRowButtons.esm.js +5 -3
  10. package/dist/components/ConditionalAccess/ComplexConditionRowButtons.esm.js.map +1 -1
  11. package/dist/components/ConditionalAccess/ConditionalAccessSidebar.esm.js +5 -3
  12. package/dist/components/ConditionalAccess/ConditionalAccessSidebar.esm.js.map +1 -1
  13. package/dist/components/ConditionalAccess/ConditionsFormRow.esm.js +7 -5
  14. package/dist/components/ConditionalAccess/ConditionsFormRow.esm.js.map +1 -1
  15. package/dist/components/ConditionalAccess/ConditionsFormRowFields.esm.js +4 -2
  16. package/dist/components/ConditionalAccess/ConditionsFormRowFields.esm.js.map +1 -1
  17. package/dist/components/ConditionalAccess/const.esm.js +6 -12
  18. package/dist/components/ConditionalAccess/const.esm.js.map +1 -1
  19. package/dist/components/CreateRole/AddMembersForm.esm.js +25 -19
  20. package/dist/components/CreateRole/AddMembersForm.esm.js.map +1 -1
  21. package/dist/components/CreateRole/AddedMembersTable.esm.js +10 -4
  22. package/dist/components/CreateRole/AddedMembersTable.esm.js.map +1 -1
  23. package/dist/components/CreateRole/AddedMembersTableColumn.esm.js +30 -28
  24. package/dist/components/CreateRole/AddedMembersTableColumn.esm.js.map +1 -1
  25. package/dist/components/CreateRole/CancelDialog.esm.js +8 -9
  26. package/dist/components/CreateRole/CancelDialog.esm.js.map +1 -1
  27. package/dist/components/CreateRole/CreateRolePage.esm.js +8 -6
  28. package/dist/components/CreateRole/CreateRolePage.esm.js.map +1 -1
  29. package/dist/components/CreateRole/EditRolePage.esm.js +9 -7
  30. package/dist/components/CreateRole/EditRolePage.esm.js.map +1 -1
  31. package/dist/components/CreateRole/PermissionPoliciesForm.esm.js +9 -3
  32. package/dist/components/CreateRole/PermissionPoliciesForm.esm.js.map +1 -1
  33. package/dist/components/CreateRole/PermissionPoliciesFormNestedRow.esm.js +6 -2
  34. package/dist/components/CreateRole/PermissionPoliciesFormNestedRow.esm.js.map +1 -1
  35. package/dist/components/CreateRole/PermissionPoliciesFormRow.esm.js +8 -4
  36. package/dist/components/CreateRole/PermissionPoliciesFormRow.esm.js.map +1 -1
  37. package/dist/components/CreateRole/PermissionPoliciesFormTable.esm.js +11 -6
  38. package/dist/components/CreateRole/PermissionPoliciesFormTable.esm.js.map +1 -1
  39. package/dist/components/CreateRole/PluginsDropdown.esm.js +4 -2
  40. package/dist/components/CreateRole/PluginsDropdown.esm.js.map +1 -1
  41. package/dist/components/CreateRole/ReviewStep.esm.js +9 -7
  42. package/dist/components/CreateRole/ReviewStep.esm.js.map +1 -1
  43. package/dist/components/CreateRole/RoleDetailsForm.esm.js +8 -6
  44. package/dist/components/CreateRole/RoleDetailsForm.esm.js.map +1 -1
  45. package/dist/components/CreateRole/RoleForm.esm.js +27 -23
  46. package/dist/components/CreateRole/RoleForm.esm.js.map +1 -1
  47. package/dist/components/CreateRole/SelectedPermissionPoliciesColumn.esm.js +24 -22
  48. package/dist/components/CreateRole/SelectedPermissionPoliciesColumn.esm.js.map +1 -1
  49. package/dist/components/DownloadUserStatistics.esm.js +4 -2
  50. package/dist/components/DownloadUserStatistics.esm.js.map +1 -1
  51. package/dist/components/EditRole.esm.js +4 -2
  52. package/dist/components/EditRole.esm.js.map +1 -1
  53. package/dist/components/RbacPage.esm.js +4 -2
  54. package/dist/components/RbacPage.esm.js.map +1 -1
  55. package/dist/components/RoleOverview/AboutCard.esm.js +12 -8
  56. package/dist/components/RoleOverview/AboutCard.esm.js.map +1 -1
  57. package/dist/components/RoleOverview/MembersCard.esm.js +18 -9
  58. package/dist/components/RoleOverview/MembersCard.esm.js.map +1 -1
  59. package/dist/components/RoleOverview/MembersListColumns.esm.js +42 -40
  60. package/dist/components/RoleOverview/MembersListColumns.esm.js.map +1 -1
  61. package/dist/components/RoleOverview/PermissionsCard.esm.js +27 -10
  62. package/dist/components/RoleOverview/PermissionsCard.esm.js.map +1 -1
  63. package/dist/components/RoleOverview/PermissionsListColumns.esm.js +38 -36
  64. package/dist/components/RoleOverview/PermissionsListColumns.esm.js.map +1 -1
  65. package/dist/components/RoleOverview/RoleOverviewPage.esm.js +3 -1
  66. package/dist/components/RoleOverview/RoleOverviewPage.esm.js.map +1 -1
  67. package/dist/components/RolesList/DeleteRole.esm.js +4 -2
  68. package/dist/components/RolesList/DeleteRole.esm.js.map +1 -1
  69. package/dist/components/RolesList/DeleteRoleDialog.esm.js +23 -38
  70. package/dist/components/RolesList/DeleteRoleDialog.esm.js.map +1 -1
  71. package/dist/components/RolesList/RolesList.esm.js +19 -9
  72. package/dist/components/RolesList/RolesList.esm.js.map +1 -1
  73. package/dist/components/RolesList/RolesListColumns.esm.js +63 -61
  74. package/dist/components/RolesList/RolesListColumns.esm.js.map +1 -1
  75. package/dist/components/RolesList/RolesListToolbar.esm.js +20 -10
  76. package/dist/components/RolesList/RolesListToolbar.esm.js.map +1 -1
  77. package/dist/components/Router.esm.js +4 -2
  78. package/dist/components/Router.esm.js.map +1 -1
  79. package/dist/components/Trans.esm.js +22 -0
  80. package/dist/components/Trans.esm.js.map +1 -0
  81. package/dist/hooks/useActionPermissionTooltip.esm.js +10 -5
  82. package/dist/hooks/useActionPermissionTooltip.esm.js.map +1 -1
  83. package/dist/hooks/useLanguage.esm.js +7 -0
  84. package/dist/hooks/useLanguage.esm.js.map +1 -0
  85. package/dist/hooks/useMembers.esm.js +16 -8
  86. package/dist/hooks/useMembers.esm.js.map +1 -1
  87. package/dist/hooks/usePermissionPolicies.esm.js +20 -9
  88. package/dist/hooks/usePermissionPolicies.esm.js.map +1 -1
  89. package/dist/hooks/useTranslation.esm.js +8 -0
  90. package/dist/hooks/useTranslation.esm.js.map +1 -0
  91. package/dist/translations/de.esm.js +176 -0
  92. package/dist/translations/de.esm.js.map +1 -0
  93. package/dist/translations/es.esm.js +176 -0
  94. package/dist/translations/es.esm.js.map +1 -0
  95. package/dist/translations/fr.esm.js +176 -0
  96. package/dist/translations/fr.esm.js.map +1 -0
  97. package/dist/translations/index.esm.js +15 -0
  98. package/dist/translations/index.esm.js.map +1 -0
  99. package/dist/translations/it.esm.js +176 -0
  100. package/dist/translations/it.esm.js.map +1 -0
  101. package/dist/translations/ref.esm.js +215 -0
  102. package/dist/translations/ref.esm.js.map +1 -0
  103. package/dist/utils/conditional-access-utils.esm.js +4 -4
  104. package/dist/utils/conditional-access-utils.esm.js.map +1 -1
  105. package/dist/utils/create-role-utils.esm.js +11 -11
  106. package/dist/utils/create-role-utils.esm.js.map +1 -1
  107. package/dist/utils/filter-table-data.esm.js +4 -3
  108. package/dist/utils/filter-table-data.esm.js.map +1 -1
  109. package/dist/utils/rbac-utils.esm.js +23 -19
  110. package/dist/utils/rbac-utils.esm.js.map +1 -1
  111. package/dist/utils/role-form-utils.esm.js +17 -12
  112. package/dist/utils/role-form-utils.esm.js.map +1 -1
  113. package/dist/utils/string-utils.esm.js +2 -2
  114. package/dist/utils/string-utils.esm.js.map +1 -1
  115. package/package.json +34 -20
@@ -12,8 +12,9 @@ import CardHeader from '@mui/material/CardHeader';
12
12
  import Divider from '@mui/material/Divider';
13
13
  import Paper from '@mui/material/Paper';
14
14
  import { useFormik } from 'formik';
15
+ import { useTranslation } from '../../hooks/useTranslation.esm.js';
15
16
  import { rbacApiRef } from '../../api/RBACBackendClient.esm.js';
16
- import { validationSchema, getRoleData, getPermissionPoliciesData, getNewConditionalPolicies, getRemovedConditionalPoliciesIds, getUpdatedConditionalPolicies, getConditionalPermissionPoliciesData } from '../../utils/create-role-utils.esm.js';
17
+ import { getValidationSchema, getRoleData, getPermissionPoliciesData, getNewConditionalPolicies, getRemovedConditionalPoliciesIds, getUpdatedConditionalPolicies, getConditionalPermissionPoliciesData } from '../../utils/create-role-utils.esm.js';
17
18
  import { onlyInLeft, isSamePermissionPolicy } from '../../utils/rbac-utils.esm.js';
18
19
  import { navigateTo, removePermissions, createPermissions, removeConditions, modifyConditions, createConditions } from '../../utils/role-form-utils.esm.js';
19
20
  import { AddedMembersTable } from './AddedMembersTable.esm.js';
@@ -35,6 +36,7 @@ const RoleForm = ({
35
36
  const [openCancelDialog, setOpenCancelDialog] = useState(false);
36
37
  const navigate = useNavigate();
37
38
  const rbacApi = useApi(rbacApiRef);
39
+ const { t } = useTranslation();
38
40
  const updateRole = async (values, formikHelpers) => {
39
41
  try {
40
42
  const newData = getRoleData(values);
@@ -53,7 +55,7 @@ const RoleForm = ({
53
55
  const res = await rbacApi.updateRole(oldData, newData);
54
56
  if (res.error) {
55
57
  throw new Error(
56
- `${"Unable to edit the role. "}${res.error.message}`
58
+ `${t("errors.editRole")} ${res.error.message}`
57
59
  );
58
60
  } else {
59
61
  const oldPermissionsData = getPermissionPoliciesData(initialValues);
@@ -67,12 +69,12 @@ const RoleForm = ({
67
69
  newPermissionsData,
68
70
  isSamePermissionPolicy
69
71
  );
70
- await removePermissions(newName, deletePermissions, rbacApi);
71
- await createPermissions(newPermissions, rbacApi);
72
- await removeConditions(deleteConditions, rbacApi);
73
- await modifyConditions(updateConditions, rbacApi);
74
- await createConditions(newConditions, rbacApi);
75
- navigateTo(navigate, roleName, newName, "updated", step);
72
+ await removePermissions(newName, deletePermissions, rbacApi, t);
73
+ await createPermissions(newPermissions, rbacApi, t);
74
+ await removeConditions(deleteConditions, rbacApi, t);
75
+ await modifyConditions(updateConditions, rbacApi, t);
76
+ await createConditions(newConditions, rbacApi, t);
77
+ navigateTo(navigate, t, roleName, newName, "updated", step);
76
78
  }
77
79
  } catch (e) {
78
80
  formikHelpers.setStatus({ submitError: e });
@@ -86,20 +88,22 @@ const RoleForm = ({
86
88
  const res = await rbacApi.createRole(newData);
87
89
  if (res.error) {
88
90
  throw new Error(
89
- `${"Unable to create role. "}${res.error.message}`
91
+ `${t("errors.createRole")} ${res.error.message}`
90
92
  );
91
93
  }
92
94
  await createPermissions(
93
95
  newPermissionsData,
94
96
  rbacApi,
95
- "Role was created successfully but unable to add permission policies to the role."
97
+ t,
98
+ t("errors.roleCreatedSuccess")
96
99
  );
97
100
  await createConditions(
98
101
  newConditionalPermissionPoliciesData,
99
102
  rbacApi,
100
- "Role created successfully but unable to add conditions to the role."
103
+ t,
104
+ t("errors.roleCreatedConditionsSuccess")
101
105
  );
102
- navigateTo(navigate, roleName, newData.name, "created", step);
106
+ navigateTo(navigate, t, roleName, newData.name, "created", step);
103
107
  } catch (e) {
104
108
  formikHelpers.setStatus({ submitError: e });
105
109
  }
@@ -107,7 +111,7 @@ const RoleForm = ({
107
111
  const formik = useFormik({
108
112
  enableReinitialize: true,
109
113
  initialValues,
110
- validationSchema,
114
+ validationSchema: getValidationSchema(t),
111
115
  onSubmit: async (values, formikHelpers) => {
112
116
  if (roleName) {
113
117
  updateRole(values, formikHelpers);
@@ -176,7 +180,7 @@ const RoleForm = ({
176
180
  actions: {
177
181
  showBack: false,
178
182
  showNext: true,
179
- nextText: "Next",
183
+ nextText: t("roleForm.steps.next"),
180
184
  canNext: () => !!formik.values.name && !formik.errors.name,
181
185
  onNext: () => handleNext("name")
182
186
  },
@@ -199,11 +203,11 @@ const RoleForm = ({
199
203
  title: titles.usersAndGroupsTitle,
200
204
  actions: {
201
205
  showNext: true,
202
- nextText: "Next",
206
+ nextText: t("roleForm.steps.next"),
203
207
  canNext: () => formik.values.selectedMembers?.length > 0 && !formik.errors.selectedMembers,
204
208
  onNext: () => handleNext("selectedMembers"),
205
209
  showBack: true,
206
- backText: "Back",
210
+ backText: t("roleForm.steps.back"),
207
211
  onBack: handleBack
208
212
  },
209
213
  children: /* @__PURE__ */ jsxs(Box, { children: [
@@ -233,11 +237,11 @@ const RoleForm = ({
233
237
  title: titles.permissionPoliciesTitle,
234
238
  actions: {
235
239
  showNext: true,
236
- nextText: "Next",
240
+ nextText: t("roleForm.steps.next"),
237
241
  canNext: () => canNextPermissionPoliciesStep(),
238
242
  onNext: () => handleNext("permissionPoliciesRows"),
239
243
  showBack: true,
240
- backText: "Back",
244
+ backText: t("roleForm.steps.back"),
241
245
  onBack: handleBack
242
246
  },
243
247
  children: /* @__PURE__ */ jsx(
@@ -256,8 +260,8 @@ const RoleForm = ({
256
260
  /* @__PURE__ */ jsx(SimpleStepperStep, { title: "", end: true, children: /* @__PURE__ */ jsxs(Paper, { square: true, elevation: 0, children: [
257
261
  /* @__PURE__ */ jsx(ReviewStep, { values: formik.values, isEditing: !!roleName }),
258
262
  /* @__PURE__ */ jsx("br", {}),
259
- /* @__PURE__ */ jsx(Button, { onClick: handleBack, children: "Back" }),
260
- /* @__PURE__ */ jsx(Button, { onClick: (e) => handleReset(e), children: "Reset" }),
263
+ /* @__PURE__ */ jsx(Button, { onClick: handleBack, children: t("roleForm.steps.back") }),
264
+ /* @__PURE__ */ jsx(Button, { onClick: (e) => handleReset(e), children: t("roleForm.steps.reset") }),
261
265
  /* @__PURE__ */ jsx(
262
266
  Button,
263
267
  {
@@ -265,7 +269,7 @@ const RoleForm = ({
265
269
  color: "primary",
266
270
  type: "submit",
267
271
  disabled: !!formik.errors.name || !!formik.errors.selectedMembers || !formik.dirty,
268
- children: submitLabel || "Create"
272
+ children: submitLabel || (roleName ? t("roleForm.steps.update") : t("roleForm.steps.create"))
269
273
  }
270
274
  )
271
275
  ] }) })
@@ -277,7 +281,7 @@ const RoleForm = ({
277
281
  style: { position: "absolute", right: "2.75rem", bottom: "2.75rem" },
278
282
  onClick: () => setOpenCancelDialog(true),
279
283
  color: "primary",
280
- children: "Cancel"
284
+ children: t("roleForm.steps.cancel")
281
285
  }
282
286
  )
283
287
  ]
@@ -289,7 +293,7 @@ const RoleForm = ({
289
293
  open: openCancelDialog,
290
294
  editForm: !!roleName,
291
295
  closeDialog: () => setOpenCancelDialog(false),
292
- navigateTo: () => navigateTo(navigate, roleName, undefined, undefined, step)
296
+ navigateTo: () => navigateTo(navigate, t, roleName, undefined, undefined, step)
293
297
  }
294
298
  )
295
299
  ] });
@@ -1 +1 @@
1
- {"version":3,"file":"RoleForm.esm.js","sources":["../../../src/components/CreateRole/RoleForm.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 { useState, MouseEvent } from 'react';\nimport { useNavigate } from 'react-router-dom';\n\nimport { SimpleStepper, SimpleStepperStep } from '@backstage/core-components';\nimport { useApi } from '@backstage/core-plugin-api';\n\nimport Alert from '@mui/material/Alert';\nimport Box from '@mui/material/Box';\nimport Button from '@mui/material/Button';\nimport Card from '@mui/material/Card';\nimport CardContent from '@mui/material/CardContent';\nimport CardHeader from '@mui/material/CardHeader';\nimport Divider from '@mui/material/Divider';\nimport Paper from '@mui/material/Paper';\nimport { FormikErrors, FormikHelpers, useFormik } from 'formik';\n\nimport { rbacApiRef } from '../../api/RBACBackendClient';\nimport { MemberEntity, PermissionsData, RoleError } from '../../types';\nimport {\n getConditionalPermissionPoliciesData,\n getNewConditionalPolicies,\n getPermissionPoliciesData,\n getRemovedConditionalPoliciesIds,\n getRoleData,\n getUpdatedConditionalPolicies,\n validationSchema,\n} from '../../utils/create-role-utils';\nimport { isSamePermissionPolicy, onlyInLeft } from '../../utils/rbac-utils';\nimport {\n createConditions,\n createPermissions,\n modifyConditions,\n navigateTo,\n removeConditions,\n removePermissions,\n} from '../../utils/role-form-utils';\nimport { AddedMembersTable } from './AddedMembersTable';\nimport { AddMembersForm } from './AddMembersForm';\nimport { PermissionPoliciesForm } from './PermissionPoliciesForm';\nimport { ReviewStep } from './ReviewStep';\nimport { RoleDetailsForm } from './RoleDetailsForm';\nimport { RoleFormValues } from './types';\nimport CancelDialog from './CancelDialog';\n\ntype RoleFormProps = {\n membersData: { members: MemberEntity[]; loading: boolean; error: Error };\n titles: {\n formTitle: string;\n nameAndDescriptionTitle: string;\n usersAndGroupsTitle: string;\n permissionPoliciesTitle: string;\n };\n submitLabel?: string;\n roleName?: string;\n step?: number;\n initialValues: RoleFormValues;\n};\n\nexport const RoleForm = ({\n roleName,\n step,\n titles,\n membersData,\n submitLabel,\n initialValues,\n}: RoleFormProps) => {\n const [activeStep, setActiveStep] = useState<number>(step || 0);\n const [openCancelDialog, setOpenCancelDialog] = useState<boolean>(false);\n const navigate = useNavigate();\n const rbacApi = useApi(rbacApiRef);\n\n const updateRole = async (\n values: RoleFormValues,\n formikHelpers: FormikHelpers<RoleFormValues>,\n ) => {\n try {\n const newData = getRoleData(values);\n const newName = newData.name;\n const newPermissionsData = getPermissionPoliciesData(values);\n const newConditions = getNewConditionalPolicies(values);\n const deleteConditions = getRemovedConditionalPoliciesIds(\n values,\n initialValues,\n );\n const updateConditions = getUpdatedConditionalPolicies(\n values,\n initialValues,\n );\n\n const oldData = getRoleData(initialValues);\n const res = await rbacApi.updateRole(oldData, newData);\n if ((res as RoleError).error) {\n throw new Error(\n `${'Unable to edit the role. '}${(res as RoleError).error.message}`,\n );\n } else {\n const oldPermissionsData = getPermissionPoliciesData(initialValues);\n const newPermissions = onlyInLeft(\n newPermissionsData,\n oldPermissionsData,\n isSamePermissionPolicy,\n );\n const deletePermissions = onlyInLeft(\n oldPermissionsData,\n newPermissionsData,\n isSamePermissionPolicy,\n );\n\n await removePermissions(newName, deletePermissions, rbacApi);\n await createPermissions(newPermissions, rbacApi);\n\n await removeConditions(deleteConditions, rbacApi);\n await modifyConditions(updateConditions, rbacApi);\n await createConditions(newConditions, rbacApi);\n\n navigateTo(navigate, roleName, newName, 'updated', step);\n }\n } catch (e) {\n formikHelpers.setStatus({ submitError: e });\n }\n };\n\n const newRole = async (\n values: RoleFormValues,\n formikHelpers: FormikHelpers<RoleFormValues>,\n ) => {\n try {\n const newData = getRoleData(values);\n const newPermissionsData = getPermissionPoliciesData(values);\n const newConditionalPermissionPoliciesData =\n getConditionalPermissionPoliciesData(values);\n\n const res = await rbacApi.createRole(newData);\n if ((res as RoleError).error) {\n throw new Error(\n `${'Unable to create role. '}${(res as RoleError).error.message}`,\n );\n }\n\n await createPermissions(\n newPermissionsData,\n rbacApi,\n 'Role was created successfully but unable to add permission policies to the role.',\n );\n\n await createConditions(\n newConditionalPermissionPoliciesData,\n rbacApi,\n 'Role created successfully but unable to add conditions to the role.',\n );\n\n navigateTo(navigate, roleName, newData.name, 'created', step);\n } catch (e) {\n formikHelpers.setStatus({ submitError: e });\n }\n };\n\n const formik = useFormik<RoleFormValues>({\n enableReinitialize: true,\n initialValues,\n validationSchema: validationSchema,\n onSubmit: async (\n values: RoleFormValues,\n formikHelpers: FormikHelpers<RoleFormValues>,\n ) => {\n if (roleName) {\n updateRole(values, formikHelpers);\n } else {\n newRole(values, formikHelpers);\n }\n },\n });\n\n const validateStepField = (fieldName: string) => {\n switch (fieldName) {\n case 'name': {\n formik.validateField(fieldName);\n return formik.errors.name;\n }\n case 'selectedMembers': {\n formik.validateField(fieldName);\n return formik.errors.selectedMembers;\n }\n case 'permissionPoliciesRows': {\n formik.values.permissionPoliciesRows.forEach((_pp, index) => {\n formik.validateField(`permissionPoliciesRows[${index}].plugin`);\n formik.validateField(`permissionPoliciesRows[${index}].permission`);\n });\n return formik.errors.permissionPoliciesRows;\n }\n default:\n return undefined;\n }\n };\n\n const handleNext = (fieldName?: string) => {\n const error = fieldName && validateStepField(fieldName);\n if (!fieldName || !error) {\n formik.setErrors({});\n const stepNum = Math.min(activeStep + 1, 3);\n setActiveStep(stepNum);\n }\n };\n\n const canNextPermissionPoliciesStep = () => {\n const selectedPluginsLength = formik.values.selectedPlugins.filter(\n sp => !!sp.value,\n ).length;\n return (\n selectedPluginsLength > 0 &&\n formik.values.permissionPoliciesRows.filter(pp =>\n formik.values.selectedPlugins.find(sp => sp.value === pp.plugin),\n ).length >= selectedPluginsLength &&\n !formik.errors.selectedPlugins &&\n (!formik.errors.permissionPoliciesRows ||\n (Array.isArray(formik.errors.permissionPoliciesRows) &&\n (\n formik.errors.permissionPoliciesRows as unknown as FormikErrors<\n PermissionsData[]\n >[]\n )?.filter(err => !!err)?.length === 0))\n );\n };\n\n const handleBack = () => setActiveStep(Math.max(activeStep - 1, 0));\n\n const handleReset = (\n e: MouseEvent<HTMLButtonElement, globalThis.MouseEvent>,\n ) => {\n setActiveStep(0);\n formik.handleReset(e);\n };\n\n return (\n <Card style={{ overflow: 'auto' }}>\n <CardHeader title={titles.formTitle} />\n <Divider />\n <CardContent\n component=\"form\"\n onSubmit={formik.handleSubmit}\n style={{ position: 'relative' }}\n >\n <SimpleStepper activeStep={activeStep}>\n <SimpleStepperStep\n title={titles.nameAndDescriptionTitle}\n actions={{\n showBack: false,\n showNext: true,\n nextText: 'Next',\n canNext: () => !!formik.values.name && !formik.errors.name,\n onNext: () => handleNext('name'),\n }}\n >\n <RoleDetailsForm\n name={formik.values.name}\n description={formik.values.description}\n owner={formik.values.owner}\n handleBlur={formik.handleBlur}\n handleChange={formik.handleChange}\n nameError={formik.errors.name}\n />\n </SimpleStepperStep>\n <SimpleStepperStep\n title={titles.usersAndGroupsTitle}\n actions={{\n showNext: true,\n nextText: 'Next',\n canNext: () =>\n formik.values.selectedMembers?.length > 0 &&\n !formik.errors.selectedMembers,\n onNext: () => handleNext('selectedMembers'),\n showBack: true,\n backText: 'Back',\n onBack: handleBack,\n }}\n >\n <Box>\n <AddMembersForm\n selectedMembers={formik.values.selectedMembers}\n selectedMembersError={formik.errors.selectedMembers as string}\n setFieldValue={formik.setFieldValue}\n membersData={membersData}\n />\n <br />\n <AddedMembersTable\n selectedMembers={formik.values.selectedMembers}\n setFieldValue={formik.setFieldValue}\n />\n </Box>\n </SimpleStepperStep>\n <SimpleStepperStep\n title={titles.permissionPoliciesTitle}\n actions={{\n showNext: true,\n nextText: 'Next',\n canNext: () => canNextPermissionPoliciesStep(),\n onNext: () => handleNext('permissionPoliciesRows'),\n showBack: true,\n backText: 'Back',\n onBack: handleBack,\n }}\n >\n <PermissionPoliciesForm\n permissionPoliciesRows={formik.values.permissionPoliciesRows}\n selectedPlugins={formik.values.selectedPlugins}\n selectedPluginsError={\n formik.errors.selectedPlugins as FormikErrors<string>\n }\n setFieldValue={formik.setFieldValue}\n setFieldError={formik.setFieldError}\n handleBlur={formik.handleBlur}\n />\n </SimpleStepperStep>\n <SimpleStepperStep title=\"\" end>\n <Paper square elevation={0}>\n <ReviewStep values={formik.values} isEditing={!!roleName} />\n <br />\n <Button onClick={handleBack}>Back</Button>\n <Button onClick={e => handleReset(e)}>Reset</Button>\n <Button\n variant=\"contained\"\n color=\"primary\"\n type=\"submit\"\n disabled={\n !!formik.errors.name ||\n !!formik.errors.selectedMembers ||\n !formik.dirty\n }\n >\n {submitLabel || 'Create'}\n </Button>\n </Paper>\n </SimpleStepperStep>\n </SimpleStepper>\n {formik.status?.submitError && (\n <Box style={{ paddingBottom: '16px' }}>\n <Alert severity=\"error\">{`${formik.status.submitError}`}</Alert>\n </Box>\n )}\n <Button\n style={{ position: 'absolute', right: '2.75rem', bottom: '2.75rem' }}\n onClick={() => setOpenCancelDialog(true)}\n color=\"primary\"\n >\n Cancel\n </Button>\n </CardContent>\n <CancelDialog\n open={openCancelDialog}\n editForm={!!roleName}\n closeDialog={() => setOpenCancelDialog(false)}\n navigateTo={() =>\n navigateTo(navigate, roleName, undefined, undefined, step)\n }\n />\n </Card>\n );\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"RoleForm.esm.js","sources":["../../../src/components/CreateRole/RoleForm.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 { useState, MouseEvent } from 'react';\nimport { useNavigate } from 'react-router-dom';\n\nimport { SimpleStepper, SimpleStepperStep } from '@backstage/core-components';\nimport { useApi } from '@backstage/core-plugin-api';\n\nimport Alert from '@mui/material/Alert';\nimport Box from '@mui/material/Box';\nimport Button from '@mui/material/Button';\nimport Card from '@mui/material/Card';\nimport CardContent from '@mui/material/CardContent';\nimport CardHeader from '@mui/material/CardHeader';\nimport Divider from '@mui/material/Divider';\nimport Paper from '@mui/material/Paper';\nimport { FormikErrors, FormikHelpers, useFormik } from 'formik';\n\nimport { useTranslation } from '../../hooks/useTranslation';\n\nimport { rbacApiRef } from '../../api/RBACBackendClient';\nimport { MemberEntity, PermissionsData, RoleError } from '../../types';\nimport {\n getConditionalPermissionPoliciesData,\n getNewConditionalPolicies,\n getPermissionPoliciesData,\n getRemovedConditionalPoliciesIds,\n getRoleData,\n getUpdatedConditionalPolicies,\n getValidationSchema,\n} from '../../utils/create-role-utils';\nimport { isSamePermissionPolicy, onlyInLeft } from '../../utils/rbac-utils';\nimport {\n createConditions,\n createPermissions,\n modifyConditions,\n navigateTo,\n removeConditions,\n removePermissions,\n} from '../../utils/role-form-utils';\nimport { AddedMembersTable } from './AddedMembersTable';\nimport { AddMembersForm } from './AddMembersForm';\nimport { PermissionPoliciesForm } from './PermissionPoliciesForm';\nimport { ReviewStep } from './ReviewStep';\nimport { RoleDetailsForm } from './RoleDetailsForm';\nimport { RoleFormValues } from './types';\nimport CancelDialog from './CancelDialog';\n\ntype RoleFormProps = {\n membersData: { members: MemberEntity[]; loading: boolean; error: Error };\n titles: {\n formTitle: string;\n nameAndDescriptionTitle: string;\n usersAndGroupsTitle: string;\n permissionPoliciesTitle: string;\n };\n submitLabel?: string;\n roleName?: string;\n step?: number;\n initialValues: RoleFormValues;\n};\n\nexport const RoleForm = ({\n roleName,\n step,\n titles,\n membersData,\n submitLabel,\n initialValues,\n}: RoleFormProps) => {\n const [activeStep, setActiveStep] = useState<number>(step || 0);\n const [openCancelDialog, setOpenCancelDialog] = useState<boolean>(false);\n const navigate = useNavigate();\n const rbacApi = useApi(rbacApiRef);\n const { t } = useTranslation();\n\n const updateRole = async (\n values: RoleFormValues,\n formikHelpers: FormikHelpers<RoleFormValues>,\n ) => {\n try {\n const newData = getRoleData(values);\n const newName = newData.name;\n const newPermissionsData = getPermissionPoliciesData(values);\n const newConditions = getNewConditionalPolicies(values);\n const deleteConditions = getRemovedConditionalPoliciesIds(\n values,\n initialValues,\n );\n const updateConditions = getUpdatedConditionalPolicies(\n values,\n initialValues,\n );\n\n const oldData = getRoleData(initialValues);\n const res = await rbacApi.updateRole(oldData, newData);\n if ((res as RoleError).error) {\n throw new Error(\n `${t('errors.editRole')} ${(res as RoleError).error.message}`,\n );\n } else {\n const oldPermissionsData = getPermissionPoliciesData(initialValues);\n const newPermissions = onlyInLeft(\n newPermissionsData,\n oldPermissionsData,\n isSamePermissionPolicy,\n );\n const deletePermissions = onlyInLeft(\n oldPermissionsData,\n newPermissionsData,\n isSamePermissionPolicy,\n );\n\n await removePermissions(newName, deletePermissions, rbacApi, t);\n await createPermissions(newPermissions, rbacApi, t);\n\n await removeConditions(deleteConditions, rbacApi, t);\n await modifyConditions(updateConditions, rbacApi, t);\n await createConditions(newConditions, rbacApi, t);\n\n navigateTo(navigate, t, roleName, newName, 'updated', step);\n }\n } catch (e) {\n formikHelpers.setStatus({ submitError: e });\n }\n };\n\n const newRole = async (\n values: RoleFormValues,\n formikHelpers: FormikHelpers<RoleFormValues>,\n ) => {\n try {\n const newData = getRoleData(values);\n const newPermissionsData = getPermissionPoliciesData(values);\n const newConditionalPermissionPoliciesData =\n getConditionalPermissionPoliciesData(values);\n\n const res = await rbacApi.createRole(newData);\n if ((res as RoleError).error) {\n throw new Error(\n `${t('errors.createRole')} ${(res as RoleError).error.message}`,\n );\n }\n\n await createPermissions(\n newPermissionsData,\n rbacApi,\n t,\n t('errors.roleCreatedSuccess'),\n );\n\n await createConditions(\n newConditionalPermissionPoliciesData,\n rbacApi,\n t,\n t('errors.roleCreatedConditionsSuccess'),\n );\n\n navigateTo(navigate, t, roleName, newData.name, 'created', step);\n } catch (e) {\n formikHelpers.setStatus({ submitError: e });\n }\n };\n\n const formik = useFormik<RoleFormValues>({\n enableReinitialize: true,\n initialValues,\n validationSchema: getValidationSchema(t),\n onSubmit: async (\n values: RoleFormValues,\n formikHelpers: FormikHelpers<RoleFormValues>,\n ) => {\n if (roleName) {\n updateRole(values, formikHelpers);\n } else {\n newRole(values, formikHelpers);\n }\n },\n });\n\n const validateStepField = (fieldName: string) => {\n switch (fieldName) {\n case 'name': {\n formik.validateField(fieldName);\n return formik.errors.name;\n }\n case 'selectedMembers': {\n formik.validateField(fieldName);\n return formik.errors.selectedMembers;\n }\n case 'permissionPoliciesRows': {\n formik.values.permissionPoliciesRows.forEach((_pp, index) => {\n formik.validateField(`permissionPoliciesRows[${index}].plugin`);\n formik.validateField(`permissionPoliciesRows[${index}].permission`);\n });\n return formik.errors.permissionPoliciesRows;\n }\n default:\n return undefined;\n }\n };\n\n const handleNext = (fieldName?: string) => {\n const error = fieldName && validateStepField(fieldName);\n if (!fieldName || !error) {\n formik.setErrors({});\n const stepNum = Math.min(activeStep + 1, 3);\n setActiveStep(stepNum);\n }\n };\n\n const canNextPermissionPoliciesStep = () => {\n const selectedPluginsLength = formik.values.selectedPlugins.filter(\n sp => !!sp.value,\n ).length;\n return (\n selectedPluginsLength > 0 &&\n formik.values.permissionPoliciesRows.filter(pp =>\n formik.values.selectedPlugins.find(sp => sp.value === pp.plugin),\n ).length >= selectedPluginsLength &&\n !formik.errors.selectedPlugins &&\n (!formik.errors.permissionPoliciesRows ||\n (Array.isArray(formik.errors.permissionPoliciesRows) &&\n (\n formik.errors.permissionPoliciesRows as unknown as FormikErrors<\n PermissionsData[]\n >[]\n )?.filter(err => !!err)?.length === 0))\n );\n };\n\n const handleBack = () => setActiveStep(Math.max(activeStep - 1, 0));\n\n const handleReset = (\n e: MouseEvent<HTMLButtonElement, globalThis.MouseEvent>,\n ) => {\n setActiveStep(0);\n formik.handleReset(e);\n };\n\n return (\n <Card style={{ overflow: 'auto' }}>\n <CardHeader title={titles.formTitle} />\n <Divider />\n <CardContent\n component=\"form\"\n onSubmit={formik.handleSubmit}\n style={{ position: 'relative' }}\n >\n <SimpleStepper activeStep={activeStep}>\n <SimpleStepperStep\n title={titles.nameAndDescriptionTitle}\n actions={{\n showBack: false,\n showNext: true,\n nextText: t('roleForm.steps.next'),\n canNext: () => !!formik.values.name && !formik.errors.name,\n onNext: () => handleNext('name'),\n }}\n >\n <RoleDetailsForm\n name={formik.values.name}\n description={formik.values.description}\n owner={formik.values.owner}\n handleBlur={formik.handleBlur}\n handleChange={formik.handleChange}\n nameError={formik.errors.name}\n />\n </SimpleStepperStep>\n <SimpleStepperStep\n title={titles.usersAndGroupsTitle}\n actions={{\n showNext: true,\n nextText: t('roleForm.steps.next'),\n canNext: () =>\n formik.values.selectedMembers?.length > 0 &&\n !formik.errors.selectedMembers,\n onNext: () => handleNext('selectedMembers'),\n showBack: true,\n backText: t('roleForm.steps.back'),\n onBack: handleBack,\n }}\n >\n <Box>\n <AddMembersForm\n selectedMembers={formik.values.selectedMembers}\n selectedMembersError={formik.errors.selectedMembers as string}\n setFieldValue={formik.setFieldValue}\n membersData={membersData}\n />\n <br />\n <AddedMembersTable\n selectedMembers={formik.values.selectedMembers}\n setFieldValue={formik.setFieldValue}\n />\n </Box>\n </SimpleStepperStep>\n <SimpleStepperStep\n title={titles.permissionPoliciesTitle}\n actions={{\n showNext: true,\n nextText: t('roleForm.steps.next'),\n canNext: () => canNextPermissionPoliciesStep(),\n onNext: () => handleNext('permissionPoliciesRows'),\n showBack: true,\n backText: t('roleForm.steps.back'),\n onBack: handleBack,\n }}\n >\n <PermissionPoliciesForm\n permissionPoliciesRows={formik.values.permissionPoliciesRows}\n selectedPlugins={formik.values.selectedPlugins}\n selectedPluginsError={\n formik.errors.selectedPlugins as FormikErrors<string>\n }\n setFieldValue={formik.setFieldValue}\n setFieldError={formik.setFieldError}\n handleBlur={formik.handleBlur}\n />\n </SimpleStepperStep>\n <SimpleStepperStep title=\"\" end>\n <Paper square elevation={0}>\n <ReviewStep values={formik.values} isEditing={!!roleName} />\n <br />\n <Button onClick={handleBack}>{t('roleForm.steps.back')}</Button>\n <Button onClick={e => handleReset(e)}>\n {t('roleForm.steps.reset')}\n </Button>\n <Button\n variant=\"contained\"\n color=\"primary\"\n type=\"submit\"\n disabled={\n !!formik.errors.name ||\n !!formik.errors.selectedMembers ||\n !formik.dirty\n }\n >\n {submitLabel ||\n (roleName\n ? t('roleForm.steps.update')\n : t('roleForm.steps.create'))}\n </Button>\n </Paper>\n </SimpleStepperStep>\n </SimpleStepper>\n {formik.status?.submitError && (\n <Box style={{ paddingBottom: '16px' }}>\n <Alert severity=\"error\">{`${formik.status.submitError}`}</Alert>\n </Box>\n )}\n <Button\n style={{ position: 'absolute', right: '2.75rem', bottom: '2.75rem' }}\n onClick={() => setOpenCancelDialog(true)}\n color=\"primary\"\n >\n {t('roleForm.steps.cancel')}\n </Button>\n </CardContent>\n <CancelDialog\n open={openCancelDialog}\n editForm={!!roleName}\n closeDialog={() => setOpenCancelDialog(false)}\n navigateTo={() =>\n navigateTo(navigate, t, roleName, undefined, undefined, step)\n }\n />\n </Card>\n );\n};\n"],"names":[],"mappings":"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"}
@@ -1,29 +1,31 @@
1
1
  import { getRulesNumber } from '../../utils/create-role-utils.esm.js';
2
2
  import { getPolicyString } from '../../utils/rbac-utils.esm.js';
3
3
 
4
- const selectedPermissionPoliciesColumn = () => [
5
- {
6
- title: "Plugin",
7
- field: "plugin"
8
- },
9
- {
10
- title: "Permission",
11
- field: "permission"
12
- },
13
- {
14
- title: "Policies",
15
- field: "policies",
16
- render: (policies) => getPolicyString(policies)
17
- },
18
- {
19
- title: "Conditional",
20
- field: "conditions",
21
- render: (conditions) => {
22
- const totalRules = getRulesNumber(conditions);
23
- return totalRules ? `${totalRules} ${totalRules > 1 ? "rules" : "rule"}` : "-";
4
+ const selectedPermissionPoliciesColumn = (t) => {
5
+ return [
6
+ {
7
+ title: t("permissionPolicies.plugin"),
8
+ field: "plugin"
9
+ },
10
+ {
11
+ title: t("permissionPolicies.permission"),
12
+ field: "permission"
13
+ },
14
+ {
15
+ title: t("permissionPolicies.policies"),
16
+ field: "policies",
17
+ render: (policies) => getPolicyString(policies)
18
+ },
19
+ {
20
+ title: t("permissionPolicies.conditional"),
21
+ field: "conditions",
22
+ render: (conditions) => {
23
+ const totalRules = getRulesNumber(conditions);
24
+ return totalRules ? `${totalRules} ${totalRules > 1 ? t("permissionPolicies.rules") : t("permissionPolicies.rule")}` : "-";
25
+ }
24
26
  }
25
- }
26
- ];
27
+ ];
28
+ };
27
29
 
28
30
  export { selectedPermissionPoliciesColumn };
29
31
  //# sourceMappingURL=SelectedPermissionPoliciesColumn.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"SelectedPermissionPoliciesColumn.esm.js","sources":["../../../src/components/CreateRole/SelectedPermissionPoliciesColumn.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 { getRulesNumber } from '../../utils/create-role-utils';\nimport { getPolicyString } from '../../utils/rbac-utils';\nimport { ConditionsData } from '../ConditionalAccess/types';\nimport { RowPolicy } from './types';\n\nexport const selectedPermissionPoliciesColumn = () => [\n {\n title: 'Plugin',\n field: 'plugin',\n },\n {\n title: 'Permission',\n field: 'permission',\n },\n {\n title: 'Policies',\n field: 'policies',\n render: (policies: RowPolicy[]) => getPolicyString(policies),\n },\n {\n title: 'Conditional',\n field: 'conditions',\n render: (conditions: ConditionsData) => {\n const totalRules = getRulesNumber(conditions);\n return totalRules\n ? `${totalRules} ${totalRules > 1 ? 'rules' : 'rule'}`\n : '-';\n },\n },\n];\n"],"names":[],"mappings":";;;AAoBO,MAAM,mCAAmC,MAAM;AAAA,EACpD;AAAA,IACE,KAAO,EAAA,QAAA;AAAA,IACP,KAAO,EAAA;AAAA,GACT;AAAA,EACA;AAAA,IACE,KAAO,EAAA,YAAA;AAAA,IACP,KAAO,EAAA;AAAA,GACT;AAAA,EACA;AAAA,IACE,KAAO,EAAA,UAAA;AAAA,IACP,KAAO,EAAA,UAAA;AAAA,IACP,MAAQ,EAAA,CAAC,QAA0B,KAAA,eAAA,CAAgB,QAAQ;AAAA,GAC7D;AAAA,EACA;AAAA,IACE,KAAO,EAAA,aAAA;AAAA,IACP,KAAO,EAAA,YAAA;AAAA,IACP,MAAA,EAAQ,CAAC,UAA+B,KAAA;AACtC,MAAM,MAAA,UAAA,GAAa,eAAe,UAAU,CAAA;AAC5C,MAAO,OAAA,UAAA,GACH,GAAG,UAAU,CAAA,CAAA,EAAI,aAAa,CAAI,GAAA,OAAA,GAAU,MAAM,CAClD,CAAA,GAAA,GAAA;AAAA;AACN;AAEJ;;;;"}
1
+ {"version":3,"file":"SelectedPermissionPoliciesColumn.esm.js","sources":["../../../src/components/CreateRole/SelectedPermissionPoliciesColumn.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 { getRulesNumber } from '../../utils/create-role-utils';\nimport { getPolicyString } from '../../utils/rbac-utils';\nimport { ConditionsData } from '../ConditionalAccess/types';\nimport { RowPolicy } from './types';\nimport { TranslationFunction } from '@backstage/core-plugin-api/alpha';\nimport { rbacTranslationRef } from '../../translations';\n\nexport const selectedPermissionPoliciesColumn = (\n t: TranslationFunction<typeof rbacTranslationRef.T>,\n) => {\n return [\n {\n title: t('permissionPolicies.plugin'),\n field: 'plugin',\n },\n {\n title: t('permissionPolicies.permission'),\n field: 'permission',\n },\n {\n title: t('permissionPolicies.policies'),\n field: 'policies',\n render: (policies: RowPolicy[]) => getPolicyString(policies),\n },\n {\n title: t('permissionPolicies.conditional'),\n field: 'conditions',\n render: (conditions: ConditionsData) => {\n const totalRules = getRulesNumber(conditions);\n return totalRules\n ? `${totalRules} ${totalRules > 1 ? t('permissionPolicies.rules') : t('permissionPolicies.rule')}`\n : '-';\n },\n },\n ];\n};\n"],"names":[],"mappings":";;;AAsBa,MAAA,gCAAA,GAAmC,CAC9C,CACG,KAAA;AACH,EAAO,OAAA;AAAA,IACL;AAAA,MACE,KAAA,EAAO,EAAE,2BAA2B,CAAA;AAAA,MACpC,KAAO,EAAA;AAAA,KACT;AAAA,IACA;AAAA,MACE,KAAA,EAAO,EAAE,+BAA+B,CAAA;AAAA,MACxC,KAAO,EAAA;AAAA,KACT;AAAA,IACA;AAAA,MACE,KAAA,EAAO,EAAE,6BAA6B,CAAA;AAAA,MACtC,KAAO,EAAA,UAAA;AAAA,MACP,MAAQ,EAAA,CAAC,QAA0B,KAAA,eAAA,CAAgB,QAAQ;AAAA,KAC7D;AAAA,IACA;AAAA,MACE,KAAA,EAAO,EAAE,gCAAgC,CAAA;AAAA,MACzC,KAAO,EAAA,YAAA;AAAA,MACP,MAAA,EAAQ,CAAC,UAA+B,KAAA;AACtC,QAAM,MAAA,UAAA,GAAa,eAAe,UAAU,CAAA;AAC5C,QAAA,OAAO,UACH,GAAA,CAAA,EAAG,UAAU,CAAA,CAAA,EAAI,UAAa,GAAA,CAAA,GAAI,CAAE,CAAA,0BAA0B,CAAI,GAAA,CAAA,CAAE,yBAAyB,CAAC,CAC9F,CAAA,GAAA,GAAA;AAAA;AACN;AACF,GACF;AACF;;;;"}
@@ -2,9 +2,11 @@ import { jsx } from 'react/jsx-runtime';
2
2
  import { useApi } from '@backstage/core-plugin-api';
3
3
  import Button from '@mui/material/Button';
4
4
  import { licensedUsersApiRef } from '../api/LicensedUsersClient.esm.js';
5
+ import { useTranslation } from '../hooks/useTranslation.esm.js';
5
6
 
6
7
  function DownloadCSVLink() {
7
8
  const licensedUsersClient = useApi(licensedUsersApiRef);
9
+ const { t } = useTranslation();
8
10
  const handleDownload = async (event) => {
9
11
  event.preventDefault();
10
12
  try {
@@ -15,7 +17,7 @@ function DownloadCSVLink() {
15
17
  const url = window.URL.createObjectURL(blob);
16
18
  const a = document.createElement("a");
17
19
  a.href = url;
18
- a.download = "licensed-users.csv";
20
+ a.download = t("common.csvFilename");
19
21
  document.body.appendChild(a);
20
22
  a.click();
21
23
  document.body.removeChild(a);
@@ -40,7 +42,7 @@ function DownloadCSVLink() {
40
42
  marginTop: "1rem"
41
43
  },
42
44
  size: "small",
43
- children: "Download User List"
45
+ children: t("common.exportCSV")
44
46
  }
45
47
  );
46
48
  }
@@ -1 +1 @@
1
- {"version":3,"file":"DownloadUserStatistics.esm.js","sources":["../../src/components/DownloadUserStatistics.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 { MouseEvent } from 'react';\n\nimport { useApi } from '@backstage/core-plugin-api';\n\nimport Button from '@mui/material/Button';\n\nimport { licensedUsersApiRef } from '../api/LicensedUsersClient';\n\nfunction DownloadCSVLink() {\n const licensedUsersClient = useApi(licensedUsersApiRef);\n const handleDownload = async (\n event: MouseEvent<HTMLAnchorElement, globalThis.MouseEvent>,\n ) => {\n event.preventDefault(); // Prevent the default link behavior\n\n try {\n const response = await licensedUsersClient.downloadStatistics();\n\n if (response.ok) {\n // Get the CSV data as a string\n const csvData = await response.text();\n\n // Create a Blob from the CSV data\n const blob = new Blob([csvData], { type: 'text/csv' });\n const url = window.URL.createObjectURL(blob);\n\n // Create a temporary link to trigger the download\n const a = document.createElement('a');\n a.href = url;\n a.download = 'licensed-users.csv';\n document.body.appendChild(a);\n a.click();\n\n // Clean up the temporary link and object URL\n document.body.removeChild(a);\n window.URL.revokeObjectURL(url);\n } else {\n throw new Error(\n `Failed to download the csv file with list licensed users ${response.statusText}`,\n );\n }\n } catch (error) {\n throw new Error(`Error during the download: ${error}`);\n }\n };\n\n return (\n <Button\n href=\"/download-csv\"\n onClick={handleDownload}\n sx={{\n color: theme => theme.palette.link,\n textDecoration: 'underline',\n marginTop: '1rem',\n }}\n size=\"small\"\n >\n Download User List\n </Button>\n );\n}\n\nexport default DownloadCSVLink;\n"],"names":[],"mappings":";;;;;AAuBA,SAAS,eAAkB,GAAA;AACzB,EAAM,MAAA,mBAAA,GAAsB,OAAO,mBAAmB,CAAA;AACtD,EAAM,MAAA,cAAA,GAAiB,OACrB,KACG,KAAA;AACH,IAAA,KAAA,CAAM,cAAe,EAAA;AAErB,IAAI,IAAA;AACF,MAAM,MAAA,QAAA,GAAW,MAAM,mBAAA,CAAoB,kBAAmB,EAAA;AAE9D,MAAA,IAAI,SAAS,EAAI,EAAA;AAEf,QAAM,MAAA,OAAA,GAAU,MAAM,QAAA,CAAS,IAAK,EAAA;AAGpC,QAAM,MAAA,IAAA,GAAO,IAAI,IAAK,CAAA,CAAC,OAAO,CAAG,EAAA,EAAE,IAAM,EAAA,UAAA,EAAY,CAAA;AACrD,QAAA,MAAM,GAAM,GAAA,MAAA,CAAO,GAAI,CAAA,eAAA,CAAgB,IAAI,CAAA;AAG3C,QAAM,MAAA,CAAA,GAAI,QAAS,CAAA,aAAA,CAAc,GAAG,CAAA;AACpC,QAAA,CAAA,CAAE,IAAO,GAAA,GAAA;AACT,QAAA,CAAA,CAAE,QAAW,GAAA,oBAAA;AACb,QAAS,QAAA,CAAA,IAAA,CAAK,YAAY,CAAC,CAAA;AAC3B,QAAA,CAAA,CAAE,KAAM,EAAA;AAGR,QAAS,QAAA,CAAA,IAAA,CAAK,YAAY,CAAC,CAAA;AAC3B,QAAO,MAAA,CAAA,GAAA,CAAI,gBAAgB,GAAG,CAAA;AAAA,OACzB,MAAA;AACL,QAAA,MAAM,IAAI,KAAA;AAAA,UACR,CAAA,0DAAA,EAA6D,SAAS,UAAU,CAAA;AAAA,SAClF;AAAA;AACF,aACO,KAAO,EAAA;AACd,MAAA,MAAM,IAAI,KAAA,CAAM,CAA8B,2BAAA,EAAA,KAAK,CAAE,CAAA,CAAA;AAAA;AACvD,GACF;AAEA,EACE,uBAAA,GAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,IAAK,EAAA,eAAA;AAAA,MACL,OAAS,EAAA,cAAA;AAAA,MACT,EAAI,EAAA;AAAA,QACF,KAAA,EAAO,CAAS,KAAA,KAAA,KAAA,CAAM,OAAQ,CAAA,IAAA;AAAA,QAC9B,cAAgB,EAAA,WAAA;AAAA,QAChB,SAAW,EAAA;AAAA,OACb;AAAA,MACA,IAAK,EAAA,OAAA;AAAA,MACN,QAAA,EAAA;AAAA;AAAA,GAED;AAEJ;;;;"}
1
+ {"version":3,"file":"DownloadUserStatistics.esm.js","sources":["../../src/components/DownloadUserStatistics.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 { MouseEvent } from 'react';\n\nimport { useApi } from '@backstage/core-plugin-api';\n\nimport Button from '@mui/material/Button';\n\nimport { licensedUsersApiRef } from '../api/LicensedUsersClient';\nimport { useTranslation } from '../hooks/useTranslation';\n\nfunction DownloadCSVLink() {\n const licensedUsersClient = useApi(licensedUsersApiRef);\n const { t } = useTranslation();\n const handleDownload = async (\n event: MouseEvent<HTMLAnchorElement, globalThis.MouseEvent>,\n ) => {\n event.preventDefault(); // Prevent the default link behavior\n\n try {\n const response = await licensedUsersClient.downloadStatistics();\n\n if (response.ok) {\n // Get the CSV data as a string\n const csvData = await response.text();\n\n // Create a Blob from the CSV data\n const blob = new Blob([csvData], { type: 'text/csv' });\n const url = window.URL.createObjectURL(blob);\n\n // Create a temporary link to trigger the download\n const a = document.createElement('a');\n a.href = url;\n a.download = t('common.csvFilename');\n document.body.appendChild(a);\n a.click();\n\n // Clean up the temporary link and object URL\n document.body.removeChild(a);\n window.URL.revokeObjectURL(url);\n } else {\n throw new Error(\n `Failed to download the csv file with list licensed users ${response.statusText}`,\n );\n }\n } catch (error) {\n throw new Error(`Error during the download: ${error}`);\n }\n };\n\n return (\n <Button\n href=\"/download-csv\"\n onClick={handleDownload}\n sx={{\n color: theme => theme.palette.link,\n textDecoration: 'underline',\n marginTop: '1rem',\n }}\n size=\"small\"\n >\n {t('common.exportCSV')}\n </Button>\n );\n}\n\nexport default DownloadCSVLink;\n"],"names":[],"mappings":";;;;;;AAwBA,SAAS,eAAkB,GAAA;AACzB,EAAM,MAAA,mBAAA,GAAsB,OAAO,mBAAmB,CAAA;AACtD,EAAM,MAAA,EAAE,CAAE,EAAA,GAAI,cAAe,EAAA;AAC7B,EAAM,MAAA,cAAA,GAAiB,OACrB,KACG,KAAA;AACH,IAAA,KAAA,CAAM,cAAe,EAAA;AAErB,IAAI,IAAA;AACF,MAAM,MAAA,QAAA,GAAW,MAAM,mBAAA,CAAoB,kBAAmB,EAAA;AAE9D,MAAA,IAAI,SAAS,EAAI,EAAA;AAEf,QAAM,MAAA,OAAA,GAAU,MAAM,QAAA,CAAS,IAAK,EAAA;AAGpC,QAAM,MAAA,IAAA,GAAO,IAAI,IAAK,CAAA,CAAC,OAAO,CAAG,EAAA,EAAE,IAAM,EAAA,UAAA,EAAY,CAAA;AACrD,QAAA,MAAM,GAAM,GAAA,MAAA,CAAO,GAAI,CAAA,eAAA,CAAgB,IAAI,CAAA;AAG3C,QAAM,MAAA,CAAA,GAAI,QAAS,CAAA,aAAA,CAAc,GAAG,CAAA;AACpC,QAAA,CAAA,CAAE,IAAO,GAAA,GAAA;AACT,QAAE,CAAA,CAAA,QAAA,GAAW,EAAE,oBAAoB,CAAA;AACnC,QAAS,QAAA,CAAA,IAAA,CAAK,YAAY,CAAC,CAAA;AAC3B,QAAA,CAAA,CAAE,KAAM,EAAA;AAGR,QAAS,QAAA,CAAA,IAAA,CAAK,YAAY,CAAC,CAAA;AAC3B,QAAO,MAAA,CAAA,GAAA,CAAI,gBAAgB,GAAG,CAAA;AAAA,OACzB,MAAA;AACL,QAAA,MAAM,IAAI,KAAA;AAAA,UACR,CAAA,0DAAA,EAA6D,SAAS,UAAU,CAAA;AAAA,SAClF;AAAA;AACF,aACO,KAAO,EAAA;AACd,MAAA,MAAM,IAAI,KAAA,CAAM,CAA8B,2BAAA,EAAA,KAAK,CAAE,CAAA,CAAA;AAAA;AACvD,GACF;AAEA,EACE,uBAAA,GAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,IAAK,EAAA,eAAA;AAAA,MACL,OAAS,EAAA,cAAA;AAAA,MACT,EAAI,EAAA;AAAA,QACF,KAAA,EAAO,CAAS,KAAA,KAAA,KAAA,CAAM,OAAQ,CAAA,IAAA;AAAA,QAC9B,cAAgB,EAAA,WAAA;AAAA,QAChB,SAAW,EAAA;AAAA,OACb;AAAA,MACA,IAAK,EAAA,OAAA;AAAA,MAEJ,YAAE,kBAAkB;AAAA;AAAA,GACvB;AAEJ;;;;"}
@@ -6,6 +6,7 @@ import Tooltip from '@mui/material/Tooltip';
6
6
  import { policyEntityUpdatePermission } from '@backstage-community/plugin-rbac-common';
7
7
  import { useNavigate } from 'react-router-dom';
8
8
  import { useActionPermissionTooltip } from '../hooks/useActionPermissionTooltip.esm.js';
9
+ import { useTranslation } from '../hooks/useTranslation.esm.js';
9
10
 
10
11
  const EditRole = ({
11
12
  roleName,
@@ -14,6 +15,7 @@ const EditRole = ({
14
15
  tooltip,
15
16
  to
16
17
  }) => {
18
+ const { t } = useTranslation();
17
19
  const navigate = useNavigate();
18
20
  const { name, namespace, kind } = parseEntityRef(roleName);
19
21
  const { disable, tooltipText, testIdText } = useActionPermissionTooltip({
@@ -31,9 +33,9 @@ const EditRole = ({
31
33
  navigate(to ?? `../role/${kind}/${namespace}/${name}`);
32
34
  },
33
35
  "data-testid": testIdText,
34
- "aria-label": "Update",
36
+ "aria-label": t("common.update"),
35
37
  disabled: disable,
36
- title: tooltip ?? "Edit Role",
38
+ title: tooltip ?? t("common.editRole"),
37
39
  sx: {
38
40
  p: 1,
39
41
  borderRadius: "50%",
@@ -1 +1 @@
1
- {"version":3,"file":"EditRole.esm.js","sources":["../../src/components/EditRole.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 { parseEntityRef } from '@backstage/catalog-model';\n\nimport EditIcon from '@mui/icons-material/Edit';\nimport IconButton from '@mui/material/IconButton';\nimport Tooltip from '@mui/material/Tooltip';\nimport { policyEntityUpdatePermission } from '@backstage-community/plugin-rbac-common';\nimport { useNavigate } from 'react-router-dom';\nimport { useActionPermissionTooltip } from '../hooks/useActionPermissionTooltip';\n\ntype EditRoleProps = {\n roleName: string;\n canEdit: boolean;\n dataTestId?: string;\n tooltip?: string;\n to?: string;\n};\n\nconst EditRole = ({\n roleName,\n canEdit,\n dataTestId,\n tooltip,\n to,\n}: EditRoleProps) => {\n const navigate = useNavigate();\n const { name, namespace, kind } = parseEntityRef(roleName);\n\n const { disable, tooltipText, testIdText } = useActionPermissionTooltip({\n permission: policyEntityUpdatePermission,\n resourceRef: roleName,\n canAct: canEdit,\n action: 'edit',\n dataTestId: dataTestId,\n fallbackTooltip: tooltip,\n });\n\n return (\n <Tooltip title={tooltipText}>\n <IconButton\n onClick={() => {\n navigate(to ?? `../role/${kind}/${namespace}/${name}`);\n }}\n data-testid={testIdText}\n aria-label=\"Update\"\n disabled={disable}\n title={tooltip ?? 'Edit Role'}\n sx={{\n p: 1,\n borderRadius: '50%',\n '&:hover': { borderRadius: '50%' },\n }}\n >\n <EditIcon />\n </IconButton>\n </Tooltip>\n );\n};\n\nexport default EditRole;\n"],"names":[],"mappings":";;;;;;;;;AAgCA,MAAM,WAAW,CAAC;AAAA,EAChB,QAAA;AAAA,EACA,OAAA;AAAA,EACA,UAAA;AAAA,EACA,OAAA;AAAA,EACA;AACF,CAAqB,KAAA;AACnB,EAAA,MAAM,WAAW,WAAY,EAAA;AAC7B,EAAA,MAAM,EAAE,IAAM,EAAA,SAAA,EAAW,IAAK,EAAA,GAAI,eAAe,QAAQ,CAAA;AAEzD,EAAA,MAAM,EAAE,OAAA,EAAS,WAAa,EAAA,UAAA,KAAe,0BAA2B,CAAA;AAAA,IACtE,UAAY,EAAA,4BAAA;AAAA,IACZ,WAAa,EAAA,QAAA;AAAA,IACb,MAAQ,EAAA,OAAA;AAAA,IACR,MAAQ,EAAA,MAAA;AAAA,IACR,UAAA;AAAA,IACA,eAAiB,EAAA;AAAA,GAClB,CAAA;AAED,EACE,uBAAA,GAAA,CAAC,OAAQ,EAAA,EAAA,KAAA,EAAO,WACd,EAAA,QAAA,kBAAA,GAAA;AAAA,IAAC,UAAA;AAAA,IAAA;AAAA,MACC,SAAS,MAAM;AACb,QAAA,QAAA,CAAS,MAAM,CAAW,QAAA,EAAA,IAAI,IAAI,SAAS,CAAA,CAAA,EAAI,IAAI,CAAE,CAAA,CAAA;AAAA,OACvD;AAAA,MACA,aAAa,EAAA,UAAA;AAAA,MACb,YAAW,EAAA,QAAA;AAAA,MACX,QAAU,EAAA,OAAA;AAAA,MACV,OAAO,OAAW,IAAA,WAAA;AAAA,MAClB,EAAI,EAAA;AAAA,QACF,CAAG,EAAA,CAAA;AAAA,QACH,YAAc,EAAA,KAAA;AAAA,QACd,SAAA,EAAW,EAAE,YAAA,EAAc,KAAM;AAAA,OACnC;AAAA,MAEA,8BAAC,QAAS,EAAA,EAAA;AAAA;AAAA,GAEd,EAAA,CAAA;AAEJ;;;;"}
1
+ {"version":3,"file":"EditRole.esm.js","sources":["../../src/components/EditRole.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 { parseEntityRef } from '@backstage/catalog-model';\n\nimport EditIcon from '@mui/icons-material/Edit';\nimport IconButton from '@mui/material/IconButton';\nimport Tooltip from '@mui/material/Tooltip';\nimport { policyEntityUpdatePermission } from '@backstage-community/plugin-rbac-common';\nimport { useNavigate } from 'react-router-dom';\nimport { useActionPermissionTooltip } from '../hooks/useActionPermissionTooltip';\nimport { useTranslation } from '../hooks/useTranslation';\n\ntype EditRoleProps = {\n roleName: string;\n canEdit: boolean;\n dataTestId?: string;\n tooltip?: string;\n to?: string;\n};\n\nconst EditRole = ({\n roleName,\n canEdit,\n dataTestId,\n tooltip,\n to,\n}: EditRoleProps) => {\n const { t } = useTranslation();\n const navigate = useNavigate();\n const { name, namespace, kind } = parseEntityRef(roleName);\n\n const { disable, tooltipText, testIdText } = useActionPermissionTooltip({\n permission: policyEntityUpdatePermission,\n resourceRef: roleName,\n canAct: canEdit,\n action: 'edit',\n dataTestId: dataTestId,\n fallbackTooltip: tooltip,\n });\n\n return (\n <Tooltip title={tooltipText}>\n <IconButton\n onClick={() => {\n navigate(to ?? `../role/${kind}/${namespace}/${name}`);\n }}\n data-testid={testIdText}\n aria-label={t('common.update')}\n disabled={disable}\n title={tooltip ?? t('common.editRole')}\n sx={{\n p: 1,\n borderRadius: '50%',\n '&:hover': { borderRadius: '50%' },\n }}\n >\n <EditIcon />\n </IconButton>\n </Tooltip>\n );\n};\n\nexport default EditRole;\n"],"names":[],"mappings":";;;;;;;;;;AAiCA,MAAM,WAAW,CAAC;AAAA,EAChB,QAAA;AAAA,EACA,OAAA;AAAA,EACA,UAAA;AAAA,EACA,OAAA;AAAA,EACA;AACF,CAAqB,KAAA;AACnB,EAAM,MAAA,EAAE,CAAE,EAAA,GAAI,cAAe,EAAA;AAC7B,EAAA,MAAM,WAAW,WAAY,EAAA;AAC7B,EAAA,MAAM,EAAE,IAAM,EAAA,SAAA,EAAW,IAAK,EAAA,GAAI,eAAe,QAAQ,CAAA;AAEzD,EAAA,MAAM,EAAE,OAAA,EAAS,WAAa,EAAA,UAAA,KAAe,0BAA2B,CAAA;AAAA,IACtE,UAAY,EAAA,4BAAA;AAAA,IACZ,WAAa,EAAA,QAAA;AAAA,IACb,MAAQ,EAAA,OAAA;AAAA,IACR,MAAQ,EAAA,MAAA;AAAA,IACR,UAAA;AAAA,IACA,eAAiB,EAAA;AAAA,GAClB,CAAA;AAED,EACE,uBAAA,GAAA,CAAC,OAAQ,EAAA,EAAA,KAAA,EAAO,WACd,EAAA,QAAA,kBAAA,GAAA;AAAA,IAAC,UAAA;AAAA,IAAA;AAAA,MACC,SAAS,MAAM;AACb,QAAA,QAAA,CAAS,MAAM,CAAW,QAAA,EAAA,IAAI,IAAI,SAAS,CAAA,CAAA,EAAI,IAAI,CAAE,CAAA,CAAA;AAAA,OACvD;AAAA,MACA,aAAa,EAAA,UAAA;AAAA,MACb,YAAA,EAAY,EAAE,eAAe,CAAA;AAAA,MAC7B,QAAU,EAAA,OAAA;AAAA,MACV,KAAA,EAAO,OAAW,IAAA,CAAA,CAAE,iBAAiB,CAAA;AAAA,MACrC,EAAI,EAAA;AAAA,QACF,CAAG,EAAA,CAAA;AAAA,QACH,YAAc,EAAA,KAAA;AAAA,QACd,SAAA,EAAW,EAAE,YAAA,EAAc,KAAM;AAAA,OACnC;AAAA,MAEA,8BAAC,QAAS,EAAA,EAAA;AAAA;AAAA,GAEd,EAAA,CAAA;AAEJ;;;;"}
@@ -5,18 +5,20 @@ import { useApi } from '@backstage/core-plugin-api';
5
5
  import { rbacApiRef } from '../api/RBACBackendClient.esm.js';
6
6
  import { useAsync } from 'react-use';
7
7
  import { DeleteDialogContextProvider } from './DeleteDialogContext.esm.js';
8
+ import { useTranslation } from '../hooks/useTranslation.esm.js';
8
9
 
9
10
  const RbacPage = ({ useHeader = true }) => {
10
11
  const rbacApi = useApi(rbacApiRef);
12
+ const { t } = useTranslation();
11
13
  const { loading: isUserLoading, value: result } = useAsync(
12
14
  async () => await rbacApi.getUserAuthorization(),
13
15
  []
14
16
  );
15
17
  if (!isUserLoading) {
16
18
  return result?.status === "Authorized" ? /* @__PURE__ */ jsxs(Page, { themeId: "tool", children: [
17
- useHeader && /* @__PURE__ */ jsx(Header, { title: "RBAC" }),
19
+ useHeader && /* @__PURE__ */ jsx(Header, { title: t("page.title") }),
18
20
  /* @__PURE__ */ jsx(Content, { children: /* @__PURE__ */ jsx(DeleteDialogContextProvider, { children: /* @__PURE__ */ jsx(RolesList, {}) }) })
19
- ] }) : /* @__PURE__ */ jsx(ErrorPage, { statusMessage: "Not Found" });
21
+ ] }) : /* @__PURE__ */ jsx(ErrorPage, { statusMessage: t("errors.notFound") });
20
22
  }
21
23
  return /* @__PURE__ */ jsx(Progress, {});
22
24
  };
@@ -1 +1 @@
1
- {"version":3,"file":"RbacPage.esm.js","sources":["../../src/components/RbacPage.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 { Content, Header, Page, Progress } from '@backstage/core-components';\n\nimport { RolesList } from './RolesList/RolesList';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { rbacApiRef } from '../api/RBACBackendClient';\nimport { useAsync } from 'react-use';\nimport { ErrorPage } from '@backstage/core-components';\nimport { DeleteDialogContextProvider } from './DeleteDialogContext';\n\nexport const RbacPage = ({ useHeader = true }: { useHeader?: boolean }) => {\n const rbacApi = useApi(rbacApiRef);\n const { loading: isUserLoading, value: result } = useAsync(\n async () => await rbacApi.getUserAuthorization(),\n [],\n );\n\n if (!isUserLoading) {\n return result?.status === 'Authorized' ? (\n <Page themeId=\"tool\">\n {useHeader && <Header title=\"RBAC\" />}\n <Content>\n <DeleteDialogContextProvider>\n <RolesList />\n </DeleteDialogContextProvider>\n </Content>\n </Page>\n ) : (\n <ErrorPage statusMessage=\"Not Found\" />\n );\n }\n return <Progress />;\n};\n"],"names":[],"mappings":";;;;;;;;AAwBO,MAAM,QAAW,GAAA,CAAC,EAAE,SAAA,GAAY,MAAoC,KAAA;AACzE,EAAM,MAAA,OAAA,GAAU,OAAO,UAAU,CAAA;AACjC,EAAA,MAAM,EAAE,OAAA,EAAS,aAAe,EAAA,KAAA,EAAO,QAAW,GAAA,QAAA;AAAA,IAChD,YAAY,MAAM,OAAA,CAAQ,oBAAqB,EAAA;AAAA,IAC/C;AAAC,GACH;AAEA,EAAA,IAAI,CAAC,aAAe,EAAA;AAClB,IAAA,OAAO,QAAQ,MAAW,KAAA,YAAA,mBACvB,IAAA,CAAA,IAAA,EAAA,EAAK,SAAQ,MACX,EAAA,QAAA,EAAA;AAAA,MAAa,SAAA,oBAAA,GAAA,CAAC,MAAO,EAAA,EAAA,KAAA,EAAM,MAAO,EAAA,CAAA;AAAA,0BAClC,OACC,EAAA,EAAA,QAAA,kBAAA,GAAA,CAAC,+BACC,QAAC,kBAAA,GAAA,CAAA,SAAA,EAAA,EAAU,GACb,CACF,EAAA;AAAA,KAAA,EACF,CAEA,mBAAA,GAAA,CAAC,SAAU,EAAA,EAAA,aAAA,EAAc,WAAY,EAAA,CAAA;AAAA;AAGzC,EAAA,2BAAQ,QAAS,EAAA,EAAA,CAAA;AACnB;;;;"}
1
+ {"version":3,"file":"RbacPage.esm.js","sources":["../../src/components/RbacPage.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 { Content, Header, Page, Progress } from '@backstage/core-components';\n\nimport { RolesList } from './RolesList/RolesList';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { rbacApiRef } from '../api/RBACBackendClient';\nimport { useAsync } from 'react-use';\nimport { ErrorPage } from '@backstage/core-components';\nimport { DeleteDialogContextProvider } from './DeleteDialogContext';\nimport { useTranslation } from '../hooks/useTranslation';\n\nexport const RbacPage = ({ useHeader = true }: { useHeader?: boolean }) => {\n const rbacApi = useApi(rbacApiRef);\n const { t } = useTranslation();\n const { loading: isUserLoading, value: result } = useAsync(\n async () => await rbacApi.getUserAuthorization(),\n [],\n );\n\n if (!isUserLoading) {\n return result?.status === 'Authorized' ? (\n <Page themeId=\"tool\">\n {useHeader && <Header title={t('page.title')} />}\n <Content>\n <DeleteDialogContextProvider>\n <RolesList />\n </DeleteDialogContextProvider>\n </Content>\n </Page>\n ) : (\n <ErrorPage statusMessage={t('errors.notFound')} />\n );\n }\n return <Progress />;\n};\n"],"names":[],"mappings":";;;;;;;;;AAyBO,MAAM,QAAW,GAAA,CAAC,EAAE,SAAA,GAAY,MAAoC,KAAA;AACzE,EAAM,MAAA,OAAA,GAAU,OAAO,UAAU,CAAA;AACjC,EAAM,MAAA,EAAE,CAAE,EAAA,GAAI,cAAe,EAAA;AAC7B,EAAA,MAAM,EAAE,OAAA,EAAS,aAAe,EAAA,KAAA,EAAO,QAAW,GAAA,QAAA;AAAA,IAChD,YAAY,MAAM,OAAA,CAAQ,oBAAqB,EAAA;AAAA,IAC/C;AAAC,GACH;AAEA,EAAA,IAAI,CAAC,aAAe,EAAA;AAClB,IAAA,OAAO,QAAQ,MAAW,KAAA,YAAA,mBACvB,IAAA,CAAA,IAAA,EAAA,EAAK,SAAQ,MACX,EAAA,QAAA,EAAA;AAAA,MAAA,SAAA,oBAAc,GAAA,CAAA,MAAA,EAAA,EAAO,KAAO,EAAA,CAAA,CAAE,YAAY,CAAG,EAAA,CAAA;AAAA,0BAC7C,OACC,EAAA,EAAA,QAAA,kBAAA,GAAA,CAAC,+BACC,QAAC,kBAAA,GAAA,CAAA,SAAA,EAAA,EAAU,GACb,CACF,EAAA;AAAA,KAAA,EACF,oBAEC,GAAA,CAAA,SAAA,EAAA,EAAU,aAAe,EAAA,CAAA,CAAE,iBAAiB,CAAG,EAAA,CAAA;AAAA;AAGpD,EAAA,2BAAQ,QAAS,EAAA,EAAA,CAAA;AACnB;;;;"}
@@ -7,6 +7,8 @@ import CardHeader from '@mui/material/CardHeader';
7
7
  import Grid from '@mui/material/Grid';
8
8
  import { makeStyles } from '@mui/styles';
9
9
  import { useRole } from '../../hooks/useRole.esm.js';
10
+ import { useTranslation } from '../../hooks/useTranslation.esm.js';
11
+ import { useLanguage } from '../../hooks/useLanguage.esm.js';
10
12
 
11
13
  const useStyles = makeStyles({
12
14
  text: {
@@ -14,6 +16,8 @@ const useStyles = makeStyles({
14
16
  }
15
17
  });
16
18
  const AboutCard = ({ roleName }) => {
19
+ const { t } = useTranslation();
20
+ const locale = useLanguage();
17
21
  const classes = useStyles();
18
22
  const { role, roleError, loading } = useRole(roleName);
19
23
  if (loading) {
@@ -22,13 +26,13 @@ const AboutCard = ({ roleName }) => {
22
26
  let lastModified = role?.metadata?.lastModified;
23
27
  if (lastModified) {
24
28
  const date = new Date(lastModified);
25
- const time = date.toLocaleString("en-US", {
29
+ const time = date.toLocaleString(locale ?? "en", {
26
30
  hour: "2-digit",
27
31
  minute: "2-digit",
28
32
  hour12: false,
29
33
  timeZone: "UTC"
30
34
  });
31
- lastModified = `${date.getUTCDate()} ${date.toLocaleString("default", {
35
+ lastModified = `${date.getUTCDate()} ${date.toLocaleString(locale ?? "en", {
32
36
  month: "short"
33
37
  })} ${date.getUTCFullYear()}, ${time}`;
34
38
  } else {
@@ -48,7 +52,7 @@ const AboutCard = ({ roleName }) => {
48
52
  marginBottom: "10px"
49
53
  },
50
54
  children: [
51
- /* @__PURE__ */ jsx(CardHeader, { title: "About" }),
55
+ /* @__PURE__ */ jsx(CardHeader, { title: t("common.about") }),
52
56
  /* @__PURE__ */ jsx(
53
57
  CardContent,
54
58
  {
@@ -59,32 +63,32 @@ const AboutCard = ({ roleName }) => {
59
63
  WarningPanel,
60
64
  {
61
65
  message: roleError?.message,
62
- title: "Something went wrong while fetching role",
66
+ title: t("errors.fetchRole"),
63
67
  severity: "error"
64
68
  }
65
69
  ) }) : /* @__PURE__ */ jsxs(Grid, { container: true, spacing: 2, children: [
66
- /* @__PURE__ */ jsx(Grid, { item: true, xs: 3, sm: 6, lg: 3, children: /* @__PURE__ */ jsx(AboutField, { label: "Description", children: /* @__PURE__ */ jsx(
70
+ /* @__PURE__ */ jsx(Grid, { item: true, xs: 3, sm: 6, lg: 3, children: /* @__PURE__ */ jsx(AboutField, { label: t("common.description"), children: /* @__PURE__ */ jsx(
67
71
  MarkdownContent,
68
72
  {
69
73
  className: classes.text,
70
74
  content: description
71
75
  }
72
76
  ) }) }),
73
- /* @__PURE__ */ jsx(Grid, { item: true, xs: 3, sm: 6, lg: 3, children: /* @__PURE__ */ jsx(AboutField, { label: "Modified By", children: /* @__PURE__ */ jsx(
77
+ /* @__PURE__ */ jsx(Grid, { item: true, xs: 3, sm: 6, lg: 3, children: /* @__PURE__ */ jsx(AboutField, { label: t("common.modifiedBy"), children: /* @__PURE__ */ jsx(
74
78
  MarkdownContent,
75
79
  {
76
80
  className: classes.text,
77
81
  content: modifiedBy
78
82
  }
79
83
  ) }) }),
80
- /* @__PURE__ */ jsx(Grid, { item: true, xs: 3, sm: 6, lg: 3, children: /* @__PURE__ */ jsx(AboutField, { label: "Last Modified", children: /* @__PURE__ */ jsx(
84
+ /* @__PURE__ */ jsx(Grid, { item: true, xs: 3, sm: 6, lg: 3, children: /* @__PURE__ */ jsx(AboutField, { label: t("common.lastModified"), children: /* @__PURE__ */ jsx(
81
85
  MarkdownContent,
82
86
  {
83
87
  className: classes.text,
84
88
  content: lastModified
85
89
  }
86
90
  ) }) }),
87
- /* @__PURE__ */ jsx(Grid, { item: true, xs: 3, sm: 6, lg: 3, children: /* @__PURE__ */ jsx(AboutField, { label: "Owner", children: /* @__PURE__ */ jsx(MarkdownContent, { className: classes.text, content: owner }) }) })
91
+ /* @__PURE__ */ jsx(Grid, { item: true, xs: 3, sm: 6, lg: 3, children: /* @__PURE__ */ jsx(AboutField, { label: t("common.owner"), children: /* @__PURE__ */ jsx(MarkdownContent, { className: classes.text, content: owner }) }) })
88
92
  ] })
89
93
  }
90
94
  )
@@ -1 +1 @@
1
- {"version":3,"file":"AboutCard.esm.js","sources":["../../../src/components/RoleOverview/AboutCard.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 {\n MarkdownContent,\n Progress,\n WarningPanel,\n} from '@backstage/core-components';\nimport { AboutField } from '@backstage/plugin-catalog';\n\nimport Card from '@mui/material/Card';\nimport CardContent from '@mui/material/CardContent';\nimport CardHeader from '@mui/material/CardHeader';\nimport Grid from '@mui/material/Grid';\nimport { makeStyles } from '@mui/styles';\n\nimport { useRole } from '../../hooks/useRole';\n\nconst useStyles = makeStyles({\n text: {\n wordBreak: 'break-word',\n },\n});\n\ntype AboutCardProps = {\n roleName: string;\n};\n\nexport const AboutCard = ({ roleName }: AboutCardProps) => {\n const classes = useStyles();\n const { role, roleError, loading } = useRole(roleName);\n if (loading) {\n return <Progress />;\n }\n\n let lastModified = role?.metadata?.lastModified;\n if (lastModified) {\n const date = new Date(lastModified);\n const time = date.toLocaleString('en-US', {\n hour: '2-digit' as const,\n minute: '2-digit' as const,\n hour12: false,\n timeZone: 'UTC',\n });\n lastModified = `${date.getUTCDate()} ${date.toLocaleString('default', {\n month: 'short',\n })} ${date.getUTCFullYear()}, ${time}`;\n } else {\n lastModified = '--';\n }\n\n const description =\n role?.metadata?.description && role.metadata.description.length > 0\n ? role.metadata.description\n : '--';\n const modifiedBy =\n role?.metadata?.modifiedBy && role.metadata.modifiedBy.length > 0\n ? role.metadata.modifiedBy\n : '--';\n const owner =\n role?.metadata?.owner && role.metadata.owner.length > 0\n ? role.metadata.owner\n : '--';\n\n return (\n <Card\n sx={{\n display: 'flex',\n flexDirection: 'column',\n height: 'calc(100% - 10px)', // for pages without content header\n marginBottom: '10px',\n }}\n >\n <CardHeader title=\"About\" />\n <CardContent\n sx={{\n flex: 1,\n }}\n >\n {roleError.name ? (\n <div style={{ paddingBottom: '16px' }}>\n <WarningPanel\n message={roleError?.message}\n title=\"Something went wrong while fetching role\"\n severity=\"error\"\n />\n </div>\n ) : (\n <Grid container spacing={2}>\n <Grid item xs={3} sm={6} lg={3}>\n <AboutField label=\"Description\">\n <MarkdownContent\n className={classes.text}\n content={description}\n />\n </AboutField>\n </Grid>\n <Grid item xs={3} sm={6} lg={3}>\n <AboutField label=\"Modified By\">\n <MarkdownContent\n className={classes.text}\n content={modifiedBy}\n />\n </AboutField>\n </Grid>\n <Grid item xs={3} sm={6} lg={3}>\n <AboutField label=\"Last Modified\">\n <MarkdownContent\n className={classes.text}\n content={lastModified}\n />\n </AboutField>\n </Grid>\n <Grid item xs={3} sm={6} lg={3}>\n <AboutField label=\"Owner\">\n <MarkdownContent className={classes.text} content={owner} />\n </AboutField>\n </Grid>\n </Grid>\n )}\n </CardContent>\n </Card>\n );\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"AboutCard.esm.js","sources":["../../../src/components/RoleOverview/AboutCard.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 {\n MarkdownContent,\n Progress,\n WarningPanel,\n} from '@backstage/core-components';\nimport { AboutField } from '@backstage/plugin-catalog';\n\nimport Card from '@mui/material/Card';\nimport CardContent from '@mui/material/CardContent';\nimport CardHeader from '@mui/material/CardHeader';\nimport Grid from '@mui/material/Grid';\nimport { makeStyles } from '@mui/styles';\n\nimport { useRole } from '../../hooks/useRole';\nimport { useTranslation } from '../../hooks/useTranslation';\nimport { useLanguage } from '../../hooks/useLanguage';\n\nconst useStyles = makeStyles({\n text: {\n wordBreak: 'break-word',\n },\n});\n\ntype AboutCardProps = {\n roleName: string;\n};\n\nexport const AboutCard = ({ roleName }: AboutCardProps) => {\n const { t } = useTranslation();\n const locale = useLanguage();\n const classes = useStyles();\n const { role, roleError, loading } = useRole(roleName);\n if (loading) {\n return <Progress />;\n }\n\n let lastModified = role?.metadata?.lastModified;\n if (lastModified) {\n const date = new Date(lastModified);\n const time = date.toLocaleString(locale ?? 'en', {\n hour: '2-digit' as const,\n minute: '2-digit' as const,\n hour12: false,\n timeZone: 'UTC',\n });\n lastModified = `${date.getUTCDate()} ${date.toLocaleString(locale ?? 'en', {\n month: 'short',\n })} ${date.getUTCFullYear()}, ${time}`;\n } else {\n lastModified = '--';\n }\n\n const description =\n role?.metadata?.description && role.metadata.description.length > 0\n ? role.metadata.description\n : '--';\n const modifiedBy =\n role?.metadata?.modifiedBy && role.metadata.modifiedBy.length > 0\n ? role.metadata.modifiedBy\n : '--';\n const owner =\n role?.metadata?.owner && role.metadata.owner.length > 0\n ? role.metadata.owner\n : '--';\n\n return (\n <Card\n sx={{\n display: 'flex',\n flexDirection: 'column',\n height: 'calc(100% - 10px)', // for pages without content header\n marginBottom: '10px',\n }}\n >\n <CardHeader title={t('common.about')} />\n <CardContent\n sx={{\n flex: 1,\n }}\n >\n {roleError.name ? (\n <div style={{ paddingBottom: '16px' }}>\n <WarningPanel\n message={roleError?.message}\n title={t('errors.fetchRole')}\n severity=\"error\"\n />\n </div>\n ) : (\n <Grid container spacing={2}>\n <Grid item xs={3} sm={6} lg={3}>\n <AboutField label={t('common.description')}>\n <MarkdownContent\n className={classes.text}\n content={description}\n />\n </AboutField>\n </Grid>\n <Grid item xs={3} sm={6} lg={3}>\n <AboutField label={t('common.modifiedBy')}>\n <MarkdownContent\n className={classes.text}\n content={modifiedBy}\n />\n </AboutField>\n </Grid>\n <Grid item xs={3} sm={6} lg={3}>\n <AboutField label={t('common.lastModified')}>\n <MarkdownContent\n className={classes.text}\n content={lastModified}\n />\n </AboutField>\n </Grid>\n <Grid item xs={3} sm={6} lg={3}>\n <AboutField label={t('common.owner')}>\n <MarkdownContent className={classes.text} content={owner} />\n </AboutField>\n </Grid>\n </Grid>\n )}\n </CardContent>\n </Card>\n );\n};\n"],"names":[],"mappings":"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"}