{ "kind": "open-flow-workflow", "version": 1, "name": "Create an HTML Timesheet Report", "content": { "modelVersion": 14, "document": { "bindings": {}, "graph": { "nodes": { "n_afdcae8f4e0fb270": { "name": "Enter timesheet records", "kind": "start", "inputDefs": [ { "jsonSchema": { "type": "array", "items": { "type": "object", "additionalProperties": true } }, "nullable": false, "handle": "records" } ] }, "n_d6cbc3100fb090ad": { "inputs": { "records": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_afdcae8f4e0fb270", "output": "records" } ] } }, "name": "Build the timesheet report", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "array", "items": { "type": "object", "additionalProperties": true } }, "nullable": false, "handle": "records" } ], "outputs": [ { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "html" } ], "name": "Build the timesheet report", "moduleId": "n_b567b5e4b19a4931", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } }, "n_ca8f14d2fc39207b": { "inputs": { "html": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_d6cbc3100fb090ad", "output": "html" } ] } }, "name": "Create the HTML file", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "html" } ], "outputs": [ { "jsonSchema": { "type": "object", "properties": { "kind": { "const": "artifact" }, "id": { "type": "string" }, "name": { "type": "string" }, "mediaType": { "type": "string" }, "size": { "type": "integer", "minimum": 1 }, "digest": { "type": "string" } }, "required": [ "kind", "id", "name", "size", "digest" ] }, "nullable": false, "handle": "file" } ], "name": "Create the HTML file", "moduleId": "n_5786e42869f7c491", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } }, "n_d004a5d7f5cf87c8": { "name": "Download the report", "kind": "outputs", "outputDefs": [ { "jsonSchema": { "type": "object", "properties": { "kind": { "const": "artifact" }, "id": { "type": "string" }, "name": { "type": "string" }, "mediaType": { "type": "string" }, "size": { "type": "integer", "minimum": 1 }, "digest": { "type": "string" } }, "required": [ "kind", "id", "name", "size", "digest" ] }, "nullable": false, "handle": "file" } ], "outputMappings": { "file": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_ca8f14d2fc39207b", "output": "file" } ] } } } }, "edges": [ { "source": "n_afdcae8f4e0fb270", "target": "n_d6cbc3100fb090ad" }, { "source": "n_d6cbc3100fb090ad", "target": "n_ca8f14d2fc39207b" }, { "source": "n_ca8f14d2fc39207b", "target": "n_d004a5d7f5cf87c8" } ] } }, "modules": { "n_b567b5e4b19a4931": { "name": "Build the timesheet report", "imports": [], "source": "export default function report({records}){\n if(!Array.isArray(records)||!records.length)throw Error('Provide timesheet records');const esc=x=>String(x??'').replace(/[&<>\"']/g,c=>({'&':'&','<':'<','>':'>','\"':'"',\"'\":'''}[c]));const rows=records.map(r=>{if(!r||typeof r.UserName!=='string'||!r.UserName||typeof r.TaskTitle!=='string'||!r.TaskTitle||typeof r.date!=='string'||typeof r.UserAvatar!=='string'||!/^https:\\/\\//i.test(r.UserAvatar)||!Number.isFinite(Number(r.hours)))throw Error('Invalid timesheet record');return r}).sort((a,b)=>a.UserName.localeCompare(b.UserName)||a.TaskTitle.localeCompare(b.TaskTitle)||a.date.localeCompare(b.date));let html='
'+total.toFixed(2)+' - Total hours for this task
';if(r.UserName!==user){user=r.UserName;html+='| Date | Hours | Task Description |
|---|---|---|
| '+esc(r.date.split('T')[0])+' | '+Number(r.hours).toFixed(2)+' | '+esc(r.note)+' |
'+total.toFixed(2)+' - Total hours for this task
Timesheet report generated on: '+new Date().toISOString().slice(0,10)+'
';return{html};}\n" }, "n_5786e42869f7c491": { "name": "Create the HTML file", "imports": [], "source": "export default async function file({html},context){return {file:await context.artifact.put(Buffer.from(html,'utf8'),{name:'report.html',mediaType:'text/html'})};}\n" } } }, "presentation": { "designer": { "version": 1, "flow": { "direction": "vertical" } } } }