Yangman - delayed progress bar is displayed
[dlux.git] / modules / yangman-resources / src / main / resources / yangman / controllers / request-header.controller.js
1 define([
2     'app/yangman/controllers/params-admin.controller',
3     'app/yangman/services/time-tracking.services',
4 ], function (ParamsAdminCtrl) {
5     'use strict';
6
7     angular.module('app.yangman').controller('RequestHeaderCtrl', RequestHeaderCtrl);
8
9     RequestHeaderCtrl.$inject = [
10         '$timeout', '$mdDialog', '$mdToast', '$scope', '$rootScope', 'ENV', 'YangmanService', 'ParametersService',
11         'PathUtilsService', 'RequestsService', '$filter', 'DataBackupService', 'constants', 'TimeTrackingService'
12     ];
13
14     function RequestHeaderCtrl($timeout, $mdDialog, $mdToast, $scope, $rootScope, ENV, YangmanService, ParametersService,
15                                PathUtilsService, RequestService, $filter, DataBackupService, constants,
16                                TimeTrackingService) {
17         var requestHeader = this;
18
19         requestHeader.allOperations = [constants.OPERATION_GET, constants.OPERATION_POST, constants.OPERATION_PUT, constants.OPERATION_DELETE];
20         requestHeader.constants = constants;
21         requestHeader.urlChanged = false;
22         requestHeader.executedOperation = null;
23         requestHeader.selectedOperationsList = [];
24         requestHeader.selectedOperation = null;
25         requestHeader.requestUrl = '';
26         requestHeader.selectedPluginsButtons = [];
27         requestHeader.selectedPlugin = null;
28         requestHeader.statusObj = null;
29
30         // methods
31         requestHeader.executeOperation = executeOperation;
32         requestHeader.executePluginFunctionality = executePluginFunctionality;
33         requestHeader.fillNodeData = fillNodeData;
34         requestHeader.changeDataType = changeDataType;
35         requestHeader.prepareDataAndExecute = prepareDataAndExecute;
36         requestHeader.initMountPoint = initMountPoint;
37         requestHeader.setJsonView = setJsonView;
38         requestHeader.setRequestUrl = setRequestUrl;
39         requestHeader.showParamsAdmin = showParamsAdmin;
40         requestHeader.saveRequestToCollection = saveRequestToCollection;
41         requestHeader.unsetPluginFunctionality = unsetPluginFunctionality;
42
43         // watchers
44         /**
45          * Set selected operations based on data store
46          */
47         $scope.$on(constants.SET_SEL_OPERATIONS, function (event, operations, setUrl) {
48             setAllowedMethods(operations);
49
50             if ( setUrl ) {
51                 setRequestUrl();
52             }
53         });
54
55         /**
56          * Watching for changes in shown detail data type (radio button)
57          */
58         $scope.$on(constants.YANGMAN_HEADER_INIT, function (event, args) {
59             init();
60             setRequestUrl(args.params.path);
61             setRequestMethod(args.params.method);
62             setRequestStatus(args.params.statusObj);
63             setJsonView();
64             (args.cbk || angular.noop)();
65         });
66
67         $scope.$on(constants.YANGMAN_FILL_NODE_FROM_REQ, function (event, args) {
68             setNodeDataFromRequestData(args.params.requestUrl, args.params.leftpanel);
69             (args.cbk || angular.noop)();
70         });
71
72         $scope.$on(constants.YANGMAN_EXECUTE_WITH_DATA, function (event, args) {
73             executeOperation(args.params.data ? angular.fromJson(args.params.data) : {}, args.cbk);
74         });
75
76         init();
77
78         /**
79          * Setter for selected operation
80          * @param method
81          */
82         function setRequestMethod(method){
83             requestHeader.selectedOperation = method;
84         }
85
86         /**
87          * Setter for request status
88          * @param statusObj
89          */
90         function setRequestStatus(statusObj){
91             requestHeader.statusObj = statusObj;
92         }
93
94         /**
95          * Show popup for parameters administration
96          * @param event
97          */
98         function showParamsAdmin(event) {
99             $mdDialog.show({
100                 controller: ParamsAdminCtrl,
101                 controllerAs: 'paramsAdmin',
102                 templateUrl: $scope.globalViewPath + 'popup/parameters-admin.tpl.html',
103                 parent: angular.element('#yangmanModule'),
104                 targetEvent: event,
105                 clickOutsideToClose: true,
106                 locals: {
107                     parametersList: $scope.parametersList,
108                 },
109             }).then(
110                 function (){
111                     $scope.parametersList.loadListFromStorage();
112                 },
113                 function (){
114                     $scope.parametersList.loadListFromStorage();
115                 }
116             );
117         }
118
119         /**
120          * Method for selecting correct json view by selected operation
121          */
122         function setJsonView(){
123             var both = [constants.OPERATION_PUT, constants.OPERATION_POST];
124
125             if ( both.indexOf(requestHeader.selectedOperation) > -1 ){
126                 $scope.setJsonView(true, true);
127             } else {
128                 $scope.setJsonView(true, false);
129             }
130         }
131
132         /**
133          * Change displayed data type to json or form, after switching set current data to be displayed
134          */
135         function changeDataType(){
136             $scope.switchSection('rightPanelSection', requestHeader.selectedShownDataType);
137
138             if(!$scope.node || requestHeader.urlChanged) {
139                 requestHeader.setRequestUrl();
140                 requestHeader.urlChanged = false;
141             }
142
143             // if changing to json, fill codemirror data
144             if ( requestHeader.selectedShownDataType === constants.DISPLAY_TYPE_REQ_DATA && $scope.node ){
145                 setJsonView();
146                 sendRequestData($scope.buildRootRequest(), 'SENT');
147             }
148
149             // if changing to form, try to fill node data
150             if (requestHeader.selectedShownDataType === constants.DISPLAY_TYPE_FORM) {
151                 var reqData = {};
152
153                 reqData = getDataForForm();
154                 setNodeDataFromRequestData(requestHeader.requestUrl);
155
156                 if ( $scope.node ) {
157
158                     YangmanService.fillNodeFromResponse($scope.node, reqData);
159                     $scope.node.expanded = true;
160                 }
161             }
162         }
163
164         /**
165          * Helper method for building correct json data for form, rpc included
166          * @returns {*}
167          */
168         function getDataForForm(){
169             var params = {
170                     reqData: null,
171                 },
172                 dataTypeFunc = {
173                     rpc: function () {
174                         var sentData = { reqData: null },
175                             allData = { sent: null, received: null };
176
177                         $scope.rootBroadcast(constants.YANGMAN_GET_CODEMIRROR_DATA_RECEIVED, params);
178                         $scope.rootBroadcast(constants.YANGMAN_GET_CODEMIRROR_DATA_SENT, sentData);
179
180                         allData.sent = sentData.reqData ? angular.fromJson(sentData.reqData) : {};
181                         allData.received = params.reqData ? angular.fromJson(params.reqData) : {};
182
183                         return YangmanService.prepareReceivedData(
184                             $scope.node,
185                             requestHeader.selectedOperation,
186                             allData.received,
187                             allData.sent,
188                             requestHeader.selectedShownDataType
189                         );
190                     },
191                     default: function (){
192                         var dataType;
193                         if(requestHeader.executedOperation) {
194                             dataType = requestHeader.executedOperation === constants.OPERATION_GET ? constants.REQUEST_DATA_TYPE_RECEIVED : 'SENT';
195                         }
196                         else {
197                             dataType = requestHeader.selectedOperation === constants.OPERATION_GET ? constants.REQUEST_DATA_TYPE_RECEIVED : 'SENT';
198                         }
199
200                         $scope.rootBroadcast(constants.YANGMAN_GET_CODEMIRROR_DATA + dataType, params);
201                         return params.reqData ? angular.fromJson(params.reqData) : {};
202                     },
203                 };
204
205             return $scope.node ? (dataTypeFunc[$scope.node.type] || dataTypeFunc.default)() : {};
206         }
207
208         /**
209          * Send data to codemirror
210          * @param data
211          */
212         function sendRequestData(data, type){
213             $scope.rootBroadcast(
214                 constants.YANGMAN_SET_CODEMIRROR_DATA + type,
215                 { data: data instanceof Object ? JSON.stringify(data, null, 4) : data }
216             );
217         }
218
219         function sendErrorData(response) {
220             $scope.rootBroadcast(constants.YANGMAN_SET_ERROR_DATA, response);
221         }
222
223         /**
224          * Create empty parameters list, load from local storage and set to $scope
225          */
226         function initParams(){
227             $scope.parametersList.loadListFromStorage();
228         }
229
230         /**
231          * Initialization
232          */
233         function init(){
234             setAllowedMethods(requestHeader.allOperations);
235             initParams();
236             requestHeader.selectedShownDataType = $scope.rightPanelSection;
237         }
238
239         /**
240          * Set allowed operations for request
241          * @param operations
242          */
243         function setAllowedMethods(operations){
244             requestHeader.selectedOperationsList = operations.length ? operations : requestHeader.allOperations;
245             if (operations.indexOf(requestHeader.selectedOperation) === -1){
246                 requestHeader.selectedOperation = requestHeader.selectedOperationsList[0];
247             }
248         }
249
250         /**
251          * Set header request url if json selected
252          */
253         function setRequestUrl(path){
254             requestHeader.requestUrl = path || ($scope.selectedSubApi ?
255                     ENV.getBaseURL('MD_SAL') + '/restconf/' + $scope.selectedSubApi.buildApiRequestString() : '');
256         }
257
258
259         /**
260          * Try to set api, module, dataStore and node, if api indexes for request url available
261          * and set (or unset) module detail panel to be displayed
262          * @param requestUrl url to try to find
263          * @param leftpanel index of main left tabs to be displayed (we dont want to display module detail in all cases)
264          */
265         function setNodeDataFromRequestData(requestUrl, leftpanel){
266
267             setApiByUrl(requestUrl, function (treeApis) {
268                 // set module
269                 $scope.setModule($filter('filter')(treeApis, { label: $scope.selectedApi.module })[0]);
270
271                 // set datastore
272                 $scope.setDataStore(
273                     $filter('filter')(
274                         $scope.selectedModule.children,
275                         { label: $scope.selectedSubApi.storage })[0],
276                     true,
277                     leftpanel
278                 );
279
280                 // set node
281                 $scope.setNode($scope.selectedSubApi.node);
282
283                 // fill subapi path
284                 PathUtilsService.fillPath($scope.selectedSubApi.pathArray, requestUrl);
285                 setRequestUrl();
286             });
287         }
288
289         /**
290          * Try to set current (depending on url) selectedApi and selectedSubApi to $scope if it exists in api tree data
291          * @param url
292          * @param cbk
293          * @param fill
294          */
295         function setApiByUrl(url, cbk, fill){
296             $scope.rootBroadcast(constants.YANGMAN_GET_API_TREE_DATA, null, function (treeApis) {
297                 var apisIndexes =
298                     PathUtilsService.searchNodeByPath(url, treeApis, null, true, true);
299
300                 if ( apisIndexes ) {
301
302                     // set apis
303                     $scope.setApi(
304                         $scope.apis[apisIndexes.indexApi],
305                         $scope.apis[apisIndexes.indexApi].subApis[apisIndexes.indexSubApi]
306                     );
307
308                     if ( $scope.selectedSubApi && fill ) {
309                         var updatedUrl = YangmanService.cutUrl(url);
310                         PathUtilsService.fillPath($scope.selectedSubApi.pathArray, updatedUrl);
311
312                     }
313
314                     (cbk || angular.noop)(treeApis);
315                 }
316             });
317         }
318
319         function saveRequestToCollection(event) {
320             var historyReq = null,
321                 sentData = { reqData: null },
322                 receivedData = { reqData: null };
323
324             if (requestHeader.selectedShownDataType === constants.DISPLAY_TYPE_FORM) {
325                 requestHeader.setRequestUrl();
326             }
327
328             historyReq = RequestService.createHistoryRequest(
329                 null, null, requestHeader.requestUrl, requestHeader.selectedOperation, '', '', ''
330             );
331
332             $scope.rootBroadcast(constants.YANGMAN_GET_CODEMIRROR_DATA_SENT, sentData);
333             $scope.rootBroadcast(constants.YANGMAN_GET_CODEMIRROR_DATA_RECEIVED, receivedData);
334
335             RequestService.fillRequestByMethod(
336                 historyReq, sentData, receivedData, requestHeader.selectedOperation, $scope.node,
337                 requestHeader.selectedShownDataType
338             );
339
340             $scope.rootBroadcast(constants.YANGMAN_SAVE_REQUEST_TO_COLLECTION, { event: event, reqObj: historyReq });
341         }
342
343         function showRequestProgress(){
344             $scope.rootBroadcast(constants.YANGMAN_EXECUTING_REQUEST_PROGRESS_START);
345         }
346
347
348         function finishRequestProgress(message){
349             $scope.rootBroadcast(constants.YANGMAN_EXECUTING_REQUEST_PROGRESS_STOP);
350         }
351
352         /**
353          * Execute request operation
354          */
355         function executeOperation(requestData, executeCbk){
356             TimeTrackingService.startTimer();
357             var allowExecuteOperation =
358                 requestHeader.selectedShownDataType === constants.DISPLAY_TYPE_FORM && $scope.selectedSubApi ?
359                     !PathUtilsService.checkEmptyIdentifiers($scope.selectedSubApi.pathArray) : true;
360
361
362             if ( allowExecuteOperation ) {
363
364                 showRequestProgress();
365                 $scope.rootBroadcast(constants.YANGMAN_SET_ERROR_MESSAGE, '');
366
367                 setRequestUrl(
368                     requestHeader.selectedShownDataType === constants.DISPLAY_TYPE_REQ_DATA ?
369                         requestHeader.requestUrl :
370                         null
371                 );
372                 if ( requestHeader.selectedShownDataType === constants.DISPLAY_TYPE_REQ_DATA ){
373                     setApiByUrl(requestHeader.requestUrl, null, true);
374                 }
375
376                 var historyReq = RequestService.createHistoryRequest(
377                     null,
378                     null,
379                     requestHeader.requestUrl,
380                     requestHeader.selectedOperation,
381                     '', '', ''
382                 );
383
384                 YangmanService.executeRequestOperation(
385                     $scope.selectedApi,
386                     $scope.selectedSubApi,
387                     requestHeader.selectedOperation,
388                     $scope.node,
389                     requestHeader.selectedShownDataType,
390                     requestHeader.requestUrl,
391                     requestData,
392                     $scope.parametersList,
393                     executeReqSuccCbk,
394                     executeReqErrCbk
395                 );
396                 requestHeader.executedOperation = requestHeader.selectedOperation;
397             } else {
398                 $scope.rootBroadcast(
399                     constants.YANGMAN_SET_ERROR_MESSAGE,
400                     $filter('translate')(constants.YANGMAN_ERROR_EMPTY_IDENTIFIERS)
401                 );
402                 finishRequestProgress();
403             }
404
405             /**
406              * Success callback after executin operation
407              * @param reqInfo
408              * @param response
409              */
410             function executeReqSuccCbk(reqInfo, response) {
411
412                 var preparedReceivedData = YangmanService.prepareReceivedData(
413                     $scope.node,
414                     requestHeader.selectedOperation,
415                     response.data ? response.data.plain() : {},
416                     reqInfo.requestSrcData,
417                     requestHeader.selectedShownDataType
418                 );
419
420                 finishRequestProgress();
421
422                 requestHeader.statusObj = reqInfo;
423
424                 sendErrorData({});
425
426                 if (requestHeader.selectedShownDataType === constants.DISPLAY_TYPE_REQ_DATA){
427
428                     setNodeDataFromRequestData(requestHeader.requestUrl);
429                     sendRequestData(preparedReceivedData, constants.REQUEST_DATA_TYPE_RECEIVED);
430                     sendRequestData(reqInfo.requestSrcData || {}, 'SENT');
431                 } else {
432
433                     if ($scope.node && requestHeader.selectedOperation !== constants.OPERATION_DELETE){
434
435                         YangmanService.fillNodeFromResponse($scope.node, preparedReceivedData);
436                         YangmanService.handleNodeIdentifier(
437                             $scope.parametersList, $scope.selectedSubApi, $scope.node
438                         );
439                         $scope.node.expanded = true;
440
441                         $scope.rootBroadcast(constants.YANGMAN_DISABLE_ADDING_LIST_ELEMENT);
442                         preparedReceivedData = YangmanService.checkRpcReceivedData(preparedReceivedData, $scope.node);
443                         sendRequestData(preparedReceivedData, constants.REQUEST_DATA_TYPE_RECEIVED);
444                     }
445                 }
446
447                 // create and set history request
448                 requestHeader.statusObj.time = TimeTrackingService.returnTime();
449
450                 historyReq.setExecutionData(
451                     reqInfo.requestSrcData,
452                     preparedReceivedData,
453                     reqInfo.status,
454                     reqInfo.status,
455                     reqInfo.statusText,
456                     requestHeader.statusObj.time
457                 );
458
459                 $scope.rootBroadcast(constants.YANGMAN_SAVE_EXECUTED_REQUEST, historyReq, function (){
460                     $scope.rootBroadcast(constants.YANGMAN_SELECT_THE_NEWEST_REQUEST);
461                 });
462
463                 (executeCbk || angular.noop)(historyReq);
464
465             }
466
467             /**
468              * Error callback after executin operation
469              * @param reqInfo
470              * @param response
471              */
472             function executeReqErrCbk(reqInfo, response) {
473                 requestHeader.statusObj = reqInfo;
474
475                 finishRequestProgress();
476
477                 requestHeader.statusObj.time = TimeTrackingService.returnTime();
478
479                 historyReq.setExecutionData(
480                     reqInfo.requestSrcData,
481                     response.data,
482                     reqInfo.status,
483                     reqInfo.status,
484                     reqInfo.statusText,
485                     requestHeader.statusObj.time
486                 );
487                 $scope.rootBroadcast(constants.YANGMAN_SAVE_EXECUTED_REQUEST, historyReq, function (){
488                     $scope.rootBroadcast(constants.YANGMAN_SELECT_THE_NEWEST_REQUEST);
489                 });
490
491                 if (response.data) {
492                     // try to fill code mirror editor
493                     sendRequestData(response.data, constants.REQUEST_DATA_TYPE_RECEIVED);
494                     sendErrorData(response.data);
495                 }
496
497                 (executeCbk || angular.noop)(historyReq);
498
499
500             }
501
502         }
503
504         /**
505          * TODO :: description
506          * @param pathElem
507          * @param identifier
508          */
509         function fillNodeData(pathElem, identifier) {
510             if ($scope.selectedSubApi && $scope.selectedSubApi.storage === constants.DATA_STORE_CONFIG &&
511                 $scope.selectedSubApi.pathArray.indexOf(pathElem) === ($scope.selectedSubApi.pathArray.length - 1)) {
512                 PathUtilsService.fillListNode($scope.node, identifier.label, identifier.value);
513             }
514
515             requestHeader.urlChanged = true;
516         }
517
518         /**
519          * Check data before executin operations
520          */
521         function prepareDataAndExecute(cbk){
522             if (requestHeader.statusObj) {
523                 requestHeader.statusObj.statusText = null;
524                 requestHeader.statusObj.time = null;
525             }
526
527             showRequestProgress();
528
529             $timeout(prepareData);
530             function prepareData() {
531                 if ( requestHeader.requestUrl.length ) {
532                     if ( requestHeader.selectedShownDataType === constants.DISPLAY_TYPE_REQ_DATA ) {
533                         // get json data
534                         var params = { reqData: null };
535                         $scope.rootBroadcast(constants.YANGMAN_GET_CODEMIRROR_DATA_SENT, params);
536                         executeOperation(params.reqData ? angular.fromJson(params.reqData) : {}, cbk);
537                     } else {
538                         executeOperation({}, cbk);
539                     }
540                 }
541             }
542         }
543
544         /**
545          * Mount point initialization
546          * @param mountPointStructure
547          * @param mountPointTreeApis
548          * @param mountPointApis
549          * @param augmentations
550          */
551         function initMountPoint(mountPointTreeApis, mountPointApis, augmentations, reqObj){
552             DataBackupService.storeFromScope(
553                 [
554                     'selectedDatastore', 'node', 'apis',
555                     'selectedApi', 'selectedSubApi', 'augmentations', 'selectedModule',
556                 ],
557                 $scope,
558                 'MAIN_SCOPE'
559             );
560
561             $scope.rootBroadcast(constants.YANGMAN_GET_API_TREE_DATA, null, function (treeApis) {
562                 DataBackupService.storeFromScope(
563                     ['treeApis'],
564                     { treeApis: treeApis },
565                     'MODULES_LIST'
566                 );
567             });
568
569             $scope.setNode(null);
570             $scope.setModule(null);
571             $scope.setGlobalParams(mountPointApis, augmentations);
572             $scope.setDataStore(null);
573             requestHeader.statusObj = reqObj;
574             $scope.rootBroadcast(constants.YANGMAN_SET_API_TREE_DATA, mountPointTreeApis);
575         }
576
577         /**
578          * Executing custom plugin callback
579          * @param customPlugin
580          */
581         function executePluginFunctionality(customPlugin){
582             requestHeader.selectedPlugin = customPlugin;
583             customPlugin.runCallback({ scope: $scope, controller: requestHeader });
584         }
585
586         /**
587          * Unset custom plugin functionality - get back major params from scope
588          */
589         function unsetPluginFunctionality(){
590             if ( requestHeader.selectedPlugin ) {
591                 $scope.unsetPlugin(requestHeader);
592             }
593
594             requestHeader.selectedPlugin = null;
595             requestHeader.selectedPluginsButtons = [];
596         }
597
598     }
599
600 });