@ederzeel/nuxt-schema-form-nightly 0.1.0-29104388.947c8fa → 0.1.0-29104758.61b406e
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/dist/runtime/components/Array.vue +116 -71
- package/package.json +2 -1
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
<script lang="ts" setup>
|
|
2
2
|
import { Draft2019 } from 'json-schema-library'
|
|
3
3
|
import SComponent from './Component.vue'
|
|
4
|
-
import { ref, computed } from 'vue'
|
|
4
|
+
import { ref, computed, h, resolveComponent } from 'vue'
|
|
5
|
+
import type { TableColumn } from '@nuxt/ui'
|
|
6
|
+
import type { Row } from '@tanstack/vue-table'
|
|
7
|
+
|
|
8
|
+
const UDropdownMenu = resolveComponent('UDropdownMenu')
|
|
9
|
+
const UButton = resolveComponent('UButton')
|
|
5
10
|
|
|
6
11
|
const props = defineProps<{
|
|
7
12
|
id: string
|
|
@@ -9,18 +14,20 @@ const props = defineProps<{
|
|
|
9
14
|
description?: string
|
|
10
15
|
jsonSchemaPath: string
|
|
11
16
|
items: PropertiesType
|
|
12
|
-
modelValue: unknown[]
|
|
17
|
+
modelValue: Record<string, unknown>[]
|
|
13
18
|
isRequired: boolean
|
|
14
19
|
minItems?: number
|
|
15
20
|
maxItems?: number
|
|
16
21
|
edit?: boolean
|
|
17
|
-
columns?:
|
|
22
|
+
columns?: TableColumn<{}>[]
|
|
18
23
|
editInline?: boolean
|
|
19
24
|
}>()
|
|
20
25
|
|
|
21
26
|
type ColumnItem = {
|
|
22
27
|
key: string
|
|
23
28
|
label?: string
|
|
29
|
+
header?: string
|
|
30
|
+
accessorKey?: string
|
|
24
31
|
class?: string
|
|
25
32
|
}
|
|
26
33
|
|
|
@@ -31,7 +38,7 @@ type PropertiesType = {
|
|
|
31
38
|
[key: string]: unknown
|
|
32
39
|
}
|
|
33
40
|
const emit = defineEmits(['update:modelValue', 'submit'])
|
|
34
|
-
const onInput = (value:
|
|
41
|
+
const onInput = (value: Record<string, unknown>, index: number) => {
|
|
35
42
|
props.modelValue[index] = value
|
|
36
43
|
emit('update:modelValue', props.modelValue)
|
|
37
44
|
}
|
|
@@ -55,7 +62,7 @@ const add = () => {
|
|
|
55
62
|
|
|
56
63
|
const remove = (index: number) => {
|
|
57
64
|
const res = props.modelValue.splice(index, 1)
|
|
58
|
-
emit('update:modelValue',
|
|
65
|
+
emit('update:modelValue', props.modelValue)
|
|
59
66
|
}
|
|
60
67
|
|
|
61
68
|
const massRemove = () => {
|
|
@@ -67,33 +74,16 @@ const massRemove = () => {
|
|
|
67
74
|
emit('update:modelValue', res)
|
|
68
75
|
}
|
|
69
76
|
|
|
70
|
-
const model = ref({
|
|
77
|
+
const model = ref<{ open: boolean; index: number; value: Record<string, unknown> }>({
|
|
71
78
|
open: false,
|
|
72
|
-
index: 0
|
|
79
|
+
index: 0,
|
|
80
|
+
value: {}
|
|
73
81
|
})
|
|
74
82
|
|
|
75
83
|
const open = (index: number) => {
|
|
76
|
-
model.value = { open: true, index: index }
|
|
84
|
+
model.value = { open: true, index: index, value: structuredClone(values.value[index]) }
|
|
77
85
|
}
|
|
78
86
|
|
|
79
|
-
const actions = (i: number) => [
|
|
80
|
-
[
|
|
81
|
-
{
|
|
82
|
-
label: 'edit',
|
|
83
|
-
click: () => open(i)
|
|
84
|
-
}
|
|
85
|
-
],
|
|
86
|
-
[
|
|
87
|
-
{
|
|
88
|
-
label: 'delete',
|
|
89
|
-
click: () => {
|
|
90
|
-
remove(i)
|
|
91
|
-
selectedRows.value = []
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
]
|
|
95
|
-
]
|
|
96
|
-
|
|
97
87
|
const massActions = [
|
|
98
88
|
[
|
|
99
89
|
{
|
|
@@ -106,39 +96,86 @@ const massActions = [
|
|
|
106
96
|
]
|
|
107
97
|
]
|
|
108
98
|
|
|
109
|
-
const columns = computed(() => {
|
|
99
|
+
const columns = computed<TableColumn<{}>[]>(() => {
|
|
110
100
|
const columns = props.columns ?? []
|
|
101
|
+
if (props.editInline) {
|
|
102
|
+
columns.push({
|
|
103
|
+
id: 'expand',
|
|
104
|
+
cell: ({ row }) =>
|
|
105
|
+
h(UButton, {
|
|
106
|
+
color: 'neutral',
|
|
107
|
+
variant: 'ghost',
|
|
108
|
+
icon: 'i-lucide-chevron-down',
|
|
109
|
+
square: true,
|
|
110
|
+
'aria-label': 'Expand',
|
|
111
|
+
ui: {
|
|
112
|
+
leadingIcon: ['transition-transform', row.getIsExpanded() ? 'duration-200 rotate-180' : '']
|
|
113
|
+
},
|
|
114
|
+
onClick: () => row.toggleExpanded()
|
|
115
|
+
})
|
|
116
|
+
})
|
|
117
|
+
}
|
|
111
118
|
|
|
112
119
|
if (props.items.type === 'object') {
|
|
113
|
-
for (const column of Object.keys(props?.items?.properties).map(x => ({
|
|
120
|
+
for (const column of Object.keys(props?.items?.properties).map<TableColumn<{}>>(x => ({
|
|
121
|
+
header: x,
|
|
122
|
+
accessorKey: x,
|
|
123
|
+
cell: ({ row }) => row.getValue(x)
|
|
124
|
+
}))) {
|
|
114
125
|
columns.push(column)
|
|
115
126
|
}
|
|
116
127
|
}
|
|
117
128
|
|
|
118
129
|
if (props.edit) {
|
|
119
130
|
columns.push({
|
|
120
|
-
|
|
121
|
-
|
|
131
|
+
id: 'actions',
|
|
132
|
+
cell: ({ row }) => {
|
|
133
|
+
return h(
|
|
134
|
+
'div',
|
|
135
|
+
{ class: 'text-right' },
|
|
136
|
+
h(
|
|
137
|
+
UDropdownMenu,
|
|
138
|
+
{
|
|
139
|
+
content: {
|
|
140
|
+
align: 'end'
|
|
141
|
+
},
|
|
142
|
+
items: getRowItems(row),
|
|
143
|
+
'aria-label': 'Actions dropdown'
|
|
144
|
+
},
|
|
145
|
+
() =>
|
|
146
|
+
h(UButton, {
|
|
147
|
+
icon: 'i-lucide-ellipsis-vertical',
|
|
148
|
+
color: 'neutral',
|
|
149
|
+
variant: 'ghost',
|
|
150
|
+
class: 'ml-auto',
|
|
151
|
+
'aria-label': 'Actions dropdown'
|
|
152
|
+
})
|
|
153
|
+
)
|
|
154
|
+
)
|
|
155
|
+
}
|
|
122
156
|
})
|
|
123
157
|
}
|
|
124
158
|
|
|
125
159
|
return columns
|
|
126
160
|
})
|
|
127
161
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
]
|
|
162
|
+
function getRowItems(row: Row<{}>) {
|
|
163
|
+
return [
|
|
164
|
+
{
|
|
165
|
+
label: 'edit',
|
|
166
|
+
onSelect: () => open(row.index)
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
label: 'delete',
|
|
170
|
+
onSelect: () => {
|
|
171
|
+
remove(row.index)
|
|
172
|
+
selectedRows.value = []
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
]
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
const selectedRows = ref<{ __id: any }[]>([])
|
|
142
179
|
|
|
143
180
|
const expand = ref({
|
|
144
181
|
openedRows: [],
|
|
@@ -146,7 +183,16 @@ const expand = ref({
|
|
|
146
183
|
})
|
|
147
184
|
|
|
148
185
|
const options = computed(() => {
|
|
149
|
-
|
|
186
|
+
let res: {
|
|
187
|
+
modelValue?: any
|
|
188
|
+
'onUpdate:modelValue'?: (v: any) => void
|
|
189
|
+
expand?: {
|
|
190
|
+
openedRows: any[]
|
|
191
|
+
row: null
|
|
192
|
+
}
|
|
193
|
+
'update:expand'?: (v: any) => void
|
|
194
|
+
} = {}
|
|
195
|
+
|
|
150
196
|
if (props.edit) {
|
|
151
197
|
res.modelValue = selectedRows.value
|
|
152
198
|
res['onUpdate:modelValue'] = value => (selectedRows.value = value)
|
|
@@ -155,6 +201,7 @@ const options = computed(() => {
|
|
|
155
201
|
res.expand = expand.value
|
|
156
202
|
res['update:expand'] = value => (expand.value = value)
|
|
157
203
|
}
|
|
204
|
+
|
|
158
205
|
return res
|
|
159
206
|
})
|
|
160
207
|
</script>
|
|
@@ -176,39 +223,37 @@ const options = computed(() => {
|
|
|
176
223
|
</UDropdownMenu>
|
|
177
224
|
</div>
|
|
178
225
|
</div>
|
|
179
|
-
<UTable v-bind="options" by="__id" :
|
|
180
|
-
<template #
|
|
181
|
-
|
|
182
|
-
row.name
|
|
183
|
-
}}</span>
|
|
184
|
-
</template>
|
|
185
|
-
|
|
186
|
-
<template #expand="{ row, index }">
|
|
226
|
+
<UTable v-bind="options" by="__id" :data="values" :columns="columns" class="flex-1">
|
|
227
|
+
<template #expanded="{ row }">
|
|
228
|
+
{{ row }}
|
|
187
229
|
<div class="p-4">
|
|
188
|
-
<SComponent :id="id.length <= 0 ? `${index}` : `${id}[${index}].${items.id}`"
|
|
189
|
-
:json-schema-path="jsonSchemaPath?.length <= 0 ? `properties.${index}` : `${jsonSchemaPath}[${index}]`
|
|
190
|
-
|
|
230
|
+
<SComponent :id="id.length <= 0 ? `${row.index}` : `${id}[${row.index}].${items.id}`"
|
|
231
|
+
:model-value="row.original" :json-schema-path="jsonSchemaPath?.length <= 0 ? `properties.${row.index}` : `${jsonSchemaPath}[${row.index}]`
|
|
232
|
+
" v-bind="items" :isRequired="false" class="mt-4"
|
|
233
|
+
@update:model-value="(event: Record<string, unknown>) => onInput(event, row.index)"
|
|
191
234
|
@submit="() => emit('submit')" />
|
|
192
235
|
</div>
|
|
193
236
|
</template>
|
|
194
|
-
|
|
195
|
-
<template #actions-data="{ index }">
|
|
196
|
-
<UDropdownMenu :items="actions(index)">
|
|
197
|
-
<UButton color="neutral" variant="ghost" icon="i-heroicons-ellipsis-horizontal-20-solid" />
|
|
198
|
-
</UDropdownMenu>
|
|
199
|
-
</template>
|
|
200
237
|
</UTable>
|
|
201
238
|
</div>
|
|
202
239
|
<UModal v-model:open="model.open">
|
|
203
|
-
<
|
|
204
|
-
<
|
|
205
|
-
:
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
240
|
+
<template #content>
|
|
241
|
+
<UCard>
|
|
242
|
+
<SComponent :id="id.length <= 0 ? `${model.index}` : `${id}[0].${items.id}`" :model-value="model.value"
|
|
243
|
+
:json-schema-path="jsonSchemaPath?.length <= 0 ? `properties.${model.index}` : `${jsonSchemaPath}[${model.index}]`
|
|
244
|
+
" v-bind="items" :isRequired="false" class="mt-4"
|
|
245
|
+
@update:model-value="(event: Record<string, unknown>) => (model.value = event)"
|
|
246
|
+
@submit="() => emit('submit')" />
|
|
247
|
+
<template #footer>
|
|
248
|
+
<UButton @click="
|
|
249
|
+
() => {
|
|
250
|
+
onInput(model.value, model.index)
|
|
251
|
+
model.open = false
|
|
252
|
+
}
|
|
253
|
+
">Save</UButton>
|
|
254
|
+
</template>
|
|
255
|
+
</UCard>
|
|
256
|
+
</template>
|
|
212
257
|
</UModal>
|
|
213
258
|
</div>
|
|
214
259
|
</template>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ederzeel/nuxt-schema-form-nightly",
|
|
3
|
-
"version": "0.1.0-
|
|
3
|
+
"version": "0.1.0-29104758.61b406e",
|
|
4
4
|
"description": "A runtime form generator for nuxt",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -52,6 +52,7 @@
|
|
|
52
52
|
"@nuxt/kit": "^3.15.4",
|
|
53
53
|
"@nuxt/module-builder": "^0.8.4",
|
|
54
54
|
"@nuxt/ui": "^3.0.0",
|
|
55
|
+
"@tanstack/vue-table": "^8.21.3",
|
|
55
56
|
"@types/eslint": "^9.6.1",
|
|
56
57
|
"eslint": "^9.19.0",
|
|
57
58
|
"eslint-config-prettier": "^10.0.1",
|