@conduction/nextcloud-vue 2.97.0 → 2.98.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/components/CnAppRoot/CnAppRoot.vue2.js +17 -0
- package/dist/esm/components/CnAppRoot/CnAppRoot.vue2.js.map +1 -1
- package/dist/esm/components/CnAppRoot/CnAppRoot.vue3.js.map +1 -1
- package/dist/esm/components/CnChartWidget/CnChartWidget.vue.js +1 -1
- package/dist/esm/components/CnChartWidget/CnChartWidget.vue2.js +106 -2
- package/dist/esm/components/CnChartWidget/CnChartWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnChartWidget/CnChartWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnChecklistRunWidget/CnChecklistRunWidget.vue.js +9 -0
- package/dist/esm/components/CnChecklistRunWidget/CnChecklistRunWidget.vue.js.map +1 -0
- package/dist/esm/components/CnChecklistRunWidget/CnChecklistRunWidget.vue2.js +964 -0
- package/dist/esm/components/CnChecklistRunWidget/CnChecklistRunWidget.vue2.js.map +1 -0
- package/dist/esm/components/CnChecklistRunWidget/CnChecklistRunWidget.vue3.js +282 -0
- package/dist/esm/components/CnChecklistRunWidget/CnChecklistRunWidget.vue3.js.map +1 -0
- package/dist/esm/components/CnChecklistRunWidget/index.js +28 -0
- package/dist/esm/components/CnChecklistRunWidget/index.js.map +1 -0
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue.js +1 -1
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js +1 -0
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js.map +1 -1
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue3.js.map +1 -1
- package/dist/esm/components/CnDataTable/CnDataTable.vue2.js +26 -8
- package/dist/esm/components/CnDataTable/CnDataTable.vue2.js.map +1 -1
- package/dist/esm/components/CnDataTable/CnDataTable.vue3.js.map +1 -1
- package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js +188 -5
- package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js.map +1 -1
- package/dist/esm/components/CnDetailPage/CnDetailPage.vue3.js.map +1 -1
- package/dist/esm/components/CnFeaturesAndRoadmapView/CnFeaturesAndRoadmapView.vue.js +1 -1
- package/dist/esm/components/CnFeaturesAndRoadmapView/CnFeaturesAndRoadmapView.vue2.js +3 -3
- package/dist/esm/components/CnFeaturesAndRoadmapView/CnFeaturesAndRoadmapView.vue2.js.map +1 -1
- package/dist/esm/components/CnFeaturesAndRoadmapView/CnFeaturesAndRoadmapView.vue3.js.map +1 -1
- package/dist/esm/components/CnFeaturesBoard/CnFeaturesBoard.vue.js +1 -1
- package/dist/esm/components/CnFeaturesBoard/CnFeaturesBoard.vue2.js +27 -0
- package/dist/esm/components/CnFeaturesBoard/CnFeaturesBoard.vue2.js.map +1 -1
- package/dist/esm/components/CnFeaturesBoard/CnFeaturesBoard.vue3.js +16 -2
- package/dist/esm/components/CnFeaturesBoard/CnFeaturesBoard.vue3.js.map +1 -1
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js +43 -3
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js.map +1 -1
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js.map +1 -1
- package/dist/esm/components/CnOrderedListField/CnOrderedListField.vue.js +9 -0
- package/dist/esm/components/CnOrderedListField/CnOrderedListField.vue.js.map +1 -0
- package/dist/esm/components/CnOrderedListField/CnOrderedListField.vue2.js +220 -0
- package/dist/esm/components/CnOrderedListField/CnOrderedListField.vue2.js.map +1 -0
- package/dist/esm/components/CnOrderedListField/CnOrderedListField.vue3.js +121 -0
- package/dist/esm/components/CnOrderedListField/CnOrderedListField.vue3.js.map +1 -0
- package/dist/esm/components/CnUserSettingsDialog/CnUserSettingsDialog.vue.js +1 -1
- package/dist/esm/components/CnUserSettingsDialog/CnUserSettingsDialog.vue2.js +83 -9
- package/dist/esm/components/CnUserSettingsDialog/CnUserSettingsDialog.vue2.js.map +1 -1
- package/dist/esm/components/CnUserSettingsDialog/CnUserSettingsDialog.vue3.js +80 -11
- package/dist/esm/components/CnUserSettingsDialog/CnUserSettingsDialog.vue3.js.map +1 -1
- package/dist/esm/components/CnWidgetGrid/registerDashboardWidgets.js +1 -0
- package/dist/esm/components/CnWidgetGrid/registerDashboardWidgets.js.map +1 -1
- package/dist/esm/composables/indexSources.js +238 -2
- package/dist/esm/composables/indexSources.js.map +1 -1
- package/dist/esm/composables/useOrganisationStore.js +115 -0
- package/dist/esm/composables/useOrganisationStore.js.map +1 -0
- package/dist/esm/index.js +2 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/l10n/en.json.js +15 -1
- package/dist/esm/l10n/en.json.js.map +1 -1
- package/dist/esm/l10n/nl.json.js +30 -1
- package/dist/esm/l10n/nl.json.js.map +1 -1
- package/dist/esm/library-style.js +1 -1
- package/dist/esm/nextcloud-vue.css +424 -206
- package/dist/esm/utils/builtInFormatters.js +34 -1
- package/dist/esm/utils/builtInFormatters.js.map +1 -1
- package/dist/esm/utils/libraryWidgetKeys.js +1 -0
- package/dist/esm/utils/libraryWidgetKeys.js.map +1 -1
- package/dist/esm/utils/matrixCells.js +158 -0
- package/dist/esm/utils/matrixCells.js.map +1 -0
- package/dist/esm/utils/nextcloudDirectory.js +121 -0
- package/dist/esm/utils/nextcloudDirectory.js.map +1 -0
- package/dist/esm/utils/validateManifestV2.compiled.js +3 -3
- package/dist/esm/utils/validateManifestV2.compiled.js.map +1 -1
- package/dist/nextcloud-vue.cjs.js +12538 -9716
- package/dist/nextcloud-vue.cjs.js.map +2 -2
- package/dist/nextcloud-vue.css +424 -206
- package/l10n/en.json +15 -1
- package/l10n/nl.json +30 -1
- package/package.json +2 -2
- package/scripts/merge-l10n.js +196 -0
- package/src/components/CnAppRoot/CnAppRoot.md +1 -0
- package/src/components/CnAppRoot/CnAppRoot.vue +17 -0
- package/src/components/CnChartWidget/CnChartWidget.md +2 -1
- package/src/components/CnChartWidget/CnChartWidget.vue +106 -2
- package/src/components/CnChecklistRunWidget/CnChecklistRunWidget.vue +1269 -0
- package/src/components/CnChecklistRunWidget/index.js +27 -0
- package/src/components/CnDashboardPage/CnDashboardPage.vue +1 -0
- package/src/components/CnDataTable/CnDataTable.vue +26 -8
- package/src/components/CnDetailPage/CnDetailPage.md +48 -0
- package/src/components/CnDetailPage/CnDetailPage.vue +188 -5
- package/src/components/CnFeaturesAndRoadmapView/CnFeaturesAndRoadmapView.vue +3 -3
- package/src/components/CnFeaturesBoard/CnFeaturesBoard.vue +38 -2
- package/src/components/CnIndexPage/CnIndexPage.md +28 -0
- package/src/components/CnIndexPage/CnIndexPage.vue +43 -3
- package/src/components/CnOrderedListField/CnOrderedListField.vue +386 -0
- package/src/components/CnOrderedListField/index.js +7 -0
- package/src/components/CnUserSettingsDialog/CnUserSettingsDialog.vue +139 -10
- package/src/components/CnWidgetGrid/registerDashboardWidgets.js +1 -0
- package/src/components/index.js +2 -0
- package/src/composables/indexSources.js +237 -1
- package/src/composables/useOrganisationStore.js +111 -0
- package/src/index.js +2 -0
- package/src/schemas/app-manifest-v2.schema.json +33 -3
- package/src/utils/builtInFormatters.js +33 -0
- package/src/utils/libraryWidgetKeys.js +1 -0
- package/src/utils/matrixCells.js +154 -0
- package/src/utils/nextcloudDirectory.js +117 -0
- package/src/utils/validateManifestV2.compiled.js +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CnUserSettingsDialog.vue2.js","sources":["../../../../src/components/CnUserSettingsDialog/CnUserSettingsDialog.vue"],"sourcesContent":["<!--\n - SPDX-FileCopyrightText: 2026 Conduction B.V.\n - SPDX-License-Identifier: EUPL-1.2\n-->\n<template>\n\t<CnDialog\n\t\tclass=\"cn-user-settings-dialog\"\n\t\t:name=\"title\"\n\t\tlook=\"board\"\n\t\twidth=\"wizard\"\n\t\t:eyebrow=\"eyebrow\"\n\t\t:subtitle=\"subtitle\"\n\t\t:open=\"open\"\n\t\t:style=\"eyebrowStyle\"\n\t\tdata-testid=\"cn-user-settings-dialog\"\n\t\t@update:open=\"onUpdateOpen\"\n\t\t@closing=\"close\">\n\t\t<div class=\"cn-user-settings-dialog__body\">\n\t\t\t<nav\n\t\t\t\tv-if=\"sections.length > 0\"\n\t\t\t\tclass=\"cn-user-settings-dialog__nav\"\n\t\t\t\t:aria-label=\"navLabel\"\n\t\t\t\tdata-testid=\"cn-user-settings-nav\">\n\t\t\t\t<ul>\n\t\t\t\t\t<li v-for=\"section in sections\" :key=\"section.id\">\n\t\t\t\t\t\t<a\n\t\t\t\t\t\t\t:href=\"`#settings-section_${section.id}`\"\n\t\t\t\t\t\t\tclass=\"cn-user-settings-dialog__nav-link\"\n\t\t\t\t\t\t\t:class=\"{ 'cn-user-settings-dialog__nav-link--active': section.id === selected }\"\n\t\t\t\t\t\t\t:aria-current=\"section.id === selected ? 'true' : undefined\"\n\t\t\t\t\t\t\t:data-testid=\"`cn-user-settings-nav-${section.id}`\"\n\t\t\t\t\t\t\t@click.prevent=\"selectSection(section.id)\">\n\t\t\t\t\t\t\t<span v-if=\"section.icon\" class=\"cn-user-settings-dialog__nav-icon\" aria-hidden=\"true\">\n\t\t\t\t\t\t\t\t<CnVNodes :vnodes=\"section.icon\" />\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t<span>{{ section.name }}</span>\n\t\t\t\t\t\t</a>\n\t\t\t\t\t</li>\n\t\t\t\t</ul>\n\t\t\t</nav>\n\t\t\t<div class=\"cn-user-settings-dialog__sections\">\n\t\t\t\t<!-- @slot default NcAppSettingsSection children; each registers itself in the navigation. -->\n\t\t\t\t<slot />\n\t\t\t</div>\n\t\t</div>\n\t\t<template #actions>\n\t\t\t<p class=\"cn-user-settings-dialog__note\" data-testid=\"cn-user-settings-note\">\n\t\t\t\t{{ footerNote }}\n\t\t\t</p>\n\t\t\t<NcButton variant=\"secondary\" data-testid=\"cn-user-settings-close\" @click=\"close\">\n\t\t\t\t{{ closeLabel }}\n\t\t\t</NcButton>\n\t\t</template>\n\t</CnDialog>\n</template>\n\n<script>\nimport { translate as t } from '@nextcloud/l10n'\nimport { NcButton } from '@nextcloud/vue'\nimport { markRaw } from 'vue'\nimport CnDialog from '../CnDialog/CnDialog.vue'\n\n/**\n * The key NcAppSettingsSection injects to register itself with its dialog\n * (`Symbol.for`, so the same symbol `@nextcloud/vue` provides).\n */\nconst REGISTRATION_KEY = Symbol.for('NcAppSettingsDialog:registration')\n\n/** Renders a section's icon vnodes as they were registered. */\nconst CnVNodes = {\n\tname: 'CnVNodes',\n\tprops: { vnodes: { type: [Array, Object], default: null } },\n\trender() {\n\t\treturn this.vnodes\n\t},\n}\n\n/**\n * CnUserSettingsDialog - the user settings dialog in the board look (board\n * PqPersoonlijk): eyebrow, title and subtitle, a left navigation listing the\n * sections with their icons, the sections themselves, and a footer with a\n * note that changes save straight away and a Close button.\n *\n * The sections stay the app's: any `NcAppSettingsSection` in the default slot\n * registers itself with this dialog exactly as it does with\n * `NcAppSettingsDialog`, with its name, order and `#icon` slot. CnAppRoot\n * renders this dialog instead of `NcAppSettingsDialog` under the board look.\n *\n * @spec openspec/changes/user-settings-board-dialog/specs/user-settings-board-dialog/spec.md#requirement-the-user-settings-dialog-takes-the-board-look\n *\n * @event update:open Emitted with `false` when the dialog closes.\n */\nexport default {\n\tname: 'CnUserSettingsDialog',\n\n\tcomponents: { CnDialog, CnVNodes, NcButton },\n\n\tprovide() {\n\t\treturn {\n\t\t\t[REGISTRATION_KEY]: {\n\t\t\t\tregisterSection: this.registerSection,\n\t\t\t\tunregisterSection: this.unregisterSection,\n\t\t\t},\n\t\t}\n\t},\n\n\tprops: {\n\t\t/** Whether the dialog is open. */\n\t\topen: { type: Boolean, default: false },\n\t\t/** Dialog title; also its accessible name. */\n\t\ttitle: { type: String, required: true },\n\t\t/** Context line above the title. */\n\t\teyebrow: { type: String, default: () => t('nextcloud-vue', 'Your account') },\n\t\t/** Sentence under the title. */\n\t\tsubtitle: { type: String, default: () => t('nextcloud-vue', 'Only for you. Colleagues keep their own settings.') },\n\t\t/** The app's name, after the footer note. */\n\t\tappName: { type: String, default: '' },\n\t},\n\n\temits: ['update:open'],\n\n\tdata() {\n\t\treturn {\n\t\t\tsections: [],\n\t\t\tselected: '',\n\t\t\tpicked: false,\n\t\t}\n\t},\n\n\tcomputed: {\n\t\t/** @return {object} The board's eyebrow: muted, in sentence case. */\n\t\teyebrowStyle() {\n\t\t\treturn { '--cn-dialog-eyebrow-transform': 'none', '--cn-dialog-eyebrow-color': 'var(--color-text-maxcontrast)' }\n\t\t},\n\n\t\t/** @return {string} The navigation's accessible name. */\n\t\tnavLabel() {\n\t\t\treturn t('nextcloud-vue', 'Sections of the settings')\n\t\t},\n\n\t\t/** @return {string} The footer note, with the app's name when known. */\n\t\tfooterNote() {\n\t\t\tconst note = t('nextcloud-vue', 'Changes are saved straight away')\n\t\t\treturn this.appName ? `${note} · ${this.appName}` : note\n\t\t},\n\n\t\t/** @return {string} The Close button label. */\n\t\tcloseLabel() {\n\t\t\treturn t('nextcloud-vue', 'Close')\n\t\t},\n\t},\n\n\tmethods: {\n\t\t/**\n\t\t * Add a section to the navigation, kept in `order`; a section\n\t\t * without one goes last. Until the reader picks one, the first\n\t\t * section is current.\n\t\t *\n\t\t * @param {string} id The section id.\n\t\t * @param {string} name The section name.\n\t\t * @param {number} [order] The section's place.\n\t\t * @param {Array} [icon] The section's icon vnodes.\n\t\t */\n\t\tregisterSection(id, name, order, icon) {\n\t\t\tconst rest = this.sections.filter((section) => section.id !== id)\n\t\t\tconst place = typeof order === 'number' ? order : Math.max(0, ...rest.map((section) => section.order)) + 1\n\t\t\tthis.sections = [...rest, { id, name, order: place, icon: icon ? markRaw(icon) : null }].sort((a, b) => a.order - b.order)\n\t\t\tif (!this.picked) {\n\t\t\t\tthis.selected = this.sections[0].id\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Remove a section from the navigation.\n\t\t *\n\t\t * @param {string} id The section id.\n\t\t */\n\t\tunregisterSection(id) {\n\t\t\tthis.sections = this.sections.filter((section) => section.id !== id)\n\t\t\tif (this.selected === id) {\n\t\t\t\tthis.selected = this.sections.length > 0 ? this.sections[0].id : ''\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Mark a section current and scroll it into view.\n\t\t *\n\t\t * @param {string} id The section id.\n\t\t */\n\t\tselectSection(id) {\n\t\t\tthis.picked = true\n\t\t\tthis.selected = id\n\t\t\tconst target = typeof document !== 'undefined' ? document.getElementById(`settings-section_${id}`) : null\n\t\t\tif (target && typeof target.scrollIntoView === 'function') {\n\t\t\t\ttarget.scrollIntoView({ behavior: 'smooth', block: 'start' })\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Follow NcDialog's own open state.\n\t\t *\n\t\t * @param {boolean} value Whether NcDialog is open.\n\t\t */\n\t\tonUpdateOpen(value) {\n\t\t\tif (!value) {\n\t\t\t\tthis.close()\n\t\t\t}\n\t\t},\n\n\t\t/** Close the dialog. */\n\t\tclose() {\n\t\t\t/**\n\t\t\t * @event update:open Emitted with `false` when the dialog closes (Close button, close icon, Escape).\n\t\t\t */\n\t\t\tthis.$emit('update:open', false)\n\t\t},\n\t},\n}\n</script>\n\n<style scoped>\n.cn-user-settings-dialog__body {\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\tgap: 0 24px;\n}\n\n.cn-user-settings-dialog__nav {\n\tflex: 0 0 200px;\n\twidth: 200px;\n\tpadding-top: 18px;\n}\n\n.cn-user-settings-dialog__nav ul {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 2px;\n\tmargin: 0;\n\tpadding: 0;\n\tlist-style: none;\n}\n\n.cn-user-settings-dialog__nav-link {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 10px;\n\tmin-height: 40px;\n\tpadding: 0 12px;\n\tborder-radius: var(--border-radius-element, 8px);\n\tfont-size: 15px;\n\tcolor: var(--color-main-text);\n\ttext-decoration: none;\n}\n\n.cn-user-settings-dialog__nav-link:hover {\n\tbackground: var(--color-background-hover);\n}\n\n.cn-user-settings-dialog__nav-link:focus-visible {\n\toutline: 2px solid var(--color-primary-element);\n\toutline-offset: 2px;\n}\n\n.cn-user-settings-dialog__nav-link--active,\n.cn-user-settings-dialog__nav-link--active:hover {\n\tbackground: var(--color-primary-element-light);\n\tcolor: var(--color-primary-element-light-text);\n\tfont-weight: 600;\n}\n\n.cn-user-settings-dialog__nav-icon {\n\tdisplay: inline-flex;\n\tflex: none;\n\twidth: 18px;\n\theight: 18px;\n\talign-items: center;\n\tjustify-content: center;\n}\n\n.cn-user-settings-dialog__sections {\n\tdisplay: flex;\n\tflex: 1 1 380px;\n\tflex-direction: column;\n\tmin-width: 0;\n}\n\n.cn-user-settings-dialog__sections :deep(.app-settings-section) {\n\tmargin: 0;\n\tpadding: 18px 0;\n\tborder-top: 1px solid var(--color-border);\n}\n\n.cn-user-settings-dialog__sections :deep(.app-settings-section__name) {\n\tmargin: 0 0 12px;\n\tfont-size: 17px;\n\tfont-weight: 700;\n}\n\n.cn-user-settings-dialog__note {\n\tflex: 1 1 auto;\n\tmargin: 0;\n\tfont-size: 14px;\n\tcolor: var(--color-text-maxcontrast);\n}\n</style>\n"],"names":["CnDialog","t"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"CnUserSettingsDialog.vue2.js","sources":["../../../../src/components/CnUserSettingsDialog/CnUserSettingsDialog.vue"],"sourcesContent":["<!--\n - SPDX-FileCopyrightText: 2026 Conduction B.V.\n - SPDX-License-Identifier: EUPL-1.2\n-->\n<template>\n\t<CnDialog\n\t\tclass=\"cn-user-settings-dialog\"\n\t\t:name=\"title\"\n\t\tlook=\"board\"\n\t\twidth=\"wizard\"\n\t\t:eyebrow=\"eyebrow\"\n\t\t:subtitle=\"subtitle\"\n\t\t:open=\"open\"\n\t\t:style=\"eyebrowStyle\"\n\t\tdata-testid=\"cn-user-settings-dialog\"\n\t\t@update:open=\"onUpdateOpen\"\n\t\t@closing=\"close\">\n\t\t<div class=\"cn-user-settings-dialog__body\">\n\t\t\t<nav\n\t\t\t\tv-if=\"sections.length > 0\"\n\t\t\t\tclass=\"cn-user-settings-dialog__nav\"\n\t\t\t\t:aria-label=\"navLabel\"\n\t\t\t\tdata-testid=\"cn-user-settings-nav\">\n\t\t\t\t<!-- `nextcloudLinks`: Nextcloud's own personal settings first, as\n\t\t\t\t links, then one entry for this app holding its sections. -->\n\t\t\t\t<ul v-if=\"ncLinks.length > 0\" class=\"cn-user-settings-dialog__nc-links\" data-testid=\"cn-user-settings-nc-links\">\n\t\t\t\t\t<li v-for=\"link in ncLinks\" :key=\"link.key\">\n\t\t\t\t\t\t<a :href=\"link.href\" class=\"cn-user-settings-dialog__nav-link\">\n\t\t\t\t\t\t\t<span v-if=\"link.icon\" class=\"cn-user-settings-dialog__nav-icon\" aria-hidden=\"true\">\n\t\t\t\t\t\t\t\t<CnIcon :name=\"link.icon\" :size=\"18\" />\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t<span>{{ link.label }}</span>\n\t\t\t\t\t\t</a>\n\t\t\t\t\t</li>\n\t\t\t\t</ul>\n\t\t\t\t<p v-if=\"ncLinks.length > 0 && appName\"\n\t\t\t\t\tclass=\"cn-user-settings-dialog__group\"\n\t\t\t\t\tdata-testid=\"cn-user-settings-app-group\">\n\t\t\t\t\t{{ appName }}\n\t\t\t\t</p>\n\t\t\t\t<ul :class=\"{ 'cn-user-settings-dialog__group-sections': ncLinks.length > 0 }\">\n\t\t\t\t\t<li v-for=\"section in sections\" :key=\"section.id\">\n\t\t\t\t\t\t<a\n\t\t\t\t\t\t\t:href=\"`#settings-section_${section.id}`\"\n\t\t\t\t\t\t\tclass=\"cn-user-settings-dialog__nav-link\"\n\t\t\t\t\t\t\t:class=\"{ 'cn-user-settings-dialog__nav-link--active': section.id === selected }\"\n\t\t\t\t\t\t\t:aria-current=\"section.id === selected ? 'true' : undefined\"\n\t\t\t\t\t\t\t:data-testid=\"`cn-user-settings-nav-${section.id}`\"\n\t\t\t\t\t\t\t@click.prevent=\"selectSection(section.id)\">\n\t\t\t\t\t\t\t<span v-if=\"section.icon\" class=\"cn-user-settings-dialog__nav-icon\" aria-hidden=\"true\">\n\t\t\t\t\t\t\t\t<CnVNodes :vnodes=\"section.icon\" />\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t<span>{{ section.name }}</span>\n\t\t\t\t\t\t</a>\n\t\t\t\t\t</li>\n\t\t\t\t</ul>\n\t\t\t</nav>\n\t\t\t<div class=\"cn-user-settings-dialog__sections\">\n\t\t\t\t<!-- @slot default NcAppSettingsSection children; each registers itself in the navigation. -->\n\t\t\t\t<slot />\n\t\t\t\t<!-- A section's `#icon` also stands before its heading. -->\n\t\t\t\t<template v-for=\"section in sections\" :key=\"`heading-icon-${section.id}-${section.name}`\">\n\t\t\t\t\t<Teleport v-if=\"section.icon && headingTargets.includes(section.id)\" :to=\"`#settings-section_${section.id}--label`\">\n\t\t\t\t\t\t<span class=\"cn-user-settings-dialog__heading-icon\" aria-hidden=\"true\" :data-testid=\"`cn-user-settings-heading-icon-${section.id}`\">\n\t\t\t\t\t\t\t<CnVNodes :vnodes=\"section.icon\" />\n\t\t\t\t\t\t</span>\n\t\t\t\t\t</Teleport>\n\t\t\t\t</template>\n\t\t\t</div>\n\t\t</div>\n\t\t<template #actions>\n\t\t\t<p class=\"cn-user-settings-dialog__note\" data-testid=\"cn-user-settings-note\">\n\t\t\t\t{{ footerNote }}\n\t\t\t</p>\n\t\t\t<NcButton variant=\"secondary\" data-testid=\"cn-user-settings-close\" @click=\"close\">\n\t\t\t\t{{ closeLabel }}\n\t\t\t</NcButton>\n\t\t</template>\n\t</CnDialog>\n</template>\n\n<script>\nimport { translate as t } from '@nextcloud/l10n'\nimport { generateUrl } from '@nextcloud/router'\nimport { NcButton } from '@nextcloud/vue'\nimport { cloneVNode, markRaw, ref } from 'vue'\nimport CnDialog from '../CnDialog/CnDialog.vue'\nimport CnIcon from '../CnIcon/CnIcon.vue'\n\n/**\n * The key NcAppSettingsSection injects to register itself with its dialog\n * (`Symbol.for`, so the same symbol `@nextcloud/vue` provides).\n */\nconst REGISTRATION_KEY = Symbol.for('NcAppSettingsDialog:registration')\n\n/** The key NcAppSettingsSection injects for the legacy design flag. */\nconst LEGACY_DESIGN_KEY = Symbol.for('NcAppSettingsDialog:legacy')\n\n/** Renders a section's icon vnodes as they were registered. */\nconst CnVNodes = {\n\tname: 'CnVNodes',\n\tprops: { vnodes: { type: [Array, Object], default: null } },\n\trender() {\n\t\t// A section's icon is drawn twice (navigation and heading), so each draw gets its own copy.\n\t\tconst list = Array.isArray(this.vnodes) ? this.vnodes : [this.vnodes]\n\t\treturn list.map((vnode) => (vnode && typeof vnode === 'object' ? cloneVNode(vnode) : vnode))\n\t},\n}\n\n/**\n * CnUserSettingsDialog - the user settings dialog in the board look (board\n * PqPersoonlijk): eyebrow, title and subtitle, a left navigation listing the\n * sections with their icons, the current section (the others stay mounted\n * but hidden), and a footer with a note that changes save straight away and\n * a Close button.\n *\n * The sections stay the app's: any `NcAppSettingsSection` in the default slot\n * registers itself with this dialog exactly as it does with\n * `NcAppSettingsDialog`, with its name, order and `#icon` slot. CnAppRoot\n * renders this dialog instead of `NcAppSettingsDialog` under the board look.\n *\n * @spec openspec/changes/user-settings-board-dialog/specs/user-settings-board-dialog/spec.md#requirement-the-user-settings-dialog-takes-the-board-look\n *\n * @event update:open Emitted with `false` when the dialog closes.\n */\nexport default {\n\tname: 'CnUserSettingsDialog',\n\n\tcomponents: { CnDialog, CnIcon, CnVNodes, NcButton },\n\n\tprovide() {\n\t\treturn {\n\t\t\t[REGISTRATION_KEY]: {\n\t\t\t\tregisterSection: this.registerSection,\n\t\t\t\tunregisterSection: this.unregisterSection,\n\t\t\t},\n\n\t\t\t// NcAppSettingsSection also asks its dialog whether to use the legacy design.\n\t\t\t[LEGACY_DESIGN_KEY]: ref(false),\n\t\t}\n\t},\n\n\tprops: {\n\t\t/** Whether the dialog is open. */\n\t\topen: { type: Boolean, default: false },\n\t\t/** Dialog title; also its accessible name. */\n\t\ttitle: { type: String, required: true },\n\t\t/** Context line above the title. */\n\t\teyebrow: { type: String, default: () => t('nextcloud-vue', 'Your account') },\n\t\t/** Sentence under the title. */\n\t\tsubtitle: { type: String, default: () => t('nextcloud-vue', 'Only for you. Colleagues keep their own settings.') },\n\t\t/** The app's name, after the footer note and as the navigation entry holding its sections. */\n\t\tappName: { type: String, default: '' },\n\t\t/**\n\t\t * Nextcloud's own personal settings, listed first in the navigation as\n\t\t * links: `[{ label, section? | href?, icon? }]`. `section` is a\n\t\t * personal settings section id (`/settings/user/<section>`). With any,\n\t\t * the app's sections sit under one entry named after the app.\n\t\t */\n\t\tnextcloudLinks: { type: Array, default: () => [] },\n\t},\n\n\temits: ['update:open'],\n\n\tdata() {\n\t\treturn {\n\t\t\tsections: [],\n\t\t\tselected: '',\n\t\t\t/** Ids of the sections whose heading is in the page, for the heading icons. */\n\t\t\theadingTargets: [],\n\t\t\tpicked: false,\n\t\t}\n\t},\n\n\tcomputed: {\n\t\t/**\n\t\t * The Nextcloud links with their URL.\n\t\t *\n\t\t * @spec openspec/changes/user-settings-nav-groups/specs/user-settings-board-dialog/spec.md#requirement-the-board-user-settings-navigation-can-list-nextclouds-own-sections-first\n\t\t * @return {Array<{key: string, label: string, href: string, icon: string}>}\n\t\t */\n\t\tncLinks() {\n\t\t\treturn (Array.isArray(this.nextcloudLinks) ? this.nextcloudLinks : [])\n\t\t\t\t.filter((link) => link && typeof link === 'object' && typeof link.label === 'string' && link.label !== '' && (link.href || link.section))\n\t\t\t\t.map((link, index) => ({\n\t\t\t\t\tkey: String(link.section || link.href || index),\n\t\t\t\t\tlabel: link.label,\n\t\t\t\t\thref: link.href || generateUrl('/settings/user/{section}', { section: String(link.section) }),\n\t\t\t\t\ticon: typeof link.icon === 'string' ? link.icon : '',\n\t\t\t\t}))\n\t\t},\n\n\t\t/** @return {object} The board's eyebrow: muted, in sentence case. */\n\t\teyebrowStyle() {\n\t\t\treturn { '--cn-dialog-eyebrow-transform': 'none', '--cn-dialog-eyebrow-color': 'var(--color-text-maxcontrast)' }\n\t\t},\n\n\t\t/** @return {string} The navigation's accessible name. */\n\t\tnavLabel() {\n\t\t\treturn t('nextcloud-vue', 'Sections of the settings')\n\t\t},\n\n\t\t/** @return {string} The footer note, with the app's name when known. */\n\t\tfooterNote() {\n\t\t\tconst note = t('nextcloud-vue', 'Changes are saved straight away')\n\t\t\treturn this.appName ? `${note} · ${this.appName}` : note\n\t\t},\n\n\t\t/** @return {string} The Close button label. */\n\t\tcloseLabel() {\n\t\t\treturn t('nextcloud-vue', 'Close')\n\t\t},\n\t},\n\n\twatch: {\n\t\tsections() {\n\t\t\tthis.$nextTick(() => {\n\t\t\t\tthis.headingTargets = typeof document === 'undefined'\n\t\t\t\t\t? []\n\t\t\t\t\t: this.sections.filter((section) => section.icon && document.getElementById(`settings-section_${section.id}--label`)).map((section) => section.id)\n\t\t\t\tthis.showSelected()\n\t\t\t})\n\t\t},\n\n\t\tselected() {\n\t\t\tthis.$nextTick(() => this.showSelected())\n\t\t},\n\t},\n\n\tmethods: {\n\t\t/**\n\t\t * Add a section to the navigation, kept in `order`; a section\n\t\t * without one goes last. Until the reader picks one, the first\n\t\t * section is current.\n\t\t *\n\t\t * @param {string} id The section id.\n\t\t * @param {string} name The section name.\n\t\t * @param {number} [order] The section's place.\n\t\t * @param {Array} [icon] The section's icon vnodes.\n\t\t */\n\t\tregisterSection(id, name, order, icon) {\n\t\t\tconst rest = this.sections.filter((section) => section.id !== id)\n\t\t\tconst place = typeof order === 'number' ? order : Math.max(0, ...rest.map((section) => section.order)) + 1\n\t\t\tthis.sections = [...rest, { id, name, order: place, icon: icon ? markRaw(icon) : null }].sort((a, b) => a.order - b.order)\n\t\t\tif (!this.picked) {\n\t\t\t\tthis.selected = this.sections[0].id\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Remove a section from the navigation.\n\t\t *\n\t\t * @param {string} id The section id.\n\t\t */\n\t\tunregisterSection(id) {\n\t\t\tthis.sections = this.sections.filter((section) => section.id !== id)\n\t\t\tif (this.selected === id) {\n\t\t\t\tthis.selected = this.sections.length > 0 ? this.sections[0].id : ''\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Mark a section current and scroll it into view.\n\t\t *\n\t\t * @param {string} id The section id.\n\t\t */\n\t\tselectSection(id) {\n\t\t\tthis.picked = true\n\t\t\tthis.selected = id\n\t\t\tthis.$nextTick(() => {\n\t\t\t\tthis.showSelected()\n\t\t\t\tconst heading = typeof document !== 'undefined' ? document.getElementById(`settings-section_${id}--label`) : null\n\t\t\t\tif (heading) {\n\t\t\t\t\theading.setAttribute('tabindex', '-1')\n\t\t\t\t\theading.focus()\n\t\t\t\t}\n\t\t\t})\n\t\t},\n\n\t\t/**\n\t\t * Show the current section and hide the others. They stay mounted,\n\t\t * so what a reader typed in one survives a switch.\n\t\t *\n\t\t * @spec openspec/changes/user-settings-one-section/specs/user-settings-board-dialog/spec.md#requirement-the-board-user-settings-dialog-shows-one-section-at-a-time\n\t\t */\n\t\tshowSelected() {\n\t\t\tif (typeof document === 'undefined') {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tfor (const section of this.sections) {\n\t\t\t\tconst el = document.getElementById(`settings-section_${section.id}`)\n\t\t\t\tif (el) {\n\t\t\t\t\tel.hidden = section.id !== this.selected\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Follow NcDialog's own open state.\n\t\t *\n\t\t * @param {boolean} value Whether NcDialog is open.\n\t\t */\n\t\tonUpdateOpen(value) {\n\t\t\tif (!value) {\n\t\t\t\tthis.close()\n\t\t\t}\n\t\t},\n\n\t\t/** Close the dialog. */\n\t\tclose() {\n\t\t\t/**\n\t\t\t * @event update:open Emitted with `false` when the dialog closes (Close button, close icon, Escape).\n\t\t\t */\n\t\t\tthis.$emit('update:open', false)\n\t\t},\n\t},\n}\n</script>\n\n<style scoped>\n.cn-user-settings-dialog__body {\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\tgap: 0 24px;\n}\n\n.cn-user-settings-dialog__nav {\n\tflex: 0 0 200px;\n\twidth: 200px;\n\tpadding-top: 18px;\n}\n\n.cn-user-settings-dialog__nav ul {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 2px;\n\tmargin: 0;\n\tpadding: 0;\n\tlist-style: none;\n}\n\n.cn-user-settings-dialog__nav-link {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 10px;\n\tmin-height: 40px;\n\tpadding: 0 12px;\n\tborder-radius: var(--border-radius-element, 8px);\n\tfont-size: 15px;\n\tcolor: var(--color-main-text);\n\ttext-decoration: none;\n}\n\n.cn-user-settings-dialog__nav-link:hover {\n\tbackground: var(--color-background-hover);\n}\n\n.cn-user-settings-dialog__nav-link:focus-visible {\n\toutline: 2px solid var(--color-primary-element);\n\toutline-offset: 2px;\n}\n\n.cn-user-settings-dialog__nav-link--active,\n.cn-user-settings-dialog__nav-link--active:hover {\n\tbackground: var(--color-primary-element-light);\n\tcolor: var(--color-primary-element-light-text);\n\tfont-weight: 600;\n}\n\n.cn-user-settings-dialog__nav-icon {\n\tdisplay: inline-flex;\n\tflex: none;\n\twidth: 18px;\n\theight: 18px;\n\talign-items: center;\n\tjustify-content: center;\n}\n\n.cn-user-settings-dialog__sections {\n\tdisplay: flex;\n\tflex: 1 1 380px;\n\tflex-direction: column;\n\tmin-width: 0;\n}\n\n.cn-user-settings-dialog__sections :deep(.app-settings-section) {\n\tmargin: 0;\n\tpadding: 18px 0;\n\tborder-top: 1px solid var(--color-border);\n}\n\n.cn-user-settings-dialog__sections :deep(.app-settings-section__name) {\n\tmargin: 0 0 12px;\n\tfont-size: 17px;\n\tfont-weight: 700;\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 10px;\n}\n\n.cn-user-settings-dialog__note {\n\tflex: 1 1 auto;\n\tmargin: 0;\n\tfont-size: 14px;\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-user-settings-dialog__nc-links {\n\tmargin-bottom: 2px;\n}\n\n.cn-user-settings-dialog__group {\n\tmargin: 10px 0 2px;\n\tpadding: 0 12px;\n\tfont-size: 15px;\n\tfont-weight: 600;\n\tcolor: var(--color-main-text);\n}\n\n.cn-user-settings-dialog__group-sections {\n\tpadding-inline-start: 12px;\n}\n\n.cn-user-settings-dialog__heading-icon {\n\tdisplay: inline-flex;\n\torder: -1;\n\tcolor: var(--color-text-maxcontrast);\n}\n\n/* One section at a time: the others are mounted but hidden. */\n.cn-user-settings-dialog__sections :deep(.app-settings-section[hidden]) {\n\tdisplay: none;\n}\n</style>\n"],"names":["CnDialog","CnIcon","t"],"mappings":"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"}
|
|
@@ -1,20 +1,38 @@
|
|
|
1
|
-
import { resolveComponent, openBlock, createBlock, normalizeStyle, withCtx, createElementVNode, toDisplayString, createVNode, createTextVNode, createElementBlock, Fragment, renderList, normalizeClass, withModifiers,
|
|
1
|
+
import { resolveComponent, openBlock, createBlock, normalizeStyle, withCtx, createElementVNode, toDisplayString, createVNode, createTextVNode, createElementBlock, Fragment, renderList, createCommentVNode, normalizeClass, withModifiers, renderSlot, Teleport } from 'vue';
|
|
2
2
|
|
|
3
3
|
const _hoisted_1 = { class: "cn-user-settings-dialog__body" };
|
|
4
4
|
const _hoisted_2 = ["aria-label"];
|
|
5
|
-
const _hoisted_3 =
|
|
6
|
-
|
|
5
|
+
const _hoisted_3 = {
|
|
6
|
+
key: 0,
|
|
7
|
+
class: "cn-user-settings-dialog__nc-links",
|
|
8
|
+
"data-testid": "cn-user-settings-nc-links"
|
|
9
|
+
};
|
|
10
|
+
const _hoisted_4 = ["href"];
|
|
11
|
+
const _hoisted_5 = {
|
|
7
12
|
key: 0,
|
|
8
13
|
class: "cn-user-settings-dialog__nav-icon",
|
|
9
14
|
"aria-hidden": "true"
|
|
10
15
|
};
|
|
11
|
-
const _hoisted_5 = { class: "cn-user-settings-dialog__sections" };
|
|
12
16
|
const _hoisted_6 = {
|
|
17
|
+
key: 1,
|
|
18
|
+
class: "cn-user-settings-dialog__group",
|
|
19
|
+
"data-testid": "cn-user-settings-app-group"
|
|
20
|
+
};
|
|
21
|
+
const _hoisted_7 = ["href", "aria-current", "data-testid", "onClick"];
|
|
22
|
+
const _hoisted_8 = {
|
|
23
|
+
key: 0,
|
|
24
|
+
class: "cn-user-settings-dialog__nav-icon",
|
|
25
|
+
"aria-hidden": "true"
|
|
26
|
+
};
|
|
27
|
+
const _hoisted_9 = { class: "cn-user-settings-dialog__sections" };
|
|
28
|
+
const _hoisted_10 = ["data-testid"];
|
|
29
|
+
const _hoisted_11 = {
|
|
13
30
|
class: "cn-user-settings-dialog__note",
|
|
14
31
|
"data-testid": "cn-user-settings-note"
|
|
15
32
|
};
|
|
16
33
|
|
|
17
34
|
function render(_ctx, _cache, $props, $setup, $data, $options) {
|
|
35
|
+
const _component_CnIcon = resolveComponent("CnIcon");
|
|
18
36
|
const _component_CnVNodes = resolveComponent("CnVNodes");
|
|
19
37
|
const _component_NcButton = resolveComponent("NcButton");
|
|
20
38
|
const _component_CnDialog = resolveComponent("CnDialog");
|
|
@@ -33,7 +51,7 @@ function render(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
33
51
|
onClosing: $options.close
|
|
34
52
|
}, {
|
|
35
53
|
actions: withCtx(() => [
|
|
36
|
-
createElementVNode("p",
|
|
54
|
+
createElementVNode("p", _hoisted_11, toDisplayString($options.footerNote), 1 /* TEXT */),
|
|
37
55
|
createVNode(_component_NcButton, {
|
|
38
56
|
variant: "secondary",
|
|
39
57
|
"data-testid": "cn-user-settings-close",
|
|
@@ -54,7 +72,36 @@ function render(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
54
72
|
"aria-label": $options.navLabel,
|
|
55
73
|
"data-testid": "cn-user-settings-nav"
|
|
56
74
|
}, [
|
|
57
|
-
|
|
75
|
+
($options.ncLinks.length > 0)
|
|
76
|
+
? (openBlock(), createElementBlock("ul", _hoisted_3, [
|
|
77
|
+
(openBlock(true), createElementBlock(Fragment, null, renderList($options.ncLinks, (link) => {
|
|
78
|
+
return (openBlock(), createElementBlock("li", {
|
|
79
|
+
key: link.key
|
|
80
|
+
}, [
|
|
81
|
+
createElementVNode("a", {
|
|
82
|
+
href: link.href,
|
|
83
|
+
class: "cn-user-settings-dialog__nav-link"
|
|
84
|
+
}, [
|
|
85
|
+
(link.icon)
|
|
86
|
+
? (openBlock(), createElementBlock("span", _hoisted_5, [
|
|
87
|
+
createVNode(_component_CnIcon, {
|
|
88
|
+
name: link.icon,
|
|
89
|
+
size: 18
|
|
90
|
+
}, null, 8 /* PROPS */, ["name"])
|
|
91
|
+
]))
|
|
92
|
+
: createCommentVNode("v-if", true),
|
|
93
|
+
createElementVNode("span", null, toDisplayString(link.label), 1 /* TEXT */)
|
|
94
|
+
], 8 /* PROPS */, _hoisted_4)
|
|
95
|
+
]))
|
|
96
|
+
}), 128 /* KEYED_FRAGMENT */))
|
|
97
|
+
]))
|
|
98
|
+
: createCommentVNode("v-if", true),
|
|
99
|
+
($options.ncLinks.length > 0 && $props.appName)
|
|
100
|
+
? (openBlock(), createElementBlock("p", _hoisted_6, toDisplayString($props.appName), 1 /* TEXT */))
|
|
101
|
+
: createCommentVNode("v-if", true),
|
|
102
|
+
createElementVNode("ul", {
|
|
103
|
+
class: normalizeClass({ 'cn-user-settings-dialog__group-sections': $options.ncLinks.length > 0 })
|
|
104
|
+
}, [
|
|
58
105
|
(openBlock(true), createElementBlock(Fragment, null, renderList($data.sections, (section) => {
|
|
59
106
|
return (openBlock(), createElementBlock("li", {
|
|
60
107
|
key: section.id
|
|
@@ -67,21 +114,43 @@ function render(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
67
114
|
onClick: withModifiers($event => ($options.selectSection(section.id)), ["prevent"])
|
|
68
115
|
}, [
|
|
69
116
|
(section.icon)
|
|
70
|
-
? (openBlock(), createElementBlock("span",
|
|
117
|
+
? (openBlock(), createElementBlock("span", _hoisted_8, [
|
|
71
118
|
createVNode(_component_CnVNodes, {
|
|
72
119
|
vnodes: section.icon
|
|
73
120
|
}, null, 8 /* PROPS */, ["vnodes"])
|
|
74
121
|
]))
|
|
75
122
|
: createCommentVNode("v-if", true),
|
|
76
123
|
createElementVNode("span", null, toDisplayString(section.name), 1 /* TEXT */)
|
|
77
|
-
], 10 /* CLASS, PROPS */,
|
|
124
|
+
], 10 /* CLASS, PROPS */, _hoisted_7)
|
|
78
125
|
]))
|
|
79
126
|
}), 128 /* KEYED_FRAGMENT */))
|
|
80
|
-
])
|
|
127
|
+
], 2 /* CLASS */)
|
|
81
128
|
], 8 /* PROPS */, _hoisted_2))
|
|
82
129
|
: createCommentVNode("v-if", true),
|
|
83
|
-
createElementVNode("div",
|
|
84
|
-
renderSlot(_ctx.$slots, "default")
|
|
130
|
+
createElementVNode("div", _hoisted_9, [
|
|
131
|
+
renderSlot(_ctx.$slots, "default"),
|
|
132
|
+
(openBlock(true), createElementBlock(Fragment, null, renderList($data.sections, (section) => {
|
|
133
|
+
return (openBlock(), createElementBlock(Fragment, {
|
|
134
|
+
key: `heading-icon-${section.id}-${section.name}`
|
|
135
|
+
}, [
|
|
136
|
+
(section.icon && $data.headingTargets.includes(section.id))
|
|
137
|
+
? (openBlock(), createBlock(Teleport, {
|
|
138
|
+
key: 0,
|
|
139
|
+
to: `#settings-section_${section.id}--label`
|
|
140
|
+
}, [
|
|
141
|
+
createElementVNode("span", {
|
|
142
|
+
class: "cn-user-settings-dialog__heading-icon",
|
|
143
|
+
"aria-hidden": "true",
|
|
144
|
+
"data-testid": `cn-user-settings-heading-icon-${section.id}`
|
|
145
|
+
}, [
|
|
146
|
+
createVNode(_component_CnVNodes, {
|
|
147
|
+
vnodes: section.icon
|
|
148
|
+
}, null, 8 /* PROPS */, ["vnodes"])
|
|
149
|
+
], 8 /* PROPS */, _hoisted_10)
|
|
150
|
+
], 8 /* PROPS */, ["to"]))
|
|
151
|
+
: createCommentVNode("v-if", true)
|
|
152
|
+
], 64 /* STABLE_FRAGMENT */))
|
|
153
|
+
}), 128 /* KEYED_FRAGMENT */))
|
|
85
154
|
])
|
|
86
155
|
])
|
|
87
156
|
]),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CnUserSettingsDialog.vue3.js","sources":["../../../../src/components/CnUserSettingsDialog/CnUserSettingsDialog.vue?vue&type=template&id=8ebfd3c8&lang.js"],"sourcesContent":["<!--\n - SPDX-FileCopyrightText: 2026 Conduction B.V.\n - SPDX-License-Identifier: EUPL-1.2\n-->\n<template>\n\t<CnDialog\n\t\tclass=\"cn-user-settings-dialog\"\n\t\t:name=\"title\"\n\t\tlook=\"board\"\n\t\twidth=\"wizard\"\n\t\t:eyebrow=\"eyebrow\"\n\t\t:subtitle=\"subtitle\"\n\t\t:open=\"open\"\n\t\t:style=\"eyebrowStyle\"\n\t\tdata-testid=\"cn-user-settings-dialog\"\n\t\t@update:open=\"onUpdateOpen\"\n\t\t@closing=\"close\">\n\t\t<div class=\"cn-user-settings-dialog__body\">\n\t\t\t<nav\n\t\t\t\tv-if=\"sections.length > 0\"\n\t\t\t\tclass=\"cn-user-settings-dialog__nav\"\n\t\t\t\t:aria-label=\"navLabel\"\n\t\t\t\tdata-testid=\"cn-user-settings-nav\">\n\t\t\t\t<ul>\n\t\t\t\t\t<li v-for=\"section in sections\" :key=\"section.id\">\n\t\t\t\t\t\t<a\n\t\t\t\t\t\t\t:href=\"`#settings-section_${section.id}`\"\n\t\t\t\t\t\t\tclass=\"cn-user-settings-dialog__nav-link\"\n\t\t\t\t\t\t\t:class=\"{ 'cn-user-settings-dialog__nav-link--active': section.id === selected }\"\n\t\t\t\t\t\t\t:aria-current=\"section.id === selected ? 'true' : undefined\"\n\t\t\t\t\t\t\t:data-testid=\"`cn-user-settings-nav-${section.id}`\"\n\t\t\t\t\t\t\t@click.prevent=\"selectSection(section.id)\">\n\t\t\t\t\t\t\t<span v-if=\"section.icon\" class=\"cn-user-settings-dialog__nav-icon\" aria-hidden=\"true\">\n\t\t\t\t\t\t\t\t<CnVNodes :vnodes=\"section.icon\" />\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t<span>{{ section.name }}</span>\n\t\t\t\t\t\t</a>\n\t\t\t\t\t</li>\n\t\t\t\t</ul>\n\t\t\t</nav>\n\t\t\t<div class=\"cn-user-settings-dialog__sections\">\n\t\t\t\t<!-- @slot default NcAppSettingsSection children; each registers itself in the navigation. -->\n\t\t\t\t<slot />\n\t\t\t</div>\n\t\t</div>\n\t\t<template #actions>\n\t\t\t<p class=\"cn-user-settings-dialog__note\" data-testid=\"cn-user-settings-note\">\n\t\t\t\t{{ footerNote }}\n\t\t\t</p>\n\t\t\t<NcButton variant=\"secondary\" data-testid=\"cn-user-settings-close\" @click=\"close\">\n\t\t\t\t{{ closeLabel }}\n\t\t\t</NcButton>\n\t\t</template>\n\t</CnDialog>\n</template>\n\n<script>\nimport { translate as t } from '@nextcloud/l10n'\nimport { NcButton } from '@nextcloud/vue'\nimport { markRaw } from 'vue'\nimport CnDialog from '../CnDialog/CnDialog.vue'\n\n/**\n * The key NcAppSettingsSection injects to register itself with its dialog\n * (`Symbol.for`, so the same symbol `@nextcloud/vue` provides).\n */\nconst REGISTRATION_KEY = Symbol.for('NcAppSettingsDialog:registration')\n\n/** Renders a section's icon vnodes as they were registered. */\nconst CnVNodes = {\n\tname: 'CnVNodes',\n\tprops: { vnodes: { type: [Array, Object], default: null } },\n\trender() {\n\t\treturn this.vnodes\n\t},\n}\n\n/**\n * CnUserSettingsDialog - the user settings dialog in the board look (board\n * PqPersoonlijk): eyebrow, title and subtitle, a left navigation listing the\n * sections with their icons, the sections themselves, and a footer with a\n * note that changes save straight away and a Close button.\n *\n * The sections stay the app's: any `NcAppSettingsSection` in the default slot\n * registers itself with this dialog exactly as it does with\n * `NcAppSettingsDialog`, with its name, order and `#icon` slot. CnAppRoot\n * renders this dialog instead of `NcAppSettingsDialog` under the board look.\n *\n * @spec openspec/changes/user-settings-board-dialog/specs/user-settings-board-dialog/spec.md#requirement-the-user-settings-dialog-takes-the-board-look\n *\n * @event update:open Emitted with `false` when the dialog closes.\n */\nexport default {\n\tname: 'CnUserSettingsDialog',\n\n\tcomponents: { CnDialog, CnVNodes, NcButton },\n\n\tprovide() {\n\t\treturn {\n\t\t\t[REGISTRATION_KEY]: {\n\t\t\t\tregisterSection: this.registerSection,\n\t\t\t\tunregisterSection: this.unregisterSection,\n\t\t\t},\n\t\t}\n\t},\n\n\tprops: {\n\t\t/** Whether the dialog is open. */\n\t\topen: { type: Boolean, default: false },\n\t\t/** Dialog title; also its accessible name. */\n\t\ttitle: { type: String, required: true },\n\t\t/** Context line above the title. */\n\t\teyebrow: { type: String, default: () => t('nextcloud-vue', 'Your account') },\n\t\t/** Sentence under the title. */\n\t\tsubtitle: { type: String, default: () => t('nextcloud-vue', 'Only for you. Colleagues keep their own settings.') },\n\t\t/** The app's name, after the footer note. */\n\t\tappName: { type: String, default: '' },\n\t},\n\n\temits: ['update:open'],\n\n\tdata() {\n\t\treturn {\n\t\t\tsections: [],\n\t\t\tselected: '',\n\t\t\tpicked: false,\n\t\t}\n\t},\n\n\tcomputed: {\n\t\t/** @return {object} The board's eyebrow: muted, in sentence case. */\n\t\teyebrowStyle() {\n\t\t\treturn { '--cn-dialog-eyebrow-transform': 'none', '--cn-dialog-eyebrow-color': 'var(--color-text-maxcontrast)' }\n\t\t},\n\n\t\t/** @return {string} The navigation's accessible name. */\n\t\tnavLabel() {\n\t\t\treturn t('nextcloud-vue', 'Sections of the settings')\n\t\t},\n\n\t\t/** @return {string} The footer note, with the app's name when known. */\n\t\tfooterNote() {\n\t\t\tconst note = t('nextcloud-vue', 'Changes are saved straight away')\n\t\t\treturn this.appName ? `${note} · ${this.appName}` : note\n\t\t},\n\n\t\t/** @return {string} The Close button label. */\n\t\tcloseLabel() {\n\t\t\treturn t('nextcloud-vue', 'Close')\n\t\t},\n\t},\n\n\tmethods: {\n\t\t/**\n\t\t * Add a section to the navigation, kept in `order`; a section\n\t\t * without one goes last. Until the reader picks one, the first\n\t\t * section is current.\n\t\t *\n\t\t * @param {string} id The section id.\n\t\t * @param {string} name The section name.\n\t\t * @param {number} [order] The section's place.\n\t\t * @param {Array} [icon] The section's icon vnodes.\n\t\t */\n\t\tregisterSection(id, name, order, icon) {\n\t\t\tconst rest = this.sections.filter((section) => section.id !== id)\n\t\t\tconst place = typeof order === 'number' ? order : Math.max(0, ...rest.map((section) => section.order)) + 1\n\t\t\tthis.sections = [...rest, { id, name, order: place, icon: icon ? markRaw(icon) : null }].sort((a, b) => a.order - b.order)\n\t\t\tif (!this.picked) {\n\t\t\t\tthis.selected = this.sections[0].id\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Remove a section from the navigation.\n\t\t *\n\t\t * @param {string} id The section id.\n\t\t */\n\t\tunregisterSection(id) {\n\t\t\tthis.sections = this.sections.filter((section) => section.id !== id)\n\t\t\tif (this.selected === id) {\n\t\t\t\tthis.selected = this.sections.length > 0 ? this.sections[0].id : ''\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Mark a section current and scroll it into view.\n\t\t *\n\t\t * @param {string} id The section id.\n\t\t */\n\t\tselectSection(id) {\n\t\t\tthis.picked = true\n\t\t\tthis.selected = id\n\t\t\tconst target = typeof document !== 'undefined' ? document.getElementById(`settings-section_${id}`) : null\n\t\t\tif (target && typeof target.scrollIntoView === 'function') {\n\t\t\t\ttarget.scrollIntoView({ behavior: 'smooth', block: 'start' })\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Follow NcDialog's own open state.\n\t\t *\n\t\t * @param {boolean} value Whether NcDialog is open.\n\t\t */\n\t\tonUpdateOpen(value) {\n\t\t\tif (!value) {\n\t\t\t\tthis.close()\n\t\t\t}\n\t\t},\n\n\t\t/** Close the dialog. */\n\t\tclose() {\n\t\t\t/**\n\t\t\t * @event update:open Emitted with `false` when the dialog closes (Close button, close icon, Escape).\n\t\t\t */\n\t\t\tthis.$emit('update:open', false)\n\t\t},\n\t},\n}\n</script>\n\n<style scoped>\n.cn-user-settings-dialog__body {\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\tgap: 0 24px;\n}\n\n.cn-user-settings-dialog__nav {\n\tflex: 0 0 200px;\n\twidth: 200px;\n\tpadding-top: 18px;\n}\n\n.cn-user-settings-dialog__nav ul {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 2px;\n\tmargin: 0;\n\tpadding: 0;\n\tlist-style: none;\n}\n\n.cn-user-settings-dialog__nav-link {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 10px;\n\tmin-height: 40px;\n\tpadding: 0 12px;\n\tborder-radius: var(--border-radius-element, 8px);\n\tfont-size: 15px;\n\tcolor: var(--color-main-text);\n\ttext-decoration: none;\n}\n\n.cn-user-settings-dialog__nav-link:hover {\n\tbackground: var(--color-background-hover);\n}\n\n.cn-user-settings-dialog__nav-link:focus-visible {\n\toutline: 2px solid var(--color-primary-element);\n\toutline-offset: 2px;\n}\n\n.cn-user-settings-dialog__nav-link--active,\n.cn-user-settings-dialog__nav-link--active:hover {\n\tbackground: var(--color-primary-element-light);\n\tcolor: var(--color-primary-element-light-text);\n\tfont-weight: 600;\n}\n\n.cn-user-settings-dialog__nav-icon {\n\tdisplay: inline-flex;\n\tflex: none;\n\twidth: 18px;\n\theight: 18px;\n\talign-items: center;\n\tjustify-content: center;\n}\n\n.cn-user-settings-dialog__sections {\n\tdisplay: flex;\n\tflex: 1 1 380px;\n\tflex-direction: column;\n\tmin-width: 0;\n}\n\n.cn-user-settings-dialog__sections :deep(.app-settings-section) {\n\tmargin: 0;\n\tpadding: 18px 0;\n\tborder-top: 1px solid var(--color-border);\n}\n\n.cn-user-settings-dialog__sections :deep(.app-settings-section__name) {\n\tmargin: 0 0 12px;\n\tfont-size: 17px;\n\tfont-weight: 700;\n}\n\n.cn-user-settings-dialog__note {\n\tflex: 1 1 auto;\n\tmargin: 0;\n\tfont-size: 14px;\n\tcolor: var(--color-text-maxcontrast);\n}\n</style>\n"],"names":["_toDisplayString","_createVNode","_createElementVNode","_createElementBlock","_Fragment","_renderList","_withModifiers","_openBlock","_renderSlot"],"mappings":";;AAqBO,MAAA,UAAA,GAAA,EAAA,KAAK,EAAC,+BAAY,GAAA;;;;;AAehB,EAAA,KAAA,EAAA,mCAAA;AAAA,EAAA,aAAA,EAAA,MAAA;;AAQF,MAAA,UAAA,GAAA,EAAA,KAAA,EAAA,mCAAA,GAAA;;AAMF,EAAA,KAAM,EAAC,+BAAO;AAAA,EAAA,aAAA,EAAA,uBAAA;;;;;;;;;AAxCjB,IAAA,KAAK,EAAC,yBAAW;AAChB,IAAA,IAAI,EAAE,MAAK,CAAA,KAAA;AACZ,IAAA,IAAI,EAAC,OAAM;AACX,IAAA,KAAK,EAAC,QAAQ;AACb,IAAA,OAAO,EAAE,MAAO,CAAA,OAAA;AAChB,IAAA,QAAQ,EAAE,MAAQ,CAAA,QAAA;AAClB,IAAA,IAAI,EAAE,MAAI,CAAA,IAAA;AACV,IAAA,KAAK,iBAAE,QAAY,CAAA,YAAA,CAAA;AACnB,IAAA,aAAG,EAAA,yBAAA;mBACQ,EAAE,QAAY,CAAA,YAAA;AACxB,IAAA,SAAM,EAAE,QAAK,CAAA,KAAA;;AA6BJ,IAAA,OAAO,gBAGb;wBAAA,CAAA,GAAA,YAAA,EAAAA,eAAA,CADA,QAAM,CAAA,UAAA,CAAA,EAAA,CAAA,YAAA;MAEVC;AAAQ,QAAA,OAAA,EAAA,WAAA;AAAA,QAAA,aAAA,EAAA,wBAAA;AAAA,QAAA,OAAA,EAAA,QAAA,CAAA,KAAA;;;;;;;;qBAhCP,MA2BE;AA3BF,MAAAC,kBAAA,CA2BE,OA3BF,UA2BE,EAAA;AAzBC,QAAA,CAAA,KAAA,CAAA,QAAA,CAAA,MAAA,GAAA,CAAA;0BADHC,kBAqBI,CAAA,KAAA,EAAA;;AAnBH,cAAA,KAAI,EAAC,8BAA8B;0BACjC,EAAA,QAAA,CAAA,QAAA;AACA,cAAA,aAAQ,EAAC,sBAAsB;;cAC/BD,kBAeC,CAAA,IAAA,EAAA,IAAA,EAAA;kCAdDC,kBAaG,CAAAC,QAAA,EAAA,IAAA,EAAAC,UAAA,CAbiB,KAAQ,CAAA,QAAA,EAAA,CAAlB,OAAM,KAAA;uCAAhBF,kBAaG,CAAA,IAAA,EAAA;oBAb4B,GAAG,EAAE,OAAO,CAAC,EAAE;;sCAY3C,CAAA,GAAA,EAAA;sBAVF,IAAI,EAAA,CAAA,kBAAA,EAAuB,OAAO,CAAC,EAAE,CAAA,CAAA;AACtC,sBAAA,KAAK,kBAAC,mCAAmC,EAAA,EAAA,2CAAA,EACc,OAAO,CAAC,EAAE,KAAK,KAAQ,CAAA,QAAA,EAAA,CAAA,CAAA;AAC7E,sBAAA,cAAY,EAAE,OAAO,CAAC,EAAE,KAAK,KAAA,CAAA,QAAK,YAAA,SAAA;sBAClC,aAAK,EAAA,CAAA,qBAAA,EAAA,OAAA,CAAA,EAAA,CAAA,CAAA;AACL,sBAAA,OAAK,EAAUG,aAAA,CAAA,MAAA,KAAA,QAAA,CAAA,aAAa,CAAC,OAAA,CAAA,EAAA,CAAA,CAAA,EAAA,CAAA,SAAA,CAAA,CAAA;;AAC5B,sBAAA,CAAA,OAAA,CAAA,IAAA;AAAF,2BAAAC,SAAA,EAAA,EAAAJ,kBAAA,CAEC,QAFD,UAEC,EAAA;4BADAF,WAAC,CAAA,mBAAA,EAAA;8BAAA,MAAA,EAAA,OAAA,CAAA,IAAA;;;;sBAEFC,kBAAC,CAAA,MAAA,EAAA,IAAA,EAAAF,eAAA,CAAA,OAAA,CAAA,IAAA,CAAA,EAAA,CAAA,YAAA;;;;;;;AAKL,QAAAE,kBAAA,CAGM,OAHN,UAGM,EAAA;UADLM,UAAQ,CAAA,IAAA,CAAA,MAAA,EAAA,SAAA,CAAA;;;;;;;;;;"}
|
|
1
|
+
{"version":3,"file":"CnUserSettingsDialog.vue3.js","sources":["../../../../src/components/CnUserSettingsDialog/CnUserSettingsDialog.vue?vue&type=template&id=e537e50a&lang.js"],"sourcesContent":["<!--\n - SPDX-FileCopyrightText: 2026 Conduction B.V.\n - SPDX-License-Identifier: EUPL-1.2\n-->\n<template>\n\t<CnDialog\n\t\tclass=\"cn-user-settings-dialog\"\n\t\t:name=\"title\"\n\t\tlook=\"board\"\n\t\twidth=\"wizard\"\n\t\t:eyebrow=\"eyebrow\"\n\t\t:subtitle=\"subtitle\"\n\t\t:open=\"open\"\n\t\t:style=\"eyebrowStyle\"\n\t\tdata-testid=\"cn-user-settings-dialog\"\n\t\t@update:open=\"onUpdateOpen\"\n\t\t@closing=\"close\">\n\t\t<div class=\"cn-user-settings-dialog__body\">\n\t\t\t<nav\n\t\t\t\tv-if=\"sections.length > 0\"\n\t\t\t\tclass=\"cn-user-settings-dialog__nav\"\n\t\t\t\t:aria-label=\"navLabel\"\n\t\t\t\tdata-testid=\"cn-user-settings-nav\">\n\t\t\t\t<!-- `nextcloudLinks`: Nextcloud's own personal settings first, as\n\t\t\t\t links, then one entry for this app holding its sections. -->\n\t\t\t\t<ul v-if=\"ncLinks.length > 0\" class=\"cn-user-settings-dialog__nc-links\" data-testid=\"cn-user-settings-nc-links\">\n\t\t\t\t\t<li v-for=\"link in ncLinks\" :key=\"link.key\">\n\t\t\t\t\t\t<a :href=\"link.href\" class=\"cn-user-settings-dialog__nav-link\">\n\t\t\t\t\t\t\t<span v-if=\"link.icon\" class=\"cn-user-settings-dialog__nav-icon\" aria-hidden=\"true\">\n\t\t\t\t\t\t\t\t<CnIcon :name=\"link.icon\" :size=\"18\" />\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t<span>{{ link.label }}</span>\n\t\t\t\t\t\t</a>\n\t\t\t\t\t</li>\n\t\t\t\t</ul>\n\t\t\t\t<p v-if=\"ncLinks.length > 0 && appName\"\n\t\t\t\t\tclass=\"cn-user-settings-dialog__group\"\n\t\t\t\t\tdata-testid=\"cn-user-settings-app-group\">\n\t\t\t\t\t{{ appName }}\n\t\t\t\t</p>\n\t\t\t\t<ul :class=\"{ 'cn-user-settings-dialog__group-sections': ncLinks.length > 0 }\">\n\t\t\t\t\t<li v-for=\"section in sections\" :key=\"section.id\">\n\t\t\t\t\t\t<a\n\t\t\t\t\t\t\t:href=\"`#settings-section_${section.id}`\"\n\t\t\t\t\t\t\tclass=\"cn-user-settings-dialog__nav-link\"\n\t\t\t\t\t\t\t:class=\"{ 'cn-user-settings-dialog__nav-link--active': section.id === selected }\"\n\t\t\t\t\t\t\t:aria-current=\"section.id === selected ? 'true' : undefined\"\n\t\t\t\t\t\t\t:data-testid=\"`cn-user-settings-nav-${section.id}`\"\n\t\t\t\t\t\t\t@click.prevent=\"selectSection(section.id)\">\n\t\t\t\t\t\t\t<span v-if=\"section.icon\" class=\"cn-user-settings-dialog__nav-icon\" aria-hidden=\"true\">\n\t\t\t\t\t\t\t\t<CnVNodes :vnodes=\"section.icon\" />\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t<span>{{ section.name }}</span>\n\t\t\t\t\t\t</a>\n\t\t\t\t\t</li>\n\t\t\t\t</ul>\n\t\t\t</nav>\n\t\t\t<div class=\"cn-user-settings-dialog__sections\">\n\t\t\t\t<!-- @slot default NcAppSettingsSection children; each registers itself in the navigation. -->\n\t\t\t\t<slot />\n\t\t\t\t<!-- A section's `#icon` also stands before its heading. -->\n\t\t\t\t<template v-for=\"section in sections\" :key=\"`heading-icon-${section.id}-${section.name}`\">\n\t\t\t\t\t<Teleport v-if=\"section.icon && headingTargets.includes(section.id)\" :to=\"`#settings-section_${section.id}--label`\">\n\t\t\t\t\t\t<span class=\"cn-user-settings-dialog__heading-icon\" aria-hidden=\"true\" :data-testid=\"`cn-user-settings-heading-icon-${section.id}`\">\n\t\t\t\t\t\t\t<CnVNodes :vnodes=\"section.icon\" />\n\t\t\t\t\t\t</span>\n\t\t\t\t\t</Teleport>\n\t\t\t\t</template>\n\t\t\t</div>\n\t\t</div>\n\t\t<template #actions>\n\t\t\t<p class=\"cn-user-settings-dialog__note\" data-testid=\"cn-user-settings-note\">\n\t\t\t\t{{ footerNote }}\n\t\t\t</p>\n\t\t\t<NcButton variant=\"secondary\" data-testid=\"cn-user-settings-close\" @click=\"close\">\n\t\t\t\t{{ closeLabel }}\n\t\t\t</NcButton>\n\t\t</template>\n\t</CnDialog>\n</template>\n\n<script>\nimport { translate as t } from '@nextcloud/l10n'\nimport { generateUrl } from '@nextcloud/router'\nimport { NcButton } from '@nextcloud/vue'\nimport { cloneVNode, markRaw, ref } from 'vue'\nimport CnDialog from '../CnDialog/CnDialog.vue'\nimport CnIcon from '../CnIcon/CnIcon.vue'\n\n/**\n * The key NcAppSettingsSection injects to register itself with its dialog\n * (`Symbol.for`, so the same symbol `@nextcloud/vue` provides).\n */\nconst REGISTRATION_KEY = Symbol.for('NcAppSettingsDialog:registration')\n\n/** The key NcAppSettingsSection injects for the legacy design flag. */\nconst LEGACY_DESIGN_KEY = Symbol.for('NcAppSettingsDialog:legacy')\n\n/** Renders a section's icon vnodes as they were registered. */\nconst CnVNodes = {\n\tname: 'CnVNodes',\n\tprops: { vnodes: { type: [Array, Object], default: null } },\n\trender() {\n\t\t// A section's icon is drawn twice (navigation and heading), so each draw gets its own copy.\n\t\tconst list = Array.isArray(this.vnodes) ? this.vnodes : [this.vnodes]\n\t\treturn list.map((vnode) => (vnode && typeof vnode === 'object' ? cloneVNode(vnode) : vnode))\n\t},\n}\n\n/**\n * CnUserSettingsDialog - the user settings dialog in the board look (board\n * PqPersoonlijk): eyebrow, title and subtitle, a left navigation listing the\n * sections with their icons, the current section (the others stay mounted\n * but hidden), and a footer with a note that changes save straight away and\n * a Close button.\n *\n * The sections stay the app's: any `NcAppSettingsSection` in the default slot\n * registers itself with this dialog exactly as it does with\n * `NcAppSettingsDialog`, with its name, order and `#icon` slot. CnAppRoot\n * renders this dialog instead of `NcAppSettingsDialog` under the board look.\n *\n * @spec openspec/changes/user-settings-board-dialog/specs/user-settings-board-dialog/spec.md#requirement-the-user-settings-dialog-takes-the-board-look\n *\n * @event update:open Emitted with `false` when the dialog closes.\n */\nexport default {\n\tname: 'CnUserSettingsDialog',\n\n\tcomponents: { CnDialog, CnIcon, CnVNodes, NcButton },\n\n\tprovide() {\n\t\treturn {\n\t\t\t[REGISTRATION_KEY]: {\n\t\t\t\tregisterSection: this.registerSection,\n\t\t\t\tunregisterSection: this.unregisterSection,\n\t\t\t},\n\n\t\t\t// NcAppSettingsSection also asks its dialog whether to use the legacy design.\n\t\t\t[LEGACY_DESIGN_KEY]: ref(false),\n\t\t}\n\t},\n\n\tprops: {\n\t\t/** Whether the dialog is open. */\n\t\topen: { type: Boolean, default: false },\n\t\t/** Dialog title; also its accessible name. */\n\t\ttitle: { type: String, required: true },\n\t\t/** Context line above the title. */\n\t\teyebrow: { type: String, default: () => t('nextcloud-vue', 'Your account') },\n\t\t/** Sentence under the title. */\n\t\tsubtitle: { type: String, default: () => t('nextcloud-vue', 'Only for you. Colleagues keep their own settings.') },\n\t\t/** The app's name, after the footer note and as the navigation entry holding its sections. */\n\t\tappName: { type: String, default: '' },\n\t\t/**\n\t\t * Nextcloud's own personal settings, listed first in the navigation as\n\t\t * links: `[{ label, section? | href?, icon? }]`. `section` is a\n\t\t * personal settings section id (`/settings/user/<section>`). With any,\n\t\t * the app's sections sit under one entry named after the app.\n\t\t */\n\t\tnextcloudLinks: { type: Array, default: () => [] },\n\t},\n\n\temits: ['update:open'],\n\n\tdata() {\n\t\treturn {\n\t\t\tsections: [],\n\t\t\tselected: '',\n\t\t\t/** Ids of the sections whose heading is in the page, for the heading icons. */\n\t\t\theadingTargets: [],\n\t\t\tpicked: false,\n\t\t}\n\t},\n\n\tcomputed: {\n\t\t/**\n\t\t * The Nextcloud links with their URL.\n\t\t *\n\t\t * @spec openspec/changes/user-settings-nav-groups/specs/user-settings-board-dialog/spec.md#requirement-the-board-user-settings-navigation-can-list-nextclouds-own-sections-first\n\t\t * @return {Array<{key: string, label: string, href: string, icon: string}>}\n\t\t */\n\t\tncLinks() {\n\t\t\treturn (Array.isArray(this.nextcloudLinks) ? this.nextcloudLinks : [])\n\t\t\t\t.filter((link) => link && typeof link === 'object' && typeof link.label === 'string' && link.label !== '' && (link.href || link.section))\n\t\t\t\t.map((link, index) => ({\n\t\t\t\t\tkey: String(link.section || link.href || index),\n\t\t\t\t\tlabel: link.label,\n\t\t\t\t\thref: link.href || generateUrl('/settings/user/{section}', { section: String(link.section) }),\n\t\t\t\t\ticon: typeof link.icon === 'string' ? link.icon : '',\n\t\t\t\t}))\n\t\t},\n\n\t\t/** @return {object} The board's eyebrow: muted, in sentence case. */\n\t\teyebrowStyle() {\n\t\t\treturn { '--cn-dialog-eyebrow-transform': 'none', '--cn-dialog-eyebrow-color': 'var(--color-text-maxcontrast)' }\n\t\t},\n\n\t\t/** @return {string} The navigation's accessible name. */\n\t\tnavLabel() {\n\t\t\treturn t('nextcloud-vue', 'Sections of the settings')\n\t\t},\n\n\t\t/** @return {string} The footer note, with the app's name when known. */\n\t\tfooterNote() {\n\t\t\tconst note = t('nextcloud-vue', 'Changes are saved straight away')\n\t\t\treturn this.appName ? `${note} · ${this.appName}` : note\n\t\t},\n\n\t\t/** @return {string} The Close button label. */\n\t\tcloseLabel() {\n\t\t\treturn t('nextcloud-vue', 'Close')\n\t\t},\n\t},\n\n\twatch: {\n\t\tsections() {\n\t\t\tthis.$nextTick(() => {\n\t\t\t\tthis.headingTargets = typeof document === 'undefined'\n\t\t\t\t\t? []\n\t\t\t\t\t: this.sections.filter((section) => section.icon && document.getElementById(`settings-section_${section.id}--label`)).map((section) => section.id)\n\t\t\t\tthis.showSelected()\n\t\t\t})\n\t\t},\n\n\t\tselected() {\n\t\t\tthis.$nextTick(() => this.showSelected())\n\t\t},\n\t},\n\n\tmethods: {\n\t\t/**\n\t\t * Add a section to the navigation, kept in `order`; a section\n\t\t * without one goes last. Until the reader picks one, the first\n\t\t * section is current.\n\t\t *\n\t\t * @param {string} id The section id.\n\t\t * @param {string} name The section name.\n\t\t * @param {number} [order] The section's place.\n\t\t * @param {Array} [icon] The section's icon vnodes.\n\t\t */\n\t\tregisterSection(id, name, order, icon) {\n\t\t\tconst rest = this.sections.filter((section) => section.id !== id)\n\t\t\tconst place = typeof order === 'number' ? order : Math.max(0, ...rest.map((section) => section.order)) + 1\n\t\t\tthis.sections = [...rest, { id, name, order: place, icon: icon ? markRaw(icon) : null }].sort((a, b) => a.order - b.order)\n\t\t\tif (!this.picked) {\n\t\t\t\tthis.selected = this.sections[0].id\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Remove a section from the navigation.\n\t\t *\n\t\t * @param {string} id The section id.\n\t\t */\n\t\tunregisterSection(id) {\n\t\t\tthis.sections = this.sections.filter((section) => section.id !== id)\n\t\t\tif (this.selected === id) {\n\t\t\t\tthis.selected = this.sections.length > 0 ? this.sections[0].id : ''\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Mark a section current and scroll it into view.\n\t\t *\n\t\t * @param {string} id The section id.\n\t\t */\n\t\tselectSection(id) {\n\t\t\tthis.picked = true\n\t\t\tthis.selected = id\n\t\t\tthis.$nextTick(() => {\n\t\t\t\tthis.showSelected()\n\t\t\t\tconst heading = typeof document !== 'undefined' ? document.getElementById(`settings-section_${id}--label`) : null\n\t\t\t\tif (heading) {\n\t\t\t\t\theading.setAttribute('tabindex', '-1')\n\t\t\t\t\theading.focus()\n\t\t\t\t}\n\t\t\t})\n\t\t},\n\n\t\t/**\n\t\t * Show the current section and hide the others. They stay mounted,\n\t\t * so what a reader typed in one survives a switch.\n\t\t *\n\t\t * @spec openspec/changes/user-settings-one-section/specs/user-settings-board-dialog/spec.md#requirement-the-board-user-settings-dialog-shows-one-section-at-a-time\n\t\t */\n\t\tshowSelected() {\n\t\t\tif (typeof document === 'undefined') {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tfor (const section of this.sections) {\n\t\t\t\tconst el = document.getElementById(`settings-section_${section.id}`)\n\t\t\t\tif (el) {\n\t\t\t\t\tel.hidden = section.id !== this.selected\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Follow NcDialog's own open state.\n\t\t *\n\t\t * @param {boolean} value Whether NcDialog is open.\n\t\t */\n\t\tonUpdateOpen(value) {\n\t\t\tif (!value) {\n\t\t\t\tthis.close()\n\t\t\t}\n\t\t},\n\n\t\t/** Close the dialog. */\n\t\tclose() {\n\t\t\t/**\n\t\t\t * @event update:open Emitted with `false` when the dialog closes (Close button, close icon, Escape).\n\t\t\t */\n\t\t\tthis.$emit('update:open', false)\n\t\t},\n\t},\n}\n</script>\n\n<style scoped>\n.cn-user-settings-dialog__body {\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\tgap: 0 24px;\n}\n\n.cn-user-settings-dialog__nav {\n\tflex: 0 0 200px;\n\twidth: 200px;\n\tpadding-top: 18px;\n}\n\n.cn-user-settings-dialog__nav ul {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 2px;\n\tmargin: 0;\n\tpadding: 0;\n\tlist-style: none;\n}\n\n.cn-user-settings-dialog__nav-link {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 10px;\n\tmin-height: 40px;\n\tpadding: 0 12px;\n\tborder-radius: var(--border-radius-element, 8px);\n\tfont-size: 15px;\n\tcolor: var(--color-main-text);\n\ttext-decoration: none;\n}\n\n.cn-user-settings-dialog__nav-link:hover {\n\tbackground: var(--color-background-hover);\n}\n\n.cn-user-settings-dialog__nav-link:focus-visible {\n\toutline: 2px solid var(--color-primary-element);\n\toutline-offset: 2px;\n}\n\n.cn-user-settings-dialog__nav-link--active,\n.cn-user-settings-dialog__nav-link--active:hover {\n\tbackground: var(--color-primary-element-light);\n\tcolor: var(--color-primary-element-light-text);\n\tfont-weight: 600;\n}\n\n.cn-user-settings-dialog__nav-icon {\n\tdisplay: inline-flex;\n\tflex: none;\n\twidth: 18px;\n\theight: 18px;\n\talign-items: center;\n\tjustify-content: center;\n}\n\n.cn-user-settings-dialog__sections {\n\tdisplay: flex;\n\tflex: 1 1 380px;\n\tflex-direction: column;\n\tmin-width: 0;\n}\n\n.cn-user-settings-dialog__sections :deep(.app-settings-section) {\n\tmargin: 0;\n\tpadding: 18px 0;\n\tborder-top: 1px solid var(--color-border);\n}\n\n.cn-user-settings-dialog__sections :deep(.app-settings-section__name) {\n\tmargin: 0 0 12px;\n\tfont-size: 17px;\n\tfont-weight: 700;\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 10px;\n}\n\n.cn-user-settings-dialog__note {\n\tflex: 1 1 auto;\n\tmargin: 0;\n\tfont-size: 14px;\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-user-settings-dialog__nc-links {\n\tmargin-bottom: 2px;\n}\n\n.cn-user-settings-dialog__group {\n\tmargin: 10px 0 2px;\n\tpadding: 0 12px;\n\tfont-size: 15px;\n\tfont-weight: 600;\n\tcolor: var(--color-main-text);\n}\n\n.cn-user-settings-dialog__group-sections {\n\tpadding-inline-start: 12px;\n}\n\n.cn-user-settings-dialog__heading-icon {\n\tdisplay: inline-flex;\n\torder: -1;\n\tcolor: var(--color-text-maxcontrast);\n}\n\n/* One section at a time: the others are mounted but hidden. */\n.cn-user-settings-dialog__sections :deep(.app-settings-section[hidden]) {\n\tdisplay: none;\n}\n</style>\n"],"names":["_toDisplayString","_createVNode","_createElementVNode","_createElementBlock","_openBlock","_Fragment","_renderList","_normalizeClass","_withModifiers","_renderSlot","_createBlock","_Teleport"],"mappings":"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"}
|
|
@@ -51,6 +51,7 @@ import '../CnTasksWidget/index.js';
|
|
|
51
51
|
import '../CnSectionsWidget/index.js';
|
|
52
52
|
import '../CnFactsWidget/index.js';
|
|
53
53
|
import '../CnDeviceFramesWidget/index.js';
|
|
54
|
+
import '../CnChecklistRunWidget/index.js';
|
|
54
55
|
import '../CnPartyActionsWidget/index.js';
|
|
55
56
|
import '../CnFieldListWidget/index.js';
|
|
56
57
|
import '../CnSettingsFormWidget/index.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registerDashboardWidgets.js","sources":["../../../../src/components/CnWidgetGrid/registerDashboardWidgets.js"],"sourcesContent":["/**\n * Side-effect aggregator for the cn-widget-library dashboard widget catalog.\n *\n * Importing this module imports every migrated widget's `index.js`, each of\n * which self-registers its `{ renderer, form, defaultContent, displayName,\n * icon }` into `dashboardWidgetRegistry` at load time. The library barrel\n * imports this module so the catalog is populated whenever a consuming app\n * imports `@conduction/nextcloud-vue`; `CnWidgetGrid` then resolves widgets by\n * type key and `CnAddWidgetModal` lists the addable types.\n *\n * The individual widget components are intentionally NOT public exports — they\n * are resolved by their registry type key (the whole point of the registry),\n * so consumers reference them via the manifest `widgetKey`, not by import.\n *\n * @module components/CnWidgetGrid/registerDashboardWidgets\n */\n\nimport CnChartWidget from '../CnChartWidget/CnChartWidget.vue'\nimport CnChartWidgetForm from '../CnChartWidgetForm/CnChartWidgetForm.vue'\nimport CnConversationWidget from '../CnConversationThread/CnConversationWidget.vue'\nimport CnCountdownWidget from '../CnCountdownWidget/CnCountdownWidget.vue'\nimport CnCountdownWidgetForm from '../CnCountdownWidgetForm/CnCountdownWidgetForm.vue'\nimport CnDocumentReviewWidget from '../CnDocumentReviewList/CnDocumentReviewWidget.vue'\nimport CnMapWidget from '../CnMapWidget/CnMapWidget.vue'\nimport CnMapWidgetForm from '../CnMapWidgetForm/CnMapWidgetForm.vue'\nimport CnMarkdownWidget2 from '../CnMarkdownWidget/CnMarkdownWidget.vue'\nimport CnMarkdownWidgetForm2 from '../CnMarkdownWidgetForm/CnMarkdownWidgetForm.vue'\nimport CnNextStepWidget from '../CnNextStepCard/CnNextStepWidget.vue'\nimport CnObjectListWidget2 from '../CnObjectListWidget/CnObjectListWidget.vue'\nimport CnObjectListWidgetForm2 from '../CnObjectListWidgetForm/CnObjectListWidgetForm.vue'\nimport CnRelatedObjectsWidget from '../CnRelatedObjectsWidget/CnRelatedObjectsWidget.vue'\nimport CnRelatedObjectsWidgetForm from '../CnRelatedObjectsWidgetForm/CnRelatedObjectsWidgetForm.vue'\nimport CnSavedViewWidget2 from '../CnSavedViewWidget/CnSavedViewWidget.vue'\nimport CnSavedViewWidgetForm2 from '../CnSavedViewWidgetForm/CnSavedViewWidgetForm.vue'\nimport CnStackedBarWidget from '../CnStackedBarWidget/CnStackedBarWidget.vue'\nimport CnStackedBarWidgetForm from '../CnStackedBarWidgetForm/CnStackedBarWidgetForm.vue'\nimport CnStagesWidget from '../CnStagesWidget/CnStagesWidget.vue'\nimport CnStagesWidgetForm from '../CnStagesWidgetForm/CnStagesWidgetForm.vue'\nimport CnStatsBlockWidget from '../CnStatsBlockWidget/CnStatsBlockWidget.vue'\nimport CnStatsBlockWidgetForm from '../CnStatsBlockWidgetForm/CnStatsBlockWidgetForm.vue'\nimport CnTabsWidget from '../CnTabsWidget/CnTabsWidget.vue'\nimport CnTabsWidgetForm from '../CnTabsWidgetForm/CnTabsWidgetForm.vue'\nimport CnWeekStripWidget from '../CnWeekStripWidget/CnWeekStripWidget.vue'\nimport CnWeekStripWidgetForm from '../CnWeekStripWidgetForm/CnWeekStripWidgetForm.vue'\n// Typed widgets registered with an explicit renderer + config FORM. chart /\n// stats-block render through CnDashboardPage's own isChart()/isStatsBlock()\n// branches and `related` through CnDetailPage's isRelatedWidget() branch — the\n// registry entry exists so the cog editor + Add-widget picker get a form (and,\n// for `related`, the detail-page surface). `table` aliases the object-list\n// renderer/form for legacy manifests using type:'table'.\nimport { registerDashboardWidget } from './dashboardWidgetRegistry.js'\n\nimport '../CnLabelWidget/index.js'\nimport '../CnTextWidget/index.js'\nimport '../CnImageWidget/index.js'\nimport '../CnLinkButtonWidget/index.js'\nimport '../CnDividerWidget/index.js'\nimport '../CnHeaderWidget/index.js'\nimport '../CnQuicklinksWidget/index.js'\nimport '../CnVideoWidget/index.js'\nimport '../CnDashTileWidget/index.js'\nimport '../CnLinksWidget/index.js'\nimport '../CnMenuWidget/index.js'\nimport '../CnContainerWidget/index.js'\nimport '../CnFilesWidget/index.js'\nimport '../CnPeopleWidget/index.js'\nimport '../CnCalendarWidget/index.js'\nimport '../CnNcWidgetWidget/index.js'\nimport '../CnSpendAnalyticsWidget/index.js'\nimport '../CnStatWidget/index.js'\nimport '../CnDeltaWidget/index.js'\nimport '../CnGaugeWidget/index.js'\nimport '../CnFlowRunsWidget/index.js'\nimport '../CnTasksWidget/index.js'\nimport '../CnSectionsWidget/index.js'\nimport '../CnFactsWidget/index.js'\nimport '../CnDeviceFramesWidget/index.js'\nimport '../CnPartyActionsWidget/index.js'\nimport '../CnFieldListWidget/index.js'\nimport '../CnSettingsFormWidget/index.js'\nimport '../CnSwitchRowsWidget/index.js'\nimport '../CnRadioCardsWidget/index.js'\nimport '../CnChipsFieldWidget/index.js'\nimport '../CnToggleTableWidget/index.js'\nimport '../CnChoicePickerWidget/index.js'\nimport '../CnRecordListWidget/index.js'\nimport '../CnSavedViewsWidget/index.js'\nimport '../CnNotepadWidget/index.js'\nimport '../CnObjectDataWidget/dashboardRegistration.js'\nimport '../CnObjectGeoWidget/dashboardRegistration.js'\nimport '../CnWidgetObjectTable/dashboardRegistration.js'\nimport '../CnAuditTrailWidget/dashboardRegistration.js'\nimport '../CnTimelineWidget/dashboardRegistration.js'\nimport '../CnKbSearchWidget/index.js'\nimport '../CnInteractionFormWidget/index.js'\nimport '../CnBannerWidget/index.js'\nimport '../CnWorkspaceFilterWidget/index.js'\n\nregisterDashboardWidget('chart', {\n\trenderer: CnChartWidget,\n\tform: CnChartWidgetForm,\n\tdefaultContent: {\n\t\tchartKind: 'area',\n\t\tdataSource: { register: '', schema: '', filter: {}, bucket: { field: '', interval: 'month', metric: 'count', metricField: '' } },\n\t},\n\tdisplayName: 'Chart',\n\ticon: 'ChartLine',\n})\n\nregisterDashboardWidget('stats-block', {\n\trenderer: CnStatsBlockWidget,\n\tform: CnStatsBlockWidgetForm,\n\tdefaultContent: {\n\t\ttitle: '',\n\t\tprops: { countLabel: '', variant: 'default', iconClass: '' },\n\t\tdataSource: { register: '', schema: '', metric: 'count', field: '', filter: {} },\n\t},\n\tdisplayName: 'Statistic card',\n\ticon: 'ChartBar',\n\t// Card family (docs/architecture/cards-and-widgets.md), like `stat` and\n\t// `delta`: the tile headlines itself with its own title, so the wrapper\n\t// renders no header of its own and would otherwise show the title twice.\n\tcard: true,\n})\n\n// `table` and `object-list` (below) are legacy aliases of `object-table` — same\n// config form (CnObjectListWidgetForm), same job. They stay registered so\n// existing placements keep rendering, but are hidden from every Add-widget\n// picker via a sentinel surface no picker queries (see widgetTypeAllowsSurface):\n// `object-table` is the one to add now. Rendering resolves through\n// getWidgetTypeEntry, which ignores `surfaces`, so hidden ≠ broken.\nregisterDashboardWidget('table', {\n\trenderer: CnObjectListWidget2,\n\tform: CnObjectListWidgetForm2,\n\tdefaultContent: {\n\t\tregister: '',\n\t\tschema: '',\n\t\tfilter: {},\n\t\tsort: { field: '', dir: 'asc' },\n\t\tlimit: 10,\n\t\tcolumns: [],\n\t},\n\tdisplayName: 'Table',\n\ticon: 'ClipboardList',\n\tsurfaces: ['legacy'],\n})\n\n// `object-list` is registered HERE and only here. Registering it from\n// CnObjectListWidget/index.js instead is not enough: package.json declares\n// `sideEffects: [\"**/*.css\"]` (ADR-061 tree-shaking), which lets\n// rollup/webpack legally DROP bare imports of side-effect-free JS modules —\n// the dist bundle shipped without the object-list registration and every\n// manifest `type:\"object-list\"` widget rendered blank. Inline calls in this\n// module survive because consumers import live bindings from the registry.\n//\n// That index.js ALSO self-registered, with a divergent entry (limit 5, no\n// `surfaces`), so both ran in a consumer's build — components/index.js\n// re-exports it, so it was never tree-shaken — and last-registration-wins\n// decided whether this legacy alias stayed hidden from the Add-widget picker.\n// The self-registration is gone; this entry is the one that already won.\nregisterDashboardWidget('object-list', {\n\trenderer: CnObjectListWidget2,\n\tform: CnObjectListWidgetForm2,\n\tdefaultContent: {\n\t\tregister: '',\n\t\tschema: '',\n\t\tfilter: {},\n\t\tsort: { field: '', dir: 'asc' },\n\t\tlimit: 25,\n\t\tcolumns: [],\n\t},\n\tdisplayName: 'Object list',\n\ticon: 'ClipboardList',\n\tsurfaces: ['legacy'],\n})\n\n// `saved-view`: a list driven by one of the reader's saved views. The only data\n// widget a user may add themselves, because the view carries the register and\n// schema a user would otherwise have to name. Registered inline for the same\n// tree-shaking reason as `object-list` above.\n// @spec openspec/changes/a-saved-view-drives-a-widget/tasks.md#task-1.1\nregisterDashboardWidget('saved-view', {\n\trenderer: CnSavedViewWidget2,\n\tform: CnSavedViewWidgetForm2,\n\tdefaultContent: { viewId: '', limit: 10 },\n\tdisplayName: 'Saved view',\n\ticon: 'ClipboardList',\n\tuserAddable: true,\n})\n\n// `markdown`: prose inside a grid page, through the one shared renderer. The\n// only catalog widget a PUBLIC host may mount so far: every other entry is\n// `public: false` until its author opts in deliberately.\n// @spec openspec/changes/widget-registry-public-flag/tasks.md#task-4\nregisterDashboardWidget('markdown', {\n\trenderer: CnMarkdownWidget2,\n\tform: CnMarkdownWidgetForm2,\n\tdefaultContent: { markdown: '' },\n\tdisplayName: 'Markdown',\n\ticon: 'FormatTitle',\n\tpublic: true,\n})\n\nregisterDashboardWidget('related', {\n\trenderer: CnRelatedObjectsWidget,\n\tform: CnRelatedObjectsWidgetForm,\n\tdefaultContent: { title: '', groups: [], hideSingleTabTitle: true, showTotalCount: true },\n\tdisplayName: 'Object relations',\n\ticon: 'FileTreeOutline',\n\tsurfaces: ['detail-page'],\n\townsTitle: true,\n})\n\n// `map` is registered here for the same tree-shaking reason as `object-list`\n// above — a bare `import '../CnMapWidget/index.js'` is a side-effect-free JS module\n// as far as the bundler is concerned, so it may legally be dropped and the widget\n// would silently never appear in Add Widget. CnMapWidget/index.js carried a\n// byte-identical copy of this entry, which only produced a duplicate-registration\n// warning on every consumer's boot; it no longer registers.\nregisterDashboardWidget('map', {\n\trenderer: CnMapWidget,\n\tform: CnMapWidgetForm,\n\tdefaultContent: {\n\t\tregister: '',\n\t\tschema: '',\n\t\t// The Netherlands, roughly — only visible until autoFit frames the objects.\n\t\tcenter: [52.13, 5.29],\n\t\tzoom: 7,\n\t\theight: '400px',\n\t\tpopupField: '',\n\t\tclustering: false,\n\t\tautoFit: true,\n\t\t// A map with no tile layer renders as a grey box. `basemaps` is opt-in and\n\t\t// empty by default (so consumers declaring a `tile` entry in `layers` are\n\t\t// unaffected), which meant a freshly-placed Map widget had NO background at\n\t\t// all. Ship OpenStreetMap — the Nextcloud CSP already allows *.tile.openstreetmap.org.\n\t\tbasemaps: [\n\t\t\t{\n\t\t\t\tname: 'OpenStreetMap',\n\t\t\t\turl: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',\n\t\t\t\tattribution: '© OpenStreetMap contributors',\n\t\t\t\toptions: { maxZoom: 19 },\n\t\t\t},\n\t\t],\n\t\tmarkers: {\n\t\t\tdataSource: { register: '', schema: '' },\n\t\t\tpopupField: '',\n\t\t\tclustering: false,\n\t\t},\n\t},\n\tdisplayName: 'Map',\n\ticon: 'Map',\n})\n\nregisterDashboardWidget('countdown', {\n\trenderer: CnCountdownWidget,\n\tform: CnCountdownWidgetForm,\n\tdefaultContent: {\n\t\tlabel: '',\n\t\tfield: '',\n\t\ticon: 'ClockOutline',\n\t\tthresholds: {},\n\t\tshowDate: true,\n\t},\n\tdisplayName: 'Countdown',\n\ticon: 'ClockOutline',\n\t// Card family: the tile headlines itself, so the wrapper draws no header.\n\tcard: true,\n\t// It reads a date off the BOUND RECORD, which only a detail page has.\n\tsurfaces: ['detail-page'],\n})\n\n// The case surfaces (detail-action-model-and-case-surfaces). Each reads the\n// BOUND RECORD, which only a detail page has, and none has a config form yet,\n// so `form: null` keeps them out of the Add-widget picker: they are placed\n// from the manifest. Registered inline for the same tree-shaking reason as\n// `map` above.\nregisterDashboardWidget('next-step', {\n\trenderer: CnNextStepWidget,\n\tform: null,\n\tdefaultContent: { field: 'status', stages: {} },\n\tdisplayName: 'Next step',\n\ticon: 'CheckCircleOutline',\n\tsurfaces: ['detail-page'],\n\townsTitle: true,\n})\n\nregisterDashboardWidget('document-review', {\n\trenderer: CnDocumentReviewWidget,\n\tform: null,\n\tdefaultContent: { field: 'documents', statusField: 'reviewStatus', statuses: [] },\n\tdisplayName: 'Document review',\n\ticon: 'FileDocumentCheckOutline',\n\tsurfaces: ['detail-page'],\n\townsTitle: true,\n})\n\nregisterDashboardWidget('conversation', {\n\trenderer: CnConversationWidget,\n\tform: null,\n\tdefaultContent: { field: 'messages', endpoint: '' },\n\tdisplayName: 'Conversation',\n\ticon: 'ForumOutline',\n\tsurfaces: ['detail-page'],\n\townsTitle: true,\n})\n\n// The record's stages, where clicking a stage moves the record there.\n// Registered inline for the same tree-shaking reason as `map` above.\nregisterDashboardWidget('stages', {\n\trenderer: CnStagesWidget,\n\tform: CnStagesWidgetForm,\n\tdefaultContent: {\n\t\tcurrentField: 'status',\n\t\torientation: 'horizontal',\n\t\tsize: 'medium',\n\t\tstagesEndpoint: { url: '', path: '' },\n\t\t// The LIFECYCLE, not a record write. OpenRegister decides what is\n\t\t// reachable and re-validates the move; a field write has neither.\n\t\ttransition: { kind: 'lifecycle' },\n\t},\n\tdisplayName: 'Stages',\n\ticon: 'Timeline',\n\t// Card family on the detail grid: a titled wrapper around a self-contained\n\t// strip, like the KPI tiles it usually sits beside.\n\tcard: true,\n\t// It reads and moves the BOUND RECORD, which only a detail page has.\n\tsurfaces: ['detail-page'],\n})\n\nregisterDashboardWidget('tabs', {\n\trenderer: CnTabsWidget,\n\tform: CnTabsWidgetForm,\n\tdefaultContent: {\n\t\ttabs: [],\n\t\tariaLabel: '',\n\t},\n\tdisplayName: 'Tabs',\n\ticon: 'TabPlus',\n\t// Renders OTHER widgets, so CnDetailWidgetHost hands it the surface's\n\t// sibling definitions and the context its children will need.\n\tcontainer: true,\n\t// The strip's labels ARE the titles, so a card header above them would name\n\t// the group twice.\n\townsTitle: true,\n\tsurfaces: ['detail-page'],\n})\n\n// The current week as day columns, with the dated items under each day.\n// Registered inline for the same tree-shaking reason as `map` above.\nregisterDashboardWidget('week-strip', {\n\trenderer: CnWeekStripWidget,\n\tform: CnWeekStripWidgetForm,\n\tdefaultContent: {\n\t\tsource: { register: '', schema: '', filter: {} },\n\t\tdateField: '',\n\t\ttitleField: '',\n\t\tmetaFields: [],\n\t\tdays: 5,\n\t\titemRoute: '',\n\t\temptyText: '',\n\t},\n\tdisplayName: 'Week strip',\n\ticon: 'Calendar',\n})\n\n// One segmented bar with a legend that carries the numbers.\nregisterDashboardWidget('stacked-bar', {\n\trenderer: CnStackedBarWidget,\n\tform: CnStackedBarWidgetForm,\n\tdefaultContent: {\n\t\tsource: { register: '', schema: '', groupBy: '', filter: {} },\n\t\torder: [],\n\t\tlabels: {},\n\t\temptyText: '',\n\t},\n\tdisplayName: 'Stacked bar',\n\ticon: 'ChartBar',\n})\n\n/**\n * Explicit no-op that guarantees this module (and therefore every widget's\n * self-registration side effect) is evaluated. Now optional: `CnDashboardPage`\n * and `CnDetailPage` import this module themselves, and a second call changes\n * nothing because the module body runs once.\n *\n * @return {void}\n */\nexport function registerBuiltinDashboardWidgets() {}\n"],"names":["CnChartWidget","CnChartWidgetForm","CnStatsBlockWidget","CnStatsBlockWidgetForm","CnObjectListWidget2","CnObjectListWidgetForm2","CnSavedViewWidget2","CnSavedViewWidgetForm2","CnMarkdownWidget2","CnMarkdownWidgetForm2","CnRelatedObjectsWidget","CnRelatedObjectsWidgetForm","CnMapWidget","CnMapWidgetForm","CnCountdownWidget","CnCountdownWidgetForm","CnNextStepWidget","CnDocumentReviewWidget","CnConversationWidget","CnStagesWidget","CnStagesWidgetForm","CnTabsWidget","CnTabsWidgetForm","CnWeekStripWidget","CnWeekStripWidgetForm","CnStackedBarWidget","CnStackedBarWidgetForm"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"registerDashboardWidgets.js","sources":["../../../../src/components/CnWidgetGrid/registerDashboardWidgets.js"],"sourcesContent":["/**\n * Side-effect aggregator for the cn-widget-library dashboard widget catalog.\n *\n * Importing this module imports every migrated widget's `index.js`, each of\n * which self-registers its `{ renderer, form, defaultContent, displayName,\n * icon }` into `dashboardWidgetRegistry` at load time. The library barrel\n * imports this module so the catalog is populated whenever a consuming app\n * imports `@conduction/nextcloud-vue`; `CnWidgetGrid` then resolves widgets by\n * type key and `CnAddWidgetModal` lists the addable types.\n *\n * The individual widget components are intentionally NOT public exports — they\n * are resolved by their registry type key (the whole point of the registry),\n * so consumers reference them via the manifest `widgetKey`, not by import.\n *\n * @module components/CnWidgetGrid/registerDashboardWidgets\n */\n\nimport CnChartWidget from '../CnChartWidget/CnChartWidget.vue'\nimport CnChartWidgetForm from '../CnChartWidgetForm/CnChartWidgetForm.vue'\nimport CnConversationWidget from '../CnConversationThread/CnConversationWidget.vue'\nimport CnCountdownWidget from '../CnCountdownWidget/CnCountdownWidget.vue'\nimport CnCountdownWidgetForm from '../CnCountdownWidgetForm/CnCountdownWidgetForm.vue'\nimport CnDocumentReviewWidget from '../CnDocumentReviewList/CnDocumentReviewWidget.vue'\nimport CnMapWidget from '../CnMapWidget/CnMapWidget.vue'\nimport CnMapWidgetForm from '../CnMapWidgetForm/CnMapWidgetForm.vue'\nimport CnMarkdownWidget2 from '../CnMarkdownWidget/CnMarkdownWidget.vue'\nimport CnMarkdownWidgetForm2 from '../CnMarkdownWidgetForm/CnMarkdownWidgetForm.vue'\nimport CnNextStepWidget from '../CnNextStepCard/CnNextStepWidget.vue'\nimport CnObjectListWidget2 from '../CnObjectListWidget/CnObjectListWidget.vue'\nimport CnObjectListWidgetForm2 from '../CnObjectListWidgetForm/CnObjectListWidgetForm.vue'\nimport CnRelatedObjectsWidget from '../CnRelatedObjectsWidget/CnRelatedObjectsWidget.vue'\nimport CnRelatedObjectsWidgetForm from '../CnRelatedObjectsWidgetForm/CnRelatedObjectsWidgetForm.vue'\nimport CnSavedViewWidget2 from '../CnSavedViewWidget/CnSavedViewWidget.vue'\nimport CnSavedViewWidgetForm2 from '../CnSavedViewWidgetForm/CnSavedViewWidgetForm.vue'\nimport CnStackedBarWidget from '../CnStackedBarWidget/CnStackedBarWidget.vue'\nimport CnStackedBarWidgetForm from '../CnStackedBarWidgetForm/CnStackedBarWidgetForm.vue'\nimport CnStagesWidget from '../CnStagesWidget/CnStagesWidget.vue'\nimport CnStagesWidgetForm from '../CnStagesWidgetForm/CnStagesWidgetForm.vue'\nimport CnStatsBlockWidget from '../CnStatsBlockWidget/CnStatsBlockWidget.vue'\nimport CnStatsBlockWidgetForm from '../CnStatsBlockWidgetForm/CnStatsBlockWidgetForm.vue'\nimport CnTabsWidget from '../CnTabsWidget/CnTabsWidget.vue'\nimport CnTabsWidgetForm from '../CnTabsWidgetForm/CnTabsWidgetForm.vue'\nimport CnWeekStripWidget from '../CnWeekStripWidget/CnWeekStripWidget.vue'\nimport CnWeekStripWidgetForm from '../CnWeekStripWidgetForm/CnWeekStripWidgetForm.vue'\n// Typed widgets registered with an explicit renderer + config FORM. chart /\n// stats-block render through CnDashboardPage's own isChart()/isStatsBlock()\n// branches and `related` through CnDetailPage's isRelatedWidget() branch — the\n// registry entry exists so the cog editor + Add-widget picker get a form (and,\n// for `related`, the detail-page surface). `table` aliases the object-list\n// renderer/form for legacy manifests using type:'table'.\nimport { registerDashboardWidget } from './dashboardWidgetRegistry.js'\n\nimport '../CnLabelWidget/index.js'\nimport '../CnTextWidget/index.js'\nimport '../CnImageWidget/index.js'\nimport '../CnLinkButtonWidget/index.js'\nimport '../CnDividerWidget/index.js'\nimport '../CnHeaderWidget/index.js'\nimport '../CnQuicklinksWidget/index.js'\nimport '../CnVideoWidget/index.js'\nimport '../CnDashTileWidget/index.js'\nimport '../CnLinksWidget/index.js'\nimport '../CnMenuWidget/index.js'\nimport '../CnContainerWidget/index.js'\nimport '../CnFilesWidget/index.js'\nimport '../CnPeopleWidget/index.js'\nimport '../CnCalendarWidget/index.js'\nimport '../CnNcWidgetWidget/index.js'\nimport '../CnSpendAnalyticsWidget/index.js'\nimport '../CnStatWidget/index.js'\nimport '../CnDeltaWidget/index.js'\nimport '../CnGaugeWidget/index.js'\nimport '../CnFlowRunsWidget/index.js'\nimport '../CnTasksWidget/index.js'\nimport '../CnSectionsWidget/index.js'\nimport '../CnFactsWidget/index.js'\nimport '../CnDeviceFramesWidget/index.js'\nimport '../CnChecklistRunWidget/index.js'\nimport '../CnPartyActionsWidget/index.js'\nimport '../CnFieldListWidget/index.js'\nimport '../CnSettingsFormWidget/index.js'\nimport '../CnSwitchRowsWidget/index.js'\nimport '../CnRadioCardsWidget/index.js'\nimport '../CnChipsFieldWidget/index.js'\nimport '../CnToggleTableWidget/index.js'\nimport '../CnChoicePickerWidget/index.js'\nimport '../CnRecordListWidget/index.js'\nimport '../CnSavedViewsWidget/index.js'\nimport '../CnNotepadWidget/index.js'\nimport '../CnObjectDataWidget/dashboardRegistration.js'\nimport '../CnObjectGeoWidget/dashboardRegistration.js'\nimport '../CnWidgetObjectTable/dashboardRegistration.js'\nimport '../CnAuditTrailWidget/dashboardRegistration.js'\nimport '../CnTimelineWidget/dashboardRegistration.js'\nimport '../CnKbSearchWidget/index.js'\nimport '../CnInteractionFormWidget/index.js'\nimport '../CnBannerWidget/index.js'\nimport '../CnWorkspaceFilterWidget/index.js'\n\nregisterDashboardWidget('chart', {\n\trenderer: CnChartWidget,\n\tform: CnChartWidgetForm,\n\tdefaultContent: {\n\t\tchartKind: 'area',\n\t\tdataSource: { register: '', schema: '', filter: {}, bucket: { field: '', interval: 'month', metric: 'count', metricField: '' } },\n\t},\n\tdisplayName: 'Chart',\n\ticon: 'ChartLine',\n})\n\nregisterDashboardWidget('stats-block', {\n\trenderer: CnStatsBlockWidget,\n\tform: CnStatsBlockWidgetForm,\n\tdefaultContent: {\n\t\ttitle: '',\n\t\tprops: { countLabel: '', variant: 'default', iconClass: '' },\n\t\tdataSource: { register: '', schema: '', metric: 'count', field: '', filter: {} },\n\t},\n\tdisplayName: 'Statistic card',\n\ticon: 'ChartBar',\n\t// Card family (docs/architecture/cards-and-widgets.md), like `stat` and\n\t// `delta`: the tile headlines itself with its own title, so the wrapper\n\t// renders no header of its own and would otherwise show the title twice.\n\tcard: true,\n})\n\n// `table` and `object-list` (below) are legacy aliases of `object-table` — same\n// config form (CnObjectListWidgetForm), same job. They stay registered so\n// existing placements keep rendering, but are hidden from every Add-widget\n// picker via a sentinel surface no picker queries (see widgetTypeAllowsSurface):\n// `object-table` is the one to add now. Rendering resolves through\n// getWidgetTypeEntry, which ignores `surfaces`, so hidden ≠ broken.\nregisterDashboardWidget('table', {\n\trenderer: CnObjectListWidget2,\n\tform: CnObjectListWidgetForm2,\n\tdefaultContent: {\n\t\tregister: '',\n\t\tschema: '',\n\t\tfilter: {},\n\t\tsort: { field: '', dir: 'asc' },\n\t\tlimit: 10,\n\t\tcolumns: [],\n\t},\n\tdisplayName: 'Table',\n\ticon: 'ClipboardList',\n\tsurfaces: ['legacy'],\n})\n\n// `object-list` is registered HERE and only here. Registering it from\n// CnObjectListWidget/index.js instead is not enough: package.json declares\n// `sideEffects: [\"**/*.css\"]` (ADR-061 tree-shaking), which lets\n// rollup/webpack legally DROP bare imports of side-effect-free JS modules —\n// the dist bundle shipped without the object-list registration and every\n// manifest `type:\"object-list\"` widget rendered blank. Inline calls in this\n// module survive because consumers import live bindings from the registry.\n//\n// That index.js ALSO self-registered, with a divergent entry (limit 5, no\n// `surfaces`), so both ran in a consumer's build — components/index.js\n// re-exports it, so it was never tree-shaken — and last-registration-wins\n// decided whether this legacy alias stayed hidden from the Add-widget picker.\n// The self-registration is gone; this entry is the one that already won.\nregisterDashboardWidget('object-list', {\n\trenderer: CnObjectListWidget2,\n\tform: CnObjectListWidgetForm2,\n\tdefaultContent: {\n\t\tregister: '',\n\t\tschema: '',\n\t\tfilter: {},\n\t\tsort: { field: '', dir: 'asc' },\n\t\tlimit: 25,\n\t\tcolumns: [],\n\t},\n\tdisplayName: 'Object list',\n\ticon: 'ClipboardList',\n\tsurfaces: ['legacy'],\n})\n\n// `saved-view`: a list driven by one of the reader's saved views. The only data\n// widget a user may add themselves, because the view carries the register and\n// schema a user would otherwise have to name. Registered inline for the same\n// tree-shaking reason as `object-list` above.\n// @spec openspec/changes/a-saved-view-drives-a-widget/tasks.md#task-1.1\nregisterDashboardWidget('saved-view', {\n\trenderer: CnSavedViewWidget2,\n\tform: CnSavedViewWidgetForm2,\n\tdefaultContent: { viewId: '', limit: 10 },\n\tdisplayName: 'Saved view',\n\ticon: 'ClipboardList',\n\tuserAddable: true,\n})\n\n// `markdown`: prose inside a grid page, through the one shared renderer. The\n// only catalog widget a PUBLIC host may mount so far: every other entry is\n// `public: false` until its author opts in deliberately.\n// @spec openspec/changes/widget-registry-public-flag/tasks.md#task-4\nregisterDashboardWidget('markdown', {\n\trenderer: CnMarkdownWidget2,\n\tform: CnMarkdownWidgetForm2,\n\tdefaultContent: { markdown: '' },\n\tdisplayName: 'Markdown',\n\ticon: 'FormatTitle',\n\tpublic: true,\n})\n\nregisterDashboardWidget('related', {\n\trenderer: CnRelatedObjectsWidget,\n\tform: CnRelatedObjectsWidgetForm,\n\tdefaultContent: { title: '', groups: [], hideSingleTabTitle: true, showTotalCount: true },\n\tdisplayName: 'Object relations',\n\ticon: 'FileTreeOutline',\n\tsurfaces: ['detail-page'],\n\townsTitle: true,\n})\n\n// `map` is registered here for the same tree-shaking reason as `object-list`\n// above — a bare `import '../CnMapWidget/index.js'` is a side-effect-free JS module\n// as far as the bundler is concerned, so it may legally be dropped and the widget\n// would silently never appear in Add Widget. CnMapWidget/index.js carried a\n// byte-identical copy of this entry, which only produced a duplicate-registration\n// warning on every consumer's boot; it no longer registers.\nregisterDashboardWidget('map', {\n\trenderer: CnMapWidget,\n\tform: CnMapWidgetForm,\n\tdefaultContent: {\n\t\tregister: '',\n\t\tschema: '',\n\t\t// The Netherlands, roughly — only visible until autoFit frames the objects.\n\t\tcenter: [52.13, 5.29],\n\t\tzoom: 7,\n\t\theight: '400px',\n\t\tpopupField: '',\n\t\tclustering: false,\n\t\tautoFit: true,\n\t\t// A map with no tile layer renders as a grey box. `basemaps` is opt-in and\n\t\t// empty by default (so consumers declaring a `tile` entry in `layers` are\n\t\t// unaffected), which meant a freshly-placed Map widget had NO background at\n\t\t// all. Ship OpenStreetMap — the Nextcloud CSP already allows *.tile.openstreetmap.org.\n\t\tbasemaps: [\n\t\t\t{\n\t\t\t\tname: 'OpenStreetMap',\n\t\t\t\turl: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',\n\t\t\t\tattribution: '© OpenStreetMap contributors',\n\t\t\t\toptions: { maxZoom: 19 },\n\t\t\t},\n\t\t],\n\t\tmarkers: {\n\t\t\tdataSource: { register: '', schema: '' },\n\t\t\tpopupField: '',\n\t\t\tclustering: false,\n\t\t},\n\t},\n\tdisplayName: 'Map',\n\ticon: 'Map',\n})\n\nregisterDashboardWidget('countdown', {\n\trenderer: CnCountdownWidget,\n\tform: CnCountdownWidgetForm,\n\tdefaultContent: {\n\t\tlabel: '',\n\t\tfield: '',\n\t\ticon: 'ClockOutline',\n\t\tthresholds: {},\n\t\tshowDate: true,\n\t},\n\tdisplayName: 'Countdown',\n\ticon: 'ClockOutline',\n\t// Card family: the tile headlines itself, so the wrapper draws no header.\n\tcard: true,\n\t// It reads a date off the BOUND RECORD, which only a detail page has.\n\tsurfaces: ['detail-page'],\n})\n\n// The case surfaces (detail-action-model-and-case-surfaces). Each reads the\n// BOUND RECORD, which only a detail page has, and none has a config form yet,\n// so `form: null` keeps them out of the Add-widget picker: they are placed\n// from the manifest. Registered inline for the same tree-shaking reason as\n// `map` above.\nregisterDashboardWidget('next-step', {\n\trenderer: CnNextStepWidget,\n\tform: null,\n\tdefaultContent: { field: 'status', stages: {} },\n\tdisplayName: 'Next step',\n\ticon: 'CheckCircleOutline',\n\tsurfaces: ['detail-page'],\n\townsTitle: true,\n})\n\nregisterDashboardWidget('document-review', {\n\trenderer: CnDocumentReviewWidget,\n\tform: null,\n\tdefaultContent: { field: 'documents', statusField: 'reviewStatus', statuses: [] },\n\tdisplayName: 'Document review',\n\ticon: 'FileDocumentCheckOutline',\n\tsurfaces: ['detail-page'],\n\townsTitle: true,\n})\n\nregisterDashboardWidget('conversation', {\n\trenderer: CnConversationWidget,\n\tform: null,\n\tdefaultContent: { field: 'messages', endpoint: '' },\n\tdisplayName: 'Conversation',\n\ticon: 'ForumOutline',\n\tsurfaces: ['detail-page'],\n\townsTitle: true,\n})\n\n// The record's stages, where clicking a stage moves the record there.\n// Registered inline for the same tree-shaking reason as `map` above.\nregisterDashboardWidget('stages', {\n\trenderer: CnStagesWidget,\n\tform: CnStagesWidgetForm,\n\tdefaultContent: {\n\t\tcurrentField: 'status',\n\t\torientation: 'horizontal',\n\t\tsize: 'medium',\n\t\tstagesEndpoint: { url: '', path: '' },\n\t\t// The LIFECYCLE, not a record write. OpenRegister decides what is\n\t\t// reachable and re-validates the move; a field write has neither.\n\t\ttransition: { kind: 'lifecycle' },\n\t},\n\tdisplayName: 'Stages',\n\ticon: 'Timeline',\n\t// Card family on the detail grid: a titled wrapper around a self-contained\n\t// strip, like the KPI tiles it usually sits beside.\n\tcard: true,\n\t// It reads and moves the BOUND RECORD, which only a detail page has.\n\tsurfaces: ['detail-page'],\n})\n\nregisterDashboardWidget('tabs', {\n\trenderer: CnTabsWidget,\n\tform: CnTabsWidgetForm,\n\tdefaultContent: {\n\t\ttabs: [],\n\t\tariaLabel: '',\n\t},\n\tdisplayName: 'Tabs',\n\ticon: 'TabPlus',\n\t// Renders OTHER widgets, so CnDetailWidgetHost hands it the surface's\n\t// sibling definitions and the context its children will need.\n\tcontainer: true,\n\t// The strip's labels ARE the titles, so a card header above them would name\n\t// the group twice.\n\townsTitle: true,\n\tsurfaces: ['detail-page'],\n})\n\n// The current week as day columns, with the dated items under each day.\n// Registered inline for the same tree-shaking reason as `map` above.\nregisterDashboardWidget('week-strip', {\n\trenderer: CnWeekStripWidget,\n\tform: CnWeekStripWidgetForm,\n\tdefaultContent: {\n\t\tsource: { register: '', schema: '', filter: {} },\n\t\tdateField: '',\n\t\ttitleField: '',\n\t\tmetaFields: [],\n\t\tdays: 5,\n\t\titemRoute: '',\n\t\temptyText: '',\n\t},\n\tdisplayName: 'Week strip',\n\ticon: 'Calendar',\n})\n\n// One segmented bar with a legend that carries the numbers.\nregisterDashboardWidget('stacked-bar', {\n\trenderer: CnStackedBarWidget,\n\tform: CnStackedBarWidgetForm,\n\tdefaultContent: {\n\t\tsource: { register: '', schema: '', groupBy: '', filter: {} },\n\t\torder: [],\n\t\tlabels: {},\n\t\temptyText: '',\n\t},\n\tdisplayName: 'Stacked bar',\n\ticon: 'ChartBar',\n})\n\n/**\n * Explicit no-op that guarantees this module (and therefore every widget's\n * self-registration side effect) is evaluated. Now optional: `CnDashboardPage`\n * and `CnDetailPage` import this module themselves, and a second call changes\n * nothing because the module body runs once.\n *\n * @return {void}\n */\nexport function registerBuiltinDashboardWidgets() {}\n"],"names":["CnChartWidget","CnChartWidgetForm","CnStatsBlockWidget","CnStatsBlockWidgetForm","CnObjectListWidget2","CnObjectListWidgetForm2","CnSavedViewWidget2","CnSavedViewWidgetForm2","CnMarkdownWidget2","CnMarkdownWidgetForm2","CnRelatedObjectsWidget","CnRelatedObjectsWidgetForm","CnMapWidget","CnMapWidgetForm","CnCountdownWidget","CnCountdownWidgetForm","CnNextStepWidget","CnDocumentReviewWidget","CnConversationWidget","CnStagesWidget","CnStagesWidgetForm","CnTabsWidget","CnTabsWidgetForm","CnWeekStripWidget","CnWeekStripWidgetForm","CnStackedBarWidget","CnStackedBarWidgetForm"],"mappings":"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"}
|