@conduction/nextcloud-vue 2.62.0 → 2.63.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 (154) hide show
  1. package/dist/esm/components/CnAdminActionCard/CnAdminActionCard.vue.js +10 -0
  2. package/dist/esm/components/CnAdminActionCard/CnAdminActionCard.vue.js.map +1 -0
  3. package/dist/esm/components/CnAdminActionCard/CnAdminActionCard.vue2.js +189 -0
  4. package/dist/esm/components/CnAdminActionCard/CnAdminActionCard.vue2.js.map +1 -0
  5. package/dist/esm/components/CnAdminActionCard/CnAdminActionCard.vue3.js +72 -0
  6. package/dist/esm/components/CnAdminActionCard/CnAdminActionCard.vue3.js.map +1 -0
  7. package/dist/esm/components/CnAppNav/CnAppNav.vue2.js +271 -32
  8. package/dist/esm/components/CnAppNav/CnAppNav.vue2.js.map +1 -1
  9. package/dist/esm/components/CnAppNav/CnAppNav.vue3.js.map +1 -1
  10. package/dist/esm/components/CnAppRoot/CnAppRoot.vue2.js +99 -9
  11. package/dist/esm/components/CnAppRoot/CnAppRoot.vue2.js.map +1 -1
  12. package/dist/esm/components/CnAppRoot/CnAppRoot.vue3.js +39 -18
  13. package/dist/esm/components/CnAppRoot/CnAppRoot.vue3.js.map +1 -1
  14. package/dist/esm/components/CnChoiceCards/CnChoiceCards.vue2.js.map +1 -1
  15. package/dist/esm/components/CnChoiceCards/CnChoiceCards.vue3.js +53 -37
  16. package/dist/esm/components/CnChoiceCards/CnChoiceCards.vue3.js.map +1 -1
  17. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js.map +1 -1
  18. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue3.js +2 -2
  19. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue3.js.map +1 -1
  20. package/dist/esm/components/CnDataTable/CnColumnFilterPopover.vue.js +10 -0
  21. package/dist/esm/components/CnDataTable/CnColumnFilterPopover.vue.js.map +1 -0
  22. package/dist/esm/components/CnDataTable/CnColumnFilterPopover.vue2.js +293 -0
  23. package/dist/esm/components/CnDataTable/CnColumnFilterPopover.vue2.js.map +1 -0
  24. package/dist/esm/components/CnDataTable/CnColumnFilterPopover.vue3.js +189 -0
  25. package/dist/esm/components/CnDataTable/CnColumnFilterPopover.vue3.js.map +1 -0
  26. package/dist/esm/components/CnDataTable/CnDataTable.vue2.js +216 -8
  27. package/dist/esm/components/CnDataTable/CnDataTable.vue2.js.map +1 -1
  28. package/dist/esm/components/CnDataTable/CnDataTable.vue3.js +118 -50
  29. package/dist/esm/components/CnDataTable/CnDataTable.vue3.js.map +1 -1
  30. package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue2.js.map +1 -1
  31. package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue3.js +2 -1
  32. package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue3.js.map +1 -1
  33. package/dist/esm/components/CnFieldHelper/CnFieldHelper.vue2.js +3 -1
  34. package/dist/esm/components/CnFieldHelper/CnFieldHelper.vue2.js.map +1 -1
  35. package/dist/esm/components/CnFieldHelper/CnFieldHelper.vue3.js +1 -1
  36. package/dist/esm/components/CnFieldHelper/CnFieldHelper.vue3.js.map +1 -1
  37. package/dist/esm/components/CnFormDialog/CnFormDialog.vue2.js +234 -9
  38. package/dist/esm/components/CnFormDialog/CnFormDialog.vue2.js.map +1 -1
  39. package/dist/esm/components/CnFormDialog/CnFormDialog.vue3.js +96 -57
  40. package/dist/esm/components/CnFormDialog/CnFormDialog.vue3.js.map +1 -1
  41. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js +51 -2
  42. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js.map +1 -1
  43. package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js +5 -1
  44. package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js.map +1 -1
  45. package/dist/esm/components/CnIndexPage/selfModeActions.js +3 -3
  46. package/dist/esm/components/CnIndexPage/selfModeActions.js.map +1 -1
  47. package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue2.js +36 -1
  48. package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue2.js.map +1 -1
  49. package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue3.js +4 -1
  50. package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue3.js.map +1 -1
  51. package/dist/esm/components/CnResourceSelect/CnResourceSelect.vue2.js +121 -12
  52. package/dist/esm/components/CnResourceSelect/CnResourceSelect.vue2.js.map +1 -1
  53. package/dist/esm/components/CnResourceSelect/CnResourceSelect.vue3.js +3 -1
  54. package/dist/esm/components/CnResourceSelect/CnResourceSelect.vue3.js.map +1 -1
  55. package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue2.js +326 -1
  56. package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue2.js.map +1 -1
  57. package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue3.js +112 -26
  58. package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue3.js.map +1 -1
  59. package/dist/esm/components/CnTimelineWidget/CnTimelineWidget.vue.js +10 -0
  60. package/dist/esm/components/CnTimelineWidget/CnTimelineWidget.vue.js.map +1 -0
  61. package/dist/esm/components/CnTimelineWidget/CnTimelineWidget.vue2.js +337 -0
  62. package/dist/esm/components/CnTimelineWidget/CnTimelineWidget.vue2.js.map +1 -0
  63. package/dist/esm/components/CnTimelineWidget/CnTimelineWidget.vue3.js +102 -0
  64. package/dist/esm/components/CnTimelineWidget/CnTimelineWidget.vue3.js.map +1 -0
  65. package/dist/esm/components/CnTimelineWidget/dashboardRegistration.js +34 -0
  66. package/dist/esm/components/CnTimelineWidget/dashboardRegistration.js.map +1 -0
  67. package/dist/esm/components/CnWalkthrough/CnWalkthrough.vue2.js +131 -8
  68. package/dist/esm/components/CnWalkthrough/CnWalkthrough.vue2.js.map +1 -1
  69. package/dist/esm/components/CnWalkthrough/CnWalkthrough.vue3.js +40 -38
  70. package/dist/esm/components/CnWalkthrough/CnWalkthrough.vue3.js.map +1 -1
  71. package/dist/esm/components/CnWidgetGrid/builtInWidgets.js +8 -6
  72. package/dist/esm/components/CnWidgetGrid/builtInWidgets.js.map +1 -1
  73. package/dist/esm/components/CnWidgetGrid/registerDashboardWidgets.js +1 -0
  74. package/dist/esm/components/CnWidgetGrid/registerDashboardWidgets.js.map +1 -1
  75. package/dist/esm/components/CnWizardDialog/CnWizardDialog.vue2.js +19 -0
  76. package/dist/esm/components/CnWizardDialog/CnWizardDialog.vue2.js.map +1 -1
  77. package/dist/esm/components/CnWizardDialog/CnWizardDialog.vue3.js +1 -1
  78. package/dist/esm/components/CnWizardDialog/CnWizardDialog.vue3.js.map +1 -1
  79. package/dist/esm/composables/useDependencyCheck.js +65 -0
  80. package/dist/esm/composables/useDependencyCheck.js.map +1 -0
  81. package/dist/esm/composables/useWalkthrough.js +218 -6
  82. package/dist/esm/composables/useWalkthrough.js.map +1 -1
  83. package/dist/esm/index.js +2 -0
  84. package/dist/esm/index.js.map +1 -1
  85. package/dist/esm/l10n/en.json.js +43 -0
  86. package/dist/esm/l10n/en.json.js.map +1 -1
  87. package/dist/esm/l10n/nl.json.js +43 -0
  88. package/dist/esm/l10n/nl.json.js.map +1 -1
  89. package/dist/esm/nextcloud-vue.css +449 -0
  90. package/dist/esm/store/useObjectStore.js +8 -0
  91. package/dist/esm/store/useObjectStore.js.map +1 -1
  92. package/dist/esm/utils/columnFilters.js +311 -0
  93. package/dist/esm/utils/columnFilters.js.map +1 -0
  94. package/dist/esm/utils/groupAutocomplete.js +123 -0
  95. package/dist/esm/utils/groupAutocomplete.js.map +1 -0
  96. package/dist/esm/utils/libraryWidgetKeys.js +2 -0
  97. package/dist/esm/utils/libraryWidgetKeys.js.map +1 -1
  98. package/dist/esm/utils/pickerOptions.js +198 -0
  99. package/dist/esm/utils/pickerOptions.js.map +1 -0
  100. package/dist/esm/utils/schema.js +83 -7
  101. package/dist/esm/utils/schema.js.map +1 -1
  102. package/dist/esm/utils/timelineEvents.js +174 -0
  103. package/dist/esm/utils/timelineEvents.js.map +1 -0
  104. package/dist/esm/utils/validateManifestV2.compiled.js +2 -2
  105. package/dist/esm/utils/validateManifestV2.compiled.js.map +1 -1
  106. package/dist/esm/utils/walkthroughSignals.js +88 -0
  107. package/dist/esm/utils/walkthroughSignals.js.map +1 -0
  108. package/dist/nextcloud-vue.cjs.js +9369 -5193
  109. package/dist/nextcloud-vue.cjs.js.map +2 -2
  110. package/dist/nextcloud-vue.css +449 -0
  111. package/l10n/en.json +43 -0
  112. package/l10n/nl.json +43 -0
  113. package/package.json +1 -1
  114. package/src/components/CnAdminActionCard/CnAdminActionCard.vue +234 -0
  115. package/src/components/CnAdminActionCard/index.js +4 -0
  116. package/src/components/CnAppNav/CnAppNav.vue +271 -32
  117. package/src/components/CnAppRoot/CnAppRoot.vue +129 -15
  118. package/src/components/CnChoiceCards/CnChoiceCards.vue +56 -31
  119. package/src/components/CnDashboardPage/CnDashboardPage.vue +2 -2
  120. package/src/components/CnDataTable/CnColumnFilterPopover.vue +524 -0
  121. package/src/components/CnDataTable/CnDataTable.md +3 -0
  122. package/src/components/CnDataTable/CnDataTable.vue +260 -4
  123. package/src/components/CnDetailWidgetHost/CnDetailWidgetHost.vue +2 -2
  124. package/src/components/CnFieldHelper/CnFieldHelper.vue +4 -2
  125. package/src/components/CnFormDialog/CnFormDialog.vue +290 -31
  126. package/src/components/CnIndexPage/CnIndexPage.vue +55 -2
  127. package/src/components/CnIndexPage/selfModeActions.js +3 -3
  128. package/src/components/CnObjectListWidget/CnObjectListWidget.vue +39 -1
  129. package/src/components/CnResourceSelect/CnResourceSelect.vue +123 -12
  130. package/src/components/CnSetupWizard/CnSetupWizard.vue +392 -3
  131. package/src/components/CnTimelineWidget/CnTimelineWidget.vue +477 -0
  132. package/src/components/CnTimelineWidget/dashboardRegistration.js +32 -0
  133. package/src/components/CnTimelineWidget/index.js +4 -0
  134. package/src/components/CnWalkthrough/CnWalkthrough.vue +143 -10
  135. package/src/components/CnWidgetGrid/builtInWidgets.js +2 -0
  136. package/src/components/CnWidgetGrid/registerDashboardWidgets.js +1 -0
  137. package/src/components/CnWizardDialog/CnWizardDialog.vue +20 -1
  138. package/src/components/index.js +2 -0
  139. package/src/composables/useDependencyCheck.js +61 -0
  140. package/src/composables/useWalkthrough.js +217 -5
  141. package/src/css/dashboard.css +49 -0
  142. package/src/css/detail-page.css +19 -0
  143. package/src/css/table.css +81 -0
  144. package/src/index.js +2 -0
  145. package/src/schemas/app-manifest-v2.schema.json +23 -1
  146. package/src/store/useObjectStore.js +8 -0
  147. package/src/utils/columnFilters.js +324 -0
  148. package/src/utils/groupAutocomplete.js +119 -0
  149. package/src/utils/libraryWidgetKeys.js +2 -0
  150. package/src/utils/pickerOptions.js +194 -0
  151. package/src/utils/schema.js +83 -7
  152. package/src/utils/timelineEvents.js +171 -0
  153. package/src/utils/validateManifestV2.compiled.js +2 -2
  154. package/src/utils/walkthroughSignals.js +94 -0
@@ -13,6 +13,8 @@
13
13
  :disabled="disabled"
14
14
  :placeholder="placeholder"
15
15
  :filterable="false"
16
+ :multiple="multiple"
17
+ :keepOpen="multiple"
16
18
  label="label"
17
19
  @search="onSearch"
18
20
  @update:modelValue="onInput">
@@ -93,12 +95,21 @@ export default {
93
95
  required: true,
94
96
  },
95
97
 
96
- /** Currently-selected object id (v-model). */
98
+ /** Currently-selected object id (v-model), or an array of ids when `multiple`. */
97
99
  modelValue: {
98
- type: [String, Number],
100
+ type: [String, Number, Array],
99
101
  default: '',
100
102
  },
101
103
 
104
+ /**
105
+ * Pick several objects. `modelValue` is then an array of ids, and a
106
+ * create adds the new object to the selection.
107
+ */
108
+ multiple: {
109
+ type: Boolean,
110
+ default: false,
111
+ },
112
+
102
113
  /** Object field used as the option label AND written on create. */
103
114
  labelField: {
104
115
  type: String,
@@ -219,6 +230,9 @@ export default {
219
230
  // The selected option object kept locally so the label shows even
220
231
  // before/without a matching search result (e.g. a pre-set modelValue).
221
232
  localSelected: null,
233
+ // Options seen so far, keyed by value, so a multiple selection
234
+ // keeps its labels when the search results move on.
235
+ known: {},
222
236
  }
223
237
  },
224
238
 
@@ -232,6 +246,19 @@ export default {
232
246
  }
233
247
  },
234
248
 
249
+ /**
250
+ * The selected ids as strings (multiple mode).
251
+ *
252
+ * @return {string[]}
253
+ */
254
+ selectedIds() {
255
+ const value = this.modelValue
256
+ if (Array.isArray(value)) {
257
+ return value.filter((v) => v !== null && v !== undefined && v !== '').map((v) => String(v))
258
+ }
259
+ return value ? [String(value)] : []
260
+ },
261
+
235
262
  /** The `${register}-${schema}` object-type slug used by the store. */
236
263
  typeSlug() {
237
264
  return `${this.register}-${this.schema}`
@@ -239,6 +266,11 @@ export default {
239
266
 
240
267
  /** The currently-selected option, for NcSelect's model-value. */
241
268
  selectedOption() {
269
+ if (this.multiple) {
270
+ return this.selectedIds.map((id) => this.known[id]
271
+ || this.options.find((o) => o.value === id)
272
+ || { value: id, label: id })
273
+ }
242
274
  if (this.localSelected && this.localSelected.value === this.modelValue) {
243
275
  return this.localSelected
244
276
  }
@@ -310,9 +342,9 @@ export default {
310
342
  // The scope moved, so anything already selected may no longer be
311
343
  // in it. Drop the stale options + selection, then re-seed.
312
344
  this.options = []
313
- if (this.modelValue) {
345
+ if (this.selectedIds.length > 0) {
314
346
  this.localSelected = null
315
- this.$emit('update:modelValue', '')
347
+ this.$emit('update:modelValue', this.multiple ? [] : '')
316
348
  }
317
349
  if (this.search.trim().length >= this.minChars) {
318
350
  this.onSearch(this.search)
@@ -347,7 +379,7 @@ export default {
347
379
  const items = Array.isArray(collection)
348
380
  ? collection
349
381
  : (this.objectStore.collections[this.typeSlug] || [])
350
- this.options = items.map((o) => this.toOption(o))
382
+ this.options = this.remember(items.map((o) => this.toOption(o)))
351
383
  } catch {
352
384
  this.options = []
353
385
  } finally {
@@ -392,7 +424,7 @@ export default {
392
424
  const items = Array.isArray(collection)
393
425
  ? collection
394
426
  : (this.objectStore.collections[this.typeSlug] || [])
395
- this.options = items.map((o) => this.toOption(o))
427
+ this.options = this.remember(items.map((o) => this.toOption(o)))
396
428
  } catch {
397
429
  this.options = []
398
430
  } finally {
@@ -408,6 +440,10 @@ export default {
408
440
  * @return {Promise<void>}
409
441
  */
410
442
  async onInput(option) {
443
+ if (this.multiple) {
444
+ await this.onMultipleInput(Array.isArray(option) ? option : (option ? [option] : []))
445
+ return
446
+ }
411
447
  if (!option) {
412
448
  this.localSelected = null
413
449
  /**
@@ -425,19 +461,58 @@ export default {
425
461
  this.$emit('update:modelValue', option.value)
426
462
  },
427
463
 
464
+ /**
465
+ * Handle a change of a multiple selection. A synthetic create option
466
+ * creates the object and adds it; the rest emit their ids.
467
+ *
468
+ * @param {Array<object>} chosen The selected options.
469
+ * @return {Promise<void>}
470
+ */
471
+ async onMultipleInput(chosen) {
472
+ const createOption = chosen.find((o) => o && o.__create)
473
+ const ids = chosen.filter((o) => o && !o.__create).map((o) => String(o.value))
474
+ this.remember(chosen.filter((o) => o && !o.__create))
475
+ if (!createOption) {
476
+ this.$emit('update:modelValue', ids)
477
+ return
478
+ }
479
+ const created = await this.createFromTerm(createOption.label, ids)
480
+ if (!created) {
481
+ this.$emit('update:modelValue', ids)
482
+ }
483
+ },
484
+
485
+ /**
486
+ * Cache options by value so their labels survive a new search.
487
+ *
488
+ * @param {Array<object>} options Options to remember.
489
+ * @return {Array<object>} The same options.
490
+ */
491
+ remember(options) {
492
+ const next = { ...this.known }
493
+ for (const o of options) {
494
+ if (o && o.value) {
495
+ next[o.value] = o
496
+ }
497
+ }
498
+ this.known = next
499
+ return options
500
+ },
501
+
428
502
  /**
429
503
  * Create a new object from the typed term and select it.
430
504
  *
431
505
  * @param {string} term The term to write to `labelField`.
432
- * @return {Promise<void>}
506
+ * @param {string[]} [keep] Multiple mode: the ids already selected, which the new id joins.
507
+ * @return {Promise<object|null>} The created object, or null.
433
508
  */
434
- async createFromTerm(term) {
509
+ async createFromTerm(term, keep = []) {
435
510
  if (!this.objectStore && !this.createHandler) {
436
- return
511
+ return null
437
512
  }
438
513
  const name = (term || '').trim()
439
514
  if (!name) {
440
- return
515
+ return null
441
516
  }
442
517
  this.loading = true
443
518
  try {
@@ -456,20 +531,26 @@ export default {
456
531
  created = await this.objectStore.saveObject(this.typeSlug, payload)
457
532
  }
458
533
  if (!created) {
459
- return
534
+ return null
460
535
  }
461
536
  const option = this.toOption(created)
537
+ this.remember([option])
462
538
  this.options = [option, ...this.options.filter((o) => o.value !== option.value)]
463
539
  this.localSelected = option
464
- this.$emit('update:modelValue', option.value)
540
+ this.search = ''
541
+ this.$emit('update:modelValue', this.multiple
542
+ ? [...keep.filter((id) => id !== option.value), option.value]
543
+ : option.value)
465
544
  /**
466
545
  * @event create A new object was created from the search term.
467
546
  * @type {object} The created OpenRegister object.
468
547
  */
469
548
  this.$emit('create', created)
549
+ return created
470
550
  } catch (e) {
471
551
  // eslint-disable-next-line no-console
472
552
  console.warn('[CnResourceSelect] create failed', e)
553
+ return null
473
554
  } finally {
474
555
  this.loading = false
475
556
  }
@@ -508,6 +589,10 @@ export default {
508
589
  * @return {Promise<void>}
509
590
  */
510
591
  async ensureSelectedLoaded() {
592
+ if (this.multiple) {
593
+ await this.ensureManyLoaded()
594
+ return
595
+ }
511
596
  if (!this.modelValue || this.selectedOption || !this.objectStore) {
512
597
  return
513
598
  }
@@ -524,6 +609,32 @@ export default {
524
609
  // Leave the id un-labelled rather than crash.
525
610
  }
526
611
  },
612
+
613
+ /**
614
+ * Multiple mode: fetch each selected id whose label is not known yet.
615
+ *
616
+ * @return {Promise<void>}
617
+ */
618
+ async ensureManyLoaded() {
619
+ if (!this.objectStore || typeof this.objectStore.fetchObject !== 'function') {
620
+ return
621
+ }
622
+ const missing = this.selectedIds.filter((id) => !this.known[id] && !this.options.some((o) => o.value === id))
623
+ if (missing.length === 0) {
624
+ return
625
+ }
626
+ this.ensureRegistered()
627
+ for (const id of missing) {
628
+ try {
629
+ const obj = await this.objectStore.fetchObject(this.typeSlug, id)
630
+ if (obj) {
631
+ this.remember([this.toOption(obj)])
632
+ }
633
+ } catch {
634
+ // Leave the id un-labelled rather than crash.
635
+ }
636
+ }
637
+ },
527
638
  },
528
639
  }
529
640
  </script>