feat: add publish configuration option to collections (#3467)
This commit is contained in:
@ -55,6 +55,41 @@ describe('config', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('slug', () => {
|
||||
it('should set default slug config if not set', () => {
|
||||
expect(applyDefaults(fromJS({ collections: [] })).get('slug')).toEqual(
|
||||
fromJS({ encoding: 'unicode', clean_accents: false, sanitize_replacement: '-' }),
|
||||
);
|
||||
});
|
||||
|
||||
it('should not overwrite slug encoding if set', () => {
|
||||
expect(
|
||||
applyDefaults(fromJS({ collections: [], slug: { encoding: 'ascii' } })).getIn([
|
||||
'slug',
|
||||
'encoding',
|
||||
]),
|
||||
).toEqual('ascii');
|
||||
});
|
||||
|
||||
it('should not overwrite slug clean_accents if set', () => {
|
||||
expect(
|
||||
applyDefaults(fromJS({ collections: [], slug: { clean_accents: true } })).getIn([
|
||||
'slug',
|
||||
'clean_accents',
|
||||
]),
|
||||
).toEqual(true);
|
||||
});
|
||||
|
||||
it('should not overwrite slug sanitize_replacement if set', () => {
|
||||
expect(
|
||||
applyDefaults(fromJS({ collections: [], slug: { sanitize_replacement: '_' } })).getIn([
|
||||
'slug',
|
||||
'sanitize_replacement',
|
||||
]),
|
||||
).toEqual('_');
|
||||
});
|
||||
});
|
||||
|
||||
describe('collections', () => {
|
||||
it('should strip leading slashes from collection folder', () => {
|
||||
expect(
|
||||
@ -62,8 +97,8 @@ describe('config', () => {
|
||||
fromJS({
|
||||
collections: [{ folder: '/foo' }],
|
||||
}),
|
||||
).get('collections'),
|
||||
).toEqual(fromJS([{ folder: 'foo' }]));
|
||||
).getIn(['collections', 0, 'folder']),
|
||||
).toEqual('foo');
|
||||
});
|
||||
|
||||
it('should strip leading slashes from collection files', () => {
|
||||
@ -72,43 +107,8 @@ describe('config', () => {
|
||||
fromJS({
|
||||
collections: [{ files: [{ file: '/foo' }] }],
|
||||
}),
|
||||
).get('collections'),
|
||||
).toEqual(fromJS([{ files: [{ file: 'foo' }] }]));
|
||||
});
|
||||
|
||||
describe('slug', () => {
|
||||
it('should set default slug config if not set', () => {
|
||||
expect(applyDefaults(fromJS({ collections: [] })).get('slug')).toEqual(
|
||||
fromJS({ encoding: 'unicode', clean_accents: false, sanitize_replacement: '-' }),
|
||||
);
|
||||
});
|
||||
|
||||
it('should not overwrite slug encoding if set', () => {
|
||||
expect(
|
||||
applyDefaults(fromJS({ collections: [], slug: { encoding: 'ascii' } })).getIn([
|
||||
'slug',
|
||||
'encoding',
|
||||
]),
|
||||
).toEqual('ascii');
|
||||
});
|
||||
|
||||
it('should not overwrite slug clean_accents if set', () => {
|
||||
expect(
|
||||
applyDefaults(fromJS({ collections: [], slug: { clean_accents: true } })).getIn([
|
||||
'slug',
|
||||
'clean_accents',
|
||||
]),
|
||||
).toEqual(true);
|
||||
});
|
||||
|
||||
it('should not overwrite slug sanitize_replacement if set', () => {
|
||||
expect(
|
||||
applyDefaults(fromJS({ collections: [], slug: { sanitize_replacement: '_' } })).getIn([
|
||||
'slug',
|
||||
'sanitize_replacement',
|
||||
]),
|
||||
).toEqual('_');
|
||||
});
|
||||
).getIn(['collections', 0, 'files', 0, 'file']),
|
||||
).toEqual('foo');
|
||||
});
|
||||
|
||||
describe('public_folder and media_folder', () => {
|
||||
@ -118,16 +118,8 @@ describe('config', () => {
|
||||
fromJS({
|
||||
collections: [{ folder: 'foo', media_folder: 'static/images/docs' }],
|
||||
}),
|
||||
).get('collections'),
|
||||
).toEqual(
|
||||
fromJS([
|
||||
{
|
||||
folder: 'foo',
|
||||
media_folder: 'static/images/docs',
|
||||
public_folder: 'static/images/docs',
|
||||
},
|
||||
]),
|
||||
);
|
||||
).getIn(['collections', 0, 'public_folder']),
|
||||
).toEqual('static/images/docs');
|
||||
});
|
||||
|
||||
it('should not overwrite collection public_folder if set', () => {
|
||||
@ -142,30 +134,42 @@ describe('config', () => {
|
||||
},
|
||||
],
|
||||
}),
|
||||
).get('collections'),
|
||||
).toEqual(
|
||||
fromJS([
|
||||
{
|
||||
folder: 'foo',
|
||||
media_folder: 'static/images/docs',
|
||||
public_folder: 'images/docs',
|
||||
},
|
||||
]),
|
||||
);
|
||||
).getIn(['collections', 0, 'public_folder']),
|
||||
).toEqual('images/docs');
|
||||
});
|
||||
|
||||
it("should set collection media_folder and public_folder to an empty string when collection path exists, but collection media_folder doesn't", () => {
|
||||
const result = applyDefaults(
|
||||
fromJS({
|
||||
collections: [{ folder: 'foo', path: '{{slug}}/index' }],
|
||||
}),
|
||||
);
|
||||
expect(result.getIn(['collections', 0, 'media_folder'])).toEqual('');
|
||||
expect(result.getIn(['collections', 0, 'public_folder'])).toEqual('');
|
||||
});
|
||||
});
|
||||
|
||||
describe('publish', () => {
|
||||
it('should set publish to true if not set', () => {
|
||||
expect(
|
||||
applyDefaults(
|
||||
fromJS({
|
||||
collections: [{ folder: 'foo', path: '{{slug}}/index' }],
|
||||
collections: [{ folder: 'foo', media_folder: 'static/images/docs' }],
|
||||
}),
|
||||
).get('collections'),
|
||||
).toEqual(
|
||||
fromJS([
|
||||
{ folder: 'foo', path: '{{slug}}/index', media_folder: '', public_folder: '' },
|
||||
]),
|
||||
);
|
||||
).getIn(['collections', 0, 'publish']),
|
||||
).toEqual(true);
|
||||
});
|
||||
|
||||
it('should not override existing publish config', () => {
|
||||
expect(
|
||||
applyDefaults(
|
||||
fromJS({
|
||||
collections: [
|
||||
{ folder: 'foo', media_folder: 'static/images/docs', publish: false },
|
||||
],
|
||||
}),
|
||||
).getIn(['collections', 0, 'publish']),
|
||||
).toEqual(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -58,6 +58,10 @@ export function applyDefaults(config) {
|
||||
map.set(
|
||||
'collections',
|
||||
map.get('collections').map(collection => {
|
||||
if (!collection.has('publish')) {
|
||||
collection = collection.set('publish', true);
|
||||
}
|
||||
|
||||
const folder = collection.get('folder');
|
||||
if (folder) {
|
||||
if (collection.has('path') && !collection.has('media_folder')) {
|
||||
|
@ -301,48 +301,146 @@ class EditorToolbar extends React.Component {
|
||||
);
|
||||
};
|
||||
|
||||
renderSimplePublishControls = () => {
|
||||
const {
|
||||
collection,
|
||||
onPersist,
|
||||
onPersistAndNew,
|
||||
onPersistAndDuplicate,
|
||||
onDuplicate,
|
||||
isPersisting,
|
||||
hasChanged,
|
||||
isNewEntry,
|
||||
t,
|
||||
} = this.props;
|
||||
renderWorkflowStatusControls = () => {
|
||||
const { isUpdatingStatus, onChangeStatus, currentStatus, t, useOpenAuthoring } = this.props;
|
||||
return (
|
||||
<ToolbarDropdown
|
||||
dropdownTopOverlap="40px"
|
||||
dropdownWidth="120px"
|
||||
renderButton={() => (
|
||||
<StatusButton>
|
||||
{isUpdatingStatus
|
||||
? t('editor.editorToolbar.updating')
|
||||
: t('editor.editorToolbar.setStatus')}
|
||||
</StatusButton>
|
||||
)}
|
||||
>
|
||||
<StatusDropdownItem
|
||||
label={t('editor.editorToolbar.draft')}
|
||||
onClick={() => onChangeStatus('DRAFT')}
|
||||
icon={currentStatus === status.get('DRAFT') ? 'check' : null}
|
||||
/>
|
||||
<StatusDropdownItem
|
||||
label={t('editor.editorToolbar.inReview')}
|
||||
onClick={() => onChangeStatus('PENDING_REVIEW')}
|
||||
icon={currentStatus === status.get('PENDING_REVIEW') ? 'check' : null}
|
||||
/>
|
||||
{useOpenAuthoring ? (
|
||||
''
|
||||
) : (
|
||||
<StatusDropdownItem
|
||||
label={t('editor.editorToolbar.ready')}
|
||||
onClick={() => onChangeStatus('PENDING_PUBLISH')}
|
||||
icon={currentStatus === status.get('PENDING_PUBLISH') ? 'check' : null}
|
||||
/>
|
||||
)}
|
||||
</ToolbarDropdown>
|
||||
);
|
||||
};
|
||||
|
||||
renderNewEntryWorkflowPublishControls = ({ canCreate, canPublish }) => {
|
||||
const { isPublishing, onPublish, onPublishAndNew, onPublishAndDuplicate, t } = this.props;
|
||||
|
||||
return canPublish ? (
|
||||
<ToolbarDropdown
|
||||
dropdownTopOverlap="40px"
|
||||
dropdownWidth="150px"
|
||||
renderButton={() => (
|
||||
<PublishButton>
|
||||
{isPublishing
|
||||
? t('editor.editorToolbar.publishing')
|
||||
: t('editor.editorToolbar.publish')}
|
||||
</PublishButton>
|
||||
)}
|
||||
>
|
||||
<DropdownItem
|
||||
label={t('editor.editorToolbar.publishNow')}
|
||||
icon="arrow"
|
||||
iconDirection="right"
|
||||
onClick={onPublish}
|
||||
/>
|
||||
{canCreate ? (
|
||||
<>
|
||||
<DropdownItem
|
||||
label={t('editor.editorToolbar.publishAndCreateNew')}
|
||||
icon="add"
|
||||
onClick={onPublishAndNew}
|
||||
/>
|
||||
<DropdownItem
|
||||
label={t('editor.editorToolbar.publishAndDuplicate')}
|
||||
icon="add"
|
||||
onClick={onPublishAndDuplicate}
|
||||
/>
|
||||
</>
|
||||
) : null}
|
||||
</ToolbarDropdown>
|
||||
) : (
|
||||
''
|
||||
);
|
||||
};
|
||||
|
||||
renderExistingEntryWorkflowPublishControls = ({ canCreate, canPublish }) => {
|
||||
const { unPublish, onDuplicate, isPersisting, t } = this.props;
|
||||
|
||||
return canPublish || canCreate ? (
|
||||
<ToolbarDropdown
|
||||
dropdownTopOverlap="40px"
|
||||
dropdownWidth="150px"
|
||||
renderButton={() => (
|
||||
<PublishedToolbarButton>
|
||||
{isPersisting
|
||||
? t('editor.editorToolbar.unpublishing')
|
||||
: t('editor.editorToolbar.published')}
|
||||
</PublishedToolbarButton>
|
||||
)}
|
||||
>
|
||||
{canPublish && (
|
||||
<DropdownItem
|
||||
label={t('editor.editorToolbar.unpublish')}
|
||||
icon="arrow"
|
||||
iconDirection="right"
|
||||
onClick={unPublish}
|
||||
/>
|
||||
)}
|
||||
{canCreate && (
|
||||
<DropdownItem
|
||||
label={t('editor.editorToolbar.duplicate')}
|
||||
icon="add"
|
||||
onClick={onDuplicate}
|
||||
/>
|
||||
)}
|
||||
</ToolbarDropdown>
|
||||
) : (
|
||||
''
|
||||
);
|
||||
};
|
||||
|
||||
renderExistingEntrySimplePublishControls = ({ canCreate }) => {
|
||||
const { onDuplicate, t } = this.props;
|
||||
return canCreate ? (
|
||||
<ToolbarDropdown
|
||||
dropdownTopOverlap="40px"
|
||||
dropdownWidth="150px"
|
||||
renderButton={() => (
|
||||
<PublishedToolbarButton>{t('editor.editorToolbar.published')}</PublishedToolbarButton>
|
||||
)}
|
||||
>
|
||||
{
|
||||
<DropdownItem
|
||||
label={t('editor.editorToolbar.duplicate')}
|
||||
icon="add"
|
||||
onClick={onDuplicate}
|
||||
/>
|
||||
}
|
||||
</ToolbarDropdown>
|
||||
) : (
|
||||
<PublishedButton>{t('editor.editorToolbar.published')}</PublishedButton>
|
||||
);
|
||||
};
|
||||
|
||||
renderNewEntrySimplePublishControls = ({ canCreate }) => {
|
||||
const { onPersist, onPersistAndNew, onPersistAndDuplicate, isPersisting, t } = this.props;
|
||||
|
||||
const canCreate = collection.get('create');
|
||||
if (!isNewEntry && !hasChanged) {
|
||||
return (
|
||||
<>
|
||||
{this.renderDeployPreviewControls(t('editor.editorToolbar.deployButtonLabel'))}
|
||||
{canCreate ? (
|
||||
<ToolbarDropdown
|
||||
dropdownTopOverlap="40px"
|
||||
dropdownWidth="150px"
|
||||
renderButton={() => (
|
||||
<PublishedToolbarButton>
|
||||
{t('editor.editorToolbar.published')}
|
||||
</PublishedToolbarButton>
|
||||
)}
|
||||
>
|
||||
{
|
||||
<DropdownItem
|
||||
label={t('editor.editorToolbar.duplicate')}
|
||||
icon="add"
|
||||
onClick={onDuplicate}
|
||||
/>
|
||||
}
|
||||
</ToolbarDropdown>
|
||||
) : (
|
||||
<PublishedButton>{t('editor.editorToolbar.published')}</PublishedButton>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<div>
|
||||
<ToolbarDropdown
|
||||
@ -381,6 +479,21 @@ class EditorToolbar extends React.Component {
|
||||
);
|
||||
};
|
||||
|
||||
renderSimplePublishControls = () => {
|
||||
const { collection, hasChanged, isNewEntry, t } = this.props;
|
||||
|
||||
const canCreate = collection.get('create');
|
||||
if (!isNewEntry && !hasChanged) {
|
||||
return (
|
||||
<>
|
||||
{this.renderDeployPreviewControls(t('editor.editorToolbar.deployButtonLabel'))}
|
||||
{this.renderExistingEntrySimplePublishControls({ canCreate })}
|
||||
</>
|
||||
);
|
||||
}
|
||||
return this.renderNewEntrySimplePublishControls({ canCreate });
|
||||
};
|
||||
|
||||
renderWorkflowSaveControls = () => {
|
||||
const {
|
||||
onPersist,
|
||||
@ -421,95 +534,17 @@ class EditorToolbar extends React.Component {
|
||||
};
|
||||
|
||||
renderWorkflowPublishControls = () => {
|
||||
const {
|
||||
collection,
|
||||
isUpdatingStatus,
|
||||
isPublishing,
|
||||
onChangeStatus,
|
||||
onPublish,
|
||||
unPublish,
|
||||
onDuplicate,
|
||||
onPublishAndNew,
|
||||
onPublishAndDuplicate,
|
||||
currentStatus,
|
||||
isNewEntry,
|
||||
useOpenAuthoring,
|
||||
isPersisting,
|
||||
t,
|
||||
} = this.props;
|
||||
const { collection, currentStatus, isNewEntry, useOpenAuthoring, t } = this.props;
|
||||
|
||||
const canCreate = collection.get('create');
|
||||
const canPublish = collection.get('publish') && !useOpenAuthoring;
|
||||
|
||||
if (currentStatus) {
|
||||
return (
|
||||
<>
|
||||
{this.renderDeployPreviewControls(t('editor.editorToolbar.deployPreviewButtonLabel'))}
|
||||
<ToolbarDropdown
|
||||
dropdownTopOverlap="40px"
|
||||
dropdownWidth="120px"
|
||||
renderButton={() => (
|
||||
<StatusButton>
|
||||
{isUpdatingStatus
|
||||
? t('editor.editorToolbar.updating')
|
||||
: t('editor.editorToolbar.setStatus')}
|
||||
</StatusButton>
|
||||
)}
|
||||
>
|
||||
<StatusDropdownItem
|
||||
label={t('editor.editorToolbar.draft')}
|
||||
onClick={() => onChangeStatus('DRAFT')}
|
||||
icon={currentStatus === status.get('DRAFT') ? 'check' : null}
|
||||
/>
|
||||
<StatusDropdownItem
|
||||
label={t('editor.editorToolbar.inReview')}
|
||||
onClick={() => onChangeStatus('PENDING_REVIEW')}
|
||||
icon={currentStatus === status.get('PENDING_REVIEW') ? 'check' : null}
|
||||
/>
|
||||
{useOpenAuthoring ? (
|
||||
''
|
||||
) : (
|
||||
<StatusDropdownItem
|
||||
label={t('editor.editorToolbar.ready')}
|
||||
onClick={() => onChangeStatus('PENDING_PUBLISH')}
|
||||
icon={currentStatus === status.get('PENDING_PUBLISH') ? 'check' : null}
|
||||
/>
|
||||
)}
|
||||
</ToolbarDropdown>
|
||||
{useOpenAuthoring ? (
|
||||
''
|
||||
) : (
|
||||
<ToolbarDropdown
|
||||
dropdownTopOverlap="40px"
|
||||
dropdownWidth="150px"
|
||||
renderButton={() => (
|
||||
<PublishButton>
|
||||
{isPublishing
|
||||
? t('editor.editorToolbar.publishing')
|
||||
: t('editor.editorToolbar.publish')}
|
||||
</PublishButton>
|
||||
)}
|
||||
>
|
||||
<DropdownItem
|
||||
label={t('editor.editorToolbar.publishNow')}
|
||||
icon="arrow"
|
||||
iconDirection="right"
|
||||
onClick={onPublish}
|
||||
/>
|
||||
{canCreate ? (
|
||||
<>
|
||||
<DropdownItem
|
||||
label={t('editor.editorToolbar.publishAndCreateNew')}
|
||||
icon="add"
|
||||
onClick={onPublishAndNew}
|
||||
/>
|
||||
<DropdownItem
|
||||
label={t('editor.editorToolbar.publishAndDuplicate')}
|
||||
icon="add"
|
||||
onClick={onPublishAndDuplicate}
|
||||
/>
|
||||
</>
|
||||
) : null}
|
||||
</ToolbarDropdown>
|
||||
)}
|
||||
{this.renderWorkflowStatusControls()}
|
||||
{this.renderNewEntryWorkflowPublishControls({ canCreate, canPublish })}
|
||||
</>
|
||||
);
|
||||
}
|
||||
@ -521,31 +556,7 @@ class EditorToolbar extends React.Component {
|
||||
return (
|
||||
<>
|
||||
{this.renderDeployPreviewControls(t('editor.editorToolbar.deployButtonLabel'))}
|
||||
<ToolbarDropdown
|
||||
dropdownTopOverlap="40px"
|
||||
dropdownWidth="150px"
|
||||
renderButton={() => (
|
||||
<PublishedToolbarButton>
|
||||
{isPersisting
|
||||
? t('editor.editorToolbar.unpublishing')
|
||||
: t('editor.editorToolbar.published')}
|
||||
</PublishedToolbarButton>
|
||||
)}
|
||||
>
|
||||
<DropdownItem
|
||||
label={t('editor.editorToolbar.unpublish')}
|
||||
icon="arrow"
|
||||
iconDirection="right"
|
||||
onClick={unPublish}
|
||||
/>
|
||||
{canCreate && (
|
||||
<DropdownItem
|
||||
label={t('editor.editorToolbar.duplicate')}
|
||||
icon="add"
|
||||
onClick={onDuplicate}
|
||||
/>
|
||||
)}
|
||||
</ToolbarDropdown>
|
||||
{this.renderExistingEntryWorkflowPublishControls({ canCreate, canPublish })}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ const WorkflowTopDescription = styled.p`
|
||||
|
||||
class Workflow extends Component {
|
||||
static propTypes = {
|
||||
collections: ImmutablePropTypes.orderedMap,
|
||||
collections: ImmutablePropTypes.orderedMap.isRequired,
|
||||
isEditorialWorkflow: PropTypes.bool.isRequired,
|
||||
isOpenAuthoring: PropTypes.bool,
|
||||
isFetching: PropTypes.bool,
|
||||
|
@ -126,6 +126,7 @@ const WorkflowCard = ({
|
||||
editLink,
|
||||
timestamp,
|
||||
onDelete,
|
||||
allowPublish,
|
||||
canPublish,
|
||||
onPublish,
|
||||
t,
|
||||
@ -143,11 +144,13 @@ const WorkflowCard = ({
|
||||
? t('workflow.workflowCard.deleteChanges')
|
||||
: t('workflow.workflowCard.deleteNewEntry')}
|
||||
</DeleteButton>
|
||||
<PublishButton disabled={!canPublish} onClick={onPublish}>
|
||||
{isModification
|
||||
? t('workflow.workflowCard.publishChanges')
|
||||
: t('workflow.workflowCard.publishNewEntry')}
|
||||
</PublishButton>
|
||||
{allowPublish && (
|
||||
<PublishButton disabled={!canPublish} onClick={onPublish}>
|
||||
{isModification
|
||||
? t('workflow.workflowCard.publishChanges')
|
||||
: t('workflow.workflowCard.publishNewEntry')}
|
||||
</PublishButton>
|
||||
)}
|
||||
</CardButtonContainer>
|
||||
</WorkflowCardContainer>
|
||||
);
|
||||
@ -161,6 +164,7 @@ WorkflowCard.propTypes = {
|
||||
editLink: PropTypes.string.isRequired,
|
||||
timestamp: PropTypes.string.isRequired,
|
||||
onDelete: PropTypes.func.isRequired,
|
||||
allowPublish: PropTypes.bool.isRequired,
|
||||
canPublish: PropTypes.bool.isRequired,
|
||||
onPublish: PropTypes.func.isRequired,
|
||||
t: PropTypes.func.isRequired,
|
||||
|
@ -134,7 +134,7 @@ class WorkflowList extends React.Component {
|
||||
handleDelete: PropTypes.func.isRequired,
|
||||
t: PropTypes.func.isRequired,
|
||||
isOpenAuthoring: PropTypes.bool,
|
||||
collections: ImmutablePropTypes.orderedMap,
|
||||
collections: ImmutablePropTypes.orderedMap.isRequired,
|
||||
};
|
||||
|
||||
handleChangeStatus = (newStatus, dragProps) => {
|
||||
@ -210,11 +210,15 @@ class WorkflowList extends React.Component {
|
||||
const editLink = `collections/${entry.getIn(['metaData', 'collection'])}/entries/${slug}`;
|
||||
const ownStatus = entry.getIn(['metaData', 'status']);
|
||||
const collectionName = entry.getIn(['metaData', 'collection']);
|
||||
const collectionLabel = collections
|
||||
?.find(collection => collection.get('name') === collectionName)
|
||||
?.get('label');
|
||||
const collection = collections.find(
|
||||
collection => collection.get('name') === collectionName,
|
||||
);
|
||||
const collectionLabel = collection?.get('label');
|
||||
const isModification = entry.get('isModification');
|
||||
|
||||
const allowPublish = collection?.get('publish');
|
||||
const canPublish = ownStatus === status.last() && !entry.get('isPersisting', false);
|
||||
|
||||
return (
|
||||
<DragSource
|
||||
namespace={DNDNamespace}
|
||||
@ -235,6 +239,7 @@ class WorkflowList extends React.Component {
|
||||
editLink={editLink}
|
||||
timestamp={timestamp}
|
||||
onDelete={this.requestDelete.bind(this, collectionName, slug, ownStatus)}
|
||||
allowPublish={allowPublish}
|
||||
canPublish={canPublish}
|
||||
onPublish={this.requestPublish.bind(this, collectionName, slug, ownStatus)}
|
||||
/>
|
||||
|
@ -152,5 +152,17 @@ describe('config', () => {
|
||||
);
|
||||
}).not.toThrowError();
|
||||
});
|
||||
|
||||
it('should throw if collection publish is not a boolean', () => {
|
||||
expect(() => {
|
||||
validateConfig(merge(validConfig, { collections: [{ publish: 'false' }] }));
|
||||
}).toThrowError("'collections[0].publish' should be boolean");
|
||||
});
|
||||
|
||||
it('should not throw if collection publish is a boolean', () => {
|
||||
expect(() => {
|
||||
validateConfig(merge(validConfig, { collections: [{ publish: false }] }));
|
||||
}).not.toThrowError();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -117,6 +117,7 @@ const getConfigSchema = () => ({
|
||||
preview_path: { type: 'string' },
|
||||
preview_path_date_field: { type: 'string' },
|
||||
create: { type: 'boolean' },
|
||||
publish: { type: 'boolean' },
|
||||
editor: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
|
Reference in New Issue
Block a user