Files
Will Miao 53f7ff407a fix(workflows): restore uses the app confirmation modal and a loading overlay
- Replace the browser confirm() with a generic #confirmationModal
  (template + ModalManager registration + showConfirmationModal() helper
  in modalUtils.js, promise-based, danger-styled confirm button).
- Show the loadingManager overlay while the restore request is in flight;
  .json restores re-download from CivitAI and the wait previously looked
  like a dead click. The overlay hides in a finally block.
2026-10-29 12:23:22 +08:00

96 lines
4.2 KiB
JavaScript

import { MODEL_TYPES } from '../api/apiConfig.js';
import { getModelApiClient } from '../api/modelApiFactory.js';
import { state } from '../state/index.js';
import { copyToClipboard, showToast } from './uiHelpers.js';
import { translate } from './i18nHelpers.js';
import { showConfirmationModal } from './modalUtils.js';
/**
* Push a library workflow into the running ComfyUI graph (plugin mode only;
* the backend rejects standalone mode since there is no graph to push into).
* @param {string} filePath
*/
export async function sendWorkflowToComfy(filePath) {
try {
await getModelApiClient(MODEL_TYPES.WORKFLOW).sendToComfy(filePath);
showToast('workflows.sendToComfy.success', {}, 'success');
} catch (error) {
console.error('Failed to send workflow to ComfyUI:', error);
showToast('workflows.sendToComfy.failed', { message: error.message }, 'error');
}
}
/**
* Copy the extracted workflow document to the clipboard so the user can
* paste it into ComfyUI (Ctrl+V) to load it. Works in standalone mode too.
* @param {string} filePath
*/
export async function copyWorkflowToClipboard(filePath) {
try {
const workflow = await getModelApiClient(MODEL_TYPES.WORKFLOW).fetchWorkflowContent(filePath);
await copyToClipboard(JSON.stringify(workflow));
} catch (error) {
console.error('Failed to copy workflow:', error);
showToast('workflows.copyWorkflow.failed', { message: error.message }, 'error');
}
}
/**
* Ask the ComfyUI tab that has this workflow open (and edited) to write its
* current graph back into the managed library document.
* @param {string} filePath
*/
export async function updateWorkflowFromComfy(filePath) {
try {
const result = await getModelApiClient(MODEL_TYPES.WORKFLOW).updateFromComfy(filePath);
showToast('workflows.updateFromComfy.success', {}, 'success');
// Re-render the card in place: the scroller shows its shared
// "Updated" cue and the item picks up the new document hash.
const updateData = result && result.sha256 ? { sha256: result.sha256 } : {};
state.virtualScroller?.updateSingleItem(filePath, updateData);
} catch (error) {
const kind = error.kind || 'unknown';
if (kind === 'no_changes' || kind === 'cancelled') {
const key = kind === 'no_changes' ? 'noChanges' : 'cancelled';
showToast(`workflows.updateFromComfy.${key}`, {}, 'info');
} else {
console.error('Failed to update workflow from ComfyUI:', error);
showToast('workflows.updateFromComfy.failed', { message: error.message }, 'error');
}
}
}
/**
* Restore a workflow to its downloaded state, discarding local edits. Bare
* .json artifacts are re-downloaded from the recorded CivitAI version;
* container artifacts (.zip/images) are re-extracted from the pristine file.
* @param {string} filePath
*/
export async function restoreWorkflow(filePath) {
const confirmed = await showConfirmationModal({
title: translate('workflows.restoreDownloaded.title', {}),
message: translate('workflows.restoreDownloaded.message', {}),
confirmText: translate('workflows.restoreDownloaded.confirmButton', {}),
danger: true,
});
if (!confirmed) {
return;
}
// .json restores re-download from CivitAI, which can take a moment; keep
// a blocking indicator up so the wait does not look like a dead click.
state.loadingManager?.showSimpleLoading(translate('workflows.restoreDownloaded.restoring', {}));
try {
const result = await getModelApiClient(MODEL_TYPES.WORKFLOW).restore(filePath);
showToast('workflows.restoreDownloaded.success', {}, 'success');
// Re-render the card in place: the scroller shows its shared
// "Updated" cue and the item picks up the restored document hash.
const updateData = result && result.sha256 ? { sha256: result.sha256 } : {};
state.virtualScroller?.updateSingleItem(filePath, updateData);
} catch (error) {
console.error('Failed to restore workflow:', error);
showToast('workflows.restoreDownloaded.failed', { message: error.message }, 'error');
} finally {
state.loadingManager?.hide();
}
}