@live-change/frontend-auto-form 0.9.162 → 0.9.164
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/front/src/components/crud/ActionForm.vue +2 -2
- package/front/src/components/form/CodeEditor.vue +111 -0
- package/front/src/components/form/JsonInput.vue +81 -0
- package/front/src/components/form/TriggerInput.vue +142 -0
- package/front/src/components/form/TriggerPicker.vue +145 -0
- package/front/src/components/form/provideAutoInputConfiguration.js +4 -0
- package/front/src/logic/actionData.js +17 -6
- package/front/src/logic/editorData.js +1 -1
- package/package.json +13 -13
|
@@ -154,7 +154,7 @@
|
|
|
154
154
|
|
|
155
155
|
const returnType = computed(() => {
|
|
156
156
|
const returnType = actionFormData.action.definition.returns
|
|
157
|
-
return returnType
|
|
157
|
+
return returnType?.type
|
|
158
158
|
})
|
|
159
159
|
|
|
160
160
|
function handleSubmit(ev) {
|
|
@@ -178,7 +178,7 @@
|
|
|
178
178
|
resultWithType.value = null
|
|
179
179
|
if(type === 'task_Task') {
|
|
180
180
|
task.value = result
|
|
181
|
-
} else if(type.split('_').length === 1) {
|
|
181
|
+
} else if(type && type.split('_').length === 1) {
|
|
182
182
|
if(typeof result === 'object') {
|
|
183
183
|
resultWithType.value = {
|
|
184
184
|
type: type,
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<prism-editor v-if="isMounted"
|
|
3
|
+
class="code-editor p-component p-textarea" :highlight="highlight"
|
|
4
|
+
:style="{ height: (codeLines * 1.35 + 1.23) + 'em' }"
|
|
5
|
+
v-model="code"
|
|
6
|
+
:readonly="readOnly" :line-numbers="codeLines > 1" />
|
|
7
|
+
<Message v-if="editResult.error" severity="error" variant="simple" size="small">
|
|
8
|
+
{{ editResult.error }}
|
|
9
|
+
</Message>
|
|
10
|
+
<Textarea class="hidden" />
|
|
11
|
+
</template>
|
|
12
|
+
|
|
13
|
+
<script setup>
|
|
14
|
+
|
|
15
|
+
import Textarea from 'primevue/textarea'
|
|
16
|
+
import { stringify } from "javascript-stringify"
|
|
17
|
+
|
|
18
|
+
import 'vue-prism-editor/dist/prismeditor.min.css'
|
|
19
|
+
import 'prismjs/themes/prism-coy.css'
|
|
20
|
+
import * as Prism from 'prismjs/components/prism-core'
|
|
21
|
+
import 'prismjs/components/prism-clike'
|
|
22
|
+
import 'prismjs/components/prism-javascript'
|
|
23
|
+
|
|
24
|
+
import Message from "primevue/message"
|
|
25
|
+
|
|
26
|
+
import { PrismEditor } from 'vue-prism-editor'
|
|
27
|
+
|
|
28
|
+
import { ref, computed, watch, onMounted } from 'vue'
|
|
29
|
+
|
|
30
|
+
const isMounted = ref(false)
|
|
31
|
+
onMounted(() => isMounted.value = true)
|
|
32
|
+
|
|
33
|
+
const props = defineProps({
|
|
34
|
+
initialCode: {
|
|
35
|
+
type: String
|
|
36
|
+
},
|
|
37
|
+
initialData: {
|
|
38
|
+
},
|
|
39
|
+
readOnly: {
|
|
40
|
+
type: Boolean,
|
|
41
|
+
default: false
|
|
42
|
+
},
|
|
43
|
+
env: {
|
|
44
|
+
type: Object
|
|
45
|
+
},
|
|
46
|
+
dbSugar: {
|
|
47
|
+
type: Object
|
|
48
|
+
}
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
const { readOnly, env, dbSugar } = props
|
|
52
|
+
|
|
53
|
+
const emit = defineEmits(['result'])
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
const code = ref(props.initialCode !== undefined ? props.initialCode : stringify(props.initialData, null, " "))
|
|
57
|
+
|
|
58
|
+
watch(() => props.initialCode, () => {
|
|
59
|
+
if(props.initialCode == code.value) return
|
|
60
|
+
code.value = props.initialCode !== undefined ? props.initialCode : stringify(props.initialData, null, " ")
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
function highlight(code) {
|
|
64
|
+
return Prism.highlight(code, Prism.languages.js, "js")
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const codeLines = computed(() => code.value.split('\n').length)
|
|
68
|
+
|
|
69
|
+
const modified = computed(() => code.value != props.initialCode)
|
|
70
|
+
|
|
71
|
+
const editResult = computed(() => {
|
|
72
|
+
if(!modified.value && props.initialData) return { data: props.initialData, code: code.value }
|
|
73
|
+
try {
|
|
74
|
+
const $ = env || {}
|
|
75
|
+
const db = dbSugar || {}
|
|
76
|
+
//console.log("COMPILE CODE", code.value)
|
|
77
|
+
const result = eval(`(${code.value})`)
|
|
78
|
+
if(result === false) return { data: false, code: code.value }
|
|
79
|
+
if(result) return { data: result, code: code.value }
|
|
80
|
+
return { error: 'empty' }
|
|
81
|
+
} catch(e) {
|
|
82
|
+
if(e instanceof SyntaxError) {
|
|
83
|
+
if(e.lineNumber) return {
|
|
84
|
+
error: `${e.message} at ${e.lineNumber}:${e.columnNumber - (e.lineNumber ? 0 : -1)}`
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return { error: e.message }
|
|
88
|
+
}
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
function reset() {
|
|
92
|
+
code.value = props.initialCode !== undefined ? props.initialCode : stringify(props.initialData, null, " ")
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
watch(() => editResult.value, () => emit('result', editResult.value))
|
|
96
|
+
|
|
97
|
+
defineExpose({ reset })
|
|
98
|
+
|
|
99
|
+
</script>
|
|
100
|
+
|
|
101
|
+
<style lang="scss">
|
|
102
|
+
.code-editor {
|
|
103
|
+
font-family: monospace;
|
|
104
|
+
outline: none;
|
|
105
|
+
.prism-editor__container {
|
|
106
|
+
textarea {
|
|
107
|
+
outline: none;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
</style>
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div>
|
|
3
|
+
|
|
4
|
+
<CodeEditor :readOnly="false" :initialData="initialData" @result="result => handleEditResult(result)"
|
|
5
|
+
:ref="el => editorElementFound(el)" />
|
|
6
|
+
|
|
7
|
+
</div>
|
|
8
|
+
</template>
|
|
9
|
+
|
|
10
|
+
<script setup>
|
|
11
|
+
|
|
12
|
+
import CodeEditor from './CodeEditor.vue'
|
|
13
|
+
import Textarea from 'primevue/textarea'
|
|
14
|
+
|
|
15
|
+
import { defineProps, defineEmits, toRefs, ref, defineModel, computed, watch } from 'vue'
|
|
16
|
+
import { useElementSize } from '@vueuse/core'
|
|
17
|
+
|
|
18
|
+
const props = defineProps({
|
|
19
|
+
definition: {
|
|
20
|
+
type: Object
|
|
21
|
+
},
|
|
22
|
+
properties: {
|
|
23
|
+
type: Object,
|
|
24
|
+
default: () => ({})
|
|
25
|
+
},
|
|
26
|
+
rootValue: {
|
|
27
|
+
type: Object,
|
|
28
|
+
default: () => ({})
|
|
29
|
+
},
|
|
30
|
+
propName: {
|
|
31
|
+
type: String,
|
|
32
|
+
default: ''
|
|
33
|
+
},
|
|
34
|
+
i18n: {
|
|
35
|
+
type: String,
|
|
36
|
+
default: ''
|
|
37
|
+
}
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
const { definition, properties, rootValue, propName, i18n: i18nPrefix } = toRefs(props)
|
|
41
|
+
|
|
42
|
+
const model = defineModel({
|
|
43
|
+
required: true
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
const initialData = ref(JSON.parse(JSON.stringify(model.value ?? null)))
|
|
48
|
+
const edited = ref(false)
|
|
49
|
+
let editTimeout = null
|
|
50
|
+
|
|
51
|
+
function handleEditResult(result) {
|
|
52
|
+
edited.value = true
|
|
53
|
+
model.value = result.data
|
|
54
|
+
if(editTimeout) clearTimeout(editTimeout)
|
|
55
|
+
editTimeout = setTimeout(() => {
|
|
56
|
+
edited.value = false
|
|
57
|
+
editTimeout = null
|
|
58
|
+
}, 1000)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
watch(() => model.value, currentData => {
|
|
62
|
+
const refresh = !edited.value
|
|
63
|
+
initialData.value = JSON.parse(JSON.stringify(currentData))
|
|
64
|
+
if(refresh) {
|
|
65
|
+
//editedData.value = JSON.parse(currentData)
|
|
66
|
+
setTimeout(() => {
|
|
67
|
+
codeEditor.value.reset()
|
|
68
|
+
})
|
|
69
|
+
}
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
const codeEditor = ref()
|
|
73
|
+
function editorElementFound(element) {
|
|
74
|
+
codeEditor.value = element
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
</script>
|
|
78
|
+
|
|
79
|
+
<style>
|
|
80
|
+
|
|
81
|
+
</style>
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div>
|
|
3
|
+
<div ref="selectElement" class="p-select p-component p-inputwrapper w-full" @click="toggleObjectPicker">
|
|
4
|
+
<span v-if="!(model?.name && model?.service)" class="p-select-label p-placeholder" tabindex="0" role="combobox">
|
|
5
|
+
<span>
|
|
6
|
+
Select trigger
|
|
7
|
+
</span>
|
|
8
|
+
</span>
|
|
9
|
+
<span v-else class="p-select-label">
|
|
10
|
+
<span>
|
|
11
|
+
{{ model.service }} - {{ model.name }}
|
|
12
|
+
</span>
|
|
13
|
+
</span>
|
|
14
|
+
<div class="p-select-dropdown" data-pc-section="dropdown">
|
|
15
|
+
<ChevronDownIcon />
|
|
16
|
+
</div>
|
|
17
|
+
</div>
|
|
18
|
+
|
|
19
|
+
<!-- <pre>objt = {{ objectType }}</pre> -->
|
|
20
|
+
|
|
21
|
+
<Popover ref="triggerPickerPopover" :pt="{
|
|
22
|
+
root: {
|
|
23
|
+
class: 'trigger-picker-popover overflow-y-auto',
|
|
24
|
+
style: {
|
|
25
|
+
minWidth: `${width}px`,
|
|
26
|
+
maxHeight: `calc(50vh - 30px)`
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}">
|
|
30
|
+
<TriggerPicker v-model="model" :definition="definition" :properties="properties"
|
|
31
|
+
:rootValue="rootValue" :propName="propName" :i18n="i18n" @selected="handleSelected" />
|
|
32
|
+
</Popover>
|
|
33
|
+
|
|
34
|
+
<!-- needed to autoload styles: -->
|
|
35
|
+
<Select class="hidden" :options="[1,2,3]" />
|
|
36
|
+
|
|
37
|
+
<AutoField v-if="triggerDefinition" v-model="triggerProperties"
|
|
38
|
+
:definition="{ ...triggerDefinition, type: 'Object' }"
|
|
39
|
+
:rootValue="rootValue" :propName="propName+'.properties'"
|
|
40
|
+
:i18n="i18n" label="trigger.properties" />
|
|
41
|
+
|
|
42
|
+
<div class="flex items-center gap-2 mt-2">
|
|
43
|
+
<ToggleSwitch v-model="returnTask" id="returnTask" />
|
|
44
|
+
<label for="returnTask">Trigger returns task to wait for</label>
|
|
45
|
+
</div>
|
|
46
|
+
|
|
47
|
+
</div>
|
|
48
|
+
</template>
|
|
49
|
+
|
|
50
|
+
<script setup>
|
|
51
|
+
import ChevronDownIcon from '@primevue/icons/chevrondown'
|
|
52
|
+
import Select from 'primevue/select'
|
|
53
|
+
import Popover from 'primevue/popover'
|
|
54
|
+
import ToggleSwitch from 'primevue/toggleswitch'
|
|
55
|
+
import TriggerPicker from './TriggerPicker.vue'
|
|
56
|
+
|
|
57
|
+
import AutoField from './AutoField.vue'
|
|
58
|
+
|
|
59
|
+
import { defineProps, defineEmits, toRefs, ref, defineModel, computed } from 'vue'
|
|
60
|
+
import { useElementSize } from '@vueuse/core'
|
|
61
|
+
|
|
62
|
+
const props = defineProps({
|
|
63
|
+
definition: {
|
|
64
|
+
type: Object
|
|
65
|
+
},
|
|
66
|
+
properties: {
|
|
67
|
+
type: Object,
|
|
68
|
+
default: () => ({})
|
|
69
|
+
},
|
|
70
|
+
rootValue: {
|
|
71
|
+
type: Object,
|
|
72
|
+
default: () => ({})
|
|
73
|
+
},
|
|
74
|
+
propName: {
|
|
75
|
+
type: String,
|
|
76
|
+
default: ''
|
|
77
|
+
},
|
|
78
|
+
i18n: {
|
|
79
|
+
type: String,
|
|
80
|
+
default: ''
|
|
81
|
+
}
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
const { definition, properties, rootValue, propName, i18n: i18nPrefix } = toRefs(props)
|
|
85
|
+
|
|
86
|
+
const model = defineModel({
|
|
87
|
+
required: true
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
import { useApi } from '@live-change/vue3-ssr'
|
|
91
|
+
const api = useApi()
|
|
92
|
+
|
|
93
|
+
const triggerPickerPopover = ref()
|
|
94
|
+
const selectElement = ref()
|
|
95
|
+
const { width } = useElementSize(selectElement)
|
|
96
|
+
|
|
97
|
+
const toggleObjectPicker = (event) => {
|
|
98
|
+
triggerPickerPopover.value.toggle(event)
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const handleSelected = (object) => {
|
|
102
|
+
triggerPickerPopover.value.hide()
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const triggerDefinition = computed(() => {
|
|
106
|
+
if(!model.value?.service || !model.value?.name) return null
|
|
107
|
+
const service = api.metadata.api.value.services.find(s => s.name === model.value.service)
|
|
108
|
+
if(!service) return null
|
|
109
|
+
return service.triggers[model.value.name][0]
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
const triggerProperties = computed({
|
|
113
|
+
get() {
|
|
114
|
+
return model.value?.properties
|
|
115
|
+
},
|
|
116
|
+
set(value) {
|
|
117
|
+
model.value = { ...(model.value ?? {}), properties: value }
|
|
118
|
+
}
|
|
119
|
+
})
|
|
120
|
+
|
|
121
|
+
const returnTask = computed({
|
|
122
|
+
get() {
|
|
123
|
+
return model.value?.returnTask
|
|
124
|
+
},
|
|
125
|
+
set(value) {
|
|
126
|
+
model.value = { ...(model.value ?? {}), returnTask: value }
|
|
127
|
+
}
|
|
128
|
+
})
|
|
129
|
+
|
|
130
|
+
</script>
|
|
131
|
+
|
|
132
|
+
<style>
|
|
133
|
+
.trigger-picker-popover {
|
|
134
|
+
margin-top: 1px;
|
|
135
|
+
}
|
|
136
|
+
.trigger-picker-popover:before {
|
|
137
|
+
display: none;
|
|
138
|
+
}
|
|
139
|
+
.trigger-picker-popover:after {
|
|
140
|
+
display: none;
|
|
141
|
+
}
|
|
142
|
+
</style>
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div>
|
|
3
|
+
<div>
|
|
4
|
+
<div v-if="!(model?.service)" class="p-1 py-2 sticky top-0 z-10">
|
|
5
|
+
<div class="flex flex-col gap-2">
|
|
6
|
+
<!-- <label :for="`type-select-${uid}`">{{ t('objectPicker.selectObjectType') }}</label> -->
|
|
7
|
+
<!-- <Select v-model="selectedService" :options="serviceOptions" :id="`service-select-${uid}`"
|
|
8
|
+
:placeholder="t('triggerPicker.selectService')" /> -->
|
|
9
|
+
<div class="text-sm text-surface-600 dark:text-surface-400 mb-2">{{ t('triggerPicker.selectService') }}</div>
|
|
10
|
+
<div class="flex flex-col gap-2">
|
|
11
|
+
<div v-for="service in serviceOptions" :key="service"
|
|
12
|
+
class="p-2 hover:bg-surface-100 dark:hover:bg-surface-800 cursor-pointer"
|
|
13
|
+
@click="selectedService = service">
|
|
14
|
+
{{ service }}
|
|
15
|
+
</div>
|
|
16
|
+
</div>
|
|
17
|
+
</div>
|
|
18
|
+
</div>
|
|
19
|
+
|
|
20
|
+
<div v-if="model?.service">
|
|
21
|
+
<div class="text-sm text-surface-600 dark:text-surface-400 mb-2">
|
|
22
|
+
{{ t('triggerPicker.selectedService') }} {{ model.service }}
|
|
23
|
+
<Button class="ml-2" icon="pi pi-times" size="small" outlined rounded @click="selectedService = null" />
|
|
24
|
+
</div>
|
|
25
|
+
<div class="text-sm text-surface-600 dark:text-surface-400 mb-2">{{ t('triggerPicker.selectTrigger') }}</div>
|
|
26
|
+
<div class="flex flex-col gap-2">
|
|
27
|
+
<div v-for="trigger in triggerOptions" :key="trigger"
|
|
28
|
+
class="p-2 hover:bg-surface-100 dark:hover:bg-surface-800 cursor-pointer"
|
|
29
|
+
@click="selectedTrigger = trigger">
|
|
30
|
+
{{ trigger }}
|
|
31
|
+
</div>
|
|
32
|
+
</div>
|
|
33
|
+
</div>
|
|
34
|
+
</div>
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
<!-- <pre>isTypeNeeded = {{ isTypeNeeded }}</pre>
|
|
38
|
+
<pre>typePropertyName = {{ typePropertyName }}</pre>
|
|
39
|
+
<pre>typePropertyPath = {{ typePropertyPath }}</pre>
|
|
40
|
+
<pre>typeModel = {{ typeModel }}</pre> -->
|
|
41
|
+
<!-- <div>
|
|
42
|
+
<pre>objectsPathRangeConfig = {{ objectsPathRangeConfig }}</pre>
|
|
43
|
+
<pre>objectsPathRangeFunction = {{ objectsPathRangeFunction }}</pre>
|
|
44
|
+
<pre>selectedType = {{ selectedType }}</pre>
|
|
45
|
+
<pre>definition = {{ definition }}</pre>
|
|
46
|
+
<pre>properties = {{ properties }}</pre>
|
|
47
|
+
<pre>typeOptions = {{ typeOptions }}</pre>
|
|
48
|
+
<pre>model = {{ model }}</pre>
|
|
49
|
+
</div> -->
|
|
50
|
+
</div>
|
|
51
|
+
</template>
|
|
52
|
+
|
|
53
|
+
<script setup>
|
|
54
|
+
import Select from 'primevue/select'
|
|
55
|
+
import Button from 'primevue/button'
|
|
56
|
+
import AutoObjectIdentification from '../crud/DefaultObjectIdentification.vue'
|
|
57
|
+
import { RangeViewer, injectComponent } from "@live-change/vue3-components"
|
|
58
|
+
|
|
59
|
+
import { defineProps, defineEmits, toRefs, ref, defineModel, computed, useId, inject, unref } from 'vue'
|
|
60
|
+
import pluralize from 'pluralize'
|
|
61
|
+
|
|
62
|
+
const uid = useId()
|
|
63
|
+
|
|
64
|
+
const props = defineProps({
|
|
65
|
+
definition: {
|
|
66
|
+
type: Object
|
|
67
|
+
},
|
|
68
|
+
properties: {
|
|
69
|
+
type: Object,
|
|
70
|
+
default: () => ({})
|
|
71
|
+
},
|
|
72
|
+
rootValue: {
|
|
73
|
+
type: Object,
|
|
74
|
+
default: () => ({})
|
|
75
|
+
},
|
|
76
|
+
propName: {
|
|
77
|
+
type: String,
|
|
78
|
+
default: ''
|
|
79
|
+
},
|
|
80
|
+
i18n: {
|
|
81
|
+
type: String,
|
|
82
|
+
default: ''
|
|
83
|
+
},
|
|
84
|
+
showServiceName: {
|
|
85
|
+
type: Boolean,
|
|
86
|
+
default: false
|
|
87
|
+
},
|
|
88
|
+
view: {
|
|
89
|
+
type: String,
|
|
90
|
+
default: 'range'
|
|
91
|
+
}
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
const { definition, properties, rootValue, propName, i18n, view } = toRefs(props)
|
|
95
|
+
|
|
96
|
+
const model = defineModel({
|
|
97
|
+
required: true
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
const emit = defineEmits(['selected'])
|
|
101
|
+
|
|
102
|
+
import { useI18n } from 'vue-i18n'
|
|
103
|
+
const { t: tI18n, te } = useI18n()
|
|
104
|
+
const t = (key, ...params) => tI18n(
|
|
105
|
+
te(i18n.value + propName.value + key)
|
|
106
|
+
? i18n.value + propName.value + key
|
|
107
|
+
: key, ...params
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
import { useApi } from '@live-change/vue3-ssr'
|
|
111
|
+
const api = useApi()
|
|
112
|
+
const serviceOptions = computed(() => {
|
|
113
|
+
return api.metadata.api.value.services.map(s => s.name)
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
const selectedService = computed({
|
|
117
|
+
get() {
|
|
118
|
+
return model.value?.service
|
|
119
|
+
},
|
|
120
|
+
set(value) {
|
|
121
|
+
model.value = { ...(model.value ?? {}), service: value }
|
|
122
|
+
}
|
|
123
|
+
})
|
|
124
|
+
|
|
125
|
+
const triggerOptions = computed(() => {
|
|
126
|
+
if(!selectedService.value) return []
|
|
127
|
+
const service = api.metadata.api.value.services.find(s => s.name === selectedService.value)
|
|
128
|
+
if(!service) return []
|
|
129
|
+
return Object.keys(service.triggers)
|
|
130
|
+
})
|
|
131
|
+
|
|
132
|
+
const selectedTrigger = computed({
|
|
133
|
+
get() {
|
|
134
|
+
return model.value?.name
|
|
135
|
+
},
|
|
136
|
+
set(value) {
|
|
137
|
+
model.value = { ...(model.value ?? {}), name: value }
|
|
138
|
+
emit('selected', model.value)
|
|
139
|
+
}
|
|
140
|
+
})
|
|
141
|
+
|
|
142
|
+
</script>
|
|
143
|
+
|
|
144
|
+
<style scoped>
|
|
145
|
+
</style>
|
|
@@ -73,6 +73,10 @@ types.Boolean = inputs.switch = {
|
|
|
73
73
|
|
|
74
74
|
types.any = inputs.object = inputConfig(() => import('./ObjectInput.vue'))
|
|
75
75
|
|
|
76
|
+
inputs.json = inputConfig(() => import('./JsonInput.vue'))
|
|
77
|
+
|
|
78
|
+
inputs.trigger = inputConfig(() => import('./TriggerInput.vue'))
|
|
79
|
+
|
|
76
80
|
|
|
77
81
|
export function provideAutoInputConfiguration() {
|
|
78
82
|
for(let type in types) {
|
|
@@ -6,6 +6,7 @@ import { synchronized, defaultData } from '@live-change/vue3-components'
|
|
|
6
6
|
import { propertiesValidationErrors } from './validation.js'
|
|
7
7
|
|
|
8
8
|
import { cyrb128 } from './utils.js'
|
|
9
|
+
import deepmerge from 'deepmerge'
|
|
9
10
|
|
|
10
11
|
export default async function actionData(options) {
|
|
11
12
|
if(!options) throw new Error('options must be provided')
|
|
@@ -81,7 +82,16 @@ export default async function actionData(options) {
|
|
|
81
82
|
|
|
82
83
|
const propertiesServerErrors = ref({})
|
|
83
84
|
const lastSentData = ref(null)
|
|
84
|
-
|
|
85
|
+
|
|
86
|
+
console.log("INITIAL VALUE", initialValue)
|
|
87
|
+
console.log("DEFAULT DATA", defaultData(action.definition))
|
|
88
|
+
|
|
89
|
+
const mergedInitialValue = deepmerge(
|
|
90
|
+
defaultData(action.definition),
|
|
91
|
+
JSON.parse(JSON.stringify(initialValue))
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
const formData = ref(mergedInitialValue)
|
|
85
95
|
const done = ref(false)
|
|
86
96
|
|
|
87
97
|
let commandPromise = null
|
|
@@ -121,7 +131,7 @@ export default async function actionData(options) {
|
|
|
121
131
|
function saveDraft(data){
|
|
122
132
|
return createOrUpdateDraftAction({ ...data, from: formData.value })
|
|
123
133
|
}
|
|
124
|
-
const source = computed(() => draftData.value?.data ||
|
|
134
|
+
const source = computed(() => draftData.value?.data || mergedInitialValue)
|
|
125
135
|
const synchronizedData = synchronized({
|
|
126
136
|
source,
|
|
127
137
|
update: saveDraft,
|
|
@@ -143,7 +153,7 @@ export default async function actionData(options) {
|
|
|
143
153
|
}
|
|
144
154
|
})
|
|
145
155
|
const changed = computed(() =>
|
|
146
|
-
JSON.stringify(
|
|
156
|
+
JSON.stringify(mergedInitialValue ?? {})
|
|
147
157
|
!== JSON.stringify({ ...synchronizedData.value.value, [timeField]: undefined })
|
|
148
158
|
)
|
|
149
159
|
|
|
@@ -172,7 +182,7 @@ export default async function actionData(options) {
|
|
|
172
182
|
if(workingZone)
|
|
173
183
|
workingZone.addPromise('discardDraft:'+serviceName+':'+actionName, discardPromise)
|
|
174
184
|
await discardPromise
|
|
175
|
-
synchronizedData.value.value = editableSavedData.value ||
|
|
185
|
+
synchronizedData.value.value = editableSavedData.value || JSON.parse(JSON.stringify(mergedInitialValue))
|
|
176
186
|
if(toast && discardedDraftToast) toast.add({ severity: 'info', summary: resetToast, life: 1500 })
|
|
177
187
|
done.value = false
|
|
178
188
|
onReset()
|
|
@@ -181,6 +191,7 @@ export default async function actionData(options) {
|
|
|
181
191
|
return {
|
|
182
192
|
parameters,
|
|
183
193
|
initialValue,
|
|
194
|
+
mergedInitialValue,
|
|
184
195
|
editableProperties,
|
|
185
196
|
value: synchronizedData.value,
|
|
186
197
|
changed,
|
|
@@ -207,12 +218,12 @@ export default async function actionData(options) {
|
|
|
207
218
|
}
|
|
208
219
|
|
|
209
220
|
const changed = computed(() =>
|
|
210
|
-
JSON.stringify(
|
|
221
|
+
JSON.stringify(mergedInitialValue ?? {})
|
|
211
222
|
!== JSON.stringify(formData.value)
|
|
212
223
|
)
|
|
213
224
|
|
|
214
225
|
function reset() {
|
|
215
|
-
formData.value = JSON.parse(JSON.stringify(
|
|
226
|
+
formData.value = JSON.parse(JSON.stringify(mergedInitialValue))
|
|
216
227
|
}
|
|
217
228
|
|
|
218
229
|
return {
|
|
@@ -93,7 +93,7 @@ export default function editorData(options) {
|
|
|
93
93
|
const removeDraftAction = draft && api.actions.draft.resetMyDraft
|
|
94
94
|
|
|
95
95
|
return Promise.all([
|
|
96
|
-
live(savedDataPath), live(draftDataPath)
|
|
96
|
+
live(savedDataPath, appContext), live(draftDataPath, appContext)
|
|
97
97
|
]).then(([savedData, draftData]) => {
|
|
98
98
|
|
|
99
99
|
const isNew = computed(() => !savedData.value)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@live-change/frontend-auto-form",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.164",
|
|
4
4
|
"scripts": {
|
|
5
5
|
"memDev": "node server/start.js memDev --enableSessions --initScript ./init.js --dbAccess",
|
|
6
6
|
"localDevInit": "rm tmp.db; lcli localDev --enableSessions --initScript ./init.js",
|
|
@@ -22,16 +22,16 @@
|
|
|
22
22
|
"type": "module",
|
|
23
23
|
"dependencies": {
|
|
24
24
|
"@fortawesome/fontawesome-free": "^6.7.2",
|
|
25
|
-
"@live-change/cli": "^0.9.
|
|
26
|
-
"@live-change/dao": "^0.9.
|
|
27
|
-
"@live-change/dao-vue3": "^0.9.
|
|
28
|
-
"@live-change/dao-websocket": "^0.9.
|
|
29
|
-
"@live-change/framework": "^0.9.
|
|
30
|
-
"@live-change/image-frontend": "^0.9.
|
|
31
|
-
"@live-change/image-service": "^0.9.
|
|
32
|
-
"@live-change/session-service": "^0.9.
|
|
33
|
-
"@live-change/vue3-components": "^0.9.
|
|
34
|
-
"@live-change/vue3-ssr": "^0.9.
|
|
25
|
+
"@live-change/cli": "^0.9.164",
|
|
26
|
+
"@live-change/dao": "^0.9.164",
|
|
27
|
+
"@live-change/dao-vue3": "^0.9.164",
|
|
28
|
+
"@live-change/dao-websocket": "^0.9.164",
|
|
29
|
+
"@live-change/framework": "^0.9.164",
|
|
30
|
+
"@live-change/image-frontend": "^0.9.164",
|
|
31
|
+
"@live-change/image-service": "^0.9.164",
|
|
32
|
+
"@live-change/session-service": "^0.9.164",
|
|
33
|
+
"@live-change/vue3-components": "^0.9.164",
|
|
34
|
+
"@live-change/vue3-ssr": "^0.9.164",
|
|
35
35
|
"@vueuse/core": "^12.3.0",
|
|
36
36
|
"codeceptjs-assert": "^0.0.5",
|
|
37
37
|
"compression": "^1.7.5",
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
"vue3-scroll-border": "0.1.7"
|
|
53
53
|
},
|
|
54
54
|
"devDependencies": {
|
|
55
|
-
"@live-change/codeceptjs-helper": "^0.9.
|
|
55
|
+
"@live-change/codeceptjs-helper": "^0.9.164",
|
|
56
56
|
"codeceptjs": "^3.6.10",
|
|
57
57
|
"generate-password": "1.7.1",
|
|
58
58
|
"playwright": "1.49.1",
|
|
@@ -63,5 +63,5 @@
|
|
|
63
63
|
"author": "Michał Łaszczewski <michal@laszczewski.pl>",
|
|
64
64
|
"license": "ISC",
|
|
65
65
|
"description": "",
|
|
66
|
-
"gitHead": "
|
|
66
|
+
"gitHead": "38f9fb8b01a9527d8f6036e174edd1fa41443301"
|
|
67
67
|
}
|