@strapi/plugin-users-permissions 0.0.0-next.ce51df0e18404afc8a1aa7f504c1006a7a221459 → 0.0.0-next.ce84fada19d58a7dfbdd553035e6558f8befcba4

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 (194) hide show
  1. package/.eslintignore +1 -2
  2. package/.eslintrc +17 -0
  3. package/LICENSE +18 -3
  4. package/admin/src/components/BoundRoute/{index.js → index.jsx} +2 -2
  5. package/admin/src/components/FormModal/Input/{index.js → index.jsx} +32 -31
  6. package/admin/src/components/FormModal/index.jsx +115 -0
  7. package/admin/src/components/Permissions/PermissionRow/{CheckboxWrapper.js → CheckboxWrapper.jsx} +4 -3
  8. package/admin/src/components/Permissions/PermissionRow/{SubCategory.js → SubCategory.jsx} +13 -22
  9. package/admin/src/components/Permissions/index.jsx +47 -0
  10. package/admin/src/components/Permissions/reducer.js +1 -1
  11. package/admin/src/components/Policies/{index.js → index.jsx} +7 -5
  12. package/admin/src/components/UsersPermissions/{index.js → index.jsx} +15 -7
  13. package/admin/src/components/UsersPermissions/reducer.js +1 -1
  14. package/admin/src/index.js +14 -23
  15. package/admin/src/pages/AdvancedSettings/index.jsx +214 -0
  16. package/admin/src/pages/AdvancedSettings/utils/layout.js +20 -35
  17. package/admin/src/pages/AdvancedSettings/utils/schema.js +5 -2
  18. package/admin/src/pages/EmailTemplates/components/EmailForm.jsx +156 -0
  19. package/admin/src/pages/EmailTemplates/components/{EmailTable.js → EmailTable.jsx} +20 -17
  20. package/admin/src/pages/EmailTemplates/{index.js → index.jsx} +36 -62
  21. package/admin/src/pages/EmailTemplates/utils/schema.js +18 -6
  22. package/admin/src/pages/Providers/{index.js → index.jsx} +98 -113
  23. package/admin/src/pages/Providers/utils/forms.js +11 -11
  24. package/admin/src/pages/Roles/constants.js +3 -3
  25. package/admin/src/pages/Roles/hooks/usePlugins.js +4 -4
  26. package/admin/src/pages/Roles/index.jsx +24 -0
  27. package/admin/src/pages/Roles/pages/{CreatePage.js → CreatePage.jsx} +64 -60
  28. package/admin/src/pages/Roles/pages/{EditPage.js → EditPage.jsx} +73 -69
  29. package/admin/src/pages/Roles/pages/ListPage/components/{TableBody.js → TableBody.jsx} +27 -31
  30. package/admin/src/pages/Roles/pages/ListPage/{index.js → index.jsx} +81 -55
  31. package/admin/src/translations/en.json +1 -1
  32. package/admin/src/utils/prefixPluginTranslations.js +13 -0
  33. package/dist/_chunks/ar-BguGUqwK.js +44 -0
  34. package/dist/_chunks/ar-BguGUqwK.js.map +1 -0
  35. package/dist/_chunks/ar-CK8BRRXB.mjs +44 -0
  36. package/dist/_chunks/ar-CK8BRRXB.mjs.map +1 -0
  37. package/dist/_chunks/cs-BVigMk0l.mjs +50 -0
  38. package/dist/_chunks/cs-BVigMk0l.mjs.map +1 -0
  39. package/dist/_chunks/cs-BW8-K_GY.js +50 -0
  40. package/dist/_chunks/cs-BW8-K_GY.js.map +1 -0
  41. package/dist/_chunks/de-BKUdRFI4.mjs +62 -0
  42. package/dist/_chunks/de-BKUdRFI4.mjs.map +1 -0
  43. package/dist/_chunks/de-owXpVluI.js +62 -0
  44. package/dist/_chunks/de-owXpVluI.js.map +1 -0
  45. package/dist/_chunks/dk-BQiTK50l.mjs +86 -0
  46. package/dist/_chunks/dk-BQiTK50l.mjs.map +1 -0
  47. package/dist/_chunks/dk-LXAnbuBk.js +86 -0
  48. package/dist/_chunks/dk-LXAnbuBk.js.map +1 -0
  49. package/dist/_chunks/en-DOHtPf-2.mjs +86 -0
  50. package/dist/_chunks/en-DOHtPf-2.mjs.map +1 -0
  51. package/dist/_chunks/en-MHo5mcsU.js +86 -0
  52. package/dist/_chunks/en-MHo5mcsU.js.map +1 -0
  53. package/dist/_chunks/es-BwLCLXAQ.js +86 -0
  54. package/dist/_chunks/es-BwLCLXAQ.js.map +1 -0
  55. package/dist/_chunks/es-DNgOVMjD.mjs +86 -0
  56. package/dist/_chunks/es-DNgOVMjD.mjs.map +1 -0
  57. package/dist/_chunks/fr-DkgRugiU.mjs +50 -0
  58. package/dist/_chunks/fr-DkgRugiU.mjs.map +1 -0
  59. package/dist/_chunks/fr-DkhpSjjm.js +50 -0
  60. package/dist/_chunks/fr-DkhpSjjm.js.map +1 -0
  61. package/dist/_chunks/id-BTemOeTZ.js +62 -0
  62. package/dist/_chunks/id-BTemOeTZ.js.map +1 -0
  63. package/dist/_chunks/id-BdEsvnaF.mjs +62 -0
  64. package/dist/_chunks/id-BdEsvnaF.mjs.map +1 -0
  65. package/dist/_chunks/index-BOrMKeRw.mjs +249 -0
  66. package/dist/_chunks/index-BOrMKeRw.mjs.map +1 -0
  67. package/dist/_chunks/index-Belq5KbY.js +1173 -0
  68. package/dist/_chunks/index-Belq5KbY.js.map +1 -0
  69. package/dist/_chunks/index-Bz6iwjmq.mjs +615 -0
  70. package/dist/_chunks/index-Bz6iwjmq.mjs.map +1 -0
  71. package/dist/_chunks/index-CD4fcjMf.js +638 -0
  72. package/dist/_chunks/index-CD4fcjMf.js.map +1 -0
  73. package/dist/_chunks/index-CNonxjKA.js +281 -0
  74. package/dist/_chunks/index-CNonxjKA.js.map +1 -0
  75. package/dist/_chunks/index-CuNna9c6.mjs +262 -0
  76. package/dist/_chunks/index-CuNna9c6.mjs.map +1 -0
  77. package/dist/_chunks/index-D5NoyXgv.js +366 -0
  78. package/dist/_chunks/index-D5NoyXgv.js.map +1 -0
  79. package/dist/_chunks/index-DGJ3FzF4.js +248 -0
  80. package/dist/_chunks/index-DGJ3FzF4.js.map +1 -0
  81. package/dist/_chunks/index-DThn8eCU.mjs +1143 -0
  82. package/dist/_chunks/index-DThn8eCU.mjs.map +1 -0
  83. package/dist/_chunks/index-Dk2iD2AC.mjs +344 -0
  84. package/dist/_chunks/index-Dk2iD2AC.mjs.map +1 -0
  85. package/dist/_chunks/index-TfyEeDrd-BfJxOAzF.mjs +11845 -0
  86. package/dist/_chunks/index-TfyEeDrd-BfJxOAzF.mjs.map +1 -0
  87. package/dist/_chunks/index-TfyEeDrd-QiBdpWEj.js +11869 -0
  88. package/dist/_chunks/index-TfyEeDrd-QiBdpWEj.js.map +1 -0
  89. package/dist/_chunks/it-B-rv0E24.mjs +62 -0
  90. package/dist/_chunks/it-B-rv0E24.mjs.map +1 -0
  91. package/dist/_chunks/it-D1rH6V6_.js +62 -0
  92. package/dist/_chunks/it-D1rH6V6_.js.map +1 -0
  93. package/dist/_chunks/ja-C8K-VBPD.mjs +48 -0
  94. package/dist/_chunks/ja-C8K-VBPD.mjs.map +1 -0
  95. package/dist/_chunks/ja-DqShgTMf.js +48 -0
  96. package/dist/_chunks/ja-DqShgTMf.js.map +1 -0
  97. package/dist/_chunks/ko-B9DGEPWH.js +86 -0
  98. package/dist/_chunks/ko-B9DGEPWH.js.map +1 -0
  99. package/dist/_chunks/ko-Busb0wIY.mjs +86 -0
  100. package/dist/_chunks/ko-Busb0wIY.mjs.map +1 -0
  101. package/dist/_chunks/ms-ByvsQjRt.mjs +49 -0
  102. package/dist/_chunks/ms-ByvsQjRt.mjs.map +1 -0
  103. package/dist/_chunks/ms-CPBU3LWf.js +49 -0
  104. package/dist/_chunks/ms-CPBU3LWf.js.map +1 -0
  105. package/dist/_chunks/nl-5qO8Rpcy.mjs +48 -0
  106. package/dist/_chunks/nl-5qO8Rpcy.mjs.map +1 -0
  107. package/dist/_chunks/nl-CwNB6YoO.js +48 -0
  108. package/dist/_chunks/nl-CwNB6YoO.js.map +1 -0
  109. package/dist/_chunks/pl-BdIzifBE.mjs +86 -0
  110. package/dist/_chunks/pl-BdIzifBE.mjs.map +1 -0
  111. package/dist/_chunks/pl-Do9UD69f.js +86 -0
  112. package/dist/_chunks/pl-Do9UD69f.js.map +1 -0
  113. package/dist/_chunks/pt-BIO24ioG.mjs +48 -0
  114. package/dist/_chunks/pt-BIO24ioG.mjs.map +1 -0
  115. package/dist/_chunks/pt-BR-D7dZhxuP.js +44 -0
  116. package/dist/_chunks/pt-BR-D7dZhxuP.js.map +1 -0
  117. package/dist/_chunks/pt-BR-f0p23AQZ.mjs +44 -0
  118. package/dist/_chunks/pt-BR-f0p23AQZ.mjs.map +1 -0
  119. package/dist/_chunks/pt-fdvyOnUp.js +48 -0
  120. package/dist/_chunks/pt-fdvyOnUp.js.map +1 -0
  121. package/dist/_chunks/ru-C94rjPGA.js +86 -0
  122. package/dist/_chunks/ru-C94rjPGA.js.map +1 -0
  123. package/dist/_chunks/ru-VWy-IB7K.mjs +86 -0
  124. package/dist/_chunks/ru-VWy-IB7K.mjs.map +1 -0
  125. package/dist/_chunks/sk-BABEhykl.js +50 -0
  126. package/dist/_chunks/sk-BABEhykl.js.map +1 -0
  127. package/dist/_chunks/sk-B_LIcepm.mjs +50 -0
  128. package/dist/_chunks/sk-B_LIcepm.mjs.map +1 -0
  129. package/dist/_chunks/sv-ABLKOokl.mjs +86 -0
  130. package/dist/_chunks/sv-ABLKOokl.mjs.map +1 -0
  131. package/dist/_chunks/sv-Be43LhA9.js +86 -0
  132. package/dist/_chunks/sv-Be43LhA9.js.map +1 -0
  133. package/dist/_chunks/th-DKyP7ueR.mjs +60 -0
  134. package/dist/_chunks/th-DKyP7ueR.mjs.map +1 -0
  135. package/dist/_chunks/th-DgVhVLhL.js +60 -0
  136. package/dist/_chunks/th-DgVhVLhL.js.map +1 -0
  137. package/dist/_chunks/tr-B_idhkEs.js +85 -0
  138. package/dist/_chunks/tr-B_idhkEs.js.map +1 -0
  139. package/dist/_chunks/tr-qa1Q5UjC.mjs +85 -0
  140. package/dist/_chunks/tr-qa1Q5UjC.mjs.map +1 -0
  141. package/dist/_chunks/uk-BmRqbeQc.mjs +49 -0
  142. package/dist/_chunks/uk-BmRqbeQc.mjs.map +1 -0
  143. package/dist/_chunks/uk-LHOivnhP.js +49 -0
  144. package/dist/_chunks/uk-LHOivnhP.js.map +1 -0
  145. package/dist/_chunks/vi-CdVRdKDw.js +50 -0
  146. package/dist/_chunks/vi-CdVRdKDw.js.map +1 -0
  147. package/dist/_chunks/vi-HW-EdMea.mjs +50 -0
  148. package/dist/_chunks/vi-HW-EdMea.mjs.map +1 -0
  149. package/dist/_chunks/zh-5hKkVPA4.mjs +86 -0
  150. package/dist/_chunks/zh-5hKkVPA4.mjs.map +1 -0
  151. package/dist/_chunks/zh-Cuq8gMnF.js +86 -0
  152. package/dist/_chunks/zh-Cuq8gMnF.js.map +1 -0
  153. package/dist/_chunks/zh-Hans-BHilK-yc.mjs +86 -0
  154. package/dist/_chunks/zh-Hans-BHilK-yc.mjs.map +1 -0
  155. package/dist/_chunks/zh-Hans-GQDMKtY4.js +86 -0
  156. package/dist/_chunks/zh-Hans-GQDMKtY4.js.map +1 -0
  157. package/dist/admin/index.js +4 -0
  158. package/dist/admin/index.js.map +1 -0
  159. package/dist/admin/index.mjs +5 -0
  160. package/dist/admin/index.mjs.map +1 -0
  161. package/package.json +46 -27
  162. package/packup.config.ts +22 -0
  163. package/server/bootstrap/index.js +18 -50
  164. package/server/bootstrap/users-permissions-actions.js +6 -0
  165. package/server/config.js +29 -0
  166. package/server/content-types/user/index.js +0 -1
  167. package/server/controllers/auth.js +53 -60
  168. package/server/controllers/content-manager-user.js +28 -30
  169. package/server/controllers/role.js +1 -1
  170. package/server/controllers/user.js +8 -9
  171. package/server/middlewares/rateLimit.js +1 -1
  172. package/server/register.js +1 -1
  173. package/server/services/jwt.js +3 -3
  174. package/server/services/permission.js +3 -7
  175. package/server/services/providers-registry.js +469 -261
  176. package/server/services/providers.js +10 -5
  177. package/server/services/role.js +15 -13
  178. package/server/services/user.js +56 -19
  179. package/server/services/users-permissions.js +15 -13
  180. package/server/utils/index.d.ts +2 -1
  181. package/server/utils/sanitize/sanitizers.js +7 -3
  182. package/server/utils/sanitize/visitors/remove-user-relation-from-role-entities.js +2 -2
  183. package/.eslintrc.js +0 -14
  184. package/admin/src/components/FormModal/index.js +0 -126
  185. package/admin/src/components/Permissions/index.js +0 -55
  186. package/admin/src/pages/AdvancedSettings/index.js +0 -259
  187. package/admin/src/pages/EmailTemplates/components/EmailForm.js +0 -176
  188. package/admin/src/pages/Roles/index.js +0 -33
  189. package/admin/src/pages/Roles/pages/ListPage/utils/api.js +0 -30
  190. package/server/bootstrap/grant-config.js +0 -131
  191. package/strapi-admin.js +0 -3
  192. package/strapi-server.js +0 -3
  193. /package/admin/src/components/Permissions/PermissionRow/{index.js → index.jsx} +0 -0
  194. /package/admin/src/contexts/UsersPermissionsContext/{index.js → index.jsx} +0 -0
@@ -2,30 +2,20 @@ import * as React from 'react';
2
2
 
3
3
  import {
4
4
  Button,
5
- ContentLayout,
6
5
  Flex,
7
6
  Grid,
8
- GridItem,
9
- HeaderLayout,
10
7
  Main,
11
8
  Textarea,
12
9
  TextInput,
13
10
  Typography,
11
+ Field,
14
12
  } from '@strapi/design-system';
15
- import {
16
- CheckPagePermissions,
17
- Form,
18
- SettingsPageTitle,
19
- useFetchClient,
20
- useNotification,
21
- useOverlayBlocker,
22
- useTracking,
23
- } from '@strapi/helper-plugin';
24
13
  import { Check } from '@strapi/icons';
25
- import { Formik } from 'formik';
14
+ import { Page, useTracking, useNotification, useFetchClient, Layouts } from '@strapi/strapi/admin';
15
+ import { Formik, Form } from 'formik';
26
16
  import { useIntl } from 'react-intl';
27
17
  import { useMutation } from 'react-query';
28
- import { useHistory } from 'react-router-dom';
18
+ import { useNavigate } from 'react-router-dom';
29
19
 
30
20
  import UsersPermissions from '../../../components/UsersPermissions';
31
21
  import { PERMISSIONS } from '../../../constants';
@@ -35,9 +25,8 @@ import { usePlugins } from '../hooks/usePlugins';
35
25
 
36
26
  export const CreatePage = () => {
37
27
  const { formatMessage } = useIntl();
38
- const toggleNotification = useNotification();
39
- const { goBack } = useHistory();
40
- const { lockApp, unlockApp } = useOverlayBlocker();
28
+ const { toggleNotification } = useNotification();
29
+ const navigate = useNavigate();
41
30
  const { isLoading: isLoadingPlugins, permissions, routes } = usePlugins();
42
31
  const { trackUsage } = useTracking();
43
32
  const permissionsRef = React.useRef();
@@ -45,11 +34,11 @@ export const CreatePage = () => {
45
34
  const mutation = useMutation((body) => post(`/users-permissions/roles`, body), {
46
35
  onError() {
47
36
  toggleNotification({
48
- type: 'warning',
49
- message: {
37
+ type: 'danger',
38
+ message: formatMessage({
50
39
  id: 'notification.error',
51
40
  defaultMessage: 'An error occurred',
52
- },
41
+ }),
53
42
  });
54
43
  },
55
44
 
@@ -58,34 +47,34 @@ export const CreatePage = () => {
58
47
 
59
48
  toggleNotification({
60
49
  type: 'success',
61
- message: {
50
+ message: formatMessage({
62
51
  id: getTrad('Settings.roles.created'),
63
52
  defaultMessage: 'Role created',
64
- },
53
+ }),
65
54
  });
66
55
 
67
56
  // Forcing redirecting since we don't have the id in the response
68
- goBack();
57
+ navigate(-1);
69
58
  },
70
59
  });
71
60
 
72
61
  const handleCreateRoleSubmit = async (data) => {
73
- lockApp();
74
-
75
62
  // TODO: refactor. Child -> parent component communication is evil;
76
63
  // We should either move the provider one level up or move the state
77
64
  // straight into redux.
78
65
  const permissions = permissionsRef.current.getPermissions();
79
66
 
80
67
  await mutation.mutate({ ...data, ...permissions, users: [] });
81
-
82
- unlockApp();
83
68
  };
84
69
 
85
70
  return (
86
71
  <Main>
87
- {/* TODO: This needs to be translated */}
88
- <SettingsPageTitle name="Roles" />
72
+ <Page.Title>
73
+ {formatMessage(
74
+ { id: 'Settings.PageTitle', defaultMessage: 'Settings - {name}' },
75
+ { name: 'Roles' }
76
+ )}
77
+ </Page.Title>
89
78
  <Formik
90
79
  enableReinitialize
91
80
  initialValues={{ name: '', description: '' }}
@@ -94,7 +83,7 @@ export const CreatePage = () => {
94
83
  >
95
84
  {({ handleSubmit, values, handleChange, errors }) => (
96
85
  <Form noValidate onSubmit={handleSubmit}>
97
- <HeaderLayout
86
+ <Layouts.Header
98
87
  primaryAction={
99
88
  !isLoadingPlugins && (
100
89
  <Button type="submit" loading={mutation.isLoading} startIcon={<Check />}>
@@ -114,7 +103,7 @@ export const CreatePage = () => {
114
103
  defaultMessage: 'Define the rights given to the role',
115
104
  })}
116
105
  />
117
- <ContentLayout>
106
+ <Layouts.Content>
118
107
  <Flex
119
108
  background="neutral0"
120
109
  direction="column"
@@ -128,43 +117,58 @@ export const CreatePage = () => {
128
117
  shadow="filterShadow"
129
118
  >
130
119
  <Flex direction="column" alignItems="stretch">
131
- <Typography variant="delta" as="h2">
120
+ <Typography variant="delta" tag="h2">
132
121
  {formatMessage({
133
122
  id: getTrad('EditPage.form.roles'),
134
123
  defaultMessage: 'Role details',
135
124
  })}
136
125
  </Typography>
137
126
 
138
- <Grid gap={4}>
139
- <GridItem col={6}>
140
- <TextInput
127
+ <Grid.Root gap={4}>
128
+ <Grid.Item col={6} direction="column" alignItems="stretch">
129
+ <Field.Root
141
130
  name="name"
142
- value={values.name || ''}
143
- onChange={handleChange}
144
- label={formatMessage({
145
- id: 'global.name',
146
- defaultMessage: 'Name',
147
- })}
148
- error={errors?.name ? formatMessage({ id: errors.name }) : false}
131
+ error={
132
+ errors?.name
133
+ ? formatMessage({ id: errors.name, defaultMessage: 'Name is required' })
134
+ : false
135
+ }
149
136
  required
150
- />
151
- </GridItem>
152
- <GridItem col={6}>
153
- <Textarea
154
- id="description"
155
- value={values.description || ''}
156
- onChange={handleChange}
157
- label={formatMessage({
158
- id: 'global.description',
159
- defaultMessage: 'Description',
160
- })}
137
+ >
138
+ <Field.Label>
139
+ {formatMessage({
140
+ id: 'global.name',
141
+ defaultMessage: 'Name',
142
+ })}
143
+ </Field.Label>
144
+ <TextInput value={values.name || ''} onChange={handleChange} />
145
+ <Field.Error />
146
+ </Field.Root>
147
+ </Grid.Item>
148
+ <Grid.Item col={6} direction="column" alignItems="stretch">
149
+ <Field.Root
150
+ name="description"
161
151
  error={
162
- errors?.description ? formatMessage({ id: errors.description }) : false
152
+ errors?.description
153
+ ? formatMessage({
154
+ id: errors.description,
155
+ defaultMessage: 'Description is required',
156
+ })
157
+ : false
163
158
  }
164
159
  required
165
- />
166
- </GridItem>
167
- </Grid>
160
+ >
161
+ <Field.Label>
162
+ {formatMessage({
163
+ id: 'global.description',
164
+ defaultMessage: 'Description',
165
+ })}
166
+ </Field.Label>
167
+ <Textarea value={values.description || ''} onChange={handleChange} />
168
+ <Field.Error />
169
+ </Field.Root>
170
+ </Grid.Item>
171
+ </Grid.Root>
168
172
  </Flex>
169
173
 
170
174
  {!isLoadingPlugins && (
@@ -175,7 +179,7 @@ export const CreatePage = () => {
175
179
  />
176
180
  )}
177
181
  </Flex>
178
- </ContentLayout>
182
+ </Layouts.Content>
179
183
  </Form>
180
184
  )}
181
185
  </Formik>
@@ -184,7 +188,7 @@ export const CreatePage = () => {
184
188
  };
185
189
 
186
190
  export const ProtectedRolesCreatePage = () => (
187
- <CheckPagePermissions permissions={PERMISSIONS.createRole}>
191
+ <Page.Protect permissions={PERMISSIONS.createRole}>
188
192
  <CreatePage />
189
- </CheckPagePermissions>
193
+ </Page.Protect>
190
194
  );
@@ -1,33 +1,28 @@
1
1
  import * as React from 'react';
2
2
 
3
3
  import {
4
- ContentLayout,
5
- HeaderLayout,
6
4
  Main,
7
5
  Button,
8
6
  Flex,
9
7
  TextInput,
10
8
  Textarea,
11
9
  Typography,
12
- GridItem,
13
10
  Grid,
11
+ Field,
14
12
  } from '@strapi/design-system';
13
+ import { Check } from '@strapi/icons';
15
14
  import {
16
- CheckPagePermissions,
17
- useOverlayBlocker,
18
- SettingsPageTitle,
19
- LoadingIndicatorPage,
20
- Form,
15
+ Page,
16
+ BackButton,
21
17
  useAPIErrorHandler,
22
- useFetchClient,
23
18
  useNotification,
24
- Link,
25
- } from '@strapi/helper-plugin';
26
- import { ArrowLeft, Check } from '@strapi/icons';
27
- import { Formik } from 'formik';
19
+ useFetchClient,
20
+ Layouts,
21
+ } from '@strapi/strapi/admin';
22
+ import { Formik, Form } from 'formik';
28
23
  import { useIntl } from 'react-intl';
29
24
  import { useQuery, useMutation } from 'react-query';
30
- import { useRouteMatch } from 'react-router-dom';
25
+ import { useMatch } from 'react-router-dom';
31
26
 
32
27
  import UsersPermissions from '../../../components/UsersPermissions';
33
28
  import { PERMISSIONS } from '../../../constants';
@@ -37,11 +32,10 @@ import { usePlugins } from '../hooks/usePlugins';
37
32
 
38
33
  export const EditPage = () => {
39
34
  const { formatMessage } = useIntl();
40
- const toggleNotification = useNotification();
41
- const { lockApp, unlockApp } = useOverlayBlocker();
35
+ const { toggleNotification } = useNotification();
42
36
  const {
43
37
  params: { id },
44
- } = useRouteMatch(`/settings/users-permissions/roles/:id`);
38
+ } = useMatch(`/settings/users-permissions/roles/:id`);
45
39
  const { get } = useFetchClient();
46
40
  const { isLoading: isLoadingPlugins, routes } = usePlugins();
47
41
  const {
@@ -63,7 +57,7 @@ export const EditPage = () => {
63
57
  const mutation = useMutation((body) => put(`/users-permissions/roles/${id}`, body), {
64
58
  onError(error) {
65
59
  toggleNotification({
66
- type: 'warning',
60
+ type: 'danger',
67
61
  message: formatAPIError(error),
68
62
  });
69
63
  },
@@ -71,10 +65,10 @@ export const EditPage = () => {
71
65
  async onSuccess() {
72
66
  toggleNotification({
73
67
  type: 'success',
74
- message: {
68
+ message: formatMessage({
75
69
  id: getTrad('Settings.roles.created'),
76
70
  defaultMessage: 'Role edited',
77
- },
71
+ }),
78
72
  });
79
73
 
80
74
  await refetchRole();
@@ -82,24 +76,23 @@ export const EditPage = () => {
82
76
  });
83
77
 
84
78
  const handleEditRoleSubmit = async (data) => {
85
- // Set loading state
86
- lockApp();
87
-
88
79
  const permissions = permissionsRef.current.getPermissions();
89
80
 
90
81
  await mutation.mutate({ ...data, ...permissions, users: [] });
91
-
92
- unlockApp();
93
82
  };
94
83
 
95
84
  if (isLoadingRole) {
96
- return <LoadingIndicatorPage />;
85
+ return <Page.Loading />;
97
86
  }
98
87
 
99
88
  return (
100
89
  <Main>
101
- {/* TODO: this needs to be translated */}
102
- <SettingsPageTitle name="Roles" />
90
+ <Page.Title>
91
+ {formatMessage(
92
+ { id: 'Settings.PageTitle', defaultMessage: 'Settings - {name}' },
93
+ { name: 'Roles' }
94
+ )}
95
+ </Page.Title>
103
96
  <Formik
104
97
  enableReinitialize
105
98
  initialValues={{ name: role.name, description: role.description }}
@@ -108,9 +101,9 @@ export const EditPage = () => {
108
101
  >
109
102
  {({ handleSubmit, values, handleChange, errors }) => (
110
103
  <Form noValidate onSubmit={handleSubmit}>
111
- <HeaderLayout
104
+ <Layouts.Header
112
105
  primaryAction={
113
- !isLoadingPlugins && (
106
+ !isLoadingPlugins ? (
114
107
  <Button
115
108
  disabled={role.code === 'strapi-super-admin'}
116
109
  type="submit"
@@ -122,20 +115,13 @@ export const EditPage = () => {
122
115
  defaultMessage: 'Save',
123
116
  })}
124
117
  </Button>
125
- )
118
+ ) : null
126
119
  }
127
120
  title={role.name}
128
121
  subtitle={role.description}
129
- navigationAction={
130
- <Link startIcon={<ArrowLeft />} to="/settings/users-permissions/roles">
131
- {formatMessage({
132
- id: 'global.back',
133
- defaultMessage: 'Back',
134
- })}
135
- </Link>
136
- }
122
+ navigationAction={<BackButton />}
137
123
  />
138
- <ContentLayout>
124
+ <Layouts.Content>
139
125
  <Flex
140
126
  background="neutral0"
141
127
  direction="column"
@@ -149,43 +135,61 @@ export const EditPage = () => {
149
135
  shadow="filterShadow"
150
136
  >
151
137
  <Flex direction="column" alignItems="stretch" gap={4}>
152
- <Typography variant="delta" as="h2">
138
+ <Typography variant="delta" tag="h2">
153
139
  {formatMessage({
154
140
  id: getTrad('EditPage.form.roles'),
155
141
  defaultMessage: 'Role details',
156
142
  })}
157
143
  </Typography>
158
144
 
159
- <Grid gap={4}>
160
- <GridItem col={6}>
161
- <TextInput
145
+ <Grid.Root gap={4}>
146
+ <Grid.Item col={6} direction="column" alignItems="stretch">
147
+ <Field.Root
162
148
  name="name"
163
- value={values.name || ''}
164
- onChange={handleChange}
165
- label={formatMessage({
166
- id: 'global.name',
167
- defaultMessage: 'Name',
168
- })}
169
- error={errors?.name ? formatMessage({ id: errors.name }) : false}
149
+ error={
150
+ errors?.name
151
+ ? formatMessage({
152
+ id: errors.name,
153
+ defaultMessage: 'Name is required',
154
+ })
155
+ : false
156
+ }
170
157
  required
171
- />
172
- </GridItem>
173
- <GridItem col={6}>
174
- <Textarea
175
- id="description"
176
- value={values.description || ''}
177
- onChange={handleChange}
178
- label={formatMessage({
179
- id: 'global.description',
180
- defaultMessage: 'Description',
181
- })}
158
+ >
159
+ <Field.Label>
160
+ {formatMessage({
161
+ id: 'global.name',
162
+ defaultMessage: 'Name',
163
+ })}
164
+ </Field.Label>
165
+ <TextInput value={values.name || ''} onChange={handleChange} />
166
+ <Field.Error />
167
+ </Field.Root>
168
+ </Grid.Item>
169
+ <Grid.Item col={6} direction="column" alignItems="stretch">
170
+ <Field.Root
171
+ name="description"
182
172
  error={
183
- errors?.description ? formatMessage({ id: errors.description }) : false
173
+ errors?.description
174
+ ? formatMessage({
175
+ id: errors.description,
176
+ defaultMessage: 'Description is required',
177
+ })
178
+ : false
184
179
  }
185
180
  required
186
- />
187
- </GridItem>
188
- </Grid>
181
+ >
182
+ <Field.Label>
183
+ {formatMessage({
184
+ id: 'global.description',
185
+ defaultMessage: 'Description',
186
+ })}
187
+ </Field.Label>
188
+ <Textarea value={values.description || ''} onChange={handleChange} />
189
+ <Field.Error />
190
+ </Field.Root>
191
+ </Grid.Item>
192
+ </Grid.Root>
189
193
  </Flex>
190
194
 
191
195
  {!isLoadingPlugins && (
@@ -196,7 +200,7 @@ export const EditPage = () => {
196
200
  />
197
201
  )}
198
202
  </Flex>
199
- </ContentLayout>
203
+ </Layouts.Content>
200
204
  </Form>
201
205
  )}
202
206
  </Formik>
@@ -205,7 +209,7 @@ export const EditPage = () => {
205
209
  };
206
210
 
207
211
  export const ProtectedRolesEditPage = () => (
208
- <CheckPagePermissions permissions={PERMISSIONS.updateRole}>
212
+ <Page.Protect permissions={PERMISSIONS.updateRole}>
209
213
  <EditPage />
210
- </CheckPagePermissions>
214
+ </Page.Protect>
211
215
  );
@@ -1,24 +1,23 @@
1
1
  import React from 'react';
2
2
 
3
3
  import { Flex, IconButton, Link, Tbody, Td, Tr, Typography } from '@strapi/design-system';
4
- import { CheckPermissions, onRowClick, pxToRem, stopPropagation } from '@strapi/helper-plugin';
5
4
  import { Pencil, Trash } from '@strapi/icons';
6
5
  import PropTypes from 'prop-types';
7
6
  import { useIntl } from 'react-intl';
8
- import { useHistory } from 'react-router-dom';
9
- import styled from 'styled-components';
7
+ import { useNavigate, NavLink } from 'react-router-dom';
8
+ import { styled } from 'styled-components';
10
9
 
11
10
  const EditLink = styled(Link)`
12
11
  align-items: center;
13
- height: ${pxToRem(32)};
12
+ height: 3.2rem;
13
+ width: 3.2rem;
14
14
  display: flex;
15
15
  justify-content: center;
16
- padding: ${({ theme }) => `${theme.spaces[2]}}`};
17
- width: ${pxToRem(32)};
16
+ padding: ${({ theme }) => `${theme.spaces[2]}`};
18
17
 
19
18
  svg {
20
- height: ${pxToRem(12)};
21
- width: ${pxToRem(12)};
19
+ height: 1.6rem;
20
+ width: 1.6rem;
22
21
 
23
22
  path {
24
23
  fill: ${({ theme }) => theme.colors.neutral500};
@@ -35,9 +34,9 @@ const EditLink = styled(Link)`
35
34
  }
36
35
  `;
37
36
 
38
- const TableBody = ({ sortedRoles, canDelete, permissions, setRoleToDelete, onDelete }) => {
37
+ const TableBody = ({ sortedRoles, canDelete, canUpdate, setRoleToDelete, onDelete }) => {
39
38
  const { formatMessage } = useIntl();
40
- const { push } = useHistory();
39
+ const navigate = useNavigate();
41
40
  const [showConfirmDelete, setShowConfirmDelete] = onDelete;
42
41
 
43
42
  const checkCanDeleteRole = (role) =>
@@ -48,14 +47,10 @@ const TableBody = ({ sortedRoles, canDelete, permissions, setRoleToDelete, onDel
48
47
  setShowConfirmDelete(!showConfirmDelete);
49
48
  };
50
49
 
51
- const handleClickEdit = (id) => {
52
- push(`/settings/users-permissions/roles/${id}`);
53
- };
54
-
55
50
  return (
56
51
  <Tbody>
57
52
  {sortedRoles?.map((role) => (
58
- <Tr key={role.name} {...onRowClick({ fn: () => handleClickEdit(role.id) })}>
53
+ <Tr key={role.name} onClick={() => navigate(role.id.toString())}>
59
54
  <Td width="20%">
60
55
  <Typography>{role.name}</Typography>
61
56
  </Td>
@@ -74,10 +69,11 @@ const TableBody = ({ sortedRoles, canDelete, permissions, setRoleToDelete, onDel
74
69
  </Typography>
75
70
  </Td>
76
71
  <Td>
77
- <Flex justifyContent="end" {...stopPropagation}>
78
- <CheckPermissions permissions={permissions.updateRole}>
72
+ <Flex justifyContent="end" onClick={(e) => e.stopPropagation()}>
73
+ {canUpdate ? (
79
74
  <EditLink
80
- to={`/settings/users-permissions/roles/${role.id}`}
75
+ tag={NavLink}
76
+ to={role.id.toString()}
81
77
  aria-label={formatMessage(
82
78
  { id: 'app.component.table.edit', defaultMessage: 'Edit {target}' },
83
79
  { target: `${role.name}` }
@@ -85,20 +81,19 @@ const TableBody = ({ sortedRoles, canDelete, permissions, setRoleToDelete, onDel
85
81
  >
86
82
  <Pencil />
87
83
  </EditLink>
88
- </CheckPermissions>
84
+ ) : null}
89
85
 
90
86
  {checkCanDeleteRole(role) && (
91
- <CheckPermissions permissions={permissions.deleteRole}>
92
- <IconButton
93
- onClick={() => handleClickDelete(role.id)}
94
- noBorder
95
- icon={<Trash />}
96
- label={formatMessage(
97
- { id: 'global.delete-target', defaultMessage: 'Delete {target}' },
98
- { target: `${role.name}` }
99
- )}
100
- />
101
- </CheckPermissions>
87
+ <IconButton
88
+ onClick={() => handleClickDelete(role.id.toString())}
89
+ variant="ghost"
90
+ label={formatMessage(
91
+ { id: 'global.delete-target', defaultMessage: 'Delete {target}' },
92
+ { target: `${role.name}` }
93
+ )}
94
+ >
95
+ <Trash />
96
+ </IconButton>
102
97
  )}
103
98
  </Flex>
104
99
  </Td>
@@ -112,12 +107,13 @@ export default TableBody;
112
107
 
113
108
  TableBody.defaultProps = {
114
109
  canDelete: false,
110
+ canUpdate: false,
115
111
  };
116
112
 
117
113
  TableBody.propTypes = {
118
114
  onDelete: PropTypes.array.isRequired,
119
- permissions: PropTypes.object.isRequired,
120
115
  setRoleToDelete: PropTypes.func.isRequired,
121
116
  sortedRoles: PropTypes.array.isRequired,
122
117
  canDelete: PropTypes.bool,
118
+ canUpdate: PropTypes.bool,
123
119
  };