diff --git a/docs/getting-started/navigation.md b/docs/getting-started/navigation.md index 07ec281b0..aa559fc6f 100644 --- a/docs/getting-started/navigation.md +++ b/docs/getting-started/navigation.md @@ -208,6 +208,34 @@ Navigation definition also supports custom components to be dynamically render. ] ``` +Navigation items or group of navigation items can be conditional render based on defined rules. + +```json +"navbar": [ + { + "id": "custom-group-1", + "rules": { + "visible": "rule-reference-id" + }, + "items": [ ... ] + }, + { + "id": "custom-group-2", + "items": [ + { + "id": "itemId", + "rules": { + "visible": "rule-reference-id" + }, + ... + } + ] + } +] +``` + +For more informations about rules checkout [Rules](../extending/rules.md) section. + Note that components must be declared as entryComponents under the app module. For more information about the content of a custom page see [Document List Layout](/features/document-list-layout) section. diff --git a/src/app/extensions/extension.service.spec.ts b/src/app/extensions/extension.service.spec.ts index cd23575f2..33748a2dc 100644 --- a/src/app/extensions/extension.service.spec.ts +++ b/src/app/extensions/extension.service.spec.ts @@ -694,6 +694,62 @@ describe('AppExtensionService', () => { { items: [{ children: [] }] } ]); }); + + it('should filter out items based on rule', () => { + spyOn(service, 'filterVisible').and.callFake(item => { + if (item.rules) { + return item.rules.visible; + } else { + return true; + } + }); + + const navigation = service.getApplicationNavigation([ + { + id: 'groupId', + items: [ + { + id: 'itemId', + route: 'route1', + rules: { visible: false } + } + ] + } + ]); + + expect(navigation).toEqual([{ id: 'groupId', items: [] }]); + }); + + it('should filter out group based on rule', () => { + spyOn(service, 'filterVisible').and.callFake(item => { + if (item.rules) { + return item.rules.visible; + } else { + return true; + } + }); + + const navigation = service.getApplicationNavigation([ + { + id: 'group1', + rules: { + visible: false + }, + items: [ + { + id: 'item1', + route: 'route1' + } + ] + }, + { + id: 'group2', + items: [] + } + ]); + + expect(navigation).toEqual([{ id: 'group2', items: [] }]); + }); }); describe('getSharedLinkViewerToolbarActions', () => { diff --git a/src/app/extensions/extension.service.ts b/src/app/extensions/extension.service.ts index 6ff144fe7..89937256c 100644 --- a/src/app/extensions/extension.service.ts +++ b/src/app/extensions/extension.service.ts @@ -235,71 +235,73 @@ export class AppExtensionService implements RuleContext { } getApplicationNavigation(elements) { - return elements.map(group => { - return { - ...group, - items: (group.items || []) - .filter(entry => !entry.disabled) - .filter(item => this.filterVisible(item)) - .sort(sortByOrder) - .map(item => { - if (item.children && item.children.length > 0) { - item.children = item.children - .filter(entry => !entry.disabled) - .filter(child => this.filterVisible(child)) - .sort(sortByOrder) - .map(child => { - if (child.component) { - return { - ...child - }; - } + return elements + .filter(group => this.filterVisible(group)) + .map(group => { + return { + ...group, + items: (group.items || []) + .filter(entry => !entry.disabled) + .filter(item => this.filterVisible(item)) + .sort(sortByOrder) + .map(item => { + if (item.children && item.children.length > 0) { + item.children = item.children + .filter(entry => !entry.disabled) + .filter(child => this.filterVisible(child)) + .sort(sortByOrder) + .map(child => { + if (child.component) { + return { + ...child + }; + } + + if (!child.click) { + const childRouteRef = this.extensions.getRouteById( + child.route + ); + const childUrl = `/${ + childRouteRef ? childRouteRef.path : child.route + }`; + return { + ...child, + url: childUrl + }; + } - if (!child.click) { - const childRouteRef = this.extensions.getRouteById( - child.route - ); - const childUrl = `/${ - childRouteRef ? childRouteRef.path : child.route - }`; return { ...child, - url: childUrl + action: child.click }; - } + }); - return { - ...child, - action: child.click - }; - }); + return { + ...item + }; + } - return { - ...item - }; - } + if (item.component) { + return { ...item }; + } - if (item.component) { - return { ...item }; - } + if (!item.click) { + const routeRef = this.extensions.getRouteById(item.route); + const url = `/${routeRef ? routeRef.path : item.route}`; + return { + ...item, + url + }; + } - if (!item.click) { - const routeRef = this.extensions.getRouteById(item.route); - const url = `/${routeRef ? routeRef.path : item.route}`; return { ...item, - url + action: item.click }; - } - - return { - ...item, - action: item.click - }; - }) - .reduce(reduceEmptyMenus, []) - }; - }); + }) + .reduce(reduceEmptyMenus, []) + }; + }); } loadContentMetadata(config: ExtensionConfig): any {