@@ -8,17 +8,56 @@ Joomla = window.Joomla || {};
88 async function makeRequest ( url ) {
99 try {
1010 const paths = Joomla . getOptions ( 'system.paths' ) ;
11- const uri = `${ paths ? `${ paths . rootFull } administrator/index.php` : window . location . pathname } ?option=com_workflow&extension=com_content&layout=modal&view=graph${ url } ` ;
12- const response = await fetch ( uri , {
13- credentials : 'same-origin'
14- } ) ;
15- if ( ! response . ok ) throw new Error ( `HTTP ${ response . status } ` ) ;
11+ const uri = `${ paths ? `${ paths . rootFull } administrator/index.php` : window . location . pathname
12+ } ?option=com_workflow&extension=com_content&layout=modal&view=graph${ url } `;
13+
14+ const response = await fetch ( uri , { credentials : 'same-origin' } ) ;
15+
16+ if ( ! response . ok ) {
17+ // Normalize message based on status
18+ let message = 'An unexpected error occurred.' ;
19+ if ( response . status === 401 ) {
20+ message = 'Not authenticated.' ;
21+ } else if ( response . status === 403 || response . status === 404 ) {
22+ message = 'You do not have permission to access the workflows.' ;
23+ } else {
24+ message = `Request failed with status ${ response . status } ` ;
25+ }
26+ throw new Error ( message ) ;
27+ }
28+
1629 return await response . json ( ) ;
30+
1731 } catch ( err ) {
18- console . error ( '[Workflow Graph] Request failed:' , url , err ) ;
19- return null ;
32+ showErrorInModal ( err . message ) ;
33+ throw err ;
2034 }
2135 }
36+
37+ function showErrorInModal ( errorMessage ) {
38+ const container = document . getElementById ( "workflow-container" ) ;
39+ const stageContainer = document . getElementById ( "stages" ) ;
40+
41+ if ( container ) {
42+ // Clear the main container and show error
43+ container . innerHTML = `
44+ <div class="alert alert-danger" role="alert">
45+ <h4 class="alert-heading">Error Loading Workflow</h4>
46+ <p class="mb-0">${ errorMessage } </p>
47+ </div>
48+ ` ;
49+ } else if ( stageContainer ) {
50+ // Fallback: show in stages container
51+ stageContainer . innerHTML = `
52+ <div class="alert alert-danger" role="alert">
53+ <h4 class="alert-heading">Error Loading Workflow</h4>
54+ <p class="mb-0">${ errorMessage } </p>
55+ </div>
56+ ` ;
57+ }
58+ }
59+
60+
2261 async function getWorkflow ( id ) {
2362 return makeRequest ( `&task=graph.getWorkflow&workflow_id=${ id } &format=json` ) ;
2463 }
@@ -101,40 +140,40 @@ Joomla = window.Joomla || {};
101140 return stages ;
102141 }
103142 function generateNodes ( stages , transitions ) {
104- // Ensure every stage has a position object
105- stages . forEach ( stage => {
106- if ( ! stage . position || isNaN ( stage . position . x ) || isNaN ( stage . position . y ) ) {
107- stage . position = { x : 0 , y : 0 } ;
108- } else {
109- stage . position . x = parseFloat ( stage . position . x ) ;
110- stage . position . y = parseFloat ( stage . position . y ) ;
111- }
112- } ) ;
113- const hasStart = transitions . some ( tr => tr . from_stage_id === - 1 ) ;
114- if ( hasStart && ! stages . find ( s => s . id === 'From Any' ) ) stages . unshift ( {
115- id : 'From Any' ,
116- title : 'From Any' ,
117- position : { x : 600 , y : - 200 }
118- } ) ;
119- const positionedStages = calculateAutoLayout ( stages , transitions ) ;
120- return positionedStages . map ( stage => {
121- const isVirtual = stage . id === 'From Any' ;
122- return {
123- id : `stage-${ stage . id } ` ,
124- position : stage . position ,
125- data : stage ,
126- className : `stage ${ stage . default ? 'default' : '' } ${ isVirtual ? 'virtual' : '' } ` ,
127- innerHTML : `
143+ // Ensure every stage has a position object
144+ stages . forEach ( stage => {
145+ if ( ! stage . position || isNaN ( stage . position . x ) || isNaN ( stage . position . y ) ) {
146+ stage . position = { x : 0 , y : 0 } ;
147+ } else {
148+ stage . position . x = parseFloat ( stage . position . x ) ;
149+ stage . position . y = parseFloat ( stage . position . y ) ;
150+ }
151+ } ) ;
152+ const hasStart = transitions . some ( tr => tr . from_stage_id === - 1 ) ;
153+ if ( hasStart && ! stages . find ( s => s . id === 'From Any' ) ) stages . unshift ( {
154+ id : 'From Any' ,
155+ title : 'From Any' ,
156+ position : { x : 600 , y : - 200 }
157+ } ) ;
158+ const positionedStages = calculateAutoLayout ( stages , transitions ) ;
159+ return positionedStages . map ( stage => {
160+ const isVirtual = stage . id === 'From Any' ;
161+ return {
162+ id : `stage-${ stage . id } ` ,
163+ position : stage . position ,
164+ data : stage ,
165+ className : `stage ${ stage . default ? 'default' : '' } ${ isVirtual ? 'virtual' : '' } ` ,
166+ innerHTML : `
128167 <div class="stage-title text-truncate" style="max-width: 180px;" title="${ stage . title } ">${ stage . title } </div>
129168 ${ stage . description ? `<div class="stage-description text-truncate small text-white" style="max-width: 180px;" title="${ stage . description } ">${ stage . description } </div>` : '' }
130169 <div style="display: flex; gap: 4px; align-items: center; margin-top: 2px;">
131170 ${ stage . default ? '<div class="badge bg-warning bg-opacity-10 rounded-pill p-1">DEFAULT</div>' : '' }
132171 ${ typeof stage . published !== 'undefined' ? `<div class="badge ${ stage . published == 1 ? 'bg-success' : 'bg-warning' } rounded-pill p-1">${ stage . published == 1 ? 'ENABLED' : 'DISABLED' } </div>` : '' }
133172 </div>
134173 `
135- } ;
136- } ) ;
137- }
174+ } ;
175+ } ) ;
176+ }
138177
139178 /**
140179 * Generates edge objects with robust pathing and centered labels.
@@ -284,7 +323,7 @@ Joomla = window.Joomla || {};
284323
285324 // Mark as initialized
286325 container . setAttribute ( 'data-workflow-initialized' , 'true' ) ;
287- const workflowId = parseInt ( container . dataset . workflowId , 10 ) || 2 ;
326+ const workflowId = parseInt ( container . dataset . workflowId , 10 ) ;
288327 if ( ! workflowId ) {
289328 console . warn ( "[Workflow Graph] Invalid workflow ID." ) ;
290329 return ;
@@ -405,7 +444,7 @@ Joomla = window.Joomla || {};
405444 state . stages = stages ;
406445 state . transitions = transitions ;
407446 if ( ! state . stages . length ) {
408- stageContainer . innerHTML = "<p> No stages defined.</p>" ;
447+ showErrorInModal ( ' No stages found.' ) ;
409448 return ;
410449 }
411450
@@ -550,7 +589,7 @@ Joomla = window.Joomla || {};
550589 } , 100 ) ; // Reduced delay for faster fitting
551590 } ) . catch ( error => {
552591 console . error ( '[Workflow Graph] Failed to initialize:' , error ) ;
553- stageContainer . innerHTML = `<p class="error"> Failed to load workflow data: ${ error . message } </p>` ;
592+ showErrorInModal ( ` Failed to load workflow data: ${ error . message } ` ) ;
554593 } ) ;
555594 }
556595
0 commit comments