@conduction/nextcloud-vue 2.108.0 → 2.110.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 (161) hide show
  1. package/dist/esm/components/CnActionDialog/CnActionDialog.vue.js +1 -1
  2. package/dist/esm/components/CnActionDialog/CnActionDialog.vue2.js +115 -12
  3. package/dist/esm/components/CnActionDialog/CnActionDialog.vue2.js.map +1 -1
  4. package/dist/esm/components/CnActionDialog/CnActionDialog.vue3.js +36 -9
  5. package/dist/esm/components/CnActionDialog/CnActionDialog.vue3.js.map +1 -1
  6. package/dist/esm/components/CnAddressSearch/CnAddressSearch.vue.js +10 -0
  7. package/dist/esm/components/CnAddressSearch/CnAddressSearch.vue.js.map +1 -0
  8. package/dist/esm/components/CnAddressSearch/CnAddressSearch.vue2.js +305 -0
  9. package/dist/esm/components/CnAddressSearch/CnAddressSearch.vue2.js.map +1 -0
  10. package/dist/esm/components/CnAddressSearch/CnAddressSearch.vue3.js +38 -0
  11. package/dist/esm/components/CnAddressSearch/CnAddressSearch.vue3.js.map +1 -0
  12. package/dist/esm/components/CnAssignDialog/CnAssignDialog.vue.js +10 -0
  13. package/dist/esm/components/CnAssignDialog/CnAssignDialog.vue.js.map +1 -0
  14. package/dist/esm/components/CnAssignDialog/CnAssignDialog.vue2.js +398 -0
  15. package/dist/esm/components/CnAssignDialog/CnAssignDialog.vue2.js.map +1 -0
  16. package/dist/esm/components/CnAssignDialog/CnAssignDialog.vue3.js +155 -0
  17. package/dist/esm/components/CnAssignDialog/CnAssignDialog.vue3.js.map +1 -0
  18. package/dist/esm/components/CnDecisionListWidget/CnDecisionListWidget.vue.js +9 -0
  19. package/dist/esm/components/CnDecisionListWidget/CnDecisionListWidget.vue.js.map +1 -0
  20. package/dist/esm/components/CnDecisionListWidget/CnDecisionListWidget.vue2.js +281 -0
  21. package/dist/esm/components/CnDecisionListWidget/CnDecisionListWidget.vue2.js.map +1 -0
  22. package/dist/esm/components/CnDecisionListWidget/CnDecisionListWidget.vue3.js +137 -0
  23. package/dist/esm/components/CnDecisionListWidget/CnDecisionListWidget.vue3.js.map +1 -0
  24. package/dist/esm/components/CnDuplicateWarning/CnDuplicateWarning.vue.js +9 -0
  25. package/dist/esm/components/CnDuplicateWarning/CnDuplicateWarning.vue.js.map +1 -0
  26. package/dist/esm/components/CnDuplicateWarning/CnDuplicateWarning.vue2.js +225 -0
  27. package/dist/esm/components/CnDuplicateWarning/CnDuplicateWarning.vue2.js.map +1 -0
  28. package/dist/esm/components/CnDuplicateWarning/CnDuplicateWarning.vue3.js +110 -0
  29. package/dist/esm/components/CnDuplicateWarning/CnDuplicateWarning.vue3.js.map +1 -0
  30. package/dist/esm/components/CnFormDialog/CnFormDialog.vue.js +1 -1
  31. package/dist/esm/components/CnFormDialog/CnFormDialog.vue2.js +19 -3
  32. package/dist/esm/components/CnFormDialog/CnFormDialog.vue2.js.map +1 -1
  33. package/dist/esm/components/CnFormDialog/CnFormDialog.vue3.js.map +1 -1
  34. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js +30 -0
  35. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js.map +1 -1
  36. package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js +513 -481
  37. package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js.map +1 -1
  38. package/dist/esm/components/CnNcDashboardList/CnNcDashboardList.vue.js +9 -0
  39. package/dist/esm/components/CnNcDashboardList/CnNcDashboardList.vue.js.map +1 -0
  40. package/dist/esm/components/CnNcDashboardList/CnNcDashboardList.vue2.js +181 -0
  41. package/dist/esm/components/CnNcDashboardList/CnNcDashboardList.vue2.js.map +1 -0
  42. package/dist/esm/components/CnNcDashboardList/CnNcDashboardList.vue3.js +50 -0
  43. package/dist/esm/components/CnNcDashboardList/CnNcDashboardList.vue3.js.map +1 -0
  44. package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue.js +1 -1
  45. package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue2.js +102 -1
  46. package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue2.js.map +1 -1
  47. package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue3.js +6 -6
  48. package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue3.js.map +1 -1
  49. package/dist/esm/components/CnPlanWidget/CnPlanWidget.vue.js +9 -0
  50. package/dist/esm/components/CnPlanWidget/CnPlanWidget.vue.js.map +1 -0
  51. package/dist/esm/components/CnPlanWidget/CnPlanWidget.vue2.js +190 -0
  52. package/dist/esm/components/CnPlanWidget/CnPlanWidget.vue2.js.map +1 -0
  53. package/dist/esm/components/CnPlanWidget/CnPlanWidget.vue3.js +91 -0
  54. package/dist/esm/components/CnPlanWidget/CnPlanWidget.vue3.js.map +1 -0
  55. package/dist/esm/components/CnPlanWidget/CnPlanWidgetRow.vue.js +9 -0
  56. package/dist/esm/components/CnPlanWidget/CnPlanWidgetRow.vue.js.map +1 -0
  57. package/dist/esm/components/CnPlanWidget/CnPlanWidgetRow.vue2.js +64 -0
  58. package/dist/esm/components/CnPlanWidget/CnPlanWidgetRow.vue2.js.map +1 -0
  59. package/dist/esm/components/CnPlanWidget/CnPlanWidgetRow.vue3.js +49 -0
  60. package/dist/esm/components/CnPlanWidget/CnPlanWidgetRow.vue3.js.map +1 -0
  61. package/dist/esm/components/CnRedactionEditor/CnRedactionEditor.vue.js +9 -0
  62. package/dist/esm/components/CnRedactionEditor/CnRedactionEditor.vue.js.map +1 -0
  63. package/dist/esm/components/CnRedactionEditor/CnRedactionEditor.vue2.js +382 -0
  64. package/dist/esm/components/CnRedactionEditor/CnRedactionEditor.vue2.js.map +1 -0
  65. package/dist/esm/components/CnRedactionEditor/CnRedactionEditor.vue3.js +285 -0
  66. package/dist/esm/components/CnRedactionEditor/CnRedactionEditor.vue3.js.map +1 -0
  67. package/dist/esm/components/CnRetentionWidget/CnRetentionWidget.vue.js +9 -0
  68. package/dist/esm/components/CnRetentionWidget/CnRetentionWidget.vue.js.map +1 -0
  69. package/dist/esm/components/CnRetentionWidget/CnRetentionWidget.vue2.js +277 -0
  70. package/dist/esm/components/CnRetentionWidget/CnRetentionWidget.vue2.js.map +1 -0
  71. package/dist/esm/components/CnRetentionWidget/CnRetentionWidget.vue3.js +183 -0
  72. package/dist/esm/components/CnRetentionWidget/CnRetentionWidget.vue3.js.map +1 -0
  73. package/dist/esm/components/CnWidgetGrid/builtInWidgets.js +16 -14
  74. package/dist/esm/components/CnWidgetGrid/builtInWidgets.js.map +1 -1
  75. package/dist/esm/components/CnWidgetGrid/registerDashboardWidgets.js +53 -22
  76. package/dist/esm/components/CnWidgetGrid/registerDashboardWidgets.js.map +1 -1
  77. package/dist/esm/components/CnWorkQueue/CnWorkQueue.vue.js +9 -0
  78. package/dist/esm/components/CnWorkQueue/CnWorkQueue.vue.js.map +1 -0
  79. package/dist/esm/components/CnWorkQueue/CnWorkQueue.vue2.js +253 -0
  80. package/dist/esm/components/CnWorkQueue/CnWorkQueue.vue2.js.map +1 -0
  81. package/dist/esm/components/CnWorkQueue/CnWorkQueue.vue3.js +197 -0
  82. package/dist/esm/components/CnWorkQueue/CnWorkQueue.vue3.js.map +1 -0
  83. package/dist/esm/index.js +12 -0
  84. package/dist/esm/index.js.map +1 -1
  85. package/dist/esm/l10n/en.json.js +106 -1
  86. package/dist/esm/l10n/en.json.js.map +1 -1
  87. package/dist/esm/l10n/nl.json.js +105 -1
  88. package/dist/esm/l10n/nl.json.js.map +1 -1
  89. package/dist/esm/library-style.js +1 -1
  90. package/dist/esm/nextcloud-vue.css +510 -76
  91. package/dist/esm/utils/actionsDispatcher.js +11 -3
  92. package/dist/esm/utils/actionsDispatcher.js.map +1 -1
  93. package/dist/esm/utils/builtInModals.js +3 -1
  94. package/dist/esm/utils/builtInModals.js.map +1 -1
  95. package/dist/esm/utils/duplicateWarning.js +62 -0
  96. package/dist/esm/utils/duplicateWarning.js.map +1 -0
  97. package/dist/esm/utils/errors.js +4 -0
  98. package/dist/esm/utils/errors.js.map +1 -1
  99. package/dist/esm/utils/libraryWidgetKeys.js +4 -0
  100. package/dist/esm/utils/libraryWidgetKeys.js.map +1 -1
  101. package/dist/esm/utils/openDuplicateWarning.js +39 -0
  102. package/dist/esm/utils/openDuplicateWarning.js.map +1 -0
  103. package/dist/esm/utils/optionsFrom.js +69 -2
  104. package/dist/esm/utils/optionsFrom.js.map +1 -1
  105. package/dist/esm/utils/planTree.js +57 -0
  106. package/dist/esm/utils/planTree.js.map +1 -0
  107. package/dist/esm/utils/redactionSegments.js +53 -0
  108. package/dist/esm/utils/redactionSegments.js.map +1 -0
  109. package/dist/esm/utils/registerNcDashboardWidgets.js +61 -0
  110. package/dist/esm/utils/registerNcDashboardWidgets.js.map +1 -0
  111. package/dist/esm/utils/searchRefusal.js +62 -0
  112. package/dist/esm/utils/searchRefusal.js.map +1 -0
  113. package/dist/esm/utils/validateManifestV2.compiled.js +3 -3
  114. package/dist/esm/utils/validateManifestV2.compiled.js.map +1 -1
  115. package/dist/nextcloud-vue.cjs.js +17560 -12844
  116. package/dist/nextcloud-vue.cjs.js.map +2 -2
  117. package/dist/nextcloud-vue.css +510 -76
  118. package/l10n/en.json +106 -1
  119. package/l10n/nl.json +105 -1
  120. package/package.json +1 -1
  121. package/src/components/CnActionDialog/CnActionDialog.vue +134 -13
  122. package/src/components/CnAddressSearch/CnAddressSearch.vue +343 -0
  123. package/src/components/CnAddressSearch/index.js +12 -0
  124. package/src/components/CnAssignDialog/CnAssignDialog.vue +525 -0
  125. package/src/components/CnAssignDialog/index.js +12 -0
  126. package/src/components/CnDecisionListWidget/CnDecisionListWidget.vue +388 -0
  127. package/src/components/CnDecisionListWidget/index.js +12 -0
  128. package/src/components/CnDuplicateWarning/CnDuplicateWarning.vue +318 -0
  129. package/src/components/CnDuplicateWarning/index.js +12 -0
  130. package/src/components/CnFormDialog/CnFormDialog.vue +19 -3
  131. package/src/components/CnIndexPage/CnIndexPage.vue +52 -0
  132. package/src/components/CnNcDashboardList/CnNcDashboardList.vue +218 -0
  133. package/src/components/CnNcDashboardList/index.js +12 -0
  134. package/src/components/CnObjectListWidget/CnObjectListWidget.vue +107 -6
  135. package/src/components/CnPlanWidget/CnPlanWidget.vue +246 -0
  136. package/src/components/CnPlanWidget/CnPlanWidgetRow.vue +117 -0
  137. package/src/components/CnPlanWidget/index.js +12 -0
  138. package/src/components/CnRedactionEditor/CnRedactionEditor.vue +655 -0
  139. package/src/components/CnRedactionEditor/index.js +13 -0
  140. package/src/components/CnRetentionWidget/CnRetentionWidget.vue +413 -0
  141. package/src/components/CnRetentionWidget/index.js +12 -0
  142. package/src/components/CnWidgetGrid/builtInWidgets.js +2 -0
  143. package/src/components/CnWidgetGrid/registerDashboardWidgets.js +31 -0
  144. package/src/components/CnWorkQueue/CnWorkQueue.vue +463 -0
  145. package/src/components/CnWorkQueue/index.js +12 -0
  146. package/src/components/index.js +9 -0
  147. package/src/css/index-page.css +24 -0
  148. package/src/index.js +12 -0
  149. package/src/schemas/app-manifest-v2.schema.json +119 -3
  150. package/src/utils/actionsDispatcher.js +10 -2
  151. package/src/utils/builtInModals.js +3 -1
  152. package/src/utils/duplicateWarning.js +59 -0
  153. package/src/utils/errors.js +4 -0
  154. package/src/utils/libraryWidgetKeys.js +4 -0
  155. package/src/utils/openDuplicateWarning.js +35 -0
  156. package/src/utils/optionsFrom.js +68 -1
  157. package/src/utils/planTree.js +54 -0
  158. package/src/utils/redactionSegments.js +50 -0
  159. package/src/utils/registerNcDashboardWidgets.js +57 -0
  160. package/src/utils/searchRefusal.js +59 -0
  161. package/src/utils/validateManifestV2.compiled.js +3 -3
@@ -2,7 +2,7 @@ import script from './CnActionDialog.vue2.js';
2
2
  import { render } from './CnActionDialog.vue3.js';
3
3
 
4
4
  script.render = render;
5
- script.__scopeId = "data-v-53fea6f0";
5
+ script.__scopeId = "data-v-0bb28fd1";
6
6
  const __sfc_main = script;
7
7
 
8
8
  export { __sfc_main as default };
@@ -2,7 +2,7 @@ import axios__default from '@nextcloud/axios';
2
2
  import { emit } from '@nextcloud/event-bus';
3
3
  import { translate } from '@nextcloud/l10n';
4
4
  import { generateUrl } from '@nextcloud/router';
5
- import { NcButton, NcNoteCard, NcTextArea } from '@nextcloud/vue';
5
+ import { NcButton, NcNoteCard, NcSelect, NcTextArea, NcTextField } from '@nextcloud/vue';
6
6
  import CheckCircle from 'vue-material-design-icons/CheckCircle.vue';
7
7
  import CircleOutline from 'vue-material-design-icons/CircleOutline.vue';
8
8
  import HelpCircleOutline from 'vue-material-design-icons/HelpCircleOutline.vue';
@@ -27,7 +27,8 @@ let reasonSeq = 0;
27
27
  * note and Archive it.
28
28
  *
29
29
  * `config`:
30
- * - `title`, `eyebrow`, `subtitle`, `doneText`: texts, through the host translate.
30
+ * - `title`, `subtitle`, `doneText`: texts, through the host translate;
31
+ * `eyebrow` a template filled from the record ("Close off · {identifier}").
31
32
  * - `summary`: `{ source?, title, meta?, badge?, icon? }`: templates filled from
32
33
  * the record (`source` an endpointSource to read it from, else `object`).
33
34
  * - `facts`: `[{ title?, items: [{ label, value }] }]`, `value` a template.
@@ -35,8 +36,14 @@ let reasonSeq = 0;
35
36
  * `{ id, met, label?, detail? }` read from `source`; `labels[id]` gives an
36
37
  * item's `{ label, detail?, unmetDetail? }`; the ids in `required` must be
37
38
  * met before the action can run. `met: null` reads as unknown.
38
- * - `permission`: `{ source, allowedPath, reasonPath? }`: the action runs only
39
- * while `allowedPath` reads true; `reasonPath` says why not.
39
+ * - `permission`: `{ source, listPath?, match?, allowedPath, reasonPath? }`:
40
+ * the action runs only while `allowedPath` reads true; `reasonPath` says
41
+ * why not. With `listPath` the paths read the entry of that list whose
42
+ * fields equal `match` (`{ act: "archive" }`).
43
+ * - `fields`: `[{ field, type?: "text"|"date"|"datetime"|"select", label?,
44
+ * required?, options?: [{ value, label, fills? }] }]`: inputs sent beside
45
+ * the reason, required by default; a select option's `fills` sets other
46
+ * fields that are still empty.
40
47
  * - `reason`: `{ label?, hint?, required?, field? }`: a text area; required by
41
48
  * default; sent as `field` (default `reason`).
42
49
  * - `note`: `{ variant?, title?, text }`: a read-only note.
@@ -49,7 +56,7 @@ let reasonSeq = 0;
49
56
  var script = {
50
57
  name: 'CnActionDialog',
51
58
 
52
- components: { CheckCircle, CircleOutline, CnDialog: __sfc_main, CnIcon: __sfc_main$1, HelpCircleOutline, NcButton, NcNoteCard, NcTextArea },
59
+ components: { CheckCircle, CircleOutline, CnDialog: __sfc_main, CnIcon: __sfc_main$1, HelpCircleOutline, NcButton, NcNoteCard, NcSelect, NcTextArea, NcTextField },
53
60
 
54
61
  inject: {
55
62
  /** The host app's translate (CnAppRoot `cnTranslate`). */
@@ -95,6 +102,7 @@ var script = {
95
102
  checklistError: '',
96
103
  allowed: true,
97
104
  reason: '',
105
+ values: {},
98
106
  busy: false,
99
107
  refusal: '',
100
108
  done: false,
@@ -105,7 +113,21 @@ var script = {
105
113
  computed: {
106
114
  /** @return {object} The token context. */
107
115
  tokenCtx() {
108
- return { objectId: this.objectId, object: this.record || {} }
116
+ return { objectId: this.recordId, object: this.record || {} }
117
+ },
118
+
119
+ /**
120
+ * The record's id: `objectId`, or the route's `id` when the prop is
121
+ * empty or a token the opener could not resolve.
122
+ *
123
+ * @return {string|number}
124
+ */
125
+ recordId() {
126
+ const given = this.objectId;
127
+ if (given !== '' && given !== null && given !== undefined && !String(given).startsWith('@')) {
128
+ return given
129
+ }
130
+ return (this.$route && this.$route.params && this.$route.params.id) || ''
109
131
  },
110
132
 
111
133
  /** @return {object} The confirm config. */
@@ -191,7 +213,27 @@ var script = {
191
213
  * @return {boolean}
192
214
  */
193
215
  canConfirm() {
194
- return !this.busy && this.allowed && this.requiredMet && (!this.reasonNeeded || this.reason.trim() !== '')
216
+ return !this.busy && this.allowed && this.requiredMet && this.fieldsFilled && (!this.reasonNeeded || this.reason.trim() !== '')
217
+ },
218
+
219
+ /** @return {string} The eyebrow, filled from the record once it is known. */
220
+ eyebrowText() {
221
+ return this.record ? this.fill(this.config.eyebrow) || this.text(this.config.eyebrow) : this.text(this.config.eyebrow)
222
+ },
223
+
224
+ /** @return {Array<object>} The fields with a name. */
225
+ fields() {
226
+ return (Array.isArray(this.config.fields) ? this.config.fields : []).filter((f) => f && f.field)
227
+ },
228
+
229
+ /**
230
+ * Whether every required field has a value.
231
+ *
232
+ * @spec openspec/changes/action-dialog-fields-and-acts/specs/action-dialog/spec.md#requirement-an-action-dialog-asks-for-fields-and-reads-a-permission-from-a-list
233
+ * @return {boolean}
234
+ */
235
+ fieldsFilled() {
236
+ return this.fields.every((f) => f.required === false || String(this.values[f.field] ?? '').trim() !== '')
195
237
  },
196
238
  },
197
239
 
@@ -266,6 +308,63 @@ var script = {
266
308
  }
267
309
  },
268
310
 
311
+ /**
312
+ * The entry of a list whose fields equal `match`, or null.
313
+ *
314
+ * @param {unknown} list The list.
315
+ * @param {object} [match] The fields to match.
316
+ * @return {object|null}
317
+ */
318
+ matchIn(list, match) {
319
+ const wanted = Object.entries(match || {});
320
+ return (Array.isArray(list) ? list : []).find((entry) => entry && wanted.every(([key, value]) => String(entry[key]) === String(value))) || null
321
+ },
322
+
323
+ /**
324
+ * A select field's options, labels translated.
325
+ *
326
+ * @param {object} field The field.
327
+ * @return {Array<{id: string, label: string, fills?: object}>}
328
+ */
329
+ optionsOf(field) {
330
+ return (Array.isArray(field.options) ? field.options : []).map((o) => ({ id: String(o.value), label: this.text(o.label) || String(o.value), fills: o.fills }))
331
+ },
332
+
333
+ /**
334
+ * A select field's chosen option.
335
+ *
336
+ * @param {object} field The field.
337
+ * @return {object|null}
338
+ */
339
+ selectedOption(field) {
340
+ return this.optionsOf(field).find((o) => o.id === String(this.values[field.field] ?? '')) || null
341
+ },
342
+
343
+ /**
344
+ * Set a field's value.
345
+ *
346
+ * @param {string} name The field.
347
+ * @param {unknown} value The value.
348
+ */
349
+ setValue(name, value) {
350
+ this.values = { ...this.values, [name]: value === null || value === undefined ? '' : String(value) };
351
+ },
352
+
353
+ /**
354
+ * Choose a select option; its `fills` set the fields still empty.
355
+ *
356
+ * @param {object} field The select field.
357
+ * @param {{id: string, fills?: object}|null} option The option.
358
+ */
359
+ pick(field, option) {
360
+ this.setValue(field.field, option ? option.id : '');
361
+ for (const [name, value] of Object.entries((option && option.fills) || {})) {
362
+ if (String(this.values[name] ?? '').trim() === '') {
363
+ this.setValue(name, this.text(value) || value);
364
+ }
365
+ }
366
+ },
367
+
269
368
  /** @return {Promise<void>} */
270
369
  async loadPermission() {
271
370
  const def = this.config.permission;
@@ -274,8 +373,9 @@ var script = {
274
373
  }
275
374
  try {
276
375
  const data = await this.read(def.source);
277
- this.allowed = readPath(data, def.allowedPath || 'allowed') === true;
278
- this.refusal = this.allowed || !def.reasonPath ? '' : String(readPath(data, def.reasonPath) || '');
376
+ const entry = def.listPath ? this.matchIn(readPath(data, def.listPath), def.match) : data;
377
+ this.allowed = readPath(entry, def.allowedPath || 'allowed') === true;
378
+ this.refusal = this.allowed || !def.reasonPath ? '' : String(readPath(entry, def.reasonPath) || '');
279
379
  } catch {
280
380
  this.allowed = false;
281
381
  }
@@ -306,15 +406,18 @@ var script = {
306
406
  if (this.config.reason) {
307
407
  body[this.config.reason.field || 'reason'] = reason;
308
408
  }
409
+ for (const field of this.fields) {
410
+ body[field.field] = this.values[field.field] ?? '';
411
+ }
309
412
  const method = String(request.method || 'POST').toLowerCase();
310
413
  await axios__default[['post', 'put', 'patch', 'delete'].includes(method) ? method : 'post'](/^https?:\/\//i.test(url) ? url : generateUrl(url), body);
311
414
  } else if (this.confirmConfig.action && typeof this.cnDispatchAction === 'function') {
312
- await this.cnDispatchAction({ ...this.confirmConfig.action, args: [...(this.confirmConfig.action.args || []), { reason }] });
415
+ await this.cnDispatchAction({ ...this.confirmConfig.action, args: [...(this.confirmConfig.action.args || []), { ...this.values, reason }] });
313
416
  }
314
417
  this.done = true;
315
418
  emit(PAGE_REFRESH, {});
316
- /** @event done The action ran. Payload: `{ reason }`. */
317
- this.$emit('done', { reason });
419
+ /** @event done The action ran. Payload: the field values and `reason`. */
420
+ this.$emit('done', { ...this.values, reason });
318
421
  } catch (failure) {
319
422
  const data = failure && failure.response && failure.response.data;
320
423
  this.refusal = String((data && (data.message || data.error)) || translate('nextcloud-vue', 'The action could not be completed.'));
@@ -1 +1 @@
1
- {"version":3,"file":"CnActionDialog.vue2.js","sources":["../../../../src/components/CnActionDialog/CnActionDialog.vue"],"sourcesContent":["<!--\n - SPDX-FileCopyrightText: 2026 Conduction B.V.\n - SPDX-License-Identifier: EUPL-1.2\n-->\n<template>\n\t<CnDialog\n\t\t:name=\"text(config.title) || t('nextcloud-vue', 'Confirm')\"\n\t\t:eyebrow=\"text(config.eyebrow)\"\n\t\t:subtitle=\"text(config.subtitle)\"\n\t\twidth=\"form\"\n\t\t:noClose=\"busy\"\n\t\tdata-testid=\"cn-action-dialog\"\n\t\t@closing=\"close\">\n\t\t<div v-if=\"!done\" class=\"cn-action-dialog\">\n\t\t\t<!-- The record the action is about: its title, a meta line, a badge. -->\n\t\t\t<div v-if=\"summary\" class=\"cn-action-dialog__summary\" data-testid=\"cn-action-dialog-summary\">\n\t\t\t\t<CnIcon :name=\"config.summary.icon || 'FolderOutline'\" :size=\"20\" class=\"cn-action-dialog__summary-icon\" />\n\t\t\t\t<span class=\"cn-action-dialog__summary-text\">\n\t\t\t\t\t<strong>{{ summary.title }}</strong>\n\t\t\t\t\t<span v-if=\"summary.meta\" class=\"cn-action-dialog__muted\">{{ summary.meta }}</span>\n\t\t\t\t</span>\n\t\t\t\t<span v-if=\"summary.badge\" class=\"cn-action-dialog__badge\">{{ summary.badge }}</span>\n\t\t\t</div>\n\n\t\t\t<!-- Facts about the record, in titled groups (\"Retention under the case type\"). -->\n\t\t\t<section v-for=\"(section, index) in factSections\"\n\t\t\t\t:key=\"`facts-${index}`\"\n\t\t\t\tclass=\"cn-action-dialog__section\"\n\t\t\t\tdata-testid=\"cn-action-dialog-facts\">\n\t\t\t\t<h3 v-if=\"section.title\" class=\"cn-action-dialog__title\">\n\t\t\t\t\t{{ section.title }}\n\t\t\t\t</h3>\n\t\t\t\t<dl class=\"cn-action-dialog__facts\">\n\t\t\t\t\t<div v-for=\"fact in section.facts\" :key=\"fact.label\">\n\t\t\t\t\t\t<dt>{{ fact.label }}</dt>\n\t\t\t\t\t\t<dd>{{ fact.value }}</dd>\n\t\t\t\t\t</div>\n\t\t\t\t</dl>\n\t\t\t</section>\n\n\t\t\t<!-- The checklist, read from an endpoint: each item met, not met or\n\t\t\t unknown. Items named in `required` decide whether the action may\n\t\t\t run; the others inform. -->\n\t\t\t<section v-if=\"config.checklist\" class=\"cn-action-dialog__section\" data-testid=\"cn-action-dialog-checklist\">\n\t\t\t\t<h3 v-if=\"config.checklist.title\" class=\"cn-action-dialog__title\">\n\t\t\t\t\t{{ text(config.checklist.title) }}\n\t\t\t\t</h3>\n\t\t\t\t<p v-if=\"checklistError\" class=\"cn-action-dialog__muted\" role=\"status\">\n\t\t\t\t\t{{ checklistError }}\n\t\t\t\t</p>\n\t\t\t\t<ul class=\"cn-action-dialog__checks\">\n\t\t\t\t\t<li v-for=\"item in checklist\"\n\t\t\t\t\t\t:key=\"item.id\"\n\t\t\t\t\t\tclass=\"cn-action-dialog__check\"\n\t\t\t\t\t\t:data-testid=\"`cn-action-dialog-check-${item.id}`\"\n\t\t\t\t\t\t:data-met=\"String(item.met)\">\n\t\t\t\t\t\t<CheckCircle v-if=\"item.met === true\" :size=\"20\" class=\"cn-action-dialog__check-icon cn-action-dialog__check-icon--met\" />\n\t\t\t\t\t\t<HelpCircleOutline v-else-if=\"item.met === null\" :size=\"20\" class=\"cn-action-dialog__check-icon\" />\n\t\t\t\t\t\t<CircleOutline v-else :size=\"20\" class=\"cn-action-dialog__check-icon\" />\n\t\t\t\t\t\t<strong class=\"cn-action-dialog__check-label\">{{ item.label }}</strong>\n\t\t\t\t\t\t<span v-if=\"item.detail\" class=\"cn-action-dialog__muted\">{{ item.detail }}</span>\n\t\t\t\t\t</li>\n\t\t\t\t</ul>\n\t\t\t</section>\n\n\t\t\t<div v-if=\"config.reason\" class=\"cn-action-dialog__field\">\n\t\t\t\t<NcTextArea\n\t\t\t\t\t:id=\"reasonId\"\n\t\t\t\t\tv-model=\"reason\"\n\t\t\t\t\t:label=\"reasonLabel\"\n\t\t\t\t\t:labelOutside=\"false\"\n\t\t\t\t\tresize=\"vertical\"\n\t\t\t\t\tdata-testid=\"cn-action-dialog-reason\" />\n\t\t\t\t<span v-if=\"config.reason.hint\" class=\"cn-action-dialog__muted\">{{ text(config.reason.hint) }}</span>\n\t\t\t</div>\n\n\t\t\t<NcNoteCard v-if=\"config.note\"\n\t\t\t\t:type=\"noteType\"\n\t\t\t\t:heading=\"text(config.note.title)\"\n\t\t\t\tdata-testid=\"cn-action-dialog-note\">\n\t\t\t\t{{ text(config.note.text) }}\n\t\t\t</NcNoteCard>\n\n\t\t\t<p v-if=\"refusal\"\n\t\t\t\tclass=\"cn-action-dialog__error\"\n\t\t\t\trole=\"alert\"\n\t\t\t\tdata-testid=\"cn-action-dialog-refusal\">\n\t\t\t\t{{ refusal }}\n\t\t\t</p>\n\t\t</div>\n\n\t\t<p v-else role=\"status\" data-testid=\"cn-action-dialog-done\">\n\t\t\t{{ text(config.doneText) || t('nextcloud-vue', 'Done') }}\n\t\t</p>\n\n\t\t<template #actions>\n\t\t\t<NcButton :disabled=\"busy\" data-testid=\"cn-action-dialog-cancel\" @click=\"close\">\n\t\t\t\t{{ done ? t('nextcloud-vue', 'Close') : t('nextcloud-vue', 'Cancel') }}\n\t\t\t</NcButton>\n\t\t\t<NcButton v-if=\"!done\"\n\t\t\t\tvariant=\"primary\"\n\t\t\t\t:disabled=\"!canConfirm\"\n\t\t\t\tdata-testid=\"cn-action-dialog-confirm\"\n\t\t\t\t@click=\"confirm\">\n\t\t\t\t<template v-if=\"confirmConfig.icon\" #icon>\n\t\t\t\t\t<CnIcon :name=\"confirmConfig.icon\" :size=\"20\" />\n\t\t\t\t</template>\n\t\t\t\t{{ text(confirmConfig.label) || t('nextcloud-vue', 'Confirm') }}\n\t\t\t</NcButton>\n\t\t</template>\n\t</CnDialog>\n</template>\n\n<script>\nimport axios from '@nextcloud/axios'\nimport { emit } from '@nextcloud/event-bus'\nimport { translate as t } from '@nextcloud/l10n'\nimport { generateUrl } from '@nextcloud/router'\nimport { NcButton, NcNoteCard, NcTextArea } from '@nextcloud/vue'\nimport CheckCircle from 'vue-material-design-icons/CheckCircle.vue'\nimport CircleOutline from 'vue-material-design-icons/CircleOutline.vue'\nimport HelpCircleOutline from 'vue-material-design-icons/HelpCircleOutline.vue'\nimport { fetchEndpointSource, interpolateUrlTokens } from '../../composables/useEndpointSource.js'\nimport { fillTemplate } from '../../utils/fillTemplate.js'\nimport { readPath } from '../../utils/readPath.js'\nimport { CnDialog } from '../CnDialog/index.js'\nimport { CnIcon } from '../CnIcon/index.js'\n\n/** The page refresh channel the built-in widgets listen on. */\nconst PAGE_REFRESH = 'cn:page:refresh'\n\n/** Gives each dialog's reason field its own id. */\nlet reasonSeq = 0\n\n/**\n * CnActionDialog — the generic \"summary, checklist, reason, confirm\" dialog\n * for an act on a record, configured from the manifest (an `open-modal`\n * action's props), so an app does not hand-build each one. dossiq's archive\n * dialog (board DqArchiveren) is the first: the case, what its case type\n * keeps, a readiness checklist read from an endpoint, a reason, a read-only\n * note and Archive it.\n *\n * `config`:\n * - `title`, `eyebrow`, `subtitle`, `doneText`: texts, through the host translate.\n * - `summary`: `{ source?, title, meta?, badge?, icon? }`: templates filled from\n * the record (`source` an endpointSource to read it from, else `object`).\n * - `facts`: `[{ title?, items: [{ label, value }] }]`, `value` a template.\n * - `checklist`: `{ title?, source, itemsPath?, labels?, required? }`: items\n * `{ id, met, label?, detail? }` read from `source`; `labels[id]` gives an\n * item's `{ label, detail?, unmetDetail? }`; the ids in `required` must be\n * met before the action can run. `met: null` reads as unknown.\n * - `permission`: `{ source, allowedPath, reasonPath? }`: the action runs only\n * while `allowedPath` reads true; `reasonPath` says why not.\n * - `reason`: `{ label?, hint?, required?, field? }`: a text area; required by\n * default; sent as `field` (default `reason`).\n * - `note`: `{ variant?, title?, text }`: a read-only note.\n * - `confirm`: `{ label, icon?, request?: { method?, url, body? }, action? }`.\n * `request` posts itself (`body` templates filled with the record and\n * `{reason}`); `action` dispatches a manifest action through the page.\n *\n * Tokens (`@objectId`, `@object.<field>`) resolve in every url.\n */\nexport default {\n\tname: 'CnActionDialog',\n\n\tcomponents: { CheckCircle, CircleOutline, CnDialog, CnIcon, HelpCircleOutline, NcButton, NcNoteCard, NcTextArea },\n\n\tinject: {\n\t\t/** The host app's translate (CnAppRoot `cnTranslate`). */\n\t\tcnTranslate: { default: () => (key) => key },\n\t\t/** The page's pre-bound action dispatcher (CnPageRenderer), for `confirm.action`. */\n\t\tcnDispatchAction: { default: null },\n\t},\n\n\tprops: {\n\t\t/**\n\t\t * The dialog's configuration (see the component docs).\n\t\t *\n\t\t * @type {object}\n\t\t */\n\t\tconfig: {\n\t\t\ttype: Object,\n\t\t\tdefault: () => ({}),\n\t\t},\n\n\t\t/** The record's id, for the `@objectId` token. */\n\t\tobjectId: {\n\t\t\ttype: [String, Number],\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * The record, when the host has it: the summary and facts read it.\n\t\t *\n\t\t * @type {object|null}\n\t\t */\n\t\tobject: {\n\t\t\ttype: Object,\n\t\t\tdefault: null,\n\t\t},\n\t},\n\n\temits: ['close', 'done'],\n\n\tdata() {\n\t\treturn {\n\t\t\trecord: this.object,\n\t\t\titems: [],\n\t\t\tchecklistError: '',\n\t\t\tallowed: true,\n\t\t\treason: '',\n\t\t\tbusy: false,\n\t\t\trefusal: '',\n\t\t\tdone: false,\n\t\t\treasonId: `cn-action-dialog-reason-${++reasonSeq}`,\n\t\t}\n\t},\n\n\tcomputed: {\n\t\t/** @return {object} The token context. */\n\t\ttokenCtx() {\n\t\t\treturn { objectId: this.objectId, object: this.record || {} }\n\t\t},\n\n\t\t/** @return {object} The confirm config. */\n\t\tconfirmConfig() {\n\t\t\treturn this.config.confirm && typeof this.config.confirm === 'object' ? this.config.confirm : {}\n\t\t},\n\n\t\t/**\n\t\t * The summary row, or null without one or before the record is known.\n\t\t *\n\t\t * @spec openspec/changes/action-dialog/specs/action-dialog/spec.md#requirement-a-manifest-configures-an-action-dialog\n\t\t * @return {{title: string, meta: string, badge: string}|null}\n\t\t */\n\t\tsummary() {\n\t\t\tconst def = this.config.summary\n\t\t\tif (!def || !this.record) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst title = this.fill(def.title)\n\t\t\treturn title ? { title, meta: this.fill(def.meta), badge: this.fill(def.badge) } : null\n\t\t},\n\n\t\t/** @return {Array<{title: string, facts: Array<{label: string, value: string}>}>} The fact groups. */\n\t\tfactSections() {\n\t\t\tif (!Array.isArray(this.config.facts) || !this.record) {\n\t\t\t\treturn []\n\t\t\t}\n\t\t\tconst empty = t('nextcloud-vue', 'Not set')\n\t\t\treturn this.config.facts.map((section) => ({\n\t\t\t\ttitle: this.text(section.title),\n\t\t\t\tfacts: (Array.isArray(section.items) ? section.items : []).map((fact) => ({ label: this.text(fact.label), value: this.fill(fact.value) || empty })),\n\t\t\t}))\n\t\t},\n\n\t\t/**\n\t\t * The checklist rows: label and detail from `labels` by id, else the item's own.\n\t\t *\n\t\t * @spec openspec/changes/action-dialog/specs/action-dialog/spec.md#requirement-a-manifest-configures-an-action-dialog\n\t\t * @return {Array<{id: string, met: (boolean|null), label: string, detail: string}>}\n\t\t */\n\t\tchecklist() {\n\t\t\tconst labels = (this.config.checklist && this.config.checklist.labels) || {}\n\t\t\treturn this.items.map((item) => {\n\t\t\t\tconst met = item.met === null || item.met === undefined ? null : item.met === true\n\t\t\t\tconst own = labels[item.id] || {}\n\t\t\t\tconst detail = met === false && own.unmetDetail ? own.unmetDetail : (own.detail || item.detail || '')\n\t\t\t\treturn {\n\t\t\t\t\tid: String(item.id),\n\t\t\t\t\tmet,\n\t\t\t\t\tlabel: this.fill(own.label || item.label || String(item.id), item),\n\t\t\t\t\tdetail: met === null && !item.detail ? t('nextcloud-vue', 'Could not be read') : this.fill(detail, item),\n\t\t\t\t}\n\t\t\t})\n\t\t},\n\n\t\t/** @return {boolean} Whether every required item is met. */\n\t\trequiredMet() {\n\t\t\tconst required = (this.config.checklist && Array.isArray(this.config.checklist.required)) ? this.config.checklist.required.map(String) : []\n\t\t\treturn required.every((id) => this.items.some((item) => String(item.id) === id && item.met === true))\n\t\t},\n\n\t\t/** @return {boolean} Whether a reason is asked and needed. */\n\t\treasonNeeded() {\n\t\t\treturn Boolean(this.config.reason) && this.config.reason.required !== false\n\t\t},\n\n\t\t/** @return {string} The reason field's label. */\n\t\treasonLabel() {\n\t\t\treturn this.text(this.config.reason && this.config.reason.label) || t('nextcloud-vue', 'Reason')\n\t\t},\n\n\t\t/** @return {string} The note's NcNoteCard type. */\n\t\tnoteType() {\n\t\t\tconst variant = this.config.note && this.config.note.variant\n\t\t\treturn ['info', 'warning', 'error', 'success'].includes(variant) ? variant : 'info'\n\t\t},\n\n\t\t/**\n\t\t * Whether the action may run: allowed, required items met, a reason\n\t\t * when one is needed, and nothing in flight.\n\t\t *\n\t\t * @spec openspec/changes/action-dialog/specs/action-dialog/spec.md#requirement-a-manifest-configures-an-action-dialog\n\t\t * @return {boolean}\n\t\t */\n\t\tcanConfirm() {\n\t\t\treturn !this.busy && this.allowed && this.requiredMet && (!this.reasonNeeded || this.reason.trim() !== '')\n\t\t},\n\t},\n\n\tasync mounted() {\n\t\tawait Promise.all([this.loadRecord(), this.loadChecklist(), this.loadPermission()])\n\t},\n\n\tmethods: {\n\t\tt,\n\n\t\t/**\n\t\t * A config text through the host translate, '' for anything else.\n\t\t *\n\t\t * @param {unknown} value The text.\n\t\t * @return {string}\n\t\t */\n\t\ttext(value) {\n\t\t\treturn typeof value === 'string' && value !== '' ? this.cnTranslate(value) : ''\n\t\t},\n\n\t\t/**\n\t\t * A template filled from a row (the record by default), translated first.\n\t\t *\n\t\t * @param {unknown} template The template.\n\t\t * @param {object} [row] The row.\n\t\t * @return {string}\n\t\t */\n\t\tfill(template, row) {\n\t\t\tif (typeof template !== 'string' || template === '') {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t\treturn fillTemplate(this.cnTranslate(template), row || this.record || {}).trim()\n\t\t},\n\n\t\t/**\n\t\t * Read an endpoint, fresh.\n\t\t *\n\t\t * @param {object} source An endpointSource block.\n\t\t * @return {Promise<unknown>}\n\t\t */\n\t\tread(source) {\n\t\t\treturn fetchEndpointSource(source, this.tokenCtx, { fresh: true })\n\t\t},\n\n\t\t/** @return {Promise<void>} */\n\t\tasync loadRecord() {\n\t\t\tconst source = this.config.summary && this.config.summary.source\n\t\t\tif (!source || !source.url) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst data = await this.read(source)\n\t\t\t\tthis.record = data && typeof data === 'object' ? data : this.record\n\t\t\t} catch {\n\t\t\t\t// The summary stays empty; the checklist and the action still work.\n\t\t\t}\n\t\t},\n\n\t\t/** @return {Promise<void>} */\n\t\tasync loadChecklist() {\n\t\t\tconst def = this.config.checklist\n\t\t\tif (!def || !def.source || !def.source.url) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst data = await this.read(def.source)\n\t\t\t\tconst list = def.itemsPath ? readPath(data, def.itemsPath) : data\n\t\t\t\tthis.items = Array.isArray(list) ? list.filter((item) => item && item.id !== undefined) : []\n\t\t\t} catch {\n\t\t\t\tthis.items = []\n\t\t\t\tthis.checklistError = t('nextcloud-vue', 'Whether this is ready could not be read.')\n\t\t\t}\n\t\t},\n\n\t\t/** @return {Promise<void>} */\n\t\tasync loadPermission() {\n\t\t\tconst def = this.config.permission\n\t\t\tif (!def || !def.source || !def.source.url) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst data = await this.read(def.source)\n\t\t\t\tthis.allowed = readPath(data, def.allowedPath || 'allowed') === true\n\t\t\t\tthis.refusal = this.allowed || !def.reasonPath ? '' : String(readPath(data, def.reasonPath) || '')\n\t\t\t} catch {\n\t\t\t\tthis.allowed = false\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Run the action once: post `confirm.request`, or dispatch\n\t\t * `confirm.action`, then show the done text and refresh the page.\n\t\t *\n\t\t * @spec openspec/changes/action-dialog/specs/action-dialog/spec.md#requirement-a-manifest-configures-an-action-dialog\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync confirm() {\n\t\t\tif (!this.canConfirm) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.busy = true\n\t\t\tthis.refusal = ''\n\t\t\tconst reason = this.reason.trim()\n\t\t\ttry {\n\t\t\t\tconst request = this.confirmConfig.request\n\t\t\t\tif (request && request.url) {\n\t\t\t\t\tconst url = interpolateUrlTokens(request.url, this.tokenCtx)\n\t\t\t\t\tconst body = {}\n\t\t\t\t\tfor (const [key, value] of Object.entries(request.body || {})) {\n\t\t\t\t\t\tbody[key] = typeof value === 'string' ? fillTemplate(value, { ...(this.record || {}), reason }) : value\n\t\t\t\t\t}\n\t\t\t\t\tif (this.config.reason) {\n\t\t\t\t\t\tbody[this.config.reason.field || 'reason'] = reason\n\t\t\t\t\t}\n\t\t\t\t\tconst method = String(request.method || 'POST').toLowerCase()\n\t\t\t\t\tawait axios[['post', 'put', 'patch', 'delete'].includes(method) ? method : 'post'](/^https?:\\/\\//i.test(url) ? url : generateUrl(url), body)\n\t\t\t\t} else if (this.confirmConfig.action && typeof this.cnDispatchAction === 'function') {\n\t\t\t\t\tawait this.cnDispatchAction({ ...this.confirmConfig.action, args: [...(this.confirmConfig.action.args || []), { reason }] })\n\t\t\t\t}\n\t\t\t\tthis.done = true\n\t\t\t\temit(PAGE_REFRESH, {})\n\t\t\t\t/** @event done The action ran. Payload: `{ reason }`. */\n\t\t\t\tthis.$emit('done', { reason })\n\t\t\t} catch (failure) {\n\t\t\t\tconst data = failure && failure.response && failure.response.data\n\t\t\t\tthis.refusal = String((data && (data.message || data.error)) || t('nextcloud-vue', 'The action could not be completed.'))\n\t\t\t} finally {\n\t\t\t\tthis.busy = false\n\t\t\t}\n\t\t},\n\n\t\t/** Close the dialog, unless the action is running. */\n\t\tclose() {\n\t\t\tif (this.busy) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\t/** @event close The dialog was closed. */\n\t\t\tthis.$emit('close')\n\t\t},\n\t},\n}\n</script>\n\n<style scoped>\n.cn-action-dialog {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 16px;\n}\n\n.cn-action-dialog__summary {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 10px;\n\tpadding: 12px 14px;\n\tborder: 1px solid var(--color-border);\n\tborder-radius: var(--border-radius-large, 8px);\n}\n\n.cn-action-dialog__summary-text {\n\tdisplay: flex;\n\tflex: 1 1 auto;\n\tflex-direction: column;\n\tmin-width: 0;\n}\n\n.cn-action-dialog__badge {\n\tpadding: 3px 10px;\n\tborder-radius: 12px;\n\tbackground: var(--color-background-dark);\n\tfont-size: 13px;\n\tfont-weight: 600;\n\twhite-space: nowrap;\n}\n\n.cn-action-dialog__title {\n\tmargin: 0 0 8px;\n\tfont-size: 15px;\n\tfont-weight: 700;\n}\n\n.cn-action-dialog__facts {\n\tdisplay: grid;\n\tgrid-template-columns: repeat(auto-fit, minmax(180px, 1fr));\n\tgap: 8px 16px;\n\tmargin: 0;\n}\n\n.cn-action-dialog__facts dt {\n\tcolor: var(--color-text-maxcontrast);\n\tfont-size: 13px;\n}\n\n.cn-action-dialog__facts dd {\n\tmargin: 0;\n}\n\n.cn-action-dialog__checks {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 8px;\n\tmargin: 0;\n\tpadding: 0;\n\tlist-style: none;\n}\n\n.cn-action-dialog__check {\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\talign-items: center;\n\tgap: 8px;\n}\n\n.cn-action-dialog__check-icon {\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-action-dialog__check-icon--met {\n\tcolor: var(--color-success-text, var(--color-success));\n}\n\n.cn-action-dialog__muted {\n\tcolor: var(--color-text-maxcontrast);\n\tfont-size: 14px;\n}\n\n.cn-action-dialog__field {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 4px;\n}\n\n.cn-action-dialog__error {\n\tmargin: 0;\n\tcolor: var(--color-error-text, var(--color-error));\n}\n</style>\n"],"names":["CnDialog","CnIcon","t","axios"],"mappings":"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"}
1
+ {"version":3,"file":"CnActionDialog.vue2.js","sources":["../../../../src/components/CnActionDialog/CnActionDialog.vue"],"sourcesContent":["<!--\n - SPDX-FileCopyrightText: 2026 Conduction B.V.\n - SPDX-License-Identifier: EUPL-1.2\n-->\n<template>\n\t<CnDialog\n\t\t:name=\"text(config.title) || t('nextcloud-vue', 'Confirm')\"\n\t\t:eyebrow=\"eyebrowText\"\n\t\t:subtitle=\"text(config.subtitle)\"\n\t\twidth=\"form\"\n\t\t:noClose=\"busy\"\n\t\tdata-testid=\"cn-action-dialog\"\n\t\t@closing=\"close\">\n\t\t<div v-if=\"!done\" class=\"cn-action-dialog\">\n\t\t\t<!-- The record the action is about: its title, a meta line, a badge. -->\n\t\t\t<div v-if=\"summary\" class=\"cn-action-dialog__summary\" data-testid=\"cn-action-dialog-summary\">\n\t\t\t\t<CnIcon :name=\"config.summary.icon || 'FolderOutline'\" :size=\"20\" class=\"cn-action-dialog__summary-icon\" />\n\t\t\t\t<span class=\"cn-action-dialog__summary-text\">\n\t\t\t\t\t<strong>{{ summary.title }}</strong>\n\t\t\t\t\t<span v-if=\"summary.meta\" class=\"cn-action-dialog__muted\">{{ summary.meta }}</span>\n\t\t\t\t</span>\n\t\t\t\t<span v-if=\"summary.badge\" class=\"cn-action-dialog__badge\">{{ summary.badge }}</span>\n\t\t\t</div>\n\n\t\t\t<!-- Facts about the record, in titled groups (\"Retention under the case type\"). -->\n\t\t\t<section v-for=\"(section, index) in factSections\"\n\t\t\t\t:key=\"`facts-${index}`\"\n\t\t\t\tclass=\"cn-action-dialog__section\"\n\t\t\t\tdata-testid=\"cn-action-dialog-facts\">\n\t\t\t\t<h3 v-if=\"section.title\" class=\"cn-action-dialog__title\">\n\t\t\t\t\t{{ section.title }}\n\t\t\t\t</h3>\n\t\t\t\t<dl class=\"cn-action-dialog__facts\">\n\t\t\t\t\t<div v-for=\"fact in section.facts\" :key=\"fact.label\">\n\t\t\t\t\t\t<dt>{{ fact.label }}</dt>\n\t\t\t\t\t\t<dd>{{ fact.value }}</dd>\n\t\t\t\t\t</div>\n\t\t\t\t</dl>\n\t\t\t</section>\n\n\t\t\t<!-- The checklist, read from an endpoint: each item met, not met or\n\t\t\t unknown. Items named in `required` decide whether the action may\n\t\t\t run; the others inform. -->\n\t\t\t<section v-if=\"config.checklist\" class=\"cn-action-dialog__section\" data-testid=\"cn-action-dialog-checklist\">\n\t\t\t\t<h3 v-if=\"config.checklist.title\" class=\"cn-action-dialog__title\">\n\t\t\t\t\t{{ text(config.checklist.title) }}\n\t\t\t\t</h3>\n\t\t\t\t<p v-if=\"checklistError\" class=\"cn-action-dialog__muted\" role=\"status\">\n\t\t\t\t\t{{ checklistError }}\n\t\t\t\t</p>\n\t\t\t\t<ul class=\"cn-action-dialog__checks\">\n\t\t\t\t\t<li v-for=\"item in checklist\"\n\t\t\t\t\t\t:key=\"item.id\"\n\t\t\t\t\t\tclass=\"cn-action-dialog__check\"\n\t\t\t\t\t\t:data-testid=\"`cn-action-dialog-check-${item.id}`\"\n\t\t\t\t\t\t:data-met=\"String(item.met)\">\n\t\t\t\t\t\t<CheckCircle v-if=\"item.met === true\" :size=\"20\" class=\"cn-action-dialog__check-icon cn-action-dialog__check-icon--met\" />\n\t\t\t\t\t\t<HelpCircleOutline v-else-if=\"item.met === null\" :size=\"20\" class=\"cn-action-dialog__check-icon\" />\n\t\t\t\t\t\t<CircleOutline v-else :size=\"20\" class=\"cn-action-dialog__check-icon\" />\n\t\t\t\t\t\t<strong class=\"cn-action-dialog__check-label\">{{ item.label }}</strong>\n\t\t\t\t\t\t<span v-if=\"item.detail\" class=\"cn-action-dialog__muted\">{{ item.detail }}</span>\n\t\t\t\t\t</li>\n\t\t\t\t</ul>\n\t\t\t</section>\n\n\t\t\t<!-- Fields the action asks for, sent beside the reason. -->\n\t\t\t<div v-for=\"field in fields\"\n\t\t\t\t:key=\"field.field\"\n\t\t\t\tclass=\"cn-action-dialog__field\"\n\t\t\t\t:data-testid=\"`cn-action-dialog-field-${field.field}`\">\n\t\t\t\t<NcSelect v-if=\"field.type === 'select'\"\n\t\t\t\t\t:modelValue=\"selectedOption(field)\"\n\t\t\t\t\t:options=\"optionsOf(field)\"\n\t\t\t\t\t:inputLabel=\"text(field.label) || field.field\"\n\t\t\t\t\t:clearable=\"field.required === false\"\n\t\t\t\t\t@update:modelValue=\"(option) => pick(field, option)\" />\n\t\t\t\t<NcTextField v-else\n\t\t\t\t\t:modelValue=\"values[field.field] || ''\"\n\t\t\t\t\t:type=\"field.type === 'datetime' ? 'datetime-local' : (field.type === 'date' ? 'date' : 'text')\"\n\t\t\t\t\t:label=\"text(field.label) || field.field\"\n\t\t\t\t\t@update:modelValue=\"(value) => setValue(field.field, value)\" />\n\t\t\t</div>\n\n\t\t\t<div v-if=\"config.reason\" class=\"cn-action-dialog__field\">\n\t\t\t\t<NcTextArea\n\t\t\t\t\t:id=\"reasonId\"\n\t\t\t\t\tv-model=\"reason\"\n\t\t\t\t\t:label=\"reasonLabel\"\n\t\t\t\t\t:labelOutside=\"false\"\n\t\t\t\t\tresize=\"vertical\"\n\t\t\t\t\tdata-testid=\"cn-action-dialog-reason\" />\n\t\t\t\t<span v-if=\"config.reason.hint\" class=\"cn-action-dialog__muted\">{{ text(config.reason.hint) }}</span>\n\t\t\t</div>\n\n\t\t\t<NcNoteCard v-if=\"config.note\"\n\t\t\t\t:type=\"noteType\"\n\t\t\t\t:heading=\"text(config.note.title)\"\n\t\t\t\tdata-testid=\"cn-action-dialog-note\">\n\t\t\t\t{{ text(config.note.text) }}\n\t\t\t</NcNoteCard>\n\n\t\t\t<p v-if=\"refusal\"\n\t\t\t\tclass=\"cn-action-dialog__error\"\n\t\t\t\trole=\"alert\"\n\t\t\t\tdata-testid=\"cn-action-dialog-refusal\">\n\t\t\t\t{{ refusal }}\n\t\t\t</p>\n\t\t</div>\n\n\t\t<p v-else role=\"status\" data-testid=\"cn-action-dialog-done\">\n\t\t\t{{ text(config.doneText) || t('nextcloud-vue', 'Done') }}\n\t\t</p>\n\n\t\t<template #actions>\n\t\t\t<NcButton :disabled=\"busy\" data-testid=\"cn-action-dialog-cancel\" @click=\"close\">\n\t\t\t\t{{ done ? t('nextcloud-vue', 'Close') : t('nextcloud-vue', 'Cancel') }}\n\t\t\t</NcButton>\n\t\t\t<NcButton v-if=\"!done\"\n\t\t\t\tvariant=\"primary\"\n\t\t\t\t:disabled=\"!canConfirm\"\n\t\t\t\tdata-testid=\"cn-action-dialog-confirm\"\n\t\t\t\t@click=\"confirm\">\n\t\t\t\t<template v-if=\"confirmConfig.icon\" #icon>\n\t\t\t\t\t<CnIcon :name=\"confirmConfig.icon\" :size=\"20\" />\n\t\t\t\t</template>\n\t\t\t\t{{ text(confirmConfig.label) || t('nextcloud-vue', 'Confirm') }}\n\t\t\t</NcButton>\n\t\t</template>\n\t</CnDialog>\n</template>\n\n<script>\nimport axios from '@nextcloud/axios'\nimport { emit } from '@nextcloud/event-bus'\nimport { translate as t } from '@nextcloud/l10n'\nimport { generateUrl } from '@nextcloud/router'\nimport { NcButton, NcNoteCard, NcSelect, NcTextArea, NcTextField } from '@nextcloud/vue'\nimport CheckCircle from 'vue-material-design-icons/CheckCircle.vue'\nimport CircleOutline from 'vue-material-design-icons/CircleOutline.vue'\nimport HelpCircleOutline from 'vue-material-design-icons/HelpCircleOutline.vue'\nimport { fetchEndpointSource, interpolateUrlTokens } from '../../composables/useEndpointSource.js'\nimport { fillTemplate } from '../../utils/fillTemplate.js'\nimport { readPath } from '../../utils/readPath.js'\nimport { CnDialog } from '../CnDialog/index.js'\nimport { CnIcon } from '../CnIcon/index.js'\n\n/** The page refresh channel the built-in widgets listen on. */\nconst PAGE_REFRESH = 'cn:page:refresh'\n\n/** Gives each dialog's reason field its own id. */\nlet reasonSeq = 0\n\n/**\n * CnActionDialog — the generic \"summary, checklist, reason, confirm\" dialog\n * for an act on a record, configured from the manifest (an `open-modal`\n * action's props), so an app does not hand-build each one. dossiq's archive\n * dialog (board DqArchiveren) is the first: the case, what its case type\n * keeps, a readiness checklist read from an endpoint, a reason, a read-only\n * note and Archive it.\n *\n * `config`:\n * - `title`, `subtitle`, `doneText`: texts, through the host translate;\n * `eyebrow` a template filled from the record (\"Close off · {identifier}\").\n * - `summary`: `{ source?, title, meta?, badge?, icon? }`: templates filled from\n * the record (`source` an endpointSource to read it from, else `object`).\n * - `facts`: `[{ title?, items: [{ label, value }] }]`, `value` a template.\n * - `checklist`: `{ title?, source, itemsPath?, labels?, required? }`: items\n * `{ id, met, label?, detail? }` read from `source`; `labels[id]` gives an\n * item's `{ label, detail?, unmetDetail? }`; the ids in `required` must be\n * met before the action can run. `met: null` reads as unknown.\n * - `permission`: `{ source, listPath?, match?, allowedPath, reasonPath? }`:\n * the action runs only while `allowedPath` reads true; `reasonPath` says\n * why not. With `listPath` the paths read the entry of that list whose\n * fields equal `match` (`{ act: \"archive\" }`).\n * - `fields`: `[{ field, type?: \"text\"|\"date\"|\"datetime\"|\"select\", label?,\n * required?, options?: [{ value, label, fills? }] }]`: inputs sent beside\n * the reason, required by default; a select option's `fills` sets other\n * fields that are still empty.\n * - `reason`: `{ label?, hint?, required?, field? }`: a text area; required by\n * default; sent as `field` (default `reason`).\n * - `note`: `{ variant?, title?, text }`: a read-only note.\n * - `confirm`: `{ label, icon?, request?: { method?, url, body? }, action? }`.\n * `request` posts itself (`body` templates filled with the record and\n * `{reason}`); `action` dispatches a manifest action through the page.\n *\n * Tokens (`@objectId`, `@object.<field>`) resolve in every url.\n */\nexport default {\n\tname: 'CnActionDialog',\n\n\tcomponents: { CheckCircle, CircleOutline, CnDialog, CnIcon, HelpCircleOutline, NcButton, NcNoteCard, NcSelect, NcTextArea, NcTextField },\n\n\tinject: {\n\t\t/** The host app's translate (CnAppRoot `cnTranslate`). */\n\t\tcnTranslate: { default: () => (key) => key },\n\t\t/** The page's pre-bound action dispatcher (CnPageRenderer), for `confirm.action`. */\n\t\tcnDispatchAction: { default: null },\n\t},\n\n\tprops: {\n\t\t/**\n\t\t * The dialog's configuration (see the component docs).\n\t\t *\n\t\t * @type {object}\n\t\t */\n\t\tconfig: {\n\t\t\ttype: Object,\n\t\t\tdefault: () => ({}),\n\t\t},\n\n\t\t/** The record's id, for the `@objectId` token. */\n\t\tobjectId: {\n\t\t\ttype: [String, Number],\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * The record, when the host has it: the summary and facts read it.\n\t\t *\n\t\t * @type {object|null}\n\t\t */\n\t\tobject: {\n\t\t\ttype: Object,\n\t\t\tdefault: null,\n\t\t},\n\t},\n\n\temits: ['close', 'done'],\n\n\tdata() {\n\t\treturn {\n\t\t\trecord: this.object,\n\t\t\titems: [],\n\t\t\tchecklistError: '',\n\t\t\tallowed: true,\n\t\t\treason: '',\n\t\t\tvalues: {},\n\t\t\tbusy: false,\n\t\t\trefusal: '',\n\t\t\tdone: false,\n\t\t\treasonId: `cn-action-dialog-reason-${++reasonSeq}`,\n\t\t}\n\t},\n\n\tcomputed: {\n\t\t/** @return {object} The token context. */\n\t\ttokenCtx() {\n\t\t\treturn { objectId: this.recordId, object: this.record || {} }\n\t\t},\n\n\t\t/**\n\t\t * The record's id: `objectId`, or the route's `id` when the prop is\n\t\t * empty or a token the opener could not resolve.\n\t\t *\n\t\t * @return {string|number}\n\t\t */\n\t\trecordId() {\n\t\t\tconst given = this.objectId\n\t\t\tif (given !== '' && given !== null && given !== undefined && !String(given).startsWith('@')) {\n\t\t\t\treturn given\n\t\t\t}\n\t\t\treturn (this.$route && this.$route.params && this.$route.params.id) || ''\n\t\t},\n\n\t\t/** @return {object} The confirm config. */\n\t\tconfirmConfig() {\n\t\t\treturn this.config.confirm && typeof this.config.confirm === 'object' ? this.config.confirm : {}\n\t\t},\n\n\t\t/**\n\t\t * The summary row, or null without one or before the record is known.\n\t\t *\n\t\t * @spec openspec/changes/action-dialog/specs/action-dialog/spec.md#requirement-a-manifest-configures-an-action-dialog\n\t\t * @return {{title: string, meta: string, badge: string}|null}\n\t\t */\n\t\tsummary() {\n\t\t\tconst def = this.config.summary\n\t\t\tif (!def || !this.record) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst title = this.fill(def.title)\n\t\t\treturn title ? { title, meta: this.fill(def.meta), badge: this.fill(def.badge) } : null\n\t\t},\n\n\t\t/** @return {Array<{title: string, facts: Array<{label: string, value: string}>}>} The fact groups. */\n\t\tfactSections() {\n\t\t\tif (!Array.isArray(this.config.facts) || !this.record) {\n\t\t\t\treturn []\n\t\t\t}\n\t\t\tconst empty = t('nextcloud-vue', 'Not set')\n\t\t\treturn this.config.facts.map((section) => ({\n\t\t\t\ttitle: this.text(section.title),\n\t\t\t\tfacts: (Array.isArray(section.items) ? section.items : []).map((fact) => ({ label: this.text(fact.label), value: this.fill(fact.value) || empty })),\n\t\t\t}))\n\t\t},\n\n\t\t/**\n\t\t * The checklist rows: label and detail from `labels` by id, else the item's own.\n\t\t *\n\t\t * @spec openspec/changes/action-dialog/specs/action-dialog/spec.md#requirement-a-manifest-configures-an-action-dialog\n\t\t * @return {Array<{id: string, met: (boolean|null), label: string, detail: string}>}\n\t\t */\n\t\tchecklist() {\n\t\t\tconst labels = (this.config.checklist && this.config.checklist.labels) || {}\n\t\t\treturn this.items.map((item) => {\n\t\t\t\tconst met = item.met === null || item.met === undefined ? null : item.met === true\n\t\t\t\tconst own = labels[item.id] || {}\n\t\t\t\tconst detail = met === false && own.unmetDetail ? own.unmetDetail : (own.detail || item.detail || '')\n\t\t\t\treturn {\n\t\t\t\t\tid: String(item.id),\n\t\t\t\t\tmet,\n\t\t\t\t\tlabel: this.fill(own.label || item.label || String(item.id), item),\n\t\t\t\t\tdetail: met === null && !item.detail ? t('nextcloud-vue', 'Could not be read') : this.fill(detail, item),\n\t\t\t\t}\n\t\t\t})\n\t\t},\n\n\t\t/** @return {boolean} Whether every required item is met. */\n\t\trequiredMet() {\n\t\t\tconst required = (this.config.checklist && Array.isArray(this.config.checklist.required)) ? this.config.checklist.required.map(String) : []\n\t\t\treturn required.every((id) => this.items.some((item) => String(item.id) === id && item.met === true))\n\t\t},\n\n\t\t/** @return {boolean} Whether a reason is asked and needed. */\n\t\treasonNeeded() {\n\t\t\treturn Boolean(this.config.reason) && this.config.reason.required !== false\n\t\t},\n\n\t\t/** @return {string} The reason field's label. */\n\t\treasonLabel() {\n\t\t\treturn this.text(this.config.reason && this.config.reason.label) || t('nextcloud-vue', 'Reason')\n\t\t},\n\n\t\t/** @return {string} The note's NcNoteCard type. */\n\t\tnoteType() {\n\t\t\tconst variant = this.config.note && this.config.note.variant\n\t\t\treturn ['info', 'warning', 'error', 'success'].includes(variant) ? variant : 'info'\n\t\t},\n\n\t\t/**\n\t\t * Whether the action may run: allowed, required items met, a reason\n\t\t * when one is needed, and nothing in flight.\n\t\t *\n\t\t * @spec openspec/changes/action-dialog/specs/action-dialog/spec.md#requirement-a-manifest-configures-an-action-dialog\n\t\t * @return {boolean}\n\t\t */\n\t\tcanConfirm() {\n\t\t\treturn !this.busy && this.allowed && this.requiredMet && this.fieldsFilled && (!this.reasonNeeded || this.reason.trim() !== '')\n\t\t},\n\n\t\t/** @return {string} The eyebrow, filled from the record once it is known. */\n\t\teyebrowText() {\n\t\t\treturn this.record ? this.fill(this.config.eyebrow) || this.text(this.config.eyebrow) : this.text(this.config.eyebrow)\n\t\t},\n\n\t\t/** @return {Array<object>} The fields with a name. */\n\t\tfields() {\n\t\t\treturn (Array.isArray(this.config.fields) ? this.config.fields : []).filter((f) => f && f.field)\n\t\t},\n\n\t\t/**\n\t\t * Whether every required field has a value.\n\t\t *\n\t\t * @spec openspec/changes/action-dialog-fields-and-acts/specs/action-dialog/spec.md#requirement-an-action-dialog-asks-for-fields-and-reads-a-permission-from-a-list\n\t\t * @return {boolean}\n\t\t */\n\t\tfieldsFilled() {\n\t\t\treturn this.fields.every((f) => f.required === false || String(this.values[f.field] ?? '').trim() !== '')\n\t\t},\n\t},\n\n\tasync mounted() {\n\t\tawait Promise.all([this.loadRecord(), this.loadChecklist(), this.loadPermission()])\n\t},\n\n\tmethods: {\n\t\tt,\n\n\t\t/**\n\t\t * A config text through the host translate, '' for anything else.\n\t\t *\n\t\t * @param {unknown} value The text.\n\t\t * @return {string}\n\t\t */\n\t\ttext(value) {\n\t\t\treturn typeof value === 'string' && value !== '' ? this.cnTranslate(value) : ''\n\t\t},\n\n\t\t/**\n\t\t * A template filled from a row (the record by default), translated first.\n\t\t *\n\t\t * @param {unknown} template The template.\n\t\t * @param {object} [row] The row.\n\t\t * @return {string}\n\t\t */\n\t\tfill(template, row) {\n\t\t\tif (typeof template !== 'string' || template === '') {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t\treturn fillTemplate(this.cnTranslate(template), row || this.record || {}).trim()\n\t\t},\n\n\t\t/**\n\t\t * Read an endpoint, fresh.\n\t\t *\n\t\t * @param {object} source An endpointSource block.\n\t\t * @return {Promise<unknown>}\n\t\t */\n\t\tread(source) {\n\t\t\treturn fetchEndpointSource(source, this.tokenCtx, { fresh: true })\n\t\t},\n\n\t\t/** @return {Promise<void>} */\n\t\tasync loadRecord() {\n\t\t\tconst source = this.config.summary && this.config.summary.source\n\t\t\tif (!source || !source.url) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst data = await this.read(source)\n\t\t\t\tthis.record = data && typeof data === 'object' ? data : this.record\n\t\t\t} catch {\n\t\t\t\t// The summary stays empty; the checklist and the action still work.\n\t\t\t}\n\t\t},\n\n\t\t/** @return {Promise<void>} */\n\t\tasync loadChecklist() {\n\t\t\tconst def = this.config.checklist\n\t\t\tif (!def || !def.source || !def.source.url) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst data = await this.read(def.source)\n\t\t\t\tconst list = def.itemsPath ? readPath(data, def.itemsPath) : data\n\t\t\t\tthis.items = Array.isArray(list) ? list.filter((item) => item && item.id !== undefined) : []\n\t\t\t} catch {\n\t\t\t\tthis.items = []\n\t\t\t\tthis.checklistError = t('nextcloud-vue', 'Whether this is ready could not be read.')\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * The entry of a list whose fields equal `match`, or null.\n\t\t *\n\t\t * @param {unknown} list The list.\n\t\t * @param {object} [match] The fields to match.\n\t\t * @return {object|null}\n\t\t */\n\t\tmatchIn(list, match) {\n\t\t\tconst wanted = Object.entries(match || {})\n\t\t\treturn (Array.isArray(list) ? list : []).find((entry) => entry && wanted.every(([key, value]) => String(entry[key]) === String(value))) || null\n\t\t},\n\n\t\t/**\n\t\t * A select field's options, labels translated.\n\t\t *\n\t\t * @param {object} field The field.\n\t\t * @return {Array<{id: string, label: string, fills?: object}>}\n\t\t */\n\t\toptionsOf(field) {\n\t\t\treturn (Array.isArray(field.options) ? field.options : []).map((o) => ({ id: String(o.value), label: this.text(o.label) || String(o.value), fills: o.fills }))\n\t\t},\n\n\t\t/**\n\t\t * A select field's chosen option.\n\t\t *\n\t\t * @param {object} field The field.\n\t\t * @return {object|null}\n\t\t */\n\t\tselectedOption(field) {\n\t\t\treturn this.optionsOf(field).find((o) => o.id === String(this.values[field.field] ?? '')) || null\n\t\t},\n\n\t\t/**\n\t\t * Set a field's value.\n\t\t *\n\t\t * @param {string} name The field.\n\t\t * @param {unknown} value The value.\n\t\t */\n\t\tsetValue(name, value) {\n\t\t\tthis.values = { ...this.values, [name]: value === null || value === undefined ? '' : String(value) }\n\t\t},\n\n\t\t/**\n\t\t * Choose a select option; its `fills` set the fields still empty.\n\t\t *\n\t\t * @param {object} field The select field.\n\t\t * @param {{id: string, fills?: object}|null} option The option.\n\t\t */\n\t\tpick(field, option) {\n\t\t\tthis.setValue(field.field, option ? option.id : '')\n\t\t\tfor (const [name, value] of Object.entries((option && option.fills) || {})) {\n\t\t\t\tif (String(this.values[name] ?? '').trim() === '') {\n\t\t\t\t\tthis.setValue(name, this.text(value) || value)\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t/** @return {Promise<void>} */\n\t\tasync loadPermission() {\n\t\t\tconst def = this.config.permission\n\t\t\tif (!def || !def.source || !def.source.url) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst data = await this.read(def.source)\n\t\t\t\tconst entry = def.listPath ? this.matchIn(readPath(data, def.listPath), def.match) : data\n\t\t\t\tthis.allowed = readPath(entry, def.allowedPath || 'allowed') === true\n\t\t\t\tthis.refusal = this.allowed || !def.reasonPath ? '' : String(readPath(entry, def.reasonPath) || '')\n\t\t\t} catch {\n\t\t\t\tthis.allowed = false\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Run the action once: post `confirm.request`, or dispatch\n\t\t * `confirm.action`, then show the done text and refresh the page.\n\t\t *\n\t\t * @spec openspec/changes/action-dialog/specs/action-dialog/spec.md#requirement-a-manifest-configures-an-action-dialog\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync confirm() {\n\t\t\tif (!this.canConfirm) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.busy = true\n\t\t\tthis.refusal = ''\n\t\t\tconst reason = this.reason.trim()\n\t\t\ttry {\n\t\t\t\tconst request = this.confirmConfig.request\n\t\t\t\tif (request && request.url) {\n\t\t\t\t\tconst url = interpolateUrlTokens(request.url, this.tokenCtx)\n\t\t\t\t\tconst body = {}\n\t\t\t\t\tfor (const [key, value] of Object.entries(request.body || {})) {\n\t\t\t\t\t\tbody[key] = typeof value === 'string' ? fillTemplate(value, { ...(this.record || {}), reason }) : value\n\t\t\t\t\t}\n\t\t\t\t\tif (this.config.reason) {\n\t\t\t\t\t\tbody[this.config.reason.field || 'reason'] = reason\n\t\t\t\t\t}\n\t\t\t\t\tfor (const field of this.fields) {\n\t\t\t\t\t\tbody[field.field] = this.values[field.field] ?? ''\n\t\t\t\t\t}\n\t\t\t\t\tconst method = String(request.method || 'POST').toLowerCase()\n\t\t\t\t\tawait axios[['post', 'put', 'patch', 'delete'].includes(method) ? method : 'post'](/^https?:\\/\\//i.test(url) ? url : generateUrl(url), body)\n\t\t\t\t} else if (this.confirmConfig.action && typeof this.cnDispatchAction === 'function') {\n\t\t\t\t\tawait this.cnDispatchAction({ ...this.confirmConfig.action, args: [...(this.confirmConfig.action.args || []), { ...this.values, reason }] })\n\t\t\t\t}\n\t\t\t\tthis.done = true\n\t\t\t\temit(PAGE_REFRESH, {})\n\t\t\t\t/** @event done The action ran. Payload: the field values and `reason`. */\n\t\t\t\tthis.$emit('done', { ...this.values, reason })\n\t\t\t} catch (failure) {\n\t\t\t\tconst data = failure && failure.response && failure.response.data\n\t\t\t\tthis.refusal = String((data && (data.message || data.error)) || t('nextcloud-vue', 'The action could not be completed.'))\n\t\t\t} finally {\n\t\t\t\tthis.busy = false\n\t\t\t}\n\t\t},\n\n\t\t/** Close the dialog, unless the action is running. */\n\t\tclose() {\n\t\t\tif (this.busy) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\t/** @event close The dialog was closed. */\n\t\t\tthis.$emit('close')\n\t\t},\n\t},\n}\n</script>\n\n<style scoped>\n.cn-action-dialog {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 16px;\n}\n\n.cn-action-dialog__summary {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 10px;\n\tpadding: 12px 14px;\n\tborder: 1px solid var(--color-border);\n\tborder-radius: var(--border-radius-large, 8px);\n}\n\n.cn-action-dialog__summary-text {\n\tdisplay: flex;\n\tflex: 1 1 auto;\n\tflex-direction: column;\n\tmin-width: 0;\n}\n\n.cn-action-dialog__badge {\n\tpadding: 3px 10px;\n\tborder-radius: 12px;\n\tbackground: var(--color-background-dark);\n\tfont-size: 13px;\n\tfont-weight: 600;\n\twhite-space: nowrap;\n}\n\n.cn-action-dialog__title {\n\tmargin: 0 0 8px;\n\tfont-size: 15px;\n\tfont-weight: 700;\n}\n\n.cn-action-dialog__facts {\n\tdisplay: grid;\n\tgrid-template-columns: repeat(auto-fit, minmax(180px, 1fr));\n\tgap: 8px 16px;\n\tmargin: 0;\n}\n\n.cn-action-dialog__facts dt {\n\tcolor: var(--color-text-maxcontrast);\n\tfont-size: 13px;\n}\n\n.cn-action-dialog__facts dd {\n\tmargin: 0;\n}\n\n.cn-action-dialog__checks {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 8px;\n\tmargin: 0;\n\tpadding: 0;\n\tlist-style: none;\n}\n\n.cn-action-dialog__check {\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\talign-items: center;\n\tgap: 8px;\n}\n\n.cn-action-dialog__check-icon {\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-action-dialog__check-icon--met {\n\tcolor: var(--color-success-text, var(--color-success));\n}\n\n.cn-action-dialog__muted {\n\tcolor: var(--color-text-maxcontrast);\n\tfont-size: 14px;\n}\n\n.cn-action-dialog__field {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 4px;\n}\n\n.cn-action-dialog__error {\n\tmargin: 0;\n\tcolor: var(--color-error-text, var(--color-error));\n}\n</style>\n"],"names":["CnDialog","CnIcon","t","axios"],"mappings":";;;;;;;;;;;;;;AAkJA;AACA,MAAM,YAAW,GAAI,kBAAgB;;AAErC;AACA,IAAI,SAAQ,GAAI,EAAA;;AAEhB;AACC;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;;AAGA;;;;AAIA;;;AAGA;AACA;;;;AAIA;AACA;;AAEA;;;AAGA;;;AAGD,aAAe;AACd,CAAA,IAAI,EAAE,gBAAgB;;CAEtB,UAAU,EAAE,EAAE,WAAW,EAAE,aAAa,YAAEA,UAAQ,UAAEC,YAAM,EAAE,iBAAiB,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAU,EAAG;;AAExI,CAAA,MAAM,EAAE;;AAEP,EAAA,WAAW,EAAE,EAAE,OAAO,EAAE,MAAM,CAAC,GAAG,KAAK,KAAK;AAC5C;AACA,EAAA,gBAAgB,EAAE,EAAE,OAAO,EAAE,MAAM;EACnC;;AAED,CAAA,KAAK,EAAE;AACN;;AAEC;;;AAGD,EAAA,MAAM,EAAE;GACP,IAAI,EAAE,MAAM;AACZ,GAAA,OAAO,EAAE,OAAO,EAAE,CAAC;GACnB;;AAED;AACA,EAAA,QAAQ,EAAE;AACT,GAAA,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;GACtB,OAAO,EAAE,EAAE;GACX;;AAED;;AAEC;AACA;;AAED,EAAA,MAAM,EAAE;GACP,IAAI,EAAE,MAAM;GACZ,OAAO,EAAE,IAAI;GACb;EACD;;CAED,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC;;AAExB,CAAA,IAAI,GAAG;AACN,EAAA,OAAO;AACN,GAAA,MAAM,EAAE,IAAI,CAAC,MAAM;AACnB,GAAA,KAAK,EAAE,EAAE;AACT,GAAA,cAAc,EAAE,EAAE;GAClB,OAAO,EAAE,IAAI;AACb,GAAA,MAAM,EAAE,EAAE;AACV,GAAA,MAAM,EAAE,EAAE;GACV,IAAI,EAAE,KAAK;GACX,OAAO,EAAE,EAAE;GACX,IAAI,EAAE,KAAK;GACX,QAAQ,EAAE,CAAC,wBAAwB,EAAE,EAAE,SAAS,CAAC,CAAC;AACnD,GAAA;EACA;;AAED,CAAA,QAAQ,EAAE;AACT;EACA,QAAQ,GAAG;GACV,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,MAAO,IAAG,EAAG,EAAA;GAC5D;;AAED;;AAEC;AACA;;;EAGD,QAAQ,GAAG;GACV,MAAM,KAAM,GAAE,IAAI,CAAC,SAAO;AAC1B,GAAA,IAAI,KAAM,KAAI,EAAG,IAAG,KAAM,KAAI,QAAQ,KAAI,KAAM,SAAQ,IAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE;IAC5F,OAAO,KAAI;AACZ,IAAA;AACA,GAAA,OAAO,CAAC,IAAI,CAAC,MAAO,IAAG,IAAI,CAAC,MAAM,CAAC,MAAK,IAAK,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,KAAK,EAAC;GACxE;;AAED;AACA,EAAA,aAAa,GAAG;AACf,GAAA,OAAO,IAAI,CAAC,MAAM,CAAC,OAAM,IAAK,OAAO,IAAI,CAAC,MAAM,CAAC,OAAQ,KAAI,QAAS,GAAE,IAAI,CAAC,MAAM,CAAC,OAAM,GAAI,EAAC;GAC/F;;AAED;;AAEC;;;;AAID,EAAA,OAAO,GAAG;GACT,MAAM,GAAI,GAAE,IAAI,CAAC,MAAM,CAAC,QAAM;GAC9B,IAAI,CAAC,GAAI,IAAG,CAAC,IAAI,CAAC,MAAM,EAAE;AACzB,IAAA,OAAO,IAAG;AACX,IAAA;AACA,GAAA,MAAM,KAAM,GAAE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAA;AACjC,GAAA,OAAO,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAE,EAAA,GAAI,IAAG;GACtF;;AAED;AACA,EAAA,YAAY,GAAG;GACd,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAA,IAAK,CAAC,IAAI,CAAC,MAAM,EAAE;AACtD,IAAA,OAAO,EAAC;AACT,IAAA;AACA,GAAA,MAAM,KAAI,GAAIC,SAAC,CAAC,eAAe,EAAE,SAAS,EAAA;AAC1C,GAAA,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,OAAO,MAAM;AAC1C,IAAA,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;AAC/B,IAAA,KAAK,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAE,GAAE,OAAO,CAAC,KAAI,GAAI,EAAE,EAAE,GAAG,CAAC,CAAC,IAAI,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAA,IAAK,KAAM,EAAC,CAAC,CAAC;AACpJ,IAAC,CAAC,CAAA;GACF;;AAED;AACC;AACA;;AAEA;;EAED,SAAS,GAAG;AACX,GAAA,MAAM,MAAK,GAAI,CAAC,IAAI,CAAC,MAAM,CAAC,SAAQ,IAAK,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,KAAK,GAAC;GAC3E,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK;AAC/B,IAAA,MAAM,GAAI,GAAE,IAAI,CAAC,GAAI,KAAI,IAAG,IAAK,IAAI,CAAC,GAAI,KAAI,SAAU,GAAE,IAAK,GAAE,IAAI,CAAC,GAAE,KAAM,KAAG;IACjF,MAAM,GAAI,GAAE,MAAM,CAAC,IAAI,CAAC,EAAE,CAAA,IAAK,GAAC;AAChC,IAAA,MAAM,MAAK,GAAI,QAAQ,SAAS,GAAG,CAAC,cAAc,GAAG,CAAC,eAAe,GAAG,CAAC,MAAO,IAAG,IAAI,CAAC,UAAU,EAAE,EAAA;AACpG,IAAA,OAAO;AACN,KAAA,EAAE,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;AACnB,KAAA,GAAG;KACH,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAM,IAAG,IAAI,CAAC,KAAI,IAAK,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC;AAClE,KAAA,MAAM,EAAE,GAAE,KAAM,QAAQ,CAAC,IAAI,CAAC,SAASA,SAAC,CAAC,eAAe,EAAE,mBAAmB,CAAE,GAAE,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC;AACzG,KAAA;IACA,CAAA;GACD;;;EAGD,WAAW,GAAG;AACb,GAAA,MAAM,QAAO,GAAI,CAAC,IAAI,CAAC,MAAM,CAAC,SAAU,IAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAA,GAAI,GAAC;AAC1I,GAAA,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,IAAI,CAAC,EAAE,CAAE,KAAI,EAAG,IAAG,IAAI,CAAC,GAAE,KAAM,IAAI,CAAC,CAAA;GACpG;;;AAGD,EAAA,YAAY,GAAG;AACd,GAAA,OAAO,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAE,IAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,QAAS,KAAI,KAAI;GAC1E;;AAED;EACA,WAAW,GAAG;AACb,GAAA,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAO,IAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAA,IAAKA,SAAC,CAAC,eAAe,EAAE,QAAQ,CAAA;GAC/F;;AAED;EACA,QAAQ,GAAG;GACV,MAAM,OAAQ,GAAE,IAAI,CAAC,MAAM,CAAC,IAAK,IAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,QAAM;AAC3D,GAAA,OAAO,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAA,GAAI,UAAU,MAAK;GAClF;;AAED;;AAEC;AACA;;AAEA;;EAED,UAAU,GAAG;GACZ,OAAO,CAAC,IAAI,CAAC,IAAG,IAAK,IAAI,CAAC,OAAM,IAAK,IAAI,CAAC,WAAU,IAAK,IAAI,CAAC,YAAa,KAAI,CAAC,IAAI,CAAC,YAAW,IAAK,IAAI,CAAC,MAAM,CAAC,IAAI,EAAC,KAAM,EAAE,CAAA;GAC9H;;AAED;EACA,WAAW,GAAG;GACb,OAAO,IAAI,CAAC,MAAO,GAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAA,IAAK,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAE,GAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAA;GACrH;;AAED;AACA,EAAA,MAAM,GAAG;AACR,GAAA,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAA,GAAI,IAAI,CAAC,MAAM,CAAC,MAAK,GAAI,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,KAAK,CAAE,IAAG,CAAC,CAAC,KAAK,CAAA;GAC/F;;AAED;AACC;AACA;AACA;AACA;;AAED,EAAA,YAAY,GAAG;AACd,GAAA,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,QAAS,KAAI,SAAS,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAA,IAAK,EAAE,CAAC,CAAC,IAAI,EAAC,KAAM,EAAE,CAAA;GACxG;EACD;;AAED,CAAA,MAAM,OAAO,GAAG;AACf,EAAA,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,IAAI,CAAC,aAAa,EAAE,EAAE,IAAI,CAAC,cAAc,EAAE,CAAC,EAAA;EAClF;;AAED,CAAA,OAAO,EAAE;KACRA,SAAC;;AAED;;AAEC;;AAEA;;EAED,IAAI,CAAC,KAAK,EAAE;AACX,GAAA,OAAO,OAAO,KAAM,KAAI,QAAO,IAAK,KAAI,KAAM,EAAG,GAAE,IAAI,CAAC,WAAW,CAAC,KAAK,CAAA,GAAI,EAAC;GAC9E;;AAED;;AAEC;AACA;;AAEA;;AAED,EAAA,IAAI,CAAC,QAAQ,EAAE,GAAG,EAAE;AACnB,GAAA,IAAI,OAAO,aAAa,YAAY,QAAS,KAAI,EAAE,EAAE;AACpD,IAAA,OAAO,EAAC;AACT,IAAA;AACA,GAAA,OAAO,YAAY,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,EAAE,GAAI,IAAG,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,IAAI,EAAC;GAC/E;;AAED;AACC;AACA;AACA;;;EAGD,IAAI,CAAC,MAAM,EAAE;GACZ,OAAO,mBAAmB,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,IAAG,EAAG,CAAA;GACjE;;;AAGD,EAAA,MAAM,UAAU,GAAG;GAClB,MAAM,MAAO,GAAE,IAAI,CAAC,MAAM,CAAC,OAAQ,IAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,OAAK;GAC/D,IAAI,CAAC,MAAK,IAAK,CAAC,MAAM,CAAC,GAAG,EAAE;IAC3B,MAAK;AACN,IAAA;AACA,GAAA,IAAI;AACH,IAAA,MAAM,IAAG,GAAI,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,EAAA;IACnC,IAAI,CAAC,MAAK,GAAI,IAAG,IAAK,OAAO,SAAS,QAAO,GAAI,IAAG,GAAI,IAAI,CAAC,OAAK;AACnE,IAAA,CAAE,MAAM;;AAER,IAAA;GACA;;;AAGD,EAAA,MAAM,aAAa,GAAG;GACrB,MAAM,GAAE,GAAI,IAAI,CAAC,MAAM,CAAC,UAAQ;AAChC,GAAA,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAO,IAAG,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE;IAC3C,MAAK;AACN,IAAA;AACA,GAAA,IAAI;AACH,IAAA,MAAM,IAAK,GAAE,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAA;IACvC,MAAM,IAAG,GAAI,GAAG,CAAC,SAAU,GAAE,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAC,SAAS,CAAE,GAAE,KAAG;AAChE,IAAA,IAAI,CAAC,KAAM,GAAE,KAAK,CAAC,OAAO,CAAC,IAAI,CAAE,GAAE,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,KAAK,IAAK,IAAG,IAAI,CAAC,EAAC,KAAM,SAAS,CAAA,GAAI,GAAC;AAC5F,IAAA,CAAE,MAAM;IACP,IAAI,CAAC,KAAM,GAAE,GAAC;AACd,IAAA,IAAI,CAAC,cAAa,GAAIA,SAAC,CAAC,eAAe,EAAE,0CAA0C,EAAA;AACpF,IAAA;GACA;;AAED;;AAEC;;AAEA;AACA;;AAED,EAAA,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE;AACpB,GAAA,MAAM,SAAS,MAAM,CAAC,OAAO,CAAC,KAAI,IAAK,EAAE,EAAA;AACzC,GAAA,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAE,GAAE,IAAG,GAAI,EAAE,EAAE,IAAI,CAAC,CAAC,KAAK,KAAK,KAAI,IAAK,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,KAAK,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA,KAAM,MAAM,CAAC,KAAK,CAAC,CAAC,CAAA,IAAK,IAAG;GAC9I;;AAED;AACC;AACA;;;;AAID,EAAA,SAAS,CAAC,KAAK,EAAE;AAChB,GAAA,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAE,GAAE,KAAK,CAAC,OAAM,GAAI,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAA,IAAK,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,KAAI,EAAG,CAAC,CAAA;GAC7J;;AAED;;AAEC;;AAEA;;AAED,EAAA,cAAc,CAAC,KAAK,EAAE;AACrB,GAAA,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAG,KAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAA,IAAK,EAAE,CAAC,CAAA,IAAK,IAAG;GAChG;;AAED;AACC;AACA;;;;AAID,EAAA,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE;AACrB,GAAA,IAAI,CAAC,MAAK,GAAI,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,GAAG,KAAM,KAAI,IAAK,IAAG,UAAU,SAAU,GAAE,EAAG,GAAE,MAAM,CAAC,KAAK,CAAE,GAAA;GACnG;;AAED;;AAEC;AACA;;;AAGD,EAAA,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE;AACnB,GAAA,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,EAAE,SAAS,MAAM,CAAC,EAAG,GAAE,EAAE,EAAA;AAClD,GAAA,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAE,IAAG,MAAM,CAAC,OAAO,CAAC,CAAC,MAAK,IAAK,MAAM,CAAC,KAAK,KAAK,EAAE,CAAC,EAAE;AAC3E,IAAA,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAE,IAAG,EAAE,CAAC,CAAC,IAAI,EAAG,KAAI,EAAE,EAAE;AAClD,KAAA,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,KAAK,KAAK,EAAA;AAC9C,KAAA;AACD,IAAA;GACA;;;AAGD,EAAA,MAAM,cAAc,GAAG;AACtB,GAAA,MAAM,GAAI,GAAE,IAAI,CAAC,MAAM,CAAC,WAAS;AACjC,GAAA,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAO,IAAG,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE;IAC3C,MAAK;AACN,IAAA;AACA,GAAA,IAAI;AACH,IAAA,MAAM,IAAK,GAAE,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAA;AACvC,IAAA,MAAM,KAAM,GAAE,GAAG,CAAC,QAAS,GAAE,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAC,QAAQ,CAAC,EAAE,GAAG,CAAC,KAAK,IAAI,KAAG;IACxF,IAAI,CAAC,OAAM,GAAI,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC,WAAY,IAAG,SAAS,CAAE,KAAI,KAAG;AACpE,IAAA,IAAI,CAAC,OAAM,GAAI,IAAI,CAAC,OAAQ,IAAG,CAAC,GAAG,CAAC,UAAW,GAAE,EAAC,GAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC,UAAU,KAAK,EAAE,EAAA;AACnG,IAAA,CAAE,MAAM;AACP,IAAA,IAAI,CAAC,OAAQ,GAAE,MAAI;AACpB,IAAA;GACA;;AAED;;;AAGC;;;;AAID,EAAA,MAAM,OAAO,GAAG;AACf,GAAA,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE;IACrB,MAAK;AACN,IAAA;GACA,IAAI,CAAC,IAAK,GAAE,KAAG;AACf,GAAA,IAAI,CAAC,OAAQ,GAAE,GAAC;GAChB,MAAM,MAAO,GAAE,IAAI,CAAC,MAAM,CAAC,IAAI,GAAC;AAChC,GAAA,IAAI;AACH,IAAA,MAAM,UAAU,IAAI,CAAC,aAAa,CAAC,QAAM;IACzC,IAAI,OAAM,IAAK,OAAO,CAAC,GAAG,EAAE;KAC3B,MAAM,GAAI,GAAE,oBAAoB,CAAC,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,QAAQ,EAAA;KAC3D,MAAM,IAAK,GAAE,GAAC;KACd,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAA,IAAK,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,IAAK,IAAG,EAAE,CAAC,EAAE;AAC9D,MAAA,IAAI,CAAC,GAAG,CAAE,GAAE,OAAO,KAAI,KAAM,QAAO,GAAI,YAAY,CAAC,KAAK,EAAE,EAAE,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC,EAAE,QAAQ,CAAA,GAAI,MAAI;AACvG,MAAA;KACA,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE;MACvB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,KAAI,IAAK,QAAQ,CAAE,GAAE,OAAK;AACnD,MAAA;KACA,KAAK,MAAM,KAAI,IAAK,IAAI,CAAC,MAAM,EAAE;AAChC,MAAA,IAAI,CAAC,KAAK,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAE,IAAG,GAAC;AAClD,MAAA;KACA,MAAM,MAAK,GAAI,MAAM,CAAC,OAAO,CAAC,MAAO,IAAG,MAAM,CAAC,CAAC,WAAW,GAAC;AAC5D,KAAA,MAAMC,cAAK,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAA,GAAI,MAAO,GAAE,MAAM,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC,GAAG,CAAE,GAAE,GAAI,GAAE,WAAW,CAAC,GAAG,CAAC,EAAE,IAAI,EAAA;AAC5I,KAAA,MAAO,IAAI,IAAI,CAAC,aAAa,CAAC,MAAK,IAAK,OAAO,IAAI,CAAC,gBAAe,KAAM,UAAU,EAAE;AACpF,KAAA,MAAM,IAAI,CAAC,gBAAgB,CAAC,EAAE,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,IAAK,IAAG,EAAE,CAAC,EAAE,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,MAAO,EAAC,GAAG,EAAA;AAC5I,KAAA;IACA,IAAI,CAAC,IAAK,GAAE,KAAG;AACf,IAAA,IAAI,CAAC,YAAY,EAAE,EAAE,EAAA;;AAErB,IAAA,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAA;AAC9C,IAAA,CAAE,OAAO,OAAO,EAAE;IACjB,MAAM,IAAG,GAAI,OAAQ,IAAG,OAAO,CAAC,QAAO,IAAK,OAAO,CAAC,QAAQ,CAAC,KAAG;IAChE,IAAI,CAAC,OAAM,GAAI,MAAM,CAAC,CAAC,IAAK,KAAI,IAAI,CAAC,WAAW,IAAI,CAAC,KAAK,CAAC,KAAKD,SAAC,CAAC,eAAe,EAAE,oCAAoC,CAAC,EAAA;AACzH,IAAA,SAAU;AACT,IAAA,IAAI,CAAC,IAAG,GAAI,MAAI;AACjB,IAAA;GACA;;AAED;AACA,EAAA,KAAK,GAAG;GACP,IAAI,IAAI,CAAC,IAAI,EAAE;IACd,MAAK;AACN,IAAA;AACA;AACA,GAAA,IAAI,CAAC,KAAK,CAAC,OAAO,EAAA;GAClB;EACD;AACF;;;;"}
@@ -44,21 +44,22 @@ const _hoisted_14 = {
44
44
  key: 3,
45
45
  class: "cn-action-dialog__muted"
46
46
  };
47
- const _hoisted_15 = {
47
+ const _hoisted_15 = ["data-testid"];
48
+ const _hoisted_16 = {
48
49
  key: 2,
49
50
  class: "cn-action-dialog__field"
50
51
  };
51
- const _hoisted_16 = {
52
+ const _hoisted_17 = {
52
53
  key: 0,
53
54
  class: "cn-action-dialog__muted"
54
55
  };
55
- const _hoisted_17 = {
56
+ const _hoisted_18 = {
56
57
  key: 4,
57
58
  class: "cn-action-dialog__error",
58
59
  role: "alert",
59
60
  "data-testid": "cn-action-dialog-refusal"
60
61
  };
61
- const _hoisted_18 = {
62
+ const _hoisted_19 = {
62
63
  key: 1,
63
64
  role: "status",
64
65
  "data-testid": "cn-action-dialog-done"
@@ -69,6 +70,8 @@ function render(_ctx, _cache, $props, $setup, $data, $options) {
69
70
  const _component_CheckCircle = resolveComponent("CheckCircle");
70
71
  const _component_HelpCircleOutline = resolveComponent("HelpCircleOutline");
71
72
  const _component_CircleOutline = resolveComponent("CircleOutline");
73
+ const _component_NcSelect = resolveComponent("NcSelect");
74
+ const _component_NcTextField = resolveComponent("NcTextField");
72
75
  const _component_NcTextArea = resolveComponent("NcTextArea");
73
76
  const _component_NcNoteCard = resolveComponent("NcNoteCard");
74
77
  const _component_NcButton = resolveComponent("NcButton");
@@ -76,7 +79,7 @@ function render(_ctx, _cache, $props, $setup, $data, $options) {
76
79
 
77
80
  return (openBlock(), createBlock(_component_CnDialog, {
78
81
  name: $options.text($props.config.title) || $options.t('nextcloud-vue', 'Confirm'),
79
- eyebrow: $options.text($props.config.eyebrow),
82
+ eyebrow: $options.eyebrowText,
80
83
  subtitle: $options.text($props.config.subtitle),
81
84
  width: "form",
82
85
  noClose: $data.busy,
@@ -206,8 +209,32 @@ function render(_ctx, _cache, $props, $setup, $data, $options) {
206
209
  ])
207
210
  ]))
208
211
  : createCommentVNode("v-if", true),
212
+ (openBlock(true), createElementBlock(Fragment, null, renderList($options.fields, (field) => {
213
+ return (openBlock(), createElementBlock("div", {
214
+ key: field.field,
215
+ class: "cn-action-dialog__field",
216
+ "data-testid": `cn-action-dialog-field-${field.field}`
217
+ }, [
218
+ (field.type === 'select')
219
+ ? (openBlock(), createBlock(_component_NcSelect, {
220
+ key: 0,
221
+ modelValue: $options.selectedOption(field),
222
+ options: $options.optionsOf(field),
223
+ inputLabel: $options.text(field.label) || field.field,
224
+ clearable: field.required === false,
225
+ "onUpdate:modelValue": (option) => $options.pick(field, option)
226
+ }, null, 8 /* PROPS */, ["modelValue", "options", "inputLabel", "clearable", "onUpdate:modelValue"]))
227
+ : (openBlock(), createBlock(_component_NcTextField, {
228
+ key: 1,
229
+ modelValue: $data.values[field.field] || '',
230
+ type: field.type === 'datetime' ? 'datetime-local' : (field.type === 'date' ? 'date' : 'text'),
231
+ label: $options.text(field.label) || field.field,
232
+ "onUpdate:modelValue": (value) => $options.setValue(field.field, value)
233
+ }, null, 8 /* PROPS */, ["modelValue", "type", "label", "onUpdate:modelValue"]))
234
+ ], 8 /* PROPS */, _hoisted_15))
235
+ }), 128 /* KEYED_FRAGMENT */)),
209
236
  ($props.config.reason)
210
- ? (openBlock(), createElementBlock("div", _hoisted_15, [
237
+ ? (openBlock(), createElementBlock("div", _hoisted_16, [
211
238
  createVNode(_component_NcTextArea, {
212
239
  id: $data.reasonId,
213
240
  modelValue: $data.reason,
@@ -218,7 +245,7 @@ function render(_ctx, _cache, $props, $setup, $data, $options) {
218
245
  "data-testid": "cn-action-dialog-reason"
219
246
  }, null, 8 /* PROPS */, ["id", "modelValue", "label"]),
220
247
  ($props.config.reason.hint)
221
- ? (openBlock(), createElementBlock("span", _hoisted_16, toDisplayString($options.text($props.config.reason.hint)), 1 /* TEXT */))
248
+ ? (openBlock(), createElementBlock("span", _hoisted_17, toDisplayString($options.text($props.config.reason.hint)), 1 /* TEXT */))
222
249
  : createCommentVNode("v-if", true)
223
250
  ]))
224
251
  : createCommentVNode("v-if", true),
@@ -236,10 +263,10 @@ function render(_ctx, _cache, $props, $setup, $data, $options) {
236
263
  }, 8 /* PROPS */, ["type", "heading"]))
237
264
  : createCommentVNode("v-if", true),
238
265
  ($data.refusal)
239
- ? (openBlock(), createElementBlock("p", _hoisted_17, toDisplayString($data.refusal), 1 /* TEXT */))
266
+ ? (openBlock(), createElementBlock("p", _hoisted_18, toDisplayString($data.refusal), 1 /* TEXT */))
240
267
  : createCommentVNode("v-if", true)
241
268
  ]))
242
- : (openBlock(), createElementBlock("p", _hoisted_18, toDisplayString($options.text($props.config.doneText) || $options.t('nextcloud-vue', 'Done')), 1 /* TEXT */))
269
+ : (openBlock(), createElementBlock("p", _hoisted_19, toDisplayString($options.text($props.config.doneText) || $options.t('nextcloud-vue', 'Done')), 1 /* TEXT */))
243
270
  ]),
244
271
  _: 1 /* STABLE */
245
272
  }, 8 /* PROPS */, ["name", "eyebrow", "subtitle", "noClose", "onClosing"]))
@@ -1 +1 @@
1
- {"version":3,"file":"CnActionDialog.vue3.js","sources":["../../../../src/components/CnActionDialog/CnActionDialog.vue?vue&type=template&id=53fea6f0&lang.js"],"sourcesContent":["<!--\n - SPDX-FileCopyrightText: 2026 Conduction B.V.\n - SPDX-License-Identifier: EUPL-1.2\n-->\n<template>\n\t<CnDialog\n\t\t:name=\"text(config.title) || t('nextcloud-vue', 'Confirm')\"\n\t\t:eyebrow=\"text(config.eyebrow)\"\n\t\t:subtitle=\"text(config.subtitle)\"\n\t\twidth=\"form\"\n\t\t:noClose=\"busy\"\n\t\tdata-testid=\"cn-action-dialog\"\n\t\t@closing=\"close\">\n\t\t<div v-if=\"!done\" class=\"cn-action-dialog\">\n\t\t\t<!-- The record the action is about: its title, a meta line, a badge. -->\n\t\t\t<div v-if=\"summary\" class=\"cn-action-dialog__summary\" data-testid=\"cn-action-dialog-summary\">\n\t\t\t\t<CnIcon :name=\"config.summary.icon || 'FolderOutline'\" :size=\"20\" class=\"cn-action-dialog__summary-icon\" />\n\t\t\t\t<span class=\"cn-action-dialog__summary-text\">\n\t\t\t\t\t<strong>{{ summary.title }}</strong>\n\t\t\t\t\t<span v-if=\"summary.meta\" class=\"cn-action-dialog__muted\">{{ summary.meta }}</span>\n\t\t\t\t</span>\n\t\t\t\t<span v-if=\"summary.badge\" class=\"cn-action-dialog__badge\">{{ summary.badge }}</span>\n\t\t\t</div>\n\n\t\t\t<!-- Facts about the record, in titled groups (\"Retention under the case type\"). -->\n\t\t\t<section v-for=\"(section, index) in factSections\"\n\t\t\t\t:key=\"`facts-${index}`\"\n\t\t\t\tclass=\"cn-action-dialog__section\"\n\t\t\t\tdata-testid=\"cn-action-dialog-facts\">\n\t\t\t\t<h3 v-if=\"section.title\" class=\"cn-action-dialog__title\">\n\t\t\t\t\t{{ section.title }}\n\t\t\t\t</h3>\n\t\t\t\t<dl class=\"cn-action-dialog__facts\">\n\t\t\t\t\t<div v-for=\"fact in section.facts\" :key=\"fact.label\">\n\t\t\t\t\t\t<dt>{{ fact.label }}</dt>\n\t\t\t\t\t\t<dd>{{ fact.value }}</dd>\n\t\t\t\t\t</div>\n\t\t\t\t</dl>\n\t\t\t</section>\n\n\t\t\t<!-- The checklist, read from an endpoint: each item met, not met or\n\t\t\t unknown. Items named in `required` decide whether the action may\n\t\t\t run; the others inform. -->\n\t\t\t<section v-if=\"config.checklist\" class=\"cn-action-dialog__section\" data-testid=\"cn-action-dialog-checklist\">\n\t\t\t\t<h3 v-if=\"config.checklist.title\" class=\"cn-action-dialog__title\">\n\t\t\t\t\t{{ text(config.checklist.title) }}\n\t\t\t\t</h3>\n\t\t\t\t<p v-if=\"checklistError\" class=\"cn-action-dialog__muted\" role=\"status\">\n\t\t\t\t\t{{ checklistError }}\n\t\t\t\t</p>\n\t\t\t\t<ul class=\"cn-action-dialog__checks\">\n\t\t\t\t\t<li v-for=\"item in checklist\"\n\t\t\t\t\t\t:key=\"item.id\"\n\t\t\t\t\t\tclass=\"cn-action-dialog__check\"\n\t\t\t\t\t\t:data-testid=\"`cn-action-dialog-check-${item.id}`\"\n\t\t\t\t\t\t:data-met=\"String(item.met)\">\n\t\t\t\t\t\t<CheckCircle v-if=\"item.met === true\" :size=\"20\" class=\"cn-action-dialog__check-icon cn-action-dialog__check-icon--met\" />\n\t\t\t\t\t\t<HelpCircleOutline v-else-if=\"item.met === null\" :size=\"20\" class=\"cn-action-dialog__check-icon\" />\n\t\t\t\t\t\t<CircleOutline v-else :size=\"20\" class=\"cn-action-dialog__check-icon\" />\n\t\t\t\t\t\t<strong class=\"cn-action-dialog__check-label\">{{ item.label }}</strong>\n\t\t\t\t\t\t<span v-if=\"item.detail\" class=\"cn-action-dialog__muted\">{{ item.detail }}</span>\n\t\t\t\t\t</li>\n\t\t\t\t</ul>\n\t\t\t</section>\n\n\t\t\t<div v-if=\"config.reason\" class=\"cn-action-dialog__field\">\n\t\t\t\t<NcTextArea\n\t\t\t\t\t:id=\"reasonId\"\n\t\t\t\t\tv-model=\"reason\"\n\t\t\t\t\t:label=\"reasonLabel\"\n\t\t\t\t\t:labelOutside=\"false\"\n\t\t\t\t\tresize=\"vertical\"\n\t\t\t\t\tdata-testid=\"cn-action-dialog-reason\" />\n\t\t\t\t<span v-if=\"config.reason.hint\" class=\"cn-action-dialog__muted\">{{ text(config.reason.hint) }}</span>\n\t\t\t</div>\n\n\t\t\t<NcNoteCard v-if=\"config.note\"\n\t\t\t\t:type=\"noteType\"\n\t\t\t\t:heading=\"text(config.note.title)\"\n\t\t\t\tdata-testid=\"cn-action-dialog-note\">\n\t\t\t\t{{ text(config.note.text) }}\n\t\t\t</NcNoteCard>\n\n\t\t\t<p v-if=\"refusal\"\n\t\t\t\tclass=\"cn-action-dialog__error\"\n\t\t\t\trole=\"alert\"\n\t\t\t\tdata-testid=\"cn-action-dialog-refusal\">\n\t\t\t\t{{ refusal }}\n\t\t\t</p>\n\t\t</div>\n\n\t\t<p v-else role=\"status\" data-testid=\"cn-action-dialog-done\">\n\t\t\t{{ text(config.doneText) || t('nextcloud-vue', 'Done') }}\n\t\t</p>\n\n\t\t<template #actions>\n\t\t\t<NcButton :disabled=\"busy\" data-testid=\"cn-action-dialog-cancel\" @click=\"close\">\n\t\t\t\t{{ done ? t('nextcloud-vue', 'Close') : t('nextcloud-vue', 'Cancel') }}\n\t\t\t</NcButton>\n\t\t\t<NcButton v-if=\"!done\"\n\t\t\t\tvariant=\"primary\"\n\t\t\t\t:disabled=\"!canConfirm\"\n\t\t\t\tdata-testid=\"cn-action-dialog-confirm\"\n\t\t\t\t@click=\"confirm\">\n\t\t\t\t<template v-if=\"confirmConfig.icon\" #icon>\n\t\t\t\t\t<CnIcon :name=\"confirmConfig.icon\" :size=\"20\" />\n\t\t\t\t</template>\n\t\t\t\t{{ text(confirmConfig.label) || t('nextcloud-vue', 'Confirm') }}\n\t\t\t</NcButton>\n\t\t</template>\n\t</CnDialog>\n</template>\n\n<script>\nimport axios from '@nextcloud/axios'\nimport { emit } from '@nextcloud/event-bus'\nimport { translate as t } from '@nextcloud/l10n'\nimport { generateUrl } from '@nextcloud/router'\nimport { NcButton, NcNoteCard, NcTextArea } from '@nextcloud/vue'\nimport CheckCircle from 'vue-material-design-icons/CheckCircle.vue'\nimport CircleOutline from 'vue-material-design-icons/CircleOutline.vue'\nimport HelpCircleOutline from 'vue-material-design-icons/HelpCircleOutline.vue'\nimport { fetchEndpointSource, interpolateUrlTokens } from '../../composables/useEndpointSource.js'\nimport { fillTemplate } from '../../utils/fillTemplate.js'\nimport { readPath } from '../../utils/readPath.js'\nimport { CnDialog } from '../CnDialog/index.js'\nimport { CnIcon } from '../CnIcon/index.js'\n\n/** The page refresh channel the built-in widgets listen on. */\nconst PAGE_REFRESH = 'cn:page:refresh'\n\n/** Gives each dialog's reason field its own id. */\nlet reasonSeq = 0\n\n/**\n * CnActionDialog — the generic \"summary, checklist, reason, confirm\" dialog\n * for an act on a record, configured from the manifest (an `open-modal`\n * action's props), so an app does not hand-build each one. dossiq's archive\n * dialog (board DqArchiveren) is the first: the case, what its case type\n * keeps, a readiness checklist read from an endpoint, a reason, a read-only\n * note and Archive it.\n *\n * `config`:\n * - `title`, `eyebrow`, `subtitle`, `doneText`: texts, through the host translate.\n * - `summary`: `{ source?, title, meta?, badge?, icon? }`: templates filled from\n * the record (`source` an endpointSource to read it from, else `object`).\n * - `facts`: `[{ title?, items: [{ label, value }] }]`, `value` a template.\n * - `checklist`: `{ title?, source, itemsPath?, labels?, required? }`: items\n * `{ id, met, label?, detail? }` read from `source`; `labels[id]` gives an\n * item's `{ label, detail?, unmetDetail? }`; the ids in `required` must be\n * met before the action can run. `met: null` reads as unknown.\n * - `permission`: `{ source, allowedPath, reasonPath? }`: the action runs only\n * while `allowedPath` reads true; `reasonPath` says why not.\n * - `reason`: `{ label?, hint?, required?, field? }`: a text area; required by\n * default; sent as `field` (default `reason`).\n * - `note`: `{ variant?, title?, text }`: a read-only note.\n * - `confirm`: `{ label, icon?, request?: { method?, url, body? }, action? }`.\n * `request` posts itself (`body` templates filled with the record and\n * `{reason}`); `action` dispatches a manifest action through the page.\n *\n * Tokens (`@objectId`, `@object.<field>`) resolve in every url.\n */\nexport default {\n\tname: 'CnActionDialog',\n\n\tcomponents: { CheckCircle, CircleOutline, CnDialog, CnIcon, HelpCircleOutline, NcButton, NcNoteCard, NcTextArea },\n\n\tinject: {\n\t\t/** The host app's translate (CnAppRoot `cnTranslate`). */\n\t\tcnTranslate: { default: () => (key) => key },\n\t\t/** The page's pre-bound action dispatcher (CnPageRenderer), for `confirm.action`. */\n\t\tcnDispatchAction: { default: null },\n\t},\n\n\tprops: {\n\t\t/**\n\t\t * The dialog's configuration (see the component docs).\n\t\t *\n\t\t * @type {object}\n\t\t */\n\t\tconfig: {\n\t\t\ttype: Object,\n\t\t\tdefault: () => ({}),\n\t\t},\n\n\t\t/** The record's id, for the `@objectId` token. */\n\t\tobjectId: {\n\t\t\ttype: [String, Number],\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * The record, when the host has it: the summary and facts read it.\n\t\t *\n\t\t * @type {object|null}\n\t\t */\n\t\tobject: {\n\t\t\ttype: Object,\n\t\t\tdefault: null,\n\t\t},\n\t},\n\n\temits: ['close', 'done'],\n\n\tdata() {\n\t\treturn {\n\t\t\trecord: this.object,\n\t\t\titems: [],\n\t\t\tchecklistError: '',\n\t\t\tallowed: true,\n\t\t\treason: '',\n\t\t\tbusy: false,\n\t\t\trefusal: '',\n\t\t\tdone: false,\n\t\t\treasonId: `cn-action-dialog-reason-${++reasonSeq}`,\n\t\t}\n\t},\n\n\tcomputed: {\n\t\t/** @return {object} The token context. */\n\t\ttokenCtx() {\n\t\t\treturn { objectId: this.objectId, object: this.record || {} }\n\t\t},\n\n\t\t/** @return {object} The confirm config. */\n\t\tconfirmConfig() {\n\t\t\treturn this.config.confirm && typeof this.config.confirm === 'object' ? this.config.confirm : {}\n\t\t},\n\n\t\t/**\n\t\t * The summary row, or null without one or before the record is known.\n\t\t *\n\t\t * @spec openspec/changes/action-dialog/specs/action-dialog/spec.md#requirement-a-manifest-configures-an-action-dialog\n\t\t * @return {{title: string, meta: string, badge: string}|null}\n\t\t */\n\t\tsummary() {\n\t\t\tconst def = this.config.summary\n\t\t\tif (!def || !this.record) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst title = this.fill(def.title)\n\t\t\treturn title ? { title, meta: this.fill(def.meta), badge: this.fill(def.badge) } : null\n\t\t},\n\n\t\t/** @return {Array<{title: string, facts: Array<{label: string, value: string}>}>} The fact groups. */\n\t\tfactSections() {\n\t\t\tif (!Array.isArray(this.config.facts) || !this.record) {\n\t\t\t\treturn []\n\t\t\t}\n\t\t\tconst empty = t('nextcloud-vue', 'Not set')\n\t\t\treturn this.config.facts.map((section) => ({\n\t\t\t\ttitle: this.text(section.title),\n\t\t\t\tfacts: (Array.isArray(section.items) ? section.items : []).map((fact) => ({ label: this.text(fact.label), value: this.fill(fact.value) || empty })),\n\t\t\t}))\n\t\t},\n\n\t\t/**\n\t\t * The checklist rows: label and detail from `labels` by id, else the item's own.\n\t\t *\n\t\t * @spec openspec/changes/action-dialog/specs/action-dialog/spec.md#requirement-a-manifest-configures-an-action-dialog\n\t\t * @return {Array<{id: string, met: (boolean|null), label: string, detail: string}>}\n\t\t */\n\t\tchecklist() {\n\t\t\tconst labels = (this.config.checklist && this.config.checklist.labels) || {}\n\t\t\treturn this.items.map((item) => {\n\t\t\t\tconst met = item.met === null || item.met === undefined ? null : item.met === true\n\t\t\t\tconst own = labels[item.id] || {}\n\t\t\t\tconst detail = met === false && own.unmetDetail ? own.unmetDetail : (own.detail || item.detail || '')\n\t\t\t\treturn {\n\t\t\t\t\tid: String(item.id),\n\t\t\t\t\tmet,\n\t\t\t\t\tlabel: this.fill(own.label || item.label || String(item.id), item),\n\t\t\t\t\tdetail: met === null && !item.detail ? t('nextcloud-vue', 'Could not be read') : this.fill(detail, item),\n\t\t\t\t}\n\t\t\t})\n\t\t},\n\n\t\t/** @return {boolean} Whether every required item is met. */\n\t\trequiredMet() {\n\t\t\tconst required = (this.config.checklist && Array.isArray(this.config.checklist.required)) ? this.config.checklist.required.map(String) : []\n\t\t\treturn required.every((id) => this.items.some((item) => String(item.id) === id && item.met === true))\n\t\t},\n\n\t\t/** @return {boolean} Whether a reason is asked and needed. */\n\t\treasonNeeded() {\n\t\t\treturn Boolean(this.config.reason) && this.config.reason.required !== false\n\t\t},\n\n\t\t/** @return {string} The reason field's label. */\n\t\treasonLabel() {\n\t\t\treturn this.text(this.config.reason && this.config.reason.label) || t('nextcloud-vue', 'Reason')\n\t\t},\n\n\t\t/** @return {string} The note's NcNoteCard type. */\n\t\tnoteType() {\n\t\t\tconst variant = this.config.note && this.config.note.variant\n\t\t\treturn ['info', 'warning', 'error', 'success'].includes(variant) ? variant : 'info'\n\t\t},\n\n\t\t/**\n\t\t * Whether the action may run: allowed, required items met, a reason\n\t\t * when one is needed, and nothing in flight.\n\t\t *\n\t\t * @spec openspec/changes/action-dialog/specs/action-dialog/spec.md#requirement-a-manifest-configures-an-action-dialog\n\t\t * @return {boolean}\n\t\t */\n\t\tcanConfirm() {\n\t\t\treturn !this.busy && this.allowed && this.requiredMet && (!this.reasonNeeded || this.reason.trim() !== '')\n\t\t},\n\t},\n\n\tasync mounted() {\n\t\tawait Promise.all([this.loadRecord(), this.loadChecklist(), this.loadPermission()])\n\t},\n\n\tmethods: {\n\t\tt,\n\n\t\t/**\n\t\t * A config text through the host translate, '' for anything else.\n\t\t *\n\t\t * @param {unknown} value The text.\n\t\t * @return {string}\n\t\t */\n\t\ttext(value) {\n\t\t\treturn typeof value === 'string' && value !== '' ? this.cnTranslate(value) : ''\n\t\t},\n\n\t\t/**\n\t\t * A template filled from a row (the record by default), translated first.\n\t\t *\n\t\t * @param {unknown} template The template.\n\t\t * @param {object} [row] The row.\n\t\t * @return {string}\n\t\t */\n\t\tfill(template, row) {\n\t\t\tif (typeof template !== 'string' || template === '') {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t\treturn fillTemplate(this.cnTranslate(template), row || this.record || {}).trim()\n\t\t},\n\n\t\t/**\n\t\t * Read an endpoint, fresh.\n\t\t *\n\t\t * @param {object} source An endpointSource block.\n\t\t * @return {Promise<unknown>}\n\t\t */\n\t\tread(source) {\n\t\t\treturn fetchEndpointSource(source, this.tokenCtx, { fresh: true })\n\t\t},\n\n\t\t/** @return {Promise<void>} */\n\t\tasync loadRecord() {\n\t\t\tconst source = this.config.summary && this.config.summary.source\n\t\t\tif (!source || !source.url) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst data = await this.read(source)\n\t\t\t\tthis.record = data && typeof data === 'object' ? data : this.record\n\t\t\t} catch {\n\t\t\t\t// The summary stays empty; the checklist and the action still work.\n\t\t\t}\n\t\t},\n\n\t\t/** @return {Promise<void>} */\n\t\tasync loadChecklist() {\n\t\t\tconst def = this.config.checklist\n\t\t\tif (!def || !def.source || !def.source.url) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst data = await this.read(def.source)\n\t\t\t\tconst list = def.itemsPath ? readPath(data, def.itemsPath) : data\n\t\t\t\tthis.items = Array.isArray(list) ? list.filter((item) => item && item.id !== undefined) : []\n\t\t\t} catch {\n\t\t\t\tthis.items = []\n\t\t\t\tthis.checklistError = t('nextcloud-vue', 'Whether this is ready could not be read.')\n\t\t\t}\n\t\t},\n\n\t\t/** @return {Promise<void>} */\n\t\tasync loadPermission() {\n\t\t\tconst def = this.config.permission\n\t\t\tif (!def || !def.source || !def.source.url) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst data = await this.read(def.source)\n\t\t\t\tthis.allowed = readPath(data, def.allowedPath || 'allowed') === true\n\t\t\t\tthis.refusal = this.allowed || !def.reasonPath ? '' : String(readPath(data, def.reasonPath) || '')\n\t\t\t} catch {\n\t\t\t\tthis.allowed = false\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Run the action once: post `confirm.request`, or dispatch\n\t\t * `confirm.action`, then show the done text and refresh the page.\n\t\t *\n\t\t * @spec openspec/changes/action-dialog/specs/action-dialog/spec.md#requirement-a-manifest-configures-an-action-dialog\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync confirm() {\n\t\t\tif (!this.canConfirm) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.busy = true\n\t\t\tthis.refusal = ''\n\t\t\tconst reason = this.reason.trim()\n\t\t\ttry {\n\t\t\t\tconst request = this.confirmConfig.request\n\t\t\t\tif (request && request.url) {\n\t\t\t\t\tconst url = interpolateUrlTokens(request.url, this.tokenCtx)\n\t\t\t\t\tconst body = {}\n\t\t\t\t\tfor (const [key, value] of Object.entries(request.body || {})) {\n\t\t\t\t\t\tbody[key] = typeof value === 'string' ? fillTemplate(value, { ...(this.record || {}), reason }) : value\n\t\t\t\t\t}\n\t\t\t\t\tif (this.config.reason) {\n\t\t\t\t\t\tbody[this.config.reason.field || 'reason'] = reason\n\t\t\t\t\t}\n\t\t\t\t\tconst method = String(request.method || 'POST').toLowerCase()\n\t\t\t\t\tawait axios[['post', 'put', 'patch', 'delete'].includes(method) ? method : 'post'](/^https?:\\/\\//i.test(url) ? url : generateUrl(url), body)\n\t\t\t\t} else if (this.confirmConfig.action && typeof this.cnDispatchAction === 'function') {\n\t\t\t\t\tawait this.cnDispatchAction({ ...this.confirmConfig.action, args: [...(this.confirmConfig.action.args || []), { reason }] })\n\t\t\t\t}\n\t\t\t\tthis.done = true\n\t\t\t\temit(PAGE_REFRESH, {})\n\t\t\t\t/** @event done The action ran. Payload: `{ reason }`. */\n\t\t\t\tthis.$emit('done', { reason })\n\t\t\t} catch (failure) {\n\t\t\t\tconst data = failure && failure.response && failure.response.data\n\t\t\t\tthis.refusal = String((data && (data.message || data.error)) || t('nextcloud-vue', 'The action could not be completed.'))\n\t\t\t} finally {\n\t\t\t\tthis.busy = false\n\t\t\t}\n\t\t},\n\n\t\t/** Close the dialog, unless the action is running. */\n\t\tclose() {\n\t\t\tif (this.busy) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\t/** @event close The dialog was closed. */\n\t\t\tthis.$emit('close')\n\t\t},\n\t},\n}\n</script>\n\n<style scoped>\n.cn-action-dialog {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 16px;\n}\n\n.cn-action-dialog__summary {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 10px;\n\tpadding: 12px 14px;\n\tborder: 1px solid var(--color-border);\n\tborder-radius: var(--border-radius-large, 8px);\n}\n\n.cn-action-dialog__summary-text {\n\tdisplay: flex;\n\tflex: 1 1 auto;\n\tflex-direction: column;\n\tmin-width: 0;\n}\n\n.cn-action-dialog__badge {\n\tpadding: 3px 10px;\n\tborder-radius: 12px;\n\tbackground: var(--color-background-dark);\n\tfont-size: 13px;\n\tfont-weight: 600;\n\twhite-space: nowrap;\n}\n\n.cn-action-dialog__title {\n\tmargin: 0 0 8px;\n\tfont-size: 15px;\n\tfont-weight: 700;\n}\n\n.cn-action-dialog__facts {\n\tdisplay: grid;\n\tgrid-template-columns: repeat(auto-fit, minmax(180px, 1fr));\n\tgap: 8px 16px;\n\tmargin: 0;\n}\n\n.cn-action-dialog__facts dt {\n\tcolor: var(--color-text-maxcontrast);\n\tfont-size: 13px;\n}\n\n.cn-action-dialog__facts dd {\n\tmargin: 0;\n}\n\n.cn-action-dialog__checks {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 8px;\n\tmargin: 0;\n\tpadding: 0;\n\tlist-style: none;\n}\n\n.cn-action-dialog__check {\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\talign-items: center;\n\tgap: 8px;\n}\n\n.cn-action-dialog__check-icon {\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-action-dialog__check-icon--met {\n\tcolor: var(--color-success-text, var(--color-success));\n}\n\n.cn-action-dialog__muted {\n\tcolor: var(--color-text-maxcontrast);\n\tfont-size: 14px;\n}\n\n.cn-action-dialog__field {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 4px;\n}\n\n.cn-action-dialog__error {\n\tmargin: 0;\n\tcolor: var(--color-error-text, var(--color-error));\n}\n</style>\n"],"names":["_createVNode","_createBlock","_createTextVNode","_openBlock","_createElementBlock","_createElementVNode","_toDisplayString","_Fragment","_renderList"],"mappings":"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"}
1
+ {"version":3,"file":"CnActionDialog.vue3.js","sources":["../../../../src/components/CnActionDialog/CnActionDialog.vue?vue&type=template&id=0bb28fd1&lang.js"],"sourcesContent":["<!--\n - SPDX-FileCopyrightText: 2026 Conduction B.V.\n - SPDX-License-Identifier: EUPL-1.2\n-->\n<template>\n\t<CnDialog\n\t\t:name=\"text(config.title) || t('nextcloud-vue', 'Confirm')\"\n\t\t:eyebrow=\"eyebrowText\"\n\t\t:subtitle=\"text(config.subtitle)\"\n\t\twidth=\"form\"\n\t\t:noClose=\"busy\"\n\t\tdata-testid=\"cn-action-dialog\"\n\t\t@closing=\"close\">\n\t\t<div v-if=\"!done\" class=\"cn-action-dialog\">\n\t\t\t<!-- The record the action is about: its title, a meta line, a badge. -->\n\t\t\t<div v-if=\"summary\" class=\"cn-action-dialog__summary\" data-testid=\"cn-action-dialog-summary\">\n\t\t\t\t<CnIcon :name=\"config.summary.icon || 'FolderOutline'\" :size=\"20\" class=\"cn-action-dialog__summary-icon\" />\n\t\t\t\t<span class=\"cn-action-dialog__summary-text\">\n\t\t\t\t\t<strong>{{ summary.title }}</strong>\n\t\t\t\t\t<span v-if=\"summary.meta\" class=\"cn-action-dialog__muted\">{{ summary.meta }}</span>\n\t\t\t\t</span>\n\t\t\t\t<span v-if=\"summary.badge\" class=\"cn-action-dialog__badge\">{{ summary.badge }}</span>\n\t\t\t</div>\n\n\t\t\t<!-- Facts about the record, in titled groups (\"Retention under the case type\"). -->\n\t\t\t<section v-for=\"(section, index) in factSections\"\n\t\t\t\t:key=\"`facts-${index}`\"\n\t\t\t\tclass=\"cn-action-dialog__section\"\n\t\t\t\tdata-testid=\"cn-action-dialog-facts\">\n\t\t\t\t<h3 v-if=\"section.title\" class=\"cn-action-dialog__title\">\n\t\t\t\t\t{{ section.title }}\n\t\t\t\t</h3>\n\t\t\t\t<dl class=\"cn-action-dialog__facts\">\n\t\t\t\t\t<div v-for=\"fact in section.facts\" :key=\"fact.label\">\n\t\t\t\t\t\t<dt>{{ fact.label }}</dt>\n\t\t\t\t\t\t<dd>{{ fact.value }}</dd>\n\t\t\t\t\t</div>\n\t\t\t\t</dl>\n\t\t\t</section>\n\n\t\t\t<!-- The checklist, read from an endpoint: each item met, not met or\n\t\t\t unknown. Items named in `required` decide whether the action may\n\t\t\t run; the others inform. -->\n\t\t\t<section v-if=\"config.checklist\" class=\"cn-action-dialog__section\" data-testid=\"cn-action-dialog-checklist\">\n\t\t\t\t<h3 v-if=\"config.checklist.title\" class=\"cn-action-dialog__title\">\n\t\t\t\t\t{{ text(config.checklist.title) }}\n\t\t\t\t</h3>\n\t\t\t\t<p v-if=\"checklistError\" class=\"cn-action-dialog__muted\" role=\"status\">\n\t\t\t\t\t{{ checklistError }}\n\t\t\t\t</p>\n\t\t\t\t<ul class=\"cn-action-dialog__checks\">\n\t\t\t\t\t<li v-for=\"item in checklist\"\n\t\t\t\t\t\t:key=\"item.id\"\n\t\t\t\t\t\tclass=\"cn-action-dialog__check\"\n\t\t\t\t\t\t:data-testid=\"`cn-action-dialog-check-${item.id}`\"\n\t\t\t\t\t\t:data-met=\"String(item.met)\">\n\t\t\t\t\t\t<CheckCircle v-if=\"item.met === true\" :size=\"20\" class=\"cn-action-dialog__check-icon cn-action-dialog__check-icon--met\" />\n\t\t\t\t\t\t<HelpCircleOutline v-else-if=\"item.met === null\" :size=\"20\" class=\"cn-action-dialog__check-icon\" />\n\t\t\t\t\t\t<CircleOutline v-else :size=\"20\" class=\"cn-action-dialog__check-icon\" />\n\t\t\t\t\t\t<strong class=\"cn-action-dialog__check-label\">{{ item.label }}</strong>\n\t\t\t\t\t\t<span v-if=\"item.detail\" class=\"cn-action-dialog__muted\">{{ item.detail }}</span>\n\t\t\t\t\t</li>\n\t\t\t\t</ul>\n\t\t\t</section>\n\n\t\t\t<!-- Fields the action asks for, sent beside the reason. -->\n\t\t\t<div v-for=\"field in fields\"\n\t\t\t\t:key=\"field.field\"\n\t\t\t\tclass=\"cn-action-dialog__field\"\n\t\t\t\t:data-testid=\"`cn-action-dialog-field-${field.field}`\">\n\t\t\t\t<NcSelect v-if=\"field.type === 'select'\"\n\t\t\t\t\t:modelValue=\"selectedOption(field)\"\n\t\t\t\t\t:options=\"optionsOf(field)\"\n\t\t\t\t\t:inputLabel=\"text(field.label) || field.field\"\n\t\t\t\t\t:clearable=\"field.required === false\"\n\t\t\t\t\t@update:modelValue=\"(option) => pick(field, option)\" />\n\t\t\t\t<NcTextField v-else\n\t\t\t\t\t:modelValue=\"values[field.field] || ''\"\n\t\t\t\t\t:type=\"field.type === 'datetime' ? 'datetime-local' : (field.type === 'date' ? 'date' : 'text')\"\n\t\t\t\t\t:label=\"text(field.label) || field.field\"\n\t\t\t\t\t@update:modelValue=\"(value) => setValue(field.field, value)\" />\n\t\t\t</div>\n\n\t\t\t<div v-if=\"config.reason\" class=\"cn-action-dialog__field\">\n\t\t\t\t<NcTextArea\n\t\t\t\t\t:id=\"reasonId\"\n\t\t\t\t\tv-model=\"reason\"\n\t\t\t\t\t:label=\"reasonLabel\"\n\t\t\t\t\t:labelOutside=\"false\"\n\t\t\t\t\tresize=\"vertical\"\n\t\t\t\t\tdata-testid=\"cn-action-dialog-reason\" />\n\t\t\t\t<span v-if=\"config.reason.hint\" class=\"cn-action-dialog__muted\">{{ text(config.reason.hint) }}</span>\n\t\t\t</div>\n\n\t\t\t<NcNoteCard v-if=\"config.note\"\n\t\t\t\t:type=\"noteType\"\n\t\t\t\t:heading=\"text(config.note.title)\"\n\t\t\t\tdata-testid=\"cn-action-dialog-note\">\n\t\t\t\t{{ text(config.note.text) }}\n\t\t\t</NcNoteCard>\n\n\t\t\t<p v-if=\"refusal\"\n\t\t\t\tclass=\"cn-action-dialog__error\"\n\t\t\t\trole=\"alert\"\n\t\t\t\tdata-testid=\"cn-action-dialog-refusal\">\n\t\t\t\t{{ refusal }}\n\t\t\t</p>\n\t\t</div>\n\n\t\t<p v-else role=\"status\" data-testid=\"cn-action-dialog-done\">\n\t\t\t{{ text(config.doneText) || t('nextcloud-vue', 'Done') }}\n\t\t</p>\n\n\t\t<template #actions>\n\t\t\t<NcButton :disabled=\"busy\" data-testid=\"cn-action-dialog-cancel\" @click=\"close\">\n\t\t\t\t{{ done ? t('nextcloud-vue', 'Close') : t('nextcloud-vue', 'Cancel') }}\n\t\t\t</NcButton>\n\t\t\t<NcButton v-if=\"!done\"\n\t\t\t\tvariant=\"primary\"\n\t\t\t\t:disabled=\"!canConfirm\"\n\t\t\t\tdata-testid=\"cn-action-dialog-confirm\"\n\t\t\t\t@click=\"confirm\">\n\t\t\t\t<template v-if=\"confirmConfig.icon\" #icon>\n\t\t\t\t\t<CnIcon :name=\"confirmConfig.icon\" :size=\"20\" />\n\t\t\t\t</template>\n\t\t\t\t{{ text(confirmConfig.label) || t('nextcloud-vue', 'Confirm') }}\n\t\t\t</NcButton>\n\t\t</template>\n\t</CnDialog>\n</template>\n\n<script>\nimport axios from '@nextcloud/axios'\nimport { emit } from '@nextcloud/event-bus'\nimport { translate as t } from '@nextcloud/l10n'\nimport { generateUrl } from '@nextcloud/router'\nimport { NcButton, NcNoteCard, NcSelect, NcTextArea, NcTextField } from '@nextcloud/vue'\nimport CheckCircle from 'vue-material-design-icons/CheckCircle.vue'\nimport CircleOutline from 'vue-material-design-icons/CircleOutline.vue'\nimport HelpCircleOutline from 'vue-material-design-icons/HelpCircleOutline.vue'\nimport { fetchEndpointSource, interpolateUrlTokens } from '../../composables/useEndpointSource.js'\nimport { fillTemplate } from '../../utils/fillTemplate.js'\nimport { readPath } from '../../utils/readPath.js'\nimport { CnDialog } from '../CnDialog/index.js'\nimport { CnIcon } from '../CnIcon/index.js'\n\n/** The page refresh channel the built-in widgets listen on. */\nconst PAGE_REFRESH = 'cn:page:refresh'\n\n/** Gives each dialog's reason field its own id. */\nlet reasonSeq = 0\n\n/**\n * CnActionDialog — the generic \"summary, checklist, reason, confirm\" dialog\n * for an act on a record, configured from the manifest (an `open-modal`\n * action's props), so an app does not hand-build each one. dossiq's archive\n * dialog (board DqArchiveren) is the first: the case, what its case type\n * keeps, a readiness checklist read from an endpoint, a reason, a read-only\n * note and Archive it.\n *\n * `config`:\n * - `title`, `subtitle`, `doneText`: texts, through the host translate;\n * `eyebrow` a template filled from the record (\"Close off · {identifier}\").\n * - `summary`: `{ source?, title, meta?, badge?, icon? }`: templates filled from\n * the record (`source` an endpointSource to read it from, else `object`).\n * - `facts`: `[{ title?, items: [{ label, value }] }]`, `value` a template.\n * - `checklist`: `{ title?, source, itemsPath?, labels?, required? }`: items\n * `{ id, met, label?, detail? }` read from `source`; `labels[id]` gives an\n * item's `{ label, detail?, unmetDetail? }`; the ids in `required` must be\n * met before the action can run. `met: null` reads as unknown.\n * - `permission`: `{ source, listPath?, match?, allowedPath, reasonPath? }`:\n * the action runs only while `allowedPath` reads true; `reasonPath` says\n * why not. With `listPath` the paths read the entry of that list whose\n * fields equal `match` (`{ act: \"archive\" }`).\n * - `fields`: `[{ field, type?: \"text\"|\"date\"|\"datetime\"|\"select\", label?,\n * required?, options?: [{ value, label, fills? }] }]`: inputs sent beside\n * the reason, required by default; a select option's `fills` sets other\n * fields that are still empty.\n * - `reason`: `{ label?, hint?, required?, field? }`: a text area; required by\n * default; sent as `field` (default `reason`).\n * - `note`: `{ variant?, title?, text }`: a read-only note.\n * - `confirm`: `{ label, icon?, request?: { method?, url, body? }, action? }`.\n * `request` posts itself (`body` templates filled with the record and\n * `{reason}`); `action` dispatches a manifest action through the page.\n *\n * Tokens (`@objectId`, `@object.<field>`) resolve in every url.\n */\nexport default {\n\tname: 'CnActionDialog',\n\n\tcomponents: { CheckCircle, CircleOutline, CnDialog, CnIcon, HelpCircleOutline, NcButton, NcNoteCard, NcSelect, NcTextArea, NcTextField },\n\n\tinject: {\n\t\t/** The host app's translate (CnAppRoot `cnTranslate`). */\n\t\tcnTranslate: { default: () => (key) => key },\n\t\t/** The page's pre-bound action dispatcher (CnPageRenderer), for `confirm.action`. */\n\t\tcnDispatchAction: { default: null },\n\t},\n\n\tprops: {\n\t\t/**\n\t\t * The dialog's configuration (see the component docs).\n\t\t *\n\t\t * @type {object}\n\t\t */\n\t\tconfig: {\n\t\t\ttype: Object,\n\t\t\tdefault: () => ({}),\n\t\t},\n\n\t\t/** The record's id, for the `@objectId` token. */\n\t\tobjectId: {\n\t\t\ttype: [String, Number],\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * The record, when the host has it: the summary and facts read it.\n\t\t *\n\t\t * @type {object|null}\n\t\t */\n\t\tobject: {\n\t\t\ttype: Object,\n\t\t\tdefault: null,\n\t\t},\n\t},\n\n\temits: ['close', 'done'],\n\n\tdata() {\n\t\treturn {\n\t\t\trecord: this.object,\n\t\t\titems: [],\n\t\t\tchecklistError: '',\n\t\t\tallowed: true,\n\t\t\treason: '',\n\t\t\tvalues: {},\n\t\t\tbusy: false,\n\t\t\trefusal: '',\n\t\t\tdone: false,\n\t\t\treasonId: `cn-action-dialog-reason-${++reasonSeq}`,\n\t\t}\n\t},\n\n\tcomputed: {\n\t\t/** @return {object} The token context. */\n\t\ttokenCtx() {\n\t\t\treturn { objectId: this.recordId, object: this.record || {} }\n\t\t},\n\n\t\t/**\n\t\t * The record's id: `objectId`, or the route's `id` when the prop is\n\t\t * empty or a token the opener could not resolve.\n\t\t *\n\t\t * @return {string|number}\n\t\t */\n\t\trecordId() {\n\t\t\tconst given = this.objectId\n\t\t\tif (given !== '' && given !== null && given !== undefined && !String(given).startsWith('@')) {\n\t\t\t\treturn given\n\t\t\t}\n\t\t\treturn (this.$route && this.$route.params && this.$route.params.id) || ''\n\t\t},\n\n\t\t/** @return {object} The confirm config. */\n\t\tconfirmConfig() {\n\t\t\treturn this.config.confirm && typeof this.config.confirm === 'object' ? this.config.confirm : {}\n\t\t},\n\n\t\t/**\n\t\t * The summary row, or null without one or before the record is known.\n\t\t *\n\t\t * @spec openspec/changes/action-dialog/specs/action-dialog/spec.md#requirement-a-manifest-configures-an-action-dialog\n\t\t * @return {{title: string, meta: string, badge: string}|null}\n\t\t */\n\t\tsummary() {\n\t\t\tconst def = this.config.summary\n\t\t\tif (!def || !this.record) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst title = this.fill(def.title)\n\t\t\treturn title ? { title, meta: this.fill(def.meta), badge: this.fill(def.badge) } : null\n\t\t},\n\n\t\t/** @return {Array<{title: string, facts: Array<{label: string, value: string}>}>} The fact groups. */\n\t\tfactSections() {\n\t\t\tif (!Array.isArray(this.config.facts) || !this.record) {\n\t\t\t\treturn []\n\t\t\t}\n\t\t\tconst empty = t('nextcloud-vue', 'Not set')\n\t\t\treturn this.config.facts.map((section) => ({\n\t\t\t\ttitle: this.text(section.title),\n\t\t\t\tfacts: (Array.isArray(section.items) ? section.items : []).map((fact) => ({ label: this.text(fact.label), value: this.fill(fact.value) || empty })),\n\t\t\t}))\n\t\t},\n\n\t\t/**\n\t\t * The checklist rows: label and detail from `labels` by id, else the item's own.\n\t\t *\n\t\t * @spec openspec/changes/action-dialog/specs/action-dialog/spec.md#requirement-a-manifest-configures-an-action-dialog\n\t\t * @return {Array<{id: string, met: (boolean|null), label: string, detail: string}>}\n\t\t */\n\t\tchecklist() {\n\t\t\tconst labels = (this.config.checklist && this.config.checklist.labels) || {}\n\t\t\treturn this.items.map((item) => {\n\t\t\t\tconst met = item.met === null || item.met === undefined ? null : item.met === true\n\t\t\t\tconst own = labels[item.id] || {}\n\t\t\t\tconst detail = met === false && own.unmetDetail ? own.unmetDetail : (own.detail || item.detail || '')\n\t\t\t\treturn {\n\t\t\t\t\tid: String(item.id),\n\t\t\t\t\tmet,\n\t\t\t\t\tlabel: this.fill(own.label || item.label || String(item.id), item),\n\t\t\t\t\tdetail: met === null && !item.detail ? t('nextcloud-vue', 'Could not be read') : this.fill(detail, item),\n\t\t\t\t}\n\t\t\t})\n\t\t},\n\n\t\t/** @return {boolean} Whether every required item is met. */\n\t\trequiredMet() {\n\t\t\tconst required = (this.config.checklist && Array.isArray(this.config.checklist.required)) ? this.config.checklist.required.map(String) : []\n\t\t\treturn required.every((id) => this.items.some((item) => String(item.id) === id && item.met === true))\n\t\t},\n\n\t\t/** @return {boolean} Whether a reason is asked and needed. */\n\t\treasonNeeded() {\n\t\t\treturn Boolean(this.config.reason) && this.config.reason.required !== false\n\t\t},\n\n\t\t/** @return {string} The reason field's label. */\n\t\treasonLabel() {\n\t\t\treturn this.text(this.config.reason && this.config.reason.label) || t('nextcloud-vue', 'Reason')\n\t\t},\n\n\t\t/** @return {string} The note's NcNoteCard type. */\n\t\tnoteType() {\n\t\t\tconst variant = this.config.note && this.config.note.variant\n\t\t\treturn ['info', 'warning', 'error', 'success'].includes(variant) ? variant : 'info'\n\t\t},\n\n\t\t/**\n\t\t * Whether the action may run: allowed, required items met, a reason\n\t\t * when one is needed, and nothing in flight.\n\t\t *\n\t\t * @spec openspec/changes/action-dialog/specs/action-dialog/spec.md#requirement-a-manifest-configures-an-action-dialog\n\t\t * @return {boolean}\n\t\t */\n\t\tcanConfirm() {\n\t\t\treturn !this.busy && this.allowed && this.requiredMet && this.fieldsFilled && (!this.reasonNeeded || this.reason.trim() !== '')\n\t\t},\n\n\t\t/** @return {string} The eyebrow, filled from the record once it is known. */\n\t\teyebrowText() {\n\t\t\treturn this.record ? this.fill(this.config.eyebrow) || this.text(this.config.eyebrow) : this.text(this.config.eyebrow)\n\t\t},\n\n\t\t/** @return {Array<object>} The fields with a name. */\n\t\tfields() {\n\t\t\treturn (Array.isArray(this.config.fields) ? this.config.fields : []).filter((f) => f && f.field)\n\t\t},\n\n\t\t/**\n\t\t * Whether every required field has a value.\n\t\t *\n\t\t * @spec openspec/changes/action-dialog-fields-and-acts/specs/action-dialog/spec.md#requirement-an-action-dialog-asks-for-fields-and-reads-a-permission-from-a-list\n\t\t * @return {boolean}\n\t\t */\n\t\tfieldsFilled() {\n\t\t\treturn this.fields.every((f) => f.required === false || String(this.values[f.field] ?? '').trim() !== '')\n\t\t},\n\t},\n\n\tasync mounted() {\n\t\tawait Promise.all([this.loadRecord(), this.loadChecklist(), this.loadPermission()])\n\t},\n\n\tmethods: {\n\t\tt,\n\n\t\t/**\n\t\t * A config text through the host translate, '' for anything else.\n\t\t *\n\t\t * @param {unknown} value The text.\n\t\t * @return {string}\n\t\t */\n\t\ttext(value) {\n\t\t\treturn typeof value === 'string' && value !== '' ? this.cnTranslate(value) : ''\n\t\t},\n\n\t\t/**\n\t\t * A template filled from a row (the record by default), translated first.\n\t\t *\n\t\t * @param {unknown} template The template.\n\t\t * @param {object} [row] The row.\n\t\t * @return {string}\n\t\t */\n\t\tfill(template, row) {\n\t\t\tif (typeof template !== 'string' || template === '') {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t\treturn fillTemplate(this.cnTranslate(template), row || this.record || {}).trim()\n\t\t},\n\n\t\t/**\n\t\t * Read an endpoint, fresh.\n\t\t *\n\t\t * @param {object} source An endpointSource block.\n\t\t * @return {Promise<unknown>}\n\t\t */\n\t\tread(source) {\n\t\t\treturn fetchEndpointSource(source, this.tokenCtx, { fresh: true })\n\t\t},\n\n\t\t/** @return {Promise<void>} */\n\t\tasync loadRecord() {\n\t\t\tconst source = this.config.summary && this.config.summary.source\n\t\t\tif (!source || !source.url) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst data = await this.read(source)\n\t\t\t\tthis.record = data && typeof data === 'object' ? data : this.record\n\t\t\t} catch {\n\t\t\t\t// The summary stays empty; the checklist and the action still work.\n\t\t\t}\n\t\t},\n\n\t\t/** @return {Promise<void>} */\n\t\tasync loadChecklist() {\n\t\t\tconst def = this.config.checklist\n\t\t\tif (!def || !def.source || !def.source.url) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst data = await this.read(def.source)\n\t\t\t\tconst list = def.itemsPath ? readPath(data, def.itemsPath) : data\n\t\t\t\tthis.items = Array.isArray(list) ? list.filter((item) => item && item.id !== undefined) : []\n\t\t\t} catch {\n\t\t\t\tthis.items = []\n\t\t\t\tthis.checklistError = t('nextcloud-vue', 'Whether this is ready could not be read.')\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * The entry of a list whose fields equal `match`, or null.\n\t\t *\n\t\t * @param {unknown} list The list.\n\t\t * @param {object} [match] The fields to match.\n\t\t * @return {object|null}\n\t\t */\n\t\tmatchIn(list, match) {\n\t\t\tconst wanted = Object.entries(match || {})\n\t\t\treturn (Array.isArray(list) ? list : []).find((entry) => entry && wanted.every(([key, value]) => String(entry[key]) === String(value))) || null\n\t\t},\n\n\t\t/**\n\t\t * A select field's options, labels translated.\n\t\t *\n\t\t * @param {object} field The field.\n\t\t * @return {Array<{id: string, label: string, fills?: object}>}\n\t\t */\n\t\toptionsOf(field) {\n\t\t\treturn (Array.isArray(field.options) ? field.options : []).map((o) => ({ id: String(o.value), label: this.text(o.label) || String(o.value), fills: o.fills }))\n\t\t},\n\n\t\t/**\n\t\t * A select field's chosen option.\n\t\t *\n\t\t * @param {object} field The field.\n\t\t * @return {object|null}\n\t\t */\n\t\tselectedOption(field) {\n\t\t\treturn this.optionsOf(field).find((o) => o.id === String(this.values[field.field] ?? '')) || null\n\t\t},\n\n\t\t/**\n\t\t * Set a field's value.\n\t\t *\n\t\t * @param {string} name The field.\n\t\t * @param {unknown} value The value.\n\t\t */\n\t\tsetValue(name, value) {\n\t\t\tthis.values = { ...this.values, [name]: value === null || value === undefined ? '' : String(value) }\n\t\t},\n\n\t\t/**\n\t\t * Choose a select option; its `fills` set the fields still empty.\n\t\t *\n\t\t * @param {object} field The select field.\n\t\t * @param {{id: string, fills?: object}|null} option The option.\n\t\t */\n\t\tpick(field, option) {\n\t\t\tthis.setValue(field.field, option ? option.id : '')\n\t\t\tfor (const [name, value] of Object.entries((option && option.fills) || {})) {\n\t\t\t\tif (String(this.values[name] ?? '').trim() === '') {\n\t\t\t\t\tthis.setValue(name, this.text(value) || value)\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t/** @return {Promise<void>} */\n\t\tasync loadPermission() {\n\t\t\tconst def = this.config.permission\n\t\t\tif (!def || !def.source || !def.source.url) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst data = await this.read(def.source)\n\t\t\t\tconst entry = def.listPath ? this.matchIn(readPath(data, def.listPath), def.match) : data\n\t\t\t\tthis.allowed = readPath(entry, def.allowedPath || 'allowed') === true\n\t\t\t\tthis.refusal = this.allowed || !def.reasonPath ? '' : String(readPath(entry, def.reasonPath) || '')\n\t\t\t} catch {\n\t\t\t\tthis.allowed = false\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Run the action once: post `confirm.request`, or dispatch\n\t\t * `confirm.action`, then show the done text and refresh the page.\n\t\t *\n\t\t * @spec openspec/changes/action-dialog/specs/action-dialog/spec.md#requirement-a-manifest-configures-an-action-dialog\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync confirm() {\n\t\t\tif (!this.canConfirm) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.busy = true\n\t\t\tthis.refusal = ''\n\t\t\tconst reason = this.reason.trim()\n\t\t\ttry {\n\t\t\t\tconst request = this.confirmConfig.request\n\t\t\t\tif (request && request.url) {\n\t\t\t\t\tconst url = interpolateUrlTokens(request.url, this.tokenCtx)\n\t\t\t\t\tconst body = {}\n\t\t\t\t\tfor (const [key, value] of Object.entries(request.body || {})) {\n\t\t\t\t\t\tbody[key] = typeof value === 'string' ? fillTemplate(value, { ...(this.record || {}), reason }) : value\n\t\t\t\t\t}\n\t\t\t\t\tif (this.config.reason) {\n\t\t\t\t\t\tbody[this.config.reason.field || 'reason'] = reason\n\t\t\t\t\t}\n\t\t\t\t\tfor (const field of this.fields) {\n\t\t\t\t\t\tbody[field.field] = this.values[field.field] ?? ''\n\t\t\t\t\t}\n\t\t\t\t\tconst method = String(request.method || 'POST').toLowerCase()\n\t\t\t\t\tawait axios[['post', 'put', 'patch', 'delete'].includes(method) ? method : 'post'](/^https?:\\/\\//i.test(url) ? url : generateUrl(url), body)\n\t\t\t\t} else if (this.confirmConfig.action && typeof this.cnDispatchAction === 'function') {\n\t\t\t\t\tawait this.cnDispatchAction({ ...this.confirmConfig.action, args: [...(this.confirmConfig.action.args || []), { ...this.values, reason }] })\n\t\t\t\t}\n\t\t\t\tthis.done = true\n\t\t\t\temit(PAGE_REFRESH, {})\n\t\t\t\t/** @event done The action ran. Payload: the field values and `reason`. */\n\t\t\t\tthis.$emit('done', { ...this.values, reason })\n\t\t\t} catch (failure) {\n\t\t\t\tconst data = failure && failure.response && failure.response.data\n\t\t\t\tthis.refusal = String((data && (data.message || data.error)) || t('nextcloud-vue', 'The action could not be completed.'))\n\t\t\t} finally {\n\t\t\t\tthis.busy = false\n\t\t\t}\n\t\t},\n\n\t\t/** Close the dialog, unless the action is running. */\n\t\tclose() {\n\t\t\tif (this.busy) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\t/** @event close The dialog was closed. */\n\t\t\tthis.$emit('close')\n\t\t},\n\t},\n}\n</script>\n\n<style scoped>\n.cn-action-dialog {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 16px;\n}\n\n.cn-action-dialog__summary {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 10px;\n\tpadding: 12px 14px;\n\tborder: 1px solid var(--color-border);\n\tborder-radius: var(--border-radius-large, 8px);\n}\n\n.cn-action-dialog__summary-text {\n\tdisplay: flex;\n\tflex: 1 1 auto;\n\tflex-direction: column;\n\tmin-width: 0;\n}\n\n.cn-action-dialog__badge {\n\tpadding: 3px 10px;\n\tborder-radius: 12px;\n\tbackground: var(--color-background-dark);\n\tfont-size: 13px;\n\tfont-weight: 600;\n\twhite-space: nowrap;\n}\n\n.cn-action-dialog__title {\n\tmargin: 0 0 8px;\n\tfont-size: 15px;\n\tfont-weight: 700;\n}\n\n.cn-action-dialog__facts {\n\tdisplay: grid;\n\tgrid-template-columns: repeat(auto-fit, minmax(180px, 1fr));\n\tgap: 8px 16px;\n\tmargin: 0;\n}\n\n.cn-action-dialog__facts dt {\n\tcolor: var(--color-text-maxcontrast);\n\tfont-size: 13px;\n}\n\n.cn-action-dialog__facts dd {\n\tmargin: 0;\n}\n\n.cn-action-dialog__checks {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 8px;\n\tmargin: 0;\n\tpadding: 0;\n\tlist-style: none;\n}\n\n.cn-action-dialog__check {\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\talign-items: center;\n\tgap: 8px;\n}\n\n.cn-action-dialog__check-icon {\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-action-dialog__check-icon--met {\n\tcolor: var(--color-success-text, var(--color-success));\n}\n\n.cn-action-dialog__muted {\n\tcolor: var(--color-text-maxcontrast);\n\tfont-size: 14px;\n}\n\n.cn-action-dialog__field {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 4px;\n}\n\n.cn-action-dialog__error {\n\tmargin: 0;\n\tcolor: var(--color-error-text, var(--color-error));\n}\n</style>\n"],"names":["_createVNode","_createBlock","_createTextVNode","_openBlock","_createElementBlock","_createElementVNode","_toDisplayString","_Fragment","_renderList"],"mappings":"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"}