-
Jorrit Schaap authoredJorrit Schaap authored
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
gridcontroller.js 38.88 KiB
// $Id: controller.js 32761 2015-11-02 11:50:21Z schaap $
var gridControllerMod = angular.module('GridControllerMod', ['ui.grid',
'ui.grid.edit',
'ui.grid.selection',
'ui.grid.resizeColumns',
'ui.grid.autoResize']);
gridControllerMod.controller('GridController', ['$scope', 'dataService', 'uiGridConstants', function($scope, dataService, uiGridConstants) {
var self = this;
self.lastUpdateTimestamp = new Date(0);
self.waitingForDelayedUpdate = false;
$scope.dataService = dataService;
$scope.columns = [
{ field: 'name',
enableCellEdit: false,
width: '*',
minWidth: '100',
},
{ field: 'project_name',
displayName:'Project',
enableCellEdit: false,
cellTemplate:'<div style=\'padding-top:5px;\'><a target="_blank" href="https://lofar.astron.nl/mom3/user/project/setUpMom2ObjectDetails.do?view=generalinfo&mom2ObjectId={{row.entity.project_mom2object_id}}">{{row.entity[col.field]}}</a></div>',
width: '*',
minWidth: '80',
filter: {
type: uiGridConstants.filter.SELECT,
selectOptions: []
}
},
{ field: 'starttime',
displayName: 'Start',
width: '120',
type: 'date',
enableCellEdit: false,
enableCellEditOnFocus: false,
cellTemplate:'<div style=\'text-align:center; padding-top:5px;\'>{{row.entity[col.field] | date:\'yyyy-MM-dd HH:mm:ss\'}}</div>',
sort: { direction: uiGridConstants.ASC, priority: 3 }
},
{ field: 'endtime',
displayName: 'End',
width: '120',
type: 'date',
enableCellEdit: false,
enableCellEditOnFocus: false,
cellTemplate:'<div style=\'text-align:center; padding-top:5px;\'>{{row.entity[col.field] | date:\'yyyy-MM-dd HH:mm:ss\'}}</div>'
},
{ field: 'duration',
displayName: 'Duration',
width: '70',
type: 'number',
enableFiltering: false,
enableCellEdit: false,
enableCellEditOnFocus: false,
cellTemplate:'<div style=\'text-align:center; padding-top:5px;\'>{{row.entity[col.field] | secondsToHHmmss}}</div>'
},
{ field: 'status',
enableCellEdit: false,
width: '70',
filter: {
condition: uiGridConstants.filter.EXACT,
type: uiGridConstants.filter.SELECT,
selectOptions: []
},
cellClass: function(grid, row, col, rowRenderIndex, colRenderIndex) {
return "grid-status-" + grid.getCellValue(row,col);
}
},
{ field: 'info',
displayName: 'Info',
enableCellEdit: false,
width: '45',
filter: {
condition: function(searchTerm, cellValue, row, column) {
var do_include = false;
switch(searchTerm) {
case 0: do_include = (row.entity.blocked_by_ids.length > 0); break;
case 1: do_include = (row.entity.ingest_status=="ingesting"); break;
case 2: do_include = (row.entity.ingest_status=="ingested"); break;
case 3: do_include = (row.entity.ingest_status=="failed"); break;
default: break;
};
return do_include;
},
type: uiGridConstants.filter.SELECT,
selectOptions: []
},
editableCellTemplate: 'ui-grid/dropdownEditor',
editDropdownOptionsArray: [],
headerTooltip: "Additional status information",
cellTemplate: '<div style="text-align: center" class="ui-grid-cell-contents">' +
'<span ng-if="row.entity.blocked_by_ids.length > 0"><img ng-src="static/icons/blocked.png" title="Blocked by {{row.entity.blocked_by_ids.length.toString()}} predecessor(s)" /></span>' +
'<span ng-if="row.entity.ingest_status==\'ingesting\'"><img ng-src="static/icons/ingest_in_progress.png" title="Ingest in progress" /></span>' +
'<span ng-if="row.entity.ingest_status==\'ingested\'"><img ng-src="static/icons/ingest_successful.png" title="Ingest successful" /></span>' +
'<span ng-if="row.entity.ingest_status==\'failed\'"><img ng-src="static/icons/ingest_failed.png" title="Ingest failed" /></span>' +
'</div>'
},
{ field: 'type',
enableCellEdit: false,
width: '80',
filter: {
condition: uiGridConstants.filter.EXACT,
type: uiGridConstants.filter.SELECT,
selectOptions: []
},
sort: { direction: uiGridConstants.ASC, priority: 2 }
},
{ field: 'disk_usage',
displayName: 'Size',
type: 'number',
enableCellEdit: false,
cellTemplate:'<div style=\'text-align:right\'>{{row.entity.disk_usage_readable}}</div>',
width: '80',
filter: {
type: uiGridConstants.filter.SELECT,
condition: uiGridConstants.filter.GREATER_THAN,
selectOptions: [{ value:1e9, label: '> 1G'}, { value:1e10, label: '> 10G'}, { value:1e11, label: '> 100G'}, { value:1e12, label: '> 1T'} ]
}
},
{ field: 'mom_object_group_id',
displayName: 'Group ID',
enableCellEdit: false,
cellTemplate:'<div style=\'text-align:center; padding-top:5px;\'><a target="_blank" href="https://lofar.astron.nl/mom3/user/project/setUpMom2ObjectDetails.do?view=generalinfo&mom2ObjectId={{row.entity.mom_object_group_mom2object_id}}">{{row.entity.mom_object_group_id}}</a></div>',
width: '80',
filter: {
condition: uiGridConstants.filter.EXACT,
type: uiGridConstants.filter.SELECT,
selectOptions: []
}
},
{ field: 'mom_id',
displayName: 'MoM ID',
enableCellEdit: false,
cellTemplate:'<div style=\'text-align:center; padding-top:5px;\'><a target="_blank" href="https://lofar.astron.nl/mom3/user/project/setUpMom2ObjectDetails.do?view=generalinfo&mom2ObjectId={{row.entity.mom2object_id}}">{{row.entity[col.field]}}</a></div>',
width: '65'
},
{ field: 'otdb_id',
displayName: 'SAS ID',
enableCellEdit: false,
cellTemplate:'<div style=\'text-align:center; padding-top:5px;\'>{{row.entity.otdb_id}}</div>',
width: '65'
},
{ field: 'id',
displayName: 'RADB ID',
enableCellEdit: false,
cellTemplate:'<div style=\'text-align:center; padding-top:5px;\'><a target="_blank" href="tasks/{{row.entity.id}}.html">{{row.entity[col.field]}}</a></div>',
width: '72'
},
{ field: 'cluster',
displayName: 'Cluster',
enableCellEdit: false,
width: '65',
filter: {
condition: uiGridConstants.filter.EXACT,
type: uiGridConstants.filter.SELECT,
selectOptions: []
},
cellClass: function(grid, row, col, rowRenderIndex, colRenderIndex) {
var value = grid.getCellValue(row,col);
return "grid-cluster-" + value;
},
sort: { direction: uiGridConstants.ASC, priority: 1 }
}];
$scope.gridOptions = {
enableGridMenu: false,
enableSorting: true,
enableFiltering: true,
enableCellEdit: false,
enableColumnResize: true,
enableHorizontalScrollbar: uiGridConstants.scrollbars.NEVER,
enableRowSelection: true,
enableRowHeaderSelection: true,
enableFullRowSelection: false,
modifierKeysToMultiSelect: true,
multiSelect:true,
enableSelectionBatchEvent:false,
gridMenuShowHideColumns: false,
columnDefs: $scope.columns,
data: [],
// rowTemplate: "<div ng-repeat=\"(colRenderIndex, col) in colContainer.renderedColumns track by col.uid\" ui-grid-one-bind-id-grid=\"rowRenderIndex + '-' + col.uid + '-cell'\" class=\"ui-grid-cell\" ng-class=\"{ 'ui-grid-row-header-cell': col.isRowHeader }\" role=\"{{col.isRowHeader ? 'rowheader' : 'gridcell'}}\" ui-grid-cell></div>"
rowTemplate: "<div ng-repeat=\"(colRenderIndex, col) in colContainer.renderedColumns track by col.uid\" ui-grid-one-bind-id-grid=\"rowRenderIndex + '-' + col.uid + '-cell'\" class=\"ui-grid-cell\" ng-class=\"{ 'ui-grid-row-header-cell': col.isRowHeader }\" role=\"{{col.isRowHeader ? 'rowheader' : 'gridcell'}}\" ui-grid-cell context-menu>",
onRegisterApi: function(gridApi){
$scope.gridApi = gridApi;
$scope.gridApi.core.on.rowsRendered($scope, function() {
//on.rowsRendered is called whenever the data/filtering of the grid changed
//update the filteredTasks in the dataService from the resulting new grid rows
$scope.$evalAsync(function() {
var taskDict = $scope.dataService.taskDict;
$scope.dataService.filteredTasks = [];
var rows = $scope.gridApi.core.getVisibleRows(grid);
var numRows = rows.length;
for(var i = 0; i < numRows; i++) {
var row = rows[i];
if(row.visible)
{
var task_id = row.entity.id;
var task = taskDict[task_id];
if(task) {
$scope.dataService.filteredTasks.push(task);
}
row.setSelected($scope.dataService.selected_task_ids.indexOf(task_id) != -1);
}
}
$scope.dataService.filteredTaskDict = $scope.dataService.toIdBasedDict($scope.dataService.filteredTasks);
$scope.dataService.filteredTaskChangeCntr++;
if($scope.dataService.filteredTasks.length == 0) {
var otdb_col = $scope.gridApi.grid.columns.find(function(c) {return c.field == 'otdb_id'; });
if(otdb_col && otdb_col.filters.length && otdb_col.filters[0].hasOwnProperty('term')) {
var otdb_id = otdb_col.filters[0].term;
$scope.$parent.$parent.loadTaskByOTDBIdSelectAndJumpIntoView(otdb_id).then(function() {
otdb_col.filters[0].term = null;
});
} else {
var mom_col = $scope.gridApi.grid.columns.find(function(c) {return c.field == 'mom_id'; });
if(mom_col && mom_col.filters.length && mom_col.filters[0].hasOwnProperty('term')) {
var mom_id = mom_col.filters[0].term;
$scope.$parent.$parent.loadTaskByMoMIdSelectAndJumpIntoView(mom_id).then(function(task) {
mom_col.filters[0].term = null;
if(task == undefined) {
//getting the task by mom_id did not find a task
//maybe the entered id was a mom group_id?
//let's try to loadTasksByMoMGroupIdSelectAndJumpIntoView
$scope.$parent.$parent.loadTasksByMoMGroupIdSelectAndJumpIntoView(mom_id).then(function(tasks) {
if(tasks == undefined || tasks.length == 0) {
//getting the tasks by mom group id did not find any tasks
//maybe the entered id was a mom parent group_id?
//let's try to loadTasksByMoMParentGroupIdSelectAndJumpIntoView
$scope.$parent.$parent.loadTasksByMoMParentGroupIdSelectAndJumpIntoView(mom_id).then(function(tasks) {
//pass
});
}
});
}
});
}
}
}
});
});
gridApi.edit.on.afterCellEdit($scope,function(rowEntity, colDef, newValue, oldValue){
var task = $scope.dataService.taskDict[rowEntity.id];
var newTask = { id: task.id, status: task.status };
$scope.dataService.putTask(newTask);
});
gridApi.selection.on.rowSelectionChanged($scope,function(row){
if(row.entity.id) {
if(row.isSelected) {
$scope.dataService.addSelectedTaskId(row.entity.id);
} else if(!row.isSelected) {
$scope.dataService.removeSelectedTaskId(row.entity.id);
}
}
});
}
};
function fillColumFilterSelectOptions(options, columnDef) {
var columnSelectOptions = [];
if(options) {
for(var i = 0; i < options.length; i++) {
var option = options[i];
if(option.hasOwnProperty('value') && option.hasOwnProperty('label')) {
columnSelectOptions.push({ value: option.value, label: option.label })
}
else {
columnSelectOptions.push({ value: option, label: option })
}
}
}
columnDef.filter.selectOptions = columnSelectOptions;
};
function populateListAsync() {
var now = new Date();
var diff = now.getTime() - self.lastUpdateTimestamp.getTime();
if(diff > 500) {
self.waitingForDelayedUpdate = false;
$scope.$evalAsync(populateList);
}
else {
if (!self.waitingForDelayedUpdate) {
self.waitingForDelayedUpdate = true;
setTimeout(populateListAsync, diff);
}
}
};
function populateList() {
if('tasks' in $scope.dataService && $scope.dataService.tasks.length > 0) {
var viewFrom = $scope.dataService.viewTimeSpan.from;
var viewTo = $scope.dataService.viewTimeSpan.to;
$scope.dataService.filteredTasks = [];
var gridTasks = [];
for(var task of $scope.dataService.tasks) {
if(task.endtime >= viewFrom && task.starttime <= viewTo) {
$scope.dataService.filteredTasks.push(task);
var gridTask = {
id: task.id,
name: task.name,
project_name: task.project_name,
mom_id: task.mom_id,
otdb_id: task.otdb_id,
starttime: task.starttime,
endtime: task.endtime,
duration: task.duration,
status: task.status,
type: task.type,
project_mom2object_id: task.project_mom2object_id,
mom2object_id: task.mom2object_id,
mom_object_group_id: task.mom_object_group_id,
mom_object_group_name: task.mom_object_group_name,
mom_object_group_mom2object_id: task.mom_object_group_mom2object_id,
mom_object_parent_group_id: task.mom_object_parent_group_id,
cluster: task.cluster,
blocked_by_ids: task.blocked_by_ids,
ingest_status: task.ingest_status === null ? undefined : task.ingest_status,
disk_usage: task.disk_usage === null ? undefined : task.disk_usage,
disk_usage_readable: task.disk_usage_readable === null ? undefined : task.disk_usage_readable
};
gridTasks.push(gridTask);
}
}
$scope.gridOptions.data = gridTasks;
} else
$scope.gridOptions.data = []
fillProjectsColumFilterSelectOptions()
fillGroupsColumFilterSelectOptions();
self.lastUpdateTimestamp = new Date();
};
function jumpToSelectedTaskRows() {
var rowIndices = dataService.selected_task_ids.map(function(t_id) { return $scope.gridOptions.data.findIndex(function(row) {return row.id == t_id; } ); });
rowIndices = rowIndices.filter(function(idx) {return idx > -1;}).sort();
for(var rowIndex of rowIndices) {
$scope.gridApi.core.scrollTo($scope.gridOptions.data[rowIndex], null);
}
};
function onSelectedTaskIdsChanged() {
var selected_task_ids = $scope.dataService.selected_task_ids;
var rows = $scope.gridApi.grid.rows;
for(var row of rows) {
row.setSelected(selected_task_ids.indexOf(row.entity.id) != -1);
}
//find out if we have selected all tasks in a single mom group
var selected_tasks = $scope.dataService.selected_task_ids.map(function(t_id) { return $scope.dataService.taskDict[t_id]; }).filter(function(t) { return t != undefined;});
if(selected_tasks && selected_tasks.length > 1) {
var selected_task_group_ids = selected_tasks.map(function(t) { return t.mom_object_group_id; });
selected_task_group_ids = selected_task_group_ids.unique();
if(selected_task_group_ids.length == 1) {
//we have selected tasks in a single mom group
//find out if we have selected all tasks within this mom group
var mom_object_group_id = selected_task_group_ids[0];
var all_group_tasks = $scope.dataService.tasks.filter(function(t) { return t.mom_object_group_id == mom_object_group_id; });
if(all_group_tasks.length == selected_tasks.length) {
//we have selected all tasks in a single mom group
//apply filter on group column to see only tasks within this group
var group_col = $scope.gridApi.grid.columns.find(function(c) {return c.field == 'mom_object_group_id'; });
if(group_col) {
var mom_object_group_name = all_group_tasks[0].mom_object_group_name;
var label = mom_object_group_id + ' ' + mom_object_group_name;
var groupSelectOptions = [ { value: mom_object_group_id, label: label} ];
fillColumFilterSelectOptions(groupSelectOptions, $scope.columns[9]);
group_col.filters[0].term = mom_object_group_id;
}
}
}
}
$scope.$evalAsync(jumpToSelectedTaskRows);
};
$scope.$watch('dataService.taskChangeCntr', function() { populateListAsync(); });
$scope.$watch('dataService.claimChangeCntr', function() { populateListAsync(); });
$scope.$watch('dataService.viewTimeSpan', function() {
populateListAsync();
$scope.$evalAsync(jumpToSelectedTaskRows);
}, true);
function fillFilterSelectOptions() {
if(dataService.initialLoadComplete) {
fillStatusColumFilterSelectOptions();
fillInfoColumFilterSelectOptions();
fillTypeColumFilterSelectOptions();
fillProjectsColumFilterSelectOptions();
fillGroupsColumFilterSelectOptions();
fillColumFilterSelectOptions(['CEP2', 'CEP4'], $scope.columns[13]);
}
};
$scope.$watch('dataService.filteredTaskChangeCntr', function() { $scope.$evalAsync(fillFilterSelectOptions()); });
$scope.$watch('dataService.initialLoadComplete', function() { $scope.$evalAsync(fillFilterSelectOptions()); });
function fillProjectsColumFilterSelectOptions() {
var projectNames = [];
var momProjectsDict = $scope.dataService.momProjectsDict;
var tasks = $scope.dataService.filteredTasks;
var project_col = $scope.gridApi.grid.columns.find(function(c) {return c.field == 'project_name'; });
if(project_col && project_col.filters.length && project_col.filters[0].term) {
tasks = $scope.dataService.tasks;
}
//get unique projectIds from tasks
var task_project_ids = tasks.map(function(t) { return t.project_mom_id; });
task_project_ids = task_project_ids.unique();
for(var project_id of task_project_ids) {
if(momProjectsDict.hasOwnProperty(project_id)) {
var projectName = momProjectsDict[project_id].name;
if(!(projectName in projectNames)) {
projectNames.push(projectName);
}
}
}
projectNames.sort();
fillColumFilterSelectOptions(projectNames, $scope.columns[1]);
};
function fillStatusColumFilterSelectOptions() {
var tasks = $scope.dataService.filteredTasks;
var status_col = $scope.gridApi.grid.columns.find(function(c) {return c.field == 'status'; });
if(status_col && status_col.filters.length && status_col.filters[0].term) {
tasks = $scope.dataService.tasks;
}
//get unique statuses from tasks
var task_statuses = tasks.map(function(t) { return t.status; });
task_statuses = task_statuses.unique();
task_statuses.sort();
fillColumFilterSelectOptions(task_statuses, $scope.columns[5]);
};
function fillTypeColumFilterSelectOptions() {
var tasks = $scope.dataService.filteredTasks;
var type_col = $scope.gridApi.grid.columns.find(function(c) {return c.field == 'type'; });
if(type_col && type_col.filters.length && type_col.filters[0].term) {
tasks = $scope.dataService.tasks;
}
//get unique types from tasks
var task_types = tasks.map(function(t) { return t.type; });
task_types = task_types.unique();
task_types.sort();
fillColumFilterSelectOptions(task_types, $scope.columns[7]);
};
function fillGroupsColumFilterSelectOptions() {
if($scope.columns[9].filter.term) {
return;
}
var tasks = $scope.dataService.filteredTasks;
//get unique groupNames from tasks
var groupId2Name = {};
var groupIds = [];
for(var task of tasks) {
if(task.mom_object_group_id) {
if(!groupId2Name.hasOwnProperty(task.mom_object_group_id)) {
groupId2Name[task.mom_object_group_id] = task.mom_object_group_name;
groupIds.push(task.mom_object_group_id);
}
}
}
groupIds.sort();
fillColumFilterSelectOptions(groupIds, $scope.columns[9]);
};
function fillInfoColumFilterSelectOptions() {
var tasks = $scope.dataService.filteredTasks;
var info_col = $scope.gridApi.grid.columns.find(function(c) {return c.field == 'info'; });
if(info_col && info_col.filters.length && info_col.filters[0].term) {
tasks = $scope.dataService.tasks;
}
// Generate a list of unique information items
var task_info = [];
var info_bit_flags = 0x00;
for(var task of tasks) {
if((task.blocked_by_ids.length > 0) && !(info_bit_flags & 0x01)) {
task_info.push({ value: 0, label: 'Blocked tasks' });
info_bit_flags |= 0x01;
}
if((task.ingest_status === 'ingesting') && !(info_bit_flags & 0x02)) {
task_info.push({ value: 1, label: 'Ingests in progress' });
info_bit_flags |= 0x02;
}
if((task.ingest_status === 'ingested') && !(info_bit_flags & 0x04)) {
task_info.push({ value: 2, label: 'Successful ingests' });
info_bit_flags |= 0x04;
}
if((task.ingest_status === 'failed') && !(info_bit_flags & 0x08)) {
task_info.push({ value: 3, label: 'Failed ingests' });
info_bit_flags |= 0x08;
}
};
// sort on key values
function keysrt(key,desc) {
return function(a,b){
return desc ? ~~(a[key] < b[key]) : ~~(a[key] > b[key]);
}
}
task_info.sort(keysrt('value'));
fillColumFilterSelectOptions(task_info, $scope.columns[6]);
};
$scope.$watch('dataService.selected_task_ids', onSelectedTaskIdsChanged, true);
$scope.$watch('dataService.selected_project_id', function() {
fillProjectsColumFilterSelectOptions();
var project_col = $scope.gridApi.grid.columns.find(function(c) {return c.field == 'project_name'; });
if(project_col && project_col.filters.length) {
if(dataService.selected_project_id != undefined) {
var projectName = dataService.momProjectsDict[dataService.selected_project_id].name;
if(projectName != undefined) {
var project_names = project_col.filter.selectOptions.map(function(so) { return so.value;});
if(project_names.includes(projectName)) {
project_col.filters[0].term = projectName;
}
}
}
}
});
}]);
gridControllerMod.directive('contextMenu', ['$document', '$window', function($document, $window) {
return {
restrict: 'A',
scope: {
},
link: function($scope, $element, $attrs) {
function handleContextMenuEvent(event) {
//pragmatic 'hard-coded' way of getting the dataService and the rowEntity via scope tree.
var dataService = $scope.$parent.$parent.$parent.$parent.$parent.$parent.$parent.$parent.dataService;
var cleanupCtrl = $scope.$parent.$parent.$parent.$parent.$parent.$parent.$parent.$parent.$parent.cleanupCtrl;
var rowEntity = $scope.$parent.$parent.$parent.row.entity;
if(!dataService || !rowEntity)
return true;
var taskId = rowEntity.id;
var task = dataService.taskDict[taskId];
if(!task)
return true;
if(!dataService.isTaskIdSelected(taskId)) {
dataService.setSelectedTaskId(taskId);
}
var docElement = angular.element($document);
//search for already existing contextmenu element
while($document.find('#grid-context-menu').length) {
//found, remove it, so we can create a fresh one
$document.find('#grid-context-menu')[0].remove();
//unbind document close event handlers
docElement.unbind('click', closeContextMenu);
docElement.unbind('contextmenu', closeContextMenu);
}
//create contextmenu element
//with list of menu items,
//each with it's own action
var contextmenuElement = angular.element('<div id="grid-context-menu"></div>');
var ulElement = angular.element('<ul class="dropdown-menu" role="menu" style="left:' + event.clientX + 'px; top:' + event.clientY + 'px; z-index: 100000; display:block;"></ul>');
contextmenuElement.append(ulElement);
var selected_tasks = dataService.selected_task_ids.map(function(t_id) { return dataService.taskDict[t_id]; });
selected_tasks = selected_tasks.filter(function(t) { return t != undefined; });
var selected_cep4_tasks = selected_tasks.filter(function(t) { return t['cluster'] == 'CEP4'; });
// var liElement = angular.element('<li><a href="#">Copy Task</a></li>');
// ulElement.append(liElement);
// liElement.on('click', function() {
// closeContextMenu();
// //TODO: remove link to dataService in this generic plugin
// dataService.copyTask(task);
// });
var liElement = angular.element('<li><a href="#">Select group</a></li>');
ulElement.append(liElement);
liElement.on('click', function() {
closeContextMenu();
var dataCtrlScope = $scope.$parent.$parent.$parent.$parent.$parent.$parent.$parent.$parent.$parent.$parent;
dataCtrlScope.loadTasksByMoMGroupIdSelectAndJumpIntoView(task.mom_object_group_id);
});
var liElement = angular.element('<li><a href="#">Select parent group</a></li>');
ulElement.append(liElement);
liElement.on('click', function() {
closeContextMenu();
var dataCtrlScope = $scope.$parent.$parent.$parent.$parent.$parent.$parent.$parent.$parent.$parent.$parent;
dataCtrlScope.loadTasksByMoMParentGroupIdSelectAndJumpIntoView(task.mom_object_parent_group_id);
});
var blocked_selected_cep4_tasks = selected_cep4_tasks.filter(function(t) { return (t.blocked_by_ids.length > 0); });
if(blocked_selected_cep4_tasks.length > 0) {
var liContent = '<li><a href="#">Select blocking predecessor(s)</a></li>'
var liElement = angular.element(liContent);
ulElement.append(liElement);
liElement.on('click', function() {
closeContextMenu();
var blocking_predecessors = []
for(var task of blocked_selected_cep4_tasks) {
blocking_predecessors = blocking_predecessors.concat(task.blocked_by_ids);
}
var dataCtrlScope = $scope.$parent.$parent.$parent.$parent.$parent.$parent.$parent.$parent.$parent.$parent;
dataCtrlScope.loadTasksSelectAndJumpIntoView(blocking_predecessors);
});
}
if(task.type == 'observation' && dataService.config.inspection_plots_base_url) {
var liElement = angular.element('<li><a href="#">Inspection Plots</a></li>');
ulElement.append(liElement);
liElement.on('click', function() {
closeContextMenu();
var url = dataService.config.inspection_plots_base_url + '/' + task.otdb_id;
$window.open(url, '_blank');
});
}
var ingest_tasks = selected_tasks.filter(function(t) { return t.ingest_status != undefined; });
if(ingest_tasks.length > 0 && dataService.config.lta_base_url) {
var liElement = angular.element('<li><a href="#">Open in LTA catalogue</a></li>');
ulElement.append(liElement);
liElement.on('click', function() {
closeContextMenu();
//example: http://lofar.target.rug.nl/Lofar?mode=query_result_page_user&product=AveragingPipeline&ObservationId=544965&project=LC6_015
//map task.sub_type to url product parameter
var project2project2product2tasksDict = {};
for(var t of ingest_tasks) {
var lta_product;
switch(t.sub_type) {
case 'averaging_pipeline': lta_product = 'AveragingPipeline'; break;
case 'calibration_pipeline': lta_product = 'CalibrationPipeline'; break;
case 'pulsar_pipeline': lta_product = 'PulsarPipeline'; break;
case 'lofar_imaging_pipeline': lta_product = 'ImagingPipeline'; break;
case 'imaging_pipeline_msss': lta_product = 'ImagingPipeline'; break;
case 'long_baseline_pipeline': lta_product = 'LongBaselinePipeline'; break;
case 'lofar_observation': lta_product = 'Observation'; break;
}
if(lta_product) {
if(!project2project2product2tasksDict.hasOwnProperty(t.project_name)) {
project2project2product2tasksDict[t.project_name] = {};
}
if(!project2project2product2tasksDict[t.project_name].hasOwnProperty(lta_product)) {
project2project2product2tasksDict[t.project_name][lta_product] = [];
}
project2project2product2tasksDict[t.project_name][lta_product].push(t);
}
}
var window_cntr = 0;
for(var project in project2project2product2tasksDict) {
for(var product in project2project2product2tasksDict[project]) {
var product_tasks = project2project2product2tasksDict[project][product];
var otdb_ids = product_tasks.map(function(pt) { return pt.otdb_id; });
var otdb_ids_string = otdb_ids.join(',');
var url = dataService.config.lta_base_url + '/Lofar?mode=query_result_page_user&product=' + product + '&ObservationId=' + otdb_ids_string + '&project=' + project;
setTimeout(function(url_arg) {
$window.open(url_arg, '_blank');
}, window_cntr*250, url);
window_cntr += 1;
}
}
});
}
var liContent = selected_cep4_tasks.length == selected_tasks.length ? '<li><a href="#">Show disk usage</a></li>' : '<li><a href="#" style="color:#aaaaaa">Show disk usage</a></li>'
var liElement = angular.element(liContent);
ulElement.append(liElement);
if(selected_cep4_tasks.length == selected_tasks.length) {
liElement.on('click', function() {
closeContextMenu();
cleanupCtrl.showTaskDiskUsage(task);
});
}
var completed_selected_cep4_tasks = selected_cep4_tasks.filter(function(t) { return t.status == 'finished' || t.status == 'aborted'; });
var liContent = completed_selected_cep4_tasks.length == selected_tasks.length ? '<li><a href="#">Delete data</a></li>' : '<li><a href="#" style="color:#aaaaaa">Delete data</a></li>'
var liElement = angular.element(liContent);
ulElement.append(liElement);
if(completed_selected_cep4_tasks.length == selected_tasks.length) {
liElement.on('click', function() {
closeContextMenu();
cleanupCtrl.deleteSelectedTasksDataWithConfirmation();
});
}
var approved_selected_cep4_pipelines = selected_cep4_tasks.filter(function(t) { return t.status == 'approved' && t.type == 'pipeline'; });
if(approved_selected_cep4_pipelines.length > 0) {
var liContent = '<li><a href="#">Schedule approved CEP4 pipelines</a></li>'
var liElement = angular.element(liContent);
ulElement.append(liElement);
liElement.on('click', function() {
closeContextMenu();
for(var pl of approved_selected_cep4_pipelines) {
var newTask = { id: pl.id, status: 'prescheduled' };
dataService.putTask(newTask);
}
});
}
var scheduled_selected_cep4_pipelines = selected_cep4_tasks.filter(function(t) { return (t.status == 'prescheduled' || t.status == 'scheduled' || t.status == 'queued') && t.type == 'pipeline'; });
if(scheduled_selected_cep4_pipelines.length > 0) {
var liContent = '<li><a href="#">Unschedule (pre)scheduled/queued CEP4 pipelines</a></li>'
var liElement = angular.element(liContent);
ulElement.append(liElement);
liElement.on('click', function() {
closeContextMenu();
for(var pl of scheduled_selected_cep4_pipelines) {
if(pl.status == 'queued') {
var newTask = { id: pl.id, status: 'aborted' };
dataService.putTask(newTask);
}
var newTask = { id: pl.id, status: 'approved' };
dataService.putTask(newTask);
}
});
}
var active_selected_cep4_pipelines = selected_cep4_tasks.filter(function(t) { return (t.status == 'active' || t.status == 'completing') && t.type == 'pipeline'; });
if(active_selected_cep4_pipelines.length > 0) {
var liContent = '<li><a href="#">Abort active CEP4 pipelines</a></li>'
var liElement = angular.element(liContent);
ulElement.append(liElement);
liElement.on('click', function() {
closeContextMenu();
for(var pl of active_selected_cep4_pipelines) {
var newTask = { id: pl.id, status: 'aborted' };
dataService.putTask(newTask);
}
});
}
var aborted_selected_cep4_pipelines = selected_cep4_tasks.filter(function(t) { return (t.status == 'aborted' || t.status == 'error') && t.type == 'pipeline'; });
if(aborted_selected_cep4_pipelines.length > 0) {
var liContent = '<li><a href="#">Reschedule aborted/error CEP4 pipelines</a></li>'
var liElement = angular.element(liContent);
ulElement.append(liElement);
liElement.on('click', function() {
closeContextMenu();
for(var pl of aborted_selected_cep4_pipelines) {
var newTask = { id: pl.id, status: 'prescheduled' };
dataService.putTask(newTask);
}
});
}
var closeContextMenu = function(cme) {
contextmenuElement.remove();
//unbind document close event handlers
docElement.unbind('click', closeContextMenu);
docElement.unbind('contextmenu', closeContextMenu);
};
//click anywhere to remove the contextmenu
docElement.bind('click', closeContextMenu);
docElement.bind('contextmenu', closeContextMenu);
//add contextmenu to body
var body = $document.find('body');
body.append(contextmenuElement);
//prevent bubbling event upwards
return false;
}
$element.bind('contextmenu', handleContextMenuEvent);
$scope.$on('$destroy', function() {
$element.unbind('contextmenu', handleContextMenuEvent);
});
}
};
}]);