refactor: abstract delete logic into useDestroy composable to reduce code duplication in data table actions

This commit is contained in:
Yoga Pangestu 2026-06-23 11:07:16 +07:00
parent dfd2c5560b
commit 18650f1cbf
18 changed files with 147 additions and 354 deletions

View File

@ -0,0 +1,46 @@
import { router } from '@inertiajs/vue3';
import { ref } from 'vue';
import { toast } from 'vue-sonner';
interface UseDestroyOptions {
url: string;
preserveScroll?: boolean;
errorMessage?: string;
onSuccess?: () => void;
onError?: (errors: Record<string, string>) => string | void;
}
export function useDestroy({ url, preserveScroll = true, errorMessage, onSuccess, onError }: UseDestroyOptions) {
const open = ref(false);
const processing = ref(false);
function destroy() {
processing.value = true;
router.delete(url, {
preserveScroll,
onSuccess: () => {
open.value = false;
onSuccess?.();
},
onError: (errors) => {
if (onError) {
const result = onError(errors);
if (typeof result === 'string') {
toast.error(result);
return;
}
}
if (errorMessage) {
toast.error(errorMessage);
}
},
onFinish: () => {
processing.value = false;
},
});
}
return { open, processing, destroy };
}

View File

@ -1,12 +1,11 @@
<script setup lang="ts">
import { router } from '@inertiajs/vue3';
import { Pencil, Trash2 } from '@lucide/vue';
import { computed, ref } from 'vue';
import { toast } from 'vue-sonner';
import { computed } from 'vue';
import ConfirmDialog from '@/components/ConfirmDialog.vue';
import { Button } from '@/components/ui/button';
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip';
import { useCan } from '@/composables/useCan';
import { useDestroy } from '@/composables/useDestroy';
import type { CashTransactionListItem } from '@/types/cash';
import { destroy } from '@/routes/admin/finance/cash/transactions';
@ -22,25 +21,10 @@ const { can } = useCan();
const showActions = computed(() => props.transaction.reference_type === null);
const deleteConfirmOpen = ref(false);
const deleteProcessing = ref(false);
function destroyTransaction() {
deleteProcessing.value = true;
router.delete(destroy.url(props.transaction.id), {
preserveScroll: true,
onSuccess: () => {
deleteConfirmOpen.value = false;
},
onError: (errors) => {
toast.error(errors.amount || errors.transaction || 'Gagal menghapus setor kas.');
},
onFinish: () => {
deleteProcessing.value = false;
},
});
}
const { open: deleteConfirmOpen, processing: deleteProcessing, destroy: destroyTransaction } = useDestroy({
url: destroy.url(props.transaction.id),
onError: (errors) => errors.amount || errors.transaction || 'Gagal menghapus setor kas.',
});
</script>
<template>

View File

@ -7,6 +7,7 @@ import ConfirmDialog from '@/components/ConfirmDialog.vue';
import { Button } from '@/components/ui/button';
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip';
import { useCan } from '@/composables/useCan';
import { useDestroy } from '@/composables/useDestroy';
import type { EmployeeAdvanceListItem } from '@/types/employee-advance';
import { destroy, approve, pay } from '@/routes/admin/finance/employee_advances';
@ -41,29 +42,15 @@ const canDelete = computed(() => (
&& can('employee_advances.delete')
));
const deleteConfirmOpen = ref(false);
const approveConfirmOpen = ref(false);
const payConfirmOpen = ref(false);
const deleteProcessing = ref(false);
const approveProcessing = ref(false);
const payProcessing = ref(false);
function destroyEmployeeAdvance() {
deleteProcessing.value = true;
router.delete(destroy.url(props.employeeAdvance.id), {
preserveScroll: true,
onSuccess: () => {
deleteConfirmOpen.value = false;
},
onError: () => {
toast.error('Gagal menghapus kasbon.');
},
onFinish: () => {
deleteProcessing.value = false;
},
});
}
const { open: deleteConfirmOpen, processing: deleteProcessing, destroy: destroyEmployeeAdvance } = useDestroy({
url: destroy.url(props.employeeAdvance.id),
errorMessage: 'Gagal menghapus kasbon.',
});
function approveEmployeeAdvance() {
approveProcessing.value = true;

View File

@ -1,12 +1,10 @@
<script setup lang="ts">
import { router } from '@inertiajs/vue3';
import { Pencil, Trash2 } from '@lucide/vue';
import { ref } from 'vue';
import { toast } from 'vue-sonner';
import ConfirmDialog from '@/components/ConfirmDialog.vue';
import { Button } from '@/components/ui/button';
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip';
import { useCan } from '@/composables/useCan';
import { useDestroy } from '@/composables/useDestroy';
import type { ExpenseListItem } from '@/types/expense';
import { destroy } from '@/routes/admin/finance/expenses';
@ -21,25 +19,10 @@ const emit = defineEmits<{
const { can } = useCan();
const deleteConfirmOpen = ref(false);
const deleteProcessing = ref(false);
function destroyExpense() {
deleteProcessing.value = true;
router.delete(destroy.url(props.expense.id), {
preserveScroll: true,
onSuccess: () => {
deleteConfirmOpen.value = false;
},
onError: (errors) => {
toast.error(errors.amount || errors.transaction || 'Gagal menghapus pengeluaran.');
},
onFinish: () => {
deleteProcessing.value = false;
},
});
}
const { open: deleteConfirmOpen, processing: deleteProcessing, destroy: destroyExpense } = useDestroy({
url: destroy.url(props.expense.id),
onError: (errors) => errors.amount || errors.transaction || 'Gagal menghapus pengeluaran.',
});
</script>
<template>

View File

@ -1,8 +1,5 @@
<script setup lang="ts">
import { router } from '@inertiajs/vue3';
import { Trash2 } from '@lucide/vue';
import { ref } from 'vue';
import { toast } from 'vue-sonner';
import AttendanceMap from './AttendanceMap.vue';
import AttendancePhotoCell from './attendance-photo-cell.vue';
import ConfirmDialog from '@/components/ConfirmDialog.vue';
@ -15,6 +12,7 @@ import {
DialogTitle,
} from '@/components/ui/dialog';
import { useCan } from '@/composables/useCan';
import { useDestroy } from '@/composables/useDestroy';
import type { AttendanceListItem } from '@/types/attendance';
import { destroy } from '@/routes/admin/hr/attendances';
@ -26,30 +24,13 @@ const props = defineProps<{
const { can } = useCan();
const deleteConfirmOpen = ref(false);
const deleteProcessing = ref(false);
function destroyAttendance() {
if (!props.attendance) {
return;
}
deleteProcessing.value = true;
router.delete(destroy.url(props.attendance.id), {
preserveScroll: true,
onSuccess: () => {
deleteConfirmOpen.value = false;
open.value = false;
},
onError: () => {
toast.error('Gagal menghapus data presensi.');
},
onFinish: () => {
deleteProcessing.value = false;
},
});
}
const { open: deleteConfirmOpen, processing: deleteProcessing, destroy: destroyAttendance } = useDestroy({
url: destroy.url(props.attendance?.id ?? 0),
errorMessage: 'Gagal menghapus data presensi.',
onSuccess: () => {
open.value = false;
},
});
</script>
<template>

View File

@ -1,12 +1,10 @@
<script setup lang="ts">
import { router } from '@inertiajs/vue3';
import { Trash2 } from '@lucide/vue';
import { ref } from 'vue';
import { toast } from 'vue-sonner';
import ConfirmDialog from '@/components/ConfirmDialog.vue';
import { Button } from '@/components/ui/button';
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip';
import { useCan } from '@/composables/useCan';
import { useDestroy } from '@/composables/useDestroy';
import type { AttendanceListItem } from '@/types/attendance';
import { destroy } from '@/routes/admin/hr/attendances';
@ -16,25 +14,10 @@ const props = defineProps<{
const { can } = useCan();
const deleteConfirmOpen = ref(false);
const deleteProcessing = ref(false);
function destroyAttendance() {
deleteProcessing.value = true;
router.delete(destroy.url(props.attendance.id), {
preserveScroll: true,
onSuccess: () => {
deleteConfirmOpen.value = false;
},
onError: () => {
toast.error('Gagal menghapus data presensi.');
},
onFinish: () => {
deleteProcessing.value = false;
},
});
}
const { open: deleteConfirmOpen, processing: deleteProcessing, destroy: destroyAttendance } = useDestroy({
url: destroy.url(props.attendance.id),
errorMessage: 'Gagal menghapus data presensi.',
});
</script>
<template>

View File

@ -7,6 +7,7 @@ import ConfirmDialog from '@/components/ConfirmDialog.vue';
import { Button } from '@/components/ui/button';
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip';
import { useCan } from '@/composables/useCan';
import { useDestroy } from '@/composables/useDestroy';
import type { EmployeeListItem } from '@/types/employee';
import { edit, destroy, reset_password } from '@/routes/admin/hr/employees';
@ -18,26 +19,14 @@ const { can } = useCan();
const page = usePage();
const defaultPassword = page.props.auth.password_default as string;
const deleteConfirmOpen = ref(false);
const resetPasswordConfirmOpen = ref(false);
const deleteProcessing = ref(false);
const resetPasswordProcessing = ref(false);
function destroyEmployee() {
deleteProcessing.value = true;
router.delete(destroy.url(props.employee.id), {
onSuccess: () => {
deleteConfirmOpen.value = false;
},
onError: () => {
toast.error('Gagal menghapus pegawai.');
},
onFinish: () => {
deleteProcessing.value = false;
},
});
}
const { open: deleteConfirmOpen, processing: deleteProcessing, destroy: destroyEmployee } = useDestroy({
url: destroy.url(props.employee.id),
preserveScroll: false,
errorMessage: 'Gagal menghapus pegawai.',
});
function resetPassword() {
resetPasswordProcessing.value = true;

View File

@ -7,6 +7,7 @@ import ConfirmDialog from '@/components/ConfirmDialog.vue';
import { Button } from '@/components/ui/button';
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip';
import { useCan } from '@/composables/useCan';
import { useDestroy } from '@/composables/useDestroy';
import type { LeaveRequestListItem } from '@/types/leave-request';
import { destroy, approve } from '@/routes/admin/hr/leave_requests';
@ -41,27 +42,13 @@ const canDelete = computed(() => (
&& can('leave_requests.delete')
));
const deleteConfirmOpen = ref(false);
const approveConfirmOpen = ref(false);
const deleteProcessing = ref(false);
const approveProcessing = ref(false);
function destroyLeaveRequest() {
deleteProcessing.value = true;
router.delete(destroy.url(props.leaveRequest.id), {
preserveScroll: true,
onSuccess: () => {
deleteConfirmOpen.value = false;
},
onError: () => {
toast.error('Gagal menghapus pengajuan cuti.');
},
onFinish: () => {
deleteProcessing.value = false;
},
});
}
const { open: deleteConfirmOpen, processing: deleteProcessing, destroy: destroyLeaveRequest } = useDestroy({
url: destroy.url(props.leaveRequest.id),
errorMessage: 'Gagal menghapus pengajuan cuti.',
});
function approveLeaveRequest() {
approveProcessing.value = true;

View File

@ -30,6 +30,7 @@ import {
TooltipTrigger,
} from '@/components/ui/tooltip';
import { useCan } from '@/composables/useCan';
import { useDestroy } from '@/composables/useDestroy';
import { CuttingStatus } from '@/constants/cutting-status';
import { RupiahInput } from '@/components/form/rupiah-input';
import { parseRupiah } from '@/lib/rupiah';
@ -47,8 +48,6 @@ const props = defineProps<{
const { can } = useCan();
const deleteConfirmOpen = ref(false);
const deleteProcessing = ref(false);
const statusConfirmOpen = ref(false);
const statusProcessing = ref(false);
const rejectDialogOpen = ref(false);
@ -56,6 +55,11 @@ const verifyDialogOpen = ref(false);
const allMatches = ref(true);
const pendingAction = ref<CuttingStatusAction | null>(null);
const { open: deleteConfirmOpen, processing: deleteProcessing, destroy: destroyCutting } = useDestroy({
url: destroy.url(props.cutting.id),
errorMessage: 'Gagal menghapus cutting.',
});
const rejectForm = useForm({
status: CuttingStatus.REJECTED,
reason: '',
@ -284,23 +288,6 @@ watch(rejectDialogOpen, (isOpen) => {
}
});
function destroyCutting() {
deleteProcessing.value = true;
router.delete(destroy.url(props.cutting.id), {
preserveScroll: true,
onSuccess: () => {
deleteConfirmOpen.value = false;
},
onError: () => {
toast.error('Gagal menghapus cutting.');
},
onFinish: () => {
deleteProcessing.value = false;
},
});
}
function actionIcon(status: string) {
if (status === CuttingStatus.COMPLETED) {
return Scissors;

View File

@ -30,6 +30,7 @@ import {
TableRow,
} from '@/components/ui/table';
import { useCan } from '@/composables/useCan';
import { useDestroy } from '@/composables/useDestroy';
import { MarketplaceFeeScope } from '@/constants/marketplace-fee-scope';
import { MarketplaceFeeValueType } from '@/constants/marketplace-fee-value-type';
import { OrderStatus } from '@/constants/order-status';
@ -44,8 +45,6 @@ const props = defineProps<{
const { can } = useCan();
const deleteConfirmOpen = ref(false);
const deleteProcessing = ref(false);
const statusConfirmOpen = ref(false);
const statusProcessing = ref(false);
const pendingAction = ref<OrderStatusAction | null>(null);
@ -53,6 +52,12 @@ const pendingAction = ref<OrderStatusAction | null>(null);
const canEdit = computed(() => props.order.is_editable && can('orders.update'));
const canDelete = computed(() => can('orders.delete'));
const { open: deleteConfirmOpen, processing: deleteProcessing, destroy: destroyOrder } = useDestroy({
url: destroy.url(props.order.id),
preserveScroll: false,
errorMessage: 'Gagal menghapus pesanan.',
});
const creatorName = computed(() => {
return props.order.created_by?.profile?.full_name ?? props.order.created_by?.username ?? '-';
});
@ -115,22 +120,6 @@ function transitionStatus() {
});
}
function destroyOrder() {
deleteProcessing.value = true;
router.delete(destroy.url(props.order.id), {
onSuccess: () => {
deleteConfirmOpen.value = false;
},
onError: () => {
toast.error('Gagal menghapus pesanan.');
},
onFinish: () => {
deleteProcessing.value = false;
},
});
}
const items = computed(() => props.order.items ?? []);
const summaryRows = computed(() => {

View File

@ -8,6 +8,7 @@ import ConfirmDialog from '@/components/ConfirmDialog.vue';
import { Button } from '@/components/ui/button';
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip';
import { useCan } from '@/composables/useCan';
import { useDestroy } from '@/composables/useDestroy';
import { OrderStatus } from '@/constants/order-status';
import type { OrderListItem, OrderStatusAction } from '@/types/order';
import { show, edit, destroy, transition_status } from '@/routes/admin/manage/orders';
@ -18,8 +19,6 @@ const props = defineProps<{
const { can } = useCan();
const deleteConfirmOpen = ref(false);
const deleteProcessing = ref(false);
const statusConfirmOpen = ref(false);
const statusProcessing = ref(false);
const pendingAction = ref<OrderStatusAction | null>(null);
@ -29,6 +28,11 @@ const availableActions = computed(() => props.order.available_actions ?? []);
const canEdit = computed(() => props.order.is_editable && can('orders.update'));
const canDelete = computed(() => can('orders.delete'));
const { open: deleteConfirmOpen, processing: deleteProcessing, destroy: destroyOrder } = useDestroy({
url: destroy.url(props.order.id),
errorMessage: 'Gagal menghapus pesanan.',
});
function canPerformAction(action: OrderStatusAction): boolean {
return can(action.permission);
}
@ -76,23 +80,6 @@ function transitionStatus() {
});
}
function destroyOrder() {
deleteProcessing.value = true;
router.delete(destroy.url(props.order.id), {
preserveScroll: true,
onSuccess: () => {
deleteConfirmOpen.value = false;
},
onError: () => {
toast.error('Gagal menghapus pesanan.');
},
onFinish: () => {
deleteProcessing.value = false;
},
});
}
function actionIcon(status: string) {
if (status === OrderStatus.PROCESSING) {
return Send;

View File

@ -1,12 +1,11 @@
<script setup lang="ts">
import { Link, router } from '@inertiajs/vue3';
import { Link } from '@inertiajs/vue3';
import { Pencil, Trash2 } from '@lucide/vue';
import { ref } from 'vue';
import { toast } from 'vue-sonner';
import ConfirmDialog from '@/components/ConfirmDialog.vue';
import { Button } from '@/components/ui/button';
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip';
import { useCan } from '@/composables/useCan';
import { useDestroy } from '@/composables/useDestroy';
import type { PurchaseListItem } from '@/types/purchase';
import { edit, destroy } from '@/routes/admin/manage/purchases';
@ -16,25 +15,10 @@ const props = defineProps<{
const { can } = useCan();
const deleteConfirmOpen = ref(false);
const deleteProcessing = ref(false);
function destroyPurchase() {
deleteProcessing.value = true;
router.delete(destroy.url(props.purchase.id), {
preserveScroll: true,
onSuccess: () => {
deleteConfirmOpen.value = false;
},
onError: () => {
toast.error('Gagal menghapus belanja.');
},
onFinish: () => {
deleteProcessing.value = false;
},
});
}
const { open: deleteConfirmOpen, processing: deleteProcessing, destroy: destroyPurchase } = useDestroy({
url: destroy.url(props.purchase.id),
errorMessage: 'Gagal menghapus belanja.',
});
</script>
<template>

View File

@ -1,12 +1,10 @@
<script setup lang="ts">
import { router } from '@inertiajs/vue3';
import { Pencil, Trash2 } from '@lucide/vue';
import { ref } from 'vue';
import { toast } from 'vue-sonner';
import ConfirmDialog from '@/components/ConfirmDialog.vue';
import { Button } from '@/components/ui/button';
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip';
import { useCan } from '@/composables/useCan';
import { useDestroy } from '@/composables/useDestroy';
import type { CategoryListItem } from '@/types/category';
import { destroy } from '@/routes/admin/master/categories';
@ -20,25 +18,10 @@ const emit = defineEmits<{
const { can } = useCan();
const deleteConfirmOpen = ref(false);
const deleteProcessing = ref(false);
function destroyCategory() {
deleteProcessing.value = true;
router.delete(destroy.url(props.category.id), {
preserveScroll: true,
onSuccess: () => {
deleteConfirmOpen.value = false;
},
onError: () => {
toast.error('Gagal menghapus kategori.');
},
onFinish: () => {
deleteProcessing.value = false;
},
});
}
const { open: deleteConfirmOpen, processing: deleteProcessing, destroy: destroyCategory } = useDestroy({
url: destroy.url(props.category.id),
errorMessage: 'Gagal menghapus kategori.',
});
</script>
<template>

View File

@ -1,12 +1,10 @@
<script setup lang="ts">
import { router } from '@inertiajs/vue3';
import { Pencil, Trash2 } from '@lucide/vue';
import { ref } from 'vue';
import { toast } from 'vue-sonner';
import ConfirmDialog from '@/components/ConfirmDialog.vue';
import { Button } from '@/components/ui/button';
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip';
import { useCan } from '@/composables/useCan';
import { useDestroy } from '@/composables/useDestroy';
import type { CustomerListItem } from '@/types/customer';
import { destroy } from '@/routes/admin/master/customers';
@ -20,25 +18,10 @@ const emit = defineEmits<{
const { can } = useCan();
const deleteConfirmOpen = ref(false);
const deleteProcessing = ref(false);
function destroyCustomer() {
deleteProcessing.value = true;
router.delete(destroy.url(props.customer.id), {
preserveScroll: true,
onSuccess: () => {
deleteConfirmOpen.value = false;
},
onError: () => {
toast.error('Gagal menghapus customer.');
},
onFinish: () => {
deleteProcessing.value = false;
},
});
}
const { open: deleteConfirmOpen, processing: deleteProcessing, destroy: destroyCustomer } = useDestroy({
url: destroy.url(props.customer.id),
errorMessage: 'Gagal menghapus customer.',
});
</script>
<template>

View File

@ -1,12 +1,11 @@
<script setup lang="ts">
import { Link, router } from '@inertiajs/vue3';
import { Link } from '@inertiajs/vue3';
import { Pencil, Trash2 } from '@lucide/vue';
import { ref } from 'vue';
import { toast } from 'vue-sonner';
import ConfirmDialog from '@/components/ConfirmDialog.vue';
import { Button } from '@/components/ui/button';
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip';
import { useCan } from '@/composables/useCan';
import { useDestroy } from '@/composables/useDestroy';
import type { ProductListItem } from '@/types/product';
import { edit, destroy } from '@/routes/admin/master/products';
@ -16,24 +15,11 @@ const props = defineProps<{
const { can } = useCan();
const deleteConfirmOpen = ref(false);
const deleteProcessing = ref(false);
function destroyProduct() {
deleteProcessing.value = true;
router.delete(destroy.url(props.product.id), {
onSuccess: () => {
deleteConfirmOpen.value = false;
},
onError: () => {
toast.error('Gagal menghapus produk.');
},
onFinish: () => {
deleteProcessing.value = false;
},
});
}
const { open: deleteConfirmOpen, processing: deleteProcessing, destroy: destroyProduct } = useDestroy({
url: destroy.url(props.product.id),
preserveScroll: false,
errorMessage: 'Gagal menghapus produk.',
});
</script>
<template>

View File

@ -1,12 +1,11 @@
<script setup lang="ts">
import { Link, router } from '@inertiajs/vue3';
import { Link } from '@inertiajs/vue3';
import { Pencil, Trash2 } from '@lucide/vue';
import { ref } from 'vue';
import { toast } from 'vue-sonner';
import ConfirmDialog from '@/components/ConfirmDialog.vue';
import { Button } from '@/components/ui/button';
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip';
import { useCan } from '@/composables/useCan';
import { useDestroy } from '@/composables/useDestroy';
import type { RawMaterialListItem } from '@/types/raw-material';
import { edit, destroy } from '@/routes/admin/master/raw_materials';
@ -16,24 +15,11 @@ const props = defineProps<{
const { can } = useCan();
const deleteConfirmOpen = ref(false);
const deleteProcessing = ref(false);
function destroyRawMaterial() {
deleteProcessing.value = true;
router.delete(destroy.url(props.material.id), {
onSuccess: () => {
deleteConfirmOpen.value = false;
},
onError: () => {
toast.error('Gagal menghapus bahan baku.');
},
onFinish: () => {
deleteProcessing.value = false;
},
});
}
const { open: deleteConfirmOpen, processing: deleteProcessing, destroy: destroyRawMaterial } = useDestroy({
url: destroy.url(props.material.id),
preserveScroll: false,
errorMessage: 'Gagal menghapus bahan baku.',
});
</script>
<template>

View File

@ -1,12 +1,10 @@
<script setup lang="ts">
import { router } from '@inertiajs/vue3';
import { Pencil, Trash2 } from '@lucide/vue';
import { ref } from 'vue';
import { toast } from 'vue-sonner';
import ConfirmDialog from '@/components/ConfirmDialog.vue';
import { Button } from '@/components/ui/button';
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip';
import { useCan } from '@/composables/useCan';
import { useDestroy } from '@/composables/useDestroy';
import type { SupplierListItem } from '@/types/supplier';
import { destroy } from '@/routes/admin/master/suppliers';
@ -20,25 +18,10 @@ const emit = defineEmits<{
const { can } = useCan();
const deleteConfirmOpen = ref(false);
const deleteProcessing = ref(false);
function destroySupplier() {
deleteProcessing.value = true;
router.delete(destroy.url(props.supplier.id), {
preserveScroll: true,
onSuccess: () => {
deleteConfirmOpen.value = false;
},
onError: () => {
toast.error('Gagal menghapus supplier.');
},
onFinish: () => {
deleteProcessing.value = false;
},
});
}
const { open: deleteConfirmOpen, processing: deleteProcessing, destroy: destroySupplier } = useDestroy({
url: destroy.url(props.supplier.id),
errorMessage: 'Gagal menghapus supplier.',
});
</script>
<template>

View File

@ -1,12 +1,12 @@
<script setup lang="ts">
import { Link, router } from '@inertiajs/vue3';
import { Link } from '@inertiajs/vue3';
import { Pencil, Trash2 } from '@lucide/vue';
import { computed, ref } from 'vue';
import { toast } from 'vue-sonner';
import { computed } from 'vue';
import ConfirmDialog from '@/components/ConfirmDialog.vue';
import { Button } from '@/components/ui/button';
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip';
import { useCan } from '@/composables/useCan';
import { useDestroy } from '@/composables/useDestroy';
import type { RoleListItem } from './columns';
import { edit, destroy } from '@/routes/admin/system/roles';
@ -16,29 +16,14 @@ const props = defineProps<{
const { can } = useCan();
const deleteConfirmOpen = ref(false);
const deleteProcessing = ref(false);
const isSystemRole = computed(() => {
return ['developer', 'owner', 'admin-toko', 'admin-bahan-baku', 'direktur', 'marketing', 'cashier', 'non-operator'].includes(props.role.name);
});
function destroyRole() {
deleteProcessing.value = true;
router.delete(destroy.url(props.role.id), {
preserveScroll: true,
onSuccess: () => {
deleteConfirmOpen.value = false;
},
onError: () => {
toast.error('Gagal menghapus role.');
},
onFinish: () => {
deleteProcessing.value = false;
},
});
}
const { open: deleteConfirmOpen, processing: deleteProcessing, destroy: destroyRole } = useDestroy({
url: destroy.url(props.role.id),
errorMessage: 'Gagal menghapus role.',
});
</script>
<template>