Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
3e3448e
[restore] conflict notification commits restore
viva-jinyi Aug 2, 2025
a1ea18c
[fix] Restore conflict notification work and fix tests
viva-jinyi Aug 2, 2025
aefa3a9
[fix] Use Vue 3.5 destructuring syntax for props with defaults
viva-jinyi Aug 2, 2025
7389790
[feature] dual modal supported
viva-jinyi Aug 2, 2025
134341d
[fix] Fix date format in PackCard test for locale consistency
viva-jinyi Aug 2, 2025
ff31e2d
[fix] title text modified
viva-jinyi Aug 5, 2025
42ad8eb
[fix] Fix conflict red dot not syncing
viva-jinyi Aug 5, 2025
63b6af5
[fix] Add conflict detection when installed packages list updates
viva-jinyi Aug 6, 2025
73f2489
fix: use selected target_branch for PR base in update-manager-types w…
viva-jinyi Aug 6, 2025
87db9cc
[fix] test code timeout error fixed
viva-jinyi Aug 6, 2025
7d0e971
[chore] Update ComfyUI-Manager API types from ComfyUI-Manager@4e6f970…
comfy-pr-bot Aug 6, 2025
4c99172
[types] Add proper types for ImportFailInfo API endpoints (#4783)
viva-jinyi Aug 6, 2025
33bf377
[fix] ci error fixed & button max-width modified
viva-jinyi Aug 7, 2025
59e1945
fix: node pack card width adapted
viva-jinyi Aug 12, 2025
35873fa
fix: prevent duplicate api calls & installedPacksWithVersions instead…
viva-jinyi Aug 12, 2025
a5153cd
feat: run conflict detection after Apply Changes
viva-jinyi Aug 17, 2025
267e07e
refactor: simplify PackInstallButton isInstalling state management
viva-jinyi Aug 27, 2025
91e462d
feat: improve multi-package selection handling (#5116)
viva-jinyi Aug 27, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/update-manager-types.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -99,4 +99,4 @@ jobs:
labels: Manager
delete-branch: true
add-paths: |
src/types/generatedManagerTypes.ts
src/types/generatedManagerTypes.ts
192 changes: 131 additions & 61 deletions package-lock.json

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,14 @@ import ProgressSpinner from 'primevue/progressspinner'
import { computed, onMounted } from 'vue'

import GlobalDialog from '@/components/dialog/GlobalDialog.vue'
import { useConflictDetection } from '@/composables/useConflictDetection'
import config from '@/config'
import { useWorkspaceStore } from '@/stores/workspaceStore'

import { electronAPI, isElectron } from './utils/envUtil'

const workspaceStore = useWorkspaceStore()
const conflictDetection = useConflictDetection()
const isLoading = computed<boolean>(() => workspaceStore.spinner)
const handleKey = (e: KeyboardEvent) => {
workspaceStore.shiftDown = e.shiftKey
Expand All @@ -47,5 +49,9 @@ onMounted(() => {
if (isElectron()) {
document.addEventListener('contextmenu', showContextMenu)
}

// Initialize conflict detection in background
// This runs async and doesn't block UI setup
void conflictDetection.initializeConflictDetection()
})
</script>
2 changes: 1 addition & 1 deletion src/components/dialog/GlobalDialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
/>

<template v-if="item.footerComponent" #footer>
<component :is="item.footerComponent" />
<component :is="item.footerComponent" v-bind="item.footerProps" />
</template>
</Dialog>
</template>
Expand Down
14 changes: 1 addition & 13 deletions src/components/dialog/content/LoadWorkflowWarning.vue
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
size="md"
:disabled="!!error || missingNodePacks.length === 0"
:is-loading="isLoading"
:is-installing="isInstalling"
:node-packs="missingNodePacks"
:label="
isLoading
Expand All @@ -55,15 +54,13 @@ import { computed, onMounted, ref } from 'vue'

import NoResultsPlaceholder from '@/components/common/NoResultsPlaceholder.vue'
import MissingCoreNodesMessage from '@/components/dialog/content/MissingCoreNodesMessage.vue'
import PackInstallButton from '@/components/dialog/content/manager/button/PackInstallButton.vue'
import { useMissingNodes } from '@/composables/nodePack/useMissingNodes'
import { useComfyManagerService } from '@/services/comfyManagerService'
import { useDialogService } from '@/services/dialogService'
import { useComfyManagerStore } from '@/stores/comfyManagerStore'
import type { MissingNodeType } from '@/types/comfy'
import { ManagerTab } from '@/types/comfyManagerTypes'

import PackInstallButton from './manager/button/PackInstallButton.vue'

const props = defineProps<{
missingNodeTypes: MissingNodeType[]
}>()
Expand All @@ -72,17 +69,8 @@ const props = defineProps<{
const { missingNodePacks, isLoading, error, missingCoreNodes } =
useMissingNodes()

const comfyManagerStore = useComfyManagerStore()
const isLegacyManager = ref(false)

// Check if any of the missing packs are currently being installed
const isInstalling = computed(() => {
if (!missingNodePacks.value?.length) return false
return missingNodePacks.value.some((pack) =>
comfyManagerStore.isPackInstalling(pack.id)
)
})

const uniqueNodes = computed(() => {
const seenTypes = new Set()
return props.missingNodeTypes
Expand Down
59 changes: 56 additions & 3 deletions src/components/dialog/content/manager/ManagerDialogContent.vue
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,35 @@
}"
>
<div class="px-6 flex flex-col h-full">
<!-- Conflict Warning Banner -->
<div
v-if="shouldShowManagerBanner"
class="bg-yellow-600 bg-opacity-20 border border-yellow-400 rounded-lg p-4 mt-3 mb-4 flex items-center gap-6 relative"
>
<i class="pi pi-exclamation-triangle text-yellow-600 text-lg"></i>
<div class="flex flex-col gap-2 flex-1">
<p class="text-sm font-bold m-0">
{{ $t('manager.conflicts.warningBanner.title') }}
</p>
<p class="text-xs m-0">
{{ $t('manager.conflicts.warningBanner.message') }}
</p>
<p
class="text-sm font-bold m-0 cursor-pointer"
@click="onClickWarningLink"
>
{{ $t('manager.conflicts.warningBanner.button') }}
</p>
</div>
<button
type="button"
class="absolute top-2 right-2 w-6 h-6 border-none outline-none bg-transparent flex items-center justify-center text-yellow-600 rounded transition-colors"
:aria-label="$t('g.close')"
@click="dismissWarningBanner"
>
<i class="pi pi-times text-sm"></i>
</button>
</div>
<RegistrySearchBar
v-model:searchQuery="searchQuery"
v-model:searchMode="searchMode"
Expand All @@ -34,6 +63,7 @@
:suggestions="suggestions"
:is-missing-tab="isMissingTab"
:sort-options="sortOptions"
:is-update-available-tab="isUpdateAvailableTab"
/>
<div class="flex-1 overflow-auto">
<div
Expand Down Expand Up @@ -69,7 +99,9 @@
:is-selected="
selectedNodePacks.some((pack) => pack.id === item.id)
"
@click.stop="(event) => selectNodePack(item, event)"
@click.stop="
(event: MouseEvent) => selectNodePack(item, event)
"
/>
</template>
</VirtualGrid>
Expand Down Expand Up @@ -101,7 +133,8 @@ import {
onMounted,
onUnmounted,
ref,
watch
watch,
watchEffect
} from 'vue'
import { useI18n } from 'vue-i18n'

Expand All @@ -119,6 +152,7 @@ import { useManagerStatePersistence } from '@/composables/manager/useManagerStat
import { useInstalledPacks } from '@/composables/nodePack/useInstalledPacks'
import { usePackUpdateStatus } from '@/composables/nodePack/usePackUpdateStatus'
import { useWorkflowPacks } from '@/composables/nodePack/useWorkflowPacks'
import { useConflictAcknowledgment } from '@/composables/useConflictAcknowledgment'
import { useRegistrySearch } from '@/composables/useRegistrySearch'
import { useComfyManagerStore } from '@/stores/comfyManagerStore'
import { useComfyRegistryStore } from '@/stores/comfyRegistryStore'
Expand All @@ -133,12 +167,13 @@ const { initialTab } = defineProps<{
const { t } = useI18n()
const comfyManagerStore = useComfyManagerStore()
const { getPackById } = useComfyRegistryStore()
const conflictAcknowledgment = useConflictAcknowledgment()
const persistedState = useManagerStatePersistence()
const initialState = persistedState.loadStoredState()

const GRID_STYLE = {
display: 'grid',
gridTemplateColumns: 'repeat(auto-fill, minmax(19rem, 1fr))',
gridTemplateColumns: 'repeat(auto-fill, minmax(17rem, 1fr))',
padding: '0.5rem',
gap: '1.5rem'
} as const
Expand All @@ -149,6 +184,13 @@ const {
toggle: toggleSideNav
} = useResponsiveCollapse()

// Use conflict acknowledgment state from composable
const {
shouldShowManagerBanner,
dismissWarningBanner,
dismissRedDotNotification
} = conflictAcknowledgment

const tabs = ref<TabItem[]>([
{ id: ManagerTab.All, label: t('g.all'), icon: 'pi-list' },
{ id: ManagerTab.Installed, label: t('g.installed'), icon: 'pi-box' },
Expand Down Expand Up @@ -312,6 +354,13 @@ watch([isAllTab, searchResults], () => {
displayPacks.value = searchResults.value
})

const onClickWarningLink = () => {
window.open(
'https://docs.comfy.org/troubleshooting/custom-node-issues',
'_blank'
)
}

const onResultsChange = () => {
switch (selectedTab.value?.id) {
case ManagerTab.Installed:
Expand Down Expand Up @@ -472,6 +521,10 @@ watch([searchQuery, selectedTab], () => {
}
})

watchEffect(() => {
dismissRedDotNotification()
})

onBeforeUnmount(() => {
persistedState.persistState({
selectedTabId: selectedTab.value?.id,
Expand Down
Loading