9ac57b19d43cb4aa9a85eab4df1765a776af0c09
[portal/sdk.git] /
1 /*
2  * Copyright (c) 2014 DataTorrent, Inc. ALL Rights Reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 'use strict';
18
19 angular.module('ui.dashboard')
20   .controller('DashboardWidgetCtrl', ['$scope', '$element', '$compile', '$window', '$timeout',
21     function($scope, $element, $compile, $window, $timeout) {
22
23       $scope.status = {
24         isopen: false
25       };
26
27       // Fills "container" with compiled view
28       $scope.makeTemplateString = function() {
29
30         var widget = $scope.widget;
31
32         // First, build template string
33         var templateString = '';
34
35         if (widget.templateUrl) {
36
37           // Use ng-include for templateUrl
38           templateString = '<div ng-include="\'' + widget.templateUrl + '\'"></div>';
39
40         } else if (widget.template) {
41
42           // Direct string template
43           templateString = widget.template;
44
45         } else {
46
47           // Assume attribute directive
48           templateString = '<div ' + widget.directive;
49
50           // Check if data attribute was specified
51           if (widget.dataAttrName) {
52             widget.attrs = widget.attrs || {};
53             widget.attrs[widget.dataAttrName] = 'widgetData';
54           }
55
56           // Check for specified attributes
57           if (widget.attrs) {
58
59             // First check directive name attr
60             if (widget.attrs[widget.directive]) {
61               templateString += '="' + widget.attrs[widget.directive] + '"';
62             }
63
64             // Add attributes
65             _.each(widget.attrs, function(value, attr) {
66
67               // make sure we aren't reusing directive attr
68               if (attr !== widget.directive) {
69                 templateString += ' ' + attr + '="' + value + '"';
70               }
71
72             });
73           }
74           templateString += '></div>';
75         }
76         return templateString;
77       };
78
79       $scope.grabResizer = function(e) {
80
81         var widget = $scope.widget;
82         var widgetElm = $element.find('.widget');
83
84         // ignore middle- and right-click
85         if (e.which !== 1) {
86           return;
87         }
88
89         e.stopPropagation();
90         e.originalEvent.preventDefault();
91
92         // get the starting horizontal position
93         var initX = e.clientX;
94         // console.log('initX', initX);
95
96         // Get the current width of the widget and dashboard
97         var pixelWidth = widgetElm.width();
98         var pixelHeight = widgetElm.height();
99         var widgetStyleWidth = widget.containerStyle.width;
100         var widthUnits = widget.widthUnits;
101         var unitWidth = parseFloat(widgetStyleWidth);
102
103         // create marquee element for resize action
104         var $marquee = angular.element('<div class="widget-resizer-marquee" style="height: ' + pixelHeight + 'px; width: ' + pixelWidth + 'px; z-index:'+ 200 +';"></div>');
105         widgetElm.append($marquee);
106         // create an overlaying div to block other widgets in order to stop their iframe events from being triggered
107         var $marquee2 = angular.element('<div style="  position: absolute; top: 0; left: 0; height: ' + pixelHeight + 'px; width: ' + (pixelWidth+200) + 'px; z-index:'+ 100 +';"></div>');
108         widgetElm.append($marquee2);
109         
110         // determine the unit/pixel ratio
111         var transformMultiplier = unitWidth / pixelWidth;
112
113         // updates marquee with preview of new width
114         var mousemove = function(e) {
115           var curX = e.clientX;
116 //          console.log(curX);
117 //          console.log(e);
118           var pixelChange = curX - initX;
119           var newWidth = pixelWidth + pixelChange;
120           $marquee.css('width', newWidth + 'px');
121           $marquee2.css('width', (newWidth + 200) + 'px');
122
123         };
124
125         // sets new widget width on mouseup
126         var mouseup = function(e) {
127           // remove listener and marquee
128           jQuery($window).off('mousemove', mousemove);
129           $marquee.remove();
130           $marquee2.remove();
131
132           // calculate change in units
133           var curX = e.clientX;
134           var pixelChange = curX - initX;
135           var unitChange = Math.round(pixelChange * transformMultiplier * 100) / 100;
136
137           // add to initial unit width
138           var newWidth = unitWidth * 1 + unitChange;
139           widget.setWidth(newWidth, widthUnits);
140           $scope.$emit('widgetChanged', widget);
141           $scope.$apply();
142           $scope.$broadcast('widgetResized', {
143             width: newWidth
144           });
145         };
146
147 //        jQuery($window).on('mousemove', mousemove).one('mouseup', mouseup);
148         jQuery($window).on('mousemove', mousemove).one('mouseup', mouseup);
149       };
150
151       //TODO refactor
152       $scope.grabSouthResizer = function(e) {
153         var widgetElm = $element.find('.widget');
154
155         // ignore middle- and right-click
156         if (e.which !== 1) {
157           return;
158         }
159
160         e.stopPropagation();
161         e.originalEvent.preventDefault();
162
163         // get the starting horizontal position
164         var initY = e.clientY;
165         // console.log('initX', initX);
166
167         // Get the current width of the widget and dashboard
168         var pixelWidth = widgetElm.width();
169         var pixelHeight = widgetElm.height();
170
171         // create marquee element for resize action
172         var $marquee = angular.element('<div class="widget-resizer-marquee" style="height: ' + pixelHeight + 'px; width: ' + pixelWidth + 'px;"></div>');
173         widgetElm.append($marquee);
174
175         // updates marquee with preview of new height
176         var mousemove = function(e) {
177           var curY = e.clientY;
178           var pixelChange = curY - initY;
179           var newHeight = pixelHeight + pixelChange;
180           $marquee.css('height', newHeight + 'px');
181         };
182
183         // sets new widget width on mouseup
184         var mouseup = function(e) {
185           // remove listener and marquee
186           jQuery($window).off('mousemove', mousemove);
187           $marquee.remove();
188
189           // calculate height change
190           var curY = e.clientY;
191           var pixelChange = curY - initY;
192
193           //var widgetContainer = widgetElm.parent(); // widget container responsible for holding widget width and height
194           var widgetContainer = widgetElm.find('.widget-content');
195
196           var diff = pixelChange;
197           var height = parseInt(widgetContainer.css('height'), 10);
198           var newHeight = (height + diff);
199
200           //$scope.widget.style.height = newHeight + 'px';
201
202           $scope.widget.setHeight(newHeight + 'px');
203
204           $scope.$emit('widgetChanged', $scope.widget);
205           $scope.$apply(); // make AngularJS to apply style changes
206
207           $scope.$broadcast('widgetResized', {
208             height: newHeight
209           });
210         };
211
212         jQuery($window).on('mousemove', mousemove).one('mouseup', mouseup);
213       };
214
215       // replaces widget title with input
216       $scope.editTitle = function(widget) {
217         var widgetElm = $element.find('.widget');
218         widget.editingTitle = true;
219         // HACK: get the input to focus after being displayed.
220         $timeout(function() {
221           widgetElm.find('form.widget-title input:eq(0)').focus()[0].setSelectionRange(0, 9999);
222         });
223       };
224
225       // saves whatever is in the title input as the new title
226       $scope.saveTitleEdit = function(widget) {
227         widget.editingTitle = false;
228         $scope.$emit('widgetChanged', widget);
229       };
230
231       $scope.compileTemplate = function() {
232         var container = $scope.findWidgetContainer($element);
233         var templateString = $scope.makeTemplateString();
234         var widgetElement = angular.element(templateString);
235
236         container.empty();
237         container.append(widgetElement);
238         $compile(widgetElement)($scope);
239       };
240
241       $scope.findWidgetContainer = function(element) {
242         // widget placeholder is the first (and only) child of .widget-content
243         return element.find('.widget-content');
244       };
245     }
246   ]);