From 0ada100fe0ecde98f23d66f4b11b2a04111d4f43 Mon Sep 17 00:00:00 2001
From: Jorrit Schaap <schaap@astron.nl>
Date: Tue, 10 May 2016 13:06:27 +0000
Subject: [PATCH] Task #9349: made contextmenu plugin for gantt. call copyTask
 via dataservice via webservice on menu click.

---
 .gitattributes                                |  1 +
 .../lib/CMakeLists.txt                        |  1 +
 .../static/app/controllers/datacontroller.js  |  7 ++
 .../app/controllers/ganttprojectcontroller.js | 56 ++++++++++--
 .../controllers/ganttresourcecontroller.js    | 52 +++++++++--
 .../angular-gantt-contextmenu-plugin.js       | 86 +++++++++++++++++++
 .../lib/templates/index.html                  |  3 +
 7 files changed, 192 insertions(+), 14 deletions(-)
 create mode 100644 SAS/ResourceAssignment/ResourceAssignmentEditor/lib/static/app/gantt-plugins/angular-gantt-contextmenu-plugin.js

diff --git a/.gitattributes b/.gitattributes
index 34409cbffb7..137391a8366 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -5060,6 +5060,7 @@ SAS/ResourceAssignment/ResourceAssignmentEditor/lib/static/app/controllers/datac
 SAS/ResourceAssignment/ResourceAssignmentEditor/lib/static/app/controllers/ganttprojectcontroller.js -text
 SAS/ResourceAssignment/ResourceAssignmentEditor/lib/static/app/controllers/ganttresourcecontroller.js -text
 SAS/ResourceAssignment/ResourceAssignmentEditor/lib/static/app/controllers/gridcontroller.js -text
+SAS/ResourceAssignment/ResourceAssignmentEditor/lib/static/app/gantt-plugins/angular-gantt-contextmenu-plugin.js -text
 SAS/ResourceAssignment/ResourceAssignmentEditor/lib/static/css/bootstrap.min.css -text
 SAS/ResourceAssignment/ResourceAssignmentEditor/lib/static/css/main.css -text
 SAS/ResourceAssignment/ResourceAssignmentEditor/lib/static/favicon.ico -text
diff --git a/SAS/ResourceAssignment/ResourceAssignmentEditor/lib/CMakeLists.txt b/SAS/ResourceAssignment/ResourceAssignmentEditor/lib/CMakeLists.txt
index 0e9c1f37a64..ffbddce6f5c 100644
--- a/SAS/ResourceAssignment/ResourceAssignmentEditor/lib/CMakeLists.txt
+++ b/SAS/ResourceAssignment/ResourceAssignmentEditor/lib/CMakeLists.txt
@@ -35,6 +35,7 @@ set(app_files
     static/app/controllers/ganttresourcecontroller.js
     static/app/controllers/chartresourceusagecontroller.js
     static/app/controllers/ganttprojectcontroller.js
+    static/app/gantt-plugins/angular-gantt-contextmenu-plugin.js
     static/css/main.css
     templates/index.html)
 
diff --git a/SAS/ResourceAssignment/ResourceAssignmentEditor/lib/static/app/controllers/datacontroller.js b/SAS/ResourceAssignment/ResourceAssignmentEditor/lib/static/app/controllers/datacontroller.js
index 0d773e2e956..f851a446570 100644
--- a/SAS/ResourceAssignment/ResourceAssignmentEditor/lib/static/app/controllers/datacontroller.js
+++ b/SAS/ResourceAssignment/ResourceAssignmentEditor/lib/static/app/controllers/datacontroller.js
@@ -254,6 +254,13 @@ angular.module('raeApp').factory("dataService", ['$http', '$q', function($http,
         })
     };
 
+    self.copyTask = function(task) {
+        $http.put('/rest/tasks/' + task.id + '/copy').error(function(result) {
+            console.log("Error. Could not copy task. " + result);
+            alert("Error: Could not copy task with mom id " + task.mom_id);
+        })
+    };
+
     self.computeMinMaxTaskTimes = function() {
         var starttimes = self.filteredTasks.map(function(t) { return t.starttime;});
         var endtimes = self.filteredTasks.map(function(t) { return t.endtime;});
diff --git a/SAS/ResourceAssignment/ResourceAssignmentEditor/lib/static/app/controllers/ganttprojectcontroller.js b/SAS/ResourceAssignment/ResourceAssignmentEditor/lib/static/app/controllers/ganttprojectcontroller.js
index 4ad95c83910..85782ee0c7e 100644
--- a/SAS/ResourceAssignment/ResourceAssignmentEditor/lib/static/app/controllers/ganttprojectcontroller.js
+++ b/SAS/ResourceAssignment/ResourceAssignmentEditor/lib/static/app/controllers/ganttprojectcontroller.js
@@ -13,7 +13,8 @@ var ganttProjectControllerMod = angular.module('GanttProjectControllerMod', [
                                         'gantt.groups',
                                         'gantt.dependencies',
                                         'gantt.overlap',
-                                        'gantt.resizeSensor']).config(['$compileProvider', function($compileProvider) {
+                                        'gantt.resizeSensor',
+                                        'gantt.contextmenu']).config(['$compileProvider', function($compileProvider) {
     $compileProvider.debugInfoEnabled(false); // Remove debug info (angularJS >= 1.3)
 }]);
 
@@ -48,34 +49,73 @@ ganttProjectControllerMod.controller('GanttProjectController', ['$scope', 'dataS
                 }
             );
 
-            api.directives.on.new($scope, function(directiveName, directiveScope, element) {
+            api.directives.on.new($scope, function(directiveName, directiveScope, directiveElement) {
                 if (directiveName === 'ganttRow' || directiveName === 'ganttRowLabel' ) {
-                    element.bind('click', function(event) {
+                    directiveElement.bind('click', function(event) {
                         if(directiveScope.row.model.project) {
                             $scope.dataService.selected_project_id = directiveScope.row.model.project.id;
                         }
                     });
                 } else if (directiveName === 'ganttTask') {
-                    element.bind('click', function(event) {
+                    directiveElement.bind('click', function(event) {
                         if(directiveScope.task.model.raTask) {
                             $scope.dataService.selected_task_id = directiveScope.task.model.raTask.id;
                         }
                     });
-                    element.bind('dblclick', function(event) {
+                    directiveElement.bind('dblclick', function(event) {
                         if(directiveScope.task.model.raTask) {
                             $scope.dataService.selected_task_id = directiveScope.task.model.raTask.id;
                             $scope.jumpToSelectedTasks();
                         }
                     });
+//                     directiveElement.bind('contextmenu', function(event) {
+//                         if(directiveScope.task.model.raTask) {
+//                             $scope.dataService.selected_task_id = directiveScope.task.model.raTask.id;
+//                         }
+//
+//                         //search for already existing contextmenu element
+//                         if(directiveElement.find('#gantt-project-context-menu').length) {
+//                             //found, remove it, so we can create a fresh one
+//                             directiveElement.find('#gantt-project-context-menu')[0].remove();
+//                         }
+//
+//                         //create contextmenu element
+//                         //with list of menu items,
+//                         //each with it's own action
+//                         var contextmenuElement = angular.element('<div id="gantt-project-context-menu"></div>');
+//                         ulElement = angular.element('<ul style="z-index:10000; position:fixed; top:initial; left:initial; display:block;" role="menu" class="dropdown-menu"></ul>');
+//                         contextmenuElement.append(ulElement);
+//                         liElement = angular.element('<li><a href="#">Copy Task</a></li>');
+//                         ulElement.append(liElement);
+//                         liElement.on('click', function() {
+//                             $scope.dataService.copyTask(directiveScope.task.model.raTask);
+//                             closeContextMenu();
+//                         });
+//
+//                         var closeContextMenu = function() {
+//                             contextmenuElement.remove();
+//                             angular.element(document).unbind('click', closeContextMenu);
+//                         };
+//
+//                         //click anywhere to remove the contextmenu
+//                         angular.element(document).bind('click', closeContextMenu);
+//
+//                         //add contextmenu to clicked element
+//                         directiveElement.append(contextmenuElement);
+//
+//                         //prevent bubbling event upwards
+//                         return false;
+//                     });
                 }
             });
 
-            api.directives.on.destroy($scope, function(directiveName, directiveScope, element) {
+            api.directives.on.destroy($scope, function(directiveName, directiveScope, directiveElement) {
                 if (directiveName === 'ganttRow' || directiveName === 'ganttRowLabel' || directiveName === 'ganttTask') {
-                    element.unbind('click');
+                    directiveElement.unbind('click');
                 }
                 if (directiveName === 'ganttTask') {
-                    element.unbind('dblclick');
+                    directiveElement.unbind('dblclick');
+//                     directiveElement.unbind('contextmenu');
                 }
             });
         }
diff --git a/SAS/ResourceAssignment/ResourceAssignmentEditor/lib/static/app/controllers/ganttresourcecontroller.js b/SAS/ResourceAssignment/ResourceAssignmentEditor/lib/static/app/controllers/ganttresourcecontroller.js
index f75da077ea7..a59b2b741f4 100644
--- a/SAS/ResourceAssignment/ResourceAssignmentEditor/lib/static/app/controllers/ganttresourcecontroller.js
+++ b/SAS/ResourceAssignment/ResourceAssignmentEditor/lib/static/app/controllers/ganttresourcecontroller.js
@@ -11,7 +11,8 @@ var ganttResourceControllerMod = angular.module('GanttResourceControllerMod', [
                                         'gantt.tree',
                                         'gantt.groups',
                                         'gantt.overlap',
-                                        'gantt.resizeSensor']).config(['$compileProvider', function($compileProvider) {
+                                        'gantt.resizeSensor',
+                                        'gantt.contextmenu']).config(['$compileProvider', function($compileProvider) {
     $compileProvider.debugInfoEnabled(false); // Remove debug info (angularJS >= 1.3)
 }]);
 
@@ -45,9 +46,9 @@ ganttResourceControllerMod.controller('GanttResourceController', ['$scope', 'dat
                     api.tasks.on.resizeEnd($scope, moveHandler);
             });
 
-            api.directives.on.new($scope, function(directiveName, directiveScope, element) {
+            api.directives.on.new($scope, function(directiveName, directiveScope, directiveElement) {
                 if (directiveName === 'ganttRow' || directiveName === 'ganttRowLabel' ) {
-                    element.bind('click', function(event) {
+                    directiveElement.bind('click', function(event) {
                         if(directiveScope.row.model.resource) {
                             $scope.dataService.selected_resource_id = directiveScope.row.model.resource.id;
                         } else if(directiveScope.row.model.resourceGroup) {
@@ -55,7 +56,7 @@ ganttResourceControllerMod.controller('GanttResourceController', ['$scope', 'dat
                         }
                     });
                 } else if (directiveName === 'ganttTask') {
-                    element.bind('click', function(event) {
+                    directiveElement.bind('click', function(event) {
                         if(directiveScope.task.model.raTask) {
                             $scope.dataService.selected_task_id = directiveScope.task.model.raTask.id;
                         }
@@ -63,12 +64,51 @@ ganttResourceControllerMod.controller('GanttResourceController', ['$scope', 'dat
                             $scope.dataService.selected_resourceClaim_id = directiveScope.task.model.claim.id;
                         }
                     });
+                    directiveElement.bind('contextmenu', function(event) {
+                        if(directiveScope.task.model.raTask) {
+                            $scope.dataService.selected_task_id = directiveScope.task.model.raTask.id;
+                        }
+
+                        //search for already existing contextmenu element
+                        if(directiveElement.find('#gantt-resource-context-menu').length) {
+                            //found, remove it, so we can create a fresh one
+                            directiveElement.find('#gantt-resource-context-menu')[0].remove();
+                        }
+
+                        //create contextmenu element
+                        //with list of menu items,
+                        //each with it's own action
+                        var contextmenuElement = angular.element('<div id="gantt-resource-context-menu"></div>');
+                        ulElement = angular.element('<ul style="z-index:10000; position:fixed; top:initial; left:initial; display:block;" role="menu" class="dropdown-menu"></ul>');
+                        contextmenuElement.append(ulElement);
+                        liElement = angular.element('<li><a href="#">Copy Task</a></li>');
+                        ulElement.append(liElement);
+                        liElement.on('click', function() {
+                            $scope.dataService.copyTask(directiveScope.task.model.raTask);
+                            closeContextMenu();
+                        });
+
+                        var closeContextMenu = function() {
+                            contextmenuElement.remove();
+                            angular.element(document).unbind('click', closeContextMenu);
+                        };
+
+                        //click anywhere to remove the contextmenu
+                        angular.element(document).bind('click', closeContextMenu);
+
+                        //add contextmenu to clicked element
+                        directiveElement.append(contextmenuElement);
+
+                        //prevent bubbling event upwards
+                        return false;
+                    });
                 }
             });
 
-            api.directives.on.destroy($scope, function(directiveName, directiveScope, element) {
+            api.directives.on.destroy($scope, function(directiveName, directiveScope, directiveElement) {
                 if (directiveName === 'ganttRow' || directiveName === 'ganttRowLabel' || directiveName === 'ganttTask') {
-                    element.unbind('click');
+                    directiveElement.unbind('click');
+                    directiveElement.unbind('contextmenu');
                 }
             });
         }
diff --git a/SAS/ResourceAssignment/ResourceAssignmentEditor/lib/static/app/gantt-plugins/angular-gantt-contextmenu-plugin.js b/SAS/ResourceAssignment/ResourceAssignmentEditor/lib/static/app/gantt-plugins/angular-gantt-contextmenu-plugin.js
new file mode 100644
index 00000000000..19280914c28
--- /dev/null
+++ b/SAS/ResourceAssignment/ResourceAssignmentEditor/lib/static/app/gantt-plugins/angular-gantt-contextmenu-plugin.js
@@ -0,0 +1,86 @@
+(function(){
+    'use strict';
+    angular.module('gantt.contextmenu', ['gantt', 'gantt.contextmenu.templates']).directive('ganttContextmenu', ['$compile', '$document', function($compile, $document) {
+        return {
+            restrict: 'E',
+            require: '^gantt',
+            scope: {
+                enabled: '=?'
+            },
+            link: function(scope, element, attrs, ganttCtrl) {
+                var api = ganttCtrl.gantt.api;
+
+                // Load options from global options attribute.
+                if (scope.options && typeof(scope.options.contextmenu) === 'object') {
+                    for (var option in scope.options.contextmenu) {
+                        scope[option] = scope.options[option];
+                    }
+                }
+
+                if (scope.enabled === undefined) {
+                    scope.enabled = true;
+                }
+
+                api.directives.on.new(scope, function(dName, dScope, dElement, dAttrs, dController) {
+                    //for each new ganttTask
+                    if (dName === 'ganttTask') {
+                        dElement.bind('contextmenu', function(event) {
+                            //TODO: remove link to dataService in this generic plugin
+                            var dataService = dScope.scope.dataService;
+
+                            if(dScope.task.model.raTask) {
+                                dataService.selected_task_id = dScope.task.model.raTask.id;
+                            }
+
+                            //search for already existing contextmenu element
+                            if(dElement.find('#gantt-context-menu').length) {
+                                //found, remove it, so we can create a fresh one
+                                dElement.find('#gantt-context-menu')[0].remove();
+                            }
+
+                            //create contextmenu element
+                            //with list of menu items,
+                            //each with it's own action
+                            var contextmenuElement = angular.element('<div id="gantt-context-menu"></div>');
+                            var ulElement = angular.element('<ul style="z-index:10000; position:fixed; top:initial; left:initial; display:block;" role="menu" class="dropdown-menu"></ul>');
+                            contextmenuElement.append(ulElement);
+                            var liElement = angular.element('<li><a href="#">Copy Task</a></li>');
+                            ulElement.append(liElement);
+                            liElement.on('click', function() {
+                                //TODO: remove link to dataService in this generic plugin
+                                dataService.copyTask(dScope.task.model.raTask);
+                                closeContextMenu();
+                            });
+
+                            var closeContextMenu = function() {
+                                contextmenuElement.remove();
+                                angular.element(document).unbind('click', closeContextMenu);
+                            };
+
+                            //click anywhere to remove the contextmenu
+                            angular.element(document).bind('click', closeContextMenu);
+
+                            //add contextmenu to clicked element
+                            dElement.append(contextmenuElement);
+
+                            //prevent bubbling event upwards
+                            return false;
+                        });
+                    }
+                });
+
+                api.directives.on.destroy(scope, function(dName, dScope, dElement, dAttrs, dController) {
+                    //for each destroyed ganttTask
+                    if (dName === 'ganttTask') {
+                        dElement.unbind('contextmenu');
+                    }
+                });
+            }
+        };
+    }]);
+}());
+
+angular.module('gantt.contextmenu.templates', []).run(['$templateCache', function($templateCache) {
+
+}]);
+
diff --git a/SAS/ResourceAssignment/ResourceAssignmentEditor/lib/templates/index.html b/SAS/ResourceAssignment/ResourceAssignmentEditor/lib/templates/index.html
index 214ea165b3b..4c1655f2932 100644
--- a/SAS/ResourceAssignment/ResourceAssignmentEditor/lib/templates/index.html
+++ b/SAS/ResourceAssignment/ResourceAssignmentEditor/lib/templates/index.html
@@ -40,6 +40,7 @@
     <script src="/static/app/controllers/gridcontroller.js"></script>
     <script src="/static/app/controllers/ganttresourcecontroller.js"></script>
     <script src="/static/app/controllers/ganttprojectcontroller.js"></script>
+    <script src="/static/app/gantt-plugins/angular-gantt-contextmenu-plugin.js"></script>
     <script src="/static/app/controllers/chartresourceusagecontroller.js"></script>
     </head>
     <body>
@@ -124,6 +125,7 @@
                                 </gantt-movable>
                                 <gantt-tooltips enabled="true" date-format="'YYYY-MM-DD HH:mm'"></gantt-tooltips>
                                 <gantt-dependencies enabled="true"></gantt-dependencies>
+                                <gantt-contextmenu enabled="true"></gantt-contextmenu>
                             </div>
                         </div>
                     </uib-tab>
@@ -144,6 +146,7 @@
                                     allow-resizing="true"
                                     allow-row-switching="false"></gantt-movable>
                                 <gantt-tooltips enabled="true" date-format="'YYYY-MM-DD HH:mm'"></gantt-tooltips>
+                                <gantt-contextmenu enabled="true"></gantt-contextmenu>
                             </div>
                         </div>
                     </uib-tab>
-- 
GitLab