@conduction/nextcloud-vue 2.56.0-beta.12 → 2.56.0-beta.14

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 (119) hide show
  1. package/dist/esm/components/CnActionsBar/CnActionsBar.vue2.js +19 -0
  2. package/dist/esm/components/CnActionsBar/CnActionsBar.vue2.js.map +1 -1
  3. package/dist/esm/components/CnActionsBar/CnActionsBar.vue3.js +10 -3
  4. package/dist/esm/components/CnActionsBar/CnActionsBar.vue3.js.map +1 -1
  5. package/dist/esm/components/CnAppNav/CnAppNav.vue2.js +101 -5
  6. package/dist/esm/components/CnAppNav/CnAppNav.vue2.js.map +1 -1
  7. package/dist/esm/components/CnAppNav/CnAppNav.vue3.js +23 -7
  8. package/dist/esm/components/CnAppNav/CnAppNav.vue3.js.map +1 -1
  9. package/dist/esm/components/CnBreadcrumbs/CnBreadcrumbs.vue2.js +13 -0
  10. package/dist/esm/components/CnBreadcrumbs/CnBreadcrumbs.vue2.js.map +1 -1
  11. package/dist/esm/components/CnBreadcrumbs/CnBreadcrumbs.vue3.js +2 -1
  12. package/dist/esm/components/CnBreadcrumbs/CnBreadcrumbs.vue3.js.map +1 -1
  13. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js +125 -4
  14. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js.map +1 -1
  15. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue3.js +439 -381
  16. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue3.js.map +1 -1
  17. package/dist/esm/components/CnDataTable/CnColumnFilterPopover.vue2.js +9 -3
  18. package/dist/esm/components/CnDataTable/CnColumnFilterPopover.vue2.js.map +1 -1
  19. package/dist/esm/components/CnDataTable/CnColumnFilterPopover.vue3.js +1 -1
  20. package/dist/esm/components/CnDataTable/CnColumnFilterPopover.vue3.js.map +1 -1
  21. package/dist/esm/components/CnDataTable/CnDataTable.vue2.js +4 -4
  22. package/dist/esm/components/CnDataTable/CnDataTable.vue2.js.map +1 -1
  23. package/dist/esm/components/CnDataTable/CnDataTable.vue3.js.map +1 -1
  24. package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js +142 -26
  25. package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js.map +1 -1
  26. package/dist/esm/components/CnDetailPage/CnDetailPage.vue3.js +195 -124
  27. package/dist/esm/components/CnDetailPage/CnDetailPage.vue3.js.map +1 -1
  28. package/dist/esm/components/CnFkResolveCell/CnFkResolveCell.vue2.js +3 -1
  29. package/dist/esm/components/CnFkResolveCell/CnFkResolveCell.vue2.js.map +1 -1
  30. package/dist/esm/components/CnFormDialog/CnFormDialog.vue2.js +144 -4
  31. package/dist/esm/components/CnFormDialog/CnFormDialog.vue2.js.map +1 -1
  32. package/dist/esm/components/CnFormDialog/CnFormDialog.vue3.js.map +1 -1
  33. package/dist/esm/components/CnHeaderWidget/CnHeaderWidget.vue2.js +84 -11
  34. package/dist/esm/components/CnHeaderWidget/CnHeaderWidget.vue2.js.map +1 -1
  35. package/dist/esm/components/CnHeaderWidget/CnHeaderWidget.vue3.js +3 -2
  36. package/dist/esm/components/CnHeaderWidget/CnHeaderWidget.vue3.js.map +1 -1
  37. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js +31 -1
  38. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js.map +1 -1
  39. package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js +335 -313
  40. package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js.map +1 -1
  41. package/dist/esm/components/CnSegmentedControl/CnSegmentedControl.vue2.js +11 -0
  42. package/dist/esm/components/CnSegmentedControl/CnSegmentedControl.vue2.js.map +1 -1
  43. package/dist/esm/components/CnSegmentedControl/CnSegmentedControl.vue3.js +2 -1
  44. package/dist/esm/components/CnSegmentedControl/CnSegmentedControl.vue3.js.map +1 -1
  45. package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue2.js +5 -11
  46. package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue2.js.map +1 -1
  47. package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue3.js.map +1 -1
  48. package/dist/esm/components/CnStagesWidget/CnStagesWidget.vue2.js.map +1 -1
  49. package/dist/esm/components/CnStagesWidget/CnStagesWidget.vue3.js.map +1 -1
  50. package/dist/esm/components/CnStatWidget/CnStatWidget.vue2.js +22 -3
  51. package/dist/esm/components/CnStatWidget/CnStatWidget.vue2.js.map +1 -1
  52. package/dist/esm/components/CnStatWidget/CnStatWidget.vue3.js +10 -3
  53. package/dist/esm/components/CnStatWidget/CnStatWidget.vue3.js.map +1 -1
  54. package/dist/esm/composables/useDependencyCheck.js +44 -1
  55. package/dist/esm/composables/useDependencyCheck.js.map +1 -1
  56. package/dist/esm/composables/useListView.js +43 -1
  57. package/dist/esm/composables/useListView.js.map +1 -1
  58. package/dist/esm/composables/useSetupStatus.js +26 -3
  59. package/dist/esm/composables/useSetupStatus.js.map +1 -1
  60. package/dist/esm/l10n/en.json.js +7 -1
  61. package/dist/esm/l10n/en.json.js.map +1 -1
  62. package/dist/esm/l10n/nl.json.js +7 -1
  63. package/dist/esm/l10n/nl.json.js.map +1 -1
  64. package/dist/esm/mixins/pageViews.js +400 -0
  65. package/dist/esm/mixins/pageViews.js.map +1 -0
  66. package/dist/esm/nextcloud-vue.css +202 -2
  67. package/dist/esm/store/plugins/liveUpdates.js +19 -9
  68. package/dist/esm/store/plugins/liveUpdates.js.map +1 -1
  69. package/dist/esm/store/useObjectStore.js +138 -42
  70. package/dist/esm/store/useObjectStore.js.map +1 -1
  71. package/dist/esm/utils/actionsDispatcher.js +25 -2
  72. package/dist/esm/utils/actionsDispatcher.js.map +1 -1
  73. package/dist/esm/utils/columnFilters.js +27 -3
  74. package/dist/esm/utils/columnFilters.js.map +1 -1
  75. package/dist/esm/utils/schema.js +40 -2
  76. package/dist/esm/utils/schema.js.map +1 -1
  77. package/dist/esm/utils/validateManifestV2.compiled.js +2 -2
  78. package/dist/esm/utils/validateManifestV2.compiled.js.map +1 -1
  79. package/dist/nextcloud-vue.cjs.js +2857 -1335
  80. package/dist/nextcloud-vue.cjs.js.map +2 -2
  81. package/dist/nextcloud-vue.css +202 -2
  82. package/l10n/en.json +7 -1
  83. package/l10n/nl.json +7 -1
  84. package/package.json +1 -1
  85. package/src/components/CnActionsBar/CnActionsBar.md +2 -1
  86. package/src/components/CnActionsBar/CnActionsBar.vue +25 -1
  87. package/src/components/CnAppNav/CnAppNav.vue +150 -9
  88. package/src/components/CnBreadcrumbs/CnBreadcrumbs.vue +14 -0
  89. package/src/components/CnDashboardPage/CnDashboardPage.vue +194 -10
  90. package/src/components/CnDataTable/CnColumnFilterPopover.vue +11 -5
  91. package/src/components/CnDataTable/CnDataTable.md +1 -1
  92. package/src/components/CnDataTable/CnDataTable.vue +4 -4
  93. package/src/components/CnDetailPage/CnDetailPage.md +5 -1
  94. package/src/components/CnDetailPage/CnDetailPage.vue +208 -11
  95. package/src/components/CnFkResolveCell/CnFkResolveCell.vue +3 -1
  96. package/src/components/CnFormDialog/CnFormDialog.vue +144 -4
  97. package/src/components/CnHeaderWidget/CnHeaderWidget.vue +100 -13
  98. package/src/components/CnIndexPage/CnIndexPage.md +2 -1
  99. package/src/components/CnIndexPage/CnIndexPage.vue +47 -1
  100. package/src/components/CnSegmentedControl/CnSegmentedControl.md +1 -1
  101. package/src/components/CnSegmentedControl/CnSegmentedControl.vue +12 -0
  102. package/src/components/CnSetupWizard/CnSetupWizard.vue +5 -11
  103. package/src/components/CnStagesWidget/CnStagesWidget.vue +9 -0
  104. package/src/components/CnStatWidget/CnStatWidget.vue +33 -5
  105. package/src/composables/useDependencyCheck.js +43 -0
  106. package/src/composables/useListView.js +43 -1
  107. package/src/composables/useSetupStatus.js +26 -3
  108. package/src/css/actions-bar.css +20 -2
  109. package/src/css/detail-page.css +27 -0
  110. package/src/css/kpi-card.css +47 -0
  111. package/src/mixins/pageViews.js +396 -0
  112. package/src/schemas/app-manifest-v2.schema.json +53 -4
  113. package/src/schemas/app-manifest.schema.json +1 -1
  114. package/src/store/plugins/liveUpdates.js +19 -9
  115. package/src/store/useObjectStore.js +137 -41
  116. package/src/utils/actionsDispatcher.js +25 -2
  117. package/src/utils/columnFilters.js +29 -2
  118. package/src/utils/schema.js +40 -2
  119. package/src/utils/validateManifestV2.compiled.js +2 -2
@@ -264,6 +264,27 @@ const baseActions = {
264
264
  this.facets = { ...this.facets, [slug]: {} };
265
265
  },
266
266
 
267
+ /**
268
+ * Give a registered type a second schema path segment to try once when
269
+ * its own answers 404 (see `_fetchWithSchemaFallback`). Set by
270
+ * `resolveObjectOpType` for a schema title it kebab-cased, with the
271
+ * title as written. A type that is not registered is left alone.
272
+ *
273
+ * @spec openspec/changes/zuiddrecht-pixel-gaps-2/specs/zuiddrecht-pixel-gaps-2/spec.md#requirement-a-schema-title-falls-back-to-its-written-form
274
+ * @param {string} slug The type slug
275
+ * @param {string} schema The fallback schema path segment
276
+ */
277
+ setSchemaFallback(slug, schema) {
278
+ const config = this.objectTypeRegistry[slug];
279
+ if (!config || typeof schema !== 'string' || schema === '') {
280
+ return
281
+ }
282
+ this.objectTypeRegistry = {
283
+ ...this.objectTypeRegistry,
284
+ [slug]: { ...config, schemaFallback: schema },
285
+ };
286
+ },
287
+
267
288
  /**
268
289
  * Unregister an object type and clean up all its state.
269
290
  *
@@ -433,11 +454,12 @@ const baseActions = {
433
454
  *
434
455
  * @param {string} type The type slug
435
456
  * @param {string|null} [id] Optional object ID
457
+ * @param {string|null} [schema] Schema path segment to use instead of the type's own
436
458
  * @return {string} Full API URL path
437
459
  */
438
- _buildUrl(type, id = null) {
460
+ _buildUrl(type, id = null, schema = null) {
439
461
  const config = this._getTypeConfig(type);
440
- let url = `${this._options.baseUrl}/${config.register}/${config.schema}`;
462
+ let url = `${this._options.baseUrl}/${config.register}/${schema ?? config.schema}`;
441
463
  if (id) {
442
464
  url += `/${id}`;
443
465
  }
@@ -458,11 +480,12 @@ const baseActions = {
458
480
  * @param {string} type The type slug
459
481
  * @param {object} [params] Extra query parameters
460
482
  * @param {string|null} [id] Optional object ID
483
+ * @param {string|null} [schema] Schema path segment to use instead of the type's own
461
484
  * @return {string} Full API URL path including query string
462
485
  */
463
- _buildUrlWithParams(type, params = {}, id = null) {
486
+ _buildUrlWithParams(type, params = {}, id = null, schema = null) {
464
487
  const config = this._getTypeConfig(type);
465
- let url = `${this._options.baseUrl}/${config.register}/${config.schema}`;
488
+ let url = `${this._options.baseUrl}/${config.register}/${schema ?? config.schema}`;
466
489
  if (id) {
467
490
  url += `/${id}`;
468
491
  }
@@ -472,6 +495,54 @@ const baseActions = {
472
495
  return url
473
496
  },
474
497
 
498
+ /**
499
+ * Fetch for a type, retrying ONCE with its `schemaFallback` when the
500
+ * schema path segment answers 404. A type without a fallback (every type
501
+ * not registered by `resolveObjectOpType` for a kebab-cased title) makes
502
+ * exactly the one request it always made. When the retry succeeds the
503
+ * fallback becomes the type's schema, so later calls go straight to it;
504
+ * when it does not, the first answer is returned and nothing changes.
505
+ *
506
+ * @spec openspec/changes/zuiddrecht-pixel-gaps-2/specs/zuiddrecht-pixel-gaps-2/spec.md#requirement-a-schema-title-falls-back-to-its-written-form
507
+ * @param {string} type The type slug
508
+ * @param {function((string|null)): string} makeUrl Builds the URL; called with
509
+ * null for the type's own schema, or with the fallback segment.
510
+ * @param {object} init The fetch options.
511
+ * @return {Promise<Response>} The response to use.
512
+ */
513
+ async _fetchWithSchemaFallback(type, makeUrl, init) {
514
+ // `makeUrl` wraps `_buildUrl` / `_buildUrlWithParams`, so `url` is built
515
+ // from the prefixed `_options.baseUrl` like every other request here.
516
+ let url = makeUrl(null);
517
+ const response = await fetch(url, init);
518
+ if (!response || response.status !== 404) {
519
+ return response
520
+ }
521
+ const config = this.objectTypeRegistry[type];
522
+ const fallback = config && config.schemaFallback;
523
+ if (!fallback || String(fallback) === String(config.schema)) {
524
+ return response
525
+ }
526
+ let retry;
527
+ try {
528
+ url = makeUrl(fallback);
529
+ retry = await fetch(url, init);
530
+ } catch {
531
+ return response
532
+ }
533
+ if (!retry || !retry.ok) {
534
+ discardResponseBody(retry);
535
+ return response
536
+ }
537
+ discardResponseBody(response);
538
+ const { schemaFallback: _, ...rest } = config;
539
+ this.objectTypeRegistry = {
540
+ ...this.objectTypeRegistry,
541
+ [type]: { ...rest, schema: fallback },
542
+ };
543
+ return retry
544
+ },
545
+
475
546
  /**
476
547
  * Clear the error state for a type.
477
548
  *
@@ -585,9 +656,12 @@ const baseActions = {
585
656
  *
586
657
  * @param {string} type The registered type slug
587
658
  * @param {object} [params] Query parameters (_limit, _page, _search, _order, filters)
659
+ * @param {object} [options] Call options
660
+ * @param {{error?: object|null}} [options.outcome] Opt-in sink for THIS call's own result: `error` is set to the error it records on `errors[type]`, or `null` on success. Unlike `errors[type]`, which every call for the type shares, a later call cannot overwrite it.
588
661
  * @return {Promise<Array>} The fetched collection (also stored in state)
589
662
  */
590
- async fetchCollection(type, params = {}) {
663
+ async fetchCollection(type, params = {}, options = {}) {
664
+ const outcome = (options && typeof options.outcome === 'object' && options.outcome) || null;
591
665
  this.loading = { ...this.loading, [type]: true };
592
666
  this.errors = { ...this.errors, [type]: null };
593
667
 
@@ -604,17 +678,23 @@ const baseActions = {
604
678
  }
605
679
  }
606
680
 
607
- const url = this._buildUrlWithParams(type, fetchParams);
608
-
609
- const response = await fetch(url, {
610
- method: 'GET',
611
- headers: this._buildHeaders(),
612
- });
681
+ const response = await this._fetchWithSchemaFallback(
682
+ type,
683
+ (schema) => this._buildUrlWithParams(type, fetchParams, null, schema),
684
+ {
685
+ method: 'GET',
686
+ headers: this._buildHeaders(),
687
+ },
688
+ );
613
689
 
614
690
  if (!response.ok) {
615
- this.errors = { ...this.errors, [type]: await parseResponseError(response, type) };
691
+ const failure = await parseResponseError(response, type);
692
+ this.errors = { ...this.errors, [type]: failure };
693
+ if (outcome) {
694
+ outcome.error = failure;
695
+ }
616
696
  // eslint-disable-next-line no-console -- diagnostic for a failure this code already degrades from
617
- console.error(`Error fetching ${type} collection:`, this.errors[type]);
697
+ console.error(`Error fetching ${type} collection:`, failure);
618
698
  return []
619
699
  }
620
700
 
@@ -638,14 +718,18 @@ const baseActions = {
638
718
  this.facets = { ...this.facets, [type]: transformed };
639
719
  }
640
720
 
721
+ if (outcome) {
722
+ outcome.error = null;
723
+ }
641
724
  return results
642
725
  } catch (error) {
643
- this.errors = {
644
- ...this.errors,
645
- [type]: error.name === 'TypeError'
646
- ? networkError(error)
647
- : genericError(error),
648
- };
726
+ const failure = error.name === 'TypeError'
727
+ ? networkError(error)
728
+ : genericError(error);
729
+ this.errors = { ...this.errors, [type]: failure };
730
+ if (outcome) {
731
+ outcome.error = failure;
732
+ }
649
733
  // eslint-disable-next-line no-console -- diagnostic for a failure this code already degrades from
650
734
  console.error(`Error fetching ${type} collection:`, error);
651
735
  return []
@@ -675,11 +759,14 @@ const baseActions = {
675
759
  */
676
760
  async fetchCollectionForOptions(type, params = {}) {
677
761
  try {
678
- const url = this._buildUrlWithParams(type, params);
679
- const response = await fetch(url, {
680
- method: 'GET',
681
- headers: this._buildHeaders(),
682
- });
762
+ const response = await this._fetchWithSchemaFallback(
763
+ type,
764
+ (schema) => this._buildUrlWithParams(type, params, null, schema),
765
+ {
766
+ method: 'GET',
767
+ headers: this._buildHeaders(),
768
+ },
769
+ );
683
770
 
684
771
  if (!response.ok) {
685
772
  discardResponseBody(response);
@@ -734,10 +821,14 @@ const baseActions = {
734
821
  this.errors = { ...this.errors, [type]: null };
735
822
 
736
823
  try {
737
- const response = await fetch(url, {
738
- method: 'GET',
739
- headers: this._buildHeaders(),
740
- });
824
+ const response = await this._fetchWithSchemaFallback(
825
+ type,
826
+ (schema) => (schema === null ? url : this._buildUrl(type, id, schema)),
827
+ {
828
+ method: 'GET',
829
+ headers: this._buildHeaders(),
830
+ },
831
+ );
741
832
 
742
833
  if (!response.ok) {
743
834
  this.errors = { ...this.errors, [type]: await parseResponseError(response, type) };
@@ -805,16 +896,19 @@ const baseActions = {
805
896
 
806
897
  try {
807
898
  const isUpdate = !!objectData.id;
808
- const url = isUpdate
809
- ? this._buildUrl(type, objectData.id)
810
- : this._buildUrl(type);
811
899
  const method = isUpdate ? 'PUT' : 'POST';
812
900
 
813
- const response = await fetch(url, {
814
- method,
815
- headers: this._buildHeaders(),
816
- body: JSON.stringify(objectData),
817
- });
901
+ const response = await this._fetchWithSchemaFallback(
902
+ type,
903
+ (schema) => (isUpdate
904
+ ? this._buildUrl(type, objectData.id, schema)
905
+ : this._buildUrl(type, null, schema)),
906
+ {
907
+ method,
908
+ headers: this._buildHeaders(),
909
+ body: JSON.stringify(objectData),
910
+ },
911
+ );
818
912
 
819
913
  if (!response.ok) {
820
914
  this.errors = { ...this.errors, [type]: await parseResponseError(response, type) };
@@ -866,12 +960,14 @@ const baseActions = {
866
960
  this.errors = { ...this.errors, [type]: null };
867
961
 
868
962
  try {
869
- const url = this._buildUrl(type, id);
870
-
871
- const response = await fetch(url, {
872
- method: 'DELETE',
873
- headers: this._buildHeaders(),
874
- });
963
+ const response = await this._fetchWithSchemaFallback(
964
+ type,
965
+ (schema) => this._buildUrl(type, id, schema),
966
+ {
967
+ method: 'DELETE',
968
+ headers: this._buildHeaders(),
969
+ },
970
+ );
875
971
 
876
972
  if (!response.ok) {
877
973
  this.errors = { ...this.errors, [type]: await parseResponseError(response, type) };