@strapi/plugin-users-permissions 4.12.5 → 4.12.6

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 (32) hide show
  1. package/admin/src/components/Permissions/index.js +2 -4
  2. package/admin/src/index.js +7 -8
  3. package/admin/src/pages/AdvancedSettings/index.js +41 -24
  4. package/admin/src/pages/EmailTemplates/index.js +62 -47
  5. package/admin/src/pages/Providers/index.js +64 -58
  6. package/admin/src/{hooks → pages/Roles/hooks}/usePlugins.js +15 -8
  7. package/admin/src/pages/Roles/index.js +10 -7
  8. package/admin/src/pages/Roles/pages/CreatePage.js +190 -0
  9. package/admin/src/pages/Roles/pages/EditPage.js +211 -0
  10. package/admin/src/pages/Roles/{ListPage → pages/ListPage}/components/TableBody.js +41 -11
  11. package/admin/src/pages/Roles/{ListPage → pages/ListPage}/index.js +19 -15
  12. package/jest.config.front.js +1 -1
  13. package/package.json +4 -4
  14. package/admin/src/hooks/index.js +0 -5
  15. package/admin/src/hooks/useFetchRole/index.js +0 -67
  16. package/admin/src/hooks/useFetchRole/reducer.js +0 -31
  17. package/admin/src/hooks/useForm/index.js +0 -68
  18. package/admin/src/hooks/useForm/reducer.js +0 -40
  19. package/admin/src/hooks/useRolesList/index.js +0 -65
  20. package/admin/src/hooks/useRolesList/init.js +0 -5
  21. package/admin/src/hooks/useRolesList/reducer.js +0 -31
  22. package/admin/src/pages/AdvancedSettings/utils/api.js +0 -16
  23. package/admin/src/pages/EmailTemplates/utils/api.js +0 -16
  24. package/admin/src/pages/Providers/reducer.js +0 -54
  25. package/admin/src/pages/Providers/utils/api.js +0 -24
  26. package/admin/src/pages/Providers/utils/createProvidersArray.js +0 -21
  27. package/admin/src/pages/Roles/CreatePage.js +0 -185
  28. package/admin/src/pages/Roles/EditPage.js +0 -197
  29. package/admin/src/pages/Roles/ProtectedCreatePage.js +0 -15
  30. package/admin/src/pages/Roles/ProtectedEditPage.js +0 -15
  31. package/admin/src/pages/Roles/ProtectedListPage.js +0 -17
  32. /package/admin/src/pages/Roles/{ListPage → pages/ListPage}/utils/api.js +0 -0
@@ -1,6 +1,6 @@
1
1
  import React, { useReducer } from 'react';
2
2
 
3
- import { Accordion, AccordionContent, AccordionToggle, Box, Flex } from '@strapi/design-system';
3
+ import { Accordion, AccordionContent, AccordionToggle, Flex } from '@strapi/design-system';
4
4
  import { useIntl } from 'react-intl';
5
5
 
6
6
  import { useUsersPermissions } from '../../contexts/UsersPermissionsContext';
@@ -44,9 +44,7 @@ const Permissions = () => {
44
44
  variant={index % 2 ? 'primary' : 'secondary'}
45
45
  />
46
46
  <AccordionContent>
47
- <Box>
48
- <PermissionRow permissions={modifiedData[collapse.name]} name={collapse.name} />
49
- </Box>
47
+ <PermissionRow permissions={modifiedData[collapse.name]} name={collapse.name} />
50
48
  </AccordionContent>
51
49
  </Accordion>
52
50
  ))}
@@ -9,7 +9,6 @@ import { prefixPluginTranslations } from '@strapi/helper-plugin';
9
9
  import pluginPkg from '../../package.json';
10
10
 
11
11
  import { PERMISSIONS } from './constants';
12
- import pluginId from './pluginId';
13
12
  import getTrad from './utils/getTrad';
14
13
 
15
14
  const name = pluginPkg.strapi.name;
@@ -19,7 +18,7 @@ export default {
19
18
  // Create the plugin's settings section
20
19
  app.createSettingSection(
21
20
  {
22
- id: pluginId,
21
+ id: 'users-permissions',
23
22
  intlLabel: {
24
23
  id: getTrad('Settings.section-label'),
25
24
  defaultMessage: 'Users & Permissions plugin',
@@ -32,7 +31,7 @@ export default {
32
31
  defaultMessage: 'Roles',
33
32
  },
34
33
  id: 'roles',
35
- to: `/settings/${pluginId}/roles`,
34
+ to: `/settings/users-permissions/roles`,
36
35
  async Component() {
37
36
  const component = await import(
38
37
  /* webpackChunkName: "users-roles-settings-page" */ './pages/Roles'
@@ -48,7 +47,7 @@ export default {
48
47
  defaultMessage: 'Providers',
49
48
  },
50
49
  id: 'providers',
51
- to: `/settings/${pluginId}/providers`,
50
+ to: `/settings/users-permissions/providers`,
52
51
  async Component() {
53
52
  const component = await import(
54
53
  /* webpackChunkName: "users-providers-settings-page" */ './pages/Providers'
@@ -64,7 +63,7 @@ export default {
64
63
  defaultMessage: 'Email templates',
65
64
  },
66
65
  id: 'email-templates',
67
- to: `/settings/${pluginId}/email-templates`,
66
+ to: `/settings/users-permissions/email-templates`,
68
67
  async Component() {
69
68
  const component = await import(
70
69
  /* webpackChunkName: "users-email-settings-page" */ './pages/EmailTemplates'
@@ -80,7 +79,7 @@ export default {
80
79
  defaultMessage: 'Advanced Settings',
81
80
  },
82
81
  id: 'advanced-settings',
83
- to: `/settings/${pluginId}/advanced-settings`,
82
+ to: `/settings/users-permissions/advanced-settings`,
84
83
  async Component() {
85
84
  const component = await import(
86
85
  /* webpackChunkName: "users-advanced-settings-page" */ './pages/AdvancedSettings'
@@ -94,7 +93,7 @@ export default {
94
93
  );
95
94
 
96
95
  app.registerPlugin({
97
- id: pluginId,
96
+ id: 'users-permissions',
98
97
  name,
99
98
  });
100
99
  },
@@ -107,7 +106,7 @@ export default {
107
106
  )
108
107
  .then(({ default: data }) => {
109
108
  return {
110
- data: prefixPluginTranslations(data, pluginId),
109
+ data: prefixPluginTranslations(data, 'users-permissions'),
111
110
  locale,
112
111
  };
113
112
  })
@@ -20,6 +20,8 @@ import {
20
20
  GenericInput,
21
21
  LoadingIndicatorPage,
22
22
  SettingsPageTitle,
23
+ useAPIErrorHandler,
24
+ useFetchClient,
23
25
  useFocusWhenNavigate,
24
26
  useNotification,
25
27
  useOverlayBlocker,
@@ -33,7 +35,6 @@ import { useMutation, useQuery, useQueryClient } from 'react-query';
33
35
  import { PERMISSIONS } from '../../constants';
34
36
  import { getTrad } from '../../utils';
35
37
 
36
- import { fetchData, putAdvancedSettings } from './utils/api';
37
38
  import layout from './utils/layout';
38
39
  import schema from './utils/schema';
39
40
 
@@ -49,6 +50,9 @@ const AdvancedSettingsPage = () => {
49
50
  const { lockApp, unlockApp } = useOverlayBlocker();
50
51
  const { notifyStatus } = useNotifyAT();
51
52
  const queryClient = useQueryClient();
53
+ const { get, put } = useFetchClient();
54
+ const { formatAPIError } = useAPIErrorHandler();
55
+
52
56
  useFocusWhenNavigate();
53
57
 
54
58
  const {
@@ -56,28 +60,37 @@ const AdvancedSettingsPage = () => {
56
60
  allowedActions: { canUpdate },
57
61
  } = useRBAC({ update: PERMISSIONS.updateAdvancedSettings });
58
62
 
59
- const { status: isLoadingData, data } = useQuery('advanced', () => fetchData(), {
60
- onSuccess() {
61
- notifyStatus(
62
- formatMessage({
63
- id: getTrad('Form.advancedSettings.data.loaded'),
64
- defaultMessage: 'Advanced settings data has been loaded',
65
- })
66
- );
67
- },
68
- onError() {
69
- toggleNotification({
70
- type: 'warning',
71
- message: { id: getTrad('notification.error'), defaultMessage: 'An error occured' },
72
- });
63
+ const { isLoading: isLoadingData, data } = useQuery(
64
+ ['users-permissions', 'advanced'],
65
+ async () => {
66
+ const { data } = await get('/users-permissions/advanced');
67
+
68
+ return data;
73
69
  },
74
- });
70
+ {
71
+ onSuccess() {
72
+ notifyStatus(
73
+ formatMessage({
74
+ id: getTrad('Form.advancedSettings.data.loaded'),
75
+ defaultMessage: 'Advanced settings data has been loaded',
76
+ })
77
+ );
78
+ },
79
+ onError() {
80
+ toggleNotification({
81
+ type: 'warning',
82
+ message: { id: getTrad('notification.error'), defaultMessage: 'An error occured' },
83
+ });
84
+ },
85
+ }
86
+ );
75
87
 
76
- const isLoading = isLoadingForPermissions || isLoadingData !== 'success';
88
+ const isLoading = isLoadingForPermissions || isLoadingData;
77
89
 
78
- const submitMutation = useMutation((body) => putAdvancedSettings(body), {
90
+ const submitMutation = useMutation((body) => put('/users-permissions/advanced', body), {
79
91
  async onSuccess() {
80
- await queryClient.invalidateQueries('advanced');
92
+ await queryClient.invalidateQueries(['users-permissions', 'advanced']);
93
+
81
94
  toggleNotification({
82
95
  type: 'success',
83
96
  message: { id: getTrad('notification.success.saved'), defaultMessage: 'Saved' },
@@ -85,11 +98,12 @@ const AdvancedSettingsPage = () => {
85
98
 
86
99
  unlockApp();
87
100
  },
88
- onError() {
101
+ onError(error) {
89
102
  toggleNotification({
90
103
  type: 'warning',
91
- message: { id: getTrad('notification.error'), defaultMessage: 'An error occured' },
104
+ message: formatAPIError(error),
92
105
  });
106
+
93
107
  unlockApp();
94
108
  },
95
109
  refetchActive: true,
@@ -100,9 +114,12 @@ const AdvancedSettingsPage = () => {
100
114
  const handleSubmit = async (body) => {
101
115
  lockApp();
102
116
 
103
- const urlConfirmation = body.email_confirmation ? body.email_confirmation_redirection : '';
104
-
105
- await submitMutation.mutateAsync({ ...body, email_confirmation_redirection: urlConfirmation });
117
+ submitMutation.mutate({
118
+ ...body,
119
+ email_confirmation_redirection: body.email_confirmation
120
+ ? body.email_confirmation_redirection
121
+ : '',
122
+ });
106
123
  };
107
124
 
108
125
  if (isLoading) {
@@ -1,10 +1,12 @@
1
- import React, { useRef, useState } from 'react';
1
+ import * as React from 'react';
2
2
 
3
3
  import { ContentLayout, HeaderLayout, Main, useNotifyAT } from '@strapi/design-system';
4
4
  import {
5
5
  CheckPagePermissions,
6
6
  LoadingIndicatorPage,
7
7
  SettingsPageTitle,
8
+ useAPIErrorHandler,
9
+ useFetchClient,
8
10
  useFocusWhenNavigate,
9
11
  useNotification,
10
12
  useOverlayBlocker,
@@ -19,7 +21,6 @@ import { getTrad } from '../../utils';
19
21
 
20
22
  import EmailForm from './components/EmailForm';
21
23
  import EmailTable from './components/EmailTable';
22
- import { fetchData, putEmailTemplate } from './utils/api';
23
24
 
24
25
  const ProtectedEmailTemplatesPage = () => (
25
26
  <CheckPagePermissions permissions={PERMISSIONS.readEmailTemplates}>
@@ -33,36 +34,46 @@ const EmailTemplatesPage = () => {
33
34
  const { notifyStatus } = useNotifyAT();
34
35
  const toggleNotification = useNotification();
35
36
  const { lockApp, unlockApp } = useOverlayBlocker();
36
- const trackUsageRef = useRef(trackUsage);
37
37
  const queryClient = useQueryClient();
38
+ const { get, put } = useFetchClient();
39
+ const { formatAPIError } = useAPIErrorHandler();
40
+
38
41
  useFocusWhenNavigate();
39
42
 
40
- const [isModalOpen, setIsModalOpen] = useState(false);
41
- const [templateToEdit, setTemplateToEdit] = useState(null);
43
+ const [isModalOpen, setIsModalOpen] = React.useState(false);
44
+ const [templateToEdit, setTemplateToEdit] = React.useState(null);
42
45
 
43
46
  const {
44
47
  isLoading: isLoadingForPermissions,
45
48
  allowedActions: { canUpdate },
46
49
  } = useRBAC({ update: PERMISSIONS.updateEmailTemplates });
47
50
 
48
- const { status: isLoadingData, data } = useQuery('email-templates', () => fetchData(), {
49
- onSuccess() {
50
- notifyStatus(
51
- formatMessage({
52
- id: getTrad('Email.template.data.loaded'),
53
- defaultMessage: 'Email templates has been loaded',
54
- })
55
- );
56
- },
57
- onError() {
58
- toggleNotification({
59
- type: 'warning',
60
- message: { id: 'notification.error', defaultMessage: 'An error occured' },
61
- });
51
+ const { isLoading: isLoadingData, data } = useQuery(
52
+ ['users-permissions', 'email-templates'],
53
+ async () => {
54
+ const { data } = await get('/users-permissions/email-templates');
55
+
56
+ return data;
62
57
  },
63
- });
58
+ {
59
+ onSuccess() {
60
+ notifyStatus(
61
+ formatMessage({
62
+ id: getTrad('Email.template.data.loaded'),
63
+ defaultMessage: 'Email templates has been loaded',
64
+ })
65
+ );
66
+ },
67
+ onError(error) {
68
+ toggleNotification({
69
+ type: 'warning',
70
+ message: formatAPIError(error),
71
+ });
72
+ },
73
+ }
74
+ );
64
75
 
65
- const isLoading = isLoadingForPermissions || isLoadingData !== 'success';
76
+ const isLoading = isLoadingForPermissions || isLoadingData;
66
77
 
67
78
  const handleToggle = () => {
68
79
  setIsModalOpen((prev) => !prev);
@@ -73,34 +84,38 @@ const EmailTemplatesPage = () => {
73
84
  handleToggle();
74
85
  };
75
86
 
76
- const submitMutation = useMutation((body) => putEmailTemplate({ 'email-templates': body }), {
77
- async onSuccess() {
78
- await queryClient.invalidateQueries('email-templates');
79
-
80
- toggleNotification({
81
- type: 'success',
82
- message: { id: 'notification.success.saved', defaultMessage: 'Saved' },
83
- });
84
-
85
- trackUsageRef.current('didEditEmailTemplates');
86
-
87
- unlockApp();
88
- handleToggle();
89
- },
90
- onError() {
91
- toggleNotification({
92
- type: 'warning',
93
- message: { id: 'notification.error', defaultMessage: 'An error occured' },
94
- });
95
- unlockApp();
96
- },
97
- refetchActive: true,
98
- });
99
- const { isLoading: isSubmittingForm } = submitMutation;
87
+ const submitMutation = useMutation(
88
+ (body) => put('/users-permissions/email-templates', { 'email-templates': body }),
89
+ {
90
+ async onSuccess() {
91
+ await queryClient.invalidateQueries(['users-permissions', 'email-templates']);
92
+
93
+ toggleNotification({
94
+ type: 'success',
95
+ message: { id: 'notification.success.saved', defaultMessage: 'Saved' },
96
+ });
97
+
98
+ trackUsage('didEditEmailTemplates');
99
+
100
+ unlockApp();
101
+ handleToggle();
102
+ },
103
+ onError(error) {
104
+ toggleNotification({
105
+ type: 'warning',
106
+ message: formatAPIError(error),
107
+ });
108
+
109
+ unlockApp();
110
+ },
111
+ refetchActive: true,
112
+ }
113
+ );
100
114
 
101
115
  const handleSubmit = (body) => {
102
116
  lockApp();
103
- trackUsageRef.current('willEditEmailTemplates');
117
+
118
+ trackUsage('willEditEmailTemplates');
104
119
 
105
120
  const editedTemplates = { ...data, [templateToEdit]: body };
106
121
  submitMutation.mutate(editedTemplates);
@@ -129,7 +144,7 @@ const EmailTemplatesPage = () => {
129
144
  }
130
145
 
131
146
  return (
132
- <Main aria-busy={isSubmittingForm}>
147
+ <Main aria-busy={submitMutation.isLoading}>
133
148
  <SettingsPageTitle
134
149
  name={formatMessage({
135
150
  id: getTrad('HeaderNav.link.emailTemplates'),
@@ -1,4 +1,4 @@
1
- import React, { useMemo, useRef, useState } from 'react';
1
+ import * as React from 'react';
2
2
 
3
3
  import {
4
4
  ContentLayout,
@@ -13,7 +13,6 @@ import {
13
13
  Thead,
14
14
  Tr,
15
15
  Typography,
16
- useNotifyAT,
17
16
  VisuallyHidden,
18
17
  } from '@strapi/design-system';
19
18
  import {
@@ -22,6 +21,9 @@ import {
22
21
  onRowClick,
23
22
  SettingsPageTitle,
24
23
  stopPropagation,
24
+ useAPIErrorHandler,
25
+ useCollator,
26
+ useFetchClient,
25
27
  useFocusWhenNavigate,
26
28
  useNotification,
27
29
  useOverlayBlocker,
@@ -29,7 +31,6 @@ import {
29
31
  useTracking,
30
32
  } from '@strapi/helper-plugin';
31
33
  import { Pencil } from '@strapi/icons';
32
- import has from 'lodash/has';
33
34
  import upperFirst from 'lodash/upperFirst';
34
35
  import { useIntl } from 'react-intl';
35
36
  import { useMutation, useQuery, useQueryClient } from 'react-query';
@@ -38,90 +39,94 @@ import FormModal from '../../components/FormModal';
38
39
  import { PERMISSIONS } from '../../constants';
39
40
  import { getTrad } from '../../utils';
40
41
 
41
- import { fetchData, putProvider } from './utils/api';
42
- import createProvidersArray from './utils/createProvidersArray';
43
42
  import forms from './utils/forms';
44
43
 
45
44
  export const ProvidersPage = () => {
46
- const { formatMessage } = useIntl();
47
- useFocusWhenNavigate();
48
- const { notifyStatus } = useNotifyAT();
45
+ const { formatMessage, locale } = useIntl();
49
46
  const queryClient = useQueryClient();
50
47
  const { trackUsage } = useTracking();
51
- const trackUsageRef = useRef(trackUsage);
52
- const [isOpen, setIsOpen] = useState(false);
53
- const [isSubmiting, setIsSubmiting] = useState(false);
54
- const [providerToEditName, setProviderToEditName] = useState(null);
48
+ const [isOpen, setIsOpen] = React.useState(false);
49
+ const [providerToEditName, setProviderToEditName] = React.useState(null);
55
50
  const toggleNotification = useNotification();
56
51
  const { lockApp, unlockApp } = useOverlayBlocker();
52
+ const { get, put } = useFetchClient();
53
+ const { formatAPIError } = useAPIErrorHandler();
54
+ const formatter = useCollator(locale, {
55
+ sensitivity: 'base',
56
+ });
57
+
58
+ useFocusWhenNavigate();
57
59
 
58
60
  const {
59
- isLoading: isLoadingForPermissions,
61
+ isLoading: isLoadingPermissions,
60
62
  allowedActions: { canUpdate },
61
63
  } = useRBAC({ update: PERMISSIONS.updateProviders });
62
64
 
63
- const {
64
- isLoading: isLoadingForData,
65
- data: modifiedData,
66
- isFetching,
67
- } = useQuery('get-providers', () => fetchData(toggleNotification), {
68
- onSuccess() {
69
- notifyStatus(
70
- formatMessage({
71
- id: getTrad('Providers.data.loaded'),
72
- defaultMessage: 'Providers have been loaded',
73
- })
74
- );
75
- },
76
- initialData: {},
77
- });
65
+ const { isLoading: isLoadingData, data } = useQuery(
66
+ ['users-permissions', 'get-providers'],
67
+ async () => {
68
+ const { data } = await get('/users-permissions/providers');
78
69
 
79
- const isLoading = isLoadingForData || isFetching;
70
+ return data;
71
+ },
72
+ {
73
+ initialData: {},
74
+ }
75
+ );
80
76
 
81
- const submitMutation = useMutation(putProvider, {
77
+ const submitMutation = useMutation((body) => put('/users-permissions/providers', body), {
82
78
  async onSuccess() {
83
- await queryClient.invalidateQueries('get-providers');
79
+ await queryClient.invalidateQueries(['users-permissions', 'providers']);
80
+
84
81
  toggleNotification({
85
- type: 'info',
82
+ type: 'success',
86
83
  message: { id: getTrad('notification.success.submit') },
87
84
  });
88
85
 
89
- trackUsageRef.current('didEditAuthenticationProvider');
90
- setIsSubmiting(false);
86
+ trackUsage('didEditAuthenticationProvider');
87
+
91
88
  handleToggleModal();
92
89
  unlockApp();
93
90
  },
94
- onError() {
91
+ onError(error) {
95
92
  toggleNotification({
96
93
  type: 'warning',
97
- message: { id: 'notification.error' },
94
+ message: formatAPIError(error),
98
95
  });
96
+
99
97
  unlockApp();
100
- setIsSubmiting(false);
101
98
  },
102
99
  refetchActive: false,
103
100
  });
104
101
 
105
- const providers = useMemo(() => createProvidersArray(modifiedData), [modifiedData]);
102
+ const providers = Object.entries(data)
103
+ .reduce((acc, [name, provider]) => {
104
+ const { icon, enabled, subdomain } = provider;
105
+
106
+ acc.push({
107
+ name,
108
+ icon: icon === 'envelope' ? ['fas', 'envelope'] : ['fab', icon],
109
+ enabled,
110
+ subdomain,
111
+ });
112
+
113
+ return acc;
114
+ }, [])
115
+ .sort((a, b) => formatter.compare(a.name, b.name));
106
116
 
107
- const rowCount = providers.length;
117
+ const isLoading = isLoadingData || isLoadingPermissions;
108
118
 
109
- const isProviderWithSubdomain = useMemo(() => {
119
+ const isProviderWithSubdomain = React.useMemo(() => {
110
120
  if (!providerToEditName) {
111
121
  return false;
112
122
  }
113
123
 
114
124
  const providerToEdit = providers.find((obj) => obj.name === providerToEditName);
115
125
 
116
- return has(providerToEdit, 'subdomain');
126
+ return !!providerToEdit?.subdomain;
117
127
  }, [providers, providerToEditName]);
118
128
 
119
- const pageTitle = formatMessage({
120
- id: getTrad('HeaderNav.link.providers'),
121
- defaultMessage: 'Providers',
122
- });
123
-
124
- const layoutToRender = useMemo(() => {
129
+ const layoutToRender = React.useMemo(() => {
125
130
  if (providerToEditName === 'email') {
126
131
  return forms.email;
127
132
  }
@@ -145,20 +150,21 @@ export const ProvidersPage = () => {
145
150
  };
146
151
 
147
152
  const handleSubmit = async (values) => {
148
- setIsSubmiting(true);
149
-
150
153
  lockApp();
151
154
 
152
- trackUsageRef.current('willEditAuthenticationProvider');
155
+ trackUsage('willEditAuthenticationProvider');
153
156
 
154
- const body = { ...modifiedData, [providerToEditName]: values };
155
-
156
- submitMutation.mutate({ providers: body });
157
+ submitMutation.mutate({ providers: { ...data, [providerToEditName]: values } });
157
158
  };
158
159
 
159
160
  return (
160
161
  <Layout>
161
- <SettingsPageTitle name={pageTitle} />
162
+ <SettingsPageTitle
163
+ name={formatMessage({
164
+ id: getTrad('HeaderNav.link.providers'),
165
+ defaultMessage: 'Providers',
166
+ })}
167
+ />
162
168
  <Main>
163
169
  <HeaderLayout
164
170
  title={formatMessage({
@@ -166,11 +172,11 @@ export const ProvidersPage = () => {
166
172
  defaultMessage: 'Providers',
167
173
  })}
168
174
  />
169
- {isLoading || isLoadingForPermissions ? (
175
+ {isLoading ? (
170
176
  <LoadingIndicatorPage />
171
177
  ) : (
172
178
  <ContentLayout>
173
- <Table colCount={3} rowCount={rowCount + 1}>
179
+ <Table colCount={3} rowCount={providers.length + 1}>
174
180
  <Thead>
175
181
  <Tr>
176
182
  <Th>
@@ -243,9 +249,9 @@ export const ProvidersPage = () => {
243
249
  )}
244
250
  </Main>
245
251
  <FormModal
246
- initialData={modifiedData[providerToEditName]}
252
+ initialData={data[providerToEditName]}
247
253
  isOpen={isOpen}
248
- isSubmiting={isSubmiting}
254
+ isSubmiting={submitMutation.isLoading}
249
255
  layout={layoutToRender}
250
256
  headerBreadcrumbs={[
251
257
  formatMessage({
@@ -3,8 +3,7 @@ import { useEffect } from 'react';
3
3
  import { useNotification, useFetchClient, useAPIErrorHandler } from '@strapi/helper-plugin';
4
4
  import { useQueries } from 'react-query';
5
5
 
6
- import pluginId from '../pluginId';
7
- import { cleanPermissions, getTrad } from '../utils';
6
+ import { cleanPermissions, getTrad } from '../../../utils';
8
7
 
9
8
  export const usePlugins = () => {
10
9
  const toggleNotification = useNotification();
@@ -21,19 +20,23 @@ export const usePlugins = () => {
21
20
  { data: routes, isLoading: isLoadingRoutes, error: routesError, refetch: refetchRoutes },
22
21
  ] = useQueries([
23
22
  {
24
- queryKey: [pluginId, 'permissions'],
23
+ queryKey: ['users-permissions', 'permissions'],
25
24
  async queryFn() {
26
- const res = await get(`/${pluginId}/permissions`);
25
+ const {
26
+ data: { permissions },
27
+ } = await get(`/users-permissions/permissions`);
27
28
 
28
- return res.data.permissions;
29
+ return permissions;
29
30
  },
30
31
  },
31
32
  {
32
- queryKey: [pluginId, 'routes'],
33
+ queryKey: ['users-permissions', 'routes'],
33
34
  async queryFn() {
34
- const res = await get(`/${pluginId}/routes`);
35
+ const {
36
+ data: { routes },
37
+ } = await get(`/users-permissions/routes`);
35
38
 
36
- return res.data.routes;
39
+ return routes;
37
40
  },
38
41
  },
39
42
  ]);
@@ -63,8 +66,12 @@ export const usePlugins = () => {
63
66
  const isLoading = isLoadingPermissions || isLoadingRoutes;
64
67
 
65
68
  return {
69
+ // TODO: these return values need to be memoized, otherwise
70
+ // they will create infinite rendering loops when used as
71
+ // effect dependencies
66
72
  permissions: permissions ? cleanPermissions(permissions) : {},
67
73
  routes: routes ?? {},
74
+
68
75
  getData: refetchQueries,
69
76
  isLoading,
70
77
  };
@@ -4,23 +4,26 @@ import { AnErrorOccurred, CheckPagePermissions } from '@strapi/helper-plugin';
4
4
  import { Route, Switch } from 'react-router-dom';
5
5
 
6
6
  import { PERMISSIONS } from '../../constants';
7
- import pluginId from '../../pluginId';
8
7
 
9
- import ProtectedRolesCreatePage from './ProtectedCreatePage';
10
- import ProtectedRolesEditPage from './ProtectedEditPage';
11
- import ProtectedRolesListPage from './ProtectedListPage';
8
+ import { ProtectedRolesCreatePage } from './pages/CreatePage';
9
+ import { ProtectedRolesEditPage } from './pages/EditPage';
10
+ import { ProtectedRolesListPage } from './pages/ListPage';
12
11
 
13
12
  const Roles = () => {
14
13
  return (
15
14
  <CheckPagePermissions permissions={PERMISSIONS.accessRoles}>
16
15
  <Switch>
17
16
  <Route
18
- path={`/settings/${pluginId}/roles/new`}
17
+ path="/settings/users-permissions/roles/new"
19
18
  component={ProtectedRolesCreatePage}
20
19
  exact
21
20
  />
22
- <Route path={`/settings/${pluginId}/roles/:id`} component={ProtectedRolesEditPage} exact />
23
- <Route path={`/settings/${pluginId}/roles`} component={ProtectedRolesListPage} exact />
21
+ <Route
22
+ path="/settings/users-permissions/roles/:id"
23
+ component={ProtectedRolesEditPage}
24
+ exact
25
+ />
26
+ <Route path="/settings/users-permissions/roles" component={ProtectedRolesListPage} exact />
24
27
  <Route path="" component={AnErrorOccurred} />
25
28
  </Switch>
26
29
  </CheckPagePermissions>