@hrspd-gss/bole-clickwizard-designer 1.0.1 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,6 @@
1
1
  import { default as React } from 'react';
2
2
  import { Workflow, WorkflowEditorProps } from './types';
3
+
3
4
  export interface WorkflowEditorRef {
4
5
  getWorkflow: () => Workflow;
5
6
  setWorkflow: (workflow: Workflow) => void;
package/dist/index.js CHANGED
@@ -1,6 +1 @@
1
- (function(te,f){typeof exports=="object"&&typeof module<"u"?f(exports,require("react")):typeof define=="function"&&define.amd?define(["exports","react"],f):(te=typeof globalThis<"u"?globalThis:te||self,f(te.BoleClickwizardDesigner={},te.React))})(this,(function(te,f){"use strict";var Ie={exports:{}},xe={};var De;function Fe(){if(De)return xe;De=1;var D=Symbol.for("react.transitional.element"),U=Symbol.for("react.fragment");function re(T,M,C){var c=null;if(C!==void 0&&(c=""+C),M.key!==void 0&&(c=""+M.key),"key"in M){C={};for(var B in M)B!=="key"&&(C[B]=M[B])}else C=M;return M=C.ref,{$$typeof:D,type:T,key:c,ref:M!==void 0?M:null,props:C}}return xe.Fragment=U,xe.jsx=re,xe.jsxs=re,xe}var ve={};var Ae;function ze(){return Ae||(Ae=1,process.env.NODE_ENV!=="production"&&(function(){function D(o){if(o==null)return null;if(typeof o=="function")return o.$$typeof===A?null:o.displayName||o.name||null;if(typeof o=="string")return o;switch(o){case Q:return"Fragment";case ae:return"Profiler";case _e:return"StrictMode";case J:return"Suspense";case ie:return"SuspenseList";case g:return"Activity"}if(typeof o=="object")switch(typeof o.tag=="number"&&console.error("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."),o.$$typeof){case se:return"Portal";case je:return o.displayName||"Context";case ue:return(o._context.displayName||"Context")+".Consumer";case Re:var d=o.render;return o=o.displayName,o||(o=d.displayName||d.name||"",o=o!==""?"ForwardRef("+o+")":"ForwardRef"),o;case ce:return d=o.displayName||null,d!==null?d:D(o.type)||"Memo";case ye:d=o._payload,o=o._init;try{return D(o(d))}catch{}}return null}function U(o){return""+o}function re(o){try{U(o);var d=!1}catch{d=!0}if(d){d=console;var j=d.error,N=typeof Symbol=="function"&&Symbol.toStringTag&&o[Symbol.toStringTag]||o.constructor.name||"Object";return j.call(d,"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",N),U(o)}}function T(o){if(o===Q)return"<>";if(typeof o=="object"&&o!==null&&o.$$typeof===ye)return"<...>";try{var d=D(o);return d?"<"+d+">":"<...>"}catch{return"<...>"}}function M(){var o=pe.A;return o===null?null:o.getOwner()}function C(){return Error("react-stack-top-frame")}function c(o){if(fe.call(o,"key")){var d=Object.getOwnPropertyDescriptor(o,"key").get;if(d&&d.isReactWarning)return!1}return o.key!==void 0}function B(o,d){function j(){v||(v=!0,console.error("%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)",d))}j.isReactWarning=!0,Object.defineProperty(o,"key",{get:j,configurable:!0})}function m(){var o=D(this.type);return Ee[o]||(Ee[o]=!0,console.error("Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release.")),o=this.props.ref,o!==void 0?o:null}function G(o,d,j,N,$,ke){var E=j.ref;return o={$$typeof:we,type:o,key:d,props:j,_owner:N},(E!==void 0?E:null)!==null?Object.defineProperty(o,"ref",{enumerable:!1,get:m}):Object.defineProperty(o,"ref",{enumerable:!1,value:null}),o._store={},Object.defineProperty(o._store,"validated",{configurable:!1,enumerable:!1,writable:!0,value:0}),Object.defineProperty(o,"_debugInfo",{configurable:!1,enumerable:!1,writable:!0,value:null}),Object.defineProperty(o,"_debugStack",{configurable:!1,enumerable:!1,writable:!0,value:$}),Object.defineProperty(o,"_debugTask",{configurable:!1,enumerable:!1,writable:!0,value:ke}),Object.freeze&&(Object.freeze(o.props),Object.freeze(o)),o}function x(o,d,j,N,$,ke){var E=d.children;if(E!==void 0)if(N)if(q(E)){for(N=0;N<E.length;N++)V(E[N]);Object.freeze&&Object.freeze(E)}else console.error("React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead.");else V(E);if(fe.call(d,"key")){E=D(o);var ee=Object.keys(d).filter(function(Se){return Se!=="key"});N=0<ee.length?"{key: someKey, "+ee.join(": ..., ")+": ...}":"{key: someKey}",ge[E+N]||(ee=0<ee.length?"{"+ee.join(": ..., ")+": ...}":"{}",console.error(`A props object containing a "key" prop is being spread into JSX:
2
- let props = %s;
3
- <%s {...props} />
4
- React keys must be passed directly to JSX without using spread:
5
- let props = %s;
6
- <%s key={someKey} {...props} />`,N,E,ee,E),ge[E+N]=!0)}if(E=null,j!==void 0&&(re(j),E=""+j),c(d)&&(re(d.key),E=""+d.key),"key"in d){j={};for(var be in d)be!=="key"&&(j[be]=d[be])}else j=d;return E&&B(j,typeof o=="function"?o.displayName||o.name||"Unknown":o),G(o,E,j,M(),$,ke)}function V(o){Ne(o)?o._store&&(o._store.validated=1):typeof o=="object"&&o!==null&&o.$$typeof===ye&&(o._payload.status==="fulfilled"?Ne(o._payload.value)&&o._payload.value._store&&(o._payload.value._store.validated=1):o._store&&(o._store.validated=1))}function Ne(o){return typeof o=="object"&&o!==null&&o.$$typeof===we}var oe=f,we=Symbol.for("react.transitional.element"),se=Symbol.for("react.portal"),Q=Symbol.for("react.fragment"),_e=Symbol.for("react.strict_mode"),ae=Symbol.for("react.profiler"),ue=Symbol.for("react.consumer"),je=Symbol.for("react.context"),Re=Symbol.for("react.forward_ref"),J=Symbol.for("react.suspense"),ie=Symbol.for("react.suspense_list"),ce=Symbol.for("react.memo"),ye=Symbol.for("react.lazy"),g=Symbol.for("react.activity"),A=Symbol.for("react.client.reference"),pe=oe.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,fe=Object.prototype.hasOwnProperty,q=Array.isArray,L=console.createTask?console.createTask:function(){return null};oe={react_stack_bottom_frame:function(o){return o()}};var v,Ee={},X=oe.react_stack_bottom_frame.bind(oe,C)(),S=L(T(C)),ge={};ve.Fragment=Q,ve.jsx=function(o,d,j){var N=1e4>pe.recentlyCreatedOwnerStacks++;return x(o,d,j,!1,N?Error("react-stack-top-frame"):X,N?L(T(o)):S)},ve.jsxs=function(o,d,j){var N=1e4>pe.recentlyCreatedOwnerStacks++;return x(o,d,j,!0,N?Error("react-stack-top-frame"):X,N?L(T(o)):S)}})()),ve}var Le;function Ue(){return Le||(Le=1,process.env.NODE_ENV==="production"?Ie.exports=Fe():Ie.exports=ze()),Ie.exports}var t=Ue();const Y=200,ne=80,Je=31,Xe=16,Ze=16,Ke=9,Qe=14,qe=f.forwardRef(({initialWorkflow:D,onChange:U,className:re,nodeTypeConfigs:T=[]},M)=>{const C=f.useMemo(()=>{const e=new Map;return T.forEach(r=>{e.set(r.type,r)}),e},[T]),[c,B]=f.useState(D),[m,G]=f.useState(null),[x,V]=f.useState(null),[Ne,oe]=f.useState(null),[we,se]=f.useState(null),[Q,_e]=f.useState(null),[ae,ue]=f.useState(null),[je,Re]=f.useState(!1),[J,ie]=f.useState(null),[ce,ye]=f.useState(new Map),[g,A]=f.useState(null),[pe,fe]=f.useState(null),q=f.useRef(null),L=f.useRef(null),v=f.useRef(null),Ee=f.useRef(null),X=f.useRef(new Map);f.useEffect(()=>{B(D)},[D]);const S=e=>{B(e),U?.(e)};f.useEffect(()=>{const e=()=>{const s=new Map;X.current.forEach((a,i)=>{a&&s.set(i,a.offsetHeight)});let n=!1;s.forEach((a,i)=>{ce.get(i)!==a&&(n=!0)}),(n||s.size!==ce.size)&&ye(s)};e();const r=new ResizeObserver(()=>{e()});return X.current.forEach(s=>{s&&r.observe(s)}),()=>{r.disconnect()}},[c.nodes]),f.useImperativeHandle(M,()=>({getWorkflow:()=>c,setWorkflow:e=>{S(e),G(null)}}));const ge=f.useCallback(()=>{if(!m)return;let e=[...c.nodes],r=[...c.edges];if(m.type==="node"){const s=c.nodes.find(n=>n.id===m.id);if(s?.type==="start"||s?.type==="end")return;e=c.nodes.filter(n=>n.id!==m.id),r=c.edges.filter(n=>n.sourceNodeId!==m.id&&n.targetNodeId!==m.id)}else r=c.edges.filter(s=>s.id!==m.id);G(null),S({nodes:e,edges:r})},[m,c,S]);f.useEffect(()=>{const e=r=>{const s=r.target,n=s.tagName==="INPUT"||s.tagName==="TEXTAREA"||s.tagName==="SELECT"||s.isContentEditable;if(r.key==="Escape"){if(g){A(null),fe(null);return}if(x){V(null);return}if(m){J&&(B(J),U?.(J)),G(null),ue(null),ie(null);return}}m&&(r.key==="Delete"||r.key==="Backspace")&&!n&&ge()};return document.addEventListener("keydown",e),()=>{document.removeEventListener("keydown",e)}},[m,ge,J,U,x,g]);const o=(e,r)=>{const n=e.target.closest(".workflow-node").getBoundingClientRect();q.current={nodeId:r,offset:{x:e.clientX-n.left,y:e.clientY-n.top}},e.dataTransfer.effectAllowed="move"},d=e=>{e.preventDefault()},j=e=>{if(e.preventDefault(),!q.current||!v.current)return;const r=v.current.getBoundingClientRect(),s={x:e.clientX-r.left+v.current.scrollLeft-q.current.offset.x,y:e.clientY-r.top+v.current.scrollTop-q.current.offset.y},n=c.nodes.map(a=>a.id===q.current?.nodeId?{...a,position:{x:Math.max(0,s.x),y:Math.max(0,s.y)}}:a);S({...c,nodes:n}),q.current=null},N=(e,r)=>{ie(JSON.parse(JSON.stringify(c))),G({type:e,id:r})},$=(e,r)=>{if(m){if(m.type==="node"){const s=c.nodes.map(n=>{if(n.id===m.id){if(e==="type"){const i=C.get(r),l=i?.defaultParameters?{...i.defaultParameters}:{};return{...n,type:r,parameters:l}}if(e in n&&e!=="parameters")return{...n,[e]:r};const a={...n.parameters||{},[e]:r};return{...n,parameters:a}}return n});S({...c,nodes:s})}else if(m.type==="edge"){const s=c.edges.map(n=>n.id===m.id?{...n,[e]:r}:n);S({...c,edges:s})}}},ke=(e,r)=>{if(e.stopPropagation(),!v.current)return;const s=v.current.getBoundingClientRect(),n=c.nodes.find(u=>u.id===r);if(!n)return;const a=X.current.get(r),i=a?a.offsetHeight:ne,l={x:n.position.x+Y,y:n.position.y+i/2};V({startNodeId:r,startPos:l,endPos:{x:e.clientX-s.left+v.current.scrollLeft,y:e.clientY-s.top+v.current.scrollTop}})},E=(e,r,s)=>{if(e.stopPropagation(),!v.current)return;const n=c.edges.find(w=>w.id===r);if(!n)return;const a=v.current.getBoundingClientRect(),i=n.sourceNodeId,l=n.targetNodeId,u=c.nodes.find(w=>w.id===i),k=c.nodes.find(w=>w.id===l);if(!u||!k)return;const p=X.current.get(i),I=p?p.offsetHeight:ne,h={x:u.position.x+Y,y:u.position.y+I/2};A({edgeId:r,endpoint:s,startPos:h,endPos:{x:e.clientX-a.left+v.current.scrollLeft,y:e.clientY-a.top+v.current.scrollTop}}),se(null)},ee=e=>{if(!v.current)return;if(g){e.preventDefault();const s=v.current.getBoundingClientRect();A({...g,endPos:{x:e.clientX-s.left+v.current.scrollLeft,y:e.clientY-s.top+v.current.scrollTop}});return}if(!x)return;e.preventDefault();const r=v.current.getBoundingClientRect();V({...x,endPos:{x:e.clientX-r.left+v.current.scrollLeft,y:e.clientY-r.top+v.current.scrollTop}})},be=(e,r)=>{if(e.stopPropagation(),g){const a=c.edges.find(p=>p.id===g.edgeId);if(!a){A(null);return}if(g.endpoint==="source"&&r===a.targetNodeId){A(null);return}if(g.endpoint==="target"&&r===a.sourceNodeId){A(null);return}const i=g.endpoint==="source"?r:a.sourceNodeId,l=g.endpoint==="target"?r:a.targetNodeId;if(c.edges.some(p=>p.id!==a.id&&p.sourceNodeId===i&&p.targetNodeId===l)){A(null);return}const k=c.edges.map(p=>p.id===g.edgeId?{...p,sourceNodeId:i,targetNodeId:l}:p);S({...c,edges:k}),A(null);return}if(!x){N("node",r);return}if(x.startNodeId===r){V(null);return}const s={id:`edge_${Date.now()}`,sourceNodeId:x.startNodeId,targetNodeId:r};if(c.edges.some(a=>a.sourceNodeId===s.sourceNodeId&&a.targetNodeId===s.targetNodeId)){V(null);return}S({...c,edges:[...c.edges,s]}),V(null)},Se=e=>{if(g){A(null);return}if(x&&v.current){const r=v.current.getBoundingClientRect(),s=e.clientX-r.left+v.current.scrollLeft,n=e.clientY-r.top+v.current.scrollTop;ie(JSON.parse(JSON.stringify(c)));const a=`node_${Date.now()}`,i=T.length>0?T[0].type:"task",l=T.length>0?T[0]:null,u=l?.defaultParameters?{...l.defaultParameters}:{},k={id:a,name:"New Node",type:i,position:{x:Math.max(0,s-Y/2),y:Math.max(0,n-ne/2)},parameters:u},p={id:`edge_${Date.now()}`,sourceNodeId:x.startNodeId,targetNodeId:a},I={nodes:[...c.nodes,k],edges:[...c.edges,p]};S(I),V(null),G({type:"node",id:a});return}G(null)},et=e=>{if(e.type==="start")return null;if(e.type==="end")return t.jsxs("div",{className:"form-group",style:{display:"flex",alignItems:"center",gap:"8px",cursor:"pointer"},children:[t.jsx("input",{type:"checkbox",id:"end-autoclose",checked:!!e.parameters?.autoCloseTab,onChange:s=>$("autoCloseTab",s.target.checked)}),t.jsx("label",{htmlFor:"end-autoclose",style:{margin:0,cursor:"pointer"},children:"自動關閉 Tab"})]});const r=C.get(e.type);if((e.type==="goto"||e.type==="click")&&e.parameters){const s=e.parameters.dialogMode||"autoAccept";return t.jsxs("div",{children:[t.jsxs("div",{className:"form-group",children:[t.jsx("label",{children:"Dialog 處理"}),t.jsxs("select",{value:s,onChange:n=>$("dialogMode",n.target.value),children:[t.jsx("option",{value:"autoAccept",children:"autoAccept(自動接受 confirm,並關閉 alert)"}),t.jsx("option",{value:"autoDismiss",children:"autoDismiss(自動取消 confirm)"}),t.jsx("option",{value:"reportOnly",children:"reportOnly(僅回報)"})]})]}),r?.renderProperties?r.renderProperties(e.parameters,$):null]})}return r?.renderProperties&&e.parameters?r.renderProperties(e.parameters,$):null},le=(e,r)=>{if(!m||m.type!=="edge")return;const s=c.edges.find(i=>i.id===m.id);if(!s)return;let n=s.condition?{...s.condition}:{type:"none"};if(e==="type")r==="none"?n=void 0:(n={type:r},r==="compare"&&(n.left={source:"variable",name:""},n.operator="==",n.right={source:"literal",value:""}));else if(n){if(e==="operator")n.operator=r;else if(e==="expression")n.expression=r;else if(e.startsWith("left.")){const i=e.substring(5);(!n.left||typeof n.left!="object")&&(n.left={source:"variable",name:""}),i==="source"?n.left={source:r}:n.left[i]=r}else if(e.startsWith("right.")){const i=e.substring(6);(!n.right||typeof n.right!="object")&&(n.right={source:"literal",value:""}),i==="source"?n.right={source:r}:n.right[i]=r}}const a=c.edges.map(i=>i.id===m.id?{...i,condition:n}:i);S({...c,edges:a})},tt=f.useCallback(e=>{const r=[],n=(e?c.edges.find(l=>l.id===e):null)?.sourceNodeId,a=new Set,i=new Set;if(n){const l=c.nodes.find(u=>u.type==="start");if(l){l.id;const u=new Map;c.edges.forEach(p=>{u.has(p.targetNodeId)||u.set(p.targetNodeId,new Set),u.get(p.targetNodeId).add(p.sourceNodeId)});const k=p=>{if(a.has(p))return;a.add(p),i.add(p);const I=u.get(p);I&&I.forEach(h=>k(h))};k(n)}}else c.nodes.forEach(l=>i.add(l.id));return c.nodes.forEach(l=>{if(i.has(l.id)&&l.parameters){const u=l.parameters.outputVariable;u&&typeof u=="string"&&u.trim()!==""&&r.push(u.trim())}}),[...new Set(r)].sort()},[c]),$e=(e,r,s,n)=>{const a=r?.source||"literal",i=tt(n);return t.jsxs("div",{className:"condition-value-group",children:[t.jsx("label",{children:s}),t.jsxs("div",{className:"condition-value-row",children:[t.jsxs("select",{value:a,onChange:l=>le(`${e}.source`,l.target.value),className:"condition-source-select",children:[t.jsx("option",{value:"literal",children:"固定值"}),t.jsx("option",{value:"variable",children:"變數"}),t.jsx("option",{value:"result",children:"節點結果"})]}),a==="literal"&&t.jsx("input",{type:"text",value:r?.value??"",onChange:l=>le(`${e}.value`,l.target.value),placeholder:"輸入值",className:"condition-value-input"}),a==="variable"&&t.jsxs(t.Fragment,{children:[t.jsx("input",{type:"text",list:`${e}-variable-list`,value:r?.name??"",onChange:l=>le(`${e}.name`,l.target.value),placeholder:i.length>0?"輸入或選擇變數...":"輸入變數名稱",className:"condition-value-input"}),i.length>0&&t.jsx("datalist",{id:`${e}-variable-list`,children:i.map(l=>t.jsx("option",{value:l},l))})]}),a==="result"&&t.jsx("input",{type:"text",value:r?.path??"",onChange:l=>le(`${e}.path`,l.target.value),placeholder:"結果路徑 (如: data.value)",className:"condition-value-input"})]})]})},nt=e=>{const r=e.condition,s=r?.type||"none";return t.jsxs("div",{className:"edge-condition-editor",children:[t.jsxs("div",{className:"form-group",children:[t.jsx("label",{children:"條件類型"}),t.jsxs("select",{value:s,onChange:n=>le("type",n.target.value),children:[t.jsx("option",{value:"none",children:"無條件(總是執行)"}),t.jsx("option",{value:"success",children:"成功時執行"}),t.jsx("option",{value:"failure",children:"失敗時執行"}),t.jsx("option",{value:"compare",children:"比較條件"}),t.jsx("option",{value:"expression",children:"自訂表達式"}),t.jsx("option",{value:"else",children:"其他條件皆不成立時 (Else)"})]})]}),s==="compare"&&t.jsxs("div",{className:"compare-condition-editor",children:[$e("left",r?.left,"左值",e.id),t.jsxs("div",{className:"form-group",children:[t.jsx("label",{children:"運算子"}),t.jsxs("select",{value:r?.operator||"==",onChange:n=>le("operator",n.target.value),children:[t.jsx("option",{value:"==",children:"等於 (==)"}),t.jsx("option",{value:"===",children:"嚴格等於 (===)"}),t.jsx("option",{value:"!=",children:"不等於 (!=)"}),t.jsx("option",{value:"!==",children:"嚴格不等於 (!==)"}),t.jsx("option",{value:">",children:"大於 (>)"}),t.jsx("option",{value:">=",children:"大於等於 (>=)"}),t.jsx("option",{value:"<",children:"小於 (<)"}),t.jsx("option",{value:"<=",children:"小於等於 (<=)"}),t.jsx("option",{value:"contains",children:"包含"}),t.jsx("option",{value:"startsWith",children:"開頭是"}),t.jsx("option",{value:"endsWith",children:"結尾是"}),t.jsx("option",{value:"matches",children:"正則匹配"})]})]}),$e("right",r?.right,"右值",e.id)]}),s==="expression"&&t.jsxs("div",{className:"form-group",children:[t.jsx("label",{children:"表達式"}),t.jsx("textarea",{value:r?.expression||"",onChange:n=>le("expression",n.target.value),placeholder:"例如: result.success && variables.count > 0",rows:3}),t.jsx("small",{className:"form-hint",children:"可用變數: result (節點結果), context (執行上下文), variables (工作流程變數)"})]})]})},rt=()=>{J&&(B(J),U?.(J)),G(null),ue(null),ie(null)},ot=()=>{G(null),ue(null),ie(null)},st=e=>{if(e.target.closest("input, select, textarea, button"))return;e.preventDefault(),Re(!0);const r=Ee.current;if(!r)return;const s=r.getBoundingClientRect(),n=ae?.x??s.left,a=ae?.y??s.top;L.current={startX:e.clientX,startY:e.clientY,startPosX:n,startPosY:a}};f.useEffect(()=>{if(!je)return;const e=s=>{if(!L.current)return;const n=s.clientX-L.current.startX,a=s.clientY-L.current.startY;ue({x:L.current.startPosX+n,y:L.current.startPosY+a})},r=()=>{Re(!1),L.current=null};return document.addEventListener("mousemove",e),document.addEventListener("mouseup",r),()=>{document.removeEventListener("mousemove",e),document.removeEventListener("mouseup",r)}},[je]);const at=()=>{if(!m)return null;let e,r=m.type==="node";if(r?e=c.nodes.find(n=>n.id===m.id):e=c.edges.find(n=>n.id===m.id),!e)return null;T.map(n=>n.type);const s=ae?{position:"fixed",left:ae.x,top:ae.y,transform:"none"}:{};return t.jsx("div",{className:"properties-popup-overlay",onClick:n=>n.stopPropagation(),children:t.jsxs("div",{ref:Ee,className:`properties-popup ${je?"dragging":""}`,style:s,children:[t.jsxs("div",{className:"properties-popup-header",onMouseDown:st,children:[t.jsxs("h4",{children:["Edit: ",r?e.name:"Edge"]}),t.jsx("button",{className:"properties-popup-close",onClick:rt,children:"×"})]}),t.jsxs("div",{className:"properties-popup-content",children:[t.jsxs("div",{className:"form-group",children:[t.jsx("label",{children:"ID"}),t.jsx("input",{type:"text",readOnly:!0,value:e.id})]}),r&&e.type!=="start"&&e.type!=="end"&&t.jsxs(t.Fragment,{children:[t.jsxs("div",{className:"form-group",children:[t.jsx("label",{children:"Name"}),t.jsx("input",{type:"text",value:e.name,onChange:n=>$("name",n.target.value)})]}),t.jsxs("div",{className:"form-group",children:[t.jsx("label",{children:"Type"}),t.jsx("select",{value:e.type,onChange:n=>$("type",n.target.value),children:T.map(n=>t.jsx("option",{value:n.type,children:n.label||n.type},n.type))})]})]}),r&&et(e),!r&&nt(e)]}),t.jsxs("div",{className:"properties-popup-footer",children:[(r&&e.type!=="start"&&e.type!=="end"||!r)&&t.jsx("button",{className:"btn-danger",onClick:ge,children:"Delete"}),t.jsx("button",{className:"btn-primary",onClick:ot,children:"OK"})]})]})})},He=new Map(c.nodes.map(e=>[e.id,e])),We=e=>{const r=ce.get(e.id);if(r&&r>0)return r;if(!e.parameters||Object.keys(e.parameters).length===0)return ne;const s=Object.entries(e.parameters).filter(([p,I])=>I!=null&&I!=="");if(s.length===0)return ne;const n=Math.min(s.length,3),a=s.length>3,i=n+(a?1:0),l=Je+Xe+Ze,u=Ke+i*Qe,k=l+u;return Math.max(ne,k)},Ye=(e,r,s,n,a,i,l,u,k,p,I,h,w=10)=>{const de=k-5,Z=p-5,H=I+10,_=h+10;for(let he=1;he<w;he++){const R=he/w,b=Math.pow(1-R,3)*e+3*Math.pow(1-R,2)*R*s+3*(1-R)*Math.pow(R,2)*a+Math.pow(R,3)*l,y=Math.pow(1-R,3)*r+3*Math.pow(1-R,2)*R*n+3*(1-R)*Math.pow(R,2)*i+Math.pow(R,3)*u;if(b>=de&&b<=de+H&&y>=Z&&y<=Z+_)return!0}return!1},Te=(()=>{const e=new Map,r=new Map;return c.edges.forEach(s=>{const n=[s.sourceNodeId,s.targetNodeId].sort().join("-");e.set(n,(e.get(n)||0)+1)}),c.edges.map(s=>{const n=He.get(s.sourceNodeId),a=He.get(s.targetNodeId);if(!n||!a)return null;const i=We(n),l=We(a),u=[s.sourceNodeId,s.targetNodeId].sort().join("-"),k=e.get(u)||1,p=r.get(u)||0;r.set(u,p+1);const w=(p-(k-1)/2)*15,Pe=n.position.y+i/2,de=a.position.x+Y/2,Z=a.position.y+l/2,H=n.position.x+Y,_=Pe+w,he=de-H,R=Z-_;let b,y,W;Math.abs(he)>Math.abs(R)?he>0?(b=a.position.x,y=Z+w,W="left"):(b=a.position.x+Y,y=Z+w,W="right"):R>0?(b=de+w,y=a.position.y,W="top"):(b=de+w,y=a.position.y+l,W="bottom");const Ge=de-(n.position.x+Y/2),Ve=Z-Pe,it=Math.sqrt(Ge*Ge+Ve*Ve);let F=Math.max(40,it*.3),me=H+F,z=_,K,P;W==="left"?(K=b-F,P=y):W==="right"?(K=b+F,P=y):W==="top"?(K=b,P=y-F):(K=b,P=y+F);let Oe=Ye(H,_,me,z,K,P,b,y,a.position.x,a.position.y,Y,l);if(Oe){const Ce=l+30;if(W==="right"?(Z<=_?(z=_+Ce,P=y+Ce):(z=_-Ce,P=y-Ce),me=H+F*1.5,K=b+F*1.5):(W==="top"||W==="bottom")&&(me=H+F*1.5,W==="top"?P=y-F*1.5:P=y+F*1.5),Oe=Ye(H,_,me,z,K,P,b,y,a.position.x,a.position.y,Y,l),Oe){const Me=l+60;Z<=_?(z=Math.max(z,_+Me),P=Math.max(P,y+Me)):(z=Math.min(z,_-Me),P=Math.min(P,y-Me))}}const ct=`M ${H},${_} C ${me},${z} ${K},${P} ${b},${y}`,lt=m?.id===s.id?"url(#arrowhead-selected)":"url(#arrowhead)",O=.5,dt=Math.pow(1-O,3)*H+3*Math.pow(1-O,2)*O*me+3*(1-O)*Math.pow(O,2)*K+Math.pow(O,3)*b,ut=Math.pow(1-O,3)*_+3*Math.pow(1-O,2)*O*z+3*(1-O)*Math.pow(O,2)*P+Math.pow(O,3)*y;return{edge:s,pathData:ct,markerId:lt,startX:H,startY:_,endX:b,endY:y,midX:dt,midY:ut,isSelected:m?.id===s.id}}).filter(Boolean)})(),Be=f.useMemo(()=>{let n=800,a=600;return c.nodes.forEach(i=>{const l=ce.get(i.id)||ne,u=i.position.x+Y+100,k=i.position.y+l+100;u>n&&(n=u),k>a&&(a=k)}),{width:n,height:a}},[c.nodes,ce]);return t.jsx("div",{className:`workflow-editor-container ${re||""}`,children:t.jsx("div",{className:"workflow-body",children:t.jsxs("div",{ref:v,className:"workflow-canvas",onDragOver:d,onDrop:j,onMouseMove:ee,onClick:Se,children:[t.jsx("div",{className:"workflow-canvas-content",style:{width:`${Be.width}px`,height:`${Be.height}px`}}),t.jsxs("svg",{className:"workflow-svg-layer",children:[t.jsxs("defs",{children:[t.jsx("marker",{id:"arrowhead",viewBox:"0 0 10 10",refX:"8",refY:"5",markerWidth:"6",markerHeight:"6",orient:"auto-start-reverse",children:t.jsx("path",{d:"M 0 0 L 10 5 L 0 10 z",fill:"#495057"})}),t.jsx("marker",{id:"arrowhead-selected",viewBox:"0 0 10 10",refX:"8",refY:"5",markerWidth:"6",markerHeight:"6",orient:"auto-start-reverse",children:t.jsx("path",{d:"M 0 0 L 10 5 L 0 10 z",fill:"#007bff"})}),t.jsx("marker",{id:"arrowhead-active",viewBox:"0 0 10 10",refX:"8",refY:"5",markerWidth:"6",markerHeight:"6",orient:"auto-start-reverse",children:t.jsx("path",{d:"M 0 0 L 10 5 L 0 10 z",fill:"#28a745"})}),Te.map(({edge:e,startX:r,startY:s,endX:n,endY:a,isSelected:i})=>t.jsxs("linearGradient",{id:`edge-gradient-${e.id}`,gradientUnits:"userSpaceOnUse",x1:r,y1:s,x2:n,y2:a,children:[t.jsx("stop",{offset:"0%",stopColor:i?"#007bff":"#adb5bd"}),t.jsx("stop",{offset:"100%",stopColor:i?"#0056b3":"#495057"})]},`gradient-${e.id}`))]}),Te.map(({edge:e,pathData:r,markerId:s,midX:n,midY:a,isSelected:i})=>{e.id;const l=g?.edgeId===e.id;return t.jsxs("g",{onClick:u=>{u.stopPropagation(),N("edge",e.id)},onMouseEnter:()=>se(e.id),onMouseLeave:()=>se(null),children:[t.jsx("path",{className:`workflow-edge ${i?"selected":""} ${l?"reconnecting":""}`,d:r,stroke:`url(#edge-gradient-${e.id})`,markerEnd:s}),t.jsx("path",{className:"workflow-edge-interactive",d:r}),e.condition&&t.jsxs("g",{className:"edge-condition-indicator",onClick:u=>{u.stopPropagation(),N("edge",e.id)},style:{cursor:"pointer"},children:[t.jsx("path",{d:`M ${n} ${a-10} L ${n+10} ${a} L ${n} ${a+10} L ${n-10} ${a} Z`,className:`edge-condition-bg ${i?"selected":""}`}),t.jsx("path",{d:`M ${n-4} ${a-3} L ${n} ${a+1} L ${n+4} ${a-3} M ${n} ${a+1} L ${n} ${a+4}`,className:`edge-condition-icon ${i?"selected":""}`,fill:"none",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})]})]},e.id)}),x&&t.jsx("path",{className:"workflow-edge-preview",d:`M ${x.startPos.x},${x.startPos.y} L ${x.endPos.x},${x.endPos.y}`,markerEnd:"url(#arrowhead)"}),g&&t.jsx("path",{className:"workflow-edge-preview workflow-edge-reconnect",d:`M ${g.startPos.x},${g.startPos.y} L ${g.endPos.x},${g.endPos.y}`,markerEnd:g.endpoint==="target"?"url(#arrowhead)":void 0,markerStart:g.endpoint==="source"?"url(#arrowhead)":void 0})]}),x&&!Q&&t.jsxs("div",{className:"workflow-node-preview",style:{left:`${x.endPos.x}px`,top:`${x.endPos.y}px`},children:[t.jsx("div",{className:"workflow-node-preview-header",children:"New Node"}),t.jsxs("div",{className:"workflow-node-preview-body",children:[t.jsx("span",{className:"workflow-node-preview-hint",children:"點擊放置節點"}),t.jsx("span",{className:"workflow-node-preview-esc",children:"ESC 取消"})]})]}),x&&Q&&t.jsxs("div",{className:"workflow-node-preview workflow-node-preview-connect",style:{left:`${x.endPos.x}px`,top:`${x.endPos.y}px`},children:[t.jsx("div",{className:"workflow-node-preview-header",children:"連接節點"}),t.jsxs("div",{className:"workflow-node-preview-body",children:[t.jsx("span",{className:"workflow-node-preview-hint",children:"點擊連接到此節點"}),t.jsx("span",{className:"workflow-node-preview-esc",children:"ESC 取消"})]})]}),c.nodes.map(e=>{const r=C.get(e.type),s=e.parameters&&Object.keys(e.parameters).length>0?Object.entries(e.parameters).filter(([h,w])=>w!=null&&w!=="").map(([h,w])=>{const Pe=typeof w=="string"&&w.length>20?w.substring(0,20)+"...":String(w);return`${h}: ${Pe}`}).slice(0,3):[],n=x&&x.startNodeId!==e.id,a=Q===e.id&&n,i=g?c.edges.find(h=>h.id===g.edgeId):null,l=g&&i?g.endpoint==="target"?i.targetNodeId:i.sourceNodeId:null,u=i?.sourceNodeId,k=u?c.edges.filter(h=>h.sourceNodeId===u).map(h=>h.targetNodeId):[],p=g&&l!==e.id&&u!==e.id&&!k.includes(e.id),I=pe===e.id&&p;return t.jsxs("div",{ref:h=>{h?X.current.set(e.id,h):X.current.delete(e.id)},draggable:!0,onDragStart:h=>o(h,e.id),onMouseEnter:()=>{oe(e.id),x&&x.startNodeId!==e.id&&_e(e.id),p&&fe(e.id)},onMouseLeave:()=>{oe(null),Q===e.id&&_e(null),pe===e.id&&fe(null)},onClick:h=>be(h,e.id),"data-node-id":e.id,className:`workflow-node ${m?.id===e.id?"selected":""} ${x?"node-connecting-target":""} ${a?"node-connecting-hover":""} ${g?"node-connecting-target":""} ${I?"node-connecting-hover":""}`,style:{top:`${e.position.y}px`,left:`${e.position.x}px`},children:[t.jsx("div",{className:"workflow-node-header",children:e.name}),t.jsxs("div",{className:"workflow-node-body",children:[t.jsxs("p",{className:"workflow-node-type",children:["Type: ",r?.label||e.type]}),s.length>0&&t.jsxs("div",{className:"workflow-node-params",children:[s.map((h,w)=>t.jsx("div",{className:"workflow-node-param",children:h},w)),e.parameters&&Object.keys(e.parameters).filter(h=>e.parameters[h]!==void 0&&e.parameters[h]!==null&&e.parameters[h]!=="").length>3&&t.jsx("div",{className:"workflow-node-param workflow-node-param-more",children:"..."})]})]}),Ne===e.id&&e.type!=="end"&&!x&&!g&&t.jsx("div",{className:"node-add-handle-container handle-right",children:t.jsx("div",{className:"node-add-handle",onClick:h=>ke(h,e.id),children:"+"})})]},e.id)}),t.jsx("svg",{className:"workflow-svg-connectors",children:Te.map(({edge:e,startX:r,startY:s,isSelected:n})=>Ne===e.sourceNodeId?null:t.jsx("circle",{cx:r,cy:s,r:4,className:`edge-connector ${n?"selected":""}`,onClick:a=>{a.stopPropagation(),N("edge",e.id)}},e.id))}),t.jsx("svg",{className:"workflow-svg-edge-actions",children:Te.map(({edge:e,midX:r,midY:s,isSelected:n})=>!(we===e.id||n)||g?null:t.jsxs("g",{className:"edge-action-buttons",onMouseEnter:()=>se(e.id),onMouseLeave:()=>se(null),children:[t.jsx("rect",{x:r-38,y:s-18,width:76,height:36,rx:18,ry:18,className:"edge-action-container-bg"}),t.jsxs("g",{className:"edge-action-btn edge-action-edit",onClick:i=>{i.stopPropagation(),N("edge",e.id)},style:{cursor:"pointer"},children:[t.jsx("circle",{cx:r-16,cy:s,r:12,className:"edge-action-bg"}),t.jsx("path",{d:`M ${r-20} ${s+2} L ${r-14} ${s-4} L ${r-12} ${s-2} L ${r-18} ${s+4} Z`,className:"edge-action-icon",fill:"#fff"})]}),t.jsxs("g",{className:"edge-action-btn edge-action-reconnect",onClick:i=>E(i,e.id,"target"),style:{cursor:"pointer"},children:[t.jsx("circle",{cx:r+16,cy:s,r:12,className:"edge-action-bg"}),t.jsx("path",{d:`M ${r+11} ${s} L ${r+21} ${s} M ${r+18} ${s-3} L ${r+21} ${s} L ${r+18} ${s+3}`,className:"edge-action-icon",fill:"none",stroke:"#fff",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})]})]},e.id))}),at()]})})})});te.WorkflowEditor=qe,Object.defineProperty(te,Symbol.toStringTag,{value:"Module"})}));
1
+ (function(A,t){typeof exports=="object"&&typeof module<"u"?t(exports,require("react")):typeof define=="function"&&define.amd?define(["exports","react"],t):(A=typeof globalThis<"u"?globalThis:A||self,t(A.BoleClickwizardDesigner={},A.React))})(this,function(A,t){"use strict";const Me=t.forwardRef(({initialWorkflow:se,onChange:$,className:xe,nodeTypeConfigs:S=[]},$e)=>{const le=t.useMemo(()=>{const e=new Map;return S.forEach(n=>{e.set(n.type,n)}),e},[S]),[i,R]=t.useState(se),[d,L]=t.useState(null),[f,W]=t.useState(null),[ue,pe]=t.useState(null),[me,K]=t.useState(null),[ee,fe]=t.useState(null),[_,te]=t.useState(null),[ae,ge]=t.useState(!1),[G,U]=t.useState(null),[q,He]=t.useState(new Map),[p,O]=t.useState(null),[Ee,ie]=t.useState(null),z=t.useRef(null),B=t.useRef(null),E=t.useRef(null),Ne=t.useRef(null),Y=t.useRef(new Map);t.useEffect(()=>{R(se)},[se]);const H=e=>{R(e),$==null||$(e)};t.useEffect(()=>{const e=()=>{const o=new Map;Y.current.forEach((s,l)=>{s&&o.set(l,s.offsetHeight)});let r=!1;o.forEach((s,l)=>{q.get(l)!==s&&(r=!0)}),(r||o.size!==q.size)&&He(o)};e();const n=new ResizeObserver(()=>{e()});return Y.current.forEach(o=>{o&&n.observe(o)}),()=>{n.disconnect()}},[i.nodes]),t.useImperativeHandle($e,()=>({getWorkflow:()=>i,setWorkflow:e=>{H(e),L(null)}}));const ce=t.useCallback(()=>{if(!d)return;let e=[...i.nodes],n=[...i.edges];if(d.type==="node"){const o=i.nodes.find(r=>r.id===d.id);if((o==null?void 0:o.type)==="start"||(o==null?void 0:o.type)==="end")return;e=i.nodes.filter(r=>r.id!==d.id),n=i.edges.filter(r=>r.sourceNodeId!==d.id&&r.targetNodeId!==d.id)}else n=i.edges.filter(o=>o.id!==d.id);L(null),H({nodes:e,edges:n})},[d,i,H]);t.useEffect(()=>{const e=n=>{const o=n.target,r=o.tagName==="INPUT"||o.tagName==="TEXTAREA"||o.tagName==="SELECT"||o.isContentEditable;if(n.key==="Escape"){if(p){O(null),ie(null);return}if(f){W(null);return}if(d){G&&(R(G),$==null||$(G)),L(null),te(null),U(null);return}}d&&(n.key==="Delete"||n.key==="Backspace")&&!r&&ce()};return document.addEventListener("keydown",e),()=>{document.removeEventListener("keydown",e)}},[d,ce,G,$,f,p]);const be=(e,n)=>{const r=e.target.closest(".workflow-node").getBoundingClientRect();z.current={nodeId:n,offset:{x:e.clientX-r.left,y:e.clientY-r.top}},e.dataTransfer.effectAllowed="move"},Pe=e=>{e.preventDefault()},_e=e=>{if(e.preventDefault(),!z.current||!E.current)return;const n=E.current.getBoundingClientRect(),o={x:e.clientX-n.left+E.current.scrollLeft-z.current.offset.x,y:e.clientY-n.top+E.current.scrollTop-z.current.offset.y},r=i.nodes.map(s=>{var l;return s.id===((l=z.current)==null?void 0:l.nodeId)?{...s,position:{x:Math.max(0,o.x),y:Math.max(0,o.y)}}:s});H({...i,nodes:r}),z.current=null},Z=(e,n)=>{U(JSON.parse(JSON.stringify(i))),L({type:e,id:n})},F=(e,n)=>{if(d){if(d.type==="node"){const o=i.nodes.map(r=>{if(r.id===d.id){if(e==="type"){const l=le.get(n),a=l!=null&&l.defaultParameters?{...l.defaultParameters}:{};return{...r,type:n,parameters:a}}if(e in r&&e!=="parameters")return{...r,[e]:n};const s={...r.parameters||{},[e]:n};return{...r,parameters:s}}return r});H({...i,nodes:o})}else if(d.type==="edge"){const o=i.edges.map(r=>r.id===d.id?{...r,[e]:n}:r);H({...i,edges:o})}}},Oe=(e,n)=>{if(e.stopPropagation(),!E.current)return;const o=E.current.getBoundingClientRect(),r=i.nodes.find(c=>c.id===n);if(!r)return;const s=Y.current.get(n),l=s?s.offsetHeight:80,a={x:r.position.x+200,y:r.position.y+l/2};W({startNodeId:n,startPos:a,endPos:{x:e.clientX-o.left+E.current.scrollLeft,y:e.clientY-o.top+E.current.scrollTop}})},Ce=(e,n,o)=>{if(e.stopPropagation(),!E.current)return;const r=i.edges.find(g=>g.id===n);if(!r)return;const s=E.current.getBoundingClientRect(),l=r.sourceNodeId,a=r.targetNodeId,c=i.nodes.find(g=>g.id===l),h=i.nodes.find(g=>g.id===a);if(!c||!h)return;const u=Y.current.get(l),y=u?u.offsetHeight:80,m={x:c.position.x+200,y:c.position.y+y/2};O({edgeId:n,endpoint:o,startPos:m,endPos:{x:e.clientX-s.left+E.current.scrollLeft,y:e.clientY-s.top+E.current.scrollTop}}),K(null)},Te=e=>{if(!E.current)return;if(p){e.preventDefault();const o=E.current.getBoundingClientRect();O({...p,endPos:{x:e.clientX-o.left+E.current.scrollLeft,y:e.clientY-o.top+E.current.scrollTop}});return}if(!f)return;e.preventDefault();const n=E.current.getBoundingClientRect();W({...f,endPos:{x:e.clientX-n.left+E.current.scrollLeft,y:e.clientY-n.top+E.current.scrollTop}})},Se=(e,n)=>{if(e.stopPropagation(),p){const s=i.edges.find(u=>u.id===p.edgeId);if(!s){O(null);return}if(p.endpoint==="source"&&n===s.targetNodeId){O(null);return}if(p.endpoint==="target"&&n===s.sourceNodeId){O(null);return}const l=p.endpoint==="source"?n:s.sourceNodeId,a=p.endpoint==="target"?n:s.targetNodeId;if(i.edges.some(u=>u.id!==s.id&&u.sourceNodeId===l&&u.targetNodeId===a)){O(null);return}const h=i.edges.map(u=>u.id===p.edgeId?{...u,sourceNodeId:l,targetNodeId:a}:u);H({...i,edges:h}),O(null);return}if(!f){Z("node",n);return}if(f.startNodeId===n){W(null);return}const o={id:`edge_${Date.now()}`,sourceNodeId:f.startNodeId,targetNodeId:n};if(i.edges.some(s=>s.sourceNodeId===o.sourceNodeId&&s.targetNodeId===o.targetNodeId)){W(null);return}H({...i,edges:[...i.edges,o]}),W(null)},Le=e=>{if(p){O(null);return}if(f&&E.current){const n=E.current.getBoundingClientRect(),o=e.clientX-n.left+E.current.scrollLeft,r=e.clientY-n.top+E.current.scrollTop;U(JSON.parse(JSON.stringify(i)));const s=`node_${Date.now()}`,l=S.length>0?S[0].type:"task",a=S.length>0?S[0]:null,c=a!=null&&a.defaultParameters?{...a.defaultParameters}:{},h={id:s,name:"New Node",type:l,position:{x:Math.max(0,o-200/2),y:Math.max(0,r-80/2)},parameters:c},u={id:`edge_${Date.now()}`,sourceNodeId:f.startNodeId,targetNodeId:s},y={nodes:[...i.nodes,h],edges:[...i.edges,u]};H(y),W(null),L({type:"node",id:s});return}L(null)},Ae=e=>{var o;if(e.type==="start")return null;if(e.type==="end")return t.createElement("div",{className:"form-group",style:{display:"flex",alignItems:"center",gap:"8px",cursor:"pointer"}},t.createElement("input",{type:"checkbox",id:"end-autoclose",checked:!!((o=e.parameters)!=null&&o.autoCloseTab),onChange:r=>F("autoCloseTab",r.target.checked)}),t.createElement("label",{htmlFor:"end-autoclose",style:{margin:0,cursor:"pointer"}},"自動關閉 Tab"));const n=le.get(e.type);if((e.type==="goto"||e.type==="click")&&e.parameters){const r=e.parameters.dialogMode||"autoAccept";return t.createElement("div",null,t.createElement("div",{className:"form-group"},t.createElement("label",null,"Dialog 處理"),t.createElement("select",{value:r,onChange:s=>F("dialogMode",s.target.value)},t.createElement("option",{value:"autoAccept"},"autoAccept(自動接受 confirm,並關閉 alert)"),t.createElement("option",{value:"autoDismiss"},"autoDismiss(自動取消 confirm)"),t.createElement("option",{value:"reportOnly"},"reportOnly(僅回報)"))),n!=null&&n.renderProperties?n.renderProperties(e.parameters,F):null)}return n!=null&&n.renderProperties&&e.parameters?n.renderProperties(e.parameters,F):null},V=(e,n)=>{if(!d||d.type!=="edge")return;const o=i.edges.find(l=>l.id===d.id);if(!o)return;let r=o.condition?{...o.condition}:{type:"none"};if(e==="type")n==="none"?r=void 0:(r={type:n},n==="compare"&&(r.left={source:"variable",name:""},r.operator="==",r.right={source:"literal",value:""}));else if(r){if(e==="operator")r.operator=n;else if(e==="expression")r.expression=n;else if(e.startsWith("left.")){const l=e.substring(5);(!r.left||typeof r.left!="object")&&(r.left={source:"variable",name:""}),l==="source"?r.left={source:n}:r.left[l]=n}else if(e.startsWith("right.")){const l=e.substring(6);(!r.right||typeof r.right!="object")&&(r.right={source:"literal",value:""}),l==="source"?r.right={source:n}:r.right[l]=n}}const s=i.edges.map(l=>l.id===d.id?{...l,condition:r}:l);H({...i,edges:s})},We=t.useCallback(e=>{const n=[],o=e?i.edges.find(a=>a.id===e):null,r=o==null?void 0:o.sourceNodeId,s=new Set,l=new Set;if(r){const a=i.nodes.find(c=>c.type==="start");if(a){a.id;const c=new Map;i.edges.forEach(u=>{c.has(u.targetNodeId)||c.set(u.targetNodeId,new Set),c.get(u.targetNodeId).add(u.sourceNodeId)});const h=u=>{if(s.has(u))return;s.add(u),l.add(u);const y=c.get(u);y&&y.forEach(m=>h(m))};h(r)}}else i.nodes.forEach(a=>l.add(a.id));return i.nodes.forEach(a=>{if(l.has(a.id)&&a.parameters){const c=a.parameters.outputVariable;c&&typeof c=="string"&&c.trim()!==""&&n.push(c.trim())}}),[...new Set(n)].sort()},[i]),he=(e,n,o,r)=>{const s=(n==null?void 0:n.source)||"literal",l=We(r);return t.createElement("div",{className:"condition-value-group"},t.createElement("label",null,o),t.createElement("div",{className:"condition-value-row"},t.createElement("select",{value:s,onChange:a=>V(`${e}.source`,a.target.value),className:"condition-source-select"},t.createElement("option",{value:"literal"},"固定值"),t.createElement("option",{value:"variable"},"變數"),t.createElement("option",{value:"result"},"節點結果")),s==="literal"&&t.createElement("input",{type:"text",value:(n==null?void 0:n.value)??"",onChange:a=>V(`${e}.value`,a.target.value),placeholder:"輸入值",className:"condition-value-input"}),s==="variable"&&t.createElement(t.Fragment,null,t.createElement("input",{type:"text",list:`${e}-variable-list`,value:(n==null?void 0:n.name)??"",onChange:a=>V(`${e}.name`,a.target.value),placeholder:l.length>0?"輸入或選擇變數...":"輸入變數名稱",className:"condition-value-input"}),l.length>0&&t.createElement("datalist",{id:`${e}-variable-list`},l.map(a=>t.createElement("option",{key:a,value:a})))),s==="result"&&t.createElement("input",{type:"text",value:(n==null?void 0:n.path)??"",onChange:a=>V(`${e}.path`,a.target.value),placeholder:"結果路徑 (如: data.value)",className:"condition-value-input"})))},Ge=e=>{const n=e.condition,o=(n==null?void 0:n.type)||"none";return t.createElement("div",{className:"edge-condition-editor"},t.createElement("div",{className:"form-group"},t.createElement("label",null,"條件類型"),t.createElement("select",{value:o,onChange:r=>V("type",r.target.value)},t.createElement("option",{value:"none"},"無條件(總是執行)"),t.createElement("option",{value:"success"},"成功時執行"),t.createElement("option",{value:"failure"},"失敗時執行"),t.createElement("option",{value:"compare"},"比較條件"),t.createElement("option",{value:"expression"},"自訂表達式"),t.createElement("option",{value:"else"},"其他條件皆不成立時 (Else)"))),o==="compare"&&t.createElement("div",{className:"compare-condition-editor"},he("left",n==null?void 0:n.left,"左值",e.id),t.createElement("div",{className:"form-group"},t.createElement("label",null,"運算子"),t.createElement("select",{value:(n==null?void 0:n.operator)||"==",onChange:r=>V("operator",r.target.value)},t.createElement("option",{value:"=="},"等於 (==)"),t.createElement("option",{value:"==="},"嚴格等於 (===)"),t.createElement("option",{value:"!="},"不等於 (!=)"),t.createElement("option",{value:"!=="},"嚴格不等於 (!==)"),t.createElement("option",{value:">"},"大於 (>)"),t.createElement("option",{value:">="},"大於等於 (>=)"),t.createElement("option",{value:"<"},"小於 (<)"),t.createElement("option",{value:"<="},"小於等於 (<=)"),t.createElement("option",{value:"contains"},"包含"),t.createElement("option",{value:"startsWith"},"開頭是"),t.createElement("option",{value:"endsWith"},"結尾是"),t.createElement("option",{value:"matches"},"正則匹配"))),he("right",n==null?void 0:n.right,"右值",e.id)),o==="expression"&&t.createElement("div",{className:"form-group"},t.createElement("label",null,"表達式"),t.createElement("textarea",{value:(n==null?void 0:n.expression)||"",onChange:r=>V("expression",r.target.value),placeholder:"例如: result.success && variables.count > 0",rows:3}),t.createElement("small",{className:"form-hint"},"可用變數: result (節點結果), context (執行上下文), variables (工作流程變數)")))},Be=()=>{G&&(R(G),$==null||$(G)),L(null),te(null),U(null)},Ve=()=>{L(null),te(null),U(null)},je=e=>{if(e.target.closest("input, select, textarea, button"))return;e.preventDefault(),ge(!0);const n=Ne.current;if(!n)return;const o=n.getBoundingClientRect(),r=(_==null?void 0:_.x)??o.left,s=(_==null?void 0:_.y)??o.top;B.current={startX:e.clientX,startY:e.clientY,startPosX:r,startPosY:s}};t.useEffect(()=>{if(!ae)return;const e=o=>{if(!B.current)return;const r=o.clientX-B.current.startX,s=o.clientY-B.current.startY;te({x:B.current.startPosX+r,y:B.current.startPosY+s})},n=()=>{ge(!1),B.current=null};return document.addEventListener("mousemove",e),document.addEventListener("mouseup",n),()=>{document.removeEventListener("mousemove",e),document.removeEventListener("mouseup",n)}},[ae]);const ze=()=>{if(!d)return null;let e,n=d.type==="node";if(n?e=i.nodes.find(r=>r.id===d.id):e=i.edges.find(r=>r.id===d.id),!e)return null;S.map(r=>r.type);const o=_?{position:"fixed",left:_.x,top:_.y,transform:"none"}:{};return t.createElement("div",{className:"properties-popup-overlay",onClick:r=>r.stopPropagation()},t.createElement("div",{ref:Ne,className:`properties-popup ${ae?"dragging":""}`,style:o},t.createElement("div",{className:"properties-popup-header",onMouseDown:je},t.createElement("h4",null,"Edit: ",n?e.name:"Edge"),t.createElement("button",{className:"properties-popup-close",onClick:Be},"×")),t.createElement("div",{className:"properties-popup-content"},t.createElement("div",{className:"form-group"},t.createElement("label",null,"ID"),t.createElement("input",{type:"text",readOnly:!0,value:e.id})),n&&e.type!=="start"&&e.type!=="end"&&t.createElement(t.Fragment,null,t.createElement("div",{className:"form-group"},t.createElement("label",null,"Name"),t.createElement("input",{type:"text",value:e.name,onChange:r=>F("name",r.target.value)})),t.createElement("div",{className:"form-group"},t.createElement("label",null,"Type"),t.createElement("select",{value:e.type,onChange:r=>F("type",r.target.value)},S.map(r=>t.createElement("option",{key:r.type,value:r.type},r.label||r.type))))),n&&Ae(e),!n&&Ge(e)),t.createElement("div",{className:"properties-popup-footer"},(n&&e.type!=="start"&&e.type!=="end"||!n)&&t.createElement("button",{className:"btn-danger",onClick:ce},"Delete"),t.createElement("button",{className:"btn-primary",onClick:Ve},"OK"))))},we=new Map(i.nodes.map(e=>[e.id,e])),ve=e=>{const n=q.get(e.id);if(n&&n>0)return n;if(!e.parameters||Object.keys(e.parameters).length===0)return 80;const o=Object.entries(e.parameters).filter(([u,y])=>y!=null&&y!=="");if(o.length===0)return 80;const r=Math.min(o.length,3),s=o.length>3,l=r+(s?1:0),a=63,c=9+l*14,h=a+c;return Math.max(80,h)},ye=(e,n,o,r,s,l,a,c,h,u,y,m,g=10)=>{const j=h-5,C=u-5,M=y+5*2,I=m+5*2;for(let X=1;X<g;X++){const k=X/g,w=Math.pow(1-k,3)*e+3*Math.pow(1-k,2)*k*o+3*(1-k)*Math.pow(k,2)*s+Math.pow(k,3)*a,N=Math.pow(1-k,3)*n+3*Math.pow(1-k,2)*k*r+3*(1-k)*Math.pow(k,2)*l+Math.pow(k,3)*c;if(w>=j&&w<=j+M&&N>=C&&N<=C+I)return!0}return!1},ne=(()=>{const e=new Map,n=new Map;return i.edges.forEach(o=>{const r=[o.sourceNodeId,o.targetNodeId].sort().join("-");e.set(r,(e.get(r)||0)+1)}),i.edges.map(o=>{const r=we.get(o.sourceNodeId),s=we.get(o.targetNodeId);if(!r||!s)return null;const l=ve(r),a=ve(s),c=[o.sourceNodeId,o.targetNodeId].sort().join("-"),h=e.get(c)||1,u=n.get(c)||0;n.set(c,u+1);const g=(u-(h-1)/2)*15,Q=r.position.y+l/2,j=s.position.x+200/2,C=s.position.y+a/2,M=r.position.x+200,I=Q+g,X=j-M,k=C-I;let w,N,x;Math.abs(X)>Math.abs(k)?X>0?(w=s.position.x,N=C+g,x="left"):(w=s.position.x+200,N=C+g,x="right"):k>0?(w=j+g,N=s.position.y,x="top"):(w=j+g,N=s.position.y+a,x="bottom");const ke=j-(r.position.x+200/2),De=C-Q,Ye=Math.sqrt(ke*ke+De*De);let b=Math.max(40,Ye*.3),J=M+b,P=I,T,v;x==="left"?(T=w-b,v=N):x==="right"?(T=w+b,v=N):x==="top"?(T=w,v=N-b):(T=w,v=N+b);let de=ye(M,I,J,P,T,v,w,N,s.position.x,s.position.y,200,a);if(de){const re=a+30;if(x==="right"?(C<=I?(P=I+re,v=N+re):(P=I-re,v=N-re),J=M+b*1.5,T=w+b*1.5):(x==="top"||x==="bottom")&&(J=M+b*1.5,x==="top"?v=N-b*1.5:v=N+b*1.5),de=ye(M,I,J,P,T,v,w,N,s.position.x,s.position.y,200,a),de){const oe=a+60;C<=I?(P=Math.max(P,I+oe),v=Math.max(v,N+oe)):(P=Math.min(P,I-oe),v=Math.min(v,N-oe))}}const Fe=`M ${M},${I} C ${J},${P} ${T},${v} ${w},${N}`,Xe=(d==null?void 0:d.id)===o.id?"url(#arrowhead-selected)":"url(#arrowhead)",D=.5,Je=Math.pow(1-D,3)*M+3*Math.pow(1-D,2)*D*J+3*(1-D)*Math.pow(D,2)*T+Math.pow(D,3)*w,Ke=Math.pow(1-D,3)*I+3*Math.pow(1-D,2)*D*P+3*(1-D)*Math.pow(D,2)*v+Math.pow(D,3)*N;return{edge:o,pathData:Fe,markerId:Xe,startX:M,startY:I,endX:w,endY:N,midX:Je,midY:Ke,isSelected:(d==null?void 0:d.id)===o.id}}).filter(Boolean)})(),Ie=t.useMemo(()=>{let r=800,s=600;return i.nodes.forEach(l=>{const a=q.get(l.id)||80,c=l.position.x+200+100,h=l.position.y+a+100;c>r&&(r=c),h>s&&(s=h)}),{width:r,height:s}},[i.nodes,q]);return t.createElement("div",{className:`workflow-editor-container ${xe||""}`},t.createElement("div",{className:"workflow-body"},t.createElement("div",{ref:E,className:"workflow-canvas",onDragOver:Pe,onDrop:_e,onMouseMove:Te,onClick:Le},t.createElement("div",{className:"workflow-canvas-content",style:{width:`${Ie.width}px`,height:`${Ie.height}px`}}),t.createElement("svg",{className:"workflow-svg-layer"},t.createElement("defs",null,t.createElement("marker",{id:"arrowhead",viewBox:"0 0 10 10",refX:"8",refY:"5",markerWidth:"6",markerHeight:"6",orient:"auto-start-reverse"},t.createElement("path",{d:"M 0 0 L 10 5 L 0 10 z",fill:"#495057"})),t.createElement("marker",{id:"arrowhead-selected",viewBox:"0 0 10 10",refX:"8",refY:"5",markerWidth:"6",markerHeight:"6",orient:"auto-start-reverse"},t.createElement("path",{d:"M 0 0 L 10 5 L 0 10 z",fill:"#007bff"})),t.createElement("marker",{id:"arrowhead-active",viewBox:"0 0 10 10",refX:"8",refY:"5",markerWidth:"6",markerHeight:"6",orient:"auto-start-reverse"},t.createElement("path",{d:"M 0 0 L 10 5 L 0 10 z",fill:"#28a745"})),ne.map(({edge:e,startX:n,startY:o,endX:r,endY:s,isSelected:l})=>t.createElement("linearGradient",{key:`gradient-${e.id}`,id:`edge-gradient-${e.id}`,gradientUnits:"userSpaceOnUse",x1:n,y1:o,x2:r,y2:s},t.createElement("stop",{offset:"0%",stopColor:l?"#007bff":"#adb5bd"}),t.createElement("stop",{offset:"100%",stopColor:l?"#0056b3":"#495057"})))),ne.map(({edge:e,pathData:n,markerId:o,midX:r,midY:s,isSelected:l})=>{e.id;const a=(p==null?void 0:p.edgeId)===e.id;return t.createElement("g",{key:e.id,onClick:c=>{c.stopPropagation(),Z("edge",e.id)},onMouseEnter:()=>K(e.id),onMouseLeave:()=>K(null)},t.createElement("path",{className:`workflow-edge ${l?"selected":""} ${a?"reconnecting":""}`,d:n,stroke:`url(#edge-gradient-${e.id})`,markerEnd:o}),t.createElement("path",{className:"workflow-edge-interactive",d:n}),e.condition&&t.createElement("g",{className:"edge-condition-indicator",onClick:c=>{c.stopPropagation(),Z("edge",e.id)},style:{cursor:"pointer"}},t.createElement("path",{d:`M ${r} ${s-10} L ${r+10} ${s} L ${r} ${s+10} L ${r-10} ${s} Z`,className:`edge-condition-bg ${l?"selected":""}`}),t.createElement("path",{d:`M ${r-4} ${s-3} L ${r} ${s+1} L ${r+4} ${s-3} M ${r} ${s+1} L ${r} ${s+4}`,className:`edge-condition-icon ${l?"selected":""}`,fill:"none",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})))}),f&&t.createElement("path",{className:"workflow-edge-preview",d:`M ${f.startPos.x},${f.startPos.y} L ${f.endPos.x},${f.endPos.y}`,markerEnd:"url(#arrowhead)"}),p&&t.createElement("path",{className:"workflow-edge-preview workflow-edge-reconnect",d:`M ${p.startPos.x},${p.startPos.y} L ${p.endPos.x},${p.endPos.y}`,markerEnd:p.endpoint==="target"?"url(#arrowhead)":void 0,markerStart:p.endpoint==="source"?"url(#arrowhead)":void 0})),f&&!ee&&t.createElement("div",{className:"workflow-node-preview",style:{left:`${f.endPos.x}px`,top:`${f.endPos.y}px`}},t.createElement("div",{className:"workflow-node-preview-header"},"New Node"),t.createElement("div",{className:"workflow-node-preview-body"},t.createElement("span",{className:"workflow-node-preview-hint"},"點擊放置節點"),t.createElement("span",{className:"workflow-node-preview-esc"},"ESC 取消"))),f&&ee&&t.createElement("div",{className:"workflow-node-preview workflow-node-preview-connect",style:{left:`${f.endPos.x}px`,top:`${f.endPos.y}px`}},t.createElement("div",{className:"workflow-node-preview-header"},"連接節點"),t.createElement("div",{className:"workflow-node-preview-body"},t.createElement("span",{className:"workflow-node-preview-hint"},"點擊連接到此節點"),t.createElement("span",{className:"workflow-node-preview-esc"},"ESC 取消"))),i.nodes.map(e=>{const n=le.get(e.type),o=e.parameters&&Object.keys(e.parameters).length>0?Object.entries(e.parameters).filter(([m,g])=>g!=null&&g!=="").map(([m,g])=>{const Q=typeof g=="string"&&g.length>20?g.substring(0,20)+"...":String(g);return`${m}: ${Q}`}).slice(0,3):[],r=f&&f.startNodeId!==e.id,s=ee===e.id&&r,l=p?i.edges.find(m=>m.id===p.edgeId):null,a=p&&l?p.endpoint==="target"?l.targetNodeId:l.sourceNodeId:null,c=l==null?void 0:l.sourceNodeId,h=c?i.edges.filter(m=>m.sourceNodeId===c).map(m=>m.targetNodeId):[],u=p&&a!==e.id&&c!==e.id&&!h.includes(e.id),y=Ee===e.id&&u;return t.createElement("div",{key:e.id,ref:m=>{m?Y.current.set(e.id,m):Y.current.delete(e.id)},draggable:!0,onDragStart:m=>be(m,e.id),onMouseEnter:()=>{pe(e.id),f&&f.startNodeId!==e.id&&fe(e.id),u&&ie(e.id)},onMouseLeave:()=>{pe(null),ee===e.id&&fe(null),Ee===e.id&&ie(null)},onClick:m=>Se(m,e.id),"data-node-id":e.id,className:`workflow-node ${(d==null?void 0:d.id)===e.id?"selected":""} ${f?"node-connecting-target":""} ${s?"node-connecting-hover":""} ${p?"node-connecting-target":""} ${y?"node-connecting-hover":""}`,style:{top:`${e.position.y}px`,left:`${e.position.x}px`}},t.createElement("div",{className:"workflow-node-header"},e.name),t.createElement("div",{className:"workflow-node-body"},t.createElement("p",{className:"workflow-node-type"},"Type: ",(n==null?void 0:n.label)||e.type),o.length>0&&t.createElement("div",{className:"workflow-node-params"},o.map((m,g)=>t.createElement("div",{key:g,className:"workflow-node-param"},m)),e.parameters&&Object.keys(e.parameters).filter(m=>e.parameters[m]!==void 0&&e.parameters[m]!==null&&e.parameters[m]!=="").length>3&&t.createElement("div",{className:"workflow-node-param workflow-node-param-more"},"..."))),ue===e.id&&e.type!=="end"&&!f&&!p&&t.createElement("div",{className:"node-add-handle-container handle-right"},t.createElement("div",{className:"node-add-handle",onClick:m=>Oe(m,e.id)},"+")))}),t.createElement("svg",{className:"workflow-svg-connectors"},ne.map(({edge:e,startX:n,startY:o,isSelected:r})=>ue===e.sourceNodeId?null:t.createElement("circle",{key:e.id,cx:n,cy:o,r:4,className:`edge-connector ${r?"selected":""}`,onClick:s=>{s.stopPropagation(),Z("edge",e.id)}}))),t.createElement("svg",{className:"workflow-svg-edge-actions"},ne.map(({edge:e,midX:n,midY:o,isSelected:r})=>!(me===e.id||r)||p?null:t.createElement("g",{key:e.id,className:"edge-action-buttons",onMouseEnter:()=>K(e.id),onMouseLeave:()=>K(null)},t.createElement("rect",{x:n-38,y:o-18,width:76,height:36,rx:18,ry:18,className:"edge-action-container-bg"}),t.createElement("g",{className:"edge-action-btn edge-action-edit",onClick:l=>{l.stopPropagation(),Z("edge",e.id)},style:{cursor:"pointer"}},t.createElement("circle",{cx:n-16,cy:o,r:12,className:"edge-action-bg"}),t.createElement("path",{d:`M ${n-20} ${o+2} L ${n-14} ${o-4} L ${n-12} ${o-2} L ${n-18} ${o+4} Z`,className:"edge-action-icon",fill:"#fff"})),t.createElement("g",{className:"edge-action-btn edge-action-reconnect",onClick:l=>Ce(l,e.id,"target"),style:{cursor:"pointer"}},t.createElement("circle",{cx:n+16,cy:o,r:12,className:"edge-action-bg"}),t.createElement("path",{d:`M ${n+11} ${o} L ${n+21} ${o} M ${n+18} ${o-3} L ${n+21} ${o} L ${n+18} ${o+3}`,className:"edge-action-icon",fill:"none",stroke:"#fff",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"}))))),ze())))});A.WorkflowEditor=Me,Object.defineProperty(A,Symbol.toStringTag,{value:"Module"})});