@conduction/nextcloud-vue 2.74.0 → 2.76.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 (126) hide show
  1. package/dist/esm/components/CnAppNav/CnAppNav.vue2.js +19 -14
  2. package/dist/esm/components/CnAppNav/CnAppNav.vue2.js.map +1 -1
  3. package/dist/esm/components/CnAppNav/CnAppNav.vue3.js +2 -2
  4. package/dist/esm/components/CnAppNav/CnAppNav.vue3.js.map +1 -1
  5. package/dist/esm/components/CnAppRoot/CnAppRoot.vue2.js +77 -26
  6. package/dist/esm/components/CnAppRoot/CnAppRoot.vue2.js.map +1 -1
  7. package/dist/esm/components/CnAppRoot/CnAppRoot.vue3.js +22 -14
  8. package/dist/esm/components/CnAppRoot/CnAppRoot.vue3.js.map +1 -1
  9. package/dist/esm/components/CnBannerWidget/CnBannerWidget.vue2.js +23 -4
  10. package/dist/esm/components/CnBannerWidget/CnBannerWidget.vue2.js.map +1 -1
  11. package/dist/esm/components/CnBannerWidget/CnBannerWidget.vue3.js.map +1 -1
  12. package/dist/esm/components/CnBrandBar/CnBrandBar.vue.js +9 -0
  13. package/dist/esm/components/CnBrandBar/CnBrandBar.vue.js.map +1 -0
  14. package/dist/esm/components/CnBrandBar/CnBrandBar.vue2.js +107 -0
  15. package/dist/esm/components/CnBrandBar/CnBrandBar.vue2.js.map +1 -0
  16. package/dist/esm/components/CnBrandBar/CnBrandBar.vue3.js +79 -0
  17. package/dist/esm/components/CnBrandBar/CnBrandBar.vue3.js.map +1 -0
  18. package/dist/esm/components/CnCardGrid/CnCardGrid.vue2.js +6 -0
  19. package/dist/esm/components/CnCardGrid/CnCardGrid.vue2.js.map +1 -1
  20. package/dist/esm/components/CnCardGrid/CnCardGrid.vue3.js +3 -2
  21. package/dist/esm/components/CnCardGrid/CnCardGrid.vue3.js.map +1 -1
  22. package/dist/esm/components/CnCredentials/CnCredentials.vue2.js +11 -10
  23. package/dist/esm/components/CnCredentials/CnCredentials.vue2.js.map +1 -1
  24. package/dist/esm/components/CnCredentials/CnCredentials.vue3.js.map +1 -1
  25. package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js +8 -5
  26. package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js.map +1 -1
  27. package/dist/esm/components/CnDetailPage/CnDetailPage.vue3.js.map +1 -1
  28. package/dist/esm/components/CnEnvironmentBanner/CnEnvironmentBanner.vue2.js +4 -1
  29. package/dist/esm/components/CnEnvironmentBanner/CnEnvironmentBanner.vue2.js.map +1 -1
  30. package/dist/esm/components/CnEnvironmentBanner/CnEnvironmentBanner.vue3.js.map +1 -1
  31. package/dist/esm/components/CnFormDialog/CnFormDialog.vue2.js +7 -0
  32. package/dist/esm/components/CnFormDialog/CnFormDialog.vue2.js.map +1 -1
  33. package/dist/esm/components/CnFormDialog/CnFormDialog.vue3.js +14 -7
  34. package/dist/esm/components/CnFormDialog/CnFormDialog.vue3.js.map +1 -1
  35. package/dist/esm/components/CnFormPage/CnFormPage.vue2.js +32 -0
  36. package/dist/esm/components/CnFormPage/CnFormPage.vue2.js.map +1 -1
  37. package/dist/esm/components/CnFormPage/CnFormPage.vue3.js +6 -3
  38. package/dist/esm/components/CnFormPage/CnFormPage.vue3.js.map +1 -1
  39. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js +144 -6
  40. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js.map +1 -1
  41. package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js +14 -13
  42. package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js.map +1 -1
  43. package/dist/esm/components/CnIndexPage/selfModeActions.js +90 -14
  44. package/dist/esm/components/CnIndexPage/selfModeActions.js.map +1 -1
  45. package/dist/esm/components/CnIndexPage/useSelfFetchList.js +15 -3
  46. package/dist/esm/components/CnIndexPage/useSelfFetchList.js.map +1 -1
  47. package/dist/esm/components/CnObjectCard/CnObjectCard.vue2.js +26 -0
  48. package/dist/esm/components/CnObjectCard/CnObjectCard.vue2.js.map +1 -1
  49. package/dist/esm/components/CnObjectCard/CnObjectCard.vue3.js +26 -9
  50. package/dist/esm/components/CnObjectCard/CnObjectCard.vue3.js.map +1 -1
  51. package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue2.js +19 -3
  52. package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue2.js.map +1 -1
  53. package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue3.js.map +1 -1
  54. package/dist/esm/components/CnQuickFilterBar/CnQuickFilterBar.vue2.js +18 -2
  55. package/dist/esm/components/CnQuickFilterBar/CnQuickFilterBar.vue2.js.map +1 -1
  56. package/dist/esm/components/CnQuickFilterBar/CnQuickFilterBar.vue3.js +2 -2
  57. package/dist/esm/components/CnQuickFilterBar/CnQuickFilterBar.vue3.js.map +1 -1
  58. package/dist/esm/components/CnRelatedObjectsWidget/CnRelatedObjectsWidget.vue2.js +153 -38
  59. package/dist/esm/components/CnRelatedObjectsWidget/CnRelatedObjectsWidget.vue2.js.map +1 -1
  60. package/dist/esm/components/CnRelatedObjectsWidget/CnRelatedObjectsWidget.vue3.js +74 -56
  61. package/dist/esm/components/CnRelatedObjectsWidget/CnRelatedObjectsWidget.vue3.js.map +1 -1
  62. package/dist/esm/components/CnStatsBlock/CnStatsBlock.vue2.js +16 -0
  63. package/dist/esm/components/CnStatsBlock/CnStatsBlock.vue2.js.map +1 -1
  64. package/dist/esm/components/CnStatsBlock/CnStatsBlock.vue3.js +2 -2
  65. package/dist/esm/components/CnStatsBlock/CnStatsBlock.vue3.js.map +1 -1
  66. package/dist/esm/composables/useObjectLock.js +41 -10
  67. package/dist/esm/composables/useObjectLock.js.map +1 -1
  68. package/dist/esm/directives/cnSelectAria.js +55 -0
  69. package/dist/esm/directives/cnSelectAria.js.map +1 -0
  70. package/dist/esm/index.js +1 -0
  71. package/dist/esm/index.js.map +1 -1
  72. package/dist/esm/l10n/en.json.js +7 -1
  73. package/dist/esm/l10n/en.json.js.map +1 -1
  74. package/dist/esm/l10n/nl.json.js +8 -2
  75. package/dist/esm/l10n/nl.json.js.map +1 -1
  76. package/dist/esm/nextcloud-vue.css +154 -2
  77. package/dist/esm/store/useObjectStore.js +37 -9
  78. package/dist/esm/store/useObjectStore.js.map +1 -1
  79. package/dist/esm/utils/cnFetch.js +17 -2
  80. package/dist/esm/utils/cnFetch.js.map +1 -1
  81. package/dist/esm/utils/objectSignals.js +44 -0
  82. package/dist/esm/utils/objectSignals.js.map +1 -0
  83. package/dist/esm/utils/resolveBrand.js +38 -0
  84. package/dist/esm/utils/resolveBrand.js.map +1 -0
  85. package/dist/esm/utils/validateManifestV2.compiled.js +2 -2
  86. package/dist/esm/utils/validateManifestV2.compiled.js.map +1 -1
  87. package/dist/nextcloud-vue.cjs.js +9640 -8649
  88. package/dist/nextcloud-vue.cjs.js.map +2 -2
  89. package/dist/nextcloud-vue.css +154 -2
  90. package/l10n/en.json +7 -1
  91. package/l10n/nl.json +8 -2
  92. package/package.json +1 -1
  93. package/src/components/CnAppNav/CnAppNav.vue +21 -16
  94. package/src/components/CnAppRoot/CnAppRoot.vue +53 -0
  95. package/src/components/CnBannerWidget/CnBannerWidget.vue +23 -4
  96. package/src/components/CnBrandBar/CnBrandBar.vue +230 -0
  97. package/src/components/CnCardGrid/CnCardGrid.md +1 -0
  98. package/src/components/CnCardGrid/CnCardGrid.vue +7 -0
  99. package/src/components/CnCredentials/CnCredentials.vue +17 -16
  100. package/src/components/CnDetailPage/CnDetailPage.vue +8 -5
  101. package/src/components/CnEnvironmentBanner/CnEnvironmentBanner.vue +4 -1
  102. package/src/components/CnFormDialog/CnFormDialog.vue +10 -0
  103. package/src/components/CnFormPage/CnFormPage.vue +33 -0
  104. package/src/components/CnIndexPage/CnIndexPage.md +15 -0
  105. package/src/components/CnIndexPage/CnIndexPage.vue +157 -18
  106. package/src/components/CnIndexPage/selfModeActions.js +89 -13
  107. package/src/components/CnIndexPage/useSelfFetchList.js +15 -3
  108. package/src/components/CnObjectCard/CnObjectCard.md +1 -0
  109. package/src/components/CnObjectCard/CnObjectCard.vue +89 -1
  110. package/src/components/CnObjectListWidget/CnObjectListWidget.vue +19 -3
  111. package/src/components/CnQuickFilterBar/CnQuickFilterBar.vue +20 -4
  112. package/src/components/CnRelatedObjectsWidget/CnRelatedObjectsWidget.vue +181 -38
  113. package/src/components/CnStatsBlock/CnStatsBlock.vue +18 -2
  114. package/src/composables/__tests__/useObjectLock.endpoints.spec.js +83 -0
  115. package/src/composables/useObjectLock.js +41 -10
  116. package/src/css/form-field.css +1 -1
  117. package/src/css/look-board-index.css +35 -1
  118. package/src/directives/cnSelectAria.js +54 -0
  119. package/src/index.js +1 -0
  120. package/src/schemas/app-manifest-v2.schema.json +6 -1
  121. package/src/store/useObjectStore.js +37 -9
  122. package/src/utils/cnFetch.js +16 -1
  123. package/src/utils/index.js +1 -0
  124. package/src/utils/objectSignals.js +41 -0
  125. package/src/utils/resolveBrand.js +37 -0
  126. package/src/utils/validateManifestV2.compiled.js +2 -2
@@ -795,7 +795,7 @@
795
795
  }
796
796
 
797
797
  /* An invalid field: 2px error border on the control, 4px edge on the group. */
798
- .cn-look-board .cn-form-field--invalid input,
798
+ .cn-look-board .cn-form-field--invalid input:not([type='checkbox']):not([type='radio']),
799
799
  .cn-look-board .cn-form-field--invalid textarea,
800
800
  .cn-look-board .cn-form-field--invalid .select {
801
801
  border: var(--cn-field-error-border) solid var(--color-error);
@@ -1490,7 +1490,10 @@
1490
1490
  }
1491
1491
 
1492
1492
  .cn-look-board .cn-index-page__main.cn-index-page__main--table {
1493
- flex: 0 1 auto;
1493
+ /* The body is a row: the card takes the width left beside a sidebar (the
1494
+ board's table card spans the content), and keeps the height of its rows. */
1495
+ flex: 1 1 auto;
1496
+ align-self: flex-start;
1494
1497
  border: 1px solid var(--color-border);
1495
1498
  border-radius: var(--cn-board-card-radius, 12px);
1496
1499
  background: var(--color-main-background);
@@ -1680,6 +1683,37 @@
1680
1683
  background: var(--color-primary-element-light);
1681
1684
  }
1682
1685
 
1686
+ /* The status accent outranks the board's border, also on hover and selection. */
1687
+ .cn-look-board .cn-object-card.cn-object-card--board.cn-object-card--accent {
1688
+ border-inline-start-width: 4px;
1689
+ padding-inline-start: 13px;
1690
+ }
1691
+
1692
+ .cn-look-board .cn-object-card.cn-object-card--board.cn-object-card--accent-success,
1693
+ .cn-look-board .cn-object-card.cn-object-card--board.cn-object-card--accent-success:hover {
1694
+ border-inline-start-color: var(--color-element-success);
1695
+ }
1696
+
1697
+ .cn-look-board .cn-object-card.cn-object-card--board.cn-object-card--accent-warning,
1698
+ .cn-look-board .cn-object-card.cn-object-card--board.cn-object-card--accent-warning:hover {
1699
+ border-inline-start-color: var(--color-element-warning);
1700
+ }
1701
+
1702
+ .cn-look-board .cn-object-card.cn-object-card--board.cn-object-card--accent-error,
1703
+ .cn-look-board .cn-object-card.cn-object-card--board.cn-object-card--accent-error:hover {
1704
+ border-inline-start-color: var(--color-element-error);
1705
+ }
1706
+
1707
+ .cn-look-board .cn-object-card.cn-object-card--board.cn-object-card--accent-info,
1708
+ .cn-look-board .cn-object-card.cn-object-card--board.cn-object-card--accent-info:hover {
1709
+ border-inline-start-color: var(--color-element-info);
1710
+ }
1711
+
1712
+ .cn-look-board .cn-object-card.cn-object-card--board.cn-object-card--accent-primary,
1713
+ .cn-look-board .cn-object-card.cn-object-card--board.cn-object-card--accent-primary:hover {
1714
+ border-inline-start-color: var(--color-primary-element);
1715
+ }
1716
+
1683
1717
  .cn-look-board .cn-object-card--board .cn-object-card__content {
1684
1718
  display: flex;
1685
1719
  flex: 1 1 auto;
@@ -19425,6 +19459,18 @@ a.cn-xwiki-card__title[data-v-54e85fe3]:hover {
19425
19459
  color: var(--color-text-maxcontrast);
19426
19460
  font-style: italic;
19427
19461
  }
19462
+ .cn-related-objects-widget__section-status[data-v-44c2988f] {
19463
+ margin: 0;
19464
+ padding: var(--default-grid-baseline, 4px) calc(2 * var(--default-grid-baseline, 4px));
19465
+ color: var(--color-text-maxcontrast);
19466
+ font-size: 0.85em;
19467
+ }
19468
+ .cn-related-objects-widget__section-error[data-v-44c2988f] {
19469
+ margin: 0;
19470
+ padding: var(--default-grid-baseline, 4px) calc(2 * var(--default-grid-baseline, 4px));
19471
+ color: var(--color-error-text, var(--color-error));
19472
+ font-size: 0.85em;
19473
+ }
19428
19474
  .cn-related-objects-widget__empty-state[data-v-44c2988f] {
19429
19475
  /* NcEmptyContent defaults to filling tall parents; inside a widget cell a
19430
19476
  compact block reads better. */
@@ -22090,6 +22136,47 @@ to { background-position: -200% 0;
22090
22136
  border-color: var(--color-primary-element);
22091
22137
  background: var(--color-primary-element-light);
22092
22138
  }
22139
+
22140
+ /* The 4px start border takes 3px of padding, so the content stays put. */
22141
+ .cn-object-card.cn-object-card--accent[data-v-6f672c8f] {
22142
+ border-inline-start-width: 4px;
22143
+ padding-inline-start: 13px;
22144
+ }
22145
+ .cn-object-card.cn-object-card--accent-success[data-v-6f672c8f] {
22146
+ border-inline-start-color: var(--color-element-success);
22147
+ }
22148
+ .cn-object-card.cn-object-card--accent-warning[data-v-6f672c8f] {
22149
+ border-inline-start-color: var(--color-element-warning);
22150
+ }
22151
+ .cn-object-card.cn-object-card--accent-error[data-v-6f672c8f] {
22152
+ border-inline-start-color: var(--color-element-error);
22153
+ }
22154
+ .cn-object-card.cn-object-card--accent-info[data-v-6f672c8f] {
22155
+ border-inline-start-color: var(--color-element-info);
22156
+ }
22157
+ .cn-object-card.cn-object-card--accent-primary[data-v-6f672c8f] {
22158
+ border-inline-start-color: var(--color-primary-element);
22159
+ }
22160
+ .cn-object-card__accent-icon[data-v-6f672c8f] {
22161
+ display: inline-flex;
22162
+ vertical-align: -2px;
22163
+ margin-inline-end: 4px;
22164
+ }
22165
+ .cn-object-card--accent-success .cn-object-card__accent-icon[data-v-6f672c8f] {
22166
+ color: var(--color-text-success);
22167
+ }
22168
+ .cn-object-card--accent-warning .cn-object-card__accent-icon[data-v-6f672c8f] {
22169
+ color: var(--color-text-warning);
22170
+ }
22171
+ .cn-object-card--accent-error .cn-object-card__accent-icon[data-v-6f672c8f] {
22172
+ color: var(--color-text-error);
22173
+ }
22174
+ .cn-object-card--accent-info .cn-object-card__accent-icon[data-v-6f672c8f] {
22175
+ color: var(--color-element-info);
22176
+ }
22177
+ .cn-object-card--accent-primary .cn-object-card__accent-icon[data-v-6f672c8f] {
22178
+ color: var(--color-primary-element);
22179
+ }
22093
22180
  .cn-object-card__checkbox[data-v-6f672c8f] {
22094
22181
  flex-shrink: 0;
22095
22182
  padding-top: 2px;
@@ -38840,6 +38927,71 @@ a.cn-integration-card__title[data-v-f7e9bbfa]:hover {
38840
38927
  }
38841
38928
 
38842
38929
 
38930
+ /* The host is one flex item at the start of Nextcloud's header. */
38931
+ .cn-brand-bar-host {
38932
+ flex: none;
38933
+ display: flex;
38934
+ align-items: center;
38935
+ height: 100%;
38936
+ margin-inline-end: 12px;
38937
+ }
38938
+ .cn-brand-bar {
38939
+ box-sizing: border-box;
38940
+ display: flex;
38941
+ align-items: center;
38942
+ gap: 12px;
38943
+ width: var(--cn-board-brand-width, 237px);
38944
+ }
38945
+ .cn-brand-bar__brand {
38946
+ flex: 1 1 0;
38947
+ box-sizing: border-box;
38948
+ display: flex;
38949
+ align-items: center;
38950
+ gap: 10px;
38951
+ min-width: 0;
38952
+ min-height: 48px;
38953
+ max-height: 100%;
38954
+ padding: 0 6px;
38955
+ border-radius: 8px;
38956
+ color: var(--color-background-plain-text, var(--color-main-text));
38957
+ }
38958
+ .cn-brand-bar__emblem {
38959
+ flex: none;
38960
+ height: var(--cn-nav-emblem-size, 34px);
38961
+ width: auto;
38962
+ object-fit: contain;
38963
+ }
38964
+ .cn-brand-bar__emblem--theme {
38965
+ display: inline-block;
38966
+ width: var(--cn-nav-emblem-size, 34px);
38967
+ background: var(--nldesign-emblem-url) center / contain no-repeat;
38968
+ }
38969
+ .cn-brand-bar__text {
38970
+ display: flex;
38971
+ flex-direction: column;
38972
+ line-height: 1.15;
38973
+ min-width: 0;
38974
+ }
38975
+ .cn-brand-bar__caption {
38976
+ font-size: 13px;
38977
+ white-space: nowrap;
38978
+ opacity: 0.8;
38979
+ }
38980
+ .cn-brand-bar__name {
38981
+ font-size: 18px;
38982
+ font-weight: 700;
38983
+ white-space: nowrap;
38984
+ }
38985
+ .cn-brand-bar__divider {
38986
+ flex: none;
38987
+ width: 1px;
38988
+ height: 28px;
38989
+ background: currentColor;
38990
+ opacity: 0.25;
38991
+ color: var(--color-background-plain-text, var(--color-main-text));
38992
+ }
38993
+
38994
+
38843
38995
  .cn-notif-prefs__intro[data-v-72cc0056] {
38844
38996
  margin-bottom: 12px;
38845
38997
  color: var(--color-text-maxcontrast);
@@ -240,9 +240,10 @@ const baseActions = {
240
240
  * @param {object} [slugs] Optional slug hints for live-updates transport
241
241
  * @param {string|null} [slugs.registerSlug] Canonical register slug (e.g. 'zaken')
242
242
  * @param {string|null} [slugs.schemaSlug] Canonical schema slug (e.g. 'meldingen')
243
+ * @param {string} [slugs.collectionUrl] Endpoint `fetchCollection` lists from instead of `/register/schema`; every other call keeps the pair URL
243
244
  */
244
245
  registerObjectType(slug, schemaId, registerId, slugs = {}) {
245
- const { registerSlug = null, schemaSlug = null } = slugs;
246
+ const { registerSlug = null, schemaSlug = null, collectionUrl = null } = slugs;
246
247
  // Replace entire objects so Vue 2 reactivity detects the change
247
248
  // (Vue 2 cannot track new properties added to existing reactive objects)
248
249
  this.objectTypeRegistry = {
@@ -252,6 +253,7 @@ const baseActions = {
252
253
  register: registerId,
253
254
  registerSlug,
254
255
  schemaSlug,
256
+ ...(collectionUrl ? { collectionUrl } : {}),
255
257
  },
256
258
  };
257
259
  this.collections = { ...this.collections, [slug]: [] };
@@ -496,6 +498,31 @@ const baseActions = {
496
498
  return url
497
499
  },
498
500
 
501
+ /**
502
+ * Build the list URL for a type registered with a `collectionUrl`. `_order`
503
+ * goes in the bracket form (`_order[key]=dir`) every PHP endpoint parses.
504
+ *
505
+ * @param {object} config The type config
506
+ * @param {object} [params] Query parameters
507
+ * @return {string} Full URL including query string
508
+ */
509
+ _buildCollectionUrl(config, params = {}) {
510
+ const { _order: order, ...rest } = params;
511
+ const merged = { ...rest };
512
+ if (order && typeof order === 'object') {
513
+ for (const [key, dir] of Object.entries(order)) {
514
+ merged[`_order[${key}]`] = dir;
515
+ }
516
+ }
517
+ const lang = this._resolveLanguage();
518
+ if (lang) {
519
+ merged._lang = lang;
520
+ }
521
+ const url = prefixUrl(config.collectionUrl);
522
+ const query = buildQueryString(merged);
523
+ return query && url.includes('?') ? url + '&' + query.slice(1) : url + query
524
+ },
525
+
499
526
  /**
500
527
  * Fetch for a type, retrying ONCE with its `schemaFallback` when the
501
528
  * schema path segment answers 404. A type without a fallback (every type
@@ -685,14 +712,15 @@ const baseActions = {
685
712
  }
686
713
  }
687
714
 
688
- const response = await this._fetchWithSchemaFallback(
689
- type,
690
- (schema) => this._buildUrlWithParams(type, fetchParams, null, schema),
691
- {
692
- method: 'GET',
693
- headers: this._buildHeaders(),
694
- },
695
- );
715
+ const config = this._getTypeConfig(type);
716
+ const init = { method: 'GET', headers: this._buildHeaders() };
717
+ const response = config.collectionUrl
718
+ ? await trackedFetch(this._buildCollectionUrl(config, fetchParams), init)
719
+ : await this._fetchWithSchemaFallback(
720
+ type,
721
+ (schema) => this._buildUrlWithParams(type, fetchParams, null, schema),
722
+ init,
723
+ );
696
724
 
697
725
  if (!response.ok) {
698
726
  const failure = await parseResponseError(response, type);