{{ $t('manager.infoPanelEmpty') }}
@@ -71,15 +74,15 @@ import { computed, onUnmounted, provide, ref, toRef } from 'vue'
import { useI18n } from 'vue-i18n'
import DotSpinner from '@/components/common/DotSpinner.vue'
+import PropertiesAccordionItem from '@/components/rightSidePanel/layout/PropertiesAccordionItem.vue'
import Button from '@/components/ui/button/Button.vue'
+import ModelInfoField from '@/platform/assets/components/modelInfo/ModelInfoField.vue'
import { useComfyRegistryStore } from '@/stores/comfyRegistryStore'
import type { components } from '@/types/comfyRegistryTypes'
+import { cn } from '@/utils/tailwindUtil'
import PackStatusMessage from '@/workbench/extensions/manager/components/manager/PackStatusMessage.vue'
import PackInstallButton from '@/workbench/extensions/manager/components/manager/button/PackInstallButton.vue'
import PackUninstallButton from '@/workbench/extensions/manager/components/manager/button/PackUninstallButton.vue'
-import InfoPanelHeader from '@/workbench/extensions/manager/components/manager/infoPanel/InfoPanelHeader.vue'
-import MetadataRow from '@/workbench/extensions/manager/components/manager/infoPanel/MetadataRow.vue'
-import PackIconStacked from '@/workbench/extensions/manager/components/manager/packIcon/PackIconStacked.vue'
import { usePacksSelection } from '@/workbench/extensions/manager/composables/nodePack/usePacksSelection'
import { usePacksStatus } from '@/workbench/extensions/manager/composables/nodePack/usePacksStatus'
import { useConflictDetection } from '@/workbench/extensions/manager/composables/useConflictDetection'
@@ -92,6 +95,11 @@ const { nodePacks } = defineProps<{
}>()
const { t } = useI18n()
+
+const accordionClass = cn(
+ 'bg-modal-panel-background border-t border-border-default'
+)
+
const managerStore = useComfyManagerStore()
const nodePacksRef = toRef(() => nodePacks)
diff --git a/src/workbench/extensions/manager/components/manager/infoPanel/InfoTabs.vue b/src/workbench/extensions/manager/components/manager/infoPanel/InfoTabs.vue
deleted file mode 100644
index 29ae4f986..000000000
--- a/src/workbench/extensions/manager/components/manager/infoPanel/InfoTabs.vue
+++ /dev/null
@@ -1,89 +0,0 @@
-
-
-
-
-
-
- ⚠️
- {{ importFailed ? $t('g.error') : $t('g.warning') }}
-
-
-
- {{ $t('g.description') }}
-
-
- {{ $t('g.nodes') }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/workbench/extensions/manager/components/manager/infoPanel/InfoTextSection.vue b/src/workbench/extensions/manager/components/manager/infoPanel/InfoTextSection.vue
deleted file mode 100644
index 3307a140e..000000000
--- a/src/workbench/extensions/manager/components/manager/infoPanel/InfoTextSection.vue
+++ /dev/null
@@ -1,38 +0,0 @@
-
-
-
-
- {{ section.title }}
-
-
-
-
-
-
-
diff --git a/src/workbench/extensions/manager/components/manager/infoPanel/MetadataRow.vue b/src/workbench/extensions/manager/components/manager/infoPanel/MetadataRow.vue
deleted file mode 100644
index 56436b9f0..000000000
--- a/src/workbench/extensions/manager/components/manager/infoPanel/MetadataRow.vue
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
-
{{ label }}
-
- {{ value }}
-
-
-
-
-
diff --git a/src/workbench/extensions/manager/components/manager/infoPanel/tabs/DescriptionTabPanel.test.ts b/src/workbench/extensions/manager/components/manager/infoPanel/tabs/DescriptionTabPanel.test.ts
index 93e6d0ee8..07b2a36ae 100644
--- a/src/workbench/extensions/manager/components/manager/infoPanel/tabs/DescriptionTabPanel.test.ts
+++ b/src/workbench/extensions/manager/components/manager/infoPanel/tabs/DescriptionTabPanel.test.ts
@@ -15,13 +15,6 @@ const i18n = createI18n({
}
})
-const TRANSLATIONS = {
- description: 'Description',
- repository: 'Repository',
- license: 'License',
- noDescription: 'No description available'
-}
-
describe('DescriptionTabPanel', () => {
const mountComponent = (props: {
nodePack: Partial
@@ -34,16 +27,6 @@ describe('DescriptionTabPanel', () => {
})
}
- const getSectionByTitle = (
- wrapper: ReturnType,
- title: string
- ) => {
- const sections = wrapper
- .findComponent({ name: 'InfoTextSection' })
- .props('sections')
- return sections.find((s: any) => s.title === title)
- }
-
const createNodePack = (
overrides: Partial = {}
) => ({
@@ -134,37 +117,36 @@ describe('DescriptionTabPanel', () => {
licenseTests.forEach((test) => {
it(test.name, () => {
const wrapper = mountComponent({ nodePack: test.nodePack })
- const licenseSection = getSectionByTitle(wrapper, TRANSLATIONS.license)
- expect(licenseSection).toBeDefined()
- expect(licenseSection.text).toBe(test.expected.text)
- expect(licenseSection.isUrl).toBe(test.expected.isUrl)
+ if (test.expected.isUrl) {
+ const link = wrapper
+ .findAll('a')
+ .find((a) => a.text().includes(test.expected.text))
+ expect(link).toBeDefined()
+ expect(link!.attributes('href')).toBe(test.expected.text)
+ } else {
+ expect(wrapper.text()).toContain(test.expected.text)
+ }
})
})
})
describe('description sections', () => {
- it('shows description section', () => {
+ it('shows description text', () => {
const wrapper = mountComponent({
nodePack: createNodePack()
})
- const descriptionSection = getSectionByTitle(
- wrapper,
- TRANSLATIONS.description
- )
- expect(descriptionSection).toBeDefined()
- expect(descriptionSection.text).toBe('Test description')
+ expect(wrapper.text()).toContain('Test description')
})
- it('shows repository section when available', () => {
+ it('shows repository link when available', () => {
const wrapper = mountComponent({
nodePack: createNodePack({
repository: 'https://github.com/user/repo'
})
})
- const repoSection = getSectionByTitle(wrapper, TRANSLATIONS.repository)
- expect(repoSection).toBeDefined()
- expect(repoSection.text).toBe('https://github.com/user/repo')
- expect(repoSection.isUrl).toBe(true)
+ const repoLink = wrapper.find('a[href="https://github.com/user/repo"]')
+ expect(repoLink.exists()).toBe(true)
+ expect(repoLink.attributes('target')).toBe('_blank')
})
it('shows fallback text when description is missing', () => {
@@ -173,7 +155,7 @@ describe('DescriptionTabPanel', () => {
description: undefined
}
})
- expect(wrapper.find('p').text()).toBe(TRANSLATIONS.noDescription)
+ expect(wrapper.text()).toContain('No description available')
})
})
})
diff --git a/src/workbench/extensions/manager/components/manager/infoPanel/tabs/DescriptionTabPanel.vue b/src/workbench/extensions/manager/components/manager/infoPanel/tabs/DescriptionTabPanel.vue
index e6b203cd8..bfd0e7486 100644
--- a/src/workbench/extensions/manager/components/manager/infoPanel/tabs/DescriptionTabPanel.vue
+++ b/src/workbench/extensions/manager/components/manager/infoPanel/tabs/DescriptionTabPanel.vue
@@ -1,24 +1,57 @@
-
-
-
- {{ $t('manager.noDescription') }}
-
-
-
- {{ $t('manager.dependencies') }}
-
+
+
@@ -26,10 +59,10 @@
import { computed } from 'vue'
import { useI18n } from 'vue-i18n'
+import ModelInfoField from '@/platform/assets/components/modelInfo/ModelInfoField.vue'
import type { components } from '@/types/comfyRegistryTypes'
import { isValidUrl } from '@/utils/formatUtil'
-import InfoTextSection from '@/workbench/extensions/manager/components/manager/infoPanel/InfoTextSection.vue'
-import type { TextSection } from '@/workbench/extensions/manager/components/manager/infoPanel/InfoTextSection.vue'
+import MarkdownText from '@/workbench/extensions/manager/components/manager/infoPanel/MarkdownText.vue'
const { t } = useI18n()
@@ -37,6 +70,8 @@ const { nodePack } = defineProps<{
nodePack: components['schemas']['Node']
}>()
+const isGitHubLink = (url: string): boolean => url.includes('github.com')
+
const isLicenseFile = (filename: string): boolean => {
// Match LICENSE, LICENSE.md, LICENSE.txt (case insensitive)
const licensePattern = /^license(\.md|\.txt)?$/i
@@ -118,33 +153,8 @@ const formatLicense = (
}
}
-const descriptionSections = computed
(() => {
- const sections: TextSection[] = [
- {
- title: t('g.description'),
- text: nodePack.description || t('manager.noDescription')
- }
- ]
-
- if (nodePack.repository) {
- sections.push({
- title: t('manager.repository'),
- text: nodePack.repository,
- isUrl: isValidUrl(nodePack.repository)
- })
- }
-
- if (nodePack.license) {
- const licenseInfo = formatLicense(nodePack.license)
- if (licenseInfo && licenseInfo.text) {
- sections.push({
- title: t('manager.license'),
- text: licenseInfo.text,
- isUrl: licenseInfo.isUrl
- })
- }
- }
-
- return sections
+const licenseInfo = computed(() => {
+ if (!nodePack.license) return null
+ return formatLicense(nodePack.license)
})
diff --git a/src/workbench/extensions/manager/components/manager/infoPanel/tabs/NodesTabPanel.vue b/src/workbench/extensions/manager/components/manager/infoPanel/tabs/NodesTabPanel.vue
index 3f0c5db20..8dd5e8a2f 100644
--- a/src/workbench/extensions/manager/components/manager/infoPanel/tabs/NodesTabPanel.vue
+++ b/src/workbench/extensions/manager/components/manager/infoPanel/tabs/NodesTabPanel.vue
@@ -1,18 +1,8 @@
-
+
-
-
-
-
+
+
diff --git a/src/workbench/extensions/manager/components/manager/infoPanel/tabs/WarningTabPanel.vue b/src/workbench/extensions/manager/components/manager/infoPanel/tabs/WarningTabPanel.vue
index 472a60e1d..9643155bb 100644
--- a/src/workbench/extensions/manager/components/manager/infoPanel/tabs/WarningTabPanel.vue
+++ b/src/workbench/extensions/manager/components/manager/infoPanel/tabs/WarningTabPanel.vue
@@ -3,15 +3,12 @@