-
-
Notifications
You must be signed in to change notification settings - Fork 622
Expand file tree
/
Copy pathRowActions.vue
More file actions
102 lines (90 loc) · 3.19 KB
/
RowActions.vue
File metadata and controls
102 lines (90 loc) · 3.19 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
<script setup>
import {
Dropdown,
DropdownItem,
DropdownMenu,
DropdownSeparator,
Skeleton,
} from '@ui';
import { injectListingContext } from '../Listing/Listing.vue';
import ItemActions from '@/components/actions/ItemActions.vue';
import { hasSlotContent } from '@/composables/has-slot-content';
import { computed, ref, watch } from 'vue';
const props = defineProps({
row: {
type: Object,
required: true,
},
});
const { actionUrl, actionContext, refresh, reorderable, allowActionsWhileReordering } = injectListingContext();
const busy = ref(false);
const hasPrependedActionsContent = hasSlotContent('prepended-actions', computed(() => ({ row: props.row })));
const shouldShowActions = computed(() => {
if (reorderable.value && !allowActionsWhileReordering.value) return false;
return hasPrependedActionsContent.value || props.row.actions?.length > 0;
});
watch(busy, (busy) => Statamic.$progress.loading('action', busy));
function actionStarted() {
busy.value = true;
}
function actionCompleted(successful = null, response = {}) {
busy.value = false;
successful ? actionSuccess(response) : actionFailed(response);
}
function actionSuccess(response) {
if (response.message !== false) {
Statamic.$toast.success(response.message || __('Action completed'));
}
refresh();
}
function actionFailed(response) {
Statamic.$toast.error(response.message || __('Action failed'));
}
function dropdownHovered(loadActions) {
if (actionUrl.value) loadActions();
}
</script>
<template>
<ItemActions
v-if="shouldShowActions"
:url="actionUrl"
:item="row.id"
:context="actionContext"
:actions="row.actions"
@started="actionStarted"
@completed="actionCompleted"
v-slot="{ actions, loadActions, shouldShowSkeleton }"
>
<Dropdown
@mouseover="dropdownHovered(loadActions)"
@focus="dropdownHovered(loadActions)"
@click="dropdownHovered(loadActions)"
placement="left-start"
class="me-3"
>
<DropdownMenu>
<slot name="prepended-actions" :row="row" />
<DropdownSeparator v-if="hasPrependedActionsContent && (shouldShowSkeleton || actions.length)" />
<template v-if="shouldShowSkeleton">
<div v-for="index in 3" :key="index" class="contents">
<Skeleton class="m-1 size-5" />
<Skeleton
class="mx-2 my-1.5 h-5"
:class="index === 1 ? 'w-28' : index === 2 ? 'w-36' : 'w-24'"
/>
</div>
</template>
<template v-else>
<DropdownItem
v-for="action in actions"
:key="action.handle"
:text="__(action.title)"
:icon="action.icon"
:variant="action.dangerous ? 'destructive' : 'default'"
@click="action.run"
/>
</template>
</DropdownMenu>
</Dropdown>
</ItemActions>
</template>