Project

General

Profile

1
var module = angular.module('workflowsUI', ['ngRoute', 'ngGrid', 'dnetWorkflowsControllers']);
2

    
3
module.config(['$routeProvider', function ($routeProvider) {
4
	$routeProvider
5
		.when('/list/:section', {
6
			controller: 'wfListCtrl',
7
			templateUrl: '../resources/html/wf/wf-list.html'
8
		})
9
		.when('/wf/:wf', {
10
			controller: 'workflowCtrl',
11
			templateUrl: function (params) {
12
				if (params.wf == '_') {
13
					return "../resources/html/wf/empty.html";
14
				} else {
15
					return 'wf/workflow.html?id=' + params.wf + '&dt=' + new Date().getTime();
16
				}
17
			}
18
		}).when('/api/:repoId/:ifaceId', {
19
			controller: 'repoApiCtrl',
20
			templateUrl: function (params) {
21
				return 'wf/repoApi.html?repoId=' + params.repoId + "&ifaceId=" + params.ifaceId + '&dt=' + new Date().getTime();
22
			}
23
		})
24
		.otherwise({redirectTo: '/'});
25
}]);
26

    
27
module.service('sharedProperties', function () {
28
	var graphNodes = [];
29
	var graphArcs = [];
30
	var validParamValuesCache = {};
31
	var nodeLevelSizes = [];
32

    
33
	var updatePosition = function (node, level) {
34

    
35
		if (node.x == 0 && node.y == 0) {
36

    
37
			while (nodeLevelSizes.length <= level) {
38
				nodeLevelSizes.push(0);
39
			}
40

    
41
			node.x = (nodeLevelSizes[level] * 230) + 10;
42
			node.y = (level * 110) + 10;
43

    
44
			nodeLevelSizes[level]++;
45

    
46
			angular.forEach(graphArcs, function (arc) {
47
					if (arc.from == node.name) {
48

    
49
						if (arc.from == arc.to) {
50
							arc.x1 = arc.x2 = node.x + 190;
51
							arc.y1 = arc.y2 = node.y + 25
52
						} else {
53
							angular.forEach(graphNodes, function (other) {
54
								if (arc.to == other.name) {
55
									updatePosition(other, level + 1);
56

    
57
									var dx = node.x - other.x;
58
									var dy = node.y - other.y;
59
									// TODO : linee verticali che si sovrappongono (nodi che distano piu di un livello), linee che passano sotto ai nodi, linee che risalgono,
60

    
61
									if (dy < 0) {
62
										// linee con frecce in basso
63

    
64
										arc.x1 = node.x + 90;
65
										arc.y1 = node.y + 55;
66

    
67
										arc.x2 = other.x + 90;
68
										arc.y2 = other.y - 15;
69

    
70
										var step;
71
										if (dx > 0) {
72
											step = Math.min(80, 2 * Math.sqrt(dx));
73
										} else if (dx < 0) {
74
											step = Math.max(-80, -2 * Math.sqrt(-dx));
75
										} else {
76
											step = 0;
77
										}
78
										arc.x1 -= step;
79
										arc.x2 += step;
80
									} else if (dy > 0) {
81
										arc.x1 = node.x + 90;
82
										arc.y1 = node.y - 15;
83

    
84
										arc.x2 = other.x + 90;
85
										arc.y2 = other.y + 55;
86

    
87
										var step;
88
										if (dx > 0) {
89
											step = Math.min(80, 2 * Math.sqrt(dx));
90
										} else if (dx < 0) {
91
											step = Math.max(-80, -2 * Math.sqrt(-dx));
92
										} else {
93
											step = 0;
94
										}
95
										arc.x1 -= step;
96
										arc.x2 += step;
97

    
98
									} else {
99
										// linee orizzonatali
100
										arc.x1 = node.x;
101
										arc.x2 = other.x;
102

    
103
										arc.y1 = arc.y2 = node.y + 25 - (Math.min(20, Math.abs(dx / 230) - 1)) * 5;
104

    
105
										if (dx > 0) {
106
											arc.x1 -= 5;
107
											arc.x2 += 190;
108
										} else {
109
											arc.x1 += 190;
110
											arc.x2 -= 5;
111
										}
112
									}
113
								}
114
							});
115
						}
116
					}
117
				}
118
			);
119
		}
120
	};
121

    
122
	return {
123

    
124
		listValidValuesForUserParam: function (func, refresh) {
125
			if (refresh || !validParamValuesCache[func]) {
126
				try {
127
					validParamValuesCache[func] = eval(func);
128
				} catch (e) {
129
					alert('Error evaluating function: ' + func);
130
					validParamValuesCache[func] = [];
131
				}
132
			}
133
			return validParamValuesCache[func];
134
		},
135
		registerNode: function (node) {
136
			graphNodes.push(node);
137
		},
138
		registerArc: function (arc) {
139
			graphArcs.push(arc);
140
		},
141
		resetGraph: function () {
142
			graphNodes = [];
143
			graphArcs = [];
144
		},
145
		rearrangeNodes: function () {
146
			nodeLevelSizes.length = 0;
147
			angular.forEach(graphNodes, function (node) {
148
				node.x = 0;
149
				node.y = 0;
150
			});
151

    
152
			angular.forEach(graphNodes, function (node) {
153
				if (node.type == 'start') {
154
					updatePosition(node, 0);
155
				}
156
			});
157
		}
158
	};
159
});
160

    
161
module.directive('bsHasError', function () {
162
	return {
163
		restrict: "A",
164
		link: function (scope, element, attrs, ctrl) {
165
			element.toggleClass('has-feedback', true);
166
			var input = element.find('input[ng-model], select[ng-model]');
167
			if (input) {
168
				scope.$watch(function () {
169
					if (input.controller('ngModel').$invalid) {
170
						return 0;
171
					} else if (!input.controller('ngModel').$viewValue) {
172
						return 1;
173
					} else {
174
						return 2;
175
					}
176
				}, function (code) {
177
					if (code < 0) return;
178

    
179
					element.toggleClass('has-error', (code == 0));
180
					element.toggleClass('has-warning', (code == 1));
181
					element.toggleClass('has-success', (code == 2));
182

    
183
					var feedback = element.find('.form-control-feedback');
184
					if (feedback) {
185
						feedback.toggleClass('glyphicon-remove', (code == 0));
186
						feedback.toggleClass('glyphicon-warning-sign', (code == 1));
187
						feedback.toggleClass('glyphicon-ok', (code == 2));
188
					}
189
				});
190
			}
191
		}
192
	};
193
});
194

    
195

    
196
module.directive('wfFormRowStatic', function () {
197
	return {
198
		restrict: 'E',
199
		scope: {
200
			name: '@',
201
			value: '@',
202
			description: '@',
203
			valueStyle: '@'
204
		},
205
		templateUrl: '../resources/html/wf/wf-form-row-static.html'
206
	}
207
});
208

    
209
module.directive('wfFormRowStaticImg', function () {
210
	return {
211
		restrict: 'E',
212
		scope: {
213
			name: '@',
214
			value: '@',
215
			img: '@',
216
			description: '@',
217
			valueStyle: '@',
218
		},
219
		templateUrl: '../resources/html/wf/wf-form-row-static-img.html'
220
	}
221
});
222

    
223
module.directive('wfFormRowLabel', function () {
224
	return {
225
		restrict: 'E',
226
		scope: {
227
			name: '@',
228
			value: '@',
229
			description: '@',
230
			labelClass: '@'
231
		},
232
		templateUrl: '../resources/html/wf/wf-form-row-label.html'
233
	}
234
});
235

    
236
module.directive('wfFormRowLink', function () {
237
	return {
238
		restrict: 'E',
239
		scope: {
240
			name: '@',
241
			value: '@',
242
			description: '@',
243
			url: '@'
244
		},
245
		templateUrl: '../resources/html/wf/wf-form-row-link.html'
246
	}
247
});
248

    
249
module.directive('wfFormRowSelect', function (sharedProperties) {
250
	return {
251
		restrict: 'E',
252
		templateUrl: '../resources/html/wf/wf-form-row-select.html',
253
		scope: {
254
			name: '@',
255
			value: '@',
256
			mandatory: '@',
257
			description: '@',
258
			initValue: '@',
259
			ngModel: '=',
260
			ngOriginalModel: '=',
261
			values: '=',
262
			valuesFunction: '@'
263
		},
264
		link: function (scope) {
265
			scope.finalValues = [];
266

    
267
			scope.ngModel = scope.initValue;
268
			scope.ngOriginalModel = scope.initValue;
269

    
270
			scope.isRequired = (scope.mandatory == "true");
271

    
272
			if (scope.values) {
273
				scope.finalValues = scope.values;
274
			} else if (scope.valuesFunction) {
275
				scope.finalValues = sharedProperties.listValidValuesForUserParam(scope.valuesFunction);
276
			}
277
		}
278
	}
279
});
280

    
281
module.directive('wfFormRowMultiSelect', function (sharedProperties) {
282
	return {
283
		restrict: 'E',
284
		templateUrl: '../resources/html/wf/wf-form-row-multi-select.html',
285
		scope: {
286
			name: '@',
287
			value: '@',
288
			mandatory: '@',
289
			description: '@',
290
			initValue: '@',
291
			ngModel: '=',
292
			ngOriginalModel: '=',
293
			values: '=',
294
			valuesFunction: '@'
295
		},
296
		link: function (scope) {
297
			scope.finalValues = [];
298

    
299
			scope.ngModel = scope.initValue.split(',');
300
			scope.ngOriginalModel = scope.initValue.split(',');
301

    
302
			scope.isRequired = (scope.mandatory == "true");
303

    
304
			if (scope.values) {
305
				scope.finalValues = scope.values;
306
			} else if (scope.valuesFunction) {
307
				scope.finalValues = sharedProperties.listValidValuesForUserParam(scope.valuesFunction);
308
			}
309
			
310
			scope.refreshValues = function() {
311
				scope.finalValues = sharedProperties.listValidValuesForUserParam(scope.valuesFunction, true);
312
			}
313
		}
314
	}
315
});
316

    
317

    
318
module.directive('wfFormRowText', function () {
319
	return {
320
		restrict: 'E',
321
		templateUrl: '../resources/html/wf/wf-form-row-text.html',
322
		//require: '^ngModel',
323
		scope: {
324
			name: '@',
325
			mandatory: '@',
326
			description: '@',
327
			initValue: '@',
328
			type: '@',
329
			regex: '@',
330
			ngModel: '=',
331
			ngOriginalModel: '='
332
		},
333
		link: function (scope) {
334

    
335
			scope.ngModel = "";
336
			scope.ngOriginalModel = "";
337

    
338
			if (scope.initValue) {
339
				scope.ngModel = scope.initValue;
340
				scope.ngOriginalModel = scope.initValue;
341
			}
342

    
343
			scope.isRequired = (scope.mandatory == "true");
344
			
345
			if (scope.regex) {
346
				scope.mypattern = new RegExp(scope.regex);
347
			} else if (scope.type == 'boolean') {
348
				scope.mypattern = new RegExp("^(true|false)$");
349
			} else if (scope.type == 'int') {
350
				scope.mypattern = new RegExp("^[-+]?[0-9]+$");
351
			} else if (scope.type == 'float') {
352
				scope.mypattern = new RegExp("^[-+]?[0-9]+(\.[0-9]+)?$");
353
			} else if (scope.type == 'date') {
354
				scope.mypattern = new RegExp("^(0[1-9]|[12][0-9]|3[01])[- \/.](0[1-9]|1[012])[- \/.](19|20)\d\d$");
355
			} else {
356
				scope.mypattern = new RegExp("^.+$");
357
			}
358
		}
359
	}
360
});
361

    
362
module.directive('wfFormUpdate', function ($http) {
363
	return {
364
		restrict: 'E',
365
		templateUrl: '../resources/html/wf/wf-form-update.html',
366
		scope: {
367
			wfId: '@',
368
			mode: '@',
369
			priority: '@',
370
			email: '@',
371
			scheduled: '@',
372
			cron: '@',
373
			interval: '@'
374
		},
375
		link: function (scope) {
376
			initSpinner();
377

    
378
			scope.originalWf = {
379
				'wfId': scope.wfId,
380
				'mode': scope.mode,
381
				'priority': scope.priority,
382
				'email': scope.email,
383
				'scheduled': (scope.scheduled == 'true'),
384
				'cron': scope.cron,
385
				'interval': scope.interval
386
			};
387

    
388
			scope.reset = function () {
389
				scope.wf = angular.copy(scope.originalWf);
390
			};
391

    
392
			scope.updateWf = function () {
393
				showSpinner();
394
				$http.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded; charset=UTF-8";
395
				$http.post('wf/update_workflow.do', $.param({
396
					'json': JSON.stringify(scope.wf)
397
				})).success(function (data) {
398
					scope.originalWf = angular.copy(scope.wf);
399

    
400
					hideSpinner();
401
					show_notification("info", 'Workflow updated !');
402
				}).error(function (err) {
403
					show_notification("error", err.message);
404
					hideSpinner();
405
				});
406
			};
407

    
408
			scope.reset();
409

    
410
		}
411
	}
412
});
413

    
414

    
415
module.directive('wfSubWorkflows', function ($http) {
416
	return {
417
		restrict: 'E',
418
		templateUrl: '../resources/html/wf/wf-sub-workflows.html',
419
		scope: {
420
			children: '=',
421
			currentProc: '='
422
		},
423
		link: function (scope) {
424
			scope.executeWf = function (wfId) {
425
				$http.get('wf/wf.start?id=' + wfId).success(function (data) {
426
					scope.currentProc = data;
427
					$('#monitorProcWfModal').modal('show');
428
				}).error(function (err) {
429
					show_notification("error", "Error executing wf: " + err.message);
430
				});
431
			};
432
		}
433
	}
434
});
435

    
436

    
437
module.directive('wfHistory', function () {
438
	return {
439
		restrict: 'E',
440
		templateUrl: '../resources/html/wf/wf-history.html',
441
		scope: {
442
			ngModel: '=',
443
			onRefresh: '&'
444
		},
445
		link: function (scope) {
446
			scope.doOnRefesh = function () {
447
				scope.onRefresh();
448
			}
449
		}
450
	}
451
});
452

    
453
module.directive('wfProcModal', function (sharedProperties, $sce, $http) {
454
	return {
455
		restrict: 'E',
456
		templateUrl: '../resources/html/wf/wf-proc-modal.html',
457
		scope: {
458
			proc: '='
459
		},
460
		link: function (scope) {
461
			initSpinner();
462

    
463
			scope.to_trusted = function (html_code) {
464
				return $sce.trustAsHtml(html_code);
465
			}
466

    
467
			scope.refresh = function () {
468
				showSpinner();
469
				$http.get('wf/journal.get?id=' + scope.proc.procId).success(function (data) {
470
					scope.proc = data;
471
					hideSpinner();
472
				}).error(function (e) {
473
					show_notification('error', 'Error fetching process info: ' + e);
474
					hideSpinner();
475
				});
476
			}
477

    
478
			scope.kill = function () {
479
				if (confirm("Are you sure ?")) {
480
					showSpinner();
481
					$http.get('wf/proc.kill?id=' + scope.proc.procId).success(function (data) {
482
						scope.currentProc = {};
483
						hideSpinner();
484
						$('#monitorProcWfModal').modal('hide');
485
						show_notification('info', 'Workflow killed !');
486
					}).error(function (e) {
487
						show_notification('error', 'Error killing process: ' + e);
488
						hideSpinner();
489
					});
490
				}
491
			}
492

    
493
			scope.calculateDateDiff = function (start, end) {
494
				if (start <= 0 || end <= 0) {
495
					return '-';
496
				}
497
				var seconds = 0;
498
				var minutes = 0;
499
				var hours = 0;
500
				var days = 0;
501

    
502
				if (end > start) {
503
					seconds = Math.round((end - start) / 1000);
504

    
505
					if (seconds > 60) {
506
						minutes = Math.floor(seconds / 60);
507
						seconds = seconds % 60;
508
						if (minutes > 60) {
509
							hours = Math.floor(minutes / 60);
510
							minutes = minutes % 60;
511
							if (hours > 24) {
512
								days = Math.floor(hours / 24);
513
								hours = hours % 24;
514
							}
515
						}
516
					}
517
				}
518

    
519
				var res = '';
520
				if (days > 0) {
521
					if (res) {
522
						res += ', ';
523
					}
524
					res += days + " day(s)"
525
				}
526
				if (hours > 0) {
527
					if (res) {
528
						res += ', ';
529
					}
530
					res += hours + " hour(s)"
531
				}
532
				if (minutes > 0) {
533
					if (res) {
534
						res += ', ';
535
					}
536
					res += minutes + " minute(s)"
537
				}
538
				if (seconds > 0) {
539
					if (res) {
540
						res += ', ';
541
					}
542
					res += seconds + " second(s)"
543
				}
544

    
545
				if (!res) {
546
					res = '0 seconds';
547
				}
548

    
549
				return res;
550
			}
551

    
552
		}
553
	}
554
});
555

    
556

    
557
module.directive('wfGraphNode', function (sharedProperties) {
558
	return {
559
		restrict: 'E',
560
		replace: true,
561
		templateNamespace: 'svg',
562
		templateUrl: '../resources/html/wf/wf-graph-node.html',
563
		scope: {
564
			name: '@',
565
			type: '@'
566
		},
567
		link: function (scope) {
568
			scope.node = {
569
				name: scope.name,
570
				type: scope.type,
571
				x: 0,
572
				y: 0
573
			};
574

    
575
			if (scope.type == 'start') {
576
				scope.clazz = 'graphStartNode';
577
			} else if (scope.type == 'success') {
578
				scope.clazz = 'graphSuccessNode';
579
			} else if (scope.type == 'join') {
580
				scope.clazz = 'graphJoinNode';
581
			} else {
582
				scope.clazz = 'graphSimpleNode';
583
			}
584

    
585
			sharedProperties.registerNode(scope.node);
586

    
587
			scope.showNodeInfo = function () {
588
				alert("TODO");
589
			}
590
		}
591
	}
592
});
593

    
594
module.directive('wfGraphArc', function (sharedProperties) {
595
	return {
596
		restrict: 'E',
597
		replace: true,
598
		templateNamespace: 'svg',
599
		templateUrl: '../resources/html/wf/wf-graph-arc.html',
600
		scope: {
601
			name: '@',
602
			from: '@',
603
			to: '@'
604
		},
605
		link: function (scope) {
606
			scope.arc = {
607
				name: scope.name,
608
				from: scope.from,
609
				to: scope.to,
610
				x1: 0,
611
				y1: 0,
612
				x2: 0,
613
				y2: 0
614
			};
615

    
616
			sharedProperties.registerArc(scope.arc);
617
		}
618
	}
619
});
620

    
621
//addCommonDirectives(module);
622

    
623

    
(8-8/15)