[PORTAL-7] Rebase
[portal.git] / ecomp-portal-FE-common / client / app / views / users / new-user-dialogs / bulk-user.controller.js
1 /*-\r
2  * ================================================================================\r
3  * ECOMP Portal\r
4  * ================================================================================\r
5  * Copyright (C) 2017 AT&T Intellectual Property\r
6  * ================================================================================\r
7  * Licensed under the Apache License, Version 2.0 (the "License");\r
8  * you may not use this file except in compliance with the License.\r
9  * You may obtain a copy of the License at\r
10  * \r
11  *      http://www.apache.org/licenses/LICENSE-2.0\r
12  * \r
13  * Unless required by applicable law or agreed to in writing, software\r
14  * distributed under the License is distributed on an "AS IS" BASIS,\r
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
16  * See the License for the specific language governing permissions and\r
17  * limitations under the License.\r
18  * ================================================================================\r
19  */\r
20 /**\r
21  * bulk user upload controller\r
22  */\r
23 'use strict';\r
24 (function () {\r
25     class BulkUserModalCtrl {\r
26         constructor($scope, $log, $filter, $q, usersService, applicationsService, confirmBoxService, functionalMenuService, ngDialog) {\r
27                 \r
28                 // Set to true for copious console output\r
29                 var debug = false;\r
30                 // Roles fetched from app service\r
31                 var appRolesResult = [];\r
32                 // Users fetched from user service\r
33                 var     userCheckResult = [];\r
34                 // Requests for user-role assignment built by validator\r
35                 var appUserRolesRequest = [];\r
36                 \r
37                 let init = () => {\r
38                         if (debug)\r
39                                 $log.debug('BulkUserModalCtrl::init');\r
40                         // Angular insists on this.\r
41                         $scope.fileModel = {};\r
42                         // Model for drop-down\r
43                         $scope.adminApps = [];\r
44                         // Enable modal controls\r
45                         this.step1 = true;\r
46                         this.fileSelected = false;\r
47 \r
48                         // Flag that indicates background work is proceeding\r
49                         $scope.isProcessing = true;\r
50 \r
51                         // Load user's admin applications\r
52                         applicationsService.getAdminApps().promise().then(apps => {\r
53                                 if (debug)\r
54                                         $log.debug('BulkUserModalCtrl::init: getAdminApps returned' + JSON.stringify(apps));\r
55                     if (!apps || typeof(apps) != 'object') {\r
56                         $log.error('BulkUserModalCtrl::init: getAdminApps returned unexpected data');\r
57                     }\r
58                     else {\r
59                         if (debug)\r
60                                 $log.debug('BulkUserModalCtrl::init:  admin apps length is ', apps.length);\r
61                         \r
62                         // Sort app names and populate the drop-down model\r
63                         let sortedApps = apps.sort(getSortOrder('name', true));\r
64                         for (let i = 0; i < sortedApps.length; ++i) {\r
65                             $scope.adminApps.push({\r
66                                 index: i,\r
67                                 id: sortedApps[i].id,\r
68                                 value: sortedApps[i].name,\r
69                                 title: sortedApps[i].name\r
70                             });\r
71                         }\r
72                         // Pick the first one in the list\r
73                         $scope.selectedApplication = $scope.adminApps[0];\r
74                     }\r
75                                 $scope.isProcessing = false;\r
76                 }).catch(err => {\r
77                     $log.error('BulkUserModalCtrl::init: getAdminApps threw', err);\r
78                         $scope.isProcessing = false;\r
79                 });\r
80                         \r
81                 }; // init\r
82                 \r
83                 // Answers a function that compares properties with the specified name.\r
84                 let getSortOrder = (prop, foldCase) => {\r
85                 return function(a, b) {\r
86                         let aProp = foldCase ? a[prop].toLowerCase() : a[prop];\r
87                         let bProp = foldCase ? b[prop].toLowerCase() : b[prop];\r
88                     if (aProp > bProp)\r
89                         return 1;\r
90                     else if (aProp < bProp) \r
91                         return -1;\r
92                     else\r
93                         return 0;\r
94                 }\r
95             }\r
96                 \r
97                 //This is a fix for dropdown selection, due to b2b dropdown only update value field\r
98                 $scope.$watch('selectedApplication.value', (newVal, oldVal) => {\r
99                         for(var i=0;i<$scope.adminApps.length;i++){                     \r
100                                 if($scope.adminApps[i].value==newVal){\r
101                                         $scope.selectedApplication=angular.copy($scope.adminApps[i]);;\r
102                                 }\r
103                         }\r
104                 });\r
105 \r
106                 // Invoked when user picks an app on the drop-down.\r
107                 $scope.appSelected = () => {\r
108                         if (debug)\r
109                                 $log.debug('BulkUserModalCtrl::appSelected: selectedApplication.id is ' + $scope.selectedApplication.id);\r
110                         this.appSelected = true;\r
111                 }\r
112                 \r
113                 // Caches the file name supplied by the event handler.\r
114                 $scope.fileChangeHandler = (event, files) => {\r
115                         this.fileSelected = true;\r
116                         this.fileToRead = files[0];\r
117                         if (debug)\r
118                                 $log.debug("BulkUserModalCtrl::fileChangeHandler: file is ", this.fileToRead);\r
119                 }; // file change handler\r
120                 \r
121                 /**\r
122                  * Reads the contents of the file, calls portal endpoints\r
123                  * to validate roles, userIds and existing role assignments;\r
124                  * ultimately builds array of requests to be sent.\r
125                  * Creates scope variable with input file contents for\r
126                  * communication with functions.\r
127                  * \r
128                  * This function performs a synchronous step-by-step process\r
129                  * using asynchronous promises. The code could all be inline\r
130                  * here but the nesting becomes unwieldy.\r
131                  */\r
132                 $scope.readValidateFile = () => {\r
133                         $scope.isProcessing = true;\r
134                         $scope.progressMsg = 'Reading upload file..';\r
135                         var reader = new FileReader();\r
136                         reader.onload = function(event) {\r
137                                 $scope.uploadFile = $filter('csvToObj')(reader.result);\r
138                                 if (debug)\r
139                                         $log.debug('BulkUserModalCtrl::readValidateFile onload: data length is ' + $scope.uploadFile.length);\r
140                                 // sort input by orgUserId\r
141                                 $scope.uploadFile.sort(getSortOrder('orgUserId', true));\r
142                                 \r
143                                 let appid = $scope.selectedApplication.id;\r
144                                 $scope.progressMsg = 'Fetching application roles..';\r
145                     functionalMenuService.getManagedRolesMenu(appid).then(function (rolesObj) {\r
146                         if (debug)\r
147                                 $log.debug("BulkUserModalCtrl::readValidateFile: managedRolesMenu returned " + JSON.stringify(rolesObj));\r
148                                         appRolesResult = rolesObj;\r
149                                         $scope.progressMsg = 'Validating application roles..';\r
150                         $scope.verifyRoles();\r
151                                 \r
152                         let userPromises = $scope.buildUserChecks();\r
153                         if (debug)\r
154                                 $log.debug('BulkUserModalCtrl::readValidateFile: userPromises length is ' + userPromises.length);\r
155                         $scope.progressMsg = 'Validating Org Users..';\r
156                         $q.all(userPromises).then(function() {\r
157                                 if (debug)\r
158                                         $log.debug('BulkUserModalCtrl::readValidateFile: userCheckResult length is ' + userCheckResult.length);\r
159                                 $scope.evalUserCheckResults();\r
160                                         \r
161                                 let appPromises = $scope.buildAppRoleChecks();\r
162                                 if (debug)\r
163                                         $log.debug('BulkUserModalCtrl::readValidateFile: appPromises length is ' + appPromises.length);\r
164                                 $scope.progressMsg = 'Querying application for user roles..';\r
165                                 $q.all(appPromises).then( function() {\r
166                                         if (debug)\r
167                                                 $log.debug('BulkUserModalCtrl::readValidateFile: appUserRolesRequest length is ' + appUserRolesRequest.length);\r
168                                         $scope.evalAppRoleCheckResults();\r
169                                         \r
170                                                         // Re sort by line for the confirmation dialog\r
171                                                         $scope.uploadFile.sort(getSortOrder('line', false));\r
172                                                         // We're done, confirm box may show the table\r
173                                                         if (debug)\r
174                                                                 $log.debug('BulkUserModalCtrl::readValidateFile inner-then ends');\r
175                                                         $scope.progressMsg = 'Done.';\r
176                                                         $scope.isProcessing = false;\r
177                                 },\r
178                                 function(error) {\r
179                                         $log.error('BulkUserModalCtrl::readValidateFile: failed retrieving user-app roles');\r
180                                                         $scope.isProcessing = false;\r
181                                 }\r
182                                 ); // then of app promises\r
183                         },\r
184                         function(error) {\r
185                                 $log.error('BulkUserModalCtrl::readValidateFile: failed retrieving user info');\r
186                                 $scope.isProcessing = false;\r
187                         }\r
188                         ); // then of user promises\r
189                     },\r
190                     function(error) {\r
191                         $log.error('BulkUserModalCtrl::readValidateFile: failed retrieving app role info');\r
192                         $scope.isProcessing = false;\r
193                     }\r
194                     ); // then of role promise\r
195            \r
196                         } // onload\r
197                         \r
198                         // Invoke the reader on the selected file\r
199                         reader.readAsText(this.fileToRead);\r
200                 }; \r
201                 \r
202                 /**\r
203                  * Evaluates the result set returned by the app role service.\r
204                  * Sets an uploadFile array element status if a role is not defined.\r
205                  * Reads and writes scope variable uploadFile.\r
206                  * Reads closure variable appRolesResult.\r
207                  */\r
208                 $scope.verifyRoles = () => {\r
209                         if (debug)\r
210                                 $log.debug('BulkUserModalCtrl::verifyRoles: appRoles is ' + JSON.stringify(appRolesResult));\r
211                         // check roles in upload file against defined app roles\r
212                         $scope.uploadFile.forEach( function (uploadRow) {\r
213                                 // skip rows that already have a defined status: headers etc.\r
214                                 if (uploadRow.status) {\r
215                                         if (debug)\r
216                                                 $log.debug('BulkUserModalCtrl::verifyRoles: skip row ' + uploadRow.line);\r
217                                         return;\r
218                                 }\r
219                                 uploadRow.role = uploadRow.role.trim();\r
220                                 var foundRole=false;\r
221                                 for (var i=0; i < appRolesResult.length; i++) {\r
222                                         if (uploadRow.role.toUpperCase() === appRolesResult[i].rolename.trim().toUpperCase()) {\r
223                                                 if (debug)\r
224                                                         $log.debug('BulkUserModalCtrl::verifyRoles: match on role ' + uploadRow.role);\r
225                                                 foundRole=true;\r
226                                                 break;\r
227                                         }\r
228                                 };\r
229                                 if (!foundRole) {\r
230                                         if (debug)\r
231                                                 $log.debug('BulkUserModalCtrl::verifyRoles: NO match on role ' + uploadRow.role);\r
232                                         uploadRow.status = 'Invalid role';\r
233                                 };\r
234                         }); // foreach\r
235                 }; // verifyRoles\r
236                 \r
237                 /**\r
238                  * Builds and returns an array of promises to invoke the \r
239                  * searchUsers service for each unique Org User UID in the input.\r
240                  * Reads and writes scope variable uploadFile, which must be sorted by Org User UID.\r
241                  * The promise function writes to closure variable userCheckResult\r
242                  */\r
243                 $scope.buildUserChecks = () => {\r
244                         if (debug)\r
245                                 $log.debug('BulkUserModalCtrl::buildUserChecks: uploadFile length is ' + $scope.uploadFile.length);\r
246                         userCheckResult = [];\r
247                         let promises = [];\r
248                         let prevRow = null;\r
249                         $scope.uploadFile.forEach(function (uploadRow) {\r
250                                 if (uploadRow.status) {\r
251                                         if (debug)\r
252                                                 $log.debug('BulkUserModalCtrl::buildUserChecks: skip row ' + uploadRow.line);\r
253                                         return;\r
254                                 };\r
255                                 // detect repeated UIDs\r
256                                 if (prevRow == null || prevRow.orgUserId.toLowerCase() !== uploadRow.orgUserId.toLowerCase()) {\r
257                                         if (debug)\r
258                                                 $log.debug('BulkUserModalCtrl::buildUserChecks: create request for orgUserId ' + uploadRow.orgUserId);\r
259                                         let userPromise = usersService.searchUsers(uploadRow.orgUserId).promise().then( (usersList) => {\r
260                                                 if (typeof usersList[0] !== "undefined") {\r
261                                                         userCheckResult.push({ \r
262                                                                 orgUserId:    usersList[0].orgUserId,\r
263                                                                 firstName: usersList[0].firstName,\r
264                                                                 lastName:  usersList[0].lastName,\r
265                                                                 jobTitle:  usersList[0].jobTitle\r
266                                                         });\r
267                                                 }\r
268                                                 else {\r
269                                                         // User not found.\r
270                                                         if (debug)\r
271                                                                 $log.debug('BulkUserModalCtrl::buildUserChecks: searchUsers returned null');\r
272                                                 }\r
273                                         }, function(error){\r
274                                                 $log.error('BulkUserModalCtrl::buildUserChecks: searchUsers failed ' + JSON.stringify(error));\r
275                                         }); \r
276                                         promises.push(userPromise);\r
277                                 }\r
278                                 else {\r
279                                         if (debug)\r
280                                                 $log.debug('BulkUserModalCtrl::buildUserChecks: skip repeated orgUserId ' + uploadRow.orgUserId);                                       \r
281                                 }\r
282                                 prevRow = uploadRow;\r
283                         }); // foreach\r
284                         return promises;\r
285                 }; // buildUserChecks\r
286                 \r
287                 /**\r
288                  * Evaluates the result set returned by the user service to set\r
289                  * the uploadFile array element status if the user was not found.\r
290                  * Reads and writes scope variable uploadFile.\r
291                  * Reads closure variable userCheckResult.\r
292                  */\r
293                 $scope.evalUserCheckResults = () => {\r
294                         if (debug)\r
295                                 $log.debug('BulkUserModalCtrl::evalUserCheckResult: uploadFile length is ' + $scope.uploadFile.length);\r
296                         $scope.uploadFile.forEach(function (uploadRow) {\r
297                                 if (uploadRow.status) {\r
298                                         if (debug)\r
299                                                 $log.debug('BulkUserModalCtrl::evalUserCheckResults: skip row ' + uploadRow.line);\r
300                                         return;\r
301                                 };\r
302                                 let foundorgUserId = false;\r
303                                 userCheckResult.forEach(function(userItem) {\r
304                                         if (uploadRow.orgUserId.toLowerCase() === userItem.orgUserId.toLowerCase()) {\r
305                                                 if (debug)\r
306                                                         $log.debug('BulkUserModalCtrl::evalUserCheckResults: found orgUserId ' + uploadRow.orgUserId);\r
307                                                 foundorgUserId=true;\r
308                                         };\r
309                                 });\r
310                                 if (!foundorgUserId) {\r
311                                         if (debug)\r
312                                                 $log.debug('BulkUserModalCtrl::evalUserCheckResults: NO match on orgUserId ' + uploadRow.orgUserId);\r
313                                         uploadRow.status = 'Invalid orgUserId';\r
314                                 }\r
315                         }); // foreach\r
316                 }; // evalUserCheckResults\r
317 \r
318             /**\r
319                  * Builds and returns an array of promises to invoke the getUserAppRoles\r
320                  * service for each unique Org User in the input file.\r
321                  * Each promise creates an update to be sent to the remote application\r
322                  * with all role names.\r
323                  * Reads scope variable uploadFile, which must be sorted by Org User.\r
324                  * The promise function writes to closure variable appUserRolesRequest\r
325                  */\r
326                 $scope.buildAppRoleChecks = () => {\r
327                         if (debug)\r
328                                 $log.debug('BulkUserModalCtrl::buildAppRoleChecks: uploadFile length is ' + $scope.uploadFile.length); \r
329                         appUserRolesRequest = [];\r
330                         let appId = $scope.selectedApplication.id;\r
331                         let promises = [];\r
332                         let prevRow = null;\r
333                         $scope.uploadFile.forEach( function (uploadRow) {\r
334                                 if (uploadRow.status) {\r
335                                         if (debug)\r
336                                                 $log.debug('BulkUserModalCtrl::buildAppRoleChecks: skip row ' + uploadRow.line);\r
337                                         return;\r
338                                 }\r
339                                 // Because the input is sorted, generate only one request for each Org User\r
340                                 if (prevRow == null || prevRow.orgUserId.toLowerCase() !== uploadRow.orgUserId.toLowerCase()) {\r
341                                  if (debug)\r
342                                          $log.debug('BulkUserModalCtrl::buildAppRoleChecks: create request for orgUserId ' + uploadRow.orgUserId);\r
343                                  let appPromise = usersService.getUserAppRoles(appId, uploadRow.orgUserId).promise().then( (userAppRolesResult) => {\r
344                                          // Reply for unknown user has all defined roles with isApplied=false on each.  \r
345                                          if (typeof userAppRolesResult[0] !== "undefined") {\r
346                                                  if (debug)\r
347                                                          $log.debug('BulkUserModalCtrl::buildAppRoleChecks: adding result ' \r
348                                                                          + JSON.stringify(userAppRolesResult));\r
349                                                  appUserRolesRequest.push({\r
350                                                          orgUserId: uploadRow.orgUserId,\r
351                                                          userAppRoles: userAppRolesResult                                                        \r
352                                                  });\r
353                                          } else {\r
354                                                  $log.error('BulkUserModalCtrl::buildAppRoleChecks: getUserAppRoles returned ' + JSON.stringify(userAppRolesResult));\r
355                                          };\r
356                                  }, function(error){\r
357                                          $log.error('BulkUserModalCtrl::buildAppRoleChecks: getUserAppRoles failed ', error);\r
358                                  });\r
359                                  promises.push(appPromise);\r
360                                 } else {\r
361                                  if (debug)\r
362                                          $log.debug('BulkUserModalCtrl::buildAppRoleChecks: duplicate orgUserId, skip: '+ uploadRow.orgUserId);\r
363                          }\r
364                          prevRow = uploadRow;\r
365                  }); // foreach\r
366                         return promises;\r
367                 }; // buildAppRoleChecks\r
368                 \r
369                 /**\r
370                  * Evaluates the result set returned by the app service and adjusts \r
371                  * the list of updates to be sent to the remote application by setting\r
372                  * isApplied=true for each role name found in the upload file.\r
373                  * Reads and writes scope variable uploadFile.\r
374                  * Reads closure variable appUserRolesRequest.\r
375                  */\r
376                 $scope.evalAppRoleCheckResults = () => {\r
377                         if (debug)\r
378                                 $log.debug('BulkUserModalCtrl::evalAppRoleCheckResults: uploadFile length is ' + $scope.uploadFile.length);\r
379                         $scope.uploadFile.forEach(function (uploadRow) {\r
380                                 if (uploadRow.status) {\r
381                                         if (debug)\r
382                                                 $log.debug('BulkUserModalCtrl::evalAppRoleCheckResults: skip row ' + uploadRow.line);\r
383                                         return;\r
384                                 }\r
385                                 // Search for the match in the app-user-roles array\r
386                                 appUserRolesRequest.forEach( function (appUserRoleObj) {\r
387                                         if (uploadRow.orgUserId.toLowerCase() === appUserRoleObj.orgUserId.toLowerCase()) {\r
388                                                 if (debug)\r
389                                                         $log.debug('BulkUserModalCtrl::evalAppRoleCheckResults: match on orgUserId ' + uploadRow.orgUserId);\r
390                                                 let roles = appUserRoleObj.userAppRoles;\r
391                                                 roles.forEach(function (appRoleItem) {\r
392                                                         //if (debug)\r
393                                                         //      $log.debug('BulkUserModalCtrl::evalAppRoleCheckResults: checking uploadRow.role='\r
394                                                         //                      + uploadRow.role + ', appRoleItem.roleName= ' + appRoleItem.roleName);\r
395                                                         if (uploadRow.role === appRoleItem.roleName) {\r
396                                                                 if (appRoleItem.isApplied) {\r
397                                                                         if (debug)\r
398                                                                                 $log.debug('BulkUserModalCtrl::evalAppRoleCheckResults: existing role ' \r
399                                                                                         + appRoleItem.roleName);\r
400                                                                         uploadRow.status = 'Role exists';\r
401                                                                 }\r
402                                                                 else {\r
403                                                                         if (debug)\r
404                                                                                 $log.debug('BulkUserModalCtrl::evalAppRoleCheckResults: new role ' \r
405                                                                                         + appRoleItem.roleName);\r
406                                                                         // After much back-and-forth I decided a clear indicator\r
407                                                                         // is better than blank in the table status column.\r
408                                                                         uploadRow.status = 'OK';\r
409                                                                         appRoleItem.isApplied = true;\r
410                                                                 }\r
411                                                                 // This count is not especially interesting.\r
412                                                                 // numberUserRolesSucceeded++;\r
413                                                         }\r
414                                                 }); // for each role\r
415                                         }\r
416                                 }); // for each result          \r
417                         }); // for each row\r
418                 }; // evalAppRoleCheckResults\r
419              \r
420                 /**\r
421                  * Sends requests to Portal requesting user role assignment.\r
422                  * That endpoint handles creation of the user at the remote app if necessary.\r
423                  * Reads closure variable appUserRolesRequest.\r
424                  * Invoked by the Next button on the confirmation dialog.\r
425                  */\r
426                 $scope.updateDB = () => {\r
427                         $scope.isProcessing = true;\r
428                         $scope.progressMsg = 'Sending requests to application..';\r
429                         if (debug)\r
430                                 $log.debug('BulkUserModalCtrl::updateDB: request length is ' + appUserRolesRequest.length);\r
431                         var numberUsersSucceeded = 0;\r
432                         let promises = [];\r
433                         appUserRolesRequest.forEach(function(appUserRoleObj) {\r
434                                 if (debug) \r
435                                         $log.debug('BulkUserModalCtrl::updateDB: appUserRoleObj is ' + JSON.stringify(appUserRoleObj));\r
436                      let updateRequest = {\r
437                                  orgUserId: appUserRoleObj.orgUserId, \r
438                                  appId: $scope.selectedApplication.id, \r
439                                  appRoles: appUserRoleObj.userAppRoles\r
440                      };\r
441                      if (debug)\r
442                          $log.debug('BulkUserModalCtrl::updateDB: updateRequest is ' + JSON.stringify(updateRequest));\r
443                      let updatePromise = usersService.updateUserAppRoles(updateRequest).promise().then(res => {\r
444                          if (debug)\r
445                                  $log.debug('BulkUserModalCtrl::updateDB: updated successfully: ' + JSON.stringify(res));\r
446                          numberUsersSucceeded++;\r
447                      }).catch(err => {\r
448                          // What to do if one of many fails??\r
449                          $log.error('BulkUserModalCtrl::updateDB failed: ', err);\r
450                          confirmBoxService.showInformation(\r
451                                          'Failed to update the user application roles. ' +\r
452                                          'Error: ' + err.status).then(isConfirmed => { });\r
453                      }).finally( () => {\r
454                          // $log.debug('BulkUserModalCtrl::updateDB: finally()');\r
455                      });\r
456                      promises.push(updatePromise);\r
457                  }); // for each\r
458                         \r
459                  // Run all the promises\r
460                  $q.all(promises).then(function(){\r
461                          $scope.isProcessing = false;\r
462                          confirmBoxService.showInformation('Processed ' + numberUsersSucceeded + ' users.').then(isConfirmed => {\r
463                                  // Close the upload-confirm dialog\r
464                                  ngDialog.close();\r
465                          });\r
466                  });\r
467              }; // updateDb\r
468              \r
469                 // Sets the variable that hides/reveals the user controls\r
470                 $scope.step2 = () => {\r
471                         this.fileSelected = false;\r
472                         $scope.selectedFile = null;\r
473                         $scope.fileModel = null;\r
474                         this.step1 = false;                     \r
475                 }\r
476                 \r
477              // Navigate between dialog screens using step number: 1,2,...\r
478              $scope.navigateBack = () => {\r
479                  this.step1 = true;\r
480                  this.fileSelected = false;\r
481              };\r
482              \r
483              // Opens a dialog to show the data to be uploaded.\r
484              // Invoked by the upload button on the bulk user dialog.\r
485              $scope.confirmUpload = () => {\r
486                 // Start the process\r
487                 $scope.readValidateFile();\r
488                 // Dialog shows progress\r
489                 ngDialog.open({\r
490                         templateUrl: 'app/views/users/new-user-dialogs/bulk-user.confirm.html',\r
491                         scope: $scope\r
492                 });\r
493              };\r
494 \r
495              // Invoked by the Cancel button on the confirmation dialog.\r
496              $scope.cancelUpload = () => {\r
497                  ngDialog.close();\r
498              };\r
499              \r
500              init();\r
501         } // constructor\r
502     } // class\r
503     BulkUserModalCtrl.$inject = ['$scope', '$log', '$filter', '$q', 'usersService', 'applicationsService', 'confirmBoxService', 'functionalMenuService', 'ngDialog'];    \r
504     angular.module('ecompApp').controller('BulkUserModalCtrl', BulkUserModalCtrl);\r
505 \r
506     angular.module('ecompApp').directive('fileChange', ['$parse', function($parse){\r
507         return {\r
508                 require: 'ngModel',\r
509             restrict: 'A',\r
510             link : function($scope, element, attrs, ngModel) {\r
511                 var attrHandler = $parse(attrs['fileChange']);\r
512                 var handler=function(e) {\r
513                         $scope.$apply(function() {\r
514                                 attrHandler($scope, { $event:e, files:e.target.files } );\r
515                                 $scope.selectedFile = e.target.files[0].name;\r
516                         });\r
517                 };\r
518                 element[0].addEventListener('change',handler,false);\r
519            }\r
520         }\r
521     }]);\r
522 \r
523     angular.module('ecompApp').filter('csvToObj',function() {\r
524         return function(input) {\r
525             var result = [];\r
526             var len, i, line, o;\r
527                 var lines = input.split('\n');\r
528             // Need 1-based index below\r
529             for (len = lines.length, i = 1; i <= len; ++i) {\r
530                 // Use 0-based index for array\r
531                 line = lines[i - 1].trim();\r
532                         if (line.length == 0) {\r
533                                 // console.log("Skipping blank line");\r
534                                 result.push({\r
535                                         line: i,\r
536                                         orgUserId: '',\r
537                                         role: '',\r
538                                         status: 'Blank line'\r
539                                 });\r
540                                 continue;\r
541                         }\r
542                         o = line.split(',');\r
543                         if (o.length !== 2) {\r
544                                 // other lengths not valid for upload\r
545                                 result.push({\r
546                                         line: i,\r
547                                         orgUserId: line,   \r
548                                         role: '',\r
549                                         status: 'Failed to find 2 comma-separated values'\r
550                                 });\r
551                         }\r
552                         else {\r
553                                 // console.log("Valid line: ", val);\r
554                                 let entry = {\r
555                                                 line: i,\r
556                                                 orgUserId: o[0],\r
557                                                 role: o[1]\r
558                                                 // leave status undefined, this could be valid.\r
559                                 };\r
560                                 if (o[0].toLowerCase() === 'orgUserId') {\r
561                                         // not valid for upload, so set status\r
562                                         entry.status = 'Header';\r
563                                 }\r
564                                 else if (o[0].trim() == '' || o[1].trim() == '') {\r
565                                         // defend against line with only a single comma etc.\r
566                                         entry.status = 'Failed to find 2 non-empty values';                                     \r
567                                 }\r
568                                 result.push(entry);\r
569                         } // len 2\r
570             } // for\r
571             return result;\r
572         };\r
573     });\r
574     \r
575   \r
576         \r
577 })();\r