Skip to content

Commit

Permalink
feat(nested collections) legacy mode (#7387)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
demshy authored Feb 13, 2025
1 parent 08f0ccb commit b85ec3d
Show file tree
Hide file tree
Showing 9 changed files with 39 additions and 11 deletions.
4 changes: 2 additions & 2 deletions dev-test/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ collections: # A list of collections the CMS should be able to edit
folder: '_restaurants'
slug: '{{year}}-{{month}}-{{day}}-{{slug}}'
summary: '{{title}} -- {{year}}/{{month}}/{{day}}'
create: true # Allow users to create new documents in this collection
create: true # Allow users to create new documents in this collection
editor:
visualEditing: true
fields: # The fields each document in this collection have
Expand Down Expand Up @@ -276,7 +276,7 @@ collections: # A list of collections the CMS should be able to edit
label_singular: 'Page'
folder: _pages
create: true
nested: { depth: 100 }
nested: { depth: 100, subfolders: false }
fields:
- label: Title
name: title
Expand Down
1 change: 1 addition & 0 deletions packages/decap-cms-core/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,7 @@ declare module 'decap-cms-core' {
publish?: boolean;
nested?: {
depth: number;
subfolders?: boolean;
};
meta?: { path?: { label: string; widget: string; index_file: string } };

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ export class EntriesCollection extends React.Component {
}
}

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

// if subfolders legacy mode is enabled, show only immediate subfolders
// also show index file in root folder
if (subfolders) {
const depth = entryPath.split('/').length;
return path ? depth === 2 : depth <= 2;
}

// only show immediate children
return !entryPath.includes('/');
});
Expand All @@ -145,7 +152,12 @@ function mapStateToProps(state, ownProps) {

if (collection.has('nested')) {
const collectionFolder = collection.get('folder');
entries = filterNestedEntries(filterTerm || '', collectionFolder, entries);
entries = filterNestedEntries(
filterTerm || '',
collectionFolder,
entries,
collection.get('nested').get('subfolders') !== false,
);
}
const entriesLoaded = selectEntriesLoaded(state.entries, collection.get('name'));
const isFetching = selectIsFetching(state.entries, collection.get('name'));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,9 @@ describe('EntriesCollection', () => {
});

const { asFragment } = renderWithRedux(
<ConnectedEntriesCollection collection={collection.set('nested', fromJS({ depth: 10 }))} />,
<ConnectedEntriesCollection
collection={collection.set('nested', fromJS({ depth: 10, subfolders: false }))}
/>,
{
store,
},
Expand All @@ -140,7 +142,7 @@ describe('EntriesCollection', () => {

const { asFragment } = renderWithRedux(
<ConnectedEntriesCollection
collection={collection.set('nested', fromJS({ depth: 10 }))}
collection={collection.set('nested', fromJS({ depth: 10, subfolders: false }))}
filterTerm="dir3/dir4"
/>,
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ exports[`EntriesCollection should render show only immediate children for nested
<DocumentFragment>
<mock-entries
collectionname="Pages"
collections="Map { \\"name\\": \\"pages\\", \\"label\\": \\"Pages\\", \\"folder\\": \\"src/pages\\", \\"nested\\": Map { \\"depth\\": 10 } }"
collections="Map { \\"name\\": \\"pages\\", \\"label\\": \\"Pages\\", \\"folder\\": \\"src/pages\\", \\"nested\\": Map { \\"depth\\": 10, \\"subfolders\\": false } }"
cursor="[object Object]"
entries="List [ Map { \\"slug\\": \\"index\\", \\"path\\": \\"src/pages/index.md\\", \\"data\\": Map { \\"title\\": \\"Root\\" } } ]"
isfetching="false"
Expand All @@ -28,7 +28,7 @@ exports[`EntriesCollection should render with applied filter term for nested col
<DocumentFragment>
<mock-entries
collectionname="Pages"
collections="Map { \\"name\\": \\"pages\\", \\"label\\": \\"Pages\\", \\"folder\\": \\"src/pages\\", \\"nested\\": Map { \\"depth\\": 10 } }"
collections="Map { \\"name\\": \\"pages\\", \\"label\\": \\"Pages\\", \\"folder\\": \\"src/pages\\", \\"nested\\": Map { \\"depth\\": 10, \\"subfolders\\": false } }"
cursor="[object Object]"
entries="List [ Map { \\"slug\\": \\"dir3/dir4/index\\", \\"path\\": \\"src/pages/dir3/dir4/index.md\\", \\"data\\": Map { \\"title\\": \\"File 4\\" } } ]"
isfetching="false"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,13 @@ function TreeNode(props) {
const collectionName = collection.get('name');

const sortedData = sortBy(treeData, getNodeTitle);
const subfolders = collection.get('nested')?.get('subfolders') !== false;
return sortedData.map(node => {
const leaf = node.children.length === 0 && depth > 0;
const leaf =
depth > 0 &&
(subfolders
? node.children.length <= 1 && !node.children[0]?.isDir
: node.children.length === 0);
if (leaf) {
return null;
}
Expand All @@ -90,7 +95,11 @@ function TreeNode(props) {
}
const title = getNodeTitle(node);

const hasChildren = depth === 0 || node.children.some(c => c.isDir);
const hasChildren =
depth === 0 ||
(subfolders
? node.children.some(c => c.children.some(c => c.isDir))
: node.children.some(c => c.isDir));

return (
<React.Fragment key={node.path}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ describe('NestedCollection', () => {
label: 'Pages',
folder: 'src/pages',
fields: [{ name: 'title', widget: 'string' }],
nested: {
subfolders: false,
},
});

it('should render correctly with no entries', () => {
Expand Down
1 change: 1 addition & 0 deletions packages/decap-cms-core/src/constants/configSchema.js
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@ function getConfigSchema() {
type: 'object',
properties: {
depth: { type: 'number', minimum: 1, maximum: 1000 },
subfolders: { type: 'boolean' },
summary: { type: 'string' },
},
required: ['depth'],
Expand Down
2 changes: 1 addition & 1 deletion packages/decap-cms-core/src/types/redux.ts
Original file line number Diff line number Diff line change
Expand Up @@ -582,7 +582,7 @@ export type CollectionFile = StaticallyTypedRecord<{

export type CollectionFiles = List<CollectionFile>;

type NestedObject = { depth: number };
type NestedObject = { depth: number; subfolders?: boolean };

type Nested = StaticallyTypedRecord<NestedObject>;

Expand Down

0 comments on commit b85ec3d

Please sign in to comment.