Skip to content
Snippets Groups Projects
Select Git revision
  • ffc24b8760dd98cd475595af3ab961582cfef9a4
  • master default protected
  • L2SS-1914-fix_job_dispatch
  • TMSS-3170
  • TMSS-3167
  • TMSS-3161
  • TMSS-3158-Front-End-Only-Allow-Changing-Again
  • TMSS-3133
  • TMSS-3319-Fix-Templates
  • test-fix-deploy
  • TMSS-3134
  • TMSS-2872
  • defer-state
  • add-custom-monitoring-points
  • TMSS-3101-Front-End-Only
  • TMSS-984-choices
  • SDC-1400-Front-End-Only
  • TMSS-3079-PII
  • TMSS-2936
  • check-for-max-244-subbands
  • TMSS-2927---Front-End-Only-PXII
  • Before-Remove-TMSS
  • LOFAR-Release-4_4_318 protected
  • LOFAR-Release-4_4_317 protected
  • LOFAR-Release-4_4_316 protected
  • LOFAR-Release-4_4_315 protected
  • LOFAR-Release-4_4_314 protected
  • LOFAR-Release-4_4_313 protected
  • LOFAR-Release-4_4_312 protected
  • LOFAR-Release-4_4_311 protected
  • LOFAR-Release-4_4_310 protected
  • LOFAR-Release-4_4_309 protected
  • LOFAR-Release-4_4_308 protected
  • LOFAR-Release-4_4_307 protected
  • LOFAR-Release-4_4_306 protected
  • LOFAR-Release-4_4_304 protected
  • LOFAR-Release-4_4_303 protected
  • LOFAR-Release-4_4_302 protected
  • LOFAR-Release-4_4_301 protected
  • LOFAR-Release-4_4_300 protected
  • LOFAR-Release-4_4_299 protected
41 results

__init__.py

Blame
  • Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    ganttprojectcontroller.js 13.63 KiB
    // $Id: ganttprojectcontroller.js 32761 2015-11-02 11:50:21Z schaap $
    
    var ganttProjectControllerMod = angular.module('GanttProjectControllerMod', [
                                            'gantt',
                                            'gantt.sortable',
                                            'gantt.movable',
                                            'gantt.drawtask',
                                            'gantt.tooltips',
                                            'gantt.bounds',
                                            'gantt.progress',
                                            'gantt.table',
                                            'gantt.tree',
                                            'gantt.groups',
                                            'gantt.dependencies',
                                            'gantt.overlap',
                                            'gantt.resizeSensor',
                                            'gantt.contextmenu']).config(['$compileProvider', function($compileProvider) {
        $compileProvider.debugInfoEnabled(false); // Remove debug info (angularJS >= 1.3)
    }]);
    
    ganttProjectControllerMod.controller('GanttProjectController', ['$scope', 'dataService', function($scope, dataService) {
    
        var self = this;
        self.doInitialCollapse = true;
    
        $scope.dataService = dataService;
        $scope.ganttData = [];
        $scope.enabled = true;
    
        self.taskStatusColors = dataService.taskStatusColors;
        self.lastUpdateTimestamp = new Date(0);
        self.waitingForDelayedUpdate = false;
    
        $scope.options = {
            mode: 'custom',
            viewScale: '1 hours',
            currentDate: 'line',
            currentDateValue: $scope.dataService.lofarTime,
            columnMagnet: '1 minutes',
            timeFramesMagnet: false,
            sideMode: 'Table',
            autoExpand: 'both',
            taskOutOfRange: 'truncate',
            dependencies: false,
            api: function(api) {
                // API Object is used to control methods and events from angular-gantt.
                $scope.api = api;
    
                api.core.on.ready($scope, function () {
                        api.tasks.on.moveEnd($scope, moveHandler);
                        api.tasks.on.resizeEnd($scope, moveHandler);
                    }
                );
    
                api.directives.on.new($scope, function(directiveName, directiveScope, directiveElement) {
                    if (directiveName === 'ganttRow' || directiveName === 'ganttRowLabel' ) {
                        directiveElement.bind('click', function(event) {
                            if(directiveScope.row.model.project) {
                                $scope.dataService.selected_project_id = directiveScope.row.model.project.id;
                            }
                        });
                    } else if (directiveName === 'ganttTask') {
                        directiveElement.bind('click', function(event) {
                            if(directiveScope.task.model.raTask) {
                                if(event.ctrlKey) {
                                    $scope.dataService.toggleTaskSelection(directiveScope.task.model.raTask.id);
                                } else {
                                    $scope.dataService.setSelectedTaskId(directiveScope.task.model.raTask.id);
                                }
                            }
                        });
                        directiveElement.bind('dblclick', function(event) {
                            if(directiveScope.task.model.raTask) {
                                $scope.dataService.setSelectedTaskId(directiveScope.task.model.raTask.id);
                                $scope.jumpToSelectedTasks();
                            }
                        });
                    }
                });
    
                api.directives.on.destroy($scope, function(directiveName, directiveScope, directiveElement) {
                    if (directiveName === 'ganttRow' || directiveName === 'ganttRowLabel' || directiveName === 'ganttTask') {
                        directiveElement.unbind('click');
                    }
                    if (directiveName === 'ganttTask') {
                        directiveElement.unbind('dblclick');
                    }
                });
            }
        };
    
        function moveHandler(item)
        {
            var task_id = item.model.id;
    
            if(task_id) {
                var task = $scope.dataService.taskDict[task_id];
                var updatedTask = {
                    id: task.id,
                    starttime: item.model.from._d,
                    endtime: item.model.to._d
                };
                $scope.dataService.putTask(updatedTask);
            }
        };
    
        function updateGanttDataAsync() {
            $scope.$evalAsync(updateGanttData);
        };
    
        function updateGanttDataAsync() {
            var now = new Date();
            var diff = now.getTime() - self.lastUpdateTimestamp.getTime();
            if(diff > 500) {
                self.waitingForDelayedUpdate = false;
                $scope.$evalAsync(updateGanttData);
            }
            else {
                if (!self.waitingForDelayedUpdate) {
                    self.waitingForDelayedUpdate = true;
                    setTimeout(updateGanttDataAsync, diff);
                }
            }
        };
    
        function updateGanttData() {
            if(!$scope.enabled) {
                return;
            }
    
            if(!dataService.initialLoadComplete) {
                return;
            }
    
            var projectsDict = $scope.dataService.momProjectsDict;
            var numProjecs = $scope.dataService.momProjects.length;
    
            if(numProjecs == 0) {
                $scope.ganttData = [];
                return;
            }
    
            var taskDict = $scope.dataService.filteredTaskDict;
            var tasks = $scope.dataService.filteredTasks;
            var numTasks = tasks.length;
    
            var ganntRows = [];
    
            if(numProjecs > 0 && numTasks > 0) {
                var lowerViewBound = $scope.dataService.viewTimeSpan.from;
                var upperViewBound = $scope.dataService.viewTimeSpan.to;
                $scope.options.fromDate = lowerViewBound;
                $scope.options.toDate = upperViewBound;
                var fullTimespanInMinutes = (upperViewBound - lowerViewBound) / (60 * 1000);
    
                if(fullTimespanInMinutes > 28*24*60) {
                    $scope.options.viewScale = '7 days';
                } else if(fullTimespanInMinutes > 14*24*60) {
                    $scope.options.viewScale = '1 day';
                } else if(fullTimespanInMinutes > 7*24*60) {
                    $scope.options.viewScale = '6 hours';
                } else if(fullTimespanInMinutes > 2*24*60) {
                    $scope.options.viewScale = '3 hours';
                } else if(fullTimespanInMinutes > 12*60) {
                    $scope.options.viewScale = '1 hours';
                } else if(fullTimespanInMinutes > 3*60) {
                    $scope.options.viewScale = '30 minutes';
                } else {
                    $scope.options.viewScale = '15 minutes';
                }
    
                //only enable dependencies (arrows between tasks) in detailed view
                $scope.options.dependencies = (fullTimespanInMinutes <= 6*60 && numTasks <= 100) || numTasks < 20;
    
                //start with aggregating all tasks per type,
                //and plot these in the upper rows,
                //so we can see the observartion and pipeline scheduling usage/efficiency
                for(var type of ['observation', 'pipeline']) {
                    var typeTasks = tasks.filter(function(t) { return t.type == type;}).sort(function(a, b) { return a.starttime.getTime() -  b.starttime.getTime(); });;
                    var numTypeTasks = typeTasks.length;
    
                    if(numTypeTasks > 0) {
                        var typeAggregateRow = {
                                id: type + 's_aggregated',
                                name: ('All ' + type + 's').toUpperCase(),
                                tasks: []
                            };
                        ganntRows.push(typeAggregateRow);
    
                        var task = typeTasks[0];
    
                        var rowTask = {
                            id: typeAggregateRow.id + '_task_' + typeAggregateRow.tasks.length,
                            from: task.starttime,
                            color: '#cceecc',
                            movable: false
                        };
    
                        if(rowTask.from < lowerViewBound) {
                            rowTask.from = lowerViewBound;
                        }
    
                        for(var i = 1; i < numTypeTasks; i++) {
                            var prev_task = task;
                            task = typeTasks[i];
    
                            if(task.starttime > prev_task.endtime) {
                                rowTask.to = prev_task.endtime;
    
                                if(rowTask.to > upperViewBound) {
                                    rowTask.to = upperViewBound;
                                }
    
                                typeAggregateRow.tasks.push(rowTask);
    
                                rowTask = {
                                    id: typeAggregateRow.id + '_task_' + typeAggregateRow.tasks.length,
                                    from: task.starttime,
                                    color: '#cceecc',
                                    movable: false
                                };
    
                                if(rowTask.from < lowerViewBound) {
                                    rowTask.from = lowerViewBound;
                                }
                            }
                        }
    
                        if(!rowTask.to) {
                            rowTask.to = task.endtime;
    
                            if(rowTask.to > upperViewBound) {
                                rowTask.to = upperViewBound;
                            }
                        }
    
                        typeAggregateRow.tasks.push(rowTask);
                        var aggTaskTotalDuration = 0.0 + typeAggregateRow.tasks.map(function(t) { return t.to - t.from;}).reduce(function(a, b) { return a+b; });
                        var usage = aggTaskTotalDuration / (upperViewBound - lowerViewBound);
                        var usagePerc = parseFloat(Math.round(100.0 * usage * 10.0) / 10.0).toFixed(1);
                        typeAggregateRow.name += ' (' + usagePerc + '%)';
                    }
                }
    
                var editableTaskStatusIds = $scope.dataService.editableTaskStatusIds;
                var ganntRowsDict = {};
    
                for(var i = 0; i < numTasks; i++) {
                    var task = tasks[i];
                    var project = projectsDict[task.project_mom_id];
    
                    if(!project) {
                        continue;
                    }
    
                    var projectTypeRowsId = 'project_' + task.project_mom_id + '_type_' + task.type_id;
                    var ganntProjectTypeRows = ganntRowsDict[projectTypeRowsId];
    
                    if(!ganntProjectTypeRows) {
                        ganntProjectTypeRows = [];
                        ganntRowsDict[projectTypeRowsId] = ganntProjectTypeRows;
                    }
    
                    var availableRow = ganntProjectTypeRows.find(function(row) {
                        var overlappingTasks = row.tasks.filter(function(t) {
                            return (t.from >= task.starttime && t.from <= task.endtime) ||
                                   (t.to >= task.starttime && t.to <= task.endtime) ||
                                   (t.from <= task.starttime && t.to >= task.endtime);
                        });
                        return overlappingTasks.length == 0;
                    });
    
                    if(!availableRow)
                    {
                        availableRow = {
                            id: projectTypeRowsId + '_' + (ganntProjectTypeRows.length+1),
                            name: project.name + ' ' + task.type,
                            project: project,
                            tasks: []
                        };
    
                        ganntProjectTypeRows.push(availableRow);
                        ganntRows.push(availableRow);
                    }
                    
                    // Scheduled tasks that are blocked tasks are shown differently and use a tooltip
                    var css_class = "task-status-";
                    if (task.blocked_by_ids.length > 0) {
                        css_class += "blocked";
                    }
                    else {
                        css_class += task.status;
                    }
    
                    var rowTask = {
                        id: task.id.toString(),
                        name: task.name,
                        from: task.starttime,
                        to: task.endtime,
                        raTask: task,
                        
                        // Leave color property undefined; it is now defined by CSS
                        //color: self.taskStatusColors[task.status],
                        
                        classes: css_class,
                        movable: $.inArray(task.status_id, editableTaskStatusIds) > -1
                    };
    
                    if(dataService.isTaskIdSelected(task.id)) {
                        rowTask.classes += ' task-selected-task';
                    }
    
                    if($scope.options.dependencies && task.predecessor_ids && task.predecessor_ids.length > 0) {
                        rowTask['dependencies'] = [];
                        for(var predId of task.predecessor_ids) {
                                rowTask['dependencies'].push({'from': predId});
                        }
                    }
    
                    availableRow.tasks.push(rowTask);
                }
            }
    
            $scope.ganttData = ganntRows;
            self.lastUpdateTimestamp = new Date();
        };
    
        $scope.$watch('dataService.initialLoadComplete', updateGanttDataAsync);
        $scope.$watch('dataService.selected_task_ids', updateGanttDataAsync, true);
        $scope.$watch('dataService.viewTimeSpan', updateGanttDataAsync, true);
        $scope.$watch('dataService.filteredTaskChangeCntr', updateGanttDataAsync);
        $scope.$watch('enabled', function() { setTimeout(updateGanttDataAsync, 500); } );
        $scope.$watch('dataService.lofarTime', function() {
            $scope.$evalAsync(function() {
                if($scope.dataService.lofarTime.getSeconds() % 10 == 0) {
                    $scope.options.currentDateValue= $scope.dataService.lofarTime;}
            });
        });
    }
    ]);