@strapi/admin 4.7.2-exp.24dd7d95972fa822bf43e9b095b51027402c229e → 4.8.1

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 (171) hide show
  1. package/admin/src/content-manager/components/ComponentInitializer/index.js +1 -1
  2. package/admin/src/content-manager/components/EditViewDataManagerProvider/index.js +3 -31
  3. package/admin/src/content-manager/components/EditViewDataManagerProvider/reducer.js +65 -134
  4. package/admin/src/content-manager/components/EditViewDataManagerProvider/utils/findAllAndReplace.js +85 -0
  5. package/admin/src/content-manager/components/EditViewDataManagerProvider/utils/index.js +1 -2
  6. package/admin/src/content-manager/components/EditViewDataManagerProvider/utils/schema.js +7 -1
  7. package/admin/src/content-manager/components/NonRepeatableComponent/index.js +1 -1
  8. package/admin/src/content-manager/components/RelationInput/RelationInput.js +1 -2
  9. package/admin/src/content-manager/components/RelationInputDataManager/RelationInputDataManager.js +39 -33
  10. package/admin/src/content-manager/hooks/useRelation/useRelation.js +2 -2
  11. package/admin/src/content-manager/pages/EditView/Header/index.js +1 -1
  12. package/admin/src/content-manager/utils/createDefaultForm.js +0 -8
  13. package/admin/src/pages/AuthPage/components/Register/index.js +1 -1
  14. package/admin/src/pages/SettingsPage/components/Tokens/FormHead/index.js +1 -0
  15. package/admin/src/pages/SettingsPage/components/Tokens/Table/index.js +2 -2
  16. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/utils/schema.js +1 -1
  17. package/admin/src/pages/SettingsPage/pages/Roles/CreatePage/index.js +266 -4
  18. package/admin/src/pages/SettingsPage/pages/Roles/EditPage/components/ConditionsModal/ActionRow/index.js +1 -2
  19. package/admin/src/pages/SettingsPage/pages/Roles/EditPage/components/ContentTypeCollapse/Collapse/index.js +2 -3
  20. package/admin/src/pages/SettingsPage/pages/Roles/EditPage/components/ContentTypeCollapse/CollapsePropertyMatrix/ActionRow/index.js +2 -3
  21. package/admin/src/pages/SettingsPage/pages/Roles/EditPage/components/ContentTypeCollapse/CollapsePropertyMatrix/SubActionRow/index.js +2 -3
  22. package/admin/src/pages/SettingsPage/pages/Roles/EditPage/components/GlobalActions/index.js +9 -4
  23. package/admin/src/pages/SettingsPage/pages/Roles/EditPage/components/PluginsAndSettings/SubCategory/index.js +3 -7
  24. package/admin/src/pages/SettingsPage/pages/Roles/ListPage/index.js +303 -124
  25. package/admin/src/pages/SettingsPage/pages/TransferTokens/EditView/utils/schema.js +1 -1
  26. package/admin/src/pages/SettingsPage/utils/defaultRoutes.js +18 -10
  27. package/admin/src/translations/ca.json +7 -13
  28. package/admin/src/translations/de.json +0 -6
  29. package/admin/src/translations/dk.json +0 -6
  30. package/admin/src/translations/en.json +0 -6
  31. package/admin/src/translations/es.json +0 -6
  32. package/admin/src/translations/eu.json +165 -171
  33. package/admin/src/translations/fr.json +0 -6
  34. package/admin/src/translations/gu.json +0 -6
  35. package/admin/src/translations/he.json +0 -6
  36. package/admin/src/translations/hi.json +0 -6
  37. package/admin/src/translations/hu.json +0 -6
  38. package/admin/src/translations/id.json +0 -6
  39. package/admin/src/translations/it.json +0 -6
  40. package/admin/src/translations/ja.json +0 -6
  41. package/admin/src/translations/ko.json +0 -6
  42. package/admin/src/translations/ml.json +0 -6
  43. package/admin/src/translations/nl.json +0 -6
  44. package/admin/src/translations/no.json +0 -6
  45. package/admin/src/translations/pl.json +0 -6
  46. package/admin/src/translations/pt-BR.json +0 -6
  47. package/admin/src/translations/ru.json +0 -6
  48. package/admin/src/translations/sa.json +0 -6
  49. package/admin/src/translations/sk.json +0 -6
  50. package/admin/src/translations/sv.json +0 -6
  51. package/admin/src/translations/th.json +0 -6
  52. package/admin/src/translations/tr.json +0 -6
  53. package/admin/src/translations/zh-Hans.json +0 -6
  54. package/admin/src/translations/zh.json +0 -6
  55. package/build/{4649.daa290f6.chunk.js → 4649.33220ac3.chunk.js} +2 -2
  56. package/build/{6891.ef7464be.chunk.js → 7112.2bf13da3.chunk.js} +6 -6
  57. package/build/7259.3675c199.chunk.js +1 -0
  58. package/build/{3094.1cac9087.chunk.js → 8580.0aa21940.chunk.js} +5 -5
  59. package/build/{Admin-authenticatedApp.884faefa.chunk.js → Admin-authenticatedApp.1f2fd68f.chunk.js} +4 -4
  60. package/build/Admin_settingsPage.caf3b9ab.chunk.js +9 -0
  61. package/build/{admin-app.d9d96db4.chunk.js → admin-app.4b313104.chunk.js} +2 -2
  62. package/build/admin-edit-roles-page.3b196317.chunk.js +216 -0
  63. package/build/{admin-edit-users.48031e30.chunk.js → admin-edit-users.af3b0f15.chunk.js} +1 -1
  64. package/build/admin-roles-list.0ad504a7.chunk.js +2 -0
  65. package/build/{admin-users.77b4188a.chunk.js → admin-users.af8c3123.chunk.js} +1 -1
  66. package/build/api-tokens-list-page.93f24348.chunk.js +16 -0
  67. package/build/ca-json.43e14418.chunk.js +1 -0
  68. package/build/content-manager.84afc839.chunk.js +1139 -0
  69. package/build/{content-type-builder.cdd117c3.chunk.js → content-type-builder.55dac849.chunk.js} +1 -1
  70. package/build/de-json.fcac7381.chunk.js +1 -0
  71. package/build/dk-json.e34cad0d.chunk.js +1 -0
  72. package/build/{en-json.e688dfe2.chunk.js → en-json.01a88a30.chunk.js} +1 -1
  73. package/build/es-json.715b6fd8.chunk.js +1 -0
  74. package/build/eu-json.fb17c8f9.chunk.js +1 -0
  75. package/build/fr-json.f66c3211.chunk.js +1 -0
  76. package/build/gu-json.4d667d0c.chunk.js +1 -0
  77. package/build/{he-json.f0de8cdb.chunk.js → he-json.3cf0b48a.chunk.js} +1 -1
  78. package/build/{hi-json.14a17920.chunk.js → hi-json.323be97d.chunk.js} +1 -1
  79. package/build/{hu-json.33172d09.chunk.js → hu-json.fe71e6c8.chunk.js} +1 -1
  80. package/build/id-json.41e07c46.chunk.js +1 -0
  81. package/build/index.html +1 -1
  82. package/build/it-json.bfe27ed8.chunk.js +1 -0
  83. package/build/ja-json.81b6d1e3.chunk.js +1 -0
  84. package/build/ko-json.4539f4ba.chunk.js +1 -0
  85. package/build/main.5b92c1d6.js +3809 -0
  86. package/build/{ml-json.3e69969b.chunk.js → ml-json.8988e374.chunk.js} +1 -1
  87. package/build/{nl-json.641782d5.chunk.js → nl-json.98345913.chunk.js} +1 -1
  88. package/build/{no-json.9b3cd181.chunk.js → no-json.19a2dbfa.chunk.js} +1 -1
  89. package/build/pl-json.59a5dab3.chunk.js +1 -0
  90. package/build/pt-BR-json.9410688b.chunk.js +1 -0
  91. package/build/{ru-json.c4a4f50b.chunk.js → ru-json.6a01cea6.chunk.js} +1 -1
  92. package/build/runtime~main.a3892432.js +2 -0
  93. package/build/sa-json.6359a11c.chunk.js +1 -0
  94. package/build/sk-json.2374f129.chunk.js +1 -0
  95. package/build/{sv-json.207afc0d.chunk.js → sv-json.ae6e71ea.chunk.js} +1 -1
  96. package/build/th-json.5f659396.chunk.js +1 -0
  97. package/build/{tr-json.f1a0d19d.chunk.js → tr-json.bac5dbd3.chunk.js} +1 -1
  98. package/build/transfer-tokens-list-page.ce37354b.chunk.js +16 -0
  99. package/build/zh-Hans-json.4c9706a6.chunk.js +1 -0
  100. package/build/{zh-json.085a34f4.chunk.js → zh-json.3529f1e5.chunk.js} +1 -1
  101. package/ee/server/controllers/index.js +0 -1
  102. package/ee/server/controllers/role.js +0 -39
  103. package/ee/server/controllers/user.js +1 -35
  104. package/ee/server/routes/index.js +0 -49
  105. package/ee/server/validation/role.js +28 -20
  106. package/package.json +13 -13
  107. package/server/bootstrap.js +0 -1
  108. package/server/controllers/api-token.js +4 -2
  109. package/server/controllers/permission.js +2 -4
  110. package/server/controllers/role.js +70 -23
  111. package/server/controllers/transfer/runner.js +5 -3
  112. package/server/domain/user.js +3 -0
  113. package/server/routes/roles.js +48 -0
  114. package/server/services/permission/permissions-manager/sanitize.js +2 -2
  115. package/server/services/permission/queries.js +1 -74
  116. package/server/strategies/data-transfer.js +3 -1
  117. package/server/validation/permission.js +1 -82
  118. package/server/validation/role.js +44 -0
  119. package/admin/src/assets/images/hot-air-balloon.png +0 -0
  120. package/admin/src/assets/images/upgrade-details.png +0 -0
  121. package/admin/src/components/UpgradePlanModal/index.js +0 -123
  122. package/admin/src/content-manager/components/EditViewDataManagerProvider/utils/findLeafByPathAndReplace.js +0 -51
  123. package/admin/src/content-manager/components/EditViewDataManagerProvider/utils/recursivelyFindPathsBasedOnCondition.js +0 -79
  124. package/admin/src/pages/SettingsPage/pages/Roles/EditPage/components/ConditionsModal/ActionRow/utils/constants.js +0 -3
  125. package/admin/src/pages/SettingsPage/pages/Roles/EditPage/components/ContentTypeCollapse/Collapse/utils/constants.js +0 -3
  126. package/admin/src/pages/SettingsPage/pages/Roles/EditPage/components/ContentTypeCollapse/CollapsePropertyMatrix/ActionRow/utils/constants.js +0 -3
  127. package/admin/src/pages/SettingsPage/pages/Roles/EditPage/components/ContentTypeCollapse/CollapsePropertyMatrix/SubActionRow/utils/constants.js +0 -3
  128. package/admin/src/pages/SettingsPage/pages/Roles/EditPage/components/GlobalActions/utils/constants.js +0 -3
  129. package/admin/src/pages/SettingsPage/pages/Roles/EditPage/components/PluginsAndSettings/SubCategory/utils/constants.js +0 -3
  130. package/build/617f9c948fa79e6d73bd.png +0 -0
  131. package/build/6d21938306785f176538.png +0 -0
  132. package/build/7259.63e91b59.chunk.js +0 -1
  133. package/build/Admin_settingsPage.6814a96e.chunk.js +0 -177
  134. package/build/admin-edit-roles-page.bf130aaf.chunk.js +0 -1
  135. package/build/api-tokens-list-page.149903c8.chunk.js +0 -16
  136. package/build/ca-json.59c4502c.chunk.js +0 -1
  137. package/build/content-manager.d792c194.chunk.js +0 -1139
  138. package/build/de-json.dbc2cf1b.chunk.js +0 -1
  139. package/build/dk-json.52f67b15.chunk.js +0 -1
  140. package/build/es-json.c40c57dd.chunk.js +0 -1
  141. package/build/eu-json.6702a0d2.chunk.js +0 -1
  142. package/build/fr-json.ea9ec573.chunk.js +0 -1
  143. package/build/gu-json.94f0d242.chunk.js +0 -1
  144. package/build/id-json.e0d83d41.chunk.js +0 -1
  145. package/build/it-json.8be59205.chunk.js +0 -1
  146. package/build/ja-json.3008b720.chunk.js +0 -1
  147. package/build/ko-json.7d2f95b1.chunk.js +0 -1
  148. package/build/main.64fe0c37.js +0 -3928
  149. package/build/pl-json.05814145.chunk.js +0 -1
  150. package/build/pt-BR-json.d72350de.chunk.js +0 -1
  151. package/build/runtime~main.684b5fed.js +0 -2
  152. package/build/sa-json.e5e7ccaf.chunk.js +0 -1
  153. package/build/sk-json.3529b8aa.chunk.js +0 -1
  154. package/build/th-json.f664b96d.chunk.js +0 -1
  155. package/build/transfer-tokens-list-page.c6f8039a.chunk.js +0 -16
  156. package/build/zh-Hans-json.993d085f.chunk.js +0 -1
  157. package/ee/admin/pages/SettingsPage/pages/Roles/CreatePage/index.js +0 -270
  158. package/ee/admin/pages/SettingsPage/pages/Roles/EditPage/components/ConditionsModal/ActionRow/utils/constants.js +0 -3
  159. package/ee/admin/pages/SettingsPage/pages/Roles/EditPage/components/ConditionsModal/ConditionsSelect/MenuList/utils/constants.js +0 -3
  160. package/ee/admin/pages/SettingsPage/pages/Roles/EditPage/components/ContentTypeCollapse/Collapse/utils/constants.js +0 -3
  161. package/ee/admin/pages/SettingsPage/pages/Roles/EditPage/components/ContentTypeCollapse/CollapsePropertyMatrix/ActionRow/utils/constants.js +0 -3
  162. package/ee/admin/pages/SettingsPage/pages/Roles/EditPage/components/ContentTypeCollapse/CollapsePropertyMatrix/SubActionRow/utils/constants.js +0 -3
  163. package/ee/admin/pages/SettingsPage/pages/Roles/EditPage/components/GlobalActions/utils/constants.js +0 -3
  164. package/ee/admin/pages/SettingsPage/pages/Roles/EditPage/components/PluginsAndSettings/SubCategory/utils/constants.js +0 -3
  165. package/ee/admin/pages/SettingsPage/pages/Roles/ListPage/index.js +0 -376
  166. package/ee/admin/pages/SettingsPage/pages/Roles/ProtectedListPage/index.js +0 -12
  167. package/ee/server/controllers/permission.js +0 -21
  168. package/ee/server/validation/permission.js +0 -8
  169. package/server/domain/role.js +0 -29
  170. /package/{ee/admin → admin/src}/pages/SettingsPage/pages/Roles/CreatePage/utils/schema.js +0 -0
  171. /package/{ee/admin → admin/src}/pages/SettingsPage/pages/Roles/ListPage/reducer.js +0 -0
@@ -1,49 +1,138 @@
1
- import React, { useCallback, useState } from 'react';
2
- import matchSorter from 'match-sorter';
1
+ import React, { useCallback, useEffect, useReducer, useState } from 'react';
3
2
  import {
3
+ ConfirmDialog,
4
+ LoadingIndicatorPage,
5
+ SearchURLQuery,
4
6
  SettingsPageTitle,
5
- useQuery,
6
- useTracking,
7
+ getFetchClient,
8
+ useNotification,
9
+ useQueryParams,
10
+ useRBAC,
7
11
  useFocusWhenNavigate,
8
12
  } from '@strapi/helper-plugin';
9
- import { Plus, Trash, Pencil, Duplicate } from '@strapi/icons';
13
+ import { Plus, Trash, Duplicate, Pencil } from '@strapi/icons';
10
14
  import {
11
15
  Button,
16
+ ActionLayout,
12
17
  ContentLayout,
13
18
  HeaderLayout,
19
+ Main,
14
20
  Table,
15
21
  Tbody,
16
- Th,
22
+ TFooter,
17
23
  Thead,
24
+ Th,
18
25
  Tr,
19
- TFooter,
20
26
  Typography,
21
- Main,
22
27
  VisuallyHidden,
23
28
  } from '@strapi/design-system';
24
-
29
+ import { get } from 'lodash';
30
+ import matchSorter from 'match-sorter';
25
31
  import { useIntl } from 'react-intl';
26
32
  import { useHistory } from 'react-router-dom';
27
- import RoleRow from './components/RoleRow';
28
- import EmptyRole from './components/EmptyRole';
29
- import UpgradePlanModal from '../../../../../components/UpgradePlanModal';
30
33
  import { useRolesList } from '../../../../../hooks';
34
+ import adminPermissions from '../../../../../permissions';
35
+ import EmptyRole from './components/EmptyRole';
36
+ import BaseRoleRow from './components/RoleRow';
37
+ import reducer, { initialState } from './reducer';
31
38
 
32
39
  const useSortedRoles = () => {
33
- const { roles, isLoading } = useRolesList();
40
+ useFocusWhenNavigate();
41
+ const {
42
+ isLoading: isLoadingForPermissions,
43
+ allowedActions: { canCreate, canDelete, canRead, canUpdate },
44
+ } = useRBAC(adminPermissions.settings.roles);
34
45
 
35
- const query = useQuery();
36
- const _q = decodeURIComponent(query.get('_q') || '');
46
+ const { getData, roles, isLoading } = useRolesList(false);
47
+ const [{ query }] = useQueryParams();
48
+ const _q = query?._q || '';
37
49
  const sortedRoles = matchSorter(roles, _q, { keys: ['name', 'description'] });
38
50
 
39
- return { isLoading, sortedRoles };
51
+ useEffect(() => {
52
+ if (!isLoadingForPermissions && canRead) {
53
+ getData();
54
+ }
55
+ }, [isLoadingForPermissions, canRead, getData]);
56
+
57
+ return {
58
+ isLoadingForPermissions,
59
+ canCreate,
60
+ canDelete,
61
+ canRead,
62
+ canUpdate,
63
+ isLoading,
64
+ getData,
65
+ sortedRoles,
66
+ roles,
67
+ };
40
68
  };
41
69
 
42
- const useRoleActions = () => {
70
+ const useRoleActions = ({ getData, canCreate, canDelete, canUpdate }) => {
43
71
  const { formatMessage } = useIntl();
44
- const [isModalOpen, setIsModalOpen] = useState(false);
45
- const { trackUsage } = useTracking();
72
+
73
+ const toggleNotification = useNotification();
74
+ const [isWarningDeleteAllOpened, setIsWarningDeleteAllOpenend] = useState(false);
46
75
  const { push } = useHistory();
76
+ const [{ selectedRoles, showModalConfirmButtonLoading, roleToDelete }, dispatch] = useReducer(
77
+ reducer,
78
+ initialState
79
+ );
80
+
81
+ const { post } = getFetchClient();
82
+
83
+ const handleDeleteData = async () => {
84
+ try {
85
+ dispatch({
86
+ type: 'ON_REMOVE_ROLES',
87
+ });
88
+
89
+ await post('/admin/roles/batch-delete', {
90
+ ids: [roleToDelete],
91
+ });
92
+
93
+ await getData();
94
+
95
+ dispatch({
96
+ type: 'RESET_DATA_TO_DELETE',
97
+ });
98
+ } catch (err) {
99
+ const errorIds = get(err, ['response', 'payload', 'data', 'ids'], null);
100
+
101
+ if (errorIds && Array.isArray(errorIds)) {
102
+ const errorsMsg = errorIds.join('\n');
103
+ toggleNotification({
104
+ type: 'warning',
105
+ message: errorsMsg,
106
+ });
107
+ } else {
108
+ toggleNotification({
109
+ type: 'warning',
110
+ message: { id: 'notification.error' },
111
+ });
112
+ }
113
+ }
114
+ handleToggleModal();
115
+ };
116
+
117
+ const onRoleDuplicate = useCallback(
118
+ (id) => {
119
+ push(`/settings/roles/duplicate/${id}`);
120
+ },
121
+ [push]
122
+ );
123
+
124
+ const handleNewRoleClick = () => push('/settings/roles/new');
125
+
126
+ const onRoleRemove = useCallback((roleId) => {
127
+ dispatch({
128
+ type: 'SET_ROLE_TO_DELETE',
129
+ id: roleId,
130
+ });
131
+
132
+ handleToggleModal();
133
+ }, []);
134
+
135
+ const handleToggleModal = () => setIsWarningDeleteAllOpenend((prev) => !prev);
47
136
 
48
137
  const handleGoTo = useCallback(
49
138
  (id) => {
@@ -52,144 +141,234 @@ const useRoleActions = () => {
52
141
  [push]
53
142
  );
54
143
 
55
- const handleToggle = useCallback(() => {
56
- setIsModalOpen((prev) => !prev);
57
- }, []);
144
+ const handleClickDelete = useCallback(
145
+ (e, role) => {
146
+ e.preventDefault();
147
+ e.stopPropagation();
58
148
 
59
- const handleToggleModalForCreatingRole = useCallback(() => {
60
- trackUsage('didShowRBACUpgradeModal');
61
- setIsModalOpen(true);
62
- }, [trackUsage]);
149
+ if (role.usersCount) {
150
+ toggleNotification({
151
+ type: 'info',
152
+ message: { id: 'Roles.ListPage.notification.delete-not-allowed' },
153
+ });
154
+ } else {
155
+ onRoleRemove(role.id);
156
+ }
157
+ },
158
+ [toggleNotification, onRoleRemove]
159
+ );
160
+
161
+ const handleClickDuplicate = useCallback(
162
+ (e, role) => {
163
+ e.preventDefault();
164
+ e.stopPropagation();
165
+ onRoleDuplicate(role.id);
166
+ },
167
+ [onRoleDuplicate]
168
+ );
63
169
 
64
170
  const getIcons = useCallback(
65
171
  (role) => [
66
- {
67
- onClick: handleToggle,
68
- label: formatMessage({ id: 'app.utils.duplicate', defaultMessage: 'Duplicate' }),
69
- icon: <Duplicate />,
70
- },
71
- {
72
- onClick: () => handleGoTo(role.id),
73
- label: formatMessage({ id: 'app.utils.edit', defaultMessage: 'Edit' }),
74
- icon: <Pencil />,
75
- },
76
- {
77
- onClick: handleToggle,
78
- label: formatMessage({ id: 'global.delete', defaultMessage: 'Delete' }),
79
- icon: <Trash />,
80
- },
172
+ ...(canCreate
173
+ ? [
174
+ {
175
+ onClick: (e) => handleClickDuplicate(e, role),
176
+ label: formatMessage({ id: 'app.utils.duplicate', defaultMessage: 'Duplicate' }),
177
+ icon: <Duplicate />,
178
+ },
179
+ ]
180
+ : []),
181
+ ...(canUpdate
182
+ ? [
183
+ {
184
+ onClick: () => handleGoTo(role.id),
185
+ label: formatMessage({ id: 'app.utils.edit', defaultMessage: 'Edit' }),
186
+ icon: <Pencil />,
187
+ },
188
+ ]
189
+ : []),
190
+ ...(canDelete
191
+ ? [
192
+ {
193
+ onClick: (e) => handleClickDelete(e, role),
194
+ label: formatMessage({ id: 'global.delete', defaultMessage: 'Delete' }),
195
+ icon: <Trash />,
196
+ },
197
+ ]
198
+ : []),
81
199
  ],
82
- [formatMessage, handleToggle, handleGoTo]
200
+ [
201
+ formatMessage,
202
+ handleClickDelete,
203
+ handleClickDuplicate,
204
+ handleGoTo,
205
+ canCreate,
206
+ canUpdate,
207
+ canDelete,
208
+ ]
83
209
  );
84
210
 
85
211
  return {
86
- isModalOpen,
87
- handleToggleModalForCreatingRole,
88
- handleToggle,
212
+ handleNewRoleClick,
89
213
  getIcons,
214
+ selectedRoles,
215
+ isWarningDeleteAllOpened,
216
+ showModalConfirmButtonLoading,
217
+ handleToggleModal,
218
+ handleDeleteData,
90
219
  };
91
220
  };
92
221
 
93
222
  const RoleListPage = () => {
94
223
  const { formatMessage } = useIntl();
95
- useFocusWhenNavigate();
96
224
 
97
- const { sortedRoles, isLoading } = useSortedRoles();
98
- const { isModalOpen, handleToggle, handleToggleModalForCreatingRole, getIcons } =
99
- useRoleActions();
225
+ const {
226
+ isLoadingForPermissions,
227
+ canCreate,
228
+ canRead,
229
+ canDelete,
230
+ canUpdate,
231
+ isLoading,
232
+ getData,
233
+ sortedRoles,
234
+ } = useSortedRoles();
235
+
236
+ const {
237
+ handleNewRoleClick,
238
+ getIcons,
239
+ isWarningDeleteAllOpened,
240
+ showModalConfirmButtonLoading,
241
+ handleToggleModal,
242
+ handleDeleteData,
243
+ } = useRoleActions({ getData, canCreate, canDelete, canUpdate });
244
+
245
+ // ! TODO - Show the search bar only if the user is allowed to read - add the search input
246
+ // canRead
100
247
 
101
248
  const rowCount = sortedRoles.length + 1;
102
- const colCount = 5;
249
+ const colCount = 6;
250
+
251
+ if (isLoadingForPermissions) {
252
+ return (
253
+ <Main>
254
+ <LoadingIndicatorPage />
255
+ </Main>
256
+ );
257
+ }
103
258
 
104
- // ! TODO - Add the search input
259
+ const title = formatMessage({
260
+ id: 'global.roles',
261
+ defaultMessage: 'roles',
262
+ });
105
263
 
106
264
  return (
107
265
  <Main>
108
266
  <SettingsPageTitle name="Roles" />
109
267
  <HeaderLayout
110
268
  primaryAction={
111
- <Button onClick={handleToggleModalForCreatingRole} startIcon={<Plus />} size="S">
112
- {formatMessage({
113
- id: 'Settings.roles.list.button.add',
114
- defaultMessage: 'Add new role',
115
- })}
116
- </Button>
269
+ canCreate ? (
270
+ <Button onClick={handleNewRoleClick} startIcon={<Plus />} size="S">
271
+ {formatMessage({
272
+ id: 'Settings.roles.list.button.add',
273
+ defaultMessage: 'Add new role',
274
+ })}
275
+ </Button>
276
+ ) : null
117
277
  }
118
- title={formatMessage({
119
- id: 'global.roles',
120
- defaultMessage: 'roles',
121
- })}
278
+ title={title}
122
279
  subtitle={formatMessage({
123
280
  id: 'Settings.roles.list.description',
124
281
  defaultMessage: 'List of roles',
125
282
  })}
283
+ as="h2"
126
284
  />
127
- <ContentLayout>
128
- <Table
129
- colCount={colCount}
130
- rowCount={rowCount}
131
- footer={
132
- <TFooter onClick={handleToggleModalForCreatingRole} icon={<Plus />}>
133
- {formatMessage({
134
- id: 'Settings.roles.list.button.add',
135
- defaultMessage: 'Add new role',
136
- })}
137
- </TFooter>
285
+ {canRead && (
286
+ <ActionLayout
287
+ startActions={
288
+ <SearchURLQuery
289
+ label={formatMessage(
290
+ { id: 'app.component.search.label', defaultMessage: 'Search for {target}' },
291
+ { target: title }
292
+ )}
293
+ />
138
294
  }
139
- >
140
- <Thead>
141
- <Tr>
142
- <Th>
143
- <Typography variant="sigma" textColor="neutral600">
295
+ />
296
+ )}
297
+ {canRead && (
298
+ <ContentLayout>
299
+ <Table
300
+ colCount={colCount}
301
+ rowCount={rowCount}
302
+ footer={
303
+ canCreate ? (
304
+ <TFooter onClick={handleNewRoleClick} icon={<Plus />}>
144
305
  {formatMessage({
145
- id: 'global.name',
146
- defaultMessage: 'Name',
306
+ id: 'Settings.roles.list.button.add',
307
+ defaultMessage: 'Add new role',
147
308
  })}
148
- </Typography>
149
- </Th>
150
- <Th>
151
- <Typography variant="sigma" textColor="neutral600">
152
- {formatMessage({
153
- id: 'global.description',
154
- defaultMessage: 'Description',
155
- })}
156
- </Typography>
157
- </Th>
158
- <Th>
159
- <Typography variant="sigma" textColor="neutral600">
160
- {formatMessage({
161
- id: 'global.users',
162
- defaultMessage: 'Users',
163
- })}
164
- </Typography>
165
- </Th>
166
- <Th>
167
- <VisuallyHidden>
168
- {formatMessage({
169
- id: 'global.actions',
170
- defaultMessage: 'Actions',
171
- })}
172
- </VisuallyHidden>
173
- </Th>
174
- </Tr>
175
- </Thead>
176
- <Tbody>
177
- {sortedRoles?.map((role, rowIndex) => (
178
- <RoleRow
179
- key={role.id}
180
- id={role.id}
181
- name={role.name}
182
- description={role.description}
183
- usersCount={role.usersCount}
184
- icons={getIcons(role)}
185
- rowIndex={rowIndex + 2}
186
- />
187
- ))}
188
- </Tbody>
189
- </Table>
190
- {!rowCount && !isLoading && <EmptyRole />}
191
- </ContentLayout>
192
- <UpgradePlanModal isOpen={isModalOpen} onClose={handleToggle} />
309
+ </TFooter>
310
+ ) : null
311
+ }
312
+ >
313
+ <Thead>
314
+ <Tr aria-rowindex={1}>
315
+ <Th>
316
+ <Typography variant="sigma" textColor="neutral600">
317
+ {formatMessage({
318
+ id: 'global.name',
319
+ defaultMessage: 'Name',
320
+ })}
321
+ </Typography>
322
+ </Th>
323
+ <Th>
324
+ <Typography variant="sigma" textColor="neutral600">
325
+ {formatMessage({
326
+ id: 'global.description',
327
+ defaultMessage: 'Description',
328
+ })}
329
+ </Typography>
330
+ </Th>
331
+ <Th>
332
+ <Typography variant="sigma" textColor="neutral600">
333
+ {formatMessage({
334
+ id: 'global.users',
335
+ defaultMessage: 'Users',
336
+ })}
337
+ </Typography>
338
+ </Th>
339
+ <Th>
340
+ <VisuallyHidden>
341
+ {formatMessage({
342
+ id: 'global.actions',
343
+ defaultMessage: 'Actions',
344
+ })}
345
+ </VisuallyHidden>
346
+ </Th>
347
+ </Tr>
348
+ </Thead>
349
+ <Tbody>
350
+ {sortedRoles?.map((role, index) => (
351
+ <BaseRoleRow
352
+ key={role.id}
353
+ id={role.id}
354
+ name={role.name}
355
+ description={role.description}
356
+ usersCount={role.usersCount}
357
+ icons={getIcons(role)}
358
+ rowIndex={index + 2}
359
+ />
360
+ ))}
361
+ </Tbody>
362
+ </Table>
363
+ {!rowCount && !isLoading && <EmptyRole />}
364
+ </ContentLayout>
365
+ )}
366
+ <ConfirmDialog
367
+ isOpen={isWarningDeleteAllOpened}
368
+ onConfirm={handleDeleteData}
369
+ isConfirmButtonLoading={showModalConfirmButtonLoading}
370
+ onToggleDialog={handleToggleModal}
371
+ />
193
372
  </Main>
194
373
  );
195
374
  };
@@ -2,7 +2,7 @@ import * as yup from 'yup';
2
2
  import { translatedErrors } from '@strapi/helper-plugin';
3
3
 
4
4
  const schema = yup.object().shape({
5
- name: yup.string(translatedErrors.string).required(translatedErrors.required),
5
+ name: yup.string(translatedErrors.string).max(100).required(translatedErrors.required),
6
6
  description: yup.string().nullable(),
7
7
  lifespan: yup.number().integer().min(0).nullable().defined(translatedErrors.required),
8
8
  });
@@ -1,25 +1,33 @@
1
- import RolesCreatePage from 'ee_else_ce/pages/SettingsPage/pages/Roles/CreatePage';
2
- import ProtectedRolesListPage from 'ee_else_ce/pages/SettingsPage/pages/Roles/ProtectedListPage';
3
-
4
1
  const defaultRoutes = [
5
2
  {
6
- Component() {
7
- return { default: ProtectedRolesListPage };
8
- },
3
+ async Component() {
4
+ const component = await import(
5
+ /* webpackChunkName: "admin-roles-list" */ '../pages/Roles/ProtectedListPage'
6
+ );
9
7
 
8
+ return component;
9
+ },
10
10
  to: '/settings/roles',
11
11
  exact: true,
12
12
  },
13
13
  {
14
- Component() {
15
- return { default: RolesCreatePage };
14
+ async Component() {
15
+ const component = await import(
16
+ /* webpackChunkName: "admin-edit-roles-page" */ '../pages/Roles/CreatePage'
17
+ );
18
+
19
+ return component;
16
20
  },
17
21
  to: '/settings/roles/duplicate/:id',
18
22
  exact: true,
19
23
  },
20
24
  {
21
- Component() {
22
- return { default: RolesCreatePage };
25
+ async Component() {
26
+ const component = await import(
27
+ /* webpackChunkName: "admin-edit-roles-page" */ '../pages/Roles/CreatePage'
28
+ );
29
+
30
+ return component;
23
31
  },
24
32
  to: '/settings/roles/new',
25
33
  exact: true,
@@ -162,7 +162,7 @@
162
162
  "Settings.webhooks.create": "Crea un webhook",
163
163
  "Settings.webhooks.create.header": "Crea una nova capçalera",
164
164
  "Settings.webhooks.created": "Webhook creat",
165
- "Settings.webhooks.event.publish-tooltip": "Aquest esdeveniment només existeix per a continguts amb el sistema Esborrany\/Publicació habilitat",
165
+ "Settings.webhooks.event.publish-tooltip": "Aquest esdeveniment només existeix per a continguts amb el sistema Esborrany/Publicació habilitat",
166
166
  "Settings.webhooks.events.create": "Crear",
167
167
  "Settings.webhooks.events.update": "Actualitzar",
168
168
  "Settings.webhooks.form.events": "Esdeveniments",
@@ -245,20 +245,20 @@
245
245
  "app.components.EmptyAttributes.title": "Encara no hi ha camps",
246
246
  "app.components.EmptyStateLayout.content-document": "No s'ha trobat contingut",
247
247
  "app.components.EmptyStateLayout.content-permissions": "No tens els permisos per accedir a aquest contingut.",
248
- "app.components.GuidedTour.CM.create.content": "<p>Creeu i gestioneu tot el contingut aquí al Gestor de continguts.<\/p><p>Ex.: Si fem l'exemple del lloc web del bloc més enllà, es pot escriure un article, desar-lo i publicar-lo com vulgui.<\/p>< p>💡 Consell ràpid: no us oblideu de fer clic a Publicar al contingut que creeu.<\/p>",
248
+ "app.components.GuidedTour.CM.create.content": "<p>Creeu i gestioneu tot el contingut aquí al Gestor de continguts.</p><p>Ex.: Si fem l'exemple del lloc web del bloc més enllà, es pot escriure un article, desar-lo i publicar-lo com vulgui.</p>< p>💡 Consell ràpid: no us oblideu de fer clic a Publicar al contingut que creeu.</p>",
249
249
  "app.components.GuidedTour.CM.create.title": "⚡️ Crea contingut",
250
- "app.components.GuidedTour.CM.success.content": "<p>Increïble, un últim pas per fer!<\/p><b>🚀 Veure contingut en acció<\/b>",
250
+ "app.components.GuidedTour.CM.success.content": "<p>Increïble, un últim pas per fer!</p><b>🚀 Veure contingut en acció</b>",
251
251
  "app.components.GuidedTour.CM.success.cta.title": "Prova l'API",
252
252
  "app.components.GuidedTour.CM.success.title": "Pas 2: completat ✅",
253
- "app.components.GuidedTour.CTB.create.content": "<p>Els tipus de col·lecció us ajuden a gestionar diverses entrades, els tipus únics són adequats per gestionar només una entrada.<\/p> <p>Ex: per a un lloc web de bloc, els articles serien un tipus de col·lecció mentre que una pàgina d'inici seria un tipus únic. <\/p>",
253
+ "app.components.GuidedTour.CTB.create.content": "<p>Els tipus de col·lecció us ajuden a gestionar diverses entrades, els tipus únics són adequats per gestionar només una entrada.</p> <p>Ex: per a un lloc web de bloc, els articles serien un tipus de col·lecció mentre que una pàgina d'inici seria un tipus únic. </p>",
254
254
  "app.components.GuidedTour.CTB.create.cta.title": "Creeu un tipus de col·lecció",
255
255
  "app.components.GuidedTour.CTB.create.title": "🧠 Crea un primer tipus de col·lecció",
256
- "app.components.GuidedTour.CTB.success.content": "<p>Que vagi bé!<\/p><b>⚡️ Què t'agradaria compartir amb el món?<\/b>",
256
+ "app.components.GuidedTour.CTB.success.content": "<p>Que vagi bé!</p><b>⚡️ Què t'agradaria compartir amb el món?</b>",
257
257
  "app.components.GuidedTour.CTB.success.title": "Pas 1: Completat ✅",
258
- "app.components.GuidedTour.apiTokens.create.content": "<p>Genereu aquí un testimoni d'autenticació i recupereu el contingut que acabeu de crear.<\/p>",
258
+ "app.components.GuidedTour.apiTokens.create.content": "<p>Genereu aquí un testimoni d'autenticació i recupereu el contingut que acabeu de crear.</p>",
259
259
  "app.components.GuidedTour.apiTokens.create.cta.title": "Genereu un testimoni API",
260
260
  "app.components.GuidedTour.apiTokens.create.title": "🚀 Veure contingut en acció",
261
- "app.components.GuidedTour.apiTokens.success.content": "<p>Consulteu el contingut en acció fent una sol·licitud HTTP:<\/p><ul><li><p>A aquest URL: <light>https:\/\/'<'YOUR_DOMAIN'>'\/api\/'<' YOUR_CT'>'<\/light><\/p><\/li><li><p>Amb la capçalera: <light>Autorització: portador '<'YOUR_API_TOKEN'>'<\/light><\/p><\/li ><\/ul><p>Per obtenir més maneres d'interaccionar amb el contingut, consulteu la <documentationLink>documentació<\/documentationLink>.<\/p>",
261
+ "app.components.GuidedTour.apiTokens.success.content": "<p>Consulteu el contingut en acció fent una sol·licitud HTTP:</p><ul><li><p>A aquest URL: <light>https://'<'YOUR_DOMAIN'>'/api/'<' YOUR_CT'>'</light></p></li><li><p>Amb la capçalera: <light>Autorització: portador '<'YOUR_API_TOKEN'>'</light></p></li ></ul><p>Per obtenir més maneres d'interaccionar amb el contingut, consulteu la <documentationLink>documentació</documentationLink>.</p>",
262
262
  "app.components.GuidedTour.apiTokens.success.cta.title": "Torna a la pàgina d'inici",
263
263
  "app.components.GuidedTour.apiTokens.success.title": "Pas 3: Completat ✅",
264
264
  "app.components.GuidedTour.create-content": "Crea contingut",
@@ -328,12 +328,6 @@
328
328
  "app.components.PluginCard.more-details": "Més detalls",
329
329
  "app.components.ToggleCheckbox.off-label": "Apagat",
330
330
  "app.components.ToggleCheckbox.on-label": "Encès",
331
- "app.components.UpgradePlanModal.button": "SABER MÉS",
332
- "app.components.UpgradePlanModal.limit-reached": "Has assolit el límit máxim",
333
- "app.components.UpgradePlanModal.text-Strapi": "de Strapi actualitzant el seu pla al",
334
- "app.components.UpgradePlanModal.text-ce": "Edició de la Comunitat",
335
- "app.components.UpgradePlanModal.text-ee": "Edició Empresarial",
336
- "app.components.UpgradePlanModal.text-power": "Desbloqueja tot el poder",
337
331
  "app.components.Users.MagicLink.connect": "Envieu aquest enllaç a l'usuari perquè es connecti.",
338
332
  "app.components.Users.MagicLink.connect.sso": "Envieu aquest enllaç a l'usuari, el primer inici de sessió es pot fer a través d'un proveïdor de SSO",
339
333
  "app.components.Users.ModalCreateBody.block-title.details": "Detalls",
@@ -324,12 +324,6 @@
324
324
  "app.components.PluginCard.more-details": "Mehr Details",
325
325
  "app.components.ToggleCheckbox.off-label": "Nein",
326
326
  "app.components.ToggleCheckbox.on-label": "Ja",
327
- "app.components.UpgradePlanModal.button": "Mehr erfahren",
328
- "app.components.UpgradePlanModal.limit-reached": "Limit erreicht",
329
- "app.components.UpgradePlanModal.text-ce": "Community Edition",
330
- "app.components.UpgradePlanModal.text-ee": "Enterprise Edition",
331
- "app.components.UpgradePlanModal.text-power": "Schalte die ganze Power frei",
332
- "app.components.UpgradePlanModal.text-strapi": "in dem du Strapi upgradest auf",
333
327
  "app.components.Users.MagicLink.connect": "Diesen Link dem Benutzer zum Registrieren schicken.",
334
328
  "app.components.Users.MagicLink.connect.sso": "Sende dem Benutzer diesen Link, das erste Login kann über einen SSO-Anbeiter gemacht werden",
335
329
  "app.components.Users.ModalCreateBody.block-title.details": "Details",
@@ -274,12 +274,6 @@
274
274
  "app.components.PluginCard.more-details": "Flere detaljer",
275
275
  "app.components.ToggleCheckbox.off-label": "Fra",
276
276
  "app.components.ToggleCheckbox.on-label": "Til",
277
- "app.components.UpgradePlanModal.button": "LÆR MERE",
278
- "app.components.UpgradePlanModal.limit-reached": "Du har nået grænsen",
279
- "app.components.UpgradePlanModal.text-ce": "Community Edition",
280
- "app.components.UpgradePlanModal.text-ee": "Enterprise Edition",
281
- "app.components.UpgradePlanModal.text-power": "Lås op for det fulle potentiale",
282
- "app.components.UpgradePlanModal.text-strapi": "af Strapi ved at opgradere til",
283
277
  "app.components.Users.MagicLink.connect": "Send dette link til brugeren for at de kan connecte.",
284
278
  "app.components.Users.MagicLink.connect.sso": "Send dette link til brugeren. Det første log ind kan klares med en SSO provider",
285
279
  "app.components.Users.ModalCreateBody.block-title.details": "Detaljer",
@@ -477,12 +477,6 @@
477
477
  "app.components.PluginCard.more-details": "More details",
478
478
  "app.components.ToggleCheckbox.off-label": "False",
479
479
  "app.components.ToggleCheckbox.on-label": "True",
480
- "app.components.UpgradePlanModal.button": "Learn more",
481
- "app.components.UpgradePlanModal.limit-reached": "You have reached the limit",
482
- "app.components.UpgradePlanModal.text-ce": "Community Edition",
483
- "app.components.UpgradePlanModal.text-ee": "Enterprise Edition",
484
- "app.components.UpgradePlanModal.text-power": "Unlock the full power of Strapi by upgrading your plan to the Enterprise Edition",
485
- "app.components.UpgradePlanModal.text-strapi": "of Strapi by upgrading your plan to the",
486
480
  "app.components.Users.MagicLink.connect": "Copy and share this link to give access to this user",
487
481
  "app.components.Users.MagicLink.connect.sso": "Send this link to the user, the first login can be made via a SSO provider",
488
482
  "app.components.Users.ModalCreateBody.block-title.details": "User details",
@@ -274,12 +274,6 @@
274
274
  "app.components.PluginCard.more-details": "Más detalles",
275
275
  "app.components.ToggleCheckbox.off-label": "Apagado",
276
276
  "app.components.ToggleCheckbox.on-label": "Encendido",
277
- "app.components.UpgradePlanModal.button": "SABER MÁS",
278
- "app.components.UpgradePlanModal.limit-reached": "Has alcanzado el límite",
279
- "app.components.UpgradePlanModal.text-ce": "Edición de la Comunidad",
280
- "app.components.UpgradePlanModal.text-ee": "Edición Empresarial",
281
- "app.components.UpgradePlanModal.text-power": "Desbloquea todo el poder",
282
- "app.components.UpgradePlanModal.text-strapi": "de Strapi actualizando su plan al",
283
277
  "app.components.Users.MagicLink.connect": "Envíe este enlace al usuario para que se conecte.",
284
278
  "app.components.Users.MagicLink.connect.sso": "Envíe este enlace al usuario, el primer inicio de sesión se puede realizar a través de un proveedor de SSO",
285
279
  "app.components.Users.ModalCreateBody.block-title.details": "Detalles",