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