aboutsummaryrefslogtreecommitdiffstats
path: root/ccsdk-app-overlay
diff options
context:
space:
mode:
authorKotagiri, Ramprasad (rp5662) <rp5662@att.com>2020-08-07 15:54:10 -0400
committerKotagiri, Ramprasad (rp5662) <rp5662@att.com>2020-08-12 12:38:26 -0400
commit09762dc92a06fb885f7055796db390a3a1baa535 (patch)
treee377c24a2cccb0a7d90b7b8560a7d8eef048a610 /ccsdk-app-overlay
parentf796af3a840d0fd9319e3dfe45ef0e548cd90171 (diff)
CCSDK DCAE dashboard feature changes
Issue-ID: DCAEGEN2-1857 Issue-ID: DCAEGEN2-2074 Issue-ID: DCAEGEN2-2364 Change-Id: I97f5ec4599512ed848136971b11d4c2a137a4999 Signed-off-by: Kotagiri, Ramprasad (rp5662) <rp5662@att.com>
Diffstat (limited to 'ccsdk-app-overlay')
-rw-r--r--ccsdk-app-overlay/pom.xml7
-rw-r--r--ccsdk-app-overlay/src/main/webapp/WEB-INF/oom-app.hbm.xml49
-rw-r--r--ccsdk-app-overlay/src/main/webapp/app/ccsdk/cloudify/blueprint-controllers.js464
-rw-r--r--ccsdk-app-overlay/src/main/webapp/app/ccsdk/cloudify/blueprint-service.js114
-rw-r--r--ccsdk-app-overlay/src/main/webapp/app/ccsdk/cloudify/blueprint_popups.html187
-rw-r--r--ccsdk-app-overlay/src/main/webapp/app/ccsdk/cloudify/blueprint_table.html98
-rw-r--r--ccsdk-app-overlay/src/main/webapp/app/ccsdk/cloudify/deployment-controllers.js2352
-rw-r--r--ccsdk-app-overlay/src/main/webapp/app/ccsdk/cloudify/deployment-service.js97
-rw-r--r--ccsdk-app-overlay/src/main/webapp/app/ccsdk/cloudify/deployment_popups.html201
-rw-r--r--ccsdk-app-overlay/src/main/webapp/app/ccsdk/cloudify/deployment_table.html426
-rw-r--r--ccsdk-app-overlay/src/main/webapp/app/ccsdk/cloudify/execution-service.js27
-rw-r--r--ccsdk-app-overlay/src/main/webapp/app/ccsdk/cloudify/plugin-service.js31
-rw-r--r--ccsdk-app-overlay/src/main/webapp/app/ccsdk/cloudify/plugin-table-controller.js64
-rw-r--r--ccsdk-app-overlay/src/main/webapp/app/ccsdk/cloudify/plugin_table.html (renamed from ccsdk-app-overlay/src/main/webapp/app/ccsdk/home/controller_table.html)56
-rw-r--r--ccsdk-app-overlay/src/main/webapp/app/ccsdk/cloudify/tosca-table-controller.js106
-rw-r--r--ccsdk-app-overlay/src/main/webapp/app/ccsdk/cloudify/tosca_table.html87
-rw-r--r--ccsdk-app-overlay/src/main/webapp/app/ccsdk/consul/node_table.html4
-rw-r--r--ccsdk-app-overlay/src/main/webapp/app/ccsdk/consul/service_health_table.html6
-rw-r--r--ccsdk-app-overlay/src/main/webapp/app/ccsdk/external/angular-local-storage.js592
-rw-r--r--ccsdk-app-overlay/src/main/webapp/app/ccsdk/external/select.css362
-rw-r--r--ccsdk-app-overlay/src/main/webapp/app/ccsdk/external/select.js2427
-rw-r--r--ccsdk-app-overlay/src/main/webapp/app/ccsdk/home/api_doc.html26
-rw-r--r--ccsdk-app-overlay/src/main/webapp/app/ccsdk/home/appDS2.js32
-rw-r--r--ccsdk-app-overlay/src/main/webapp/app/ccsdk/home/controller-service.js159
-rw-r--r--ccsdk-app-overlay/src/main/webapp/app/ccsdk/home/ecd_popup_templates.html (renamed from ccsdk-app-overlay/src/main/webapp/app/ccsdk/home/oom_popup_templates.html)2
-rw-r--r--ccsdk-app-overlay/src/main/webapp/app/ccsdk/home/executions-view-controller.js45
-rw-r--r--ccsdk-app-overlay/src/main/webapp/app/ccsdk/home/executions_view.html5
-rw-r--r--ccsdk-app-overlay/src/main/webapp/app/ccsdk/home/http-interceptor.js29
-rw-r--r--ccsdk-app-overlay/src/main/webapp/app/ccsdk/home/oom-instances-controller.js70
-rw-r--r--ccsdk-app-overlay/src/main/webapp/app/ccsdk/home/oom-router.js97
-rw-r--r--ccsdk-app-overlay/src/main/webapp/app/ccsdk/home/oom-style.css301
-rw-r--r--ccsdk-app-overlay/src/main/webapp/app/ccsdk/home/oom_instances_popup.html86
-rw-r--r--ccsdk-app-overlay/src/main/webapp/app/ccsdk/home/oom_spa.html164
-rw-r--r--ccsdk-app-overlay/src/main/webapp/app/ccsdk/home/tree-view-controller.js113
-rw-r--r--ccsdk-app-overlay/src/main/webapp/app/ccsdk/home/tree-view-directive.js165
-rw-r--r--ccsdk-app-overlay/src/main/webapp/app/ccsdk/home/tree-view-style.css132
-rw-r--r--ccsdk-app-overlay/src/main/webapp/app/ccsdk/home/tree_view.html24
-rw-r--r--ccsdk-app-overlay/src/main/webapp/app/ccsdk/inventory/blueprint-controllers.js2300
-rw-r--r--ccsdk-app-overlay/src/main/webapp/app/ccsdk/inventory/blueprint-service.js91
-rw-r--r--ccsdk-app-overlay/src/main/webapp/app/ccsdk/inventory/deployment-controllers.js1352
-rw-r--r--ccsdk-app-overlay/src/main/webapp/app/ccsdk/inventory/deployment-service.js160
-rw-r--r--ccsdk-app-overlay/src/main/webapp/app/ccsdk/inventory/execution-service.js58
-rw-r--r--ccsdk-app-overlay/src/main/webapp/app/ccsdk/inventory/inventory_blueprint_popups.html108
-rw-r--r--ccsdk-app-overlay/src/main/webapp/app/ccsdk/inventory/inventory_blueprint_table.html470
-rw-r--r--ccsdk-app-overlay/src/main/webapp/app/ccsdk/inventory/inventory_deployment_popups.html1378
-rw-r--r--ccsdk-app-overlay/src/main/webapp/app/ccsdk/inventory/inventory_deployment_table.html148
-rw-r--r--ccsdk-app-overlay/src/main/webapp/app/ccsdk/inventory/inventory_execution_popups.html520
-rw-r--r--ccsdk-app-overlay/src/main/webapp/app/ccsdk/ops/dbcl_view.html6
-rw-r--r--ccsdk-app-overlay/src/main/webapp/app/ccsdk/ops/tabs-view-controller.js271
-rw-r--r--ccsdk-app-overlay/src/main/webapp/app/ccsdk/ops/tabs_view.html131
50 files changed, 9216 insertions, 6984 deletions
diff --git a/ccsdk-app-overlay/pom.xml b/ccsdk-app-overlay/pom.xml
index f6a95cf..d103674 100644
--- a/ccsdk-app-overlay/pom.xml
+++ b/ccsdk-app-overlay/pom.xml
@@ -6,12 +6,12 @@
<parent>
<groupId>org.onap.ccsdk.dashboard</groupId>
<artifactId>ccsdk-app-parent</artifactId>
- <version>1.3.2-SNAPSHOT</version>
+ <version>1.4.0-SNAPSHOT</version>
</parent>
<groupId>org.onap.ccsdk.dashboard</groupId>
<artifactId>ccsdk-app-overlay</artifactId>
- <version>1.3.2-SNAPSHOT</version>
+ <version>1.4.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>ONAP Operations Manager Dashboard overlay</name>
<description>CCSDK Dashboard web resources</description>
@@ -22,9 +22,11 @@
<skiptests>true</skiptests>
</properties>
+
<build>
<plugins>
<!-- Silence Eclipse warnings by declaring Java 1.8 class output format -->
+ <!--
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
@@ -34,6 +36,7 @@
<target>1.8</target>
</configuration>
</plugin>
+ -->
</plugins>
</build>
diff --git a/ccsdk-app-overlay/src/main/webapp/WEB-INF/oom-app.hbm.xml b/ccsdk-app-overlay/src/main/webapp/WEB-INF/oom-app.hbm.xml
deleted file mode 100644
index b302346..0000000
--- a/ccsdk-app-overlay/src/main/webapp/WEB-INF/oom-app.hbm.xml
+++ /dev/null
@@ -1,49 +0,0 @@
-<?xml version="1.0"?>
-<!--
- =============LICENSE_START=========================================================
-
- =================================================================================
- Copyright (c) 2017 AT&T Intellectual Property. All rights reserved.
- ================================================================================
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file 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.
- ============LICENSE_END=========================================================
-
- ECOMP is a trademark and service mark of AT&T Intellectual Property.
- -->
-
-<!DOCTYPE hibernate-mapping PUBLIC
- "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
- "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
-
-<hibernate-mapping package="org.onap.ccsdk.dashboard.domain">
-
- <!-- class mapping details -->
- <class name="ControllerEndpoint" table="ecd_endpoint">
- <id name="userId" column="user_id" />
- <property name="name" column="name"/>
- <property name="url" column="url"/>
- </class>
- <class name="EcdComponent" table="ecd_component">
- <id name="compId" column="ecd_component_id">
- <generator class="native">
- <param name="sequence">seq_ecd_component</param>
- </generator>
- </id>
- <property name="cname" column="ecd_component_name"/>
- <property name="dname" column="ecd_component_display"/>
- </class>
- <query name="getAllComponents">
- FROM EcdComponent
- </query>
-
-</hibernate-mapping>
diff --git a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/cloudify/blueprint-controllers.js b/ccsdk-app-overlay/src/main/webapp/app/ccsdk/cloudify/blueprint-controllers.js
deleted file mode 100644
index c764165..0000000
--- a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/cloudify/blueprint-controllers.js
+++ /dev/null
@@ -1,464 +0,0 @@
-/*******************************************************************************
- * =============LICENSE_START=========================================================
- *
- * =================================================================================
- * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file 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.
- * ============LICENSE_END=========================================================
- *
- * ECOMP is a trademark and service mark of AT&T Intellectual Property.
- *******************************************************************************/
-appDS2.controller('blueprintTableController', function($rootScope, $scope, $log, $modal, modalService, BlueprintService) {
- 'use strict';
-
- // Controls logging in this controller
- var debug = false;
-
- // this object holds all app data and functions
- $scope.ecdapp = {};
- // models for controls on screen
- $scope.ecdapp.tableData = [];
- $scope.ecdapp.currentPageNum = 1;
- $scope.ecdapp.viewPerPage = 10;
- // other
- $scope.ecdapp.errMsg = null;
- $scope.ecdapp.isDataLoading = true;
- $scope.ecdapp.isRequestFailed = false;
-
- /**
- * Loads the table. Interprets the remote controller's response and copies
- * to scope variables. The response is either list to be assigned to
- * tableData, or an error to be shown.
- */
- $scope.ecdapp.loadTable = function() {
- $scope.ecdapp.isDataLoading = true;
- BlueprintService.getBlueprints($scope.ecdapp.currentPageNum, $scope.ecdapp.viewPerPage)
- .then(function(jsonObj) {
- if (jsonObj.error) {
- $log.error("blueprintController.loadTable failed: " + jsonObj.error);
- $scope.ecdapp.isRequestFailed = true;
- $scope.ecdapp.errMsg = jsonObj.error;
- $scope.ecdapp.tableData = [];
- } else {
- if (debug)
- $log.debug("bluePrintController.loadTable succeeded, size " + jsonObj.data.length);
- $scope.ecdapp.isRequestFailed = false;
- $scope.ecdapp.errMsg = null;
- $scope.ecdapp.totalPages = jsonObj.totalPages;
- $scope.ecdapp.tableData = jsonObj.items;
- }
- $scope.ecdapp.isDataLoading = false;
- }, function(error) {
- $log.error("blueprintController.loadTable failed: " + error);
- $scope.ecdapp.isRequestFailed = true;
- $scope.ecdapp.errMsg = error;
- $scope.ecdapp.tableData = [];
- $scope.ecdapp.isDataLoading = false;
- });
- };
-
- /**
- * Invoked at first page load AND when
- * user clicks on the B2B pagination control.
- */
- $scope.pageChangeHandler = function(page) {
- // console.log('pageChangeHandler: current is ' + $scope.ecdapp.currentPageNum + ' new is ' + page);
- $scope.ecdapp.currentPageNum = page;
- $scope.ecdapp.loadTable();
- }
-
- /**
- * Shows a modal pop-up with blueprint content.
- * Passes data in via an object named "message".
- */
- $scope.ecdapp.viewBlueprintModalPopup = function(blueprint) {
- $scope.ecdapp.editBlueprint = null;
- var modalInstance = $modal.open({
- templateUrl : 'blueprint_view_popup.html',
- controller : 'blueprintViewCtrl',
- windowClass: 'modal-docked',
- sizeClass: 'modal-medium',
- resolve : {
- message : function() {
- var dataForPopup = {
- blueprint : blueprint
- };
- return dataForPopup;
- }
- }
- });
- modalInstance.result.then(function() {
- // No response.
- });
- };
-
- /**
- * Shows a modal pop-up to upload a blueprint.
- * Passes data in via an object named "message".
- * On success, updates the table.
- */
- $scope.ecdapp.uploadBlueprintModalPopup = function() {
- $scope.ecdapp.editBlueprint = null;
- var modalInstance = $modal.open({
- templateUrl : 'blueprint_upload_popup.html',
- controller : 'blueprintUploadCtrl',
- windowClass: 'modal-docked',
- sizeClass: 'modal-small',
- resolve : {
- message : function() {
- var dataForPopup = {
- blueprint : $scope.ecdapp.editBlueprint,
- blueprintList : $scope.ecdapp.tableData
- };
- return dataForPopup;
- }
- }
- });
- modalInstance.result.then(function(response) {
- if (debug)
- $log.debug('uploadBlueprintModalPopup: response: ' + JSON.stringify(response));
- if (response == null) {
- // $log.debug('user closed dialog');
- }
- else {
- if (response.error != null) {
- $log.error('uploadBlueprintModalPopup failed: ' + response.error);
- alert('Failed to upload blueprint:\n' + response.error);
- }
- else {
- // success, get the updated list.
- $scope.ecdapp.loadTable();
- }
- }
- });
- };
-
- /**
- * Shows a modal pop-up to create a deployment from a blueprint.
- * Passes data in via an object named "message".
- */
- $scope.ecdapp.deployBlueprintModalPopup = function(blueprint) {
- var modalInstance = $modal.open({
- templateUrl : 'blueprint_deploy_popup.html',
- controller : 'blueprintDeployCtrl',
- windowClass: 'modal-docked',
- sizeClass: 'modal-medium',
- resolve : {
- message : function() {
- var dataForPopup = {
- blueprint : blueprint
- };
- return dataForPopup;
- }
- }
- });
- modalInstance.result.then(function(response) {
- if (debug)
- $log.debug('deployBlueprintModalPopup: response: ' + JSON.stringify(response));
- if (response == null) {
- if (debug)
- $log.debug('user closed dialog');
- }
- else {
- if (response.error != null) {
- $log.error('deployBlueprintModalPopup failed: ' + response.error);
- alert('Failed to deploy blueprint:\n' + response.error);
- // No need to update THIS table.
- // Must switch to deployments page to see result? Awkward.
- }
- }
- });
- };
-
- /**
- * Shows a modal pop-up to confirm deletion.
- * On successful completion, updates the table.
- */
- $scope.ecdapp.deleteBlueprintModalPopup = function(blueprint) {
- modalService.popupConfirmWin("Confirm", "Delete blueprint with ID '"
- + blueprint.id + "'?", function() {
- BlueprintService.deleteBlueprint(blueprint.id).then(
- function(response) {
- if (debug)
- $log.debug('deleteBlueprintModalPopup: response: ' + JSON.stringify(response));
- if (response && response.error) {
- // $log.error('deleteBlueprint failed: ' + response.error);
- alert('Failed to delete blueprint:\n' + response.error);
- }
- else {
- // No response body on success.
- $scope.ecdapp.loadTable();
- }
- },
- function(error) {
- $log.error('BlueprintService.deleteBlueprint failed: ' + error);
- alert('Service failed to delete blueprint:\n' + error);
- });
- });
- };
-
- // Populate the table on load. Note that the b2b selector code
- // sets the page-number value, and the change event calls load table.
- // Do not call this here to avoid double load:
- // $scope.ecdapp.loadTable();
-
-});
-
-/*************************************************************************/
-
-appDS2.controller('blueprintUploadCtrl', function(
- $scope, $log, $modalInstance, message, BlueprintService) {
-
- 'use strict';
-
- // this object holds all app data and functions
- $scope.ecdapp = {};
- $scope.ecdapp.label = 'Upload Blueprint';
- $scope.ecdapp.uploadRequest =
- {
- blueprint_id : '',
- blueprint_filename : '',
- zip_url : ''
- };
-
- /**
- * Validates content of user-editable fields.
- * Uses the list in message.feedList
- * Returns null if all is well,
- * a descriptive error message otherwise.
- */
- $scope.ecdapp.validateRequest = function(uploadRequest) {
- if (uploadRequest == null)
- return "No data found.\nPlease enter some values.";
- if (uploadRequest.blueprint_id == null || uploadRequest.blueprint_id.trim() === '')
- return "ID is required.\nPlease enter a value.";
- if (uploadRequest.blueprint_filename == null || uploadRequest.blueprint_filename.trim() === '')
- return "File name is required.\nPlease enter a value.";
- if (uploadRequest.blueprint_filename.toLowerCase().substr(-4) !== 'yaml')
- return "File name must end with YAML.\nPlease use that suffix.";
- if (uploadRequest.zip_url == null || uploadRequest.zip_url.trim() === '')
- return "Zip file URL is required.\nPlease enter a value.";
- return null;
- }
-
- $scope.ecdapp.uploadBlueprint = function(uploadRequest) {
- var validateMsg = $scope.ecdapp.validateRequest(uploadRequest);
- if (validateMsg != null) {
- alert('Invalid upload request:\n' + validateMsg);
- return;
- }
- BlueprintService.uploadBlueprint(uploadRequest)
- .then(function(response) {
- // $log.debug('blueprintPopupCtrl: response: ' + response);
- if (response.error)
- alert('Failed to upload blueprint:\n' + response.error);
- else
- $modalInstance.close(response);
- },
- function (error) {
- $log.error('blueprintUploadCtrl: error while uploading: ' + error);
- alert('Server rejected upload request:\n' + error);
- }
- );
-
- };
-
-});
-
-/*************************************************************************/
-
-appDS2.controller('blueprintViewCtrl', function(
- $scope, $log, message, BlueprintService) {
-
- 'use strict';
-
- var debug = false;
-
- if (debug)
- $log.debug("blueprintViewCtrl.message: " + JSON.stringify(message));
-
- // this object holds all app data and functions
- $scope.ecdapp = {};
- $scope.ecdapp.blueprintId = message.blueprint.id;
-
- $scope.ecdapp.label = 'View Blueprint ' + message.blueprint.id;
-
- // Fetch the blueprint
- $scope.ecdapp.isDataLoading = true;
- BlueprintService.viewBlueprint(message.blueprint.id).then(function(jsonObj) {
- if (debug)
- $log.debug("blueprintViewCtrl.viewBlueprint response: " + JSON.stringify(jsonObj));
- if (jsonObj.error) {
- $scope.ecdapp.errMsg = 'Request Failed';
- }
- else {
- $scope.ecdapp.blueprint = jsonObj.content;
- }
- $scope.ecdapp.isDataLoading = false;
- }, function(error) {
- $scope.ecdapp.isDataLoading = false;
- alert('Failed to get blueprint. Please retry.');
- $log.error("blueprintViewCtrl failed: " + error);
- });
-
-});
-
-
-/*************************************************************************/
-
-appDS2.controller('blueprintDeployCtrl', function(
- $scope, $log, $modalInstance, message, DeploymentService) {
-
- 'use strict';
-
- // Controls logging in this controller
- var debug = false;
-
- // this object holds all app data and functions
- $scope.ecdapp = {};
- $scope.ecdapp.label = 'Deploy Blueprint';
-
- // Cache the input parameter names for validation
- if (debug)
- $log.debug('blueprintDeployCtrl: inputs: ' + JSON.stringify(message.blueprint.plan.inputs));
- $scope.ecdapp.inputsDict = message.blueprint.plan.inputs;
-
- // Copy the input parameter names and default values
- let inputsAndDefaults = {};
- for (var pkey in message.blueprint.plan.inputs) {
- if (debug)
- $log.debug('blueprintDeployCtrl: checking key ' + pkey);
- let dval = message.blueprint.plan.inputs[pkey].default;
- if (! dval)
- dval = '';
- inputsAndDefaults[pkey] = dval;
- }
- if (debug)
- $log.debug('blueprintDeployCtrl: inputsAndDefaults: ' + JSON.stringify(inputsAndDefaults));
-
- // Create an object for edit
- $scope.ecdapp.editRequest = {
- deployment_id : '',
- blueprint_id : message.blueprint.id,
- fileModel : null,
- parmFileDict : inputsAndDefaults
- };
-
- /**
- * Handler for file-read event reads file, parses YAML, validates content.
- */
- var fileReader = new FileReader();
- fileReader.onload = function(event) {
- let yamlString = fileReader.result;
- if (debug)
- $log.debug('fileReader.onload: read: ' + yamlString);
- let ydict = {};
- try {
- ydict = YAML.parse(yamlString);
- }
- catch (ex) {
- alert('Failed to parse file as YAML:\n' + ex);
- }
- // Process the file
- for (var ykey in ydict) {
- let yval = ydict[ykey];
- if (debug)
- $log.debug('fileReader.onload: typeof ' + ykey + ' is ' + typeof ykey);
- // Allow only expected keys with scalar values
- if (! (ykey in $scope.ecdapp.editRequest.parmFileDict))
- alert('Unexpected file content:\nKey not defined by blueprint:\n' + ykey);
- else if (typeof yval !== 'string' && typeof yval !== 'number')
- alert('Unexpected file content:\nNot a simple key-value pair:\n' + ykey);
- else
- $scope.ecdapp.editRequest.parmFileDict[ykey] = yval;
- }
- if (debug)
- $log.debug('fileReader.onload: parmFileDict: ' + JSON.stringify($scope.ecdapp.editRequest.parmFileDict));
-
- // Update table in all cases
- $scope.$apply();
- }
-
- // Handler for file-select event
- $scope.handleFileSelect = function() {
- if (debug)
- $log.debug('handleFileSelect: $scope.ecdapp.fileModel.name is ' + $scope.ecdapp.editRequest.fileModel.name);
- fileReader.readAsText($scope.ecdapp.editRequest.fileModel);
- };
-
- /**
- * Validates content of user-editable fields.
- * Returns null if all is well,
- * a descriptive error message otherwise.
- */
- $scope.ecdapp.validateRequest = function(editRequest) {
- if (editRequest == null)
- return 'No data found.\nPlease enter some values.';
- if (editRequest.deployment_id == null || editRequest.deployment_id.trim() == '')
- return 'Deployment ID is required.\nPlease enter a value.';
- if (editRequest.blueprint_id == null || editRequest.blueprint_id.trim() == '')
- return 'Blueprint ID is required.\nPlease enter a value.';
- // Check that every file parameter is defined by blueprint
- for (var pkey in $scope.ecdapp.editRequest.parmFileDict) {
- // Defined in blueprint?
- if (! $scope.ecdapp.inputsDict[pkey])
- return 'Unexpected input parameter\n' + pkey;
- // Populated?
- let parmVal = $scope.ecdapp.editRequest.parmFileDict[pkey];
- if (parmVal == null || (typeof (parmVal) === 'string' && parmVal.trim().length == 0))
- return 'Missing value for parameter\n' + pkey;
- }
- // Check that a value is supplied for every expected input
- for (var bkey in $scope.ecdapp.inputsDict) {
- if (! $scope.ecdapp.editRequest.parmFileDict[bkey])
- return 'Missing input parameter\n' + bkey;
- }
- return null;
- }
-
- $scope.ecdapp.deployBlueprint = function(editRequest) {
- if (debug)
- $log.debug('deployBlueprint: editRequest is ' + JSON.stringify($scope.ecdapp.editRequest));
- var validateMsg = $scope.ecdapp.validateRequest(editRequest);
- if (validateMsg != null) {
- alert('Invalid Request:\n' + validateMsg);
- return;
- }
- // Create request with key:value parameters dictionary
- let deployRequest = {
- deployment_id : editRequest.deployment_id,
- blueprint_id : editRequest.blueprint_id,
- parameters : {}
- };
- for (var pkey in $scope.ecdapp.editRequest.parmFileDict)
- deployRequest.parameters[pkey] = $scope.ecdapp.editRequest.parmFileDict[pkey];
- if (debug)
- $log.debug('deployBlueprint: deployRequest is ' + JSON.stringify(deployRequest));
-
- DeploymentService.deployBlueprint(deployRequest)
- .then(function(response) {
- if (response.error)
- alert('Failed to deploy blueprint:\n' + response.error);
- else
- $modalInstance.close(response);
- },
- function (error) {
- $log.error('blueprintDeployCtrl: error while deploying: ' + error);
- alert('Server rejected deployment request:\n' + error);
- }
- );
-
- };
-
-});
diff --git a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/cloudify/blueprint-service.js b/ccsdk-app-overlay/src/main/webapp/app/ccsdk/cloudify/blueprint-service.js
deleted file mode 100644
index f058b09..0000000
--- a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/cloudify/blueprint-service.js
+++ /dev/null
@@ -1,114 +0,0 @@
-/*******************************************************************************
- * =============LICENSE_START=========================================================
- *
- * =================================================================================
- * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file 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.
- * ============LICENSE_END=========================================================
- *
- * ECOMP is a trademark and service mark of AT&T Intellectual Property.
- *******************************************************************************/
-appDS2.factory('BlueprintService', function ($http, $q, $log) {
- return {
- /**
- * Gets one page of blue prints objects.
- * @param {Number} pageNum - page number; e.g., 1
- * @param {Number} viewPerPage - number of items per page; e.g., 25
- * @return {JSON} Response object from remote side
- */
- getBlueprints: function(pageNum,viewPerPage) {
- // cache control for IE
- let cc = "&cc=" + new Date().getTime().toString();
- let url = 'blueprints?pageNum=' + pageNum + '&viewPerPage=' + viewPerPage + cc;
- return $http({
- method: 'GET',
- url: url,
- cache: false,
- responseType: 'json'
- }).then(function(response) {
- if (response.data == null || typeof response.data != 'object')
- return $q.reject('BlueprintService.getBlueprints: response.data null or not object');
- else
- return response.data;
- },
- function(error) {
- $log.error('BlueprintService.getBlueprints failed: ' + JSON.stringify(error));
- return $q.reject(error.statusText);
- });
- },
-
- /**
- * Gets blueprint content.
- * @return {JSON} Response object from remote side
- */
- viewBlueprint: function(id) {
- // cache control for IE
- let url = 'viewblueprints/' + id;
- return $http({
- method: 'GET',
- url: url,
- cache: false,
- responseType: 'json'
- }).then(function(response) {
- if (response.data == null || typeof response.data != 'object')
- return $q.reject('BlueprintService.viewBlueprint: response.data null or not object');
- else
- return response.data;
- },
- function(error) {
- $log.error('BlueprintService.viewBlueprint failed: ' + JSON.stringify(error));
- return $q.reject(error.statusText);
- });
- },
-
- uploadBlueprint: function(uploadRequest) {
- let url = 'blueprints';
- return $http({
- method: 'POST',
- url: url,
- data: uploadRequest,
- responseType: 'json'
- }).then(function(response) {
- if (response.data == null || typeof response.data != 'object')
- return $q.reject('BlueprintService.uploadBlueprint: response.data null or not object');
- else
- return response.data;
- },
- function(error) {
- $log.error('BlueprintService.uploadBlueprint failed: ' + JSON.stringify(error));
- return $q.reject(error.statusText);
- });
- },
-
- deleteBlueprint: function(id) {
- let url = 'blueprints/' + id;
- return $http({
- method: 'DELETE',
- url: url,
- cache: false,
- responseType: 'json'
- }).then(function(response) {
- // This is called on response code 200..299.
- // On success, response.data is null.
- // On failure, response.data has an error message.
- return response.data;
- },
- function(error) {
- $log.error('BlueprintService.deleteBlueprint failed: ' + JSON.stringify(error));
- return $q.reject(error.statusText);
- });
- }
-
- };
-});
diff --git a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/cloudify/blueprint_popups.html b/ccsdk-app-overlay/src/main/webapp/app/ccsdk/cloudify/blueprint_popups.html
deleted file mode 100644
index ee92d84..0000000
--- a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/cloudify/blueprint_popups.html
+++ /dev/null
@@ -1,187 +0,0 @@
-<script type="text/ng-template" id="blueprint_upload_popup.html">
-
- <div class="b2b-modal-header ng-scope">
- <h2 id="myModalLabel" modal-title="">{{ecdapp.label}}</h2>
- <div class="corner-button in">
- <button type="button" class="close" aria-label="Close"
- ng-click="$dismiss('cancel')"></button>
- </div>
- </div>
-
- <div class="b2b-modal-body ng-scope ng-isolate-scope" tabindex="0"
- role="region" aria-label="Modal body content">
-
- <div class="row-nowrap">
- <div class="span12">
- <div class="form-row">
- <label for="blueprintId">*Blueprint ID</label>
- <div class="field-group">
- <!--autofocus is HTML5 attribute; doesn't work in Firefox-->
- <input id="blueprintId" class="span12" type="text" data-ng-model="ecdapp.editBlueprint.blueprint_id" autofocus>
- </div>
- </div>
- </div>
- </div>
-
- <div class="row-nowrap">
- <div class="span12">
- <div class="form-row">
- <label for="blueprintFileName">*File Name</label>
- <div class="field-group">
- <input id="blueprintFileName" class="span12" type="text" data-ng-model="ecdapp.editBlueprint.blueprint_filename">
- </div>
- </div>
- </div>
- </div>
-
- <div class="row-nowrap">
- <div class="span12">
- <div class="form-row">
- <label for="zipFileUrl">*Zip File URL</label>
- <div class="field-group">
- <input id="zipFileUrl" class="span12" type="text" data-ng-model="ecdapp.editBlueprint.zip_url">
- </div>
- </div>
- </div>
- </div>
-
- </div>
-
- <div class="b2b-modal-footer ng-scope ng-isolate-scope">
- <div class="cta-button-group in">
- <button class="btn btn-alt btn-small" type="button"
- ng-click="ecdapp.uploadBlueprint(ecdapp.editBlueprint);">
- Save
- </button>
- <button class="btn btn-small" type="button"
- ng-click="$dismiss('cancel')">
- Cancel
- </button>
- </div>
- </div>
-
-</script>
-
-<script type="text/ng-template" id="blueprint_view_popup.html">
-
- <div class="b2b-modal-header ng-scope">
- <h2 id="myModalLabel" modal-title="">{{ecdapp.label}}</h2>
- <div class="corner-button in">
- <button type="button" class="close" aria-label="Close"
- ng-click="$dismiss('cancel')"></button>
- </div>
- </div>
-
- <div class="b2b-modal-body ng-scope ng-isolate-scope" tabindex="0"
- role="region" aria-label="Modal body content">
-
- <!-- show progress indicator -->
- <div ng-show="ecdapp.isDataLoading">
- <div class="span" style="margin-bottom:20px;">
- <i class="icon-primary-spinner small" role="img" aria-label="Please wait while the content loads"></i>
- Please wait while the content loads.
- </div>
- </div>
-
- <div ng-show="ecdapp.errMsg">
- <span class="ecd-error-message">{{ecdapp.errMsg}}</span>
- </div>
-
- <div ng-hide="ecdapp.errMsg">
- <pre>{{ecdapp.blueprint}}</pre>
- </div>
-
- </div>
-
- <div class="b2b-modal-footer ng-scope ng-isolate-scope">
- <div class="cta-button-group in">
- <button class="btn btn-alt btn-small" type="button"
- ng-click="$dismiss('cancel');">
- Close
- </button>
- </div>
- </div>
-
-</script>
-
-<script type="text/ng-template" id="blueprint_deploy_popup.html">
-
- <style>
- .ecd-parameter-table
- {
- border: 1px;
- overflow: auto;
- }
- .ecd-parameter-table th
- {
- font-size: 1.4rem;
- }
- </style>
-
- <div class="b2b-modal-header ng-scope">
- <h2 id="myModalLabel" modal-title="">{{ecdapp.label}}</h2>
- <div class="corner-button in">
- <button type="button" class="close" aria-label="Close"
- ng-click="$dismiss('cancel')"></button>
- </div>
- </div>
-
- <div class="b2b-modal-body ng-scope ng-isolate-scope" tabindex="0"
- role="region" aria-label="Modal body content">
-
- <div class="row-nowrap">
- <div class="span12">
- <label for="blueprintFileName">*Deployment ID</label>
- <!--autofocus is HTML5 attribute; doesn't work in Firefox-->
- <input id="blueprintFileName" class="span12" type="text" data-ng-model="ecdapp.editRequest.deployment_id" autofocus/>
- </div>
- <div class="span12">
- <label for="blueprintId">Blueprint ID</label>
- <!--not editable-->
- <input id="blueprintId" class="span12" type="text" disabled="disabled" data-ng-model="ecdapp.editRequest.blueprint_id"/>
- </div>
- </div>
-
- <div class="row-nowrap">
- <div class="span12">
- <div class="form-row">
- <label for="parameters">*Parameters</label>
- <div b2b-file-drop file-model="ecdapp.editRequest.fileModel" on-drop="handleFileSelect()" align="center">
- <span b2b-file-link file-model="ecdapp.editRequest.fileModel" on-file-select="handleFileSelect()" >
- Drag &amp; drop a parameters YAML file here, or click to browse.
- </span>
- </div>
- </div>
- <div class="ecd-parameter-table">
- <table id="parameters">
- <tr id="ecd-table-header">
- <th width="40%">Name</th>
- <th width="60%">Value</th>
- </tr>
- <tbody ng-repeat="(pkey, pval) in ecdapp.editRequest.parmFileDict">
- <tr id="tr-rowData">
- <td ng-bind="pkey"/>
- <td ng-bind="pval"/>
- </tr>
- </tbody>
- </table>
- </div>
- </div>
- </div>
-
- </div>
-
- <div class="b2b-modal-footer ng-scope ng-isolate-scope">
- <div class="cta-button-group in">
- <button class="btn btn-alt btn-small" type="button"
- ng-click="ecdapp.deployBlueprint(ecdapp.editRequest);">
- Save
- </button>
- <button class="btn btn-small" type="button"
- ng-click="$dismiss('cancel')">
- Cancel
- </button>
- </div>
- </div>
-
-</script>
diff --git a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/cloudify/blueprint_table.html b/ccsdk-app-overlay/src/main/webapp/app/ccsdk/cloudify/blueprint_table.html
deleted file mode 100644
index 3ce60b9..0000000
--- a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/cloudify/blueprint_table.html
+++ /dev/null
@@ -1,98 +0,0 @@
-<div id="page-content">
-
- <h1 class="heading-page" id="blueprints-page">Blueprints</h1>
-
- <!-- show progress indicator -->
- <div ng-show="ecdapp.isDataLoading">
- <div class="span" style="margin-bottom:20px;">
- <i class="icon-primary-spinner small" role="img" aria-label="Please wait while the content loads"></i>
- Please wait while the content loads.
- </div>
- </div>
-
- <div ng-hide="ecdapp.isDataLoading">
-
- <div id="button-search-row">
- <button class="btn btn-alt btn-small"
- type="submit"
- ng-click="ecdapp.uploadBlueprintModalPopup();">
- Upload Blueprint...
- </button>
- <div style="float:right;">
- <div class="form-field form-field__small">
- <input
- type="text"
- placeholder="Search Blueprints"
- ng-model="ecdapp.searchString"/>
- </div>
- </div>
- </div>
-
- <div ng-show="ecdapp.isRequestFailed">
- <span class="ecd-error-message">{{ecdapp.errMsg}}</span>
- </div>
-
- <div ng-hide="ecdapp.isRequestFailed">
-
- <div
- b2b-table
- id="blueprints-table"
- class="b2b-table-div"
- table-data="ecdapp.tableData"
- search-string="ecdapp.searchString"
- current-page="ecdapp.currentPageIgnored"
- next-sort="ecdapp.nextSortIgnored">
-
- <table>
-
- <thead b2b-table-row type="header">
- <tr id="th-header-row">
- <th b2b-table-header key="id">ID</th>
- <th b2b-table-header key="main_file_name">File Name</th>
- <th b2b-table-header key="description">Description</th>
- <th b2b-table-header key="created_at">Created Date</th>
- <th b2b-table-header key="updated_at">Updated Date</th>
- <th b2b-table-header sortable="false"><i class="icon-controls-gear ecd-icon-display"></i></th>
- </tr>
- </thead>
-
- <tbody b2b-table-row type="body" row-repeat="rowData in ecdapp.tableData">
- <tr id="tr-rowData">
- <td b2b-table-body
- ng-bind="rowData.id"/>
- <td b2b-table-body
- ng-bind="rowData.main_file_name"/>
- <td b2b-table-body
- ng-bind="rowData.description"/>
- <td b2b-table-body
- ng-bind="rowData.created_at"/>
- <td b2b-table-body
- ng-bind="rowData.updated_at"/>
- <td b2b-table-body>
- <div ng-click="ecdapp.viewBlueprintModalPopup(rowData);">
- <a href="" title="View blueprint" class="icon-people-preview ecd-icon-action"></a>
- </div>
- <div ng-click="ecdapp.deployBlueprintModalPopup(rowData);">
- <a href="" title="Deploy blueprint" class="icon-datanetwork-cloudupload ecd-icon-action"></a>
- </div>
- <div ng-click="ecdapp.deleteBlueprintModalPopup(rowData);">
- <a href="" title="Delete blueprint" class="icon-misc-trash ecd-icon-action"></a>
- </div>
- </td>
- </tr>
- </tbody>
- </table>
- </div>
-
- <div b2b-pagination="" total-pages="ecdapp.totalPages"
- current-page="ecdapp.currentPageNum" click-handler="pageChangeHandler"
- role="navigation">
- </div>
-
- <div style="height: 10px;">
- <!-- space between page number and black footer -->
- </div>
-
- </div><!-- loading -->
-
-</div><!-- page content -->
diff --git a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/cloudify/deployment-controllers.js b/ccsdk-app-overlay/src/main/webapp/app/ccsdk/cloudify/deployment-controllers.js
index 1e80082..f89ce76 100644
--- a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/cloudify/deployment-controllers.js
+++ b/ccsdk-app-overlay/src/main/webapp/app/ccsdk/cloudify/deployment-controllers.js
@@ -1,26 +1,6 @@
-/*******************************************************************************
- * =============LICENSE_START=========================================================
- *
- * =================================================================================
- * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file 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.
- * ============LICENSE_END=========================================================
- *
- * ECOMP is a trademark and service mark of AT&T Intellectual Property.
- *******************************************************************************/
appDS2.controller('deploymentTableController', function(
- $rootScope, $scope, $log, $modal, DeploymentService) {
+ $rootScope, $scope, $log, $modal, $routeParams, DeploymentService, ControllerService,
+ InventoryDeploymentService, localStorageService, $interval) {
'use strict';
@@ -36,17 +16,469 @@ appDS2.controller('deploymentTableController', function(
// other
$scope.ecdapp.errMsg = null;
$scope.ecdapp.isDataLoading = true;
- $scope.ecdapp.isRequestFailed = false;
+ $scope.ecdapp.isRequestFailed = false;
+ $scope.ecdapp.useCache = true;
+ $scope.ecdapp.groupByTenant = false;
+ $scope.ecdapp.filterByUser = true;
+ $scope.ecdapp.cache_switch = {
+ value: true
+ };
+ $scope.ecdapp.getTenants = function() {
+ ControllerService.getTenants()
+ .then(function(jsonObj) {
+ if (jsonObj.error) {
+ $log.error("blueprintController.getTenants failed: " + jsonObj.error);
+ $scope.ecdapp.isRequestFailed = true;
+ $scope.ecdapp.errMsg = jsonObj.error;
+ $scope.ecdapp.tableData = [];
+ } else {
+ var tenants = [];
+ for (var tenIndx = 0; tenIndx < jsonObj.items.length; tenIndx++) {
+ tenants.push(jsonObj.items[tenIndx].name);
+ }
+ $scope.ecdapp.availableTenants = tenants;
+ if ($scope.ecdapp.availableTenants != undefined) {
+ $scope.ecdapp.selectedTenant = $scope.ecdapp.availableTenants[0];
+ }
+ localStorageService.set('tenants', JSON.stringify(tenants));
+ }
+ }, function(error) {
+ $log.error("blueprintController.getTenants failed: " + error);
+ $scope.ecdapp.isRequestFailed = true;
+ $scope.ecdapp.errMsg = error;
+ });
+ };
+
+ $scope.ecdapp.availableTenants = JSON.parse(localStorageService.get('tenants'));
+ if ($scope.ecdapp.availableTenants == undefined) {
+ $scope.ecdapp.getTenants();
+ } else {
+ //$scope.ecdapp.selectedTenant = $scope.ecdapp.availableTenants[0];
+ $scope.ecdapp.selectedTenant = '';
+ }
+ // searching
+ $scope.ecdapp.searchBy = $routeParams.depId;
+ if ($scope.ecdapp.searchBy == undefined) {
+ $scope.ecdapp.searchBy = "tenant:" + $scope.ecdapp.selectedTenant + ";" +
+ "cache:" + $scope.ecdapp.useCache + ";" +"owner:" + $scope.userId + ";";
+ //+ "user:" + $scope.ecdapp.filterByUser + ";";
+ } else {
+ if ($scope.ecdapp.searchBy.includes("owner")) {
+ if ($scope.ecdapp.searchBy.split(":")[1] === "group") {
+ $scope.ecdapp.filterByUser = false;
+ $scope.ecdapp.searchBy = "tenant:" + $scope.ecdapp.selectedTenant + ";" +
+ "cache:" + $scope.ecdapp.useCache + ";";
+ }
+ } else {
+ $scope.ecdapp.selectedTenant = $scope.ecdapp.searchBy.split(";")[0].split(":")[1]
+ }
+ }
+ //$scope.ecdapp.selectedTenant = "default_tenant";
+ //if ($scope.ecdapp.availableTenants != undefined) {
+ // $scope.ecdapp.selectedTenant = $scope.ecdapp.availableTenants[0];
+ //}
+
+ // sorting
+ $scope.ecdapp.sortBy = null;
+
+ $scope.ecdapp.isDisabled = false;
+ $scope.ecdapp.isDetailView = false;
+ $scope.ecdapp.isHelmType = false;
+ $scope.ecdapp.aafUsernameString;
+ $scope.ecdapp.dcaeTargetTypeString;
+ $scope.ecdapp.selectedSrvc;
+ $scope.ecdapp.usingAafFilter = false;
+ $scope.ecdapp.usingDcaeTargetTypeFilter = false;
+ $scope.ecdapp.selectedOwner;
+ $scope.ecdapp.availableServices; // = JSON.parse(localStorageService.get('deplNames'));
+ $scope.ecdapp.selectedServices;
+ $scope.ecdapp.bpOwners = JSON.parse(localStorageService.get('bpOwners'));
+
+ $scope.ecdapp.availableStatus =
+ ['pending','started','cancelling','force_cancelling','cancelled','terminated','failed'];
+ $scope.ecdapp.selectedStatus;
+
+ $scope.ecdapp.showingMoreFilters = false;
+
+ $scope.ecdapp.toggleMoreFilters = function() {
+ $scope.ecdapp.showingMoreFilters = !$scope.ecdapp.showingMoreFilters;
+ };
+
+
+ // Handler for disabling non aaf/dcae target type search fields
+ $scope.ecdapp.handleDisableOtherFields = function() {
+ //If using aaf filter, disable others
+ //and clear the dcae target type field
+ if ($scope.ecdapp.aafUsernameString == '' || typeof $scope.ecdapp.aafUsernameString == "undefined")
+ $scope.ecdapp.usingAafFilter = false;
+ else {
+ $scope.ecdapp.usingAafFilter = true;
+ $scope.ecdapp.dcaeTargetTypeString = '';
+ }
+
+ //If using dcae target type filter, disable others
+ //and clear the aaf filter field
+ if ($scope.ecdapp.dcaeTargetTypeString == '' || typeof $scope.ecdapp.dcaeTargetTypeString == "undefined")
+ $scope.ecdapp.usingDcaeTargetTypeFilter = false;
+ else {
+ $scope.ecdapp.usingDcaeTargetTypeFilter = true;
+ $scope.ecdapp.aafUsernameString = '';
+ }
+ };
+
+ // get the blueprints summary list
+ $scope.ecdapp.bp = [];
+ $scope.ecdapp.getAllAuthBpList = function() {
+ InventoryBlueprintService.getBlueprintsSummary()
+ .then(function(jsonObj) {
+ if (jsonObj.error) {
+ $log.error("inventoryDeploymentUpdateCtrl.loadTable failed: " + jsonObj.error);
+ $scope.ecdapp.errMsg = jsonObj.error;
+ $scope.ecdapp.bp = [];
+ } else {
+ $scope.ecdapp.errMsg = null;
+ $scope.ecdapp.bp = jsonObj;
+ }
+ $scope.ecdapp.isDataLoading = false;
+ }, function(error) {
+ $log.error("inventoryDeploymentUpdateCtrl.loadTable failed: " + error);
+ $scope.ecdapp.errMsg = error;
+ $scope.ecdapp.bp = [];
+ $scope.ecdapp.isDataLoading = false;
+ });
+ };
+
+ $scope.ecdapp.getDeploymentsList = function() {
+ InventoryDeploymentService.getDeploymentList($scope.ecdapp.searchBy).then(
+ function(jsonObj) {
+ if (jsonObj.error) {
+ $log.error("inventoryDeploymentController.getDeploymentList failed: "
+ + jsonObj.error);
+ $scope.ecdapp.availableServices = [];
+ } else {
+ //localStorageService.set('deplNames', JSON.stringify(jsonObj));
+ $scope.ecdapp.availableServices = jsonObj;
+ //JSON.parse(localStorageService.get('deplNames'));
+ }
+ },
+ function(error) {
+ $log.error("inventoryDeploymentController.getDeploymentList failed: "
+ + error);
+ $scope.ecdapp.availableServices = [];
+ });
+ };
+
+ $scope.ecdapp.reloadTable = function() {
+ $scope.ecdapp.currentPageNum = 1;
+ $scope.ecdapp.searchBy = "tenant:" + $scope.ecdapp.selectedTenant + ";"
+ +"cache:" + $scope.ecdapp.useCache + ";";
+ //+ "user:" + $scope.ecdapp.filterByUser + ";";
+ if ($scope.ecdapp.filterByUser) {
+ $scope.ecdapp.searchBy += "owner:" + $scope.userId + ";";
+ }
+ $scope.ecdapp.searchString = '';
+ $scope.ecdapp.resetFilters();
+ $scope.ecdapp.loadTable();
+ };
+
+ $scope.ecdapp.resetFilters = function() {
+ $scope.ecdapp.selectedServices = '';
+ $scope.ecdapp.selectedTenants = '';
+ $scope.ecdapp.selectedStatus = '';
+ $scope.ecdapp.selectedOwner = '';
+ $scope.ecdapp.isHelmType = false;
+ $scope.ecdapp.searchString = '';
+ $scope.ecdapp.searchBy = "tenant:" + $scope.ecdapp.selectedTenant + ";"
+ +"cache:" + $scope.ecdapp.useCache + ";";
+ if ($scope.ecdapp.filterByUser) {
+ $scope.ecdapp.searchBy += "owner:" + $scope.userId + ";";
+ }
+ /*
+ $scope.ecdapp.searchBy = "tenant:" + $scope.ecdapp.selectedTenant + ";"
+ +"cache:" + $scope.ecdapp.useCache + ";"+ "user:" + $scope.ecdapp.filterByUser + ";";
+ */
+ };
+ $scope.ecdapp.filterBySvc = function() {
+ if ( typeof $scope.ecdapp.searchString != "undefined" &&
+ $scope.ecdapp.searchString != '') {
+ if ($scope.ecdapp.searchString.includes("serviceRef:") ||
+ $scope.ecdapp.searchString.includes("tenant:") ||
+ $scope.ecdapp.searchString.includes("status:") ||
+ $scope.ecdapp.searchString.includes("helm:")) {
+ $scope.ecdapp.searchBy = $scope.ecdapp.searchString +";cache:" + $scope.ecdapp.useCache + ";";
+ // + "user:" + $scope.ecdapp.filterByUser + ";";
+ } else {
+ $scope.ecdapp.searchBy = "tenant:" + $scope.ecdapp.selectedTenant + ";"
+ $scope.ecdapp.searchBy += 'serviceRef:' + $scope.ecdapp.searchString +";cache:" + $scope.ecdapp.useCache + ";";
+ //+ "user:" + $scope.ecdapp.filterByUser + ";";
+ }
+ if ($scope.ecdapp.filterByUser) {
+ $scope.ecdapp.searchBy += "owner:" + $scope.userId + ";";
+ }
+ $scope.ecdapp.searchTable();
+ }
+ };
+
+ $scope.ecdapp.extendedfilterSrch = function() {
+ /*
+ $scope.ecdapp.searchBy = "tenant:" + $scope.ecdapp.selectedTenant + ";" +
+ "cache:" + $scope.ecdapp.useCache + ";" + "user:" + $scope.ecdapp.filterByUser + ";";
+ *
+ */
+ $scope.ecdapp.searchBy = "tenant:" + $scope.ecdapp.selectedTenant + ";" +
+ "cache:" + $scope.ecdapp.useCache + ";";
+
+ if ( typeof $scope.ecdapp.selectedServices != "undefined" &&
+ $scope.ecdapp.selectedServices != '') {
+ var svcFilterStr = 'serviceRef:' + $scope.ecdapp.selectedServices.toString();
+ $scope.ecdapp.searchBy += svcFilterStr + ";"
+ }
+ if ( typeof $scope.ecdapp.selectedOwner != "undefined" &&
+ $scope.ecdapp.selectedOwner != '') {
+ var ownerFilterStr = 'owner:' + $scope.ecdapp.selectedOwner.toString();
+ $scope.ecdapp.searchBy += ownerFilterStr + ';'
+ }
+ if ( typeof $scope.ecdapp.selectedStatus != "undefined" &&
+ $scope.ecdapp.selectedStatus != '') {
+ var statusFilterStr = 'status:' + $scope.ecdapp.selectedStatus.toString();
+ $scope.ecdapp.searchBy += statusFilterStr + ';'
+ }
+ if ( typeof $scope.ecdapp.isHelmType != "undefined" &&
+ $scope.ecdapp.isHelmType == true) {
+ var helmFilterStr = 'helm:' + $scope.ecdapp.isHelmType;
+ $scope.ecdapp.searchBy += helmFilterStr + ';'
+ }
+
+ if ($scope.ecdapp.filterByUser) {
+ $scope.ecdapp.searchBy += "owner:" + $scope.userId + ";";
+ }
+ //If using AAF username filter, ignore other fields and do filtered search.
+ if ($scope.ecdapp.usingAafFilter) {
+ var aafFilterStr = 'aafUsername:' + $scope.ecdapp.aafUsernameString.toString();
+ $scope.ecdapp.searchBy = $scope.ecdapp.aafUsernameString.toString();
+ $scope.ecdapp.searchString = aafFilterStr + ';';
+ $scope.ecdapp.searchTableAafFilter();
+ }
+ else if ($scope.ecdapp.usingDcaeTargetTypeFilter) {
+ var dcaeTargetTypeFilterStr = 'dcaeTargetType:' + $scope.ecdapp.dcaeTargetTypeString.toString();
+ $scope.ecdapp.searchBy = $scope.ecdapp.dcaeTargetTypeString.toString();
+ $scope.ecdapp.searchString = dcaeTargetTypeFilterStr + ';';
+ $scope.ecdapp.searchTableDcaeTargetTypeFilter();
+ }
+ else {
+ $scope.ecdapp.searchString = $scope.ecdapp.searchBy;
+ $scope.ecdapp.searchTable();
+ }
+ };
+
+ $scope.ecdapp.sortTable = function(sortBy) {
+ $scope.ecdapp.isDataLoading = true;
+ $scope.ecdapp.sortBy = sortBy;
+ DeploymentService.getDeployments($scope.ecdapp.currentPageNum,
+ $scope.ecdapp.viewPerPage, $scope.ecdapp.sortBy, $scope.ecdapp.searchBy).then(
+ function(jsonObj) {
+ if (jsonObj.error) {
+ $log.error("DeploymentController.sortTable failed: "
+ + jsonObj.error);
+ $scope.ecdapp.isRequestFailed = true;
+ $scope.ecdapp.errMsg = jsonObj.error;
+ $scope.ecdapp.tableData = [];
+ } else {
+ $scope.ecdapp.isRequestFailed = false;
+ $scope.ecdapp.errMsg = null;
+ $scope.ecdapp.totalPages = jsonObj.totalPages;
+ $scope.ecdapp.tableData = jsonObj.items;
+ }
+ $scope.ecdapp.isDataLoading = false;
+ },
+ function(error) {
+ $log.error("DeploymentController.sortTable failed: "
+ + error);
+ $scope.ecdapp.isRequestFailed = true;
+ $scope.ecdapp.errMsg = error;
+ $scope.ecdapp.tableData = [];
+ $scope.ecdapp.isDataLoading = false;
+ });
+ };
+ /**
+ * Loads the table. Interprets the remote controller's response and copies
+ * to scope variables. The response is either a list to be assigned to
+ * tableData, or an error to be shown.
+ */
+ $scope.ecdapp.searchTable = function() {
+ $scope.ecdapp.isDataLoading = true;
+ $scope.ecdapp.showingMoreFilters = false;
+ if ($scope.ecdapp.currentPageNum != 1) {
+ $scope.ecdapp.currentPageNum = 1;
+ } else {
+ $scope.ecdapp.stopLoading();
+ DeploymentService.getDeployments($scope.ecdapp.currentPageNum,
+ $scope.ecdapp.viewPerPage, $scope.ecdapp.sortBy, $scope.ecdapp.searchBy).then(
+ function(jsonObj) {
+ stop = $interval( function(){ $scope.ecdapp.loadTable(); }, 180000, 100, false);
+ $scope.ecdapp.searchString = $scope.ecdapp.searchBy;
+ if (jsonObj.error) {
+ $log.error("DeploymentController.loadTable failed: "
+ + jsonObj.error);
+ $scope.ecdapp.isRequestFailed = true;
+ $scope.ecdapp.errMsg = jsonObj.error;
+ $scope.ecdapp.tableData = [];
+ } else {
+ $scope.ecdapp.isRequestFailed = false;
+ $scope.ecdapp.errMsg = null;
+ $scope.ecdapp.totalPages = jsonObj.totalPages;
+ $scope.ecdapp.tableData = jsonObj.items;
+ }
+ $scope.ecdapp.isDataLoading = false;
+ },
+ function(error) {
+ $scope.ecdapp.searchString = $scope.ecdapp.searchBy;
+ $scope.ecdapp.searchBy = '';
+ $log.error("DeploymentController.loadTable failed: "
+ + error);
+ $scope.ecdapp.isRequestFailed = true;
+ $scope.ecdapp.errMsg = error;
+ $scope.ecdapp.tableData = [];
+ $scope.ecdapp.isDataLoading = false;
+ });
+ }
+ };
+
+ /**
+ * Loads the table with AAF Filter. Interprets the remote controller's response and copies
+ * to scope variables. The response is either a list to be assigned to
+ * tableData, or an error to be shown.
+ */
+ $scope.ecdapp.searchTableAafFilter = function() {
+ $scope.ecdapp.isDataLoading = true;
+ $scope.ecdapp.showingMoreFilters = false;
+ if ($scope.ecdapp.currentPageNum != 1) {
+ $scope.ecdapp.currentPageNum = 1;
+ } else {
+ $scope.ecdapp.stopLoading();
+ InventoryDeploymentService.getDeploymentsAafFilter($scope.ecdapp.currentPageNum,
+ $scope.ecdapp.viewPerPage, $scope.ecdapp.searchBy).then(
+ function(jsonObj) {
+ stop = $interval( function(){ $scope.ecdapp.loadTable(); }, 180000, 100, false);
+ $scope.ecdapp.searchString = $scope.ecdapp.searchBy;
+ if (jsonObj.error) {
+ $log.error("inventoryDeploymentController.loadTable failed: "
+ + jsonObj.error);
+ $scope.ecdapp.isRequestFailed = true;
+ $scope.ecdapp.errMsg = jsonObj.error;
+ $scope.ecdapp.tableData = [];
+ } else {
+ $scope.ecdapp.isRequestFailed = false;
+ $scope.ecdapp.errMsg = null;
+ $scope.ecdapp.totalPages = jsonObj.totalPages;
+ $scope.ecdapp.tableData = jsonObj.items;
+ //$scope.ecdapp.updateTable();
+ }
+ $scope.ecdapp.isDataLoading = false;
+ },
+ function(error) {
+ $scope.ecdapp.searchString = $scope.ecdapp.searchBy;
+ $scope.ecdapp.searchBy = '';
+ $log.error("inventoryDeploymentController.loadTable failed: "
+ + error);
+ $scope.ecdapp.isRequestFailed = true;
+ $scope.ecdapp.errMsg = error;
+ $scope.ecdapp.tableData = [];
+ $scope.ecdapp.isDataLoading = false;
+ });
+ }
+ };
+
+ /**
+ * Loads the table with Dcae target type Filter. Interprets the remote controller's response and copies
+ * to scope variables. The response is either a list to be assigned to
+ * tableData, or an error to be shown.
+ */
+ $scope.ecdapp.searchTableDcaeTargetTypeFilter = function() {
+ $scope.ecdapp.isDataLoading = true;
+ $scope.ecdapp.showingMoreFilters = false;
+ if ($scope.ecdapp.currentPageNum != 1) {
+ $scope.ecdapp.currentPageNum = 1;
+ } else {
+ $scope.ecdapp.stopLoading();
+ InventoryDeploymentService.getDeploymentsDcaeTargetTypeFilter($scope.ecdapp.currentPageNum,
+ $scope.ecdapp.viewPerPage, $scope.ecdapp.searchBy).then(
+ function(jsonObj) {
+ stop = $interval( function(){ $scope.ecdapp.loadTable(); }, 180000, 100, false);
+ $scope.ecdapp.searchString = $scope.ecdapp.searchBy;
+ if (jsonObj.error) {
+ $log.error("inventoryDeploymentController.loadTable failed: "
+ + jsonObj.error);
+ $scope.ecdapp.isRequestFailed = true;
+ $scope.ecdapp.errMsg = jsonObj.error;
+ $scope.ecdapp.tableData = [];
+ } else {
+ $scope.ecdapp.isRequestFailed = false;
+ $scope.ecdapp.errMsg = null;
+ $scope.ecdapp.totalPages = jsonObj.totalPages;
+ $scope.ecdapp.tableData = jsonObj.items;
+ //$scope.ecdapp.updateTable();
+ }
+ $scope.ecdapp.isDataLoading = false;
+ },
+ function(error) {
+ $scope.ecdapp.searchString = $scope.ecdapp.searchBy;
+ $scope.ecdapp.searchBy = '';
+ $log.error("inventoryDeploymentController.loadTable failed: "
+ + error);
+ $scope.ecdapp.isRequestFailed = true;
+ $scope.ecdapp.errMsg = error;
+ $scope.ecdapp.tableData = [];
+ $scope.ecdapp.isDataLoading = false;
+ });
+ }
+ };
+ $scope.ecdapp.stopLoading = function() {
+ if (angular.isDefined(stop)) {
+ $interval.cancel(stop);
+ stop = undefined;
+ }
+ };
+
+ $scope.ecdapp.toggleRefresh = function() {
+ if ($scope.ecdapp.useCache === true) {
+ stop = $interval( function(){ $scope.ecdapp.loadTable(); }, 180000, 100, false);
+ } else {
+ $scope.ecdapp.stopLoading();
+ }
+ };
+
+ if ($scope.ecdapp.useCache === true) {
+ stop = $interval( function(){ $scope.ecdapp.loadTable(); }, 180000, 100, false);
+ }
+
+ $scope.ecdapp.toggleUserFilt = function() {
+ if ($scope.ecdapp.filterByUser === true) {
+ $scope.ecdapp.groupByTenant = false;
+ $scope.ecdapp.selectedTenant = '';
+ } else {
+ $scope.ecdapp.searchString = '';
+ }
+ $scope.ecdapp.reloadTable();
+ }
+
+ $scope.ecdapp.toggleTenantFilt = function() {
+ if ($scope.ecdapp.groupByTenant === false) {
+ $scope.ecdapp.selectedTenant = '';
+ }
+ }
/**
* Loads the table. Interprets the remote controller's response and copies
* to scope variables. The response is either a list to be assigned to
* tableData, or an error to be shown.
*/
- $scope.ecdapp.loadTable = function() {
+ $scope.ecdapp.loadTable = function(sortBy, searchBy) {
$scope.ecdapp.isDataLoading = true;
+ //$scope.ecdapp.searchString = '';
+ $scope.ecdapp.sortBy = sortBy;
DeploymentService.getDeployments($scope.ecdapp.currentPageNum,
- $scope.ecdapp.viewPerPage).then(
+ $scope.ecdapp.viewPerPage, $scope.ecdapp.sortBy, $scope.ecdapp.searchBy).then(
function(jsonObj) {
if (jsonObj.error) {
$log.error("deploymentController.loadTable failed: "
@@ -69,7 +501,13 @@ appDS2.controller('deploymentTableController', function(
$scope.ecdapp.errMsg = error;
$scope.ecdapp.tableData = [];
$scope.ecdapp.isDataLoading = false;
+ var loc = location.pathname;
+ var loc1 = loc.replace("/", "");
+ var loc2 = loc1.replace("/ecd", "/login.htm");
+ alert("Session expired - Sign in again");
+ location.replace("/"+loc2);
});
+ $scope.ecdapp.getDeploymentsList();
};
/**
@@ -79,9 +517,186 @@ appDS2.controller('deploymentTableController', function(
$scope.pageChangeHandler = function(page) {
// console.log('pageChangeHandler: current is ' + $scope.ecdapp.currentPageNum + ' new is ' + page);
$scope.ecdapp.currentPageNum = page;
- $scope.ecdapp.loadTable();
+ //$scope.ecdapp.searchBy = "tenant:" + $scope.ecdapp.selectedTenant + ";";
+ $scope.ecdapp.loadTable($scope.ecdapp.sortBy, $scope.ecdapp.searchBy);
}
+ $scope.ecdapp.tenantChangeHandler = function() {
+ $scope.ecdapp.currentPageNum = 1;
+ $scope.ecdapp.searchBy = "tenant:" + $scope.ecdapp.selectedTenant + ";"
+ +"cache:" + $scope.ecdapp.useCache + ";";
+ //+ "user:" + $scope.ecdapp.filterByUser + ";";
+ if ($scope.ecdapp.filterByUser) {
+ $scope.ecdapp.searchBy += "owner:" + $scope.userId + ";";
+ }
+ $scope.ecdapp.searchString = $scope.ecdapp.searchBy;
+ $scope.ecdapp.loadTable($scope.ecdapp.sortBy, $scope.ecdapp.searchBy);
+ }
+
+ //$scope.ecdapp.getTenants();
+
+ /**
+ * modal pop-up for app reconfig operation
+ *
+ */
+ $scope.ecdapp.reconfigDeploymentModalPopup = function(deployment) {
+ var modalInstance = $modal.open({
+ templateUrl : 'app_reconfig_view_popup.html',
+ controller : 'appReconfigCtrl',
+ windowClass: 'modal-docked',
+ sizeClass: 'modal-jumbo',
+ resolve : {
+ message : function() {
+ var dataForPopup = {
+ deployment : deployment
+ };
+ return dataForPopup;
+ }
+ }
+ });
+ modalInstance.result.then(function(response) {
+ // No response.
+ });
+ };
+
+ /**
+ * Shows a modal pop-up to confirm deletion.
+ * On successful completion, updates the table.
+ */
+ $scope.ecdapp.deleteDeploymentModalPopup = function(deployment) {
+ deployment.onlyLatest = true;
+ var modalInstance = $modal.open({
+ templateUrl : 'inventory_deployment_delete_popup.html',
+ controller : 'deploymentDeleteCtrl',
+ sizeClass: 'modal-small',
+ resolve : {
+ message : function() {
+ var dataForPopup = {
+ deployment : deployment,
+ };
+ return dataForPopup;
+ }
+ }
+ });
+ modalInstance.result.then(function(response) {
+ if (debug)
+ $log.debug('deleteDeploymentPopup: response: ' + JSON.stringify(response));
+ if (response == null) {
+ // $log.debug('user closed dialog');
+ }
+ else {
+ if (response.error != null) {
+ $log.error('deleteDeploymentModalPopup failed: ' + response.error);
+ alert('Failed to delete deployment:\n' + response.error);
+ }
+ else {
+ $scope.ecdapp.viewDeploymentExecutionsModalPopup(deployment);
+ }
+ }
+ });
+ };
+
+ /**
+ * Shows a modal pop-up with executions for a deployment.
+ * Passes data in via an object named "deployment".
+ */
+ $scope.ecdapp.viewDeploymentExecutionsModalPopup = function(deployment) {
+ var modalInstance = $modal.open({
+ templateUrl : 'inventory_execution_view_popup.html',
+ controller : 'deploymentExecutionsViewCtrl',
+ windowClass: 'modal-docked',
+ sizeClass: 'modal-jumbo',
+ resolve : {
+ message : function() {
+ var dataForPopup = {
+ deployment : deployment
+ };
+ return dataForPopup;
+ }
+ }
+ });
+ modalInstance.result.then(function(response) {
+ // No response.
+ });
+ };
+
+
+ $scope.ecdapp.viewDeploymentInputsModalPopup = function(deployment) {
+ var modalInstance = $modal.open({
+ templateUrl : 'inventory_deployment_inputs_view_popup.html',
+ controller : 'deploymentInputsViewCtrl',
+ windowClass: 'modal-docked',
+ sizeClass: 'modal-jumbo',
+ resolve : {
+ message : function() {
+ var dataForPopup = {
+ deployment : deployment
+ };
+ return dataForPopup;
+ }
+ }
+ });
+ modalInstance.result.then(function(response) {
+ // No response.
+ });
+ };
+
+ /**
+ * Shows a modal pop-up to initiate update blueprint for a deployment
+ */
+ $scope.ecdapp.updateDeploymentModalPopup = function(deployment) {
+ var modalInstance = $modal.open({
+ templateUrl: 'inventory_deployment_update_popup.html',
+ controller: 'deploymentUpdateCtrl',
+ windowClass: 'modal-docked',
+ sizeClass: 'modal-jumbo',
+ resolve: {
+ message: function() {
+ var dataForPopup = {
+ deployment : deployment
+ };
+ return dataForPopup;
+ }
+ }
+ });
+ modalInstance.result.then(function(response) {
+ if (response != null) {
+ if (response.error != null) {
+ $log.error('updateDeploymentModalPopup failed: ' + response.error);
+ alert('Failed to update deployment:\n' + response.error);
+ }
+ else {
+ $scope.ecdapp.viewDeploymentExecutionsModalPopup(deployment);
+ }
+ }
+ });
+ };
+
+ /**
+ * Shows a modal pop-up with blueprint content.
+ * Passes data in via an object named "message".
+ */
+ $scope.ecdapp.getBlueprintDataModal = function(deployment) {
+ var modalInstance = $modal.open({
+ templateUrl : 'blueprint_content_popup.html',
+ controller : 'deployBlueprintContentCtrl',
+ windowClass: 'modal-docked',
+ sizeClass: 'modal-jumbo',
+ resolve : {
+ message : function() {
+ var dataForPopup = {
+ blueprint : deployment,
+ tenant_name: $scope.ecdapp.selectedTenant
+ };
+ return dataForPopup;
+ }
+ }
+ });
+ modalInstance.result.then(function(response) {
+ });
+ };
+
+
/**
* Shows a modal pop-up to create an execution from a deployment.
* Passes data in via an object named "message".
@@ -96,7 +711,7 @@ appDS2.controller('deploymentTableController', function(
resolve : {
message : function() {
var dataForPopup = {
- deployment : deployment
+ deployment : deployment,
};
return dataForPopup;
}
@@ -119,253 +734,1480 @@ appDS2.controller('deploymentTableController', function(
});
};
- /**
- * Shows a modal pop-up to confirm deletion.
- * On successful completion, updates the table.
- */
- $scope.ecdapp.deleteDeploymentModalPopup = function(deployment) {
- var modalInstance = $modal.open({
- templateUrl : 'deployment_delete_popup.html',
- controller : 'deploymentDeleteCtrl',
- sizeClass: 'modal-small',
- resolve : {
- message : function() {
- var dataForPopup = {
- deployment : deployment
- };
- return dataForPopup;
- }
- }
- });
- modalInstance.result.then(function(response) {
- if (debug)
- $log.debug('deleteDeploymentPopup: response: ' + JSON.stringify(response));
- if (response == null) {
- // $log.debug('user closed dialog');
- }
- else {
- if (response.error != null) {
- $log.error('deleteDeploymentModalPopup failed: ' + response.error);
- alert('Failed to delete deployment:\n' + response.error);
- }
- else {
- // success, get the updated list.
- $scope.ecdapp.loadTable()
- }
- }
- });
- };
+ $scope.ecdapp.checkHelmStatus = function(deployment) {
+ var selTenant = deployment.tenant_name;
+ if ( typeof selTenant === "undefined" ) {
+ selTenant = "default_tenant";
+ }
+ deployment.onlyLatest = true;
+
+ // This object holds data for this operation
+ $scope.ecdapp.helmStatusRequest = {
+ "deployment_id": deployment.id,
+ "workflow_name": "status",
+ "tenant": selTenant
+ };
+ InventoryDeploymentService.helmStatusFlow($scope.ecdapp.helmStatusRequest).then(function(jsonObj) {
+ if (debug)
+ $log.debug("checkHelmStatus response: " + JSON.stringify(jsonObj));
+ if (jsonObj.error) {
+ $scope.ecdapp.errMsg = 'Request Failed: ' + jsonObj.error;
+ $scope.ecdapp.updatingDeployment = false;
+ $scope.ecdapp.isDataLoading = false;
+ alert('Request Failed: ' + jsonObj.error);
+ } else {
+ console.log('%c POSTED helm status request', 'color: magenta; font-weight: bold;');
+ $scope.ecdapp.viewDeploymentExecutionsModalPopup(deployment);
+ }
+ }, function(error) {
+ $log.error('helmStatusFlow failed: ' + error);
+ alert('helmStatusFlow failed: ' + error);
+ });
+
+ };
+
+ /**
+ * Shows a modal pop-up to initiate helm upgrade for a deployment
+ */
+ $scope.ecdapp.upgradeDeploymentModalPopup = function(deployment) {
+ //console.log(deployment);
+ var modalInstance = $modal.open({
+ templateUrl: 'inventory_deployment_upgrade_popup.html',
+ controller: 'deploymentUpgradeCtrl',
+ windowClass: 'modal-docked',
+ sizeClass: 'modal-jumbo',
+ resolve: {
+ message: function() {
+ var dataForPopup = {
+ deployment : deployment
+ };
+ return dataForPopup;
+ }
+ }
+ });
+ };
+
+ /**
+ * Shows a modal pop-up to initiate helm rollback for a deployment
+ */
+ $scope.ecdapp.rollbackDeploymentModalPopup = function(deployment) {
+ var modalInstance = $modal.open({
+ templateUrl: 'inventory_deployment_rollback_popup.html',
+ controller: 'deploymentRollbackCtrl',
+ windowClass: 'modal-docked',
+ sizeClass: 'modal-jumbo',
+ resolve: {
+ message: function() {
+ var dataForPopup = {
+ deployment : deployment
+ };
+ return dataForPopup;
+ }
+ }
+ });
+ modalInstance.result.then(function(response) {
+ // No response.
+ });
+ };
+ $scope.$on('$destroy', function() {
+ // Make sure that the interval is destroyed too
+ $scope.ecdapp.stopLoading();
+ });
+
});
/*************************************************************************/
appDS2.controller('deploymentDeleteCtrl', function(
- $scope, $log, $modalInstance, message, DeploymentService) {
+ $scope, $rootScope, $log, $modalInstance, message, InventoryDeploymentService) {
- 'use strict';
-
- // Controls logging in this controller
- var debug = false;
+ 'use strict';
- // this object holds all app data and functions
- $scope.ecdapp = {};
- $scope.ecdapp.label = 'Delete Deployment';
- $scope.ecdapp.deploymentId = message.deployment.id;
- $scope.ecdapp.ignoreLiveNodes = false;
-
- $scope.ecdapp.deleteDeploymentById = function(){
- DeploymentService.deleteDeployment($scope.ecdapp.deploymentId, $scope.ecdapp.ignoreLiveNodes).then(
- function(response) {
- if (debug)
- $log.debug('deploymentDeleteCtrl.deleteDeployment: ' + JSON.stringify(response));
- if (response && response.error) {
- $log.error('DeploymentService.deleteDeployment failed: ' + response.error);
- alert('Failed to delete deployment:\n' + response.error);
- }
- else {
- // Delete service returns null on success.
- $modalInstance.close("success");
- }
- },
- function(error) {
- $log.error('DeploymentService.deleteDeployment failed: ' + error);
- alert('Service failed to delete deployment:\n' + error);
- });
- }
+ // Controls logging in this controller
+ var debug = false;
+
+ // this object holds all app data and functions
+ $scope.ecdapp = {};
+ $scope.ecdapp.label = 'Undeploy?';
+ $scope.ecdapp.deploymentRef = message.deployment.id;
+ var selTenant = message.deployment.tenant_name;
+ $scope.ecdapp.ui_tenant = selTenant;
+ $scope.ecdapp.tenant = selTenant;
+
+ $scope.ecdapp.deleteDeploymentById = function(){
+ $scope.ecdapp.isDisabled = true;
+ InventoryDeploymentService.deleteDeployment($scope.ecdapp.deploymentRef, $scope.ecdapp.tenant).then(
+ function(response) {
+ if (debug)
+ $log.debug('inventoryDeploymentDeleteCtrl.deleteDeployment: ' + JSON.stringify(response));
+ if (response && response.error) {
+ $log.error('InventoryDeploymentService.deleteDeployment failed: ' + response.error);
+ alert('Failed to delete deployment:\n' + response.error);
+ }
+ else {
+ // Delete service returns null on success.
+ $modalInstance.close("success");
+ }
+ },
+ function(error) {
+ $log.error('InventoryDeploymentService.deleteDeployment failed: ' + error);
+ alert('Service failed to delete deployment:\n' + error);
+ });
+ }
});
/*************************************************************************/
-appDS2.controller('deploymentExecuteCtrl', function(
- $scope, $log, $modalInstance, message, ExecutionService) {
+appDS2.controller('deploymentExecutionsViewCtrl', function(
+ $scope, $rootScope, $interval, $log, $modalInstance, message, modalService, InventoryExecutionService, ExecutionService) {
- 'use strict';
-
- // Controls logging in this controller
- var debug = false;
+ 'use strict';
- // this object holds all app data and functions
- $scope.ecdapp = {};
- $scope.ecdapp.label = 'Execute Deployment';
-
- // Cache the input parameter names for validation
- $scope.ecdapp.inputsDict = {};
- if (debug)
- $log.debug('DeploymentXeqCtrl: inputsDict is ' + JSON.stringify($scope.ecdapp.inputsDict));
-
- // Copy the input names and values
- // (different structure than blueprint)
- /*for (var pkey in message.deployment.inputs) {
- let dval = message.deployment.inputs[pkey];
- inputsAndValues[pkey] = dval;
- }*/
-
- // Gather workflow names as a simple list
- var workflowList = [];
- for (var i = 0; i < message.deployment.workflows.length; i++)
- workflowList.push(message.deployment.workflows[i].name);
- if (debug)
- $log.debug('DeploymentXeqCtrl: workflowList is ' + JSON.stringify(workflowList));
-
- // Create an object for edit.
- $scope.ecdapp.editRequest = {
- deployment_id : message.deployment.id,
- allow_custom_parameter : false,
- force : false,
- // Has title and value objects
- workflow_name: { value : '' },
- workflow_list : workflowList,
- fileModel : null,
- parmFileDict : {}
- };
-
- $scope.selectWorkflowName = function(){
- var workflows = message.deployment.workflows;
- let inputsAndValues = {};
- var res = workflows.filter(function(d){
- if(d.name == $scope.ecdapp.editRequest.workflow_name.value){
- return d
- }
- });
- for(var key in res[0].parameters){
- inputsAndValues[key] = typeof (res[0].parameters[key].default) === 'string' ? res[0].parameters[key].default : null;
- }
- $scope.ecdapp.inputsDict = inputsAndValues;
- $scope.ecdapp.editRequest.parmFileDict = inputsAndValues;
- };
-
- if (debug)
- $log.debug('DeploymentXeqCtrl: editRequest is ' + JSON.stringify($scope.ecdapp.editRequest));
+ var debug = false;
- /**
- * Handler for file-read event reads file, parses YAML, validates content.
- */
- var fileReader = new FileReader();
- fileReader.onload = function(event) {
- let yamlString = fileReader.result;
- if (debug)
- $log.debug('fileReader.onload: read: ' + yamlString);
- let ydict = {};
- try {
- ydict = YAML.parse(yamlString);
- }
- catch (ex) {
- alert('Failed to parse file as YAML:\n' + ex);
- }
- for (var ykey in ydict) {
- let yval = ydict[ykey];
- if (debug)
- $log.debug('fileReader.onload: typeof ' + ykey + ' is ' + typeof ykey);
- // Only accept valid, expected key-value pairs
- if (typeof yval !== 'string' && typeof yval!=='number')
- alert('Unexpected file content:\nNot a simple key-value pair:\n' + ykey);
- else if (! (ykey in $scope.ecdapp.editRequest.parmFileDict))
- alert('Unexpected file content:\nKey not defined by deployment:\n' + ykey);
- else
- $scope.ecdapp.editRequest.parmFileDict[ykey] = yval;
- }
- if (debug)
- $log.debug('fileReader.onload: parmFileDict: ' + JSON.stringify($scope.ecdapp.editRequest.parmFileDict));
-
- // Update table in all cases
- $scope.$apply();
- }
+ if (debug)
+ $log.debug("inventoryDeploymentsExecutionsViewCtrl.message: " + JSON.stringify(message));
- // Handler for file-select event
- $scope.handleFileSelect = function() {
- if (debug)
- $log.debug('handleFileSelect: $scope.ecdapp.fileModel.name is ' + $scope.ecdapp.editRequest.fileModel.name);
- fileReader.readAsText($scope.ecdapp.editRequest.fileModel);
- };
+ // this object holds all app data and functions
+ $scope.ecdapp = {};
+ // models for controls on screen
+ $scope.ecdapp.label = 'Deployment ' + message.deployment.id + ' Executions';
+ $scope.ecdapp.tableData = [];
+ $scope.ecdapp.logTableData = [];
+ $scope.ecdapp.currentPageNum = 1;
+ $scope.ecdapp.viewPerPage = 10;
+ $scope.ecdapp.currentLogPageNum = 1;
+ $scope.ecdapp.selectedRow = null;
- /**
- * Validates content of user-editable fields.
- * Returns null if all is well,
- * a descriptive error message otherwise.
- */
- var validateRequest = function(editRequest) {
- if (debug)
- $log.debug('validateRequest: editRequest is ' + JSON.stringify(editRequest));
- if (editRequest == null)
- return "No data found.\nPlease enter some values.";
- if (editRequest.deployment_id == null || editRequest.deployment_id.trim() == '')
- return "Deployment ID is required.\nPlease enter a value.";
- if (editRequest.workflow_name.value == null || editRequest.workflow_name.value.trim() == '')
- return "Workflow name is required.\nPlease select a workflow.";
- // Check that every file parameter is defined by blueprint
- for (var pkey in $scope.ecdapp.editRequest.parmFileDict) {
- // Defined in blueprint?
- if (! $scope.ecdapp.inputsDict[pkey])
- return 'Unexpected input parameter\n' + pkey;
- // Populated?
- let parmVal = $scope.ecdapp.editRequest.parmFileDict[pkey];
- if (parmVal.trim().length == 0)
- return 'Missing value for parameter ' + pkey;
- }
- // Check that a value is supplied for every expected input
- for (var bkey in $scope.ecdapp.inputsDict) {
- if (! $scope.ecdapp.editRequest.parmFileDict[bkey])
- return 'Missing input parameter\n' + bkey;
- }
- return null;
- }
-
- $scope.ecdapp.executeDeployment = function(editRequest) {
- var validateMsg = validateRequest(editRequest);
- if (validateMsg != null) {
- alert('Invalid execution request:\n' + validateMsg);
- return;
- }
-
- // Create request with key:value parameters dictionary
- let executeRequest = {
- deployment_id : editRequest.deployment_id,
- workflow_name : editRequest.workflow_name.value,
- allow_custom_parameter : editRequest.allow_custom_parameter,
- force : editRequest.force,
- parameters : {}
- };
- for (var pkey in $scope.ecdapp.editRequest.parmFileDict)
- executeRequest.parameters[pkey] = $scope.ecdapp.editRequest.parmFileDict[pkey];
- if (debug)
- $log.debug('executeDeployment: executeRequest is ' + JSON.stringify(executeRequest));
-
- ExecutionService.executeDeployment(executeRequest)
- .then(function(response) {
- if (response.error)
- alert('Failed to create execution:\n' + response.error);
- else
- $modalInstance.close(response);
- },
- function (error) {
- $log.error('deploymentExecuteCtrl: error while creating execution: ' + error);
- alert('Server rejected execute request:\n' + error);
- }
- );
+ // other
+ $scope.ecdapp.errMsg = null;
+ $scope.ecdapp.isDataLoading = true;
+ $scope.ecdapp.isEventLogQuery = false;
+ $scope.ecdapp.isRequestFailed = false;
+ $scope.ecdapp.isLastExecution = message.deployment.onlyLatest;
+ $scope.ecdapp.isLogType = true;
+ $scope.ecdapp.refresh_switch = {
+ value: true
+ };
+ $scope.ecdapp.options = {
+ "on":"On",
+ "off":"Off"
+ }
+ var selTenant = message.deployment.tenant_name;
- };
+ $scope.ecdapp.ui_tenant = selTenant;
+ $scope.ecdapp.tenant = selTenant;
+ $scope.ecdapp.execId = "";
+ $scope.ecdapp.deplRef = message.deployment.id;
+ var stop;
+ /**
+ * Loads the table. Interprets the remote controller's response and copies
+ * to scope variables. The response is either a list to be assigned to
+ * tableData, or an error to be shown.
+ */
+ $scope.ecdapp.loadTable = function() {
+ $scope.ecdapp.isDataLoading = true;
+ InventoryExecutionService.getExecutionsByDeployment($scope.ecdapp.deplRef,
+ $scope.ecdapp.tenant,
+ $scope.ecdapp.currentPageNum,
+ $scope.ecdapp.viewPerPage).then(
+ function(jsonObj) {
+ if (jsonObj.error) {
+ $log.error("deploymentExecutionsViewCtrl.loadTable failed: "
+ + jsonObj.error);
+ $scope.ecdapp.isRequestFailed = true;
+ if (jsonObj.error.includes("404")) {
+ $scope.ecdapp.errMsg = "404 - Deployment " + message.deployment.deploymentRef + " Not Found!";
+ }
+ $scope.ecdapp.tableData = [];
+ $scope.ecdapp.stopLoading();
+ } else {
+ $scope.ecdapp.isRequestFailed = false;
+ $scope.ecdapp.errMsg = null;
+ $scope.ecdapp.totalPages = jsonObj.totalPages;
+ var resultLen = jsonObj.items.length;
+ if (resultLen != undefined && resultLen > 0) {
+ var exec_id = jsonObj.items[resultLen-1].id;
+ $scope.ecdapp.execId = exec_id;
+ $scope.ecdapp.selectedRow = resultLen-1;
+ if ($scope.ecdapp.isLastExecution) {
+ $scope.ecdapp.tableData = [];
+ $scope.ecdapp.tableData.push(jsonObj.items[resultLen-1]);
+ } else {
+ $scope.ecdapp.tableData = jsonObj.items;
+ }
+ $scope.ecdapp.getExecutionLogs($scope.ecdapp.selectedRow, exec_id, $scope.ecdapp.tenant);
+ }
+ }
+ $scope.ecdapp.isDataLoading = false;
+ },
+ function(error) {
+ $log.error("inventoryDeploymentExecutionsViewCtrl.loadTable failed: "
+ + error);
+ $scope.ecdapp.isRequestFailed = true;
+ $scope.ecdapp.errMsg = error;
+ $scope.ecdapp.tableData = [];
+ $scope.ecdapp.isDataLoading = false;
+ $scope.ecdapp.stopLoading();
+ });
+ };
+ $scope.$watch('ecdapp.refresh_switch["value"]', function(newValue,oldValue,scope) {
+ if (newValue != oldValue) {
+ if (newValue === true) {
+ $scope.ecdapp.loadTable();
+ stop = $interval( function(){ $scope.ecdapp.loadTable(); }, 30000, 100, false);
+ } else {
+ $scope.ecdapp.stopLoading();
+ }
+ }
+ }, true);
+
+ if ($scope.ecdapp.refresh_switch.value === true) {
+ stop = $interval( function(){ $scope.ecdapp.loadTable(); }, 30000, 100, false);
+ }
+
+ $scope.ecdapp.stopLoading = function() {
+ if (angular.isDefined(stop)) {
+ $interval.cancel(stop);
+ stop = undefined;
+ }
+ };
+ $scope.ecdapp.copyStringToClipboard = function(str) {
+ // Create new element
+ var el = document.createElement('textarea');
+ // Set value (string to be copied)
+ el.value = str;
+ // Set non-editable to avoid focus and move outside of view
+ el.setAttribute('readonly', '');
+ el.style = {position: 'absolute', left: '-9999px'};
+ document.body.appendChild(el);
+ // Select text inside element
+ el.select();
+ // Copy text to clipboard
+ document.execCommand('copy');
+ // Remove temporary element
+ document.body.removeChild(el);
+ };
+
+ $scope.ecdapp.cancelExecutionModalPopup = function(execution, tenant) {
+ modalService.popupConfirmWin("Confirm", "Cancel execution with ID '"
+ + execution.id + "'?", function() {
+ $scope.ecdapp.isCancelOn = true;
+ // TODO: gather action from user
+ InventoryExecutionService.cancelExecution(execution.id, execution.deployment_id, "force-cancel", tenant).then(
+ function(response) {
+ if (debug)
+ $log.debug("Controller.cancelExecutionModalPopup: " + JSON.stringify(response));
+ if (response && response.error) {
+ // $log.error('cancelExectuion failed: ' + response.error);
+ alert('Failed to cancel execution:\n' + response.error);
+ $scope.ecdapp.isCancelOn = false;
+ }
+ else {
+ // No response body on success.
+ $scope.ecdapp.isCancelOn = false;
+ $scope.ecdapp.loadTable();
+ }
+ },
+ function(error) {
+ $scope.ecdapp.isCancelOn = false;
+ $log.error('ExecutionService.cancelExecution failed: ' + error);
+ alert('Service failed to cancel execution:\n' + error);
+ });
+ })
+ };
+
+ /**
+ * Invoked at first page load AND when
+ * user clicks on the B2B pagination control.
+ */
+ $scope.pageChangeHandler = function(page) {
+ if (debug)
+ console.log('pageChangeHandler: current is ' + $scope.ecdapp.currentPageNum + ' new is ' + page);
+ $scope.ecdapp.currentPageNum = page;
+ $scope.ecdapp.loadTable();
+
+ }
+ $scope.pageChangeHandlerEvent = function(page) {
+ if (debug)
+ console.log('pageChangeHandlerEvent: current is ' + $scope.ecdapp.currentLogPageNum + ' new is ' + page);
+ if (page != $scope.ecdapp.currentLogPageNum ) {
+ $scope.ecdapp.currentLogPageNum = page;
+ $scope.ecdapp.getExecutionLogs($scope.ecdapp.selectedRow, $scope.ecdapp.execId, $scope.ecdapp.tenant);
+ }
+ }
+
+ $scope.ecdapp.setClickedRow = function(index){ //function that sets the value of selectedRow to current index
+ $scope.ecdapp.selectedRow = index;
+ }
+ $scope.ecdapp.selected = false;
+ $scope.ecdapp.toggleStatusDefinitions = function() {
+ $scope.ecdapp.selected = $scope.ecdapp.selected ? false :true;
+ }
+
+ /**
+ * Shows a modal pop-up with the error.
+ */
+ $scope.ecdapp.viewErrorModalPopup = function(row) {
+ $modalInstance.dismiss('cancel');
+ modalService.showFailure('Error Details', row.error, function() { } );
+ };
+
+ $scope.ecdapp.getExecutionLogs = function(rowIdx, id, tenant) {
+ $scope.ecdapp.setClickedRow(rowIdx);
+ $scope.ecdapp.execId = id;
+ $scope.ecdapp.isEventLogQuery = false;
+ InventoryExecutionService.getEventsByExecution(id , $scope.ecdapp.isLogType, tenant,
+ $scope.ecdapp.currentLogPageNum, $scope.ecdapp.viewPerPage ).then(
+ function(jsonObj) {
+ if (jsonObj.error) {
+ $log.error("inventoryDeploymentExecutionsViewCtrl.getExecutionLogs failed: "
+ + jsonObj.error);
+ $scope.ecdapp.isEventLogQuery = false;
+ $scope.ecdapp.evtErrMsg = jsonObj.error;
+ $scope.ecdapp.logTableData = [];
+ } else {
+ $scope.ecdapp.isEventLogQuery = true;
+ $scope.ecdapp.evtErrMsg = null;
+ $scope.ecdapp.totalLogPages = jsonObj.totalPages;
+ $scope.ecdapp.logTableData = jsonObj.items;
+ }
+ $scope.ecdapp.isDataLoading = false;
+ },
+ function(error) {
+ $log.error("inventoryDeploymentExecutionsViewCtrl.getExecutionLogs failed: "
+ + error);
+ $scope.ecdapp.evtErrMsg = error;
+ $scope.ecdapp.logTableData = [];
+ $scope.ecdapp.isDataLoading = false;
+ });
+ }
+
+ $scope.$on('$destroy', function() {
+ // Make sure that the interval is destroyed too
+ $scope.ecdapp.stopLoading();
+ });
+});
+
+
+/*************************************************************************/
+appDS2.controller('deploymentInputsViewCtrl', function(
+ $scope, $rootScope, $log, $modalInstance, message, InventoryDeploymentService) {
+
+ 'use strict';
+
+ // Controls logging in this controller
+ var debug = false;
+
+ // this object holds all app data and functions
+ $scope.ecdapp = {};
+ $scope.ecdapp.label = 'Deployment Inputs';
+ $scope.ecdapp.deploymentRef = message.deployment.id;
+ $scope.ecdapp.serviceId = message.deployment.serviceId;
+ $scope.ecdapp.errMsg = null;
+ $scope.ecdapp.isDataLoading = true;
+ $scope.ecdapp.isRequestFailed = false;
+ var selTenant = message.deployment.tenant_name;
+ if ( typeof selTenant === "undefined" ) {
+ selTenant = "default_tenant";
+ }
+ $scope.ecdapp.ui_tenant = selTenant;
+ $scope.ecdapp.tenant = selTenant;
+ let inputsAndDescriptions = {};
+ let inputsAndDefaults = {};
+ // Get associated blueprint for inputs info
+ InventoryDeploymentService.getBlueprint($scope.ecdapp.deploymentRef, $scope.ecdapp.tenant).then(function(blueprint) {
+ if (debug)
+ $log.debug("inventoryDeploymentInputsViewCtrl.getBlueprint response: " + JSON.stringify(blueprint));
+ if (!blueprint.error) {
+ for (var pkey in blueprint.items[0].plan.inputs) {
+ let description = blueprint.items[0].plan.inputs[pkey].description;
+ if ( typeof description === "undefined" ) {
+ description = '';
+ }
+ inputsAndDescriptions[pkey] = description;
+ }
+ $scope.ecdapp.deployment.descriptionDict = inputsAndDescriptions;
+ }
+ },
+ function(error) {
+ $log.error('InventoryDeploymentService.getBlueprint failed: ' + JSON.stringify(error));
+ });
+
+ InventoryDeploymentService.getDeployment($scope.ecdapp.deploymentRef, $scope.ecdapp.tenant).then(function(deployment) {
+ if (deployment.items.length == 0) {
+ $scope.ecdapp.errMsg = "404 - Deployment " + message.deployment.deploymentRef + " Not Found!";
+ $log.error("InventoryDeploymentSerice.getDeployment failed: "
+ + $scope.ecdapp.errMsg);
+ $scope.ecdapp.isRequestFailed = true;
+ }
+ // Deployment IDs are unique, so this will always return exactly one item!
+ // retrieve blueprintId and inputs of deployment.
+ else {
+ $scope.ecdapp.errMsg = null;
+ //$scope.ecdapp.deployment = deployment.items[0];
+ let ydict = deployment.items[0].inputs;
+ for (var ykey in ydict) {
+ let yval = ydict[ykey];
+ if (yval.constructor === {}.constructor)
+ inputsAndDefaults[ykey] = JSON.stringify(yval, undefined, 2);
+ else
+ inputsAndDefaults[ykey] = yval;
+ }
+ $scope.ecdapp.isRequestFailed = false;
+ }
+ $scope.ecdapp.isDataLoading = false;
+ },
+ function(error) {
+ $log.error('InventoryDeploymentService.getDeployment failed: ' + JSON.stringify(error));
+ $scope.ecdapp.isRequestFailed = true;
+ $scope.ecdapp.errMsg = error;
+ $scope.ecdapp.isDataLoading = false;
+ });
+ $scope.ecdapp.deployment = {
+ parmFileDict : inputsAndDefaults,
+ descriptionDict : inputsAndDescriptions
+ };
});
+/*************************************************************************/
+
+appDS2.controller('deployBlueprintContentCtrl', function(
+ $scope, $log, message, DeploymentService) {
+
+ 'use strict';
+
+ var debug = false;
+
+ if (debug)
+ $log.debug("deployBlueprintContentCtrl.message: " + JSON.stringify(message));
+
+ // this object holds all app data and functions
+ $scope.ecdapp = {};
+ $scope.ecdapp.label = 'View Blueprint ' + message.blueprint.blueprint_id;
+ // Fetch the blueprint
+ $scope.ecdapp.isDataLoading = true;
+ DeploymentService.getBlueprintContent(message.blueprint.blueprint_id, message.tenant_name).then(function(jsonObj) {
+ if (debug)
+ $log.debug("deployBlueprintContentCtrl.viewBlueprint response: " + JSON.stringify(jsonObj));
+ if (jsonObj.error) {
+ $scope.ecdapp.errMsg = 'Request Failed';
+ }
+ else {
+ $scope.ecdapp.typeName = message.blueprint.blueprint_id;
+ $scope.ecdapp.blueprint = jsonObj.data;
+ }
+ $scope.ecdapp.isDataLoading = false;
+ }, function(error) {
+ $scope.ecdapp.isDataLoading = false;
+ alert('Failed to get blueprint. Please retry.');
+ $log.error("deployBlueprintContentCtrl failed: " + error);
+ });
+});
+
+
+ /*************************************************************************/
+ appDS2.controller('deploymentUpdateCtrl', function(
+ $scope, $log, $modalInstance, message, InventoryBlueprintService, InventoryDeploymentService) {
+
+ 'use strict';
+
+ var debug = false;
+ if (debug)
+ $log.debug("inventoryDeploymentUpdateCtrl.message: " + JSON.stringify(message));
+
+ // this object holds all app data and functions
+ $scope.ecdapp = {};
+ $scope.ecdapp.deploymentInProgress = false;
+ $scope.ecdapp.serviceTypeComplete = false;
+ $scope.ecdapp.isDataLoading = true;
+ $scope.ecdapp.errMsg = null;
+ $scope.ecdapp.label = 'Update ' + message.deployment.id;
+ $scope.ecdapp.deploymentRef = message.deployment.id;
+ var selTenant = message.deployment.tenant_name;
+ if ( typeof selTenant === "undefined" ) {
+ selTenant = "default_tenant";
+ }
+ $scope.ecdapp.tenant = selTenant;
+ $scope.ecdapp.ui_tenant = selTenant;
+ $scope.ecdapp.updateBp = '';
+ $scope.ecdapp.typeName = '';
+ $scope.ecdapp.typeId = '';
+ $scope.ecdapp.inputsDict = {};
+ $scope.ecdapp.nodeInst = [];
+ $scope.ecdapp.selectedNodeInst;
+ $scope.ecdapp.editRequest = {
+ deployment_id : $scope.ecdapp.deploymentRef,
+ type_id : '',
+ fileModel : null,
+ parmFileDict : {},
+ descriptionDict : {},
+ tenant : $scope.ecdapp.tenant
+ };
+ $scope.ecdapp.install_flow = {
+ value: true
+ };
+
+ $scope.ecdapp.uninstall_flow = {
+ value: true
+ };
+
+ $scope.ecdapp.reinstall_flow = {
+ value: true
+ };
+
+ $scope.ecdapp.install_first_flow_flag = {
+ value: false
+ };
+
+ $scope.ecdapp.force_flag = {
+ value: false
+ };
+
+ $scope.ecdapp.ignore_failure_flag = {
+ value: false
+ };
+
+ $scope.ecdapp.skip_install = false;
+ $scope.ecdapp.skip_uninstall = false;
+ $scope.ecdapp.skip_reinstall = false;
+ $scope.ecdapp.install_first_flow = false;
+ $scope.ecdapp.force = false;
+ $scope.ecdapp.ignore_failure = false;
+
+ $scope.$watch('ecdapp.install_flow["value"]', function(newValue,oldValue,scope) {
+ if (newValue != oldValue) {
+ console.log("toggled install flow: " + newValue);
+ $scope.ecdapp.skip_install = oldValue;
+ }
+ }, true);
+
+ $scope.$watch('ecdapp.uninstall_flow["value"]', function(newValue,oldValue,scope) {
+ if (newValue != oldValue) {
+ console.log("toggled uninstall flow: " + newValue);
+ $scope.ecdapp.skip_uninstall = oldValue;
+ }
+ }, true);
+
+ $scope.$watch('ecdapp.reinstall_flow["value"]', function(newValue,oldValue,scope) {
+ if (newValue != oldValue) {
+ console.log("toggled reinstall flow: " + newValue);
+ $scope.ecdapp.skip_reinstall = oldValue;
+ }
+ }, true);
+
+ $scope.$watch('ecdapp.install_first_flow_flag["value"]', function(newValue,oldValue,scope) {
+ if (newValue != oldValue) {
+ console.log("toggled install first flow: " + newValue);
+ $scope.ecdapp.install_first_flow = newValue;
+ }
+ }, true);
+
+ $scope.$watch('ecdapp.force_flag["value"]', function(newValue,oldValue,scope) {
+ if (newValue != oldValue) {
+ console.log("toggled force flag: " + newValue);
+ $scope.ecdapp.force = newValue;
+ }
+ }, true);
+
+ $scope.$watch('ecdapp.ignore_failure_flag["value"]', function(newValue,oldValue,scope) {
+ if (newValue != oldValue) {
+ console.log("toggled ignore_failure flow: " + newValue);
+ $scope.ecdapp.ignore_failure = newValue;
+ }
+ }, true);
+
+ // deployment node instances
+ InventoryDeploymentService.getNodeInstances($scope.ecdapp.deploymentRef, $scope.ecdapp.tenant)
+ .then(function(jsonObj) {
+ if (jsonObj.error) {
+ $log.error("inventoryDeploymentUpdateCtrl.getNodeInstances failed: " + jsonObj.error);
+ $scope.ecdapp.errMsg = jsonObj.error;
+ $scope.ecdapp.nodeInst = [];
+ } else {
+ $scope.ecdapp.errMsg = null;
+ for (var nodeIndx = 0; nodeIndx < jsonObj.items.length; nodeIndx++) {
+ $scope.ecdapp.nodeInst.push(jsonObj.items[nodeIndx].id);
+ }
+ }
+ }, function(error) {
+ $log.error("inventoryDeploymentUpdateCtrl.getNodeInstances failed: " + error);
+ $scope.ecdapp.errMsg = error;
+ $scope.ecdapp.nodeInst = [];
+ $scope.ecdapp.isDataLoading = false;
+ });
+
+ // current blueprint
+/* var typeLink = message.deployment.typeLink.href;
+ var n = typeLink.lastIndexOf("/");
+ var typeId = typeLink.substring(n+1);
+ // Fetch the blueprint
+ $scope.ecdapp.isDataLoading = true;
+ InventoryBlueprintService.viewBlueprint(typeId).then(function(jsonObj) {
+ if (debug)
+ $log.debug("inventoryDeploymentUpdateCtrl.viewBlueprint response: " + JSON.stringify(jsonObj));
+ if (jsonObj.error) {
+ $scope.ecdapp.errMsg = 'Request Failed';
+ }
+ else {
+ $scope.ecdapp.typeName = jsonObj.typeName;
+ $scope.ecdapp.typeId = jsonObj.typeId;
+ $scope.ecdapp.bp.push(jsonObj);
+ $scope.ecdapp.getBlueprint();
+ }
+ //$scope.ecdapp.isDataLoading = false;
+ }, function(error) {
+ $scope.ecdapp.isDataLoading = false;
+ alert('Failed to get blueprint. Please retry.');
+ $log.error("blueprintViewCtrl failed: " + error);
+ });*/
+
+ // get the blueprints from inventory matching deployment reference filter
+ $scope.ecdapp.bp = [];
+ InventoryBlueprintService.getBlueprintsSummary()
+ .then(function(jsonObj) {
+ if (jsonObj.error) {
+ $log.error("inventoryDeploymentUpdateCtrl.loadTable failed: " + jsonObj.error);
+ $scope.ecdapp.errMsg = jsonObj.error;
+ $scope.ecdapp.bp = [];
+ } else {
+ $scope.ecdapp.errMsg = null;
+ $scope.ecdapp.bp = jsonObj;
+ }
+ $scope.ecdapp.isDataLoading = false;
+ }, function(error) {
+ $log.error("inventoryDeploymentUpdateCtrl.loadTable failed: " + error);
+ $scope.ecdapp.errMsg = error;
+ $scope.ecdapp.bp = [];
+ $scope.ecdapp.isDataLoading = false;
+ });
+ $scope.ecdapp.getBlueprint = function() {
+ $scope.ecdapp.isDataLoading = true;
+ InventoryBlueprintService.viewBlueprint($scope.ecdapp.typeId).then(function(jsonObj) {
+ if (debug)
+ $log.debug("inventoryDeploymentUpdateCtrl.viewBlueprint response: " + JSON.stringify(jsonObj));
+ if (jsonObj.error) {
+ $scope.ecdapp.errMsg = 'Request Failed';
+ $scope.ecdapp.serviceTypeComplete = false;
+ $scope.ecdapp.isDataLoading = false;
+ }
+ else {
+ $scope.ecdapp.typeName = jsonObj.typeName;
+ $scope.ecdapp.typeVersion = jsonObj.typeVersion;
+ $scope.ecdapp.inputsDict = jsonObj.blueprintInputs;
+ // query the current deployment inputs
+ InventoryDeploymentService.getDeployment($scope.ecdapp.deploymentRef, $scope.ecdapp.tenant).then(function(deployment) {
+ if (deployment.items.length == 0) {
+ $scope.ecdapp.errMsg = "404 - Deployment " + message.deployment.deploymentRef + " Not Found!";
+ $log.error("InventoryDeploymentSerice.getDeployment failed: "
+ + $scope.ecdapp.errMsg);
+ //$scope.ecdapp.isRequestFailed = true;
+ $scope.ecdapp.serviceTypeComplete = true;
+ }
+ // Deployment IDs are unique, so this will always return exactly one item!.
+ // retrieve inputs of deployment.
+ else {
+ $scope.ecdapp.errMsg = null;
+ $scope.ecdapp.deployment = deployment.items[0];
+ // Copy the input parameter names and default values
+ let inputsAndDefaults = {};
+ let inputsAndDescriptions = {};
+ let ydict = deployment.items[0].inputs;
+ for (var ykey in ydict) {
+ let yval = ydict[ykey];
+ if (yval.constructor === {}.constructor)
+ inputsAndDefaults[ykey] = JSON.stringify(yval, undefined, 2);
+ else
+ //$scope.ecdapp.deployment.inputs[ykey] = yval;
+ inputsAndDefaults[ykey] = yval;
+ }
+ for (var pkey in $scope.ecdapp.inputsDict) {
+ //$scope.ecdapp.deployment = deployment.items[0];
+ let description = $scope.ecdapp.inputsDict[pkey].description;
+ if ( typeof description === "undefined" )
+ description = '';
+ inputsAndDescriptions[pkey] = description;
+ }
+
+ $scope.ecdapp.editRequest.parmFileDict = inputsAndDefaults;
+ $scope.ecdapp.editRequest.descriptionDict = inputsAndDescriptions;
+ $scope.ecdapp.editRequest.type_id = $scope.ecdapp.typeId;
+ if (debug)
+ $log.debug('inventoryBlueprintDeployCtrl: inputsAndDefaults: ' + JSON.stringify(inputsAndDefaults));
+
+ $scope.ecdapp.serviceTypeComplete = true;
+ //$scope.$apply();
+ }
+ $scope.ecdapp.isDataLoading = false;
+ },
+ function(error) {
+ $log.error('InventoryDeploymentService.getDeployment failed: ' + JSON.stringify(error));
+ $scope.ecdapp.isRequestFailed = true;
+ $scope.ecdapp.errMsg = error;
+ $scope.ecdapp.isDataLoading = false;
+ });
+ }
+ $scope.ecdapp.isDataLoading = false;
+ }, function(error) {
+ $scope.ecdapp.isDataLoading = false;
+ $scope.ecdapp.serviceTypeComplete = false;
+ alert('Failed to get blueprint. Please retry with valid blueprint ID.');
+ $log.error("inventoryDeploymentUpdateCtrl failed: " + error);
+ });
+ };
+
+ /**
+ * Handler for file-read event reads file, parses JSON, validates content.
+ */
+ var fileReader = new FileReader();
+ fileReader.onload = function(event) {
+ let jsonString = fileReader.result;
+ if (debug)
+ $log.debug('fileReader.onload: read: ' + jsonString);
+ let ydict = {};
+ try {
+ ydict = JSON.parse(jsonString);
+ }
+ catch (ex) {
+ alert('Failed to parse file as JSON:\n' + ex);
+ }
+ // Process the file
+ for (var ykey in ydict) {
+ let yval = ydict[ykey];
+ if (debug)
+ $log.debug('fileReader.onload: typeof ' + ykey + ' is ' + typeof ykey);
+ // Allow only expected keys with scalar values
+ if (! (ykey in $scope.ecdapp.editRequest.parmFileDict))
+ alert('Unexpected file content:\nKey not defined by blueprint:\n' + ykey);
+ if (yval.constructor === {}.constructor)
+ $scope.ecdapp.editRequest.parmFileDict[ykey] = angular.toJson(yval);
+ else
+ $scope.ecdapp.editRequest.parmFileDict[ykey] = yval;
+ }
+ if (debug)
+ $log.debug('fileReader.onload: parmFileDict: ' + JSON.stringify($scope.ecdapp.editRequest.parmFileDict));
+
+ // Update table in all cases
+ $scope.$apply();
+ }
+
+ // Handler for file-select event
+ $scope.handleFileSelect = function() {
+ if (debug)
+ $log.debug('handleFileSelect: $scope.ecdapp.fileModel.name is ' + $scope.ecdapp.editRequest.fileModel.name);
+ fileReader.readAsText($scope.ecdapp.editRequest.fileModel);
+ };
+
+ $scope.ecdapp.validateRequest = function(editRequest) {
+ if (editRequest == null)
+ return 'No data found.\nPlease enter some values.';
+ if (editRequest.deployment_id == null || editRequest.deployment_id.trim() == '')
+ return 'Deployment ID is required.\nPlease enter a value.';
+ if (editRequest.type_id == null || editRequest.type_id.trim() == '')
+ return 'Type ID is required.\nPlease enter a value.';
+ // Check that every file parameter is defined by blueprint
+ for (var pkey in $scope.ecdapp.editRequest.parmFileDict) {
+ // Defined in blueprint?
+ if (! $scope.ecdapp.inputsDict[pkey])
+ return 'Unexpected input parameter\n' + pkey;
+ }
+ return null;
+ }
+
+ $scope.ecdapp.updateDeployment = function(editRequest) {
+ if (debug)
+ $log.debug('deployBlueprint: editRequest is ' + JSON.stringify($scope.ecdapp.editRequest));
+ var validateMsg = $scope.ecdapp.validateRequest(editRequest);
+ if (validateMsg != null) {
+ alert('Invalid Request:\n' + validateMsg);
+ $scope.ecdapp.errMsg = validateMsg;
+ return;
+ }
+ // Create request with key:value parameters dictionary
+ let deploymentRequestObject = {
+ deploymentId : editRequest.deployment_id,
+ serviceTypeId : editRequest.type_id,
+ inputs : {},
+ tenant : editRequest.tenant,
+ method : "update",
+ reinstall_list : $scope.ecdapp.selectedNodeInst,
+ skip_install : $scope.ecdapp.skip_install,
+ skip_uninstall : $scope.ecdapp.skip_uninstall,
+ skip_reinstall : $scope.ecdapp.skip_reinstall,
+ force : $scope.ecdapp.force,
+ ignore_failure : $scope.ecdapp.ignore_failure,
+ install_first : $scope.ecdapp.install_first_flow
+ };
+
+ for (var pkey in $scope.ecdapp.editRequest.parmFileDict)
+ try {
+ deploymentRequestObject.inputs[pkey] = angular.fromJson($scope.ecdapp.editRequest.parmFileDict[pkey]);
+ } catch (error) {
+ deploymentRequestObject.inputs[pkey] = $scope.ecdapp.editRequest.parmFileDict[pkey];
+ }
+ if (debug)
+ $log.debug('deployBlueprint: deploymentRequestObject is ' + JSON.stringify(deployRequestObject));
+
+ $scope.ecdapp.deploymentInProgress = true;
+ InventoryDeploymentService.deployBlueprint(deploymentRequestObject)
+ .then(function(response) {
+ $scope.ecdapp.deploymentInProgress = false;
+ if (response.error) {
+ alert('Failed to deploy blueprint:\n' + response.error);
+ $scope.ecdapp.errMsg = response.error;
+ } else {
+ alert('Deployment update request sent successfully, query the execution status for final outcome');
+ $modalInstance.close(response);
+ }
+ },
+ function (error) {
+ $log.error('inventoryBlueprintDeployCtrl: error while deploying: ' + error);
+ alert('Server rejected deployment request:\n' + error);
+ $scope.ecdapp.deploymentInProgress = false;
+ }
+ );
+ };
+
+ });
+
+ /*************************************************************************/
+ appDS2.controller('deploymentRollbackCtrl', function(
+ $scope, $rootScope, $log, $modalInstance, message, InventoryDeploymentService) {
+
+ 'use strict';
+
+ // Controls logging in this controller
+ var debug = false;
+
+ // this object holds all app data and functions
+ $scope.ecdapp = {};
+ $scope.ecdapp.label = 'Deployment Rollback';
+ $scope.ecdapp.revisions = [];
+ $scope.ecdapp.deploymentRef = message.deployment.id;
+ $scope.ecdapp.serviceId = message.deployment.serviceId;
+ $scope.ecdapp.errMsg = null;
+ $scope.ecdapp.isDataLoading = true;
+ $scope.ecdapp.isRequestFailed = false;
+ $scope.ecdapp.updatingDeployment = false;
+ var selTenant = message.deployment.tenant_name;
+ if ( typeof selTenant === "undefined" ) {
+ selTenant = "default_tenant";
+ }
+ $scope.ecdapp.tenant = selTenant;
+ $scope.ecdapp.ui_tenant = selTenant;
+ $scope.ecdapp.local_revisions = [];
+ // This object holds data for this operation
+ $scope.ecdapp.rollbackRequest = {
+ "deployment_id": message.deployment.deploymentRef,
+ "workflow_name": "rollback",
+ "tenant": selTenant,
+ "revision": 1
+ };
+
+ InventoryDeploymentService.getNodeInstanceVersions($scope.ecdapp.deploymentRef, $scope.ecdapp.tenant).then(function(nodeRunTime) {
+ if (nodeRunTime == null) {
+ $scope.ecdapp.errMsg = "Failed to retrieve Node instance runtime information";
+ $log.error("InventoryDeploymentSerice.getNodeInstanceVersions failed: "
+ + $scope.ecdapp.errMsg);
+ $scope.ecdapp.isRequestFailed = true;
+ } else {
+ $scope.ecdapp.errMsg = null;
+ $scope.ecdapp.revisions = nodeRunTime.items[0].runtime_properties['helm-history'];
+ if (Array.isArray($scope.ecdapp.revisions) ) {
+ var dLen = $scope.ecdapp.revisions.length;
+
+ for (var i = 1; i < dLen; i++) {
+ var str = $scope.ecdapp.revisions[i].replace(/\s+/g, ' ');
+ var itemStrArr = str.split(" ");
+ var itemLen = itemStrArr.length;
+ var revObj = {};
+ revObj.revision = itemStrArr[0].trim();
+ revObj.updated = itemStrArr.slice(1,5).toString().replace(/,/g, ' ');
+ revObj.status = itemStrArr[6].trim();
+ revObj.chart = itemStrArr[7].trim();
+ revObj.description = itemStrArr.slice(8,itemLen).toString().replace(/,/g, ' ');
+ revObj.name = itemStrArr[0].trim();
+ revObj.checked = false;
+ $scope.ecdapp.local_revisions.push(revObj);
+ }
+ }
+ console.log($scope.ecdapp.local_revisions);
+ $scope.ecdapp.isRequestFailed = false;
+ }
+ $scope.ecdapp.isDataLoading = false;
+ },
+ function(error) {
+ $log.error('InventoryDeploymentService.getNodeInstanceVersions failed: ' + JSON.stringify(error));
+ $scope.ecdapp.isRequestFailed = true;
+ $scope.ecdapp.errMsg = error;
+ $scope.ecdapp.isDataLoading = false;
+ });
+ $scope.ecdapp.updateSelection = function(position) {
+ $scope.ecdapp.rollbackRequest.revision = position;
+ angular.forEach($scope.ecdapp.local_revisions, function(item, index) {
+ if (position != index+1)
+ item.checked = false;
+ });
+ }
+ /**
+ * rollback deployment based on parameters user enters/adjusts in modal popup
+ * First retrieves the node-id using the blueprintId
+ * Using the node-id and deploymentId, retrieves the node-instance-id
+ * Calls the update resource API, passing object with deploymentId, and changed parameters
+ */
+ $scope.ecdapp.rollbackWorkflow = function(revision) {
+ $scope.ecdapp.updatingDeployment = true;
+ $scope.ecdapp.isDataLoading = true;
+ InventoryDeploymentService.rollbackFlow($scope.ecdapp.rollbackRequest).then(function(jsonObj) {
+ if (debug)
+ $log.debug("inventoryDeploymentRollbackCtrl.rollbackWorkflow response: " + JSON.stringify(jsonObj));
+ if (jsonObj.error) {
+ $scope.ecdapp.errMsg = 'Request Failed: ' + jsonObj.error;
+ $scope.ecdapp.updatingDeployment = false;
+ $scope.ecdapp.isDataLoading = false;
+ } else {
+ console.log('%c ROLLBACK RESOURCES COMPLETED', 'color: magenta; font-weight: bold;');
+ alert('Rollback request for ' + $scope.ecdapp.deploymentRef + ' successfully went through to Cloudiy. Rollback is now pending');
+ $scope.ecdapp.updatingDeployment = false;
+ $scope.ecdapp.isDataLoading = false;
+ }
+ }, function(error) {
+ $scope.ecdapp.updatingDeployment = false;
+ $log.error('inventoryDeploymentRollbackCtrl failed: ' + error);
+ alert('Failed to rollback Deployment ' + $scope.ecdapp.deploymentRef + '. Please retry.');
+ $scope.ecdapp.isDataLoading = false;
+ });
+ }
+ });
+
+ /*************************************************************************/
+ appDS2.controller('appReconfigCtrl', function(
+ $scope, $rootScope, $log, $modalInstance, message, InventoryDeploymentService, DeploymentService) {
+
+ 'use strict';
+
+ var debug = true;
+ // this object holds all app data and functions
+ $scope.ecdapp = {};
+ $scope.ecdapp.tenant = message.deployment.tenant_name;
+ $scope.ecdapp.deploymentId = message.deployment.id;
+ $scope.ecdapp.bpId = message.deployment.blueprint_id;
+ $scope.ecdapp.errMsg = null;
+ $scope.ecdapp.isDataLoading = true;
+ $scope.ecdapp.isRequestFailed = false;
+ $scope.ecdapp.updatingDeployment = false;
+ $scope.ecdapp.parmFileDict = {};
+ $scope.ecdapp.parmCurrFileDict = {};
+ $scope.ecdapp.app_config_from_bp = {};
+ $scope.ecdapp.app_config_new = {};
+ $scope.ecdapp.app_config_bakup = {};
+ $scope.ecdapp.app_config_inputs = [];
+ $scope.ecdapp.app_config_bp_str ='';
+ $scope.ecdapp.app_config_latest_str ='';
+ $scope.ecdapp.descriptionDict = {};
+ $scope.ecdapp.appConfigOverride = {};
+ $scope.ecdapp.app_config_input_map = {};
+
+ $scope.ecdapp.reconfigRequest = {
+ deployment_id: $scope.ecdapp.deploymentId,
+ workflow_id: 'execute_operation',
+ parameters: {},
+ tenant: $scope.ecdapp.tenant
+ };
+ $scope.ecdapp.reconfigRequest.parameters.operation =
+ 'dcae.interfaces.lifecycle.Reconfiguration';
+ $scope.ecdapp.reconfigRequest.parameters.operation_kwargs = {};
+ $scope.ecdapp.reconfigRequest.parameters.operation_kwargs.type = 'app_reconfig';
+ $scope.ecdapp.reconfigRequest.parameters.operation_kwargs.application_config = {};
+ $scope.ecdapp.reconfigRequest.parameters.allow_kwargs_override = true;
+ $scope.ecdapp.reconfigRequest.parameters.type_names =
+ ['dcae.nodes.DockerContainerForComponents', 'dcae.nodes.DockerContainerForComponentsUsingDmaap',
+ 'dcae.nodes.ContainerizedServiceComponent', 'dcae.nodes.ContainerizedServiceComponentUsingDmaap'];
+
+ // get the BP object from cloudify
+ // get the depl object from cloudify
+ // get the node instance data from cloudify
+ // parse the application_config from BP node properties
+ // parse the inputs from deployment
+ // display FORM with current input fields that are referred in the appl
+ // config object
+ // display application_config on the screen and setup data binding to the
+ // input FORM
+ // create POST request body for start execution to cloudify
+ // invoke service method to send POST request to cloudify
+ InventoryDeploymentService.getBlueprint($scope.ecdapp.bpId,
+ $scope.ecdapp.tenant).then(function(blueprint) {
+ if (debug)
+ $log.debug("appReconfigCtrl.getBlueprint response: " + JSON.stringify(blueprint));
+ if (blueprint.error) {
+ $scope.ecdapp.errMsg = 'Request Failed: ' + blueprint.error;
+ $scope.ecdapp.updatingDeployment = false;
+ $scope.ecdapp.isRequestFailed = true;
+ }
+ else {
+ $scope.ecdapp.isRequestFailed = false;
+ if (Array.isArray(blueprint.items) && blueprint.items.length > 0) {
+ var foundNode = blueprint.items[0].plan.nodes.find(function checkAppConfig(node) {
+ if (Object.keys(node.properties).includes("application_config")) {
+ return true;
+ }
+ });
+ if (foundNode != undefined && foundNode.properties != undefined ) {
+ $scope.ecdapp.app_config_from_bp = foundNode.properties.application_config;
+ $scope.ecdapp.app_config_bp_str =
+ JSON.stringify($scope.ecdapp.app_config_from_bp, undefined, 4);
+
+ $scope.ecdapp.checkType = function(key1, value1) {
+ if (value1 instanceof Object && !Array.isArray(value1)) {
+ for (let [key2, value2] of Object.entries(value1)) {
+ if (key2 == "get_input") {
+ $scope.ecdapp.app_config_inputs.push(value2);
+ $scope.ecdapp.app_config_input_map[key1] = value2;
+ } else {
+ $scope.ecdapp.checkType(key2, value2);
+ }
+ }
+ }
+ };
+
+ for (let [key1, value1] of
+ Object.entries($scope.ecdapp.app_config_from_bp))
+ {
+ $scope.ecdapp.checkType(key1, value1);
+ }
+ }
+
+ let inputsAndDescriptions = {};
+ for (var pkey in blueprint.items[0].plan.inputs) {
+ let description = blueprint.items[0].plan.inputs[pkey].description;
+ if ( typeof description === "undefined" ) {
+ description = '';
+ }
+ inputsAndDescriptions[pkey] = description;
+ }
+ $scope.ecdapp.descriptionDict = inputsAndDescriptions;
+
+ InventoryDeploymentService.getDeployment($scope.ecdapp.deploymentId,
+ $scope.ecdapp.tenant).then(function(deployment) {
+ if (deployment.items.length == 0) {
+ $scope.ecdapp.errMsg = "404 - Deployment " + $scope.ecdapp.deploymentId + " Not Found!";
+ $log.error("InventoryDeploymentSerice.getDeployment failed: "
+ + $scope.ecdapp.errMsg);
+ $scope.ecdapp.isRequestFailed = true;
+ }
+ else {
+ $scope.ecdapp.errMsg = null;
+ $scope.ecdapp.deployment = deployment.items[0];
+ $scope.ecdapp.isRequestFailed = false;
+ if (Array.isArray(deployment.items) && deployment.items.length > 0) {
+ var deplInputs = deployment.items[0].inputs;
+ $scope.ecdapp.app_config_inputs.forEach(function findMatch(value, index, array) {
+ for (let [key, val] of Object.entries(deplInputs)) {
+ if (value == key) {
+ $scope.ecdapp.parmFileDict[key] = val;
+ }
+ }
+ });
+ }
+ }
+ $scope.ecdapp.isDataLoading = false;
+ },
+ function(error) {
+ $log.error('InventoryDeploymentService.getDeployment failed: ' + JSON.stringify(error));
+ $scope.ecdapp.isRequestFailed = true;
+ $scope.ecdapp.errMsg = error;
+ $scope.ecdapp.isDataLoading = false;
+ });
+
+ InventoryDeploymentService.getNodeInstanceData($scope.ecdapp.deploymentId,
+ $scope.ecdapp.tenant).then(function(nodeInstances) {
+ if (Array.isArray(nodeInstances.items) && nodeInstances.items.length > 0) {
+ var foundNode = nodeInstances.items.find(function checkAppConfig(item) {
+ if (Object.keys(item.runtime_properties).includes("application_config")) {
+ return true;
+ }
+ });
+ if (foundNode != undefined) {
+ $scope.ecdapp.app_config_new = foundNode.runtime_properties.application_config;
+ $scope.ecdapp.app_config_latest_str =
+ JSON.stringify($scope.ecdapp.app_config_new, undefined, 4);
+ for (let [key, value] of
+ Object.entries(foundNode.runtime_properties.application_config))
+ {
+ if (value.constructor === {}.constructor)
+ $scope.ecdapp.appConfigOverride[key] = angular.toJson(value);
+ else
+ $scope.ecdapp.appConfigOverride[key] = value;
+ }
+ $scope.ecdapp.app_config_inputs.forEach(function findMatch(value, index, array) {
+ for (let [key, val] of Object.entries($scope.ecdapp.appConfigOverride)) {
+ if (value == key) {
+ $scope.ecdapp.parmCurrFileDict[key] = val;
+ }
+ }
+ });
+ }
+ }
+ },
+ function(error) {
+ $log.error('InventoryDeploymentService.getNodeInstances failed: ' + JSON.stringify(error));
+ });
+ }
+ $scope.ecdapp.isDataLoading = false;
+ }
+ },
+ function(error) {
+ $log.error('InventoryDeploymentService.getBlueprint failed: ' + JSON.stringify(error));
+ $scope.ecdapp.isRequestFailed = true;
+ $scope.ecdapp.errMsg = error;
+ $scope.ecdapp.isDataLoading = false;
+ });
+
+ $scope.ecdapp.refreshAppConfig = function(newInputs) {
+ angular.copy($scope.ecdapp.app_config_from_bp, $scope.ecdapp.app_config_bakup);
+ for (let [input_key, input_val] of Object.entries(newInputs)) {
+ $scope.ecdapp.replaceNewInput(input_key, input_val, $scope.ecdapp.app_config_from_bp);
+ }
+ angular.copy($scope.ecdapp.app_config_from_bp, $scope.ecdapp.app_config_new);
+ angular.copy($scope.ecdapp.app_config_bakup, $scope.ecdapp.app_config_from_bp);
+
+ $scope.ecdapp.app_config_latest_str =
+ JSON.stringify($scope.ecdapp.app_config_new, undefined, 4);
+ };
+
+ var fileReader = new FileReader();
+ fileReader.onload = function(event) {
+ let jsonString = fileReader.result;
+ let ydict = {};
+ try {
+ ydict = JSON.parse(jsonString);
+ }
+ catch (ex) {
+ alert('Failed to parse file as JSON:\n' + ex);
+ }
+ // Process the file
+ for (var ykey in ydict) {
+ let yval = ydict[ykey];
+ // Allow only expected keys with scalar values
+ if (ykey in $scope.ecdapp.parmFileDict)
+ {
+ // alert('Unexpected file content:\nKey not defined by blueprint:\n' +
+ // ykey);
+ if (yval.constructor === {}.constructor)
+ $scope.ecdapp.parmFileDict[ykey] = angular.toJson(yval);
+ else
+ $scope.ecdapp.parmFileDict[ykey] = yval;
+ }
+ }
+ $scope.ecdapp.refreshAppConfig($scope.ecdapp.parmFileDict);
+ $scope.$apply();
+ };
+ // Handler for file-select event
+ $scope.handleFileSelect = function() {
+ if (debug)
+ $log.debug('handleFileSelect: $scope.ecdapp.fileModel.name is ' + $scope.ecdapp.editRequest.fileModel.name);
+ fileReader.readAsText($scope.ecdapp.editRequest.fileModel);
+ };
+ $scope.ecdapp.replaceNewInput = function(input_key, input_val, src) {
+ var itemFound = false;
+ for (let [key, value] of Object.entries(src)) {
+ if (value instanceof Object && !Array.isArray(value)) {
+ for (let [key2, value2] of Object.entries(value)) {
+ if (key2 == "get_input" && value2 == input_key) {
+ src[key] = input_val;
+ itemFound = true;
+ break;
+ } else {
+ $scope.ecdapp.replaceNewInput(input_key, input_val, value2);
+ }
+ }
+ }
+ if (itemFound) {
+ break;
+ }
+ }
+ };
+
+ $scope.ecdapp.reconfigDeploymentById = function(newInputs) {
+ $scope.ecdapp.updatingDeployment = true;
+ angular.copy($scope.ecdapp.app_config_from_bp, $scope.ecdapp.app_config_bakup);
+ for (let [input_key, input_val] of Object.entries(newInputs)) {
+ $scope.ecdapp.replaceNewInput(input_key, input_val,
+ $scope.ecdapp.app_config_from_bp);
+ }
+ angular.copy($scope.ecdapp.app_config_from_bp, $scope.ecdapp.app_config_new);
+ angular.copy($scope.ecdapp.app_config_bakup, $scope.ecdapp.app_config_from_bp);
+ $scope.ecdapp.app_config_latest_str =
+ JSON.stringify($scope.ecdapp.app_config_new, undefined, 4);
+
+ $scope.ecdapp.reconfigRequest.parameters.operation_kwargs.application_config =
+ $scope.ecdapp.app_config_new;
+
+ DeploymentService.reconfigFlow($scope.ecdapp.reconfigRequest).then(function(jsonObj) {
+ if (debug)
+ $log.debug("appReconfigCtrl.reconfigFlow response: " + JSON.stringify(jsonObj));
+ if (jsonObj.error) {
+ $scope.ecdapp.errMsg = 'Request Failed: ' + jsonObj.error;
+ $scope.ecdapp.updatingDeployment = false;
+ }
+ else {
+ $scope.ecdapp.updatingDeployment = false;
+ alert('application reconfig request for ' + $scope.ecdapp.deploymentId + ' successfully went through to Cloudify. Reconfig is now pending');
+ $modalInstance.dismiss('cancel');
+ }
+ }, function(error) {
+ $scope.ecdapp.updatingDeployment = false;
+ alert('Failed to perform reconfig for Deployment Id ' + $scope.ecdapp.deploymentId);
+ $log.error('appReconfigCtrl.reconfigFlow failed: ' + error);
+ });
+
+ };
+ });
+
+ /*************************************************************************/
+ appDS2.controller('deploymentUpgradeCtrl', function(
+ $scope, $rootScope, $log, $modalInstance, message, InventoryDeploymentService) {
+
+ 'use strict';
+
+ // Controls logging in this controller
+ var debug = false;
+
+ // this object holds all app data and functions
+ $scope.ecdapp = {};
+ $scope.ecdapp.label = 'Deployment Upgrade';
+ $scope.ecdapp.deployment = null;
+ $scope.ecdapp.deploymentRef = message.deployment.id; //THIS IS THE BLUEPRINT ID
+ $scope.ecdapp.bpId = message.deployment.blueprint_id;
+ $scope.ecdapp.serviceId = message.deployment.serviceId;
+ $scope.ecdapp.errMsg = null;
+ $scope.ecdapp.isDataLoading = true;
+ $scope.ecdapp.isRequestFailed = false;
+ $scope.ecdapp.updatingDeployment = false;
+ var selTenant = message.deployment.tenant_name;
+ if ( typeof selTenant === "undefined" ) {
+ selTenant = "default_tenant";
+ }
+ $scope.ecdapp.tenant = selTenant;
+ $scope.ecdapp.ui_tenant = selTenant;
+ $scope.ecdapp.parmFileDict = {};
+
+ // This object holds data for editing the input parameters
+ $scope.ecdapp.editRequest = {
+ deployment_id: '',
+ type_id: '',
+ fileModel: null,
+ resourceConstants: {},
+ resourceDefinitionChanges: {}
+ };
+ //First get the blueprintId associated with the deployment, along with the inputs of the deployment
+ InventoryDeploymentService.getDeployment($scope.ecdapp.deploymentRef, $scope.ecdapp.tenant).then(function(deployment) {
+ if (deployment.items.length == 0) {
+ $scope.ecdapp.errMsg = "404 - Deployment " + message.deployment.deploymentRef + " Not Found!";
+ $log.error("InventoryDeploymentSerice.getDeployment failed: "
+ + $scope.ecdapp.errMsg);
+ $scope.ecdapp.isRequestFailed = true;
+ }
+ // Deployment IDs are unique, so this will always return exactly one item!
+ else {
+ $scope.ecdapp.errMsg = null;
+ $scope.ecdapp.deployment = deployment.items[0];
+ $scope.ecdapp.isRequestFailed = false;
+ $scope.ecdapp.editRequest.type_id = deployment.items[0].blueprint_id;
+ $scope.ecdapp.parmFileDict = deployment.items[0].inputs;
+ Object.keys($scope.ecdapp.parmFileDict).map(function(key, index) {
+ if (key == 'config-format' || key == 'config-url' || key == 'chart-version' || key == 'chart-repo-url' || key == 'config-set') {
+ $scope.ecdapp.editRequest.resourceDefinitionChanges[key] = $scope.ecdapp.parmFileDict[key];
+ } else {
+ $scope.ecdapp.editRequest.resourceConstants[key] = $scope.ecdapp.parmFileDict[key];
+ }
+ //$scope.ecdapp.editRequest.resourceDefinitionChanges['config_set'] = '';
+ });
+ }
+ $scope.ecdapp.isDataLoading = false;
+ },
+ function(error) {
+ $log.error('InventoryDeploymentService.getDeployment failed: ' + JSON.stringify(error));
+ $scope.ecdapp.isRequestFailed = true;
+ $scope.ecdapp.errMsg = error;
+ $scope.ecdapp.isDataLoading = false;
+ });
+
+ /**
+ * Validates content of user-editable fields.
+ * Returns null if all is well,
+ * a descriptive error message otherwise.
+ */
+
+ $scope.ecdapp.validateRequest = function(editRequest) {
+ if (editRequest == null)
+ return 'No data found.\nPlease enter some values.';
+ if (editRequest["chart-version"] == null || editRequest["chart-version"].trim() == '')
+ return 'Chart version is required.\nPlease enter a value.';
+ if (!editRequest["config-format"] || editRequest["config-format"].trim() == '') {
+ return 'config format is required.\nPlease enter a value.';
+ }
+ if ((!editRequest["config-url"] || editRequest["config-url"].trim() == '') &&
+ (!editRequest["config_set"] || editRequest["config_set"].trim() == '')) {
+ return 'Config URL or Config set is required.\nPlease enter either of these input values';
+ }
+ return null;
+ };
+
+ /**
+ * Helm upgrade for deployment based on parameters user enters in modal popup
+ * First retrieves the node-id using the blueprintId
+ * Using the node-id and deploymentId, retrieves the node-instance-id
+ * Calls the start execution API, passing object with deploymentId, and changed parameters
+ */
+
+ $scope.ecdapp.upgradeWorkflow = function(resourceDefinitionChanges) {
+ $scope.ecdapp.updatingDeployment = true;
+ let nodeId = '';
+
+ // validate request
+ var validateMsg = $scope.ecdapp.validateRequest(resourceDefinitionChanges);
+ if (validateMsg != null) {
+ alert('Invalid Request:\n' + validateMsg);
+ $scope.ecdapp.updatingDeployment = false;
+ return;
+ }
+ //get node id from blueprint
+ InventoryDeploymentService.getBlueprint($scope.ecdapp.bpId, $scope.ecdapp.tenant).then(function(blueprint) {
+ if (debug)
+ $log.debug("inventoryDeploymentUpgradeCtrl.getBlueprint response: " + JSON.stringify(blueprint));
+ if (blueprint.error) {
+ $scope.ecdapp.errMsg = 'Request Failed: ' + blueprint.error;
+ $scope.ecdapp.updatingDeployment = false;
+ }
+ else {
+ //console.log('returned blueprint:' + blueprint);
+ let count = 0;
+ //console.log("number of node objects in array: " + blueprint.items[0].plan.nodes.length);
+ //console.log(JSON.stringify(blueprint));
+ blueprint.items[0].plan.nodes.map(function(node) {
+ if (node.type == 'onap.nodes.component') {
+ //want to get FIRST node with type 'cloudify.kubernetes.resources.Deployment' so only set nodeID for first matching type
+ if (count < 1) {
+ nodeId = node.id;
+ }
+ count = count + 1;
+ }
+ });
+ //if no node has type 'cloudify.kubernetes.resources.Deployment', return message saying no deployment exists and exit (ie nodeId still is '')
+ if (nodeId == '') {
+ alert('Failed to retrieve Node Id. No matching deployment found (no deployment exists)');
+ $scope.ecdapp.updatingDeployment = false;
+ return;
+ }
+ //found node id. now need to retrieve node-instance-id
+ console.log('%c RETRIEVED NODE ID: ' + nodeId, 'color: orange; font-weight: bold;');
+ let nodeInstanceId = '';
+ InventoryDeploymentService.getNodeInstanceId($scope.ecdapp.deploymentRef, nodeId, $scope.ecdapp.tenant).then(function(jsonObj) {
+ if (debug)
+ $log.debug("inventoryDeploymentUpgradeCtrl.getNodeInstanceId response: " + JSON.stringify(jsonObj));
+ if (jsonObj.error) {
+ $scope.ecdapp.errMsg = 'Request Failed: ' + jsonObj.error;
+ $scope.ecdapp.updatingDeployment = false;
+ }
+ else {
+ //if nodeInstanceId is still '' then it wasn't found, stop flow)
+ if (jsonObj.items[0].id == '') {
+ alert('Failed to retrieve Node Instance Id for Node Id' + nodeId);
+ $scope.ecdapp.updatingDeployment = false;
+ return;
+ }
+ //found node-instance-id. now need to update resources
+ nodeInstanceId = jsonObj.items[0].id;
+ console.log('%c RETRIEVED NODE INSTANCE ID:' + nodeInstanceId, 'color: green; font-weight: bold;');
+ //console.log(resourceDefinitionChanges);
+ InventoryDeploymentService.upgradeFlow($scope.ecdapp.deploymentRef, nodeInstanceId, resourceDefinitionChanges, $scope.ecdapp.tenant).then(function(jsonObj) {
+ if (debug)
+ $log.debug("inventoryDeploymentUpgradeCtrl.updateResources response: " + JSON.stringify(jsonObj));
+ if (jsonObj.error) {
+ $scope.ecdapp.errMsg = 'Request Failed: ' + jsonObj.error;
+ $scope.ecdapp.updatingDeployment = false;
+ }
+ else {
+ console.log('%c UPDATE RESOURCES COMPLETED', 'color: magenta; font-weight: bold;');
+ //console.log(jsonObj);
+ $scope.ecdapp.updatingDeployment = false;
+ alert('Helm Upgrade request for ' + $scope.ecdapp.deploymentRef + ' successfully went through to Cloudiy. Upgrade is now pending'); $modalInstance.dismiss('cancel');
+ }
+ }, function(error) {
+ $scope.ecdapp.updatingDeployment = false;
+ alert('Failed to perform upgrade for Deployment Id ' + $scope.ecdapp.deploymentRef + ' and Node Instance Id ' + nodeInstanceId + '. Please retry.');
+ $log.error('inventoryDeploymentUpgradeCtrl failed: ' + error);
+ });
+ }
+ }, function(error) {
+ $scope.ecdapp.updatingDeployment = false;
+ alert('Failed to get Node Instance Id for deploymentId ' + $scope.ecdapp.deploymentRef + ' and Node Id ' + nodeId + '. Please retry.');
+ $log.error('inventoryDeploymentUpgradeCtrl failed: ' + error);
+ });
+
+ }
+ }, function(error) {
+ $scope.ecdapp.updatingDeployment = false;
+ alert('Failed to get blueprint for blueprintId ' + $scope.ecdapp.deploymentRef + '. Please retry.');
+ $log.error('inventoryDeploymentUpgradeCtrl failed: ' + error);
+ });
+ };
+
+ /**
+ * Handler for file-read event reads file, parses JSON, validates content.
+ */
+
+ var fileReader = new FileReader();
+ fileReader.onload = function(event) {
+ let jsonString = fileReader.result;
+ if (debug)
+ $log.debug('fileReader.onload: read: ' + jsonString);
+ let ydict = {};
+ try {
+ ydict = JSON.parse(jsonString);
+ }
+ catch (ex) {
+ alert('Failed to parse file as JSON:\n' + ex);
+ }
+ // Process the file
+ for (var ykey in ydict) {
+ let yval = ydict[ykey];
+ if (debug)
+ $log.debug('fileReader.onload: typeof ' + ykey + ' is ' + typeof ykey);
+ // Allow only expected keys with scalar values
+ if (! (ykey in $scope.ecdapp.parmFileDict))
+ alert('Unexpected file content:\nKey not defined by blueprint:\n' + ykey);
+ if (yval.constructor === {}.constructor)
+ $scope.ecdapp.parmFileDict[ykey] = angular.toJson(yval);
+ else
+ $scope.ecdapp.parmFileDict[ykey] = yval;
+ }
+ if (debug)
+ $log.debug('fileReader.onload: parmFileDict: ' + JSON.stringify($scope.ecdapp.parmFileDict));
+
+ // Update table in all cases
+ //$scope.ecdapp.setResourceDefinitionChanges($scope.ecdapp.editRequest.resourceDefinitionChanges, $scope.ecdapp.editRequest.parmFileDict);
+ Object.keys($scope.ecdapp.parmFileDict).map(function(key, index) {
+
+ if (key == 'config-format' || key == 'config-url' || key == 'chart-version' || key == 'chart-repo-url' || key == 'config-set') {
+ $scope.ecdapp.editRequest.resourceDefinitionChanges[key] = $scope.ecdapp.parmFileDict[key];
+ } else {
+ $scope.ecdapp.editRequest.resourceConstants[key] = $scope.ecdapp.parmFileDict[key];
+ }
+ });
+ //$scope.$apply();
+ };
+
+ // Handler for file-select event
+ $scope.handleFileSelect = function() {
+ if (debug)
+ $log.debug('handleFileSelect: $scope.ecdapp.fileModel.name is ' + $scope.ecdapp.editRequest.fileModel.name);
+ fileReader.readAsText($scope.ecdapp.editRequest.fileModel);
+ };
+
+ });
+
diff --git a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/cloudify/deployment-service.js b/ccsdk-app-overlay/src/main/webapp/app/ccsdk/cloudify/deployment-service.js
index cee83c3..f7f9db3 100644
--- a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/cloudify/deployment-service.js
+++ b/ccsdk-app-overlay/src/main/webapp/app/ccsdk/cloudify/deployment-service.js
@@ -1,24 +1,3 @@
-/*******************************************************************************
- * =============LICENSE_START=========================================================
- *
- * =================================================================================
- * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file 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.
- * ============LICENSE_END=========================================================
- *
- * ECOMP is a trademark and service mark of AT&T Intellectual Property.
- *******************************************************************************/
appDS2.factory('DeploymentService', function ($http, $q, $log) {
return {
/**
@@ -27,10 +6,19 @@ appDS2.factory('DeploymentService', function ($http, $q, $log) {
* @param {Number} viewPerPage - number of items per page; e.g., 25
* @return {JSON} Response object from remote side
*/
- getDeployments: function(pageNum,viewPerPage) {
+ getDeployments: function(pageNum,viewPerPage,sortBy,searchBy) {
// cache control for IE
let cc = "&cc=" + new Date().getTime().toString();
- let url = 'deployments?pageNum=' + pageNum + '&viewPerPage=' + viewPerPage + cc;
+ let url = null;
+ if (sortBy && searchBy) {
+ url = 'deployments?pageNum=' + pageNum + '&viewPerPage=' + viewPerPage + '&sortBy=' + sortBy + '&searchBy=' + searchBy + cc;
+ } else if (sortBy) {
+ url = 'deployments?pageNum=' + pageNum + '&viewPerPage=' + viewPerPage + '&sortBy=' + sortBy + cc;
+ } else if (searchBy) {
+ url = 'deployments?pageNum=' + pageNum + '&viewPerPage=' + viewPerPage + '&searchBy=' + searchBy + cc;
+ } else {
+ url = 'deployments?pageNum=' + pageNum + '&viewPerPage=' + viewPerPage +cc;
+ }
return $http({
method: 'GET',
url: url,
@@ -84,6 +72,69 @@ appDS2.factory('DeploymentService', function ($http, $q, $log) {
$log.error('DeploymentService.deleteDeployment failed: ' + JSON.stringify(error));
return $q.reject(error.statusText);
});
+ },
+
+ getBlueprintContent: function(id, tenant) {
+ let url ='blueprints/' + id + '/archive?tenant=' + tenant;
+ return $http({
+ method: 'GET',
+ url: url,
+ cache: false,
+ responseType: 'yaml'
+ }).then(function(response) {
+ // This is called on response code 200..299.
+ // On success, response.data is null.
+ // On failure, response.data has an error message.
+/* var contentType = "application/octet-stream";
+ var data = response.data
+ var urlCreator = window.URL || window.webkitURL || window.mozURL || window.msURL;
+ if (urlCreator) {
+ var blob = new Blob([data], { type: contentType });
+ var url = urlCreator.createObjectURL(blob);
+ var a = document.createElement("a");
+ document.body.appendChild(a);
+ a.style = "display: none";
+ a.href = url;
+ a.download = "blueprint.yaml"; //you may assign this value from header as well
+ a.click();
+ window.URL.revokeObjectURL(url);
+ }*/
+ return response;
+ },
+ function(error) {
+ $log.error('DeploymentService.getBlueprintContent failed: ' + JSON.stringify(error));
+ return $q.reject(error.statusText);
+ });
+ },
+
+ reconfigFlow: function(reconfigRequest) {
+ let body = {
+ "deployment_id": reconfigRequest.deployment_id,
+ "workflow_id": reconfigRequest.workflow_id,
+ "allow_custom_parameters": true,
+ "force": true,
+ "tenant": reconfigRequest.tenant,
+ "parameters": reconfigRequest.parameters
+ };
+ let urlStr = 'executions';
+ return $http({
+ method: 'POST',
+ url: urlStr,
+ data: body,
+ cache: false,
+ responseType: 'json'
+ }).then(function(response) {
+ if (response.data == null)
+ return $q.reject('DeploymentService.reconfigFlow: response.data null or not object');
+ else {
+ console.log(response);
+ return response.data;
+ }
+ },
+ function(error) {
+ $log.error('DeploymentService.reconfigFlow failed: ' + JSON.stringify(error));
+ return $q.reject(error.statusText);
+ });
}
};
});
diff --git a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/cloudify/deployment_popups.html b/ccsdk-app-overlay/src/main/webapp/app/ccsdk/cloudify/deployment_popups.html
index f4a4cdd..d051495 100644
--- a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/cloudify/deployment_popups.html
+++ b/ccsdk-app-overlay/src/main/webapp/app/ccsdk/cloudify/deployment_popups.html
@@ -1,3 +1,43 @@
+<script type="text/ng-template" id="blueprint_content_popup.html">
+ <div class="b2b-modal-header ng-scope">
+ <h2 id="myModalLabel" modal-title="">{{ecdapp.label}}</h2>
+ <div class="corner-button in">
+ <button type="button" class="close" aria-label="Close"
+ ng-click="$dismiss('cancel')"></button>
+ </div>
+ </div>
+ <div class="b2b-modal-body ng-scope ng-isolate-scope" tabindex="0"
+ role="region" aria-label="Modal body content">
+ <!-- show progress indicator -->
+ <div ng-show="ecdapp.isDataLoading">
+ <div class="span" style="margin-bottom: 20px;">
+ <i class="icon-spinner small" role="img"
+ aria-label="Please wait while the content loads"></i> Please
+ wait while the content loads.
+ </div>
+ </div>
+ <div ng-show="ecdapp.errMsg">
+ <span class="ecd-error-message">{{ecdapp.errMsg}}</span>
+ </div>
+ <div class="row-nowrap">
+ <div class="span12">
+ <label for="typeName">Blueprint Name</label>
+ <!--not editable-->
+ <input id="typeName" class="span12" type="text"
+ disabled="disabled" data-ng-model="ecdapp.typeName" />
+ </div>
+ </div>
+ <div ng-hide="ecdapp.errMsg">
+ <pre>{{ecdapp.blueprint}}</pre>
+ </div>
+ </div>
+ <div class="b2b-modal-footer ng-scope ng-isolate-scope">
+ <div class="cta-button-group in">
+ <button class="btn btn-alt btn-small" type="button"
+ ng-click="$dismiss('cancel');">Close</button>
+ </div>
+ </div>
+</script>
<script type="text/ng-template" id="deployment_execute_popup.html">
<style>
@@ -91,7 +131,7 @@
<tbody ng-repeat="(pkey, pval) in ecdapp.editRequest.parmFileDict">
<tr id="tr-rowData">
<td ng-bind="pkey"/>
- <td ng-bind="pval"/>
+ <td><input id="parameterValue" class="span12" type="text" data-ng-model="ecdapp.editRequest.parmFileDict[pkey]" autofocus/></td>
</tr>
</tbody>
</table>
@@ -116,49 +156,138 @@
</script>
-<script type="text/ng-template" id="deployment_delete_popup.html">
-
-
- <div class="b2b-modal-header ng-scope">
- <h2 id="myModalLabel" modal-title="">{{ecdapp.label}}</h2>
- <div class="corner-button in">
- <button type="button" class="close" aria-label="Close"
- ng-click="$dismiss('cancel')"></button>
- </div>
- </div>
-
- <div class="b2b-modal-body ng-scope ng-isolate-scope" tabindex="0"
+<script type="text/ng-template" id="app_reconfig_view_popup.html">
+ <div class="b2b-modal-header ng-scope">
+ <h2 id="myModalLabel" modal-title="">
+ <span style="font-weight: bolder; background: aqua;">{{ecdapp.deploymentId}}</span>
+ Execute Reconfiguration
+ </h2>
+ <div class="corner-button in">
+ <button type="button" class="close" aria-label="Close"
+ ng-click="$dismiss('cancel')"></button>
+ </div>
+ </div>
+ <div class="b2b-modal-body ng-scope ng-isolate-scope" tabindex="0"
role="region" aria-label="Modal body content">
-
- <div class="span12">
- <div class="form-row">
- <div class="field-group">
- <label>
- Delete deployment with ID '{{ecdapp.deploymentId}}'?
- </label>
+ <!-- show progress indicator -->
+ <div ng-show="ecdapp.isDataLoading">
+ <div class="span" style="margin-bottom: 20px;">
+ <i class="icon-spinner small" role="img"
+ aria-label="Please wait while the content loads"></i> Please
+ wait while the content loads.
+ </div>
+ </div>
+ <div ng-show="ecdapp.errMsg">
+ <span class="ecd-error-message">{{ecdapp.errMsg}}</span>
+ </div>
+ <div ng-hide="ecdapp.isDataLoading" style="margin-top: 10px;">
+ <div class="row-nowrap">
+ <div class="span9">
+ <div class="form-row">
+ <label for="parameters">Configuration Inputs</label>
+ <div class="tooltip" b2b-tooltip trigger="focus" style="float:right;">
+ <a href="javascript:void(0)" class="tooltip-element" data-placement="left" role="button" aria-label="Help" aria-describedby="tooltiptext1" >
+ blueprint
+ <div class="arrow"></div>
+ </a>
+ <div class="tooltip-wrapper" role="tooltip" aria-live="polite" aria-atomic="false" style="z-index:1111">
+ <div class="tooltip-size-control">
+ <div class="helpertext" tabindex="-1" role="tooltip" id="tooltiptext1">
+ <div class="popover-title">Application Configuration Blueprint</div>
+ <div class="popover-content">
+ <pre>{{ecdapp.app_config_bp_str}}</pre>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ <div b2b-file-drop
+ file-model="ecdapp.editRequest.fileModel"
+ on-drop="handleFileSelect()" align="center">
+ <span b2b-file-link
+ file-model="ecdapp.editRequest.fileModel"
+ on-file-select="handleFileSelect()"> Drag
+ &amp; drop a parameters JSON file here, or click to
+ browse. </span>
+ </div>
+ </div>
+ <div class="ecd-parameter-table">
+ <table id="parameters">
+ <tr id="ecd-table-header">
+ <th width="20%">Name</th>
+ <th width="40%">Initial Value</th>
+ <th width="40%">Current Value</th>
+ </tr>
+ <tbody
+ ng-repeat="(pkey, pval) in ecdapp.parmFileDict">
+ <tr id="tr-rowData">
+ <td>
+ <div style="font-weight: bold;">{{pkey}}</div>
+ <div style="margin-top: 8px; font-weight: lighter;">{{ecdapp.descriptionDict[pkey]}}</div>
+ </td>
+ <td><input class="span12"
+ type="text" disabled="disabled"
+ data-ng-model="ecdapp.parmFileDict[pkey]"
+ autofocus />
+ </td>
+ <td><input class="span12"
+ type="text"
+ data-ng-model="ecdapp.parmCurrFileDict[pkey]"
+ ng-keyup="ecdapp.refreshAppConfig(ecdapp.parmCurrFileDict);"
+ autofocus />
+ </td>
+ </tr>
+ </tbody>
+ </table>
</div>
+ <!--
+ <div class="reconfig-params" style="margin-top: 10px;">
+ <label for="parameters">Configuration Override</label>
+ <table id="reconfig">
+ <tr id="ecd-table-header">
+ <th width="50%">Name</th>
+ <th width="50%">Value</th>
+ </tr>
+ <tbody
+ ng-repeat="(pkey, pval) in ecdapp.appConfigOverride">
+ <tr id="tr-rowData">
+ <td>
+ <div style="font-weight: bold;">{{pkey}}</div>
+ </td>
+ <td><input class="span12"
+ type="text"
+ ng-keyup="ecdapp.refreshAppConfigOverride(pkey, pval);"
+ data-ng-model="ecdapp.appConfigOverride[pkey]" autofocus />
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ -->
</div>
- </div>
-
- <div class="span12">
- <div class="form-row">
- <label for="ignoreLiveNodesCheck">&nbsp;</label>
- <div class="field-group">
- <label for="ignoreLiveNodes" class="checkbox">
- <input id="ignoreLiveNodes" type="checkbox" ng-model="ecdapp.ignoreLiveNodes" />
- <i class="skin"></i><span>Ignore Live Nodes</span>
- </label>
+ <div class="span3">
+ <div class="form-row">
+ <label style="text-decoration: underline;">Application Configuration</label>
+ <pre style="font-weight: bold;">{{ecdapp.app_config_latest_str}}</pre>
</div>
</div>
- </div>
-
+ </div>
</div>
-
- <div class="b2b-modal-footer ng-scope ng-isolate-scope">
+ <!-- show progress indicator -->
+ <div style="width: 100%;">
+ <div ng-show="ecdapp.updatingDeployment"
+ style="display: table; margin: 0 auto;" class="span">
+ <i class="icon-spinner small" role="img"
+ aria-label="Update Deployment in Progress..."></i> Update
+ Deployment in Progress...
+ </div>
+ </div>
+ <div ng-hide="ecdapp.isDataLoading" class="b2b-modal-footer ng-scope ng-isolate-scope">
<div class="cta-button-group in">
<button class="btn btn-alt btn-small" type="button"
- ng-click="ecdapp.deleteDeploymentById(deployment);">
- Delete
+ ng-show="!ecdapp.updatingDeployment"
+ ng-click="ecdapp.reconfigDeploymentById(ecdapp.parmCurrFileDict);">
+ Submit
</button>
<button class="btn btn-small" type="button"
ng-click="$dismiss('cancel')">
diff --git a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/cloudify/deployment_table.html b/ccsdk-app-overlay/src/main/webapp/app/ccsdk/cloudify/deployment_table.html
index c414484..211d17d 100644
--- a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/cloudify/deployment_table.html
+++ b/ccsdk-app-overlay/src/main/webapp/app/ccsdk/cloudify/deployment_table.html
@@ -1,93 +1,339 @@
<div id="page-content">
+ <h1 class="heading-page" id="deployments-page">Deployments</h1>
+ <div style="float: right; margin-top: -20px;" class="span4 form-row">
+ <div ng-show="ecdapp.groupByTenant" class="field-group span10">
+ <label title="Cloudify Tenant" for="cldTenants">Tenant: {{ecdapp.selectedTenant}}</label>
+ <select id="cldTenants" name="cldTenants" b2b-dropdown placeholder-text="Select Tenant"
+ class="span8"
+ ng-model="ecdapp.selectedTenant"
+ ng-change="ecdapp.tenantChangeHandler()">
+ <option b2b-dropdown-list
+ option-repeat="d in ecdapp.availableTenants" value="{{d}}">{{d}}</option>
+ </select>
+ </div>
+ </div>
+ <!-- show progress indicator -->
+ <div ng-show="ecdapp.isDataLoading">
+ <div class="span" style="margin-bottom: 20px;">
+ <i class="icon-spinner small" role="img"
+ aria-label="Please wait while the content loads"></i> Please
+ wait while the content loads.
+ </div>
+ </div>
+ <div>
+ <div id="button-search-row" style="margin-left: 45px; width: 60%;"
+ ng-hide="ecdapp.isDataLoading">
+ <div>
+ <div class="group">
+ <div class="advanced-search">
+ <button tabindex="-1"
+ style="position: absolute; margin-left: -35px; border: none; background: none; top: 5px;"
+ "class="btn btn-small" title="Reload view without applying basic filters"
+ type="button" ng-click="ecdapp.reloadTable()">
+ <i class="icon-arrows-replay-restart"></i>
+ </button>
+ <button tabindex="1"
+ style="position: absolute; border: none; background: none; margin-left: 5px; top: 5px;"
+ "class="btn btn-medium" type="button"
+ ng-click="ecdapp.filterBySvc()">
+ <i class="ion-search"></i>
+ </button>
+ <input tabindex="0" style="padding-left: 50px;"
+ class="advanced-search-input" type="text"
+ placeholder="Search Deployments"
+ title="multiple deployment name patterns - comma separated values"
+ ng-model="ecdapp.searchString"
+ ng-keydown="[13, 32].includes($event.keyCode) && ecdapp.filterBySvc()"></input>
+ <button type="button" id="show-menu-filters"
+ class="btn dropdown-toggle"
+ ng-click="ecdapp.toggleMoreFilters()" data-toggle="dropdown"
+ title="More Filters">
+ <i class="icon-controls-down"></i>
+ </button>
+ </div>
+ </div>
+ <div class="menu-filters" ng-show="ecdapp.showingMoreFilters">
+ <div class="group">
+ <label class="col-sm-3 control-label">Service IDs: </label>
+ <ui-select multiple ng-model="ecdapp.selectedServices"
+ ng-disabled="ecdapp.usingAafFilter || ecdapp.usingDcaeTargetTypeFilter"
+ theme="bootstrap" close-on-select="false" title="Service ID">
+ <ui-select-match class="ui-select-match">{{$item}}</ui-select-match>
+ <ui-select-choices class="ui-select-choices"
+ repeat="service in ecdapp.availableServices | filter:$select.search"
+ position='down'> {{service}} </ui-select-choices> </ui-select>
+ </div>
+ <div class="group" ng-hide="ecdapp.filterByUser">
+ <label class="col-sm-3 control-label">Owners: </label>
+ <ui-select multiple ng-model="ecdapp.selectedOwner"
+ theme="bootstrap" close-on-select="false"
+ title="Blueprint owner"> <ui-select-match
+ class="ui-select-match">{{$item}}</ui-select-match> <ui-select-choices
+ class="ui-select-choices"
+ repeat="owner in ecdapp.bpOwners | filter:$select.search"
+ position='down'> {{owner}} </ui-select-choices> </ui-select>
+ </div>
+ <div class="group">
+ <label class="col-sm-3 control-label">Status: </label>
+ <ui-select multiple ng-model="ecdapp.selectedStatus"
+ ng-disabled="ecdapp.usingAafFilter || ecdapp.usingDcaeTargetTypeFilter"
+ theme="bootstrap" close-on-select="false"
+ title="Install Status"> <ui-select-match
+ class="ui-select-match">{{$item}}</ui-select-match> <ui-select-choices
+ class="ui-select-choices"
+ repeat="status in ecdapp.availableStatus | filter:$select.search"
+ position='down'> {{status}} </ui-select-choices> </ui-select>
+ </div>
+ <div title="Helm only" style="margin-top: 10px;">
+ <label for="checkbox1" class="checkbox"> <input
+ ng-disabled="ecdapp.usingAafFilter || ecdapp.usingDcaeTargetTypeFilter"
+ id="checkbox1" type="checkbox" ng-model="ecdapp.isHelmType"><i
+ class="skin"></i><span>Helm Chart Deployment</span>
+ </label>
+ </div>
+ <div class="group">
+ <label class="col-sm-3 control-label">AAF Username: </label> <input
+ tabindex="0" class="advanced-search-input" type="text"
+ title="Filter by AAF Username in inputs - *Disables other fields*"
+ ng-disabled="ecdapp.usingDcaeTargetTypeFilter"
+ ng-model="ecdapp.aafUsernameString"
+ ng-change="ecdapp.handleDisableOtherFields()"></input>
+ </div>
+ <div class="group">
+ <label class="col-sm-3 control-label">DCAE Target
+ Type: </label> <input tabindex="0" class="advanced-search-input"
+ type="text"
+ title="Filter by DCAE Target Type in inputs - *Disables other fields*"
+ ng-disabled="ecdapp.usingAafFilter"
+ ng-model="ecdapp.dcaeTargetTypeString"
+ ng-change="ecdapp.handleDisableOtherFields()"></input>
+ </div>
+ <div class="group" style="float: right;">
+ <button tabindex="-1" class="btn btn-small"
+ title="Reset Filters" type="button"
+ ng-click="ecdapp.resetFilters()">
+ <i class="icon-arrows-replay-restart"></i>
+ </button>
+ <button tabindex="1" class="btn btn-small"
+ title="Filtered search" type="button"
+ ng-click="ecdapp.extendedfilterSrch()">
+ <i class="ion-search"></i>
+ </button>
+ </div>
+ </div>
+ </div>
+ </div>
+ <div id="depFilter" style="margin-left: 20px;margin-top: 10px; margin-bottom: 10px;" title="Additional filters">
+ <label for="checkbox3" class="checkbox" style="margin-right: 100px;">
+ <input id="checkbox3" type="checkbox" ng-model="ecdapp.filterByUser" ng-change="ecdapp.toggleUserFilt()" class="ng-valid ng-dirty ng-valid-parse ng-touched">
+ <i class="skin"></i><span>My Deployments</span>
+ </label>
+ <label for="checkbox1" class="checkbox" style="margin-right: 20px;">
+ <input id="checkbox1" type="checkbox" ng-model="ecdapp.useCache" ng-change="ecdapp.toggleRefresh()" class="ng-pristine ng-untouched ng-valid">
+ <i class="skin"></i><span>Cache</span>
+ </label>
+ <label for="checkbox2" class="checkbox" >
+ <input id="checkbox2" type="checkbox" ng-model="ecdapp.groupByTenant" ng-change="ecdapp.toggleTenantFilt()" class="ng-valid ng-dirty ng-valid-parse ng-touched">
+ <i class="skin"></i><span>Tenant</span>
+ </label>
+ </div>
+ </div>
- <h1 class="heading-page" id="deployments-page">Deployments</h1>
-
- <!-- show progress indicator -->
- <div ng-show="ecdapp.isDataLoading">
- <div class="span" style="margin-bottom:20px;">
- <i class="icon-primary-spinner small" role="img" aria-label="Please wait while the content loads"></i>
- Please wait while the content loads.
- </div>
- </div>
+ <div ng-show="ecdapp.isRequestFailed">
+ <span class="ecd-error-message">{{ecdapp.errMsg}}</span>
+ </div>
+ <div ng-hide="ecdapp.isRequestFailed">
+ <div b2b-table id="deployments-table" class="b2b-table-div"
+ table-data="ecdapp.tableData"
+ current-page="ecdapp.currentPageIgnored"
+ next-sort="ecdapp.nextSortIgnored">
+ <table>
+ <thead b2b-table-row type="header">
+ <tr id="th-header-row">
+ <th b2b-table-header sortable="false" key="id"
+ ng-click="ecdapp.sortTable('id')">ID</th>
+ <th b2b-table-header sortable="false" key="blueprint_id"
+ ng-click="ecdapp.sortTable('blueprint_id')">Blueprint ID</th>
+ <!-- <th b2b-table-header key="description">Description</th> -->
+ <th b2b-table-header sortable="false" key="created_at"
+ ng-click="ecdapp.sortTable('created_at')">Created Date</th>
+ <th b2b-table-header sortable="false" key="owner"
+ ng-click="ecdapp.sortTable('created_at')">Owner</th>
+ <th b2b-table-header sortable="false" key="tenant" >Tenant</th>
+ <!-- <th b2b-table-header key="updated_at">Updated Date</th>-->
+ <th b2b-table-header sortable="false" key="status">Health</th>
+ <th b2b-table-header sortable="false">Actions</th>
+ <!-- <th b2b-table-header sortable="false"><i class="icon-controls-gear ecd-icon-display"></i></th> -->
+ </tr>
+ </thead>
+ <tbody b2b-table-row type="body"
+ row-repeat="rowData in ecdapp.tableData">
+ <tr id="tr-rowData">
+ <td b2b-table-body>
+ <div>
+ <div ng-if="rowData.lastExecution.status !== undefined" class="stat_tooltip"
+ style="width: 30px; position: relative;">
+ <img ng-if="rowData.lastExecution.status !== undefined &&
+ rowData.lastExecution.status == 'terminated'"
+ src="static/fusion/images/active.png"/>
+ <img ng-if="rowData.lastExecution.status !== undefined &&
+ rowData.lastExecution.status == 'failed'"
+ src="static/fusion/images/inactive.png"/>
+ <img ng-if="rowData.lastExecution.status !== undefined &&
+ rowData.lastExecution.status == 'started'"
+ src="static/fusion/images/loading.gif"/>
+ <img ng-if="rowData.lastExecution.status !== undefined &&
+ rowData.lastExecution.status == 'pending'"
+ src="static/fusion/images/loading.gif"/>
+ <div class="wrapper">
+ <div>
+ <span
+ style="left: 10px; font-weight: bold; position: relative; top: 10px;">Last
+ Execution in Cloudify</span>
+ <table>
+ <thead>
+ <tr>
+ <th>Workflow</th>
+ <th>Status</th>
+ <th>Created</th>
+ <th>Ended</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>{{rowData.lastExecution.workflow_id}}</td>
+ <td>{{rowData.lastExecution.status}}</td>
+ <td>{{rowData.lastExecution.created_at}}</td>
+ <td>{{rowData.lastExecution.ended_at}}</td>
+ </tr>
+ <div
+ style="position: relative; top: 150px; width: 250px; margin: 0 auto;">
+ <button style="border-radius: 5px;"
+ ng-click="ecdapp.viewDeploymentExecutionsModalPopup(rowData)">
+ View Executions</button>
+ </div>
+ </tbody>
+ </table>
+ </div>
+ </div>
+ </div>
+ <div style="position: relative; left: 10px;">{{rowData.id}}</div>
+ </div>
+ </td>
+ <td b2b-table-body>
+ <div ng-if="rowData.description !== undefined" class="gen_tooltip">{{rowData.blueprint_id}}
+ <div>
+ <span class="gen_tooltiptext_r">{{rowData.description}}</span>
+ </div>
+ </div>
+ <div ng-if="rowData.description === undefined">{{rowData.blueprint_id}}</div>
+ </td>
+ <td b2b-table-body ng-bind="rowData.created_at"/>
+ <!-- <td b2b-table-body ng-bind="rowData.updated_at" /> -->
+ <td b2b-table-body ng-bind="rowData.owner"/>
+ <td b2b-table-body ng-bind="rowData.tenant_name"/>
+ <td b2b-table-body>
+ <img ng-if="rowData.healthStatus == 'passing'"
+ src="static/fusion/images/active.png"
+ title="{{rowData.healthStatus}}" /> <img
+ ng-if="rowData.healthStatus == 'critical'"
+ src="static/fusion/images/inactive.png"
+ title="{{rowData.healthStatus}}" /> </span>
+ </td>
+ <td b2b-table-body>
+ <div class="btn-group btn-actions"
+ style="margin-bottom: 0; box-shadow: none;">
+ <button type="button" class="btn dropdown-toggle"
+ data-toggle="dropdown" title="More Actions">
+ <i class="icon-apps-marketplace"></i>
+ </button>
+ <ul class="dropdown-menu">
+ <li>
+ <div ng-show="rowData.lastExecution.status != ''"
+ ng-click="ecdapp.getBlueprintDataModal(rowData);">
+ <i class="icon-documents-book ecd-icon-action"></i><a
+ href="">View blueprint</a>
+ </div>
+ </li>
+ <li>
+ <div ng-show="rowData.lastExecution.status != ''"
+ ng-click="ecdapp.viewDeploymentInputsModalPopup(rowData);">
+ <i class="icoDocuments-report ecd-icon-action"></i><a
+ href="">View Inputs</a>
+ </div>
+ </li>
+ <li>
+ <div ng-show="rowData.lastExecution.status != ''"
+ ng-click="ecdapp.viewDeploymentExecutionsModalPopup(rowData);">
+ <i class="icon-overview ecd-icon-action"></i><a
+ href="">View executions</a>
+ </div>
+ </li>
+ <li>
+ <div
+ ng-show="rowData.canDeploy && rowData.lastExecution.status === 'terminated'"
+ ng-click="ecdapp.updateDeploymentModalPopup(rowData);">
+ <i class="icon-misc-pen ecd-icon-action"></i><a
+ href="">Update deployment</a>
+ </div>
+ </li>
+ <li>
+ <div
+ ng-show="rowData.canDeploy && rowData.lastExecution.status != ''"
+ ng-click="ecdapp.deleteDeploymentModalPopup(rowData);">
+ <i class="icon-misc-trash ecd-icon-action"></i><a
+ href="">Undeploy</a>
+ </div>
+ </li>
+ <li>
+ <div
+ ng-show="rowData.isHelm && rowData.helmStatus"
+ ng-click="ecdapp.checkHelmStatus(rowData);">
+ <i class="icoDocuments-report ecd-icon-action"></i><a
+ href="">Helm Status</a>
+ </div>
+ </li>
+ <li>
+ <div
+ ng-show="rowData.canDeploy && rowData.isHelm"
+ ng-click="ecdapp.upgradeDeploymentModalPopup(rowData);">
+ <i
+ class="icon-controls-down ecd-icon-action"></i><a
+ href="">Helm Upgrade</a>
+ </div>
+ </li>
+ <li>
+ <div
+ ng-show="rowData.canDeploy && rowData.isHelm"
+ ng-click="ecdapp.rollbackDeploymentModalPopup(rowData);">
+ <i
+ class="icon-controls-up ecd-icon-action"></i><a
+ href="">Helm Rollback</a>
+ </div>
+ </li>
+ <li>
+ <div
+ ng-click="ecdapp.reconfigDeploymentModalPopup(rowData);">
+ <i
+ class="icon-datanetwork-contentdelivery ecd-icon-action"></i><a
+ href="">Reconfigure</a>
+ </div>
+ </li>
+ </ul>
+ </div> <!-- .btn-group -->
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ <div b2b-pagination="" total-pages="ecdapp.totalPages"
+ current-page="ecdapp.currentPageNum"
+ click-handler="pageChangeHandler" role="navigation"></div>
+ </div>
+</div>
+<div style="height: 10px;">
+ <!-- space between page number and black footer -->
+</div>
- <div ng-hide="ecdapp.isDataLoading">
-
- <div id="button-search-row">
- <div style="float:right;">
- <div class="form-field form-field__small">
- <input
- type="text"
- placeholder="Search Deployments"
- ng-model="ecdapp.searchString"/>
- </div>
- </div>
- </div>
-
- <div ng-show="ecdapp.isRequestFailed">
- <span class="ecd-error-message">{{ecdapp.errMsg}}</span>
- </div>
-
- <div ng-hide="ecdapp.isRequestFailed">
-
- <div
- b2b-table
- id="deployments-table"
- class="b2b-table-div"
- table-data="ecdapp.tableData"
- search-string="ecdapp.searchString"
- current-page="ecdapp.currentPageIgnored"
- next-sort="ecdapp.nextSortIgnored">
-
- <table>
-
- <thead b2b-table-row type="header">
- <tr id="th-header-row">
- <th b2b-table-header key="deployment_id">ID</th>
- <th b2b-table-header key="blueprint_id">Blueprint ID</th>
- <th b2b-table-header key="description">Description</th>
- <th b2b-table-header key="created_at">Created Date</th>
- <th b2b-table-header key="updated_at">Updated Date</th>
- <th b2b-table-header sortable="false"><i class="icon-controls-gear ecd-icon-display"></i></th>
- </tr>
- </thead>
-
- <tbody b2b-table-row type="body" row-repeat="rowData in ecdapp.tableData">
- <tr id="tr-rowData">
- <td b2b-table-body
- ng-bind="rowData.id"/>
- <td b2b-table-body
- ng-bind="rowData.blueprint_id"/>
- <td b2b-table-body
- ng-bind="rowData.description"/>
- <td b2b-table-body
- ng-bind="rowData.created_at"/>
- <td b2b-table-body
- ng-bind="rowData.updated_at"/>
- <td b2b-table-body>
- <div ng-click="ecdapp.createExecutionModalPopup(rowData);">
- <a href="" title="Create execution" class="icon-controls-playalt ecd-icon-action"></a>
- </div>
- <div ng-click="ecdapp.deleteDeploymentModalPopup(rowData);">
- <a href="" title="Delete deployment" class="icon-misc-trash ecd-icon-action"></a>
- </div>
- </td>
- </tr>
- </tbody>
- </table>
- </div>
-
- <div b2b-pagination="" total-pages="ecdapp.totalPages"
- current-page="ecdapp.currentPageNum" click-handler="pageChangeHandler"
- role="navigation">
- </div>
-
- </div>
- </div>
-
- <div style="height: 10px;">
- <!-- space between page number and black footer -->
- </div>
-
- </div><!-- loading -->
-
-</div><!-- page content -->
+<!-- loading -->
+<!-- page content -->
diff --git a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/cloudify/execution-service.js b/ccsdk-app-overlay/src/main/webapp/app/ccsdk/cloudify/execution-service.js
index 34414c4..e4a8879 100644
--- a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/cloudify/execution-service.js
+++ b/ccsdk-app-overlay/src/main/webapp/app/ccsdk/cloudify/execution-service.js
@@ -1,24 +1,3 @@
-/*******************************************************************************
- * =============LICENSE_START=========================================================
- *
- * =================================================================================
- * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file 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.
- * ============LICENSE_END=========================================================
- *
- * ECOMP is a trademark and service mark of AT&T Intellectual Property.
- *******************************************************************************/
appDS2.factory('ExecutionService', function ($http, $q, $log) {
return {
/**
@@ -88,8 +67,8 @@ appDS2.factory('ExecutionService', function ($http, $q, $log) {
});
},
- cancelExecution: function(id, deploymentId, action) {
- let url = 'executions/' + id + '?deployment_id=' + deploymentId + '&action=' + action;
+ cancelExecution: function(id, deploymentId, action, tenant) {
+ let url = 'executions/' + id + '?deployment_id=' + deploymentId + '&action=' + action + '&tenant=' + tenant;
return $http({
method: 'DELETE',
url: url,
@@ -105,6 +84,6 @@ appDS2.factory('ExecutionService', function ($http, $q, $log) {
$log.error('ExecutionService.cancelExecution failed: ' + JSON.stringify(error));
return $q.reject(error.statusText);
});
- }
+ },
};
});
diff --git a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/cloudify/plugin-service.js b/ccsdk-app-overlay/src/main/webapp/app/ccsdk/cloudify/plugin-service.js
new file mode 100644
index 0000000..0d34db3
--- /dev/null
+++ b/ccsdk-app-overlay/src/main/webapp/app/ccsdk/cloudify/plugin-service.js
@@ -0,0 +1,31 @@
+appDS2.factory('PluginService', function ($http, $q, $log) {
+ return {
+ /**
+ * Gets one page of objects.
+ * @param {Number} pageNum - page number; e.g., 1
+ * @param {Number} viewPerPage - number of items per page; e.g., 25
+ * @return {JSON} Response object from remote side
+ */
+ getPlugins: function(pageNum,viewPerPage) {
+ // cache control for IE
+ let cc = "&cc=" + new Date().getTime().toString();
+ let url = 'plugins?pageNum=' + pageNum + '&viewPerPage=' + viewPerPage + cc;
+ return $http({
+ method: 'GET',
+ url: url,
+ cache: false,
+ responseType: 'json'
+ }).then(function(response) {
+ if (response.data == null || typeof response.data != 'object')
+ return $q.reject('PluginService.getPlugins: response.data null or not object');
+ else
+ return response.data;
+ },
+ function(error) {
+ $log.error('PluginService.getPlugins failed: ' + JSON.stringify(error));
+ return $q.reject(error.statusText);
+ });
+ }
+
+ };
+});
diff --git a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/cloudify/plugin-table-controller.js b/ccsdk-app-overlay/src/main/webapp/app/ccsdk/cloudify/plugin-table-controller.js
new file mode 100644
index 0000000..23b59aa
--- /dev/null
+++ b/ccsdk-app-overlay/src/main/webapp/app/ccsdk/cloudify/plugin-table-controller.js
@@ -0,0 +1,64 @@
+appDS2.controller('PluginsTableController', function(
+ $rootScope, $scope, $log, $modal, modalService, PluginService) {
+
+ 'use strict';
+
+ // Controls logging in this controller
+ var debug = false;
+
+ // this object holds all app data and functions
+ $scope.ecdapp = {};
+ // models for controls on screen
+ $scope.ecdapp.tableData = [];
+ $scope.ecdapp.currentPageNum = 1;
+ $scope.ecdapp.viewPerPage = 10;
+ // other
+ $scope.ecdapp.errMsg = null;
+ $scope.ecdapp.isDataLoading = true;
+ $scope.ecdapp.isRequestFailed = false;
+
+ /**
+ * Loads the table. Interprets the remote controller's response and copies
+ * to scope variables. The response is either a list to be assigned to
+ * tableData, or an error to be shown.
+ */
+ $scope.ecdapp.loadTable = function() {
+ $scope.ecdapp.isDataLoading = true;
+ PluginService.getPlugins($scope.ecdapp.currentPageNum,
+ $scope.ecdapp.viewPerPage).then(
+ function(jsonObj) {
+ if (jsonObj.error) {
+ $log.error("PluginsTableController.loadTable failed: "
+ + jsonObj.error);
+ $scope.ecdapp.isRequestFailed = true;
+ $scope.ecdapp.errMsg = jsonObj.error;
+ $scope.ecdapp.tableData = [];
+ } else {
+ $scope.ecdapp.isRequestFailed = false;
+ $scope.ecdapp.errMsg = null;
+ $scope.ecdapp.tableData = jsonObj;
+ }
+ $scope.ecdapp.isDataLoading = false;
+ },
+ function(error) {
+ $log.error("PluginsTableController.loadTable failed: "
+ + error);
+ $scope.ecdapp.isRequestFailed = true;
+ $scope.ecdapp.errMsg = error;
+ $scope.ecdapp.tableData = [];
+ $scope.ecdapp.isDataLoading = false;
+ });
+ };
+
+ /**
+ * Invoked at first page load AND when
+ * user clicks on the B2B pagination control.
+ */
+ $scope.pageChangeHandler = function(page) {
+ if (debug)
+ console.log('pageChangeHandler: current is ' + $scope.ecdapp.currentPageNum + ' new is ' + page);
+ $scope.ecdapp.currentPageNum = page;
+ $scope.ecdapp.loadTable();
+ }
+
+});
diff --git a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/home/controller_table.html b/ccsdk-app-overlay/src/main/webapp/app/ccsdk/cloudify/plugin_table.html
index 965b701..99935b8 100644
--- a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/home/controller_table.html
+++ b/ccsdk-app-overlay/src/main/webapp/app/ccsdk/cloudify/plugin_table.html
@@ -1,7 +1,5 @@
<div id="page-content">
-
- <h1 class="heading-page" id="controllers">ECOMP-C Instances</h1>
-
+ <h1 class="heading-page" id="plugins-page">Cloudify Plugins</h1>
<!-- show progress indicator -->
<div ng-show="ecdapp.isDataLoading">
<div class="span" style="margin-bottom:20px;">
@@ -10,14 +8,13 @@
</div>
</div>
- <div ng-hide="ecdapp.isDataLoading">
-
+ <div ng-hide="ecdapp.isDataLoading">
<div id="button-search-row">
<div style="float:right;">
<div class="form-field form-field__small">
<input
type="text"
- placeholder="Search Controllers"
+ placeholder="Search Plugins"
ng-model="ecdapp.searchString"/>
</div>
</div>
@@ -27,53 +24,48 @@
<span class="ecd-error-message">{{ecdapp.errMsg}}</span>
</div>
- <div ng-hide="ecdapp.isRequestFailed">
-
+ <div ng-hide="ecdapp.isRequestFailed">
<div
b2b-table
- id="controllers-table"
+ id="plugins-table"
class="b2b-table-div"
table-data="ecdapp.tableData"
search-string="ecdapp.searchString"
current-page="ecdapp.currentPageIgnored"
next-sort="ecdapp.nextSortIgnored">
-
- <table>
-
+ <table>
<thead b2b-table-row type="header">
<tr id="th-header-row">
- <th b2b-table-header sortable="false">Selected</th>
- <th b2b-table-header key="name">Name</th>
- <th b2b-table-header key="url">URL</th>
+ <th b2b-table-header key="name">Package name</th>
+ <th b2b-table-header key="version">Package version</th>
+ <th b2b-table-header key="platform">Supported Platform</th>
+ <th b2b-table-header key="distribution">Distribution</th>
+ <th b2b-table-header key="uploaded_at">Uploaded at</th>
</tr>
</thead>
<tbody b2b-table-row type="body" row-repeat="rowData in ecdapp.tableData">
<tr id="tr-rowData">
- <td b2b-table-body>
- <label class="radio">
- <input
- type="radio"
- name="ecdSelGroup"
- title="rowData.url"
- ng-value="rowData.url"
- ng-model="ecdapp.radiobutton.url"
- ng-change="ecdapp.selectController(rowData);">
- <i class="skin"></i>
- <span></span>
- </label>
- </td>
<td b2b-table-body
- ng-bind="rowData.name"/>
+ ng-bind="rowData.package_name"/>
<td b2b-table-body
- ng-bind="rowData.url"/>
+ ng-bind="rowData.package_version"/>
+ <td b2b-table-body
+ ng-bind="rowData.supported_platform"/>
+ <td b2b-table-body
+ ng-bind="rowData.distribution"/>
+ <td b2b-table-body
+ ng-bind="rowData.uploaded_at"/>
</tr>
</tbody>
</table>
</div>
- <!-- no pagination -->
-
+ <div b2b-pagination="" total-pages="ecdapp.totalPages"
+ current-page="ecdapp.currentPageNum" click-handler="pageChangeHandler"
+ role="navigation">
+ </div>
+
</div>
<div style="height: 10px;">
diff --git a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/cloudify/tosca-table-controller.js b/ccsdk-app-overlay/src/main/webapp/app/ccsdk/cloudify/tosca-table-controller.js
deleted file mode 100644
index cafc517..0000000
--- a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/cloudify/tosca-table-controller.js
+++ /dev/null
@@ -1,106 +0,0 @@
-/*******************************************************************************
- * =============LICENSE_START=========================================================
- *
- * =================================================================================
- * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file 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.
- * ============LICENSE_END=========================================================
- *
- * ECOMP is a trademark and service mark of AT&T Intellectual Property.
- *******************************************************************************/
-appDS2.controller('toscaTableController', function(
- $rootScope, $scope, $log, $modal, modalService, ExecutionService) {
-
- 'use strict';
-
- // this object holds all app data and functions
- $scope.ecdapp = {};
- // models for controls on screen
- $scope.ecdapp.tableData = [];
- $scope.ecdapp.currentPageNum = 1;
- $scope.ecdapp.viewPerPage = 10;
- // other
- $scope.ecdapp.errMsg = null;
- $scope.ecdapp.isDataLoading = true;
- $scope.ecdapp.isRequestFailed = false;
-
- /**
- * Loads the table. Interprets the remote controller's response and copies
- * to scope variables. The response is either a list to be assigned to
- * tableData, or an error to be shown.
- */
- $scope.ecdapp.loadTable = function() {
- var toBeDefined = true;
- if (toBeDefined) {
- $scope.ecdapp.isDataLoading = false;
- $scope.ecdapp.isRequestFailed = true;
- $scope.ecdapp.errMsg = 'TOSCA Models not available (yet).';
- }
- else {
- $scope.ecdapp.isDataLoading = true;
- ExecutionService.getExecutions($scope.ecdapp.currentPageNum,
- $scope.ecdapp.viewPerPage).then(
- function(jsonObj) {
- if (jsonObj.error) {
- $log.error("executionController.loadTable failed: "
- + jsonObj.error);
- $scope.ecdapp.isRequestFailed = true;
- $scope.ecdapp.errMsg = jsonObj.error;
- $scope.ecdapp.tableData = [];
- } else {
- $scope.ecdapp.isRequestFailed = false;
- $scope.ecdapp.errMsg = null;
- $scope.ecdapp.totalPages = jsonObj.totalPages;
- $scope.ecdapp.tableData = jsonObj.items;
- }
- $scope.ecdapp.isDataLoading = false;
- },
- function(error) {
- $log.error("executionController.loadTable failed: "
- + error);
- $scope.ecdapp.isRequestFailed = true;
- $scope.ecdapp.errMsg = error;
- $scope.ecdapp.tableData = [];
- $scope.ecdapp.isDataLoading = false;
- });
- }
- };
-
- /**
- * Invoked at first page load AND when
- * user clicks on the B2B pagination control.
- */
- $scope.pageChangeHandler = function(page) {
- // console.log('pageChangeHandler: current is ' + $scope.ecdapp.currentPageNum + ' new is ' + page);
- $scope.ecdapp.currentPageNum = page;
- $scope.ecdapp.loadTable();
- }
-
- /**
- * Shows a modal pop-up to confirm deletion.
- * On successful completion, updates the table.
- */
- $scope.ecdapp.deleteToscaModalPopup = function(execution) {
- modalService.popupConfirmWin("Confirm", "Delete TOSCA model with ID '"
- + execution.id + "'?", function() {
- // TODO: gather action from user
- })
- };
-
- // Populate the table on load. Note that the b2b selector code
- // sets the page-number value, and the change event calls load table.
- // Do not call this here to avoid double load:
- // $scope.ecdapp.loadTable();
-
-});
diff --git a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/cloudify/tosca_table.html b/ccsdk-app-overlay/src/main/webapp/app/ccsdk/cloudify/tosca_table.html
deleted file mode 100644
index affec91..0000000
--- a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/cloudify/tosca_table.html
+++ /dev/null
@@ -1,87 +0,0 @@
-<div id="page-content">
-
- <h1 class="heading-page" id="blueprints-page">TOSCA Models</h1>
-
- <!-- show progress indicator -->
- <div ng-show="ecdapp.isDataLoading">
- <div class="span" style="margin-bottom:20px;">
- <i class="icon-primary-spinner small" role="img" aria-label="Please wait while the content loads"></i>
- Please wait while the content loads.
- </div>
- </div>
-
- <div ng-hide="ecdapp.isDataLoading">
-
- <div id="button-search-row">
- <div style="float:right;">
- <div class="form-field form-field__small">
- <input
- type="text"
- placeholder="Search TOSCA Models"
- ng-model="ecdapp.searchString"/>
- </div>
- </div>
- </div>
-
- <div ng-show="ecdapp.isRequestFailed">
- <span class="ecd-error-message">{{ecdapp.errMsg}}</span>
- </div>
-
- <div ng-hide="ecdapp.isRequestFailed">
-
- <div
- b2b-table
- id="tosca-table"
- class="b2b-table-div"
- table-data="ecdapp.tableData"
- search-string="ecdapp.searchString"
- current-page="ecdapp.currentPageIgnored"
- next-sort="ecdapp.nextSortIgnored">
-
- <table>
-
- <thead b2b-table-row type="header">
- <tr id="th-header-row">
- <th b2b-table-header key="id">ID</th>
- <th b2b-table-header key="name">Name</th>
- <th b2b-table-header key="description">Description</th>
- <th b2b-table-header key="created_at">Created Date</th>
- <th b2b-table-header key="updated_at">Updated Date</th>
- <th b2b-table-header sortable="false"><i class="icon-controls-gear ecd-icon-display"></i></th>
- </tr>
- </thead>
-
- <tbody b2b-table-row type="body" row-repeat="rowData in ecdapp.tableData">
- <tr id="tr-rowData">
- <td b2b-table-body
- ng-bind="rowData.id"/>
- <td b2b-table-body
- ng-bind="rowData.main_file_name"/>
- <td b2b-table-body
- ng-bind="rowData.description"/>
- <td b2b-table-body
- ng-bind="rowData.created_at"/>
- <td b2b-table-body
- ng-bind="rowData.updated_at"/>
- <td b2b-table-body>
- <div ng-click="ecdapp.deleteToscaModalPopup(rowData);">
- <a href="" title="Delete TOSCA model" class="icon-misc-trash ecd-icon-action"></a>
- </div>
- </td>
- </tr>
- </tbody>
- </table>
- </div>
-
- <div b2b-pagination="" total-pages="ecdapp.totalPages"
- current-page="ecdapp.currentPageNum" click-handler="pageChangeHandler"
- role="navigation">
- </div>
-
- <div style="height: 10px;">
- <!-- space between page number and black footer -->
- </div>
-
- </div><!-- loading -->
-
-</div><!-- page content -->
diff --git a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/consul/node_table.html b/ccsdk-app-overlay/src/main/webapp/app/ccsdk/consul/node_table.html
index 670fa6a..5471dbd 100644
--- a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/consul/node_table.html
+++ b/ccsdk-app-overlay/src/main/webapp/app/ccsdk/consul/node_table.html
@@ -47,7 +47,7 @@
<th b2b-table-header key="node">Node Name</th>
<th b2b-table-header key="id">Node ID</th>
<th b2b-table-header key="address">Address</th>
- <th b2b-table-header sortable="false"><i class="icon-settings ecd-icon-display"></i></th>
+ <th b2b-table-header sortable="false"><i class="icon-controls-gear ecd-icon-display"></i></th>
</tr>
</thead>
@@ -59,7 +59,7 @@
<td b2b-table-body ng-bind="rowData.address" />
<td b2b-table-body>
<div ng-click="ecdapp.viewServicesModalPopup(rowData, ecdapp.datacenter);">
- <a href="" title="View node services" class="icon-overview ecd-icon-action"></a>
+ <a href="" title="View node services" class="icon-people-preview ecd-icon-action"></a>
</div>
</td>
</tr>
diff --git a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/consul/service_health_table.html b/ccsdk-app-overlay/src/main/webapp/app/ccsdk/consul/service_health_table.html
index 40e8d95..56a7345 100644
--- a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/consul/service_health_table.html
+++ b/ccsdk-app-overlay/src/main/webapp/app/ccsdk/consul/service_health_table.html
@@ -50,9 +50,10 @@
<th b2b-table-header key="status">Status</th>
<th b2b-table-header key="node">Node Name</th>
<th b2b-table-header key="serviceID">Service ID</th>
+ <th b2b-table-header key="serviceID">Tenant</th>
<th b2b-table-header key="notes">Notes</th>
<th b2b-table-header key="output">Output</th>
- <th b2b-table-header sortable="false"><i class="icon-settings ecd-icon-display"></i></th>
+ <th b2b-table-header sortable="false"><i class="icon-controls-gear ecd-icon-display"></i></th>
</tr>
</thead>
@@ -69,11 +70,12 @@
</td>
<td b2b-table-body ng-bind="rowData.node" />
<td b2b-table-body ng-bind="rowData.serviceID" />
+ <td b2b-table-body ng-bind="rowData.tenant" />
<td b2b-table-body ng-bind="rowData.notes" />
<td b2b-table-body ng-bind="rowData.output" />
<td b2b-table-body>
<div ng-click="ecdapp.viewHealthHistoryModalPopup(rowData);">
- <a href="" title="View history" class="icoDocuments-bookmarks ecd-icon-action"></a>
+ <a href="" title="View history" class="icon-datanetwork-history ecd-icon-action"></a>
</div>
<div ng-click="ecdapp.deregisterServiceModalPopup(rowData);">
<a href="" title="Deregister service" class="icon-misc-trash ecd-icon-action"></a>
diff --git a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/external/angular-local-storage.js b/ccsdk-app-overlay/src/main/webapp/app/ccsdk/external/angular-local-storage.js
new file mode 100644
index 0000000..a936f14
--- /dev/null
+++ b/ccsdk-app-overlay/src/main/webapp/app/ccsdk/external/angular-local-storage.js
@@ -0,0 +1,592 @@
+/**
+ * An Angular module that gives you access to the browsers local storage
+ * @version v0.7.1 - 2017-06-21
+ * @link https://github.com/grevory/angular-local-storage
+ * @author grevory <greg@gregpike.ca>
+ * @license MIT License, http://www.opensource.org/licenses/MIT
+ */
+(function (window, angular) {
+var isDefined = angular.isDefined,
+ isUndefined = angular.isUndefined,
+ isNumber = angular.isNumber,
+ isObject = angular.isObject,
+ isArray = angular.isArray,
+ isString = angular.isString,
+ extend = angular.extend,
+ toJson = angular.toJson;
+
+angular
+ .module('LocalStorageModule', [])
+ .provider('localStorageService', function() {
+ // You should set a prefix to avoid overwriting any local storage variables from the rest of your app
+ // e.g. localStorageServiceProvider.setPrefix('yourAppName');
+ // With provider you can use config as this:
+ // myApp.config(function (localStorageServiceProvider) {
+ // localStorageServiceProvider.prefix = 'yourAppName';
+ // });
+ this.prefix = 'ls';
+
+ // You could change web storage type localstorage or sessionStorage
+ this.storageType = 'localStorage';
+
+ // Cookie options (usually in case of fallback)
+ // expiry = Number of days before cookies expire // 0 = Does not expire
+ // path = The web path the cookie represents
+ // secure = Wether the cookies should be secure (i.e only sent on HTTPS requests)
+ this.cookie = {
+ expiry: 30,
+ path: '/',
+ secure: false
+ };
+
+ // Decides wether we should default to cookies if localstorage is not supported.
+ this.defaultToCookie = true;
+
+ // Send signals for each of the following actions?
+ this.notify = {
+ setItem: true,
+ removeItem: false
+ };
+
+ // Setter for the prefix
+ this.setPrefix = function(prefix) {
+ this.prefix = prefix;
+ return this;
+ };
+
+ // Setter for the storageType
+ this.setStorageType = function(storageType) {
+ this.storageType = storageType;
+ return this;
+ };
+ // Setter for defaultToCookie value, default is true.
+ this.setDefaultToCookie = function (shouldDefault) {
+ this.defaultToCookie = !!shouldDefault; // Double-not to make sure it's a bool value.
+ return this;
+ };
+ // Setter for cookie config
+ this.setStorageCookie = function(exp, path, secure) {
+ this.cookie.expiry = exp;
+ this.cookie.path = path;
+ this.cookie.secure = secure;
+ return this;
+ };
+
+ // Setter for cookie domain
+ this.setStorageCookieDomain = function(domain) {
+ this.cookie.domain = domain;
+ return this;
+ };
+
+ // Setter for notification config
+ // itemSet & itemRemove should be booleans
+ this.setNotify = function(itemSet, itemRemove) {
+ this.notify = {
+ setItem: itemSet,
+ removeItem: itemRemove
+ };
+ return this;
+ };
+
+ this.$get = ['$rootScope', '$window', '$document', '$parse','$timeout', function($rootScope, $window, $document, $parse, $timeout) {
+ var self = this;
+ var prefix = self.prefix;
+ var cookie = self.cookie;
+ var notify = self.notify;
+ var storageType = self.storageType;
+ var webStorage;
+
+ // When Angular's $document is not available
+ if (!$document) {
+ $document = document;
+ } else if ($document[0]) {
+ $document = $document[0];
+ }
+
+ // If there is a prefix set in the config lets use that with an appended period for readability
+ if (prefix.substr(-1) !== '.') {
+ prefix = !!prefix ? prefix + '.' : '';
+ }
+ var deriveQualifiedKey = function(key) {
+ return prefix + key;
+ };
+
+ // Removes prefix from the key.
+ var underiveQualifiedKey = function (key) {
+ return key.replace(new RegExp('^' + prefix, 'g'), '');
+ };
+
+ // Check if the key is within our prefix namespace.
+ var isKeyPrefixOurs = function (key) {
+ return key.indexOf(prefix) === 0;
+ };
+
+ // Checks the browser to see if local storage is supported
+ var checkSupport = function () {
+ try {
+ var supported = (storageType in $window && $window[storageType] !== null);
+
+ // When Safari (OS X or iOS) is in private browsing mode, it appears as though localStorage
+ // is available, but trying to call .setItem throws an exception.
+ //
+ // "QUOTA_EXCEEDED_ERR: DOM Exception 22: An attempt was made to add something to storage
+ // that exceeded the quota."
+ var key = deriveQualifiedKey('__' + Math.round(Math.random() * 1e7));
+ if (supported) {
+ webStorage = $window[storageType];
+ webStorage.setItem(key, '');
+ webStorage.removeItem(key);
+ }
+
+ return supported;
+ } catch (e) {
+ // Only change storageType to cookies if defaulting is enabled.
+ if (self.defaultToCookie)
+ storageType = 'cookie';
+ $rootScope.$broadcast('LocalStorageModule.notification.error', e.message);
+ return false;
+ }
+ };
+ var browserSupportsLocalStorage = checkSupport();
+
+ // Directly adds a value to local storage
+ // If local storage is not available in the browser use cookies
+ // Example use: localStorageService.add('library','angular');
+ var addToLocalStorage = function (key, value, type) {
+ var previousType = getStorageType();
+
+ try {
+ setStorageType(type);
+
+ // Let's convert undefined values to null to get the value consistent
+ if (isUndefined(value)) {
+ value = null;
+ } else {
+ value = toJson(value);
+ }
+
+ // If this browser does not support local storage use cookies
+ if (!browserSupportsLocalStorage && self.defaultToCookie || self.storageType === 'cookie') {
+ if (!browserSupportsLocalStorage) {
+ $rootScope.$broadcast('LocalStorageModule.notification.warning', 'LOCAL_STORAGE_NOT_SUPPORTED');
+ }
+
+ if (notify.setItem) {
+ $rootScope.$broadcast('LocalStorageModule.notification.setitem', {key: key, newvalue: value, storageType: 'cookie'});
+ }
+ return addToCookies(key, value);
+ }
+
+ try {
+ if (webStorage) {
+ webStorage.setItem(deriveQualifiedKey(key), value);
+ }
+ if (notify.setItem) {
+ $rootScope.$broadcast('LocalStorageModule.notification.setitem', {key: key, newvalue: value, storageType: self.storageType});
+ }
+ } catch (e) {
+ $rootScope.$broadcast('LocalStorageModule.notification.error', e.message);
+ return addToCookies(key, value);
+ }
+ return true;
+ } finally {
+ setStorageType(previousType);
+ }
+ };
+
+ // Directly get a value from local storage
+ // Example use: localStorageService.get('library'); // returns 'angular'
+ var getFromLocalStorage = function (key, type) {
+ var previousType = getStorageType();
+
+ try {
+ setStorageType(type);
+
+ if (!browserSupportsLocalStorage && self.defaultToCookie || self.storageType === 'cookie') {
+ if (!browserSupportsLocalStorage) {
+ $rootScope.$broadcast('LocalStorageModule.notification.warning', 'LOCAL_STORAGE_NOT_SUPPORTED');
+ }
+
+ return getFromCookies(key);
+ }
+
+ var item = webStorage ? webStorage.getItem(deriveQualifiedKey(key)) : null;
+ // angular.toJson will convert null to 'null', so a proper conversion is needed
+ // FIXME not a perfect solution, since a valid 'null' string can't be stored
+ if (!item || item === 'null') {
+ return null;
+ }
+
+ try {
+ return JSON.parse(item);
+ } catch (e) {
+ return item;
+ }
+ } finally {
+ setStorageType(previousType);
+ }
+ };
+
+ // Remove an item from local storage
+ // Example use: localStorageService.remove('library'); // removes the key/value pair of library='angular'
+ //
+ // This is var-arg removal, check the last argument to see if it is a storageType
+ // and set type accordingly before removing.
+ //
+ var removeFromLocalStorage = function () {
+ var previousType = getStorageType();
+
+ try {
+ // can't pop on arguments, so we do this
+ var consumed = 0;
+ if (arguments.length >= 1 &&
+ (arguments[arguments.length - 1] === 'localStorage' ||
+ arguments[arguments.length - 1] === 'sessionStorage')) {
+ consumed = 1;
+ setStorageType(arguments[arguments.length - 1]);
+ }
+
+ var i, key;
+ for (i = 0; i < arguments.length - consumed; i++) {
+ key = arguments[i];
+ if (!browserSupportsLocalStorage && self.defaultToCookie || self.storageType === 'cookie') {
+ if (!browserSupportsLocalStorage) {
+ $rootScope.$broadcast('LocalStorageModule.notification.warning', 'LOCAL_STORAGE_NOT_SUPPORTED');
+ }
+
+ if (notify.removeItem) {
+ $rootScope.$broadcast('LocalStorageModule.notification.removeitem', {key: key, storageType: 'cookie'});
+ }
+ removeFromCookies(key);
+ }
+ else {
+ try {
+ webStorage.removeItem(deriveQualifiedKey(key));
+ if (notify.removeItem) {
+ $rootScope.$broadcast('LocalStorageModule.notification.removeitem', {
+ key: key,
+ storageType: self.storageType
+ });
+ }
+ } catch (e) {
+ $rootScope.$broadcast('LocalStorageModule.notification.error', e.message);
+ removeFromCookies(key);
+ }
+ }
+ }
+ } finally {
+ setStorageType(previousType);
+ }
+ };
+
+ // Return array of keys for local storage
+ // Example use: var keys = localStorageService.keys()
+ var getKeysForLocalStorage = function (type) {
+ var previousType = getStorageType();
+
+ try {
+ setStorageType(type);
+
+ if (!browserSupportsLocalStorage) {
+ $rootScope.$broadcast('LocalStorageModule.notification.warning', 'LOCAL_STORAGE_NOT_SUPPORTED');
+ return [];
+ }
+
+ var prefixLength = prefix.length;
+ var keys = [];
+ for (var key in webStorage) {
+ // Only return keys that are for this app
+ if (key.substr(0, prefixLength) === prefix) {
+ try {
+ keys.push(key.substr(prefixLength));
+ } catch (e) {
+ $rootScope.$broadcast('LocalStorageModule.notification.error', e.Description);
+ return [];
+ }
+ }
+ }
+
+ return keys;
+ } finally {
+ setStorageType(previousType);
+ }
+ };
+
+ // Remove all data for this app from local storage
+ // Also optionally takes a regular expression string and removes the matching key-value pairs
+ // Example use: localStorageService.clearAll();
+ // Should be used mostly for development purposes
+ var clearAllFromLocalStorage = function (regularExpression, type) {
+ var previousType = getStorageType();
+
+ try {
+ setStorageType(type);
+
+ // Setting both regular expressions independently
+ // Empty strings result in catchall RegExp
+ var prefixRegex = !!prefix ? new RegExp('^' + prefix) : new RegExp();
+ var testRegex = !!regularExpression ? new RegExp(regularExpression) : new RegExp();
+
+ if (!browserSupportsLocalStorage && self.defaultToCookie || self.storageType === 'cookie') {
+ if (!browserSupportsLocalStorage) {
+ $rootScope.$broadcast('LocalStorageModule.notification.warning', 'LOCAL_STORAGE_NOT_SUPPORTED');
+ }
+ return clearAllFromCookies();
+ }
+ if (!browserSupportsLocalStorage && !self.defaultToCookie)
+ return false;
+ var prefixLength = prefix.length;
+
+ for (var key in webStorage) {
+ // Only remove items that are for this app and match the regular expression
+ if (prefixRegex.test(key) && testRegex.test(key.substr(prefixLength))) {
+ try {
+ removeFromLocalStorage(key.substr(prefixLength));
+ } catch (e) {
+ $rootScope.$broadcast('LocalStorageModule.notification.error', e.message);
+ return clearAllFromCookies();
+ }
+ }
+ }
+
+ return true;
+ } finally {
+ setStorageType(previousType);
+ }
+ };
+
+ // Checks the browser to see if cookies are supported
+ var browserSupportsCookies = (function() {
+ try {
+ return $window.navigator.cookieEnabled ||
+ ("cookie" in $document && ($document.cookie.length > 0 ||
+ ($document.cookie = "test").indexOf.call($document.cookie, "test") > -1));
+ } catch (e) {
+ $rootScope.$broadcast('LocalStorageModule.notification.error', e.message);
+ return false;
+ }
+ }());
+
+ // Directly adds a value to cookies
+ // Typically used as a fallback if local storage is not available in the browser
+ // Example use: localStorageService.cookie.add('library','angular');
+ var addToCookies = function (key, value, daysToExpiry, secure) {
+
+ if (isUndefined(value)) {
+ return false;
+ } else if(isArray(value) || isObject(value)) {
+ value = toJson(value);
+ }
+
+ if (!browserSupportsCookies) {
+ $rootScope.$broadcast('LocalStorageModule.notification.error', 'COOKIES_NOT_SUPPORTED');
+ return false;
+ }
+
+ try {
+ var expiry = '',
+ expiryDate = new Date(),
+ cookieDomain = '';
+
+ if (value === null) {
+ // Mark that the cookie has expired one day ago
+ expiryDate.setTime(expiryDate.getTime() + (-1 * 24 * 60 * 60 * 1000));
+ expiry = "; expires=" + expiryDate.toGMTString();
+ value = '';
+ } else if (isNumber(daysToExpiry) && daysToExpiry !== 0) {
+ expiryDate.setTime(expiryDate.getTime() + (daysToExpiry * 24 * 60 * 60 * 1000));
+ expiry = "; expires=" + expiryDate.toGMTString();
+ } else if (cookie.expiry !== 0) {
+ expiryDate.setTime(expiryDate.getTime() + (cookie.expiry * 24 * 60 * 60 * 1000));
+ expiry = "; expires=" + expiryDate.toGMTString();
+ }
+ if (!!key) {
+ var cookiePath = "; path=" + cookie.path;
+ if (cookie.domain) {
+ cookieDomain = "; domain=" + cookie.domain;
+ }
+ /* Providing the secure parameter always takes precedence over config
+ * (allows developer to mix and match secure + non-secure) */
+ if (typeof secure === 'boolean') {
+ if (secure === true) {
+ /* We've explicitly specified secure,
+ * add the secure attribute to the cookie (after domain) */
+ cookieDomain += "; secure";
+ }
+ // else - secure has been supplied but isn't true - so don't set secure flag, regardless of what config says
+ }
+ else if (cookie.secure === true) {
+ // secure parameter wasn't specified, get default from config
+ cookieDomain += "; secure";
+ }
+ $document.cookie = deriveQualifiedKey(key) + "=" + encodeURIComponent(value) + expiry + cookiePath + cookieDomain;
+ }
+ } catch (e) {
+ $rootScope.$broadcast('LocalStorageModule.notification.error', e.message);
+ return false;
+ }
+ return true;
+ };
+
+ // Directly get a value from a cookie
+ // Example use: localStorageService.cookie.get('library'); // returns 'angular'
+ var getFromCookies = function (key) {
+ if (!browserSupportsCookies) {
+ $rootScope.$broadcast('LocalStorageModule.notification.error', 'COOKIES_NOT_SUPPORTED');
+ return false;
+ }
+
+ var cookies = $document.cookie && $document.cookie.split(';') || [];
+ for(var i=0; i < cookies.length; i++) {
+ var thisCookie = cookies[i];
+ while (thisCookie.charAt(0) === ' ') {
+ thisCookie = thisCookie.substring(1,thisCookie.length);
+ }
+ if (thisCookie.indexOf(deriveQualifiedKey(key) + '=') === 0) {
+ var storedValues = decodeURIComponent(thisCookie.substring(prefix.length + key.length + 1, thisCookie.length));
+ try {
+ var parsedValue = JSON.parse(storedValues);
+ return typeof(parsedValue) === 'number' ? storedValues : parsedValue;
+ } catch(e) {
+ return storedValues;
+ }
+ }
+ }
+ return null;
+ };
+
+ var removeFromCookies = function (key) {
+ addToCookies(key,null);
+ };
+
+ var clearAllFromCookies = function () {
+ var thisCookie = null;
+ var prefixLength = prefix.length;
+ var cookies = $document.cookie.split(';');
+ for(var i = 0; i < cookies.length; i++) {
+ thisCookie = cookies[i];
+
+ while (thisCookie.charAt(0) === ' ') {
+ thisCookie = thisCookie.substring(1, thisCookie.length);
+ }
+
+ var key = thisCookie.substring(prefixLength, thisCookie.indexOf('='));
+ removeFromCookies(key);
+ }
+ };
+
+ var getStorageType = function() {
+ return storageType;
+ };
+
+ var setStorageType = function(type) {
+ if (type && storageType !== type) {
+ storageType = type;
+ browserSupportsLocalStorage = checkSupport();
+ }
+ return browserSupportsLocalStorage;
+ };
+
+ // Add a listener on scope variable to save its changes to local storage
+ // Return a function which when called cancels binding
+ var bindToScope = function(scope, key, def, lsKey, type) {
+ lsKey = lsKey || key;
+ var value = getFromLocalStorage(lsKey, type);
+
+ if (value === null && isDefined(def)) {
+ value = def;
+ } else if (isObject(value) && isObject(def)) {
+ value = extend(value, def);
+ }
+
+ $parse(key).assign(scope, value);
+
+ return scope.$watch(key, function(newVal) {
+ addToLocalStorage(lsKey, newVal, type);
+ }, isObject(scope[key]));
+ };
+
+ // Add listener to local storage, for update callbacks.
+ if (browserSupportsLocalStorage) {
+ if ($window.addEventListener) {
+ $window.addEventListener("storage", handleStorageChangeCallback, false);
+ $rootScope.$on('$destroy', function() {
+ $window.removeEventListener("storage", handleStorageChangeCallback);
+ });
+ } else if($window.attachEvent){
+ // attachEvent and detachEvent are proprietary to IE v6-10
+ $window.attachEvent("onstorage", handleStorageChangeCallback);
+ $rootScope.$on('$destroy', function() {
+ $window.detachEvent("onstorage", handleStorageChangeCallback);
+ });
+ }
+ }
+
+ // Callback handler for storage changed.
+ function handleStorageChangeCallback(e) {
+ if (!e) { e = $window.event; }
+ if (notify.setItem) {
+ if (isString(e.key) && isKeyPrefixOurs(e.key)) {
+ var key = underiveQualifiedKey(e.key);
+ // Use timeout, to avoid using $rootScope.$apply.
+ $timeout(function () {
+ $rootScope.$broadcast('LocalStorageModule.notification.changed', { key: key, newvalue: e.newValue, storageType: self.storageType });
+ });
+ }
+ }
+ }
+
+ // Return localStorageService.length
+ // ignore keys that not owned
+ var lengthOfLocalStorage = function(type) {
+ var previousType = getStorageType();
+
+ try {
+ setStorageType(type);
+
+ var count = 0;
+ var storage = $window[storageType];
+ for(var i = 0; i < storage.length; i++) {
+ if(storage.key(i).indexOf(prefix) === 0 ) {
+ count++;
+ }
+ }
+
+ return count;
+ } finally {
+ setStorageType(previousType);
+ }
+ };
+
+ var changePrefix = function(localStoragePrefix) {
+ prefix = localStoragePrefix;
+ };
+
+ return {
+ isSupported: browserSupportsLocalStorage,
+ getStorageType: getStorageType,
+ setStorageType: setStorageType,
+ setPrefix: changePrefix,
+ set: addToLocalStorage,
+ add: addToLocalStorage, //DEPRECATED
+ get: getFromLocalStorage,
+ keys: getKeysForLocalStorage,
+ remove: removeFromLocalStorage,
+ clearAll: clearAllFromLocalStorage,
+ bind: bindToScope,
+ deriveKey: deriveQualifiedKey,
+ underiveKey: underiveQualifiedKey,
+ length: lengthOfLocalStorage,
+ defaultToCookie: this.defaultToCookie,
+ cookie: {
+ isSupported: browserSupportsCookies,
+ set: addToCookies,
+ add: addToCookies, //DEPRECATED
+ get: getFromCookies,
+ remove: removeFromCookies,
+ clearAll: clearAllFromCookies
+ }
+ };
+ }];
+ });
+})(window, window.angular); \ No newline at end of file
diff --git a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/external/select.css b/ccsdk-app-overlay/src/main/webapp/app/ccsdk/external/select.css
new file mode 100644
index 0000000..0e713bb
--- /dev/null
+++ b/ccsdk-app-overlay/src/main/webapp/app/ccsdk/external/select.css
@@ -0,0 +1,362 @@
+/*!
+ * ui-select
+ * http://github.com/angular-ui/ui-select
+ * Version: 0.19.7 - 2017-04-15T14:28:36.790Z
+ * License: MIT
+ */
+
+
+/* Style when highlighting a search. */
+.ui-select-highlight {
+ font-weight: bold;
+}
+
+.ui-select-offscreen {
+ clip: rect(0 0 0 0) !important;
+ width: 1px !important;
+ height: 1px !important;
+ border: 0 !important;
+ margin: 0 !important;
+ padding: 0 !important;
+ overflow: hidden !important;
+ position: absolute !important;
+ outline: 0 !important;
+ left: 0px !important;
+ top: 0px !important;
+}
+
+
+.ui-select-choices-row:hover {
+ background-color: #f5f5f5;
+}
+
+/* Select2 theme */
+
+/* Mark invalid Select2 */
+.ng-dirty.ng-invalid > a.select2-choice {
+ border-color: #D44950;
+}
+
+.select2-result-single {
+ padding-left: 0;
+}
+
+.select2-locked > .select2-search-choice-close{
+ display:none;
+}
+
+.select-locked > .ui-select-match-close{
+ display:none;
+}
+
+body > .select2-container.open {
+ z-index: 9999; /* The z-index Select2 applies to the select2-drop */
+}
+
+/* Handle up direction Select2 */
+.ui-select-container[theme="select2"].direction-up .ui-select-match,
+.ui-select-container.select2.direction-up .ui-select-match {
+ border-radius: 4px; /* FIXME hardcoded value :-/ */
+ border-top-left-radius: 0;
+ border-top-right-radius: 0;
+}
+.ui-select-container[theme="select2"].direction-up .ui-select-dropdown,
+.ui-select-container.select2.direction-up .ui-select-dropdown {
+ border-radius: 4px; /* FIXME hardcoded value :-/ */
+ border-bottom-left-radius: 0;
+ border-bottom-right-radius: 0;
+
+ border-top-width: 1px; /* FIXME hardcoded value :-/ */
+ border-top-style: solid;
+
+ box-shadow: 0 -4px 8px rgba(0, 0, 0, 0.25);
+
+ margin-top: -4px; /* FIXME hardcoded value :-/ */
+}
+.ui-select-container[theme="select2"].direction-up .ui-select-dropdown .select2-search,
+.ui-select-container.select2.direction-up .ui-select-dropdown .select2-search {
+ margin-top: 4px; /* FIXME hardcoded value :-/ */
+}
+.ui-select-container[theme="select2"].direction-up.select2-dropdown-open .ui-select-match,
+.ui-select-container.select2.direction-up.select2-dropdown-open .ui-select-match {
+ border-bottom-color: #5897fb;
+}
+
+.ui-select-container[theme="select2"] .ui-select-dropdown .ui-select-search-hidden,
+.ui-select-container[theme="select2"] .ui-select-dropdown .ui-select-search-hidden input{
+ opacity: 0;
+ height: 0;
+ min-height: 0;
+ padding: 0;
+ margin: 0;
+ border:0;
+}
+
+/* Selectize theme */
+
+/* Helper class to show styles when focus */
+.selectize-input.selectize-focus{
+ border-color: #007FBB !important;
+}
+
+/* Fix input width for Selectize theme */
+.selectize-control.single > .selectize-input > input {
+ width: 100%;
+}
+
+/* Fix line break when there's at least one item selected with the Selectize theme */
+.selectize-control.multi > .selectize-input > input {
+ margin: 0 !important;
+}
+
+/* Fix dropdown width for Selectize theme */
+.selectize-control > .selectize-dropdown {
+ width: 100%;
+}
+
+/* Mark invalid Selectize */
+.ng-dirty.ng-invalid > div.selectize-input {
+ border-color: #D44950;
+}
+
+/* Handle up direction Selectize */
+.ui-select-container[theme="selectize"].direction-up .ui-select-dropdown {
+ box-shadow: 0 -4px 8px rgba(0, 0, 0, 0.25);
+ margin-top: -2px; /* FIXME hardcoded value :-/ */
+}
+
+.ui-select-container[theme="selectize"] input.ui-select-search-hidden{
+ opacity: 0;
+ height: 0;
+ min-height: 0;
+ padding: 0;
+ margin: 0;
+ border:0;
+ width: 0;
+}
+
+/* Bootstrap theme */
+
+/* Helper class to show styles when focus */
+.btn-default-focus {
+ color: #333;
+ background-color: #EBEBEB;
+ border-color: #ADADAD;
+ text-decoration: none;
+ outline: 5px auto -webkit-focus-ring-color;
+ outline-offset: -2px;
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6);
+}
+
+.ui-select-bootstrap .ui-select-toggle {
+ position: relative;
+}
+
+.ui-select-bootstrap .ui-select-toggle > .caret {
+ position: absolute;
+ height: 10px;
+ top: 50%;
+ right: 10px;
+ margin-top: -2px;
+}
+
+/* Fix Bootstrap dropdown position when inside a input-group */
+.input-group > .ui-select-bootstrap.dropdown {
+ /* Instead of relative */
+ position: static;
+}
+
+.input-group > .ui-select-bootstrap > input.ui-select-search.form-control {
+ border-radius: 4px; /* FIXME hardcoded value :-/ */
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+}
+.input-group > .ui-select-bootstrap > input.ui-select-search.form-control.direction-up {
+ border-radius: 4px !important; /* FIXME hardcoded value :-/ */
+ border-top-right-radius: 0 !important;
+ border-bottom-right-radius: 0 !important;
+}
+
+.ui-select-bootstrap .ui-select-search-hidden{
+ opacity: 0;
+ height: 0;
+ min-height: 0;
+ padding: 0;
+ margin: 0;
+ border:0;
+}
+
+.ui-select-bootstrap > .ui-select-match > .btn{
+ /* Instead of center because of .btn */
+ text-align: left !important;
+}
+
+.ui-select-bootstrap > .ui-select-match > .caret {
+ position: absolute;
+ top: 45%;
+ right: 15px;
+}
+
+/* See Scrollable Menu with Bootstrap 3 http://stackoverflow.com/questions/19227496 */
+.ui-select-bootstrap > .ui-select-choices ,.ui-select-bootstrap > .ui-select-no-choice {
+ width: 100%;
+ height: auto;
+ max-height: 200px;
+ overflow-x: hidden;
+ margin-top: -1px;
+}
+
+body > .ui-select-bootstrap.open {
+ z-index: 1000; /* Standard Bootstrap dropdown z-index */
+}
+
+.ui-select-multiple.ui-select-bootstrap {
+ height: auto;
+ padding: 3px 3px 0 3px;
+}
+
+.ui-select-multiple.ui-select-bootstrap input.ui-select-search {
+ background-color: transparent !important; /* To prevent double background when disabled */
+ border: none;
+ outline: none;
+ height: 1.666666em;
+ margin-bottom: 3px;
+}
+
+.ui-select-multiple.ui-select-bootstrap .ui-select-match .close {
+ font-size: 1.6em;
+ line-height: 0.75;
+}
+
+.ui-select-multiple.ui-select-bootstrap .ui-select-match-item {
+ outline: 0;
+ margin: 0 3px 3px 0;
+}
+
+.ui-select-multiple .ui-select-match-item {
+ position: relative;
+}
+
+.ui-select-multiple .ui-select-match-item.dropping .ui-select-match-close {
+ pointer-events: none;
+}
+
+.ui-select-multiple:hover .ui-select-match-item.dropping-before:before {
+ content: "";
+ position: absolute;
+ top: 0;
+ right: 100%;
+ height: 100%;
+ margin-right: 2px;
+ border-left: 1px solid #428bca;
+}
+
+.ui-select-multiple:hover .ui-select-match-item.dropping-after:after {
+ content: "";
+ position: absolute;
+ top: 0;
+ left: 100%;
+ height: 100%;
+ margin-left: 2px;
+ border-right: 1px solid #428bca;
+}
+
+.ui-select-bootstrap .ui-select-choices-row>span {
+ cursor: pointer;
+ display: block;
+ padding: 3px 20px;
+ clear: both;
+ font-weight: 400;
+ line-height: 1.42857143;
+ color: #333;
+ white-space: nowrap;
+}
+
+.ui-select-bootstrap .ui-select-choices-row>span:hover, .ui-select-bootstrap .ui-select-choices-row>span:focus {
+ text-decoration: none;
+ color: #262626;
+ background-color: #f5f5f5;
+}
+
+.ui-select-bootstrap .ui-select-choices-row.active>span {
+ color: #fff;
+ text-decoration: none;
+ outline: 0;
+ background-color: #428bca;
+}
+
+.ui-select-bootstrap .ui-select-choices-row.disabled>span,
+.ui-select-bootstrap .ui-select-choices-row.active.disabled>span {
+ color: #777;
+ cursor: not-allowed;
+ background-color: #fff;
+}
+
+/* fix hide/show angular animation */
+.ui-select-match.ng-hide-add,
+.ui-select-search.ng-hide-add {
+ display: none !important;
+}
+
+/* Mark invalid Bootstrap */
+.ui-select-bootstrap.ng-dirty.ng-invalid > button.btn.ui-select-match {
+ border-color: #D44950;
+}
+
+/* Handle up direction Bootstrap */
+.ui-select-container[theme="bootstrap"].direction-up .ui-select-dropdown {
+ box-shadow: 0 -4px 8px rgba(0, 0, 0, 0.25);
+}
+
+.ui-select-bootstrap .ui-select-match-text {
+ width: 100%;
+ padding-right: 1em;
+}
+.ui-select-bootstrap .ui-select-match-text span {
+ display: inline-block;
+ width: 100%;
+ overflow: hidden;
+}
+.ui-select-bootstrap .ui-select-toggle > a.btn {
+ position: absolute;
+ height: 10px;
+ right: 10px;
+ margin-top: -2px;
+}
+
+/* Spinner */
+.ui-select-refreshing.glyphicon {
+ position: absolute;
+ right: 0;
+ padding: 8px 27px;
+ }
+
+@-webkit-keyframes ui-select-spin {
+ 0% {
+ -webkit-transform: rotate(0deg);
+ transform: rotate(0deg);
+ }
+ 100% {
+ -webkit-transform: rotate(359deg);
+ transform: rotate(359deg);
+ }
+}
+@keyframes ui-select-spin {
+ 0% {
+ -webkit-transform: rotate(0deg);
+ transform: rotate(0deg);
+ }
+ 100% {
+ -webkit-transform: rotate(359deg);
+ transform: rotate(359deg);
+ }
+}
+
+.ui-select-spin {
+ -webkit-animation: ui-select-spin 2s infinite linear;
+ animation: ui-select-spin 2s infinite linear;
+}
+
+.ui-select-refreshing.ng-animate {
+ -webkit-animation: none 0s;
+}
diff --git a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/external/select.js b/ccsdk-app-overlay/src/main/webapp/app/ccsdk/external/select.js
new file mode 100644
index 0000000..5ac4e0b
--- /dev/null
+++ b/ccsdk-app-overlay/src/main/webapp/app/ccsdk/external/select.js
@@ -0,0 +1,2427 @@
+/*!
+ * ui-select
+ * http://github.com/angular-ui/ui-select
+ * Version: 0.19.7 - 2017-04-15T14:28:36.649Z
+ * License: MIT
+ */
+
+
+(function () {
+"use strict";
+var KEY = {
+ TAB: 9,
+ ENTER: 13,
+ ESC: 27,
+ SPACE: 32,
+ LEFT: 37,
+ UP: 38,
+ RIGHT: 39,
+ DOWN: 40,
+ SHIFT: 16,
+ CTRL: 17,
+ ALT: 18,
+ PAGE_UP: 33,
+ PAGE_DOWN: 34,
+ HOME: 36,
+ END: 35,
+ BACKSPACE: 8,
+ DELETE: 46,
+ COMMAND: 91,
+
+ MAP: { 91 : "COMMAND", 8 : "BACKSPACE" , 9 : "TAB" , 13 : "ENTER" , 16 : "SHIFT" , 17 : "CTRL" , 18 : "ALT" , 19 : "PAUSEBREAK" , 20 : "CAPSLOCK" , 27 : "ESC" , 32 : "SPACE" , 33 : "PAGE_UP", 34 : "PAGE_DOWN" , 35 : "END" , 36 : "HOME" , 37 : "LEFT" , 38 : "UP" , 39 : "RIGHT" , 40 : "DOWN" , 43 : "+" , 44 : "PRINTSCREEN" , 45 : "INSERT" , 46 : "DELETE", 48 : "0" , 49 : "1" , 50 : "2" , 51 : "3" , 52 : "4" , 53 : "5" , 54 : "6" , 55 : "7" , 56 : "8" , 57 : "9" , 59 : ";", 61 : "=" , 65 : "A" , 66 : "B" , 67 : "C" , 68 : "D" , 69 : "E" , 70 : "F" , 71 : "G" , 72 : "H" , 73 : "I" , 74 : "J" , 75 : "K" , 76 : "L", 77 : "M" , 78 : "N" , 79 : "O" , 80 : "P" , 81 : "Q" , 82 : "R" , 83 : "S" , 84 : "T" , 85 : "U" , 86 : "V" , 87 : "W" , 88 : "X" , 89 : "Y" , 90 : "Z", 96 : "0" , 97 : "1" , 98 : "2" , 99 : "3" , 100 : "4" , 101 : "5" , 102 : "6" , 103 : "7" , 104 : "8" , 105 : "9", 106 : "*" , 107 : "+" , 109 : "-" , 110 : "." , 111 : "/", 112 : "F1" , 113 : "F2" , 114 : "F3" , 115 : "F4" , 116 : "F5" , 117 : "F6" , 118 : "F7" , 119 : "F8" , 120 : "F9" , 121 : "F10" , 122 : "F11" , 123 : "F12", 144 : "NUMLOCK" , 145 : "SCROLLLOCK" , 186 : ";" , 187 : "=" , 188 : "," , 189 : "-" , 190 : "." , 191 : "/" , 192 : "`" , 219 : "[" , 220 : "\\" , 221 : "]" , 222 : "'"
+ },
+
+ isControl: function (e) {
+ var k = e.which;
+ switch (k) {
+ case KEY.COMMAND:
+ case KEY.SHIFT:
+ case KEY.CTRL:
+ case KEY.ALT:
+ return true;
+ }
+
+ if (e.metaKey || e.ctrlKey || e.altKey) return true;
+
+ return false;
+ },
+ isFunctionKey: function (k) {
+ k = k.which ? k.which : k;
+ return k >= 112 && k <= 123;
+ },
+ isVerticalMovement: function (k){
+ return ~[KEY.UP, KEY.DOWN].indexOf(k);
+ },
+ isHorizontalMovement: function (k){
+ return ~[KEY.LEFT,KEY.RIGHT,KEY.BACKSPACE,KEY.DELETE].indexOf(k);
+ },
+ toSeparator: function (k) {
+ var sep = {ENTER:"\n",TAB:"\t",SPACE:" "}[k];
+ if (sep) return sep;
+ // return undefined for special keys other than enter, tab or space.
+ // no way to use them to cut strings.
+ return KEY[k] ? undefined : k;
+ }
+ };
+
+function isNil(value) {
+ return angular.isUndefined(value) || value === null;
+}
+
+/**
+ * Add querySelectorAll() to jqLite.
+ *
+ * jqLite find() is limited to lookups by tag name.
+ * TODO This will change with future versions of AngularJS, to be removed when this happens
+ *
+ * See jqLite.find - why not use querySelectorAll? https://github.com/angular/angular.js/issues/3586
+ * See feat(jqLite): use querySelectorAll instead of getElementsByTagName in jqLite.find https://github.com/angular/angular.js/pull/3598
+ */
+if (angular.element.prototype.querySelectorAll === undefined) {
+ angular.element.prototype.querySelectorAll = function(selector) {
+ return angular.element(this[0].querySelectorAll(selector));
+ };
+}
+
+/**
+ * Add closest() to jqLite.
+ */
+if (angular.element.prototype.closest === undefined) {
+ angular.element.prototype.closest = function( selector) {
+ var elem = this[0];
+ var matchesSelector = elem.matches || elem.webkitMatchesSelector || elem.mozMatchesSelector || elem.msMatchesSelector;
+
+ while (elem) {
+ if (matchesSelector.bind(elem)(selector)) {
+ return elem;
+ } else {
+ elem = elem.parentElement;
+ }
+ }
+ return false;
+ };
+}
+
+var latestId = 0;
+
+var uis = angular.module('ui.select', [])
+
+.constant('uiSelectConfig', {
+ theme: 'bootstrap',
+ searchEnabled: true,
+ sortable: false,
+ placeholder: '', // Empty by default, like HTML tag <select>
+ refreshDelay: 1000, // In milliseconds
+ closeOnSelect: true,
+ skipFocusser: false,
+ dropdownPosition: 'auto',
+ removeSelected: true,
+ resetSearchInput: true,
+ generateId: function() {
+ return latestId++;
+ },
+ appendToBody: false,
+ spinnerEnabled: false,
+ spinnerClass: 'glyphicon glyphicon-refresh ui-select-spin',
+ backspaceReset: true
+})
+
+// See Rename minErr and make it accessible from outside https://github.com/angular/angular.js/issues/6913
+.service('uiSelectMinErr', function() {
+ var minErr = angular.$$minErr('ui.select');
+ return function() {
+ var error = minErr.apply(this, arguments);
+ var message = error.message.replace(new RegExp('\nhttp://errors.angularjs.org/.*'), '');
+ return new Error(message);
+ };
+})
+
+// Recreates old behavior of ng-transclude. Used internally.
+.directive('uisTranscludeAppend', function () {
+ return {
+ link: function (scope, element, attrs, ctrl, transclude) {
+ transclude(scope, function (clone) {
+ element.append(clone);
+ });
+ }
+ };
+})
+
+/**
+ * Highlights text that matches $select.search.
+ *
+ * Taken from AngularUI Bootstrap Typeahead
+ * See https://github.com/angular-ui/bootstrap/blob/0.10.0/src/typeahead/typeahead.js#L340
+ */
+.filter('highlight', function() {
+ function escapeRegexp(queryToEscape) {
+ return ('' + queryToEscape).replace(/([.?*+^$[\]\\(){}|-])/g, '\\$1');
+ }
+
+ return function(matchItem, query) {
+ return query && matchItem ? ('' + matchItem).replace(new RegExp(escapeRegexp(query), 'gi'), '<span class="ui-select-highlight">$&</span>') : matchItem;
+ };
+})
+
+/**
+ * A read-only equivalent of jQuery's offset function: http://api.jquery.com/offset/
+ *
+ * Taken from AngularUI Bootstrap Position:
+ * See https://github.com/angular-ui/bootstrap/blob/master/src/position/position.js#L70
+ */
+.factory('uisOffset',
+ ['$document', '$window',
+ function ($document, $window) {
+
+ return function(element) {
+ var boundingClientRect = element[0].getBoundingClientRect();
+ return {
+ width: boundingClientRect.width || element.prop('offsetWidth'),
+ height: boundingClientRect.height || element.prop('offsetHeight'),
+ top: boundingClientRect.top + ($window.pageYOffset || $document[0].documentElement.scrollTop),
+ left: boundingClientRect.left + ($window.pageXOffset || $document[0].documentElement.scrollLeft)
+ };
+ };
+}]);
+
+/**
+ * Debounces functions
+ *
+ * Taken from UI Bootstrap $$debounce source code
+ * See https://github.com/angular-ui/bootstrap/blob/master/src/debounce/debounce.js
+ *
+ */
+uis.factory('$$uisDebounce', ['$timeout', function($timeout) {
+ return function(callback, debounceTime) {
+ var timeoutPromise;
+
+ return function() {
+ var self = this;
+ var args = Array.prototype.slice.call(arguments);
+ if (timeoutPromise) {
+ $timeout.cancel(timeoutPromise);
+ }
+
+ timeoutPromise = $timeout(function() {
+ callback.apply(self, args);
+ }, debounceTime);
+ };
+ };
+}]);
+
+uis.directive('uiSelectChoices',
+ ['uiSelectConfig', 'uisRepeatParser', 'uiSelectMinErr', '$compile', '$window',
+ function(uiSelectConfig, RepeatParser, uiSelectMinErr, $compile, $window) {
+
+ return {
+ restrict: 'EA',
+ require: '^uiSelect',
+ replace: true,
+ transclude: true,
+ templateUrl: function(tElement) {
+ // Needed so the uiSelect can detect the transcluded content
+ tElement.addClass('ui-select-choices');
+
+ // Gets theme attribute from parent (ui-select)
+ var theme = tElement.parent().attr('theme') || uiSelectConfig.theme;
+ return theme + '/choices.tpl.html';
+ },
+
+ compile: function(tElement, tAttrs) {
+
+ if (!tAttrs.repeat) throw uiSelectMinErr('repeat', "Expected 'repeat' expression.");
+
+ // var repeat = RepeatParser.parse(attrs.repeat);
+ var groupByExp = tAttrs.groupBy;
+ var groupFilterExp = tAttrs.groupFilter;
+
+ if (groupByExp) {
+ var groups = tElement.querySelectorAll('.ui-select-choices-group');
+ if (groups.length !== 1) throw uiSelectMinErr('rows', "Expected 1 .ui-select-choices-group but got '{0}'.", groups.length);
+ groups.attr('ng-repeat', RepeatParser.getGroupNgRepeatExpression());
+ }
+
+ var parserResult = RepeatParser.parse(tAttrs.repeat);
+
+ var choices = tElement.querySelectorAll('.ui-select-choices-row');
+ if (choices.length !== 1) {
+ throw uiSelectMinErr('rows', "Expected 1 .ui-select-choices-row but got '{0}'.", choices.length);
+ }
+
+ choices.attr('ng-repeat', parserResult.repeatExpression(groupByExp))
+ .attr('ng-if', '$select.open'); //Prevent unnecessary watches when dropdown is closed
+
+
+ var rowsInner = tElement.querySelectorAll('.ui-select-choices-row-inner');
+ if (rowsInner.length !== 1) {
+ throw uiSelectMinErr('rows', "Expected 1 .ui-select-choices-row-inner but got '{0}'.", rowsInner.length);
+ }
+ rowsInner.attr('uis-transclude-append', ''); //Adding uisTranscludeAppend directive to row element after choices element has ngRepeat
+
+ // If IE8 then need to target rowsInner to apply the ng-click attr as choices will not capture the event.
+ var clickTarget = $window.document.addEventListener ? choices : rowsInner;
+ clickTarget.attr('ng-click', '$select.select(' + parserResult.itemName + ',$select.skipFocusser,$event)');
+
+ return function link(scope, element, attrs, $select) {
+
+
+ $select.parseRepeatAttr(attrs.repeat, groupByExp, groupFilterExp); //Result ready at $select.parserResult
+ $select.disableChoiceExpression = attrs.uiDisableChoice;
+ $select.onHighlightCallback = attrs.onHighlight;
+ $select.minimumInputLength = parseInt(attrs.minimumInputLength) || 0;
+ $select.dropdownPosition = attrs.position ? attrs.position.toLowerCase() : uiSelectConfig.dropdownPosition;
+
+ scope.$watch('$select.search', function(newValue) {
+ if(newValue && !$select.open && $select.multiple) $select.activate(false, true);
+ $select.activeIndex = $select.tagging.isActivated ? -1 : 0;
+ if (!attrs.minimumInputLength || $select.search.length >= attrs.minimumInputLength) {
+ $select.refresh(attrs.refresh);
+ } else {
+ $select.items = [];
+ }
+ });
+
+ attrs.$observe('refreshDelay', function() {
+ // $eval() is needed otherwise we get a string instead of a number
+ var refreshDelay = scope.$eval(attrs.refreshDelay);
+ $select.refreshDelay = refreshDelay !== undefined ? refreshDelay : uiSelectConfig.refreshDelay;
+ });
+
+ scope.$watch('$select.open', function(open) {
+ if (open) {
+ tElement.attr('role', 'listbox');
+ $select.refresh(attrs.refresh);
+ } else {
+ element.removeAttr('role');
+ }
+ });
+ };
+ }
+ };
+}]);
+
+/**
+ * Contains ui-select "intelligence".
+ *
+ * The goal is to limit dependency on the DOM whenever possible and
+ * put as much logic in the controller (instead of the link functions) as possible so it can be easily tested.
+ */
+uis.controller('uiSelectCtrl',
+ ['$scope', '$element', '$timeout', '$filter', '$$uisDebounce', 'uisRepeatParser', 'uiSelectMinErr', 'uiSelectConfig', '$parse', '$injector', '$window',
+ function($scope, $element, $timeout, $filter, $$uisDebounce, RepeatParser, uiSelectMinErr, uiSelectConfig, $parse, $injector, $window) {
+
+ var ctrl = this;
+
+ var EMPTY_SEARCH = '';
+
+ ctrl.placeholder = uiSelectConfig.placeholder;
+ ctrl.searchEnabled = uiSelectConfig.searchEnabled;
+ ctrl.sortable = uiSelectConfig.sortable;
+ ctrl.refreshDelay = uiSelectConfig.refreshDelay;
+ ctrl.paste = uiSelectConfig.paste;
+ ctrl.resetSearchInput = uiSelectConfig.resetSearchInput;
+ ctrl.refreshing = false;
+ ctrl.spinnerEnabled = uiSelectConfig.spinnerEnabled;
+ ctrl.spinnerClass = uiSelectConfig.spinnerClass;
+ ctrl.removeSelected = uiSelectConfig.removeSelected; //If selected item(s) should be removed from dropdown list
+ ctrl.closeOnSelect = true; //Initialized inside uiSelect directive link function
+ ctrl.skipFocusser = false; //Set to true to avoid returning focus to ctrl when item is selected
+ ctrl.search = EMPTY_SEARCH;
+
+ ctrl.activeIndex = 0; //Dropdown of choices
+ ctrl.items = []; //All available choices
+
+ ctrl.open = false;
+ ctrl.focus = false;
+ ctrl.disabled = false;
+ ctrl.selected = undefined;
+
+ ctrl.dropdownPosition = 'auto';
+
+ ctrl.focusser = undefined; //Reference to input element used to handle focus events
+ ctrl.multiple = undefined; // Initialized inside uiSelect directive link function
+ ctrl.disableChoiceExpression = undefined; // Initialized inside uiSelectChoices directive link function
+ ctrl.tagging = {isActivated: false, fct: undefined};
+ ctrl.taggingTokens = {isActivated: false, tokens: undefined};
+ ctrl.lockChoiceExpression = undefined; // Initialized inside uiSelectMatch directive link function
+ ctrl.clickTriggeredSelect = false;
+ ctrl.$filter = $filter;
+ ctrl.$element = $element;
+
+ // Use $injector to check for $animate and store a reference to it
+ ctrl.$animate = (function () {
+ try {
+ return $injector.get('$animate');
+ } catch (err) {
+ // $animate does not exist
+ return null;
+ }
+ })();
+
+ ctrl.searchInput = $element.querySelectorAll('input.ui-select-search');
+ if (ctrl.searchInput.length !== 1) {
+ throw uiSelectMinErr('searchInput', "Expected 1 input.ui-select-search but got '{0}'.", ctrl.searchInput.length);
+ }
+
+ ctrl.isEmpty = function() {
+ return isNil(ctrl.selected) || ctrl.selected === '' || (ctrl.multiple && ctrl.selected.length === 0);
+ };
+
+ function _findIndex(collection, predicate, thisArg){
+ if (collection.findIndex){
+ return collection.findIndex(predicate, thisArg);
+ } else {
+ var list = Object(collection);
+ var length = list.length >>> 0;
+ var value;
+
+ for (var i = 0; i < length; i++) {
+ value = list[i];
+ if (predicate.call(thisArg, value, i, list)) {
+ return i;
+ }
+ }
+ return -1;
+ }
+ }
+
+ // Most of the time the user does not want to empty the search input when in typeahead mode
+ function _resetSearchInput() {
+ if (ctrl.resetSearchInput) {
+ ctrl.search = EMPTY_SEARCH;
+ //reset activeIndex
+ if (ctrl.selected && ctrl.items.length && !ctrl.multiple) {
+ ctrl.activeIndex = _findIndex(ctrl.items, function(item){
+ return angular.equals(this, item);
+ }, ctrl.selected);
+ }
+ }
+ }
+
+ function _groupsFilter(groups, groupNames) {
+ var i, j, result = [];
+ for(i = 0; i < groupNames.length ;i++){
+ for(j = 0; j < groups.length ;j++){
+ if(groups[j].name == [groupNames[i]]){
+ result.push(groups[j]);
+ }
+ }
+ }
+ return result;
+ }
+
+ // When the user clicks on ui-select, displays the dropdown list
+ ctrl.activate = function(initSearchValue, avoidReset) {
+ if (!ctrl.disabled && !ctrl.open) {
+ if(!avoidReset) _resetSearchInput();
+
+ $scope.$broadcast('uis:activate');
+ ctrl.open = true;
+ ctrl.activeIndex = ctrl.activeIndex >= ctrl.items.length ? 0 : ctrl.activeIndex;
+ // ensure that the index is set to zero for tagging variants
+ // that where first option is auto-selected
+ if ( ctrl.activeIndex === -1 && ctrl.taggingLabel !== false ) {
+ ctrl.activeIndex = 0;
+ }
+
+ var container = $element.querySelectorAll('.ui-select-choices-content');
+ var searchInput = $element.querySelectorAll('.ui-select-search');
+ if (ctrl.$animate && ctrl.$animate.on && ctrl.$animate.enabled(container[0])) {
+ var animateHandler = function(elem, phase) {
+ if (phase === 'start' && ctrl.items.length === 0) {
+ // Only focus input after the animation has finished
+ ctrl.$animate.off('removeClass', searchInput[0], animateHandler);
+ $timeout(function () {
+ ctrl.focusSearchInput(initSearchValue);
+ });
+ } else if (phase === 'close') {
+ // Only focus input after the animation has finished
+ ctrl.$animate.off('enter', container[0], animateHandler);
+ $timeout(function () {
+ ctrl.focusSearchInput(initSearchValue);
+ });
+ }
+ };
+
+ if (ctrl.items.length > 0) {
+ ctrl.$animate.on('enter', container[0], animateHandler);
+ } else {
+ ctrl.$animate.on('removeClass', searchInput[0], animateHandler);
+ }
+ } else {
+ $timeout(function () {
+ ctrl.focusSearchInput(initSearchValue);
+ if(!ctrl.tagging.isActivated && ctrl.items.length > 1) {
+ _ensureHighlightVisible();
+ }
+ });
+ }
+ }
+ else if (ctrl.open && !ctrl.searchEnabled) {
+ // Close the selection if we don't have search enabled, and we click on the select again
+ ctrl.close();
+ }
+ };
+
+ ctrl.focusSearchInput = function (initSearchValue) {
+ ctrl.search = initSearchValue || ctrl.search;
+ ctrl.searchInput[0].focus();
+ };
+
+ ctrl.findGroupByName = function(name) {
+ return ctrl.groups && ctrl.groups.filter(function(group) {
+ return group.name === name;
+ })[0];
+ };
+
+ ctrl.parseRepeatAttr = function(repeatAttr, groupByExp, groupFilterExp) {
+ function updateGroups(items) {
+ var groupFn = $scope.$eval(groupByExp);
+ ctrl.groups = [];
+ angular.forEach(items, function(item) {
+ var groupName = angular.isFunction(groupFn) ? groupFn(item) : item[groupFn];
+ var group = ctrl.findGroupByName(groupName);
+ if(group) {
+ group.items.push(item);
+ }
+ else {
+ ctrl.groups.push({name: groupName, items: [item]});
+ }
+ });
+ if(groupFilterExp){
+ var groupFilterFn = $scope.$eval(groupFilterExp);
+ if( angular.isFunction(groupFilterFn)){
+ ctrl.groups = groupFilterFn(ctrl.groups);
+ } else if(angular.isArray(groupFilterFn)){
+ ctrl.groups = _groupsFilter(ctrl.groups, groupFilterFn);
+ }
+ }
+ ctrl.items = [];
+ ctrl.groups.forEach(function(group) {
+ ctrl.items = ctrl.items.concat(group.items);
+ });
+ }
+
+ function setPlainItems(items) {
+ ctrl.items = items || [];
+ }
+
+ ctrl.setItemsFn = groupByExp ? updateGroups : setPlainItems;
+
+ ctrl.parserResult = RepeatParser.parse(repeatAttr);
+
+ ctrl.isGrouped = !!groupByExp;
+ ctrl.itemProperty = ctrl.parserResult.itemName;
+
+ //If collection is an Object, convert it to Array
+
+ var originalSource = ctrl.parserResult.source;
+
+ //When an object is used as source, we better create an array and use it as 'source'
+ var createArrayFromObject = function(){
+ var origSrc = originalSource($scope);
+ $scope.$uisSource = Object.keys(origSrc).map(function(v){
+ var result = {};
+ result[ctrl.parserResult.keyName] = v;
+ result.value = origSrc[v];
+ return result;
+ });
+ };
+
+ if (ctrl.parserResult.keyName){ // Check for (key,value) syntax
+ createArrayFromObject();
+ ctrl.parserResult.source = $parse('$uisSource' + ctrl.parserResult.filters);
+ $scope.$watch(originalSource, function(newVal, oldVal){
+ if (newVal !== oldVal) createArrayFromObject();
+ }, true);
+ }
+
+ ctrl.refreshItems = function (data){
+ data = data || ctrl.parserResult.source($scope);
+ var selectedItems = ctrl.selected;
+ //TODO should implement for single mode removeSelected
+ if (ctrl.isEmpty() || (angular.isArray(selectedItems) && !selectedItems.length) || !ctrl.multiple || !ctrl.removeSelected) {
+ ctrl.setItemsFn(data);
+ }else{
+ if ( data !== undefined && data !== null ) {
+ var filteredItems = data.filter(function(i) {
+ return angular.isArray(selectedItems) ? selectedItems.every(function(selectedItem) {
+ return !angular.equals(i, selectedItem);
+ }) : !angular.equals(i, selectedItems);
+ });
+ ctrl.setItemsFn(filteredItems);
+ }
+ }
+ if (ctrl.dropdownPosition === 'auto' || ctrl.dropdownPosition === 'up'){
+ $scope.calculateDropdownPos();
+ }
+ $scope.$broadcast('uis:refresh');
+ };
+
+ // See https://github.com/angular/angular.js/blob/v1.2.15/src/ng/directive/ngRepeat.js#L259
+ $scope.$watchCollection(ctrl.parserResult.source, function(items) {
+ if (items === undefined || items === null) {
+ // If the user specifies undefined or null => reset the collection
+ // Special case: items can be undefined if the user did not initialized the collection on the scope
+ // i.e $scope.addresses = [] is missing
+ ctrl.items = [];
+ } else {
+ if (!angular.isArray(items)) {
+ throw uiSelectMinErr('items', "Expected an array but got '{0}'.", items);
+ } else {
+ //Remove already selected items (ex: while searching)
+ //TODO Should add a test
+ ctrl.refreshItems(items);
+
+ //update the view value with fresh data from items, if there is a valid model value
+ if(angular.isDefined(ctrl.ngModel.$modelValue)) {
+ ctrl.ngModel.$modelValue = null; //Force scope model value and ngModel value to be out of sync to re-run formatters
+ }
+ }
+ }
+ });
+
+ };
+
+ var _refreshDelayPromise;
+
+ /**
+ * Typeahead mode: lets the user refresh the collection using his own function.
+ *
+ * See Expose $select.search for external / remote filtering https://github.com/angular-ui/ui-select/pull/31
+ */
+ ctrl.refresh = function(refreshAttr) {
+ if (refreshAttr !== undefined) {
+ // Debounce
+ // See https://github.com/angular-ui/bootstrap/blob/0.10.0/src/typeahead/typeahead.js#L155
+ // FYI AngularStrap typeahead does not have debouncing: https://github.com/mgcrea/angular-strap/blob/v2.0.0-rc.4/src/typeahead/typeahead.js#L177
+ if (_refreshDelayPromise) {
+ $timeout.cancel(_refreshDelayPromise);
+ }
+ _refreshDelayPromise = $timeout(function() {
+ if ($scope.$select.search.length >= $scope.$select.minimumInputLength) {
+ var refreshPromise = $scope.$eval(refreshAttr);
+ if (refreshPromise && angular.isFunction(refreshPromise.then) && !ctrl.refreshing) {
+ ctrl.refreshing = true;
+ refreshPromise.finally(function() {
+ ctrl.refreshing = false;
+ });
+ }
+ }
+ }, ctrl.refreshDelay);
+ }
+ };
+
+ ctrl.isActive = function(itemScope) {
+ if ( !ctrl.open ) {
+ return false;
+ }
+ var itemIndex = ctrl.items.indexOf(itemScope[ctrl.itemProperty]);
+ var isActive = itemIndex == ctrl.activeIndex;
+
+ if ( !isActive || itemIndex < 0 ) {
+ return false;
+ }
+
+ if (isActive && !angular.isUndefined(ctrl.onHighlightCallback)) {
+ itemScope.$eval(ctrl.onHighlightCallback);
+ }
+
+ return isActive;
+ };
+
+ var _isItemSelected = function (item) {
+ return (ctrl.selected && angular.isArray(ctrl.selected) &&
+ ctrl.selected.filter(function (selection) { return angular.equals(selection, item); }).length > 0);
+ };
+
+ var disabledItems = [];
+
+ function _updateItemDisabled(item, isDisabled) {
+ var disabledItemIndex = disabledItems.indexOf(item);
+ if (isDisabled && disabledItemIndex === -1) {
+ disabledItems.push(item);
+ }
+
+ if (!isDisabled && disabledItemIndex > -1) {
+ disabledItems.splice(disabledItemIndex, 1);
+ }
+ }
+
+ function _isItemDisabled(item) {
+ return disabledItems.indexOf(item) > -1;
+ }
+
+ ctrl.isDisabled = function(itemScope) {
+
+ if (!ctrl.open) return;
+
+ var item = itemScope[ctrl.itemProperty];
+ var itemIndex = ctrl.items.indexOf(item);
+ var isDisabled = false;
+
+ if (itemIndex >= 0 && (angular.isDefined(ctrl.disableChoiceExpression) || ctrl.multiple)) {
+
+ if (item.isTag) return false;
+
+ if (ctrl.multiple) {
+ isDisabled = _isItemSelected(item);
+ }
+
+ if (!isDisabled && angular.isDefined(ctrl.disableChoiceExpression)) {
+ isDisabled = !!(itemScope.$eval(ctrl.disableChoiceExpression));
+ }
+
+ _updateItemDisabled(item, isDisabled);
+ }
+
+ return isDisabled;
+ };
+
+
+ // When the user selects an item with ENTER or clicks the dropdown
+ ctrl.select = function(item, skipFocusser, $event) {
+ if (isNil(item) || !_isItemDisabled(item)) {
+
+ if ( ! ctrl.items && ! ctrl.search && ! ctrl.tagging.isActivated) return;
+
+ if (!item || !_isItemDisabled(item)) {
+ // if click is made on existing item, prevent from tagging, ctrl.search does not matter
+ ctrl.clickTriggeredSelect = false;
+ if($event && ($event.type === 'click' || $event.type === 'touchend') && item)
+ ctrl.clickTriggeredSelect = true;
+
+ if(ctrl.tagging.isActivated && ctrl.clickTriggeredSelect === false) {
+ // if taggingLabel is disabled and item is undefined we pull from ctrl.search
+ if ( ctrl.taggingLabel === false ) {
+ if ( ctrl.activeIndex < 0 ) {
+ if (item === undefined) {
+ item = ctrl.tagging.fct !== undefined ? ctrl.tagging.fct(ctrl.search) : ctrl.search;
+ }
+ if (!item || angular.equals( ctrl.items[0], item ) ) {
+ return;
+ }
+ } else {
+ // keyboard nav happened first, user selected from dropdown
+ item = ctrl.items[ctrl.activeIndex];
+ }
+ } else {
+ // tagging always operates at index zero, taggingLabel === false pushes
+ // the ctrl.search value without having it injected
+ if ( ctrl.activeIndex === 0 ) {
+ // ctrl.tagging pushes items to ctrl.items, so we only have empty val
+ // for `item` if it is a detected duplicate
+ if ( item === undefined ) return;
+
+ // create new item on the fly if we don't already have one;
+ // use tagging function if we have one
+ if ( ctrl.tagging.fct !== undefined && typeof item === 'string' ) {
+ item = ctrl.tagging.fct(item);
+ if (!item) return;
+ // if item type is 'string', apply the tagging label
+ } else if ( typeof item === 'string' ) {
+ // trim the trailing space
+ item = item.replace(ctrl.taggingLabel,'').trim();
+ }
+ }
+ }
+ // search ctrl.selected for dupes potentially caused by tagging and return early if found
+ if (_isItemSelected(item)) {
+ ctrl.close(skipFocusser);
+ return;
+ }
+ }
+ _resetSearchInput();
+ $scope.$broadcast('uis:select', item);
+
+ if (ctrl.closeOnSelect) {
+ ctrl.close(skipFocusser);
+ }
+ }
+ }
+ };
+
+ // Closes the dropdown
+ ctrl.close = function(skipFocusser) {
+ if (!ctrl.open) return;
+ if (ctrl.ngModel && ctrl.ngModel.$setTouched) ctrl.ngModel.$setTouched();
+ ctrl.open = false;
+ _resetSearchInput();
+ $scope.$broadcast('uis:close', skipFocusser);
+
+ };
+
+ ctrl.setFocus = function(){
+ if (!ctrl.focus) ctrl.focusInput[0].focus();
+ };
+
+ ctrl.clear = function($event) {
+ ctrl.select(null);
+ $event.stopPropagation();
+ $timeout(function() {
+ ctrl.focusser[0].focus();
+ }, 0, false);
+ };
+
+ // Toggle dropdown
+ ctrl.toggle = function(e) {
+ if (ctrl.open) {
+ ctrl.close();
+ e.preventDefault();
+ e.stopPropagation();
+ } else {
+ ctrl.activate();
+ }
+ };
+
+ // Set default function for locked choices - avoids unnecessary
+ // logic if functionality is not being used
+ ctrl.isLocked = function () {
+ return false;
+ };
+
+ $scope.$watch(function () {
+ return angular.isDefined(ctrl.lockChoiceExpression) && ctrl.lockChoiceExpression !== "";
+ }, _initaliseLockedChoices);
+
+ function _initaliseLockedChoices(doInitalise) {
+ if(!doInitalise) return;
+
+ var lockedItems = [];
+
+ function _updateItemLocked(item, isLocked) {
+ var lockedItemIndex = lockedItems.indexOf(item);
+ if (isLocked && lockedItemIndex === -1) {
+ lockedItems.push(item);
+ }
+
+ if (!isLocked && lockedItemIndex > -1) {
+ lockedItems.splice(lockedItemIndex, 1);
+ }
+ }
+
+ function _isItemlocked(item) {
+ return lockedItems.indexOf(item) > -1;
+ }
+
+ ctrl.isLocked = function (itemScope, itemIndex) {
+ var isLocked = false,
+ item = ctrl.selected[itemIndex];
+
+ if(item) {
+ if (itemScope) {
+ isLocked = !!(itemScope.$eval(ctrl.lockChoiceExpression));
+ _updateItemLocked(item, isLocked);
+ } else {
+ isLocked = _isItemlocked(item);
+ }
+ }
+
+ return isLocked;
+ };
+ }
+
+
+ var sizeWatch = null;
+ var updaterScheduled = false;
+ ctrl.sizeSearchInput = function() {
+
+ var input = ctrl.searchInput[0],
+ container = ctrl.$element[0],
+ calculateContainerWidth = function() {
+ // Return the container width only if the search input is visible
+ return container.clientWidth * !!input.offsetParent;
+ },
+ updateIfVisible = function(containerWidth) {
+ if (containerWidth === 0) {
+ return false;
+ }
+ var inputWidth = containerWidth - input.offsetLeft;
+ if (inputWidth < 50) inputWidth = containerWidth;
+ ctrl.searchInput.css('width', inputWidth+'px');
+ return true;
+ };
+
+ ctrl.searchInput.css('width', '10px');
+ $timeout(function() { //Give tags time to render correctly
+ if (sizeWatch === null && !updateIfVisible(calculateContainerWidth())) {
+ sizeWatch = $scope.$watch(function() {
+ if (!updaterScheduled) {
+ updaterScheduled = true;
+ $scope.$$postDigest(function() {
+ updaterScheduled = false;
+ if (updateIfVisible(calculateContainerWidth())) {
+ sizeWatch();
+ sizeWatch = null;
+ }
+ });
+ }
+ }, angular.noop);
+ }
+ });
+ };
+
+ function _handleDropDownSelection(key) {
+ var processed = true;
+ switch (key) {
+ case KEY.DOWN:
+ if (!ctrl.open && ctrl.multiple) ctrl.activate(false, true); //In case its the search input in 'multiple' mode
+ else if (ctrl.activeIndex < ctrl.items.length - 1) {
+ var idx = ++ctrl.activeIndex;
+ while(_isItemDisabled(ctrl.items[idx]) && idx < ctrl.items.length) {
+ ctrl.activeIndex = ++idx;
+ }
+ }
+ break;
+ case KEY.UP:
+ var minActiveIndex = (ctrl.search.length === 0 && ctrl.tagging.isActivated) ? -1 : 0;
+ if (!ctrl.open && ctrl.multiple) ctrl.activate(false, true); //In case its the search input in 'multiple' mode
+ else if (ctrl.activeIndex > minActiveIndex) {
+ var idxmin = --ctrl.activeIndex;
+ while(_isItemDisabled(ctrl.items[idxmin]) && idxmin > minActiveIndex) {
+ ctrl.activeIndex = --idxmin;
+ }
+ }
+ break;
+ case KEY.TAB:
+ if (!ctrl.multiple || ctrl.open) ctrl.select(ctrl.items[ctrl.activeIndex], true);
+ break;
+ case KEY.ENTER:
+ if(ctrl.open && (ctrl.tagging.isActivated || ctrl.activeIndex >= 0)){
+ ctrl.select(ctrl.items[ctrl.activeIndex], ctrl.skipFocusser); // Make sure at least one dropdown item is highlighted before adding if not in tagging mode
+ } else {
+ ctrl.activate(false, true); //In case its the search input in 'multiple' mode
+ }
+ break;
+ case KEY.ESC:
+ ctrl.close();
+ break;
+ default:
+ processed = false;
+ }
+ return processed;
+ }
+
+ // Bind to keyboard shortcuts
+ ctrl.searchInput.on('keydown', function(e) {
+
+ var key = e.which;
+
+ if (~[KEY.ENTER,KEY.ESC].indexOf(key)){
+ e.preventDefault();
+ e.stopPropagation();
+ }
+
+ $scope.$apply(function() {
+
+ var tagged = false;
+
+ if (ctrl.items.length > 0 || ctrl.tagging.isActivated) {
+ if(!_handleDropDownSelection(key) && !ctrl.searchEnabled) {
+ e.preventDefault();
+ e.stopPropagation();
+ }
+ if ( ctrl.taggingTokens.isActivated ) {
+ for (var i = 0; i < ctrl.taggingTokens.tokens.length; i++) {
+ if ( ctrl.taggingTokens.tokens[i] === KEY.MAP[e.keyCode] ) {
+ // make sure there is a new value to push via tagging
+ if ( ctrl.search.length > 0 ) {
+ tagged = true;
+ }
+ }
+ }
+ if ( tagged ) {
+ $timeout(function() {
+ ctrl.searchInput.triggerHandler('tagged');
+ var newItem = ctrl.search.replace(KEY.MAP[e.keyCode],'').trim();
+ if ( ctrl.tagging.fct ) {
+ newItem = ctrl.tagging.fct( newItem );
+ }
+ if (newItem) ctrl.select(newItem, true);
+ });
+ }
+ }
+ }
+
+ });
+
+ if(KEY.isVerticalMovement(key) && ctrl.items.length > 0){
+ _ensureHighlightVisible();
+ }
+
+ if (key === KEY.ENTER || key === KEY.ESC) {
+ e.preventDefault();
+ e.stopPropagation();
+ }
+
+ });
+
+ ctrl.searchInput.on('paste', function (e) {
+ var data;
+
+ if (window.clipboardData && window.clipboardData.getData) { // IE
+ data = window.clipboardData.getData('Text');
+ } else {
+ data = (e.originalEvent || e).clipboardData.getData('text/plain');
+ }
+
+ // Prepend the current input field text to the paste buffer.
+ data = ctrl.search + data;
+
+ if (data && data.length > 0) {
+ // If tagging try to split by tokens and add items
+ if (ctrl.taggingTokens.isActivated) {
+ var items = [];
+ for (var i = 0; i < ctrl.taggingTokens.tokens.length; i++) { // split by first token that is contained in data
+ var separator = KEY.toSeparator(ctrl.taggingTokens.tokens[i]) || ctrl.taggingTokens.tokens[i];
+ if (data.indexOf(separator) > -1) {
+ items = data.split(separator);
+ break; // only split by one token
+ }
+ }
+ if (items.length === 0) {
+ items = [data];
+ }
+ var oldsearch = ctrl.search;
+ angular.forEach(items, function (item) {
+ var newItem = ctrl.tagging.fct ? ctrl.tagging.fct(item) : item;
+ if (newItem) {
+ ctrl.select(newItem, true);
+ }
+ });
+ ctrl.search = oldsearch || EMPTY_SEARCH;
+ e.preventDefault();
+ e.stopPropagation();
+ } else if (ctrl.paste) {
+ ctrl.paste(data);
+ ctrl.search = EMPTY_SEARCH;
+ e.preventDefault();
+ e.stopPropagation();
+ }
+ }
+ });
+
+ ctrl.searchInput.on('tagged', function() {
+ $timeout(function() {
+ _resetSearchInput();
+ });
+ });
+
+ // See https://github.com/ivaynberg/select2/blob/3.4.6/select2.js#L1431
+ function _ensureHighlightVisible() {
+ var container = $element.querySelectorAll('.ui-select-choices-content');
+ var choices = container.querySelectorAll('.ui-select-choices-row');
+ if (choices.length < 1) {
+ throw uiSelectMinErr('choices', "Expected multiple .ui-select-choices-row but got '{0}'.", choices.length);
+ }
+
+ if (ctrl.activeIndex < 0) {
+ return;
+ }
+
+ var highlighted = choices[ctrl.activeIndex];
+ var posY = highlighted.offsetTop + highlighted.clientHeight - container[0].scrollTop;
+ var height = container[0].offsetHeight;
+
+ if (posY > height) {
+ container[0].scrollTop += posY - height;
+ } else if (posY < highlighted.clientHeight) {
+ if (ctrl.isGrouped && ctrl.activeIndex === 0)
+ container[0].scrollTop = 0; //To make group header visible when going all the way up
+ else
+ container[0].scrollTop -= highlighted.clientHeight - posY;
+ }
+ }
+
+ var onResize = $$uisDebounce(function() {
+ ctrl.sizeSearchInput();
+ }, 50);
+
+ angular.element($window).bind('resize', onResize);
+
+ $scope.$on('$destroy', function() {
+ ctrl.searchInput.off('keyup keydown tagged blur paste');
+ angular.element($window).off('resize', onResize);
+ });
+
+ $scope.$watch('$select.activeIndex', function(activeIndex) {
+ if (activeIndex)
+ $element.find('input').attr(
+ 'aria-activedescendant',
+ 'ui-select-choices-row-' + ctrl.generatedId + '-' + activeIndex);
+ });
+
+ $scope.$watch('$select.open', function(open) {
+ if (!open)
+ $element.find('input').removeAttr('aria-activedescendant');
+ });
+}]);
+
+uis.directive('uiSelect',
+ ['$document', 'uiSelectConfig', 'uiSelectMinErr', 'uisOffset', '$compile', '$parse', '$timeout',
+ function($document, uiSelectConfig, uiSelectMinErr, uisOffset, $compile, $parse, $timeout) {
+
+ return {
+ restrict: 'EA',
+ templateUrl: function(tElement, tAttrs) {
+ var theme = tAttrs.theme || uiSelectConfig.theme;
+ return theme + (angular.isDefined(tAttrs.multiple) ? '/select-multiple.tpl.html' : '/select.tpl.html');
+ },
+ replace: true,
+ transclude: true,
+ require: ['uiSelect', '^ngModel'],
+ scope: true,
+
+ controller: 'uiSelectCtrl',
+ controllerAs: '$select',
+ compile: function(tElement, tAttrs) {
+
+ // Allow setting ngClass on uiSelect
+ var match = /{(.*)}\s*{(.*)}/.exec(tAttrs.ngClass);
+ if(match) {
+ var combined = '{'+ match[1] +', '+ match[2] +'}';
+ tAttrs.ngClass = combined;
+ tElement.attr('ng-class', combined);
+ }
+
+ //Multiple or Single depending if multiple attribute presence
+ if (angular.isDefined(tAttrs.multiple))
+ tElement.append('<ui-select-multiple/>').removeAttr('multiple');
+ else
+ tElement.append('<ui-select-single/>');
+
+ if (tAttrs.inputId)
+ tElement.querySelectorAll('input.ui-select-search')[0].id = tAttrs.inputId;
+
+ return function(scope, element, attrs, ctrls, transcludeFn) {
+
+ var $select = ctrls[0];
+ var ngModel = ctrls[1];
+
+ $select.generatedId = uiSelectConfig.generateId();
+ $select.baseTitle = attrs.title || 'Select box';
+ $select.focusserTitle = $select.baseTitle + ' focus';
+ $select.focusserId = 'focusser-' + $select.generatedId;
+
+ $select.closeOnSelect = function() {
+ if (angular.isDefined(attrs.closeOnSelect)) {
+ return $parse(attrs.closeOnSelect)();
+ } else {
+ return uiSelectConfig.closeOnSelect;
+ }
+ }();
+
+ scope.$watch('skipFocusser', function() {
+ var skipFocusser = scope.$eval(attrs.skipFocusser);
+ $select.skipFocusser = skipFocusser !== undefined ? skipFocusser : uiSelectConfig.skipFocusser;
+ });
+
+ $select.onSelectCallback = $parse(attrs.onSelect);
+ $select.onRemoveCallback = $parse(attrs.onRemove);
+
+ //Set reference to ngModel from uiSelectCtrl
+ $select.ngModel = ngModel;
+
+ $select.choiceGrouped = function(group){
+ return $select.isGrouped && group && group.name;
+ };
+
+ if(attrs.tabindex){
+ attrs.$observe('tabindex', function(value) {
+ $select.focusInput.attr('tabindex', value);
+ element.removeAttr('tabindex');
+ });
+ }
+
+ scope.$watch(function () { return scope.$eval(attrs.searchEnabled); }, function(newVal) {
+ $select.searchEnabled = newVal !== undefined ? newVal : uiSelectConfig.searchEnabled;
+ });
+
+ scope.$watch('sortable', function() {
+ var sortable = scope.$eval(attrs.sortable);
+ $select.sortable = sortable !== undefined ? sortable : uiSelectConfig.sortable;
+ });
+
+ attrs.$observe('backspaceReset', function() {
+ // $eval() is needed otherwise we get a string instead of a boolean
+ var backspaceReset = scope.$eval(attrs.backspaceReset);
+ $select.backspaceReset = backspaceReset !== undefined ? backspaceReset : true;
+ });
+
+ attrs.$observe('limit', function() {
+ //Limit the number of selections allowed
+ $select.limit = (angular.isDefined(attrs.limit)) ? parseInt(attrs.limit, 10) : undefined;
+ });
+
+ scope.$watch('removeSelected', function() {
+ var removeSelected = scope.$eval(attrs.removeSelected);
+ $select.removeSelected = removeSelected !== undefined ? removeSelected : uiSelectConfig.removeSelected;
+ });
+
+ attrs.$observe('disabled', function() {
+ // No need to use $eval() (thanks to ng-disabled) since we already get a boolean instead of a string
+ $select.disabled = attrs.disabled !== undefined ? attrs.disabled : false;
+ });
+
+ attrs.$observe('resetSearchInput', function() {
+ // $eval() is needed otherwise we get a string instead of a boolean
+ var resetSearchInput = scope.$eval(attrs.resetSearchInput);
+ $select.resetSearchInput = resetSearchInput !== undefined ? resetSearchInput : true;
+ });
+
+ attrs.$observe('paste', function() {
+ $select.paste = scope.$eval(attrs.paste);
+ });
+
+ attrs.$observe('tagging', function() {
+ if(attrs.tagging !== undefined)
+ {
+ // $eval() is needed otherwise we get a string instead of a boolean
+ var taggingEval = scope.$eval(attrs.tagging);
+ $select.tagging = {isActivated: true, fct: taggingEval !== true ? taggingEval : undefined};
+ }
+ else
+ {
+ $select.tagging = {isActivated: false, fct: undefined};
+ }
+ });
+
+ attrs.$observe('taggingLabel', function() {
+ if(attrs.tagging !== undefined )
+ {
+ // check eval for FALSE, in this case, we disable the labels
+ // associated with tagging
+ if ( attrs.taggingLabel === 'false' ) {
+ $select.taggingLabel = false;
+ }
+ else
+ {
+ $select.taggingLabel = attrs.taggingLabel !== undefined ? attrs.taggingLabel : '(new)';
+ }
+ }
+ });
+
+ attrs.$observe('taggingTokens', function() {
+ if (attrs.tagging !== undefined) {
+ var tokens = attrs.taggingTokens !== undefined ? attrs.taggingTokens.split('|') : [',','ENTER'];
+ $select.taggingTokens = {isActivated: true, tokens: tokens };
+ }
+ });
+
+ attrs.$observe('spinnerEnabled', function() {
+ // $eval() is needed otherwise we get a string instead of a boolean
+ var spinnerEnabled = scope.$eval(attrs.spinnerEnabled);
+ $select.spinnerEnabled = spinnerEnabled !== undefined ? spinnerEnabled : uiSelectConfig.spinnerEnabled;
+ });
+
+ attrs.$observe('spinnerClass', function() {
+ var spinnerClass = attrs.spinnerClass;
+ $select.spinnerClass = spinnerClass !== undefined ? attrs.spinnerClass : uiSelectConfig.spinnerClass;
+ });
+
+ //Automatically gets focus when loaded
+ if (angular.isDefined(attrs.autofocus)){
+ $timeout(function(){
+ $select.setFocus();
+ });
+ }
+
+ //Gets focus based on scope event name (e.g. focus-on='SomeEventName')
+ if (angular.isDefined(attrs.focusOn)){
+ scope.$on(attrs.focusOn, function() {
+ $timeout(function(){
+ $select.setFocus();
+ });
+ });
+ }
+
+ function onDocumentClick(e) {
+ if (!$select.open) return; //Skip it if dropdown is close
+
+ var contains = false;
+
+ if (window.jQuery) {
+ // Firefox 3.6 does not support element.contains()
+ // See Node.contains https://developer.mozilla.org/en-US/docs/Web/API/Node.contains
+ contains = window.jQuery.contains(element[0], e.target);
+ } else {
+ contains = element[0].contains(e.target);
+ }
+
+ if (!contains && !$select.clickTriggeredSelect) {
+ var skipFocusser;
+ if (!$select.skipFocusser) {
+ //Will lose focus only with certain targets
+ var focusableControls = ['input','button','textarea','select'];
+ var targetController = angular.element(e.target).controller('uiSelect'); //To check if target is other ui-select
+ skipFocusser = targetController && targetController !== $select; //To check if target is other ui-select
+ if (!skipFocusser) skipFocusser = ~focusableControls.indexOf(e.target.tagName.toLowerCase()); //Check if target is input, button or textarea
+ } else {
+ skipFocusser = true;
+ }
+ $select.close(skipFocusser);
+ scope.$digest();
+ }
+ $select.clickTriggeredSelect = false;
+ }
+
+ // See Click everywhere but here event http://stackoverflow.com/questions/12931369
+ $document.on('click', onDocumentClick);
+
+ scope.$on('$destroy', function() {
+ $document.off('click', onDocumentClick);
+ });
+
+ // Move transcluded elements to their correct position in main template
+ transcludeFn(scope, function(clone) {
+ // See Transclude in AngularJS http://blog.omkarpatil.com/2012/11/transclude-in-angularjs.html
+
+ // One day jqLite will be replaced by jQuery and we will be able to write:
+ // var transcludedElement = clone.filter('.my-class')
+ // instead of creating a hackish DOM element:
+ var transcluded = angular.element('<div>').append(clone);
+
+ var transcludedMatch = transcluded.querySelectorAll('.ui-select-match');
+ transcludedMatch.removeAttr('ui-select-match'); //To avoid loop in case directive as attr
+ transcludedMatch.removeAttr('data-ui-select-match'); // Properly handle HTML5 data-attributes
+ if (transcludedMatch.length !== 1) {
+ throw uiSelectMinErr('transcluded', "Expected 1 .ui-select-match but got '{0}'.", transcludedMatch.length);
+ }
+ element.querySelectorAll('.ui-select-match').replaceWith(transcludedMatch);
+
+ var transcludedChoices = transcluded.querySelectorAll('.ui-select-choices');
+ transcludedChoices.removeAttr('ui-select-choices'); //To avoid loop in case directive as attr
+ transcludedChoices.removeAttr('data-ui-select-choices'); // Properly handle HTML5 data-attributes
+ if (transcludedChoices.length !== 1) {
+ throw uiSelectMinErr('transcluded', "Expected 1 .ui-select-choices but got '{0}'.", transcludedChoices.length);
+ }
+ element.querySelectorAll('.ui-select-choices').replaceWith(transcludedChoices);
+
+ var transcludedNoChoice = transcluded.querySelectorAll('.ui-select-no-choice');
+ transcludedNoChoice.removeAttr('ui-select-no-choice'); //To avoid loop in case directive as attr
+ transcludedNoChoice.removeAttr('data-ui-select-no-choice'); // Properly handle HTML5 data-attributes
+ if (transcludedNoChoice.length == 1) {
+ element.querySelectorAll('.ui-select-no-choice').replaceWith(transcludedNoChoice);
+ }
+ });
+
+ // Support for appending the select field to the body when its open
+ var appendToBody = scope.$eval(attrs.appendToBody);
+ if (appendToBody !== undefined ? appendToBody : uiSelectConfig.appendToBody) {
+ scope.$watch('$select.open', function(isOpen) {
+ if (isOpen) {
+ positionDropdown();
+ } else {
+ resetDropdown();
+ }
+ });
+
+ // Move the dropdown back to its original location when the scope is destroyed. Otherwise
+ // it might stick around when the user routes away or the select field is otherwise removed
+ scope.$on('$destroy', function() {
+ resetDropdown();
+ });
+ }
+
+ // Hold on to a reference to the .ui-select-container element for appendToBody support
+ var placeholder = null,
+ originalWidth = '';
+
+ function positionDropdown() {
+ // Remember the absolute position of the element
+ var offset = uisOffset(element);
+
+ // Clone the element into a placeholder element to take its original place in the DOM
+ placeholder = angular.element('<div class="ui-select-placeholder"></div>');
+ placeholder[0].style.width = offset.width + 'px';
+ placeholder[0].style.height = offset.height + 'px';
+ element.after(placeholder);
+
+ // Remember the original value of the element width inline style, so it can be restored
+ // when the dropdown is closed
+ originalWidth = element[0].style.width;
+
+ // Now move the actual dropdown element to the end of the body
+ $document.find('body').append(element);
+
+ element[0].style.position = 'absolute';
+ element[0].style.left = offset.left + 'px';
+ element[0].style.top = offset.top + 'px';
+ element[0].style.width = offset.width + 'px';
+ }
+
+ function resetDropdown() {
+ if (placeholder === null) {
+ // The dropdown has not actually been display yet, so there's nothing to reset
+ return;
+ }
+
+ // Move the dropdown element back to its original location in the DOM
+ placeholder.replaceWith(element);
+ placeholder = null;
+
+ element[0].style.position = '';
+ element[0].style.left = '';
+ element[0].style.top = '';
+ element[0].style.width = originalWidth;
+
+ // Set focus back on to the moved element
+ $select.setFocus();
+ }
+
+ // Hold on to a reference to the .ui-select-dropdown element for direction support.
+ var dropdown = null,
+ directionUpClassName = 'direction-up';
+
+ // Support changing the direction of the dropdown if there isn't enough space to render it.
+ scope.$watch('$select.open', function() {
+
+ if ($select.dropdownPosition === 'auto' || $select.dropdownPosition === 'up'){
+ scope.calculateDropdownPos();
+ }
+
+ });
+
+ var setDropdownPosUp = function(offset, offsetDropdown){
+
+ offset = offset || uisOffset(element);
+ offsetDropdown = offsetDropdown || uisOffset(dropdown);
+
+ dropdown[0].style.position = 'absolute';
+ dropdown[0].style.top = (offsetDropdown.height * -1) + 'px';
+ element.addClass(directionUpClassName);
+
+ };
+
+ var setDropdownPosDown = function(offset, offsetDropdown){
+
+ element.removeClass(directionUpClassName);
+
+ offset = offset || uisOffset(element);
+ offsetDropdown = offsetDropdown || uisOffset(dropdown);
+
+ dropdown[0].style.position = '';
+ dropdown[0].style.top = '';
+
+ };
+
+ var calculateDropdownPosAfterAnimation = function() {
+ // Delay positioning the dropdown until all choices have been added so its height is correct.
+ $timeout(function() {
+ if ($select.dropdownPosition === 'up') {
+ //Go UP
+ setDropdownPosUp();
+ } else {
+ //AUTO
+ element.removeClass(directionUpClassName);
+
+ var offset = uisOffset(element);
+ var offsetDropdown = uisOffset(dropdown);
+
+ //https://code.google.com/p/chromium/issues/detail?id=342307#c4
+ var scrollTop = $document[0].documentElement.scrollTop || $document[0].body.scrollTop; //To make it cross browser (blink, webkit, IE, Firefox).
+
+ // Determine if the direction of the dropdown needs to be changed.
+ if (offset.top + offset.height + offsetDropdown.height > scrollTop + $document[0].documentElement.clientHeight) {
+ //Go UP
+ setDropdownPosUp(offset, offsetDropdown);
+ }else{
+ //Go DOWN
+ setDropdownPosDown(offset, offsetDropdown);
+ }
+ }
+
+ // Display the dropdown once it has been positioned.
+ dropdown[0].style.opacity = 1;
+ });
+ };
+
+ var opened = false;
+
+ scope.calculateDropdownPos = function() {
+ if ($select.open) {
+ dropdown = angular.element(element).querySelectorAll('.ui-select-dropdown');
+
+ if (dropdown.length === 0) {
+ return;
+ }
+
+ // Hide the dropdown so there is no flicker until $timeout is done executing.
+ if ($select.search === '' && !opened) {
+ dropdown[0].style.opacity = 0;
+ opened = true;
+ }
+
+ if (!uisOffset(dropdown).height && $select.$animate && $select.$animate.on && $select.$animate.enabled(dropdown)) {
+ var needsCalculated = true;
+
+ $select.$animate.on('enter', dropdown, function (elem, phase) {
+ if (phase === 'close' && needsCalculated) {
+ calculateDropdownPosAfterAnimation();
+ needsCalculated = false;
+ }
+ });
+ } else {
+ calculateDropdownPosAfterAnimation();
+ }
+ } else {
+ if (dropdown === null || dropdown.length === 0) {
+ return;
+ }
+
+ // Reset the position of the dropdown.
+ dropdown[0].style.opacity = 0;
+ dropdown[0].style.position = '';
+ dropdown[0].style.top = '';
+ element.removeClass(directionUpClassName);
+ }
+ };
+ };
+ }
+ };
+}]);
+
+uis.directive('uiSelectMatch', ['uiSelectConfig', function(uiSelectConfig) {
+ return {
+ restrict: 'EA',
+ require: '^uiSelect',
+ replace: true,
+ transclude: true,
+ templateUrl: function(tElement) {
+ // Needed so the uiSelect can detect the transcluded content
+ tElement.addClass('ui-select-match');
+
+ var parent = tElement.parent();
+ // Gets theme attribute from parent (ui-select)
+ var theme = getAttribute(parent, 'theme') || uiSelectConfig.theme;
+ var multi = angular.isDefined(getAttribute(parent, 'multiple'));
+
+ return theme + (multi ? '/match-multiple.tpl.html' : '/match.tpl.html');
+ },
+ link: function(scope, element, attrs, $select) {
+ $select.lockChoiceExpression = attrs.uiLockChoice;
+ attrs.$observe('placeholder', function(placeholder) {
+ $select.placeholder = placeholder !== undefined ? placeholder : uiSelectConfig.placeholder;
+ });
+
+ function setAllowClear(allow) {
+ $select.allowClear = (angular.isDefined(allow)) ? (allow === '') ? true : (allow.toLowerCase() === 'true') : false;
+ }
+
+ attrs.$observe('allowClear', setAllowClear);
+ setAllowClear(attrs.allowClear);
+
+ if($select.multiple){
+ $select.sizeSearchInput();
+ }
+
+ }
+ };
+
+ function getAttribute(elem, attribute) {
+ if (elem[0].hasAttribute(attribute))
+ return elem.attr(attribute);
+
+ if (elem[0].hasAttribute('data-' + attribute))
+ return elem.attr('data-' + attribute);
+
+ if (elem[0].hasAttribute('x-' + attribute))
+ return elem.attr('x-' + attribute);
+ }
+}]);
+
+uis.directive('uiSelectMultiple', ['uiSelectMinErr','$timeout', function(uiSelectMinErr, $timeout) {
+ return {
+ restrict: 'EA',
+ require: ['^uiSelect', '^ngModel'],
+
+ controller: ['$scope','$timeout', function($scope, $timeout){
+
+ var ctrl = this,
+ $select = $scope.$select,
+ ngModel;
+
+ if (angular.isUndefined($select.selected))
+ $select.selected = [];
+
+ //Wait for link fn to inject it
+ $scope.$evalAsync(function(){ ngModel = $scope.ngModel; });
+
+ ctrl.activeMatchIndex = -1;
+
+ ctrl.updateModel = function(){
+ ngModel.$setViewValue(Date.now()); //Set timestamp as a unique string to force changes
+ ctrl.refreshComponent();
+ };
+
+ ctrl.refreshComponent = function(){
+ //Remove already selected items
+ //e.g. When user clicks on a selection, the selected array changes and
+ //the dropdown should remove that item
+ if($select.refreshItems){
+ $select.refreshItems();
+ }
+ if($select.sizeSearchInput){
+ $select.sizeSearchInput();
+ }
+ };
+
+ // Remove item from multiple select
+ ctrl.removeChoice = function(index){
+
+ // if the choice is locked, don't remove it
+ if($select.isLocked(null, index)) return false;
+
+ var removedChoice = $select.selected[index];
+
+ var locals = {};
+ locals[$select.parserResult.itemName] = removedChoice;
+
+ $select.selected.splice(index, 1);
+ ctrl.activeMatchIndex = -1;
+ $select.sizeSearchInput();
+
+ // Give some time for scope propagation.
+ $timeout(function(){
+ $select.onRemoveCallback($scope, {
+ $item: removedChoice,
+ $model: $select.parserResult.modelMapper($scope, locals)
+ });
+ });
+
+ ctrl.updateModel();
+
+ return true;
+ };
+
+ ctrl.getPlaceholder = function(){
+ //Refactor single?
+ if($select.selected && $select.selected.length) return;
+ return $select.placeholder;
+ };
+
+
+ }],
+ controllerAs: '$selectMultiple',
+
+ link: function(scope, element, attrs, ctrls) {
+
+ var $select = ctrls[0];
+ var ngModel = scope.ngModel = ctrls[1];
+ var $selectMultiple = scope.$selectMultiple;
+
+ //$select.selected = raw selected objects (ignoring any property binding)
+
+ $select.multiple = true;
+
+ //Input that will handle focus
+ $select.focusInput = $select.searchInput;
+
+ //Properly check for empty if set to multiple
+ ngModel.$isEmpty = function(value) {
+ return !value || value.length === 0;
+ };
+
+ //From view --> model
+ ngModel.$parsers.unshift(function () {
+ var locals = {},
+ result,
+ resultMultiple = [];
+ for (var j = $select.selected.length - 1; j >= 0; j--) {
+ locals = {};
+ locals[$select.parserResult.itemName] = $select.selected[j];
+ result = $select.parserResult.modelMapper(scope, locals);
+ resultMultiple.unshift(result);
+ }
+ return resultMultiple;
+ });
+
+ // From model --> view
+ ngModel.$formatters.unshift(function (inputValue) {
+ var data = $select.parserResult && $select.parserResult.source (scope, { $select : {search:''}}), //Overwrite $search
+ locals = {},
+ result;
+ if (!data) return inputValue;
+ var resultMultiple = [];
+ var checkFnMultiple = function(list, value){
+ if (!list || !list.length) return;
+ for (var p = list.length - 1; p >= 0; p--) {
+ locals[$select.parserResult.itemName] = list[p];
+ result = $select.parserResult.modelMapper(scope, locals);
+ if($select.parserResult.trackByExp){
+ var propsItemNameMatches = /(\w*)\./.exec($select.parserResult.trackByExp);
+ var matches = /\.([^\s]+)/.exec($select.parserResult.trackByExp);
+ if(propsItemNameMatches && propsItemNameMatches.length > 0 && propsItemNameMatches[1] == $select.parserResult.itemName){
+ if(matches && matches.length>0 && result[matches[1]] == value[matches[1]]){
+ resultMultiple.unshift(list[p]);
+ return true;
+ }
+ }
+ }
+ if (angular.equals(result,value)){
+ resultMultiple.unshift(list[p]);
+ return true;
+ }
+ }
+ return false;
+ };
+ if (!inputValue) return resultMultiple; //If ngModel was undefined
+ for (var k = inputValue.length - 1; k >= 0; k--) {
+ //Check model array of currently selected items
+ if (!checkFnMultiple($select.selected, inputValue[k])){
+ //Check model array of all items available
+ if (!checkFnMultiple(data, inputValue[k])){
+ //If not found on previous lists, just add it directly to resultMultiple
+ resultMultiple.unshift(inputValue[k]);
+ }
+ }
+ }
+ return resultMultiple;
+ });
+
+ //Watch for external model changes
+ scope.$watchCollection(function(){ return ngModel.$modelValue; }, function(newValue, oldValue) {
+ if (oldValue != newValue){
+ //update the view value with fresh data from items, if there is a valid model value
+ if(angular.isDefined(ngModel.$modelValue)) {
+ ngModel.$modelValue = null; //Force scope model value and ngModel value to be out of sync to re-run formatters
+ }
+ $selectMultiple.refreshComponent();
+ }
+ });
+
+ ngModel.$render = function() {
+ // Make sure that model value is array
+ if(!angular.isArray(ngModel.$viewValue)){
+ // Have tolerance for null or undefined values
+ if (isNil(ngModel.$viewValue)){
+ ngModel.$viewValue = [];
+ } else {
+ throw uiSelectMinErr('multiarr', "Expected model value to be array but got '{0}'", ngModel.$viewValue);
+ }
+ }
+ $select.selected = ngModel.$viewValue;
+ $selectMultiple.refreshComponent();
+ scope.$evalAsync(); //To force $digest
+ };
+
+ scope.$on('uis:select', function (event, item) {
+ if($select.selected.length >= $select.limit) {
+ return;
+ }
+ $select.selected.push(item);
+ var locals = {};
+ locals[$select.parserResult.itemName] = item;
+
+ $timeout(function(){
+ $select.onSelectCallback(scope, {
+ $item: item,
+ $model: $select.parserResult.modelMapper(scope, locals)
+ });
+ });
+ $selectMultiple.updateModel();
+ });
+
+ scope.$on('uis:activate', function () {
+ $selectMultiple.activeMatchIndex = -1;
+ });
+
+ scope.$watch('$select.disabled', function(newValue, oldValue) {
+ // As the search input field may now become visible, it may be necessary to recompute its size
+ if (oldValue && !newValue) $select.sizeSearchInput();
+ });
+
+ $select.searchInput.on('keydown', function(e) {
+ var key = e.which;
+ scope.$apply(function() {
+ var processed = false;
+ // var tagged = false; //Checkme
+ if(KEY.isHorizontalMovement(key)){
+ processed = _handleMatchSelection(key);
+ }
+ if (processed && key != KEY.TAB) {
+ //TODO Check si el tab selecciona aun correctamente
+ //Crear test
+ e.preventDefault();
+ e.stopPropagation();
+ }
+ });
+ });
+ function _getCaretPosition(el) {
+ if(angular.isNumber(el.selectionStart)) return el.selectionStart;
+ // selectionStart is not supported in IE8 and we don't want hacky workarounds so we compromise
+ else return el.value.length;
+ }
+ // Handles selected options in "multiple" mode
+ function _handleMatchSelection(key){
+ var caretPosition = _getCaretPosition($select.searchInput[0]),
+ length = $select.selected.length,
+ // none = -1,
+ first = 0,
+ last = length-1,
+ curr = $selectMultiple.activeMatchIndex,
+ next = $selectMultiple.activeMatchIndex+1,
+ prev = $selectMultiple.activeMatchIndex-1,
+ newIndex = curr;
+
+ if(caretPosition > 0 || ($select.search.length && key == KEY.RIGHT)) return false;
+
+ $select.close();
+
+ function getNewActiveMatchIndex(){
+ switch(key){
+ case KEY.LEFT:
+ // Select previous/first item
+ if(~$selectMultiple.activeMatchIndex) return prev;
+ // Select last item
+ else return last;
+ break;
+ case KEY.RIGHT:
+ // Open drop-down
+ if(!~$selectMultiple.activeMatchIndex || curr === last){
+ $select.activate();
+ return false;
+ }
+ // Select next/last item
+ else return next;
+ break;
+ case KEY.BACKSPACE:
+ // Remove selected item and select previous/first
+ if(~$selectMultiple.activeMatchIndex){
+ if($selectMultiple.removeChoice(curr)) {
+ return prev;
+ } else {
+ return curr;
+ }
+
+ } else {
+ // If nothing yet selected, select last item
+ return last;
+ }
+ break;
+ case KEY.DELETE:
+ // Remove selected item and select next item
+ if(~$selectMultiple.activeMatchIndex){
+ $selectMultiple.removeChoice($selectMultiple.activeMatchIndex);
+ return curr;
+ }
+ else return false;
+ }
+ }
+
+ newIndex = getNewActiveMatchIndex();
+
+ if(!$select.selected.length || newIndex === false) $selectMultiple.activeMatchIndex = -1;
+ else $selectMultiple.activeMatchIndex = Math.min(last,Math.max(first,newIndex));
+
+ return true;
+ }
+
+ $select.searchInput.on('keyup', function(e) {
+
+ if ( ! KEY.isVerticalMovement(e.which) ) {
+ scope.$evalAsync( function () {
+ $select.activeIndex = $select.taggingLabel === false ? -1 : 0;
+ });
+ }
+ // Push a "create new" item into array if there is a search string
+ if ( $select.tagging.isActivated && $select.search.length > 0 ) {
+
+ // return early with these keys
+ if (e.which === KEY.TAB || KEY.isControl(e) || KEY.isFunctionKey(e) || e.which === KEY.ESC || KEY.isVerticalMovement(e.which) ) {
+ return;
+ }
+ // always reset the activeIndex to the first item when tagging
+ $select.activeIndex = $select.taggingLabel === false ? -1 : 0;
+ // taggingLabel === false bypasses all of this
+ if ($select.taggingLabel === false) return;
+
+ var items = angular.copy( $select.items );
+ var stashArr = angular.copy( $select.items );
+ var newItem;
+ var item;
+ var hasTag = false;
+ var dupeIndex = -1;
+ var tagItems;
+ var tagItem;
+
+ // case for object tagging via transform `$select.tagging.fct` function
+ if ( $select.tagging.fct !== undefined) {
+ tagItems = $select.$filter('filter')(items,{'isTag': true});
+ if ( tagItems.length > 0 ) {
+ tagItem = tagItems[0];
+ }
+ // remove the first element, if it has the `isTag` prop we generate a new one with each keyup, shaving the previous
+ if ( items.length > 0 && tagItem ) {
+ hasTag = true;
+ items = items.slice(1,items.length);
+ stashArr = stashArr.slice(1,stashArr.length);
+ }
+ newItem = $select.tagging.fct($select.search);
+ // verify the new tag doesn't match the value of a possible selection choice or an already selected item.
+ if (
+ stashArr.some(function (origItem) {
+ return angular.equals(origItem, newItem);
+ }) ||
+ $select.selected.some(function (origItem) {
+ return angular.equals(origItem, newItem);
+ })
+ ) {
+ scope.$evalAsync(function () {
+ $select.activeIndex = 0;
+ $select.items = items;
+ });
+ return;
+ }
+ if (newItem) newItem.isTag = true;
+ // handle newItem string and stripping dupes in tagging string context
+ } else {
+ // find any tagging items already in the $select.items array and store them
+ tagItems = $select.$filter('filter')(items,function (item) {
+ return item.match($select.taggingLabel);
+ });
+ if ( tagItems.length > 0 ) {
+ tagItem = tagItems[0];
+ }
+ item = items[0];
+ // remove existing tag item if found (should only ever be one tag item)
+ if ( item !== undefined && items.length > 0 && tagItem ) {
+ hasTag = true;
+ items = items.slice(1,items.length);
+ stashArr = stashArr.slice(1,stashArr.length);
+ }
+ newItem = $select.search+' '+$select.taggingLabel;
+ if ( _findApproxDupe($select.selected, $select.search) > -1 ) {
+ return;
+ }
+ // verify the the tag doesn't match the value of an existing item from
+ // the searched data set or the items already selected
+ if ( _findCaseInsensitiveDupe(stashArr.concat($select.selected)) ) {
+ // if there is a tag from prev iteration, strip it / queue the change
+ // and return early
+ if ( hasTag ) {
+ items = stashArr;
+ scope.$evalAsync( function () {
+ $select.activeIndex = 0;
+ $select.items = items;
+ });
+ }
+ return;
+ }
+ if ( _findCaseInsensitiveDupe(stashArr) ) {
+ // if there is a tag from prev iteration, strip it
+ if ( hasTag ) {
+ $select.items = stashArr.slice(1,stashArr.length);
+ }
+ return;
+ }
+ }
+ if ( hasTag ) dupeIndex = _findApproxDupe($select.selected, newItem);
+ // dupe found, shave the first item
+ if ( dupeIndex > -1 ) {
+ items = items.slice(dupeIndex+1,items.length-1);
+ } else {
+ items = [];
+ if (newItem) items.push(newItem);
+ items = items.concat(stashArr);
+ }
+ scope.$evalAsync( function () {
+ $select.activeIndex = 0;
+ $select.items = items;
+
+ if ($select.isGrouped) {
+ // update item references in groups, so that indexOf will work after angular.copy
+ var itemsWithoutTag = newItem ? items.slice(1) : items;
+ $select.setItemsFn(itemsWithoutTag);
+ if (newItem) {
+ // add tag item as a new group
+ $select.items.unshift(newItem);
+ $select.groups.unshift({name: '', items: [newItem], tagging: true});
+ }
+ }
+ });
+ }
+ });
+ function _findCaseInsensitiveDupe(arr) {
+ if ( arr === undefined || $select.search === undefined ) {
+ return false;
+ }
+ var hasDupe = arr.filter( function (origItem) {
+ if ( $select.search.toUpperCase() === undefined || origItem === undefined ) {
+ return false;
+ }
+ return origItem.toUpperCase() === $select.search.toUpperCase();
+ }).length > 0;
+
+ return hasDupe;
+ }
+ function _findApproxDupe(haystack, needle) {
+ var dupeIndex = -1;
+ if(angular.isArray(haystack)) {
+ var tempArr = angular.copy(haystack);
+ for (var i = 0; i <tempArr.length; i++) {
+ // handle the simple string version of tagging
+ if ( $select.tagging.fct === undefined ) {
+ // search the array for the match
+ if ( tempArr[i]+' '+$select.taggingLabel === needle ) {
+ dupeIndex = i;
+ }
+ // handle the object tagging implementation
+ } else {
+ var mockObj = tempArr[i];
+ if (angular.isObject(mockObj)) {
+ mockObj.isTag = true;
+ }
+ if ( angular.equals(mockObj, needle) ) {
+ dupeIndex = i;
+ }
+ }
+ }
+ }
+ return dupeIndex;
+ }
+
+ $select.searchInput.on('blur', function() {
+ $timeout(function() {
+ $selectMultiple.activeMatchIndex = -1;
+ });
+ });
+
+ }
+ };
+}]);
+
+uis.directive('uiSelectNoChoice',
+ ['uiSelectConfig', function (uiSelectConfig) {
+ return {
+ restrict: 'EA',
+ require: '^uiSelect',
+ replace: true,
+ transclude: true,
+ templateUrl: function (tElement) {
+ // Needed so the uiSelect can detect the transcluded content
+ tElement.addClass('ui-select-no-choice');
+
+ // Gets theme attribute from parent (ui-select)
+ var theme = tElement.parent().attr('theme') || uiSelectConfig.theme;
+ return theme + '/no-choice.tpl.html';
+ }
+ };
+ }]);
+
+uis.directive('uiSelectSingle', ['$timeout','$compile', function($timeout, $compile) {
+ return {
+ restrict: 'EA',
+ require: ['^uiSelect', '^ngModel'],
+ link: function(scope, element, attrs, ctrls) {
+
+ var $select = ctrls[0];
+ var ngModel = ctrls[1];
+
+ //From view --> model
+ ngModel.$parsers.unshift(function (inputValue) {
+ // Keep original value for undefined and null
+ if (isNil(inputValue)) {
+ return inputValue;
+ }
+
+ var locals = {},
+ result;
+ locals[$select.parserResult.itemName] = inputValue;
+ result = $select.parserResult.modelMapper(scope, locals);
+ return result;
+ });
+
+ //From model --> view
+ ngModel.$formatters.unshift(function (inputValue) {
+ // Keep original value for undefined and null
+ if (isNil(inputValue)) {
+ return inputValue;
+ }
+
+ var data = $select.parserResult && $select.parserResult.source (scope, { $select : {search:''}}), //Overwrite $search
+ locals = {},
+ result;
+ if (data){
+ var checkFnSingle = function(d){
+ locals[$select.parserResult.itemName] = d;
+ result = $select.parserResult.modelMapper(scope, locals);
+ return result === inputValue;
+ };
+ //If possible pass same object stored in $select.selected
+ if ($select.selected && checkFnSingle($select.selected)) {
+ return $select.selected;
+ }
+ for (var i = data.length - 1; i >= 0; i--) {
+ if (checkFnSingle(data[i])) return data[i];
+ }
+ }
+ return inputValue;
+ });
+
+ //Update viewValue if model change
+ scope.$watch('$select.selected', function(newValue) {
+ if (ngModel.$viewValue !== newValue) {
+ ngModel.$setViewValue(newValue);
+ }
+ });
+
+ ngModel.$render = function() {
+ $select.selected = ngModel.$viewValue;
+ };
+
+ scope.$on('uis:select', function (event, item) {
+ $select.selected = item;
+ var locals = {};
+ locals[$select.parserResult.itemName] = item;
+
+ $timeout(function() {
+ $select.onSelectCallback(scope, {
+ $item: item,
+ $model: isNil(item) ? item : $select.parserResult.modelMapper(scope, locals)
+ });
+ });
+ });
+
+ scope.$on('uis:close', function (event, skipFocusser) {
+ $timeout(function(){
+ $select.focusser.prop('disabled', false);
+ if (!skipFocusser) $select.focusser[0].focus();
+ },0,false);
+ });
+
+ scope.$on('uis:activate', function () {
+ focusser.prop('disabled', true); //Will reactivate it on .close()
+ });
+
+ //Idea from: https://github.com/ivaynberg/select2/blob/79b5bf6db918d7560bdd959109b7bcfb47edaf43/select2.js#L1954
+ var focusser = angular.element("<input ng-disabled='$select.disabled' class='ui-select-focusser ui-select-offscreen' type='text' id='{{ $select.focusserId }}' aria-label='{{ $select.focusserTitle }}' aria-haspopup='true' role='button' />");
+ $compile(focusser)(scope);
+ $select.focusser = focusser;
+
+ //Input that will handle focus
+ $select.focusInput = focusser;
+
+ element.parent().append(focusser);
+ focusser.bind("focus", function(){
+ scope.$evalAsync(function(){
+ $select.focus = true;
+ });
+ });
+ focusser.bind("blur", function(){
+ scope.$evalAsync(function(){
+ $select.focus = false;
+ });
+ });
+ focusser.bind("keydown", function(e){
+
+ if (e.which === KEY.BACKSPACE && $select.backspaceReset !== false) {
+ e.preventDefault();
+ e.stopPropagation();
+ $select.select(undefined);
+ scope.$apply();
+ return;
+ }
+
+ if (e.which === KEY.TAB || KEY.isControl(e) || KEY.isFunctionKey(e) || e.which === KEY.ESC) {
+ return;
+ }
+
+ if (e.which == KEY.DOWN || e.which == KEY.UP || e.which == KEY.ENTER || e.which == KEY.SPACE){
+ e.preventDefault();
+ e.stopPropagation();
+ $select.activate();
+ }
+
+ scope.$digest();
+ });
+
+ focusser.bind("keyup input", function(e){
+
+ if (e.which === KEY.TAB || KEY.isControl(e) || KEY.isFunctionKey(e) || e.which === KEY.ESC || e.which == KEY.ENTER || e.which === KEY.BACKSPACE) {
+ return;
+ }
+
+ $select.activate(focusser.val()); //User pressed some regular key, so we pass it to the search input
+ focusser.val('');
+ scope.$digest();
+
+ });
+
+
+ }
+ };
+}]);
+
+// Make multiple matches sortable
+uis.directive('uiSelectSort', ['$timeout', 'uiSelectConfig', 'uiSelectMinErr', function($timeout, uiSelectConfig, uiSelectMinErr) {
+ return {
+ require: ['^^uiSelect', '^ngModel'],
+ link: function(scope, element, attrs, ctrls) {
+ if (scope[attrs.uiSelectSort] === null) {
+ throw uiSelectMinErr('sort', 'Expected a list to sort');
+ }
+
+ var $select = ctrls[0];
+ var $ngModel = ctrls[1];
+
+ var options = angular.extend({
+ axis: 'horizontal'
+ },
+ scope.$eval(attrs.uiSelectSortOptions));
+
+ var axis = options.axis;
+ var draggingClassName = 'dragging';
+ var droppingClassName = 'dropping';
+ var droppingBeforeClassName = 'dropping-before';
+ var droppingAfterClassName = 'dropping-after';
+
+ scope.$watch(function(){
+ return $select.sortable;
+ }, function(newValue){
+ if (newValue) {
+ element.attr('draggable', true);
+ } else {
+ element.removeAttr('draggable');
+ }
+ });
+
+ element.on('dragstart', function(event) {
+ element.addClass(draggingClassName);
+
+ (event.dataTransfer || event.originalEvent.dataTransfer).setData('text', scope.$index.toString());
+ });
+
+ element.on('dragend', function() {
+ removeClass(draggingClassName);
+ });
+
+ var move = function(from, to) {
+ /*jshint validthis: true */
+ this.splice(to, 0, this.splice(from, 1)[0]);
+ };
+
+ var removeClass = function(className) {
+ angular.forEach($select.$element.querySelectorAll('.' + className), function(el){
+ angular.element(el).removeClass(className);
+ });
+ };
+
+ var dragOverHandler = function(event) {
+ event.preventDefault();
+
+ var offset = axis === 'vertical' ? event.offsetY || event.layerY || (event.originalEvent ? event.originalEvent.offsetY : 0) : event.offsetX || event.layerX || (event.originalEvent ? event.originalEvent.offsetX : 0);
+
+ if (offset < (this[axis === 'vertical' ? 'offsetHeight' : 'offsetWidth'] / 2)) {
+ removeClass(droppingAfterClassName);
+ element.addClass(droppingBeforeClassName);
+
+ } else {
+ removeClass(droppingBeforeClassName);
+ element.addClass(droppingAfterClassName);
+ }
+ };
+
+ var dropTimeout;
+
+ var dropHandler = function(event) {
+ event.preventDefault();
+
+ var droppedItemIndex = parseInt((event.dataTransfer || event.originalEvent.dataTransfer).getData('text'), 10);
+
+ // prevent event firing multiple times in firefox
+ $timeout.cancel(dropTimeout);
+ dropTimeout = $timeout(function() {
+ _dropHandler(droppedItemIndex);
+ }, 20);
+ };
+
+ var _dropHandler = function(droppedItemIndex) {
+ var theList = scope.$eval(attrs.uiSelectSort);
+ var itemToMove = theList[droppedItemIndex];
+ var newIndex = null;
+
+ if (element.hasClass(droppingBeforeClassName)) {
+ if (droppedItemIndex < scope.$index) {
+ newIndex = scope.$index - 1;
+ } else {
+ newIndex = scope.$index;
+ }
+ } else {
+ if (droppedItemIndex < scope.$index) {
+ newIndex = scope.$index;
+ } else {
+ newIndex = scope.$index + 1;
+ }
+ }
+
+ move.apply(theList, [droppedItemIndex, newIndex]);
+
+ $ngModel.$setViewValue(Date.now());
+
+ scope.$apply(function() {
+ scope.$emit('uiSelectSort:change', {
+ array: theList,
+ item: itemToMove,
+ from: droppedItemIndex,
+ to: newIndex
+ });
+ });
+
+ removeClass(droppingClassName);
+ removeClass(droppingBeforeClassName);
+ removeClass(droppingAfterClassName);
+
+ element.off('drop', dropHandler);
+ };
+
+ element.on('dragenter', function() {
+ if (element.hasClass(draggingClassName)) {
+ return;
+ }
+
+ element.addClass(droppingClassName);
+
+ element.on('dragover', dragOverHandler);
+ element.on('drop', dropHandler);
+ });
+
+ element.on('dragleave', function(event) {
+ if (event.target != element) {
+ return;
+ }
+
+ removeClass(droppingClassName);
+ removeClass(droppingBeforeClassName);
+ removeClass(droppingAfterClassName);
+
+ element.off('dragover', dragOverHandler);
+ element.off('drop', dropHandler);
+ });
+ }
+ };
+}]);
+
+uis.directive('uisOpenClose', ['$parse', '$timeout', function ($parse, $timeout) {
+ return {
+ restrict: 'A',
+ require: 'uiSelect',
+ link: function (scope, element, attrs, $select) {
+ $select.onOpenCloseCallback = $parse(attrs.uisOpenClose);
+
+ scope.$watch('$select.open', function (isOpen, previousState) {
+ if (isOpen !== previousState) {
+ $timeout(function () {
+ $select.onOpenCloseCallback(scope, {
+ isOpen: isOpen
+ });
+ });
+ }
+ });
+ }
+ };
+}]);
+
+/**
+ * Parses "repeat" attribute.
+ *
+ * Taken from AngularJS ngRepeat source code
+ * See https://github.com/angular/angular.js/blob/v1.2.15/src/ng/directive/ngRepeat.js#L211
+ *
+ * Original discussion about parsing "repeat" attribute instead of fully relying on ng-repeat:
+ * https://github.com/angular-ui/ui-select/commit/5dd63ad#commitcomment-5504697
+ */
+
+uis.service('uisRepeatParser', ['uiSelectMinErr','$parse', function(uiSelectMinErr, $parse) {
+ var self = this;
+
+ /**
+ * Example:
+ * expression = "address in addresses | filter: {street: $select.search} track by $index"
+ * itemName = "address",
+ * source = "addresses | filter: {street: $select.search}",
+ * trackByExp = "$index",
+ */
+ self.parse = function(expression) {
+
+
+ var match;
+ //var isObjectCollection = /\(\s*([\$\w][\$\w]*)\s*,\s*([\$\w][\$\w]*)\s*\)/.test(expression);
+ // If an array is used as collection
+
+ // if (isObjectCollection){
+ // 000000000000000000000000000000111111111000000000000000222222222222220033333333333333333333330000444444444444444444000000000000000055555555555000000000000000000000066666666600000000
+ match = expression.match(/^\s*(?:([\s\S]+?)\s+as\s+)?(?:([\$\w][\$\w]*)|(?:\(\s*([\$\w][\$\w]*)\s*,\s*([\$\w][\$\w]*)\s*\)))\s+in\s+(\s*[\s\S]+?)?(?:\s+track\s+by\s+([\s\S]+?))?\s*$/);
+
+ // 1 Alias
+ // 2 Item
+ // 3 Key on (key,value)
+ // 4 Value on (key,value)
+ // 5 Source expression (including filters)
+ // 6 Track by
+
+ if (!match) {
+ throw uiSelectMinErr('iexp', "Expected expression in form of '_item_ in _collection_[ track by _id_]' but got '{0}'.",
+ expression);
+ }
+
+ var source = match[5],
+ filters = '';
+
+ // When using (key,value) ui-select requires filters to be extracted, since the object
+ // is converted to an array for $select.items
+ // (in which case the filters need to be reapplied)
+ if (match[3]) {
+ // Remove any enclosing parenthesis
+ source = match[5].replace(/(^\()|(\)$)/g, '');
+ // match all after | but not after ||
+ var filterMatch = match[5].match(/^\s*(?:[\s\S]+?)(?:[^\|]|\|\|)+([\s\S]*)\s*$/);
+ if(filterMatch && filterMatch[1].trim()) {
+ filters = filterMatch[1];
+ source = source.replace(filters, '');
+ }
+ }
+
+ return {
+ itemName: match[4] || match[2], // (lhs) Left-hand side,
+ keyName: match[3], //for (key, value) syntax
+ source: $parse(source),
+ filters: filters,
+ trackByExp: match[6],
+ modelMapper: $parse(match[1] || match[4] || match[2]),
+ repeatExpression: function (grouped) {
+ var expression = this.itemName + ' in ' + (grouped ? '$group.items' : '$select.items');
+ if (this.trackByExp) {
+ expression += ' track by ' + this.trackByExp;
+ }
+ return expression;
+ }
+ };
+
+ };
+
+ self.getGroupNgRepeatExpression = function() {
+ return '$group in $select.groups track by $group.name';
+ };
+
+}]);
+
+}());
+angular.module("ui.select").run(["$templateCache", function($templateCache) {$templateCache.put("bootstrap/choices.tpl.html","<ul class=\"ui-select-choices ui-select-choices-content ui-select-dropdown dropdown-menu\" ng-show=\"$select.open && $select.items.length > 0\"><li class=\"ui-select-choices-group\" id=\"ui-select-choices-{{ $select.generatedId }}\"><div class=\"divider\" ng-show=\"$select.isGrouped && $index > 0\"></div><div ng-show=\"$select.isGrouped\" class=\"ui-select-choices-group-label dropdown-header\" ng-bind=\"$group.name\"></div><div ng-attr-id=\"ui-select-choices-row-{{ $select.generatedId }}-{{$index}}\" class=\"ui-select-choices-row\" ng-class=\"{active: $select.isActive(this), disabled: $select.isDisabled(this)}\" role=\"option\"><span class=\"ui-select-choices-row-inner\"></span></div></li></ul>");
+$templateCache.put("bootstrap/match-multiple.tpl.html","<span class=\"ui-select-match\"><span ng-repeat=\"$item in $select.selected track by $index\"><span class=\"ui-select-match-item btn btn-default btn-xs\" tabindex=\"-1\" type=\"button\" ng-disabled=\"$select.disabled\" ng-click=\"$selectMultiple.activeMatchIndex = $index;\" ng-class=\"{\'btn-primary\':$selectMultiple.activeMatchIndex === $index, \'select-locked\':$select.isLocked(this, $index)}\" ui-select-sort=\"$select.selected\"><span class=\"close ui-select-match-close\" ng-hide=\"$select.disabled\" ng-click=\"$selectMultiple.removeChoice($index)\">&nbsp;&times;</span> <span uis-transclude-append=\"\"></span></span></span></span>");
+$templateCache.put("bootstrap/match.tpl.html","<div class=\"ui-select-match\" ng-hide=\"$select.open && $select.searchEnabled\" ng-disabled=\"$select.disabled\" ng-class=\"{\'btn-default-focus\':$select.focus}\"><span tabindex=\"-1\" class=\"btn btn-default form-control ui-select-toggle\" aria-label=\"{{ $select.baseTitle }} activate\" ng-disabled=\"$select.disabled\" ng-click=\"$select.activate()\" style=\"outline: 0;\"><span ng-show=\"$select.isEmpty()\" class=\"ui-select-placeholder text-muted\">{{$select.placeholder}}</span> <span ng-hide=\"$select.isEmpty()\" class=\"ui-select-match-text pull-left\" ng-class=\"{\'ui-select-allow-clear\': $select.allowClear && !$select.isEmpty()}\" ng-transclude=\"\"></span> <i class=\"caret pull-right\" ng-click=\"$select.toggle($event)\"></i> <a ng-show=\"$select.allowClear && !$select.isEmpty() && ($select.disabled !== true)\" aria-label=\"{{ $select.baseTitle }} clear\" style=\"margin-right: 10px\" ng-click=\"$select.clear($event)\" class=\"btn btn-xs btn-link pull-right\"><i class=\"glyphicon glyphicon-remove\" aria-hidden=\"true\"></i></a></span></div>");
+$templateCache.put("bootstrap/no-choice.tpl.html","<ul class=\"ui-select-no-choice dropdown-menu\" ng-show=\"$select.items.length == 0\"><li ng-transclude=\"\"></li></ul>");
+$templateCache.put("bootstrap/select-multiple.tpl.html","<div class=\"ui-select-container ui-select-multiple ui-select-bootstrap dropdown form-control\" ng-class=\"{open: $select.open}\"><div><div class=\"ui-select-match\"></div><input type=\"search\" autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" class=\"ui-select-search input-xs\" placeholder=\"{{$selectMultiple.getPlaceholder()}}\" ng-disabled=\"$select.disabled\" ng-click=\"$select.activate()\" ng-model=\"$select.search\" role=\"combobox\" aria-expanded=\"{{$select.open}}\" aria-label=\"{{$select.baseTitle}}\" ng-class=\"{\'spinner\': $select.refreshing}\" ondrop=\"return false;\"></div><div class=\"ui-select-choices\"></div><div class=\"ui-select-no-choice\"></div></div>");
+$templateCache.put("bootstrap/select.tpl.html","<div class=\"ui-select-container ui-select-bootstrap dropdown\" ng-class=\"{open: $select.open}\"><div class=\"ui-select-match\"></div><span ng-show=\"$select.open && $select.refreshing && $select.spinnerEnabled\" class=\"ui-select-refreshing {{$select.spinnerClass}}\"></span> <input type=\"search\" autocomplete=\"off\" tabindex=\"-1\" aria-expanded=\"true\" aria-label=\"{{ $select.baseTitle }}\" aria-owns=\"ui-select-choices-{{ $select.generatedId }}\" class=\"form-control ui-select-search\" ng-class=\"{ \'ui-select-search-hidden\' : !$select.searchEnabled }\" placeholder=\"{{$select.placeholder}}\" ng-model=\"$select.search\" ng-show=\"$select.open\"><div class=\"ui-select-choices\"></div><div class=\"ui-select-no-choice\"></div></div>");
+$templateCache.put("select2/choices.tpl.html","<ul tabindex=\"-1\" class=\"ui-select-choices ui-select-choices-content select2-results\"><li class=\"ui-select-choices-group\" ng-class=\"{\'select2-result-with-children\': $select.choiceGrouped($group) }\"><div ng-show=\"$select.choiceGrouped($group)\" class=\"ui-select-choices-group-label select2-result-label\" ng-bind=\"$group.name\"></div><ul id=\"ui-select-choices-{{ $select.generatedId }}\" ng-class=\"{\'select2-result-sub\': $select.choiceGrouped($group), \'select2-result-single\': !$select.choiceGrouped($group) }\"><li role=\"option\" ng-attr-id=\"ui-select-choices-row-{{ $select.generatedId }}-{{$index}}\" class=\"ui-select-choices-row\" ng-class=\"{\'select2-highlighted\': $select.isActive(this), \'select2-disabled\': $select.isDisabled(this)}\"><div class=\"select2-result-label ui-select-choices-row-inner\"></div></li></ul></li></ul>");
+$templateCache.put("select2/match-multiple.tpl.html","<span class=\"ui-select-match\"><li class=\"ui-select-match-item select2-search-choice\" ng-repeat=\"$item in $select.selected track by $index\" ng-class=\"{\'select2-search-choice-focus\':$selectMultiple.activeMatchIndex === $index, \'select2-locked\':$select.isLocked(this, $index)}\" ui-select-sort=\"$select.selected\"><span uis-transclude-append=\"\"></span> <a href=\"javascript:;\" class=\"ui-select-match-close select2-search-choice-close\" ng-click=\"$selectMultiple.removeChoice($index)\" tabindex=\"-1\"></a></li></span>");
+$templateCache.put("select2/match.tpl.html","<a class=\"select2-choice ui-select-match\" ng-class=\"{\'select2-default\': $select.isEmpty()}\" ng-click=\"$select.toggle($event)\" aria-label=\"{{ $select.baseTitle }} select\"><span ng-show=\"$select.isEmpty()\" class=\"select2-chosen\">{{$select.placeholder}}</span> <span ng-hide=\"$select.isEmpty()\" class=\"select2-chosen\" ng-transclude=\"\"></span> <abbr ng-if=\"$select.allowClear && !$select.isEmpty()\" class=\"select2-search-choice-close\" ng-click=\"$select.clear($event)\"></abbr> <span class=\"select2-arrow ui-select-toggle\"><b></b></span></a>");
+$templateCache.put("select2/no-choice.tpl.html","<div class=\"ui-select-no-choice dropdown\" ng-show=\"$select.items.length == 0\"><div class=\"dropdown-content\"><div data-selectable=\"\" ng-transclude=\"\"></div></div></div>");
+$templateCache.put("select2/select-multiple.tpl.html","<div class=\"ui-select-container ui-select-multiple select2 select2-container select2-container-multi\" ng-class=\"{\'select2-container-active select2-dropdown-open open\': $select.open, \'select2-container-disabled\': $select.disabled}\"><ul class=\"select2-choices\"><span class=\"ui-select-match\"></span><li class=\"select2-search-field\"><input type=\"search\" autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" role=\"combobox\" aria-expanded=\"true\" aria-owns=\"ui-select-choices-{{ $select.generatedId }}\" aria-label=\"{{ $select.baseTitle }}\" aria-activedescendant=\"ui-select-choices-row-{{ $select.generatedId }}-{{ $select.activeIndex }}\" class=\"select2-input ui-select-search\" placeholder=\"{{$selectMultiple.getPlaceholder()}}\" ng-disabled=\"$select.disabled\" ng-hide=\"$select.disabled\" ng-model=\"$select.search\" ng-click=\"$select.activate()\" style=\"width: 34px;\" ondrop=\"return false;\"></li></ul><div class=\"ui-select-dropdown select2-drop select2-with-searchbox select2-drop-active\" ng-class=\"{\'select2-display-none\': !$select.open || $select.items.length === 0}\"><div class=\"ui-select-choices\"></div></div></div>");
+$templateCache.put("select2/select.tpl.html","<div class=\"ui-select-container select2 select2-container\" ng-class=\"{\'select2-container-active select2-dropdown-open open\': $select.open, \'select2-container-disabled\': $select.disabled, \'select2-container-active\': $select.focus, \'select2-allowclear\': $select.allowClear && !$select.isEmpty()}\"><div class=\"ui-select-match\"></div><div class=\"ui-select-dropdown select2-drop select2-with-searchbox select2-drop-active\" ng-class=\"{\'select2-display-none\': !$select.open}\"><div class=\"search-container\" ng-class=\"{\'ui-select-search-hidden\':!$select.searchEnabled, \'select2-search\':$select.searchEnabled}\"><input type=\"search\" autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" ng-class=\"{\'select2-active\': $select.refreshing}\" role=\"combobox\" aria-expanded=\"true\" aria-owns=\"ui-select-choices-{{ $select.generatedId }}\" aria-label=\"{{ $select.baseTitle }}\" class=\"ui-select-search select2-input\" ng-model=\"$select.search\"></div><div class=\"ui-select-choices\"></div><div class=\"ui-select-no-choice\"></div></div></div>");
+$templateCache.put("selectize/choices.tpl.html","<div ng-show=\"$select.open\" class=\"ui-select-choices ui-select-dropdown selectize-dropdown\" ng-class=\"{\'single\': !$select.multiple, \'multi\': $select.multiple}\"><div class=\"ui-select-choices-content selectize-dropdown-content\"><div class=\"ui-select-choices-group optgroup\"><div ng-show=\"$select.isGrouped\" class=\"ui-select-choices-group-label optgroup-header\" ng-bind=\"$group.name\"></div><div role=\"option\" class=\"ui-select-choices-row\" ng-class=\"{active: $select.isActive(this), disabled: $select.isDisabled(this)}\"><div class=\"option ui-select-choices-row-inner\" data-selectable=\"\"></div></div></div></div></div>");
+$templateCache.put("selectize/match-multiple.tpl.html","<div class=\"ui-select-match\" data-value=\"\" ng-repeat=\"$item in $select.selected track by $index\" ng-click=\"$selectMultiple.activeMatchIndex = $index;\" ng-class=\"{\'active\':$selectMultiple.activeMatchIndex === $index}\" ui-select-sort=\"$select.selected\"><span class=\"ui-select-match-item\" ng-class=\"{\'select-locked\':$select.isLocked(this, $index)}\"><span uis-transclude-append=\"\"></span> <span class=\"remove ui-select-match-close\" ng-hide=\"$select.disabled\" ng-click=\"$selectMultiple.removeChoice($index)\">&times;</span></span></div>");
+$templateCache.put("selectize/match.tpl.html","<div ng-hide=\"$select.searchEnabled && ($select.open || $select.isEmpty())\" class=\"ui-select-match\"><span ng-show=\"!$select.searchEnabled && ($select.isEmpty() || $select.open)\" class=\"ui-select-placeholder text-muted\">{{$select.placeholder}}</span> <span ng-hide=\"$select.isEmpty() || $select.open\" ng-transclude=\"\"></span></div>");
+$templateCache.put("selectize/no-choice.tpl.html","<div class=\"ui-select-no-choice selectize-dropdown\" ng-show=\"$select.items.length == 0\"><div class=\"selectize-dropdown-content\"><div data-selectable=\"\" ng-transclude=\"\"></div></div></div>");
+$templateCache.put("selectize/select-multiple.tpl.html","<div class=\"ui-select-container selectize-control multi plugin-remove_button\" ng-class=\"{\'open\': $select.open}\"><div class=\"selectize-input\" ng-class=\"{\'focus\': $select.open, \'disabled\': $select.disabled, \'selectize-focus\' : $select.focus}\" ng-click=\"$select.open && !$select.searchEnabled ? $select.toggle($event) : $select.activate()\"><div class=\"ui-select-match\"></div><input type=\"search\" autocomplete=\"off\" tabindex=\"-1\" class=\"ui-select-search\" ng-class=\"{\'ui-select-search-hidden\':!$select.searchEnabled}\" placeholder=\"{{$selectMultiple.getPlaceholder()}}\" ng-model=\"$select.search\" ng-disabled=\"$select.disabled\" aria-expanded=\"{{$select.open}}\" aria-label=\"{{ $select.baseTitle }}\" ondrop=\"return false;\"></div><div class=\"ui-select-choices\"></div><div class=\"ui-select-no-choice\"></div></div>");
+$templateCache.put("selectize/select.tpl.html","<div class=\"ui-select-container selectize-control single\" ng-class=\"{\'open\': $select.open}\"><div class=\"selectize-input\" ng-class=\"{\'focus\': $select.open, \'disabled\': $select.disabled, \'selectize-focus\' : $select.focus}\" ng-click=\"$select.open && !$select.searchEnabled ? $select.toggle($event) : $select.activate()\"><div class=\"ui-select-match\"></div><input type=\"search\" autocomplete=\"off\" tabindex=\"-1\" class=\"ui-select-search ui-select-toggle\" ng-class=\"{\'ui-select-search-hidden\':!$select.searchEnabled}\" ng-click=\"$select.toggle($event)\" placeholder=\"{{$select.placeholder}}\" ng-model=\"$select.search\" ng-hide=\"!$select.isEmpty() && !$select.open\" ng-disabled=\"$select.disabled\" aria-label=\"{{ $select.baseTitle }}\"></div><div class=\"ui-select-choices\"></div><div class=\"ui-select-no-choice\"></div></div>");}]); \ No newline at end of file
diff --git a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/home/api_doc.html b/ccsdk-app-overlay/src/main/webapp/app/ccsdk/home/api_doc.html
deleted file mode 100644
index 342406c..0000000
--- a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/home/api_doc.html
+++ /dev/null
@@ -1,26 +0,0 @@
-<!--
- ============LICENSE_START==========================================
- ===================================================================
- Copyright (C) 2020 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.
-
- ============LICENSE_END============================================
- -->
-<div id="page-content">
- <iframe scrolling="yes" frameborder="0" style="width:100%; height: 800px;"
- ng-src="api-specs.html">
- </iframe>
-</div> \ No newline at end of file
diff --git a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/home/appDS2.js b/ccsdk-app-overlay/src/main/webapp/app/ccsdk/home/appDS2.js
index ebb35cd..f29d7ad 100644
--- a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/home/appDS2.js
+++ b/ccsdk-app-overlay/src/main/webapp/app/ccsdk/home/appDS2.js
@@ -1,30 +1,14 @@
-/*******************************************************************************
- * =============LICENSE_START=========================================================
- *
- * =================================================================================
- * Copyright (c) 2020 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file 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.
- * ============LICENSE_END=========================================================
- *
- *******************************************************************************/
-
/* Angular application for the EC Dashboard web UI */
var appDS2 = angular.module("abs",
[
'ngCookies', 'ngRoute', 'ngMessages','ngSanitize',
- 'ui.bootstrap', 'ui.bootstrap.modal',
+ 'ui.bootstrap', 'ui.bootstrap.modal', 'ui.select',
'b2b.att',
- 'modalServices'
+ 'modalServices', 'LocalStorageModule'
]
- );
+ ).config(function($sceDelegateProvider) {
+ $sceDelegateProvider.resourceUrlWhitelist(['**']);
+ }).config(['localStorageServiceProvider', function(localStorageServiceProvider) {
+ localStorageServiceProvider.setPrefix('eom')
+ .setStorageType('sessionStorage');
+ }]);
diff --git a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/home/controller-service.js b/ccsdk-app-overlay/src/main/webapp/app/ccsdk/home/controller-service.js
index 65495f1..cfa8be7 100644
--- a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/home/controller-service.js
+++ b/ccsdk-app-overlay/src/main/webapp/app/ccsdk/home/controller-service.js
@@ -1,24 +1,3 @@
-/*******************************************************************************
- * =============LICENSE_START=========================================================
- *
- * =================================================================================
- * Copyright (c) 2020 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file 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.
- * ============LICENSE_END=========================================================
- *
- *******************************************************************************/
-
appDS2.factory('ControllerService', function ($http, $q, $log) {
return {
/**
@@ -39,20 +18,20 @@ appDS2.factory('ControllerService', function ($http, $q, $log) {
return $q.reject(error.statusText);
});
},
- getApiSwaggerSpec: function() {
- return $http({
- method: 'GET',
- url: 'nb-api/api-docs',
- cache: true,
- responseType: 'json'
- }).then(function(response) {
- return response.data;
- },
- function(error) {
- $log.error('ControllerService.getApiSwaggerSpec failed: ' + JSON.stringify(error));
- return $q.reject(error.statusText);
- });
- },
+ getApiSwaggerSpec: function() {
+ return $http({
+ method: 'GET',
+ url: 'api-docs',
+ cache: true,
+ responseType: 'json'
+ }).then(function(response) {
+ return response.data;
+ },
+ function(error) {
+ $log.error('ControllerService.getApiSwaggerSpec failed: ' + JSON.stringify(error));
+ return $q.reject(error.statusText);
+ });
+ },
/**
* Gets the cloudify tenant names.
*
@@ -74,70 +53,114 @@ appDS2.factory('ControllerService', function ($http, $q, $log) {
return $q.reject(error.statusText);
});
},
+ getConsulLink: function() {
+ return $http({
+ method: 'GET',
+ url: 'consul_url',
+ cache: false,
+ responseType: 'text'
+ }).then(function(response) {
+ if (response.data == null)
+ return $q.reject('ControllerService.getConsulLink: response.data null or not object');
+ else
+ return response.data;
+ },
+ function(error) {
+ $log.error('ControllerService.getConsulLink failed: ' + JSON.stringify(error));
+ return $q.reject(error.statusText);
+ });
+ },
/**
* Gets the ops tools info
*
*/
- getOpsUrls: function() {
+ getDcaeLinks: function() {
return $http({
method: 'GET',
- url: 'ops',
- cache: true,
- responseType: 'json'
+ url: 'dcae_links',
+ cache: false,
+ responseType: 'text'
}).then(function(response) {
- if (response.data == null || typeof response.data != 'object')
- return $q.reject('ControllerService.getOpsUrls: response.data null or not object');
+ if (response.data == null)
+ return $q.reject('ControllerService.getDcaeLinks: response.data null or not object');
else
return response.data;
},
function(error) {
- $log.error('ControllerService.getOpsUrls failed: ' + JSON.stringify(error));
+ $log.error('ControllerService.getDcaeLinks failed: ' + JSON.stringify(error));
return $q.reject(error.statusText);
});
},
- /**
- * Gets ECOMP-C Endpoint objects.
- * No provision for pagination here.
- * @return {JSON} Response object from remote side
- */
- getControllers: function() {
- // cache control for IE
- var cc = "?cc=" + new Date().getTime().toString();
+
+ getOpsToolUrls: function() {
return $http({
- method: 'GET',
- url: 'controllers' + cc,
- cache: true,
- responseType: 'json'
+ method: 'GET',
+ url: 'ops_links',
+ cache: false,
+ responseType: 'json'
}).then(function(response) {
if (response.data == null || typeof response.data != 'object')
- return $q.reject('ControllerService.getControllers: response.data null or not object');
+ return $q.reject('ControllerService.getOpsToolUrls: response.data null or not object');
else
return response.data;
},
function(error) {
- $log.error('ControllerService.getControllers failed: ' + JSON.stringify(error));
+ $log.error('ControllerService.getOpsToolUrls failed: ' + JSON.stringify(error));
return $q.reject(error.statusText);
- });
+ });
},
- setControllerSelection: function(row) {
- // $log.debug('ControllerService.setControllerSelection: invoked with ' + JSON.stringify(row));
+ //Get the links from database table along with site/tenant list
+ getOpsToolMenuLinks: function() {
return $http({
- method: 'POST',
- url: 'controllers',
- data: row,
- responseType: 'json'
+ method: 'GET',
+ url: 'ops_menu_links',
+ cache: false,
+ responseType: 'json'
}).then(function(response) {
if (response.data == null || typeof response.data != 'object')
- return $q.reject('ControllerService.setControllerSelection: response.data null or not object');
+ return $q.reject('ControllerService.getOpsToolMenuLinks: response.data null or not object');
else
return response.data;
},
function(error) {
- $log.error('ControllerService.setControllerSelection failed: ' + JSON.stringify(error));
+ $log.error('ControllerService.getOpsToolMenuLinks failed: ' + JSON.stringify(error));
return $q.reject(error.statusText);
- });
- }
-
+ });
+ },
+ getUserRoleData: function() {
+ return $http({
+ method: 'GET',
+ url: 'user-role-details',
+ cache: false,
+ responseType: 'json'
+ }).then(function(response) {
+ if (response.data == null || typeof response.data != 'object')
+ return $q.reject('ControllerService.getUserRoleData: response.data null or not object');
+ else
+ return response.data;
+ },
+ function(error) {
+ $log.error('ControllerService.getUserRoleData failed: ' + JSON.stringify(error));
+ return $q.reject(error.statusText);
+ });
+ },
+ getPluginsCount: function() {
+ return $http({
+ method: 'GET',
+ url: 'plugins-count',
+ cache: false,
+ responseType: 'json'
+ }).then(function(response) {
+ if (response.data == null || typeof response.data != 'object')
+ return $q.reject('ControllerService.getPluginsCount: response.data null or not object');
+ else
+ return response.data;
+ },
+ function(error) {
+ $log.error('ControllerService.getPluginsCount failed: ' + JSON.stringify(error));
+ return $q.reject(error.statusText);
+ });
+ }
};
});
diff --git a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/home/oom_popup_templates.html b/ccsdk-app-overlay/src/main/webapp/app/ccsdk/home/ecd_popup_templates.html
index fe4d505..9e640e9 100644
--- a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/home/oom_popup_templates.html
+++ b/ccsdk-app-overlay/src/main/webapp/app/ccsdk/home/ecd_popup_templates.html
@@ -62,4 +62,4 @@
</button>
</div>
</div>
-</script>
+</script> \ No newline at end of file
diff --git a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/home/executions-view-controller.js b/ccsdk-app-overlay/src/main/webapp/app/ccsdk/home/executions-view-controller.js
deleted file mode 100644
index 2491e50..0000000
--- a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/home/executions-view-controller.js
+++ /dev/null
@@ -1,45 +0,0 @@
-appDS2.controller('executionsViewController', function($scope, $rootScope, ControllerService, $modal, ExecutionService, $log) {
-
- $scope.parent = { 'blueprint_id': 'Root', 'parent': 'parent' };
- $scope.ecdapp = {};
- $scope.ecdapp.isDataLoading = false;
- $scope.ecdapp.appLabel = "";
- $rootScope.tenantList = {
- tenant: '',
- data: {}
- };
- var debug = false;
-
- var getTenants = function() {
- ControllerService.getTenants()
- .then(function(jsonObj) {
- if (jsonObj.error) {
- $log.error("executionsViewController.getTenants failed: " + jsonObj.error);
- $scope.ecdapp.isRequestFailed = true;
- $scope.ecdapp.errMsg = jsonObj.error;
- $scope.ecdapp.tableData = [];
- } else {
- $rootScope.tenantList.data = jsonObj.items;
- $rootScope.tenantList.tenant = jsonObj.items[0].name;
- }
- }, function(error) {
- $log.error("executionsViewController.loadTable failed: " + error);
- $scope.ecdapp.isRequestFailed = true;
- $scope.ecdapp.errMsg = error;
- });
- };
-
- var getAppLabel = function() {
- ControllerService.getAppLabel().then(function(jsonObj) {
- if (debug)
- $log.debug("Controller.getAppLabel succeeded: " + JSON.stringify(jsonObj));
- $scope.ecdapp.appLabel = jsonObj;
- }, function(error) {
- $log.error("Controller.getAppLabel failed: " + error);
- });
- };
- // Initialize the page
- getAppLabel();
- getTenants();
-
-});
diff --git a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/home/executions_view.html b/ccsdk-app-overlay/src/main/webapp/app/ccsdk/home/executions_view.html
deleted file mode 100644
index 5623b1c..0000000
--- a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/home/executions_view.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<div id="page-content">
-
- <h4 class="heading-page" id="controllers">DCAE Dashboard</h4>
-</div>
-
diff --git a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/home/http-interceptor.js b/ccsdk-app-overlay/src/main/webapp/app/ccsdk/home/http-interceptor.js
deleted file mode 100644
index 0f5410d..0000000
--- a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/home/http-interceptor.js
+++ /dev/null
@@ -1,29 +0,0 @@
-appDS2.factory('httpInterceptor', function ($q, $rootScope, $location) {
- return {
- 'request': function (config) {
- return config;
- },
- /*
- 'requestError': function (rejection) {
- },
- */
- 'response': function (response) {
- if (response.data == null) {
- var loc = location.pathname;
- console.log("location path name: " + loc);
- var loc1 = loc.replace("/", "");
- var loc2 = loc1.replace("/ecd", "/login.htm");
- console.log("location url: " + loc2);
- alert("Your session has expired. Please log in again...");
- location.replace("/"+loc2);
- }
- return response;
- },
- // optional method
- 'responseError': function (rejection) {
- }
- };
- })
- .config(function($httpProvider) {
- $httpProvider.interceptors.push('httpInterceptor');
- }); \ No newline at end of file
diff --git a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/home/oom-instances-controller.js b/ccsdk-app-overlay/src/main/webapp/app/ccsdk/home/oom-instances-controller.js
deleted file mode 100644
index f07d1b3..0000000
--- a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/home/oom-instances-controller.js
+++ /dev/null
@@ -1,70 +0,0 @@
-/*******************************************************************************
- * =============LICENSE_START=========================================================
- *
- * =================================================================================
- * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file 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.
- * ============LICENSE_END=========================================================
- *
- * ECOMP is a trademark and service mark of AT&T Intellectual Property.
- *******************************************************************************/
-appDS2.controller('selectEcompcController', function(
- $scope, $rootScope, $log, $modalInstance, message, ControllerService) {
-
- // message brings the table items
-
- 'use strict';
-
- // Set to true for verbose output
- var debug = false;
-
- // this object holds data and functions
- $scope.ecdapp = {};
- $scope.ecdapp.tableData = message.items;
-
- // Populate the model that drives the radio buttons.
- // Radio buttons require a model with the value of the button
- // that is selected. The data comes across with a boolean
- // indicator on each row, selected or not, which is useless
- // for driving the radio buttons. This model uses the URL
- // as the unique value.
- $scope.ecdapp.radiobutton = {
- url : null
- };
- for (var rowNum in message.items) {
- let row = message.items[rowNum];
- if (debug)
- $log.debug('selectEcompcController: row is ' + JSON.stringify(row));
- if (row.selected)
- $scope.ecdapp.radiobutton.url = row.url;
- }
-
- /**
- * Handles a click on radio button to select a controller.
- */
- $scope.ecdapp.selectController = function(row) {
- if (debug)
- $log.debug('selectController: row is ' + JSON.stringify(row));
- if (row == null || row.url == null)
- $log.error('selectController invoked with bad argument');
- else
- ControllerService.setControllerSelection(row).then(function(data) {
- $rootScope.$broadcast('controllerChange', {name: row.name})
- },
- function(error) {
- $log.error('selectController failed: ' + error);
- });
- };
-
-});
diff --git a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/home/oom-router.js b/ccsdk-app-overlay/src/main/webapp/app/ccsdk/home/oom-router.js
deleted file mode 100644
index 0b43341..0000000
--- a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/home/oom-router.js
+++ /dev/null
@@ -1,97 +0,0 @@
-/*******************************************************************************
- * =============LICENSE_START=========================================================
- *
- * =================================================================================
- * Copyright (c) 2020 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file 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.
- * ============LICENSE_END=========================================================
- *
- *******************************************************************************/
-appDS2.config(function($routeProvider) {
- $routeProvider
- .when('/api', {
- templateUrl: 'app/ccsdk/home/api_doc.html',
- controller : ''
- })
- .when('/api-spec', {
- templateUrl: 'app/ccsdk/home/rest-api-spec.html',
- controller : 'apiDocsController'
- })
- .when('/ibp', {
- templateUrl: 'app/ccsdk/inventory/inventory_blueprint_table.html',
- controller : 'inventoryBlueprintTableController'
- })
- .when('/idep', {
- templateUrl: 'app/ccsdk/inventory/inventory_deployment_table.html',
- controller : 'inventoryDeploymentTableController'
- })
- .when('/idep/:depId', {
- templateUrl: 'app/ccsdk/inventory/inventory_deployment_table.html',
- controller : 'inventoryDeploymentTableController'
- })
- .when('/sh', {
- templateUrl: 'app/ccsdk/consul/service_health_table.html',
- controller : 'serviceHealthTableController'
- })
- .when('/nh', {
- templateUrl: 'app/ccsdk/consul/node_table.html',
- controller : 'nodeTableController'
- })
- .when('/dc', {
- templateUrl: 'app/ccsdk/consul/datacenter_table.html',
- controller : 'datacenterTableController'
- })
- .when('/profile/:profileId', {
- templateUrl: 'app/fusion/scripts/DS2-view-models/ds2-profile/self_profile.html',
- controller: 'selfProfileController'
- })
- .when('/profile_search', {
- templateUrl: 'app/fusion/scripts/DS2-view-models/ds2-profile/profile_searchDS2.html',
- controller : "profileSearchCtrlDS2"
- })
- .when('/post_search', {
- templateUrl: 'app/fusion/scripts/DS2-view-models/ds2-profile/post.html',
- controller: 'postController'
- })
- .when('/self_profile', {
- templateUrl: 'app/fusion/scripts/DS2-view-models/ds2-profile/self_profile.html',
- controller: 'selfProfileController'
- })
- .when('/role_list', {
- templateUrl: 'app/fusion/scripts/DS2-view-models/ds2-admin/role_list.html',
- controller : 'adminController'
- })
- .when('/role_function_list', {
- templateUrl: 'app/fusion/scripts/DS2-view-models/ds2-admin/role-function.html',
- controller : "adminController"
- })
- .when('/jcs_admin', {
- templateUrl: 'app/fusion/scripts/DS2-view-models/ds2-admin/jcs_admin.html',
- controller: 'adminController'
- })
- .when('/admin_menu_edit', {
- templateUrl: 'app/fusion/scripts/DS2-view-models/ds2-admin/admin-menu-edit.html',
- controller: 'AdminMenuEditController'
- })
- .when('/usage_list', {
- templateUrl: 'app/fusion/scripts/DS2-view-models/ds2-admin/usage.html',
- controller: 'usageListControllerDS2'
- })
- .otherwise({
- templateUrl: 'app/ccsdk/home/executions_view.html',
- controller : 'executionsViewController'
- })
- ;
-
-}); \ No newline at end of file
diff --git a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/home/oom-style.css b/ccsdk-app-overlay/src/main/webapp/app/ccsdk/home/oom-style.css
deleted file mode 100644
index a4e9a97..0000000
--- a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/home/oom-style.css
+++ /dev/null
@@ -1,301 +0,0 @@
-/* Styles for ECOMP Controller Dashboard */
-
-.content-container {
- min-height: 650px;
- width: calc(100% - 50px);
-}
-
-.ecd-error-message {
- font-size: 14px;
- font-weight: bold;
- color: red;
-}
-
-.ecd-icon-display {
- font-size: 18px;
-}
-
-.ecd-icon-action {
- font-size: 18px;
-}
-
-.ecd-icon-action:hover {
- color: red;
- text-decoration: none;
-}
-
-.selected {
- background-color:black;
- color:white;
- font-weight:bold;
-}
-.red-background {
- background-color: #ff0000b3;
- }
-.green-background {
- background-color: #bbf0bb;
- }
-.td-error {
- border-top: 5px dotted red;
- border-bottom: 5px dotted red;
- }
-.menu {
- display: none;
- z-index: 1000;
- border: 1px dotted;
- border-radius: 5px;
- padding: 10px;
- width: 50%;
- background: azure;
- position: fixed;
- overflow: scroll;
-}
-
-.show-menu {
- z-index: 800;
-}
-
-#show-menu {
- display: none;
-}
-
-#show-menu:checked ~ .menu {
- display: block;
-}
-
-#show-menu:checked ~ .show-menu {
- color: blue;
-}
-
-.menu-off {
- position: fixed;
- left: 0;
- right: 0;
- top: 0;
- bottom: 0;
- z-index: 700;
- display: none;
-}
-
-.menu-off {
- display: none;
-}
-
-#show-menu:checked ~ .menu-off {
- display: block;
-}
-
-#show-menu:checked ~ .show-menu {
- display: none;
-}
-
-.menu-off input[type=checkbox]:checked ~ .menu {
- display: none;
-}
-
-.menu-off input[type=checkbox]:checked ~ .show-menu {
- display: block;
-}
-
-td > .btn-group {
- min-width: 0;
- width: auto;
-}
-
-.dropup,
-.dropdown {
- position: relative;
-}
-.dropdown-toggle:focus {
- outline: 0;
-}
-.dropdown-menu {
- position: absolute;
- top: 100%;
- left: 0;
- z-index: 1000;
- display: none;
- float: left;
- min-width: 160px;
- padding: 5px 0;
- margin: 2px 0 0;
- font-size: 14px;
- text-align: left;
- list-style: none;
- background-color: #fff;
- -webkit-background-clip: padding-box;
- background-clip: padding-box;
- border: 1px solid #ccc;
- border: 1px solid rgba(0, 0, 0, .15);
- border-radius: 4px;
- -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, .175);
- box-shadow: 0 6px 12px rgba(0, 0, 0, .175);
-}
-.dropdown-menu.pull-right {
- right: 0;
- left: auto;
-}
-.dropdown-menu .divider {
- height: 1px;
- margin: 9px 0;
- overflow: hidden;
- background-color: #e5e5e5;
-}
-.dropdown-menu > li > a {
- display: block;
- padding: 3px 20px;
- clear: both;
- font-weight: normal;
- line-height: 1.42857143;
- color: #333;
- white-space: nowrap;
-}
-.dropdown-menu > li > a:hover,
-.dropdown-menu > li > a:focus {
- color: #262626;
- text-decoration: none;
- background-color: #f5f5f5;
-}
-.dropdown-menu > .active > a,
-.dropdown-menu > .active > a:hover,
-.dropdown-menu > .active > a:focus {
- color: #fff;
- text-decoration: none;
- background-color: #337ab7;
- outline: 0;
-}
-.dropdown-menu > .disabled > a,
-.dropdown-menu > .disabled > a:hover,
-.dropdown-menu > .disabled > a:focus {
- color: #777;
-}
-.dropdown-menu > .disabled > a:hover,
-.dropdown-menu > .disabled > a:focus {
- text-decoration: none;
- cursor: not-allowed;
- background-color: transparent;
- background-image: none;
- filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
-}
-.open > .dropdown-menu {
- display: block;
-}
-.open > a {
- outline: 0;
-}
-.dropdown-menu-right {
- right: 0;
- left: auto;
-}
-.dropdown-menu-left {
- right: auto;
- left: 0;
-}
-.dropdown-header {
- display: block;
- padding: 3px 20px;
- font-size: 12px;
- line-height: 1.42857143;
- color: #777;
- white-space: nowrap;
-}
-.dropdown-backdrop {
- position: fixed;
- top: 0;
- right: 0;
- bottom: 0;
- left: 0;
- z-index: 990;
-}
-.pull-right > .dropdown-menu {
- right: 0;
- left: auto;
-}
-.dropup .caret,
-.navbar-fixed-bottom .dropdown .caret {
- content: "";
- border-top: 0;
- border-bottom: 4px dashed;
- border-bottom: 4px solid \9;
-}
-.dropup .dropdown-menu,
-.navbar-fixed-bottom .dropdown .dropdown-menu {
- top: auto;
- bottom: 100%;
- margin-bottom: 2px;
-}
-@media (min-width: 768px) {
- .navbar-right .dropdown-menu {
- right: 0;
- left: auto;
- }
- .navbar-right .dropdown-menu-left {
- right: auto;
- left: 0;
- }
-}
-
-.dropdown-menu li {
- margin-bottom: 10px;
-}
-
-.dropdown-menu li div {
- padding-left: 5px;
-}
-
-.dropdown-menu li div i {
- margin-right: 5px;
-}
-
-td > .btn-group > .btn {
- min-width: 0;
- color: #0568ae;
-}
-
-td > .btn-group > .btn> i {
- font-size: 30px;
-}
-
-li > a.active {
- font-weight: bolder;
- outline: thin dotted #666;
-}
-
-tr:hover {
- background-color: #f2f2f2;
-}
-
-tr:focus {
- background-color: #f2f2f2;
-}
-
-.modalwrapper.modal-docked .modal-jumbo {
- max-height: 100%;
- height: 100%;
- overflow: hidden;
- top: 0;
- width: 100%;
- max-width: 100%;
-}
-
-#addAppDiv {
- padding-left: 10px;
- background: lightgray;
- border-radius: 5px;
- padding-bottom: 15px;
-}
-
-.field-group.error .error-msg {
- color: red;
- display: block;
- font-size: 14px;
- line-height: 14px;
- font-family: "Omnes-ATT-W02-Medium";
- position: relative;
- padding-left: 18px;
- margin-top: 10px;
-}
-
-.heading-page {
- margin-bottom: 20px;
-}
diff --git a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/home/oom_instances_popup.html b/ccsdk-app-overlay/src/main/webapp/app/ccsdk/home/oom_instances_popup.html
deleted file mode 100644
index bc523aa..0000000
--- a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/home/oom_instances_popup.html
+++ /dev/null
@@ -1,86 +0,0 @@
-<script type="text/ng-template" id="ecompc_instances_popup.html">
-<style>
- .ecd-parameter-table
- {
- border: 1px;
- width: 550px;
- height: 225px;
- overflow: auto;
- }
- .modal
- {
- display:block
- }
- .radio input:checked + .skin:after{
- height: 22px;
- width: 22px;
- }
- .close-button
- {
- background: #0568ae;
- color: #ffffff;";
- }
-
-</style>
-
- <div class="b2b-modal-header ng-scope">
- <h1 class="heading-page" id="controllerInstance">Select ECOMP-C Instance</h1>
- <div class="corner-button in">
- <button type="button" class="close" aria-label="Close"
- ng-click="$dismiss('cancel')"></button>
- </div>
- </div>
-
- <div class="b2b-modal-body ng-scope ng-isolate-scope" tabindex="0"
- role="region" aria-label="Modal body content">
-
- <div b2b-table
- id="controllers-modal"
- class="b2b-table-div"
- table-data="ecdapp.tableData"
- search-string="ecdapp.searchString"
- current-page="ecdapp.currentPageIgnored"
- next-sort="ecdapp.nextSortIgnored">
- <table>
- <thead b2b-table-row type="header">
- <tr id="th-header-row">
- <th b2b-table-header sortable="false">Selected</th>
- <th b2b-table-header key="name">Name</th>
- <th b2b-table-header key="url">URL</th>
- </tr>
- </thead>
-
- <tbody b2b-table-row type="body" row-repeat="rowData in ecdapp.tableData">
- <tr id="tr-rowData">
- <td b2b-table-body>
- <label class="radio">
- <input
- type="radio"
- name="ecdSelGroup"
- title="rowData.url"
- ng-value="rowData.url"
- ng-model="ecdapp.radiobutton.url"
- ng-change="ecdapp.selectController(rowData);">
- <i class="skin"></i>
- <span></span>
- </label>
- </td>
- <td b2b-table-body
- ng-bind="rowData.name"/>
- <td b2b-table-body
- ng-bind="rowData.url"/>
- </tr>
- </tbody>
- </table>
- </div>
- </div>
-
- <div class="b2b-modal-footer ng-scope ng-isolate-scope">
- <div class="cta-button-group in">
- <button class="btn btn-small close-button" type="button" ng-click="$close()">
- Close
- </button>
- </div>
- </div>
-
-</script>
diff --git a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/home/oom_spa.html b/ccsdk-app-overlay/src/main/webapp/app/ccsdk/home/oom_spa.html
deleted file mode 100644
index fabb450..0000000
--- a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/home/oom_spa.html
+++ /dev/null
@@ -1,164 +0,0 @@
-<!--
- ============LICENSE_START==========================================
- ===================================================================
- Copyright (C) 2020 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.
-
- ============LICENSE_END============================================
- -->
-
-<!DOCTYPE html>
-<!-- DCAE Dashboard single-page application using B2B/DS2. -->
-<html>
- <head>
- <meta charset="UTF-8">
- <title>DCAE Dashboard</title>
- <link rel="icon" type="image/ico" href="app/ccsdk/images/onap_32x32.ico" />
-
- <!-- Third-party scripts from EPSDK overlay -->
- <script src="app/fusion/external/angular-1.4.13/angular.js"></script>
- <script src="app/fusion/external/angular-1.4.13/angular-cookies.js"></script>
- <script src="app/fusion/external/angular-1.4.13/angular-messages.js"></script>
- <script src="app/fusion/external/angular-1.4.13/angular-route.js"></script>
- <script src="app/fusion/external/angular-1.4.13/angular-sanitize.js"></script>
- <script src="app/fusion/external/angular-1.4.13/angular-touch.js"></script>
- <script src="app/fusion/external/jquery/dist/jquery.min.js"></script>
- <!--<script src="app/fusion/external/javascript-detect-element-resize/jquery.resize.js"></script>-->
- <script src="app/fusion/external/angular-bootstrap/ui-bootstrap-tpls.min.js"></script>
-
- <!-- Third-party scripts from app -->
- <!-- https://github.com/jeremyfa/yaml.js -->
- <script src="app/ccsdk/external/bootstrap.min.js" type="text/javascript"></script>
- <script src="app/ccsdk/external/yaml.js" type="text/javascript"></script>
-
- <script src="app/fusion/external/b2b/js/b2b-angular/b2b-library.js"></script>
- <!-- Tweaked CSS -->
- <link rel="stylesheet" type="text/css" href="app/fusion/external/b2b/css/b2b-angular/b2b-angular.css">
- <link rel="stylesheet" type="text/css" href="app/fusion/external/b2b/css/b2b-angular/font_icons.css">
-
- <!-- icons in open source -->
- <link rel="stylesheet" type="text/css" href="app/fusion/external/ds2/css/digital-ng-library/ionicons.css">
- <link rel="stylesheet" type="text/css" href="app/fusion/external/ds2/css/digital-ng-library/ecomp-ionicons.css">
-
- <link rel="stylesheet" type="text/css" href="app/fusion/styles/ecomp.css">
-
- <!-- main app -->
- <script src="app/ccsdk/home/modal-service.js"></script>
- <script src="app/ccsdk/home/appDS2.js"></script>
-
- <!-- directives and services -->
- <script src="app/fusion/scripts/DS2-services/userInfoServiceDS2.js"></script>
- <script src="app/fusion/scripts/DS2-services/headerServiceDS2.js"></script>
- <script src="app/fusion/scripts/DS2-services/manifestService.js"></script>
- <script src="app/fusion/scripts/DS2-directives/footer.js"></script>
- <script src="app/fusion/scripts/DS2-directives/ds2Header.js"></script>
- <script src="app/fusion/scripts/DS2-services/leftMenuServiceDS2.js"></script>
- <script src="app/fusion/scripts/DS2-directives/ds2LeftMenu.js"></script>
- <script src="app/fusion/scripts/DS2-directives/b2b-leftnav-ext.js"></script>
-
- <!-- OOM home -->
- <script src="app/ccsdk/home/controller-service.js"></script>
- <script src="app/ccsdk/home/executions-view-controller.js"></script>
- <script src="app/ccsdk/home/api-docs-controller.js"></script>
- <!--
- <script src="app/ccsdk/home/tree-view-controller.js"></script>
- <script src="app/ccsdk/home/tree-view-directive.js"></script>
- <script src="app/ccsdk/home/oom-instances-controller.js"></script>
- <script src="app/ccsdk/home/http-interceptor.js"></script>
- -->
- <link rel="stylesheet" href="app/ccsdk/home/tree-view-style.css"/>
- <link rel="stylesheet" href="app/ccsdk/home/oom-style.css"/>
-
- <!-- Cloudify -->
- <script src="app/ccsdk/cloudify/blueprint-service.js"></script>
- <script src="app/ccsdk/cloudify/deployment-service.js"></script>
- <script src="app/ccsdk/cloudify/execution-service.js"></script>
- <script src="app/ccsdk/cloudify/tosca-table-controller.js"></script>
- <script src="app/ccsdk/cloudify/blueprint-controllers.js"></script>
- <script src="app/ccsdk/cloudify/deployment-controllers.js"></script>
- <script src="app/ccsdk/cloudify/execution-table-controller.js"></script>
-
- <!--Inventory-->
- <script src="app/ccsdk/inventory/blueprint-service.js"></script>
- <script src="app/ccsdk/inventory/deployment-service.js"></script>
- <script src="app/ccsdk/inventory/execution-service.js"></script>
- <script src="app/ccsdk/inventory/blueprint-controllers.js"></script>
- <script src="app/ccsdk/inventory/deployment-controllers.js"></script>
-
- <!-- Consul -->
- <script src="app/ccsdk/consul/service-health-service.js"></script>
- <script src="app/ccsdk/consul/service-controllers.js"></script>
- <script src="app/ccsdk/consul/node-table-controller.js"></script>
- <script src="app/ccsdk/consul/node-health-service.js"></script>
- <script src="app/ccsdk/consul/node-services-controller.js"></script>
- <script src="app/ccsdk/consul/datacenter-table-controller.js"></script>
- <script src="app/ccsdk/consul/datacenter-health-service.js"></script>
-
- <!-- Ops -->
- <script src="app/ccsdk/ops/tabs-view-controller.js"></script>
-
- <!-- user admin pages -->
- <script src="app/fusion/scripts/DS2-services/adminService.js"></script>
- <script src="app/fusion/scripts/DS2-services/ds2-profile/selfProfileService.js"></script>
- <script src="app/fusion/scripts/DS2-services/profileServiceDS2.js"></script>
- <script src="app/fusion/scripts/DS2-controllers/ds-profile/post-controller.js"></script>
- <script src="app/fusion/scripts/DS2-controllers/ds2-profile/self-profile-controller.js"></script>
- <script src="app/fusion/scripts/DS2-services/postSearch.js"></script>
- <script src="app/fusion/scripts/DS2-controllers/profile-search-controller-DS2.js"></script>
-
- <!-- app admin pages -->
- <script src="app/fusion/scripts/DS2-services/adminMenuService.js"></script>
- <script src="app/fusion/scripts/DS2-controllers/admin-controller.js"></script>
- <script src="app/fusion/scripts/DS2-controllers/admin-menu-edit.js"></script>
- <script src="app/fusion/scripts/DS2-controllers/usage-list-controller.js"></script>
- <script src="app/fusion/scripts/DS2-controllers/fn-menu-add-popup-controller.js"></script>
-
- <!-- main page -->
- <script src="app/ccsdk/home/oom-router.js"></script>
-
- <style>
- .csep-root1{
- background: white;
- }
- .dropdown-submenu {
- position: relative;
- }
-
- .dropdown-submenu .dropdown-menu {
- top: 0;
- left: 100%;
- margin-top: -1px;
- }
- </style>
-
- </head>
- <body class="appBody" ng-app="abs">
- <!-- double quotation marks are required for the popup templates - values are string literals -->
- <div ng-include src="'app/ccsdk/home/oom_popup_templates.html'"></div>
- <div ng-include src="'app/ccsdk/home/oom_instances_popup.html'"></div>
- <div ng-include src="'app/ccsdk/cloudify/blueprint_popups.html'"></div>
- <div ng-include src="'app/ccsdk/cloudify/deployment_popups.html'"></div>
- <div ng-include src="'app/ccsdk/inventory/inventory_blueprint_popups.html'"></div>
- <div ng-include src="'app/ccsdk/inventory/inventory_deployment_popups.html'"></div>
- <div ng-include src="'app/ccsdk/inventory/inventory_execution_popups.html'"></div>
- <div ng-include src="'app/ccsdk/consul/service_popups.html'"></div>
- <div ng-include src="'app/ccsdk/consul/node_popups.html'"></div>
- <div ds2-header id="header" class="header-container"></div>
- <div ds2-menu id="menu-container" class="menu-container"></div>
- <div ng-view id="rightContentProfile" class="content-container"></div>
- <div ds2-footer class="footer-container"></div>
- </body>
-</html>
diff --git a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/home/tree-view-controller.js b/ccsdk-app-overlay/src/main/webapp/app/ccsdk/home/tree-view-controller.js
deleted file mode 100644
index 99005fb..0000000
--- a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/home/tree-view-controller.js
+++ /dev/null
@@ -1,113 +0,0 @@
-appDS2.controller('treeViewController',function(
- $scope, $rootScope, $log, $modal, ExecutionService, ControllerService){
-
- 'use strict';
-
- // Set to true for verbose output
- var debug = false;
-
- // this object holds all app data and functions
- $scope.ecdapp = {};
- $scope.ecdapp.isDataLoading = false;
- $scope.ecdapp.isRequestFailed = false;
- $scope.orgChart = true;
- $scope.status = '';
- var selectedItem = {
- name: ''
- };
- // Initial data as eye candy
- $scope.orgChartData = [ { 'blueprint_id': 'Root', 'parent': 'parent' } ];
- var controllersList = [];
-
- var getControllers = function(){
- ControllerService.getControllers().then(function(jsonObj) {
- if (debug)
- $log.debug("treeViewController.getControllers succeeded: " + JSON.stringify(jsonObj));
- // Empty
- controllersList.length = 0;
- // Refill
- jsonObj.filter(function(d) {
- controllersList.push(d);
- if (d.selected)
- selectedItem = d;
- return;
- });
- $scope.ecdapp.loadTable();
- }, function(error) {
- alert('Failed to load controllers. Please retry.');
- $log.error("treeViewController.getControllers failed: " + error);
- });
- }
-
- /**
- * Called from the directive when user picks a status value.
- */
- $scope.ecdapp.loadTable = function(status) {
- $scope.ecdapp.isDataLoading = true;
- $scope.status = status;
- // Empty list and create the root controller item
- $scope.orgChartData.length = 0;
- $scope.orgChartData.push({
- "blueprint_id": selectedItem.name,
- "parent": "parent"
- });
- ExecutionService.getExecutionsByStatus(status).then(
- function(jsonObj) {
- if (jsonObj.error) {
- $log.error("treeViewController.loadTable failed: "
- + jsonObj.error);
- $scope.ecdapp.isRequestFailed = true;
- $scope.ecdapp.errMsg = jsonObj.error;
- } else {
- $scope.ecdapp.isRequestFailed = false;
- $scope.ecdapp.errMsg = null;
- for (var i=0; i < jsonObj.items.length; i++) {
- $scope.orgChartData.push(jsonObj.items[i]);
- }
- $scope.$broadcast('listenEvent', {data: $scope.orgChartData} );
- }
- $scope.ecdapp.isDataLoading = false;
- },
- function(error) {
- $log.error("treeViewController.loadTable failed: "
- + error);
- $scope.ecdapp.isRequestFailed = true;
- $scope.ecdapp.errMsg = error;
- $scope.ecdapp.isDataLoading = false;
- });
- };
-
- // Listens for change of the selected controller
- $rootScope.$on('controllerChange', function(e, d){
- $scope.orgChartData[0].blueprint_id = d.name;
- $scope.$broadcast('listenEvent', {data: $scope.orgChartData});
- })
-
- // Shows popup with list of controllers
- $scope.ecdapp.showEcompCInstancesModalPopup = function() {
- var modalInstance = $modal.open({
- templateUrl : 'ecompc_instances_popup.html',
- controller : 'selectEcompcController',
- windowClass: 'modal-docked',
- sizeClass: 'modal-medium',
- resolve : {
- message : function() {
- return { items: controllersList }
- }
- }
- });
- modalInstance.result.then(function(response) {
- // Always reload the table
- // $log.debug('modalInstance: reloading controllers');
- getControllers('active');
- },
- function(error) {
- // Should never happen
- $log.error('modalInstance: ERROR!?');
- });
- };
-
- // Populate the table on load.
- getControllers('active');
-
-});
diff --git a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/home/tree-view-directive.js b/ccsdk-app-overlay/src/main/webapp/app/ccsdk/home/tree-view-directive.js
deleted file mode 100644
index 834026b..0000000
--- a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/home/tree-view-directive.js
+++ /dev/null
@@ -1,165 +0,0 @@
-(function() {
- 'use strict';
-
- appDS2.directive("orgChart", supervisorOrgChart);
- supervisorOrgChart.$inject = ['$http', '$templateCache', 'ExecutionService'];
-
- function supervisorOrgChart($http, $templateCache, ExecutionService) {
- return {
- restrict: 'E',
- scope: {
- data: '=',
- getCall: '&',
- modalCall: '&',
- status: '='
- },
-
- link: function(scope, elem, attrs) {
-
- scope.$on('listenEvent', function(event, data) {
- data = data.data;
- scope.data = data;
- $('.jOrgChart').remove();
- drawOrgChart(data);
- });
-
-
- var items = [],
- mCheck = [];
- var currentZoom = 100;
- var data = scope.data;
- var selectedStatus = scope.status;
- function statusSelectoin(status){
- $('#statusclick li').removeClass('active');
- scope.getCall()(status);
- }
-
- function drawOrgChart(data, supervisorOrg) {
- items = [];
- var itemHtml = "";
- for(var i=0; i<data.length; i++){
- loops(data[i]);
- }
- function loops(root) {
- var className;
- if (root.parent == "parent") {
- items.push("<li class='root '>" +
- "<div><div class='label_node' style='position:relative'>" +
- "<span class='' style='position:absolute; left:1px; top:5px'>"+
- "<div class='dropdown dd_"+root.id+"'>"+
- "<div style='float: right;'>"+
- "<button id='dd_"+root.id+"' class='btn btn-default dropdown-toggle icon-misc-filter' type='button' data-toggle='dropdown'>"+
- "</button>"+
- "<ul class='dropdown-menu' id='statusclick'>"+
- "<li id='active'>Active</li>"+
- "<li id='cancelled'>Cancelled</li>"+
- "<li id='terminated'>Terminated</li>"+
- "<li id='failed'>Failed</li>"+
- "</ul>"+
- "</div>"+
- "</div>"+
- "</span>"+
- "<span style='position: absolute; font-size: 12px; left:30px; top:10px' class='title-span'>" + root.blueprint_id + "</span>"+
- "<button id='dd_"+root.id+"' style='margin-top: 5px; position: absolute; right: 2px;' class='openmodal btn btn-default dropdown-toggle icon-controls-gear' " +
- "type='button' data-toggle='dropdown'>"+
- "</button>"+
- "</div></div></br>"+
- "<div style='padding-top:25px'><img src='app/ecdapp/images/ecomp-login-550x360.jpg' width='180' height='100'></div>"+
- "<div class='expandBtn'><span id='exp_"+root.id+"'><i class='icon-controls-add-maximize'></i></span></div><ul>");
- } else {
- itemHtml = "<li class='child'>"+
- "<div style='padding-top:3px'><span class='label_node'>"+
-
- "<span class='title-span'>" + root.blueprint_id + "</span>"+
- "<span class='icon-span ddIcon'>"+
- "<div class='dropdown dd_"+root.id+"'>"+
- "<div style='float: right; margin-top: -14px;'>"+
- "<button id='dd_"+root.id+"' class='btn btn-default dropdown-toggle' type='button' data-toggle='dropdown'><i class='icon-people-preview'></i>"+
- "<span id='dd_"+root.id+"'></span></button>"+
- "<ul class='dropdown-menu'>"+
- "<li><a tabindex='-1' href='javascript:void(0);'>Execution Id: " + root.id + "</a></li>"+
- "<li><a tabindex='-1' href='javascript:void(0);'>Health Check Status: </a></li>"+
- "<li><a tabindex='-1' href='javascript:void(0);'>Please click here for more information </a></li>"+
- "</ul>"+
- "</div>"+
- "</div>"+
- "</span>"+
- "</span></div></br>"+
- "<div style='padding-top:35px'><img src='app/ecdapp/images/ecomp.png' width='180' height='100'></div></li>";
- items.push(itemHtml);
- }
- } // End the generate html code
-
- items.push('</ul></li>');
- var listElem = $("<ul/>", {
- "class": "org",
- "style": "float:right;",
- html: items.join("")
- }).appendTo(elem);
-
- var opts = {
- chartElement: elem,
- rowcolor: false
- };
- //elem.html('');
- $(elem).find(".org").jOrgChart(opts);
- listElem.remove();
-
- setTimeout(function(){
- $('.dropdown .dropdown-toggle').on("click", function(e){
- var cls = '.'+ e.target.id;
- var subcls = cls + ' a.test';
- if($(cls).hasClass('open')){
- $(cls).removeClass('open');
- $(subcls).next('ul').css({display: 'none'});
- } else{
- $(cls).addClass('open');
- }
- });
-
- $('.dropdown-submenu a.test').on("mouseover", function(e){
- console.log("hi");
- $('#'+e.target.id).next('ul').toggle();
- });
-
- $('#statusclick li').click(function(event){
- statusSelectoin(event.target.id);
- })
-
- $('.openmodal').click(function(event){
- openModal();
- })
-
- $(document).on('click','.expandBtn', function(event, data) {
- event.stopImmediatePropagation()
- var $this = $(this);
- var $tr = $this.closest("tr");
- if ($tr.hasClass('contracted')) {
- $(this).addClass('fa-minus').removeClass('fa-plus');
- $tr.removeClass('contracted').addClass('expanded');
- $tr.nextAll("tr").css('visibility', '');
- } else {
- $(this).addClass('fa-plus').removeClass('fa-minus');
- $tr.removeClass('expanded').addClass('contracted');
- $tr.nextAll("tr").css('visibility', 'hidden');
- }
- });
-
- var selectedStatus = scope.status;
- if(selectedStatus){
- $('#'+selectedStatus).addClass('active');
- }
-
- function openModal(){
- scope.modalCall()();
- }
-
- },0);
- }
-
- drawOrgChart(data);
-
- },
- };
- };
-})(); \ No newline at end of file
diff --git a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/home/tree-view-style.css b/ccsdk-app-overlay/src/main/webapp/app/ccsdk/home/tree-view-style.css
deleted file mode 100644
index 5a3e056..0000000
--- a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/home/tree-view-style.css
+++ /dev/null
@@ -1,132 +0,0 @@
-/* Basic styling */
-
-::-webkit-scrollbar
-{
- width: 12px; /* for vertical scrollbars */
- height: 7px; /* for horizontal scrollbars */
-}
-
-::-webkit-scrollbar-track
-{
- background: rgba(0, 0, 0, 0.1);
-}
-
-::-webkit-scrollbar-thumb
-{
- background: rgba(0, 0, 0, 0.5);
-}
-
-.orgChart .label_node{
- padding-bottom: 5px;
-}
-
-.orgChart .icon-span{
- float:left;width:25px;
- padding-top: 3px;
-}
-.orgChart .title-span{
- width:110px;float:left; font-size:14px;
- padding-top: 3px;
-}
-
-/* Draw the lines */
-.jOrgChart{
- position: relative;
- /* left: 245px; */
- width:100%;
- min-width: 100%;
- overflow-x: auto;
-
-}
-.jOrgChart .line {
- height : 20px;
- width : 4px;
-}
-
-.jOrgChart .down {
- background-color : black;
- margin : 0px auto;
-}
-
-.jOrgChart .top {
- border-top : 3px solid black;
-}
-
-.jOrgChart button{
- min-width : 20px;
- width : 20px;
- height : 20px;
- padding : 0;
-}
-
-.jOrgChart .dropdown{
- display: inline-block;
-}
-
-.jOrgChart .downloadIcon{
- position: relative;
- left: 1px;
- float:left;
-}
-
-.jOrgChart .ddIcon{
- position: relative;
- float: right;
- top: 6px;
-}
-
-.jOrgChart .left {
- border-right : 2px solid black;
-}
-
-.jOrgChart .right {
- border-left : 2px solid black;
-}
-
-/* node cell */
-.jOrgChart td {
- text-align : center;
- vertical-align : top;
- padding : 0 !important;
- border : none;
- border-bottom : 1px solid white;
-}
-
-/* The node */
-.jOrgChart .node {
- background-color : #efefef;
- display : inline-block;
- width : 180px;
- height : 200px;
- z-index : 10;
- margin : 0 2px;
-}
-
-.expandBtn {
- background-color: #efefef;
- padding-top:9px;
-}
-
-/* jQuery drag 'n drop */
-
-.drag-active {
- border-style : dotted !important;
-}
-
-.drop-hover {
- border-style : solid !important;
- border-color : #E05E00 !important;
-}
-
-#statusclick{
- padding: 0 !important
-}
-
-#statusclick li {
- padding :5px;
-}
-
-#statusclick li.active{
- background: #337ab7;
- color: white;
-} \ No newline at end of file
diff --git a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/home/tree_view.html b/ccsdk-app-overlay/src/main/webapp/app/ccsdk/home/tree_view.html
deleted file mode 100644
index d5364e8..0000000
--- a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/home/tree_view.html
+++ /dev/null
@@ -1,24 +0,0 @@
-<!-- Included bootstrap files at a page level to avoid issues with DS2 library -->
-<script src="app/ecdapp/external/bootstrap.min.js"></script>
-<link rel="stylesheet" href="app/ecdapp/external/bootstrap.min.css"/>
-
-<div id="page-content">
-
- <org-chart data=orgChartData status="status" showOrgTable="showOrgTable" get-call="ecdapp.loadTable" modal-call="ecdapp.showEcompCInstancesModalPopup">
- </org-chart>
- <div ng-show="ecdapp.isDataLoading">
- <div class="text-center" style="margin-bottom:20px;">
- <i class="icon-spinner small" role="img" aria-label="Please wait while the content loads"></i>
- Please wait while the content loads.
- </div>
- </div>
- <div ng-hide="ecdapp.isDataLoading">
- <div ng-if="orgChartData.length == 1" class="col-xs-12 text-center" style="position:relative;">
- <b>No components found</b>
- </div>
- </div>
- <div ng-show="ecdapp.isRequestFailed">
- <span class="ecd-error-message">{{ecdapp.errMsg}}</span>
- </div>
-
-</div>
diff --git a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/inventory/blueprint-controllers.js b/ccsdk-app-overlay/src/main/webapp/app/ccsdk/inventory/blueprint-controllers.js
index fceab0e..b474348 100644
--- a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/inventory/blueprint-controllers.js
+++ b/ccsdk-app-overlay/src/main/webapp/app/ccsdk/inventory/blueprint-controllers.js
@@ -1,1037 +1,1329 @@
appDS2.controller('inventoryBlueprintTableController', function(
- $rootScope, $scope, $log, $modal, modalService, InventoryBlueprintService, InventoryDeploymentService) {
-
- 'use strict';
-
- // Controls logging in this controller
- var debug = false;
-
- // this object holds all app data and functions
- $scope.ecdapp = {};
- // models for controls on screen
- $scope.ecdapp.tableData = [];
- $scope.ecdapp.currentPageNum = 1;
- $scope.ecdapp.viewPerPage = 10;
- // other
- $scope.ecdapp.errMsg = null;
- $scope.ecdapp.isDataLoading = true;
- $scope.ecdapp.isRequestFailed = false;
- // sorting
- $scope.ecdapp.sortBy = null;
- // searching
- $scope.ecdapp.searchBy = null;
-
- $scope.ecdapp.trackBpRowIndex = function(indx) {
- $scope.ecdapp.tableData[indx].expanded = !$scope.ecdapp.tableData[indx].expanded;
- };
-
- $scope.ecdapp.updateTable = function() {
- $scope.ecdapp.isSrvcDataLoading = true;
- var srvcTypIds = [];
- var srvcIds = [];
- var bpDepls =[];
- var cloneGrid = $scope.ecdapp.tableData;
- angular.forEach($scope.ecdapp.tableData, function(item, index) {
- angular.forEach(item, function(value, key) {
- if (key === "typeId") {
- srvcTypIds.push(value);
- }
- });
- });
-
- InventoryBlueprintService.getDeploymentForBp(srvcTypIds)
- .then(function(jsonObj) {
- if (jsonObj.error) {
- $log.error("inventoryBlueprintController.updateTable failed: " + jsonObj.error);
- } else {
- bpDepls = jsonObj;
- for (var typIndx = 0; typIndx < bpDepls.length; typIndx++) {
- srvcIds.push(bpDepls[typIndx].serviceRefList);
- }
- angular.forEach(cloneGrid, function(item, index) {
- item.deployments = srvcIds[index];
- item.expanded = false;
- });
- $scope.ecdapp.tableData = cloneGrid;
- }
- $scope.ecdapp.isSrvcDataLoading = false;
- }, function(error) {
- $log.error("inventoryBlueprintController.updateTable failed: " + error);
- bpDepls = [];
- $scope.ecdapp.isSrvcDataLoading = false;
- });
-
- }
-
- $scope.ecdapp.JSONToCSVConverter = function(blueprint)
- {
- var array = typeof blueprint != 'object' ? JSON.parse(blueprint) : blueprint;
- var str = '';
- for (var i = 0; i < array.length; i++) {
- var line = '';
-
- for (var index in array[i]) {
- line += array[i][index] + ',';
+ $rootScope, $scope, $log, $modal, modalService, ControllerService, $interval, $routeParams,
+ InventoryBlueprintService, InventoryDeploymentService, localStorageService) {
+
+ 'use strict';
+
+ // Controls logging in this controller
+ var debug = false;
+ var stop;
+
+ // this object holds all app data and functions
+ $scope.ecdapp = {};
+ // models for controls on screen
+ $scope.ecdapp.tableData = [];
+ $scope.ecdapp.currentPage = 1;
+ $scope.ecdapp.viewPerPage = 10;
+ // other
+ $scope.ecdapp.errMsg = null;
+ $scope.ecdapp.isDataLoading = true;
+ $scope.ecdapp.isRequestFailed = false;
+ $scope.ecdapp.filterByUser = true;
+ // sorting
+ $scope.ecdapp.sortBy = null;
+
+ // searching
+ $scope.ecdapp.searchBy = $routeParams.bpId;
+ if ($scope.ecdapp.searchBy == undefined) {
+ $scope.ecdapp.searchBy = "owner:" + $scope.userId + ";";
+ } else {
+ if ($scope.ecdapp.searchBy.includes("owner")) {
+ if ($scope.ecdapp.searchBy.split(":")[1] === "group") {
+ $scope.ecdapp.filterByUser = false;
+ $scope.ecdapp.searchBy = undefined;
+ }
+ }
+ }
+
+ $scope.ecdapp.searchString;
+ $scope.ecdapp.availableTenants = JSON.parse(localStorageService.get('tenants'));
+ $scope.ecdapp.isInternal = localStorageService.get('internal');
+ if ($scope.ecdapp.isInternal) {
+ $scope.ecdapp.components = JSON.parse(localStorageService.get('appComponents'));
+ $scope.ecdapp.apps = JSON.parse(localStorageService.get('apps'));
+ $scope.ecdapp.selectedApp;
+ $scope.ecdapp.selectedComp;
+ $scope.ecdapp.availableComp = JSON.parse(localStorageService.get('components'));
+ }
+ $scope.ecdapp.selectedBp;
+ $scope.ecdapp.availableBp = JSON.parse(localStorageService.get('bpNames'));
+
+ $scope.ecdapp.selectedOwner;
+
+ $scope.ecdapp.showingMoreFilters = false;
+
+ $scope.ecdapp.toggleMoreFilters = function() {
+ $scope.ecdapp.showingMoreFilters = !$scope.ecdapp.showingMoreFilters;
+ };
+
+ $scope.ecdapp.trackBpRowIndex = function(indx) {
+ $scope.ecdapp.tableData[indx].expanded = !$scope.ecdapp.tableData[indx].expanded;
+ };
+
+ $scope.ecdapp.updateTable = function() {
+ $scope.ecdapp.isSrvcDataLoading = true;
+ var srvcTypIds = [];
+ var srvcIds = [];
+ var bpDepls =[];
+ var cloneGrid = $scope.ecdapp.tableData;
+ angular.forEach($scope.ecdapp.tableData, function(item, index) {
+ angular.forEach(item, function(value, key) {
+ if (key === "typeId") {
+ srvcTypIds.push(value);
+ }
+ });
+ });
+
+ InventoryBlueprintService.getDeploymentForBp(srvcTypIds)
+ .then(function(jsonObj) {
+ if (jsonObj.error) {
+ $log.error("inventoryBlueprintController.updateTable failed: " + jsonObj.error);
+ } else {
+ bpDepls = jsonObj;
+ for (var typIndx = 0; typIndx < bpDepls.length; typIndx++) {
+ srvcIds.push(bpDepls[typIndx].serviceRefList);
+ }
+ angular.forEach(cloneGrid, function(item, index) {
+ item.deployments = srvcIds[index];
+ item.expanded = false;
+ });
+ $scope.ecdapp.tableData = cloneGrid;
+ }
+ $scope.ecdapp.isSrvcDataLoading = false;
+ }, function(error) {
+ $log.error("inventoryBlueprintController.updateTable failed: " + error);
+ bpDepls = [];
+ $scope.ecdapp.isSrvcDataLoading = false;
+ });
+ }
+
+ $scope.ecdapp.JSONToCSVConverter = function(blueprint) {
+ var array = typeof blueprint != 'object' ? JSON.parse(blueprint) : blueprint;
+ var str = '';
+ for (var i = 0; i < array.length; i++) {
+ var line = '';
+ for (var index in array[i]) {
+ line += array[i][index] + ',';
+ }
+ line.slice(0, line.Length - 1);
+ str += line + '\r\n';
+ }
+
+ var uri = 'data:text/csv;charset=utf-8,' + escape(str);
+ var fileName = 'exported';
+
+ var link = document.createElement("a");
+ link.href= uri;
+
+ link.style = "visibility:hidden";
+ link.download = fileName + ".csv";
+
+ document.body.appendChild(link);
+ link.click();
+ document.body.removeChild(link);
+ };
+
+ $scope.ecdapp.createcsv = function(blueprint) {
+ var bpArr =[];
+ bpArr.push(blueprint);
+ $scope.ecdapp.JSONToCSVConverter(bpArr);
+ };
+
+ $scope.ecdapp.exportJson = function(blueprint) {
+ var bpExportObj = {};
+ bpExportObj.application = blueprint.application;
+ bpExportObj.component = blueprint.component;
+ bpExportObj.typeName = blueprint.typeName;
+ bpExportObj.typeVersion = blueprint.typeVersion;
+ bpExportObj.blueprintTemplate = blueprint.blueprintTemplate;
+
+ var bpStr = JSON.stringify(bpExportObj);
+ var uri = 'data:text/json;charset=utf-8,' + escape(bpStr);
+ var fileName = blueprint.application + '_' + blueprint.component +
+ '_' + blueprint.typeName + '_' + blueprint.typeVersion;
+
+ var link = document.createElement("a");
+ link.href= uri;
+
+ link.style = "visibility:hidden";
+ link.download = fileName + ".json";
+
+ document.body.appendChild(link);
+ link.click();
+ document.body.removeChild(link);
+ };
+
+ $scope.ecdapp.getTenants = function() {
+ ControllerService.getTenants()
+ .then(function(jsonObj) {
+ if (jsonObj.error) {
+ $log.error("blueprintController.getTenants failed: " + jsonObj.error);
+ $scope.ecdapp.isRequestFailed = true;
+ $scope.ecdapp.errMsg = jsonObj.error;
+ $scope.ecdapp.tableData = [];
+ } else {
+ var tenants = [];
+ for (var tenIndx = 0; tenIndx < jsonObj.items.length; tenIndx++) {
+ tenants.push(jsonObj.items[tenIndx].name);
}
+ localStorageService.set('tenants', JSON.stringify(tenants));
+ $scope.ecdapp.availableTenants = JSON.parse(localStorageService.get('tenants'));
+ }
+ }, function(error) {
+ $log.error("blueprintController.getTenants failed: " + error);
+ $scope.ecdapp.isRequestFailed = true;
+ $scope.ecdapp.errMsg = error;
+ });
+ };
+
+ $scope.ecdapp.getOwnersList = function() {
+ $scope.ecdapp.bpOwners = JSON.parse(localStorageService.get('bpOwners'));
+ if ($scope.ecdapp.bpOwners == null) {
+ InventoryBlueprintService.getOwnersList().then(
+ function(jsonObj) {
+ if (jsonObj.error) {
+ $log.error("bpCtlr.getOwnersList failed: "
+ + jsonObj.error);
+ $scope.ecdapp.bpOwners = [];
+ } else {
+ $scope.ecdapp.bpOwners = jsonObj;
+ localStorageService.set('bpOwners', JSON.stringify(jsonObj));
+ }
+ },
+ function(error) {
+ $log.error("inventoryDeploymentController.getOwnersList failed: "
+ + error);
+ $scope.ecdapp.bpOwners = [];
+ });
+ }
+ };
+
+ $scope.ecdapp.getBlueprintsList = function() {
+ $scope.ecdapp.availableBp = JSON.parse(localStorageService.get('bpNames'));
+ if ($scope.ecdapp.availableBp == null) {
+ InventoryBlueprintService.getBlueprintsList().then(
+ function(jsonObj) {
+ if (jsonObj.error) {
+ $log.error("execViewCtlr.getBlueprintsList failed: "
+ + jsonObj.error);
+ $scope.ecdapp.availableBp = [];
+ } else {
+ $scope.ecdapp.availableBp = jsonObj.items;
+ localStorageService.set('bpNames', JSON.stringify(jsonObj.items));
+ //$scope.ecdapp.availableBp = JSON.parse(localStorageService.get('bpNames'));
+ }
+ },
+ function(error) {
+ $log.error("inventoryDeploymentController.getDeploymentList failed: "
+ + error);
+ $scope.ecdapp.availableBp = [];
+ });
+ }
+ };
+
+ /**
+ * Get the components from database
+ *
+ */
+ $scope.ecdapp.getAppComponents = function() {
+ InventoryBlueprintService.getComponents()
+ .then(function(jsonObj) {
+ if (jsonObj.error) {
+ $log.error("inventoryBlueprintController.loadComponents failed: " + jsonObj.error);
+ $scope.ecdapp.components = [];
+ } else {
+ if (debug)
+ $log.debug("inventoryBlueprintController.loadComponents succeeded, size " + jsonObj.data.length);
+ $scope.ecdapp.isRequestFailed = false;
+ $scope.ecdapp.errMsg = null;
+ $scope.ecdapp.components = jsonObj;
+ if (Array.isArray($scope.ecdapp.components) ) {
+ angular.forEach($scope.ecdapp.components, function(item, index) {
+ angular.forEach(item, function(value, key) {
+ if (key === "app") {
+ $scope.ecdapp.apps.push(value);
+ } else {
+ angular.forEach(value, function(item, index) {
+ angular.forEach(item, function(value, key) {
+ if (key === "cname") {
+ if (!$scope.ecdapp.availableComp.includes(value)) {
+ $scope.ecdapp.availableComp.push(value);
+ }
+ }
+ });
+ });
+ }
+ });
+ });
+ }
+ }
+ $scope.ecdapp.isDataLoading = false;
+ }, function(error) {
+ $log.error("inventoryBlueprintController.loadComponents failed: " + error);
+ $scope.ecdapp.components = [];
+ });
+ };
+
+ /**
+ * Loads the table. Interprets the remote controller's response and copies
+ * to scope variables. The response is either list to be assigned to
+ * tableData, or an error to be shown.
+ */
+ $scope.ecdapp.loadTable = function(sortBy, searchBy) {
+ $scope.ecdapp.isDataLoading = true;
+ $scope.ecdapp.sortBy = sortBy;
+ //$scope.ecdapp.searchBy = searchBy;
+ InventoryBlueprintService.getBlueprints($scope.ecdapp.currentPage, $scope.ecdapp.viewPerPage, $scope.ecdapp.sortBy, $scope.ecdapp.searchBy)
+ .then(function(jsonObj) {
+ if (jsonObj.error) {
+ $log.error("inventoryBlueprintController.loadTable failed: " + jsonObj.error);
+ $scope.ecdapp.isRequestFailed = true;
+ $scope.ecdapp.errMsg = jsonObj.error;
+ $scope.ecdapp.tableData = [];
+ } else {
+ //if (debug)
+ //$log.debug("inventoryBlueprintController.loadTable succeeded, size " + jsonObj.data.length);
+ $scope.ecdapp.isRequestFailed = false;
+ $scope.ecdapp.errMsg = null;
+ $scope.ecdapp.totalPages = jsonObj.totalPages;
+ $scope.ecdapp.tableData = jsonObj.items;
+ //$scope.ecdapp.updateTable();
+ $scope.ecdapp.getBlueprintsList();
+ $scope.ecdapp.getOwnersList();
+ }
+ $scope.ecdapp.isDataLoading = false;
+ }, function(error) {
+ $log.error("inventoryBlueprintController.loadTable failed: " + error);
+ $scope.ecdapp.isRequestFailed = true;
+ $scope.ecdapp.errMsg = error;
+ $scope.ecdapp.tableData = [];
+ $scope.ecdapp.isDataLoading = false;
+ var loc = location.pathname;
+ var loc1 = loc.replace("/", "");
+ var loc2 = loc1.replace("/ecd", "/login.htm");
+ alert("Session expired - Sign in again");
+ location.replace("/"+loc2);
+ });
+ };
+
+ stop = $interval( function(){ $scope.ecdapp.loadTable(); }, 300000, 100, false);
+
+ $scope.ecdapp.stopLoading = function() {
+ if (angular.isDefined(stop)) {
+ $interval.cancel(stop);
+ stop = undefined;
+ }
+ };
+
+ /**
+ * Loads the table. Interprets the remote controller's response and copies
+ * to scope variables. The response is either list to be assigned to
+ * tableData, or an error to be shown.
+ */
+ $scope.ecdapp.sortTable = function(sortBy) {
+ $scope.ecdapp.isDataLoading = true;
+ $scope.ecdapp.sortBy = sortBy;
+ InventoryBlueprintService.getBlueprints($scope.ecdapp.currentPage, $scope.ecdapp.viewPerPage, sortBy, $scope.ecdapp.searchBy)
+ .then(function(jsonObj) {
+ if (jsonObj.error) {
+ $log.error("inventoryBlueprintController.loadTable failed: " + jsonObj.error);
+ $scope.ecdapp.isRequestFailed = true;
+ $scope.ecdapp.errMsg = jsonObj.error;
+ $scope.ecdapp.tableData = [];
+ } else {
+ if (debug)
+ $log.debug("inventoryBlueprintController.loadTable succeeded, size " + jsonObj.data.length);
+ $scope.ecdapp.isRequestFailed = false;
+ $scope.ecdapp.errMsg = null;
+ $scope.ecdapp.totalPages = jsonObj.totalPages;
+ $scope.ecdapp.tableData = jsonObj.items;
+ //$scope.ecdapp.updateTable();
+ }
+ $scope.ecdapp.isDataLoading = false;
+ }, function(error) {
+ $log.error("inventoryBlueprintController.loadTable failed: " + error);
+ $scope.ecdapp.isRequestFailed = true;
+ $scope.ecdapp.errMsg = error;
+ $scope.ecdapp.tableData = [];
+ $scope.ecdapp.isDataLoading = false;
+ });
+ };
- line.slice(0, line.Length - 1);
+ $scope.ecdapp.filterBySvc = function() {
+ if ( typeof $scope.ecdapp.searchString != "undefined" &&
+ $scope.ecdapp.searchString != '') {
+ if ($scope.ecdapp.searchString.includes("serviceRef:") ||
+ $scope.ecdapp.searchString.includes("app:") ||
+ $scope.ecdapp.searchString.includes("comp:")) {
+ if ($scope.ecdapp.filterByUser) {
+ $scope.ecdapp.searchBy = $scope.ecdapp.searchString + ";" + "owner:" + $scope.userId + ";" + ";";
+ } else {
+ $scope.ecdapp.searchBy = $scope.ecdapp.searchString;
+ }
+ } else {
+ if ($scope.ecdapp.filterByUser) {
+ $scope.ecdapp.searchBy = 'contains:' + $scope.ecdapp.searchString + ";" + "owner:" + $scope.userId + ";";
+ } else {
+ $scope.ecdapp.searchBy = 'contains:' + $scope.ecdapp.searchString;
+ }
+ }
+ $scope.ecdapp.searchTable();
+ }
+ };
- str += line + '\r\n';
+ $scope.ecdapp.extendedfilterSrch = function() {
+ if ( typeof $scope.ecdapp.selectedBp != "undefined" &&
+ $scope.ecdapp.selectedBp != '') {
+ var svcFilterStr = 'serviceRef:' + $scope.ecdapp.selectedBp.toString();
+ $scope.ecdapp.searchBy = svcFilterStr + ';'
+ if ( typeof $scope.ecdapp.selectedApp != "undefined" &&
+ $scope.ecdapp.selectedApp != '') {
+ var appFilterStr = 'app:' + $scope.ecdapp.selectedApp.toString();
+ $scope.ecdapp.searchBy += appFilterStr + ';'
+ }
+ if ( typeof $scope.ecdapp.selectedComp != "undefined" &&
+ $scope.ecdapp.selectedComp != '') {
+ var compFilterStr = 'comp:' + $scope.ecdapp.selectedComp.toString();
+ $scope.ecdapp.searchBy += compFilterStr + ';'
}
+ if ( typeof $scope.ecdapp.selectedOwner != "undefined" &&
+ $scope.ecdapp.selectedOwner != '') {
+ var ownerFilterStr = 'owner:' + $scope.ecdapp.selectedOwner.toString();
+ $scope.ecdapp.searchBy += ownerFilterStr + ';'
+ }
+ } else {
+ if ( typeof $scope.ecdapp.selectedApp != "undefined" &&
+ $scope.ecdapp.selectedApp != '') {
+ var appFilterStr = 'app:' + $scope.ecdapp.selectedApp.toString();
+ $scope.ecdapp.searchBy = appFilterStr + ';'
+ if ( typeof $scope.ecdapp.selectedComp != "undefined" &&
+ $scope.ecdapp.selectedComp != '' ) {
+ var compFilterStr = 'comp:' + $scope.ecdapp.selectedComp.toString();
+ $scope.ecdapp.searchBy += compFilterStr + ';'
+ }
+ if ( typeof $scope.ecdapp.selectedOwner != "undefined" &&
+ $scope.ecdapp.selectedOwner != '') {
+ var ownerFilterStr = 'owner:' + $scope.ecdapp.selectedOwner.toString();
+ $scope.ecdapp.searchBy += ownerFilterStr + ';'
+ }
+ } else {
+ if ( typeof $scope.ecdapp.selectedComp != "undefined" &&
+ $scope.ecdapp.selectedComp != '') {
+ var compFilterStr = 'comp:' + $scope.ecdapp.selectedComp.toString();
+ $scope.ecdapp.searchBy = compFilterStr + ';'
+ if ( typeof $scope.ecdapp.selectedOwner != "undefined" &&
+ $scope.ecdapp.selectedOwner != '') {
+ var ownerFilterStr = 'owner:' + $scope.ecdapp.selectedOwner.toString();
+ $scope.ecdapp.searchBy += ownerFilterStr + ';'
+ }
+ } else {
+ if ( typeof $scope.ecdapp.selectedOwner != "undefined" &&
+ $scope.ecdapp.selectedOwner != '') {
+ var ownerFilterStr = 'owner:' + $scope.ecdapp.selectedOwner.toString();
+ $scope.ecdapp.searchBy = ownerFilterStr + ';'
+ }
+ }
+
+ }
+ }
+ if ($scope.ecdapp.filterByUser) {
+ $scope.ecdapp.searchBy += "owner:" + $scope.userId + ";";
+ }
+ $scope.ecdapp.searchString = $scope.ecdapp.searchBy;
+ $scope.ecdapp.searchTable();
+ };
+
+ /**
+ * Loads the table. Interprets the remote controller's response and copies
+ * to scope variables. The response is either list to be assigned to
+ * tableData, or an error to be shown.
+ */
+ $scope.ecdapp.searchTable = function() {
+ $scope.ecdapp.isDataLoading = true;
+ $scope.ecdapp.showingMoreFilters = false;
+ if ($scope.ecdapp.currentPage != 1) {
+ $scope.ecdapp.currentPage = 1;
+ } else {
+ InventoryBlueprintService.getBlueprints($scope.ecdapp.currentPage, $scope.ecdapp.viewPerPage, $scope.ecdapp.sortBy, $scope.ecdapp.searchBy)
+ .then(function(jsonObj) {
+ if (jsonObj.error) {
+ $log.error("inventoryBlueprintController.loadTable failed: " + jsonObj.error);
+ $scope.ecdapp.isRequestFailed = true;
+ $scope.ecdapp.errMsg = jsonObj.error;
+ $scope.ecdapp.tableData = [];
+ } else {
+ if (debug)
+ $log.debug("inventoryBlueprintController.loadTable succeeded, size " + jsonObj.data.length);
+ $scope.ecdapp.isRequestFailed = false;
+ $scope.ecdapp.errMsg = null;
+ $scope.ecdapp.totalPages = jsonObj.totalPages;
+ $scope.ecdapp.tableData = jsonObj.items;
+ //$scope.ecdapp.updateTable();
+ }
+ $scope.ecdapp.isDataLoading = false;
+ }, function(error) {
+ $log.error("inventoryBlueprintController.loadTable failed: " + error);
+ $scope.ecdapp.isRequestFailed = true;
+ $scope.ecdapp.errMsg = error;
+ $scope.ecdapp.tableData = [];
+ $scope.ecdapp.isDataLoading = false;
+ var loc = location.pathname;
+ var loc1 = loc.replace("/", "");
+ var loc2 = loc1.replace("/ecd", "/login.htm");
+ alert("Session expired - Sign in again");
+ location.replace("/"+loc2);
+ });
+ }
+ };
+
+ $scope.ecdapp.resetFilters = function() {
+ $scope.ecdapp.selectedBp = '';
+ $scope.ecdapp.selectedApp = '';
+ $scope.ecdapp.selectedComp = '';
+ $scope.ecdapp.selectedOwner = '';
+ $scope.ecdapp.searchString = '';
+ };
+
+ $scope.ecdapp.reloadTable = function() {
+ $scope.ecdapp.currentPage = 1;
+ if ($scope.ecdapp.filterByUser) {
+ $scope.ecdapp.searchBy = "owner:" + $scope.userId + ";";
+ } else {
+ $scope.ecdapp.searchBy = '';
+ }
+ $scope.ecdapp.searchString = '';
+ $scope.ecdapp.resetFilters();
+ $scope.ecdapp.loadTable();
+ };
+
+ $scope.ecdapp.toggleUserFilt = function() {
+ $scope.ecdapp.reloadTable();
+ /*
+ if ($scope.ecdapp.filterByUser === false) {
+ $scope.ecdapp.searchString = '';
+ }
+ */
+ }
+ /**
+ * Invoked at first page load AND when
+ * user clicks on the B2B pagination control.
+ */
+ $scope.pageChangeHandler = function(page) {
+ $scope.ecdapp.currentPage = page;
+ $scope.ecdapp.loadTable($scope.ecdapp.sortBy, $scope.ecdapp.searchBy);
+ }
+
+ /**
+ * Shows a modal pop-up to update a blueprint.
+ * Passes data in via an object named "message".
+ * On success, updates the table.
+ */
+ $scope.ecdapp.updateBlueprintModalPopup = function(blueprint) {
+ $scope.ecdapp.editBlueprint = null;
+ var modalInstance = $modal.open({
+ templateUrl : 'inventory_blueprint_update_popup.html',
+ controller : 'inventoryBlueprintUpdateCtrl',
+ windowClass: 'modal-docked',
+ sizeClass: 'modal-jumbo',
+ resolve : {
+ message : function() {
+ var dataForPopup = {
+ blueprint : blueprint
+ };
+ return dataForPopup;
+ }
+ }
+ });
+ modalInstance.result.then(function(response) {
+
+ if (debug)
+ $log.debug('updateBlueprintModalPopup: response: ' + JSON.stringify(response));
+ if (response == null) {
+ if (debug)
+ $log.debug('user closed dialog');
+ }
+ else {
+ if (response.error != null) {
+ $log.error('updateBlueprintModalPopup failed: ' + response.error);
+ alert('Failed to update blueprint:\n' + response.error);
+ }
+ else {
+ // success, get the updated list.
+ $scope.ecdapp.loadTable()
+ }
+ }
+ });
+ };
+
+ /**
+ * Shows a modal pop-up with blueprint content.
+ * Passes data in via an object named "message".
+ */
+ $scope.ecdapp.viewBlueprintModalPopup = function(blueprint) {
+ $scope.ecdapp.editBlueprint = null;
+ var modalInstance = $modal.open({
+ templateUrl : 'inventory_blueprint_view_popup.html',
+ controller : 'inventoryBlueprintViewCtrl',
+ windowClass: 'modal-docked',
+ sizeClass: 'modal-jumbo',
+ resolve : {
+ message : function() {
+ var dataForPopup = {
+ blueprint : blueprint
+ };
+ return dataForPopup;
+ }
+ }
+ });
+ modalInstance.result.then(function(response) {
+ // No response.
+ });
+ };
- var uri = 'data:text/csv;charset=utf-8,' + escape(str);
- var fileName = 'exported';
-
- var link = document.createElement("a");
- link.href= uri;
-
- link.style = "visibility:hidden";
- link.download = fileName + ".csv";
-
- document.body.appendChild(link);
- link.click();
- document.body.removeChild(link);
- };
-
- $scope.ecdapp.createcsv = function(blueprint)
- {
- var bpArr =[];
- bpArr.push(blueprint);
- $scope.ecdapp.JSONToCSVConverter(bpArr);
- };
-
- $scope.ecdapp.exportJson = function(blueprint)
- {
- var bpExportObj = {};
- bpExportObj.application = blueprint.application;
- bpExportObj.component = blueprint.component;
- bpExportObj.typeName = blueprint.typeName;
- bpExportObj.typeVersion = blueprint.typeVersion;
- bpExportObj.blueprintTemplate = blueprint.blueprintTemplate;
-
- var bpStr = JSON.stringify(bpExportObj);
- var uri = 'data:text/json;charset=utf-8,' + escape(bpStr);
- var fileName = blueprint.application + '_' + blueprint.component +
- '_' + blueprint.typeName + '_' + blueprint.typeVersion;
-
- var link = document.createElement("a");
- link.href= uri;
-
- link.style = "visibility:hidden";
- link.download = fileName + ".json";
-
- document.body.appendChild(link);
- link.click();
- document.body.removeChild(link);
- };
- /**
- * Loads the table. Interprets the remote controller's response and copies
- * to scope variables. The response is either list to be assigned to
- * tableData, or an error to be shown.
- */
- $scope.ecdapp.loadTable = function(sortBy, searchBy) {
- $scope.ecdapp.isDataLoading = true;
- $scope.ecdapp.sortBy = sortBy;
- $scope.ecdapp.searchBy = searchBy;
- InventoryBlueprintService.getBlueprints($scope.ecdapp.currentPageNum, $scope.ecdapp.viewPerPage, sortBy, searchBy)
- .then(function(jsonObj) {
- if (jsonObj.error) {
- $log.error("inventoryBlueprintController.loadTable failed: " + jsonObj.error);
- $scope.ecdapp.isRequestFailed = true;
- $scope.ecdapp.errMsg = jsonObj.error;
- $scope.ecdapp.tableData = [];
- } else {
- //if (debug)
- //$log.debug("inventoryBlueprintController.loadTable succeeded, size " + jsonObj.data.length);
- $scope.ecdapp.isRequestFailed = false;
- $scope.ecdapp.errMsg = null;
- $scope.ecdapp.totalPages = jsonObj.totalPages;
- $scope.ecdapp.tableData = jsonObj.items;
- $scope.ecdapp.updateTable();
- }
- $scope.ecdapp.isDataLoading = false;
- }, function(error) {
- $log.error("inventoryBlueprintController.loadTable failed: " + error);
- $scope.ecdapp.isRequestFailed = true;
- $scope.ecdapp.errMsg = error;
- $scope.ecdapp.tableData = [];
- $scope.ecdapp.isDataLoading = false;
- });
- };
-
- /**
- * Loads the table. Interprets the remote controller's response and copies
- * to scope variables. The response is either list to be assigned to
- * tableData, or an error to be shown.
- */
- $scope.ecdapp.sortTable = function(sortBy) {
- $scope.ecdapp.isDataLoading = true;
- $scope.ecdapp.sortBy = sortBy;
- InventoryBlueprintService.getBlueprints($scope.ecdapp.currentPageNum, $scope.ecdapp.viewPerPage, sortBy, $scope.ecdapp.searchBy)
- .then(function(jsonObj) {
- if (jsonObj.error) {
- $log.error("inventoryBlueprintController.loadTable failed: " + jsonObj.error);
- $scope.ecdapp.isRequestFailed = true;
- $scope.ecdapp.errMsg = jsonObj.error;
- $scope.ecdapp.tableData = [];
- } else {
- if (debug)
- $log.debug("inventoryBlueprintController.loadTable succeeded, size " + jsonObj.data.length);
- $scope.ecdapp.isRequestFailed = false;
- $scope.ecdapp.errMsg = null;
- $scope.ecdapp.totalPages = jsonObj.totalPages;
- $scope.ecdapp.tableData = jsonObj.items;
- $scope.ecdapp.updateTable();
- }
- $scope.ecdapp.isDataLoading = false;
- }, function(error) {
- $log.error("inventoryBlueprintController.loadTable failed: " + error);
- $scope.ecdapp.isRequestFailed = true;
- $scope.ecdapp.errMsg = error;
- $scope.ecdapp.tableData = [];
- $scope.ecdapp.isDataLoading = false;
- });
- };
-
- /**
- * Loads the table. Interprets the remote controller's response and copies
- * to scope variables. The response is either list to be assigned to
- * tableData, or an error to be shown.
- */
- $scope.ecdapp.searchTable = function(searchBy) {
- $scope.ecdapp.isDataLoading = true;
- $scope.ecdapp.searchBy = searchBy;
- InventoryBlueprintService.getBlueprints($scope.ecdapp.currentPageNum, $scope.ecdapp.viewPerPage, $scope.ecdapp.sortBy, searchBy)
- .then(function(jsonObj) {
- if (jsonObj.error) {
- $log.error("inventoryBlueprintController.loadTable failed: " + jsonObj.error);
- $scope.ecdapp.isRequestFailed = true;
- $scope.ecdapp.errMsg = jsonObj.error;
- $scope.ecdapp.tableData = [];
- } else {
- if (debug)
- $log.debug("inventoryBlueprintController.loadTable succeeded, size " + jsonObj.data.length);
- $scope.ecdapp.isRequestFailed = false;
- $scope.ecdapp.errMsg = null;
- $scope.ecdapp.totalPages = jsonObj.totalPages;
- $scope.ecdapp.tableData = jsonObj.items;
- $scope.ecdapp.updateTable();
- }
- $scope.ecdapp.isDataLoading = false;
- }, function(error) {
- $log.error("inventoryBlueprintController.loadTable failed: " + error);
- $scope.ecdapp.isRequestFailed = true;
- $scope.ecdapp.errMsg = error;
- $scope.ecdapp.tableData = [];
- $scope.ecdapp.isDataLoading = false;
- });
- };
-
- /**
- * Invoked at first page load AND when
- * user clicks on the B2B pagination control.
- */
- $scope.pageChangeHandler = function(page) {
- // console.log('pageChangeHandler: current is ' + $scope.ecdapp.currentPageNum + ' new is ' + page);
- $scope.ecdapp.currentPageNum = page;
- $scope.ecdapp.loadTable($scope.ecdapp.sortBy, $scope.ecdapp.searchBy);
- }
-
- /**
- * Shows a modal pop-up to update a blueprint.
- * Passes data in via an object named "message".
- * On success, updates the table.
- */
- $scope.ecdapp.updateBlueprintModalPopup = function(blueprint) {
- $scope.ecdapp.editBlueprint = null;
- var modalInstance = $modal.open({
- templateUrl : 'inventory_blueprint_update_popup.html',
- controller : 'inventoryBlueprintUpdateCtrl',
- windowClass: 'modal-docked',
- sizeClass: 'modal-jumbo',
- resolve : {
- message : function() {
- var dataForPopup = {
- blueprint : blueprint
- };
- return dataForPopup;
- }
- }
- });
- modalInstance.result.then(function(response) {
-
- if (debug)
- $log.debug('updateBlueprintModalPopup: response: ' + JSON.stringify(response));
- if (response == null) {
- if (debug)
- $log.debug('user closed dialog');
- }
- else {
- if (response.error != null) {
- $log.error('updateBlueprintModalPopup failed: ' + response.error);
- alert('Failed to update blueprint:\n' + response.error);
- }
- else {
- // success, get the updated list.
- $scope.ecdapp.loadTable()
- }
- }
- });
- };
-
- /**
- * Shows a modal pop-up with blueprint content.
- * Passes data in via an object named "message".
- */
- $scope.ecdapp.viewBlueprintModalPopup = function(blueprint) {
- $scope.ecdapp.editBlueprint = null;
- var modalInstance = $modal.open({
- templateUrl : 'inventory_blueprint_view_popup.html',
- controller : 'inventoryBlueprintViewCtrl',
- windowClass: 'modal-docked',
- sizeClass: 'modal-jumbo',
- resolve : {
- message : function() {
- var dataForPopup = {
- blueprint : blueprint
- };
- return dataForPopup;
- }
- }
- });
- modalInstance.result.then(function(response) {
- // No response.
- });
- };
-
- /**
- * Shows a modal pop-up to upload a blueprint.
- * Passes data in via an object named "message".
- * On success, updates the table.
- */
- $scope.ecdapp.uploadBlueprintModalPopup = function() {
- $scope.ecdapp.editBlueprint = null;
- var modalInstance = $modal.open({
- templateUrl : 'inventory_blueprint_upload_popup.html',
- controller : 'inventoryBlueprintUploadCtrl',
- windowClass: 'modal-docked',
- sizeClass: 'modal-jumbo',
- resolve : {
- message : function() {
- var dataForPopup = {
- blueprint : $scope.ecdapp.editBlueprint,
- blueprintList : $scope.ecdapp.tableData,
- };
- return dataForPopup;
- }
- }
- });
- modalInstance.result.then(function(response) {
- if (debug)
- $log.debug('uploadBlueprintModalPopup: response: ' + JSON.stringify(response));
- if (response == null) {
- if (debug)
- $log.debug('user closed dialog');
- }
- else {
- if (response.error != null) {
- $log.error('uploadBlueprintModalPopup failed: ' + response.error);
- alert('Failed to upload blueprint:\n' + response.error);
- }
- else {
- // success, get the updated list.
- $scope.ecdapp.loadTable()
- }
- }
- });
- };
-
- /**
- * Shows a modal pop-up to create a deployment from a blueprint.
- * Passes data in via an object named "message".
- */
- $scope.ecdapp.deployBlueprintModalPopup = function(blueprint) {
- var modalInstance = $modal.open({
- templateUrl : 'inventory_blueprint_deploy_popup.html',
- controller : 'inventoryBlueprintDeployCtrl',
- windowClass: 'modal-docked',
- sizeClass: 'modal-jumbo',
- resolve : {
- message : function() {
- var dataForPopup = {
- blueprint : blueprint,
- };
- return dataForPopup;
- }
- }
- });
- modalInstance.result.then(function(response) {
- if (debug)
- $log.debug('deployBlueprintModalPopup: response: ' + JSON.stringify(response));
- if (response == null) {
- if (debug)
- $log.debug('user closed dialog');
- }
- else {
- if (response.error != null) {
- $log.error('deployBlueprintModalPopup failed: ' + response.error);
- alert('Failed to deploy blueprint:\n' + response.error);
- // No need to update THIS table.
- // Must switch to deployments page to see result? Awkward.
- }
- }
- });
- };
-
- /**
- * Shows a modal pop-up to confirm deletion.
- * On successful completion, updates the table.
- */
- $scope.ecdapp.deleteBlueprintModalPopup = function(blueprint) {
- modalService.popupConfirmWin("Confirm", "Delete blueprint with name '"
- + blueprint.typeName + "'?", function() {
- InventoryBlueprintService.deleteBlueprint(blueprint.typeId).then(
- function(response) {
- if (debug)
- $log.debug('deleteBlueprintModalPopup: response: ' + JSON.stringify(response));
- if (response && response.error) {
- // $log.error('deleteBlueprint failed: ' + response.error);
- alert('Failed to delete blueprint:\n' + response.error);
- }
- else {
- // No response body on success.
- $scope.ecdapp.loadTable();
- }
- },
- function(error) {
- $log.error('InventoryBlueprintService.deleteBlueprint failed: ' + error);
- alert('Service failed to delete blueprint:\n' + error);
- });
- })
- };
+ /**
+ * Shows a modal pop-up to upload a blueprint.
+ * Passes data in via an object named "message".
+ * On success, updates the table.
+ */
+ $scope.ecdapp.uploadBlueprintModalPopup = function() {
+ $scope.ecdapp.editBlueprint = null;
+ var modalInstance = $modal.open({
+ templateUrl : 'inventory_blueprint_upload_popup.html',
+ controller : 'inventoryBlueprintUploadCtrl',
+ windowClass: 'modal-docked',
+ sizeClass: 'modal-jumbo',
+ resolve : {
+ message : function() {
+ var dataForPopup = {
+ apps : $scope.ecdapp.apps,
+ appComps: $scope.ecdapp.components
+ };
+ return dataForPopup;
+ }
+ }
+ });
+ modalInstance.result.then(function(response) {
+ if (debug)
+ $log.debug('uploadBlueprintModalPopup: response: ' + JSON.stringify(response));
+ if (response == null) {
+ if (debug)
+ $log.debug('user closed dialog');
+ }
+ else {
+ if (response.error != null) {
+ $log.error('uploadBlueprintModalPopup failed: ' + response.error);
+ alert('Failed to upload blueprint:\n' + response.error);
+ }
+ else {
+ // success, get the updated list.
+ $scope.ecdapp.loadTable()
+ }
+ }
+ });
+ };
+
+ /**
+ * Shows a modal pop-up to create a deployment from a blueprint.
+ * Passes data in via an object named "message".
+ */
+ $scope.ecdapp.deployBlueprintModalPopup = function(blueprint) {
+ var modalInstance = $modal.open({
+ templateUrl : 'inventory_blueprint_deploy_popup.html',
+ controller : 'inventoryBlueprintDeployCtrl',
+ windowClass: 'modal-docked',
+ sizeClass: 'modal-jumbo',
+ resolve : {
+ message : function() {
+ var dataForPopup = {
+ blueprint : blueprint,
+ tenantList : $scope.ecdapp.availableTenants
+ };
+ return dataForPopup;
+ }
+ }
+ });
+ modalInstance.result.then(function(response) {
+ if (debug)
+ $log.debug('deployBlueprintModalPopup: response: ' + JSON.stringify(response));
+ if (response == null) {
+ if (debug)
+ $log.debug('user closed dialog');
+ }
+ else {
+ if (response.error != null) {
+ $log.error('deployBlueprintModalPopup failed: ' + response.error);
+ alert('Failed to deploy blueprint:\n' + response.error);
+ // No need to update THIS table.
+ // Must switch to deployments page to see result? Awkward.
+ }
+ }
+ });
+ };
+ /**
+ * Shows a modal pop-up to confirm deletion.
+ * On successful completion, updates the table.
+ */
+ $scope.ecdapp.deleteBlueprintModalPopup = function(blueprint) {
+ modalService.popupConfirmWin("Confirm", "Delete blueprint with name '"
+ + blueprint.typeName + "'?", function() {
+ InventoryBlueprintService.deleteBlueprint(blueprint.typeId).then(
+ function(response) {
+ if (debug)
+ $log.debug('deleteBlueprintModalPopup: response: ' + JSON.stringify(response));
+ if (response && response.error) {
+ // $log.error('deleteBlueprint failed: ' + response.error);
+ alert('Failed to delete blueprint:\n' + response.error);
+ }
+ else {
+ // No response body on success.
+ $scope.ecdapp.loadTable();
+ }
+ },
+ function(error) {
+ $log.error('InventoryBlueprintService.deleteBlueprint failed: ' + error);
+ alert('Service failed to delete blueprint:\n' + error);
+ });
+ })
+ };
+
+ $scope.ecdapp.getTenants();
+
+ $scope.$on('$destroy', function() {
+ // Make sure that the interval is destroyed too
+ $scope.ecdapp.stopLoading();
+ });
+
});
/*************************************************************************/
appDS2.controller('inventoryBlueprintUpdateCtrl', function(
- $scope, $log, $modalInstance, message, InventoryBlueprintService) {
-
- 'use strict';
-
- // Controls logging in this controller
- var debug = false;
-
- // this object holds all app data and functions
- $scope.ecdapp = {};
- $scope.ecdapp.label = 'Update Blueprint';
- $scope.ecdapp.updateInProgress = false;
- // Create a ServiceTypeRequest object for edit
- $scope.ecdapp.serviceType = angular.copy(message.blueprint);
-
- /**
- * Validates content of user-editable fields.
- * Returns null if all is well,
- * a descriptive error message otherwise.
- */
- $scope.ecdapp.validateRequest = function(serviceType) {
- if (serviceType == null)
- return 'No data found.\nPlease enter some values.';
- if (serviceType.blueprintTemplate == null || serviceType.blueprintTemplate.trim() == '')
- return 'Blueprint Template is required.\nPlease enter a value.';
- let blueprintTemplate = {};
- try {
- blueprintTemplate = YAML.parse(serviceType.blueprintTemplate);
- }
- catch (ex) {
- return ('Blueprint template is not in YAML format:\n' + ex);
- }
- return null;
- }
-
- $scope.ecdapp.updateBlueprint = function(serviceType) {
- $scope.ecdapp.updateInProgress = true;
- if (debug)
- $log.debug('updateBlueprint: serviceType is ' + JSON.stringify($scope.ecdapp.serviceType));
- var validateMsg = $scope.ecdapp.validateRequest(serviceType);
- if (validateMsg != null) {
- alert('Invalid Request:\n' + validateMsg);
- return;
- }
-
- InventoryBlueprintService.updateBlueprint(serviceType)
- .then(function(response) {
- if (debug)
- $log.debug('inventoryBlueprintUpdateCtrl.updateBlueprint: ' + JSON.stringify(response));
- if (response && response.error) {
- $log.error('InventoryBlueprintService.updateBlueprint failed: ' + response.error);
- alert('Failed to update blueprint:\n' + response.error);
- }
- else {
- // Delete service returns null on success.
- $modalInstance.close("success");
- }
- $scope.ecdapp.updateInProgress = false;
- },
- function(error) {
- $log.error('InventoryBlueprintService.updateBlueprint failed: ' + error);
- $scope.ecdapp.updateInProgress = false;
- alert('Service failed to update blueprint:\n' + error);
- });
-
- };
+ $scope, $log, $modalInstance, message, InventoryBlueprintService) {
+
+ 'use strict';
+
+ // Controls logging in this controller
+ var debug = false;
+
+ // this object holds all app data and functions
+ $scope.ecdapp = {};
+ $scope.ecdapp.label = 'Update Blueprint';
+ $scope.ecdapp.updateInProgress = false;
+ // Create a ServiceTypeRequest object for edit
+ $scope.ecdapp.serviceTypeRequest = angular.copy(message.blueprint);
+
+ $scope.ecdapp.serviceType =
+ {
+ asdcResourceId : '',
+ asdcServiceId : '',
+ asdcServiceURL : '',
+ blueprintTemplate : '',
+ owner : $scope.ecdapp.serviceTypeRequest.owner,
+ serviceIds : [],
+ serviceLocations : [],
+ typeName : $scope.ecdapp.serviceTypeRequest.typeName,
+ typeVersion : $scope.ecdapp.serviceTypeRequest.typeVersion,
+ vnfTypes : [],
+ application: $scope.ecdapp.serviceTypeRequest.application,
+ component: $scope.ecdapp.serviceTypeRequest.component
+ };
+
+ // Fetch the blueprint
+ $scope.ecdapp.isDataLoading = true;
+ InventoryBlueprintService.viewBlueprint(message.blueprint.typeId).then(function(jsonObj) {
+ if (debug)
+ $log.debug("inventoryBlueprintViewCtrl.viewBlueprint response: " + JSON.stringify(jsonObj));
+ if (jsonObj.error) {
+ $scope.ecdapp.errMsg = 'Request Failed';
+ }
+ else {
+ $scope.ecdapp.serviceType.blueprintTemplate = jsonObj.blueprintTemplate;
+ }
+ $scope.ecdapp.isDataLoading = false;
+ }, function(error) {
+ $scope.ecdapp.isDataLoading = false;
+ $log.error("blueprintViewCtrl failed: " + error);
+ });
+
+ /**
+ * Validates content of user-editable fields.
+ * Returns null if all is well,
+ * a descriptive error message otherwise.
+ */
+ $scope.ecdapp.validateRequest = function(serviceType) {
+ if (serviceType == null)
+ return 'No data found.\nPlease enter some values.';
+ if (serviceType.blueprintTemplate == null || serviceType.blueprintTemplate.trim() == '')
+ return 'Blueprint Template is required.\nPlease enter a value.';
+ let blueprintTemplate = {};
+ try {
+ blueprintTemplate = YAML.parse(serviceType.blueprintTemplate);
+ }
+ catch (ex) {
+ return ('Blueprint template is not in YAML format:\n' + ex);
+ }
+ return null;
+ }
+
+ $scope.ecdapp.updateBlueprint = function(serviceType) {
+ $scope.ecdapp.updateInProgress = true;
+ if (debug)
+ $log.debug('updateBlueprint: serviceType is ' + JSON.stringify($scope.ecdapp.serviceType));
+ var validateMsg = $scope.ecdapp.validateRequest(serviceType);
+ if (validateMsg != null) {
+ alert('Invalid Request:\n' + validateMsg);
+ return;
+ }
+
+ InventoryBlueprintService.updateBlueprint(serviceType)
+ .then(function(response) {
+ if (debug)
+ $log.debug('inventoryBlueprintUpdateCtrl.updateBlueprint: ' + JSON.stringify(response));
+ if (response && response.error) {
+ $log.error('InventoryBlueprintService.updateBlueprint failed: ' + response.error);
+ alert('Failed to update blueprint:\n' + response.error);
+ }
+ else {
+ $modalInstance.close("success");
+ }
+ $scope.ecdapp.updateInProgress = false;
+ },
+ function(error) {
+ $log.error('InventoryBlueprintService.updateBlueprint failed: ' + error);
+ $scope.ecdapp.updateInProgress = false;
+ alert('Service failed to update blueprint:\n' + error);
+ });
+
+ };
});
appDS2.controller('inventoryBlueprintUploadCtrl', function(
- $scope, $log, $modalInstance, message, InventoryBlueprintService) {
-
- 'use strict';
-
- // Controls logging in this controller
- var debug = false;
-
- // this object holds all app data and functions
- $scope.ecdapp = {};
- $scope.ecdapp.label = 'Upload Blueprint';
- $scope.ecdapp.uploadInProgress = false;
- $scope.ecdapp.serviceTypeRequest =
- {
- asdcResourceId : '',
- asdcServiceId : '',
- asdcServiceURL : '',
- blueprintTemplate : '',
- owner : $scope.userId,
- serviceIds : '',
- serviceLocations : '',
- typeName : '',
- typeVersion : '',
- vnfTypes : '',
- application: '',
- component: ''
- };
- $scope.ecdapp.writeRole = false;
- $scope.ecdapp.newCompName = "";
- $scope.ecdapp.newCompDisplayName = "";
- $scope.ecdapp.newCompId = null;
- $scope.ecdapp.enableAppForm = false;
- $scope.ecdapp.apps = [];
- $scope.ecdapp.comps = [];
- $scope.ecdapp.validAppl = false;
- $scope.ecdapp.validComp = false;
- $scope.ecdapp.isImport = false;
-
- /**
- * Handler for file-read event reads file, parses JSON, validates content.
- */
- var importFileReader = new FileReader();
- importFileReader.onload = function(event) {
- let jsonString = importFileReader.result;
- if (debug)
- $log.debug('fileReader.onload: read: ' + jsonString);
- let ydict = {};
- try {
- ydict = JSON.parse(jsonString);
- }
- catch (ex) {
- alert('Failed to parse file as JSON:\n' + ex);
- }
- // Process the file
- for (var ykey in ydict) {
- let yval = ydict[ykey];
- if (debug)
- $log.debug('importFileReader.onload: typeof ' + ykey + ' is ' + typeof ykey);
-
- if (ykey === "application") {
- $scope.ecdapp.serviceTypeRequest.application = yval;
- $scope.ecdapp.validAppl = true;
- } else if (ykey === "component") {
- $scope.ecdapp.serviceTypeRequest.component = yval;
- $scope.ecdapp.validComp = true;
- } else if (ykey === "typeName") {
- $scope.ecdapp.serviceTypeRequest.typeName = yval;
- } else if (ykey === "typeVersion") {
- $scope.ecdapp.serviceTypeRequest.typeVersion = yval;
- } else if (ykey === "blueprintTemplate") {
- $scope.ecdapp.serviceTypeRequest.blueprintTemplate = yval;
- }
- }
- }
-
- $scope.ecdapp.handleImportCb = function($event) {
- var checkbox = $event.target;
- var action = (checkbox.checked ? 'import' : 'regular');
- if (action === 'import') {
- $scope.ecdapp.serviceTypeRequest.application = '';
- $scope.ecdapp.serviceTypeRequest.component = '';
- $scope.ecdapp.isImport = true;
- }
- if (action === 'regular') {
- $scope.ecdapp.serviceTypeRequest.application = 'Select Application';
- $scope.ecdapp.serviceTypeRequest.component = 'Select Component';
- $scope.ecdapp.isImport = false;
- }
- }
- // Handler for file-select event
- $scope.ecdapp.handleImportFile = function() {
- if (debug)
- $log.debug('handleFileSelect: $scope.ecdapp.fileModel.name is ' + $scope.ecdapp.serviceTypeRequest.fileModel.name);
- importFileReader.readAsText($scope.ecdapp.serviceTypeRequest.fileModel);
- };
-
- /**
- * Get the components from database
- *
- */
- InventoryBlueprintService.getComponents()
- .then(function(jsonObj) {
- if (jsonObj.error) {
- $log.error("inventoryBlueprintController.loadComponents failed: " + jsonObj.error);
- $scope.ecdapp.components = [];
- } else {
- if (debug)
- $log.debug("inventoryBlueprintController.loadComponents succeeded, size " + jsonObj.data.length);
- $scope.ecdapp.isRequestFailed = false;
- $scope.ecdapp.errMsg = null;
- $scope.ecdapp.components = jsonObj;
- if (Array.isArray($scope.ecdapp.components) ) {
- angular.forEach($scope.ecdapp.components, function(item, index) {
- angular.forEach(item, function(value, key) {
- if (key === "app") {
- $scope.ecdapp.apps.push(value);
- }
- });
- });
- }
- }
- $scope.ecdapp.isDataLoading = false;
- }, function(error) {
- $log.error("inventoryBlueprintController.loadComponents failed: " + error);
- $scope.ecdapp.components = [];
- });
-
- //$scope.ecdapp.components = [{"ECOMPC":[{"compId":1,"cname":"controller","dname":"CONTROLLER"},{"compId":2,"cname":"mso","dname":"MSO"},{"compId":3,"cname":"appc","dname":"APP-C"},{"compId":4,"cname":"clamp","dname":"CLAMP"},{"compId":5,"cname":"ecompscheduler","dname":"ECOMP SCHEDULER"},{"compId":6,"cname":"policy","dname":"POLICY"},{"compId":7,"cname":"eipam","dname":"EIPAM"},{"compId":181,"cname":"pdasms","dname":"PDAS-MS"},{"cname":"true"}]},
- // {"DCAE": [{"compId":8,"cname":"dcae","dname":"DCAE"}]}];
- $scope.ecdapp.selectAppComp = function(appName) {
- if(appName === "Select Application"){
- $scope.ecdapp.validAppl = false;
- } else {
- $scope.ecdapp.validAppl = true;
- for (var appIndx = 0; appIndx < $scope.ecdapp.components.length; appIndx++) {
- if ($scope.ecdapp.components[appIndx].app === appName) {
- $scope.ecdapp.comps = $scope.ecdapp.components[appIndx].comps;
- break;
- }
- }
- }
- }
- $scope.ecdapp.validateComp = function(appName) {
- if($scope.ecdapp.serviceTypeRequest.component === "Select Component"){
- $scope.ecdapp.validComp = false;
- } else {
- $scope.ecdapp.validComp = true;
- }
- }
- var fileReader = new FileReader();
- fileReader.onload = function(event) {
- let yamlString = fileReader.result;
- $scope.ecdapp.serviceTypeRequest.blueprintTemplate = yamlString;
- }
- $scope.ecdapp.enableAddApp = function() {
- if ($scope.ecdapp.enableAppForm) {
- $scope.ecdapp.enableAppForm = false;
- } else {
- $scope.ecdapp.enableAppForm = true;
- }
- }
- $scope.ecdapp.addApplication = function(appName, compId, compName, compDisplayName) {
- // save new application to database, reload components list
- if (compName.trim().length < 1 || compDisplayName.trim().length < 1) {
- alert("Must enter value for Component name and display name");
- return;
+ $scope, $log, $modalInstance, message, InventoryBlueprintService, localStorageService) {
+
+ 'use strict';
+
+ // Controls logging in this controller
+ var debug = false;
+
+ // this object holds all app data and functions
+ $scope.ecdapp = {};
+ $scope.ecdapp.label = 'Upload Blueprint';
+ $scope.ecdapp.uploadInProgress = false;
+
+ $scope.ecdapp.serviceTypeRequest =
+ {
+ asdcResourceId : '',
+ asdcServiceId : '',
+ asdcServiceURL : '',
+ blueprintTemplate : '',
+ owner : $scope.userId,
+ serviceIds : '',
+ serviceLocations : '',
+ typeName : '',
+ typeVersion : '',
+ vnfTypes : '',
+ application: '',
+ component: ''
+ };
+
+ if (!$scope.ecdapp.isInternal) {
+ $scope.ecdapp.serviceTypeRequest.application = 'DCAE';
+ $scope.ecdapp.serviceTypeRequest.component = 'dcae';
+ }
+ $scope.ecdapp.writeRole = false;
+ $scope.ecdapp.isImport = false;
+
+ /**
+ * Handler for file-read event reads file, parses JSON, validates content.
+ */
+ var importFileReader = new FileReader();
+ importFileReader.onload = function(event) {
+ let jsonString = importFileReader.result;
+ if (debug)
+ $log.debug('fileReader.onload: read: ' + jsonString);
+ let ydict = {};
+ try {
+ ydict = JSON.parse(jsonString);
+ }
+ catch (ex) {
+ alert('Failed to parse file as JSON:\n' + ex);
+ }
+ // Process the file
+ for (var ykey in ydict) {
+ let yval = ydict[ykey];
+ if (debug)
+ $log.debug('importFileReader.onload: typeof ' + ykey + ' is ' + typeof ykey);
+
+ if (ykey === "application") {
+ $scope.ecdapp.serviceTypeRequest.application = yval;
+ $scope.ecdapp.validAppl = true;
+ } else if (ykey === "component") {
+ $scope.ecdapp.serviceTypeRequest.component = yval;
+ $scope.ecdapp.validComp = true;
+ } else if (ykey === "typeName") {
+ $scope.ecdapp.serviceTypeRequest.typeName = yval;
+ } else if (ykey === "typeVersion") {
+ $scope.ecdapp.serviceTypeRequest.typeVersion = yval;
+ } else if (ykey === "blueprintTemplate") {
+ $scope.ecdapp.serviceTypeRequest.blueprintTemplate = yval;
+ }
+ }
+ }
+
+ $scope.ecdapp.handleImportCb = function($event) {
+ var checkbox = $event.target;
+ var action = (checkbox.checked ? 'import' : 'regular');
+ if (action === 'import' && $scope.ecdapp.isInternal) {
+ $scope.ecdapp.serviceTypeRequest.application = '';
+ $scope.ecdapp.serviceTypeRequest.component = '';
+ $scope.ecdapp.isImport = true;
+ }
+ if (action === 'regular' && $scope.ecdapp.isInternal) {
+ $scope.ecdapp.serviceTypeRequest.application = 'Select Application';
+ $scope.ecdapp.serviceTypeRequest.component = 'Select Component';
+ $scope.ecdapp.isImport = false;
+ }
+ }
+ // Handler for file-select event
+ $scope.ecdapp.handleImportFile = function() {
+ if (debug)
+ $log.debug('handleFileSelect: $scope.ecdapp.fileModel.name is ' + $scope.ecdapp.serviceTypeRequest.fileModel.name);
+ importFileReader.readAsText($scope.ecdapp.serviceTypeRequest.fileModel);
+ };
+
+
+ //$scope.ecdapp.components = [{"ECOMPC":[{"compId":1,"cname":"controller","dname":"CONTROLLER"},{"compId":2,"cname":"mso","dname":"MSO"},{"compId":3,"cname":"appc","dname":"APP-C"},{"compId":4,"cname":"clamp","dname":"CLAMP"},{"compId":5,"cname":"ecompscheduler","dname":"ECOMP SCHEDULER"},{"compId":6,"cname":"policy","dname":"POLICY"},{"compId":7,"cname":"eipam","dname":"EIPAM"},{"compId":181,"cname":"pdasms","dname":"PDAS-MS"},{"cname":"true"}]},
+ // {"DCAE": [{"compId":8,"cname":"dcae","dname":"DCAE"}]}];
+ $scope.ecdapp.selectAppComp = function(appName) {
+ if(appName === "Select Application") {
+ $scope.ecdapp.validAppl = false;
+ } else {
+ $scope.ecdapp.comps = [];
+ $scope.ecdapp.serviceTypeRequest.component = "";
+ $scope.ecdapp.validAppl = true;
+ for (var appIndx = 0; appIndx < $scope.ecdapp.components.length; appIndx++) {
+ if ($scope.ecdapp.components[appIndx].app === appName) {
+ $scope.ecdapp.comps = $scope.ecdapp.components[appIndx].comps;
+ break;
}
- //console.log("Saving " + applicationName + " to components list");
- InventoryBlueprintService.insertComponent(compName, compDisplayName.toUpperCase()).then(function(jsonObj) {
- if (jsonObj.error) {
- $log.error("inventoryBlueprintController.loadComponents failed: " + jsonObj.error);
- } else {
- if (debug)
- $log.debug("inventoryBlueprintController.loadComponents succeeded, size " + jsonObj.data.length);
- //console.log(jsonObj);
- InventoryBlueprintService.getComponents().then(function(jsonObj) {
- /*
- $scope.ecdapp.newApplicationName = "";
- $scope.ecdapp.newApplicationDisplayName = "";
- $scope.ecdapp.selectedOption = $scope.ecdapp.components[0];
- */
- $scope.ecdapp.components = jsonObj;
- $scope.ecdapp.enableAppForm = false;
- $scope.ecdapp.selectAppComp(appName);
- });
- }
- }, function(error) {
- $log.error("inventoryBlueprintController.addApplication failed: " + error);
- });
- };
-
- // Handler for file-select event
- $scope.handleFileSelect = function() {
- if (debug)
- $log.debug('handleFileSelect: $scope.ecdapp.fileModel.name is ' + $scope.ecdapp.serviceTypeRequest.fileModel.name);
- fileReader.readAsText($scope.ecdapp.serviceTypeRequest.fileModel);
- };
- // Convert serviceIds, serviceLocations, and vnfTypes to JSON Array
- $scope.ecdapp.convertStringsToArrays = function(serviceTypeRequest) {
- if (serviceTypeRequest.serviceIds || serviceTypeRequest.serviceIds.trim() != '') {
- try {
- serviceTypeRequest.serviceIds = angular.fromJson(serviceTypeRequest.serviceIds.split(","));
- } catch (error) {
- return 'Service Ids is not in the correct format.';
- }
- } else {
- serviceTypeRequest.serviceIds = [];
- }
-
- if (serviceTypeRequest.serviceLocations || serviceTypeRequest.serviceLocations.trim() != '') {
- try {
- serviceTypeRequest.serviceLocations = angular.fromJson(serviceTypeRequest.serviceLocations.split(","));
- } catch (error) {
- return 'Service Locations is not in the correct format.';
- }
- } else {
- serviceTypeRequest.serviceLocations = [];
- }
-
- if (serviceTypeRequest.vnfTypes || serviceTypeRequest.vnfTypes.trim() != '') {
- try {
- serviceTypeRequest.vnfTypes = angular.fromJson(serviceTypeRequest.vnfTypes.split(","));
- } catch (error) {
- return 'VNF Types is not in the correct format.';
- }
- } else {
- serviceTypeRequest.vnfTypes = [];
- }
-
- try {
- if (isNaN(serviceTypeRequest.typeVersion)) {
- serviceTypeRequest.typeVersion = serviceTypeRequest.typeVersion.replace(/\./gi, "");
- serviceTypeRequest.typeVersion = angular.fromJson(serviceTypeRequest.typeVersion);
- }
- } catch (error) {
- return 'typeVersion is not in the correct format.';
- }
-
- return null;
- }
-
- /**
- * Validates content of user-editable fields.
- * Returns null if all is well,
- * a descriptive error message otherwise.
- */
- $scope.ecdapp.validateRequest = function(serviceTypeRequest) {
- if (!serviceTypeRequest)
- return 'No data found.\nPlease enter some values.';
- if (!serviceTypeRequest.owner || serviceTypeRequest.owner.trim() == '') {
- return 'Application/Owner is required.\nPlease enter a value.';
- }
- if (!serviceTypeRequest.typeName || serviceTypeRequest.typeName.trim() == '') {
- return 'Type Name is required.\nPlease enter a value.';
- }
- if (!serviceTypeRequest.typeVersion ) {
- //|| serviceTypeRequest.typeVersion.trim() == '') {
- return 'Type Version is required.\nPlease enter a value.';
- }
- if (!serviceTypeRequest.blueprintTemplate || serviceTypeRequest.blueprintTemplate.trim() == '')
- return 'Blueprint Template is required.\nPlease enter a value.';
-
- return null;
- }
-
- $scope.ecdapp.uploadBlueprint = function(serviceTypeRequest) {
- if (debug)
- $log.debug('uploadBlueprint: serviceType is ' + JSON.stringify(serviceTypeRequest));
- $scope.ecdapp.uploadInProgress = true;
- var validateMsg = $scope.ecdapp.validateRequest(serviceTypeRequest);
- if (validateMsg != null) {
- editServiceType = angular.copy(serviceTypeRequest);
- alert('Invalid Request:\n' + validateMsg);
- $scope.ecdapp.uploadInProgress = false;
- return;
- }
- //var authUser = $scope.userId;
- //serviceTypeRequest.owner = serviceTypeRequest.owner + ':' + authUser;
- // Create a editServiceTypeRequest object for edit
- var editServiceType = angular.copy(serviceTypeRequest);
- var convertMsg = $scope.ecdapp.convertStringsToArrays(editServiceType);
- if (convertMsg != null) {
- editServiceType = angular.copy(serviceTypeRequest);
- alert('Invalid Request:\n' + convertMsg);
- return;
- }
-
- InventoryBlueprintService.uploadBlueprint(editServiceType)
- .then(function(response) {
- if (debug)
- $log.debug('inventoryBlueprintUploadCtrl.uploadBlueprint: ' + JSON.stringify(response));
- if (response && response.error) {
- $log.error('InventoryBlueprintService.uploadBlueprint failed: ' + response.error);
- alert('Failed to upload blueprint:\n' + response.error);
- }
- else {
- // Upload service returns null on success.
- $modalInstance.close("success");
- }
- $scope.ecdapp.uploadInProgress = false;
- },
- function(error) {
- $log.error('InventoryBlueprintService.uploadBlueprint failed: ' + error);
- $scope.ecdapp.uploadInProgress = false;
- alert('Service failed to upload blueprint:\n' + error);
- });
-
- };
+ }
+ }
+ }
+
+ $scope.ecdapp.validateComp = function(appName) {
+ if($scope.ecdapp.serviceTypeRequest.component === "Select Component"){
+ $scope.ecdapp.validComp = false;
+ } else {
+ $scope.ecdapp.validComp = true;
+ }
+ }
+ var fileReader = new FileReader();
+ fileReader.onload = function(event) {
+ let yamlString = fileReader.result;
+ $scope.ecdapp.serviceTypeRequest.blueprintTemplate = yamlString;
+ }
+
+ // Handler for file-select event
+ $scope.handleFileSelect = function() {
+ if (debug)
+ $log.debug('handleFileSelect: $scope.ecdapp.fileModel.name is ' + $scope.ecdapp.serviceTypeRequest.fileModel.name);
+ fileReader.readAsText($scope.ecdapp.serviceTypeRequest.fileModel);
+ };
+ // Convert serviceIds, serviceLocations, and vnfTypes to JSON Array
+
+ $scope.ecdapp.convertStringsToArrays = function(serviceTypeRequest) {
+ if (serviceTypeRequest.serviceIds || serviceTypeRequest.serviceIds.trim() != '') {
+ try {
+ serviceTypeRequest.serviceIds = angular.fromJson(serviceTypeRequest.serviceIds.split(","));
+ } catch (error) {
+ return 'Service Ids is not in the correct format.';
+ }
+ } else {
+ serviceTypeRequest.serviceIds = [];
+ }
+
+ if (serviceTypeRequest.serviceLocations || serviceTypeRequest.serviceLocations.trim() != '') {
+ try {
+ serviceTypeRequest.serviceLocations = angular.fromJson(serviceTypeRequest.serviceLocations.split(","));
+ } catch (error) {
+ return 'Service Locations is not in the correct format.';
+ }
+ } else {
+ serviceTypeRequest.serviceLocations = [];
+ }
+
+ if (serviceTypeRequest.vnfTypes || serviceTypeRequest.vnfTypes.trim() != '') {
+ try {
+ serviceTypeRequest.vnfTypes = angular.fromJson(serviceTypeRequest.vnfTypes.split(","));
+ } catch (error) {
+ return 'VNF Types is not in the correct format.';
+ }
+ } else {
+ serviceTypeRequest.vnfTypes = [];
+ }
+ return null;
+ }
+
+ $scope.ecdapp.isInt = function(value) {
+ return !isNaN(value) &&
+ parseInt(Number(value)) == value &&
+ !isNaN(parseInt(value, 10));
+ }
+ /**
+ * Validates content of user-editable fields.
+ * Returns null if all is well,
+ * a descriptive error message otherwise.
+ */
+ $scope.ecdapp.validateRequest = function(serviceTypeRequest) {
+ if (!serviceTypeRequest)
+ return 'No data found.\nPlease enter some values.';
+ if (!serviceTypeRequest.owner || serviceTypeRequest.owner.trim() == '') {
+ return 'Application/Owner is required.\nPlease enter a value.';
+ }
+ if (!serviceTypeRequest.typeName || serviceTypeRequest.typeName.trim() == '') {
+ return 'Type Name is required.\nPlease enter a value.';
+ }
+ if (!serviceTypeRequest.typeVersion ) {
+ //|| serviceTypeRequest.typeVersion.trim() == '') {
+ return 'Type Version is required.\nPlease enter a value.';
+ }
+ if (!$scope.ecdapp.isInt(serviceTypeRequest.typeVersion) ) {
+ //|| serviceTypeRequest.typeVersion.trim() == '') {
+ return 'Type Version should be a valid Integer.';
+ }
+ if (!serviceTypeRequest.blueprintTemplate || serviceTypeRequest.blueprintTemplate.trim() == '')
+ return 'Blueprint Template is required.\nPlease enter a value.';
+
+ return null;
+ }
+
+ $scope.ecdapp.uploadBlueprint = function(serviceTypeRequest) {
+ if (debug)
+ $log.debug('uploadBlueprint: serviceType is ' + JSON.stringify(serviceTypeRequest));
+ $scope.ecdapp.uploadInProgress = true;
+ var validateMsg = $scope.ecdapp.validateRequest(serviceTypeRequest);
+ if (validateMsg != null) {
+ editServiceType = angular.copy(serviceTypeRequest);
+ alert('Invalid Request:\n' + validateMsg);
+ $scope.ecdapp.uploadInProgress = false;
+ return;
+ }
+ //var authUser = $scope.userId;
+ //serviceTypeRequest.owner = serviceTypeRequest.owner + ':' + authUser;
+ // Create a editServiceTypeRequest object for edit
+ var editServiceType = angular.copy(serviceTypeRequest);
+ var convertMsg = $scope.ecdapp.convertStringsToArrays(editServiceType);
+ if (convertMsg != null) {
+ editServiceType = angular.copy(serviceTypeRequest);
+ alert('Invalid Request:\n' + convertMsg);
+ return;
+ }
+
+ InventoryBlueprintService.uploadBlueprint(editServiceType)
+ .then(function(response) {
+ if (debug)
+ $log.debug('inventoryBlueprintUploadCtrl.uploadBlueprint: ' + JSON.stringify(response));
+ if (response && response.error) {
+ $log.error('InventoryBlueprintService.uploadBlueprint failed: ' + response.error);
+ alert('Failed to upload blueprint:\n' + response.error);
+ }
+ else {
+ // Upload service returns null on success.
+ $modalInstance.close("success");
+ }
+ $scope.ecdapp.uploadInProgress = false;
+ },
+ function(error) {
+ $log.error('InventoryBlueprintService.uploadBlueprint failed: ' + error);
+ $scope.ecdapp.uploadInProgress = false;
+ alert('Service failed to upload blueprint:\n' + error);
+ });
+
+ };
});
/*************************************************************************/
appDS2.controller('inventoryBlueprintViewCtrl', function(
- $scope, $log, message, InventoryBlueprintService) {
-
- 'use strict';
-
- var debug = false;
-
- if (debug)
- $log.debug("inventoryBlueprintViewCtrl.message: " + JSON.stringify(message));
-
- // this object holds all app data and functions
- $scope.ecdapp = {};
- $scope.ecdapp.blueprintId = message.blueprint.typeId;
-
- $scope.ecdapp.label = 'View Blueprint ' + message.blueprint.typeName;
-
- // Fetch the blueprint
- $scope.ecdapp.isDataLoading = true;
- InventoryBlueprintService.viewBlueprint(message.blueprint.typeId).then(function(jsonObj) {
- if (debug)
- $log.debug("inventoryBlueprintViewCtrl.viewBlueprint response: " + JSON.stringify(jsonObj));
- if (jsonObj.error) {
- $scope.ecdapp.errMsg = 'Request Failed';
- }
- else {
- $scope.ecdapp.blueprint = jsonObj.blueprintTemplate;
- }
- $scope.ecdapp.isDataLoading = false;
- }, function(error) {
- $scope.ecdapp.isDataLoading = false;
- alert('Failed to get blueprint. Please retry.');
- $log.error("blueprintViewCtrl failed: " + error);
- });
-
+ $scope, $log, message, InventoryBlueprintService) {
+
+ 'use strict';
+
+ var debug = false;
+
+ if (debug)
+ $log.debug("inventoryBlueprintViewCtrl.message: " + JSON.stringify(message));
+
+ // this object holds all app data and functions
+ $scope.ecdapp = {};
+ $scope.ecdapp.blueprintId = message.blueprint.typeId;
+
+ $scope.ecdapp.label = 'View Blueprint ' + message.blueprint.typeName;
+
+ // Fetch the blueprint
+ $scope.ecdapp.isDataLoading = true;
+ InventoryBlueprintService.viewBlueprint(message.blueprint.typeId).then(function(jsonObj) {
+ if (debug)
+ $log.debug("inventoryBlueprintViewCtrl.viewBlueprint response: " + JSON.stringify(jsonObj));
+ if (jsonObj.error) {
+ $scope.ecdapp.errMsg = 'Request Failed';
+ }
+ else {
+ $scope.ecdapp.blueprint = jsonObj.blueprintTemplate;
+ }
+ $scope.ecdapp.isDataLoading = false;
+ }, function(error) {
+ $scope.ecdapp.isDataLoading = false;
+ alert('Failed to get blueprint. Please retry.');
+ $log.error("blueprintViewCtrl failed: " + error);
+ });
+
});
+appDS2.directive('json', function() {
+ return {
+ restrict: 'A', // only activate on element attribute
+ require: 'ngModel', // get a hold of NgModelController
+ link: function(scope, element, attrs, ngModelCtrl) {
+ function toUser(object) {
+ if (typeof object === 'object') {
+ return angular.toJson(object, true);
+ } else {
+ return object;
+ }
+ }
+ ngModelCtrl.$formatters.push(toUser);
+ // $watch(attrs.ngModel) wouldn't work if this directive created a new scope;
+ // see http://stackoverflow.com/questions/14693052/watch-ngmodel-from-inside-directive-using-isolate-scope how to do it then
+ scope.$watch(attrs.ngModel, function(newValue, oldValue) {
+ if (newValue != oldValue) {
+ ngModelCtrl.$setViewValue(toUser(newValue));
+ // TODO avoid this causing the focus of the input to be lost..
+ ngModelCtrl.$render();
+ }
+ }, true); // MUST use objectEquality (true) here, for some reason..
+ }
+ };
+});
/*************************************************************************/
appDS2.controller('inventoryBlueprintDeployCtrl', function(
- $scope, $rootScope, $log, $modal, $modalInstance, message, InventoryDeploymentService, InventoryBlueprintService) {
-
- 'use strict';
-
- // Controls logging in this controller
- var debug = false;
-
- // this object holds all app data and functions
- $scope.ecdapp = {};
- $scope.ecdapp.label = 'Deploy Blueprint';
- $scope.ecdapp.errMsg = '';
-
- // deployment in progress
- $scope.ecdapp.deploymentInProgress = false;
- $scope.ecdapp.isDataLoading = false;
- $scope.ecdapp.tenant = $rootScope.tenantList.tenant;
- $scope.ecdapp.validTenant = false;
-
- // Cache the input parameter names for validation
- if (debug)
- $log.debug('inventoryBlueprintDeployCtrl: inputs: ' + JSON.stringify(message.blueprint.blueprintInputs));
- $scope.ecdapp.inputsDict = message.blueprint.blueprintInputs;
-
- // Copy the input parameter names and default values
- let inputsAndDefaults = {};
- for (var pkey in message.blueprint.blueprintInputs) {
- if (debug)
- $log.debug('inventoryBlueprintDeployCtrl: checking key ' + pkey);
- let dval = message.blueprint.blueprintInputs[pkey].defaultValue;
- if ( typeof dval === "undefined" )
- dval = '';
- inputsAndDefaults[pkey] = dval;
- }
- if (debug)
- $log.debug('inventoryBlueprintDeployCtrl: inputsAndDefaults: ' + JSON.stringify(inputsAndDefaults));
-
- // Create an object for edit
- //var genDeployId = message.blueprint.component + "_" + message.blueprint.typeName;
- $scope.ecdapp.editRequest = {
- deployment_id : '',
- type_id : message.blueprint.typeId,
- fileModel : null,
- parmFileDict : inputsAndDefaults,
- tenant : '',
- component: message.blueprint.component,
- tag : message.blueprint.typeName
- };
- $scope.ecdapp.validateTenant = function(){
- if($scope.ecdapp.editRequest.tenant === "Select Tenant"){
- $scope.ecdapp.validTenant = false;
- }else{
- $scope.ecdapp.validTenant = true;
- }
+ $scope, $rootScope, $log, $modal, $modalInstance, message, InventoryDeploymentService, InventoryBlueprintService) {
+
+ 'use strict';
+
+ // Controls logging in this controller
+ var debug = false;
+
+ // this object holds all app data and functions
+ $scope.ecdapp = {};
+ $scope.ecdapp.label = 'Deploy Blueprint';
+ $scope.ecdapp.errMsg = '';
+ $scope.ecdapp.availableTenants = message.tenantList;
+
+ $scope.ecdapp.deploymentInProgress = false;
+ $scope.ecdapp.validTenant = false;
+ let inputsAndDefaults = {};
+ let inputsAndDescriptions = {};
+
+ // Create an object for edit
+ $scope.ecdapp.editRequest = {
+ deployment_id : '',
+ type_id : message.blueprint.typeId,
+ fileModel : null,
+ parmFileDict : inputsAndDefaults,
+ descriptionDict : inputsAndDescriptions,
+ tenant : '',
+ component: message.blueprint.component,
+ tag : message.blueprint.typeName
+ };
+ // Fetch the blueprint
+ $scope.ecdapp.isDataLoading = true;
+ InventoryBlueprintService.viewBlueprint(message.blueprint.typeId).then(function(jsonObj) {
+ if (debug)
+ $log.debug("inventoryBlueprintViewCtrl.viewBlueprint response: " + JSON.stringify(jsonObj));
+ if (jsonObj.error) {
+ $scope.ecdapp.errMsg = 'Request Failed';
+ }
+ else {
+ $scope.ecdapp.inputsDict = jsonObj.blueprintInputs;
+ for (var pkey in $scope.ecdapp.inputsDict) {
+ if (debug)
+ $log.debug('inventoryBlueprintDeployCtrl: checking key ' + pkey);
+ let dval = $scope.ecdapp.inputsDict[pkey].defaultValue;
+ let description = $scope.ecdapp.inputsDict[pkey].description;
+ if ( typeof dval === "undefined" )
+ dval = '';
+ if ( typeof description === "undefined" )
+ description = '';
+ inputsAndDefaults[pkey] = dval;
+ inputsAndDescriptions[pkey] = description;
+ if (debug)
+ $log.debug('inventoryBlueprintDeployCtrl: inputsAndDefaults: ' + JSON.stringify(inputsAndDefaults));
+ }
+ }
+ $scope.ecdapp.isDataLoading = false;
+ }, function(error) {
+ $scope.ecdapp.isDataLoading = false;
+ alert('Failed to get blueprint. Please retry.');
+ $log.error("blueprintViewCtrl failed: " + error);
+ });
+
+ $scope.ecdapp.validateTenant = function(){
+ if($scope.ecdapp.editRequest.tenant === "Select Tenant"){
+ $scope.ecdapp.validTenant = false;
+ }else{
+ $scope.ecdapp.validTenant = true;
+ }
+ }
+ /**
+ * Handler for file-read event reads file, parses JSON, validates content.
+ */
+ var fileReader = new FileReader();
+ fileReader.onload = function(event) {
+ let jsonString = fileReader.result;
+ if (debug)
+ $log.debug('fileReader.onload: read: ' + jsonString);
+ let ydict = {};
+ try {
+ ydict = JSON.parse(jsonString);
+ }
+ catch (ex) {
+ alert('Failed to parse file as JSON:\n' + ex);
}
- /**
- * Handler for file-read event reads file, parses JSON, validates content.
- */
- var fileReader = new FileReader();
- fileReader.onload = function(event) {
- let jsonString = fileReader.result;
- if (debug)
- $log.debug('fileReader.onload: read: ' + jsonString);
- let ydict = {};
- try {
- ydict = JSON.parse(jsonString);
- }
- catch (ex) {
- alert('Failed to parse file as JSON:\n' + ex);
- }
- // Process the file
- for (var ykey in ydict) {
- let yval = ydict[ykey];
- if (debug)
- $log.debug('fileReader.onload: typeof ' + ykey + ' is ' + typeof ykey);
- // Allow only expected keys with scalar values
- if (! (ykey in $scope.ecdapp.editRequest.parmFileDict))
- alert('Unexpected file content:\nKey not defined by blueprint:\n' + ykey);
- /*
+ // Process the file
+ for (var ykey in ydict) {
+ let yval = ydict[ykey];
+ if (debug)
+ $log.debug('fileReader.onload: typeof ' + ykey + ' is ' + typeof ykey);
+ // Allow only expected keys with scalar values
+ if (! (ykey in $scope.ecdapp.editRequest.parmFileDict))
+ alert('Unexpected file content:\nKey not defined by blueprint:\n' + ykey);
+ /*
else if (typeof yval !== 'string' && typeof yval !== 'number')
alert('Unexpected file content:\nNot a simple key-value pair:\n' + ykey);
- */
- if (yval.constructor === {}.constructor)
- $scope.ecdapp.editRequest.parmFileDict[ykey] = angular.toJson(yval);
- else
- $scope.ecdapp.editRequest.parmFileDict[ykey] = yval;
- }
- if (debug)
- $log.debug('fileReader.onload: parmFileDict: ' + JSON.stringify($scope.ecdapp.editRequest.parmFileDict));
-
- // Update table in all cases
- $scope.$apply();
- }
-
- // Handler for file-select event
- $scope.handleFileSelect = function() {
- if (debug)
- $log.debug('handleFileSelect: $scope.ecdapp.fileModel.name is ' + $scope.ecdapp.editRequest.fileModel.name);
- fileReader.readAsText($scope.ecdapp.editRequest.fileModel);
- };
-
- /**
- * Validates content of user-editable fields.
- * Returns null if all is well,
- * a descriptive error message otherwise.
- */
- $scope.ecdapp.validateRequest = function(editRequest) {
- if (editRequest == null)
- return 'No data found.\nPlease enter some values.';
- if (editRequest.deployment_id == null || editRequest.deployment_id.trim() == '')
- return 'Deployment ID is required.\nPlease enter a value.';
- if (editRequest.type_id == null || editRequest.type_id.trim() == '')
- return 'Type ID is required.\nPlease enter a value.';
- if (editRequest.tag == null || editRequest.tag.trim() == '')
- return 'Deployment tag is required.\nPlease enter a value.';
- if (editRequest.tenant == null || editRequest.tenant.trim() == '')
- return 'Tenant name is required.\nPlease enter a value.';
- // Check that every file parameter is defined by blueprint
- for (var pkey in $scope.ecdapp.editRequest.parmFileDict) {
- // Defined in blueprint?
- if (! $scope.ecdapp.inputsDict[pkey])
- return 'Unexpected input parameter\n' + pkey;
- return null;
- }
- };
-
- $scope.ecdapp.viewDeploymentExecutionsModalPopup = function(deployment) {
- var modalInstance = $modal.open({
- templateUrl : 'inventory_execution_view_popup.html',
- controller : 'inventoryDeploymentExecutionsViewCtrl',
- windowClass: 'modal-docked',
- sizeClass: 'modal-jumbo',
- resolve : {
- message : function() {
- var dataForPopup = {
- deployment : deployment
- };
- return dataForPopup;
- }
- }
- });
- modalInstance.result.then(function(response) {
- // No response.
- });
- };
- $scope.ecdapp.deployBlueprint = function(editRequest) {
- //editRequest.tenant = $rootScope.tenantList.tenant;
- $scope.ecdapp.errMsg = '';
- editRequest.deployment_id = editRequest.component + "_" + editRequest.tag;
- if (debug)
- $log.debug('deployBlueprint: editRequest is ' + JSON.stringify($scope.ecdapp.editRequest));
- var validateMsg = $scope.ecdapp.validateRequest(editRequest);
- if (validateMsg != null) {
- alert('Invalid Request:\n' + validateMsg);
- return;
- }
- // Create request with key:value parameters dictionary
- let deploymentRequestObject = {
- deploymentId : editRequest.deployment_id,
- serviceTypeId : editRequest.type_id,
- inputs : {},
- tenant : editRequest.tenant,
- method : "create"
- };
- let deploymentExecObj = {
- deploymentRef : editRequest.deployment_id,
- tenant : editRequest.tenant
- }
- for (var pkey in $scope.ecdapp.editRequest.parmFileDict)
- try {
- deploymentRequestObject.inputs[pkey] = angular.fromJson($scope.ecdapp.editRequest.parmFileDict[pkey]);
- } catch (error) {
- deploymentRequestObject.inputs[pkey] = $scope.ecdapp.editRequest.parmFileDict[pkey];
- }
- if (debug)
- $log.debug('deployBlueprint: deploymentRequestObject is ' + JSON.stringify(deployRequestObject));
-
- $scope.ecdapp.deploymentInProgress = true;
- InventoryDeploymentService.deployBlueprint(deploymentRequestObject)
- .then(function(response) {
- $scope.ecdapp.deploymentInProgress = false;
- if (response.error) {
- $scope.ecdapp.errMsg = 'Failed to deploy blueprint: ' + response.error;
- alert('Failed to deploy blueprint:\n' + response.error);
- }
- else {
- $modalInstance.close(response);
- // launch the view executions modal
- $scope.ecdapp.viewDeploymentExecutionsModalPopup(deploymentExecObj);
- }
- },
- function (error) {
- $log.error('inventoryBlueprintDeployCtrl: error while deploying: ' + error);
- $scope.ecdapp.errMsg = 'Server rejected deployment request: ' + error;
- alert('Server rejected deployment request:\n' + error);
- $scope.ecdapp.deploymentInProgress = false;
- }
- );
- };
+ */
+ if (yval.constructor === {}.constructor)
+ $scope.ecdapp.editRequest.parmFileDict[ykey] = angular.toJson(yval);
+ else
+ $scope.ecdapp.editRequest.parmFileDict[ykey] = yval;
+ }
+ if (debug)
+ $log.debug('fileReader.onload: parmFileDict: ' + JSON.stringify($scope.ecdapp.editRequest.parmFileDict));
+
+ // Update table in all cases
+ $scope.$apply();
+ }
+
+ // Handler for file-select event
+ $scope.handleFileSelect = function() {
+ if (debug)
+ $log.debug('handleFileSelect: $scope.ecdapp.fileModel.name is ' + $scope.ecdapp.editRequest.fileModel.name);
+ fileReader.readAsText($scope.ecdapp.editRequest.fileModel);
+ };
+
+ /**
+ * Validates content of user-editable fields.
+ * Returns null if all is well,
+ * a descriptive error message otherwise.
+ */
+ $scope.ecdapp.validateRequest = function(editRequest) {
+ if (editRequest == null)
+ return 'No data found.\nPlease enter some values.';
+ if (editRequest.deployment_id == null || editRequest.deployment_id.trim() == '')
+ return 'Deployment ID is required.\nPlease enter a value.';
+ if (editRequest.type_id == null || editRequest.type_id.trim() == '')
+ return 'Type ID is required.\nPlease enter a value.';
+ if (editRequest.tag == null || editRequest.tag.trim() == '')
+ return 'Deployment tag is required.\nPlease enter a value.';
+ if (editRequest.tenant == null || editRequest.tenant.trim() == '')
+ return 'Tenant name is required.\nPlease enter a value.';
+ // Check that every file parameter is defined by blueprint
+ for (var pkey in $scope.ecdapp.editRequest.parmFileDict) {
+ // Defined in blueprint?
+ if (! $scope.ecdapp.inputsDict[pkey])
+ return 'Unexpected input parameter\n' + pkey;
+ return null;
+ }
+ };
+
+ $scope.ecdapp.viewDeploymentExecutionsModalPopup = function(deployment) {
+ var modalInstance = $modal.open({
+ templateUrl : 'inventory_execution_view_popup.html',
+ controller : 'inventoryDeploymentExecutionsViewCtrl',
+ windowClass: 'modal-docked',
+ sizeClass: 'modal-jumbo',
+ resolve : {
+ message : function() {
+ var dataForPopup = {
+ deployment : deployment
+ };
+ return dataForPopup;
+ }
+ }
+ });
+ modalInstance.result.then(function(response) {
+ // No response.
+ });
+ };
+ $scope.ecdapp.deployBlueprint = function(editRequest) {
+ //editRequest.tenant = $rootScope.tenantList.tenant;
+ $scope.ecdapp.errMsg = '';
+ editRequest.deployment_id = editRequest.component + "_" + editRequest.tag;
+ if (debug)
+ $log.debug('deployBlueprint: editRequest is ' + JSON.stringify($scope.ecdapp.editRequest));
+ var validateMsg = $scope.ecdapp.validateRequest(editRequest);
+ if (validateMsg != null) {
+ alert('Invalid Request:\n' + validateMsg);
+ return;
+ }
+ // Create request with key:value parameters dictionary
+ let deploymentRequestObject = {
+ deploymentId : editRequest.deployment_id,
+ serviceTypeId : editRequest.type_id,
+ inputs : {},
+ tenant : editRequest.tenant,
+ method : "create"
+ };
+ let deploymentExecObj = {
+ deploymentRef : editRequest.deployment_id,
+ tenant : editRequest.tenant
+ }
+ for (var pkey in $scope.ecdapp.editRequest.parmFileDict)
+ try {
+ deploymentRequestObject.inputs[pkey] = angular.fromJson($scope.ecdapp.editRequest.parmFileDict[pkey]);
+ } catch (error) {
+ deploymentRequestObject.inputs[pkey] = $scope.ecdapp.editRequest.parmFileDict[pkey];
+ }
+ if (debug)
+ $log.debug('deployBlueprint: deploymentRequestObject is ' + JSON.stringify(deployRequestObject));
+
+ $scope.ecdapp.deploymentInProgress = true;
+
+ InventoryDeploymentService.deployBlueprint(deploymentRequestObject)
+ .then(function(response) {
+ $scope.ecdapp.deploymentInProgress = false;
+ if (response.error) {
+ $scope.ecdapp.errMsg = 'Failed to deploy blueprint: ' + response.error;
+ alert('Failed to deploy blueprint:\n' + response.error);
+ InventoryDeploymentService.deleteBlueprint(editRequest.deployment_id, editRequest.tenant);
+ }
+ else {
+ $modalInstance.close(response);
+ // launch the view executions modal
+ $scope.ecdapp.viewDeploymentExecutionsModalPopup(deploymentExecObj);
+ }
+ },
+ function (error) {
+ $log.error('inventoryBlueprintDeployCtrl: error while deploying: ' + error);
+ $scope.ecdapp.errMsg = 'Server rejected deployment request: ' + error;
+ alert('Server rejected deployment request:\n' + error);
+ $scope.ecdapp.deploymentInProgress = false;
+ }
+ );
+ };
});
diff --git a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/inventory/blueprint-service.js b/ccsdk-app-overlay/src/main/webapp/app/ccsdk/inventory/blueprint-service.js
index b553c9e..02709d3 100644
--- a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/inventory/blueprint-service.js
+++ b/ccsdk-app-overlay/src/main/webapp/app/ccsdk/inventory/blueprint-service.js
@@ -35,11 +35,92 @@ appDS2.factory('InventoryBlueprintService', function ($http, $q, $log) {
return $q.reject(error.statusText);
});
},
+ getBlueprintsSummary: function() {
+ // cache control for IE
+ let cc = "&cc=" + new Date().getTime().toString();
+ let url = null;
+ url = 'inventory/dcae-service-types?_include=typeName,typeVersion,typeId' + cc;
+ return $http({
+ method: 'GET',
+ url: url,
+ cache: false,
+ responseType: 'json'
+ }).then(function(response) {
+ if (response.data == null || typeof response.data != 'object')
+ return $q.reject('InventoryBlueprintService.getBlueprintsSummary: response.data null or not object');
+ else
+ return response.data;
+ },
+ function(error) {
+ $log.error('InventoryBlueprintService.getBlueprintsSummary failed: ' + JSON.stringify(error));
+ return $q.reject(error.statusText);
+ });
+ },
+ getOwnersList: function() {
+ let url = 'inventory/owners';
+ return $http({
+ method: 'GET',
+ url: url,
+ cache: false,
+ responseType: 'json'
+ }).then(function(response) {
+ if (response.data == null || typeof response.data != 'object')
+ return $q.reject('InventoryBlueprintService.getOwnersList: response.data null or not object');
+ else
+ return response.data;
+ },
+ function(error) {
+ $log.error('InventoryBlueprintService.getOwnersList failed: ' + JSON.stringify(error));
+ return $q.reject(error.statusText);
+ });
+ },
+ getBlueprintsList: function() {
+ let url = 'inventory/service-type-list';
+ return $http({
+ method: 'GET',
+ url: url,
+ cache: false,
+ responseType: 'json'
+ }).then(function(response) {
+ if (response.data == null || typeof response.data != 'object')
+ return $q.reject('InventoryBlueprintService.getBlueprintsList: response.data null or not object');
+ else
+ return response.data;
+ },
+ function(error) {
+ $log.error('InventoryBlueprintService.getBlueprintsList failed: ' + JSON.stringify(error));
+ return $q.reject(error.statusText);
+ });
+ },
+ getBlueprintIdsList: function(searchBy) {
+ let url = '';
+ if (searchBy) {
+ url = 'inventory/service-type-id-list?searchBy=' + searchBy;
+ } else {
+ url = 'inventory/service-type-id-list';
+ }
+ return $http({
+ method: 'GET',
+ url: url,
+ cache: false,
+ responseType: 'json'
+ }).then(function(response) {
+ if (response.data == null || typeof response.data != 'object')
+ return $q.reject('InventoryBlueprintService.getBlueprintIdsList: response.data null or not object');
+ else
+ return response.data;
+ },
+ function(error) {
+ $log.error('InventoryBlueprintService.getBlueprintIdsList failed: ' + JSON.stringify(error));
+ return $q.reject(error.statusText);
+ });
+ },
/**
* get deployments for a blueprint
*/
getDeploymentForBp: function(bpArr) {
- let url = 'inventory/dcae-services/typeIds';
+ let url = 'deployment_blueprint_map';
+ //let url = 'inventory/dcae-services/typeIds';
return $http({
method: 'POST',
url: url,
@@ -49,7 +130,6 @@ appDS2.factory('InventoryBlueprintService', function ($http, $q, $log) {
if (response.data == null)
return $q.reject('InventoryBlueprintService.getDeploymentForBp: response.data null or not object');
else {
- console.log(response.data);
return response.data;
}
},
@@ -166,7 +246,6 @@ appDS2.factory('InventoryBlueprintService', function ($http, $q, $log) {
if (response.data == null)
return $q.reject('InventoryBlueprintService.viewBlueprint: response.data null or not object');
else {
- console.log(response.data);
return response.data;
}
},
@@ -281,6 +360,12 @@ appDS2.factory('InventoryBlueprintService', function ($http, $q, $log) {
},
*/
deleteBlueprint: function(typeId) {
+ /*var typeId = blueprint.typeId;
+ var deploymentItems = blueprint.deployments.items;
+ var deplIdList = [];
+ for (var i=0; i < deploymentItems.length; i++) {
+ deplIdList.push(deploymentItems.id);
+ }*/
let url = 'inventory/dcae-service-types/' + typeId;
return $http({
method: 'DELETE',
diff --git a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/inventory/deployment-controllers.js b/ccsdk-app-overlay/src/main/webapp/app/ccsdk/inventory/deployment-controllers.js
deleted file mode 100644
index e17dcae..0000000
--- a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/inventory/deployment-controllers.js
+++ /dev/null
@@ -1,1352 +0,0 @@
-appDS2.controller('inventoryDeploymentTableController', function(
- $rootScope, $scope, $routeParams, $route,
- $interval, $log, $modal, modalService,
- InventoryDeploymentService, InventoryBlueprintService) {
-
- 'use strict';
-
- // Controls logging in this controller
- var debug = false;
-
- // this object holds all app data and functions
- $scope.ecdapp = {};
- // models for controls on screen
- $scope.ecdapp.tableData = [];
- $scope.ecdapp.currentPageNum = 1;
- $scope.ecdapp.viewPerPage = 10;
- // other
- $scope.ecdapp.errMsg = null;
- $scope.ecdapp.isDataLoading = true;
- $scope.ecdapp.isRequestFailed = false;
- // sorting
- $scope.ecdapp.sortBy = null;
- // searching
- $scope.ecdapp.searchBy = $routeParams.depId;
- $scope.ecdapp.selectedRow = null; // initialize our variable to null
- $scope.ecdapp.setClickedRow = function(index){ //function that sets the value of selectedRow to current index
- $scope.ecdapp.selectedRow = index;
- }
-
- $scope.ecdapp.updateTable = function() {
- $scope.ecdapp.isSrvcDataLoading = true;
- var srvcIds = [];
- var cloneGrid = $scope.ecdapp.tableData;
- angular.forEach($scope.ecdapp.tableData, function(item, index) {
- angular.forEach(item, function(value, key) {
- if (key === "deploymentRef") {
- srvcIds.push(value);
- }
- });
- });
-
- InventoryDeploymentService.getDeploymentStatus(srvcIds)
- .then(function(jsonObj) {
- if (jsonObj.error) {
- $log.error("inventoryDeploymentTableController.updateTable failed: " + jsonObj.error);
- } else {
- for (var indx = 0; indx < jsonObj.length; indx++) {
- if (jsonObj[indx].status === "terminated") {
- jsonObj[indx].status = "completed";
- jsonObj[indx].statusImg = "static/fusion/images/active.png";
- } else {
- jsonObj[indx].statusImg = "static/fusion/images/inactive.png";
- }
- cloneGrid[indx].statusInfo = jsonObj[indx];
- }
- $scope.ecdapp.tableData = cloneGrid;
- }
- $scope.ecdapp.isSrvcDataLoading = false;
- }, function(error) {
- $log.error("inventoryBlueprintController.updateTable failed: " + error);
- $scope.ecdapp.isSrvcDataLoading = false;
- });
- }
- /**
- * Loads the table. Interprets the remote controller's response and copies
- * to scope variables. The response is either a list to be assigned to
- * tableData, or an error to be shown.
- */
- $scope.ecdapp.loadTable = function(sortBy, searchBy) {
- $scope.ecdapp.isDataLoading = true;
- $scope.ecdapp.sortBy = sortBy;
- $scope.ecdapp.searchBy = searchBy;
- InventoryDeploymentService.getDeployments($scope.ecdapp.currentPageNum,
- $scope.ecdapp.viewPerPage, sortBy, searchBy).then(
- function(jsonObj) {
- if (jsonObj.error) {
- $log.error("inventoryDeploymentController.loadTable failed: "
- + jsonObj.error);
- $scope.ecdapp.isRequestFailed = true;
- $scope.ecdapp.errMsg = jsonObj.error;
- $scope.ecdapp.tableData = [];
- } else {
- $scope.ecdapp.isRequestFailed = false;
- $scope.ecdapp.errMsg = null;
- $scope.ecdapp.totalPages = jsonObj.totalPages;
- $scope.ecdapp.tableData = jsonObj.items;
- $scope.ecdapp.updateTable();
- }
- $scope.ecdapp.isDataLoading = false;
- },
- function(error) {
- $log.error("inventoryDeploymentController.loadTable failed: "
- + error);
- $scope.ecdapp.isRequestFailed = true;
- $scope.ecdapp.errMsg = error;
- $scope.ecdapp.tableData = [];
- $scope.ecdapp.isDataLoading = false;
- });
- };
-
- /**
- * Loads the table. Interprets the remote controller's response and copies
- * to scope variables. The response is either a list to be assigned to
- * tableData, or an error to be shown.
- */
- $scope.ecdapp.sortTable = function(sortBy) {
- $scope.ecdapp.isDataLoading = true;
- $scope.ecdapp.sortBy = sortBy;
- InventoryDeploymentService.getDeployments($scope.ecdapp.currentPageNum,
- $scope.ecdapp.viewPerPage, sortBy, $scope.ecdapp.searchBy).then(
- function(jsonObj) {
- if (jsonObj.error) {
- $log.error("inventoryDeploymentController.loadTable failed: "
- + jsonObj.error);
- $scope.ecdapp.isRequestFailed = true;
- $scope.ecdapp.errMsg = jsonObj.error;
- $scope.ecdapp.tableData = [];
- } else {
- $scope.ecdapp.isRequestFailed = false;
- $scope.ecdapp.errMsg = null;
- $scope.ecdapp.totalPages = jsonObj.totalPages;
- $scope.ecdapp.tableData = jsonObj.items;
- $scope.ecdapp.updateTable();
- }
- $scope.ecdapp.isDataLoading = false;
- },
- function(error) {
- $log.error("inventoryDeploymentController.loadTable failed: "
- + error);
- $scope.ecdapp.isRequestFailed = true;
- $scope.ecdapp.errMsg = error;
- $scope.ecdapp.tableData = [];
- $scope.ecdapp.isDataLoading = false;
- });
- };
-
- /**
- * Loads the table. Interprets the remote controller's response and copies
- * to scope variables. The response is either a list to be assigned to
- * tableData, or an error to be shown.
- */
- $scope.ecdapp.searchTable = function(searchBy) {
- $scope.ecdapp.isDataLoading = true;
- $scope.ecdapp.searchBy = searchBy;
- InventoryDeploymentService.getDeployments($scope.ecdapp.currentPageNum,
- $scope.ecdapp.viewPerPage, $scope.ecdapp.sortBy, searchBy).then(
- function(jsonObj) {
- if (jsonObj.error) {
- $log.error("inventoryDeploymentController.loadTable failed: "
- + jsonObj.error);
- $scope.ecdapp.isRequestFailed = true;
- $scope.ecdapp.errMsg = jsonObj.error;
- $scope.ecdapp.tableData = [];
- } else {
- $scope.ecdapp.isRequestFailed = false;
- $scope.ecdapp.errMsg = null;
- $scope.ecdapp.totalPages = jsonObj.totalPages;
- $scope.ecdapp.tableData = jsonObj.items;
- $scope.ecdapp.updateTable();
- }
- $scope.ecdapp.isDataLoading = false;
- },
- function(error) {
- $log.error("inventoryDeploymentController.loadTable failed: "
- + error);
- $scope.ecdapp.isRequestFailed = true;
- $scope.ecdapp.errMsg = error;
- $scope.ecdapp.tableData = [];
- $scope.ecdapp.isDataLoading = false;
- });
- };
-
- $scope.ecdapp.checkHelmStatus = function(deployment) {
- var selTenant = deployment.statusInfo.tenant_name;
- if ( typeof selTenant === "undefined" ) {
- selTenant = "default_tenant";
- }
- deployment.onlyLatest = true;
-
- // This object holds data for this operation
- $scope.ecdapp.helmStatusRequest = {
- "deployment_id": deployment.deploymentRef,
- "workflow_name": "status",
- "tenant": selTenant
- };
- InventoryDeploymentService.helmStatusFlow($scope.ecdapp.helmStatusRequest).then(function(jsonObj) {
- if (debug)
- $log.debug("checkHelmStatus response: " + JSON.stringify(jsonObj));
- if (jsonObj.error) {
- $scope.ecdapp.errMsg = 'Request Failed: ' + jsonObj.error;
- $scope.ecdapp.updatingDeployment = false;
- $scope.ecdapp.isDataLoading = false;
- } else {
- console.log('%c POSTED helm status request', 'color: magenta; font-weight: bold;');
- }
- }, function(error) {
- $log.error('helmStatusFlow failed: ' + error);
- });
- $scope.ecdapp.viewDeploymentExecutionsModalPopup(deployment);
- };
- /**
- * Shows a modal pop-up with blueprint content.
- * Passes data in via an object named "message".
- */
- $scope.ecdapp.viewBlueprintDataModal = function(deployment) {
- var modalInstance = $modal.open({
- templateUrl : 'blueprint_data_view_popup.html',
- controller : 'deployBlueprintViewCtrl',
- windowClass: 'modal-docked',
- sizeClass: 'modal-jumbo',
- resolve : {
- message : function() {
- var dataForPopup = {
- blueprint : deployment
- };
- return dataForPopup;
- }
- }
- });
- modalInstance.result.then(function(response) {
- });
- };
-
- /**
- * Invoked at first page load AND when
- * user clicks on the B2B pagination control.
- */
- $scope.pageChangeHandler = function(page) {
- // console.log('pageChangeHandler: current is ' + $scope.ecdapp.currentPageNum + ' new is ' + page);
- $scope.ecdapp.currentPageNum = page;
- $scope.ecdapp.loadTable($scope.ecdapp.sortBy, $scope.ecdapp.searchBy);
- }
-
- /**
- * Shows a modal pop-up to confirm deletion.
- * On successful completion, updates the table.
- */
- $scope.ecdapp.deleteDeploymentModalPopup = function(deployment) {
- deployment.onlyLatest = true;
- var modalInstance = $modal.open({
- templateUrl : 'inventory_deployment_delete_popup.html',
- controller : 'inventoryDeploymentDeleteCtrl',
- sizeClass: 'modal-small',
- resolve : {
- message : function() {
- var dataForPopup = {
- deployment : deployment,
- };
- return dataForPopup;
- }
- }
- });
- modalInstance.result.then(function(response) {
- if (debug)
- $log.debug('deleteDeploymentPopup: response: ' + JSON.stringify(response));
- if (response == null) {
- // $log.debug('user closed dialog');
- }
- else {
- if (response.error != null) {
- $log.error('deleteDeploymentModalPopup failed: ' + response.error);
- alert('Failed to delete deployment:\n' + response.error);
- }
- else {
- $scope.ecdapp.viewDeploymentExecutionsModalPopup(deployment);
- }
- }
- });
- };
-
- /**
- * Shows a modal pop-up with executions for a deployment.
- * Passes data in via an object named "deployment".
- */
- $scope.ecdapp.viewDeploymentExecutionsModalPopup = function(deployment) {
- var modalInstance = $modal.open({
- templateUrl : 'inventory_execution_view_popup.html',
- controller : 'inventoryDeploymentExecutionsViewCtrl',
- windowClass: 'modal-docked',
- sizeClass: 'modal-jumbo',
- resolve : {
- message : function() {
- var dataForPopup = {
- deployment : deployment
- };
- return dataForPopup;
- }
- }
- });
- modalInstance.result.then(function(response) {
- // No response.
- });
- };
-
- /**
- * Shows a modal pop-up with executions for a deployment.
- * Passes data in via an object named "deployment".
- */
- $scope.ecdapp.viewDeploymentInputsModalPopup = function(deployment) {
- var modalInstance = $modal.open({
- templateUrl : 'inventory_deployment_inputs_view_popup.html',
- controller : 'inventoryDeploymentInputsViewCtrl',
- windowClass: 'modal-docked',
- sizeClass: 'modal-jumbo',
- resolve : {
- message : function() {
- var dataForPopup = {
- deployment : deployment
- };
- return dataForPopup;
- }
- }
- });
- modalInstance.result.then(function(response) {
- // No response.
- });
- };
-
- /**
- * Shows a modal pop-up to initiate helm upgrade for a deployment
- */
- $scope.ecdapp.upgradeDeploymentModalPopup = function(deployment) {
- //console.log(deployment);
- var modalInstance = $modal.open({
- templateUrl: 'inventory_deployment_upgrade_popup.html',
- controller: 'inventoryDeploymentUpgradeCtrl',
- windowClass: 'modal-docked',
- sizeClass: 'modal-jumbo',
- resolve: {
- message: function() {
- var dataForPopup = {
- deployment : deployment
- };
- return dataForPopup;
- }
- }
- });
- modalInstance.result.then(function(response) {
- // No response.
- });
- };
-
- /**
- * Shows a modal pop-up to initiate helm rollback for a deployment
- */
- $scope.ecdapp.rollbackDeploymentModalPopup = function(deployment) {
- var modalInstance = $modal.open({
- templateUrl: 'inventory_deployment_rollback_popup.html',
- controller: 'inventoryDeploymentRollbackCtrl',
- windowClass: 'modal-docked',
- sizeClass: 'modal-jumbo',
- resolve: {
- message: function() {
- var dataForPopup = {
- deployment : deployment
- };
- return dataForPopup;
- }
- }
- });
- modalInstance.result.then(function(response) {
- // No response.
- });
- };
-
- /**
- * Shows a modal pop-up to initiate update blueprint for a deployment
- */
- $scope.ecdapp.updateDeploymentModalPopup = function(deployment) {
- var modalInstance = $modal.open({
- templateUrl: 'inventory_deployment_update_popup.html',
- controller: 'inventoryDeploymentUpdateCtrl',
- windowClass: 'modal-docked',
- sizeClass: 'modal-jumbo',
- resolve: {
- message: function() {
- var dataForPopup = {
- deployment : deployment
- };
- return dataForPopup;
- }
- }
- });
- };
-
- /**
- * Shows a modal pop-up to confirm service deletion.
- * On successful completion, updates the table.
- */
- $scope.ecdapp.deleteServiceModalPopup = function(service) {
- modalService.popupConfirmWin("Confirm", "Delete Service with ID '"
- + service.serviceId + "'?", function() {
- InventoryDeploymentService.deleteService(service.serviceId).then(
- function(response) {
- if (debug)
- $log.debug('deleteServiceModalPopup: response: ' + JSON.stringify(response));
- if (response && response.error) {
- alert('Failed to delete service:\n' + response.error);
- }
- else {
- // No response body on success.
- $scope.ecdapp.loadTable();
- }
- },
- function(error) {
- $log.error('InventoryDeploymentService.deleteService failed: ' + error);
- alert('Service failed to delete service:\n' + error);
- });
- })
- };
-});
-
-/*************************************************************************/
-
-appDS2.controller('inventoryDeploymentDeleteCtrl', function(
- $scope, $rootScope, $log, $modalInstance, message, InventoryDeploymentService) {
-
- 'use strict';
-
- // Controls logging in this controller
- var debug = false;
-
- // this object holds all app data and functions
- $scope.ecdapp = {};
- $scope.ecdapp.label = 'Undeploy?';
- $scope.ecdapp.deploymentRef = message.deployment.deploymentRef;
- var selTenant = message.deployment.statusInfo.tenant_name;
- $scope.ecdapp.ui_tenant = selTenant;
- $scope.ecdapp.tenant = selTenant;
-
- $scope.ecdapp.deleteDeploymentById = function(){
- InventoryDeploymentService.deleteDeployment($scope.ecdapp.deploymentRef, $scope.ecdapp.tenant).then(
- function(response) {
- if (debug)
- $log.debug('inventoryDeploymentDeleteCtrl.deleteDeployment: ' + JSON.stringify(response));
- if (response && response.error) {
- $log.error('InventoryDeploymentService.deleteDeployment failed: ' + response.error);
- alert('Failed to delete deployment:\n' + response.error);
- }
- else {
- // Delete service returns null on success.
- $modalInstance.close("success");
- }
- },
- function(error) {
- $log.error('InventoryDeploymentService.deleteDeployment failed: ' + error);
- alert('Service failed to delete deployment:\n' + error);
- });
- }
-
-});
-
-/*************************************************************************/
-
-appDS2.controller('inventoryDeploymentExecutionsViewCtrl', function(
- $scope, $rootScope, $interval, $log, $modalInstance, message, modalService, InventoryExecutionService, ExecutionService) {
-
- 'use strict';
-
- var debug = false;
-
- if (debug)
- $log.debug("inventoryDeploymentsExecutionsViewCtrl.message: " + JSON.stringify(message));
-
- // this object holds all app data and functions
- $scope.ecdapp = {};
- // models for controls on screen
- $scope.ecdapp.label = 'Deployment Executions';
- $scope.ecdapp.tableData = [];
- $scope.ecdapp.logTableData = [];
- $scope.ecdapp.currentPageNum = 1;
- $scope.ecdapp.viewPerPage = 50;
- $scope.ecdapp.currentLogPageNum = 1;
-
- // other
- $scope.ecdapp.errMsg = null;
- $scope.ecdapp.isDataLoading = true;
- $scope.ecdapp.isEventLogQuery = false;
- $scope.ecdapp.isRequestFailed = false;
- $scope.ecdapp.isLastExecution = message.deployment.onlyLatest;
- $scope.ecdapp.isLogType = true;
- $scope.ecdapp.refresh_switch = {
- value: true
- };
- $scope.ecdapp.options = {
- "on":"On",
- "off":"Off"
- }
- var selTenant = 'default_tenant';
-
- if (typeof message.deployment.statusInfo === "undefined") {
- selTenant = message.deployment.tenant;
- } else {
- selTenant = message.deployment.statusInfo.tenant_name;
- }
-
- $scope.ecdapp.ui_tenant = selTenant;
- $scope.ecdapp.tenant = selTenant;
- $scope.ecdapp.deplRef = message.deployment.deploymentRef;
- var stop;
- /**
- * Loads the table. Interprets the remote controller's response and copies
- * to scope variables. The response is either a list to be assigned to
- * tableData, or an error to be shown.
- */
- $scope.ecdapp.loadTable = function() {
- $scope.ecdapp.isDataLoading = true;
- InventoryExecutionService.getExecutionsByDeployment(message.deployment.deploymentRef,
- $scope.ecdapp.tenant,
- $scope.ecdapp.currentPageNum,
- $scope.ecdapp.viewPerPage).then(
- function(jsonObj) {
- if (jsonObj.error) {
- $log.error("inventoryDeploymentExecutionsViewCtrl.loadTable failed: "
- + jsonObj.error);
- $scope.ecdapp.isRequestFailed = true;
- if (jsonObj.error.includes("404")) {
- $scope.ecdapp.errMsg = "404 - Deployment " + message.deployment.deploymentRef + " Not Found!";
- }
- $scope.ecdapp.tableData = [];
- $scope.ecdapp.stopLoading();
- } else {
- $scope.ecdapp.isRequestFailed = false;
- $scope.ecdapp.errMsg = null;
- $scope.ecdapp.totalPages = jsonObj.totalPages;
- var resultLen = jsonObj.items.length;
- if (resultLen != undefined && resultLen > 0) {
- var exec_id = jsonObj.items[resultLen-1].id;
- if ($scope.ecdapp.isLastExecution) {
- $scope.ecdapp.tableData = [];
- $scope.ecdapp.tableData.push(jsonObj.items[resultLen-1]);
- } else {
- $scope.ecdapp.tableData = jsonObj.items;
- }
- $scope.ecdapp.getExecutionLogs(exec_id, $scope.ecdapp.tenant);
- }
- }
- $scope.ecdapp.isDataLoading = false;
- },
- function(error) {
- $log.error("inventoryDeploymentExecutionsViewCtrl.loadTable failed: "
- + error);
- $scope.ecdapp.isRequestFailed = true;
- $scope.ecdapp.errMsg = error;
- $scope.ecdapp.tableData = [];
- $scope.ecdapp.isDataLoading = false;
- $scope.ecdapp.stopLoading();
- });
- };
- $scope.$watch('ecdapp.refresh_switch["value"]', function(newValue,oldValue,scope) {
- if (newValue != oldValue) {
- if (newValue === true) {
- $scope.ecdapp.loadTable();
- stop = $interval( function(){ $scope.ecdapp.loadTable(); }, 30000, 100, false);
- } else {
- $scope.ecdapp.stopLoading();
- }
- }
- }, true);
-
- if ($scope.ecdapp.refresh_switch.value === true) {
- stop = $interval( function(){ $scope.ecdapp.loadTable(); }, 30000, 100, false);
- }
-
- $scope.ecdapp.stopLoading = function() {
- if (angular.isDefined(stop)) {
- $interval.cancel(stop);
- stop = undefined;
- }
- };
-
- $scope.ecdapp.cancelExecutionModalPopup = function(execution, tenant) {
- modalService.popupConfirmWin("Confirm", "Cancel execution with ID '"
- + execution.id + "'?", function() {
- $scope.ecdapp.isCancelOn = true;
- // TODO: gather action from user
- InventoryExecutionService.cancelExecution(execution.id, execution.deployment_id, "force-cancel", tenant).then(
- function(response) {
- if (debug)
- $log.debug("Controller.cancelExecutionModalPopup: " + JSON.stringify(response));
- if (response && response.error) {
- // $log.error('cancelExectuion failed: ' + response.error);
- alert('Failed to cancel execution:\n' + response.error);
- $scope.ecdapp.isCancelOn = false;
- }
- else {
- // No response body on success.
- $scope.ecdapp.isCancelOn = false;
- $scope.ecdapp.loadTable();
- }
- },
- function(error) {
- $scope.ecdapp.isCancelOn = false;
- $log.error('ExecutionService.cancelExecution failed: ' + error);
- alert('Service failed to cancel execution:\n' + error);
- });
- })
- };
-
- /**
- * Invoked at first page load AND when
- * user clicks on the B2B pagination control.
- */
- $scope.pageChangeHandler = function(page) {
- if (debug)
- console.log('pageChangeHandler: current is ' + $scope.ecdapp.currentPageNum + ' new is ' + page);
- $scope.ecdapp.currentPageNum = page;
- $scope.ecdapp.loadTable();
-
- }
-
- $scope.ecdapp.selected = false;
- $scope.ecdapp.toggleStatusDefinitions = function() {
- $scope.ecdapp.selected = $scope.ecdapp.selected ? false :true;
- }
-
- /**
- * Shows a modal pop-up with the error.
- */
- $scope.ecdapp.viewErrorModalPopup = function(row) {
- $modalInstance.dismiss('cancel');
- modalService.showFailure('Error Details', row.error, function() { } );
- };
-
- $scope.ecdapp.getExecutionLogs = function(id, tenant) {
- $scope.ecdapp.executionId = id;
- $scope.ecdapp.isEventLogQuery = false;
- InventoryExecutionService.getEventsByExecution(id , $scope.ecdapp.isLogType, tenant,
- $scope.ecdapp.currentLogPageNum, $scope.ecdapp.viewPerPage ).then(
- function(jsonObj) {
- if (jsonObj.error) {
- $log.error("inventoryDeploymentExecutionsViewCtrl.getExecutionLogs failed: "
- + jsonObj.error);
- $scope.ecdapp.isEventLogQuery = false;
- $scope.ecdapp.evtErrMsg = jsonObj.error;
- $scope.ecdapp.logTableData = [];
- } else {
- $scope.ecdapp.isEventLogQuery = true;
- $scope.ecdapp.evtErrMsg = null;
- $scope.ecdapp.totalLogPages = jsonObj.totalPages;
- $scope.ecdapp.logTableData = jsonObj.items;
- /*
- if ($scope.ecdapp.isLogType) {
- $scope.ecdapp.logTableData = jsonObj.items;
- } else {
- $scope.ecdapp.logTableData = [];
- angular.forEach(jsonObj.items, function(item, index) {
- angular.forEach(item, function(value, key) {
- if (key === "type" && value != "cloudify_log") {
- $scope.ecdapp.logTableData.push(item);
- }
- });
- });
- }
- */
- }
- $scope.ecdapp.isDataLoading = false;
- },
- function(error) {
- $log.error("inventoryDeploymentExecutionsViewCtrl.getExecutionLogs failed: "
- + error);
- $scope.ecdapp.evtErrMsg = error;
- $scope.ecdapp.logTableData = [];
- $scope.ecdapp.isDataLoading = false;
- });
- }
-
- $scope.$on('$destroy', function() {
- // Make sure that the interval is destroyed too
- $scope.ecdapp.stopLoading();
- });
-});
-
-/*************************************************************************/
-appDS2.controller('inventoryDeploymentInputsViewCtrl', function(
- $scope, $rootScope, $log, $modalInstance, message, InventoryDeploymentService) {
-
- 'use strict';
-
- // Controls logging in this controller
- var debug = false;
-
- // this object holds all app data and functions
- $scope.ecdapp = {};
- $scope.ecdapp.label = 'Deployment Inputs';
- $scope.ecdapp.deployment = null;
- $scope.ecdapp.deploymentRef = message.deployment.deploymentRef;
- $scope.ecdapp.serviceId = message.deployment.serviceId;
- $scope.ecdapp.errMsg = null;
- $scope.ecdapp.isDataLoading = true;
- $scope.ecdapp.isRequestFailed = false;
- var selTenant = message.deployment.statusInfo.tenant_name;
- if ( typeof selTenant === "undefined" ) {
- selTenant = "default_tenant";
- }
- $scope.ecdapp.ui_tenant = selTenant;
- $scope.ecdapp.tenant = selTenant;
-
- InventoryDeploymentService.getDeployment(message.deployment.deploymentRef, $scope.ecdapp.tenant).then(function(deployment) {
- if (deployment.items.length == 0) {
- $scope.ecdapp.errMsg = "404 - Deployment " + message.deployment.deploymentRef + " Not Found!";
- $log.error("InventoryDeploymentSerice.getDeployment failed: "
- + $scope.ecdapp.errMsg);
- $scope.ecdapp.isRequestFailed = true;
- }
- // Deployment IDs are unique, so this will always return exactly one item!
- // retrieve blueprintId and inputs of deployment.
- else {
- $scope.ecdapp.errMsg = null;
- $scope.ecdapp.deployment = deployment.items[0];
- $scope.ecdapp.isRequestFailed = false;
- }
- $scope.ecdapp.isDataLoading = false;
- },
- function(error) {
- $log.error('InventoryDeploymentService.getDeployment failed: ' + JSON.stringify(error));
- $scope.ecdapp.isRequestFailed = true;
- $scope.ecdapp.errMsg = error;
- $scope.ecdapp.isDataLoading = false;
- });
-});
-
-/*************************************************************************/
-appDS2.controller('inventoryDeploymentUpdateCtrl', function(
- $scope, $log, $modalInstance, message, InventoryBlueprintService, InventoryDeploymentService) {
-
- 'use strict';
-
- var debug = false;
- if (debug)
- $log.debug("inventoryDeploymentUpdateCtrl.message: " + JSON.stringify(message));
-
- // this object holds all app data and functions
- $scope.ecdapp = {};
- $scope.ecdapp.deploymentInProgress = false;
- $scope.ecdapp.serviceTypeComplete = false;
- $scope.ecdapp.isDataLoading = true;
- $scope.ecdapp.errMsg = null;
- $scope.ecdapp.label = 'Update Deployment: ' + message.deployment.deploymentRef;
- $scope.ecdapp.deploymentRef = message.deployment.deploymentRef;
- var selTenant = message.deployment.statusInfo.tenant_name;
- if ( typeof selTenant === "undefined" ) {
- selTenant = "default_tenant";
- }
- $scope.ecdapp.tenant = selTenant;
- $scope.ecdapp.ui_tenant = selTenant;
- $scope.ecdapp.typeName = '';
- $scope.ecdapp.typeId = '';
- $scope.ecdapp.inputsDict = {};
- $scope.ecdapp.editRequest = {
- deployment_id : message.deployment.deploymentRef,
- type_id : '',
- fileModel : null,
- parmFileDict : {},
- tenant : $scope.ecdapp.tenant
- };
-
- // get the blueprints from inventory matching deployment reference filter
- $scope.ecdapp.bp = [];
- var sortBy = '';
- var searchBy = message.deployment.deploymentRef.split("_", 1);
- searchBy = searchBy[0];
- InventoryBlueprintService.getBlueprints(1, 100, sortBy, searchBy)
- .then(function(jsonObj) {
- if (jsonObj.error) {
- $log.error("inventoryDeploymentUpdateCtrl.loadTable failed: " + jsonObj.error);
- $scope.ecdapp.errMsg = jsonObj.error;
- $scope.ecdapp.bp = [];
- } else {
- $scope.ecdapp.errMsg = null;
- $scope.ecdapp.bp = jsonObj.items;
- if (Array.isArray($scope.ecdapp.bp) ) {
- angular.forEach($scope.ecdapp.bp, function(item, index) {
- item.checked = false;
- });
- }
- }
- $scope.ecdapp.isDataLoading = false;
- }, function(error) {
- $log.error("inventoryDeploymentUpdateCtrl.loadTable failed: " + error);
- $scope.ecdapp.errMsg = error;
- $scope.ecdapp.bp = [];
- $scope.ecdapp.isDataLoading = false;
- });
- $scope.ecdapp.updateSelection = function(position) {
- $scope.ecdapp.typeId = position;
- $scope.ecdapp.editRequest.type_id = position;
- angular.forEach($scope.ecdapp.bp, function(item, index) {
- if (position != index+1)
- item.checked = false;
- });
- }
- $scope.ecdapp.getBlueprint = function() {
- $scope.ecdapp.isDataLoading = true;
- InventoryBlueprintService.viewBlueprint($scope.ecdapp.typeId).then(function(jsonObj) {
- if (debug)
- $log.debug("inventoryDeploymentUpdateCtrl.viewBlueprint response: " + JSON.stringify(jsonObj));
- if (jsonObj.error) {
- $scope.ecdapp.errMsg = 'Request Failed';
- $scope.ecdapp.serviceTypeComplete = false;
- $scope.ecdapp.isDataLoading = false;
- }
- else {
- $scope.ecdapp.typeName = jsonObj.typeName;
- $scope.ecdapp.typeVersion = jsonObj.typeVersion;
- $scope.ecdapp.inputsDict = jsonObj.blueprintInputs;
- // query the current deployment inputs
- InventoryDeploymentService.getDeployment(message.deployment.deploymentRef, $scope.ecdapp.tenant).then(function(deployment) {
- if (deployment.items.length == 0) {
- $scope.ecdapp.errMsg = "404 - Deployment " + message.deployment.deploymentRef + " Not Found!";
- $log.error("InventoryDeploymentSerice.getDeployment failed: "
- + $scope.ecdapp.errMsg);
- //$scope.ecdapp.isRequestFailed = true;
- $scope.ecdapp.serviceTypeComplete = true;
- }
- // Deployment IDs are unique, so this will always return exactly one item!
- // retrieve inputs of deployment.
- else {
- $scope.ecdapp.errMsg = null;
- $scope.ecdapp.deployment = deployment.items[0];
- // Copy the input parameter names and default values
- let inputsAndDefaults = {};
- for (var pkey in $scope.ecdapp.inputsDict) {
- if (debug)
- $log.debug('inventoryDeploymentUpdateCtrl: checking key ' + pkey);
- let dval = $scope.ecdapp.deployment.inputs[pkey];
- //$scope.ecdapp.inputsDict[pkey].defaultValue;
- if (dval === undefined || dval === null) {
- dval = '';
- }
- inputsAndDefaults[pkey] = dval;
- }
- $scope.ecdapp.editRequest.parmFileDict = inputsAndDefaults;
- $scope.ecdapp.editRequest.type_id = $scope.ecdapp.typeId;
- if (debug)
- $log.debug('inventoryBlueprintDeployCtrl: inputsAndDefaults: ' + JSON.stringify(inputsAndDefaults));
-
- $scope.ecdapp.serviceTypeComplete = true;
- //$scope.$apply();
- }
- $scope.ecdapp.isDataLoading = false;
- },
- function(error) {
- $log.error('InventoryDeploymentService.getDeployment failed: ' + JSON.stringify(error));
- $scope.ecdapp.isRequestFailed = true;
- $scope.ecdapp.errMsg = error;
- $scope.ecdapp.isDataLoading = false;
- });
- }
- $scope.ecdapp.isDataLoading = false;
- }, function(error) {
- $scope.ecdapp.isDataLoading = false;
- $scope.ecdapp.serviceTypeComplete = false;
- alert('Failed to get blueprint. Please retry with valid blueprint ID.');
- $log.error("inventoryDeploymentUpdateCtrl failed: " + error);
- });
- };
-
- /**
- * Handler for file-read event reads file, parses JSON, validates content.
- */
- var fileReader = new FileReader();
- fileReader.onload = function(event) {
- let jsonString = fileReader.result;
- if (debug)
- $log.debug('fileReader.onload: read: ' + jsonString);
- let ydict = {};
- try {
- ydict = JSON.parse(jsonString);
- }
- catch (ex) {
- alert('Failed to parse file as JSON:\n' + ex);
- }
- // Process the file
- for (var ykey in ydict) {
- let yval = ydict[ykey];
- if (debug)
- $log.debug('fileReader.onload: typeof ' + ykey + ' is ' + typeof ykey);
- // Allow only expected keys with scalar values
- if (! (ykey in $scope.ecdapp.editRequest.parmFileDict))
- alert('Unexpected file content:\nKey not defined by blueprint:\n' + ykey);
- if (yval.constructor === {}.constructor)
- $scope.ecdapp.editRequest.parmFileDict[ykey] = angular.toJson(yval);
- else
- $scope.ecdapp.editRequest.parmFileDict[ykey] = yval;
- }
- if (debug)
- $log.debug('fileReader.onload: parmFileDict: ' + JSON.stringify($scope.ecdapp.editRequest.parmFileDict));
-
- // Update table in all cases
- $scope.$apply();
- }
-
- // Handler for file-select event
- $scope.handleFileSelect = function() {
- if (debug)
- $log.debug('handleFileSelect: $scope.ecdapp.fileModel.name is ' + $scope.ecdapp.editRequest.fileModel.name);
- fileReader.readAsText($scope.ecdapp.editRequest.fileModel);
- };
-
- $scope.ecdapp.validateRequest = function(editRequest) {
- if (editRequest == null)
- return 'No data found.\nPlease enter some values.';
- if (editRequest.deployment_id == null || editRequest.deployment_id.trim() == '')
- return 'Deployment ID is required.\nPlease enter a value.';
- if (editRequest.type_id == null || editRequest.type_id.trim() == '')
- return 'Type ID is required.\nPlease enter a value.';
- // Check that every file parameter is defined by blueprint
- for (var pkey in $scope.ecdapp.editRequest.parmFileDict) {
- // Defined in blueprint?
- if (! $scope.ecdapp.inputsDict[pkey])
- return 'Unexpected input parameter\n' + pkey;
- }
- return null;
- }
-
- $scope.ecdapp.updateDeployment = function(editRequest) {
- if (debug)
- $log.debug('deployBlueprint: editRequest is ' + JSON.stringify($scope.ecdapp.editRequest));
- var validateMsg = $scope.ecdapp.validateRequest(editRequest);
- if (validateMsg != null) {
- alert('Invalid Request:\n' + validateMsg);
- $scope.ecdapp.errMsg = validateMsg;
- return;
- }
- // Create request with key:value parameters dictionary
- let deploymentRequestObject = {
- deploymentId : editRequest.deployment_id,
- serviceTypeId : editRequest.type_id,
- inputs : {},
- tenant : editRequest.tenant,
- method : "update"
- };
- for (var pkey in $scope.ecdapp.editRequest.parmFileDict)
- try {
- deploymentRequestObject.inputs[pkey] = angular.fromJson($scope.ecdapp.editRequest.parmFileDict[pkey]);
- } catch (error) {
- deploymentRequestObject.inputs[pkey] = $scope.ecdapp.editRequest.parmFileDict[pkey];
- }
- if (debug)
- $log.debug('deployBlueprint: deploymentRequestObject is ' + JSON.stringify(deployRequestObject));
-
- $scope.ecdapp.deploymentInProgress = true;
- InventoryDeploymentService.deployBlueprint(deploymentRequestObject)
- .then(function(response) {
- $scope.ecdapp.deploymentInProgress = false;
- if (response.error) {
- alert('Failed to deploy blueprint:\n' + response.error);
- $scope.ecdapp.errMsg = response.error;
- } else {
- alert('Deployment update request sent successfully, query the execution status for final outcome');
- $modalInstance.close(response);
- }
- },
- function (error) {
- $log.error('inventoryBlueprintDeployCtrl: error while deploying: ' + error);
- alert('Server rejected deployment request:\n' + error);
- $scope.ecdapp.deploymentInProgress = false;
- }
- );
- };
-
-});
-
-
-/*************************************************************************/
-
-appDS2.controller('deployBlueprintViewCtrl', function(
- $scope, $log, message, InventoryBlueprintService) {
-
- 'use strict';
-
- var debug = false;
-
- if (debug)
- $log.debug("deployBlueprintViewCtrl.message: " + JSON.stringify(message));
-
- // this object holds all app data and functions
- $scope.ecdapp = {};
- $scope.ecdapp.label = 'View Blueprint ' + message.blueprint.deploymentRef;
-
- var typeLink = message.blueprint.typeLink.href;
- var n = typeLink.lastIndexOf("/");
- var typeId = typeLink.substring(n+1);
- // Fetch the blueprint
- $scope.ecdapp.isDataLoading = true;
- InventoryBlueprintService.viewBlueprint(typeId).then(function(jsonObj) {
- if (debug)
- $log.debug("deployBlueprintViewCtrl.viewBlueprint response: " + JSON.stringify(jsonObj));
- if (jsonObj.error) {
- $scope.ecdapp.errMsg = 'Request Failed';
- }
- else {
- $scope.ecdapp.typeName = jsonObj.typeName;
- $scope.ecdapp.blueprint = jsonObj.blueprintTemplate;
- }
- $scope.ecdapp.isDataLoading = false;
- }, function(error) {
- $scope.ecdapp.isDataLoading = false;
- alert('Failed to get blueprint. Please retry.');
- $log.error("blueprintViewCtrl failed: " + error);
- });
-});
-
-/*************************************************************************/
-appDS2.controller('inventoryDeploymentRollbackCtrl', function(
- $scope, $rootScope, $log, $modalInstance, message, InventoryDeploymentService) {
-
- 'use strict';
-
- // Controls logging in this controller
- var debug = false;
-
- // this object holds all app data and functions
- $scope.ecdapp = {};
- $scope.ecdapp.label = 'Deployment Rollback';
- $scope.ecdapp.revisions = [];
- $scope.ecdapp.deploymentRef = message.deployment.deploymentRef;
- $scope.ecdapp.serviceId = message.deployment.serviceId;
- $scope.ecdapp.errMsg = null;
- $scope.ecdapp.isDataLoading = true;
- $scope.ecdapp.isRequestFailed = false;
- $scope.ecdapp.updatingDeployment = false;
- var selTenant = message.deployment.statusInfo.tenant_name;
- if ( typeof selTenant === "undefined" ) {
- selTenant = "default_tenant";
- }
- $scope.ecdapp.tenant = selTenant;
- $scope.ecdapp.ui_tenant = selTenant;
- $scope.ecdapp.local_revisions = [];
- // This object holds data for this operation
- $scope.ecdapp.rollbackRequest = {
- "deployment_id": message.deployment.deploymentRef,
- "workflow_name": "rollback",
- "tenant": selTenant,
- "revision": 1
- };
-
- InventoryDeploymentService.getNodeInstanceVersions($scope.ecdapp.deploymentRef, $scope.ecdapp.tenant).then(function(nodeRunTime) {
- if (nodeRunTime == null) {
- $scope.ecdapp.errMsg = "Failed to retrieve Node instance runtime information";
- $log.error("InventoryDeploymentSerice.getNodeInstanceVersions failed: "
- + $scope.ecdapp.errMsg);
- $scope.ecdapp.isRequestFailed = true;
- } else {
- $scope.ecdapp.errMsg = null;
- $scope.ecdapp.revisions = nodeRunTime.items[0].runtime_properties['helm-history'];
- if (Array.isArray($scope.ecdapp.revisions) ) {
- var dLen = $scope.ecdapp.revisions.length;
-
- for (var i = 1; i < dLen; i++) {
- var str = $scope.ecdapp.revisions[i].replace(/\s+/g, ' ');
- var itemStrArr = str.split(" ");
- var itemLen = itemStrArr.length;
- var revObj = {};
- revObj.revision = itemStrArr[0].trim();
- revObj.updated = itemStrArr.slice(1,5).toString().replace(/,/g, ' ');
- revObj.status = itemStrArr[6].trim();
- revObj.chart = itemStrArr[7].trim();
- revObj.description = itemStrArr.slice(8,itemLen).toString().replace(/,/g, ' ');
- revObj.name = itemStrArr[0].trim();
- revObj.checked = false;
- $scope.ecdapp.local_revisions.push(revObj);
- }
- }
- console.log($scope.ecdapp.local_revisions);
- $scope.ecdapp.isRequestFailed = false;
- }
- $scope.ecdapp.isDataLoading = false;
- },
- function(error) {
- $log.error('InventoryDeploymentService.getNodeInstanceVersions failed: ' + JSON.stringify(error));
- $scope.ecdapp.isRequestFailed = true;
- $scope.ecdapp.errMsg = error;
- $scope.ecdapp.isDataLoading = false;
- });
- $scope.ecdapp.updateSelection = function(position) {
- $scope.ecdapp.rollbackRequest.revision = position;
- angular.forEach($scope.ecdapp.local_revisions, function(item, index) {
- if (position != index+1)
- item.checked = false;
- });
- }
- /**
- * rollback deployment based on parameters user enters/adjusts in modal popup
- * First retrieves the node-id using the blueprintId
- * Using the node-id and deploymentId, retrieves the node-instance-id
- * Calls the update resource API, passing object with deploymentId, and changed parameters
- */
- $scope.ecdapp.rollbackWorkflow = function(revision) {
- $scope.ecdapp.updatingDeployment = true;
- $scope.ecdapp.isDataLoading = true;
- InventoryDeploymentService.rollbackFlow($scope.ecdapp.rollbackRequest).then(function(jsonObj) {
- if (debug)
- $log.debug("inventoryDeploymentRollbackCtrl.rollbackWorkflow response: " + JSON.stringify(jsonObj));
- if (jsonObj.error) {
- $scope.ecdapp.errMsg = 'Request Failed: ' + jsonObj.error;
- $scope.ecdapp.updatingDeployment = false;
- $scope.ecdapp.isDataLoading = false;
- } else {
- console.log('%c ROLLBACK RESOURCES COMPLETED', 'color: magenta; font-weight: bold;');
- alert('Rollback request for ' + $scope.ecdapp.deploymentRef + ' successfully went through to Cloudiy. Rollback is now pending');
- $scope.ecdapp.updatingDeployment = false;
- $scope.ecdapp.isDataLoading = false;
- }
- }, function(error) {
- $scope.ecdapp.updatingDeployment = false;
- $log.error('inventoryDeploymentRollbackCtrl failed: ' + error);
- alert('Failed to rollback Deployment ' + $scope.ecdapp.deploymentRef + '. Please retry.');
- $scope.ecdapp.isDataLoading = false;
- });
- }
-});
-
-/*************************************************************************/
-appDS2.controller('inventoryDeploymentUpgradeCtrl', function(
- $scope, $rootScope, $log, $modalInstance, message, InventoryDeploymentService) {
-
- 'use strict';
-
- // Controls logging in this controller
- var debug = false;
-
- // this object holds all app data and functions
- $scope.ecdapp = {};
- $scope.ecdapp.label = 'Deployment Upgrade';
- $scope.ecdapp.deployment = null;
- $scope.ecdapp.deploymentRef = message.deployment.deploymentRef; //THIS IS THE BLUEPRINT ID
- $scope.ecdapp.serviceId = message.deployment.serviceId;
- $scope.ecdapp.errMsg = null;
- $scope.ecdapp.isDataLoading = true;
- $scope.ecdapp.isRequestFailed = false;
- $scope.ecdapp.updatingDeployment = false;
- var selTenant = message.deployment.statusInfo.tenant_name;
- if ( typeof selTenant === "undefined" ) {
- selTenant = "default_tenant";
- }
- $scope.ecdapp.tenant = selTenant;
- $scope.ecdapp.ui_tenant = selTenant;
- $scope.ecdapp.parmFileDict = {};
-
- // This object holds data for editing the input parameters
- $scope.ecdapp.editRequest = {
- deployment_id: '',
- type_id: '',
- fileModel: null,
- resourceConstants: {},
- resourceDefinitionChanges: {}
- };
- //First get the blueprintId associated with the deployment, along with the inputs of the deployment
- InventoryDeploymentService.getDeployment(message.deployment.deploymentRef, $scope.ecdapp.tenant).then(function(deployment) {
- if (deployment.items.length == 0) {
- $scope.ecdapp.errMsg = "404 - Deployment " + message.deployment.deploymentRef + " Not Found!";
- $log.error("InventoryDeploymentSerice.getDeployment failed: "
- + $scope.ecdapp.errMsg);
- $scope.ecdapp.isRequestFailed = true;
- }
- // Deployment IDs are unique, so this will always return exactly one item!
- else {
- $scope.ecdapp.errMsg = null;
- $scope.ecdapp.deployment = deployment.items[0];
- $scope.ecdapp.isRequestFailed = false;
- $scope.ecdapp.editRequest.type_id = deployment.items[0].blueprint_id;
- $scope.ecdapp.parmFileDict = deployment.items[0].inputs;
- Object.keys($scope.ecdapp.parmFileDict).map(function(key, index) {
- if (key == 'config-format' || key == 'config-url' || key == 'chart-version' || key == 'chart-repo-url') {
- $scope.ecdapp.editRequest.resourceDefinitionChanges[key] = $scope.ecdapp.parmFileDict[key];
- } else {
- $scope.ecdapp.editRequest.resourceConstants[key] = $scope.ecdapp.parmFileDict[key];
- }
- });
- }
- $scope.ecdapp.isDataLoading = false;
- },
- function(error) {
- $log.error('InventoryDeploymentService.getDeployment failed: ' + JSON.stringify(error));
- $scope.ecdapp.isRequestFailed = true;
- $scope.ecdapp.errMsg = error;
- $scope.ecdapp.isDataLoading = false;
- });
-
- /**
- * Validates content of user-editable fields.
- * Returns null if all is well,
- * a descriptive error message otherwise.
- */
- $scope.ecdapp.validateRequest = function(editRequest) {
- if (editRequest == null)
- return 'No data found.\nPlease enter some values.';
- if (editRequest["chart-version"] == null || editRequest["chart-version"].trim() == '')
- return 'Chart version is required.\nPlease enter a value.';
- if (!editRequest["config-format"] || editRequest["config-format"].trim() == '') {
- return 'config format is required.\nPlease enter a value.';
- }
- if (!editRequest["config-url"] || editRequest["config-url"].trim() == '') {
- return 'Config URL is required.\nPlease enter a value.';
- }
- return null;
- };
-
- /**
- * Helm upgrade for deployment based on parameters user enters in modal popup
- * First retrieves the node-id using the blueprintId
- * Using the node-id and deploymentId, retrieves the node-instance-id
- * Calls the start execution API, passing object with deploymentId, and changed parameters
- */
-
- $scope.ecdapp.upgradeWorkflow = function(resourceDefinitionChanges) {
- $scope.ecdapp.updatingDeployment = true;
- let nodeId = '';
-
- // validate request
- var validateMsg = $scope.ecdapp.validateRequest(resourceDefinitionChanges);
- if (validateMsg != null) {
- alert('Invalid Request:\n' + validateMsg);
- $scope.ecdapp.updatingDeployment = false;
- return;
- }
- //get node id from blueprint
- InventoryDeploymentService.getBlueprint($scope.ecdapp.deploymentRef, $scope.ecdapp.tenant).then(function(blueprint) {
- if (debug)
- $log.debug("inventoryDeploymentUpgradeCtrl.getBlueprint response: " + JSON.stringify(blueprint));
- if (blueprint.error) {
- $scope.ecdapp.errMsg = 'Request Failed: ' + blueprint.error;
- $scope.ecdapp.updatingDeployment = false;
- }
- else {
- //console.log('returned blueprint:' + blueprint);
- let count = 0;
- //console.log("number of node objects in array: " + blueprint.items[0].plan.nodes.length);
- //console.log(JSON.stringify(blueprint));
- blueprint.items[0].plan.nodes.map(function(node) {
- if (node.type == 'onap.nodes.component') {
- //want to get FIRST node with type 'cloudify.kubernetes.resources.Deployment' so only set nodeID for first matching type
- if (count < 1) {
- nodeId = node.id;
- }
- count = count + 1;
- }
- });
- //if no node has type 'cloudify.kubernetes.resources.Deployment', return message saying no deployment exists and exit (ie nodeId still is '')
- if (nodeId == '') {
- alert('Failed to retrieve Node Id. No matching deployment found (no deployment exists)');
- $scope.ecdapp.updatingDeployment = false;
- return;
- }
- //found node id. now need to retrieve node-instance-id
- console.log('%c RETRIEVED NODE ID: ' + nodeId, 'color: orange; font-weight: bold;');
- let nodeInstanceId = '';
- InventoryDeploymentService.getNodeInstanceId($scope.ecdapp.deploymentRef, nodeId, $scope.ecdapp.tenant).then(function(jsonObj) {
- if (debug)
- $log.debug("inventoryDeploymentUpgradeCtrl.getNodeInstanceId response: " + JSON.stringify(jsonObj));
- if (jsonObj.error) {
- $scope.ecdapp.errMsg = 'Request Failed: ' + jsonObj.error;
- $scope.ecdapp.updatingDeployment = false;
- }
- else {
- //if nodeInstanceId is still '' then it wasn't found, stop flow)
- if (jsonObj.items[0].id == '') {
- alert('Failed to retrieve Node Instance Id for Node Id' + nodeId);
- $scope.ecdapp.updatingDeployment = false;
- return;
- }
- //found node-instance-id. now need to update resources
- nodeInstanceId = jsonObj.items[0].id;
- console.log('%c RETRIEVED NODE INSTANCE ID:' + nodeInstanceId, 'color: green; font-weight: bold;');
- //console.log(resourceDefinitionChanges);
- InventoryDeploymentService.upgradeFlow($scope.ecdapp.deploymentRef, nodeInstanceId, resourceDefinitionChanges, $scope.ecdapp.tenant).then(function(jsonObj) {
- if (debug)
- $log.debug("inventoryDeploymentUpgradeCtrl.updateResources response: " + JSON.stringify(jsonObj));
- if (jsonObj.error) {
- $scope.ecdapp.errMsg = 'Request Failed: ' + jsonObj.error;
- $scope.ecdapp.updatingDeployment = false;
- }
- else {
- console.log('%c UPDATE RESOURCES COMPLETED', 'color: magenta; font-weight: bold;');
- //console.log(jsonObj);
- $scope.ecdapp.updatingDeployment = false;
- alert('Helm Upgrade request for ' + $scope.ecdapp.deploymentRef + ' successfully went through to Cloudiy. Upgrade is now pending'); $modalInstance.dismiss('cancel');
- }
- }, function(error) {
- $scope.ecdapp.updatingDeployment = false;
- alert('Failed to perform upgrade for Deployment Id ' + $scope.ecdapp.deploymentRef + ' and Node Instance Id ' + nodeInstanceId + '. Please retry.');
- $log.error('inventoryDeploymentUpgradeCtrl failed: ' + error);
- });
- }
- }, function(error) {
- $scope.ecdapp.updatingDeployment = false;
- alert('Failed to get Node Instance Id for deploymentId ' + $scope.ecdapp.deploymentRef + ' and Node Id ' + nodeId + '. Please retry.');
- $log.error('inventoryDeploymentUpgradeCtrl failed: ' + error);
- });
-
- }
- }, function(error) {
- $scope.ecdapp.updatingDeployment = false;
- alert('Failed to get blueprint for blueprintId ' + $scope.ecdapp.deploymentRef + '. Please retry.');
- $log.error('inventoryDeploymentUpgradeCtrl failed: ' + error);
- });
- };
-
- /**
- * Handler for file-read event reads file, parses JSON, validates content.
- */
-
- var fileReader = new FileReader();
- fileReader.onload = function(event) {
- let jsonString = fileReader.result;
- if (debug)
- $log.debug('fileReader.onload: read: ' + jsonString);
- let ydict = {};
- try {
- ydict = JSON.parse(jsonString);
- }
- catch (ex) {
- alert('Failed to parse file as JSON:\n' + ex);
- }
- // Process the file
- for (var ykey in ydict) {
- let yval = ydict[ykey];
- if (debug)
- $log.debug('fileReader.onload: typeof ' + ykey + ' is ' + typeof ykey);
- // Allow only expected keys with scalar values
- if (! (ykey in $scope.ecdapp.parmFileDict))
- alert('Unexpected file content:\nKey not defined by blueprint:\n' + ykey);
- if (yval.constructor === {}.constructor)
- $scope.ecdapp.parmFileDict[ykey] = angular.toJson(yval);
- else
- $scope.ecdapp.parmFileDict[ykey] = yval;
- }
- if (debug)
- $log.debug('fileReader.onload: parmFileDict: ' + JSON.stringify($scope.ecdapp.parmFileDict));
-
- // Update table in all cases
- //$scope.ecdapp.setResourceDefinitionChanges($scope.ecdapp.editRequest.resourceDefinitionChanges, $scope.ecdapp.editRequest.parmFileDict);
- Object.keys($scope.ecdapp.parmFileDict).map(function(key, index) {
- if (key == 'config-format' || key == 'config-url' || key == 'chart-version') {
- $scope.ecdapp.editRequest.resourceDefinitionChanges[key] = $scope.ecdapp.parmFileDict[key];
- } else {
- $scope.ecdapp.editRequest.resourceConstants[key] = $scope.ecdapp.parmFileDict[key];
- }
- });
- //$scope.$apply();
- };
-
- // Handler for file-select event
- $scope.handleFileSelect = function() {
- if (debug)
- $log.debug('handleFileSelect: $scope.ecdapp.fileModel.name is ' + $scope.ecdapp.editRequest.fileModel.name);
- fileReader.readAsText($scope.ecdapp.editRequest.fileModel);
- };
-
-}); \ No newline at end of file
diff --git a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/inventory/deployment-service.js b/ccsdk-app-overlay/src/main/webapp/app/ccsdk/inventory/deployment-service.js
index 3fa2b2c..7b7a177 100644
--- a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/inventory/deployment-service.js
+++ b/ccsdk-app-overlay/src/main/webapp/app/ccsdk/inventory/deployment-service.js
@@ -4,7 +4,7 @@ appDS2.factory('InventoryDeploymentService', function ($http, $q, $log) {
* Gets one page of objects.
* @param {Number} pageNum - page number; e.g., 1
* @param {Number} viewPerPage - number of items per page; e.g., 25
- * @return {JSON} Response object from remote side
+ * @return {JSON} Response object from remote side.
*/
getDeployments: function(pageNum,viewPerPage,sortBy,searchBy) {
// cache control for IE
@@ -17,7 +17,7 @@ appDS2.factory('InventoryDeploymentService', function ($http, $q, $log) {
} else if (searchBy) {
url = 'inventory/dcae-services?pageNum=' + pageNum + '&viewPerPage=' + viewPerPage + '&searchBy=' + searchBy + cc;
} else {
- url = url = 'inventory/dcae-services?pageNum=' + pageNum + '&viewPerPage=' + viewPerPage + cc;
+ url = 'inventory/dcae-services?pageNum=' + pageNum + '&viewPerPage=' + viewPerPage + cc;
}
return $http({
method: 'GET',
@@ -35,6 +35,94 @@ appDS2.factory('InventoryDeploymentService', function ($http, $q, $log) {
return $q.reject(error.statusText);
});
},
+ getDeploymentsAafFilter: function(pageNum,viewPerPage,aafUsername) {
+ // cache control for IE
+ let cc = "&cc=" + new Date().getTime().toString();
+ let url = null;
+
+ url = 'filtered-deployments?pageNum=' + pageNum + '&viewPerPage=' + viewPerPage + '&inputKey=aaf_username' + '&inputValue=' + aafUsername + cc;
+
+ return $http({
+ method: 'GET',
+ url: url,
+ cache: false,
+ responseType: 'json'
+ }).then(function(response) {
+ if (response.data == null || typeof response.data != 'object')
+ return $q.reject('InventoryDeploymentService.getDeploymentsAafFilter: response.data null or not object');
+ else
+ return response.data;
+ },
+ function(error) {
+ $log.error('InventoryDeploymentService.getDeploymentsAafFilter failed: ' + JSON.stringify(error));
+ return $q.reject(error.statusText);
+ });
+ },
+ getDeploymentsDcaeTargetTypeFilter: function(pageNum,viewPerPage,dcaeTargetType) {
+ // cache control for IE
+ let cc = "&cc=" + new Date().getTime().toString();
+ let url = null;
+
+ url = 'filtered-deployments?pageNum=' + pageNum + '&viewPerPage=' + viewPerPage + '&inputKey=dcae_target_type' + '&inputValue=' + dcaeTargetType + cc;
+
+ return $http({
+ method: 'GET',
+ url: url,
+ cache: false,
+ responseType: 'json'
+ }).then(function(response) {
+ if (response.data == null || typeof response.data != 'object')
+ return $q.reject('InventoryDeploymentService.getDeploymentsDcaeTargetTypeFilter: response.data null or not object');
+ else
+ return response.data;
+ },
+ function(error) {
+ $log.error('InventoryDeploymentService.getDeploymentsDcaeTargetTypeFilter failed: ' + JSON.stringify(error));
+ return $q.reject(error.statusText);
+ });
+ },
+ getDeploymentCount: function(searchBy) {
+ let url = 'service-list-count';
+ if (searchBy) {
+ url = url + '?searchBy=' + searchBy;
+ }
+ return $http({
+ method: 'GET',
+ url: url,
+ cache: false,
+ responseType: 'json'
+ }).then(function(response) {
+ if (response.data == null || typeof response.data != 'object')
+ return $q.reject('InventoryDeploymentService.getDeploymentList: response.data null or not object');
+ else
+ return response.data;
+ },
+ function(error) {
+ $log.error('InventoryDeploymentService.getDeploymentList failed: ' + JSON.stringify(error));
+ return $q.reject(error.statusText);
+ });
+ },
+ getDeploymentList: function(searchBy) {
+ let url = 'service-list';
+ if (searchBy) {
+ url = url + '?searchBy=' + searchBy;
+ }
+ return $http({
+ method: 'GET',
+ url: url,
+ cache: false,
+ responseType: 'json'
+ }).then(function(response) {
+ if (response.data == null || typeof response.data != 'object')
+ return $q.reject('InventoryDeploymentService.getDeploymentList: response.data null or not object');
+ else
+ return response.data;
+ },
+ function(error) {
+ $log.error('InventoryDeploymentService.getDeploymentList failed: ' + JSON.stringify(error));
+ return $q.reject(error.statusText);
+ });
+ },
getDeploymentStatus: function(srvcIds) {
let url = 'deployment-status';
return $http({
@@ -128,6 +216,26 @@ appDS2.factory('InventoryDeploymentService', function ($http, $q, $log) {
return $q.reject(error.statusText);
});
},
+ deleteBlueprint: function(blueprintId, tenant) {
+ let url = 'blueprints/' + blueprintId + '?tenant=' + tenant;
+ return $http({
+ method: 'DELETE',
+ url: url,
+ responseType: 'json'
+ }).then(function(response) {
+ if (response.data == null)
+ return $q.reject('InventoryDeploymentService.deleteBlueprint: response.data null or not object');
+ else {
+ console.log('%c DELETE BLUEPRINT FOR ID ' + blueprintId, 'color: blue; font-weight: bold;');
+ console.log(response.data);
+ return response.data;
+ }
+ },
+ function(error) {
+ $log.error('InventoryDeploymentService.deleteBlueprint failed: ' + JSON.stringify(error));
+ return $q.reject(error.statusText);
+ });
+ },
getBlueprint: function(blueprintId, tenant) {
let url = 'blueprints/' + blueprintId + '?tenant=' + tenant;
//console.log("url: " + url);
@@ -191,6 +299,46 @@ appDS2.factory('InventoryDeploymentService', function ($http, $q, $log) {
return $q.reject(error.statusText);
});
},
+ getNodeInstances: function(deploymentId, tenant) {
+ console.log("entered getNodeInstances service function");
+ let url = 'node-instances/' + deploymentId + '?tenant=' + tenant;
+ return $http({
+ method: 'GET',
+ url: url,
+ cache: false,
+ responseType: 'json'
+ }).then(function(response) {
+ if (response.data == null)
+ return $q.reject('InventoryDeploymentService.getNodeInstances: response.data null or not object');
+ else {
+ return response.data;
+ }
+ },
+ function(error) {
+ $log.error('InventoryDeploymentService.getNodeInstances failed: ' + JSON.stringify(error));
+ return $q.reject(error.statusText);
+ });
+ },
+ getNodeInstanceData: function(deploymentId, tenant) {
+ console.log("entered getNodeInstanceData service function");
+ let url = 'node-instances-data?deployment=' + deploymentId + '&tenant=' + tenant;
+ return $http({
+ method: 'GET',
+ url: url,
+ cache: false,
+ responseType: 'json'
+ }).then(function(response) {
+ if (response.data == null)
+ return $q.reject('InventoryDeploymentService.getNodeInstanceData: response.data null or not object');
+ else {
+ return response.data;
+ }
+ },
+ function(error) {
+ $log.error('InventoryDeploymentService.getNodeInstances failed: ' + JSON.stringify(error));
+ return $q.reject(error.statusText);
+ });
+ },
updateResources: function(deploymentId, nodeInstanceId, resource_definition_changes) {
let body = {
"deployment_id": deploymentId,
@@ -291,6 +439,7 @@ appDS2.factory('InventoryDeploymentService', function ($http, $q, $log) {
let configFormat = resource_definition_changes["config-format"];
let chartUrl = resource_definition_changes["chart-repo-url"];
let chartVersion = resource_definition_changes["chart-version"];
+ let configSet = resource_definition_changes["config-set"];
let body = {
"deployment_id": deploymentId,
"workflow_id": "upgrade",
@@ -298,11 +447,12 @@ appDS2.factory('InventoryDeploymentService', function ($http, $q, $log) {
"force": true,
"tenant": tenant,
"parameters": {
+ "config_set": configSet,
"node_instance_id": nodeInstanceId,
+ "chart_version": chartVersion,
+ "chart_repo_url": chartUrl,
"config_url": configUrl,
- "config_format": configFormat,
- "chartRepo": chartUrl,
- "chartVersion": chartVersion
+ "config_format": configFormat
}
};
let urlStr = 'executions';
diff --git a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/inventory/execution-service.js b/ccsdk-app-overlay/src/main/webapp/app/ccsdk/inventory/execution-service.js
index a4181f4..a756a2b 100644
--- a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/inventory/execution-service.js
+++ b/ccsdk-app-overlay/src/main/webapp/app/ccsdk/inventory/execution-service.js
@@ -6,6 +6,64 @@ appDS2.factory('InventoryExecutionService', function ($http, $q, $log) {
* @param {Number} viewPerPage - number of items per page; e.g., 25
* @return {JSON} Response object from remote side
*/
+ getActiveExecutions: function(pageNum, viewPerPage) {
+ let cc = "&cc=" + new Date().getTime().toString();
+ let url = 'executions/active?pageNum=' + pageNum + '&viewPerPage=' + viewPerPage + cc;
+ return $http({
+ method: 'GET',
+ url: url,
+ cache: false,
+ responseType: 'json'
+ }).then(function(response) {
+ if (response.data == null || typeof response.data != 'object')
+ return $q.reject('InventoryExecutionService.getActiveExecutions: response.data null or not object');
+ else
+ return response.data;
+ },
+ function(error) {
+ $log.error('InventoryExecutionService.getActiveExecutions failed: ' + JSON.stringify(error));
+ return $q.reject(error.statusText);
+ });
+ },
+ getExecutionsById: function(id, tenant, pageNum, viewPerPage) {
+ let cc = "&cc=" + new Date().getTime().toString();
+ let url = 'executions/'+ id + '?pageNum=' + pageNum + '&viewPerPage=' + viewPerPage + '&tenant=' + tenant + '&status=' + status + cc;
+ return $http({
+ method: 'GET',
+ url: url,
+ cache: false,
+ responseType: 'json'
+ }).then(function(response) {
+ if (response.data == null || typeof response.data != 'object')
+ return $q.reject('InventoryExecutionService.getExecutionsById: response.data null or not object');
+ else
+ return response.data;
+ },
+ function(error) {
+ $log.error('InventoryExecutionService.getExecutionsById failed: ' + JSON.stringify(error));
+ return $q.reject(error.statusText);
+ });
+ },
+ getExecutionsByTenant: function(tenant, status, pageNum, viewPerPage) {
+ // cache control for IE
+ let cc = "&cc=" + new Date().getTime().toString();
+ let url = 'executions/tenant?pageNum=' + pageNum + '&viewPerPage=' + viewPerPage + '&tenant=' + tenant + '&status=' + status + cc;
+ return $http({
+ method: 'GET',
+ url: url,
+ cache: false,
+ responseType: 'json'
+ }).then(function(response) {
+ if (response.data == null || typeof response.data != 'object')
+ return $q.reject('InventoryExecutionService.getExecutionsByTenant: response.data null or not object');
+ else
+ return response.data;
+ },
+ function(error) {
+ $log.error('InventoryExecutionService.getExecutionsByTenant failed: ' + JSON.stringify(error));
+ return $q.reject(error.statusText);
+ });
+ },
getExecutionsByDeployment: function(deploymentId, tenant, pageNum, viewPerPage) {
// cache control for IE
let cc = "&cc=" + new Date().getTime().toString();
diff --git a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/inventory/inventory_blueprint_popups.html b/ccsdk-app-overlay/src/main/webapp/app/ccsdk/inventory/inventory_blueprint_popups.html
index eed1dfe..d17c065 100644
--- a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/inventory/inventory_blueprint_popups.html
+++ b/ccsdk-app-overlay/src/main/webapp/app/ccsdk/inventory/inventory_blueprint_popups.html
@@ -1,5 +1,5 @@
<script type="text/ng-template"
- id="inventory_blueprint_update_popup.html">
+ id="inventory_blueprint_update_popup.html">
<style>
.ecd-parameter-table
@@ -30,6 +30,13 @@
Blueprint <span style="font-weight: bolder;background: aqua;">{{ecdapp.serviceType.typeName}}</span> upload is in progress...
</div>
</div>
+ <!-- show progress indicator -->
+ <div ng-show="ecdapp.isDataLoading">
+ <div class="span" style="margin-bottom:20px;">
+ <i class="icon-spinner small" role="img" aria-label="Please wait while the content loads"></i>
+ Please wait while the content loads.
+ </div>
+ </div>
<form name="updateForm">
<div class="row-nowrap" style="margin-top:-20px;">
<div class="span4 form-row">
@@ -89,9 +96,9 @@
<div class="span6 form-row">
<label class="span12" for="typeName">*Blueprint Version</label>
<div class="field-group tooltip-onclick" b2b-tooltip>
- <input type="text" id="typeVer" name="typeVer" class="span12" data-ng-model="ecdapp.serviceType.typeVersion" disabled="disabled">
+ <input type="text" id="typeVer" name="typeVer" class="span12" data-ng-model="ecdapp.serviceType.typeVersion">
<button class="reset-field" type="button" aria-label="Reset text field"></button>
- <button id="tooltipButton3" class="btn icon-content-listguide tooltip-element icon-tooltip" data-toggle="button" aria-label="Email help" aria-describedby="tooltipContent4" >
+ <button id="tooltipButton33" class="btn icon-content-listguide tooltip-element icon-tooltip" data-toggle="button" aria-label="Email help" aria-describedby="tooltipContent4" >
</button>
<div class="helpertext" tabindex="-1" role="tooltip" id="tooltipContent4">
<div class="popover-title">Blueprint or Type version - a required input</div>
@@ -140,7 +147,7 @@
</div>
<div class="b2b-modal-footer ng-scope ng-isolate-scope">
- <div class="cta-button-group in">
+ <div ng-hide="ecdapp.updateInProgress" class="cta-button-group in">
<button class="btn btn-alt btn-small" type="submit" ng-disabled="updateForm.$invalid"
ng-click="ecdapp.updateBlueprint(ecdapp.serviceType);">
Save
@@ -153,9 +160,8 @@
</div>
</script>
-
<script type="text/ng-template"
- id="inventory_blueprint_upload_popup.html">
+ id="inventory_blueprint_upload_popup.html">
<style>
.ecd-parameter-table
@@ -218,7 +224,7 @@
</div>
</div>
<form name="uploadForm">
- <div class="row-nowrap" style="margin-top:-20px;" ng-show="ecdapp.isImport">
+ <div class="row-nowrap" style="margin-top:-20px;" ng-show="ecdapp.isImport && ecdapp.isInternal">
<div class="span3 form-row" ng-class="{'error':uploadForm.appl.$touched && !ecdapp.validAppl}">
<div class="tooltip" b2b-tooltip trigger="focus">
<a href="javascript:void(0)" class="tooltip-element" data-placement="bottom" role="button" aria-label="Help" aria-describedby="tooltiptext1" >
@@ -302,7 +308,7 @@
</div>
</div>
</div>
- <div class="row-nowrap" style="margin-top:-20px;" ng-hide="ecdapp.isImport">
+ <div class="row-nowrap" style="margin-top:-20px;" ng-show="!ecdapp.isImport && ecdapp.isInternal">
<div class="span3 form-row" ng-class="{'error':uploadForm.appl.$touched && !ecdapp.validAppl}">
<div class="tooltip" b2b-tooltip trigger="focus">
<a href="javascript:void(0)" class="tooltip-element" data-placement="bottom" role="button" aria-label="Help" aria-describedby="tooltiptext1" >
@@ -322,7 +328,8 @@
</div>
</div>
<div class="field-group">
- <select id="appl" name="appl" b2b-dropdown placeholder-text="Select Application" class="span8" data-ng-model="ecdapp.serviceTypeRequest.application" ng-change="ecdapp.selectAppComp(ecdapp.serviceTypeRequest.application)" required>
+ <select id="appl" name="appl" b2b-dropdown placeholder-text="Select Application"
+ class="span8" data-ng-model="ecdapp.serviceTypeRequest.application" ng-change="ecdapp.selectAppComp(ecdapp.serviceTypeRequest.application)" required>
<option b2b-dropdown-list option-repeat="d in ecdapp.apps" value="{{d}}">{{d}}</option>
</select>
</div>
@@ -356,7 +363,11 @@
</div>
</div>
<div class="field-group">
- <select b2b-dropdown name="comp" class="span8" placeholder-text="Select Component" data-ng-model="ecdapp.serviceTypeRequest.component" ng-change="ecdapp.validateComp()" ng-disabled="!ecdapp.validAppl" required>
+
+ <select b2b-dropdown name="comp" class="span8" placeholder-text="Select Component"
+ data-ng-init="ecdapp.serviceTypeRequest.component"
+ data-ng-model="ecdapp.serviceTypeRequest.component" ng-change="ecdapp.validateComp()"
+ ng-disabled="!ecdapp.validAppl" required>
<option b2b-dropdown-list option-repeat="d in ecdapp.comps" value="{{d.cname}}">{{d.dname}}</option>
</select>
</div>
@@ -396,56 +407,13 @@
</div>
</div>
</div>
- <div class="row-nowrap" ng-hide="ecdapp.isImport">
- <div id="addAppDiv" class="span12 row-nowrap" ng-show="ecdapp.enableAppForm">
- <div class="span4 form-row">
- <label>*Component Name</label>
- <div class="field-group tooltip-onclick" b2b-tooltip>
- <input type="text" class="span12" data-ng-model="ecdapp.newCompName" placeholder="Example: scheduler">
- <button class="reset-field" type="button" aria-label="Reset text field"></button>
- <button id="tooltipButton1" class="btn icon-tooltip tooltip-element" data-toggle="button" aria-label="Comp Name" aria-describedby="tooltipContent1" >
- </button>
- <div class="helpertext" tabindex="-1" role="tooltip" id="tooltipContent1">
- <div class="popover-title">Component name - a required input</div>
- <div class="popover-content">
- <p>Component name is a sub-string of the application namespace in AAF. A non-admin user should only add a new component if that user's role belongs to the component namespace.</p>
- <strong class="hidden-spoken">Double tap to close help message.</strong>
- </div>
- </div>
- </div>
- </div>
- <div class="span4 form-row">
- <label>*Component Display Name</label>
- <div class="field-group tooltip-onclick" b2b-tooltip>
- <input type="text" class="span12" data-ng-model="ecdapp.newCompDisplayName" placeholder="Example: ECOMP SCHEDULER" style="text-transform:uppercase">
- <button class="reset-field" type="button" aria-label="Reset text field"></button>
- <button id="tooltipButton2" class="btn icon-tooltip tooltip-element" data-toggle="button" aria-label="Email help" aria-describedby="tooltipContent2" >
- </button>
- <div class="helpertext" tabindex="-1" role="tooltip" id="tooltipContent2">
- <div class="popover-title">Component Display Name - a required input</div>
- <div class="popover-content">
- <p>Component display name in selection menu</p>
- <strong class="hidden-spoken">Double tap to close help message.</strong>
- </div>
- </div>
- </div>
- </div>
- <div class="span1 form-row">
- <label></label>
- <div class="field-group" ng-click="ecdapp.addApplication(ecdapp.serviceTypeRequest.application, ecdapp.newCompId,
- ecdapp.newCompName, ecdapp.newCompDisplayName);">
- <a href="" title="Add Component" class="icon-arrows-quick-sync ecd-icon-action"></a>
- </div>
- </div>
- </div>
- </div>
<div class="row-nowrap">
<div class="span6 form-row" ng-class="{'error':uploadForm.typeName.$touched && uploadForm.typeName.$invalid}">
<label class="span12" for="typeName">*Blueprint Name</label>
<div class="field-group tooltip-onclick" b2b-tooltip>
<input type="text" id="typeName" name="typeName" class="span12" data-ng-model="ecdapp.serviceTypeRequest.typeName" placeholder="Example: mso_helm_chart" required>
<button class="reset-field" type="button" aria-label="Reset text field"></button>
- <button id="tooltipButton3" class="btn icon-tooltip tooltip-element" data-toggle="button" aria-label="Email help" aria-describedby="tooltipContent3" >
+ <button id="tooltipButton35" class="btn icon-tooltip tooltip-element" data-toggle="button" aria-label="Email help" aria-describedby="tooltipContent3" >
</button>
<div class="helpertext" tabindex="-1" role="tooltip" id="tooltipContent3">
<div class="popover-title">Blueprint or Type name - a required input</div>
@@ -465,12 +433,12 @@
<div class="field-group tooltip-onclick" b2b-tooltip>
<input type="text" id="typeVer" name="typeVer" class="span12" data-ng-model="ecdapp.serviceTypeRequest.typeVersion" placeholder="Example: 181017" required>
<button class="reset-field" type="button" aria-label="Reset text field"></button>
- <button id="tooltipButton3" class="btn icon-tooltip tooltip-element" data-toggle="button" aria-label="Email help" aria-describedby="tooltipContent4" >
+ <button id="tooltipButton41" class="btn icon-tooltip tooltip-element" data-toggle="button" aria-label="Email help" aria-describedby="tooltipContent4" >
</button>
<div class="helpertext" tabindex="-1" role="tooltip" id="tooltipContent4">
<div class="popover-title">Blueprint or Type version - a required input</div>
<div class="popover-content">
- <p>Blueprint or Service Type version may be an integer, example: 10, 181017 or a semantic version string, example: 1902.01.03. Semantic version string is converted to an integer by removing "...", before inserting into inventory. This field is used to identify the blueprint template version or a component package version.</p>
+ <p>Blueprint or Service Type version should be an integer. This field is used to identify the blueprint template version or a component package version.</p>
<strong class="hidden-spoken">Double tap to close help message.</strong>
</div>
</div>
@@ -523,8 +491,12 @@
</div>
<div class="b2b-modal-footer ng-scope ng-isolate-scope">
- <div class="cta-button-group in">
- <button class="btn btn-alt btn-small" type="submit" ng-disabled="uploadForm.$invalid || !ecdapp.validAppl || !ecdapp.validComp"
+ <div ng-hide="ecdapp.uploadInProgress" class="cta-button-group in">
+ <button class="btn btn-alt btn-small" type="submit" ng-show="ecdapp.isInternal" ng-disabled="uploadForm.$invalid || !ecdapp.validAppl || !ecdapp.validComp"
+ ng-click="ecdapp.uploadBlueprint(ecdapp.serviceTypeRequest);">
+ Save
+ </button>
+ <button class="btn btn-alt btn-small" type="submit" ng-show="!ecdapp.isInternal" ng-disabled="uploadForm.$invalid"
ng-click="ecdapp.uploadBlueprint(ecdapp.serviceTypeRequest);">
Save
</button>
@@ -535,7 +507,6 @@
</div>
</div>
</script>
-
<script type="text/ng-template" id="inventory_blueprint_view_popup.html">
<div class="b2b-modal-header ng-scope">
@@ -577,9 +548,8 @@
</div>
</script>
-
<script type="text/ng-template"
- id="inventory_blueprint_deploy_popup.html">
+ id="inventory_blueprint_deploy_popup.html">
<style>
.ecd-parameter-table
@@ -685,7 +655,7 @@
</div>
</div>
<select id="cldTenants" name="tenant" b2b-dropdown placeholder-text="Select Tenant" class="span8" data-ng-model="ecdapp.editRequest.tenant" ng-change="ecdapp.validateTenant()">
- <option b2b-dropdown-list option-repeat="d in tenantList.data" value="{{d.name}}">{{d.name}}</option>
+ <option b2b-dropdown-list option-repeat="d in ecdapp.availableTenants" value="{{d}}">{{d}}</option>
</select>
<div ng-if="deployForm.tenant.$touched && !ecdapp.validTenant" id="tenantDropdown" role="alert" class="error-msg" aria-live="polite" aria-atomic="true" >
<i class="icon-badgealert" aria-hidden="true"></i>
@@ -710,7 +680,7 @@
</div>
</div>
- <div ng-hide="ecdapp.deploymentInProgress" class="row-nowrap">
+ <div ng-hide="ecdapp.isDataLoading" class="row-nowrap">
<div class="span12">
<div class="form-row">
<label for="parameters">*Parameters</label>
@@ -723,13 +693,17 @@
<div class="ecd-parameter-table">
<table id="parameters">
<tr id="ecd-table-header">
- <th width="60%">Name</th>
- <th width="40%">Value</th>
+ <th width="30%">Name</th>
+ <!--<th width="40%">Description</th>-->
+ <th width="70%">Value</th>
</tr>
<tbody ng-repeat="(pkey, pval) in ecdapp.editRequest.parmFileDict">
<tr id="tr-rowData">
- <td ng-bind="pkey"/>
- <td><input id="parameterValue" class="span12" type="text" data-ng-model="ecdapp.editRequest.parmFileDict[pkey]" autofocus/></td>
+ <td>
+ <div style="font-weight: bold;">{{pkey}}</div>
+ <div style="margin-top: 8px; font-weight: lighter;">{{ecdapp.editRequest.descriptionDict[pkey]}}</div>
+ </td>
+ <td><input json id="parameterValue" class="span12" type="text" data-ng-model="ecdapp.editRequest.parmFileDict[pkey]" autofocus/></td>
</tr>
</tbody>
</table>
diff --git a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/inventory/inventory_blueprint_table.html b/ccsdk-app-overlay/src/main/webapp/app/ccsdk/inventory/inventory_blueprint_table.html
index 763d956..044db14 100644
--- a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/inventory/inventory_blueprint_table.html
+++ b/ccsdk-app-overlay/src/main/webapp/app/ccsdk/inventory/inventory_blueprint_table.html
@@ -1,177 +1,297 @@
<div id="page-content">
-
- <h1 class="heading-page" id="blueprints">Blueprints</h1>
- <!-- show progress indicator -->
- <div ng-show="ecdapp.isDataLoading">
- <div class="span" style="margin-bottom:20px;">
- <i class="icon-spinner small" role="img" aria-label="Please wait while the content loads"></i>
- Please wait while the content loads.
- </div>
- </div>
-
- <div ng-hide="ecdapp.isDataLoading">
- <div id="button-search-row">
- <span class="tooltip" b2b-tooltip>
- <a href="#" class="btn btn-alt btn-small tooltip-element" tabindex="0" role="button" data-placement="bottom"
- aria-label="Help" ng-click="ecdapp.uploadBlueprintModalPopup()" aria-describedby="tooltiptextBtn">
- Create
- <span class="arrow"></span>
- </a>
- <span class="tooltip-wrapper">
- <span class="tooltip-size-control">
- <span id="tooltiptextBtn" role="tooltip" aria-live="polite" aria-hidden="true" class="helpertext" tabindex="-1">
- <span class="popover-title">Upload a blueprint</span>
- <span class="popover-content">
- <span>Click to open up a FORM to upload and create a new blueprint in inventory.</span>
- <strong class="hidden-spoken hidden-desktop">Double tap to close help message.</strong>
- </span>
- </span>
- </span>
- </span>
+ <h1 class="heading-page" id="blueprint-page">Blueprints</h1>
+
+ <!-- show progress indicator -->
+ <div ng-show="ecdapp.isDataLoading">
+ <div class="span" style="margin-bottom: 20px;">
+ <i class="icon-spinner small" role="img"
+ aria-label="Please wait while the content loads"></i> Please
+ wait while the content loads.
+ </div>
+ </div>
+ <div ng-hide="ecdapp.isDataLoading" style="margin-bottom: 20px;">
+ <span class="tooltip" b2b-tooltip> <a href="#"
+ class="btn btn-alt btn-small tooltip-element" tabindex="0"
+ role="button" data-placement="bottom" aria-label="Help"
+ ng-click="ecdapp.uploadBlueprintModalPopup()"
+ aria-describedby="tooltiptextBtn"> Upload <span class="arrow"></span>
+ </a> <span class="tooltip-wrapper"> <span
+ class="tooltip-size-control"> <span id="tooltiptextBtn"
+ role="tooltip" aria-live="polite" aria-hidden="true"
+ class="helpertext" tabindex="-1"> <span
+ class="popover-title">Upload a blueprint</span> <span
+ class="popover-content"> <span>Click to open
+ up a FORM to upload and create a new blueprint in
+ inventory.</span> <strong class="hidden-spoken hidden-desktop">Double
+ tap to close help message.</strong>
+ </span>
+ </span>
+ </span>
</span>
- <div style="float:right;">
- <div class="group">
- <button tabindex="-1" class="btn btn-small" title="Reset Filters" type="button" ng-click="ecdapp.loadTable()"><i class="icon-arrows-replay-restart"></i></button>
- <input tabindex="0" class="btn btn-small" type="text" placeholder="Search Blueprints" ng-model="ecdapp.searchBy"></input>
- <button tabindex="1" class="btn btn-small" title="Search" type="button" ng-click="ecdapp.searchTable(ecdapp.searchBy)"><i class="ion-search"></i></button>
- </div>
- </div>
- </div>
-
- <div ng-show="ecdapp.isRequestFailed">
- <span class="ecd-error-message">{{ecdapp.errMsg}}</span>
- </div>
-
- <div ng-hide="ecdapp.isRequestFailed">
-
- <div
- b2b-table
- id="blueprints-table"
- class="b2b-table-div"
- table-data="ecdapp.tableData"
- current-page="ecdapp.currentPageIgnored"
- next-sort="ecdapp.nextSortIgnored">
-
- <table>
-
- <thead b2b-table-row type="header">
- <tr id="th-header-row">
- <th id="expandTableHeading0" b2b-table-header sortable="false" key="application" ng-click="ecdapp.sortTable('application')">Application</th>
- <th b2b-table-header sortable="false" key="component" ng-click="ecdapp.sortTable('component')">Component</th>
- <th b2b-table-header sortable="false" key="type_name" ng-click="ecdapp.sortTable('typeName')">Name</th>
- <th b2b-table-header sortable="false" key="type_version" ng-click="ecdapp.sortTable('typeVersion')">Version</th>
- <th b2b-table-header sortable="false" key="created_at" ng-click="ecdapp.sortTable('created')">Created Date</th>
- <th b2b-table-header sortable="false" key="deployment_ref">Deployments
- <button style="margin-bottom:-5px; box-shadow:0 0 0 0 rgba(0, 0, 0, 0.15); min-width:0;" tabindex="1" class="btn btn-small" title="Refresh Deployments" type="button" ng-click="ecdapp.updateTable()">
- <i class="icon-arrows-replay-restart"></i>
- </button>
- <div ng-show="ecdapp.isSrvcDataLoading">
- <div class="span" style="margin-bottom:5px;">
- <i class="icon-spinner small" role="img" aria-label="Deployment Info is loading"></i>
- Deployment Info is loading
- </div>
- </div>
- </th>
- <th b2b-table-header sortable="false">Actions</th>
- <th b2b-table-header sortable="false" key="owner" ng-click="ecdapp.sortTable('owner')">Owner</th>
- <th b2b-table-header sortable="false" key="type_id" ng-click="ecdapp.sortTable('typeId')">ID</th>
- </tr>
- </thead>
-
- <tbody b2b-table-row type="body" ng-repeat="rowData in ecdapp.tableData">
- <tr id="tr-rowData{{index}}" tabindex="0">
- <td b2b-table-body id="expandTable_t1_{{$index}}" headers="expandTableHeading0"
- ng-bind="rowData.application"/>
- <td b2b-table-body
- ng-bind="rowData.component" />
- <td b2b-table-body
- ng-bind="rowData.typeName" />
- <td b2b-table-body
- ng-bind="rowData.typeVersion" />
- <td b2b-table-body
- ng-bind="rowData.created | date : 'MM-dd-yyyy HH:mm:ss Z'" />
- <td b2b-table-body ng-class="{'b2b-td-noLeftBorder' : rowData.expanded}" style="padding-right:0px;">
- <span>{{rowData.deployments.totalCount}}
- <i ng-if="rowData.deployments.totalCount != 0" class="pull-right" aria-label="{{rowData.expanded ? 'Collapse row ' + rowData.deployments : 'Expand row ' + rowData.deployments}}"
- ng-class="{'icon-accordion-plus': !rowData.expanded, 'icon-accordion-minus' : rowData.expanded}"
- ng-click="rowData.expanded=!rowData.expanded" b2b-accessibility-click="13,32" tabindex="0" role="button" aria-expanded="false"
- title="click to view service information"></i>
- </span>
- </td>
- <td b2b-table-body >
- <div class="btn-group btn-actions" style="margin-bottom:0;box-shadow:none;">
- <button type="button" class="btn dropdown-toggle" data-toggle="dropdown" title="More Actions"><i class="icon-apps-marketplace"></i></button>
- <ul class="dropdown-menu">
- <li>
- <div ng-click="ecdapp.viewBlueprintModalPopup(rowData);">
- <i class="icon-documents-book ecd-icon-action"></i><a href="">View</a>
- </div>
- </li>
- <li>
- <div ng-click="ecdapp.exportJson(rowData);">
- <i class="icon-documents-copy ecd-icon-action"></i><a href="">Export</a>
- </div>
- </li>
- <li>
- <div ng-show="rowData.canDeploy && rowData.deployments.totalCount === 0" ng-click="ecdapp.updateBlueprintModalPopup(rowData);">
- <i class="icon-misc-pen ecd-icon-action"></i><a href="">Update</a>
- </div>
- </li>
- <li>
- <div ng-show="rowData.canDeploy" ng-click="ecdapp.deployBlueprintModalPopup(rowData);">
- <i class="icon-arrows-download ecd-icon-action"></i><a href="">Deploy</a>
- </div>
- </li>
- <li>
- <div ng-show="rowData.canDeploy && rowData.deployments.totalCount === 0" ng-click="ecdapp.deleteBlueprintModalPopup(rowData);">
- <i class="icon-misc-trash ecd-icon-action"></i><a href="">Delete</a>
- </div>
- </li>
- </ul>
- </div><!-- .btn-group -->
- </td>
- <td b2b-table-body
- ng-bind="rowData.owner" />
- <td b2b-table-body
- ng-bind="rowData.typeId" />
- </tr>
- <tr ng-show="rowData.expanded">
- <td colspan="6" class="b2b-td-noTopBorder" headers="expandTable_t1_{{$index}}">
- <p class="offscreen-text">Expanded Row details for {{rowData.deployments}}</p>
- <ul>
- <li class="mar-top-30" ng-repeat="srvcData in rowData.deployments.items">
- <div> <span class="font-medium">{{$index+1}}</span> </div>
- <div class="b2b-leading-dots">
- <span class="font-medium">Deployment ID</span>
- <!-- <span class="pull-right" ng-bind="srvcData.serviceId"><a href="ecd#/idep/{{srvcData.serviceId}}"></a></span>-->
- <span class="pull-right"><a href="ecd#/idep/{{srvcData.serviceId}}">{{srvcData.serviceId}}</a></span>
- </div>
- <div class="b2b-leading-dots">
- <span class="font-medium">Created timestamp</span>
- <span class="pull-right" ng-bind="srvcData.created | date : 'MM-dd-yyyy HH:mm:ss Z'"" />
- </div>
- <div class="b2b-leading-dots">
- <span class="font-medium">Modified timestamp</span>
- <span class="pull-right" ng-bind="srvcData.modified | date : 'MM-dd-yyyy HH:mm:ss Z'"" />
- </div>
- </li>
- <br>
- </ul>
- </td>
- </tr>
- </tbody>
- </table>
- </div>
-
- <div b2b-pagination="" total-pages="ecdapp.totalPages"
- current-page="ecdapp.currentPageNum" click-handler="pageChangeHandler"
- role="navigation">
- </div>
-
- <div style="height: 10px;">
- <!-- space between page number and black footer -->
- </div>
-
- </div><!-- loading -->
-
-</div><!-- page content -->
+ </span>
+ </div>
+ <div id="button-search-row" style="width: 60%; margin-left: 45px; float:right; margin-top: -30px;"
+ ng-hide="ecdapp.isDataLoading">
+ <div>
+ <div class="group">
+ <div class="advanced-search">
+ <button tabindex="-1"
+ style="position: absolute; margin-left: -35px; border: none; background: none; top: 5px;"
+ "class="btn btn-small" title="show unfiltered view"
+ type="button" ng-click="ecdapp.reloadTable()">
+ <i class="icon-arrows-replay-restart"></i>
+ </button>
+ <button tabindex="1"
+ style="position: absolute; border: none; background: none; margin-left: 5px; top: 5px;"
+ "class="btn btn-medium" type="button"
+ ng-click="ecdapp.filterBySvc()">
+ <i class="ion-search"></i>
+ </button>
+ <input type="text" style="padding-left: 50px;"
+ class="advanced-search-input"
+ placeholder="Search Blueprints"
+ ng-model="ecdapp.searchString"
+ ng-keydown="[13, 32].includes($event.keyCode) && ecdapp.filterBySvc()"></input>
+ <button type="button" id="show-menu-filters"
+ class="btn dropdown-toggle"
+ ng-click="ecdapp.toggleMoreFilters()"
+ data-toggle="dropdown" title="More Filters">
+ <i class="icon-controls-down"></i>
+ </button>
+ </div>
+ </div>
+ <div class="menu-filters" ng-show="ecdapp.showingMoreFilters">
+ <div class="group">
+ <label class="col-sm-3 control-label">Blueprints: </label>
+ <ui-select multiple ng-model="ecdapp.selectedBp"
+ theme="bootstrap" close-on-select="false"
+ title="Blueprint Name"> <ui-select-match
+ class="ui-select-match">{{$item}}</ui-select-match> <ui-select-choices
+ class="ui-select-choices"
+ repeat="bp in ecdapp.availableBp | filter:$select.search"
+ position='down'> {{bp}} </ui-select-choices> </ui-select>
+ </div>
+ <div class="group" ng-show="ecdapp.isInternal">
+ <label class="col-sm-3 control-label">Applications:
+ </label>
+ <ui-select multiple ng-model="ecdapp.selectedApp"
+ theme="bootstrap" close-on-select="false"
+ title="Application"> <ui-select-match
+ class="ui-select-match">{{$item}}</ui-select-match> <ui-select-choices
+ class="ui-select-choices"
+ repeat="app in ecdapp.apps | filter:$select.search"
+ position='down'> {{app}} </ui-select-choices> </ui-select>
+ </div>
+ <div class="group" ng-show="ecdapp.isInternal">
+ <label class="col-sm-3 control-label">Components: </label>
+ <ui-select multiple ng-model="ecdapp.selectedComp"
+ theme="bootstrap" close-on-select="false"
+ title="Component name"> <ui-select-match
+ class="ui-select-match">{{$item}}</ui-select-match> <ui-select-choices
+ class="ui-select-choices"
+ repeat="comp in ecdapp.availableComp | filter:$select.search"
+ position='down'> {{comp}} </ui-select-choices> </ui-select>
+ </div>
+ <div class="group" ng-hide="ecdapp.filterByUser">
+ <label class="col-sm-3 control-label">Owners: </label>
+ <ui-select multiple ng-model="ecdapp.selectedOwner"
+ theme="bootstrap" close-on-select="false"
+ title="Blueprint owner"> <ui-select-match
+ class="ui-select-match">{{$item}}</ui-select-match> <ui-select-choices
+ class="ui-select-choices"
+ repeat="owner in ecdapp.bpOwners | filter:$select.search"
+ position='down'> {{owner}} </ui-select-choices> </ui-select>
+ </div>
+ <div class="group" style="float: right;">
+ <button tabindex="-1" class="btn btn-small"
+ title="Reset Filters" type="button"
+ ng-click="ecdapp.resetFilters()">
+ <i class="icon-arrows-replay-restart"></i>
+ </button>
+ <button tabindex="1" class="btn btn-small"
+ title="Filtered search" type="button"
+ ng-click="ecdapp.extendedfilterSrch()">
+ <i class="ion-search"></i>
+ </button>
+ </div>
+ </div>
+ </div>
+ <div style="margin-left: 20px; margin-top: 10px;" title="Search filters">
+ <label for="checkbox3" class="checkbox">
+ <input id="checkbox3" type="checkbox" ng-model="ecdapp.filterByUser" ng-change="ecdapp.toggleUserFilt()"
+ class="ng-valid ng-dirty ng-valid-parse ng-touched">
+ <i class="skin"></i><span>My Blueprints</span>
+ </label>
+ </div>
+ </div>
+
+ <div ng-show="ecdapp.isRequestFailed">
+ <span class="ecd-error-message">{{ecdapp.errMsg}}</span>
+ </div>
+ <div ng-hide="ecdapp.isRequestFailed" >
+ <div b2b-table id="blueprints-table" class="b2b-table-div"
+ table-data="ecdapp.tableData"
+ current-page="ecdapp.currentPageIgnored"
+ next-sort="ecdapp.nextSortIgnored">
+ <table>
+ <thead b2b-table-row type="header">
+ <tr id="th-header-row">
+ <th b2b-table-header sortable="false" key="type_name"
+ ng-click="ecdapp.sortTable('typeName')">Name</th>
+ <th b2b-table-header sortable="false" key="type_version"
+ ng-click="ecdapp.sortTable('typeVersion')">Version</th>
+ <th b2b-table-header sortable="false" key="created_at"
+ ng-click="ecdapp.sortTable('created')">Created Date</th>
+ <th b2b-table-header sortable="false" key="deployment_ref">
+ <button style="margin-bottom: -10px;box-shadow: 0 0 0 0 rgba(0, 0, 0, 0.15);min-width: 0;margin-left: -20px;" tabindex="1" class="btn btn-small ng-scope" title="Refresh Deployments" type="button" ng-click="ecdapp.updateTable()">
+ <i class="icon-arrows-replay-restart"></i>
+ <span class="ng-scope">Deployments</span>
+ </button>
+ <div ng-show="ecdapp.isSrvcDataLoading" class="ng-scope ng-hide">
+ <div class="span" style="margin-bottom: 5px;">
+ <i class="icon-spinner small" role="img" aria-label="Deployment Info is loading"></i>
+ Deployment Info is loading
+ </div>
+ </div>
+ </th>
+ <th b2b-table-header sortable="false">Actions</th>
+ <th b2b-table-header sortable="false" key="component"
+ ng-click="ecdapp.sortTable('component')">Component</th>
+ <th b2b-table-header sortable="false" key="owner"
+ ng-click="ecdapp.sortTable('owner')">Owner</th>
+ <th b2b-table-header sortable="false" key="type_id"
+ ng-click="ecdapp.sortTable('typeId')">ID</th>
+ </tr>
+ </thead>
+ <tbody b2b-table-row type="body"
+ ng-repeat="rowData in ecdapp.tableData">
+ <tr id="tr-rowData{{index}}" tabindex="0">
+ <td b2b-table-body ng-bind="rowData.typeName" />
+ <td b2b-table-body ng-bind="rowData.typeVersion" />
+ <td b2b-table-body
+ ng-bind="rowData.created | date : 'MM-dd-yyyy HH:mm:ss Z'" />
+ <td b2b-table-body ng-if="rowData.deployments == undefined">
+ 0
+ </td>
+ <td b2b-table-body ng-if="rowData.deployments"
+ ng-class="{'b2b-td-noLeftBorder' : rowData.expanded}"
+ style="padding-right: 0px;"><span>{{rowData.deployments.totalCount}}
+ <i ng-if="rowData.deployments && rowData.deployments.totalCount != 0"
+ class="pull-right"
+ aria-label="{{rowData.expanded ? 'Collapse row ' + rowData.deployments : 'Expand row ' + rowData.deployments}}"
+ ng-class="{'icon-accordion-plus': !rowData.expanded, 'icon-accordion-minus' : rowData.expanded}"
+ ng-click="rowData.expanded=!rowData.expanded"
+ b2b-accessibility-click="13,32" tabindex="0"
+ role="button" aria-expanded="false"
+ title="click to view service information"></i>
+ </span></td>
+ <td b2b-table-body>
+ <div class="btn-group btn-actions"
+ style="margin-bottom: 0; box-shadow: none;">
+ <button type="button" class="btn dropdown-toggle"
+ data-toggle="dropdown" title="More Actions">
+ <i class="icon-apps-marketplace"></i>
+ </button>
+ <ul class="dropdown-menu">
+ <li>
+ <div
+ ng-click="ecdapp.viewBlueprintModalPopup(rowData);">
+ <i class="icon-documents-book ecd-icon-action"></i><a
+ href="">View</a>
+ </div>
+ </li>
+ <li>
+ <div ng-click="ecdapp.exportJson(rowData);">
+ <i class="icon-documents-copy ecd-icon-action"></i><a
+ href="">Export</a>
+ </div>
+ </li>
+ <li>
+ <div
+ ng-show="rowData.canDeploy && (rowData.deployments == undefined || rowData.deployments.totalCount === 0)"
+ ng-click="ecdapp.updateBlueprintModalPopup(rowData);">
+ <i class="icon-misc-pen ecd-icon-action"></i><a
+ href="">Update</a>
+ </div>
+ </li>
+ <li>
+ <div ng-show="rowData.canDeploy"
+ ng-click="ecdapp.deployBlueprintModalPopup(rowData);">
+ <i class="icon-arrows-download ecd-icon-action"></i><a
+ href="">Deploy</a>
+ </div>
+ </li>
+ <li>
+ <div
+ ng-show="rowData.canDeploy && (rowData.deployments == undefined || rowData.deployments.totalCount === 0)"
+ ng-click="ecdapp.deleteBlueprintModalPopup(rowData);">
+ <i class="icon-misc-trash ecd-icon-action"></i><a
+ href="">Delete</a>
+ </div>
+ </li>
+ </ul>
+ </div>
+ <!-- .btn-group -->
+ </td>
+ <td b2b-table-body ng-bind="rowData.component" />
+ <td b2b-table-body ng-bind="rowData.owner" />
+ <td b2b-table-body ng-bind="rowData.typeId" />
+ </tr>
+ <tr ng-show="rowData.expanded">
+ <td colspan="6" class="b2b-td-noTopBorder"
+ headers="expandTable_t1_{{$index}}">
+ <p class="offscreen-text">Expanded Row details for
+ {{rowData.deployments}}</p>
+ <ul>
+ <li class="mar-top-30"
+ ng-repeat="srvcData in rowData.deployments.items">
+ <div>
+ <span class="font-medium">{{$index+1}}</span>
+ </div>
+ <div class="b2b-leading-dots" ng-show="srvcData.tenant_name.length > 0">
+ <span class="font-medium">Deployment ID</span>
+ <span class="pull-right">
+ <a href="ecd#/idep/tenant:{{srvcData.tenant_name}};serviceRef:{{srvcData.id}}">
+ {{srvcData.id}}
+ </a>
+ </span>
+ </div>
+ <div class="b2b-leading-dots" ng-show="srvcData.tenant_name.length == 0">
+ <span class="font-medium">Deployment ID</span> <span
+ class="pull-right" ng-bind="srvcData.id" />
+ </div>
+ <div class="b2b-leading-dots" ng-show="srvcData.tenant_name.length > 0">
+ <span class="font-medium">Cloudify Tenant</span> <span
+ class="pull-right" ng-bind="srvcData.tenant_name" />
+ </div>
+ <div class="b2b-leading-dots">
+ <span class="font-medium">Created timestamp</span> <span
+ class="pull-right"
+ ng-bind="srvcData.created_at | date : 'MM-dd-yyyy HH:mm:ss Z'" " />
+ </div>
+ <div class="b2b-leading-dots">
+ <span class="font-medium">Modified timestamp</span>
+ <span class="pull-right"
+ ng-bind="srvcData.updated_at | date : 'MM-dd-yyyy HH:mm:ss Z'" " />
+ </div>
+ </li>
+ <br>
+ </ul>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ <div b2b-pagination="" total-pages="ecdapp.totalPages"
+ current-page="ecdapp.currentPage"
+ click-handler="pageChangeHandler" role="navigation"></div>
+ <div style="height: 10px;">
+ <!-- space between page number and black footer -->
+ </div>
+ </div>
+ <!-- loading -->
+</div>
+<div style="height: 10px;">
+ <!-- space between page number and black footer -->
+</div>
+<!-- page content -->
diff --git a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/inventory/inventory_deployment_popups.html b/ccsdk-app-overlay/src/main/webapp/app/ccsdk/inventory/inventory_deployment_popups.html
index e9bf3ea..41c3115 100644
--- a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/inventory/inventory_deployment_popups.html
+++ b/ccsdk-app-overlay/src/main/webapp/app/ccsdk/inventory/inventory_deployment_popups.html
@@ -1,657 +1,737 @@
<script type="text/ng-template" id="inventory_deployment_execute_popup.html">
-
- <style>
- .ecd-parameter-table
- {
- border: 0px;
- overflow: auto;
- }
- .ecd-parameter-table th
- {
- font-size: 1.4rem;
- }
- </style>
-
- <div class="b2b-modal-header ng-scope">
- <h2 id="myModalLabel" modal-title="">{{ecdapp.label}}</h2>
- <div class="corner-button in">
- <button type="button" class="close" aria-label="Close"
- ng-click="$dismiss('cancel')"></button>
- </div>
- </div>
-
- <div class="b2b-modal-body ng-scope ng-isolate-scope" tabindex="0"
- role="region" aria-label="Modal body content">
-
- <div class="row-nowrap">
- <div class="span12">
- <div class="form-row">
- <label for="blueprintId">Deployment ID</label>
- <div class="field-group">
- <!--autofocus is HTML5 attribute; doesn't work in Firefox-->
- <input id="blueprintId" class="span12" type="text" data-ng-model="ecdapp.editRequest.deployment_id" autofocus/>
- </div>
- </div>
- </div>
- <div class="span12">
- <div class="form-row">
- <label for="allowCustom">&nbsp;</label>
- <div class="field-group">
- <label for="allowCustomParameters" class="checkbox">
- <input id="allowCustomParameters" type="checkbox" ng-model="ecdapp.editRequest.allow_custom_parameter" />
- <i class="skin"></i><span>Allow Custom Parameters</span>
- </label>
- </div>
- </div>
- </div>
- </div>
-
- <div class="row-nowrap">
- <div class="span12">
- <div class="form-row">
- <label for="workflowName">Workflow Name</label>
- <div class="field-group">
- <select b2b-dropdown id="workflowName" name="workflowName" ng-model="ecdapp.editRequest.workflow_name.value" ng-change="selectWorkflowName()">
- <option b2b-dropdown-list option-repeat="w in ecdapp.editRequest.workflow_list" value="{{w}}">
- {{w}}
- </option>
- </select>
- </div>
- </div>
- </div>
- <div class="span12">
- <div class="form-row">
- <label for="force">&nbsp;</label>
- <div class="field-group">
- <label for="force" class="checkbox">
- <input id="force" type="checkbox" ng-model="ecdapp.editRequest.force" />
- <i class="skin"></i><span>Force</span>
- </label>
- </div>
- </div>
- </div>
- </div>
-
- <div class="row-nowrap">
- <div class="span12">
- <div class="form-row">
- <label for="parameters">*Parameters</label>
- <div b2b-file-drop file-model="ecdapp.editRequest.fileModel" on-drop="handleFileSelect()" align="center">
- <span b2b-file-link file-model="ecdapp.editRequest.fileModel" on-file-select="handleFileSelect()" >
- Drag &amp; drop a parameters YAML file here, or click to browse.
- </span>
- </div>
- </div>
- <div class="ecd-parameter-table">
- <table id="parameters">
- <tr id="ecd-table-header">
- <th width="40%">Name</th>
- <th width="60%">Value</th>
- </tr>
- <tbody ng-repeat="(pkey, pval) in ecdapp.editRequest.parmFileDict">
- <tr id="tr-rowData">
- <td ng-bind="pkey"/>
- <td><input id="parameterValue" class="span12" type="text" data-ng-model="ecdapp.editRequest.parmFileDict[pkey]" autofocus/></td>
- </tr>
- </tbody>
- </table>
- </div>
- </div>
- </div>
-
- </div>
-
- <div class="b2b-modal-footer ng-scope ng-isolate-scope">
- <div class="cta-button-group in">
- <button class="btn btn-alt btn-small" type="button"
- ng-click="ecdapp.executeDeployment(ecdapp.editRequest);">
- Save
- </button>
- <button class="btn btn-small" type="button"
- ng-click="$dismiss('cancel')">
- Cancel
- </button>
- </div>
- </div>
-
+<style>
+.ecd-parameter-table {
+ border: 0px;
+ overflow: auto;
+}
+
+.ecd-parameter-table th {
+ font-size: 1.4rem;
+}
+</style>
+<div class="b2b-modal-header ng-scope">
+ <h2 id="myModalLabel" modal-title="">{{ecdapp.label}}</h2>
+ <div class="corner-button in">
+ <button type="button" class="close" aria-label="Close"
+ ng-click="$dismiss('cancel')"></button>
+ </div>
+</div>
+<div class="b2b-modal-body ng-scope ng-isolate-scope" tabindex="0"
+ role="region" aria-label="Modal body content">
+ <div class="row-nowrap">
+ <div class="span12">
+ <div class="form-row">
+ <label for="blueprintId">Deployment ID</label>
+ <div class="field-group">
+ <!--autofocus is HTML5 attribute; doesn't work in Firefox-->
+ <input id="blueprintId" class="span12" type="text"
+ data-ng-model="ecdapp.editRequest.deployment_id" autofocus />
+ </div>
+ </div>
+ </div>
+ <div class="span12">
+ <div class="form-row">
+ <label for="allowCustom">&nbsp;</label>
+ <div class="field-group">
+ <label for="allowCustomParameters" class="checkbox"> <input
+ id="allowCustomParameters" type="checkbox"
+ ng-model="ecdapp.editRequest.allow_custom_parameter" /> <i
+ class="skin"></i><span>Allow Custom Parameters</span>
+ </label>
+ </div>
+ </div>
+ </div>
+ </div>
+ <div class="row-nowrap">
+ <div class="span12">
+ <div class="form-row">
+ <label for="workflowName">Workflow Name</label>
+ <div class="field-group">
+ <select b2b-dropdown id="workflowName" name="workflowName"
+ ng-model="ecdapp.editRequest.workflow_name.value"
+ ng-change="selectWorkflowName()">
+ <option b2b-dropdown-list
+ option-repeat="w in ecdapp.editRequest.workflow_list"
+ value="{{w}}">{{w}}</option>
+ </select>
+ </div>
+ </div>
+ </div>
+ <div class="span12">
+ <div class="form-row">
+ <label for="force">&nbsp;</label>
+ <div class="field-group">
+ <label for="force" class="checkbox"> <input id="force"
+ type="checkbox" ng-model="ecdapp.editRequest.force" /> <i
+ class="skin"></i><span>Force</span>
+ </label>
+ </div>
+ </div>
+ </div>
+ </div>
+ <div class="row-nowrap">
+ <div class="span12">
+ <div class="form-row">
+ <label for="parameters">*Parameters</label>
+ <div b2b-file-drop file-model="ecdapp.editRequest.fileModel"
+ on-drop="handleFileSelect()" align="center">
+ <span b2b-file-link file-model="ecdapp.editRequest.fileModel"
+ on-file-select="handleFileSelect()"> Drag &amp; drop
+ a parameters YAML file here, or click to browse. </span>
+ </div>
+ </div>
+ <div class="ecd-parameter-table">
+ <table id="parameters">
+ <tr id="ecd-table-header">
+ <th width="40%">Name</th>
+ <th width="60%">Value</th>
+ </tr>
+ <tbody
+ ng-repeat="(pkey, pval) in ecdapp.editRequest.parmFileDict">
+ <tr id="tr-rowData">
+ <td ng-bind="pkey" />
+ <td><input id="parameterValue" class="span12"
+ type="text"
+ data-ng-model="ecdapp.editRequest.parmFileDict[pkey]"
+ autofocus /></td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ </div>
+ </div>
+</div>
+<div class="b2b-modal-footer ng-scope ng-isolate-scope">
+ <div class="cta-button-group in">
+ <button class="btn btn-alt btn-small" type="button"
+ ng-click="ecdapp.executeDeployment(ecdapp.editRequest);">
+ Save</button>
+ <button class="btn btn-small" type="button"
+ ng-click="$dismiss('cancel')">Cancel</button>
+ </div>
+</div>
</script>
-
-<script type="text/ng-template" id="inventory_deployment_delete_popup.html">
-
-
- <div class="b2b-modal-header ng-scope">
- <h2 id="myModalLabel" modal-title="">{{ecdapp.label}}</h2>
- <div class="corner-button in">
- <button type="button" class="close" aria-label="Close"
- ng-click="$dismiss('cancel')"></button>
- </div>
- </div>
-
- <div ng-hide="ecdapp.errMsg">
- <div class="row-nowrap" style="margin-bottom:10px; margin-left:10px;"">
- <div class="span6">
- <label for="tenant">Tenant</label>
- <!--not editable-->
- <input id="tenant" class="span12" type="text" disabled="disabled" data-ng-model="ecdapp.ui_tenant"/>
- </div>
- </div>
- </div>
-
- <div class="b2b-modal-body ng-scope ng-isolate-scope" tabindex="0"
- role="region" aria-label="Modal body content">
-
- <div class="span12">
- <div class="form-row">
- <div class="field-group">
- <label>
- Undeploy the deployment with ID '{{ecdapp.deploymentRef}}'?
- </label>
- </div>
- </div>
- </div>
- </div>
-
- <div class="b2b-modal-footer ng-scope ng-isolate-scope">
- <div class="cta-button-group in">
- <button class="btn btn-alt btn-small" type="button"
- ng-click="ecdapp.deleteDeploymentById(deployment);">
- Undeploy
- </button>
- <button class="btn btn-small" type="button"
- ng-click="$dismiss('cancel')">
- Cancel
- </button>
- </div>
- </div>
-
+<script type="text/ng-template"
+ id="inventory_deployment_delete_popup.html">
+<div class="b2b-modal-header ng-scope">
+ <h3 id="myModalLabel" modal-title="">
+ {{ecdapp.label}}
+ </h2>
+ <div class="corner-button in">
+ <button type="button" class="close" aria-label="Close"
+ ng-click="$dismiss('cancel')"></button>
+ </div>
+</div>
+<div ng-hide="ecdapp.errMsg">
+ <div class="row-nowrap"
+ style="margin-bottom: 10px; margin-left: 10px;"">
+ <div class="span6">
+ <label for="tenant">Tenant</label>
+ <!--not editable-->
+ <input id="tenant" class="span12" type="text" disabled="disabled"
+ data-ng-model="ecdapp.ui_tenant" />
+ </div>
+ </div>
+</div>
+<div class="b2b-modal-body ng-scope ng-isolate-scope" tabindex="0"
+ role="region" aria-label="Modal body content">
+ <div class="span12">
+ <div class="form-row">
+ <div class="field-group">
+ <label> Undeploy the deployment with ID
+ '{{ecdapp.deploymentRef}}'? </label>
+ </div>
+ </div>
+ </div>
+</div>
+<div class="b2b-modal-footer ng-scope ng-isolate-scope">
+ <div class="cta-button-group in">
+ <button class="btn btn-alt btn-small" type="button"
+ ng-disabled="ecdapp.isDisabled"
+ ng-click="ecdapp.deleteDeploymentById(deployment);">
+ Undeploy</button>
+ <button class="btn btn-small" type="button"
+ ng-click="$dismiss('cancel')">Cancel</button>
+ </div>
+</div>
</script>
-
-<script type="text/ng-template" id="inventory_deployment_inputs_view_popup.html">
-
- <style>
- .ecd-parameter-table
- {
- border: 1px;
- overflow: auto;
- }
- .ecd-parameter-table th
- {
- font-size: 1.4rem;
- }
- </style>
-
- <div class="b2b-modal-header ng-scope">
- <h2 id="myModalLabel" modal-title="">{{ecdapp.label}}</h2>
- <div class="corner-button in">
- <button type="button" class="close" aria-label="Close"
- ng-click="$dismiss('cancel')"></button>
- </div>
- </div>
-
- <div class="b2b-modal-body ng-scope ng-isolate-scope" tabindex="0"
- role="region" aria-label="Modal body content">
-
- <!-- show progress indicator -->
- <div ng-show="ecdapp.isDataLoading">
- <div class="span" style="margin-bottom:20px;">
- <i class="icon-spinner small" role="img" aria-label="Please wait while the content loads"></i>
- Please wait while the content loads.
- </div>
- </div>
-
- <div ng-show="ecdapp.errMsg">
- <span class="ecd-error-message">{{ecdapp.errMsg}}</span>
- </div>
-
- <div ng-hide="ecdapp.errMsg">
- <div class="row-nowrap" style="margin-bottom:10px;">
- <div class="span6">
- <label for="tenant">Tenant</label>
- <!--not editable-->
- <input id="tenant" class="span12" type="text" disabled="disabled" data-ng-model="ecdapp.ui_tenant"/>
- </div>
- </div>
- </div>
-
- <div ng-hide="ecdapp.errMsg">
- <div class="row-nowrap">
- <div class="span12">
- <label for="deploymentRef">Deployment Ref</label>
- <!--not editable-->
- <input id="deploymentRef" class="span12" type="text" disabled="disabled" data-ng-model="ecdapp.deploymentRef"/>
- </div>
- <div class="span12">
- <label for="serviceId">Service ID</label>
- <!--not editable-->
- <input id="serviceId" class="span12" type="text" disabled="disabled" data-ng-model="ecdapp.serviceId"/>
- </div>
- </div>
-
- <div class="row-nowrap">
- <div class="span12">
- <table id="parameters">
- <tr id="ecd-table-header">
- <th width="40%">Name</th>
- <th width="60%">Value</th>
- </tr>
- <tbody ng-repeat="(pkey, pval) in ecdapp.deployment.inputs">
- <tr id="tr-rowData">
- <td ng-bind="pkey"/>
- <td ng-bind="pval"/>
- </tr>
- </tbody>
- </table>
- </div>
- </div>
- </div>
- </div>
+<script type="text/ng-template"
+ id="inventory_deployment_inputs_view_popup.html">
+<style>
+.ecd-parameter-table {
+ border: 1px;
+ overflow: auto;
+}
+
+.ecd-parameter-table th {
+ font-size: 1.4rem;
+}
+</style>
+<div class="b2b-modal-header ng-scope">
+ <h2 id="myModalLabel" modal-title="">{{ecdapp.label}}</h2>
+ <div class="corner-button in">
+ <button type="button" class="close" aria-label="Close"
+ ng-click="$dismiss('cancel')"></button>
+ </div>
+</div>
+<div class="b2b-modal-body ng-scope ng-isolate-scope" tabindex="0"
+ role="region" aria-label="Modal body content">
+ <!-- show progress indicator -->
+ <div ng-show="ecdapp.isDataLoading">
+ <div class="span" style="margin-bottom: 20px;">
+ <i class="icon-spinner small" role="img"
+ aria-label="Please wait while the content loads"></i> Please
+ wait while the content loads.
+ </div>
+ </div>
+ <div ng-show="ecdapp.errMsg">
+ <span class="ecd-error-message">{{ecdapp.errMsg}}</span>
+ </div>
+ <div ng-hide="ecdapp.errMsg">
+ <div class="row-nowrap" style="margin-bottom: 10px;">
+ <div class="span6">
+ <label for="tenant">Tenant</label>
+ <!--not editable-->
+ <input id="tenant" class="span12" type="text"
+ disabled="disabled" data-ng-model="ecdapp.ui_tenant" />
+ </div>
+ </div>
+ </div>
+ <div ng-hide="ecdapp.errMsg">
+ <div class="row-nowrap">
+ <div class="span12">
+ <label for="deploymentRef">Deployment Ref</label>
+ <!--not editable-->
+ <input id="deploymentRef" class="span12" type="text"
+ disabled="disabled" data-ng-model="ecdapp.deploymentRef" />
+ </div>
+ <div class="span12">
+ <label for="serviceId">Service ID</label>
+ <!--not editable-->
+ <input id="serviceId" class="span12" type="text"
+ disabled="disabled" data-ng-model="ecdapp.serviceId" />
+ </div>
+ </div>
+ <div class="row-nowrap">
+ <div class="span12">
+ <table id="parameters">
+ <tr id="ecd-table-header">
+ <th width="30%">Name</th>
+ <th width="70%">Value</th>
+ </tr>
+ <tbody ng-repeat="(pkey, pval) in ecdapp.deployment.parmFileDict">
+ <tr id="tr-rowData">
+ <td>
+ <div style="font-weight: bold;">{{pkey}}</div>
+ <div style="margin-top: 10px; font-weight: lighter;">
+ {{ecdapp.deployment.descriptionDict[pkey]}}</div>
+ </td>
+ <td> <pre>{{pval}}</pre></td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ </div>
+ </div>
+</div>
</script>
-<script type="text/ng-template" id="inventory_deployment_update_popup.html">
-
- <div class="b2b-modal-header ng-scope">
- <h2 id="myModalLabel" modal-title="">{{ecdapp.label}}</h2>
- <div class="corner-button in">
- <button type="button" class="close" aria-label="Close"
- ng-click="$dismiss('cancel')"></button>
- </div>
- </div>
-
- <div class="b2b-modal-body ng-scope ng-isolate-scope" tabindex="0"
- role="region" aria-label="Modal body content">
-
- <div ng-show="ecdapp.errMsg">
- <span class="ecd-error-message">{{ecdapp.errMsg}}</span>
- </div>
-
- <div class="row-nowrap">
- <div class="span12">
- <label for="deploymentRef">Deployment Ref</label>
- <input id="deploymentRef" class="span12" type="text" disabled="disabled" data-ng-model="ecdapp.deploymentRef"/>
- </div>
- <div class="span12">
- <label for="tenantName">Tenant Name</label>
- <!--not editable-->
- <input id="tenantName" class="span12" type="text" disabled="disabled" data-ng-model="ecdapp.ui_tenant"/>
- </div>
- </div>
-
- <div ng-hide="ecdapp.isDataLoading" style="margin-top:20px;">
- <div
- b2b-table
- id="service-type-table"
- class="b2b-table-div"
- table-data="ecdapp.bp" >
- <table>
- <thead b2b-table-row type="header">
- <tr id="th-header-row">
- <th b2b-table-header>Blueprint Name</th>
- <th b2b-table-header>Blueprint Version</th>
- <th b2b-table-header>Type ID</th>
- <th b2b-table-header>Description</th>
- <th b2b-table-header sortable="false"><i class="icon-controls-gear ecd-icon-display"></i></th>
- </tr>
- </thead>
- <tbody b2b-table-row type="body" row-repeat="rowData in ecdapp.bp">
- <tr id="tr-rowData">
- <td b2b-table-body
- ng-bind="rowData.typeName"/>
- <td b2b-table-body
- ng-bind="rowData.typeVersion"/>
- <td b2b-table-body
- ng-bind="rowData.typeId"/>
- <td b2b-table-body
- ng-bind="rowData.blueprintDescription"/>
- <td b2b-table-body>
- <div class="form-row">
- <label for="bpCb{{index}}" class="checkbox">
- <input id="bpCb{{index}}" type="checkbox" ng-model="rowData.checked" ng-click="ecdapp.updateSelection(rowData.typeId)" />
- <i class="skin"></i>
- </label>
- </div>
- </td>
- </tr>
- </tbody>
- </table>
- </div>
- </div>
- <div ng-hide="ecdapp.isDataLoading" class="row-nowrap" style="margin-top:20px;">
- <div class="span12">
- <label for="typeID">Blueprint[Service Type] ID</label>
- <input id="typeID" class="span12" type="text" data-ng-model="ecdapp.typeId" title="ID of the blueprint to use for the update"/>
- </div>
- <div class="cta-button-group in">
- <button class="btn btn-alt btn-small" type="button"
- ng-click="ecdapp.getBlueprint()">
- Get Blueprint data
- </button>
- </div>
- </div>
-
- <!-- show progress indicator -->
- <div ng-show="ecdapp.isDataLoading">
- <div class="span" style="margin-bottom:20px;">
- <i class="icon-spinner small" role="img" aria-label="Please wait while the content loads"></i>
- Please wait while the content loads.
- </div>
- </div>
-
- <div ng-hide="ecdapp.isDataLoading" class="row-nowrap">
- <div class="span12">
- <div class="form-row">
- <label for="parameters">*Parameters</label>
- <div b2b-file-drop file-model="ecdapp.editRequest.fileModel" on-drop="handleFileSelect()" align="center">
- <span b2b-file-link file-model="ecdapp.editRequest.fileModel" on-file-select="handleFileSelect()" >
- Drag &amp; drop a parameters JSON file here, or click to browse.
- </span>
- </div>
- </div>
- <div class="ecd-parameter-table">
- <table id="parameters">
- <tr id="ecd-table-header">
- <th width="40%">Name</th>
- <th width="60%">Value</th>
- </tr>
- <tbody ng-repeat="(pkey, pval) in ecdapp.editRequest.parmFileDict">
- <tr id="tr-rowData">
- <td ng-bind="pkey"/>
- <td><input id="parameterValue" class="span12" type="text" data-ng-model="ecdapp.editRequest.parmFileDict[pkey]" autofocus/></td>
- </tr>
- </tbody>
- </table>
- </div>
- </div>
- </div>
- </div>
-
- <!-- show progress indicator -->
- <div ng-show="ecdapp.deploymentInProgress">
- <div class="span" style="margin-bottom:20px;">
- <i class="icon-spinner small" role="img" aria-label="Please wait while the content loads"></i>
- Please wait while the task completes.
- </div>
- </div>
-
- <div class="b2b-modal-footer ng-scope ng-isolate-scope">
- <div class="cta-button-group in" ng-hide="ecdapp.deploymentInProgress">
- <button class="btn btn-alt btn-small" type="button"
- ng-click="ecdapp.updateDeployment(ecdapp.editRequest)" ng-show="!ecdapp.isDataLoading && !ecdapp.errMsg">
- Update
- </button>
- <button class="btn btn-alt btn-small" type="button"
- ng-click="$dismiss('cancel');">
- Close
- </button>
- </div>
- </div>
-
+<script type="text/ng-template"
+ id="inventory_deployment_update_popup.html">
+<div class="b2b-modal-header ng-scope">
+ <h3 id="myModalLabel" modal-title="">{{ecdapp.label}}</h3>
+ <div class="corner-button in">
+ <button type="button" class="close" aria-label="Close"
+ ng-click="$dismiss('cancel')"></button>
+ </div>
+</div>
+<div class="b2b-modal-body ng-scope ng-isolate-scope" tabindex="0"
+ role="region" aria-label="Modal body content">
+ <div ng-show="ecdapp.errMsg">
+ <span class="ecd-error-message">{{ecdapp.errMsg}}</span>
+ </div>
+ <div ng-hide="ecdapp.isDataLoading" style="margin-top: -5px;">
+ <div class="field-group">
+ <label for="bp">Blueprint</label> <select
+ style="font-size: 1.2rem;" id="bp" name="appl" b2b-dropdown
+ class="span6" ng-model="ecdapp.typeId"
+ ng-change="ecdapp.getBlueprint()" required>
+ <option b2b-dropdown-list option-repeat="d in ecdapp.bp"
+ value="{{d.typeId}}">{{d.typeName}}
+ version#{{d.typeVersion}}</option>
+ </select>
+ </div>
+ </div>
+ <!-- show progress indicator -->
+ <div ng-show="ecdapp.isDataLoading">
+ <div class="span" style="margin-bottom: 20px;">
+ <i class="icon-spinner small" role="img"
+ aria-label="Please wait while the content loads"></i> Please
+ wait while the content loads.
+ </div>
+ </div>
+ <div ng-hide="ecdapp.isDataLoading" class="row-nowrap">
+ <div class="span12">
+ <div class="form-row">
+ <label for="parameters">*Inputs</label>
+ <div b2b-file-drop file-model="ecdapp.editRequest.fileModel"
+ on-drop="handleFileSelect()" align="center">
+ <span b2b-file-link file-model="ecdapp.editRequest.fileModel"
+ on-file-select="handleFileSelect()"> Drag &amp; drop
+ a parameters JSON file here, or click to browse. </span>
+ </div>
+ </div>
+ <div class="ecd-parameter-table">
+ <table id="parameters">
+ <tbody
+ ng-repeat="(pkey, pval) in ecdapp.editRequest.parmFileDict">
+ <tr id="tr-rowData">
+ <td
+ style="padding: 5px 0 2px 0; font-size: 1.2rem; width: 100%; border: none;"
+ ng-bind="pkey">
+ <div style="font-weight: bold;">{{pkey}}</div>
+ <div style="margin-top: 8px; font-weight: lighter;">{{ecdapp.editRequest.descriptionDict[pkey]}}</div>
+ </td>
+ </tr>
+ <tr id="tr-rowData">
+ <td
+ style="padding: 0 5px 5px; font-size: 1.2rem; width: 100%; border: none;">
+ <input id="parameterValue" class="span12" type="text"
+ data-ng-model="ecdapp.editRequest.parmFileDict[pkey]"
+ autofocus />
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ </div>
+ </div>
+ <div style="border-bottom: 1px solid black;">Actions</div>
+ <div style="margin-top: 10px;">
+ <label for="install_flow" class="btn-switch-label"
+ ng-class="{'b2b-disabled-label':allDisabled}"> <input
+ type="button" aria-pressed="{{ecdapp.install_flow.value}}"
+ id="refresh_switch" b2b-switches
+ ng-model="ecdapp.install_flow.value" ng-disabled="allDisabled"
+ aria-disabled="{{allDisabled}}"
+ aria-label="Auto-refresh is {{ecdapp.install_flow.value?'On':'Off'}}. {{allDisabled?'Disabled. Explanation why it is disabled':''}}">
+ <label style="margin-left: 10px;" aria-hidden="true">Run
+ install workflow</label> <span class="tooltip" b2b-tooltip> <a
+ href="#" class="icon-tooltip tooltip-element" tabindex="0"
+ role="button" data-placement="top" aria-label="Help"
+ aria-describedby="tooltiptextRadio"> <span class="arrow"></span>
+ </a> <span class="tooltip-wrapper"> <span
+ class="tooltip-size-control"> <span
+ id="tooltiptextRadio" role="tooltip" aria-live="polite"
+ aria-hidden="true" class="helpertext" tabindex="-1">
+ <span class="popover-title">Run install lifecycle
+ operations</span> <span class="popover-content"> </span>
+ </span>
+ </span>
+ </span>
+ </span>
+ </label>
+ </div>
+ <div style="margin-top: 10px;">
+ <label for="uninstall_flow" class="btn-switch-label"
+ ng-class="{'b2b-disabled-label':allDisabled}"> <input
+ type="button" aria-pressed="{{ecdapp.uninstall_flow.value}}"
+ id="refresh_switch" b2b-switches
+ ng-model="ecdapp.uninstall_flow.value" ng-disabled="allDisabled"
+ aria-disabled="{{allDisabled}}"
+ aria-label="Auto-refresh is {{ecdapp.uninstall_flow.value?'On':'Off'}}. {{allDisabled?'Disabled. Explanation why it is disabled':''}}">
+ <label style="margin-left: 10px;" aria-hidden="true">Run
+ uninstall workflow</label> <span class="tooltip" b2b-tooltip> <a
+ href="#" class="icon-tooltip tooltip-element" tabindex="0"
+ role="button" data-placement="top" aria-label="Help"
+ aria-describedby="tooltiptextRadio"> <span class="arrow"></span>
+ </a> <span class="tooltip-wrapper"> <span
+ class="tooltip-size-control"> <span
+ id="tooltiptextRadio" role="tooltip" aria-live="polite"
+ aria-hidden="true" class="helpertext" tabindex="-1">
+ <span class="popover-title">Run uninstall lifecycle
+ operations</span> <span class="popover-content"> </span>
+ </span>
+ </span>
+ </span>
+ </span>
+ </label>
+ </div>
+ <div style="margin-top: 10px;">
+ <label for="install_first_flow" class="btn-switch-label"
+ ng-class="{'b2b-disabled-label':allDisabled}"> <input
+ type="button"
+ aria-pressed="{{ecdapp.install_first_flow_flag.value}}"
+ id="refresh_switch" b2b-switches
+ ng-model="ecdapp.install_first_flow_flag.value"
+ ng-disabled="allDisabled" aria-disabled="{{allDisabled}}"
+ aria-label="Auto-refresh is {{ecdapp.install_first_flow_flag.value?'On':'Off'}}. {{allDisabled?'Disabled. Explanation why it is disabled':''}}">
+ <label style="margin-left: 10px;" aria-hidden="true">Run
+ install workflow first</label> <span class="tooltip" b2b-tooltip>
+ <a href="#" class="icon-tooltip tooltip-element" tabindex="0"
+ role="button" data-placement="top" aria-label="Help"
+ aria-describedby="tooltiptextRadio"> <span class="arrow"></span>
+ </a> <span class="tooltip-wrapper"> <span
+ class="tooltip-size-control"> <span
+ id="tooltiptextRadio" role="tooltip" aria-live="polite"
+ aria-hidden="true" class="helpertext" tabindex="-1">
+ <span class="popover-title">Run install workflow
+ first, then uninstall workflow. Default: first uninstall
+ then install workflow.</span> <span class="popover-content">
+ </span>
+ </span>
+ </span>
+ </span>
+ </span>
+ </label>
+ </div>
+ <div style="margin-top: 10px;">
+ <label for="reinstall_flow" class="btn-switch-label"
+ ng-class="{'b2b-disabled-label':allDisabled}"> <input
+ type="button" aria-pressed="{{ecdapp.reinstall_flow.value}}"
+ id="refresh_switch" b2b-switches
+ ng-model="ecdapp.reinstall_flow.value" ng-disabled="allDisabled"
+ aria-disabled="{{allDisabled}}"
+ aria-label="Auto-refresh is {{ecdapp.reinstall_flow.value?'On':'Off'}}. {{allDisabled?'Disabled. Explanation why it is disabled':''}}">
+ <label style="margin-left: 10px;" aria-hidden="true">Run
+ automatic reinstall</label> <span class="tooltip" b2b-tooltip> <a
+ href="#" class="icon-tooltip tooltip-element" tabindex="0"
+ role="button" data-placement="top" aria-label="Help"
+ aria-describedby="tooltiptextRadio"> <span class="arrow"></span>
+ </a> <span class="tooltip-wrapper"> <span
+ class="tooltip-size-control"> <span
+ id="tooltiptextRadio" role="tooltip" aria-live="polite"
+ aria-hidden="true" class="helpertext" tabindex="-1">
+ <span class="popover-title">Automatically reinstall
+ node instances whose properties have been modified as
+ part of deployment update. If not set then, node
+ instances that were explicitly given to "Reinstall node
+ instances list" will be reinstalled.</span> <span
+ class="popover-content"> </span>
+ </span>
+ </span>
+ </span>
+ </span>
+ </label>
+ </div>
+ <div style="margin-top: 10px;">
+ <div class="field-group">
+ <div class="group">
+ <label class="col-sm-3 control-label">Reinstall node
+ instances list </label> <span class="tooltip" b2b-tooltip> <a
+ href="#" class="icon-tooltip tooltip-element" tabindex="0"
+ role="button" data-placement="top" aria-label="Help"
+ aria-describedby="tooltiptextRadio"> <span class="arrow"></span>
+ </a> <span class="tooltip-wrapper"> <span
+ class="tooltip-size-control"> <span
+ id="tooltiptextRadio" role="tooltip" aria-live="polite"
+ aria-hidden="true" class="helpertext" tabindex="-1">
+ <span class="popover-title">Node instances to be
+ installed as part of the deployment update. They will
+ be reinstalled even if "Run automatic reinstall" is
+ not set</span> <span class="popover-content"> </span>
+ </span>
+ </span>
+ </span>
+ </span>
+ <ui-select multiple ng-model="ecdapp.selectedNodeInst"
+ theme="bootstrap" close-on-select="false"
+ title="node instance"> <ui-select-match
+ class="ui-select-match">{{$item}}</ui-select-match> <ui-select-choices
+ class="ui-select-choices"
+ repeat="nodeInst in ecdapp.nodeInst | filter:$select.search"
+ position='down'> {{nodeInst}} </ui-select-choices> </ui-select>
+ </div>
+ </div>
+ <div style="margin-top: 10px;">
+ <label for="force" class="btn-switch-label"
+ ng-class="{'b2b-disabled-label':allDisabled}"> <input
+ type="button" aria-pressed="{{ecdapp.force_flag.value}}"
+ id="refresh_switch" b2b-switches
+ ng-model="ecdapp.force_flag.value" ng-disabled="allDisabled"
+ aria-disabled="{{allDisabled}}"
+ aria-label="Auto-refresh is {{ecdapp.force_flag.value?'On':'Off'}}. {{allDisabled?'Disabled. Explanation why it is disabled':''}}">
+ <label style="margin-left: 10px;" aria-hidden="true">Force
+ update</label> <span class="tooltip" b2b-tooltip> <a href="#"
+ class="icon-tooltip tooltip-element" tabindex="0"
+ role="button" data-placement="top" aria-label="Help"
+ aria-describedby="tooltiptextRadio"> <span class="arrow"></span>
+ </a> <span class="tooltip-wrapper"> <span
+ class="tooltip-size-control"> <span
+ id="tooltiptextRadio" role="tooltip" aria-live="polite"
+ aria-hidden="true" class="helpertext" tabindex="-1">
+ <span class="popover-title">Force running update
+ in case a previous update on this deployment has
+ failed to finish successfully</span> <span
+ class="popover-content"> </span>
+ </span>
+ </span>
+ </span>
+ </span>
+ </label>
+ </div>
+ </div>
+ <!-- show progress indicator -->
+ <div ng-show="ecdapp.deploymentInProgress">
+ <div class="span" style="margin-bottom: 20px;">
+ <i class="icon-spinner small" role="img"
+ aria-label="Please wait while the content loads"></i> Please
+ wait while the task completes.
+ </div>
+ </div>
+ <div class="b2b-modal-footer ng-scope ng-isolate-scope">
+ <div class="cta-button-group in"
+ ng-hide="ecdapp.deploymentInProgress">
+ <button class="btn btn-alt btn-small" type="button"
+ ng-click="ecdapp.updateDeployment(ecdapp.editRequest)"
+ ng-show="!ecdapp.isDataLoading && !ecdapp.errMsg">
+ Update</button>
+ <button class="btn btn-alt btn-small" type="button"
+ ng-click="$dismiss('cancel');">Close</button>
+ </div>
+ </div>
</script>
<script type="text/ng-template" id="blueprint_data_view_popup.html">
-
- <div class="b2b-modal-header ng-scope">
- <h2 id="myModalLabel" modal-title="">{{ecdapp.label}}</h2>
- <div class="corner-button in">
- <button type="button" class="close" aria-label="Close"
- ng-click="$dismiss('cancel')"></button>
- </div>
- </div>
-
- <div class="b2b-modal-body ng-scope ng-isolate-scope" tabindex="0"
- role="region" aria-label="Modal body content">
-
- <!-- show progress indicator -->
- <div ng-show="ecdapp.isDataLoading">
- <div class="span" style="margin-bottom:20px;">
- <i class="icon-spinner small" role="img" aria-label="Please wait while the content loads"></i>
- Please wait while the content loads.
- </div>
- </div>
-
- <div ng-show="ecdapp.errMsg">
- <span class="ecd-error-message">{{ecdapp.errMsg}}</span>
- </div>
-
- <div class="row-nowrap">
- <div class="span12">
- <label for="typeName">Blueprint Name</label>
- <!--not editable-->
- <input id="typeName" class="span12" type="text" disabled="disabled" data-ng-model="ecdapp.typeName"/>
- </div>
- </div>
- <div ng-hide="ecdapp.errMsg">
- <pre>{{ecdapp.blueprint}}</pre>
- </div>
-
- </div>
-
- <div class="b2b-modal-footer ng-scope ng-isolate-scope">
- <div class="cta-button-group in">
- <button class="btn btn-alt btn-small" type="button"
- ng-click="$dismiss('cancel');">
- Close
- </button>
- </div>
- </div>
-
-</script>
-
-<script type="text/ng-template" id="inventory_deployment_rollback_popup.html">
-
- <div class="b2b-modal-header ng-scope">
- <h2 id="myModalLabel" modal-title="">{{ecdapp.label}}</h2>
- <div class="corner-button in">
- <button type="button" class="close" aria-label="Close"
- ng-click="$dismiss('cancel')"></button>
- </div>
- </div>
-
- <div class="b2b-modal-body ng-scope ng-isolate-scope" tabindex="0"
- role="region" aria-label="Modal body content">
-
- <!-- show progress indicator -->
- <div ng-show="ecdapp.isDataLoading">
- <div class="span" style="margin-bottom:20px;">
- <i class="icon-spinner small" role="img" aria-label="Please wait while the content loads"></i>
- Please wait while the content loads.
- </div>
- </div>
-
- <div ng-show="ecdapp.errMsg">
- <span class="ecd-error-message">{{ecdapp.errMsg}}</span>
- </div>
-
- <div ng-hide="ecdapp.errMsg">
- <div class="row-nowrap">
- <div class="span12">
- <label for="deploymentRef">Deployment Ref</label>
- <!--not editable-->
- <input id="deploymentRef" class="span12" type="text" disabled="disabled" data-ng-model="ecdapp.deploymentRef"/>
- </div>
- <div class="span12">
- <label for="serviceId">Service ID</label>
- <!--not editable-->
- <input id="serviceId" class="span12" type="text" disabled="disabled" data-ng-model="ecdapp.serviceId"/>
- </div>
- <div class="span12">
- <label for="tenantName">Tenant Name</label>
- <!--not editable-->
- <input id="tenantName" class="span12" type="text" disabled="disabled" data-ng-model="ecdapp.ui_tenant"/>
- </div>
- </div>
-
- <div ng-hide="ecdapp.isDataLoading">
- <div
- b2b-table
- id="revisions-table"
- class="b2b-table-div"
- table-data="ecdapp.local_revisions" >
- <table>
- <thead b2b-table-row type="header">
- <tr id="th-header-row">
- <th b2b-table-header>Revision</th>
- <th b2b-table-header>Updated</th>
- <th b2b-table-header>Status</th>
- <th b2b-table-header>Chart</th>
- <th b2b-table-header>Description</th>
- <th b2b-table-header sortable="false"><i class="icon-controls-gear ecd-icon-display"></i></th>
- </tr>
- </thead>
-
- <tbody b2b-table-row type="body" row-repeat="rowData in ecdapp.local_revisions">
- <tr id="tr-rowData">
- <td b2b-table-body
- ng-bind="rowData.revision"/>
- <td b2b-table-body
- ng-bind="rowData.updated"/>
- <td b2b-table-body
- ng-bind="rowData.status"/>
- <td b2b-table-body
- ng-bind="rowData.chart"/>
- <td b2b-table-body
- ng-bind="rowData.description"/>
- <td ng-if="!$last" b2b-table-body>
- <div class="form-row">
- <label class="checkbox">
- <input type="checkbox" ng-model="rowData.checked" ng-click="ecdapp.updateSelection(rowData.revision)" />
- <i class="skin"></i>
- </label>
- </div>
- </td>
- </tr>
- </tbody>
- </table>
- </div>
- </div>
- </div>
-
- <div class="b2b-modal-footer ng-scope ng-isolate-scope">
- <div class="cta-button-group in">
- <button class="btn btn-alt btn-small" type="button"
- ng-click="ecdapp.rollbackWorkflow(ecdapp.revision);" ng-show="!ecdapp.isDataLoading && !ecdapp.errMsg">
- Start Rollback
- </button>
- <button class="btn btn-alt btn-small" type="button"
- ng-click="$dismiss('cancel');">
- Close
- </button>
- </div>
- </div>
-
+ <div class="b2b-modal-header ng-scope">
+ <h2 id="myModalLabel" modal-title="">{{ecdapp.label}}</h2>
+ <div class="corner-button in">
+ <button type="button" class="close" aria-label="Close"
+ ng-click="$dismiss('cancel')"></button>
+ </div>
+ </div>
+ <div class="b2b-modal-body ng-scope ng-isolate-scope" tabindex="0"
+ role="region" aria-label="Modal body content">
+ <!-- show progress indicator -->
+ <div ng-show="ecdapp.isDataLoading">
+ <div class="span" style="margin-bottom: 20px;">
+ <i class="icon-spinner small" role="img"
+ aria-label="Please wait while the content loads"></i> Please
+ wait while the content loads.
+ </div>
+ </div>
+ <div ng-show="ecdapp.errMsg">
+ <span class="ecd-error-message">{{ecdapp.errMsg}}</span>
+ </div>
+ <div class="row-nowrap">
+ <div class="span12">
+ <label for="typeName">Blueprint Name</label>
+ <!--not editable-->
+ <input id="typeName" class="span12" type="text"
+ disabled="disabled" data-ng-model="ecdapp.typeName" />
+ </div>
+ </div>
+ <div ng-hide="ecdapp.errMsg">
+ <pre>{{ecdapp.blueprint}}</pre>
+ </div>
+ </div>
+ <div class="b2b-modal-footer ng-scope ng-isolate-scope">
+ <div class="cta-button-group in">
+ <button class="btn btn-alt btn-small" type="button"
+ ng-click="$dismiss('cancel');">Close</button>
+ </div>
+ </div>
</script>
-
-<script type="text/ng-template" id="inventory_deployment_upgrade_popup.html">
-
- <style>
- .ecd-parameter-table
- {
- border: 1px;
- overflow: auto;
- }
- .ecd-parameter-table th
- {
- font-size: 1.4rem;
- }
- </style>
-
- <div class="b2b-modal-header ng-scope">
- <h2 id="myModalLabel" modal-title="">{{ecdapp.label}}</h2>
- <div class="corner-button in">
- <button type="button" class="close" aria-label="Close"
- ng-click="$dismiss('cancel')"></button>
- </div>
- </div>
-
- <div class="b2b-modal-body ng-scope ng-isolate-scope" tabindex="0"
- role="region" aria-label="Modal body content">
-
- <!-- show progress indicator -->
- <div ng-show="ecdapp.isDataLoading">
- <div class="span" style="margin-bottom:20px;">
- <i class="icon-spinner small" role="img" aria-label="Please wait while the content loads"></i>
- Please wait while the content loads.
- </div>
- </div>
-
- <div ng-show="ecdapp.errMsg">
- <span class="ecd-error-message">{{ecdapp.errMsg}}</span>
- </div>
-
- <div ng-hide="ecdapp.errMsg">
- <div class="row-nowrap">
- <div class="span12">
- <label for="deploymentRef">Deployment Ref</label>
- <!--not editable-->
- <input id="deploymentRef" class="span12" type="text" disabled="disabled" data-ng-model="ecdapp.deploymentRef"/>
- </div>
- <div class="span12">
- <label for="serviceId">Service ID</label>
- <!--not editable-->
- <input id="serviceId" class="span12" type="text" disabled="disabled" data-ng-model="ecdapp.serviceId"/>
- </div>
- <div class="span12">
- <label for="tenantName">Tenant Name</label>
- <!--not editable-->
- <input id="tenantName" class="span12" type="text" disabled="disabled" data-ng-model="ecdapp.ui_tenant"/>
- </div>
- </div>
-
- <div class="row-nowrap">
- <div class="span12">
- <div class="form-row">
- <label for="parameters">*Parameters</label>
- <div b2b-file-drop file-model="ecdapp.editRequest.fileModel" on-drop="handleFileSelect()" align="center">
- <span b2b-file-link file-model="ecdapp.editRequest.fileModel" on-file-select="handleFileSelect()" >
- Drag &amp; drop a parameters JSON file here, or click to browse.
- </span>
- </div>
- </div>
- <div class="ecd-parameter-table">
- <table id="parameters">
- <tr id="ecd-table-header">
- <th width="40%">Name</th>
- <th width="60%">Value</th>
- </tr>
- <tbody ng-repeat="(pkey, pval) in ecdapp.editRequest.resourceDefinitionChanges">
- <tr id="tr-rowData">
- <td ng-bind="pkey"/>
- <td>
- <input id="parameterValue" class="span12" type="text"
- data-ng-model="ecdapp.editRequest.resourceDefinitionChanges[pkey]" autofocus/>
- </td>
- </tr>
- </tbody>
- <tbody ng-repeat="(pkey, pval) in ecdapp.editRequest.resourceConstants">
- <tr id="tr-rowData">
- <td ng-bind="pkey"/>
- <td ng-bind="pval"/>
- </tr>
- </tbody>
- </table>
- </div>
- </div>
- </div>
- </div>
- </div>
-
- <!-- show progress indicator -->
- <div style="width: 100%;">
- <div ng-show="ecdapp.updatingDeployment" style="display: table; margin: 0 auto;" class="span">
- <i class="icon-spinner small" role="img" aria-label="Update Deployment in Progress..."></i>
- Update Deployment in Progress...
- </div>
- </div>
-
- <div class="b2b-modal-footer ng-scope ng-isolate-scope" ng-show="!ecdapp.updatingDeployment">
- <div class="cta-button-group in">
- <!--<div ng-show="!ecdapp.isDataLoading">-->
- <button class="btn btn-alt btn-small" type="button"
- ng-click="ecdapp.upgradeWorkflow(ecdapp.editRequest.resourceDefinitionChanges);" ng-show="!ecdapp.isDataLoading && !ecdapp.errMsg">
- Start Upgrade
- </button>
- <!--</div>-->
- <button class="btn btn-small" type="button"
- ng-click="$dismiss('cancel')">
- Cancel
- </button>
- </div>
- </div>
+<script type="text/ng-template"
+ id="inventory_deployment_rollback_popup.html">
+ <div class="b2b-modal-header ng-scope">
+ <h2 id="myModalLabel" modal-title="">{{ecdapp.label}}</h2>
+ <div class="corner-button in">
+ <button type="button" class="close" aria-label="Close"
+ ng-click="$dismiss('cancel')"></button>
+ </div>
+ </div>
+ <div class="b2b-modal-body ng-scope ng-isolate-scope" tabindex="0"
+ role="region" aria-label="Modal body content">
+ <!-- show progress indicator -->
+ <div ng-show="ecdapp.isDataLoading">
+ <div class="span" style="margin-bottom: 20px;">
+ <i class="icon-spinner small" role="img"
+ aria-label="Please wait while the content loads"></i> Please
+ wait while the content loads.
+ </div>
+ </div>
+ <div ng-show="ecdapp.errMsg">
+ <span class="ecd-error-message">{{ecdapp.errMsg}}</span>
+ </div>
+ <div ng-hide="ecdapp.errMsg">
+ <div class="row-nowrap">
+ <div class="span12">
+ <label for="deploymentRef">Deployment Ref</label>
+ <!--not editable-->
+ <input id="deploymentRef" class="span12" type="text"
+ disabled="disabled" data-ng-model="ecdapp.deploymentRef" />
+ </div>
+ <div class="span12">
+ <label for="serviceId">Service ID</label>
+ <!--not editable-->
+ <input id="serviceId" class="span12" type="text"
+ disabled="disabled" data-ng-model="ecdapp.serviceId" />
+ </div>
+ <div class="span12">
+ <label for="tenantName">Tenant Name</label>
+ <!--not editable-->
+ <input id="tenantName" class="span12" type="text"
+ disabled="disabled" data-ng-model="ecdapp.ui_tenant" />
+ </div>
+ </div>
+ <div ng-hide="ecdapp.isDataLoading">
+ <div b2b-table id="revisions-table" class="b2b-table-div"
+ table-data="ecdapp.local_revisions">
+ <table>
+ <thead b2b-table-row type="header">
+ <tr id="th-header-row">
+ <th b2b-table-header>Revision</th>
+ <th b2b-table-header>Updated</th>
+ <th b2b-table-header>Status</th>
+ <th b2b-table-header>Chart</th>
+ <th b2b-table-header>Description</th>
+ <th b2b-table-header sortable="false"><i
+ class="icon-controls-gear ecd-icon-display"></i></th>
+ </tr>
+ </thead>
+ <tbody b2b-table-row type="body"
+ row-repeat="rowData in ecdapp.local_revisions">
+ <tr id="tr-rowData">
+ <td b2b-table-body ng-bind="rowData.revision" />
+ <td b2b-table-body ng-bind="rowData.updated" />
+ <td b2b-table-body ng-bind="rowData.status" />
+ <td b2b-table-body ng-bind="rowData.chart" />
+ <td b2b-table-body ng-bind="rowData.description" />
+ <td ng-if="!$last" b2b-table-body>
+ <div class="form-row">
+ <label class="checkbox"> <input
+ type="checkbox" ng-model="rowData.checked"
+ ng-click="ecdapp.updateSelection(rowData.revision)" />
+ <i class="skin"></i>
+ </label>
+ </div>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ </div>
+ </div>
+ <div class="b2b-modal-footer ng-scope ng-isolate-scope">
+ <div class="cta-button-group in">
+ <button class="btn btn-alt btn-small" type="button"
+ ng-click="ecdapp.rollbackWorkflow(ecdapp.revision);"
+ ng-show="!ecdapp.isDataLoading && !ecdapp.errMsg">
+ Start Rollback</button>
+ <button class="btn btn-alt btn-small" type="button"
+ ng-click="$dismiss('cancel');">Close</button>
+ </div>
+ </div>
</script>
+<script type="text/ng-template"
+ id="inventory_deployment_upgrade_popup.html">
+ <style>
+.ecd-parameter-table {
+ border: 1px;
+ overflow: auto;
+}
+
+.ecd-parameter-table th {
+ font-size: 1.4rem;
+}
+</style>
+ <div class="b2b-modal-header ng-scope">
+ <h2 id="myModalLabel" modal-title="">{{ecdapp.label}}</h2>
+ <div class="corner-button in">
+ <button type="button" class="close" aria-label="Close"
+ ng-click="$dismiss('cancel')"></button>
+ </div>
+ </div>
+ <div class="b2b-modal-body ng-scope ng-isolate-scope" tabindex="0"
+ role="region" aria-label="Modal body content">
+ <!-- show progress indicator -->
+ <div ng-show="ecdapp.isDataLoading">
+ <div class="span" style="margin-bottom: 20px;">
+ <i class="icon-spinner small" role="img"
+ aria-label="Please wait while the content loads"></i> Please
+ wait while the content loads.
+ </div>
+ </div>
+ <div ng-show="ecdapp.errMsg">
+ <span class="ecd-error-message">{{ecdapp.errMsg}}</span>
+ </div>
+ <div ng-hide="ecdapp.errMsg">
+ <div class="row-nowrap">
+ <div class="span12">
+ <label for="deploymentRef">Deployment Ref</label>
+ <!--not editable-->
+ <input id="deploymentRef" class="span12" type="text"
+ disabled="disabled" data-ng-model="ecdapp.deploymentRef" />
+ </div>
+ <div class="span12">
+ <label for="tenantName">Tenant Name</label>
+ <!--not editable-->
+ <input id="tenantName" class="span12" type="text"
+ disabled="disabled" data-ng-model="ecdapp.ui_tenant" />
+ </div>
+ </div>
+ <div class="row-nowrap">
+ <div class="span12">
+ <div class="form-row">
+ <label for="parameters">*Parameters</label>
+ <div b2b-file-drop
+ file-model="ecdapp.editRequest.fileModel"
+ on-drop="handleFileSelect()" align="center">
+ <span b2b-file-link
+ file-model="ecdapp.editRequest.fileModel"
+ on-file-select="handleFileSelect()"> Drag
+ &amp; drop a parameters JSON file here, or click to
+ browse. </span>
+ </div>
+ </div>
+ <div class="ecd-parameter-table">
+ <table id="parameters">
+ <tr id="ecd-table-header">
+ <th width="40%">Name</th>
+ <th width="60%">Value</th>
+ </tr>
+ <tbody
+ ng-repeat="(pkey, pval) in ecdapp.editRequest.resourceDefinitionChanges">
+ <tr id="tr-rowData">
+ <td ng-bind="pkey" />
+ <td><input id="parameterValue" class="span12"
+ type="text"
+ data-ng-model="ecdapp.editRequest.resourceDefinitionChanges[pkey]"
+ autofocus /></td>
+ </tr>
+ </tbody>
+ <tbody
+ ng-repeat="(pkey, pval) in ecdapp.editRequest.resourceConstants">
+ <tr id="tr-rowData">
+ <td ng-bind="pkey" />
+ <td ng-bind="pval" />
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ <!-- show progress indicator -->
+ <div style="width: 100%;">
+ <div ng-show="ecdapp.updatingDeployment"
+ style="display: table; margin: 0 auto;" class="span">
+ <i class="icon-spinner small" role="img"
+ aria-label="Update Deployment in Progress..."></i> Update
+ Deployment in Progress...
+ </div>
+ </div>
+ <div class="b2b-modal-footer ng-scope ng-isolate-scope"
+ ng-show="!ecdapp.updatingDeployment">
+ <div class="cta-button-group in">
+ <!--<div ng-show="!ecdapp.isDataLoading">-->
+ <button class="btn btn-alt btn-small" type="button"
+ ng-click="ecdapp.upgradeWorkflow(ecdapp.editRequest.resourceDefinitionChanges);"
+ ng-show="!ecdapp.isDataLoading && !ecdapp.errMsg">
+ Start Upgrade</button>
+ <!--</div>-->
+ <button class="btn btn-small" type="button"
+ ng-click="$dismiss('cancel')">Cancel</button>
+ </div>
+ </div>
+</script> \ No newline at end of file
diff --git a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/inventory/inventory_deployment_table.html b/ccsdk-app-overlay/src/main/webapp/app/ccsdk/inventory/inventory_deployment_table.html
deleted file mode 100644
index 66ab9b5..0000000
--- a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/inventory/inventory_deployment_table.html
+++ /dev/null
@@ -1,148 +0,0 @@
-<div id="page-content">
-
- <h1 class="heading-page" id="deployments-page">Deployments</h1>
-
- <!-- show progress indicator -->
- <div ng-show="ecdapp.isDataLoading">
- <div class="span" style="margin-bottom:20px;">
- <i class="icon-spinner small" role="img" aria-label="Please wait while the content loads"></i>
- Please wait while the content loads.
- </div>
- </div>
-
- <div ng-hide="ecdapp.isDataLoading">
- <div id="button-search-row">
- <div style="float:right;">
- <div class="group">
- <button tabindex="-1" class="btn btn-small" title="Reset Filters" type="button" ng-click="ecdapp.loadTable()"><i class="icon-arrows-replay-restart"></i></button>
- <input tabindex="0" class="btn btn-small" type="text" placeholder="Search Deployments" ng-model="ecdapp.searchBy"></input>
- <button tabindex="1" class="btn btn-small" type="button" ng-click="ecdapp.searchTable(ecdapp.searchBy)"><i class="ion-search"></i></button>
- </div>
- </div>
- </div>
-
- <div ng-show="ecdapp.isRequestFailed">
- <span class="ecd-error-message">{{ecdapp.errMsg}}</span>
- </div>
-
- <div ng-hide="ecdapp.isRequestFailed">
- <div
- b2b-table
- id="deployments-table"
- class="b2b-table-div"
- table-data="ecdapp.tableData"
- current-page="ecdapp.currentPageIgnored"
- next-sort="ecdapp.nextSortIgnored">
- <table>
- <thead b2b-table-row type="header">
- <tr id="th-header-row">
- <th b2b-table-header sortable="false" key="serviceId" ng-click="ecdapp.sortTable('serviceId')">Service ID/Deployment Ref.</th>
- <th b2b-table-header sortable="false" key="created" ng-click="ecdapp.sortTable('created')">Created</th>
- <th b2b-table-header sortable="false" key="updated" ng-click="ecdapp.sortTable('modified')">Modified</th>
- <th b2b-table-header sortable="false" key="tenant" style="background-color:#dbefef;">Tenant
- <button style="margin-bottom:-5px; box-shadow:0 0 0 0 rgba(0, 0, 0, 0.15); min-width:0;" tabindex="1" class="btn btn-small" title="Refresh Tenant and Status" type="button" ng-click="ecdapp.updateTable()">
- <i class="icon-arrows-replay-restart"></i>
- </button>
- <div ng-show="ecdapp.isSrvcDataLoading">
- <div class="span" style="margin-bottom:5px;">
- <i class="icon-spinner small" role="img" aria-label="Deployment Info is loading"></i>
- Tenant and Status Info loading
- </div>
- </div>
- </th>
- <th b2b-table-header sortable="false" key="status" style="background-color:#dbefef;">Install Status</th>
- <th b2b-table-header sortable="false" style="background-color:#dbefef;">Actions</th>
- </tr>
- </thead>
-
- <tbody b2b-table-row type="body" row-repeat="rowData in ecdapp.tableData">
- <tr id="tr-rowData">
- <td b2b-table-body
- ng-bind="rowData.serviceId"
- ng-class="{'td-error' : rowData.statusInfo === undefined}"/>
- <td b2b-table-body
- ng-bind="rowData.created | date : 'MM-dd-yyyy HH:mm:ss Z'"
- ng-class="{'td-error' : rowData.statusInfo === undefined}"/>
- <td b2b-table-body
- ng-bind="rowData.modified | date : 'MM-dd-yyyy HH:mm:ss Z'"
- ng-class="{'td-error' : rowData.statusInfo === undefined}"/>
- <td b2b-table-body
- ng-bind="rowData.statusInfo.tenant_name"
- ng-class="{'td-error' : rowData.statusInfo === undefined}"/>
- <td b2b-table-body
- ng-class="{'td-error' : rowData.statusInfo === undefined}">
- <img ng-src="{{rowData.statusInfo.statusImg}}" title="{{rowData.statusInfo.status}}" />
- </span>
- </td>
- <td b2b-table-body ng-class="{'td-error' : rowData.statusInfo === undefined}">
- <div class="btn-group btn-actions" style="margin-bottom:0;box-shadow:none;">
- <button type="button" class="btn dropdown-toggle" data-toggle="dropdown" title="More Actions"><i class="icon-apps-marketplace"></i></button>
- <ul class="dropdown-menu">
- <li>
- <div ng-click="ecdapp.viewBlueprintDataModal(rowData);">
- <i class="icon-documents-book ecd-icon-action"></i><a href="">View blueprint</a>
- </div>
- </li>
- <li>
- <div ng-click="ecdapp.viewDeploymentInputsModalPopup(rowData);">
- <i class="icoDocuments-report ecd-icon-action"></i><a href="">View Inputs</a>
- </div>
- </li>
- <li>
- <div ng-click="ecdapp.viewDeploymentExecutionsModalPopup(rowData);">
- <i class="icon-overview ecd-icon-action"></i><a href="">View executions</a>
- </div>
- </li>
- <li>
- <div ng-show="rowData.canDeploy && rowData.statusInfo.status === 'completed'" ng-click="ecdapp.updateDeploymentModalPopup(rowData);">
- <i class="icon-misc-pen ecd-icon-action"></i><a href="">Update deployment</a>
- </div>
- </li>
- <li>
- <div ng-show="rowData.canDeploy" ng-click="ecdapp.deleteDeploymentModalPopup(rowData);">
- <i class="icon-misc-trash ecd-icon-action"></i><a href="">Undeploy</a>
- </div>
- </li>
- <li>
- <div ng-show="rowData.statusInfo.is_helm && rowData.statusInfo.helm_status && rowData.statusInfo.status === 'completed'" ng-click="ecdapp.checkHelmStatus(rowData);">
- <i class="icoDocuments-report ecd-icon-action"></i><a href="">Helm Status</a>
- </div>
- </li>
- <li>
- <div ng-show="rowData.canDeploy && rowData.statusInfo.is_helm && rowData.statusInfo.status === 'completed'" ng-click="ecdapp.upgradeDeploymentModalPopup(rowData);">
- <i class="icon-controls-down ecd-icon-action"></i><a href="#">Helm upgrade deployment</a>
- </div>
- </li>
- <li>
- <div ng-show="rowData.canDeploy && rowData.statusInfo.is_helm && rowData.statusInfo.status === 'completed'" ng-click="ecdapp.rollbackDeploymentModalPopup(rowData);">
- <i class="icon-controls-up"></i><a href="#">Helm rollback deployment</a>
- </div>
- </li>
- <li>
- <div ng-show="rowData.canDeploy && rowData.statusInfo === undefined" ng-click="ecdapp.deleteServiceModalPopup(rowData);">
- <i class="icon-misc-trash ecd-icon-action"></i><a href="">Delete Service</a>
- </div>
- </li>
- </ul>
- </div><!-- .btn-group -->
- </td>
- </tr>
- </tbody>
- </table>
- </div>
-
- <div b2b-pagination="" total-pages="ecdapp.totalPages"
- current-page="ecdapp.currentPageNum" click-handler="pageChangeHandler"
- role="navigation">
- </div>
-
- </div>
- </div>
-
- <div style="height: 10px;">
- <!-- space between page number and black footer -->
- </div>
-
-</div><!-- loading -->
-
-</div><!-- page content -->
diff --git a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/inventory/inventory_execution_popups.html b/ccsdk-app-overlay/src/main/webapp/app/ccsdk/inventory/inventory_execution_popups.html
index 4b870dc..6277207 100644
--- a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/inventory/inventory_execution_popups.html
+++ b/ccsdk-app-overlay/src/main/webapp/app/ccsdk/inventory/inventory_execution_popups.html
@@ -1,255 +1,271 @@
<script type="text/ng-template" id="inventory_execution_view_popup.html">
- <div class="b2b-modal-header ng-scope">
- <h2 id="myModalLabel" style="margin-left: 200px;" modal-title="">{{ecdapp.label}}</h2>
- <div class="corner-button in">
- <button type="button" class="close" aria-label="Close"
- ng-click="$dismiss('cancel')"></button>
- </div>
- <div style="position: absolute;">
- <label for="show-menu" class="show-menu" title="click to view more info">&#9776;</label>
- <input type="checkbox" id="show-menu" />
- <div class="menu" ng-hide="ecdapp.errMsg">
- <!--<div class="row-nowrap" style="margin-bottom:10px;"> -->
- <div class="span12" style="margin-bottom:10px;">
- <label for="deploymentRef">Deployment Ref</label>
- <!--not editable-->
- <input id="deploymentRef" class="span6" type="text" data-ng-model="ecdapp.deplRef"/>
- </div>
- <div class="span12" style="margin-bottom:10px;">
- <label for="tenant">Tenant</label>
- <!--not editable-->
- <input id="tenant" class="span6" type="text" data-ng-model="ecdapp.ui_tenant"/>
- </div>
- <!-- <button ng-click="ecdapp.toggleStatusDefinitions()" class="btn btn-alt btn-small">Click to view status definitions</button> -->
- <div>
- <div b2b-table id="status-table" class="b2b-table-div">
- <table id="status-definition-table">
- <thead b2b-table-row type="header">
- <tr id="th-header-row">
- <th b2b-table-header key="status">Status</th>
- <th b2b-table-header key="definition">Definition</th>
- </tr>
- </thead>
- <tbody b2b-table-row type="body">
- <tr>
- <td>waiting to start</td>
- <td>The execution is waiting for a worker to start it</td>
- </tr>
- <tr>
- <td>in progress</td>
- <td>The execution is currently running.</td>
- </tr>
- <tr>
- <td>cancel in progress</td>
- <td>The execution is currently being cancelled.</td>
- </tr>
- <tr>
- <td>force-cancelling in progress</td>
- <td>The execution is currently being force-cancelled.</td>
- </tr>
- <tr>
- <td>cancelled</td>
- <td>The execution has been cancelled.</td>
- </tr>
- <tr>
- <td>successful</td>
- <td>The execution has terminated successfully.</td>
- </tr>
- <tr>
- <td>failed</td>
- <td>The execution has failed. Click on the button in the error column to view the error details.</td>
- </tr>
- </tbody>
- </table>
- </div>
- </div>
- </div>
- </div>
- </div>
-
- <div class="b2b-modal-body ng-scope ng-isolate-scope" tabindex="0"
- role="region" aria-label="Modal body content">
-
- <!--<h1 class="heading-page" id="executions-page">Executions</h1> -->
-
- <!-- show progress indicator -->
- <div ng-show="ecdapp.isDataLoading">
- <div class="span" style="margin-bottom:20px;">
- <i class="icon-spinner small" role="img" aria-label="Please wait while the content loads"></i>
- Please wait while the content loads.
- </div>
- </div>
- <div ng-show="ecdapp.isCancelOn">
- <div class="span" style="margin-bottom:20px;">
- <i class="icon-spinner small" role="img" aria-label="Cancel in progress"></i>
- Cancel in progress
- </div>
- </div>
- <div ng-show="ecdapp.errMsg">
- <span class="ecd-error-message">{{ecdapp.errMsg}}</span>
- </div>
- <div ng-show="ecdapp.evtErrMsg">
- <span class="ecd-error-message">{{ecdapp.evtErrMsg}}</span>
- </div>
-
- <div class="form-row" style="margin-top:0px;">
- <div style="float: left; width: 200px; margin-left: 30px;" title="switch to enable/disable screen refresh">
- <label for="refresh_switch" class="btn-switch-label" ng-class="{'b2b-disabled-label':allDisabled}">
- <span aria-hidden="true">Auto-refresh</span>
- <input type="button" aria-pressed="{{ecdapp.refresh_switch.value}}" id="refresh_switch" b2b-switches ng-model="ecdapp.refresh_switch.value" ng-disabled="allDisabled" aria-disabled="{{allDisabled}}" aria-label="Auto-refresh is {{ecdapp.refresh_switch.value?'On':'Off'}}. {{allDisabled?'Disabled. Explanation why it is disabled':''}}">
- </label>
- </div>
- <div style="float: right;" title="Checkbox to view latest execution workflow only">
- <label for="checkbox1" class="checkbox">
- <input id="checkbox1" type="checkbox" ng-model="ecdapp.isLastExecution"><i class="skin"></i><span>Last execution</span>
- </label>
- </div>
+<div class="b2b-modal-header ng-scope">
+ <h2 id="myModalLabel" modal-title="">
+ Deployment <span style="font-weight: bolder; background: aqua;">{{ecdapp.deplRef}}</span>
+ Executions
+ </h2>
+ <div class="corner-button in">
+ <button type="button" class="close" aria-label="Close"
+ ng-click="$dismiss('cancel')"></button>
+ </div>
+ <div style="position: absolute; right: 50px; top: 40px;">
+ <label for="show-menu" class="show-menu"
+ title="click to view more info">&#9776;</label> <input
+ type="checkbox" id="show-menu" />
+ <div class="menu" ng-hide="ecdapp.errMsg">
+ <div class="span12" style="margin-bottom: 10px;">
+ <label for="tenant">Tenant</label>
+ <!--not editable-->
+ <input id="tenant" class="span6" type="text"
+ data-ng-model="ecdapp.ui_tenant" />
+ </div>
+ <div>
+ <div b2b-table id="status-table" class="b2b-table-div">
+ <table id="status-definition-table">
+ <thead b2b-table-row type="header">
+ <tr id="th-header-row">
+ <th b2b-table-header key="status">Status</th>
+ <th b2b-table-header key="definition">Definition</th>
+ </tr>
+ </thead>
+ <tbody b2b-table-row type="body">
+ <tr>
+ <td>waiting to start</td>
+ <td>The execution is waiting for a worker to start
+ it</td>
+ </tr>
+ <tr>
+ <td>in progress</td>
+ <td>The execution is currently running.</td>
+ </tr>
+ <tr>
+ <td>cancel in progress</td>
+ <td>The execution is currently being cancelled.</td>
+ </tr>
+ <tr>
+ <td>force-cancelling in progress</td>
+ <td>The execution is currently being
+ force-cancelled.</td>
+ </tr>
+ <tr>
+ <td>cancelled</td>
+ <td>The execution has been cancelled.</td>
+ </tr>
+ <tr>
+ <td>successful</td>
+ <td>The execution has terminated successfully.</td>
+ </tr>
+ <tr>
+ <td>failed</td>
+ <td>The execution has failed. Click on the button
+ in the error column to view the error details.</td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ </div>
</div>
-
- <div ng-hide="ecdapp.errMsg">
- <div
- b2b-table
- id="executions-table"
- class="b2b-table-div"
- table-data="ecdapp.tableData"
- search-string="ecdapp.searchString"
- current-page="ecdapp.currentPageIgnored"
- next-sort="ecdapp.nextSortIgnored">
-
- <table>
- <thead b2b-table-row type="header">
- <tr id="th-header-row">
- <th b2b-table-header key="created_at">Created Date</th>
- <th b2b-table-header key="workflow_id">Workflow ID</th>
- <th b2b-table-header key="id">ID</th>
- <th b2b-table-header key="status">Status</th>
- <th b2b-table-header sortable="false"><i class="icon-settings ecd-icon-display"></i></th>
- </tr>
- </thead>
-
- <tbody b2b-table-row type="body" row-repeat="rowData in ecdapp.tableData">
- <tr id="tr-rowData">
- <td b2b-table-body
- ng-bind="rowData.created_at"/>
- <td b2b-table-body
- ng-bind="rowData.workflow_id"/>
- <td b2b-table-body
- ng-bind="rowData.id"/>
- <td b2b-table-body ng-if="rowData.status == 'pending'">
- waiting to start
- </td>
- <td b2b-table-body ng-if="rowData.status == 'started'">
- <div ng-click="ecdapp.getExecutionLogs(rowData.id, ecdapp.ui_tenant);">
- <a href="" title="View execution logs" class="tooltip">in progress</a>
- </div>
- </td>
- <td b2b-table-body ng-if="rowData.status == 'cancelling'">
- <div ng-click="ecdapp.getExecutionLogs(rowData.id, ecdapp.ui_tenant);">
- <a href="" title="View execution logs" class="tooltip">cancel in progress</a>
- </div>
- </td>
- <td b2b-table-body ng-if="rowData.status == 'force_cancelling'">
- <div ng-click="ecdapp.getExecutionLogs(rowData.id, ecdapp.ui_tenant);">
- <a href="" title="View execution logs" class="tooltip">force-cancelling in progress</a>
- </div>
- </td>
- <td b2b-table-body ng-if="rowData.status == 'cancelled'">
- <div ng-click="ecdapp.getExecutionLogs(rowData.id, ecdapp.ui_tenant);">
- <a href="" title="View execution logs" class="tooltip">cancelled</a>
- </div>
- </td>
- <td b2b-table-body ng-if="rowData.status == 'terminated'">
- <div ng-click="ecdapp.getExecutionLogs(rowData.id, ecdapp.ui_tenant);">
- <a href="" title="View execution logs" class="tooltip">successful</a>
- </div>
- </td>
- <td b2b-table-body ng-if="rowData.status == 'failed'">
- <div ng-click="ecdapp.getExecutionLogs(rowData.id, ecdapp.ui_tenant);">
- <a href="" title="View execution logs" class="tooltip">failed</a>
- </div>
- </td>
- <td b2b-table-body ng-if="rowData.status == 'failed'">
- <div ng-show="rowData.error" ng-click="ecdapp.viewErrorModalPopup(rowData);">
- <a href="" title="View error details" class="icon-people-preview ecd-icon-action"></a>
- </div>
- </td>
- <td b2b-table-body ng-if="rowData.status == 'started'">
- <div ng-click="ecdapp.cancelExecutionModalPopup(rowData, ecdapp.ui_tenant);">
- <a href="" title="Cancel execution" class="ion-stop ecd-icon-action"></a>
- </div>
- </td>
- </tr>
- </tbody>
- </table>
- </div>
- <!-- <div b2b-pagination="" total-pages="ecdapp.totalPages"
- current-page="ecdapp.currentPageNum" click-handler="pageChangeHandler"
- role="navigation">
- </div> -->
- </div>
- <div ng-show="ecdapp.isEventLogQuery">
- <div style="float: left;">
- <h3>Events/Logs </h3>
- <h4>execution id: {{ecdapp.executionId}} </h4>
- </div>
- <div style="float: right;" title="Checkbox to Include log type events">
- <label for="checkbox2" class="checkbox">
- <input id="checkbox2" type="checkbox" ng-model="ecdapp.isLogType"><i class="skin"></i><span>Include Logs</span>
- </label>
- </div>
-
- <div
- b2b-table
- id="logs-table"
- class="b2b-table-div"
- table-data="ecdapp.logTableData"
- current-page="ecdapp.currentPageIgnored"
- next-sort="ecdapp.nextSortIgnored">
- <table>
- <thead b2b-table-row type="header">
- <tr id="th-header-row">
- <th b2b-table-header key="reported_timestamp">Reported Timestamp</th>
- <th b2b-table-header key="timestamp">Type</th>
- <th b2b-table-header key="event_type">Event Type</th>
- <th b2b-table-header key="message">Message</th>
- <th b2b-table-header key="node_name">Node name</th>
- <th b2b-table-header key="node_instance_id">Node Instance</th>
- <th b2b-table-header key="error_causes">Error Causes</th>
- </tr>
- </thead>
- <tbody b2b-table-row type="body" row-repeat="rowData in ecdapp.logTableData">
- <tr id="tr-rowData" ng-class="{ 'red-background' : rowData.message.toLowerCase().contains("error") }">
- <td b2b-table-body
- ng-bind="rowData.reported_timestamp"/>
- <td b2b-table-body
- ng-bind="rowData.type"/>
- <td b2b-table-body
- ng-bind="rowData.event_type"/>
- <td b2b-table-body
- ng-bind="rowData.message"/>
- <td b2b-table-body
- ng-bind="rowData.node_name"/>
- <td b2b-table-body
- ng-bind="rowData.node_instance_id"/>
- <td b2b-table-body
- ng-bind="rowData.error_causes[0].traceback"/>
- </tr>
- </tbody>
- </table>
- </div>
- <div b2b-pagination="" total-pages="ecdapp.totalLogPages"
- current-page="ecdapp.currentLogPageNum" click-handler="pageChangeHandler"
- role="navigation">
- </div>
- </div>
-
- <div class="b2b-modal-footer ng-scope ng-isolate-scope">
- <div class="cta-button-group in">
- <button class="btn btn-alt btn-small" type="button"
- ng-click="$dismiss('cancel');">
- Close
- </button>
- </div>
- </div>
-
+ </div>
+</div>
+<div class="b2b-modal-body ng-scope ng-isolate-scope" tabindex="0"
+ role="region" aria-label="Modal body content">
+ <!--<h1 class="heading-page" id="executions-page">Executions</h1> -->
+ <!-- show progress indicator -->
+ <div ng-show="ecdapp.isDataLoading">
+ <div class="span" style="margin-bottom: 20px;">
+ <i class="icon-spinner small" role="img"
+ aria-label="Please wait while the content loads"></i> Please
+ wait while the content loads.
+ </div>
+ </div>
+ <div ng-show="ecdapp.isCancelOn">
+ <div class="span" style="margin-bottom: 20px;">
+ <i class="icon-spinner small" role="img"
+ aria-label="Cancel in progress"></i> Cancel in progress
+ </div>
+ </div>
+ <div ng-show="ecdapp.errMsg">
+ <span class="ecd-error-message">{{ecdapp.errMsg}}</span>
+ </div>
+ <div ng-show="ecdapp.evtErrMsg">
+ <span class="ecd-error-message">{{ecdapp.evtErrMsg}}</span>
+ </div>
+ <div class="form-row" style="margin-top: 0px;">
+ <div style="float: left; width: 200px; margin-left: 30px;"
+ title="switch to enable/disable screen refresh">
+ <label for="refresh_switch" class="btn-switch-label"
+ ng-class="{'b2b-disabled-label':allDisabled}"> <span
+ aria-hidden="true">Auto-refresh</span> <input type="button"
+ aria-pressed="{{ecdapp.refresh_switch.value}}"
+ id="refresh_switch" b2b-switches
+ ng-model="ecdapp.refresh_switch.value" ng-disabled="allDisabled"
+ aria-disabled="{{allDisabled}}"
+ aria-label="Auto-refresh is {{ecdapp.refresh_switch.value?'On':'Off'}}. {{allDisabled?'Disabled. Explanation why it is disabled':''}}">
+ </label>
+ </div>
+ <div style="float: right;"
+ title="Checkbox to view latest execution workflow only">
+ <label for="checkbox1" class="checkbox"> <input
+ id="checkbox1" type="checkbox" ng-model="ecdapp.isLastExecution"><i
+ class="skin"></i><span>Last execution</span>
+ </label>
+ </div>
+ </div>
+ <div ng-hide="ecdapp.errMsg">
+ <div b2b-table id="executions-table" class="b2b-table-div"
+ table-data="ecdapp.tableData" search-string="ecdapp.searchString"
+ current-page="ecdapp.currentPageIgnored"
+ next-sort="ecdapp.nextSortIgnored">
+ <table>
+ <thead b2b-table-row type="header">
+ <tr id="th-header-row">
+ <th b2b-table-header key="index">#</th>
+ <th b2b-table-header key="created_at">Created Date</th>
+ <th b2b-table-header key="workflow_id">Workflow ID</th>
+ <th b2b-table-header key="id">ID</th>
+ <th b2b-table-header key="status">Status</th>
+ <th b2b-table-header sortable="false">Actions<i
+ class="icon-controls-gear ecd-icon-display"></i></th>
+ </tr>
+ </thead>
+ <tbody b2b-table-row type="body"
+ ng-repeat="rowData in ecdapp.tableData"
+ ng-class="{'selected':$index == ecdapp.selectedRow}">
+ <!--ng-click="ecdapp.setClickedRow($index)" -->
+ <tr id="tr-rowData">
+ <td b2b-table-body>{{$index+1}}</td>
+ <td b2b-table-body ng-bind="rowData.created_at" />
+ <td b2b-table-body ng-bind="rowData.workflow_id" />
+ <td b2b-table-body ng-bind="rowData.id" />
+ <td b2b-table-body ng-if="rowData.status == 'pending'">
+ waiting to start</td>
+ <td b2b-table-body ng-if="rowData.status == 'started'">
+ <div
+ ng-click="ecdapp.getExecutionLogs($index, rowData.id, ecdapp.ui_tenant);">
+ <a href="" title="View execution logs" class="tooltip">in
+ progress</a>
+ </div>
+ </td>
+ <td b2b-table-body ng-if="rowData.status == 'cancelling'">
+ <div
+ ng-click="ecdapp.getExecutionLogs($index, rowData.id, ecdapp.ui_tenant);">
+ <a href="" title="View execution logs" class="tooltip">cancel
+ in progress</a>
+ </div>
+ </td>
+ <td b2b-table-body
+ ng-if="rowData.status == 'force_cancelling'">
+ <div
+ ng-click="ecdapp.getExecutionLogs($index, rowData.id, ecdapp.ui_tenant);">
+ <a href="" title="View execution logs" class="tooltip">force-cancelling
+ in progress</a>
+ </div>
+ </td>
+ <td b2b-table-body ng-if="rowData.status == 'cancelled'">
+ <div
+ ng-click="ecdapp.getExecutionLogs($index, rowData.id, ecdapp.ui_tenant);">
+ <a href="" title="View execution logs" class="tooltip">cancelled</a>
+ </div>
+ </td>
+ <td b2b-table-body ng-if="rowData.status == 'terminated'">
+ <div
+ ng-click="ecdapp.getExecutionLogs($index, rowData.id, ecdapp.ui_tenant);">
+ <a href="" title="View execution logs" class="tooltip">successful</a>
+ </div>
+ </td>
+ <td b2b-table-body ng-if="rowData.status == 'failed'">
+ <div
+ ng-click="ecdapp.getExecutionLogs($index, rowData.id, ecdapp.ui_tenant);">
+ <a href="" title="View execution logs" class="tooltip">failed</a>
+ </div>
+ </td>
+ <td b2b-table-body ng-if="rowData.status == 'failed'">
+ <div ng-show="rowData.error"
+ ng-click="ecdapp.viewErrorModalPopup(rowData);">
+ <a href="" title="View error details"
+ class="icon-people-preview ecd-icon-action"></a>
+ </div>
+ </td>
+ <td b2b-table-body ng-if="rowData.status == 'started'">
+ <div
+ ng-click="ecdapp.cancelExecutionModalPopup(rowData, ecdapp.ui_tenant);">
+ <a href="" title="Cancel execution"
+ class="icon-controls-stop ecd-icon-action"></a>
+ </div>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ <div b2b-pagination="" total-pages="ecdapp.totalPages"
+ current-page="ecdapp.currentPageNum"
+ click-handler="pageChangeHandler" role="navigation"></div>
+ </div>
+ <div ng-show="ecdapp.isEventLogQuery">
+ <div style="float: left;">
+ <h3>Events/Logs</h3>
+ <h4>execution id: {{ecdapp.execId}}</h4>
+ </div>
+ <div style="float: right;"
+ title="Checkbox to Include log type events">
+ <label for="checkbox2" class="checkbox"> <input
+ id="checkbox2" type="checkbox" ng-model="ecdapp.isLogType"><i
+ class="skin"></i><span>Include Logs</span>
+ </label>
+ </div>
+ <div b2b-table id="logs-table" class="b2b-table-div"
+ table-data="ecdapp.logTableData"
+ current-page="ecdapp.currentPageIgnored"
+ next-sort="ecdapp.nextSortIgnored">
+ <table>
+ <thead b2b-table-row type="header">
+ <tr id="th-header-row">
+ <th b2b-table-header key="reported_timestamp">Reported
+ Timestamp</th>
+ <th b2b-table-header key="timestamp">Type</th>
+ <th b2b-table-header key="event_type">Event Type</th>
+ <th b2b-table-header key="message">Message</th>
+ <th b2b-table-header key="node_name">Node name</th>
+ <th b2b-table-header key="node_instance_id">Node
+ Instance</th>
+ <th b2b-table-header key="error_causes">Error Causes</th>
+ </tr>
+ </thead>
+ <tbody b2b-table-row type="body"
+ row-repeat="rowData in ecdapp.logTableData">
+ <tr id="tr-rowData" ng-style="{'background-color':rowData.event_type === 'task_failed'
+ || rowData.event_type === 'workflow_failed' ? '#fbbbbb' : '#ffffff'}">
+ <td b2b-table-body ng-bind="rowData.reported_timestamp" />
+ <td b2b-table-body ng-bind="rowData.type" />
+ <td b2b-table-body ng-bind="rowData.event_type" />
+ <td b2b-table-body>
+ <div class="my-tooltip">
+ {{rowData.message | limitTo: 1000}}
+ <div class="wrapper">
+ <div class="clip-btn-div">
+ <button style="border-radius: 5px;margin-top: -20px;"
+ ng-click="ecdapp.copyStringToClipboard(rowData.message)">Copy Message</button>
+ </div>
+ <span class="my-tooltiptext">{{rowData.message}}</span>
+ </div>
+ </div>
+ </td>
+ <td b2b-table-body ng-bind="rowData.node_name" />
+ <td b2b-table-body ng-bind="rowData.node_instance_id" />
+ <td b2b-table-body
+ ng-bind="rowData.error_causes[0].traceback" />
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ <div b2b-pagination="" total-pages="ecdapp.totalLogPages"
+ current-page="ecdapp.currentLogPageNum"
+ click-handler="pageChangeHandlerEvent" role="navigation"></div>
+ </div>
+ <div class="b2b-modal-footer ng-scope ng-isolate-scope">
+ <div class="cta-button-group in">
+ <button class="btn btn-alt btn-small" type="button"
+ ng-click="$dismiss('cancel');">Close</button>
+ </div>
+ </div>
</script> \ No newline at end of file
diff --git a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/ops/dbcl_view.html b/ccsdk-app-overlay/src/main/webapp/app/ccsdk/ops/dbcl_view.html
deleted file mode 100644
index da9fb74..0000000
--- a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/ops/dbcl_view.html
+++ /dev/null
@@ -1,6 +0,0 @@
-<div id="page-content" ng-controller="tabsController">
- <h1> DMaap Bus Controller</h1>
- <iframe scrolling="yes" frameborder="0" style="width:100%; height: 800px;"
- ng-src="{{opsMenu[5].url}}">
- </iframe>
-</div> \ No newline at end of file
diff --git a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/ops/tabs-view-controller.js b/ccsdk-app-overlay/src/main/webapp/app/ccsdk/ops/tabs-view-controller.js
deleted file mode 100644
index f37a4f0..0000000
--- a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/ops/tabs-view-controller.js
+++ /dev/null
@@ -1,271 +0,0 @@
-appDS2.controller('tabsController', function ($rootScope, $scope, $interval, b2bDOMHelper, $timeout, $route) {
- 'use strict';
- $scope.ecdapp = {};
- $scope.ecdapp.opsItem = $route.current.$$route.item;
- $scope.ecdapp.activeTabsId = $scope.ecdapp.opsItem ;
- $scope.ecdapp.activeTabUrl = '';
- $scope.ecdapp.isInit = false;
- $scope.ecdapp.cfy = {};
- $scope.ecdapp.cfy.url = ''; //$rootScope.opsMenu[0].url;
- $scope.ecdapp.cfy.site = '';
- $scope.ecdapp.cnsl = {};
- $scope.ecdapp.cnsl.url = ''; //$rootScope.opsMenu[2].url;
- $scope.ecdapp.k8 = {};
- $scope.ecdapp.k8.site = '';
- $scope.ecdapp.k8.url = ''; //$rootScope.opsMenu[3].url;
- $scope.ecdapp.k8.tenant = '';
- $scope.ecdapp.prom = {};
- $scope.ecdapp.prom.tenant = '';
- $scope.ecdapp.prom.site = '';
- $scope.ecdapp.prom.url = ''; //$rootScope.opsMenu[4].url;
- $scope.ecdapp.grf = {};
- $scope.ecdapp.grf.site = '';
- $scope.ecdapp.grf.tenant = '';
- $scope.ecdapp.grf.url = ''; //$rootScope.opsMenu[1].url;
- $scope.ecdapp.isFrameLoaded = true;
- $scope.ecdapp.cfySite = '';
- $scope.ecdapp.cnslSite = '';
- $scope.ecdapp.appCluster = '';
- $scope.ecdapp.k8.cluster = '';
- $scope.ecdapp.grf.cluster = '';
- $scope.ecdapp.prom.cluster = '';
-
- var key = $scope.ecdapp.opsItem;
-
- // if it's not already part of our keys array
- if($rootScope.menuKeys.indexOf(key) === -1) {
- // add it to our keys array
- $rootScope.menuKeys.push(key);
- for (var itemTab = 0; itemTab < $rootScope.opsMenu.length; itemTab++) {
- if ($rootScope.opsMenu[itemTab].id === key) {
- $rootScope.gTabs.push($rootScope.opsMenu[itemTab]);
- //$scope.ecdapp.activeTabUrl = $rootScope.opsMenu[itemTab].url;
- break;
- }
- }
- }
- $scope.ecdapp.gTabs = $rootScope.gTabs;
- /*
- angular.forEach($rootScope.opsMenu, function(item) {
- if
- // we check to see whether our object exists
- var key = $scope.ecdapp.opsItem;
- // if it's not already part of our keys array
- if($rootScope.menuKeys.indexOf(key) === -1) {
- // add it to our keys array
- $rootScope.menuKeys.push(key);
- // push this item to our final output array
- $rootScope.gTabs.push(item);
- $scope.ecdapp.activeTabUrl = item.url;
- } else {
- if (item.id === key) {
- $scope.ecdapp.activeTabUrl = item.url;
- }
- }
- });
-
-
- for (var menuTab = 0; menuTab < $scope.ecdapp.gTabs.length; menuTab++) {
- if ($scope.ecdapp.gTabs[menuTab].id === key) {
- $scope.ecdapp.activeTabUrl = $scope.ecdapp.gTabs[menuTab].url;
- break;
- }
- }
- */
- $scope.ecdapp.isInit = true;
- $rootScope.activeTabsId = $scope.ecdapp.opsItem;
-
- $rootScope.$watch('activeTabsId', function (newVal, oldVal) {
- if(newVal !== oldVal) {
- var selectedTab;
- for (selectedTab = 0; selectedTab < $rootScope.opsMenu.length; selectedTab++) {
- if ($rootScope.opsMenu[selectedTab].id === newVal) {
- //$scope.ecdapp.activeTabUrl = $rootScope.opsMenu[selectedTab].url;
- break;
- }
- }
- var selectedTabPanelElement = document.getElementById($rootScope.opsMenu[selectedTab].tabPanelId);
-
- var elem = null;
- if (selectedTabPanelElement) {
- elem = b2bDOMHelper.firstTabableElement(selectedTabPanelElement);
- }
-
- if (elem) {
- $timeout(function () {
- elem.focus();
- }, 100);
- }
- }
- });
-
-
- $scope.ecdapp.selectAppTenant = function(site) {
- if(site != "Select Site") {
- for (var indx = 0; indx < $rootScope.site_tenant_map.length; indx++) {
- if ($rootScope.site_tenant_map[indx].site === site) {
- $scope.ecdapp.appTenants = $rootScope.site_tenant_map[indx].tenant;
- break;
- }
- }
- }
- }
-
- $scope.ecdapp.selectCluster = function(tenant) {
- if(tenant != "Select Tenant") {
- for (var indx = 0; indx < $rootScope.tenant_cluster_map.length; indx++) {
- if ($rootScope.tenant_cluster_map[indx].tenant === tenant) {
- $scope.ecdapp.appCluster = $rootScope.tenant_cluster_map[indx].cluster;
- }
- }
- }
- }
-
- var stopPolling;
- //var doIframePolling;
- $scope.ecdapp.appFrameReload = function(cluster, app) {
- if(cluster != "Select K8s cluster") {
- $scope.ecdapp.isFrameLoaded = false;
- for (var indx = 0; indx < $rootScope.tenant_cluster_apps_map.length; indx++) {
- if ($rootScope.tenant_cluster_apps_map[indx].cluster === cluster) {
- if (app === 'prom') {
- $scope.ecdapp.prom.url = $rootScope.tenant_cluster_apps_map[indx].prom;
- } else if (app === 'grf') {
- $scope.ecdapp.grf.url = $rootScope.tenant_cluster_apps_map[indx].grf;
- } else {
- $scope.ecdapp.k8.url = $rootScope.tenant_cluster_apps_map[indx].k8;
- }
- break;
- }
- }
- stopPolling = $timeout(function () {
- $timeout.cancel(stopPolling);
- stopPolling = undefined;
- $scope.ecdapp.isFrameLoaded = true;
- },30000);
- }
- }
-
- $scope.ecdapp.cfyCnslFrameReload = function(site, app) {
- if(site != "Select Site") {
- $scope.ecdapp.isFrameLoaded = false;
- for (var indx = 0; indx < $rootScope.site_cfy_cnsl_map.length; indx++) {
- if ($rootScope.site_cfy_cnsl_map[indx].site === site) {
- if (app === 'cfy') {
- $scope.ecdapp.cfy.url = $rootScope.site_cfy_cnsl_map[indx].cfy;
- } else {
- $scope.ecdapp.cnsl.url = $rootScope.site_cfy_cnsl_map[indx].cnsl;
- }
- break;
- }
- }
- stopPolling = $timeout(function () {
- $timeout.cancel(stopPolling);
- stopPolling = undefined;
- $scope.ecdapp.isFrameLoaded = true;
- },30000);
- }
- }
- document.querySelector("iframe").addEventListener("load", function() {
- $scope.ecdapp.isFrameLoaded = true;
- $scope.$apply();
- });
- $scope.$on("$destroy",function() {
- $timeout.cancel(stopPolling);
- //$interval.cancel(doIframePolling);
- });
-
- /*
- * $scope.ecdapp.selectK8Tenant = function(site) {
- if(site != "Select Site") {
- for (var indx = 0; indx < $rootScope.site_tenant_map.length; indx++) {
- if ($rootScope.site_tenant_map[indx].site === site) {
- $scope.ecdapp.k8Tenants = $rootScope.site_tenant_map[indx].tenant;
- break;
- }
- }
- }
- }
-
- $scope.ecdapp.selectK8App = function(t) {
- if(t != "Select Tenant for K8s components") {
- for (var indx = 0; indx < $rootScope.tenant_cluster_map.length; indx++) {
- if ($rootScope.tenant_cluster_map[indx].tenant === t) {
- $scope.ecdapp.k8.url = $rootScope.tenant_cluster_map[indx].k8s;
- break;
- }
- }
- }
- }
-
- $scope.ecdapp.selectGrfTenant = function(site) {
- if(site != "Select Site") {
- for (var indx = 0; indx < $rootScope.site_tenant_map.length; indx++) {
- if ($rootScope.site_tenant_map[indx].site === site) {
- $scope.ecdapp.grfTenants = $rootScope.site_tenant_map[indx].tenant;
- break;
- }
- }
- }
- }
-
- $scope.ecdapp.selectGrfApp = function(t) {
- if(t != "Select Tenant for Grafana") {
- for (var indx = 0; indx < $rootScope.tenant_cluster_map.length; indx++) {
- if ($rootScope.tenant_cluster_map[indx].tenant === t) {
- $scope.ecdapp.grf.url = $rootScope.tenant_cluster_map[indx].grf;
- break;
- }
- }
- }
- }
-
- $scope.ecdapp.selectPromTenant = function(site) {
- if(site != "Select Site") {
- for (var indx = 0; indx < $rootScope.site_tenant_map.length; indx++) {
- if ($rootScope.site_tenant_map[indx].site === site) {
- $scope.ecdapp.promTenants = $rootScope.site_tenant_map[indx].tenant;
- break;
- }
- }
- }
- }
-
- $scope.ecdapp.selectPromApp = function(t) {
- if(t != "Select Tenant for Prometheus") {
- for (var indx = 0; indx < $rootScope.tenant_cluster_map.length; indx++) {
- if ($rootScope.tenant_cluster_map[indx].tenant === t) {
- $scope.ecdapp.prom.url = $rootScope.tenant_cluster_map[indx].prom;
- break;
- }
- }
- }
- }
-
- doIframePolling = $interval(function () {
- if(document.querySelector("iframe") &&
- document.querySelector("iframe").contentDocument.head &&
- document.querySelector("iframe").contentDocument.head.innerHTML != '')
- {
- $interval.cancel(doIframePolling);
- doIframePolling = undefined;
- $timeout.cancel(stopPolling);
- stopPolling = undefined;
- $scope.ecdapp.isCfyLoadDone = true;
- }
- },400);
-
- stopPolling = $timeout(function () {
- //$interval.cancel(doIframePolling);
- //doIframePolling = undefined;
- $timeout.cancel(stopPolling);
- stopPolling = undefined;
- $scope.ecdapp.isCfyLoadDone = true;
- },30000);
- }
- }
-
- */
-
-
-}); \ No newline at end of file
diff --git a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/ops/tabs_view.html b/ccsdk-app-overlay/src/main/webapp/app/ccsdk/ops/tabs_view.html
deleted file mode 100644
index aa5b1f8..0000000
--- a/ccsdk-app-overlay/src/main/webapp/app/ccsdk/ops/tabs_view.html
+++ /dev/null
@@ -1,131 +0,0 @@
-<div id="page-content" ng-controller="tabsController">
- <div ng-show="ecdapp.isInit">
- <b2b-tabset tab-id-selected="activeTabsId">
- <b2b-tab ng-repeat="tab in ecdapp.gTabs" tab-item="tab"
- id="{{tab.uniqueId}}" aria-controls="{{tab.tabPanelId}}"
- ng-disabled="tab.disabled">
- {{tab.title}}
- </b2b-tab>
- </b2b-tabset>
- </div>
-
- <div class="tab-content">
- <div id="threetab1x" role="tabpanel" aria-labelledby="uniqueTab1x" aria-hidden="{{'cfy'===activeTabsId}}" class="tab-pane" ng-class="{'active': 'cfy'===activeTabsId}">
- <div class="row-nowrap" style="margin-top:-20px; margin-bottom: 5px;">
- <div class="span3 form-row">
- <label for="cfy-site-url">Site</label>
- <select id="cfy-site-url" name="cfy-site-url" b2b-dropdown placeholder-text="Select Site" data-ng-model="ecdapp.cfySite" ng-change="ecdapp.cfyCnslFrameReload(ecdapp.cfySite, 'cfy')" required>
- <option b2b-dropdown-list option-repeat="d in site_cfy_cnsl_map" value="{{d.site}}">{{d.site}}</option>
- </select>
- </div>
- </div>
- <div ng-hide="ecdapp.isFrameLoaded" class="span">
- <i class="icon-spinner small" role="img" aria-label="Please wait while the content loads"></i>
- Please wait while the content loads.
- </div>
- <iframe id="cfy_frame" ng-show="ecdapp.isFrameLoaded" aria-expanded="true" scrolling="yes" frameborder="0" style="width:100%; height: 800px;" ng-src="{{ecdapp.cfy.url}}">
- </iframe>
- </div>
- <div id="threetab2x" role="tabpanel" aria-labelledby="uniqueTab2x" aria-hidden="{{'grf'===activeTabsId}}" class="tab-pane" ng-class="{'active': 'grf'===activeTabsId}">
- <div class="row-nowrap" style="margin-top:-20px; margin-bottom: 5px;">
- <div class="span3 form-row">
- <label for="grf-site-url">Site</label>
- <select id="grf-site-url" name="grf-site-url" b2b-dropdown placeholder-text="Select Site" data-ng-model="ecdapp.grf.site" ng-change="ecdapp.selectAppTenant(ecdapp.grf.site)" required>
- <option b2b-dropdown-list option-repeat="d in site_cfy_cnsl_map" value="{{d.site}}">{{d.site}}</option>
- </select>
- </div>
- <div class="span4 form-row">
- <label for="grf-ten-url">Tenant</label>
- <select id="grf-ten-url" name="grf-ten-url" b2b-dropdown placeholder-text="Select Tenant" data-ng-model="ecdapp.grf.tenant" ng-change="ecdapp.selectCluster(ecdapp.grf.tenant)" required>
- <option b2b-dropdown-list option-repeat="t in ecdapp.appTenants" value="{{t}}">{{t}}</option>
- </select>
- </div>
- <div class="span3 form-row">
- <label for="grf-cluster-url">Cluster</label>
- <select id="grf-cluster-url" name="grf-cluster-url" b2b-dropdown placeholder-text="Select K8s cluster" data-ng-model="ecdapp.grf.cluster" ng-change="ecdapp.appFrameReload(ecdapp.grf.cluster, 'grf')" required>
- <option b2b-dropdown-list option-repeat="c in ecdapp.appCluster" value="{{c}}">{{c}}</option>
- </select>
- </div>
- </div>
- <div ng-hide="ecdapp.isFrameLoaded" class="span">
- <i class="icon-spinner small" role="img" aria-label="Please wait while the content loads"></i>
- Please wait while the content loads.
- </div>
- <iframe ng-show="ecdapp.isFrameLoaded" scrolling="yes" frameborder="0" style="width:100%; height: 800px;" ng-src="{{ecdapp.grf.url}}">
- </iframe>
- </div>
- <div id="threetab3x" role="tabpanel" aria-labelledby="uniqueTab3x" aria-hidden="{{'cnsl'===activeTabsId}}" class="tab-pane" ng-class="{'active': 'cnsl'===activeTabsId}">
- <div class="row-nowrap" style="margin-top:-20px; margin-bottom: 5px;">
- <div class="span3 form-row">
- <label for="cnsl-site-url">Site</label>
- <select id="cnsl-site-url" name="cnsl-site-url" b2b-dropdown placeholder-text="Select Site" data-ng-model="ecdapp.cnslSite" ng-change="ecdapp.cfyCnslFrameReload(ecdapp.cnslSite, 'cnsl')" required>
- <option b2b-dropdown-list option-repeat="d in site_cfy_cnsl_map" value="{{d.site}}">{{d.site}}</option>
- </select>
- </div>
- </div>
- <div ng-hide="ecdapp.isFrameLoaded" class="span">
- <i class="icon-spinner small" role="img" aria-label="Please wait while the content loads"></i>
- Please wait while the content loads.
- </div>
- <iframe ng-show="ecdapp.isFrameLoaded" scrolling="yes" frameborder="0" style="width:100%; height: 800px;" ng-src="{{ecdapp.cnsl.url}}">
- </iframe>
- </div>
- <div id="threetab4x" role="tabpanel" aria-labelledby="uniqueTab4x" aria-hidden="{{'k8s'===activeTabsId}}" class="tab-pane" ng-class="{'active': 'k8s'===activeTabsId}">
- <div class="row-nowrap" style="margin-top:-20px; margin-bottom: 5px;">
- <div class="span3 form-row">
- <label for="k8s-site-url">Site</label>
- <select id="k8s-site-url" name="k8s-site-url" b2b-dropdown placeholder-text="Select Site" data-ng-model="ecdapp.k8.site" ng-change="ecdapp.selectAppTenant(ecdapp.k8.site)" required>
- <option b2b-dropdown-list option-repeat="d in site_cfy_cnsl_map" value="{{d.site}}">{{d.site}}</option>
- </select>
- </div>
- <div class="span6 form-row">
- <label for="k8s-ten-url">Tenant</label>
- <select id="k8s-ten-url" name="k8s-ten-url" b2b-dropdown placeholder-text="Select Tenant" data-ng-model="ecdapp.k8.tenant" ng-change="ecdapp.selectCluster(ecdapp.k8.tenant)" required>
- <option b2b-dropdown-list option-repeat="t in ecdapp.appTenants" value="{{t}}">{{t}}</option>
- </select>
- </div>
- <div class="span3 form-row">
- <label for="k8s-cluster-url">Cluster</label>
- <select id="k8s-cluster-url" name="k8s-cluster-url" b2b-dropdown placeholder-text="Select K8s cluster" data-ng-model="ecdapp.k8.cluster" ng-change="ecdapp.appFrameReload(ecdapp.k8.cluster, 'k8')" required>
- <option b2b-dropdown-list option-repeat="c in ecdapp.appCluster" value="{{c}}">{{c}}</option>
- </select>
- </div>
- </div>
- <div ng-hide="ecdapp.isFrameLoaded" class="span">
- <i class="icon-spinner small" role="img" aria-label="Please wait while the content loads"></i>
- Please wait while the content loads.
- </div>
- <iframe ng-show="ecdapp.isFrameLoaded" scrolling="yes" frameborder="0" style="width:100%; height: 800px;" ng-src="{{ecdapp.k8.url}}">
- </iframe>
- </div>
- <div id="threetab5x" role="tabpanel" aria-labelledby="uniqueTab5x" aria-hidden="{{'prom'===activeTabsId}}" class="tab-pane" ng-class="{'active': 'prom'===activeTabsId}">
- <div class="row-nowrap" style="margin-top:-20px; margin-bottom: 5px;">
- <div class="span3 form-row">
- <label for="prom-site-url">Site</label>
- <select id="prom-site-url" name="prom-site-url" b2b-dropdown placeholder-text="Select Site" data-ng-model="ecdapp.prom.site" ng-change="ecdapp.selectAppTenant(ecdapp.prom.site)" required>
- <option b2b-dropdown-list option-repeat="d in site_cfy_cnsl_map" value="{{d.site}}">{{d.site}}</option>
- </select>
- </div>
- <div class="span6 form-row">
- <label for="prom-ten-url">Tenant</label>
- <select id="prom-ten-url" name="prom-ten-url" b2b-dropdown placeholder-text="Select Tenant" data-ng-model="ecdapp.prom.tenant" ng-change="ecdapp.selectCluster(ecdapp.prom.tenant)" required>
- <option b2b-dropdown-list option-repeat="t in ecdapp.appTenants" value="{{t}}">{{t}}</option>
- </select>
- </div>
- <div class="span3 form-row">
- <label for="prom-cluster-url">Cluster</label>
- <select id="prom-cluster-url" name="prom-cluster-url" b2b-dropdown placeholder-text="Select K8s cluster" data-ng-model="ecdapp.prom.cluster" ng-change="ecdapp.appFrameReload(ecdapp.prom.cluster, 'prom')" required>
- <option b2b-dropdown-list option-repeat="c in ecdapp.appCluster" value="{{c}}">{{c}}</option>
- </select>
- </div>
- </div>
- <div ng-hide="ecdapp.isFrameLoaded" class="span">
- <i class="icon-spinner small" role="img" aria-label="Please wait while the content loads"></i>
- Please wait while the content loads.
- </div>
- <iframe ng-show="ecdapp.isFrameLoaded" scrolling="yes" frameborder="0" style="width:100%; height: 800px;" ng-src="{{ecdapp.prom.url}}">
- </iframe>
- </div>
- </div>
-
-</div> \ No newline at end of file