viur-ui 0.0.1

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 (114) hide show
  1. package/README.md +79 -0
  2. package/index.d.ts +351 -0
  3. package/index.js +46 -0
  4. package/package.json +84 -0
  5. package/src/components/Browser/Browser.vue +496 -0
  6. package/src/components/Browser/TreeNav.vue +408 -0
  7. package/src/components/Browser/ViurBrowser.d.vue.ts +64 -0
  8. package/src/components/Browser/ViurBrowser.vue +271 -0
  9. package/src/components/Browser/dragSession.ts +134 -0
  10. package/src/components/Browser/index.ts +14 -0
  11. package/src/components/Browser/types.ts +30 -0
  12. package/src/components/DataTable/ColumnFilterPanel.vue +225 -0
  13. package/src/components/DataTable/DataTable.vue +3155 -0
  14. package/src/components/DataTable/ViurDataTable.d.vue.ts +72 -0
  15. package/src/components/DataTable/ViurDataTable.vue +331 -0
  16. package/src/components/DataTable/columns.ts +400 -0
  17. package/src/components/DataTable/index.ts +60 -0
  18. package/src/components/DataTable/rows.ts +446 -0
  19. package/src/components/DataTable/types.ts +267 -0
  20. package/src/components/DataTable/useColumnLayout.ts +294 -0
  21. package/src/components/DataTable/useGridNavigation.ts +193 -0
  22. package/src/components/DataTable/useVirtualRows.ts +126 -0
  23. package/src/components/DataTable/viurColumns.ts +330 -0
  24. package/src/forms/ViForm.d.vue.ts +106 -0
  25. package/src/forms/ViForm.vue +592 -0
  26. package/src/forms/ViFormCategory.vue +57 -0
  27. package/src/forms/bones/Bone.vue +1023 -0
  28. package/src/forms/bones/BoneActions.vue +127 -0
  29. package/src/forms/bones/BoneLabel.vue +122 -0
  30. package/src/forms/bones/BoneMultipleList.vue +91 -0
  31. package/src/forms/bones/BoneMultipleWrapper.vue +105 -0
  32. package/src/forms/bones/BoneNestedWrapper.vue +155 -0
  33. package/src/forms/bones/BoneSingleEntry.vue +51 -0
  34. package/src/forms/bones/FilterBone.vue +694 -0
  35. package/src/forms/bones/actionbar/defaultBar.vue +98 -0
  36. package/src/forms/bones/actionbar/fileBar.vue +165 -0
  37. package/src/forms/bones/actionbar/relationalBar.vue +125 -0
  38. package/src/forms/bones/actions/ActionDialog.vue +70 -0
  39. package/src/forms/bones/actions/Debug.vue +106 -0
  40. package/src/forms/bones/actions/Delete.vue +13 -0
  41. package/src/forms/bones/actions/DescribeImage.vue +201 -0
  42. package/src/forms/bones/actions/Download.vue +27 -0
  43. package/src/forms/bones/actions/Placeholder.vue +14 -0
  44. package/src/forms/bones/actions/Translation.vue +238 -0
  45. package/src/forms/bones/actions/index.js +280 -0
  46. package/src/forms/bones/bone.d.ts +45 -0
  47. package/src/forms/bones/country_information.json +779 -0
  48. package/src/forms/bones/index.js +225 -0
  49. package/src/forms/bones/uploadAdapter.js +46 -0
  50. package/src/forms/bones/utils.js +284 -0
  51. package/src/forms/bones/view/base_item.vue +35 -0
  52. package/src/forms/bones/view/boneLogic.js +202 -0
  53. package/src/forms/bones/view/index.js +5 -0
  54. package/src/forms/bones/widgets/booleanBone.vue +83 -0
  55. package/src/forms/bones/widgets/booleanBoneChoose.vue +57 -0
  56. package/src/forms/bones/widgets/booleanBoneSelect.vue +58 -0
  57. package/src/forms/bones/widgets/codeBone.vue +214 -0
  58. package/src/forms/bones/widgets/colorBone.vue +75 -0
  59. package/src/forms/bones/widgets/dateBone.vue +114 -0
  60. package/src/forms/bones/widgets/emailBone.vue +100 -0
  61. package/src/forms/bones/widgets/fileBone.vue +273 -0
  62. package/src/forms/bones/widgets/jsonBone.vue +63 -0
  63. package/src/forms/bones/widgets/keyBone.vue +71 -0
  64. package/src/forms/bones/widgets/numericBone.vue +125 -0
  65. package/src/forms/bones/widgets/passwordBone.vue +215 -0
  66. package/src/forms/bones/widgets/phoneBone.vue +173 -0
  67. package/src/forms/bones/widgets/rawBone.vue +94 -0
  68. package/src/forms/bones/widgets/recordBone.vue +64 -0
  69. package/src/forms/bones/widgets/relationalBone.vue +164 -0
  70. package/src/forms/bones/widgets/relationalBoneSelect.vue +120 -0
  71. package/src/forms/bones/widgets/selectBone.vue +122 -0
  72. package/src/forms/bones/widgets/selectBoneChoose.vue +104 -0
  73. package/src/forms/bones/widgets/spatialBone.vue +111 -0
  74. package/src/forms/bones/widgets/stringBone.vue +139 -0
  75. package/src/forms/bones/widgets/textBone.vue +641 -0
  76. package/src/forms/install.d.ts +4 -0
  77. package/src/forms/install.js +43 -0
  78. package/src/forms/layouts/LayloutList2Columns.vue +57 -0
  79. package/src/forms/layouts/LayoutCategory.vue +38 -0
  80. package/src/forms/layouts/LayoutList.vue +31 -0
  81. package/src/forms/utils.js +601 -0
  82. package/src/public/assets/icons/fontawesome-manifest.json +8 -0
  83. package/src/public/assets/icons/regular/file.svg +1 -0
  84. package/src/public/assets/icons/solid/arrows-left-right.svg +1 -0
  85. package/src/public/assets/icons/solid/bug.svg +1 -0
  86. package/src/public/assets/icons/solid/check.svg +1 -0
  87. package/src/public/assets/icons/solid/circle-info.svg +1 -0
  88. package/src/public/assets/icons/solid/compress.svg +1 -0
  89. package/src/public/assets/icons/solid/download.svg +1 -0
  90. package/src/public/assets/icons/solid/expand.svg +1 -0
  91. package/src/public/assets/icons/solid/grip-vertical.svg +1 -0
  92. package/src/public/assets/icons/solid/plus.svg +1 -0
  93. package/src/public/assets/icons/solid/question.svg +1 -0
  94. package/src/public/assets/icons/solid/triangle-exclamation.svg +1 -0
  95. package/src/public/assets/icons/solid/upload.svg +1 -0
  96. package/src/public/assets/icons/solid/xmark.svg +1 -0
  97. package/src/request/cache.js +183 -0
  98. package/src/request/configStore.js +516 -0
  99. package/src/request/envelope.js +211 -0
  100. package/src/request/index.js +35 -0
  101. package/src/request/messageStore.js +201 -0
  102. package/src/request/request.js +752 -0
  103. package/src/request/skel.js +90 -0
  104. package/src/theme/colorStore.js +168 -0
  105. package/src/translations/de.js +178 -0
  106. package/src/translations/en.js +177 -0
  107. package/src/user/LoginScreen.d.vue.ts +54 -0
  108. package/src/user/LoginScreen.vue +627 -0
  109. package/src/user/google.js +75 -0
  110. package/src/user/index.js +3 -0
  111. package/src/user/store.d.ts +59 -0
  112. package/src/user/store.js +183 -0
  113. package/src/webawesomeCompat.css +72 -0
  114. package/src/webawesomeConfig.js +61 -0
@@ -0,0 +1,280 @@
1
+ import { defineAsyncComponent, unref } from "vue"
2
+ import Translation from "./Translation.vue"
3
+ import Debug from "./Debug.vue"
4
+
5
+ // Lazy: DescribeImage zieht `@viur/vue-utils` (Legacy-Paket) nach. Eager
6
+ // importiert bricht damit der ganze Formular-Baum in Anwendungen, die dieses
7
+ // Paket nicht haben — obwohl sie die Action gar nicht benutzen. So wird es erst
8
+ // beim tatsächlichen Öffnen des Dialogs geladen (wie die schweren Bones).
9
+ const DescribeImage = defineAsyncComponent(() => import("./DescribeImage.vue"))
10
+ import { handler as downloadHandler } from "./Download.vue"
11
+ import { handler as placeholderHandler } from "./Placeholder.vue"
12
+ import { handler as deleteHandler } from "./Delete.vue"
13
+
14
+ /**
15
+ * Default-Definitionen: identisches Inline-Format wie früher in BoneActions.
16
+ * Strings in `bone.params.actions` werden hier nachgeschlagen.
17
+ * Custom-Objekte aus `bone.params.actions` werden in gleicher Form durchgereicht.
18
+ */
19
+ const defaultActions = {
20
+ translate: {
21
+ type: "assistant",
22
+ arg: "translate",
23
+ name: "Übersetzen",
24
+ icon: "translate",
25
+ library: "default",
26
+ title: "Übersetzen",
27
+ },
28
+ describe_image: {
29
+ type: "assistant",
30
+ arg: "describe_image",
31
+ name: "Bildbeschreibung erstellen",
32
+ icon: "file-richtext",
33
+ library: "default",
34
+ title: "Bild beschreiben",
35
+ },
36
+ download: {
37
+ type: "callback",
38
+ arg: "download",
39
+ name: "Download",
40
+ icon: "download",
41
+ library: "default",
42
+ title: "bone.download",
43
+ // Gerüst wie das Zeilen-X: auch ohne `boneactions` da (früher ein Knopf im
44
+ // Datei-Widget) — und nur lesend, also auch bei readonly-Bones.
45
+ required: true,
46
+ allowReadonly: true,
47
+ },
48
+ debug: {
49
+ type: "assistant",
50
+ arg: "debug",
51
+ name: "Debug",
52
+ icon: "bug",
53
+ library: "default",
54
+ title: "Bone Debug-Informationen anzeigen",
55
+ },
56
+ placeholder: {
57
+ type: "callback",
58
+ arg: "placeholder",
59
+ name: "Placeholder",
60
+ icon: "wrench",
61
+ library: "default",
62
+ title: "Platzhalter (TODO: entfernen)",
63
+ },
64
+ delete: {
65
+ type: "callback",
66
+ arg: "delete",
67
+ name: "Löschen",
68
+ icon: "xmark",
69
+ library: "default",
70
+ title: "bone.del",
71
+ position: "end",
72
+ variant: "danger",
73
+ // Gerüst: ohne sie wird man eine gesetzte Relation/Datei nicht wieder los
74
+ // (früher ein Knopf im Widget) — daher auch ohne `boneactions` da.
75
+ required: true,
76
+ // Nur bei relationalen Single-Bones sichtbar (nicht multiple).
77
+ when: (ctx) => prefixMatches("relational", ctx?.bone?.type) && !ctx?.bone?.multiple,
78
+ },
79
+ removeEntry: {
80
+ type: "callback",
81
+ arg: "removeEntry",
82
+ name: "Entfernen",
83
+ icon: "xmark",
84
+ library: "default",
85
+ title: "bone.del",
86
+ position: "end",
87
+ variant: "danger",
88
+ // PFLICHT-Action (Gerüst): entfernt DIESE Zeile eines multiple-Bones —
89
+ // ohne sie würde man einen Eintrag nie wieder los. Nur in Zeilen-Kontexten
90
+ // (BoneActions mit index) sichtbar.
91
+ required: true,
92
+ when: (ctx) => ctx?.multipleRow === true,
93
+ },
94
+ }
95
+
96
+ /** Dialog-Inhalt für `type: "assistant"` Actions, gemappt per `arg`. */
97
+ const componentRegistry = {
98
+ translate: Translation,
99
+ describe_image: DescribeImage,
100
+ debug: Debug,
101
+ }
102
+
103
+ /** Direkt aufgerufene Handler für `type: "callback"` Actions, gemappt per `arg`. */
104
+ const handlerRegistry = {
105
+ download: downloadHandler,
106
+ placeholder: placeholderHandler,
107
+ delete: deleteHandler,
108
+ removeEntry: (ctx) => ctx.removeEntry?.(),
109
+ }
110
+
111
+ /** Kein Wert zum Bearbeiten: leer, oder ein Objekt/Array ohne Inhalt (nur
112
+ * null/undefined/leere Listen — wie `isObjectEmpty` im Bone). */
113
+ function isEmptyValue(value) {
114
+ if (!value) return true
115
+ if (typeof value !== "object") return false
116
+ return Object.values(value).every((entry) => entry == null || (Array.isArray(entry) && entry.length === 0))
117
+ }
118
+
119
+ /** Disabled-Check per `arg`. Erhält den Action-Kontext (name, value, index, lang, bone, boneState). */
120
+ const disabledRegistry = {
121
+ translate: (ctx) => !ctx.bone?.languages,
122
+ describe_image: (ctx) => !ctx.value?.dest?.key,
123
+ download: (ctx) => !ctx.value?.dest?.downloadUrl,
124
+ // am EIGENEN Wert — bei Mehrsprachigkeit der einer Sprache, nicht des Bones
125
+ delete: (ctx) => isEmptyValue(ctx.value),
126
+ }
127
+
128
+ /**
129
+ * Default-Actions pro Bone-Type-Prefix. Beim Auflösen werden ALLE matchenden
130
+ * Prefixes zusammengeführt (kürzester zuerst, dedupliziert).
131
+ *
132
+ * Matching-Regel: Prefix matcht, wenn `boneType === prefix` (exakt) ODER
133
+ * `boneType.startsWith(prefix + ".")` (Subtype). Der leere Prefix `""` matcht alles.
134
+ *
135
+ * Definitionen mit `required: true` (delete, download) erscheinen auch ohne
136
+ * `boneactions`; ein Host kann sie hier trotzdem abwählen (wie per `"-name"`).
137
+ */
138
+ const defaultActionsByType = {
139
+ "": ["debug", "placeholder"],
140
+ relational: ["delete"],
141
+ "relational.tree.leaf.file": ["download"],
142
+ }
143
+
144
+ /**
145
+ * PFLICHT-Actions pro Bone-Type-Prefix (Gerüst-Funktionen). Anders als die
146
+ * Defaults überleben sie sowohl eine `bone.params.actions`-Liste des Servers
147
+ * als auch `setDefaultActionsForType` des Hosts — nur ihr eigenes
148
+ * `when`-Prädikat (funktionale Verfügbarkeit) blendet sie aus. Sie werden
149
+ * außerdem auch OHNE `boneactions` gerendert (BoneActions filtert darauf).
150
+ */
151
+ const requiredActionsByType = {
152
+ "": ["removeEntry"],
153
+ }
154
+
155
+ function prefixMatches(prefix, boneType) {
156
+ if (prefix === "") return true
157
+ if (!boneType) return false
158
+ return boneType === prefix || boneType.startsWith(prefix + ".")
159
+ }
160
+
161
+ /**
162
+ * Erweitert die Registry. Jedes Feld ist optional.
163
+ * @param {string} name
164
+ * @param {{ default?: object, component?: object, handler?: Function, disabled?: Function }} opts
165
+ */
166
+ export function addAction(name, opts) {
167
+ if (opts.default) defaultActions[name] = opts.default
168
+ if (opts.component) componentRegistry[name] = opts.component
169
+ if (opts.handler) handlerRegistry[name] = opts.handler
170
+ if (opts.disabled) disabledRegistry[name] = opts.disabled
171
+ }
172
+
173
+ /** Setzt die Standard-Actions für einen Bone-Type-Prefix. */
174
+ export function setDefaultActionsForType(typePrefix, actionNames) {
175
+ defaultActionsByType[typePrefix] = actionNames
176
+ }
177
+
178
+ /** Setzt die PFLICHT-Actions für einen Bone-Type-Prefix (Host-Kuratierung). */
179
+ export function setRequiredActionsForType(typePrefix, actionNames) {
180
+ requiredActionsByType[typePrefix] = actionNames
181
+ }
182
+
183
+ /**
184
+ * Formular-weite Action-Konfiguration (ViForm `actions`-Prop, via
185
+ * provide("boneActionsConfig") — ggf. eine Ref) für EINEN Bone auflösen:
186
+ * Array gilt für alle Bones, Objekt pro Bone-Name mit `"*"` für alle.
187
+ * Die Einträge haben dieselbe Form wie `bone.params.actions` (inkl. `"-name"`).
188
+ */
189
+ export function formConfiguredActions(config, boneName) {
190
+ const value = unref(config)
191
+ if (!value) return []
192
+ if (Array.isArray(value)) return [...value]
193
+ return [...(value["*"] ?? []), ...(value[boneName] ?? [])]
194
+ }
195
+
196
+ export function getActionComponent(arg) {
197
+ return componentRegistry[arg]
198
+ }
199
+
200
+ export function getActionHandler(arg) {
201
+ return handlerRegistry[arg]
202
+ }
203
+
204
+ export function isActionDisabled(action, ctx) {
205
+ // Im Readonly-Modus sind grundsätzlich alle Actions deaktiviert — bis auf
206
+ // rein lesende (`allowReadonly`, z.B. Download).
207
+ if (ctx?.boneState?.readonly && !action?.allowReadonly) return true
208
+ const fn = disabledRegistry[action?.arg]
209
+ return fn ? !!fn(ctx) : false
210
+ }
211
+
212
+ /**
213
+ * Sammelt alle Action-Namen einer Prefix-Map für einen Bone-Type über
214
+ * matchende Prefixes (kürzester zuerst, dedupliziert).
215
+ *
216
+ * @param {Record<string, string[]>} map
217
+ * @param {string} boneType
218
+ * @returns {string[]}
219
+ */
220
+ function collectFromMap(map, boneType) {
221
+ const matched = Object.keys(map)
222
+ .filter((p) => prefixMatches(p, boneType))
223
+ .sort((a, b) => a.length - b.length)
224
+ const names = []
225
+ for (const p of matched) {
226
+ for (const n of map[p]) {
227
+ if (!names.includes(n)) names.push(n)
228
+ }
229
+ }
230
+ return names
231
+ }
232
+
233
+ /** Liefert den `arg`-Identifier eines Eintrags (String oder Inline-Definition). */
234
+ function entryArg(entry) {
235
+ return typeof entry === "string" ? entry : entry?.arg
236
+ }
237
+
238
+ /**
239
+ * Löst die Action-Liste für einen Bone auf.
240
+ * - Type-Defaults aus `defaultActionsByType` werden **immer** angewendet
241
+ * (matchende Prefixes vereint, kürzester zuerst).
242
+ * - PFLICHT-Actions aus `requiredActionsByType` kommen zusätzlich IMMER dazu.
243
+ * - `configured` (typisch `bone.params.actions`) wird vorangestellt und die
244
+ * Defaults werden dedupliziert dazugemerged. So bleibt z.B. die `delete`-
245
+ * Action für relationale Bones immer verfügbar, auch wenn das Backend eine
246
+ * `params.actions`-Liste schickt.
247
+ * - EXPLIZITE ABWAHL: ein String-Eintrag `"-name"` in `configured` entfernt
248
+ * die Action `name` — auch eine Default- oder Pflicht-Action (die bewusste
249
+ * Abwahl am Bone schlägt die Pflicht; nur sie).
250
+ * - Strings werden via Default-Lookup aufgelöst, Inline-Objekte durchgereicht.
251
+ * - Actions mit `when(ctx)` werden ausgefiltert, wenn das Prädikat falsy liefert.
252
+ *
253
+ * Jede zurückgegebene Action ist eine flache Kopie, damit `_opened`-Mutationen
254
+ * den Source nicht verändern. Sortiert: Actions mit `position: "end"` ans Ende.
255
+ *
256
+ * @param {object} bone - vollständige Bone-Definition (mit type, multiple, params)
257
+ * @param {Array<string|object>|undefined} configured
258
+ * @param {object} [boneState] - reactive Bone-State (für when/disabled-Predicates)
259
+ * @param {object} [extras] - zusätzlicher Kontext für `when` (z.B. injizierte Hosts wie `relationSelector`)
260
+ * @returns {object[]}
261
+ */
262
+ export function resolveActions(bone, configured, boneState, extras = {}) {
263
+ const defaults = collectFromMap(defaultActionsByType, bone?.type)
264
+ const required = collectFromMap(requiredActionsByType, bone?.type)
265
+ const entries = Array.isArray(configured) ? [...configured] : []
266
+ // Explizite Abwahl: "-name"-Einträge sammeln und aus der Liste nehmen.
267
+ const disabled = new Set(entries.filter((e) => typeof e === "string" && e.startsWith("-")).map((e) => e.slice(1)))
268
+ const names = entries.filter((e) => !(typeof e === "string" && e.startsWith("-")))
269
+ for (const d of [...defaults, ...required]) {
270
+ if (!names.some((e) => entryArg(e) === d)) names.push(d)
271
+ }
272
+ const ctx = { bone, boneState, ...extras }
273
+ return names
274
+ .filter((entry) => !disabled.has(entryArg(entry)))
275
+ .map((entry) => (typeof entry === "string" ? defaultActions[entry] : entry))
276
+ .filter(Boolean)
277
+ .map((a) => ({ ...a }))
278
+ .filter((a) => (typeof a.when === "function" ? !!a.when(ctx) : true))
279
+ .sort((a, b) => (a.position === "end" ? 1 : 0) - (b.position === "end" ? 1 : 0))
280
+ }
@@ -0,0 +1,45 @@
1
+ import type { DefineComponent } from "vue"
2
+
3
+ export interface BoneProps {
4
+ /** Das Bone-Widget-Component-Objekt (z.B. StringBone). Typischerweise von ViForm gesetzt. */
5
+ is?: object
6
+ /** Bone-Identifier; muss einem Key in structure und skel entsprechen. */
7
+ name: string
8
+ /** Explizite Sprach-Liste; überschreibt bonestructure.languages. */
9
+ languages?: unknown[]
10
+ /** Expliziter Multiple-Flag; überschreibt bonestructure.multiple. */
11
+ multiple?: boolean
12
+ /** Expliziter Readonly-Flag; überschreibt bonestructure.readonly. */
13
+ readonly?: boolean
14
+ /** Expliziter Required-Flag; überschreibt bonestructure.required. */
15
+ required?: boolean
16
+ /** Zusätzliche Parameter; überschreibt bonestructure.params. */
17
+ params?: Record<string, unknown>
18
+ /** Expliziter Wert; überschreibt skel[name] wenn gesetzt. */
19
+ value?: object | string | number | boolean | unknown[]
20
+ /** Vollständige Skeleton-Struktur (alle Bone-Definitionen des Formulars). */
21
+ structure: Record<string, unknown>
22
+ /** Skeleton-Datenobjekt mit den aktuellen Werten. */
23
+ skel: unknown
24
+ /** Fehler-Array aus der Server-Antwort. Einträge mit passendem fieldPath werden angezeigt. */
25
+ errors?: unknown[]
26
+ /** Label-Modus. */
27
+ label?: "normal" | "top" | "hide" | "placeholder"
28
+ /** Aktiviert BoneActions-Schaltflächen neben dem Input. */
29
+ boneactions?: boolean
30
+ /** Zeigt Tooltip-Inhalt als wa-alert statt als Tooltip. */
31
+ showLabelInfo?: boolean
32
+ /** Gibt autofocus an das Bone-Widget weiter. */
33
+ autofocus?: boolean
34
+ /** Standardmäßig aktive Sprache im Multilang-Tab. */
35
+ defaultLanguage?: string
36
+ /** Erzwingt den Tooltip auf dem Input-Bereich unabhängig vom Label-Modus. */
37
+ showBoneTooltip?: boolean
38
+ /** Fehler-Darstellungsstil. */
39
+ errorStyle?: "default" | "decent"
40
+ /** Aktiviert Debug-Modus: Bone-Name als Tooltip am Label. */
41
+ debug?: boolean
42
+ }
43
+
44
+ declare const Bone: DefineComponent<BoneProps>
45
+ export default Bone