@strapi/admin 4.4.0-beta.1 → 4.4.0-beta.3

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 (97) hide show
  1. package/admin/src/StrapiApp.js +4 -12
  2. package/admin/src/components/Providers/index.js +14 -10
  3. package/admin/src/content-manager/components/FieldTypeIcon/index.js +31 -1
  4. package/admin/src/content-manager/components/Inputs/index.js +30 -10
  5. package/admin/src/content-manager/pages/EditSettingsView/components/FormModal.js +7 -2
  6. package/admin/src/content-manager/pages/EditSettingsView/index.js +2 -1
  7. package/admin/src/content-manager/pages/EditView/index.js +91 -84
  8. package/admin/src/core/apis/CustomFields.js +80 -0
  9. package/admin/src/core/apis/index.js +1 -0
  10. package/admin/src/hooks/index.js +0 -1
  11. package/admin/src/pages/AuthPage/utils/forms.js +2 -2
  12. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/index.js +180 -452
  13. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/utils/schema.js +1 -2
  14. package/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/DynamicTable/DeleteButton/index.js +0 -1
  15. package/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/DynamicTable/UpdateButton/index.js +36 -3
  16. package/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/DynamicTable/index.js +11 -13
  17. package/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/index.js +2 -3
  18. package/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/utils/tableHeaders.js +8 -8
  19. package/admin/src/pages/SettingsPage/pages/ApiTokens/ProtectedEditView/index.js +1 -1
  20. package/admin/src/pages/SettingsPage/pages/Users/ListPage/ModalForm/utils/schema.js +1 -1
  21. package/admin/src/pages/SettingsPage/pages/Users/utils/validations/users/profile.js +2 -2
  22. package/admin/src/permissions/defaultPermissions.js +6 -2
  23. package/admin/src/translations/en.json +0 -17
  24. package/build/524.40377968.chunk.js +644 -0
  25. package/build/{Admin-authenticatedApp.3a31a087.chunk.js → Admin-authenticatedApp.50e41ff2.chunk.js} +1 -1
  26. package/build/{Admin_homePage.6d5e3236.chunk.js → Admin_homePage.118926e0.chunk.js} +1 -1
  27. package/build/{Admin_profilePage.83991a6c.chunk.js → Admin_profilePage.9d50ac44.chunk.js} +4 -4
  28. package/build/{Admin_settingsPage.fc9c607a.chunk.js → Admin_settingsPage.98a711e5.chunk.js} +16 -16
  29. package/build/admin-app.8bc3e80f.chunk.js +112 -0
  30. package/build/admin-edit-roles-page.554ba3fa.chunk.js +1 -0
  31. package/build/{admin-edit-users.5bebf473.chunk.js → admin-edit-users.c585212f.chunk.js} +2 -2
  32. package/build/{admin-users.dccd5f4c.chunk.js → admin-users.97a08630.chunk.js} +1 -1
  33. package/build/api-tokens-create-page.4c262d6e.chunk.js +1 -0
  34. package/build/api-tokens-edit-page.10a9d368.chunk.js +1 -0
  35. package/build/api-tokens-list-page.442c9f3c.chunk.js +15 -0
  36. package/build/content-manager.2a6f876d.chunk.js +1178 -0
  37. package/build/content-type-builder-list-view.5b3cd768.chunk.js +194 -0
  38. package/build/content-type-builder-translation-en-json.f985c9c4.chunk.js +1 -0
  39. package/build/content-type-builder.d4610e20.chunk.js +145 -0
  40. package/build/en-json.12bc5a14.chunk.js +1 -0
  41. package/build/index.html +1 -1
  42. package/build/{main.cdfda31e.js → main.fdc482f3.js} +1151 -1151
  43. package/build/{runtime~main.fa8f8898.js → runtime~main.29105d25.js} +2 -2
  44. package/build/sso-settings-page.445184e0.chunk.js +1 -0
  45. package/build/{webhook-edit-page.9e46fc3f.chunk.js → webhook-edit-page.d2ea3351.chunk.js} +1 -1
  46. package/package.json +7 -8
  47. package/server/bootstrap.js +1 -19
  48. package/server/config/admin-actions.js +0 -20
  49. package/server/content-types/api-token.js +1 -25
  50. package/server/content-types/index.js +0 -1
  51. package/server/controllers/api-token.js +1 -24
  52. package/server/controllers/index.js +0 -1
  53. package/server/routes/api-tokens.js +0 -11
  54. package/server/routes/index.js +0 -2
  55. package/server/services/api-token.js +29 -310
  56. package/server/services/constants.js +0 -10
  57. package/server/services/permission/engine-hooks.js +82 -0
  58. package/server/services/permission/engine.js +226 -36
  59. package/server/services/permission.js +1 -4
  60. package/server/strategies/admin.js +1 -7
  61. package/server/strategies/api-token.js +11 -71
  62. package/server/validation/api-tokens.js +2 -12
  63. package/server/validation/common-validators.js +1 -1
  64. package/admin/src/contexts/ApiTokenPermissions/index.js +0 -24
  65. package/admin/src/hooks/useRegenerate/index.js +0 -34
  66. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/ActionBoundRoutes/index.js +0 -56
  67. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/BoundRoute/getMethodColor.js +0 -41
  68. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/BoundRoute/index.js +0 -72
  69. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/CollapsableContentType/CheckBoxWrapper.js +0 -30
  70. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/CollapsableContentType/index.js +0 -150
  71. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/ContenTypesSection/index.js +0 -37
  72. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/Permissions/index.js +0 -40
  73. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/Regenerate/index.js +0 -68
  74. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/init.js +0 -13
  75. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/reducer.js +0 -55
  76. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/utils/getDateOfExpiration.js +0 -16
  77. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/utils/index.js +0 -5
  78. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/utils/transformPermissionsData.js +0 -36
  79. package/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/DynamicTable/DefaultButton/index.js +0 -63
  80. package/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/DynamicTable/ReadButton/index.js +0 -19
  81. package/build/4235.982b5799.chunk.js +0 -30
  82. package/build/611.a91aff91.chunk.js +0 -158
  83. package/build/7379.d246dd38.chunk.js +0 -1
  84. package/build/admin-app.41b6472c.chunk.js +0 -112
  85. package/build/admin-edit-roles-page.4dd6bcb9.chunk.js +0 -1
  86. package/build/api-tokens-create-page.29cc87b6.chunk.js +0 -1
  87. package/build/api-tokens-edit-page.c294a88f.chunk.js +0 -1
  88. package/build/api-tokens-list-page.bb36535f.chunk.js +0 -16
  89. package/build/content-manager.fb5ee865.chunk.js +0 -1178
  90. package/build/content-type-builder-list-view.8cc534e0.chunk.js +0 -194
  91. package/build/content-type-builder-translation-en-json.201bfb78.chunk.js +0 -1
  92. package/build/content-type-builder.42cecba9.chunk.js +0 -142
  93. package/build/en-json.a9918c93.chunk.js +0 -1
  94. package/build/sso-settings-page.9ceb0140.chunk.js +0 -1
  95. package/server/content-types/api-token-permission.js +0 -36
  96. package/server/controllers/content-api.js +0 -15
  97. package/server/routes/content-api.js +0 -20
@@ -1,4 +1,4 @@
1
- import React, { useEffect, useState, useRef, useReducer } from 'react';
1
+ import React, { useEffect, useRef } from 'react';
2
2
  import { useIntl } from 'react-intl';
3
3
  import {
4
4
  SettingsPageTitle,
@@ -9,8 +9,6 @@ import {
9
9
  useTracking,
10
10
  useGuidedTour,
11
11
  Link,
12
- usePersistentState,
13
- useRBAC,
14
12
  } from '@strapi/helper-plugin';
15
13
  import { HeaderLayout, ContentLayout } from '@strapi/design-system/Layout';
16
14
  import { Main } from '@strapi/design-system/Main';
@@ -25,132 +23,47 @@ import { Grid, GridItem } from '@strapi/design-system/Grid';
25
23
  import { TextInput } from '@strapi/design-system/TextInput';
26
24
  import { Textarea } from '@strapi/design-system/Textarea';
27
25
  import { Select, Option } from '@strapi/design-system/Select';
28
- import { get } from 'lodash';
26
+ import get from 'lodash/get';
29
27
  import { useRouteMatch, useHistory } from 'react-router-dom';
30
28
  import { useQuery } from 'react-query';
31
29
  import { formatAPIErrors } from '../../../../../utils';
32
30
  import { axiosInstance } from '../../../../../core/utils';
33
- import { getDateOfExpiration, schema } from './utils';
31
+ import schema from './utils/schema';
34
32
  import LoadingView from './components/LoadingView';
35
33
  import HeaderContentBox from './components/ContentBox';
36
- import Permissions from './components/Permissions';
37
- import Regenerate from './components/Regenerate';
38
- import adminPermissions from '../../../../../permissions';
39
- import { ApiTokenPermissionsContextProvider } from '../../../../../contexts/ApiTokenPermissions';
40
- import init from './init';
41
- import reducer, { initialState } from './reducer';
42
-
43
- const MSG_ERROR_NAME_TAKEN = 'Name already taken';
44
34
 
45
35
  const ApiTokenCreateView = () => {
36
+ let apiToken;
46
37
  useFocusWhenNavigate();
47
38
  const { formatMessage } = useIntl();
48
39
  const { lockApp, unlockApp } = useOverlayBlocker();
49
40
  const toggleNotification = useNotification();
50
41
  const history = useHistory();
51
- const [apiToken, setApiToken] = useState(
52
- history.location.state?.apiToken.accessKey
53
- ? {
54
- ...history.location.state.apiToken,
55
- }
56
- : null
57
- );
58
42
  const { trackUsage } = useTracking();
59
43
  const trackUsageRef = useRef(trackUsage);
60
44
  const { setCurrentStep } = useGuidedTour();
61
- const {
62
- allowedActions: { canCreate, canUpdate, canRegenerate },
63
- } = useRBAC(adminPermissions.settings['api-tokens']);
64
- const [lang] = usePersistentState('strapi-admin-language', 'en');
65
- const [state, dispatch] = useReducer(reducer, initialState, (state) => init(state, {}));
45
+
66
46
  const {
67
47
  params: { id },
68
48
  } = useRouteMatch('/settings/api-tokens/:id');
69
49
 
70
50
  const isCreating = id === 'create';
71
51
 
72
- useQuery(
73
- 'content-api-permissions',
74
- async () => {
75
- const [permissions, routes] = await Promise.all(
76
- ['/admin/content-api/permissions', '/admin/content-api/routes'].map(async (url) => {
77
- const { data } = await axiosInstance.get(url);
78
-
79
- return data.data;
80
- })
81
- );
82
-
83
- dispatch({
84
- type: 'UPDATE_PERMISSIONS_LAYOUT',
85
- value: permissions,
86
- });
87
-
88
- dispatch({
89
- type: 'UPDATE_ROUTES',
90
- value: routes,
91
- });
92
-
93
- if (apiToken) {
94
- if (apiToken?.type === 'read-only') {
95
- dispatch({
96
- type: 'ON_CHANGE_READ_ONLY',
97
- });
98
- }
99
- if (apiToken?.type === 'full-access') {
100
- dispatch({
101
- type: 'SELECT_ALL_ACTIONS',
102
- });
103
- }
104
- if (apiToken?.type === 'custom') {
105
- dispatch({
106
- type: 'UPDATE_PERMISSIONS',
107
- value: apiToken?.permissions,
108
- });
109
- }
110
- }
111
- },
112
- {
113
- onError() {
114
- toggleNotification({
115
- type: 'warning',
116
- message: { id: 'notification.error', defaultMessage: 'An error occured' },
117
- });
118
- },
119
- }
120
- );
121
-
122
52
  useEffect(() => {
123
53
  trackUsageRef.current(isCreating ? 'didAddTokenFromList' : 'didEditTokenFromList');
124
54
  }, [isCreating]);
125
55
 
126
- const { status } = useQuery(
56
+ if (history.location.state?.apiToken.accessKey) {
57
+ apiToken = history.location.state.apiToken;
58
+ }
59
+
60
+ const { status, data } = useQuery(
127
61
  ['api-token', id],
128
62
  async () => {
129
63
  const {
130
64
  data: { data },
131
65
  } = await axiosInstance.get(`/admin/api-tokens/${id}`);
132
66
 
133
- setApiToken({
134
- ...data,
135
- });
136
-
137
- if (data?.type === 'read-only') {
138
- dispatch({
139
- type: 'ON_CHANGE_READ_ONLY',
140
- });
141
- }
142
- if (data?.type === 'full-access') {
143
- dispatch({
144
- type: 'SELECT_ALL_ACTIONS',
145
- });
146
- }
147
- if (data?.type === 'custom') {
148
- dispatch({
149
- type: 'UPDATE_PERMISSIONS',
150
- value: data?.permissions,
151
- });
152
- }
153
-
154
67
  return data;
155
68
  },
156
69
  {
@@ -164,6 +77,10 @@ const ApiTokenCreateView = () => {
164
77
  }
165
78
  );
166
79
 
80
+ if (data) {
81
+ apiToken = data;
82
+ }
83
+
167
84
  const handleSubmit = async (body, actions) => {
168
85
  trackUsageRef.current(isCreating ? 'willCreateToken' : 'willEditToken');
169
86
  lockApp();
@@ -172,122 +89,37 @@ const ApiTokenCreateView = () => {
172
89
  const {
173
90
  data: { data: response },
174
91
  } = isCreating
175
- ? await axiosInstance.post(`/admin/api-tokens`, {
176
- ...body,
177
- lifespan:
178
- body.lifespan && parseInt(body.lifespan, 10)
179
- ? parseInt(body.lifespan, 10)
180
- : body.lifespan,
181
- permissions: body.type === 'custom' ? state.selectedActions : null,
182
- })
183
- : await axiosInstance.put(`/admin/api-tokens/${id}`, {
184
- name: body.name,
185
- description: body.description,
186
- type: body.type,
187
- permissions: body.type === 'custom' ? state.selectedActions : null,
188
- });
92
+ ? await axiosInstance.post(`/admin/api-tokens`, body)
93
+ : await axiosInstance.put(`/admin/api-tokens/${id}`, body);
189
94
 
190
- if (isCreating) {
191
- history.replace(`/settings/api-tokens/${response.id}`, { apiToken: response });
192
- setCurrentStep('apiTokens.success');
193
- }
194
- unlockApp();
195
- setApiToken({
196
- ...response,
197
- });
95
+ apiToken = response;
198
96
 
199
97
  toggleNotification({
200
98
  type: 'success',
201
- message: isCreating
202
- ? formatMessage({
203
- id: 'notification.success.tokencreated',
204
- defaultMessage: 'API Token successfully created',
205
- })
206
- : formatMessage({
207
- id: 'notification.success.tokenedited',
208
- defaultMessage: 'API Token successfully edited',
209
- }),
99
+ message: formatMessage({ id: 'notification.success.saved', defaultMessage: 'Saved' }),
210
100
  });
211
101
 
212
102
  trackUsageRef.current(isCreating ? 'didCreateToken' : 'didEditToken', {
213
103
  type: apiToken.type,
214
104
  });
105
+
106
+ if (isCreating) {
107
+ history.replace(`/settings/api-tokens/${response.id}`, { apiToken: response });
108
+ setCurrentStep('apiTokens.success');
109
+ }
215
110
  } catch (err) {
216
111
  const errors = formatAPIErrors(err.response.data);
217
112
  actions.setErrors(errors);
218
113
 
219
- if (err?.response?.data?.error?.message === MSG_ERROR_NAME_TAKEN) {
220
- toggleNotification({
221
- type: 'warning',
222
- message: get(err, 'response.data.message', 'notification.error.tokennamenotunique'),
223
- });
224
- } else {
225
- toggleNotification({
226
- type: 'warning',
227
- message: get(err, 'response.data.message', 'notification.error'),
228
- });
229
- }
230
- unlockApp();
231
- }
232
- };
233
-
234
- const [hasChangedPermissions, setHasChangedPermissions] = useState(false);
235
-
236
- const handleChangeCheckbox = ({ target: { value } }) => {
237
- setHasChangedPermissions(true);
238
- dispatch({
239
- type: 'ON_CHANGE',
240
- value,
241
- });
242
- };
243
-
244
- const handleChangeSelectAllCheckbox = ({ target: { value } }) => {
245
- setHasChangedPermissions(true);
246
- value.forEach((action) => {
247
- dispatch({
248
- type: 'ON_CHANGE',
249
- value: action.actionId,
250
- });
251
- });
252
- };
253
-
254
- const handleChangeSelectApiTokenType = ({ target: { value } }) => {
255
- setHasChangedPermissions(false);
256
-
257
- if (value === 'full-access') {
258
- dispatch({
259
- type: 'SELECT_ALL_ACTIONS',
260
- });
261
- }
262
- if (value === 'read-only') {
263
- dispatch({
264
- type: 'ON_CHANGE_READ_ONLY',
114
+ toggleNotification({
115
+ type: 'warning',
116
+ message: get(err, 'response.data.message', 'notification.error'),
265
117
  });
266
118
  }
267
- };
268
-
269
- const setSelectedAction = ({ target: { value } }) => {
270
- dispatch({
271
- type: 'SET_SELECTED_ACTION',
272
- value,
273
- });
274
- };
275
-
276
- const handleRegenerate = (newKey) => {
277
- setApiToken({
278
- ...apiToken,
279
- accessKey: newKey,
280
- });
281
- };
282
119
 
283
- const providerValue = {
284
- ...state,
285
- onChange: handleChangeCheckbox,
286
- onChangeSelectAll: handleChangeSelectAllCheckbox,
287
- setSelectedAction,
120
+ unlockApp();
288
121
  };
289
122
 
290
- const canEditInputs = (canUpdate && !isCreating) || (canCreate && isCreating);
291
123
  const isLoading = !isCreating && !apiToken && status !== 'success';
292
124
 
293
125
  if (isLoading) {
@@ -295,266 +127,162 @@ const ApiTokenCreateView = () => {
295
127
  }
296
128
 
297
129
  return (
298
- <ApiTokenPermissionsContextProvider value={providerValue}>
299
- <Main>
300
- <SettingsPageTitle name="API Tokens" />
301
- <Formik
302
- validationSchema={schema}
303
- validateOnChange={false}
304
- initialValues={{
305
- name: apiToken?.name || '',
306
- description: apiToken?.description || '',
307
- type: apiToken?.type,
308
- lifespan: apiToken?.lifespan ? apiToken.lifespan.toString() : apiToken?.lifespan,
309
- }}
310
- enableReinitialize
311
- onSubmit={(body, actions) => handleSubmit(body, actions)}
312
- >
313
- {({ errors, handleChange, isSubmitting, values, setFieldValue }) => {
314
- if (hasChangedPermissions && values?.type !== 'custom') {
315
- setFieldValue('type', 'custom');
316
- }
317
-
318
- return (
319
- <Form>
320
- <HeaderLayout
321
- title={
322
- apiToken?.name ||
323
- formatMessage({
324
- id: 'Settings.apiTokens.createPage.title',
325
- defaultMessage: 'Create API Token',
326
- })
327
- }
328
- primaryAction={
329
- canEditInputs ? (
330
- <Stack horizontal spacing={2}>
331
- {canRegenerate && apiToken?.id && (
332
- <Regenerate
333
- onRegenerate={handleRegenerate}
334
- idToRegenerate={apiToken?.id}
130
+ <Main>
131
+ <SettingsPageTitle name="API Tokens" />
132
+ <Formik
133
+ validationSchema={schema}
134
+ validateOnChange={false}
135
+ initialValues={{
136
+ name: apiToken?.name || '',
137
+ description: apiToken?.description || '',
138
+ type: apiToken?.type || 'read-only',
139
+ }}
140
+ onSubmit={handleSubmit}
141
+ >
142
+ {({ errors, handleChange, isSubmitting, values }) => {
143
+ return (
144
+ <Form>
145
+ <HeaderLayout
146
+ title={
147
+ apiToken?.name ||
148
+ formatMessage({
149
+ id: 'Settings.apiTokens.createPage.title',
150
+ defaultMessage: 'Create API Token',
151
+ })
152
+ }
153
+ primaryAction={
154
+ <Button
155
+ disabled={isSubmitting}
156
+ loading={isSubmitting}
157
+ startIcon={<Check />}
158
+ type="submit"
159
+ size="L"
160
+ >
161
+ {formatMessage({
162
+ id: 'global.save',
163
+ defaultMessage: 'Save',
164
+ })}
165
+ </Button>
166
+ }
167
+ navigationAction={
168
+ <Link startIcon={<ArrowLeft />} to="/settings/api-tokens">
169
+ {formatMessage({
170
+ id: 'global.back',
171
+ defaultMessage: 'Back',
172
+ })}
173
+ </Link>
174
+ }
175
+ />
176
+ <ContentLayout>
177
+ <Stack spacing={6}>
178
+ {Boolean(apiToken?.name) && <HeaderContentBox apiToken={apiToken.accessKey} />}
179
+ <Box
180
+ background="neutral0"
181
+ hasRadius
182
+ shadow="filterShadow"
183
+ paddingTop={6}
184
+ paddingBottom={6}
185
+ paddingLeft={7}
186
+ paddingRight={7}
187
+ >
188
+ <Stack spacing={4}>
189
+ <Typography variant="delta" as="h2">
190
+ {formatMessage({
191
+ id: 'global.details',
192
+ defaultMessage: 'Details',
193
+ })}
194
+ </Typography>
195
+ <Grid gap={5}>
196
+ <GridItem key="name" col={6} xs={12}>
197
+ <TextInput
198
+ name="name"
199
+ error={
200
+ errors.name
201
+ ? formatMessage(
202
+ errors.name?.id
203
+ ? errors.name
204
+ : { id: errors.name, defaultMessage: errors.name }
205
+ )
206
+ : null
207
+ }
208
+ label={formatMessage({
209
+ id: 'Settings.apiTokens.form.name',
210
+ defaultMessage: 'Name',
211
+ })}
212
+ onChange={handleChange}
213
+ value={values.name}
214
+ required
335
215
  />
336
- )}
337
- <Button
338
- disabled={isSubmitting}
339
- loading={isSubmitting}
340
- startIcon={<Check />}
341
- type="submit"
342
- size="S"
343
- >
344
- {formatMessage({
345
- id: 'global.save',
346
- defaultMessage: 'Save',
347
- })}
348
- </Button>
349
- </Stack>
350
- ) : (
351
- canRegenerate &&
352
- apiToken?.id && (
353
- <Regenerate onRegenerate={handleRegenerate} idToRegenerate={apiToken?.id} />
354
- )
355
- )
356
- }
357
- navigationAction={
358
- <Link startIcon={<ArrowLeft />} to="/settings/api-tokens">
359
- {formatMessage({
360
- id: 'global.back',
361
- defaultMessage: 'Back',
362
- })}
363
- </Link>
364
- }
365
- />
366
- <ContentLayout>
367
- <Stack spacing={6}>
368
- {Boolean(apiToken?.name) && <HeaderContentBox apiToken={apiToken.accessKey} />}
369
- <Box
370
- background="neutral0"
371
- hasRadius
372
- shadow="filterShadow"
373
- paddingTop={6}
374
- paddingBottom={6}
375
- paddingLeft={7}
376
- paddingRight={7}
377
- >
378
- <Stack spacing={4}>
379
- <Typography variant="delta" as="h2">
380
- {formatMessage({
381
- id: 'global.details',
382
- defaultMessage: 'Details',
383
- })}
384
- </Typography>
385
- <Grid gap={5}>
386
- <GridItem key="name" col={6} xs={12}>
387
- <TextInput
388
- name="name"
389
- error={
390
- errors.name
391
- ? formatMessage(
392
- errors.name?.id
393
- ? errors.name
394
- : { id: errors.name, defaultMessage: errors.name }
395
- )
396
- : null
397
- }
398
- label={formatMessage({
399
- id: 'Settings.apiTokens.form.name',
400
- defaultMessage: 'Name',
401
- })}
402
- onChange={handleChange}
403
- value={values.name}
404
- disabled={!canEditInputs}
405
- required
406
- />
407
- </GridItem>
408
- <GridItem key="description" col={6} xs={12}>
409
- <Textarea
410
- label={formatMessage({
411
- id: 'Settings.apiTokens.form.description',
412
- defaultMessage: 'Description',
216
+ </GridItem>
217
+ <GridItem key="description" col={6} xs={12}>
218
+ <Textarea
219
+ label={formatMessage({
220
+ id: 'Settings.apiTokens.form.description',
221
+ defaultMessage: 'Description',
222
+ })}
223
+ name="description"
224
+ error={
225
+ errors.description
226
+ ? formatMessage(
227
+ errors.description?.id
228
+ ? errors.description
229
+ : {
230
+ id: errors.description,
231
+ defaultMessage: errors.description,
232
+ }
233
+ )
234
+ : null
235
+ }
236
+ onChange={handleChange}
237
+ >
238
+ {values.description}
239
+ </Textarea>
240
+ </GridItem>
241
+ <GridItem key="type" col={6} xs={12}>
242
+ <Select
243
+ name="type"
244
+ label={formatMessage({
245
+ id: 'Settings.apiTokens.form.type',
246
+ defaultMessage: 'Token type',
247
+ })}
248
+ value={values.type}
249
+ error={
250
+ errors.type
251
+ ? formatMessage(
252
+ errors.type?.id
253
+ ? errors.type
254
+ : { id: errors.type, defaultMessage: errors.type }
255
+ )
256
+ : null
257
+ }
258
+ onChange={(value) => {
259
+ handleChange({ target: { name: 'type', value } });
260
+ }}
261
+ >
262
+ <Option value="read-only">
263
+ {formatMessage({
264
+ id: 'Settings.apiTokens.types.read-only',
265
+ defaultMessage: 'Read-only',
413
266
  })}
414
- name="description"
415
- error={
416
- errors.description
417
- ? formatMessage(
418
- errors.description?.id
419
- ? errors.description
420
- : {
421
- id: errors.description,
422
- defaultMessage: errors.description,
423
- }
424
- )
425
- : null
426
- }
427
- onChange={handleChange}
428
- disabled={!canEditInputs}
429
- >
430
- {values.description}
431
- </Textarea>
432
- </GridItem>
433
- <GridItem key="lifespan" col={6} xs={12}>
434
- <Select
435
- name="lifespan"
436
- label={formatMessage({
437
- id: 'Settings.apiTokens.form.duration',
438
- defaultMessage: 'Token duration',
439
- })}
440
- value={values.lifespan}
441
- error={
442
- errors.lifespan
443
- ? formatMessage(
444
- errors.lifespan?.id
445
- ? errors.lifespan
446
- : { id: errors.lifespan, defaultMessage: errors.lifespan }
447
- )
448
- : null
449
- }
450
- onChange={(value) => {
451
- handleChange({ target: { name: 'lifespan', value } });
452
- }}
453
- required
454
- disabled={!isCreating}
455
- placeholder="Select"
456
- >
457
- <Option value="604800000">
458
- {formatMessage({
459
- id: 'Settings.apiTokens.duration.7-days',
460
- defaultMessage: '7 days',
461
- })}
462
- </Option>
463
- <Option value="2592000000">
464
- {formatMessage({
465
- id: 'Settings.apiTokens.duration.30-days',
466
- defaultMessage: '30 days',
467
- })}
468
- </Option>
469
- <Option value="7776000000">
470
- {formatMessage({
471
- id: 'Settings.apiTokens.duration.90-days',
472
- defaultMessage: '90 days',
473
- })}
474
- </Option>
475
- <Option value={null}>
476
- {formatMessage({
477
- id: 'Settings.apiTokens.duration.unlimited',
478
- defaultMessage: 'Unlimited',
479
- })}
480
- </Option>
481
- </Select>
482
- <Typography variant="pi" textColor="neutral600">
483
- {!isCreating &&
484
- `${formatMessage({
485
- id: 'Settings.apiTokens.duration.expiration-date',
486
- defaultMessage: 'Expiration date',
487
- })}: ${getDateOfExpiration(
488
- apiToken?.createdAt,
489
- parseInt(values.lifespan, 10),
490
- lang
491
- )}`}
492
- </Typography>
493
- </GridItem>
494
-
495
- <GridItem key="type" col={6} xs={12}>
496
- <Select
497
- name="type"
498
- label={formatMessage({
499
- id: 'Settings.apiTokens.form.type',
500
- defaultMessage: 'Token type',
267
+ </Option>
268
+ <Option value="full-access">
269
+ {formatMessage({
270
+ id: 'Settings.apiTokens.types.full-access',
271
+ defaultMessage: 'Full access',
501
272
  })}
502
- value={values?.type}
503
- error={
504
- errors.type
505
- ? formatMessage(
506
- errors.type?.id
507
- ? errors.type
508
- : { id: errors.type, defaultMessage: errors.type }
509
- )
510
- : null
511
- }
512
- onChange={(value) => {
513
- handleChangeSelectApiTokenType({ target: { value } });
514
- handleChange({ target: { name: 'type', value } });
515
- }}
516
- placeholder="Select"
517
- required
518
- disabled={!canEditInputs}
519
- >
520
- <Option value="read-only">
521
- {formatMessage({
522
- id: 'Settings.apiTokens.types.read-only',
523
- defaultMessage: 'Read-only',
524
- })}
525
- </Option>
526
- <Option value="full-access">
527
- {formatMessage({
528
- id: 'Settings.apiTokens.types.full-access',
529
- defaultMessage: 'Full access',
530
- })}
531
- </Option>
532
- <Option value="custom">
533
- {formatMessage({
534
- id: 'Settings.apiTokens.types.custom',
535
- defaultMessage: 'Custom',
536
- })}
537
- </Option>
538
- </Select>
539
- </GridItem>
540
- </Grid>
541
- </Stack>
542
- </Box>
543
- <Permissions
544
- disabled={
545
- !canEditInputs ||
546
- values?.type === 'read-only' ||
547
- values?.type === 'full-access'
548
- }
549
- />
550
- </Stack>
551
- </ContentLayout>
552
- </Form>
553
- );
554
- }}
555
- </Formik>
556
- </Main>
557
- </ApiTokenPermissionsContextProvider>
273
+ </Option>
274
+ </Select>
275
+ </GridItem>
276
+ </Grid>
277
+ </Stack>
278
+ </Box>
279
+ </Stack>
280
+ </ContentLayout>
281
+ </Form>
282
+ );
283
+ }}
284
+ </Formik>
285
+ </Main>
558
286
  );
559
287
  };
560
288