Move validation and handler to page level

This commit is contained in:
Mark Kaylor 2023-04-28 10:13:28 +02:00
parent e254aa5093
commit 7c9c2d13d7
3 changed files with 53 additions and 45 deletions

View File

@ -1,13 +1,10 @@
import React, { useState } from 'react';
import { useSelector } from 'react-redux';
import PropTypes from 'prop-types';
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 ConfirmDialogDeleteAll from '../ConfirmDialogDeleteAll';
import { createYupSchema } from '../../../utils';
import { listViewDomain } from '../../../pages/ListView/selectors';
const BulkActionsBar = ({
showPublish,
@ -15,8 +12,8 @@ const BulkActionsBar = ({
onConfirmDeleteAll,
selectedEntries,
clearSelectedEntries,
handleBulkPublish,
}) => {
const { data, contentType, components } = useSelector(listViewDomain());
const { formatMessage } = useIntl();
const { trackUsage } = useTracking();
@ -43,50 +40,12 @@ const BulkActionsBar = ({
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 (
<>
{showPublish && (
<>
<Button variant="tertiary" onClick={handleBulkPublish}>
<Button variant="tertiary" onClick={() => handleBulkPublish(selectedEntries)}>
{formatMessage({ id: 'app.utils.publish', defaultMessage: 'Publish' })}
</Button>
<Button variant="tertiary">
@ -123,6 +82,7 @@ BulkActionsBar.propTypes = {
onConfirmDeleteAll: PropTypes.func,
selectedEntries: PropTypes.array.isRequired,
clearSelectedEntries: PropTypes.func.isRequired,
handleBulkPublish: PropTypes.func.isRequired,
};
export default BulkActionsBar;

View File

@ -23,6 +23,7 @@ const DynamicTable = ({
isLoading,
onConfirmDelete,
onConfirmDeleteAll,
handleBulkPublish,
layout,
rows,
}) => {
@ -107,6 +108,7 @@ const DynamicTable = ({
onConfirmDeleteAll={onConfirmDeleteAll}
selectedEntries={selectedEntries}
clearSelectedEntries={clearSelectedEntries}
handleBulkPublish={handleBulkPublish}
/>
)}
>
@ -150,6 +152,7 @@ DynamicTable.propTypes = {
onConfirmDelete: PropTypes.func.isRequired,
onConfirmDeleteAll: PropTypes.func.isRequired,
rows: PropTypes.array.isRequired,
handleBulkPublish: PropTypes.func.isRequired,
};
export default DynamicTable;

View File

@ -21,6 +21,7 @@ import {
useTracking,
Link,
useAPIErrorHandler,
getYupInnerErrors,
} from '@strapi/helper-plugin';
import {
@ -42,7 +43,7 @@ import { InjectionZone } from '../../../shared/components';
import permissions from '../../../permissions';
import { getRequestUrl, getTrad } from '../../utils';
import { createYupSchema, getRequestUrl, getTrad } from '../../utils';
import FieldPicker from './FieldPicker';
import PaginationFooter from './PaginationFooter';
@ -201,6 +202,49 @@ function ListView({
[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(() => {
const CancelToken = axios.CancelToken;
const source = CancelToken.source();
@ -342,6 +386,7 @@ function ListView({
layout={layout}
rows={data}
action={getCreateAction({ variant: 'secondary' })}
handleBulkPublish={handleBulkPublish}
/>
<PaginationFooter pagination={{ pageCount: pagination?.pageCount || 1 }} />
</>