IKHSAN
EN Read in EnglishID

opendesk

Publik
Branch
main
Commit terakhir
08d9f3328 Oktober 2026

CallLogs.vue

Buka raw
<template>
  <div class="flex flex-col">
    <LayoutHeader>
      <template #left-header>
        <div class="text-lg-medium text-ink-gray-9">Call Logs</div>
      </template>
      <template #right-header>
        <Button
          label="New Call Log"
          theme="gray"
          variant="solid"
          @click="newCallLog"
          icon-left="lucide-plus"
        />
      </template>
    </LayoutHeader>
    <ListViewBuilder
      ref="listViewRef"
      :options="options"
      @row-click="openCallLog"
    />
    <CallLogDetailModal
      v-model="showCallLogDetailModal"
      v-model:callLogModal="showCallLogModal"
      :callLogId="callLogId"
    />
    <CallLogModal
      v-model="showCallLogModal"
      :callLogId="callLogId"
      @after-insert="
        () => {
          listViewRef?.reload();
        }
      "
    />
  </div>
</template>

<script setup lang="ts">
import Icon from "@opendesk/shared/Icon.vue";
import LayoutHeader from "@/components/LayoutHeader.vue";
import ListViewBuilder from "@/components/ListViewBuilder.vue";
import { Avatar, Badge, Button, usePageMeta } from "frappe-ui";
import { computed, h, ref } from "vue";
import CallLogDetailModal from "./CallLogDetailModal.vue";
import CallLogModal from "./CallLogModal.vue";
import { statusColorMap, statusLabelMap } from "./utils";
import { PhoneIcon } from "@/components/icons";

const showCallLogModal = ref(false);
const showCallLogDetailModal = ref(false);
const callLogId = ref("");

const listViewRef = ref(null);

const options = computed(() => {
  return {
    doctype: "TP Call Log",
    selectable: true,
    showSelectBanner: true,
    emptyState: {
      title: "No Call Logs Found",
      icon: PhoneIcon,
    },
    columnConfig: {
      caller: {
        prefix: ({ row }) => {
          return h(Avatar, {
            shape: "circle",
            image: row._caller?.image || "Unknown",
            label: row._caller?.label || "Unknown",
            size: "sm",
          });
        },
        custom: ({ row }) => {
          return h("span", row._caller?.label || "Unknown");
        },
      },
      receiver: {
        prefix: ({ row }) => {
          return h(Avatar, {
            shape: "circle",
            image: row._receiver?.image || "Unknown",
            label: row._receiver?.label || "Unknown",
            size: "sm",
          });
        },
        custom: ({ row }) => {
          return h("span", row._receiver?.label || "Unknown");
        },
      },
      type: {
        prefix: ({ row }) => {
          let icon =
            row.type === "Incoming"
              ? "lucide-phone-incoming"
              : "lucide-phone-outgoing";
          return h(Icon, {
            icon,
            class: ["size-3 shrink-0"],
          });
        },
      },
      status: {
        custom: ({ row }) => {
          return h(Badge, {
            label: statusLabelMap[row.status],
            variant: "subtle",
            theme: statusColorMap[row.status],
          });
        },
      },
      duration: {
        prefix: () => {
          return h(Icon, {
            icon: "lucide-clock",
            class: ["size-3 shrink-0"],
          });
        },
        custom: ({ row }) => {
          return h("span", row.duration ? row.duration + "s" : "0s");
        },
      },
    },
  };
});

const newCallLog = () => {
  callLogId.value = "";
  showCallLogModal.value = true;
};

function openCallLog(id: string): void {
  callLogId.value = id;
  showCallLogDetailModal.value = true;
}

usePageMeta(() => {
  return {
    title: "Call Logs",
  };
});
</script>
byte
3.601
baris
144
Jenis
vue
Commit terakhir
28 Oktober 2026