123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110 |
- <template>
- <ui-card
- class="hover:ring-2 flex flex-col group hover:ring-accent dark:hover:ring-gray-200"
- >
- <slot name="header">
- <div class="flex items-center mb-4">
- <ui-img
- v-if="data.icon?.startsWith('http')"
- :src="data.icon"
- class="overflow-hidden rounded-lg"
- style="height: 40px; width: 40px"
- alt="Can not display"
- />
- <span v-else class="p-2 rounded-lg bg-box-transparent">
- <v-remixicon :name="data.icon || icon" />
- </span>
- <div class="flex-grow"></div>
- <button
- class="invisible group-hover:visible"
- @click="$emit('execute', data)"
- >
- <v-remixicon name="riPlayLine" />
- </button>
- <ui-popover v-if="showDetails" class="h-6 ml-2">
- <template #trigger>
- <button>
- <v-remixicon name="riMoreLine" />
- </button>
- </template>
- <ui-list class="space-y-1" style="min-width: 150px">
- <ui-list-item
- v-for="item in menu"
- :key="item.id"
- v-close-popover
- class="cursor-pointer"
- @click="$emit('menuSelected', { id: item.id, data })"
- >
- <v-remixicon :name="item.icon" class="mr-2 -ml-1" />
- <span class="capitalize">{{ item.name }}</span>
- </ui-list-item>
- </ui-list>
- </ui-popover>
- </div>
- </slot>
- <div class="cursor-pointer flex-1" @click="$emit('click', data)">
- <p class="line-clamp font-semibold leading-tight">
- {{ data.name }}
- </p>
- <p
- v-show="data.description"
- class="text-gray-600 dark:text-gray-200 line-clamp leading-tight mb-1"
- >
- {{ data.description }}
- </p>
- </div>
- <div class="flex items-center text-gray-600 dark:text-gray-200">
- <p class="flex-1">{{ state.date }}</p>
- <slot name="footer-content" />
- <v-remixicon
- v-if="state.triggerText"
- v-tooltip="state.triggerText"
- :class="{ 'ml-2': $slots['footer-content'] }"
- name="riFlashlightLine"
- size="20"
- />
- </div>
- </ui-card>
- </template>
- <script setup>
- import { onMounted, shallowReactive } from 'vue';
- import { useI18n } from 'vue-i18n';
- import dayjs from '@/lib/dayjs';
- import triggerText from '@/utils/trigger-text';
- const props = defineProps({
- data: {
- type: Object,
- default: () => ({}),
- },
- icon: {
- type: String,
- default: 'riGlobalLine',
- },
- showDetails: {
- type: Boolean,
- default: true,
- },
- menu: {
- type: Array,
- default: () => [],
- },
- });
- defineEmits(['execute', 'click', 'menuSelected']);
- const { t } = useI18n();
- const state = shallowReactive({
- triggerText: null,
- date: dayjs(props.data.createdAt).fromNow(),
- });
- onMounted(async () => {
- const { trigger, id } = props.data;
- if (!trigger) return;
- state.triggerText = await triggerText(trigger, t, id);
- });
- </script>
|