summaryrefslogtreecommitdiffstats
path: root/ecomp-portal-FE-common
diff options
context:
space:
mode:
authorKishore Reddy, Gujja (kg811t) <kg811t@research.att.com>2018-05-14 17:19:51 -0400
committerKishore Reddy, Gujja (kg811t) <kg811t@research.att.com>2018-05-25 13:39:38 -0400
commit2845910b34682056c1949f82e39d9205a26554e9 (patch)
tree825474a899dc5783e6ea8c4aefd26b6d4c881dfd /ecomp-portal-FE-common
parent485296388748c1efb5737cf7ae9d4a8254681552 (diff)
Bulk upload changes and music health check apis
Issue-ID: PORTAL-290, PORTAL-291 Bulk upload changes and music health check apis Change-Id: I63d289d75420658ff4a14385a5106838fa8c32b2 Signed-off-by: Kishore Reddy, Gujja (kg811t) <kg811t@research.att.com>
Diffstat (limited to 'ecomp-portal-FE-common')
-rw-r--r--ecomp-portal-FE-common/client/app/services/functionalMenu/functionalMenu.service.js129
-rw-r--r--ecomp-portal-FE-common/client/app/services/widgets-catalog/widgets-catalog.service.js23
-rw-r--r--ecomp-portal-FE-common/client/app/views/account-onboarding/account-add-details/account-add-details.html2
-rw-r--r--ecomp-portal-FE-common/client/app/views/role/bulk-upload-dialogs/bulk-upload-functions-confirm.html135
-rw-r--r--ecomp-portal-FE-common/client/app/views/role/bulk-upload-dialogs/bulk-upload-global-role-functions-confirm.html117
-rw-r--r--ecomp-portal-FE-common/client/app/views/role/bulk-upload-dialogs/bulk-upload-role-functions-confirm.html122
-rw-r--r--ecomp-portal-FE-common/client/app/views/role/bulk-upload-dialogs/bulk-upload-role-functions-controller.js987
-rw-r--r--ecomp-portal-FE-common/client/app/views/role/bulk-upload-dialogs/bulk-upload-role-functions-modal.html105
-rw-r--r--ecomp-portal-FE-common/client/app/views/role/bulk-upload-dialogs/bulk-upload-role-functions-modal.less100
-rw-r--r--ecomp-portal-FE-common/client/app/views/role/bulk-upload-dialogs/bulk-upload-roles-confirm.html109
-rw-r--r--ecomp-portal-FE-common/client/app/views/role/role-create-edit-popup-controller.js4
-rw-r--r--ecomp-portal-FE-common/client/app/views/role/role-list-controller.js30
-rw-r--r--ecomp-portal-FE-common/client/app/views/role/role_list.html1
-rw-r--r--ecomp-portal-FE-common/client/app/views/users/users.controller.js10
-rw-r--r--ecomp-portal-FE-common/client/app/views/users/users.tpl.html1
-rw-r--r--ecomp-portal-FE-common/client/app/views/widget-onboarding/widget-details-dialog/widget-details.controller.js8
-rw-r--r--ecomp-portal-FE-common/client/app/views/widget-onboarding/widget-details-dialog/widget-details.modal.html2
17 files changed, 1866 insertions, 19 deletions
diff --git a/ecomp-portal-FE-common/client/app/services/functionalMenu/functionalMenu.service.js b/ecomp-portal-FE-common/client/app/services/functionalMenu/functionalMenu.service.js
index 6c8e6194..6d1d813d 100644
--- a/ecomp-portal-FE-common/client/app/services/functionalMenu/functionalMenu.service.js
+++ b/ecomp-portal-FE-common/client/app/services/functionalMenu/functionalMenu.service.js
@@ -329,6 +329,135 @@
});
return deferred.promise;
}
+
+ saveBulkRole(appId, appRole)
+ {
+ let canceller = this.$q.defer();
+ let isActive = false;
+
+ let cancel = () => {
+ if(isActive){
+ this.$log.debug('FunctionalMenuService::saveBulkRole: canceling the request');
+ canceller.resolve();
+ }
+ };
+
+ let promise = () => {
+ let deferred = this.$q.defer();
+ let url = this.conf.api.saveRole.replace(':appId', appId);
+ this.$http({
+ method: 'POST',
+ url: url,
+ cache: false,
+ data : appRole,
+ headers: {
+ 'X-ECOMP-RequestID':this.uuid.generate()
+ }
+ }).then( res => {
+ if (this.utilsService.isValidJSON(res)== false) {
+ deferred.reject('UsersService::saveBulkRole: Failed');
+ } else {
+ deferred.resolve(res.data);
+ }
+ })
+ .catch( status => {
+ deferred.reject(status);
+ });
+
+ return deferred.promise;
+ };
+
+ return {
+ cancel: cancel,
+ promise: promise
+ };
+ }
+
+ saveBulkFunction(appId, appFunction)
+ {
+ let canceller = this.$q.defer();
+ let isActive = false;
+
+ let cancel = () => {
+ if(isActive){
+ this.$log.debug('FunctionalMenuService::saveRoleFunction: canceling the request');
+ canceller.resolve();
+ }
+ };
+
+ let promise = () => {
+ let deferred = this.$q.defer();
+ let url = this.conf.api.saveRoleFunction.replace(':appId', appId);
+ this.$http({
+ method: 'POST',
+ url: url,
+ cache: false,
+ data : appFunction,
+ headers: {
+ 'X-ECOMP-RequestID':this.uuid.generate()
+ }
+ }).then( res => {
+ if (this.utilsService.isValidJSON(res)== false) {
+ deferred.reject('UsersService::saveRoleFunction: Failed');
+ } else {
+ deferred.resolve(res.data);
+ }
+ })
+ .catch( status => {
+ deferred.reject(status);
+ });
+
+ return deferred.promise;
+ };
+
+ return {
+ cancel: cancel,
+ promise: promise
+ };
+ }
+
+ updateBulkRoleFunction(appId, roleFunction)
+ {
+ let canceller = this.$q.defer();
+ let isActive = false;
+
+ let cancel = () => {
+ if(isActive){
+ this.$log.debug('FunctionalMenuService::updateBulkRoleFunction: canceling the request');
+ canceller.resolve();
+ }
+ };
+
+ let promise = () => {
+ let deferred = this.$q.defer();
+ let url = this.conf.api.uploadRoleFunction.replace(':appId', appId);
+ this.$http({
+ method: 'POST',
+ url: url,
+ cache: false,
+ data : roleFunction,
+ headers: {
+ 'X-ECOMP-RequestID':this.uuid.generate()
+ }
+ }).then( res => {
+ if (this.utilsService.isValidJSON(res)== false) {
+ deferred.reject('UsersService::updateBulkRoleFunction: Failed');
+ } else {
+ deferred.resolve(res.data);
+ }
+ })
+ .catch( status => {
+ deferred.reject(status);
+ });
+
+ return deferred.promise;
+ };
+
+ return {
+ cancel: cancel,
+ promise: promise
+ };
+ }
}
FunctionalMenuService.$inject = ['$q', '$log', '$http', 'conf','uuid4', 'utilsService'];
diff --git a/ecomp-portal-FE-common/client/app/services/widgets-catalog/widgets-catalog.service.js b/ecomp-portal-FE-common/client/app/services/widgets-catalog/widgets-catalog.service.js
index f7e5a476..0a3946bd 100644
--- a/ecomp-portal-FE-common/client/app/services/widgets-catalog/widgets-catalog.service.js
+++ b/ecomp-portal-FE-common/client/app/services/widgets-catalog/widgets-catalog.service.js
@@ -96,6 +96,29 @@
});
return deferred.promise;
}
+ getUploadFlag() {
+ let deferred = this.$q.defer();
+ let url = this.conf.api.widgetCommon + '/uploadFlag';
+ this.$http({
+ method: "GET",
+ url: url,
+ cache: false,
+ headers: {
+ 'X-Widgets-Type': 'all',
+ 'X-ECOMP-RequestID':this.uuid.generate()
+ }
+ }).then(res => {
+ if (res == null || res.data == null) {
+ deferred.reject("WidgetsCatalogService::getUploadFlag Failed");
+ } else {
+ deferred.resolve(res.data);
+ }
+ })
+ .catch(status => {
+ deferred.reject(status);
+ });
+ return deferred.promise;
+ }
createWidget(newWidget, file) {
console.log(newWidget);
diff --git a/ecomp-portal-FE-common/client/app/views/account-onboarding/account-add-details/account-add-details.html b/ecomp-portal-FE-common/client/app/views/account-onboarding/account-add-details/account-add-details.html
index 394971ce..03d7d1c4 100644
--- a/ecomp-portal-FE-common/client/app/views/account-onboarding/account-add-details/account-add-details.html
+++ b/ecomp-portal-FE-common/client/app/views/account-onboarding/account-add-details/account-add-details.html
@@ -194,7 +194,7 @@ padding-top:10px;
<div class="b2b-modal-footer">
<div class="cta-button-group cta-modal-footer-flex">
<div class="item">
- <div id="account-details-next-button" class="btn btn-alt btn-small" ng-click="$dismiss('cancel')">Cancel</div>
+ <div id="account-details-next-cancel" class="btn btn-alt btn-small" ng-click="$dismiss('cancel')">Cancel</div>
<div id="account-details-next-button" class="btn btn-alt btn-small" ng-click="accountAddDetails.saveChanges()">Save</div>
</div>
</div>
diff --git a/ecomp-portal-FE-common/client/app/views/role/bulk-upload-dialogs/bulk-upload-functions-confirm.html b/ecomp-portal-FE-common/client/app/views/role/bulk-upload-dialogs/bulk-upload-functions-confirm.html
new file mode 100644
index 00000000..cf24e9f5
--- /dev/null
+++ b/ecomp-portal-FE-common/client/app/views/role/bulk-upload-dialogs/bulk-upload-functions-confirm.html
@@ -0,0 +1,135 @@
+<!--
+ ============LICENSE_START==========================================
+ ONAP Portal
+ ===================================================================
+ Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ ===================================================================
+
+ Unless otherwise specified, all software contained herein is licensed
+ under the Apache License, Version 2.0 (the "License");
+ you may not use this software except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ Unless otherwise specified, all documentation contained herein is licensed
+ under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ you may not use this documentation except in compliance with the License.
+ You may obtain a copy of the License at
+
+ https://creativecommons.org/licenses/by/4.0/
+
+ Unless required by applicable law or agreed to in writing, documentation
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ ============LICENSE_END============================================
+
+ ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ -->
+<div>
+ <div class="b2b-modal-header">
+ <h2 class="heading-medium" id="newAdmin">Bulk Upload Functions
+ Confirmation</h2>
+ <div class="corner-button in">
+ <button type="button" class="close" aria-label="Close"
+ id="bulk-user-button-close" ng-click="$dismiss('cancel')"></button>
+ </div>
+ </div>
+ <div class="b2b-modal-body">
+
+ <!-- progress indicator -->
+ <div class="upload-instructions" ng-show="isProcessing">
+ {{progressMsg}} <br> <br> <span class="ecomp-spinner"></span>
+ </div>
+
+ <div ng-hide="isProcessing">
+ <div class="upload-instructions">Click OK to upload the valid
+ functions. Invalid or existing functions will be ignored.</div>
+ <p>
+ <span id="required" style="color: Red; font-size: 180%;"
+ visible="false">*</span>Type can only contain alphanumeric
+ characters, dots(.) and underscores(_)
+ </p>
+ <p>
+ <span id="required" style="color: Red; font-size: 180%;"
+ visible="false">*</span>Action can only contain alphanumeric
+ characters, hyphens(-), dots(.) and underscores(_) and single
+ asterisk character(*)
+ </p>
+ <p>
+ <span id="required" style="color: Red; font-size: 180%;"
+ visible="false">*</span>Instance/Code can only contain alphanumeric
+ characters, hyphens(-), dots(.), colons(:), forwardSlash(/) ,
+ asterisk(*) and underscores(_)
+ </p>
+ <p>
+ <span id="required" style="color: Red; font-size: 180%;"
+ visible="false">*</span>Name can only contain alphanumeric
+ characters, spaces, hyphens(-), dots(.) and underscores(_)
+ </p>
+ </div>
+ <div class="c-ecomp-portal-abs-table default"
+ style="height: 250px !important">
+ <table b2b-table table-data="uploadFile"
+ search-string="bulkRoleAndFunctions.searchString"
+ view-per-page="bulkRoleAndFunctions.viewPerPageIgnored"
+ current-page="bulkRoleAndFunctions.currentPageIgnored"
+ total-page="bulkRoleAndFunctions.totalPageIgnored">
+ <thead b2b-table-row type="header">
+ <tr>
+ <th id="th-line" b2b-table-header sortable="false">Line</th>
+ <th id="th-type" b2b-table-header sortable="false">Type</th>
+ <th id="th-instance" b2b-table-header sortable="false">Instance/Code</th>
+ <th id="th-action" b2b-table-header sortable="false">Action</th>
+ <th id="th-name" b2b-table-header sortable="false">Name</th>
+ <th id="th-status" b2b-table-header sortable="false">Status</th>
+ </tr>
+ </thead>
+ <!-- Use track-by="UNIQUE KEY HERE" or leave out if no unique keys in data -->
+ <tbody b2b-table-row type="body" class="table-body"
+ row-repeat="rowData in uploadFile">
+ <tr id="tr-rowData">
+ <td class="td-first" b2b-table-body>
+ <div ng-bind="rowData.line"></div>
+ </td>
+ <td b2b-table-body>
+ <div ng-bind="rowData.type"></div>
+ </td>
+ <td b2b-table-body>
+ <div ng-bind="rowData.instance"></div>
+ </td>
+ <td b2b-table-body>
+ <div ng-bind="rowData.action"></div>
+ </td>
+ <td b2b-table-body>
+ <div ng-bind="rowData.name"></div>
+ </td>
+ <td b2b-table-body>
+ <div ng-bind="rowData.status"></div>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+
+ </div>
+
+</div>
+<div class="b2b-modal-footer">
+ <div class="cta-button-group in">
+ <button id="bulk-user-ok-button" class="btn btn-alt btn-small"
+ ng-class="{disabled: isValidating}" ng-click="updateFunctionsInDB()">Ok</button>
+ <button id="bulk-user-cancel-button" class="btn btn-alt btn-small"
+ ng-click="$dismiss('cancel')">Cancel</button>
+ </div>
+</div>
+</div>
diff --git a/ecomp-portal-FE-common/client/app/views/role/bulk-upload-dialogs/bulk-upload-global-role-functions-confirm.html b/ecomp-portal-FE-common/client/app/views/role/bulk-upload-dialogs/bulk-upload-global-role-functions-confirm.html
new file mode 100644
index 00000000..4b173fd3
--- /dev/null
+++ b/ecomp-portal-FE-common/client/app/views/role/bulk-upload-dialogs/bulk-upload-global-role-functions-confirm.html
@@ -0,0 +1,117 @@
+<!--
+ ============LICENSE_START==========================================
+ ONAP Portal
+ ===================================================================
+ Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ ===================================================================
+
+ Unless otherwise specified, all software contained herein is licensed
+ under the Apache License, Version 2.0 (the "License");
+ you may not use this software except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ Unless otherwise specified, all documentation contained herein is licensed
+ under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ you may not use this documentation except in compliance with the License.
+ You may obtain a copy of the License at
+
+ https://creativecommons.org/licenses/by/4.0/
+
+ Unless required by applicable law or agreed to in writing, documentation
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ ============LICENSE_END============================================
+
+ ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ -->
+<div>
+ <div class="b2b-modal-header">
+ <h2 class="heading-medium" id="newAdmin">Bulk Upload
+ Global-Role-Functions Confirmation</h2>
+ <div class="corner-button in">
+ <button type="button" class="close" aria-label="Close"
+ id="bulk-user-button-close" ng-click="$dismiss('cancel')"></button>
+ </div>
+ </div>
+ <div class="b2b-modal-body">
+
+ <!-- progress indicator -->
+ <div class="upload-instructions" ng-show="isProcessing">
+ {{progressMsg}} <br> <br> <span class="ecomp-spinner"></span>
+ </div>
+
+ <div ng-hide="isProcessing">
+ <div class="upload-instructions">Click OK to upload the valid
+ requests. Invalid requests will be ignored.</div>
+ <div class="c-ecomp-portal-abs-table default"
+ style="height: 250px !important">
+ <table b2b-table table-data="uploadFile"
+ search-string="bulkRoleAndFunctions.searchString"
+ view-per-page="bulkRoleAndFunctions.viewPerPageIgnored"
+ current-page="bulkRoleAndFunctions.currentPageIgnored"
+ total-page="bulkRoleAndFunctions.totalPageIgnored">
+ <thead b2b-table-row type="header">
+ <tr>
+ <th id="th-line" b2b-table-header sortable="false">Line</th>
+ <th id="th-approle" b2b-table-header sortable="false">Global Role Name</th>
+ <th id="th-type" b2b-table-header sortable="false">Function Type</th>
+ <th id="th-instance" b2b-table-header sortable="false">Function Instance</th>
+ <th id="th-action" b2b-table-header sortable="false">Function Action</th>
+ <th id="th-delete" b2b-table-header sortable="false">Function Name</th>
+ <th id="th-status" b2b-table-header sortable="false">Status</th>
+ </tr>
+ </thead>
+ <!-- Use track-by="UNIQUE KEY HERE" or leave out if no unique keys in data -->
+ <tbody b2b-table-row type="body" class="table-body"
+ row-repeat="rowData in uploadFile">
+ <tr id="tr-rowData">
+ <td class="td-first" b2b-table-body>
+ <div ng-bind="rowData.line"></div>
+ </td>
+ <td b2b-table-body>
+ <div ng-bind="rowData.role"></div>
+ </td>
+ <td b2b-table-body>
+ <div ng-bind="rowData.type"></div>
+ </td>
+ <td b2b-table-body>
+ <div ng-bind="rowData.instance"></div>
+ </td>
+ <td b2b-table-body>
+ <div ng-bind="rowData.action"></div>
+ </td>
+ <td b2b-table-body>
+ <div ng-bind="rowData.name"></div>
+ </td>
+ <td b2b-table-body>
+ <div ng-bind="rowData.status"></div>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+
+ </div>
+
+ </div>
+ <div class="b2b-modal-footer">
+ <div class="cta-button-group in">
+ <button id="bulk-user-ok-button" class="btn btn-alt btn-small"
+ ng-class="{disabled: isValidating}"
+ ng-click="updateGlobalRoleFunctionsInDB()">Ok</button>
+ <button id="bulk-user-cancel-button" class="btn btn-alt btn-small"
+ ng-click="$dismiss('cancel')">Cancel</button>
+ </div>
+ </div>
+</div>
diff --git a/ecomp-portal-FE-common/client/app/views/role/bulk-upload-dialogs/bulk-upload-role-functions-confirm.html b/ecomp-portal-FE-common/client/app/views/role/bulk-upload-dialogs/bulk-upload-role-functions-confirm.html
new file mode 100644
index 00000000..dce8e99e
--- /dev/null
+++ b/ecomp-portal-FE-common/client/app/views/role/bulk-upload-dialogs/bulk-upload-role-functions-confirm.html
@@ -0,0 +1,122 @@
+<!--
+ ============LICENSE_START==========================================
+ ONAP Portal
+ ===================================================================
+ Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ ===================================================================
+
+ Unless otherwise specified, all software contained herein is licensed
+ under the Apache License, Version 2.0 (the "License");
+ you may not use this software except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ Unless otherwise specified, all documentation contained herein is licensed
+ under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ you may not use this documentation except in compliance with the License.
+ You may obtain a copy of the License at
+
+ https://creativecommons.org/licenses/by/4.0/
+
+ Unless required by applicable law or agreed to in writing, documentation
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ ============LICENSE_END============================================
+
+ ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ -->
+<div>
+ <div class="b2b-modal-header">
+ <h2 class="heading-medium" id="newAdmin">Bulk Upload
+ Role-Functions Confirmation</h2>
+ <div class="corner-button in">
+ <button type="button" class="close" aria-label="Close"
+ id="bulk-user-button-close" ng-click="$dismiss('cancel')"></button>
+ </div>
+ </div>
+ <div class="b2b-modal-body">
+
+ <!-- progress indicator -->
+ <div class="upload-instructions" ng-show="isProcessing">
+ {{progressMsg}} <br> <br> <span class="ecomp-spinner"></span>
+ </div>
+
+ <div ng-hide="isProcessing">
+ <div class="upload-instructions">Click OK to upload the valid
+ requests. Invalid requests will be ignored.</div>
+ <div class="c-ecomp-portal-abs-table default"
+ style="height: 250px !important">
+ <table b2b-table table-data="uploadFile"
+ search-string="bulkRoleAndFunctions.searchString"
+ view-per-page="bulkRoleAndFunctions.viewPerPageIgnored"
+ current-page="bulkRoleAndFunctions.currentPageIgnored"
+ total-page="bulkRoleAndFunctions.totalPageIgnored">
+ <thead b2b-table-row type="header">
+ <tr>
+ <th id="th-line" b2b-table-header sortable="false">Line</th>
+ <th id="th-approle" b2b-table-header sortable="false">Role
+ Name</th>
+ <th id="th-type" b2b-table-header sortable="false">Function
+ Type</th>
+ <th id="th-instance" b2b-table-header sortable="false">Function
+ Instance</th>
+ <th id="th-action" b2b-table-header sortable="false">Function
+ Action</th>
+ <th id="th-delete" b2b-table-header sortable="false">Function
+ Name</th>
+ <th id="th-status" b2b-table-header sortable="false">Status</th>
+ </tr>
+ </thead>
+ <!-- Use track-by="UNIQUE KEY HERE" or leave out if no unique keys in data -->
+ <tbody b2b-table-row type="body" class="table-body"
+ row-repeat="rowData in uploadFile">
+ <tr id="tr-rowData">
+ <td class="td-first" b2b-table-body>
+ <div ng-bind="rowData.line"></div>
+ </td>
+ <td b2b-table-body>
+ <div ng-bind="rowData.role"></div>
+ </td>
+ <td b2b-table-body>
+ <div ng-bind="rowData.type"></div>
+ </td>
+ <td b2b-table-body>
+ <div ng-bind="rowData.instance"></div>
+ </td>
+ <td b2b-table-body>
+ <div ng-bind="rowData.action"></div>
+ </td>
+ <td b2b-table-body>
+ <div ng-bind="rowData.name"></div>
+ </td>
+ <td b2b-table-body>
+ <div ng-bind="rowData.status"></div>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+
+ </div>
+
+ </div>
+ <div class="b2b-modal-footer">
+ <div class="cta-button-group in">
+ <button id="bulk-user-ok-button" class="btn btn-alt btn-small"
+ ng-class="{disabled: isValidating}"
+ ng-click="updateRoleFunctionsInDB()">Ok</button>
+ <button id="bulk-user-cancel-button" class="btn btn-alt btn-small"
+ ng-click="$dismiss('cancel')">Cancel</button>
+ </div>
+ </div>
+</div>
diff --git a/ecomp-portal-FE-common/client/app/views/role/bulk-upload-dialogs/bulk-upload-role-functions-controller.js b/ecomp-portal-FE-common/client/app/views/role/bulk-upload-dialogs/bulk-upload-role-functions-controller.js
new file mode 100644
index 00000000..41af0bc6
--- /dev/null
+++ b/ecomp-portal-FE-common/client/app/views/role/bulk-upload-dialogs/bulk-upload-role-functions-controller.js
@@ -0,0 +1,987 @@
+/*-
+ * ============LICENSE_START==========================================
+ * ONAP Portal
+ * ===================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ============LICENSE_END============================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+/**
+ * bulk upload role-functions controller
+ */
+'use strict';
+(function () {
+ class BulkRoleAndFunctionsModalCtrl {
+ constructor($scope, $log, $filter, $q, $modalInstance, $modal, ngDialog, message, confirmBoxService, usersService, applicationsService, functionalMenuService, RoleService) {
+ // Set to true for copious console output
+ var debug = false;
+ // Roles fetched from Role service
+ var appRoleFuncsResult = [];
+ // Functions fetched from Role service
+ var appFunctionsResult = [];
+ // Global roles fetched from Role service
+ var appGlobalRolesResult = [];
+
+ var appId = message.appid;
+
+ $scope.ngRepeatBulkUploadOptions = [
+ {id: '1', title: 'Functions', value: 'functions'},
+ {id: '2', title: 'Roles', value: 'roles'},
+ {id: '3', title: 'Role Functions', value: 'roleFunctions'},
+ {id: '4', title: 'Global Role Functions', value: 'globalRoleFunctions'}
+ ];
+
+ $scope.selectedUploadType = $scope.ngRepeatBulkUploadOptions[0];
+ $scope.UploadTypeInstruction = "Function Type, Function Instance, Function Action, Function Name";
+ $scope.changeUploadTypeInstruction = function(typeInstrc){
+ switch(typeInstrc) {
+ case 'functions':
+ $scope.UploadTypeInstruction = "Function Type, Function Instance, Function Action, Function Name";
+ break;
+ case 'roles':
+ $scope.UploadTypeInstruction = "Role Name, Priority (Optional)";
+ break;
+ case 'roleFunctions':
+ $scope.UploadTypeInstruction = "Role Name, Function Type, Function Instance, Function Action, Function Name";
+ break;
+ default:
+ $scope.UploadTypeInstruction = "Global Role Name, Function Type, Function Instance, Function Action, Function Name";
+ }
+ };
+
+ let init = () => {
+ if (debug)
+ $log.debug('BulkRoleAndFunctionsModalCtrl::init');
+ // Angular insists on this.
+ $scope.fileModel = {};
+ // Enable modal controls
+ this.step1 = true;
+
+ this.fileSelected = false;
+ }; // init
+
+ // Answers a function that compares properties with the specified name.
+ let getSortOrder = (prop, foldCase) => {
+ return function(a, b) {
+ let aProp = foldCase ? a[prop].toLowerCase() : a[prop];
+ let bProp = foldCase ? b[prop].toLowerCase() : b[prop];
+ if (aProp > bProp)
+ return 1;
+ else if (aProp < bProp)
+ return -1;
+ else
+ return 0;
+ }
+ }
+
+ // Caches the file name supplied by the event handler.
+ $scope.fileChangeHandler = (event, files) => {
+ this.fileSelected = true;
+ this.fileToRead = files[0];
+ if (debug)
+ $log.debug("BulkRoleAndFunctionsModalCtrl::fileChangeHandler: file is ", this.fileToRead);
+ }; // file change handler
+
+ /**
+ * Reads the contents of the file, calls portal endpoints to
+ * validate roles, userIds and existing role assignments;
+ * ultimately builds array of requests to be sent. Creates scope
+ * variable with input file contents for communication with
+ * functions.
+ *
+ * This function performs a synchronous step-by-step process
+ * using asynchronous promises. The code could all be inline
+ * here but the nesting becomes unwieldy.
+ */
+ $scope.readValidateFile = (typeUpload) => {
+ $scope.isProcessing = true;
+ $scope.progressMsg = 'Reading upload file...';
+ var reader = new FileReader();
+ reader.onload = function(event) {
+ if(typeUpload === 'roles'){
+ $scope.uploadFile = $filter('csvToRoleObj')(reader.result);
+ if (debug){
+ $log.debug('BulkRoleAndFunctionsModalCtrl::readValidateFile onload: data length is ' + $scope.uploadFile.length);
+ }
+ $scope.progressMsg = 'Fetching & validating application roles...';
+ // fetch app roles
+ RoleService.getRoles(appId).then(function (appRoles){
+ if (debug){
+ $log.debug("BulkRoleAndFunctionsModalCtrl::readValidateFile: getRoles returned " + JSON.stringify(appFunctions.data));
+ }
+ let availableRolesList = JSON.parse(appRoles.data);
+ appRoleFuncsResult = availableRolesList.availableRoles;
+ $scope.evalAppRolesCheckResults();
+ // Re sort by line for the confirmation dialog
+ $scope.uploadFile.sort(getSortOrder('line', false));
+ // We're done, confirm box may show the table
+ if (debug)
+ $log.debug('BulkRoleAndFunctionsModalCtrl::readValidateFile inner-then ends');
+ $scope.progressMsg = 'Done.';
+ $scope.isProcessing = false;
+ }, function(error) {
+ $log.error('BulkUserModalCtrl::readValidateFile: failed retrieving app roles info');
+ $scope.isProcessing = false;
+ });
+ } else if (typeUpload === 'roleFunctions'){
+ $scope.uploadFile = $filter('csvToRoleFuncObj')(reader.result);
+ if (debug){
+ $log.debug('BulkRoleAndFunctionsModalCtrl::readValidateFile onload: data length is ' + $scope.uploadFile.length);
+ }
+ $scope.progressMsg = 'Fetching & validating application role functions...';
+ //fetch app functions
+ RoleService.getRoleFunctionList(appId).then(function (appFunctions){
+ if (debug)
+ $log.debug("BulkRoleAndFunctionsModalCtrl::readValidateFile: getRoleFunctionList returned " + JSON.stringify(appFunctions.data));
+ let availableRoleFunctionsList = JSON.parse(appFunctions.data);
+ appFunctionsResult = availableRoleFunctionsList.availableRoleFunctions;
+ // fetch app roles
+ RoleService.getRoles(appId).then(function (appRoles){
+ if (debug){
+ $log.debug("BulkRoleAndFunctionsModalCtrl::readValidateFile: getRoles returned " + JSON.stringify(appFunctions.data));
+ }
+ let availableRolesList = JSON.parse(appRoles.data);
+ appRoleFuncsResult = availableRolesList.availableRoles;
+ $scope.evalAppRoleFuncsCheckResults();
+ // Re sort by line for the confirmation dialog
+ $scope.uploadFile.sort(getSortOrder('line', false));
+ // We're done, confirm box may show the table
+ if (debug)
+ $log.debug('BulkRoleAndFunctionsModalCtrl::readValidateFile inner-then ends');
+ $scope.progressMsg = 'Done.';
+ $scope.isProcessing = false;
+ }, function(error) {
+ $log.error('BulkUserModalCtrl::readValidateFile: failed retrieving app roles info');
+ $scope.isProcessing = false;
+ });
+ },
+ function(error) {
+ $log.error('BulkUserModalCtrl::readValidateFile: failed retrieving app functions info');
+ $scope.isProcessing = false;
+ }
+ );
+ } else if(typeUpload === 'functions'){
+ $scope.uploadFile = $filter('csvToFuncObj')(reader.result);
+ if (debug){
+ $log.debug('BulkRoleAndFunctionsModalCtrl::readValidateFile onload: data length is ' + $scope.uploadFile.length);
+ }
+ $scope.progressMsg = 'Fetching & validating the application functions...';
+ // fetch app functions
+ RoleService.getRoleFunctionList(appId).then(function (appFunctions){
+ if (debug)
+ $log.debug("BulkRoleAndFunctionsModalCtrl::readValidateFile: getRoleFunctionList returned " + JSON.stringify(appFunctions.data));
+ let availableRoleFunctionsList = JSON.parse(appFunctions.data);
+ appFunctionsResult = availableRoleFunctionsList.availableRoleFunctions;
+ $scope.verifyFunctions();
+ $scope.evalAppFunctionsCheckResults();
+ // Re sort by line for the confirmation dialog
+ $scope.uploadFile.sort(getSortOrder('line', false));
+ // We're done, confirm box may show the table
+ if (debug)
+ $log.debug('BulkRoleAndFunctionsModalCtrl::readValidateFile inner-then ends');
+ $scope.progressMsg = 'Done.';
+ $scope.isProcessing = false;
+ },
+ function(error) {
+ $log.error('BulkUserModalCtrl::readValidateFile: failed retrieving app functions info');
+ $scope.isProcessing = false;
+ }
+ );
+ } else if(typeUpload === 'globalRoleFunctions'){
+ $scope.uploadFile = $filter('csvToRoleFuncObj')(reader.result);
+ if (debug){
+ $log.debug('BulkRoleAndFunctionsModalCtrl::readValidateFile onload: data length is ' + $scope.uploadFile.length);
+ }
+ $scope.progressMsg = 'Fetching application global role functions...';
+ //fetch app functions
+ RoleService.getRoleFunctionList(appId).then(function (appFunctions){
+ if (debug)
+ $log.debug("BulkRoleAndFunctionsModalCtrl::readValidateFile: getRoleFunctionList returned " + JSON.stringify(appFunctions.data));
+ let availableRoleFunctionsList = JSON.parse(appFunctions.data);
+ appFunctionsResult = availableRoleFunctionsList.availableRoleFunctions;
+ // fetch app roles
+ RoleService.getRoles(appId).then(function (appRoles){
+ if (debug){
+ $log.debug("BulkRoleAndFunctionsModalCtrl::readValidateFile: getRoles returned " + JSON.stringify(appFunctions.data));
+ }
+ let availableRolesList = JSON.parse(appRoles.data);
+ appRoleFuncsResult = availableRolesList.availableRoles;
+ appRoleFuncsResult.forEach(function(appRole) {
+ if(appRole.name.toLowerCase().startsWith("global_")){
+ appGlobalRolesResult.push(appRole);
+ }
+ });
+ $scope.evalAppRoleFuncsCheckResults(typeUpload);
+ // Re sort by line for the confirmation dialog
+ $scope.uploadFile.sort(getSortOrder('line', false));
+ // We're done, confirm box may show the table
+ if (debug)
+ $log.debug('BulkRoleAndFunctionsModalCtrl::readValidateFile inner-then ends');
+ $scope.progressMsg = 'Done.';
+ $scope.isProcessing = false;
+ }, function(error) {
+ $log.error('BulkUserModalCtrl::readValidateFile: failed retrieving app roles info');
+ $scope.isProcessing = false;
+ });
+ },
+ function(error) {
+ $log.error('BulkUserModalCtrl::readValidateFile: failed retrieving app functions info');
+ $scope.isProcessing = false;
+ }
+ );
+ }
+
+ } // onload
+
+ // Invoke the reader on the selected file
+ reader.readAsText(this.fileToRead);
+ };
+
+ /**
+ * Evaluates the result set returned by the role service.
+ * Sets an uploadFile array element status if a functions is not
+ * defined. Reads and writes scope variable uploadFile. Reads
+ * closure variable appFunctionsResult.
+ */
+ $scope.verifyFunctions = () => {
+ if (debug)
+ $log.debug('BulkRoleAndFunctionsModalCtrl::verifyFunctions: appFunctions is ' + JSON.stringify(appFunctionsResult));
+ // check functions in upload file against defined app functions
+ $scope.uploadFile.forEach( function (uploadRow) {
+ // skip rows that already have a defined status: headers etc.
+ if (uploadRow.status) {
+ if (debug)
+ $log.debug('BulkRoleAndFunctionsModalCtrl::verifyFunctions: skip row ' + uploadRow.line);
+ return;
+ }
+ for (var i=0; i < appFunctionsResult.length; i++) {
+ if (uploadRow.type.toUpperCase() === appFunctionsResult[i].type.toUpperCase()
+ && uploadRow.instance.toUpperCase() === appFunctionsResult[i].code.toUpperCase()
+ && uploadRow.action.toUpperCase() === appFunctionsResult[i].action.toUpperCase()) {
+ if (debug)
+ $log.debug('BulkRoleAndFunctionsModalCtrl::verifyFunctions: match on function ' + uploadRow.type,
+ uploadRow.instance, uploadRow.type, uploadRow.type);
+ break;
+ }
+ }
+ }); // foreach
+ }; // verifyFunctions
+
+ /**
+ * Evaluates the result set of existing functions returned by
+ * the Roleservice and list of functions found in the upload file.
+ * Reads and writes scope variable uploadFile.
+ * Reads closure variable appFunctionsResult.
+ */
+ $scope.evalAppFunctionsCheckResults = () => {
+ if (debug)
+ $log.debug('BulkRoleAndFunctionsModalCtrl::evalAppFunctionsCheckResults: uploadFile length is ' + $scope.uploadFile.length);
+ $scope.uploadFile.forEach(function (uploadRow) {
+ if (uploadRow.status) {
+ if (debug)
+ $log.debug('BulkRoleAndFunctionsModalCtrl::evalAppFunctionsCheckResults: skip row ' + uploadRow.line);
+ return;
+ }
+ // Search for the match in the app-functions
+ // array
+ let isFunctionExist = false;
+ appFunctionsResult.forEach( function (exixtingFuncObj) {
+ if (uploadRow.type.toUpperCase() === exixtingFuncObj.type.toUpperCase()
+ && uploadRow.instance.toUpperCase() === exixtingFuncObj.code.toUpperCase()
+ && uploadRow.action.toUpperCase() === exixtingFuncObj.action.toUpperCase()) {
+ uploadRow.status = 'Function exits!';
+ uploadRow.isCreate = false;
+ isFunctionExist = true;
+ }
+ }); // for each result
+ if(!isFunctionExist) {
+ if(/[^a-zA-Z0-9\-\.\_]/.test(uploadRow.type)
+ || (uploadRow.action !== '*'
+ && /[^a-zA-Z0-9\-\.\_]/.test(uploadRow.action))
+ || /[^a-zA-Z0-9\-\:\_\./*]/.test(uploadRow.instance)
+ || /[^a-zA-Z0-9\-\_ \.]/.test(uploadRow.name)){
+ uploadRow.status = 'Invalid function';
+ uploadRow.isCreate = false;
+ } else {
+ if (debug){
+ $log.debug('BulkRoleAndFunctionsModalCtrl::evalAppFunctionsCheckResults: new function '
+ + uploadRow);
+ }
+ // After much back-and-forth I decided a clear indicator is better than blank in the table status column.
+ uploadRow.status = 'Create';
+ uploadRow.isCreate = true;
+ }
+ }
+ }); // for each row
+ }; // evalAppFunctionsCheckResults
+
+ /**
+ * Evaluates the result set of existing roles returned by
+ * the Roleservice and list of roles found in the upload file.
+ * Reads and writes scope variable uploadFile.
+ * Reads closure variable appRolesResult.
+ */
+ $scope.evalAppRolesCheckResults = () => {
+ if (debug)
+ $log.debug('BulkRoleAndFunctionsModalCtrl::evalAppRolesCheckResults: uploadFile length is ' + $scope.uploadFile.length);
+ $scope.uploadFile.forEach(function (uploadRow) {
+ if (uploadRow.status) {
+ if (debug)
+ $log.debug('BulkRoleAndFunctionsModalCtrl::evalAppRolesCheckResults: skip row ' + uploadRow.line);
+ return;
+ }
+ // Search for the match in the app-roles
+ // array
+ let isRoleExist = false;
+ appRoleFuncsResult.forEach( function (existingRoleObj) {
+ if (uploadRow.role.toUpperCase() === existingRoleObj.name.toUpperCase()) {
+ uploadRow.status = 'Role exits!';
+ uploadRow.isCreate = false;
+ isRoleExist = true;
+ }
+ }); // for each result
+ if(!isRoleExist) {
+ if(/[^a-zA-Z0-9\-\_ \.\/]/.test(uploadRow.role) ||
+ uploadRow.role.toLowerCase().startsWith("global_")){
+ uploadRow.status = 'Invalid role!';
+ uploadRow.isCreate = false;
+ } else {
+ if (debug){
+ $log.debug('BulkRoleAndFunctionsModalCtrl::evalAppRolesCheckResults: new function '
+ + uploadRow);
+ }
+ // After much back-and-forth I decided a clear indicator is better than blank in the table status column.
+ uploadRow.status = 'Create';
+ uploadRow.isCreate = true;
+ }
+ }
+ }); // for each row
+ }; // evalAppRolesCheckResults
+
+ /**
+ * Evaluates the result set of existing roles returned by
+ * the Roleservice and list of roles found in the upload file.
+ * Reads and writes scope variable uploadFile.
+ * Reads closure variable appRolesResult.
+ */
+ $scope.evalAppRoleFuncsCheckResults = (typeUpload) => {
+ if (debug)
+ $log.debug('BulkRoleAndFunctionsModalCtrl::evalAppRoleFuncsCheckResults: uploadFile length is ' + $scope.uploadFile.length);
+ $scope.uploadFile.forEach(function (uploadRow) {
+ if (uploadRow.status) {
+ if (debug)
+ $log.debug('BulkRoleAndFunctionsModalCtrl::evalAppRoleFuncsCheckResults: skip row ' + uploadRow.line);
+ return;
+ }
+ // Search for the match in the app-functions array
+ let isValidFunc = false;
+ appFunctionsResult.forEach(function (existingFuncObj){
+ if(uploadRow.type.toUpperCase() === existingFuncObj.type.toUpperCase()
+ && uploadRow.instance.toUpperCase() === existingFuncObj.code.toUpperCase()
+ && uploadRow.action.toUpperCase() === existingFuncObj.action.toUpperCase()
+ && uploadRow.name.toUpperCase() === existingFuncObj.name.toUpperCase()){
+ isValidFunc = true;
+ }
+ });
+
+ let isValidRole = false;
+ let isRoleFuncExist = false;
+ if(typeUpload === 'globalRoleFunctions'){
+ // Search for the match in the app-role array
+ appGlobalRolesResult.forEach( function (existingRoleObj) {
+ if (uploadRow.role.toUpperCase() === existingRoleObj.name.toUpperCase()) {
+ isValidRole = true;
+ if(isValidFunc){
+ existingRoleObj.roleFunctions.forEach(function (existingRoleFuncObj){
+ if(uploadRow.type.toUpperCase() === existingRoleFuncObj.type.toUpperCase()
+ && uploadRow.instance.toUpperCase() === existingRoleFuncObj.code.toUpperCase()
+ && uploadRow.action.toUpperCase() === existingRoleFuncObj.action.toUpperCase()){
+ isRoleFuncExist = true;
+ }
+ });
+ }
+ }
+ }); // for each result
+ } else {
+ // Search for the match in the app-role array
+ appRoleFuncsResult.forEach( function (existingRoleObj) {
+ if (uploadRow.role.toUpperCase() === existingRoleObj.name.toUpperCase()) {
+ isValidRole = true;
+ if(isValidFunc){
+ existingRoleObj.roleFunctions.forEach(function (existingRoleFuncObj){
+ if(uploadRow.type.toUpperCase() === existingRoleFuncObj.type.toUpperCase()
+ && uploadRow.instance.toUpperCase() === existingRoleFuncObj.code.toUpperCase()
+ && uploadRow.action.toUpperCase() === existingRoleFuncObj.action.toUpperCase()){
+ isRoleFuncExist = true;
+ }
+ });
+ }
+ }
+ }); // for each result
+ }
+
+ uploadRow.isCreate = false;
+ if(typeUpload === 'globalRoleFunctions' && (!isValidRole || !isValidFunc)){
+ uploadRow.status = 'Invalid global role function!';
+ } else if(typeUpload !== 'globalRoleFunctions' && (!isValidRole || !isValidFunc)){
+ uploadRow.status = 'Invalid role function!';
+ } else if(typeUpload === 'globalRoleFunctions' && !isRoleFuncExist) {
+ uploadRow.status = 'Add global role function!';
+ uploadRow.isCreate = true;
+ } else if(typeUpload !== 'globalRoleFunctions' && !isRoleFuncExist){
+ uploadRow.status = 'Add role function!';
+ uploadRow.isCreate = true;
+ } else if(typeUpload === 'globalRoleFunctions'){
+ uploadRow.status = 'Global role function exists!';
+ } else {
+ uploadRow.status = 'Role function exists!';
+ }
+
+ }); // for each row
+ }; // evalAppRolesCheckResults
+
+
+ /**
+ * Sends requests to Portal BE requesting application functions assignment.
+ * That endpoint handles creation of the application functions in the
+ * external auth system if necessary. Reads closure variable appFunctionsResult.
+ * Invoked by the Next button on the confirmation dialog.
+ */
+ $scope.updateFunctionsInDB = () => {
+ $scope.isProcessing = true;
+ $scope.progressMsg = 'Sending requests to application..';
+ if (debug)
+ $log.debug('BulkRoleAndFunctionsModalCtrl::updateFunctionsInDB: request length is ' + appUserRolesRequest.length);
+ var numberFunctionsSucceeded = 0;
+ let promises = [];
+ $scope.uploadFile.forEach(function(appFuncPostData) {
+ if (debug)
+ $log.debug('BulkRoleAndFunctionsModalCtrl::updateFunctionsInDB: appFuncPostData is ' + JSON.stringify(appFuncPostData));
+ let updateFunctionsFinalPostData = {
+ type: appFuncPostData.type,
+ code: appFuncPostData.instance,
+ action: appFuncPostData.action,
+ name: appFuncPostData.name
+ };
+ if (debug)
+ $log.debug('BulkRoleAndFunctionsModalCtrl::updateFunctionsInDB: updateFunctionsFinalPostData is ' + JSON.stringify(updateFunctionsFinalPostData));
+ let updatePromise = {};
+ if(appFuncPostData.isCreate){
+ updatePromise = functionalMenuService.saveBulkFunction(appId, updateFunctionsFinalPostData).promise().then(res => {
+ if (debug)
+ $log.debug('BulkRoleAndFunctionsModalCtrl::updateFunctionsInDB: updated successfully: ' + JSON.stringify(res));
+ numberFunctionsSucceeded++;
+ }).catch(err => {
+ // What to do if one of many fails??
+ $log.error('BulkRoleAndFunctionsModalCtrl::updateFunctionsInDB failed: ', err);
+ confirmBoxService.showInformation(
+ 'Failed to update the application functions. ' +
+ 'Error: ' + err.status).then(isConfirmed => { });
+ }).finally( () => {
+ });
+ }
+ promises.push(updatePromise);
+ }); // for each
+
+ // Run all the promises
+ $q.all(promises).then(function(){
+ $scope.isProcessing = false;
+ confirmBoxService.showInformation('Processed ' + numberFunctionsSucceeded + ' records.').then(isConfirmed => {
+ // Close the upload-confirm dialog
+ ngDialog.close();
+ });
+ });
+ }; // updateFunctionsInDB
+
+ /**
+ * Sends requests to Portal BE requesting application functions assignment.
+ * That endpoint handles creation of the application role in the
+ * external auth system if necessary. Reads closure variable appRoleFuncResult.
+ * Invoked by the Next button on the confirmation dialog.
+ */
+ $scope.updateRolesInDB = () => {
+ $scope.isProcessing = true;
+ $scope.progressMsg = 'Sending requests to application..';
+ if (debug)
+ $log.debug('BulkRoleAndFunctionsModalCtrl::updateRolesInDB: request length is ' + appUserRolesRequest.length);
+ var numberRolesSucceeded = 0;
+ let promises = [];
+ $scope.uploadFile.forEach(function(appRolePostData) {
+ let priority = parseInt(appRolePostData.priority);
+ if (debug)
+ $log.debug('BulkRoleAndFunctionsModalCtrl::updateRolesInDB: appRolePostData is ' + JSON.stringify(appFuncPostData));
+ let uplaodRolePostData = "";
+ if(isNaN(priority)){
+ uplaodRolePostData = {
+ name: appRolePostData.role,
+ active: true,
+ }
+ } else {
+ uplaodRolePostData = {
+ name: appRolePostData.role,
+ priority: appRolePostData.priority,
+ active: true,
+ }
+ }
+ var postData = {
+ role: uplaodRolePostData,
+ roleFunctions: [],
+ childRoles: []
+ }
+ if (debug)
+ $log.debug('BulkRoleAndFunctionsModalCtrl::updateRolesInDB: uplaodRoleFinalPostData is ' + JSON.stringify(uplaodRoleFinalPostData));
+ let updatePromise = {};
+ if(appRolePostData.isCreate){
+ updatePromise = functionalMenuService.saveBulkRole(appId, JSON.stringify(postData)).promise().then(res => {
+ if (debug)
+ $log.debug('BulkRoleAndFunctionsModalCtrl::updateRolesInDB: updated successfully: ' + JSON.stringify(res));
+ numberRolesSucceeded++;
+ }).catch(err => {
+ // What to do if one of many fails??
+ $log.error('BulkRoleAndFunctionsModalCtrl::updateRolesInDB failed: ', err);
+ confirmBoxService.showInformation(
+ 'Failed to update the application role. ' +
+ 'Error: ' + err.status).then(isConfirmed => { });
+ }).finally( () => {
+ });
+ }
+ promises.push(updatePromise);
+ }); // for each
+
+ // Run all the promises
+ $q.all(promises).then(function(){
+ $scope.isProcessing = false;
+ confirmBoxService.showInformation('Processed ' + numberRolesSucceeded + ' records. Please sync roles').then(isConfirmed => {
+ // Close the upload-confirm dialog
+ ngDialog.close();
+ });
+ });
+ }; // updateRolesInDB
+
+ /**
+ * Sends requests to Portal BE requesting role function assignment.
+ * That endpoint handles adding role function in the external auth system
+ * if necessary.Invoked by the Next button on the confirmation dialog.
+ */
+ $scope.updateRoleFunctionsInDB = () => {
+ $scope.isProcessing = true;
+ $scope.progressMsg = 'Sending requests to application..';
+ if (debug)
+ $log.debug('BulkRoleAndFunctionsModalCtrl::updateRoleFunctionsInDB: request length is ' + appUserRolesRequest.length);
+ var numberRoleFunctionSucceeded = 0;
+ let promises = [];
+ $scope.uploadFile.forEach(function(appRoleFuncPostData) {
+ if (debug)
+ $log.debug('BulkRoleAndFunctionsModalCtrl::updateRoleFunctionsInDB: appRoleFuncPostData is ' + JSON.stringify(appFuncPostData));
+ let updateRoleFunctionFinalPostData = {
+ roleName: appRoleFuncPostData.role,
+ type: appRoleFuncPostData.type,
+ instance: appRoleFuncPostData.instance,
+ action: appRoleFuncPostData.action,
+ name: appRoleFuncPostData.name,
+ isGlobalRolePartnerFunc: false
+ };
+ if (debug)
+ $log.debug('BulkRoleAndFunctionsModalCtrl::updateRoleFunctionsInDB: updateRoleFunctionFinalPostData is ' + JSON.stringify(updateFunctionsFinalPostData));
+ let updatePromise = {};
+ if(appRoleFuncPostData.isCreate){
+ updatePromise = functionalMenuService.updateBulkRoleFunction(appId, updateRoleFunctionFinalPostData).promise().then(res => {
+ if (debug)
+ $log.debug('BulkRoleAndFunctionsModalCtrl::updateRoleFunctionsInDB: updated successfully: ' + JSON.stringify(res));
+ numberRoleFunctionSucceeded++;
+ }).catch(err => {
+ // What to do if one of many fails??
+ $log.error('BulkRoleAndFunctionsModalCtrl::updateRoleFunctionsInDB failed: ', err);
+ confirmBoxService.showInformation(
+ 'Failed to update the application role function. ' +
+ 'Error: ' + err.status).then(isConfirmed => { });
+ }).finally( () => {
+ });
+ }
+ promises.push(updatePromise);
+ }); // for each
+
+ // Run all the promises
+ $q.all(promises).then(function(){
+ $scope.isProcessing = false;
+ confirmBoxService.showInformation('Processed ' + numberRoleFunctionSucceeded + ' records. Please sync roles to reflect in portal').then(isConfirmed => {
+ // Close the upload-confirm dialog
+ ngDialog.close();
+ });
+ });
+ }; // updateRoleFunctionsInDB
+
+ /**
+ * Sends requests to Portal requesting global role functions assignment.
+ * That endpoint handles updating global role functions in the external auth system
+ * if necessary. Invoked by the Next button on the confirmation dialog.
+ */
+ $scope.updateGlobalRoleFunctionsInDB = () => {
+ $scope.isProcessing = true;
+ $scope.progressMsg = 'Sending requests to application..';
+ if (debug)
+ $log.debug('BulkRoleAndFunctionsModalCtrl::updateGlobalRoleFunctionsInDB: request length is ' + appUserRolesRequest.length);
+ var numberGlobalRoleFunctionSucceeded = 0;
+ let promises = [];
+ $scope.uploadFile.forEach(function(appRoleFuncPostData) {
+ if (debug)
+ $log.debug('BulkRoleAndFunctionsModalCtrl::updateGlobalRoleFunctionsInDB: appRoleFuncPostData is ' + JSON.stringify(appFuncPostData));
+ let updateGlobalRoleFunctionFinalPostData = {
+ roleName: appRoleFuncPostData.role,
+ type: appRoleFuncPostData.type,
+ instance: appRoleFuncPostData.instance,
+ action: appRoleFuncPostData.action,
+ name: appRoleFuncPostData.name,
+ isGlobalRolePartnerFunc: true
+ };
+ if (debug)
+ $log.debug('BulkRoleAndFunctionsModalCtrl::updateGlobalRoleFunctionsInDB: updateRoleFunctionFinalPostData is ' + JSON.stringify(updateFunctionsFinalPostData));
+ let updatePromise = {};
+ if(appRoleFuncPostData.isCreate){
+ updatePromise = functionalMenuService.updateBulkRoleFunction(appId, updateGlobalRoleFunctionFinalPostData).promise().then(res => {
+ if (debug)
+ $log.debug('BulkRoleAndFunctionsModalCtrl::updateGlobalRoleFunctionsInDB: updated successfully: ' + JSON.stringify(res));
+ numberGlobalRoleFunctionSucceeded++;
+ }).catch(err => {
+ // What to do if one of many fails??
+ $log.error('BulkRoleAndFunctionsModalCtrl::updateGlobalRoleFunctionsInDB failed: ', err);
+ confirmBoxService.showInformation(
+ 'Failed to update the global role partner function. ' +
+ 'Error: ' + err.status).then(isConfirmed => { });
+ }).finally( () => {
+ });
+ }
+ promises.push(updatePromise);
+ }); // for each
+
+ // Run all the promises
+ $q.all(promises).then(function(){
+ $scope.isProcessing = false;
+ confirmBoxService.showInformation('Processed ' + numberGlobalRoleFunctionSucceeded + ' records. Please sync roles to reflect in portal').then(isConfirmed => {
+ // Close the upload-confirm dialog
+ ngDialog.close();
+ });
+ });
+ }; // updateGlobalRoleFunctionsInDB
+
+ // Sets the variable that hides/reveals the user controls
+ $scope.step2 = () => {
+ this.fileSelected = false;
+ $scope.selectedFile = null;
+ $scope.fileModel = null;
+ this.step1 = false;
+ }
+
+ // Navigate between dialog screens using step number: 1,2,...
+ $scope.navigateBack = () => {
+ this.step1 = true;
+ this.fileSelected = false;
+ };
+
+ // Opens a dialog to show the data to be uploaded.
+ // Invoked by the upload button on the bulk user dialog.
+ $scope.confirmUpload = (typeUpload) => {
+ // Start the process
+ $scope.readValidateFile(typeUpload);
+ // Dialog shows progress
+ if(typeUpload === 'functions'){
+ $modal.open({
+ templateUrl: 'app/views/role/bulk-upload-dialogs/bulk-upload-functions-confirm.html',
+ controller: '',
+ sizeClass: 'modal-medium',
+ resolve:'',
+ scope: $scope
+ })
+ } else if(typeUpload === 'roleFunctions'){
+ $modal.open({
+ templateUrl: 'app/views/role/bulk-upload-dialogs/bulk-upload-role-functions-confirm.html',
+ controller: '',
+ sizeClass: 'modal-medium',
+ resolve:'',
+ scope: $scope
+ })
+
+ } else if(typeUpload === 'roles'){
+ $modal.open({
+ templateUrl: 'app/views/role/bulk-upload-dialogs/bulk-upload-roles-confirm.html',
+ controller: '',
+ sizeClass: 'modal-medium',
+ resolve:'',
+ scope: $scope
+ })
+ } else if(typeUpload === 'globalRoleFunctions'){
+ $modal.open({
+ templateUrl: 'app/views/role/bulk-upload-dialogs/bulk-upload-global-role-functions-confirm.html',
+ controller: '',
+ sizeClass: 'modal-medium',
+ resolve:'',
+ scope: $scope
+ })
+ }
+ };
+
+ // Invoked by the Cancel button on the confirmation dialog.
+ $scope.cancelUpload = () => {
+ ngDialog.close();
+ };
+
+ init();
+ } // constructor
+ } // class
+ BulkRoleAndFunctionsModalCtrl.$inject = ['$scope', '$log', '$filter', '$q', '$modalInstance', '$modal', 'ngDialog', 'message', 'confirmBoxService', 'usersService', 'applicationsService', 'functionalMenuService', 'RoleService'];
+ angular.module('ecompApp').controller('BulkRoleAndFunctionsModalCtrl', BulkRoleAndFunctionsModalCtrl);
+
+ angular.module('ecompApp').directive('fileChange', ['$parse', function($parse){
+ return {
+ require: 'ngModel',
+ restrict: 'A',
+ link : function($scope, element, attrs, ngModel) {
+ var attrHandler = $parse(attrs['fileChange']);
+ var handler=function(e) {
+ $scope.$apply(function() {
+ attrHandler($scope, { $event:e, files:e.target.files } );
+ $scope.selectedFile = e.target.files[0].name;
+ });
+ };
+ element[0].addEventListener('change',handler,false);
+ }
+ }
+ }]);
+
+ angular.module('ecompApp').filter('csvToFuncObj',function() {
+ return function(input) {
+ var result = [];
+ var len, i, line, o;
+ var lines = input.split('\n');
+ // Need 1-based index below
+ for (len = lines.length, i = 1; i <= len; ++i) {
+ // Use 0-based index for array
+ line = lines[i - 1].trim();
+ if (line.length == 0) {
+ // console.log("Skipping blank line");
+ result.push({
+ line: i,
+ type: '',
+ instance: '',
+ action: '',
+ name: '',
+ status: 'Blank line'
+ });
+ continue;
+ }
+ o = line.split(',');
+ if (o.length !== 4) {
+ // other lengths not valid for upload
+ result.push({
+ line: i,
+ type: o[0],
+ instance: o[1],
+ action: o[2],
+ name: '',
+ status: 'Failed to find 4 comma-separated values'
+ });
+ }
+ else {
+ // console.log("Valid line: ", val);
+ let entry = {
+ line: i,
+ type: o[0],
+ instance: o[1],
+ action: o[2],
+ name: o[3]
+ // leave status undefined, this
+ // could be valid.
+ };
+ if (o[0].toLowerCase() === 'type') {
+ // not valid for upload, so set status
+ entry.status = 'Header';
+ }
+ else if (o[0].toLowerCase() === 'instance') {
+ // not valid for upload, so set status
+ entry.status = 'Header';
+ }
+ else if (o[0].toLowerCase() === 'action') {
+ // not valid for upload, so set status
+ entry.status = 'Header';
+ }
+ else if (o[0].toLowerCase() === 'name') {
+ // not valid for upload, so set status
+ entry.status = 'Header';
+ }
+ else if (o[0].trim() == '' || o[1].trim() == '' || o[2].trim() == '' || o[3].trim() == '') {
+ // defend against line with only a
+ // single comma etc.
+ entry.status = 'Failed to find non-empty values';
+ }
+ result.push(entry);
+ } // len 2
+ } // for
+ return result;
+ };
+ });
+
+ angular.module('ecompApp').filter('csvToRoleFuncObj',function() {
+ return function(input) {
+ var result = [];
+ var len, i, line, o;
+ var lines = input.split('\n');
+ // Need 1-based index below
+ for (len = lines.length, i = 1; i <= len; ++i) {
+ // Use 0-based index for array
+ line = lines[i - 1].trim();
+ if (line.length == 0) {
+ // console.log("Skipping blank line");
+ result.push({
+ line: i,
+ role:'',
+ type: '',
+ instance: '',
+ action: '',
+ name: '',
+ status: 'Blank line'
+ });
+ continue;
+ }
+ o = line.split(',');
+ if (o.length !== 5) {
+ // other lengths not valid for upload
+ result.push({
+ line: i,
+ role: o[0],
+ type: o[1],
+ instance: o[2],
+ action: o[3],
+ name: '',
+ status: 'Failed to find 4 comma-separated values'
+ });
+ }
+ else {
+ // console.log("Valid line: ", val);
+ let entry = {
+ line: i,
+ role: o[0],
+ type: o[1],
+ instance: o[2],
+ action: o[3],
+ name: o[4]
+ // leave status undefined, this
+ // could be valid.
+ };
+ if (o[0].toLowerCase() === 'role') {
+ // not valid for upload, so set status
+ entry.status = 'Header';
+ } else if (o[0].toLowerCase() === 'type') {
+ // not valid for upload, so set status
+ entry.status = 'Header';
+ }
+ else if (o[0].toLowerCase() === 'instance') {
+ // not valid for upload, so set status
+ entry.status = 'Header';
+ }
+ else if (o[0].toLowerCase() === 'action') {
+ // not valid for upload, so set status
+ entry.status = 'Header';
+ }
+ else if (o[0].toLowerCase() === 'name') {
+ // not valid for upload, so set status
+ entry.status = 'Header';
+ }
+ else if (o[0].trim() == '' || o[1].trim() == '' || o[2].trim() == '' || o[3].trim() == '' || o[4].trim() == '') {
+ // defend against line with only a
+ // single comma etc.
+ entry.status = 'Failed to find non-empty values';
+ }
+ result.push(entry);
+ } // len 2
+ } // for
+ return result;
+ };
+ });
+
+ angular.module('ecompApp').filter('csvToRoleObj',function() {
+ return function(input) {
+ var result = [];
+ var len, i, line, o;
+ var lines = input.split('\n');
+ // Need 1-based index below
+ for (len = lines.length, i = 1; i <= len; ++i) {
+ // Use 0-based index for array
+ line = lines[i - 1].trim();
+ if (line.length == 0) {
+ // console.log("Skipping blank line");
+ result.push({
+ line: i,
+ role:'',
+ priority: '',
+ status: 'Blank line'
+ });
+ continue;
+ }
+ o = line.split(',');
+ if (o.length === 0 && line.length !== 0) {
+ // other lengths not valid for upload
+ result.push({
+ line: i,
+ role: o[0],
+ priority:null
+ });
+ }
+ else {
+ // console.log("Valid line: ", val);
+ let entry = {
+ line: i,
+ role: o[0],
+ priority: o[1]
+ // leave status undefined, this
+ // could be valid.
+ };
+ if (o[0].toLowerCase() === 'role') {
+ // not valid for upload, so set status
+ entry.status = 'Header';
+ }
+ if (o[0].toLowerCase() === 'priority') {
+ // not valid for upload, so set status
+ entry.status = 'Header';
+ }
+ else if (o[0].trim() == '') {
+ // defend against line with only a
+ // single comma etc.
+ entry.status = 'Failed to find non-empty values';
+ }
+ result.push(entry);
+ } // len 2
+ } // for
+ return result;
+ };
+ });
+
+})();
diff --git a/ecomp-portal-FE-common/client/app/views/role/bulk-upload-dialogs/bulk-upload-role-functions-modal.html b/ecomp-portal-FE-common/client/app/views/role/bulk-upload-dialogs/bulk-upload-role-functions-modal.html
new file mode 100644
index 00000000..6c6a4e73
--- /dev/null
+++ b/ecomp-portal-FE-common/client/app/views/role/bulk-upload-dialogs/bulk-upload-role-functions-modal.html
@@ -0,0 +1,105 @@
+<!--
+ ============LICENSE_START==========================================
+ ONAP Portal
+ ===================================================================
+ Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ ===================================================================
+
+ Unless otherwise specified, all software contained herein is licensed
+ under the Apache License, Version 2.0 (the "License");
+ you may not use this software except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ Unless otherwise specified, all documentation contained herein is licensed
+ under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ you may not use this documentation except in compliance with the License.
+ You may obtain a copy of the License at
+
+ https://creativecommons.org/licenses/by/4.0/
+
+ Unless required by applicable law or agreed to in writing, documentation
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ ============LICENSE_END============================================
+
+ ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ -->
+<div>
+ <div class="b2b-modal-header">
+ <h2 class="heading-medium" id="newAdmin">Bulk Upload Role-Function</h2>
+ <div class="corner-button in">
+ <button type="button" class="close" aria-label="Close"
+ id="bulkuser-button-close" ng-click="$dismiss('cancel')"></button>
+ </div>
+ </div>
+ <div class="b2b-modal-body">
+ <div class="b2b-modal-body-div">
+ <div ng-show="bulkRoleAndFunctions.step1">
+ <div class="upload-instructions">Select Upload Type:</div>
+ <div class="c-ecomp-portal-abs-select default">
+
+ <select id="bulk-user-dropdown-apps" name="dropdown1" b2b-dropdown
+ ng-model="selectedUploadType.value" ng-change="changeUploadTypeInstruction(selectedUploadType.value)">
+ <option b2b-dropdown-list
+ option-repeat="d in ngRepeatBulkUploadOptions"
+ value="{{d.value}}">{{d.title}}</option>
+ </select>
+
+ </div>
+ </div>
+
+ <div ng-hide="bulkRoleAndFunctions.step1">
+ <div class="upload-instructions">Select Upload File:</div>
+ <!-- input type=file is difficult to style.
+ Instead use a label styled as a button. -->
+ <label class="file-label"> <input type="file"
+ file-change="fileChangeHandler($event,files)" ng-model="fileModel" />
+ <span></span>
+ </label>{{selectedFile}}
+ <div class="upload-instructions">
+ File must be .csv or .txt and one entry per line with this format:
+ <p>{{UploadTypeInstruction}}</p>
+ </div>
+ </div>
+
+ <!-- progress indicator in middle -->
+ <div ng-show="isProcessing">
+ <span class="ecomp-spinner"></span>
+ </div>
+ <br>
+ </div>
+ </div>
+ <div class="b2b-modal-footer">
+ <div class="cta-button-group in">
+ <button id="bulk-user-back-button" class="btn btn-alt btn-small"
+ ng-hide="bulkRoleAndFunctions.step1" ng-click="navigateBack()">Back</button>
+ <button id="bulk-user-next-button" class="btn btn-alt btn-small"
+ ng-hide="!bulkRoleAndFunctions.step1"
+ ng-click="!isProcessing && step2()"
+ ng-class="{disabled: isProcessing}">Next</button>
+ <button id="bulk-user-upload-button" class="btn btn-alt btn-small"
+ ng-hide="bulkRoleAndFunctions.step1"
+ ng-click="bulkRoleAndFunctions.fileSelected && confirmUpload(selectedUploadType.value)"
+ ng-class="{disabled: !bulkRoleAndFunctions.fileSelected}">Upload</button>
+ <button id="bulk-user-cancel-button" class="btn btn-alt btn-small"
+ ng-click="$dismiss('cancel')">Cancel</button>
+ </div>
+ </div>
+</div>
+
+<script>
+$(document).ready(function(){
+ $(".ngdialog-close").attr('id','dialog-close');
+});
+</script>
diff --git a/ecomp-portal-FE-common/client/app/views/role/bulk-upload-dialogs/bulk-upload-role-functions-modal.less b/ecomp-portal-FE-common/client/app/views/role/bulk-upload-dialogs/bulk-upload-role-functions-modal.less
new file mode 100644
index 00000000..8ab5603f
--- /dev/null
+++ b/ecomp-portal-FE-common/client/app/views/role/bulk-upload-dialogs/bulk-upload-role-functions-modal.less
@@ -0,0 +1,100 @@
+/*-
+ * ============LICENSE_START==========================================
+ * ONAP Portal
+ * ===================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ============LICENSE_END============================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+.bulk-user-modal {
+ height: 430px;
+
+ .title {
+ .dGray18r;
+ border-bottom: @blue-active 3px solid;
+ }
+
+ .main {
+ margin: 16px;
+
+ .upload-instructions {
+ .dGray14r;
+ }
+
+ // http://stackoverflow.com/questions/572768/styling-an-input-type-file-button
+
+ .file-label {
+ border: 1px solid #ffffff;
+ border-radius: 6px;
+ margin-top: 4px;
+ margin-bottom: 4px;
+ margin-left: 0px;
+ margin-right: 8px;
+ color: #ffffff;
+ background: #067ab4;
+ display: inline-block;
+ text-align: center;
+ font-family: Omnes-ECOMP-W02-Medium,Arial;
+ font-size: 14px;
+ height: 29px;
+ line-height: 29px;
+ width: 90px;
+
+ input[type="file"] {
+ // Hide the browser's control
+ display: none;
+ }
+
+ }
+
+ .file-label:hover {
+ background: #009fdb;
+ }
+
+ .file-label:active {
+ background: #009fdb;
+ }
+
+ .file-label:invalid+span {
+ color: #ffffff;
+ }
+
+ .file-label:valid+span {
+ color: #ffffff;
+ }
+
+ }
+
+}
+.b2b-modal-body-div{
+ height:250px;
+}
diff --git a/ecomp-portal-FE-common/client/app/views/role/bulk-upload-dialogs/bulk-upload-roles-confirm.html b/ecomp-portal-FE-common/client/app/views/role/bulk-upload-dialogs/bulk-upload-roles-confirm.html
new file mode 100644
index 00000000..e5e4a86b
--- /dev/null
+++ b/ecomp-portal-FE-common/client/app/views/role/bulk-upload-dialogs/bulk-upload-roles-confirm.html
@@ -0,0 +1,109 @@
+<!--
+ ============LICENSE_START==========================================
+ ONAP Portal
+ ===================================================================
+ Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ ===================================================================
+
+ Unless otherwise specified, all software contained herein is licensed
+ under the Apache License, Version 2.0 (the "License");
+ you may not use this software except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ Unless otherwise specified, all documentation contained herein is licensed
+ under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ you may not use this documentation except in compliance with the License.
+ You may obtain a copy of the License at
+
+ https://creativecommons.org/licenses/by/4.0/
+
+ Unless required by applicable law or agreed to in writing, documentation
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ ============LICENSE_END============================================
+
+ ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ -->
+<div>
+ <div class="b2b-modal-header">
+ <h2 class="heading-medium" id="newAdmin">Bulk Upload Roles
+ Confirmation</h2>
+ <div class="corner-button in">
+ <button type="button" class="close" aria-label="Close"
+ id="bulk-user-button-close" ng-click="$dismiss('cancel')"></button>
+ </div>
+ </div>
+ <div class="b2b-modal-body">
+
+ <!-- progress indicator -->
+ <div class="upload-instructions" ng-show="isProcessing">
+ {{progressMsg}} <br> <br> <span class="ecomp-spinner"></span>
+ </div>
+
+ <div ng-hide="isProcessing">
+ <div class="upload-instructions">Click OK to upload the valid
+ roles. Invalid or existing roles will be ignored.</div>
+ <p>
+ <span id="required" style="color: Red; font-size: 180%;"
+ visible="false">*</span>Name can only contain alphanumeric
+ characters, dots(.), forward slashes(/), and underscores(_)
+ </p>
+ </div>
+ <div class="c-ecomp-portal-abs-table default"
+ style="height: 250px !important">
+ <table b2b-table table-data="uploadFile"
+ search-string="bulkRoleAndFunctions.searchString"
+ view-per-page="bulkRoleAndFunctions.viewPerPageIgnored"
+ current-page="bulkRoleAndFunctions.currentPageIgnored"
+ total-page="bulkRoleAndFunctions.totalPageIgnored">
+ <thead b2b-table-row type="header">
+ <tr>
+ <th id="th-line" b2b-table-header sortable="false">Line</th>
+ <th id="th-name" b2b-table-header sortable="false">Name</th>
+ <th id="th-priority" b2b-table-header sortable="false">Priority</th>
+ <th id="th-status" b2b-table-header sortable="false">Status</th>
+ </tr>
+ </thead>
+ <!-- Use track-by="UNIQUE KEY HERE" or leave out if no unique keys in data -->
+ <tbody b2b-table-row type="body" class="table-body"
+ row-repeat="rowData in uploadFile">
+ <tr id="tr-rowData">
+ <td class="td-first" b2b-table-body>
+ <div ng-bind="rowData.line"></div>
+ </td>
+ <td b2b-table-body>
+ <div ng-bind="rowData.role"></div>
+ </td>
+ <td b2b-table-body>
+ <div ng-bind="rowData.priority"></div>
+ </td>
+ <td b2b-table-body>
+ <div ng-bind="rowData.status"></div>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+
+ </div>
+
+</div>
+<div class="b2b-modal-footer">
+ <div class="cta-button-group in">
+ <button id="bulk-user-ok-button" class="btn btn-alt btn-small"
+ ng-class="{disabled: isValidating}" ng-click="updateRolesInDB()">Ok</button>
+ <button id="bulk-user-cancel-button" class="btn btn-alt btn-small"
+ ng-click="$dismiss('cancel')">Cancel</button>
+ </div>
+</div>
diff --git a/ecomp-portal-FE-common/client/app/views/role/role-create-edit-popup-controller.js b/ecomp-portal-FE-common/client/app/views/role/role-create-edit-popup-controller.js
index 2c531262..2b49d9ab 100644
--- a/ecomp-portal-FE-common/client/app/views/role/role-create-edit-popup-controller.js
+++ b/ecomp-portal-FE-common/client/app/views/role/role-create-edit-popup-controller.js
@@ -63,9 +63,9 @@ app.controller('roleCreateEditController',function($scope, conf, $http, $modalIn
availableRoleFunction.selected = true;
console.log(availableRoleFunction.selected);
}
- };
+ }
$scope.availableRoleFunctions.push(availableRoleFunction);
- };
+ }
$scope.toggleRoleFunction = function(selected,selectedRoleFunction){
if($scope.roleFunctions){
diff --git a/ecomp-portal-FE-common/client/app/views/role/role-list-controller.js b/ecomp-portal-FE-common/client/app/views/role/role-list-controller.js
index 46ff0d73..acfb25e0 100644
--- a/ecomp-portal-FE-common/client/app/views/role/role-list-controller.js
+++ b/ecomp-portal-FE-common/client/app/views/role/role-list-controller.js
@@ -44,6 +44,7 @@ app.controller('roleListController', function ($scope,RoleService, applicationsS
$scope.goToUrl = function(roleIdVal) {
$state.go("root.role", {"roleId":roleIdVal});
}
+
$scope.toggleRole = function(appId, selected, availableRole) {
var toggleType = null;
if(selected) {
@@ -122,8 +123,29 @@ app.controller('roleListController', function ($scope,RoleService, applicationsS
});
}
};
+
+ $scope.openBulkUploadRolesAndFunctionsModal = function(appId) {
+ var modalInstance = $modal.open({
+ templateUrl: 'app/views/role/bulk-upload-dialogs/bulk-upload-role-functions-modal.html',
+ controller: 'BulkRoleAndFunctionsModalCtrl as bulkRoleAndFunctions',
+ sizeClass: 'modal-medium',
+ resolve: {
+ message: function () {
+ var message = {
+ appid: appId
+ };
+ return message;
+ }
+ }
+ });
+ modalInstance.result.then(function (confirmed) {
+ if(confirmed == 'confirmed'){
+ // update role list table
+ }
+ });
+ };
- //getCentalizedApps
+ // getCentalizedApps
$scope.getCentralizedApps = function(userId) {
RoleService.getCentralizedApps(userId).then(res=> {
if (res.length>0) {
@@ -193,7 +215,7 @@ app.controller('roleListController', function ($scope,RoleService, applicationsS
init();
- //edit Role
+ // edit Role
$scope.editRoleModalPopup = function(appId, availableRole) {
$scope.editRole = availableRole;
if(appId != undefined && availableRole.id != undefined){
@@ -215,7 +237,7 @@ app.controller('roleListController', function ($scope,RoleService, applicationsS
availableRoleFunctions: availableRoleFunctions,
appId: $scope.apps.selectedCentralizedApp,
role: role
- };
+ };
return message;
}
}
@@ -232,7 +254,7 @@ app.controller('roleListController', function ($scope,RoleService, applicationsS
};
- //add Role
+ // add Role
$scope.addRoleModalPopup = function(appId) {
if(appId){
var roleId = 0;
diff --git a/ecomp-portal-FE-common/client/app/views/role/role_list.html b/ecomp-portal-FE-common/client/app/views/role/role_list.html
index ae07c203..b082c3ea 100644
--- a/ecomp-portal-FE-common/client/app/views/role/role_list.html
+++ b/ecomp-portal-FE-common/client/app/views/role/role_list.html
@@ -60,6 +60,7 @@
<div id="button-create-role" align="left" class="admins-table-btn-create" >
<button id="button-create-role" ng-click="addRoleModalPopup(apps.selectedCentralizedApp)" class = "btn btn-alt btn-small">Create</button>
<button id="button-sync-role" ng-show="syncRolesApplied" ng-click="syncRolesFromExternalAuthSystem(apps.selectedCentralizedApp)" class = "btn btn-alt btn-small"><i class="icon-arrows-update-refresh-syncL" aria-hidden="true"></i>&nbsp;Sync Roles</button>
+ <button id="button-bulk-upload" ng-show="syncRolesApplied" ng-click="openBulkUploadRolesAndFunctionsModal(apps.selectedCentralizedApp)" class = "btn btn-alt btn-small"><i class="icon-arrows-upload" aria-hidden="true"></i>&nbsp;Bulk Upload</button>
</div>
<br>
<div class="property-label">
diff --git a/ecomp-portal-FE-common/client/app/views/users/users.controller.js b/ecomp-portal-FE-common/client/app/views/users/users.controller.js
index 0a05d702..dfe1da6c 100644
--- a/ecomp-portal-FE-common/client/app/views/users/users.controller.js
+++ b/ecomp-portal-FE-common/client/app/views/users/users.controller.js
@@ -253,16 +253,6 @@
});
};
- this.syncRolesFromExternalAuthSystem = (appId) =>{
- applicationsService.syncRolesEcompFromExtAuthSystem(appId).then(function(res){
- if(res.status == 200){
- confirmBoxService.showInformation('Sync operation completed successfully!').then(isConfirmed => {});
- } else{
- confirmBoxService.showInformation('Sync operation failed for '+app).then(isConfirmed => {});
- }
- });
- };
-
$scope.$watch('users.selectedApp.value', (newVal, oldVal) => {
if(typeof(newVal) != 'undefined' && !newVal.includes("Select")){
applicationsService.getSingleAppInfo(newVal).then(function(res) {
diff --git a/ecomp-portal-FE-common/client/app/views/users/users.tpl.html b/ecomp-portal-FE-common/client/app/views/users/users.tpl.html
index 14371236..ef08e50b 100644
--- a/ecomp-portal-FE-common/client/app/views/users/users.tpl.html
+++ b/ecomp-portal-FE-common/client/app/views/users/users.tpl.html
@@ -54,7 +54,6 @@
</div>
<button class="btn btn-alt btn-small" id="users-button-add" ng-click="users.openAddNewUserModal()"><i class="icon-people-userbookmark" aria-hidden="true"></i>&nbsp;Add User</button>
<button class="btn btn-alt btn-small" id="users-bulk-upload-button-add" ng-click="users.openBulkUserUploadModal()"><i class="icon-arrows-upload" aria-hidden="true"></i>&nbsp;Bulk Upload</button>
- <button class="btn btn-alt btn-small" id="users-button-sync" ng-show="syncRolesApplied" ng-click="users.syncRolesFromExternalAuthSystem(app.appId)"><i class="icon-arrows-update-refresh-syncL" aria-hidden="true"></i>&nbsp;Sync Roles</button>
</div>
</div>
<div ng-hide="users.isLoadingTable">
diff --git a/ecomp-portal-FE-common/client/app/views/widget-onboarding/widget-details-dialog/widget-details.controller.js b/ecomp-portal-FE-common/client/app/views/widget-onboarding/widget-details-dialog/widget-details.controller.js
index 377d5c80..b6429015 100644
--- a/ecomp-portal-FE-common/client/app/views/widget-onboarding/widget-details-dialog/widget-details.controller.js
+++ b/ecomp-portal-FE-common/client/app/views/widget-onboarding/widget-details-dialog/widget-details.controller.js
@@ -242,6 +242,14 @@
}).finally(()=> {
this.isLoadingTable = false;
});
+
+ widgetsCatalogService.getUploadFlag().then(res => {
+ this.uploadFlag=res;
+ }).catch(err => {
+ $log.error('WidgetOnboardingDetailsModalCtrl::init error: ' + err);
+ }).finally(()=> {
+ });
+
getAvailableApps();
getAvailableServices();
};
diff --git a/ecomp-portal-FE-common/client/app/views/widget-onboarding/widget-details-dialog/widget-details.modal.html b/ecomp-portal-FE-common/client/app/views/widget-onboarding/widget-details-dialog/widget-details.modal.html
index fd3a1248..ade07b95 100644
--- a/ecomp-portal-FE-common/client/app/views/widget-onboarding/widget-details-dialog/widget-details.modal.html
+++ b/ecomp-portal-FE-common/client/app/views/widget-onboarding/widget-details-dialog/widget-details.modal.html
@@ -145,7 +145,7 @@
</div>
</div>
- <div class="item required">
+ <div ng-show=" widgetOnboardingDetails.uploadFlag">
<div class="item-label">Upload Widget</div>
<div>
<input id="widget-onboarding-details-upload-file"