IKHSAN
EN Read in EnglishID

opendesk

Publik
Branch
main
Commit terakhir
08d9f3328 Oktober 2026

DeleteWithTicketsDialog.vue

Buka raw
<template>
  <Dialog v-model:open="open" :title="dialogTitle" size="md">
    <template #default>
      <div class="flex flex-col gap-4">
        <p class="text-p-base text-ink-gray-7">{{ message }}</p>
        <Checkbox
          v-if="count"
          size="sm"
          v-model="deleteLinkedTickets"
          :label="__('Delete {0} ticket(s)', [count])"
        />
      </div>
    </template>
    <template #actions>
      <div class="flex justify-end">
        <Button
          variant="solid"
          theme="red"
          icon-left="lucide-trash-2"
          :label="__('Delete')"
          :loading="isDeleting"
          @click="confirmDelete"
        />
      </div>
    </template>
  </Dialog>
</template>

<script setup lang="ts">
import { __ } from "@/translation";
import { Button, Checkbox, createResource, Dialog } from "frappe-ui";
import { computed, ref, watch } from "vue";

const props = defineProps<{
  /** Name of the record being deleted. */
  name: string;
  /** OD Ticket link field that ties tickets to this record. */
  linkField: "customer" | "contact";
  /** Confirmation copy shown above the checkbox. */
  message: string;
  title?: string;
  /** Async delete handler; the button stays in a loading state until it settles. */
  onDelete: (payload: { deleteLinkedTickets: boolean }) => Promise<void> | void;
}>();

const open = defineModel<boolean>({ default: false });

const resource = createResource({
  url: "frappe.client.get_count",
  params: {
    doctype: "OD Ticket",
    filters: { [props.linkField]: props.name },
  },
  auto: true,
});

const count = computed<number>(() => {
  if (resource.loading) return 0;
  return resource.data ?? 0;
});

const deleteLinkedTickets = ref(false);
const isDeleting = ref(false);

const dialogTitle = computed(() => props.title ?? __("Delete"));

async function confirmDelete() {
  if (isDeleting.value) return;
  isDeleting.value = true;
  try {
    await props.onDelete({ deleteLinkedTickets: deleteLinkedTickets.value });
    open.value = false;
  } catch {
    // Keep the dialog open on failure; the handler surfaces the error.
  } finally {
    isDeleting.value = false;
  }
}

watch(
  open,
  (isOpen) => {
    if (isOpen) {
      resource.reload();
    }
  },
  { immediate: true }
);
</script>
byte
2.285
baris
90
Jenis
vue
Commit terakhir
28 Oktober 2026