@conduction/nextcloud-vue 2.79.0 → 2.80.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 (197) hide show
  1. package/dist/esm/components/CnActionButtons/CnActionButtons.vue2.js.map +1 -1
  2. package/dist/esm/components/CnActionButtons/CnActionButtons.vue3.js +3 -1
  3. package/dist/esm/components/CnActionButtons/CnActionButtons.vue3.js.map +1 -1
  4. package/dist/esm/components/CnActionsBar/CnActionsBar.vue2.js +32 -3
  5. package/dist/esm/components/CnActionsBar/CnActionsBar.vue2.js.map +1 -1
  6. package/dist/esm/components/CnActionsBar/CnActionsBar.vue3.js +10 -8
  7. package/dist/esm/components/CnActionsBar/CnActionsBar.vue3.js.map +1 -1
  8. package/dist/esm/components/CnBannerWidget/CnBannerWidget.vue2.js +39 -3
  9. package/dist/esm/components/CnBannerWidget/CnBannerWidget.vue2.js.map +1 -1
  10. package/dist/esm/components/CnBannerWidget/CnBannerWidget.vue3.js.map +1 -1
  11. package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue2.js +79 -1
  12. package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue2.js.map +1 -1
  13. package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue3.js +133 -96
  14. package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue3.js.map +1 -1
  15. package/dist/esm/components/CnDataTable/CnDataTable.vue2.js.map +1 -1
  16. package/dist/esm/components/CnDataTable/CnDataTable.vue3.js +1 -0
  17. package/dist/esm/components/CnDataTable/CnDataTable.vue3.js.map +1 -1
  18. package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js +62 -4
  19. package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js.map +1 -1
  20. package/dist/esm/components/CnDetailPage/CnDetailPage.vue3.js.map +1 -1
  21. package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue2.js +24 -0
  22. package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue2.js.map +1 -1
  23. package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue3.js +43 -4
  24. package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue3.js.map +1 -1
  25. package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue.js +11 -0
  26. package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue.js.map +1 -0
  27. package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue2.js +736 -0
  28. package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue2.js.map +1 -0
  29. package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue3.js +238 -0
  30. package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue3.js.map +1 -0
  31. package/dist/esm/components/CnFactsWidget/index.js +30 -0
  32. package/dist/esm/components/CnFactsWidget/index.js.map +1 -0
  33. package/dist/esm/components/CnFieldListWidget/CnFieldListWidget.vue.js +10 -0
  34. package/dist/esm/components/CnFieldListWidget/CnFieldListWidget.vue.js.map +1 -0
  35. package/dist/esm/components/CnFieldListWidget/CnFieldListWidget.vue2.js +551 -0
  36. package/dist/esm/components/CnFieldListWidget/CnFieldListWidget.vue2.js.map +1 -0
  37. package/dist/esm/components/CnFieldListWidget/CnFieldListWidget.vue3.js +183 -0
  38. package/dist/esm/components/CnFieldListWidget/CnFieldListWidget.vue3.js.map +1 -0
  39. package/dist/esm/components/CnFieldListWidget/index.js +29 -0
  40. package/dist/esm/components/CnFieldListWidget/index.js.map +1 -0
  41. package/dist/esm/components/CnFormDialog/CnFormDialog.vue2.js +65 -17
  42. package/dist/esm/components/CnFormDialog/CnFormDialog.vue2.js.map +1 -1
  43. package/dist/esm/components/CnFormDialog/CnFormDialog.vue3.js +4 -4
  44. package/dist/esm/components/CnFormDialog/CnFormDialog.vue3.js.map +1 -1
  45. package/dist/esm/components/CnFormPage/CnFormPage.vue2.js +18 -3
  46. package/dist/esm/components/CnFormPage/CnFormPage.vue2.js.map +1 -1
  47. package/dist/esm/components/CnFormPage/CnFormPage.vue3.js.map +1 -1
  48. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js +305 -72
  49. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js.map +1 -1
  50. package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js +31 -13
  51. package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js.map +1 -1
  52. package/dist/esm/components/CnIndexPage/CnIndexPageWidgets.vue.js +10 -0
  53. package/dist/esm/components/CnIndexPage/CnIndexPageWidgets.vue.js.map +1 -0
  54. package/dist/esm/components/CnIndexPage/CnIndexPageWidgets.vue2.js +99 -0
  55. package/dist/esm/components/CnIndexPage/CnIndexPageWidgets.vue2.js.map +1 -0
  56. package/dist/esm/components/CnIndexPage/CnIndexPageWidgets.vue3.js +48 -0
  57. package/dist/esm/components/CnIndexPage/CnIndexPageWidgets.vue3.js.map +1 -0
  58. package/dist/esm/components/CnPageRenderer/CnPageRenderer.vue2.js +29 -1
  59. package/dist/esm/components/CnPageRenderer/CnPageRenderer.vue2.js.map +1 -1
  60. package/dist/esm/components/CnPageRenderer/CnPageRenderer.vue3.js.map +1 -1
  61. package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue.js +10 -0
  62. package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue.js.map +1 -0
  63. package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue2.js +387 -0
  64. package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue2.js.map +1 -0
  65. package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue3.js +169 -0
  66. package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue3.js.map +1 -0
  67. package/dist/esm/components/CnRecordListWidget/index.js +31 -0
  68. package/dist/esm/components/CnRecordListWidget/index.js.map +1 -0
  69. package/dist/esm/components/CnSectionsWidget/CnSectionsWidget.vue.js +10 -0
  70. package/dist/esm/components/CnSectionsWidget/CnSectionsWidget.vue.js.map +1 -0
  71. package/dist/esm/components/CnSectionsWidget/CnSectionsWidget.vue2.js +351 -0
  72. package/dist/esm/components/CnSectionsWidget/CnSectionsWidget.vue2.js.map +1 -0
  73. package/dist/esm/components/CnSectionsWidget/CnSectionsWidget.vue3.js +71 -0
  74. package/dist/esm/components/CnSectionsWidget/CnSectionsWidget.vue3.js.map +1 -0
  75. package/dist/esm/components/CnSectionsWidget/index.js +35 -0
  76. package/dist/esm/components/CnSectionsWidget/index.js.map +1 -0
  77. package/dist/esm/components/CnStagesWidget/CnStagesWidget.vue2.js +81 -2
  78. package/dist/esm/components/CnStagesWidget/CnStagesWidget.vue2.js.map +1 -1
  79. package/dist/esm/components/CnStagesWidget/CnStagesWidget.vue3.js.map +1 -1
  80. package/dist/esm/components/CnStatWidget/CnStatWidget.vue2.js.map +1 -1
  81. package/dist/esm/components/CnStatWidget/CnStatWidget.vue3.js +1 -0
  82. package/dist/esm/components/CnStatWidget/CnStatWidget.vue3.js.map +1 -1
  83. package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue2.js +122 -7
  84. package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue2.js.map +1 -1
  85. package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue3.js +84 -23
  86. package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue3.js.map +1 -1
  87. package/dist/esm/components/CnWidgetGrid/registerDashboardWidgets.js +4 -0
  88. package/dist/esm/components/CnWidgetGrid/registerDashboardWidgets.js.map +1 -1
  89. package/dist/esm/components/CnWorkspaceFilterWidget/CnWorkspaceFilterWidget.vue2.js +106 -2
  90. package/dist/esm/components/CnWorkspaceFilterWidget/CnWorkspaceFilterWidget.vue2.js.map +1 -1
  91. package/dist/esm/components/CnWorkspaceFilterWidget/CnWorkspaceFilterWidget.vue3.js +105 -53
  92. package/dist/esm/components/CnWorkspaceFilterWidget/CnWorkspaceFilterWidget.vue3.js.map +1 -1
  93. package/dist/esm/composables/useFormDraft.js +140 -9
  94. package/dist/esm/composables/useFormDraft.js.map +1 -1
  95. package/dist/esm/index.js +4 -0
  96. package/dist/esm/index.js.map +1 -1
  97. package/dist/esm/integrations/builtin/field-inspection/CnFieldInspectionCard.vue2.js +28 -20
  98. package/dist/esm/integrations/builtin/field-inspection/CnFieldInspectionCard.vue2.js.map +1 -1
  99. package/dist/esm/integrations/builtin/field-inspection/CnFieldInspectionCard.vue3.js +9 -0
  100. package/dist/esm/integrations/builtin/field-inspection/CnFieldInspectionCard.vue3.js.map +1 -1
  101. package/dist/esm/integrations/builtin/field-inspection.js +21 -0
  102. package/dist/esm/integrations/builtin/field-inspection.js.map +1 -1
  103. package/dist/esm/integrations/offline/checklistSubmission.js +141 -0
  104. package/dist/esm/integrations/offline/checklistSubmission.js.map +1 -0
  105. package/dist/esm/integrations/offline/fieldCollectionHelpers.js +70 -5
  106. package/dist/esm/integrations/offline/fieldCollectionHelpers.js.map +1 -1
  107. package/dist/esm/integrations/offline/index.js +2 -1
  108. package/dist/esm/integrations/offline/index.js.map +1 -1
  109. package/dist/esm/integrations/offline/offlineDb.js +6 -1
  110. package/dist/esm/integrations/offline/offlineDb.js.map +1 -1
  111. package/dist/esm/integrations/offline/syncReplayService.js +8 -2
  112. package/dist/esm/integrations/offline/syncReplayService.js.map +1 -1
  113. package/dist/esm/l10n/en.json.js +12 -1
  114. package/dist/esm/l10n/en.json.js.map +1 -1
  115. package/dist/esm/l10n/nl.json.js +16 -2
  116. package/dist/esm/l10n/nl.json.js.map +1 -1
  117. package/dist/esm/nextcloud-vue.css +1000 -59
  118. package/dist/esm/utils/detailActionModel.js +60 -3
  119. package/dist/esm/utils/detailActionModel.js.map +1 -1
  120. package/dist/esm/utils/fillTemplate.js +114 -0
  121. package/dist/esm/utils/fillTemplate.js.map +1 -0
  122. package/dist/esm/utils/libraryWidgetKeys.js +4 -0
  123. package/dist/esm/utils/libraryWidgetKeys.js.map +1 -1
  124. package/dist/esm/utils/queryPresets.js +96 -0
  125. package/dist/esm/utils/queryPresets.js.map +1 -0
  126. package/dist/esm/utils/resolveFilterTokens.js +11 -0
  127. package/dist/esm/utils/resolveFilterTokens.js.map +1 -1
  128. package/dist/esm/utils/schema.js +21 -0
  129. package/dist/esm/utils/schema.js.map +1 -1
  130. package/dist/esm/utils/sentinelTokens.js +3 -3
  131. package/dist/esm/utils/sentinelTokens.js.map +1 -1
  132. package/dist/esm/utils/validateManifestV2.compiled.js +3 -3
  133. package/dist/esm/utils/validateManifestV2.compiled.js.map +1 -1
  134. package/dist/esm/utils/widgetDispatch.js +7 -1
  135. package/dist/esm/utils/widgetDispatch.js.map +1 -1
  136. package/dist/nextcloud-vue.cjs.js +12368 -7717
  137. package/dist/nextcloud-vue.cjs.js.map +2 -2
  138. package/dist/nextcloud-vue.css +1000 -59
  139. package/l10n/en.json +12 -1
  140. package/l10n/nl.json +16 -2
  141. package/package.json +1 -1
  142. package/src/components/CnActionButtons/CnActionButtons.vue +2 -0
  143. package/src/components/CnActionsBar/CnActionsBar.md +4 -0
  144. package/src/components/CnActionsBar/CnActionsBar.vue +42 -10
  145. package/src/components/CnBannerWidget/CnBannerWidget.vue +39 -3
  146. package/src/components/CnCellRenderer/CnCellRenderer.vue +188 -1
  147. package/src/components/CnDataTable/CnDataTable.vue +1 -0
  148. package/src/components/CnDetailPage/CnDetailPage.md +1 -1
  149. package/src/components/CnDetailPage/CnDetailPage.vue +63 -3
  150. package/src/components/CnDetailWidgetHost/CnDetailWidgetHost.vue +66 -0
  151. package/src/components/CnFactsWidget/CnFactsWidget.vue +1050 -0
  152. package/src/components/CnFactsWidget/index.js +29 -0
  153. package/src/components/CnFieldListWidget/CnFieldListWidget.vue +746 -0
  154. package/src/components/CnFieldListWidget/index.js +28 -0
  155. package/src/components/CnFormDialog/CnFormDialog.md +9 -3
  156. package/src/components/CnFormDialog/CnFormDialog.vue +69 -21
  157. package/src/components/CnFormPage/CnFormPage.vue +18 -3
  158. package/src/components/CnIndexPage/CnIndexPage.vue +254 -6
  159. package/src/components/CnIndexPage/CnIndexPageWidgets.vue +169 -0
  160. package/src/components/CnPageRenderer/CnPageRenderer.vue +29 -1
  161. package/src/components/CnRecordListWidget/CnRecordListWidget.vue +603 -0
  162. package/src/components/CnRecordListWidget/index.js +30 -0
  163. package/src/components/CnSectionsWidget/CnSectionsWidget.vue +489 -0
  164. package/src/components/CnSectionsWidget/index.js +34 -0
  165. package/src/components/CnStagesWidget/CnStagesWidget.vue +81 -2
  166. package/src/components/CnStatWidget/CnStatWidget.vue +1 -1
  167. package/src/components/CnTabsWidget/CnTabsWidget.vue +184 -8
  168. package/src/components/CnWidgetGrid/registerDashboardWidgets.js +4 -0
  169. package/src/components/CnWorkspaceFilterWidget/CnWorkspaceFilterWidget.vue +188 -4
  170. package/src/components/index.js +4 -0
  171. package/src/composables/__tests__/useFormDraft.spec.js +69 -0
  172. package/src/composables/useFormDraft.js +139 -8
  173. package/src/css/form-field.css +14 -0
  174. package/src/css/index-page.css +71 -0
  175. package/src/css/kpi-card.css +32 -0
  176. package/src/css/look-board-detail.css +77 -0
  177. package/src/css/look-board-index.css +51 -0
  178. package/src/css/look-board.css +37 -2
  179. package/src/css/table.css +19 -0
  180. package/src/index.js +4 -0
  181. package/src/integrations/builtin/field-inspection/CnFieldInspectionCard.vue +35 -20
  182. package/src/integrations/builtin/field-inspection.js +21 -0
  183. package/src/integrations/offline/checklistSubmission.js +137 -0
  184. package/src/integrations/offline/fieldCollectionHelpers.js +69 -4
  185. package/src/integrations/offline/index.js +3 -0
  186. package/src/integrations/offline/offlineDb.js +6 -1
  187. package/src/integrations/offline/syncReplayService.js +8 -2
  188. package/src/schemas/app-manifest-v2.schema.json +104 -5
  189. package/src/utils/detailActionModel.js +59 -2
  190. package/src/utils/fillTemplate.js +110 -0
  191. package/src/utils/libraryWidgetKeys.js +4 -0
  192. package/src/utils/queryPresets.js +93 -0
  193. package/src/utils/resolveFilterTokens.js +11 -0
  194. package/src/utils/schema.js +21 -0
  195. package/src/utils/sentinelTokens.js +3 -3
  196. package/src/utils/validateManifestV2.compiled.js +3 -3
  197. package/src/utils/widgetDispatch.js +7 -1
@@ -0,0 +1,387 @@
1
+ import { subscribe, unsubscribe } from '@nextcloud/event-bus';
2
+ import { translate } from '@nextcloud/l10n';
3
+ import { NcLoadingIcon } from '@nextcloud/vue';
4
+ import ChevronRight from 'vue-material-design-icons/ChevronRight.vue';
5
+ import __sfc_main from '../CnIcon/CnIcon.vue.js';
6
+ import __sfc_main$1 from '../CnStatusBadge/CnStatusBadge.vue.js';
7
+ import { isBadgeVariant } from '../../utils/badgeVariants.js';
8
+ import { firstFilled, fillTemplate } from '../../utils/fillTemplate.js';
9
+ import { readPath } from '../../utils/readPath.js';
10
+ import { dropOptionalUnresolved, resolveFilterTokens, hasUnresolvedTokens } from '../../utils/resolveFilterTokens.js';
11
+
12
+ const PAGE_REFRESH_CHANNEL = 'cn:page:refresh';
13
+ const PRESENTATIONS = ['rows', 'feed', 'inline'];
14
+
15
+ /**
16
+ * Unwrap a value that may be a ref.
17
+ *
18
+ * @param {unknown} value The value.
19
+ * @return {unknown} The plain value.
20
+ */
21
+ function unwrap(value) {
22
+ return value && typeof value === 'object' && 'value' in value ? value.value : value
23
+ }
24
+
25
+ /**
26
+ * CnRecordListWidget — the objects of another schema that point at this
27
+ * record, drawn as the boards draw them (screens-relation-pages).
28
+ *
29
+ * A person page lists its open cases ("Verlichting fietspad Lindelaan,
30
+ * 2026-0082 · Woo-verzoek, In behandeling, Termijn 1 nov"), its latest contact
31
+ * moments (an icon by channel, a meta line, the summary) and its relations
32
+ * ("Secretaris van Buurtvereniging Oost"). Each is a list of another schema's
33
+ * objects filtered on a reference to this record. The source keys are those of
34
+ * `object-list` (`register`, `schema`, `filter` with the `@objectId` /
35
+ * `@object.<field>` / `@workspace.<key>` tokens, `sort`, `limit`, `extend`,
36
+ * `rowRoute`); what differs is the drawing: `presentation` is `rows`, `feed`
37
+ * or `inline`, and each line is a template (`"{identifier} · {caseTypeName}"`,
38
+ * `"Termijn {deadline|date}"`).
39
+ *
40
+ * A content-only catalog type: on a card surface the detail host draws the
41
+ * titled card. The widget emits `header` with `{ link, note }` (the
42
+ * `headerLink` and `headerNote` with `{total}` filled in) for that card's
43
+ * header.
44
+ */
45
+ var script = {
46
+ name: 'CnRecordListWidget',
47
+
48
+ components: { ChevronRight, CnIcon: __sfc_main, CnStatusBadge: __sfc_main$1, NcLoadingIcon },
49
+
50
+ inject: {
51
+ /** Detail-page object context (`{ objectId, object, register, schema }`). */
52
+ cnObjectContext: { default: null },
53
+ /** Page workspace bag, for `@workspace.<key>` tokens. */
54
+ cnWorkspaceContext: { default: null },
55
+ /** The host app's translate function. */
56
+ cnTranslate: { default: () => (key) => key },
57
+ },
58
+
59
+ props: {
60
+ /**
61
+ * The list config: `{ register, schema, filter?, sort?, limit?, extend?,
62
+ * presentation?, title?, meta?, text?, label?, pill?, trailing?, icon?,
63
+ * rowRoute?, rowIdField?, headerLink?, headerNote?, emptyText?, errorText? }`.
64
+ *
65
+ * @type {object}
66
+ */
67
+ content: {
68
+ type: Object,
69
+ default: () => ({}),
70
+ },
71
+
72
+ /** The current record's id, for the `@objectId` token. */
73
+ objectId: {
74
+ type: [String, Number],
75
+ default: null,
76
+ },
77
+
78
+ /** The current record, for `@object.<field>` tokens. */
79
+ objectData: {
80
+ type: Object,
81
+ default: null,
82
+ },
83
+ },
84
+
85
+ emits: ['header'],
86
+
87
+ data() {
88
+ return {
89
+ rows: [],
90
+ total: 0,
91
+ loading: false,
92
+ error: false,
93
+ }
94
+ },
95
+
96
+ computed: {
97
+ /** @return {string} `rows`, `feed` or `inline`. */
98
+ presentation() {
99
+ const value = this.content?.presentation;
100
+ return PRESENTATIONS.includes(value) ? value : 'rows'
101
+ },
102
+
103
+ /** @return {object} The token context: record, id and workspace. */
104
+ tokenCtx() {
105
+ const injected = unwrap(this.cnObjectContext) || {};
106
+ return {
107
+ ...injected,
108
+ objectId: this.objectId ?? injected.objectId ?? this.objectData?.id ?? null,
109
+ object: this.objectData || injected.object || null,
110
+ workspace: unwrap(this.cnWorkspaceContext) || {},
111
+ }
112
+ },
113
+
114
+ /** @return {object} The filter with its tokens resolved. */
115
+ resolvedFilter() {
116
+ const filter = this.content?.filter;
117
+ return dropOptionalUnresolved(resolveFilterTokens(filter && typeof filter === 'object' ? filter : {}, this.tokenCtx))
118
+ },
119
+
120
+ /** @return {boolean} A required token (the record id, say) has no value yet. */
121
+ waiting() {
122
+ return hasUnresolvedTokens(this.resolvedFilter)
123
+ },
124
+
125
+ /** @return {number} The fetch cap. */
126
+ limit() {
127
+ const value = Number(this.content?.limit);
128
+ return Number.isFinite(value) && value > 0 ? Math.floor(value) : 5
129
+ },
130
+
131
+ /** @return {string} What a fetch depends on; a change fetches again. */
132
+ requestKey() {
133
+ const c = this.content || {};
134
+ return JSON.stringify([c.register, c.schema, this.resolvedFilter, c.sort, this.limit, c.extend, this.waiting])
135
+ },
136
+
137
+ /** @return {Array<object>} The rows ready to draw. */
138
+ items() {
139
+ const c = this.content || {};
140
+ return this.rows.slice(0, this.limit).map((row, index) => {
141
+ const link = this.rowLink(row);
142
+ return {
143
+ key: (row && (row.id || row['@self']?.id)) || `row-${index}`,
144
+ tag: link ? 'router-link' : 'div',
145
+ attrs: link ? { to: link } : {},
146
+ title: this.fill(c.title, row),
147
+ meta: this.fill(c.meta, row),
148
+ text: this.fill(c.text, row),
149
+ label: this.fill(c.label, row),
150
+ trailing: c.trailing ? firstFilled(c.trailing, row, this.translate) : '',
151
+ pill: this.pillOf(row),
152
+ icon: this.iconOf(row),
153
+ }
154
+ })
155
+ },
156
+
157
+ /** @return {object|null} The header link with `{total}` filled and tokens resolved. */
158
+ headerLink() {
159
+ const link = this.content?.headerLink;
160
+ if (!link || typeof link !== 'object' || typeof link.label !== 'string' || link.label === '') {
161
+ return null
162
+ }
163
+ const resolved = { label: this.withTotal(link.label) };
164
+ if (link.route) {
165
+ resolved.route = link.route;
166
+ if (link.params && typeof link.params === 'object') {
167
+ resolved.params = resolveFilterTokens(link.params, this.tokenCtx);
168
+ }
169
+ if (link.query && typeof link.query === 'object') {
170
+ resolved.query = resolveFilterTokens(link.query, this.tokenCtx);
171
+ }
172
+ } else if (typeof link.href === 'string') {
173
+ resolved.href = link.href;
174
+ }
175
+ return resolved
176
+ },
177
+
178
+ /** @return {string} The header note with `{total}` filled. */
179
+ headerNote() {
180
+ const note = this.content?.headerNote;
181
+ return typeof note === 'string' && note !== '' ? this.withTotal(note) : ''
182
+ },
183
+
184
+ /** @return {string} The empty line. */
185
+ emptyLabel() {
186
+ return this.content?.emptyText ? this.translate(this.content.emptyText) : translate('nextcloud-vue', 'Nothing here yet')
187
+ },
188
+
189
+ /** @return {string} The error line. */
190
+ errorLabel() {
191
+ return this.content?.errorText ? this.translate(this.content.errorText) : translate('nextcloud-vue', 'This list could not be loaded.')
192
+ },
193
+
194
+ /** @return {string} The spinner's accessible name. */
195
+ loadingLabel() {
196
+ return translate('nextcloud-vue', 'Loading …')
197
+ },
198
+ },
199
+
200
+ watch: {
201
+ requestKey() {
202
+ this.fetchRows();
203
+ },
204
+ },
205
+
206
+ mounted() {
207
+ this.onRefresh = () => this.fetchRows();
208
+ subscribe(PAGE_REFRESH_CHANNEL, this.onRefresh);
209
+ this.fetchRows();
210
+ },
211
+
212
+ beforeUnmount() {
213
+ unsubscribe(PAGE_REFRESH_CHANNEL, this.onRefresh);
214
+ },
215
+
216
+ methods: {
217
+ /**
218
+ * Translate a manifest string through the host app.
219
+ *
220
+ * @param {string} text The text.
221
+ * @return {string} The translation.
222
+ */
223
+ translate(text) {
224
+ return typeof this.cnTranslate === 'function' ? this.cnTranslate(text) : text
225
+ },
226
+
227
+ /**
228
+ * Fill a template from a row, after translating it.
229
+ *
230
+ * @param {string} template The template.
231
+ * @param {object} row The row.
232
+ * @return {string} The text, '' when a token is empty.
233
+ */
234
+ fill(template, row) {
235
+ return typeof template === 'string' && template !== '' ? fillTemplate(this.translate(template), row) : ''
236
+ },
237
+
238
+ /**
239
+ * Replace `{total}` in a translated label.
240
+ *
241
+ * @param {string} label The label.
242
+ * @return {string} The text.
243
+ */
244
+ withTotal(label) {
245
+ return this.translate(label).replace(/\{total\}/g, String(this.total))
246
+ },
247
+
248
+ /**
249
+ * The route a row opens: `rowRoute` with the id at `rowIdField`.
250
+ *
251
+ * @param {object} row The row.
252
+ * @return {object|null} The router location, or null.
253
+ */
254
+ rowLink(row) {
255
+ const route = this.content?.rowRoute;
256
+ if (!route || !this.$router || !row) {
257
+ return null
258
+ }
259
+ const field = this.content?.rowIdField;
260
+ const id = field ? readPath(row, field) : (row.id || row['@self']?.id);
261
+ if (id === null || id === undefined || id === '' || typeof id === 'object') {
262
+ return null
263
+ }
264
+ return { name: route, params: { id: String(id) } }
265
+ },
266
+
267
+ /**
268
+ * The row's pill: `{ field, labels?, colorMap?, variant? }`.
269
+ *
270
+ * @param {object} row The row.
271
+ * @return {{label: string, variant: string}|null} The pill, or null.
272
+ */
273
+ pillOf(row) {
274
+ const pill = this.content?.pill;
275
+ if (!pill || typeof pill !== 'object' || !pill.field) {
276
+ return null
277
+ }
278
+ const raw = readPath(row, pill.field);
279
+ if (raw === null || raw === undefined || raw === '' || typeof raw === 'object') {
280
+ return null
281
+ }
282
+ const key = String(raw);
283
+ const labels = pill.labels && typeof pill.labels === 'object' ? pill.labels : {};
284
+ const map = pill.colorMap && typeof pill.colorMap === 'object' ? pill.colorMap : {};
285
+ const found = Object.keys(map).find((k) => k.toLowerCase() === key.toLowerCase());
286
+ const variant = found ? map[found] : pill.variant;
287
+ return {
288
+ label: labels[key] ? this.translate(labels[key]) : key,
289
+ variant: isBadgeVariant(variant) ? variant : 'default',
290
+ }
291
+ },
292
+
293
+ /**
294
+ * The feed icon: an icon name, or `{ field, map, default }`.
295
+ *
296
+ * @param {object} row The row.
297
+ * @return {string} The MDI icon name.
298
+ */
299
+ iconOf(row) {
300
+ const icon = this.content?.icon;
301
+ if (typeof icon === 'string' && icon !== '') {
302
+ return icon
303
+ }
304
+ if (icon && typeof icon === 'object') {
305
+ const raw = icon.field ? readPath(row, icon.field) : undefined;
306
+ const map = icon.map && typeof icon.map === 'object' ? icon.map : {};
307
+ if (raw !== null && raw !== undefined && map[String(raw)]) {
308
+ return map[String(raw)]
309
+ }
310
+ if (typeof icon.default === 'string' && icon.default !== '') {
311
+ return icon.default
312
+ }
313
+ }
314
+ return 'CircleSmall'
315
+ },
316
+
317
+ /** Tell the card around this list what its header shows. */
318
+ emitHeader() {
319
+ /**
320
+ * @event header Emitted after every read with the card header's parts.
321
+ * @type {{link: (object|null), note: string}} The header link (resolved, with `{total}` filled) and the note.
322
+ */
323
+ this.$emit('header', { link: this.headerLink, note: this.headerNote });
324
+ },
325
+
326
+ /**
327
+ * Fetch the list. Sends nothing while a required token is unresolved
328
+ * or the source is incomplete.
329
+ *
330
+ * @return {Promise<void>}
331
+ */
332
+ async fetchRows() {
333
+ const c = this.content || {};
334
+ if (!c.register || !c.schema || this.waiting) {
335
+ this.rows = [];
336
+ this.total = 0;
337
+ this.error = false;
338
+ this.emitHeader();
339
+ return
340
+ }
341
+ this.loading = true;
342
+ this.error = false;
343
+ try {
344
+ const [{ default: axios }, { generateUrl }] = await Promise.all([
345
+ import('@nextcloud/axios'),
346
+ import('@nextcloud/router'),
347
+ ]);
348
+ const url = generateUrl('/apps/openregister/api/objects/{register}/{schema}', { register: c.register, schema: c.schema });
349
+ const params = { _limit: this.limit };
350
+ if (c.sort && typeof c.sort === 'object' && c.sort.field) {
351
+ params[`_order[${c.sort.field}]`] = c.sort.dir === 'desc' ? 'desc' : 'asc';
352
+ }
353
+ if (Array.isArray(c.extend)) {
354
+ const extend = c.extend.filter((e) => typeof e === 'string' && e !== '');
355
+ if (extend.length > 0) {
356
+ params._extend = extend;
357
+ }
358
+ }
359
+ for (const [key, value] of Object.entries(this.resolvedFilter)) {
360
+ if (value && typeof value === 'object' && !Array.isArray(value)) {
361
+ for (const [op, operand] of Object.entries(value)) {
362
+ params[`${key}[${op}]`] = operand;
363
+ }
364
+ } else if (value !== '' && value !== null && value !== undefined) {
365
+ params[key] = value;
366
+ }
367
+ }
368
+ const response = await axios.get(url, { params });
369
+ const data = response && response.data ? response.data : {};
370
+ this.rows = Array.isArray(data.results) ? data.results : [];
371
+ this.total = typeof data.total === 'number' ? data.total : this.rows.length;
372
+ } catch (e) {
373
+ // eslint-disable-next-line no-console
374
+ console.warn('[CnRecordListWidget] failed to load objects:', e);
375
+ this.rows = [];
376
+ this.total = 0;
377
+ this.error = true;
378
+ } finally {
379
+ this.loading = false;
380
+ this.emitHeader();
381
+ }
382
+ },
383
+ },
384
+ };
385
+
386
+ export { script as default };
387
+ //# sourceMappingURL=CnRecordListWidget.vue2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CnRecordListWidget.vue2.js","sources":["../../../../src/components/CnRecordListWidget/CnRecordListWidget.vue"],"sourcesContent":["<!--\n - SPDX-FileCopyrightText: 2026 Conduction B.V.\n - SPDX-License-Identifier: EUPL-1.2\n-->\n\n<template>\n\t<div\n\t\tclass=\"cn-record-list\"\n\t\t:class=\"`cn-record-list--${presentation}`\"\n\t\tdata-testid=\"cn-record-list\">\n\t\t<p v-if=\"error\" class=\"cn-record-list__error\" data-testid=\"cn-record-list-error\">\n\t\t\t{{ errorLabel }}\n\t\t</p>\n\t\t<div v-else-if=\"loading && rows.length === 0\" class=\"cn-record-list__loading\">\n\t\t\t<NcLoadingIcon :size=\"20\" :name=\"loadingLabel\" />\n\t\t</div>\n\t\t<p v-else-if=\"rows.length === 0\" class=\"cn-record-list__empty\" data-testid=\"cn-record-list-empty\">\n\t\t\t{{ emptyLabel }}\n\t\t</p>\n\t\t<ul v-else class=\"cn-record-list__list\">\n\t\t\t<li\n\t\t\t\tv-for=\"item in items\"\n\t\t\t\t:key=\"item.key\"\n\t\t\t\tclass=\"cn-record-list__item\"\n\t\t\t\tdata-testid=\"cn-record-list-item\">\n\t\t\t\t<!-- rows: title and meta, then the pill, the date and a chevron. -->\n\t\t\t\t<component\n\t\t\t\t\t:is=\"item.tag\"\n\t\t\t\t\tv-if=\"presentation === 'rows'\"\n\t\t\t\t\tclass=\"cn-record-list__row\"\n\t\t\t\t\t:class=\"{ 'cn-record-list__row--link': item.tag !== 'div' }\"\n\t\t\t\t\tv-bind=\"item.attrs\">\n\t\t\t\t\t<span class=\"cn-record-list__main\">\n\t\t\t\t\t\t<span v-if=\"item.title\" class=\"cn-record-list__title\">{{ item.title }}</span>\n\t\t\t\t\t\t<span v-if=\"item.meta\" class=\"cn-record-list__meta\">{{ item.meta }}</span>\n\t\t\t\t\t</span>\n\t\t\t\t\t<span v-if=\"item.pill || item.trailing\" class=\"cn-record-list__aside\">\n\t\t\t\t\t\t<CnStatusBadge\n\t\t\t\t\t\t\tv-if=\"item.pill\"\n\t\t\t\t\t\t\t:label=\"item.pill.label\"\n\t\t\t\t\t\t\t:variant=\"item.pill.variant\"\n\t\t\t\t\t\t\tsize=\"small\" />\n\t\t\t\t\t\t<span v-if=\"item.trailing\" class=\"cn-record-list__trailing\">{{ item.trailing }}</span>\n\t\t\t\t\t</span>\n\t\t\t\t\t<ChevronRight\n\t\t\t\t\t\tv-if=\"item.tag !== 'div'\"\n\t\t\t\t\t\tclass=\"cn-record-list__chevron\"\n\t\t\t\t\t\t:size=\"18\"\n\t\t\t\t\t\taria-hidden=\"true\" />\n\t\t\t\t</component>\n\n\t\t\t\t<!-- feed: a round icon, a meta line and the text. -->\n\t\t\t\t<div v-else-if=\"presentation === 'feed'\" class=\"cn-record-list__feed-row\">\n\t\t\t\t\t<span class=\"cn-record-list__feed-icon\" aria-hidden=\"true\">\n\t\t\t\t\t\t<CnIcon :name=\"item.icon\" :size=\"18\" />\n\t\t\t\t\t</span>\n\t\t\t\t\t<component :is=\"item.tag\" class=\"cn-record-list__main\" v-bind=\"item.attrs\">\n\t\t\t\t\t\t<span v-if=\"item.meta\" class=\"cn-record-list__meta\">{{ item.meta }}</span>\n\t\t\t\t\t\t<span v-if=\"item.text\" class=\"cn-record-list__text\">{{ item.text }}</span>\n\t\t\t\t\t</component>\n\t\t\t\t</div>\n\n\t\t\t\t<!-- inline: a label and the title, the title a link. -->\n\t\t\t\t<div v-else class=\"cn-record-list__inline-row\">\n\t\t\t\t\t<span v-if=\"item.label\" class=\"cn-record-list__label\">{{ item.label }}</span>\n\t\t\t\t\t<component :is=\"item.tag\" class=\"cn-record-list__inline-title\" v-bind=\"item.attrs\">\n\t\t\t\t\t\t{{ item.title }}\n\t\t\t\t\t</component>\n\t\t\t\t</div>\n\t\t\t</li>\n\t\t</ul>\n\t</div>\n</template>\n\n<script>\nimport { subscribe, unsubscribe } from '@nextcloud/event-bus'\nimport { translate as t } from '@nextcloud/l10n'\nimport { NcLoadingIcon } from '@nextcloud/vue'\nimport ChevronRight from 'vue-material-design-icons/ChevronRight.vue'\nimport CnIcon from '../CnIcon/CnIcon.vue'\nimport CnStatusBadge from '../CnStatusBadge/CnStatusBadge.vue'\nimport { isBadgeVariant } from '../../utils/badgeVariants.js'\nimport { fillTemplate, firstFilled } from '../../utils/fillTemplate.js'\nimport { readPath } from '../../utils/readPath.js'\nimport { dropOptionalUnresolved, hasUnresolvedTokens, resolveFilterTokens } from '../../utils/resolveFilterTokens.js'\n\nconst PAGE_REFRESH_CHANNEL = 'cn:page:refresh'\nconst PRESENTATIONS = ['rows', 'feed', 'inline']\n\n/**\n * Unwrap a value that may be a ref.\n *\n * @param {unknown} value The value.\n * @return {unknown} The plain value.\n */\nfunction unwrap(value) {\n\treturn value && typeof value === 'object' && 'value' in value ? value.value : value\n}\n\n/**\n * CnRecordListWidget — the objects of another schema that point at this\n * record, drawn as the boards draw them (screens-relation-pages).\n *\n * A person page lists its open cases (\"Verlichting fietspad Lindelaan,\n * 2026-0082 · Woo-verzoek, In behandeling, Termijn 1 nov\"), its latest contact\n * moments (an icon by channel, a meta line, the summary) and its relations\n * (\"Secretaris van Buurtvereniging Oost\"). Each is a list of another schema's\n * objects filtered on a reference to this record. The source keys are those of\n * `object-list` (`register`, `schema`, `filter` with the `@objectId` /\n * `@object.<field>` / `@workspace.<key>` tokens, `sort`, `limit`, `extend`,\n * `rowRoute`); what differs is the drawing: `presentation` is `rows`, `feed`\n * or `inline`, and each line is a template (`\"{identifier} · {caseTypeName}\"`,\n * `\"Termijn {deadline|date}\"`).\n *\n * A content-only catalog type: on a card surface the detail host draws the\n * titled card. The widget emits `header` with `{ link, note }` (the\n * `headerLink` and `headerNote` with `{total}` filled in) for that card's\n * header.\n */\nexport default {\n\tname: 'CnRecordListWidget',\n\n\tcomponents: { ChevronRight, CnIcon, CnStatusBadge, NcLoadingIcon },\n\n\tinject: {\n\t\t/** Detail-page object context (`{ objectId, object, register, schema }`). */\n\t\tcnObjectContext: { default: null },\n\t\t/** Page workspace bag, for `@workspace.<key>` tokens. */\n\t\tcnWorkspaceContext: { default: null },\n\t\t/** The host app's translate function. */\n\t\tcnTranslate: { default: () => (key) => key },\n\t},\n\n\tprops: {\n\t\t/**\n\t\t * The list config: `{ register, schema, filter?, sort?, limit?, extend?,\n\t\t * presentation?, title?, meta?, text?, label?, pill?, trailing?, icon?,\n\t\t * rowRoute?, rowIdField?, headerLink?, headerNote?, emptyText?, errorText? }`.\n\t\t *\n\t\t * @type {object}\n\t\t */\n\t\tcontent: {\n\t\t\ttype: Object,\n\t\t\tdefault: () => ({}),\n\t\t},\n\n\t\t/** The current record's id, for the `@objectId` token. */\n\t\tobjectId: {\n\t\t\ttype: [String, Number],\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/** The current record, for `@object.<field>` tokens. */\n\t\tobjectData: {\n\t\t\ttype: Object,\n\t\t\tdefault: null,\n\t\t},\n\t},\n\n\temits: ['header'],\n\n\tdata() {\n\t\treturn {\n\t\t\trows: [],\n\t\t\ttotal: 0,\n\t\t\tloading: false,\n\t\t\terror: false,\n\t\t}\n\t},\n\n\tcomputed: {\n\t\t/** @return {string} `rows`, `feed` or `inline`. */\n\t\tpresentation() {\n\t\t\tconst value = this.content?.presentation\n\t\t\treturn PRESENTATIONS.includes(value) ? value : 'rows'\n\t\t},\n\n\t\t/** @return {object} The token context: record, id and workspace. */\n\t\ttokenCtx() {\n\t\t\tconst injected = unwrap(this.cnObjectContext) || {}\n\t\t\treturn {\n\t\t\t\t...injected,\n\t\t\t\tobjectId: this.objectId ?? injected.objectId ?? this.objectData?.id ?? null,\n\t\t\t\tobject: this.objectData || injected.object || null,\n\t\t\t\tworkspace: unwrap(this.cnWorkspaceContext) || {},\n\t\t\t}\n\t\t},\n\n\t\t/** @return {object} The filter with its tokens resolved. */\n\t\tresolvedFilter() {\n\t\t\tconst filter = this.content?.filter\n\t\t\treturn dropOptionalUnresolved(resolveFilterTokens(filter && typeof filter === 'object' ? filter : {}, this.tokenCtx))\n\t\t},\n\n\t\t/** @return {boolean} A required token (the record id, say) has no value yet. */\n\t\twaiting() {\n\t\t\treturn hasUnresolvedTokens(this.resolvedFilter)\n\t\t},\n\n\t\t/** @return {number} The fetch cap. */\n\t\tlimit() {\n\t\t\tconst value = Number(this.content?.limit)\n\t\t\treturn Number.isFinite(value) && value > 0 ? Math.floor(value) : 5\n\t\t},\n\n\t\t/** @return {string} What a fetch depends on; a change fetches again. */\n\t\trequestKey() {\n\t\t\tconst c = this.content || {}\n\t\t\treturn JSON.stringify([c.register, c.schema, this.resolvedFilter, c.sort, this.limit, c.extend, this.waiting])\n\t\t},\n\n\t\t/** @return {Array<object>} The rows ready to draw. */\n\t\titems() {\n\t\t\tconst c = this.content || {}\n\t\t\treturn this.rows.slice(0, this.limit).map((row, index) => {\n\t\t\t\tconst link = this.rowLink(row)\n\t\t\t\treturn {\n\t\t\t\t\tkey: (row && (row.id || row['@self']?.id)) || `row-${index}`,\n\t\t\t\t\ttag: link ? 'router-link' : 'div',\n\t\t\t\t\tattrs: link ? { to: link } : {},\n\t\t\t\t\ttitle: this.fill(c.title, row),\n\t\t\t\t\tmeta: this.fill(c.meta, row),\n\t\t\t\t\ttext: this.fill(c.text, row),\n\t\t\t\t\tlabel: this.fill(c.label, row),\n\t\t\t\t\ttrailing: c.trailing ? firstFilled(c.trailing, row, this.translate) : '',\n\t\t\t\t\tpill: this.pillOf(row),\n\t\t\t\t\ticon: this.iconOf(row),\n\t\t\t\t}\n\t\t\t})\n\t\t},\n\n\t\t/** @return {object|null} The header link with `{total}` filled and tokens resolved. */\n\t\theaderLink() {\n\t\t\tconst link = this.content?.headerLink\n\t\t\tif (!link || typeof link !== 'object' || typeof link.label !== 'string' || link.label === '') {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst resolved = { label: this.withTotal(link.label) }\n\t\t\tif (link.route) {\n\t\t\t\tresolved.route = link.route\n\t\t\t\tif (link.params && typeof link.params === 'object') {\n\t\t\t\t\tresolved.params = resolveFilterTokens(link.params, this.tokenCtx)\n\t\t\t\t}\n\t\t\t\tif (link.query && typeof link.query === 'object') {\n\t\t\t\t\tresolved.query = resolveFilterTokens(link.query, this.tokenCtx)\n\t\t\t\t}\n\t\t\t} else if (typeof link.href === 'string') {\n\t\t\t\tresolved.href = link.href\n\t\t\t}\n\t\t\treturn resolved\n\t\t},\n\n\t\t/** @return {string} The header note with `{total}` filled. */\n\t\theaderNote() {\n\t\t\tconst note = this.content?.headerNote\n\t\t\treturn typeof note === 'string' && note !== '' ? this.withTotal(note) : ''\n\t\t},\n\n\t\t/** @return {string} The empty line. */\n\t\temptyLabel() {\n\t\t\treturn this.content?.emptyText ? this.translate(this.content.emptyText) : t('nextcloud-vue', 'Nothing here yet')\n\t\t},\n\n\t\t/** @return {string} The error line. */\n\t\terrorLabel() {\n\t\t\treturn this.content?.errorText ? this.translate(this.content.errorText) : t('nextcloud-vue', 'This list could not be loaded.')\n\t\t},\n\n\t\t/** @return {string} The spinner's accessible name. */\n\t\tloadingLabel() {\n\t\t\treturn t('nextcloud-vue', 'Loading …')\n\t\t},\n\t},\n\n\twatch: {\n\t\trequestKey() {\n\t\t\tthis.fetchRows()\n\t\t},\n\t},\n\n\tmounted() {\n\t\tthis.onRefresh = () => this.fetchRows()\n\t\tsubscribe(PAGE_REFRESH_CHANNEL, this.onRefresh)\n\t\tthis.fetchRows()\n\t},\n\n\tbeforeUnmount() {\n\t\tunsubscribe(PAGE_REFRESH_CHANNEL, this.onRefresh)\n\t},\n\n\tmethods: {\n\t\t/**\n\t\t * Translate a manifest string through the host app.\n\t\t *\n\t\t * @param {string} text The text.\n\t\t * @return {string} The translation.\n\t\t */\n\t\ttranslate(text) {\n\t\t\treturn typeof this.cnTranslate === 'function' ? this.cnTranslate(text) : text\n\t\t},\n\n\t\t/**\n\t\t * Fill a template from a row, after translating it.\n\t\t *\n\t\t * @param {string} template The template.\n\t\t * @param {object} row The row.\n\t\t * @return {string} The text, '' when a token is empty.\n\t\t */\n\t\tfill(template, row) {\n\t\t\treturn typeof template === 'string' && template !== '' ? fillTemplate(this.translate(template), row) : ''\n\t\t},\n\n\t\t/**\n\t\t * Replace `{total}` in a translated label.\n\t\t *\n\t\t * @param {string} label The label.\n\t\t * @return {string} The text.\n\t\t */\n\t\twithTotal(label) {\n\t\t\treturn this.translate(label).replace(/\\{total\\}/g, String(this.total))\n\t\t},\n\n\t\t/**\n\t\t * The route a row opens: `rowRoute` with the id at `rowIdField`.\n\t\t *\n\t\t * @param {object} row The row.\n\t\t * @return {object|null} The router location, or null.\n\t\t */\n\t\trowLink(row) {\n\t\t\tconst route = this.content?.rowRoute\n\t\t\tif (!route || !this.$router || !row) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst field = this.content?.rowIdField\n\t\t\tconst id = field ? readPath(row, field) : (row.id || row['@self']?.id)\n\t\t\tif (id === null || id === undefined || id === '' || typeof id === 'object') {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\treturn { name: route, params: { id: String(id) } }\n\t\t},\n\n\t\t/**\n\t\t * The row's pill: `{ field, labels?, colorMap?, variant? }`.\n\t\t *\n\t\t * @param {object} row The row.\n\t\t * @return {{label: string, variant: string}|null} The pill, or null.\n\t\t */\n\t\tpillOf(row) {\n\t\t\tconst pill = this.content?.pill\n\t\t\tif (!pill || typeof pill !== 'object' || !pill.field) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst raw = readPath(row, pill.field)\n\t\t\tif (raw === null || raw === undefined || raw === '' || typeof raw === 'object') {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst key = String(raw)\n\t\t\tconst labels = pill.labels && typeof pill.labels === 'object' ? pill.labels : {}\n\t\t\tconst map = pill.colorMap && typeof pill.colorMap === 'object' ? pill.colorMap : {}\n\t\t\tconst found = Object.keys(map).find((k) => k.toLowerCase() === key.toLowerCase())\n\t\t\tconst variant = found ? map[found] : pill.variant\n\t\t\treturn {\n\t\t\t\tlabel: labels[key] ? this.translate(labels[key]) : key,\n\t\t\t\tvariant: isBadgeVariant(variant) ? variant : 'default',\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * The feed icon: an icon name, or `{ field, map, default }`.\n\t\t *\n\t\t * @param {object} row The row.\n\t\t * @return {string} The MDI icon name.\n\t\t */\n\t\ticonOf(row) {\n\t\t\tconst icon = this.content?.icon\n\t\t\tif (typeof icon === 'string' && icon !== '') {\n\t\t\t\treturn icon\n\t\t\t}\n\t\t\tif (icon && typeof icon === 'object') {\n\t\t\t\tconst raw = icon.field ? readPath(row, icon.field) : undefined\n\t\t\t\tconst map = icon.map && typeof icon.map === 'object' ? icon.map : {}\n\t\t\t\tif (raw !== null && raw !== undefined && map[String(raw)]) {\n\t\t\t\t\treturn map[String(raw)]\n\t\t\t\t}\n\t\t\t\tif (typeof icon.default === 'string' && icon.default !== '') {\n\t\t\t\t\treturn icon.default\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn 'CircleSmall'\n\t\t},\n\n\t\t/** Tell the card around this list what its header shows. */\n\t\temitHeader() {\n\t\t\t/**\n\t\t\t * @event header Emitted after every read with the card header's parts.\n\t\t\t * @type {{link: (object|null), note: string}} The header link (resolved, with `{total}` filled) and the note.\n\t\t\t */\n\t\t\tthis.$emit('header', { link: this.headerLink, note: this.headerNote })\n\t\t},\n\n\t\t/**\n\t\t * Fetch the list. Sends nothing while a required token is unresolved\n\t\t * or the source is incomplete.\n\t\t *\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync fetchRows() {\n\t\t\tconst c = this.content || {}\n\t\t\tif (!c.register || !c.schema || this.waiting) {\n\t\t\t\tthis.rows = []\n\t\t\t\tthis.total = 0\n\t\t\t\tthis.error = false\n\t\t\t\tthis.emitHeader()\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.loading = true\n\t\t\tthis.error = false\n\t\t\ttry {\n\t\t\t\tconst [{ default: axios }, { generateUrl }] = await Promise.all([\n\t\t\t\t\timport('@nextcloud/axios'),\n\t\t\t\t\timport('@nextcloud/router'),\n\t\t\t\t])\n\t\t\t\tconst url = generateUrl('/apps/openregister/api/objects/{register}/{schema}', { register: c.register, schema: c.schema })\n\t\t\t\tconst params = { _limit: this.limit }\n\t\t\t\tif (c.sort && typeof c.sort === 'object' && c.sort.field) {\n\t\t\t\t\tparams[`_order[${c.sort.field}]`] = c.sort.dir === 'desc' ? 'desc' : 'asc'\n\t\t\t\t}\n\t\t\t\tif (Array.isArray(c.extend)) {\n\t\t\t\t\tconst extend = c.extend.filter((e) => typeof e === 'string' && e !== '')\n\t\t\t\t\tif (extend.length > 0) {\n\t\t\t\t\t\tparams._extend = extend\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tfor (const [key, value] of Object.entries(this.resolvedFilter)) {\n\t\t\t\t\tif (value && typeof value === 'object' && !Array.isArray(value)) {\n\t\t\t\t\t\tfor (const [op, operand] of Object.entries(value)) {\n\t\t\t\t\t\t\tparams[`${key}[${op}]`] = operand\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (value !== '' && value !== null && value !== undefined) {\n\t\t\t\t\t\tparams[key] = value\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tconst response = await axios.get(url, { params })\n\t\t\t\tconst data = response && response.data ? response.data : {}\n\t\t\t\tthis.rows = Array.isArray(data.results) ? data.results : []\n\t\t\t\tthis.total = typeof data.total === 'number' ? data.total : this.rows.length\n\t\t\t} catch (e) {\n\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\tconsole.warn('[CnRecordListWidget] failed to load objects:', e)\n\t\t\t\tthis.rows = []\n\t\t\t\tthis.total = 0\n\t\t\t\tthis.error = true\n\t\t\t} finally {\n\t\t\t\tthis.loading = false\n\t\t\t\tthis.emitHeader()\n\t\t\t}\n\t\t},\n\t},\n}\n</script>\n\n<style scoped>\n.cn-record-list__list {\n\tlist-style: none;\n\tmargin: 0;\n\tpadding: 0;\n}\n\n.cn-record-list__empty,\n.cn-record-list__error {\n\tcolor: var(--color-text-maxcontrast);\n\tmargin: 0;\n}\n\n.cn-record-list__loading {\n\tdisplay: flex;\n\tjustify-content: center;\n\tpadding: 8px 0;\n}\n\n/* rows */\n.cn-record-list--rows .cn-record-list__item + .cn-record-list__item {\n\tborder-top: 1px solid var(--color-border);\n}\n\n.cn-record-list__row {\n\talign-items: center;\n\tcolor: var(--color-main-text);\n\tdisplay: flex;\n\tgap: 16px;\n\tpadding: 12px 0;\n\ttext-decoration: none;\n}\n\n.cn-record-list__row--link:hover .cn-record-list__title,\n.cn-record-list__row--link:focus-visible .cn-record-list__title {\n\ttext-decoration: underline;\n}\n\n.cn-record-list__main {\n\tdisplay: flex;\n\tflex: 1 1 auto;\n\tflex-direction: column;\n\tgap: 2px;\n\tmin-width: 0;\n}\n\n.cn-record-list__title {\n\tfont-size: 15px;\n\tfont-weight: 700;\n}\n\n.cn-record-list__meta {\n\tcolor: var(--color-text-maxcontrast);\n\tfont-size: 13px;\n}\n\n.cn-record-list__aside {\n\talign-items: center;\n\tdisplay: flex;\n\tflex: none;\n\tgap: 16px;\n}\n\n.cn-record-list__trailing {\n\tfont-size: 14px;\n\twhite-space: nowrap;\n}\n\n.cn-record-list__chevron {\n\tcolor: var(--color-text-maxcontrast);\n\tflex: none;\n}\n\n/* feed */\n.cn-record-list--feed .cn-record-list__item + .cn-record-list__item {\n\tborder-top: 1px solid var(--color-border);\n}\n\n.cn-record-list__feed-row {\n\talign-items: flex-start;\n\tdisplay: flex;\n\tgap: 14px;\n\tpadding: 12px 0;\n}\n\n.cn-record-list__feed-icon {\n\talign-items: center;\n\tbackground: var(--color-primary-element-light);\n\tborder-radius: 50%;\n\tcolor: var(--color-primary-element-light-text, var(--color-primary-element));\n\tdisplay: flex;\n\tflex: none;\n\theight: 36px;\n\tjustify-content: center;\n\twidth: 36px;\n}\n\n.cn-record-list__text {\n\tfont-size: 15px;\n}\n\n.cn-record-list--feed .cn-record-list__main {\n\tcolor: var(--color-main-text);\n\ttext-decoration: none;\n}\n\n/* inline */\n.cn-record-list__inline-row {\n\tpadding: 4px 0;\n}\n\n.cn-record-list__label {\n\tmargin-inline-end: 4px;\n}\n\n.cn-record-list__inline-title {\n\tcolor: var(--color-main-text);\n}\n\na.cn-record-list__inline-title {\n\tcolor: var(--color-primary-element);\n\ttext-decoration: underline;\n}\n</style>\n\n<style>\n/* In a narrow side column a row stacks: title, meta, then pill and date. */\n.cn-detail-page__side .cn-record-list__row {\n\talign-items: flex-start;\n\tflex-direction: column;\n\tgap: 6px;\n}\n\n.cn-detail-page__side .cn-record-list__row .cn-record-list__title {\n\tcolor: var(--color-primary-element);\n\ttext-decoration: underline;\n}\n\n.cn-detail-page__side .cn-record-list__chevron {\n\tdisplay: none;\n}\n</style>\n"],"names":["CnIcon","CnStatusBadge","t"],"mappings":"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"}
@@ -0,0 +1,169 @@
1
+ import { resolveComponent, openBlock, createElementBlock, normalizeClass, toDisplayString, createVNode, Fragment, renderList, createBlock, resolveDynamicComponent, mergeProps, withCtx, createElementVNode, createCommentVNode, createTextVNode } from 'vue';
2
+
3
+ const _hoisted_1 = {
4
+ key: 0,
5
+ class: "cn-record-list__error",
6
+ "data-testid": "cn-record-list-error"
7
+ };
8
+ const _hoisted_2 = {
9
+ key: 1,
10
+ class: "cn-record-list__loading"
11
+ };
12
+ const _hoisted_3 = {
13
+ key: 2,
14
+ class: "cn-record-list__empty",
15
+ "data-testid": "cn-record-list-empty"
16
+ };
17
+ const _hoisted_4 = {
18
+ key: 3,
19
+ class: "cn-record-list__list"
20
+ };
21
+ const _hoisted_5 = { class: "cn-record-list__main" };
22
+ const _hoisted_6 = {
23
+ key: 0,
24
+ class: "cn-record-list__title"
25
+ };
26
+ const _hoisted_7 = {
27
+ key: 1,
28
+ class: "cn-record-list__meta"
29
+ };
30
+ const _hoisted_8 = {
31
+ key: 0,
32
+ class: "cn-record-list__aside"
33
+ };
34
+ const _hoisted_9 = {
35
+ key: 1,
36
+ class: "cn-record-list__trailing"
37
+ };
38
+ const _hoisted_10 = {
39
+ key: 1,
40
+ class: "cn-record-list__feed-row"
41
+ };
42
+ const _hoisted_11 = {
43
+ class: "cn-record-list__feed-icon",
44
+ "aria-hidden": "true"
45
+ };
46
+ const _hoisted_12 = {
47
+ key: 0,
48
+ class: "cn-record-list__meta"
49
+ };
50
+ const _hoisted_13 = {
51
+ key: 1,
52
+ class: "cn-record-list__text"
53
+ };
54
+ const _hoisted_14 = {
55
+ key: 2,
56
+ class: "cn-record-list__inline-row"
57
+ };
58
+ const _hoisted_15 = {
59
+ key: 0,
60
+ class: "cn-record-list__label"
61
+ };
62
+
63
+ function render(_ctx, _cache, $props, $setup, $data, $options) {
64
+ const _component_NcLoadingIcon = resolveComponent("NcLoadingIcon");
65
+ const _component_CnStatusBadge = resolveComponent("CnStatusBadge");
66
+ const _component_ChevronRight = resolveComponent("ChevronRight");
67
+ const _component_CnIcon = resolveComponent("CnIcon");
68
+
69
+ return (openBlock(), createElementBlock("div", {
70
+ class: normalizeClass(["cn-record-list", `cn-record-list--${$options.presentation}`]),
71
+ "data-testid": "cn-record-list"
72
+ }, [
73
+ ($data.error)
74
+ ? (openBlock(), createElementBlock("p", _hoisted_1, toDisplayString($options.errorLabel), 1 /* TEXT */))
75
+ : ($data.loading && $data.rows.length === 0)
76
+ ? (openBlock(), createElementBlock("div", _hoisted_2, [
77
+ createVNode(_component_NcLoadingIcon, {
78
+ size: 20,
79
+ name: $options.loadingLabel
80
+ }, null, 8 /* PROPS */, ["name"])
81
+ ]))
82
+ : ($data.rows.length === 0)
83
+ ? (openBlock(), createElementBlock("p", _hoisted_3, toDisplayString($options.emptyLabel), 1 /* TEXT */))
84
+ : (openBlock(), createElementBlock("ul", _hoisted_4, [
85
+ (openBlock(true), createElementBlock(Fragment, null, renderList($options.items, (item) => {
86
+ return (openBlock(), createElementBlock("li", {
87
+ key: item.key,
88
+ class: "cn-record-list__item",
89
+ "data-testid": "cn-record-list-item"
90
+ }, [
91
+ ($options.presentation === 'rows')
92
+ ? (openBlock(), createBlock(resolveDynamicComponent(item.tag), mergeProps({
93
+ key: 0,
94
+ class: ["cn-record-list__row", { 'cn-record-list__row--link': item.tag !== 'div' }]
95
+ }, { ref_for: true }, item.attrs), {
96
+ default: withCtx(() => [
97
+ createElementVNode("span", _hoisted_5, [
98
+ (item.title)
99
+ ? (openBlock(), createElementBlock("span", _hoisted_6, toDisplayString(item.title), 1 /* TEXT */))
100
+ : createCommentVNode("v-if", true),
101
+ (item.meta)
102
+ ? (openBlock(), createElementBlock("span", _hoisted_7, toDisplayString(item.meta), 1 /* TEXT */))
103
+ : createCommentVNode("v-if", true)
104
+ ]),
105
+ (item.pill || item.trailing)
106
+ ? (openBlock(), createElementBlock("span", _hoisted_8, [
107
+ (item.pill)
108
+ ? (openBlock(), createBlock(_component_CnStatusBadge, {
109
+ key: 0,
110
+ label: item.pill.label,
111
+ variant: item.pill.variant,
112
+ size: "small"
113
+ }, null, 8 /* PROPS */, ["label", "variant"]))
114
+ : createCommentVNode("v-if", true),
115
+ (item.trailing)
116
+ ? (openBlock(), createElementBlock("span", _hoisted_9, toDisplayString(item.trailing), 1 /* TEXT */))
117
+ : createCommentVNode("v-if", true)
118
+ ]))
119
+ : createCommentVNode("v-if", true),
120
+ (item.tag !== 'div')
121
+ ? (openBlock(), createBlock(_component_ChevronRight, {
122
+ key: 1,
123
+ class: "cn-record-list__chevron",
124
+ size: 18,
125
+ "aria-hidden": "true"
126
+ }))
127
+ : createCommentVNode("v-if", true)
128
+ ]),
129
+ _: 2 /* DYNAMIC */
130
+ }, 1040 /* FULL_PROPS, DYNAMIC_SLOTS */, ["class"]))
131
+ : ($options.presentation === 'feed')
132
+ ? (openBlock(), createElementBlock("div", _hoisted_10, [
133
+ createElementVNode("span", _hoisted_11, [
134
+ createVNode(_component_CnIcon, {
135
+ name: item.icon,
136
+ size: 18
137
+ }, null, 8 /* PROPS */, ["name"])
138
+ ]),
139
+ (openBlock(), createBlock(resolveDynamicComponent(item.tag), mergeProps({ class: "cn-record-list__main" }, { ref_for: true }, item.attrs), {
140
+ default: withCtx(() => [
141
+ (item.meta)
142
+ ? (openBlock(), createElementBlock("span", _hoisted_12, toDisplayString(item.meta), 1 /* TEXT */))
143
+ : createCommentVNode("v-if", true),
144
+ (item.text)
145
+ ? (openBlock(), createElementBlock("span", _hoisted_13, toDisplayString(item.text), 1 /* TEXT */))
146
+ : createCommentVNode("v-if", true)
147
+ ]),
148
+ _: 2 /* DYNAMIC */
149
+ }, 1040 /* FULL_PROPS, DYNAMIC_SLOTS */))
150
+ ]))
151
+ : (openBlock(), createElementBlock("div", _hoisted_14, [
152
+ (item.label)
153
+ ? (openBlock(), createElementBlock("span", _hoisted_15, toDisplayString(item.label), 1 /* TEXT */))
154
+ : createCommentVNode("v-if", true),
155
+ (openBlock(), createBlock(resolveDynamicComponent(item.tag), mergeProps({ class: "cn-record-list__inline-title" }, { ref_for: true }, item.attrs), {
156
+ default: withCtx(() => [
157
+ createTextVNode(toDisplayString(item.title), 1 /* TEXT */)
158
+ ]),
159
+ _: 2 /* DYNAMIC */
160
+ }, 1040 /* FULL_PROPS, DYNAMIC_SLOTS */))
161
+ ]))
162
+ ]))
163
+ }), 128 /* KEYED_FRAGMENT */))
164
+ ]))
165
+ ], 2 /* CLASS */))
166
+ }
167
+
168
+ export { render };
169
+ //# sourceMappingURL=CnRecordListWidget.vue3.js.map