From a77f59ce0102bbf54fffca8f51e122b866f5a9b8 Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Tue, 13 Oct 2026 19:12:56 +0200 Subject: [PATCH] fix(dialogs): dashboard settings in the board's three tabs Details, Talen and Delen with a share count, as board LpDashboardInstellingen draws them. The default switch and the detail fields move under Details; nothing is removed. A caller that still asks for the old default tab lands on Details. --- src/modals/DashboardConfigModal.vue | 101 +++++++++--------- .../__tests__/DashboardConfigModal.spec.js | 40 +++++++ 2 files changed, 88 insertions(+), 53 deletions(-) diff --git a/src/modals/DashboardConfigModal.vue b/src/modals/DashboardConfigModal.vue index 24d684b43..70c37069a 100644 --- a/src/modals/DashboardConfigModal.vue +++ b/src/modals/DashboardConfigModal.vue @@ -53,6 +53,12 @@ @click="currentTab = tab.id"> {{ tab.label }} + + {{ tab.count }} + @@ -138,21 +144,9 @@ :uploadFn="iconUploadFn" @input="form.icon = $event" /> - - - - -
+
@@ -171,8 +165,12 @@
+
- + +
-
- -
@@ -448,9 +438,7 @@ import FormatListBulleted from 'vue-material-design-icons/FormatListBulleted.vue import Lock from 'vue-material-design-icons/Lock.vue' import Plus from 'vue-material-design-icons/Plus.vue' import ShareVariant from 'vue-material-design-icons/ShareVariant.vue' -import StarOutline from 'vue-material-design-icons/StarOutline.vue' import Translate from 'vue-material-design-icons/Translate.vue' -import Tune from 'vue-material-design-icons/Tune.vue' import DetailsTab from '../components/Workspace/config/DetailsTab.vue' import LanguagesTab from '../components/Workspace/config/LanguagesTab.vue' import { api } from '../services/api.js' @@ -482,9 +470,7 @@ export default { Close, Account, AccountGroup, - Tune, ShareVariant, - StarOutline, ContentCopy, Check, Lock, @@ -556,7 +542,9 @@ export default { data() { return { - currentTab: this.initialTab || 'general', + currentTab: + this.initialTab === 'default' ? 'general' : this.initialTab || 'general', + form: { name: '', description: '', @@ -657,37 +645,30 @@ export default { */ tabs() { const list = [ - { id: 'general', label: t('launchpad', 'General'), icon: Tune }, + { + id: 'general', + label: t('launchpad', 'Details'), + icon: FormatListBulleted, + }, ] + // dashboard-language-and-details-tabs: language versions, for the + // owner (a dashboard needs a uuid first, so the strip is hidden + // while creating). + if (this.canManageShares && this.dashboard?.uuid) { + list.push({ + id: 'languages', + label: t('launchpad', 'Languages'), + icon: Translate, + }) + } if (this.canManageShares) { list.push({ id: 'sharing', label: t('launchpad', 'Sharing'), icon: ShareVariant, + count: this.localShares.length, }) } - list.push({ - id: 'default', - label: t('launchpad', 'Default'), - icon: StarOutline, - }) - // dashboard-language-and-details-tabs: language versions and - // detail fields, for the owner (a dashboard needs a uuid first, - // so the strip is hidden while creating). - if (this.canManageShares && this.dashboard?.uuid) { - list.push( - { - id: 'languages', - label: t('launchpad', 'Languages'), - icon: Translate, - }, - { - id: 'details', - label: t('launchpad', 'Details'), - icon: FormatListBulleted, - }, - ) - } return list }, @@ -783,7 +764,9 @@ export default { // top-bar share action opens directly on Sharing). Fall back // to General if the requested tab is the share tab but the // user cannot manage shares. - const wanted = this.initialTab || 'general' + // `default` was its own tab; the switch now sits under Details. + const wanted + = this.initialTab === 'default' ? 'general' : this.initialTab || 'general' this.currentTab = wanted === 'sharing' && !this.canManageShares ? 'general' @@ -1457,4 +1440,16 @@ export default { .dashboard-config__error { color: var(--color-error-text); } + +/* The count on the Delen tab (board LpDashboardInstellingen). */ +.dashboard-config__tab-count { + min-width: 20px; + padding: 0 6px; + border-radius: var(--border-radius-pill); + background: var(--color-background-dark); + font-size: 12px; + font-weight: 600; + line-height: 20px; + text-align: center; +} diff --git a/src/modals/__tests__/DashboardConfigModal.spec.js b/src/modals/__tests__/DashboardConfigModal.spec.js index a8b67b9de..8c7eee1fe 100644 --- a/src/modals/__tests__/DashboardConfigModal.spec.js +++ b/src/modals/__tests__/DashboardConfigModal.spec.js @@ -143,4 +143,44 @@ describe('DashboardConfigModal tab split', () => { }) expect(wrapper.vm.currentTab).toBe('general') }) + + it('has the board\'s three tabs: Details, Languages, Sharing', () => { + const wrapper = mountModal() + const ids = wrapper + .findAll('[role="tab"]') + .map((tab) => tab.attributes('data-test')) + expect(ids).toEqual([ + 'config-tab-general', + 'config-tab-languages', + 'config-tab-sharing', + ]) + expect(wrapper.find('[data-test="config-tab-general"]').text()).toContain( + 'Details', + ) + }) + + it('puts the default switch under Details', () => { + const wrapper = mountModal() + const general = wrapper.find('[data-test="config-panel-general"]') + expect(general.text()).toContain('Default dashboard') + expect(wrapper.find('[data-test="config-panel-default"]').exists()).toBe( + false, + ) + }) + + it('lands on Details when an old caller asks for the default tab', () => { + const wrapper = mountModal({ initialTab: 'default' }) + expect(wrapper.vm.currentTab).toBe('general') + }) + + it('counts the shares on the Sharing tab', async () => { + const wrapper = mountModal() + // Let the modal's own share load settle first; it resets the list. + await new Promise((resolve) => setTimeout(resolve, 0)) + wrapper.vm.localShares = [{ shareWith: 'a' }, { shareWith: 'b' }] + await wrapper.vm.$nextTick() + expect( + wrapper.find('[data-test="config-tab-count-sharing"]').text(), + ).toBe('2') + }) })