diff --git a/custom_routes.py b/custom_routes.py index 849fc92..5fc6d80 100644 --- a/custom_routes.py +++ b/custom_routes.py @@ -3035,3 +3035,28 @@ async def get_workflows_proxy(request): return web.json_response(json_data, status=response.status) except Exception as e: return web.json_response({"error": str(e)}, status=500) + + +# for getting a workflow by id +@server.PromptServer.instance.routes.get("/comfyui-deploy/workflow") +async def get_workflow_proxy(request): + workflow_id = request.rel_url.query.get("workflow_id") + api_url = request.rel_url.query.get("api_url", "https://api.comfydeploy.com") + auth_header = request.headers.get("Authorization") + + if not auth_header: + return web.json_response( + {"error": "Authorization header is required"}, status=401 + ) + + target_url = f"{api_url}/api/workflow/{workflow_id}" + + try: + await ensure_client_session() + async with client_session.get( + target_url, headers={"Authorization": auth_header} + ) as response: + json_data = await response.json() + return web.json_response(json_data, status=response.status) + except Exception as e: + return web.json_response({"error": str(e)}, status=500) diff --git a/web-plugin/workflow-list.js b/web-plugin/workflow-list.js index 46ce5a2..cd1cf83 100644 --- a/web-plugin/workflow-list.js +++ b/web-plugin/workflow-list.js @@ -44,7 +44,7 @@ async function fetchWorkflows(getData, offset = 0, limit = 20, search = "") { } } -function createWorkflowItem(workflow, getTimeAgo) { +function createWorkflowItem(workflow, getTimeAgo, getData) { const li = document.createElement("li"); li.style.cssText = ` border-bottom: 1px solid #444; @@ -61,6 +61,73 @@ function createWorkflowItem(workflow, getTimeAgo) { li.style.background = "transparent"; }); + // Add click handler to fetch and load workflow data + li.addEventListener("click", async () => { + try { + const data = getData(); + if (!data.apiKey) { + console.error("No API key configured"); + return; + } + + // Show loading toast + const loadingToast = window.app.extensionManager.toast.add({ + severity: "info", + summary: "Loading workflow...", + detail: `Loading "${workflow.name}"`, + life: 3000, + }); + + const params = new URLSearchParams({ + workflow_id: workflow.id, + api_url: data.apiUrl || "https://api.comfydeploy.com", + }); + + const response = await fetch(`/comfyui-deploy/workflow?${params}`, { + method: "GET", + headers: { + Authorization: `Bearer ${data.apiKey}`, + "Content-Type": "application/json", + }, + }); + + if (!response.ok) { + throw new Error(`Failed to fetch workflow: ${response.status}`); + } + + const workflowData = await response.json(); + console.log("Workflow data:", workflowData); + + // Load the workflow into the graph + if (workflowData.versions && workflowData.versions.length > 0) { + const latestVersion = workflowData.versions[0]; + if (latestVersion.workflow && window.app) { + // Load the workflow + window.app.loadGraphData(latestVersion.workflow); + + // Show success toast + window.app.extensionManager.toast.add({ + severity: "success", + summary: "Workflow loaded successfully", + detail: `Loaded "${workflow.name}" v${latestVersion.version}`, + life: 3000, + }); + } + } + } catch (error) { + console.error("Error loading workflow:", error); + // Show error toast + window.app.extensionManager.toast.add({ + severity: "error", + summary: "Failed to load workflow", + detail: error.message, + life: 5000, + }); + } finally { + loadingToast.close(); + } + }); + const updatedDate = new Date(workflow.updated_at); const timeAgo = getTimeAgo(updatedDate); @@ -69,39 +136,40 @@ function createWorkflowItem(workflow, getTimeAgo) {
${ workflow.cover_image - ? ` -
- Workflow cover -
- 📄 -
-
- ` - : ` -
- 📄 -
- ` + ? `` + : `
+ ${workflow.name.charAt(0).toUpperCase()} +
` }
-
+

${workflow.name} -

+ ${ workflow.pinned - ? '📌' + ? `📌` : "" }
-
+ ${ + workflow.description + ? `

+ ${workflow.description} +

` + : "" + } + +
+ - Updated ${timeAgo} + ${workflow.user_name} • Updated ${timeAgo}
@@ -139,7 +207,7 @@ async function loadMoreWorkflows(element, getData, getTimeAgo) { // Render new workflow items newWorkflows.forEach((workflow) => { - const workflowItem = createWorkflowItem(workflow, getTimeAgo); + const workflowItem = createWorkflowItem(workflow, getTimeAgo, getData); workflowsList.appendChild(workflowItem); }); } @@ -174,10 +242,16 @@ async function initializeWorkflowsList(element, getData, getTimeAgo) { const workflowsList = element.querySelector("#workflows-list"); const workflowsLoading = element.querySelector("#workflows-loading"); - if (workflowsState.initialized) return; + // Check if already initialized AND the DOM elements still exist + if ( + workflowsState.initialized && + workflowsList && + workflowsList.children.length > 0 + ) + return; try { - // Reset state + // Reset state (always reset when reinitializing) workflowsState = { workflows: [], offset: 0, @@ -188,6 +262,11 @@ async function initializeWorkflowsList(element, getData, getTimeAgo) { currentSearch: "", }; + // Clear existing content in case of reinitialization + if (workflowsList) { + workflowsList.innerHTML = ""; + } + // Show container and loading workflowsContainer.style.display = "block"; workflowsLoading.style.display = "flex";