mirror of
https://github.com/strapi/strapi.git
synced 2025-08-11 18:27:22 +00:00
Move validation and handler to page level
This commit is contained in:
parent
e254aa5093
commit
7c9c2d13d7
@ -1,13 +1,10 @@
|
|||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { useSelector } from 'react-redux';
|
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { Button } from '@strapi/design-system';
|
import { Button } from '@strapi/design-system';
|
||||||
import { useTracking, getYupInnerErrors } from '@strapi/helper-plugin';
|
import { useTracking } from '@strapi/helper-plugin';
|
||||||
import { useIntl } from 'react-intl';
|
import { useIntl } from 'react-intl';
|
||||||
|
|
||||||
import ConfirmDialogDeleteAll from '../ConfirmDialogDeleteAll';
|
import ConfirmDialogDeleteAll from '../ConfirmDialogDeleteAll';
|
||||||
import { createYupSchema } from '../../../utils';
|
|
||||||
import { listViewDomain } from '../../../pages/ListView/selectors';
|
|
||||||
|
|
||||||
const BulkActionsBar = ({
|
const BulkActionsBar = ({
|
||||||
showPublish,
|
showPublish,
|
||||||
@ -15,8 +12,8 @@ const BulkActionsBar = ({
|
|||||||
onConfirmDeleteAll,
|
onConfirmDeleteAll,
|
||||||
selectedEntries,
|
selectedEntries,
|
||||||
clearSelectedEntries,
|
clearSelectedEntries,
|
||||||
|
handleBulkPublish,
|
||||||
}) => {
|
}) => {
|
||||||
const { data, contentType, components } = useSelector(listViewDomain());
|
|
||||||
const { formatMessage } = useIntl();
|
const { formatMessage } = useIntl();
|
||||||
const { trackUsage } = useTracking();
|
const { trackUsage } = useTracking();
|
||||||
|
|
||||||
@ -43,50 +40,12 @@ const BulkActionsBar = ({
|
|||||||
handleToggleShowDeleteAllModal();
|
handleToggleShowDeleteAllModal();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
/**
|
|
||||||
* @param {number[]} selectedIds - Array of ids to publish
|
|
||||||
* @returns {{validIds: number[], errors: Object.<number, string>}} - Returns an object with the valid ids and the errors
|
|
||||||
*/
|
|
||||||
const validateEntriesToPublish = async () => {
|
|
||||||
const validations = { validIds: [], errors: {} };
|
|
||||||
// Create the validation schema based on the contentType
|
|
||||||
const schema = createYupSchema(contentType, { components }, { isDraft: false });
|
|
||||||
// Get the selected entries
|
|
||||||
const entries = data.filter((entry) => {
|
|
||||||
return selectedEntries.includes(entry.id);
|
|
||||||
});
|
|
||||||
// Validate each entry and map the unresolved promises
|
|
||||||
const validationPromises = entries.map((entry) =>
|
|
||||||
schema.validate(entry, { abortEarly: false })
|
|
||||||
);
|
|
||||||
// Resolve all the promises in one go
|
|
||||||
const resolvedPromises = await Promise.allSettled(validationPromises);
|
|
||||||
// Set the validations
|
|
||||||
resolvedPromises.forEach((promise) => {
|
|
||||||
if (promise.status === 'rejected') {
|
|
||||||
const entityId = promise.reason.value.id;
|
|
||||||
validations.errors[entityId] = getYupInnerErrors(promise.reason);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (promise.status === 'fulfilled') {
|
|
||||||
validations.validIds.push(promise.value.id);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return validations;
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleBulkPublish = async () => {
|
|
||||||
const validations = await validateEntriesToPublish();
|
|
||||||
// TODO: Remove log when we actually do something with the validations
|
|
||||||
console.log(validations);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{showPublish && (
|
{showPublish && (
|
||||||
<>
|
<>
|
||||||
<Button variant="tertiary" onClick={handleBulkPublish}>
|
<Button variant="tertiary" onClick={() => handleBulkPublish(selectedEntries)}>
|
||||||
{formatMessage({ id: 'app.utils.publish', defaultMessage: 'Publish' })}
|
{formatMessage({ id: 'app.utils.publish', defaultMessage: 'Publish' })}
|
||||||
</Button>
|
</Button>
|
||||||
<Button variant="tertiary">
|
<Button variant="tertiary">
|
||||||
@ -123,6 +82,7 @@ BulkActionsBar.propTypes = {
|
|||||||
onConfirmDeleteAll: PropTypes.func,
|
onConfirmDeleteAll: PropTypes.func,
|
||||||
selectedEntries: PropTypes.array.isRequired,
|
selectedEntries: PropTypes.array.isRequired,
|
||||||
clearSelectedEntries: PropTypes.func.isRequired,
|
clearSelectedEntries: PropTypes.func.isRequired,
|
||||||
|
handleBulkPublish: PropTypes.func.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default BulkActionsBar;
|
export default BulkActionsBar;
|
||||||
|
@ -23,6 +23,7 @@ const DynamicTable = ({
|
|||||||
isLoading,
|
isLoading,
|
||||||
onConfirmDelete,
|
onConfirmDelete,
|
||||||
onConfirmDeleteAll,
|
onConfirmDeleteAll,
|
||||||
|
handleBulkPublish,
|
||||||
layout,
|
layout,
|
||||||
rows,
|
rows,
|
||||||
}) => {
|
}) => {
|
||||||
@ -107,6 +108,7 @@ const DynamicTable = ({
|
|||||||
onConfirmDeleteAll={onConfirmDeleteAll}
|
onConfirmDeleteAll={onConfirmDeleteAll}
|
||||||
selectedEntries={selectedEntries}
|
selectedEntries={selectedEntries}
|
||||||
clearSelectedEntries={clearSelectedEntries}
|
clearSelectedEntries={clearSelectedEntries}
|
||||||
|
handleBulkPublish={handleBulkPublish}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
@ -150,6 +152,7 @@ DynamicTable.propTypes = {
|
|||||||
onConfirmDelete: PropTypes.func.isRequired,
|
onConfirmDelete: PropTypes.func.isRequired,
|
||||||
onConfirmDeleteAll: PropTypes.func.isRequired,
|
onConfirmDeleteAll: PropTypes.func.isRequired,
|
||||||
rows: PropTypes.array.isRequired,
|
rows: PropTypes.array.isRequired,
|
||||||
|
handleBulkPublish: PropTypes.func.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default DynamicTable;
|
export default DynamicTable;
|
||||||
|
@ -21,6 +21,7 @@ import {
|
|||||||
useTracking,
|
useTracking,
|
||||||
Link,
|
Link,
|
||||||
useAPIErrorHandler,
|
useAPIErrorHandler,
|
||||||
|
getYupInnerErrors,
|
||||||
} from '@strapi/helper-plugin';
|
} from '@strapi/helper-plugin';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@ -42,7 +43,7 @@ import { InjectionZone } from '../../../shared/components';
|
|||||||
|
|
||||||
import permissions from '../../../permissions';
|
import permissions from '../../../permissions';
|
||||||
|
|
||||||
import { getRequestUrl, getTrad } from '../../utils';
|
import { createYupSchema, getRequestUrl, getTrad } from '../../utils';
|
||||||
|
|
||||||
import FieldPicker from './FieldPicker';
|
import FieldPicker from './FieldPicker';
|
||||||
import PaginationFooter from './PaginationFooter';
|
import PaginationFooter from './PaginationFooter';
|
||||||
@ -201,6 +202,49 @@ function ListView({
|
|||||||
[slug, params, fetchData, toggleNotification, formatAPIError, del]
|
[slug, params, fetchData, toggleNotification, formatAPIError, del]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {number[]} selectedEntries - Array of ids to publish
|
||||||
|
* @returns {{validIds: number[], errors: Object.<number, string>}} - Returns an object with the valid ids and the errors
|
||||||
|
*/
|
||||||
|
const validateEntriesToPublish = async (selectedEntries) => {
|
||||||
|
const validations = { validIds: [], errors: {} };
|
||||||
|
// Create the validation schema based on the contentType
|
||||||
|
const schema = createYupSchema(
|
||||||
|
contentType,
|
||||||
|
{ components: layout.components },
|
||||||
|
{ isDraft: false }
|
||||||
|
);
|
||||||
|
// Get the selected entries
|
||||||
|
const entries = data.filter((entry) => {
|
||||||
|
return selectedEntries.includes(entry.id);
|
||||||
|
});
|
||||||
|
// Validate each entry and map the unresolved promises
|
||||||
|
const validationPromises = entries.map((entry) =>
|
||||||
|
schema.validate(entry, { abortEarly: false })
|
||||||
|
);
|
||||||
|
// Resolve all the promises in one go
|
||||||
|
const resolvedPromises = await Promise.allSettled(validationPromises);
|
||||||
|
// Set the validations
|
||||||
|
resolvedPromises.forEach((promise) => {
|
||||||
|
if (promise.status === 'rejected') {
|
||||||
|
const entityId = promise.reason.value.id;
|
||||||
|
validations.errors[entityId] = getYupInnerErrors(promise.reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (promise.status === 'fulfilled') {
|
||||||
|
validations.validIds.push(promise.value.id);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return validations;
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleBulkPublish = async (selectedEntries) => {
|
||||||
|
const validations = await validateEntriesToPublish(selectedEntries);
|
||||||
|
// TODO: Remove log when we actually do something with the validations
|
||||||
|
console.log(validations);
|
||||||
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const CancelToken = axios.CancelToken;
|
const CancelToken = axios.CancelToken;
|
||||||
const source = CancelToken.source();
|
const source = CancelToken.source();
|
||||||
@ -342,6 +386,7 @@ function ListView({
|
|||||||
layout={layout}
|
layout={layout}
|
||||||
rows={data}
|
rows={data}
|
||||||
action={getCreateAction({ variant: 'secondary' })}
|
action={getCreateAction({ variant: 'secondary' })}
|
||||||
|
handleBulkPublish={handleBulkPublish}
|
||||||
/>
|
/>
|
||||||
<PaginationFooter pagination={{ pageCount: pagination?.pageCount || 1 }} />
|
<PaginationFooter pagination={{ pageCount: pagination?.pageCount || 1 }} />
|
||||||
</>
|
</>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user