77 }"
88 :pt =" {
99 body: { class: 'p-0 flex flex-col w-full h-full rounded-2xl gap-0' },
10- content: { class: 'flex-1 flex flex-col rounded-2xl' },
11- title: {
12- class:
13- 'self-stretch w-full px-4 py-3 inline-flex justify-start items-center gap-6'
14- },
10+ content: { class: 'flex-1 flex flex-col rounded-2xl min-h-0' },
11+ title: { class: 'w-full h-full rounded-t-lg cursor-pointer' },
1512 footer: { class: 'p-0 m-0' }
1613 }"
1714 >
1815 <template #title >
19- <PackCardHeader :node-pack =" nodePack" />
16+ <PackBanner :node-pack =" nodePack" />
2017 </template >
2118 <template #content >
22- <ContentDivider />
2319 <template v-if =" isInstalling " >
2420 <div
2521 class =" self-stretch inline-flex flex-col justify-center items-center gap-2 h-full"
3430 </template >
3531 <template v-else >
3632 <div
37- class =" self-stretch px-4 py-3 inline-flex justify-start items-start cursor-pointer "
33+ class =" self-stretch inline-flex flex-col justify-start items-start"
3834 >
39- <PackIcon :node-pack =" nodePack" />
4035 <div
41- class =" px-4 inline-flex flex-col justify-start items-start overflow-hidden "
36+ class =" px-4 py-3 inline-flex justify-start items-start cursor-pointer w-full "
4237 >
43- <span
44- class =" text-sm font-bold truncate overflow-hidden text-ellipsis"
45- >
46- {{ nodePack.name }}
47- </span >
4838 <div
49- class =" self-stretch inline-flex justify-center items-center gap-2.5 "
39+ class =" inline-flex flex-col justify-start items-start overflow-hidden gap-y-3 w-full "
5040 >
41+ <span
42+ class =" text-base font-bold truncate overflow-hidden text-ellipsis"
43+ >
44+ {{ nodePack.name }}
45+ </span >
5146 <p
5247 v-if =" nodePack.description"
53- class =" flex-1 justify-start text-muted text-sm font-medium leading-3 break-words overflow-hidden min-h-12 line-clamp-3"
48+ class =" flex-1 justify-start text-muted text-sm font-medium break-words overflow-hidden min-h-12 line-clamp-3 my-0 leading-5 "
5449 >
5550 {{ nodePack.description }}
5651 </p >
57- </div >
58- <div
59- class =" self-stretch inline-flex justify-start items-center gap-2"
60- >
61- <div
62- v-if =" nodesCount"
63- class =" px-2 py-1 flex justify-center text-sm items-center gap-1"
64- >
65- <div class =" text-center justify-center font-medium leading-3" >
66- {{ nodesCount }} {{ $t('g.nodes') }}
67- </div >
68- </div >
69- <div class =" px-2 py-1 flex justify-center items-center gap-1" >
52+ <div class =" flex flex-col gap-y-2" >
7053 <div
71- v-if =" isUpdateAvailable"
72- class =" w-4 h-4 relative overflow-hidden"
54+ class =" self-stretch inline-flex justify-start items-center gap-1"
7355 >
74- <i class =" pi pi-arrow-circle-up text-blue-600" />
56+ <div
57+ v-if =" nodesCount"
58+ class =" pr-2 py-1 flex justify-center text-sm items-center gap-1"
59+ >
60+ <div
61+ class =" text-center justify-center font-medium leading-3"
62+ >
63+ {{ nodesCount }} {{ $t('g.nodes') }}
64+ </div >
65+ </div >
66+ <div class =" px-2 py-1 flex justify-center items-center gap-1" >
67+ <div
68+ v-if =" isUpdateAvailable"
69+ class =" w-4 h-4 relative overflow-hidden"
70+ >
71+ <i class =" pi pi-arrow-circle-up text-blue-600" />
72+ </div >
73+ <PackVersionBadge :node-pack =" nodePack" />
74+ </div >
75+ <div
76+ v-if =" formattedLatestVersionDate"
77+ class =" px-2 py-1 flex justify-center items-center gap-1 text-xs text-muted font-medium"
78+ >
79+ {{ formattedLatestVersionDate }}
80+ </div >
81+ </div >
82+ <div class =" flex" >
83+ <span
84+ v-if =" publisherName"
85+ class =" text-xs text-muted font-medium leading-3 max-w-40 truncate"
86+ >
87+ {{ publisherName }}
88+ </span >
7589 </div >
76- <PackVersionBadge :node-pack =" nodePack" />
7790 </div >
7891 </div >
7992 </div >
@@ -92,11 +105,12 @@ import { whenever } from '@vueuse/core'
92105import Card from ' primevue/card'
93106import ProgressSpinner from ' primevue/progressspinner'
94107import { computed , provide , ref } from ' vue'
108+ import { useI18n } from ' vue-i18n'
95109
96110import ContentDivider from ' @/components/common/ContentDivider.vue'
97111import PackVersionBadge from ' @/components/dialog/content/manager/PackVersionBadge.vue'
112+ import PackBanner from ' @/components/dialog/content/manager/packBanner/PackBanner.vue'
98113import PackCardFooter from ' @/components/dialog/content/manager/packCard/PackCardFooter.vue'
99- import PackIcon from ' @/components/dialog/content/manager/packIcon/PackIcon.vue'
100114import { usePackUpdateStatus } from ' @/composables/nodePack/usePackUpdateStatus'
101115import { useComfyManagerStore } from ' @/stores/comfyManagerStore'
102116import { IsInstallingKey } from ' @/types/comfyManagerTypes'
@@ -107,6 +121,8 @@ const { nodePack, isSelected = false } = defineProps<{
107121 isSelected? : boolean
108122}>()
109123
124+ const { d } = useI18n ()
125+
110126const isInstalling = ref (false )
111127provide (IsInstallingKey , isInstalling )
112128
@@ -122,4 +138,19 @@ whenever(isInstalled, () => (isInstalling.value = false))
122138
123139// TODO: remove type assertion once comfy_nodes is added to node (pack) info type in backend
124140const nodesCount = computed (() => (nodePack as any ).comfy_nodes ?.length )
141+
142+ const publisherName = computed (() => {
143+ if (! nodePack ) return null
144+
145+ const { publisher, author } = nodePack
146+ return publisher ?.name ?? publisher ?.id ?? author
147+ })
148+
149+ const formattedLatestVersionDate = computed (() => {
150+ if (! nodePack .latest_version ?.createdAt ) return null
151+
152+ return d (new Date (nodePack .latest_version .createdAt ), {
153+ dateStyle: ' medium'
154+ })
155+ })
125156 </script >
0 commit comments