@conduction/nextcloud-vue 2.119.0 → 2.121.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.
- package/dist/esm/components/CnAiFeaturesWidget/CnAiFeaturesWidget.vue.js +9 -0
- package/dist/esm/components/CnAiFeaturesWidget/CnAiFeaturesWidget.vue.js.map +1 -0
- package/dist/esm/components/CnAiFeaturesWidget/CnAiFeaturesWidget.vue2.js +226 -0
- package/dist/esm/components/CnAiFeaturesWidget/CnAiFeaturesWidget.vue2.js.map +1 -0
- package/dist/esm/components/CnAiFeaturesWidget/CnAiFeaturesWidget.vue3.js +211 -0
- package/dist/esm/components/CnAiFeaturesWidget/CnAiFeaturesWidget.vue3.js.map +1 -0
- package/dist/esm/components/CnAiFeaturesWidget/CnAiSuggestionDecision.vue.js +9 -0
- package/dist/esm/components/CnAiFeaturesWidget/CnAiSuggestionDecision.vue.js.map +1 -0
- package/dist/esm/components/CnAiFeaturesWidget/CnAiSuggestionDecision.vue2.js +64 -0
- package/dist/esm/components/CnAiFeaturesWidget/CnAiSuggestionDecision.vue2.js.map +1 -0
- package/dist/esm/components/CnAiFeaturesWidget/CnAiSuggestionDecision.vue3.js +89 -0
- package/dist/esm/components/CnAiFeaturesWidget/CnAiSuggestionDecision.vue3.js.map +1 -0
- package/dist/esm/components/CnIcon/semanticIcons.js +2 -2
- package/dist/esm/components/CnIcon/semanticIcons.js.map +1 -1
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js +53 -1
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js.map +1 -1
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js +546 -523
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js.map +1 -1
- package/dist/esm/components/CnIndexPage/useNamedSource.js +9 -0
- package/dist/esm/components/CnIndexPage/useNamedSource.js.map +1 -1
- package/dist/esm/components/CnObjectPermissionsTab/CnObjectPermissionsTab.vue.js +9 -0
- package/dist/esm/components/CnObjectPermissionsTab/CnObjectPermissionsTab.vue.js.map +1 -0
- package/dist/esm/components/CnObjectPermissionsTab/CnObjectPermissionsTab.vue2.js +257 -0
- package/dist/esm/components/CnObjectPermissionsTab/CnObjectPermissionsTab.vue2.js.map +1 -0
- package/dist/esm/components/CnObjectPermissionsTab/CnObjectPermissionsTab.vue3.js +266 -0
- package/dist/esm/components/CnObjectPermissionsTab/CnObjectPermissionsTab.vue3.js.map +1 -0
- package/dist/esm/components/CnObjectSidebar/CnObjectSidebar.vue.js +1 -1
- package/dist/esm/components/CnObjectSidebar/CnObjectSidebar.vue2.js +14 -7
- package/dist/esm/components/CnObjectSidebar/CnObjectSidebar.vue2.js.map +1 -1
- package/dist/esm/components/CnObjectSidebar/CnObjectSidebar.vue3.js.map +1 -1
- package/dist/esm/components/CnObjectTranslationsWidget/CnObjectTranslationsWidget.vue.js +9 -0
- package/dist/esm/components/CnObjectTranslationsWidget/CnObjectTranslationsWidget.vue.js.map +1 -0
- package/dist/esm/components/CnObjectTranslationsWidget/CnObjectTranslationsWidget.vue2.js +278 -0
- package/dist/esm/components/CnObjectTranslationsWidget/CnObjectTranslationsWidget.vue2.js.map +1 -0
- package/dist/esm/components/CnObjectTranslationsWidget/CnObjectTranslationsWidget.vue3.js +128 -0
- package/dist/esm/components/CnObjectTranslationsWidget/CnObjectTranslationsWidget.vue3.js.map +1 -0
- package/dist/esm/components/CnReadinessChecklist/CnReadinessChecklist.vue.js +9 -0
- package/dist/esm/components/CnReadinessChecklist/CnReadinessChecklist.vue.js.map +1 -0
- package/dist/esm/components/CnReadinessChecklist/CnReadinessChecklist.vue2.js +214 -0
- package/dist/esm/components/CnReadinessChecklist/CnReadinessChecklist.vue2.js.map +1 -0
- package/dist/esm/components/CnReadinessChecklist/CnReadinessChecklist.vue3.js +125 -0
- package/dist/esm/components/CnReadinessChecklist/CnReadinessChecklist.vue3.js.map +1 -0
- package/dist/esm/components/CnSchemaRulesWidget/CnSchemaRulesWidget.vue.js +9 -0
- package/dist/esm/components/CnSchemaRulesWidget/CnSchemaRulesWidget.vue.js.map +1 -0
- package/dist/esm/components/CnSchemaRulesWidget/CnSchemaRulesWidget.vue2.js +163 -0
- package/dist/esm/components/CnSchemaRulesWidget/CnSchemaRulesWidget.vue2.js.map +1 -0
- package/dist/esm/components/CnSchemaRulesWidget/CnSchemaRulesWidget.vue3.js +131 -0
- package/dist/esm/components/CnSchemaRulesWidget/CnSchemaRulesWidget.vue3.js.map +1 -0
- package/dist/esm/components/CnSchemaRulesWidget/schemaRules.js +127 -0
- package/dist/esm/components/CnSchemaRulesWidget/schemaRules.js.map +1 -0
- package/dist/esm/components/CnSearchIndexStatus/CnSearchIndexStatus.vue.js +9 -0
- package/dist/esm/components/CnSearchIndexStatus/CnSearchIndexStatus.vue.js.map +1 -0
- package/dist/esm/components/CnSearchIndexStatus/CnSearchIndexStatus.vue2.js +82 -0
- package/dist/esm/components/CnSearchIndexStatus/CnSearchIndexStatus.vue2.js.map +1 -0
- package/dist/esm/components/CnSearchIndexStatus/CnSearchIndexStatus.vue3.js +61 -0
- package/dist/esm/components/CnSearchIndexStatus/CnSearchIndexStatus.vue3.js.map +1 -0
- package/dist/esm/components/CnSearchIndexStatus/searchIndexStatus.js +60 -0
- package/dist/esm/components/CnSearchIndexStatus/searchIndexStatus.js.map +1 -0
- package/dist/esm/components/CnShippedConfigurationSection/CnShippedConfigurationSection.vue.js +10 -0
- package/dist/esm/components/CnShippedConfigurationSection/CnShippedConfigurationSection.vue.js.map +1 -0
- package/dist/esm/components/CnShippedConfigurationSection/CnShippedConfigurationSection.vue2.js +226 -0
- package/dist/esm/components/CnShippedConfigurationSection/CnShippedConfigurationSection.vue2.js.map +1 -0
- package/dist/esm/components/CnShippedConfigurationSection/CnShippedConfigurationSection.vue3.js +126 -0
- package/dist/esm/components/CnShippedConfigurationSection/CnShippedConfigurationSection.vue3.js.map +1 -0
- package/dist/esm/components/CnStateMachineEditor/CnStateMachineEditor.vue.js +10 -0
- package/dist/esm/components/CnStateMachineEditor/CnStateMachineEditor.vue.js.map +1 -0
- package/dist/esm/components/CnStateMachineEditor/CnStateMachineEditor.vue2.js +944 -0
- package/dist/esm/components/CnStateMachineEditor/CnStateMachineEditor.vue2.js.map +1 -0
- package/dist/esm/components/CnStateMachineEditor/CnStateMachineEditor.vue3.js +276 -0
- package/dist/esm/components/CnStateMachineEditor/CnStateMachineEditor.vue3.js.map +1 -0
- package/dist/esm/components/CnStateMachineEditor/CnStateMachineFields.vue.js +9 -0
- package/dist/esm/components/CnStateMachineEditor/CnStateMachineFields.vue.js.map +1 -0
- package/dist/esm/components/CnStateMachineEditor/CnStateMachineFields.vue2.js +354 -0
- package/dist/esm/components/CnStateMachineEditor/CnStateMachineFields.vue2.js.map +1 -0
- package/dist/esm/components/CnStateMachineEditor/CnStateMachineFields.vue3.js +392 -0
- package/dist/esm/components/CnStateMachineEditor/CnStateMachineFields.vue3.js.map +1 -0
- package/dist/esm/components/CnStateMachineEditor/CnStateMachineNode.vue.js +9 -0
- package/dist/esm/components/CnStateMachineEditor/CnStateMachineNode.vue.js.map +1 -0
- package/dist/esm/components/CnStateMachineEditor/CnStateMachineNode.vue2.js +180 -0
- package/dist/esm/components/CnStateMachineEditor/CnStateMachineNode.vue2.js.map +1 -0
- package/dist/esm/components/CnStateMachineEditor/CnStateMachineNode.vue3.js +208 -0
- package/dist/esm/components/CnStateMachineEditor/CnStateMachineNode.vue3.js.map +1 -0
- package/dist/esm/components/CnStateMachineEditor/CnStateMachinePanel.vue.js +9 -0
- package/dist/esm/components/CnStateMachineEditor/CnStateMachinePanel.vue.js.map +1 -0
- package/dist/esm/components/CnStateMachineEditor/CnStateMachinePanel.vue2.js +244 -0
- package/dist/esm/components/CnStateMachineEditor/CnStateMachinePanel.vue2.js.map +1 -0
- package/dist/esm/components/CnStateMachineEditor/CnStateMachinePanel.vue3.js +76 -0
- package/dist/esm/components/CnStateMachineEditor/CnStateMachinePanel.vue3.js.map +1 -0
- package/dist/esm/components/CnStateMachineEditor/stateMachineFields.js +290 -0
- package/dist/esm/components/CnStateMachineEditor/stateMachineFields.js.map +1 -0
- package/dist/esm/components/CnTimelineWidget/CnTimelineManage.vue.js +9 -0
- package/dist/esm/components/CnTimelineWidget/CnTimelineManage.vue.js.map +1 -0
- package/dist/esm/components/CnTimelineWidget/CnTimelineManage.vue2.js +448 -0
- package/dist/esm/components/CnTimelineWidget/CnTimelineManage.vue2.js.map +1 -0
- package/dist/esm/components/CnTimelineWidget/CnTimelineManage.vue3.js +303 -0
- package/dist/esm/components/CnTimelineWidget/CnTimelineManage.vue3.js.map +1 -0
- package/dist/esm/components/CnTimelineWidget/CnTimelineWidget.vue.js +1 -1
- package/dist/esm/components/CnTimelineWidget/CnTimelineWidget.vue2.js +19 -2
- package/dist/esm/components/CnTimelineWidget/CnTimelineWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnTimelineWidget/CnTimelineWidget.vue3.js +73 -62
- package/dist/esm/components/CnTimelineWidget/CnTimelineWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnWidgetGrid/builtInWidgets.js +6 -0
- package/dist/esm/components/CnWidgetGrid/builtInWidgets.js.map +1 -1
- package/dist/esm/components/CnWidgetGrid/registerDashboardWidgets.js +42 -32
- package/dist/esm/components/CnWidgetGrid/registerDashboardWidgets.js.map +1 -1
- package/dist/esm/composables/indexSources.js +116 -16
- package/dist/esm/composables/indexSources.js.map +1 -1
- package/dist/esm/index.js +9 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/l10n/en.json.js +207 -1
- package/dist/esm/l10n/en.json.js.map +1 -1
- package/dist/esm/l10n/nl.json.js +207 -1
- package/dist/esm/l10n/nl.json.js.map +1 -1
- package/dist/esm/library-style.js +1 -1
- package/dist/esm/nextcloud-vue.css +951 -16
- package/dist/esm/utils/aiFeatures.js +245 -0
- package/dist/esm/utils/aiFeatures.js.map +1 -0
- package/dist/esm/utils/aiSuggestionTracker.js +182 -0
- package/dist/esm/utils/aiSuggestionTracker.js.map +1 -0
- package/dist/esm/utils/libraryWidgetKeys.js +2 -0
- package/dist/esm/utils/libraryWidgetKeys.js.map +1 -1
- package/dist/esm/utils/objectPermissions.js +552 -0
- package/dist/esm/utils/objectPermissions.js.map +1 -0
- package/dist/esm/utils/objectTranslations.js +180 -0
- package/dist/esm/utils/objectTranslations.js.map +1 -0
- package/dist/esm/utils/stateMachineValidation.js +254 -0
- package/dist/esm/utils/stateMachineValidation.js.map +1 -0
- package/dist/esm/utils/widgetDispatch.js +3 -1
- package/dist/esm/utils/widgetDispatch.js.map +1 -1
- package/dist/nextcloud-vue.cjs.js +23038 -14567
- package/dist/nextcloud-vue.cjs.js.map +2 -2
- package/dist/nextcloud-vue.css +951 -16
- package/l10n/en.json +207 -1
- package/l10n/nl.json +207 -1
- package/package.json +1 -1
- package/src/components/CnAiFeaturesWidget/CnAiFeaturesWidget.vue +416 -0
- package/src/components/CnAiFeaturesWidget/CnAiSuggestionDecision.vue +136 -0
- package/src/components/CnAiFeaturesWidget/__tests__/CnAiFeaturesWidget.spec.js +213 -0
- package/src/components/CnAiFeaturesWidget/index.js +14 -0
- package/src/components/CnIndexPage/CnIndexPage.vue +74 -3
- package/src/components/CnIndexPage/useNamedSource.js +9 -0
- package/src/components/CnObjectPermissionsTab/CnObjectPermissionsTab.vue +499 -0
- package/src/components/CnObjectPermissionsTab/__tests__/CnObjectPermissionsTab.spec.js +186 -0
- package/src/components/CnObjectPermissionsTab/index.js +13 -0
- package/src/components/CnObjectSidebar/CnObjectSidebar.vue +8 -1
- package/src/components/CnObjectTranslationsWidget/CnObjectTranslationsWidget.vue +424 -0
- package/src/components/CnObjectTranslationsWidget/__tests__/CnObjectTranslationsWidget.spec.js +189 -0
- package/src/components/CnObjectTranslationsWidget/index.js +13 -0
- package/src/components/CnReadinessChecklist/CnReadinessChecklist.vue +335 -0
- package/src/components/CnReadinessChecklist/index.js +9 -0
- package/src/components/CnSchemaRulesWidget/CnSchemaRulesWidget.vue +300 -0
- package/src/components/CnSchemaRulesWidget/index.js +10 -0
- package/src/components/CnSchemaRulesWidget/schemaRules.js +123 -0
- package/src/components/CnSearchIndexStatus/CnSearchIndexStatus.vue +160 -0
- package/src/components/CnSearchIndexStatus/index.js +10 -0
- package/src/components/CnSearchIndexStatus/searchIndexStatus.js +56 -0
- package/src/components/CnShippedConfigurationSection/CnShippedConfigurationSection.vue +328 -0
- package/src/components/CnShippedConfigurationSection/index.js +9 -0
- package/src/components/CnStateMachineEditor/CnStateMachineEditor.vue +1332 -0
- package/src/components/CnStateMachineEditor/CnStateMachineFields.vue +791 -0
- package/src/components/CnStateMachineEditor/CnStateMachineNode.vue +442 -0
- package/src/components/CnStateMachineEditor/CnStateMachinePanel.vue +326 -0
- package/src/components/CnStateMachineEditor/index.js +8 -0
- package/src/components/CnStateMachineEditor/stateMachineFields.js +287 -0
- package/src/components/CnTimelineWidget/CnTimelineManage.vue +827 -0
- package/src/components/CnTimelineWidget/CnTimelineWidget.vue +29 -3
- package/src/components/CnWidgetGrid/builtInWidgets.js +6 -0
- package/src/components/CnWidgetGrid/registerDashboardWidgets.js +10 -0
- package/src/components/index.js +8 -0
- package/src/composables/indexSources.js +116 -16
- package/src/css/index-page.css +7 -0
- package/src/index.js +9 -0
- package/src/utils/aiFeatures.js +241 -0
- package/src/utils/aiSuggestionTracker.js +178 -0
- package/src/utils/libraryWidgetKeys.js +2 -0
- package/src/utils/objectPermissions.js +548 -0
- package/src/utils/objectTranslations.js +176 -0
- package/src/utils/stateMachineValidation.js +250 -0
- package/src/utils/widgetDispatch.js +3 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { resolveComponent, openBlock, createElementBlock, toDisplayString, createCommentVNode, createVNode, createElementVNode, Fragment,
|
|
1
|
+
import { resolveComponent, openBlock, createBlock, createElementBlock, toDisplayString, createCommentVNode, createVNode, createElementVNode, Fragment, withCtx, createTextVNode, renderList, normalizeClass } from 'vue';
|
|
2
2
|
|
|
3
3
|
const _hoisted_1 = ["aria-busy"];
|
|
4
4
|
const _hoisted_2 = {
|
|
@@ -32,70 +32,81 @@ const _hoisted_11 = {
|
|
|
32
32
|
};
|
|
33
33
|
|
|
34
34
|
function render(_ctx, _cache, $props, $setup, $data, $options) {
|
|
35
|
+
const _component_CnTimelineManage = resolveComponent("CnTimelineManage");
|
|
35
36
|
const _component_NcLoadingIcon = resolveComponent("NcLoadingIcon");
|
|
36
37
|
const _component_NcNoteCard = resolveComponent("NcNoteCard");
|
|
37
38
|
|
|
38
|
-
return (
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
(
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
class: "cn-timeline-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
39
|
+
return ($options.manage)
|
|
40
|
+
? (openBlock(), createBlock(_component_CnTimelineManage, {
|
|
41
|
+
key: 0,
|
|
42
|
+
register: $options.resolvedRegister,
|
|
43
|
+
schema: $options.resolvedSchema,
|
|
44
|
+
objectId: $options.resolvedObjectId,
|
|
45
|
+
apiBase: $props.apiBase,
|
|
46
|
+
content: $props.content
|
|
47
|
+
}, null, 8 /* PROPS */, ["register", "schema", "objectId", "apiBase", "content"]))
|
|
48
|
+
: (openBlock(), createElementBlock("section", {
|
|
49
|
+
key: 1,
|
|
50
|
+
class: "cn-timeline-widget",
|
|
51
|
+
"data-testid": "cn-timeline-widget",
|
|
52
|
+
"aria-busy": $data.loading ? 'true' : 'false'
|
|
53
|
+
}, [
|
|
54
|
+
($options.resolvedTitle)
|
|
55
|
+
? (openBlock(), createElementBlock("h3", _hoisted_2, toDisplayString($options.resolvedTitle), 1 /* TEXT */))
|
|
56
|
+
: createCommentVNode("v-if", true),
|
|
57
|
+
($data.loading && $options.events.length === 0)
|
|
58
|
+
? (openBlock(), createElementBlock("div", _hoisted_3, [
|
|
59
|
+
createVNode(_component_NcLoadingIcon, {
|
|
60
|
+
size: 24,
|
|
61
|
+
"aria-hidden": "true"
|
|
62
|
+
}),
|
|
63
|
+
createElementVNode("span", null, toDisplayString($options.loadingLabel), 1 /* TEXT */)
|
|
64
|
+
]))
|
|
65
|
+
: (openBlock(), createElementBlock(Fragment, { key: 2 }, [
|
|
66
|
+
($data.failedSources.length > 0)
|
|
67
|
+
? (openBlock(), createBlock(_component_NcNoteCard, {
|
|
68
|
+
key: 0,
|
|
69
|
+
type: "warning",
|
|
70
|
+
"data-testid": "cn-timeline-widget-error"
|
|
71
|
+
}, {
|
|
72
|
+
default: withCtx(() => [
|
|
73
|
+
createTextVNode(toDisplayString($options.failedText), 1 /* TEXT */)
|
|
74
|
+
]),
|
|
75
|
+
_: 1 /* STABLE */
|
|
76
|
+
}))
|
|
77
|
+
: createCommentVNode("v-if", true),
|
|
78
|
+
($options.events.length === 0)
|
|
79
|
+
? (openBlock(), createElementBlock("p", _hoisted_4, toDisplayString($options.emptyLabel), 1 /* TEXT */))
|
|
80
|
+
: (openBlock(), createElementBlock("ol", _hoisted_5, [
|
|
81
|
+
(openBlock(true), createElementBlock(Fragment, null, renderList($options.events, (event) => {
|
|
82
|
+
return (openBlock(), createElementBlock("li", {
|
|
83
|
+
key: event.id,
|
|
84
|
+
class: normalizeClass(["cn-timeline-widget__event", { 'cn-timeline-widget__event--upcoming': event.upcoming }]),
|
|
85
|
+
"data-source": event.source,
|
|
86
|
+
"data-testid": "cn-timeline-widget-event"
|
|
87
|
+
}, [
|
|
88
|
+
_cache[0] || (_cache[0] = createElementVNode("span", {
|
|
89
|
+
class: "cn-timeline-widget__dot",
|
|
90
|
+
"aria-hidden": "true"
|
|
91
|
+
}, null, -1 /* CACHED */)),
|
|
92
|
+
createElementVNode("div", _hoisted_7, [
|
|
93
|
+
createElementVNode("time", {
|
|
94
|
+
class: "cn-timeline-widget__when",
|
|
95
|
+
datetime: event.at.toISOString()
|
|
96
|
+
}, toDisplayString($options.formatMoment(event)), 9 /* TEXT, PROPS */, _hoisted_8),
|
|
97
|
+
(event.upcoming)
|
|
98
|
+
? (openBlock(), createElementBlock("span", _hoisted_9, toDisplayString($options.upcomingLabel), 1 /* TEXT */))
|
|
99
|
+
: createCommentVNode("v-if", true),
|
|
100
|
+
createElementVNode("p", _hoisted_10, toDisplayString($options.translate(event.label)), 1 /* TEXT */),
|
|
101
|
+
(event.detail)
|
|
102
|
+
? (openBlock(), createElementBlock("p", _hoisted_11, toDisplayString(event.detail), 1 /* TEXT */))
|
|
103
|
+
: createCommentVNode("v-if", true)
|
|
104
|
+
])
|
|
105
|
+
], 10 /* CLASS, PROPS */, _hoisted_6))
|
|
106
|
+
}), 128 /* KEYED_FRAGMENT */))
|
|
107
|
+
]))
|
|
108
|
+
], 64 /* STABLE_FRAGMENT */))
|
|
109
|
+
], 8 /* PROPS */, _hoisted_1))
|
|
99
110
|
}
|
|
100
111
|
|
|
101
112
|
export { render };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CnTimelineWidget.vue3.js","sources":["../../../../src/components/CnTimelineWidget/CnTimelineWidget.vue?vue&type=template&id=091aa98d&lang.js"],"sourcesContent":["<!-- SPDX-License-Identifier: EUPL-1.2 -->\n<!-- SPDX-FileCopyrightText: 2026 Conduction B.V. <info@conduction.nl> -->\n<template>\n\t<section class=\"cn-timeline-widget\" data-testid=\"cn-timeline-widget\" :aria-busy=\"loading ? 'true' : 'false'\">\n\t\t<h3 v-if=\"resolvedTitle\" class=\"cn-timeline-widget__title\">\n\t\t\t{{ resolvedTitle }}\n\t\t</h3>\n\n\t\t<div v-if=\"loading && events.length === 0\" class=\"cn-timeline-widget__loading\">\n\t\t\t<NcLoadingIcon :size=\"24\" aria-hidden=\"true\" />\n\t\t\t<span>{{ loadingLabel }}</span>\n\t\t</div>\n\n\t\t<template v-else>\n\t\t\t<!-- A failed read is not an empty history: say which part is missing. -->\n\t\t\t<NcNoteCard v-if=\"failedSources.length > 0\" type=\"warning\" data-testid=\"cn-timeline-widget-error\">\n\t\t\t\t{{ failedText }}\n\t\t\t</NcNoteCard>\n\n\t\t\t<p v-if=\"events.length === 0\" class=\"cn-timeline-widget__empty\" data-testid=\"cn-timeline-widget-empty\">\n\t\t\t\t{{ emptyLabel }}\n\t\t\t</p>\n\n\t\t\t<ol v-else class=\"cn-timeline-widget__list\">\n\t\t\t\t<li\n\t\t\t\t\tv-for=\"event in events\"\n\t\t\t\t\t:key=\"event.id\"\n\t\t\t\t\tclass=\"cn-timeline-widget__event\"\n\t\t\t\t\t:class=\"{ 'cn-timeline-widget__event--upcoming': event.upcoming }\"\n\t\t\t\t\t:data-source=\"event.source\"\n\t\t\t\t\tdata-testid=\"cn-timeline-widget-event\">\n\t\t\t\t\t<span class=\"cn-timeline-widget__dot\" aria-hidden=\"true\" />\n\t\t\t\t\t<div class=\"cn-timeline-widget__body\">\n\t\t\t\t\t\t<time class=\"cn-timeline-widget__when\" :datetime=\"event.at.toISOString()\">\n\t\t\t\t\t\t\t{{ formatMoment(event) }}\n\t\t\t\t\t\t</time>\n\t\t\t\t\t\t<span v-if=\"event.upcoming\" class=\"cn-timeline-widget__badge\">\n\t\t\t\t\t\t\t{{ upcomingLabel }}\n\t\t\t\t\t\t</span>\n\t\t\t\t\t\t<p class=\"cn-timeline-widget__label\">\n\t\t\t\t\t\t\t{{ translate(event.label) }}\n\t\t\t\t\t\t</p>\n\t\t\t\t\t\t<p v-if=\"event.detail\" class=\"cn-timeline-widget__detail\">\n\t\t\t\t\t\t\t{{ event.detail }}\n\t\t\t\t\t\t</p>\n\t\t\t\t\t</div>\n\t\t\t\t</li>\n\t\t\t</ol>\n\t\t</template>\n\t</section>\n</template>\n\n<script>\nimport { getLanguage, translate as t } from '@nextcloud/l10n'\nimport { NcLoadingIcon, NcNoteCard } from '@nextcloud/vue'\nimport { auditEvents, fieldEvents, listEvents, relatedEvents, sortEvents, timelineEntryEvents } from '../../utils/timelineEvents.js'\nimport { userLocale } from '../../utils/userLocale.js'\n\n/**\n * CnTimelineWidget — an object's dated events in time order (`timeline`\n * widget type for detail pages).\n *\n * Generalises dossiq's case timeline. It merges up to four sources, all\n * optional, into one list:\n *\n * - `fields`: the object's own date properties, `[{ field, label }]`. A\n * dotted path reaches metadata, such as `@self.created`.\n * - `related`: related objects, `[{ register?, schema, field, dateField?,\n * label, titleField? }]`. Rows of `schema` whose `field` holds this object's\n * id become events at their `dateField` (default `@self.created`).\n * - `auditTrail: true`: the object's audit trail, one event per change.\n * - `timeline: true`: OpenRegister's timeline of notes, calls and messages.\n *\n * Oldest first by default (`order: 'desc'` flips it). A moment after now is\n * marked upcoming, in words as well as style.\n *\n * ```json\n * { \"type\": \"timeline\", \"content\": {\n * \"title\": \"Timeline\",\n * \"fields\": [\n * { \"field\": \"@self.created\", \"label\": \"Booking created\" },\n * { \"field\": \"depositClearedAt\", \"label\": \"Deposit cleared\" },\n * { \"field\": \"confirmationSentAt\", \"label\": \"Confirmation mail sent\" },\n * { \"field\": \"startsAt\", \"label\": \"Starts\" },\n * { \"field\": \"endsAt\", \"label\": \"Ends\" }\n * ] } }\n * ```\n *\n * The object comes from the detail page's context, like `audit-trail`:\n * explicit props win, then the injects, then `content`.\n *\n * @spec openspec/changes/timeline-widget/specs/timeline-widget/spec.md#requirement-a-timeline-widget-shows-an-objects-dated-events-in-order\n */\nexport default {\n\tname: 'CnTimelineWidget',\n\n\tcomponents: {\n\t\tNcLoadingIcon,\n\t\tNcNoteCard,\n\t},\n\n\tinject: {\n\t\t/** Detail-page object context from CnDetailPage (a ref or a raw bag). */\n\t\tcnObjectContext: { default: null },\n\t\t/** Detail object context holder from CnPageRenderer (`{ value: { objectData, ... } }`). */\n\t\tcnDetailObjectContext: { default: null },\n\t\t/** Consumer translation function; labels are authored in English. */\n\t\tcnTranslate: { default: () => (key) => key },\n\t},\n\n\tprops: {\n\t\t/** Register slug; object context spread as props by CnWidgetGrid. */\n\t\tregister: { type: String, default: '' },\n\t\t/**\n\t\t * Schema slug, or the schema object the detail context supplies.\n\t\t *\n\t\t * @type {string|object}\n\t\t */\n\t\tschema: { type: [String, Object], default: '' },\n\t\t/** The object's id. */\n\t\tobjectId: { type: String, default: '' },\n\t\t/** The object itself, when the host already has it. */\n\t\tobject: { type: Object, default: null },\n\t\t/** Card title override. */\n\t\ttitle: { type: String, default: '' },\n\t\t/** Stored widget content: `{ title, fields, related, auditTrail, timeline, order }`. */\n\t\tcontent: { type: Object, default: () => ({}) },\n\t\t/** OpenRegister API base. */\n\t\tapiBase: { type: String, default: '/apps/openregister/api' },\n\t},\n\n\tdata() {\n\t\treturn {\n\t\t\tloading: false,\n\t\t\trelatedRows: {},\n\t\t\tauditEntries: [],\n\t\t\ttimelineEntries: [],\n\t\t\tfailedSources: [],\n\t\t\tfetchedObject: null,\n\t\t\tloadSeq: 0,\n\t\t}\n\t},\n\n\tcomputed: {\n\t\tctx() {\n\t\t\tconst raw = this.cnObjectContext\n\t\t\tconst inj = raw && (raw.value !== undefined ? raw.value : raw)\n\t\t\tconst holder = this.cnDetailObjectContext && this.cnDetailObjectContext.value\n\t\t\treturn inj || holder || {}\n\t\t},\n\n\t\tresolvedObjectId() {\n\t\t\treturn this.objectId || this.ctx.objectId || this.content.objectId || ''\n\t\t},\n\n\t\tresolvedRegister() {\n\t\t\treturn this.register || this.ctx.register || this.content.register || ''\n\t\t},\n\n\t\tresolvedSchema() {\n\t\t\tconst s = this.schema || this.ctx.schema || this.content.schema || ''\n\t\t\treturn typeof s === 'string' ? s : (s && (s.slug || s.name || s.id)) || ''\n\t\t},\n\n\t\t/**\n\t\t * The object: explicit prop, then the page context, then a fetch of\n\t\t * our own when only the id is known.\n\t\t *\n\t\t * @return {object|null}\n\t\t */\n\t\tresolvedObject() {\n\t\t\treturn this.object || this.ctx.object || this.ctx.objectData || this.fetchedObject || null\n\t\t},\n\n\t\tresolvedTitle() {\n\t\t\tconst raw = this.title || this.content.title || ''\n\t\t\treturn raw ? this.translate(raw) : ''\n\t\t},\n\n\t\tfieldsConfig() {\n\t\t\treturn Array.isArray(this.content.fields) ? this.content.fields : []\n\t\t},\n\n\t\trelatedConfig() {\n\t\t\treturn Array.isArray(this.content.related) ? this.content.related.filter((r) => r && r.schema && r.field) : []\n\t\t},\n\n\t\t/**\n\t\t * Every event from every source, in time order.\n\t\t *\n\t\t * @return {Array<object>}\n\t\t */\n\t\tevents() {\n\t\t\tconst now = new Date()\n\t\t\tconst all = [\n\t\t\t\t...fieldEvents(this.resolvedObject || {}, this.fieldsConfig, now),\n\t\t\t\t...listEvents(this.resolvedObject || {}, this.content.lists, now),\n\t\t\t\t...this.relatedConfig.flatMap((cfg, i) => relatedEvents(this.relatedRows[i] || [], cfg, now)),\n\t\t\t\t...auditEvents(this.auditEntries, this.describeAudit, now),\n\t\t\t\t...timelineEntryEvents(this.timelineEntries, t('nextcloud-vue', 'Note'), now),\n\t\t\t]\n\t\t\treturn sortEvents(all, this.content.order === 'desc' ? 'desc' : 'asc')\n\t\t},\n\n\t\t/**\n\t\t * A signature of what to fetch, so a change refetches once.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tloadKey() {\n\t\t\treturn JSON.stringify({\n\t\t\t\tid: this.resolvedObjectId,\n\t\t\t\tregister: this.resolvedRegister,\n\t\t\t\tschema: this.resolvedSchema,\n\t\t\t\trelated: this.relatedConfig,\n\t\t\t\taudit: this.content.auditTrail === true,\n\t\t\t\ttimeline: this.content.timeline === true,\n\t\t\t\tneedObject: this.fieldsConfig.length > 0 && !(this.object || this.ctx.object || this.ctx.objectData),\n\t\t\t})\n\t\t},\n\n\t\tfailedText() {\n\t\t\treturn t('nextcloud-vue', 'Part of the timeline could not load: {parts}.', {\n\t\t\t\tparts: this.failedSources.map((s) => this.sourceName(s)).join(', '),\n\t\t\t})\n\t\t},\n\n\t\tloadingLabel() {\n\t\t\treturn t('nextcloud-vue', 'Loading…')\n\t\t},\n\n\t\temptyLabel() {\n\t\t\treturn t('nextcloud-vue', 'Nothing has happened yet.')\n\t\t},\n\n\t\tupcomingLabel() {\n\t\t\treturn t('nextcloud-vue', 'Upcoming')\n\t\t},\n\t},\n\n\twatch: {\n\t\tloadKey: {\n\t\t\timmediate: true,\n\t\t\thandler() {\n\t\t\t\tthis.load()\n\t\t\t},\n\t\t},\n\t},\n\n\tmethods: {\n\t\ttranslate(text) {\n\t\t\treturn text ? this.cnTranslate(text) : ''\n\t\t},\n\n\t\tsourceName(source) {\n\t\t\tif (source === 'audit') {\n\t\t\t\treturn t('nextcloud-vue', 'changes')\n\t\t\t}\n\t\t\tif (source === 'timeline') {\n\t\t\t\treturn t('nextcloud-vue', 'notes and messages')\n\t\t\t}\n\t\t\tif (source === 'object') {\n\t\t\t\treturn t('nextcloud-vue', 'dates')\n\t\t\t}\n\t\t\treturn t('nextcloud-vue', 'related items')\n\t\t},\n\n\t\t/**\n\t\t * The label of an audit event, from its action and who did it.\n\t\t *\n\t\t * @param {string} action The audit action (create, update, delete).\n\t\t * @param {string} actor Who did it.\n\t\t * @return {string}\n\t\t */\n\t\tdescribeAudit(action, actor) {\n\t\t\tconst known = {\n\t\t\t\tcreate: t('nextcloud-vue', 'Created'),\n\t\t\t\tupdate: t('nextcloud-vue', 'Updated'),\n\t\t\t\tdelete: t('nextcloud-vue', 'Deleted'),\n\t\t\t}\n\t\t\tconst what = known[action] || action || t('nextcloud-vue', 'Changed')\n\t\t\treturn actor ? t('nextcloud-vue', '{action} by {actor}', { action: what, actor }) : what\n\t\t},\n\n\t\t/**\n\t\t * Show a moment in the reader's language: a date for a calendar day,\n\t\t * date and time otherwise.\n\t\t *\n\t\t * @param {object} event The event.\n\t\t * @return {string}\n\t\t */\n\t\tformatMoment(event) {\n\t\t\tconst locale = (typeof getLanguage === 'function' && getLanguage()) || undefined\n\t\t\tconst options = event.dateOnly\n\t\t\t\t? { dateStyle: 'medium' }\n\t\t\t\t: { dateStyle: 'medium', timeStyle: 'short' }\n\t\t\ttry {\n\t\t\t\treturn new Intl.DateTimeFormat(locale, options).format(event.at)\n\t\t\t} catch {\n\t\t\t\treturn event.at.toLocaleString(userLocale())\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Fetch every configured source. Each one fails on its own, so one\n\t\t * unreachable source never hides the others.\n\t\t *\n\t\t * @return {Promise<void>}\n\t\t * @spec openspec/changes/timeline-widget/specs/timeline-widget/spec.md#requirement-a-timeline-widget-shows-an-objects-dated-events-in-order\n\t\t */\n\t\tasync load() {\n\t\t\tconst id = this.resolvedObjectId\n\t\t\tconst register = this.resolvedRegister\n\t\t\tconst schema = this.resolvedSchema\n\t\t\tconst seq = ++this.loadSeq\n\t\t\tif (!id || !register || !schema) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst [{ default: axios }, { generateUrl }] = await Promise.all([\n\t\t\t\timport('@nextcloud/axios'),\n\t\t\t\timport('@nextcloud/router'),\n\t\t\t])\n\t\t\tconst base = `${this.apiBase}/objects/${register}/${schema}/${id}`\n\t\t\tconst failed = []\n\t\t\tconst jobs = []\n\n\t\t\tif (this.fieldsConfig.length > 0 && !(this.object || this.ctx.object || this.ctx.objectData)) {\n\t\t\t\tjobs.push(axios.get(generateUrl(base))\n\t\t\t\t\t.then((r) => {\n\t\t\t\t\t\tthis.fetchedObject = (r && r.data) || null\n\t\t\t\t\t})\n\t\t\t\t\t.catch(() => failed.push('object')))\n\t\t\t}\n\n\t\t\tconst rows = {}\n\t\t\tthis.relatedConfig.forEach((cfg, i) => {\n\t\t\t\tconst url = generateUrl(`${this.apiBase}/objects/${cfg.register || register}/${cfg.schema}`)\n\t\t\t\tjobs.push(axios.get(url, { params: { [cfg.field]: id, _limit: cfg.limit || 50 } })\n\t\t\t\t\t.then((r) => {\n\t\t\t\t\t\tconst data = r && r.data\n\t\t\t\t\t\trows[i] = (data && (data.results || data)) || []\n\t\t\t\t\t})\n\t\t\t\t\t.catch(() => {\n\t\t\t\t\t\trows[i] = []\n\t\t\t\t\t\tif (!failed.includes('related')) {\n\t\t\t\t\t\t\tfailed.push('related')\n\t\t\t\t\t\t}\n\t\t\t\t\t}))\n\t\t\t})\n\n\t\t\tif (this.content.auditTrail === true) {\n\t\t\t\tjobs.push(axios.get(generateUrl(`${base}/audit-trails`), { params: { limit: this.content.auditLimit || 50 } })\n\t\t\t\t\t.then((r) => {\n\t\t\t\t\t\tconst data = r && r.data\n\t\t\t\t\t\tthis.auditEntries = (data && (data.results || data)) || []\n\t\t\t\t\t})\n\t\t\t\t\t.catch(() => {\n\t\t\t\t\t\tthis.auditEntries = []\n\t\t\t\t\t\tfailed.push('audit')\n\t\t\t\t\t}))\n\t\t\t}\n\n\t\t\tif (this.content.timeline === true) {\n\t\t\t\tjobs.push(axios.get(generateUrl(`${base}/timeline`))\n\t\t\t\t\t.then((r) => {\n\t\t\t\t\t\tconst data = r && r.data\n\t\t\t\t\t\tthis.timelineEntries = (data && (data.results || data)) || []\n\t\t\t\t\t})\n\t\t\t\t\t.catch(() => {\n\t\t\t\t\t\tthis.timelineEntries = []\n\t\t\t\t\t\tfailed.push('timeline')\n\t\t\t\t\t}))\n\t\t\t}\n\n\t\t\tif (jobs.length === 0) {\n\t\t\t\tthis.failedSources = []\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.loading = true\n\t\t\tawait Promise.all(jobs)\n\t\t\tif (seq !== this.loadSeq) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.relatedRows = rows\n\t\t\tthis.failedSources = failed\n\t\t\tthis.loading = false\n\t\t},\n\t},\n}\n</script>\n\n<style scoped>\n.cn-timeline-widget {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 8px;\n}\n\n.cn-timeline-widget__title {\n\tmargin: 0;\n\tfont-size: var(--font-size-large, 1.1em);\n}\n\n.cn-timeline-widget__loading {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 8px;\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-timeline-widget__empty {\n\tmargin: 0;\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-timeline-widget__list {\n\tmargin: 0;\n\tpadding: 0;\n\tlist-style: none;\n}\n\n.cn-timeline-widget__event {\n\tposition: relative;\n\tdisplay: flex;\n\tgap: 12px;\n\tpadding-block-end: 12px;\n}\n\n/* The line between dots: drawn from each dot down to the next event. */\n.cn-timeline-widget__event:not(:last-child)::before {\n\tcontent: '';\n\tposition: absolute;\n\tinset-block: 14px 0;\n\tinset-inline-start: 5px;\n\tborder-inline-start: 2px solid var(--color-border-dark);\n}\n\n.cn-timeline-widget__dot {\n\tflex: 0 0 auto;\n\twidth: 12px;\n\theight: 12px;\n\tmargin-block-start: 4px;\n\tborder-radius: 50%;\n\tbackground-color: var(--color-primary-element);\n}\n\n/* Upcoming: a hollow dot, plus the word \"Upcoming\" beside the date. */\n.cn-timeline-widget__event--upcoming .cn-timeline-widget__dot {\n\tbox-sizing: border-box;\n\tborder: 2px solid var(--color-primary-element);\n\tbackground-color: var(--color-main-background);\n}\n\n.cn-timeline-widget__body {\n\tmin-width: 0;\n}\n\n.cn-timeline-widget__when {\n\tfont-size: var(--font-size-small, 13px);\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-timeline-widget__badge {\n\tmargin-inline-start: 8px;\n\tfont-size: var(--font-size-small, 13px);\n\tfont-weight: bold;\n\tcolor: var(--color-main-text);\n}\n\n.cn-timeline-widget__label {\n\tmargin: 0;\n\tfont-weight: bold;\n}\n\n.cn-timeline-widget__detail {\n\tmargin: 0;\n\toverflow-wrap: anywhere;\n}\n</style>\n"],"names":["_createElementBlock","_toDisplayString","_createVNode","_createBlock","_openBlock","_Fragment","_renderList","_normalizeClass","_createElementVNode"],"mappings":";;;;;AAMM,EAAA,KAAA,EAAA,2BAAA;;;;AAI2B,EAAA,KAAA,EAAA,6BAAA;;;;AAW3B,EAAA,KAAA,EAAA,2BAAA;AAAA,EAAA,aAAA,EAAA,0BAAA;;;;AAIQ,EAAA,KAAK,EAAE,0BAAM;;;AASjB,MAAA,UAAA,GAAA,EAAA,KAAK,EAAC,0BAAe,GAAA;;;;AAInB,EAAA,KAAA,EAAA,2BAAA;;AAGH,MAAA,WAAA,GAAA,EAAA,KAAA,EAAA,2BAAA,GAAA;;;AAGA,EAAA,KAAA,EAAA,4BAAA;;;;;;;uBAvCNA;AAAO,IAAA,KAAK,EAAC,oBAAK;AAAA,IAAA,aAAA,EAAA,oBAAA;AAAA,IAAA,WAAA,EAAA,KAAA,CAAA,OAAA,GAAA,MAAA,GAAA,OAAA;;KACf,QAAA,CAAA,aAAA;sBAAJA,kBAEK,CAAA,IAAA,EAFL,UAEK,EAAAC,eAAA;;KAEM,KAAO,CAAA,OAAA,IAAK,QAAK,CAAA,MAAA,CAAC,MAAE,KAAA,CAAA;yCAGzB,iBAAA,EAAA;UAFLC,WAAI,CAAA,wBAAA,EAAA;AAAA,YAAA,IAAA,EAAA,EAAA;AAAA,YAAA,aAAA,EAAA,MAAA;;;;sBAIJF;AAEY,UAAA,CAAA,KAAA,CAAA,aAAA,CAAA,MAAA,GAAA,CAAA;4BAAZG,WAEa,CAAA,qBAAA,EAAA;;AAFD,gBAAA,IAAA,EAAA,SAAA;AAAA,gBAAA,aAAA,EAAA,0BAAA;;;;;;;;AAIT,UAAA,CAAA,QAAA,CAAA,MAAA,CAAA,MAAA,KAAA,CAAA;4BAAHH,kBAEI,CAAA,GAAA,EAFJ,UAEI,EAAAC,eAAA;AAEF,eAAAG,SAAA,EAAA,EAAAJ,kBAAA,CAwBG,MAxBH,UAwBG,EAAA;kCAvBHA,kBAsBI,CAAAK,QAAA,EAAA,IAAA,EAAAC,UAAA,CArBY,QAAM,CAAA,MAAA,EAAA,CAAf,KAAK,KAAA;uCADZN,kBAsBI,CAAA,IAAA,EAAA;oBApBH,GAAG,EAAE,KAAK,CAAC,EAAE;AACd,oBAAA,KAAK,EAACO,cAAA,CAAA,CAAA,2BAAoB,EACY,EAAA,qCAAA,EAAA,KAAA,CAAA,QAAA,EAAA,CAAA,CAAA;oBACrC,aAAW,EAAE,KAAK,CAAC,MAAM;AAC1B,oBAAA,aAAW,EAAC,0BAAyB;;8CACpCC,kBAA0D,CAAA,MAAA,EAAA;AAAtD,sBAAA,KAAM,EAAC,yBAAyB;AAAC,sBAAA,aAAW,EAAC,MAAM;;uCActD,iBAAA,EAAA;sBAZDA,kBAEO,CAAA,MAAA,EAAA;AAFD,wBAAA,KAAA,EAAA,0BAAA;AAAA,wBAAA,QAAA,EAAA,KAAA,CAAA,EAAA,CAAA,WAAA,EAAA;AACF,uBAAA,EAAAP,eAAA,CAAA,QAAA,CAAA,YAAY,CAAC,KAAK,CAAA,CAAA,EAAA,CAAA,oBAAA,UAAA,CAAA;AAEhB,sBAAA,CAAA,KAAA,CAAA,QAAA;wCAAND,kBAEO,CAAA,MAAA,EAFP,UAEO,EAAAC,eAAA,CADH,QAAa,CAAA,aAAA,CAAA,EAAA,CAAA,YAAA;;AAEjB,sBAAAO,kBAAA,CAEI,KAFJ,WAEI,EAAAP,eAAA,CADA,kBAAS,CAAC,KAAK,CAAC,KAAK,CAAA,CAAA,EAAA,CAAA,YAAA;AAEtB,sBAAA,CAAA,KAAA,CAAA,MAAA;AAAH,2BAAAG,SAAA,EAAA,EAAAJ,kBAAA,CAEE,GAFF,EAAA,WAEE,EADEC,eAAA,CAAA,KAAA,CAAA,MAAA,CAAA,EAAA,CAAA,YAAA;;;;;;;;;;;;"}
|
|
1
|
+
{"version":3,"file":"CnTimelineWidget.vue3.js","sources":["../../../../src/components/CnTimelineWidget/CnTimelineWidget.vue?vue&type=template&id=7ed4cc4c&lang.js"],"sourcesContent":["<!-- SPDX-License-Identifier: EUPL-1.2 -->\n<!-- SPDX-FileCopyrightText: 2026 Conduction B.V. <info@conduction.nl> -->\n<template>\n\t<CnTimelineManage v-if=\"manage\"\n\t\t:register=\"resolvedRegister\"\n\t\t:schema=\"resolvedSchema\"\n\t\t:objectId=\"resolvedObjectId\"\n\t\t:apiBase=\"apiBase\"\n\t\t:content=\"content\" />\n\t<section v-else\n\t\tclass=\"cn-timeline-widget\"\n\t\tdata-testid=\"cn-timeline-widget\"\n\t\t:aria-busy=\"loading ? 'true' : 'false'\">\n\t\t<h3 v-if=\"resolvedTitle\" class=\"cn-timeline-widget__title\">\n\t\t\t{{ resolvedTitle }}\n\t\t</h3>\n\n\t\t<div v-if=\"loading && events.length === 0\" class=\"cn-timeline-widget__loading\">\n\t\t\t<NcLoadingIcon :size=\"24\" aria-hidden=\"true\" />\n\t\t\t<span>{{ loadingLabel }}</span>\n\t\t</div>\n\n\t\t<template v-else>\n\t\t\t<!-- A failed read is not an empty history: say which part is missing. -->\n\t\t\t<NcNoteCard v-if=\"failedSources.length > 0\" type=\"warning\" data-testid=\"cn-timeline-widget-error\">\n\t\t\t\t{{ failedText }}\n\t\t\t</NcNoteCard>\n\n\t\t\t<p v-if=\"events.length === 0\" class=\"cn-timeline-widget__empty\" data-testid=\"cn-timeline-widget-empty\">\n\t\t\t\t{{ emptyLabel }}\n\t\t\t</p>\n\n\t\t\t<ol v-else class=\"cn-timeline-widget__list\">\n\t\t\t\t<li\n\t\t\t\t\tv-for=\"event in events\"\n\t\t\t\t\t:key=\"event.id\"\n\t\t\t\t\tclass=\"cn-timeline-widget__event\"\n\t\t\t\t\t:class=\"{ 'cn-timeline-widget__event--upcoming': event.upcoming }\"\n\t\t\t\t\t:data-source=\"event.source\"\n\t\t\t\t\tdata-testid=\"cn-timeline-widget-event\">\n\t\t\t\t\t<span class=\"cn-timeline-widget__dot\" aria-hidden=\"true\" />\n\t\t\t\t\t<div class=\"cn-timeline-widget__body\">\n\t\t\t\t\t\t<time class=\"cn-timeline-widget__when\" :datetime=\"event.at.toISOString()\">\n\t\t\t\t\t\t\t{{ formatMoment(event) }}\n\t\t\t\t\t\t</time>\n\t\t\t\t\t\t<span v-if=\"event.upcoming\" class=\"cn-timeline-widget__badge\">\n\t\t\t\t\t\t\t{{ upcomingLabel }}\n\t\t\t\t\t\t</span>\n\t\t\t\t\t\t<p class=\"cn-timeline-widget__label\">\n\t\t\t\t\t\t\t{{ translate(event.label) }}\n\t\t\t\t\t\t</p>\n\t\t\t\t\t\t<p v-if=\"event.detail\" class=\"cn-timeline-widget__detail\">\n\t\t\t\t\t\t\t{{ event.detail }}\n\t\t\t\t\t\t</p>\n\t\t\t\t\t</div>\n\t\t\t\t</li>\n\t\t\t</ol>\n\t\t</template>\n\t</section>\n</template>\n\n<script>\nimport { getLanguage, translate as t } from '@nextcloud/l10n'\nimport { NcLoadingIcon, NcNoteCard } from '@nextcloud/vue'\nimport CnTimelineManage from './CnTimelineManage.vue'\nimport { auditEvents, fieldEvents, listEvents, relatedEvents, sortEvents, timelineEntryEvents } from '../../utils/timelineEvents.js'\nimport { userLocale } from '../../utils/userLocale.js'\n\n/**\n * CnTimelineWidget — an object's dated events in time order (`timeline`\n * widget type for detail pages).\n *\n * Generalises dossiq's case timeline. It merges up to four sources, all\n * optional, into one list:\n *\n * - `fields`: the object's own date properties, `[{ field, label }]`. A\n * dotted path reaches metadata, such as `@self.created`.\n * - `related`: related objects, `[{ register?, schema, field, dateField?,\n * label, titleField? }]`. Rows of `schema` whose `field` holds this object's\n * id become events at their `dateField` (default `@self.created`).\n * - `auditTrail: true`: the object's audit trail, one event per change.\n * - `timeline: true`: OpenRegister's timeline of notes, calls and messages.\n *\n * Oldest first by default (`order: 'desc'` flips it). A moment after now is\n * marked upcoming, in words as well as style.\n *\n * `manage: true` swaps the read view for the manage view (CnTimelineManage)\n * over OpenRegister's timeline alone: kind chips, a visibility filter, pin,\n * follow-up, a note composer with standard text blocks, CSV export, and\n * `entryActions` that open a registry modal on an entry. The manage controls\n * are drawn only when the timeline read answers `canManage: true`.\n *\n * ```json\n * { \"type\": \"timeline\", \"content\": {\n * \"title\": \"Timeline\",\n * \"fields\": [\n * { \"field\": \"@self.created\", \"label\": \"Booking created\" },\n * { \"field\": \"depositClearedAt\", \"label\": \"Deposit cleared\" },\n * { \"field\": \"confirmationSentAt\", \"label\": \"Confirmation mail sent\" },\n * { \"field\": \"startsAt\", \"label\": \"Starts\" },\n * { \"field\": \"endsAt\", \"label\": \"Ends\" }\n * ] } }\n * ```\n *\n * The object comes from the detail page's context, like `audit-trail`:\n * explicit props win, then the injects, then `content`.\n *\n * @spec openspec/changes/timeline-widget/specs/timeline-widget/spec.md#requirement-a-timeline-widget-shows-an-objects-dated-events-in-order\n */\nexport default {\n\tname: 'CnTimelineWidget',\n\n\tcomponents: {\n\t\tCnTimelineManage,\n\t\tNcLoadingIcon,\n\t\tNcNoteCard,\n\t},\n\n\tinject: {\n\t\t/** Detail-page object context from CnDetailPage (a ref or a raw bag). */\n\t\tcnObjectContext: { default: null },\n\t\t/** Detail object context holder from CnPageRenderer (`{ value: { objectData, ... } }`). */\n\t\tcnDetailObjectContext: { default: null },\n\t\t/** Consumer translation function; labels are authored in English. */\n\t\tcnTranslate: { default: () => (key) => key },\n\t},\n\n\tprops: {\n\t\t/** Register slug; object context spread as props by CnWidgetGrid. */\n\t\tregister: { type: String, default: '' },\n\t\t/**\n\t\t * Schema slug, or the schema object the detail context supplies.\n\t\t *\n\t\t * @type {string|object}\n\t\t */\n\t\tschema: { type: [String, Object], default: '' },\n\t\t/** The object's id. */\n\t\tobjectId: { type: String, default: '' },\n\t\t/** The object itself, when the host already has it. */\n\t\tobject: { type: Object, default: null },\n\t\t/** Card title override. */\n\t\ttitle: { type: String, default: '' },\n\t\t/** Stored widget content: `{ title, fields, related, auditTrail, timeline, order, manage, entryActions, ... }`. */\n\t\tcontent: { type: Object, default: () => ({}) },\n\t\t/** OpenRegister API base. */\n\t\tapiBase: { type: String, default: '/apps/openregister/api' },\n\t},\n\n\tdata() {\n\t\treturn {\n\t\t\tloading: false,\n\t\t\trelatedRows: {},\n\t\t\tauditEntries: [],\n\t\t\ttimelineEntries: [],\n\t\t\tfailedSources: [],\n\t\t\tfetchedObject: null,\n\t\t\tloadSeq: 0,\n\t\t}\n\t},\n\n\tcomputed: {\n\t\tctx() {\n\t\t\tconst raw = this.cnObjectContext\n\t\t\tconst inj = raw && (raw.value !== undefined ? raw.value : raw)\n\t\t\tconst holder = this.cnDetailObjectContext && this.cnDetailObjectContext.value\n\t\t\treturn inj || holder || {}\n\t\t},\n\n\t\tresolvedObjectId() {\n\t\t\treturn this.objectId || this.ctx.objectId || this.content.objectId || ''\n\t\t},\n\n\t\tresolvedRegister() {\n\t\t\treturn this.register || this.ctx.register || this.content.register || ''\n\t\t},\n\n\t\tresolvedSchema() {\n\t\t\tconst s = this.schema || this.ctx.schema || this.content.schema || ''\n\t\t\treturn typeof s === 'string' ? s : (s && (s.slug || s.name || s.id)) || ''\n\t\t},\n\n\t\t/**\n\t\t * The object: explicit prop, then the page context, then a fetch of\n\t\t * our own when only the id is known.\n\t\t *\n\t\t * @return {object|null}\n\t\t */\n\t\tresolvedObject() {\n\t\t\treturn this.object || this.ctx.object || this.ctx.objectData || this.fetchedObject || null\n\t\t},\n\n\t\t/**\n\t\t * Whether the manage view renders instead of the read view.\n\t\t *\n\t\t * @return {boolean}\n\t\t */\n\t\tmanage() {\n\t\t\treturn this.content.manage === true\n\t\t},\n\n\t\tresolvedTitle() {\n\t\t\tconst raw = this.title || this.content.title || ''\n\t\t\treturn raw ? this.translate(raw) : ''\n\t\t},\n\n\t\tfieldsConfig() {\n\t\t\treturn Array.isArray(this.content.fields) ? this.content.fields : []\n\t\t},\n\n\t\trelatedConfig() {\n\t\t\treturn Array.isArray(this.content.related) ? this.content.related.filter((r) => r && r.schema && r.field) : []\n\t\t},\n\n\t\t/**\n\t\t * Every event from every source, in time order.\n\t\t *\n\t\t * @return {Array<object>}\n\t\t */\n\t\tevents() {\n\t\t\tconst now = new Date()\n\t\t\tconst all = [\n\t\t\t\t...fieldEvents(this.resolvedObject || {}, this.fieldsConfig, now),\n\t\t\t\t...listEvents(this.resolvedObject || {}, this.content.lists, now),\n\t\t\t\t...this.relatedConfig.flatMap((cfg, i) => relatedEvents(this.relatedRows[i] || [], cfg, now)),\n\t\t\t\t...auditEvents(this.auditEntries, this.describeAudit, now),\n\t\t\t\t...timelineEntryEvents(this.timelineEntries, t('nextcloud-vue', 'Note'), now),\n\t\t\t]\n\t\t\treturn sortEvents(all, this.content.order === 'desc' ? 'desc' : 'asc')\n\t\t},\n\n\t\t/**\n\t\t * A signature of what to fetch, so a change refetches once.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tloadKey() {\n\t\t\treturn JSON.stringify({\n\t\t\t\tid: this.resolvedObjectId,\n\t\t\t\tregister: this.resolvedRegister,\n\t\t\t\tschema: this.resolvedSchema,\n\t\t\t\trelated: this.relatedConfig,\n\t\t\t\taudit: this.content.auditTrail === true,\n\t\t\t\ttimeline: this.content.timeline === true,\n\t\t\t\tneedObject: this.fieldsConfig.length > 0 && !(this.object || this.ctx.object || this.ctx.objectData),\n\t\t\t})\n\t\t},\n\n\t\tfailedText() {\n\t\t\treturn t('nextcloud-vue', 'Part of the timeline could not load: {parts}.', {\n\t\t\t\tparts: this.failedSources.map((s) => this.sourceName(s)).join(', '),\n\t\t\t})\n\t\t},\n\n\t\tloadingLabel() {\n\t\t\treturn t('nextcloud-vue', 'Loading…')\n\t\t},\n\n\t\temptyLabel() {\n\t\t\treturn t('nextcloud-vue', 'Nothing has happened yet.')\n\t\t},\n\n\t\tupcomingLabel() {\n\t\t\treturn t('nextcloud-vue', 'Upcoming')\n\t\t},\n\t},\n\n\twatch: {\n\t\tloadKey: {\n\t\t\timmediate: true,\n\t\t\thandler() {\n\t\t\t\tthis.load()\n\t\t\t},\n\t\t},\n\t},\n\n\tmethods: {\n\t\ttranslate(text) {\n\t\t\treturn text ? this.cnTranslate(text) : ''\n\t\t},\n\n\t\tsourceName(source) {\n\t\t\tif (source === 'audit') {\n\t\t\t\treturn t('nextcloud-vue', 'changes')\n\t\t\t}\n\t\t\tif (source === 'timeline') {\n\t\t\t\treturn t('nextcloud-vue', 'notes and messages')\n\t\t\t}\n\t\t\tif (source === 'object') {\n\t\t\t\treturn t('nextcloud-vue', 'dates')\n\t\t\t}\n\t\t\treturn t('nextcloud-vue', 'related items')\n\t\t},\n\n\t\t/**\n\t\t * The label of an audit event, from its action and who did it.\n\t\t *\n\t\t * @param {string} action The audit action (create, update, delete).\n\t\t * @param {string} actor Who did it.\n\t\t * @return {string}\n\t\t */\n\t\tdescribeAudit(action, actor) {\n\t\t\tconst known = {\n\t\t\t\tcreate: t('nextcloud-vue', 'Created'),\n\t\t\t\tupdate: t('nextcloud-vue', 'Updated'),\n\t\t\t\tdelete: t('nextcloud-vue', 'Deleted'),\n\t\t\t}\n\t\t\tconst what = known[action] || action || t('nextcloud-vue', 'Changed')\n\t\t\treturn actor ? t('nextcloud-vue', '{action} by {actor}', { action: what, actor }) : what\n\t\t},\n\n\t\t/**\n\t\t * Show a moment in the reader's language: a date for a calendar day,\n\t\t * date and time otherwise.\n\t\t *\n\t\t * @param {object} event The event.\n\t\t * @return {string}\n\t\t */\n\t\tformatMoment(event) {\n\t\t\tconst locale = (typeof getLanguage === 'function' && getLanguage()) || undefined\n\t\t\tconst options = event.dateOnly\n\t\t\t\t? { dateStyle: 'medium' }\n\t\t\t\t: { dateStyle: 'medium', timeStyle: 'short' }\n\t\t\ttry {\n\t\t\t\treturn new Intl.DateTimeFormat(locale, options).format(event.at)\n\t\t\t} catch {\n\t\t\t\treturn event.at.toLocaleString(userLocale())\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Fetch every configured source. Each one fails on its own, so one\n\t\t * unreachable source never hides the others.\n\t\t *\n\t\t * @return {Promise<void>}\n\t\t * @spec openspec/changes/timeline-widget/specs/timeline-widget/spec.md#requirement-a-timeline-widget-shows-an-objects-dated-events-in-order\n\t\t */\n\t\tasync load() {\n\t\t\tconst id = this.resolvedObjectId\n\t\t\tconst register = this.resolvedRegister\n\t\t\tconst schema = this.resolvedSchema\n\t\t\tconst seq = ++this.loadSeq\n\t\t\tif (!id || !register || !schema || this.manage) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst [{ default: axios }, { generateUrl }] = await Promise.all([\n\t\t\t\timport('@nextcloud/axios'),\n\t\t\t\timport('@nextcloud/router'),\n\t\t\t])\n\t\t\tconst base = `${this.apiBase}/objects/${register}/${schema}/${id}`\n\t\t\tconst failed = []\n\t\t\tconst jobs = []\n\n\t\t\tif (this.fieldsConfig.length > 0 && !(this.object || this.ctx.object || this.ctx.objectData)) {\n\t\t\t\tjobs.push(axios.get(generateUrl(base))\n\t\t\t\t\t.then((r) => {\n\t\t\t\t\t\tthis.fetchedObject = (r && r.data) || null\n\t\t\t\t\t})\n\t\t\t\t\t.catch(() => failed.push('object')))\n\t\t\t}\n\n\t\t\tconst rows = {}\n\t\t\tthis.relatedConfig.forEach((cfg, i) => {\n\t\t\t\tconst url = generateUrl(`${this.apiBase}/objects/${cfg.register || register}/${cfg.schema}`)\n\t\t\t\tjobs.push(axios.get(url, { params: { [cfg.field]: id, _limit: cfg.limit || 50 } })\n\t\t\t\t\t.then((r) => {\n\t\t\t\t\t\tconst data = r && r.data\n\t\t\t\t\t\trows[i] = (data && (data.results || data)) || []\n\t\t\t\t\t})\n\t\t\t\t\t.catch(() => {\n\t\t\t\t\t\trows[i] = []\n\t\t\t\t\t\tif (!failed.includes('related')) {\n\t\t\t\t\t\t\tfailed.push('related')\n\t\t\t\t\t\t}\n\t\t\t\t\t}))\n\t\t\t})\n\n\t\t\tif (this.content.auditTrail === true) {\n\t\t\t\tjobs.push(axios.get(generateUrl(`${base}/audit-trails`), { params: { limit: this.content.auditLimit || 50 } })\n\t\t\t\t\t.then((r) => {\n\t\t\t\t\t\tconst data = r && r.data\n\t\t\t\t\t\tthis.auditEntries = (data && (data.results || data)) || []\n\t\t\t\t\t})\n\t\t\t\t\t.catch(() => {\n\t\t\t\t\t\tthis.auditEntries = []\n\t\t\t\t\t\tfailed.push('audit')\n\t\t\t\t\t}))\n\t\t\t}\n\n\t\t\tif (this.content.timeline === true) {\n\t\t\t\tjobs.push(axios.get(generateUrl(`${base}/timeline`))\n\t\t\t\t\t.then((r) => {\n\t\t\t\t\t\tconst data = r && r.data\n\t\t\t\t\t\tthis.timelineEntries = (data && (data.results || data)) || []\n\t\t\t\t\t})\n\t\t\t\t\t.catch(() => {\n\t\t\t\t\t\tthis.timelineEntries = []\n\t\t\t\t\t\tfailed.push('timeline')\n\t\t\t\t\t}))\n\t\t\t}\n\n\t\t\tif (jobs.length === 0) {\n\t\t\t\tthis.failedSources = []\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.loading = true\n\t\t\tawait Promise.all(jobs)\n\t\t\tif (seq !== this.loadSeq) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.relatedRows = rows\n\t\t\tthis.failedSources = failed\n\t\t\tthis.loading = false\n\t\t},\n\t},\n}\n</script>\n\n<style scoped>\n.cn-timeline-widget {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 8px;\n}\n\n.cn-timeline-widget__title {\n\tmargin: 0;\n\tfont-size: var(--font-size-large, 1.1em);\n}\n\n.cn-timeline-widget__loading {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 8px;\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-timeline-widget__empty {\n\tmargin: 0;\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-timeline-widget__list {\n\tmargin: 0;\n\tpadding: 0;\n\tlist-style: none;\n}\n\n.cn-timeline-widget__event {\n\tposition: relative;\n\tdisplay: flex;\n\tgap: 12px;\n\tpadding-block-end: 12px;\n}\n\n/* The line between dots: drawn from each dot down to the next event. */\n.cn-timeline-widget__event:not(:last-child)::before {\n\tcontent: '';\n\tposition: absolute;\n\tinset-block: 14px 0;\n\tinset-inline-start: 5px;\n\tborder-inline-start: 2px solid var(--color-border-dark);\n}\n\n.cn-timeline-widget__dot {\n\tflex: 0 0 auto;\n\twidth: 12px;\n\theight: 12px;\n\tmargin-block-start: 4px;\n\tborder-radius: 50%;\n\tbackground-color: var(--color-primary-element);\n}\n\n/* Upcoming: a hollow dot, plus the word \"Upcoming\" beside the date. */\n.cn-timeline-widget__event--upcoming .cn-timeline-widget__dot {\n\tbox-sizing: border-box;\n\tborder: 2px solid var(--color-primary-element);\n\tbackground-color: var(--color-main-background);\n}\n\n.cn-timeline-widget__body {\n\tmin-width: 0;\n}\n\n.cn-timeline-widget__when {\n\tfont-size: var(--font-size-small, 13px);\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-timeline-widget__badge {\n\tmargin-inline-start: 8px;\n\tfont-size: var(--font-size-small, 13px);\n\tfont-weight: bold;\n\tcolor: var(--color-main-text);\n}\n\n.cn-timeline-widget__label {\n\tmargin: 0;\n\tfont-weight: bold;\n}\n\n.cn-timeline-widget__detail {\n\tmargin: 0;\n\toverflow-wrap: anywhere;\n}\n</style>\n"],"names":["_createElementBlock","_toDisplayString","_createVNode","_createBlock","_openBlock","_Fragment","_renderList","_normalizeClass","_createElementVNode"],"mappings":";;;;;AAeM,EAAA,KAAA,EAAA,2BAAA;;;;AAI2B,EAAA,KAAA,EAAA,6BAAA;;;;AAW3B,EAAA,KAAA,EAAA,2BAAA;AAAA,EAAA,aAAA,EAAA,0BAAA;;;;AAIQ,EAAA,KAAK,EAAE,0BAAM;;;AASjB,MAAA,UAAA,GAAA,EAAA,KAAK,EAAC,0BAAe,GAAA;;;;AAInB,EAAA,KAAA,EAAA,2BAAA;;AAGH,MAAA,WAAA,GAAA,EAAA,KAAA,EAAA,2BAAA,GAAA;;;AAGA,EAAA,KAAA,EAAA,4BAAA;;;;;;;;UAhDgB,QAAA,CAAA,MAAA;+BAKF,CAAA,2BAAA,EAAA;;AAJpB,QAAA,QAAQ,EAAE,QAAgB,CAAA,gBAAA;AAC1B,QAAA,MAAM,EAAE,QAAQ,CAAA,cAAA;AAChB,QAAA,QAAQ,EAAE,QAAS,CAAA,gBAAA;AACnB,QAAA,OAAO,EAAE,MAAG,CAAA,OAAA;AACZ,QAAA,OAAO,EAAE,MAAO,CAAA,OAAA;;oBACjBA;;AACA,QAAA,KAAK,EAAC,oBAAoB;AAC1B,QAAA,aAAW,EAAC,oBAAoB;AAC/B,QAAA,WAAS,EAAE,KAAO,CAAA,OAAA,GAAA,MAAA,GAAA,OAAA;;SACf,QAAA,CAAA,aAAA;0BAAJA,kBAEK,CAAA,IAAA,EAFL,UAEK,EAAAC,eAAA;;SAEM,KAAO,CAAA,OAAA,IAAK,QAAK,CAAA,MAAA,CAAC,MAAE,KAAA,CAAA;6CAGzB,iBAAA,EAAA;cAFLC,WAAI,CAAA,wBAAA,EAAA;AAAA,gBAAA,IAAA,EAAA,EAAA;AAAA,gBAAA,aAAA,EAAA,MAAA;;;;0BAIJF;AAEY,cAAA,CAAA,KAAA,CAAA,aAAA,CAAA,MAAA,GAAA,CAAA;gCAAZG,WAEa,CAAA,qBAAA,EAAA;;AAFD,oBAAA,IAAA,EAAA,SAAA;AAAA,oBAAA,aAAA,EAAA,0BAAA;;;;;;;;AAIT,cAAA,CAAA,QAAA,CAAA,MAAA,CAAA,MAAA,KAAA,CAAA;gCAAHH,kBAEI,CAAA,GAAA,EAFJ,UAEI,EAAAC,eAAA;AAEF,mBAAAG,SAAA,EAAA,EAAAJ,kBAAA,CAwBG,MAxBH,UAwBG,EAAA;sCAvBHA,kBAsBI,CAAAK,QAAA,EAAA,IAAA,EAAAC,UAAA,CArBY,QAAM,CAAA,MAAA,EAAA,CAAf,KAAK,KAAA;2CADZN,kBAsBI,CAAA,IAAA,EAAA;wBApBH,GAAG,EAAE,KAAK,CAAC,EAAE;AACd,wBAAA,KAAK,EAACO,cAAA,CAAA,CAAA,2BAAoB,EACY,EAAA,qCAAA,EAAA,KAAA,CAAA,QAAA,EAAA,CAAA,CAAA;wBACrC,aAAW,EAAE,KAAK,CAAC,MAAM;AAC1B,wBAAA,aAAW,EAAC,0BAAyB;;kDACpCC,kBAA0D,CAAA,MAAA,EAAA;AAAtD,0BAAA,KAAM,EAAC,yBAAyB;AAAC,0BAAA,aAAW,EAAC,MAAM;;2CActD,iBAAA,EAAA;0BAZDA,kBAEO,CAAA,MAAA,EAAA;AAFD,4BAAA,KAAA,EAAA,0BAAA;AAAA,4BAAA,QAAA,EAAA,KAAA,CAAA,EAAA,CAAA,WAAA,EAAA;AACF,2BAAA,EAAAP,eAAA,CAAA,QAAA,CAAA,YAAY,CAAC,KAAK,CAAA,CAAA,EAAA,CAAA,oBAAA,UAAA,CAAA;AAEhB,0BAAA,CAAA,KAAA,CAAA,QAAA;4CAAND,kBAEO,CAAA,MAAA,EAFP,UAEO,EAAAC,eAAA,CADH,QAAa,CAAA,aAAA,CAAA,EAAA,CAAA,YAAA;;AAEjB,0BAAAO,kBAAA,CAEI,KAFJ,WAEI,EAAAP,eAAA,CADA,kBAAS,CAAC,KAAK,CAAC,KAAK,CAAA,CAAA,EAAA,CAAA,YAAA;AAEtB,0BAAA,CAAA,KAAA,CAAA,MAAA;AAAH,+BAAAG,SAAA,EAAA,EAAAJ,kBAAA,CAEE,GAFF,EAAA,WAEE,EADEC,eAAA,CAAA,KAAA,CAAA,MAAA,CAAA,EAAA,CAAA,YAAA;;;;;;;;;;;;"}
|
|
@@ -10,6 +10,7 @@ import __sfc_main$b from '../CnNoticeWidget/CnNoticeWidget.vue.js';
|
|
|
10
10
|
import __sfc_main$6 from '../CnObjectDataWidget/CnObjectDataWidget.vue.js';
|
|
11
11
|
import __sfc_main$3 from '../CnObjectGeoWidget/CnObjectGeoWidget.vue.js';
|
|
12
12
|
import __sfc_main$7 from '../CnObjectMetadataWidget/CnObjectMetadataWidget.vue.js';
|
|
13
|
+
import __sfc_main$k from '../CnObjectTranslationsWidget/CnObjectTranslationsWidget.vue.js';
|
|
13
14
|
import __sfc_main$8 from '../CnRelatedObjectsWidget/CnRelatedObjectsWidget.vue.js';
|
|
14
15
|
import __sfc_main$i from '../CnSavedViewAlertWidget/CnSavedViewAlertWidget.vue.js';
|
|
15
16
|
import __sfc_main$g from '../CnTextWidget/CnTextWidget.vue.js';
|
|
@@ -75,6 +76,10 @@ import __sfc_main from '../CnWidgetObjectTable/CnWidgetObjectTable.vue.js';
|
|
|
75
76
|
* data — the intended remedy for a deep menu group collapsed into one
|
|
76
77
|
* top-level entry via `menu-layout.json` relocations.
|
|
77
78
|
*
|
|
79
|
+
* The `object-translations` key places CnObjectTranslationsWidget: the
|
|
80
|
+
* object's translatable properties per register language, with completeness
|
|
81
|
+
* chips and one save (register / schema / objectId via the detail-context merge).
|
|
82
|
+
*
|
|
78
83
|
* @type {Record<string, import('vue').Component>}
|
|
79
84
|
*/
|
|
80
85
|
const BUILT_IN_WIDGETS = {
|
|
@@ -98,6 +103,7 @@ const BUILT_IN_WIDGETS = {
|
|
|
98
103
|
divider: __sfc_main$h,
|
|
99
104
|
'saved-view-alert': __sfc_main$i,
|
|
100
105
|
exports: __sfc_main$j,
|
|
106
|
+
'object-translations': __sfc_main$k,
|
|
101
107
|
};
|
|
102
108
|
|
|
103
109
|
export { BUILT_IN_WIDGETS };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"builtInWidgets.js","sources":["../../../../src/components/CnWidgetGrid/builtInWidgets.js"],"sourcesContent":["/**\n * SPDX-FileCopyrightText: 2024 Conduction B.V.\n * SPDX-License-Identifier: EUPL-1.2\n *\n * builtInWidgets — internal registry of the library's built-in v2 widget components.\n *\n * Keys are the `widgetKey` values used in v2 manifests.\n * Values are the Vue component definitions.\n *\n * CnWidgetGrid resolves widget keys first against this registry, then against\n * the consumer-supplied `cnRegistry` inject. A consumer can override a built-in\n * by registering a custom component with the same key in `cnRegistry`.\n *\n * Spec: REQ-MVR-005 (manifest-v2-renderer) — widget key resolution\n */\n\nimport CnAuditTrailWidget from '../CnAuditTrailWidget/CnAuditTrailWidget.vue'\nimport CnBannerWidget from '../CnBannerWidget/CnBannerWidget.vue'\nimport CnDecisionListWidget from '../CnDecisionListWidget/CnDecisionListWidget.vue'\nimport CnDividerWidget from '../CnDividerWidget/CnDividerWidget.vue'\nimport CnExportsWidget from '../CnExportsWidget/CnExportsWidget.vue'\nimport CnHeaderWidget from '../CnHeaderWidget/CnHeaderWidget.vue'\nimport CnIntegrationWidget from '../CnIntegrationWidget/CnIntegrationWidget.vue'\nimport CnNavCardGrid from '../CnNavCardGrid/CnNavCardGrid.vue'\nimport CnNoticeWidget from '../CnNoticeWidget/CnNoticeWidget.vue'\nimport CnObjectDataWidget from '../CnObjectDataWidget/CnObjectDataWidget.vue'\nimport CnObjectGeoWidget from '../CnObjectGeoWidget/CnObjectGeoWidget.vue'\nimport CnObjectMetadataWidget from '../CnObjectMetadataWidget/CnObjectMetadataWidget.vue'\nimport CnRelatedObjectsWidget from '../CnRelatedObjectsWidget/CnRelatedObjectsWidget.vue'\nimport CnSavedViewAlertWidget from '../CnSavedViewAlertWidget/CnSavedViewAlertWidget.vue'\nimport CnTextWidget from '../CnTextWidget/CnTextWidget.vue'\nimport CnTimelineWidget from '../CnTimelineWidget/CnTimelineWidget.vue'\nimport CnWidgetCardGrid from '../CnWidgetCardGrid/CnWidgetCardGrid.vue'\nimport CnWidgetFormRenderer from '../CnWidgetFormRenderer/CnWidgetFormRenderer.vue'\nimport CnWidgetMapViewer from '../CnWidgetMapViewer/CnWidgetMapViewer.vue'\nimport CnWidgetObjectTable from '../CnWidgetObjectTable/CnWidgetObjectTable.vue'\n\n/**\n * Built-in widget registry.\n *\n * The `data` and `metadata` keys are the canonical object-detail widgets:\n * a manifest `type:\"detail\"` page that places `widgetKey:\"data\"` /\n * `widgetKey:\"metadata\"` gets the object's editable property grid /\n * read-only `@self` metadata respectively. Both need the loaded object —\n * `CnPageRenderer` loads it for the detail page and `CnWidgetGrid` merges\n * `{ objectData, schema, objectType, objectId, register, store }` into each\n * widget's props (see CnWidgetGrid.resolvedWidgets), so the manifest entry\n * needs no per-widget `props`.\n *\n * The `integration` key places an OpenRegister integration leaf\n * (`CnIntegrationWidget`) on the page — e.g. Integriq's `sync-contract`\n * (\"Synced from\"). Pick the leaf with `props.only: \"<integrationId>\"`; the\n * object's `register` / `objectId` arrive via the detail-context merge, and\n * the manifest should set `props.schema` to the schema slug (the merged\n * context `schema` is the schema *object*, so an explicit slug prop wins).\n *\n * The `banner` key places a declarative notice banner (CnBannerWidget):\n * `props { variant, text, visibleWhen?, route? }` — see the component for\n * the visibleWhen predicate shape.\n *\n * The `audit-trail` key places the object change-log card\n * (CnAuditTrailWidget) — a detail-page widget whose register / schema /\n * objectId arrive via the detail-context merge (or explicit `props`).\n *\n * The `header` / `text` / `divider` keys reuse the dashboard catalog's\n * content-only presentation widgets on v2 pages: each takes a single\n * `props.content` object with the same shape their dashboard `content`\n * blob uses (see the components' docblocks).\n *\n * The `nav-card-grid` key (ADR-044 §4 cards-collapse) places CnNavCardGrid:\n * a grid of arbitrary navigation-link cards from `props.entries` (the\n * navCardEntry shape). Unlike `card-grid` (CnWidgetCardGrid, which renders\n * OpenRegister objects as CnObjectCard), `nav-card-grid` renders links, not\n * data — the intended remedy for a deep menu group collapsed into one\n * top-level entry via `menu-layout.json` relocations.\n *\n * @type {Record<string, import('vue').Component>}\n */\nexport const BUILT_IN_WIDGETS = {\n\t'object-table': CnWidgetObjectTable,\n\t'form-renderer': CnWidgetFormRenderer,\n\t'map-viewer': CnWidgetMapViewer,\n\t'object-geo': CnObjectGeoWidget,\n\t'card-grid': CnWidgetCardGrid,\n\t'nav-card-grid': CnNavCardGrid,\n\tdata: CnObjectDataWidget,\n\tmetadata: CnObjectMetadataWidget,\n\trelated: CnRelatedObjectsWidget,\n\tintegration: CnIntegrationWidget,\n\tbanner: CnBannerWidget,\n\tnotice: CnNoticeWidget,\n\t'decision-list': CnDecisionListWidget,\n\t'audit-trail': CnAuditTrailWidget,\n\ttimeline: CnTimelineWidget,\n\theader: CnHeaderWidget,\n\ttext: CnTextWidget,\n\tdivider: CnDividerWidget,\n\t'saved-view-alert': CnSavedViewAlertWidget,\n\texports: CnExportsWidget,\n}\n"],"names":["CnWidgetObjectTable","CnWidgetFormRenderer","CnWidgetMapViewer","CnObjectGeoWidget","CnWidgetCardGrid","CnNavCardGrid","CnObjectDataWidget","CnObjectMetadataWidget","CnRelatedObjectsWidget","CnIntegrationWidget","CnBannerWidget","CnNoticeWidget","CnDecisionListWidget","CnAuditTrailWidget","CnTimelineWidget","CnHeaderWidget","CnTextWidget","CnDividerWidget","CnSavedViewAlertWidget","CnExportsWidget"],"mappings":"
|
|
1
|
+
{"version":3,"file":"builtInWidgets.js","sources":["../../../../src/components/CnWidgetGrid/builtInWidgets.js"],"sourcesContent":["/**\n * SPDX-FileCopyrightText: 2024 Conduction B.V.\n * SPDX-License-Identifier: EUPL-1.2\n *\n * builtInWidgets — internal registry of the library's built-in v2 widget components.\n *\n * Keys are the `widgetKey` values used in v2 manifests.\n * Values are the Vue component definitions.\n *\n * CnWidgetGrid resolves widget keys first against this registry, then against\n * the consumer-supplied `cnRegistry` inject. A consumer can override a built-in\n * by registering a custom component with the same key in `cnRegistry`.\n *\n * Spec: REQ-MVR-005 (manifest-v2-renderer) — widget key resolution\n */\n\nimport CnAuditTrailWidget from '../CnAuditTrailWidget/CnAuditTrailWidget.vue'\nimport CnBannerWidget from '../CnBannerWidget/CnBannerWidget.vue'\nimport CnDecisionListWidget from '../CnDecisionListWidget/CnDecisionListWidget.vue'\nimport CnDividerWidget from '../CnDividerWidget/CnDividerWidget.vue'\nimport CnExportsWidget from '../CnExportsWidget/CnExportsWidget.vue'\nimport CnHeaderWidget from '../CnHeaderWidget/CnHeaderWidget.vue'\nimport CnIntegrationWidget from '../CnIntegrationWidget/CnIntegrationWidget.vue'\nimport CnNavCardGrid from '../CnNavCardGrid/CnNavCardGrid.vue'\nimport CnNoticeWidget from '../CnNoticeWidget/CnNoticeWidget.vue'\nimport CnObjectDataWidget from '../CnObjectDataWidget/CnObjectDataWidget.vue'\nimport CnObjectGeoWidget from '../CnObjectGeoWidget/CnObjectGeoWidget.vue'\nimport CnObjectMetadataWidget from '../CnObjectMetadataWidget/CnObjectMetadataWidget.vue'\nimport CnObjectTranslationsWidget from '../CnObjectTranslationsWidget/CnObjectTranslationsWidget.vue'\nimport CnRelatedObjectsWidget from '../CnRelatedObjectsWidget/CnRelatedObjectsWidget.vue'\nimport CnSavedViewAlertWidget from '../CnSavedViewAlertWidget/CnSavedViewAlertWidget.vue'\nimport CnTextWidget from '../CnTextWidget/CnTextWidget.vue'\nimport CnTimelineWidget from '../CnTimelineWidget/CnTimelineWidget.vue'\nimport CnWidgetCardGrid from '../CnWidgetCardGrid/CnWidgetCardGrid.vue'\nimport CnWidgetFormRenderer from '../CnWidgetFormRenderer/CnWidgetFormRenderer.vue'\nimport CnWidgetMapViewer from '../CnWidgetMapViewer/CnWidgetMapViewer.vue'\nimport CnWidgetObjectTable from '../CnWidgetObjectTable/CnWidgetObjectTable.vue'\n\n/**\n * Built-in widget registry.\n *\n * The `data` and `metadata` keys are the canonical object-detail widgets:\n * a manifest `type:\"detail\"` page that places `widgetKey:\"data\"` /\n * `widgetKey:\"metadata\"` gets the object's editable property grid /\n * read-only `@self` metadata respectively. Both need the loaded object —\n * `CnPageRenderer` loads it for the detail page and `CnWidgetGrid` merges\n * `{ objectData, schema, objectType, objectId, register, store }` into each\n * widget's props (see CnWidgetGrid.resolvedWidgets), so the manifest entry\n * needs no per-widget `props`.\n *\n * The `integration` key places an OpenRegister integration leaf\n * (`CnIntegrationWidget`) on the page — e.g. Integriq's `sync-contract`\n * (\"Synced from\"). Pick the leaf with `props.only: \"<integrationId>\"`; the\n * object's `register` / `objectId` arrive via the detail-context merge, and\n * the manifest should set `props.schema` to the schema slug (the merged\n * context `schema` is the schema *object*, so an explicit slug prop wins).\n *\n * The `banner` key places a declarative notice banner (CnBannerWidget):\n * `props { variant, text, visibleWhen?, route? }` — see the component for\n * the visibleWhen predicate shape.\n *\n * The `audit-trail` key places the object change-log card\n * (CnAuditTrailWidget) — a detail-page widget whose register / schema /\n * objectId arrive via the detail-context merge (or explicit `props`).\n *\n * The `header` / `text` / `divider` keys reuse the dashboard catalog's\n * content-only presentation widgets on v2 pages: each takes a single\n * `props.content` object with the same shape their dashboard `content`\n * blob uses (see the components' docblocks).\n *\n * The `nav-card-grid` key (ADR-044 §4 cards-collapse) places CnNavCardGrid:\n * a grid of arbitrary navigation-link cards from `props.entries` (the\n * navCardEntry shape). Unlike `card-grid` (CnWidgetCardGrid, which renders\n * OpenRegister objects as CnObjectCard), `nav-card-grid` renders links, not\n * data — the intended remedy for a deep menu group collapsed into one\n * top-level entry via `menu-layout.json` relocations.\n *\n * The `object-translations` key places CnObjectTranslationsWidget: the\n * object's translatable properties per register language, with completeness\n * chips and one save (register / schema / objectId via the detail-context merge).\n *\n * @type {Record<string, import('vue').Component>}\n */\nexport const BUILT_IN_WIDGETS = {\n\t'object-table': CnWidgetObjectTable,\n\t'form-renderer': CnWidgetFormRenderer,\n\t'map-viewer': CnWidgetMapViewer,\n\t'object-geo': CnObjectGeoWidget,\n\t'card-grid': CnWidgetCardGrid,\n\t'nav-card-grid': CnNavCardGrid,\n\tdata: CnObjectDataWidget,\n\tmetadata: CnObjectMetadataWidget,\n\trelated: CnRelatedObjectsWidget,\n\tintegration: CnIntegrationWidget,\n\tbanner: CnBannerWidget,\n\tnotice: CnNoticeWidget,\n\t'decision-list': CnDecisionListWidget,\n\t'audit-trail': CnAuditTrailWidget,\n\ttimeline: CnTimelineWidget,\n\theader: CnHeaderWidget,\n\ttext: CnTextWidget,\n\tdivider: CnDividerWidget,\n\t'saved-view-alert': CnSavedViewAlertWidget,\n\texports: CnExportsWidget,\n\t'object-translations': CnObjectTranslationsWidget,\n}\n"],"names":["CnWidgetObjectTable","CnWidgetFormRenderer","CnWidgetMapViewer","CnObjectGeoWidget","CnWidgetCardGrid","CnNavCardGrid","CnObjectDataWidget","CnObjectMetadataWidget","CnRelatedObjectsWidget","CnIntegrationWidget","CnBannerWidget","CnNoticeWidget","CnDecisionListWidget","CnAuditTrailWidget","CnTimelineWidget","CnHeaderWidget","CnTextWidget","CnDividerWidget","CnSavedViewAlertWidget","CnExportsWidget","CnObjectTranslationsWidget"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAsBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACY,MAAC,gBAAgB,GAAG;AAChC,CAAC,cAAc,EAAEA,UAAmB;AACpC,CAAC,eAAe,EAAEC,YAAoB;AACtC,CAAC,YAAY,EAAEC,YAAiB;AAChC,CAAC,YAAY,EAAEC,YAAiB;AAChC,CAAC,WAAW,EAAEC,YAAgB;AAC9B,CAAC,eAAe,EAAEC,YAAa;AAC/B,CAAC,IAAI,EAAEC,YAAkB;AACzB,CAAC,QAAQ,EAAEC,YAAsB;AACjC,CAAC,OAAO,EAAEC,YAAsB;AAChC,CAAC,WAAW,EAAEC,YAAmB;AACjC,CAAC,MAAM,EAAEC,YAAc;AACvB,CAAC,MAAM,EAAEC,YAAc;AACvB,CAAC,eAAe,EAAEC,YAAoB;AACtC,CAAC,aAAa,EAAEC,YAAkB;AAClC,CAAC,QAAQ,EAAEC,YAAgB;AAC3B,CAAC,MAAM,EAAEC,YAAc;AACvB,CAAC,IAAI,EAAEC,YAAY;AACnB,CAAC,OAAO,EAAEC,YAAe;AACzB,CAAC,kBAAkB,EAAEC,YAAsB;AAC3C,CAAC,OAAO,EAAEC,YAAe;AACzB,CAAC,qBAAqB,EAAEC,YAA0B;AAClD;;;;"}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import __sfc_main$
|
|
1
|
+
import __sfc_main$m from '../CnAiCompanion/CnAiChatWidget.vue.js';
|
|
2
2
|
import __sfc_main from '../CnChartWidget/CnChartWidget.vue.js';
|
|
3
3
|
import __sfc_main$1 from '../CnChartWidgetForm/CnChartWidgetForm.vue.js';
|
|
4
|
-
import __sfc_main$
|
|
4
|
+
import __sfc_main$p from '../CnConversationThread/CnConversationWidget.vue.js';
|
|
5
5
|
import __sfc_main$e from '../CnCountdownWidget/CnCountdownWidget.vue.js';
|
|
6
6
|
import __sfc_main$f from '../CnCountdownWidgetForm/CnCountdownWidgetForm.vue.js';
|
|
7
|
-
import __sfc_main$
|
|
8
|
-
import __sfc_main$
|
|
9
|
-
import __sfc_main$
|
|
7
|
+
import __sfc_main$l from '../CnDocumentReviewList/CnDocumentReviewWidget.vue.js';
|
|
8
|
+
import __sfc_main$o from '../CnEventsCard/CnEventsCard.vue.js';
|
|
9
|
+
import __sfc_main$n from '../CnMacrosWidget/CnMacrosWidget.vue.js';
|
|
10
10
|
import __sfc_main$c from '../CnMapWidget/CnMapWidget.vue.js';
|
|
11
11
|
import __sfc_main$d from '../CnMapWidgetForm/CnMapWidgetForm.vue.js';
|
|
12
12
|
import __sfc_main$8 from '../CnMarkdownWidget/CnMarkdownWidget.vue.js';
|
|
@@ -14,24 +14,25 @@ import __sfc_main$9 from '../CnMarkdownWidgetForm/CnMarkdownWidgetForm.vue.js';
|
|
|
14
14
|
import __sfc_main$g from '../CnNextStepCard/CnNextStepWidget.vue.js';
|
|
15
15
|
import __sfc_main$4 from '../CnObjectListWidget/CnObjectListWidget.vue.js';
|
|
16
16
|
import __sfc_main$5 from '../CnObjectListWidgetForm/CnObjectListWidgetForm.vue.js';
|
|
17
|
-
import __sfc_main$
|
|
17
|
+
import __sfc_main$j from '../CnPlanWidget/CnPlanWidget.vue.js';
|
|
18
18
|
import __sfc_main$a from '../CnRelatedObjectsWidget/CnRelatedObjectsWidget.vue.js';
|
|
19
19
|
import __sfc_main$b from '../CnRelatedObjectsWidgetForm/CnRelatedObjectsWidgetForm.vue.js';
|
|
20
20
|
import __sfc_main$h from '../CnRetentionWidget/CnRetentionWidget.vue.js';
|
|
21
21
|
import __sfc_main$6 from '../CnSavedViewWidget/CnSavedViewWidget.vue.js';
|
|
22
22
|
import __sfc_main$7 from '../CnSavedViewWidgetForm/CnSavedViewWidgetForm.vue.js';
|
|
23
|
-
import __sfc_main$
|
|
24
|
-
import __sfc_main$w from '../
|
|
25
|
-
import __sfc_main$
|
|
26
|
-
import __sfc_main$q from '../
|
|
23
|
+
import __sfc_main$i from '../CnSchemaRulesWidget/CnSchemaRulesWidget.vue.js';
|
|
24
|
+
import __sfc_main$w from '../CnStackedBarWidget/CnStackedBarWidget.vue.js';
|
|
25
|
+
import __sfc_main$x from '../CnStackedBarWidgetForm/CnStackedBarWidgetForm.vue.js';
|
|
26
|
+
import __sfc_main$q from '../CnStagesWidget/CnStagesWidget.vue.js';
|
|
27
|
+
import __sfc_main$r from '../CnStagesWidgetForm/CnStagesWidgetForm.vue.js';
|
|
27
28
|
import __sfc_main$2 from '../CnStatsBlockWidget/CnStatsBlockWidget.vue.js';
|
|
28
29
|
import __sfc_main$3 from '../CnStatsBlockWidgetForm/CnStatsBlockWidgetForm.vue.js';
|
|
29
|
-
import __sfc_main$
|
|
30
|
-
import __sfc_main$
|
|
31
|
-
import __sfc_main$
|
|
32
|
-
import __sfc_main$
|
|
33
|
-
import __sfc_main$
|
|
34
|
-
import __sfc_main$
|
|
30
|
+
import __sfc_main$s from '../CnTabsWidget/CnTabsWidget.vue.js';
|
|
31
|
+
import __sfc_main$t from '../CnTabsWidgetForm/CnTabsWidgetForm.vue.js';
|
|
32
|
+
import __sfc_main$y from '../CnTeamWorkloadWidget/CnTeamWorkloadWidget.vue.js';
|
|
33
|
+
import __sfc_main$u from '../CnWeekStripWidget/CnWeekStripWidget.vue.js';
|
|
34
|
+
import __sfc_main$v from '../CnWeekStripWidgetForm/CnWeekStripWidgetForm.vue.js';
|
|
35
|
+
import __sfc_main$k from '../CnWorkQueue/CnWorkQueue.vue.js';
|
|
35
36
|
import { registerDashboardWidget } from './dashboardWidgetRegistry.js';
|
|
36
37
|
import '../CnLabelWidget/index.js';
|
|
37
38
|
import '../CnTextWidget/index.js';
|
|
@@ -304,9 +305,18 @@ registerDashboardWidget('retention', {
|
|
|
304
305
|
ownsTitle: true,
|
|
305
306
|
});
|
|
306
307
|
|
|
307
|
-
registerDashboardWidget('
|
|
308
|
+
registerDashboardWidget('schema-rules', {
|
|
308
309
|
renderer: __sfc_main$i,
|
|
309
310
|
form: null,
|
|
311
|
+
defaultContent: { register: '', schema: '', objectId: '' },
|
|
312
|
+
displayName: 'Schema rules',
|
|
313
|
+
icon: 'ScaleBalance',
|
|
314
|
+
surfaces: ['detail-page'],
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
registerDashboardWidget('plan', {
|
|
318
|
+
renderer: __sfc_main$j,
|
|
319
|
+
form: null,
|
|
310
320
|
defaultContent: { emptyText: '' },
|
|
311
321
|
displayName: 'Plan',
|
|
312
322
|
icon: 'FormatListChecks',
|
|
@@ -315,7 +325,7 @@ registerDashboardWidget('plan', {
|
|
|
315
325
|
});
|
|
316
326
|
|
|
317
327
|
registerDashboardWidget('work-queue', {
|
|
318
|
-
renderer: __sfc_main$
|
|
328
|
+
renderer: __sfc_main$k,
|
|
319
329
|
form: null,
|
|
320
330
|
defaultContent: { source: null },
|
|
321
331
|
displayName: 'Work queue',
|
|
@@ -323,7 +333,7 @@ registerDashboardWidget('work-queue', {
|
|
|
323
333
|
});
|
|
324
334
|
|
|
325
335
|
registerDashboardWidget('document-review', {
|
|
326
|
-
renderer: __sfc_main$
|
|
336
|
+
renderer: __sfc_main$l,
|
|
327
337
|
form: null,
|
|
328
338
|
defaultContent: { field: 'documents', statusField: 'reviewStatus', statuses: [] },
|
|
329
339
|
displayName: 'Document review',
|
|
@@ -335,7 +345,7 @@ registerDashboardWidget('document-review', {
|
|
|
335
345
|
// The AI Chat Companion embedded in the page: the assistant as a tab or card
|
|
336
346
|
// rather than the launcher's floating window (DqZaakAssistent).
|
|
337
347
|
registerDashboardWidget('ai-chat', {
|
|
338
|
-
renderer: __sfc_main$
|
|
348
|
+
renderer: __sfc_main$m,
|
|
339
349
|
form: null,
|
|
340
350
|
defaultContent: { chatAppId: '' },
|
|
341
351
|
displayName: 'Assistant',
|
|
@@ -347,7 +357,7 @@ registerDashboardWidget('ai-chat', {
|
|
|
347
357
|
// The macros the record's schema declares, each run by a button
|
|
348
358
|
// (DqZaakAssistent "Macro's").
|
|
349
359
|
registerDashboardWidget('macros', {
|
|
350
|
-
renderer: __sfc_main$
|
|
360
|
+
renderer: __sfc_main$n,
|
|
351
361
|
form: null,
|
|
352
362
|
defaultContent: { description: '', emptyText: '' },
|
|
353
363
|
displayName: 'Macros',
|
|
@@ -358,7 +368,7 @@ registerDashboardWidget('macros', {
|
|
|
358
368
|
// The appointments booked on a record that is not an object (a flow task),
|
|
359
369
|
// read from a source or an endpoint.
|
|
360
370
|
registerDashboardWidget('events', {
|
|
361
|
-
renderer: __sfc_main$
|
|
371
|
+
renderer: __sfc_main$o,
|
|
362
372
|
form: null,
|
|
363
373
|
defaultContent: { source: null, endpoint: '', emptyText: '' },
|
|
364
374
|
displayName: 'Appointments',
|
|
@@ -367,7 +377,7 @@ registerDashboardWidget('events', {
|
|
|
367
377
|
});
|
|
368
378
|
|
|
369
379
|
registerDashboardWidget('conversation', {
|
|
370
|
-
renderer: __sfc_main$
|
|
380
|
+
renderer: __sfc_main$p,
|
|
371
381
|
form: null,
|
|
372
382
|
defaultContent: { field: 'messages', endpoint: '' },
|
|
373
383
|
displayName: 'Conversation',
|
|
@@ -379,8 +389,8 @@ registerDashboardWidget('conversation', {
|
|
|
379
389
|
// The record's stages, where clicking a stage moves the record there.
|
|
380
390
|
// Registered inline for the same tree-shaking reason as `map` above.
|
|
381
391
|
registerDashboardWidget('stages', {
|
|
382
|
-
renderer: __sfc_main$
|
|
383
|
-
form: __sfc_main$
|
|
392
|
+
renderer: __sfc_main$q,
|
|
393
|
+
form: __sfc_main$r,
|
|
384
394
|
defaultContent: {
|
|
385
395
|
currentField: 'status',
|
|
386
396
|
orientation: 'horizontal',
|
|
@@ -400,8 +410,8 @@ registerDashboardWidget('stages', {
|
|
|
400
410
|
});
|
|
401
411
|
|
|
402
412
|
registerDashboardWidget('tabs', {
|
|
403
|
-
renderer: __sfc_main$
|
|
404
|
-
form: __sfc_main$
|
|
413
|
+
renderer: __sfc_main$s,
|
|
414
|
+
form: __sfc_main$t,
|
|
405
415
|
defaultContent: {
|
|
406
416
|
tabs: [],
|
|
407
417
|
ariaLabel: '',
|
|
@@ -420,8 +430,8 @@ registerDashboardWidget('tabs', {
|
|
|
420
430
|
// The current week as day columns, with the dated items under each day.
|
|
421
431
|
// Registered inline for the same tree-shaking reason as `map` above.
|
|
422
432
|
registerDashboardWidget('week-strip', {
|
|
423
|
-
renderer: __sfc_main$
|
|
424
|
-
form: __sfc_main$
|
|
433
|
+
renderer: __sfc_main$u,
|
|
434
|
+
form: __sfc_main$v,
|
|
425
435
|
defaultContent: {
|
|
426
436
|
source: { register: '', schema: '', filter: {} },
|
|
427
437
|
dateField: '',
|
|
@@ -437,8 +447,8 @@ registerDashboardWidget('week-strip', {
|
|
|
437
447
|
|
|
438
448
|
// One segmented bar with a legend that carries the numbers.
|
|
439
449
|
registerDashboardWidget('stacked-bar', {
|
|
440
|
-
renderer: __sfc_main$
|
|
441
|
-
form: __sfc_main$
|
|
450
|
+
renderer: __sfc_main$w,
|
|
451
|
+
form: __sfc_main$x,
|
|
442
452
|
defaultContent: {
|
|
443
453
|
source: { register: '', schema: '', groupBy: '', filter: {} },
|
|
444
454
|
order: [],
|
|
@@ -453,7 +463,7 @@ registerDashboardWidget('stacked-bar', {
|
|
|
453
463
|
// person's open count from the app (DqTeamwachtrij "Team vandaag"). Placed
|
|
454
464
|
// from the manifest: there is no config form yet.
|
|
455
465
|
registerDashboardWidget('team-workload', {
|
|
456
|
-
renderer: __sfc_main$
|
|
466
|
+
renderer: __sfc_main$y,
|
|
457
467
|
form: null,
|
|
458
468
|
defaultContent: { source: { url: '', responsePath: '', userField: 'userId', nameField: 'displayName', countField: 'count' } },
|
|
459
469
|
displayName: 'Team workload',
|