Repository: decaporg/decap-cms (JavaScript)

Issue:
It should not be possible to delete entries in a file collection
_Ported from https://github.com/netlify-templates/gatsby-starter-netlify-cms/issues/266 raised by @switowski_

<!-- Please don't delete this template because we'll close your issue -->
<!-- Before creating an issue please make sure you are using the latest version of the starter. -->
<!-- This project is starter project using Gatsby and NetlifyCMS in it, if you think the issue can originate from upstream then please report it-->
# Bug report

<!-- Please ask questions on Spectrum for Gatsby questions or the Gitter channel for NetlifyCMS. -->
<!-- https://spectrum.chat/?t=da07ec65-96f9-41be-baf0-0271b5b772ef -->
<!-- https://gitter.im/netlify/NetlifyCMS -->
<!-- Issues which contain questions or support requests will be closed. -->

**What is the current behavior?**

When I delete a page from the admin panel, the Netlify builds will crash.

**If the current behavior is a bug, please provide the steps to reproduce.**

* I started from a clean installation (by clicking "Deploy to netlify" under the "Gatsby Site Starter" on https://www.netlifycms.org/docs/start-with-a-template/).
* I deleted the "Products" page from the admin panel by clicking "Delete entry"
* Now the builds on Netlify are failing (because of a problem reported here: https://github.com/netlify/netlify-cms/issues/2314):

```
9:19:32 AM: success update schema — 0.059
9:19:33 AM: error #85907 GRAPHQL
9:19:33 AM: There was an error in your GraphQL query:
9:19:33 AM: - Unknown field 'testimonials' on type 'MarkdownRemarkFrontmatter'.
9:19:33 AM: File: src/templates/product-page.js
9:19:33 AM: See our docs page for more info on this error: https://gatsby.dev/issue-how-to
9:19:33 AM: npm
9:19:33 AM:  ERR! code ELIFECYCLE
9:19:33 AM: npm
9:19:33 AM:  ERR! errno
9:19:33 AM:  1
9:19:33 AM: npm
9:19:33 AM: ERR! gatsby-starter-netlify-cms@1.1.3 build:app: `npm run clean && gatsby build`
```


<!-- A great way to do this is to provide your configuration via a GitHub repository -->
<!-- The most helpful is a minimal reproduction with instructions on how to reproduce -->
<!-- Please only add small code snippets directly into this issue -->
<!-- https://gist.github.com is a good place for longer code snippets -->
<!-- If your issue is caused by a plugin or loader, please create an issue on the loader/plugin repository instead -->

**What is the expected behavior?**

According to the information that I got from this short Twitter exchange: https://twitter.com/SebaWitowski/status/1152122153946558464
it shouldn't be possible to delete the pages from the admin interface as it will break Gatsby.
So maybe you can delete/hide the "Delete entry" button for the pages?

<!-- "It should work" is not a helpful explanation -->
<!-- Explain exactly how it should behave -->

**Other relevant information:**

I don't have gatsby installed locally. I just clicked "Deploy to Netlify" and logged in to the admin panel directly.
The last commit of `gatsby-starter-netlify-cms` at the time when I deployed it to Netlify was:
```
commit 62a53ae6de9f703ecb80937e448a8c0cf013cea1
Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Date:   Wed Jul 17 13:45:21 2019 -0400

    chore(deps): lock file maintenance (#252)
```
<!--Run `gatsby info --clipboard` in your project directory and paste the output here. Not working? You may need to update your global gatsby-cli - `npm install -g gatsby-cli` -->

Node.js version: 
NPM/Yarn version
Operating System: 
Additional tools:


Discussion:
This issue was raised on the Gatsby starter repo, but the core issue is that file collection entries can be deleted for some reason, even though they can't be created from the CMS. I'm not sure if this is a regression or if it was always this way, but deletion should be disabled for file collection entries.
@erquhart Is there any way to approach this issue? I am thinking about passing `delete: false` in [config.yml](https://github.com/netlify-templates/gatsby-starter-netlify-cms/blob/master/static/admin/config.yml)
@Ananthakr that should work, looking at the code it appears that delete defaults to true for a file-based collection but you should be able to override it.
`delete: false` doesn't do anything. There is still the option to delete the file. Also `widget` doesn't work and `editor: { preview: false }` doesn't work. They are all ignored.

config:
```
import CMS from "netlify-cms-app";

const config = {
  load_config_file: false,
  media_folder: "static/img",
  public_folder: "img",
  collections: [
    {
      label: "Settings",
      name: "settings",
      files: [
        {
          label: "Business Details",
          name: "business",
          delete: false,
          editor: {
            preview: false
          },
          widget: "list",
          file: `${__dirname}/data/business.yaml`,
          fields: [
            { label: "Business Name", name: "name", widget: "string" },
            { label: "Phone Number", name: "phone", widget: "string" },
            { label: "Email", name: "email", widget: "string" }
          ]
        }
      ]
    }
  ]
};

CMS.init({ config });
```
@TidyIQ Those properties do work, but only on a collection level, not per file.
OK cool thanks, that works for `delete` and `preview` however it still doesn't work for `widget`.
That's because you haven't nested the list widget within the file's `fields` property. Have a look at the [file collections example ](https://www.netlifycms.org/docs/collection-types/#file-collections)from the docs to better understand the structure.

That will still result in the fields being a key: value pair rather than a list. As per the example provided in that link, it will result in something like:

```
// site/content/about.yml

title: Title
intro: ##Markdown intro content
team:
  - name: Team One
    position: Boss
```

Whereas adding it where I have **should** result in the following (although like I mentioned, it doesn't. It just gets ignored):

```
// site/content/about.yml

- title: Title
  intro: ##Markdown intro content
  team:
    - name: Team One
      position: Boss
```
That's not yet supported, lists have to be named, unfortunately. https://github.com/netlify/netlify-cms/issues/1877
OK, thanks. I'll have to figure out a workaround as I'm having the same problem when using Gatsby as the OP of that issue (although I'm using the `gatsby-transformer-yaml` plugin instead of `gatsby-transformer-json`).



Patch:
diff --git a/packages/netlify-cms-core/src/reducers/collections.js b/packages/netlify-cms-core/src/reducers/collections.js
index 9296dafd2213..c2ae8b5a40e9 100644
--- a/packages/netlify-cms-core/src/reducers/collections.js
+++ b/packages/netlify-cms-core/src/reducers/collections.js
@@ -89,7 +89,7 @@ const selectors = {
       return false;
     },
     allowDeletion(collection) {
-      return collection.get('delete', true);
+      return collection.get('delete', false);
     },
     templateName(collection, slug) {
       return slug;


Test patch:
diff --git a/packages/netlify-cms-core/src/reducers/__tests__/collections.spec.js b/packages/netlify-cms-core/src/reducers/__tests__/collections.spec.js
index 151f5d72f8f0..4ca7eee6f214 100644
--- a/packages/netlify-cms-core/src/reducers/__tests__/collections.spec.js
+++ b/packages/netlify-cms-core/src/reducers/__tests__/collections.spec.js
@@ -1,6 +1,7 @@
 import { OrderedMap, fromJS } from 'immutable';
 import { configLoaded } from 'Actions/config';
-import collections from '../collections';
+import collections, { selectAllowDeletion } from '../collections';
+import { FILES, FOLDER } from 'Constants/collectionTypes';
 
 describe('collections', () => {
   it('should handle an empty state', () => {
@@ -29,9 +30,22 @@ describe('collections', () => {
           name: 'posts',
           folder: '_posts',
           fields: [{ name: 'title', widget: 'string' }],
-          type: 'folder_based_collection',
+          type: FOLDER,
         }),
       }),
     );
   });
+
+  describe('selectAllowDeletions', () => {
+    it('should not allow deletions for file collections', () => {
+      expect(
+        selectAllowDeletion(
+          fromJS({
+            name: 'pages',
+            type: FILES,
+          }),
+        ),
+      ).toBe(false);
+    });
+  });
 });