Yangman - view switched to json when request is run from history
[dlux.git] / modules / yangman-resources / src / main / resources / yangman / controllers / requests-list.controller.js
1 define([
2     'app/yangman/controllers/save-req-dialog.controller',
3     'app/yangman/controllers/edit-collection-dialog.controller',
4     'app/yangman/services/handle-file.services',
5 ], function (SaveReqDialogCtrl, EditCollectionDialogCtrl) {
6     'use strict';
7
8     angular.module('app.yangman').controller('RequestsListCtrl', RequestsListCtrl);
9
10     RequestsListCtrl.$inject = [
11         '$filter', '$mdDialog', '$scope', 'YMHandleFileService', 'PathUtilsService', 'RequestsService', 'YangmanService',
12         'YangmanDesignService', 'constants',
13     ];
14
15     /**
16      * Controller for requests lists, means History requests and Collections requests
17      * @param $filter
18      * @param $mdDialog
19      * @param $scope
20      * @param YMHandleFileService
21      * @param PathUtilsService
22      * @param RequestsService
23      * @param YangmanService
24      * @param YangmanDesignService
25      * @constructor
26      */
27     function RequestsListCtrl($filter, $mdDialog, $scope, YMHandleFileService, PathUtilsService, RequestsService,
28                               YangmanService, YangmanDesignService, constants) {
29         var vm = this;
30
31         /**
32          * List of all collections containing requests, loads even for history controller to use collection names
33          * in saving requests dialog
34          * @type {*|CollectionList}
35          */
36         vm.collectionList = null;
37         vm.constants = constants;
38
39         /**
40          *
41          * @type {*|HistoryList}
42          */
43         vm.requestList = null;
44         vm.mainList = null;
45         vm.collectionsSortAsc = true;
46         vm.search = '';
47
48         // methods
49         vm.clearCollectionList = clearCollectionList;
50         vm.clearFilter = clearFilter;
51         vm.clearHistoryList = clearHistoryList;
52         vm.colMatchingReqsCount = colMatchingReqsCount;
53         vm.deselectAllFilteredRequests = deselectAllFilteredReqs;
54         vm.downloadCollection = downloadCollection;
55         vm.executeRequest = executeRequest;
56         vm.fakeFilter = fakeFilter;
57         vm.filterCol = filterCol;
58         vm.filterColName = filterColName;
59         vm.filterReq = filterReq;
60         vm.init = init;
61         vm.readCollectionFromFile = readCollectionFromFile;
62         vm.selectAllFilteredRequests = selectAllFilteredReqs;
63         vm.selectRequest = selectRequest;
64         vm.showData = showData;
65         vm.showDgDeleteCollection = showDgDeleteCollection;
66         vm.showDgDeleteRequests = showDgDeleteRequests;
67         vm.showDgEditCollection = showDgEditCollection;
68         vm.showDgSaveReq = showDgSaveReq;
69         vm.showForm = showForm;
70         vm.toggleCollectionsSort = toggleCollectionsSort;
71         vm.selectOnlyThisRequest = selectOnlyThisRequest;
72         vm.deselectAllRequests = deselectAllRequests;
73         vm.filterCollReq = filterCollReq;
74
75         /**
76          * Save request obje to collection from other controller
77          * @param reqObj
78          */
79         function saveRequestFromExt(event, args) {
80             vm.showDgSaveReq(args.params.event, args.params.reqObj, false);
81         }
82
83
84         /**
85          * Clear history requests list and save to storage
86          */
87         function clearHistoryList(event) {
88
89             YangmanDesignService.disableMdMenuItem(event);
90
91             var confirm = $mdDialog.confirm()
92                 .title($filter('translate')('YANGMAN_DELETE_HISTORY_CONFIRM_TITLE'))
93                 .textContent($filter('translate')('YANGMAN_DELETE_HISTORY_CONFIRM_TEXT'))
94                 .ariaLabel($filter('translate')('YANGMAN_DELETE_HISTORY_CONFIRM_TITLE'))
95                 .targetEvent(event)
96                 .ok($filter('translate')('YANGMAN_OK'))
97                 .cancel($filter('translate')('YANGMAN_CANCEL'));
98
99             $mdDialog.show(confirm).then(function (){
100                 vm.requestList.clear();
101                 vm.requestList.saveToStorage();
102                 loadHistoryList();
103                 YangmanDesignService.enableMdMenuItem(event);
104             }, function (){
105                 YangmanDesignService.enableMdMenuItem(event);
106             });
107         }
108
109         /**
110          * Clear collections requests list and save to storage
111          */
112         function clearCollectionList(event) {
113             var confirm = $mdDialog.confirm()
114                 .title($filter('translate')('YANGMAN_DELETE_COLLECTION_CONFIRM_TITLE'))
115                 .textContent($filter('translate')('YANGMAN_DELETE_COLLECTION_CONFIRM_TEXT'))
116                 .ariaLabel($filter('translate')('YANGMAN_DELETE_COLLECTION_CONFIRM_TITLE'))
117                 .targetEvent(event)
118                 .ok($filter('translate')('YANGMAN_OK'))
119                 .cancel($filter('translate')('YANGMAN_CANCEL'));
120
121             YangmanDesignService.disableMdMenuItem(event);
122
123             $mdDialog.show(confirm).then(function (){
124                 vm.collectionList.clear();
125                 vm.collectionList.saveToStorage();
126                 $scope.rootBroadcast(constants.YANGMAN_REFRESH_COLLECTIONS);
127                 YangmanDesignService.enableMdMenuItem(event);
128             }, function () {
129                 YangmanDesignService.enableMdMenuItem(event);
130             });
131         }
132
133         /**
134          * Create history request from other ctrl
135          * @param broadcastEvent
136          * @param params
137          */
138         function saveBcstedHistoryRequest(broadcastEvent, params) {
139             vm.requestList.addItemToList(params.params);
140             vm.requestList.saveToStorage();
141             (params.cbk || angular.noop)();
142         }
143
144         /**
145          * Clear value of input file used to import collection
146          * todo: move to design utils
147          */
148         function clearFileInputValue(){
149             angular.element(document).find('#importCollection').val('');
150         }
151
152         /**
153          * Importing collection from a file
154          * todo: error handling - msgs for user
155          * @param $fileContent
156          */
157         function readCollectionFromFile($fileContent) {
158             var data = $fileContent;
159
160             if (data && YangmanService.validateFile(data, constants.COLLECTION_CHECK_ARRAY)){
161                 try {
162                     vm.collectionList.loadListFromFile(data);
163                     vm.collectionList.saveToStorage();
164                     $scope.rootBroadcast(constants.YANGMAN_REFRESH_COLLECTIONS);
165                     clearFileInputValue();
166                 }
167                 catch (e) {
168                     clearFileInputValue();
169                     console.error('DataStorage error:', e);
170                 }
171             }
172             else {
173                 clearFileInputValue();
174             }
175             removeButtonBackground();
176
177             function removeButtonBackground() {
178                 $('#importCollection').next().css({ 'background': 'transparent' });
179             }
180         }
181
182         function toggleCollectionsSort() {
183             vm.collectionsSortAsc = !vm.collectionsSortAsc;
184         }
185
186         /**
187          * Export collection to json file
188          * @param {Collection} collection
189          */
190         function downloadCollection(collection) {
191
192             var cListJSON = vm.collectionList.getCollectionInRawJSON(collection.name);
193
194             YMHandleFileService.downloadFile(collection.name + '.json', cListJSON, 'json', 'charset=utf-8',
195                 function (){},
196                 function (e){
197                     console.error('ExportCollection error:', e);
198                 }
199             );
200         }
201
202         /**
203          * Fill request form in right panel with request data
204          * @param reqObj
205          */
206         function showForm(reqObj) {
207             var data = reqObj.sentData;
208
209             // exception for get meth
210             if ( reqObj.method === constants.OPERATION_GET ) {
211                 data = reqObj.receivedData;
212             }
213
214             $scope.rootBroadcast(
215                 constants.YANGMAN_SET_CODEMIRROR_DATA_RECEIVED, { data: reqObj.setDataForView(reqObj.receivedData) }
216             );
217             $scope.rootBroadcast(
218                 constants.YANGMAN_SET_CODEMIRROR_DATA_SENT, { data: reqObj.setDataForView(reqObj.sentData) }
219             );
220
221             $scope.rootBroadcast(constants.YANGMAN_SET_ERROR_DATA,
222                 reqObj.receivedData && reqObj.receivedData.hasOwnProperty('errors') ? reqObj.receivedData : {});
223
224             $scope.rootBroadcast(constants.YANGMAN_FILL_NODE_FROM_REQ, { requestUrl: reqObj.path, requestData: data },
225                 function (){
226                     $scope.setRightPanelSection(constants.DISPLAY_TYPE_FORM);
227                     $scope.rootBroadcast(constants.YANGMAN_HEADER_INIT, {
228                         path: reqObj.path,
229                         method: reqObj.method,
230                         statusObj: {
231                             status: reqObj.responseStatus,
232                             statusText: reqObj.responseStatusText,
233                             time: reqObj.responseTime,
234                         },
235                     });
236
237                     if ( $scope.node ) {
238                         // prepare data for filling form
239                         data = $scope.node.type === constants.NODE_RPC ?
240                                 YangmanService.prepareReceivedData(
241                                     $scope.node,
242                                     reqObj.method,
243                                     reqObj.receivedData,
244                                     reqObj.sentData,
245                                     constants.DISPLAY_TYPE_FORM
246                                 ) : data;
247
248                         // try to fill node
249                         YangmanService.fillNodeFromResponse($scope.node, data);
250                         $scope.node.expanded = true;
251                     }
252
253                 }
254             );
255
256         }
257
258         /**
259          * Force request header to execute request with data from reqObj
260          * @param reqObj
261          */
262         function executeRequest(reqObj) {
263             if ($scope.rightPanelSection === constants.DISPLAY_TYPE_FORM) {
264                 showForm(reqObj);
265             }
266             else {
267                 showData(reqObj);
268             }
269             $scope.rootBroadcast(constants.YANGMAN_EXECUTE_WITH_DATA,{ data: reqObj.sentData });
270         }
271
272         /**
273          * Method for setup data into CM, Header, find api, subapi, node
274          * @param reqObj
275          * @param status
276          */
277         function showData(reqObj, select){
278             var headerObj = {
279                 path: reqObj.path,
280                 method: reqObj.method,
281             };
282
283             // action select request
284             if ( select ) {
285                 headerObj.statusObj = {
286                     status: reqObj.responseStatus,
287                     statusText: reqObj.responseStatusText,
288                     time: reqObj.responseTime,
289                 };
290
291                 $scope.rootBroadcast(
292                     constants.YANGMAN_SET_ERROR_DATA,
293                     reqObj.receivedData && reqObj.receivedData.hasOwnProperty('errors') ? reqObj.receivedData : {}
294                 );
295             }
296
297             $scope.setRightPanelSection(constants.DISPLAY_TYPE_REQ_DATA);
298             $scope.setJsonView(true, reqObj.method !== constants.OPERATION_GET);
299
300             $scope.rootBroadcast(constants.YANGMAN_HEADER_INIT, headerObj);
301             $scope.rootBroadcast(constants.YANGMAN_FILL_NODE_FROM_REQ, { requestUrl: reqObj.path });
302
303             $scope.rootBroadcast(
304                 constants.YANGMAN_SET_CODEMIRROR_DATA_RECEIVED,
305                 { data: reqObj.setDataForView(reqObj.receivedData) }
306             );
307
308             $scope.rootBroadcast(
309                 constants.YANGMAN_SET_CODEMIRROR_DATA_SENT,
310                 { data: reqObj.setDataForView(reqObj.sentData) }
311             );
312         }
313
314         /**
315          * Clear current ctrl search value
316          */
317         function clearFilter(){
318             vm.search = '';
319         }
320
321         /**
322          * Dialog for deleting either selected requests or reqObj
323          *
324          * @param event
325          * @param reqObj
326          */
327         function showDgDeleteRequests(event, reqObj){
328
329             var confirm = $mdDialog.confirm()
330                 .title($filter('translate')('YANGMAN_DELETE_REQ_CONFIRM_TITLE'))
331                 .textContent($filter('translate')('YANGMAN_DELETE_REQ_CONFIRM_TEXT'))
332                 .ariaLabel($filter('translate')('YANGMAN_DELETE_REQ_CONFIRM_TITLE'))
333                 .targetEvent(event)
334                 .ok($filter('translate')('YANGMAN_OK'))
335                 .cancel($filter('translate')('YANGMAN_CANCEL'));
336
337             YangmanDesignService.disableMdMenuItem(event);
338
339             $mdDialog.show(confirm).then(function (){
340                 if (reqObj){
341                     vm.mainList.deleteRequestItem(reqObj);
342                 }
343                 else {
344                     vm.mainList.getSelectedItems(
345                         vm.mainList === vm.collectionList ? filterCollReq : filterReq
346                     ).forEach(function (elem){
347                         vm.mainList.deleteRequestItem(elem);
348                     });
349                 }
350                 vm.mainList.saveToStorage();
351
352                 if (vm.mainList === vm.requestList) {
353                     loadHistoryList();
354                 }
355                 else {
356                     refreshCollectionsWithExpansion();
357                 }
358             }, function (){
359                 YangmanDesignService.enableMdMenuItem(event);
360             });
361         }
362
363
364         /**
365          * Dialog for deleting collection and refreshing collections
366          * @param ev
367          * @param collObj
368          */
369         function showDgDeleteCollection(ev, collObj){
370             var confirm = $mdDialog.confirm()
371                 .title($filter('translate')('YANGMAN_DELETE_COL_CONFIRM_TITLE') + ' ' + collObj.name + '?')
372                 .textContent($filter('translate')('YANGMAN_DELETE_COL_CONFIRM_TEXT'))
373                 .ariaLabel($filter('translate')('YANGMAN_DELETE_COL_CONFIRM_TITLE'))
374                 .targetEvent(ev)
375                 .ok($filter('translate')('YANGMAN_OK'))
376                 .cancel($filter('translate')('YANGMAN_CANCEL'));
377
378             YangmanDesignService.disableMdMenuItem(ev);
379
380             $mdDialog.show(confirm).then(function (){
381                 vm.collectionList.deleteCollection(collObj);
382                 vm.collectionList.saveToStorage();
383                 refreshCollectionsWithExpansion();
384             }, function (){
385                 YangmanDesignService.enableMdMenuItem(ev);
386             });
387         }
388
389         /**
390          * Check if reqObj matches current search value
391          * @param reqObj
392          * @returns {boolean}
393          */
394         function filterReq(reqObj){
395             var searchPhrase = vm.search.toLocaleLowerCase();
396             return reqObj.path.toLowerCase().indexOf(searchPhrase) > -1 ||
397                 reqObj.collection.toLowerCase().indexOf(searchPhrase) > -1 ||
398                 reqObj.method.toLowerCase() === searchPhrase;
399         }
400
401         /**
402          * Check if collection name matches current search value or any collection req matches
403          * @param colObj
404          */
405         function filterCol(colObj){
406             return filterColName(colObj) || colObj.data.some(filterReq);
407         }
408
409         /**
410          * Get count of requests matching filter in collection colObj
411          * @param colObj
412          * @returns {*}
413          */
414         function colMatchingReqsCount(colObj){
415             return colObj.data.filter(vm.filterReq).length;
416         }
417
418         /**
419          * Check if collection name matches current filter
420          * @param colObj
421          * @returns {boolean}
422          */
423         function filterColName(colObj){
424             return colObj.name.toLowerCase().indexOf(vm.search.toLowerCase()) > -1;
425         }
426
427         /**
428          * Returns true
429          * @returns {boolean}
430          */
431         function fakeFilter(){
432             return true;
433         }
434
435
436         /**
437          * Show dialog for saving reqObj to collection (used for duplicate req too)
438          * @param ev
439          * @param reqObj
440          * @param duplicate
441          */
442         function showDgSaveReq(ev, reqObj, duplicate){
443
444             $mdDialog.show({
445                 controller: SaveReqDialogCtrl,
446                 controllerAs: 'dialog',
447                 templateUrl: $scope.globalViewPath + 'leftpanel/save-req-dialog.tpl.html',
448                 parent: angular.element('#yangmanModule'),
449                 targetEvent: ev,
450                 clickOutsideToClose: true,
451                 locals: {
452                     requests: reqObj ? [reqObj] : vm.mainList.getSelectedItems(
453                         vm.mainList === vm.collectionList ? filterCollReq : filterReq
454                     ),
455                     collectionNames: vm.collectionList.getCollectionNames(),
456                     duplicate: duplicate || false,
457                 },
458             }).then(saveRequests);
459         }
460
461         /**
462          * Add each request from requests array to collectionList and save
463          * @param requests
464          */
465         function saveRequests(requests){
466             requests.forEach(function (reqObj){
467                 vm.collectionList.addItemToList(RequestsService.clearUnnecessaryProperties(reqObj.clone()));
468                 vm.collectionList.saveToStorage();
469                 refreshCollectionsWithExpansion();
470             });
471         }
472
473
474         /**
475          * Dialog for editing collection name (used for duplicating collection too)
476          * @param ev
477          * @param collection
478          * @param {boolean} duplicate
479          */
480         function showDgEditCollection(ev, collection, duplicate){
481             $mdDialog.show({
482                 controller: EditCollectionDialogCtrl,
483                 controllerAs: 'dialog',
484                 templateUrl: $scope.globalViewPath + 'leftpanel/edit-collection-dialog.tpl.html',
485                 parent: angular.element('#yangmanModule'),
486                 targetEvent: ev,
487                 clickOutsideToClose: true,
488                 locals: {
489                     collection: collection,
490                     allCollections: vm.collectionList.collections,
491                     duplicate: duplicate,
492                 },
493             }).then(duplicate ? duplicateCollection : changeCollectionName);
494         }
495
496         /**
497          * Rename collection
498          * @param {array} names 0. element is old name, 1. element is new name
499          */
500         function changeCollectionName(names){
501             vm.collectionList.renameCollection(names[0], names[1]);
502             vm.collectionList.saveToStorage();
503             refreshCollectionsWithExpansion();
504         }
505
506         /**
507          * Create collection duplicate, save and refresh collections
508          * @param {array} names 0. element is old name, 1. element is new name
509          */
510         function duplicateCollection(names){
511             vm.collectionList.duplicateCollection(names[0], names[1]);
512             vm.collectionList.saveToStorage();
513             refreshCollectionsWithExpansion();
514         }
515
516
517         function selectNewestRequest() {
518             vm.mainList.toggleReqSelection(true, vm.mainList.getNewestRequest());
519         }
520
521         function loadCollectionsList() {
522             vm.collectionList.loadListFromStorage();
523         }
524
525         function loadHistoryList() {
526             vm.requestList.loadListFromStorage();
527         }
528
529         /**
530          *
531          * @param mainList collectionList or requestList object
532          */
533         function init(mainList){
534
535             vm.collectionList = RequestsService.createEmptyCollectionList('yangman_collectionsList');
536             // collections are loaded for both history and collections tab
537             loadCollectionsList();
538
539             vm.requestList = RequestsService.createEmptyHistoryList('yangman_requestsList');
540
541
542             // if request was selected, deselect requests in all other instances of RequestsListCtrl
543             $scope.$on(constants.YANGMAN_DESELECT_REQUESTS, function (event, params) {
544                 if (params.params.broadcastingCtrl !== vm) {
545                     deselectAllRequests();
546                 }
547             });
548
549             $scope.$on(constants.YANGMAN_REFRESH_COLLECTIONS, function (event, params){
550                 loadCollectionsList();
551                 (params.cbk || angular.noop)();
552             });
553
554             // list type dependend operations
555             if (mainList === 'history') {
556
557                 vm.mainList = vm.requestList;
558                 loadHistoryList();
559
560                 $scope.$on(constants.YANGMAN_REFRESH_HISTORY, loadHistoryList);
561                 // saving from request header after execution
562                 $scope.$on(constants.YANGMAN_SAVE_EXECUTED_REQUEST, saveBcstedHistoryRequest);
563                 // select newest request
564                 $scope.$on(constants.YANGMAN_SELECT_THE_NEWEST_REQUEST, selectNewestRequest);
565             }
566             else {
567                 vm.mainList = vm.collectionList;
568                 // saving from request header
569                 $scope.$on(constants.YANGMAN_SAVE_REQUEST_TO_COLLECTION, saveRequestFromExt);
570                 // saving collections expanded status on refresh
571                 $scope.$on(constants.YANGMAN_REFRESH_AND_EXPAND_COLLECTIONS, function(){
572                     var expandedColNames = vm.collectionList.getExpandedCollectionNames();
573                     $scope.rootBroadcast(constants.YANGMAN_REFRESH_COLLECTIONS, {}, function (){
574                         vm.collectionList.expandCollectionByNames(expandedColNames);
575                     });
576                 });
577             }
578
579         }
580
581
582         /**
583          * Request in list selection
584          * For history reqs it is possible multiselect, thats why event.ctrlKey is used
585          * @param event
586          * @param requestObj
587          */
588         function selectRequest(event, requestObj){
589             $scope.rootBroadcast(constants.YANGMAN_DESELECT_REQUESTS, { broadcastingCtrl: vm });
590             vm.mainList.toggleReqSelection(!event.ctrlKey, requestObj);
591             if (!event.ctrlKey){
592                 if ($scope.rightPanelSection === constants.DISPLAY_TYPE_FORM) {
593                     vm.showForm(requestObj, true);
594                 }
595                 else {
596                     vm.showData(requestObj, true);
597                 }
598             }
599         }
600
601         /**
602          * Mark only requestObj in current list as selected
603          * Used for example when user clicks on request submenu
604          * @param requestObj
605          */
606         function selectOnlyThisRequest(requestObj){
607             vm.mainList.toggleReqSelection(true, requestObj);
608         }
609
610         /**
611          * Deselect history requests
612          */
613         function deselectAllFilteredReqs(){
614             vm.mainList.deselectAllFilteredItems(vm.mainList === vm.collectionList ? filterCollReq : vm.filterReq);
615         }
616
617         function deselectAllRequests() {
618             vm.mainList.deselectAllItems();
619         }
620
621         /**
622          * Select history requests
623          */
624         function selectAllFilteredReqs(){
625             vm.mainList.selectAllFilteredItems(vm.mainList === vm.collectionList ? filterCollReq : vm.filterReq);
626         }
627
628         /**
629          * Use when selecting filtered requests if they are saved to some collection
630          * Additional filter is if the collection of the request is expanded
631          * @param request
632          * @returns {*|boolean}
633          */
634         function filterCollReq(request) {
635             return vm.collectionList.getCollection(request.collection).expanded && vm.filterReq(request);
636         }
637
638         /**
639          * Refresh and expand collections
640          */
641         function refreshCollectionsWithExpansion(){
642             $scope.rootBroadcast(constants.YANGMAN_REFRESH_AND_EXPAND_COLLECTIONS);
643         }
644
645     }
646
647 });