atom-nuxt 1.0.156 → 1.2.2
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 +29 -12
- package/dist/runtime/components/CrudFormLoader.vue +121 -98
- package/dist/runtime/components/CrudListLoader.vue +28 -17
- package/dist/runtime/components/CrudPaginatedLoader.vue +112 -53
- 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 -31
- 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 -72
- package/dist/runtime/components/CrudUploadField.vue.d.ts +0 -23
- package/dist/runtime/components/CrudUploadFieldSelection.vue.d.ts +0 -18
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import CrudErrorDisplay from "../components/CrudErrorDisplay.vue";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import {computed} from "vue";
|
|
4
|
+
import {useDisplay} from "vuetify";
|
|
5
|
+
|
|
5
6
|
const props = defineProps({
|
|
6
7
|
action: {
|
|
7
8
|
type: String,
|
|
@@ -54,6 +55,11 @@ const props = defineProps({
|
|
|
54
55
|
required: false,
|
|
55
56
|
default: "Delete item"
|
|
56
57
|
},
|
|
58
|
+
viewTitle: {
|
|
59
|
+
type: String,
|
|
60
|
+
required: false,
|
|
61
|
+
default: "View item"
|
|
62
|
+
},
|
|
57
63
|
saveAction: {
|
|
58
64
|
type: Function,
|
|
59
65
|
required: true
|
|
@@ -91,16 +97,22 @@ const props = defineProps({
|
|
|
91
97
|
}
|
|
92
98
|
});
|
|
93
99
|
const item = defineModel();
|
|
94
|
-
const dialogOpen = defineModel(
|
|
100
|
+
const dialogOpen = defineModel('dialog');
|
|
95
101
|
const hasItem = computed(() => item.value && Object.keys(item.value).length > 0);
|
|
102
|
+
|
|
96
103
|
const buttonTitle = computed(() => {
|
|
97
|
-
return props.btnText ? props.btnText : props.action ===
|
|
104
|
+
return props.btnText ? props.btnText : (props.action === 'create' ? props.createTitle : (props.action === 'update' ? props.updateTitle : (props.action === 'delete' ? props.deleteTitle : (props.action === 'view' ? props.viewTitle : ''))));
|
|
98
105
|
});
|
|
106
|
+
|
|
99
107
|
const buttonIcon = computed(() => {
|
|
100
|
-
return props.btnIcon ? props.btnIcon : props.action ===
|
|
108
|
+
return props.btnIcon ? props.btnIcon : (props.action === 'create' ? 'mdi-plus' : (props.action === 'update' ? 'mdi-pencil' : (props.action === 'delete' ? 'mdi-delete' : (props.action === 'view' ? 'mdi-eye' : 'mdi-timer-sand'))));
|
|
101
109
|
});
|
|
110
|
+
|
|
102
111
|
const display = useDisplay();
|
|
103
112
|
const isLarge = computed(() => display.lgAndUp.value);
|
|
113
|
+
|
|
114
|
+
const readonly = computed(() => props.action === 'view');
|
|
115
|
+
|
|
104
116
|
</script>
|
|
105
117
|
|
|
106
118
|
<template>
|
|
@@ -129,7 +141,7 @@ const isLarge = computed(() => display.lgAndUp.value);
|
|
|
129
141
|
Loading
|
|
130
142
|
</v-toolbar-title>
|
|
131
143
|
<v-toolbar-title v-else>{{
|
|
132
|
-
action === 'create' ? createTitle : (action === 'update' ? updateTitle : (action === 'delete' ? deleteTitle : ''))
|
|
144
|
+
action === 'create' ? createTitle : (action === 'update' ? updateTitle : (action === 'delete' ? deleteTitle : (action === 'view' ? viewTitle : '')))
|
|
133
145
|
}}
|
|
134
146
|
</v-toolbar-title>
|
|
135
147
|
</v-toolbar>
|
|
@@ -143,7 +155,7 @@ const isLarge = computed(() => display.lgAndUp.value);
|
|
|
143
155
|
<v-progress-circular indeterminate color="primary"></v-progress-circular>
|
|
144
156
|
</div>
|
|
145
157
|
|
|
146
|
-
<div v-if="(hasItem && !itemPending) || action === 'create'" class="flex-fill">
|
|
158
|
+
<div v-if="(hasItem && !itemPending) || action === 'create' || action === 'view'" class="flex-fill">
|
|
147
159
|
<suspense>
|
|
148
160
|
<template #fallback>
|
|
149
161
|
<div v-if="!itemPending" class="d-flex flex-fill flex-column justify-center align-center"
|
|
@@ -151,21 +163,22 @@ const isLarge = computed(() => display.lgAndUp.value);
|
|
|
151
163
|
<v-progress-circular indeterminate color="primary"></v-progress-circular>
|
|
152
164
|
</div>
|
|
153
165
|
</template>
|
|
154
|
-
<slot
|
|
155
|
-
|
|
156
|
-
|
|
166
|
+
<slot :action="action"
|
|
167
|
+
:readonly="readonly"
|
|
168
|
+
:item="item"
|
|
169
|
+
:errors="formErrors">
|
|
157
170
|
|
|
158
171
|
</slot>
|
|
159
172
|
</suspense>
|
|
160
173
|
</div>
|
|
161
174
|
</div>
|
|
162
|
-
<v-card-actions v-if="!hideActions" class="pa-0 border-t pa-4 elevation-5">
|
|
175
|
+
<v-card-actions v-if="!hideActions && action !== 'view'" class="pa-0 border-t pa-4 elevation-5">
|
|
163
176
|
<v-btn
|
|
164
177
|
size="large"
|
|
165
178
|
class="px-5"
|
|
166
179
|
:width="isLarge ? 'auto' : '100%'"
|
|
167
180
|
:disabled="disabled || !action"
|
|
168
|
-
:color="btnColor ? btnColor : (action === 'create' ? 'success' : (action === 'update' ? 'info' : (action === 'delete' ? 'error' : 'light')))"
|
|
181
|
+
:color="btnColor ? btnColor : (action === 'create' ? 'success' : (action === 'update' ? 'info' : (action === 'delete' ? 'error' : (action === 'view' ? 'primary' : 'light'))))"
|
|
169
182
|
variant="flat"
|
|
170
183
|
@click="saveAction"
|
|
171
184
|
:loading="formPending"
|
|
@@ -178,3 +191,7 @@ const isLarge = computed(() => display.lgAndUp.value);
|
|
|
178
191
|
</v-card>
|
|
179
192
|
</v-dialog>
|
|
180
193
|
</template>
|
|
194
|
+
|
|
195
|
+
<style scoped>
|
|
196
|
+
|
|
197
|
+
</style>
|
|
@@ -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>
|