@strapi/plugin-users-permissions 0.0.0-next.fb3a0b82484ce466b1efb1b28f16fc8ef73aba4a → 0.0.0-next.fc1775f7731f8999840e56e298a216b9a6c5c4ad

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 (198) 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 +16 -43
  15. package/admin/src/pages/AdvancedSettings/index.jsx +214 -0
  16. package/admin/src/pages/AdvancedSettings/utils/layout.js +20 -35
  17. package/admin/src/pages/AdvancedSettings/utils/schema.js +5 -2
  18. package/admin/src/pages/EmailTemplates/components/EmailForm.jsx +156 -0
  19. package/admin/src/pages/EmailTemplates/components/{EmailTable.js → EmailTable.jsx} +20 -17
  20. package/admin/src/pages/EmailTemplates/{index.js → index.jsx} +36 -62
  21. package/admin/src/pages/EmailTemplates/utils/schema.js +18 -6
  22. package/admin/src/pages/Providers/{index.js → index.jsx} +98 -113
  23. package/admin/src/pages/Providers/utils/forms.js +23 -11
  24. package/admin/src/pages/Roles/constants.js +3 -3
  25. package/admin/src/pages/Roles/hooks/usePlugins.js +4 -4
  26. package/admin/src/pages/Roles/index.jsx +24 -0
  27. package/admin/src/pages/Roles/pages/{CreatePage.js → CreatePage.jsx} +53 -58
  28. package/admin/src/pages/Roles/pages/{EditPage.js → EditPage.jsx} +63 -68
  29. package/admin/src/pages/Roles/pages/ListPage/components/{TableBody.js → TableBody.jsx} +27 -31
  30. package/admin/src/pages/Roles/pages/ListPage/{index.js → index.jsx} +79 -55
  31. package/admin/src/translations/en.json +1 -1
  32. package/admin/src/utils/prefixPluginTranslations.js +13 -0
  33. package/dist/_chunks/ar-BguGUqwK.js +44 -0
  34. package/dist/_chunks/ar-BguGUqwK.js.map +1 -0
  35. package/dist/_chunks/ar-CK8BRRXB.mjs +44 -0
  36. package/dist/_chunks/ar-CK8BRRXB.mjs.map +1 -0
  37. package/dist/_chunks/cs-BVigMk0l.mjs +50 -0
  38. package/dist/_chunks/cs-BVigMk0l.mjs.map +1 -0
  39. package/dist/_chunks/cs-BW8-K_GY.js +50 -0
  40. package/dist/_chunks/cs-BW8-K_GY.js.map +1 -0
  41. package/dist/_chunks/de-BKUdRFI4.mjs +62 -0
  42. package/dist/_chunks/de-BKUdRFI4.mjs.map +1 -0
  43. package/dist/_chunks/de-owXpVluI.js +62 -0
  44. package/dist/_chunks/de-owXpVluI.js.map +1 -0
  45. package/dist/_chunks/dk-BQiTK50l.mjs +86 -0
  46. package/dist/_chunks/dk-BQiTK50l.mjs.map +1 -0
  47. package/dist/_chunks/dk-LXAnbuBk.js +86 -0
  48. package/dist/_chunks/dk-LXAnbuBk.js.map +1 -0
  49. package/dist/_chunks/en-DOHtPf-2.mjs +86 -0
  50. package/dist/_chunks/en-DOHtPf-2.mjs.map +1 -0
  51. package/dist/_chunks/en-MHo5mcsU.js +86 -0
  52. package/dist/_chunks/en-MHo5mcsU.js.map +1 -0
  53. package/dist/_chunks/es-BwLCLXAQ.js +86 -0
  54. package/dist/_chunks/es-BwLCLXAQ.js.map +1 -0
  55. package/dist/_chunks/es-DNgOVMjD.mjs +86 -0
  56. package/dist/_chunks/es-DNgOVMjD.mjs.map +1 -0
  57. package/dist/_chunks/fr-DkgRugiU.mjs +50 -0
  58. package/dist/_chunks/fr-DkgRugiU.mjs.map +1 -0
  59. package/dist/_chunks/fr-DkhpSjjm.js +50 -0
  60. package/dist/_chunks/fr-DkhpSjjm.js.map +1 -0
  61. package/dist/_chunks/id-BTemOeTZ.js +62 -0
  62. package/dist/_chunks/id-BTemOeTZ.js.map +1 -0
  63. package/dist/_chunks/id-BdEsvnaF.mjs +62 -0
  64. package/dist/_chunks/id-BdEsvnaF.mjs.map +1 -0
  65. package/dist/_chunks/index-6IfauKkm.js +365 -0
  66. package/dist/_chunks/index-6IfauKkm.js.map +1 -0
  67. package/dist/_chunks/index-BH2Kbto3.mjs +344 -0
  68. package/dist/_chunks/index-BH2Kbto3.mjs.map +1 -0
  69. package/dist/_chunks/index-BPLSKK9l.mjs +1142 -0
  70. package/dist/_chunks/index-BPLSKK9l.mjs.map +1 -0
  71. package/dist/_chunks/index-BteVBZ5H.js +252 -0
  72. package/dist/_chunks/index-BteVBZ5H.js.map +1 -0
  73. package/dist/_chunks/index-CItjLvCp.mjs +617 -0
  74. package/dist/_chunks/index-CItjLvCp.mjs.map +1 -0
  75. package/dist/_chunks/index-CU5dmnhc.js +280 -0
  76. package/dist/_chunks/index-CU5dmnhc.js.map +1 -0
  77. package/dist/_chunks/index-D4QvcqXm-BWNRataA.mjs +11090 -0
  78. package/dist/_chunks/index-D4QvcqXm-BWNRataA.mjs.map +1 -0
  79. package/dist/_chunks/index-D4QvcqXm-HpyyuCo7.js +11113 -0
  80. package/dist/_chunks/index-D4QvcqXm-HpyyuCo7.js.map +1 -0
  81. package/dist/_chunks/index-DDd0fVR6.js +1171 -0
  82. package/dist/_chunks/index-DDd0fVR6.js.map +1 -0
  83. package/dist/_chunks/index-DMkiPQOl.mjs +262 -0
  84. package/dist/_chunks/index-DMkiPQOl.mjs.map +1 -0
  85. package/dist/_chunks/index-DZnDAnLg.mjs +253 -0
  86. package/dist/_chunks/index-DZnDAnLg.mjs.map +1 -0
  87. package/dist/_chunks/index-Dd0JjBda.js +639 -0
  88. package/dist/_chunks/index-Dd0JjBda.js.map +1 -0
  89. package/dist/_chunks/it-B-rv0E24.mjs +62 -0
  90. package/dist/_chunks/it-B-rv0E24.mjs.map +1 -0
  91. package/dist/_chunks/it-D1rH6V6_.js +62 -0
  92. package/dist/_chunks/it-D1rH6V6_.js.map +1 -0
  93. package/dist/_chunks/ja-C8K-VBPD.mjs +48 -0
  94. package/dist/_chunks/ja-C8K-VBPD.mjs.map +1 -0
  95. package/dist/_chunks/ja-DqShgTMf.js +48 -0
  96. package/dist/_chunks/ja-DqShgTMf.js.map +1 -0
  97. package/dist/_chunks/ko-B9DGEPWH.js +86 -0
  98. package/dist/_chunks/ko-B9DGEPWH.js.map +1 -0
  99. package/dist/_chunks/ko-Busb0wIY.mjs +86 -0
  100. package/dist/_chunks/ko-Busb0wIY.mjs.map +1 -0
  101. package/dist/_chunks/ms-ByvsQjRt.mjs +49 -0
  102. package/dist/_chunks/ms-ByvsQjRt.mjs.map +1 -0
  103. package/dist/_chunks/ms-CPBU3LWf.js +49 -0
  104. package/dist/_chunks/ms-CPBU3LWf.js.map +1 -0
  105. package/dist/_chunks/nl-5qO8Rpcy.mjs +48 -0
  106. package/dist/_chunks/nl-5qO8Rpcy.mjs.map +1 -0
  107. package/dist/_chunks/nl-CwNB6YoO.js +48 -0
  108. package/dist/_chunks/nl-CwNB6YoO.js.map +1 -0
  109. package/dist/_chunks/pl-BdIzifBE.mjs +86 -0
  110. package/dist/_chunks/pl-BdIzifBE.mjs.map +1 -0
  111. package/dist/_chunks/pl-Do9UD69f.js +86 -0
  112. package/dist/_chunks/pl-Do9UD69f.js.map +1 -0
  113. package/dist/_chunks/pt-BIO24ioG.mjs +48 -0
  114. package/dist/_chunks/pt-BIO24ioG.mjs.map +1 -0
  115. package/dist/_chunks/pt-BR-D7dZhxuP.js +44 -0
  116. package/dist/_chunks/pt-BR-D7dZhxuP.js.map +1 -0
  117. package/dist/_chunks/pt-BR-f0p23AQZ.mjs +44 -0
  118. package/dist/_chunks/pt-BR-f0p23AQZ.mjs.map +1 -0
  119. package/dist/_chunks/pt-fdvyOnUp.js +48 -0
  120. package/dist/_chunks/pt-fdvyOnUp.js.map +1 -0
  121. package/dist/_chunks/ru-C94rjPGA.js +86 -0
  122. package/dist/_chunks/ru-C94rjPGA.js.map +1 -0
  123. package/dist/_chunks/ru-VWy-IB7K.mjs +86 -0
  124. package/dist/_chunks/ru-VWy-IB7K.mjs.map +1 -0
  125. package/dist/_chunks/sk-BABEhykl.js +50 -0
  126. package/dist/_chunks/sk-BABEhykl.js.map +1 -0
  127. package/dist/_chunks/sk-B_LIcepm.mjs +50 -0
  128. package/dist/_chunks/sk-B_LIcepm.mjs.map +1 -0
  129. package/dist/_chunks/sv-ABLKOokl.mjs +86 -0
  130. package/dist/_chunks/sv-ABLKOokl.mjs.map +1 -0
  131. package/dist/_chunks/sv-Be43LhA9.js +86 -0
  132. package/dist/_chunks/sv-Be43LhA9.js.map +1 -0
  133. package/dist/_chunks/th-DKyP7ueR.mjs +60 -0
  134. package/dist/_chunks/th-DKyP7ueR.mjs.map +1 -0
  135. package/dist/_chunks/th-DgVhVLhL.js +60 -0
  136. package/dist/_chunks/th-DgVhVLhL.js.map +1 -0
  137. package/dist/_chunks/tr-B_idhkEs.js +85 -0
  138. package/dist/_chunks/tr-B_idhkEs.js.map +1 -0
  139. package/dist/_chunks/tr-qa1Q5UjC.mjs +85 -0
  140. package/dist/_chunks/tr-qa1Q5UjC.mjs.map +1 -0
  141. package/dist/_chunks/uk-BmRqbeQc.mjs +49 -0
  142. package/dist/_chunks/uk-BmRqbeQc.mjs.map +1 -0
  143. package/dist/_chunks/uk-LHOivnhP.js +49 -0
  144. package/dist/_chunks/uk-LHOivnhP.js.map +1 -0
  145. package/dist/_chunks/vi-CdVRdKDw.js +50 -0
  146. package/dist/_chunks/vi-CdVRdKDw.js.map +1 -0
  147. package/dist/_chunks/vi-HW-EdMea.mjs +50 -0
  148. package/dist/_chunks/vi-HW-EdMea.mjs.map +1 -0
  149. package/dist/_chunks/zh-5hKkVPA4.mjs +86 -0
  150. package/dist/_chunks/zh-5hKkVPA4.mjs.map +1 -0
  151. package/dist/_chunks/zh-Cuq8gMnF.js +86 -0
  152. package/dist/_chunks/zh-Cuq8gMnF.js.map +1 -0
  153. package/dist/_chunks/zh-Hans-BHilK-yc.mjs +86 -0
  154. package/dist/_chunks/zh-Hans-BHilK-yc.mjs.map +1 -0
  155. package/dist/_chunks/zh-Hans-GQDMKtY4.js +86 -0
  156. package/dist/_chunks/zh-Hans-GQDMKtY4.js.map +1 -0
  157. package/dist/admin/index.js +4 -0
  158. package/dist/admin/index.js.map +1 -0
  159. package/dist/admin/index.mjs +5 -0
  160. package/dist/admin/index.mjs.map +1 -0
  161. package/package.json +45 -27
  162. package/packup.config.ts +22 -0
  163. package/server/bootstrap/index.js +18 -51
  164. package/server/bootstrap/users-permissions-actions.js +6 -0
  165. package/server/config.js +29 -0
  166. package/server/content-types/user/index.js +0 -1
  167. package/server/controllers/auth.js +62 -63
  168. package/server/controllers/content-manager-user.js +28 -30
  169. package/server/controllers/role.js +17 -4
  170. package/server/controllers/user.js +8 -9
  171. package/server/controllers/validation/auth.js +81 -25
  172. package/server/graphql/types/index.js +1 -0
  173. package/server/graphql/types/me.js +1 -0
  174. package/server/graphql/types/user-input.js +20 -0
  175. package/server/middlewares/rateLimit.js +1 -1
  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 -55
  190. package/admin/src/pages/AdvancedSettings/index.js +0 -259
  191. package/admin/src/pages/EmailTemplates/components/EmailForm.js +0 -176
  192. package/admin/src/pages/Roles/index.js +0 -33
  193. package/admin/src/pages/Roles/pages/ListPage/utils/api.js +0 -30
  194. package/server/bootstrap/grant-config.js +0 -131
  195. package/strapi-admin.js +0 -3
  196. package/strapi-server.js +0 -3
  197. /package/admin/src/components/Permissions/PermissionRow/{index.js → index.jsx} +0 -0
  198. /package/admin/src/contexts/UsersPermissionsContext/{index.js → index.jsx} +0 -0
@@ -0,0 +1,214 @@
1
+ import React from 'react';
2
+
3
+ import { Box, Button, Flex, Grid, Typography, useNotifyAT } from '@strapi/design-system';
4
+ import { Check } from '@strapi/icons';
5
+ import {
6
+ useAPIErrorHandler,
7
+ Page,
8
+ Form,
9
+ InputRenderer,
10
+ useNotification,
11
+ useFetchClient,
12
+ useRBAC,
13
+ Layouts,
14
+ } from '@strapi/strapi/admin';
15
+ import { useIntl } from 'react-intl';
16
+ import { useMutation, useQuery, useQueryClient } from 'react-query';
17
+
18
+ import { PERMISSIONS } from '../../constants';
19
+ import { getTrad } from '../../utils';
20
+
21
+ import layout from './utils/layout';
22
+ import schema from './utils/schema';
23
+
24
+ const ProtectedAdvancedSettingsPage = () => (
25
+ <Page.Protect permissions={PERMISSIONS.readAdvancedSettings}>
26
+ <AdvancedSettingsPage />
27
+ </Page.Protect>
28
+ );
29
+
30
+ const AdvancedSettingsPage = () => {
31
+ const { formatMessage } = useIntl();
32
+ const { toggleNotification } = useNotification();
33
+ const { notifyStatus } = useNotifyAT();
34
+ const queryClient = useQueryClient();
35
+ const { get, put } = useFetchClient();
36
+ const { formatAPIError } = useAPIErrorHandler();
37
+
38
+ const {
39
+ isLoading: isLoadingForPermissions,
40
+ allowedActions: { canUpdate },
41
+ } = useRBAC({ update: PERMISSIONS.updateAdvancedSettings });
42
+
43
+ const { isLoading: isLoadingData, data } = useQuery(
44
+ ['users-permissions', 'advanced'],
45
+ async () => {
46
+ const { data } = await get('/users-permissions/advanced');
47
+
48
+ return data;
49
+ },
50
+ {
51
+ onSuccess() {
52
+ notifyStatus(
53
+ formatMessage({
54
+ id: getTrad('Form.advancedSettings.data.loaded'),
55
+ defaultMessage: 'Advanced settings data has been loaded',
56
+ })
57
+ );
58
+ },
59
+ onError() {
60
+ toggleNotification({
61
+ type: 'danger',
62
+ message: formatMessage({
63
+ id: getTrad('notification.error'),
64
+ defaultMessage: 'An error occured',
65
+ }),
66
+ });
67
+ },
68
+ }
69
+ );
70
+
71
+ const isLoading = isLoadingForPermissions || isLoadingData;
72
+
73
+ const submitMutation = useMutation((body) => put('/users-permissions/advanced', body), {
74
+ async onSuccess() {
75
+ await queryClient.invalidateQueries(['users-permissions', 'advanced']);
76
+
77
+ toggleNotification({
78
+ type: 'success',
79
+ message: formatMessage({
80
+ id: getTrad('notification.success.saved'),
81
+ defaultMessage: 'Saved',
82
+ }),
83
+ });
84
+ },
85
+ onError(error) {
86
+ toggleNotification({
87
+ type: 'danger',
88
+ message: formatAPIError(error),
89
+ });
90
+ },
91
+ refetchActive: true,
92
+ });
93
+
94
+ const { isLoading: isSubmittingForm } = submitMutation;
95
+
96
+ const handleSubmit = async (body) => {
97
+ submitMutation.mutate({
98
+ ...body,
99
+ email_confirmation_redirection: body.email_confirmation
100
+ ? body.email_confirmation_redirection
101
+ : '',
102
+ });
103
+ };
104
+
105
+ if (isLoading) {
106
+ return <Page.Loading />;
107
+ }
108
+
109
+ return (
110
+ <Page.Main aria-busy={isSubmittingForm}>
111
+ <Page.Title>
112
+ {formatMessage(
113
+ { id: 'Settings.PageTitle', defaultMessage: 'Settings - {name}' },
114
+ {
115
+ name: formatMessage({
116
+ id: getTrad('HeaderNav.link.advancedSettings'),
117
+ defaultMessage: 'Advanced Settings',
118
+ }),
119
+ }
120
+ )}
121
+ </Page.Title>
122
+ <Form onSubmit={handleSubmit} initialValues={data.settings} validationSchema={schema}>
123
+ {({ values, isSubmitting, modified }) => {
124
+ return (
125
+ <>
126
+ <Layouts.Header
127
+ title={formatMessage({
128
+ id: getTrad('HeaderNav.link.advancedSettings'),
129
+ defaultMessage: 'Advanced Settings',
130
+ })}
131
+ primaryAction={
132
+ <Button
133
+ loading={isSubmitting}
134
+ type="submit"
135
+ disabled={!modified || !canUpdate}
136
+ startIcon={<Check />}
137
+ size="S"
138
+ >
139
+ {formatMessage({ id: 'global.save', defaultMessage: 'Save' })}
140
+ </Button>
141
+ }
142
+ />
143
+ <Layouts.Content>
144
+ <Box
145
+ background="neutral0"
146
+ hasRadius
147
+ shadow="filterShadow"
148
+ paddingTop={6}
149
+ paddingBottom={6}
150
+ paddingLeft={7}
151
+ paddingRight={7}
152
+ >
153
+ <Flex direction="column" alignItems="stretch" gap={4}>
154
+ <Typography variant="delta" tag="h2">
155
+ {formatMessage({
156
+ id: 'global.settings',
157
+ defaultMessage: 'Settings',
158
+ })}
159
+ </Typography>
160
+ <Grid.Root gap={6}>
161
+ {[
162
+ {
163
+ label: {
164
+ id: getTrad('EditForm.inputSelect.label.role'),
165
+ defaultMessage: 'Default role for authenticated users',
166
+ },
167
+ hint: {
168
+ id: getTrad('EditForm.inputSelect.description.role'),
169
+ defaultMessage:
170
+ 'It will attach the new authenticated user to the selected role.',
171
+ },
172
+ options: data.roles.map((role) => ({
173
+ label: role.name,
174
+ value: role.type,
175
+ })),
176
+ name: 'default_role',
177
+ size: 6,
178
+ type: 'enumeration',
179
+ },
180
+ ...layout,
181
+ ].map(({ size, ...field }) => (
182
+ <Grid.Item
183
+ key={field.name}
184
+ col={size}
185
+ direction="column"
186
+ alignItems="stretch"
187
+ >
188
+ <InputRenderer
189
+ {...field}
190
+ disabled={
191
+ field.name === 'email_confirmation_redirection' &&
192
+ values.email_confirmation === false
193
+ }
194
+ label={formatMessage(field.label)}
195
+ hint={field.hint ? formatMessage(field.hint) : undefined}
196
+ placeholder={
197
+ field.placeholder ? formatMessage(field.placeholder) : undefined
198
+ }
199
+ />
200
+ </Grid.Item>
201
+ ))}
202
+ </Grid.Root>
203
+ </Flex>
204
+ </Box>
205
+ </Layouts.Content>
206
+ </>
207
+ );
208
+ }}
209
+ </Form>
210
+ </Page.Main>
211
+ );
212
+ };
213
+
214
+ export { ProtectedAdvancedSettingsPage, AdvancedSettingsPage };
@@ -2,45 +2,39 @@ import { getTrad } from '../../../utils';
2
2
 
3
3
  const layout = [
4
4
  {
5
- intlLabel: {
5
+ label: {
6
6
  id: getTrad('EditForm.inputToggle.label.email'),
7
7
  defaultMessage: 'One account per email address',
8
8
  },
9
- description: {
9
+ hint: {
10
10
  id: getTrad('EditForm.inputToggle.description.email'),
11
11
  defaultMessage:
12
12
  'Disallow the user to create multiple accounts using the same email address with different authentication providers.',
13
13
  },
14
14
  name: 'unique_email',
15
- type: 'bool',
16
- size: {
17
- col: 12,
18
- xs: 12,
19
- },
15
+ type: 'boolean',
16
+ size: 12,
20
17
  },
21
18
  {
22
- intlLabel: {
19
+ label: {
23
20
  id: getTrad('EditForm.inputToggle.label.sign-up'),
24
21
  defaultMessage: 'Enable sign-ups',
25
22
  },
26
- description: {
23
+ hint: {
27
24
  id: getTrad('EditForm.inputToggle.description.sign-up'),
28
25
  defaultMessage:
29
26
  'When disabled (OFF), the registration process is forbidden. No one can subscribe anymore no matter the used provider.',
30
27
  },
31
28
  name: 'allow_register',
32
- type: 'bool',
33
- size: {
34
- col: 12,
35
- xs: 12,
36
- },
29
+ type: 'boolean',
30
+ size: 12,
37
31
  },
38
32
  {
39
- intlLabel: {
33
+ label: {
40
34
  id: getTrad('EditForm.inputToggle.label.email-reset-password'),
41
35
  defaultMessage: 'Reset password page',
42
36
  },
43
- description: {
37
+ hint: {
44
38
  id: getTrad('EditForm.inputToggle.description.email-reset-password'),
45
39
  defaultMessage: "URL of your application's reset password page.",
46
40
  },
@@ -49,34 +43,28 @@ const layout = [
49
43
  defaultMessage: 'ex: https://youtfrontend.com/reset-password',
50
44
  },
51
45
  name: 'email_reset_password',
52
- type: 'text',
53
- size: {
54
- col: 6,
55
- xs: 12,
56
- },
46
+ type: 'string',
47
+ size: 12,
57
48
  },
58
49
  {
59
- intlLabel: {
50
+ label: {
60
51
  id: getTrad('EditForm.inputToggle.label.email-confirmation'),
61
52
  defaultMessage: 'Enable email confirmation',
62
53
  },
63
- description: {
54
+ hint: {
64
55
  id: getTrad('EditForm.inputToggle.description.email-confirmation'),
65
56
  defaultMessage: 'When enabled (ON), new registered users receive a confirmation email.',
66
57
  },
67
58
  name: 'email_confirmation',
68
- type: 'bool',
69
- size: {
70
- col: 12,
71
- xs: 12,
72
- },
59
+ type: 'boolean',
60
+ size: 12,
73
61
  },
74
62
  {
75
- intlLabel: {
63
+ label: {
76
64
  id: getTrad('EditForm.inputToggle.label.email-confirmation-redirection'),
77
65
  defaultMessage: 'Redirection url',
78
66
  },
79
- description: {
67
+ hint: {
80
68
  id: getTrad('EditForm.inputToggle.description.email-confirmation-redirection'),
81
69
  defaultMessage: 'After you confirmed your email, choose where you will be redirected.',
82
70
  },
@@ -85,11 +73,8 @@ const layout = [
85
73
  defaultMessage: 'ex: https://youtfrontend.com/email-confirmation',
86
74
  },
87
75
  name: 'email_confirmation_redirection',
88
- type: 'text',
89
- size: {
90
- col: 6,
91
- xs: 12,
92
- },
76
+ type: 'string',
77
+ size: 12,
93
78
  },
94
79
  ];
95
80
 
@@ -1,4 +1,4 @@
1
- import { translatedErrors } from '@strapi/helper-plugin';
1
+ import { translatedErrors } from '@strapi/strapi/admin';
2
2
  import * as yup from 'yup';
3
3
 
4
4
  // eslint-disable-next-line prefer-regex-literals
@@ -12,7 +12,10 @@ const schema = yup.object().shape({
12
12
  }),
13
13
  email_reset_password: yup
14
14
  .string(translatedErrors.string)
15
- .matches(URL_REGEX, translatedErrors.regex)
15
+ .matches(URL_REGEX, {
16
+ id: translatedErrors.regex.id,
17
+ defaultMessage: 'This is not a valid URL',
18
+ })
16
19
  .nullable(),
17
20
  });
18
21
 
@@ -0,0 +1,156 @@
1
+ import React from 'react';
2
+
3
+ import { Button, Grid, Modal, Breadcrumbs, Crumb, VisuallyHidden } from '@strapi/design-system';
4
+ import { Form, InputRenderer } from '@strapi/strapi/admin';
5
+ import PropTypes from 'prop-types';
6
+ import { useIntl } from 'react-intl';
7
+
8
+ import { getTrad } from '../../../utils';
9
+ import schema from '../utils/schema';
10
+
11
+ const EmailForm = ({ template = {}, onToggle, open, onSubmit }) => {
12
+ const { formatMessage } = useIntl();
13
+
14
+ return (
15
+ <Modal.Root open={open} onOpenChange={onToggle}>
16
+ <Modal.Content>
17
+ <Modal.Header>
18
+ <Breadcrumbs
19
+ label={`${formatMessage({
20
+ id: getTrad('PopUpForm.header.edit.email-templates'),
21
+ defaultMessage: 'Edit email template',
22
+ })}, ${
23
+ template.display
24
+ ? formatMessage({
25
+ id: getTrad(template.display),
26
+ defaultMessage: template.display,
27
+ })
28
+ : ''
29
+ }`}
30
+ >
31
+ <Crumb>
32
+ {formatMessage({
33
+ id: getTrad('PopUpForm.header.edit.email-templates'),
34
+ defaultMessage: 'Edit email template',
35
+ })}
36
+ </Crumb>
37
+ <Crumb isCurrent>
38
+ {template.display
39
+ ? formatMessage({ id: getTrad(template.display), defaultMessage: template.display })
40
+ : ''}
41
+ </Crumb>
42
+ </Breadcrumbs>
43
+ <VisuallyHidden>
44
+ <Modal.Title>
45
+ {`${formatMessage({
46
+ id: getTrad('PopUpForm.header.edit.email-templates'),
47
+ defaultMessage: 'Edit email template',
48
+ })}, ${template.display ? formatMessage({ id: getTrad(template.display), defaultMessage: template.display }) : ''}`}
49
+ </Modal.Title>
50
+ </VisuallyHidden>
51
+ </Modal.Header>
52
+ <Form onSubmit={onSubmit} initialValues={template} validationSchema={schema}>
53
+ {({ isSubmitting }) => {
54
+ return (
55
+ <>
56
+ <Modal.Body>
57
+ <Grid.Root gap={5}>
58
+ {[
59
+ {
60
+ label: formatMessage({
61
+ id: getTrad('PopUpForm.Email.options.from.name.label'),
62
+ defaultMessage: 'Shipper name',
63
+ }),
64
+ name: 'options.from.name',
65
+ size: 6,
66
+ type: 'string',
67
+ },
68
+ {
69
+ label: formatMessage({
70
+ id: getTrad('PopUpForm.Email.options.from.email.label'),
71
+ defaultMessage: 'Shipper email',
72
+ }),
73
+ name: 'options.from.email',
74
+ size: 6,
75
+ type: 'string',
76
+ },
77
+ {
78
+ label: formatMessage({
79
+ id: getTrad('PopUpForm.Email.options.response_email.label'),
80
+ defaultMessage: 'Response email',
81
+ }),
82
+ name: 'options.response_email',
83
+ size: 6,
84
+ type: 'string',
85
+ },
86
+ {
87
+ label: formatMessage({
88
+ id: getTrad('PopUpForm.Email.options.object.label'),
89
+ defaultMessage: 'Subject',
90
+ }),
91
+ name: 'options.object',
92
+ size: 6,
93
+ type: 'string',
94
+ },
95
+ {
96
+ label: formatMessage({
97
+ id: getTrad('PopUpForm.Email.options.message.label'),
98
+ defaultMessage: 'Message',
99
+ }),
100
+ name: 'options.message',
101
+ size: 12,
102
+ type: 'text',
103
+ },
104
+ ].map(({ size, ...field }) => (
105
+ <Grid.Item
106
+ key={field.name}
107
+ col={size}
108
+ direction="column"
109
+ alignItems="stretch"
110
+ >
111
+ <InputRenderer {...field} />
112
+ </Grid.Item>
113
+ ))}
114
+ </Grid.Root>
115
+ </Modal.Body>
116
+ <Modal.Footer>
117
+ <Modal.Close>
118
+ <Button variant="tertiary">Cancel</Button>
119
+ </Modal.Close>
120
+ <Button loading={isSubmitting} type="submit">
121
+ Finish
122
+ </Button>
123
+ </Modal.Footer>
124
+ </>
125
+ );
126
+ }}
127
+ </Form>
128
+ </Modal.Content>
129
+ </Modal.Root>
130
+ );
131
+ };
132
+
133
+ EmailForm.defaultProps = {
134
+ template: {},
135
+ };
136
+
137
+ EmailForm.propTypes = {
138
+ template: PropTypes.shape({
139
+ display: PropTypes.string,
140
+ icon: PropTypes.string,
141
+ options: PropTypes.shape({
142
+ from: PropTypes.shape({
143
+ name: PropTypes.string,
144
+ email: PropTypes.string,
145
+ }),
146
+ message: PropTypes.string,
147
+ object: PropTypes.string,
148
+ response_email: PropTypes.string,
149
+ }),
150
+ }),
151
+ open: PropTypes.bool.isRequired,
152
+ onSubmit: PropTypes.func.isRequired,
153
+ onToggle: PropTypes.func.isRequired,
154
+ };
155
+
156
+ export default EmailForm;
@@ -1,7 +1,6 @@
1
1
  import React from 'react';
2
2
 
3
3
  import {
4
- Icon,
5
4
  IconButton,
6
5
  Table,
7
6
  Tbody,
@@ -11,9 +10,9 @@ import {
11
10
  Tr,
12
11
  Typography,
13
12
  VisuallyHidden,
13
+ Box,
14
14
  } from '@strapi/design-system';
15
- import { onRowClick, stopPropagation } from '@strapi/helper-plugin';
16
- import { Check, Pencil, Refresh } from '@strapi/icons';
15
+ import { Check, Pencil, ArrowClockwise as Refresh } from '@strapi/icons';
17
16
  import PropTypes from 'prop-types';
18
17
  import { useIntl } from 'react-intl';
19
18
 
@@ -53,16 +52,16 @@ const EmailTable = ({ canUpdate, onEditClick }) => {
53
52
  </Tr>
54
53
  </Thead>
55
54
  <Tbody>
56
- <Tr {...onRowClick({ fn: () => onEditClick('reset_password') })}>
55
+ <Tr cursor="pointer" onClick={() => onEditClick('reset_password')}>
57
56
  <Td>
58
- <Icon>
57
+ <Box width="3.2rem" height="3.2rem" padding="0.8rem">
59
58
  <Refresh
60
59
  aria-label={formatMessage({
61
60
  id: 'global.reset-password',
62
61
  defaultMessage: 'Reset password',
63
62
  })}
64
63
  />
65
- </Icon>
64
+ </Box>
66
65
  </Td>
67
66
  <Td>
68
67
  <Typography>
@@ -72,28 +71,30 @@ const EmailTable = ({ canUpdate, onEditClick }) => {
72
71
  })}
73
72
  </Typography>
74
73
  </Td>
75
- <Td {...stopPropagation}>
74
+ <Td onClick={(e) => e.stopPropagation()}>
76
75
  <IconButton
77
76
  onClick={() => onEditClick('reset_password')}
78
77
  label={formatMessage({
79
78
  id: getTrad('Email.template.form.edit.label'),
80
79
  defaultMessage: 'Edit a template',
81
80
  })}
82
- noBorder
83
- icon={canUpdate && <Pencil />}
84
- />
81
+ variant="ghost"
82
+ disabled={!canUpdate}
83
+ >
84
+ <Pencil />
85
+ </IconButton>
85
86
  </Td>
86
87
  </Tr>
87
- <Tr {...onRowClick({ fn: () => onEditClick('email_confirmation') })}>
88
+ <Tr cursor="pointer" onClick={() => onEditClick('email_confirmation')}>
88
89
  <Td>
89
- <Icon>
90
+ <Box width="3.2rem" height="3.2rem" padding="0.8rem">
90
91
  <Check
91
92
  aria-label={formatMessage({
92
93
  id: getTrad('Email.template.email_confirmation'),
93
94
  defaultMessage: 'Email address confirmation',
94
95
  })}
95
96
  />
96
- </Icon>
97
+ </Box>
97
98
  </Td>
98
99
  <Td>
99
100
  <Typography>
@@ -103,16 +104,18 @@ const EmailTable = ({ canUpdate, onEditClick }) => {
103
104
  })}
104
105
  </Typography>
105
106
  </Td>
106
- <Td {...stopPropagation}>
107
+ <Td onClick={(e) => e.stopPropagation()}>
107
108
  <IconButton
108
109
  onClick={() => onEditClick('email_confirmation')}
109
110
  label={formatMessage({
110
111
  id: getTrad('Email.template.form.edit.label'),
111
112
  defaultMessage: 'Edit a template',
112
113
  })}
113
- noBorder
114
- icon={canUpdate && <Pencil />}
115
- />
114
+ variant="ghost"
115
+ disabled={!canUpdate}
116
+ >
117
+ <Pencil />
118
+ </IconButton>
116
119
  </Td>
117
120
  </Tr>
118
121
  </Tbody>