mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-04-29 02:32:18 +00:00
refactor: Extract AssetsSidebarTab template and improve UI structure
- Extract sidebar template into reusable AssetSidebarTemplate component - Replace PrimeVue Tabs with TextButton for better visual consistency - Add i18n key for "Back to all assets" button - Improve job detail view header layout with better spacing - Maintain existing functionality while cleaning up template structure
This commit is contained in:
33
src/components/sidebar/tabs/AssetSidebarTemplate.vue
Normal file
33
src/components/sidebar/tabs/AssetSidebarTemplate.vue
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
<template>
|
||||||
|
<div
|
||||||
|
class="flex h-full flex-col bg-white dark-theme:bg-zinc-900"
|
||||||
|
:class="props.class"
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<div
|
||||||
|
v-if="slots.top"
|
||||||
|
class="flex min-h-12 items-center border-b border-zinc-200 px-4 py-2 dark-theme:border-zinc-700"
|
||||||
|
>
|
||||||
|
<slot name="top" />
|
||||||
|
</div>
|
||||||
|
<div v-if="slots.header" class="px-4">
|
||||||
|
<slot name="header" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- h-0 to force scrollpanel to grow -->
|
||||||
|
<ScrollPanel class="h-0 grow">
|
||||||
|
<slot name="body" />
|
||||||
|
</ScrollPanel>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import ScrollPanel from 'primevue/scrollpanel'
|
||||||
|
import { useSlots } from 'vue'
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
class?: string
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const slots = useSlots()
|
||||||
|
</script>
|
||||||
@@ -1,45 +1,52 @@
|
|||||||
<template>
|
<template>
|
||||||
<SidebarTabTemplate
|
<AssetsSidebarTemplate>
|
||||||
:title="isInFolderView ? '' : $t('sideToolbar.mediaAssets')"
|
<template #top>
|
||||||
>
|
<span v-if="!isInFolderView" class="font-bold">
|
||||||
<template v-if="isInFolderView" #tool-buttons>
|
{{ $t('sideToolbar.mediaAssets') }}
|
||||||
<div class="flex w-full items-center gap-2">
|
</span>
|
||||||
<span class="font-medium"
|
<div v-else class="flex w-full items-center justify-between gap-2">
|
||||||
>Job ID: {{ folderPromptId?.substring(0, 8) }}</span
|
<div class="flex items-center gap-2">
|
||||||
>
|
<span class="font-bold">{{ $t('Job ID') }}:</span>
|
||||||
<button
|
<span class="text-sm">{{ folderPromptId?.substring(0, 8) }}</span>
|
||||||
class="rounded p-1 transition-colors hover:bg-neutral-100 dark-theme:hover:bg-neutral-700"
|
<i class="mb-1 icon-[lucide--copy] text-sm" @click="copyJobId"></i>
|
||||||
:title="$t('g.copy')"
|
</div>
|
||||||
@click="copyJobId"
|
<div>
|
||||||
>
|
<span>{{ formattedExecutionTime }}</span>
|
||||||
<i class="icon-[lucide--copy] size-4" />
|
</div>
|
||||||
</button>
|
|
||||||
<span class="ml-auto text-sm text-neutral-500">
|
|
||||||
{{ formattedExecutionTime }}
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #header>
|
<template #header>
|
||||||
<!-- Job Detail View Header -->
|
<!-- Job Detail View Header -->
|
||||||
<div
|
<div v-if="isInFolderView" class="pt-4 pb-1">
|
||||||
v-if="isInFolderView"
|
<IconTextButton
|
||||||
class="border-b border-neutral-300 px-4 pt-2 pb-3 dark-theme:border-neutral-700"
|
:label="$t('sideToolbar.backToAssets')"
|
||||||
>
|
type="secondary"
|
||||||
<button
|
|
||||||
class="flex items-center gap-2 rounded bg-neutral-100 px-3 py-1.5 text-sm transition-colors hover:bg-neutral-200 dark-theme:bg-neutral-700 dark-theme:hover:bg-neutral-600"
|
|
||||||
@click="exitFolderView"
|
@click="exitFolderView"
|
||||||
>
|
>
|
||||||
<i class="icon-[lucide--arrow-left] size-4" />
|
<template #icon>
|
||||||
<span>Back to all assets</span>
|
<i class="icon-[lucide--arrow-left] size-4" />
|
||||||
</button>
|
</template>
|
||||||
|
</IconTextButton>
|
||||||
</div>
|
</div>
|
||||||
<!-- Normal Tab View -->
|
<!-- Normal Tab View -->
|
||||||
<Tabs v-model:value="activeTab" class="w-full">
|
<div v-else class="flex items-center gap-2 pt-4 pb-1">
|
||||||
|
<TextButton
|
||||||
|
:label="$t('sideToolbar.labels.imported')"
|
||||||
|
:type="activeTab === 'input' ? 'secondary' : 'transparent'"
|
||||||
|
@click.stop="activeTab = 'input'"
|
||||||
|
/>
|
||||||
|
<TextButton
|
||||||
|
:label="$t('sideToolbar.labels.generated')"
|
||||||
|
:type="activeTab === 'output' ? 'secondary' : 'transparent'"
|
||||||
|
@click.stop="activeTab = 'output'"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<!-- <Tabs v-else v-model:value="activeTab" class="w-full">
|
||||||
<TabList class="border-b border-neutral-300">
|
<TabList class="border-b border-neutral-300">
|
||||||
<Tab value="input">{{ $t('sideToolbar.labels.imported') }}</Tab>
|
<Tab value="input">{{ $t('sideToolbar.labels.imported') }}</Tab>
|
||||||
<Tab value="output">{{ $t('sideToolbar.labels.generated') }}</Tab>
|
<Tab value="output">{{ $t('sideToolbar.labels.generated') }}</Tab>
|
||||||
</TabList>
|
</TabList>
|
||||||
</Tabs>
|
</Tabs> -->
|
||||||
</template>
|
</template>
|
||||||
<template #body>
|
<template #body>
|
||||||
<VirtualGrid
|
<VirtualGrid
|
||||||
@@ -87,7 +94,7 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</SidebarTabTemplate>
|
</AssetsSidebarTemplate>
|
||||||
<ResultGallery
|
<ResultGallery
|
||||||
v-model:active-index="galleryActiveIndex"
|
v-model:active-index="galleryActiveIndex"
|
||||||
:all-gallery-items="galleryItems"
|
:all-gallery-items="galleryItems"
|
||||||
@@ -96,15 +103,13 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import ProgressSpinner from 'primevue/progressspinner'
|
import ProgressSpinner from 'primevue/progressspinner'
|
||||||
import Tab from 'primevue/tab'
|
|
||||||
import TabList from 'primevue/tablist'
|
|
||||||
import Tabs from 'primevue/tabs'
|
|
||||||
import { useToast } from 'primevue/usetoast'
|
import { useToast } from 'primevue/usetoast'
|
||||||
import { computed, onMounted, ref, watch } from 'vue'
|
import { computed, onMounted, ref, watch } from 'vue'
|
||||||
|
|
||||||
|
import IconTextButton from '@/components/button/IconTextButton.vue'
|
||||||
|
import TextButton from '@/components/button/TextButton.vue'
|
||||||
import NoResultsPlaceholder from '@/components/common/NoResultsPlaceholder.vue'
|
import NoResultsPlaceholder from '@/components/common/NoResultsPlaceholder.vue'
|
||||||
import VirtualGrid from '@/components/common/VirtualGrid.vue'
|
import VirtualGrid from '@/components/common/VirtualGrid.vue'
|
||||||
import SidebarTabTemplate from '@/components/sidebar/tabs/SidebarTabTemplate.vue'
|
|
||||||
import ResultGallery from '@/components/sidebar/tabs/queue/ResultGallery.vue'
|
import ResultGallery from '@/components/sidebar/tabs/queue/ResultGallery.vue'
|
||||||
import MediaAssetCard from '@/platform/assets/components/MediaAssetCard.vue'
|
import MediaAssetCard from '@/platform/assets/components/MediaAssetCard.vue'
|
||||||
import { useMediaAssets } from '@/platform/assets/composables/useMediaAssets'
|
import { useMediaAssets } from '@/platform/assets/composables/useMediaAssets'
|
||||||
@@ -115,6 +120,8 @@ import {
|
|||||||
getMediaTypeFromFilenamePlural
|
getMediaTypeFromFilenamePlural
|
||||||
} from '@/utils/formatUtil'
|
} from '@/utils/formatUtil'
|
||||||
|
|
||||||
|
import AssetsSidebarTemplate from './AssetSidebarTemplate.vue'
|
||||||
|
|
||||||
const activeTab = ref<'input' | 'output'>('input')
|
const activeTab = ref<'input' | 'output'>('input')
|
||||||
const mediaAssets = ref<AssetItem[]>([])
|
const mediaAssets = ref<AssetItem[]>([])
|
||||||
const selectedAsset = ref<AssetItem | null>(null)
|
const selectedAsset = ref<AssetItem | null>(null)
|
||||||
|
|||||||
@@ -597,6 +597,7 @@
|
|||||||
"templates": "Templates",
|
"templates": "Templates",
|
||||||
"assets": "Assets",
|
"assets": "Assets",
|
||||||
"mediaAssets": "Media Assets",
|
"mediaAssets": "Media Assets",
|
||||||
|
"backToAssets": "Back to all assets",
|
||||||
"labels": {
|
"labels": {
|
||||||
"queue": "Queue",
|
"queue": "Queue",
|
||||||
"nodes": "Nodes",
|
"nodes": "Nodes",
|
||||||
|
|||||||
Reference in New Issue
Block a user