@conduction/nextcloud-vue 2.137.0 → 2.139.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 (105) hide show
  1. package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue.js +1 -1
  2. package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue2.js +6 -4
  3. package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue2.js.map +1 -1
  4. package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue3.js.map +1 -1
  5. package/dist/esm/components/CnChartWidget/CnChartWidget.vue.js +1 -1
  6. package/dist/esm/components/CnChartWidget/CnChartWidget.vue2.js.map +1 -1
  7. package/dist/esm/components/CnChartWidget/CnChartWidget.vue3.js.map +1 -1
  8. package/dist/esm/components/CnDetailCard/CnDetailCard.vue.js +1 -1
  9. package/dist/esm/components/CnDetailCard/CnDetailCard.vue2.js +6 -0
  10. package/dist/esm/components/CnDetailCard/CnDetailCard.vue2.js.map +1 -1
  11. package/dist/esm/components/CnDetailCard/CnDetailCard.vue3.js +24 -7
  12. package/dist/esm/components/CnDetailCard/CnDetailCard.vue3.js.map +1 -1
  13. package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue.js +1 -1
  14. package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue2.js +2 -0
  15. package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue2.js.map +1 -1
  16. package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue3.js.map +1 -1
  17. package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue.js +1 -1
  18. package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue2.js.map +1 -1
  19. package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue3.js.map +1 -1
  20. package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue.js +1 -1
  21. package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue2.js +43 -1
  22. package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue2.js.map +1 -1
  23. package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue3.js.map +1 -1
  24. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js +133 -6
  25. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js.map +1 -1
  26. package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js +25 -17
  27. package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js.map +1 -1
  28. package/dist/esm/components/CnIndexSidebar/CnIndexSidebar.vue2.js +2 -0
  29. package/dist/esm/components/CnIndexSidebar/CnIndexSidebar.vue2.js.map +1 -1
  30. package/dist/esm/components/CnIndexSidebar/CnIndexSidebar.vue3.js +13 -2
  31. package/dist/esm/components/CnIndexSidebar/CnIndexSidebar.vue3.js.map +1 -1
  32. package/dist/esm/components/CnMailTab/dashboardRegistration.js +4 -0
  33. package/dist/esm/components/CnMailTab/dashboardRegistration.js.map +1 -1
  34. package/dist/esm/components/CnNotificationMatrix/CnNotificationMatrix.vue.js +1 -1
  35. package/dist/esm/components/CnNotificationMatrix/CnNotificationMatrix.vue2.js.map +1 -1
  36. package/dist/esm/components/CnNotificationMatrix/CnNotificationMatrix.vue3.js.map +1 -1
  37. package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue.js +1 -1
  38. package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue2.js +1 -1
  39. package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue2.js.map +1 -1
  40. package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue3.js.map +1 -1
  41. package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue.js +1 -1
  42. package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue2.js +2 -0
  43. package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue2.js.map +1 -1
  44. package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue3.js +2 -1
  45. package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue3.js.map +1 -1
  46. package/dist/esm/components/CnOrderedListField/CnOrderedListField.vue.js +1 -1
  47. package/dist/esm/components/CnOrderedListField/CnOrderedListField.vue2.js +6 -0
  48. package/dist/esm/components/CnOrderedListField/CnOrderedListField.vue2.js.map +1 -1
  49. package/dist/esm/components/CnOrderedListField/CnOrderedListField.vue3.js +3 -3
  50. package/dist/esm/components/CnOrderedListField/CnOrderedListField.vue3.js.map +1 -1
  51. package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue.js +1 -1
  52. package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue2.js +16 -0
  53. package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue2.js.map +1 -1
  54. package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue3.js +11 -5
  55. package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue3.js.map +1 -1
  56. package/dist/esm/components/CnSavedViewMenuSettings/CnSavedViewMenuSettings.vue.js +1 -1
  57. package/dist/esm/components/CnSavedViewMenuSettings/CnSavedViewMenuSettings.vue2.js.map +1 -1
  58. package/dist/esm/components/CnSavedViewMenuSettings/CnSavedViewMenuSettings.vue3.js +1 -0
  59. package/dist/esm/components/CnSavedViewMenuSettings/CnSavedViewMenuSettings.vue3.js.map +1 -1
  60. package/dist/esm/components/CnUserSettingsDialog/CnUserSettingsDialog.vue.js +1 -1
  61. package/dist/esm/components/CnUserSettingsDialog/CnUserSettingsDialog.vue2.js.map +1 -1
  62. package/dist/esm/components/CnUserSettingsDialog/CnUserSettingsDialog.vue3.js.map +1 -1
  63. package/dist/esm/composables/indexSources.js +78 -12
  64. package/dist/esm/composables/indexSources.js.map +1 -1
  65. package/dist/esm/l10n/en.json.js +12 -1
  66. package/dist/esm/l10n/en.json.js.map +1 -1
  67. package/dist/esm/l10n/nl.json.js +12 -1
  68. package/dist/esm/l10n/nl.json.js.map +1 -1
  69. package/dist/esm/library-style.js +1 -1
  70. package/dist/esm/nextcloud-vue.css +685 -512
  71. package/dist/esm/utils/resolveFilterTokens.js +9 -0
  72. package/dist/esm/utils/resolveFilterTokens.js.map +1 -1
  73. package/dist/esm/utils/sentinelTokens.js +1 -1
  74. package/dist/esm/utils/sentinelTokens.js.map +1 -1
  75. package/dist/nextcloud-vue.cjs.js +580 -236
  76. package/dist/nextcloud-vue.cjs.js.map +2 -2
  77. package/dist/nextcloud-vue.css +685 -512
  78. package/l10n/en.json +12 -1
  79. package/l10n/nl.json +12 -1
  80. package/package.json +1 -1
  81. package/src/components/CnCellRenderer/CnCellRenderer.vue +6 -4
  82. package/src/components/CnChartWidget/CnChartWidget.vue +4 -0
  83. package/src/components/CnDetailCard/CnDetailCard.md +1 -0
  84. package/src/components/CnDetailCard/CnDetailCard.vue +25 -1
  85. package/src/components/CnDetailWidgetHost/CnDetailWidgetHost.vue +2 -0
  86. package/src/components/CnFactsWidget/CnFactsWidget.vue +6 -4
  87. package/src/components/CnFilesBrowser/CnFilesBrowser.vue +54 -1
  88. package/src/components/CnIndexPage/CnIndexPage.vue +135 -7
  89. package/src/components/CnIndexSidebar/CnIndexSidebar.vue +10 -2
  90. package/src/components/CnMailTab/dashboardRegistration.js +4 -0
  91. package/src/components/CnNotificationMatrix/CnNotificationMatrix.vue +4 -0
  92. package/src/components/CnObjectListWidget/CnObjectListWidget.vue +1 -1
  93. package/src/components/CnObjectSidebar/CnFilesTab.vue +3 -0
  94. package/src/components/CnOrderedListField/CnOrderedListField.vue +11 -1
  95. package/src/components/CnRecordListWidget/CnRecordListWidget.vue +22 -3
  96. package/src/components/CnSavedViewMenuSettings/CnSavedViewMenuSettings.vue +1 -0
  97. package/src/components/CnUserSettingsDialog/CnUserSettingsDialog.vue +3 -0
  98. package/src/composables/indexSources.js +78 -12
  99. package/src/css/dialog.css +26 -0
  100. package/src/css/index-page.css +5 -0
  101. package/src/css/look-board-detail.css +36 -0
  102. package/src/css/look-board-index.css +21 -0
  103. package/src/css/look-board.css +47 -0
  104. package/src/utils/resolveFilterTokens.js +9 -0
  105. package/src/utils/sentinelTokens.js +1 -1
@@ -38,7 +38,8 @@ import { countLine } from '../../utils/countLine.js';
38
38
  import { reportBindingProblems } from '../../utils/diagnostics.js';
39
39
  import { fetchGroupedCounts } from '../../utils/fetchAggregate.js';
40
40
  import { fetchListTotal, fetchFilterCounts } from '../../utils/fetchFilterCounts.js';
41
- import { rangeEnds, listText, relativeRangeText, rangeChipText } from '../../utils/filterRangeLabel.js';
41
+ import { fillTemplate } from '../../utils/fillTemplate.js';
42
+ import { listText, rangeEnds, relativeRangeText, rangeChipText } from '../../utils/filterRangeLabel.js';
42
43
  import { unwrapAppConfig } from '../../utils/formatMetric.js';
43
44
  import { loadGroupDisplayName, groupDisplayName } from '../../utils/groupAutocomplete.js';
44
45
  import { HEADING_LEVEL } from '../../utils/headingLevel.js';
@@ -821,6 +822,21 @@ var script = {
821
822
  default: '',
822
823
  },
823
824
 
825
+ /**
826
+ * Board look: the count line while a saved view is applied (manifest
827
+ * `config.savedViewCountText`), a template as `countText` that may name
828
+ * the view's conditions as `{view}`: its description, else its filters
829
+ * in words (DqFilterInMenu "3 van 48 lopende zaken · termijn binnen 7
830
+ * dagen, van mij · gesorteerd op termijn"). A view's own `countText`
831
+ * override and a scope's come first.
832
+ *
833
+ * @spec openspec/changes/applied-view-lights-its-lens/specs/applied-view-lights-its-lens/spec.md
834
+ */
835
+ savedViewCountText: {
836
+ type: String,
837
+ default: '',
838
+ },
839
+
824
840
  /**
825
841
  * Board look: a count line per view (manifest `config.countTextByView`),
826
842
  * `{ table?, cards?, list?, board?, map? }`, each a template as
@@ -3161,6 +3177,8 @@ var script = {
3161
3177
  savedViewCounts: null,
3162
3178
  // The id (or slug) of the saved view that is applied; its chip shows selected under the board look.
3163
3179
  appliedSavedViewId: '',
3180
+ /** Whether the reader picked a lens chip after the applied view (then their chip shows). */
3181
+ lensChosenByHand: false,
3164
3182
  // The sort option the applied view's `overrides.sortOption` selected, so leaving the view can undo it.
3165
3183
  viewSortOption: '',
3166
3184
  // The applied view's filters as one comparable key, so the address keeps naming the view until they change.
@@ -5000,13 +5018,53 @@ var script = {
5000
5018
  * @spec openspec/changes/working-list-row-actions/specs/index-page/spec.md
5001
5019
  */
5002
5020
  /**
5003
- * The chip the strip lights: the active tab, else the default tab of
5004
- * tabs that arrived after setup (`quickFiltersFrom`), which is the
5005
- * one the fetch applies.
5021
+ * The lens chip an applied saved view narrows within: the non-default
5022
+ * tab whose every condition the view's own conditions (its filters
5023
+ * over its locked filters, tokens as written) hold, the most specific
5024
+ * first (DqFilterInMenu: "Termijn deze week" lit for the view of that
5025
+ * name). Null without an applied view or a fitting tab.
5026
+ *
5027
+ * @return {number|null} The tab index.
5028
+ * @spec openspec/changes/applied-view-lights-its-lens/specs/applied-view-lights-its-lens/spec.md
5029
+ */
5030
+ appliedViewLensIndex() {
5031
+ const view = this.appliedSavedView;
5032
+ const tabs = Array.isArray(this.tabStripEntries) ? this.tabStripEntries : [];
5033
+ if (!view || tabs.length === 0) {
5034
+ return null
5035
+ }
5036
+ const query = view.query && typeof view.query === 'object' ? view.query : {};
5037
+ const locked = query.overrides && typeof query.overrides.lockedFilters === 'object' ? query.overrides.lockedFilters : {};
5038
+ const conditions = { ...(locked || {}), ...(query.filters || view.filters || {}) };
5039
+ const same = (a, b) => JSON.stringify(Array.isArray(a) ? a.map(String) : String(a)) === JSON.stringify(Array.isArray(b) ? b.map(String) : String(b));
5040
+ let best = null;
5041
+ let bestSize = 0;
5042
+ tabs.forEach((tab, index) => {
5043
+ const filter = tab && tab.filter && typeof tab.filter === 'object' ? tab.filter : {};
5044
+ const keys = Object.keys(filter);
5045
+ if (tab.default === true || keys.length === 0 || keys.length <= bestSize) {
5046
+ return
5047
+ }
5048
+ if (keys.every((key) => Object.hasOwn(conditions, key) && same(conditions[key], filter[key]))) {
5049
+ best = index;
5050
+ bestSize = keys.length;
5051
+ }
5052
+ });
5053
+ return best
5054
+ },
5055
+
5056
+ /**
5057
+ * The chip the strip lights: the lens an applied saved view narrows
5058
+ * within (until the reader picks a chip), else the active tab, else
5059
+ * the default tab of tabs that arrived after setup
5060
+ * (`quickFiltersFrom`), which is the one the fetch applies.
5006
5061
  *
5007
5062
  * @return {number|null} The tab index, or null without tabs.
5008
5063
  */
5009
5064
  shownQuickFilterIndex() {
5065
+ if (!this.quickFilterMultiple && !this.lensChosenByHand && this.appliedViewLensIndex !== null) {
5066
+ return this.appliedViewLensIndex
5067
+ }
5010
5068
  if (this.activeQuickFilterIndex !== null && this.activeQuickFilterIndex !== undefined) {
5011
5069
  return this.activeQuickFilterIndex
5012
5070
  }
@@ -5800,6 +5858,31 @@ var script = {
5800
5858
  return translatePlural('nextcloud-vue', '%n without an address', '%n without an address', this.mapList.missing.length)
5801
5859
  },
5802
5860
 
5861
+ /**
5862
+ * The sentence on that card naming the rows without a place by the
5863
+ * list's title template, three at most and the rest counted: "A, B and
5864
+ * C have no location, so they are not on the map." Empty without a
5865
+ * title template.
5866
+ *
5867
+ * @spec openspec/changes/map-missing-card-names-the-cases/specs/map-missing-card-names-the-cases/spec.md#requirement-the-missing-address-card-names-the-cases-it-counts
5868
+ * @return {string} The sentence.
5869
+ */
5870
+ mapMissingNote() {
5871
+ const list = this.mapConfig && this.mapConfig.list;
5872
+ const template = list && typeof list.title === 'string' ? this.cnTranslate(list.title) : '';
5873
+ const missing = this.mapList.missing;
5874
+ if (template === '' || missing.length === 0) {
5875
+ return ''
5876
+ }
5877
+ const shown = missing.slice(0, 3).map((row) => fillTemplate(template, row, undefined, this.cnFormatters ? { formatters: this.cnFormatters } : null)).filter((title) => title !== '');
5878
+ if (shown.length === 0) {
5879
+ return ''
5880
+ }
5881
+ const rest = missing.length - shown.length;
5882
+ const names = listText(rest > 0 ? [...shown, translatePlural('nextcloud-vue', '%n other', '%n others', rest)] : shown, getCanonicalLocale() || undefined);
5883
+ return translatePlural('nextcloud-vue', '{names} has no location, so it is not on the map.', '{names} have no location, so they are not on the map.', missing.length, { names })
5884
+ },
5885
+
5803
5886
  /** @return {string} The link from that card to the table. */
5804
5887
  mapMissingLink() {
5805
5888
  return translate('nextcloud-vue', 'Show them in the table')
@@ -7371,6 +7454,11 @@ var script = {
7371
7454
  * @return {string}
7372
7455
  */
7373
7456
  presentedCountText() {
7457
+ const viewLine = this.savedViewCountText;
7458
+ const view = this.appliedSavedView;
7459
+ if (view && typeof viewLine === 'string' && viewLine !== '' && this.activeScopePresentation.countText === undefined && !savedViewOverrides(view)?.countText) {
7460
+ return viewLine
7461
+ }
7374
7462
  if (this.activeScopePresentation.countText === undefined) {
7375
7463
  const byView = this.countTextByView;
7376
7464
  const own = byView && typeof byView === 'object' ? byView[this.currentViewMode] : undefined;
@@ -7381,6 +7469,23 @@ var script = {
7381
7469
  return this.presented('countText')
7382
7470
  },
7383
7471
 
7472
+ /**
7473
+ * The applied saved view's conditions for the count line's `{view}`:
7474
+ * its description, else its filters in words, starting lower case.
7475
+ *
7476
+ * @return {string}
7477
+ * @spec openspec/changes/applied-view-lights-its-lens/specs/applied-view-lights-its-lens/spec.md
7478
+ */
7479
+ appliedViewConditionsText() {
7480
+ const view = this.appliedSavedView;
7481
+ if (!view) {
7482
+ return ''
7483
+ }
7484
+ const own = typeof view.description === 'string' ? view.description.trim() : '';
7485
+ const text = own !== '' ? own : String(this.viewFilterSummary(view) || '');
7486
+ return text.charAt(0).toLowerCase() + text.slice(1)
7487
+ },
7488
+
7384
7489
  headerDescriptionBase() {
7385
7490
  const total = this.effectivePagination?.total;
7386
7491
  // Board look: the count line is a template over the rows on this page
@@ -7404,6 +7509,7 @@ var script = {
7404
7509
  .replace('{shown}', String(shown))
7405
7510
  .replace('{total}', String(total))
7406
7511
  .replace(/\{term\}/g, this.sourceTerm)
7512
+ .replace(/\{view\}/g, this.appliedViewConditionsText)
7407
7513
  }
7408
7514
  return this.countLine(this.countSubtitle, total, shown)
7409
7515
  }
@@ -7469,6 +7575,17 @@ var script = {
7469
7575
  return !!this.resolvedSidebar.enabled && this.resolvedSidebar.show !== false
7470
7576
  },
7471
7577
 
7578
+ /**
7579
+ * Whether the page's side panel is open now; the board look then lays
7580
+ * the header out narrower (DqZakenSorteren).
7581
+ *
7582
+ * @spec openspec/changes/board-header-buttons-under-title-beside-side-panel/specs/board-header-buttons-under-title-beside-side-panel/spec.md#requirement-the-header-buttons-sit-under-the-title-while-the-side-panel-is-open
7583
+ * @return {boolean}
7584
+ */
7585
+ sidebarPanelOpen() {
7586
+ return Boolean(this.sidebarOpen && this.hasSidebar)
7587
+ },
7588
+
7472
7589
  /**
7473
7590
  * Whether the board toolbar draws the Filter button as a menu: the
7474
7591
  * board look, `filterMenu` on, something to filter by, and no filter
@@ -7511,7 +7628,9 @@ var script = {
7511
7628
 
7512
7629
  /** Search props forwarded to the embedded CnIndexSidebar (defaults applied per CnIndexSidebar). */
7513
7630
  sidebarSearchProps() {
7514
- return (this.sidebar && this.sidebar.search) || {}
7631
+ // The page's own search hint, unless `sidebar.search` names one.
7632
+ const own = this.shownSearchPlaceholder ? { searchPlaceholder: this.shownSearchPlaceholder } : {};
7633
+ return { ...own, ...((this.sidebar && this.sidebar.search) || {}) }
7515
7634
  },
7516
7635
 
7517
7636
  /**
@@ -9334,6 +9453,7 @@ var script = {
9334
9453
  // `activeQuickFilterIndex` is a setup-returned ref; the
9335
9454
  // Vue 2 ref-unwrap proxy makes plain assignment work.
9336
9455
  this.activeQuickFilterIndex = index;
9456
+ this.lensChosenByHand = true;
9337
9457
  this.$emit('quick-filter-change', index);
9338
9458
  },
9339
9459
 
@@ -10102,10 +10222,16 @@ var script = {
10102
10222
  const bucket = facet && Array.isArray(facet.values)
10103
10223
  ? facet.values.find((fv) => fv && typeof fv === 'object' && String(fv.value) === id)
10104
10224
  : null;
10105
- if (bucket && typeof bucket.label === 'string' && bucket.label !== '') {
10225
+ // A facet that only echoes the value names nothing; a group or an
10226
+ // option below may.
10227
+ if (bucket && typeof bucket.label === 'string' && bucket.label !== '' && bucket.label !== id) {
10106
10228
  return this.cnTranslate(bucket.label)
10107
10229
  }
10108
10230
  const prop = this.effectiveSchema?.properties?.[key];
10231
+ // The reader on a user filter is "me" (DqFilterInMenu "Behandelaar: ik").
10232
+ if (prop && prop.referenceType === 'nextcloud-user' && id === (getCurrentUser()?.uid ?? '')) {
10233
+ return translate('nextcloud-vue', 'me')
10234
+ }
10109
10235
  if (prop && prop.referenceType === 'nextcloud-group') {
10110
10236
  const name = groupDisplayName(id);
10111
10237
  if (name === null) {
@@ -11763,6 +11889,7 @@ var script = {
11763
11889
  */
11764
11890
  onApplySavedView(view, { keepSavedViewKey = false } = {}) {
11765
11891
  this.appliedSavedViewId = view && (view.id || view.slug) ? String(view.id || view.slug) : '';
11892
+ this.lensChosenByHand = false;
11766
11893
  const state = extractViewState(view);
11767
11894
  // A view's filters may carry tokens (`@me`, `@myTeam`): resolved here,
11768
11895
  // and an optional one that answers nothing (no team) is dropped. A