diff --git a/example/config.yml b/example/config.yml index 3b1cbf5b..c1866961 100644 --- a/example/config.yml +++ b/example/config.yml @@ -27,6 +27,7 @@ collections: # A list of collections the CMS should be able to edit - name: "settings" label: "Settings" + delete: false # Prevent users from deleting documents in this collection editor: preview: false files: diff --git a/src/backends/backend.js b/src/backends/backend.js index 67fd06e6..d1f72ada 100644 --- a/src/backends/backend.js +++ b/src/backends/backend.js @@ -3,7 +3,7 @@ import TestRepoBackend from "./test-repo/implementation"; import GitHubBackend from "./github/implementation"; import GitGatewayBackend from "./git-gateway/implementation"; import { resolveFormat } from "../formats/formats"; -import { selectListMethod, selectEntrySlug, selectEntryPath, selectAllowNewEntries, selectFolderEntryExtension } from "../reducers/collections"; +import { selectListMethod, selectEntrySlug, selectEntryPath, selectAllowNewEntries, selectAllowDeletion, selectFolderEntryExtension } from "../reducers/collections"; import { createEntry } from "../valueObjects/Entry"; import { sanitizeSlug } from "../lib/urlHelper"; @@ -246,6 +246,11 @@ class Backend { deleteEntry(config, collection, slug) { const path = selectEntryPath(collection, slug); + + if (!selectAllowDeletion(collection)) { + throw (new Error("Not allowed to delete entries in this collection")); + } + const commitMessage = `Delete ${ collection.get('label') } “${ slug }”`; return this.implementation.deleteFile(path, commitMessage); } diff --git a/src/containers/editorialWorkflow/EntryPageHOC.js b/src/containers/editorialWorkflow/EntryPageHOC.js index afe683ba..c41a81ae 100644 --- a/src/containers/editorialWorkflow/EntryPageHOC.js +++ b/src/containers/editorialWorkflow/EntryPageHOC.js @@ -2,6 +2,7 @@ import React from 'react'; import { connect } from 'react-redux'; import { EDITORIAL_WORKFLOW } from '../../constants/publishModes'; import { selectUnpublishedEntry, selectEntry } from '../../reducers'; +import { selectAllowDeletion } from "../../reducers/collections"; import { loadUnpublishedEntry, persistUnpublishedEntry } from '../../actions/editorialWorkflow'; @@ -15,11 +16,14 @@ export default function EntryPageHOC(EntryPage) { function mapStateToProps(state, ownProps) { const { collections } = state; const isEditorialWorkflow = (state.config.get('publish_mode') === EDITORIAL_WORKFLOW); - const returnObj = { isEditorialWorkflow, showDelete: !ownProps.newEntry }; + const collection = collections.get(ownProps.match.params.name); + const returnObj = { + isEditorialWorkflow, + showDelete: !ownProps.newEntry && selectAllowDeletion(collection), + }; if (isEditorialWorkflow) { returnObj.showDelete = false; const slug = ownProps.match.params.slug; - const collection = collections.get(ownProps.match.params.name); const unpublishedEntry = selectUnpublishedEntry(state, collection.get('name'), slug); if (unpublishedEntry) { returnObj.unpublishedEntry = true; diff --git a/src/reducers/collections.js b/src/reducers/collections.js index 4c0bf1c0..118d9489 100644 --- a/src/reducers/collections.js +++ b/src/reducers/collections.js @@ -47,6 +47,9 @@ const selectors = { allowNewEntries(collection) { return collection.get('create'); }, + allowDeletion(collection) { + return collection.get('delete', true); + }, templateName(collection) { return collection.get('name'); }, @@ -74,6 +77,9 @@ const selectors = { allowNewEntries() { return false; }, + allowDeletion(collection) { + return collection.get('delete', true); + }, templateName(collection, slug) { return slug; }, @@ -86,6 +92,7 @@ export const selectEntryPath = (collection, slug) => selectors[collection.get('t export const selectEntrySlug = (collection, path) => selectors[collection.get('type')].entrySlug(collection, path); export const selectListMethod = collection => selectors[collection.get('type')].listMethod(); export const selectAllowNewEntries = collection => selectors[collection.get('type')].allowNewEntries(collection); +export const selectAllowDeletion = collection => selectors[collection.get('type')].allowDeletion(collection); export const selectTemplateName = (collection, slug) => selectors[collection.get('type')].templateName(collection, slug); export const selectInferedField = (collection, fieldName) => { const inferableField = INFERABLE_FIELDS[fieldName];