@live-change/frontend-auto-form 0.9.85 → 0.9.87
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/ActionButtons.vue +80 -0
- package/front/src/components/crud/ActionForm.vue +137 -8
- package/front/src/components/crud/AutoObjectIdentification.vue +1 -1
- package/front/src/components/crud/DefaultObjectIdentification.vue +72 -4
- package/front/src/components/crud/InjectedObjectIndentification.vue +3 -3
- package/front/src/components/crud/ModelEditor.vue +25 -8
- package/front/src/components/crud/ModelList.vue +55 -14
- package/front/src/components/crud/ModelSingle.vue +5 -5
- package/front/src/components/crud/ModelView.vue +88 -28
- package/front/src/components/schema/DataWithSchema.vue +15 -11
- package/front/src/components/schema/SchemaFromDefinition.vue +23 -0
- package/front/src/components/view/AutoView.vue +19 -4
- package/front/src/components/view/DefaultFieldView.vue +1 -1
- package/front/src/logic/actionData.js +8 -5
- package/front/src/logic/schema.js +37 -15
- package/front/src/logic/viewData.js +6 -6
- package/front/src/pages/Action.vue +9 -8
- package/front/src/pages/{Editor.vue → Create.vue} +16 -34
- package/front/src/pages/Edit.vue +76 -0
- package/front/src/pages/Models.vue +1 -1
- package/front/src/pages/View.vue +5 -30
- package/front/src/router.js +15 -3
- package/index.js +2 -0
- package/package.json +14 -14
|
@@ -1,15 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div>
|
|
3
3
|
|
|
4
|
-
<!-- <h4>identifiers</h4>
|
|
5
|
-
<pre>{{ identifiers }}</pre>
|
|
6
|
-
|
|
7
|
-
<h4>definition</h4>
|
|
8
|
-
<pre>{{ modelDefinition }}</pre>
|
|
9
|
-
|
|
10
|
-
<h4>object</h4>
|
|
11
|
-
<pre>{{ object }}</pre>-->
|
|
12
|
-
|
|
13
4
|
<div v-if="object">
|
|
14
5
|
<ObjectPath :objectType="service + '_' + model" :object="object.to ?? object.id" class="mb-6" />
|
|
15
6
|
|
|
@@ -20,12 +11,12 @@
|
|
|
20
11
|
</div>
|
|
21
12
|
<div class="flex flex-row flex-wrap justify-between align-items-top">
|
|
22
13
|
<div class="text-2xl mb-6">
|
|
23
|
-
<strong>{{ model }}</strong>
|
|
14
|
+
<strong class="mr-2">{{ model }}</strong>
|
|
24
15
|
<ObjectIdentification
|
|
25
16
|
:objectType="service + '_' + model"
|
|
26
17
|
:object="object.to ?? object.id"
|
|
27
18
|
:data="object"
|
|
28
|
-
class="
|
|
19
|
+
class=""
|
|
29
20
|
/>
|
|
30
21
|
</div>
|
|
31
22
|
<div class="flex flex-row flex-wrap justify-between align-items-top gap-2">
|
|
@@ -41,6 +32,21 @@
|
|
|
41
32
|
|
|
42
33
|
</div>
|
|
43
34
|
|
|
35
|
+
<div v-if="connectedActions"
|
|
36
|
+
class="bg-surface-0 dark:bg-surface-900 p-4 shadow-sm rounded-border mb-6">
|
|
37
|
+
<div class="text-xl mb-3">
|
|
38
|
+
Actions
|
|
39
|
+
</div>
|
|
40
|
+
<div class="flex flex-row flex-wrap gap-2">
|
|
41
|
+
<div v-for="action of connectedActions" class="mb-0">
|
|
42
|
+
<!-- <pre>{{ action }}</pre> -->
|
|
43
|
+
<router-link :to="actionRoute(action)">
|
|
44
|
+
<Button :label="action.label" icon="pi pi-play" class="p-button mb-0" />
|
|
45
|
+
</router-link>
|
|
46
|
+
</div>
|
|
47
|
+
</div>
|
|
48
|
+
</div>
|
|
49
|
+
|
|
44
50
|
<div v-for="preparedRelation of visibleObjectRelations" class="mb-6">
|
|
45
51
|
<ModelSingle :service="preparedRelation.service" :model="preparedRelation.model"
|
|
46
52
|
:views="preparedRelation.views">
|
|
@@ -98,7 +104,7 @@
|
|
|
98
104
|
|
|
99
105
|
<div class="bg-surface-0 dark:bg-surface-900 p-4 shadow-sm rounded-border">
|
|
100
106
|
|
|
101
|
-
|
|
107
|
+
<!-- <pre>visibleRangeRelations = {{ visibleRangeRelations }}</pre>
|
|
102
108
|
<pre>preparedRelations = {{ preparedRelations }}</pre>
|
|
103
109
|
|
|
104
110
|
<div v-if="backwardRelations">
|
|
@@ -109,9 +115,13 @@
|
|
|
109
115
|
)
|
|
110
116
|
}}</pre>
|
|
111
117
|
</div>
|
|
118
|
+
<pre>accessControlRoles = {{ accessControlRoles }}</pre> -->
|
|
119
|
+
|
|
120
|
+
<pre>id = {{ id }}</pre>
|
|
112
121
|
|
|
122
|
+
<pre>definition = {{ modelDefinition }}</pre>
|
|
113
123
|
|
|
114
|
-
|
|
124
|
+
<pre>object = {{ object }}</pre>
|
|
115
125
|
|
|
116
126
|
</div>
|
|
117
127
|
|
|
@@ -143,9 +153,9 @@
|
|
|
143
153
|
type: String,
|
|
144
154
|
required: true,
|
|
145
155
|
},
|
|
146
|
-
|
|
147
|
-
type:
|
|
148
|
-
|
|
156
|
+
id: {
|
|
157
|
+
type: String,
|
|
158
|
+
required: true,
|
|
149
159
|
},
|
|
150
160
|
attributes: {
|
|
151
161
|
type: Object,
|
|
@@ -156,7 +166,7 @@
|
|
|
156
166
|
default: ''
|
|
157
167
|
}
|
|
158
168
|
})
|
|
159
|
-
const { service, model,
|
|
169
|
+
const { service, model, id, attributes, i18n } = toRefs(props)
|
|
160
170
|
|
|
161
171
|
const emit = defineEmits(['saved', 'draftSaved', 'draftDiscarded', 'saveError', 'created' ])
|
|
162
172
|
|
|
@@ -178,6 +188,25 @@
|
|
|
178
188
|
return api.services?.[service.value]?.models?.[model.value]
|
|
179
189
|
})
|
|
180
190
|
|
|
191
|
+
const connectedActions = computed(() => {
|
|
192
|
+
const srcActions = modelDefinition.value?.connectedActions
|
|
193
|
+
if(!srcActions) return null
|
|
194
|
+
return Object.values(srcActions).map(action => {
|
|
195
|
+
const config = {
|
|
196
|
+
service: service.value,
|
|
197
|
+
...action
|
|
198
|
+
}
|
|
199
|
+
const actionDefinition = api.getServiceDefinition(config.service).actions[config.name]
|
|
200
|
+
if(!actionDefinition) throw new Error("Action " + config.service + "_" + config.name + " definition not found")
|
|
201
|
+
const label = actionDefinition.label ?? action.label ?? actionDefinition.name
|
|
202
|
+
return {
|
|
203
|
+
...config,
|
|
204
|
+
definition: actionDefinition,
|
|
205
|
+
label
|
|
206
|
+
}
|
|
207
|
+
})
|
|
208
|
+
})
|
|
209
|
+
|
|
181
210
|
import { getForwardRelations, getBackwardRelations, anyRelationsTypes, prepareObjectRelations }
|
|
182
211
|
from '../../logic/relations.js'
|
|
183
212
|
const forwardRelations = computed(() => getForwardRelations(modelDefinition.value, () => true, api))
|
|
@@ -188,7 +217,7 @@
|
|
|
188
217
|
const viewDataPromise = viewData({
|
|
189
218
|
service: service.value,
|
|
190
219
|
model: model.value,
|
|
191
|
-
|
|
220
|
+
id: id.value,
|
|
192
221
|
path, api
|
|
193
222
|
})
|
|
194
223
|
|
|
@@ -205,14 +234,18 @@
|
|
|
205
234
|
return prepareObjectRelations(objectType.value, object.value.to ?? object.value.id, api)
|
|
206
235
|
})
|
|
207
236
|
|
|
208
|
-
const visibleRangeRelations = computed(() => preparedRelations.value
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
237
|
+
const visibleRangeRelations = computed(() => preparedRelations.value
|
|
238
|
+
.filter(preparedRelation => !preparedRelation.singular)
|
|
239
|
+
.map(preparedRelation => {
|
|
240
|
+
const accessibleViews = preparedRelation.views.filter(view => preparedRelation.access.value[view.name])
|
|
241
|
+
if(accessibleViews.length === 0) return null
|
|
242
|
+
return {
|
|
243
|
+
...preparedRelation,
|
|
244
|
+
views: accessibleViews
|
|
245
|
+
}
|
|
246
|
+
})
|
|
247
|
+
.filter(x => x !== null)
|
|
248
|
+
)
|
|
216
249
|
|
|
217
250
|
const visibleObjectRelations = computed(() => preparedRelations.value.filter(preparedRelation => {
|
|
218
251
|
if(!preparedRelation.singular) return false
|
|
@@ -228,14 +261,41 @@
|
|
|
228
261
|
const accessControlRoles = computed(() => modelDefinition.value?.accessRoles ?? [])
|
|
229
262
|
|
|
230
263
|
const editRoute = computed(() => ({
|
|
231
|
-
name: 'auto-form:
|
|
264
|
+
name: 'auto-form:edit',
|
|
232
265
|
params: {
|
|
233
266
|
serviceName: service.value,
|
|
234
267
|
modelName: model.value,
|
|
235
|
-
|
|
268
|
+
id: id.value
|
|
236
269
|
}
|
|
237
270
|
}))
|
|
238
271
|
|
|
272
|
+
function actionRoute(action) {
|
|
273
|
+
const myType = service.value + '_' + model.value
|
|
274
|
+
const parameterName = action.objectParameter ??
|
|
275
|
+
Object.entries(action.definition.properties).find(([key, value]) => value.type === myType)?.[0] ??
|
|
276
|
+
Object.keys(action.definition.properties)?.[0]
|
|
277
|
+
|
|
278
|
+
if(parameterName) {
|
|
279
|
+
const parametersJson = JSON.stringify({
|
|
280
|
+
[parameterName]: object.value.to ?? object.value.id
|
|
281
|
+
})
|
|
282
|
+
return {
|
|
283
|
+
name: 'auto-form:actionParameters',
|
|
284
|
+
params: {
|
|
285
|
+
serviceName: action.service,
|
|
286
|
+
actionName: action.name,
|
|
287
|
+
parametersJson
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
return {
|
|
292
|
+
name: 'auto-form:action',
|
|
293
|
+
params: {
|
|
294
|
+
serviceName: action.service,
|
|
295
|
+
actionName: action.name
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
}
|
|
239
299
|
|
|
240
300
|
</script>
|
|
241
301
|
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
2
|
+
<pre>
|
|
3
|
+
#### {{ prefix }} Data Schema
|
|
4
|
+
|
|
5
|
+
{{ JSON.stringify(schema, null, 2) }}
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
#### {{ prefix }} Data:
|
|
9
|
+
|
|
10
|
+
{{ JSON.stringify(clearData, null, 2) }}
|
|
11
|
+
</pre>
|
|
12
12
|
</template>
|
|
13
13
|
|
|
14
14
|
<script setup>
|
|
@@ -19,7 +19,11 @@
|
|
|
19
19
|
data: {
|
|
20
20
|
type: Object,
|
|
21
21
|
required: true,
|
|
22
|
-
}
|
|
22
|
+
},
|
|
23
|
+
prefix: {
|
|
24
|
+
type: String,
|
|
25
|
+
default: ''
|
|
26
|
+
}
|
|
23
27
|
})
|
|
24
28
|
const { data } = toRefs(props)
|
|
25
29
|
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<pre>{{ schema }}</pre>
|
|
3
|
+
</template>
|
|
4
|
+
|
|
5
|
+
<script setup>
|
|
6
|
+
|
|
7
|
+
import { schemaFromDefinition } from "../../logic/schema.js"
|
|
8
|
+
import { defineProps, toRefs, computed, getCurrentInstance } from "vue"
|
|
9
|
+
|
|
10
|
+
const props = defineProps({
|
|
11
|
+
definition: {
|
|
12
|
+
type: Object,
|
|
13
|
+
required: true,
|
|
14
|
+
}
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
const { definition } = toRefs(props)
|
|
18
|
+
|
|
19
|
+
const appContext = getCurrentInstance().appContext
|
|
20
|
+
|
|
21
|
+
const schema = computed(() => schemaFromDefinition(definition.value, undefined, undefined, appContext))
|
|
22
|
+
|
|
23
|
+
</script>
|
|
@@ -85,12 +85,25 @@
|
|
|
85
85
|
filter: viewFilter.value
|
|
86
86
|
}))
|
|
87
87
|
|
|
88
|
+
import { useApi } from '@live-change/vue3-ssr'
|
|
89
|
+
const api = useApi()
|
|
90
|
+
|
|
88
91
|
const viewComponent = computed(() => {
|
|
89
92
|
const type = definition.value.type ?? 'Object'
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
93
|
+
let defaultComponent = undefined
|
|
94
|
+
if(type.indexOf('_') > 0) {
|
|
95
|
+
const [service, model] = type.split('_')
|
|
96
|
+
const modelDefinition = api.getServiceDefinition(service)?.models[model]
|
|
97
|
+
if(modelDefinition) {
|
|
98
|
+
defaultComponent = defineAsyncComponent(() => import('../crud/InjectedObjectIndentification.vue'))
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
if(!defaultComponent) {
|
|
102
|
+
defaultComponent = (type === 'Object')
|
|
103
|
+
? defineAsyncComponent(() => import('./ObjectView.vue'))
|
|
104
|
+
: defineAsyncComponent(() => import('./JsonView.vue'))
|
|
105
|
+
}
|
|
106
|
+
return injectComponent(viewComponentRequest.value, defaultComponent)
|
|
94
107
|
})
|
|
95
108
|
|
|
96
109
|
const viewClass = computed(() => [definition.value?.view?.class, props.class])
|
|
@@ -102,6 +115,8 @@
|
|
|
102
115
|
...(definition.value?.view?.attributes),
|
|
103
116
|
...(props.attributes),
|
|
104
117
|
value: value.value,
|
|
118
|
+
type: definition.value.type,
|
|
119
|
+
object: value.value,
|
|
105
120
|
definition: definition.value,
|
|
106
121
|
class: viewClass.value,
|
|
107
122
|
style: viewStyle.value,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="field" :class="fieldClass" :style="fieldStyle">
|
|
2
|
+
<div class="field flex flex-col" :class="fieldClass" :style="fieldStyle">
|
|
3
3
|
<slot name="label"
|
|
4
4
|
v-bind="{ uid, value, definition, viewClass, viewStyle, attributes, propName, rootValue, i18n }">
|
|
5
5
|
<label :for="uid" class="font-medium text-lg">{{ t( label ) }}</label>
|
|
@@ -11,7 +11,7 @@ export default async function actionData(options) {
|
|
|
11
11
|
if(!options) throw new Error('options must be provided')
|
|
12
12
|
|
|
13
13
|
const {
|
|
14
|
-
parameters,
|
|
14
|
+
parameters = {},
|
|
15
15
|
initialValue = {},
|
|
16
16
|
|
|
17
17
|
service: serviceName,
|
|
@@ -50,7 +50,10 @@ export default async function actionData(options) {
|
|
|
50
50
|
if(!service) throw new Error('service must be defined in options')
|
|
51
51
|
const action = service.actions[actionName]
|
|
52
52
|
if(!action) throw new Error('action must be defined in options')
|
|
53
|
-
|
|
53
|
+
|
|
54
|
+
const editableProperties = (action.definition.editableProperties ?? Object.keys(action.definition.properties))
|
|
55
|
+
.filter(key => !parameters[key])
|
|
56
|
+
|
|
54
57
|
let draftIdParts = []
|
|
55
58
|
let idKey = null
|
|
56
59
|
for(const [parameterName, parameter] of Object.entries(parameters || {})) {
|
|
@@ -152,7 +155,6 @@ export default async function actionData(options) {
|
|
|
152
155
|
const result = await submitData(synchronizedData.value.value)
|
|
153
156
|
if(result === Error) return // silent return on error, because it's handled in onError
|
|
154
157
|
if(draftData.value) await removeDraftAction(draftIdentifiers)
|
|
155
|
-
onDone(result)
|
|
156
158
|
if(toast && doneToast) toast.add({ severity: 'success', summary: doneToast, life: 1500 })
|
|
157
159
|
}
|
|
158
160
|
|
|
@@ -179,6 +181,7 @@ export default async function actionData(options) {
|
|
|
179
181
|
return {
|
|
180
182
|
parameters,
|
|
181
183
|
initialValue,
|
|
184
|
+
editableProperties,
|
|
182
185
|
value: synchronizedData.value,
|
|
183
186
|
changed,
|
|
184
187
|
submit,
|
|
@@ -200,7 +203,6 @@ export default async function actionData(options) {
|
|
|
200
203
|
async function submit() {
|
|
201
204
|
const result = await submitData(formData.value)
|
|
202
205
|
if(result === Error) return // silent return on error, because it's handled in onError
|
|
203
|
-
onSaved(result)
|
|
204
206
|
if(toast && doneToast) toast.add({ severity: 'success', summary: doneToast, life: 1500 })
|
|
205
207
|
}
|
|
206
208
|
|
|
@@ -214,8 +216,9 @@ export default async function actionData(options) {
|
|
|
214
216
|
}
|
|
215
217
|
|
|
216
218
|
return {
|
|
217
|
-
parameters,
|
|
219
|
+
parameters,
|
|
218
220
|
initialValue,
|
|
221
|
+
editableProperties,
|
|
219
222
|
value: formData,
|
|
220
223
|
changed,
|
|
221
224
|
submit,
|
|
@@ -28,27 +28,49 @@ function addSchema(schemas, schema) {
|
|
|
28
28
|
export function schemaFromDefinition(definition, data, type, appContext = getCurrentInstance().appContext) {
|
|
29
29
|
if(!type) type = definition.type
|
|
30
30
|
if(type === 'Object') {
|
|
31
|
+
const properties = Object.fromEntries(
|
|
32
|
+
Object.entries(definition.properties).map(
|
|
33
|
+
([key, value]) => [key, schemaFromDefinition(value, data?.[key], undefined, appContext)])
|
|
34
|
+
)
|
|
35
|
+
for(const key in definition.properties) {
|
|
36
|
+
const prop = definition.properties[key]
|
|
37
|
+
if(key.endsWith('Type') && prop.type === 'type') {
|
|
38
|
+
const keyWithoutType = key.slice(0, -4)
|
|
39
|
+
properties[key] = {
|
|
40
|
+
type: 'string',
|
|
41
|
+
enum: prop.enum,
|
|
42
|
+
enumDescriptions: prop.enumDescriptions,
|
|
43
|
+
description: `Type of ${keyWithoutType}`,
|
|
44
|
+
}
|
|
45
|
+
properties[keyWithoutType] = {
|
|
46
|
+
type: 'string',
|
|
47
|
+
description: `Id of Object with type defined in ${key}`,
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
31
51
|
return {
|
|
32
52
|
type: 'object',
|
|
33
|
-
properties
|
|
34
|
-
|
|
35
|
-
),
|
|
36
|
-
description: definition.description
|
|
53
|
+
properties,
|
|
54
|
+
description: definition.description,
|
|
37
55
|
}
|
|
38
56
|
} else if(type === 'Array') {
|
|
39
57
|
const schema = {
|
|
40
58
|
type: 'array',
|
|
41
|
-
items: schemaFromDefinition(definition.items ?? definition.of, data[0], undefined, appContext),
|
|
42
|
-
description: definition.description
|
|
59
|
+
items: schemaFromDefinition(definition.items ?? definition.of, data?.[0], undefined, appContext),
|
|
60
|
+
description: definition.description,
|
|
43
61
|
}
|
|
44
|
-
|
|
45
|
-
|
|
62
|
+
if(data) {
|
|
63
|
+
for(const item of data) {
|
|
64
|
+
extendSchema(schema.items, item, schema.items.modelName, schema.items.serviceName)
|
|
65
|
+
}
|
|
46
66
|
}
|
|
47
67
|
return schema
|
|
48
68
|
} else if(type === 'String') {
|
|
49
69
|
return {
|
|
50
70
|
type: 'string',
|
|
51
|
-
description: definition.description
|
|
71
|
+
description: definition.description,
|
|
72
|
+
enum: definition.enum,
|
|
73
|
+
enumDescriptions: definition.enumDescriptions
|
|
52
74
|
}
|
|
53
75
|
} else if(type === 'Number') {
|
|
54
76
|
return {
|
|
@@ -70,9 +92,8 @@ export function schemaFromDefinition(definition, data, type, appContext = getCur
|
|
|
70
92
|
const api = useApi(appContext)
|
|
71
93
|
const [serviceName, modelName] = definition.type.split('_')
|
|
72
94
|
const serviceDefinition = api.getServiceDefinition(serviceName)
|
|
73
|
-
const modelDefinition = serviceDefinition?.models?.[modelName]
|
|
74
|
-
|
|
75
|
-
if(typeof data === 'string') {
|
|
95
|
+
const modelDefinition = serviceDefinition?.models?.[modelName]
|
|
96
|
+
if(!data || typeof data === 'string') {
|
|
76
97
|
return {
|
|
77
98
|
type: 'string',
|
|
78
99
|
description: `Id of ${modelName} from ${serviceName} service.`
|
|
@@ -94,6 +115,7 @@ export function schemaFromDefinition(definition, data, type, appContext = getCur
|
|
|
94
115
|
}
|
|
95
116
|
|
|
96
117
|
function extendSchema(schema, data, viewName, serviceName, appContext) {
|
|
118
|
+
if(!data) return
|
|
97
119
|
if(Array.isArray(data)) {
|
|
98
120
|
if(!schema.items) {
|
|
99
121
|
schema.items = generateSchema(data, schema, 'items', appContext)
|
|
@@ -108,7 +130,7 @@ function extendSchema(schema, data, viewName, serviceName, appContext) {
|
|
|
108
130
|
description: schema.modelName ? `Id of ${schema.modelName} from ${schema.serviceName} service.` : `Id.`
|
|
109
131
|
}
|
|
110
132
|
} else {
|
|
111
|
-
generateSchema(value, schema.properties, property)
|
|
133
|
+
generateSchema(value, schema.properties, property, appContext)
|
|
112
134
|
}
|
|
113
135
|
}
|
|
114
136
|
}
|
|
@@ -116,7 +138,7 @@ function extendSchema(schema, data, viewName, serviceName, appContext) {
|
|
|
116
138
|
}
|
|
117
139
|
|
|
118
140
|
function generateSchema(data, schemaObject, schemaProperty, appContext) {
|
|
119
|
-
const api = useApi(appContext)
|
|
141
|
+
const api = useApi(appContext)
|
|
120
142
|
if(!schemaObject[schemaProperty]) {
|
|
121
143
|
schemaObject[schemaProperty] = {
|
|
122
144
|
anyOf: []
|
|
@@ -180,4 +202,4 @@ export function cleanData(data) {
|
|
|
180
202
|
}
|
|
181
203
|
return cleanedProperties
|
|
182
204
|
}
|
|
183
|
-
}
|
|
205
|
+
}
|
|
@@ -5,7 +5,7 @@ export default async function viewData(options) {
|
|
|
5
5
|
if(!options) throw new Error('options must be provided')
|
|
6
6
|
|
|
7
7
|
const {
|
|
8
|
-
|
|
8
|
+
id,
|
|
9
9
|
service: serviceName,
|
|
10
10
|
model: modelName,
|
|
11
11
|
|
|
@@ -13,22 +13,22 @@ export default async function viewData(options) {
|
|
|
13
13
|
api = useApi(),
|
|
14
14
|
} = options
|
|
15
15
|
|
|
16
|
-
if(!
|
|
16
|
+
if(!id) throw new Error('id must be defined')
|
|
17
17
|
if(!serviceName || !modelName) throw new Error('service and model must be defined')
|
|
18
18
|
|
|
19
19
|
const service = api.services[serviceName]
|
|
20
20
|
const model = service.models[modelName]
|
|
21
21
|
const {
|
|
22
|
-
crudMethods = model.crud
|
|
23
|
-
identifiersNames = model.identifiers,
|
|
22
|
+
crudMethods = model.crud
|
|
24
23
|
//editableProperties = model.editableProperties ?? Object.keys(model.properties)
|
|
25
24
|
} = options
|
|
26
25
|
|
|
27
26
|
if(!crudMethods) throw new Error('crud methods must be defined in model or options')
|
|
28
|
-
if(!identifiersNames) throw new Error('identifiers names must be defined in model or options')
|
|
29
27
|
// if(!editableProperties) throw new Error('editableProperties must be defined in model or options')
|
|
30
28
|
|
|
31
|
-
const savedDataPath = path[serviceName][crudMethods.read](
|
|
29
|
+
const savedDataPath = path[serviceName][crudMethods.read]({
|
|
30
|
+
[modelName[0].toLowerCase() + modelName.slice(1)]: id
|
|
31
|
+
})
|
|
32
32
|
|
|
33
33
|
let data
|
|
34
34
|
let error
|
|
@@ -1,18 +1,14 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="w-full lg:w-8/12 md:w-11/12">
|
|
3
3
|
<div class="bg-surface-0 dark:bg-surface-900 p-4 shadow-sm rounded-border">
|
|
4
|
-
<div class="text-xl mb-2">
|
|
5
|
-
Service <strong>{{ serviceName }}</strong>
|
|
6
|
-
</div>
|
|
7
|
-
<div class="text-2xl mb-4">
|
|
8
|
-
Action <strong>{{ actionName }}</strong>
|
|
9
|
-
</div>
|
|
10
4
|
|
|
11
5
|
<ActionForm
|
|
12
6
|
:service="serviceName"
|
|
13
|
-
:action="actionName"
|
|
7
|
+
:action="actionName"
|
|
8
|
+
:parameters="parameters"
|
|
14
9
|
@done="handleDone"
|
|
15
10
|
/>
|
|
11
|
+
|
|
16
12
|
</div>
|
|
17
13
|
</div>
|
|
18
14
|
</template>
|
|
@@ -29,9 +25,14 @@
|
|
|
29
25
|
actionName: {
|
|
30
26
|
type: String,
|
|
31
27
|
required: true
|
|
28
|
+
},
|
|
29
|
+
parametersJson: {
|
|
30
|
+
type: String
|
|
32
31
|
}
|
|
33
32
|
})
|
|
34
|
-
const { serviceName, actionName } = toRefs(props)
|
|
33
|
+
const { serviceName, actionName, parametersJson } = toRefs(props)
|
|
34
|
+
|
|
35
|
+
const parameters = computed(() => parametersJson.value ? JSON.parse(parametersJson.value) : {})
|
|
35
36
|
|
|
36
37
|
import { useApi } from '@live-change/vue3-ssr'
|
|
37
38
|
const api = useApi()
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
<div class="bg-surface-0 dark:bg-surface-900 p-4 shadow-sm rounded-border">
|
|
9
9
|
|
|
10
10
|
<ModelEditor :service="serviceName" :model="modelName" :identifiers="identifiersObject" draft
|
|
11
|
-
@created="handleCreated"/>
|
|
11
|
+
@created="handleCreated" @saved="handleSaved" />
|
|
12
12
|
|
|
13
13
|
</div>
|
|
14
14
|
</div>
|
|
@@ -29,20 +29,12 @@
|
|
|
29
29
|
type: String,
|
|
30
30
|
required: true,
|
|
31
31
|
},
|
|
32
|
-
|
|
32
|
+
identifiersWithNames: {
|
|
33
33
|
type: Array,
|
|
34
34
|
default: () => []
|
|
35
|
-
},
|
|
36
|
-
identifiersTypes: {
|
|
37
|
-
type: Array,
|
|
38
|
-
default: () => undefined
|
|
39
|
-
},
|
|
40
|
-
identifiersProperties: {
|
|
41
|
-
type: Array,
|
|
42
|
-
default: () => undefined
|
|
43
35
|
}
|
|
44
36
|
})
|
|
45
|
-
const { serviceName, modelName,
|
|
37
|
+
const { serviceName, modelName, identifiersWithNames } = toRefs(props)
|
|
46
38
|
|
|
47
39
|
import { useApi, usePath, live } from '@live-change/vue3-ssr'
|
|
48
40
|
const api = useApi()
|
|
@@ -58,13 +50,10 @@
|
|
|
58
50
|
|
|
59
51
|
const identifiersObject = computed(() => {
|
|
60
52
|
const result = {}
|
|
61
|
-
for(
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
} else {
|
|
66
|
-
result[identifierDefinition.name] = identifier
|
|
67
|
-
}
|
|
53
|
+
for(let i = 0; i < identifiersWithNames.value.length; i+=2) {
|
|
54
|
+
const name = identifiersWithNames.value[i]
|
|
55
|
+
const identifier = identifiersWithNames.value[i+1]
|
|
56
|
+
result[name] = identifier
|
|
68
57
|
}
|
|
69
58
|
return result
|
|
70
59
|
})
|
|
@@ -73,24 +62,17 @@
|
|
|
73
62
|
const router = useRouter()
|
|
74
63
|
|
|
75
64
|
function handleCreated(id) {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
65
|
+
console.log("HANDLE CREATED", id)
|
|
66
|
+
//console.log("newIdentifiers", newIdentifiers)
|
|
67
|
+
router.push({
|
|
68
|
+
name: 'auto-form:view',
|
|
69
|
+
params: {
|
|
70
|
+
serviceName: serviceName.value,
|
|
71
|
+
modelName: modelName.value,
|
|
72
|
+
id
|
|
79
73
|
}
|
|
80
|
-
return identifiers.value[i]
|
|
81
74
|
})
|
|
82
|
-
|
|
83
|
-
//console.log("newIdentifiers", newIdentifiers)
|
|
84
|
-
if(JSON.stringify(identifiers.value) !== JSON.stringify(newIdentifiers)) {
|
|
85
|
-
router.push({
|
|
86
|
-
name: 'auto-form:editor',
|
|
87
|
-
params: {
|
|
88
|
-
serviceName: serviceName.value,
|
|
89
|
-
modelName: modelName.value,
|
|
90
|
-
identifiers: newIdentifiers
|
|
91
|
-
}
|
|
92
|
-
})
|
|
93
|
-
}
|
|
75
|
+
|
|
94
76
|
}
|
|
95
77
|
|
|
96
78
|
</script>
|