From c9d9573be9a22afd8f75e176d37057bd8453154e Mon Sep 17 00:00:00 2001 From: Ferdinand Thiessen Date: Thu, 2 Nov 2023 02:09:30 +0100 Subject: [PATCH 1/2] fix(NcAppSettingsDialog): Rework section registration workflow Instead of reading the default slot on mount time we use injected `(un)registerSection` functions. Those can be called by the section to register themself or unregister. This makes the sections reactive and requires less work with internal vnode data. Signed-off-by: Ferdinand Thiessen --- .../NcAppSettingsDialog.vue | 76 ++++++++++--------- .../NcAppSettingsSection.vue | 19 +++++ 2 files changed, 60 insertions(+), 35 deletions(-) diff --git a/src/components/NcAppSettingsDialog/NcAppSettingsDialog.vue b/src/components/NcAppSettingsDialog/NcAppSettingsDialog.vue index 33a3c8183a..a5b3c308b8 100644 --- a/src/components/NcAppSettingsDialog/NcAppSettingsDialog.vue +++ b/src/components/NcAppSettingsDialog/NcAppSettingsDialog.vue @@ -84,16 +84,18 @@ export default { @@ -119,6 +121,12 @@ export default { }, mixins: [isMobile], + provide() { + return { + registerSection: this.registerSection, + unregisterSection: this.registerSection, + } + }, props: { /** @@ -170,6 +178,11 @@ export default { linkClicked: false, addedScrollListener: false, scroller: null, + /** + * Currently registered settings sections + * @type {{ id: string, name: string }} + */ + sections: [], } }, @@ -197,10 +210,6 @@ export default { settingsNavigationAriaLabel() { return t('Settings navigation') }, - - getNavigationItems() { - return this.getSettingsNavigation(this.$slots.default) - }, }, mounted() { @@ -224,36 +233,33 @@ export default { methods: { /** - * Builds the settings navigation menu - * - * @param {object} slots The default slots object passed from the render function. - * @return {Array} the navigation items + * Called when a new section is registered + * @param {string} id The section ID + * @param {string} name The section name */ - getSettingsNavigation(slots) { - // Array of navigationitems strings - const navigationItems = slots.filter(vNode => vNode.componentOptions).map(vNode => { - return { - id: vNode.componentOptions.propsData?.id, - name: vNode.componentOptions.propsData?.name, - } - }) - const navigationNames = slots.map(item => item.name) - const navigationIds = slots.map(item => item.id) - + registerSection(id, name) { // Check for the uniqueness of section names - navigationItems.forEach((element, index) => { - const newNamesArray = [...navigationNames] - const newIdArray = [...navigationIds] - newNamesArray.splice(index, 1) - newIdArray.splice(index, 1) - if (newNamesArray.includes(element.name)) { - throw new Error(`Duplicate section name found: ${element}. Settings navigation sections must have unique section names.`) - } - if (newIdArray.includes(element.id)) { - throw new Error(`Duplicate section id found: ${element}. Settings navigation sections must have unique section ids.`) + if (this.sections.some(({ id: otherId }) => id === otherId)) { + throw new Error(`Duplicate section id found: ${id}. Settings navigation sections must have unique section ids.`) + } + if (this.sections.some(({ name: otherName }) => name === otherName)) { + throw new Error(`Duplicate section name found: ${name}. Settings navigation sections must have unique section names.`) } + + const newSections = [...this.sections, { id, name }] + // Sort sections by order in slots + this.sections = newSections.sort(({ id: idA }, { id: idB }) => { + const indexOf = (id) => this.$slots.default.indexOf(vnode => vnode?.componentOptions?.propsData?.id === id) + return indexOf(idA) - indexOf(idB) }) - return navigationItems + }, + + /** + * Called when a new section is unregistered + * @param {string} id The section ID + */ + unregisterSection(id) { + this.sections = this.sections.filter(({ id: otherId }) => id === otherId) }, /** diff --git a/src/components/NcAppSettingsSection/NcAppSettingsSection.vue b/src/components/NcAppSettingsSection/NcAppSettingsSection.vue index b65a25349f..18037e22d4 100644 --- a/src/components/NcAppSettingsSection/NcAppSettingsSection.vue +++ b/src/components/NcAppSettingsSection/NcAppSettingsSection.vue @@ -32,6 +32,7 @@ From 36bbbf1203c8a83f3e1ef56a092cd3721a65968a Mon Sep 17 00:00:00 2001 From: Ferdinand Thiessen Date: Thu, 2 Nov 2023 02:11:55 +0100 Subject: [PATCH 2/2] feat(NcAppSettingsDialog): Allow to provide icons for the section name in the navigation Signed-off-by: Ferdinand Thiessen --- .../NcAppSettingsDialog.vue | 107 +++++++++++++++++- .../NcAppSettingsSection.vue | 8 +- 2 files changed, 106 insertions(+), 9 deletions(-) diff --git a/src/components/NcAppSettingsDialog/NcAppSettingsDialog.vue b/src/components/NcAppSettingsDialog/NcAppSettingsDialog.vue index a5b3c308b8..a750d80e07 100644 --- a/src/components/NcAppSettingsDialog/NcAppSettingsDialog.vue +++ b/src/components/NcAppSettingsDialog/NcAppSettingsDialog.vue @@ -74,6 +74,69 @@ export default { } ``` + +You can also add icons to the section navigation: + +```vue + + + +```