@narrative.io/jsonforms-provider-protocols 2.11.0 → 2.12.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.
- package/README.md +193 -33
- package/dist/core/initFormData.d.ts +17 -0
- package/dist/core/initFormData.d.ts.map +1 -0
- package/dist/core/initFormData.js +99 -0
- package/dist/core/initFormData.js.map +1 -0
- package/dist/core/projection.d.ts +36 -0
- package/dist/core/projection.d.ts.map +1 -0
- package/dist/core/projection.js +77 -0
- package/dist/core/projection.js.map +1 -0
- package/dist/core/refs.d.ts +58 -0
- package/dist/core/refs.d.ts.map +1 -0
- package/dist/core/refs.js +70 -0
- package/dist/core/refs.js.map +1 -0
- package/dist/core/resolveScope.d.ts +17 -0
- package/dist/core/resolveScope.d.ts.map +1 -0
- package/dist/core/resolveScope.js +28 -0
- package/dist/core/resolveScope.js.map +1 -0
- package/dist/core/seedProjectionTargets.d.ts +60 -0
- package/dist/core/seedProjectionTargets.d.ts.map +1 -0
- package/dist/core/seedProjectionTargets.js +52 -0
- package/dist/core/seedProjectionTargets.js.map +1 -0
- package/dist/core/transforms.d.ts +8 -10
- package/dist/core/transforms.d.ts.map +1 -1
- package/dist/core/transforms.js +58 -13
- package/dist/core/transforms.js.map +1 -1
- package/dist/core/types.d.ts +8 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/index.d.ts +9 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +21 -3
- package/dist/index.js.map +1 -1
- package/dist/jsonforms-provider-protocols.css +6 -2
- package/dist/no-eval-ajv.d.ts +70 -0
- package/dist/no-eval-ajv.d.ts.map +1 -0
- package/dist/no-eval-ajv.js +247 -0
- package/dist/no-eval-ajv.js.map +1 -0
- package/dist/vue/components/ProviderAutocomplete.vue.d.ts.map +1 -1
- package/dist/vue/components/ProviderAutocomplete.vue.js +12 -6
- package/dist/vue/components/ProviderAutocomplete.vue.js.map +1 -1
- package/dist/vue/components/ProviderMultiSelect.vue.d.ts.map +1 -1
- package/dist/vue/components/ProviderMultiSelect.vue.js +1 -1
- package/dist/vue/components/ProviderMultiSelect.vue2.js +21 -11
- package/dist/vue/components/ProviderMultiSelect.vue2.js.map +1 -1
- package/dist/vue/components/ProviderObjectMultiSelect.vue.d.ts +9 -0
- package/dist/vue/components/ProviderObjectMultiSelect.vue.d.ts.map +1 -0
- package/dist/vue/components/ProviderObjectMultiSelect.vue.js +8 -0
- package/dist/vue/components/ProviderObjectMultiSelect.vue.js.map +1 -0
- package/dist/vue/components/ProviderObjectMultiSelect.vue2.js +142 -0
- package/dist/vue/components/ProviderObjectMultiSelect.vue2.js.map +1 -0
- package/dist/vue/components/ProviderSelect.vue.d.ts.map +1 -1
- package/dist/vue/components/ProviderSelect.vue.js +1 -1
- package/dist/vue/components/ProviderSelect.vue2.js +22 -10
- package/dist/vue/components/ProviderSelect.vue2.js.map +1 -1
- package/dist/vue/composables/useDataLayer.d.ts +10 -0
- package/dist/vue/composables/useDataLayer.d.ts.map +1 -0
- package/dist/vue/composables/useDataLayer.js +26 -0
- package/dist/vue/composables/useDataLayer.js.map +1 -0
- package/dist/vue/composables/useDerive.d.ts +5 -2
- package/dist/vue/composables/useDerive.d.ts.map +1 -1
- package/dist/vue/composables/useDerive.js +29 -12
- package/dist/vue/composables/useDerive.js.map +1 -1
- package/dist/vue/composables/useDeriveInitialValue.d.ts +36 -0
- package/dist/vue/composables/useDeriveInitialValue.d.ts.map +1 -0
- package/dist/vue/composables/useDeriveInitialValue.js +125 -0
- package/dist/vue/composables/useDeriveInitialValue.js.map +1 -0
- package/dist/vue/composables/useDirtyValidation.d.ts +9 -0
- package/dist/vue/composables/useDirtyValidation.d.ts.map +1 -0
- package/dist/vue/composables/useDirtyValidation.js +15 -0
- package/dist/vue/composables/useDirtyValidation.js.map +1 -0
- package/dist/vue/composables/useProjection.d.ts +42 -0
- package/dist/vue/composables/useProjection.d.ts.map +1 -0
- package/dist/vue/composables/useProjection.js +116 -0
- package/dist/vue/composables/useProjection.js.map +1 -0
- package/dist/vue/composables/useProvider.d.ts +2 -2
- package/dist/vue/composables/useProvider.d.ts.map +1 -1
- package/dist/vue/composables/useProvider.js +14 -10
- package/dist/vue/composables/useProvider.js.map +1 -1
- package/dist/vue/index.d.ts +9 -1
- package/dist/vue/index.d.ts.map +1 -1
- package/dist/vue/index.js +72 -34
- package/dist/vue/index.js.map +1 -1
- package/dist/vue/primevue/JfBoolean.vue.d.ts +9 -0
- package/dist/vue/primevue/JfBoolean.vue.d.ts.map +1 -1
- package/dist/vue/primevue/JfBoolean.vue.js +44 -17
- package/dist/vue/primevue/JfBoolean.vue.js.map +1 -1
- package/dist/vue/primevue/JfEnum.vue.d.ts +9 -0
- package/dist/vue/primevue/JfEnum.vue.d.ts.map +1 -1
- package/dist/vue/primevue/JfEnum.vue.js +38 -24
- package/dist/vue/primevue/JfEnum.vue.js.map +1 -1
- package/dist/vue/primevue/JfEnumArray.vue.d.ts +9 -0
- package/dist/vue/primevue/JfEnumArray.vue.d.ts.map +1 -1
- package/dist/vue/primevue/JfEnumArray.vue.js +40 -20
- package/dist/vue/primevue/JfEnumArray.vue.js.map +1 -1
- package/dist/vue/primevue/JfNumber.vue.d.ts +9 -0
- package/dist/vue/primevue/JfNumber.vue.d.ts.map +1 -1
- package/dist/vue/primevue/JfNumber.vue.js +33 -23
- package/dist/vue/primevue/JfNumber.vue.js.map +1 -1
- package/dist/vue/primevue/JfText.vue.d.ts +9 -0
- package/dist/vue/primevue/JfText.vue.d.ts.map +1 -1
- package/dist/vue/primevue/JfText.vue.js +51 -35
- package/dist/vue/primevue/JfText.vue.js.map +1 -1
- package/dist/vue/primevue/JfTextArea.vue.d.ts +9 -0
- package/dist/vue/primevue/JfTextArea.vue.d.ts.map +1 -1
- package/dist/vue/primevue/JfTextArea.vue.js +34 -19
- package/dist/vue/primevue/JfTextArea.vue.js.map +1 -1
- package/dist/vue/primevue/index.d.ts.map +1 -1
- package/dist/vue/primevue/index.js +100 -8
- package/dist/vue/primevue/index.js.map +1 -1
- package/dist/vue/utils/objectMultiSelect.d.ts +68 -0
- package/dist/vue/utils/objectMultiSelect.d.ts.map +1 -0
- package/dist/vue/utils/objectMultiSelect.js +72 -0
- package/dist/vue/utils/objectMultiSelect.js.map +1 -0
- package/dist/vue/utils/placeholder.d.ts +17 -0
- package/dist/vue/utils/placeholder.d.ts.map +1 -0
- package/dist/vue/utils/placeholder.js +17 -0
- package/dist/vue/utils/placeholder.js.map +1 -0
- package/package.json +10 -2
- package/src/core/initFormData.ts +208 -0
- package/src/core/projection.ts +147 -0
- package/src/core/refs.ts +166 -0
- package/src/core/resolveScope.ts +54 -0
- package/src/core/seedProjectionTargets.ts +144 -0
- package/src/core/transforms.ts +118 -26
- package/src/core/types.ts +9 -0
- package/src/index.ts +22 -2
- package/src/no-eval-ajv.ts +381 -0
- package/src/vue/components/ProviderAutocomplete.vue +11 -7
- package/src/vue/components/ProviderMultiSelect.vue +22 -15
- package/src/vue/components/ProviderObjectMultiSelect.vue +169 -0
- package/src/vue/components/ProviderSelect.vue +23 -14
- package/src/vue/composables/useDataLayer.ts +43 -0
- package/src/vue/composables/useDerive.ts +62 -16
- package/src/vue/composables/useDeriveInitialValue.ts +195 -0
- package/src/vue/composables/useDirtyValidation.ts +20 -0
- package/src/vue/composables/useProjection.ts +245 -0
- package/src/vue/composables/useProvider.ts +28 -11
- package/src/vue/index.ts +83 -47
- package/src/vue/primevue/JfBoolean.vue +35 -12
- package/src/vue/primevue/JfEnum.vue +35 -26
- package/src/vue/primevue/JfEnumArray.vue +37 -20
- package/src/vue/primevue/JfNumber.vue +32 -24
- package/src/vue/primevue/JfText.vue +48 -33
- package/src/vue/primevue/JfTextArea.vue +32 -21
- package/src/vue/primevue/index.ts +114 -8
- package/src/vue/styles.css +26 -1
- package/src/vue/utils/objectMultiSelect.ts +171 -0
- package/src/vue/utils/placeholder.ts +42 -0
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { defineComponent, inject, computed, watch, createElementBlock, openBlock, createCommentVNode, createVNode, unref, toDisplayString } from "vue";
|
|
2
|
+
import { useJsonFormsControl } from "@jsonforms/vue";
|
|
3
|
+
import { useProvider } from "../composables/useProvider.js";
|
|
4
|
+
import { useProjection } from "../composables/useProjection.js";
|
|
5
|
+
import { resolvePlaceholder } from "../utils/placeholder.js";
|
|
6
|
+
import { resolveItemsSchema, resolveObjectKeys, fromMultiSelectShape, sameObjectSet, toMultiSelectShape } from "../utils/objectMultiSelect.js";
|
|
7
|
+
import MultiSelect from "primevue/multiselect";
|
|
8
|
+
const _hoisted_1 = { class: "jf-control" };
|
|
9
|
+
const _hoisted_2 = {
|
|
10
|
+
key: 0,
|
|
11
|
+
class: "jf-label"
|
|
12
|
+
};
|
|
13
|
+
const _hoisted_3 = {
|
|
14
|
+
key: 1,
|
|
15
|
+
class: "jf-description"
|
|
16
|
+
};
|
|
17
|
+
const _hoisted_4 = {
|
|
18
|
+
key: 2,
|
|
19
|
+
class: "p-error",
|
|
20
|
+
role: "alert"
|
|
21
|
+
};
|
|
22
|
+
const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
23
|
+
__name: "ProviderObjectMultiSelect",
|
|
24
|
+
props: {
|
|
25
|
+
uischema: {},
|
|
26
|
+
schema: {},
|
|
27
|
+
path: {}
|
|
28
|
+
},
|
|
29
|
+
setup(__props) {
|
|
30
|
+
const props = __props;
|
|
31
|
+
const { control, handleChange: rawHandleChange } = useJsonFormsControl(props);
|
|
32
|
+
const {
|
|
33
|
+
projectedData,
|
|
34
|
+
projectedLabel,
|
|
35
|
+
handleProjectedChange: handleChange
|
|
36
|
+
} = useProjection(control, rawHandleChange);
|
|
37
|
+
const jsonforms = inject("jsonforms", null);
|
|
38
|
+
const rootSchema = computed(
|
|
39
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
40
|
+
() => jsonforms?.core?.schema ?? control.value.schema
|
|
41
|
+
);
|
|
42
|
+
const itemsSchema = computed(
|
|
43
|
+
() => resolveItemsSchema(
|
|
44
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
45
|
+
control.value.schema,
|
|
46
|
+
rootSchema.value
|
|
47
|
+
)
|
|
48
|
+
);
|
|
49
|
+
const objectKeys = computed(() => {
|
|
50
|
+
const resolved = resolveObjectKeys(
|
|
51
|
+
control.value.uischema?.options,
|
|
52
|
+
itemsSchema.value
|
|
53
|
+
);
|
|
54
|
+
if (!resolved) {
|
|
55
|
+
throw new Error(
|
|
56
|
+
"[ProviderObjectMultiSelect] objectKeys could not be resolved. Specify `uischema.options.objectKeys = { value, label }` or declare exactly two `required` properties on the array's items schema so they can be inferred."
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
return resolved;
|
|
60
|
+
});
|
|
61
|
+
const binding = computed(() => {
|
|
62
|
+
const provider = control.value.uischema?.options?.provider;
|
|
63
|
+
if (provider && typeof provider === "object" && !provider.load) {
|
|
64
|
+
return { ...provider, load: "mount" };
|
|
65
|
+
}
|
|
66
|
+
return provider;
|
|
67
|
+
});
|
|
68
|
+
const deps = computed(
|
|
69
|
+
() => control.value.schema?.["x-provider"]?.dependsOn ?? []
|
|
70
|
+
);
|
|
71
|
+
const depValues = computed(() => deps.value.map(() => null));
|
|
72
|
+
const injectedFormData = inject("formData", { value: {} });
|
|
73
|
+
const rootData = computed(() => injectedFormData.value || {});
|
|
74
|
+
const { items, loading, error } = useProvider(binding, {
|
|
75
|
+
data: rootData,
|
|
76
|
+
path: control.value.path,
|
|
77
|
+
dependsOnValues: depValues
|
|
78
|
+
});
|
|
79
|
+
watch(
|
|
80
|
+
[items, loading],
|
|
81
|
+
([newItems, isLoading]) => {
|
|
82
|
+
if (!control.value.uischema?.options?.autoSelectSingle || isLoading || newItems.length !== 1) {
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
const single = newItems[0];
|
|
86
|
+
const current = Array.isArray(projectedData.value) ? projectedData.value : [];
|
|
87
|
+
if (current.length === 0) {
|
|
88
|
+
handleChange(control.value.path, [
|
|
89
|
+
{
|
|
90
|
+
[objectKeys.value.value]: single.value,
|
|
91
|
+
[objectKeys.value.label]: single.label
|
|
92
|
+
}
|
|
93
|
+
]);
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
{ immediate: true }
|
|
97
|
+
);
|
|
98
|
+
const value = computed({
|
|
99
|
+
get() {
|
|
100
|
+
return toMultiSelectShape(projectedData.value, objectKeys.value);
|
|
101
|
+
},
|
|
102
|
+
set(val) {
|
|
103
|
+
const next = fromMultiSelectShape(val, objectKeys.value);
|
|
104
|
+
const curr = Array.isArray(projectedData.value) ? projectedData.value : [];
|
|
105
|
+
if (!sameObjectSet(curr, next, objectKeys.value.value)) {
|
|
106
|
+
handleChange(control.value.path, next);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
const placeholder = computed(() => {
|
|
111
|
+
if (loading.value) return "Loading…";
|
|
112
|
+
return resolvePlaceholder(
|
|
113
|
+
control.value.uischema,
|
|
114
|
+
projectedLabel.value,
|
|
115
|
+
"select"
|
|
116
|
+
);
|
|
117
|
+
});
|
|
118
|
+
return (_ctx, _cache) => {
|
|
119
|
+
return openBlock(), createElementBlock("div", _hoisted_1, [
|
|
120
|
+
unref(projectedLabel) ? (openBlock(), createElementBlock("label", _hoisted_2, toDisplayString(unref(projectedLabel)), 1)) : createCommentVNode("", true),
|
|
121
|
+
unref(control).description ? (openBlock(), createElementBlock("div", _hoisted_3, toDisplayString(unref(control).description), 1)) : createCommentVNode("", true),
|
|
122
|
+
createVNode(unref(MultiSelect), {
|
|
123
|
+
modelValue: value.value,
|
|
124
|
+
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => value.value = $event),
|
|
125
|
+
class: "w-full!",
|
|
126
|
+
options: unref(items),
|
|
127
|
+
"option-label": "label",
|
|
128
|
+
"data-key": "value",
|
|
129
|
+
display: "chip",
|
|
130
|
+
placeholder: placeholder.value,
|
|
131
|
+
disabled: !unref(control).enabled || unref(loading),
|
|
132
|
+
"show-clear": true
|
|
133
|
+
}, null, 8, ["modelValue", "options", "placeholder", "disabled"]),
|
|
134
|
+
unref(error) ? (openBlock(), createElementBlock("small", _hoisted_4, "Failed to load: " + toDisplayString(unref(error)), 1)) : createCommentVNode("", true)
|
|
135
|
+
]);
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
export {
|
|
140
|
+
_sfc_main as default
|
|
141
|
+
};
|
|
142
|
+
//# sourceMappingURL=ProviderObjectMultiSelect.vue2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProviderObjectMultiSelect.vue2.js","sources":["../../../src/vue/components/ProviderObjectMultiSelect.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { ControlElement, JsonSchema } from \"@jsonforms/core\";\nimport { useJsonFormsControl } from \"@jsonforms/vue\";\nimport { computed, inject, watch } from \"vue\";\nimport { useProvider } from \"../composables/useProvider\";\nimport { useProjection } from \"../composables/useProjection\";\nimport { resolvePlaceholder } from \"../utils/placeholder\";\nimport {\n fromMultiSelectShape,\n resolveItemsSchema,\n resolveObjectKeys,\n sameObjectSet,\n toMultiSelectShape,\n type MultiSelectOption,\n type ObjectKeys,\n} from \"../utils/objectMultiSelect\";\nimport MultiSelect from \"primevue/multiselect\";\n\nconst props = defineProps<{\n uischema: ControlElement;\n schema: JsonSchema;\n path: string;\n}>();\nconst { control, handleChange: rawHandleChange } = useJsonFormsControl(props);\nconst {\n projectedData,\n projectedLabel,\n handleProjectedChange: handleChange,\n} = useProjection(control, rawHandleChange);\n\n// Pull root schema so item-schema $refs resolve against the consumer's $defs.\nconst jsonforms = inject<{\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n core?: { schema?: Record<string, any> };\n} | null>(\"jsonforms\", null);\nconst rootSchema = computed(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n () => (jsonforms?.core?.schema ?? control.value.schema) as Record<string, any>,\n);\n\nconst itemsSchema = computed(() =>\n resolveItemsSchema(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n control.value.schema as Record<string, any>,\n rootSchema.value,\n ),\n);\n\nconst objectKeys = computed<ObjectKeys>(() => {\n const resolved = resolveObjectKeys(\n control.value.uischema?.options as\n | { objectKeys?: { value?: unknown; label?: unknown } }\n | undefined,\n itemsSchema.value,\n );\n if (!resolved) {\n throw new Error(\n \"[ProviderObjectMultiSelect] objectKeys could not be resolved. \" +\n \"Specify `uischema.options.objectKeys = { value, label }` or declare \" +\n \"exactly two `required` properties on the array's items schema so \" +\n \"they can be inferred.\",\n );\n }\n return resolved;\n});\n\nconst binding = computed(() => {\n const provider = control.value.uischema?.options?.provider;\n if (provider && typeof provider === \"object\" && !provider.load) {\n return { ...provider, load: \"mount\" };\n }\n return provider;\n});\n\nconst deps = computed(\n () =>\n ((\n (control.value.schema as Record<string, unknown>)?.[\n \"x-provider\"\n ] as Record<string, unknown>\n )?.dependsOn as string[]) ?? [],\n);\nconst depValues = computed(() => deps.value.map(() => null));\n\nconst injectedFormData = inject<{ value: unknown }>(\"formData\", { value: {} });\nconst rootData = computed(() => injectedFormData.value || {});\n\nconst { items, loading, error } = useProvider(binding, {\n data: rootData,\n path: control.value.path,\n dependsOnValues: depValues,\n});\n\n// Auto-select when provider returns only one item — paired-object variant.\nwatch(\n [items, loading],\n ([newItems, isLoading]) => {\n if (\n !control.value.uischema?.options?.autoSelectSingle ||\n isLoading ||\n newItems.length !== 1\n ) {\n return;\n }\n const single = newItems[0]!;\n const current = Array.isArray(projectedData.value) ? projectedData.value : [];\n if (current.length === 0) {\n handleChange(control.value.path, [\n {\n [objectKeys.value.value]: single.value,\n [objectKeys.value.label]: single.label,\n },\n ]);\n }\n },\n { immediate: true },\n);\n\nconst value = computed<MultiSelectOption[]>({\n get() {\n return toMultiSelectShape(projectedData.value, objectKeys.value);\n },\n set(val) {\n const next = fromMultiSelectShape(val, objectKeys.value);\n const curr = Array.isArray(projectedData.value) ? projectedData.value : [];\n if (!sameObjectSet(curr, next, objectKeys.value.value)) {\n handleChange(control.value.path, next);\n }\n },\n});\n\nconst placeholder = computed(() => {\n if (loading.value) return \"Loading…\";\n return resolvePlaceholder(\n control.value.uischema,\n projectedLabel.value,\n \"select\",\n );\n});\n</script>\n\n<template>\n <div class=\"jf-control\">\n <label v-if=\"projectedLabel\" class=\"jf-label\">{{ projectedLabel }}</label>\n <div v-if=\"control.description\" class=\"jf-description\">\n {{ control.description }}\n </div>\n <MultiSelect\n v-model=\"value\"\n class=\"w-full!\"\n :options=\"items\"\n option-label=\"label\"\n data-key=\"value\"\n display=\"chip\"\n :placeholder=\"placeholder\"\n :disabled=\"!control.enabled || loading\"\n :show-clear=\"true\"\n />\n <small v-if=\"error\" class=\"p-error\" role=\"alert\"\n >Failed to load: {{ error }}</small\n >\n </div>\n</template>\n\n<style scoped>\n:deep(.p-multiselect-label) {\n text-align: left;\n}\n</style>\n"],"names":["_openBlock","_createElementBlock","_unref","_toDisplayString","_createVNode"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProviderSelect.vue.d.ts","sourceRoot":"","sources":["../../../src/vue/components/ProviderSelect.vue"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ProviderSelect.vue.d.ts","sourceRoot":"","sources":["../../../src/vue/components/ProviderSelect.vue"],"names":[],"mappings":"AAwHA,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAUlE,KAAK,WAAW,GAAG;IACjB,QAAQ,EAAE,cAAc,CAAC;IACzB,MAAM,EAAE,UAAU,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;;AAmLF,wBAEG"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import _sfc_main from "./ProviderSelect.vue2.js";
|
|
2
2
|
/* empty css */
|
|
3
3
|
import _export_sfc from "../../_virtual/_plugin-vue_export-helper.js";
|
|
4
|
-
const ProviderSelect = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-
|
|
4
|
+
const ProviderSelect = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-cbb98bc4"]]);
|
|
5
5
|
export {
|
|
6
6
|
ProviderSelect as default
|
|
7
7
|
};
|
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
import { defineComponent, computed, inject, watch, createElementBlock, openBlock, createCommentVNode, createVNode, unref, toDisplayString } from "vue";
|
|
2
2
|
import { useJsonFormsControl } from "@jsonforms/vue";
|
|
3
3
|
import { useProvider } from "../composables/useProvider.js";
|
|
4
|
+
import { useDeriveInitialValue } from "../composables/useDeriveInitialValue.js";
|
|
5
|
+
import { useProjection } from "../composables/useProjection.js";
|
|
4
6
|
import { shouldAutoSelect } from "../utils/autoSelect.js";
|
|
7
|
+
import { resolvePlaceholder } from "../utils/placeholder.js";
|
|
5
8
|
import Dropdown from "primevue/dropdown";
|
|
6
|
-
const _hoisted_1 = { class: "
|
|
9
|
+
const _hoisted_1 = { class: "jf-control" };
|
|
7
10
|
const _hoisted_2 = {
|
|
8
11
|
key: 0,
|
|
9
|
-
class: "
|
|
12
|
+
class: "jf-label"
|
|
10
13
|
};
|
|
11
14
|
const _hoisted_3 = {
|
|
12
15
|
key: 1,
|
|
13
|
-
class: "
|
|
16
|
+
class: "jf-description"
|
|
14
17
|
};
|
|
15
18
|
const _hoisted_4 = {
|
|
16
19
|
key: 2,
|
|
@@ -26,7 +29,12 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
26
29
|
},
|
|
27
30
|
setup(__props) {
|
|
28
31
|
const props = __props;
|
|
29
|
-
const { control, handleChange } = useJsonFormsControl(props);
|
|
32
|
+
const { control, handleChange: rawHandleChange } = useJsonFormsControl(props);
|
|
33
|
+
const {
|
|
34
|
+
projectedData,
|
|
35
|
+
projectedLabel,
|
|
36
|
+
handleProjectedChange: handleChange
|
|
37
|
+
} = useProjection(control, rawHandleChange);
|
|
30
38
|
const binding = computed(() => {
|
|
31
39
|
const provider = control.value.uischema?.options?.provider;
|
|
32
40
|
if (provider && typeof provider === "object" && !provider.load) {
|
|
@@ -44,8 +52,9 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
44
52
|
data: rootData,
|
|
45
53
|
// Pass the reactive reference
|
|
46
54
|
path: control.value.path,
|
|
47
|
-
dependsOnValues: depValues
|
|
55
|
+
dependsOnValues: depValues
|
|
48
56
|
});
|
|
57
|
+
useDeriveInitialValue({ control, handleChange });
|
|
49
58
|
watch(
|
|
50
59
|
[items, loading],
|
|
51
60
|
([newItems, isLoading]) => {
|
|
@@ -53,7 +62,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
53
62
|
autoSelectSingle: control.value.uischema?.options?.autoSelectSingle !== false,
|
|
54
63
|
isLoading,
|
|
55
64
|
items: newItems,
|
|
56
|
-
currentValue:
|
|
65
|
+
currentValue: projectedData.value
|
|
57
66
|
});
|
|
58
67
|
if (valueToSelect !== null) {
|
|
59
68
|
handleChange(control.value.path, valueToSelect);
|
|
@@ -62,17 +71,20 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
62
71
|
{ immediate: true }
|
|
63
72
|
);
|
|
64
73
|
const value = computed({
|
|
65
|
-
get: () =>
|
|
74
|
+
get: () => projectedData.value,
|
|
66
75
|
set: (v) => handleChange(control.value.path, v)
|
|
67
76
|
});
|
|
68
77
|
const placeholder = computed(() => {
|
|
69
78
|
if (loading.value) return "Loading…";
|
|
70
|
-
|
|
71
|
-
|
|
79
|
+
return resolvePlaceholder(
|
|
80
|
+
control.value.uischema,
|
|
81
|
+
projectedLabel.value,
|
|
82
|
+
"select"
|
|
83
|
+
);
|
|
72
84
|
});
|
|
73
85
|
return (_ctx, _cache) => {
|
|
74
86
|
return openBlock(), createElementBlock("div", _hoisted_1, [
|
|
75
|
-
unref(
|
|
87
|
+
unref(projectedLabel) ? (openBlock(), createElementBlock("label", _hoisted_2, toDisplayString(unref(projectedLabel)), 1)) : createCommentVNode("", true),
|
|
76
88
|
unref(control).description ? (openBlock(), createElementBlock("div", _hoisted_3, toDisplayString(unref(control).description), 1)) : createCommentVNode("", true),
|
|
77
89
|
createVNode(unref(Dropdown), {
|
|
78
90
|
modelValue: value.value,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProviderSelect.vue2.js","sources":["../../../src/vue/components/ProviderSelect.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { ControlElement, JsonSchema } from \"@jsonforms/core\";\nimport { useJsonFormsControl } from \"@jsonforms/vue\";\nimport { computed, inject, watch } from \"vue\";\nimport { useProvider } from \"../composables/useProvider\";\nimport { shouldAutoSelect } from \"../utils/autoSelect\";\nimport Dropdown from \"primevue/dropdown\";\n\nconst props = defineProps<{\n uischema: ControlElement;\n schema: JsonSchema;\n path: string;\n}>();\nconst { control, handleChange } = useJsonFormsControl(props);\n\nconst binding = computed(() => {\n const provider = control.value.uischema?.options?.provider;\n // Ensure load property is set to 'mount' by default\n if (provider && typeof provider === \"object\" && !provider.load) {\n return { ...provider, load: \"mount\" };\n }\n return provider;\n});\n\nconst deps = computed(\n () =>\n ((\n (control.value.schema as Record<string, unknown>)?.[\n \"x-provider\"\n ] as Record<string, unknown>\n )?.dependsOn as string[]) ?? [],\n);\nconst depValues = computed(() => deps.value.map(() => null)); // you can resolve actual values via control.value.data & pointers\n\n// Get the root form data from JSONForms context for template URL resolution\nconst injectedFormData = inject<{ value: unknown }>(\"formData\", { value: {} });\nconst rootData = computed(() => injectedFormData.value || {});\n\nconst { items, loading, error } = useProvider(binding, {\n data: rootData, // Pass the reactive reference\n path: control.value.path,\n dependsOnValues: depValues
|
|
1
|
+
{"version":3,"file":"ProviderSelect.vue2.js","sources":["../../../src/vue/components/ProviderSelect.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { ControlElement, JsonSchema } from \"@jsonforms/core\";\nimport { useJsonFormsControl } from \"@jsonforms/vue\";\nimport { computed, inject, watch } from \"vue\";\nimport { useProvider } from \"../composables/useProvider\";\nimport { useDeriveInitialValue } from \"../composables/useDeriveInitialValue\";\nimport { useProjection } from \"../composables/useProjection\";\nimport { shouldAutoSelect } from \"../utils/autoSelect\";\nimport { resolvePlaceholder } from \"../utils/placeholder\";\nimport Dropdown from \"primevue/dropdown\";\n\nconst props = defineProps<{\n uischema: ControlElement;\n schema: JsonSchema;\n path: string;\n}>();\nconst { control, handleChange: rawHandleChange } = useJsonFormsControl(props);\nconst {\n projectedData,\n projectedLabel,\n handleProjectedChange: handleChange,\n} = useProjection(control, rawHandleChange);\n\nconst binding = computed(() => {\n const provider = control.value.uischema?.options?.provider;\n // Ensure load property is set to 'mount' by default\n if (provider && typeof provider === \"object\" && !provider.load) {\n return { ...provider, load: \"mount\" };\n }\n return provider;\n});\n\nconst deps = computed(\n () =>\n ((\n (control.value.schema as Record<string, unknown>)?.[\n \"x-provider\"\n ] as Record<string, unknown>\n )?.dependsOn as string[]) ?? [],\n);\nconst depValues = computed(() => deps.value.map(() => null)); // you can resolve actual values via control.value.data & pointers\n\n// Get the root form data from JSONForms context for template URL resolution\nconst injectedFormData = inject<{ value: unknown }>(\"formData\", { value: {} });\nconst rootData = computed(() => injectedFormData.value || {});\n\nconst { items, loading, error } = useProvider(binding, {\n data: rootData, // Pass the reactive reference\n path: control.value.path,\n dependsOnValues: depValues,\n});\n\n// Provider will automatically reload when rootData changes due to reactive cache key\n\n// deriveInitialValue — async API-based initial value seeding\nuseDeriveInitialValue({ control, handleChange });\n\n// Auto-select when provider returns only one item (enabled by default)\nwatch(\n [items, loading],\n ([newItems, isLoading]) => {\n const valueToSelect = shouldAutoSelect({\n autoSelectSingle:\n control.value.uischema?.options?.autoSelectSingle !== false,\n isLoading,\n items: newItems,\n currentValue: projectedData.value,\n });\n\n if (valueToSelect !== null) {\n handleChange(control.value.path, valueToSelect);\n }\n },\n { immediate: true },\n);\n\nconst value = computed({\n get: () => projectedData.value,\n set: (v) => handleChange(control.value.path, v),\n});\n\nconst placeholder = computed(() => {\n if (loading.value) return \"Loading…\";\n return resolvePlaceholder(\n control.value.uischema,\n projectedLabel.value,\n \"select\",\n );\n});\n</script>\n\n<template>\n <div class=\"jf-control\">\n <label v-if=\"projectedLabel\" class=\"jf-label\">{{ projectedLabel }}</label>\n <div v-if=\"control.description\" class=\"jf-description\">\n {{ control.description }}\n </div>\n <Dropdown\n v-model=\"value\"\n class=\"w-full!\"\n :options=\"items\"\n option-label=\"label\"\n option-value=\"value\"\n :placeholder=\"placeholder\"\n :disabled=\"!control.enabled || loading\"\n :show-clear=\"true\"\n />\n <small v-if=\"error\" class=\"p-error\" role=\"alert\"\n >Failed to load: {{ error }}</small\n >\n </div>\n</template>\n\n<style scoped>\n:deep(.p-dropdown-label) {\n text-align: left;\n}\n</style>\n"],"names":["_openBlock","_createElementBlock","_unref","_toDisplayString","_createVNode"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAWA,UAAM,QAAQ;AAKd,UAAM,EAAE,SAAS,cAAc,gBAAA,IAAoB,oBAAoB,KAAK;AAC5E,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA,uBAAuB;AAAA,IAAA,IACrB,cAAc,SAAS,eAAe;AAE1C,UAAM,UAAU,SAAS,MAAM;AAC7B,YAAM,WAAW,QAAQ,MAAM,UAAU,SAAS;AAElD,UAAI,YAAY,OAAO,aAAa,YAAY,CAAC,SAAS,MAAM;AAC9D,eAAO,EAAE,GAAG,UAAU,MAAM,QAAA;AAAA,MAC9B;AACA,aAAO;AAAA,IACT,CAAC;AAED,UAAM,OAAO;AAAA,MACX,MAEK,QAAQ,MAAM,SACb,YACF,GACC,aAA0B,CAAA;AAAA,IAAC;AAElC,UAAM,YAAY,SAAS,MAAM,KAAK,MAAM,IAAI,MAAM,IAAI,CAAC;AAG3D,UAAM,mBAAmB,OAA2B,YAAY,EAAE,OAAO,CAAA,GAAI;AAC7E,UAAM,WAAW,SAAS,MAAM,iBAAiB,SAAS,CAAA,CAAE;AAE5D,UAAM,EAAE,OAAO,SAAS,MAAA,IAAU,YAAY,SAAS;AAAA,MACrD,MAAM;AAAA;AAAA,MACN,MAAM,QAAQ,MAAM;AAAA,MACpB,iBAAiB;AAAA,IAAA,CAClB;AAKD,0BAAsB,EAAE,SAAS,cAAc;AAG/C;AAAA,MACE,CAAC,OAAO,OAAO;AAAA,MACf,CAAC,CAAC,UAAU,SAAS,MAAM;AACzB,cAAM,gBAAgB,iBAAiB;AAAA,UACrC,kBACE,QAAQ,MAAM,UAAU,SAAS,qBAAqB;AAAA,UACxD;AAAA,UACA,OAAO;AAAA,UACP,cAAc,cAAc;AAAA,QAAA,CAC7B;AAED,YAAI,kBAAkB,MAAM;AAC1B,uBAAa,QAAQ,MAAM,MAAM,aAAa;AAAA,QAChD;AAAA,MACF;AAAA,MACA,EAAE,WAAW,KAAA;AAAA,IAAK;AAGpB,UAAM,QAAQ,SAAS;AAAA,MACrB,KAAK,MAAM,cAAc;AAAA,MACzB,KAAK,CAAC,MAAM,aAAa,QAAQ,MAAM,MAAM,CAAC;AAAA,IAAA,CAC/C;AAED,UAAM,cAAc,SAAS,MAAM;AACjC,UAAI,QAAQ,MAAO,QAAO;AAC1B,aAAO;AAAA,QACL,QAAQ,MAAM;AAAA,QACd,eAAe;AAAA,QACf;AAAA,MAAA;AAAA,IAEJ,CAAC;;AAIC,aAAAA,UAAA,GAAAC,mBAkBM,OAlBN,YAkBM;AAAA,QAjBSC,MAAA,cAAA,kBAAbD,mBAA0E,SAA1E,YAA0EE,gBAAzBD,MAAA,cAAA,CAAc,GAAA,CAAA;QACpDA,MAAA,OAAA,EAAQ,eAAnBF,UAAA,GAAAC,mBAEM,OAFN,YAEME,gBADDD,MAAA,OAAA,EAAQ,WAAW,GAAA,CAAA;QAExBE,YASEF,MAAA,QAAA,GAAA;AAAA,sBARS,MAAA;AAAA,uEAAA,MAAK,QAAA;AAAA,UACd,OAAM;AAAA,UACL,SAASA,MAAA,KAAA;AAAA,UACV,gBAAa;AAAA,UACb,gBAAa;AAAA,UACZ,aAAa,YAAA;AAAA,UACb,UAAQ,CAAGA,MAAA,OAAA,EAAQ,WAAWA,MAAA,OAAA;AAAA,UAC9B,cAAY;AAAA,QAAA;QAEFA,MAAA,KAAA,KAAbF,aAAAC,mBAEC,SAFD,YACG,qCAAmBC,MAAA,KAAA,CAAK,GAAA,CAAA;;;;;"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type DeepReadonly, type Ref } from "vue";
|
|
2
|
+
import type { ConnectorDataLayer } from "../../core/types";
|
|
3
|
+
export declare const DATA_LAYER_KEY: unique symbol;
|
|
4
|
+
export interface DataLayer {
|
|
5
|
+
push(data: Partial<ConnectorDataLayer>): void;
|
|
6
|
+
state: DeepReadonly<Ref<ConnectorDataLayer>>;
|
|
7
|
+
}
|
|
8
|
+
export declare function createDataLayer(): DataLayer;
|
|
9
|
+
export declare function useDataLayer(): DeepReadonly<Ref<ConnectorDataLayer>>;
|
|
10
|
+
//# sourceMappingURL=useDataLayer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useDataLayer.d.ts","sourceRoot":"","sources":["../../../src/vue/composables/useDataLayer.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,YAAY,EACjB,KAAK,GAAG,EACT,MAAM,KAAK,CAAC;AACb,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAE3D,eAAO,MAAM,cAAc,eAAsB,CAAC;AAElD,MAAM,WAAW,SAAS;IACxB,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,kBAAkB,CAAC,GAAG,IAAI,CAAC;IAC9C,KAAK,EAAE,YAAY,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC,CAAC;CAC9C;AAED,wBAAgB,eAAe,IAAI,SAAS,CAa3C;AAED,wBAAgB,YAAY,IAAI,YAAY,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC,CAUpE"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { ref, readonly, provide, inject } from "vue";
|
|
2
|
+
const DATA_LAYER_KEY = Symbol("dataLayer");
|
|
3
|
+
function createDataLayer() {
|
|
4
|
+
const state = ref({});
|
|
5
|
+
const dataLayer = {
|
|
6
|
+
push(data) {
|
|
7
|
+
state.value = { ...state.value, ...data };
|
|
8
|
+
},
|
|
9
|
+
state: readonly(state)
|
|
10
|
+
};
|
|
11
|
+
provide(DATA_LAYER_KEY, dataLayer);
|
|
12
|
+
return dataLayer;
|
|
13
|
+
}
|
|
14
|
+
function useDataLayer() {
|
|
15
|
+
const dataLayer = inject(DATA_LAYER_KEY, null);
|
|
16
|
+
if (dataLayer) {
|
|
17
|
+
return dataLayer.state;
|
|
18
|
+
}
|
|
19
|
+
return readonly(ref({}));
|
|
20
|
+
}
|
|
21
|
+
export {
|
|
22
|
+
DATA_LAYER_KEY,
|
|
23
|
+
createDataLayer,
|
|
24
|
+
useDataLayer
|
|
25
|
+
};
|
|
26
|
+
//# sourceMappingURL=useDataLayer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useDataLayer.js","sources":["../../../src/vue/composables/useDataLayer.ts"],"sourcesContent":["import {\n ref,\n provide,\n inject,\n readonly,\n type DeepReadonly,\n type Ref,\n} from \"vue\";\nimport type { ConnectorDataLayer } from \"../../core/types\";\n\nexport const DATA_LAYER_KEY = Symbol(\"dataLayer\");\n\nexport interface DataLayer {\n push(data: Partial<ConnectorDataLayer>): void;\n state: DeepReadonly<Ref<ConnectorDataLayer>>;\n}\n\nexport function createDataLayer(): DataLayer {\n const state = ref<ConnectorDataLayer>({});\n\n const dataLayer: DataLayer = {\n push(data: Partial<ConnectorDataLayer>) {\n state.value = { ...state.value, ...data };\n },\n state: readonly(state) as DeepReadonly<Ref<ConnectorDataLayer>>,\n };\n\n provide(DATA_LAYER_KEY, dataLayer);\n\n return dataLayer;\n}\n\nexport function useDataLayer(): DeepReadonly<Ref<ConnectorDataLayer>> {\n const dataLayer = inject<DataLayer | null>(DATA_LAYER_KEY, null);\n if (dataLayer) {\n return dataLayer.state;\n }\n\n // No dataLayer provided — return empty reactive ref\n return readonly(ref<ConnectorDataLayer>({})) as DeepReadonly<\n Ref<ConnectorDataLayer>\n >;\n}\n"],"names":[],"mappings":";AAUO,MAAM,iBAAiB,OAAO,WAAW;AAOzC,SAAS,kBAA6B;AAC3C,QAAM,QAAQ,IAAwB,EAAE;AAExC,QAAM,YAAuB;AAAA,IAC3B,KAAK,MAAmC;AACtC,YAAM,QAAQ,EAAE,GAAG,MAAM,OAAO,GAAG,KAAA;AAAA,IACrC;AAAA,IACA,OAAO,SAAS,KAAK;AAAA,EAAA;AAGvB,UAAQ,gBAAgB,SAAS;AAEjC,SAAO;AACT;AAEO,SAAS,eAAsD;AACpE,QAAM,YAAY,OAAyB,gBAAgB,IAAI;AAC/D,MAAI,WAAW;AACb,WAAO,UAAU;AAAA,EACnB;AAGA,SAAO,SAAS,IAAwB,CAAA,CAAE,CAAC;AAG7C;"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type Ref } from "vue";
|
|
1
|
+
import { type Ref, type ComputedRef } from "vue";
|
|
2
2
|
import { type ControlElement } from "@jsonforms/core";
|
|
3
3
|
interface DeriveOptions {
|
|
4
4
|
control: Ref<{
|
|
@@ -7,7 +7,10 @@ interface DeriveOptions {
|
|
|
7
7
|
data: unknown;
|
|
8
8
|
}>;
|
|
9
9
|
handleChange: (path: string, value: unknown) => void;
|
|
10
|
+
/** When projection is active, pass projectedData so the comparison
|
|
11
|
+
* matches the projected (unwrapped) value rather than raw scope data. */
|
|
12
|
+
data?: Ref<unknown> | ComputedRef<unknown>;
|
|
10
13
|
}
|
|
11
|
-
export declare function useDerive({ control, handleChange }: DeriveOptions): void;
|
|
14
|
+
export declare function useDerive({ control, handleChange, data: dataOverride, }: DeriveOptions): void;
|
|
12
15
|
export {};
|
|
13
16
|
//# sourceMappingURL=useDerive.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useDerive.d.ts","sourceRoot":"","sources":["../../../src/vue/composables/useDerive.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"useDerive.d.ts","sourceRoot":"","sources":["../../../src/vue/composables/useDerive.ts"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,GAAG,EACR,KAAK,WAAW,EACjB,MAAM,KAAK,CAAC;AACb,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGtD,UAAU,aAAa;IACrB,OAAO,EAAE,GAAG,CAAC;QACX,QAAQ,EAAE,cAAc,CAAC;QACzB,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,OAAO,CAAC;KACf,CAAC,CAAC;IACH,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACrD;8EAC0E;IAC1E,IAAI,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;CAC5C;AAED,wBAAgB,SAAS,CAAC,EACxB,OAAO,EACP,YAAY,EACZ,IAAI,EAAE,YAAY,GACnB,EAAE,aAAa,QAgFf"}
|
|
@@ -1,14 +1,17 @@
|
|
|
1
|
-
import { inject, computed, watch } from "vue";
|
|
1
|
+
import { inject, computed, ref, watch, unref } from "vue";
|
|
2
2
|
import "@jsonforms/core";
|
|
3
|
-
|
|
3
|
+
import { useDataLayer } from "./useDataLayer.js";
|
|
4
|
+
function useDerive({
|
|
5
|
+
control,
|
|
6
|
+
handleChange,
|
|
7
|
+
data: dataOverride
|
|
8
|
+
}) {
|
|
4
9
|
const injectedFormData = inject("formData", {
|
|
5
10
|
value: {}
|
|
6
11
|
});
|
|
7
12
|
const rootData = computed(() => injectedFormData.value || {});
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
});
|
|
11
|
-
const externalData = computed(() => injectedExternalData.value || {});
|
|
13
|
+
const dataLayerState = useDataLayer();
|
|
14
|
+
const dataLayerData = computed(() => dataLayerState.value || {});
|
|
12
15
|
const deriveConfig = computed(() => {
|
|
13
16
|
const options = control.value.uischema?.options;
|
|
14
17
|
return {
|
|
@@ -17,8 +20,10 @@ function useDerive({ control, handleChange }) {
|
|
|
17
20
|
// 'follow' = auto-update, 'manual' = user controlled
|
|
18
21
|
};
|
|
19
22
|
});
|
|
23
|
+
const lastDerivedValue = ref(void 0);
|
|
24
|
+
let isFirstRun = true;
|
|
20
25
|
watch(
|
|
21
|
-
[rootData,
|
|
26
|
+
[rootData, dataLayerData, deriveConfig],
|
|
22
27
|
([data, extData, config]) => {
|
|
23
28
|
if (!config.expression || config.mode !== "follow") {
|
|
24
29
|
return;
|
|
@@ -29,7 +34,19 @@ function useDerive({ control, handleChange }) {
|
|
|
29
34
|
data,
|
|
30
35
|
extData
|
|
31
36
|
);
|
|
32
|
-
|
|
37
|
+
const compareData = dataOverride ? unref(dataOverride) : control.value.data;
|
|
38
|
+
if (isFirstRun) {
|
|
39
|
+
isFirstRun = false;
|
|
40
|
+
lastDerivedValue.value = derivedValue;
|
|
41
|
+
const isFieldEmpty = compareData === void 0 || compareData === null || compareData === "";
|
|
42
|
+
if (isFieldEmpty && derivedValue !== compareData) {
|
|
43
|
+
handleChange(control.value.path, derivedValue);
|
|
44
|
+
}
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
if (derivedValue === lastDerivedValue.value) return;
|
|
48
|
+
lastDerivedValue.value = derivedValue;
|
|
49
|
+
if (derivedValue !== compareData) {
|
|
33
50
|
handleChange(control.value.path, derivedValue);
|
|
34
51
|
}
|
|
35
52
|
} catch (error) {
|
|
@@ -42,10 +59,10 @@ function useDerive({ control, handleChange }) {
|
|
|
42
59
|
{ deep: true, immediate: true }
|
|
43
60
|
);
|
|
44
61
|
}
|
|
45
|
-
function resolveDeriveExpression(expression, data,
|
|
46
|
-
if (expression.startsWith("
|
|
47
|
-
const propertyPath = expression.slice(
|
|
48
|
-
return resolvePropertyPath(propertyPath,
|
|
62
|
+
function resolveDeriveExpression(expression, data, dataLayerData) {
|
|
63
|
+
if (expression.startsWith("dataLayer(") && expression.endsWith(")")) {
|
|
64
|
+
const propertyPath = expression.slice(10, -1);
|
|
65
|
+
return resolvePropertyPath(propertyPath, dataLayerData);
|
|
49
66
|
}
|
|
50
67
|
if (!expression.includes("(") && !expression.includes("+") && !expression.includes("?")) {
|
|
51
68
|
return resolvePropertyPath(expression, data);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useDerive.js","sources":["../../../src/vue/composables/useDerive.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"useDerive.js","sources":["../../../src/vue/composables/useDerive.ts"],"sourcesContent":["import {\n computed,\n ref,\n watch,\n unref,\n inject,\n type Ref,\n type ComputedRef,\n} from \"vue\";\nimport { type ControlElement } from \"@jsonforms/core\";\nimport { useDataLayer } from \"./useDataLayer\";\n\ninterface DeriveOptions {\n control: Ref<{\n uischema: ControlElement;\n path: string;\n data: unknown;\n }>;\n handleChange: (path: string, value: unknown) => void;\n /** When projection is active, pass projectedData so the comparison\n * matches the projected (unwrapped) value rather than raw scope data. */\n data?: Ref<unknown> | ComputedRef<unknown>;\n}\n\nexport function useDerive({\n control,\n handleChange,\n data: dataOverride,\n}: DeriveOptions) {\n // Get the root form data from JSONForms context\n const injectedFormData = inject<{ value: unknown }>(\"formData\", {\n value: {},\n });\n const rootData = computed(() => injectedFormData.value || {});\n\n // Get data from the dataLayer\n const dataLayerState = useDataLayer();\n const dataLayerData = computed(() => dataLayerState.value || {});\n\n // Extract derive configuration from uischema options\n const deriveConfig = computed(() => {\n const options = control.value.uischema?.options as\n | { derive?: string; mode?: string }\n | undefined;\n return {\n expression: options?.derive,\n mode: options?.mode || \"follow\", // 'follow' = auto-update, 'manual' = user controlled\n };\n });\n\n // Track the last resolved source value so we only update the field\n // when the source itself changes, not on every form data mutation.\n const lastDerivedValue = ref<unknown>(undefined);\n // First watch fire is special: a pre-populated field (edit flow seeded\n // from a saved connection) must not be clobbered by whatever the source\n // resolves to on mount. We record the source value but skip handleChange.\n let isFirstRun = true;\n\n // Watch for changes in form data and dataLayer and update derived field\n watch(\n [rootData, dataLayerData, deriveConfig],\n ([data, extData, config]) => {\n if (!config.expression || config.mode !== \"follow\") {\n return;\n }\n\n try {\n const derivedValue = resolveDeriveExpression(\n config.expression,\n data,\n extData,\n );\n const compareData = dataOverride\n ? unref(dataOverride)\n : control.value.data;\n\n if (isFirstRun) {\n isFirstRun = false;\n lastDerivedValue.value = derivedValue;\n // On mount, only populate the field if it's empty.\n // A non-empty seed represents user intent (edit flow) and must\n // be preserved. Subsequent source changes will still propagate.\n const isFieldEmpty =\n compareData === undefined ||\n compareData === null ||\n compareData === \"\";\n if (isFieldEmpty && derivedValue !== compareData) {\n handleChange(control.value.path, derivedValue);\n }\n return;\n }\n\n // Only update if the SOURCE value changed, not just the field value\n if (derivedValue === lastDerivedValue.value) return;\n lastDerivedValue.value = derivedValue;\n\n if (derivedValue !== compareData) {\n handleChange(control.value.path, derivedValue);\n }\n } catch (error) {\n console.warn(\n `Failed to derive value for ${control.value.path}:`,\n error,\n );\n }\n },\n { deep: true, immediate: true },\n );\n}\n\nfunction resolveDeriveExpression(\n expression: string,\n data: unknown,\n dataLayerData?: unknown,\n): unknown {\n // Handle dataLayer() syntax\n if (expression.startsWith(\"dataLayer(\") && expression.endsWith(\")\")) {\n const propertyPath = expression.slice(10, -1); // Remove \"dataLayer(\" and \")\"\n return resolvePropertyPath(propertyPath, dataLayerData);\n }\n\n // Handle simple property paths like \"country.name\"\n if (\n !expression.includes(\"(\") &&\n !expression.includes(\"+\") &&\n !expression.includes(\"?\")\n ) {\n return resolvePropertyPath(expression, data);\n }\n\n // For now, we'll only support simple property paths and dataLayer() calls\n // Complex expressions would require a safe expression evaluator\n return resolvePropertyPath(expression, data);\n}\n\nfunction resolvePropertyPath(path: string, data: unknown): unknown {\n if (!path || !data) return \"\";\n\n const keys = path.split(\".\");\n let value: unknown = data;\n\n for (const key of keys) {\n if (value && typeof value === \"object\" && key in value) {\n value = (value as Record<string, unknown>)[key];\n } else {\n return null;\n }\n }\n\n return value;\n}\n"],"names":[],"mappings":";;;AAwBO,SAAS,UAAU;AAAA,EACxB;AAAA,EACA;AAAA,EACA,MAAM;AACR,GAAkB;AAEhB,QAAM,mBAAmB,OAA2B,YAAY;AAAA,IAC9D,OAAO,CAAA;AAAA,EAAC,CACT;AACD,QAAM,WAAW,SAAS,MAAM,iBAAiB,SAAS,CAAA,CAAE;AAG5D,QAAM,iBAAiB,aAAA;AACvB,QAAM,gBAAgB,SAAS,MAAM,eAAe,SAAS,CAAA,CAAE;AAG/D,QAAM,eAAe,SAAS,MAAM;AAClC,UAAM,UAAU,QAAQ,MAAM,UAAU;AAGxC,WAAO;AAAA,MACL,YAAY,SAAS;AAAA,MACrB,MAAM,SAAS,QAAQ;AAAA;AAAA,IAAA;AAAA,EAE3B,CAAC;AAID,QAAM,mBAAmB,IAAa,MAAS;AAI/C,MAAI,aAAa;AAGjB;AAAA,IACE,CAAC,UAAU,eAAe,YAAY;AAAA,IACtC,CAAC,CAAC,MAAM,SAAS,MAAM,MAAM;AAC3B,UAAI,CAAC,OAAO,cAAc,OAAO,SAAS,UAAU;AAClD;AAAA,MACF;AAEA,UAAI;AACF,cAAM,eAAe;AAAA,UACnB,OAAO;AAAA,UACP;AAAA,UACA;AAAA,QAAA;AAEF,cAAM,cAAc,eAChB,MAAM,YAAY,IAClB,QAAQ,MAAM;AAElB,YAAI,YAAY;AACd,uBAAa;AACb,2BAAiB,QAAQ;AAIzB,gBAAM,eACJ,gBAAgB,UAChB,gBAAgB,QAChB,gBAAgB;AAClB,cAAI,gBAAgB,iBAAiB,aAAa;AAChD,yBAAa,QAAQ,MAAM,MAAM,YAAY;AAAA,UAC/C;AACA;AAAA,QACF;AAGA,YAAI,iBAAiB,iBAAiB,MAAO;AAC7C,yBAAiB,QAAQ;AAEzB,YAAI,iBAAiB,aAAa;AAChC,uBAAa,QAAQ,MAAM,MAAM,YAAY;AAAA,QAC/C;AAAA,MACF,SAAS,OAAO;AACd,gBAAQ;AAAA,UACN,8BAA8B,QAAQ,MAAM,IAAI;AAAA,UAChD;AAAA,QAAA;AAAA,MAEJ;AAAA,IACF;AAAA,IACA,EAAE,MAAM,MAAM,WAAW,KAAA;AAAA,EAAK;AAElC;AAEA,SAAS,wBACP,YACA,MACA,eACS;AAET,MAAI,WAAW,WAAW,YAAY,KAAK,WAAW,SAAS,GAAG,GAAG;AACnE,UAAM,eAAe,WAAW,MAAM,IAAI,EAAE;AAC5C,WAAO,oBAAoB,cAAc,aAAa;AAAA,EACxD;AAGA,MACE,CAAC,WAAW,SAAS,GAAG,KACxB,CAAC,WAAW,SAAS,GAAG,KACxB,CAAC,WAAW,SAAS,GAAG,GACxB;AACA,WAAO,oBAAoB,YAAY,IAAI;AAAA,EAC7C;AAIA,SAAO,oBAAoB,YAAY,IAAI;AAC7C;AAEA,SAAS,oBAAoB,MAAc,MAAwB;AACjE,MAAI,CAAC,QAAQ,CAAC,KAAM,QAAO;AAE3B,QAAM,OAAO,KAAK,MAAM,GAAG;AAC3B,MAAI,QAAiB;AAErB,aAAW,OAAO,MAAM;AACtB,QAAI,SAAS,OAAO,UAAU,YAAY,OAAO,OAAO;AACtD,cAAS,MAAkC,GAAG;AAAA,IAChD,OAAO;AACL,aAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO;AACT;"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { type Ref, type ComputedRef } from "vue";
|
|
2
|
+
import { type ControlElement } from "@jsonforms/core";
|
|
3
|
+
import { type TransformPipeline } from "../../core/transforms";
|
|
4
|
+
import type { AuthConfig } from "../../core/types";
|
|
5
|
+
export interface DeriveInitialValueCfg {
|
|
6
|
+
protocol: string;
|
|
7
|
+
config: {
|
|
8
|
+
url: string;
|
|
9
|
+
method?: "GET" | "POST";
|
|
10
|
+
headers?: Record<string, string>;
|
|
11
|
+
query?: Record<string, unknown>;
|
|
12
|
+
body?: unknown;
|
|
13
|
+
auth?: AuthConfig;
|
|
14
|
+
items: string;
|
|
15
|
+
map: {
|
|
16
|
+
value: string;
|
|
17
|
+
};
|
|
18
|
+
transforms?: TransformPipeline;
|
|
19
|
+
showError?: boolean;
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
interface DeriveInitialValueOptions {
|
|
23
|
+
control: Ref<{
|
|
24
|
+
uischema: ControlElement;
|
|
25
|
+
path: string;
|
|
26
|
+
data: unknown;
|
|
27
|
+
}>;
|
|
28
|
+
handleChange: (path: string, value: unknown) => void;
|
|
29
|
+
data?: Ref<unknown> | ComputedRef<unknown>;
|
|
30
|
+
}
|
|
31
|
+
export declare function useDeriveInitialValue({ control, handleChange, }: DeriveInitialValueOptions): {
|
|
32
|
+
loading: Ref<boolean, boolean>;
|
|
33
|
+
error: Ref<string | undefined, string | undefined>;
|
|
34
|
+
};
|
|
35
|
+
export {};
|
|
36
|
+
//# sourceMappingURL=useDeriveInitialValue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useDeriveInitialValue.d.ts","sourceRoot":"","sources":["../../../src/vue/composables/useDeriveInitialValue.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgC,KAAK,GAAG,EAAE,KAAK,WAAW,EAAE,MAAM,KAAK,CAAC;AAC/E,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGtD,OAAO,EAEL,KAAK,iBAAiB,EACvB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE;QACN,GAAG,EAAE,MAAM,CAAC;QACZ,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;QACxB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACjC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAChC,IAAI,CAAC,EAAE,OAAO,CAAC;QACf,IAAI,CAAC,EAAE,UAAU,CAAC;QAClB,KAAK,EAAE,MAAM,CAAC;QACd,GAAG,EAAE;YAAE,KAAK,EAAE,MAAM,CAAA;SAAE,CAAC;QACvB,UAAU,CAAC,EAAE,iBAAiB,CAAC;QAC/B,SAAS,CAAC,EAAE,OAAO,CAAC;KACrB,CAAC;CACH;AAED,UAAU,yBAAyB;IACjC,OAAO,EAAE,GAAG,CAAC;QACX,QAAQ,EAAE,cAAc,CAAC;QACzB,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,OAAO,CAAC;KACf,CAAC,CAAC;IACH,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACrD,IAAI,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;CAC5C;AAsDD,wBAAgB,qBAAqB,CAAC,EACpC,OAAO,EACP,YAAY,GACb,EAAE,yBAAyB;;;EAuG3B"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { inject, computed, ref, watch } from "vue";
|
|
2
|
+
import "@jsonforms/core";
|
|
3
|
+
import { renderTpl, renderObj } from "../../core/templating.js";
|
|
4
|
+
import { jp } from "../../core/jsonpath.js";
|
|
5
|
+
import { applyTransformPipeline } from "../../core/transforms.js";
|
|
6
|
+
function buildAuthHeaders(auth, globalAuth) {
|
|
7
|
+
const headers = {};
|
|
8
|
+
if (!auth) return headers;
|
|
9
|
+
if (auth.use && globalAuth?.[auth.use]) {
|
|
10
|
+
const globalValue = globalAuth[auth.use];
|
|
11
|
+
const value = typeof globalValue === "function" ? globalValue() : globalValue;
|
|
12
|
+
if (auth.use === "apiKey") headers["X-API-Key"] = String(value);
|
|
13
|
+
else if (auth.use === "bearer")
|
|
14
|
+
headers["Authorization"] = `Bearer ${value}`;
|
|
15
|
+
else if (auth.use === "token") headers["Authorization"] = `Token ${value}`;
|
|
16
|
+
return headers;
|
|
17
|
+
}
|
|
18
|
+
if (auth.bearer) {
|
|
19
|
+
const v = typeof auth.bearer === "function" ? auth.bearer() : auth.bearer;
|
|
20
|
+
headers["Authorization"] = `Bearer ${v}`;
|
|
21
|
+
}
|
|
22
|
+
if (auth.apiKey) {
|
|
23
|
+
const v = typeof auth.apiKey === "function" ? auth.apiKey() : auth.apiKey;
|
|
24
|
+
headers["X-API-Key"] = String(v);
|
|
25
|
+
}
|
|
26
|
+
if (auth.token) {
|
|
27
|
+
const v = typeof auth.token === "function" ? auth.token() : auth.token;
|
|
28
|
+
headers["Authorization"] = `Token ${v}`;
|
|
29
|
+
}
|
|
30
|
+
return headers;
|
|
31
|
+
}
|
|
32
|
+
function hasUnresolvedTemplates(templateUrl, renderedUrl) {
|
|
33
|
+
if (!templateUrl.includes("{{")) return false;
|
|
34
|
+
const pathPart = renderedUrl.replace(/^https?:\/\/[^/]+/, "");
|
|
35
|
+
if (pathPart.includes("//")) return true;
|
|
36
|
+
if (renderedUrl.endsWith("/") && !templateUrl.endsWith("/")) return true;
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
function useDeriveInitialValue({
|
|
40
|
+
control,
|
|
41
|
+
handleChange
|
|
42
|
+
}) {
|
|
43
|
+
const injectedFormData = inject("formData", {
|
|
44
|
+
value: {}
|
|
45
|
+
});
|
|
46
|
+
const rootData = computed(() => injectedFormData.value || {});
|
|
47
|
+
const auth = inject("providerAuth", {});
|
|
48
|
+
const cfg = computed(() => {
|
|
49
|
+
return control.value.uischema?.options?.deriveInitialValue;
|
|
50
|
+
});
|
|
51
|
+
const resolvedUrl = computed(() => {
|
|
52
|
+
const c = cfg.value;
|
|
53
|
+
if (!c?.config?.url) return null;
|
|
54
|
+
const rendered = renderTpl(c.config.url, { data: rootData.value });
|
|
55
|
+
if (hasUnresolvedTemplates(c.config.url, rendered)) return null;
|
|
56
|
+
return rendered;
|
|
57
|
+
});
|
|
58
|
+
const lastFetchedUrl = ref(null);
|
|
59
|
+
const loading = ref(false);
|
|
60
|
+
const error = ref(void 0);
|
|
61
|
+
watch(
|
|
62
|
+
resolvedUrl,
|
|
63
|
+
async (url) => {
|
|
64
|
+
if (!url || !cfg.value) return;
|
|
65
|
+
if (url === lastFetchedUrl.value) return;
|
|
66
|
+
lastFetchedUrl.value = url;
|
|
67
|
+
loading.value = true;
|
|
68
|
+
error.value = void 0;
|
|
69
|
+
try {
|
|
70
|
+
const c = cfg.value.config;
|
|
71
|
+
const fullUrl = new URL(url);
|
|
72
|
+
const q = renderObj(c.query ?? {}, {
|
|
73
|
+
data: rootData.value
|
|
74
|
+
});
|
|
75
|
+
for (const [k, v] of Object.entries(q)) {
|
|
76
|
+
if (v !== void 0 && v !== "")
|
|
77
|
+
fullUrl.searchParams.set(k, String(v));
|
|
78
|
+
}
|
|
79
|
+
const baseHeaders = renderObj(c.headers ?? {}, {
|
|
80
|
+
data: rootData.value
|
|
81
|
+
});
|
|
82
|
+
const authHeaders = buildAuthHeaders(c.auth, auth);
|
|
83
|
+
const headers = { ...baseHeaders, ...authHeaders };
|
|
84
|
+
const method = c.method ?? "GET";
|
|
85
|
+
const requestInit = { method, headers };
|
|
86
|
+
if (method !== "GET" && c.body) {
|
|
87
|
+
requestInit.body = JSON.stringify(
|
|
88
|
+
renderObj(c.body, { data: rootData.value })
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
const res = await fetch(fullUrl.toString(), requestInit);
|
|
92
|
+
if (!res.ok) {
|
|
93
|
+
if (c.showError !== false) {
|
|
94
|
+
throw new Error(`REST ${res.status}`);
|
|
95
|
+
}
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
const json = await res.json();
|
|
99
|
+
let items = jp(json, c.items);
|
|
100
|
+
if (c.transforms && c.transforms.length > 0) {
|
|
101
|
+
items = applyTransformPipeline(items, c.transforms);
|
|
102
|
+
}
|
|
103
|
+
if (items.length === 0) return;
|
|
104
|
+
const derivedValue = jp(items[0], c.map.value)[0];
|
|
105
|
+
if (derivedValue !== void 0) {
|
|
106
|
+
handleChange(control.value.path, derivedValue);
|
|
107
|
+
}
|
|
108
|
+
} catch (e) {
|
|
109
|
+
error.value = e?.message ?? String(e);
|
|
110
|
+
console.warn(
|
|
111
|
+
`deriveInitialValue fetch failed for ${control.value.path}:`,
|
|
112
|
+
e
|
|
113
|
+
);
|
|
114
|
+
} finally {
|
|
115
|
+
loading.value = false;
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
{ immediate: true }
|
|
119
|
+
);
|
|
120
|
+
return { loading, error };
|
|
121
|
+
}
|
|
122
|
+
export {
|
|
123
|
+
useDeriveInitialValue
|
|
124
|
+
};
|
|
125
|
+
//# sourceMappingURL=useDeriveInitialValue.js.map
|