@strapi/admin 4.6.1 → 4.7.0-beta.0

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 (93) hide show
  1. package/admin/src/assets/images/onboarding-preview.png +0 -0
  2. package/admin/src/content-manager/components/CollectionTypeFormWrapper/index.js +0 -2
  3. package/admin/src/hooks/useRegenerate/index.js +2 -2
  4. package/admin/src/hooks/useSettingsMenu/utils/defaultGlobalLinks.js +7 -0
  5. package/admin/src/pages/Admin/Onboarding/constants.js +46 -0
  6. package/admin/src/pages/Admin/Onboarding/index.js +161 -89
  7. package/admin/src/pages/Admin/index.js +5 -2
  8. package/admin/src/pages/SettingsPage/{pages/ApiTokens/EditView/components → components/Tokens}/FormHead/index.js +36 -19
  9. package/admin/src/pages/SettingsPage/components/Tokens/FormiTokenContainer/LifeSpanInput.js +96 -0
  10. package/admin/src/pages/SettingsPage/components/Tokens/LifeSpanInput/index.js +98 -0
  11. package/admin/src/pages/SettingsPage/components/Tokens/Regenerate/index.js +73 -0
  12. package/admin/src/pages/SettingsPage/{pages/ApiTokens/ListView/DynamicTable → components/Tokens/Table}/DefaultButton/index.js +1 -1
  13. package/admin/src/pages/SettingsPage/{pages/ApiTokens/ListView/DynamicTable → components/Tokens/Table}/DeleteButton/index.js +1 -1
  14. package/admin/src/pages/SettingsPage/{pages/ApiTokens/ListView/DynamicTable → components/Tokens/Table}/ReadButton/index.js +0 -0
  15. package/admin/src/pages/SettingsPage/{pages/ApiTokens/ListView/DynamicTable → components/Tokens/Table}/UpdateButton/index.js +0 -0
  16. package/admin/src/pages/SettingsPage/components/Tokens/Table/index.js +135 -0
  17. package/admin/src/pages/SettingsPage/{pages/ApiTokens/EditView/components/ContentBox → components/Tokens/TokenBox}/index.js +17 -17
  18. package/admin/src/pages/SettingsPage/components/Tokens/TokenDescription/index.js +51 -0
  19. package/admin/src/pages/SettingsPage/components/Tokens/TokenName/index.js +46 -0
  20. package/admin/src/pages/SettingsPage/components/Tokens/TokenTypeSelect/index.js +69 -0
  21. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/CollapsableContentType/index.js +5 -3
  22. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/FormApiTokenContainer/index.js +52 -142
  23. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/Regenerate/index.js +5 -1
  24. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/index.js +37 -14
  25. package/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/index.js +5 -13
  26. package/admin/src/pages/SettingsPage/pages/TransferTokens/EditView/components/FormTransferTokenContainer/index.js +105 -0
  27. package/admin/src/pages/SettingsPage/pages/TransferTokens/EditView/components/LoadingView/index.js +50 -0
  28. package/admin/src/pages/SettingsPage/pages/TransferTokens/EditView/index.js +201 -0
  29. package/admin/src/pages/SettingsPage/pages/TransferTokens/EditView/utils/getDateOfExpiration.js +16 -0
  30. package/admin/src/pages/SettingsPage/pages/TransferTokens/EditView/utils/index.js +4 -0
  31. package/admin/src/pages/SettingsPage/pages/TransferTokens/EditView/utils/schema.js +10 -0
  32. package/admin/src/pages/SettingsPage/pages/TransferTokens/ListView/index.js +182 -0
  33. package/admin/src/pages/SettingsPage/pages/TransferTokens/ListView/utils/tableHeaders.js +48 -0
  34. package/admin/src/pages/SettingsPage/pages/TransferTokens/ProtectedCreateView/index.js +14 -0
  35. package/admin/src/pages/SettingsPage/pages/TransferTokens/ProtectedEditView/index.js +14 -0
  36. package/admin/src/pages/SettingsPage/pages/TransferTokens/ProtectedListView/index.js +12 -0
  37. package/admin/src/pages/SettingsPage/utils/defaultRoutes.js +33 -0
  38. package/admin/src/permissions/defaultPermissions.js +8 -0
  39. package/admin/src/translations/en.json +18 -1
  40. package/build/19eb2dfcf2603eb55733.png +0 -0
  41. package/build/4649.15cc0afe.chunk.js +30 -0
  42. package/build/7259.aa68d808.chunk.js +1 -0
  43. package/build/7407.883fb1f5.chunk.js +1 -0
  44. package/build/Admin-authenticatedApp.f29f6021.chunk.js +79 -0
  45. package/build/{Admin_settingsPage.d1493824.chunk.js → Admin_settingsPage.178dc6e3.chunk.js} +25 -25
  46. package/build/{admin-app.25934eaa.chunk.js → admin-app.77a50e1f.chunk.js} +19 -19
  47. package/build/{api-tokens-create-page.d248362d.chunk.js → api-tokens-create-page.0db3aec1.chunk.js} +1 -1
  48. package/build/{api-tokens-edit-page.8516fa20.chunk.js → api-tokens-edit-page.671e0e26.chunk.js} +1 -1
  49. package/build/api-tokens-list-page.7387102c.chunk.js +16 -0
  50. package/build/{content-manager.35ff9726.chunk.js → content-manager.42b24d46.chunk.js} +77 -77
  51. package/build/en-json.b0748970.chunk.js +1 -0
  52. package/build/index.html +1 -1
  53. package/build/main.1022ed01.js +4393 -0
  54. package/build/runtime~main.84941a97.js +2 -0
  55. package/build/transfer-tokens-create-page.16e23791.chunk.js +1 -0
  56. package/build/transfer-tokens-edit-page.3886c973.chunk.js +1 -0
  57. package/build/transfer-tokens-list-page.e8010a89.chunk.js +16 -0
  58. package/package.json +12 -12
  59. package/server/bootstrap.js +2 -0
  60. package/server/config/admin-actions.js +48 -0
  61. package/server/content-types/index.js +2 -0
  62. package/server/content-types/transfer-token-permission.js +36 -0
  63. package/server/content-types/transfer-token.js +66 -0
  64. package/server/controllers/api-token.js +4 -5
  65. package/server/controllers/index.js +1 -0
  66. package/server/controllers/transfer/index.js +13 -0
  67. package/server/controllers/transfer/runner.js +24 -0
  68. package/server/controllers/transfer/token.js +131 -0
  69. package/server/register.js +2 -9
  70. package/server/routes/index.js +2 -0
  71. package/server/routes/transfer.js +95 -0
  72. package/server/services/api-token.js +2 -3
  73. package/server/services/constants.js +6 -0
  74. package/server/services/index.js +1 -0
  75. package/server/services/transfer/index.js +6 -0
  76. package/server/services/transfer/permission.js +22 -0
  77. package/server/services/transfer/token.js +409 -0
  78. package/server/strategies/api-token.js +4 -2
  79. package/server/strategies/data-transfer.js +107 -0
  80. package/server/strategies/index.js +1 -0
  81. package/server/utils/index.d.ts +2 -0
  82. package/server/validation/api-tokens.js +1 -6
  83. package/server/validation/transfer/index.js +5 -0
  84. package/server/validation/transfer/token.js +34 -0
  85. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/FormBody/index.js +0 -78
  86. package/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/DynamicTable/index.js +0 -112
  87. package/build/4318.f96a9d4d.chunk.js +0 -30
  88. package/build/8633.00ccd382.chunk.js +0 -1
  89. package/build/Admin-authenticatedApp.ce646f66.chunk.js +0 -75
  90. package/build/api-tokens-list-page.44a79fda.chunk.js +0 -16
  91. package/build/en-json.1f137a90.chunk.js +0 -1
  92. package/build/main.7b151630.js +0 -4377
  93. package/build/runtime~main.a20d633b.js +0 -2
@@ -1,15 +1,14 @@
1
1
  import React from 'react';
2
2
  import { useIntl } from 'react-intl';
3
- import { usePersistentState } from '@strapi/helper-plugin';
4
3
  import PropTypes from 'prop-types';
5
4
  import { Box } from '@strapi/design-system/Box';
6
5
  import { Grid, GridItem } from '@strapi/design-system/Grid';
7
- import { Select, Option } from '@strapi/design-system/Select';
8
6
  import { Stack } from '@strapi/design-system/Stack';
9
- import { Textarea } from '@strapi/design-system/Textarea';
10
- import { TextInput } from '@strapi/design-system/TextInput';
11
7
  import { Typography } from '@strapi/design-system/Typography';
12
- import { getDateOfExpiration } from '../../utils';
8
+ import LifeSpanInput from '../../../../../components/Tokens/LifeSpanInput';
9
+ import TokenName from '../../../../../components/Tokens/TokenName';
10
+ import TokenDescription from '../../../../../components/Tokens/TokenDescription';
11
+ import TokenTypeSelect from '../../../../../components/Tokens/TokenTypeSelect';
13
12
 
14
13
  const FormApiTokenContainer = ({
15
14
  errors,
@@ -22,7 +21,6 @@ const FormApiTokenContainer = ({
22
21
  setHasChangedPermissions,
23
22
  }) => {
24
23
  const { formatMessage } = useIntl();
25
- const [lang] = usePersistentState('strapi-admin-language', 'en');
26
24
 
27
25
  const handleChangeSelectApiTokenType = ({ target: { value } }) => {
28
26
  setHasChangedPermissions(false);
@@ -39,6 +37,30 @@ const FormApiTokenContainer = ({
39
37
  }
40
38
  };
41
39
 
40
+ const typeOptions = [
41
+ {
42
+ value: 'read-only',
43
+ label: {
44
+ id: 'Settings.apiTokens.types.read-only',
45
+ defaultMessage: 'Read-only',
46
+ },
47
+ },
48
+ {
49
+ value: 'full-access',
50
+ label: {
51
+ id: 'Settings.apiTokens.types.full-access',
52
+ defaultMessage: 'Full access',
53
+ },
54
+ },
55
+ {
56
+ value: 'custom',
57
+ label: {
58
+ id: 'Settings.apiTokens.types.custom',
59
+ defaultMessage: 'Custom',
60
+ },
61
+ },
62
+ ];
63
+
42
64
  return (
43
65
  <Box
44
66
  background="neutral0"
@@ -58,158 +80,46 @@ const FormApiTokenContainer = ({
58
80
  </Typography>
59
81
  <Grid gap={5}>
60
82
  <GridItem key="name" col={6} xs={12}>
61
- <TextInput
62
- name="name"
63
- error={
64
- errors.name
65
- ? formatMessage(
66
- errors.name?.id
67
- ? errors.name
68
- : { id: errors.name, defaultMessage: errors.name }
69
- )
70
- : null
71
- }
72
- label={formatMessage({
73
- id: 'Settings.apiTokens.form.name',
74
- defaultMessage: 'Name',
75
- })}
83
+ <TokenName
84
+ errors={errors}
85
+ values={values}
86
+ canEditInputs={canEditInputs}
76
87
  onChange={onChange}
77
- value={values.name}
78
- disabled={!canEditInputs}
79
- required
80
88
  />
81
89
  </GridItem>
82
90
  <GridItem key="description" col={6} xs={12}>
83
- <Textarea
84
- label={formatMessage({
85
- id: 'Settings.apiTokens.form.description',
86
- defaultMessage: 'Description',
87
- })}
88
- name="description"
89
- error={
90
- errors.description
91
- ? formatMessage(
92
- errors.description?.id
93
- ? errors.description
94
- : {
95
- id: errors.description,
96
- defaultMessage: errors.description,
97
- }
98
- )
99
- : null
100
- }
91
+ <TokenDescription
92
+ errors={errors}
93
+ values={values}
94
+ canEditInputs={canEditInputs}
101
95
  onChange={onChange}
102
- disabled={!canEditInputs}
103
- >
104
- {values.description}
105
- </Textarea>
96
+ />
106
97
  </GridItem>
107
98
  <GridItem key="lifespan" col={6} xs={12}>
108
- <Select
109
- name="lifespan"
110
- label={formatMessage({
111
- id: 'Settings.apiTokens.form.duration',
112
- defaultMessage: 'Token duration',
113
- })}
114
- value={values.lifespan !== null ? values.lifespan : '0'}
115
- error={
116
- errors.lifespan
117
- ? formatMessage(
118
- errors.lifespan?.id
119
- ? errors.lifespan
120
- : { id: errors.lifespan, defaultMessage: errors.lifespan }
121
- )
122
- : null
123
- }
124
- onChange={(value) => {
125
- onChange({ target: { name: 'lifespan', value } });
126
- }}
127
- required
128
- disabled={!isCreating}
129
- placeholder="Select"
130
- >
131
- <Option value="604800000">
132
- {formatMessage({
133
- id: 'Settings.apiTokens.duration.7-days',
134
- defaultMessage: '7 days',
135
- })}
136
- </Option>
137
- <Option value="2592000000">
138
- {formatMessage({
139
- id: 'Settings.apiTokens.duration.30-days',
140
- defaultMessage: '30 days',
141
- })}
142
- </Option>
143
- <Option value="7776000000">
144
- {formatMessage({
145
- id: 'Settings.apiTokens.duration.90-days',
146
- defaultMessage: '90 days',
147
- })}
148
- </Option>
149
- <Option value="0">
150
- {formatMessage({
151
- id: 'Settings.apiTokens.duration.unlimited',
152
- defaultMessage: 'Unlimited',
153
- })}
154
- </Option>
155
- </Select>
156
- <Typography variant="pi" textColor="neutral600">
157
- {!isCreating &&
158
- `${formatMessage({
159
- id: 'Settings.apiTokens.duration.expiration-date',
160
- defaultMessage: 'Expiration date',
161
- })}: ${getDateOfExpiration(
162
- apiToken?.createdAt,
163
- parseInt(values.lifespan, 10),
164
- lang
165
- )}`}
166
- </Typography>
99
+ <LifeSpanInput
100
+ isCreating={isCreating}
101
+ errors={errors}
102
+ values={values}
103
+ onChange={onChange}
104
+ token={apiToken}
105
+ />
167
106
  </GridItem>
168
107
 
169
108
  <GridItem key="type" col={6} xs={12}>
170
- <Select
171
- name="type"
172
- label={formatMessage({
109
+ <TokenTypeSelect
110
+ values={values}
111
+ errors={errors}
112
+ label={{
173
113
  id: 'Settings.apiTokens.form.type',
174
114
  defaultMessage: 'Token type',
175
- })}
176
- value={values?.type}
177
- error={
178
- errors.type
179
- ? formatMessage(
180
- errors.type?.id
181
- ? errors.type
182
- : { id: errors.type, defaultMessage: errors.type }
183
- )
184
- : null
185
- }
115
+ }}
186
116
  onChange={(value) => {
187
117
  handleChangeSelectApiTokenType({ target: { value } });
188
118
  onChange({ target: { name: 'type', value } });
189
119
  }}
190
- placeholder="Select"
191
- required
192
- disabled={!canEditInputs}
193
- >
194
- <Option value="read-only">
195
- {formatMessage({
196
- id: 'Settings.apiTokens.types.read-only',
197
- defaultMessage: 'Read-only',
198
- })}
199
- </Option>
200
- <Option value="full-access">
201
- {formatMessage({
202
- id: 'Settings.apiTokens.types.full-access',
203
- defaultMessage: 'Full access',
204
- })}
205
- </Option>
206
- <Option value="custom">
207
- {formatMessage({
208
- id: 'Settings.apiTokens.types.custom',
209
- defaultMessage: 'Custom',
210
- })}
211
- </Option>
212
- </Select>
120
+ options={typeOptions}
121
+ canEditInputs={canEditInputs}
122
+ />
213
123
  </GridItem>
214
124
  </Grid>
215
125
  </Stack>
@@ -9,7 +9,11 @@ import { useRegenerate } from '../../../../../../../hooks';
9
9
  export const Regenerate = ({ onRegenerate, idToRegenerate }) => {
10
10
  const { formatMessage } = useIntl();
11
11
  const [showConfirmDialog, setShowConfirmDialog] = useState(false);
12
- const { regenerateData, isLoadingConfirmation } = useRegenerate(idToRegenerate, onRegenerate);
12
+ const { regenerateData, isLoadingConfirmation } = useRegenerate(
13
+ '/admin/api-tokens/',
14
+ idToRegenerate,
15
+ onRegenerate
16
+ );
13
17
  const handleConfirmRegeneration = async () => {
14
18
  regenerateData();
15
19
  setShowConfirmDialog(false);
@@ -15,15 +15,19 @@ import { Main } from '@strapi/design-system/Main';
15
15
  import { Formik } from 'formik';
16
16
  import { useRouteMatch, useHistory } from 'react-router-dom';
17
17
  import { useQuery } from 'react-query';
18
+ import { ContentLayout } from '@strapi/design-system/Layout';
19
+ import { Stack } from '@strapi/design-system/Stack';
18
20
  import { formatAPIErrors } from '../../../../../utils';
19
21
  import { schema } from './utils';
20
22
  import LoadingView from './components/LoadingView';
21
- import FormHead from './components/FormHead';
22
- import FormBody from './components/FormBody';
23
23
  import adminPermissions from '../../../../../permissions';
24
24
  import { ApiTokenPermissionsContextProvider } from '../../../../../contexts/ApiTokenPermissions';
25
25
  import init from './init';
26
26
  import reducer, { initialState } from './reducer';
27
+ import Permissions from './components/Permissions';
28
+ import FormApiTokenContainer from './components/FormApiTokenContainer';
29
+ import TokenBox from '../../../components/Tokens/TokenBox';
30
+ import FormHead from '../../../components/Tokens/FormHead';
27
31
 
28
32
  const MSG_ERROR_NAME_TAKEN = 'Name already taken';
29
33
 
@@ -280,22 +284,41 @@ const ApiTokenCreateView = () => {
280
284
  return (
281
285
  <Form>
282
286
  <FormHead
283
- apiToken={apiToken}
284
- setApiToken={setApiToken}
287
+ backUrl="/settings/api-tokens"
288
+ title={{
289
+ id: 'Settings.apiTokens.createPage.title',
290
+ defaultMessage: 'Create API Token',
291
+ }}
292
+ token={apiToken}
293
+ setToken={setApiToken}
285
294
  canEditInputs={canEditInputs}
286
295
  canRegenerate={canRegenerate}
287
296
  isSubmitting={isSubmitting}
297
+ regenerateUrl="/admin/api-tokens/"
288
298
  />
289
- <FormBody
290
- apiToken={apiToken}
291
- errors={errors}
292
- onChange={handleChange}
293
- canEditInputs={canEditInputs}
294
- isCreating={isCreating}
295
- values={values}
296
- onDispatch={dispatch}
297
- setHasChangedPermissions={setHasChangedPermissions}
298
- />
299
+
300
+ <ContentLayout>
301
+ <Stack spacing={6}>
302
+ {Boolean(apiToken?.name) && <TokenBox token={apiToken?.accessKey} />}
303
+ <FormApiTokenContainer
304
+ errors={errors}
305
+ onChange={handleChange}
306
+ canEditInputs={canEditInputs}
307
+ isCreating={isCreating}
308
+ values={values}
309
+ apiToken={apiToken}
310
+ onDispatch={dispatch}
311
+ setHasChangedPermissions={setHasChangedPermissions}
312
+ />
313
+ <Permissions
314
+ disabled={
315
+ !canEditInputs ||
316
+ values?.type === 'read-only' ||
317
+ values?.type === 'full-access'
318
+ }
319
+ />
320
+ </Stack>
321
+ </ContentLayout>
299
322
  </Form>
300
323
  );
301
324
  }}
@@ -11,7 +11,6 @@ import {
11
11
  NoPermissions,
12
12
  useRBAC,
13
13
  NoContent,
14
- DynamicTable,
15
14
  useTracking,
16
15
  useGuidedTour,
17
16
  useFetchClient,
@@ -24,7 +23,7 @@ import Plus from '@strapi/icons/Plus';
24
23
 
25
24
  import adminPermissions from '../../../../../permissions';
26
25
  import tableHeaders from './utils/tableHeaders';
27
- import TableRows from './DynamicTable';
26
+ import Table from '../../../components/Tokens/Table';
28
27
 
29
28
  const ApiTokenListView = () => {
30
29
  useFocusWhenNavigate();
@@ -144,22 +143,15 @@ const ApiTokenListView = () => {
144
143
  <ContentLayout>
145
144
  {!canRead && <NoPermissions />}
146
145
  {shouldDisplayDynamicTable && (
147
- <DynamicTable
146
+ <Table
147
+ permissions={{ canRead, canDelete, canUpdate }}
148
148
  headers={headers}
149
149
  contentType="api-tokens"
150
150
  rows={apiTokens}
151
- withBulkActions={canDelete || canUpdate || canRead}
152
151
  isLoading={isLoading}
153
152
  onConfirmDelete={(id) => deleteMutation.mutateAsync(id)}
154
- >
155
- <TableRows
156
- canRead={canRead}
157
- canDelete={canDelete}
158
- canUpdate={canUpdate}
159
- rows={apiTokens}
160
- withBulkActions={canDelete || canUpdate || canRead}
161
- />
162
- </DynamicTable>
153
+ tokens={apiTokens}
154
+ />
163
155
  )}
164
156
  {shouldDisplayNoContentWithCreationButton && (
165
157
  <NoContent
@@ -0,0 +1,105 @@
1
+ import React from 'react';
2
+ import { useIntl } from 'react-intl';
3
+ import PropTypes from 'prop-types';
4
+ import { Box } from '@strapi/design-system/Box';
5
+ import { Grid, GridItem } from '@strapi/design-system/Grid';
6
+ import { Stack } from '@strapi/design-system/Stack';
7
+
8
+ import { Typography } from '@strapi/design-system/Typography';
9
+ import LifeSpanInput from '../../../../../components/Tokens/LifeSpanInput';
10
+ import TokenName from '../../../../../components/Tokens/TokenName';
11
+ import TokenDescription from '../../../../../components/Tokens/TokenDescription';
12
+
13
+ const FormTransferTokenContainer = ({
14
+ errors,
15
+ onChange,
16
+ canEditInputs,
17
+ isCreating,
18
+ values,
19
+ transferToken,
20
+ }) => {
21
+ const { formatMessage } = useIntl();
22
+
23
+ return (
24
+ <Box
25
+ background="neutral0"
26
+ hasRadius
27
+ shadow="filterShadow"
28
+ paddingTop={6}
29
+ paddingBottom={6}
30
+ paddingLeft={7}
31
+ paddingRight={7}
32
+ >
33
+ <Stack spacing={4}>
34
+ <Typography variant="delta" as="h2">
35
+ {formatMessage({
36
+ id: 'global.details',
37
+ defaultMessage: 'Details',
38
+ })}
39
+ </Typography>
40
+ <Grid gap={5}>
41
+ <GridItem key="name" col={6} xs={12}>
42
+ <TokenName
43
+ errors={errors}
44
+ values={values}
45
+ canEditInputs={canEditInputs}
46
+ onChange={onChange}
47
+ />
48
+ </GridItem>
49
+ <GridItem key="description" col={6} xs={12}>
50
+ <TokenDescription
51
+ errors={errors}
52
+ values={values}
53
+ canEditInputs={canEditInputs}
54
+ onChange={onChange}
55
+ />
56
+ </GridItem>
57
+ <GridItem key="lifespan" col={6} xs={12}>
58
+ <LifeSpanInput
59
+ isCreating={isCreating}
60
+ errors={errors}
61
+ values={values}
62
+ onChange={onChange}
63
+ token={transferToken}
64
+ />
65
+ </GridItem>
66
+ </Grid>
67
+ </Stack>
68
+ </Box>
69
+ );
70
+ };
71
+
72
+ FormTransferTokenContainer.propTypes = {
73
+ errors: PropTypes.shape({
74
+ name: PropTypes.string,
75
+ description: PropTypes.string,
76
+ lifespan: PropTypes.string,
77
+ type: PropTypes.string,
78
+ }),
79
+ onChange: PropTypes.func.isRequired,
80
+ canEditInputs: PropTypes.bool.isRequired,
81
+ values: PropTypes.shape({
82
+ name: PropTypes.string,
83
+ description: PropTypes.string,
84
+ lifespan: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
85
+ type: PropTypes.string,
86
+ }).isRequired,
87
+ isCreating: PropTypes.bool.isRequired,
88
+ transferToken: PropTypes.shape({
89
+ id: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
90
+ type: PropTypes.string,
91
+ lifespan: PropTypes.string,
92
+ name: PropTypes.string,
93
+ accessKey: PropTypes.string,
94
+ permissions: PropTypes.array,
95
+ description: PropTypes.string,
96
+ createdAt: PropTypes.string,
97
+ }),
98
+ };
99
+
100
+ FormTransferTokenContainer.defaultProps = {
101
+ errors: {},
102
+ transferToken: {},
103
+ };
104
+
105
+ export default FormTransferTokenContainer;
@@ -0,0 +1,50 @@
1
+ import React from 'react';
2
+ import {
3
+ SettingsPageTitle,
4
+ LoadingIndicatorPage,
5
+ useFocusWhenNavigate,
6
+ } from '@strapi/helper-plugin';
7
+ import { HeaderLayout, ContentLayout } from '@strapi/design-system/Layout';
8
+ import { Main } from '@strapi/design-system/Main';
9
+ import { Button } from '@strapi/design-system/Button';
10
+ import Check from '@strapi/icons/Check';
11
+ import { useIntl } from 'react-intl';
12
+ import PropTypes from 'prop-types';
13
+
14
+ const LoadingView = ({ transferTokenName }) => {
15
+ const { formatMessage } = useIntl();
16
+ useFocusWhenNavigate();
17
+
18
+ return (
19
+ <Main aria-busy="true">
20
+ <SettingsPageTitle name="Transfer Tokens" />
21
+ <HeaderLayout
22
+ primaryAction={
23
+ <Button disabled startIcon={<Check />} type="button" size="L">
24
+ {formatMessage({ id: 'global.save', defaultMessage: 'Save' })}
25
+ </Button>
26
+ }
27
+ title={
28
+ transferTokenName ||
29
+ formatMessage({
30
+ id: 'Settings.transferTokens.createPage.title',
31
+ defaultMessage: 'Create Transfer Token',
32
+ })
33
+ }
34
+ />
35
+ <ContentLayout>
36
+ <LoadingIndicatorPage />
37
+ </ContentLayout>
38
+ </Main>
39
+ );
40
+ };
41
+
42
+ LoadingView.defaultProps = {
43
+ transferTokenName: null,
44
+ };
45
+
46
+ LoadingView.propTypes = {
47
+ transferTokenName: PropTypes.string,
48
+ };
49
+
50
+ export default LoadingView;