@strapi/admin 4.12.4 → 4.12.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/admin/src/content-manager/components/Wysiwyg/WysiwygNav.js +7 -30
- package/admin/src/content-manager/hooks/useSyncRbac/index.js +10 -2
- package/admin/src/content-manager/pages/CollectionTypeRecursivePath/index.js +1 -1
- package/admin/src/content-manager/pages/EditViewLayoutManager/index.js +2 -2
- package/admin/src/content-manager/pages/ListSettingsView/index.js +16 -41
- package/admin/src/content-manager/pages/ListView/index.js +27 -1
- package/admin/src/content-manager/pages/ListViewLayoutManager/index.js +2 -2
- package/admin/src/pages/MarketplacePage/index.js +0 -1
- package/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/index.js +24 -31
- package/admin/src/pages/SettingsPage/pages/TransferTokens/ListView/index.js +11 -6
- package/admin/src/pages/SettingsPage/pages/Users/EditPage/index.js +2 -0
- package/admin/src/pages/SettingsPage/pages/Users/ListPage/index.js +1 -0
- package/admin/src/translations/zh-Hans.json +918 -902
- package/build/4546.7a3c0d03.chunk.js +1 -0
- package/build/{9806.3392505e.chunk.js → 9806.5d5a0e8d.chunk.js} +16 -16
- package/build/{Admin-authenticatedApp.f5ece8ff.chunk.js → Admin-authenticatedApp.01fc56de.chunk.js} +1 -1
- package/build/{Admin_marketplace.dde9c148.chunk.js → Admin_marketplace.c94239f6.chunk.js} +1 -1
- package/build/admin-edit-users.acfd4128.chunk.js +10 -0
- package/build/{admin-users.123aa08e.chunk.js → admin-users.00e20017.chunk.js} +1 -1
- package/build/api-tokens-list-page.0af7d431.chunk.js +16 -0
- package/build/audit-logs-settings-page.0f73ccf8.chunk.js +1 -0
- package/build/content-manager.b40f79c0.chunk.js +1099 -0
- package/build/{content-type-builder.40534de5.chunk.js → content-type-builder.cd999f6e.chunk.js} +2 -2
- package/build/i18n-translation-ru-json.a3dbc125.chunk.js +1 -0
- package/build/index.html +1 -1
- package/build/main.9dbe4579.js +2859 -0
- package/build/{runtime~main.bb4efc54.js → runtime~main.46a609e9.js} +2 -2
- package/build/transfer-tokens-list-page.d6986b03.chunk.js +16 -0
- package/build/users-permissions-translation-zh-Hans-json.8d82c809.chunk.js +1 -0
- package/build/{users-roles-settings-page.3f9f063e.chunk.js → users-roles-settings-page.9d9a1eff.chunk.js} +1 -1
- package/build/zh-Hans-json.97efd015.chunk.js +1 -0
- package/package.json +10 -10
- package/build/4546.cfafae68.chunk.js +0 -1
- package/build/admin-edit-users.79eeb125.chunk.js +0 -10
- package/build/api-tokens-list-page.505bf7e0.chunk.js +0 -16
- package/build/audit-logs-settings-page.4b422831.chunk.js +0 -1
- package/build/content-manager.2af15f57.chunk.js +0 -1099
- package/build/i18n-translation-ru-json.401bc498.chunk.js +0 -1
- package/build/main.f13fc96c.js +0 -2856
- package/build/transfer-tokens-list-page.22147d2c.chunk.js +0 -16
- package/build/users-permissions-translation-zh-Hans-json.6ab714ee.chunk.js +0 -1
- package/build/zh-Hans-json.937b395b.chunk.js +0 -1
|
@@ -64,22 +64,16 @@ const WysiwygNav = ({
|
|
|
64
64
|
</Select>
|
|
65
65
|
|
|
66
66
|
<MainButtons>
|
|
67
|
-
<CustomIconButton disabled
|
|
68
|
-
<CustomIconButton disabled
|
|
69
|
-
<CustomIconButton
|
|
70
|
-
disabled
|
|
71
|
-
id="Underline"
|
|
72
|
-
label="Underline"
|
|
73
|
-
name="Underline"
|
|
74
|
-
icon={<Underline />}
|
|
75
|
-
/>
|
|
67
|
+
<CustomIconButton disabled label="Bold" name="Bold" icon={<Bold />} />
|
|
68
|
+
<CustomIconButton disabled label="Italic" name="Italic" icon={<Italic />} />
|
|
69
|
+
<CustomIconButton disabled label="Underline" name="Underline" icon={<Underline />} />
|
|
76
70
|
</MainButtons>
|
|
77
71
|
|
|
78
|
-
<MoreButton disabled
|
|
72
|
+
<MoreButton disabled label="More" icon={<More />} />
|
|
79
73
|
</StyledFlex>
|
|
80
74
|
|
|
81
75
|
{!isExpandMode && (
|
|
82
|
-
<Button onClick={onTogglePreviewMode} variant="tertiary"
|
|
76
|
+
<Button onClick={onTogglePreviewMode} variant="tertiary">
|
|
83
77
|
{formatMessage({
|
|
84
78
|
id: 'components.Wysiwyg.ToggleMode.markdown-mode',
|
|
85
79
|
defaultMessage: 'Markdown mode',
|
|
@@ -110,21 +104,18 @@ const WysiwygNav = ({
|
|
|
110
104
|
<MainButtons>
|
|
111
105
|
<CustomIconButton
|
|
112
106
|
onClick={() => onActionClick('Bold', editorRef)}
|
|
113
|
-
id="Bold"
|
|
114
107
|
label="Bold"
|
|
115
108
|
name="Bold"
|
|
116
109
|
icon={<Bold />}
|
|
117
110
|
/>
|
|
118
111
|
<CustomIconButton
|
|
119
112
|
onClick={() => onActionClick('Italic', editorRef)}
|
|
120
|
-
id="Italic"
|
|
121
113
|
label="Italic"
|
|
122
114
|
name="Italic"
|
|
123
115
|
icon={<Italic />}
|
|
124
116
|
/>
|
|
125
117
|
<CustomIconButton
|
|
126
118
|
onClick={() => onActionClick('Underline', editorRef)}
|
|
127
|
-
id="Underline"
|
|
128
119
|
label="Underline"
|
|
129
120
|
name="Underline"
|
|
130
121
|
icon={<Underline />}
|
|
@@ -134,37 +125,27 @@ const WysiwygNav = ({
|
|
|
134
125
|
<MoreButton
|
|
135
126
|
ref={buttonMoreRef}
|
|
136
127
|
onClick={handleTogglePopover}
|
|
137
|
-
id="more"
|
|
138
128
|
label="More"
|
|
139
129
|
icon={<More />}
|
|
140
130
|
/>
|
|
141
131
|
{visiblePopover && (
|
|
142
|
-
<Popover
|
|
143
|
-
onDismiss={handleTogglePopover}
|
|
144
|
-
centered
|
|
145
|
-
source={buttonMoreRef}
|
|
146
|
-
spacing={4}
|
|
147
|
-
id="popover"
|
|
148
|
-
>
|
|
132
|
+
<Popover onDismiss={handleTogglePopover} centered source={buttonMoreRef} spacing={4}>
|
|
149
133
|
<Flex>
|
|
150
134
|
<IconButtonGroupMargin>
|
|
151
135
|
<CustomIconButton
|
|
152
136
|
onClick={() => onActionClick('Strikethrough', editorRef, handleTogglePopover)}
|
|
153
|
-
id="Strikethrough"
|
|
154
137
|
label="Strikethrough"
|
|
155
138
|
name="Strikethrough"
|
|
156
139
|
icon={<StrikeThrough />}
|
|
157
140
|
/>
|
|
158
141
|
<CustomIconButton
|
|
159
142
|
onClick={() => onActionClick('BulletList', editorRef, handleTogglePopover)}
|
|
160
|
-
id="BulletList"
|
|
161
143
|
label="BulletList"
|
|
162
144
|
name="BulletList"
|
|
163
145
|
icon={<BulletList />}
|
|
164
146
|
/>
|
|
165
147
|
<CustomIconButton
|
|
166
148
|
onClick={() => onActionClick('NumberList', editorRef, handleTogglePopover)}
|
|
167
|
-
id="NumberList"
|
|
168
149
|
label="NumberList"
|
|
169
150
|
name="NumberList"
|
|
170
151
|
icon={<NumberList />}
|
|
@@ -173,7 +154,6 @@ const WysiwygNav = ({
|
|
|
173
154
|
<IconButtonGroup>
|
|
174
155
|
<CustomIconButton
|
|
175
156
|
onClick={() => onActionClick('Code', editorRef, handleTogglePopover)}
|
|
176
|
-
id="Code"
|
|
177
157
|
label="Code"
|
|
178
158
|
name="Code"
|
|
179
159
|
icon={<Code />}
|
|
@@ -183,14 +163,12 @@ const WysiwygNav = ({
|
|
|
183
163
|
handleTogglePopover();
|
|
184
164
|
onToggleMediaLib();
|
|
185
165
|
}}
|
|
186
|
-
id="Image"
|
|
187
166
|
label="Image"
|
|
188
167
|
name="Image"
|
|
189
168
|
icon={<Image />}
|
|
190
169
|
/>
|
|
191
170
|
<CustomLinkIconButton
|
|
192
171
|
onClick={() => onActionClick('Link', editorRef, handleTogglePopover)}
|
|
193
|
-
id="Link"
|
|
194
172
|
label="Link"
|
|
195
173
|
name="Link"
|
|
196
174
|
// eslint-disable-next-line jsx-a11y/anchor-is-valid
|
|
@@ -198,7 +176,6 @@ const WysiwygNav = ({
|
|
|
198
176
|
/>
|
|
199
177
|
<CustomIconButton
|
|
200
178
|
onClick={() => onActionClick('Quote', editorRef, handleTogglePopover)}
|
|
201
|
-
id="Quote"
|
|
202
179
|
label="Quote"
|
|
203
180
|
name="Quote"
|
|
204
181
|
icon={<Quote />}
|
|
@@ -210,7 +187,7 @@ const WysiwygNav = ({
|
|
|
210
187
|
</StyledFlex>
|
|
211
188
|
|
|
212
189
|
{onTogglePreviewMode && (
|
|
213
|
-
<Button onClick={onTogglePreviewMode} variant="tertiary"
|
|
190
|
+
<Button onClick={onTogglePreviewMode} variant="tertiary">
|
|
214
191
|
{formatMessage({
|
|
215
192
|
id: 'components.Wysiwyg.ToggleMode.preview-mode',
|
|
216
193
|
defaultMessage: 'Preview mode',
|
|
@@ -6,9 +6,10 @@ import { resetPermissions, setPermissions } from './actions';
|
|
|
6
6
|
import { selectCollectionTypePermissions, selectPermissions } from './selectors';
|
|
7
7
|
|
|
8
8
|
const useSyncRbac = (query, collectionTypeUID, containerName = 'listView') => {
|
|
9
|
+
const dispatch = useDispatch();
|
|
10
|
+
|
|
9
11
|
const collectionTypesRelatedPermissions = useSelector(selectCollectionTypePermissions);
|
|
10
12
|
const permissions = useSelector(selectPermissions);
|
|
11
|
-
const dispatch = useDispatch();
|
|
12
13
|
|
|
13
14
|
const relatedPermissions = collectionTypesRelatedPermissions[collectionTypeUID];
|
|
14
15
|
|
|
@@ -24,7 +25,14 @@ const useSyncRbac = (query, collectionTypeUID, containerName = 'listView') => {
|
|
|
24
25
|
return () => {};
|
|
25
26
|
}, [relatedPermissions, dispatch, query, containerName]);
|
|
26
27
|
|
|
27
|
-
|
|
28
|
+
// Check if the permissions are related to the current collectionTypeUID
|
|
29
|
+
const isPermissionMismatch =
|
|
30
|
+
permissions?.some((permission) => permission.subject !== collectionTypeUID) ?? true;
|
|
31
|
+
|
|
32
|
+
return {
|
|
33
|
+
isValid: permissions && !isPermissionMismatch,
|
|
34
|
+
permissions,
|
|
35
|
+
};
|
|
28
36
|
};
|
|
29
37
|
|
|
30
38
|
export default useSyncRbac;
|
|
@@ -12,7 +12,7 @@ import { useFetchContentTypeLayout } from '../../hooks';
|
|
|
12
12
|
import { formatLayoutToApi } from '../../utils';
|
|
13
13
|
import EditSettingsView from '../EditSettingsView';
|
|
14
14
|
import EditViewLayoutManager from '../EditViewLayoutManager';
|
|
15
|
-
import ListSettingsView from '../ListSettingsView';
|
|
15
|
+
import { ListSettingsView } from '../ListSettingsView';
|
|
16
16
|
import ListViewLayout from '../ListViewLayoutManager';
|
|
17
17
|
|
|
18
18
|
import ErrorFallback from './components/ErrorFallback';
|
|
@@ -16,7 +16,7 @@ const EditViewLayoutManager = ({ layout, ...rest }) => {
|
|
|
16
16
|
const dispatch = useDispatch();
|
|
17
17
|
const [{ query }] = useQueryParams();
|
|
18
18
|
const { runHookWaterfall } = useStrapiApp();
|
|
19
|
-
const permissions = useSyncRbac(query, rest.slug, 'editView');
|
|
19
|
+
const { permissions, isValid: isValidPermissions } = useSyncRbac(query, rest.slug, 'editView');
|
|
20
20
|
|
|
21
21
|
useEffect(() => {
|
|
22
22
|
// Allow the plugins to extend the edit view layout
|
|
@@ -29,7 +29,7 @@ const EditViewLayoutManager = ({ layout, ...rest }) => {
|
|
|
29
29
|
};
|
|
30
30
|
}, [layout, dispatch, query, runHookWaterfall]);
|
|
31
31
|
|
|
32
|
-
if (!currentLayout || !
|
|
32
|
+
if (!currentLayout || !isValidPermissions) {
|
|
33
33
|
return <LoadingIndicatorPage />;
|
|
34
34
|
}
|
|
35
35
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as React from 'react';
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
4
|
Button,
|
|
@@ -9,13 +9,7 @@ import {
|
|
|
9
9
|
Layout,
|
|
10
10
|
Main,
|
|
11
11
|
} from '@strapi/design-system';
|
|
12
|
-
import {
|
|
13
|
-
ConfirmDialog,
|
|
14
|
-
Link,
|
|
15
|
-
useFetchClient,
|
|
16
|
-
useNotification,
|
|
17
|
-
useTracking,
|
|
18
|
-
} from '@strapi/helper-plugin';
|
|
12
|
+
import { Link, useFetchClient, useNotification, useTracking } from '@strapi/helper-plugin';
|
|
19
13
|
import { ArrowLeft, Check } from '@strapi/icons';
|
|
20
14
|
import isEqual from 'lodash/isEqual';
|
|
21
15
|
import upperFirst from 'lodash/upperFirst';
|
|
@@ -34,16 +28,14 @@ import { SortDisplayedFields } from './components/SortDisplayedFields';
|
|
|
34
28
|
import { EXCLUDED_SORT_ATTRIBUTE_TYPES } from './constants';
|
|
35
29
|
import reducer, { initialState } from './reducer';
|
|
36
30
|
|
|
37
|
-
const ListSettingsView = ({ layout, slug }) => {
|
|
31
|
+
export const ListSettingsView = ({ layout, slug }) => {
|
|
38
32
|
const { put } = useFetchClient();
|
|
39
33
|
const { formatMessage } = useIntl();
|
|
40
34
|
const { trackUsage } = useTracking();
|
|
41
35
|
const pluginsQueryParams = usePluginsQueryParams();
|
|
42
36
|
const toggleNotification = useNotification();
|
|
43
|
-
const { refetchData } = useContext(ModelsContext);
|
|
44
|
-
const [
|
|
45
|
-
const toggleWarningSubmit = () => setWarningSubmit((prevState) => !prevState);
|
|
46
|
-
const [{ fieldToEdit, fieldForm, initialData, modifiedData }, dispatch] = useReducer(
|
|
37
|
+
const { refetchData } = React.useContext(ModelsContext);
|
|
38
|
+
const [{ fieldToEdit, fieldForm, initialData, modifiedData }, dispatch] = React.useReducer(
|
|
47
39
|
reducer,
|
|
48
40
|
initialState,
|
|
49
41
|
() => ({
|
|
@@ -101,16 +93,6 @@ const ListSettingsView = ({ layout, slug }) => {
|
|
|
101
93
|
}
|
|
102
94
|
);
|
|
103
95
|
|
|
104
|
-
const handleConfirm = async () => {
|
|
105
|
-
const { layouts, settings, metadatas } = modifiedData;
|
|
106
|
-
|
|
107
|
-
mutate({
|
|
108
|
-
layouts,
|
|
109
|
-
settings,
|
|
110
|
-
metadatas,
|
|
111
|
-
});
|
|
112
|
-
};
|
|
113
|
-
|
|
114
96
|
const handleAddField = (item) => {
|
|
115
97
|
dispatch({
|
|
116
98
|
type: 'ADD_FIELD',
|
|
@@ -134,9 +116,17 @@ const ListSettingsView = ({ layout, slug }) => {
|
|
|
134
116
|
}
|
|
135
117
|
};
|
|
136
118
|
|
|
137
|
-
const handleSubmit = (
|
|
138
|
-
|
|
139
|
-
|
|
119
|
+
const handleSubmit = (event) => {
|
|
120
|
+
event.preventDefault();
|
|
121
|
+
|
|
122
|
+
const { layouts, settings, metadatas } = modifiedData;
|
|
123
|
+
|
|
124
|
+
mutate({
|
|
125
|
+
layouts,
|
|
126
|
+
settings,
|
|
127
|
+
metadatas,
|
|
128
|
+
});
|
|
129
|
+
|
|
140
130
|
trackUsage('willSaveContentTypeLayout');
|
|
141
131
|
};
|
|
142
132
|
|
|
@@ -253,19 +243,6 @@ const ListSettingsView = ({ layout, slug }) => {
|
|
|
253
243
|
/>
|
|
254
244
|
</Flex>
|
|
255
245
|
</ContentLayout>
|
|
256
|
-
|
|
257
|
-
<ConfirmDialog
|
|
258
|
-
bodyText={{
|
|
259
|
-
id: getTrad('popUpWarning.warning.updateAllSettings'),
|
|
260
|
-
defaultMessage: 'This will modify all your settings',
|
|
261
|
-
}}
|
|
262
|
-
iconRightButton={<Check />}
|
|
263
|
-
isConfirmButtonLoading={isSubmittingForm}
|
|
264
|
-
isOpen={showWarningSubmit}
|
|
265
|
-
onToggleDialog={toggleWarningSubmit}
|
|
266
|
-
onConfirm={handleConfirm}
|
|
267
|
-
variantRightButton="success-light"
|
|
268
|
-
/>
|
|
269
246
|
</form>
|
|
270
247
|
|
|
271
248
|
{isModalFormOpen && (
|
|
@@ -305,5 +282,3 @@ ListSettingsView.propTypes = {
|
|
|
305
282
|
}).isRequired,
|
|
306
283
|
slug: PropTypes.string.isRequired,
|
|
307
284
|
};
|
|
308
|
-
|
|
309
|
-
export default ListSettingsView;
|
|
@@ -180,6 +180,22 @@ function ListView({
|
|
|
180
180
|
data: { results, pagination: paginationResult },
|
|
181
181
|
} = await fetchClient.get(endPoint, options);
|
|
182
182
|
|
|
183
|
+
// If user enters a page number that doesn't exist, redirect him to the last page
|
|
184
|
+
if (paginationResult.page > paginationResult.pageCount && paginationResult.pageCount > 0) {
|
|
185
|
+
const query = {
|
|
186
|
+
...params,
|
|
187
|
+
page: paginationResult.pageCount,
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
push({
|
|
191
|
+
pathname,
|
|
192
|
+
state: { from: pathname },
|
|
193
|
+
search: stringify(query),
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
|
|
183
199
|
notifyStatus(
|
|
184
200
|
formatMessage(
|
|
185
201
|
{
|
|
@@ -219,7 +235,17 @@ function ListView({
|
|
|
219
235
|
});
|
|
220
236
|
}
|
|
221
237
|
},
|
|
222
|
-
[
|
|
238
|
+
[
|
|
239
|
+
formatMessage,
|
|
240
|
+
getData,
|
|
241
|
+
getDataSucceeded,
|
|
242
|
+
notifyStatus,
|
|
243
|
+
push,
|
|
244
|
+
toggleNotification,
|
|
245
|
+
fetchClient,
|
|
246
|
+
params,
|
|
247
|
+
pathname,
|
|
248
|
+
]
|
|
223
249
|
);
|
|
224
250
|
|
|
225
251
|
const handleConfirmDeleteAllData = React.useCallback(
|
|
@@ -14,7 +14,7 @@ const ListViewLayout = ({ layout, ...props }) => {
|
|
|
14
14
|
const dispatch = useDispatch();
|
|
15
15
|
const { replace } = useHistory();
|
|
16
16
|
const [{ query, rawQuery }] = useQueryParams();
|
|
17
|
-
const permissions = useSyncRbac(query, props.slug, 'listView');
|
|
17
|
+
const { permissions, isValid: isValidPermissions } = useSyncRbac(query, props.slug, 'listView');
|
|
18
18
|
const redirectionLink = useFindRedirectionLink(props.slug);
|
|
19
19
|
|
|
20
20
|
useEffect(() => {
|
|
@@ -33,7 +33,7 @@ const ListViewLayout = ({ layout, ...props }) => {
|
|
|
33
33
|
};
|
|
34
34
|
}, [dispatch]);
|
|
35
35
|
|
|
36
|
-
if (!
|
|
36
|
+
if (!isValidPermissions) {
|
|
37
37
|
return null;
|
|
38
38
|
}
|
|
39
39
|
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as React from 'react';
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { ContentLayout, HeaderLayout, Main } from '@strapi/design-system';
|
|
4
4
|
import {
|
|
5
5
|
LinkButton,
|
|
6
6
|
NoContent,
|
|
7
7
|
NoPermissions,
|
|
8
8
|
SettingsPageTitle,
|
|
9
|
+
useAPIErrorHandler,
|
|
9
10
|
useFetchClient,
|
|
10
11
|
useFocusWhenNavigate,
|
|
11
12
|
useGuidedTour,
|
|
@@ -38,16 +39,17 @@ const ApiTokenListView = () => {
|
|
|
38
39
|
const { push } = useHistory();
|
|
39
40
|
const { trackUsage } = useTracking();
|
|
40
41
|
const { startSection } = useGuidedTour();
|
|
41
|
-
const startSectionRef = useRef(startSection);
|
|
42
|
+
const startSectionRef = React.useRef(startSection);
|
|
42
43
|
const { get, del } = useFetchClient();
|
|
44
|
+
const { formatAPIError } = useAPIErrorHandler();
|
|
43
45
|
|
|
44
|
-
useEffect(() => {
|
|
46
|
+
React.useEffect(() => {
|
|
45
47
|
if (startSectionRef.current) {
|
|
46
48
|
startSectionRef.current('apiTokens');
|
|
47
49
|
}
|
|
48
50
|
}, []);
|
|
49
51
|
|
|
50
|
-
useEffect(() => {
|
|
52
|
+
React.useEffect(() => {
|
|
51
53
|
push({ search: qs.stringify({ sort: 'name:ASC' }, { encode: false }) });
|
|
52
54
|
}, [push]);
|
|
53
55
|
|
|
@@ -59,16 +61,13 @@ const ApiTokenListView = () => {
|
|
|
59
61
|
},
|
|
60
62
|
}));
|
|
61
63
|
|
|
62
|
-
const {
|
|
63
|
-
data: apiTokens,
|
|
64
|
-
status,
|
|
65
|
-
isFetching,
|
|
66
|
-
} = useQuery(
|
|
64
|
+
const { data: apiTokens, isLoading: isLoadingTokens } = useQuery(
|
|
67
65
|
['api-tokens'],
|
|
68
66
|
async () => {
|
|
69
67
|
trackUsage('willAccessTokenList', {
|
|
70
68
|
tokenType: API_TOKEN_TYPE,
|
|
71
69
|
});
|
|
70
|
+
|
|
72
71
|
const {
|
|
73
72
|
data: { data },
|
|
74
73
|
} = await get(`/admin/api-tokens`);
|
|
@@ -78,19 +77,18 @@ const ApiTokenListView = () => {
|
|
|
78
77
|
return data;
|
|
79
78
|
},
|
|
80
79
|
{
|
|
80
|
+
cacheTime: 0,
|
|
81
81
|
enabled: canRead,
|
|
82
|
-
onError() {
|
|
82
|
+
onError(error) {
|
|
83
83
|
toggleNotification({
|
|
84
84
|
type: 'warning',
|
|
85
|
-
message:
|
|
85
|
+
message: formatAPIError(error),
|
|
86
86
|
});
|
|
87
87
|
},
|
|
88
88
|
}
|
|
89
89
|
);
|
|
90
90
|
|
|
91
|
-
const isLoading =
|
|
92
|
-
canRead &&
|
|
93
|
-
((status !== 'success' && status !== 'error') || (status === 'success' && isFetching));
|
|
91
|
+
const isLoading = isLoadingTokens;
|
|
94
92
|
|
|
95
93
|
const deleteMutation = useMutation(
|
|
96
94
|
async (id) => {
|
|
@@ -101,25 +99,20 @@ const ApiTokenListView = () => {
|
|
|
101
99
|
await queryClient.invalidateQueries(['api-tokens']);
|
|
102
100
|
trackUsage('didDeleteToken');
|
|
103
101
|
},
|
|
104
|
-
onError(
|
|
105
|
-
|
|
106
|
-
toggleNotification({ type: 'warning', message: err.response.data.data });
|
|
107
|
-
} else {
|
|
108
|
-
toggleNotification({
|
|
109
|
-
type: 'warning',
|
|
110
|
-
message: { id: 'notification.error', defaultMessage: 'An error occured' },
|
|
111
|
-
});
|
|
112
|
-
}
|
|
102
|
+
onError(error) {
|
|
103
|
+
toggleNotification({ type: 'warning', message: formatAPIError(error) });
|
|
113
104
|
},
|
|
114
105
|
}
|
|
115
106
|
);
|
|
116
107
|
|
|
117
|
-
const
|
|
118
|
-
const
|
|
119
|
-
const
|
|
108
|
+
const hasApiTokens = apiTokens && apiTokens.length > 0;
|
|
109
|
+
const shouldDisplayDynamicTable = canRead && hasApiTokens;
|
|
110
|
+
const shouldDisplayNoContent = canRead && !hasApiTokens && !canCreate;
|
|
111
|
+
const shouldDisplayNoContentWithCreationButton = canRead && !hasApiTokens && canCreate;
|
|
120
112
|
|
|
121
113
|
return (
|
|
122
114
|
<Main aria-busy={isLoading}>
|
|
115
|
+
{/* TODO: this needs to be translated */}
|
|
123
116
|
<SettingsPageTitle name="API Tokens" />
|
|
124
117
|
<HeaderLayout
|
|
125
118
|
title={formatMessage({ id: 'Settings.apiTokens.title', defaultMessage: 'API Tokens' })}
|
|
@@ -128,7 +121,7 @@ const ApiTokenListView = () => {
|
|
|
128
121
|
defaultMessage: 'List of generated tokens to consume the API',
|
|
129
122
|
})}
|
|
130
123
|
primaryAction={
|
|
131
|
-
canCreate
|
|
124
|
+
canCreate && (
|
|
132
125
|
<LinkButton
|
|
133
126
|
data-testid="create-api-token-button"
|
|
134
127
|
startIcon={<Plus />}
|
|
@@ -145,7 +138,7 @@ const ApiTokenListView = () => {
|
|
|
145
138
|
defaultMessage: 'Create new API Token',
|
|
146
139
|
})}
|
|
147
140
|
</LinkButton>
|
|
148
|
-
)
|
|
141
|
+
)
|
|
149
142
|
}
|
|
150
143
|
/>
|
|
151
144
|
<ContentLayout>
|
|
@@ -169,12 +162,12 @@ const ApiTokenListView = () => {
|
|
|
169
162
|
defaultMessage: 'Add your first API Token',
|
|
170
163
|
}}
|
|
171
164
|
action={
|
|
172
|
-
<
|
|
165
|
+
<LinkButton variant="secondary" startIcon={<Plus />} to="/settings/api-tokens/create">
|
|
173
166
|
{formatMessage({
|
|
174
167
|
id: 'Settings.apiTokens.addNewToken',
|
|
175
168
|
defaultMessage: 'Add new API Token',
|
|
176
169
|
})}
|
|
177
|
-
</
|
|
170
|
+
</LinkButton>
|
|
178
171
|
}
|
|
179
172
|
/>
|
|
180
173
|
)}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { useEffect, useRef } from 'react';
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { ContentLayout, HeaderLayout, Main } from '@strapi/design-system';
|
|
4
4
|
import {
|
|
5
5
|
LinkButton,
|
|
6
6
|
NoContent,
|
|
@@ -136,9 +136,10 @@ const TransferTokenListView = () => {
|
|
|
136
136
|
}
|
|
137
137
|
);
|
|
138
138
|
|
|
139
|
-
const
|
|
140
|
-
const
|
|
141
|
-
const
|
|
139
|
+
const hasTransferTokens = transferTokens && transferTokens?.length > 0;
|
|
140
|
+
const shouldDisplayDynamicTable = canRead && hasTransferTokens;
|
|
141
|
+
const shouldDisplayNoContent = canRead && !hasTransferTokens && !canCreate;
|
|
142
|
+
const shouldDisplayNoContentWithCreationButton = canRead && !hasTransferTokens && canCreate;
|
|
142
143
|
|
|
143
144
|
return (
|
|
144
145
|
<Main aria-busy={isLoading}>
|
|
@@ -194,12 +195,16 @@ const TransferTokenListView = () => {
|
|
|
194
195
|
defaultMessage: 'Add your first Transfer Token',
|
|
195
196
|
}}
|
|
196
197
|
action={
|
|
197
|
-
<
|
|
198
|
+
<LinkButton
|
|
199
|
+
variant="secondary"
|
|
200
|
+
startIcon={<Plus />}
|
|
201
|
+
to="/settings/transfer-tokens/create"
|
|
202
|
+
>
|
|
198
203
|
{formatMessage({
|
|
199
204
|
id: 'Settings.transferTokens.addNewToken',
|
|
200
205
|
defaultMessage: 'Add new Transfer Token',
|
|
201
206
|
})}
|
|
202
|
-
</
|
|
207
|
+
</LinkButton>
|
|
203
208
|
}
|
|
204
209
|
/>
|
|
205
210
|
)}
|