@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.
Files changed (179) hide show
  1. package/dist/esm/components/CnAiFeaturesWidget/CnAiFeaturesWidget.vue.js +9 -0
  2. package/dist/esm/components/CnAiFeaturesWidget/CnAiFeaturesWidget.vue.js.map +1 -0
  3. package/dist/esm/components/CnAiFeaturesWidget/CnAiFeaturesWidget.vue2.js +226 -0
  4. package/dist/esm/components/CnAiFeaturesWidget/CnAiFeaturesWidget.vue2.js.map +1 -0
  5. package/dist/esm/components/CnAiFeaturesWidget/CnAiFeaturesWidget.vue3.js +211 -0
  6. package/dist/esm/components/CnAiFeaturesWidget/CnAiFeaturesWidget.vue3.js.map +1 -0
  7. package/dist/esm/components/CnAiFeaturesWidget/CnAiSuggestionDecision.vue.js +9 -0
  8. package/dist/esm/components/CnAiFeaturesWidget/CnAiSuggestionDecision.vue.js.map +1 -0
  9. package/dist/esm/components/CnAiFeaturesWidget/CnAiSuggestionDecision.vue2.js +64 -0
  10. package/dist/esm/components/CnAiFeaturesWidget/CnAiSuggestionDecision.vue2.js.map +1 -0
  11. package/dist/esm/components/CnAiFeaturesWidget/CnAiSuggestionDecision.vue3.js +89 -0
  12. package/dist/esm/components/CnAiFeaturesWidget/CnAiSuggestionDecision.vue3.js.map +1 -0
  13. package/dist/esm/components/CnIcon/semanticIcons.js +2 -2
  14. package/dist/esm/components/CnIcon/semanticIcons.js.map +1 -1
  15. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js +53 -1
  16. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js.map +1 -1
  17. package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js +546 -523
  18. package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js.map +1 -1
  19. package/dist/esm/components/CnIndexPage/useNamedSource.js +9 -0
  20. package/dist/esm/components/CnIndexPage/useNamedSource.js.map +1 -1
  21. package/dist/esm/components/CnObjectPermissionsTab/CnObjectPermissionsTab.vue.js +9 -0
  22. package/dist/esm/components/CnObjectPermissionsTab/CnObjectPermissionsTab.vue.js.map +1 -0
  23. package/dist/esm/components/CnObjectPermissionsTab/CnObjectPermissionsTab.vue2.js +257 -0
  24. package/dist/esm/components/CnObjectPermissionsTab/CnObjectPermissionsTab.vue2.js.map +1 -0
  25. package/dist/esm/components/CnObjectPermissionsTab/CnObjectPermissionsTab.vue3.js +266 -0
  26. package/dist/esm/components/CnObjectPermissionsTab/CnObjectPermissionsTab.vue3.js.map +1 -0
  27. package/dist/esm/components/CnObjectSidebar/CnObjectSidebar.vue.js +1 -1
  28. package/dist/esm/components/CnObjectSidebar/CnObjectSidebar.vue2.js +14 -7
  29. package/dist/esm/components/CnObjectSidebar/CnObjectSidebar.vue2.js.map +1 -1
  30. package/dist/esm/components/CnObjectSidebar/CnObjectSidebar.vue3.js.map +1 -1
  31. package/dist/esm/components/CnObjectTranslationsWidget/CnObjectTranslationsWidget.vue.js +9 -0
  32. package/dist/esm/components/CnObjectTranslationsWidget/CnObjectTranslationsWidget.vue.js.map +1 -0
  33. package/dist/esm/components/CnObjectTranslationsWidget/CnObjectTranslationsWidget.vue2.js +278 -0
  34. package/dist/esm/components/CnObjectTranslationsWidget/CnObjectTranslationsWidget.vue2.js.map +1 -0
  35. package/dist/esm/components/CnObjectTranslationsWidget/CnObjectTranslationsWidget.vue3.js +128 -0
  36. package/dist/esm/components/CnObjectTranslationsWidget/CnObjectTranslationsWidget.vue3.js.map +1 -0
  37. package/dist/esm/components/CnReadinessChecklist/CnReadinessChecklist.vue.js +9 -0
  38. package/dist/esm/components/CnReadinessChecklist/CnReadinessChecklist.vue.js.map +1 -0
  39. package/dist/esm/components/CnReadinessChecklist/CnReadinessChecklist.vue2.js +214 -0
  40. package/dist/esm/components/CnReadinessChecklist/CnReadinessChecklist.vue2.js.map +1 -0
  41. package/dist/esm/components/CnReadinessChecklist/CnReadinessChecklist.vue3.js +125 -0
  42. package/dist/esm/components/CnReadinessChecklist/CnReadinessChecklist.vue3.js.map +1 -0
  43. package/dist/esm/components/CnSchemaRulesWidget/CnSchemaRulesWidget.vue.js +9 -0
  44. package/dist/esm/components/CnSchemaRulesWidget/CnSchemaRulesWidget.vue.js.map +1 -0
  45. package/dist/esm/components/CnSchemaRulesWidget/CnSchemaRulesWidget.vue2.js +163 -0
  46. package/dist/esm/components/CnSchemaRulesWidget/CnSchemaRulesWidget.vue2.js.map +1 -0
  47. package/dist/esm/components/CnSchemaRulesWidget/CnSchemaRulesWidget.vue3.js +131 -0
  48. package/dist/esm/components/CnSchemaRulesWidget/CnSchemaRulesWidget.vue3.js.map +1 -0
  49. package/dist/esm/components/CnSchemaRulesWidget/schemaRules.js +127 -0
  50. package/dist/esm/components/CnSchemaRulesWidget/schemaRules.js.map +1 -0
  51. package/dist/esm/components/CnSearchIndexStatus/CnSearchIndexStatus.vue.js +9 -0
  52. package/dist/esm/components/CnSearchIndexStatus/CnSearchIndexStatus.vue.js.map +1 -0
  53. package/dist/esm/components/CnSearchIndexStatus/CnSearchIndexStatus.vue2.js +82 -0
  54. package/dist/esm/components/CnSearchIndexStatus/CnSearchIndexStatus.vue2.js.map +1 -0
  55. package/dist/esm/components/CnSearchIndexStatus/CnSearchIndexStatus.vue3.js +61 -0
  56. package/dist/esm/components/CnSearchIndexStatus/CnSearchIndexStatus.vue3.js.map +1 -0
  57. package/dist/esm/components/CnSearchIndexStatus/searchIndexStatus.js +60 -0
  58. package/dist/esm/components/CnSearchIndexStatus/searchIndexStatus.js.map +1 -0
  59. package/dist/esm/components/CnShippedConfigurationSection/CnShippedConfigurationSection.vue.js +10 -0
  60. package/dist/esm/components/CnShippedConfigurationSection/CnShippedConfigurationSection.vue.js.map +1 -0
  61. package/dist/esm/components/CnShippedConfigurationSection/CnShippedConfigurationSection.vue2.js +226 -0
  62. package/dist/esm/components/CnShippedConfigurationSection/CnShippedConfigurationSection.vue2.js.map +1 -0
  63. package/dist/esm/components/CnShippedConfigurationSection/CnShippedConfigurationSection.vue3.js +126 -0
  64. package/dist/esm/components/CnShippedConfigurationSection/CnShippedConfigurationSection.vue3.js.map +1 -0
  65. package/dist/esm/components/CnStateMachineEditor/CnStateMachineEditor.vue.js +10 -0
  66. package/dist/esm/components/CnStateMachineEditor/CnStateMachineEditor.vue.js.map +1 -0
  67. package/dist/esm/components/CnStateMachineEditor/CnStateMachineEditor.vue2.js +944 -0
  68. package/dist/esm/components/CnStateMachineEditor/CnStateMachineEditor.vue2.js.map +1 -0
  69. package/dist/esm/components/CnStateMachineEditor/CnStateMachineEditor.vue3.js +276 -0
  70. package/dist/esm/components/CnStateMachineEditor/CnStateMachineEditor.vue3.js.map +1 -0
  71. package/dist/esm/components/CnStateMachineEditor/CnStateMachineFields.vue.js +9 -0
  72. package/dist/esm/components/CnStateMachineEditor/CnStateMachineFields.vue.js.map +1 -0
  73. package/dist/esm/components/CnStateMachineEditor/CnStateMachineFields.vue2.js +354 -0
  74. package/dist/esm/components/CnStateMachineEditor/CnStateMachineFields.vue2.js.map +1 -0
  75. package/dist/esm/components/CnStateMachineEditor/CnStateMachineFields.vue3.js +392 -0
  76. package/dist/esm/components/CnStateMachineEditor/CnStateMachineFields.vue3.js.map +1 -0
  77. package/dist/esm/components/CnStateMachineEditor/CnStateMachineNode.vue.js +9 -0
  78. package/dist/esm/components/CnStateMachineEditor/CnStateMachineNode.vue.js.map +1 -0
  79. package/dist/esm/components/CnStateMachineEditor/CnStateMachineNode.vue2.js +180 -0
  80. package/dist/esm/components/CnStateMachineEditor/CnStateMachineNode.vue2.js.map +1 -0
  81. package/dist/esm/components/CnStateMachineEditor/CnStateMachineNode.vue3.js +208 -0
  82. package/dist/esm/components/CnStateMachineEditor/CnStateMachineNode.vue3.js.map +1 -0
  83. package/dist/esm/components/CnStateMachineEditor/CnStateMachinePanel.vue.js +9 -0
  84. package/dist/esm/components/CnStateMachineEditor/CnStateMachinePanel.vue.js.map +1 -0
  85. package/dist/esm/components/CnStateMachineEditor/CnStateMachinePanel.vue2.js +244 -0
  86. package/dist/esm/components/CnStateMachineEditor/CnStateMachinePanel.vue2.js.map +1 -0
  87. package/dist/esm/components/CnStateMachineEditor/CnStateMachinePanel.vue3.js +76 -0
  88. package/dist/esm/components/CnStateMachineEditor/CnStateMachinePanel.vue3.js.map +1 -0
  89. package/dist/esm/components/CnStateMachineEditor/stateMachineFields.js +290 -0
  90. package/dist/esm/components/CnStateMachineEditor/stateMachineFields.js.map +1 -0
  91. package/dist/esm/components/CnTimelineWidget/CnTimelineManage.vue.js +9 -0
  92. package/dist/esm/components/CnTimelineWidget/CnTimelineManage.vue.js.map +1 -0
  93. package/dist/esm/components/CnTimelineWidget/CnTimelineManage.vue2.js +448 -0
  94. package/dist/esm/components/CnTimelineWidget/CnTimelineManage.vue2.js.map +1 -0
  95. package/dist/esm/components/CnTimelineWidget/CnTimelineManage.vue3.js +303 -0
  96. package/dist/esm/components/CnTimelineWidget/CnTimelineManage.vue3.js.map +1 -0
  97. package/dist/esm/components/CnTimelineWidget/CnTimelineWidget.vue.js +1 -1
  98. package/dist/esm/components/CnTimelineWidget/CnTimelineWidget.vue2.js +19 -2
  99. package/dist/esm/components/CnTimelineWidget/CnTimelineWidget.vue2.js.map +1 -1
  100. package/dist/esm/components/CnTimelineWidget/CnTimelineWidget.vue3.js +73 -62
  101. package/dist/esm/components/CnTimelineWidget/CnTimelineWidget.vue3.js.map +1 -1
  102. package/dist/esm/components/CnWidgetGrid/builtInWidgets.js +6 -0
  103. package/dist/esm/components/CnWidgetGrid/builtInWidgets.js.map +1 -1
  104. package/dist/esm/components/CnWidgetGrid/registerDashboardWidgets.js +42 -32
  105. package/dist/esm/components/CnWidgetGrid/registerDashboardWidgets.js.map +1 -1
  106. package/dist/esm/composables/indexSources.js +116 -16
  107. package/dist/esm/composables/indexSources.js.map +1 -1
  108. package/dist/esm/index.js +9 -0
  109. package/dist/esm/index.js.map +1 -1
  110. package/dist/esm/l10n/en.json.js +207 -1
  111. package/dist/esm/l10n/en.json.js.map +1 -1
  112. package/dist/esm/l10n/nl.json.js +207 -1
  113. package/dist/esm/l10n/nl.json.js.map +1 -1
  114. package/dist/esm/library-style.js +1 -1
  115. package/dist/esm/nextcloud-vue.css +951 -16
  116. package/dist/esm/utils/aiFeatures.js +245 -0
  117. package/dist/esm/utils/aiFeatures.js.map +1 -0
  118. package/dist/esm/utils/aiSuggestionTracker.js +182 -0
  119. package/dist/esm/utils/aiSuggestionTracker.js.map +1 -0
  120. package/dist/esm/utils/libraryWidgetKeys.js +2 -0
  121. package/dist/esm/utils/libraryWidgetKeys.js.map +1 -1
  122. package/dist/esm/utils/objectPermissions.js +552 -0
  123. package/dist/esm/utils/objectPermissions.js.map +1 -0
  124. package/dist/esm/utils/objectTranslations.js +180 -0
  125. package/dist/esm/utils/objectTranslations.js.map +1 -0
  126. package/dist/esm/utils/stateMachineValidation.js +254 -0
  127. package/dist/esm/utils/stateMachineValidation.js.map +1 -0
  128. package/dist/esm/utils/widgetDispatch.js +3 -1
  129. package/dist/esm/utils/widgetDispatch.js.map +1 -1
  130. package/dist/nextcloud-vue.cjs.js +23038 -14567
  131. package/dist/nextcloud-vue.cjs.js.map +2 -2
  132. package/dist/nextcloud-vue.css +951 -16
  133. package/l10n/en.json +207 -1
  134. package/l10n/nl.json +207 -1
  135. package/package.json +1 -1
  136. package/src/components/CnAiFeaturesWidget/CnAiFeaturesWidget.vue +416 -0
  137. package/src/components/CnAiFeaturesWidget/CnAiSuggestionDecision.vue +136 -0
  138. package/src/components/CnAiFeaturesWidget/__tests__/CnAiFeaturesWidget.spec.js +213 -0
  139. package/src/components/CnAiFeaturesWidget/index.js +14 -0
  140. package/src/components/CnIndexPage/CnIndexPage.vue +74 -3
  141. package/src/components/CnIndexPage/useNamedSource.js +9 -0
  142. package/src/components/CnObjectPermissionsTab/CnObjectPermissionsTab.vue +499 -0
  143. package/src/components/CnObjectPermissionsTab/__tests__/CnObjectPermissionsTab.spec.js +186 -0
  144. package/src/components/CnObjectPermissionsTab/index.js +13 -0
  145. package/src/components/CnObjectSidebar/CnObjectSidebar.vue +8 -1
  146. package/src/components/CnObjectTranslationsWidget/CnObjectTranslationsWidget.vue +424 -0
  147. package/src/components/CnObjectTranslationsWidget/__tests__/CnObjectTranslationsWidget.spec.js +189 -0
  148. package/src/components/CnObjectTranslationsWidget/index.js +13 -0
  149. package/src/components/CnReadinessChecklist/CnReadinessChecklist.vue +335 -0
  150. package/src/components/CnReadinessChecklist/index.js +9 -0
  151. package/src/components/CnSchemaRulesWidget/CnSchemaRulesWidget.vue +300 -0
  152. package/src/components/CnSchemaRulesWidget/index.js +10 -0
  153. package/src/components/CnSchemaRulesWidget/schemaRules.js +123 -0
  154. package/src/components/CnSearchIndexStatus/CnSearchIndexStatus.vue +160 -0
  155. package/src/components/CnSearchIndexStatus/index.js +10 -0
  156. package/src/components/CnSearchIndexStatus/searchIndexStatus.js +56 -0
  157. package/src/components/CnShippedConfigurationSection/CnShippedConfigurationSection.vue +328 -0
  158. package/src/components/CnShippedConfigurationSection/index.js +9 -0
  159. package/src/components/CnStateMachineEditor/CnStateMachineEditor.vue +1332 -0
  160. package/src/components/CnStateMachineEditor/CnStateMachineFields.vue +791 -0
  161. package/src/components/CnStateMachineEditor/CnStateMachineNode.vue +442 -0
  162. package/src/components/CnStateMachineEditor/CnStateMachinePanel.vue +326 -0
  163. package/src/components/CnStateMachineEditor/index.js +8 -0
  164. package/src/components/CnStateMachineEditor/stateMachineFields.js +287 -0
  165. package/src/components/CnTimelineWidget/CnTimelineManage.vue +827 -0
  166. package/src/components/CnTimelineWidget/CnTimelineWidget.vue +29 -3
  167. package/src/components/CnWidgetGrid/builtInWidgets.js +6 -0
  168. package/src/components/CnWidgetGrid/registerDashboardWidgets.js +10 -0
  169. package/src/components/index.js +8 -0
  170. package/src/composables/indexSources.js +116 -16
  171. package/src/css/index-page.css +7 -0
  172. package/src/index.js +9 -0
  173. package/src/utils/aiFeatures.js +241 -0
  174. package/src/utils/aiSuggestionTracker.js +178 -0
  175. package/src/utils/libraryWidgetKeys.js +2 -0
  176. package/src/utils/objectPermissions.js +548 -0
  177. package/src/utils/objectTranslations.js +176 -0
  178. package/src/utils/stateMachineValidation.js +250 -0
  179. package/src/utils/widgetDispatch.js +3 -1
@@ -0,0 +1,442 @@
1
+ <!--
2
+ - SPDX-FileCopyrightText: 2026 Conduction B.V. <info@conduction.nl>
3
+ - SPDX-License-Identifier: EUPL-1.2
4
+ -->
5
+ <template>
6
+ <div class="cn-sm-node" :class="{ 'cn-sm-node--final': final }">
7
+ <div class="cn-sm-node__header">
8
+ <span class="cn-sm-node__name">{{ label }}</span>
9
+ <span
10
+ v-if="showSteps && steps.length > 0"
11
+ class="cn-sm-node__count"
12
+ :title="say('stepCount', { count: steps.length })">
13
+ <span aria-hidden="true">{{ steps.length }}</span>
14
+ <span class="cn-sm-node__sr">{{ say('stepCount', { count: steps.length }) }}</span>
15
+ </span>
16
+
17
+ <!-- Every pointer gesture on the canvas has a menu entry here, so a
18
+ keyboard reaches all of them. Keys and pointer events stop at
19
+ this wrapper: the node's own handler would otherwise move or
20
+ remove the state on an arrow or Delete meant for the menu. -->
21
+ <div
22
+ v-if="!readOnly"
23
+ class="cn-sm-node__menu nodrag nopan"
24
+ @keydown.stop
25
+ @click.stop
26
+ @mousedown.stop
27
+ @pointerdown.stop>
28
+ <NcActions
29
+ :open="menuOpen"
30
+ :inline="0"
31
+ :aria-label="say('stateActions', { name: label })"
32
+ @update:open="$emit('update:menuOpen', $event)">
33
+ <NcActionButton
34
+ v-for="target in connectTargets"
35
+ :key="`connect-${target.id}`"
36
+ closeAfterClick
37
+ @click="$emit('connect', target.id)">
38
+ <template #icon>
39
+ <ArrowRight :size="20" />
40
+ </template>
41
+ {{ say('connectTo', { name: target.label }) }}
42
+ </NcActionButton>
43
+ <NcActionButton
44
+ v-for="transition in outgoing"
45
+ :key="`edit-${transition.id}`"
46
+ closeAfterClick
47
+ @click="$emit('edit-transition', transition.id)">
48
+ <template #icon>
49
+ <Pencil :size="20" />
50
+ </template>
51
+ {{ say('editTransitionTo', { name: transition.targetLabel }) }}
52
+ </NcActionButton>
53
+ <NcActionButton
54
+ v-for="transition in outgoing"
55
+ :key="`disconnect-${transition.id}`"
56
+ closeAfterClick
57
+ @click="$emit('disconnect', transition.id)">
58
+ <template #icon>
59
+ <LinkOff :size="20" />
60
+ </template>
61
+ {{ say('disconnectFrom', { name: transition.targetLabel }) }}
62
+ </NcActionButton>
63
+ <NcActionButton v-if="showSteps" closeAfterClick @click="$emit('add-step')">
64
+ <template #icon>
65
+ <Plus :size="20" />
66
+ </template>
67
+ {{ say('addStep') }}
68
+ </NcActionButton>
69
+ <NcActionButton closeAfterClick @click="$emit('delete-state')">
70
+ <template #icon>
71
+ <DeleteOutline :size="20" />
72
+ </template>
73
+ {{ say('deleteState') }}
74
+ </NcActionButton>
75
+ </NcActions>
76
+ </div>
77
+ </div>
78
+
79
+ <span v-if="final" class="cn-sm-node__chip">{{ say('final') }}</span>
80
+
81
+ <ul v-if="showSteps && steps.length > 0" class="cn-sm-node__steps">
82
+ <li v-for="(step, index) in steps" :key="step.id">
83
+ <button
84
+ type="button"
85
+ class="cn-sm-node__step nodrag nopan"
86
+ :class="{
87
+ 'cn-sm-node__step--required': isRequired(step),
88
+ 'cn-sm-node__step--selected': step.id === selectedStepId,
89
+ }"
90
+ :aria-pressed="step.id === selectedStepId ? 'true' : 'false'"
91
+ :draggable="readOnly ? 'false' : 'true'"
92
+ @click.stop="$emit('step-click', step.id)"
93
+ @keydown="onStepKeydown(index, $event)"
94
+ @mousedown.stop
95
+ @pointerdown.stop
96
+ @dragstart.stop="onStepDragStart(index, $event)"
97
+ @dragover.prevent
98
+ @drop.stop.prevent="onStepDrop(index)">
99
+ <span v-if="isRequired(step)" class="cn-sm-node__required" aria-hidden="true">*</span>
100
+ <span class="cn-sm-node__step-name">{{ stepTitle(step) }}</span>
101
+ <span v-if="isRequired(step)" class="cn-sm-node__sr">{{ say('required') }}</span>
102
+ <span v-if="badgeOf(step) > 0" class="cn-sm-node__checks">{{ badgeOf(step) }}</span>
103
+ </button>
104
+ </li>
105
+ </ul>
106
+
107
+ <button
108
+ v-if="showSteps && !readOnly"
109
+ type="button"
110
+ class="cn-sm-node__add nodrag nopan"
111
+ @click.stop="$emit('add-step')"
112
+ @keydown.stop
113
+ @mousedown.stop
114
+ @pointerdown.stop>
115
+ <Plus :size="16" />
116
+ <span>{{ say('addStep') }}</span>
117
+ </button>
118
+ </div>
119
+ </template>
120
+
121
+ <script>
122
+ import { NcActionButton, NcActions } from '@nextcloud/vue'
123
+ import ArrowRight from 'vue-material-design-icons/ArrowRight.vue'
124
+ import DeleteOutline from 'vue-material-design-icons/DeleteOutline.vue'
125
+ import LinkOff from 'vue-material-design-icons/LinkOff.vue'
126
+ import Pencil from 'vue-material-design-icons/Pencil.vue'
127
+ import Plus from 'vue-material-design-icons/Plus.vue'
128
+ import { asList } from '../../utils/stateMachineValidation.js'
129
+
130
+ /**
131
+ * The body of one state on the CnStateMachineEditor canvas: its name, its
132
+ * steps, and a menu that offers every canvas gesture from the keyboard.
133
+ *
134
+ * Rendered inside CnGraphCanvas's focusable node wrapper, which owns moving
135
+ * (arrow keys), connecting (`c`) and removing (Delete) the state.
136
+ */
137
+ export default {
138
+ name: 'CnStateMachineNode',
139
+
140
+ components: { NcActions, NcActionButton, ArrowRight, DeleteOutline, LinkOff, Pencil, Plus },
141
+
142
+ props: {
143
+ /** The state's name. */
144
+ label: {
145
+ type: String,
146
+ required: true,
147
+ },
148
+
149
+ /** Whether the state is final. */
150
+ final: {
151
+ type: Boolean,
152
+ default: false,
153
+ },
154
+
155
+ /** The state's steps, in order. */
156
+ steps: {
157
+ type: Array,
158
+ default: () => [],
159
+ },
160
+
161
+ /** Whether steps are part of this machine. */
162
+ showSteps: {
163
+ type: Boolean,
164
+ default: true,
165
+ },
166
+
167
+ /** Record keys of a step: `{ title, required, badge }`. */
168
+ stepKeys: {
169
+ type: Object,
170
+ default: () => ({ title: 'title', required: 'required', badge: '' }),
171
+ },
172
+
173
+ /** The step whose panel is open. */
174
+ selectedStepId: {
175
+ type: String,
176
+ default: null,
177
+ },
178
+
179
+ /** States this one has no transition to yet: `{ id, label }`. */
180
+ connectTargets: {
181
+ type: Array,
182
+ default: () => [],
183
+ },
184
+
185
+ /** Transitions leaving this state: `{ id, targetLabel }`. */
186
+ outgoing: {
187
+ type: Array,
188
+ default: () => [],
189
+ },
190
+
191
+ /** Whether the actions menu is open. */
192
+ menuOpen: {
193
+ type: Boolean,
194
+ default: false,
195
+ },
196
+
197
+ /** Hide every editing control. */
198
+ readOnly: {
199
+ type: Boolean,
200
+ default: false,
201
+ },
202
+
203
+ /** Resolves an editor text by name: `(name, vars) => string`. */
204
+ say: {
205
+ type: Function,
206
+ required: true,
207
+ },
208
+ },
209
+
210
+ emits: [
211
+ 'add-step',
212
+ 'connect',
213
+ 'delete-state',
214
+ 'disconnect',
215
+ 'edit-transition',
216
+ 'step-click',
217
+ 'step-move',
218
+ 'update:menuOpen',
219
+ ],
220
+
221
+ data() {
222
+ return {
223
+ dragIndex: null,
224
+ }
225
+ },
226
+
227
+ methods: {
228
+ /**
229
+ * @param {object} step A step.
230
+ * @return {string} Its title.
231
+ */
232
+ stepTitle(step) {
233
+ return step[this.stepKeys.title] || ''
234
+ },
235
+
236
+ /**
237
+ * @param {object} step A step.
238
+ * @return {boolean} Whether it is required.
239
+ */
240
+ isRequired(step) {
241
+ return this.stepKeys.required ? step[this.stepKeys.required] === true : false
242
+ },
243
+
244
+ /**
245
+ * @param {object} step A step.
246
+ * @return {number} The length of the list its badge counts, 0 for none.
247
+ */
248
+ badgeOf(step) {
249
+ return this.stepKeys.badge ? asList(step[this.stepKeys.badge]).length : 0
250
+ },
251
+
252
+ /**
253
+ * Keys on a step stay on the step: Alt with an arrow moves it within the
254
+ * state, everything else is the button's own.
255
+ *
256
+ * @param {number} index The step's position.
257
+ * @param {KeyboardEvent} event The key event.
258
+ * @return {void}
259
+ */
260
+ onStepKeydown(index, event) {
261
+ event.stopPropagation()
262
+ if (this.readOnly || event.altKey !== true) {
263
+ return
264
+ }
265
+ if (event.key === 'ArrowUp' && index > 0) {
266
+ event.preventDefault()
267
+ this.$emit('step-move', { from: index, to: index - 1 })
268
+ } else if (event.key === 'ArrowDown' && index < this.steps.length - 1) {
269
+ event.preventDefault()
270
+ this.$emit('step-move', { from: index, to: index + 1 })
271
+ }
272
+ },
273
+
274
+ /**
275
+ * @param {number} index The dragged step.
276
+ * @param {DragEvent} event The drag event.
277
+ * @return {void}
278
+ */
279
+ onStepDragStart(index, event) {
280
+ this.dragIndex = index
281
+ if (event.dataTransfer) {
282
+ event.dataTransfer.effectAllowed = 'move'
283
+ event.dataTransfer.setData('text/plain', String(index))
284
+ }
285
+ },
286
+
287
+ /**
288
+ * @param {number} index The step dropped on.
289
+ * @return {void}
290
+ */
291
+ onStepDrop(index) {
292
+ if (this.dragIndex !== null && this.dragIndex !== index) {
293
+ this.$emit('step-move', { from: this.dragIndex, to: index })
294
+ }
295
+ this.dragIndex = null
296
+ },
297
+ },
298
+ }
299
+ </script>
300
+
301
+ <style scoped>
302
+ .cn-sm-node {
303
+ display: flex;
304
+ flex-direction: column;
305
+ gap: 6px;
306
+ text-align: start;
307
+ }
308
+
309
+ .cn-sm-node__header {
310
+ display: flex;
311
+ align-items: center;
312
+ gap: 6px;
313
+ min-width: 0;
314
+ }
315
+
316
+ .cn-sm-node__name {
317
+ flex: 1 1 auto;
318
+ min-width: 0;
319
+ overflow: hidden;
320
+ font-size: 14px;
321
+ font-weight: 600;
322
+ text-overflow: ellipsis;
323
+ white-space: nowrap;
324
+ }
325
+
326
+ .cn-sm-node__count {
327
+ flex: none;
328
+ min-width: 20px;
329
+ padding: 0 6px;
330
+ border-radius: 10px;
331
+ background: var(--color-primary-element, #0082c9);
332
+ color: var(--color-primary-element-text, #fff);
333
+ font-size: 12px;
334
+ font-weight: 600;
335
+ text-align: center;
336
+ }
337
+
338
+ .cn-sm-node__menu {
339
+ flex: none;
340
+ margin: -6px -8px -6px 0;
341
+ }
342
+
343
+ .cn-sm-node__chip {
344
+ align-self: flex-start;
345
+ padding: 2px 8px;
346
+ border-radius: 10px;
347
+ background: var(--color-success, #2d7b41);
348
+ color: var(--color-success-text, #fff);
349
+ font-size: 12px;
350
+ font-weight: 600;
351
+ }
352
+
353
+ .cn-sm-node__steps {
354
+ display: flex;
355
+ flex-direction: column;
356
+ margin: 0 -12px;
357
+ padding: 0;
358
+ list-style: none;
359
+ }
360
+
361
+ .cn-sm-node__step {
362
+ display: flex;
363
+ align-items: center;
364
+ gap: 4px;
365
+ width: 100%;
366
+ min-height: 28px;
367
+ padding: 2px 12px;
368
+ border: 0;
369
+ background: none;
370
+ color: var(--color-main-text, #222);
371
+ font: inherit;
372
+ font-size: 13px;
373
+ text-align: start;
374
+ cursor: pointer;
375
+ }
376
+
377
+ .cn-sm-node__step:hover,
378
+ .cn-sm-node__step--selected {
379
+ background: var(--color-background-hover, #f5f5f5);
380
+ }
381
+
382
+ .cn-sm-node__step:focus-visible,
383
+ .cn-sm-node__add:focus-visible {
384
+ outline: 2px solid var(--color-primary-element, #0082c9);
385
+ outline-offset: -2px;
386
+ }
387
+
388
+ .cn-sm-node__step--required {
389
+ font-weight: 600;
390
+ }
391
+
392
+ .cn-sm-node__required {
393
+ color: var(--color-error-text, #c9302c);
394
+ }
395
+
396
+ .cn-sm-node__step-name {
397
+ flex: 1 1 auto;
398
+ min-width: 0;
399
+ overflow: hidden;
400
+ text-overflow: ellipsis;
401
+ white-space: nowrap;
402
+ }
403
+
404
+ .cn-sm-node__checks {
405
+ flex: none;
406
+ padding: 0 4px;
407
+ border-radius: 4px;
408
+ background: var(--color-background-dark, #ededed);
409
+ color: var(--color-text-maxcontrast, #6b6b6b);
410
+ font-size: 11px;
411
+ }
412
+
413
+ .cn-sm-node__add {
414
+ display: flex;
415
+ align-items: center;
416
+ gap: 4px;
417
+ margin: 0 -12px -8px;
418
+ min-height: 32px;
419
+ padding: 4px 12px;
420
+ border: 0;
421
+ border-top: 1px solid var(--color-border, #d0d0d0);
422
+ background: none;
423
+ color: var(--color-text-maxcontrast, #6b6b6b);
424
+ font: inherit;
425
+ font-size: 13px;
426
+ cursor: pointer;
427
+ }
428
+
429
+ .cn-sm-node__add:hover {
430
+ background: var(--color-background-hover, #f5f5f5);
431
+ color: var(--color-main-text, #222);
432
+ }
433
+
434
+ .cn-sm-node__sr {
435
+ position: absolute;
436
+ width: 1px;
437
+ height: 1px;
438
+ overflow: hidden;
439
+ clip-path: inset(50%);
440
+ white-space: nowrap;
441
+ }
442
+ </style>