atom-nuxt 1.1.0 → 1.3.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/dist/module.cjs +5 -0
- package/dist/module.d.mts +1 -2
- package/dist/module.d.ts +22 -0
- package/dist/module.json +3 -3
- package/dist/runtime/components/AlertDisplay.vue +18 -11
- package/dist/runtime/components/CrudAddressSearchField.vue +35 -22
- package/dist/runtime/components/CrudApiSelectorField.vue +24 -11
- package/dist/runtime/components/CrudConfirmDialog.vue +17 -11
- package/dist/runtime/components/CrudErrorDisplay.vue +4 -3
- package/dist/runtime/components/CrudFilter.vue +46 -25
- package/dist/runtime/components/CrudFilterList.vue +6 -0
- package/dist/runtime/components/CrudFormDialog.vue +16 -6
- package/dist/runtime/components/CrudFormLoader.vue +121 -98
- package/dist/runtime/components/CrudListLoader.vue +28 -17
- package/dist/runtime/components/CrudPaginatedLoader.vue +93 -57
- package/dist/runtime/components/CrudUploadField.vue +28 -6
- package/dist/runtime/components/CrudUploadFieldSelection.vue +27 -19
- package/dist/types.d.mts +2 -4
- package/dist/types.d.ts +7 -0
- package/package.json +1 -1
- package/dist/runtime/components/AlertDisplay.vue.d.ts +0 -2
- package/dist/runtime/components/CrudAddressSearchField.vue.d.ts +0 -8
- package/dist/runtime/components/CrudApiSelectorField.vue.d.ts +0 -30
- package/dist/runtime/components/CrudConfirmDialog.vue.d.ts +0 -18
- package/dist/runtime/components/CrudErrorDisplay.vue.d.ts +0 -6
- package/dist/runtime/components/CrudFilter.vue.d.ts +0 -8
- package/dist/runtime/components/CrudFilterList.vue.d.ts +0 -5
- package/dist/runtime/components/CrudFormDialog.vue.d.ts +0 -33
- package/dist/runtime/components/CrudFormLoader.vue.d.ts +0 -41
- package/dist/runtime/components/CrudListLoader.vue.d.ts +0 -37
- package/dist/runtime/components/CrudPaginatedLoader.vue.d.ts +0 -75
- package/dist/runtime/components/CrudUploadField.vue.d.ts +0 -23
- package/dist/runtime/components/CrudUploadFieldSelection.vue.d.ts +0 -18
|
@@ -1,99 +1,102 @@
|
|
|
1
1
|
<script setup async>
|
|
2
|
-
import { computed, watch } from
|
|
3
|
-
import { useCrudConverters } from
|
|
4
|
-
import { useCrudApi } from
|
|
5
|
-
import { useListenerService } from
|
|
6
|
-
import CrudFormDialog from
|
|
7
|
-
import { useRoute, useRouter } from
|
|
8
|
-
|
|
9
|
-
const
|
|
2
|
+
import { computed, watch } from 'vue'
|
|
3
|
+
import { useCrudConverters } from '../composables/useCrudConverters'
|
|
4
|
+
import { useCrudApi } from '../composables/useCrudApi'
|
|
5
|
+
import { useListenerService } from '../composables/useListenerService'
|
|
6
|
+
import CrudFormDialog from './CrudFormDialog.vue'
|
|
7
|
+
import { useRoute, useRouter } from '#app'
|
|
8
|
+
|
|
9
|
+
const { cloneDeep } = useCrudConverters()
|
|
10
|
+
|
|
11
|
+
const emits = defineEmits(['update', 'delete', 'create'])
|
|
12
|
+
|
|
10
13
|
const props = defineProps({
|
|
11
14
|
loaderKey: {
|
|
12
15
|
type: String,
|
|
13
|
-
required: false
|
|
16
|
+
required: false,
|
|
14
17
|
},
|
|
15
18
|
initialItem: {
|
|
16
19
|
type: Object,
|
|
17
|
-
required: false
|
|
20
|
+
required: false,
|
|
18
21
|
},
|
|
19
22
|
path: {
|
|
20
23
|
type: String,
|
|
21
|
-
required: true
|
|
24
|
+
required: true,
|
|
22
25
|
},
|
|
23
26
|
allowCreate: {
|
|
24
27
|
type: Boolean,
|
|
25
|
-
default: false
|
|
28
|
+
default: false,
|
|
26
29
|
},
|
|
27
30
|
hideFilters: {
|
|
28
31
|
type: Boolean,
|
|
29
|
-
default: false
|
|
32
|
+
default: false,
|
|
30
33
|
},
|
|
31
34
|
title: {
|
|
32
35
|
type: String,
|
|
33
|
-
required: false
|
|
36
|
+
required: false,
|
|
34
37
|
},
|
|
35
38
|
transformItem: {
|
|
36
39
|
type: Function,
|
|
37
|
-
required: false
|
|
40
|
+
required: false,
|
|
38
41
|
},
|
|
39
42
|
transformItems: {
|
|
40
43
|
type: Function,
|
|
41
|
-
required: false
|
|
44
|
+
required: false,
|
|
42
45
|
},
|
|
43
46
|
beforeSave: {
|
|
44
47
|
type: Function,
|
|
45
|
-
required: false
|
|
48
|
+
required: false,
|
|
46
49
|
},
|
|
47
50
|
beforeCreate: {
|
|
48
51
|
type: Function,
|
|
49
|
-
required: false
|
|
52
|
+
required: false,
|
|
50
53
|
},
|
|
51
54
|
beforeUpdate: {
|
|
52
55
|
type: Function,
|
|
53
|
-
required: false
|
|
56
|
+
required: false,
|
|
54
57
|
},
|
|
55
58
|
beforeDelete: {
|
|
56
59
|
type: Function,
|
|
57
|
-
required: false
|
|
60
|
+
required: false,
|
|
58
61
|
},
|
|
59
62
|
updateTitle: {
|
|
60
63
|
type: String,
|
|
61
64
|
required: false,
|
|
62
65
|
default() {
|
|
63
|
-
return
|
|
64
|
-
}
|
|
66
|
+
return 'Update item'
|
|
67
|
+
},
|
|
65
68
|
},
|
|
66
69
|
deleteTitle: {
|
|
67
70
|
type: String,
|
|
68
71
|
required: false,
|
|
69
72
|
default() {
|
|
70
|
-
return
|
|
71
|
-
}
|
|
73
|
+
return 'Delete item'
|
|
74
|
+
},
|
|
72
75
|
},
|
|
73
76
|
createTitle: {
|
|
74
77
|
type: String,
|
|
75
78
|
required: false,
|
|
76
79
|
default() {
|
|
77
|
-
return
|
|
78
|
-
}
|
|
80
|
+
return 'Create item'
|
|
81
|
+
},
|
|
79
82
|
},
|
|
80
83
|
customFilters: {
|
|
81
84
|
type: Object,
|
|
82
85
|
required: false,
|
|
83
86
|
default: () => {
|
|
84
|
-
}
|
|
87
|
+
},
|
|
85
88
|
},
|
|
86
89
|
await: {
|
|
87
90
|
type: Boolean,
|
|
88
91
|
required: false,
|
|
89
|
-
default: false
|
|
92
|
+
default: false,
|
|
90
93
|
},
|
|
91
94
|
listeners: {
|
|
92
95
|
type: Array,
|
|
93
96
|
required: false,
|
|
94
|
-
default: () => []
|
|
95
|
-
}
|
|
96
|
-
})
|
|
97
|
+
default: () => [],
|
|
98
|
+
},
|
|
99
|
+
})
|
|
97
100
|
const {
|
|
98
101
|
getItem,
|
|
99
102
|
updateItem,
|
|
@@ -103,106 +106,122 @@ const {
|
|
|
103
106
|
formErrors,
|
|
104
107
|
formPending,
|
|
105
108
|
itemErrors,
|
|
106
|
-
itemPending
|
|
107
|
-
} = useCrudApi(props.path, false, props.transformItem, props.transformItems)
|
|
108
|
-
|
|
109
|
-
const
|
|
110
|
-
const
|
|
111
|
-
|
|
109
|
+
itemPending,
|
|
110
|
+
} = useCrudApi(props.path, false, props.transformItem, props.transformItems)
|
|
111
|
+
|
|
112
|
+
const route = useRoute()
|
|
113
|
+
const router = useRouter()
|
|
114
|
+
|
|
115
|
+
const action = computed(() => route.query[(props.loaderKey ?? '') + 'action'])
|
|
116
|
+
const actionId = computed(() => route.query[(props.loaderKey ?? '') + 'actionId'])
|
|
117
|
+
|
|
112
118
|
const dialogOpen = computed({
|
|
113
|
-
get: () => !!(action.value ===
|
|
119
|
+
get: () => !!(action.value === 'create' || (action.value === 'update' && actionId.value) || (action.value === 'delete' && actionId.value)),
|
|
114
120
|
set: (value) => {
|
|
115
121
|
if (!value) {
|
|
116
122
|
if (router.options.history.state.back) {
|
|
117
|
-
router.back()
|
|
118
|
-
}
|
|
119
|
-
|
|
123
|
+
router.back()
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
const currentQuery = route.query
|
|
120
127
|
if (props.loaderKey) {
|
|
121
|
-
delete currentQuery[(props.loaderKey ??
|
|
122
|
-
delete currentQuery[(props.loaderKey ??
|
|
123
|
-
} else {
|
|
124
|
-
delete currentQuery.action;
|
|
125
|
-
delete currentQuery.actionId;
|
|
128
|
+
delete (currentQuery[(props.loaderKey ?? '') + 'action'])
|
|
129
|
+
delete (currentQuery[(props.loaderKey ?? '') + 'actionId'])
|
|
126
130
|
}
|
|
127
|
-
|
|
131
|
+
else {
|
|
132
|
+
delete currentQuery.action
|
|
133
|
+
delete currentQuery.actionId
|
|
134
|
+
}
|
|
135
|
+
router.replace({ ...route, query: currentQuery })
|
|
128
136
|
}
|
|
129
137
|
}
|
|
130
|
-
}
|
|
131
|
-
})
|
|
138
|
+
},
|
|
139
|
+
})
|
|
132
140
|
const updateForm = async (id) => {
|
|
133
|
-
const newQuery = { query: { ...route.query } }
|
|
141
|
+
const newQuery = { query: { ...route.query } }
|
|
134
142
|
if (props.loaderKey) {
|
|
135
|
-
newQuery.query[(props.loaderKey ??
|
|
136
|
-
newQuery.query[(props.loaderKey ??
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
newQuery.query.
|
|
143
|
+
newQuery.query[(props.loaderKey ?? '') + 'action'] = 'update'
|
|
144
|
+
newQuery.query[(props.loaderKey ?? '') + 'actionId'] = id
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
newQuery.query.action = 'update'
|
|
148
|
+
newQuery.query.actionId = id
|
|
140
149
|
}
|
|
141
|
-
await router.push(newQuery)
|
|
142
|
-
}
|
|
150
|
+
await router.push(newQuery)
|
|
151
|
+
}
|
|
143
152
|
const deleteForm = async (id) => {
|
|
144
|
-
const newQuery = { query: { ...route.query } }
|
|
153
|
+
const newQuery = { query: { ...route.query } }
|
|
145
154
|
if (props.loaderKey) {
|
|
146
|
-
newQuery.query[(props.loaderKey ??
|
|
147
|
-
newQuery.query[(props.loaderKey ??
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
newQuery.query.
|
|
155
|
+
newQuery.query[(props.loaderKey ?? '') + 'action'] = 'delete'
|
|
156
|
+
newQuery.query[(props.loaderKey ?? '') + 'actionId'] = id
|
|
157
|
+
}
|
|
158
|
+
else {
|
|
159
|
+
newQuery.query.action = 'delete'
|
|
160
|
+
newQuery.query.actionId = id
|
|
151
161
|
}
|
|
152
|
-
await router.push(newQuery)
|
|
153
|
-
}
|
|
162
|
+
await router.push(newQuery)
|
|
163
|
+
}
|
|
154
164
|
const createForm = () => {
|
|
155
|
-
item.value = props.initialItem ? cloneDeep(props.initialItem) : {}
|
|
156
|
-
const newQuery = { query: { ...route.query } }
|
|
165
|
+
item.value = props.initialItem ? cloneDeep(props.initialItem) : {}
|
|
166
|
+
const newQuery = { query: { ...route.query } }
|
|
157
167
|
if (props.loaderKey) {
|
|
158
|
-
newQuery.query[(props.loaderKey ??
|
|
159
|
-
} else {
|
|
160
|
-
newQuery.query.action = "create";
|
|
168
|
+
newQuery.query[(props.loaderKey ?? '') + 'action'] = 'create'
|
|
161
169
|
}
|
|
162
|
-
|
|
163
|
-
|
|
170
|
+
else {
|
|
171
|
+
newQuery.query.action = 'create'
|
|
172
|
+
}
|
|
173
|
+
router.push(newQuery)
|
|
174
|
+
}
|
|
175
|
+
|
|
164
176
|
const saveAction = async () => {
|
|
165
|
-
formPending.value = true
|
|
166
|
-
let itemToSave = JSON.parse(JSON.stringify(item.value))
|
|
177
|
+
formPending.value = true
|
|
178
|
+
let itemToSave = JSON.parse(JSON.stringify(item.value))
|
|
167
179
|
if (props.beforeSave != null) {
|
|
168
|
-
itemToSave = await props.beforeSave(itemToSave)
|
|
180
|
+
itemToSave = await props.beforeSave(itemToSave)
|
|
169
181
|
}
|
|
170
|
-
if (action.value ===
|
|
182
|
+
if (action.value === 'create') {
|
|
171
183
|
if (props.beforeCreate != null) {
|
|
172
|
-
itemToSave = await props.beforeCreate(itemToSave)
|
|
184
|
+
itemToSave = await props.beforeCreate(itemToSave)
|
|
173
185
|
}
|
|
174
|
-
await createItem(itemToSave)
|
|
175
|
-
}
|
|
186
|
+
await createItem(itemToSave)
|
|
187
|
+
}
|
|
188
|
+
else if (action.value === 'update') {
|
|
176
189
|
if (props.beforeUpdate != null) {
|
|
177
|
-
itemToSave = await props.beforeUpdate(itemToSave)
|
|
190
|
+
itemToSave = await props.beforeUpdate(itemToSave)
|
|
178
191
|
}
|
|
179
|
-
await updateItem(itemToSave.id, itemToSave)
|
|
180
|
-
}
|
|
192
|
+
await updateItem(itemToSave.id, itemToSave)
|
|
193
|
+
}
|
|
194
|
+
else if (action.value === 'delete') {
|
|
181
195
|
if (props.beforeDelete != null) {
|
|
182
|
-
itemToSave = await props.beforeDelete(itemToSave)
|
|
196
|
+
itemToSave = await props.beforeDelete(itemToSave)
|
|
183
197
|
}
|
|
184
|
-
await deleteItem(itemToSave.id)
|
|
198
|
+
await deleteItem(itemToSave.id)
|
|
185
199
|
}
|
|
186
200
|
if (formErrors.value == null || Object.keys(formErrors.value).length === 0) {
|
|
187
|
-
emits(action.value,
|
|
188
|
-
notify(props.path +
|
|
189
|
-
dialogOpen.value = false
|
|
201
|
+
emits(action.value,itemToSave);
|
|
202
|
+
notify(props.path + ':' + action.value, itemToSave)
|
|
203
|
+
dialogOpen.value = false
|
|
190
204
|
}
|
|
191
|
-
}
|
|
205
|
+
}
|
|
206
|
+
|
|
192
207
|
watch(action, () => {
|
|
193
208
|
try {
|
|
194
|
-
if (action.value ===
|
|
195
|
-
getItem(actionId.value)
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
209
|
+
if (action.value === 'update' && actionId.value) {
|
|
210
|
+
getItem(actionId.value)
|
|
211
|
+
}
|
|
212
|
+
else if (action.value === 'create') {
|
|
213
|
+
item.value = props.initialItem ? cloneDeep(props.initialItem) : {}
|
|
214
|
+
}
|
|
215
|
+
else if (action.value === 'delete' && actionId.value) {
|
|
216
|
+
getItem(actionId.value)
|
|
200
217
|
}
|
|
201
|
-
} catch (error) {
|
|
202
|
-
console.error("Error in actionId watcher:", error);
|
|
203
218
|
}
|
|
204
|
-
|
|
205
|
-
|
|
219
|
+
catch (error) {
|
|
220
|
+
console.error('Error in actionId watcher:', error)
|
|
221
|
+
}
|
|
222
|
+
}, { immediate: true })
|
|
223
|
+
|
|
224
|
+
const { notify } = useListenerService()
|
|
206
225
|
</script>
|
|
207
226
|
|
|
208
227
|
<template>
|
|
@@ -236,3 +255,7 @@ const { notify } = useListenerService();
|
|
|
236
255
|
</crud-form-dialog>
|
|
237
256
|
</div>
|
|
238
257
|
</template>
|
|
258
|
+
|
|
259
|
+
<style scoped>
|
|
260
|
+
|
|
261
|
+
</style>
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
<script setup async>
|
|
2
|
-
import {
|
|
2
|
+
import {useCrudApi} from "../composables/useCrudApi";
|
|
3
3
|
import CrudErrorDisplay from "./CrudErrorDisplay.vue";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
4
|
+
import {useListenerService} from "../composables/useListenerService";
|
|
5
|
+
import {watch, onMounted, onBeforeUnmount, ref} from "vue";
|
|
6
|
+
import {useDebounceFn} from "@vueuse/core";
|
|
7
|
+
|
|
7
8
|
const props = defineProps({
|
|
8
|
-
debounced: {
|
|
9
|
+
debounced : {
|
|
9
10
|
type: Boolean,
|
|
10
|
-
default:
|
|
11
|
+
default :false
|
|
11
12
|
},
|
|
12
|
-
disableNoResults: {
|
|
13
|
+
disableNoResults : {
|
|
13
14
|
type: Boolean,
|
|
14
15
|
default: false
|
|
15
16
|
},
|
|
@@ -36,7 +37,7 @@ const props = defineProps({
|
|
|
36
37
|
required: false,
|
|
37
38
|
default: false
|
|
38
39
|
},
|
|
39
|
-
listeners: {
|
|
40
|
+
listeners : {
|
|
40
41
|
type: Array,
|
|
41
42
|
required: false,
|
|
42
43
|
default: () => []
|
|
@@ -63,44 +64,50 @@ const {
|
|
|
63
64
|
totalPages,
|
|
64
65
|
hasListErrors
|
|
65
66
|
} = useCrudApi(props.path);
|
|
67
|
+
|
|
66
68
|
const debouncedGet = useDebounceFn(getItems, 500);
|
|
69
|
+
|
|
67
70
|
const lastRequest = ref(null);
|
|
71
|
+
|
|
68
72
|
const setLastRequest = () => {
|
|
69
|
-
lastRequest.value = JSON.stringify({
|
|
70
|
-
}
|
|
73
|
+
lastRequest.value = JSON.stringify({page: props.page, perPage: props.perPage, customFilters: props.customFilters});
|
|
74
|
+
}
|
|
75
|
+
|
|
71
76
|
watch(() => props.customFilters, () => {
|
|
72
|
-
if (lastRequest.value === JSON.stringify({
|
|
77
|
+
if (lastRequest.value === JSON.stringify({page: props.page, perPage: props.perPage, customFilters: props.customFilters})) {
|
|
73
78
|
return;
|
|
74
79
|
}
|
|
75
|
-
if
|
|
80
|
+
if(props.debounced) {
|
|
76
81
|
debouncedGet(props.page, props.perPage, props.customFilters);
|
|
77
82
|
} else {
|
|
78
83
|
getItems(props.page, props.perPage, props.customFilters);
|
|
79
84
|
}
|
|
80
85
|
setLastRequest();
|
|
81
|
-
});
|
|
86
|
+
}, {deep: true});
|
|
82
87
|
watch(() => props.page, () => {
|
|
83
88
|
getItems(props.page, props.perPage, props.customFilters);
|
|
84
89
|
});
|
|
85
|
-
if
|
|
90
|
+
if(props.await) {
|
|
86
91
|
await getItems(props.page, props.perPage, props.customFilters);
|
|
87
92
|
} else {
|
|
88
93
|
getItems(props.page, props.perPage, props.customFilters);
|
|
89
94
|
}
|
|
90
95
|
setLastRequest();
|
|
91
|
-
|
|
96
|
+
|
|
97
|
+
const {addListener, removeLocalListenersWithEvent, notify} = useListenerService();
|
|
92
98
|
onMounted(() => {
|
|
93
99
|
props.listeners.forEach((listener) => {
|
|
94
100
|
addListener(listener, (data) => {
|
|
95
101
|
getItems(props.page, null, props.customFilters);
|
|
96
102
|
});
|
|
97
103
|
});
|
|
98
|
-
})
|
|
104
|
+
})
|
|
99
105
|
onBeforeUnmount(() => {
|
|
100
106
|
props.listeners.forEach((listener) => {
|
|
101
107
|
removeLocalListenersWithEvent(listener);
|
|
102
108
|
});
|
|
103
|
-
})
|
|
109
|
+
})
|
|
110
|
+
|
|
104
111
|
</script>
|
|
105
112
|
|
|
106
113
|
<template>
|
|
@@ -128,3 +135,7 @@ onBeforeUnmount(() => {
|
|
|
128
135
|
</slot>
|
|
129
136
|
</div>
|
|
130
137
|
</template>
|
|
138
|
+
|
|
139
|
+
<style scoped>
|
|
140
|
+
|
|
141
|
+
</style>
|