@conduction/nextcloud-vue 2.100.0 → 2.102.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/components/CnActionsBar/CnActionsBar.vue2.js +22 -0
- package/dist/esm/components/CnActionsBar/CnActionsBar.vue2.js.map +1 -1
- package/dist/esm/components/CnActionsBar/CnActionsBar.vue3.js +8 -6
- package/dist/esm/components/CnActionsBar/CnActionsBar.vue3.js.map +1 -1
- package/dist/esm/components/CnChartWidget/CnChartWidget.vue.js +1 -1
- package/dist/esm/components/CnChartWidget/CnChartWidget.vue2.js +29 -4
- package/dist/esm/components/CnChartWidget/CnChartWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnChartWidget/CnChartWidget.vue3.js +9 -1
- package/dist/esm/components/CnChartWidget/CnChartWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnChoiceCards/CnChoiceCards.vue.js +1 -1
- package/dist/esm/components/CnChoiceCards/CnChoiceCards.vue2.js +22 -1
- package/dist/esm/components/CnChoiceCards/CnChoiceCards.vue2.js.map +1 -1
- package/dist/esm/components/CnChoiceCards/CnChoiceCards.vue3.js +26 -16
- package/dist/esm/components/CnChoiceCards/CnChoiceCards.vue3.js.map +1 -1
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue.js +1 -1
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js +70 -6
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js.map +1 -1
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue3.js +105 -74
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue3.js.map +1 -1
- package/dist/esm/components/CnExportsWidget/CnExportsWidget.vue.js +9 -0
- package/dist/esm/components/CnExportsWidget/CnExportsWidget.vue.js.map +1 -0
- package/dist/esm/components/CnExportsWidget/CnExportsWidget.vue2.js +139 -0
- package/dist/esm/components/CnExportsWidget/CnExportsWidget.vue2.js.map +1 -0
- package/dist/esm/components/CnExportsWidget/CnExportsWidget.vue3.js +76 -0
- package/dist/esm/components/CnExportsWidget/CnExportsWidget.vue3.js.map +1 -0
- package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue.js +1 -1
- package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue2.js +160 -2
- package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue2.js.map +1 -1
- package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue3.js +206 -94
- package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue3.js.map +1 -1
- package/dist/esm/components/CnFilesBrowser/filesReview.js +61 -0
- package/dist/esm/components/CnFilesBrowser/filesReview.js.map +1 -0
- package/dist/esm/components/CnGroupedCardsWidget/CnGroupedCardsWidget.vue.js +9 -0
- package/dist/esm/components/CnGroupedCardsWidget/CnGroupedCardsWidget.vue.js.map +1 -0
- package/dist/esm/components/CnGroupedCardsWidget/CnGroupedCardsWidget.vue2.js +279 -0
- package/dist/esm/components/CnGroupedCardsWidget/CnGroupedCardsWidget.vue2.js.map +1 -0
- package/dist/esm/components/CnGroupedCardsWidget/CnGroupedCardsWidget.vue3.js +122 -0
- package/dist/esm/components/CnGroupedCardsWidget/CnGroupedCardsWidget.vue3.js.map +1 -0
- package/dist/esm/components/CnGroupedCardsWidget/index.js +29 -0
- package/dist/esm/components/CnGroupedCardsWidget/index.js.map +1 -0
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js +320 -74
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js.map +1 -1
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js +323 -213
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js.map +1 -1
- package/dist/esm/components/CnIndexPage/useNamedSource.js +30 -3
- package/dist/esm/components/CnIndexPage/useNamedSource.js.map +1 -1
- package/dist/esm/components/CnMapWidget/CnMapWidget.vue.js +1 -1
- package/dist/esm/components/CnMapWidget/CnMapWidget.vue2.js +15 -0
- package/dist/esm/components/CnMapWidget/CnMapWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnMapWidget/CnMapWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnMenuWidget/CnMenuWidget.vue.js +1 -1
- package/dist/esm/components/CnMenuWidget/CnMenuWidget.vue2.js +25 -1
- package/dist/esm/components/CnMenuWidget/CnMenuWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnMenuWidget/CnMenuWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue.js +1 -1
- package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue2.js +14 -1
- package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue3.js +14 -6
- package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue.js +1 -1
- package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue2.js +10 -0
- package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue2.js.map +1 -1
- package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue3.js +6 -1
- package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue3.js.map +1 -1
- package/dist/esm/components/CnOrderedListField/CnOrderedListField.vue.js +1 -1
- package/dist/esm/components/CnOrderedListField/CnOrderedListField.vue2.js +91 -4
- package/dist/esm/components/CnOrderedListField/CnOrderedListField.vue2.js.map +1 -1
- package/dist/esm/components/CnOrderedListField/CnOrderedListField.vue3.js +63 -38
- package/dist/esm/components/CnOrderedListField/CnOrderedListField.vue3.js.map +1 -1
- package/dist/esm/components/CnQuickFilterBar/CnQuickFilterBar.vue.js +1 -1
- package/dist/esm/components/CnQuickFilterBar/CnQuickFilterBar.vue2.js +106 -4
- package/dist/esm/components/CnQuickFilterBar/CnQuickFilterBar.vue2.js.map +1 -1
- package/dist/esm/components/CnQuickFilterBar/CnQuickFilterBar.vue3.js +70 -25
- package/dist/esm/components/CnQuickFilterBar/CnQuickFilterBar.vue3.js.map +1 -1
- package/dist/esm/components/CnSavedViewAlertWidget/CnSavedViewAlertWidget.vue.js +9 -0
- package/dist/esm/components/CnSavedViewAlertWidget/CnSavedViewAlertWidget.vue.js.map +1 -0
- package/dist/esm/components/CnSavedViewAlertWidget/CnSavedViewAlertWidget.vue2.js +175 -0
- package/dist/esm/components/CnSavedViewAlertWidget/CnSavedViewAlertWidget.vue2.js.map +1 -0
- package/dist/esm/components/CnSavedViewAlertWidget/CnSavedViewAlertWidget.vue3.js +77 -0
- package/dist/esm/components/CnSavedViewAlertWidget/CnSavedViewAlertWidget.vue3.js.map +1 -0
- package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue.js +1 -1
- package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue2.js +35 -2
- package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue2.js.map +1 -1
- package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue3.js.map +1 -1
- package/dist/esm/components/CnWidgetGrid/builtInWidgets.js +4 -0
- package/dist/esm/components/CnWidgetGrid/builtInWidgets.js.map +1 -1
- package/dist/esm/components/CnWidgetGrid/registerDashboardWidgets.js +1 -0
- package/dist/esm/components/CnWidgetGrid/registerDashboardWidgets.js.map +1 -1
- package/dist/esm/components/CnWidgetObjectTable/CnWidgetObjectTable.vue.js +1 -1
- package/dist/esm/components/CnWidgetObjectTable/CnWidgetObjectTable.vue2.js +2 -23
- package/dist/esm/components/CnWidgetObjectTable/CnWidgetObjectTable.vue2.js.map +1 -1
- package/dist/esm/components/CnWidgetObjectTable/CnWidgetObjectTable.vue3.js.map +1 -1
- package/dist/esm/composables/indexSources.js +176 -20
- package/dist/esm/composables/indexSources.js.map +1 -1
- package/dist/esm/composables/useEndpointSource.js +28 -6
- package/dist/esm/composables/useEndpointSource.js.map +1 -1
- package/dist/esm/index.js +1 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/l10n/en.json.js +41 -1
- package/dist/esm/l10n/en.json.js.map +1 -1
- package/dist/esm/l10n/nl.json.js +39 -1
- package/dist/esm/l10n/nl.json.js.map +1 -1
- package/dist/esm/library-style.js +1 -1
- package/dist/esm/nextcloud-vue.css +939 -376
- package/dist/esm/utils/builtInFormatters.js +24 -4
- package/dist/esm/utils/builtInFormatters.js.map +1 -1
- package/dist/esm/utils/languageMapText.js +50 -0
- package/dist/esm/utils/languageMapText.js.map +1 -0
- package/dist/esm/utils/libraryWidgetKeys.js +3 -0
- package/dist/esm/utils/libraryWidgetKeys.js.map +1 -1
- package/dist/esm/utils/mapList.js +71 -0
- package/dist/esm/utils/mapList.js.map +1 -0
- package/dist/esm/utils/rowClassRules.js +43 -0
- package/dist/esm/utils/rowClassRules.js.map +1 -0
- package/dist/esm/utils/validateManifestV2.compiled.js +3 -3
- package/dist/esm/utils/validateManifestV2.compiled.js.map +1 -1
- package/dist/esm/utils/visibleWhen.js +19 -2
- package/dist/esm/utils/visibleWhen.js.map +1 -1
- package/dist/nextcloud-vue.cjs.js +9681 -7136
- package/dist/nextcloud-vue.cjs.js.map +2 -2
- package/dist/nextcloud-vue.css +939 -376
- package/l10n/en.json +41 -1
- package/l10n/nl.json +39 -1
- package/package.json +1 -1
- package/src/components/CnActionsBar/CnActionsBar.md +1 -0
- package/src/components/CnActionsBar/CnActionsBar.vue +31 -4
- package/src/components/CnChartWidget/CnChartWidget.md +3 -2
- package/src/components/CnChartWidget/CnChartWidget.vue +42 -4
- package/src/components/CnChoiceCards/CnChoiceCards.md +39 -0
- package/src/components/CnChoiceCards/CnChoiceCards.vue +93 -16
- package/src/components/CnDashboardPage/CnDashboardPage.vue +110 -21
- package/src/components/CnExportsWidget/CnExportsWidget.vue +233 -0
- package/src/components/CnExportsWidget/index.js +7 -0
- package/src/components/CnFilesBrowser/CnFilesBrowser.vue +324 -0
- package/src/components/CnFilesBrowser/filesReview.js +57 -0
- package/src/components/CnGroupedCardsWidget/CnGroupedCardsWidget.vue +433 -0
- package/src/components/CnGroupedCardsWidget/index.js +28 -0
- package/src/components/CnIndexPage/CnIndexPage.md +5 -1
- package/src/components/CnIndexPage/CnIndexPage.vue +313 -9
- package/src/components/CnIndexPage/useNamedSource.js +30 -3
- package/src/components/CnMapWidget/CnMapWidget.vue +37 -0
- package/src/components/CnMenuWidget/CnMenuWidget.vue +25 -1
- package/src/components/CnObjectListWidget/CnObjectListWidget.vue +29 -1
- package/src/components/CnObjectSidebar/CnFilesTab.vue +15 -0
- package/src/components/CnOrderedListField/CnOrderedListField.vue +151 -5
- package/src/components/CnQuickFilterBar/CnQuickFilterBar.md +1 -0
- package/src/components/CnQuickFilterBar/CnQuickFilterBar.vue +159 -5
- package/src/components/CnSavedViewAlertWidget/CnSavedViewAlertWidget.vue +272 -0
- package/src/components/CnSavedViewAlertWidget/index.js +7 -0
- package/src/components/CnSetupWizard/CnSetupWizard.vue +35 -2
- package/src/components/CnWidgetGrid/builtInWidgets.js +4 -0
- package/src/components/CnWidgetGrid/registerDashboardWidgets.js +1 -0
- package/src/components/CnWidgetObjectTable/CnWidgetObjectTable.vue +2 -23
- package/src/components/index.js +3 -0
- package/src/composables/indexSources.js +175 -19
- package/src/composables/useEndpointSource.js +28 -6
- package/src/css/index-page.css +117 -0
- package/src/css/look-board-index.css +10 -0
- package/src/css/look-board.css +44 -0
- package/src/index.js +1 -0
- package/src/schemas/app-manifest-v2.schema.json +85 -3
- package/src/utils/builtInFormatters.js +24 -4
- package/src/utils/languageMapText.js +46 -0
- package/src/utils/libraryWidgetKeys.js +3 -0
- package/src/utils/mapList.js +67 -0
- package/src/utils/rowClassRules.js +39 -0
- package/src/utils/validateManifestV2.compiled.js +3 -3
- package/src/utils/visibleWhen.js +19 -2
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="cn-index-page"
|
|
3
|
-
:class="[lookClass, { 'cn-index-page--with-side-panel': hasSidePanel }]"
|
|
3
|
+
:class="[lookClass, { 'cn-index-page--with-side-panel': hasSidePanel, 'cn-index-page--quick-filters-toolbar': quickFilterPlacement === 'toolbar' }]"
|
|
4
4
|
data-testid="cn-index-page"
|
|
5
5
|
@keydown="onListKeydown">
|
|
6
6
|
<!-- Header — overridable via #header slot. CnPageHeader ALWAYS renders:
|
|
@@ -13,12 +13,12 @@
|
|
|
13
13
|
region (WCAG 2.4.6 / 1.3.1). -->
|
|
14
14
|
<slot
|
|
15
15
|
name="header"
|
|
16
|
-
:title="
|
|
16
|
+
:title="shownTitle"
|
|
17
17
|
:description="headerDescription"
|
|
18
18
|
:icon="resolvedIcon"
|
|
19
19
|
:showTitle="showTitle">
|
|
20
20
|
<CnPageHeader
|
|
21
|
-
:title="
|
|
21
|
+
:title="shownTitle"
|
|
22
22
|
:description="headerDescription"
|
|
23
23
|
:icon="showTitleIcon && !isBoardLook ? resolvedIcon : ''"
|
|
24
24
|
:breadcrumb="presented('breadcrumb')"
|
|
@@ -163,6 +163,7 @@
|
|
|
163
163
|
:showBuildiqButton="!buildiqInHeader"
|
|
164
164
|
:bulkNoun="boardBulkNoun"
|
|
165
165
|
:bulkHint="bulkHint ? cnTranslate(bulkHint) : bulkHint"
|
|
166
|
+
:bulkBandAlways="bulkBandAlways"
|
|
166
167
|
:pagination="effectivePagination"
|
|
167
168
|
:objectCount="effectiveObjects.length"
|
|
168
169
|
:selectable="selectable"
|
|
@@ -369,6 +370,7 @@
|
|
|
369
370
|
:tabs="tabStripEntries"
|
|
370
371
|
:mode="quickFilterMode"
|
|
371
372
|
:maxVisible="quickFilterMaxVisible"
|
|
373
|
+
:fit="quickFilterPlacement === 'toolbar'"
|
|
372
374
|
:multiple="quickFilterMultiple"
|
|
373
375
|
:activeIndex="activeQuickFilterIndex"
|
|
374
376
|
:selectedIndices="selectedQuickFilterIndices"
|
|
@@ -747,6 +749,7 @@
|
|
|
747
749
|
:sortOrder="effectiveSortOrder"
|
|
748
750
|
:sortKeys="effectiveSortKeys"
|
|
749
751
|
:selectable="selectable"
|
|
752
|
+
:hideHeader="hideTableHeader"
|
|
750
753
|
:rowClickToView="rowClickOpens"
|
|
751
754
|
:selectedIds="internalSelectedIds"
|
|
752
755
|
:rowKey="rowKey"
|
|
@@ -754,7 +757,7 @@
|
|
|
754
757
|
:excludeColumns="excludeColumns"
|
|
755
758
|
:includeColumns="includeColumns"
|
|
756
759
|
:columnOverrides="columnOverrides"
|
|
757
|
-
:rowClass="
|
|
760
|
+
:rowClass="compiledRowClass"
|
|
758
761
|
:rowTitle="rowTitle"
|
|
759
762
|
:showUnread="showUnreadRows"
|
|
760
763
|
:filterable="tableHeaderFilters"
|
|
@@ -845,9 +848,64 @@
|
|
|
845
848
|
filter / sidebar / quick-filter machinery as table and cards.
|
|
846
849
|
A marker click routes back through onRowClick for identical
|
|
847
850
|
detail-page navigation. -->
|
|
851
|
+
<!-- Map with a numbered list beside it (`mapConfig.list`,
|
|
852
|
+
DqZakenKaart): one framed card, the list numbered as the pins
|
|
853
|
+
are, the row under the pointer marked on both sides, and the
|
|
854
|
+
rows without a place counted under the list with a way to
|
|
855
|
+
the table. -->
|
|
856
|
+
<div v-else-if="currentViewMode === 'map' && mapListEnabled"
|
|
857
|
+
class="cn-index-page__map-card"
|
|
858
|
+
data-testid="cn-index-map-card">
|
|
859
|
+
<CnMapWidget
|
|
860
|
+
class="cn-index-page__map"
|
|
861
|
+
:center="mapCenter"
|
|
862
|
+
:zoom="mapZoom"
|
|
863
|
+
:layers="mapLayers"
|
|
864
|
+
:basemaps="mapBasemaps"
|
|
865
|
+
:markers="mapMarkers"
|
|
866
|
+
:clustering="mapClustering"
|
|
867
|
+
:autoFit="true"
|
|
868
|
+
height="100%"
|
|
869
|
+
@markerClick="onMarkerClick" />
|
|
870
|
+
<div class="cn-index-page__map-side">
|
|
871
|
+
<ol class="cn-index-page__map-list" :aria-label="mapListLabel" data-testid="cn-index-map-list">
|
|
872
|
+
<li v-for="item in mapList.items"
|
|
873
|
+
:key="item.key"
|
|
874
|
+
class="cn-index-page__map-item"
|
|
875
|
+
:class="{ 'cn-index-page__map-item--active': activeMapKey === item.key }"
|
|
876
|
+
data-testid="cn-index-map-item"
|
|
877
|
+
@mouseenter="activeMapKey = item.key"
|
|
878
|
+
@mouseleave="activeMapKey = ''"
|
|
879
|
+
@focusin="activeMapKey = item.key">
|
|
880
|
+
<span class="cn-index-page__map-number" aria-hidden="true">{{ item.n }}</span>
|
|
881
|
+
<div class="cn-index-page__map-text">
|
|
882
|
+
<button type="button" class="cn-index-page__map-title" @click="onRowClick(item.row)">
|
|
883
|
+
{{ item.title }}
|
|
884
|
+
</button>
|
|
885
|
+
<span v-if="item.sub" class="cn-index-page__map-sub">{{ item.sub }}</span>
|
|
886
|
+
<span v-if="item.pills.length > 0 || item.due" class="cn-index-page__map-pills">
|
|
887
|
+
<CnStatusBadge v-for="(pill, index) in item.pills"
|
|
888
|
+
:key="index"
|
|
889
|
+
:label="pill.label"
|
|
890
|
+
:variant="pill.variant" />
|
|
891
|
+
<span v-if="item.due" class="cn-index-page__map-due">{{ item.due }}</span>
|
|
892
|
+
</span>
|
|
893
|
+
</div>
|
|
894
|
+
</li>
|
|
895
|
+
</ol>
|
|
896
|
+
<div v-if="mapList.missing.length > 0" class="cn-index-page__map-missing" data-testid="cn-index-map-missing">
|
|
897
|
+
<strong>{{ mapMissingTitle }}</strong>
|
|
898
|
+
<NcButton variant="tertiary-no-background" data-testid="cn-index-map-missing-table" @click="onViewModeChange('table')">
|
|
899
|
+
{{ mapMissingLink }}
|
|
900
|
+
</NcButton>
|
|
901
|
+
</div>
|
|
902
|
+
</div>
|
|
903
|
+
</div>
|
|
904
|
+
|
|
848
905
|
<CnMapWidget
|
|
849
906
|
v-else-if="currentViewMode === 'map'"
|
|
850
907
|
class="cn-index-page__map"
|
|
908
|
+
:zoom="mapZoom"
|
|
851
909
|
:center="mapCenter"
|
|
852
910
|
:layers="mapLayers"
|
|
853
911
|
:basemaps="mapBasemaps"
|
|
@@ -1194,6 +1252,7 @@ import CnQuickEditDialog from '../../dialogs/CnQuickEditDialog.vue'
|
|
|
1194
1252
|
import CnBuildiqEditButton from '../CnBuildiqEditButton/CnBuildiqEditButton.vue'
|
|
1195
1253
|
import CnEmptyContent from '../CnEmptyContent/CnEmptyContent.vue'
|
|
1196
1254
|
import CnFollowToggle from '../CnFollowToggle/CnFollowToggle.vue'
|
|
1255
|
+
import CnStatusBadge from '../CnStatusBadge/CnStatusBadge.vue'
|
|
1197
1256
|
import CnIndexPageWidgets from './CnIndexPageWidgets.vue'
|
|
1198
1257
|
import { useContextMenu } from '../../composables/index.js'
|
|
1199
1258
|
import { useLook } from '../../composables/useLook.js'
|
|
@@ -1223,6 +1282,7 @@ import { lensUnavailableText } from '../../utils/lensAvailability.js'
|
|
|
1223
1282
|
import { isModifiedClick, openRowTarget } from '../../utils/linkNavigation.js'
|
|
1224
1283
|
import { resolveClaimedTeams, resolveClaimTokens, splitViewsIntoTabs, viewAsTab, viewIdOf } from '../../utils/listLenses.js'
|
|
1225
1284
|
import { LIST_SHORTCUTS, listPaletteCommands, shortcutFor } from '../../utils/listShortcuts.js'
|
|
1285
|
+
import { mapListItems } from '../../utils/mapList.js'
|
|
1226
1286
|
import { multiKeySort } from '../../utils/multiKeySort.js'
|
|
1227
1287
|
import { fetchGroups } from '../../utils/nextcloudDirectory.js'
|
|
1228
1288
|
import { OBJECTS_CHANGED_EVENT } from '../../utils/objectSignals.js'
|
|
@@ -1234,6 +1294,7 @@ import { resolveFilterMap } from '../../utils/routeFilters.js'
|
|
|
1234
1294
|
import { availableRowActions, DEFAULT_ROW_ACTION_FIELD, refusalReasonFor, undeclaredRowActions, withoutViewWhenRowOpensDetail } from '../../utils/rowActionAvailability.js'
|
|
1235
1295
|
import { isRowActionVisible, rowActionPayload } from '../../utils/rowActionItem.js'
|
|
1236
1296
|
import { isNewTabClick, isNewTabHandled, isRowMiddleClick, markNewTabHandled, preventMiddleClickAutoscroll } from '../../utils/rowAuxClick.js'
|
|
1297
|
+
import { compileRowClass } from '../../utils/rowClassRules.js'
|
|
1237
1298
|
import { DEFAULT_ROW_INDICATOR_CAP } from '../../utils/rowIndicators.js'
|
|
1238
1299
|
import { buildRouteQueryFromViewState, buildViewCreatePayload, extractViewState, extractViewStateFromRouteQuery, normalizeSharedWith, savedViewScope, viewMatchesScope } from '../../utils/savedViewHelpers.js'
|
|
1239
1300
|
import { columnsFromSchema, fieldsFromSchema } from '../../utils/schema.js'
|
|
@@ -1508,6 +1569,7 @@ export default {
|
|
|
1508
1569
|
|
|
1509
1570
|
components: {
|
|
1510
1571
|
CnIndexPageWidgets,
|
|
1572
|
+
CnStatusBadge,
|
|
1511
1573
|
NcNoteCard,
|
|
1512
1574
|
CnBuildiqEditButton,
|
|
1513
1575
|
CnFollowToggle,
|
|
@@ -1576,6 +1638,29 @@ export default {
|
|
|
1576
1638
|
* Falls back to an empty object so `CnIndexPage` works standalone
|
|
1577
1639
|
* (unit tests, isolated mount) without `CnAppRoot`.
|
|
1578
1640
|
*/
|
|
1641
|
+
/**
|
|
1642
|
+
* The list a side-panel widget reads (`cnIndexList`): the applied saved
|
|
1643
|
+
* view, the list's total, and a way to hand back a view that changed
|
|
1644
|
+
* (the saved-view alert widget). Getters, so a widget follows the page.
|
|
1645
|
+
*
|
|
1646
|
+
* @return {object}
|
|
1647
|
+
*/
|
|
1648
|
+
provide() {
|
|
1649
|
+
return {
|
|
1650
|
+
cnIndexList: Object.defineProperties({}, {
|
|
1651
|
+
appliedView: { enumerable: true, get: () => this.appliedSavedView },
|
|
1652
|
+
total: {
|
|
1653
|
+
enumerable: true,
|
|
1654
|
+
get: () => {
|
|
1655
|
+
const total = this.effectivePagination && this.effectivePagination.total
|
|
1656
|
+
return typeof total === 'number' ? total : undefined
|
|
1657
|
+
},
|
|
1658
|
+
},
|
|
1659
|
+
replaceSavedView: { enumerable: true, value: (view) => this.replaceSavedView(view) },
|
|
1660
|
+
}),
|
|
1661
|
+
}
|
|
1662
|
+
},
|
|
1663
|
+
|
|
1579
1664
|
inject: {
|
|
1580
1665
|
cnCustomComponents: { default: () => ({}) },
|
|
1581
1666
|
/** The permissions the user holds, provided by CnAppRoot; for gated page tabs. */
|
|
@@ -1856,6 +1941,17 @@ export default {
|
|
|
1856
1941
|
default: '',
|
|
1857
1942
|
},
|
|
1858
1943
|
|
|
1944
|
+
/**
|
|
1945
|
+
* Board look: draw the bulk band before anything is selected too, its
|
|
1946
|
+
* buttons disabled until there is a selection (DqZaken, DqWerkbord).
|
|
1947
|
+
* Manifest key `config.bulkBandAlways`. Only when the band has an
|
|
1948
|
+
* action to offer.
|
|
1949
|
+
*/
|
|
1950
|
+
bulkBandAlways: {
|
|
1951
|
+
type: Boolean,
|
|
1952
|
+
default: false,
|
|
1953
|
+
},
|
|
1954
|
+
|
|
1859
1955
|
/**
|
|
1860
1956
|
* Board look: the 13px hint after the bulk band's buttons ("See what
|
|
1861
1957
|
* changes first, then run it"). Manifest key `config.bulkHint`.
|
|
@@ -1873,7 +1969,9 @@ export default {
|
|
|
1873
1969
|
* variant?, icon?, format?, id? }`: `action` is `add` (the Add flow;
|
|
1874
1970
|
* its label defaults to the Add label), `export` (the export leaf in
|
|
1875
1971
|
* `format`, `csv` by default, else the export dialog), `import`,
|
|
1876
|
-
* `refresh`,
|
|
1972
|
+
* `refresh`, `save-view` (the save-current-view dialog: the board's
|
|
1973
|
+
* "Zoekopdracht opslaan", label "Save view" by default), or the id of a
|
|
1974
|
+
* `headerActions` entry; `variant` is
|
|
1877
1975
|
* `primary` or `secondary` (the default). Shown only with
|
|
1878
1976
|
* `showTitle`. When they show, the actions bar drops its Views and
|
|
1879
1977
|
* Actions menus, and the Add button and Export menu when a button
|
|
@@ -2035,6 +2133,21 @@ export default {
|
|
|
2035
2133
|
default: null,
|
|
2036
2134
|
},
|
|
2037
2135
|
|
|
2136
|
+
/**
|
|
2137
|
+
* Where the quick-filter chips sit (manifest `config.quickFilterPlacement`).
|
|
2138
|
+
* `''` (the default) as before. `'toolbar'` keeps them on one row with
|
|
2139
|
+
* the Filter button and the view switch, in whatever width that row has
|
|
2140
|
+
* beside a side panel (DqTeamwachtrij): the chips take the room the
|
|
2141
|
+
* buttons leave, and those that do not fit move into the overflow chip.
|
|
2142
|
+
*
|
|
2143
|
+
* @type {''|'toolbar'}
|
|
2144
|
+
*/
|
|
2145
|
+
quickFilterPlacement: {
|
|
2146
|
+
type: String,
|
|
2147
|
+
default: '',
|
|
2148
|
+
validator: (v) => ['', 'toolbar'].includes(v),
|
|
2149
|
+
},
|
|
2150
|
+
|
|
2038
2151
|
/**
|
|
2039
2152
|
* How the quick filters render: `'chips'` (pill strip, default) or
|
|
2040
2153
|
* `'dropdown'` (a single `NcSelect`). Sourced from the manifest as
|
|
@@ -2185,6 +2298,16 @@ export default {
|
|
|
2185
2298
|
default: true,
|
|
2186
2299
|
},
|
|
2187
2300
|
|
|
2301
|
+
/**
|
|
2302
|
+
* Draw the table without its column-header row (manifest
|
|
2303
|
+
* `config.hideTableHeader`), for a list the board draws as plain rows
|
|
2304
|
+
* (DqTeamwachtrij). Pair it with `selectable: false` for no checkboxes.
|
|
2305
|
+
*/
|
|
2306
|
+
hideTableHeader: {
|
|
2307
|
+
type: Boolean,
|
|
2308
|
+
default: false,
|
|
2309
|
+
},
|
|
2310
|
+
|
|
2188
2311
|
/**
|
|
2189
2312
|
* When true, a row/card click emits `row-click` (to open/navigate) even
|
|
2190
2313
|
* while `selectable` — selection then happens via the checkbox only.
|
|
@@ -2328,8 +2451,15 @@ export default {
|
|
|
2328
2451
|
* - `popupField` — object property rendered in the marker popup.
|
|
2329
2452
|
* - `center` — optional `[lat, lng]` fallback centre when the filtered set
|
|
2330
2453
|
* has no plottable rows.
|
|
2454
|
+
* - `zoom` — the map's initial zoom level.
|
|
2455
|
+
* - `list` — a numbered list beside the map, map and list in one card
|
|
2456
|
+
* (DqZakenKaart): `{ title, sub?, pills?: [{ path?, text?, map?,
|
|
2457
|
+
* colorMap? }], due? }`, field templates read per row. The pins carry the
|
|
2458
|
+
* list's numbers, the row under the pointer is marked on both, the rows
|
|
2459
|
+
* without a place are counted under the list with a link to the table,
|
|
2460
|
+
* and the page's count line adds how many are on the map.
|
|
2331
2461
|
*
|
|
2332
|
-
* @type {{ latField?: string, lngField?: string, geoField?: string, popupField?: string, center?: [number, number] }}
|
|
2462
|
+
* @type {{ latField?: string, lngField?: string, geoField?: string, popupField?: string, center?: [number, number], zoom?: number, list?: object }}
|
|
2333
2463
|
*/
|
|
2334
2464
|
mapConfig: {
|
|
2335
2465
|
type: Object,
|
|
@@ -2594,9 +2724,18 @@ export default {
|
|
|
2594
2724
|
default: 'Loading…',
|
|
2595
2725
|
},
|
|
2596
2726
|
|
|
2597
|
-
/**
|
|
2727
|
+
/**
|
|
2728
|
+
* CSS class(es) for a row: a function `(row) => string`, or (manifest
|
|
2729
|
+
* `config.rowClass`) rules `[{ when: { field, op?, value }, class }]`,
|
|
2730
|
+
* each adding its class to a row whose field compares to the value
|
|
2731
|
+
* (the `visibleWhen` operators, `@today` included). DqTaken marks an
|
|
2732
|
+
* overdue task: `{ when: { field: "dueAt", op: "lt", value: "@today" },
|
|
2733
|
+
* class: "cn-row--overdue" }`.
|
|
2734
|
+
*
|
|
2735
|
+
* @type {((row: object) => string)|Array<{when: {field: string, op?: string, value: unknown}, class: string}>|null}
|
|
2736
|
+
*/
|
|
2598
2737
|
rowClass: {
|
|
2599
|
-
type: Function,
|
|
2738
|
+
type: [Function, Array],
|
|
2600
2739
|
default: null,
|
|
2601
2740
|
},
|
|
2602
2741
|
|
|
@@ -3678,6 +3817,10 @@ export default {
|
|
|
3678
3817
|
//
|
|
3679
3818
|
// Seeded from the route query so a shared link lands filtered, the
|
|
3680
3819
|
// same way `_order` and a deep-link filter already do for self-fetch.
|
|
3820
|
+
// The page a paging named source shows: page 1 at the source config's
|
|
3821
|
+
// `limit` (20 by default), moved by the pager.
|
|
3822
|
+
const namedPageSize = Number(props.sourceConfig && props.sourceConfig.limit) > 0 ? Number(props.sourceConfig.limit) : 20
|
|
3823
|
+
const namedPaging = ref({ page: 1, limit: namedPageSize })
|
|
3681
3824
|
const namedActiveFilters = ref(namedFiltersFromRoute(getCurrentInstance(), props))
|
|
3682
3825
|
|
|
3683
3826
|
const {
|
|
@@ -3686,7 +3829,7 @@ export default {
|
|
|
3686
3829
|
namedRows,
|
|
3687
3830
|
namedLoading,
|
|
3688
3831
|
namedQuickFilters,
|
|
3689
|
-
} = useNamedSource(props, { activeQuickFilterIndex, activeFilters: namedActiveFilters })
|
|
3832
|
+
} = useNamedSource(props, { activeQuickFilterIndex, activeFilters: namedActiveFilters, paging: namedPaging })
|
|
3690
3833
|
|
|
3691
3834
|
return {
|
|
3692
3835
|
isBoard: isBoardLook,
|
|
@@ -3698,6 +3841,7 @@ export default {
|
|
|
3698
3841
|
namedLoading,
|
|
3699
3842
|
namedQuickFilters,
|
|
3700
3843
|
namedActiveFilters,
|
|
3844
|
+
namedPaging,
|
|
3701
3845
|
contextMenuOpen,
|
|
3702
3846
|
contextMenuRow,
|
|
3703
3847
|
openContextMenu,
|
|
@@ -3745,6 +3889,8 @@ export default {
|
|
|
3745
3889
|
pageTabCounts: {},
|
|
3746
3890
|
/** The `headerMetaCounts` totals, by name; a failed one is null. */
|
|
3747
3891
|
headerMetaCountValues: {},
|
|
3892
|
+
/** The row the pointer is on in the map list, by key; '' for none. */
|
|
3893
|
+
activeMapKey: '',
|
|
3748
3894
|
/** The tabs `quickFiltersFrom` produced, or null before they load. */
|
|
3749
3895
|
generatedQuickFilters: null,
|
|
3750
3896
|
/** Count per saved-view id, for the views control; null = none. */
|
|
@@ -4658,6 +4804,9 @@ export default {
|
|
|
4658
4804
|
const loaded = this.effectivePagination || {}
|
|
4659
4805
|
return Number(loaded.page || 1) < Number(loaded.pages || 1)
|
|
4660
4806
|
}
|
|
4807
|
+
if (this.isNamedSource && this.namedSource && this.namedSource.pages === true) {
|
|
4808
|
+
return Number(this.effectivePagination?.pages || 1) > 1
|
|
4809
|
+
}
|
|
4661
4810
|
return Number(this.pagination?.pages || 1) > 1
|
|
4662
4811
|
},
|
|
4663
4812
|
|
|
@@ -5503,6 +5652,8 @@ export default {
|
|
|
5503
5652
|
*/
|
|
5504
5653
|
mapMarkers() {
|
|
5505
5654
|
const features = []
|
|
5655
|
+
// With the list beside the map, a pin carries the row's number there.
|
|
5656
|
+
const numbers = this.mapListEnabled ? new Map(this.mapList.items.map((item) => [item.row, item.n])) : null
|
|
5506
5657
|
for (const row of this.displayObjects) {
|
|
5507
5658
|
const geometry = this.resolveRowGeometry(row)
|
|
5508
5659
|
if (!geometry) {
|
|
@@ -5514,6 +5665,7 @@ export default {
|
|
|
5514
5665
|
properties: {
|
|
5515
5666
|
[this.rowKey]: row[this.rowKey],
|
|
5516
5667
|
...(this.mapConfig.popupField ? { [this.mapConfig.popupField]: row[this.mapConfig.popupField] } : {}),
|
|
5668
|
+
...(numbers && numbers.has(row) ? { markerNumber: numbers.get(row), markerActive: this.activeMapKey === String(row[this.rowKey]) } : {}),
|
|
5517
5669
|
},
|
|
5518
5670
|
})
|
|
5519
5671
|
}
|
|
@@ -5540,6 +5692,57 @@ export default {
|
|
|
5540
5692
|
return this.mapConfig.clustering !== false
|
|
5541
5693
|
},
|
|
5542
5694
|
|
|
5695
|
+
/** @return {number|undefined} The map's initial zoom (`mapConfig.zoom`), when a number. */
|
|
5696
|
+
mapZoom() {
|
|
5697
|
+
const zoom = this.mapConfig && this.mapConfig.zoom
|
|
5698
|
+
return typeof zoom === 'number' && Number.isFinite(zoom) ? zoom : undefined
|
|
5699
|
+
},
|
|
5700
|
+
|
|
5701
|
+
/** @return {boolean} Whether the map draws its numbered list (`mapConfig.list`). */
|
|
5702
|
+
mapListEnabled() {
|
|
5703
|
+
const list = this.mapConfig && this.mapConfig.list
|
|
5704
|
+
return Boolean(list && typeof list === 'object' && typeof list.title === 'string' && list.title !== '')
|
|
5705
|
+
},
|
|
5706
|
+
|
|
5707
|
+
/**
|
|
5708
|
+
* The map list's entries, numbered as the pins, and the rows without a
|
|
5709
|
+
* place. Templates go through the host's translate first.
|
|
5710
|
+
*
|
|
5711
|
+
* @return {{items: Array<object>, missing: Array<object>}}
|
|
5712
|
+
*/
|
|
5713
|
+
mapList() {
|
|
5714
|
+
if (!this.mapListEnabled) {
|
|
5715
|
+
return { items: [], missing: [] }
|
|
5716
|
+
}
|
|
5717
|
+
const list = this.mapConfig.list
|
|
5718
|
+
const translated = {
|
|
5719
|
+
...list,
|
|
5720
|
+
title: this.cnTranslate(list.title),
|
|
5721
|
+
sub: list.sub ? this.cnTranslate(list.sub) : '',
|
|
5722
|
+
due: list.due ? this.cnTranslate(list.due) : '',
|
|
5723
|
+
}
|
|
5724
|
+
return mapListItems(this.displayObjects, translated, {
|
|
5725
|
+
rowKey: this.rowKey,
|
|
5726
|
+
located: (row) => Boolean(this.resolveRowGeometry(row)),
|
|
5727
|
+
translate: (text) => this.cnTranslate(text),
|
|
5728
|
+
})
|
|
5729
|
+
},
|
|
5730
|
+
|
|
5731
|
+
/** @return {string} The list's accessible name. */
|
|
5732
|
+
mapListLabel() {
|
|
5733
|
+
return t('nextcloud-vue', 'On the map')
|
|
5734
|
+
},
|
|
5735
|
+
|
|
5736
|
+
/** @return {string} The card under the list, for the rows without a place. */
|
|
5737
|
+
mapMissingTitle() {
|
|
5738
|
+
return n('nextcloud-vue', '%n without an address', '%n without an address', this.mapList.missing.length)
|
|
5739
|
+
},
|
|
5740
|
+
|
|
5741
|
+
/** @return {string} The link from that card to the table. */
|
|
5742
|
+
mapMissingLink() {
|
|
5743
|
+
return t('nextcloud-vue', 'Show them in the table')
|
|
5744
|
+
},
|
|
5745
|
+
|
|
5543
5746
|
/**
|
|
5544
5747
|
* Extra (non-background) map layers — WMS / WFS / GeoJSON overlays declared in
|
|
5545
5748
|
* `mapConfig.layers`. The background map comes from `mapBasemaps` instead, so
|
|
@@ -5640,9 +5843,57 @@ export default {
|
|
|
5640
5843
|
if (this.selfFetchFailed) {
|
|
5641
5844
|
return { ...this.list.pagination.value, total: 0, page: 1, pages: 1 }
|
|
5642
5845
|
}
|
|
5846
|
+
// A named source that reports its own total (the search source)
|
|
5847
|
+
// gives the count line its number.
|
|
5848
|
+
if (this.isNamedSource && this.namedSource && typeof this.namedSource.total === 'function') {
|
|
5849
|
+
const total = this.namedSource.total()
|
|
5850
|
+
// A source with `pages: true` gets the pager the self-fetched lists draw.
|
|
5851
|
+
if (this.namedSource.pages === true) {
|
|
5852
|
+
const { page, limit } = this.namedPaging
|
|
5853
|
+
return { page, limit, total, pages: Math.max(1, Math.ceil(total / limit)) }
|
|
5854
|
+
}
|
|
5855
|
+
return { ...(this.pagination || {}), total }
|
|
5856
|
+
}
|
|
5643
5857
|
return this.isSelfFetchMode ? this.list.pagination.value : this.pagination
|
|
5644
5858
|
},
|
|
5645
5859
|
|
|
5860
|
+
/**
|
|
5861
|
+
* The saved view the page has applied, or null.
|
|
5862
|
+
*
|
|
5863
|
+
* @return {object|null}
|
|
5864
|
+
*/
|
|
5865
|
+
appliedSavedView() {
|
|
5866
|
+
const id = this.appliedSavedViewId
|
|
5867
|
+
if (!id) {
|
|
5868
|
+
return null
|
|
5869
|
+
}
|
|
5870
|
+
return (this.savedViews || []).find((view) => view && (String(view.id) === id || String(view.slug) === id || String(view.uuid) === id)) || null
|
|
5871
|
+
},
|
|
5872
|
+
|
|
5873
|
+
/**
|
|
5874
|
+
* The term a named source searched for, for `{term}` in the title and
|
|
5875
|
+
* the count line ("Zoeken: Lindelaan"), or ''.
|
|
5876
|
+
*
|
|
5877
|
+
* @return {string}
|
|
5878
|
+
*/
|
|
5879
|
+
sourceTerm() {
|
|
5880
|
+
return this.isNamedSource && this.namedSource && typeof this.namedSource.term === 'function' ? String(this.namedSource.term() || '') : ''
|
|
5881
|
+
},
|
|
5882
|
+
|
|
5883
|
+
/**
|
|
5884
|
+
* The page title with `{term}` filled in.
|
|
5885
|
+
*
|
|
5886
|
+
* @return {string}
|
|
5887
|
+
*/
|
|
5888
|
+
shownTitle() {
|
|
5889
|
+
const title = this.presented('title')
|
|
5890
|
+
// A title with the term is translated here, before the term goes in,
|
|
5891
|
+
// so its catalogue entry is found ("Zoeken: {term}").
|
|
5892
|
+
return typeof title === 'string' && title.includes('{term}')
|
|
5893
|
+
? this.cnTranslate(title).replace(/\{term\}/g, this.sourceTerm)
|
|
5894
|
+
: title
|
|
5895
|
+
},
|
|
5896
|
+
|
|
5646
5897
|
/**
|
|
5647
5898
|
* Whether the table marks unread rows. The boards draw every row alike,
|
|
5648
5899
|
* so under the board look only a page that offers the Unread lens
|
|
@@ -5854,6 +6105,16 @@ export default {
|
|
|
5854
6105
|
return (this.effectiveSchema && this.effectiveSchema.slug) || ''
|
|
5855
6106
|
},
|
|
5856
6107
|
|
|
6108
|
+
/**
|
|
6109
|
+
* The row-class function the table takes: a function as given, or the
|
|
6110
|
+
* manifest's rules compiled.
|
|
6111
|
+
*
|
|
6112
|
+
* @return {?(row: object) => string}
|
|
6113
|
+
*/
|
|
6114
|
+
compiledRowClass() {
|
|
6115
|
+
return compileRowClass(this.rowClass)
|
|
6116
|
+
},
|
|
6117
|
+
|
|
5857
6118
|
/** @return {number} How many leading columns the person pinned (0 while a saved view's columns are applied). */
|
|
5858
6119
|
pinnedColumnCount() {
|
|
5859
6120
|
if (!this.personalColumns || Array.isArray(this.appliedViewColumns) || !this.personalLayout) {
|
|
@@ -6383,6 +6644,9 @@ export default {
|
|
|
6383
6644
|
if (label === '' && button.action === 'actions-menu') {
|
|
6384
6645
|
label = t('nextcloud-vue', 'Actions')
|
|
6385
6646
|
}
|
|
6647
|
+
if (label === '' && button.action === 'save-view') {
|
|
6648
|
+
label = t('nextcloud-vue', 'Save view')
|
|
6649
|
+
}
|
|
6386
6650
|
return {
|
|
6387
6651
|
key: String(button.id || button.action || index),
|
|
6388
6652
|
label,
|
|
@@ -6710,7 +6974,23 @@ export default {
|
|
|
6710
6974
|
return valid.length > 0 ? JSON.stringify(valid) : ''
|
|
6711
6975
|
},
|
|
6712
6976
|
|
|
6977
|
+
/**
|
|
6978
|
+
* The header's description line, and on the map with its list the
|
|
6979
|
+
* number of rows on the map after a middle dot ("· 5 met een adres op
|
|
6980
|
+
* de kaart", DqZakenKaart).
|
|
6981
|
+
*
|
|
6982
|
+
* @return {string}
|
|
6983
|
+
*/
|
|
6713
6984
|
headerDescription() {
|
|
6985
|
+
const base = this.headerDescriptionBase
|
|
6986
|
+
if (this.currentViewMode !== 'map' || !this.mapListEnabled) {
|
|
6987
|
+
return base
|
|
6988
|
+
}
|
|
6989
|
+
const onMap = n('nextcloud-vue', '%n with an address on the map', '%n with an address on the map', this.mapList.items.length)
|
|
6990
|
+
return base ? `${base} · ${onMap}` : onMap
|
|
6991
|
+
},
|
|
6992
|
+
|
|
6993
|
+
headerDescriptionBase() {
|
|
6714
6994
|
const total = this.effectivePagination?.total
|
|
6715
6995
|
// Board look: the count line is a template over the rows on this page
|
|
6716
6996
|
// and all rows, "{shown} of {total}" unless the page says otherwise.
|
|
@@ -6731,6 +7011,7 @@ export default {
|
|
|
6731
7011
|
return this.cnTranslate(countText)
|
|
6732
7012
|
.replace('{shown}', String(shown))
|
|
6733
7013
|
.replace('{total}', String(total))
|
|
7014
|
+
.replace(/\{term\}/g, this.sourceTerm)
|
|
6734
7015
|
}
|
|
6735
7016
|
return this.countLine(this.countSubtitle, total, shown)
|
|
6736
7017
|
}
|
|
@@ -8177,6 +8458,8 @@ export default {
|
|
|
8177
8458
|
this.showImportDialog = true
|
|
8178
8459
|
} else if (button.action === 'refresh') {
|
|
8179
8460
|
this.onRefreshEvent()
|
|
8461
|
+
} else if (button.action === 'save-view') {
|
|
8462
|
+
this.showSaveViewDialog = true
|
|
8180
8463
|
} else {
|
|
8181
8464
|
this.onHeaderAction({ action: button.action, id: button.action })
|
|
8182
8465
|
}
|
|
@@ -8556,6 +8839,9 @@ export default {
|
|
|
8556
8839
|
if (this.isSelfFetchMode && typeof this.list.onPageChange === 'function') {
|
|
8557
8840
|
this.list.onPageChange(page)
|
|
8558
8841
|
}
|
|
8842
|
+
if (this.isNamedSource && this.namedSource && this.namedSource.pages === true) {
|
|
8843
|
+
this.namedPaging = { ...this.namedPaging, page }
|
|
8844
|
+
}
|
|
8559
8845
|
this.$emit('page-changed', page)
|
|
8560
8846
|
},
|
|
8561
8847
|
|
|
@@ -8571,6 +8857,9 @@ export default {
|
|
|
8571
8857
|
if (this.isSelfFetchMode && typeof this.list.onPageSizeChange === 'function') {
|
|
8572
8858
|
this.list.onPageSizeChange(size)
|
|
8573
8859
|
}
|
|
8860
|
+
if (this.isNamedSource && this.namedSource && this.namedSource.pages === true) {
|
|
8861
|
+
this.namedPaging = { page: 1, limit: size }
|
|
8862
|
+
}
|
|
8574
8863
|
this.$emit('page-size-changed', size)
|
|
8575
8864
|
},
|
|
8576
8865
|
|
|
@@ -10187,6 +10476,21 @@ export default {
|
|
|
10187
10476
|
}
|
|
10188
10477
|
},
|
|
10189
10478
|
|
|
10479
|
+
/**
|
|
10480
|
+
* Put a saved view that changed elsewhere (its alert) back in the list,
|
|
10481
|
+
* matched on its id or uuid.
|
|
10482
|
+
*
|
|
10483
|
+
* @param {object} view The saved view as the server returned it.
|
|
10484
|
+
* @return {void}
|
|
10485
|
+
*/
|
|
10486
|
+
replaceSavedView(view) {
|
|
10487
|
+
if (!view || typeof view !== 'object') {
|
|
10488
|
+
return
|
|
10489
|
+
}
|
|
10490
|
+
const same = (other) => other && ((view.id !== undefined && other.id === view.id) || (view.uuid && other.uuid === view.uuid))
|
|
10491
|
+
this.savedViews = (this.savedViews || []).map((other) => (same(other) ? view : other))
|
|
10492
|
+
},
|
|
10493
|
+
|
|
10190
10494
|
async onSaveViewConfirm({ name, isPublic, sharedWith, presentation }) {
|
|
10191
10495
|
const state = this.isSelfFetchMode
|
|
10192
10496
|
? this.currentViewState()
|
|
@@ -75,7 +75,10 @@ export function useNamedSource(props, options = {}) {
|
|
|
75
75
|
}
|
|
76
76
|
}
|
|
77
77
|
|
|
78
|
-
const
|
|
78
|
+
const cnTranslate = inject('cnTranslate', null)
|
|
79
|
+
const source = resolveIndexSource(props.entitySource, props.sourceConfig, {
|
|
80
|
+
translate: (text) => (typeof cnTranslate === 'function' ? cnTranslate(text) : text),
|
|
81
|
+
})
|
|
79
82
|
|
|
80
83
|
// An unknown source name resolves to null and was already warned about.
|
|
81
84
|
// The page then behaves as an empty index rather than throwing.
|
|
@@ -102,6 +105,9 @@ export function useNamedSource(props, options = {}) {
|
|
|
102
105
|
const tabs = manifestTabs || sourceTabs
|
|
103
106
|
const activeIndex = options.activeQuickFilterIndex || null
|
|
104
107
|
const activeFilters = options.activeFilters || null
|
|
108
|
+
// A source that pages (`pages: true`) gets the page as `limit` and
|
|
109
|
+
// `offset`, from the pager the page draws for it.
|
|
110
|
+
const paging = source.pages === true ? (options.paging || null) : null
|
|
105
111
|
|
|
106
112
|
// Seed the default tab before the watcher below registers: the mount load
|
|
107
113
|
// already carries this tab's filter, so the seed must not fire a second
|
|
@@ -162,6 +168,7 @@ export function useNamedSource(props, options = {}) {
|
|
|
162
168
|
activeFilters ? activeFilters.value : null,
|
|
163
169
|
props.entitySource,
|
|
164
170
|
),
|
|
171
|
+
...(paging ? { limit: paging.value.limit, offset: (paging.value.page - 1) * paging.value.limit } : {}),
|
|
165
172
|
},
|
|
166
173
|
tokenCtx(),
|
|
167
174
|
)
|
|
@@ -179,15 +186,35 @@ export function useNamedSource(props, options = {}) {
|
|
|
179
186
|
|
|
180
187
|
// Registered AFTER the seed above, so only a person switching tabs
|
|
181
188
|
// reloads. Without tabs there is nothing to watch.
|
|
189
|
+
/**
|
|
190
|
+
* Reload for a new query: on a paging source back to page 1, which
|
|
191
|
+
* reloads through the paging watcher below.
|
|
192
|
+
*
|
|
193
|
+
* @return {void}
|
|
194
|
+
*/
|
|
195
|
+
function reloadFromFirstPage() {
|
|
196
|
+
if (paging && paging.value.page !== 1) {
|
|
197
|
+
paging.value = { ...paging.value, page: 1 }
|
|
198
|
+
return
|
|
199
|
+
}
|
|
200
|
+
loadActive()
|
|
201
|
+
}
|
|
202
|
+
|
|
182
203
|
if (tabs && activeIndex) {
|
|
183
|
-
watch(activeIndex,
|
|
204
|
+
watch(activeIndex, reloadFromFirstPage)
|
|
184
205
|
}
|
|
185
206
|
|
|
186
207
|
// A sidebar choice is a new QUERY, not a new view of the page already
|
|
187
208
|
// fetched, so it reloads. `deep` because the map is rewritten key by key
|
|
188
209
|
// and a shallow watch misses a second value added to the same field.
|
|
189
210
|
if (activeFilters) {
|
|
190
|
-
watch(activeFilters,
|
|
211
|
+
watch(activeFilters, reloadFromFirstPage, { deep: true })
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// A new page, or a new page size, is a new request. A new tab or filter
|
|
215
|
+
// first returns to page 1, which reloads through here.
|
|
216
|
+
if (paging) {
|
|
217
|
+
watch(paging, loadActive, { deep: true })
|
|
191
218
|
}
|
|
192
219
|
|
|
193
220
|
// No manual invalidation tick here on purpose. The adapters read from a
|
|
@@ -865,6 +865,21 @@ export default {
|
|
|
865
865
|
const color = (feature.properties && feature.properties.markerColor)
|
|
866
866
|
|| (this.cfg.markers && this.cfg.markers.iconColor)
|
|
867
867
|
|| 'var(--color-primary-element, #2196F3)'
|
|
868
|
+
// A numbered pin, the number the list beside the map shows for the
|
|
869
|
+
// same row (an index map with `mapConfig.list`); the active row's
|
|
870
|
+
// pin draws darker.
|
|
871
|
+
const number = feature.properties && Number(feature.properties.markerNumber)
|
|
872
|
+
if (Number.isInteger(number) && number > 0) {
|
|
873
|
+
const active = feature.properties.markerActive === true
|
|
874
|
+
return L.marker(latlng, {
|
|
875
|
+
icon: L.divIcon({
|
|
876
|
+
className: active ? 'cn-map-widget__pin cn-map-widget__pin--active' : 'cn-map-widget__pin',
|
|
877
|
+
html: `<span>${number}</span>`,
|
|
878
|
+
iconSize: [26, 26],
|
|
879
|
+
iconAnchor: [13, 13],
|
|
880
|
+
}),
|
|
881
|
+
})
|
|
882
|
+
}
|
|
868
883
|
if (this.cfg.markers && this.cfg.markers.iconUrl) {
|
|
869
884
|
return L.marker(latlng, {
|
|
870
885
|
icon: L.icon({ iconUrl: this.cfg.markers.iconUrl, iconSize: [25, 41], iconAnchor: [12, 41] }),
|
|
@@ -1479,3 +1494,25 @@ export default {
|
|
|
1479
1494
|
background: var(--color-background-hover);
|
|
1480
1495
|
}
|
|
1481
1496
|
</style>
|
|
1497
|
+
|
|
1498
|
+
<style>
|
|
1499
|
+
/* A numbered pin (`properties.markerNumber`): a 26px primary circle with its
|
|
1500
|
+
number in white, the active one darker. Unscoped, because Leaflet creates
|
|
1501
|
+
the marker element outside the template. */
|
|
1502
|
+
.cn-map-widget__pin {
|
|
1503
|
+
display: flex;
|
|
1504
|
+
align-items: center;
|
|
1505
|
+
justify-content: center;
|
|
1506
|
+
border: 2px solid var(--color-main-background);
|
|
1507
|
+
border-radius: 50%;
|
|
1508
|
+
background: var(--color-primary-element);
|
|
1509
|
+
color: var(--color-primary-element-text);
|
|
1510
|
+
font-size: 13px;
|
|
1511
|
+
font-weight: 700;
|
|
1512
|
+
box-sizing: border-box;
|
|
1513
|
+
}
|
|
1514
|
+
|
|
1515
|
+
.cn-map-widget__pin--active {
|
|
1516
|
+
background: var(--color-primary-element-light-text);
|
|
1517
|
+
}
|
|
1518
|
+
</style>
|