diff --git a/app/client/models/DocModel.ts b/app/client/models/DocModel.ts index ad6ad06d..41a586e4 100644 --- a/app/client/models/DocModel.ts +++ b/app/client/models/DocModel.ts @@ -223,16 +223,21 @@ export class DocModel { this.allPages = ko.computed(() => allPages.all()); this.menuPages = ko.computed(() => { const pagesToShow = this.allPages().filter(p => !p.isSpecial()).sort((a, b) => a.pagePos() - b.pagePos()); - // Helper to find all children of a page. - const children = memoize((page: PageRec) => { - const following = pagesToShow.slice(pagesToShow.indexOf(page) + 1); - const firstOutside = following.findIndex(p => p.indentation() <= page.indentation()); - return firstOutside >= 0 ? following.slice(0, firstOutside) : following; + const parent = memoize((page: PageRec) => { + const myIdentation = page.indentation(); + if (myIdentation === 0) { return null; } + const idx = pagesToShow.indexOf(page); + // Find first page starting from before that has lower indentation then mine. + const beforeMe = pagesToShow.slice(0, idx).reverse(); + return beforeMe.find(p => p.indentation() < myIdentation) ?? null; }); - // Helper to test if the page is hidden and all its children are hidden. - // In that case, we won't show it at all. - const hide = memoize((page: PageRec): boolean => page.isCensored() && children(page).every(p => hide(p))); - return pagesToShow.filter(p => !hide(p)); + const ancestors = memoize((page: PageRec): PageRec[] => { + const anc = parent(page); + return anc ? [anc, ...ancestors(anc)] : []; + }); + // Helper to test if the page is hidden or is in a hidden branch. + const hidden = memoize((page: PageRec): boolean => page.isHidden() || ancestors(page).some(p => p.isHidden())); + return pagesToShow.filter(p => !hidden(p)); }); this.visibleDocPages = ko.computed(() => this.allPages().filter(p => !p.isHidden())); diff --git a/test/nbrowser/Pages.ts b/test/nbrowser/Pages.ts index 1e406904..9d1bde63 100644 --- a/test/nbrowser/Pages.ts +++ b/test/nbrowser/Pages.ts @@ -38,43 +38,34 @@ describe('Pages', function() { assert.deepEqual(await gu.getPageTree(), [ { label: 'Interactions', children: [ - { label: 'Documents' }, + {label: 'Documents' }, ] }, { label: 'People', children: [ - { label: 'User & Leads', children: [{ label: 'Overview' }] }, + {label: 'User & Leads', children: [ + {label: 'Overview'}] }, ] }, ]); const revertAcl = await gu.beginAclTran(api, doc.id); - // Update ACL, hide People table from all users. - await hideTable("People"); + // Update ACL, hide Overview table from all users. + await hideTable("Overview"); // We will be reloaded, but it's not easy to wait for it, so do the refresh manually. await gu.reloadDoc(); assert.deepEqual(await gu.getPageTree(), [ { label: 'Interactions', children: [ - { label: 'Documents'}, + {label: 'Documents'}, ] }, { - label: 'CENSORED', children: [ - { label: 'User & Leads', children: [{ label: 'Overview' }] }, + label: 'People', children: [ + {label: 'User & Leads'}, ] }, ]); - // Test that we can't click this page. - await driver.findContent('.test-treeview-itemHeader', /CENSORED/).click(); - await gu.waitForServer(); - assert.equal(await gu.getSectionTitle(), 'INTERACTIONS'); - - // Test that we don't have move handler. - assert.isFalse( - await driver.findContent('.test-treeview-itemHeaderWrapper', /CENSORED/) - .find('.test-treeview-handle').isPresent() - ); // Now hide User_Leads await hideTable("User_Leads"); @@ -86,14 +77,12 @@ describe('Pages', function() { ] }, { - label: 'CENSORED', children: [ - { label: 'CENSORED', children: [{ label: 'Overview' }] }, - ] + label: 'People' }, ]); - // Now hide Overview, and test that whole node is hidden. - await hideTable("Overview"); + // Now hide People, and test that whole node is hidden. + await hideTable("People"); await gu.reloadDoc(); assert.deepEqual(await gu.getPageTree(), [ {