@conduction/nextcloud-vue 2.132.0 → 2.134.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 (107) hide show
  1. package/dist/esm/components/CnActionButtons/CnActionButtons.vue.js +1 -1
  2. package/dist/esm/components/CnActionButtons/CnActionButtons.vue2.js +14 -0
  3. package/dist/esm/components/CnActionButtons/CnActionButtons.vue2.js.map +1 -1
  4. package/dist/esm/components/CnActionButtons/CnActionButtons.vue3.js +5 -4
  5. package/dist/esm/components/CnActionButtons/CnActionButtons.vue3.js.map +1 -1
  6. package/dist/esm/components/CnConditionListEditor/CnConditionListEditor.vue.js +9 -0
  7. package/dist/esm/components/CnConditionListEditor/CnConditionListEditor.vue.js.map +1 -0
  8. package/dist/esm/components/CnConditionListEditor/CnConditionListEditor.vue2.js +237 -0
  9. package/dist/esm/components/CnConditionListEditor/CnConditionListEditor.vue2.js.map +1 -0
  10. package/dist/esm/components/CnConditionListEditor/CnConditionListEditor.vue3.js +103 -0
  11. package/dist/esm/components/CnConditionListEditor/CnConditionListEditor.vue3.js.map +1 -0
  12. package/dist/esm/components/CnConditionListEditor/conditionOperators.js +121 -0
  13. package/dist/esm/components/CnConditionListEditor/conditionOperators.js.map +1 -0
  14. package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js +12 -0
  15. package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js.map +1 -1
  16. package/dist/esm/components/CnDetailPage/CnDetailPage.vue3.js +1 -1
  17. package/dist/esm/components/CnDetailPage/CnDetailPage.vue3.js.map +1 -1
  18. package/dist/esm/components/CnFieldListWidget/CnFieldListWidget.vue.js +1 -1
  19. package/dist/esm/components/CnFieldListWidget/CnFieldListWidget.vue2.js +85 -10
  20. package/dist/esm/components/CnFieldListWidget/CnFieldListWidget.vue2.js.map +1 -1
  21. package/dist/esm/components/CnFieldListWidget/CnFieldListWidget.vue3.js +60 -36
  22. package/dist/esm/components/CnFieldListWidget/CnFieldListWidget.vue3.js.map +1 -1
  23. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js +8 -1
  24. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js.map +1 -1
  25. package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js.map +1 -1
  26. package/dist/esm/components/CnIntegrationWidget/CnIntegrationWidget.vue.js +1 -1
  27. package/dist/esm/components/CnIntegrationWidget/CnIntegrationWidget.vue2.js +10 -0
  28. package/dist/esm/components/CnIntegrationWidget/CnIntegrationWidget.vue2.js.map +1 -1
  29. package/dist/esm/components/CnIntegrationWidget/CnIntegrationWidget.vue3.js.map +1 -1
  30. package/dist/esm/components/CnNcWidgetWidget/CnNcWidgetWidget.vue.js +1 -1
  31. package/dist/esm/components/CnNcWidgetWidget/CnNcWidgetWidget.vue2.js +46 -7
  32. package/dist/esm/components/CnNcWidgetWidget/CnNcWidgetWidget.vue2.js.map +1 -1
  33. package/dist/esm/components/CnNcWidgetWidget/CnNcWidgetWidget.vue3.js +1 -1
  34. package/dist/esm/components/CnNcWidgetWidget/CnNcWidgetWidget.vue3.js.map +1 -1
  35. package/dist/esm/components/CnObjectPartiesWidget/CnObjectPartiesWidget.vue.js +1 -1
  36. package/dist/esm/components/CnObjectPartiesWidget/CnObjectPartiesWidget.vue2.js +258 -6
  37. package/dist/esm/components/CnObjectPartiesWidget/CnObjectPartiesWidget.vue2.js.map +1 -1
  38. package/dist/esm/components/CnObjectPartiesWidget/CnObjectPartiesWidget.vue3.js +283 -131
  39. package/dist/esm/components/CnObjectPartiesWidget/CnObjectPartiesWidget.vue3.js.map +1 -1
  40. package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue.js +1 -1
  41. package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue2.js +42 -2
  42. package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue2.js.map +1 -1
  43. package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue3.js.map +1 -1
  44. package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue.js +1 -1
  45. package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue2.js +1 -1
  46. package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue2.js.map +1 -1
  47. package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue3.js.map +1 -1
  48. package/dist/esm/dialogs/CnPartyAddDialog.vue.js +9 -0
  49. package/dist/esm/dialogs/CnPartyAddDialog.vue.js.map +1 -0
  50. package/dist/esm/dialogs/CnPartyAddDialog.vue2.js +184 -0
  51. package/dist/esm/dialogs/CnPartyAddDialog.vue2.js.map +1 -0
  52. package/dist/esm/dialogs/CnPartyAddDialog.vue3.js +168 -0
  53. package/dist/esm/dialogs/CnPartyAddDialog.vue3.js.map +1 -0
  54. package/dist/esm/index.js +2 -0
  55. package/dist/esm/index.js.map +1 -1
  56. package/dist/esm/l10n/en.json.js +27 -1
  57. package/dist/esm/l10n/en.json.js.map +1 -1
  58. package/dist/esm/l10n/nl.json.js +27 -1
  59. package/dist/esm/l10n/nl.json.js.map +1 -1
  60. package/dist/esm/library-style.js +1 -1
  61. package/dist/esm/nextcloud-vue.css +353 -217
  62. package/dist/esm/store/plugins/liveUpdates.js +13 -4
  63. package/dist/esm/store/plugins/liveUpdates.js.map +1 -1
  64. package/dist/esm/store/useObjectStore.js +28 -5
  65. package/dist/esm/store/useObjectStore.js.map +1 -1
  66. package/dist/esm/utils/detailActionModel.js +6 -0
  67. package/dist/esm/utils/detailActionModel.js.map +1 -1
  68. package/dist/esm/utils/listLenses.js +20 -1
  69. package/dist/esm/utils/listLenses.js.map +1 -1
  70. package/dist/esm/utils/objectParties.js +79 -1
  71. package/dist/esm/utils/objectParties.js.map +1 -1
  72. package/dist/esm/utils/objectRows.js +59 -0
  73. package/dist/esm/utils/objectRows.js.map +1 -0
  74. package/dist/esm/utils/validateManifestV2.compiled.js +3 -3
  75. package/dist/esm/utils/validateManifestV2.compiled.js.map +1 -1
  76. package/dist/nextcloud-vue.cjs.js +7460 -5803
  77. package/dist/nextcloud-vue.cjs.js.map +2 -2
  78. package/dist/nextcloud-vue.css +353 -217
  79. package/l10n/en.json +27 -1
  80. package/l10n/nl.json +27 -1
  81. package/package.json +1 -1
  82. package/src/components/CnActionButtons/CnActionButtons.vue +15 -0
  83. package/src/components/CnConditionListEditor/CnConditionListEditor.vue +346 -0
  84. package/src/components/CnConditionListEditor/conditionOperators.js +126 -0
  85. package/src/components/CnConditionListEditor/index.js +17 -0
  86. package/src/components/CnDetailPage/CnDetailPage.md +1 -0
  87. package/src/components/CnDetailPage/CnDetailPage.vue +13 -1
  88. package/src/components/CnFieldListWidget/CnFieldListWidget.vue +105 -12
  89. package/src/components/CnIndexPage/CnIndexPage.vue +8 -1
  90. package/src/components/CnIntegrationWidget/CnIntegrationWidget.vue +10 -0
  91. package/src/components/CnNcWidgetWidget/CnNcWidgetWidget.vue +47 -8
  92. package/src/components/CnObjectPartiesWidget/CnObjectPartiesWidget.vue +401 -3
  93. package/src/components/CnRecordListWidget/CnRecordListWidget.vue +42 -2
  94. package/src/components/CnTabsWidget/CnTabsWidget.vue +1 -1
  95. package/src/components/index.js +1 -0
  96. package/src/css/look-board-index.css +6 -0
  97. package/src/css/look-board.css +35 -7
  98. package/src/dialogs/CnPartyAddDialog.vue +309 -0
  99. package/src/index.js +2 -0
  100. package/src/schemas/app-manifest-v2.schema.json +17 -1
  101. package/src/store/plugins/liveUpdates.js +13 -4
  102. package/src/store/useObjectStore.js +28 -5
  103. package/src/utils/detailActionModel.js +6 -0
  104. package/src/utils/listLenses.js +20 -1
  105. package/src/utils/objectParties.js +78 -0
  106. package/src/utils/objectRows.js +55 -0
  107. package/src/utils/validateManifestV2.compiled.js +3 -3
@@ -0,0 +1,103 @@
1
+ import { resolveComponent, openBlock, createElementBlock, toDisplayString, createCommentVNode, Fragment, renderList, createVNode, createBlock, withCtx, createTextVNode } from 'vue';
2
+
3
+ const _hoisted_1 = { class: "cn-condition-list" };
4
+ const _hoisted_2 = {
5
+ key: 0,
6
+ class: "cn-condition-list__label"
7
+ };
8
+ const _hoisted_3 = {
9
+ key: 1,
10
+ class: "cn-condition-list__empty"
11
+ };
12
+
13
+ function render(_ctx, _cache, $props, $setup, $data, $options) {
14
+ const _component_NcSelect = resolveComponent("NcSelect");
15
+ const _component_NcTextField = resolveComponent("NcTextField");
16
+ const _component_Close = resolveComponent("Close");
17
+ const _component_NcButton = resolveComponent("NcButton");
18
+ const _component_Plus = resolveComponent("Plus");
19
+
20
+ return (openBlock(), createElementBlock("fieldset", _hoisted_1, [
21
+ ($props.label)
22
+ ? (openBlock(), createElementBlock("legend", _hoisted_2, toDisplayString($props.label), 1 /* TEXT */))
23
+ : createCommentVNode("v-if", true),
24
+ ($data.rows.length === 0)
25
+ ? (openBlock(), createElementBlock("p", _hoisted_3, toDisplayString($props.emptyText || $options.t('nextcloud-vue', 'No conditions: the rule always applies.')), 1 /* TEXT */))
26
+ : createCommentVNode("v-if", true),
27
+ (openBlock(true), createElementBlock(Fragment, null, renderList($data.rows, (row, i) => {
28
+ return (openBlock(), createElementBlock("div", {
29
+ key: i,
30
+ class: "cn-condition-list__row"
31
+ }, [
32
+ createVNode(_component_NcSelect, {
33
+ class: "cn-condition-list__field",
34
+ modelValue: $options.fieldOption(row.field),
35
+ options: $options.fieldOptions,
36
+ label: "label",
37
+ inputLabel: $options.t('nextcloud-vue', 'Field'),
38
+ clearable: false,
39
+ "onUpdate:modelValue": $event => ($options.setField(i, $event))
40
+ }, null, 8 /* PROPS */, ["modelValue", "options", "inputLabel", "onUpdate:modelValue"]),
41
+ createVNode(_component_NcSelect, {
42
+ class: "cn-condition-list__operator",
43
+ modelValue: $options.operatorOption(row.operator),
44
+ options: $options.operatorOptions(row.field),
45
+ label: "label",
46
+ inputLabel: $options.t('nextcloud-vue', 'Operator'),
47
+ clearable: false,
48
+ disabled: !row.field,
49
+ "onUpdate:modelValue": $event => ($options.setOperator(i, $event))
50
+ }, null, 8 /* PROPS */, ["modelValue", "options", "inputLabel", "disabled", "onUpdate:modelValue"]),
51
+ ($options.takesValue(row.operator))
52
+ ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [
53
+ ($options.valueOptions(row.field))
54
+ ? (openBlock(), createBlock(_component_NcSelect, {
55
+ key: 0,
56
+ class: "cn-condition-list__value",
57
+ modelValue: $options.valueOption(row),
58
+ options: $options.valueOptions(row.field),
59
+ label: "label",
60
+ inputLabel: $options.t('nextcloud-vue', 'Value'),
61
+ clearable: false,
62
+ "onUpdate:modelValue": $event => ($options.setValue(i, $event ? $event.id : ''))
63
+ }, null, 8 /* PROPS */, ["modelValue", "options", "inputLabel", "onUpdate:modelValue"]))
64
+ : (openBlock(), createBlock(_component_NcTextField, {
65
+ key: 1,
66
+ class: "cn-condition-list__value",
67
+ type: $options.inputType(row.field),
68
+ modelValue: row.value === undefined || row.value === null ? '' : String(row.value),
69
+ label: $options.t('nextcloud-vue', 'Value'),
70
+ "onUpdate:modelValue": $event => ($options.setValue(i, $options.typedValue(row.field, $event)))
71
+ }, null, 8 /* PROPS */, ["type", "modelValue", "label", "onUpdate:modelValue"]))
72
+ ], 64 /* STABLE_FRAGMENT */))
73
+ : createCommentVNode("v-if", true),
74
+ createVNode(_component_NcButton, {
75
+ variant: "tertiary",
76
+ "aria-label": $options.t('nextcloud-vue', 'Remove condition'),
77
+ onClick: $event => ($options.remove(i))
78
+ }, {
79
+ icon: withCtx(() => [
80
+ createVNode(_component_Close, { size: 18 })
81
+ ]),
82
+ _: 1 /* STABLE */
83
+ }, 8 /* PROPS */, ["aria-label", "onClick"])
84
+ ]))
85
+ }), 128 /* KEYED_FRAGMENT */)),
86
+ createVNode(_component_NcButton, {
87
+ variant: "tertiary",
88
+ disabled: $props.fields.length === 0,
89
+ onClick: $options.add
90
+ }, {
91
+ icon: withCtx(() => [
92
+ createVNode(_component_Plus, { size: 18 })
93
+ ]),
94
+ default: withCtx(() => [
95
+ createTextVNode(" " + toDisplayString($options.t('nextcloud-vue', 'Add condition')), 1 /* TEXT */)
96
+ ]),
97
+ _: 1 /* STABLE */
98
+ }, 8 /* PROPS */, ["disabled", "onClick"])
99
+ ]))
100
+ }
101
+
102
+ export { render };
103
+ //# sourceMappingURL=CnConditionListEditor.vue3.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CnConditionListEditor.vue3.js","sources":["../../../../src/components/CnConditionListEditor/CnConditionListEditor.vue?vue&type=template&id=f00a4cf2&lang.js"],"sourcesContent":["<!--\n - SPDX-FileCopyrightText: 2026 Conduction B.V.\n - SPDX-License-Identifier: EUPL-1.2\n-->\n\n<template>\n\t<fieldset class=\"cn-condition-list\">\n\t\t<legend v-if=\"label\" class=\"cn-condition-list__label\">\n\t\t\t{{ label }}\n\t\t</legend>\n\t\t<p v-if=\"rows.length === 0\" class=\"cn-condition-list__empty\">\n\t\t\t{{ emptyText || t('nextcloud-vue', 'No conditions: the rule always applies.') }}\n\t\t</p>\n\t\t<div\n\t\t\tv-for=\"(row, i) in rows\"\n\t\t\t:key=\"i\"\n\t\t\tclass=\"cn-condition-list__row\">\n\t\t\t<NcSelect\n\t\t\t\tclass=\"cn-condition-list__field\"\n\t\t\t\t:modelValue=\"fieldOption(row.field)\"\n\t\t\t\t:options=\"fieldOptions\"\n\t\t\t\tlabel=\"label\"\n\t\t\t\t:inputLabel=\"t('nextcloud-vue', 'Field')\"\n\t\t\t\t:clearable=\"false\"\n\t\t\t\t@update:modelValue=\"setField(i, $event)\" />\n\t\t\t<NcSelect\n\t\t\t\tclass=\"cn-condition-list__operator\"\n\t\t\t\t:modelValue=\"operatorOption(row.operator)\"\n\t\t\t\t:options=\"operatorOptions(row.field)\"\n\t\t\t\tlabel=\"label\"\n\t\t\t\t:inputLabel=\"t('nextcloud-vue', 'Operator')\"\n\t\t\t\t:clearable=\"false\"\n\t\t\t\t:disabled=\"!row.field\"\n\t\t\t\t@update:modelValue=\"setOperator(i, $event)\" />\n\t\t\t<template v-if=\"takesValue(row.operator)\">\n\t\t\t\t<NcSelect\n\t\t\t\t\tv-if=\"valueOptions(row.field)\"\n\t\t\t\t\tclass=\"cn-condition-list__value\"\n\t\t\t\t\t:modelValue=\"valueOption(row)\"\n\t\t\t\t\t:options=\"valueOptions(row.field)\"\n\t\t\t\t\tlabel=\"label\"\n\t\t\t\t\t:inputLabel=\"t('nextcloud-vue', 'Value')\"\n\t\t\t\t\t:clearable=\"false\"\n\t\t\t\t\t@update:modelValue=\"setValue(i, $event ? $event.id : '')\" />\n\t\t\t\t<NcTextField\n\t\t\t\t\tv-else\n\t\t\t\t\tclass=\"cn-condition-list__value\"\n\t\t\t\t\t:type=\"inputType(row.field)\"\n\t\t\t\t\t:modelValue=\"row.value === undefined || row.value === null ? '' : String(row.value)\"\n\t\t\t\t\t:label=\"t('nextcloud-vue', 'Value')\"\n\t\t\t\t\t@update:modelValue=\"setValue(i, typedValue(row.field, $event))\" />\n\t\t\t</template>\n\t\t\t<NcButton\n\t\t\t\tvariant=\"tertiary\"\n\t\t\t\t:aria-label=\"t('nextcloud-vue', 'Remove condition')\"\n\t\t\t\t@click=\"remove(i)\">\n\t\t\t\t<template #icon>\n\t\t\t\t\t<Close :size=\"18\" />\n\t\t\t\t</template>\n\t\t\t</NcButton>\n\t\t</div>\n\t\t<NcButton variant=\"tertiary\" :disabled=\"fields.length === 0\" @click=\"add\">\n\t\t\t<template #icon>\n\t\t\t\t<Plus :size=\"18\" />\n\t\t\t</template>\n\t\t\t{{ t('nextcloud-vue', 'Add condition') }}\n\t\t</NcButton>\n\t</fieldset>\n</template>\n\n<script>\nimport { translate as t } from '@nextcloud/l10n'\nimport { NcButton, NcSelect, NcTextField } from '@nextcloud/vue'\nimport Close from 'vue-material-design-icons/Close.vue'\nimport Plus from 'vue-material-design-icons/Plus.vue'\nimport { operatorLabel, operatorsForType, operatorTakesValue } from './conditionOperators.js'\n\n/**\n * CnConditionListEditor - the conditions of a rule as rows over an object's\n * own fields: field, operator, value. All rows hold together. The operators\n * follow the field's type (see `operatorsForType`), \"is filled in\" needs no\n * value, and the value is a choice for a choice or yes/no field.\n *\n * v-model on `{ field, operator, value }[]`, in both dialects (`value`/`input`\n * and `modelValue`/`update:modelValue`). Read a condition back as words with\n * `conditionSentence` from `./conditionOperators.js`.\n */\nexport default {\n\tname: 'CnConditionListEditor',\n\n\tcomponents: { NcButton, NcSelect, NcTextField, Close, Plus },\n\n\tprops: {\n\t\t/**\n\t\t * The conditions.\n\t\t *\n\t\t * @type {Array<{field: string, operator: string, value?: unknown}>}\n\t\t */\n\t\tvalue: { type: Array, default: () => [] },\n\t\t/**\n\t\t * The same value under Vue 3's v-model name; wins over `value` when passed.\n\t\t *\n\t\t * @type {Array}\n\t\t */\n\t\tmodelValue: { type: Array, default: undefined },\n\t\t/**\n\t\t * The fields a condition may name: `{ id, label, type, options?, format? }`.\n\t\t * `type` is number, integer, date, boolean, presence or anything else (text);\n\t\t * `options` (`[{ id, label }]`) make the value a choice.\n\t\t *\n\t\t * @type {Array<{id: string, label: string, type?: string, options?: Array}>}\n\t\t */\n\t\tfields: { type: Array, default: () => [] },\n\t\t/**\n\t\t * The legend above the rows, already translated.\n\t\t *\n\t\t * @type {string}\n\t\t */\n\t\tlabel: { type: String, default: '' },\n\t\t/**\n\t\t * What an empty list says, already translated.\n\t\t *\n\t\t * @type {string}\n\t\t */\n\t\temptyText: { type: String, default: '' },\n\t},\n\n\temits: ['input', 'update:modelValue'],\n\n\tdata() {\n\t\treturn {\n\t\t\trows: this.copy(this.modelValue !== undefined ? this.modelValue : this.value),\n\t\t}\n\t},\n\n\tcomputed: {\n\t\t/**\n\t\t * The field choices.\n\t\t *\n\t\t * @return {Array<{id: string, label: string}>}\n\t\t */\n\t\tfieldOptions() {\n\t\t\treturn this.fields.map((f) => ({ id: f.id, label: f.label || f.id }))\n\t\t},\n\t},\n\n\twatch: {\n\t\tvalue(next) {\n\t\t\tif (this.modelValue === undefined) {\n\t\t\t\tthis.rows = this.copy(next)\n\t\t\t}\n\t\t},\n\n\t\tmodelValue(next) {\n\t\t\tif (next !== undefined) {\n\t\t\t\tthis.rows = this.copy(next)\n\t\t\t}\n\t\t},\n\t},\n\n\tmethods: {\n\t\tt,\n\n\t\t/**\n\t\t * A detached copy of the bound conditions.\n\t\t *\n\t\t * @param {Array} list The conditions.\n\t\t * @return {Array} The copy.\n\t\t */\n\t\tcopy(list) {\n\t\t\treturn (Array.isArray(list) ? list : []).map((row) => ({ ...row }))\n\t\t},\n\n\t\t/**\n\t\t * The field with this id.\n\t\t *\n\t\t * @param {string} id The field id.\n\t\t * @return {object|undefined}\n\t\t */\n\t\tfieldOf(id) {\n\t\t\treturn this.fields.find((f) => f.id === id)\n\t\t},\n\n\t\tfieldOption(id) {\n\t\t\treturn this.fieldOptions.find((o) => o.id === id) || null\n\t\t},\n\n\t\toperatorOptions(fieldId) {\n\t\t\treturn operatorsForType(this.fieldOf(fieldId)?.type).map((id) => ({ id, label: operatorLabel(id) }))\n\t\t},\n\n\t\toperatorOption(operator) {\n\t\t\treturn operator ? { id: operator, label: operatorLabel(operator) } : null\n\t\t},\n\n\t\ttakesValue(operator) {\n\t\t\treturn operatorTakesValue(operator)\n\t\t},\n\n\t\t/**\n\t\t * The value choices of a field, or null when its value is typed.\n\t\t *\n\t\t * @param {string} fieldId The field id.\n\t\t * @return {Array<{id: string, label: string}>|null}\n\t\t */\n\t\tvalueOptions(fieldId) {\n\t\t\tconst field = this.fieldOf(fieldId)\n\t\t\tif (field?.type === 'boolean') {\n\t\t\t\treturn [\n\t\t\t\t\t{ id: true, label: t('nextcloud-vue', 'Yes') },\n\t\t\t\t\t{ id: false, label: t('nextcloud-vue', 'No') },\n\t\t\t\t]\n\t\t\t}\n\t\t\tif (Array.isArray(field?.options) && field.options.length > 0) {\n\t\t\t\treturn field.options.map((o) => (typeof o === 'object'\n\t\t\t\t\t? { id: o.id ?? o.value, label: o.label ?? String(o.id ?? o.value) }\n\t\t\t\t\t: { id: o, label: String(o) }))\n\t\t\t}\n\t\t\treturn null\n\t\t},\n\n\t\tvalueOption(row) {\n\t\t\treturn (this.valueOptions(row.field) || []).find((o) => String(o.id) === String(row.value)) || null\n\t\t},\n\n\t\tinputType(fieldId) {\n\t\t\tconst type = this.fieldOf(fieldId)?.type\n\t\t\tif (type === 'number' || type === 'integer') {\n\t\t\t\treturn 'number'\n\t\t\t}\n\t\t\treturn type === 'date' ? 'date' : 'text'\n\t\t},\n\n\t\t/**\n\t\t * A typed value as stored: a number for a number field.\n\t\t *\n\t\t * @param {string} fieldId The field id.\n\t\t * @param {string} raw What was typed.\n\t\t * @return {string|number}\n\t\t */\n\t\ttypedValue(fieldId, raw) {\n\t\t\tconst type = this.fieldOf(fieldId)?.type\n\t\t\tif ((type === 'number' || type === 'integer') && raw !== '' && !Number.isNaN(Number(raw))) {\n\t\t\t\treturn Number(raw)\n\t\t\t}\n\t\t\treturn raw\n\t\t},\n\n\t\tsetField(i, option) {\n\t\t\tconst field = this.fieldOf(option?.id)\n\t\t\tconst operators = operatorsForType(field?.type)\n\t\t\tthis.rows[i] = { field: option?.id || '', operator: operators[0], value: field?.type === 'boolean' ? true : '' }\n\t\t\tthis.emitRows()\n\t\t},\n\n\t\tsetOperator(i, option) {\n\t\t\tconst row = { ...this.rows[i], operator: option?.id || 'eq' }\n\t\t\tif (!operatorTakesValue(row.operator)) {\n\t\t\t\tdelete row.value\n\t\t\t} else if (row.value === undefined) {\n\t\t\t\trow.value = ''\n\t\t\t}\n\t\t\tthis.rows[i] = row\n\t\t\tthis.emitRows()\n\t\t},\n\n\t\tsetValue(i, value) {\n\t\t\tthis.rows[i] = { ...this.rows[i], value }\n\t\t\tthis.emitRows()\n\t\t},\n\n\t\tadd() {\n\t\t\tthis.rows.push({ field: '', operator: 'eq', value: '' })\n\t\t\tthis.emitRows()\n\t\t},\n\n\t\tremove(i) {\n\t\t\tthis.rows.splice(i, 1)\n\t\t\tthis.emitRows()\n\t\t},\n\n\t\t/**\n\t\t * Tell the consumer, in both v-model dialects.\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\temitRows() {\n\t\t\tconst next = this.copy(this.rows)\n\t\t\t/**\n\t\t\t * The conditions changed.\n\t\t\t *\n\t\t\t * @event input\n\t\t\t * @type {Array}\n\t\t\t */\n\t\t\tthis.$emit('input', next)\n\t\t\t/**\n\t\t\t * The conditions changed (Vue 3 v-model).\n\t\t\t *\n\t\t\t * @event update:modelValue\n\t\t\t * @type {Array}\n\t\t\t */\n\t\t\tthis.$emit('update:modelValue', next)\n\t\t},\n\t},\n}\n</script>\n\n<style scoped>\n.cn-condition-list {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 8px;\n\tborder: 0;\n\tmargin: 0;\n\tpadding: 0;\n\tmin-width: 0;\n}\n\n.cn-condition-list__label {\n\tfont-weight: 600;\n\tpadding: 0;\n\tmargin-bottom: 4px;\n}\n\n.cn-condition-list__empty {\n\tcolor: var(--color-text-maxcontrast);\n\tmargin: 0;\n}\n\n.cn-condition-list__row {\n\tdisplay: grid;\n\tgrid-template-columns: minmax(0, 2fr) minmax(0, 1.4fr) minmax(0, 1.6fr) auto;\n\tgap: 8px;\n\talign-items: end;\n}\n\n.cn-condition-list__row > :nth-child(3):last-child {\n\tgrid-column: 4;\n}\n\n@media (max-width: 640px) {\n\t.cn-condition-list__row {\n\t\tgrid-template-columns: minmax(0, 1fr) auto;\n\t}\n}\n</style>\n"],"names":["_openBlock","_createElementBlock","_toDisplayString","_Fragment","_renderList","_createVNode","_createBlock"],"mappings":"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"}
@@ -0,0 +1,121 @@
1
+ import { translate, getCanonicalLocale } from '@nextcloud/l10n';
2
+
3
+ /**
4
+ * SPDX-FileCopyrightText: 2026 Conduction B.V.
5
+ * SPDX-License-Identifier: EUPL-1.2
6
+ *
7
+ * The operators a condition can use on a field of a given type, and a
8
+ * condition written as the words of a rule ("Bouwkosten groter is dan
9
+ * € 100.000"). Shared by CnConditionListEditor and the apps that list rules.
10
+ *
11
+ * @module components/CnConditionListEditor/conditionOperators
12
+ */
13
+
14
+
15
+ const OPERATORS_BY_TYPE = Object.freeze({
16
+ number: ['eq', 'neq', 'gt', 'gte', 'lt', 'lte', 'present'],
17
+ integer: ['eq', 'neq', 'gt', 'gte', 'lt', 'lte', 'present'],
18
+ date: ['eq', 'neq', 'gt', 'gte', 'lt', 'lte', 'present'],
19
+ boolean: ['eq'],
20
+ presence: ['present'],
21
+ });
22
+
23
+ const DEFAULT_OPERATORS = Object.freeze(['eq', 'neq', 'present']);
24
+
25
+ /**
26
+ * The operators that fit a field type.
27
+ *
28
+ * Numbers and dates compare; yes/no is only "is"; a `presence` field (a
29
+ * document, a relation) can only be filled in; text and choices say is, is not
30
+ * or is filled in.
31
+ *
32
+ * @param {string} type The field type.
33
+ * @return {string[]} The operator ids.
34
+ */
35
+ function operatorsForType(type) {
36
+ return [...(OPERATORS_BY_TYPE[type] || DEFAULT_OPERATORS)]
37
+ }
38
+
39
+ /**
40
+ * The label of an operator in the editor's operator choice.
41
+ *
42
+ * @param {string} operator The operator id.
43
+ * @return {string} The translated label.
44
+ */
45
+ function operatorLabel(operator) {
46
+ switch (operator) {
47
+ case 'eq': return translate('nextcloud-vue', 'is')
48
+ case 'neq': return translate('nextcloud-vue', 'is not')
49
+ case 'gt': return translate('nextcloud-vue', 'greater than')
50
+ case 'gte': return translate('nextcloud-vue', 'at least')
51
+ case 'lt': return translate('nextcloud-vue', 'less than')
52
+ case 'lte': return translate('nextcloud-vue', 'at most')
53
+ case 'present': return translate('nextcloud-vue', 'is filled in')
54
+ default: return String(operator || '')
55
+ }
56
+ }
57
+
58
+ /**
59
+ * Whether an operator needs a value.
60
+ *
61
+ * @param {string} operator The operator id.
62
+ * @return {boolean} False for `present`.
63
+ */
64
+ function operatorTakesValue(operator) {
65
+ return operator !== 'present'
66
+ }
67
+
68
+ /**
69
+ * A condition's value as a reader sees it, formatted by its field.
70
+ *
71
+ * @param {unknown} value The stored value.
72
+ * @param {object|undefined} field The field (`type`, `format`, `options`).
73
+ * @return {string} The formatted value.
74
+ */
75
+ function formatConditionValue(value, field) {
76
+ const type = field?.type;
77
+ if (type === 'boolean') {
78
+ const yes = value === true || value === 'true' || value === 1 || value === '1';
79
+ return yes ? translate('nextcloud-vue', 'yes') : translate('nextcloud-vue', 'no')
80
+ }
81
+ if (Array.isArray(field?.options)) {
82
+ const option = field.options.find((o) => String(o?.id ?? o?.value ?? o) === String(value));
83
+ if (option && typeof option === 'object') {
84
+ return String(option.label ?? option.id ?? value)
85
+ }
86
+ }
87
+ if ((type === 'number' || type === 'integer') && value !== '' && value !== null && !Number.isNaN(Number(value))) {
88
+ const options = field?.format === 'currency'
89
+ ? { style: 'currency', currency: field.currency || 'EUR', maximumFractionDigits: 0 }
90
+ : {};
91
+ return new Intl.NumberFormat(getCanonicalLocale() || undefined, options).format(Number(value))
92
+ }
93
+ return String(value ?? '')
94
+ }
95
+
96
+ /**
97
+ * A condition as the clause of a rule, after "Als" / "If".
98
+ *
99
+ * @param {{field: string, operator: string, value?: unknown}} condition The condition.
100
+ * @param {Array<{id: string, label?: string, type?: string}>} fields The fields the condition may name.
101
+ * @return {string} The translated clause, for example "Bouwkosten groter is dan € 100.000".
102
+ */
103
+ function conditionSentence(condition, fields = []) {
104
+ const field = (fields || []).find((f) => f?.id === condition?.field);
105
+ const vars = {
106
+ field: field?.label || condition?.field || '',
107
+ value: formatConditionValue(condition?.value, field),
108
+ };
109
+ switch (condition?.operator) {
110
+ case 'neq': return translate('nextcloud-vue', '{field} is not {value}', vars)
111
+ case 'gt': return translate('nextcloud-vue', '{field} is greater than {value}', vars)
112
+ case 'gte': return translate('nextcloud-vue', '{field} is at least {value}', vars)
113
+ case 'lt': return translate('nextcloud-vue', '{field} is less than {value}', vars)
114
+ case 'lte': return translate('nextcloud-vue', '{field} is at most {value}', vars)
115
+ case 'present': return translate('nextcloud-vue', '{field} is filled in', vars)
116
+ default: return translate('nextcloud-vue', '{field} is {value}', vars)
117
+ }
118
+ }
119
+
120
+ export { conditionSentence, formatConditionValue, operatorLabel, operatorTakesValue, operatorsForType };
121
+ //# sourceMappingURL=conditionOperators.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conditionOperators.js","sources":["../../../../src/components/CnConditionListEditor/conditionOperators.js"],"sourcesContent":["/**\n * SPDX-FileCopyrightText: 2026 Conduction B.V.\n * SPDX-License-Identifier: EUPL-1.2\n *\n * The operators a condition can use on a field of a given type, and a\n * condition written as the words of a rule (\"Bouwkosten groter is dan\n * € 100.000\"). Shared by CnConditionListEditor and the apps that list rules.\n *\n * @module components/CnConditionListEditor/conditionOperators\n */\n\nimport { getCanonicalLocale, translate as t } from '@nextcloud/l10n'\n\n/**\n * Every operator, in the order the editor offers them.\n *\n * `present` needs no value: the field is filled in.\n *\n * @type {ReadonlyArray<string>}\n */\nexport const CONDITION_OPERATORS = Object.freeze(['eq', 'neq', 'gt', 'gte', 'lt', 'lte', 'present'])\n\nconst OPERATORS_BY_TYPE = Object.freeze({\n\tnumber: ['eq', 'neq', 'gt', 'gte', 'lt', 'lte', 'present'],\n\tinteger: ['eq', 'neq', 'gt', 'gte', 'lt', 'lte', 'present'],\n\tdate: ['eq', 'neq', 'gt', 'gte', 'lt', 'lte', 'present'],\n\tboolean: ['eq'],\n\tpresence: ['present'],\n})\n\nconst DEFAULT_OPERATORS = Object.freeze(['eq', 'neq', 'present'])\n\n/**\n * The operators that fit a field type.\n *\n * Numbers and dates compare; yes/no is only \"is\"; a `presence` field (a\n * document, a relation) can only be filled in; text and choices say is, is not\n * or is filled in.\n *\n * @param {string} type The field type.\n * @return {string[]} The operator ids.\n */\nexport function operatorsForType(type) {\n\treturn [...(OPERATORS_BY_TYPE[type] || DEFAULT_OPERATORS)]\n}\n\n/**\n * The label of an operator in the editor's operator choice.\n *\n * @param {string} operator The operator id.\n * @return {string} The translated label.\n */\nexport function operatorLabel(operator) {\n\tswitch (operator) {\n\t\tcase 'eq': return t('nextcloud-vue', 'is')\n\t\tcase 'neq': return t('nextcloud-vue', 'is not')\n\t\tcase 'gt': return t('nextcloud-vue', 'greater than')\n\t\tcase 'gte': return t('nextcloud-vue', 'at least')\n\t\tcase 'lt': return t('nextcloud-vue', 'less than')\n\t\tcase 'lte': return t('nextcloud-vue', 'at most')\n\t\tcase 'present': return t('nextcloud-vue', 'is filled in')\n\t\tdefault: return String(operator || '')\n\t}\n}\n\n/**\n * Whether an operator needs a value.\n *\n * @param {string} operator The operator id.\n * @return {boolean} False for `present`.\n */\nexport function operatorTakesValue(operator) {\n\treturn operator !== 'present'\n}\n\n/**\n * A condition's value as a reader sees it, formatted by its field.\n *\n * @param {unknown} value The stored value.\n * @param {object|undefined} field The field (`type`, `format`, `options`).\n * @return {string} The formatted value.\n */\nexport function formatConditionValue(value, field) {\n\tconst type = field?.type\n\tif (type === 'boolean') {\n\t\tconst yes = value === true || value === 'true' || value === 1 || value === '1'\n\t\treturn yes ? t('nextcloud-vue', 'yes') : t('nextcloud-vue', 'no')\n\t}\n\tif (Array.isArray(field?.options)) {\n\t\tconst option = field.options.find((o) => String(o?.id ?? o?.value ?? o) === String(value))\n\t\tif (option && typeof option === 'object') {\n\t\t\treturn String(option.label ?? option.id ?? value)\n\t\t}\n\t}\n\tif ((type === 'number' || type === 'integer') && value !== '' && value !== null && !Number.isNaN(Number(value))) {\n\t\tconst options = field?.format === 'currency'\n\t\t\t? { style: 'currency', currency: field.currency || 'EUR', maximumFractionDigits: 0 }\n\t\t\t: {}\n\t\treturn new Intl.NumberFormat(getCanonicalLocale() || undefined, options).format(Number(value))\n\t}\n\treturn String(value ?? '')\n}\n\n/**\n * A condition as the clause of a rule, after \"Als\" / \"If\".\n *\n * @param {{field: string, operator: string, value?: unknown}} condition The condition.\n * @param {Array<{id: string, label?: string, type?: string}>} fields The fields the condition may name.\n * @return {string} The translated clause, for example \"Bouwkosten groter is dan € 100.000\".\n */\nexport function conditionSentence(condition, fields = []) {\n\tconst field = (fields || []).find((f) => f?.id === condition?.field)\n\tconst vars = {\n\t\tfield: field?.label || condition?.field || '',\n\t\tvalue: formatConditionValue(condition?.value, field),\n\t}\n\tswitch (condition?.operator) {\n\t\tcase 'neq': return t('nextcloud-vue', '{field} is not {value}', vars)\n\t\tcase 'gt': return t('nextcloud-vue', '{field} is greater than {value}', vars)\n\t\tcase 'gte': return t('nextcloud-vue', '{field} is at least {value}', vars)\n\t\tcase 'lt': return t('nextcloud-vue', '{field} is less than {value}', vars)\n\t\tcase 'lte': return t('nextcloud-vue', '{field} is at most {value}', vars)\n\t\tcase 'present': return t('nextcloud-vue', '{field} is filled in', vars)\n\t\tdefault: return t('nextcloud-vue', '{field} is {value}', vars)\n\t}\n}\n"],"names":["t"],"mappings":"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"}
@@ -452,6 +452,18 @@ var script = {
452
452
  default: '',
453
453
  },
454
454
 
455
+ /**
456
+ * How tall the labelled buttons in the page's card title rows stand in
457
+ * the board look: `compact` (34px, setting and case-type pages) or
458
+ * `regular` (the 40px control height, the case page's tab cards:
459
+ * DqZaakContact "Live gesprek"). Manifest `config.cardButtons`.
460
+ */
461
+ cardButtons: {
462
+ type: String,
463
+ default: 'compact',
464
+ validator: (value) => ['compact', 'regular'].includes(value),
465
+ },
466
+
455
467
  /**
456
468
  * NcDialog size for this page's create and edit form dialogs.
457
469
  *