feat: renames revisions to versions
This commit is contained in:
@@ -9,8 +9,8 @@ import { requests } from '../api';
|
||||
import Loading from './elements/Loading';
|
||||
import StayLoggedIn from './modals/StayLoggedIn';
|
||||
import Unlicensed from './views/Unlicensed';
|
||||
import Revisions from './views/Revisions';
|
||||
import Revision from './views/Revision';
|
||||
import Versions from './views/Versions';
|
||||
import Version from './views/Version';
|
||||
|
||||
const Dashboard = lazy(() => import('./views/Dashboard'));
|
||||
const ForgotPassword = lazy(() => import('./views/ForgotPassword'));
|
||||
@@ -204,16 +204,16 @@ const Routes = () => {
|
||||
/>,
|
||||
];
|
||||
|
||||
if (collection.revisions) {
|
||||
if (collection.versions) {
|
||||
routesToReturn.push(
|
||||
<Route
|
||||
key={`${collection.slug}-revisions`}
|
||||
path={`${match.url}/collections/${collection.slug}/:id/revisions`}
|
||||
key={`${collection.slug}-versions`}
|
||||
path={`${match.url}/collections/${collection.slug}/:id/versions`}
|
||||
exact
|
||||
render={(routeProps) => {
|
||||
if (permissions?.collections?.[collection.slug]?.readRevisions?.permission) {
|
||||
if (permissions?.collections?.[collection.slug]?.readVersions?.permission) {
|
||||
return (
|
||||
<Revisions
|
||||
<Versions
|
||||
{...routeProps}
|
||||
collection={collection}
|
||||
/>
|
||||
@@ -227,13 +227,13 @@ const Routes = () => {
|
||||
|
||||
routesToReturn.push(
|
||||
<Route
|
||||
key={`${collection.slug}-view-revision`}
|
||||
path={`${match.url}/collections/${collection.slug}/:id/revisions/:revisionID`}
|
||||
key={`${collection.slug}-view-version`}
|
||||
path={`${match.url}/collections/${collection.slug}/:id/versions/:versionID`}
|
||||
exact
|
||||
render={(routeProps) => {
|
||||
if (permissions?.collections?.[collection.slug]?.readRevisions?.permission) {
|
||||
if (permissions?.collections?.[collection.slug]?.readVersions?.permission) {
|
||||
return (
|
||||
<Revision
|
||||
<Version
|
||||
{...routeProps}
|
||||
collection={collection}
|
||||
/>
|
||||
@@ -271,16 +271,16 @@ const Routes = () => {
|
||||
/>,
|
||||
];
|
||||
|
||||
if (global.revisions) {
|
||||
if (global.versions) {
|
||||
routesToReturn.push(
|
||||
<Route
|
||||
key={`${global.slug}-revisions`}
|
||||
path={`${match.url}/globals/${global.slug}/revisions`}
|
||||
key={`${global.slug}-versions`}
|
||||
path={`${match.url}/globals/${global.slug}/versions`}
|
||||
exact
|
||||
render={(routeProps) => {
|
||||
if (permissions?.globals?.[global.slug]?.readRevisions?.permission) {
|
||||
if (permissions?.globals?.[global.slug]?.readVersions?.permission) {
|
||||
return (
|
||||
<Revisions
|
||||
<Versions
|
||||
{...routeProps}
|
||||
global={global}
|
||||
/>
|
||||
@@ -293,13 +293,13 @@ const Routes = () => {
|
||||
);
|
||||
routesToReturn.push(
|
||||
<Route
|
||||
key={`${global.slug}-view-revision`}
|
||||
path={`${match.url}/globals/${global.slug}/revisions/:revisionID`}
|
||||
key={`${global.slug}-view-version`}
|
||||
path={`${match.url}/globals/${global.slug}/versions/:versionID`}
|
||||
exact
|
||||
render={(routeProps) => {
|
||||
if (permissions?.globals?.[global.slug]?.readRevisions?.permission) {
|
||||
if (permissions?.globals?.[global.slug]?.readVersions?.permission) {
|
||||
return (
|
||||
<Revision
|
||||
<Version
|
||||
{...routeProps}
|
||||
global={global}
|
||||
/>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
@import '../../../scss/styles.scss';
|
||||
|
||||
.revisions-count__button {
|
||||
.versions-count__button {
|
||||
font-weight: 600;
|
||||
|
||||
&:hover {
|
||||
@@ -6,14 +6,14 @@ import { Props } from './types';
|
||||
|
||||
import './index.scss';
|
||||
|
||||
const baseClass = 'revisions-count';
|
||||
const baseClass = 'versions-count';
|
||||
|
||||
const Revisions: React.FC<Props> = ({ collection, global, id, submissionCount }) => {
|
||||
const Versions: React.FC<Props> = ({ collection, global, id, submissionCount }) => {
|
||||
const { serverURL, routes: { admin, api } } = useConfig();
|
||||
|
||||
let initialParams;
|
||||
let fetchURL: string;
|
||||
let revisionsURL: string;
|
||||
let versionsURL: string;
|
||||
|
||||
if (collection) {
|
||||
initialParams = {
|
||||
@@ -24,13 +24,13 @@ const Revisions: React.FC<Props> = ({ collection, global, id, submissionCount })
|
||||
},
|
||||
};
|
||||
|
||||
fetchURL = `${serverURL}${api}/${collection.slug}/revisions`;
|
||||
revisionsURL = `${admin}/collections/${collection.slug}/${id}/revisions`;
|
||||
fetchURL = `${serverURL}${api}/${collection.slug}/versions`;
|
||||
versionsURL = `${admin}/collections/${collection.slug}/${id}/versions`;
|
||||
}
|
||||
|
||||
if (global) {
|
||||
fetchURL = `${serverURL}${api}/globals/${global.slug}/revisions`;
|
||||
revisionsURL = `${admin}/globals/${global.slug}/revisions`;
|
||||
fetchURL = `${serverURL}${api}/globals/${global.slug}/versions`;
|
||||
versionsURL = `${admin}/globals/${global.slug}/versions`;
|
||||
}
|
||||
|
||||
const [{ data, isLoading }, { setParams }] = usePayloadAPI(fetchURL, {
|
||||
@@ -58,7 +58,7 @@ const Revisions: React.FC<Props> = ({ collection, global, id, submissionCount })
|
||||
<React.Fragment>
|
||||
{data.docs.length === 0 && (
|
||||
<React.Fragment>
|
||||
No revisions found
|
||||
No versions found
|
||||
</React.Fragment>
|
||||
)}
|
||||
{data?.docs?.length > 0 && (
|
||||
@@ -67,11 +67,11 @@ const Revisions: React.FC<Props> = ({ collection, global, id, submissionCount })
|
||||
className={`${baseClass}__button`}
|
||||
buttonStyle="none"
|
||||
el="link"
|
||||
to={revisionsURL}
|
||||
to={versionsURL}
|
||||
>
|
||||
{data.totalDocs}
|
||||
{' '}
|
||||
revision
|
||||
version
|
||||
{data.totalDocs > 1 && 's'}
|
||||
{' '}
|
||||
found
|
||||
@@ -82,10 +82,10 @@ const Revisions: React.FC<Props> = ({ collection, global, id, submissionCount })
|
||||
)}
|
||||
{isLoading && (
|
||||
<React.Fragment>
|
||||
Loading revisions...
|
||||
Loading versions...
|
||||
</React.Fragment>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
export default Revisions;
|
||||
export default Versions;
|
||||
@@ -10,7 +10,7 @@ import CopyToClipboard from '../../elements/CopyToClipboard';
|
||||
import Meta from '../../utilities/Meta';
|
||||
import fieldTypes from '../../forms/field-types';
|
||||
import LeaveWithoutSaving from '../../modals/LeaveWithoutSaving';
|
||||
import RevisionsCount from '../../elements/RevisionsCount';
|
||||
import VersionsCount from '../../elements/VersionsCount';
|
||||
import { Props } from './types';
|
||||
|
||||
import './index.scss';
|
||||
@@ -27,7 +27,7 @@ const DefaultGlobalView: React.FC<Props> = (props) => {
|
||||
const {
|
||||
fields,
|
||||
preview,
|
||||
revisions,
|
||||
versions,
|
||||
label,
|
||||
admin: {
|
||||
description,
|
||||
@@ -101,10 +101,10 @@ const DefaultGlobalView: React.FC<Props> = (props) => {
|
||||
</div>
|
||||
{data && (
|
||||
<ul className={`${baseClass}__meta`}>
|
||||
{revisions && (
|
||||
{versions && (
|
||||
<li>
|
||||
<div className={`${baseClass}__label`}>Revisions</div>
|
||||
<RevisionsCount
|
||||
<div className={`${baseClass}__label`}>Versions</div>
|
||||
<VersionsCount
|
||||
submissionCount={submissionCount}
|
||||
global={global}
|
||||
/>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
@import '../../../../scss/styles.scss';
|
||||
|
||||
.compare-revision {
|
||||
.compare-version {
|
||||
&__error-loading {
|
||||
border: 1px solid $color-red;
|
||||
min-height: base(2);
|
||||
@@ -9,7 +9,7 @@ import { publishedVersionOption } from '../shared';
|
||||
|
||||
import './index.scss';
|
||||
|
||||
const baseClass = 'compare-revision';
|
||||
const baseClass = 'compare-version';
|
||||
|
||||
const maxResultsPerRequest = 10;
|
||||
|
||||
@@ -17,7 +17,7 @@ const baseOptions = [
|
||||
publishedVersionOption,
|
||||
];
|
||||
|
||||
const CompareRevision: React.FC<Props> = (props) => {
|
||||
const CompareVersion: React.FC<Props> = (props) => {
|
||||
const { onChange, value, baseURL, parentID } = props;
|
||||
|
||||
const {
|
||||
@@ -81,12 +81,12 @@ const CompareRevision: React.FC<Props> = (props) => {
|
||||
return (
|
||||
<div className={classes}>
|
||||
<div className={`${baseClass}__label`}>
|
||||
Compare revision against:
|
||||
Compare version against:
|
||||
</div>
|
||||
{!errorLoading && (
|
||||
<ReactSelect
|
||||
isSearchable={false}
|
||||
placeholder="Select a revision to compare"
|
||||
placeholder="Select a version to compare"
|
||||
onChange={onChange}
|
||||
onMenuScrollToBottom={() => {
|
||||
getResults({ lastLoadedPage: lastLoadedPage + 1 });
|
||||
@@ -104,4 +104,4 @@ const CompareRevision: React.FC<Props> = (props) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default CompareRevision;
|
||||
export default CompareVersion;
|
||||
@@ -10,7 +10,7 @@ import './index.scss';
|
||||
const baseClass = 'iterable-diff';
|
||||
|
||||
const Iterable: React.FC<Props & { field: ArrayField | BlockField }> = ({
|
||||
revision,
|
||||
version,
|
||||
comparison,
|
||||
permissions,
|
||||
field,
|
||||
@@ -18,9 +18,9 @@ const Iterable: React.FC<Props & { field: ArrayField | BlockField }> = ({
|
||||
locales,
|
||||
fieldComponents,
|
||||
}) => {
|
||||
const revisionRowCount = Array.isArray(revision) ? revision.length : 0;
|
||||
const versionRowCount = Array.isArray(version) ? version.length : 0;
|
||||
const comparisonRowCount = Array.isArray(comparison) ? comparison.length : 0;
|
||||
const maxRows = Math.max(revisionRowCount, comparisonRowCount);
|
||||
const maxRows = Math.max(versionRowCount, comparisonRowCount);
|
||||
|
||||
return (
|
||||
<div className={baseClass}>
|
||||
@@ -35,7 +35,7 @@ const Iterable: React.FC<Props & { field: ArrayField | BlockField }> = ({
|
||||
{maxRows > 0 && (
|
||||
<React.Fragment>
|
||||
{Array.from(Array(maxRows).keys()).map((row, i) => {
|
||||
const revisionRow = revision?.[i] || {};
|
||||
const versionRow = version?.[i] || {};
|
||||
const comparisonRow = comparison?.[i] || {};
|
||||
|
||||
let subFields: Field[] = [];
|
||||
@@ -51,19 +51,19 @@ const Iterable: React.FC<Props & { field: ArrayField | BlockField }> = ({
|
||||
},
|
||||
];
|
||||
|
||||
if (revisionRow?.blockType === comparisonRow?.blockType) {
|
||||
const matchedBlock = field.blocks.find((block) => block.slug === revisionRow?.blockType) || { fields: [] };
|
||||
if (versionRow?.blockType === comparisonRow?.blockType) {
|
||||
const matchedBlock = field.blocks.find((block) => block.slug === versionRow?.blockType) || { fields: [] };
|
||||
subFields = [
|
||||
...subFields,
|
||||
...matchedBlock.fields,
|
||||
];
|
||||
} else {
|
||||
const matchedRevisionBlock = field.blocks.find((block) => block.slug === revisionRow?.blockType) || { fields: [] };
|
||||
const matchedVersionBlock = field.blocks.find((block) => block.slug === versionRow?.blockType) || { fields: [] };
|
||||
const matchedComparisonBlock = field.blocks.find((block) => block.slug === comparisonRow?.blockType) || { fields: [] };
|
||||
|
||||
subFields = getUniqueListBy<Field>([
|
||||
...subFields,
|
||||
...matchedRevisionBlock.fields,
|
||||
...matchedVersionBlock.fields,
|
||||
...matchedComparisonBlock.fields,
|
||||
], 'name');
|
||||
}
|
||||
@@ -76,7 +76,7 @@ const Iterable: React.FC<Props & { field: ArrayField | BlockField }> = ({
|
||||
>
|
||||
<RenderFieldsToDiff
|
||||
locales={locales}
|
||||
revision={revisionRow}
|
||||
version={versionRow}
|
||||
comparison={comparisonRow}
|
||||
fieldPermissions={permissions}
|
||||
fields={subFields.filter((subField) => !(fieldAffectsData(subField) && subField.name === 'id'))}
|
||||
@@ -9,7 +9,7 @@ import './index.scss';
|
||||
const baseClass = 'nested-diff';
|
||||
|
||||
const Nested: React.FC<Props & { field: FieldWithSubFields}> = ({
|
||||
revision,
|
||||
version,
|
||||
comparison,
|
||||
permissions,
|
||||
field,
|
||||
@@ -34,7 +34,7 @@ const Nested: React.FC<Props & { field: FieldWithSubFields}> = ({
|
||||
>
|
||||
<RenderFieldsToDiff
|
||||
locales={locales}
|
||||
revision={revision}
|
||||
version={version}
|
||||
comparison={comparison}
|
||||
fieldPermissions={permissions}
|
||||
fields={field.fields}
|
||||
@@ -57,22 +57,22 @@ const generateLabelFromValue = (
|
||||
return valueToReturn;
|
||||
};
|
||||
|
||||
const Relationship: React.FC<Props & { field: RelationshipField}> = ({ field, revision, comparison }) => {
|
||||
const Relationship: React.FC<Props & { field: RelationshipField}> = ({ field, version, comparison }) => {
|
||||
const { collections } = useConfig();
|
||||
const locale = useLocale();
|
||||
|
||||
let placeholder = '';
|
||||
|
||||
if (revision === comparison) placeholder = '[no value]';
|
||||
if (version === comparison) placeholder = '[no value]';
|
||||
|
||||
let revisionToRender = revision;
|
||||
let versionToRender = version;
|
||||
let comparisonToRender = comparison;
|
||||
|
||||
if (field.hasMany) {
|
||||
if (Array.isArray(revision)) revisionToRender = revision.map((val) => generateLabelFromValue(collections, field, locale, val)).join(', ');
|
||||
if (Array.isArray(version)) versionToRender = version.map((val) => generateLabelFromValue(collections, field, locale, val)).join(', ');
|
||||
if (Array.isArray(comparison)) comparisonToRender = comparison.map((val) => generateLabelFromValue(collections, field, locale, val)).join(', ');
|
||||
} else {
|
||||
revisionToRender = generateLabelFromValue(collections, field, locale, revision);
|
||||
versionToRender = generateLabelFromValue(collections, field, locale, version);
|
||||
comparisonToRender = generateLabelFromValue(collections, field, locale, comparison);
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@ const Relationship: React.FC<Props & { field: RelationshipField}> = ({ field, re
|
||||
{field.label}
|
||||
</Label>
|
||||
<ReactDiffViewer
|
||||
oldValue={typeof revisionToRender !== 'undefined' ? String(revisionToRender) : placeholder}
|
||||
oldValue={typeof versionToRender !== 'undefined' ? String(versionToRender) : placeholder}
|
||||
newValue={typeof comparisonToRender !== 'undefined' ? String(comparisonToRender) : placeholder}
|
||||
splitView
|
||||
hideLineNumbers
|
||||
@@ -7,16 +7,16 @@ import './index.scss';
|
||||
|
||||
const baseClass = 'text-diff';
|
||||
|
||||
const Text: React.FC<Props> = ({ field, locale, revision, comparison, isRichText = false }) => {
|
||||
const Text: React.FC<Props> = ({ field, locale, version, comparison, isRichText = false }) => {
|
||||
let placeholder = '';
|
||||
|
||||
if (revision === comparison) placeholder = '[no value]';
|
||||
if (version === comparison) placeholder = '[no value]';
|
||||
|
||||
let revisionToRender = revision;
|
||||
let versionToRender = version;
|
||||
let comparisonToRender = comparison;
|
||||
|
||||
if (isRichText) {
|
||||
if (typeof revision === 'object') revisionToRender = JSON.stringify(revision, null, 2);
|
||||
if (typeof version === 'object') versionToRender = JSON.stringify(version, null, 2);
|
||||
if (typeof comparison === 'object') comparisonToRender = JSON.stringify(comparison, null, 2);
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ const Text: React.FC<Props> = ({ field, locale, revision, comparison, isRichText
|
||||
{field.label}
|
||||
</Label>
|
||||
<ReactDiffViewer
|
||||
oldValue={typeof revisionToRender !== 'undefined' ? String(revisionToRender) : placeholder}
|
||||
oldValue={typeof versionToRender !== 'undefined' ? String(versionToRender) : placeholder}
|
||||
newValue={typeof comparisonToRender !== 'undefined' ? String(comparisonToRender) : placeholder}
|
||||
splitView
|
||||
hideLineNumbers
|
||||
@@ -5,7 +5,7 @@ export type FieldComponents = Record<string, React.FC<Props>>
|
||||
|
||||
export type Props = {
|
||||
fieldComponents: FieldComponents
|
||||
revision: any
|
||||
version: any
|
||||
comparison: any
|
||||
field: any
|
||||
permissions?: Record<string, FieldPermissions>
|
||||
@@ -11,7 +11,7 @@ const RenderFieldsToDiff: React.FC<Props> = ({
|
||||
fields,
|
||||
fieldComponents,
|
||||
fieldPermissions,
|
||||
revision,
|
||||
version,
|
||||
comparison,
|
||||
locales,
|
||||
}) => (
|
||||
@@ -23,7 +23,7 @@ const RenderFieldsToDiff: React.FC<Props> = ({
|
||||
|
||||
if (Component) {
|
||||
if (fieldAffectsData(field)) {
|
||||
const revisionValue = revision[field.name];
|
||||
const versionValue = version?.[field.name];
|
||||
const comparisonValue = comparison?.[field.name];
|
||||
const hasPermission = fieldPermissions?.[field.name]?.read?.permission;
|
||||
const subFieldPermissions = fieldPermissions?.[field.name]?.fields;
|
||||
@@ -37,7 +37,7 @@ const RenderFieldsToDiff: React.FC<Props> = ({
|
||||
key={i}
|
||||
>
|
||||
{locales.map((locale) => {
|
||||
const revisionLocaleValue = revisionValue?.[locale];
|
||||
const versionLocaleValue = versionValue?.[locale];
|
||||
const comparisonLocaleValue = comparisonValue?.[locale];
|
||||
return (
|
||||
<div
|
||||
@@ -50,7 +50,7 @@ const RenderFieldsToDiff: React.FC<Props> = ({
|
||||
locales={locales}
|
||||
field={field}
|
||||
fieldComponents={fieldComponents}
|
||||
revision={revisionLocaleValue}
|
||||
version={versionLocaleValue}
|
||||
comparison={comparisonLocaleValue}
|
||||
permissions={subFieldPermissions}
|
||||
isRichText={isRichText}
|
||||
@@ -72,7 +72,7 @@ const RenderFieldsToDiff: React.FC<Props> = ({
|
||||
locales={locales}
|
||||
field={field}
|
||||
fieldComponents={fieldComponents}
|
||||
revision={revisionValue}
|
||||
version={versionValue}
|
||||
comparison={comparisonValue}
|
||||
permissions={subFieldPermissions}
|
||||
isRichText={isRichText}
|
||||
@@ -90,7 +90,7 @@ const RenderFieldsToDiff: React.FC<Props> = ({
|
||||
disableGutter
|
||||
field={field}
|
||||
fieldComponents={fieldComponents}
|
||||
revision={revision}
|
||||
version={version}
|
||||
comparison={comparison}
|
||||
permissions={fieldPermissions}
|
||||
/>
|
||||
@@ -6,7 +6,7 @@ export type Props = {
|
||||
fields: Field[]
|
||||
fieldComponents: FieldComponents,
|
||||
fieldPermissions: Record<string, FieldPermissions>
|
||||
revision: Record<string, any>
|
||||
version: Record<string, any>
|
||||
comparison: Record<string, any>
|
||||
locales: string[]
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
@import '../../../../scss/styles.scss';
|
||||
|
||||
.restore-revision {
|
||||
.restore-version {
|
||||
cursor: pointer;
|
||||
|
||||
&__modal {
|
||||
@@ -9,10 +9,10 @@ import { requests } from '../../../../api';
|
||||
|
||||
import './index.scss';
|
||||
|
||||
const baseClass = 'restore-revision';
|
||||
const modalSlug = 'restore-revision';
|
||||
const baseClass = 'restore-version';
|
||||
const modalSlug = 'restore-version';
|
||||
|
||||
const Restore: React.FC<Props> = ({ collection, global, className, revisionID, originalDocID, revisionDate }) => {
|
||||
const Restore: React.FC<Props> = ({ collection, global, className, versionID, originalDocID, versionDate }) => {
|
||||
const { serverURL, routes: { api, admin } } = useConfig();
|
||||
const history = useHistory();
|
||||
const { toggle } = useModal();
|
||||
@@ -23,15 +23,15 @@ const Restore: React.FC<Props> = ({ collection, global, className, revisionID, o
|
||||
let restoreMessage: string;
|
||||
|
||||
if (collection) {
|
||||
fetchURL = `${fetchURL}/${collection.slug}/revisions/${revisionID}`;
|
||||
fetchURL = `${fetchURL}/${collection.slug}/versions/${versionID}`;
|
||||
redirectURL = `${admin}/collections/${collection.slug}/${originalDocID}`;
|
||||
restoreMessage = `You are about to restore this ${collection.labels.singular} document to the state that it was in on ${revisionDate}.`;
|
||||
restoreMessage = `You are about to restore this ${collection.labels.singular} document to the state that it was in on ${versionDate}.`;
|
||||
}
|
||||
|
||||
if (global) {
|
||||
fetchURL = `${fetchURL}/globals/${global.slug}/revisions/${revisionID}`;
|
||||
fetchURL = `${fetchURL}/globals/${global.slug}/versions/${versionID}`;
|
||||
redirectURL = `${admin}/globals/${global.slug}`;
|
||||
restoreMessage = `You are about to restore the global ${global.label} to the state that it was in on ${revisionDate}.`;
|
||||
restoreMessage = `You are about to restore the global ${global.label} to the state that it was in on ${versionDate}.`;
|
||||
}
|
||||
|
||||
const handleRestore = useCallback(async () => {
|
||||
@@ -44,7 +44,7 @@ const Restore: React.FC<Props> = ({ collection, global, className, revisionID, o
|
||||
toast.success(json.message);
|
||||
history.push(redirectURL);
|
||||
} else {
|
||||
toast.error('There was a problem while restoring this revision.');
|
||||
toast.error('There was a problem while restoring this version.');
|
||||
}
|
||||
}, [history, fetchURL, redirectURL]);
|
||||
|
||||
@@ -54,14 +54,14 @@ const Restore: React.FC<Props> = ({ collection, global, className, revisionID, o
|
||||
onClick={() => toggle(modalSlug)}
|
||||
className={[baseClass, className].filter(Boolean).join(' ')}
|
||||
>
|
||||
Restore this revision
|
||||
Restore this version
|
||||
</Pill>
|
||||
<Modal
|
||||
slug={modalSlug}
|
||||
className={`${baseClass}__modal`}
|
||||
>
|
||||
<MinimalTemplate>
|
||||
<h1>Confirm revision restoration</h1>
|
||||
<h1>Confirm version restoration</h1>
|
||||
<p>{restoreMessage}</p>
|
||||
<Button
|
||||
buttonStyle="secondary"
|
||||
@@ -5,7 +5,7 @@ export type Props = {
|
||||
collection?: SanitizedCollectionConfig
|
||||
global?: SanitizedGlobalConfig
|
||||
className?: string
|
||||
revisionID: string
|
||||
versionID: string
|
||||
originalDocID: string
|
||||
revisionDate: string
|
||||
versionDate: string
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
@import '../../../../scss/styles.scss';
|
||||
|
||||
.select-revision-locales {
|
||||
.select-version-locales {
|
||||
flex-grow: 1;
|
||||
|
||||
&__label {
|
||||
@@ -4,7 +4,7 @@ import { Props } from './types';
|
||||
|
||||
import './index.scss';
|
||||
|
||||
const baseClass = 'select-revision-locales';
|
||||
const baseClass = 'select-version-locales';
|
||||
|
||||
const SelectLocales: React.FC<Props> = ({ onChange, value, options }) => (
|
||||
<div className={baseClass}>
|
||||
@@ -9,7 +9,7 @@ import { useStepNav } from '../../elements/StepNav';
|
||||
import { StepNavItem } from '../../elements/StepNav/types';
|
||||
import Meta from '../../utilities/Meta';
|
||||
import { LocaleOption, CompareOption, Props } from './types';
|
||||
import CompareRevision from './Compare';
|
||||
import CompareVersion from './Compare';
|
||||
import { publishedVersionOption } from './shared';
|
||||
import Restore from './Restore';
|
||||
import SelectLocales from './SelectLocales';
|
||||
@@ -21,19 +21,19 @@ import { FieldPermissions } from '../../../../auth';
|
||||
|
||||
import './index.scss';
|
||||
|
||||
const baseClass = 'view-revision';
|
||||
const baseClass = 'view-version';
|
||||
|
||||
const RevisionView: React.FC<Props> = ({ collection, global }) => {
|
||||
const VersionView: React.FC<Props> = ({ collection, global }) => {
|
||||
const { serverURL, routes: { admin, api }, admin: { dateFormat }, localization } = useConfig();
|
||||
const { setStepNav } = useStepNav();
|
||||
const { params: { id, revisionID } } = useRouteMatch<{ id?: string, revisionID: string }>();
|
||||
const { params: { id, versionID } } = useRouteMatch<{ id?: string, versionID: string }>();
|
||||
const [compareValue, setCompareValue] = useState<CompareOption>(publishedVersionOption);
|
||||
const [localeOptions] = useState<LocaleOption[]>(() => (localization?.locales ? localization.locales.map((locale) => ({ label: locale, value: locale })) : []));
|
||||
const [locales, setLocales] = useState<LocaleOption[]>(localeOptions);
|
||||
const { permissions } = useAuth();
|
||||
|
||||
let originalDocFetchURL: string;
|
||||
let revisionFetchURL: string;
|
||||
let versionFetchURL: string;
|
||||
let entityLabel: string;
|
||||
let fields: Field[];
|
||||
let fieldPermissions: Record<string, FieldPermissions>;
|
||||
@@ -44,8 +44,8 @@ const RevisionView: React.FC<Props> = ({ collection, global }) => {
|
||||
if (collection) {
|
||||
({ slug } = collection);
|
||||
originalDocFetchURL = `${serverURL}${api}/${slug}/${id}`;
|
||||
revisionFetchURL = `${serverURL}${api}/${slug}/revisions/${revisionID}`;
|
||||
compareBaseURL = `${serverURL}${api}/${slug}/revisions`;
|
||||
versionFetchURL = `${serverURL}${api}/${slug}/versions/${versionID}`;
|
||||
compareBaseURL = `${serverURL}${api}/${slug}/versions`;
|
||||
entityLabel = collection.labels.singular;
|
||||
parentID = id;
|
||||
fields = collection.fields;
|
||||
@@ -55,8 +55,8 @@ const RevisionView: React.FC<Props> = ({ collection, global }) => {
|
||||
if (global) {
|
||||
({ slug } = global);
|
||||
originalDocFetchURL = `${serverURL}${api}/globals/${slug}`;
|
||||
revisionFetchURL = `${serverURL}${api}/globals/${slug}/revisions/${revisionID}`;
|
||||
compareBaseURL = `${serverURL}${api}/globals/${slug}/revisions`;
|
||||
versionFetchURL = `${serverURL}${api}/globals/${slug}/versions/${versionID}`;
|
||||
compareBaseURL = `${serverURL}${api}/globals/${slug}/versions`;
|
||||
entityLabel = global.label;
|
||||
fields = global.fields;
|
||||
fieldPermissions = permissions.globals[global.slug].fields;
|
||||
@@ -65,7 +65,7 @@ const RevisionView: React.FC<Props> = ({ collection, global }) => {
|
||||
const useAsTitle = collection?.admin?.useAsTitle || 'id';
|
||||
const compareFetchURL = compareValue?.value === 'published' ? originalDocFetchURL : `${compareBaseURL}/${compareValue.value}`;
|
||||
|
||||
const [{ data: doc, isLoading }] = usePayloadAPI(revisionFetchURL, { initialParams: { locale: '*', depth: 1 } });
|
||||
const [{ data: doc, isLoading }] = usePayloadAPI(versionFetchURL, { initialParams: { locale: '*', depth: 1 } });
|
||||
const [{ data: originalDoc }] = usePayloadAPI(originalDocFetchURL, { initialParams: { depth: 1 } });
|
||||
const [{ data: compareDoc }] = usePayloadAPI(compareFetchURL, { initialParams: { locale: '*', depth: 1 } });
|
||||
|
||||
@@ -83,8 +83,8 @@ const RevisionView: React.FC<Props> = ({ collection, global }) => {
|
||||
url: `${admin}/collections/${collection.slug}/${id}`,
|
||||
},
|
||||
{
|
||||
label: 'Revisions',
|
||||
url: `${admin}/collections/${collection.slug}/${id}/revisions`,
|
||||
label: 'Versions',
|
||||
url: `${admin}/collections/${collection.slug}/${id}/versions`,
|
||||
},
|
||||
{
|
||||
label: doc?.createdAt ? format(new Date(doc.createdAt), dateFormat) : '',
|
||||
@@ -99,8 +99,8 @@ const RevisionView: React.FC<Props> = ({ collection, global }) => {
|
||||
label: global.label,
|
||||
},
|
||||
{
|
||||
label: 'Revisions',
|
||||
url: `${admin}/globals/${global.slug}/revisions`,
|
||||
label: 'Versions',
|
||||
url: `${admin}/globals/${global.slug}/versions`,
|
||||
},
|
||||
{
|
||||
label: doc?.createdAt ? format(new Date(doc.createdAt), dateFormat) : '',
|
||||
@@ -116,13 +116,13 @@ const RevisionView: React.FC<Props> = ({ collection, global }) => {
|
||||
const formattedCreatedAt = doc?.createdAt ? format(new Date(doc.createdAt), dateFormat) : '';
|
||||
|
||||
if (collection) {
|
||||
metaTitle = `Revision - ${formattedCreatedAt} - ${doc[useAsTitle]} - ${entityLabel}`;
|
||||
metaDesc = `Viewing revision for the ${entityLabel} ${doc[useAsTitle]}`;
|
||||
metaTitle = `Version - ${formattedCreatedAt} - ${doc[useAsTitle]} - ${entityLabel}`;
|
||||
metaDesc = `Viewing version for the ${entityLabel} ${doc[useAsTitle]}`;
|
||||
}
|
||||
|
||||
if (global) {
|
||||
metaTitle = `Revision - ${formattedCreatedAt} - ${entityLabel}`;
|
||||
metaDesc = `Viewing revision for the global ${entityLabel}`;
|
||||
metaTitle = `Version - ${formattedCreatedAt} - ${entityLabel}`;
|
||||
metaDesc = `Viewing version for the global ${entityLabel}`;
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -133,7 +133,7 @@ const RevisionView: React.FC<Props> = ({ collection, global }) => {
|
||||
/>
|
||||
<Eyebrow />
|
||||
<div className={`${baseClass}__wrap`}>
|
||||
<div className={`${baseClass}__intro`}>Revision created on:</div>
|
||||
<div className={`${baseClass}__intro`}>Version created on:</div>
|
||||
<header className={`${baseClass}__header`}>
|
||||
<h2>
|
||||
{formattedCreatedAt}
|
||||
@@ -143,8 +143,8 @@ const RevisionView: React.FC<Props> = ({ collection, global }) => {
|
||||
collection={collection}
|
||||
global={global}
|
||||
originalDocID={id}
|
||||
revisionID={revisionID}
|
||||
revisionDate={formattedCreatedAt}
|
||||
versionID={versionID}
|
||||
versionDate={formattedCreatedAt}
|
||||
/>
|
||||
</header>
|
||||
<div className={`${baseClass}__controls`}>
|
||||
@@ -155,7 +155,7 @@ const RevisionView: React.FC<Props> = ({ collection, global }) => {
|
||||
value={locales}
|
||||
/>
|
||||
)}
|
||||
<CompareRevision
|
||||
<CompareVersion
|
||||
baseURL={compareBaseURL}
|
||||
parentID={parentID}
|
||||
value={compareValue}
|
||||
@@ -165,14 +165,14 @@ const RevisionView: React.FC<Props> = ({ collection, global }) => {
|
||||
{isLoading && (
|
||||
<Loading />
|
||||
)}
|
||||
{doc?.revision && (
|
||||
{doc?.version && (
|
||||
<RenderFieldsToDiff
|
||||
locales={locales.map((locale) => locale.value)}
|
||||
fields={fields}
|
||||
fieldComponents={fieldComponents}
|
||||
fieldPermissions={fieldPermissions}
|
||||
revision={doc?.revision}
|
||||
comparison={compareValue?.value === 'published' ? compareDoc : compareDoc?.revision}
|
||||
version={doc?.version}
|
||||
comparison={compareValue?.value === 'published' ? compareDoc : compareDoc?.version}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
@@ -180,4 +180,4 @@ const RevisionView: React.FC<Props> = ({ collection, global }) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default RevisionView;
|
||||
export default VersionView;
|
||||
@@ -1,6 +1,6 @@
|
||||
@import '../../../scss/styles.scss';
|
||||
|
||||
.view-revision {
|
||||
.view-version {
|
||||
width: 100%;
|
||||
margin-bottom: base(2);
|
||||
|
||||
@@ -2,12 +2,12 @@ import React, { Suspense, lazy } from 'react';
|
||||
import Loading from '../../elements/Loading';
|
||||
import { Props } from './types';
|
||||
|
||||
const RevisionView = lazy(() => import('./Revision'));
|
||||
const VersionView = lazy(() => import('./Version'));
|
||||
|
||||
const Revision: React.FC<Props> = (props) => (
|
||||
const Version: React.FC<Props> = (props) => (
|
||||
<Suspense fallback={<Loading />}>
|
||||
<RevisionView {...props} />
|
||||
<VersionView {...props} />
|
||||
</Suspense>
|
||||
);
|
||||
|
||||
export default Revision;
|
||||
export default Version;
|
||||
@@ -20,8 +20,8 @@ const CreatedAtCell: React.FC<CreatedAtCellProps> = ({ collection, global, id, d
|
||||
|
||||
let to: string;
|
||||
|
||||
if (collection) to = `${admin}/collections/${collection.slug}/${docID}/revisions/${id}`;
|
||||
if (global) to = `${admin}/globals/${global.slug}/revisions/${id}`;
|
||||
if (collection) to = `${admin}/collections/${collection.slug}/${docID}/versions/${id}`;
|
||||
if (global) to = `${admin}/globals/${global.slug}/versions/${id}`;
|
||||
|
||||
return (
|
||||
<Link to={to}>
|
||||
@@ -61,7 +61,7 @@ export const getColumns = (collection: SanitizedCollectionConfig, global: Saniti
|
||||
components: {
|
||||
Heading: (
|
||||
<SortColumn
|
||||
label="Revision ID"
|
||||
label="Version ID"
|
||||
disable
|
||||
name="id"
|
||||
/>
|
||||
@@ -1,6 +1,6 @@
|
||||
@import '../../../scss/styles.scss';
|
||||
|
||||
.revisions {
|
||||
.versions {
|
||||
width: 100%;
|
||||
margin-bottom: base(2);
|
||||
|
||||
@@ -17,9 +17,9 @@ import { useSearchParams } from '../../utilities/SearchParams';
|
||||
|
||||
import './index.scss';
|
||||
|
||||
const baseClass = 'revisions';
|
||||
const baseClass = 'versions';
|
||||
|
||||
const Revisions: React.FC<Props> = ({ collection, global }) => {
|
||||
const Versions: React.FC<Props> = ({ collection, global }) => {
|
||||
const { serverURL, routes: { admin, api } } = useConfig();
|
||||
const { setStepNav } = useStepNav();
|
||||
const { params: { id } } = useRouteMatch<{ id: string }>();
|
||||
@@ -45,7 +45,7 @@ const Revisions: React.FC<Props> = ({ collection, global }) => {
|
||||
|
||||
const useAsTitle = collection?.admin?.useAsTitle || 'id';
|
||||
const [{ data: doc }] = usePayloadAPI(docURL);
|
||||
const [{ data: revisionsData, isLoading: isLoadingRevisions }, { setParams }] = usePayloadAPI(fetchURL);
|
||||
const [{ data: versionsData, isLoading: isLoadingVersions }, { setParams }] = usePayloadAPI(fetchURL);
|
||||
|
||||
useEffect(() => {
|
||||
let nav: StepNavItem[] = [];
|
||||
@@ -61,7 +61,7 @@ const Revisions: React.FC<Props> = ({ collection, global }) => {
|
||||
url: `${admin}/collections/${collection.slug}/${id}`,
|
||||
},
|
||||
{
|
||||
label: 'Revisions',
|
||||
label: 'Versions',
|
||||
},
|
||||
];
|
||||
}
|
||||
@@ -73,7 +73,7 @@ const Revisions: React.FC<Props> = ({ collection, global }) => {
|
||||
label: global.label,
|
||||
},
|
||||
{
|
||||
label: 'Revisions',
|
||||
label: 'Versions',
|
||||
},
|
||||
];
|
||||
}
|
||||
@@ -96,7 +96,7 @@ const Revisions: React.FC<Props> = ({ collection, global }) => {
|
||||
let fetchURLToSet: string;
|
||||
|
||||
if (collection) {
|
||||
fetchURLToSet = `${serverURL}${api}/${collection.slug}/revisions`;
|
||||
fetchURLToSet = `${serverURL}${api}/${collection.slug}/versions`;
|
||||
params.where = {
|
||||
parent: {
|
||||
equals: id,
|
||||
@@ -105,7 +105,7 @@ const Revisions: React.FC<Props> = ({ collection, global }) => {
|
||||
}
|
||||
|
||||
if (global) {
|
||||
fetchURLToSet = `${serverURL}${api}/globals/${global.slug}/revisions`;
|
||||
fetchURLToSet = `${serverURL}${api}/globals/${global.slug}/versions`;
|
||||
}
|
||||
|
||||
// Performance enhancement
|
||||
@@ -123,14 +123,14 @@ const Revisions: React.FC<Props> = ({ collection, global }) => {
|
||||
let metaTitle: string;
|
||||
|
||||
if (collection) {
|
||||
metaTitle = `Revisions - ${doc[useAsTitle]} - ${entityLabel}`;
|
||||
metaDesc = `Viewing revisions for the ${entityLabel} ${doc[useAsTitle]}`;
|
||||
metaTitle = `Versions - ${doc[useAsTitle]} - ${entityLabel}`;
|
||||
metaDesc = `Viewing versions for the ${entityLabel} ${doc[useAsTitle]}`;
|
||||
heading = doc?.[useAsTitle];
|
||||
}
|
||||
|
||||
if (global) {
|
||||
metaTitle = `Revisions - ${entityLabel}`;
|
||||
metaDesc = `Viewing revisions for the global ${entityLabel}`;
|
||||
metaTitle = `Versions - ${entityLabel}`;
|
||||
metaDesc = `Viewing versions for the global ${entityLabel}`;
|
||||
heading = entityLabel;
|
||||
useIDLabel = false;
|
||||
}
|
||||
@@ -144,7 +144,7 @@ const Revisions: React.FC<Props> = ({ collection, global }) => {
|
||||
<Eyebrow />
|
||||
<div className={`${baseClass}__wrap`}>
|
||||
<header className={`${baseClass}__header`}>
|
||||
<div className={`${baseClass}__intro`}>Showing revisions for:</div>
|
||||
<div className={`${baseClass}__intro`}>Showing versions for:</div>
|
||||
{useIDLabel && (
|
||||
<IDLabel id={doc?.id} />
|
||||
)}
|
||||
@@ -154,36 +154,36 @@ const Revisions: React.FC<Props> = ({ collection, global }) => {
|
||||
</h1>
|
||||
)}
|
||||
</header>
|
||||
{isLoadingRevisions && (
|
||||
{isLoadingVersions && (
|
||||
<Loading />
|
||||
)}
|
||||
{revisionsData?.docs && (
|
||||
{versionsData?.docs && (
|
||||
<React.Fragment>
|
||||
<Table
|
||||
data={revisionsData?.docs}
|
||||
data={versionsData?.docs}
|
||||
columns={tableColumns}
|
||||
/>
|
||||
<div className={`${baseClass}__page-controls`}>
|
||||
<Paginator
|
||||
limit={revisionsData.limit}
|
||||
totalPages={revisionsData.totalPages}
|
||||
page={revisionsData.page}
|
||||
hasPrevPage={revisionsData.hasPrevPage}
|
||||
hasNextPage={revisionsData.hasNextPage}
|
||||
prevPage={revisionsData.prevPage}
|
||||
nextPage={revisionsData.nextPage}
|
||||
limit={versionsData.limit}
|
||||
totalPages={versionsData.totalPages}
|
||||
page={versionsData.page}
|
||||
hasPrevPage={versionsData.hasPrevPage}
|
||||
hasNextPage={versionsData.hasNextPage}
|
||||
prevPage={versionsData.prevPage}
|
||||
nextPage={versionsData.nextPage}
|
||||
numberOfNeighbors={1}
|
||||
/>
|
||||
{revisionsData?.totalDocs > 0 && (
|
||||
{versionsData?.totalDocs > 0 && (
|
||||
<React.Fragment>
|
||||
<div className={`${baseClass}__page-info`}>
|
||||
{(revisionsData.page * revisionsData.limit) - (revisionsData.limit - 1)}
|
||||
{(versionsData.page * versionsData.limit) - (versionsData.limit - 1)}
|
||||
-
|
||||
{revisionsData.totalPages > 1 && revisionsData.totalPages !== revisionsData.page ? (revisionsData.limit * revisionsData.page) : revisionsData.totalDocs}
|
||||
{versionsData.totalPages > 1 && versionsData.totalPages !== versionsData.page ? (versionsData.limit * versionsData.page) : versionsData.totalDocs}
|
||||
{' '}
|
||||
of
|
||||
{' '}
|
||||
{revisionsData.totalDocs}
|
||||
{versionsData.totalDocs}
|
||||
</div>
|
||||
<PerPage
|
||||
limits={collection?.admin?.pagination?.limits}
|
||||
@@ -199,4 +199,4 @@ const Revisions: React.FC<Props> = ({ collection, global }) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default Revisions;
|
||||
export default Versions;
|
||||
@@ -0,0 +1,32 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { SanitizedCollectionConfig } from '../../../../../../collections/config/types';
|
||||
import { useWatchForm, useFormModified } from '../../../../forms/Form/context';
|
||||
|
||||
const Autosave: React.FC<{ collection: SanitizedCollectionConfig}> = ({ collection }) => {
|
||||
const { submit, fields } = useWatchForm();
|
||||
const modified = useFormModified();
|
||||
const [lastSaved, setLastSaved] = useState(() => {
|
||||
const date = new Date();
|
||||
date.setSeconds(date.getSeconds() - 2);
|
||||
return date.getTime();
|
||||
});
|
||||
|
||||
const interval = collection.versions.drafts && collection.versions.drafts.autosave ? collection.versions.drafts.autosave.interval : 5;
|
||||
|
||||
useEffect(() => {
|
||||
const lastSavedDate = new Date(lastSaved);
|
||||
lastSavedDate.setSeconds(lastSavedDate.getSeconds() + interval);
|
||||
const timeToSaveAgain = lastSavedDate.getTime();
|
||||
|
||||
if (Date.now() >= timeToSaveAgain && modified) {
|
||||
setTimeout(() => {
|
||||
console.log('Autosaving');
|
||||
}, 1000);
|
||||
setLastSaved(new Date().getTime());
|
||||
}
|
||||
}, [modified, fields, interval, lastSaved]);
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
export default Autosave;
|
||||
@@ -16,9 +16,10 @@ import fieldTypes from '../../../forms/field-types';
|
||||
import RenderTitle from '../../../elements/RenderTitle';
|
||||
import LeaveWithoutSaving from '../../../modals/LeaveWithoutSaving';
|
||||
import Auth from './Auth';
|
||||
import RevisionsCount from '../../../elements/RevisionsCount';
|
||||
import VersionsCount from '../../../elements/VersionsCount';
|
||||
import Upload from './Upload';
|
||||
import { Props } from './types';
|
||||
import Autosave from './Autosave';
|
||||
|
||||
import './index.scss';
|
||||
|
||||
@@ -51,7 +52,7 @@ const DefaultEditView: React.FC<Props> = (props) => {
|
||||
preview,
|
||||
hideAPIURL,
|
||||
},
|
||||
revisions,
|
||||
versions,
|
||||
timestamps,
|
||||
auth,
|
||||
upload,
|
||||
@@ -158,6 +159,14 @@ const DefaultEditView: React.FC<Props> = (props) => {
|
||||
{!isLoading && (
|
||||
<React.Fragment>
|
||||
<div className={`${baseClass}__sidebar-fields`}>
|
||||
{/* {collection.versions?.drafts && (
|
||||
<Select
|
||||
label="Status"
|
||||
path="_status"
|
||||
name="_status"
|
||||
options={statuses}
|
||||
/>
|
||||
)} */}
|
||||
<RenderFields
|
||||
operation={isEditing ? 'update' : 'create'}
|
||||
readOnly={!hasSavePermission}
|
||||
@@ -189,10 +198,10 @@ const DefaultEditView: React.FC<Props> = (props) => {
|
||||
<div className={`${baseClass}__label`}>ID</div>
|
||||
<div>{id}</div>
|
||||
</li>
|
||||
{revisions && (
|
||||
{versions && (
|
||||
<li>
|
||||
<div className={`${baseClass}__label`}>Revisions</div>
|
||||
<RevisionsCount
|
||||
<div className={`${baseClass}__label`}>Versions</div>
|
||||
<VersionsCount
|
||||
submissionCount={submissionCount}
|
||||
collection={collection}
|
||||
id={id}
|
||||
@@ -223,6 +232,9 @@ const DefaultEditView: React.FC<Props> = (props) => {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{(collection.versions?.drafts && collection.versions.drafts.autosave && hasSavePermission) && (
|
||||
<Autosave collection={collection} />
|
||||
)}
|
||||
</Form>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import React, { useState, useEffect, useCallback } from 'react';
|
||||
import { Redirect, useRouteMatch, useHistory, useLocation } from 'react-router-dom';
|
||||
import { useConfig, useAuth } from '@payloadcms/config-provider';
|
||||
import { useStepNav } from '../../../elements/StepNav';
|
||||
@@ -43,7 +43,7 @@ const EditView: React.FC<IndexProps> = (props) => {
|
||||
const [initialState, setInitialState] = useState({});
|
||||
const { permissions } = useAuth();
|
||||
|
||||
const onSave = async (json) => {
|
||||
const onSave = useCallback(async (json: any, version = false) => {
|
||||
if (!isEditing) {
|
||||
history.push(`${admin}/collections/${collection.slug}/${json?.doc?.id}`);
|
||||
} else {
|
||||
@@ -57,7 +57,7 @@ const EditView: React.FC<IndexProps> = (props) => {
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
||||
}, [admin, collection, fields, history, isEditing]);
|
||||
|
||||
const [{ data, isLoading, isError }] = usePayloadAPI(
|
||||
(isEditing ? `${serverURL}${api}/${slug}/${id}` : null),
|
||||
|
||||
@@ -109,8 +109,8 @@ async function accessOperation(this: Payload, args: Arguments): Promise<Permissi
|
||||
collectionOperations.push('unlock');
|
||||
}
|
||||
|
||||
if (collection.revisions) {
|
||||
collectionOperations.push('readRevisions');
|
||||
if (collection.versions) {
|
||||
collectionOperations.push('readVersions');
|
||||
}
|
||||
|
||||
executeEntityPolicies(collection, collectionOperations, 'collections');
|
||||
@@ -119,8 +119,8 @@ async function accessOperation(this: Payload, args: Arguments): Promise<Permissi
|
||||
config.globals.forEach((global) => {
|
||||
const globalOperations = ['read', 'update'];
|
||||
|
||||
if (global.revisions) {
|
||||
globalOperations.push('readRevisions');
|
||||
if (global.versions) {
|
||||
globalOperations.push('readVersions');
|
||||
}
|
||||
executeEntityPolicies(global, globalOperations, 'globals');
|
||||
});
|
||||
|
||||
@@ -34,7 +34,7 @@ export const defaults = {
|
||||
},
|
||||
auth: false,
|
||||
upload: false,
|
||||
revisions: false,
|
||||
versions: false,
|
||||
};
|
||||
|
||||
export const authDefaults = {
|
||||
|
||||
@@ -10,6 +10,8 @@ import getBaseUploadFields from '../../uploads/getBaseFields';
|
||||
import { formatLabels } from '../../utilities/formatLabels';
|
||||
import { defaults, authDefaults } from './defaults';
|
||||
import { Config } from '../../config/types';
|
||||
import { versionCollectionDefaults } from '../../versions/defaults';
|
||||
import baseVersionFields from '../../versions/baseFields';
|
||||
|
||||
const mergeBaseFields = (fields, baseFields) => {
|
||||
const mergedFields = [];
|
||||
@@ -64,8 +66,21 @@ const sanitizeCollection = (config: Config, collection: CollectionConfig): Sanit
|
||||
sanitized.slug = toKebabCase(sanitized.slug);
|
||||
sanitized.labels = sanitized.labels || formatLabels(sanitized.slug);
|
||||
|
||||
if (sanitized.revisions) {
|
||||
if (sanitized.revisions === true) sanitized.revisions = {};
|
||||
if (sanitized.versions) {
|
||||
if (sanitized.versions === true) sanitized.versions = {};
|
||||
|
||||
// const defaultsToMerge = { ... };
|
||||
|
||||
// if (sanitized.versions.drafts === false) {
|
||||
// defaultsToMerge.drafts = false;
|
||||
// } else {
|
||||
// sanitized.fields = [
|
||||
// ...sanitized.fields,
|
||||
// ...baseVersionFields,
|
||||
// ];
|
||||
// }
|
||||
|
||||
sanitized.versions = merge(versionCollectionDefaults, sanitized.versions);
|
||||
}
|
||||
|
||||
if (sanitized.upload) {
|
||||
|
||||
@@ -78,7 +78,7 @@ const collectionSchema = joi.object().keys({
|
||||
}),
|
||||
joi.boolean(),
|
||||
),
|
||||
revisions: joi.alternatives().try(
|
||||
versions: joi.alternatives().try(
|
||||
joi.object({
|
||||
maxPerDoc: joi.number(),
|
||||
retainDeleted: joi.boolean(),
|
||||
|
||||
@@ -6,7 +6,7 @@ import { Field } from '../../fields/config/types';
|
||||
import { PayloadRequest } from '../../express/types';
|
||||
import { IncomingAuthType, Auth } from '../../auth/types';
|
||||
import { IncomingUploadType, Upload } from '../../uploads/types';
|
||||
import { IncomingCollectionRevisionsType } from '../../revisions/types';
|
||||
import { IncomingCollectionVersions, SanitizedCollectionVersions } from '../../versions/types';
|
||||
|
||||
export interface CollectionModel extends PaginateModel<any>, PassportLocalModel<any> {
|
||||
buildQuery: (query: unknown, locale?: string) => Record<string, unknown>
|
||||
@@ -193,7 +193,7 @@ export type CollectionConfig = {
|
||||
delete?: Access;
|
||||
admin?: (args?: any) => boolean;
|
||||
unlock?: Access;
|
||||
readRevisions?: Access;
|
||||
readVersions?: Access;
|
||||
};
|
||||
/**
|
||||
* Collection login options
|
||||
@@ -205,15 +205,15 @@ export type CollectionConfig = {
|
||||
* Upload options
|
||||
*/
|
||||
upload?: IncomingUploadType | boolean;
|
||||
revisions?: IncomingCollectionRevisionsType | boolean;
|
||||
versions?: IncomingCollectionVersions | boolean;
|
||||
timestamps?: boolean
|
||||
};
|
||||
|
||||
export interface SanitizedCollectionConfig extends Omit<DeepRequired<CollectionConfig>, 'auth' | 'upload' | 'fields' | 'revisions'> {
|
||||
export interface SanitizedCollectionConfig extends Omit<DeepRequired<CollectionConfig>, 'auth' | 'upload' | 'fields' | 'versions'> {
|
||||
auth: Auth;
|
||||
upload: Upload;
|
||||
fields: Field[];
|
||||
revisions: IncomingCollectionRevisionsType
|
||||
versions: SanitizedCollectionVersions
|
||||
}
|
||||
|
||||
export type Collection = {
|
||||
|
||||
@@ -5,7 +5,7 @@ import passport from 'passport';
|
||||
import passportLocalMongoose from 'passport-local-mongoose';
|
||||
import Passport from 'passport-local';
|
||||
import { UpdateQuery } from 'mongodb';
|
||||
import { buildRevisionCollectionFields } from '../revisions/buildCollectionFields';
|
||||
import { buildVersionCollectionFields } from '../versions/buildCollectionFields';
|
||||
import buildQueryPlugin from '../mongoose/buildQuery';
|
||||
import apiKeyStrategy from '../auth/strategies/apiKey';
|
||||
import buildCollectionSchema from './buildSchema';
|
||||
@@ -13,7 +13,7 @@ import buildSchema from '../mongoose/buildSchema';
|
||||
import bindCollectionMiddleware from './bindCollection';
|
||||
import { CollectionModel, SanitizedCollectionConfig } from './config/types';
|
||||
import { Payload } from '../index';
|
||||
import { getRevisionsModelName } from '../revisions/getRevisionsModelName';
|
||||
import { getVersionsModelName } from '../versions/getVersionsModelName';
|
||||
|
||||
const LocalStrategy = Passport.Strategy;
|
||||
|
||||
@@ -66,12 +66,12 @@ export default function registerCollections(ctx: Payload): void {
|
||||
}
|
||||
}
|
||||
|
||||
if (collection.revisions) {
|
||||
const revisionModelName = getRevisionsModelName(collection);
|
||||
if (collection.versions) {
|
||||
const versionModelName = getVersionsModelName(collection);
|
||||
|
||||
const revisionSchema = buildSchema(
|
||||
const versionSchema = buildSchema(
|
||||
ctx.config,
|
||||
buildRevisionCollectionFields(collection),
|
||||
buildVersionCollectionFields(collection),
|
||||
{
|
||||
disableUnique: true,
|
||||
options: {
|
||||
@@ -80,10 +80,10 @@ export default function registerCollections(ctx: Payload): void {
|
||||
},
|
||||
);
|
||||
|
||||
revisionSchema.plugin(paginate, { useEstimatedCount: true })
|
||||
versionSchema.plugin(paginate, { useEstimatedCount: true })
|
||||
.plugin(buildQueryPlugin);
|
||||
|
||||
ctx.revisions[collection.slug] = mongoose.model(revisionModelName, revisionSchema) as CollectionModel;
|
||||
ctx.versions[collection.slug] = mongoose.model(versionModelName, versionSchema) as CollectionModel;
|
||||
}
|
||||
|
||||
|
||||
@@ -104,9 +104,9 @@ export default function registerCollections(ctx: Payload): void {
|
||||
find,
|
||||
update,
|
||||
findByID,
|
||||
findRevisions,
|
||||
findRevisionByID,
|
||||
restoreRevision,
|
||||
findVersions,
|
||||
findVersionByID,
|
||||
restoreVersion,
|
||||
delete: deleteHandler,
|
||||
} = ctx.requestHandlers.collections;
|
||||
|
||||
@@ -176,13 +176,13 @@ export default function registerCollections(ctx: Payload): void {
|
||||
.post(resetPassword);
|
||||
}
|
||||
|
||||
if (collection.revisions) {
|
||||
router.route(`/${slug}/revisions`)
|
||||
.get(findRevisions);
|
||||
if (collection.versions) {
|
||||
router.route(`/${slug}/versions`)
|
||||
.get(findVersions);
|
||||
|
||||
router.route(`/${slug}/revisions/:id`)
|
||||
.get(findRevisionByID)
|
||||
.post(restoreRevision);
|
||||
router.route(`/${slug}/versions/:id`)
|
||||
.get(findVersionByID)
|
||||
.post(restoreVersion);
|
||||
}
|
||||
|
||||
router.route(`/${slug}`)
|
||||
|
||||
@@ -8,7 +8,7 @@ import { APIError, Forbidden, NotFound } from '../../errors';
|
||||
import executeAccess from '../../auth/executeAccess';
|
||||
import { Where } from '../../types';
|
||||
import { hasWhereAccessResult } from '../../auth/types';
|
||||
import { TypeWithRevision } from '../../revisions/types';
|
||||
import { TypeWithVersion } from '../../versions/types';
|
||||
|
||||
export type Arguments = {
|
||||
collection: Collection
|
||||
@@ -21,7 +21,7 @@ export type Arguments = {
|
||||
depth?: number
|
||||
}
|
||||
|
||||
async function findRevisionByID<T extends TypeWithRevision<T> = any>(this: Payload, args: Arguments): Promise<T> {
|
||||
async function findVersionByID<T extends TypeWithVersion<T> = any>(this: Payload, args: Arguments): Promise<T> {
|
||||
const {
|
||||
depth,
|
||||
collection: {
|
||||
@@ -39,16 +39,16 @@ async function findRevisionByID<T extends TypeWithRevision<T> = any>(this: Paylo
|
||||
} = args;
|
||||
|
||||
if (!id) {
|
||||
throw new APIError('Missing ID of revision.', httpStatus.BAD_REQUEST);
|
||||
throw new APIError('Missing ID of version.', httpStatus.BAD_REQUEST);
|
||||
}
|
||||
|
||||
const RevisionsModel = (this.revisions[collectionConfig.slug]) as CollectionModel;
|
||||
const VersionsModel = (this.versions[collectionConfig.slug]) as CollectionModel;
|
||||
|
||||
// /////////////////////////////////////
|
||||
// Access
|
||||
// /////////////////////////////////////
|
||||
|
||||
const accessResults = !overrideAccess ? await executeAccess({ req, disableErrors, id }, collectionConfig.access.readRevisions) : true;
|
||||
const accessResults = !overrideAccess ? await executeAccess({ req, disableErrors, id }, collectionConfig.access.readVersions) : true;
|
||||
|
||||
// If errors are disabled, and access returns false, return null
|
||||
if (accessResults === false) return null;
|
||||
@@ -71,7 +71,7 @@ async function findRevisionByID<T extends TypeWithRevision<T> = any>(this: Paylo
|
||||
(queryToBuild.where.and as Where[]).push(accessResults);
|
||||
}
|
||||
|
||||
const query = await RevisionsModel.buildQuery(queryToBuild, locale);
|
||||
const query = await VersionsModel.buildQuery(queryToBuild, locale);
|
||||
|
||||
// /////////////////////////////////////
|
||||
// Find by ID
|
||||
@@ -79,7 +79,7 @@ async function findRevisionByID<T extends TypeWithRevision<T> = any>(this: Paylo
|
||||
|
||||
if (!query.$and[0]._id) throw new NotFound();
|
||||
|
||||
let result = await RevisionsModel.findOne(query, {}).lean();
|
||||
let result = await VersionsModel.findOne(query, {}).lean();
|
||||
|
||||
if (!result) {
|
||||
if (!disableErrors) {
|
||||
@@ -102,22 +102,22 @@ async function findRevisionByID<T extends TypeWithRevision<T> = any>(this: Paylo
|
||||
await collectionConfig.hooks.beforeRead.reduce(async (priorHook, hook) => {
|
||||
await priorHook;
|
||||
|
||||
result.revision = await hook({
|
||||
result.version = await hook({
|
||||
req,
|
||||
query,
|
||||
doc: result.revision,
|
||||
}) || result.revision;
|
||||
doc: result.version,
|
||||
}) || result.version;
|
||||
}, Promise.resolve());
|
||||
|
||||
// /////////////////////////////////////
|
||||
// afterRead - Fields
|
||||
// /////////////////////////////////////
|
||||
|
||||
result.revision = await this.performFieldOperations(collectionConfig, {
|
||||
result.version = await this.performFieldOperations(collectionConfig, {
|
||||
depth,
|
||||
req,
|
||||
id,
|
||||
data: result.revision,
|
||||
data: result.version,
|
||||
hook: 'afterRead',
|
||||
operation: 'read',
|
||||
currentDepth,
|
||||
@@ -133,11 +133,11 @@ async function findRevisionByID<T extends TypeWithRevision<T> = any>(this: Paylo
|
||||
await collectionConfig.hooks.afterRead.reduce(async (priorHook, hook) => {
|
||||
await priorHook;
|
||||
|
||||
result.revision = await hook({
|
||||
result.version = await hook({
|
||||
req,
|
||||
query,
|
||||
doc: result.revision,
|
||||
}) || result.revision;
|
||||
doc: result.version,
|
||||
}) || result.version;
|
||||
}, Promise.resolve());
|
||||
|
||||
// /////////////////////////////////////
|
||||
@@ -147,4 +147,4 @@ async function findRevisionByID<T extends TypeWithRevision<T> = any>(this: Paylo
|
||||
return result;
|
||||
}
|
||||
|
||||
export default findRevisionByID;
|
||||
export default findVersionByID;
|
||||
@@ -7,7 +7,7 @@ import { hasWhereAccessResult } from '../../auth/types';
|
||||
import flattenWhereConstraints from '../../utilities/flattenWhereConstraints';
|
||||
import { buildSortParam } from '../../mongoose/buildSortParam';
|
||||
import { PaginatedDocs } from '../../mongoose/types';
|
||||
import { TypeWithRevision } from '../../revisions/types';
|
||||
import { TypeWithVersion } from '../../versions/types';
|
||||
import { Payload } from '../../index';
|
||||
|
||||
export type Arguments = {
|
||||
@@ -22,7 +22,7 @@ export type Arguments = {
|
||||
showHiddenFields?: boolean
|
||||
}
|
||||
|
||||
async function findRevisions<T extends TypeWithRevision<T> = any>(this: Payload, args: Arguments): Promise<PaginatedDocs<T>> {
|
||||
async function findVersions<T extends TypeWithVersion<T> = any>(this: Payload, args: Arguments): Promise<PaginatedDocs<T>> {
|
||||
const {
|
||||
where,
|
||||
page,
|
||||
@@ -39,7 +39,7 @@ async function findRevisions<T extends TypeWithRevision<T> = any>(this: Payload,
|
||||
showHiddenFields,
|
||||
} = args;
|
||||
|
||||
const RevisionsModel = this.revisions[collectionConfig.slug] as CollectionModel;
|
||||
const VersionsModel = this.versions[collectionConfig.slug] as CollectionModel;
|
||||
|
||||
// /////////////////////////////////////
|
||||
// Access
|
||||
@@ -67,7 +67,7 @@ async function findRevisions<T extends TypeWithRevision<T> = any>(this: Payload,
|
||||
}
|
||||
|
||||
if (!overrideAccess) {
|
||||
const accessResults = await executeAccess({ req }, collectionConfig.access.readRevisions);
|
||||
const accessResults = await executeAccess({ req }, collectionConfig.access.readVersions);
|
||||
|
||||
if (hasWhereAccessResult(accessResults)) {
|
||||
if (!where) {
|
||||
@@ -82,7 +82,7 @@ async function findRevisions<T extends TypeWithRevision<T> = any>(this: Payload,
|
||||
}
|
||||
}
|
||||
|
||||
const query = await RevisionsModel.buildQuery(queryToBuild, locale);
|
||||
const query = await VersionsModel.buildQuery(queryToBuild, locale);
|
||||
|
||||
// /////////////////////////////////////
|
||||
// Find
|
||||
@@ -101,7 +101,7 @@ async function findRevisions<T extends TypeWithRevision<T> = any>(this: Payload,
|
||||
useEstimatedCount,
|
||||
};
|
||||
|
||||
const paginatedDocs = await RevisionsModel.paginate(query, optionsToExecute);
|
||||
const paginatedDocs = await VersionsModel.paginate(query, optionsToExecute);
|
||||
|
||||
// /////////////////////////////////////
|
||||
// beforeRead - Collection
|
||||
@@ -116,7 +116,7 @@ async function findRevisions<T extends TypeWithRevision<T> = any>(this: Payload,
|
||||
await collectionConfig.hooks.beforeRead.reduce(async (priorHook, hook) => {
|
||||
await priorHook;
|
||||
|
||||
docRef.revision = await hook({ req, query, doc: docRef.revision }) || docRef.revision;
|
||||
docRef.version = await hook({ req, query, doc: docRef.version }) || docRef.version;
|
||||
}, Promise.resolve());
|
||||
|
||||
return docRef;
|
||||
@@ -131,19 +131,19 @@ async function findRevisions<T extends TypeWithRevision<T> = any>(this: Payload,
|
||||
...result,
|
||||
docs: await Promise.all(result.docs.map(async (data) => ({
|
||||
...data,
|
||||
revision: await this.performFieldOperations(
|
||||
version: await this.performFieldOperations(
|
||||
collectionConfig,
|
||||
{
|
||||
depth,
|
||||
data: data.revision,
|
||||
data: data.version,
|
||||
req,
|
||||
id: data.revision.id,
|
||||
id: data.version.id,
|
||||
hook: 'afterRead',
|
||||
operation: 'read',
|
||||
overrideAccess,
|
||||
flattenLocales: true,
|
||||
showHiddenFields,
|
||||
isRevision: true,
|
||||
isVersion: true,
|
||||
},
|
||||
),
|
||||
}))),
|
||||
@@ -161,7 +161,7 @@ async function findRevisions<T extends TypeWithRevision<T> = any>(this: Payload,
|
||||
await collectionConfig.hooks.afterRead.reduce(async (priorHook, hook) => {
|
||||
await priorHook;
|
||||
|
||||
docRef.revision = await hook({ req, query, doc: doc.revision }) || doc.revision;
|
||||
docRef.version = await hook({ req, query, doc: doc.version }) || doc.version;
|
||||
}, Promise.resolve());
|
||||
|
||||
return docRef;
|
||||
@@ -180,4 +180,4 @@ async function findRevisions<T extends TypeWithRevision<T> = any>(this: Payload,
|
||||
return result;
|
||||
}
|
||||
|
||||
export default findRevisions;
|
||||
export default findVersions;
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Document } from '../../../types';
|
||||
import { PayloadRequest } from '../../../express/types';
|
||||
import { TypeWithRevision } from '../../../revisions/types';
|
||||
import { TypeWithVersion } from '../../../versions/types';
|
||||
|
||||
export type Options = {
|
||||
collection: string
|
||||
@@ -15,7 +15,7 @@ export type Options = {
|
||||
req?: PayloadRequest
|
||||
}
|
||||
|
||||
export default async function findRevisionByID<T extends TypeWithRevision<T> = any>(options: Options): Promise<T> {
|
||||
export default async function findVersionByID<T extends TypeWithVersion<T> = any>(options: Options): Promise<T> {
|
||||
const {
|
||||
collection: collectionSlug,
|
||||
depth,
|
||||
@@ -30,7 +30,7 @@ export default async function findRevisionByID<T extends TypeWithRevision<T> = a
|
||||
|
||||
const collection = this.collections[collectionSlug];
|
||||
|
||||
return this.operations.collections.findRevisionByID({
|
||||
return this.operations.collections.findVersionByID({
|
||||
depth,
|
||||
id,
|
||||
collection,
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Document, Where } from '../../../types';
|
||||
import { PaginatedDocs } from '../../../mongoose/types';
|
||||
import { TypeWithRevision } from '../../../revisions/types';
|
||||
import { TypeWithVersion } from '../../../versions/types';
|
||||
|
||||
export type Options = {
|
||||
collection: string
|
||||
@@ -16,7 +16,7 @@ export type Options = {
|
||||
where?: Where
|
||||
}
|
||||
|
||||
export default async function findRevisions<T extends TypeWithRevision<T> = any>(options: Options): Promise<PaginatedDocs<T>> {
|
||||
export default async function findVersions<T extends TypeWithVersion<T> = any>(options: Options): Promise<PaginatedDocs<T>> {
|
||||
const {
|
||||
collection: collectionSlug,
|
||||
depth,
|
||||
@@ -33,7 +33,7 @@ export default async function findRevisions<T extends TypeWithRevision<T> = any>
|
||||
|
||||
const collection = this.collections[collectionSlug];
|
||||
|
||||
return this.operations.collections.findRevisions({
|
||||
return this.operations.collections.findVersions({
|
||||
where,
|
||||
page,
|
||||
limit,
|
||||
@@ -4,9 +4,9 @@ import create from './create';
|
||||
import update from './update';
|
||||
import localDelete from './delete';
|
||||
import auth from '../../../auth/operations/local';
|
||||
import findRevisionByID from './findRevisionByID';
|
||||
import findRevisions from './findRevisions';
|
||||
import restoreRevision from './restoreRevision';
|
||||
import findVersionByID from './findVersionByID';
|
||||
import findVersions from './findVersions';
|
||||
import restoreVersion from './restoreVersion';
|
||||
|
||||
export default {
|
||||
find,
|
||||
@@ -15,7 +15,7 @@ export default {
|
||||
update,
|
||||
localDelete,
|
||||
auth,
|
||||
findRevisionByID,
|
||||
findRevisions,
|
||||
restoreRevision,
|
||||
findVersionByID,
|
||||
findVersions,
|
||||
restoreVersion,
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Document } from '../../../types';
|
||||
import { TypeWithRevision } from '../../../revisions/types';
|
||||
import { TypeWithVersion } from '../../../versions/types';
|
||||
|
||||
export type Options = {
|
||||
collection: string
|
||||
@@ -13,7 +13,7 @@ export type Options = {
|
||||
showHiddenFields?: boolean
|
||||
}
|
||||
|
||||
export default async function restoreRevision<T extends TypeWithRevision<T> = any>(options: Options): Promise<T> {
|
||||
export default async function restoreVersion<T extends TypeWithVersion<T> = any>(options: Options): Promise<T> {
|
||||
const {
|
||||
collection: collectionSlug,
|
||||
depth,
|
||||
@@ -44,5 +44,5 @@ export default async function restoreRevision<T extends TypeWithRevision<T> = an
|
||||
},
|
||||
};
|
||||
|
||||
return this.operations.collections.restoreRevision(args);
|
||||
return this.operations.collections.restoreVersion(args);
|
||||
}
|
||||
@@ -21,7 +21,7 @@ export type Arguments = {
|
||||
depth?: number
|
||||
}
|
||||
|
||||
async function restoreRevision<T extends TypeWithID = any>(this: Payload, args: Arguments): Promise<T> {
|
||||
async function restoreVersion<T extends TypeWithID = any>(this: Payload, args: Arguments): Promise<T> {
|
||||
const {
|
||||
collection: {
|
||||
Model,
|
||||
@@ -38,26 +38,26 @@ async function restoreRevision<T extends TypeWithID = any>(this: Payload, args:
|
||||
} = args;
|
||||
|
||||
if (!id) {
|
||||
throw new APIError('Missing ID of revision to restore.', httpStatus.BAD_REQUEST);
|
||||
throw new APIError('Missing ID of version to restore.', httpStatus.BAD_REQUEST);
|
||||
}
|
||||
|
||||
// /////////////////////////////////////
|
||||
// Retrieve original raw revision to get parent ID
|
||||
// Retrieve original raw version to get parent ID
|
||||
// /////////////////////////////////////
|
||||
|
||||
const RevisionModel = this.revisions[collectionConfig.slug];
|
||||
const VersionModel = this.versions[collectionConfig.slug];
|
||||
|
||||
let rawRevision = await RevisionModel.findOne({
|
||||
let rawVersion = await VersionModel.findOne({
|
||||
_id: id,
|
||||
});
|
||||
|
||||
if (!rawRevision) {
|
||||
if (!rawVersion) {
|
||||
throw new NotFound();
|
||||
}
|
||||
|
||||
rawRevision = rawRevision.toJSON({ virtuals: true });
|
||||
rawVersion = rawVersion.toJSON({ virtuals: true });
|
||||
|
||||
const parentDocID = rawRevision.parent;
|
||||
const parentDocID = rawVersion.parent;
|
||||
|
||||
// /////////////////////////////////////
|
||||
// Access
|
||||
@@ -99,7 +99,7 @@ async function restoreRevision<T extends TypeWithID = any>(this: Payload, args:
|
||||
|
||||
let result = await Model.findByIdAndUpdate(
|
||||
{ _id: parentDocID },
|
||||
rawRevision.revision,
|
||||
rawVersion.version,
|
||||
{ new: true },
|
||||
);
|
||||
|
||||
@@ -172,4 +172,4 @@ async function restoreRevision<T extends TypeWithID = any>(this: Payload, args:
|
||||
return result;
|
||||
}
|
||||
|
||||
export default restoreRevision;
|
||||
export default restoreVersion;
|
||||
@@ -18,7 +18,7 @@ import { FileData } from '../../uploads/types';
|
||||
import { PayloadRequest } from '../../express/types';
|
||||
import { hasWhereAccessResult, UserDocument } from '../../auth/types';
|
||||
import saveBufferToFile from '../../uploads/saveBufferToFile';
|
||||
import { saveCollectionRevision } from '../../revisions/saveCollectionRevision';
|
||||
import { saveCollectionVersion } from '../../versions/saveCollectionVersion';
|
||||
|
||||
export type Arguments = {
|
||||
collection: Collection
|
||||
@@ -286,11 +286,11 @@ async function update(this: Payload, incomingArgs: Arguments): Promise<Document>
|
||||
result = sanitizeInternalFields(result);
|
||||
|
||||
// /////////////////////////////////////
|
||||
// Create revision from existing doc
|
||||
// Create version from existing doc
|
||||
// /////////////////////////////////////
|
||||
|
||||
if (collectionConfig.revisions) {
|
||||
saveCollectionRevision({
|
||||
if (collectionConfig.versions) {
|
||||
saveCollectionVersion({
|
||||
payload: this,
|
||||
config: collectionConfig,
|
||||
req,
|
||||
|
||||
@@ -7,7 +7,7 @@ export type FindByIDResult = {
|
||||
doc: Document;
|
||||
};
|
||||
|
||||
export default async function findRevisionByID(req: PayloadRequest, res: Response, next: NextFunction): Promise<Response<FindByIDResult> | void> {
|
||||
export default async function findVersionByID(req: PayloadRequest, res: Response, next: NextFunction): Promise<Response<FindByIDResult> | void> {
|
||||
const options = {
|
||||
req,
|
||||
collection: req.collection,
|
||||
@@ -16,7 +16,7 @@ export default async function findRevisionByID(req: PayloadRequest, res: Respons
|
||||
};
|
||||
|
||||
try {
|
||||
const doc = await this.operations.collections.findRevisionByID(options);
|
||||
const doc = await this.operations.collections.findVersionByID(options);
|
||||
return res.json(doc);
|
||||
} catch (error) {
|
||||
return next(error);
|
||||
@@ -4,7 +4,7 @@ import { PayloadRequest } from '../../express/types';
|
||||
import { TypeWithID } from '../config/types';
|
||||
import { PaginatedDocs } from '../../mongoose/types';
|
||||
|
||||
export default async function findRevisions<T extends TypeWithID = any>(req: PayloadRequest, res: Response, next: NextFunction): Promise<Response<PaginatedDocs<T>> | void> {
|
||||
export default async function findVersions<T extends TypeWithID = any>(req: PayloadRequest, res: Response, next: NextFunction): Promise<Response<PaginatedDocs<T>> | void> {
|
||||
try {
|
||||
let page;
|
||||
|
||||
@@ -26,7 +26,7 @@ export default async function findRevisions<T extends TypeWithID = any>(req: Pay
|
||||
depth: req.query.depth,
|
||||
};
|
||||
|
||||
const result = await this.operations.collections.findRevisions(options);
|
||||
const result = await this.operations.collections.findVersions(options);
|
||||
|
||||
return res.status(httpStatus.OK).json(result);
|
||||
} catch (error) {
|
||||
@@ -9,7 +9,7 @@ export type RestoreResult = {
|
||||
doc: Document
|
||||
};
|
||||
|
||||
export default async function restoreRevision(req: PayloadRequest, res: Response, next: NextFunction): Promise<Response<RestoreResult> | void> {
|
||||
export default async function restoreVersion(req: PayloadRequest, res: Response, next: NextFunction): Promise<Response<RestoreResult> | void> {
|
||||
const options = {
|
||||
req,
|
||||
collection: req.collection,
|
||||
@@ -18,7 +18,7 @@ export default async function restoreRevision(req: PayloadRequest, res: Response
|
||||
};
|
||||
|
||||
try {
|
||||
const doc = await this.operations.collections.restoreRevision(options);
|
||||
const doc = await this.operations.collections.restoreVersion(options);
|
||||
return res.status(httpStatus.OK).json({
|
||||
...formatSuccessResponse('Restored successfully.', 'message'),
|
||||
doc,
|
||||
@@ -11,7 +11,7 @@ type Arguments = {
|
||||
fullOriginalDoc: Record<string, unknown>
|
||||
fullData: Record<string, unknown>
|
||||
flattenLocales: boolean
|
||||
isRevision: boolean
|
||||
isVersion: boolean
|
||||
}
|
||||
|
||||
type ExecuteHookArguments = {
|
||||
|
||||
@@ -23,7 +23,7 @@ type Arguments = {
|
||||
showHiddenFields?: boolean
|
||||
depth?: number
|
||||
currentDepth?: number
|
||||
isRevision?: boolean
|
||||
isVersion?: boolean
|
||||
}
|
||||
|
||||
export default async function performFieldOperations(this: Payload, entityConfig: SanitizedCollectionConfig | SanitizedGlobalConfig, args: Arguments): Promise<any> {
|
||||
@@ -43,7 +43,7 @@ export default async function performFieldOperations(this: Payload, entityConfig
|
||||
flattenLocales,
|
||||
unflattenLocales = false,
|
||||
showHiddenFields = false,
|
||||
isRevision = false,
|
||||
isVersion = false,
|
||||
} = args;
|
||||
|
||||
const fullData = deepCopyObject(data);
|
||||
@@ -103,7 +103,7 @@ export default async function performFieldOperations(this: Payload, entityConfig
|
||||
unflattenLocaleActions,
|
||||
transformActions,
|
||||
docWithLocales,
|
||||
isRevision,
|
||||
isVersion,
|
||||
});
|
||||
|
||||
if (hook === 'afterRead') {
|
||||
|
||||
@@ -36,7 +36,7 @@ type Arguments = {
|
||||
transformActions: (() => void)[]
|
||||
docWithLocales?: Record<string, any>
|
||||
skipValidation?: boolean
|
||||
isRevision: boolean
|
||||
isVersion: boolean
|
||||
}
|
||||
|
||||
const traverseFields = (args: Arguments): void => {
|
||||
@@ -69,7 +69,7 @@ const traverseFields = (args: Arguments): void => {
|
||||
transformActions,
|
||||
docWithLocales = {},
|
||||
skipValidation,
|
||||
isRevision,
|
||||
isVersion,
|
||||
} = args;
|
||||
|
||||
fields.forEach((field) => {
|
||||
@@ -226,7 +226,7 @@ const traverseFields = (args: Arguments): void => {
|
||||
fullOriginalDoc,
|
||||
fullData,
|
||||
flattenLocales,
|
||||
isRevision,
|
||||
isVersion,
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
@@ -19,11 +19,11 @@ const globalSchema = joi.object().keys({
|
||||
}),
|
||||
access: joi.object({
|
||||
read: joi.func(),
|
||||
readRevisions: joi.func(),
|
||||
readVersions: joi.func(),
|
||||
update: joi.func(),
|
||||
}),
|
||||
fields: joi.array(),
|
||||
revisions: joi.alternatives().try(
|
||||
versions: joi.alternatives().try(
|
||||
joi.object({
|
||||
max: joi.number(),
|
||||
drafts: joi.alternatives().try(
|
||||
|
||||
@@ -4,7 +4,7 @@ import { DeepRequired } from 'ts-essentials';
|
||||
import { PayloadRequest } from '../../express/types';
|
||||
import { Access, GeneratePreviewURL } from '../../config/types';
|
||||
import { Field } from '../../fields/config/types';
|
||||
import { IncomingGlobalRevisionsType } from '../../revisions/types';
|
||||
import { IncomingGlobalVersions } from '../../versions/types';
|
||||
|
||||
export type TypeWithID = {
|
||||
id: string
|
||||
@@ -45,7 +45,7 @@ export type GlobalConfig = {
|
||||
slug: string
|
||||
label?: string
|
||||
preview?: GeneratePreviewURL
|
||||
revisions?: IncomingGlobalRevisionsType | boolean
|
||||
versions?: IncomingGlobalVersions | boolean
|
||||
hooks?: {
|
||||
beforeValidate?: BeforeValidateHook[]
|
||||
beforeChange?: BeforeChangeHook[]
|
||||
@@ -55,7 +55,7 @@ export type GlobalConfig = {
|
||||
}
|
||||
access?: {
|
||||
read?: Access;
|
||||
readRevisions?: Access;
|
||||
readVersions?: Access;
|
||||
update?: Access;
|
||||
}
|
||||
fields: Field[];
|
||||
@@ -69,9 +69,9 @@ export type GlobalConfig = {
|
||||
}
|
||||
}
|
||||
|
||||
export interface SanitizedGlobalConfig extends Omit<DeepRequired<GlobalConfig>, 'fields' | 'revisions'> {
|
||||
export interface SanitizedGlobalConfig extends Omit<DeepRequired<GlobalConfig>, 'fields' | 'versions'> {
|
||||
fields: Field[]
|
||||
revisions?: {
|
||||
versions?: {
|
||||
max?: number
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,8 +4,8 @@ import paginate from 'mongoose-paginate-v2';
|
||||
import buildQueryPlugin from '../mongoose/buildQuery';
|
||||
import buildModel from './buildModel';
|
||||
import { Payload } from '../index';
|
||||
import { getRevisionsModelName } from '../revisions/getRevisionsModelName';
|
||||
import { buildRevisionGlobalFields } from '../revisions/buildGlobalFields';
|
||||
import { getVersionsModelName } from '../versions/getVersionsModelName';
|
||||
import { buildVersionGlobalFields } from '../versions/buildGlobalFields';
|
||||
import buildSchema from '../mongoose/buildSchema';
|
||||
import { GlobalModel } from './config/types';
|
||||
|
||||
@@ -17,12 +17,12 @@ export default function initGlobals(ctx: Payload): void {
|
||||
};
|
||||
|
||||
ctx.config.globals.forEach((global) => {
|
||||
if (global.revisions) {
|
||||
const revisionModelName = getRevisionsModelName(global);
|
||||
if (global.versions) {
|
||||
const versionModelName = getVersionsModelName(global);
|
||||
|
||||
const revisionSchema = buildSchema(
|
||||
const versionSchema = buildSchema(
|
||||
ctx.config,
|
||||
buildRevisionGlobalFields(global),
|
||||
buildVersionGlobalFields(global),
|
||||
{
|
||||
disableUnique: true,
|
||||
options: {
|
||||
@@ -31,10 +31,10 @@ export default function initGlobals(ctx: Payload): void {
|
||||
},
|
||||
);
|
||||
|
||||
revisionSchema.plugin(paginate, { useEstimatedCount: true })
|
||||
versionSchema.plugin(paginate, { useEstimatedCount: true })
|
||||
.plugin(buildQueryPlugin);
|
||||
|
||||
ctx.revisions[global.slug] = mongoose.model(revisionModelName, revisionSchema) as GlobalModel;
|
||||
ctx.versions[global.slug] = mongoose.model(versionModelName, versionSchema) as GlobalModel;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -48,13 +48,13 @@ export default function initGlobals(ctx: Payload): void {
|
||||
.get(ctx.requestHandlers.globals.findOne(global))
|
||||
.post(ctx.requestHandlers.globals.update(global));
|
||||
|
||||
if (global.revisions) {
|
||||
router.route(`/globals/${global.slug}/revisions`)
|
||||
.get(ctx.requestHandlers.globals.findRevisions(global));
|
||||
if (global.versions) {
|
||||
router.route(`/globals/${global.slug}/versions`)
|
||||
.get(ctx.requestHandlers.globals.findVersions(global));
|
||||
|
||||
router.route(`/globals/${global.slug}/revisions/:id`)
|
||||
.get(ctx.requestHandlers.globals.findRevisionByID(global))
|
||||
.post(ctx.requestHandlers.globals.restoreRevision(global));
|
||||
router.route(`/globals/${global.slug}/versions/:id`)
|
||||
.get(ctx.requestHandlers.globals.findVersionByID(global))
|
||||
.post(ctx.requestHandlers.globals.restoreVersion(global));
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import { Forbidden, NotFound } from '../../errors';
|
||||
import executeAccess from '../../auth/executeAccess';
|
||||
import { Where } from '../../types';
|
||||
import { hasWhereAccessResult } from '../../auth/types';
|
||||
import { TypeWithRevision } from '../../revisions/types';
|
||||
import { TypeWithVersion } from '../../versions/types';
|
||||
import { SanitizedGlobalConfig } from '../config/types';
|
||||
|
||||
export type Arguments = {
|
||||
@@ -19,7 +19,7 @@ export type Arguments = {
|
||||
depth?: number
|
||||
}
|
||||
|
||||
async function findRevisionByID<T extends TypeWithRevision<T> = any>(args: Arguments): Promise<T> {
|
||||
async function findVersionByID<T extends TypeWithVersion<T> = any>(args: Arguments): Promise<T> {
|
||||
const {
|
||||
depth,
|
||||
globalConfig,
|
||||
@@ -34,13 +34,13 @@ async function findRevisionByID<T extends TypeWithRevision<T> = any>(args: Argum
|
||||
showHiddenFields,
|
||||
} = args;
|
||||
|
||||
const RevisionsModel = this.revisions[globalConfig.slug];
|
||||
const VersionsModel = this.versions[globalConfig.slug];
|
||||
|
||||
// /////////////////////////////////////
|
||||
// Access
|
||||
// /////////////////////////////////////
|
||||
|
||||
const accessResults = !overrideAccess ? await executeAccess({ req, disableErrors, id }, globalConfig.access.readRevisions) : true;
|
||||
const accessResults = !overrideAccess ? await executeAccess({ req, disableErrors, id }, globalConfig.access.readVersions) : true;
|
||||
|
||||
// If errors are disabled, and access returns false, return null
|
||||
if (accessResults === false) return null;
|
||||
@@ -63,7 +63,7 @@ async function findRevisionByID<T extends TypeWithRevision<T> = any>(args: Argum
|
||||
(queryToBuild.where.and as Where[]).push(accessResults);
|
||||
}
|
||||
|
||||
const query = await RevisionsModel.buildQuery(queryToBuild, locale);
|
||||
const query = await VersionsModel.buildQuery(queryToBuild, locale);
|
||||
|
||||
// /////////////////////////////////////
|
||||
// Find by ID
|
||||
@@ -71,7 +71,7 @@ async function findRevisionByID<T extends TypeWithRevision<T> = any>(args: Argum
|
||||
|
||||
if (!query.$and[0]._id) throw new NotFound();
|
||||
|
||||
let result = await RevisionsModel.findOne(query, {}).lean();
|
||||
let result = await VersionsModel.findOne(query, {}).lean();
|
||||
|
||||
if (!result) {
|
||||
if (!disableErrors) {
|
||||
@@ -94,22 +94,22 @@ async function findRevisionByID<T extends TypeWithRevision<T> = any>(args: Argum
|
||||
await globalConfig.hooks.beforeRead.reduce(async (priorHook, hook) => {
|
||||
await priorHook;
|
||||
|
||||
result.revision = await hook({
|
||||
result.version = await hook({
|
||||
req,
|
||||
query,
|
||||
doc: result.revision,
|
||||
}) || result.revision;
|
||||
doc: result.version,
|
||||
}) || result.version;
|
||||
}, Promise.resolve());
|
||||
|
||||
// /////////////////////////////////////
|
||||
// afterRead - Fields
|
||||
// /////////////////////////////////////
|
||||
|
||||
result.revision = await this.performFieldOperations(globalConfig, {
|
||||
result.version = await this.performFieldOperations(globalConfig, {
|
||||
depth,
|
||||
req,
|
||||
id,
|
||||
data: result.revision,
|
||||
data: result.version,
|
||||
hook: 'afterRead',
|
||||
operation: 'read',
|
||||
currentDepth,
|
||||
@@ -125,11 +125,11 @@ async function findRevisionByID<T extends TypeWithRevision<T> = any>(args: Argum
|
||||
await globalConfig.hooks.afterRead.reduce(async (priorHook, hook) => {
|
||||
await priorHook;
|
||||
|
||||
result.revision = await hook({
|
||||
result.version = await hook({
|
||||
req,
|
||||
query,
|
||||
doc: result.revision,
|
||||
}) || result.revision;
|
||||
doc: result.version,
|
||||
}) || result.version;
|
||||
}, Promise.resolve());
|
||||
|
||||
// /////////////////////////////////////
|
||||
@@ -139,4 +139,4 @@ async function findRevisionByID<T extends TypeWithRevision<T> = any>(args: Argum
|
||||
return result;
|
||||
}
|
||||
|
||||
export default findRevisionByID;
|
||||
export default findVersionByID;
|
||||
@@ -6,7 +6,7 @@ import { PaginatedDocs } from '../../mongoose/types';
|
||||
import { hasWhereAccessResult } from '../../auth/types';
|
||||
import flattenWhereConstraints from '../../utilities/flattenWhereConstraints';
|
||||
import { buildSortParam } from '../../mongoose/buildSortParam';
|
||||
import { TypeWithRevision } from '../../revisions/types';
|
||||
import { TypeWithVersion } from '../../versions/types';
|
||||
import { SanitizedGlobalConfig } from '../config/types';
|
||||
|
||||
export type Arguments = {
|
||||
@@ -21,9 +21,7 @@ export type Arguments = {
|
||||
showHiddenFields?: boolean
|
||||
}
|
||||
|
||||
// TODO: finish
|
||||
|
||||
async function restoreRevision<T extends TypeWithRevision<T> = any>(args: Arguments): Promise<PaginatedDocs<T>> {
|
||||
async function findVersions<T extends TypeWithVersion<T> = any>(args: Arguments): Promise<PaginatedDocs<T>> {
|
||||
const {
|
||||
where,
|
||||
page,
|
||||
@@ -38,7 +36,7 @@ async function restoreRevision<T extends TypeWithRevision<T> = any>(args: Argume
|
||||
showHiddenFields,
|
||||
} = args;
|
||||
|
||||
const RevisionsModel = this.revisions[globalConfig.slug];
|
||||
const VersionsModel = this.versions[globalConfig.slug];
|
||||
|
||||
// /////////////////////////////////////
|
||||
// Access
|
||||
@@ -66,7 +64,7 @@ async function restoreRevision<T extends TypeWithRevision<T> = any>(args: Argume
|
||||
}
|
||||
|
||||
if (!overrideAccess) {
|
||||
const accessResults = await executeAccess({ req }, globalConfig.access.readRevisions);
|
||||
const accessResults = await executeAccess({ req }, globalConfig.access.readVersions);
|
||||
|
||||
if (hasWhereAccessResult(accessResults)) {
|
||||
if (!where) {
|
||||
@@ -81,7 +79,7 @@ async function restoreRevision<T extends TypeWithRevision<T> = any>(args: Argume
|
||||
}
|
||||
}
|
||||
|
||||
const query = await RevisionsModel.buildQuery(queryToBuild, locale);
|
||||
const query = await VersionsModel.buildQuery(queryToBuild, locale);
|
||||
|
||||
// /////////////////////////////////////
|
||||
// Find
|
||||
@@ -100,7 +98,7 @@ async function restoreRevision<T extends TypeWithRevision<T> = any>(args: Argume
|
||||
useEstimatedCount,
|
||||
};
|
||||
|
||||
const paginatedDocs = await RevisionsModel.paginate(query, optionsToExecute);
|
||||
const paginatedDocs = await VersionsModel.paginate(query, optionsToExecute);
|
||||
|
||||
// /////////////////////////////////////
|
||||
// afterRead - Fields
|
||||
@@ -110,19 +108,19 @@ async function restoreRevision<T extends TypeWithRevision<T> = any>(args: Argume
|
||||
...paginatedDocs,
|
||||
docs: await Promise.all(paginatedDocs.docs.map(async (data) => ({
|
||||
...data,
|
||||
revision: await this.performFieldOperations(
|
||||
version: await this.performFieldOperations(
|
||||
globalConfig,
|
||||
{
|
||||
depth,
|
||||
data: data.revision,
|
||||
data: data.version,
|
||||
req,
|
||||
id: data.revision.id,
|
||||
id: data.version.id,
|
||||
hook: 'afterRead',
|
||||
operation: 'read',
|
||||
overrideAccess,
|
||||
flattenLocales: true,
|
||||
showHiddenFields,
|
||||
isRevision: true,
|
||||
isVersion: true,
|
||||
},
|
||||
),
|
||||
}))),
|
||||
@@ -140,7 +138,7 @@ async function restoreRevision<T extends TypeWithRevision<T> = any>(args: Argume
|
||||
await globalConfig.hooks.afterRead.reduce(async (priorHook, hook) => {
|
||||
await priorHook;
|
||||
|
||||
docRef.revision = await hook({ req, query, doc: doc.revision }) || doc.revision;
|
||||
docRef.version = await hook({ req, query, doc: doc.version }) || doc.version;
|
||||
}, Promise.resolve());
|
||||
|
||||
return docRef;
|
||||
@@ -159,4 +157,4 @@ async function restoreRevision<T extends TypeWithRevision<T> = any>(args: Argume
|
||||
return result;
|
||||
}
|
||||
|
||||
export default restoreRevision;
|
||||
export default findVersions;
|
||||
@@ -6,7 +6,7 @@ import { PaginatedDocs } from '../../mongoose/types';
|
||||
import { hasWhereAccessResult } from '../../auth/types';
|
||||
import flattenWhereConstraints from '../../utilities/flattenWhereConstraints';
|
||||
import { buildSortParam } from '../../mongoose/buildSortParam';
|
||||
import { TypeWithRevision } from '../../revisions/types';
|
||||
import { TypeWithVersion } from '../../versions/types';
|
||||
import { SanitizedGlobalConfig } from '../config/types';
|
||||
|
||||
export type Arguments = {
|
||||
@@ -21,7 +21,9 @@ export type Arguments = {
|
||||
showHiddenFields?: boolean
|
||||
}
|
||||
|
||||
async function findRevisions<T extends TypeWithRevision<T> = any>(args: Arguments): Promise<PaginatedDocs<T>> {
|
||||
// TODO: finish
|
||||
|
||||
async function restoreVersion<T extends TypeWithVersion<T> = any>(args: Arguments): Promise<PaginatedDocs<T>> {
|
||||
const {
|
||||
where,
|
||||
page,
|
||||
@@ -36,7 +38,7 @@ async function findRevisions<T extends TypeWithRevision<T> = any>(args: Argument
|
||||
showHiddenFields,
|
||||
} = args;
|
||||
|
||||
const RevisionsModel = this.revisions[globalConfig.slug];
|
||||
const VersionsModel = this.versions[globalConfig.slug];
|
||||
|
||||
// /////////////////////////////////////
|
||||
// Access
|
||||
@@ -64,7 +66,7 @@ async function findRevisions<T extends TypeWithRevision<T> = any>(args: Argument
|
||||
}
|
||||
|
||||
if (!overrideAccess) {
|
||||
const accessResults = await executeAccess({ req }, globalConfig.access.readRevisions);
|
||||
const accessResults = await executeAccess({ req }, globalConfig.access.readVersions);
|
||||
|
||||
if (hasWhereAccessResult(accessResults)) {
|
||||
if (!where) {
|
||||
@@ -79,7 +81,7 @@ async function findRevisions<T extends TypeWithRevision<T> = any>(args: Argument
|
||||
}
|
||||
}
|
||||
|
||||
const query = await RevisionsModel.buildQuery(queryToBuild, locale);
|
||||
const query = await VersionsModel.buildQuery(queryToBuild, locale);
|
||||
|
||||
// /////////////////////////////////////
|
||||
// Find
|
||||
@@ -98,7 +100,7 @@ async function findRevisions<T extends TypeWithRevision<T> = any>(args: Argument
|
||||
useEstimatedCount,
|
||||
};
|
||||
|
||||
const paginatedDocs = await RevisionsModel.paginate(query, optionsToExecute);
|
||||
const paginatedDocs = await VersionsModel.paginate(query, optionsToExecute);
|
||||
|
||||
// /////////////////////////////////////
|
||||
// afterRead - Fields
|
||||
@@ -108,19 +110,19 @@ async function findRevisions<T extends TypeWithRevision<T> = any>(args: Argument
|
||||
...paginatedDocs,
|
||||
docs: await Promise.all(paginatedDocs.docs.map(async (data) => ({
|
||||
...data,
|
||||
revision: await this.performFieldOperations(
|
||||
version: await this.performFieldOperations(
|
||||
globalConfig,
|
||||
{
|
||||
depth,
|
||||
data: data.revision,
|
||||
data: data.version,
|
||||
req,
|
||||
id: data.revision.id,
|
||||
id: data.version.id,
|
||||
hook: 'afterRead',
|
||||
operation: 'read',
|
||||
overrideAccess,
|
||||
flattenLocales: true,
|
||||
showHiddenFields,
|
||||
isRevision: true,
|
||||
isVersion: true,
|
||||
},
|
||||
),
|
||||
}))),
|
||||
@@ -138,7 +140,7 @@ async function findRevisions<T extends TypeWithRevision<T> = any>(args: Argument
|
||||
await globalConfig.hooks.afterRead.reduce(async (priorHook, hook) => {
|
||||
await priorHook;
|
||||
|
||||
docRef.revision = await hook({ req, query, doc: doc.revision }) || doc.revision;
|
||||
docRef.version = await hook({ req, query, doc: doc.version }) || doc.version;
|
||||
}, Promise.resolve());
|
||||
|
||||
return docRef;
|
||||
@@ -157,4 +159,4 @@ async function findRevisions<T extends TypeWithRevision<T> = any>(args: Argument
|
||||
return result;
|
||||
}
|
||||
|
||||
export default findRevisions;
|
||||
export default restoreVersion;
|
||||
@@ -2,7 +2,7 @@ import { Payload } from '../..';
|
||||
import { TypeWithID } from '../config/types';
|
||||
import executeAccess from '../../auth/executeAccess';
|
||||
import sanitizeInternalFields from '../../utilities/sanitizeInternalFields';
|
||||
import { saveGlobalRevision } from '../../revisions/saveGlobalRevision';
|
||||
import { saveGlobalVersion } from '../../versions/saveGlobalVersion';
|
||||
|
||||
async function update<T extends TypeWithID = any>(this: Payload, args): Promise<T> {
|
||||
const { globals: { Model } } = this;
|
||||
@@ -133,11 +133,11 @@ async function update<T extends TypeWithID = any>(this: Payload, args): Promise<
|
||||
global = sanitizeInternalFields(global);
|
||||
|
||||
// /////////////////////////////////////
|
||||
// Create revision from existing doc
|
||||
// Create version from existing doc
|
||||
// /////////////////////////////////////
|
||||
|
||||
if (globalConfig.revisions && hasExistingGlobal) {
|
||||
saveGlobalRevision({
|
||||
if (globalConfig.versions && hasExistingGlobal) {
|
||||
saveGlobalVersion({
|
||||
payload: this,
|
||||
config: globalConfig,
|
||||
req,
|
||||
|
||||
@@ -13,13 +13,13 @@ export default function (globalConfig: SanitizedGlobalConfig) {
|
||||
};
|
||||
|
||||
try {
|
||||
const doc = await this.operations.globals.restoreRevision(options);
|
||||
const doc = await this.operations.globals.findVersionByID(options);
|
||||
return res.json(doc);
|
||||
} catch (error) {
|
||||
return next(error);
|
||||
}
|
||||
}
|
||||
|
||||
const restoreRevisionHandler = handler.bind(this);
|
||||
return restoreRevisionHandler;
|
||||
const findVersionByIDHandler = handler.bind(this);
|
||||
return findVersionByIDHandler;
|
||||
}
|
||||
@@ -28,7 +28,7 @@ export default function (global: SanitizedGlobalConfig) {
|
||||
depth: req.query.depth,
|
||||
};
|
||||
|
||||
const result = await this.operations.globals.findRevisions(options);
|
||||
const result = await this.operations.globals.findVersions(options);
|
||||
|
||||
return res.status(httpStatus.OK).json(result);
|
||||
} catch (error) {
|
||||
@@ -36,7 +36,7 @@ export default function (global: SanitizedGlobalConfig) {
|
||||
}
|
||||
}
|
||||
|
||||
const findRevisionsHandler = handler.bind(this);
|
||||
const findVersionsandler = handler.bind(this);
|
||||
|
||||
return findRevisionsHandler;
|
||||
return findVersionsandler;
|
||||
}
|
||||
@@ -13,13 +13,13 @@ export default function (globalConfig: SanitizedGlobalConfig) {
|
||||
};
|
||||
|
||||
try {
|
||||
const doc = await this.operations.globals.findRevisionByID(options);
|
||||
const doc = await this.operations.globals.restoreVersion(options);
|
||||
return res.json(doc);
|
||||
} catch (error) {
|
||||
return next(error);
|
||||
}
|
||||
}
|
||||
|
||||
const findRevisionByIDHandler = handler.bind(this);
|
||||
return findRevisionByIDHandler;
|
||||
const restoreVersionHandler = handler.bind(this);
|
||||
return restoreVersionHandler;
|
||||
}
|
||||
@@ -6,7 +6,7 @@ import { SanitizedCollectionConfig } from '../../collections/config/types';
|
||||
import { SanitizedGlobalConfig } from '../../globals/config/types';
|
||||
import { Field } from '../../fields/config/types';
|
||||
|
||||
type OperationType = 'create' | 'read' | 'update' | 'delete' | 'unlock' | 'readRevisions';
|
||||
type OperationType = 'create' | 'read' | 'update' | 'delete' | 'unlock' | 'readVersions';
|
||||
|
||||
type ObjectTypeFields = {
|
||||
[key in OperationType | 'fields']?: { type: GraphQLObjectType };
|
||||
@@ -110,8 +110,8 @@ export default function buildPoliciesType(): GraphQLObjectType {
|
||||
collectionOperations.push('unlock');
|
||||
}
|
||||
|
||||
if (collection.revisions) {
|
||||
collectionOperations.push('readRevisions');
|
||||
if (collection.versions) {
|
||||
collectionOperations.push('readVersions');
|
||||
}
|
||||
|
||||
fields[formatName(collection.slug)] = {
|
||||
@@ -125,8 +125,8 @@ export default function buildPoliciesType(): GraphQLObjectType {
|
||||
Object.values(this.config.globals).forEach((global: SanitizedGlobalConfig) => {
|
||||
const globalOperations: OperationType[] = ['read', 'update'];
|
||||
|
||||
if (global.revisions) {
|
||||
globalOperations.push('readRevisions');
|
||||
if (global.versions) {
|
||||
globalOperations.push('readVersions');
|
||||
}
|
||||
|
||||
fields[formatName(global.slug)] = {
|
||||
|
||||
52
src/index.ts
52
src/index.ts
@@ -9,7 +9,7 @@ import {
|
||||
EmailOptions,
|
||||
InitOptions,
|
||||
} from './config/types';
|
||||
import { TypeWithRevision } from './revisions/types';
|
||||
import { TypeWithVersion } from './versions/types';
|
||||
import { PaginatedDocs } from './mongoose/types';
|
||||
|
||||
import Logger from './utilities/logger';
|
||||
@@ -46,9 +46,9 @@ import { Options as FindOptions } from './collections/operations/local/find';
|
||||
import { Options as FindByIDOptions } from './collections/operations/local/findByID';
|
||||
import { Options as UpdateOptions } from './collections/operations/local/update';
|
||||
import { Options as DeleteOptions } from './collections/operations/local/delete';
|
||||
import { Options as FindRevisionsOptions } from './collections/operations/local/findRevisions';
|
||||
import { Options as FindRevisionByIDOptions } from './collections/operations/local/findRevisionByID';
|
||||
import { Options as RestoreRevisionOptions } from './collections/operations/local/restoreRevision';
|
||||
import { Options as FindVersionsOptions } from './collections/operations/local/findVersions';
|
||||
import { Options as FindVersionByIDOptions } from './collections/operations/local/findVersionByID';
|
||||
import { Options as RestoreVersionOptions } from './collections/operations/local/restoreVersion';
|
||||
import { Result } from './auth/operations/login';
|
||||
|
||||
require('isomorphic-fetch');
|
||||
@@ -63,7 +63,7 @@ export class Payload {
|
||||
[slug: string]: Collection;
|
||||
} = {}
|
||||
|
||||
revisions: {
|
||||
versions: {
|
||||
[slug: string]: CollectionModel | GlobalModel;
|
||||
} = {}
|
||||
|
||||
@@ -275,42 +275,42 @@ export class Payload {
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Find revisions with criteria
|
||||
* @description Find versions with criteria
|
||||
* @param options
|
||||
* @returns revisions satisfying query
|
||||
* @returns versions satisfying query
|
||||
*/
|
||||
findRevisions = async <T extends TypeWithRevision<T> = any>(options: FindRevisionsOptions): Promise<PaginatedDocs<T>> => {
|
||||
let { findRevisions } = localOperations;
|
||||
findRevisions = findRevisions.bind(this);
|
||||
return findRevisions<T>(options);
|
||||
findVersions = async <T extends TypeWithVersion<T> = any>(options: FindVersionsOptions): Promise<PaginatedDocs<T>> => {
|
||||
let { findVersions } = localOperations;
|
||||
findVersions = findVersions.bind(this);
|
||||
return findVersions<T>(options);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Find revision by ID
|
||||
* @description Find version by ID
|
||||
* @param options
|
||||
* @returns revision with specified ID
|
||||
* @returns version with specified ID
|
||||
*/
|
||||
findRevisionByID = async <T extends TypeWithRevision<T> = any>(options: FindRevisionByIDOptions): Promise<T> => {
|
||||
let { findRevisionByID } = localOperations;
|
||||
findRevisionByID = findRevisionByID.bind(this);
|
||||
return findRevisionByID(options);
|
||||
findVersionByID = async <T extends TypeWithVersion<T> = any>(options: FindVersionByIDOptions): Promise<T> => {
|
||||
let { findVersionByID } = localOperations;
|
||||
findVersionByID = findVersionByID.bind(this);
|
||||
return findVersionByID(options);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Restore revision by ID
|
||||
* @description Restore version by ID
|
||||
* @param options
|
||||
* @returns revision with specified ID
|
||||
* @returns version with specified ID
|
||||
*/
|
||||
restoreRevision = async <T extends TypeWithRevision<T> = any>(options: RestoreRevisionOptions): Promise<T> => {
|
||||
let { restoreRevision } = localOperations;
|
||||
restoreRevision = restoreRevision.bind(this);
|
||||
return restoreRevision(options);
|
||||
restoreVersion = async <T extends TypeWithVersion<T> = any>(options: RestoreVersionOptions): Promise<T> => {
|
||||
let { restoreVersion } = localOperations;
|
||||
restoreVersion = restoreVersion.bind(this);
|
||||
return restoreVersion(options);
|
||||
}
|
||||
|
||||
// TODO: globals
|
||||
// findRevisionGlobal
|
||||
// findRevisionByIDGlobal
|
||||
// restoreRevisionGlobal
|
||||
// findVersionGlobal
|
||||
// findVersionByIDGlobal
|
||||
// restoreVersionGlobal
|
||||
// TODO:
|
||||
// graphql operations & request handlers, where
|
||||
// tests
|
||||
|
||||
@@ -14,16 +14,16 @@ import unlock from '../auth/operations/unlock';
|
||||
import create from '../collections/operations/create';
|
||||
import find from '../collections/operations/find';
|
||||
import findByID from '../collections/operations/findByID';
|
||||
import findRevisions from '../collections/operations/findRevisions';
|
||||
import findRevisionByID from '../collections/operations/findRevisionByID';
|
||||
import restoreRevision from '../collections/operations/restoreRevision';
|
||||
import findVersions from '../collections/operations/findVersions';
|
||||
import findVersionByID from '../collections/operations/findVersionByID';
|
||||
import restoreVersion from '../collections/operations/restoreVersion';
|
||||
import update from '../collections/operations/update';
|
||||
import deleteHandler from '../collections/operations/delete';
|
||||
|
||||
import findOne from '../globals/operations/findOne';
|
||||
import findGlobalRevisions from '../globals/operations/findRevisions';
|
||||
import findGlobalRevisionByID from '../globals/operations/findRevisionByID';
|
||||
import restoreGlobalRevision from '../globals/operations/restoreRevision';
|
||||
import findGlobalVersions from '../globals/operations/findVersions';
|
||||
import findGlobalVersionByID from '../globals/operations/findVersionByID';
|
||||
import restoreGlobalVersion from '../globals/operations/restoreVersion';
|
||||
import globalUpdate from '../globals/operations/update';
|
||||
|
||||
import preferenceUpdate from '../preferences/operations/update';
|
||||
@@ -35,9 +35,9 @@ export type Operations = {
|
||||
create: typeof create
|
||||
find: typeof find
|
||||
findByID: typeof findByID
|
||||
findRevisions: typeof findRevisions
|
||||
findRevisionByID: typeof findRevisionByID
|
||||
restoreRevision: typeof restoreRevision
|
||||
findVersions: typeof findVersions
|
||||
findVersionByID: typeof findVersionByID
|
||||
restoreVersion: typeof restoreVersion
|
||||
update: typeof update
|
||||
delete: typeof deleteHandler
|
||||
auth: {
|
||||
@@ -56,9 +56,9 @@ export type Operations = {
|
||||
}
|
||||
globals: {
|
||||
findOne: typeof findOne
|
||||
findRevisions: typeof findGlobalRevisions
|
||||
findRevisionByID: typeof findGlobalRevisionByID
|
||||
restoreRevision: typeof restoreGlobalRevision
|
||||
findVersions: typeof findGlobalVersions
|
||||
findVersionByID: typeof findGlobalVersionByID
|
||||
restoreVersion: typeof restoreGlobalVersion
|
||||
update: typeof globalUpdate
|
||||
}
|
||||
preferences: {
|
||||
@@ -74,9 +74,9 @@ function bindOperations(ctx: Payload): void {
|
||||
create: create.bind(ctx),
|
||||
find: find.bind(ctx),
|
||||
findByID: findByID.bind(ctx),
|
||||
findRevisions: findRevisions.bind(ctx),
|
||||
findRevisionByID: findRevisionByID.bind(ctx),
|
||||
restoreRevision: restoreRevision.bind(ctx),
|
||||
findVersions: findVersions.bind(ctx),
|
||||
findVersionByID: findVersionByID.bind(ctx),
|
||||
restoreVersion: restoreVersion.bind(ctx),
|
||||
update: update.bind(ctx),
|
||||
delete: deleteHandler.bind(ctx),
|
||||
auth: {
|
||||
@@ -95,9 +95,9 @@ function bindOperations(ctx: Payload): void {
|
||||
},
|
||||
globals: {
|
||||
findOne: findOne.bind(ctx),
|
||||
findRevisions: findGlobalRevisions.bind(ctx),
|
||||
findRevisionByID: findGlobalRevisionByID.bind(ctx),
|
||||
restoreRevision: restoreGlobalRevision.bind(ctx),
|
||||
findVersions: findGlobalVersions.bind(ctx),
|
||||
findVersionByID: findGlobalVersionByID.bind(ctx),
|
||||
restoreVersion: restoreGlobalVersion.bind(ctx),
|
||||
update: globalUpdate.bind(ctx),
|
||||
},
|
||||
preferences: {
|
||||
|
||||
@@ -13,16 +13,16 @@ import unlock from '../auth/requestHandlers/unlock';
|
||||
import create from '../collections/requestHandlers/create';
|
||||
import find from '../collections/requestHandlers/find';
|
||||
import findByID from '../collections/requestHandlers/findByID';
|
||||
import findRevisions from '../collections/requestHandlers/findRevisions';
|
||||
import findRevisionByID from '../collections/requestHandlers/findRevisionByID';
|
||||
import restoreRevision from '../collections/requestHandlers/restoreRevision';
|
||||
import findVersions from '../collections/requestHandlers/findVersions';
|
||||
import findVersionByID from '../collections/requestHandlers/findVersionByID';
|
||||
import restoreVersion from '../collections/requestHandlers/restoreVersion';
|
||||
import update from '../collections/requestHandlers/update';
|
||||
import deleteHandler from '../collections/requestHandlers/delete';
|
||||
|
||||
import findOne from '../globals/requestHandlers/findOne';
|
||||
import findGlobalRevisions from '../globals/requestHandlers/findRevisions';
|
||||
import findGlobalRevisionByID from '../globals/requestHandlers/findRevisionByID';
|
||||
import restoreGlobalRevision from '../globals/requestHandlers/restoreRevision';
|
||||
import findGlobalVersions from '../globals/requestHandlers/findVersions';
|
||||
import findGlobalVersionByID from '../globals/requestHandlers/findVersionByID';
|
||||
import restoreGlobalVersion from '../globals/requestHandlers/restoreVersion';
|
||||
import globalUpdate from '../globals/requestHandlers/update';
|
||||
import { Payload } from '../index';
|
||||
import preferenceUpdate from '../preferences/requestHandlers/update';
|
||||
@@ -34,9 +34,9 @@ export type RequestHandlers = {
|
||||
create: typeof create,
|
||||
find: typeof find,
|
||||
findByID: typeof findByID,
|
||||
findRevisions: typeof findRevisions,
|
||||
findRevisionByID: typeof findRevisionByID,
|
||||
restoreRevision: typeof restoreRevision,
|
||||
findVersions: typeof findVersions
|
||||
findVersionByID: typeof findVersionByID,
|
||||
restoreVersion: typeof restoreVersion,
|
||||
update: typeof update,
|
||||
delete: typeof deleteHandler,
|
||||
auth: {
|
||||
@@ -56,9 +56,9 @@ export type RequestHandlers = {
|
||||
globals: {
|
||||
findOne: typeof findOne,
|
||||
update: typeof globalUpdate,
|
||||
findRevisions: typeof findGlobalRevisions
|
||||
findRevisionByID: typeof findGlobalRevisionByID
|
||||
restoreRevision: typeof restoreGlobalRevision
|
||||
findVersions: typeof findGlobalVersions
|
||||
findVersionByID: typeof findGlobalVersionByID
|
||||
restoreVersion: typeof restoreGlobalVersion
|
||||
},
|
||||
preferences: {
|
||||
update: typeof preferenceUpdate,
|
||||
@@ -73,9 +73,9 @@ function bindRequestHandlers(ctx: Payload): void {
|
||||
create: create.bind(ctx),
|
||||
find: find.bind(ctx),
|
||||
findByID: findByID.bind(ctx),
|
||||
findRevisions: findRevisions.bind(ctx),
|
||||
findRevisionByID: findRevisionByID.bind(ctx),
|
||||
restoreRevision: restoreRevision.bind(ctx),
|
||||
findVersions: findVersions.bind(ctx),
|
||||
findVersionByID: findVersionByID.bind(ctx),
|
||||
restoreVersion: restoreVersion.bind(ctx),
|
||||
update: update.bind(ctx),
|
||||
delete: deleteHandler.bind(ctx),
|
||||
auth: {
|
||||
@@ -95,9 +95,9 @@ function bindRequestHandlers(ctx: Payload): void {
|
||||
globals: {
|
||||
findOne: findOne.bind(ctx),
|
||||
update: globalUpdate.bind(ctx),
|
||||
findRevisions: findGlobalRevisions.bind(ctx),
|
||||
findRevisionByID: findGlobalRevisionByID.bind(ctx),
|
||||
restoreRevision: restoreGlobalRevision.bind(ctx),
|
||||
findVersions: findGlobalVersions.bind(ctx),
|
||||
findVersionByID: findGlobalVersionByID.bind(ctx),
|
||||
restoreVersion: restoreGlobalVersion.bind(ctx),
|
||||
},
|
||||
preferences: {
|
||||
update: preferenceUpdate.bind(ctx),
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
import { IncomingCollectionRevisionsType, IncomingGlobalRevisionsType } from './types';
|
||||
|
||||
export const revisionCollectionDefaults: IncomingCollectionRevisionsType = {
|
||||
drafts: {
|
||||
autosave: {
|
||||
interval: 5, // in seconds
|
||||
},
|
||||
},
|
||||
maxPerDoc: 50,
|
||||
retainDeleted: true,
|
||||
};
|
||||
|
||||
export const revisionGlobalDefaults: IncomingGlobalRevisionsType = {
|
||||
drafts: {
|
||||
autosave: {
|
||||
interval: 5, // in seconds
|
||||
},
|
||||
},
|
||||
max: 50,
|
||||
};
|
||||
@@ -1,24 +0,0 @@
|
||||
export type Autosave = {
|
||||
interval?: number
|
||||
}
|
||||
|
||||
export type Drafts = {
|
||||
autosave?: boolean | Autosave
|
||||
}
|
||||
|
||||
export type IncomingCollectionRevisionsType = {
|
||||
maxPerDoc?: number
|
||||
retainDeleted?: boolean
|
||||
drafts?: boolean | Drafts
|
||||
}
|
||||
|
||||
export type IncomingGlobalRevisionsType = {
|
||||
max?: number
|
||||
drafts?: boolean | Drafts
|
||||
}
|
||||
|
||||
export type TypeWithRevision<T> = {
|
||||
id: string
|
||||
parent: string | number
|
||||
revision: T
|
||||
}
|
||||
30
src/versions/baseFields.ts
Normal file
30
src/versions/baseFields.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import { Field } from '../fields/config/types';
|
||||
|
||||
export const statuses = [
|
||||
{
|
||||
label: 'Draft',
|
||||
value: 'draft',
|
||||
},
|
||||
{
|
||||
label: 'Published',
|
||||
value: 'published',
|
||||
},
|
||||
];
|
||||
|
||||
const baseVersionFields: Field[] = [
|
||||
{
|
||||
name: '_status',
|
||||
label: 'Status',
|
||||
type: 'select',
|
||||
options: statuses,
|
||||
defaultValue: 'draft',
|
||||
required: true,
|
||||
admin: {
|
||||
components: {
|
||||
Field: () => null,
|
||||
},
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
export default baseVersionFields;
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Field } from '../fields/config/types';
|
||||
import { SanitizedCollectionConfig } from '../collections/config/types';
|
||||
|
||||
export const buildRevisionCollectionFields = (collection: SanitizedCollectionConfig): Field[] => [
|
||||
export const buildVersionCollectionFields = (collection: SanitizedCollectionConfig): Field[] => [
|
||||
{
|
||||
name: 'parent',
|
||||
type: 'relationship',
|
||||
@@ -9,7 +9,12 @@ export const buildRevisionCollectionFields = (collection: SanitizedCollectionCon
|
||||
relationTo: collection.slug,
|
||||
},
|
||||
{
|
||||
name: 'revision',
|
||||
name: 'autosave',
|
||||
type: 'checkbox',
|
||||
index: true,
|
||||
},
|
||||
{
|
||||
name: 'version',
|
||||
type: 'group',
|
||||
fields: collection.fields,
|
||||
},
|
||||
@@ -1,9 +1,9 @@
|
||||
import { Field } from '../fields/config/types';
|
||||
import { SanitizedGlobalConfig } from '../globals/config/types';
|
||||
|
||||
export const buildRevisionGlobalFields = (global: SanitizedGlobalConfig): Field[] => [
|
||||
export const buildVersionGlobalFields = (global: SanitizedGlobalConfig): Field[] => [
|
||||
{
|
||||
name: 'revision',
|
||||
name: 'version',
|
||||
type: 'group',
|
||||
fields: global.fields,
|
||||
},
|
||||
20
src/versions/defaults.ts
Normal file
20
src/versions/defaults.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import { IncomingCollectionVersions, IncomingGlobalVersions } from './types';
|
||||
|
||||
export const versionCollectionDefaults: IncomingCollectionVersions = {
|
||||
drafts: {
|
||||
autosave: {
|
||||
interval: 5, // in seconds
|
||||
},
|
||||
},
|
||||
maxPerDoc: 50,
|
||||
retainDeleted: true,
|
||||
};
|
||||
|
||||
export const versionGlobalDefaults: IncomingGlobalVersions = {
|
||||
drafts: {
|
||||
autosave: {
|
||||
interval: 5, // in seconds
|
||||
},
|
||||
},
|
||||
max: 50,
|
||||
};
|
||||
@@ -11,7 +11,7 @@ type Args = {
|
||||
id?: string | number
|
||||
}
|
||||
|
||||
export const enforceMaxRevisions = async ({
|
||||
export const enforceMaxVersions = async ({
|
||||
payload,
|
||||
Model,
|
||||
maxPerDoc,
|
||||
@@ -36,6 +36,6 @@ export const enforceMaxRevisions = async ({
|
||||
});
|
||||
}
|
||||
} catch (err) {
|
||||
payload.logger.error(`There was an error cleaning up old revisions for the ${entityType} ${entityLabel}`);
|
||||
payload.logger.error(`There was an error cleaning up old versions for the ${entityType} ${entityLabel}`);
|
||||
}
|
||||
};
|
||||
@@ -1,4 +1,4 @@
|
||||
import { SanitizedCollectionConfig } from '../collections/config/types';
|
||||
import { SanitizedGlobalConfig } from '../globals/config/types';
|
||||
|
||||
export const getRevisionsModelName = (entity: SanitizedCollectionConfig | SanitizedGlobalConfig): string => `_${entity.slug}_revisions`;
|
||||
export const getVersionsModelName = (entity: SanitizedCollectionConfig | SanitizedGlobalConfig): string => `_${entity.slug}_versions`;
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Payload } from '..';
|
||||
import { SanitizedCollectionConfig } from '../collections/config/types';
|
||||
import { enforceMaxRevisions } from './enforceMaxRevisions';
|
||||
import { enforceMaxVersions } from './enforceMaxVersions';
|
||||
import { PayloadRequest } from '../express/types';
|
||||
|
||||
type Args = {
|
||||
@@ -11,16 +11,16 @@ type Args = {
|
||||
id: string | number
|
||||
}
|
||||
|
||||
export const saveCollectionRevision = async ({
|
||||
export const saveCollectionVersion = async ({
|
||||
payload,
|
||||
config,
|
||||
req,
|
||||
id,
|
||||
docWithLocales,
|
||||
}: Args): Promise<void> => {
|
||||
const RevisionsModel = payload.revisions[config.slug];
|
||||
const VersionsModel = payload.versions[config.slug];
|
||||
|
||||
const revision = await payload.performFieldOperations(config, {
|
||||
const version = await payload.performFieldOperations(config, {
|
||||
id,
|
||||
depth: 0,
|
||||
req,
|
||||
@@ -32,26 +32,26 @@ export const saveCollectionRevision = async ({
|
||||
showHiddenFields: true,
|
||||
});
|
||||
|
||||
delete revision._id;
|
||||
delete version._id;
|
||||
|
||||
try {
|
||||
await RevisionsModel.create({
|
||||
await VersionsModel.create({
|
||||
parent: id,
|
||||
revision,
|
||||
version,
|
||||
});
|
||||
} catch (err) {
|
||||
payload.logger.error(`There was an error while saving a revision for the ${config.labels.singular} with ID ${id}.`);
|
||||
payload.logger.error(`There was an error while saving a version for the ${config.labels.singular} with ID ${id}.`);
|
||||
payload.logger.error(err);
|
||||
}
|
||||
|
||||
if (config.revisions.maxPerDoc) {
|
||||
enforceMaxRevisions({
|
||||
if (config.versions.maxPerDoc) {
|
||||
enforceMaxVersions({
|
||||
id,
|
||||
payload: this,
|
||||
Model: RevisionsModel,
|
||||
Model: VersionsModel,
|
||||
entityLabel: config.labels.plural,
|
||||
entityType: 'collection',
|
||||
maxPerDoc: config.revisions.maxPerDoc,
|
||||
maxPerDoc: config.versions.maxPerDoc,
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Payload } from '..';
|
||||
import { enforceMaxRevisions } from './enforceMaxRevisions';
|
||||
import { enforceMaxVersions } from './enforceMaxVersions';
|
||||
import { PayloadRequest } from '../express/types';
|
||||
import { SanitizedGlobalConfig } from '../globals/config/types';
|
||||
|
||||
@@ -10,15 +10,15 @@ type Args = {
|
||||
docWithLocales: any
|
||||
}
|
||||
|
||||
export const saveGlobalRevision = async ({
|
||||
export const saveGlobalVersion = async ({
|
||||
payload,
|
||||
config,
|
||||
req,
|
||||
docWithLocales,
|
||||
}: Args): Promise<void> => {
|
||||
const RevisionsModel = payload.revisions[config.slug];
|
||||
const VersionsModel = payload.versions[config.slug];
|
||||
|
||||
const revision = await payload.performFieldOperations(config, {
|
||||
const version = await payload.performFieldOperations(config, {
|
||||
depth: 0,
|
||||
req,
|
||||
data: docWithLocales,
|
||||
@@ -30,21 +30,21 @@ export const saveGlobalRevision = async ({
|
||||
});
|
||||
|
||||
try {
|
||||
await RevisionsModel.create({
|
||||
revision,
|
||||
await VersionsModel.create({
|
||||
version,
|
||||
});
|
||||
} catch (err) {
|
||||
payload.logger.error(`There was an error while saving a revision for the Global ${config.label}.`);
|
||||
payload.logger.error(`There was an error while saving a version for the Global ${config.label}.`);
|
||||
payload.logger.error(err);
|
||||
}
|
||||
|
||||
if (config.revisions.max) {
|
||||
enforceMaxRevisions({
|
||||
if (config.versions.max) {
|
||||
enforceMaxVersions({
|
||||
payload: this,
|
||||
Model: RevisionsModel,
|
||||
Model: VersionsModel,
|
||||
entityLabel: config.label,
|
||||
entityType: 'global',
|
||||
maxPerDoc: config.revisions.max,
|
||||
maxPerDoc: config.versions.max,
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -8,9 +8,9 @@ const { serverURL: url } = getConfig();
|
||||
let token = null;
|
||||
let headers = null;
|
||||
let postID;
|
||||
let revisionID;
|
||||
let versionID;
|
||||
|
||||
describe('Revisions - REST', () => {
|
||||
describe('Versions - REST', () => {
|
||||
beforeAll(async (done) => {
|
||||
const response = await fetch(`${url}/api/admins/login`, {
|
||||
body: JSON.stringify({
|
||||
@@ -48,7 +48,7 @@ describe('Revisions - REST', () => {
|
||||
});
|
||||
|
||||
describe('Create', () => {
|
||||
it('should allow a new revision to be created', async () => {
|
||||
it('should allow a new version to be created', async () => {
|
||||
const title2 = 'Here is an updated post title in EN';
|
||||
|
||||
const updatedPost = await fetch(`${url}/api/localized-posts/${postID}`, {
|
||||
@@ -61,22 +61,22 @@ describe('Revisions - REST', () => {
|
||||
|
||||
expect(updatedPost.doc.title).toBe(title2);
|
||||
|
||||
const revisions = await fetch(`${url}/api/localized-posts/revisions`, {
|
||||
const versions = await fetch(`${url}/api/localized-posts/versions`, {
|
||||
headers,
|
||||
}).then((res) => res.json());
|
||||
|
||||
revisionID = revisions.docs[0].id;
|
||||
versionID = versions.docs[0].id;
|
||||
});
|
||||
|
||||
it('should allow a revision to be retrieved by ID', async () => {
|
||||
const revision = await fetch(`${url}/api/localized-posts/revisions/${revisionID}`, {
|
||||
it('should allow a version to be retrieved by ID', async () => {
|
||||
const version = await fetch(`${url}/api/localized-posts/versions/${versionID}`, {
|
||||
headers,
|
||||
}).then((res) => res.json());
|
||||
|
||||
expect(revision.id).toStrictEqual(revisionID);
|
||||
expect(version.id).toStrictEqual(versionID);
|
||||
});
|
||||
|
||||
it('should allow a revision to save locales properly', async () => {
|
||||
it('should allow a version to save locales properly', async () => {
|
||||
const englishTitle = 'Title in ES';
|
||||
const spanishTitle = 'Title in ES';
|
||||
|
||||
@@ -108,17 +108,17 @@ describe('Revisions - REST', () => {
|
||||
method: 'put',
|
||||
}).then((res) => res.json());
|
||||
|
||||
const revisions = await fetch(`${url}/api/localized-posts/revisions?locale=all`, {
|
||||
const versions = await fetch(`${url}/api/localized-posts/versions?locale=all`, {
|
||||
headers,
|
||||
}).then((res) => res.json());
|
||||
|
||||
expect(revisions.docs[0].revision.title.en).toStrictEqual(englishTitle);
|
||||
expect(revisions.docs[0].revision.title.es).toStrictEqual(spanishTitle);
|
||||
expect(versions.docs[0].version.title.en).toStrictEqual(englishTitle);
|
||||
expect(versions.docs[0].version.title.es).toStrictEqual(spanishTitle);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Restore', () => {
|
||||
it('should allow a revision to be restored', async () => {
|
||||
it('should allow a version to be restored', async () => {
|
||||
const title2 = 'Here is an updated post title in EN';
|
||||
|
||||
const updatedPost = await fetch(`${url}/api/localized-posts/${postID}`, {
|
||||
@@ -131,13 +131,13 @@ describe('Revisions - REST', () => {
|
||||
|
||||
expect(updatedPost.doc.title).toBe(title2);
|
||||
|
||||
const revisions = await fetch(`${url}/api/localized-posts/revisions`, {
|
||||
const versions = await fetch(`${url}/api/localized-posts/versions`, {
|
||||
headers,
|
||||
}).then((res) => res.json());
|
||||
|
||||
revisionID = revisions.docs[0].id;
|
||||
versionID = versions.docs[0].id;
|
||||
|
||||
const restore = await fetch(`${url}/api/localized-posts/revisions/${revisionID}`, {
|
||||
const restore = await fetch(`${url}/api/localized-posts/versions/${versionID}`, {
|
||||
headers,
|
||||
method: 'post',
|
||||
}).then((res) => res.json());
|
||||
39
src/versions/types.ts
Normal file
39
src/versions/types.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
export type Autosave = {
|
||||
interval?: number
|
||||
}
|
||||
|
||||
export type IncomingDrafts = {
|
||||
autosave?: boolean | Autosave
|
||||
}
|
||||
|
||||
export type SanitizedDrafts = {
|
||||
autosave: false | Autosave
|
||||
}
|
||||
|
||||
export type IncomingCollectionVersions = {
|
||||
maxPerDoc?: number
|
||||
retainDeleted?: boolean
|
||||
drafts?: boolean | IncomingDrafts
|
||||
}
|
||||
|
||||
export interface SanitizedCollectionVersions extends Omit<IncomingCollectionVersions, 'drafts'> {
|
||||
maxPerDoc?: number
|
||||
retainDeleted: boolean
|
||||
drafts: SanitizedDrafts | false
|
||||
}
|
||||
|
||||
export type IncomingGlobalVersions= {
|
||||
max?: number
|
||||
drafts?: boolean | IncomingDrafts
|
||||
}
|
||||
|
||||
export type SanitizedGlobalVersions= {
|
||||
max: number
|
||||
drafts: SanitizedDrafts | false
|
||||
}
|
||||
|
||||
export type TypeWithVersion<T> = {
|
||||
id: string
|
||||
parent: string | number
|
||||
version: T
|
||||
}
|
||||
Reference in New Issue
Block a user