IKHSAN
ENID Baca dalam Bahasa Indonesia

opendesk

Public
Branch
main
Latest commit
08d9f3328 October 2026

AgentTicketsCard.vue

Open raw
<template>
  <div class="w-full h-full overflow-hidden">
    <CardBase
      :title="__('My Tickets')"
      :text="chartData.total"
      :percentageChange="chartData.percentageChange"
      :chartConfig="chartConfig"
      :currentDuration="currentDuration"
      @changeDuration="changeDuration"
    />
  </div>
</template>

<script setup lang="ts">
import { __ } from "@/translation";
import type { LineChart } from "@/types";
import { buildPercentageChange } from "@/utils";
import { EChartsOption } from "echarts";
import { createResource } from "frappe-ui";
import { computed, onMounted, ref, type PropType } from "vue";
import CardBase from "../../../components/ChartCardBase.vue";

const props = defineProps({
  data: {
    type: Object as PropType<LineChart>,
    required: true,
  },
});

// the untranslated key: it is lowercased straight into the API period
const currentDuration = ref("Last month");

const chartColor = {
  lineColor: "#5597F3",
  gradientColor: { start: "#abccfc", end: "rgba(229,240,254,0)" },
};

const chartData = computed(() => {
  const _data: LineChart = getAgentTicketsResource.fetched
    ? getAgentTicketsResource.data
    : props.data;

  const _percentageChange = _data?.percentage_change || 0;
  const total = _data?.total || 0;
  const dates = _data?.data?.map((item) => item.date) || [];
  const counts = _data?.data?.map((item) => item.count) || [];

  const percentageChange = buildPercentageChange(_percentageChange);

  return {
    data: counts,
    percentageChange,
    total,
    counts,
    dates,
  };
});

const chartConfig = computed<EChartsOption>(() => {
  const color = chartColor.lineColor;
  const gradientColor = chartColor.gradientColor;
  return {
    xAxis: {
      type: "category",
      data: chartData.value.dates,
      show: false,
      boundaryGap: false,
    },
    yAxis: {
      type: "value",
      show: false,
    },
    series: [
      {
        data: chartData.value.data,
        type: "line",
        symbol: "none",
        lineStyle: {
          width: 1.25,
        },
        areaStyle: {
          opacity: 0.8,
          color: {
            type: "linear",
            x: 0,
            y: 0,
            x2: 0,
            y2: 1,
            colorStops: [
              {
                offset: 0,
                color: gradientColor.start,
              },
              {
                offset: 1,
                color: gradientColor.end,
              },
            ],
            global: false,
          },
        },
      },
    ],
    color: color,
    grid: {
      left: 2,
      right: 2,
      top: 2,
      bottom: 2,
    },
  };
});

const getAgentTicketsResource = createResource({
  url: "opendesk.api.agent_home.agent_home.get_agent_tickets",
  type: "GET",
  makeParams: () => {
    return {
      period: currentDuration.value.toLowerCase(),
    };
  },
});

const changeDuration = (period: string) => {
  currentDuration.value = period;
  getAgentTicketsResource.submit();
};

onMounted(() => {
  if (!props.data?.data) {
    getAgentTicketsResource.submit();
  }
});
</script>
bytes
3,096
lines
135
Type
vue
Latest commit
28 October 2026