@strapi/plugin-users-permissions 0.0.0-next.c8d6478ec519888ce0cd754886474c3189efc733 → 0.0.0-next.ce51df0e18404afc8a1aa7f504c1006a7a221459
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.
- package/admin/src/components/Permissions/index.js +2 -4
- package/admin/src/index.js +16 -35
- package/admin/src/pages/AdvancedSettings/index.js +46 -30
- package/admin/src/pages/EmailTemplates/index.js +64 -53
- package/admin/src/pages/Providers/index.js +64 -62
- package/admin/src/{hooks → pages/Roles/hooks}/usePlugins.js +15 -8
- package/admin/src/pages/Roles/index.js +10 -7
- package/admin/src/pages/Roles/pages/CreatePage.js +190 -0
- package/admin/src/pages/Roles/pages/EditPage.js +211 -0
- package/admin/src/pages/Roles/{ListPage → pages/ListPage}/components/TableBody.js +44 -14
- package/admin/src/pages/Roles/{ListPage → pages/ListPage}/index.js +29 -30
- package/admin/src/pages/Roles/{ListPage → pages/ListPage}/utils/api.js +2 -4
- package/admin/src/translations/zh-Hans.json +80 -80
- package/admin/src/utils/index.js +0 -1
- package/documentation/content-api.yaml +1 -1
- package/jest.config.front.js +1 -1
- package/package.json +10 -10
- package/server/bootstrap/index.js +35 -0
- package/server/controllers/auth.js +46 -13
- package/server/controllers/user.js +12 -1
- package/server/middlewares/rateLimit.js +41 -21
- package/admin/src/hooks/index.js +0 -5
- package/admin/src/hooks/useFetchRole/index.js +0 -67
- package/admin/src/hooks/useFetchRole/reducer.js +0 -31
- package/admin/src/hooks/useForm/index.js +0 -70
- package/admin/src/hooks/useForm/reducer.js +0 -40
- package/admin/src/hooks/useRolesList/index.js +0 -65
- package/admin/src/hooks/useRolesList/init.js +0 -5
- package/admin/src/hooks/useRolesList/reducer.js +0 -31
- package/admin/src/pages/AdvancedSettings/utils/api.js +0 -18
- package/admin/src/pages/EmailTemplates/utils/api.js +0 -18
- package/admin/src/pages/Providers/reducer.js +0 -54
- package/admin/src/pages/Providers/utils/api.js +0 -26
- package/admin/src/pages/Providers/utils/createProvidersArray.js +0 -21
- package/admin/src/pages/Roles/CreatePage.js +0 -185
- package/admin/src/pages/Roles/EditPage.js +0 -197
- package/admin/src/pages/Roles/ProtectedCreatePage.js +0 -15
- package/admin/src/pages/Roles/ProtectedEditPage.js +0 -15
- package/admin/src/pages/Roles/ProtectedListPage.js +0 -17
- package/admin/src/utils/getRequestURL.js +0 -5
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { useReducer } from 'react';
|
|
2
2
|
|
|
3
|
-
import { Accordion, AccordionContent, AccordionToggle,
|
|
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
|
-
<
|
|
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
|
))}
|
package/admin/src/index.js
CHANGED
|
@@ -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:
|
|
21
|
+
id: 'users-permissions',
|
|
23
22
|
intlLabel: {
|
|
24
23
|
id: getTrad('Settings.section-label'),
|
|
25
24
|
defaultMessage: 'Users & Permissions plugin',
|
|
@@ -32,14 +31,9 @@ export default {
|
|
|
32
31
|
defaultMessage: 'Roles',
|
|
33
32
|
},
|
|
34
33
|
id: 'roles',
|
|
35
|
-
to: `/settings
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
/* webpackChunkName: "users-roles-settings-page" */ './pages/Roles'
|
|
39
|
-
);
|
|
40
|
-
|
|
41
|
-
return component;
|
|
42
|
-
},
|
|
34
|
+
to: `/settings/users-permissions/roles`,
|
|
35
|
+
Component: () =>
|
|
36
|
+
import(/* webpackChunkName: "users-roles-settings-page" */ './pages/Roles'),
|
|
43
37
|
permissions: PERMISSIONS.accessRoles,
|
|
44
38
|
},
|
|
45
39
|
{
|
|
@@ -48,14 +42,9 @@ export default {
|
|
|
48
42
|
defaultMessage: 'Providers',
|
|
49
43
|
},
|
|
50
44
|
id: 'providers',
|
|
51
|
-
to: `/settings
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
/* webpackChunkName: "users-providers-settings-page" */ './pages/Providers'
|
|
55
|
-
);
|
|
56
|
-
|
|
57
|
-
return component;
|
|
58
|
-
},
|
|
45
|
+
to: `/settings/users-permissions/providers`,
|
|
46
|
+
Component: () =>
|
|
47
|
+
import(/* webpackChunkName: "users-providers-settings-page" */ './pages/Providers'),
|
|
59
48
|
permissions: PERMISSIONS.readProviders,
|
|
60
49
|
},
|
|
61
50
|
{
|
|
@@ -64,14 +53,9 @@ export default {
|
|
|
64
53
|
defaultMessage: 'Email templates',
|
|
65
54
|
},
|
|
66
55
|
id: 'email-templates',
|
|
67
|
-
to: `/settings
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
/* webpackChunkName: "users-email-settings-page" */ './pages/EmailTemplates'
|
|
71
|
-
);
|
|
72
|
-
|
|
73
|
-
return component;
|
|
74
|
-
},
|
|
56
|
+
to: `/settings/users-permissions/email-templates`,
|
|
57
|
+
Component: () =>
|
|
58
|
+
import(/* webpackChunkName: "users-email-settings-page" */ './pages/EmailTemplates'),
|
|
75
59
|
permissions: PERMISSIONS.readEmailTemplates,
|
|
76
60
|
},
|
|
77
61
|
{
|
|
@@ -80,21 +64,18 @@ export default {
|
|
|
80
64
|
defaultMessage: 'Advanced Settings',
|
|
81
65
|
},
|
|
82
66
|
id: 'advanced-settings',
|
|
83
|
-
to: `/settings
|
|
84
|
-
|
|
85
|
-
|
|
67
|
+
to: `/settings/users-permissions/advanced-settings`,
|
|
68
|
+
Component: () =>
|
|
69
|
+
import(
|
|
86
70
|
/* webpackChunkName: "users-advanced-settings-page" */ './pages/AdvancedSettings'
|
|
87
|
-
)
|
|
88
|
-
|
|
89
|
-
return component;
|
|
90
|
-
},
|
|
71
|
+
),
|
|
91
72
|
permissions: PERMISSIONS.readAdvancedSettings,
|
|
92
73
|
},
|
|
93
74
|
]
|
|
94
75
|
);
|
|
95
76
|
|
|
96
77
|
app.registerPlugin({
|
|
97
|
-
id:
|
|
78
|
+
id: 'users-permissions',
|
|
98
79
|
name,
|
|
99
80
|
});
|
|
100
81
|
},
|
|
@@ -107,7 +88,7 @@ export default {
|
|
|
107
88
|
)
|
|
108
89
|
.then(({ default: data }) => {
|
|
109
90
|
return {
|
|
110
|
-
data: prefixPluginTranslations(data,
|
|
91
|
+
data: prefixPluginTranslations(data, 'users-permissions'),
|
|
111
92
|
locale,
|
|
112
93
|
};
|
|
113
94
|
})
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React
|
|
1
|
+
import React from 'react';
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
4
|
Box,
|
|
@@ -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,36 +50,47 @@ 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
|
-
const updatePermissions = useMemo(() => ({ update: PERMISSIONS.updateAdvancedSettings }), []);
|
|
55
58
|
const {
|
|
56
59
|
isLoading: isLoadingForPermissions,
|
|
57
60
|
allowedActions: { canUpdate },
|
|
58
|
-
} = useRBAC(
|
|
59
|
-
|
|
60
|
-
const {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
})
|
|
67
|
-
);
|
|
68
|
-
},
|
|
69
|
-
onError() {
|
|
70
|
-
toggleNotification({
|
|
71
|
-
type: 'warning',
|
|
72
|
-
message: { id: getTrad('notification.error'), defaultMessage: 'An error occured' },
|
|
73
|
-
});
|
|
61
|
+
} = useRBAC({ update: PERMISSIONS.updateAdvancedSettings });
|
|
62
|
+
|
|
63
|
+
const { isLoading: isLoadingData, data } = useQuery(
|
|
64
|
+
['users-permissions', 'advanced'],
|
|
65
|
+
async () => {
|
|
66
|
+
const { data } = await get('/users-permissions/advanced');
|
|
67
|
+
|
|
68
|
+
return data;
|
|
74
69
|
},
|
|
75
|
-
|
|
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
|
+
);
|
|
76
87
|
|
|
77
|
-
const isLoading = isLoadingForPermissions || isLoadingData
|
|
88
|
+
const isLoading = isLoadingForPermissions || isLoadingData;
|
|
78
89
|
|
|
79
|
-
const submitMutation = useMutation((body) =>
|
|
90
|
+
const submitMutation = useMutation((body) => put('/users-permissions/advanced', body), {
|
|
80
91
|
async onSuccess() {
|
|
81
|
-
await queryClient.invalidateQueries('advanced');
|
|
92
|
+
await queryClient.invalidateQueries(['users-permissions', 'advanced']);
|
|
93
|
+
|
|
82
94
|
toggleNotification({
|
|
83
95
|
type: 'success',
|
|
84
96
|
message: { id: getTrad('notification.success.saved'), defaultMessage: 'Saved' },
|
|
@@ -86,11 +98,12 @@ const AdvancedSettingsPage = () => {
|
|
|
86
98
|
|
|
87
99
|
unlockApp();
|
|
88
100
|
},
|
|
89
|
-
onError() {
|
|
101
|
+
onError(error) {
|
|
90
102
|
toggleNotification({
|
|
91
103
|
type: 'warning',
|
|
92
|
-
message:
|
|
104
|
+
message: formatAPIError(error),
|
|
93
105
|
});
|
|
106
|
+
|
|
94
107
|
unlockApp();
|
|
95
108
|
},
|
|
96
109
|
refetchActive: true,
|
|
@@ -101,9 +114,12 @@ const AdvancedSettingsPage = () => {
|
|
|
101
114
|
const handleSubmit = async (body) => {
|
|
102
115
|
lockApp();
|
|
103
116
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
117
|
+
submitMutation.mutate({
|
|
118
|
+
...body,
|
|
119
|
+
email_confirmation_redirection: body.email_confirmation
|
|
120
|
+
? body.email_confirmation_redirection
|
|
121
|
+
: '',
|
|
122
|
+
});
|
|
107
123
|
};
|
|
108
124
|
|
|
109
125
|
if (isLoading) {
|
|
@@ -143,7 +159,7 @@ const AdvancedSettingsPage = () => {
|
|
|
143
159
|
validationSchema={schema}
|
|
144
160
|
enableReinitialize
|
|
145
161
|
>
|
|
146
|
-
{({ errors, values, handleChange, isSubmitting }) => {
|
|
162
|
+
{({ errors, values, handleChange, isSubmitting, dirty }) => {
|
|
147
163
|
return (
|
|
148
164
|
<Form>
|
|
149
165
|
<HeaderLayout
|
|
@@ -155,7 +171,7 @@ const AdvancedSettingsPage = () => {
|
|
|
155
171
|
<Button
|
|
156
172
|
loading={isSubmitting}
|
|
157
173
|
type="submit"
|
|
158
|
-
disabled={!canUpdate}
|
|
174
|
+
disabled={canUpdate ? !dirty : !canUpdate}
|
|
159
175
|
startIcon={<Check />}
|
|
160
176
|
size="S"
|
|
161
177
|
>
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import
|
|
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,40 +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
|
-
|
|
38
|
+
const { get, put } = useFetchClient();
|
|
39
|
+
const { formatAPIError } = useAPIErrorHandler();
|
|
39
40
|
|
|
40
|
-
|
|
41
|
-
const [templateToEdit, setTemplateToEdit] = useState(null);
|
|
41
|
+
useFocusWhenNavigate();
|
|
42
42
|
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
}, []);
|
|
43
|
+
const [isModalOpen, setIsModalOpen] = React.useState(false);
|
|
44
|
+
const [templateToEdit, setTemplateToEdit] = React.useState(null);
|
|
46
45
|
|
|
47
46
|
const {
|
|
48
47
|
isLoading: isLoadingForPermissions,
|
|
49
48
|
allowedActions: { canUpdate },
|
|
50
|
-
} = useRBAC(
|
|
51
|
-
|
|
52
|
-
const {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
})
|
|
59
|
-
);
|
|
60
|
-
},
|
|
61
|
-
onError() {
|
|
62
|
-
toggleNotification({
|
|
63
|
-
type: 'warning',
|
|
64
|
-
message: { id: 'notification.error', defaultMessage: 'An error occured' },
|
|
65
|
-
});
|
|
49
|
+
} = useRBAC({ update: PERMISSIONS.updateEmailTemplates });
|
|
50
|
+
|
|
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;
|
|
66
57
|
},
|
|
67
|
-
|
|
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
|
+
);
|
|
68
75
|
|
|
69
|
-
const isLoading = isLoadingForPermissions || isLoadingData
|
|
76
|
+
const isLoading = isLoadingForPermissions || isLoadingData;
|
|
70
77
|
|
|
71
78
|
const handleToggle = () => {
|
|
72
79
|
setIsModalOpen((prev) => !prev);
|
|
@@ -77,34 +84,38 @@ const EmailTemplatesPage = () => {
|
|
|
77
84
|
handleToggle();
|
|
78
85
|
};
|
|
79
86
|
|
|
80
|
-
const submitMutation = useMutation(
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
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
|
+
);
|
|
104
114
|
|
|
105
115
|
const handleSubmit = (body) => {
|
|
106
116
|
lockApp();
|
|
107
|
-
|
|
117
|
+
|
|
118
|
+
trackUsage('willEditEmailTemplates');
|
|
108
119
|
|
|
109
120
|
const editedTemplates = { ...data, [templateToEdit]: body };
|
|
110
121
|
submitMutation.mutate(editedTemplates);
|
|
@@ -133,7 +144,7 @@ const EmailTemplatesPage = () => {
|
|
|
133
144
|
}
|
|
134
145
|
|
|
135
146
|
return (
|
|
136
|
-
<Main aria-busy={
|
|
147
|
+
<Main aria-busy={submitMutation.isLoading}>
|
|
137
148
|
<SettingsPageTitle
|
|
138
149
|
name={formatMessage({
|
|
139
150
|
id: getTrad('HeaderNav.link.emailTemplates'),
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
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,94 +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
|
|
52
|
-
const [
|
|
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
57
|
|
|
58
|
-
|
|
59
|
-
return { update: PERMISSIONS.updateProviders };
|
|
60
|
-
}, []);
|
|
58
|
+
useFocusWhenNavigate();
|
|
61
59
|
|
|
62
60
|
const {
|
|
63
|
-
isLoading:
|
|
61
|
+
isLoading: isLoadingPermissions,
|
|
64
62
|
allowedActions: { canUpdate },
|
|
65
|
-
} = useRBAC(
|
|
63
|
+
} = useRBAC({ update: PERMISSIONS.updateProviders });
|
|
66
64
|
|
|
67
|
-
const {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
} = useQuery('get-providers', () => fetchData(toggleNotification), {
|
|
72
|
-
onSuccess() {
|
|
73
|
-
notifyStatus(
|
|
74
|
-
formatMessage({
|
|
75
|
-
id: getTrad('Providers.data.loaded'),
|
|
76
|
-
defaultMessage: 'Providers have been loaded',
|
|
77
|
-
})
|
|
78
|
-
);
|
|
79
|
-
},
|
|
80
|
-
initialData: {},
|
|
81
|
-
});
|
|
65
|
+
const { isLoading: isLoadingData, data } = useQuery(
|
|
66
|
+
['users-permissions', 'get-providers'],
|
|
67
|
+
async () => {
|
|
68
|
+
const { data } = await get('/users-permissions/providers');
|
|
82
69
|
|
|
83
|
-
|
|
70
|
+
return data;
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
initialData: {},
|
|
74
|
+
}
|
|
75
|
+
);
|
|
84
76
|
|
|
85
|
-
const submitMutation = useMutation(
|
|
77
|
+
const submitMutation = useMutation((body) => put('/users-permissions/providers', body), {
|
|
86
78
|
async onSuccess() {
|
|
87
|
-
await queryClient.invalidateQueries('
|
|
79
|
+
await queryClient.invalidateQueries(['users-permissions', 'providers']);
|
|
80
|
+
|
|
88
81
|
toggleNotification({
|
|
89
|
-
type: '
|
|
82
|
+
type: 'success',
|
|
90
83
|
message: { id: getTrad('notification.success.submit') },
|
|
91
84
|
});
|
|
92
85
|
|
|
93
|
-
|
|
94
|
-
|
|
86
|
+
trackUsage('didEditAuthenticationProvider');
|
|
87
|
+
|
|
95
88
|
handleToggleModal();
|
|
96
89
|
unlockApp();
|
|
97
90
|
},
|
|
98
|
-
onError() {
|
|
91
|
+
onError(error) {
|
|
99
92
|
toggleNotification({
|
|
100
93
|
type: 'warning',
|
|
101
|
-
message:
|
|
94
|
+
message: formatAPIError(error),
|
|
102
95
|
});
|
|
96
|
+
|
|
103
97
|
unlockApp();
|
|
104
|
-
setIsSubmiting(false);
|
|
105
98
|
},
|
|
106
99
|
refetchActive: false,
|
|
107
100
|
});
|
|
108
101
|
|
|
109
|
-
const providers =
|
|
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));
|
|
110
116
|
|
|
111
|
-
const
|
|
117
|
+
const isLoading = isLoadingData || isLoadingPermissions;
|
|
112
118
|
|
|
113
|
-
const isProviderWithSubdomain = useMemo(() => {
|
|
119
|
+
const isProviderWithSubdomain = React.useMemo(() => {
|
|
114
120
|
if (!providerToEditName) {
|
|
115
121
|
return false;
|
|
116
122
|
}
|
|
117
123
|
|
|
118
124
|
const providerToEdit = providers.find((obj) => obj.name === providerToEditName);
|
|
119
125
|
|
|
120
|
-
return
|
|
126
|
+
return !!providerToEdit?.subdomain;
|
|
121
127
|
}, [providers, providerToEditName]);
|
|
122
128
|
|
|
123
|
-
const
|
|
124
|
-
id: getTrad('HeaderNav.link.providers'),
|
|
125
|
-
defaultMessage: 'Providers',
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
const layoutToRender = useMemo(() => {
|
|
129
|
+
const layoutToRender = React.useMemo(() => {
|
|
129
130
|
if (providerToEditName === 'email') {
|
|
130
131
|
return forms.email;
|
|
131
132
|
}
|
|
@@ -149,20 +150,21 @@ export const ProvidersPage = () => {
|
|
|
149
150
|
};
|
|
150
151
|
|
|
151
152
|
const handleSubmit = async (values) => {
|
|
152
|
-
setIsSubmiting(true);
|
|
153
|
-
|
|
154
153
|
lockApp();
|
|
155
154
|
|
|
156
|
-
|
|
155
|
+
trackUsage('willEditAuthenticationProvider');
|
|
157
156
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
submitMutation.mutate({ providers: body });
|
|
157
|
+
submitMutation.mutate({ providers: { ...data, [providerToEditName]: values } });
|
|
161
158
|
};
|
|
162
159
|
|
|
163
160
|
return (
|
|
164
161
|
<Layout>
|
|
165
|
-
<SettingsPageTitle
|
|
162
|
+
<SettingsPageTitle
|
|
163
|
+
name={formatMessage({
|
|
164
|
+
id: getTrad('HeaderNav.link.providers'),
|
|
165
|
+
defaultMessage: 'Providers',
|
|
166
|
+
})}
|
|
167
|
+
/>
|
|
166
168
|
<Main>
|
|
167
169
|
<HeaderLayout
|
|
168
170
|
title={formatMessage({
|
|
@@ -170,11 +172,11 @@ export const ProvidersPage = () => {
|
|
|
170
172
|
defaultMessage: 'Providers',
|
|
171
173
|
})}
|
|
172
174
|
/>
|
|
173
|
-
{isLoading
|
|
175
|
+
{isLoading ? (
|
|
174
176
|
<LoadingIndicatorPage />
|
|
175
177
|
) : (
|
|
176
178
|
<ContentLayout>
|
|
177
|
-
<Table colCount={3} rowCount={
|
|
179
|
+
<Table colCount={3} rowCount={providers.length + 1}>
|
|
178
180
|
<Thead>
|
|
179
181
|
<Tr>
|
|
180
182
|
<Th>
|
|
@@ -247,9 +249,9 @@ export const ProvidersPage = () => {
|
|
|
247
249
|
)}
|
|
248
250
|
</Main>
|
|
249
251
|
<FormModal
|
|
250
|
-
initialData={
|
|
252
|
+
initialData={data[providerToEditName]}
|
|
251
253
|
isOpen={isOpen}
|
|
252
|
-
isSubmiting={
|
|
254
|
+
isSubmiting={submitMutation.isLoading}
|
|
253
255
|
layout={layoutToRender}
|
|
254
256
|
headerBreadcrumbs={[
|
|
255
257
|
formatMessage({
|