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