diff --git a/app/assets/javascripts/angular/controllers/timelines_controller.js b/app/assets/javascripts/angular/controllers/timelines_controller.js index 8f9340da53..d9d2990469 100644 --- a/app/assets/javascripts/angular/controllers/timelines_controller.js +++ b/app/assets/javascripts/angular/controllers/timelines_controller.js @@ -16,55 +16,20 @@ openprojectApp.controller('TimelinesController', ['$scope', '$window', 'Timeline // Setup // Get server-side stuff into scope - $scope.currentTimelineId = gon.current_timeline_id; $scope.timelines = gon.timelines; + + $scope.currentTimelineId = gon.current_timeline_id; $scope.timelineOptions = gon.timeline_options; - // Get timelines stuff into scope and apply defaults - $scope.slider = null; + // Hide charts until tables are drawn $scope.underConstruction = true; - $scope.currentScaleName = 'monthly'; - // Create timeline + // Create timeline object $scope.timeline = Timeline.create($scope.timelineOptions); // Set initial expansion index $scope.timeline.expansionIndex = getInitialOutlineExpansion($scope.timelineOptions); - // Provide id for timeline container - $scope.timelineContainerNo = 1; - $scope.getTimelineContainerElementId = function() { - return 'timeline-container-' + $scope.timelineContainerNo; - }; - - $scope.$watch('currentScaleName', function(newScaleName, oldScaleName){ - if (newScaleName !== oldScaleName) { - $scope.currentScale = Timeline.ZOOM_CONFIGURATIONS[$scope.currentScaleName].scale; - $scope.timeline.scale = $scope.currentScale; - - $scope.currentScaleIndex = Timeline.ZOOM_SCALES.indexOf($scope.currentScaleName); - $scope.slider.slider('value', $scope.currentScaleIndex + 1); - - $scope.timeline.zoom($scope.currentScaleIndex); // TODO replace event-driven adaption by bindings - } - }); - - $scope.$watch('currentOutlineLevel', function(outlineLevel, formerLevel) { - if (outlineLevel !== formerLevel) { - $scope.timeline.expansionIndex = Timeline.OUTLINE_LEVELS.indexOf(outlineLevel); - $scope.timeline.expandToOutlineLevel(outlineLevel); // TODO replace event-driven adaption by bindings - } - }); - - $scope.increaseZoom = function() { - if($scope.currentScaleIndex < Object.keys(Timeline.ZOOM_CONFIGURATIONS).length - 1) { - $scope.currentScaleIndex++; - } - }; - $scope.decreaseZoom = function() { - if($scope.currentScaleIndex > 0) { - $scope.currentScaleIndex--; - } - }; - + // Count timeline containers + $scope.timelineContainerCount = 0; }]); diff --git a/app/assets/javascripts/angular/directives/timeline-container-directive.js b/app/assets/javascripts/angular/directives/timeline-container-directive.js index 9d1fe48b51..5b51989fb0 100644 --- a/app/assets/javascripts/angular/directives/timeline-container-directive.js +++ b/app/assets/javascripts/angular/directives/timeline-container-directive.js @@ -1,93 +1,11 @@ -openprojectApp.directive('timelineContainer', ['TimelineLoaderService', 'TimelineTableHelper', function(TimelineLoaderService, TimelineTableHelper) { +openprojectApp.directive('timelineContainer', [function() { return { restrict: 'E', replace: true, - templateUrl: '/templates/timelines/timeline_container.html', - link: function(scope, element, attributes) { - updateToolbar = function() { - scope.slider.slider('value', scope.timeline.zoomIndex + 1); - scope.currentOutlineLevel = Timeline.OUTLINE_LEVELS[scope.timeline.expansionIndex]; - scope.currentScaleName = Timeline.ZOOM_SCALES[scope.timeline.zoomIndex]; - }; - - completeUI = function() { - // lift the curtain, paper otherwise doesn't show w/ VML. - scope.underConstruction = false; - scope.timeline.paper = new Raphael(scope.timeline.paperElement, 640, 480); - - // perform some zooming. if there is a zoom level stored with the - // report, zoom to it. otherwise, zoom out. this also constructs - // timeline graph. - if (scope.timeline.options.zoom_factor && - scope.timeline.options.zoom_factor.length === 1) { - scope.timeline.zoom( - scope.timeline.pnum(scope.timeline.options.zoom_factor[0]) - ); - } else { - scope.timeline.zoomOut(); - } - - // perform initial outline expansion. - if (scope.timeline.options.initial_outline_expansion && - scope.timeline.options.initial_outline_expansion.length === 1) { - - scope.timeline.expandTo( - scope.timeline.pnum(scope.timeline.options.initial_outline_expansion[0]) - ); - } - - // zooming and initial outline expansion have consequences in the - // select inputs in the toolbar. - updateToolbar(); - - scope.timeline.getChart().scroll(function() { - scope.timeline.adjustTooltip(); - }); - - jQuery(window).scroll(function() { - scope.timeline.adjustTooltip(); - }); - }; - - buildWorkPackageTable = function(timeline){ - if (timeline.isGrouping() && timeline.options.grouping_two_enabled) { - timeline.secondLevelGroupingAdjustments(); - } - - tree = timeline.getLefthandTree(); - - if (tree.containsPlanningElements() || tree.containsProjects()) { - timeline.adjustForPlanningElements(); - scope.rows = TimelineTableHelper.getTableRowsFromTimelineTree(tree, timeline.options); - } else{ - scope.rows = []; - } - - return scope.rows; - }; - - drawChart = function(tree) { - timeline = scope.timeline; - - try { - window.clearTimeout(timeline.safetyHook); - - if (rows.length > 0) { - completeUI(); - } else { - timeline.warn(I18n.t('js.label_no_data'), 'warning'); - } - } catch (e) { - timeline.die(e); - } - }; - - // start timeline - scope.timeline.registerTimelineContainer(element); - - TimelineLoaderService.loadTimelineData(scope.timeline) - .then(buildWorkPackageTable) - .then(drawChart); + transclude: true, + template: '
', + link: function(scope) { + scope.timelineContainerElementId = 'timeline-container-' + (++scope.timelineContainerCount); } }; }]); diff --git a/app/assets/javascripts/angular/directives/timeline-table-container-directive.js b/app/assets/javascripts/angular/directives/timeline-table-container-directive.js new file mode 100644 index 0000000000..2cd447330f --- /dev/null +++ b/app/assets/javascripts/angular/directives/timeline-table-container-directive.js @@ -0,0 +1,87 @@ +openprojectApp.directive('timelineTableContainer', ['TimelineLoaderService', 'TimelineTableHelper', function(TimelineLoaderService, TimelineTableHelper) { + return { + restrict: 'E', + replace: true, + templateUrl: '/templates/timelines/timeline_table_container.html', + link: function(scope, element, attributes) { + completeUI = function() { + // lift the curtain, paper otherwise doesn't show w/ VML. + scope.underConstruction = false; + scope.timeline.paper = new Raphael(scope.timeline.paperElement, 640, 480); + + // perform some zooming. if there is a zoom level stored with the + // report, zoom to it. otherwise, zoom out. this also constructs + // timeline graph. + if (scope.timeline.options.zoom_factor && + scope.timeline.options.zoom_factor.length === 1) { + scope.timeline.zoom( + scope.timeline.pnum(scope.timeline.options.zoom_factor[0]) + ); + } else { + scope.timeline.zoomOut(); + } + + // perform initial outline expansion. + if (scope.timeline.options.initial_outline_expansion && + scope.timeline.options.initial_outline_expansion.length === 1) { + + scope.timeline.expandTo( + scope.timeline.pnum(scope.timeline.options.initial_outline_expansion[0]) + ); + } + + // zooming and initial outline expansion have consequences in the + // select inputs in the toolbar. + if(scope.updateToolbar) scope.updateToolbar(); + + scope.timeline.getChart().scroll(function() { + scope.timeline.adjustTooltip(); + }); + + jQuery(window).scroll(function() { + scope.timeline.adjustTooltip(); + }); + }; + + buildWorkPackageTable = function(timeline){ + if (timeline.isGrouping() && timeline.options.grouping_two_enabled) { + timeline.secondLevelGroupingAdjustments(); + } + + tree = timeline.getLefthandTree(); + + if (tree.containsPlanningElements() || tree.containsProjects()) { + timeline.adjustForPlanningElements(); + scope.rows = TimelineTableHelper.getTableRowsFromTimelineTree(tree, timeline.options); + } else{ + scope.rows = []; + } + + return scope.rows; + }; + + drawChart = function(tree) { + timeline = scope.timeline; + + try { + window.clearTimeout(timeline.safetyHook); + + if (rows.length > 0) { + completeUI(); + } else { + timeline.warn(I18n.t('js.label_no_data'), 'warning'); + } + } catch (e) { + timeline.die(e); + } + }; + + // start timeline + scope.timeline.registerTimelineContainer(element); + + TimelineLoaderService.loadTimelineData(scope.timeline) + .then(buildWorkPackageTable) + .then(drawChart); + } + }; +}]); diff --git a/app/assets/javascripts/angular/directives/timeline-toolbar-directive.js b/app/assets/javascripts/angular/directives/timeline-toolbar-directive.js new file mode 100644 index 0000000000..a454f65702 --- /dev/null +++ b/app/assets/javascripts/angular/directives/timeline-toolbar-directive.js @@ -0,0 +1,47 @@ +openprojectApp.directive('timelineToolbar', [function() { + + return { + restrict: 'E', + replace: true, + templateUrl: '/templates/timelines/toolbar.html', + link: function(scope) { + scope.currentScaleName = 'monthly'; + + scope.updateToolbar = function() { + scope.slider.slider('value', scope.timeline.zoomIndex + 1); + scope.currentOutlineLevel = Timeline.OUTLINE_LEVELS[scope.timeline.expansionIndex]; + scope.currentScaleName = Timeline.ZOOM_SCALES[scope.timeline.zoomIndex]; + }; + + scope.increaseZoom = function() { + if(scope.currentScaleIndex < Object.keys(Timeline.ZOOM_CONFIGURATIONS).length - 1) { + scope.currentScaleIndex++; + } + }; + scope.decreaseZoom = function() { + if(scope.currentScaleIndex > 0) { + scope.currentScaleIndex--; + } + }; + + scope.$watch('currentScaleName', function(newScaleName, oldScaleName){ + if (newScaleName !== oldScaleName) { + scope.currentScale = Timeline.ZOOM_CONFIGURATIONS[scope.currentScaleName].scale; + scope.timeline.scale = scope.currentScale; + + scope.currentScaleIndex = Timeline.ZOOM_SCALES.indexOf(scope.currentScaleName); + scope.slider.slider('value', scope.currentScaleIndex + 1); + + scope.timeline.zoom(scope.currentScaleIndex); // TODO replace event-driven adaption by bindings + } + }); + + scope.$watch('currentOutlineLevel', function(outlineLevel, formerLevel) { + if (outlineLevel !== formerLevel) { + scope.timeline.expansionIndex = Timeline.OUTLINE_LEVELS.indexOf(outlineLevel); + scope.timeline.expandToOutlineLevel(outlineLevel); // TODO replace event-driven adaption by bindings + } + }); + } + }; +}]); diff --git a/app/assets/javascripts/angular/services/timeline-loader-service.js b/app/assets/javascripts/angular/services/timeline-loader-service.js index 5137cef6f1..b9286938f0 100644 --- a/app/assets/javascripts/angular/services/timeline-loader-service.js +++ b/app/assets/javascripts/angular/services/timeline-loader-service.js @@ -197,8 +197,6 @@ openprojectApp.service('TimelineLoaderService', ['$q', 'FilterQueryStringBuilder - - var DataEnhancer = function (timeline) { this.timeline = timeline; diff --git a/app/views/timelines/_timeline.html.erb b/app/views/timelines/_timeline.html.erb index 891bda9849..308b7c4916 100644 --- a/app/views/timelines/_timeline.html.erb +++ b/app/views/timelines/_timeline.html.erb @@ -27,10 +27,10 @@ See doc/COPYRIGHT.rdoc for more details. ++#%> -
- <%= render 'toolbar' %> - -
+ + + + <% unless User.current.impaired? %> <%# TODO: Require autocompleter inside select_boxes.js diff --git a/public/templates/timelines/timeline_container.html b/public/templates/timelines/timeline_table_container.html similarity index 100% rename from public/templates/timelines/timeline_container.html rename to public/templates/timelines/timeline_table_container.html diff --git a/app/views/timelines/_toolbar.html b/public/templates/timelines/toolbar.html similarity index 100% rename from app/views/timelines/_toolbar.html rename to public/templates/timelines/toolbar.html