|
| 1 | +<template> |
| 2 | + <panel-item :field="field"> |
| 3 | + <template v-slot:value> |
| 4 | + <a href="#" :style="finalStyles" :class="finalClasses" :title="name" @click.stop.prevent="fireAction"> |
| 5 | + <span v-if="text" v-text="text"/> |
| 6 | + <span v-if="icon" v-html="icon"/> |
| 7 | + </a> |
| 8 | + |
| 9 | + <!-- Action Confirmation Modal --> |
| 10 | + <portal to="modals" transition="fade-transition"> |
| 11 | + <component |
| 12 | + v-if="confirmActionModalOpened" |
| 13 | + v-bind="options" |
| 14 | + class="text-left" |
| 15 | + :is="selectedAction.component" |
| 16 | + @close="closeConfirmationModal" |
| 17 | + @confirm="executeAction"> |
| 18 | + </component> |
| 19 | + </portal> |
| 20 | + </template> |
| 21 | + </panel-item> |
| 22 | +</template> |
| 23 | + |
| 24 | +<script setup> |
| 25 | +
|
| 26 | + // Vue |
| 27 | + import {computed} from 'vue'; |
| 28 | +
|
| 29 | + // Props |
| 30 | + const props = defineProps({ |
| 31 | + field: {type: Object, default: null}, |
| 32 | + queryString: {type: Object, default: null}, |
| 33 | + resourceName: {type: String, default: null}, |
| 34 | + }); |
| 35 | +
|
| 36 | + // Composables |
| 37 | + import {useHandleAction} from '../mixins/HandlesActions' |
| 38 | +
|
| 39 | + // Computed |
| 40 | + const text = computed(() => props?.field?.text || null); |
| 41 | + const icon = computed(() => props?.field?.icon || null); |
| 42 | + const name = computed(() => props?.field?.name || null); |
| 43 | + const customStyles = computed(() => props?.field?.styles || []); |
| 44 | + const customClasses = computed(() => props?.field?.classes || []); |
| 45 | + const asToolbarButton = computed(() => props?.field?.asToolbarButton === true); |
| 46 | +
|
| 47 | + const actionButtonClasses = computed(() => [ |
| 48 | + 'flex-shrink-0', 'shadow', 'rounded', 'focus:outline-none', 'ring-primary-200', 'dark:ring-gray-600', |
| 49 | + 'focus:ring', 'bg-primary-500', 'hover:bg-primary-400', 'active:bg-primary-600', |
| 50 | + 'text-white', 'dark:text-gray-800', 'inline-flex', 'items-center', 'font-bold', 'px-2', 'h-9', 'text-sm', 'flex-shrink-0', |
| 51 | + ]) |
| 52 | + const toolbarButtonClasses = computed(() => [ |
| 53 | + 'toolbar-button', 'hover:text-primary-500', 'px-2', 'v-popper--has-tooltip', 'w-10' |
| 54 | + ]) |
| 55 | +
|
| 56 | + const finalStyles = computed(() => ({...(customStyles.value || {})})) |
| 57 | + const finalClasses = computed(() => [...(asToolbarButton?.value === true ? toolbarButtonClasses.value : actionButtonClasses.value), ...(customClasses.value || [])]) |
| 58 | +
|
| 59 | + const queryString = computed(() => ({ |
| 60 | + action: selectedAction?.value?.uriKey, |
| 61 | + search: props?.queryString?.currentSearch, |
| 62 | + filters: props?.queryString?.encodedFilters, |
| 63 | + trashed: props?.queryString?.currentTrashed, |
| 64 | + viaResource: props?.queryString?.viaResource, |
| 65 | + viaResourceId: props?.queryString?.viaResourceId, |
| 66 | + viaRelationship: props?.queryString?.viaRelationship, |
| 67 | + })); |
| 68 | +
|
| 69 | + const selectedAction = computed(() => props?.field?.action); |
| 70 | +
|
| 71 | + const selectedResources = computed(() => [props?.field?.resourceId]); |
| 72 | +
|
| 73 | + // Bindings |
| 74 | + const { |
| 75 | + errors, |
| 76 | + working, |
| 77 | + fireAction, |
| 78 | + executeAction, |
| 79 | + closeConfirmationModal, |
| 80 | + confirmActionModalOpened |
| 81 | + } = useHandleAction( |
| 82 | + { |
| 83 | + queryString: queryString.value, |
| 84 | + resourceName: props?.resourceName, |
| 85 | + selectedAction: selectedAction.value, |
| 86 | + selectedResources: selectedResources.value, |
| 87 | + } |
| 88 | + ) |
| 89 | +
|
| 90 | + // Computed |
| 91 | + const options = computed(() => ({ |
| 92 | + show: true, |
| 93 | + errors: errors?.value, |
| 94 | + action: selectedAction?.value, |
| 95 | + working: working?.value === true, |
| 96 | + resourceName: props?.resourceName, |
| 97 | + selectedResources: selectedResources?.value, |
| 98 | + })) |
| 99 | +
|
| 100 | +</script> |
0 commit comments