Skip to content

Commit b85ec3d

Browse files
authored
feat(nested collections) legacy mode (#7387)
* feat(nested-collections): opt-in to legacy nested folder behaviour * style: lint * feat(nested-collection): default subfolders to true * test(nested-collections): keep the tests in the subfolders: false scenario
1 parent 08f0ccb commit b85ec3d

File tree

9 files changed

+39
-11
lines changed

9 files changed

+39
-11
lines changed

dev-test/config.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ collections: # A list of collections the CMS should be able to edit
6262
folder: '_restaurants'
6363
slug: '{{year}}-{{month}}-{{day}}-{{slug}}'
6464
summary: '{{title}} -- {{year}}/{{month}}/{{day}}'
65-
create: true # Allow users to create new documents in this collection
65+
create: true # Allow users to create new documents in this collection
6666
editor:
6767
visualEditing: true
6868
fields: # The fields each document in this collection have
@@ -276,7 +276,7 @@ collections: # A list of collections the CMS should be able to edit
276276
label_singular: 'Page'
277277
folder: _pages
278278
create: true
279-
nested: { depth: 100 }
279+
nested: { depth: 100, subfolders: false }
280280
fields:
281281
- label: Title
282282
name: title

packages/decap-cms-core/index.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,7 @@ declare module 'decap-cms-core' {
310310
publish?: boolean;
311311
nested?: {
312312
depth: number;
313+
subfolders?: boolean;
313314
};
314315
meta?: { path?: { label: string; widget: string; index_file: string } };
315316

packages/decap-cms-core/src/components/Collection/Entries/EntriesCollection.js

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ export class EntriesCollection extends React.Component {
117117
}
118118
}
119119

120-
export function filterNestedEntries(path, collectionFolder, entries) {
120+
export function filterNestedEntries(path, collectionFolder, entries, subfolders) {
121121
const filtered = entries.filter(e => {
122122
let entryPath = e.get('path').slice(collectionFolder.length + 1);
123123
if (!entryPath.startsWith(path)) {
@@ -130,6 +130,13 @@ export function filterNestedEntries(path, collectionFolder, entries) {
130130
entryPath = entryPath.slice(path.length + 1);
131131
}
132132

133+
// if subfolders legacy mode is enabled, show only immediate subfolders
134+
// also show index file in root folder
135+
if (subfolders) {
136+
const depth = entryPath.split('/').length;
137+
return path ? depth === 2 : depth <= 2;
138+
}
139+
133140
// only show immediate children
134141
return !entryPath.includes('/');
135142
});
@@ -145,7 +152,12 @@ function mapStateToProps(state, ownProps) {
145152

146153
if (collection.has('nested')) {
147154
const collectionFolder = collection.get('folder');
148-
entries = filterNestedEntries(filterTerm || '', collectionFolder, entries);
155+
entries = filterNestedEntries(
156+
filterTerm || '',
157+
collectionFolder,
158+
entries,
159+
collection.get('nested').get('subfolders') !== false,
160+
);
149161
}
150162
const entriesLoaded = selectEntriesLoaded(state.entries, collection.get('name'));
151163
const isFetching = selectIsFetching(state.entries, collection.get('name'));

packages/decap-cms-core/src/components/Collection/Entries/__tests__/EntriesCollection.spec.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,9 @@ describe('EntriesCollection', () => {
115115
});
116116

117117
const { asFragment } = renderWithRedux(
118-
<ConnectedEntriesCollection collection={collection.set('nested', fromJS({ depth: 10 }))} />,
118+
<ConnectedEntriesCollection
119+
collection={collection.set('nested', fromJS({ depth: 10, subfolders: false }))}
120+
/>,
119121
{
120122
store,
121123
},
@@ -140,7 +142,7 @@ describe('EntriesCollection', () => {
140142

141143
const { asFragment } = renderWithRedux(
142144
<ConnectedEntriesCollection
143-
collection={collection.set('nested', fromJS({ depth: 10 }))}
145+
collection={collection.set('nested', fromJS({ depth: 10, subfolders: false }))}
144146
filterTerm="dir3/dir4"
145147
/>,
146148
{

packages/decap-cms-core/src/components/Collection/Entries/__tests__/__snapshots__/EntriesCollection.spec.js.snap

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ exports[`EntriesCollection should render show only immediate children for nested
1616
<DocumentFragment>
1717
<mock-entries
1818
collectionname="Pages"
19-
collections="Map { \\"name\\": \\"pages\\", \\"label\\": \\"Pages\\", \\"folder\\": \\"src/pages\\", \\"nested\\": Map { \\"depth\\": 10 } }"
19+
collections="Map { \\"name\\": \\"pages\\", \\"label\\": \\"Pages\\", \\"folder\\": \\"src/pages\\", \\"nested\\": Map { \\"depth\\": 10, \\"subfolders\\": false } }"
2020
cursor="[object Object]"
2121
entries="List [ Map { \\"slug\\": \\"index\\", \\"path\\": \\"src/pages/index.md\\", \\"data\\": Map { \\"title\\": \\"Root\\" } } ]"
2222
isfetching="false"
@@ -28,7 +28,7 @@ exports[`EntriesCollection should render with applied filter term for nested col
2828
<DocumentFragment>
2929
<mock-entries
3030
collectionname="Pages"
31-
collections="Map { \\"name\\": \\"pages\\", \\"label\\": \\"Pages\\", \\"folder\\": \\"src/pages\\", \\"nested\\": Map { \\"depth\\": 10 } }"
31+
collections="Map { \\"name\\": \\"pages\\", \\"label\\": \\"Pages\\", \\"folder\\": \\"src/pages\\", \\"nested\\": Map { \\"depth\\": 10, \\"subfolders\\": false } }"
3232
cursor="[object Object]"
3333
entries="List [ Map { \\"slug\\": \\"dir3/dir4/index\\", \\"path\\": \\"src/pages/dir3/dir4/index.md\\", \\"data\\": Map { \\"title\\": \\"File 4\\" } } ]"
3434
isfetching="false"

packages/decap-cms-core/src/components/Collection/NestedCollection.js

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,13 @@ function TreeNode(props) {
7979
const collectionName = collection.get('name');
8080

8181
const sortedData = sortBy(treeData, getNodeTitle);
82+
const subfolders = collection.get('nested')?.get('subfolders') !== false;
8283
return sortedData.map(node => {
83-
const leaf = node.children.length === 0 && depth > 0;
84+
const leaf =
85+
depth > 0 &&
86+
(subfolders
87+
? node.children.length <= 1 && !node.children[0]?.isDir
88+
: node.children.length === 0);
8489
if (leaf) {
8590
return null;
8691
}
@@ -90,7 +95,11 @@ function TreeNode(props) {
9095
}
9196
const title = getNodeTitle(node);
9297

93-
const hasChildren = depth === 0 || node.children.some(c => c.isDir);
98+
const hasChildren =
99+
depth === 0 ||
100+
(subfolders
101+
? node.children.some(c => c.children.some(c => c.isDir))
102+
: node.children.some(c => c.isDir));
94103

95104
return (
96105
<React.Fragment key={node.path}>

packages/decap-cms-core/src/components/Collection/__tests__/NestedCollection.spec.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ describe('NestedCollection', () => {
3737
label: 'Pages',
3838
folder: 'src/pages',
3939
fields: [{ name: 'title', widget: 'string' }],
40+
nested: {
41+
subfolders: false,
42+
},
4043
});
4144

4245
it('should render correctly with no entries', () => {

packages/decap-cms-core/src/constants/configSchema.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,7 @@ function getConfigSchema() {
260260
type: 'object',
261261
properties: {
262262
depth: { type: 'number', minimum: 1, maximum: 1000 },
263+
subfolders: { type: 'boolean' },
263264
summary: { type: 'string' },
264265
},
265266
required: ['depth'],

packages/decap-cms-core/src/types/redux.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -582,7 +582,7 @@ export type CollectionFile = StaticallyTypedRecord<{
582582

583583
export type CollectionFiles = List<CollectionFile>;
584584

585-
type NestedObject = { depth: number };
585+
type NestedObject = { depth: number; subfolders?: boolean };
586586

587587
type Nested = StaticallyTypedRecord<NestedObject>;
588588

0 commit comments

Comments
 (0)