@conduction/nextcloud-vue 2.140.0 → 2.142.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.
Files changed (123) hide show
  1. package/dist/esm/components/CnAssignDialog/CnAssignDialog.vue.js +1 -1
  2. package/dist/esm/components/CnAssignDialog/CnAssignDialog.vue2.js +10 -2
  3. package/dist/esm/components/CnAssignDialog/CnAssignDialog.vue2.js.map +1 -1
  4. package/dist/esm/components/CnAssignDialog/CnAssignDialog.vue3.js.map +1 -1
  5. package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue.js +1 -1
  6. package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue2.js +24 -3
  7. package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue2.js.map +1 -1
  8. package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue3.js +3 -3
  9. package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue3.js.map +1 -1
  10. package/dist/esm/components/CnChartWidget/CnChartWidget.vue.js +1 -1
  11. package/dist/esm/components/CnChartWidget/CnChartWidget.vue2.js +12 -0
  12. package/dist/esm/components/CnChartWidget/CnChartWidget.vue2.js.map +1 -1
  13. package/dist/esm/components/CnChartWidget/CnChartWidget.vue3.js +57 -40
  14. package/dist/esm/components/CnChartWidget/CnChartWidget.vue3.js.map +1 -1
  15. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue.js +1 -1
  16. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js +1 -0
  17. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js.map +1 -1
  18. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue3.js.map +1 -1
  19. package/dist/esm/components/CnDataTable/CnDataTable.vue2.js +26 -3
  20. package/dist/esm/components/CnDataTable/CnDataTable.vue2.js.map +1 -1
  21. package/dist/esm/components/CnDataTable/CnDataTable.vue3.js +2 -1
  22. package/dist/esm/components/CnDataTable/CnDataTable.vue3.js.map +1 -1
  23. package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue.js +1 -1
  24. package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue2.js +34 -3
  25. package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue2.js.map +1 -1
  26. package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue3.js.map +1 -1
  27. package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue.js +1 -1
  28. package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue2.js +43 -3
  29. package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue2.js.map +1 -1
  30. package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue3.js +1 -1
  31. package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue3.js.map +1 -1
  32. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js +21 -1
  33. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js.map +1 -1
  34. package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js +2 -1
  35. package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js.map +1 -1
  36. package/dist/esm/components/CnIndexPage/useSelfFetchList.js +14 -0
  37. package/dist/esm/components/CnIndexPage/useSelfFetchList.js.map +1 -1
  38. package/dist/esm/components/CnIndexSidebar/CnIndexSidebar.vue2.js +65 -1
  39. package/dist/esm/components/CnIndexSidebar/CnIndexSidebar.vue2.js.map +1 -1
  40. package/dist/esm/components/CnIndexSidebar/CnIndexSidebar.vue3.js +120 -69
  41. package/dist/esm/components/CnIndexSidebar/CnIndexSidebar.vue3.js.map +1 -1
  42. package/dist/esm/components/CnMapWidget/CnMapWidget.vue.js +1 -1
  43. package/dist/esm/components/CnMapWidget/CnMapWidget.vue2.js +47 -9
  44. package/dist/esm/components/CnMapWidget/CnMapWidget.vue2.js.map +1 -1
  45. package/dist/esm/components/CnMapWidget/CnMapWidget.vue3.js.map +1 -1
  46. package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue.js +1 -1
  47. package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue2.js +3 -3
  48. package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue2.js.map +1 -1
  49. package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue3.js.map +1 -1
  50. package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue.js +1 -1
  51. package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue2.js +3 -1
  52. package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue2.js.map +1 -1
  53. package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue3.js +2 -1
  54. package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue3.js.map +1 -1
  55. package/dist/esm/components/CnPartyPicker/CnPartyPicker.vue.js +1 -1
  56. package/dist/esm/components/CnPartyPicker/CnPartyPicker.vue2.js +31 -1
  57. package/dist/esm/components/CnPartyPicker/CnPartyPicker.vue2.js.map +1 -1
  58. package/dist/esm/components/CnPartyPicker/CnPartyPicker.vue3.js.map +1 -1
  59. package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue.js +1 -1
  60. package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue2.js +2 -0
  61. package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue2.js.map +1 -1
  62. package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue3.js +1 -1
  63. package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue3.js.map +1 -1
  64. package/dist/esm/components/CnRecordListWidget/CnRecordNoteRows.vue.js +1 -1
  65. package/dist/esm/components/CnRecordListWidget/CnRecordNoteRows.vue2.js +10 -0
  66. package/dist/esm/components/CnRecordListWidget/CnRecordNoteRows.vue2.js.map +1 -1
  67. package/dist/esm/components/CnRecordListWidget/CnRecordNoteRows.vue3.js +34 -26
  68. package/dist/esm/components/CnRecordListWidget/CnRecordNoteRows.vue3.js.map +1 -1
  69. package/dist/esm/integrations/builtin/contacts/CnContactsTab.vue.js +1 -1
  70. package/dist/esm/integrations/builtin/contacts/CnContactsTab.vue2.js +52 -1
  71. package/dist/esm/integrations/builtin/contacts/CnContactsTab.vue2.js.map +1 -1
  72. package/dist/esm/integrations/builtin/contacts/CnContactsTab.vue3.js +119 -65
  73. package/dist/esm/integrations/builtin/contacts/CnContactsTab.vue3.js.map +1 -1
  74. package/dist/esm/integrations/builtin/deck/CnDeckCard.vue.js +1 -1
  75. package/dist/esm/integrations/builtin/deck/CnDeckCard.vue2.js +86 -4
  76. package/dist/esm/integrations/builtin/deck/CnDeckCard.vue2.js.map +1 -1
  77. package/dist/esm/integrations/builtin/deck/CnDeckCard.vue3.js +67 -5
  78. package/dist/esm/integrations/builtin/deck/CnDeckCard.vue3.js.map +1 -1
  79. package/dist/esm/l10n/en.json.js +11 -1
  80. package/dist/esm/l10n/en.json.js.map +1 -1
  81. package/dist/esm/l10n/nl.json.js +12 -2
  82. package/dist/esm/l10n/nl.json.js.map +1 -1
  83. package/dist/esm/library-style.js +1 -1
  84. package/dist/esm/nextcloud-vue.css +1116 -686
  85. package/dist/esm/utils/buildViewTree.js +23 -8
  86. package/dist/esm/utils/buildViewTree.js.map +1 -1
  87. package/dist/esm/utils/groupSublines.js +120 -0
  88. package/dist/esm/utils/groupSublines.js.map +1 -0
  89. package/dist/nextcloud-vue.cjs.js +2023 -1239
  90. package/dist/nextcloud-vue.cjs.js.map +2 -2
  91. package/dist/nextcloud-vue.css +1116 -686
  92. package/l10n/en.json +11 -1
  93. package/l10n/nl.json +12 -2
  94. package/package.json +1 -1
  95. package/src/components/CnAssignDialog/CnAssignDialog.vue +10 -2
  96. package/src/components/CnCellRenderer/CnCellRenderer.vue +26 -4
  97. package/src/components/CnChartWidget/CnChartWidget.md +1 -0
  98. package/src/components/CnChartWidget/CnChartWidget.vue +49 -4
  99. package/src/components/CnDashboardPage/CnDashboardPage.vue +1 -0
  100. package/src/components/CnDataTable/CnDataTable.md +1 -0
  101. package/src/components/CnDataTable/CnDataTable.vue +28 -4
  102. package/src/components/CnFactsWidget/CnFactsWidget.vue +34 -3
  103. package/src/components/CnFilesBrowser/CnFilesBrowser.vue +44 -4
  104. package/src/components/CnIndexPage/CnIndexPage.vue +22 -1
  105. package/src/components/CnIndexPage/useSelfFetchList.js +14 -0
  106. package/src/components/CnIndexSidebar/CnIndexSidebar.vue +101 -3
  107. package/src/components/CnMapWidget/CnMapWidget.vue +47 -9
  108. package/src/components/CnObjectListWidget/CnObjectListWidget.vue +3 -3
  109. package/src/components/CnObjectSidebar/CnFilesTab.vue +4 -1
  110. package/src/components/CnPartyPicker/CnPartyPicker.vue +31 -1
  111. package/src/components/CnRecordListWidget/CnRecordListWidget.vue +20 -1
  112. package/src/components/CnRecordListWidget/CnRecordNoteRows.vue +33 -9
  113. package/src/css/dialog.css +13 -1
  114. package/src/css/look-board-detail.css +107 -9
  115. package/src/css/look-board-index.css +143 -7
  116. package/src/css/look-board.css +109 -0
  117. package/src/css/table.css +12 -0
  118. package/src/integrations/builtin/contacts/CnContactsTab.vue +101 -26
  119. package/src/integrations/builtin/contacts/__tests__/CnContactsTabBoardRows.spec.js +67 -0
  120. package/src/integrations/builtin/deck/CnDeckCard.vue +121 -2
  121. package/src/integrations/builtin/deck/__tests__/CnDeckCardHeaderActions.spec.js +68 -0
  122. package/src/utils/buildViewTree.js +23 -8
  123. package/src/utils/groupSublines.js +125 -0
@@ -1 +1 @@
1
- {"version":3,"file":"CnIndexSidebar.vue3.js","sources":["../../../../src/components/CnIndexSidebar/CnIndexSidebar.vue?vue&type=template&id=1fa6a775&lang.js"],"sourcesContent":["<template>\n\t<NcAppSidebar\n\t\tref=\"appSidebar\"\n\t\tv-model:open=\"internalOpen\"\n\t\tclass=\"cn-index-sidebar-panel\"\n\t\t:name=\"resolvedName\"\n\t\t:title=\"resolvedName\"\n\t\t:subname=\"resolvedSubname\"\n\t\t:active=\"internalActiveTab\"\n\t\t:compact=\"!!resolvedIcon\"\n\t\t@close=\"$emit('update:open', false)\"\n\t\t@update:active=\"onTabChange\">\n\t\t<!-- Schema icon in sidebar header -->\n\t\t<template v-if=\"resolvedIcon\" #header>\n\t\t\t<div class=\"cn-index-sidebar__header-icon\">\n\t\t\t\t<CnIcon :name=\"resolvedIcon\" :size=\"32\" />\n\t\t\t</div>\n\t\t</template>\n\n\t\t<!-- Search Tab -->\n\t\t<NcAppSidebarTab\n\t\t\tid=\"search-tab\"\n\t\t\t:name=\"searchTabLabel\"\n\t\t\t:order=\"1\">\n\t\t\t<template #icon>\n\t\t\t\t<FilterOutline :size=\"20\" />\n\t\t\t</template>\n\n\t\t\t<div class=\"cn-index-sidebar__tab-content\">\n\t\t\t\t<div v-if=\"$slots['search-above']\" class=\"cn-index-sidebar__section\">\n\t\t\t\t\t<slot name=\"search-above\" />\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"cn-index-sidebar__section\">\n\t\t\t\t\t<!-- The board look names the field by its hint, as the list's\n\t\t\t\t\t own search field, with the magnifier (DqZakenSorteren). -->\n\t\t\t\t\t<NcTextField\n\t\t\t\t\t\t:modelValue=\"searchValue || ''\"\n\t\t\t\t\t\t:placeholder=\"searchPlaceholder\"\n\t\t\t\t\t\t:label=\"isBoardLook ? searchPlaceholder : searchLabel\"\n\t\t\t\t\t\t@update:modelValue=\"$emit('search', $event)\">\n\t\t\t\t\t\t<template v-if=\"isBoardLook\" #icon>\n\t\t\t\t\t\t\t<Magnify :size=\"18\" />\n\t\t\t\t\t\t</template>\n\t\t\t\t\t</NcTextField>\n\t\t\t\t</div>\n\n\t\t\t\t<!-- Sort (list, card and map views; the table sorts by its headers):\n\t\t\t\t the field, the direction and the order the list has now. -->\n\t\t\t\t<div v-if=\"sortOptions.length > 0\" class=\"cn-index-sidebar__section cn-index-sidebar__sort\" data-testid=\"cn-index-sidebar-sort\">\n\t\t\t\t\t<h3>{{ t('nextcloud-vue', 'Sort') }}</h3>\n\t\t\t\t\t<NcSelect\n\t\t\t\t\t\t:modelValue=\"sortSelected\"\n\t\t\t\t\t\t:options=\"sortOptions\"\n\t\t\t\t\t\tlabel=\"label\"\n\t\t\t\t\t\t:clearable=\"false\"\n\t\t\t\t\t\t:inputLabel=\"t('nextcloud-vue', 'Sort by')\"\n\t\t\t\t\t\t@update:modelValue=\"onSortField\" />\n\t\t\t\t\t<template v-if=\"isBoardLook\">\n\t\t\t\t\t\t<h4 :id=\"sortDirectionLabelId\" class=\"cn-index-sidebar__sort-direction-label\">\n\t\t\t\t\t\t\t{{ t('nextcloud-vue', 'Direction') }}\n\t\t\t\t\t\t</h4>\n\t\t\t\t\t\t<CnSegmentedControl\n\t\t\t\t\t\t\tclass=\"cn-index-sidebar__sort-direction-segments\"\n\t\t\t\t\t\t\tdata-testid=\"cn-index-sidebar-sort-direction-segments\"\n\t\t\t\t\t\t\tstretch\n\t\t\t\t\t\t\t:options=\"sortDirectionOptions\"\n\t\t\t\t\t\t\t:modelValue=\"sortDirection\"\n\t\t\t\t\t\t\t:ariaLabelledby=\"sortDirectionLabelId\"\n\t\t\t\t\t\t\t@update:modelValue=\"onSortDirection\">\n\t\t\t\t\t\t\t<template #option=\"{ option }\">\n\t\t\t\t\t\t\t\t<ArrowUp v-if=\"option.value === 'asc'\" :size=\"16\" />\n\t\t\t\t\t\t\t\t<ArrowDown v-else :size=\"16\" />\n\t\t\t\t\t\t\t\t<span class=\"cn-segmented-control__label\">{{ option.label }}</span>\n\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t</CnSegmentedControl>\n\t\t\t\t\t</template>\n\t\t\t\t\t<div v-else\n\t\t\t\t\t\tclass=\"cn-index-sidebar__sort-direction\"\n\t\t\t\t\t\trole=\"radiogroup\"\n\t\t\t\t\t\t:aria-label=\"t('nextcloud-vue', 'Direction')\">\n\t\t\t\t\t\t<NcCheckboxRadioSwitch\n\t\t\t\t\t\t\ttype=\"radio\"\n\t\t\t\t\t\t\tname=\"cn-index-sidebar-sort-direction\"\n\t\t\t\t\t\t\tvalue=\"asc\"\n\t\t\t\t\t\t\t:modelValue=\"sortDirection\"\n\t\t\t\t\t\t\t:disabled=\"!sortSelected || sortSelected.fixed === true\"\n\t\t\t\t\t\t\t@update:modelValue=\"onSortDirection\">\n\t\t\t\t\t\t\t{{ t('nextcloud-vue', 'Ascending') }}\n\t\t\t\t\t\t</NcCheckboxRadioSwitch>\n\t\t\t\t\t\t<NcCheckboxRadioSwitch\n\t\t\t\t\t\t\ttype=\"radio\"\n\t\t\t\t\t\t\tname=\"cn-index-sidebar-sort-direction\"\n\t\t\t\t\t\t\tvalue=\"desc\"\n\t\t\t\t\t\t\t:modelValue=\"sortDirection\"\n\t\t\t\t\t\t\t:disabled=\"!sortSelected || sortSelected.fixed === true\"\n\t\t\t\t\t\t\t@update:modelValue=\"onSortDirection\">\n\t\t\t\t\t\t\t{{ t('nextcloud-vue', 'Descending') }}\n\t\t\t\t\t\t</NcCheckboxRadioSwitch>\n\t\t\t\t\t</div>\n\t\t\t\t\t<p class=\"cn-index-sidebar__sort-current\" data-testid=\"cn-index-sidebar-sort-current\">\n\t\t\t\t\t\t{{ currentSortText }}\n\t\t\t\t\t</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div v-if=\"hasActiveFilters\" class=\"cn-index-sidebar__section\">\n\t\t\t\t\t<NcButton variant=\"tertiary\" @click=\"onClearAll\">\n\t\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t\t<FilterRemoveOutline :size=\"20\" />\n\t\t\t\t\t\t</template>\n\t\t\t\t\t\t{{ clearAllLabel }}\n\t\t\t\t\t</NcButton>\n\t\t\t\t</div>\n\n\t\t\t\t<div v-if=\"schemaFilters.length > 0\" class=\"cn-index-sidebar__section\">\n\t\t\t\t\t<h3>{{ filtersLabel }}</h3>\n\t\t\t\t\t<div\n\t\t\t\t\t\tv-for=\"filter in schemaFilters\"\n\t\t\t\t\t\t:key=\"filter.key\"\n\t\t\t\t\t\tclass=\"cn-index-sidebar__filter-group\">\n\t\t\t\t\t\t<div class=\"cn-index-sidebar__filter-header\">\n\t\t\t\t\t\t\t<span class=\"cn-index-sidebar__filter-label\">{{ filter.label }}</span>\n\t\t\t\t\t\t\t<NcPopover v-if=\"filter.description\" popupRole=\"dialog\">\n\t\t\t\t\t\t\t\t<template #trigger>\n\t\t\t\t\t\t\t\t\t<NcButton\n\t\t\t\t\t\t\t\t\t\tvariant=\"tertiary-no-background\"\n\t\t\t\t\t\t\t\t\t\t:aria-label=\"filter.label + ' info'\"\n\t\t\t\t\t\t\t\t\t\tclass=\"cn-index-sidebar__info-btn\">\n\t\t\t\t\t\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t\t\t\t\t\t<InformationOutline :size=\"16\" />\n\t\t\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t\t</NcButton>\n\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t<p class=\"cn-index-sidebar__filter-description\">\n\t\t\t\t\t\t\t\t\t{{ filter.description }}\n\t\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t\t</NcPopover>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<!-- A window, not a list of values: two bounds and a\n\t\t\t\t\t\t preset, emitted as the `{ from, to }` the range\n\t\t\t\t\t\t filters upstream are already spelled in. -->\n\t\t\t\t\t\t<CnDateRangePicker\n\t\t\t\t\t\t\tv-if=\"filter.type === 'date-range'\"\n\t\t\t\t\t\t\tclass=\"cn-index-sidebar__date-range\"\n\t\t\t\t\t\t\t:modelValue=\"getRangeValue(filter)\"\n\t\t\t\t\t\t\t:presets=\"filter.presets || rangePresets\"\n\t\t\t\t\t\t\t:fromLabel=\"filter.fromLabel || fromLabel\"\n\t\t\t\t\t\t\t:toLabel=\"filter.toLabel || toLabel\"\n\t\t\t\t\t\t\t:presetLabel=\"filter.label\"\n\t\t\t\t\t\t\t@update:modelValue=\"onRangeChange(filter.key, $event)\" />\n\t\t\t\t\t\t<NcTextField\n\t\t\t\t\t\t\tv-else-if=\"filter.type === 'text'\"\n\t\t\t\t\t\t\tclass=\"cn-index-sidebar__filter-text\"\n\t\t\t\t\t\t\t:modelValue=\"getTextValue(filter)\"\n\t\t\t\t\t\t\t:label=\"filter.label\"\n\t\t\t\t\t\t\t:placeholder=\"filter.label\"\n\t\t\t\t\t\t\t@update:modelValue=\"onTextChange(filter.key, $event)\" />\n\t\t\t\t\t\t<NcSelect\n\t\t\t\t\t\t\tv-else\n\t\t\t\t\t\t\tclass=\"cn-index-sidebar__select\"\n\t\t\t\t\t\t\t:modelValue=\"getSelectedFilterOptions(filter)\"\n\t\t\t\t\t\t\t:options=\"getFilterOptions(filter)\"\n\t\t\t\t\t\t\t:loading=\"isLoadingOptions(filter)\"\n\t\t\t\t\t\t\tplaceholder=\"Select...\"\n\t\t\t\t\t\t\t:inputLabel=\"filter.label\"\n\t\t\t\t\t\t\t:multiple=\"filter.multiple !== false\"\n\t\t\t\t\t\t\t:keepOpen=\"filter.multiple !== false\"\n\t\t\t\t\t\t\t:clearable=\"true\"\n\t\t\t\t\t\t\t@update:modelValue=\"onFilterChange(filter.key, $event)\" />\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<slot name=\"search-extra\" />\n\t\t\t</div>\n\t\t</NcAppSidebarTab>\n\n\t\t<!-- Columns Tab -->\n\t\t<NcAppSidebarTab\n\t\t\tid=\"columns-tab\"\n\t\t\t:name=\"columnsTabLabel\"\n\t\t\t:order=\"2\">\n\t\t\t<template #icon>\n\t\t\t\t<ViewColumnOutline :size=\"20\" />\n\t\t\t</template>\n\n\t\t\t<div class=\"cn-index-sidebar__tab-content\">\n\t\t\t\t<div class=\"cn-sidebar-columns\">\n\t\t\t\t\t<h3>{{ columnsHeading }}</h3>\n\t\t\t\t\t<p class=\"cn-sidebar-columns__description\">\n\t\t\t\t\t\t{{ columnsDescription }}\n\t\t\t\t\t</p>\n\n\t\t\t\t\t<!-- Order and pin the visible columns. Drag and the Move buttons\n\t\t\t\t\t call the same method (moveColumn); the table header is not a drag target. -->\n\t\t\t\t\t<div\n\t\t\t\t\t\tv-if=\"personalColumns && orderedVisible.length > 0\"\n\t\t\t\t\t\tclass=\"cn-sidebar-columns__order\"\n\t\t\t\t\t\tdata-testid=\"cn-sidebar-columns-order\">\n\t\t\t\t\t\t<h4>{{ t('nextcloud-vue', 'Order and pin') }}</h4>\n\t\t\t\t\t\t<ol class=\"cn-sidebar-columns__order-list\">\n\t\t\t\t\t\t\t<li\n\t\t\t\t\t\t\t\tv-for=\"(item, index) in orderedVisible\"\n\t\t\t\t\t\t\t\t:key=\"item.key\"\n\t\t\t\t\t\t\t\tclass=\"cn-sidebar-columns__order-item\"\n\t\t\t\t\t\t\t\t:class=\"{ 'cn-sidebar-columns__order-item--pinned': index < pinnedCount }\"\n\t\t\t\t\t\t\t\tdraggable=\"true\"\n\t\t\t\t\t\t\t\tdata-testid=\"cn-sidebar-columns-order-item\"\n\t\t\t\t\t\t\t\t@dragstart=\"dragFrom = index\"\n\t\t\t\t\t\t\t\t@dragover.prevent\n\t\t\t\t\t\t\t\t@drop.prevent=\"onDropColumn(index)\">\n\t\t\t\t\t\t\t\t<DragVertical :size=\"18\" class=\"cn-sidebar-columns__handle\" aria-hidden=\"true\" />\n\t\t\t\t\t\t\t\t<span class=\"cn-sidebar-columns__order-label\">{{ item.label }}</span>\n\t\t\t\t\t\t\t\t<NcButton\n\t\t\t\t\t\t\t\t\tvariant=\"tertiary\"\n\t\t\t\t\t\t\t\t\t:disabled=\"index === 0 || index === pinnedCount\"\n\t\t\t\t\t\t\t\t\t:aria-label=\"t('nextcloud-vue', 'Move {column} up', { column: item.label })\"\n\t\t\t\t\t\t\t\t\tdata-testid=\"cn-sidebar-columns-up\"\n\t\t\t\t\t\t\t\t\t@click=\"moveColumn(index, index - 1)\">\n\t\t\t\t\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t\t\t\t\t<ChevronUp :size=\"18\" />\n\t\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t</NcButton>\n\t\t\t\t\t\t\t\t<NcButton\n\t\t\t\t\t\t\t\t\tvariant=\"tertiary\"\n\t\t\t\t\t\t\t\t\t:disabled=\"index === orderedVisible.length - 1 || index === pinnedCount - 1\"\n\t\t\t\t\t\t\t\t\t:aria-label=\"t('nextcloud-vue', 'Move {column} down', { column: item.label })\"\n\t\t\t\t\t\t\t\t\tdata-testid=\"cn-sidebar-columns-down\"\n\t\t\t\t\t\t\t\t\t@click=\"moveColumn(index, index + 1)\">\n\t\t\t\t\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t\t\t\t\t<ChevronDown :size=\"18\" />\n\t\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t</NcButton>\n\t\t\t\t\t\t\t\t<NcButton\n\t\t\t\t\t\t\t\t\tvariant=\"tertiary\"\n\t\t\t\t\t\t\t\t\t:aria-pressed=\"String(index < pinnedCount)\"\n\t\t\t\t\t\t\t\t\t:aria-label=\"index < pinnedCount ? t('nextcloud-vue', 'Unpin {column}', { column: item.label }) : t('nextcloud-vue', 'Pin {column}', { column: item.label })\"\n\t\t\t\t\t\t\t\t\tdata-testid=\"cn-sidebar-columns-pin\"\n\t\t\t\t\t\t\t\t\t@click=\"togglePin(index)\">\n\t\t\t\t\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t\t\t\t\t<Pin v-if=\"index < pinnedCount\" :size=\"18\" />\n\t\t\t\t\t\t\t\t\t\t<PinOutline v-else :size=\"18\" />\n\t\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t</NcButton>\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t</ol>\n\t\t\t\t\t\t<NcButton\n\t\t\t\t\t\t\tvariant=\"tertiary\"\n\t\t\t\t\t\t\tdata-testid=\"cn-sidebar-columns-reset\"\n\t\t\t\t\t\t\t@click=\"$emit('columns-reset')\">\n\t\t\t\t\t\t\t{{ t('nextcloud-vue', 'Reset columns') }}\n\t\t\t\t\t\t</NcButton>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<template v-if=\"allColumns.length > 0 || allGroups.length > 0\">\n\t\t\t\t\t\t<!-- Schema properties group (collapsible) -->\n\t\t\t\t\t\t<div v-if=\"allColumns.length > 0\" class=\"cn-sidebar-columns__group cn-sidebar-columns__group--collapsible\">\n\t\t\t\t\t\t\t<div class=\"cn-sidebar-columns__group-header\" @click=\"propertiesExpanded = !propertiesExpanded\">\n\t\t\t\t\t\t\t\t<ChevronDown v-if=\"propertiesExpanded\" :size=\"20\" />\n\t\t\t\t\t\t\t\t<ChevronRight v-else :size=\"20\" />\n\t\t\t\t\t\t\t\t<h4>{{ resolvedPropertiesLabel }}</h4>\n\t\t\t\t\t\t\t\t<NcCheckboxRadioSwitch\n\t\t\t\t\t\t\t\t\t:modelValue=\"isGroupAllVisible(allColumns)\"\n\t\t\t\t\t\t\t\t\tclass=\"cn-sidebar-columns__select-all\"\n\t\t\t\t\t\t\t\t\t@click.stop\n\t\t\t\t\t\t\t\t\t@update:modelValue=\"toggleGroupAll(allColumns)\">\n\t\t\t\t\t\t\t\t\tAll\n\t\t\t\t\t\t\t\t</NcCheckboxRadioSwitch>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<div v-if=\"propertiesExpanded\" class=\"cn-sidebar-columns__group-content\">\n\t\t\t\t\t\t\t\t<NcCheckboxRadioSwitch\n\t\t\t\t\t\t\t\t\tv-for=\"col in allColumns\"\n\t\t\t\t\t\t\t\t\t:key=\"col.key\"\n\t\t\t\t\t\t\t\t\t:modelValue=\"isColumnVisible(col.key)\"\n\t\t\t\t\t\t\t\t\t@update:modelValue=\"toggleColumn(col.key)\">\n\t\t\t\t\t\t\t\t\t{{ col.label }}\n\t\t\t\t\t\t\t\t</NcCheckboxRadioSwitch>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t<!-- Extra column groups (built-in Metadata + external) -->\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tv-for=\"group in allGroups\"\n\t\t\t\t\t\t\t:key=\"group.id\"\n\t\t\t\t\t\t\tclass=\"cn-sidebar-columns__group cn-sidebar-columns__group--collapsible\">\n\t\t\t\t\t\t\t<div class=\"cn-sidebar-columns__group-header\" @click=\"toggleGroup(group.id)\">\n\t\t\t\t\t\t\t\t<ChevronDown v-if=\"expandedGroups[group.id]\" :size=\"20\" />\n\t\t\t\t\t\t\t\t<ChevronRight v-else :size=\"20\" />\n\t\t\t\t\t\t\t\t<h4 :lang=\"langOf(group.label)\">\n\t\t\t\t\t\t\t\t\t{{ shown(group.label) }}\n\t\t\t\t\t\t\t\t</h4>\n\t\t\t\t\t\t\t\t<NcCheckboxRadioSwitch\n\t\t\t\t\t\t\t\t\t:modelValue=\"isGroupAllVisible(group.columns)\"\n\t\t\t\t\t\t\t\t\tclass=\"cn-sidebar-columns__select-all\"\n\t\t\t\t\t\t\t\t\t@click.stop\n\t\t\t\t\t\t\t\t\t@update:modelValue=\"toggleGroupAll(group.columns)\">\n\t\t\t\t\t\t\t\t\tAll\n\t\t\t\t\t\t\t\t</NcCheckboxRadioSwitch>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<div v-if=\"expandedGroups[group.id]\" class=\"cn-sidebar-columns__group-content\">\n\t\t\t\t\t\t\t\t<NcCheckboxRadioSwitch\n\t\t\t\t\t\t\t\t\tv-for=\"col in group.columns\"\n\t\t\t\t\t\t\t\t\t:key=\"col.key\"\n\t\t\t\t\t\t\t\t\t:modelValue=\"isColumnVisible(col.key)\"\n\t\t\t\t\t\t\t\t\t@update:modelValue=\"toggleColumn(col.key)\">\n\t\t\t\t\t\t\t\t\t{{ shown(col.label) }}\n\t\t\t\t\t\t\t\t</NcCheckboxRadioSwitch>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</template>\n\n\t\t\t\t\t<p v-else class=\"cn-sidebar-columns__empty\">\n\t\t\t\t\t\tNo columns available. Provide a schema to auto-generate columns.\n\t\t\t\t\t</p>\n\t\t\t\t</div>\n\n\t\t\t\t<slot name=\"columns-extra\" />\n\t\t\t</div>\n\t\t</NcAppSidebarTab>\n\n\t\t<!-- Views tab (id filters-tab): the page's saved views (save, list, manage, add to menu). -->\n\t\t<NcAppSidebarTab\n\t\t\tv-if=\"savedViews\"\n\t\t\tid=\"filters-tab\"\n\t\t\t:name=\"t('nextcloud-vue', 'Views')\"\n\t\t\t:order=\"3\">\n\t\t\t<template #icon>\n\t\t\t\t<BookmarkOutline :size=\"20\" />\n\t\t\t</template>\n\n\t\t\t<div class=\"cn-index-sidebar__tab-content\">\n\t\t\t\t<div class=\"cn-index-sidebar__section\">\n\t\t\t\t\t<CnSavedViewsPanel\n\t\t\t\t\t\tv-bind=\"savedViewsPanelProps\"\n\t\t\t\t\t\t@apply=\"onSavedView('apply', $event)\"\n\t\t\t\t\t\t@saveRequest=\"onSavedView('save', null)\"\n\t\t\t\t\t\t@editRequest=\"onSavedView('edit', $event)\"\n\t\t\t\t\t\t@shareRequest=\"onSavedView('share', $event)\"\n\t\t\t\t\t\t@updateRequest=\"onSavedView('update', $event)\"\n\t\t\t\t\t\t@copyRequest=\"onSavedView('copy', $event)\"\n\t\t\t\t\t\t@menuToggle=\"onSavedView('menu', $event)\"\n\t\t\t\t\t\t@deleteRequest=\"onSavedView('delete', $event)\" />\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</NcAppSidebarTab>\n\n\t\t<!-- Extra tabs injected by the consumer -->\n\t\t<slot name=\"tabs\" />\n\t</NcAppSidebar>\n</template>\n\n<script>\nimport { translate as t } from '@nextcloud/l10n'\nimport { NcAppSidebar, NcAppSidebarTab, NcButton, NcCheckboxRadioSwitch, NcPopover, NcSelect, NcTextField } from '@nextcloud/vue'\nimport ArrowDown from 'vue-material-design-icons/ArrowDown.vue'\nimport ArrowUp from 'vue-material-design-icons/ArrowUp.vue'\nimport BookmarkOutline from 'vue-material-design-icons/BookmarkOutline.vue'\nimport ChevronDown from 'vue-material-design-icons/ChevronDown.vue'\nimport ChevronRight from 'vue-material-design-icons/ChevronRight.vue'\nimport ChevronUp from 'vue-material-design-icons/ChevronUp.vue'\nimport DragVertical from 'vue-material-design-icons/DragVertical.vue'\nimport FilterOutline from 'vue-material-design-icons/FilterOutline.vue'\nimport FilterRemoveOutline from 'vue-material-design-icons/FilterRemoveOutline.vue'\nimport InformationOutline from 'vue-material-design-icons/InformationOutline.vue'\nimport Magnify from 'vue-material-design-icons/Magnify.vue'\nimport Pin from 'vue-material-design-icons/Pin.vue'\nimport PinOutline from 'vue-material-design-icons/PinOutline.vue'\nimport ViewColumnOutline from 'vue-material-design-icons/ViewColumnOutline.vue'\nimport CnSavedViewsPanel from '../CnSavedViewsPanel/CnSavedViewsPanel.vue'\nimport CnSegmentedControl from '../CnSegmentedControl/CnSegmentedControl.vue'\nimport { normalizeLook } from '../../composables/useLook.js'\nimport { METADATA_COLUMNS } from '../../constants/metadata.js'\nimport { facetOptions } from '../../utils/facets.js'\nimport { labelLang } from '../../utils/manifestTranslate.js'\nimport { columnsFromSchema, filtersFromSchema } from '../../utils/schema.js'\n/**\n * CnIndexSidebar — Reusable NcAppSidebar wrapper with Search + Columns tabs.\n *\n * Designed to be schema-driven: pass a schema and the sidebar auto-generates\n * search filters, column visibility controls, and the standard Metadata group.\n * Title and properties group label are derived from schema.title by default.\n *\n * Must be rendered at the App.vue level as a sibling of NcAppContent.\n * Use provide/inject to connect it to page components.\n *\n * @slot search-above - Content rendered above the search field in the Search tab (e.g. hints, quick actions).\n * @slot search-extra - Content rendered below the search field and filters in the Search tab (e.g. saved searches).\n */\nimport { labelSidePanelClose } from '../../utils/sidePanelCloseLabel.js'\nimport { reverseSortKeys, sameSortKeys } from '../../utils/sortOrder.js'\nimport { CnDateRangePicker, DEFAULT_DATE_RANGE_PRESETS } from '../CnDateRangePicker/index.js'\nimport { CnIcon } from '../CnIcon/index.js'\nexport default {\n\tname: 'CnIndexSidebar',\n\n\tcomponents: {\n\t\tNcAppSidebar,\n\t\tNcAppSidebarTab,\n\t\tCnSavedViewsPanel,\n\t\tCnSegmentedControl,\n\t\tArrowDown,\n\t\tArrowUp,\n\t\tBookmarkOutline,\n\t\tNcTextField,\n\t\tNcSelect,\n\t\tCnDateRangePicker,\n\t\tNcCheckboxRadioSwitch,\n\t\tNcPopover,\n\t\tNcButton,\n\t\tCnIcon,\n\t\tFilterOutline,\n\t\tFilterRemoveOutline,\n\t\tViewColumnOutline,\n\t\tChevronDown,\n\t\tChevronRight,\n\t\tChevronUp,\n\t\tDragVertical,\n\t\tPin,\n\t\tPinOutline,\n\t\tInformationOutline,\n\t\tMagnify,\n\t},\n\n\tinject: {\n\t\t/**\n\t\t * Consumer translation function, provided by CnAppRoot as\n\t\t * `cnTranslate: this.translate` (bound to the host app's id). Column and\n\t\t * filter labels come from schema property titles, authored in English as\n\t\t * the canonical source; the visible label is resolved through this\n\t\t * function so it follows the user's language. Defaults to identity when\n\t\t * used standalone (no CnAppRoot ancestor).\n\t\t */\n\t\tcnTranslate: { default: () => (key) => key },\n\t\t/** The look CnAppRoot provides; the board look draws the direction as a segmented control. */\n\t\tcnLook: { default: 'nextcloud' },\n\t},\n\n\tprops: {\n\t\t/**\n\t\t * The line under the title, in place of the schema's description: the\n\t\t * page's count (\"48 zaken, 8 op deze pagina\", DqFilterBeheren).\n\t\t */\n\t\tsubtitle: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** Sidebar title. Defaults to schema.title when not set. */\n\t\ttitle: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** MDI icon name or emoji. Defaults to schema.icon when not set. */\n\t\ticon: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** Schema object for auto-generating filters, columns, and labels */\n\t\tschema: {\n\t\t\ttype: Object,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/** Array of currently visible column keys */\n\t\tvisibleColumns: {\n\t\t\ttype: Array,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * Show the Order and pin controls in the Columns tab, and Reset columns.\n\t\t * Off keeps show and hide only.\n\t\t */\n\t\tpersonalColumns: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: true,\n\t\t},\n\n\t\t/** How many of the first visible columns are pinned to the start of the table. */\n\t\tpinnedCount: {\n\t\t\ttype: Number,\n\t\t\tdefault: 0,\n\t\t},\n\n\t\t/**\n\t\t * The orders the Sort section offers, `[{ value, label, keys, fixed? }]`,\n\t\t * each `keys` a `[{ key, order }]` list read as its ascending form. An\n\t\t * option with `fixed: true` is an order of its own (the rows an endpoint\n\t\t * ranks): it is chosen by its value, has no direction, and its keys are\n\t\t * not matched against the current order. Empty draws no Sort section\n\t\t * (the table view sorts by its headers).\n\t\t */\n\t\tsortOptions: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/** The list's current order, `[{ key, order }]`. */\n\t\tcurrentSort: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/**\n\t\t * The Sort option chosen by its value, for an order that is not a list\n\t\t * of sort keys (an option with `fixed: true`, such as one whose rows an\n\t\t * endpoint ranks). Wins over matching `currentSort`.\n\t\t */\n\t\tcurrentSortValue: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** Current search term */\n\t\tsearchValue: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** Whether sidebar is open */\n\t\topen: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: true,\n\t\t},\n\n\t\t/** Current active facet filters: { fieldName: [values] } */\n\t\tactiveFilters: {\n\t\t\ttype: Object,\n\t\t\tdefault: () => ({}),\n\t\t},\n\n\t\t/** Live facet data from the API: `{ fieldName: { values: [{ value, count?, label? }] } }` */\n\t\tfacetData: {\n\t\t\ttype: Object,\n\t\t\tdefault: () => ({}),\n\t\t},\n\n\t\t/**\n\t\t * Additional column groups beyond schema properties and the built-in Metadata.\n\t\t * Each group: { id: string, label: string, columns: Array<{key, label}>, expanded?: boolean }\n\t\t */\n\t\tcolumnGroups: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/** Whether to include the built-in Metadata column group */\n\t\tshowMetadata: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: true,\n\t\t},\n\n\t\t/** Search input placeholder */\n\t\tsearchPlaceholder: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Type to search…'),\n\t\t},\n\n\t\t/** Search tab label */\n\t\tsearchTabLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Search'),\n\t\t},\n\n\t\t/** Columns tab label */\n\t\tcolumnsTabLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Columns'),\n\t\t},\n\n\t\t/** Search section heading */\n\t\tsearchLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Search'),\n\t\t},\n\n\t\t/** Filters section heading */\n\t\tfiltersLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Filters'),\n\t\t},\n\n\t\t/** \"Clear all\" button label, shown when search or a filter is active */\n\t\tclearAllLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Clear all'),\n\t\t},\n\n\t\t/**\n\t\t * Filter declarations for a page with no schema of its own: `{ name: declaration }`, the same shape a schema property has. Wins over `schema`, and feeds the Search tab only.\n\t\t *\n\t\t * 🔑 A FILTER IS NOT A COLUMN, which is the whole reason this is its\n\t\t * own prop rather than a synthetic `schema`. The schema feeds BOTH\n\t\t * tabs, so a page that declared its filters there would also offer\n\t\t * them in the Columns tab: the toggle would tick and no column would\n\t\t * appear, because the table's columns come from somewhere else\n\t\t * entirely. These reach the Search tab and nothing else.\n\t\t *\n\t\t * @type {object|null}\n\t\t */\n\t\tfilterFields: {\n\t\t\ttype: Object,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/** Start-of-window label on a date-range filter. */\n\t\tfromLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'From'),\n\t\t},\n\n\t\t/** End-of-window label on a date-range filter. */\n\t\ttoLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'To'),\n\t\t},\n\n\t\t/** Columns section heading */\n\t\tcolumnsHeading: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Column visibility'),\n\t\t},\n\n\t\t/** Columns section description */\n\t\tcolumnsDescription: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Select which columns to display in the table'),\n\t\t},\n\n\t\t/** Override label for the schema properties group. Defaults to schema.title. */\n\t\tpropertiesGroupLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * ID of the tab that should be active when the sidebar opens.\n\t\t * Built-in IDs are 'search-tab' and 'columns-tab'.\n\t\t * Use the id you set on your custom NcAppSidebarTab for custom tabs.\n\t\t */\n\t\tdefaultTab: {\n\t\t\ttype: String,\n\t\t\tdefault: 'search-tab',\n\t\t},\n\n\t\t/**\n\t\t * Switch to a tab while the sidebar is mounted, e.g. `'filters-tab'`\n\t\t * after a view was saved from the toolbar. Empty leaves the tab alone.\n\t\t */\n\t\tactiveTab: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * The page's saved views, shown in the Filters tab:\n\t\t * `{ views, loading, currentUserId, counts, selectedViewId, maxDepth, menuIds }`\n\t\t * as `CnSavedViewsPanel` takes them. `null` shows no saved views.\n\t\t * Every intent comes back as one `saved-view` event.\n\t\t */\n\t\tsavedViews: {\n\t\t\ttype: Object,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * Whether the current user is an admin.\n\t\t * When false, schema properties with `adminOnly: true` are hidden from filters.\n\t\t */\n\t\tuserIsAdmin: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: true,\n\t\t},\n\t},\n\n\temits: ['clear-filters', 'columns-change', 'columns-reorder', 'columns-reset', 'pin-change', 'filter-change', 'saved-view', 'search', 'sort-change', 'tab-change', 'update:open'],\n\n\tdata() {\n\t\treturn {\n\t\t\tinternalOpen: this.open,\n\t\t\tinternalActiveTab: this.defaultTab,\n\t\t\t/** Index of the column being dragged in the Order and pin list, or -1. */\n\t\t\tdragFrom: -1,\n\t\t\tpropertiesExpanded: true,\n\t\t\texpandedGroups: {},\n\t\t\t/**\n\t\t\t * Options loaded for a `reference` filter, keyed by field.\n\t\t\t *\n\t\t\t * A reference picker lists rows from ANOTHER list (the cases a\n\t\t\t * task can hang off, say), and neither the schema nor a facet\n\t\t\t * bucket carries them. Loaded once per field and cached, because\n\t\t\t * the sidebar re-renders on every keystroke in the search box.\n\t\t\t *\n\t\t\t * @type {Record<string, Array<{id: string, label: string}>>}\n\t\t\t */\n\t\t\treferenceOptions: {},\n\t\t\t/** @type {Record<string, boolean>} Which reference loads are in flight. */\n\t\t\treferenceLoading: {},\n\t\t}\n\t},\n\n\tcomputed: {\n\t\t/**\n\t\t * The Sort option the current order matches, as declared or reversed.\n\t\t *\n\t\t * @return {{option: object, direction: string}|null} The match, or null.\n\t\t */\n\t\tsortMatch() {\n\t\t\tif (this.currentSortValue) {\n\t\t\t\tconst chosen = this.sortOptions.find((o) => o.value === this.currentSortValue)\n\t\t\t\tif (chosen) {\n\t\t\t\t\treturn { option: chosen, direction: 'asc' }\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst current = Array.isArray(this.currentSort) ? this.currentSort : []\n\t\t\tfor (const option of this.sortOptions) {\n\t\t\t\tif (option.fixed === true) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tconst keys = Array.isArray(option.keys) ? option.keys : []\n\t\t\t\tif (sameSortKeys(keys, current)) {\n\t\t\t\t\treturn { option, direction: 'asc' }\n\t\t\t\t}\n\t\t\t\tif (sameSortKeys(reverseSortKeys(keys), current)) {\n\t\t\t\t\treturn { option, direction: 'desc' }\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn null\n\t\t},\n\n\t\t/** @return {object|null} The Sort option shown as chosen. */\n\t\tsortSelected() {\n\t\t\treturn this.sortMatch ? this.sortMatch.option : null\n\t\t},\n\n\t\t/** @return {string} The chosen direction, `asc` or `desc`. */\n\t\tsortDirection() {\n\t\t\treturn this.sortMatch ? this.sortMatch.direction : 'asc'\n\t\t},\n\n\t\t/**\n\t\t * Whether the board look applies.\n\t\t *\n\t\t * @return {boolean}\n\t\t */\n\t\tisBoardLook() {\n\t\t\tconst look = this.cnLook && typeof this.cnLook === 'object' && 'value' in this.cnLook ? this.cnLook.value : this.cnLook\n\t\t\treturn normalizeLook(look) === 'board'\n\t\t},\n\n\t\t/**\n\t\t * The two directions as segments, as board DqZakenSorteren draws them:\n\t\t * \"Oplopend\" and \"Aflopend\" with an arrow each.\n\t\t *\n\t\t * @spec openspec/changes/sidebar-sort-direction-segmented/specs/index-sidebar/spec.md#requirement-the-board-look-draws-the-sort-direction-as-two-segments\n\t\t * @return {Array<{value: string, label: string, disabled: boolean}>}\n\t\t */\n\t\tsortDirectionOptions() {\n\t\t\tconst disabled = !this.sortSelected || this.sortSelected.fixed === true\n\t\t\treturn [\n\t\t\t\t{ value: 'asc', label: t('nextcloud-vue', 'Ascending'), disabled },\n\t\t\t\t{ value: 'desc', label: t('nextcloud-vue', 'Descending'), disabled },\n\t\t\t]\n\t\t},\n\n\t\t/**\n\t\t * The id of the Direction heading that names the segments.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tsortDirectionLabelId() {\n\t\t\treturn `cn-index-sidebar-direction-${this.$.uid}`\n\t\t},\n\n\t\t/**\n\t\t * The order the list has now, in words: \"Current order: Created,\n\t\t * descending\" (\"Now: by created, descending.\" and that a view keeps\n\t\t * it, in the board look), or that it is not sorted.\n\t\t *\n\t\t * @return {string} The sentence.\n\t\t */\n\t\tcurrentSortText() {\n\t\t\t// The board look writes the order in running text, the field in\n\t\t\t// lower case: \"Now: by deadline, ascending.\" (DqZakenSorteren).\n\t\t\tconst name = (label) => (this.isBoardLook ? String(label).charAt(0).toLocaleLowerCase() + String(label).slice(1) : label)\n\t\t\tconst sentence = (order) => (this.isBoardLook\n\t\t\t\t? `${t('nextcloud-vue', 'Now: by {order}.', { order })} ${t('nextcloud-vue', 'You save the order along with a view.')}`\n\t\t\t\t: t('nextcloud-vue', 'Current order: {order}', { order }))\n\t\t\tif (this.sortMatch && this.sortMatch.option.fixed === true) {\n\t\t\t\treturn sentence(name(this.sortMatch.option.label))\n\t\t\t}\n\t\t\tconst current = Array.isArray(this.currentSort) ? this.currentSort : []\n\t\t\tif (current.length === 0) {\n\t\t\t\treturn t('nextcloud-vue', 'Not sorted')\n\t\t\t}\n\t\t\tconst labelOf = (key) => {\n\t\t\t\tconst single = this.sortOptions.find((o) => Array.isArray(o.keys) && o.keys.length === 1 && o.keys[0].key === key)\n\t\t\t\treturn name(single ? single.label : key)\n\t\t\t}\n\t\t\tconst order = this.sortMatch && this.sortMatch.option.keys.length > 1\n\t\t\t\t? `${name(this.sortMatch.option.label)}, ${this.sortDirection === 'desc' ? t('nextcloud-vue', 'descending') : t('nextcloud-vue', 'ascending')}`\n\t\t\t\t: current.map((entry) => `${labelOf(entry.key)}, ${entry.order === 'desc' ? t('nextcloud-vue', 'descending') : t('nextcloud-vue', 'ascending')}`).join('; ')\n\t\t\treturn sentence(order)\n\t\t},\n\n\t\t/**\n\t\t * The panel's props, from `savedViews`.\n\t\t *\n\t\t * @return {object}\n\t\t * @spec openspec/changes/saved-views-manage-and-defaults/tasks.md#task-6\n\t\t */\n\t\tsavedViewsPanelProps() {\n\t\t\tconst f = this.savedViews || {}\n\t\t\treturn {\n\t\t\t\tviews: Array.isArray(f.views) ? f.views : [],\n\t\t\t\tloading: f.loading === true,\n\t\t\t\tcurrentUserId: f.currentUserId || '',\n\t\t\t\tcounts: f.counts || null,\n\t\t\t\tselectedViewId: f.selectedViewId || '',\n\t\t\t\tmaxDepth: typeof f.maxDepth === 'number' ? f.maxDepth : 3,\n\t\t\t\tmenuIds: Array.isArray(f.menuIds) ? f.menuIds : null,\n\t\t\t\tsummaries: f.summaries && typeof f.summaries === 'object' ? f.summaries : null,\n\t\t\t}\n\t\t},\n\n\t\t/** Resolved icon — explicit prop overrides schema.icon */\n\t\tresolvedIcon() {\n\t\t\treturn this.icon || this.schema?.icon || ''\n\t\t},\n\n\t\t/** Sidebar name — schema title, shown as the h2 header */\n\t\tresolvedName() {\n\t\t\tif (this.title) {\n\t\t\t\treturn this.shown(this.title)\n\t\t\t}\n\t\t\treturn this.schema?.title || 'Search'\n\t\t},\n\n\t\t/** Sidebar subname: the subtitle the page hands it, else the schema description */\n\t\tresolvedSubname() {\n\t\t\tif (typeof this.subtitle === 'string' && this.subtitle !== '') {\n\t\t\t\treturn this.subtitle\n\t\t\t}\n\t\t\treturn this.schema?.description || ''\n\t\t},\n\n\t\t/** Properties group label — derived from schema.title if not explicitly set */\n\t\tresolvedPropertiesLabel() {\n\t\t\tif (this.propertiesGroupLabel) {\n\t\t\t\treturn this.propertiesGroupLabel\n\t\t\t}\n\t\t\treturn this.schema?.title || 'Properties'\n\t\t},\n\n\t\t/** All available columns from schema */\n\t\tallColumns() {\n\t\t\tif (!this.schema) {\n\t\t\t\treturn []\n\t\t\t}\n\t\t\treturn columnsFromSchema(this.schema, { translate: this.cnTranslate })\n\t\t},\n\n\t\t/** Filter definitions from schema (facetable properties, respecting RBAC) */\n\t\tschemaFilters() {\n\t\t\t// An explicitly declared filter set wins: it is the page saying\n\t\t\t// \"these are the questions\", where a schema only says \"these are\n\t\t\t// the properties\" and the sidebar has to guess which of them are\n\t\t\t// worth asking about.\n\t\t\tif (this.filterFields && Object.keys(this.filterFields).length > 0) {\n\t\t\t\treturn filtersFromSchema(\n\t\t\t\t\t{ properties: this.filterFields },\n\t\t\t\t\t{ isAdmin: this.userIsAdmin, translate: this.cnTranslate },\n\t\t\t\t)\n\t\t\t}\n\t\t\tif (!this.schema) {\n\t\t\t\treturn []\n\t\t\t}\n\t\t\treturn filtersFromSchema(this.schema, { isAdmin: this.userIsAdmin, translate: this.cnTranslate })\n\t\t},\n\n\t\t/** Whether a search term or any facet filter is currently active. */\n\t\thasActiveFilters() {\n\t\t\tif ((this.searchValue || '').length > 0) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\treturn Object.values(this.activeFilters || {}).some((v) => (Array.isArray(v) ? v.length > 0 : !!v))\n\t\t},\n\n\t\t/** Combined column groups: built-in Metadata + external groups */\n\t\tallGroups() {\n\t\t\tconst groups = []\n\t\t\tif (this.showMetadata && this.schema) {\n\t\t\t\tgroups.push({\n\t\t\t\t\tid: 'metadata',\n\t\t\t\t\tlabel: 'Metadata',\n\t\t\t\t\tcolumns: METADATA_COLUMNS,\n\t\t\t\t\texpanded: true,\n\t\t\t\t})\n\t\t\t}\n\t\t\treturn [...groups, ...this.columnGroups]\n\t\t},\n\n\t\t/** Label of each column key, from the schema properties and the groups. */\n\t\tcolumnLabels() {\n\t\t\tconst map = {}\n\t\t\tthis.allColumns.forEach((c) => {\n\t\t\t\tmap[c.key] = c.label\n\t\t\t})\n\t\t\tthis.allGroups.forEach((g) => g.columns.forEach((c) => {\n\t\t\t\tmap[c.key] = c.label\n\t\t\t}))\n\t\t\treturn map\n\t\t},\n\n\t\t/** The visible columns in their order, with labels (all columns when none were chosen). */\n\t\torderedVisible() {\n\t\t\tconst keys = this.visibleColumns === null ? this.allColumnKeys : this.visibleColumns\n\t\t\treturn keys.filter((k) => this.columnLabels[k] !== undefined).map((key) => ({ key, label: this.columnLabels[key] }))\n\t\t},\n\n\t\t/** All column keys across schema properties and all groups */\n\t\tallColumnKeys() {\n\t\t\treturn [\n\t\t\t\t...this.allColumns.map((c) => c.key),\n\t\t\t\t...this.allGroups.flatMap((g) => g.columns.map((c) => c.key)),\n\t\t\t]\n\t\t},\n\n\t\t/**\n\t\t * The presets a date-range filter offers when it declares none.\n\t\t *\n\t\t * Just `custom`. Every shipped preset rolls BACKWARDS from today\n\t\t * (\"Last 30 days\"), and a sidebar filter is as often a forward window\n\t\t * (\"due next week\") as a backward one. Offering a preset that answers\n\t\t * the wrong direction is worse than offering none: it is one click and\n\t\t * it looks deliberate.\n\t\t *\n\t\t * @return {Array<object>} The preset list.\n\t\t */\n\t\trangePresets() {\n\t\t\t// Taken FROM the picker's own list rather than written out again, so\n\t\t\t// the one preset a filter offers carries the same id and the same\n\t\t\t// label as everywhere else it appears.\n\t\t\treturn DEFAULT_DATE_RANGE_PRESETS\n\t\t\t\t.filter((preset) => preset.id === 'custom')\n\t\t\t\t.map((preset) => ({ ...preset }))\n\t\t},\n\t},\n\n\twatch: {\n\t\tactiveTab(tab) {\n\t\t\tif (tab) {\n\t\t\t\tthis.internalActiveTab = tab\n\t\t\t}\n\t\t},\n\n\t\topen(val) {\n\t\t\tthis.internalOpen = val\n\t\t},\n\n\t\tinternalOpen(val) {\n\t\t\tthis.$emit('update:open', val)\n\t\t},\n\n\t\tdefaultTab(val) {\n\t\t\tthis.internalActiveTab = val\n\t\t},\n\n\t\tallGroups: {\n\t\t\timmediate: true,\n\t\t\thandler(groups) {\n\t\t\t\tfor (const group of groups) {\n\t\t\t\t\tif (!(group.id in this.expandedGroups)) {\n\t\t\t\t\t\tthis.expandedGroups[group.id] = group.expanded !== false\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\n\t\t// A reference picker's rows load once the schema naming them arrives,\n\t\t// which on a manifest page is after mount. Watching the FILTERS rather\n\t\t// than calling from `mounted()` covers both orders.\n\t\tschemaFilters: {\n\t\t\timmediate: true,\n\t\t\thandler() {\n\t\t\t\tthis.loadReferenceOptions()\n\t\t\t},\n\t\t},\n\t},\n\n\tmounted() {\n\t\tlabelSidePanelClose(this.$refs.appSidebar)\n\t},\n\n\tmethods: {\n\t\tt,\n\n\t\t/**\n\t\t * A field chosen in the Sort section: its order, in the direction\n\t\t * already chosen.\n\t\t *\n\t\t * @param {object|null} option The chosen option.\n\t\t * @return {void}\n\t\t */\n\t\tonSortField(option) {\n\t\t\tconst chosen = option && this.sortOptions.find((o) => o.value === option.value)\n\t\t\tif (!chosen) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.emitSort(chosen, this.sortDirection)\n\t\t},\n\n\t\t/**\n\t\t * A direction chosen in the Sort section, for the chosen field.\n\t\t *\n\t\t * @param {string} direction `asc` or `desc`.\n\t\t * @return {void}\n\t\t */\n\t\tonSortDirection(direction) {\n\t\t\tif (!this.sortSelected) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.emitSort(this.sortSelected, direction === 'desc' ? 'desc' : 'asc')\n\t\t},\n\n\t\t/**\n\t\t * Emit the order an option stands for in a direction.\n\t\t *\n\t\t * @param {object} option The Sort option.\n\t\t * @param {string} direction `asc` or `desc`.\n\t\t * @return {void}\n\t\t */\n\t\temitSort(option, direction) {\n\t\t\tconst keys = Array.isArray(option.keys) ? option.keys : []\n\t\t\t/**\n\t\t\t * @event sort-change The Sort section chose an order. Payload: `[{ key, order }]`,\n\t\t\t * and the chosen option's value, which names an order that is not keys (`fixed`).\n\t\t\t */\n\t\t\tthis.$emit('sort-change', direction === 'desc' ? reverseSortKeys(keys) : keys.map((k) => ({ key: k.key, order: k.order || 'asc' })), option.value)\n\t\t},\n\n\t\t/**\n\t\t * Hand a saved-view intent to the page.\n\t\t *\n\t\t * @param {'apply'|'save'|'edit'|'share'|'presentation'|'update'|'copy'|'menu'|'delete'} action The intent.\n\t\t * @param {object|null} view The view, or null for save.\n\t\t * @spec openspec/changes/saved-views-manage-and-defaults/tasks.md#task-6\n\t\t */\n\t\tonSavedView(action, view) {\n\t\t\t/**\n\t\t\t * @event saved-view A saved-view intent from the Filters tab. Payload: `{ action, view }`.\n\t\t\t * @type {{action: string, view: (object|null)}}\n\t\t\t */\n\t\t\tthis.$emit('saved-view', { action, view })\n\t\t},\n\n\t\t/**\n\t\t * A manifest label through the injected lookup, or as written.\n\t\t *\n\t\t * @param {string} text The label as written.\n\t\t * @return {string} The label in the user's language.\n\t\t */\n\t\tshown(text) {\n\t\t\treturn typeof this.cnTranslate === 'function' && typeof text === 'string' && text !== '' ? this.cnTranslate(text) : text\n\t\t},\n\n\t\t/**\n\t\t * The `lang` of a label that fell back to its written text in another language.\n\t\t *\n\t\t * @param {string} text The label as written.\n\t\t * @return {string|undefined} The source language, or undefined.\n\t\t */\n\t\tlangOf(text) {\n\t\t\treturn labelLang(this.cnTranslate, text) || undefined\n\t\t},\n\n\t\t/**\n\t\t * Handle tab change from NcAppSidebar\n\t\t *\n\t\t * @param {string} tabId Tab identifier\n\t\t */\n\t\tonTabChange(tabId) {\n\t\t\tthis.internalActiveTab = tabId\n\t\t\tthis.$emit('tab-change', tabId)\n\t\t},\n\n\t\t/**\n\t\t * Check if a column is currently visible\n\t\t *\n\t\t * @param {string} key Column key\n\t\t */\n\t\tisColumnVisible(key) {\n\t\t\tif (this.visibleColumns === null) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\treturn this.visibleColumns.includes(key)\n\t\t},\n\n\t\t/**\n\t\t * Check if all columns in a group are visible\n\t\t *\n\t\t * @param {string[]} columns Array of column keys\n\t\t */\n\t\tisGroupAllVisible(columns) {\n\t\t\treturn columns.every((col) => this.isColumnVisible(col.key))\n\t\t},\n\n\t\t/**\n\t\t * Toggle a single column's visibility\n\t\t *\n\t\t * @param {string} key Column key\n\t\t */\n\t\ttoggleColumn(key) {\n\t\t\tlet newVisible\n\t\t\tif (this.visibleColumns === null) {\n\t\t\t\tnewVisible = this.allColumnKeys.filter((k) => k !== key)\n\t\t\t} else if (this.isColumnVisible(key)) {\n\t\t\t\tnewVisible = this.visibleColumns.filter((k) => k !== key)\n\t\t\t} else {\n\t\t\t\tnewVisible = [...this.visibleColumns, key]\n\t\t\t}\n\t\t\tthis.$emit('columns-change', newVisible)\n\t\t},\n\n\t\t/**\n\t\t * Select or deselect all columns in a group\n\t\t *\n\t\t * @param {string[]} columns Array of column keys\n\t\t */\n\t\ttoggleGroupAll(columns) {\n\t\t\tconst groupKeys = columns.map((c) => c.key)\n\t\t\tconst allVisible = this.isGroupAllVisible(columns)\n\n\t\t\tlet newVisible\n\t\t\tif (this.visibleColumns === null) {\n\t\t\t\t// Currently all visible — deselect this group\n\t\t\t\tnewVisible = this.allColumnKeys.filter((k) => !groupKeys.includes(k))\n\t\t\t} else if (allVisible) {\n\t\t\t\t// All in group visible — deselect them\n\t\t\t\tnewVisible = this.visibleColumns.filter((k) => !groupKeys.includes(k))\n\t\t\t} else {\n\t\t\t\t// Not all visible — select them all\n\t\t\t\tconst current = new Set(this.visibleColumns)\n\t\t\t\tgroupKeys.forEach((k) => current.add(k))\n\t\t\t\tnewVisible = [...current]\n\t\t\t}\n\t\t\tthis.$emit('columns-change', newVisible)\n\t\t},\n\n\t\t/**\n\t\t * Move a visible column to another place in the order. The drag and the\n\t\t * Move buttons both call this. A column stays inside its block: pinned\n\t\t * columns move among the pinned, the rest among the rest.\n\t\t *\n\t\t * @param {number} from Current index.\n\t\t * @param {number} to Target index.\n\t\t * @return {void}\n\t\t */\n\t\tmoveColumn(from, to) {\n\t\t\tconst list = this.orderedVisible.map((c) => c.key)\n\t\t\tconst lo = from < this.pinnedCount ? 0 : this.pinnedCount\n\t\t\tconst hi = from < this.pinnedCount ? this.pinnedCount - 1 : list.length - 1\n\t\t\tconst target = Math.min(hi, Math.max(lo, to))\n\t\t\tif (from < 0 || from >= list.length || target === from) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst [moved] = list.splice(from, 1)\n\t\t\tlist.splice(target, 0, moved)\n\t\t\t/**\n\t\t\t * @event columns-reorder Emitted when the user moves a column. Payload: the visible column keys in their new order.\n\t\t\t * @type {string[]}\n\t\t\t */\n\t\t\tthis.$emit('columns-reorder', list)\n\t\t},\n\n\t\t/**\n\t\t * Dropping a dragged column on another row.\n\t\t *\n\t\t * @param {number} index Index of the row it was dropped on.\n\t\t * @return {void}\n\t\t */\n\t\tonDropColumn(index) {\n\t\t\tconst from = this.dragFrom\n\t\t\tthis.dragFrom = -1\n\t\t\tif (from >= 0) {\n\t\t\t\tthis.moveColumn(from, index)\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Pin a column (it joins the pinned block at the start) or unpin it (it\n\t\t * leaves that block, to the first place after it).\n\t\t *\n\t\t * @param {number} index Index of the column.\n\t\t * @return {void}\n\t\t */\n\t\ttogglePin(index) {\n\t\t\tconst list = this.orderedVisible.map((c) => c.key)\n\t\t\tconst [moved] = list.splice(index, 1)\n\t\t\tlet count = this.pinnedCount\n\t\t\tif (index < count) {\n\t\t\t\tcount -= 1\n\t\t\t\tlist.splice(count, 0, moved)\n\t\t\t} else {\n\t\t\t\tlist.splice(count, 0, moved)\n\t\t\t\tcount += 1\n\t\t\t}\n\t\t\tthis.$emit('columns-reorder', list)\n\t\t\t/**\n\t\t\t * @event pin-change Emitted when a column is pinned or unpinned. Payload: the new number of pinned columns.\n\t\t\t * @type {number}\n\t\t\t */\n\t\t\tthis.$emit('pin-change', count)\n\t\t},\n\n\t\t/**\n\t\t * Toggle a group's expanded state\n\t\t *\n\t\t * @param {string} groupId Filter group identifier\n\t\t */\n\t\ttoggleGroup(groupId) {\n\t\t\tthis.expandedGroups[groupId] = !this.expandedGroups[groupId]\n\t\t},\n\n\t\t/**\n\t\t * Get filter options for a filter definition\n\t\t *\n\t\t * @param {object} filter Filter object\n\t\t */\n\t\tgetFilterOptions(filter) {\n\t\t\tconst live = facetOptions(\n\t\t\t\tthis.facetData[filter.key],\n\t\t\t\t(count) => t('nextcloud-vue', 'No value ({count})', { count }),\n\t\t\t)\n\t\t\tif (live !== null) {\n\t\t\t\treturn live\n\t\t\t}\n\t\t\t// A reference picker's rows come from another list, and neither a\n\t\t\t// schema enum nor a facet bucket can carry them.\n\t\t\tif (filter.type === 'reference') {\n\t\t\t\treturn this.referenceOptions[filter.key] || []\n\t\t\t}\n\t\t\treturn filter.options || []\n\t\t},\n\n\t\t/**\n\t\t * Whether a reference filter is still fetching its rows.\n\t\t *\n\t\t * Shown rather than hidden: an empty picker that is still loading and\n\t\t * one that genuinely has nothing to pick look identical, and only one\n\t\t * of them means the person should stop waiting.\n\t\t *\n\t\t * @param {object} filter The filter definition.\n\t\t *\n\t\t * @return {boolean} True while the load is in flight.\n\t\t */\n\t\tisLoadingOptions(filter) {\n\t\t\treturn this.referenceLoading[filter.key] === true\n\t\t},\n\n\t\t/**\n\t\t * The `{ from, to }` window a date-range filter currently holds.\n\t\t *\n\t\t * @param {object} filter The filter definition.\n\t\t *\n\t\t * @return {object|null} The window, or null when none is set.\n\t\t */\n\t\tgetRangeValue(filter) {\n\t\t\tconst value = this.activeFilters[filter.key]\n\t\t\tif (value && typeof value === 'object' && !Array.isArray(value)) {\n\t\t\t\treturn value\n\t\t\t}\n\t\t\treturn null\n\t\t},\n\n\t\t/**\n\t\t * A date-range filter changed.\n\t\t *\n\t\t * Emitted in the SAME `filter-change` shape every other control uses,\n\t\t * with the window as the payload's `values`, so a consumer has one\n\t\t * event to listen to and not two.\n\t\t *\n\t\t * @param {string} key The filter key.\n\t\t * @param {object|null} window The `{ from, to, preset }` value.\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tonRangeChange(key, window) {\n\t\t\tconst from = (window && window.from) || ''\n\t\t\tconst to = (window && window.to) || ''\n\t\t\tif (from === '' && to === '') {\n\t\t\t\tthis.$emit('filter-change', { key, values: [] })\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.$emit('filter-change', { key, values: { from, to } })\n\t\t},\n\n\t\t/**\n\t\t * The text a `text` filter currently holds.\n\t\t *\n\t\t * @param {object} filter The filter definition.\n\t\t *\n\t\t * @return {string} The current value.\n\t\t */\n\t\tgetTextValue(filter) {\n\t\t\tconst value = this.activeFilters[filter.key]\n\t\t\tif (Array.isArray(value)) {\n\t\t\t\treturn value.length > 0 ? String(value[0]) : ''\n\t\t\t}\n\t\t\treturn (value === undefined || value === null) ? '' : String(value)\n\t\t},\n\n\t\t/**\n\t\t * A text filter changed.\n\t\t *\n\t\t * @param {string} key The filter key.\n\t\t * @param {string} value The typed value.\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tonTextChange(key, value) {\n\t\t\tconst text = String(value ?? '').trim()\n\t\t\tthis.$emit('filter-change', { key, values: text === '' ? [] : [text] })\n\t\t},\n\n\t\t/**\n\t\t * Load the rows a `reference` filter picks from.\n\t\t *\n\t\t * Reads `optionsSource` off the schema property:\n\t\t * `{ register, schema, labelField, valueField, limit }`. The VALUE is\n\t\t * the referenced object's uuid, because that is what the server\n\t\t * filters on; the label is only what the person reads.\n\t\t *\n\t\t * Failures are logged and leave the picker empty rather than throwing:\n\t\t * one unreachable list must not take the whole sidebar with it.\n\t\t *\n\t\t * @return {Promise<void>} Resolves when every reference filter settled.\n\t\t */\n\t\tasync loadReferenceOptions() {\n\t\t\tconst pending = this.schemaFilters.filter((filter) => filter.type === 'reference'\n\t\t\t\t&& filter.optionsSource\n\t\t\t\t&& this.referenceOptions[filter.key] === undefined\n\t\t\t\t&& this.referenceLoading[filter.key] !== true)\n\t\t\tif (pending.length === 0) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tconst [{ default: axios }, { generateUrl }] = await Promise.all([\n\t\t\t\timport('@nextcloud/axios'),\n\t\t\t\timport('@nextcloud/router'),\n\t\t\t])\n\n\t\t\tawait Promise.all(pending.map(async (filter) => {\n\t\t\t\tconst source = filter.optionsSource\n\t\t\t\tif (!source.register || !source.schema) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tthis.referenceLoading = { ...this.referenceLoading, [filter.key]: true }\n\t\t\t\ttry {\n\t\t\t\t\tconst url = generateUrl('/apps/openregister/api/objects/{register}/{schema}', {\n\t\t\t\t\t\tregister: source.register,\n\t\t\t\t\t\tschema: source.schema,\n\t\t\t\t\t})\n\t\t\t\t\tconst response = await axios.get(url, { params: { _limit: source.limit || 200 } })\n\t\t\t\t\tconst rows = response?.data?.results || response?.data || []\n\t\t\t\t\tconst valueField = source.valueField || '@self.uuid'\n\t\t\t\t\tconst labelField = source.labelField || 'title'\n\t\t\t\t\tconst options = rows\n\t\t\t\t\t\t.map((row) => ({\n\t\t\t\t\t\t\tid: this.readPath(row, valueField),\n\t\t\t\t\t\t\tlabel: String(this.readPath(row, labelField) ?? this.readPath(row, valueField) ?? ''),\n\t\t\t\t\t\t}))\n\t\t\t\t\t\t.filter((option) => option.id !== null && option.id !== undefined && option.id !== '')\n\t\t\t\t\t\t.sort((a, b) => a.label.localeCompare(b.label))\n\t\t\t\t\tthis.referenceOptions = { ...this.referenceOptions, [filter.key]: options }\n\t\t\t\t} catch (error) {\n\t\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\t\tconsole.error(`[CnIndexSidebar] the reference filter \"${filter.key}\" could not load its options`, error)\n\t\t\t\t\tthis.referenceOptions = { ...this.referenceOptions, [filter.key]: [] }\n\t\t\t\t} finally {\n\t\t\t\t\tthis.referenceLoading = { ...this.referenceLoading, [filter.key]: false }\n\t\t\t\t}\n\t\t\t}))\n\t\t},\n\n\t\t/**\n\t\t * Read a dotted path off a row (`@self.uuid`, `title`).\n\t\t *\n\t\t * @param {object} row The row.\n\t\t * @param {string} path The dotted path.\n\t\t *\n\t\t * @return {unknown} The value, or undefined.\n\t\t */\n\t\treadPath(row, path) {\n\t\t\treturn String(path).split('.').reduce((acc, part) => ((acc === null || acc === undefined) ? acc : acc[part]), row)\n\t\t},\n\n\t\t/**\n\t\t * Get currently selected options for a filter\n\t\t *\n\t\t * @param {object} filter Filter object\n\t\t */\n\t\tgetSelectedFilterOptions(filter) {\n\t\t\tconst value = this.activeFilters[filter.key]\n\t\t\tif (!value) {\n\t\t\t\treturn []\n\t\t\t}\n\t\t\tconst values = Array.isArray(value) ? value : [value]\n\t\t\tconst options = this.getFilterOptions(filter)\n\t\t\treturn values.map((v) => options.find((o) => o.id === v) || { id: v, label: String(v) })\n\t\t},\n\n\t\t/**\n\t\t * Handle filter select change\n\t\t *\n\t\t * @param {string} key Filter key\n\t\t * @param {Array} selected Selected values\n\t\t */\n\t\tonFilterChange(key, selected) {\n\t\t\t// 🔴 A SINGLE-VALUED SELECT EMITS AN OBJECT, NOT AN ARRAY. NcSelect\n\t\t\t// changes the SHAPE of its payload with `multiple`, and `.map` on\n\t\t\t// the object shape throws inside an event handler, where Vue logs\n\t\t\t// it and carries on: the picker looks inert and the console says\n\t\t\t// why in a place nobody is looking.\n\t\t\tconst chosen = Array.isArray(selected) ? selected : (selected ? [selected] : [])\n\t\t\tconst values = chosen.map((o) => ((o && typeof o === 'object' && 'id' in o) ? o.id : o))\n\t\t\tthis.$emit('filter-change', { key, values })\n\t\t},\n\n\t\t/**\n\t\t * \"Clear all\" click: reset search and every active facet filter in\n\t\t * one shot, so the parent does one fetch instead of one per field.\n\t\t */\n\t\tonClearAll() {\n\t\t\t/**\n\t\t\t * @event clear-filters \"Clear all\" clicked; reset search and every active filter.\n\t\t\t */\n\t\t\tthis.$emit('clear-filters')\n\t\t},\n\t},\n}\n</script>\n\n<!-- Styles in css/index-sidebar.css -->\n"],"names":["_createBlock","_createVNode","_createElementVNode","_openBlock","_createElementBlock","_renderSlot","_Fragment","_withCtx","_toDisplayString","_createTextVNode","_renderList","_normalizeClass","_withModifiers","_mergeProps"],"mappings":"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"}
1
+ {"version":3,"file":"CnIndexSidebar.vue3.js","sources":["../../../../src/components/CnIndexSidebar/CnIndexSidebar.vue?vue&type=template&id=abd3b3ba&lang.js"],"sourcesContent":["<template>\n\t<NcAppSidebar\n\t\tref=\"appSidebar\"\n\t\tv-model:open=\"internalOpen\"\n\t\tclass=\"cn-index-sidebar-panel\"\n\t\t:name=\"resolvedName\"\n\t\t:title=\"resolvedName\"\n\t\t:subname=\"resolvedSubname\"\n\t\t:active=\"internalActiveTab\"\n\t\t:compact=\"!!resolvedIcon\"\n\t\t@close=\"$emit('update:open', false)\"\n\t\t@update:active=\"onTabChange\">\n\t\t<!-- Schema icon in sidebar header -->\n\t\t<template v-if=\"resolvedIcon\" #header>\n\t\t\t<div class=\"cn-index-sidebar__header-icon\">\n\t\t\t\t<CnIcon :name=\"resolvedIcon\" :size=\"32\" />\n\t\t\t</div>\n\t\t</template>\n\n\t\t<!-- Search Tab -->\n\t\t<NcAppSidebarTab\n\t\t\tid=\"search-tab\"\n\t\t\t:name=\"searchTabLabel\"\n\t\t\t:order=\"1\">\n\t\t\t<template #icon>\n\t\t\t\t<FilterOutline :size=\"20\" />\n\t\t\t</template>\n\n\t\t\t<div class=\"cn-index-sidebar__tab-content\">\n\t\t\t\t<div v-if=\"$slots['search-above']\" class=\"cn-index-sidebar__section\">\n\t\t\t\t\t<slot name=\"search-above\" />\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"cn-index-sidebar__section\">\n\t\t\t\t\t<!-- The board look names the field by its hint, as the list's\n\t\t\t\t\t own search field, with the magnifier (DqZakenSorteren). -->\n\t\t\t\t\t<NcTextField\n\t\t\t\t\t\t:modelValue=\"searchValue || ''\"\n\t\t\t\t\t\t:placeholder=\"searchPlaceholder\"\n\t\t\t\t\t\t:label=\"isBoardLook ? searchPlaceholder : searchLabel\"\n\t\t\t\t\t\t@update:modelValue=\"$emit('search', $event)\">\n\t\t\t\t\t\t<template v-if=\"isBoardLook\" #icon>\n\t\t\t\t\t\t\t<Magnify :size=\"18\" />\n\t\t\t\t\t\t</template>\n\t\t\t\t\t</NcTextField>\n\t\t\t\t</div>\n\n\t\t\t\t<!-- Sort (list, card and map views; the table sorts by its headers):\n\t\t\t\t the field, the direction and the order the list has now. -->\n\t\t\t\t<div v-if=\"sortOptions.length > 0\" class=\"cn-index-sidebar__section cn-index-sidebar__sort\" data-testid=\"cn-index-sidebar-sort\">\n\t\t\t\t\t<h3>{{ t('nextcloud-vue', 'Sort') }}</h3>\n\t\t\t\t\t<NcSelect\n\t\t\t\t\t\t:modelValue=\"sortSelected\"\n\t\t\t\t\t\t:options=\"sortOptions\"\n\t\t\t\t\t\tlabel=\"label\"\n\t\t\t\t\t\t:clearable=\"false\"\n\t\t\t\t\t\t:inputLabel=\"t('nextcloud-vue', 'Sort by')\"\n\t\t\t\t\t\t@update:modelValue=\"onSortField\" />\n\t\t\t\t\t<template v-if=\"isBoardLook\">\n\t\t\t\t\t\t<h4 :id=\"sortDirectionLabelId\" class=\"cn-index-sidebar__sort-direction-label\">\n\t\t\t\t\t\t\t{{ t('nextcloud-vue', 'Direction') }}\n\t\t\t\t\t\t</h4>\n\t\t\t\t\t\t<CnSegmentedControl\n\t\t\t\t\t\t\tclass=\"cn-index-sidebar__sort-direction-segments\"\n\t\t\t\t\t\t\tdata-testid=\"cn-index-sidebar-sort-direction-segments\"\n\t\t\t\t\t\t\tstretch\n\t\t\t\t\t\t\t:options=\"sortDirectionOptions\"\n\t\t\t\t\t\t\t:modelValue=\"sortDirection\"\n\t\t\t\t\t\t\t:ariaLabelledby=\"sortDirectionLabelId\"\n\t\t\t\t\t\t\t@update:modelValue=\"onSortDirection\">\n\t\t\t\t\t\t\t<template #option=\"{ option }\">\n\t\t\t\t\t\t\t\t<ArrowUp v-if=\"option.value === 'asc'\" :size=\"16\" />\n\t\t\t\t\t\t\t\t<ArrowDown v-else :size=\"16\" />\n\t\t\t\t\t\t\t\t<span class=\"cn-segmented-control__label\">{{ option.label }}</span>\n\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t</CnSegmentedControl>\n\t\t\t\t\t</template>\n\t\t\t\t\t<div v-else\n\t\t\t\t\t\tclass=\"cn-index-sidebar__sort-direction\"\n\t\t\t\t\t\trole=\"radiogroup\"\n\t\t\t\t\t\t:aria-label=\"t('nextcloud-vue', 'Direction')\">\n\t\t\t\t\t\t<NcCheckboxRadioSwitch\n\t\t\t\t\t\t\ttype=\"radio\"\n\t\t\t\t\t\t\tname=\"cn-index-sidebar-sort-direction\"\n\t\t\t\t\t\t\tvalue=\"asc\"\n\t\t\t\t\t\t\t:modelValue=\"sortDirection\"\n\t\t\t\t\t\t\t:disabled=\"!sortSelected || sortSelected.fixed === true\"\n\t\t\t\t\t\t\t@update:modelValue=\"onSortDirection\">\n\t\t\t\t\t\t\t{{ t('nextcloud-vue', 'Ascending') }}\n\t\t\t\t\t\t</NcCheckboxRadioSwitch>\n\t\t\t\t\t\t<NcCheckboxRadioSwitch\n\t\t\t\t\t\t\ttype=\"radio\"\n\t\t\t\t\t\t\tname=\"cn-index-sidebar-sort-direction\"\n\t\t\t\t\t\t\tvalue=\"desc\"\n\t\t\t\t\t\t\t:modelValue=\"sortDirection\"\n\t\t\t\t\t\t\t:disabled=\"!sortSelected || sortSelected.fixed === true\"\n\t\t\t\t\t\t\t@update:modelValue=\"onSortDirection\">\n\t\t\t\t\t\t\t{{ t('nextcloud-vue', 'Descending') }}\n\t\t\t\t\t\t</NcCheckboxRadioSwitch>\n\t\t\t\t\t</div>\n\t\t\t\t\t<p class=\"cn-index-sidebar__sort-current\" data-testid=\"cn-index-sidebar-sort-current\">\n\t\t\t\t\t\t{{ currentSortText }}\n\t\t\t\t\t</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div v-if=\"hasActiveFilters && !isBoardLook\" class=\"cn-index-sidebar__section\">\n\t\t\t\t\t<NcButton variant=\"tertiary\" @click=\"onClearAll\">\n\t\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t\t<FilterRemoveOutline :size=\"20\" />\n\t\t\t\t\t\t</template>\n\t\t\t\t\t\t{{ clearAllLabel }}\n\t\t\t\t\t</NcButton>\n\t\t\t\t</div>\n\n\t\t\t\t<div v-if=\"schemaFilters.length > 0\" class=\"cn-index-sidebar__section\">\n\t\t\t\t\t<!-- The board look: \"Alles wissen\" beside the heading (DqZakenSorteren). -->\n\t\t\t\t\t<div v-if=\"isBoardLook\" class=\"cn-index-sidebar__filters-head\" data-testid=\"cn-index-sidebar-filters-head\">\n\t\t\t\t\t\t<h3>{{ filtersLabel }}</h3>\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\tv-if=\"hasActiveFilters\"\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclass=\"cn-index-sidebar__filters-clear\"\n\t\t\t\t\t\t\t@click=\"onClearAll\">\n\t\t\t\t\t\t\t{{ clearAllLabel }}\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</div>\n\t\t\t\t\t<h3 v-else>\n\t\t\t\t\t\t{{ filtersLabel }}\n\t\t\t\t\t</h3>\n\t\t\t\t\t<div\n\t\t\t\t\t\tv-for=\"filter in schemaFilters\"\n\t\t\t\t\t\t:key=\"filter.key\"\n\t\t\t\t\t\tclass=\"cn-index-sidebar__filter-group\">\n\t\t\t\t\t\t<div class=\"cn-index-sidebar__filter-header\">\n\t\t\t\t\t\t\t<span class=\"cn-index-sidebar__filter-label\">{{ filter.label }}</span>\n\t\t\t\t\t\t\t<NcPopover v-if=\"filter.description\" popupRole=\"dialog\">\n\t\t\t\t\t\t\t\t<template #trigger>\n\t\t\t\t\t\t\t\t\t<NcButton\n\t\t\t\t\t\t\t\t\t\tvariant=\"tertiary-no-background\"\n\t\t\t\t\t\t\t\t\t\t:aria-label=\"filter.label + ' info'\"\n\t\t\t\t\t\t\t\t\t\tclass=\"cn-index-sidebar__info-btn\">\n\t\t\t\t\t\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t\t\t\t\t\t<InformationOutline :size=\"16\" />\n\t\t\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t\t</NcButton>\n\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t<p class=\"cn-index-sidebar__filter-description\">\n\t\t\t\t\t\t\t\t\t{{ filter.description }}\n\t\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t\t</NcPopover>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<!-- A window, not a list of values: two bounds and a\n\t\t\t\t\t\t preset, emitted as the `{ from, to }` the range\n\t\t\t\t\t\t filters upstream are already spelled in. -->\n\t\t\t\t\t\t<CnDateRangePicker\n\t\t\t\t\t\t\tv-if=\"filter.type === 'date-range'\"\n\t\t\t\t\t\t\tclass=\"cn-index-sidebar__date-range\"\n\t\t\t\t\t\t\t:modelValue=\"getRangeValue(filter)\"\n\t\t\t\t\t\t\t:presets=\"filter.presets || rangePresets\"\n\t\t\t\t\t\t\t:fromLabel=\"filter.fromLabel || fromLabel\"\n\t\t\t\t\t\t\t:toLabel=\"filter.toLabel || toLabel\"\n\t\t\t\t\t\t\t:presetLabel=\"filter.label\"\n\t\t\t\t\t\t\t@update:modelValue=\"onRangeChange(filter.key, $event)\" />\n\t\t\t\t\t\t<NcTextField\n\t\t\t\t\t\t\tv-else-if=\"filter.type === 'text'\"\n\t\t\t\t\t\t\tclass=\"cn-index-sidebar__filter-text\"\n\t\t\t\t\t\t\t:modelValue=\"getTextValue(filter)\"\n\t\t\t\t\t\t\t:label=\"filter.label\"\n\t\t\t\t\t\t\t:placeholder=\"filter.label\"\n\t\t\t\t\t\t\t@update:modelValue=\"onTextChange(filter.key, $event)\" />\n\t\t\t\t\t\t<!-- The board look: a short field as checkbox rows with counts. -->\n\t\t\t\t\t\t<fieldset\n\t\t\t\t\t\t\tv-else-if=\"checklistOptions(filter)\"\n\t\t\t\t\t\t\tclass=\"cn-index-sidebar__checklist\"\n\t\t\t\t\t\t\t:data-testid=\"`cn-index-sidebar-checklist-${filter.key}`\">\n\t\t\t\t\t\t\t<legend class=\"hidden-visually\">\n\t\t\t\t\t\t\t\t{{ filter.label }}\n\t\t\t\t\t\t\t</legend>\n\t\t\t\t\t\t\t<label\n\t\t\t\t\t\t\t\tv-for=\"option in checklistOptions(filter)\"\n\t\t\t\t\t\t\t\t:key=\"`${filter.key}-${option.id}`\"\n\t\t\t\t\t\t\t\tclass=\"cn-index-sidebar__checklist-row\"\n\t\t\t\t\t\t\t\tdata-testid=\"cn-index-sidebar-checklist-row\">\n\t\t\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\t\t\t\t\t:checked=\"isChecked(filter, option.id)\"\n\t\t\t\t\t\t\t\t\t@change=\"onChecklistToggle(filter, option.id, $event.target.checked)\">\n\t\t\t\t\t\t\t\t<span class=\"cn-index-sidebar__checklist-label\">{{ option.label }}</span>\n\t\t\t\t\t\t\t\t<span v-if=\"option.count !== null\" class=\"cn-index-sidebar__checklist-count\">{{ option.count }}</span>\n\t\t\t\t\t\t\t</label>\n\t\t\t\t\t\t</fieldset>\n\t\t\t\t\t\t<NcSelect\n\t\t\t\t\t\t\tv-else\n\t\t\t\t\t\t\tclass=\"cn-index-sidebar__select\"\n\t\t\t\t\t\t\t:modelValue=\"getSelectedFilterOptions(filter)\"\n\t\t\t\t\t\t\t:options=\"getFilterOptions(filter)\"\n\t\t\t\t\t\t\t:loading=\"isLoadingOptions(filter)\"\n\t\t\t\t\t\t\tplaceholder=\"Select...\"\n\t\t\t\t\t\t\t:inputLabel=\"filter.label\"\n\t\t\t\t\t\t\t:multiple=\"filter.multiple !== false\"\n\t\t\t\t\t\t\t:keepOpen=\"filter.multiple !== false\"\n\t\t\t\t\t\t\t:clearable=\"true\"\n\t\t\t\t\t\t\t@update:modelValue=\"onFilterChange(filter.key, $event)\" />\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<slot name=\"search-extra\" />\n\t\t\t</div>\n\t\t</NcAppSidebarTab>\n\n\t\t<!-- Columns Tab -->\n\t\t<NcAppSidebarTab\n\t\t\tid=\"columns-tab\"\n\t\t\t:name=\"columnsTabLabel\"\n\t\t\t:order=\"2\">\n\t\t\t<template #icon>\n\t\t\t\t<ViewColumnOutline :size=\"20\" />\n\t\t\t</template>\n\n\t\t\t<div class=\"cn-index-sidebar__tab-content\">\n\t\t\t\t<div class=\"cn-sidebar-columns\">\n\t\t\t\t\t<h3>{{ columnsHeading }}</h3>\n\t\t\t\t\t<p class=\"cn-sidebar-columns__description\">\n\t\t\t\t\t\t{{ columnsDescription }}\n\t\t\t\t\t</p>\n\n\t\t\t\t\t<!-- Order and pin the visible columns. Drag and the Move buttons\n\t\t\t\t\t call the same method (moveColumn); the table header is not a drag target. -->\n\t\t\t\t\t<div\n\t\t\t\t\t\tv-if=\"personalColumns && orderedVisible.length > 0\"\n\t\t\t\t\t\tclass=\"cn-sidebar-columns__order\"\n\t\t\t\t\t\tdata-testid=\"cn-sidebar-columns-order\">\n\t\t\t\t\t\t<h4>{{ t('nextcloud-vue', 'Order and pin') }}</h4>\n\t\t\t\t\t\t<ol class=\"cn-sidebar-columns__order-list\">\n\t\t\t\t\t\t\t<li\n\t\t\t\t\t\t\t\tv-for=\"(item, index) in orderedVisible\"\n\t\t\t\t\t\t\t\t:key=\"item.key\"\n\t\t\t\t\t\t\t\tclass=\"cn-sidebar-columns__order-item\"\n\t\t\t\t\t\t\t\t:class=\"{ 'cn-sidebar-columns__order-item--pinned': index < pinnedCount }\"\n\t\t\t\t\t\t\t\tdraggable=\"true\"\n\t\t\t\t\t\t\t\tdata-testid=\"cn-sidebar-columns-order-item\"\n\t\t\t\t\t\t\t\t@dragstart=\"dragFrom = index\"\n\t\t\t\t\t\t\t\t@dragover.prevent\n\t\t\t\t\t\t\t\t@drop.prevent=\"onDropColumn(index)\">\n\t\t\t\t\t\t\t\t<DragVertical :size=\"18\" class=\"cn-sidebar-columns__handle\" aria-hidden=\"true\" />\n\t\t\t\t\t\t\t\t<span class=\"cn-sidebar-columns__order-label\">{{ item.label }}</span>\n\t\t\t\t\t\t\t\t<NcButton\n\t\t\t\t\t\t\t\t\tvariant=\"tertiary\"\n\t\t\t\t\t\t\t\t\t:disabled=\"index === 0 || index === pinnedCount\"\n\t\t\t\t\t\t\t\t\t:aria-label=\"t('nextcloud-vue', 'Move {column} up', { column: item.label })\"\n\t\t\t\t\t\t\t\t\tdata-testid=\"cn-sidebar-columns-up\"\n\t\t\t\t\t\t\t\t\t@click=\"moveColumn(index, index - 1)\">\n\t\t\t\t\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t\t\t\t\t<ChevronUp :size=\"18\" />\n\t\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t</NcButton>\n\t\t\t\t\t\t\t\t<NcButton\n\t\t\t\t\t\t\t\t\tvariant=\"tertiary\"\n\t\t\t\t\t\t\t\t\t:disabled=\"index === orderedVisible.length - 1 || index === pinnedCount - 1\"\n\t\t\t\t\t\t\t\t\t:aria-label=\"t('nextcloud-vue', 'Move {column} down', { column: item.label })\"\n\t\t\t\t\t\t\t\t\tdata-testid=\"cn-sidebar-columns-down\"\n\t\t\t\t\t\t\t\t\t@click=\"moveColumn(index, index + 1)\">\n\t\t\t\t\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t\t\t\t\t<ChevronDown :size=\"18\" />\n\t\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t</NcButton>\n\t\t\t\t\t\t\t\t<NcButton\n\t\t\t\t\t\t\t\t\tvariant=\"tertiary\"\n\t\t\t\t\t\t\t\t\t:aria-pressed=\"String(index < pinnedCount)\"\n\t\t\t\t\t\t\t\t\t:aria-label=\"index < pinnedCount ? t('nextcloud-vue', 'Unpin {column}', { column: item.label }) : t('nextcloud-vue', 'Pin {column}', { column: item.label })\"\n\t\t\t\t\t\t\t\t\tdata-testid=\"cn-sidebar-columns-pin\"\n\t\t\t\t\t\t\t\t\t@click=\"togglePin(index)\">\n\t\t\t\t\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t\t\t\t\t<Pin v-if=\"index < pinnedCount\" :size=\"18\" />\n\t\t\t\t\t\t\t\t\t\t<PinOutline v-else :size=\"18\" />\n\t\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t</NcButton>\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t</ol>\n\t\t\t\t\t\t<NcButton\n\t\t\t\t\t\t\tvariant=\"tertiary\"\n\t\t\t\t\t\t\tdata-testid=\"cn-sidebar-columns-reset\"\n\t\t\t\t\t\t\t@click=\"$emit('columns-reset')\">\n\t\t\t\t\t\t\t{{ t('nextcloud-vue', 'Reset columns') }}\n\t\t\t\t\t\t</NcButton>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<template v-if=\"allColumns.length > 0 || allGroups.length > 0\">\n\t\t\t\t\t\t<!-- Schema properties group (collapsible) -->\n\t\t\t\t\t\t<div v-if=\"allColumns.length > 0\" class=\"cn-sidebar-columns__group cn-sidebar-columns__group--collapsible\">\n\t\t\t\t\t\t\t<div class=\"cn-sidebar-columns__group-header\" @click=\"propertiesExpanded = !propertiesExpanded\">\n\t\t\t\t\t\t\t\t<ChevronDown v-if=\"propertiesExpanded\" :size=\"20\" />\n\t\t\t\t\t\t\t\t<ChevronRight v-else :size=\"20\" />\n\t\t\t\t\t\t\t\t<h4>{{ resolvedPropertiesLabel }}</h4>\n\t\t\t\t\t\t\t\t<NcCheckboxRadioSwitch\n\t\t\t\t\t\t\t\t\t:modelValue=\"isGroupAllVisible(allColumns)\"\n\t\t\t\t\t\t\t\t\tclass=\"cn-sidebar-columns__select-all\"\n\t\t\t\t\t\t\t\t\t@click.stop\n\t\t\t\t\t\t\t\t\t@update:modelValue=\"toggleGroupAll(allColumns)\">\n\t\t\t\t\t\t\t\t\tAll\n\t\t\t\t\t\t\t\t</NcCheckboxRadioSwitch>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<div v-if=\"propertiesExpanded\" class=\"cn-sidebar-columns__group-content\">\n\t\t\t\t\t\t\t\t<NcCheckboxRadioSwitch\n\t\t\t\t\t\t\t\t\tv-for=\"col in allColumns\"\n\t\t\t\t\t\t\t\t\t:key=\"col.key\"\n\t\t\t\t\t\t\t\t\t:modelValue=\"isColumnVisible(col.key)\"\n\t\t\t\t\t\t\t\t\t@update:modelValue=\"toggleColumn(col.key)\">\n\t\t\t\t\t\t\t\t\t{{ col.label }}\n\t\t\t\t\t\t\t\t</NcCheckboxRadioSwitch>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t<!-- Extra column groups (built-in Metadata + external) -->\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tv-for=\"group in allGroups\"\n\t\t\t\t\t\t\t:key=\"group.id\"\n\t\t\t\t\t\t\tclass=\"cn-sidebar-columns__group cn-sidebar-columns__group--collapsible\">\n\t\t\t\t\t\t\t<div class=\"cn-sidebar-columns__group-header\" @click=\"toggleGroup(group.id)\">\n\t\t\t\t\t\t\t\t<ChevronDown v-if=\"expandedGroups[group.id]\" :size=\"20\" />\n\t\t\t\t\t\t\t\t<ChevronRight v-else :size=\"20\" />\n\t\t\t\t\t\t\t\t<h4 :lang=\"langOf(group.label)\">\n\t\t\t\t\t\t\t\t\t{{ shown(group.label) }}\n\t\t\t\t\t\t\t\t</h4>\n\t\t\t\t\t\t\t\t<NcCheckboxRadioSwitch\n\t\t\t\t\t\t\t\t\t:modelValue=\"isGroupAllVisible(group.columns)\"\n\t\t\t\t\t\t\t\t\tclass=\"cn-sidebar-columns__select-all\"\n\t\t\t\t\t\t\t\t\t@click.stop\n\t\t\t\t\t\t\t\t\t@update:modelValue=\"toggleGroupAll(group.columns)\">\n\t\t\t\t\t\t\t\t\tAll\n\t\t\t\t\t\t\t\t</NcCheckboxRadioSwitch>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<div v-if=\"expandedGroups[group.id]\" class=\"cn-sidebar-columns__group-content\">\n\t\t\t\t\t\t\t\t<NcCheckboxRadioSwitch\n\t\t\t\t\t\t\t\t\tv-for=\"col in group.columns\"\n\t\t\t\t\t\t\t\t\t:key=\"col.key\"\n\t\t\t\t\t\t\t\t\t:modelValue=\"isColumnVisible(col.key)\"\n\t\t\t\t\t\t\t\t\t@update:modelValue=\"toggleColumn(col.key)\">\n\t\t\t\t\t\t\t\t\t{{ shown(col.label) }}\n\t\t\t\t\t\t\t\t</NcCheckboxRadioSwitch>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</template>\n\n\t\t\t\t\t<p v-else class=\"cn-sidebar-columns__empty\">\n\t\t\t\t\t\tNo columns available. Provide a schema to auto-generate columns.\n\t\t\t\t\t</p>\n\t\t\t\t</div>\n\n\t\t\t\t<slot name=\"columns-extra\" />\n\t\t\t</div>\n\t\t</NcAppSidebarTab>\n\n\t\t<!-- Views tab (id filters-tab): the page's saved views (save, list, manage, add to menu). -->\n\t\t<NcAppSidebarTab\n\t\t\tv-if=\"savedViews\"\n\t\t\tid=\"filters-tab\"\n\t\t\t:name=\"t('nextcloud-vue', 'Views')\"\n\t\t\t:order=\"3\">\n\t\t\t<template #icon>\n\t\t\t\t<BookmarkOutline :size=\"20\" />\n\t\t\t</template>\n\n\t\t\t<div class=\"cn-index-sidebar__tab-content\">\n\t\t\t\t<div class=\"cn-index-sidebar__section\">\n\t\t\t\t\t<CnSavedViewsPanel\n\t\t\t\t\t\tv-bind=\"savedViewsPanelProps\"\n\t\t\t\t\t\t@apply=\"onSavedView('apply', $event)\"\n\t\t\t\t\t\t@saveRequest=\"onSavedView('save', null)\"\n\t\t\t\t\t\t@editRequest=\"onSavedView('edit', $event)\"\n\t\t\t\t\t\t@shareRequest=\"onSavedView('share', $event)\"\n\t\t\t\t\t\t@updateRequest=\"onSavedView('update', $event)\"\n\t\t\t\t\t\t@copyRequest=\"onSavedView('copy', $event)\"\n\t\t\t\t\t\t@menuToggle=\"onSavedView('menu', $event)\"\n\t\t\t\t\t\t@deleteRequest=\"onSavedView('delete', $event)\" />\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</NcAppSidebarTab>\n\n\t\t<!-- Extra tabs injected by the consumer -->\n\t\t<slot name=\"tabs\" />\n\t</NcAppSidebar>\n</template>\n\n<script>\nimport { translate as t } from '@nextcloud/l10n'\nimport { NcAppSidebar, NcAppSidebarTab, NcButton, NcCheckboxRadioSwitch, NcPopover, NcSelect, NcTextField } from '@nextcloud/vue'\nimport ArrowDown from 'vue-material-design-icons/ArrowDown.vue'\nimport ArrowUp from 'vue-material-design-icons/ArrowUp.vue'\nimport BookmarkOutline from 'vue-material-design-icons/BookmarkOutline.vue'\nimport ChevronDown from 'vue-material-design-icons/ChevronDown.vue'\nimport ChevronRight from 'vue-material-design-icons/ChevronRight.vue'\nimport ChevronUp from 'vue-material-design-icons/ChevronUp.vue'\nimport DragVertical from 'vue-material-design-icons/DragVertical.vue'\nimport FilterOutline from 'vue-material-design-icons/FilterOutline.vue'\nimport FilterRemoveOutline from 'vue-material-design-icons/FilterRemoveOutline.vue'\nimport InformationOutline from 'vue-material-design-icons/InformationOutline.vue'\nimport Magnify from 'vue-material-design-icons/Magnify.vue'\nimport Pin from 'vue-material-design-icons/Pin.vue'\nimport PinOutline from 'vue-material-design-icons/PinOutline.vue'\nimport ViewColumnOutline from 'vue-material-design-icons/ViewColumnOutline.vue'\nimport CnSavedViewsPanel from '../CnSavedViewsPanel/CnSavedViewsPanel.vue'\nimport CnSegmentedControl from '../CnSegmentedControl/CnSegmentedControl.vue'\nimport { normalizeLook } from '../../composables/useLook.js'\nimport { METADATA_COLUMNS } from '../../constants/metadata.js'\nimport { facetOptions, MISSING_VALUE } from '../../utils/facets.js'\nimport { labelLang } from '../../utils/manifestTranslate.js'\nimport { columnsFromSchema, filtersFromSchema } from '../../utils/schema.js'\n/**\n * CnIndexSidebar — Reusable NcAppSidebar wrapper with Search + Columns tabs.\n *\n * Designed to be schema-driven: pass a schema and the sidebar auto-generates\n * search filters, column visibility controls, and the standard Metadata group.\n * Title and properties group label are derived from schema.title by default.\n *\n * Must be rendered at the App.vue level as a sibling of NcAppContent.\n * Use provide/inject to connect it to page components.\n *\n * @slot search-above - Content rendered above the search field in the Search tab (e.g. hints, quick actions).\n * @slot search-extra - Content rendered below the search field and filters in the Search tab (e.g. saved searches).\n */\nimport { labelSidePanelClose } from '../../utils/sidePanelCloseLabel.js'\nimport { reverseSortKeys, sameSortKeys } from '../../utils/sortOrder.js'\nimport { CnDateRangePicker, DEFAULT_DATE_RANGE_PRESETS } from '../CnDateRangePicker/index.js'\nimport { CnIcon } from '../CnIcon/index.js'\n/** The most values a filter shows as checkbox rows in the board look; a longer field keeps its picker. */\nconst CHECKLIST_MAX = 12\n\nexport default {\n\tname: 'CnIndexSidebar',\n\n\tcomponents: {\n\t\tNcAppSidebar,\n\t\tNcAppSidebarTab,\n\t\tCnSavedViewsPanel,\n\t\tCnSegmentedControl,\n\t\tArrowDown,\n\t\tArrowUp,\n\t\tBookmarkOutline,\n\t\tNcTextField,\n\t\tNcSelect,\n\t\tCnDateRangePicker,\n\t\tNcCheckboxRadioSwitch,\n\t\tNcPopover,\n\t\tNcButton,\n\t\tCnIcon,\n\t\tFilterOutline,\n\t\tFilterRemoveOutline,\n\t\tViewColumnOutline,\n\t\tChevronDown,\n\t\tChevronRight,\n\t\tChevronUp,\n\t\tDragVertical,\n\t\tPin,\n\t\tPinOutline,\n\t\tInformationOutline,\n\t\tMagnify,\n\t},\n\n\tinject: {\n\t\t/**\n\t\t * Consumer translation function, provided by CnAppRoot as\n\t\t * `cnTranslate: this.translate` (bound to the host app's id). Column and\n\t\t * filter labels come from schema property titles, authored in English as\n\t\t * the canonical source; the visible label is resolved through this\n\t\t * function so it follows the user's language. Defaults to identity when\n\t\t * used standalone (no CnAppRoot ancestor).\n\t\t */\n\t\tcnTranslate: { default: () => (key) => key },\n\t\t/** The look CnAppRoot provides; the board look draws the direction as a segmented control. */\n\t\tcnLook: { default: 'nextcloud' },\n\t},\n\n\tprops: {\n\t\t/**\n\t\t * The line under the title, in place of the schema's description: the\n\t\t * page's count (\"48 zaken, 8 op deze pagina\", DqFilterBeheren).\n\t\t */\n\t\tsubtitle: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** Sidebar title. Defaults to schema.title when not set. */\n\t\ttitle: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** MDI icon name or emoji. Defaults to schema.icon when not set. */\n\t\ticon: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** Schema object for auto-generating filters, columns, and labels */\n\t\tschema: {\n\t\t\ttype: Object,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/** Array of currently visible column keys */\n\t\tvisibleColumns: {\n\t\t\ttype: Array,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * Show the Order and pin controls in the Columns tab, and Reset columns.\n\t\t * Off keeps show and hide only.\n\t\t */\n\t\tpersonalColumns: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: true,\n\t\t},\n\n\t\t/** How many of the first visible columns are pinned to the start of the table. */\n\t\tpinnedCount: {\n\t\t\ttype: Number,\n\t\t\tdefault: 0,\n\t\t},\n\n\t\t/**\n\t\t * The orders the Sort section offers, `[{ value, label, keys, fixed? }]`,\n\t\t * each `keys` a `[{ key, order }]` list read as its ascending form. An\n\t\t * option with `fixed: true` is an order of its own (the rows an endpoint\n\t\t * ranks): it is chosen by its value, has no direction, and its keys are\n\t\t * not matched against the current order. Empty draws no Sort section\n\t\t * (the table view sorts by its headers).\n\t\t */\n\t\tsortOptions: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/** The list's current order, `[{ key, order }]`. */\n\t\tcurrentSort: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/**\n\t\t * The Sort option chosen by its value, for an order that is not a list\n\t\t * of sort keys (an option with `fixed: true`, such as one whose rows an\n\t\t * endpoint ranks). Wins over matching `currentSort`.\n\t\t */\n\t\tcurrentSortValue: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** Current search term */\n\t\tsearchValue: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** Whether sidebar is open */\n\t\topen: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: true,\n\t\t},\n\n\t\t/** Current active facet filters: { fieldName: [values] } */\n\t\tactiveFilters: {\n\t\t\ttype: Object,\n\t\t\tdefault: () => ({}),\n\t\t},\n\n\t\t/** Live facet data from the API: `{ fieldName: { values: [{ value, count?, label? }] } }` */\n\t\tfacetData: {\n\t\t\ttype: Object,\n\t\t\tdefault: () => ({}),\n\t\t},\n\n\t\t/**\n\t\t * Additional column groups beyond schema properties and the built-in Metadata.\n\t\t * Each group: { id: string, label: string, columns: Array<{key, label}>, expanded?: boolean }\n\t\t */\n\t\tcolumnGroups: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/** Whether to include the built-in Metadata column group */\n\t\tshowMetadata: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: true,\n\t\t},\n\n\t\t/** Search input placeholder */\n\t\tsearchPlaceholder: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Type to search…'),\n\t\t},\n\n\t\t/** Search tab label */\n\t\tsearchTabLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Search'),\n\t\t},\n\n\t\t/** Columns tab label */\n\t\tcolumnsTabLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Columns'),\n\t\t},\n\n\t\t/** Search section heading */\n\t\tsearchLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Search'),\n\t\t},\n\n\t\t/** Filters section heading */\n\t\tfiltersLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Filters'),\n\t\t},\n\n\t\t/** \"Clear all\" button label, shown when search or a filter is active */\n\t\tclearAllLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Clear all'),\n\t\t},\n\n\t\t/**\n\t\t * Filter declarations for a page with no schema of its own: `{ name: declaration }`, the same shape a schema property has. Wins over `schema`, and feeds the Search tab only.\n\t\t *\n\t\t * 🔑 A FILTER IS NOT A COLUMN, which is the whole reason this is its\n\t\t * own prop rather than a synthetic `schema`. The schema feeds BOTH\n\t\t * tabs, so a page that declared its filters there would also offer\n\t\t * them in the Columns tab: the toggle would tick and no column would\n\t\t * appear, because the table's columns come from somewhere else\n\t\t * entirely. These reach the Search tab and nothing else.\n\t\t *\n\t\t * @type {object|null}\n\t\t */\n\t\tfilterFields: {\n\t\t\ttype: Object,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/** Start-of-window label on a date-range filter. */\n\t\tfromLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'From'),\n\t\t},\n\n\t\t/** End-of-window label on a date-range filter. */\n\t\ttoLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'To'),\n\t\t},\n\n\t\t/** Columns section heading */\n\t\tcolumnsHeading: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Column visibility'),\n\t\t},\n\n\t\t/** Columns section description */\n\t\tcolumnsDescription: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Select which columns to display in the table'),\n\t\t},\n\n\t\t/** Override label for the schema properties group. Defaults to schema.title. */\n\t\tpropertiesGroupLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * ID of the tab that should be active when the sidebar opens.\n\t\t * Built-in IDs are 'search-tab' and 'columns-tab'.\n\t\t * Use the id you set on your custom NcAppSidebarTab for custom tabs.\n\t\t */\n\t\tdefaultTab: {\n\t\t\ttype: String,\n\t\t\tdefault: 'search-tab',\n\t\t},\n\n\t\t/**\n\t\t * Switch to a tab while the sidebar is mounted, e.g. `'filters-tab'`\n\t\t * after a view was saved from the toolbar. Empty leaves the tab alone.\n\t\t */\n\t\tactiveTab: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * The page's saved views, shown in the Filters tab:\n\t\t * `{ views, loading, currentUserId, counts, selectedViewId, maxDepth, menuIds }`\n\t\t * as `CnSavedViewsPanel` takes them. `null` shows no saved views.\n\t\t * Every intent comes back as one `saved-view` event.\n\t\t */\n\t\tsavedViews: {\n\t\t\ttype: Object,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * Whether the current user is an admin.\n\t\t * When false, schema properties with `adminOnly: true` are hidden from filters.\n\t\t */\n\t\tuserIsAdmin: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: true,\n\t\t},\n\t},\n\n\temits: ['clear-filters', 'columns-change', 'columns-reorder', 'columns-reset', 'pin-change', 'filter-change', 'saved-view', 'search', 'sort-change', 'tab-change', 'update:open'],\n\n\tdata() {\n\t\treturn {\n\t\t\tinternalOpen: this.open,\n\t\t\tinternalActiveTab: this.defaultTab,\n\t\t\t/** Index of the column being dragged in the Order and pin list, or -1. */\n\t\t\tdragFrom: -1,\n\t\t\tpropertiesExpanded: true,\n\t\t\texpandedGroups: {},\n\t\t\t/**\n\t\t\t * Options loaded for a `reference` filter, keyed by field.\n\t\t\t *\n\t\t\t * A reference picker lists rows from ANOTHER list (the cases a\n\t\t\t * task can hang off, say), and neither the schema nor a facet\n\t\t\t * bucket carries them. Loaded once per field and cached, because\n\t\t\t * the sidebar re-renders on every keystroke in the search box.\n\t\t\t *\n\t\t\t * @type {Record<string, Array<{id: string, label: string}>>}\n\t\t\t */\n\t\t\treferenceOptions: {},\n\t\t\t/** @type {Record<string, boolean>} Which reference loads are in flight. */\n\t\t\treferenceLoading: {},\n\t\t}\n\t},\n\n\tcomputed: {\n\t\t/**\n\t\t * The Sort option the current order matches, as declared or reversed.\n\t\t *\n\t\t * @return {{option: object, direction: string}|null} The match, or null.\n\t\t */\n\t\tsortMatch() {\n\t\t\tif (this.currentSortValue) {\n\t\t\t\tconst chosen = this.sortOptions.find((o) => o.value === this.currentSortValue)\n\t\t\t\tif (chosen) {\n\t\t\t\t\treturn { option: chosen, direction: 'asc' }\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst current = Array.isArray(this.currentSort) ? this.currentSort : []\n\t\t\tfor (const option of this.sortOptions) {\n\t\t\t\tif (option.fixed === true) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tconst keys = Array.isArray(option.keys) ? option.keys : []\n\t\t\t\tif (sameSortKeys(keys, current)) {\n\t\t\t\t\treturn { option, direction: 'asc' }\n\t\t\t\t}\n\t\t\t\tif (sameSortKeys(reverseSortKeys(keys), current)) {\n\t\t\t\t\treturn { option, direction: 'desc' }\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn null\n\t\t},\n\n\t\t/** @return {object|null} The Sort option shown as chosen. */\n\t\tsortSelected() {\n\t\t\treturn this.sortMatch ? this.sortMatch.option : null\n\t\t},\n\n\t\t/** @return {string} The chosen direction, `asc` or `desc`. */\n\t\tsortDirection() {\n\t\t\treturn this.sortMatch ? this.sortMatch.direction : 'asc'\n\t\t},\n\n\t\t/**\n\t\t * Whether the board look applies.\n\t\t *\n\t\t * @return {boolean}\n\t\t */\n\t\tisBoardLook() {\n\t\t\tconst look = this.cnLook && typeof this.cnLook === 'object' && 'value' in this.cnLook ? this.cnLook.value : this.cnLook\n\t\t\treturn normalizeLook(look) === 'board'\n\t\t},\n\n\t\t/**\n\t\t * The two directions as segments, as board DqZakenSorteren draws them:\n\t\t * \"Oplopend\" and \"Aflopend\" with an arrow each.\n\t\t *\n\t\t * @spec openspec/changes/sidebar-sort-direction-segmented/specs/index-sidebar/spec.md#requirement-the-board-look-draws-the-sort-direction-as-two-segments\n\t\t * @return {Array<{value: string, label: string, disabled: boolean}>}\n\t\t */\n\t\tsortDirectionOptions() {\n\t\t\tconst disabled = !this.sortSelected || this.sortSelected.fixed === true\n\t\t\treturn [\n\t\t\t\t{ value: 'asc', label: t('nextcloud-vue', 'Ascending'), disabled },\n\t\t\t\t{ value: 'desc', label: t('nextcloud-vue', 'Descending'), disabled },\n\t\t\t]\n\t\t},\n\n\t\t/**\n\t\t * The id of the Direction heading that names the segments.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tsortDirectionLabelId() {\n\t\t\treturn `cn-index-sidebar-direction-${this.$.uid}`\n\t\t},\n\n\t\t/**\n\t\t * The order the list has now, in words: \"Current order: Created,\n\t\t * descending\" (\"Now: by created, descending.\" and that a view keeps\n\t\t * it, in the board look), or that it is not sorted.\n\t\t *\n\t\t * @return {string} The sentence.\n\t\t */\n\t\tcurrentSortText() {\n\t\t\t// The board look writes the order in running text, the field in\n\t\t\t// lower case: \"Now: by deadline, ascending.\" (DqZakenSorteren).\n\t\t\tconst name = (label) => (this.isBoardLook ? String(label).charAt(0).toLocaleLowerCase() + String(label).slice(1) : label)\n\t\t\tconst sentence = (order) => (this.isBoardLook\n\t\t\t\t? `${t('nextcloud-vue', 'Now: by {order}.', { order })} ${t('nextcloud-vue', 'You save the order along with a view.')}`\n\t\t\t\t: t('nextcloud-vue', 'Current order: {order}', { order }))\n\t\t\tif (this.sortMatch && this.sortMatch.option.fixed === true) {\n\t\t\t\treturn sentence(name(this.sortMatch.option.label))\n\t\t\t}\n\t\t\tconst current = Array.isArray(this.currentSort) ? this.currentSort : []\n\t\t\tif (current.length === 0) {\n\t\t\t\treturn t('nextcloud-vue', 'Not sorted')\n\t\t\t}\n\t\t\tconst labelOf = (key) => {\n\t\t\t\tconst single = this.sortOptions.find((o) => Array.isArray(o.keys) && o.keys.length === 1 && o.keys[0].key === key)\n\t\t\t\treturn name(single ? single.label : key)\n\t\t\t}\n\t\t\tconst order = this.sortMatch && this.sortMatch.option.keys.length > 1\n\t\t\t\t? `${name(this.sortMatch.option.label)}, ${this.sortDirection === 'desc' ? t('nextcloud-vue', 'descending') : t('nextcloud-vue', 'ascending')}`\n\t\t\t\t: current.map((entry) => `${labelOf(entry.key)}, ${entry.order === 'desc' ? t('nextcloud-vue', 'descending') : t('nextcloud-vue', 'ascending')}`).join('; ')\n\t\t\treturn sentence(order)\n\t\t},\n\n\t\t/**\n\t\t * The panel's props, from `savedViews`.\n\t\t *\n\t\t * @return {object}\n\t\t * @spec openspec/changes/saved-views-manage-and-defaults/tasks.md#task-6\n\t\t */\n\t\tsavedViewsPanelProps() {\n\t\t\tconst f = this.savedViews || {}\n\t\t\treturn {\n\t\t\t\tviews: Array.isArray(f.views) ? f.views : [],\n\t\t\t\tloading: f.loading === true,\n\t\t\t\tcurrentUserId: f.currentUserId || '',\n\t\t\t\tcounts: f.counts || null,\n\t\t\t\tselectedViewId: f.selectedViewId || '',\n\t\t\t\tmaxDepth: typeof f.maxDepth === 'number' ? f.maxDepth : 3,\n\t\t\t\tmenuIds: Array.isArray(f.menuIds) ? f.menuIds : null,\n\t\t\t\tsummaries: f.summaries && typeof f.summaries === 'object' ? f.summaries : null,\n\t\t\t}\n\t\t},\n\n\t\t/** Resolved icon — explicit prop overrides schema.icon */\n\t\tresolvedIcon() {\n\t\t\treturn this.icon || this.schema?.icon || ''\n\t\t},\n\n\t\t/** Sidebar name — schema title, shown as the h2 header */\n\t\tresolvedName() {\n\t\t\tif (this.title) {\n\t\t\t\treturn this.shown(this.title)\n\t\t\t}\n\t\t\treturn this.schema?.title || 'Search'\n\t\t},\n\n\t\t/** Sidebar subname: the subtitle the page hands it, else the schema description */\n\t\tresolvedSubname() {\n\t\t\tif (typeof this.subtitle === 'string' && this.subtitle !== '') {\n\t\t\t\treturn this.subtitle\n\t\t\t}\n\t\t\treturn this.schema?.description || ''\n\t\t},\n\n\t\t/** Properties group label — derived from schema.title if not explicitly set */\n\t\tresolvedPropertiesLabel() {\n\t\t\tif (this.propertiesGroupLabel) {\n\t\t\t\treturn this.propertiesGroupLabel\n\t\t\t}\n\t\t\treturn this.schema?.title || 'Properties'\n\t\t},\n\n\t\t/** All available columns from schema */\n\t\tallColumns() {\n\t\t\tif (!this.schema) {\n\t\t\t\treturn []\n\t\t\t}\n\t\t\treturn columnsFromSchema(this.schema, { translate: this.cnTranslate })\n\t\t},\n\n\t\t/** Filter definitions from schema (facetable properties, respecting RBAC) */\n\t\tschemaFilters() {\n\t\t\t// An explicitly declared filter set wins: it is the page saying\n\t\t\t// \"these are the questions\", where a schema only says \"these are\n\t\t\t// the properties\" and the sidebar has to guess which of them are\n\t\t\t// worth asking about.\n\t\t\tif (this.filterFields && Object.keys(this.filterFields).length > 0) {\n\t\t\t\treturn filtersFromSchema(\n\t\t\t\t\t{ properties: this.filterFields },\n\t\t\t\t\t{ isAdmin: this.userIsAdmin, translate: this.cnTranslate },\n\t\t\t\t)\n\t\t\t}\n\t\t\tif (!this.schema) {\n\t\t\t\treturn []\n\t\t\t}\n\t\t\treturn filtersFromSchema(this.schema, { isAdmin: this.userIsAdmin, translate: this.cnTranslate })\n\t\t},\n\n\t\t/** Whether a search term or any facet filter is currently active. */\n\t\thasActiveFilters() {\n\t\t\tif ((this.searchValue || '').length > 0) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\treturn Object.values(this.activeFilters || {}).some((v) => (Array.isArray(v) ? v.length > 0 : !!v))\n\t\t},\n\n\t\t/** Combined column groups: built-in Metadata + external groups */\n\t\tallGroups() {\n\t\t\tconst groups = []\n\t\t\tif (this.showMetadata && this.schema) {\n\t\t\t\tgroups.push({\n\t\t\t\t\tid: 'metadata',\n\t\t\t\t\tlabel: 'Metadata',\n\t\t\t\t\tcolumns: METADATA_COLUMNS,\n\t\t\t\t\texpanded: true,\n\t\t\t\t})\n\t\t\t}\n\t\t\treturn [...groups, ...this.columnGroups]\n\t\t},\n\n\t\t/** Label of each column key, from the schema properties and the groups. */\n\t\tcolumnLabels() {\n\t\t\tconst map = {}\n\t\t\tthis.allColumns.forEach((c) => {\n\t\t\t\tmap[c.key] = c.label\n\t\t\t})\n\t\t\tthis.allGroups.forEach((g) => g.columns.forEach((c) => {\n\t\t\t\tmap[c.key] = c.label\n\t\t\t}))\n\t\t\treturn map\n\t\t},\n\n\t\t/** The visible columns in their order, with labels (all columns when none were chosen). */\n\t\torderedVisible() {\n\t\t\tconst keys = this.visibleColumns === null ? this.allColumnKeys : this.visibleColumns\n\t\t\treturn keys.filter((k) => this.columnLabels[k] !== undefined).map((key) => ({ key, label: this.columnLabels[key] }))\n\t\t},\n\n\t\t/** All column keys across schema properties and all groups */\n\t\tallColumnKeys() {\n\t\t\treturn [\n\t\t\t\t...this.allColumns.map((c) => c.key),\n\t\t\t\t...this.allGroups.flatMap((g) => g.columns.map((c) => c.key)),\n\t\t\t]\n\t\t},\n\n\t\t/**\n\t\t * The presets a date-range filter offers when it declares none.\n\t\t *\n\t\t * Just `custom`. Every shipped preset rolls BACKWARDS from today\n\t\t * (\"Last 30 days\"), and a sidebar filter is as often a forward window\n\t\t * (\"due next week\") as a backward one. Offering a preset that answers\n\t\t * the wrong direction is worse than offering none: it is one click and\n\t\t * it looks deliberate.\n\t\t *\n\t\t * @return {Array<object>} The preset list.\n\t\t */\n\t\trangePresets() {\n\t\t\t// Taken FROM the picker's own list rather than written out again, so\n\t\t\t// the one preset a filter offers carries the same id and the same\n\t\t\t// label as everywhere else it appears.\n\t\t\treturn DEFAULT_DATE_RANGE_PRESETS\n\t\t\t\t.filter((preset) => preset.id === 'custom')\n\t\t\t\t.map((preset) => ({ ...preset }))\n\t\t},\n\t},\n\n\twatch: {\n\t\tactiveTab(tab) {\n\t\t\tif (tab) {\n\t\t\t\tthis.internalActiveTab = tab\n\t\t\t}\n\t\t},\n\n\t\topen(val) {\n\t\t\tthis.internalOpen = val\n\t\t},\n\n\t\tinternalOpen(val) {\n\t\t\tthis.$emit('update:open', val)\n\t\t},\n\n\t\tdefaultTab(val) {\n\t\t\tthis.internalActiveTab = val\n\t\t},\n\n\t\tallGroups: {\n\t\t\timmediate: true,\n\t\t\thandler(groups) {\n\t\t\t\tfor (const group of groups) {\n\t\t\t\t\tif (!(group.id in this.expandedGroups)) {\n\t\t\t\t\t\tthis.expandedGroups[group.id] = group.expanded !== false\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\n\t\t// A reference picker's rows load once the schema naming them arrives,\n\t\t// which on a manifest page is after mount. Watching the FILTERS rather\n\t\t// than calling from `mounted()` covers both orders.\n\t\tschemaFilters: {\n\t\t\timmediate: true,\n\t\t\thandler() {\n\t\t\t\tthis.loadReferenceOptions()\n\t\t\t},\n\t\t},\n\t},\n\n\tmounted() {\n\t\tlabelSidePanelClose(this.$refs.appSidebar)\n\t},\n\n\tmethods: {\n\t\tt,\n\n\t\t/**\n\t\t * A field chosen in the Sort section: its order, in the direction\n\t\t * already chosen.\n\t\t *\n\t\t * @param {object|null} option The chosen option.\n\t\t * @return {void}\n\t\t */\n\t\tonSortField(option) {\n\t\t\tconst chosen = option && this.sortOptions.find((o) => o.value === option.value)\n\t\t\tif (!chosen) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.emitSort(chosen, this.sortDirection)\n\t\t},\n\n\t\t/**\n\t\t * A direction chosen in the Sort section, for the chosen field.\n\t\t *\n\t\t * @param {string} direction `asc` or `desc`.\n\t\t * @return {void}\n\t\t */\n\t\tonSortDirection(direction) {\n\t\t\tif (!this.sortSelected) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.emitSort(this.sortSelected, direction === 'desc' ? 'desc' : 'asc')\n\t\t},\n\n\t\t/**\n\t\t * Emit the order an option stands for in a direction.\n\t\t *\n\t\t * @param {object} option The Sort option.\n\t\t * @param {string} direction `asc` or `desc`.\n\t\t * @return {void}\n\t\t */\n\t\temitSort(option, direction) {\n\t\t\tconst keys = Array.isArray(option.keys) ? option.keys : []\n\t\t\t/**\n\t\t\t * @event sort-change The Sort section chose an order. Payload: `[{ key, order }]`,\n\t\t\t * and the chosen option's value, which names an order that is not keys (`fixed`).\n\t\t\t */\n\t\t\tthis.$emit('sort-change', direction === 'desc' ? reverseSortKeys(keys) : keys.map((k) => ({ key: k.key, order: k.order || 'asc' })), option.value)\n\t\t},\n\n\t\t/**\n\t\t * Hand a saved-view intent to the page.\n\t\t *\n\t\t * @param {'apply'|'save'|'edit'|'share'|'presentation'|'update'|'copy'|'menu'|'delete'} action The intent.\n\t\t * @param {object|null} view The view, or null for save.\n\t\t * @spec openspec/changes/saved-views-manage-and-defaults/tasks.md#task-6\n\t\t */\n\t\tonSavedView(action, view) {\n\t\t\t/**\n\t\t\t * @event saved-view A saved-view intent from the Filters tab. Payload: `{ action, view }`.\n\t\t\t * @type {{action: string, view: (object|null)}}\n\t\t\t */\n\t\t\tthis.$emit('saved-view', { action, view })\n\t\t},\n\n\t\t/**\n\t\t * A manifest label through the injected lookup, or as written.\n\t\t *\n\t\t * @param {string} text The label as written.\n\t\t * @return {string} The label in the user's language.\n\t\t */\n\t\tshown(text) {\n\t\t\treturn typeof this.cnTranslate === 'function' && typeof text === 'string' && text !== '' ? this.cnTranslate(text) : text\n\t\t},\n\n\t\t/**\n\t\t * The `lang` of a label that fell back to its written text in another language.\n\t\t *\n\t\t * @param {string} text The label as written.\n\t\t * @return {string|undefined} The source language, or undefined.\n\t\t */\n\t\tlangOf(text) {\n\t\t\treturn labelLang(this.cnTranslate, text) || undefined\n\t\t},\n\n\t\t/**\n\t\t * Handle tab change from NcAppSidebar\n\t\t *\n\t\t * @param {string} tabId Tab identifier\n\t\t */\n\t\tonTabChange(tabId) {\n\t\t\tthis.internalActiveTab = tabId\n\t\t\tthis.$emit('tab-change', tabId)\n\t\t},\n\n\t\t/**\n\t\t * Check if a column is currently visible\n\t\t *\n\t\t * @param {string} key Column key\n\t\t */\n\t\tisColumnVisible(key) {\n\t\t\tif (this.visibleColumns === null) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\treturn this.visibleColumns.includes(key)\n\t\t},\n\n\t\t/**\n\t\t * Check if all columns in a group are visible\n\t\t *\n\t\t * @param {string[]} columns Array of column keys\n\t\t */\n\t\tisGroupAllVisible(columns) {\n\t\t\treturn columns.every((col) => this.isColumnVisible(col.key))\n\t\t},\n\n\t\t/**\n\t\t * Toggle a single column's visibility\n\t\t *\n\t\t * @param {string} key Column key\n\t\t */\n\t\ttoggleColumn(key) {\n\t\t\tlet newVisible\n\t\t\tif (this.visibleColumns === null) {\n\t\t\t\tnewVisible = this.allColumnKeys.filter((k) => k !== key)\n\t\t\t} else if (this.isColumnVisible(key)) {\n\t\t\t\tnewVisible = this.visibleColumns.filter((k) => k !== key)\n\t\t\t} else {\n\t\t\t\tnewVisible = [...this.visibleColumns, key]\n\t\t\t}\n\t\t\tthis.$emit('columns-change', newVisible)\n\t\t},\n\n\t\t/**\n\t\t * Select or deselect all columns in a group\n\t\t *\n\t\t * @param {string[]} columns Array of column keys\n\t\t */\n\t\ttoggleGroupAll(columns) {\n\t\t\tconst groupKeys = columns.map((c) => c.key)\n\t\t\tconst allVisible = this.isGroupAllVisible(columns)\n\n\t\t\tlet newVisible\n\t\t\tif (this.visibleColumns === null) {\n\t\t\t\t// Currently all visible — deselect this group\n\t\t\t\tnewVisible = this.allColumnKeys.filter((k) => !groupKeys.includes(k))\n\t\t\t} else if (allVisible) {\n\t\t\t\t// All in group visible — deselect them\n\t\t\t\tnewVisible = this.visibleColumns.filter((k) => !groupKeys.includes(k))\n\t\t\t} else {\n\t\t\t\t// Not all visible — select them all\n\t\t\t\tconst current = new Set(this.visibleColumns)\n\t\t\t\tgroupKeys.forEach((k) => current.add(k))\n\t\t\t\tnewVisible = [...current]\n\t\t\t}\n\t\t\tthis.$emit('columns-change', newVisible)\n\t\t},\n\n\t\t/**\n\t\t * Move a visible column to another place in the order. The drag and the\n\t\t * Move buttons both call this. A column stays inside its block: pinned\n\t\t * columns move among the pinned, the rest among the rest.\n\t\t *\n\t\t * @param {number} from Current index.\n\t\t * @param {number} to Target index.\n\t\t * @return {void}\n\t\t */\n\t\tmoveColumn(from, to) {\n\t\t\tconst list = this.orderedVisible.map((c) => c.key)\n\t\t\tconst lo = from < this.pinnedCount ? 0 : this.pinnedCount\n\t\t\tconst hi = from < this.pinnedCount ? this.pinnedCount - 1 : list.length - 1\n\t\t\tconst target = Math.min(hi, Math.max(lo, to))\n\t\t\tif (from < 0 || from >= list.length || target === from) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst [moved] = list.splice(from, 1)\n\t\t\tlist.splice(target, 0, moved)\n\t\t\t/**\n\t\t\t * @event columns-reorder Emitted when the user moves a column. Payload: the visible column keys in their new order.\n\t\t\t * @type {string[]}\n\t\t\t */\n\t\t\tthis.$emit('columns-reorder', list)\n\t\t},\n\n\t\t/**\n\t\t * Dropping a dragged column on another row.\n\t\t *\n\t\t * @param {number} index Index of the row it was dropped on.\n\t\t * @return {void}\n\t\t */\n\t\tonDropColumn(index) {\n\t\t\tconst from = this.dragFrom\n\t\t\tthis.dragFrom = -1\n\t\t\tif (from >= 0) {\n\t\t\t\tthis.moveColumn(from, index)\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Pin a column (it joins the pinned block at the start) or unpin it (it\n\t\t * leaves that block, to the first place after it).\n\t\t *\n\t\t * @param {number} index Index of the column.\n\t\t * @return {void}\n\t\t */\n\t\ttogglePin(index) {\n\t\t\tconst list = this.orderedVisible.map((c) => c.key)\n\t\t\tconst [moved] = list.splice(index, 1)\n\t\t\tlet count = this.pinnedCount\n\t\t\tif (index < count) {\n\t\t\t\tcount -= 1\n\t\t\t\tlist.splice(count, 0, moved)\n\t\t\t} else {\n\t\t\t\tlist.splice(count, 0, moved)\n\t\t\t\tcount += 1\n\t\t\t}\n\t\t\tthis.$emit('columns-reorder', list)\n\t\t\t/**\n\t\t\t * @event pin-change Emitted when a column is pinned or unpinned. Payload: the new number of pinned columns.\n\t\t\t * @type {number}\n\t\t\t */\n\t\t\tthis.$emit('pin-change', count)\n\t\t},\n\n\t\t/**\n\t\t * Toggle a group's expanded state\n\t\t *\n\t\t * @param {string} groupId Filter group identifier\n\t\t */\n\t\ttoggleGroup(groupId) {\n\t\t\tthis.expandedGroups[groupId] = !this.expandedGroups[groupId]\n\t\t},\n\n\t\t/**\n\t\t * Get filter options for a filter definition\n\t\t *\n\t\t * @param {object} filter Filter object\n\t\t */\n\t\tgetFilterOptions(filter) {\n\t\t\tconst live = facetOptions(\n\t\t\t\tthis.facetData[filter.key],\n\t\t\t\t(count) => t('nextcloud-vue', 'No value ({count})', { count }),\n\t\t\t)\n\t\t\tif (live !== null) {\n\t\t\t\treturn live\n\t\t\t}\n\t\t\t// A reference picker's rows come from another list, and neither a\n\t\t\t// schema enum nor a facet bucket can carry them.\n\t\t\tif (filter.type === 'reference') {\n\t\t\t\treturn this.referenceOptions[filter.key] || []\n\t\t\t}\n\t\t\treturn filter.options || []\n\t\t},\n\n\t\t/**\n\t\t * Whether a reference filter is still fetching its rows.\n\t\t *\n\t\t * Shown rather than hidden: an empty picker that is still loading and\n\t\t * one that genuinely has nothing to pick look identical, and only one\n\t\t * of them means the person should stop waiting.\n\t\t *\n\t\t * @param {object} filter The filter definition.\n\t\t *\n\t\t * @return {boolean} True while the load is in flight.\n\t\t */\n\t\tisLoadingOptions(filter) {\n\t\t\treturn this.referenceLoading[filter.key] === true\n\t\t},\n\n\t\t/**\n\t\t * The `{ from, to }` window a date-range filter currently holds.\n\t\t *\n\t\t * @param {object} filter The filter definition.\n\t\t *\n\t\t * @return {object|null} The window, or null when none is set.\n\t\t */\n\t\tgetRangeValue(filter) {\n\t\t\tconst value = this.activeFilters[filter.key]\n\t\t\tif (value && typeof value === 'object' && !Array.isArray(value)) {\n\t\t\t\treturn value\n\t\t\t}\n\t\t\treturn null\n\t\t},\n\n\t\t/**\n\t\t * A date-range filter changed.\n\t\t *\n\t\t * Emitted in the SAME `filter-change` shape every other control uses,\n\t\t * with the window as the payload's `values`, so a consumer has one\n\t\t * event to listen to and not two.\n\t\t *\n\t\t * @param {string} key The filter key.\n\t\t * @param {object|null} window The `{ from, to, preset }` value.\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tonRangeChange(key, window) {\n\t\t\tconst from = (window && window.from) || ''\n\t\t\tconst to = (window && window.to) || ''\n\t\t\tif (from === '' && to === '') {\n\t\t\t\tthis.$emit('filter-change', { key, values: [] })\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.$emit('filter-change', { key, values: { from, to } })\n\t\t},\n\n\t\t/**\n\t\t * The text a `text` filter currently holds.\n\t\t *\n\t\t * @param {object} filter The filter definition.\n\t\t *\n\t\t * @return {string} The current value.\n\t\t */\n\t\tgetTextValue(filter) {\n\t\t\tconst value = this.activeFilters[filter.key]\n\t\t\tif (Array.isArray(value)) {\n\t\t\t\treturn value.length > 0 ? String(value[0]) : ''\n\t\t\t}\n\t\t\treturn (value === undefined || value === null) ? '' : String(value)\n\t\t},\n\n\t\t/**\n\t\t * A text filter changed.\n\t\t *\n\t\t * @param {string} key The filter key.\n\t\t * @param {string} value The typed value.\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tonTextChange(key, value) {\n\t\t\tconst text = String(value ?? '').trim()\n\t\t\tthis.$emit('filter-change', { key, values: text === '' ? [] : [text] })\n\t\t},\n\n\t\t/**\n\t\t * Load the rows a `reference` filter picks from.\n\t\t *\n\t\t * Reads `optionsSource` off the schema property:\n\t\t * `{ register, schema, labelField, valueField, limit }`. The VALUE is\n\t\t * the referenced object's uuid, because that is what the server\n\t\t * filters on; the label is only what the person reads.\n\t\t *\n\t\t * Failures are logged and leave the picker empty rather than throwing:\n\t\t * one unreachable list must not take the whole sidebar with it.\n\t\t *\n\t\t * @return {Promise<void>} Resolves when every reference filter settled.\n\t\t */\n\t\tasync loadReferenceOptions() {\n\t\t\tconst pending = this.schemaFilters.filter((filter) => filter.type === 'reference'\n\t\t\t\t&& filter.optionsSource\n\t\t\t\t&& this.referenceOptions[filter.key] === undefined\n\t\t\t\t&& this.referenceLoading[filter.key] !== true)\n\t\t\tif (pending.length === 0) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tconst [{ default: axios }, { generateUrl }] = await Promise.all([\n\t\t\t\timport('@nextcloud/axios'),\n\t\t\t\timport('@nextcloud/router'),\n\t\t\t])\n\n\t\t\tawait Promise.all(pending.map(async (filter) => {\n\t\t\t\tconst source = filter.optionsSource\n\t\t\t\tif (!source.register || !source.schema) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tthis.referenceLoading = { ...this.referenceLoading, [filter.key]: true }\n\t\t\t\ttry {\n\t\t\t\t\tconst url = generateUrl('/apps/openregister/api/objects/{register}/{schema}', {\n\t\t\t\t\t\tregister: source.register,\n\t\t\t\t\t\tschema: source.schema,\n\t\t\t\t\t})\n\t\t\t\t\tconst response = await axios.get(url, { params: { _limit: source.limit || 200 } })\n\t\t\t\t\tconst rows = response?.data?.results || response?.data || []\n\t\t\t\t\tconst valueField = source.valueField || '@self.uuid'\n\t\t\t\t\tconst labelField = source.labelField || 'title'\n\t\t\t\t\tconst options = rows\n\t\t\t\t\t\t.map((row) => ({\n\t\t\t\t\t\t\tid: this.readPath(row, valueField),\n\t\t\t\t\t\t\tlabel: String(this.readPath(row, labelField) ?? this.readPath(row, valueField) ?? ''),\n\t\t\t\t\t\t}))\n\t\t\t\t\t\t.filter((option) => option.id !== null && option.id !== undefined && option.id !== '')\n\t\t\t\t\t\t.sort((a, b) => a.label.localeCompare(b.label))\n\t\t\t\t\tthis.referenceOptions = { ...this.referenceOptions, [filter.key]: options }\n\t\t\t\t} catch (error) {\n\t\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\t\tconsole.error(`[CnIndexSidebar] the reference filter \"${filter.key}\" could not load its options`, error)\n\t\t\t\t\tthis.referenceOptions = { ...this.referenceOptions, [filter.key]: [] }\n\t\t\t\t} finally {\n\t\t\t\t\tthis.referenceLoading = { ...this.referenceLoading, [filter.key]: false }\n\t\t\t\t}\n\t\t\t}))\n\t\t},\n\n\t\t/**\n\t\t * Read a dotted path off a row (`@self.uuid`, `title`).\n\t\t *\n\t\t * @param {object} row The row.\n\t\t * @param {string} path The dotted path.\n\t\t *\n\t\t * @return {unknown} The value, or undefined.\n\t\t */\n\t\treadPath(row, path) {\n\t\t\treturn String(path).split('.').reduce((acc, part) => ((acc === null || acc === undefined) ? acc : acc[part]), row)\n\t\t},\n\n\t\t/**\n\t\t * Get currently selected options for a filter\n\t\t *\n\t\t * @param {object} filter Filter object\n\t\t */\n\t\tgetSelectedFilterOptions(filter) {\n\t\t\tconst value = this.activeFilters[filter.key]\n\t\t\tif (!value) {\n\t\t\t\treturn []\n\t\t\t}\n\t\t\tconst values = Array.isArray(value) ? value : [value]\n\t\t\tconst options = this.getFilterOptions(filter)\n\t\t\treturn values.map((v) => options.find((o) => o.id === v) || { id: v, label: String(v) })\n\t\t},\n\n\t\t/**\n\t\t * A field's values as checkbox rows, in the board look and for a short\n\t\t * list only: label and count apart, from the facet when there is one,\n\t\t * else the field's own options. Null where the picker stays (the\n\t\t * Nextcloud look, a single choice, a reference, more than\n\t\t * CHECKLIST_MAX values).\n\t\t *\n\t\t * @spec openspec/changes/board-sidebar-filters-as-checkbox-lists/specs/index-sidebar/spec.md#requirement-the-board-look-draws-a-short-filter-as-a-checkbox-list-with-counts\n\t\t * @param {object} filter The filter definition.\n\t\t * @return {Array<{id: (string|number|boolean), label: string, count: (number|null)}>|null} The rows, or null.\n\t\t */\n\t\tchecklistOptions(filter) {\n\t\t\tif (!this.isBoardLook || filter.multiple === false || filter.type === 'reference') {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst facet = this.facetData[filter.key]\n\t\t\tlet rows\n\t\t\tif (facet && Array.isArray(facet.values) && facet.values.length > 0) {\n\t\t\t\trows = facet.values.map((bucket) => ({\n\t\t\t\t\tid: bucket.value,\n\t\t\t\t\tlabel: String(bucket.label !== undefined && bucket.label !== null ? bucket.label : bucket.value),\n\t\t\t\t\tcount: typeof bucket.count === 'number' ? bucket.count : null,\n\t\t\t\t}))\n\t\t\t\tif (typeof facet.missing === 'number' && facet.missing > 0) {\n\t\t\t\t\trows.push({ id: MISSING_VALUE, label: t('nextcloud-vue', 'No value'), count: facet.missing })\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\trows = (filter.options || []).map((option) => ({ id: option.id, label: String(option.label), count: null }))\n\t\t\t}\n\t\t\treturn rows.length > 0 && rows.length <= CHECKLIST_MAX ? rows : null\n\t\t},\n\n\t\t/**\n\t\t * Whether a value of a field is among its active filter values.\n\t\t *\n\t\t * @param {object} filter The filter definition.\n\t\t * @param {string|number|boolean} id The value.\n\t\t * @return {boolean}\n\t\t */\n\t\tisChecked(filter, id) {\n\t\t\tconst value = this.activeFilters[filter.key]\n\t\t\tconst values = Array.isArray(value) ? value : (value === undefined || value === null || value === '' ? [] : [value])\n\t\t\treturn values.map(String).includes(String(id))\n\t\t},\n\n\t\t/**\n\t\t * A checkbox row was toggled: the field's values with it added or taken out.\n\t\t *\n\t\t * @spec openspec/changes/board-sidebar-filters-as-checkbox-lists/specs/index-sidebar/spec.md#requirement-the-board-look-draws-a-short-filter-as-a-checkbox-list-with-counts\n\t\t * @param {object} filter The filter definition.\n\t\t * @param {string|number|boolean} id The value.\n\t\t * @param {boolean} checked Whether it is now ticked.\n\t\t * @return {void}\n\t\t */\n\t\tonChecklistToggle(filter, id, checked) {\n\t\t\tconst value = this.activeFilters[filter.key]\n\t\t\tconst current = Array.isArray(value) ? [...value] : (value === undefined || value === null || value === '' ? [] : [value])\n\t\t\tconst rest = current.filter((v) => String(v) !== String(id))\n\t\t\tthis.$emit('filter-change', { key: filter.key, values: checked ? [...rest, id] : rest })\n\t\t},\n\n\t\t/**\n\t\t * Handle filter select change\n\t\t *\n\t\t * @param {string} key Filter key\n\t\t * @param {Array} selected Selected values\n\t\t */\n\t\tonFilterChange(key, selected) {\n\t\t\t// 🔴 A SINGLE-VALUED SELECT EMITS AN OBJECT, NOT AN ARRAY. NcSelect\n\t\t\t// changes the SHAPE of its payload with `multiple`, and `.map` on\n\t\t\t// the object shape throws inside an event handler, where Vue logs\n\t\t\t// it and carries on: the picker looks inert and the console says\n\t\t\t// why in a place nobody is looking.\n\t\t\tconst chosen = Array.isArray(selected) ? selected : (selected ? [selected] : [])\n\t\t\tconst values = chosen.map((o) => ((o && typeof o === 'object' && 'id' in o) ? o.id : o))\n\t\t\tthis.$emit('filter-change', { key, values })\n\t\t},\n\n\t\t/**\n\t\t * \"Clear all\" click: reset search and every active facet filter in\n\t\t * one shot, so the parent does one fetch instead of one per field.\n\t\t */\n\t\tonClearAll() {\n\t\t\t/**\n\t\t\t * @event clear-filters \"Clear all\" clicked; reset search and every active filter.\n\t\t\t */\n\t\t\tthis.$emit('clear-filters')\n\t\t},\n\t},\n}\n</script>\n\n<!-- Styles in css/index-sidebar.css -->\n"],"names":["_createBlock","_createVNode","_createElementVNode","_openBlock","_createElementBlock","_renderSlot","_Fragment","_withCtx","_toDisplayString","_createTextVNode","_renderList","_normalizeClass","_withModifiers","_mergeProps"],"mappings":"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"}
@@ -2,7 +2,7 @@ import script from './CnMapWidget.vue2.js';
2
2
  import { render } from './CnMapWidget.vue3.js';
3
3
 
4
4
  script.render = render;
5
- script.__scopeId = "data-v-4c58b629";
5
+ script.__scopeId = "data-v-e92438e2";
6
6
  const __sfc_main = script;
7
7
 
8
8
  export { __sfc_main as default };
@@ -129,6 +129,25 @@ function controlIcon(path) {
129
129
  * @slot popup Per-marker popup body override. Scoped props: `{ feature, properties }`. When omitted, the widget renders the value of `markers.popupField` (or no popup at all when unset).
130
130
  * @slot fallback Replaces the default "map unavailable" message when Leaflet fails to load (test environments, CSP-blocked builds, offline dev). No scoped props.
131
131
  */
132
+ /**
133
+ * The count line a header spec gives (`{ one, other }` or one string, with
134
+ * `{total}`), once the marker source answered with markers.
135
+ *
136
+ * @param {object|string|undefined} spec The declared line.
137
+ * @param {object} vm The map: `markersLoaded`, `markersFailed`, `markerCount`, `cnTranslate`.
138
+ * @return {string} The line, or ''.
139
+ */
140
+ function countLine(spec, vm) {
141
+ if (!spec || !vm.markersLoaded || vm.markersFailed || vm.markerCount === 0) {
142
+ return ''
143
+ }
144
+ const text = typeof spec === 'string' ? spec : (vm.markerCount === 1 ? spec.one : spec.other);
145
+ if (typeof text !== 'string' || text === '') {
146
+ return ''
147
+ }
148
+ return vm.cnTranslate(text).replace(/\{total\}/g, String(vm.markerCount))
149
+ }
150
+
132
151
  var script = {
133
152
  name: 'CnMapWidget',
134
153
 
@@ -480,15 +499,19 @@ var script = {
480
499
  * @spec openspec/changes/map-widget-header-count/specs/map-widget-header-count/spec.md#requirement-a-map-card-can-say-how-many-places-it-shows
481
500
  */
482
501
  headerSubtitleText() {
483
- const spec = this.content?.headerSubtitle;
484
- if (!spec || !this.markersLoaded || this.markersFailed || this.markerCount === 0) {
485
- return ''
486
- }
487
- const text = typeof spec === 'string' ? spec : (this.markerCount === 1 ? spec.one : spec.other);
488
- if (typeof text !== 'string' || text === '') {
489
- return ''
490
- }
491
- return this.cnTranslate(text).replace(/\{total\}/g, String(this.markerCount))
502
+ return countLine(this.content?.headerSubtitle, this)
503
+ },
504
+
505
+ /**
506
+ * The same count as a note at the right of the card's title row
507
+ * (`content.headerNote`, the same shape as `headerSubtitle`), as the
508
+ * case boards draw "Locaties ... 1 locatie".
509
+ *
510
+ * @return {string}
511
+ * @spec openspec/changes/map-count-note/specs/map-widget/spec.md
512
+ */
513
+ headerNoteText() {
514
+ return countLine(this.content?.headerNote, this)
492
515
  },
493
516
 
494
517
  markerStatusText() {
@@ -575,6 +598,21 @@ var script = {
575
598
  }
576
599
  },
577
600
 
601
+ /**
602
+ * Report the count note to the card around the map.
603
+ *
604
+ * @param {string} note The note, or ''.
605
+ */
606
+ headerNoteText(note) {
607
+ if (this.content?.headerNote) {
608
+ /**
609
+ * @event header The card header's note at the right of the title.
610
+ * @type {{note: string}}
611
+ */
612
+ this.$emit('header', { note });
613
+ }
614
+ },
615
+
578
616
  // Keyed, never `deep: true` — see `layersKey`.
579
617
  layersKey() {
580
618
  if (this.map) {