From 45975f21c10dc9db61f2e89ed8de9f829af80c96 Mon Sep 17 00:00:00 2001 From: Till Breuer Date: Fri, 3 Jan 2014 12:55:08 +0100 Subject: [PATCH] Start rendering timelines table as angular-enhanced html template (WIP) --- .../controllers/timelines_controller.js | 2 +- .../timelines/timeline_directive.js | 50 +++++++++++++++---- .../timelines/tree_node_directive.js | 9 ++++ .../javascripts/angular/resources/timeline.js | 10 +++- .../timeline_components/tree_node.js | 8 ++- .../resources/timeline_components/ui.js | 1 - .../services/timeline_loader_service.js | 2 +- app/views/timelines/_chart_container.html | 1 + public/templates/timelines/tree.html | 28 +++++++++++ 9 files changed, 94 insertions(+), 17 deletions(-) create mode 100644 app/assets/javascripts/angular/directives/timelines/tree_node_directive.js create mode 100644 public/templates/timelines/tree.html diff --git a/app/assets/javascripts/angular/controllers/timelines_controller.js b/app/assets/javascripts/angular/controllers/timelines_controller.js index 5fc1d89004..a49ba4bac4 100644 --- a/app/assets/javascripts/angular/controllers/timelines_controller.js +++ b/app/assets/javascripts/angular/controllers/timelines_controller.js @@ -23,7 +23,7 @@ timelinesApp.controller('TimelinesController', ['$scope', '$window', 'Timeline', $scope.currentOutlineLevel = 'level3'; $scope.currentScaleName = 'monthly'; - // Load timeline + // Create timeline $scope.timeline = Timeline.create($scope.timelineOptions); // Container for timeline rendering diff --git a/app/assets/javascripts/angular/directives/timelines/timeline_directive.js b/app/assets/javascripts/angular/directives/timelines/timeline_directive.js index fe9288ed4c..52babfb037 100644 --- a/app/assets/javascripts/angular/directives/timelines/timeline_directive.js +++ b/app/assets/javascripts/angular/directives/timelines/timeline_directive.js @@ -9,9 +9,6 @@ timelinesApp.directive('timeline', function() { }; completeUI = function() { - // construct tree on left-hand-side. - scope.timeline.rebuildTree(); - // lift the curtain, paper otherwise doesn't show w/ VML. scope.underConstruction = false; scope.timeline.paper = new Raphael(scope.timeline.paperElement, 640, 480); @@ -50,16 +47,41 @@ timelinesApp.directive('timeline', function() { }); }; - drawTimeline = function(timeline){ + buildTree = function(timeline){ + if (timeline.isGrouping() && timeline.options.grouping_two_enabled) { + timeline.secondLevelGroupingAdjustments(); + } + + tree = timeline.getLefthandTree(); + + scope.availableRows = timeline.getAvailableRows(); + scope.nodes = flattenTree(tree); + scope.nodes.unshift(tree); + + return tree; + }; + + + flattenTree = function(tree) { + nodes = []; + + angular.forEach(tree.childNodes, function(node){ + nodes.push(node); + nodes = nodes.concat(flattenTree(node)); + }); + + return nodes; + }; + + drawTree = function(tree) { + console.log('-------- Draw tree --------'); + + timeline = scope.timeline; + try { window.clearTimeout(timeline.safetyHook); - if (timeline.isGrouping() && timeline.options.grouping_two_enabled) { - timeline.secondLevelGroupingAdjustments(); - } - - treeNode = timeline.getLefthandTree(); - if (treeNode.containsPlanningElements() || treeNode.containsProjects()) { + if (tree.containsPlanningElements() || tree.containsProjects()) { timeline.adjustForPlanningElements(); completeUI(); } else { @@ -68,11 +90,17 @@ timelinesApp.directive('timeline', function() { } catch (e) { timeline.die(e); } + }; // start timeline scope.timeline.registerTimelineContainer(element); - TimelineLoaderService.loadTimelineData(scope.timeline).then(drawTimeline); + TimelineLoaderService.loadTimelineData(scope.timeline) + .then(buildTree) + .then(drawTree) + .then(function(){ + scope.dataLoaded = true; + }); } }; }); diff --git a/app/assets/javascripts/angular/directives/timelines/tree_node_directive.js b/app/assets/javascripts/angular/directives/timelines/tree_node_directive.js new file mode 100644 index 0000000000..52a576a510 --- /dev/null +++ b/app/assets/javascripts/angular/directives/timelines/tree_node_directive.js @@ -0,0 +1,9 @@ +timelinesApp.directive('treeNode', function() { + return { + restrict: 'A', + scope: true, + link: function(scope, element, attributes) { + scope.node.dom_element = element; + } + }; +}); diff --git a/app/assets/javascripts/angular/resources/timeline.js b/app/assets/javascripts/angular/resources/timeline.js index 37a9a7ea41..29a7162ee9 100644 --- a/app/assets/javascripts/angular/resources/timeline.js +++ b/app/assets/javascripts/angular/resources/timeline.js @@ -626,7 +626,7 @@ timelinesApp.factory('Timeline', ['Constants', 'FilterQueryStringBuilder', 'Tree var tree = Object.create(Timeline.TreeNode); var parent_stack = []; - tree.setData(project); + tree.setData(project, 0); // there might not be any payload, due to insufficient rights and // the fact that some user with more rights originally created the @@ -637,6 +637,7 @@ timelinesApp.factory('Timeline', ['Constants', 'FilterQueryStringBuilder', 'Tree return tree; } + var level = 1; var count = 1; // for the given node, appends the given planning_elements as children, // recursively. every node will have the planning_element as data. @@ -657,9 +658,14 @@ timelinesApp.factory('Timeline', ['Constants', 'FilterQueryStringBuilder', 'Tree } } var newNode = Object.create(Timeline.TreeNode); - newNode.setData(e); + + newNode.setData(e, level); node.appendChild(newNode); + + level++; treeConstructor(newNode, newNode.getData().getSubElements()); + level--; + parent_stack.pop(); }); return node; diff --git a/app/assets/javascripts/angular/resources/timeline_components/tree_node.js b/app/assets/javascripts/angular/resources/timeline_components/tree_node.js index 8a9c762668..2daa4e0ed5 100644 --- a/app/assets/javascripts/angular/resources/timeline_components/tree_node.js +++ b/app/assets/javascripts/angular/resources/timeline_components/tree_node.js @@ -52,8 +52,14 @@ timelinesApp.factory('TreeNode', [function() { getData: function() { return this.payload; }, - setData: function(data) { + setData: function(data, level) { + this.text = data.subject || data.name; + if (data.is(Timeline.Project)) this.group = data.getFirstLevelGrouping(); + this.url = data.getUrl(); + this.payload = data; + this.level = level; + return this; }, appendChild: function(node) { diff --git a/app/assets/javascripts/angular/resources/timeline_components/ui.js b/app/assets/javascripts/angular/resources/timeline_components/ui.js index 91763072f2..d9b75b9c85 100644 --- a/app/assets/javascripts/angular/resources/timeline_components/ui.js +++ b/app/assets/javascripts/angular/resources/timeline_components/ui.js @@ -490,7 +490,6 @@ timelinesApp.factory('UI', [function() { window.clearTimeout(this.rebuildTimeout); this.rebuildTimeout = timeline.defer(function() { - timeline.rebuildTree(); // The minimum width of the whole timeline should be the actual // width of the table added to the minimum chart width. That way, diff --git a/app/assets/javascripts/angular/services/timeline_loader_service.js b/app/assets/javascripts/angular/services/timeline_loader_service.js index 326a15e63f..32e005397b 100644 --- a/app/assets/javascripts/angular/services/timeline_loader_service.js +++ b/app/assets/javascripts/angular/services/timeline_loader_service.js @@ -1114,7 +1114,7 @@ timelinesApp.service('TimelineLoaderService', ['$q', function($q) { timelineLoader.registerTimelineElements(); jQuery(timelineLoader).on('complete', function(e, data) { - jQuery.extend(timeline, data); + angular.extend(timeline, data); deferred.resolve(timeline); }); diff --git a/app/views/timelines/_chart_container.html b/app/views/timelines/_chart_container.html index 59be6e8973..f97f0825a2 100644 --- a/app/views/timelines/_chart_container.html +++ b/app/views/timelines/_chart_container.html @@ -13,6 +13,7 @@ + diff --git a/public/templates/timelines/tree.html b/public/templates/timelines/tree.html new file mode 100644 index 0000000000..27fa5e74c2 --- /dev/null +++ b/public/templates/timelines/tree.html @@ -0,0 +1,28 @@ + + + + + {{timeline.escape(node.payload.getFirstLevelGroupingName())}} + + + + + {{node.isExpanded() && '-' || '+'}} + + + + {{node.text}} + + + + + + + {{node[option]}} + + +