Fix formatting and linting issues

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
snomiao
2025-08-18 05:45:14 +00:00
parent 808d63996c
commit afd561eb83
5 changed files with 124 additions and 35 deletions

View File

@@ -42,7 +42,7 @@
> >
<span v-if="index === 0" :class="['mr-2 pi', row.icon]"></span> <span v-if="index === 0" :class="['mr-2 pi', row.icon]"></span>
<span class="whitespace-nowrap overflow-hidden text-ellipsis"> <span class="whitespace-nowrap overflow-hidden text-ellipsis">
{{ row._display[item.key] }} {{ (row._display as any)[item.key] }}
</span> </span>
</div> </div>
</div> </div>
@@ -73,9 +73,7 @@ type Item = {
size: number size: number
} }
type RecordString<T> = { type RecordString<T> = Record<keyof T, any>
[key in keyof T]: T[key]
}
type ResolvedItem<T> = T & { type ResolvedItem<T> = T & {
icon: string icon: string
@@ -137,23 +135,29 @@ const sortField = ref('name')
const iconMapLegacy = (icon: string) => { const iconMapLegacy = (icon: string) => {
const prefix = 'pi-' const prefix = 'pi-'
const legacy = { const legacy: Record<string, string> = {
audio: 'headphones' audio: 'headphones'
} }
return prefix + (legacy[icon] || icon) return prefix + (legacy[icon] || icon)
} }
const renderedItems = computed(() => { const renderedItems = computed(() => {
const columnRenderText = columns.value.reduce((acc, column) => { const columnRenderText = columns.value.reduce(
acc[column.key] = column.renderText (acc, column) => {
return acc acc[column.key] = column.renderText
}, {}) return acc
},
{} as Record<string, (val: any, row: Item) => string>
)
return props.items.map((item) => { return props.items.map((item) => {
const display = Object.entries(item).reduce((acc, [key, value]) => { const display = Object.entries(item).reduce(
acc[key] = columnRenderText[key]?.(value, item) ?? value (acc, [key, value]) => {
return acc acc[key] = columnRenderText[key]?.(value, item) ?? value
}, {} as RecordString<Item>) return acc
},
{} as Record<string, any>
)
return { ...item, icon: iconMapLegacy(item.type), _display: display } return { ...item, icon: iconMapLegacy(item.type), _display: display }
}) })
}) })
@@ -173,8 +177,8 @@ const sortedItems = computed(() => {
const direction = sortDirection.value === 'asc' ? 1 : -1 const direction = sortDirection.value === 'asc' ? 1 : -1
const sorting = (a: ResolvedItem<Item>, b: ResolvedItem<Item>) => { const sorting = (a: ResolvedItem<Item>, b: ResolvedItem<Item>) => {
const aValue = a[sortField.value] const aValue = (a as any)[sortField.value]
const bValue = b[sortField.value] const bValue = (b as any)[sortField.value]
const result = const result =
typeof aValue === 'string' typeof aValue === 'string'

View File

@@ -19,7 +19,7 @@
<script setup lang="ts" generic="T"> <script setup lang="ts" generic="T">
import { useElementSize, useScroll } from '@vueuse/core' import { useElementSize, useScroll } from '@vueuse/core'
import { clamp } from 'lodash' import { clamp } from 'es-toolkit'
import { type CSSProperties, computed, ref } from 'vue' import { type CSSProperties, computed, ref } from 'vue'
type Item = T & { key: string } type Item = T & { key: string }

View File

@@ -2,25 +2,25 @@
<SidebarTabTemplate :title="$t('sideToolbar.outputExplorer')"> <SidebarTabTemplate :title="$t('sideToolbar.outputExplorer')">
<template #tool-buttons> <template #tool-buttons>
<Button <Button
v-tooltip.bottom="$t('g.back')"
icon="pi pi-arrow-up" icon="pi pi-arrow-up"
@click="handleBackParentFolder"
severity="secondary" severity="secondary"
text text
v-tooltip.bottom="$t('g.back')"
:disabled="!currentFolder" :disabled="!currentFolder"
@click="handleBackParentFolder"
/> />
<Button <Button
v-tooltip.bottom="$t('g.refresh')"
icon="pi pi-refresh" icon="pi pi-refresh"
@click="loadFolderItems"
severity="secondary" severity="secondary"
text text
v-tooltip.bottom="$t('g.refresh')" @click="loadFolderItems"
/> />
</template> </template>
<template #header> <template #header>
<SearchBox <SearchBox
class="model-lib-search-box p-2 2xl:p-4"
v-model:modelValue="searchQuery" v-model:modelValue="searchQuery"
class="model-lib-search-box p-2 2xl:p-4"
:placeholder="$t('g.searchIn', ['output'])" :placeholder="$t('g.searchIn', ['output'])"
@search="handleSearch" @search="handleSearch"
/> />
@@ -141,14 +141,22 @@ const itemsCount = computed(() => {
const renderedItems = computed(() => { const renderedItems = computed(() => {
const query = filterContent.value const query = filterContent.value
let items = currentFolderItems.value
if (!query) { if (query) {
return currentFolderItems.value items = items.filter((item) => {
return item.name.toLowerCase().includes(query.toLowerCase())
})
} }
return currentFolderItems.value.filter((item) => { // Convert OutputItem to Item format expected by ListExplorer
return item.name.toLowerCase().includes(query.toLowerCase()) return items.map((item) => ({
}) key: item.key,
name: item.name,
type: item.type,
size: item.size,
modifyTime: item.modifyTime
}))
}) })
const handleSearch = async (query: string) => { const handleSearch = async (query: string) => {
@@ -214,11 +222,17 @@ const handleBackParentFolder = async () => {
await loadFolderItems() await loadFolderItems()
} }
const handleDbClickItem = (item: OutputItem, event: MouseEvent) => { const handleDbClickItem = (item: any, _event: MouseEvent) => {
if (item.type === 'folder') { // Find the original OutputItem from currentFolderItems
openFolder(item, folderPaths.value.length) const originalItem = currentFolderItems.value.find(
(outputItem) => outputItem.key === item.key
)
if (!originalItem) return
if (originalItem.type === 'folder') {
void openFolder(originalItem, folderPaths.value.length)
} else { } else {
openItemPreview(item) openItemPreview(originalItem)
} }
} }

View File

@@ -703,5 +703,79 @@
"UPSCALE_MODEL": "UPSCALE_MODEL", "UPSCALE_MODEL": "UPSCALE_MODEL",
"VAE": "VAE", "VAE": "VAE",
"WEBCAM": "WEBCAM" "WEBCAM": "WEBCAM"
},
"auth": {
"apiKey": {
"title": "API Key",
"label": "API Key",
"description": "Use your Comfy API key to enable API Nodes",
"placeholder": "Enter your API Key",
"error": "Invalid API Key",
"storageFailed": "Failed to store API Key",
"storageFailedDetail": "Please try again.",
"stored": "API Key stored",
"storedDetail": "Your API Key has been stored successfully",
"cleared": "API Key cleared",
"clearedDetail": "Your API Key has been cleared successfully",
"invalid": "Invalid API Key",
"invalidDetail": "Please enter a valid API Key",
"helpText": "Need an API key?",
"generateKey": "Get one here",
"whitelistInfo": "About non-whitelisted sites"
},
"login": {
"title": "Log in to your account",
"useApiKey": "Comfy API Key",
"signInOrSignUp": "Sign In / Sign Up",
"forgotPasswordError": "Failed to send password reset email",
"passwordResetSent": "Password reset email sent",
"passwordResetSentDetail": "Please check your email for a link to reset your password.",
"newUser": "New here?",
"userAvatar": "User Avatar",
"signUp": "Sign up",
"emailLabel": "Email",
"emailPlaceholder": "Enter your email",
"passwordLabel": "Password",
"passwordPlaceholder": "Enter your password",
"confirmPasswordLabel": "Confirm Password",
"confirmPasswordPlaceholder": "Enter the same password again",
"forgotPassword": "Forgot password?",
"loginButton": "Log in",
"orContinueWith": "Or continue with",
"loginWithGoogle": "Log in with Google",
"loginWithGithub": "Log in with Github",
"termsText": "By clicking \"Next\" or \"Sign Up\", you agree to our",
"termsLink": "Terms of Use",
"andText": "and",
"privacyLink": "Privacy Policy",
"success": "Login successful",
"failed": "Login failed",
"insecureContextWarning": "This connection is insecure (HTTP) - your credentials may be intercepted by attackers if you proceed to login.",
"questionsContactPrefix": "Questions? Contact us at",
"noAssociatedUser": "There is no Comfy user associated with the provided API key"
},
"signup": {
"title": "Create an account",
"alreadyHaveAccount": "Already have an account?",
"emailLabel": "Email",
"emailPlaceholder": "Enter your email",
"passwordLabel": "Password",
"passwordPlaceholder": "Enter new password",
"signUpButton": "Sign up",
"signIn": "Sign in",
"signUpWithGoogle": "Sign up with Google",
"signUpWithGithub": "Sign up with Github",
"regionRestrictionChina": "In accordance with local regulatory requirements, our services are temporarily unavailable to users located in China.",
"personalDataConsentLabel": "I agree to the processing of my personal data."
},
"signOut": {
"signOut": "Log Out",
"success": "Signed out successfully",
"successDetail": "You have been signed out of your account."
},
"passwordUpdate": {
"success": "Password Updated",
"successDetail": "Your password has been updated successfully"
}
} }
} }

View File

@@ -1,9 +1,9 @@
import { defineStore } from 'pinia' import { defineStore } from 'pinia'
import { computed, ref } from 'vue' import { computed, ref } from 'vue'
import { useOutputExplorerSidebarTab } from '@/composables/sidebarTabs/outputExplorerSidebarTab'
import { useModelLibrarySidebarTab } from '@/composables/sidebarTabs/useModelLibrarySidebarTab' import { useModelLibrarySidebarTab } from '@/composables/sidebarTabs/useModelLibrarySidebarTab'
import { useNodeLibrarySidebarTab } from '@/composables/sidebarTabs/useNodeLibrarySidebarTab' import { useNodeLibrarySidebarTab } from '@/composables/sidebarTabs/useNodeLibrarySidebarTab'
import { useOutputExplorerSidebarTab } from '@/composables/sidebarTabs/outputExplorerSidebarTab'
import { useQueueSidebarTab } from '@/composables/sidebarTabs/useQueueSidebarTab' import { useQueueSidebarTab } from '@/composables/sidebarTabs/useQueueSidebarTab'
import { useWorkflowsSidebarTab } from '@/composables/sidebarTabs/useWorkflowsSidebarTab' import { useWorkflowsSidebarTab } from '@/composables/sidebarTabs/useWorkflowsSidebarTab'
import { t, te } from '@/i18n' import { t, te } from '@/i18n'
@@ -93,7 +93,7 @@ export const useSidebarTabStore = defineStore('sidebarTab', () => {
registerSidebarTab(useNodeLibrarySidebarTab()) registerSidebarTab(useNodeLibrarySidebarTab())
registerSidebarTab(useModelLibrarySidebarTab()) registerSidebarTab(useModelLibrarySidebarTab())
registerSidebarTab(useWorkflowsSidebarTab()) registerSidebarTab(useWorkflowsSidebarTab())
<<<<<<< HEAD registerSidebarTab(useOutputExplorerSidebarTab())
const menuStore = useMenuItemStore() const menuStore = useMenuItemStore()
@@ -113,9 +113,6 @@ export const useSidebarTabStore = defineStore('sidebarTab', () => {
['View'], ['View'],
['Comfy.Canvas.ZoomIn', 'Comfy.Canvas.ZoomOut', 'Comfy.Canvas.FitView'] ['Comfy.Canvas.ZoomIn', 'Comfy.Canvas.ZoomOut', 'Comfy.Canvas.FitView']
) )
=======
registerSidebarTab(useOutputExplorerSidebarTab())
>>>>>>> e9f3e42a (Add output explorer)
} }
return { return {