Skip to content

Commit

Permalink
feat(nested collections): allow non-index files
Browse files Browse the repository at this point in the history
This commit fixes decaporg#4972 to allow nested folders with additional content
beyond an index file.

Side effect: To keep the feature simple, this will now show index files
as pages within a folder in NetlifyCMS. This enables creating additional
files alongside the given index, but is a change in behavior from the
current implementation.

Co-authored-by: Eric Gade <[email protected]>
  • Loading branch information
2 people authored and fgnass committed Dec 23, 2024
1 parent 022dbe5 commit f83c1ca
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -119,20 +119,19 @@ export class EntriesCollection extends React.Component {

export function filterNestedEntries(path, collectionFolder, entries) {
const filtered = entries.filter(e => {
const entryPath = e.get('path').slice(collectionFolder.length + 1);
let entryPath = e.get('path').slice(collectionFolder.length + 1);
if (!entryPath.startsWith(path)) {
return false;
}

// only show immediate children
// for subdirectories, trim off the parent folder corresponding to
// this nested collection entry
if (path) {
// non root path
const trimmed = entryPath.slice(path.length + 1);
return trimmed.split('/').length === 2;
} else {
// root path
return entryPath.split('/').length <= 2;
entryPath = entryPath.slice(path.length + 1);
}

// only show immediate children
return !entryPath.includes('/');
});
return filtered;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,11 @@ describe('filterNestedEntries', () => {
];
const entries = fromJS(entriesArray);
expect(filterNestedEntries('dir3', 'src/pages', entries).toJS()).toEqual([
{ slug: 'dir3/dir4/index', path: 'src/pages/dir3/dir4/index.md', data: { title: 'File 4' } },
{ slug: 'dir3/index', path: 'src/pages/dir3/index.md', data: { title: 'File 3' } },
]);
});

it('should return immediate children and root for root path', () => {
it('should return only immediate children for root path', () => {
const entriesArray = [
{ slug: 'index', path: 'src/pages/index.md', data: { title: 'Root' } },
{ slug: 'dir1/index', path: 'src/pages/dir1/index.md', data: { title: 'File 1' } },
Expand All @@ -60,8 +60,6 @@ describe('filterNestedEntries', () => {
const entries = fromJS(entriesArray);
expect(filterNestedEntries('', 'src/pages', entries).toJS()).toEqual([
{ slug: 'index', path: 'src/pages/index.md', data: { title: 'Root' } },
{ slug: 'dir1/index', path: 'src/pages/dir1/index.md', data: { title: 'File 1' } },
{ slug: 'dir3/index', path: 'src/pages/dir3/index.md', data: { title: 'File 3' } },
]);
});
});
Expand Down Expand Up @@ -126,7 +124,7 @@ describe('EntriesCollection', () => {
expect(asFragment()).toMatchSnapshot();
});

it('should render apply filter term for nested collections', () => {
it('should render with applied filter term for nested collections', () => {
const entriesArray = [
{ slug: 'index', path: 'src/pages/index.md', data: { title: 'Root' } },
{ slug: 'dir1/index', path: 'src/pages/dir1/index.md', data: { title: 'File 1' } },
Expand Down
Original file line number Diff line number Diff line change
@@ -1,36 +1,36 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`EntriesCollection should render apply filter term for nested collections 1`] = `
exports[`EntriesCollection should render connected component 1`] = `
<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\\" }"
cursor="[object Object]"
entries="List []"
entries="List [ Map { \\"slug\\": \\"index\\", \\"path\\": \\"src/pages/index.md\\", \\"data\\": Map { \\"title\\": \\"Root\\" } }, Map { \\"slug\\": \\"dir1/index\\", \\"path\\": \\"src/pages/dir1/index.md\\", \\"data\\": Map { \\"title\\": \\"File 1\\" } }, Map { \\"slug\\": \\"dir2/index\\", \\"path\\": \\"src/pages/dir2/index.md\\", \\"data\\": Map { \\"title\\": \\"File 2\\" } } ]"
isfetching="false"
/>
</DocumentFragment>
`;

exports[`EntriesCollection should render connected component 1`] = `
exports[`EntriesCollection should render show only immediate children for nested collection 1`] = `
<DocumentFragment>
<mock-entries
collectionname="Pages"
collections="Map { \\"name\\": \\"pages\\", \\"label\\": \\"Pages\\", \\"folder\\": \\"src/pages\\" }"
collections="Map { \\"name\\": \\"pages\\", \\"label\\": \\"Pages\\", \\"folder\\": \\"src/pages\\", \\"nested\\": Map { \\"depth\\": 10 } }"
cursor="[object Object]"
entries="List [ Map { \\"slug\\": \\"index\\", \\"path\\": \\"src/pages/index.md\\", \\"data\\": Map { \\"title\\": \\"Root\\" } }, Map { \\"slug\\": \\"dir1/index\\", \\"path\\": \\"src/pages/dir1/index.md\\", \\"data\\": Map { \\"title\\": \\"File 1\\" } }, Map { \\"slug\\": \\"dir2/index\\", \\"path\\": \\"src/pages/dir2/index.md\\", \\"data\\": Map { \\"title\\": \\"File 2\\" } } ]"
entries="List [ Map { \\"slug\\": \\"index\\", \\"path\\": \\"src/pages/index.md\\", \\"data\\": Map { \\"title\\": \\"Root\\" } } ]"
isfetching="false"
/>
</DocumentFragment>
`;

exports[`EntriesCollection should render show only immediate children for nested collection 1`] = `
exports[`EntriesCollection should render with applied filter term for nested collections 1`] = `
<DocumentFragment>
<mock-entries
collectionname="Pages"
collections="Map { \\"name\\": \\"pages\\", \\"label\\": \\"Pages\\", \\"folder\\": \\"src/pages\\", \\"nested\\": Map { \\"depth\\": 10 } }"
cursor="[object Object]"
entries="List [ Map { \\"slug\\": \\"index\\", \\"path\\": \\"src/pages/index.md\\", \\"data\\": Map { \\"title\\": \\"Root\\" } }, Map { \\"slug\\": \\"dir1/index\\", \\"path\\": \\"src/pages/dir1/index.md\\", \\"data\\": Map { \\"title\\": \\"File 1\\" } }, Map { \\"slug\\": \\"dir3/index\\", \\"path\\": \\"src/pages/dir3/index.md\\", \\"data\\": Map { \\"title\\": \\"File 3\\" } } ]"
entries="List [ Map { \\"slug\\": \\"dir3/dir4/index\\", \\"path\\": \\"src/pages/dir3/dir4/index.md\\", \\"data\\": Map { \\"title\\": \\"File 4\\" } } ]"
isfetching="false"
/>
</DocumentFragment>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ function TreeNode(props) {

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

const hasChildren = depth === 0 || node.children.some(c => c.children.some(c => c.isDir));
const hasChildren = depth === 0 || 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 @@ -138,6 +138,20 @@ exports[`NestedCollection should render connected component 1`] = `
margin-right: 4px;
}
.emotion-6 {
position: relative;
top: 2px;
color: #fff;
width: 0;
height: 0;
border: 5px solid transparent;
border-radius: 2px;
border-left: 6px solid currentColor;
border-right: 0;
color: currentColor;
left: 2px;
}
<a
class="emotion-0 emotion-1"
data-testid="/a"
Expand All @@ -155,6 +169,9 @@ exports[`NestedCollection should render connected component 1`] = `
>
File 1
</div>
<div
class="emotion-6 emotion-7"
/>
</div>
</a>
.emotion-0 {
Expand Down Expand Up @@ -207,6 +224,20 @@ exports[`NestedCollection should render connected component 1`] = `
margin-right: 4px;
}
.emotion-6 {
position: relative;
top: 2px;
color: #fff;
width: 0;
height: 0;
border: 5px solid transparent;
border-radius: 2px;
border-left: 6px solid currentColor;
border-right: 0;
color: currentColor;
left: 2px;
}
<a
class="emotion-0 emotion-1"
data-testid="/b"
Expand All @@ -224,6 +255,9 @@ exports[`NestedCollection should render connected component 1`] = `
>
File 2
</div>
<div
class="emotion-6 emotion-7"
/>
</div>
</a>
</DocumentFragment>
Expand Down Expand Up @@ -367,6 +401,20 @@ exports[`NestedCollection should render correctly with nested entries 1`] = `
margin-right: 4px;
}
.emotion-6 {
position: relative;
top: 2px;
color: #fff;
width: 0;
height: 0;
border: 5px solid transparent;
border-radius: 2px;
border-left: 6px solid currentColor;
border-right: 0;
color: currentColor;
left: 2px;
}
<a
class="emotion-0 emotion-1"
data-testid="/a"
Expand All @@ -384,6 +432,9 @@ exports[`NestedCollection should render correctly with nested entries 1`] = `
>
File 1
</div>
<div
class="emotion-6 emotion-7"
/>
</div>
</a>
.emotion-0 {
Expand Down Expand Up @@ -436,6 +487,20 @@ exports[`NestedCollection should render correctly with nested entries 1`] = `
margin-right: 4px;
}
.emotion-6 {
position: relative;
top: 2px;
color: #fff;
width: 0;
height: 0;
border: 5px solid transparent;
border-radius: 2px;
border-left: 6px solid currentColor;
border-right: 0;
color: currentColor;
left: 2px;
}
<a
class="emotion-0 emotion-1"
data-testid="/b"
Expand All @@ -453,6 +518,9 @@ exports[`NestedCollection should render correctly with nested entries 1`] = `
>
File 2
</div>
<div
class="emotion-6 emotion-7"
/>
</div>
</a>
</DocumentFragment>
Expand Down

0 comments on commit f83c1ca

Please sign in to comment.