@conduction/nextcloud-vue 2.62.0 → 2.64.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/CnAdminActionCard/CnAdminActionCard.vue.js +10 -0
- package/dist/esm/components/CnAdminActionCard/CnAdminActionCard.vue.js.map +1 -0
- package/dist/esm/components/CnAdminActionCard/CnAdminActionCard.vue2.js +189 -0
- package/dist/esm/components/CnAdminActionCard/CnAdminActionCard.vue2.js.map +1 -0
- package/dist/esm/components/CnAdminActionCard/CnAdminActionCard.vue3.js +72 -0
- package/dist/esm/components/CnAdminActionCard/CnAdminActionCard.vue3.js.map +1 -0
- package/dist/esm/components/CnAppNav/CnAppNav.vue2.js +425 -39
- package/dist/esm/components/CnAppNav/CnAppNav.vue2.js.map +1 -1
- package/dist/esm/components/CnAppNav/CnAppNav.vue3.js +119 -42
- package/dist/esm/components/CnAppNav/CnAppNav.vue3.js.map +1 -1
- package/dist/esm/components/CnAppRoot/CnAppRoot.vue2.js +186 -9
- package/dist/esm/components/CnAppRoot/CnAppRoot.vue2.js.map +1 -1
- package/dist/esm/components/CnAppRoot/CnAppRoot.vue3.js +65 -42
- package/dist/esm/components/CnAppRoot/CnAppRoot.vue3.js.map +1 -1
- package/dist/esm/components/CnAuditTrailCard/CnAuditTrailCard.vue2.js +61 -16
- package/dist/esm/components/CnAuditTrailCard/CnAuditTrailCard.vue2.js.map +1 -1
- package/dist/esm/components/CnAuditTrailCard/CnAuditTrailCard.vue3.js.map +1 -1
- package/dist/esm/components/CnAuditTrailWidget/CnAuditTrailWidget.vue2.js +20 -0
- package/dist/esm/components/CnAuditTrailWidget/CnAuditTrailWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnAuditTrailWidget/CnAuditTrailWidget.vue3.js +3 -2
- package/dist/esm/components/CnAuditTrailWidget/CnAuditTrailWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue2.js +33 -2
- package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue2.js.map +1 -1
- package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue3.js.map +1 -1
- package/dist/esm/components/CnChoiceCards/CnChoiceCards.vue2.js.map +1 -1
- package/dist/esm/components/CnChoiceCards/CnChoiceCards.vue3.js +53 -37
- package/dist/esm/components/CnChoiceCards/CnChoiceCards.vue3.js.map +1 -1
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js +29 -0
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js.map +1 -1
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue3.js +152 -135
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue3.js.map +1 -1
- package/dist/esm/components/CnDataTable/CnColumnFilterPopover.vue.js +10 -0
- package/dist/esm/components/CnDataTable/CnColumnFilterPopover.vue.js.map +1 -0
- package/dist/esm/components/CnDataTable/CnColumnFilterPopover.vue2.js +293 -0
- package/dist/esm/components/CnDataTable/CnColumnFilterPopover.vue2.js.map +1 -0
- package/dist/esm/components/CnDataTable/CnColumnFilterPopover.vue3.js +189 -0
- package/dist/esm/components/CnDataTable/CnColumnFilterPopover.vue3.js.map +1 -0
- package/dist/esm/components/CnDataTable/CnDataTable.vue2.js +253 -9
- package/dist/esm/components/CnDataTable/CnDataTable.vue2.js.map +1 -1
- package/dist/esm/components/CnDataTable/CnDataTable.vue3.js +126 -50
- package/dist/esm/components/CnDataTable/CnDataTable.vue3.js.map +1 -1
- package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js +66 -14
- package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js.map +1 -1
- package/dist/esm/components/CnDetailPage/CnDetailPage.vue3.js +23 -14
- package/dist/esm/components/CnDetailPage/CnDetailPage.vue3.js.map +1 -1
- package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue2.js.map +1 -1
- package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue3.js +2 -1
- package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue3.js.map +1 -1
- package/dist/esm/components/CnFieldHelper/CnFieldHelper.vue2.js +3 -1
- package/dist/esm/components/CnFieldHelper/CnFieldHelper.vue2.js.map +1 -1
- package/dist/esm/components/CnFieldHelper/CnFieldHelper.vue3.js +1 -1
- package/dist/esm/components/CnFieldHelper/CnFieldHelper.vue3.js.map +1 -1
- package/dist/esm/components/CnFormDialog/CnFormDialog.vue2.js +234 -9
- package/dist/esm/components/CnFormDialog/CnFormDialog.vue2.js.map +1 -1
- package/dist/esm/components/CnFormDialog/CnFormDialog.vue3.js +96 -57
- package/dist/esm/components/CnFormDialog/CnFormDialog.vue3.js.map +1 -1
- package/dist/esm/components/CnHeaderWidget/CnHeaderWidget.vue2.js +81 -4
- package/dist/esm/components/CnHeaderWidget/CnHeaderWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnHeaderWidget/CnHeaderWidget.vue3.js +22 -5
- package/dist/esm/components/CnHeaderWidget/CnHeaderWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js +81 -2
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js.map +1 -1
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js +7 -3
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js.map +1 -1
- package/dist/esm/components/CnIndexPage/selfModeActions.js +3 -3
- package/dist/esm/components/CnIndexPage/selfModeActions.js.map +1 -1
- package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue2.js +41 -2
- package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue3.js +8 -3
- package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnResourceSelect/CnResourceSelect.vue2.js +121 -12
- package/dist/esm/components/CnResourceSelect/CnResourceSelect.vue2.js.map +1 -1
- package/dist/esm/components/CnResourceSelect/CnResourceSelect.vue3.js +3 -1
- package/dist/esm/components/CnResourceSelect/CnResourceSelect.vue3.js.map +1 -1
- package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue2.js +326 -1
- package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue2.js.map +1 -1
- package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue3.js +112 -26
- package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue3.js.map +1 -1
- package/dist/esm/components/CnStagesWidget/CnStagesWidget.vue2.js +63 -2
- package/dist/esm/components/CnStagesWidget/CnStagesWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnStagesWidget/CnStagesWidget.vue3.js +96 -37
- package/dist/esm/components/CnStagesWidget/CnStagesWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnStagesWidget/stagesModel.js +5 -2
- package/dist/esm/components/CnStagesWidget/stagesModel.js.map +1 -1
- package/dist/esm/components/CnStatWidget/CnStatWidget.vue2.js +52 -2
- package/dist/esm/components/CnStatWidget/CnStatWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnStatWidget/CnStatWidget.vue3.js +6 -6
- package/dist/esm/components/CnStatWidget/CnStatWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue2.js +14 -2
- package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue3.js +2 -1
- package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnTimelineWidget/CnTimelineWidget.vue.js +10 -0
- package/dist/esm/components/CnTimelineWidget/CnTimelineWidget.vue.js.map +1 -0
- package/dist/esm/components/CnTimelineWidget/CnTimelineWidget.vue2.js +337 -0
- package/dist/esm/components/CnTimelineWidget/CnTimelineWidget.vue2.js.map +1 -0
- package/dist/esm/components/CnTimelineWidget/CnTimelineWidget.vue3.js +102 -0
- package/dist/esm/components/CnTimelineWidget/CnTimelineWidget.vue3.js.map +1 -0
- package/dist/esm/components/CnTimelineWidget/dashboardRegistration.js +34 -0
- package/dist/esm/components/CnTimelineWidget/dashboardRegistration.js.map +1 -0
- package/dist/esm/components/CnWalkthrough/CnWalkthrough.vue2.js +131 -8
- package/dist/esm/components/CnWalkthrough/CnWalkthrough.vue2.js.map +1 -1
- package/dist/esm/components/CnWalkthrough/CnWalkthrough.vue3.js +40 -38
- package/dist/esm/components/CnWalkthrough/CnWalkthrough.vue3.js.map +1 -1
- package/dist/esm/components/CnWidgetGrid/builtInWidgets.js +8 -6
- package/dist/esm/components/CnWidgetGrid/builtInWidgets.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/components/CnWidgetWrapper/CnWidgetWrapper.vue2.js +73 -1
- package/dist/esm/components/CnWidgetWrapper/CnWidgetWrapper.vue2.js.map +1 -1
- package/dist/esm/components/CnWidgetWrapper/CnWidgetWrapper.vue3.js +14 -2
- package/dist/esm/components/CnWidgetWrapper/CnWidgetWrapper.vue3.js.map +1 -1
- package/dist/esm/components/CnWizardDialog/CnWizardDialog.vue2.js +19 -0
- package/dist/esm/components/CnWizardDialog/CnWizardDialog.vue2.js.map +1 -1
- package/dist/esm/components/CnWizardDialog/CnWizardDialog.vue3.js +1 -1
- package/dist/esm/components/CnWizardDialog/CnWizardDialog.vue3.js.map +1 -1
- package/dist/esm/composables/useDependencyCheck.js +65 -0
- package/dist/esm/composables/useDependencyCheck.js.map +1 -0
- package/dist/esm/composables/useWalkthrough.js +218 -6
- package/dist/esm/composables/useWalkthrough.js.map +1 -1
- package/dist/esm/index.js +2 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/l10n/en.json.js +45 -1
- package/dist/esm/l10n/en.json.js.map +1 -1
- package/dist/esm/l10n/nl.json.js +45 -1
- package/dist/esm/l10n/nl.json.js.map +1 -1
- package/dist/esm/nextcloud-vue.css +780 -81
- package/dist/esm/store/useObjectStore.js +8 -0
- package/dist/esm/store/useObjectStore.js.map +1 -1
- package/dist/esm/utils/columnFilters.js +311 -0
- package/dist/esm/utils/columnFilters.js.map +1 -0
- package/dist/esm/utils/groupAutocomplete.js +123 -0
- package/dist/esm/utils/groupAutocomplete.js.map +1 -0
- package/dist/esm/utils/libraryWidgetKeys.js +2 -0
- package/dist/esm/utils/libraryWidgetKeys.js.map +1 -1
- package/dist/esm/utils/pickerOptions.js +198 -0
- package/dist/esm/utils/pickerOptions.js.map +1 -0
- package/dist/esm/utils/schema.js +83 -7
- package/dist/esm/utils/schema.js.map +1 -1
- package/dist/esm/utils/schemaRefSlug.js +19 -3
- package/dist/esm/utils/schemaRefSlug.js.map +1 -1
- package/dist/esm/utils/timelineEvents.js +174 -0
- package/dist/esm/utils/timelineEvents.js.map +1 -0
- package/dist/esm/utils/validateManifestV2.compiled.js +2 -2
- package/dist/esm/utils/validateManifestV2.compiled.js.map +1 -1
- package/dist/esm/utils/walkthroughSignals.js +88 -0
- package/dist/esm/utils/walkthroughSignals.js.map +1 -0
- package/dist/nextcloud-vue.cjs.js +13088 -7937
- package/dist/nextcloud-vue.cjs.js.map +2 -2
- package/dist/nextcloud-vue.css +780 -81
- package/l10n/en.json +45 -0
- package/l10n/nl.json +45 -0
- package/package.json +1 -1
- package/src/components/CnAdminActionCard/CnAdminActionCard.vue +234 -0
- package/src/components/CnAdminActionCard/index.js +4 -0
- package/src/components/CnAppNav/CnAppNav.vue +568 -43
- package/src/components/CnAppRoot/CnAppRoot.md +4 -0
- package/src/components/CnAppRoot/CnAppRoot.vue +223 -16
- package/src/components/CnAuditTrailCard/CnAuditTrailCard.vue +61 -16
- package/src/components/CnAuditTrailWidget/CnAuditTrailWidget.vue +22 -1
- package/src/components/CnCellRenderer/CnCellRenderer.vue +33 -2
- package/src/components/CnChoiceCards/CnChoiceCards.vue +56 -31
- package/src/components/CnDashboardPage/CnDashboardPage.vue +45 -4
- package/src/components/CnDataTable/CnColumnFilterPopover.vue +524 -0
- package/src/components/CnDataTable/CnDataTable.md +3 -0
- package/src/components/CnDataTable/CnDataTable.vue +305 -5
- package/src/components/CnDetailPage/CnDetailPage.md +4 -0
- package/src/components/CnDetailPage/CnDetailPage.vue +60 -1
- package/src/components/CnDetailWidgetHost/CnDetailWidgetHost.vue +2 -2
- package/src/components/CnFieldHelper/CnFieldHelper.vue +4 -2
- package/src/components/CnFormDialog/CnFormDialog.vue +290 -31
- package/src/components/CnHeaderWidget/CnHeaderWidget.vue +116 -6
- package/src/components/CnIndexPage/CnIndexPage.vue +87 -4
- package/src/components/CnIndexPage/selfModeActions.js +3 -3
- package/src/components/CnObjectListWidget/CnObjectListWidget.vue +46 -2
- package/src/components/CnResourceSelect/CnResourceSelect.vue +123 -12
- package/src/components/CnSetupWizard/CnSetupWizard.vue +392 -3
- package/src/components/CnStagesWidget/CnStagesWidget.vue +180 -2
- package/src/components/CnStagesWidget/stagesModel.js +5 -2
- package/src/components/CnStatWidget/CnStatWidget.vue +57 -3
- package/src/components/CnTabsWidget/CnTabsWidget.vue +15 -2
- package/src/components/CnTimelineWidget/CnTimelineWidget.vue +477 -0
- package/src/components/CnTimelineWidget/dashboardRegistration.js +32 -0
- package/src/components/CnTimelineWidget/index.js +4 -0
- package/src/components/CnWalkthrough/CnWalkthrough.vue +143 -10
- package/src/components/CnWidgetGrid/builtInWidgets.js +2 -0
- package/src/components/CnWidgetGrid/registerDashboardWidgets.js +1 -0
- package/src/components/CnWidgetWrapper/CnWidgetWrapper.md +4 -0
- package/src/components/CnWidgetWrapper/CnWidgetWrapper.vue +107 -1
- package/src/components/CnWizardDialog/CnWizardDialog.vue +20 -1
- package/src/components/index.js +2 -0
- package/src/composables/useDependencyCheck.js +61 -0
- package/src/composables/useWalkthrough.js +217 -5
- package/src/css/dashboard.css +49 -0
- package/src/css/detail-page.css +29 -4
- package/src/css/kpi-card.css +24 -1
- package/src/css/table.css +99 -6
- package/src/index.js +2 -0
- package/src/schemas/app-manifest-v2.schema.json +135 -3
- package/src/store/useObjectStore.js +8 -0
- package/src/utils/columnFilters.js +324 -0
- package/src/utils/groupAutocomplete.js +119 -0
- package/src/utils/libraryWidgetKeys.js +2 -0
- package/src/utils/pickerOptions.js +194 -0
- package/src/utils/schema.js +83 -7
- package/src/utils/schemaRefSlug.js +19 -3
- package/src/utils/timelineEvents.js +171 -0
- package/src/utils/validateManifestV2.compiled.js +2 -2
- package/src/utils/walkthroughSignals.js +94 -0
|
@@ -1,16 +1,20 @@
|
|
|
1
1
|
import axios__default from '@nextcloud/axios';
|
|
2
|
-
import { translate } from '@nextcloud/l10n';
|
|
2
|
+
import { translate, translatePlural } from '@nextcloud/l10n';
|
|
3
3
|
import { generateUrl } from '@nextcloud/router';
|
|
4
4
|
import { NcLoadingIcon, NcCheckboxRadioSwitch } from '@nextcloud/vue';
|
|
5
|
+
import FilterIcon from 'vue-material-design-icons/Filter.vue';
|
|
6
|
+
import FilterOutline from 'vue-material-design-icons/FilterOutline.vue';
|
|
7
|
+
import __sfc_main$1 from './CnColumnFilterPopover.vue.js';
|
|
5
8
|
import { useClickDragGuard } from '../../composables/useClickDragGuard.js';
|
|
9
|
+
import { columnFilterDef, columnFilterState, isColumnFilterActive, columnFilterParams, clearedColumnFilterParams, isColumnSortable } from '../../utils/columnFilters.js';
|
|
6
10
|
import { resolveHref, openRowTarget, followLinkClick } from '../../utils/linkNavigation.js';
|
|
7
11
|
import { nextSortState } from '../../utils/multiColumnSort.js';
|
|
8
12
|
import { preventMiddleClickAutoscroll, isRowMiddleClick, isNewTabHandled, markNewTabHandled, isNewTabClick } from '../../utils/rowAuxClick.js';
|
|
9
13
|
import { DEFAULT_ROW_INDICATOR_CAP, resolveRowIndicators } from '../../utils/rowIndicators.js';
|
|
10
14
|
import { columnsFromSchema } from '../../utils/schema.js';
|
|
11
15
|
import __sfc_main from '../CnCellRenderer/CnCellRenderer.vue.js';
|
|
12
|
-
import __sfc_main$
|
|
13
|
-
import __sfc_main$
|
|
16
|
+
import __sfc_main$2 from '../CnIcon/CnIcon.vue.js';
|
|
17
|
+
import __sfc_main$3 from '../CnLockIndicator/CnLockIndicator.vue.js';
|
|
14
18
|
|
|
15
19
|
/**
|
|
16
20
|
* CnDataTable — Generic sortable data table for list views.
|
|
@@ -68,8 +72,11 @@ var script = {
|
|
|
68
72
|
NcLoadingIcon,
|
|
69
73
|
NcCheckboxRadioSwitch,
|
|
70
74
|
CnCellRenderer: __sfc_main,
|
|
71
|
-
|
|
72
|
-
|
|
75
|
+
CnColumnFilterPopover: __sfc_main$1,
|
|
76
|
+
CnIcon: __sfc_main$2,
|
|
77
|
+
CnLockIndicator: __sfc_main$3,
|
|
78
|
+
FilterIcon,
|
|
79
|
+
FilterOutline,
|
|
73
80
|
},
|
|
74
81
|
|
|
75
82
|
inject: {
|
|
@@ -100,7 +107,13 @@ var script = {
|
|
|
100
107
|
* reader is looking. `columnsFromSchema` fills it from the JSON Schema property
|
|
101
108
|
* description automatically, so schema-driven tables get it for free.
|
|
102
109
|
*
|
|
103
|
-
*
|
|
110
|
+
* `secondary` draws a second, muted line under the cell's value: a field
|
|
111
|
+
* key (`"number"`), a template with `{field}` placeholders
|
|
112
|
+
* (`"{number} · {requester}"`, dotted paths allowed), or a function of
|
|
113
|
+
* the row. Empty fields leave their placeholder blank; a line that
|
|
114
|
+
* resolves to nothing is not drawn.
|
|
115
|
+
*
|
|
116
|
+
* @type {Array<{key: string, label: string, description: string, sortable: boolean, width: string, class: string, cellClass: string, secondary: (string|((row: object) => string))}|string>}
|
|
104
117
|
*/
|
|
105
118
|
columns: {
|
|
106
119
|
type: Array,
|
|
@@ -438,9 +451,39 @@ var script = {
|
|
|
438
451
|
type: Boolean,
|
|
439
452
|
default: false,
|
|
440
453
|
},
|
|
454
|
+
|
|
455
|
+
/**
|
|
456
|
+
* Show a filter button in every header whose column can filter (see
|
|
457
|
+
* `columnFilterDef`): enum, boolean, text, number, date and reference
|
|
458
|
+
* columns backed by a schema property. A column opts out with
|
|
459
|
+
* `filterable: false`. Applying a filter emits `column-filter`; the
|
|
460
|
+
* host owns the filter state and passes it back as `activeFilters`.
|
|
461
|
+
*
|
|
462
|
+
* @spec openspec/changes/table-header-sort-and-filter/specs/cn-data-table/spec.md#requirement-every-backed-column-filters-from-its-header
|
|
463
|
+
*/
|
|
464
|
+
filterable: {
|
|
465
|
+
type: Boolean,
|
|
466
|
+
default: false,
|
|
467
|
+
},
|
|
468
|
+
|
|
469
|
+
/**
|
|
470
|
+
* The active filter map, `{ paramKey: values[] }`: the same map the
|
|
471
|
+
* facet sidebar writes, so a header filter and a sidebar filter on one
|
|
472
|
+
* field show the same state.
|
|
473
|
+
*/
|
|
474
|
+
activeFilters: {
|
|
475
|
+
type: Object,
|
|
476
|
+
default: () => ({}),
|
|
477
|
+
},
|
|
478
|
+
|
|
479
|
+
/** Register slug a reference column's filter searches in when the column names none. */
|
|
480
|
+
filterRegister: {
|
|
481
|
+
type: String,
|
|
482
|
+
default: '',
|
|
483
|
+
},
|
|
441
484
|
},
|
|
442
485
|
|
|
443
|
-
emits: ['row-click', 'row-aux-click', 'row-context-menu', 'select', 'select-all', 'sort', 'view-all'],
|
|
486
|
+
emits: ['row-click', 'row-aux-click', 'row-context-menu', 'select', 'select-all', 'sort', 'view-all', 'column-filter'],
|
|
444
487
|
|
|
445
488
|
setup() {
|
|
446
489
|
// Tell a deliberate row click apart from a text-selection drag.
|
|
@@ -449,6 +492,10 @@ var script = {
|
|
|
449
492
|
|
|
450
493
|
data() {
|
|
451
494
|
return {
|
|
495
|
+
/** Key of the column whose filter panel is open, or ''. */
|
|
496
|
+
openFilterKey: '',
|
|
497
|
+
/** The open filter button's bounding rect, to place the panel. */
|
|
498
|
+
filterAnchorRect: null,
|
|
452
499
|
/**
|
|
453
500
|
* Resolved aggregate-column values, keyed by `String(row[rowKey])`
|
|
454
501
|
* then by column key. Populated by `loadAggregates()` for columns
|
|
@@ -566,8 +613,12 @@ var script = {
|
|
|
566
613
|
overrides: this.columnOverrides,
|
|
567
614
|
})
|
|
568
615
|
: this.columns;
|
|
616
|
+
// Every column backed by a schema property sorts unless it says
|
|
617
|
+
// `sortable: false`; object columns from a manifest used to need an
|
|
618
|
+
// explicit flag and so could not sort at all.
|
|
619
|
+
const withSort = (c) => (c && typeof c === 'object' ? { ...c, sortable: isColumnSortable(c, this.schema) } : c);
|
|
569
620
|
if (!(cols || []).some((c) => typeof c === 'string')) {
|
|
570
|
-
return cols || []
|
|
621
|
+
return (cols || []).map(withSort)
|
|
571
622
|
}
|
|
572
623
|
const schemaCols = this.schema
|
|
573
624
|
? columnsFromSchema(this.schema, { overrides: this.columnOverrides })
|
|
@@ -575,7 +626,7 @@ var script = {
|
|
|
575
626
|
const byKey = new Map(schemaCols.map((c) => [c.key, c]));
|
|
576
627
|
return (cols || []).map((c) => {
|
|
577
628
|
if (typeof c !== 'string') {
|
|
578
|
-
return c
|
|
629
|
+
return withSort(c)
|
|
579
630
|
}
|
|
580
631
|
return byKey.get(c) || { key: c, label: c, sortable: true }
|
|
581
632
|
})
|
|
@@ -616,6 +667,40 @@ var script = {
|
|
|
616
667
|
return links
|
|
617
668
|
},
|
|
618
669
|
|
|
670
|
+
/**
|
|
671
|
+
* The column whose filter panel is open, or null.
|
|
672
|
+
*
|
|
673
|
+
* @return {object|null}
|
|
674
|
+
*/
|
|
675
|
+
openFilterColumn() {
|
|
676
|
+
if (!this.openFilterKey) {
|
|
677
|
+
return null
|
|
678
|
+
}
|
|
679
|
+
return this.effectiveColumns.find((c) => c && c.key === this.openFilterKey && this.filterDefFor(c)) || null
|
|
680
|
+
},
|
|
681
|
+
|
|
682
|
+
/**
|
|
683
|
+
* One chip per column with an active header filter.
|
|
684
|
+
*
|
|
685
|
+
* @return {Array<{key: string, col: object, text: string, removeLabel: string}>}
|
|
686
|
+
*/
|
|
687
|
+
activeColumnFilterChips() {
|
|
688
|
+
if (!this.filterable) {
|
|
689
|
+
return []
|
|
690
|
+
}
|
|
691
|
+
return this.effectiveColumns
|
|
692
|
+
.filter((c) => c && this.isColumnFiltered(c))
|
|
693
|
+
.map((col) => {
|
|
694
|
+
const label = this.translateLabel(col.label);
|
|
695
|
+
const text = translate('nextcloud-vue', '{column}: {value}', { column: label, value: this.columnFilterSummary(col) });
|
|
696
|
+
return { key: col.key, col, text, removeLabel: translate('nextcloud-vue', 'Remove filter {column}', { column: label }) }
|
|
697
|
+
})
|
|
698
|
+
},
|
|
699
|
+
|
|
700
|
+
activeFiltersLabel() {
|
|
701
|
+
return translate('nextcloud-vue', 'Active filters')
|
|
702
|
+
},
|
|
703
|
+
|
|
619
704
|
effectiveSortKeys() {
|
|
620
705
|
if (this.sortKeys && this.sortKeys.length > 0) {
|
|
621
706
|
return this.sortKeys
|
|
@@ -999,6 +1084,36 @@ var script = {
|
|
|
999
1084
|
* @param {object} col The column definition.
|
|
1000
1085
|
* @return {unknown} The value handed to the slot / CnCellRenderer.
|
|
1001
1086
|
*/
|
|
1087
|
+
/**
|
|
1088
|
+
* The secondary line of a cell, from `col.secondary`: a function is
|
|
1089
|
+
* called with the row; a string with `{field}` placeholders is a
|
|
1090
|
+
* template filled from the row (dotted paths allowed); any other
|
|
1091
|
+
* string is a field key. Returns '' when there is nothing to draw.
|
|
1092
|
+
*
|
|
1093
|
+
* @spec openspec/changes/zuiddrecht-pixel-gaps/specs/zuiddrecht-pixel-gaps/spec.md#requirement-a-table-column-carries-a-secondary-line
|
|
1094
|
+
* @param {object} row The row.
|
|
1095
|
+
* @param {object} col The column definition.
|
|
1096
|
+
* @return {string} The secondary text, or ''.
|
|
1097
|
+
*/
|
|
1098
|
+
secondaryValue(row, col) {
|
|
1099
|
+
const spec = col?.secondary;
|
|
1100
|
+
if (typeof spec === 'function') {
|
|
1101
|
+
const out = spec(row);
|
|
1102
|
+
return out === null || out === undefined ? '' : String(out)
|
|
1103
|
+
}
|
|
1104
|
+
if (typeof spec !== 'string' || spec === '') {
|
|
1105
|
+
return ''
|
|
1106
|
+
}
|
|
1107
|
+
const asText = (v) => (v === null || v === undefined ? '' : String(v));
|
|
1108
|
+
if (spec.includes('{')) {
|
|
1109
|
+
const filled = spec.replace(/\{([^}]+)\}/g, (_, key) => asText(this.getCellValue(row, key.trim())));
|
|
1110
|
+
// A template whose every field is empty leaves only separators:
|
|
1111
|
+
// nothing worth a line.
|
|
1112
|
+
return /[\p{L}\p{N}]/u.test(filled) ? filled.trim() : ''
|
|
1113
|
+
}
|
|
1114
|
+
return asText(this.getCellValue(row, spec))
|
|
1115
|
+
},
|
|
1116
|
+
|
|
1002
1117
|
cellValue(row, col) {
|
|
1003
1118
|
if (col && col.aggregate) {
|
|
1004
1119
|
const cached = this.aggregateValues[String(row[this.rowKey])];
|
|
@@ -1287,6 +1402,135 @@ var script = {
|
|
|
1287
1402
|
* @param {string} key Column key.
|
|
1288
1403
|
* @param {MouseEvent} [event] The originating click event.
|
|
1289
1404
|
*/
|
|
1405
|
+
/**
|
|
1406
|
+
* The filter definition for a column, or null when it does not filter
|
|
1407
|
+
* (header filters off, `filterable: false`, or nothing to filter on).
|
|
1408
|
+
*
|
|
1409
|
+
* @param {object} col The column.
|
|
1410
|
+
* @return {object|null}
|
|
1411
|
+
*/
|
|
1412
|
+
filterDefFor(col) {
|
|
1413
|
+
if (!this.filterable || !col) {
|
|
1414
|
+
return null
|
|
1415
|
+
}
|
|
1416
|
+
return columnFilterDef(col, this.schema)
|
|
1417
|
+
},
|
|
1418
|
+
|
|
1419
|
+
columnFilterStateFor(col) {
|
|
1420
|
+
return columnFilterState(this.filterDefFor(col), this.activeFilters)
|
|
1421
|
+
},
|
|
1422
|
+
|
|
1423
|
+
isColumnFiltered(col) {
|
|
1424
|
+
const def = this.filterDefFor(col);
|
|
1425
|
+
return !!def && isColumnFilterActive(def, this.activeFilters)
|
|
1426
|
+
},
|
|
1427
|
+
|
|
1428
|
+
filterButtonLabel(col) {
|
|
1429
|
+
const column = this.translateLabel(col.label);
|
|
1430
|
+
return this.isColumnFiltered(col)
|
|
1431
|
+
? translate('nextcloud-vue', 'Filter {column}, active', { column })
|
|
1432
|
+
: translate('nextcloud-vue', 'Filter {column}', { column })
|
|
1433
|
+
},
|
|
1434
|
+
|
|
1435
|
+
/**
|
|
1436
|
+
* Short text for an active filter: the picked labels, or the range.
|
|
1437
|
+
*
|
|
1438
|
+
* @param {object} col The column.
|
|
1439
|
+
* @return {string}
|
|
1440
|
+
*/
|
|
1441
|
+
columnFilterSummary(col) {
|
|
1442
|
+
const def = this.filterDefFor(col);
|
|
1443
|
+
const state = this.columnFilterStateFor(col);
|
|
1444
|
+
if (!def) {
|
|
1445
|
+
return ''
|
|
1446
|
+
}
|
|
1447
|
+
if (def.kind === 'enum') {
|
|
1448
|
+
const labels = Object.fromEntries((def.options || []).map((o) => [o.value, o.label]));
|
|
1449
|
+
return state.values.map((v) => this.translateLabel(labels[v] || v)).join(', ')
|
|
1450
|
+
}
|
|
1451
|
+
if (def.kind === 'reference') {
|
|
1452
|
+
return translatePlural('nextcloud-vue', '{count} selected', '{count} selected', state.values.length, { count: state.values.length })
|
|
1453
|
+
}
|
|
1454
|
+
if (def.kind === 'number' || def.kind === 'date') {
|
|
1455
|
+
if (state.from && state.to) {
|
|
1456
|
+
return translate('nextcloud-vue', '{from} to {to}', { from: state.from, to: state.to })
|
|
1457
|
+
}
|
|
1458
|
+
return state.from
|
|
1459
|
+
? translate('nextcloud-vue', 'from {value}', { value: state.from })
|
|
1460
|
+
: translate('nextcloud-vue', 'up to {value}', { value: state.to })
|
|
1461
|
+
}
|
|
1462
|
+
if (def.kind === 'boolean') {
|
|
1463
|
+
return state.value === 'true' ? translate('nextcloud-vue', 'Yes') : translate('nextcloud-vue', 'No')
|
|
1464
|
+
}
|
|
1465
|
+
return state.value
|
|
1466
|
+
},
|
|
1467
|
+
|
|
1468
|
+
/**
|
|
1469
|
+
* Open or close a column's filter panel under its button.
|
|
1470
|
+
*
|
|
1471
|
+
* @param {object} col The column.
|
|
1472
|
+
* @param {Event} event The click.
|
|
1473
|
+
* @return {void}
|
|
1474
|
+
*/
|
|
1475
|
+
toggleColumnFilter(col, event) {
|
|
1476
|
+
if (this.openFilterKey === col.key) {
|
|
1477
|
+
this.closeColumnFilter();
|
|
1478
|
+
return
|
|
1479
|
+
}
|
|
1480
|
+
const target = event && event.currentTarget;
|
|
1481
|
+
this.filterAnchorRect = target && typeof target.getBoundingClientRect === 'function'
|
|
1482
|
+
? target.getBoundingClientRect()
|
|
1483
|
+
: null;
|
|
1484
|
+
this.openFilterKey = col.key;
|
|
1485
|
+
},
|
|
1486
|
+
|
|
1487
|
+
/**
|
|
1488
|
+
* Close the open panel and give focus back to its button.
|
|
1489
|
+
*
|
|
1490
|
+
* @return {void}
|
|
1491
|
+
*/
|
|
1492
|
+
closeColumnFilter() {
|
|
1493
|
+
const key = this.openFilterKey;
|
|
1494
|
+
this.openFilterKey = '';
|
|
1495
|
+
if (!key) {
|
|
1496
|
+
return
|
|
1497
|
+
}
|
|
1498
|
+
this.$nextTick(() => {
|
|
1499
|
+
const ref = this.$refs['filterButton-' + key];
|
|
1500
|
+
const button = Array.isArray(ref) ? ref[0] : ref;
|
|
1501
|
+
if (button && typeof button.focus === 'function') {
|
|
1502
|
+
button.focus();
|
|
1503
|
+
}
|
|
1504
|
+
});
|
|
1505
|
+
},
|
|
1506
|
+
|
|
1507
|
+
/**
|
|
1508
|
+
* Apply a panel's state: emit the query parameters it stands for.
|
|
1509
|
+
*
|
|
1510
|
+
* @param {object} col The column.
|
|
1511
|
+
* @param {object} state The panel state.
|
|
1512
|
+
* @return {void}
|
|
1513
|
+
* @spec openspec/changes/table-header-sort-and-filter/specs/cn-data-table/spec.md#requirement-a-header-filter-speaks-the-sidebars-query-language
|
|
1514
|
+
*/
|
|
1515
|
+
applyColumnFilter(col, state) {
|
|
1516
|
+
const def = this.filterDefFor(col);
|
|
1517
|
+
if (def) {
|
|
1518
|
+
/**
|
|
1519
|
+
* @event column-filter A header filter was applied or cleared.
|
|
1520
|
+
* @type {{ key: string, params: object }} `params` maps each query parameter the column owns to its values; an empty list clears it.
|
|
1521
|
+
*/
|
|
1522
|
+
this.$emit('column-filter', { key: col.key, params: columnFilterParams(def, state) });
|
|
1523
|
+
}
|
|
1524
|
+
this.closeColumnFilter();
|
|
1525
|
+
},
|
|
1526
|
+
|
|
1527
|
+
clearColumnFilter(col) {
|
|
1528
|
+
const def = this.filterDefFor(col);
|
|
1529
|
+
if (def) {
|
|
1530
|
+
this.$emit('column-filter', { key: col.key, params: clearedColumnFilterParams(def) });
|
|
1531
|
+
}
|
|
1532
|
+
},
|
|
1533
|
+
|
|
1290
1534
|
onHeaderClick(key, event) {
|
|
1291
1535
|
this.applySort(key, !!(event && event.shiftKey));
|
|
1292
1536
|
},
|