@strapi/admin 4.11.3 → 4.11.4
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/components/AuthenticatedApp/index.js +2 -2
- package/admin/src/content-manager/components/RelationInput/RelationInput.js +99 -178
- package/admin/src/content-manager/components/RelationInput/components/Option.js +17 -15
- package/admin/src/content-manager/components/RelationInput/components/RelationList.js +2 -2
- package/admin/src/content-manager/pages/ListView/index.js +12 -0
- package/admin/src/pages/SettingsPage/components/Tokens/Table/index.js +15 -1
- package/admin/src/pages/SettingsPage/pages/Roles/ProtectedEditPage/index.js +4 -10
- package/admin/src/pages/SettingsPage/pages/Users/EditPage/index.js +2 -2
- package/admin/src/pages/SettingsPage/pages/Webhooks/EditView/components/WebhookForm/utils/makeWebhookValidationSchema.js +11 -5
- package/admin/src/translations/ca.json +1 -0
- package/admin/src/translations/en.json +4 -1
- package/admin/src/translations/es.json +5 -0
- package/admin/src/translations/fr.json +1 -0
- package/build/{1799.84268ad3.chunk.js → 1799.44d2e264.chunk.js} +1 -1
- package/build/{5542.64b623c9.chunk.js → 5542.c62d0daf.chunk.js} +1 -1
- package/build/{6405.27e1bee5.chunk.js → 970.89601f27.chunk.js} +2 -2
- package/build/Admin-authenticatedApp.cb649fc1.chunk.js +79 -0
- package/build/{admin-edit-roles-page.2040034a.chunk.js → admin-edit-roles-page.3fdd6b9d.chunk.js} +11 -11
- package/build/admin-edit-users.200551e3.chunk.js +10 -0
- package/build/api-tokens-list-page.a103f526.chunk.js +16 -0
- package/build/audit-logs-settings-page.f538490f.chunk.js +1 -0
- package/build/ca-json.1fed5d8b.chunk.js +1 -0
- package/build/content-manager.c40f5ff9.chunk.js +1088 -0
- package/build/{content-type-builder-list-view.0c3ceb4e.chunk.js → content-type-builder-list-view.a200a358.chunk.js} +1 -1
- package/build/{content-type-builder.e1b6d13b.chunk.js → content-type-builder.bd1bbff1.chunk.js} +15 -15
- package/build/{email-settings-page.6b38222d.chunk.js → email-settings-page.45695daa.chunk.js} +1 -1
- package/build/en-json.fb9f6ddd.chunk.js +1 -0
- package/build/es-json.42096084.chunk.js +1 -0
- package/build/fr-json.69789980.chunk.js +1 -0
- package/build/{i18n-settings-page.ff863f20.chunk.js → i18n-settings-page.29308d0b.chunk.js} +1 -1
- package/build/index.html +1 -1
- package/build/main.ee36abd9.js +2927 -0
- package/build/{runtime~main.20c3cac6.js → runtime~main.efd966f6.js} +1 -1
- package/build/sso-settings-page.0cdb96a6.chunk.js +1 -0
- package/build/transfer-tokens-list-page.7237443d.chunk.js +16 -0
- package/build/{upload-settings.43cf16cd.chunk.js → upload-settings.cb6c14c3.chunk.js} +1 -1
- package/build/{upload.72f8f8fc.chunk.js → upload.7e629643.chunk.js} +2 -2
- package/build/users-advanced-settings-page.750b1f76.chunk.js +9 -0
- package/build/{users-email-settings-page.33359797.chunk.js → users-email-settings-page.e9bcd865.chunk.js} +1 -1
- package/build/{users-providers-settings-page.1e7a4a71.chunk.js → users-providers-settings-page.a94253e9.chunk.js} +1 -1
- package/build/{users-roles-settings-page.235378b6.chunk.js → users-roles-settings-page.1f505119.chunk.js} +5 -5
- package/build/webhook-edit-page.77ef4f1a.chunk.js +33 -0
- package/ee/admin/pages/SettingsPage/pages/AuditLogs/ListView/index.js +4 -9
- package/ee/admin/pages/SettingsPage/pages/SingleSignOn/index.js +4 -9
- package/ee/server/services/review-workflows/entity-service-decorator.js +20 -11
- package/package.json +12 -12
- package/server/content-types/User.js +10 -0
- package/server/strategies/api-token.js +9 -5
- package/server/strategies/data-transfer.js +9 -5
- package/admin/src/content-manager/components/RelationInput/components/Relation.js +0 -53
- package/build/Admin-authenticatedApp.69855f1b.chunk.js +0 -79
- package/build/admin-edit-users.53e4290a.chunk.js +0 -10
- package/build/api-tokens-list-page.201fb67a.chunk.js +0 -16
- package/build/audit-logs-settings-page.b07ad202.chunk.js +0 -1
- package/build/ca-json.43e14418.chunk.js +0 -1
- package/build/content-manager.66cec770.chunk.js +0 -1094
- package/build/en-json.f5fa476a.chunk.js +0 -1
- package/build/es-json.715b6fd8.chunk.js +0 -1
- package/build/fr-json.73494bf5.chunk.js +0 -1
- package/build/main.83edb3fc.js +0 -2926
- package/build/sso-settings-page.35b67909.chunk.js +0 -1
- package/build/transfer-tokens-list-page.217573c3.chunk.js +0 -16
- package/build/users-advanced-settings-page.1911adf5.chunk.js +0 -9
- package/build/webhook-edit-page.1ee02c4b.chunk.js +0 -33
|
@@ -38,7 +38,7 @@ const AuthenticatedApp = () => {
|
|
|
38
38
|
const [
|
|
39
39
|
{ data: appInfos, status },
|
|
40
40
|
{ data: tagName, isLoading },
|
|
41
|
-
{ data: permissions, status: fetchPermissionsStatus, refetch,
|
|
41
|
+
{ data: permissions, status: fetchPermissionsStatus, refetch, isFetching },
|
|
42
42
|
{ data: userRoles },
|
|
43
43
|
] = useQueries([
|
|
44
44
|
{ queryKey: 'app-infos', queryFn: fetchAppInfo },
|
|
@@ -86,7 +86,7 @@ const AuthenticatedApp = () => {
|
|
|
86
86
|
// We don't need to wait for the release query to be fetched before rendering the plugins
|
|
87
87
|
// however, we need the appInfos and the permissions
|
|
88
88
|
const shouldShowNotDependentQueriesLoader =
|
|
89
|
-
|
|
89
|
+
isFetching || status === 'loading' || fetchPermissionsStatus === 'loading';
|
|
90
90
|
|
|
91
91
|
const shouldShowLoader = isLoading || shouldShowNotDependentQueriesLoader;
|
|
92
92
|
|
|
@@ -1,24 +1,17 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, { useRef, useState, useMemo, useEffect } from 'react';
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
|
+
Status,
|
|
4
5
|
Box,
|
|
5
|
-
Field,
|
|
6
|
-
FieldError,
|
|
7
|
-
FieldHint,
|
|
8
|
-
FieldLabel,
|
|
9
|
-
Icon,
|
|
10
6
|
Link,
|
|
11
|
-
|
|
7
|
+
Icon,
|
|
8
|
+
Flex,
|
|
12
9
|
TextButton,
|
|
13
|
-
Tooltip,
|
|
14
10
|
Typography,
|
|
11
|
+
Tooltip,
|
|
15
12
|
VisuallyHidden,
|
|
13
|
+
Combobox,
|
|
16
14
|
} from '@strapi/design-system';
|
|
17
|
-
/**
|
|
18
|
-
* TODO: this will come in another PR.
|
|
19
|
-
*/
|
|
20
|
-
// eslint-disable-next-line no-restricted-imports
|
|
21
|
-
import { ReactSelect } from '@strapi/helper-plugin';
|
|
22
15
|
import { Cross, Refresh } from '@strapi/icons';
|
|
23
16
|
import PropTypes from 'prop-types';
|
|
24
17
|
import { FixedSizeList as List } from 'react-window';
|
|
@@ -27,7 +20,6 @@ import styled from 'styled-components';
|
|
|
27
20
|
import { usePrev } from '../../hooks';
|
|
28
21
|
|
|
29
22
|
import { Option } from './components/Option';
|
|
30
|
-
import { Relation } from './components/Relation';
|
|
31
23
|
import { RelationItem } from './components/RelationItem';
|
|
32
24
|
import { RelationList } from './components/RelationList';
|
|
33
25
|
import { RELATION_GUTTER, RELATION_ITEM_HEIGHT } from './constants';
|
|
@@ -88,7 +80,7 @@ const RelationInput = ({
|
|
|
88
80
|
searchResults,
|
|
89
81
|
size,
|
|
90
82
|
}) => {
|
|
91
|
-
const [
|
|
83
|
+
const [textValue, setTextValue] = useState('');
|
|
92
84
|
const [overflow, setOverflow] = useState('');
|
|
93
85
|
|
|
94
86
|
const listRef = useRef();
|
|
@@ -158,71 +150,10 @@ const RelationInput = ({
|
|
|
158
150
|
};
|
|
159
151
|
}, [paginatedRelations, relations, numberOfRelationsToDisplay, totalNumberOfRelations]);
|
|
160
152
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
/**
|
|
165
|
-
* This code is being isolated because it's a hack to fix a placement bug in
|
|
166
|
-
* `react-select` where when the options prop is updated the position of the
|
|
167
|
-
* menu is not recalculated.
|
|
168
|
-
*/
|
|
169
|
-
const [isMenuOpen, setIsMenuOpen] = useState(false);
|
|
170
|
-
|
|
171
|
-
const timeoutRef = useRef();
|
|
172
|
-
const previousOptions = useRef([]);
|
|
173
|
-
|
|
174
|
-
useEffect(() => {
|
|
175
|
-
/**
|
|
176
|
-
* We only really want this effect to fire once when the options
|
|
177
|
-
* change from an empty array to an array with values.
|
|
178
|
-
* Otherwise, it'll fire when the infinite scrolling happens causing
|
|
179
|
-
* the menu to jump to the top all the time when loading more.
|
|
180
|
-
*/
|
|
181
|
-
if (options.length > 0 && previousOptions.current.length === 0) {
|
|
182
|
-
setIsMenuOpen((isCurrentlyOpened) => {
|
|
183
|
-
/**
|
|
184
|
-
* If we're currently open and the options changed
|
|
185
|
-
* we want to close and open to ensure the menu's
|
|
186
|
-
* position is correctly calculated
|
|
187
|
-
*/
|
|
188
|
-
if (isCurrentlyOpened) {
|
|
189
|
-
timeoutRef.current = setTimeout(() => {
|
|
190
|
-
setIsMenuOpen(true);
|
|
191
|
-
}, 10);
|
|
192
|
-
|
|
193
|
-
return false;
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
return false;
|
|
197
|
-
});
|
|
153
|
+
const handleMenuOpen = (isOpen) => {
|
|
154
|
+
if (isOpen) {
|
|
155
|
+
onSearch();
|
|
198
156
|
}
|
|
199
|
-
|
|
200
|
-
return () => {
|
|
201
|
-
previousOptions.current = options || [];
|
|
202
|
-
};
|
|
203
|
-
}, [options]);
|
|
204
|
-
|
|
205
|
-
useEffect(() => {
|
|
206
|
-
return () => {
|
|
207
|
-
/**
|
|
208
|
-
* If the component unmounts and a timer is set we should clear that timer
|
|
209
|
-
*/
|
|
210
|
-
if (timeoutRef.current) {
|
|
211
|
-
clearTimeout(timeoutRef.current);
|
|
212
|
-
}
|
|
213
|
-
};
|
|
214
|
-
}, []);
|
|
215
|
-
|
|
216
|
-
const handleMenuClose = () => {
|
|
217
|
-
setIsMenuOpen(false);
|
|
218
|
-
};
|
|
219
|
-
/**
|
|
220
|
-
* --- ReactSelect Workaround END ---
|
|
221
|
-
*/
|
|
222
|
-
|
|
223
|
-
const handleMenuOpen = () => {
|
|
224
|
-
setIsMenuOpen(true);
|
|
225
|
-
onSearch();
|
|
226
157
|
};
|
|
227
158
|
|
|
228
159
|
/**
|
|
@@ -250,122 +181,112 @@ const RelationInput = ({
|
|
|
250
181
|
};
|
|
251
182
|
|
|
252
183
|
useEffect(() => {
|
|
184
|
+
if (updatedRelationsWith.current === 'onChange') {
|
|
185
|
+
setTextValue('');
|
|
186
|
+
}
|
|
187
|
+
|
|
253
188
|
if (
|
|
254
189
|
updatedRelationsWith.current === 'onChange' &&
|
|
255
190
|
relations.length !== previewRelationsLength
|
|
256
191
|
) {
|
|
257
192
|
listRef.current.scrollToItem(relations.length, 'end');
|
|
193
|
+
updatedRelationsWith.current = undefined;
|
|
258
194
|
} else if (
|
|
259
195
|
updatedRelationsWith.current === 'loadMore' &&
|
|
260
196
|
relations.length !== previewRelationsLength
|
|
261
197
|
) {
|
|
262
198
|
listRef.current.scrollToItem(0, 'start');
|
|
199
|
+
updatedRelationsWith.current = undefined;
|
|
263
200
|
}
|
|
264
|
-
|
|
265
|
-
updatedRelationsWith.current = undefined;
|
|
266
201
|
}, [previewRelationsLength, relations]);
|
|
267
202
|
|
|
268
203
|
const ariaDescriptionId = `${name}-item-instructions`;
|
|
269
204
|
|
|
270
205
|
return (
|
|
271
|
-
<
|
|
272
|
-
<
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
onClick={handleLoadMore}
|
|
321
|
-
loading={paginatedRelations.isLoading || paginatedRelations.isFetchingNextPage}
|
|
322
|
-
startIcon={<Refresh />}
|
|
323
|
-
>
|
|
324
|
-
{labelLoadMore}
|
|
325
|
-
</TextButton>
|
|
326
|
-
)
|
|
327
|
-
}
|
|
328
|
-
>
|
|
329
|
-
{relations.length > 0 && (
|
|
330
|
-
<RelationList overflow={overflow}>
|
|
331
|
-
<VisuallyHidden id={ariaDescriptionId}>{listAriaDescription}</VisuallyHidden>
|
|
332
|
-
<VisuallyHidden aria-live="assertive">{liveText}</VisuallyHidden>
|
|
333
|
-
<List
|
|
334
|
-
height={dynamicListHeight}
|
|
335
|
-
ref={listRef}
|
|
336
|
-
outerRef={outerListRef}
|
|
337
|
-
itemCount={totalNumberOfRelations}
|
|
338
|
-
itemSize={RELATION_ITEM_HEIGHT + RELATION_GUTTER}
|
|
339
|
-
itemData={{
|
|
340
|
-
name,
|
|
341
|
-
ariaDescribedBy: ariaDescriptionId,
|
|
342
|
-
canDrag: canReorder,
|
|
343
|
-
disabled,
|
|
344
|
-
handleCancel: onCancel,
|
|
345
|
-
handleDropItem: onDropItem,
|
|
346
|
-
handleGrabItem: onGrabItem,
|
|
347
|
-
iconButtonAriaLabel,
|
|
348
|
-
labelDisconnectRelation,
|
|
349
|
-
onRelationDisconnect,
|
|
350
|
-
publicationStateTranslations,
|
|
351
|
-
relations,
|
|
352
|
-
updatePositionOfRelation: handleUpdatePositionOfRelation,
|
|
353
|
-
}}
|
|
354
|
-
itemKey={(index) => `${relations[index].mainField}_${relations[index].id}`}
|
|
355
|
-
innerElementType="ol"
|
|
356
|
-
>
|
|
357
|
-
{ListItem}
|
|
358
|
-
</List>
|
|
359
|
-
</RelationList>
|
|
360
|
-
)}
|
|
361
|
-
{(description || error) && (
|
|
362
|
-
<Box paddingTop={2}>
|
|
363
|
-
<FieldHint />
|
|
364
|
-
<FieldError />
|
|
365
|
-
</Box>
|
|
206
|
+
<Flex gap={3} justifyContent="space-between" alignItems="end" wrap="wrap">
|
|
207
|
+
<Flex direction="column" alignItems="stretch" basis={size <= 6 ? '100%' : '70%'} gap={2}>
|
|
208
|
+
<Combobox
|
|
209
|
+
autocomplete="list"
|
|
210
|
+
error={error}
|
|
211
|
+
name={name}
|
|
212
|
+
hint={description}
|
|
213
|
+
id={id}
|
|
214
|
+
required={required}
|
|
215
|
+
label={label}
|
|
216
|
+
labelAction={labelAction}
|
|
217
|
+
disabled={disabled}
|
|
218
|
+
placeholder={placeholder}
|
|
219
|
+
hasMoreItems={searchResults.hasNextPage}
|
|
220
|
+
loading={searchResults.isLoading}
|
|
221
|
+
onOpenChange={handleMenuOpen}
|
|
222
|
+
noOptionsMessage={() => noRelationsMessage}
|
|
223
|
+
loadingMessage={loadingMessage}
|
|
224
|
+
onLoadMore={() => {
|
|
225
|
+
onSearchNextPage();
|
|
226
|
+
}}
|
|
227
|
+
textValue={textValue}
|
|
228
|
+
onChange={(relationId) => {
|
|
229
|
+
if (!relationId) {
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
onRelationConnect(options.find((opt) => opt.id === relationId));
|
|
233
|
+
updatedRelationsWith.current = 'onChange';
|
|
234
|
+
}}
|
|
235
|
+
onTextValueChange={(text) => {
|
|
236
|
+
setTextValue(text);
|
|
237
|
+
}}
|
|
238
|
+
onInputChange={(event) => {
|
|
239
|
+
onSearch(event.currentTarget.value);
|
|
240
|
+
}}
|
|
241
|
+
>
|
|
242
|
+
{options.map((opt) => {
|
|
243
|
+
return <Option key={opt.id} {...opt} />;
|
|
244
|
+
})}
|
|
245
|
+
</Combobox>
|
|
246
|
+
{shouldDisplayLoadMoreButton && (
|
|
247
|
+
<TextButton
|
|
248
|
+
disabled={paginatedRelations.isLoading || paginatedRelations.isFetchingNextPage}
|
|
249
|
+
onClick={handleLoadMore}
|
|
250
|
+
loading={paginatedRelations.isLoading || paginatedRelations.isFetchingNextPage}
|
|
251
|
+
startIcon={<Refresh />}
|
|
252
|
+
>
|
|
253
|
+
{labelLoadMore}
|
|
254
|
+
</TextButton>
|
|
366
255
|
)}
|
|
367
|
-
</
|
|
368
|
-
|
|
256
|
+
</Flex>
|
|
257
|
+
{relations.length > 0 && (
|
|
258
|
+
<RelationList overflow={overflow}>
|
|
259
|
+
<VisuallyHidden id={ariaDescriptionId}>{listAriaDescription}</VisuallyHidden>
|
|
260
|
+
<VisuallyHidden aria-live="assertive">{liveText}</VisuallyHidden>
|
|
261
|
+
<List
|
|
262
|
+
height={dynamicListHeight}
|
|
263
|
+
ref={listRef}
|
|
264
|
+
outerRef={outerListRef}
|
|
265
|
+
itemCount={totalNumberOfRelations}
|
|
266
|
+
itemSize={RELATION_ITEM_HEIGHT + RELATION_GUTTER}
|
|
267
|
+
itemData={{
|
|
268
|
+
name,
|
|
269
|
+
ariaDescribedBy: ariaDescriptionId,
|
|
270
|
+
canDrag: canReorder,
|
|
271
|
+
disabled,
|
|
272
|
+
handleCancel: onCancel,
|
|
273
|
+
handleDropItem: onDropItem,
|
|
274
|
+
handleGrabItem: onGrabItem,
|
|
275
|
+
iconButtonAriaLabel,
|
|
276
|
+
labelDisconnectRelation,
|
|
277
|
+
onRelationDisconnect,
|
|
278
|
+
publicationStateTranslations,
|
|
279
|
+
relations,
|
|
280
|
+
updatePositionOfRelation: handleUpdatePositionOfRelation,
|
|
281
|
+
}}
|
|
282
|
+
itemKey={(index) => `${relations[index].mainField}_${relations[index].id}`}
|
|
283
|
+
innerElementType="ol"
|
|
284
|
+
>
|
|
285
|
+
{ListItem}
|
|
286
|
+
</List>
|
|
287
|
+
</RelationList>
|
|
288
|
+
)}
|
|
289
|
+
</Flex>
|
|
369
290
|
);
|
|
370
291
|
};
|
|
371
292
|
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
|
|
3
|
-
import { Flex, Typography } from '@strapi/design-system';
|
|
3
|
+
import { Flex, Typography, ComboboxOption } from '@strapi/design-system';
|
|
4
4
|
import { pxToRem } from '@strapi/helper-plugin';
|
|
5
5
|
import PropTypes from 'prop-types';
|
|
6
6
|
import { useIntl } from 'react-intl';
|
|
7
|
-
import { components } from 'react-select';
|
|
8
7
|
import styled from 'styled-components';
|
|
9
8
|
|
|
10
9
|
import { getTrad } from '../../../utils';
|
|
@@ -19,10 +18,8 @@ const StyledBullet = styled.div`
|
|
|
19
18
|
border-radius: 50%;
|
|
20
19
|
`;
|
|
21
20
|
|
|
22
|
-
export const Option = (
|
|
21
|
+
export const Option = ({ publicationState, mainField, id }) => {
|
|
23
22
|
const { formatMessage } = useIntl();
|
|
24
|
-
const Component = components.Option;
|
|
25
|
-
const { publicationState, mainField, id } = props.data;
|
|
26
23
|
|
|
27
24
|
if (publicationState) {
|
|
28
25
|
const isDraft = publicationState === 'draft';
|
|
@@ -37,24 +34,29 @@ export const Option = (props) => {
|
|
|
37
34
|
const title = isDraft ? formatMessage(draftMessage) : formatMessage(publishedMessage);
|
|
38
35
|
|
|
39
36
|
return (
|
|
40
|
-
<
|
|
37
|
+
<ComboboxOption value={id} textValue={mainField ?? id}>
|
|
41
38
|
<Flex>
|
|
42
39
|
<StyledBullet title={title} isDraft={isDraft} />
|
|
43
40
|
<Typography ellipsis>{mainField ?? id}</Typography>
|
|
44
41
|
</Flex>
|
|
45
|
-
</
|
|
42
|
+
</ComboboxOption>
|
|
46
43
|
);
|
|
47
44
|
}
|
|
48
45
|
|
|
49
|
-
return
|
|
46
|
+
return (
|
|
47
|
+
<ComboboxOption value={id} textValue={mainField ?? id}>
|
|
48
|
+
{mainField ?? id}
|
|
49
|
+
</ComboboxOption>
|
|
50
|
+
);
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
Option.defaultProps = {
|
|
54
|
+
mainField: undefined,
|
|
55
|
+
publicationState: undefined,
|
|
50
56
|
};
|
|
51
57
|
|
|
52
58
|
Option.propTypes = {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
isDraft: PropTypes.bool,
|
|
57
|
-
mainField: PropTypes.string,
|
|
58
|
-
publicationState: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]),
|
|
59
|
-
}).isRequired,
|
|
59
|
+
id: PropTypes.number.isRequired,
|
|
60
|
+
mainField: PropTypes.string,
|
|
61
|
+
publicationState: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]),
|
|
60
62
|
};
|
|
@@ -33,6 +33,7 @@ import {
|
|
|
33
33
|
} from '@strapi/helper-plugin';
|
|
34
34
|
import { ArrowLeft, Cog, Plus } from '@strapi/icons';
|
|
35
35
|
import axios from 'axios';
|
|
36
|
+
import getReviewWorkflowsColumn from 'ee_else_ce/content-manager/components/DynamicTable/CellContent/ReviewWorkflowsStage/getTableColumn';
|
|
36
37
|
import isEqual from 'lodash/isEqual';
|
|
37
38
|
import PropTypes from 'prop-types';
|
|
38
39
|
import { stringify } from 'qs';
|
|
@@ -391,6 +392,17 @@ function ListView({
|
|
|
391
392
|
return formattedHeaders;
|
|
392
393
|
}
|
|
393
394
|
|
|
395
|
+
// this should not exist. Ideally we would use registerHook() similar to what has been done
|
|
396
|
+
// in the i18n plugin. In order to do that review-workflows should have been a plugin. In
|
|
397
|
+
// a future iteration we need to find a better pattern.
|
|
398
|
+
|
|
399
|
+
// In CE this will return null - in EE a column definition including the custom formatting component.
|
|
400
|
+
const reviewWorkflowColumn = getReviewWorkflowsColumn(layout);
|
|
401
|
+
|
|
402
|
+
if (reviewWorkflowColumn) {
|
|
403
|
+
formattedHeaders.push(reviewWorkflowColumn);
|
|
404
|
+
}
|
|
405
|
+
|
|
394
406
|
return [
|
|
395
407
|
...formattedHeaders,
|
|
396
408
|
{
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
useTracking,
|
|
11
11
|
} from '@strapi/helper-plugin';
|
|
12
12
|
import PropTypes from 'prop-types';
|
|
13
|
+
import { useIntl } from 'react-intl';
|
|
13
14
|
import { useHistory } from 'react-router-dom';
|
|
14
15
|
|
|
15
16
|
import DeleteButton from './DeleteButton';
|
|
@@ -28,6 +29,7 @@ const Table = ({
|
|
|
28
29
|
const { canDelete, canUpdate, canRead } = permissions;
|
|
29
30
|
const withBulkActions = canDelete || canUpdate || canRead;
|
|
30
31
|
const [{ query }] = useQueryParams();
|
|
32
|
+
const { formatMessage } = useIntl();
|
|
31
33
|
const [, sortOrder] = query ? query.sort.split(':') : 'ASC';
|
|
32
34
|
const {
|
|
33
35
|
push,
|
|
@@ -83,7 +85,19 @@ const Table = ({
|
|
|
83
85
|
<Td>
|
|
84
86
|
{token.lastUsedAt && (
|
|
85
87
|
<Typography textColor="neutral800">
|
|
86
|
-
<RelativeTime
|
|
88
|
+
<RelativeTime
|
|
89
|
+
timestamp={new Date(token.lastUsedAt)}
|
|
90
|
+
customIntervals={[
|
|
91
|
+
{
|
|
92
|
+
unit: 'hours',
|
|
93
|
+
threshold: 1,
|
|
94
|
+
text: formatMessage({
|
|
95
|
+
id: 'Settings.apiTokens.lastHour',
|
|
96
|
+
defaultMessage: 'last hour',
|
|
97
|
+
}),
|
|
98
|
+
},
|
|
99
|
+
]}
|
|
100
|
+
/>
|
|
87
101
|
</Typography>
|
|
88
102
|
)}
|
|
89
103
|
</Td>
|
|
@@ -10,19 +10,13 @@ import EditPage from '../EditPage';
|
|
|
10
10
|
const ProtectedEditPage = () => {
|
|
11
11
|
const permissions = useSelector(selectAdminPermissions);
|
|
12
12
|
|
|
13
|
-
// TODO: this is necessary because otherwise we run into an
|
|
14
|
-
// infinite rendering loop
|
|
15
|
-
const permissionsMemoized = React.useMemo(() => {
|
|
16
|
-
return {
|
|
17
|
-
read: permissions.settings.roles.read,
|
|
18
|
-
update: permissions.settings.roles.update,
|
|
19
|
-
};
|
|
20
|
-
}, [permissions.settings.roles.read, permissions.settings.roles.update]);
|
|
21
|
-
|
|
22
13
|
const {
|
|
23
14
|
isLoading,
|
|
24
15
|
allowedActions: { canRead, canUpdate },
|
|
25
|
-
} = useRBAC(
|
|
16
|
+
} = useRBAC({
|
|
17
|
+
read: permissions.settings.roles.read,
|
|
18
|
+
update: permissions.settings.roles.update,
|
|
19
|
+
});
|
|
26
20
|
|
|
27
21
|
if (isLoading) {
|
|
28
22
|
return <LoadingIndicatorPage />;
|
|
@@ -183,13 +183,13 @@ const EditPage = ({ canUpdate }) => {
|
|
|
183
183
|
validateOnChange={false}
|
|
184
184
|
validationSchema={editValidation}
|
|
185
185
|
>
|
|
186
|
-
{({ errors, values, handleChange, isSubmitting }) => {
|
|
186
|
+
{({ errors, values, handleChange, isSubmitting, dirty }) => {
|
|
187
187
|
return (
|
|
188
188
|
<Form>
|
|
189
189
|
<HeaderLayout
|
|
190
190
|
primaryAction={
|
|
191
191
|
<Button
|
|
192
|
-
disabled={isSubmitting || !canUpdate}
|
|
192
|
+
disabled={(isSubmitting || !canUpdate) ? true : !dirty}
|
|
193
193
|
startIcon={<Check />}
|
|
194
194
|
loading={isSubmitting}
|
|
195
195
|
type="submit"
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { translatedErrors } from '@strapi/helper-plugin';
|
|
2
1
|
import * as yup from 'yup';
|
|
3
2
|
|
|
4
3
|
const NAME_REGEX = /(^$)|(^[A-Za-z][_0-9A-Za-z ]*$)/;
|
|
@@ -10,11 +9,18 @@ export const makeWebhookValidationSchema = ({ formatMessage }) =>
|
|
|
10
9
|
.string()
|
|
11
10
|
.required(
|
|
12
11
|
formatMessage({
|
|
13
|
-
id: 'Settings.webhooks.validation.name',
|
|
12
|
+
id: 'Settings.webhooks.validation.name.required',
|
|
14
13
|
defaultMessage: 'Name is required',
|
|
15
14
|
})
|
|
16
15
|
)
|
|
17
|
-
.matches(
|
|
16
|
+
.matches(
|
|
17
|
+
NAME_REGEX,
|
|
18
|
+
formatMessage({
|
|
19
|
+
id: 'Settings.webhooks.validation.name.regex',
|
|
20
|
+
defaultMessage:
|
|
21
|
+
'The name must start with a letter and only contain letters, numbers, spaces and underscores',
|
|
22
|
+
})
|
|
23
|
+
),
|
|
18
24
|
url: yup
|
|
19
25
|
.string()
|
|
20
26
|
.required(
|
|
@@ -26,8 +32,8 @@ export const makeWebhookValidationSchema = ({ formatMessage }) =>
|
|
|
26
32
|
.matches(
|
|
27
33
|
URL_REGEX,
|
|
28
34
|
formatMessage({
|
|
29
|
-
id:
|
|
30
|
-
defaultMessage: 'The value
|
|
35
|
+
id: 'Settings.webhooks.validation.url.regex',
|
|
36
|
+
defaultMessage: 'The value must be a valid Url',
|
|
31
37
|
})
|
|
32
38
|
),
|
|
33
39
|
headers: yup.lazy((array) => {
|
|
@@ -88,6 +88,7 @@
|
|
|
88
88
|
"Settings.apiTokens.emptyStateLayout": "Encara no tens cap contingut...",
|
|
89
89
|
"Settings.tokens.notification.copied": "Token copiat al porta-retalls.",
|
|
90
90
|
"Settings.apiTokens.title": "Tokens d'API",
|
|
91
|
+
"Settings.apiTokens.lastHour": "darrera hora",
|
|
91
92
|
"Settings.tokens.types.full-access": "Accés complet",
|
|
92
93
|
"Settings.tokens.types.read-only": "Només lectura",
|
|
93
94
|
"Settings.application.Strapi-version": "versió de Strapi",
|
|
@@ -97,6 +97,7 @@
|
|
|
97
97
|
"Settings.apiTokens.emptyStateLayout": "You don’t have any content yet...",
|
|
98
98
|
"Settings.apiTokens.regenerate": "Regenerate",
|
|
99
99
|
"Settings.apiTokens.title": "API Tokens",
|
|
100
|
+
"Settings.apiTokens.lastHour": "last hour",
|
|
100
101
|
"Settings.application.customization": "Customization",
|
|
101
102
|
"Settings.application.customization.auth-logo.carousel-hint": "Replace the logo in the authentication pages",
|
|
102
103
|
"Settings.application.customization.carousel-hint": "Change the admin panel logo (Max dimension: {dimension}x{dimension}, Max file size: {size}KB)",
|
|
@@ -318,8 +319,10 @@
|
|
|
318
319
|
"Settings.webhooks.trigger.test": "Test-trigger",
|
|
319
320
|
"Settings.webhooks.trigger.title": "Save before Trigger",
|
|
320
321
|
"Settings.webhooks.value": "Value",
|
|
321
|
-
"Settings.webhooks.validation.name": "Name is required",
|
|
322
|
+
"Settings.webhooks.validation.name.required": "Name is required",
|
|
323
|
+
"Settings.webhooks.validation.name.regex": "The name must start with a letter and only contain letters, numbers, spaces and underscores",
|
|
322
324
|
"Settings.webhooks.validation.url.required": "Url is required",
|
|
325
|
+
"Settings.webhooks.validation.url.regex": "The value must be a valid Url",
|
|
323
326
|
"Settings.webhooks.validation.key": "Key is required",
|
|
324
327
|
"Settings.webhooks.validation.value": "Value is required",
|
|
325
328
|
"Usecase.back-end": "Back-end developer",
|
|
@@ -86,6 +86,11 @@
|
|
|
86
86
|
"Settings.apiTokens.emptyStateLayout": "Aún no tienes ningún contenido ...",
|
|
87
87
|
"Settings.tokens.notification.copied": "Token copiado al portapapeles.",
|
|
88
88
|
"Settings.apiTokens.title": "Tokens de API",
|
|
89
|
+
"Settings.apiTokens.lastHour": "última hora",
|
|
90
|
+
"Settings.tokens.ListView.headers.createdAt": "Creado en",
|
|
91
|
+
"Settings.tokens.ListView.headers.description": "Descripción",
|
|
92
|
+
"Settings.tokens.ListView.headers.lastUsedAt": "Último uso",
|
|
93
|
+
"Settings.tokens.ListView.headers.name": "Nombre",
|
|
89
94
|
"Settings.tokens.types.full-access": "Acceso completo",
|
|
90
95
|
"Settings.tokens.types.read-only": "Solo lectura",
|
|
91
96
|
"Settings.application.description": "Información global del panel de administración",
|
|
@@ -100,6 +100,7 @@
|
|
|
100
100
|
"Settings.apiTokens.createPage.BoundRoute.title": "Route rattachée à",
|
|
101
101
|
"Settings.apiTokens.createPage.permissions.header.title": "Paramètres avancés",
|
|
102
102
|
"Settings.apiTokens.createPage.permissions.header.hint": "Sélectionner les actions de l'application ou du plugin et sur l'icône de la roue crantée pour afficher la route rattachée",
|
|
103
|
+
"Settings.apiTokens.lastHour": "dernière heure",
|
|
103
104
|
"Settings.tokens.duration.30-days": "30 jours",
|
|
104
105
|
"Settings.tokens.duration.7-days": "7 jours",
|
|
105
106
|
"Settings.tokens.duration.90-days": "90 jours",
|
|
@@ -15,7 +15,7 @@ Try polyfilling it using "@formatjs/intl-listformat"
|
|
|
15
15
|
Try polyfilling it using "@formatjs/intl-displaynames"
|
|
16
16
|
`,Y.jK.MISSING_INTL_API));var L=(0,S.L6)(s,Te);try{return g(d,L).of(l)}catch(W){p(new C.Qe("Error formatting display name.",d,W))}}function ge(u){var g=u?u[Object.keys(u)[0]]:void 0;return typeof g=="string"}function re(u){u.onWarn&&u.defaultRichTextElements&&ge(u.messages||{})&&u.onWarn(`[@formatjs/intl] "defaultRichTextElements" was specified but "message" was not pre-compiled.
|
|
17
17
|
Please consider using "@formatjs/cli" to pre-compile your messages for performance.
|
|
18
|
-
For more details see https://formatjs.io/docs/getting-started/message-distribution`)}function q(u,g){var l=(0,S.ax)(g),s=(0,v.pi)((0,v.pi)({},S.Z0),u),d=s.locale,p=s.defaultLocale,w=s.onError;return d?!Intl.NumberFormat.supportedLocalesOf(d).length&&w?w(new C.gb('Missing locale data for locale: "'.concat(d,'" in Intl.NumberFormat. Using default locale: "').concat(p,'" as fallback. See https://formatjs.io/docs/react-intl#runtime-requirements for more details'))):!Intl.DateTimeFormat.supportedLocalesOf(d).length&&w&&w(new C.gb('Missing locale data for locale: "'.concat(d,'" in Intl.DateTimeFormat. Using default locale: "').concat(p,'" as fallback. See https://formatjs.io/docs/react-intl#runtime-requirements for more details'))):(w&&w(new C.OV('"locale" was not configured, using "'.concat(p,'" as fallback. See https://formatjs.io/docs/react-intl/api#intlshape for more details'))),s.locale=s.defaultLocale||"en"),re(s),(0,v.pi)((0,v.pi)({},s),{formatters:l,formatNumber:N.bind(null,s,l.getNumberFormat),formatNumberToParts:_.bind(null,s,l.getNumberFormat),formatRelativeTime:ce.bind(null,s,l.getRelativeTimeFormat),formatDate:Ne.bind(null,s,l.getDateTimeFormat),formatDateToParts:Be.bind(null,s,l.getDateTimeFormat),formatTime:Ye.bind(null,s,l.getDateTimeFormat),formatDateTimeRange:Me.bind(null,s,l.getDateTimeFormat),formatTimeToParts:He.bind(null,s,l.getDateTimeFormat),formatPlural:ze.bind(null,s,l.getPluralRules),formatMessage:J.bind(null,s,l),$t:J.bind(null,s,l),formatList:Ze.bind(null,s,l.getListFormat),formatListToParts:de.bind(null,s,l.getListFormat),formatDisplayName:Re.bind(null,s,l.getDisplayNames)})}var se=y(33961);function H(u){return{locale:u.locale,timeZone:u.timeZone,fallbackOnEmptyString:u.fallbackOnEmptyString,formats:u.formats,textComponent:u.textComponent,messages:u.messages,defaultLocale:u.defaultLocale,defaultFormats:u.defaultFormats,onError:u.onError,onWarn:u.onWarn,wrapRichTextChunksInFragment:u.wrapRichTextChunksInFragment,defaultRichTextElements:u.defaultRichTextElements}}function V(u){return u&&Object.keys(u).reduce(function(g,l){var s=u[l];return g[l]=(0,se.Gt)(s)?(0,E.dt)(s):s,g},{})}var Fe=function(u,g,l,s){for(var d=[],p=4;p<arguments.length;p++)d[p-4]=arguments[p];var w=V(s),L=J.apply(void 0,(0,v.ev)([u,g,l,w],d,!1));return Array.isArray(L)?R.Children.toArray(L):L},je=function(u,g){var l=u.defaultRichTextElements,s=(0,v._T)(u,["defaultRichTextElements"]),d=V(l),p=q((0,v.pi)((0,v.pi)((0,v.pi)({},E.Z0),s),{defaultRichTextElements:d}),g),w={locale:p.locale,timeZone:p.timeZone,fallbackOnEmptyString:p.fallbackOnEmptyString,formats:p.formats,defaultLocale:p.defaultLocale,defaultFormats:p.defaultFormats,messages:p.messages,onError:p.onError,defaultRichTextElements:d};return(0,v.pi)((0,v.pi)({},p),{formatMessage:Fe.bind(null,w,p.formatters),$t:Fe.bind(null,w,p.formatters)})},We=function(u){(0,v.ZT)(g,u);function g(){var l=u!==null&&u.apply(this,arguments)||this;return l.cache=(0,S.Sn)(),l.state={cache:l.cache,intl:je(H(l.props),l.cache),prevConfig:H(l.props)},l}return g.getDerivedStateFromProps=function(l,s){var d=s.prevConfig,p=s.cache,w=H(l);return(0,E.wU)(d,w)?null:{intl:je(w,p),prevConfig:w}},g.prototype.render=function(){return(0,E.lq)(this.state.intl),R.createElement(Z.zt,{value:this.state.intl},this.props.children)},g.displayName="IntlProvider",g.defaultProps=E.Z0,g}(R.PureComponent),Ve=We},17e3:function(B,X,y){"use strict";y.d(X,{D:function(){return Z}});var v=y(74512),R=y(72850);const Z=({children:E})=>(0,v.jsx)(R.x,{paddingLeft:10,paddingRight:10,children:E})},82055:function(B,X,y){"use strict";y.d(X,{T:function(){return he}});var v=y(74512),R=y(32735),Z=y(8471);const E=S=>{const D=(0,R.useRef)(null),[z,N]=(0,R.useState)(!0),_=([Y])=>{N(Y.isIntersecting)};return(0,R.useEffect)(()=>{const Y=D.current,le=new IntersectionObserver(_,S);return Y&&le.observe(D.current),()=>{Y&&le.disconnect()}},[D,S]),[D,z]};var k=y(
|
|
18
|
+
For more details see https://formatjs.io/docs/getting-started/message-distribution`)}function q(u,g){var l=(0,S.ax)(g),s=(0,v.pi)((0,v.pi)({},S.Z0),u),d=s.locale,p=s.defaultLocale,w=s.onError;return d?!Intl.NumberFormat.supportedLocalesOf(d).length&&w?w(new C.gb('Missing locale data for locale: "'.concat(d,'" in Intl.NumberFormat. Using default locale: "').concat(p,'" as fallback. See https://formatjs.io/docs/react-intl#runtime-requirements for more details'))):!Intl.DateTimeFormat.supportedLocalesOf(d).length&&w&&w(new C.gb('Missing locale data for locale: "'.concat(d,'" in Intl.DateTimeFormat. Using default locale: "').concat(p,'" as fallback. See https://formatjs.io/docs/react-intl#runtime-requirements for more details'))):(w&&w(new C.OV('"locale" was not configured, using "'.concat(p,'" as fallback. See https://formatjs.io/docs/react-intl/api#intlshape for more details'))),s.locale=s.defaultLocale||"en"),re(s),(0,v.pi)((0,v.pi)({},s),{formatters:l,formatNumber:N.bind(null,s,l.getNumberFormat),formatNumberToParts:_.bind(null,s,l.getNumberFormat),formatRelativeTime:ce.bind(null,s,l.getRelativeTimeFormat),formatDate:Ne.bind(null,s,l.getDateTimeFormat),formatDateToParts:Be.bind(null,s,l.getDateTimeFormat),formatTime:Ye.bind(null,s,l.getDateTimeFormat),formatDateTimeRange:Me.bind(null,s,l.getDateTimeFormat),formatTimeToParts:He.bind(null,s,l.getDateTimeFormat),formatPlural:ze.bind(null,s,l.getPluralRules),formatMessage:J.bind(null,s,l),$t:J.bind(null,s,l),formatList:Ze.bind(null,s,l.getListFormat),formatListToParts:de.bind(null,s,l.getListFormat),formatDisplayName:Re.bind(null,s,l.getDisplayNames)})}var se=y(33961);function H(u){return{locale:u.locale,timeZone:u.timeZone,fallbackOnEmptyString:u.fallbackOnEmptyString,formats:u.formats,textComponent:u.textComponent,messages:u.messages,defaultLocale:u.defaultLocale,defaultFormats:u.defaultFormats,onError:u.onError,onWarn:u.onWarn,wrapRichTextChunksInFragment:u.wrapRichTextChunksInFragment,defaultRichTextElements:u.defaultRichTextElements}}function V(u){return u&&Object.keys(u).reduce(function(g,l){var s=u[l];return g[l]=(0,se.Gt)(s)?(0,E.dt)(s):s,g},{})}var Fe=function(u,g,l,s){for(var d=[],p=4;p<arguments.length;p++)d[p-4]=arguments[p];var w=V(s),L=J.apply(void 0,(0,v.ev)([u,g,l,w],d,!1));return Array.isArray(L)?R.Children.toArray(L):L},je=function(u,g){var l=u.defaultRichTextElements,s=(0,v._T)(u,["defaultRichTextElements"]),d=V(l),p=q((0,v.pi)((0,v.pi)((0,v.pi)({},E.Z0),s),{defaultRichTextElements:d}),g),w={locale:p.locale,timeZone:p.timeZone,fallbackOnEmptyString:p.fallbackOnEmptyString,formats:p.formats,defaultLocale:p.defaultLocale,defaultFormats:p.defaultFormats,messages:p.messages,onError:p.onError,defaultRichTextElements:d};return(0,v.pi)((0,v.pi)({},p),{formatMessage:Fe.bind(null,w,p.formatters),$t:Fe.bind(null,w,p.formatters)})},We=function(u){(0,v.ZT)(g,u);function g(){var l=u!==null&&u.apply(this,arguments)||this;return l.cache=(0,S.Sn)(),l.state={cache:l.cache,intl:je(H(l.props),l.cache),prevConfig:H(l.props)},l}return g.getDerivedStateFromProps=function(l,s){var d=s.prevConfig,p=s.cache,w=H(l);return(0,E.wU)(d,w)?null:{intl:je(w,p),prevConfig:w}},g.prototype.render=function(){return(0,E.lq)(this.state.intl),R.createElement(Z.zt,{value:this.state.intl},this.props.children)},g.displayName="IntlProvider",g.defaultProps=E.Z0,g}(R.PureComponent),Ve=We},17e3:function(B,X,y){"use strict";y.d(X,{D:function(){return Z}});var v=y(74512),R=y(72850);const Z=({children:E})=>(0,v.jsx)(R.x,{paddingLeft:10,paddingRight:10,children:E})},82055:function(B,X,y){"use strict";y.d(X,{T:function(){return he}});var v=y(74512),R=y(32735),Z=y(8471);const E=S=>{const D=(0,R.useRef)(null),[z,N]=(0,R.useState)(!0),_=([Y])=>{N(Y.isIntersecting)};return(0,R.useEffect)(()=>{const Y=D.current,le=new IntersectionObserver(_,S);return Y&&le.observe(D.current),()=>{Y&&le.disconnect()}},[D,S]),[D,z]};var k=y(2285);const G=(S,D)=>{const z=(0,k.W)(D);(0,R.useLayoutEffect)(()=>{const N=new ResizeObserver(z);return Array.isArray(S)?S.forEach(_=>{_.current&&N.observe(_.current)}):S.current&&N.observe(S.current),()=>{N.disconnect()}},[S,z])};var C=y(72850),oe=y(87933),$=y(49372);const he=S=>{const D=(0,R.useRef)(null),[z,N]=(0,R.useState)(null),[_,Y]=E({root:null,rootMargin:"0px",threshold:0});return G(_,()=>{_.current&&N(_.current.getBoundingClientRect())}),(0,R.useEffect)(()=>{D.current&&N(D.current.getBoundingClientRect())},[D]),(0,v.jsxs)(v.Fragment,{children:[(0,v.jsx)("div",{style:{height:z?.height},ref:_,children:Y&&(0,v.jsx)(J,{ref:D,...S})}),!Y&&(0,v.jsx)(J,{...S,sticky:!0,width:z?.width})]})};he.displayName="HeaderLayout";const xe=(0,Z.ZP)(C.x)`
|
|
19
19
|
width: ${({width:S})=>S?`${S/16}rem`:void 0};
|
|
20
20
|
z-index: ${({theme:S})=>S.zIndices[1]};
|
|
21
21
|
`,J=R.forwardRef(({navigationAction:S,primaryAction:D,secondaryAction:z,subtitle:N,title:_,sticky:Y,width:le,...fe},ce)=>{const pe=typeof N=="string";return Y?(0,v.jsx)(xe,{paddingLeft:6,paddingRight:6,paddingTop:3,paddingBottom:3,position:"fixed",top:0,right:0,background:"neutral0",shadow:"tableShadow",width:le,"data-strapi-header-sticky":!0,children:(0,v.jsxs)(oe.k,{justifyContent:"space-between",children:[(0,v.jsxs)(oe.k,{children:[S&&(0,v.jsx)(C.x,{paddingRight:3,children:S}),(0,v.jsxs)(C.x,{children:[(0,v.jsx)($.Z,{variant:"beta",as:"h1",...fe,children:_}),pe?(0,v.jsx)($.Z,{variant:"pi",textColor:"neutral600",children:N}):N]}),z?(0,v.jsx)(C.x,{paddingLeft:4,children:z}):null]}),(0,v.jsx)(oe.k,{children:D?(0,v.jsx)(C.x,{paddingLeft:2,children:D}):void 0})]})}):(0,v.jsxs)(C.x,{ref:ce,paddingLeft:10,paddingRight:10,paddingBottom:8,paddingTop:S?6:8,background:"neutral100","data-strapi-header":!0,children:[S?(0,v.jsx)(C.x,{paddingBottom:2,children:S}):null,(0,v.jsxs)(oe.k,{justifyContent:"space-between",children:[(0,v.jsxs)(oe.k,{minWidth:0,children:[(0,v.jsx)($.Z,{as:"h1",variant:"alpha",...fe,children:_}),z?(0,v.jsx)(C.x,{paddingLeft:4,children:z}):null]}),D]}),pe?(0,v.jsx)($.Z,{variant:"epsilon",textColor:"neutral600",as:"p",children:N}):N]})})},27649:function(B,X,y){"use strict";y.d(X,{o:function(){return k}});var v=y(74512),R=y(8471),Z=y(72850);const E=(0,R.ZP)(Z.x)`
|