-
-
Notifications
You must be signed in to change notification settings - Fork 622
Expand file tree
/
Copy pathItemActions.vue
More file actions
122 lines (101 loc) · 2.96 KB
/
ItemActions.vue
File metadata and controls
122 lines (101 loc) · 2.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
<script setup>
import { ref, computed, useTemplateRef, watch, onMounted } from 'vue';
import useActions from './Actions.js';
import ConfirmableAction from './ConfirmableAction.vue';
import useSkeletonDelay from '@/composables/skeleton-delay.js';
import axios from 'axios';
const props = defineProps({
url: { type: String },
actions: { type: Array },
context: { type: Object, default: () => ({}) },
item: { required: true },
isDirty: { type: Boolean, default: false },
autoLoad: { type: Boolean, default: false },
});
const emit = defineEmits(['started', 'completed']);
const { prepareActions, runServerAction } = useActions();
const confirmableActions = useTemplateRef('confirmableActions');
const actions = ref(props.actions);
const actionsLoaded = ref(props.actions !== undefined);
const loading = ref(false);
const shouldShowSkeleton = useSkeletonDelay(loading);
let loadActionsRequest = null;
onMounted(() => {
if (props.autoLoad) loadActions();
});
watch(
() => props.actions,
() => {
actions.value = props.actions;
actionsLoaded.value = props.actions !== undefined;
},
{ deep: true }
);
let preparedActions = computed(() => {
return prepareActions(actions.value, confirmableActions.value);
});
let errors = ref({});
function runAction(action, values, onSuccess, onError) {
errors.value = {};
emit('started');
runServerAction({ action, values, onSuccess, onError, url: props.url, selections: [props.item] })
.then((data) => {
if (props.actions === undefined) {
actionsLoaded.value = false;
}
emit('completed', true, data);
})
.catch((data) => {
errors.value = data.errors;
emit('completed', false, data);
});
}
function loadActions() {
if (actionsLoaded.value) {
return Promise.resolve(actions.value);
}
if (loading.value) {
return loadActionsRequest;
}
let params = {
selections: [props.item],
};
if (props.context) {
params.context = props.context;
}
loading.value = true;
loadActionsRequest = axios
.post(props.url + '/list', params)
.then((response) => {
actions.value = response.data;
actionsLoaded.value = true;
return response.data;
})
.finally(() => {
loading.value = false;
loadActionsRequest = null;
});
return loadActionsRequest;
}
defineExpose({
preparedActions,
});
</script>
<template>
<ConfirmableAction
ref="confirmableActions"
v-for="action in actions"
:key="action.handle"
:action="action"
:selections="1"
:errors="errors"
:is-dirty="isDirty"
@confirmed="runAction"
/>
<slot
:actions="preparedActions"
:load-actions="loadActions"
:loading="loading"
:should-show-skeleton="shouldShowSkeleton"
/>
</template>