mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-04-20 14:30:41 +00:00
## Summary - Adds `settingId` parameter to `showSettingsDialog` that auto-navigates to the correct category tab, scrolls to the setting, and briefly highlights it with a CSS pulse animation - Adds `data-setting-id` attributes to setting items for stable DOM targeting - Adds "Don't show this again" checkbox with "Re-enable in Settings" deep-link to the missing nodes dialog - Adds "Re-enable in Settings" deep-link to missing models and blueprint overwrite "Don't show this again" checkboxes - Fixes #3437 ## Test plan - [x] `pnpm typecheck` passes - [x] `pnpm lint` passes - [x] Unit tests pass (59/59 including 5 new tests for `useSettingUI`) https://github.com/user-attachments/assets/a9e80aea-7b69-4686-b030-55a2e0570ff0 ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-8761-feat-scroll-to-specific-setting-when-opening-settings-dialog-3036d73d365081d18d9afe9f9ed41ebc) by [Unito](https://www.unito.io)
163 lines
4.4 KiB
Vue
163 lines
4.4 KiB
Vue
<template>
|
|
<section class="prompt-dialog-content m-2 mt-4 flex flex-col gap-6">
|
|
<span>{{ message }}</span>
|
|
<ul v-if="itemList?.length" class="m-0 flex flex-col gap-2 pl-4">
|
|
<li v-for="item of itemList" :key="item">
|
|
{{ item }}
|
|
</li>
|
|
</ul>
|
|
<Message
|
|
v-if="hint"
|
|
icon="pi pi-info-circle"
|
|
severity="secondary"
|
|
size="small"
|
|
variant="simple"
|
|
>
|
|
{{ hint }}
|
|
</Message>
|
|
<div class="flex justify-end gap-4">
|
|
<div
|
|
v-if="type === 'overwriteBlueprint'"
|
|
class="flex flex-col justify-start gap-1"
|
|
>
|
|
<div class="flex gap-4">
|
|
<input
|
|
id="doNotAskAgain"
|
|
v-model="doNotAskAgain"
|
|
type="checkbox"
|
|
class="h-4 w-4 cursor-pointer"
|
|
/>
|
|
<label for="doNotAskAgain">{{
|
|
t('missingModelsDialog.doNotAskAgain')
|
|
}}</label>
|
|
</div>
|
|
<i18n-t
|
|
v-if="doNotAskAgain"
|
|
keypath="missingModelsDialog.reEnableInSettings"
|
|
tag="span"
|
|
class="text-sm text-muted-foreground ml-8"
|
|
>
|
|
<template #link>
|
|
<Button
|
|
variant="textonly"
|
|
class="underline cursor-pointer p-0 text-sm text-muted-foreground hover:bg-transparent"
|
|
@click="openBlueprintOverwriteSetting"
|
|
>
|
|
{{ t('missingModelsDialog.reEnableInSettingsLink') }}
|
|
</Button>
|
|
</template>
|
|
</i18n-t>
|
|
</div>
|
|
|
|
<Button
|
|
v-if="type !== 'info'"
|
|
variant="secondary"
|
|
autofocus
|
|
@click="onCancel"
|
|
>
|
|
<i class="pi pi-undo" />
|
|
{{ $t('g.cancel') }}
|
|
</Button>
|
|
<Button v-if="type === 'default'" variant="primary" @click="onConfirm">
|
|
<i class="pi pi-check" />
|
|
{{ $t('g.confirm') }}
|
|
</Button>
|
|
<Button
|
|
v-else-if="type === 'delete'"
|
|
variant="destructive"
|
|
@click="onConfirm"
|
|
>
|
|
<i class="pi pi-trash" />
|
|
{{ $t('g.delete') }}
|
|
</Button>
|
|
<Button
|
|
v-else-if="type === 'overwrite' || type === 'overwriteBlueprint'"
|
|
variant="destructive"
|
|
@click="onConfirm"
|
|
>
|
|
<i class="pi pi-save" />
|
|
{{ $t('g.overwrite') }}
|
|
</Button>
|
|
<template v-else-if="type === 'dirtyClose'">
|
|
<Button variant="secondary" @click="onDeny">
|
|
<i class="pi pi-times" />
|
|
{{ $t('g.no') }}
|
|
</Button>
|
|
<Button @click="onConfirm">
|
|
<i class="pi pi-save" />
|
|
{{ $t('g.save') }}
|
|
</Button>
|
|
</template>
|
|
<Button
|
|
v-else-if="type === 'reinstall'"
|
|
variant="destructive"
|
|
@click="onConfirm"
|
|
>
|
|
<i class="pi pi-eraser" />
|
|
{{ $t('desktopMenu.reinstall') }}
|
|
</Button>
|
|
<!-- Info - just show an OK button -->
|
|
<Button v-else-if="type === 'info'" variant="primary" @click="onCancel">
|
|
{{ $t('g.ok') }}
|
|
</Button>
|
|
<!-- Invalid - just show a close button. -->
|
|
<Button v-else variant="primary" @click="onCancel">
|
|
<i class="pi pi-times" />
|
|
{{ $t('g.close') }}
|
|
</Button>
|
|
</div>
|
|
</section>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import Message from 'primevue/message'
|
|
import { ref } from 'vue'
|
|
import { useI18n } from 'vue-i18n'
|
|
|
|
import Button from '@/components/ui/button/Button.vue'
|
|
import { useSettingStore } from '@/platform/settings/settingStore'
|
|
import { useDialogService } from '@/services/dialogService'
|
|
import type { ConfirmationDialogType } from '@/services/dialogService'
|
|
import { useDialogStore } from '@/stores/dialogStore'
|
|
|
|
const props = defineProps<{
|
|
message: string
|
|
type: ConfirmationDialogType
|
|
onConfirm: (value?: boolean) => void
|
|
itemList?: string[]
|
|
hint?: string
|
|
}>()
|
|
|
|
const { t } = useI18n()
|
|
|
|
const onCancel = () => useDialogStore().closeDialog()
|
|
|
|
function openBlueprintOverwriteSetting() {
|
|
useDialogStore().closeDialog()
|
|
void useDialogService().showSettingsDialog(
|
|
undefined,
|
|
'Comfy.Workflow.WarnBlueprintOverwrite'
|
|
)
|
|
}
|
|
|
|
const doNotAskAgain = ref(false)
|
|
|
|
const onDeny = () => {
|
|
props.onConfirm(false)
|
|
useDialogStore().closeDialog()
|
|
}
|
|
|
|
const onConfirm = () => {
|
|
if (props.type === 'overwriteBlueprint' && doNotAskAgain.value)
|
|
void useSettingStore().set('Comfy.Workflow.WarnBlueprintOverwrite', false)
|
|
props.onConfirm(true)
|
|
useDialogStore().closeDialog()
|
|
}
|
|
</script>
|
|
|
|
<style lang="css" scoped>
|
|
.prompt-dialog-content {
|
|
white-space: pre-wrap;
|
|
}
|
|
</style>
|