@conduction/nextcloud-vue 2.65.0 → 2.67.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/CnActionsBar/CnActionsBar.vue2.js +19 -0
- package/dist/esm/components/CnActionsBar/CnActionsBar.vue2.js.map +1 -1
- package/dist/esm/components/CnActionsBar/CnActionsBar.vue3.js +10 -3
- package/dist/esm/components/CnActionsBar/CnActionsBar.vue3.js.map +1 -1
- package/dist/esm/components/CnAppNav/CnAppNav.vue2.js +2 -2
- package/dist/esm/components/CnAppNav/CnAppNav.vue2.js.map +1 -1
- package/dist/esm/components/CnAppNav/CnAppNav.vue3.js.map +1 -1
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js +99 -2
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js.map +1 -1
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue3.js +438 -383
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue3.js.map +1 -1
- package/dist/esm/components/CnDataTable/CnColumnFilterPopover.vue2.js +9 -3
- package/dist/esm/components/CnDataTable/CnColumnFilterPopover.vue2.js.map +1 -1
- package/dist/esm/components/CnDataTable/CnColumnFilterPopover.vue3.js +1 -1
- package/dist/esm/components/CnDataTable/CnColumnFilterPopover.vue3.js.map +1 -1
- package/dist/esm/components/CnDataTable/CnDataTable.vue2.js +4 -4
- 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 +78 -21
- package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js.map +1 -1
- package/dist/esm/components/CnDetailPage/CnDetailPage.vue3.js +129 -96
- package/dist/esm/components/CnDetailPage/CnDetailPage.vue3.js.map +1 -1
- package/dist/esm/components/CnFkResolveCell/CnFkResolveCell.vue2.js +3 -1
- package/dist/esm/components/CnFkResolveCell/CnFkResolveCell.vue2.js.map +1 -1
- package/dist/esm/components/CnFormDialog/CnFormDialog.vue2.js +144 -4
- package/dist/esm/components/CnFormDialog/CnFormDialog.vue2.js.map +1 -1
- package/dist/esm/components/CnFormDialog/CnFormDialog.vue3.js.map +1 -1
- package/dist/esm/components/CnHeaderWidget/CnHeaderWidget.vue2.js +63 -7
- package/dist/esm/components/CnHeaderWidget/CnHeaderWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnHeaderWidget/CnHeaderWidget.vue3.js +2 -1
- package/dist/esm/components/CnHeaderWidget/CnHeaderWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js +31 -1
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js.map +1 -1
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js +335 -313
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js.map +1 -1
- package/dist/esm/components/CnSegmentedControl/CnSegmentedControl.vue2.js +11 -0
- package/dist/esm/components/CnSegmentedControl/CnSegmentedControl.vue2.js.map +1 -1
- package/dist/esm/components/CnSegmentedControl/CnSegmentedControl.vue3.js +2 -1
- package/dist/esm/components/CnSegmentedControl/CnSegmentedControl.vue3.js.map +1 -1
- package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue2.js +5 -11
- package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue2.js.map +1 -1
- package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue3.js.map +1 -1
- package/dist/esm/composables/useDependencyCheck.js +44 -1
- package/dist/esm/composables/useDependencyCheck.js.map +1 -1
- package/dist/esm/composables/useListView.js +43 -1
- package/dist/esm/composables/useListView.js.map +1 -1
- package/dist/esm/composables/useSetupStatus.js +26 -3
- package/dist/esm/composables/useSetupStatus.js.map +1 -1
- package/dist/esm/l10n/en.json.js +7 -1
- package/dist/esm/l10n/en.json.js.map +1 -1
- package/dist/esm/l10n/nl.json.js +7 -1
- package/dist/esm/l10n/nl.json.js.map +1 -1
- package/dist/esm/mixins/pageViews.js +400 -0
- package/dist/esm/mixins/pageViews.js.map +1 -0
- package/dist/esm/nextcloud-vue.css +38 -2
- package/dist/esm/store/plugins/liveUpdates.js +19 -9
- package/dist/esm/store/plugins/liveUpdates.js.map +1 -1
- package/dist/esm/store/useObjectStore.js +20 -9
- package/dist/esm/store/useObjectStore.js.map +1 -1
- package/dist/esm/utils/actionsDispatcher.js +11 -2
- package/dist/esm/utils/actionsDispatcher.js.map +1 -1
- package/dist/esm/utils/columnFilters.js +27 -3
- package/dist/esm/utils/columnFilters.js.map +1 -1
- package/dist/esm/utils/schema.js +40 -2
- package/dist/esm/utils/schema.js.map +1 -1
- package/dist/esm/utils/validateManifestV2.compiled.js +2 -2
- package/dist/esm/utils/validateManifestV2.compiled.js.map +1 -1
- package/dist/nextcloud-vue.cjs.js +2377 -1247
- package/dist/nextcloud-vue.cjs.js.map +2 -2
- package/dist/nextcloud-vue.css +38 -2
- package/l10n/en.json +7 -1
- package/l10n/nl.json +7 -1
- package/package.json +1 -1
- package/src/components/CnActionsBar/CnActionsBar.md +2 -1
- package/src/components/CnActionsBar/CnActionsBar.vue +25 -1
- package/src/components/CnAppNav/CnAppNav.vue +2 -2
- package/src/components/CnDashboardPage/CnDashboardPage.vue +165 -8
- package/src/components/CnDataTable/CnColumnFilterPopover.vue +11 -5
- package/src/components/CnDataTable/CnDataTable.md +1 -1
- package/src/components/CnDataTable/CnDataTable.vue +4 -4
- package/src/components/CnDetailPage/CnDetailPage.vue +94 -5
- package/src/components/CnFkResolveCell/CnFkResolveCell.vue +3 -1
- package/src/components/CnFormDialog/CnFormDialog.vue +144 -4
- package/src/components/CnHeaderWidget/CnHeaderWidget.vue +67 -8
- package/src/components/CnIndexPage/CnIndexPage.md +2 -1
- package/src/components/CnIndexPage/CnIndexPage.vue +47 -1
- package/src/components/CnSegmentedControl/CnSegmentedControl.md +1 -1
- package/src/components/CnSegmentedControl/CnSegmentedControl.vue +12 -0
- package/src/components/CnSetupWizard/CnSetupWizard.vue +5 -11
- package/src/composables/useDependencyCheck.js +43 -0
- package/src/composables/useListView.js +43 -1
- package/src/composables/useSetupStatus.js +26 -3
- package/src/css/actions-bar.css +20 -2
- package/src/css/detail-page.css +5 -0
- package/src/mixins/pageViews.js +396 -0
- package/src/schemas/app-manifest-v2.schema.json +31 -3
- package/src/schemas/app-manifest.schema.json +1 -1
- package/src/store/plugins/liveUpdates.js +19 -9
- package/src/store/useObjectStore.js +19 -8
- package/src/utils/actionsDispatcher.js +11 -2
- package/src/utils/columnFilters.js +29 -2
- package/src/utils/schema.js +40 -2
- package/src/utils/validateManifestV2.compiled.js +2 -2
|
@@ -7,7 +7,7 @@ let popoverSeq = 0;
|
|
|
7
7
|
*
|
|
8
8
|
* Renders the control that fits the column: a checkbox list for an enum, yes,
|
|
9
9
|
* no or any for a boolean, from and to for a number or a date, a searchable
|
|
10
|
-
* list of referenced objects for a reference, and
|
|
10
|
+
* list of referenced objects for a reference, and a contains box for text.
|
|
11
11
|
* Real inputs throughout, so every control works from the keyboard. Escape
|
|
12
12
|
* closes it and the host returns focus to the filter button.
|
|
13
13
|
*
|
|
@@ -141,8 +141,14 @@ var script = {
|
|
|
141
141
|
return translate('nextcloud-vue', 'To')
|
|
142
142
|
},
|
|
143
143
|
|
|
144
|
-
|
|
145
|
-
|
|
144
|
+
/**
|
|
145
|
+
* Label of the text box: the text filter matches on contains.
|
|
146
|
+
*
|
|
147
|
+
* @return {string}
|
|
148
|
+
* @spec openspec/changes/header-filter-contains/specs/cn-data-table/spec.md#requirement-a-text-header-filter-matches-on-contains
|
|
149
|
+
*/
|
|
150
|
+
containsLabel() {
|
|
151
|
+
return translate('nextcloud-vue', 'Contains')
|
|
146
152
|
},
|
|
147
153
|
|
|
148
154
|
clearLabel() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CnColumnFilterPopover.vue2.js","sources":["../../../../src/components/CnDataTable/CnColumnFilterPopover.vue"],"sourcesContent":["<!-- SPDX-License-Identifier: EUPL-1.2 -->\n<!-- SPDX-FileCopyrightText: 2026 Conduction B.V. <info@conduction.nl> -->\n<template>\n\t<Teleport to=\"body\" :disabled=\"!teleport\">\n\t\t<div\n\t\t\tref=\"panel\"\n\t\t\tclass=\"cn-column-filter\"\n\t\t\trole=\"dialog\"\n\t\t\t:aria-labelledby=\"headingId\"\n\t\t\t:style=\"panelStyle\"\n\t\t\tdata-testid=\"cn-column-filter\"\n\t\t\t@keydown.esc.stop.prevent=\"close\"\n\t\t\t@keydown.enter=\"onEnter\">\n\t\t\t<p :id=\"headingId\" class=\"cn-column-filter__heading\">\n\t\t\t\t{{ headingText }}\n\t\t\t</p>\n\n\t\t\t<!-- enum and reference: a checkbox list of real inputs -->\n\t\t\t<template v-if=\"def.kind === 'enum' || def.kind === 'reference'\">\n\t\t\t\t<label v-if=\"def.kind === 'reference'\" class=\"cn-column-filter__field\">\n\t\t\t\t\t<span class=\"cn-column-filter__label\">{{ searchLabel }}</span>\n\t\t\t\t\t<input\n\t\t\t\t\t\tv-model=\"query\"\n\t\t\t\t\t\tclass=\"cn-column-filter__input\"\n\t\t\t\t\t\ttype=\"search\"\n\t\t\t\t\t\tdata-testid=\"cn-column-filter-search\"\n\t\t\t\t\t\t@input=\"onSearchInput\">\n\t\t\t\t</label>\n\t\t\t\t<p v-if=\"def.kind === 'reference' && referenceLoading\" class=\"cn-column-filter__hint\" role=\"status\">\n\t\t\t\t\t{{ loadingLabel }}\n\t\t\t\t</p>\n\t\t\t\t<p v-else-if=\"def.kind === 'reference' && referenceError\" class=\"cn-column-filter__hint\" role=\"status\">\n\t\t\t\t\t{{ referenceError }}\n\t\t\t\t</p>\n\t\t\t\t<fieldset class=\"cn-column-filter__options\">\n\t\t\t\t\t<legend class=\"cn-column-filter__sr-only\">\n\t\t\t\t\t\t{{ headingText }}\n\t\t\t\t\t</legend>\n\t\t\t\t\t<label\n\t\t\t\t\t\tv-for=\"option in listOptions\"\n\t\t\t\t\t\t:key=\"option.value\"\n\t\t\t\t\t\tclass=\"cn-column-filter__option\">\n\t\t\t\t\t\t<input\n\t\t\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\t\t\t:value=\"option.value\"\n\t\t\t\t\t\t\t:checked=\"draft.values.includes(option.value)\"\n\t\t\t\t\t\t\tdata-testid=\"cn-column-filter-option\"\n\t\t\t\t\t\t\t@change=\"toggleValue(option.value)\">\n\t\t\t\t\t\t<span>{{ option.label }}</span>\n\t\t\t\t\t</label>\n\t\t\t\t\t<p v-if=\"listOptions.length === 0 && !referenceLoading\" class=\"cn-column-filter__hint\">\n\t\t\t\t\t\t{{ noOptionsLabel }}\n\t\t\t\t\t</p>\n\t\t\t\t</fieldset>\n\t\t\t</template>\n\n\t\t\t<!-- boolean: yes, no, any -->\n\t\t\t<fieldset v-else-if=\"def.kind === 'boolean'\" class=\"cn-column-filter__options\">\n\t\t\t\t<legend class=\"cn-column-filter__sr-only\">\n\t\t\t\t\t{{ headingText }}\n\t\t\t\t</legend>\n\t\t\t\t<label v-for=\"option in booleanOptions\" :key=\"option.value\" class=\"cn-column-filter__option\">\n\t\t\t\t\t<input\n\t\t\t\t\t\ttype=\"radio\"\n\t\t\t\t\t\t:name=\"headingId + '-bool'\"\n\t\t\t\t\t\t:value=\"option.value\"\n\t\t\t\t\t\t:checked=\"draft.value === option.value\"\n\t\t\t\t\t\tdata-testid=\"cn-column-filter-option\"\n\t\t\t\t\t\t@change=\"draft.value = option.value\">\n\t\t\t\t\t<span>{{ option.label }}</span>\n\t\t\t\t</label>\n\t\t\t</fieldset>\n\n\t\t\t<!-- number and date: from and to -->\n\t\t\t<div v-else-if=\"def.kind === 'number' || def.kind === 'date'\" class=\"cn-column-filter__range\">\n\t\t\t\t<label class=\"cn-column-filter__field\">\n\t\t\t\t\t<span class=\"cn-column-filter__label\">{{ fromLabel }}</span>\n\t\t\t\t\t<input\n\t\t\t\t\t\tv-model=\"draft.from\"\n\t\t\t\t\t\tclass=\"cn-column-filter__input\"\n\t\t\t\t\t\t:type=\"def.kind === 'date' ? 'date' : 'number'\"\n\t\t\t\t\t\tdata-testid=\"cn-column-filter-from\">\n\t\t\t\t</label>\n\t\t\t\t<label class=\"cn-column-filter__field\">\n\t\t\t\t\t<span class=\"cn-column-filter__label\">{{ toLabel }}</span>\n\t\t\t\t\t<input\n\t\t\t\t\t\tv-model=\"draft.to\"\n\t\t\t\t\t\tclass=\"cn-column-filter__input\"\n\t\t\t\t\t\t:type=\"def.kind === 'date' ? 'date' : 'number'\"\n\t\t\t\t\t\tdata-testid=\"cn-column-filter-to\">\n\t\t\t\t</label>\n\t\t\t</div>\n\n\t\t\t<!-- string: equals -->\n\t\t\t<label v-else class=\"cn-column-filter__field\">\n\t\t\t\t<span class=\"cn-column-filter__label\">{{ equalsLabel }}</span>\n\t\t\t\t<input\n\t\t\t\t\tv-model=\"draft.value\"\n\t\t\t\t\tclass=\"cn-column-filter__input\"\n\t\t\t\t\ttype=\"text\"\n\t\t\t\t\tdata-testid=\"cn-column-filter-text\">\n\t\t\t</label>\n\n\t\t\t<div class=\"cn-column-filter__actions\">\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"cn-column-filter__button\"\n\t\t\t\t\tdata-testid=\"cn-column-filter-clear\"\n\t\t\t\t\t@click=\"clear\">\n\t\t\t\t\t{{ clearLabel }}\n\t\t\t\t</button>\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"cn-column-filter__button cn-column-filter__button--primary\"\n\t\t\t\t\tdata-testid=\"cn-column-filter-apply\"\n\t\t\t\t\t@click=\"apply\">\n\t\t\t\t\t{{ applyLabel }}\n\t\t\t\t</button>\n\t\t\t</div>\n\t\t</div>\n\t</Teleport>\n</template>\n\n<script>\nimport { translate as t } from '@nextcloud/l10n'\n\nlet popoverSeq = 0\n\n/**\n * CnColumnFilterPopover — the small panel a table header's filter button opens.\n *\n * Renders the control that fits the column: a checkbox list for an enum, yes,\n * no or any for a boolean, from and to for a number or a date, a searchable\n * list of referenced objects for a reference, and an equals box for text.\n * Real inputs throughout, so every control works from the keyboard. Escape\n * closes it and the host returns focus to the filter button.\n *\n * Internal to CnDataTable. It emits a state object; CnDataTable turns that\n * into query parameters with `columnFilterParams`.\n *\n * @spec openspec/changes/table-header-sort-and-filter/specs/cn-data-table/spec.md#requirement-every-backed-column-filters-from-its-header\n */\nexport default {\n\tname: 'CnColumnFilterPopover',\n\n\tprops: {\n\t\t/** The filter definition from `columnFilterDef`. */\n\t\tdef: {\n\t\t\ttype: Object,\n\t\t\trequired: true,\n\t\t},\n\n\t\t/** The column's current state from `columnFilterState`. */\n\t\tstate: {\n\t\t\ttype: Object,\n\t\t\tdefault: () => ({}),\n\t\t},\n\n\t\t/** The translated column label. */\n\t\tlabel: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** The filter button's bounding rect, to place the panel under it. */\n\t\tanchorRect: {\n\t\t\ttype: Object,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/** Register slug a reference column's objects live in, when the column names none. */\n\t\tregister: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** Render into `<body>`, so a scrolling table cannot clip the panel. */\n\t\tteleport: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: true,\n\t\t},\n\t},\n\n\temits: ['apply', 'close'],\n\n\tdata() {\n\t\tpopoverSeq += 1\n\t\tconst s = this.state || {}\n\t\treturn {\n\t\t\theadingId: 'cn-column-filter-' + popoverSeq,\n\t\t\tdraft: {\n\t\t\t\tvalues: Array.isArray(s.values) ? [...s.values] : [],\n\t\t\t\tvalue: s.value !== undefined && s.value !== null ? String(s.value) : '',\n\t\t\t\tfrom: s.from || '',\n\t\t\t\tto: s.to || '',\n\t\t\t},\n\n\t\t\tquery: '',\n\t\t\treferenceOptions: [],\n\t\t\treferenceLabels: {},\n\t\t\treferenceLoading: false,\n\t\t\treferenceError: '',\n\t\t\tsearchTimer: null,\n\t\t}\n\t},\n\n\tcomputed: {\n\t\theadingText() {\n\t\t\treturn t('nextcloud-vue', 'Filter {column}', { column: this.label })\n\t\t},\n\n\t\t/**\n\t\t * The options a list filter shows. For a reference, the search results\n\t\t * plus any picked object that is not among them, so a selection never\n\t\t * disappears from view.\n\t\t *\n\t\t * @return {Array<{value: string, label: string}>}\n\t\t */\n\t\tlistOptions() {\n\t\t\tif (this.def.kind !== 'reference') {\n\t\t\t\treturn this.def.options || []\n\t\t\t}\n\t\t\tconst shown = new Set(this.referenceOptions.map((o) => o.value))\n\t\t\tconst picked = this.draft.values\n\t\t\t\t.filter((v) => !shown.has(v))\n\t\t\t\t.map((v) => ({ value: v, label: this.referenceLabels[v] || v }))\n\t\t\treturn [...picked, ...this.referenceOptions]\n\t\t},\n\n\t\tbooleanOptions() {\n\t\t\treturn [\n\t\t\t\t{ value: '', label: t('nextcloud-vue', 'Any') },\n\t\t\t\t{ value: 'true', label: t('nextcloud-vue', 'Yes') },\n\t\t\t\t{ value: 'false', label: t('nextcloud-vue', 'No') },\n\t\t\t]\n\t\t},\n\n\t\tpanelStyle() {\n\t\t\tif (!this.teleport || !this.anchorRect) {\n\t\t\t\treturn {}\n\t\t\t}\n\t\t\tconst width = 280\n\t\t\tconst viewport = typeof window !== 'undefined' ? window.innerWidth : 1024\n\t\t\tconst left = Math.max(8, Math.min(this.anchorRect.left, viewport - width - 8))\n\t\t\treturn { position: 'fixed', top: `${this.anchorRect.bottom + 4}px`, left: `${left}px`, width: `${width}px` }\n\t\t},\n\n\t\tsearchLabel() {\n\t\t\treturn t('nextcloud-vue', 'Search')\n\t\t},\n\n\t\tloadingLabel() {\n\t\t\treturn t('nextcloud-vue', 'Loading…')\n\t\t},\n\n\t\tnoOptionsLabel() {\n\t\t\treturn t('nextcloud-vue', 'Nothing to choose from here.')\n\t\t},\n\n\t\tfromLabel() {\n\t\t\treturn t('nextcloud-vue', 'From')\n\t\t},\n\n\t\ttoLabel() {\n\t\t\treturn t('nextcloud-vue', 'To')\n\t\t},\n\n\t\tequalsLabel() {\n\t\t\treturn t('nextcloud-vue', 'Equals')\n\t\t},\n\n\t\tclearLabel() {\n\t\t\treturn t('nextcloud-vue', 'Clear')\n\t\t},\n\n\t\tapplyLabel() {\n\t\t\treturn t('nextcloud-vue', 'Apply')\n\t\t},\n\t},\n\n\tmounted() {\n\t\tdocument.addEventListener('mousedown', this.onOutsideMouseDown, true)\n\t\tif (this.def.kind === 'reference') {\n\t\t\tthis.loadReferenceOptions('')\n\t\t}\n\t\tthis.$nextTick(() => {\n\t\t\tconst first = this.$refs.panel && this.$refs.panel.querySelector('input, button')\n\t\t\tif (first && typeof first.focus === 'function') {\n\t\t\t\tfirst.focus()\n\t\t\t}\n\t\t})\n\t},\n\n\tbeforeUnmount() {\n\t\tdocument.removeEventListener('mousedown', this.onOutsideMouseDown, true)\n\t\tclearTimeout(this.searchTimer)\n\t},\n\n\tmethods: {\n\t\ttoggleValue(value) {\n\t\t\tthis.draft.values = this.draft.values.includes(value)\n\t\t\t\t? this.draft.values.filter((v) => v !== value)\n\t\t\t\t: [...this.draft.values, value]\n\t\t},\n\n\t\t/**\n\t\t * The state this panel applies, in the shape `columnFilterParams` reads.\n\t\t *\n\t\t * @return {object}\n\t\t */\n\t\tdraftState() {\n\t\t\tif (this.def.kind === 'enum' || this.def.kind === 'reference') {\n\t\t\t\treturn { values: [...this.draft.values] }\n\t\t\t}\n\t\t\tif (this.def.kind === 'number' || this.def.kind === 'date') {\n\t\t\t\treturn { from: this.draft.from, to: this.draft.to }\n\t\t\t}\n\t\t\treturn { value: this.draft.value }\n\t\t},\n\n\t\tapply() {\n\t\t\t/**\n\t\t\t * @event apply The person applied the filter.\n\t\t\t * @type {object} The column filter state.\n\t\t\t */\n\t\t\tthis.$emit('apply', this.draftState())\n\t\t},\n\n\t\tclear() {\n\t\t\tthis.$emit('apply', this.def.kind === 'enum' || this.def.kind === 'reference'\n\t\t\t\t? { values: [] }\n\t\t\t\t: (this.def.kind === 'number' || this.def.kind === 'date') ? { from: '', to: '' } : { value: '' })\n\t\t},\n\n\t\tclose() {\n\t\t\t/**\n\t\t\t * @event close The panel should close without applying.\n\t\t\t */\n\t\t\tthis.$emit('close')\n\t\t},\n\n\t\tonEnter(event) {\n\t\t\t// Enter in a text, number or date box applies, like a form submit.\n\t\t\t// On a checkbox or a button it keeps its own meaning.\n\t\t\tconst target = event && event.target\n\t\t\tif (target && target.tagName === 'INPUT' && ['text', 'number', 'date', 'search'].includes(target.type)) {\n\t\t\t\tevent.preventDefault()\n\t\t\t\tthis.apply()\n\t\t\t}\n\t\t},\n\n\t\tonOutsideMouseDown(event) {\n\t\t\tconst panel = this.$refs.panel\n\t\t\tif (panel && event && event.target && !panel.contains(event.target)) {\n\t\t\t\tthis.close()\n\t\t\t}\n\t\t},\n\n\t\tonSearchInput() {\n\t\t\tclearTimeout(this.searchTimer)\n\t\t\tthis.searchTimer = setTimeout(() => this.loadReferenceOptions(this.query), 250)\n\t\t},\n\n\t\t/**\n\t\t * Search the referenced objects. The value is the object's uuid,\n\t\t * because that is what the server filters a reference on.\n\t\t *\n\t\t * @param {string} search The search term.\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync loadReferenceOptions(search) {\n\t\t\tconst ref = this.def.reference || {}\n\t\t\tconst register = ref.register || this.register\n\t\t\tif (!register || !ref.schema) {\n\t\t\t\tthis.referenceError = t('nextcloud-vue', 'This column cannot list its objects.')\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.referenceLoading = true\n\t\t\tthis.referenceError = ''\n\t\t\ttry {\n\t\t\t\tconst [{ default: axios }, { generateUrl }] = await Promise.all([\n\t\t\t\t\timport('@nextcloud/axios'),\n\t\t\t\t\timport('@nextcloud/router'),\n\t\t\t\t])\n\t\t\t\tconst url = generateUrl('/apps/openregister/api/objects/{register}/{schema}', {\n\t\t\t\t\tregister,\n\t\t\t\t\tschema: String(ref.schema),\n\t\t\t\t})\n\t\t\t\tconst params = { _limit: 50 }\n\t\t\t\tif (search) {\n\t\t\t\t\tparams._search = search\n\t\t\t\t}\n\t\t\t\tconst response = await axios.get(url, { params })\n\t\t\t\tconst rows = (response && response.data && (response.data.results || response.data)) || []\n\t\t\t\tconst list = Array.isArray(rows) ? rows : []\n\t\t\t\tconst options = list\n\t\t\t\t\t.map((row) => {\n\t\t\t\t\t\tconst self = (row && row['@self']) || {}\n\t\t\t\t\t\tconst value = String(self.id || self.uuid || row.id || row.uuid || '')\n\t\t\t\t\t\tconst label = String((ref.labelField && row[ref.labelField]) || row.name || row.title || self.name || value)\n\t\t\t\t\t\treturn { value, label }\n\t\t\t\t\t})\n\t\t\t\t\t.filter((o) => o.value !== '')\n\t\t\t\tthis.referenceOptions = options\n\t\t\t\tthis.referenceLabels = { ...this.referenceLabels, ...Object.fromEntries(options.map((o) => [o.value, o.label])) }\n\t\t\t} catch {\n\t\t\t\tthis.referenceOptions = []\n\t\t\t\tthis.referenceError = t('nextcloud-vue', 'The list could not load.')\n\t\t\t} finally {\n\t\t\t\tthis.referenceLoading = false\n\t\t\t}\n\t\t},\n\t},\n}\n</script>\n\n<style scoped>\n.cn-column-filter {\n\tz-index: 10000;\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 8px;\n\tbox-sizing: border-box;\n\tmax-height: 60vh;\n\toverflow-y: auto;\n\tpadding: 12px;\n\tbackground: var(--color-main-background);\n\tcolor: var(--color-main-text);\n\tborder: 1px solid var(--color-border-dark);\n\tborder-radius: var(--border-radius-large, 8px);\n\tbox-shadow: 0 2px 8px var(--color-box-shadow);\n\tfont-weight: normal;\n\ttext-align: start;\n}\n\n.cn-column-filter__heading {\n\tmargin: 0;\n\tfont-weight: bold;\n}\n\n.cn-column-filter__options {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 4px;\n\tmargin: 0;\n\tpadding: 0;\n\tborder: none;\n}\n\n.cn-column-filter__option {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 8px;\n\tmin-height: 32px;\n\tcursor: pointer;\n}\n\n.cn-column-filter__range {\n\tdisplay: flex;\n\tgap: 8px;\n}\n\n.cn-column-filter__field {\n\tdisplay: flex;\n\tflex: 1 1 0;\n\tflex-direction: column;\n\tgap: 4px;\n\tmin-width: 0;\n}\n\n.cn-column-filter__label {\n\tfont-size: var(--font-size-small, 13px);\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-column-filter__input {\n\twidth: 100%;\n\tbox-sizing: border-box;\n\tmargin: 0;\n}\n\n.cn-column-filter__hint {\n\tmargin: 0;\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-column-filter__actions {\n\tdisplay: flex;\n\tjustify-content: flex-end;\n\tgap: 8px;\n}\n\n.cn-column-filter__button {\n\tmin-height: 34px;\n\tpadding: 0 12px;\n\tborder: 1px solid var(--color-border-dark);\n\tborder-radius: var(--border-radius-element, 8px);\n\tbackground: var(--color-main-background);\n\tcolor: var(--color-main-text);\n\tcursor: pointer;\n}\n\n.cn-column-filter__button--primary {\n\tborder-color: var(--color-primary-element);\n\tbackground: var(--color-primary-element);\n\tcolor: var(--color-primary-element-text);\n}\n\n.cn-column-filter__button:focus-visible,\n.cn-column-filter__input:focus-visible,\n.cn-column-filter__option input:focus-visible {\n\toutline: 2px solid var(--color-primary-element);\n\toutline-offset: 2px;\n}\n\n.cn-column-filter__sr-only {\n\tposition: absolute;\n\twidth: 1px;\n\theight: 1px;\n\toverflow: hidden;\n\tclip-path: inset(50%);\n\twhite-space: nowrap;\n}\n</style>\n"],"names":["t"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"CnColumnFilterPopover.vue2.js","sources":["../../../../src/components/CnDataTable/CnColumnFilterPopover.vue"],"sourcesContent":["<!-- SPDX-License-Identifier: EUPL-1.2 -->\n<!-- SPDX-FileCopyrightText: 2026 Conduction B.V. <info@conduction.nl> -->\n<template>\n\t<Teleport to=\"body\" :disabled=\"!teleport\">\n\t\t<div\n\t\t\tref=\"panel\"\n\t\t\tclass=\"cn-column-filter\"\n\t\t\trole=\"dialog\"\n\t\t\t:aria-labelledby=\"headingId\"\n\t\t\t:style=\"panelStyle\"\n\t\t\tdata-testid=\"cn-column-filter\"\n\t\t\t@keydown.esc.stop.prevent=\"close\"\n\t\t\t@keydown.enter=\"onEnter\">\n\t\t\t<p :id=\"headingId\" class=\"cn-column-filter__heading\">\n\t\t\t\t{{ headingText }}\n\t\t\t</p>\n\n\t\t\t<!-- enum and reference: a checkbox list of real inputs -->\n\t\t\t<template v-if=\"def.kind === 'enum' || def.kind === 'reference'\">\n\t\t\t\t<label v-if=\"def.kind === 'reference'\" class=\"cn-column-filter__field\">\n\t\t\t\t\t<span class=\"cn-column-filter__label\">{{ searchLabel }}</span>\n\t\t\t\t\t<input\n\t\t\t\t\t\tv-model=\"query\"\n\t\t\t\t\t\tclass=\"cn-column-filter__input\"\n\t\t\t\t\t\ttype=\"search\"\n\t\t\t\t\t\tdata-testid=\"cn-column-filter-search\"\n\t\t\t\t\t\t@input=\"onSearchInput\">\n\t\t\t\t</label>\n\t\t\t\t<p v-if=\"def.kind === 'reference' && referenceLoading\" class=\"cn-column-filter__hint\" role=\"status\">\n\t\t\t\t\t{{ loadingLabel }}\n\t\t\t\t</p>\n\t\t\t\t<p v-else-if=\"def.kind === 'reference' && referenceError\" class=\"cn-column-filter__hint\" role=\"status\">\n\t\t\t\t\t{{ referenceError }}\n\t\t\t\t</p>\n\t\t\t\t<fieldset class=\"cn-column-filter__options\">\n\t\t\t\t\t<legend class=\"cn-column-filter__sr-only\">\n\t\t\t\t\t\t{{ headingText }}\n\t\t\t\t\t</legend>\n\t\t\t\t\t<label\n\t\t\t\t\t\tv-for=\"option in listOptions\"\n\t\t\t\t\t\t:key=\"option.value\"\n\t\t\t\t\t\tclass=\"cn-column-filter__option\">\n\t\t\t\t\t\t<input\n\t\t\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\t\t\t:value=\"option.value\"\n\t\t\t\t\t\t\t:checked=\"draft.values.includes(option.value)\"\n\t\t\t\t\t\t\tdata-testid=\"cn-column-filter-option\"\n\t\t\t\t\t\t\t@change=\"toggleValue(option.value)\">\n\t\t\t\t\t\t<span>{{ option.label }}</span>\n\t\t\t\t\t</label>\n\t\t\t\t\t<p v-if=\"listOptions.length === 0 && !referenceLoading\" class=\"cn-column-filter__hint\">\n\t\t\t\t\t\t{{ noOptionsLabel }}\n\t\t\t\t\t</p>\n\t\t\t\t</fieldset>\n\t\t\t</template>\n\n\t\t\t<!-- boolean: yes, no, any -->\n\t\t\t<fieldset v-else-if=\"def.kind === 'boolean'\" class=\"cn-column-filter__options\">\n\t\t\t\t<legend class=\"cn-column-filter__sr-only\">\n\t\t\t\t\t{{ headingText }}\n\t\t\t\t</legend>\n\t\t\t\t<label v-for=\"option in booleanOptions\" :key=\"option.value\" class=\"cn-column-filter__option\">\n\t\t\t\t\t<input\n\t\t\t\t\t\ttype=\"radio\"\n\t\t\t\t\t\t:name=\"headingId + '-bool'\"\n\t\t\t\t\t\t:value=\"option.value\"\n\t\t\t\t\t\t:checked=\"draft.value === option.value\"\n\t\t\t\t\t\tdata-testid=\"cn-column-filter-option\"\n\t\t\t\t\t\t@change=\"draft.value = option.value\">\n\t\t\t\t\t<span>{{ option.label }}</span>\n\t\t\t\t</label>\n\t\t\t</fieldset>\n\n\t\t\t<!-- number and date: from and to -->\n\t\t\t<div v-else-if=\"def.kind === 'number' || def.kind === 'date'\" class=\"cn-column-filter__range\">\n\t\t\t\t<label class=\"cn-column-filter__field\">\n\t\t\t\t\t<span class=\"cn-column-filter__label\">{{ fromLabel }}</span>\n\t\t\t\t\t<input\n\t\t\t\t\t\tv-model=\"draft.from\"\n\t\t\t\t\t\tclass=\"cn-column-filter__input\"\n\t\t\t\t\t\t:type=\"def.kind === 'date' ? 'date' : 'number'\"\n\t\t\t\t\t\tdata-testid=\"cn-column-filter-from\">\n\t\t\t\t</label>\n\t\t\t\t<label class=\"cn-column-filter__field\">\n\t\t\t\t\t<span class=\"cn-column-filter__label\">{{ toLabel }}</span>\n\t\t\t\t\t<input\n\t\t\t\t\t\tv-model=\"draft.to\"\n\t\t\t\t\t\tclass=\"cn-column-filter__input\"\n\t\t\t\t\t\t:type=\"def.kind === 'date' ? 'date' : 'number'\"\n\t\t\t\t\t\tdata-testid=\"cn-column-filter-to\">\n\t\t\t\t</label>\n\t\t\t</div>\n\n\t\t\t<!-- string: contains (OpenRegister `[like]`, case-insensitive) -->\n\t\t\t<label v-else class=\"cn-column-filter__field\">\n\t\t\t\t<span class=\"cn-column-filter__label\">{{ containsLabel }}</span>\n\t\t\t\t<input\n\t\t\t\t\tv-model=\"draft.value\"\n\t\t\t\t\tclass=\"cn-column-filter__input\"\n\t\t\t\t\ttype=\"text\"\n\t\t\t\t\tdata-testid=\"cn-column-filter-text\">\n\t\t\t</label>\n\n\t\t\t<div class=\"cn-column-filter__actions\">\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"cn-column-filter__button\"\n\t\t\t\t\tdata-testid=\"cn-column-filter-clear\"\n\t\t\t\t\t@click=\"clear\">\n\t\t\t\t\t{{ clearLabel }}\n\t\t\t\t</button>\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"cn-column-filter__button cn-column-filter__button--primary\"\n\t\t\t\t\tdata-testid=\"cn-column-filter-apply\"\n\t\t\t\t\t@click=\"apply\">\n\t\t\t\t\t{{ applyLabel }}\n\t\t\t\t</button>\n\t\t\t</div>\n\t\t</div>\n\t</Teleport>\n</template>\n\n<script>\nimport { translate as t } from '@nextcloud/l10n'\n\nlet popoverSeq = 0\n\n/**\n * CnColumnFilterPopover — the small panel a table header's filter button opens.\n *\n * Renders the control that fits the column: a checkbox list for an enum, yes,\n * no or any for a boolean, from and to for a number or a date, a searchable\n * list of referenced objects for a reference, and a contains box for text.\n * Real inputs throughout, so every control works from the keyboard. Escape\n * closes it and the host returns focus to the filter button.\n *\n * Internal to CnDataTable. It emits a state object; CnDataTable turns that\n * into query parameters with `columnFilterParams`.\n *\n * @spec openspec/changes/table-header-sort-and-filter/specs/cn-data-table/spec.md#requirement-every-backed-column-filters-from-its-header\n */\nexport default {\n\tname: 'CnColumnFilterPopover',\n\n\tprops: {\n\t\t/** The filter definition from `columnFilterDef`. */\n\t\tdef: {\n\t\t\ttype: Object,\n\t\t\trequired: true,\n\t\t},\n\n\t\t/** The column's current state from `columnFilterState`. */\n\t\tstate: {\n\t\t\ttype: Object,\n\t\t\tdefault: () => ({}),\n\t\t},\n\n\t\t/** The translated column label. */\n\t\tlabel: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** The filter button's bounding rect, to place the panel under it. */\n\t\tanchorRect: {\n\t\t\ttype: Object,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/** Register slug a reference column's objects live in, when the column names none. */\n\t\tregister: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** Render into `<body>`, so a scrolling table cannot clip the panel. */\n\t\tteleport: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: true,\n\t\t},\n\t},\n\n\temits: ['apply', 'close'],\n\n\tdata() {\n\t\tpopoverSeq += 1\n\t\tconst s = this.state || {}\n\t\treturn {\n\t\t\theadingId: 'cn-column-filter-' + popoverSeq,\n\t\t\tdraft: {\n\t\t\t\tvalues: Array.isArray(s.values) ? [...s.values] : [],\n\t\t\t\tvalue: s.value !== undefined && s.value !== null ? String(s.value) : '',\n\t\t\t\tfrom: s.from || '',\n\t\t\t\tto: s.to || '',\n\t\t\t},\n\n\t\t\tquery: '',\n\t\t\treferenceOptions: [],\n\t\t\treferenceLabels: {},\n\t\t\treferenceLoading: false,\n\t\t\treferenceError: '',\n\t\t\tsearchTimer: null,\n\t\t}\n\t},\n\n\tcomputed: {\n\t\theadingText() {\n\t\t\treturn t('nextcloud-vue', 'Filter {column}', { column: this.label })\n\t\t},\n\n\t\t/**\n\t\t * The options a list filter shows. For a reference, the search results\n\t\t * plus any picked object that is not among them, so a selection never\n\t\t * disappears from view.\n\t\t *\n\t\t * @return {Array<{value: string, label: string}>}\n\t\t */\n\t\tlistOptions() {\n\t\t\tif (this.def.kind !== 'reference') {\n\t\t\t\treturn this.def.options || []\n\t\t\t}\n\t\t\tconst shown = new Set(this.referenceOptions.map((o) => o.value))\n\t\t\tconst picked = this.draft.values\n\t\t\t\t.filter((v) => !shown.has(v))\n\t\t\t\t.map((v) => ({ value: v, label: this.referenceLabels[v] || v }))\n\t\t\treturn [...picked, ...this.referenceOptions]\n\t\t},\n\n\t\tbooleanOptions() {\n\t\t\treturn [\n\t\t\t\t{ value: '', label: t('nextcloud-vue', 'Any') },\n\t\t\t\t{ value: 'true', label: t('nextcloud-vue', 'Yes') },\n\t\t\t\t{ value: 'false', label: t('nextcloud-vue', 'No') },\n\t\t\t]\n\t\t},\n\n\t\tpanelStyle() {\n\t\t\tif (!this.teleport || !this.anchorRect) {\n\t\t\t\treturn {}\n\t\t\t}\n\t\t\tconst width = 280\n\t\t\tconst viewport = typeof window !== 'undefined' ? window.innerWidth : 1024\n\t\t\tconst left = Math.max(8, Math.min(this.anchorRect.left, viewport - width - 8))\n\t\t\treturn { position: 'fixed', top: `${this.anchorRect.bottom + 4}px`, left: `${left}px`, width: `${width}px` }\n\t\t},\n\n\t\tsearchLabel() {\n\t\t\treturn t('nextcloud-vue', 'Search')\n\t\t},\n\n\t\tloadingLabel() {\n\t\t\treturn t('nextcloud-vue', 'Loading…')\n\t\t},\n\n\t\tnoOptionsLabel() {\n\t\t\treturn t('nextcloud-vue', 'Nothing to choose from here.')\n\t\t},\n\n\t\tfromLabel() {\n\t\t\treturn t('nextcloud-vue', 'From')\n\t\t},\n\n\t\ttoLabel() {\n\t\t\treturn t('nextcloud-vue', 'To')\n\t\t},\n\n\t\t/**\n\t\t * Label of the text box: the text filter matches on contains.\n\t\t *\n\t\t * @return {string}\n\t\t * @spec openspec/changes/header-filter-contains/specs/cn-data-table/spec.md#requirement-a-text-header-filter-matches-on-contains\n\t\t */\n\t\tcontainsLabel() {\n\t\t\treturn t('nextcloud-vue', 'Contains')\n\t\t},\n\n\t\tclearLabel() {\n\t\t\treturn t('nextcloud-vue', 'Clear')\n\t\t},\n\n\t\tapplyLabel() {\n\t\t\treturn t('nextcloud-vue', 'Apply')\n\t\t},\n\t},\n\n\tmounted() {\n\t\tdocument.addEventListener('mousedown', this.onOutsideMouseDown, true)\n\t\tif (this.def.kind === 'reference') {\n\t\t\tthis.loadReferenceOptions('')\n\t\t}\n\t\tthis.$nextTick(() => {\n\t\t\tconst first = this.$refs.panel && this.$refs.panel.querySelector('input, button')\n\t\t\tif (first && typeof first.focus === 'function') {\n\t\t\t\tfirst.focus()\n\t\t\t}\n\t\t})\n\t},\n\n\tbeforeUnmount() {\n\t\tdocument.removeEventListener('mousedown', this.onOutsideMouseDown, true)\n\t\tclearTimeout(this.searchTimer)\n\t},\n\n\tmethods: {\n\t\ttoggleValue(value) {\n\t\t\tthis.draft.values = this.draft.values.includes(value)\n\t\t\t\t? this.draft.values.filter((v) => v !== value)\n\t\t\t\t: [...this.draft.values, value]\n\t\t},\n\n\t\t/**\n\t\t * The state this panel applies, in the shape `columnFilterParams` reads.\n\t\t *\n\t\t * @return {object}\n\t\t */\n\t\tdraftState() {\n\t\t\tif (this.def.kind === 'enum' || this.def.kind === 'reference') {\n\t\t\t\treturn { values: [...this.draft.values] }\n\t\t\t}\n\t\t\tif (this.def.kind === 'number' || this.def.kind === 'date') {\n\t\t\t\treturn { from: this.draft.from, to: this.draft.to }\n\t\t\t}\n\t\t\treturn { value: this.draft.value }\n\t\t},\n\n\t\tapply() {\n\t\t\t/**\n\t\t\t * @event apply The person applied the filter.\n\t\t\t * @type {object} The column filter state.\n\t\t\t */\n\t\t\tthis.$emit('apply', this.draftState())\n\t\t},\n\n\t\tclear() {\n\t\t\tthis.$emit('apply', this.def.kind === 'enum' || this.def.kind === 'reference'\n\t\t\t\t? { values: [] }\n\t\t\t\t: (this.def.kind === 'number' || this.def.kind === 'date') ? { from: '', to: '' } : { value: '' })\n\t\t},\n\n\t\tclose() {\n\t\t\t/**\n\t\t\t * @event close The panel should close without applying.\n\t\t\t */\n\t\t\tthis.$emit('close')\n\t\t},\n\n\t\tonEnter(event) {\n\t\t\t// Enter in a text, number or date box applies, like a form submit.\n\t\t\t// On a checkbox or a button it keeps its own meaning.\n\t\t\tconst target = event && event.target\n\t\t\tif (target && target.tagName === 'INPUT' && ['text', 'number', 'date', 'search'].includes(target.type)) {\n\t\t\t\tevent.preventDefault()\n\t\t\t\tthis.apply()\n\t\t\t}\n\t\t},\n\n\t\tonOutsideMouseDown(event) {\n\t\t\tconst panel = this.$refs.panel\n\t\t\tif (panel && event && event.target && !panel.contains(event.target)) {\n\t\t\t\tthis.close()\n\t\t\t}\n\t\t},\n\n\t\tonSearchInput() {\n\t\t\tclearTimeout(this.searchTimer)\n\t\t\tthis.searchTimer = setTimeout(() => this.loadReferenceOptions(this.query), 250)\n\t\t},\n\n\t\t/**\n\t\t * Search the referenced objects. The value is the object's uuid,\n\t\t * because that is what the server filters a reference on.\n\t\t *\n\t\t * @param {string} search The search term.\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync loadReferenceOptions(search) {\n\t\t\tconst ref = this.def.reference || {}\n\t\t\tconst register = ref.register || this.register\n\t\t\tif (!register || !ref.schema) {\n\t\t\t\tthis.referenceError = t('nextcloud-vue', 'This column cannot list its objects.')\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.referenceLoading = true\n\t\t\tthis.referenceError = ''\n\t\t\ttry {\n\t\t\t\tconst [{ default: axios }, { generateUrl }] = await Promise.all([\n\t\t\t\t\timport('@nextcloud/axios'),\n\t\t\t\t\timport('@nextcloud/router'),\n\t\t\t\t])\n\t\t\t\tconst url = generateUrl('/apps/openregister/api/objects/{register}/{schema}', {\n\t\t\t\t\tregister,\n\t\t\t\t\tschema: String(ref.schema),\n\t\t\t\t})\n\t\t\t\tconst params = { _limit: 50 }\n\t\t\t\tif (search) {\n\t\t\t\t\tparams._search = search\n\t\t\t\t}\n\t\t\t\tconst response = await axios.get(url, { params })\n\t\t\t\tconst rows = (response && response.data && (response.data.results || response.data)) || []\n\t\t\t\tconst list = Array.isArray(rows) ? rows : []\n\t\t\t\tconst options = list\n\t\t\t\t\t.map((row) => {\n\t\t\t\t\t\tconst self = (row && row['@self']) || {}\n\t\t\t\t\t\tconst value = String(self.id || self.uuid || row.id || row.uuid || '')\n\t\t\t\t\t\tconst label = String((ref.labelField && row[ref.labelField]) || row.name || row.title || self.name || value)\n\t\t\t\t\t\treturn { value, label }\n\t\t\t\t\t})\n\t\t\t\t\t.filter((o) => o.value !== '')\n\t\t\t\tthis.referenceOptions = options\n\t\t\t\tthis.referenceLabels = { ...this.referenceLabels, ...Object.fromEntries(options.map((o) => [o.value, o.label])) }\n\t\t\t} catch {\n\t\t\t\tthis.referenceOptions = []\n\t\t\t\tthis.referenceError = t('nextcloud-vue', 'The list could not load.')\n\t\t\t} finally {\n\t\t\t\tthis.referenceLoading = false\n\t\t\t}\n\t\t},\n\t},\n}\n</script>\n\n<style scoped>\n.cn-column-filter {\n\tz-index: 10000;\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 8px;\n\tbox-sizing: border-box;\n\tmax-height: 60vh;\n\toverflow-y: auto;\n\tpadding: 12px;\n\tbackground: var(--color-main-background);\n\tcolor: var(--color-main-text);\n\tborder: 1px solid var(--color-border-dark);\n\tborder-radius: var(--border-radius-large, 8px);\n\tbox-shadow: 0 2px 8px var(--color-box-shadow);\n\tfont-weight: normal;\n\ttext-align: start;\n}\n\n.cn-column-filter__heading {\n\tmargin: 0;\n\tfont-weight: bold;\n}\n\n.cn-column-filter__options {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 4px;\n\tmargin: 0;\n\tpadding: 0;\n\tborder: none;\n}\n\n.cn-column-filter__option {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 8px;\n\tmin-height: 32px;\n\tcursor: pointer;\n}\n\n.cn-column-filter__range {\n\tdisplay: flex;\n\tgap: 8px;\n}\n\n.cn-column-filter__field {\n\tdisplay: flex;\n\tflex: 1 1 0;\n\tflex-direction: column;\n\tgap: 4px;\n\tmin-width: 0;\n}\n\n.cn-column-filter__label {\n\tfont-size: var(--font-size-small, 13px);\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-column-filter__input {\n\twidth: 100%;\n\tbox-sizing: border-box;\n\tmargin: 0;\n}\n\n.cn-column-filter__hint {\n\tmargin: 0;\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-column-filter__actions {\n\tdisplay: flex;\n\tjustify-content: flex-end;\n\tgap: 8px;\n}\n\n.cn-column-filter__button {\n\tmin-height: 34px;\n\tpadding: 0 12px;\n\tborder: 1px solid var(--color-border-dark);\n\tborder-radius: var(--border-radius-element, 8px);\n\tbackground: var(--color-main-background);\n\tcolor: var(--color-main-text);\n\tcursor: pointer;\n}\n\n.cn-column-filter__button--primary {\n\tborder-color: var(--color-primary-element);\n\tbackground: var(--color-primary-element);\n\tcolor: var(--color-primary-element-text);\n}\n\n.cn-column-filter__button:focus-visible,\n.cn-column-filter__input:focus-visible,\n.cn-column-filter__option input:focus-visible {\n\toutline: 2px solid var(--color-primary-element);\n\toutline-offset: 2px;\n}\n\n.cn-column-filter__sr-only {\n\tposition: absolute;\n\twidth: 1px;\n\theight: 1px;\n\toverflow: hidden;\n\tclip-path: inset(50%);\n\twhite-space: nowrap;\n}\n</style>\n"],"names":["t"],"mappings":"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"}
|
|
@@ -157,7 +157,7 @@ function render(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
157
157
|
])
|
|
158
158
|
]))
|
|
159
159
|
: (openBlock(), createElementBlock("label", _hoisted_21, [
|
|
160
|
-
createElementVNode("span", _hoisted_22, toDisplayString($options.
|
|
160
|
+
createElementVNode("span", _hoisted_22, toDisplayString($options.containsLabel), 1 /* TEXT */),
|
|
161
161
|
withDirectives(createElementVNode("input", {
|
|
162
162
|
"onUpdate:modelValue": _cache[4] || (_cache[4] = $event => (($data.draft.value) = $event)),
|
|
163
163
|
class: "cn-column-filter__input",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CnColumnFilterPopover.vue3.js","sources":["../../../../src/components/CnDataTable/CnColumnFilterPopover.vue?vue&type=template&id=2cb54356&lang.js"],"sourcesContent":["<!-- SPDX-License-Identifier: EUPL-1.2 -->\n<!-- SPDX-FileCopyrightText: 2026 Conduction B.V. <info@conduction.nl> -->\n<template>\n\t<Teleport to=\"body\" :disabled=\"!teleport\">\n\t\t<div\n\t\t\tref=\"panel\"\n\t\t\tclass=\"cn-column-filter\"\n\t\t\trole=\"dialog\"\n\t\t\t:aria-labelledby=\"headingId\"\n\t\t\t:style=\"panelStyle\"\n\t\t\tdata-testid=\"cn-column-filter\"\n\t\t\t@keydown.esc.stop.prevent=\"close\"\n\t\t\t@keydown.enter=\"onEnter\">\n\t\t\t<p :id=\"headingId\" class=\"cn-column-filter__heading\">\n\t\t\t\t{{ headingText }}\n\t\t\t</p>\n\n\t\t\t<!-- enum and reference: a checkbox list of real inputs -->\n\t\t\t<template v-if=\"def.kind === 'enum' || def.kind === 'reference'\">\n\t\t\t\t<label v-if=\"def.kind === 'reference'\" class=\"cn-column-filter__field\">\n\t\t\t\t\t<span class=\"cn-column-filter__label\">{{ searchLabel }}</span>\n\t\t\t\t\t<input\n\t\t\t\t\t\tv-model=\"query\"\n\t\t\t\t\t\tclass=\"cn-column-filter__input\"\n\t\t\t\t\t\ttype=\"search\"\n\t\t\t\t\t\tdata-testid=\"cn-column-filter-search\"\n\t\t\t\t\t\t@input=\"onSearchInput\">\n\t\t\t\t</label>\n\t\t\t\t<p v-if=\"def.kind === 'reference' && referenceLoading\" class=\"cn-column-filter__hint\" role=\"status\">\n\t\t\t\t\t{{ loadingLabel }}\n\t\t\t\t</p>\n\t\t\t\t<p v-else-if=\"def.kind === 'reference' && referenceError\" class=\"cn-column-filter__hint\" role=\"status\">\n\t\t\t\t\t{{ referenceError }}\n\t\t\t\t</p>\n\t\t\t\t<fieldset class=\"cn-column-filter__options\">\n\t\t\t\t\t<legend class=\"cn-column-filter__sr-only\">\n\t\t\t\t\t\t{{ headingText }}\n\t\t\t\t\t</legend>\n\t\t\t\t\t<label\n\t\t\t\t\t\tv-for=\"option in listOptions\"\n\t\t\t\t\t\t:key=\"option.value\"\n\t\t\t\t\t\tclass=\"cn-column-filter__option\">\n\t\t\t\t\t\t<input\n\t\t\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\t\t\t:value=\"option.value\"\n\t\t\t\t\t\t\t:checked=\"draft.values.includes(option.value)\"\n\t\t\t\t\t\t\tdata-testid=\"cn-column-filter-option\"\n\t\t\t\t\t\t\t@change=\"toggleValue(option.value)\">\n\t\t\t\t\t\t<span>{{ option.label }}</span>\n\t\t\t\t\t</label>\n\t\t\t\t\t<p v-if=\"listOptions.length === 0 && !referenceLoading\" class=\"cn-column-filter__hint\">\n\t\t\t\t\t\t{{ noOptionsLabel }}\n\t\t\t\t\t</p>\n\t\t\t\t</fieldset>\n\t\t\t</template>\n\n\t\t\t<!-- boolean: yes, no, any -->\n\t\t\t<fieldset v-else-if=\"def.kind === 'boolean'\" class=\"cn-column-filter__options\">\n\t\t\t\t<legend class=\"cn-column-filter__sr-only\">\n\t\t\t\t\t{{ headingText }}\n\t\t\t\t</legend>\n\t\t\t\t<label v-for=\"option in booleanOptions\" :key=\"option.value\" class=\"cn-column-filter__option\">\n\t\t\t\t\t<input\n\t\t\t\t\t\ttype=\"radio\"\n\t\t\t\t\t\t:name=\"headingId + '-bool'\"\n\t\t\t\t\t\t:value=\"option.value\"\n\t\t\t\t\t\t:checked=\"draft.value === option.value\"\n\t\t\t\t\t\tdata-testid=\"cn-column-filter-option\"\n\t\t\t\t\t\t@change=\"draft.value = option.value\">\n\t\t\t\t\t<span>{{ option.label }}</span>\n\t\t\t\t</label>\n\t\t\t</fieldset>\n\n\t\t\t<!-- number and date: from and to -->\n\t\t\t<div v-else-if=\"def.kind === 'number' || def.kind === 'date'\" class=\"cn-column-filter__range\">\n\t\t\t\t<label class=\"cn-column-filter__field\">\n\t\t\t\t\t<span class=\"cn-column-filter__label\">{{ fromLabel }}</span>\n\t\t\t\t\t<input\n\t\t\t\t\t\tv-model=\"draft.from\"\n\t\t\t\t\t\tclass=\"cn-column-filter__input\"\n\t\t\t\t\t\t:type=\"def.kind === 'date' ? 'date' : 'number'\"\n\t\t\t\t\t\tdata-testid=\"cn-column-filter-from\">\n\t\t\t\t</label>\n\t\t\t\t<label class=\"cn-column-filter__field\">\n\t\t\t\t\t<span class=\"cn-column-filter__label\">{{ toLabel }}</span>\n\t\t\t\t\t<input\n\t\t\t\t\t\tv-model=\"draft.to\"\n\t\t\t\t\t\tclass=\"cn-column-filter__input\"\n\t\t\t\t\t\t:type=\"def.kind === 'date' ? 'date' : 'number'\"\n\t\t\t\t\t\tdata-testid=\"cn-column-filter-to\">\n\t\t\t\t</label>\n\t\t\t</div>\n\n\t\t\t<!-- string: equals -->\n\t\t\t<label v-else class=\"cn-column-filter__field\">\n\t\t\t\t<span class=\"cn-column-filter__label\">{{ equalsLabel }}</span>\n\t\t\t\t<input\n\t\t\t\t\tv-model=\"draft.value\"\n\t\t\t\t\tclass=\"cn-column-filter__input\"\n\t\t\t\t\ttype=\"text\"\n\t\t\t\t\tdata-testid=\"cn-column-filter-text\">\n\t\t\t</label>\n\n\t\t\t<div class=\"cn-column-filter__actions\">\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"cn-column-filter__button\"\n\t\t\t\t\tdata-testid=\"cn-column-filter-clear\"\n\t\t\t\t\t@click=\"clear\">\n\t\t\t\t\t{{ clearLabel }}\n\t\t\t\t</button>\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"cn-column-filter__button cn-column-filter__button--primary\"\n\t\t\t\t\tdata-testid=\"cn-column-filter-apply\"\n\t\t\t\t\t@click=\"apply\">\n\t\t\t\t\t{{ applyLabel }}\n\t\t\t\t</button>\n\t\t\t</div>\n\t\t</div>\n\t</Teleport>\n</template>\n\n<script>\nimport { translate as t } from '@nextcloud/l10n'\n\nlet popoverSeq = 0\n\n/**\n * CnColumnFilterPopover — the small panel a table header's filter button opens.\n *\n * Renders the control that fits the column: a checkbox list for an enum, yes,\n * no or any for a boolean, from and to for a number or a date, a searchable\n * list of referenced objects for a reference, and an equals box for text.\n * Real inputs throughout, so every control works from the keyboard. Escape\n * closes it and the host returns focus to the filter button.\n *\n * Internal to CnDataTable. It emits a state object; CnDataTable turns that\n * into query parameters with `columnFilterParams`.\n *\n * @spec openspec/changes/table-header-sort-and-filter/specs/cn-data-table/spec.md#requirement-every-backed-column-filters-from-its-header\n */\nexport default {\n\tname: 'CnColumnFilterPopover',\n\n\tprops: {\n\t\t/** The filter definition from `columnFilterDef`. */\n\t\tdef: {\n\t\t\ttype: Object,\n\t\t\trequired: true,\n\t\t},\n\n\t\t/** The column's current state from `columnFilterState`. */\n\t\tstate: {\n\t\t\ttype: Object,\n\t\t\tdefault: () => ({}),\n\t\t},\n\n\t\t/** The translated column label. */\n\t\tlabel: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** The filter button's bounding rect, to place the panel under it. */\n\t\tanchorRect: {\n\t\t\ttype: Object,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/** Register slug a reference column's objects live in, when the column names none. */\n\t\tregister: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** Render into `<body>`, so a scrolling table cannot clip the panel. */\n\t\tteleport: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: true,\n\t\t},\n\t},\n\n\temits: ['apply', 'close'],\n\n\tdata() {\n\t\tpopoverSeq += 1\n\t\tconst s = this.state || {}\n\t\treturn {\n\t\t\theadingId: 'cn-column-filter-' + popoverSeq,\n\t\t\tdraft: {\n\t\t\t\tvalues: Array.isArray(s.values) ? [...s.values] : [],\n\t\t\t\tvalue: s.value !== undefined && s.value !== null ? String(s.value) : '',\n\t\t\t\tfrom: s.from || '',\n\t\t\t\tto: s.to || '',\n\t\t\t},\n\n\t\t\tquery: '',\n\t\t\treferenceOptions: [],\n\t\t\treferenceLabels: {},\n\t\t\treferenceLoading: false,\n\t\t\treferenceError: '',\n\t\t\tsearchTimer: null,\n\t\t}\n\t},\n\n\tcomputed: {\n\t\theadingText() {\n\t\t\treturn t('nextcloud-vue', 'Filter {column}', { column: this.label })\n\t\t},\n\n\t\t/**\n\t\t * The options a list filter shows. For a reference, the search results\n\t\t * plus any picked object that is not among them, so a selection never\n\t\t * disappears from view.\n\t\t *\n\t\t * @return {Array<{value: string, label: string}>}\n\t\t */\n\t\tlistOptions() {\n\t\t\tif (this.def.kind !== 'reference') {\n\t\t\t\treturn this.def.options || []\n\t\t\t}\n\t\t\tconst shown = new Set(this.referenceOptions.map((o) => o.value))\n\t\t\tconst picked = this.draft.values\n\t\t\t\t.filter((v) => !shown.has(v))\n\t\t\t\t.map((v) => ({ value: v, label: this.referenceLabels[v] || v }))\n\t\t\treturn [...picked, ...this.referenceOptions]\n\t\t},\n\n\t\tbooleanOptions() {\n\t\t\treturn [\n\t\t\t\t{ value: '', label: t('nextcloud-vue', 'Any') },\n\t\t\t\t{ value: 'true', label: t('nextcloud-vue', 'Yes') },\n\t\t\t\t{ value: 'false', label: t('nextcloud-vue', 'No') },\n\t\t\t]\n\t\t},\n\n\t\tpanelStyle() {\n\t\t\tif (!this.teleport || !this.anchorRect) {\n\t\t\t\treturn {}\n\t\t\t}\n\t\t\tconst width = 280\n\t\t\tconst viewport = typeof window !== 'undefined' ? window.innerWidth : 1024\n\t\t\tconst left = Math.max(8, Math.min(this.anchorRect.left, viewport - width - 8))\n\t\t\treturn { position: 'fixed', top: `${this.anchorRect.bottom + 4}px`, left: `${left}px`, width: `${width}px` }\n\t\t},\n\n\t\tsearchLabel() {\n\t\t\treturn t('nextcloud-vue', 'Search')\n\t\t},\n\n\t\tloadingLabel() {\n\t\t\treturn t('nextcloud-vue', 'Loading…')\n\t\t},\n\n\t\tnoOptionsLabel() {\n\t\t\treturn t('nextcloud-vue', 'Nothing to choose from here.')\n\t\t},\n\n\t\tfromLabel() {\n\t\t\treturn t('nextcloud-vue', 'From')\n\t\t},\n\n\t\ttoLabel() {\n\t\t\treturn t('nextcloud-vue', 'To')\n\t\t},\n\n\t\tequalsLabel() {\n\t\t\treturn t('nextcloud-vue', 'Equals')\n\t\t},\n\n\t\tclearLabel() {\n\t\t\treturn t('nextcloud-vue', 'Clear')\n\t\t},\n\n\t\tapplyLabel() {\n\t\t\treturn t('nextcloud-vue', 'Apply')\n\t\t},\n\t},\n\n\tmounted() {\n\t\tdocument.addEventListener('mousedown', this.onOutsideMouseDown, true)\n\t\tif (this.def.kind === 'reference') {\n\t\t\tthis.loadReferenceOptions('')\n\t\t}\n\t\tthis.$nextTick(() => {\n\t\t\tconst first = this.$refs.panel && this.$refs.panel.querySelector('input, button')\n\t\t\tif (first && typeof first.focus === 'function') {\n\t\t\t\tfirst.focus()\n\t\t\t}\n\t\t})\n\t},\n\n\tbeforeUnmount() {\n\t\tdocument.removeEventListener('mousedown', this.onOutsideMouseDown, true)\n\t\tclearTimeout(this.searchTimer)\n\t},\n\n\tmethods: {\n\t\ttoggleValue(value) {\n\t\t\tthis.draft.values = this.draft.values.includes(value)\n\t\t\t\t? this.draft.values.filter((v) => v !== value)\n\t\t\t\t: [...this.draft.values, value]\n\t\t},\n\n\t\t/**\n\t\t * The state this panel applies, in the shape `columnFilterParams` reads.\n\t\t *\n\t\t * @return {object}\n\t\t */\n\t\tdraftState() {\n\t\t\tif (this.def.kind === 'enum' || this.def.kind === 'reference') {\n\t\t\t\treturn { values: [...this.draft.values] }\n\t\t\t}\n\t\t\tif (this.def.kind === 'number' || this.def.kind === 'date') {\n\t\t\t\treturn { from: this.draft.from, to: this.draft.to }\n\t\t\t}\n\t\t\treturn { value: this.draft.value }\n\t\t},\n\n\t\tapply() {\n\t\t\t/**\n\t\t\t * @event apply The person applied the filter.\n\t\t\t * @type {object} The column filter state.\n\t\t\t */\n\t\t\tthis.$emit('apply', this.draftState())\n\t\t},\n\n\t\tclear() {\n\t\t\tthis.$emit('apply', this.def.kind === 'enum' || this.def.kind === 'reference'\n\t\t\t\t? { values: [] }\n\t\t\t\t: (this.def.kind === 'number' || this.def.kind === 'date') ? { from: '', to: '' } : { value: '' })\n\t\t},\n\n\t\tclose() {\n\t\t\t/**\n\t\t\t * @event close The panel should close without applying.\n\t\t\t */\n\t\t\tthis.$emit('close')\n\t\t},\n\n\t\tonEnter(event) {\n\t\t\t// Enter in a text, number or date box applies, like a form submit.\n\t\t\t// On a checkbox or a button it keeps its own meaning.\n\t\t\tconst target = event && event.target\n\t\t\tif (target && target.tagName === 'INPUT' && ['text', 'number', 'date', 'search'].includes(target.type)) {\n\t\t\t\tevent.preventDefault()\n\t\t\t\tthis.apply()\n\t\t\t}\n\t\t},\n\n\t\tonOutsideMouseDown(event) {\n\t\t\tconst panel = this.$refs.panel\n\t\t\tif (panel && event && event.target && !panel.contains(event.target)) {\n\t\t\t\tthis.close()\n\t\t\t}\n\t\t},\n\n\t\tonSearchInput() {\n\t\t\tclearTimeout(this.searchTimer)\n\t\t\tthis.searchTimer = setTimeout(() => this.loadReferenceOptions(this.query), 250)\n\t\t},\n\n\t\t/**\n\t\t * Search the referenced objects. The value is the object's uuid,\n\t\t * because that is what the server filters a reference on.\n\t\t *\n\t\t * @param {string} search The search term.\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync loadReferenceOptions(search) {\n\t\t\tconst ref = this.def.reference || {}\n\t\t\tconst register = ref.register || this.register\n\t\t\tif (!register || !ref.schema) {\n\t\t\t\tthis.referenceError = t('nextcloud-vue', 'This column cannot list its objects.')\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.referenceLoading = true\n\t\t\tthis.referenceError = ''\n\t\t\ttry {\n\t\t\t\tconst [{ default: axios }, { generateUrl }] = await Promise.all([\n\t\t\t\t\timport('@nextcloud/axios'),\n\t\t\t\t\timport('@nextcloud/router'),\n\t\t\t\t])\n\t\t\t\tconst url = generateUrl('/apps/openregister/api/objects/{register}/{schema}', {\n\t\t\t\t\tregister,\n\t\t\t\t\tschema: String(ref.schema),\n\t\t\t\t})\n\t\t\t\tconst params = { _limit: 50 }\n\t\t\t\tif (search) {\n\t\t\t\t\tparams._search = search\n\t\t\t\t}\n\t\t\t\tconst response = await axios.get(url, { params })\n\t\t\t\tconst rows = (response && response.data && (response.data.results || response.data)) || []\n\t\t\t\tconst list = Array.isArray(rows) ? rows : []\n\t\t\t\tconst options = list\n\t\t\t\t\t.map((row) => {\n\t\t\t\t\t\tconst self = (row && row['@self']) || {}\n\t\t\t\t\t\tconst value = String(self.id || self.uuid || row.id || row.uuid || '')\n\t\t\t\t\t\tconst label = String((ref.labelField && row[ref.labelField]) || row.name || row.title || self.name || value)\n\t\t\t\t\t\treturn { value, label }\n\t\t\t\t\t})\n\t\t\t\t\t.filter((o) => o.value !== '')\n\t\t\t\tthis.referenceOptions = options\n\t\t\t\tthis.referenceLabels = { ...this.referenceLabels, ...Object.fromEntries(options.map((o) => [o.value, o.label])) }\n\t\t\t} catch {\n\t\t\t\tthis.referenceOptions = []\n\t\t\t\tthis.referenceError = t('nextcloud-vue', 'The list could not load.')\n\t\t\t} finally {\n\t\t\t\tthis.referenceLoading = false\n\t\t\t}\n\t\t},\n\t},\n}\n</script>\n\n<style scoped>\n.cn-column-filter {\n\tz-index: 10000;\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 8px;\n\tbox-sizing: border-box;\n\tmax-height: 60vh;\n\toverflow-y: auto;\n\tpadding: 12px;\n\tbackground: var(--color-main-background);\n\tcolor: var(--color-main-text);\n\tborder: 1px solid var(--color-border-dark);\n\tborder-radius: var(--border-radius-large, 8px);\n\tbox-shadow: 0 2px 8px var(--color-box-shadow);\n\tfont-weight: normal;\n\ttext-align: start;\n}\n\n.cn-column-filter__heading {\n\tmargin: 0;\n\tfont-weight: bold;\n}\n\n.cn-column-filter__options {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 4px;\n\tmargin: 0;\n\tpadding: 0;\n\tborder: none;\n}\n\n.cn-column-filter__option {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 8px;\n\tmin-height: 32px;\n\tcursor: pointer;\n}\n\n.cn-column-filter__range {\n\tdisplay: flex;\n\tgap: 8px;\n}\n\n.cn-column-filter__field {\n\tdisplay: flex;\n\tflex: 1 1 0;\n\tflex-direction: column;\n\tgap: 4px;\n\tmin-width: 0;\n}\n\n.cn-column-filter__label {\n\tfont-size: var(--font-size-small, 13px);\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-column-filter__input {\n\twidth: 100%;\n\tbox-sizing: border-box;\n\tmargin: 0;\n}\n\n.cn-column-filter__hint {\n\tmargin: 0;\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-column-filter__actions {\n\tdisplay: flex;\n\tjustify-content: flex-end;\n\tgap: 8px;\n}\n\n.cn-column-filter__button {\n\tmin-height: 34px;\n\tpadding: 0 12px;\n\tborder: 1px solid var(--color-border-dark);\n\tborder-radius: var(--border-radius-element, 8px);\n\tbackground: var(--color-main-background);\n\tcolor: var(--color-main-text);\n\tcursor: pointer;\n}\n\n.cn-column-filter__button--primary {\n\tborder-color: var(--color-primary-element);\n\tbackground: var(--color-primary-element);\n\tcolor: var(--color-primary-element-text);\n}\n\n.cn-column-filter__button:focus-visible,\n.cn-column-filter__input:focus-visible,\n.cn-column-filter__option input:focus-visible {\n\toutline: 2px solid var(--color-primary-element);\n\toutline-offset: 2px;\n}\n\n.cn-column-filter__sr-only {\n\tposition: absolute;\n\twidth: 1px;\n\theight: 1px;\n\toverflow: hidden;\n\tclip-path: inset(50%);\n\twhite-space: nowrap;\n}\n</style>\n"],"names":["_createElementVNode","_Fragment","_toDisplayString","_createElementBlock","_renderList","_openBlock","_vModelDynamic","_vModelText"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"CnColumnFilterPopover.vue3.js","sources":["../../../../src/components/CnDataTable/CnColumnFilterPopover.vue?vue&type=template&id=2cb54356&lang.js"],"sourcesContent":["<!-- SPDX-License-Identifier: EUPL-1.2 -->\n<!-- SPDX-FileCopyrightText: 2026 Conduction B.V. <info@conduction.nl> -->\n<template>\n\t<Teleport to=\"body\" :disabled=\"!teleport\">\n\t\t<div\n\t\t\tref=\"panel\"\n\t\t\tclass=\"cn-column-filter\"\n\t\t\trole=\"dialog\"\n\t\t\t:aria-labelledby=\"headingId\"\n\t\t\t:style=\"panelStyle\"\n\t\t\tdata-testid=\"cn-column-filter\"\n\t\t\t@keydown.esc.stop.prevent=\"close\"\n\t\t\t@keydown.enter=\"onEnter\">\n\t\t\t<p :id=\"headingId\" class=\"cn-column-filter__heading\">\n\t\t\t\t{{ headingText }}\n\t\t\t</p>\n\n\t\t\t<!-- enum and reference: a checkbox list of real inputs -->\n\t\t\t<template v-if=\"def.kind === 'enum' || def.kind === 'reference'\">\n\t\t\t\t<label v-if=\"def.kind === 'reference'\" class=\"cn-column-filter__field\">\n\t\t\t\t\t<span class=\"cn-column-filter__label\">{{ searchLabel }}</span>\n\t\t\t\t\t<input\n\t\t\t\t\t\tv-model=\"query\"\n\t\t\t\t\t\tclass=\"cn-column-filter__input\"\n\t\t\t\t\t\ttype=\"search\"\n\t\t\t\t\t\tdata-testid=\"cn-column-filter-search\"\n\t\t\t\t\t\t@input=\"onSearchInput\">\n\t\t\t\t</label>\n\t\t\t\t<p v-if=\"def.kind === 'reference' && referenceLoading\" class=\"cn-column-filter__hint\" role=\"status\">\n\t\t\t\t\t{{ loadingLabel }}\n\t\t\t\t</p>\n\t\t\t\t<p v-else-if=\"def.kind === 'reference' && referenceError\" class=\"cn-column-filter__hint\" role=\"status\">\n\t\t\t\t\t{{ referenceError }}\n\t\t\t\t</p>\n\t\t\t\t<fieldset class=\"cn-column-filter__options\">\n\t\t\t\t\t<legend class=\"cn-column-filter__sr-only\">\n\t\t\t\t\t\t{{ headingText }}\n\t\t\t\t\t</legend>\n\t\t\t\t\t<label\n\t\t\t\t\t\tv-for=\"option in listOptions\"\n\t\t\t\t\t\t:key=\"option.value\"\n\t\t\t\t\t\tclass=\"cn-column-filter__option\">\n\t\t\t\t\t\t<input\n\t\t\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\t\t\t:value=\"option.value\"\n\t\t\t\t\t\t\t:checked=\"draft.values.includes(option.value)\"\n\t\t\t\t\t\t\tdata-testid=\"cn-column-filter-option\"\n\t\t\t\t\t\t\t@change=\"toggleValue(option.value)\">\n\t\t\t\t\t\t<span>{{ option.label }}</span>\n\t\t\t\t\t</label>\n\t\t\t\t\t<p v-if=\"listOptions.length === 0 && !referenceLoading\" class=\"cn-column-filter__hint\">\n\t\t\t\t\t\t{{ noOptionsLabel }}\n\t\t\t\t\t</p>\n\t\t\t\t</fieldset>\n\t\t\t</template>\n\n\t\t\t<!-- boolean: yes, no, any -->\n\t\t\t<fieldset v-else-if=\"def.kind === 'boolean'\" class=\"cn-column-filter__options\">\n\t\t\t\t<legend class=\"cn-column-filter__sr-only\">\n\t\t\t\t\t{{ headingText }}\n\t\t\t\t</legend>\n\t\t\t\t<label v-for=\"option in booleanOptions\" :key=\"option.value\" class=\"cn-column-filter__option\">\n\t\t\t\t\t<input\n\t\t\t\t\t\ttype=\"radio\"\n\t\t\t\t\t\t:name=\"headingId + '-bool'\"\n\t\t\t\t\t\t:value=\"option.value\"\n\t\t\t\t\t\t:checked=\"draft.value === option.value\"\n\t\t\t\t\t\tdata-testid=\"cn-column-filter-option\"\n\t\t\t\t\t\t@change=\"draft.value = option.value\">\n\t\t\t\t\t<span>{{ option.label }}</span>\n\t\t\t\t</label>\n\t\t\t</fieldset>\n\n\t\t\t<!-- number and date: from and to -->\n\t\t\t<div v-else-if=\"def.kind === 'number' || def.kind === 'date'\" class=\"cn-column-filter__range\">\n\t\t\t\t<label class=\"cn-column-filter__field\">\n\t\t\t\t\t<span class=\"cn-column-filter__label\">{{ fromLabel }}</span>\n\t\t\t\t\t<input\n\t\t\t\t\t\tv-model=\"draft.from\"\n\t\t\t\t\t\tclass=\"cn-column-filter__input\"\n\t\t\t\t\t\t:type=\"def.kind === 'date' ? 'date' : 'number'\"\n\t\t\t\t\t\tdata-testid=\"cn-column-filter-from\">\n\t\t\t\t</label>\n\t\t\t\t<label class=\"cn-column-filter__field\">\n\t\t\t\t\t<span class=\"cn-column-filter__label\">{{ toLabel }}</span>\n\t\t\t\t\t<input\n\t\t\t\t\t\tv-model=\"draft.to\"\n\t\t\t\t\t\tclass=\"cn-column-filter__input\"\n\t\t\t\t\t\t:type=\"def.kind === 'date' ? 'date' : 'number'\"\n\t\t\t\t\t\tdata-testid=\"cn-column-filter-to\">\n\t\t\t\t</label>\n\t\t\t</div>\n\n\t\t\t<!-- string: contains (OpenRegister `[like]`, case-insensitive) -->\n\t\t\t<label v-else class=\"cn-column-filter__field\">\n\t\t\t\t<span class=\"cn-column-filter__label\">{{ containsLabel }}</span>\n\t\t\t\t<input\n\t\t\t\t\tv-model=\"draft.value\"\n\t\t\t\t\tclass=\"cn-column-filter__input\"\n\t\t\t\t\ttype=\"text\"\n\t\t\t\t\tdata-testid=\"cn-column-filter-text\">\n\t\t\t</label>\n\n\t\t\t<div class=\"cn-column-filter__actions\">\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"cn-column-filter__button\"\n\t\t\t\t\tdata-testid=\"cn-column-filter-clear\"\n\t\t\t\t\t@click=\"clear\">\n\t\t\t\t\t{{ clearLabel }}\n\t\t\t\t</button>\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"cn-column-filter__button cn-column-filter__button--primary\"\n\t\t\t\t\tdata-testid=\"cn-column-filter-apply\"\n\t\t\t\t\t@click=\"apply\">\n\t\t\t\t\t{{ applyLabel }}\n\t\t\t\t</button>\n\t\t\t</div>\n\t\t</div>\n\t</Teleport>\n</template>\n\n<script>\nimport { translate as t } from '@nextcloud/l10n'\n\nlet popoverSeq = 0\n\n/**\n * CnColumnFilterPopover — the small panel a table header's filter button opens.\n *\n * Renders the control that fits the column: a checkbox list for an enum, yes,\n * no or any for a boolean, from and to for a number or a date, a searchable\n * list of referenced objects for a reference, and a contains box for text.\n * Real inputs throughout, so every control works from the keyboard. Escape\n * closes it and the host returns focus to the filter button.\n *\n * Internal to CnDataTable. It emits a state object; CnDataTable turns that\n * into query parameters with `columnFilterParams`.\n *\n * @spec openspec/changes/table-header-sort-and-filter/specs/cn-data-table/spec.md#requirement-every-backed-column-filters-from-its-header\n */\nexport default {\n\tname: 'CnColumnFilterPopover',\n\n\tprops: {\n\t\t/** The filter definition from `columnFilterDef`. */\n\t\tdef: {\n\t\t\ttype: Object,\n\t\t\trequired: true,\n\t\t},\n\n\t\t/** The column's current state from `columnFilterState`. */\n\t\tstate: {\n\t\t\ttype: Object,\n\t\t\tdefault: () => ({}),\n\t\t},\n\n\t\t/** The translated column label. */\n\t\tlabel: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** The filter button's bounding rect, to place the panel under it. */\n\t\tanchorRect: {\n\t\t\ttype: Object,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/** Register slug a reference column's objects live in, when the column names none. */\n\t\tregister: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** Render into `<body>`, so a scrolling table cannot clip the panel. */\n\t\tteleport: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: true,\n\t\t},\n\t},\n\n\temits: ['apply', 'close'],\n\n\tdata() {\n\t\tpopoverSeq += 1\n\t\tconst s = this.state || {}\n\t\treturn {\n\t\t\theadingId: 'cn-column-filter-' + popoverSeq,\n\t\t\tdraft: {\n\t\t\t\tvalues: Array.isArray(s.values) ? [...s.values] : [],\n\t\t\t\tvalue: s.value !== undefined && s.value !== null ? String(s.value) : '',\n\t\t\t\tfrom: s.from || '',\n\t\t\t\tto: s.to || '',\n\t\t\t},\n\n\t\t\tquery: '',\n\t\t\treferenceOptions: [],\n\t\t\treferenceLabels: {},\n\t\t\treferenceLoading: false,\n\t\t\treferenceError: '',\n\t\t\tsearchTimer: null,\n\t\t}\n\t},\n\n\tcomputed: {\n\t\theadingText() {\n\t\t\treturn t('nextcloud-vue', 'Filter {column}', { column: this.label })\n\t\t},\n\n\t\t/**\n\t\t * The options a list filter shows. For a reference, the search results\n\t\t * plus any picked object that is not among them, so a selection never\n\t\t * disappears from view.\n\t\t *\n\t\t * @return {Array<{value: string, label: string}>}\n\t\t */\n\t\tlistOptions() {\n\t\t\tif (this.def.kind !== 'reference') {\n\t\t\t\treturn this.def.options || []\n\t\t\t}\n\t\t\tconst shown = new Set(this.referenceOptions.map((o) => o.value))\n\t\t\tconst picked = this.draft.values\n\t\t\t\t.filter((v) => !shown.has(v))\n\t\t\t\t.map((v) => ({ value: v, label: this.referenceLabels[v] || v }))\n\t\t\treturn [...picked, ...this.referenceOptions]\n\t\t},\n\n\t\tbooleanOptions() {\n\t\t\treturn [\n\t\t\t\t{ value: '', label: t('nextcloud-vue', 'Any') },\n\t\t\t\t{ value: 'true', label: t('nextcloud-vue', 'Yes') },\n\t\t\t\t{ value: 'false', label: t('nextcloud-vue', 'No') },\n\t\t\t]\n\t\t},\n\n\t\tpanelStyle() {\n\t\t\tif (!this.teleport || !this.anchorRect) {\n\t\t\t\treturn {}\n\t\t\t}\n\t\t\tconst width = 280\n\t\t\tconst viewport = typeof window !== 'undefined' ? window.innerWidth : 1024\n\t\t\tconst left = Math.max(8, Math.min(this.anchorRect.left, viewport - width - 8))\n\t\t\treturn { position: 'fixed', top: `${this.anchorRect.bottom + 4}px`, left: `${left}px`, width: `${width}px` }\n\t\t},\n\n\t\tsearchLabel() {\n\t\t\treturn t('nextcloud-vue', 'Search')\n\t\t},\n\n\t\tloadingLabel() {\n\t\t\treturn t('nextcloud-vue', 'Loading…')\n\t\t},\n\n\t\tnoOptionsLabel() {\n\t\t\treturn t('nextcloud-vue', 'Nothing to choose from here.')\n\t\t},\n\n\t\tfromLabel() {\n\t\t\treturn t('nextcloud-vue', 'From')\n\t\t},\n\n\t\ttoLabel() {\n\t\t\treturn t('nextcloud-vue', 'To')\n\t\t},\n\n\t\t/**\n\t\t * Label of the text box: the text filter matches on contains.\n\t\t *\n\t\t * @return {string}\n\t\t * @spec openspec/changes/header-filter-contains/specs/cn-data-table/spec.md#requirement-a-text-header-filter-matches-on-contains\n\t\t */\n\t\tcontainsLabel() {\n\t\t\treturn t('nextcloud-vue', 'Contains')\n\t\t},\n\n\t\tclearLabel() {\n\t\t\treturn t('nextcloud-vue', 'Clear')\n\t\t},\n\n\t\tapplyLabel() {\n\t\t\treturn t('nextcloud-vue', 'Apply')\n\t\t},\n\t},\n\n\tmounted() {\n\t\tdocument.addEventListener('mousedown', this.onOutsideMouseDown, true)\n\t\tif (this.def.kind === 'reference') {\n\t\t\tthis.loadReferenceOptions('')\n\t\t}\n\t\tthis.$nextTick(() => {\n\t\t\tconst first = this.$refs.panel && this.$refs.panel.querySelector('input, button')\n\t\t\tif (first && typeof first.focus === 'function') {\n\t\t\t\tfirst.focus()\n\t\t\t}\n\t\t})\n\t},\n\n\tbeforeUnmount() {\n\t\tdocument.removeEventListener('mousedown', this.onOutsideMouseDown, true)\n\t\tclearTimeout(this.searchTimer)\n\t},\n\n\tmethods: {\n\t\ttoggleValue(value) {\n\t\t\tthis.draft.values = this.draft.values.includes(value)\n\t\t\t\t? this.draft.values.filter((v) => v !== value)\n\t\t\t\t: [...this.draft.values, value]\n\t\t},\n\n\t\t/**\n\t\t * The state this panel applies, in the shape `columnFilterParams` reads.\n\t\t *\n\t\t * @return {object}\n\t\t */\n\t\tdraftState() {\n\t\t\tif (this.def.kind === 'enum' || this.def.kind === 'reference') {\n\t\t\t\treturn { values: [...this.draft.values] }\n\t\t\t}\n\t\t\tif (this.def.kind === 'number' || this.def.kind === 'date') {\n\t\t\t\treturn { from: this.draft.from, to: this.draft.to }\n\t\t\t}\n\t\t\treturn { value: this.draft.value }\n\t\t},\n\n\t\tapply() {\n\t\t\t/**\n\t\t\t * @event apply The person applied the filter.\n\t\t\t * @type {object} The column filter state.\n\t\t\t */\n\t\t\tthis.$emit('apply', this.draftState())\n\t\t},\n\n\t\tclear() {\n\t\t\tthis.$emit('apply', this.def.kind === 'enum' || this.def.kind === 'reference'\n\t\t\t\t? { values: [] }\n\t\t\t\t: (this.def.kind === 'number' || this.def.kind === 'date') ? { from: '', to: '' } : { value: '' })\n\t\t},\n\n\t\tclose() {\n\t\t\t/**\n\t\t\t * @event close The panel should close without applying.\n\t\t\t */\n\t\t\tthis.$emit('close')\n\t\t},\n\n\t\tonEnter(event) {\n\t\t\t// Enter in a text, number or date box applies, like a form submit.\n\t\t\t// On a checkbox or a button it keeps its own meaning.\n\t\t\tconst target = event && event.target\n\t\t\tif (target && target.tagName === 'INPUT' && ['text', 'number', 'date', 'search'].includes(target.type)) {\n\t\t\t\tevent.preventDefault()\n\t\t\t\tthis.apply()\n\t\t\t}\n\t\t},\n\n\t\tonOutsideMouseDown(event) {\n\t\t\tconst panel = this.$refs.panel\n\t\t\tif (panel && event && event.target && !panel.contains(event.target)) {\n\t\t\t\tthis.close()\n\t\t\t}\n\t\t},\n\n\t\tonSearchInput() {\n\t\t\tclearTimeout(this.searchTimer)\n\t\t\tthis.searchTimer = setTimeout(() => this.loadReferenceOptions(this.query), 250)\n\t\t},\n\n\t\t/**\n\t\t * Search the referenced objects. The value is the object's uuid,\n\t\t * because that is what the server filters a reference on.\n\t\t *\n\t\t * @param {string} search The search term.\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync loadReferenceOptions(search) {\n\t\t\tconst ref = this.def.reference || {}\n\t\t\tconst register = ref.register || this.register\n\t\t\tif (!register || !ref.schema) {\n\t\t\t\tthis.referenceError = t('nextcloud-vue', 'This column cannot list its objects.')\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.referenceLoading = true\n\t\t\tthis.referenceError = ''\n\t\t\ttry {\n\t\t\t\tconst [{ default: axios }, { generateUrl }] = await Promise.all([\n\t\t\t\t\timport('@nextcloud/axios'),\n\t\t\t\t\timport('@nextcloud/router'),\n\t\t\t\t])\n\t\t\t\tconst url = generateUrl('/apps/openregister/api/objects/{register}/{schema}', {\n\t\t\t\t\tregister,\n\t\t\t\t\tschema: String(ref.schema),\n\t\t\t\t})\n\t\t\t\tconst params = { _limit: 50 }\n\t\t\t\tif (search) {\n\t\t\t\t\tparams._search = search\n\t\t\t\t}\n\t\t\t\tconst response = await axios.get(url, { params })\n\t\t\t\tconst rows = (response && response.data && (response.data.results || response.data)) || []\n\t\t\t\tconst list = Array.isArray(rows) ? rows : []\n\t\t\t\tconst options = list\n\t\t\t\t\t.map((row) => {\n\t\t\t\t\t\tconst self = (row && row['@self']) || {}\n\t\t\t\t\t\tconst value = String(self.id || self.uuid || row.id || row.uuid || '')\n\t\t\t\t\t\tconst label = String((ref.labelField && row[ref.labelField]) || row.name || row.title || self.name || value)\n\t\t\t\t\t\treturn { value, label }\n\t\t\t\t\t})\n\t\t\t\t\t.filter((o) => o.value !== '')\n\t\t\t\tthis.referenceOptions = options\n\t\t\t\tthis.referenceLabels = { ...this.referenceLabels, ...Object.fromEntries(options.map((o) => [o.value, o.label])) }\n\t\t\t} catch {\n\t\t\t\tthis.referenceOptions = []\n\t\t\t\tthis.referenceError = t('nextcloud-vue', 'The list could not load.')\n\t\t\t} finally {\n\t\t\t\tthis.referenceLoading = false\n\t\t\t}\n\t\t},\n\t},\n}\n</script>\n\n<style scoped>\n.cn-column-filter {\n\tz-index: 10000;\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 8px;\n\tbox-sizing: border-box;\n\tmax-height: 60vh;\n\toverflow-y: auto;\n\tpadding: 12px;\n\tbackground: var(--color-main-background);\n\tcolor: var(--color-main-text);\n\tborder: 1px solid var(--color-border-dark);\n\tborder-radius: var(--border-radius-large, 8px);\n\tbox-shadow: 0 2px 8px var(--color-box-shadow);\n\tfont-weight: normal;\n\ttext-align: start;\n}\n\n.cn-column-filter__heading {\n\tmargin: 0;\n\tfont-weight: bold;\n}\n\n.cn-column-filter__options {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 4px;\n\tmargin: 0;\n\tpadding: 0;\n\tborder: none;\n}\n\n.cn-column-filter__option {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 8px;\n\tmin-height: 32px;\n\tcursor: pointer;\n}\n\n.cn-column-filter__range {\n\tdisplay: flex;\n\tgap: 8px;\n}\n\n.cn-column-filter__field {\n\tdisplay: flex;\n\tflex: 1 1 0;\n\tflex-direction: column;\n\tgap: 4px;\n\tmin-width: 0;\n}\n\n.cn-column-filter__label {\n\tfont-size: var(--font-size-small, 13px);\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-column-filter__input {\n\twidth: 100%;\n\tbox-sizing: border-box;\n\tmargin: 0;\n}\n\n.cn-column-filter__hint {\n\tmargin: 0;\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-column-filter__actions {\n\tdisplay: flex;\n\tjustify-content: flex-end;\n\tgap: 8px;\n}\n\n.cn-column-filter__button {\n\tmin-height: 34px;\n\tpadding: 0 12px;\n\tborder: 1px solid var(--color-border-dark);\n\tborder-radius: var(--border-radius-element, 8px);\n\tbackground: var(--color-main-background);\n\tcolor: var(--color-main-text);\n\tcursor: pointer;\n}\n\n.cn-column-filter__button--primary {\n\tborder-color: var(--color-primary-element);\n\tbackground: var(--color-primary-element);\n\tcolor: var(--color-primary-element-text);\n}\n\n.cn-column-filter__button:focus-visible,\n.cn-column-filter__input:focus-visible,\n.cn-column-filter__option input:focus-visible {\n\toutline: 2px solid var(--color-primary-element);\n\toutline-offset: 2px;\n}\n\n.cn-column-filter__sr-only {\n\tposition: absolute;\n\twidth: 1px;\n\theight: 1px;\n\toverflow: hidden;\n\tclip-path: inset(50%);\n\twhite-space: nowrap;\n}\n</style>\n"],"names":["_createElementVNode","_Fragment","_toDisplayString","_createElementBlock","_renderList","_openBlock","_vModelDynamic","_vModelText"],"mappings":"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"}
|
|
@@ -26,7 +26,7 @@ import __sfc_main$3 from '../CnLockIndicator/CnLockIndicator.vue.js';
|
|
|
26
26
|
*
|
|
27
27
|
* Sorting: a plain click on a sortable header is single-sort (cycle asc → desc → cleared), unchanged from before.
|
|
28
28
|
* Shift+click (or Shift+Enter on a focused header) appends the column as a secondary/tertiary sort key, capped at 3, with numbered priority badges (1, 2, 3) once two or more rendered, sortable columns are sorted.
|
|
29
|
-
* A sort key whose column is not rendered, or not sortable, still sorts, but is not counted or numbered.
|
|
29
|
+
* A sort key whose column is not rendered, or not sortable, still sorts, but is not counted or numbered, and `aria-sort` goes to the first sort key whose column is rendered and sortable.
|
|
30
30
|
* Pass `sortKeys: [{key, order}, ...]` for multi-sort (falls back to the legacy `sortKey`/`sortOrder` props when empty).
|
|
31
31
|
* The `sort` event payload is extended, not replaced: `{key, order}` still mirrors the primary key exactly as before; a new `keys` field carries the full ordered list.
|
|
32
32
|
* See `src/utils/multiColumnSort.js` for the state machine.
|
|
@@ -1377,8 +1377,8 @@ var script = {
|
|
|
1377
1377
|
},
|
|
1378
1378
|
|
|
1379
1379
|
/**
|
|
1380
|
-
* `aria-sort` value for a column header: `'ascending'`/`'descending'` for the
|
|
1381
|
-
* `null` omits the attribute entirely (unsorted, not sortable, or not the
|
|
1380
|
+
* `aria-sort` value for a column header: `'ascending'`/`'descending'` for the first rendered sort key only, per WCAG guidance that `aria-sort` describes single-column sort state.
|
|
1381
|
+
* `null` omits the attribute entirely (unsorted, not sortable, or not the first rendered sort key).
|
|
1382
1382
|
*
|
|
1383
1383
|
* @param {object} col Column definition.
|
|
1384
1384
|
* @return {string|null}
|
|
@@ -1387,7 +1387,7 @@ var script = {
|
|
|
1387
1387
|
if (!col.sortable) {
|
|
1388
1388
|
return null
|
|
1389
1389
|
}
|
|
1390
|
-
const primary = this.
|
|
1390
|
+
const primary = this.renderedSortKeys[0];
|
|
1391
1391
|
if (!primary || primary.key !== col.key) {
|
|
1392
1392
|
return null
|
|
1393
1393
|
}
|