|
1 | 1 | <template> |
2 | 2 | <div class="inline-flex items-center gap-1"> |
3 | | - <div |
4 | | - class="overflow-hidden max-h-[20px] rounded-default" |
5 | | - :title="show ? $t('Click to hide') : $t('Click to show')" |
6 | | - @click="toggle" |
7 | | - > |
8 | | - <span |
9 | | - class="cursor-pointer select-none transition-all duration-200 text-lightListTableText dark:text-darkListTableText" |
10 | | - :class="{ |
11 | | - 'blur-[7px] hover:blur-[5px] brightness-50 dark:brightness-150': !show, |
12 | | - }" |
| 3 | + <Tooltip> |
| 4 | + <div |
| 5 | + class="overflow-hidden max-h-[20px] rounded-default" |
| 6 | + :class="{ 'shrink-0 w-[90px]': compact }" |
| 7 | + @click="toggle" |
13 | 8 | > |
14 | | - <ValueRenderer :column="column" :record="record" /> |
15 | | - </span> |
16 | | - </div> |
| 9 | + <span |
| 10 | + class="cursor-pointer select-none transition-all duration-200 text-lightListTableText dark:text-darkListTableText" |
| 11 | + :class="{ |
| 12 | + 'block truncate': compact, |
| 13 | + 'blur-[7px] hover:blur-[5px] brightness-50 dark:brightness-150': !show, |
| 14 | + }" |
| 15 | + > |
| 16 | + <template v-if="compact">{{ visualValue }}</template> |
| 17 | + <ValueRenderer v-else :column="column" :record="record" /> |
| 18 | + </span> |
| 19 | + </div> |
| 20 | + <template #tooltip> |
| 21 | + <span class="whitespace-nowrap">{{ tooltipText }}</span> |
| 22 | + </template> |
| 23 | + </Tooltip> |
| 24 | + |
| 25 | + <IconFileCopyAltSolid |
| 26 | + v-if="showCopy && rawValue" |
| 27 | + @click.stop="copyToCB" |
| 28 | + class="shrink-0 min-w-5 min-h-5 cursor-pointer text-lightPrimary dark:text-darkPrimary" |
| 29 | + /> |
17 | 30 | </div> |
18 | 31 | </template> |
19 | 32 |
|
20 | 33 | <script setup lang="ts"> |
21 | | -import { ref } from 'vue'; |
| 34 | +import { ref, computed } from 'vue'; |
| 35 | +import { useI18n } from 'vue-i18n'; |
| 36 | +import { IconFileCopyAltSolid } from '@iconify-prerendered/vue-flowbite'; |
22 | 37 | import ValueRenderer from '@/components/ValueRenderer.vue'; |
| 38 | +import Tooltip from '@/afcl/Tooltip.vue'; |
| 39 | +import { useAdminforth } from '@/adminforth'; |
23 | 40 | import type { AdminForthResourceColumnCommon, AdminForthResourceCommon, AdminUser } from '@/types/Common'; |
24 | 41 |
|
25 | 42 | const props = defineProps<{ |
26 | 43 | column: AdminForthResourceColumnCommon; |
27 | 44 | record: any; |
28 | | - meta: any; |
| 45 | + meta: { compact?: boolean; copy?: boolean } | any; |
29 | 46 | resource: AdminForthResourceCommon; |
30 | 47 | adminUser: AdminUser; |
31 | 48 | }>(); |
32 | 49 |
|
| 50 | +const { t } = useI18n(); |
| 51 | +const { alert } = useAdminforth(); |
| 52 | +
|
33 | 53 | const show = ref(false); |
34 | 54 |
|
| 55 | +const rawValue = computed(() => props.record[props.column.name]); |
| 56 | +
|
| 57 | +const compact = computed(() => props.meta?.compact); |
| 58 | +const showCopy = computed(() => compact.value && props.meta?.copy); |
| 59 | +const visualValue = computed(() => { |
| 60 | + const val = rawValue.value; |
| 61 | + if (val && String(val).length > 8) { |
| 62 | + const s = String(val); |
| 63 | + return `${s.slice(0, 4)}...${s.slice(-4)}`; |
| 64 | + } |
| 65 | + return val; |
| 66 | +}); |
| 67 | +
|
| 68 | +const tooltipText = computed(() => { |
| 69 | + if (compact.value && show.value) { |
| 70 | + return rawValue.value; |
| 71 | + } |
| 72 | + return show.value ? t('Click to hide') : t('Click to show'); |
| 73 | +}); |
| 74 | +
|
35 | 75 | function toggle(event: MouseEvent) { |
36 | 76 | show.value = !show.value; |
37 | 77 | event.stopPropagation(); |
38 | 78 | } |
| 79 | +
|
| 80 | +function copyToCB() { |
| 81 | + navigator.clipboard.writeText(rawValue.value); |
| 82 | + alert({ |
| 83 | + message: t('Copied to clipboard'), |
| 84 | + variant: 'success', |
| 85 | + }); |
| 86 | +} |
39 | 87 | </script> |
0 commit comments