obm-upload-form-ui 0.1.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 (59) hide show
  1. package/LICENSE +674 -0
  2. package/README.md +153 -0
  3. package/dist/_plugin-vue_export-helper-DQLEQ__A.js +44 -0
  4. package/dist/_plugin-vue_export-helper-DQLEQ__A.js.map +1 -0
  5. package/dist/core/client/auth.d.ts +37 -0
  6. package/dist/core/client/errors.d.ts +31 -0
  7. package/dist/core/client/formApi.d.ts +23 -0
  8. package/dist/core/client/http.d.ts +10 -0
  9. package/dist/core/config.d.ts +25 -0
  10. package/dist/core/geo/wkt.d.ts +7 -0
  11. package/dist/core/i18n/messages.d.ts +13 -0
  12. package/dist/core/index.d.ts +16 -0
  13. package/dist/core/schema/guards.d.ts +12 -0
  14. package/dist/core/schema/normalize.d.ts +10 -0
  15. package/dist/core/schema/types.d.ts +119 -0
  16. package/dist/core/submit/linked.d.ts +58 -0
  17. package/dist/core/submit/metadata.d.ts +37 -0
  18. package/dist/core/submit/submitClient.d.ts +40 -0
  19. package/dist/core/validation/engine.d.ts +18 -0
  20. package/dist/core/validation/rules.d.ts +29 -0
  21. package/dist/core/validation/types.d.ts +48 -0
  22. package/dist/core.js +377 -0
  23. package/dist/core.js.map +1 -0
  24. package/dist/custom-elements/obm-upload-form-ui.css +1 -0
  25. package/dist/custom-elements/obm-upload-form.iife.js +21 -0
  26. package/dist/custom-elements/obm-upload-form.iife.js.map +1 -0
  27. package/dist/custom-elements/obm-upload-form.js +16889 -0
  28. package/dist/custom-elements/obm-upload-form.js.map +1 -0
  29. package/dist/engine-7r1HChwT.js +174 -0
  30. package/dist/engine-7r1HChwT.js.map +1 -0
  31. package/dist/obm-upload-form-ui.css +1 -0
  32. package/dist/vue/FieldWrapper.vue.d.ts +30 -0
  33. package/dist/vue/UploadForm.vue.d.ts +58 -0
  34. package/dist/vue/ValidationSummary.vue.d.ts +13 -0
  35. package/dist/vue/fieldRegistry.d.ts +5 -0
  36. package/dist/vue/fields/ArrayField.vue.d.ts +14 -0
  37. package/dist/vue/fields/AutocompleteField.vue.d.ts +15 -0
  38. package/dist/vue/fields/BooleanField.vue.d.ts +14 -0
  39. package/dist/vue/fields/NumericField.vue.d.ts +14 -0
  40. package/dist/vue/fields/SelectField.vue.d.ts +15 -0
  41. package/dist/vue/fields/TemporalField.vue.d.ts +14 -0
  42. package/dist/vue/fields/TextAreaField.vue.d.ts +14 -0
  43. package/dist/vue/fields/TextField.vue.d.ts +14 -0
  44. package/dist/vue/fields/TimeIntervalField.vue.d.ts +14 -0
  45. package/dist/vue/fields/UnsupportedField.vue.d.ts +8 -0
  46. package/dist/vue/fields/WktTextField.vue.d.ts +14 -0
  47. package/dist/vue/index.d.ts +19 -0
  48. package/dist/vue/types.d.ts +22 -0
  49. package/dist/vue/uiText.d.ts +3 -0
  50. package/dist/vue/useFormState.d.ts +13 -0
  51. package/dist/vue-leaflet/GeometryField.vue.d.ts +14 -0
  52. package/dist/vue-leaflet/index.d.ts +9 -0
  53. package/dist/vue-leaflet.js +117 -0
  54. package/dist/vue-leaflet.js.map +1 -0
  55. package/dist/vue.js +813 -0
  56. package/dist/vue.js.map +1 -0
  57. package/dist/wkt-C0dkXG1x.js +359 -0
  58. package/dist/wkt-C0dkXG1x.js.map +1 -0
  59. package/package.json +113 -0
@@ -0,0 +1,174 @@
1
+ const N = [
2
+ "array",
3
+ "autocomplete",
4
+ "autocompletelist",
5
+ "boolean",
6
+ "crings",
7
+ "custom_list",
8
+ "date",
9
+ "datetime",
10
+ "file_id",
11
+ "line",
12
+ "list",
13
+ "numeric",
14
+ "photo_id",
15
+ "point",
16
+ "polygon",
17
+ "text",
18
+ "textarea",
19
+ "time",
20
+ "time_interval",
21
+ "timetominutes",
22
+ "wkt"
23
+ ], M = "__unknown", h = {
24
+ enforcement: "refuse",
25
+ draftChecks: "skip"
26
+ }, f = {
27
+ "validation.required": "This field is required.",
28
+ "validation.regexp": "The value does not match the required format.",
29
+ "validation.minmax.belowMin": "The value must be at least {min}.",
30
+ "validation.minmax.aboveMax": "The value must be at most {max}.",
31
+ "validation.minmax.notNumber": "The value must be a number.",
32
+ "validation.invalidRule": "The validation rule configured for this field is invalid; the value was not checked.",
33
+ "validation.notSupported": 'The "{type}" validation rule is not checked client-side in this version.'
34
+ }, v = {
35
+ "validation.required": "A mező kitöltése kötelező.",
36
+ "validation.regexp": "Az érték nem felel meg az elvárt formátumnak.",
37
+ "validation.minmax.belowMin": "Az érték legalább {min} kell legyen.",
38
+ "validation.minmax.aboveMax": "Az érték legfeljebb {max} lehet.",
39
+ "validation.minmax.notNumber": "Az értéknek számnak kell lennie.",
40
+ "validation.invalidRule": "A mezőhöz beállított ellenőrzési szabály hibás; az érték nem lett ellenőrizve.",
41
+ "validation.notSupported": 'A(z) "{type}" ellenőrzési szabályt ez a verzió nem ellenőrzi kliensoldalon.'
42
+ }, m = { en: f, hu: v }, d = "en";
43
+ function g(e, t = {}, i = d, n) {
44
+ const a = m[i.slice(0, 2).toLowerCase()] ?? m[d];
45
+ return ((n == null ? void 0 : n[e]) ?? a[e] ?? f[e] ?? e).replace(
46
+ /\{(\w+)\}/g,
47
+ (l, u) => u in t ? String(t[u]) : l
48
+ );
49
+ }
50
+ function c(e) {
51
+ return e == null ? !0 : typeof e == "string" ? e.trim() === "" : Array.isArray(e) ? e.length === 0 : !1;
52
+ }
53
+ function o(e, t, i, n, a, r = {}) {
54
+ return {
55
+ column: e.column,
56
+ rule: t,
57
+ severity: i,
58
+ messageKey: n,
59
+ message: g(n, r, a.language, a.messages),
60
+ params: r
61
+ };
62
+ }
63
+ function b(e, t, i) {
64
+ return !e.validate.required || !c(t) ? [] : [o(e, "required", "error", "validation.required", i)];
65
+ }
66
+ function k(e, t, i) {
67
+ const n = e.validate.value;
68
+ if (c(t) || n === null || n === "") return [];
69
+ let a;
70
+ try {
71
+ a = new RegExp(n);
72
+ } catch {
73
+ return [o(e, "regexp", "unsupported", "validation.invalidRule", i)];
74
+ }
75
+ return (Array.isArray(t) ? t : [t]).some((u) => !a.test(String(u))) ? [o(e, "regexp", "error", "validation.regexp", i, { pattern: n })] : [];
76
+ }
77
+ function x(e) {
78
+ const t = e.split(/[,;:]/).map((r) => r.trim());
79
+ if (t.length !== 2) return null;
80
+ const i = (r) => {
81
+ if (r === "") return null;
82
+ const l = Number(r);
83
+ return Number.isFinite(l) ? l : !1;
84
+ }, n = i(t[0]), a = i(t[1]);
85
+ return n === !1 || a === !1 || n === null && a === null ? null : { min: n, max: a };
86
+ }
87
+ function y(e, t, i) {
88
+ const n = e.validate.value;
89
+ if (c(t) || n === null || n === "") return [];
90
+ const a = x(n);
91
+ if (a === null)
92
+ return [o(e, "minmax", "unsupported", "validation.invalidRule", i)];
93
+ const r = [], l = Array.isArray(t) ? t : [t];
94
+ for (const u of l) {
95
+ const s = typeof u == "number" ? u : Number(String(u).trim());
96
+ if (!Number.isFinite(s)) {
97
+ r.push(o(e, "minmax", "error", "validation.minmax.notNumber", i));
98
+ continue;
99
+ }
100
+ a.min !== null && s < a.min && r.push(
101
+ o(e, "minmax", "error", "validation.minmax.belowMin", i, {
102
+ min: a.min
103
+ })
104
+ ), a.max !== null && s > a.max && r.push(
105
+ o(e, "minmax", "error", "validation.minmax.aboveMax", i, {
106
+ max: a.max
107
+ })
108
+ );
109
+ }
110
+ return r;
111
+ }
112
+ function A(e, t, i) {
113
+ return c(t) ? [] : [
114
+ o(e, "spatial", "unsupported", "validation.notSupported", i, {
115
+ type: "spatial"
116
+ })
117
+ ];
118
+ }
119
+ function z(e, t, i) {
120
+ return c(t) ? [] : [
121
+ o(e, "custom_check", "unsupported", "validation.notSupported", i, {
122
+ type: "custom_check"
123
+ })
124
+ ];
125
+ }
126
+ function p(e) {
127
+ return { ...h, ...e == null ? void 0 : e.policy };
128
+ }
129
+ function _(e, t, i, n) {
130
+ const a = p(n), r = { language: n == null ? void 0 : n.language, messages: n == null ? void 0 : n.messages };
131
+ if (i === "draft" && a.draftChecks === "skip") return [];
132
+ if (e.api_params.hidden) return [];
133
+ const l = [];
134
+ if (e.api_params.readonly || l.push(...b(e, t, r)), i === "final" || a.draftChecks === "all")
135
+ switch (e.validate.type) {
136
+ case "regexp":
137
+ l.push(...k(e, t, r));
138
+ break;
139
+ case "minmax":
140
+ l.push(...y(e, t, r));
141
+ break;
142
+ case "spatial":
143
+ l.push(...A(e, t, r));
144
+ break;
145
+ case "custom_check":
146
+ l.push(...z(e, t, r));
147
+ break;
148
+ }
149
+ return e.validate.soft ? l.map(
150
+ (s) => s.severity === "error" ? { ...s, severity: "warning" } : s
151
+ ) : l;
152
+ }
153
+ function T(e, t, i, n) {
154
+ const a = p(n), r = e.columns.flatMap(
155
+ (s) => _(s, t[s.column], i, n)
156
+ ), l = r.some((s) => s.severity === "error"), u = a.enforcement === "refuse" && i === "final" && l;
157
+ return { state: i, issues: r, blocking: u };
158
+ }
159
+ function w(e) {
160
+ return !e.blocking;
161
+ }
162
+ export {
163
+ d as D,
164
+ N as F,
165
+ M as U,
166
+ h as a,
167
+ _ as b,
168
+ w as c,
169
+ g as f,
170
+ c as i,
171
+ x as p,
172
+ T as v
173
+ };
174
+ //# sourceMappingURL=engine-7r1HChwT.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine-7r1HChwT.js","sources":["../src/core/schema/types.ts","../src/core/validation/types.ts","../src/core/i18n/messages.ts","../src/core/validation/rules.ts","../src/core/validation/engine.ts"],"sourcesContent":["/**\n * Typed model of the obm-project-api form schema.\n *\n * Field names mirror the API's JSON serialization exactly\n * (obm-project-api src/Models/FormDetails/**), except where a normalized\n * shape is explicitly documented (FormSchema).\n */\n\n/** Field types returned by GET /forms/{publishedFormId} (obm-project-api FormColumnType enum). */\nexport const FORM_COLUMN_TYPES = [\n 'array',\n 'autocomplete',\n 'autocompletelist',\n 'boolean',\n 'crings',\n 'custom_list',\n 'date',\n 'datetime',\n 'file_id',\n 'line',\n 'list',\n 'numeric',\n 'photo_id',\n 'point',\n 'polygon',\n 'text',\n 'textarea',\n 'time',\n 'time_interval',\n 'timetominutes',\n 'wkt',\n] as const;\n\nexport type FormColumnType = (typeof FORM_COLUMN_TYPES)[number];\n\n/**\n * Sentinel used by normalization when the API reports a type this library\n * version does not know. Such columns render as \"unsupported\" instead of failing.\n */\nexport const UNKNOWN_COLUMN_TYPE = '__unknown';\n\nexport type NormalizedColumnType = FormColumnType | typeof UNKNOWN_COLUMN_TYPE;\n\n/** obm-project-api ControlType enum (the `validate.type` field). */\nexport type ValidationControlType = 'custom_check' | 'minmax' | 'nocheck' | 'regexp' | 'spatial';\n\nexport interface ColumnValidation {\n required: boolean;\n /** Warn-but-allow tier: failures are reported as warnings and never block. */\n soft: boolean;\n type: ValidationControlType;\n /** Rule payload: regexp pattern, \"min,max\" bounds, custom function name, ... */\n value: string | null;\n}\n\nexport interface FormApiParameters {\n sticky: boolean;\n hidden: boolean;\n readonly: boolean;\n list_elements_as_buttons: boolean;\n once_field: boolean;\n unfolding_list: boolean;\n /** Only present in the JSON when non-null server-side. */\n auto_geometry?: unknown;\n}\n\nexport interface ListDefinition {\n custom_list: boolean;\n extendable: boolean;\n /** Columns whose picklists should refresh when this column changes. */\n trigger_target_column: string[];\n selected: unknown;\n multiselect: boolean;\n /** The API spreads extra snake_case keys (pre_filter_*, ...) into this object. */\n [passthrough: string]: unknown;\n}\n\nexport interface FormListElement {\n value: string;\n /** The API falls back to `value` when the label is empty; normalization guarantees it here. */\n label: string;\n filter_value?: string;\n}\n\n/** One item of `form_body`, normalized (see `normalizeFormDetails`). */\nexport interface ColumnSchema {\n column: string;\n short_name: string;\n description: string | null;\n type: NormalizedColumnType;\n /** Raw type string as received; diagnostic aid when `type` is `__unknown`. */\n raw_type: string;\n default_value: unknown;\n relation: string | null;\n position_order: number;\n validate: ColumnValidation;\n pseudo_column: string | null;\n api_params: FormApiParameters;\n has_empty_line: boolean;\n list_definition: ListDefinition | null;\n generated_list_elements: FormListElement[];\n /** Options per trigger value, keyed by the triggering column's value. */\n filterable_list_elements: Record<string, FormListElement[]> | null;\n}\n\nexport interface ObservationListSettings {\n mode?: string;\n time_limit?: number;\n [passthrough: string]: unknown;\n}\n\nexport interface ImportantField {\n column: string;\n type: string;\n [passthrough: string]: unknown;\n}\n\n/** `form_header` of GET /forms/{publishedFormId}. */\nexport interface FormHeader {\n user?: unknown;\n form_id: number;\n published_form_id: number;\n name: string;\n description: string | null;\n project_table: string;\n destination_table: string;\n tracklog_mode: string | null;\n observation_list: ObservationListSettings | null;\n periodic_notification?: unknown;\n important_fields: ImportantField[];\n highlighted_fields: string[];\n}\n\n/**\n * Normalized form schema produced by `normalizeFormDetails` from the raw\n * `{form_header, form_body}` API response: columns are sorted by\n * `position_order` and per-column oddities are smoothed over.\n */\nexport interface FormSchema {\n header: FormHeader;\n columns: ColumnSchema[];\n}\n\n/** One row of GET /forms. */\nexport interface FormListItem {\n form_id: number;\n published_form_id: number;\n /** Unix timestamp; doubles as the `form_version` sent in upload metadata. */\n last_modification_timestamp: number;\n name: string;\n}\n\n/** Raw, un-normalized response shape of GET /forms/{publishedFormId}. */\nexport interface RawFormDetails {\n form_header: Record<string, unknown>;\n form_body: unknown[];\n}\n","import type { MessageKey, MessageOverrides } from '../i18n/messages';\n\n/**\n * Lifecycle state of the record being validated. Mirrors the established OBM\n * client convention: drafts save with little or no validation, finalization\n * enforces the rules.\n */\nexport type DocumentState = 'draft' | 'final';\n\nexport type IssueSeverity = 'error' | 'warning' | 'unsupported';\n\nexport type ValidationRuleName = 'required' | 'regexp' | 'minmax' | 'spatial' | 'custom_check';\n\nexport interface ValidationIssue {\n column: string;\n rule: ValidationRuleName;\n /**\n * error: blocks under enforcement 'refuse' + state 'final'.\n * warning: soft rules; reported, never blocks.\n * unsupported: the rule cannot be checked client-side (or is misconfigured); never blocks.\n */\n severity: IssueSeverity;\n messageKey: MessageKey;\n /** Human-readable message in the requested language. */\n message: string;\n params?: Record<string, unknown>;\n}\n\nexport interface ValidationPolicy {\n /**\n * 'refuse': error-severity issues block finalization.\n * 'warn': issues are reported but never block (for when server-side\n * validation takes over enforcement).\n */\n enforcement: 'refuse' | 'warn';\n /** Which checks run when validating a draft. Draft issues never block either way. */\n draftChecks: 'skip' | 'requiredOnly' | 'all';\n}\n\n/** thr_vizfolyasok precedent: drafts skip validation, finalization refuses on errors. */\nexport const DEFAULT_VALIDATION_POLICY: ValidationPolicy = {\n enforcement: 'refuse',\n draftChecks: 'skip',\n};\n\nexport interface ValidationOptions {\n policy?: Partial<ValidationPolicy>;\n /** Language for generated messages ('en' default; 'hu' built in). */\n language?: string;\n /** Per-key message overrides. */\n messages?: MessageOverrides;\n}\n\nexport interface ValidationResult {\n state: DocumentState;\n issues: ValidationIssue[];\n /** True when submission must be refused under the active policy. */\n blocking: boolean;\n}\n","/**\n * Message catalog for strings the library itself generates (validation\n * messages). Hosts can override individual keys per call via MessageOverrides.\n */\n\nexport type MessageKey =\n | 'validation.required'\n | 'validation.regexp'\n | 'validation.minmax.belowMin'\n | 'validation.minmax.aboveMax'\n | 'validation.minmax.notNumber'\n | 'validation.invalidRule'\n | 'validation.notSupported';\n\nexport type MessageCatalog = Record<MessageKey, string>;\n\nexport type MessageOverrides = Partial<MessageCatalog>;\n\nconst en: MessageCatalog = {\n 'validation.required': 'This field is required.',\n 'validation.regexp': 'The value does not match the required format.',\n 'validation.minmax.belowMin': 'The value must be at least {min}.',\n 'validation.minmax.aboveMax': 'The value must be at most {max}.',\n 'validation.minmax.notNumber': 'The value must be a number.',\n 'validation.invalidRule':\n 'The validation rule configured for this field is invalid; the value was not checked.',\n 'validation.notSupported':\n 'The \"{type}\" validation rule is not checked client-side in this version.',\n};\n\nconst hu: MessageCatalog = {\n 'validation.required': 'A mező kitöltése kötelező.',\n 'validation.regexp': 'Az érték nem felel meg az elvárt formátumnak.',\n 'validation.minmax.belowMin': 'Az érték legalább {min} kell legyen.',\n 'validation.minmax.aboveMax': 'Az érték legfeljebb {max} lehet.',\n 'validation.minmax.notNumber': 'Az értéknek számnak kell lennie.',\n 'validation.invalidRule':\n 'A mezőhöz beállított ellenőrzési szabály hibás; az érték nem lett ellenőrizve.',\n 'validation.notSupported':\n 'A(z) \"{type}\" ellenőrzési szabályt ez a verzió nem ellenőrzi kliensoldalon.',\n};\n\nconst catalogs: Record<string, MessageCatalog> = { en, hu };\n\nexport const DEFAULT_LANGUAGE = 'en';\n\n/**\n * Resolve a message for the given language ('en' fallback for unknown\n * languages/keys) and interpolate `{param}` placeholders.\n */\nexport function formatMessage(\n key: MessageKey,\n params: Record<string, unknown> = {},\n language: string = DEFAULT_LANGUAGE,\n overrides?: MessageOverrides,\n): string {\n const catalog = catalogs[language.slice(0, 2).toLowerCase()] ?? catalogs[DEFAULT_LANGUAGE];\n const template = overrides?.[key] ?? catalog[key] ?? en[key] ?? key;\n return template.replace(/\\{(\\w+)\\}/g, (match, name: string) =>\n name in params ? String(params[name]) : match,\n );\n}\n","import { formatMessage, type MessageKey, type MessageOverrides } from '../i18n/messages';\nimport type { ColumnSchema } from '../schema/types';\nimport type { ValidationIssue, ValidationRuleName } from './types';\n\n/**\n * A value counts as empty when the user provided nothing: null, undefined,\n * empty/whitespace-only string, or an empty array. `false` and `0` are values.\n */\nexport function isEmpty(value: unknown): boolean {\n if (value === null || value === undefined) return true;\n if (typeof value === 'string') return value.trim() === '';\n if (Array.isArray(value)) return value.length === 0;\n return false;\n}\n\ninterface MessageContext {\n language?: string;\n messages?: MessageOverrides;\n}\n\nfunction issue(\n column: ColumnSchema,\n rule: ValidationRuleName,\n severity: ValidationIssue['severity'],\n messageKey: MessageKey,\n context: MessageContext,\n params: Record<string, unknown> = {},\n): ValidationIssue {\n return {\n column: column.column,\n rule,\n severity,\n messageKey,\n message: formatMessage(messageKey, params, context.language, context.messages),\n params,\n };\n}\n\nexport function checkRequired(\n column: ColumnSchema,\n value: unknown,\n context: MessageContext,\n): ValidationIssue[] {\n if (!column.validate.required || !isEmpty(value)) return [];\n return [issue(column, 'required', 'error', 'validation.required', context)];\n}\n\nexport function checkRegexp(\n column: ColumnSchema,\n value: unknown,\n context: MessageContext,\n): ValidationIssue[] {\n const pattern = column.validate.value;\n if (isEmpty(value) || pattern === null || pattern === '') return [];\n\n let regexp: RegExp;\n try {\n regexp = new RegExp(pattern);\n } catch {\n // Legacy-authored patterns must never crash the engine.\n return [issue(column, 'regexp', 'unsupported', 'validation.invalidRule', context)];\n }\n\n const values = Array.isArray(value) ? value : [value];\n const failing = values.some((item) => !regexp.test(String(item)));\n if (!failing) return [];\n return [issue(column, 'regexp', 'error', 'validation.regexp', context, { pattern })];\n}\n\n/**\n * Parse the minmax rule payload. The observed legacy convention is\n * \"min,max\" (\":\" and \";\" tolerated as separators); either bound may be blank.\n * Returns null when the payload is unparseable.\n */\nexport function parseMinmaxBounds(rule: string): { min: number | null; max: number | null } | null {\n const parts = rule.split(/[,;:]/).map((part) => part.trim());\n if (parts.length !== 2) return null;\n\n const parseBound = (part: string): number | null | false => {\n if (part === '') return null;\n const parsed = Number(part);\n return Number.isFinite(parsed) ? parsed : false;\n };\n\n const min = parseBound(parts[0]);\n const max = parseBound(parts[1]);\n if (min === false || max === false) return null;\n if (min === null && max === null) return null;\n return { min, max };\n}\n\nexport function checkMinmax(\n column: ColumnSchema,\n value: unknown,\n context: MessageContext,\n): ValidationIssue[] {\n const rule = column.validate.value;\n if (isEmpty(value) || rule === null || rule === '') return [];\n\n const bounds = parseMinmaxBounds(rule);\n if (bounds === null) {\n return [issue(column, 'minmax', 'unsupported', 'validation.invalidRule', context)];\n }\n\n const issues: ValidationIssue[] = [];\n const values = Array.isArray(value) ? value : [value];\n for (const item of values) {\n const numeric = typeof item === 'number' ? item : Number(String(item).trim());\n if (!Number.isFinite(numeric)) {\n issues.push(issue(column, 'minmax', 'error', 'validation.minmax.notNumber', context));\n continue;\n }\n if (bounds.min !== null && numeric < bounds.min) {\n issues.push(\n issue(column, 'minmax', 'error', 'validation.minmax.belowMin', context, {\n min: bounds.min,\n }),\n );\n }\n if (bounds.max !== null && numeric > bounds.max) {\n issues.push(\n issue(column, 'minmax', 'error', 'validation.minmax.aboveMax', context, {\n max: bounds.max,\n }),\n );\n }\n }\n return issues;\n}\n\n/** v0 stub: spatial rules are not evaluated client-side (see ADR 0002). */\nexport function checkSpatial(\n column: ColumnSchema,\n value: unknown,\n context: MessageContext,\n): ValidationIssue[] {\n if (isEmpty(value)) return [];\n return [\n issue(column, 'spatial', 'unsupported', 'validation.notSupported', context, {\n type: 'spatial',\n }),\n ];\n}\n\n/** v0 stub: custom_check functions live server-side and are not evaluated here. */\nexport function checkCustomCheck(\n column: ColumnSchema,\n value: unknown,\n context: MessageContext,\n): ValidationIssue[] {\n if (isEmpty(value)) return [];\n return [\n issue(column, 'custom_check', 'unsupported', 'validation.notSupported', context, {\n type: 'custom_check',\n }),\n ];\n}\n","import type { ColumnSchema, FormSchema } from '../schema/types';\nimport { checkCustomCheck, checkMinmax, checkRegexp, checkRequired, checkSpatial } from './rules';\nimport {\n DEFAULT_VALIDATION_POLICY,\n type DocumentState,\n type ValidationIssue,\n type ValidationOptions,\n type ValidationPolicy,\n type ValidationResult,\n} from './types';\n\nfunction resolvePolicy(options?: ValidationOptions): ValidationPolicy {\n return { ...DEFAULT_VALIDATION_POLICY, ...options?.policy };\n}\n\n/**\n * Validate a single field value.\n *\n * The API performs no field-level validation on write, so this engine is the\n * enforcement layer (see ADR 0002 for the full policy model).\n */\nexport function validateField(\n column: ColumnSchema,\n value: unknown,\n state: DocumentState,\n options?: ValidationOptions,\n): ValidationIssue[] {\n const policy = resolvePolicy(options);\n const context = { language: options?.language, messages: options?.messages };\n\n if (state === 'draft' && policy.draftChecks === 'skip') return [];\n // Hidden fields are invisible to the user; nothing they could fix.\n if (column.api_params.hidden) return [];\n\n const issues: ValidationIssue[] = [];\n\n // Readonly fields skip `required` (the user cannot fill them) but keep\n // content checks: a bad prefilled value is a host bug worth surfacing.\n if (!column.api_params.readonly) {\n issues.push(...checkRequired(column, value, context));\n }\n\n const contentChecksApply = state === 'final' || policy.draftChecks === 'all';\n if (contentChecksApply) {\n switch (column.validate.type) {\n case 'regexp':\n issues.push(...checkRegexp(column, value, context));\n break;\n case 'minmax':\n issues.push(...checkMinmax(column, value, context));\n break;\n case 'spatial':\n issues.push(...checkSpatial(column, value, context));\n break;\n case 'custom_check':\n issues.push(...checkCustomCheck(column, value, context));\n break;\n case 'nocheck':\n break;\n }\n }\n\n if (!column.validate.soft) return issues;\n // Soft rules are the warn-but-allow tier: downgrade errors, keep the rest.\n return issues.map((item) =>\n item.severity === 'error' ? { ...item, severity: 'warning' as const } : item,\n );\n}\n\n/**\n * Validate a whole record against the form schema.\n *\n * `blocking` is true only for enforcement 'refuse' + state 'final' with at\n * least one error-severity issue; drafts and 'warn' enforcement never block.\n */\nexport function validateForm(\n schema: FormSchema,\n data: Record<string, unknown>,\n state: DocumentState,\n options?: ValidationOptions,\n): ValidationResult {\n const policy = resolvePolicy(options);\n const issues = schema.columns.flatMap((column) =>\n validateField(column, data[column.column], state, options),\n );\n\n const hasErrors = issues.some((item) => item.severity === 'error');\n const blocking = policy.enforcement === 'refuse' && state === 'final' && hasErrors;\n\n return { state, issues, blocking };\n}\n\n/** The single submission gate consulted by the submit client and the UI layer. */\nexport function canSubmit(result: ValidationResult): boolean {\n return !result.blocking;\n}\n"],"names":["FORM_COLUMN_TYPES","UNKNOWN_COLUMN_TYPE","DEFAULT_VALIDATION_POLICY","en","hu","catalogs","DEFAULT_LANGUAGE","formatMessage","key","params","language","overrides","catalog","match","name","isEmpty","value","issue","column","rule","severity","messageKey","context","checkRequired","checkRegexp","pattern","regexp","item","parseMinmaxBounds","parts","part","parseBound","parsed","min","max","checkMinmax","bounds","issues","values","numeric","checkSpatial","checkCustomCheck","resolvePolicy","options","validateField","state","policy","validateForm","schema","data","hasErrors","blocking","canSubmit","result"],"mappings":"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"}
@@ -0,0 +1 @@
1
+ .obm-geometry__map[data-v-08c09476]{height:var(--obm-form-map-height, 300px);border:1px solid var(--obm-form-input-border, #bbb);border-radius:var(--obm-form-input-radius, 4px)}.obm-geometry__toggle[data-v-08c09476]{display:inline-flex;align-items:center;gap:.3rem;margin-top:.3rem;font-size:.85rem;color:var(--obm-form-description-color, #666);cursor:pointer}.obm-geometry__text[data-v-08c09476]{display:block;width:100%;margin-top:.3rem;padding:var(--obm-form-input-padding, .4rem .6rem);border:1px solid var(--obm-form-input-border, #bbb);border-radius:var(--obm-form-input-radius, 4px);font-family:var(--obm-form-mono-font, monospace);font-size:.9rem;box-sizing:border-box;resize:vertical}.obm-geometry__hint[data-v-08c09476]{margin:.2rem 0 0;font-size:.85rem;color:var(--obm-form-warning-color, #b9770e)}.obm-array__items[data-v-f3bd5905]{display:flex;flex-wrap:wrap;gap:.3rem;margin:0 0 .3rem;padding:0;list-style:none}.obm-array__item[data-v-f3bd5905]{display:inline-flex;align-items:center;gap:.25rem;padding:.15rem .5rem;background:var(--obm-form-accent-soft, #e8f3ec);border-radius:999px;font-size:.85rem}.obm-array__remove[data-v-f3bd5905]{border:none;background:none;cursor:pointer;font:inherit;line-height:1}.obm-array__editor[data-v-f3bd5905]{display:flex;gap:.4rem}.obm-input[data-v-f3bd5905]{padding:var(--obm-form-input-padding, .4rem .6rem);border:1px solid var(--obm-form-input-border, #bbb);border-radius:var(--obm-form-input-radius, 4px);font:inherit;flex:1;box-sizing:border-box}.obm-array__add[data-v-f3bd5905]{padding:.35rem .8rem;border:1px solid var(--obm-form-input-border, #bbb);border-radius:var(--obm-form-input-radius, 4px);background:var(--obm-form-button-bg, #f7f7f7);font:inherit;cursor:pointer}.obm-autocomplete[data-v-f1029942]{position:relative;max-width:var(--obm-form-select-width, 24rem)}.obm-input[data-v-f1029942]{padding:var(--obm-form-input-padding, .4rem .6rem);border:1px solid var(--obm-form-input-border, #bbb);border-radius:var(--obm-form-input-radius, 4px);font:inherit;width:100%;box-sizing:border-box}.obm-autocomplete__list[data-v-f1029942]{position:absolute;z-index:10;left:0;right:0;margin:.15rem 0 0;padding:0;list-style:none;background:var(--obm-form-dropdown-bg, #fff);border:1px solid var(--obm-form-input-border, #bbb);border-radius:var(--obm-form-input-radius, 4px);max-height:14rem;overflow-y:auto;box-shadow:0 2px 6px #00000026}.obm-autocomplete__option[data-v-f1029942]{padding:.35rem .6rem;cursor:pointer}.obm-autocomplete__option--active[data-v-f1029942],.obm-autocomplete__option[data-v-f1029942]:hover{background:var(--obm-form-accent-soft, #e8f3ec)}.obm-autocomplete__tags[data-v-f1029942]{display:flex;flex-wrap:wrap;gap:.3rem;margin:0 0 .3rem;padding:0;list-style:none}.obm-autocomplete__tag[data-v-f1029942]{display:inline-flex;align-items:center;gap:.25rem;padding:.15rem .5rem;background:var(--obm-form-accent-soft, #e8f3ec);border-radius:999px;font-size:.85rem}.obm-autocomplete__remove[data-v-f1029942]{border:none;background:none;cursor:pointer;font:inherit;line-height:1;padding:0 .1rem}.obm-select[data-v-dcc3af9e]{padding:var(--obm-form-input-padding, .4rem .6rem);border:1px solid var(--obm-form-input-border, #bbb);border-radius:var(--obm-form-input-radius, 4px);font:inherit;max-width:var(--obm-form-boolean-width, 8rem)}.obm-checkbox[data-v-dcc3af9e]{width:1.1rem;height:1.1rem}.obm-input[data-v-7e3304c5]{padding:var(--obm-form-input-padding, .4rem .6rem);border:1px solid var(--obm-form-input-border, #bbb);border-radius:var(--obm-form-input-radius, 4px);font:inherit;width:100%;box-sizing:border-box}.obm-input--numeric[data-v-7e3304c5]{max-width:var(--obm-form-numeric-width, 12rem)}.obm-select[data-v-956359eb]{padding:var(--obm-form-input-padding, .4rem .6rem);border:1px solid var(--obm-form-input-border, #bbb);border-radius:var(--obm-form-input-radius, 4px);font:inherit;width:100%;max-width:var(--obm-form-select-width, 24rem);box-sizing:border-box}.obm-buttons[data-v-956359eb]{display:flex;flex-wrap:wrap;gap:.4rem}.obm-buttons__item[data-v-956359eb]{padding:.35rem .8rem;border:1px solid var(--obm-form-input-border, #bbb);border-radius:var(--obm-form-input-radius, 4px);background:var(--obm-form-button-bg, #f7f7f7);font:inherit;cursor:pointer}.obm-buttons__item--active[data-v-956359eb]{background:var(--obm-form-accent, #2c7a4b);border-color:var(--obm-form-accent, #2c7a4b);color:var(--obm-form-accent-contrast, #fff)}.obm-buttons__item[data-v-956359eb]:disabled{opacity:.6;cursor:not-allowed}.obm-buttons__empty[data-v-956359eb]{color:var(--obm-form-description-color, #666);font-size:.85rem}.dp--btn-base{font:inherit;transition:var(--dp-common-transition);border:none;line-height:normal}.dp--bg-none{background:0 0}.dp--active{background:var(--dp-primary-color);color:var(--dp-primary-text-color)}.dp--flex{align-items:center;display:flex}.dp--pointer{cursor:pointer}.dp--icon{stroke:currentColor;fill:currentColor}.dp--button{text-align:center;width:100%;color:var(--dp-icon-color);cursor:pointer;padding:var(--dp-common-padding);box-sizing:border-box;height:var(--dp-button-height);place-content:center;align-items:center;display:flex}.dp--button.dp--overlay-action{position:absolute;bottom:0}.dp--button .dp--main{font-family:var(--dp-font-family);-webkit-user-select:none;user-select:none;box-sizing:border-box;width:100%;position:relative}.dp--button .dp--main *{direction:var(--dp-direction,ltr)}.dp--button:hover{background:var(--dp-hover-color);color:var(--dp-hover-icon-color)}.dp--button svg{height:var(--dp-button-icon-height);width:auto}.dp--button-bottom{border-bottom-left-radius:var(--dp-border-radius);border-bottom-right-radius:var(--dp-border-radius)}.dp--flex-display{display:flex}.dp--relative{position:relative}.dp--highlighted{background-color:var(--dp-highlight-color)}.dp--hidden-el{visibility:hidden}.dp--centered{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%)}.dp--action-row{width:100%;padding:var(--dp-action-row-padding);box-sizing:border-box;color:var(--dp-text-color);flex-flow:row;align-items:center;display:flex}.dp--action-row svg{height:var(--dp-button-icon-height);width:auto}.dp--selection-preview{color:var(--dp-text-color);font-size:var(--dp-preview-font-size);white-space:nowrap;text-overflow:ellipsis;display:block;overflow:hidden}.dp--action-buttons{white-space:nowrap;flex:0;justify-content:flex-end;align-items:center;margin-inline-start:auto;display:flex}.dp--action-button{padding:var(--dp-action-buttons-padding);line-height:var(--dp-action-button-height);height:var(--dp-action-button-height);cursor:pointer;border-radius:var(--dp-border-radius);font-size:var(--dp-preview-font-size);font-family:var(--dp-font-family);background:0 0;border:1px solid #0000;align-items:center;margin-inline-start:3px;display:inline-flex}.dp--action-cancel{color:var(--dp-text-color);border:1px solid var(--dp-border-color)}.dp--action-cancel:hover{border-color:var(--dp-primary-color);transition:var(--dp-action-row-transition)}.dp--action-buttons .dp--action-select{background:var(--dp-primary-color);color:var(--dp-primary-text-color)}.dp--action-buttons .dp--action-select:hover{background:var(--dp-primary-color);transition:var(--dp-action-row-transition)}.dp--action-buttons .dp--action-select:disabled{background:var(--dp-primary-disabled-color);cursor:not-allowed}.dp--calendar-header{color:var(--dp-text-color);white-space:nowrap;justify-content:center;align-items:center;font-weight:700;display:flex;position:relative}.dp--calendar-header-item{text-align:center;height:var(--dp-cell-size);padding:var(--dp-cell-padding);width:var(--dp-cell-size);box-sizing:border-box;flex-grow:1}.dp--calendar-row{margin:var(--dp-row-margin);justify-content:center;align-items:center;display:flex}.dp--calendar-item{text-align:center;box-sizing:border-box;color:var(--dp-text-color);flex-grow:1}.dp--calendar{position:relative}.dp--calendar-header-cell{border-bottom:thin solid var(--dp-border-color);padding:var(--dp-calendar-header-cell-padding)}.dp--cell-inner{text-align:center;border-radius:var(--dp-cell-border-radius);height:var(--dp-cell-size);padding:var(--dp-cell-padding);width:var(--dp-cell-size);box-sizing:border-box;border:1px solid #0000;justify-content:center;align-items:center;display:flex;position:relative}.dp--cell-inner:hover{transition:all .2s}.dp--range-border-start{border-start-end-radius:0;border-end-end-radius:0}.dp--range-border-end{border-start-start-radius:0;border-end-start-radius:0}.dp--range-preview{border-top:1px dashed var(--dp-primary-color);border-bottom:1px dashed var(--dp-primary-color)}.dp--cell-offset{color:var(--dp-secondary-color)}.dp--cell-disabled{color:var(--dp-secondary-color);cursor:not-allowed}.dp--date-hoverable:hover{background:var(--dp-hover-color);color:var(--dp-hover-text-color)}.dp--date-hoverable-start:hover{border-start-end-radius:0;border-end-end-radius:0}.dp--date-hoverable-end:hover{border-start-start-radius:0;border-end-start-radius:0}.dp--range-between{background:var(--dp-range-between-dates-background-color);color:var(--dp-range-between-dates-text-color);border:1px solid var(--dp-range-between-border-color);border-radius:0}.dp--range-between-week{background:var(--dp-primary-color);color:var(--dp-primary-text-color);border-radius:0}.dp--today{border:1px solid var(--dp-primary-color)}.dp--week-num{color:var(--dp-secondary-color);text-align:center}.dp--cell-auto-range{border-radius:0}.dp--cell-auto-range-start{border-inline-start:1px dashed var(--dp-primary-color);border-start-start-radius:var(--dp-cell-border-radius);border-end-start-radius:var(--dp-cell-border-radius)}.dp--cell-auto-range-end{border-inline-end:1px dashed var(--dp-primary-color);border-start-end-radius:var(--dp-cell-border-radius);border-end-end-radius:var(--dp-cell-border-radius)}.dp--calendar-header-separator{background:var(--dp-border-color);width:100%;height:1px}.dp--calendar-next{margin-inline-start:var(--dp-multi-calendars-spacing)}.dp--marker-base{background-color:var(--dp-marker-color);height:5px;position:absolute;bottom:0}.dp--marker-dot{border-radius:50%;width:5px;left:50%;transform:translate(-50%)}.dp--marker-line{width:100%;left:0}.dp--marker-tooltip{border-radius:var(--dp-border-radius);background-color:var(--dp-tooltip-color);border:1px solid var(--dp-border-color);z-index:99999;box-sizing:border-box;cursor:default;padding:5px;position:absolute}.dp--tooltip-content{white-space:nowrap}.dp--tooltip-text{color:var(--dp-text-color);flex-flow:row;align-items:center;display:flex}.dp--tooltip-mark{background-color:var(--dp-text-color);width:5px;height:5px;color:var(--dp-text-color);border-radius:50%;margin-inline-end:5px}.dp--arrow-bottom-tp{background-color:var(--dp-tooltip-color);border-inline-end:1px solid var(--dp-border-color);border-bottom:1px solid var(--dp-border-color);width:8px;height:8px;position:absolute;bottom:0;transform:translate(-50%,50%)rotate(45deg)}.dp--instance-calendar{width:100%;position:relative}.dp--flex-display[data-dp-mobile],.dp--flex-display-collapsed{flex-direction:column}.dp--cell-highlight{background-color:var(--dp-highlight-color)}.dp--input-wrap{width:100%;box-sizing:unset;position:relative}.dp--input-wrap:focus{border-color:var(--dp-border-color-hover);outline:none}.dp--input-valid{box-shadow:0 0 var(--dp-border-radius) var(--dp-success-color);border-color:var(--dp-success-color)}.dp--input-valid:hover{border-color:var(--dp-success-color)}.dp--input-invalid{box-shadow:0 0 var(--dp-border-radius) var(--dp-danger-color);border-color:var(--dp-danger-color)}.dp--input-invalid:hover{border-color:var(--dp-danger-color)}.dp--input{background-color:var(--dp-background-color);border-radius:var(--dp-border-radius);font-family:var(--dp-font-family);border:1px solid var(--dp-border-color);width:100%;font-size:var(--dp-font-size);line-height:calc(var(--dp-font-size) * 1.5);padding:var(--dp-input-padding);color:var(--dp-text-color);box-sizing:border-box;outline:none;transition:border-color .2s cubic-bezier(.645,.045,.355,1)}.dp--input::placeholder{opacity:.7}.dp--input:hover:not(.dp--input-focus){border-color:var(--dp-border-color-hover)}.dp--input-not-clearable{padding-inline-end:var(--dp-input-not-clearable-padding)!important}.dp--input-reg{caret-color:#0000}.dp--input-focus{border-color:var(--dp-border-color-focus)}.dp--disabled{background:var(--dp-disabled-color)}.dp--disabled::placeholder{color:var(--dp-disabled-color-text)}.dp--input-icons{width:var(--dp-font-size);height:var(--dp-font-size);stroke-width:0;font-size:var(--dp-font-size);line-height:calc(var(--dp-font-size) * 1.5);color:var(--dp-icon-color);box-sizing:content-box;padding:6px 12px;display:inline-block}.dp--input-icon{cursor:pointer;top:50%;color:var(--dp-icon-color);position:absolute;inset-inline-start:0;transform:translateY(-50%)}.dp--clear-btn{top:50%;cursor:pointer;color:var(--dp-icon-color);background:0 0;border:none;align-items:center;margin:0;padding:0;display:inline-flex;position:absolute;inset-inline-end:0;transform:translateY(-50%)}.dp--input-icon-pad{padding-inline-start:var(--dp-input-icon-padding)}.dp--menu{background:var(--dp-background-color);border-radius:var(--dp-border-radius);min-width:var(--dp-menu-min-width);font-family:var(--dp-font-family);font-size:var(--dp-font-size);-webkit-user-select:none;user-select:none;border:1px solid var(--dp-menu-border-color);box-sizing:border-box}.dp--menu:after,.dp--menu:before{box-sizing:border-box}.dp--menu:focus{border:1px solid var(--dp-menu-border-color);outline:none}.dp--menu-wrapper{z-index:99999;position:absolute}.dp--menu-inner{padding:var(--dp-menu-padding)}.dp--menu--inner-stretched{padding:6px 0}.dp--menu-index{z-index:99999}.dp--menu-unclickable{z-index:999999;position:absolute;top:0;right:0;bottom:0;left:0}.dp--menu-disabled{cursor:not-allowed;background:#ffffff80}.dp--menu-readonly{cursor:default;background:0 0}.dp-menu-loading{cursor:default;background:#ffffff80}.dp--menu-load-container{justify-content:center;align-items:center;width:100%;height:100%;display:flex}.dp--menu-loader{border:var(--dp-loader);box-sizing:border-box;border-bottom-color:#0000;border-radius:50%;width:48px;height:48px;animation:1s linear infinite dp-load-rotation;display:inline-block;position:absolute}@keyframes dp-load-rotation{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.dp--arrow-top{background-color:var(--dp-background-color);border-inline-end:1px solid var(--dp-menu-border-color);border-top:1px solid var(--dp-menu-border-color);width:12px;height:12px;position:absolute;transform:translateY(-50%)rotate(-45deg)}.dp--arrow-bottom{left:var(--dp-arrow-left);background-color:var(--dp-background-color);border-inline-end:1px solid var(--dp-menu-border-color);border-bottom:1px solid var(--dp-menu-border-color);width:12px;height:12px;position:absolute;bottom:0;transform:translate(-50%,50%)rotate(45deg)}.dp--action-extra{text-align:center;padding:2px 0}.dp--preset-dates{border-inline-end:1px solid var(--dp-border-color);padding:5px}.dp--preset-dates[data-dp-mobile],.dp--preset-dates-collapsed{max-width:calc(var(--dp-menu-width) - var(--dp-action-row-padding) * 2);border:none;align-self:center;display:flex;overflow-x:auto}.dp--sidebar-left{border-inline-end:1px solid var(--dp-border-color);padding:5px}.dp--sidebar-right{margin-inline-end:1px solid var(--dp-border-color);padding:5px}.dp--preset-range{text-align:left;white-space:nowrap;width:100%;color:var(--dp-text-color);border-radius:var(--dp-border-radius);transition:var(--dp-common-transition);padding:5px;display:block}.dp--preset-range:hover{background-color:var(--dp-hover-color);color:var(--dp-hover-text-color);cursor:pointer}.dp--preset-range[data-dp-mobile]{border:1px solid var(--dp-border-color);margin:0 3px}.dp--preset-range[data-dp-mobile]:first-child{margin-left:0}.dp--preset-range[data-dp-mobile]:last-child{margin-right:0}.dp--preset-range-collapsed{border:1px solid var(--dp-border-color);margin:0 3px}.dp--preset-range-collapsed:first-child{margin-left:0}.dp--preset-range-collapsed:last-child{margin-right:0}.dp--menu-content-wrapper{display:flex}.dp--menu-content-wrapper[data-dp-mobile],.dp--menu-content-wrapper-collapsed{flex-direction:column-reverse}.dp--month-year-row{height:var(--dp-month-year-row-height);color:var(--dp-text-color);box-sizing:border-box;align-items:center;display:flex}.dp--inner-nav{cursor:pointer;height:var(--dp-month-year-row-button-size);width:var(--dp-month-year-row-button-size);color:var(--dp-icon-color);text-align:center;border-radius:50%;justify-content:center;align-items:center;display:flex}.dp--inner-nav svg{height:var(--dp-button-icon-height);width:var(--dp-button-icon-height)}.dp--inner-nav:hover{background:var(--dp-hover-color);color:var(--dp-hover-icon-color)}[dir=rtl] .dp--inner-nav{transform:rotate(180deg)}.dp--inner-nav-disabled,.dp--inner-nav-disabled:hover{background:var(--dp-disabled-color);color:var(--dp-disabled-color-text);cursor:not-allowed}.dp--month-year-select-base{text-align:center;cursor:pointer;height:var(--dp-month-year-row-height);border-radius:var(--dp-border-radius);box-sizing:border-box;color:var(--dp-text-color);justify-content:center;align-items:center;display:flex}.dp--month-year-select-base:hover{background:var(--dp-hover-color);color:var(--dp-hover-text-color);transition:var(--dp-common-transition)}.dp--month-year-select{width:50%}.dp--year-select{width:100%}.dp--month-year-wrap{flex-direction:row;align-items:center;width:100%;display:flex}.dp--year-disable-select{justify-content:space-around}.dp--header-wrap{flex-direction:column;width:100%;display:flex}.dp--year-mode-picker{width:100%;height:var(--dp-cell-size);justify-content:space-between;align-items:center;display:flex}.dp--arrow-btn-nav{transition:var(--dp-common-transition);height:100%}.dp-quarter-picker-wrap{height:100%;min-width:var(--dp-menu-min-width);flex-direction:column;display:flex}.dp--qr-btn-disabled{cursor:not-allowed;background:var(--dp-disabled-color)}.dp--qr-btn-disabled:hover{background:var(--dp-disabled-color)}.dp--qr-btn{width:100%;padding:var(--dp-common-padding)}.dp--qr-btn:not(.dp--highlighted,.dp--active,.dp--qr-btn-disabled,.dp--qr-btn-between){background:0 0}.dp--qr-btn:hover:not(.dp--active,.dp--qr-btn-disabled){background:var(--dp-hover-color);color:var(--dp-hover-text-color);transition:var(--dp-common-transition)}.dp--quarter-items{flex-direction:column;flex:1;justify-content:space-evenly;width:100%;height:100%;display:flex}.dp--qr-btn-between{background:var(--dp-hover-color);color:var(--dp-hover-text-color)}.dp--overlay{background:var(--dp-background-color);z-index:99999;width:100%;font-family:var(--dp-font-family);color:var(--dp-text-color);box-sizing:border-box;transition:opacity 1s ease-out}.dp--overlay-absolute{height:100%;position:absolute;top:0;left:0}.dp--overlay-relative{position:relative}.dp--overlay-container::-webkit-scrollbar-track{box-shadow:var(--dp-scroll-bar-background);background-color:var(--dp-scroll-bar-background)}.dp--overlay-container::-webkit-scrollbar{background-color:var(--dp-scroll-bar-background);width:5px}.dp--overlay-container::-webkit-scrollbar-thumb{background-color:var(--dp-scroll-bar-color);border-radius:10px}.dp--overlay:focus{border:none;outline:none}.dp--container-flex{display:flex}.dp--container-block{display:block}.dp--overlay-container{height:var(--dp-overlay-height);flex-direction:column;overflow-y:auto}.dp--time-picker-overlay-container{height:100%}.dp--overlay-row{box-sizing:border-box;flex-wrap:wrap;align-items:center;width:100%;max-width:100%;margin-inline:auto;padding:0;display:flex}.dp--flex-row{flex:1}.dp--overlay-col{box-sizing:border-box;width:33%;padding:var(--dp-overlay-col-padding);white-space:nowrap}.dp--overlay-cell-pad{padding:var(--dp-common-padding) 0}.dp--overlay-cell-active,.dp--overlay-cell{cursor:pointer;border-radius:var(--dp-border-radius);text-align:center}.dp--overlay-cell:hover{background:var(--dp-hover-color);color:var(--dp-hover-text-color);transition:var(--dp-common-transition)}.dp--cell-in-between{background:var(--dp-hover-color);color:var(--dp-hover-text-color)}.dp--over-action-scroll{box-sizing:border-box;right:5px}.dp--overlay-cell-disabled{cursor:not-allowed;background:var(--dp-disabled-color)}.dp--overlay-cell-disabled:hover{background:var(--dp-disabled-color)}.dp--overlay-cell-active-disabled{cursor:not-allowed;background:var(--dp-primary-disabled-color)}.dp--overlay-cell-active-disabled:hover{background:var(--dp-primary-disabled-color)}.dp--tp-wrap{width:100%}.dp--tp-wrap[data-dp-mobile]{max-width:100%}.dp--time-input{-webkit-user-select:none;user-select:none;width:100%;font-family:var(--dp-font-family);color:var(--dp-text-color);justify-content:center;align-items:center;display:flex}.dp--time-col-reg-block{padding:0 20px}.dp--time-col-reg-inline{padding:0 10px}.dp--time-col-reg-with-button{padding:0 15px}.dp--time-col-reg-with-button[data-compact~=true]{padding:0 5px}.dp--time-col-sec{padding:0 10px}.dp--time-col-sec-with-button{padding:0 5px}.dp--time-col-sec-with-button[data-collapsed~=true]{padding:0}.dp--time-col{text-align:center;flex-direction:column;justify-content:center;align-items:center;display:flex}.dp--time-col-block{font-size:var(--dp-time-font-size)}.dp--inc-dec-button-disabled,.dp--inc-dec-button-disabled:hover{background:var(--dp-disabled-color);color:var(--dp-disabled-color-text);cursor:not-allowed}.dp--time-display-block{padding:0 3px}.dp--time-display-inline{padding:5px}.dp--time-picker-inline-container{justify-content:center;width:100%;display:flex}.dp--inc-dec-button{height:var(--dp-time-inc-dec-button-size);width:var(--dp-time-inc-dec-button-size);cursor:pointer;color:var(--dp-icon-color);box-sizing:border-box;border-radius:50%;justify-content:center;align-items:center;margin:0;padding:5px;display:flex}.dp--inc-dec-button svg{height:var(--dp-time-inc-dec-button-size);width:var(--dp-time-inc-dec-button-size)}.dp--inc-dec-button:hover{background:var(--dp-hover-color);color:var(--dp-hover-icon-color)}.dp--time-display{cursor:pointer;color:var(--dp-text-color);border-radius:var(--dp-border-radius);justify-content:center;align-items:center;display:flex}.dp--time-display:hover:enabled{background:var(--dp-hover-color);color:var(--dp-hover-text-color)}.dp--inc-dec-button-inline{cursor:pointer;align-items:center;width:100%;height:8px;padding:0;display:flex}.dp--pm-am-button{background:var(--dp-primary-color);color:var(--dp-primary-text-color);padding:var(--dp-common-padding);border-radius:var(--dp-border-radius);cursor:pointer;border:none}.dp--pm-am-button[data-compact~=true]{padding:7px}.dp--tp-inline-btn-bar{background-color:var(--dp-secondary-color);width:100%;height:4px;transition:var(--dp-common-transition);border-collapse:collapse}.dp--tp-inline-btn-top:hover .dp--tp-btn-in-r{background-color:var(--dp-primary-color);transform:rotate(12deg)scale(1.15)translateY(-2px)}.dp--tp-inline-btn-top:hover .dp--tp-btn-in-l,.dp--tp-inline-btn-bottom:hover .dp--tp-btn-in-r{background-color:var(--dp-primary-color);transform:rotate(-12deg)scale(1.15)translateY(-2px)}.dp--tp-inline-btn-bottom:hover .dp--tp-btn-in-l{background-color:var(--dp-primary-color);transform:rotate(12deg)scale(1.15)translateY(-2px)}.dp--time-overlay-btn{background:0 0}.dp--time-invalid{background-color:var(--dp-disabled-color)}:root{--dp-common-transition:all .1s ease-in;--dp-menu-padding:6px 8px;--dp-animation-duration:.1s;--dp-menu-appear-transition-timing:cubic-bezier(.4, 0, 1, 1);--dp-transition-timing:ease-out;--dp-action-row-transition:all .2s ease-in;--dp-font-family:-apple-system, blinkmacsystemfont, "Segoe UI", roboto, oxygen, ubuntu, cantarell, "Open Sans", "Helvetica Neue", sans-serif;--dp-border-radius:4px;--dp-cell-border-radius:4px;--dp-transition-length:22px;--dp-transition-timing-general:.1s;--dp-button-height:35px;--dp-month-year-row-height:35px;--dp-month-year-row-button-size:25px;--dp-button-icon-height:20px;--dp-calendar-wrap-padding:0 5px;--dp-cell-size:35px;--dp-cell-padding:5px;--dp-common-padding:10px;--dp-input-icon-padding:35px;--dp-input-padding:6px 30px 6px 12px;--dp-input-not-clearable-padding:12px;--dp-menu-min-width:260px;--dp-action-buttons-padding:1px 6px;--dp-row-margin:5px 0;--dp-calendar-header-cell-padding:8px;--dp-multi-calendars-spacing:10px;--dp-overlay-col-padding:3px;--dp-time-inc-dec-button-size:32px;--dp-font-size:1rem;--dp-preview-font-size:.8rem;--dp-time-font-size:2rem;--dp-action-button-height:22px;--dp-action-row-padding:8px;--dp-direction:ltr}.dp--theme-dark{--dp-background-color:#212121;--dp-text-color:#fff;--dp-hover-color:#484848;--dp-hover-text-color:#fff;--dp-hover-icon-color:#959595;--dp-primary-color:#005cb2;--dp-primary-disabled-color:#61a8ea;--dp-primary-text-color:#fff;--dp-secondary-color:#a9a9a9;--dp-border-color:#2d2d2d;--dp-menu-border-color:#2d2d2d;--dp-border-color-hover:#aaaeb7;--dp-border-color-focus:#aaaeb7;--dp-disabled-color:#737373;--dp-disabled-color-text:#d0d0d0;--dp-scroll-bar-background:#212121;--dp-scroll-bar-color:#484848;--dp-success-color:#00701a;--dp-success-color-disabled:#428f59;--dp-icon-color:#959595;--dp-danger-color:#e53935;--dp-marker-color:#e53935;--dp-tooltip-color:#3e3e3e;--dp-highlight-color:#005cb233;--dp-range-between-dates-background-color:var(--dp-hover-color,#484848);--dp-range-between-dates-text-color:var(--dp-hover-text-color,#fff);--dp-range-between-border-color:var(--dp-hover-color,#fff);--dp-loader:5px solid #005cb2}.dp--theme-light{--dp-background-color:#fff;--dp-text-color:#212121;--dp-hover-color:#f3f3f3;--dp-hover-text-color:#212121;--dp-hover-icon-color:#959595;--dp-primary-color:#1976d2;--dp-primary-disabled-color:#6bacea;--dp-primary-text-color:#fff;--dp-secondary-color:#c0c4cc;--dp-border-color:#ddd;--dp-menu-border-color:#ddd;--dp-border-color-hover:#aaaeb7;--dp-border-color-focus:#aaaeb7;--dp-disabled-color:#f6f6f6;--dp-scroll-bar-background:#f3f3f3;--dp-scroll-bar-color:#959595;--dp-success-color:#76d275;--dp-success-color-disabled:#a3d9b1;--dp-icon-color:#959595;--dp-danger-color:#ff6f60;--dp-marker-color:#ff6f60;--dp-tooltip-color:#fafafa;--dp-disabled-color-text:#8e8e8e;--dp-highlight-color:#1976d21a;--dp-range-between-dates-background-color:var(--dp-hover-color,#f3f3f3);--dp-range-between-dates-text-color:var(--dp-hover-text-color,#212121);--dp-range-between-border-color:var(--dp-hover-color,#f3f3f3);--dp-loader:5px solid #1976d2}.calendar-next-enter-active,.calendar-next-leave-active,.calendar-prev-enter-active,.calendar-prev-leave-active{transition:all var(--dp-transition-timing-general) ease-out}.calendar-next-enter-from{opacity:0;transform:translate(var(--dp-transition-length))}.calendar-next-leave-to,.calendar-prev-enter-from{opacity:0;transform:translate(calc(var(--dp-transition-length) * -1))}.calendar-prev-leave-to{opacity:0;transform:translate(var(--dp-transition-length))}.dp-menu-appear-bottom-enter-active,.dp-menu-appear-bottom-leave-active,.dp-menu-appear-top-enter-active,.dp-menu-appear-top-leave-active,.dp-slide-up-enter-active,.dp-slide-up-leave-active,.dp-slide-down-enter-active,.dp-slide-down-leave-active{transition:all var(--dp-animation-duration) var(--dp-transition-timing)}.dp-menu-appear-top-enter-from,.dp-menu-appear-top-leave-to,.dp-slide-down-leave-to,.dp-slide-up-enter-from{opacity:0;transform:translateY(var(--dp-transition-length))}.dp-menu-appear-bottom-enter-from,.dp-menu-appear-bottom-leave-to,.dp-slide-down-enter-from,.dp-slide-up-leave-to{opacity:0;transform:translateY(calc(var(--dp-transition-length) * -1))}.dp--flex-display-with-input{flex-direction:column;align-items:flex-start}.obm-input--temporal[data-v-4d74b753]{max-width:var(--obm-form-temporal-width, 16rem)}.obm-textarea[data-v-89317b83]{padding:var(--obm-form-input-padding, .4rem .6rem);border:1px solid var(--obm-form-input-border, #bbb);border-radius:var(--obm-form-input-radius, 4px);font:inherit;width:100%;box-sizing:border-box;resize:vertical}.obm-input[data-v-17beed28]{padding:var(--obm-form-input-padding, .4rem .6rem);border:1px solid var(--obm-form-input-border, #bbb);border-radius:var(--obm-form-input-radius, 4px);font:inherit;width:100%;box-sizing:border-box}.obm-input[data-v-47ce4a6f]{max-width:var(--obm-form-temporal-width, 16rem)}.obm-unsupported[data-v-bf4d6902]{padding:.5rem .75rem;border:1px dashed var(--obm-form-input-border, #bbb);border-radius:var(--obm-form-input-radius, 4px);background:var(--obm-form-muted-bg, #fafafa)}.obm-unsupported__message[data-v-bf4d6902]{margin:0;color:var(--obm-form-description-color, #666)}.obm-unsupported__type[data-v-bf4d6902]{margin:.2rem 0 0;font-size:.8rem;color:var(--obm-form-notice-color, #7f8c8d)}.obm-textarea[data-v-ddeb8617]{padding:var(--obm-form-input-padding, .4rem .6rem);border:1px solid var(--obm-form-input-border, #bbb);border-radius:var(--obm-form-input-radius, 4px);font-family:var(--obm-form-mono-font, monospace);font-size:.9rem;width:100%;box-sizing:border-box;resize:vertical}.obm-wkt__hint[data-v-ddeb8617]{margin:.2rem 0 0;font-size:.85rem;color:var(--obm-form-warning-color, #b9770e)}.obm-field[data-v-6bb9fbe4]{display:flex;flex-direction:column;gap:var(--obm-form-field-gap, .25rem);margin-bottom:var(--obm-form-field-margin, 1rem);font-family:var(--obm-form-font-family, inherit)}.obm-field__label[data-v-6bb9fbe4]{font-weight:var(--obm-form-label-weight, 600);color:var(--obm-form-label-color, inherit)}.obm-field__required[data-v-6bb9fbe4]{color:var(--obm-form-required-color, #c0392b);margin-left:.15rem}.obm-field__description[data-v-6bb9fbe4]{margin:0;font-size:var(--obm-form-description-size, .85rem);color:var(--obm-form-description-color, #666)}.obm-field__issues[data-v-6bb9fbe4]{margin:0;padding-left:1.2rem;font-size:var(--obm-form-issue-size, .85rem)}.obm-field__issue--error[data-v-6bb9fbe4]{color:var(--obm-form-error-color, #c0392b)}.obm-field__issue--warning[data-v-6bb9fbe4]{color:var(--obm-form-warning-color, #b9770e)}.obm-field__issue--notice[data-v-6bb9fbe4]{color:var(--obm-form-notice-color, #7f8c8d)}.obm-field--invalid[data-v-6bb9fbe4] input,.obm-field--invalid[data-v-6bb9fbe4] select,.obm-field--invalid[data-v-6bb9fbe4] textarea{border-color:var(--obm-form-error-color, #c0392b);outline-color:var(--obm-form-error-color, #c0392b)}.obm-summary[data-v-3ea41b02]{border:1px solid var(--obm-form-summary-border, #e0c9c5);border-left:4px solid var(--obm-form-error-color, #c0392b);border-radius:var(--obm-form-input-radius, 4px);background:var(--obm-form-summary-bg, #fdf3f2);padding:.75rem 1rem;margin-bottom:1rem}.obm-summary__title[data-v-3ea41b02]{margin:0 0 .3rem;font-weight:600}.obm-summary__title--error[data-v-3ea41b02]{color:var(--obm-form-error-color, #c0392b)}.obm-summary__title--warning[data-v-3ea41b02]{color:var(--obm-form-warning-color, #b9770e)}.obm-summary__title--notice[data-v-3ea41b02]{color:var(--obm-form-notice-color, #7f8c8d)}.obm-summary__list[data-v-3ea41b02]{margin:0 0 .5rem;padding-left:1.2rem}.obm-form[data-v-28c84992]{max-width:var(--obm-form-max-width, 42rem);font-family:var(--obm-form-font-family, inherit)}.obm-form__actions[data-v-28c84992]{display:flex;gap:.6rem;margin-top:1.25rem}.obm-form__button[data-v-28c84992]{padding:.5rem 1.1rem;border-radius:var(--obm-form-input-radius, 4px);font:inherit;cursor:pointer}.obm-form__button--draft[data-v-28c84992]{border:1px solid var(--obm-form-accent, #2c7a4b);background:transparent;color:var(--obm-form-accent, #2c7a4b)}.obm-form__button--finalize[data-v-28c84992]{border:1px solid var(--obm-form-accent, #2c7a4b);background:var(--obm-form-accent, #2c7a4b);color:var(--obm-form-accent-contrast, #fff)}.obm-form__button[data-v-28c84992]:disabled{opacity:.6;cursor:not-allowed}
@@ -0,0 +1,30 @@
1
+ import { ColumnSchema } from '../core/schema/types';
2
+ import { ValidationIssue } from '../core/validation/types';
3
+ type __VLS_Props = {
4
+ column: ColumnSchema;
5
+ issues?: ValidationIssue[];
6
+ language?: string;
7
+ /** id of the wrapped input, connected to the label. */
8
+ inputId?: string;
9
+ };
10
+ declare function __VLS_template(): {
11
+ attrs: Partial<{}>;
12
+ slots: {
13
+ default?(_: {}): any;
14
+ };
15
+ refs: {};
16
+ rootEl: HTMLDivElement;
17
+ };
18
+ type __VLS_TemplateResult = ReturnType<typeof __VLS_template>;
19
+ declare const __VLS_component: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
20
+ language: string;
21
+ issues: ValidationIssue[];
22
+ inputId: string;
23
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, HTMLDivElement>;
24
+ declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
25
+ export default _default;
26
+ type __VLS_WithTemplateSlots<T, S> = T & {
27
+ new (): {
28
+ $slots: S;
29
+ };
30
+ };
@@ -0,0 +1,58 @@
1
+ import { FormSchema } from '../core/schema/types';
2
+ import { DocumentState, ValidationOptions, ValidationResult } from '../core/validation/types';
3
+ import { FieldRegistry } from './fieldRegistry';
4
+ /**
5
+ * Schema-driven upload form. Renders form_body (already sorted by
6
+ * normalizeFormDetails), validates per the policy model (ADR 0002) and emits
7
+ * `submit` — it does not POST itself; wire the event to submitObservation().
8
+ */
9
+ type __VLS_Props = {
10
+ schema: FormSchema;
11
+ /** Initial/externally-managed values; overlaid on column defaults. */
12
+ modelValue?: Record<string, unknown>;
13
+ validation?: ValidationOptions;
14
+ registry?: Partial<FieldRegistry>;
15
+ language?: string;
16
+ disabled?: boolean;
17
+ /** Hide the draft button for single-step forms. */
18
+ showDraftButton?: boolean;
19
+ labels?: Partial<{
20
+ saveDraft: string;
21
+ finalize: string;
22
+ }>;
23
+ };
24
+ declare const _default: import('vue').DefineComponent<__VLS_Props, {
25
+ /** Sticky/once_field-aware reset for "save and add another" flows. */
26
+ resetForNextEntry: () => void;
27
+ validate: (state: DocumentState) => ValidationResult;
28
+ }, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
29
+ "update:modelValue": (values: Record<string, unknown>) => any;
30
+ submit: (payload: {
31
+ data: Record<string, unknown>;
32
+ state: DocumentState;
33
+ validation: ValidationResult;
34
+ }) => any;
35
+ refused: (result: ValidationResult) => any;
36
+ }, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{
37
+ "onUpdate:modelValue"?: ((values: Record<string, unknown>) => any) | undefined;
38
+ onSubmit?: ((payload: {
39
+ data: Record<string, unknown>;
40
+ state: DocumentState;
41
+ validation: ValidationResult;
42
+ }) => any) | undefined;
43
+ onRefused?: ((result: ValidationResult) => any) | undefined;
44
+ }>, {
45
+ language: string;
46
+ validation: ValidationOptions;
47
+ modelValue: Record<string, unknown>;
48
+ disabled: boolean;
49
+ registry: Partial<FieldRegistry>;
50
+ showDraftButton: boolean;
51
+ labels: Partial<{
52
+ saveDraft: string;
53
+ finalize: string;
54
+ }>;
55
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {
56
+ rootElement: HTMLDivElement;
57
+ }, HTMLDivElement>;
58
+ export default _default;
@@ -0,0 +1,13 @@
1
+ import { ColumnSchema } from '../core/schema/types';
2
+ import { ValidationIssue } from '../core/validation/types';
3
+ type __VLS_Props = {
4
+ issues: ValidationIssue[];
5
+ /** Used to resolve column names to labels. */
6
+ columns?: ColumnSchema[];
7
+ language?: string;
8
+ };
9
+ declare const _default: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
10
+ language: string;
11
+ columns: ColumnSchema[];
12
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
13
+ export default _default;
@@ -0,0 +1,5 @@
1
+ import { Component } from 'vue';
2
+ import { NormalizedColumnType } from '../core/schema/types';
3
+ /** Column type → widget component. Hosts may override any entry. */
4
+ export type FieldRegistry = Record<NormalizedColumnType, Component>;
5
+ export declare function createFieldRegistry(overrides?: Partial<FieldRegistry>): FieldRegistry;
@@ -0,0 +1,14 @@
1
+ import { FieldProps } from '../types';
2
+ declare const _default: import('vue').DefineComponent<FieldProps, {
3
+ inputId: string;
4
+ }, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
5
+ "update:modelValue": (value: unknown) => any;
6
+ }, string, import('vue').PublicProps, Readonly<FieldProps> & Readonly<{
7
+ "onUpdate:modelValue"?: ((value: unknown) => any) | undefined;
8
+ }>, {
9
+ language: string;
10
+ issues: import('../../core').ValidationIssue[];
11
+ disabled: boolean;
12
+ options: import('../../core').FormListElement[];
13
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, HTMLDivElement>;
14
+ export default _default;
@@ -0,0 +1,15 @@
1
+ import { FormListElement } from '../../core/schema/types';
2
+ import { FieldProps } from '../types';
3
+ declare const _default: import('vue').DefineComponent<FieldProps, {
4
+ inputId: string;
5
+ }, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
6
+ "update:modelValue": (value: unknown) => any;
7
+ }, string, import('vue').PublicProps, Readonly<FieldProps> & Readonly<{
8
+ "onUpdate:modelValue"?: ((value: unknown) => any) | undefined;
9
+ }>, {
10
+ language: string;
11
+ issues: import('../../core').ValidationIssue[];
12
+ disabled: boolean;
13
+ options: FormListElement[];
14
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, HTMLDivElement>;
15
+ export default _default;
@@ -0,0 +1,14 @@
1
+ import { FieldProps } from '../types';
2
+ declare const _default: import('vue').DefineComponent<FieldProps, {
3
+ inputId: string;
4
+ }, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
5
+ "update:modelValue": (value: unknown) => any;
6
+ }, string, import('vue').PublicProps, Readonly<FieldProps> & Readonly<{
7
+ "onUpdate:modelValue"?: ((value: unknown) => any) | undefined;
8
+ }>, {
9
+ language: string;
10
+ issues: import('../../core').ValidationIssue[];
11
+ disabled: boolean;
12
+ options: import('../../core').FormListElement[];
13
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
14
+ export default _default;
@@ -0,0 +1,14 @@
1
+ import { FieldProps } from '../types';
2
+ declare const _default: import('vue').DefineComponent<FieldProps, {
3
+ inputId: string;
4
+ }, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
5
+ "update:modelValue": (value: unknown) => any;
6
+ }, string, import('vue').PublicProps, Readonly<FieldProps> & Readonly<{
7
+ "onUpdate:modelValue"?: ((value: unknown) => any) | undefined;
8
+ }>, {
9
+ language: string;
10
+ issues: import('../../core').ValidationIssue[];
11
+ disabled: boolean;
12
+ options: import('../../core').FormListElement[];
13
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, HTMLInputElement>;
14
+ export default _default;
@@ -0,0 +1,15 @@
1
+ import { FormListElement } from '../../core/schema/types';
2
+ import { FieldProps } from '../types';
3
+ declare const _default: import('vue').DefineComponent<FieldProps, {
4
+ inputId: string;
5
+ }, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
6
+ "update:modelValue": (value: unknown) => any;
7
+ }, string, import('vue').PublicProps, Readonly<FieldProps> & Readonly<{
8
+ "onUpdate:modelValue"?: ((value: unknown) => any) | undefined;
9
+ }>, {
10
+ language: string;
11
+ issues: import('../../core').ValidationIssue[];
12
+ disabled: boolean;
13
+ options: FormListElement[];
14
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
15
+ export default _default;
@@ -0,0 +1,14 @@
1
+ import { FieldProps } from '../types';
2
+ declare const _default: import('vue').DefineComponent<FieldProps, {
3
+ inputId: string;
4
+ }, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
5
+ "update:modelValue": (value: unknown) => any;
6
+ }, string, import('vue').PublicProps, Readonly<FieldProps> & Readonly<{
7
+ "onUpdate:modelValue"?: ((value: unknown) => any) | undefined;
8
+ }>, {
9
+ language: string;
10
+ issues: import('../../core').ValidationIssue[];
11
+ disabled: boolean;
12
+ options: import('../../core').FormListElement[];
13
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
14
+ export default _default;
@@ -0,0 +1,14 @@
1
+ import { FieldProps } from '../types';
2
+ declare const _default: import('vue').DefineComponent<FieldProps, {
3
+ inputId: string;
4
+ }, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
5
+ "update:modelValue": (value: unknown) => any;
6
+ }, string, import('vue').PublicProps, Readonly<FieldProps> & Readonly<{
7
+ "onUpdate:modelValue"?: ((value: unknown) => any) | undefined;
8
+ }>, {
9
+ language: string;
10
+ issues: import('../../core').ValidationIssue[];
11
+ disabled: boolean;
12
+ options: import('../../core').FormListElement[];
13
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, HTMLTextAreaElement>;
14
+ export default _default;
@@ -0,0 +1,14 @@
1
+ import { FieldProps } from '../types';
2
+ declare const _default: import('vue').DefineComponent<FieldProps, {
3
+ inputId: string;
4
+ }, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
5
+ "update:modelValue": (value: unknown) => any;
6
+ }, string, import('vue').PublicProps, Readonly<FieldProps> & Readonly<{
7
+ "onUpdate:modelValue"?: ((value: unknown) => any) | undefined;
8
+ }>, {
9
+ language: string;
10
+ issues: import('../../core').ValidationIssue[];
11
+ disabled: boolean;
12
+ options: import('../../core').FormListElement[];
13
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, HTMLInputElement>;
14
+ export default _default;
@@ -0,0 +1,14 @@
1
+ import { FieldProps } from '../types';
2
+ declare const _default: import('vue').DefineComponent<FieldProps, {
3
+ inputId: string;
4
+ }, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
5
+ "update:modelValue": (value: unknown) => any;
6
+ }, string, import('vue').PublicProps, Readonly<FieldProps> & Readonly<{
7
+ "onUpdate:modelValue"?: ((value: unknown) => any) | undefined;
8
+ }>, {
9
+ language: string;
10
+ issues: import('../../core').ValidationIssue[];
11
+ disabled: boolean;
12
+ options: import('../../core').FormListElement[];
13
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
14
+ export default _default;
@@ -0,0 +1,8 @@
1
+ import { FieldProps } from '../types';
2
+ declare const _default: import('vue').DefineComponent<FieldProps, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<FieldProps> & Readonly<{}>, {
3
+ language: string;
4
+ issues: import('../../core').ValidationIssue[];
5
+ disabled: boolean;
6
+ options: import('../../core').FormListElement[];
7
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, HTMLDivElement>;
8
+ export default _default;
@@ -0,0 +1,14 @@
1
+ import { FieldProps } from '../types';
2
+ declare const _default: import('vue').DefineComponent<FieldProps, {
3
+ inputId: string;
4
+ }, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
5
+ "update:modelValue": (value: unknown) => any;
6
+ }, string, import('vue').PublicProps, Readonly<FieldProps> & Readonly<{
7
+ "onUpdate:modelValue"?: ((value: unknown) => any) | undefined;
8
+ }>, {
9
+ language: string;
10
+ issues: import('../../core').ValidationIssue[];
11
+ disabled: boolean;
12
+ options: import('../../core').FormListElement[];
13
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, HTMLDivElement>;
14
+ export default _default;
@@ -0,0 +1,19 @@
1
+ /** Vue 3 entry (`obm-upload-form-ui/vue`). */
2
+ export { createFieldRegistry, type FieldRegistry } from './fieldRegistry';
3
+ export { useFormState } from './useFormState';
4
+ export { uiText, type UiTextKey } from './uiText';
5
+ export type { FieldEmits, FieldProps } from './types';
6
+ export { default as FieldWrapper } from './FieldWrapper.vue';
7
+ export { default as ValidationSummary } from './ValidationSummary.vue';
8
+ export { default as UploadForm } from './UploadForm.vue';
9
+ export { default as TextField } from './fields/TextField.vue';
10
+ export { default as TextAreaField } from './fields/TextAreaField.vue';
11
+ export { default as NumericField } from './fields/NumericField.vue';
12
+ export { default as BooleanField } from './fields/BooleanField.vue';
13
+ export { default as TemporalField } from './fields/TemporalField.vue';
14
+ export { default as TimeIntervalField } from './fields/TimeIntervalField.vue';
15
+ export { default as SelectField } from './fields/SelectField.vue';
16
+ export { default as AutocompleteField } from './fields/AutocompleteField.vue';
17
+ export { default as ArrayField } from './fields/ArrayField.vue';
18
+ export { default as WktTextField } from './fields/WktTextField.vue';
19
+ export { default as UnsupportedField } from './fields/UnsupportedField.vue';
@@ -0,0 +1,22 @@
1
+ import { ColumnSchema, FormListElement } from '../core/schema/types';
2
+ import { ValidationIssue } from '../core/validation/types';
3
+ /**
4
+ * Common props contract shared by every field widget. UploadForm supplies
5
+ * them; hosts embedding a single widget provide the same shape.
6
+ */
7
+ export interface FieldProps {
8
+ column: ColumnSchema;
9
+ modelValue?: unknown;
10
+ issues?: ValidationIssue[];
11
+ disabled?: boolean;
12
+ /**
13
+ * Pre-resolved picklist options (trigger/filter logic applied by the
14
+ * caller); fields fall back to column.generated_list_elements.
15
+ */
16
+ options?: FormListElement[];
17
+ /** Language for widget-generated text ('en' default, 'hu' built in). */
18
+ language?: string;
19
+ }
20
+ export type FieldEmits = {
21
+ 'update:modelValue': [value: unknown];
22
+ };
@@ -0,0 +1,3 @@
1
+ /** Small catalog for UI strings the widgets themselves render. */
2
+ export type UiTextKey = 'saveDraft' | 'finalize' | 'required' | 'unsupportedField' | 'unsupportedFieldType' | 'validationSummaryTitle' | 'warningsTitle' | 'noticesTitle' | 'addItem' | 'removeItem' | 'invalidWkt' | 'noOptions';
3
+ export declare function uiText(key: UiTextKey, language?: string, params?: Record<string, unknown>): string;