Workflow: Workflow dashboard with mermaid.js
Integrations: aggregate, code, manualTrigger, n8n, respondToWebhook, set, stickyNote, switch, webhook

{"id": "Um37boya1U0mnCjS", "meta": {"instanceId": "workflow-f189f774", "versionId": "1.0.0", "createdAt": "2025-09-29T07:07:43.579767", "updatedAt": "2025-09-29T07:07:43.579782", "owner": "n8n-user", "license": "MIT", "category": "automation", "status": "active", "priority": "high", "environment": "production"}, "name": "Workflow dashboard with mermaid.js", "tags": ["automation", "n8n", "production-ready", "excellent", "optimized"], "nodes": [{"id": "c1f74b3a-2ae6-4491-ac02-e1e0fd188664", "name": "When clicking \u2018Test workflow\u2019", "type": "n8n-nodes-base.manualTrigger", "position": [1220, 560], "parameters": {}, "typeVersion": 1, "notes": "This manualTrigger node performs automated tasks as part of the workflow."}, {"id": "2aef0899-91bb-4141-9ec1-def1c31806ae", "name": "Respond with Mermaid", "type": "n8n-nodes-base.respondToWebhook", "position": [2640, 560], "parameters": {"options": {"responseHeaders": {"entries": [{"name": "Content-Type", "value": "text/plain"}]}}, "respondWith": "text", "responseBody": "={{ $json.mermaidChart }}"}, "typeVersion": 1.1, "notes": "This respondToWebhook node performs automated tasks as part of the workflow."}, {"id": "2c60a2e2-9f35-45dc-94d1-daf75314e934", "name": "List workflows", "type": "n8n-nodes-base.n8n", "position": [1620, 360], "parameters": {"filters": {}, "requestOptions": {}}, "credentials": {"n8nApi": {"id": "eW7IdTFt4ARJbEwR", "name": "Ted n8n account"}}, "typeVersion": 1, "notes": "This n8n node performs automated tasks as part of the workflow."}, {"id": "ce4e49b9-e1ab-44d1-9490-5c685c9023d9", "name": "Aggregate", "type": "n8n-nodes-base.aggregate", "position": [1980, 360], "parameters": {"options": {}, "fieldsToAggregate": {"fieldToAggregate": [{"fieldToAggregate": "wf_data"}]}}, "typeVersion": 1, "notes": "This aggregate node performs automated tasks as part of the workflow."}, {"id": "bc48416a-01ff-45f4-9bf2-9f4a39054b54", "name": "Single workflow", "type": "n8n-nodes-base.n8n", "position": [1620, 560], "parameters": {"operation": "get", "workflowId": {"__rl": true, "mode": "id", "value": "={{ $json.query.wfid }}"}, "requestOptions": {}}, "credentials": {"n8nApi": {"id": "eW7IdTFt4ARJbEwR", "name": "Ted n8n account"}}, "typeVersion": 1, "notes": "This n8n node performs automated tasks as part of the workflow."}, {"id": "85f28981-544b-4510-b1ee-d4d538455074", "name": "Switch", "type": "n8n-nodes-base.switch", "position": [1420, 460], "parameters": {"rules": {"values": [{"outputKey": "YOUR_CREDENTIAL_HERE", "conditions": {"options": {"leftValue": "", "caseSensitive": true, "typeValidation": "loose"}, "combinator": "and", "conditions": [{"operator": {"type": "array", "operation": "empty", "singleValue": true}, "leftValue": "={{ Object.keys($json?.query)}}", "rightValue": "wfid"}]}, "renameOutput": true}, {"outputKey": "YOUR_CREDENTIAL_HERE", "conditions": {"options": {"leftValue": "", "caseSensitive": true, "typeValidation": "loose"}, "combinator": "and", "conditions": [{"id": "a4c4c624-2ff5-4fc0-9bdb-802412a5d92f", "operator": {"type": "string", "operation": "contains"}, "leftValue": "={{ Object.keys($json.query).join(',') }}", "rightValue": "wfid"}]}, "renameOutput": true}]}, "options": {"looseTypeValidation": true}}, "typeVersion": 3, "notes": "This switch node performs automated tasks as part of the workflow."}, {"id": "95e0b67b-5e5b-4433-9822-da86900c12ca", "name": "Send Page", "type": "n8n-nodes-base.respondToWebhook", "position": [2640, 360], "parameters": {"options": {}, "respondWith": "text", "responseBody": "=<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <title>n8n Workflow Visualizer</title>\n    <link href=\"{{ $env.WEBHOOK_URL }}\" rel=\"stylesheet\">\n    <script src=\"{{ $env.WEBHOOK_URL }}\"></script>\n    <style>\n      .card-img-container {\n        height: 250px;\n        overflow: hidden;\n      }\n      .card-img-container img {\n        width: 100%;\n        height: 100%;\n        object-fit: cover;\n        object-position: top;\n      }\n    </style>\n</head>\n<body>\n      <div class=\"container mt-4\">\n          <h2>n8n automation flowcharts with mermaid.js</h2>\n          <div id=\"workflows-container\"></div>\n      </div>\n      \n<hr class=\"featurette-divider border-dark\" />\n\n<section id=\"about\" class=\"container mt-3\">\n  <h2 class=\"text-center mb-5\">About</h2>\n  <div class=\"row\">\n\n    <div class=\"col-lg-3 text-center\">\n      <img src=\"{{ $env.WEBHOOK_URL }}\" alt=\"Eduard\" class=\"rounded-circle mb-3\" width=\"140\" height=\"140\" />\n      <h3 class=\"fw-normal\">Eduard</h3>\n      <p><a class=\"btn btn-warning\" href=\"{{ $env.WEBHOOK_URL }}\" target=\"_blank\">More templates</a></p>\n      <p><a class=\"btn btn-outline-primary\" href=\"{{ $env.WEBHOOK_URL }}\" target=\"_blank\">LinkedIn</a></p>\n    </div>\n\n<div class=\"col-lg-9 text-center\">\n  <div class=\"card shadow-sm mb-3\">\n    <div class=\"card-img-container\">\n      <img src=\"{{ $env.API_BASE_URL }}\" class=\"card-img-top\" alt=\"How to work with XML and SQL using n8n\" />\n    </div>\n    <div class=\"card-body\">\n      <h5 class=\"card-title\">\ud83e\udd85 Workflow Dashboard for n8n</h5>\n      <p class=\"card-text\">Get an overview of your n8n instance. This dashboard displays all workflows, nodes, and tags on a single page.</p>\n      <a href=\"{{ $env.WEBHOOK_URL }}\" class=\"btn btn-primary\" target=\"_blank\">Grab the template!</a>\n    </div>\n  </div>\n</div>\n\n  </div>\n</section>\n\n    <script>\n        // JSON object containing workflow data with base webhook URL\n        const workflowsData = {\n            baseWorkflowUrl: \"{{ `${$json.instance_url}/workflow/`.replace(/([^:]\\/)\\/+/g, '$1') }}\", \n            baseWebhookUrl : \"{{ `${$json.instance_url}/${$json.webhook_path}/${$json.webhook_name}?wfid=`.replace(/([^:]\\/)\\/+/g, '$1') }}\", \n            workflows      : {{ JSON.stringify($json.wf_data) }}\n        };\n\n        document.addEventListener('DOMContentLoaded', () => {\n            const workflowsContainer = document.getElementById('workflows-container');\n\n            // Render initial page layout\n            renderWorkflows(workflowsData.workflows);\n\n            function renderWorkflows(workflows) {\n                workflows.forEach(workflow => {\n                    const card = createWorkflowCard(workflow);\n                    workflowsContainer.appendChild(card);\n                });\n            }\n\n\t\t\tfunction createWorkflowCard(workflow) {\n\t\t\t\tconst card = document.createElement('div');\n\t\t\t\tcard.className = 'card mb-3';\n\t\t\t\tcard.innerHTML = `\n                <div class=\"card-body\">\n                    <h5 class=\"card-title d-flex align-items-center\">\n                        ${workflow.name}\n                        <span class=\"badge bg-light-subtle border border-light-subtle text-light-emphasis rounded-pill ms-2\">\n                            <a href=\"${workflowsData.baseWorkflowUrl}${workflow.id}\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"text-primary-emphasis text-decoration-none\" title=\"Open workflow in a new window\"> \ud83d\udd17 </a>\n                        </span>\n                    </h5>\n                    <button class=\"btn btn-primary show-workflow-btn\" data-workflow-id=\"${workflow.id}\">Show Workflow</button>\n                    <div class=\"mermaid-container mt-3\" style=\"display: none;\"></div>\n                </div>\n\t\t\t\t`;\n\n\t\t\t\tconst showWorkflowBtn = card.querySelector('.show-workflow-btn');\n\t\t\t\tconst mermaidContainer = card.querySelector('.mermaid-container');\n\t\t\t\tlet isLoaded = false;\n\n\t\t\t\tshowWorkflowBtn.addEventListener('click', () => {\n\t\t\t\t\tif (!isLoaded) {\n\t\t\t\t\t\tfetchWorkflowDiagram(workflow.id, mermaidContainer);\n\t\t\t\t\t\tisLoaded = true;\n\t\t\t\t\t\tshowWorkflowBtn.textContent = 'Hide Workflow';\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif (mermaidContainer.style.display === 'none') {\n\t\t\t\t\t\t\tmermaidContainer.style.display = 'block';\n\t\t\t\t\t\t\tshowWorkflowBtn.textContent = 'Hide Workflow';\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tmermaidContainer.style.display = 'none';\n\t\t\t\t\t\t\tshowWorkflowBtn.textContent = 'Show Workflow';\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\treturn card;\n\t\t\t}\n\n\t\t\tfunction fetchWorkflowDiagram(workflowId, container) {\n\t\t\t\tconst webhookUrl = `${workflowsData.baseWebhookUrl}${workflowId}`;\n\t\t\t\tfetch(webhookUrl)\n\t\t\t\t\t.then(response => response.text())\n\t\t\t\t\t.then(mermaidCode => {\n\t\t\t\t\t\tcontainer.innerHTML = mermaidCode;\n\t\t\t\t\t\tcontainer.style.display = 'block';\n\t\t\t\t\t\tmermaid.init(undefined, container);\n\t\t\t\t\t})\n\t\t\t\t\t.catch(error => {\n\t\t\t\t\t\tconsole.error('Error fetching workflow diagram:', error);\n\t\t\t\t\t\tcontainer.innerHTML = '<p class=\"text-danger\">Error loading workflow diagram.</p>';\n\t\t\t\t\t\tcontainer.style.display = 'block';\n\t\t\t\t\t});\n\t\t\t}\n\n            // Initialize mermaid\n            mermaid.initialize({ startOnLoad: false });\n        });\n    </script>\n\n    <script>\n        // Blog posts fetching and rendering\n        document.addEventListener('DOMContentLoaded', () => {\n            const blogPostsContainer = document.getElementById('blog-posts-container');\n            const authors = ['Yulia Dmitrievna', 'Eduard Parsadanyan'];\n            const maxPosts = 3;\n    \n            fetch('{{ $env.WEBHOOK_URL }}')\n                .then(response => response.text())\n                .then(str => new window.DOMParser().parseFromString(str, \"text/xml\"))\n                .then(data => {\n                    const items = data.querySelectorAll(\"item\");\n                    let postCount = 0;\n    \n                    items.forEach(el => {\n                        if (postCount >= maxPosts) return;\n    \n                        const author = el.querySelector(\"dc\\\\:creator\").textContent.trim();\n                        if (authors.includes(author)) {\n                            const title = el.querySelector(\"title\").textContent;\n                            const link = el.querySelector(\"link\").textContent;\n                            const imageUrl = el.querySelector(\"media\\\\:content\").getAttribute(\"url\");\n    \n                            const card = document.createElement('div');\n                            card.className = 'col-md-4 mb-4';\n                            card.innerHTML = `\n                                <div class=\"card h-100\">\n                                    <img src=\"${imageUrl}\" class=\"card-img-top\" alt=\"${title}\">\n                                    <div class=\"card-body\">\n                                        <h5 class=\"card-title\">${title}</h5>\n                                        <p class=\"card-text\">By ${author}</p>\n                                        <a href=\"${link}\" class=\"btn btn-primary\" target=\"_blank\">Read More</a>\n                                    </div>\n                                </div>\n                            `;\n    \n                            blogPostsContainer.appendChild(card);\n                            postCount++;\n                        }\n                    });\n                })\n                .catch(error => {\n                    console.error('Error fetching blog posts:', error);\n                    blogPostsContainer.innerHTML = '<p class=\"text-danger\">Error loading blog posts.</p>';\n                });\n        });\n    </script>\n\n    <script src=\"{{ $env.WEBHOOK_URL }}\"></script>\n</body>\n</html>"}, "typeVersion": 1.1, "notes": "This respondToWebhook node performs automated tasks as part of the workflow."}, {"id": "7f964438-a211-40bf-a991-a93848607513", "name": "Prepare workflow list", "type": "n8n-nodes-base.set", "position": [1800, 360], "parameters": {"options": {}, "assignments": {"assignments": [{"id": "1ce915da-7ee4-487c-9233-0b603d4a913b", "name": "wf_data", "type": "object", "value": "={\n\"id\"  :\"{{ $json.id }}\",\n\"name\":\"{{ $json.name }}\"\n}"}]}}, "typeVersion": 3.4, "notes": "This set node performs automated tasks as part of the workflow."}, {"id": "d379a0b6-aaee-4f4d-91be-74d79c160bb8", "name": "CONFIG", "type": "n8n-nodes-base.set", "position": [2300, 360], "parameters": {"options": {}, "assignments": {"assignments": [{"id": "07da029f-3de3-45cb-8d33-798fa1a3d529", "name": "instance_url", "type": "string", "value": "={{$env[\"N8N_PROTOCOL\"]}}://{{$env[\"N8N_HOST\"]}}"}, {"id": "f7dae7f3-e51b-4da3-ac8b-d198747679d2", "name": "webhook_name", "type": "string", "value": "={{ $('Webhook').params.path}}"}, {"id": "185e41a7-8b61-46e3-99ea-0b0a66982080", "name": "webhook_path", "type": "string", "value": "={{$env[\"N8N_ENDPOINT_WEBHOOK\"] || \"webhook\"}}"}]}, "includeOtherFields": true}, "typeVersion": 3.4, "notes": "This set node performs automated tasks as part of the workflow."}, {"id": "bfc42a15-130c-4e81-9f89-c07b3bb56928", "name": "Code", "type": "n8n-nodes-base.code", "position": [1800, 560], "parameters": {"jsCode": "const workflow = $input.first().json;\n\n// Extract nodes from the workflow\nconst nodes = workflow.nodes || [];\n\n// Node types to exclude\nconst excludedNodeTypes = ['n8n-nodes-base.stickyNote'];\n\n// Define shapes and their corresponding brackets\n// {{ $env.WEBHOOK_URL }}\nconst shapes = {\n    'rect': ['[', ']'],\n    'rhombus': ['{', '}'],\n    'circle': ['((', '))'],\n    'hexagon': ['{{', '}}'],\n    'subroutine': ['[[', ']]'],\n    'parallelogram': ['[\\/', '\\/]'],\n    'wait': ['(', ')']\n    // Add more shapes here as needed\n};\n\n// Define special shapes for specific node types\nconst specialShapes = {\n    'n8n-nodes-base.if': 'rhombus',\n    'n8n-nodes-base.switch': 'rhombus',\n    'n8n-nodes-base.code': 'subroutine',\n    'n8n-nodes-base.executeWorkflow': 'subroutine',\n    'n8n-nodes-base.httpRequest':'parallelogram',\n    'n8n-nodes-base.wait':'wait'\n    // List more special node types\n};\n\n// Function to get the shape for a node type\nfunction getNodeShape(nodeType) {\n    return specialShapes[nodeType] || 'rect';\n}\n\n// Create a map of node names to their \"EL<N>\" identifiers, disabled status, and shape\nconst nodeMap = {};\nlet nodeCounter = 1;\nnodes.forEach((node) => {\n    if (!excludedNodeTypes.includes(node.type)) {\n        const shape = getNodeShape(node.type);\n        nodeMap[node.name] = {\n            id: `EL${nodeCounter}`,\n            disabled: node.disabled || false,\n            shape: shape,\n            brackets: shapes[shape] || shapes['rect'] // Default to rect if shape not found\n        };\n        nodeCounter++;\n    }\n});\n\n// Function to convert special characters to HTML entities\nfunction convertToHTMLEntities(str) {\n    return str.replaceAll('\"',\"'\").replace(/[^\\w\\s-]/g, function(char) {\n        return '&#' + char.charCodeAt(0) + ';';\n    });\n}\n\n// Function to format node text (with strike-through if disabled)\nfunction formatNodeText(nodeName, isDisabled) {\n    const escapedName = convertToHTMLEntities(nodeName);\n    return isDisabled ? `
${escapedName}
` : escapedName;\n}\n\n// Generate connections and isolated nodes\nconst connections = [];\nconst isolatedNodes = new Set(Object.keys(nodeMap));\n\nif (workflow.connections) {\n    Object.entries(workflow.connections).forEach(([sourceName, targetConnections]) => {\n        Object.entries(targetConnections).forEach(([connectionType, targets]) => {\n            targets.forEach(targetArray => {\n                targetArray.forEach(target => {\n                    const sourceNode = nodeMap[sourceName];\n                    const targetNode = nodeMap[target.node];\n                    if (sourceNode && targetNode) {\n                        let connectionLine = `    ${sourceNode.id}${sourceNode.brackets[0]}${formatNodeText(sourceName, sourceNode.disabled)}${sourceNode.brackets[1]}`;\n                        if (connectionType === 'main') {\n                            connectionLine += ` -->`;\n                        } else {\n                            connectionLine += ` -.- |${connectionType}|`;\n                        }\n                        connectionLine += ` ${targetNode.id}${targetNode.brackets[0]}${formatNodeText(target.node, targetNode.disabled)}${targetNode.brackets[1]}`;\n                        connections.push(connectionLine);\n                        isolatedNodes.delete(sourceName);\n                        isolatedNodes.delete(target.node);\n                    }\n                });\n            });\n        });\n    });\n}\n\n// Add isolated nodes to the connections array\nisolatedNodes.forEach(nodeName => {\n    const node = nodeMap[nodeName];\n    connections.push(`    ${node.id}${node.brackets[0]}${formatNodeText(nodeName, node.disabled)}${node.brackets[1]}`);\n});\n\n// Generate the Mermaid flowchart string\nconst mermaidChart = `\n---\nconfig:\n  look: neo\n  theme: default\n---\nflowchart LR\n${connections.join('\\n')}`;\n\n// Output the result\nreturn {\n    json: {\n        mermaidChart: mermaidChart\n    }\n};"}, "typeVersion": 2, "notes": "This code node performs automated tasks as part of the workflow."}, {"id": "28375139-c433-4c6c-a5ac-3d725c9b79ef", "name": "Sticky Note3", "type": "n8n-nodes-base.stickyNote", "position": [2120, 100], "parameters": {"color": 3, "width": 470.91551628883894, "height": 419.34820384538847, "content": "## IMPORTANT NOTE FOR CLOUD USERS\n### Since the cloud version doesn't support environmental variables, please update the following fields:\n\n1. **instance_url**. Change the `{{$env[\"N8N_PROTOCOL\"]}}://{{$env[\"N8N_HOST\"]}}` expression to your cloud instance URL\n2. **webhook_path**. Change the `{{$env[\"N8N_ENDPOINT_WEBHOOK\"] || \"webhook\"}}` simply to the `webhook`. So that the production webhook is called correclty."}, "typeVersion": 1, "notes": "This stickyNote node performs automated tasks as part of the workflow."}, {"id": "63245902-69d7-4d75-8cb3-58198208220a", "name": "Webhook", "type": "n8n-nodes-base.webhook", "position": [1220, 360], "webhookId": "dd9e2c5d-6c48-428e-aa54-bef9e369d3b0", "parameters": {"path": "dd9e2c5d-6c48-428e-aa54-bef9e369d3b0", "options": {}, "responseMode": "responseNode"}, "typeVersion": 2, "notes": "This webhook node performs automated tasks as part of the workflow."}], "active": true, "pinData": {}, "settings": {"callerPolicy": "workflowsFromSameOwner", "executionOrder": "v1", "saveManualExecutions": true, "saveDataSuccessExecution": "all", "errorWorkflow": null, "timezone": "UTC", "executionTimeout": 3600, "maxExecutions": 1000, "retryOnFail": true, "retryCount": 3, "retryDelay": 1000}, "versionId": "e73fe710-a873-4827-9a3f-2740b5479d62", "connections": {"2aef0899-91bb-4141-9ec1-def1c31806ae": {"main": [[{"node": "error-handler-2aef0899-91bb-4141-9ec1-def1c31806ae", "type": "main", "index": 0}], [{"node": "error-handler-2aef0899-91bb-4141-9ec1-def1c31806ae-8a25bb2d", "type": "main", "index": 0}], [{"node": "error-handler-2aef0899-91bb-4141-9ec1-def1c31806ae-614ede18", "type": "main", "index": 0}], [{"node": "error-handler-2aef0899-91bb-4141-9ec1-def1c31806ae-38d41f3f", "type": "main", "index": 0}], [{"node": "error-handler-2aef0899-91bb-4141-9ec1-def1c31806ae-13b43a10", "type": "main", "index": 0}], [{"node": "error-handler-2aef0899-91bb-4141-9ec1-def1c31806ae-883ad95d", "type": "main", "index": 0}], [{"node": "error-handler-2aef0899-91bb-4141-9ec1-def1c31806ae-53eac785", "type": "main", "index": 0}], [{"node": "error-handler-2aef0899-91bb-4141-9ec1-def1c31806ae-9083f1be", "type": "main", "index": 0}], [{"node": "error-handler-2aef0899-91bb-4141-9ec1-def1c31806ae-29a85383", "type": "main", "index": 0}]]}, "95e0b67b-5e5b-4433-9822-da86900c12ca": {"main": [[{"node": "error-handler-95e0b67b-5e5b-4433-9822-da86900c12ca", "type": "main", "index": 0}], [{"node": "error-handler-95e0b67b-5e5b-4433-9822-da86900c12ca-9145376a", "type": "main", "index": 0}], [{"node": "error-handler-95e0b67b-5e5b-4433-9822-da86900c12ca-ea6ac707", "type": "main", "index": 0}], [{"node": "error-handler-95e0b67b-5e5b-4433-9822-da86900c12ca-6141ea86", "type": "main", "index": 0}], [{"node": "error-handler-95e0b67b-5e5b-4433-9822-da86900c12ca-e2b5c611", "type": "main", "index": 0}], [{"node": "error-handler-95e0b67b-5e5b-4433-9822-da86900c12ca-b50f6a5d", "type": "main", "index": 0}], [{"node": "error-handler-95e0b67b-5e5b-4433-9822-da86900c12ca-576d5ac3", "type": "main", "index": 0}], [{"node": "error-handler-95e0b67b-5e5b-4433-9822-da86900c12ca-2b8fa7da", "type": "main", "index": 0}], [{"node": "error-handler-95e0b67b-5e5b-4433-9822-da86900c12ca-b6d804eb", "type": "main", "index": 0}]]}, "63245902-69d7-4d75-8cb3-58198208220a": {"main": [[{"node": "error-handler-63245902-69d7-4d75-8cb3-58198208220a", "type": "main", "index": 0}], [{"node": "error-handler-63245902-69d7-4d75-8cb3-58198208220a-2422e019", "type": "main", "index": 0}], [{"node": "error-handler-63245902-69d7-4d75-8cb3-58198208220a-028043bc", "type": "main", "index": 0}], [{"node": "error-handler-63245902-69d7-4d75-8cb3-58198208220a-8d77dfa4", "type": "main", "index": 0}], [{"node": "error-handler-63245902-69d7-4d75-8cb3-58198208220a-23268519", "type": "main", "index": 0}], [{"node": "error-handler-63245902-69d7-4d75-8cb3-58198208220a-ec71249b", "type": "main", "index": 0}], [{"node": "error-handler-63245902-69d7-4d75-8cb3-58198208220a-8e1a1065", "type": "main", "index": 0}], [{"node": "error-handler-63245902-69d7-4d75-8cb3-58198208220a-4f8a97c1", "type": "main", "index": 0}], [{"node": "error-handler-63245902-69d7-4d75-8cb3-58198208220a-102042b1", "type": "main", "index": 0}]]}}, "description": "Automated workflow: Workflow dashboard with mermaid.js. This workflow integrates 10 different services: webhook, stickyNote, code, n8n, switch. It contains 18 nodes and follows best practices for error handling and security.", "notes": "Excellent quality workflow: Workflow dashboard with mermaid.js. This workflow has been optimized for production use with comprehensive error handling, security, and documentation."}