@strapi/plugin-users-permissions 0.0.0-next.d1dda661d262d4773c59ee693c38542d9b0dc54c → 0.0.0-next.d2d15ef227d67cce89c2673764c0555c841cd29c

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 (220) 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 +19 -47
  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.jsx +148 -0
  21. package/admin/src/pages/EmailTemplates/utils/schema.js +18 -6
  22. package/admin/src/pages/Providers/index.jsx +262 -0
  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/{hooks → pages/Roles/hooks}/usePlugins.js +19 -12
  26. package/admin/src/pages/Roles/index.jsx +24 -0
  27. package/admin/src/pages/Roles/pages/CreatePage.jsx +194 -0
  28. package/admin/src/pages/Roles/pages/EditPage.jsx +215 -0
  29. package/admin/src/pages/Roles/pages/ListPage/components/TableBody.jsx +119 -0
  30. package/admin/src/pages/Roles/{ListPage/index.js → pages/ListPage/index.jsx} +105 -80
  31. package/admin/src/translations/en.json +1 -1
  32. package/admin/src/translations/zh-Hans.json +80 -80
  33. package/admin/src/utils/index.js +0 -1
  34. package/admin/src/utils/prefixPluginTranslations.js +13 -0
  35. package/dist/_chunks/ar-BguGUqwK.js +44 -0
  36. package/dist/_chunks/ar-BguGUqwK.js.map +1 -0
  37. package/dist/_chunks/ar-CK8BRRXB.mjs +44 -0
  38. package/dist/_chunks/ar-CK8BRRXB.mjs.map +1 -0
  39. package/dist/_chunks/cs-BVigMk0l.mjs +50 -0
  40. package/dist/_chunks/cs-BVigMk0l.mjs.map +1 -0
  41. package/dist/_chunks/cs-BW8-K_GY.js +50 -0
  42. package/dist/_chunks/cs-BW8-K_GY.js.map +1 -0
  43. package/dist/_chunks/de-BKUdRFI4.mjs +62 -0
  44. package/dist/_chunks/de-BKUdRFI4.mjs.map +1 -0
  45. package/dist/_chunks/de-owXpVluI.js +62 -0
  46. package/dist/_chunks/de-owXpVluI.js.map +1 -0
  47. package/dist/_chunks/dk-BQiTK50l.mjs +86 -0
  48. package/dist/_chunks/dk-BQiTK50l.mjs.map +1 -0
  49. package/dist/_chunks/dk-LXAnbuBk.js +86 -0
  50. package/dist/_chunks/dk-LXAnbuBk.js.map +1 -0
  51. package/dist/_chunks/en-DOHtPf-2.mjs +86 -0
  52. package/dist/_chunks/en-DOHtPf-2.mjs.map +1 -0
  53. package/dist/_chunks/en-MHo5mcsU.js +86 -0
  54. package/dist/_chunks/en-MHo5mcsU.js.map +1 -0
  55. package/dist/_chunks/es-BwLCLXAQ.js +86 -0
  56. package/dist/_chunks/es-BwLCLXAQ.js.map +1 -0
  57. package/dist/_chunks/es-DNgOVMjD.mjs +86 -0
  58. package/dist/_chunks/es-DNgOVMjD.mjs.map +1 -0
  59. package/dist/_chunks/fr-DkgRugiU.mjs +50 -0
  60. package/dist/_chunks/fr-DkgRugiU.mjs.map +1 -0
  61. package/dist/_chunks/fr-DkhpSjjm.js +50 -0
  62. package/dist/_chunks/fr-DkhpSjjm.js.map +1 -0
  63. package/dist/_chunks/id-BTemOeTZ.js +62 -0
  64. package/dist/_chunks/id-BTemOeTZ.js.map +1 -0
  65. package/dist/_chunks/id-BdEsvnaF.mjs +62 -0
  66. package/dist/_chunks/id-BdEsvnaF.mjs.map +1 -0
  67. package/dist/_chunks/index-B9cFxoCN.mjs +615 -0
  68. package/dist/_chunks/index-B9cFxoCN.mjs.map +1 -0
  69. package/dist/_chunks/index-BJTnrL31.js +281 -0
  70. package/dist/_chunks/index-BJTnrL31.js.map +1 -0
  71. package/dist/_chunks/index-CAgV-G5k.js +1173 -0
  72. package/dist/_chunks/index-CAgV-G5k.js.map +1 -0
  73. package/dist/_chunks/index-CI_b1cXd.mjs +1143 -0
  74. package/dist/_chunks/index-CI_b1cXd.mjs.map +1 -0
  75. package/dist/_chunks/index-Cb03Ke48.js +366 -0
  76. package/dist/_chunks/index-Cb03Ke48.js.map +1 -0
  77. package/dist/_chunks/index-DDglyd0X.mjs +262 -0
  78. package/dist/_chunks/index-DDglyd0X.mjs.map +1 -0
  79. package/dist/_chunks/index-DJOPnOVo.mjs +344 -0
  80. package/dist/_chunks/index-DJOPnOVo.mjs.map +1 -0
  81. package/dist/_chunks/index-QPUYgtlo-BfJxOAzF.mjs +11845 -0
  82. package/dist/_chunks/index-QPUYgtlo-BfJxOAzF.mjs.map +1 -0
  83. package/dist/_chunks/index-QPUYgtlo-QiBdpWEj.js +11869 -0
  84. package/dist/_chunks/index-QPUYgtlo-QiBdpWEj.js.map +1 -0
  85. package/dist/_chunks/index-_vrdPeYp.js +248 -0
  86. package/dist/_chunks/index-_vrdPeYp.js.map +1 -0
  87. package/dist/_chunks/index-bDCZWhLO.mjs +249 -0
  88. package/dist/_chunks/index-bDCZWhLO.mjs.map +1 -0
  89. package/dist/_chunks/index-cL_YxyjM.js +638 -0
  90. package/dist/_chunks/index-cL_YxyjM.js.map +1 -0
  91. package/dist/_chunks/it-B-rv0E24.mjs +62 -0
  92. package/dist/_chunks/it-B-rv0E24.mjs.map +1 -0
  93. package/dist/_chunks/it-D1rH6V6_.js +62 -0
  94. package/dist/_chunks/it-D1rH6V6_.js.map +1 -0
  95. package/dist/_chunks/ja-C8K-VBPD.mjs +48 -0
  96. package/dist/_chunks/ja-C8K-VBPD.mjs.map +1 -0
  97. package/dist/_chunks/ja-DqShgTMf.js +48 -0
  98. package/dist/_chunks/ja-DqShgTMf.js.map +1 -0
  99. package/dist/_chunks/ko-B9DGEPWH.js +86 -0
  100. package/dist/_chunks/ko-B9DGEPWH.js.map +1 -0
  101. package/dist/_chunks/ko-Busb0wIY.mjs +86 -0
  102. package/dist/_chunks/ko-Busb0wIY.mjs.map +1 -0
  103. package/dist/_chunks/ms-ByvsQjRt.mjs +49 -0
  104. package/dist/_chunks/ms-ByvsQjRt.mjs.map +1 -0
  105. package/dist/_chunks/ms-CPBU3LWf.js +49 -0
  106. package/dist/_chunks/ms-CPBU3LWf.js.map +1 -0
  107. package/dist/_chunks/nl-5qO8Rpcy.mjs +48 -0
  108. package/dist/_chunks/nl-5qO8Rpcy.mjs.map +1 -0
  109. package/dist/_chunks/nl-CwNB6YoO.js +48 -0
  110. package/dist/_chunks/nl-CwNB6YoO.js.map +1 -0
  111. package/dist/_chunks/pl-BdIzifBE.mjs +86 -0
  112. package/dist/_chunks/pl-BdIzifBE.mjs.map +1 -0
  113. package/dist/_chunks/pl-Do9UD69f.js +86 -0
  114. package/dist/_chunks/pl-Do9UD69f.js.map +1 -0
  115. package/dist/_chunks/pt-BIO24ioG.mjs +48 -0
  116. package/dist/_chunks/pt-BIO24ioG.mjs.map +1 -0
  117. package/dist/_chunks/pt-BR-D7dZhxuP.js +44 -0
  118. package/dist/_chunks/pt-BR-D7dZhxuP.js.map +1 -0
  119. package/dist/_chunks/pt-BR-f0p23AQZ.mjs +44 -0
  120. package/dist/_chunks/pt-BR-f0p23AQZ.mjs.map +1 -0
  121. package/dist/_chunks/pt-fdvyOnUp.js +48 -0
  122. package/dist/_chunks/pt-fdvyOnUp.js.map +1 -0
  123. package/dist/_chunks/ru-C94rjPGA.js +86 -0
  124. package/dist/_chunks/ru-C94rjPGA.js.map +1 -0
  125. package/dist/_chunks/ru-VWy-IB7K.mjs +86 -0
  126. package/dist/_chunks/ru-VWy-IB7K.mjs.map +1 -0
  127. package/dist/_chunks/sk-BABEhykl.js +50 -0
  128. package/dist/_chunks/sk-BABEhykl.js.map +1 -0
  129. package/dist/_chunks/sk-B_LIcepm.mjs +50 -0
  130. package/dist/_chunks/sk-B_LIcepm.mjs.map +1 -0
  131. package/dist/_chunks/sv-ABLKOokl.mjs +86 -0
  132. package/dist/_chunks/sv-ABLKOokl.mjs.map +1 -0
  133. package/dist/_chunks/sv-Be43LhA9.js +86 -0
  134. package/dist/_chunks/sv-Be43LhA9.js.map +1 -0
  135. package/dist/_chunks/th-DKyP7ueR.mjs +60 -0
  136. package/dist/_chunks/th-DKyP7ueR.mjs.map +1 -0
  137. package/dist/_chunks/th-DgVhVLhL.js +60 -0
  138. package/dist/_chunks/th-DgVhVLhL.js.map +1 -0
  139. package/dist/_chunks/tr-B_idhkEs.js +85 -0
  140. package/dist/_chunks/tr-B_idhkEs.js.map +1 -0
  141. package/dist/_chunks/tr-qa1Q5UjC.mjs +85 -0
  142. package/dist/_chunks/tr-qa1Q5UjC.mjs.map +1 -0
  143. package/dist/_chunks/uk-BmRqbeQc.mjs +49 -0
  144. package/dist/_chunks/uk-BmRqbeQc.mjs.map +1 -0
  145. package/dist/_chunks/uk-LHOivnhP.js +49 -0
  146. package/dist/_chunks/uk-LHOivnhP.js.map +1 -0
  147. package/dist/_chunks/vi-CdVRdKDw.js +50 -0
  148. package/dist/_chunks/vi-CdVRdKDw.js.map +1 -0
  149. package/dist/_chunks/vi-HW-EdMea.mjs +50 -0
  150. package/dist/_chunks/vi-HW-EdMea.mjs.map +1 -0
  151. package/dist/_chunks/zh-5hKkVPA4.mjs +86 -0
  152. package/dist/_chunks/zh-5hKkVPA4.mjs.map +1 -0
  153. package/dist/_chunks/zh-Cuq8gMnF.js +86 -0
  154. package/dist/_chunks/zh-Cuq8gMnF.js.map +1 -0
  155. package/dist/_chunks/zh-Hans-BHilK-yc.mjs +86 -0
  156. package/dist/_chunks/zh-Hans-BHilK-yc.mjs.map +1 -0
  157. package/dist/_chunks/zh-Hans-GQDMKtY4.js +86 -0
  158. package/dist/_chunks/zh-Hans-GQDMKtY4.js.map +1 -0
  159. package/dist/admin/index.js +4 -0
  160. package/dist/admin/index.js.map +1 -0
  161. package/dist/admin/index.mjs +5 -0
  162. package/dist/admin/index.mjs.map +1 -0
  163. package/documentation/content-api.yaml +1 -1
  164. package/jest.config.front.js +1 -1
  165. package/package.json +47 -28
  166. package/packup.config.ts +22 -0
  167. package/server/bootstrap/index.js +18 -15
  168. package/server/bootstrap/users-permissions-actions.js +6 -0
  169. package/server/config.js +29 -0
  170. package/server/content-types/user/index.js +0 -1
  171. package/server/controllers/auth.js +60 -34
  172. package/server/controllers/content-manager-user.js +28 -30
  173. package/server/controllers/role.js +1 -1
  174. package/server/controllers/user.js +18 -8
  175. package/server/middlewares/rateLimit.js +41 -21
  176. package/server/register.js +1 -1
  177. package/server/services/jwt.js +3 -3
  178. package/server/services/permission.js +3 -7
  179. package/server/services/providers-registry.js +469 -261
  180. package/server/services/providers.js +10 -5
  181. package/server/services/role.js +15 -13
  182. package/server/services/user.js +56 -19
  183. package/server/services/users-permissions.js +15 -13
  184. package/server/utils/index.d.ts +2 -1
  185. package/server/utils/sanitize/sanitizers.js +7 -3
  186. package/server/utils/sanitize/visitors/remove-user-relation-from-role-entities.js +2 -2
  187. package/.eslintrc.js +0 -14
  188. package/admin/src/components/FormModal/index.js +0 -126
  189. package/admin/src/components/Permissions/index.js +0 -57
  190. package/admin/src/hooks/index.js +0 -5
  191. package/admin/src/hooks/useFetchRole/index.js +0 -67
  192. package/admin/src/hooks/useFetchRole/reducer.js +0 -31
  193. package/admin/src/hooks/useForm/index.js +0 -70
  194. package/admin/src/hooks/useForm/reducer.js +0 -40
  195. package/admin/src/hooks/useRolesList/index.js +0 -65
  196. package/admin/src/hooks/useRolesList/init.js +0 -5
  197. package/admin/src/hooks/useRolesList/reducer.js +0 -31
  198. package/admin/src/pages/AdvancedSettings/index.js +0 -243
  199. package/admin/src/pages/AdvancedSettings/utils/api.js +0 -18
  200. package/admin/src/pages/EmailTemplates/components/EmailForm.js +0 -176
  201. package/admin/src/pages/EmailTemplates/index.js +0 -163
  202. package/admin/src/pages/EmailTemplates/utils/api.js +0 -18
  203. package/admin/src/pages/Providers/index.js +0 -275
  204. package/admin/src/pages/Providers/reducer.js +0 -54
  205. package/admin/src/pages/Providers/utils/api.js +0 -26
  206. package/admin/src/pages/Providers/utils/createProvidersArray.js +0 -21
  207. package/admin/src/pages/Roles/CreatePage.js +0 -185
  208. package/admin/src/pages/Roles/EditPage.js +0 -197
  209. package/admin/src/pages/Roles/ListPage/components/TableBody.js +0 -93
  210. package/admin/src/pages/Roles/ListPage/utils/api.js +0 -32
  211. package/admin/src/pages/Roles/ProtectedCreatePage.js +0 -15
  212. package/admin/src/pages/Roles/ProtectedEditPage.js +0 -15
  213. package/admin/src/pages/Roles/ProtectedListPage.js +0 -17
  214. package/admin/src/pages/Roles/index.js +0 -30
  215. package/admin/src/utils/getRequestURL.js +0 -5
  216. package/server/bootstrap/grant-config.js +0 -131
  217. package/strapi-admin.js +0 -3
  218. package/strapi-server.js +0 -3
  219. /package/admin/src/components/Permissions/PermissionRow/{index.js → index.jsx} +0 -0
  220. /package/admin/src/contexts/UsersPermissionsContext/{index.js → index.jsx} +0 -0
@@ -1,176 +0,0 @@
1
- import React from 'react';
2
-
3
- import {
4
- Button,
5
- Grid,
6
- GridItem,
7
- ModalBody,
8
- ModalFooter,
9
- ModalHeader,
10
- ModalLayout,
11
- Textarea,
12
- } from '@strapi/design-system';
13
- import { Breadcrumbs, Crumb } from '@strapi/design-system/v2';
14
- import { Form, GenericInput } from '@strapi/helper-plugin';
15
- import { Formik } from 'formik';
16
- import PropTypes from 'prop-types';
17
- import { useIntl } from 'react-intl';
18
-
19
- import { getTrad } from '../../../utils';
20
- import schema from '../utils/schema';
21
-
22
- const EmailForm = ({ template, onToggle, onSubmit }) => {
23
- const { formatMessage } = useIntl();
24
-
25
- return (
26
- <ModalLayout
27
- onClose={onToggle}
28
- labelledBy={`${formatMessage({
29
- id: getTrad('PopUpForm.header.edit.email-templates'),
30
- defaultMessage: 'Edit email template',
31
- })}, ${formatMessage({ id: getTrad(template.display), defaultMessage: template.display })}`}
32
- >
33
- <ModalHeader>
34
- <Breadcrumbs
35
- label={`${formatMessage({
36
- id: getTrad('PopUpForm.header.edit.email-templates'),
37
- defaultMessage: 'Edit email template',
38
- })}, ${formatMessage({
39
- id: getTrad(template.display),
40
- defaultMessage: template.display,
41
- })}`}
42
- >
43
- <Crumb>
44
- {formatMessage({
45
- id: getTrad('PopUpForm.header.edit.email-templates'),
46
- defaultMessage: 'Edit email template',
47
- })}
48
- </Crumb>
49
- <Crumb isCurrent>
50
- {formatMessage({ id: getTrad(template.display), defaultMessage: template.display })}
51
- </Crumb>
52
- </Breadcrumbs>
53
- </ModalHeader>
54
- <Formik
55
- onSubmit={onSubmit}
56
- initialValues={template}
57
- validateOnChange={false}
58
- validationSchema={schema}
59
- enableReinitialize
60
- >
61
- {({ errors, values, handleChange, isSubmitting }) => {
62
- return (
63
- <Form>
64
- <ModalBody>
65
- <Grid gap={5}>
66
- <GridItem col={6} s={12}>
67
- <GenericInput
68
- intlLabel={{
69
- id: getTrad('PopUpForm.Email.options.from.name.label'),
70
- defaultMessage: 'Shipper name',
71
- }}
72
- name="options.from.name"
73
- onChange={handleChange}
74
- value={values.options.from.name}
75
- error={errors?.options?.from?.name}
76
- type="text"
77
- />
78
- </GridItem>
79
- <GridItem col={6} s={12}>
80
- <GenericInput
81
- intlLabel={{
82
- id: getTrad('PopUpForm.Email.options.from.email.label'),
83
- defaultMessage: 'Shipper email',
84
- }}
85
- name="options.from.email"
86
- onChange={handleChange}
87
- value={values.options.from.email}
88
- error={errors?.options?.from?.email}
89
- type="text"
90
- />
91
- </GridItem>
92
- <GridItem col={6} s={12}>
93
- <GenericInput
94
- intlLabel={{
95
- id: getTrad('PopUpForm.Email.options.response_email.label'),
96
- defaultMessage: 'Response email',
97
- }}
98
- name="options.response_email"
99
- onChange={handleChange}
100
- value={values.options.response_email}
101
- error={errors?.options?.response_email}
102
- type="text"
103
- />
104
- </GridItem>
105
- <GridItem col={6} s={12}>
106
- <GenericInput
107
- intlLabel={{
108
- id: getTrad('PopUpForm.Email.options.object.label'),
109
- defaultMessage: 'Subject',
110
- }}
111
- name="options.object"
112
- onChange={handleChange}
113
- value={values.options.object}
114
- error={errors?.options?.object}
115
- type="text"
116
- />
117
- </GridItem>
118
- <GridItem col={12} s={12}>
119
- <Textarea
120
- label={formatMessage({
121
- id: getTrad('PopUpForm.Email.options.message.label'),
122
- defaultMessage: 'Message',
123
- })}
124
- id="options.message"
125
- onChange={handleChange}
126
- value={values.options.message}
127
- error={
128
- errors?.options?.message &&
129
- formatMessage({
130
- id: errors.options.message,
131
- defaultMessage: errors.options.message,
132
- })
133
- }
134
- />
135
- </GridItem>
136
- </Grid>
137
- </ModalBody>
138
- <ModalFooter
139
- startActions={
140
- <Button onClick={onToggle} variant="tertiary">
141
- Cancel
142
- </Button>
143
- }
144
- endActions={
145
- <Button loading={isSubmitting} type="submit">
146
- Finish
147
- </Button>
148
- }
149
- />
150
- </Form>
151
- );
152
- }}
153
- </Formik>
154
- </ModalLayout>
155
- );
156
- };
157
-
158
- EmailForm.propTypes = {
159
- template: PropTypes.shape({
160
- display: PropTypes.string,
161
- icon: PropTypes.string,
162
- options: PropTypes.shape({
163
- from: PropTypes.shape({
164
- name: PropTypes.string,
165
- email: PropTypes.string,
166
- }),
167
- message: PropTypes.string,
168
- object: PropTypes.string,
169
- response_email: PropTypes.string,
170
- }),
171
- }).isRequired,
172
- onSubmit: PropTypes.func.isRequired,
173
- onToggle: PropTypes.func.isRequired,
174
- };
175
-
176
- export default EmailForm;
@@ -1,163 +0,0 @@
1
- import React, { useMemo, useRef, useState } from 'react';
2
-
3
- import { ContentLayout, HeaderLayout, Main, useNotifyAT } from '@strapi/design-system';
4
- import {
5
- CheckPagePermissions,
6
- LoadingIndicatorPage,
7
- SettingsPageTitle,
8
- useFocusWhenNavigate,
9
- useNotification,
10
- useOverlayBlocker,
11
- useRBAC,
12
- useTracking,
13
- } from '@strapi/helper-plugin';
14
- import { useIntl } from 'react-intl';
15
- import { useMutation, useQuery, useQueryClient } from 'react-query';
16
-
17
- import { PERMISSIONS } from '../../constants';
18
- import { getTrad } from '../../utils';
19
-
20
- import EmailForm from './components/EmailForm';
21
- import EmailTable from './components/EmailTable';
22
- import { fetchData, putEmailTemplate } from './utils/api';
23
-
24
- const ProtectedEmailTemplatesPage = () => (
25
- <CheckPagePermissions permissions={PERMISSIONS.readEmailTemplates}>
26
- <EmailTemplatesPage />
27
- </CheckPagePermissions>
28
- );
29
-
30
- const EmailTemplatesPage = () => {
31
- const { formatMessage } = useIntl();
32
- const { trackUsage } = useTracking();
33
- const { notifyStatus } = useNotifyAT();
34
- const toggleNotification = useNotification();
35
- const { lockApp, unlockApp } = useOverlayBlocker();
36
- const trackUsageRef = useRef(trackUsage);
37
- const queryClient = useQueryClient();
38
- useFocusWhenNavigate();
39
-
40
- const [isModalOpen, setIsModalOpen] = useState(false);
41
- const [templateToEdit, setTemplateToEdit] = useState(null);
42
-
43
- const updatePermissions = useMemo(() => {
44
- return { update: PERMISSIONS.updateEmailTemplates };
45
- }, []);
46
-
47
- const {
48
- isLoading: isLoadingForPermissions,
49
- allowedActions: { canUpdate },
50
- } = useRBAC(updatePermissions);
51
-
52
- const { status: isLoadingData, data } = useQuery('email-templates', () => fetchData(), {
53
- onSuccess() {
54
- notifyStatus(
55
- formatMessage({
56
- id: getTrad('Email.template.data.loaded'),
57
- defaultMessage: 'Email templates has been loaded',
58
- })
59
- );
60
- },
61
- onError() {
62
- toggleNotification({
63
- type: 'warning',
64
- message: { id: 'notification.error', defaultMessage: 'An error occured' },
65
- });
66
- },
67
- });
68
-
69
- const isLoading = isLoadingForPermissions || isLoadingData !== 'success';
70
-
71
- const handleToggle = () => {
72
- setIsModalOpen((prev) => !prev);
73
- };
74
-
75
- const handleEditClick = (template) => {
76
- setTemplateToEdit(template);
77
- handleToggle();
78
- };
79
-
80
- const submitMutation = useMutation((body) => putEmailTemplate({ 'email-templates': body }), {
81
- async onSuccess() {
82
- await queryClient.invalidateQueries('email-templates');
83
-
84
- toggleNotification({
85
- type: 'success',
86
- message: { id: 'notification.success.saved', defaultMessage: 'Saved' },
87
- });
88
-
89
- trackUsageRef.current('didEditEmailTemplates');
90
-
91
- unlockApp();
92
- handleToggle();
93
- },
94
- onError() {
95
- toggleNotification({
96
- type: 'warning',
97
- message: { id: 'notification.error', defaultMessage: 'An error occured' },
98
- });
99
- unlockApp();
100
- },
101
- refetchActive: true,
102
- });
103
- const { isLoading: isSubmittingForm } = submitMutation;
104
-
105
- const handleSubmit = (body) => {
106
- lockApp();
107
- trackUsageRef.current('willEditEmailTemplates');
108
-
109
- const editedTemplates = { ...data, [templateToEdit]: body };
110
- submitMutation.mutate(editedTemplates);
111
- };
112
-
113
- if (isLoading) {
114
- return (
115
- <Main aria-busy="true">
116
- <SettingsPageTitle
117
- name={formatMessage({
118
- id: getTrad('HeaderNav.link.emailTemplates'),
119
- defaultMessage: 'Email templates',
120
- })}
121
- />
122
- <HeaderLayout
123
- title={formatMessage({
124
- id: getTrad('HeaderNav.link.emailTemplates'),
125
- defaultMessage: 'Email templates',
126
- })}
127
- />
128
- <ContentLayout>
129
- <LoadingIndicatorPage />
130
- </ContentLayout>
131
- </Main>
132
- );
133
- }
134
-
135
- return (
136
- <Main aria-busy={isSubmittingForm}>
137
- <SettingsPageTitle
138
- name={formatMessage({
139
- id: getTrad('HeaderNav.link.emailTemplates'),
140
- defaultMessage: 'Email templates',
141
- })}
142
- />
143
- <HeaderLayout
144
- title={formatMessage({
145
- id: getTrad('HeaderNav.link.emailTemplates'),
146
- defaultMessage: 'Email templates',
147
- })}
148
- />
149
- <ContentLayout>
150
- <EmailTable onEditClick={handleEditClick} canUpdate={canUpdate} />
151
- {isModalOpen && (
152
- <EmailForm
153
- template={data[templateToEdit]}
154
- onToggle={handleToggle}
155
- onSubmit={handleSubmit}
156
- />
157
- )}
158
- </ContentLayout>
159
- </Main>
160
- );
161
- };
162
-
163
- export default ProtectedEmailTemplatesPage;
@@ -1,18 +0,0 @@
1
- import { getFetchClient } from '@strapi/helper-plugin';
2
-
3
- import { getRequestURL } from '../../../utils';
4
-
5
- const fetchData = async () => {
6
- const { get } = getFetchClient();
7
- const { data } = await get(getRequestURL('email-templates'));
8
-
9
- return data;
10
- };
11
-
12
- const putEmailTemplate = (body) => {
13
- const { put } = getFetchClient();
14
-
15
- return put(getRequestURL('email-templates'), body);
16
- };
17
-
18
- export { fetchData, putEmailTemplate };
@@ -1,275 +0,0 @@
1
- import React, { useMemo, useRef, useState } from 'react';
2
-
3
- import {
4
- ContentLayout,
5
- HeaderLayout,
6
- IconButton,
7
- Layout,
8
- Main,
9
- Table,
10
- Tbody,
11
- Td,
12
- Th,
13
- Thead,
14
- Tr,
15
- Typography,
16
- useNotifyAT,
17
- VisuallyHidden,
18
- } from '@strapi/design-system';
19
- import {
20
- CheckPagePermissions,
21
- LoadingIndicatorPage,
22
- onRowClick,
23
- SettingsPageTitle,
24
- stopPropagation,
25
- useFocusWhenNavigate,
26
- useNotification,
27
- useOverlayBlocker,
28
- useRBAC,
29
- useTracking,
30
- } from '@strapi/helper-plugin';
31
- import { Pencil } from '@strapi/icons';
32
- import has from 'lodash/has';
33
- import upperFirst from 'lodash/upperFirst';
34
- import { useIntl } from 'react-intl';
35
- import { useMutation, useQuery, useQueryClient } from 'react-query';
36
-
37
- import FormModal from '../../components/FormModal';
38
- import { PERMISSIONS } from '../../constants';
39
- import { getTrad } from '../../utils';
40
-
41
- import { fetchData, putProvider } from './utils/api';
42
- import createProvidersArray from './utils/createProvidersArray';
43
- import forms from './utils/forms';
44
-
45
- export const ProvidersPage = () => {
46
- const { formatMessage } = useIntl();
47
- useFocusWhenNavigate();
48
- const { notifyStatus } = useNotifyAT();
49
- const queryClient = useQueryClient();
50
- 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);
55
- const toggleNotification = useNotification();
56
- const { lockApp, unlockApp } = useOverlayBlocker();
57
-
58
- const updatePermissions = useMemo(() => {
59
- return { update: PERMISSIONS.updateProviders };
60
- }, []);
61
-
62
- const {
63
- isLoading: isLoadingForPermissions,
64
- allowedActions: { canUpdate },
65
- } = useRBAC(updatePermissions);
66
-
67
- const {
68
- isLoading: isLoadingForData,
69
- data: modifiedData,
70
- isFetching,
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
- });
82
-
83
- const isLoading = isLoadingForData || isFetching;
84
-
85
- const submitMutation = useMutation(putProvider, {
86
- async onSuccess() {
87
- await queryClient.invalidateQueries('get-providers');
88
- toggleNotification({
89
- type: 'info',
90
- message: { id: getTrad('notification.success.submit') },
91
- });
92
-
93
- trackUsageRef.current('didEditAuthenticationProvider');
94
- setIsSubmiting(false);
95
- handleToggleModal();
96
- unlockApp();
97
- },
98
- onError() {
99
- toggleNotification({
100
- type: 'warning',
101
- message: { id: 'notification.error' },
102
- });
103
- unlockApp();
104
- setIsSubmiting(false);
105
- },
106
- refetchActive: false,
107
- });
108
-
109
- const providers = useMemo(() => createProvidersArray(modifiedData), [modifiedData]);
110
-
111
- const rowCount = providers.length;
112
-
113
- const isProviderWithSubdomain = useMemo(() => {
114
- if (!providerToEditName) {
115
- return false;
116
- }
117
-
118
- const providerToEdit = providers.find((obj) => obj.name === providerToEditName);
119
-
120
- return has(providerToEdit, 'subdomain');
121
- }, [providers, providerToEditName]);
122
-
123
- const pageTitle = formatMessage({
124
- id: getTrad('HeaderNav.link.providers'),
125
- defaultMessage: 'Providers',
126
- });
127
-
128
- const layoutToRender = useMemo(() => {
129
- if (providerToEditName === 'email') {
130
- return forms.email;
131
- }
132
-
133
- if (isProviderWithSubdomain) {
134
- return forms.providersWithSubdomain;
135
- }
136
-
137
- return forms.providers;
138
- }, [providerToEditName, isProviderWithSubdomain]);
139
-
140
- const handleToggleModal = () => {
141
- setIsOpen((prev) => !prev);
142
- };
143
-
144
- const handleClickEdit = (provider) => {
145
- if (canUpdate) {
146
- setProviderToEditName(provider.name);
147
- handleToggleModal();
148
- }
149
- };
150
-
151
- const handleSubmit = async (values) => {
152
- setIsSubmiting(true);
153
-
154
- lockApp();
155
-
156
- trackUsageRef.current('willEditAuthenticationProvider');
157
-
158
- const body = { ...modifiedData, [providerToEditName]: values };
159
-
160
- submitMutation.mutate({ providers: body });
161
- };
162
-
163
- return (
164
- <Layout>
165
- <SettingsPageTitle name={pageTitle} />
166
- <Main>
167
- <HeaderLayout
168
- title={formatMessage({
169
- id: getTrad('HeaderNav.link.providers'),
170
- defaultMessage: 'Providers',
171
- })}
172
- />
173
- {isLoading || isLoadingForPermissions ? (
174
- <LoadingIndicatorPage />
175
- ) : (
176
- <ContentLayout>
177
- <Table colCount={3} rowCount={rowCount + 1}>
178
- <Thead>
179
- <Tr>
180
- <Th>
181
- <Typography variant="sigma" textColor="neutral600">
182
- {formatMessage({ id: 'global.name', defaultMessage: 'Name' })}
183
- </Typography>
184
- </Th>
185
- <Th>
186
- <Typography variant="sigma" textColor="neutral600">
187
- {formatMessage({ id: getTrad('Providers.status'), defaultMessage: 'Status' })}
188
- </Typography>
189
- </Th>
190
- <Th>
191
- <Typography variant="sigma">
192
- <VisuallyHidden>
193
- {formatMessage({
194
- id: 'global.settings',
195
- defaultMessage: 'Settings',
196
- })}
197
- </VisuallyHidden>
198
- </Typography>
199
- </Th>
200
- </Tr>
201
- </Thead>
202
- <Tbody>
203
- {providers.map((provider) => (
204
- <Tr
205
- key={provider.name}
206
- {...onRowClick({
207
- fn: () => handleClickEdit(provider),
208
- condition: canUpdate,
209
- })}
210
- >
211
- <Td width="45%">
212
- <Typography fontWeight="semiBold" textColor="neutral800">
213
- {provider.name}
214
- </Typography>
215
- </Td>
216
- <Td width="65%">
217
- <Typography
218
- textColor={provider.enabled ? 'success600' : 'danger600'}
219
- data-testid={`enable-${provider.name}`}
220
- >
221
- {provider.enabled
222
- ? formatMessage({
223
- id: 'global.enabled',
224
- defaultMessage: 'Enabled',
225
- })
226
- : formatMessage({
227
- id: 'global.disabled',
228
- defaultMessage: 'Disabled',
229
- })}
230
- </Typography>
231
- </Td>
232
- <Td {...stopPropagation}>
233
- {canUpdate && (
234
- <IconButton
235
- onClick={() => handleClickEdit(provider)}
236
- noBorder
237
- icon={<Pencil />}
238
- label="Edit"
239
- />
240
- )}
241
- </Td>
242
- </Tr>
243
- ))}
244
- </Tbody>
245
- </Table>
246
- </ContentLayout>
247
- )}
248
- </Main>
249
- <FormModal
250
- initialData={modifiedData[providerToEditName]}
251
- isOpen={isOpen}
252
- isSubmiting={isSubmiting}
253
- layout={layoutToRender}
254
- headerBreadcrumbs={[
255
- formatMessage({
256
- id: getTrad('PopUpForm.header.edit.providers'),
257
- defaultMessage: 'Edit Provider',
258
- }),
259
- upperFirst(providerToEditName),
260
- ]}
261
- onToggle={handleToggleModal}
262
- onSubmit={handleSubmit}
263
- providerToEditName={providerToEditName}
264
- />
265
- </Layout>
266
- );
267
- };
268
-
269
- const ProtectedProvidersPage = () => (
270
- <CheckPagePermissions permissions={PERMISSIONS.readProviders}>
271
- <ProvidersPage />
272
- </CheckPagePermissions>
273
- );
274
-
275
- export default ProtectedProvidersPage;
@@ -1,54 +0,0 @@
1
- import produce from 'immer';
2
- import set from 'lodash/set';
3
-
4
- const initialState = {
5
- formErrors: {},
6
- isLoading: true,
7
- initialData: {},
8
- modifiedData: {},
9
- };
10
-
11
- const reducer = (state, action) =>
12
- // eslint-disable-next-line consistent-return
13
- produce(state, (draftState) => {
14
- switch (action.type) {
15
- case 'GET_DATA': {
16
- draftState.isLoading = true;
17
- draftState.initialData = {};
18
- draftState.modifiedData = {};
19
-
20
- break;
21
- }
22
-
23
- case 'GET_DATA_SUCCEEDED': {
24
- draftState.isLoading = false;
25
- draftState.initialData = action.data;
26
- draftState.modifiedData = action.data;
27
-
28
- break;
29
- }
30
- case 'GET_DATA_ERROR': {
31
- draftState.isLoading = true;
32
- break;
33
- }
34
- case 'ON_CHANGE': {
35
- set(draftState, ['modifiedData', ...action.keys.split('.')], action.value);
36
- break;
37
- }
38
- case 'RESET_FORM': {
39
- draftState.modifiedData = state.initialData;
40
- draftState.formErrors = {};
41
- break;
42
- }
43
- case 'SET_ERRORS': {
44
- draftState.formErrors = action.errors;
45
- break;
46
- }
47
- default: {
48
- return draftState;
49
- }
50
- }
51
- });
52
-
53
- export default reducer;
54
- export { initialState };