IKHSAN
ENID Baca dalam Bahasa Indonesia

opendesk

Public
Branch
main
Latest commit
08d9f3328 October 2026

PageInfo.vue

Open raw
<template>
  <div class="flex items-center justify-between p-5 pb-0">
    <div class="gap-x-3 flex h-full">
      <Avatar
        :size="avatar.size ?? '3xl'"
        :shape="avatar.shape ?? 'square'"
        :label="avatar.label"
        :image="avatar.image"
        class="h-[52px] w-[52px]"
      />
      <div
        class="flex flex-col h-full gap-1.5"
        :class="[
          (isMobileView || !hasDocInfo) && 'flex-1 items-center justify-center',
        ]"
      >
        <div class="flex gap-2 items-center">
          <p class="text-ink-gray-8 text-xl-medium">
            {{ avatar.label }}
          </p>
          <Tooltip v-if="badge" :text="badge.tooltip ?? ''">
            <Badge :label="badge.label" :theme="badge.theme ?? 'amber'" />
          </Tooltip>
        </div>
        <div v-if="!isMobileView" class="flex items-center gap-x-1.5">
          <template v-for="(item, index) in docInfo" :key="index">
            <template v-if="item.condition !== false">
              <span
                v-if="
                  docInfo.slice(0, index).some((i) => i.condition !== false)
                "
                class="text-ink-gray-4"
              >
                •
              </span>
              <div class="flex items-center gap-x-1">
                <component
                  v-if="item.icon"
                  :is="item.icon"
                  class="h-4 w-4 text-ink-gray-6"
                />
                <span v-if="item.value" class="text-sm text-ink-gray-8">{{
                  item.value
                }}</span>
                <template v-else-if="item.component">
                  <component :is="item.component" />
                </template>
              </div>
            </template>
          </template>
        </div>
      </div>
    </div>
    <slot name="actions" />
  </div>
</template>

<script setup lang="ts">
import { useScreenSize } from "@/composables/screen";
import { Avatar, Badge, Tooltip, type AvatarProps } from "frappe-ui";
import { computed } from "vue";

interface DocInfoItem {
  icon?: any;
  value?: string;
  component?: any;
  condition?: boolean;
}

interface BadgeInfo {
  label: string;
  theme?: "gray" | "blue" | "green" | "amber" | "red";
  tooltip?: string;
}

const props = withDefaults(
  defineProps<{
    avatar: AvatarProps;
    docInfo?: DocInfoItem[];
    badge?: BadgeInfo | null;
  }>(),
  {
    docInfo: () => [],
    badge: null,
  }
);

const { isMobileView } = useScreenSize();

const hasDocInfo = computed(() => {
  return props.docInfo?.some((item) => item.value) ?? false;
});
</script>
bytes
2,606
lines
94
Type
vue
Latest commit
28 October 2026