@strapi/admin 4.12.0-beta.5 → 4.12.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.
- package/admin/src/content-manager/pages/ListView/components/BulkActionButtons/ConfirmBulkActionDialog/index.js +2 -0
- package/admin/src/content-manager/pages/ListView/components/BulkActionButtons/SelectedEntriesModal/index.js +83 -36
- package/admin/src/pages/AuthPage/components/Register/index.js +0 -4
- package/admin/src/pages/SettingsPage/pages/Webhooks/EditView/components/Events/index.js +1 -1
- package/admin/src/translations/en.json +1 -0
- package/build/{Admin-authenticatedApp.6b8dfa45.chunk.js → Admin-authenticatedApp.376233ff.chunk.js} +1 -1
- package/build/{admin-app.c2e4e128.chunk.js → admin-app.1c3f7fd6.chunk.js} +8 -8
- package/build/{content-manager.8772445b.chunk.js → content-manager.e9205db1.chunk.js} +95 -95
- package/build/{en-json.4c733bd1.chunk.js → en-json.e34140fc.chunk.js} +1 -1
- package/build/index.html +1 -1
- package/build/{main.af84ad9c.js → main.1e3b0985.js} +1 -1
- package/build/{review-workflows-settings-list-view.3ee9190d.chunk.js → review-workflows-settings-list-view.f055e1be.chunk.js} +8 -8
- package/build/{runtime~main.a65ca6fb.js → runtime~main.58ec8df6.js} +1 -1
- package/build/{webhook-edit-page.a91f27a1.chunk.js → webhook-edit-page.6cb479ff.chunk.js} +2 -2
- package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/pages/ListView/ListView.js +1 -2
- package/ee/server/bootstrap.js +2 -0
- package/ee/server/services/auth.js +1 -1
- package/ee/server/services/index.js +1 -0
- package/ee/server/services/review-workflows/metrics/index.js +51 -0
- package/ee/server/services/review-workflows/metrics/weekly-metrics.js +76 -0
- package/ee/server/services/review-workflows/workflows/index.js +5 -0
- package/package.json +8 -8
- package/ee/server/services/review-workflows/metrics.js +0 -24
|
@@ -104,6 +104,8 @@ const ConfirmDialogPublishAll = ({ isOpen, onToggleDialog, isConfirmButtonLoadin
|
|
|
104
104
|
return data;
|
|
105
105
|
},
|
|
106
106
|
{
|
|
107
|
+
// The API is called everytime you select/deselect an entry, this check avoids us sending a query with bad data
|
|
108
|
+
enabled: selectedEntries.length > 0,
|
|
107
109
|
onError(error) {
|
|
108
110
|
toggleNotification({ type: 'warning', message: formatAPIError(error) });
|
|
109
111
|
},
|
|
@@ -46,11 +46,11 @@ const TypographyMaxWidth = styled(Typography)`
|
|
|
46
46
|
* EntryValidationText
|
|
47
47
|
* -----------------------------------------------------------------------------------------------*/
|
|
48
48
|
|
|
49
|
-
const EntryValidationText = ({
|
|
49
|
+
const EntryValidationText = ({ validationErrors, isPublished }) => {
|
|
50
50
|
const { formatMessage } = useIntl();
|
|
51
51
|
|
|
52
|
-
if (
|
|
53
|
-
const
|
|
52
|
+
if (validationErrors) {
|
|
53
|
+
const validationErrorsMessages = Object.entries(validationErrors)
|
|
54
54
|
.map(([key, value]) =>
|
|
55
55
|
formatMessage(
|
|
56
56
|
{ id: `${value.id}.withField`, defaultMessage: value.defaultMessage },
|
|
@@ -62,9 +62,9 @@ const EntryValidationText = ({ errors, isPublished }) => {
|
|
|
62
62
|
return (
|
|
63
63
|
<Flex gap={2}>
|
|
64
64
|
<Icon color="danger600" as={CrossCircle} />
|
|
65
|
-
<Tooltip description={
|
|
65
|
+
<Tooltip description={validationErrorsMessages}>
|
|
66
66
|
<TypographyMaxWidth textColor="danger600" variant="omega" fontWeight="semiBold" ellipsis>
|
|
67
|
-
{
|
|
67
|
+
{validationErrorsMessages}
|
|
68
68
|
</TypographyMaxWidth>
|
|
69
69
|
</Tooltip>
|
|
70
70
|
</Flex>
|
|
@@ -77,8 +77,8 @@ const EntryValidationText = ({ errors, isPublished }) => {
|
|
|
77
77
|
<Icon color="success600" as={CheckCircle} />
|
|
78
78
|
<Typography textColor="success600" fontWeight="bold">
|
|
79
79
|
{formatMessage({
|
|
80
|
-
id: '
|
|
81
|
-
defaultMessage: 'Published',
|
|
80
|
+
id: 'content-manager.bulk-publish.already-published',
|
|
81
|
+
defaultMessage: 'Already Published',
|
|
82
82
|
})}
|
|
83
83
|
</Typography>
|
|
84
84
|
</Flex>
|
|
@@ -99,12 +99,12 @@ const EntryValidationText = ({ errors, isPublished }) => {
|
|
|
99
99
|
};
|
|
100
100
|
|
|
101
101
|
EntryValidationText.defaultProps = {
|
|
102
|
-
|
|
102
|
+
validationErrors: undefined,
|
|
103
103
|
isPublished: false,
|
|
104
104
|
};
|
|
105
105
|
|
|
106
106
|
EntryValidationText.propTypes = {
|
|
107
|
-
|
|
107
|
+
validationErrors: PropTypes.shape({
|
|
108
108
|
[PropTypes.string]: PropTypes.shape({
|
|
109
109
|
id: PropTypes.string,
|
|
110
110
|
defaultMessage: PropTypes.string,
|
|
@@ -117,7 +117,12 @@ EntryValidationText.propTypes = {
|
|
|
117
117
|
* SelectedEntriesTableContent
|
|
118
118
|
* -----------------------------------------------------------------------------------------------*/
|
|
119
119
|
|
|
120
|
-
const SelectedEntriesTableContent = ({
|
|
120
|
+
const SelectedEntriesTableContent = ({
|
|
121
|
+
isPublishing,
|
|
122
|
+
rowsToDisplay,
|
|
123
|
+
entriesToPublish,
|
|
124
|
+
validationErrors,
|
|
125
|
+
}) => {
|
|
121
126
|
const {
|
|
122
127
|
location: { pathname },
|
|
123
128
|
} = useHistory();
|
|
@@ -149,19 +154,19 @@ const SelectedEntriesTableContent = ({ isPublishing, rowsToDisplay, entriesToPub
|
|
|
149
154
|
</Table.Head>
|
|
150
155
|
<Table.LoadingBody />
|
|
151
156
|
<Table.Body>
|
|
152
|
-
{rowsToDisplay.map((
|
|
153
|
-
<Tr key={
|
|
154
|
-
<Body.CheckboxDataCell rowId={
|
|
157
|
+
{rowsToDisplay.map((row, index) => (
|
|
158
|
+
<Tr key={row.id}>
|
|
159
|
+
<Body.CheckboxDataCell rowId={row.id} index={index} />
|
|
155
160
|
<Td>
|
|
156
|
-
<Typography>{
|
|
161
|
+
<Typography>{row.id}</Typography>
|
|
157
162
|
</Td>
|
|
158
163
|
{shouldDisplayMainField && (
|
|
159
164
|
<Td>
|
|
160
|
-
<Typography>{
|
|
165
|
+
<Typography>{row[mainField]}</Typography>
|
|
161
166
|
</Td>
|
|
162
167
|
)}
|
|
163
168
|
<Td>
|
|
164
|
-
{isPublishing && entriesToPublish.includes(
|
|
169
|
+
{isPublishing && entriesToPublish.includes(row.id) ? (
|
|
165
170
|
<Flex gap={2}>
|
|
166
171
|
<Typography>
|
|
167
172
|
{formatMessage({
|
|
@@ -172,14 +177,17 @@ const SelectedEntriesTableContent = ({ isPublishing, rowsToDisplay, entriesToPub
|
|
|
172
177
|
<Loader small />
|
|
173
178
|
</Flex>
|
|
174
179
|
) : (
|
|
175
|
-
<EntryValidationText
|
|
180
|
+
<EntryValidationText
|
|
181
|
+
validationErrors={validationErrors[row.id]}
|
|
182
|
+
isPublished={row.publishedAt !== null}
|
|
183
|
+
/>
|
|
176
184
|
)}
|
|
177
185
|
</Td>
|
|
178
186
|
<Td>
|
|
179
187
|
<IconButton
|
|
180
188
|
forwardedAs={Link}
|
|
181
189
|
to={{
|
|
182
|
-
pathname: `${pathname}/${
|
|
190
|
+
pathname: `${pathname}/${row.id}`,
|
|
183
191
|
state: { from: pathname },
|
|
184
192
|
}}
|
|
185
193
|
label={formatMessage(
|
|
@@ -188,6 +196,7 @@ const SelectedEntriesTableContent = ({ isPublishing, rowsToDisplay, entriesToPub
|
|
|
188
196
|
)}
|
|
189
197
|
noBorder
|
|
190
198
|
target="_blank"
|
|
199
|
+
marginLeft="auto"
|
|
191
200
|
>
|
|
192
201
|
<Pencil />
|
|
193
202
|
</IconButton>
|
|
@@ -203,12 +212,19 @@ SelectedEntriesTableContent.defaultProps = {
|
|
|
203
212
|
isPublishing: false,
|
|
204
213
|
rowsToDisplay: [],
|
|
205
214
|
entriesToPublish: [],
|
|
215
|
+
validationErrors: {},
|
|
206
216
|
};
|
|
207
217
|
|
|
208
218
|
SelectedEntriesTableContent.propTypes = {
|
|
209
219
|
isPublishing: PropTypes.bool,
|
|
210
220
|
rowsToDisplay: PropTypes.arrayOf(PropTypes.object),
|
|
211
221
|
entriesToPublish: PropTypes.arrayOf(PropTypes.number),
|
|
222
|
+
validationErrors: PropTypes.shape({
|
|
223
|
+
[PropTypes.string]: PropTypes.shape({
|
|
224
|
+
id: PropTypes.string,
|
|
225
|
+
defaultMessage: PropTypes.string,
|
|
226
|
+
}),
|
|
227
|
+
}),
|
|
212
228
|
};
|
|
213
229
|
|
|
214
230
|
/* -------------------------------------------------------------------------------------------------
|
|
@@ -221,7 +237,13 @@ const BoldChunk = (chunks) => <Typography fontWeight="bold">{chunks}</Typography
|
|
|
221
237
|
* SelectedEntriesModalContent
|
|
222
238
|
* -----------------------------------------------------------------------------------------------*/
|
|
223
239
|
|
|
224
|
-
const SelectedEntriesModalContent = ({
|
|
240
|
+
const SelectedEntriesModalContent = ({
|
|
241
|
+
toggleModal,
|
|
242
|
+
refetchModalData,
|
|
243
|
+
setEntriesToFetch,
|
|
244
|
+
setSelectedListViewEntries,
|
|
245
|
+
validationErrors,
|
|
246
|
+
}) => {
|
|
225
247
|
const { formatMessage } = useIntl();
|
|
226
248
|
const { selectedEntries, rows, onSelectRow, isLoading, isFetching } = useTableContext();
|
|
227
249
|
const [isDialogOpen, setIsDialogOpen] = React.useState(false);
|
|
@@ -229,15 +251,15 @@ const SelectedEntriesModalContent = ({ toggleModal, refetchModalData, setEntries
|
|
|
229
251
|
const [publishedCount, setPublishedCount] = React.useState(0);
|
|
230
252
|
|
|
231
253
|
const entriesToPublish = rows
|
|
232
|
-
.filter(({
|
|
233
|
-
.map(({
|
|
254
|
+
.filter(({ id }) => selectedEntries.includes(id) && !validationErrors[id])
|
|
255
|
+
.map(({ id }) => id);
|
|
234
256
|
|
|
235
257
|
const { post } = useFetchClient();
|
|
236
258
|
const toggleNotification = useNotification();
|
|
237
259
|
const { contentType } = useSelector(listViewDomain());
|
|
238
260
|
|
|
239
261
|
const selectedEntriesWithErrorsCount = rowsToDisplay.filter(
|
|
240
|
-
({
|
|
262
|
+
({ id }) => selectedEntries.includes(id) && validationErrors[id]
|
|
241
263
|
).length;
|
|
242
264
|
const selectedEntriesWithNoErrorsCount = selectedEntries.length - selectedEntriesWithErrorsCount;
|
|
243
265
|
|
|
@@ -247,18 +269,21 @@ const SelectedEntriesModalContent = ({ toggleModal, refetchModalData, setEntries
|
|
|
247
269
|
{
|
|
248
270
|
onSuccess() {
|
|
249
271
|
const update = rowsToDisplay.filter((row) => {
|
|
250
|
-
if (entriesToPublish.includes(row.
|
|
272
|
+
if (entriesToPublish.includes(row.id)) {
|
|
251
273
|
// Deselect the entries that have been published from the modal table
|
|
252
|
-
onSelectRow({ name: row.
|
|
274
|
+
onSelectRow({ name: row.id, value: false });
|
|
253
275
|
}
|
|
254
276
|
|
|
255
277
|
// Remove the entries that have been published from the table
|
|
256
|
-
return !entriesToPublish.includes(row.
|
|
278
|
+
return !entriesToPublish.includes(row.id);
|
|
257
279
|
});
|
|
258
280
|
|
|
259
281
|
setRowsToDisplay(update);
|
|
282
|
+
const publishedIds = update.map(({ id }) => id);
|
|
260
283
|
// Set the parent's entries to fetch when clicking refresh
|
|
261
|
-
setEntriesToFetch(
|
|
284
|
+
setEntriesToFetch(publishedIds);
|
|
285
|
+
// Deselect the entries that were published in the list view
|
|
286
|
+
setSelectedListViewEntries(publishedIds);
|
|
262
287
|
|
|
263
288
|
if (update.length === 0) {
|
|
264
289
|
toggleModal();
|
|
@@ -341,6 +366,7 @@ const SelectedEntriesModalContent = ({ toggleModal, refetchModalData, setEntries
|
|
|
341
366
|
isPublishing={bulkPublishMutation.isLoading}
|
|
342
367
|
rowsToDisplay={rowsToDisplay}
|
|
343
368
|
entriesToPublish={entriesToPublish}
|
|
369
|
+
validationErrors={validationErrors}
|
|
344
370
|
/>
|
|
345
371
|
</Box>
|
|
346
372
|
</ModalBody>
|
|
@@ -382,10 +408,21 @@ const SelectedEntriesModalContent = ({ toggleModal, refetchModalData, setEntries
|
|
|
382
408
|
);
|
|
383
409
|
};
|
|
384
410
|
|
|
411
|
+
SelectedEntriesModalContent.defaultProps = {
|
|
412
|
+
validationErrors: {},
|
|
413
|
+
};
|
|
414
|
+
|
|
385
415
|
SelectedEntriesModalContent.propTypes = {
|
|
386
416
|
toggleModal: PropTypes.func.isRequired,
|
|
387
417
|
refetchModalData: PropTypes.func.isRequired,
|
|
388
418
|
setEntriesToFetch: PropTypes.func.isRequired,
|
|
419
|
+
setSelectedListViewEntries: PropTypes.func.isRequired,
|
|
420
|
+
validationErrors: PropTypes.shape({
|
|
421
|
+
[PropTypes.string]: PropTypes.shape({
|
|
422
|
+
id: PropTypes.string,
|
|
423
|
+
defaultMessage: PropTypes.string,
|
|
424
|
+
}),
|
|
425
|
+
}),
|
|
389
426
|
};
|
|
390
427
|
|
|
391
428
|
/* -------------------------------------------------------------------------------------------------
|
|
@@ -393,18 +430,23 @@ SelectedEntriesModalContent.propTypes = {
|
|
|
393
430
|
* -----------------------------------------------------------------------------------------------*/
|
|
394
431
|
|
|
395
432
|
const SelectedEntriesModal = ({ onToggle }) => {
|
|
396
|
-
const {
|
|
433
|
+
const {
|
|
434
|
+
selectedEntries: selectedListViewEntries,
|
|
435
|
+
setSelectedEntries: setSelectedListViewEntries,
|
|
436
|
+
} = useTableContext();
|
|
397
437
|
const { contentType, components } = useSelector(listViewDomain());
|
|
398
438
|
// The child table will update this value based on the entries that were published
|
|
399
439
|
const [entriesToFetch, setEntriesToFetch] = React.useState(selectedListViewEntries);
|
|
400
|
-
|
|
401
440
|
// We want to keep the selected entries order same as the list view
|
|
402
441
|
const [
|
|
403
442
|
{
|
|
404
443
|
query: { sort },
|
|
405
444
|
},
|
|
406
445
|
] = useQueryParams();
|
|
446
|
+
|
|
407
447
|
const queryParams = {
|
|
448
|
+
page: 1,
|
|
449
|
+
pageSize: entriesToFetch.length,
|
|
408
450
|
sort,
|
|
409
451
|
filters: {
|
|
410
452
|
id: {
|
|
@@ -424,38 +466,43 @@ const SelectedEntriesModal = ({ onToggle }) => {
|
|
|
424
466
|
|
|
425
467
|
if (data.results) {
|
|
426
468
|
const schema = createYupSchema(contentType, { components }, { isDraft: false });
|
|
469
|
+
const validationErrors = {};
|
|
427
470
|
const rows = data.results.map((entry) => {
|
|
428
471
|
try {
|
|
429
472
|
schema.validateSync(entry, { abortEarly: false });
|
|
430
473
|
|
|
431
|
-
return
|
|
474
|
+
return entry;
|
|
432
475
|
} catch (e) {
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
};
|
|
476
|
+
validationErrors[entry.id] = getYupInnerErrors(e);
|
|
477
|
+
|
|
478
|
+
return entry;
|
|
437
479
|
}
|
|
438
480
|
});
|
|
439
481
|
|
|
440
|
-
return rows;
|
|
482
|
+
return { rows, validationErrors };
|
|
441
483
|
}
|
|
442
484
|
|
|
443
|
-
return
|
|
485
|
+
return {
|
|
486
|
+
rows: [],
|
|
487
|
+
validationErrors: {},
|
|
488
|
+
};
|
|
444
489
|
}
|
|
445
490
|
);
|
|
446
491
|
|
|
447
492
|
return (
|
|
448
493
|
<Table.Root
|
|
449
|
-
rows={data}
|
|
494
|
+
rows={data?.rows}
|
|
450
495
|
defaultSelectedEntries={selectedListViewEntries}
|
|
451
496
|
colCount={4}
|
|
452
497
|
isLoading={isLoading}
|
|
453
498
|
isFetching={isFetching}
|
|
454
499
|
>
|
|
455
500
|
<SelectedEntriesModalContent
|
|
501
|
+
setSelectedListViewEntries={setSelectedListViewEntries}
|
|
456
502
|
setEntriesToFetch={setEntriesToFetch}
|
|
457
503
|
toggleModal={onToggle}
|
|
458
504
|
refetchModalData={refetch}
|
|
505
|
+
validationErrors={data?.validationErrors}
|
|
459
506
|
/>
|
|
460
507
|
</Table.Root>
|
|
461
508
|
);
|
|
@@ -98,10 +98,6 @@ const Register = ({ authType, fieldsToDisable, noSignin, onSubmit, schema }) =>
|
|
|
98
98
|
|
|
99
99
|
if (!['password', 'confirmPassword'].includes(key) && typeof value === 'string') {
|
|
100
100
|
normalizedvalue = normalizedvalue.trim();
|
|
101
|
-
|
|
102
|
-
if (key === 'lastname') {
|
|
103
|
-
normalizedvalue = normalizedvalue || null;
|
|
104
|
-
}
|
|
105
101
|
}
|
|
106
102
|
|
|
107
103
|
acc[key] = normalizedvalue;
|
|
@@ -308,7 +308,7 @@ const EventRow = ({ disabledEvents, name, events, inputValue, handleSelect, hand
|
|
|
308
308
|
</Td>
|
|
309
309
|
);
|
|
310
310
|
})}
|
|
311
|
-
{events.length < targetColumns && <Td colSpan={
|
|
311
|
+
{events.length < targetColumns && <Td colSpan={targetColumns - events.length} />}
|
|
312
312
|
</Tr>
|
|
313
313
|
);
|
|
314
314
|
};
|
|
@@ -678,6 +678,7 @@
|
|
|
678
678
|
"content-manager.components.SettingsViewWrapper.pluginHeader.description.edit-settings": "Customize how the edit view will look like.",
|
|
679
679
|
"content-manager.components.SettingsViewWrapper.pluginHeader.description.list-settings": "Define the settings of the list view.",
|
|
680
680
|
"content-manager.components.SettingsViewWrapper.pluginHeader.title": "Configure the view — {name}",
|
|
681
|
+
"content-manager.bulk-publish.already-published": "Already Published",
|
|
681
682
|
"content-manager.components.TableDelete.delete": "Delete all",
|
|
682
683
|
"content-manager.components.TableDelete.deleteSelected": "Delete selected",
|
|
683
684
|
"content-manager.components.TableDelete.label": "{number, plural, one {# entry} other {# entries}} selected",
|
package/build/{Admin-authenticatedApp.6b8dfa45.chunk.js → Admin-authenticatedApp.376233ff.chunk.js}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";(self.webpackChunk_strapi_admin=self.webpackChunk_strapi_admin||[]).push([[801],{63546:function(K,T,n){n.r(T),n.d(T,{default:function(){return jt}});var e=n(32735),s=n(19565),b=n(33795),Z=n.n(b),y=n(20108),M=
|
|
1
|
+
"use strict";(self.webpackChunk_strapi_admin=self.webpackChunk_strapi_admin||[]).push([[801],{63546:function(K,T,n){n.r(T),n.d(T,{default:function(){return jt}});var e=n(32735),s=n(19565),b=n(33795),Z=n.n(b),y=n(20108),M={i8:"4.12.0"},S=n(2160),L=n(86209),P=n(74506),F=n(51968),D=n(15062),f=n(53038),Re=n(88311),ee=n.n(Re),Ae=n(75974),m=n(87933),te=n(71933),ne=n(67563),Le=n(50563),v=n(72850),V=n(41415),ae=n(35331),Oe=n(60216),r=n.n(Oe),B=n(67879),C=n(8471);const xe=(0,C.ZP)(m.k)`
|
|
2
2
|
position: fixed;
|
|
3
3
|
z-index: 4;
|
|
4
4
|
inset: 0;
|