IKHSAN
ENID Baca dalam Bahasa Indonesia

opendesk

Public
Branch
main
Latest commit
08d9f3328 October 2026

PreviewDialog.vue

Open raw
<template>
  <Dialog
    v-model:open="dialogModel.show"
    :title="__('Preview')"
    size="2xl"
    @after-leave="
      () => {
        dialogModel.ticketId = '';
        dialogModel.preview = null;
      }
    "
  >
    <template #default>
      <div class="space-y-4">
        <Link
          :value="dialogModel.ticketId"
          :label="__('Select ticket to preview')"
          doctype="OD Ticket"
          class="form-control flex-1"
          :placeholder="__('Search ticket')"
          :show-description="true"
          hide-clear-button
          @change="getResponsePreview"
        />

        <div class="space-y-1.5">
          <FormLabel :label="__('Preview')" />
          <div class="relative pointer-events-none">
            <Editor
              :model-value="dialogModel.preview"
              :extensions="extensions"
              :editable="false"
            >
              <template #default>
                <EditorContent
                  class="!prose-sm max-w-full overflow-auto min-h-[180px] max-h-80 py-1.5 px-2 rounded-4 border border-[--surface-gray-2] bg-surface-gray-2 placeholder-ink-gray-4 hover:border-outline-elevation-2 hover:bg-surface-gray-3 hover:shadow-sm focus:bg-surface-base focus:border-outline-gray-4 focus:shadow-sm focus:ring-0 focus-visible:ring-2 focus-visible:ring-outline-gray-3 text-ink-gray-8 transition-colors"
                />
              </template>
            </Editor>
            <div
              v-if="getResponsePreviewResource.loading"
              class="absolute top-0 end-0 flex items-center justify-center size-full rounded-5 bg-surface-gray-10/20"
            >
              <LoadingIndicator class="size-4" />
            </div>
          </div>
        </div>
      </div>
    </template>
  </Dialog>
</template>

<script setup lang="ts">
import { Link } from "@/components";
import { buildEditorExtensions } from "@/components/editor/config";
import { __ } from "@/translation";
import { RenderedSavedReply } from "@/types";
import {
  createListResource,
  createResource,
  Dialog,
  FormLabel,
  LoadingIndicator,
  toast,
} from "frappe-ui";
import { Editor, EditorContent } from "frappe-ui/editor";
import { watch } from "vue";
const extensions = buildEditorExtensions();

const dialogModel = defineModel<{
  show: boolean;
  ticketId: string;
  savedReply: string;
  preview: string;
}>();

const getResponsePreviewResource = createResource({
  url: "opendesk.api.saved_replies.get_rendered_saved_reply",
  onSuccess: (data: RenderedSavedReply) => {
    dialogModel.value.preview = data.message;
  },
});

const getResponsePreview = (ticketId: string) => {
  if (!ticketId) return;
  dialogModel.value.ticketId = ticketId;
  dialogModel.value.preview = null;
  getResponsePreviewResource.submit({
    ticket_id: ticketId,
    saved_reply_id: dialogModel.value.savedReply,
  });
};

watch(
  () => dialogModel.value.show,
  (newShowValue) => {
    if (newShowValue) {
      createListResource({
        doctype: "OD Ticket",
        fields: ["name"],
        start: 0,
        pageLength: 1,
        auto: true,
        onSuccess: (data) => {
          if (data.length === 0) {
            toast.error(__("No tickets found to preview."));
            return;
          }
          dialogModel.value.ticketId = data[0].name;
          getResponsePreview(data[0].name);
        },
      });
    }
  }
);
</script>
bytes
3,411
lines
117
Type
vue
Latest commit
28 October 2026