4062694ebe221d5bc712cb0e1d3f0d83d34caa71
[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 'use strict';
17
18 angular.module('ui.dashboard', ['ui.bootstrap', 'ui.sortable']);
19
20 angular.module('ui.dashboard')
21
22   .directive('dashboard', ['$http','WidgetModel', 'WidgetDefCollection', '$uibModal', 'DashboardState', '$log', function ($http, WidgetModel, WidgetDefCollection, $uibModal, DashboardState, $log) {
23
24     return {
25       restrict: 'A',
26       templateUrl: function(element, attr) {
27         return attr.templateUrl ? attr.templateUrl : 'app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboard/dashboard.html';
28       },
29       scope: true,
30
31       controller: ['$scope', '$attrs', function (scope, attrs) {
32         // default options
33         var defaults = {
34           stringifyStorage: true,
35           hideWidgetSettings: false,
36           hideWidgetClose: false,
37           settingsModalOptions: {
38             // templateUrl: 'app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboard/widget-settings-template.html',
39             templateUrl: 'app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboard/widget-settings-raptor-report-template.html',            
40             // controller: 'WidgetSettingsCtrl'
41             controller: 'WidgetSettingsRaptorReportCtrl'
42           },
43           onSettingsClose: function(result, widget) { // NOTE: dashboard scope is also passed as 3rd argument
44             jQuery.extend(true, widget, result);
45           },
46           onSettingsDismiss: function(reason) { // NOTE: dashboard scope is also passed as 2nd argument
47             $log.info('widget settings were dismissed. Reason: ', reason);
48           }
49         };
50         
51         scope.hoverEdit = false;
52         
53         scope.hoverIn = function(){
54                 this.hoverEdit = true;
55         };
56
57         scope.hoverOut = function(){
58                 this.hoverEdit = false;
59         };
60
61         // from dashboard="options"
62         scope.options = scope.$eval(attrs.dashboard);
63
64         // Deep options
65         scope.options.settingsModalOptions = scope.options.settingsModalOptions || {};
66         _.each(['settingsModalOptions'], function(key) {
67           // Ensure it exists on scope.options
68           scope.options[key] = scope.options[key] || {};
69           // Set defaults
70           _.defaults(scope.options[key], defaults[key]);
71         });
72
73         // Shallow options
74         _.defaults(scope.options, defaults);
75
76         // sortable options
77         var sortableDefaults = {
78           stop: function () {
79             scope.saveDashboard();
80           },
81           handle: '.widget-header',
82           distance: 5
83         };
84         scope.sortableOptions = angular.extend({}, sortableDefaults, scope.options.sortableOptions || {});
85
86       }],
87       link: function (scope) {
88
89         // Save default widget config for reset
90         scope.defaultWidgets = scope.options.defaultWidgets;
91
92         scope.widgetDefs = new WidgetDefCollection(scope.options.widgetDefinitions);
93         var count = 1;
94
95         // Instantiate new instance of dashboard state
96         scope.dashboardState = new DashboardState(
97           scope.options.storage,
98           scope.options.storageId,
99           scope.options.storageHash,
100           scope.widgetDefs,
101           scope.options.stringifyStorage
102         );
103
104         /**
105          * Instantiates a new widget on the dashboard
106          * @param {Object} widgetToInstantiate The definition object of the widget to be instantiated
107          */
108         scope.addWidget = function (widgetToInstantiate, doNotSave) {
109
110           if (typeof widgetToInstantiate === 'string') {
111             widgetToInstantiate = {
112               name: widgetToInstantiate
113             };
114           }
115
116           var defaultWidgetDefinition = scope.widgetDefs.getByName(widgetToInstantiate.name);
117           if (!defaultWidgetDefinition) {
118             throw 'Widget ' + widgetToInstantiate.name + ' is not found.';
119           }
120
121           // Determine the title for the new widget
122           var title;
123           if (!widgetToInstantiate.title && !defaultWidgetDefinition.title) {
124             widgetToInstantiate.title = 'Widget ' + count++;
125           }
126
127           // Instantiation
128           var widget = new WidgetModel(defaultWidgetDefinition, widgetToInstantiate);
129
130           // Add to the widgets array
131           scope.widgets.push(widget);
132           if (!doNotSave) {
133             scope.saveDashboard();
134           }
135
136           return widget;
137         };
138
139         /**
140          * Removes a widget instance from the dashboard
141          * @param  {Object} widget The widget instance object (not a definition object)
142          */
143         scope.removeWidget = function (widget) {
144           scope.widgets.splice(_.indexOf(scope.widgets, widget), 1);
145           scope.saveDashboard();
146         };
147
148         /**
149          * Opens a dialog for setting and changing widget properties
150          * @param  {Object} widget The widget instance object
151          */
152         scope.openWidgetSettings = function (widget) {
153 /*              console.log('======= widgets =======');
154                 console.log(widget);
155                 console.log('widget.report_id');
156           console.log(widget.report_id);
157 */
158                 if (widget.directive.includes("raptor-report")) {
159             var getFormFieldListUrl = "raptor.htm?action=report.run.container&c_master="+widget.report_id + "&refresh=Y";
160             $http.get(getFormFieldListUrl).then(
161               function(res){
162                 widget.reportData = res.data;                
163           });
164
165           // Set up $uibModal options 
166           var options = _.defaults(
167             { scope: scope },
168             widget.settingsModalOptions,
169             scope.options.settingsModalOptions);
170           
171 /*              console.log('======= options =======');
172         console.log(options);
173 */
174           // Ensure widget is resolved
175           options.resolve = {
176             widget: function () {
177               return widget;
178             }
179           };
180           
181           // Create the modal
182           var modalInstance = $uibModal.open(options);
183           var onClose = widget.onSettingsClose || scope.options.onSettingsClose;
184           var onDismiss = widget.onSettingsDismiss || scope.options.onSettingsDismiss;
185
186           // Set resolve and reject callbacks for the result promise
187           modalInstance.result.then(
188             function (result) {
189
190               // Call the close callback
191               onClose(result, widget, scope);
192
193               //AW Persist title change from options editor
194               scope.$emit('widgetChanged', widget);
195             },
196             function (reason) {
197               
198               // Call the dismiss callback
199               onDismiss(reason, scope);
200
201             }
202           );
203           
204                 }
205
206         };
207
208         /**
209          * Remove all widget instances from dashboard
210          */
211         scope.clear = function (doNotSave) {
212           scope.widgets = [];
213           if (doNotSave === true) {
214             return;
215           }
216           scope.saveDashboard();
217         };
218
219         /**
220          * Used for preventing default on click event
221          * @param {Object} event     A click event
222          * @param {Object} widgetDef A widget definition object
223          */
224         scope.addWidgetInternal = function (event, widgetDef) {
225 //          event.preventDefault();
226           scope.addWidget(widgetDef);
227         };
228         
229         /**
230          * Add report to dashboard
231          */
232         scope.popupAddReport = function () {
233                    var modalInstance = $uibModal.open({
234                                  animation: scope.animationsEnabled,
235                                  templateUrl: 'app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboard/add-raptor-report-template.html',
236                                  size:'sm',
237                                  controller: ['$scope', '$uibModalInstance', '$http', function ($scope, $uibModalInstance, $http) {
238                                          $scope.radioValue="chart"
239                                                         $http.get('raptor.htm?action=report.search.execute').then(
240                                                                         function(result){ 
241                                                                                 var data = result.data;
242                                                                                 var report_id_name = [];
243                                                                                 for (var i in data.rows[0]) {
244                                                                                         report_id_name.push({index:i, value: data.rows[0][i][1].searchresultField.displayValue, title: data.rows[0][i][2].searchresultField.displayValue})
245                                                                                         }
246                                                                                 $scope.raptorReportList = report_id_name;
247                                                                         });                                              
248                                          
249                                         $scope.ok = function() {
250                                                 scope.addReport($scope.selectedRaptorReport,$scope.radioValue);
251                                                 $uibModalInstance.close();
252                                                 };
253                                                 $scope.cancel = function() {
254                                           $uibModalInstance.dismiss();
255                                         };
256                             }]
257                           });
258                       modalInstance.result.then(function () {
259                           $scope.$emit('raptorReportWidgetAdded');                
260                       }, function () {
261                         $log.info('Modal dismissed at: ' + new Date());
262                       });
263                 };      
264
265                 
266             scope.popupAddRCloudNotebook = function () {
267                    var modalInstance = $uibModal.open({
268                                  animation: scope.animationsEnabled,
269                                  templateUrl: 'app/fusion/scripts/view-models/reportdashboard-page/src/components/directives/dashboard/add-rcloud-notebook-template.html',
270                                  size:'sm',
271                                  controller: ['$scope', '$uibModalInstance', '$http', function ($scope, $uibModalInstance, $http) {
272                                                 $scope.rcloud_url = ""
273                                                         
274                                         $scope.ok = function() {
275                                                 scope.addRCloudNotebook($scope.rcloud_url);
276                                                 $uibModalInstance.close();
277                                                 };
278                                                 $scope.cancel = function() {
279                                           $uibModalInstance.dismiss();
280                                         };
281                             }]
282                           });
283                       modalInstance.result.then(function () {
284                           $scope.$emit('raptorReportWidgetAdded');                
285                       }, function () {
286                         $log.info('Modal dismissed at: ' + new Date());
287                       });
288                 };              
289         
290         
291         scope.addReport = function (report1,radioValue) {
292                 scope.report1 =report1
293                 var raptor_report_type = "raptor-report-chart"
294                 if (radioValue ==='data') {
295                         raptor_report_type = 'raptor-report-data'
296                 } 
297                 console.log("report1")
298             console.log(report1);
299 //            event.preventDefault();
300             var newreport = {"title":report1.title,"name":raptor_report_type ,"style":{},"size":{"height":"350px","width":"40%"},"attrs":{"value":"randomValue"},"report_id":report1.value};
301             scope.addWidget(newreport, true); 
302             console.log("widgets");
303             console.log(scope.widgets);
304             ++scope.options.unsavedChangeCount;
305             return false;
306           };          
307           
308           /**
309            * Add rcloud notebook to dashboard
310            */
311           scope.addRCloudNotebook = function (rcloud_url) {
312                   ++scope.options.unsavedChangeCount;
313                   /* open a new prompt window */
314               //event.preventDefault();
315               var newreport = {"title":"R-Cloud","name":"r-cloud","style":{},"size":{"height":"450px","width":"40%"},"attrs":{"value":"randomValue"},"rcloud_url":rcloud_url};
316 //              console.log("newport");
317               console.log(newreport)
318               scope.addWidget(newreport, true); 
319   /*            scope.addWidget("raptor-report");*/
320               return false;
321             };
322           
323         /**
324          * Uses dashboardState service to save state
325          */
326         scope.saveDashboard = function (force) {
327           if (!scope.options.explicitSave) {
328             scope.dashboardState.save(scope.widgets);
329           } else {
330             if (!angular.isNumber(scope.options.unsavedChangeCount)) {
331               scope.options.unsavedChangeCount = 0;
332             }
333             if (force) {
334               scope.options.unsavedChangeCount = 0;
335               scope.dashboardState.save(scope.widgets);
336
337             } else {
338               ++scope.options.unsavedChangeCount;
339             }
340           }
341         };
342
343         /**
344          * Wraps saveDashboard for external use.
345          */
346         scope.externalSaveDashboard = function(force) {
347           if (angular.isDefined(force)) {
348             scope.saveDashboard(force);
349           } else {
350             scope.saveDashboard(true);
351           }
352         };
353
354         /**
355          * Clears current dash and instantiates widget definitions
356          * @param  {Array} widgets Array of definition objects
357          */
358         scope.loadWidgets = function (widgets) {
359           // AW dashboards are continuously saved today (no "save" button).
360                 console.log("widgets")
361            scope.defaultWidgets = widgets;              
362                         widgets =
363                                 [
364 //                              {"title":"DEMO Bar Chart","name":"raptor-report-chart","style":{},"size":{"height":"450px","width":"40%"},"attrs":{"value":"randomValue"},"report_id":"2"},
365 //                              {"title":"Pie Chart","name":"raptor-report-data","style":{},"size":{"height":"450px","width":"40%"},"attrs":{"value":"randomValue"},"report_id":"5"},
366 //                              {"title":"Pie Chart","name":"raptor-report-chart","style":{},"size":{"height":"450px","width":"40%"},"attrs":{"value":"randomValue"},"report_id":"5"}
367                                 ];
368                 console.log('widgets: ');
369                 console.log(JSON.stringify(widgets));
370                 
371                 scope.savedWidgetDefs = widgets;
372           scope.clear(true);
373           _.each(widgets, function (widgetDef) {
374             scope.addWidget(widgetDef, true);
375           });
376         };
377
378         /**
379          * Resets widget instances to default config
380          * @return {[type]} [description]
381          */
382         scope.resetWidgetsToDefault = function () {
383           scope.loadWidgets(scope.defaultWidgets);
384           scope.saveDashboard();
385         };
386
387         // Set default widgets array
388         var savedWidgetDefs = scope.dashboardState.load();
389
390         // Success handler
391         function handleStateLoad(saved) {
392           scope.options.unsavedChangeCount = 0;
393           if (saved && saved.length) {
394             scope.loadWidgets(saved);
395           } else if (scope.defaultWidgets) {
396             scope.loadWidgets(scope.defaultWidgets);
397           } else {
398             scope.clear(true);
399           }
400         }
401
402         if (angular.isArray(savedWidgetDefs)) {
403           handleStateLoad(savedWidgetDefs);
404         } else if (savedWidgetDefs && angular.isObject(savedWidgetDefs) && angular.isFunction(savedWidgetDefs.then)) {
405           savedWidgetDefs.then(handleStateLoad, handleStateLoad);
406         } else {
407           handleStateLoad();
408         }
409
410         // expose functionality externally
411         // functions are appended to the provided dashboard options
412         scope.options.addWidget = scope.addWidget;
413         scope.options.loadWidgets = scope.loadWidgets;
414         scope.options.saveDashboard = scope.externalSaveDashboard;
415         scope.options.removeWidget = scope.removeWidget;
416         scope.options.openWidgetSettings = scope.openWidgetSettings;
417         scope.options.clear = scope.clear;
418         scope.options.resetWidgetsToDefault = scope.resetWidgetsToDefault
419
420         // save state
421         scope.$on('widgetChanged', function (event) {
422           event.stopPropagation();
423           scope.saveDashboard();
424         });
425       }
426     };
427   }]);