1- import React , { useState , useRef , useEffect } from 'react' ;
1+ import React , { useState , useRef , useEffect , useCallback } from 'react' ;
22
33import { debounce } from 'min-dash' ;
44
@@ -27,7 +27,7 @@ function App() {
2727
2828 const [ modeler , setModeler ] = useState ( null ) ;
2929
30- const [ isConnectionConfigured , setIsConnectionConfigured ] = useState ( false ) ;
30+ const [ isConnectionConfigured , setIsConnectionConfigured ] = useState ( true ) ;
3131
3232 const [ config , setConfig ] = useState ( undefined ) ;
3333
@@ -66,18 +66,18 @@ function App() {
6666 const deploy = async ( ) => {
6767 const { xml } = await modeler . saveXML ( ) ;
6868
69- const payload = { xml } ;
69+ const resources = [ { name : 'diagram.bpmn' , content : xml } ] ;
7070
7171 if ( form ) {
72- payload . form = form ;
72+ resources . push ( { name : ' form.form' , content : form } ) ;
7373 }
7474
7575 const response = await fetch ( '/api/deploy' , {
7676 method : 'POST' ,
7777 headers : {
7878 'Content-Type' : 'application/json'
7979 } ,
80- body : JSON . stringify ( payload )
80+ body : JSON . stringify ( { resources } )
8181 } ) ;
8282
8383 return await response . json ( ) ;
@@ -119,17 +119,37 @@ function App() {
119119 . then ( response => response . json ( ) ) ;
120120 } ;
121121
122+ const searchJobs = async ( processInstanceKey , elementId ) => {
123+ return fetch ( `/api/searchJobs/${ processInstanceKey } ?elementId=${ elementId } ` )
124+ . then ( response => response . json ( ) ) ;
125+ } ;
126+
127+ const searchUserTasks = async ( processInstanceKey , elementId ) => {
128+ return fetch ( `/api/searchUserTasks/${ processInstanceKey } ?elementId=${ elementId } ` )
129+ . then ( response => response . json ( ) ) ;
130+ } ;
131+
132+ const searchMessageSubscriptions = async ( processInstanceKey , elementId ) => {
133+ return fetch ( `/api/searchMessageSubscriptions/${ processInstanceKey } ?elementId=${ elementId } ` )
134+ . then ( response => response . json ( ) ) ;
135+ } ;
136+
122137 const { current : onConfigChanged } = useRef ( debounce ( config => setConfig ( config ) , 300 ) ) ;
123138
124139 // eslint-disable-next-line no-undef
125140 const operateURL = process . env . CAMUNDA_OPERATE_BASE_URL ;
126141
142+ // eslint-disable-next-line no-undef
143+ const tasklistURL = process . env . CAMUNDA_TASKLIST_BASE_URL ;
144+
127145 return (
128146 < >
129147 < div className = "modeler" ref = { modelerRef } >
130148 < div id = "canvas" className = "canvas" > </ div >
131- < div id = "properties" className = "properties-panel" > </ div >
132- < div className = "task-testing" >
149+ < ResizablePanel className = "properties-panel" defaultWidth = { 300 } minWidth = { 200 } maxWidth = { 600 } >
150+ < div id = "properties" style = { { width : '100%' , height : '100%' } } > </ div >
151+ </ ResizablePanel >
152+ < ResizablePanel className = "task-testing" defaultWidth = { 500 } minWidth = { 300 } maxWidth = { 800 } >
133153 < TestTab
134154 injector = { injector }
135155 isConnectionConfigured = { isConnectionConfigured }
@@ -160,11 +180,15 @@ function App() {
160180 getProcessInstance,
161181 getProcessInstanceVariables,
162182 getProcessInstanceElementInstances,
163- getProcessInstanceIncident
183+ getProcessInstanceIncident,
184+ searchJobs,
185+ searchUserTasks,
186+ searchMessageSubscriptions
164187 } }
165188 config = { config }
166189 onConfigChanged = { onConfigChanged }
167190 operateBaseUrl = { operateURL }
191+ tasklistBaseUrl = { tasklistURL }
168192 documentationUrl = "https://docs.camunda.io/"
169193 onTaskExecutionStarted = { ( element ) => {
170194 console . log ( 'Task execution started:' , element . id ) ;
@@ -173,7 +197,7 @@ function App() {
173197 console . log ( 'Task execution finished:' , element . id , result . success ? 'success' : result . reason , result ) ;
174198 } }
175199 />
176- </ div >
200+ </ ResizablePanel >
177201 </ div >
178202 </ >
179203 ) ;
@@ -196,4 +220,52 @@ function TestTab(props) {
196220 </ TaskTesting > ;
197221}
198222
223+ function ResizablePanel ( { children, className, defaultWidth, minWidth, maxWidth } ) {
224+ const [ width , setWidth ] = useState ( defaultWidth ) ;
225+ const isDragging = useRef ( false ) ;
226+ const startX = useRef ( 0 ) ;
227+ const startWidth = useRef ( 0 ) ;
228+
229+ const onMouseDown = useCallback ( ( e ) => {
230+ isDragging . current = true ;
231+ startX . current = e . clientX ;
232+ startWidth . current = width ;
233+ document . body . style . cursor = 'col-resize' ;
234+ document . body . style . userSelect = 'none' ;
235+ e . preventDefault ( ) ;
236+ } , [ width ] ) ;
237+
238+ useEffect ( ( ) => {
239+ const onMouseMove = ( e ) => {
240+ if ( ! isDragging . current ) return ;
241+ const delta = startX . current - e . clientX ;
242+ const newWidth = Math . min ( maxWidth , Math . max ( minWidth , startWidth . current + delta ) ) ;
243+ setWidth ( newWidth ) ;
244+ } ;
245+
246+ const onMouseUp = ( ) => {
247+ if ( isDragging . current ) {
248+ isDragging . current = false ;
249+ document . body . style . cursor = '' ;
250+ document . body . style . userSelect = '' ;
251+ }
252+ } ;
253+
254+ document . addEventListener ( 'mousemove' , onMouseMove ) ;
255+ document . addEventListener ( 'mouseup' , onMouseUp ) ;
256+
257+ return ( ) => {
258+ document . removeEventListener ( 'mousemove' , onMouseMove ) ;
259+ document . removeEventListener ( 'mouseup' , onMouseUp ) ;
260+ } ;
261+ } , [ minWidth , maxWidth ] ) ;
262+
263+ return (
264+ < div className = { className } style = { { width : `${ width } px` } } >
265+ < div className = "resize-handle" onMouseDown = { onMouseDown } />
266+ { children }
267+ </ div >
268+ ) ;
269+ }
270+
199271export default App ;
0 commit comments