aboutsummaryrefslogtreecommitdiffstats
path: root/vid/src/main/webapp/app/vid/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'vid/src/main/webapp/app/vid/scripts')
-rw-r--r--vid/src/main/webapp/app/vid/scripts/angular-ui-tree.js1636
-rw-r--r--vid/src/main/webapp/app/vid/scripts/constants/componentConstants.js42
-rw-r--r--vid/src/main/webapp/app/vid/scripts/constants/fieldConstants.js182
-rw-r--r--vid/src/main/webapp/app/vid/scripts/constants/parameterConstants.js29
-rw-r--r--vid/src/main/webapp/app/vid/scripts/controller/InstantiationController.js1028
-rw-r--r--vid/src/main/webapp/app/vid/scripts/controller/ServiceModelController.js196
-rw-r--r--vid/src/main/webapp/app/vid/scripts/controller/VidApp.js67
-rw-r--r--vid/src/main/webapp/app/vid/scripts/controller/aaiSubscriberController.js763
-rw-r--r--vid/src/main/webapp/app/vid/scripts/controller/creationDialogController.js162
-rw-r--r--vid/src/main/webapp/app/vid/scripts/controller/deletionDialogController.js117
-rw-r--r--vid/src/main/webapp/app/vid/scripts/controller/detailsDialogController.js84
-rw-r--r--vid/src/main/webapp/app/vid/scripts/controller/dummy.txt0
-rw-r--r--vid/src/main/webapp/app/vid/scripts/controller/msoCommitController.js249
-rw-r--r--vid/src/main/webapp/app/vid/scripts/controller/sample-page-controller.js81
-rw-r--r--vid/src/main/webapp/app/vid/scripts/controller/sample-page-iframe-controller.js24
-rw-r--r--vid/src/main/webapp/app/vid/scripts/controller/sampleController.js31
-rw-r--r--vid/src/main/webapp/app/vid/scripts/controller/subscriberSearch.js385
-rw-r--r--vid/src/main/webapp/app/vid/scripts/directives/dummy.txt0
-rw-r--r--vid/src/main/webapp/app/vid/scripts/directives/extensionsDirective.js79
-rw-r--r--vid/src/main/webapp/app/vid/scripts/directives/parameterBlockDirective.js309
-rw-r--r--vid/src/main/webapp/app/vid/scripts/directives/popupWindowDirective.js88
-rw-r--r--vid/src/main/webapp/app/vid/scripts/directives/progressBarDirective.js173
-rw-r--r--vid/src/main/webapp/app/vid/scripts/services/aaiService.js111
-rw-r--r--vid/src/main/webapp/app/vid/scripts/services/asdcService.js40
-rw-r--r--vid/src/main/webapp/app/vid/scripts/services/componentService.js148
-rw-r--r--vid/src/main/webapp/app/vid/scripts/services/creationService.js683
-rw-r--r--vid/src/main/webapp/app/vid/scripts/services/dataService.js197
-rw-r--r--vid/src/main/webapp/app/vid/scripts/services/deletionService.js442
-rw-r--r--vid/src/main/webapp/app/vid/scripts/services/detailsService.js98
-rw-r--r--vid/src/main/webapp/app/vid/scripts/services/msoService.js146
-rw-r--r--vid/src/main/webapp/app/vid/scripts/services/propertyService.js116
-rw-r--r--vid/src/main/webapp/app/vid/scripts/services/utilityService.js228
-rw-r--r--vid/src/main/webapp/app/vid/scripts/utils/dummy.txt0
-rw-r--r--vid/src/main/webapp/app/vid/scripts/view-models/aaiGetSubs.htm79
-rw-r--r--vid/src/main/webapp/app/vid/scripts/view-models/aaiSubDetails.htm93
-rw-r--r--vid/src/main/webapp/app/vid/scripts/view-models/aaiSubViewEdit.htm147
-rw-r--r--vid/src/main/webapp/app/vid/scripts/view-models/creationDialog.htm64
-rw-r--r--vid/src/main/webapp/app/vid/scripts/view-models/deletionDialog.htm80
-rw-r--r--vid/src/main/webapp/app/vid/scripts/view-models/detailsDialog.htm48
-rw-r--r--vid/src/main/webapp/app/vid/scripts/view-models/dummy.txt0
-rw-r--r--vid/src/main/webapp/app/vid/scripts/view-models/instantiate.htm204
-rw-r--r--vid/src/main/webapp/app/vid/scripts/view-models/msoCommit.htm47
-rw-r--r--vid/src/main/webapp/app/vid/scripts/view-models/popupWindow.htm8
-rw-r--r--vid/src/main/webapp/app/vid/scripts/view-models/sample.html61
-rw-r--r--vid/src/main/webapp/app/vid/scripts/view-models/sampleWithIframe.html23
-rw-r--r--vid/src/main/webapp/app/vid/scripts/view-models/serviceModels.htm90
-rw-r--r--vid/src/main/webapp/app/vid/scripts/view-models/singlePageSample.html87
-rw-r--r--vid/src/main/webapp/app/vid/scripts/view-models/vidhome.htm39
48 files changed, 9004 insertions, 0 deletions
diff --git a/vid/src/main/webapp/app/vid/scripts/angular-ui-tree.js b/vid/src/main/webapp/app/vid/scripts/angular-ui-tree.js
new file mode 100644
index 000000000..a7e8cf494
--- /dev/null
+++ b/vid/src/main/webapp/app/vid/scripts/angular-ui-tree.js
@@ -0,0 +1,1636 @@
+/**
+ * @license Angular UI Tree v2.17.0
+ * (c) 2010-2016. https://github.com/angular-ui-tree/angular-ui-tree
+ * License: MIT
+ */
+(function () {
+ 'use strict';
+
+ angular.module('ui.tree', [])
+ .constant('treeConfig', {
+ treeClass: 'angular-ui-tree',
+ emptyTreeClass: 'angular-ui-tree-empty',
+ hiddenClass: 'angular-ui-tree-hidden',
+ nodesClass: 'angular-ui-tree-nodes',
+ nodeClass: 'angular-ui-tree-node',
+ handleClass: 'angular-ui-tree-handle',
+ placeholderClass: 'angular-ui-tree-placeholder',
+ dragClass: 'angular-ui-tree-drag',
+ dragThreshold: 3,
+ levelThreshold: 30,
+ defaultCollapsed: false
+ });
+
+})();
+
+(function () {
+ 'use strict';
+
+ angular.module('ui.tree')
+
+ .controller('TreeHandleController', ['$scope', '$element',
+ function ($scope, $element) {
+ this.scope = $scope;
+
+ $scope.$element = $element;
+ $scope.$nodeScope = null;
+ $scope.$type = 'uiTreeHandle';
+
+ }
+ ]);
+})();
+
+(function () {
+ 'use strict';
+
+ angular.module('ui.tree')
+ .controller('TreeNodeController', ['$scope', '$element',
+ function ($scope, $element) {
+ this.scope = $scope;
+
+ $scope.$element = $element;
+ $scope.$modelValue = null; // Model value for node;
+ $scope.$parentNodeScope = null; // uiTreeNode Scope of parent node;
+ $scope.$childNodesScope = null; // uiTreeNodes Scope of child nodes.
+ $scope.$parentNodesScope = null; // uiTreeNodes Scope of parent nodes.
+ $scope.$treeScope = null; // uiTree scope
+ $scope.$handleScope = null; // it's handle scope
+ $scope.$type = 'uiTreeNode';
+ $scope.$$allowNodeDrop = false;
+ $scope.collapsed = false;
+ $scope.expandOnHover = false;
+
+ $scope.init = function (controllersArr) {
+ var treeNodesCtrl = controllersArr[0];
+ $scope.$treeScope = controllersArr[1] ? controllersArr[1].scope : null;
+
+ // find the scope of it's parent node
+ $scope.$parentNodeScope = treeNodesCtrl.scope.$nodeScope;
+ // modelValue for current node
+ $scope.$modelValue = treeNodesCtrl.scope.$modelValue[$scope.$index];
+ $scope.$parentNodesScope = treeNodesCtrl.scope;
+ treeNodesCtrl.scope.initSubNode($scope); // init sub nodes
+
+ $element.on('$destroy', function () {
+ treeNodesCtrl.scope.destroySubNode($scope); // destroy sub nodes
+ });
+ };
+
+ $scope.index = function () {
+ return $scope.$parentNodesScope.$modelValue.indexOf($scope.$modelValue);
+ };
+
+ $scope.dragEnabled = function () {
+ return !($scope.$treeScope && !$scope.$treeScope.dragEnabled);
+ };
+
+ $scope.isSibling = function (targetNode) {
+ return $scope.$parentNodesScope == targetNode.$parentNodesScope;
+ };
+
+ $scope.isChild = function (targetNode) {
+ var nodes = $scope.childNodes();
+ return nodes && nodes.indexOf(targetNode) > -1;
+ };
+
+ $scope.prev = function () {
+ var index = $scope.index();
+ if (index > 0) {
+ return $scope.siblings()[index - 1];
+ }
+ return null;
+ };
+
+ $scope.siblings = function () {
+ return $scope.$parentNodesScope.childNodes();
+ };
+
+ $scope.childNodesCount = function () {
+ return $scope.childNodes() ? $scope.childNodes().length : 0;
+ };
+
+ $scope.hasChild = function () {
+ return $scope.childNodesCount() > 0;
+ };
+
+ $scope.childNodes = function () {
+ return $scope.$childNodesScope && $scope.$childNodesScope.$modelValue ?
+ $scope.$childNodesScope.childNodes() :
+ null;
+ };
+
+ $scope.accept = function (sourceNode, destIndex) {
+ return $scope.$childNodesScope &&
+ $scope.$childNodesScope.$modelValue &&
+ $scope.$childNodesScope.accept(sourceNode, destIndex);
+ };
+
+ $scope.remove = function () {
+ return $scope.$parentNodesScope.removeNode($scope);
+ };
+
+ $scope.toggle = function () {
+ $scope.collapsed = !$scope.collapsed;
+ $scope.$treeScope.$callbacks.toggle($scope.collapsed, $scope);
+ };
+
+ $scope.collapse = function () {
+ $scope.collapsed = true;
+ };
+
+ $scope.expand = function () {
+ $scope.collapsed = false;
+ };
+
+ $scope.depth = function () {
+ var parentNode = $scope.$parentNodeScope;
+ if (parentNode) {
+ return parentNode.depth() + 1;
+ }
+ return 1;
+ };
+
+ /**
+ * Returns the depth of the deepest subtree under this node
+ * @param scope a TreeNodesController scope object
+ * @returns Depth of all nodes *beneath* this node. If scope belongs to a leaf node, the
+ * result is 0 (it has no subtree).
+ */
+ function countSubTreeDepth(scope) {
+ var thisLevelDepth = 0,
+ childNodes = scope.childNodes(),
+ childNode,
+ childDepth,
+ i;
+ if (!childNodes || childNodes.length === 0) {
+ return 0;
+ }
+ for (i = childNodes.length - 1; i >= 0 ; i--) {
+ childNode = childNodes[i],
+ childDepth = 1 + countSubTreeDepth(childNode);
+ thisLevelDepth = Math.max(thisLevelDepth, childDepth);
+ }
+ return thisLevelDepth;
+ }
+
+ $scope.maxSubDepth = function () {
+ return $scope.$childNodesScope ? countSubTreeDepth($scope.$childNodesScope) : 0;
+ };
+ }
+ ]);
+})();
+
+(function () {
+ 'use strict';
+
+ angular.module('ui.tree')
+
+ .controller('TreeNodesController', ['$scope', '$element',
+ function ($scope, $element) {
+ this.scope = $scope;
+
+ $scope.$element = $element;
+ $scope.$modelValue = null;
+ $scope.$nodeScope = null; // the scope of node which the nodes belongs to
+ $scope.$treeScope = null;
+ $scope.$type = 'uiTreeNodes';
+ $scope.$nodesMap = {};
+
+ $scope.nodropEnabled = false;
+ $scope.maxDepth = 0;
+ $scope.cloneEnabled = false;
+
+ $scope.initSubNode = function (subNode) {
+ if (!subNode.$modelValue) {
+ return null;
+ }
+ $scope.$nodesMap[subNode.$modelValue.$$hashKey] = subNode;
+ };
+
+ $scope.destroySubNode = function (subNode) {
+ if (!subNode.$modelValue) {
+ return null;
+ }
+ $scope.$nodesMap[subNode.$modelValue.$$hashKey] = null;
+ };
+
+ $scope.accept = function (sourceNode, destIndex) {
+ return $scope.$treeScope.$callbacks.accept(sourceNode, $scope, destIndex);
+ };
+
+ $scope.beforeDrag = function (sourceNode) {
+ return $scope.$treeScope.$callbacks.beforeDrag(sourceNode);
+ };
+
+ $scope.isParent = function (node) {
+ return node.$parentNodesScope == $scope;
+ };
+
+ $scope.hasChild = function () {
+ return $scope.$modelValue.length > 0;
+ };
+
+ $scope.safeApply = function (fn) {
+ var phase = this.$root.$$phase;
+ if (phase == '$apply' || phase == '$digest') {
+ if (fn && (typeof (fn) === 'function')) {
+ fn();
+ }
+ } else {
+ this.$apply(fn);
+ }
+ };
+
+ $scope.removeNode = function (node) {
+ var index = $scope.$modelValue.indexOf(node.$modelValue);
+ if (index > -1) {
+ $scope.safeApply(function () {
+ $scope.$modelValue.splice(index, 1)[0];
+ });
+ return $scope.$treeScope.$callbacks.removed(node);
+ }
+ return null;
+ };
+
+ $scope.insertNode = function (index, nodeData) {
+ $scope.safeApply(function () {
+ $scope.$modelValue.splice(index, 0, nodeData);
+ });
+ };
+
+ $scope.childNodes = function () {
+ var i, nodes = [];
+ if ($scope.$modelValue) {
+ for (i = 0; i < $scope.$modelValue.length; i++) {
+ nodes.push($scope.$nodesMap[$scope.$modelValue[i].$$hashKey]);
+ }
+ }
+ return nodes;
+ };
+
+ $scope.depth = function () {
+ if ($scope.$nodeScope) {
+ return $scope.$nodeScope.depth();
+ }
+ return 0; // if it has no $nodeScope, it's root
+ };
+
+ // check if depth limit has reached
+ $scope.outOfDepth = function (sourceNode) {
+ var maxDepth = $scope.maxDepth || $scope.$treeScope.maxDepth;
+ if (maxDepth > 0) {
+ return $scope.depth() + sourceNode.maxSubDepth() + 1 > maxDepth;
+ }
+ return false;
+ };
+
+ }
+ ]);
+})();
+
+(function () {
+ 'use strict';
+
+ angular.module('ui.tree')
+
+ .controller('TreeController', ['$scope', '$element',
+ function ($scope, $element) {
+ this.scope = $scope;
+
+ $scope.$element = $element;
+ $scope.$nodesScope = null; // root nodes
+ $scope.$type = 'uiTree';
+ $scope.$emptyElm = null;
+ $scope.$callbacks = null;
+
+ $scope.dragEnabled = true;
+ $scope.emptyPlaceholderEnabled = true;
+ $scope.maxDepth = 0;
+ $scope.dragDelay = 0;
+ $scope.cloneEnabled = false;
+ $scope.nodropEnabled = false;
+
+ // Check if it's a empty tree
+ $scope.isEmpty = function () {
+ return ($scope.$nodesScope && $scope.$nodesScope.$modelValue
+ && $scope.$nodesScope.$modelValue.length === 0);
+ };
+
+ // add placeholder to empty tree
+ $scope.place = function (placeElm) {
+ $scope.$nodesScope.$element.append(placeElm);
+ $scope.$emptyElm.remove();
+ };
+
+ this.resetEmptyElement = function () {
+ if ((!$scope.$nodesScope.$modelValue || $scope.$nodesScope.$modelValue.length === 0) &&
+ $scope.emptyPlaceholderEnabled) {
+ $element.append($scope.$emptyElm);
+ } else {
+ $scope.$emptyElm.remove();
+ }
+ };
+
+ $scope.resetEmptyElement = this.resetEmptyElement;
+ }
+ ]);
+})();
+
+(function () {
+ 'use strict';
+
+ angular.module('ui.tree')
+ .directive('uiTree', ['treeConfig', '$window',
+ function (treeConfig, $window) {
+ return {
+ restrict: 'A',
+ scope: true,
+ controller: 'TreeController',
+ link: function (scope, element, attrs, ctrl) {
+ var callbacks = {
+ accept: null,
+ beforeDrag: null
+ },
+ config = {},
+ tdElm,
+ $trElm,
+ emptyElmColspan;
+
+ angular.extend(config, treeConfig);
+ if (config.treeClass) {
+ element.addClass(config.treeClass);
+ }
+
+ if (element.prop('tagName').toLowerCase() === 'table') {
+ scope.$emptyElm = angular.element($window.document.createElement('tr'));
+ $trElm = element.find('tr');
+ // If we can find a tr, then we can use its td children as the empty element colspan.
+ if ($trElm.length > 0) {
+ emptyElmColspan = angular.element($trElm).children().length;
+ } else {
+ // If not, by setting a huge colspan we make sure it takes full width.
+ emptyElmColspan = 1000000;
+ }
+ tdElm = angular.element($window.document.createElement('td'))
+ .attr('colspan', emptyElmColspan);
+ scope.$emptyElm.append(tdElm);
+ } else {
+ scope.$emptyElm = angular.element($window.document.createElement('div'));
+ }
+
+ if (config.emptyTreeClass) {
+ scope.$emptyElm.addClass(config.emptyTreeClass);
+ }
+
+ scope.$watch('$nodesScope.$modelValue.length', function (val) {
+ if (!angular.isNumber(val)) {
+ return;
+ }
+
+ ctrl.resetEmptyElement();
+ }, true);
+
+ scope.$watch(attrs.dragEnabled, function (val) {
+ if ((typeof val) == 'boolean') {
+ scope.dragEnabled = val;
+ }
+ });
+
+ scope.$watch(attrs.emptyPlaceholderEnabled, function (val) {
+ if ((typeof val) == 'boolean') {
+ scope.emptyPlaceholderEnabled = val;
+ ctrl.resetEmptyElement();
+ }
+ });
+
+ scope.$watch(attrs.nodropEnabled, function (val) {
+ if ((typeof val) == 'boolean') {
+ scope.nodropEnabled = val;
+ }
+ });
+
+ scope.$watch(attrs.cloneEnabled, function (val) {
+ if ((typeof val) == 'boolean') {
+ scope.cloneEnabled = val;
+ }
+ });
+
+ scope.$watch(attrs.maxDepth, function (val) {
+ if ((typeof val) == 'number') {
+ scope.maxDepth = val;
+ }
+ });
+
+ scope.$watch(attrs.dragDelay, function (val) {
+ if ((typeof val) == 'number') {
+ scope.dragDelay = val;
+ }
+ });
+
+ /**
+ * Callback checks if the destination node can accept the dragged node.
+ * By default, ui-tree will check that 'data-nodrop-enabled' is not set for the
+ * destination ui-tree-nodes, and that the 'max-depth' attribute will not be exceeded
+ * if it is set on the ui-tree or ui-tree-nodes.
+ * This callback can be overridden, but callers must manually enforce nodrop and max-depth
+ * themselves if they need those to be enforced.
+ * @param sourceNodeScope Scope of the ui-tree-node being dragged
+ * @param destNodesScope Scope of the ui-tree-nodes where the node is hovering
+ * @param destIndex Index in the destination nodes array where the source node will drop
+ * @returns {boolean} True if the node is permitted to be dropped here
+ */
+ callbacks.accept = function (sourceNodeScope, destNodesScope, destIndex) {
+ return !(destNodesScope.nodropEnabled || destNodesScope.$treeScope.nodropEnabled || destNodesScope.outOfDepth(sourceNodeScope));
+ };
+
+ callbacks.beforeDrag = function (sourceNodeScope) {
+ return true;
+ };
+
+ callbacks.expandTimeoutStart = function()
+ {
+
+ };
+
+ callbacks.expandTimeoutCancel = function()
+ {
+
+ };
+
+ callbacks.expandTimeoutEnd = function()
+ {
+
+ };
+
+ callbacks.removed = function (node) {
+
+ };
+
+ /**
+ * Callback is fired when a node is successfully dropped in a new location
+ * @param event
+ */
+ callbacks.dropped = function (event) {
+
+ };
+
+ /**
+ * Callback is fired each time the user starts dragging a node
+ * @param event
+ */
+ callbacks.dragStart = function (event) {
+
+ };
+
+ /**
+ * Callback is fired each time a dragged node is moved with the mouse/touch.
+ * @param event
+ */
+ callbacks.dragMove = function (event) {
+
+ };
+
+ /**
+ * Callback is fired when the tree exits drag mode. If the user dropped a node, the drop may have been
+ * accepted or reverted.
+ * @param event
+ */
+ callbacks.dragStop = function (event) {
+
+ };
+
+ /**
+ * Callback is fired when a user drops a node (but prior to processing the drop action)
+ * beforeDrop can return a Promise, truthy, or falsy (returning nothing is falsy).
+ * If it returns falsy, or a resolve Promise, the node move is accepted
+ * If it returns truthy, or a rejected Promise, the node move is reverted
+ * @param event
+ * @returns {Boolean|Promise} Truthy (or rejected Promise) to cancel node move; falsy (or resolved promise)
+ */
+ callbacks.beforeDrop = function (event) {
+
+ };
+
+ /**
+ * Callback is fired when a user toggles node (but after processing the toggle action)
+ * @param sourceNodeScope
+ * @param collapsed
+ */
+ callbacks.toggle = function (collapsed, sourceNodeScope) {
+
+ };
+
+ scope.$watch(attrs.uiTree, function (newVal, oldVal) {
+ angular.forEach(newVal, function (value, key) {
+ if (callbacks[key]) {
+ if (typeof value === 'function') {
+ callbacks[key] = value;
+ }
+ }
+ });
+
+ scope.$callbacks = callbacks;
+ }, true);
+
+
+ }
+ };
+ }
+ ]);
+})();
+
+(function () {
+ 'use strict';
+
+ angular.module('ui.tree')
+ .directive('uiTreeHandle', ['treeConfig',
+ function (treeConfig) {
+ return {
+ require: '^uiTreeNode',
+ restrict: 'A',
+ scope: true,
+ controller: 'TreeHandleController',
+ link: function (scope, element, attrs, treeNodeCtrl) {
+ var config = {};
+ angular.extend(config, treeConfig);
+ if (config.handleClass) {
+ element.addClass(config.handleClass);
+ }
+ // connect with the tree node.
+ if (scope != treeNodeCtrl.scope) {
+ scope.$nodeScope = treeNodeCtrl.scope;
+ treeNodeCtrl.scope.$handleScope = scope;
+ }
+ }
+ };
+ }
+ ]);
+})();
+
+(function () {
+ 'use strict';
+
+ angular.module('ui.tree')
+
+ .directive('uiTreeNode', ['treeConfig', 'UiTreeHelper', '$window', '$document', '$timeout', '$q',
+ function (treeConfig, UiTreeHelper, $window, $document, $timeout, $q) {
+ return {
+ require: ['^uiTreeNodes', '^uiTree'],
+ restrict: 'A',
+ controller: 'TreeNodeController',
+ link: function (scope, element, attrs, controllersArr) {
+ // todo startPos is unused
+ var config = {},
+ hasTouch = 'ontouchstart' in window,
+ startPos, firstMoving, dragInfo, pos,
+ placeElm, hiddenPlaceElm, dragElm,
+ treeScope = null,
+ elements, // As a parameter for callbacks
+ dragDelaying = true,
+ dragStarted = false,
+ dragTimer = null,
+ body = document.body,
+ html = document.documentElement,
+ document_height,
+ document_width,
+ dragStart,
+ tagName,
+ dragMove,
+ dragEnd,
+ dragStartEvent,
+ dragMoveEvent,
+ dragEndEvent,
+ dragCancelEvent,
+ dragDelay,
+ bindDragStartEvents,
+ bindDragMoveEvents,
+ unbindDragMoveEvents,
+ keydownHandler,
+ outOfBounds,
+ isHandleChild,
+ el;
+
+ angular.extend(config, treeConfig);
+ if (config.nodeClass) {
+ element.addClass(config.nodeClass);
+ }
+ scope.init(controllersArr);
+
+ scope.collapsed = !!UiTreeHelper.getNodeAttribute(scope, 'collapsed') || treeConfig.defaultCollapsed;
+ scope.expandOnHover = !!UiTreeHelper.getNodeAttribute(scope, 'expandOnHover');
+ scope.sourceOnly = scope.nodropEnabled || scope.$treeScope.nodropEnabled;
+
+ scope.$watch(attrs.collapsed, function (val) {
+ if ((typeof val) == 'boolean') {
+ scope.collapsed = val;
+ }
+ });
+
+ scope.$watch('collapsed', function (val) {
+ UiTreeHelper.setNodeAttribute(scope, 'collapsed', val);
+ attrs.$set('collapsed', val);
+ });
+
+ scope.$watch(attrs.expandOnHover, function(val) {
+ if ((typeof val) == 'boolean') {
+ scope.expandOnHover = val;
+ }
+ });
+
+ scope.$watch('expandOnHover', function (val) {
+ UiTreeHelper.setNodeAttribute(scope, 'expandOnHover', val);
+ attrs.$set('expandOnHover', val);
+ });
+
+ scope.$on('angular-ui-tree:collapse-all', function () {
+ scope.collapsed = true;
+ });
+
+ scope.$on('angular-ui-tree:expand-all', function () {
+ scope.collapsed = false;
+ });
+
+ /**
+ * Called when the user has grabbed a node and started dragging it
+ * @param e
+ */
+ dragStart = function (e) {
+ // disable right click
+ if (!hasTouch && (e.button === 2 || e.which === 3)) {
+ return;
+ }
+
+ // event has already fired in other scope
+ if (e.uiTreeDragging || (e.originalEvent && e.originalEvent.uiTreeDragging)) {
+ return;
+ }
+
+ // the node being dragged
+ var eventElm = angular.element(e.target),
+ isHandleChild, cloneElm, eventElmTagName, tagName,
+ eventObj, tdElm, hStyle,
+ isTreeNode,
+ isTreeNodeHandle;
+
+ // if the target element is a child element of a ui-tree-handle,
+ // use the containing handle element as target element
+ isHandleChild = UiTreeHelper.treeNodeHandlerContainerOfElement(eventElm);
+ if (isHandleChild) {
+ eventElm = angular.element(isHandleChild);
+ }
+
+ cloneElm = element.clone();
+ isTreeNode = UiTreeHelper.elementIsTreeNode(eventElm);
+ isTreeNodeHandle = UiTreeHelper.elementIsTreeNodeHandle(eventElm);
+
+ if (!isTreeNode && !isTreeNodeHandle) {
+ return;
+ }
+
+ if (isTreeNode && UiTreeHelper.elementContainsTreeNodeHandler(eventElm)) {
+ return;
+ }
+
+ eventElmTagName = eventElm.prop('tagName').toLowerCase();
+ if (eventElmTagName == 'input' ||
+ eventElmTagName == 'textarea' ||
+ eventElmTagName == 'button' ||
+ eventElmTagName == 'select') { // if it's a input or button, ignore it
+ return;
+ }
+
+ // check if it or it's parents has a 'data-nodrag' attribute
+ el = angular.element(e.target);
+ while (el && el[0] && el[0] !== element) {
+ if (UiTreeHelper.nodrag(el)) { // if the node mark as `nodrag`, DONOT drag it.
+ return;
+ }
+ el = el.parent();
+ }
+
+ if (!scope.beforeDrag(scope)) {
+ return;
+ }
+
+ e.uiTreeDragging = true; // stop event bubbling
+ if (e.originalEvent) {
+ e.originalEvent.uiTreeDragging = true;
+ }
+ e.preventDefault();
+ eventObj = UiTreeHelper.eventObj(e);
+
+ firstMoving = true;
+ dragInfo = UiTreeHelper.dragInfo(scope);
+
+ tagName = element.prop('tagName');
+
+ if (tagName.toLowerCase() === 'tr') {
+ placeElm = angular.element($window.document.createElement(tagName));
+ tdElm = angular.element($window.document.createElement('td'))
+ .addClass(config.placeholderClass)
+ .attr('colspan', element[0].children.length);
+ placeElm.append(tdElm);
+ } else {
+ placeElm = angular.element($window.document.createElement(tagName))
+ .addClass(config.placeholderClass);
+ }
+ hiddenPlaceElm = angular.element($window.document.createElement(tagName));
+ if (config.hiddenClass) {
+ hiddenPlaceElm.addClass(config.hiddenClass);
+ }
+
+ pos = UiTreeHelper.positionStarted(eventObj, element);
+ placeElm.css('height', UiTreeHelper.height(element) + 'px');
+
+ dragElm = angular.element($window.document.createElement(scope.$parentNodesScope.$element.prop('tagName')))
+ .addClass(scope.$parentNodesScope.$element.attr('class')).addClass(config.dragClass);
+ dragElm.css('width', UiTreeHelper.width(element) + 'px');
+ dragElm.css('z-index', 9999);
+
+ // Prevents cursor to change rapidly in Opera 12.16 and IE when dragging an element
+ hStyle = (element[0].querySelector('.angular-ui-tree-handle') || element[0]).currentStyle;
+ if (hStyle) {
+ document.body.setAttribute('ui-tree-cursor', $document.find('body').css('cursor') || '');
+ $document.find('body').css({'cursor': hStyle.cursor + '!important'});
+ }
+
+ if (scope.sourceOnly) {
+ placeElm.css('display', 'none');
+ }
+ element.after(placeElm);
+ element.after(hiddenPlaceElm);
+ if (dragInfo.isClone() && scope.sourceOnly) {
+ dragElm.append(cloneElm);
+ } else {
+ dragElm.append(element);
+ }
+
+ $document.find('body').append(dragElm);
+
+ dragElm.css({
+ 'left': eventObj.pageX - pos.offsetX + 'px',
+ 'top': eventObj.pageY - pos.offsetY + 'px'
+ });
+ elements = {
+ placeholder: placeElm,
+ dragging: dragElm
+ };
+
+ bindDragMoveEvents();
+ // Fire dragStart callback
+ scope.$apply(function () {
+ scope.$treeScope.$callbacks.dragStart(dragInfo.eventArgs(elements, pos));
+ });
+
+ document_height = Math.max(body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight);
+ document_width = Math.max(body.scrollWidth, body.offsetWidth, html.clientWidth, html.scrollWidth, html.offsetWidth);
+ };
+
+ dragMove = function (e) {
+ var eventObj = UiTreeHelper.eventObj(e),
+ prev,
+ next,
+ leftElmPos,
+ topElmPos,
+ top_scroll,
+ bottom_scroll,
+ target,
+ decrease,
+ targetX,
+ targetY,
+ displayElm,
+ targetNode,
+ targetElm,
+ isEmpty,
+ scrollDownBy,
+ targetOffset,
+ targetBefore;
+
+ if (dragElm) {
+ e.preventDefault();
+
+ if ($window.getSelection) {
+ $window.getSelection().removeAllRanges();
+ } else if ($window.document.selection) {
+ $window.document.selection.empty();
+ }
+
+ leftElmPos = eventObj.pageX - pos.offsetX;
+ topElmPos = eventObj.pageY - pos.offsetY;
+
+ //dragElm can't leave the screen on the left
+ if (leftElmPos < 0) {
+ leftElmPos = 0;
+ }
+
+ //dragElm can't leave the screen on the top
+ if (topElmPos < 0) {
+ topElmPos = 0;
+ }
+
+ //dragElm can't leave the screen on the bottom
+ if ((topElmPos + 10) > document_height) {
+ topElmPos = document_height - 10;
+ }
+
+ //dragElm can't leave the screen on the right
+ if ((leftElmPos + 10) > document_width) {
+ leftElmPos = document_width - 10;
+ }
+
+ dragElm.css({
+ 'left': leftElmPos + 'px',
+ 'top': topElmPos + 'px'
+ });
+
+ top_scroll = window.pageYOffset || $window.document.documentElement.scrollTop;
+ bottom_scroll = top_scroll + (window.innerHeight || $window.document.clientHeight || $window.document.clientHeight);
+
+ // to scroll down if cursor y-position is greater than the bottom position the vertical scroll
+ if (bottom_scroll < eventObj.pageY && bottom_scroll < document_height) {
+ scrollDownBy = Math.min(document_height - bottom_scroll, 10);
+ window.scrollBy(0, scrollDownBy);
+ }
+
+ // to scroll top if cursor y-position is less than the top position the vertical scroll
+ if (top_scroll > eventObj.pageY) {
+ window.scrollBy(0, -10);
+ }
+
+ UiTreeHelper.positionMoved(e, pos, firstMoving);
+ if (firstMoving) {
+ firstMoving = false;
+ return;
+ }
+
+ // check if add it as a child node first
+ // todo decrease is unused
+ decrease = (UiTreeHelper.offset(dragElm).left - UiTreeHelper.offset(placeElm).left) >= config.threshold;
+
+ targetX = eventObj.pageX - ($window.pageXOffset ||
+ $window.document.body.scrollLeft ||
+ $window.document.documentElement.scrollLeft) -
+ ($window.document.documentElement.clientLeft || 0);
+
+ targetY = eventObj.pageY - ($window.pageYOffset ||
+ $window.document.body.scrollTop ||
+ $window.document.documentElement.scrollTop) -
+ ($window.document.documentElement.clientTop || 0);
+
+ // Select the drag target. Because IE does not support CSS 'pointer-events: none', it will always
+ // pick the drag element itself as the target. To prevent this, we hide the drag element while
+ // selecting the target.
+ if (angular.isFunction(dragElm.hide)) {
+ dragElm.hide();
+ } else {
+ displayElm = dragElm[0].style.display;
+ dragElm[0].style.display = 'none';
+ }
+
+ // when using elementFromPoint() inside an iframe, you have to call
+ // elementFromPoint() twice to make sure IE8 returns the correct value
+ $window.document.elementFromPoint(targetX, targetY);
+
+ targetElm = angular.element($window.document.elementFromPoint(targetX, targetY));
+
+ // if the target element is a child element of a ui-tree-handle,
+ // use the containing handle element as target element
+ isHandleChild = UiTreeHelper.treeNodeHandlerContainerOfElement(targetElm);
+ if (isHandleChild) {
+ targetElm = angular.element(isHandleChild);
+ }
+
+ if (angular.isFunction(dragElm.show)) {
+ dragElm.show();
+ } else {
+ dragElm[0].style.display = displayElm;
+ }
+
+ outOfBounds = !UiTreeHelper.elementIsTreeNodeHandle(targetElm) &&
+ !UiTreeHelper.elementIsTreeNode(targetElm) &&
+ !UiTreeHelper.elementIsTreeNodes(targetElm) &&
+ !UiTreeHelper.elementIsTree(targetElm) &&
+ !UiTreeHelper.elementIsPlaceholder(targetElm);
+
+ // Detect out of bounds condition, update drop target display, and prevent drop
+ if (outOfBounds) {
+
+ // Remove the placeholder
+ placeElm.remove();
+
+ // If the target was an empty tree, replace the empty element placeholder
+ if (treeScope) {
+ treeScope.resetEmptyElement();
+ treeScope = null;
+ }
+ }
+
+ // move horizontal
+ if (pos.dirAx && pos.distAxX >= config.levelThreshold) {
+ pos.distAxX = 0;
+
+ // increase horizontal level if previous sibling exists and is not collapsed
+ if (pos.distX > 0) {
+ prev = dragInfo.prev();
+ if (prev && !prev.collapsed
+ && prev.accept(scope, prev.childNodesCount())) {
+ prev.$childNodesScope.$element.append(placeElm);
+ dragInfo.moveTo(prev.$childNodesScope, prev.childNodes(), prev.childNodesCount());
+ }
+ }
+
+ // decrease horizontal level
+ if (pos.distX < 0) {
+ // we can't decrease a level if an item preceeds the current one
+ next = dragInfo.next();
+ if (!next) {
+ target = dragInfo.parentNode(); // As a sibling of it's parent node
+ if (target
+ && target.$parentNodesScope.accept(scope, target.index() + 1)) {
+ target.$element.after(placeElm);
+ dragInfo.moveTo(target.$parentNodesScope, target.siblings(), target.index() + 1);
+ }
+ }
+ }
+ }
+
+ // move vertical
+ if (!pos.dirAx) {
+ if (UiTreeHelper.elementIsTree(targetElm)) {
+ targetNode = targetElm.controller('uiTree').scope;
+ } else if (UiTreeHelper.elementIsTreeNodeHandle(targetElm)) {
+ targetNode = targetElm.controller('uiTreeHandle').scope;
+ } else if (UiTreeHelper.elementIsTreeNode(targetElm)) {
+ targetNode = targetElm.controller('uiTreeNode').scope;
+ } else if (UiTreeHelper.elementIsTreeNodes(targetElm)) {
+ targetNode = targetElm.controller('uiTreeNodes').scope;
+ } else if (UiTreeHelper.elementIsPlaceholder(targetElm)) {
+ targetNode = targetElm.controller('uiTreeNodes').scope;
+ } else if (targetElm.controller('uiTreeNode')) {
+ // is a child element of a node
+ targetNode = targetElm.controller('uiTreeNode').scope;
+ }
+
+ // check it's new position
+ isEmpty = false;
+ if (!targetNode) {
+ return;
+ }
+
+ // Show the placeholder if it was hidden for nodrop-enabled and this is a new tree
+ if (targetNode.$treeScope && !targetNode.$parent.nodropEnabled && !targetNode.$treeScope.nodropEnabled) {
+ placeElm.css('display', '');
+ }
+
+ if (targetNode.$type == 'uiTree' && targetNode.dragEnabled) {
+ isEmpty = targetNode.isEmpty(); // Check if it's empty tree
+ }
+
+ if (targetNode.$type == 'uiTreeHandle') {
+ targetNode = targetNode.$nodeScope;
+ }
+
+ if (targetNode.$type != 'uiTreeNode'
+ && !isEmpty) { // Check if it is a uiTreeNode or it's an empty tree
+ return;
+ }
+
+ // if placeholder move from empty tree, reset it.
+ if (treeScope && placeElm.parent()[0] != treeScope.$element[0]) {
+ treeScope.resetEmptyElement();
+ treeScope = null;
+ }
+
+ if (isEmpty) { // it's an empty tree
+ treeScope = targetNode;
+ if (targetNode.$nodesScope.accept(scope, 0)) {
+ targetNode.place(placeElm);
+ dragInfo.moveTo(targetNode.$nodesScope, targetNode.$nodesScope.childNodes(), 0);
+ }
+ } else if (targetNode.dragEnabled()) { // drag enabled
+ if (angular.isDefined(scope.expandTimeoutOn) && scope.expandTimeoutOn !== targetNode.id) {
+ $timeout.cancel(scope.expandTimeout);
+ delete scope.expandTimeout;
+ delete scope.expandTimeoutOn;
+
+ scope.$callbacks.expandTimeoutCancel();
+ }
+
+ if (targetNode.collapsed) {
+ if (scope.expandOnHover === true || (angular.isNumber(scope.expandOnHover) && scope.expandOnHover === 0)) {
+ targetNode.collapsed = false;
+ } else if (scope.expandOnHover !== false && angular.isNumber(scope.expandOnHover) && scope.expandOnHover > 0) {
+ if (angular.isUndefined(scope.expandTimeoutOn)) {
+ scope.expandTimeoutOn = targetNode.$id;
+
+ scope.$callbacks.expandTimeoutStart();
+ scope.expandTimeout = $timeout(function()
+ {
+ scope.$callbacks.expandTimeoutEnd();
+ targetNode.collapsed = false;
+ }, scope.expandOnHover);
+ }
+ }
+ }
+
+ targetElm = targetNode.$element; // Get the element of ui-tree-node
+ targetOffset = UiTreeHelper.offset(targetElm);
+ targetBefore = targetNode.horizontal ? eventObj.pageX < (targetOffset.left + UiTreeHelper.width(targetElm) / 2)
+ : eventObj.pageY < (targetOffset.top + UiTreeHelper.height(targetElm) / 2);
+
+ if (targetNode.$parentNodesScope.accept(scope, targetNode.index())) {
+ if (targetBefore) {
+ targetElm[0].parentNode.insertBefore(placeElm[0], targetElm[0]);
+ dragInfo.moveTo(targetNode.$parentNodesScope, targetNode.siblings(), targetNode.index());
+ } else {
+ targetElm.after(placeElm);
+ dragInfo.moveTo(targetNode.$parentNodesScope, targetNode.siblings(), targetNode.index() + 1);
+ }
+ } else if (!targetBefore && targetNode.accept(scope, targetNode.childNodesCount())) { // we have to check if it can add the dragging node as a child
+ targetNode.$childNodesScope.$element.append(placeElm);
+ dragInfo.moveTo(targetNode.$childNodesScope, targetNode.childNodes(), targetNode.childNodesCount());
+ } else {
+ outOfBounds = true;
+ }
+ }
+ }
+
+ scope.$apply(function () {
+ scope.$treeScope.$callbacks.dragMove(dragInfo.eventArgs(elements, pos));
+ });
+ }
+ };
+
+ dragEnd = function (e) {
+ var dragEventArgs = dragInfo.eventArgs(elements, pos);
+ e.preventDefault();
+ unbindDragMoveEvents();
+
+ $timeout.cancel(scope.expandTimeout);
+
+ scope.$treeScope.$apply(function () {
+ $q.when(scope.$treeScope.$callbacks.beforeDrop(dragEventArgs))
+ // promise resolved (or callback didn't return false)
+ .then(function (allowDrop) {
+ if (allowDrop !== false && scope.$$allowNodeDrop && !outOfBounds) { // node drop accepted)
+ dragInfo.apply();
+ // fire the dropped callback only if the move was successful
+ scope.$treeScope.$callbacks.dropped(dragEventArgs);
+ } else { // drop canceled - revert the node to its original position
+ bindDragStartEvents();
+ }
+ })
+ // promise rejected - revert the node to its original position
+ .catch(function () {
+ bindDragStartEvents();
+ })
+ .finally(function () {
+ hiddenPlaceElm.replaceWith(scope.$element);
+ placeElm.remove();
+
+ if (dragElm) { // drag element is attached to the mouse pointer
+ dragElm.remove();
+ dragElm = null;
+ }
+ scope.$treeScope.$callbacks.dragStop(dragEventArgs);
+ scope.$$allowNodeDrop = false;
+ dragInfo = null;
+
+ // Restore cursor in Opera 12.16 and IE
+ var oldCur = document.body.getAttribute('ui-tree-cursor');
+ if (oldCur !== null) {
+ $document.find('body').css({'cursor': oldCur});
+ document.body.removeAttribute('ui-tree-cursor');
+ }
+ });
+ });
+ };
+
+ dragStartEvent = function (e) {
+ if (scope.dragEnabled()) {
+ dragStart(e);
+ }
+ };
+
+ dragMoveEvent = function (e) {
+ dragMove(e);
+ };
+
+ dragEndEvent = function (e) {
+ scope.$$allowNodeDrop = true;
+ dragEnd(e);
+ };
+
+ dragCancelEvent = function (e) {
+ dragEnd(e);
+ };
+
+ dragDelay = (function () {
+ var to;
+
+ return {
+ exec: function (fn, ms) {
+ if (!ms) {
+ ms = 0;
+ }
+ this.cancel();
+ to = $timeout(fn, ms);
+ },
+ cancel: function () {
+ $timeout.cancel(to);
+ }
+ };
+ })();
+
+ /**
+ * Binds the mouse/touch events to enable drag start for this node
+ */
+ bindDragStartEvents = function () {
+ element.bind('touchstart mousedown', function (e) {
+ dragDelay.exec(function () {
+ dragStartEvent(e);
+ }, scope.dragDelay || 0);
+ });
+ element.bind('touchend touchcancel mouseup', function () {
+ dragDelay.cancel();
+ });
+ };
+ bindDragStartEvents();
+
+ /**
+ * Binds mouse/touch events that handle moving/dropping this dragged node
+ */
+ bindDragMoveEvents = function () {
+ angular.element($document).bind('touchend', dragEndEvent);
+ angular.element($document).bind('touchcancel', dragEndEvent);
+ angular.element($document).bind('touchmove', dragMoveEvent);
+ angular.element($document).bind('mouseup', dragEndEvent);
+ angular.element($document).bind('mousemove', dragMoveEvent);
+ angular.element($document).bind('mouseleave', dragCancelEvent);
+ };
+
+ /**
+ * Unbinds mouse/touch events that handle moving/dropping this dragged node
+ */
+ unbindDragMoveEvents = function () {
+ angular.element($document).unbind('touchend', dragEndEvent);
+ angular.element($document).unbind('touchcancel', dragEndEvent);
+ angular.element($document).unbind('touchmove', dragMoveEvent);
+ angular.element($document).unbind('mouseup', dragEndEvent);
+ angular.element($document).unbind('mousemove', dragMoveEvent);
+ angular.element($document).unbind('mouseleave', dragCancelEvent);
+ };
+
+ keydownHandler = function (e) {
+ if (e.keyCode == 27) {
+ scope.$$allowNodeDrop = false;
+ dragEnd(e);
+ }
+ };
+
+ angular.element($window.document).bind('keydown', keydownHandler);
+
+ //unbind handler that retains scope
+ scope.$on('$destroy', function () {
+ angular.element($window.document).unbind('keydown', keydownHandler);
+ });
+ }
+ };
+ }
+ ]);
+
+})();
+
+(function () {
+ 'use strict';
+
+ angular.module('ui.tree')
+ .directive('uiTreeNodes', ['treeConfig', '$window',
+ function (treeConfig) {
+ return {
+ require: ['ngModel', '?^uiTreeNode', '^uiTree'],
+ restrict: 'A',
+ scope: true,
+ controller: 'TreeNodesController',
+ link: function (scope, element, attrs, controllersArr) {
+
+ var config = {},
+ ngModel = controllersArr[0],
+ treeNodeCtrl = controllersArr[1],
+ treeCtrl = controllersArr[2];
+
+ angular.extend(config, treeConfig);
+ if (config.nodesClass) {
+ element.addClass(config.nodesClass);
+ }
+
+ if (treeNodeCtrl) {
+ treeNodeCtrl.scope.$childNodesScope = scope;
+ scope.$nodeScope = treeNodeCtrl.scope;
+ } else {
+ // find the root nodes if there is no parent node and have a parent ui-tree
+ treeCtrl.scope.$nodesScope = scope;
+ }
+ scope.$treeScope = treeCtrl.scope;
+
+ if (ngModel) {
+ ngModel.$render = function () {
+ scope.$modelValue = ngModel.$modelValue;
+ };
+ }
+
+ scope.$watch(function () {
+ return attrs.maxDepth;
+ }, function (val) {
+ if ((typeof val) == 'number') {
+ scope.maxDepth = val;
+ }
+ });
+
+ scope.$watch(function () {
+ return attrs.nodropEnabled;
+ }, function (newVal) {
+ if ((typeof newVal) != 'undefined') {
+ scope.nodropEnabled = true;
+ }
+ }, true);
+
+ attrs.$observe('horizontal', function (val) {
+ scope.horizontal = ((typeof val) != 'undefined');
+ });
+
+ }
+ };
+ }
+ ]);
+})();
+
+(function () {
+ 'use strict';
+
+ angular.module('ui.tree')
+
+ /**
+ * @ngdoc service
+ * @name ui.tree.service:UiTreeHelper
+ * @requires ng.$document
+ * @requires ng.$window
+ *
+ * @description
+ * angular-ui-tree.
+ */
+ .factory('UiTreeHelper', ['$document', '$window', 'treeConfig',
+ function ($document, $window, treeConfig) {
+ return {
+
+ /**
+ * A hashtable used to storage data of nodes
+ * @type {Object}
+ */
+ nodesData: {},
+
+ setNodeAttribute: function (scope, attrName, val) {
+ if (!scope.$modelValue) {
+ return null;
+ }
+ var data = this.nodesData[scope.$modelValue.$$hashKey];
+ if (!data) {
+ data = {};
+ this.nodesData[scope.$modelValue.$$hashKey] = data;
+ }
+ data[attrName] = val;
+ },
+
+ getNodeAttribute: function (scope, attrName) {
+ if (!scope.$modelValue) {
+ return null;
+ }
+ var data = this.nodesData[scope.$modelValue.$$hashKey];
+ if (data) {
+ return data[attrName];
+ }
+ return null;
+ },
+
+ /**
+ * @ngdoc method
+ * @methodOf ui.tree.service:$nodrag
+ * @param {Object} targetElm angular element
+ * @return {Bool} check if the node can be dragged.
+ */
+ nodrag: function (targetElm) {
+ if (typeof targetElm.attr('data-nodrag') != 'undefined') {
+ return targetElm.attr('data-nodrag') !== 'false';
+ }
+ return false;
+ },
+
+ /**
+ * get the event object for touches
+ * @param {[type]} e [description]
+ * @return {[type]} [description]
+ */
+ eventObj: function (e) {
+ var obj = e;
+ if (e.targetTouches !== undefined) {
+ obj = e.targetTouches.item(0);
+ } else if (e.originalEvent !== undefined && e.originalEvent.targetTouches !== undefined) {
+ obj = e.originalEvent.targetTouches.item(0);
+ }
+ return obj;
+ },
+
+ dragInfo: function (node) {
+ return {
+ source: node,
+ sourceInfo: {
+ cloneModel: node.$treeScope.cloneEnabled === true ? angular.copy(node.$modelValue) : undefined,
+ nodeScope: node,
+ index: node.index(),
+ nodesScope: node.$parentNodesScope
+ },
+ index: node.index(),
+ siblings: node.siblings().slice(0),
+ parent: node.$parentNodesScope,
+
+ // Move the node to a new position
+ moveTo: function (parent, siblings, index) {
+ this.parent = parent;
+ this.siblings = siblings.slice(0);
+
+ // If source node is in the target nodes
+ var i = this.siblings.indexOf(this.source);
+ if (i > -1) {
+ this.siblings.splice(i, 1);
+ if (this.source.index() < index) {
+ index--;
+ }
+ }
+
+ this.siblings.splice(index, 0, this.source);
+ this.index = index;
+ },
+
+ parentNode: function () {
+ return this.parent.$nodeScope;
+ },
+
+ prev: function () {
+ if (this.index > 0) {
+ return this.siblings[this.index - 1];
+ }
+
+ return null;
+ },
+
+ next: function () {
+ if (this.index < this.siblings.length - 1) {
+ return this.siblings[this.index + 1];
+ }
+
+ return null;
+ },
+
+ isClone: function () {
+ return this.source.$treeScope.cloneEnabled === true;
+ },
+
+ clonedNode: function (node) {
+ return angular.copy(node);
+ },
+
+ isDirty: function () {
+ return this.source.$parentNodesScope != this.parent ||
+ this.source.index() != this.index;
+ },
+
+ isForeign: function () {
+ return this.source.$treeScope !== this.parent.$treeScope;
+ },
+
+ eventArgs: function (elements, pos) {
+ return {
+ source: this.sourceInfo,
+ dest: {
+ index: this.index,
+ nodesScope: this.parent
+ },
+ elements: elements,
+ pos: pos
+ };
+ },
+
+ apply: function () {
+
+ var nodeData = this.source.$modelValue;
+
+ // nodrop enabled on tree or parent
+ if (this.parent.nodropEnabled || this.parent.$treeScope.nodropEnabled) {
+ return;
+ }
+
+ // node was dropped in the same place - do nothing
+ if (!this.isDirty()) {
+ return;
+ }
+
+ // cloneEnabled and cross-tree so copy and do not remove from source
+ if (this.isClone() && this.isForeign()) {
+ this.parent.insertNode(this.index, this.sourceInfo.cloneModel);
+ } else { // Any other case, remove and reinsert
+ this.source.remove();
+ this.parent.insertNode(this.index, nodeData);
+ }
+ }
+ };
+ },
+
+ /**
+ * @ngdoc method
+ * @name ui.tree#height
+ * @methodOf ui.tree.service:UiTreeHelper
+ *
+ * @description
+ * Get the height of an element.
+ *
+ * @param {Object} element Angular element.
+ * @returns {String} Height
+ */
+ height: function (element) {
+ return element.prop('scrollHeight');
+ },
+
+ /**
+ * @ngdoc method
+ * @name ui.tree#width
+ * @methodOf ui.tree.service:UiTreeHelper
+ *
+ * @description
+ * Get the width of an element.
+ *
+ * @param {Object} element Angular element.
+ * @returns {String} Width
+ */
+ width: function (element) {
+ return element.prop('scrollWidth');
+ },
+
+ /**
+ * @ngdoc method
+ * @name ui.tree#offset
+ * @methodOf ui.nestedSortable.service:UiTreeHelper
+ *
+ * @description
+ * Get the offset values of an element.
+ *
+ * @param {Object} element Angular element.
+ * @returns {Object} Object with properties width, height, top and left
+ */
+ offset: function (element) {
+ var boundingClientRect = element[0].getBoundingClientRect();
+
+ return {
+ width: element.prop('offsetWidth'),
+ height: element.prop('offsetHeight'),
+ top: boundingClientRect.top + ($window.pageYOffset || $document[0].body.scrollTop || $document[0].documentElement.scrollTop),
+ left: boundingClientRect.left + ($window.pageXOffset || $document[0].body.scrollLeft || $document[0].documentElement.scrollLeft)
+ };
+ },
+
+ /**
+ * @ngdoc method
+ * @name ui.tree#positionStarted
+ * @methodOf ui.tree.service:UiTreeHelper
+ *
+ * @description
+ * Get the start position of the target element according to the provided event properties.
+ *
+ * @param {Object} e Event
+ * @param {Object} target Target element
+ * @returns {Object} Object with properties offsetX, offsetY, startX, startY, nowX and dirX.
+ */
+ positionStarted: function (e, target) {
+ var pos = {},
+ pageX = e.pageX,
+ pageY = e.pageY;
+
+ if (e.originalEvent && e.originalEvent.touches && (e.originalEvent.touches.length > 0)) {
+ pageX = e.originalEvent.touches[0].pageX;
+ pageY = e.originalEvent.touches[0].pageY;
+ }
+ pos.offsetX = pageX - this.offset(target).left;
+ pos.offsetY = pageY - this.offset(target).top;
+ pos.startX = pos.lastX = pageX;
+ pos.startY = pos.lastY = pageY;
+ pos.nowX = pos.nowY = pos.distX = pos.distY = pos.dirAx = 0;
+ pos.dirX = pos.dirY = pos.lastDirX = pos.lastDirY = pos.distAxX = pos.distAxY = 0;
+ return pos;
+ },
+
+ positionMoved: function (e, pos, firstMoving) {
+ var pageX = e.pageX,
+ pageY = e.pageY,
+ newAx;
+ if (e.originalEvent && e.originalEvent.touches && (e.originalEvent.touches.length > 0)) {
+ pageX = e.originalEvent.touches[0].pageX;
+ pageY = e.originalEvent.touches[0].pageY;
+ }
+ // mouse position last events
+ pos.lastX = pos.nowX;
+ pos.lastY = pos.nowY;
+
+ // mouse position this events
+ pos.nowX = pageX;
+ pos.nowY = pageY;
+
+ // distance mouse moved between events
+ pos.distX = pos.nowX - pos.lastX;
+ pos.distY = pos.nowY - pos.lastY;
+
+ // direction mouse was moving
+ pos.lastDirX = pos.dirX;
+ pos.lastDirY = pos.dirY;
+
+ // direction mouse is now moving (on both axis)
+ pos.dirX = pos.distX === 0 ? 0 : pos.distX > 0 ? 1 : -1;
+ pos.dirY = pos.distY === 0 ? 0 : pos.distY > 0 ? 1 : -1;
+
+ // axis mouse is now moving on
+ newAx = Math.abs(pos.distX) > Math.abs(pos.distY) ? 1 : 0;
+
+ // do nothing on first move
+ if (firstMoving) {
+ pos.dirAx = newAx;
+ pos.moving = true;
+ return;
+ }
+
+ // calc distance moved on this axis (and direction)
+ if (pos.dirAx !== newAx) {
+ pos.distAxX = 0;
+ pos.distAxY = 0;
+ } else {
+ pos.distAxX += Math.abs(pos.distX);
+ if (pos.dirX !== 0 && pos.dirX !== pos.lastDirX) {
+ pos.distAxX = 0;
+ }
+
+ pos.distAxY += Math.abs(pos.distY);
+ if (pos.dirY !== 0 && pos.dirY !== pos.lastDirY) {
+ pos.distAxY = 0;
+ }
+ }
+
+ pos.dirAx = newAx;
+ },
+
+ elementIsTreeNode: function (element) {
+ return typeof element.attr('ui-tree-node') !== 'undefined';
+ },
+
+ elementIsTreeNodeHandle: function (element) {
+ return typeof element.attr('ui-tree-handle') !== 'undefined';
+ },
+ elementIsTree: function (element) {
+ return typeof element.attr('ui-tree') !== 'undefined';
+ },
+ elementIsTreeNodes: function (element) {
+ return typeof element.attr('ui-tree-nodes') !== 'undefined';
+ },
+ elementIsPlaceholder: function (element) {
+ return element.hasClass(treeConfig.placeholderClass);
+ },
+ elementContainsTreeNodeHandler: function (element) {
+ return element[0].querySelectorAll('[ui-tree-handle]').length >= 1;
+ },
+ treeNodeHandlerContainerOfElement: function (element) {
+ return findFirstParentElementWithAttribute('ui-tree-handle', element[0]);
+ }
+ };
+ }
+ ]);
+
+ // TODO: optimize this loop
+ function findFirstParentElementWithAttribute(attributeName, childObj) {
+ // undefined if the mouse leaves the browser window
+ if (childObj === undefined) {
+ return null;
+ }
+ var testObj = childObj.parentNode,
+ count = 1,
+ // check for setAttribute due to exception thrown by Firefox when a node is dragged outside the browser window
+ res = (typeof testObj.setAttribute === 'function' && testObj.hasAttribute(attributeName)) ? testObj : null;
+ while (testObj && typeof testObj.setAttribute === 'function' && !testObj.hasAttribute(attributeName)) {
+ testObj = testObj.parentNode;
+ res = testObj;
+ if (testObj === document.documentElement) {
+ res = null;
+ break;
+ }
+ count++;
+ }
+
+ return res;
+ }
+
+})();
diff --git a/vid/src/main/webapp/app/vid/scripts/constants/componentConstants.js b/vid/src/main/webapp/app/vid/scripts/constants/componentConstants.js
new file mode 100644
index 000000000..b2a9f0a53
--- /dev/null
+++ b/vid/src/main/webapp/app/vid/scripts/constants/componentConstants.js
@@ -0,0 +1,42 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * 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=========================================================
+ */
+
+"use strict";
+
+app.constant("COMPONENT", (function() {
+ return {
+ NETWORK : "network",
+ SERVICE : "service",
+ VF_MODULE : "vfModule",
+ VNF : "vnf",
+ VOLUME_GROUP : "volumeGroup",
+ FULL_NAME_MAP : {
+ "persona-model-id" : "Model ID",
+ "persona-model-version" : "Model Version"
+ },
+ PARTIAL_NAME_MAP : {
+ "id" : "ID",
+ "uuid" : "UUID",
+ "vfmodule" : "VF Module",
+ "vnf" : "VNF",
+ "volumegroup" : "Volume Group"
+ }
+ };
+})())
diff --git a/vid/src/main/webapp/app/vid/scripts/constants/fieldConstants.js b/vid/src/main/webapp/app/vid/scripts/constants/fieldConstants.js
new file mode 100644
index 000000000..4663ee821
--- /dev/null
+++ b/vid/src/main/webapp/app/vid/scripts/constants/fieldConstants.js
@@ -0,0 +1,182 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * 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=========================================================
+ */
+
+"use strict";
+
+app.factory("FIELD", [ "PARAMETER", function(PARAMETER) {
+
+ /*
+ * ID values are typically used internally.
+ */
+ var ID = {
+ AVAILABLE_VOLUME_GROUP : "availableVolumeGroup",
+ INSTANCE_NAME : "instanceName",
+ LCP_REGION : "lcpRegion",
+ LCP_REGION_TEXT : "lcpRegionText",
+ PRODUCT_FAMILY : "productFamily",
+ SERVICE_TYPE : "serviceType",
+ SUBSCRIBER_NAME : "subscriberName",
+ SUPPRESS_ROLLBACK : "suppressRollback",
+ TENANT : "tenant"
+ };
+
+ var KEY = {
+ LCP_REGION_TEXT : "DEFAULTREGION"
+ };
+
+ /*
+ * NAME values are displayed on GUI pages.
+ */
+ var NAME = {
+ AVAILABLE_VOLUME_GROUP : "Available Volume Group",
+ INSTANCE_NAME : "Instance Name",
+ CUSTOMER_ID : "Customer ID",
+ LCP_REGION : "LCP Region",
+ LCP_REGION_TEXT : "AIC 2.5 Region",
+ MODEL_INVARIANT_UUID: "Model Invariant UUID",
+ MODEL_NAME: "Model Name",
+ MODEL_VERSION: "Model Version",
+ MODEL_UUID: "Model UUID",
+ PRODUCT_FAMILY : "Product Family",
+ RESOURCE_DESCRIPTION : "Resource Description",
+ RESOURCE_NAME : "Resource Name",
+ SERVICE_CATEGORY : "Service Category",
+ SERVICE_DESCRIPTION : "Service Description",
+ SERVICE_INSTANCE_ID : "Service Instance ID",
+ SERVICE_INSTANCE_NAME : "Service Instance Name",
+ SERVICE_INVARIANT_UUID : "Service Invariant UUID",
+ SERVICE_NAME : "Service Name",
+ SERVICE_TYPE : "Service Type",
+ SERVICE_UUID : "Service UUID",
+ SERVICE_VERSION : "Service Version",
+ SUBSCRIBER_NAME : "Subscriber Name",
+ SUPPRESS_ROLLBACK : "Suppress Rollback on Failure",
+ TENANT : "Tenant",
+ USER_SERVICE_INSTANCE_NAME : "User Service Instance Name",
+ VF_MODULE_DESCRIPTION : "VF Module Description",
+ VF_MODULE_LABEL : "VF Module Label",
+ VF_MODULE_TYPE : "VF Module Type"
+ };
+
+ /*
+ * PROMPT values are initial values displayed in select lists.
+ */
+ var PROMPT = {
+ AVAILABLE_VOLUME_GROUP : "Select Volume Group",
+ LCP_REGION : "Select LCP Region",
+ PRODUCT_FAMILY : "Select Product Family",
+ SERVICE_TYPE : "Select Service Type",
+ SUBSCRIBER_NAME : "Select Subscriber Name",
+ TENANT : "Select Tenant Name"
+ };
+
+ /*
+ * PARAMETER values indicate field configurations that are provided to
+ * parameter block directives.
+ */
+
+ var PARAMETER = {
+ AVAILABLE_VOLUME_GROUP : {
+ name : NAME.AVAILABLE_VOLUME_GROUP,
+ id : ID.AVAILABLE_VOLUME_GROUP,
+ type : PARAMETER.SELECT,
+ prompt : PROMPT.AVAILABLE_VOLUME_GROUP,
+ isRequired : true
+ },
+ INSTANCE_NAME : {
+ name : NAME.INSTANCE_NAME,
+ id : ID.INSTANCE_NAME,
+ isRequired : true
+ },
+ LCP_REGION : {
+ name : NAME.LCP_REGION,
+ id : ID.LCP_REGION,
+ type : PARAMETER.SELECT,
+ prompt : PROMPT.LCP_REGION,
+ isRequired : true
+ },
+ LCP_REGION_TEXT_HIDDEN : {
+ id : ID.LCP_REGION_TEXT,
+ isVisible : false
+ },
+ LCP_REGION_TEXT_VISIBLE : {
+ name : NAME.LCP_REGION_TEXT,
+ id : ID.LCP_REGION_TEXT,
+ isRequired : true,
+ isVisible : true
+ },
+ PRODUCT_FAMILY : {
+ name : NAME.PRODUCT_FAMILY,
+ id : ID.PRODUCT_FAMILY,
+ type : PARAMETER.SELECT,
+ prompt : PROMPT.PRODUCT_FAMILY,
+ isRequired : true
+ },
+ SERVICE_TYPE : {
+ name : NAME.SERVICE_TYPE,
+ id : ID.SERVICE_TYPE,
+ type : PARAMETER.SELECT,
+ prompt : PROMPT.SERVICE_TYPE,
+ isRequired : true
+ },
+ SERVICE_TYPE_DISABLED : {
+ name : NAME.SERVICE_TYPE,
+ id : ID.SERVICE_TYPE,
+ type : PARAMETER.SELECT,
+ isEnabled : false,
+ isRequired : true
+ },
+ SUPPRESS_ROLLBACK : {
+ name : NAME.SUPPRESS_ROLLBACK,
+ id : ID.SUPPRESS_ROLLBACK,
+ type : PARAMETER.BOOLEAN,
+ value : false
+ },
+ SUBSCRIBER_NAME : {
+ name : NAME.SUBSCRIBER_NAME,
+ id : ID.SUBSCRIBER_NAME,
+ type : PARAMETER.SELECT,
+ prompt : PROMPT.SUBSCRIBER_NAME,
+ isRequired : true
+ },
+ TENANT_DISABLED : {
+ name : NAME.TENANT,
+ id : ID.TENANT,
+ type : PARAMETER.SELECT,
+ isEnabled : false,
+ isRequired : true
+ },
+ TENANT_ENABLED : {
+ name : NAME.TENANT,
+ id : ID.TENANT,
+ type : PARAMETER.SELECT,
+ isEnabled : true,
+ prompt : PROMPT.TENANT,
+ isRequired : true
+ }
+ };
+
+ return {
+ ID : ID,
+ KEY : KEY,
+ NAME : NAME,
+ PARAMETER : PARAMETER
+ }
+} ]);
diff --git a/vid/src/main/webapp/app/vid/scripts/constants/parameterConstants.js b/vid/src/main/webapp/app/vid/scripts/constants/parameterConstants.js
new file mode 100644
index 000000000..466d188dc
--- /dev/null
+++ b/vid/src/main/webapp/app/vid/scripts/constants/parameterConstants.js
@@ -0,0 +1,29 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * 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=========================================================
+ */
+
+"use strict";
+
+app.constant("PARAMETER", (function() {
+ return {
+ BOOLEAN : "boolean",
+ SELECT : "select",
+ STRING : "string"
+ };
+})())
diff --git a/vid/src/main/webapp/app/vid/scripts/controller/InstantiationController.js b/vid/src/main/webapp/app/vid/scripts/controller/InstantiationController.js
new file mode 100644
index 000000000..fb9baa4b8
--- /dev/null
+++ b/vid/src/main/webapp/app/vid/scripts/controller/InstantiationController.js
@@ -0,0 +1,1028 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * 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=========================================================
+ */
+
+/**
+ * The Instantiation (or View/Edit) Controller controls the instantiation/removal of
+ * deployable objects (Services, VNFs, VF-Modules, Networks, and Volume-Groups)
+ */
+(function () {
+ "use strict";
+
+ app.requires.push('ui.tree');
+
+ app.controller("InstantiationController", function ($scope, $route, $location, $timeout, COMPONENT, DataService, PropertyService, UtilityService, $http, vidService) {
+
+ $scope.popup = new Object();
+ $scope.defaultBaseUrl = "";
+ $scope.responseTimeoutMsec = 60000;
+ $scope.properties = UtilityService.getProperties();
+ $scope.init = function() {
+
+ /*
+ * These 2 statements should be included in non-test code.
+ */
+ // takes a default value, retrieves the prop value from the file system and sets it
+ var msecs = PropertyService.retrieveMsoMaxPollingIntervalMsec(1000);
+ PropertyService.setMsoMaxPollingIntervalMsec(msecs);
+
+ // takes a default value, retrieves the prop value from the file system and sets it
+ var polls = PropertyService.retrieveMsoMaxPolls(7);
+ PropertyService.setMsoMaxPolls(polls);
+
+ //PropertyService.setMsoBaseUrl("testmso");
+ PropertyService.setServerResponseTimeoutMsec(10000);
+
+ /*
+ * Common parameters that shows an example of how the view edit screen
+ * is expected to pass some common service instance values to the
+ * popups.
+ */
+
+// DataService.setSubscriberName("Mobility");
+// DataService.setGlobalCustomerId("CUSTID12345")
+// DataService.setServiceType("Mobility Type 1");
+// DataService.setServiceInstanceName("Example Service Instance Name");
+// DataService.setServiceName("Mobility Service 1");
+// DataService.setServiceInstanceId("mmsc-test-service-instance");
+// DataService.setServiceUuid("XXXX-YYYY-ZZZZ");
+// DataService.setUserServiceInstanceName("USER_SERVICE_INSTANCE_NAME");
+ }
+
+ //PropertyService.setMsoBaseUrl("testmso");
+
+ $scope.convertModel = function(asdcModel) {
+
+ if (!asdcModel) return undefined;
+
+ var convertedAsdcModel = {
+ "service": asdcModel.service,
+ "networks": {},
+ "vnfs": {}
+ };
+
+ for (var networkUuid in asdcModel.networks) {
+ var networkModel = asdcModel.networks[networkUuid];
+ convertedAsdcModel.networks[networkModel.invariantUuid] = {};
+ convertedAsdcModel.networks[networkModel.invariantUuid][networkModel.version] = networkModel;
+ }
+
+ for (var vnfUuid in asdcModel.vnfs) {
+ var vnfModel = asdcModel.vnfs[vnfUuid];
+ convertedAsdcModel.vnfs[vnfModel.invariantUuid] = {};
+ convertedAsdcModel.vnfs[vnfModel.invariantUuid][vnfModel.version] = {
+ "uuid": vnfModel.uuid,
+ "invariantUuid": vnfModel.invariantUuid,
+ "version": vnfModel.version,
+ "name": vnfModel.name,
+ "modelCustomizationName": vnfModel.modelCustomizationName,
+ "inputs": "",
+ "description": vnfModel.description,
+ "vfModules": {},
+ "volumeGroups": {}
+ }
+
+ for (var vfModuleUuid in asdcModel.vnfs[vnfUuid].vfModules) {
+ var vfModuleModel = asdcModel.vnfs[vnfUuid].vfModules[vfModuleUuid];
+ convertedAsdcModel.vnfs[vnfModel.invariantUuid][vnfModel.version].vfModules[vfModuleModel.invariantUuid] = {};
+ convertedAsdcModel.vnfs[vnfModel.invariantUuid][vnfModel.version].vfModules[vfModuleModel.invariantUuid][vfModuleModel.version] = vfModuleModel;
+ }
+
+ for (var volumeGroupUuid in asdcModel.vnfs[vnfUuid].volumeGroups) {
+ var volumeGroupModel = asdcModel.vnfs[vnfUuid].volumeGroups[volumeGroupUuid];
+ convertedAsdcModel.vnfs[vnfModel.invariantUuid][vnfModel.version].volumeGroups[volumeGroupModel.invariantUuid] = {};
+ convertedAsdcModel.vnfs[vnfModel.invariantUuid][vnfModel.version].volumeGroups[volumeGroupModel.invariantUuid][volumeGroupModel.version] = volumeGroupModel;
+ }
+ }
+ console.log ("convertedAsdcModel: "); console.log (JSON.stringify ( convertedAsdcModel, null, 4 ) );
+ return convertedAsdcModel;
+ };
+
+ $scope.service = {
+ "model": vidService.getModel(),
+ "modelByInvariantUuid": $scope.convertModel(vidService.getModel()),
+ "instance": vidService.getInstance()
+ };
+
+ $scope.deleteNetwork = function(serviceObject, network) {
+
+ console.log("Removing Network " + network.name);
+
+ //Send delete network request to MSO
+
+ //var networks = this.service.instance.networks;
+
+ //networks.splice(networks.indexOf(network), 1);
+
+ //Retrieve updated data from A&AI
+ var serviceInstance = serviceObject.object;
+
+ DataService.setInventoryItem(network);
+ DataService.setModelInfo(COMPONENT.NETWORK, $scope.service.model);
+
+ DataService.setSubscriberName(serviceObject['subscriberName']);
+ DataService.setServiceType(serviceObject['serviceType']);
+ DataService.setServiceInstanceId(serviceInstance['service-instance-id']);
+
+ DataService.setGlobalCustomerId(serviceObject['globalCustomerId']);
+ DataService.setServiceInstanceName($scope.service.instance.name);
+
+ //DataService.setServiceName($scope.service.model.name);
+
+ //DataService.setServiceUuid("XXXX-YYYY-ZZZZ");
+ //DataService.setUserServiceInstanceName("USER_SERVICE_INSTANCE_NAME");
+
+ $scope.$broadcast("deleteComponent", {
+ componentId : COMPONENT.NETWORK,
+ callbackFunction : deleteCallbackFunction
+ });
+ };
+
+ $scope.deleteService = function(serviceObject) {
+
+ var serviceInstance = serviceObject.object;
+
+ console.log("Removing Service " + $scope.service.instance.name);
+
+ DataService.setInventoryItem(serviceInstance);
+ //DataService.setModelInfo(COMPONENT.SERVICE, $scope.service.model);
+
+ DataService.setModelInfo(COMPONENT.SERVICE, {
+ "modelInvariantId": $scope.service.model.service.invariantUuid,
+ "modelVersion": $scope.service.model.service.version,
+ "modelNameVersionId": $scope.service.model.service.uuid,
+ "modelCustomizationName": "",
+ "modelName": $scope.service.model.service.name,
+ "inputs": ""
+ });
+
+ DataService.setSubscriberName(serviceObject['subscriberName']);
+ DataService.setServiceType(serviceObject['serviceType']);
+ DataService.setServiceInstanceId(serviceInstance['service-instance-id']);
+
+ DataService.setGlobalCustomerId(serviceObject['globalCustomerId']);
+ DataService.setServiceInstanceName($scope.service.instance.name);
+
+ DataService.setServiceName($scope.service.model.service.name);
+
+ DataService.setServiceUuid($scope.service.model.service.uuid);
+ //DataService.setUserServiceInstanceName("USER_SERVICE_INSTANCE_NAME");
+
+ $scope.$broadcast("deleteComponent", {
+ componentId : COMPONENT.SERVICE,
+ callbackFunction : deleteServiceInstanceCallbackFunction
+ });
+
+ };
+
+ $scope.deleteVfModule = function(serviceObject, vfModule, vnf) {
+
+ console.log("Removing VF-Module " + vfModule.name);
+
+ var serviceInstance = serviceObject.object;
+
+ DataService.setInventoryItem(vfModule.object);
+
+ var svcModel = $scope.service.modelByInvariantUuid;
+ var vnfModelInvariantUuid = vnf.object["persona-model-id"];
+ var vnfModelVersion = vnf.object["persona-model-version"];
+ if (svcModel != null && vnfModelInvariantUuid != null && vnfModelVersion != null )
+ {
+ if ( ( UtilityService.hasContents(svcModel.vnfs) && UtilityService.hasContents(svcModel.vnfs[vnfModelInvariantUuid] ) ) &&
+ ( UtilityService.hasContents(svcModel.vnfs[vnfModelInvariantUuid][vnfModelVersion] ) ) ) {
+ var vnfModel = svcModel.vnfs[vnfModelInvariantUuid][vnfModelVersion];
+
+ // volume groups don't have persona-model-id/version in a&ai.
+ // Their persona-model-id/version is the one for the associated vfModule
+
+ var vfModuleInvariantUuid = vfModule.object["persona-model-id"];
+ var vfModuleModelVersion = vfModule.object["persona-model-version"];
+
+ if ( UtilityService.hasContents(vnfModel) && UtilityService.hasContents(vnfModel.vfModules) && UtilityService.hasContents(vfModuleInvariantUuid) && UtilityService.hasContents(vfModuleModelVersion) )
+ {
+ var vfModelGroupModel = vnfModel.vfModules[vfModuleInvariantUuid][vfModuleModelVersion];
+
+ var vfModeluuid = vfModelGroupModel.uuid;
+ if (vfModeluuid == null)
+ vfModeluuid = "";
+
+ var vnfModelCustomizationName = vnfModel.modelCustomizationName;
+ if (vnfModelCustomizationName == null)
+ vnfModelCustomizationName = "";
+
+ var vfModelName = vfModelGroupModel.name;
+ if (vfModelName == null)
+ vfModelName = "";
+
+ var vfModelVersionID = vfModule.object['vf-module-id'];
+ if (vfModelVersionID == null)
+ vfModelVersionID = "";
+
+ DataService.setModelInfo(COMPONENT.VF_MODULE, {
+ "modelInvariantId": vfModuleInvariantUuid,
+ "modelVersion": vfModuleModelVersion,
+ "modelNameVersionId": vfModeluuid,
+ "modelCustomizationName": vnfModelCustomizationName,
+ "modelName": vfModelName,
+ "inputs": ""
+ });
+
+ DataService.setVnfInstanceId(vnf.object['vnf-id']);
+ DataService.setVfModuleInstanceId(vfModelVersionID);
+
+ DataService.setSubscriberName(serviceObject['subscriberName']);
+ DataService.setServiceType(serviceObject['serviceType']);
+ DataService.setServiceInstanceId(serviceInstance['service-instance-id']);
+
+ DataService.setGlobalCustomerId(serviceObject['globalCustomerId']);
+ DataService.setServiceInstanceName($scope.service.instance.name);
+
+ DataService.setServiceName($scope.service.model.service.name);
+
+ DataService.setServiceUuid($scope.service.model.service.uuid);
+ //DataService.setUserServiceInstanceName("USER_SERVICE_INSTANCE_NAME");
+
+ $scope.$broadcast("deleteComponent", {
+ componentId : COMPONENT.VF_MODULE,
+ callbackFunction : deleteCallbackFunction
+ });
+
+ return;
+ }
+
+ }
+ }
+
+ console.log("Removing VNF " + vnf.name + " could not proceed due to missing ASDC model information.");
+
+
+ //Retrieve updated data from A&AI
+ };
+
+ $scope.deleteVnf = function(serviceObject, vnf) {
+
+ console.log("Removing VNF " + vnf.name);
+
+ var serviceInstance = serviceObject.object;
+
+ DataService.setInventoryItem(vnf.object);
+
+ var vnftype = vnf.object['vnf-type'];
+ if (vnftype == null)
+ vnftype = "";
+ else
+ {
+ var n = vnftype.search("/");
+ if (n >= 0)
+ vnftype = vnftype.substring(n+1);
+ }
+
+
+ var svcModel = $scope.service.modelByInvariantUuid;
+ var vnfModelInvariantUuid = vnf.object["persona-model-id"];
+ var vnfModelVersion = vnf.object["persona-model-version"];
+ if (svcModel != null && vnfModelInvariantUuid != null && vnfModelVersion != null )
+ {
+
+ console.log ( "vnf models: "); console.log ( JSON.stringify ($scope.service.modelByInvariantUuid.vnfs, null, 4) );
+
+ var vnfModel = $scope.service.modelByInvariantUuid.vnfs[vnfModelInvariantUuid][vnfModelVersion];
+ if (vnfModel == null)
+ {
+ DataService.setModelInfo(COMPONENT.VNF, {
+ "modelInvariantId": vnfModelInvariantUuid,
+ "modelVersion": vnfModelVersion,
+ "modelNameVersionId": "",
+ "modelCustomizationName": vnftype,
+ "modelName": "",
+ "inputs": ""
+ });
+ }
+ else
+ {
+ DataService.setModelInfo(COMPONENT.VNF, {
+ "modelInvariantId": vnfModelInvariantUuid,
+ "modelVersion": vnfModelVersion,
+ "modelNameVersionId": vnfModel.uuid,
+ "modelCustomizationName": vnftype,
+ "modelName": vnfModel.name,
+ "inputs": ""
+ });
+ }
+ }
+ else
+ {
+ console.log("Removing VNF name = " + vnf.name + " didn't get the correponding model details so sending empty model values to MSO!");
+ DataService.setModelInfo(COMPONENT.VNF, {
+ "modelInvariantId": "",
+ "modelVersion": "",
+ "modelNameVersionId": "",
+ "modelCustomizationName": vnftype,
+ "modelName": "",
+ "inputs": ""
+ });
+ }
+
+ DataService.setVnfInstanceId(vnf.object['vnf-id']);
+
+ DataService.setSubscriberName(serviceObject['subscriberName']);
+ DataService.setServiceType(serviceObject['serviceType']);
+ DataService.setServiceInstanceId(serviceInstance['service-instance-id']);
+
+ DataService.setGlobalCustomerId(serviceObject['globalCustomerId']);
+ DataService.setServiceInstanceName($scope.service.instance.name);
+
+ DataService.setServiceName($scope.service.model.service.name);
+
+ DataService.setServiceUuid($scope.service.model.service.uuid);
+ //DataService.setUserServiceInstanceName("USER_SERVICE_INSTANCE_NAME");
+
+ $scope.$broadcast("deleteComponent", {
+ componentId : COMPONENT.VNF,
+ callbackFunction : deleteCallbackFunction
+ });
+
+ };
+
+ /*
+ $scope.deleteVnf = function(serviceObject, vnf) {
+
+ console.log("Removing VNF " + vnf.name);
+
+ //Send delete VF-Module request to MSO
+
+ var svcModel = $scope.service.modelByInvariantUuid;
+ var vnfModelInvariantUuid = vnf.object["persona-model-id"];
+ var vnfModelVersion = vnf.object["persona-model-version"];
+ console.log ( "vnf models: "); console.log ( JSON.stringify ($scope.service.modelByInvariantUuid.vnfs, null, 4) );
+
+ DataService.setInventoryItem(vnf);
+
+ var vnfModel = $scope.service.modelByInvariantUuid.vnfs[vnfModelInvariantUuid][vnfModelVersion];
+
+ DataService.setModelInfo(COMPONENT.VNF, {
+ "modelInvariantId": vnfModelInvariantUuid,
+ "modelVersion": vnfModelVersion,
+ "modelNameVersionId": vnfModel.uuid,
+ "modelCustomizationName": vnfModel.modelCustomizationName,
+ "modelName": vnfModel.name,
+ "inputs": vnfModel.inputs
+ });
+
+ DataService.setSubscriberName(serviceObject['globalCustomerId']);
+ DataService.setServiceType(serviceObject['serviceType']);
+ DataService.setServiceInstanceId(serviceObject['service-instance-id']);
+
+ DataService.setGlobalCustomerId(serviceObject['globalCustomerId']);
+ DataService.setServiceInstanceName($scope.service.instance.name);
+
+ DataService.setServiceName(vnf.name);
+
+ DataService.setServiceUuid($scope.service.model.service.uuid);
+ //DataService.setUserServiceInstanceName("USER_SERVICE_INSTANCE_NAME");
+
+ $scope.$broadcast("deleteComponent", {
+ componentId : COMPONENT.VNF,
+ callbackFunction : deleteCallbackFunction
+ });
+
+ //var vnfs = this.service.instance.vnfs;
+
+ //vnfs.splice(vnfs.indexOf(vnf), 1);
+
+ //Retrieve updated data from A&AI
+ };*/
+
+ $scope.deleteVolumeGroup = function(serviceObject, vnf, vfModule, volumeGroup) {
+
+ console.log("Removing Volume Group " + volumeGroup.name);
+ var haveModel = false;
+ var svcModel = $scope.service.modelByInvariantUuid;
+
+ var vnfModelInvariantUuid = vnf.object["persona-model-id"];
+ var vnfModelVersion = vnf.object["persona-model-version"];
+
+ if ( ( UtilityService.hasContents(vnfModelInvariantUuid) ) && (UtilityService.hasContents(vnfModelVersion) ) ) {
+ if ( UtilityService.hasContents(svcModel) && UtilityService.hasContents($scope.service.modelByInvariantUuid.vnfs) ) {
+ //console.log ( "vnf models "); console.log (JSON.stringify ($scope.service.modelByInvariantUuid.vnfs, null, 4) );
+ if ( ( UtilityService.hasContents($scope.service.modelByInvariantUuid.vnfs[vnfModelInvariantUuid] ) ) &&
+ ( UtilityService.hasContents($scope.service.modelByInvariantUuid.vnfs[vnfModelInvariantUuid][vnfModelVersion] ) ) ) {
+ var vnfModel = $scope.service.modelByInvariantUuid.vnfs[vnfModelInvariantUuid][vnfModelVersion];
+
+ // volume groups don't have persona-model-id/version in a&ai.
+ // Their persona-model-id/version is the one for the associated vfModule
+
+ var vfModuleInvariantUuid = vfModule.object["persona-model-id"];
+ var vfModuleModelVersion = vfModule.object["persona-model-version"];
+
+ if ( UtilityService.hasContents(vnfModel.volumeGroups) && UtilityService.hasContents(vfModuleInvariantUuid) && UtilityService.hasContents(vfModuleModelVersion) ) {
+
+ if ( ( UtilityService.hasContents (vnfModel.volumeGroups[vfModuleInvariantUuid]) ) &&
+ (UtilityService.hasContents (vnfModel.volumeGroups[vfModuleInvariantUuid][vfModuleModelVersion]) ) ) {
+ var volGroupModel = vnfModel.volumeGroups[vfModuleInvariantUuid][vfModuleModelVersion];
+
+ DataService.setModelInfo(COMPONENT.VOLUME_GROUP, {
+ "modelInvariantId": vfModuleInvariantUuid,
+ "modelVersion": vfModuleModelVersion,
+ "modelNameVersionId": volGroupModel.uuid,
+ "modelCustomizationName": vnfModel.modelCustomizationName,
+ "modelName": volGroupModel.name,
+ "inputs": ""
+ });
+ haveModel = true;
+
+ }
+ }
+ }
+ }
+ }
+ if ( !haveModel ) {
+ DataService.setModelInfo(COMPONENT.VOLUME_GROUP, {
+ "modelInvariantId": "",
+ "modelVersion": "",
+ "modelNameVersionId": "",
+ "modelCustomizationName": "",
+ "modelName": "",
+ "inputs": ""
+ });
+ }
+
+ var serviceInstance = serviceObject.object;
+
+ DataService.setInventoryItem(volumeGroup.object);
+
+ DataService.setSubscriberName(serviceObject['subscriberName']);
+ DataService.setServiceType(serviceObject['serviceType']);
+ DataService.setServiceInstanceId(serviceInstance['service-instance-id']);
+
+ DataService.setGlobalCustomerId(serviceObject['globalCustomerId']);
+ DataService.setServiceInstanceName($scope.service.instance.name);
+
+ DataService.setServiceName($scope.service.model.service.name);
+
+ DataService.setServiceUuid($scope.service.model.service.uuid);
+ DataService.setVnfInstanceId(vnf.nodeId);
+ DataService.setVolumeGroupInstanceId(volumeGroup.nodeId);
+
+ //DataService.setUserServiceInstanceName("USER_SERVICE_INSTANCE_NAME");
+
+ $scope.$broadcast("deleteComponent", {
+ componentId : COMPONENT.VOLUME_GROUP,
+ callbackFunction : deleteCallbackFunction
+ });
+ };
+
+ $scope.deleteVnfVolumeGroup = function(serviceObject, vnf, volumeGroup) {
+
+ console.log("Removing Volume Group " + volumeGroup.name);
+ var serviceInstance = serviceObject.object;
+
+ DataService.setInventoryItem(volumeGroup.object);
+
+ var svcModel = $scope.service.modelByInvariantUuid;
+ var vnfModelInvariantUuid = vnf.object["persona-model-id"];
+ var vnfModelVersion = vnf.object["persona-model-version"];
+ var vnfModel = null;
+
+ var volGroupModelInvariantUuid = null;
+ var volGroupModelVersion = null;
+
+ // send an empty model by default since model is not required for deletes
+ DataService.setModelInfo(COMPONENT.VOLUME_GROUP, {});
+
+ if ( (volumeGroup.object != null) && ( volumeGroup.object["persona-model-id"] != null ) &&
+ (volumeGroup.object["persona-model-version"] != null) ) {
+
+ volGroupModelInvariantUuid = volumeGroup.object["persona-model-id"];
+ volGroupModelVersion = volumeGroup.object["persona-model-version"];
+
+ if (svcModel != null && vnfModelInvariantUuid != null && vnfModelVersion != null ) {
+ console.log ( "vnf models: "); console.log ( JSON.stringify ($scope.service.modelByInvariantUuid.vnfs, null, 4) );
+ if ( ($scope.service.modelByInvariantUuid.vnfs[vnfModelInvariantUuid] != null) &&
+ ($scope.service.modelByInvariantUuid.vnfs[vnfModelInvariantUuid][vnfModelVersion]) != null ) {
+
+ vnfModel = $scope.service.modelByInvariantUuid.vnfs[vnfModelInvariantUuid][vnfModelVersion];
+ if ( (vnfModel.volumeGroups != null) && ( vnfModel.volumeGroups[volGroupModelInvariantUuid] != null )
+ && ( vnfModel.volumeGroups[volGroupModelInvariantUuid][volGroupModelVersion] != null ) ) {
+
+ var volumeGroupModel = vnfModel.volumeGroups[volGroupModelInvariantUuid][volGroupModelVersion];
+
+ DataService.setModelInfo(COMPONENT.VOLUME_GROUP, {
+ "modelInvariantId": volumeGroupModel.invariantUuid,
+ "modelVersion": volumeGroupModel.version,
+ "modelNameVersionId": volumeGroupModel.uuid,
+ "modelName": volumeGroupModel.name,
+ "modelCustomizationName": volumeGroupModel.modelCustomizationName,
+ "inputs": ""
+ });
+ }
+ }
+ }
+ }
+
+ DataService.setVnfInstanceId(vnf.object['vnf-id']);
+
+ DataService.setSubscriberName(serviceObject['subscriberName']);
+ DataService.setServiceType(serviceObject['serviceType']);
+ DataService.setServiceInstanceId(serviceInstance['service-instance-id']);
+
+ DataService.setGlobalCustomerId(serviceObject['globalCustomerId']);
+ DataService.setServiceInstanceName($scope.service.instance.name);
+
+ DataService.setServiceName($scope.service.model.service.name);
+
+ DataService.setServiceUuid($scope.service.model.service.uuid);
+ DataService.setVnfInstanceId(vnf.nodeId);
+ DataService.setVolumeGroupInstanceId(volumeGroup.nodeId);
+
+ //DataService.setUserServiceInstanceName("USER_SERVICE_INSTANCE_NAME");
+
+ $scope.$broadcast("deleteComponent", {
+ componentId : COMPONENT.VOLUME_GROUP,
+ callbackFunction : deleteCallbackFunction
+ });
+ };
+
+ $scope.describeNetwork = function(serviceObject, networkObject) {
+ var serviceInstance = serviceObject.object;
+ var network = networkObject.object;
+
+ //Display popup with additional network information
+ DataService.setNetworkInstanceId(network['network-id']);
+ DataService.setInventoryItem(network);
+ //DataService.setModelInfo(network['network-id'], network);
+
+ DataService.setSubscriberName(serviceObject['subscriber-name']);
+ DataService.setServiceType(serviceObject['serviceType']);
+ DataService.setServiceInstanceId(serviceInstance['service-instance-id']);
+
+ //DataService.setVnfInstanceId("Testing");
+ $scope.$broadcast("showComponentDetails", {
+ componentId : COMPONENT.NETWORK
+ });
+ };
+
+ // for service instance id - no need for this!
+ $scope.describeService = function(serviceObject) {
+ var serviceInstance = serviceObject.object;
+
+ DataService.setInventoryItem(serviceInstance);
+ //DataService.setModelInfo(serviceInstance['service-instance-id'], serviceInstance);
+
+ DataService.setSubscriberName(serviceObject['subscriberName']);
+ DataService.setServiceType(serviceObject['serviceType']);
+ DataService.setServiceInstanceId(serviceInstance['service-instance-id']);
+
+ //Display popup with additional service information
+ $scope.$broadcast("showComponentDetails", {
+ componentId : COMPONENT.SERVICE
+ });
+
+ };
+
+ $scope.describeVfModule = function(serviceObject, vfModuleObject) {
+ var serviceInstance = serviceObject.object;
+ var vfModule = vfModuleObject.object;
+
+ //Display popup with additional VF-Module information
+ DataService.setVfModuleInstanceId(vfModule['vf-module-id']);
+ DataService.setInventoryItem(vfModule);
+ //DataService.setModelInfo(vfModule['vf-module-id'], vfModule);
+
+ DataService.setSubscriberName(serviceObject['subscriberName']);
+ DataService.setServiceType(serviceObject['serviceType']);
+ DataService.setServiceInstanceId(serviceInstance['service-instance-id']);
+
+ $scope.$broadcast("showComponentDetails", {
+ componentId : COMPONENT.VF_MODULE
+ });
+ };
+
+ $scope.describeVnf = function(serviceObject, vnfObject) {
+ var serviceInstance = serviceObject.object;
+ var vnf = vnfObject.object;
+
+ //Display popup with additional VNF information
+ DataService.setVnfInstanceId(vnf['vnf-id']);
+ DataService.setInventoryItem(vnf);
+ //DataService.setModelInfo(vnf['vnf-id'], vnf);
+
+ DataService.setSubscriberName(serviceObject['subscriberName']);
+ DataService.setServiceType(serviceObject['serviceType']);
+ DataService.setServiceInstanceId(serviceInstance['service-instance-id']);
+
+ $scope.$broadcast("showComponentDetails", {
+ componentId : COMPONENT.VNF
+ });
+ };
+
+ $scope.describeVolumeGroup = function(serviceObject, volumeGroupObject) {
+ var serviceInstance = serviceObject.object;
+ var volumeGroup = volumeGroupObject.object;
+
+ DataService.setVolumeGroupInstanceId(volumeGroup['volume-group-id']);
+ DataService.setInventoryItem(volumeGroup);
+ DataService.setModelInfo(volumeGroup['volume-group-id'], volumeGroup);
+
+ DataService.setSubscriberName(serviceObject['subscriberName']);
+ DataService.setServiceType(serviceObject['serviceType']);
+ DataService.setServiceInstanceId(serviceInstance['service-instance-id']);
+
+ //Display popup with additional Volume Group information
+ //DataService.setVnfInstanceId("Testing");
+ $scope.$broadcast("showComponentDetails", {
+ componentId : COMPONENT.VOLUME_GROUP
+ });
+ };
+
+ $scope.addNetworkInstance = function(network) {
+ console.log("Unsupported in 1610: Adding Network instance of type " + network.name + " to service instance" + this.service.instance.name);
+ };
+
+ $scope.addVnfInstance = function(vnf) {
+ //console.log ("addVnfInstance invoked VNF="); console.log (JSON.stringify (vnf,null,4));
+
+ DataService.setSubscriberName($scope.service.instance.subscriberName);
+ DataService.setGlobalCustomerId($scope.service.instance.globalCustomerId);
+ DataService.setServiceType($scope.service.instance.serviceType);
+ DataService.setServiceInstanceName($scope.service.instance.name);
+ DataService.setServiceInstanceId($scope.service.instance.id);
+ DataService.setServiceName($scope.service.model.service.name);
+
+ DataService.setModelInfo(COMPONENT.VNF, {
+ "modelType": "vnf",
+ "modelInvariantId": vnf.invariantUuid,
+ "modelVersion": vnf.version,
+ "modelNameVersionId": vnf.uuid,
+ "modelName": vnf.name,
+ "modelCustomizationName": vnf.modelCustomizationName,
+ "inputs": ""
+ });
+
+ DataService.setModelInstanceName($scope.service.model.service.name);
+
+ DataService.setModelInfo(COMPONENT.SERVICE, {
+ "modelInvariantId": $scope.service.model.service.invariantUuid,
+ "modelVersion": $scope.service.model.service.version,
+ "modelNameVersionId": $scope.service.model.service.uuid,
+ "modelName": $scope.service.model.service.name,
+ "inputs": ""
+ });
+
+ $scope.$broadcast("createComponent", {
+ componentId : COMPONENT.VNF,
+ callbackFunction : createVnfCallbackFunction
+ });
+ };
+
+ $scope.addVfModuleInstance = function(vnfInstance, vfModuleModel) {
+
+ DataService.setSubscriberName($scope.service.instance.subscriberName);
+ DataService.setGlobalCustomerId($scope.service.instance.globalCustomerId);
+ DataService.setServiceType($scope.service.instance.serviceType);
+ DataService.setServiceInstanceName($scope.service.instance.name);
+ DataService.setServiceInstanceId($scope.service.instance.id);
+ DataService.setServiceName($scope.service.model.service.name);
+
+ var vnfModelInvariantUuid = vnfInstance.object["persona-model-id"];
+ var vnfModelVersion = vnfInstance.object["persona-model-version"];
+ var vnfModel = $scope.service.modelByInvariantUuid.vnfs[vnfModelInvariantUuid][vnfModelVersion];
+
+ var availableVolumeGroupList = [];
+ angular.forEach(vnfInstance["availableVolumeGroups"], function(volumeGroupInstance, key) {
+ availableVolumeGroupList.push({"instance": volumeGroupInstance});
+ });
+
+ if (vfModuleModel.volumeGroupAllowed) {
+ DataService.setAvailableVolumeGroupList(availableVolumeGroupList);
+ }
+
+ DataService.setModelInfo(COMPONENT.SERVICE, {
+ "modelInvariantId": $scope.service.model.service.invariantUuid,
+ "modelVersion": $scope.service.model.service.version,
+ "modelNameVersionId": $scope.service.model.service.uuid,
+ "modelName": $scope.service.model.service.name,
+ "inputs": ""
+ });
+
+ DataService.setVnfInstanceId(vnfInstance.object["vnf-id"]);
+
+ DataService.setModelInfo(COMPONENT.VNF, {
+ "modelInvariantId": vnfModel.invariantUuid,
+ "modelVersion": vnfModel.version,
+ "modelNameVersionId": vnfModel.uuid,
+ "modelName": vnfModel.name,
+ "modelCustomizationName": vnfModel.modelCustomizationName,
+ "inputs": ""
+ });
+
+ DataService.setModelInfo(COMPONENT.VF_MODULE, {
+ "modelInvariantId": vfModuleModel.invariantUuid,
+ "modelVersion": vfModuleModel.version,
+ "modelNameVersionId": vfModuleModel.uuid,
+ "modelName": vfModuleModel.name,
+ "inputs": ""
+ });
+
+ $scope.$broadcast("createComponent", {
+ componentId : COMPONENT.VF_MODULE,
+ callbackFunction : createVfModuleCallbackFunction
+ });
+
+ };
+
+ $scope.addVolumeGroupInstance = function(vnfInstance, volumeGroupModel) {
+
+ DataService.setSubscriberName($scope.service.instance.subscriberName);
+ DataService.setGlobalCustomerId($scope.service.instance.globalCustomerId);
+ DataService.setServiceType($scope.service.instance.serviceType);
+ DataService.setServiceInstanceName($scope.service.instance.name);
+ DataService.setServiceInstanceId($scope.service.instance.id);
+ DataService.setServiceName($scope.service.model.service.name);
+
+ DataService.setModelInfo(COMPONENT.SERVICE, {
+ "modelInvariantId": $scope.service.model.service.invariantUuid,
+ "modelVersion": $scope.service.model.service.version,
+ "modelNameVersionId": $scope.service.model.service.uuid,
+ "modelName": $scope.service.model.service.name,
+ "inputs": ""
+ });
+
+ DataService.setVnfInstanceId(vnfInstance.object["vnf-id"]);
+
+ var vnfModelInvariantUuid = vnfInstance.object["persona-model-id"];
+ var vnfModelVersion = vnfInstance.object["persona-model-version"];
+ var vnfModel = $scope.service.modelByInvariantUuid.vnfs[vnfModelInvariantUuid][vnfModelVersion];
+
+ DataService.setModelInfo(COMPONENT.VNF, {
+ "modelInvariantId": vnfModel.invariantUuid,
+ "modelVersion": vnfModel.version,
+ "modelNameVersionId": vnfModel.uuid,
+ "modelName": vnfModel.name,
+ "modelCustomizationName": vnfModel.modelCustomizationName,
+ "inputs": ""
+ });
+
+ DataService.setModelInfo(COMPONENT.VOLUME_GROUP, {
+ "modelInvariantId": volumeGroupModel.invariantUuid,
+ "modelVersion": volumeGroupModel.version,
+ "modelNameVersionId": volumeGroupModel.uuid,
+ "modelName": volumeGroupModel.name,
+ "inputs": ""
+ });
+
+ $scope.$broadcast("createComponent", {
+ componentId : COMPONENT.VOLUME_GROUP,
+ callbackFunction : createVolumeGroupCallbackFunction
+ });
+ };
+
+ $scope.attachVolumeGroupInstance = function(vfModuleInstance, volumeGroupInstance) {
+
+ var vnfInstance = this.vnf;
+ var vnfModelInvariantUuid = vnfInstance.object["persona-model-id"];
+ var vnfModelVersion = vnfInstance.object["persona-model-version"];
+ var vnfModel = $scope.service.modelByInvariantUuid.vnfs[vnfModelInvariantUuid][vnfModelVersion];
+
+ var vfModuleModelInvariantUuid = vfModuleInstance.object["persona-model-id"];
+ var vfModuleVersion = vfModuleInstance.object["persona-model-version"];
+ var vfModuleModel = vnfModel.vfModules[vfModuleModelInvariantUuid][vfModuleVersion];
+
+ var volumeGroupModelInvariantUuid = volumeGroupInstance.object["persona-model-id"];
+ var volumeGroupModelVersion = volumeGroupInstance.object["persona-model-version"];
+ var volumeGroupModel = vnfModel.volumeGroups[volumeGroupModelInvariantUuid][volumeGroupModelVersion];
+
+ if (vfModuleModel.uuid != volumeGroupModel.uuid) alert("Cannot attach this volume group to this VF module (models do not match)");
+
+ DataService.setSubscriberName($scope.service.instance.subscriberName);
+ DataService.setGlobalCustomerId($scope.service.instance.globalCustomerId);
+ DataService.setServiceName($scope.service.model.name);
+ DataService.setServiceType($scope.service.instance.serviceType);
+ DataService.setServiceInstanceName($scope.service.instance.name);
+ DataService.setServiceInstanceId($scope.service.instance.id);
+
+ DataService.setModelInfo(COMPONENT.SERVICE, {
+ "modelInvariantId": $scope.service.model.service.invariantUuid,
+ "modelVersion": $scope.service.model.service.version,
+ "modelNameVersionId": $scope.service.model.service.uuid,
+ "modelName": $scope.service.model.service.name,
+ "inputs": ""
+ });
+
+ DataService.setVnfInstanceId(vnfInstance.object["vnf-id"]);
+
+ DataService.setModelInfo(COMPONENT.VNF, {
+ "modelInvariantId": vnfModel.invariantUuid,
+ "modelVersion": vnfModel.version,
+ "modelNameVersionId": vnfModel.uuid,
+ "modelName": vnfModel.name,
+ "modelCustomizationName": vnfModel.modelCustomizationName,
+ "inputs": ""
+ });
+
+ DataService.setModelInfo(COMPONENT.VOLUME_GROUP, {
+ "modelInvariantId": volumeGroupModel.invariantUuid,
+ "modelVersion": volumeGroupModel.version,
+ "modelNameVersionId": volumeGroupModel.uuid,
+ "modelName": volumeGroupModel.name,
+ "inputs": ""
+ });
+
+ $scope.$broadcast("createComponent", {
+ componentId : COMPONENT.VOLUME_GROUP,
+ callbackFunction : createVolumeGroupCallbackFunction
+ });
+ /*
+ * Code to manipulate the angular ui-tree
+ var volumeGroups = this.vnf.volumeGroups;
+ volumeGroups.splice(volumeGroups.indexOf(volumeGroup), 1);
+ vfModule.volumeGroups.push(volumeGroup);
+ */
+ };
+
+ $scope.resetProgress = function() {
+ $scope.percentProgress = 0;
+ $scope.progressClass = "progress-bar progress-bar-info";
+ };
+
+ $scope.setProgress = function(percentProgress) {
+ percentProgress = parseInt(percentProgress);
+ if (percentProgress >= 100) {
+ $scope.progressClass = "progress-bar progress-bar-success";
+ }
+
+ if (percentProgress < $scope.percentProgress) {
+ return;
+ }
+
+ $scope.percentProgress = percentProgress;
+ $scope.progressWidth = {width: percentProgress + "%"};
+ if (percentProgress >= 5) {
+ $scope.progressText = percentProgress + " %";
+ } else {
+ // Hidden since color combination is barely visible when progress portion is narrow.
+ $scope.progressText = "";
+ }
+ };
+
+ $scope.reloadRoute = function() {
+ $route.reload();
+ }
+
+ var createVnfCallbackFunction = function(response) {
+ $scope.callbackResults = "";
+ var color = "none";
+ $scope.callbackStyle = {
+ "background-color" : color
+ };
+
+ /*
+ * This 1/2 delay was only added to visually highlight the status
+ * change. Probably not needed in the real application code.
+ */
+ $timeout(function() {
+ $scope.callbackResults = UtilityService.getCurrentTime()
+ + " isSuccessful: " + response.isSuccessful;
+ if (response.isSuccessful) {
+ color = "#8F8";
+ $scope.reloadRoute();
+ } else {
+ color = "#F88";
+ }
+ $scope.callbackStyle = {
+ "background-color" : color
+ };
+ }, 500);
+
+
+
+ };
+
+ var deleteCallbackFunction = function(response) {
+ $scope.callbackResults = "";
+ var color = "none";
+ $scope.callbackStyle = {
+ "background-color" : color
+ };
+
+ /*
+ * This 1/2 delay was only added to visually highlight the status
+ * change. Probably not needed in the real application code.
+ */
+ $timeout(function() {
+ $scope.callbackResults = UtilityService.getCurrentTime()
+ + " isSuccessful: " + response.isSuccessful;
+ if (response.isSuccessful) {
+ color = "#8F8";
+ $scope.reloadRoute();
+ } else {
+ color = "#F88";
+ }
+ $scope.callbackStyle = {
+ "background-color" : color
+ };
+ }, 500);
+
+ };
+
+ var createVfModuleCallbackFunction = function(response) {
+ $scope.callbackResults = "";
+ var color = "none";
+ $scope.callbackStyle = {
+ "background-color" : color
+ };
+
+ /*
+ * This 1/2 delay was only added to visually highlight the status
+ * change. Probably not needed in the real application code.
+ */
+ $timeout(function() {
+ $scope.callbackResults = UtilityService.getCurrentTime()
+ + " isSuccessful: " + response.isSuccessful;
+ if (response.isSuccessful) {
+ color = "#8F8";
+ $scope.reloadRoute();
+ } else {
+ color = "#F88";
+ }
+ $scope.callbackStyle = {
+ "background-color" : color
+ };
+ }, 500);
+
+ };
+
+ var deleteServiceInstanceCallbackFunction = function(response) {
+ $scope.callbackResults = "";
+ var color = "none";
+ $scope.callbackStyle = {
+ "background-color" : color
+ };
+
+ /*
+ * This 1/2 delay was only added to visually highlight the status
+ * change. Probably not needed in the real application code.
+ */
+ $timeout(function() {
+ $scope.callbackResults = UtilityService.getCurrentTime()
+ + " isSuccessful: " + response.isSuccessful;
+ if (response.isSuccessful) {
+ color = "#8F8";
+ $location.path("/instances/services")
+ } else {
+ color = "#F88";
+ }
+ $scope.callbackStyle = {
+ "background-color" : color
+ };
+ }, 500);
+
+ };
+
+ var createVolumeGroupCallbackFunction = function(response) {
+ $scope.callbackResults = "";
+ var color = "none";
+ $scope.callbackStyle = {
+ "background-color" : color
+ };
+
+ /*
+ * This 1/2 delay was only added to visually highlight the status
+ * change. Probably not needed in the real application code.
+ */
+ $timeout(function() {
+ $scope.callbackResults = UtilityService.getCurrentTime()
+ + " isSuccessful: " + response.isSuccessful;
+ if (response.isSuccessful) {
+ color = "#8F8";
+ $scope.reloadRoute();
+ } else {
+ color = "#F88";
+ }
+ $scope.callbackStyle = {
+ "background-color" : color
+ };
+ }, 500);
+
+
+
+ };
+
+ });
+})();
diff --git a/vid/src/main/webapp/app/vid/scripts/controller/ServiceModelController.js b/vid/src/main/webapp/app/vid/scripts/controller/ServiceModelController.js
new file mode 100644
index 000000000..855c23dde
--- /dev/null
+++ b/vid/src/main/webapp/app/vid/scripts/controller/ServiceModelController.js
@@ -0,0 +1,196 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * 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=========================================================
+ */
+
+(function () {
+ 'use strict';
+
+ app.controller("ServiceModelController", function ($scope, $http, $location, COMPONENT, DataService, vidService,
+ PropertyService) {
+
+ $scope.popup = {};
+ var re = /.*?:\/\/.*?:.*?\/(.*?)\//g;
+ var baseEndpoint = re.exec($location.absUrl())[1];
+
+ $scope.getServiceModels = function() {
+ $scope.status = "Fetching service catalog from ASDC. Please wait.";
+ $http.get('/' + baseEndpoint + '/rest/models/services?distributionStatus=DISTRIBUTED')
+ .then(function(response) {
+ $scope.services = [];
+ if (angular.isArray(response.data)) {
+ $scope.services = response.data;
+ $scope.viewPerPage=10;
+ $scope.totalPage=$scope.services.length/$scope.viewPerPage;
+ $scope.sortBy="name";
+ $scope.scrollViewPerPage=2;
+ $scope.currentPage=1;
+ $scope.searchCategory;
+ $scope.searchString="";
+ $scope.currentPageNum=1;
+ $scope.isSpinnerVisible = false;
+ $scope.isProgressVisible = false;
+ } else {
+ $scope.status = "Failed to get service models from ASDC.";
+ $scope.error = true;
+ $scope.isSpinnerVisible = false;
+ }
+ }, function (response) {
+ console.log("Error: " + response);
+ });
+ }
+ $scope.init = function() {
+ // takes a default value, retrieves the prop value from the file system and sets it
+ var msecs = PropertyService.retrieveMsoMaxPollingIntervalMsec(1000);
+ PropertyService.setMsoMaxPollingIntervalMsec(msecs);
+
+ // takes a default value, retrieves the prop value from the file system and sets it
+ var polls = PropertyService.retrieveMsoMaxPolls(7);
+ PropertyService.setMsoMaxPolls(polls);
+
+ //PropertyService.setMsoBaseUrl("testmso");
+ PropertyService.setServerResponseTimeoutMsec(10000);
+ }
+
+ $scope.prevPage = function() {
+ $scope.currentPage--;
+ }
+
+ $scope.nextPage = function() {
+ $scope.currentPage++;
+ }
+
+ $scope.deployService = function(service) {
+
+ console.log("Instantiating ASDC service " + service.uuid);
+
+ $http.get('/' + baseEndpoint + '/rest/models/services/' + service.uuid)
+ .then(function successCallback(getServiceResponse) {
+
+ var serviceModel = getServiceResponse.data;
+ DataService.setServiceName(serviceModel.service.name);
+
+ DataService.setModelInfo(COMPONENT.SERVICE, {
+ "modelInvariantId": serviceModel.service.invariantUuid,
+ "modelVersion": serviceModel.service.version,
+ "modelNameVersionId": serviceModel.service.uuid,
+ "modelName": serviceModel.service.name,
+ "description": serviceModel.service.description,
+ "category":serviceModel.service.category
+ });
+
+ $scope.$broadcast("createComponent", {
+ componentId : COMPONENT.SERVICE,
+ callbackFunction : function(response) {
+ if (response.isSuccessful) {
+ vidService.setModel(serviceModel);
+
+ var subscriberId = "Not Found";
+ var serviceType = "Not Found";
+
+ var serviceInstanceId = response.instanceId;
+
+ for (var i = 0; i < response.control.length; i++) {
+ if (response.control[i].id == "subscriberName") {
+ subscriberId = response.control[i].value;
+ } else if (response.control[i].id == "serviceType") {
+ serviceType = response.control[i].value;
+ }
+ }
+
+
+ $scope.refreshSubs(subscriberId,serviceType,serviceInstanceId);
+
+ }
+ }
+ });
+
+ }, function errorCallback(response) {
+ console.log("Error: " + response);
+ });
+ };
+
+ $scope.refreshSubs = function(subscriberId, serviceType, serviceInstanceId) {
+ $scope.status = "Fetching subscriber list from A&AI...";
+ $scope.init();
+ $http.get( PropertyService.getAaiBaseUrl() + "/aai_refresh_full_subscribers", {
+
+ },{
+ timeout: $scope.responseTimeoutMsec
+ }).then(function(response){
+
+ if (response.data.status < 200 || response.data.status > 202) {
+ $scope.showError("MSO failure - see log below for details")
+ return;
+ }
+
+ $scope.customer = response.data.customer; // get data from json
+
+ $scope.customerList = [];
+
+ $scope.serviceInstanceToCustomer = [];
+
+ angular.forEach($scope.customer, function(subVal, subKey) {
+ var cust = { "globalCustomerId": subVal["global-customer-id"], "subscriberName": subVal["subscriber-name"] };
+ $scope.customerList.push(cust);
+ if (subVal["service-subscriptions"] != null) {
+ angular.forEach(subVal["service-subscriptions"]["service-subscription"], function(serviceSubscription, key) {
+ $scope.serviceInstanceId = [];
+ if (serviceSubscription["service-type"] != null) {
+ $scope.serviceType = serviceSubscription["service-type"];
+ } else {
+ $scope.serviceType = "No Service Subscription Found";
+ }
+ if (serviceSubscription["service-instances"] != null) {
+ angular.forEach(serviceSubscription["service-instances"]["service-instance"], function(instValue, instKey) {
+ var foo = { "serviceInstanceId": instValue["service-instance-id"],
+ "globalCustomerId": subVal["global-customer-id"],
+ "subscriberName": subVal["subscriber-name"] };
+ $scope.serviceInstanceToCustomer.push(foo);
+ });
+ }
+ });
+ }
+ });
+ DataService.setServiceInstanceToCustomer($scope.serviceInstanceToCustomer);
+ var serviceIdList = [];
+ $http.get(PropertyService.getAaiBaseUrl() + "/aai_get_services", {
+ },{
+ timeout: $scope.responseTimeoutMsec
+ }).then(function(response) {
+ angular.forEach(response.data, function(value, key) {
+ angular.forEach(value, function(subVal, key) {
+ var newVal = { "id" : subVal["service-id"], "description" : subVal["service-description"] };
+ serviceIdList.push(newVal);
+ DataService.setServiceIdList(serviceIdList);
+
+ $location.search({
+ "subscriberId": subscriberId,
+ "serviceType": serviceType,
+ "serviceInstanceId": serviceInstanceId
+ });
+
+ $location.path("/instantiate");
+ });
+ });
+ });
+ })
+ ["catch"]($scope.handleServerError);
+ };
+ });
+})();
diff --git a/vid/src/main/webapp/app/vid/scripts/controller/VidApp.js b/vid/src/main/webapp/app/vid/scripts/controller/VidApp.js
new file mode 100644
index 000000000..acc185cf8
--- /dev/null
+++ b/vid/src/main/webapp/app/vid/scripts/controller/VidApp.js
@@ -0,0 +1,67 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * 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=========================================================
+ */
+
+(function () {
+ 'use strict';
+
+ app.config(['$routeProvider', '$locationProvider', function ($routeProvider) {
+ $routeProvider
+ .when('/models/services', {
+ controller: 'ServiceModelController',
+ templateUrl: 'app/vid/scripts/view-models/serviceModels.htm'
+ })
+ .when('/instances/services', {
+ templateUrl : "app/vid/scripts/view-models/aaiGetSubs.htm",
+ controller : "aaiSubscriberController"
+ })
+ .when('/instances/subdetails', {
+ templateUrl : "app/vid/scripts/view-models/aaiSubDetails.htm",
+ controller : "aaiSubscriberController"
+ })
+ .when('/instantiate', {
+ controller: 'InstantiationController',
+ templateUrl: 'app/vid/scripts/view-models/instantiate.htm'
+ })
+ .otherwise({
+ redirectTo: '/models/services'
+ });
+ }]);
+
+ app.service('vidService', function() {
+ var _model = undefined;
+ var _instance = undefined;
+
+ this.setModel = function(model) {
+ _model = model;
+ };
+
+ this.getModel = function() {
+ return _model;
+ };
+
+ this.setInstance = function(instance) {
+ _instance = instance;
+ };
+
+ this.getInstance = function() {
+ return _instance;
+ };
+ });
+})();
diff --git a/vid/src/main/webapp/app/vid/scripts/controller/aaiSubscriberController.js b/vid/src/main/webapp/app/vid/scripts/controller/aaiSubscriberController.js
new file mode 100644
index 000000000..aa3b5223a
--- /dev/null
+++ b/vid/src/main/webapp/app/vid/scripts/controller/aaiSubscriberController.js
@@ -0,0 +1,763 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * 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=========================================================
+ */
+
+"use strict";
+
+app.controller("aaiSubscriberController", [ "COMPONENT", "DataService", "PropertyService", "$scope", "$http", "$timeout", "$location", "$log", "$route", "UtilityService", "vidService",
+ function(COMPONENT, DataService, PropertyService, $scope, $http, $timeout, $location, $log, $route, UtilityService, vidService) {
+
+ $scope.showVnfDetails = function(vnf) {
+ console.log("showVnfDetails");
+ DataService.setVnfInstanceId("VNF_INSTANCE_ID_12345");
+ DataService
+ .setInventoryItem(aaiResult["inventory-response-items"]["inventory-response-item"][0]);
+
+ $scope.$broadcast("showComponentDetails", {
+ componentId : COMPONENT.VNF,
+ callbackFunction : callbackFunction
+ });
+ }
+ $scope.popup = new Object();
+
+
+ $scope.isPopupVisible = false;
+ $scope.defaultBaseUrl = "";
+ $scope.responseTimeoutMsec = 60000;
+
+ $scope.serviceTypes=[ "Select a service type" ];
+ $scope.defaultSubscriberName=[ "Select a subscriber name" ];
+
+ var callbackFunction = function(response) {
+ alert(response);
+ };
+
+ $scope.getSubs = function() {
+ $scope.status = "Fetching subscriber list from A&AI...";
+ $scope.init();
+ $http.get( PropertyService.getAaiBaseUrl() + "/aai_get_full_subscribers" + '?r=' + Math.random(), {
+
+ },{
+ timeout: $scope.responseTimeoutMsec
+ }).then($scope.handleInitialResponse)
+ ["catch"]($scope.handleServerError);
+ var serviceIdList = [];
+ $http.get(PropertyService.getAaiBaseUrl() + "/aai_get_services" + '?r=' + Math.random(), {
+ },{
+ timeout: $scope.responseTimeoutMsec
+ }).then(function(response) {
+ angular.forEach(response.data, function(value, key) {
+ angular.forEach(value, function(subVal, key) {
+ var newVal = { "id" : subVal["service-id"], "description" : subVal["service-description"] };
+ serviceIdList.push(newVal);
+ DataService.setServiceIdList(serviceIdList);
+ });
+ });
+ });
+ };
+
+ $scope.refreshSubs = function() {
+ $scope.status = "Fetching subscriber list from A&AI...";
+ $scope.init();
+ $http.get(PropertyService.getAaiBaseUrl() + "/aai_refresh_full_subscribers" + '?r=' + Math.random(), {
+
+ },{
+ timeout: $scope.responseTimeoutMsec
+ }).then($scope.handleInitialResponse)
+ ["catch"]($scope.handleServerError);
+ };
+
+ $scope.getSubDetails = function(request) {
+
+ $scope.init();
+ $scope.selectedSubscriber = $location.search().selectedSubscriber;
+ $scope.selectedServiceInstance = $location.search().selectedServiceInstance;
+ $scope.status = "Fetching subscriber details from A&AI for " + $scope.selectedSubscriber;
+ $http.get(PropertyService.getAaiBaseUrl() + "/aai_sub_details/" + $scope.selectedSubscriber + '?r=' + Math.random(), {
+
+ },{
+ timeout: $scope.responseTimeoutMsec
+ }).then(function(response) {
+ $scope.subscriber = response.data;
+ $scope.selectedSubscriberName = $scope.subscriber["subscriber-name"];
+
+ $scope.displayData= [];
+ if ($scope.subscriber["service-subscriptions"] != null) {
+ angular.forEach($scope.subscriber["service-subscriptions"]["service-subscription"], function(serviceSubscription, key) {
+ $scope.serviceInstanceId = [];
+ if (serviceSubscription["service-type"] != null) {
+ $scope.serviceType = serviceSubscription["service-type"];
+ } else {
+ $scope.serviceType = "No Service Subscription Found";
+ }
+ if (serviceSubscription["service-instances"] != null) {
+ angular.forEach(serviceSubscription["service-instances"]["service-instance"], function(instValue, instKey) {
+ // put them together, i guess
+ var inst = { "serviceInstanceId": instValue["service-instance-id"],
+ "personaModelId": instValue["persona-model-id"],
+ "personaModelVersion": instValue["persona-model-version"],
+ "serviceInstanceName": instValue["service-instance-name"]
+ };
+ if ($scope.selectedServiceInstance != null) {
+ if (instValue["service-instance-id"] == $scope.selectedServiceInstance) {
+ $scope.serviceInstanceId.push(inst);
+ }
+ } else {
+ $scope.serviceInstanceId.push(inst);
+ }
+ });
+ } else {
+ if ($scope.serviceInstanceId == []) {
+ $scope.serviceInstanceId = [ "No Service Instance Found" ];
+ }
+ }
+ angular.forEach($scope.serviceInstanceId, function(subVal, subKey) {
+ $scope.displayData.push({
+ globalCustomerId : $scope.selectedSubscriber,
+ subscriberName : $scope.selectedSubscriberName,
+ serviceType : $scope.serviceType,
+ serviceInstanceId : subVal.serviceInstanceId,
+ personaModelId : subVal.personaModelId,
+ personaModelVersion : subVal.personaModelVersion,
+ serviceInstanceName : subVal.serviceInstanceName
+ });
+ });
+ });
+ } else {
+ $scope.displayData.push({
+ globalCustomerId : $scope.selectedSubscriber,
+ subscriberName : $scope.selectedSubscriberName,
+ serviceType : "No Service Subscription Found",
+ serviceInstanceId : "No Service Instance Found"
+ });
+ }
+ $scope.viewPerPage=10;
+ $scope.totalPage=$scope.displayData.length/$scope.viewPerPage;
+ $scope.scrollViewPerPage=2;
+ $scope.currentPage=1;
+ $scope.searchCategory;
+ $scope.searchString="";
+ $scope.currentPageNum=1;
+ $scope.defaultSort="subscriberName"
+ $scope.setProgress(100); // done
+ $scope.status = "Done";
+ $scope.isSpinnerVisible = false;
+ });
+ }
+
+
+ $scope.$on("deleteInstance", function(event, request) {
+ // $log.debug("deleteInstance: request:");
+ // $log.debug(request);
+ $scope.init();
+ // Use this line instead of the subsequent $http.post to change from POST to DELETE
+ // $http["delete"]($scope.baseUrl + request.url,{timeout: $scope.responseTimeoutMsec}).then($scope.requestOkay
+ $http.post($scope.baseUrl + request.url, {
+ requestDetails: request.requestDetails
+ },{
+ timeout: $scope.responseTimeoutMsec
+ }).then($scope.handleInitialResponse)
+ ["catch"]($scope.handleServerError);
+ });
+
+ $scope.init = function() {
+
+ //PropertyService.setAaiBaseUrl("testaai");
+ //PropertyService.setAsdcBaseUrl("testasdc");
+
+ // takes a default value, retrieves the prop value from the file system and sets it
+ var msecs = PropertyService.retrieveMsoMaxPollingIntervalMsec(1000);
+ PropertyService.setMsoMaxPollingIntervalMsec(msecs);
+
+ // takes a default value, retrieves the prop value from the file system and sets it
+ var polls = PropertyService.retrieveMsoMaxPolls(7);
+ PropertyService.setMsoMaxPolls(polls);
+
+ //PropertyService.setMsoBaseUrl("testmso");
+ PropertyService.setServerResponseTimeoutMsec(10000);
+
+ /*
+ * Common parameters that would typically be set when the page is
+ * displayed for a specific service instance id.
+ */
+
+// DataService.setSubscriberName("Mobility");
+// DataService.setGlobalCustomerId("CUSTID12345")
+// DataService.setServiceType("Mobility Type 1");
+// DataService.setServiceName("Mobility Service 1");
+// DataService.setServiceInstanceId("mmsc-test-service-instance");
+
+ $scope.baseUrl = $scope.defaultBaseUrl;
+
+ $scope.isSpinnerVisible = true;
+ $scope.isProgressVisible = true;
+ $scope.isPopupVisible = true;
+ $scope.requestId = "";
+ $scope.error = "";
+ $scope.pollAttempts = 0;
+ $scope.log = "";
+ $scope.enableCloseButton(false);
+ $scope.resetProgress();
+ $scope.setProgress(2); // Show "a little" progress
+ }
+
+ $scope.getComponentList = function(event, request) {
+
+ $scope.isSpinnerVisible = true;
+ $scope.isProgressVisible = true;
+ $scope.isPopupVisible = true;
+ $scope.requestId = "";
+ $scope.error = "";
+ $scope.pollAttempts = 0;
+ $scope.log = "";
+
+ $scope.resetProgress();
+ $scope.setProgress(2); // Show "a little" progress
+
+ //subscriberId=jimmy-testing&serviceType=gamma-01%2F1&serviceInstanceId=jimmy2-01%2F01%2F%2F01
+ $scope.globalCustomerId = $location.search().subscriberId;
+ $scope.serviceType = $location.search().serviceType;
+ $scope.serviceInstanceId = $location.search().serviceInstanceId;
+
+ //$scope.getAsdcModel($location.search().modelUuid);
+
+ // this should be in a config file?
+ $scope.namedQueryId = "ed0a0f5b-cf79-4784-88b2-911cd726cd3d";
+ $scope.url = PropertyService.getAaiBaseUrl() + "/aai_sub_viewedit" +
+ "/" + encodeURIComponent($scope.namedQueryId) +
+ "/" + encodeURIComponent($scope.globalCustomerId) +
+ "/" + encodeURIComponent($scope.serviceType) +
+ "/" + encodeURIComponent($scope.serviceInstanceId) + '?r=' + Math.random();
+
+ $scope.status = "Fetching service instance data from A&AI for service-instance-id=" + $scope.serviceInstanceId;
+ $http.get($scope.url, {
+ },{
+ timeout: $scope.responseTimeoutMsec
+ }).then($scope.handleInitialResponseInventoryItems)
+ ["catch"]($scope.handleServerError);
+ }
+
+ $scope.handleServerError = function(response, status) {
+ alert(response.statusText);
+ }
+
+ $scope.getAsdcModel = function(disData) {
+ $http.get(PropertyService.getAaiBaseUrl() + '/rest/models/services')
+ .then(function successCallback(response) {
+ var myUuid = null;
+ var lastVersion = -1;
+ angular.forEach(response.data, function(model, key) {
+ if (angular.equals(model.invariantUUID,disData.personaModelId)) {
+ if (model.version > lastVersion) {
+ lastVersion = model.version;
+ myUuid = model.uuid;
+ }
+
+ }
+ });
+ if (myUuid == null)
+ {
+ console.log("aaiSubscriber getAsdcModel - No matching model found matching the persona Model Id = " + disData.personaModelId);
+ }
+ else
+ {
+ console.log(myUuid);
+ $http.get(PropertyService.getAaiBaseUrl() + '/rest/models/services/' + myUuid)
+ .then(function successCallback(response2) {
+ vidService.setModel(response2.data);
+ window.location.href = "#/instantiate?subscriberId=" + disData.globalCustomerId + "&serviceType=" + disData.serviceType + "&serviceInstanceId=" + disData.serviceInstanceId;
+ console.log("aaiSubscriber getAsdcModel DONE!!!!");
+ });
+ }
+ }, function errorCallback(response) {
+ //TODO
+ });
+ }
+
+ $scope.getTenants = function(globalCustomerId) {
+ $http.get(PropertyService.getAaiBaseUrl() + '/aai_get_tenants' + globalCustomerId + '?r=' + Math.random())
+ .then(function successCallback(response) {
+ return response.data;
+ //$location.path("/instantiate");
+ }, function errorCallback(response) {
+ //TODO
+ });
+ }
+
+ $scope.handleInitialResponseInventoryItems = function(response) {
+ // $log.debug("handleInitialResponse: response contents:");
+ // $log.debug(response);
+ try {
+
+ if (response.status < 200 || response.status > 202) {
+ $scope.handleServerError(response, response.status);
+ return;
+ }
+
+ $scope.inventoryResponseItemList = response.data["inventory-response-item"]; // get data from json
+ console.log($scope.inventoryResponseItemList.toString());
+
+ $scope.displayData = [];
+ $scope.vnfs = [];
+
+ $scope.counter = 100;
+
+ angular.forEach($scope.inventoryResponseItemList, function(inventoryResponseItem, key) {
+
+ $scope.inventoryResponseItem = inventoryResponseItem;
+
+ $scope.serviceInstanceToCustomer = DataService.getServiceInstanceToCustomer();
+ var subscriberName = "";
+ angular.forEach($scope.serviceInstanceToCustomer, function(servInst, key2) {
+ if (servInst.serviceInstanceId === $scope.serviceInstanceId) {
+ subscriberName = servInst.subscriberName;
+ }
+ });
+ $scope.service.instance = {
+ "name": $scope.inventoryResponseItem["service-instance"]["service-instance-name"],
+ "serviceInstanceId": $scope.serviceInstanceId,
+ "serviceType": $scope.serviceType,
+ "globalCustomerId": $scope.globalCustomerId,
+ "subscriberName": subscriberName,
+ "id": $scope.serviceInstanceId,
+ "inputs": {
+ "a": {
+ "type": "String",
+ "description": "This variable is 'a'",
+ "default": "A default"
+ },
+ "b": {
+ "type": "String",
+ "description": "This variable is 'b'",
+ "default": "B default"
+ },
+ },
+ "object": $scope.inventoryResponseItem["service-instance"],
+ "vnfs": [],
+ "networks": []
+ }
+
+ if (inventoryResponseItem["inventory-response-items"] != null) {
+
+ angular.forEach(inventoryResponseItem["inventory-response-items"]["inventory-response-item"], function(subInventoryResponseItem, key) {
+ // i expect to find vnfs now
+
+ if (subInventoryResponseItem["l3-network"] != null) {
+ var l3NetworkObject = subInventoryResponseItem["l3-network"];
+ var l3Network = { "id": $scope.counter++,
+ "name": l3NetworkObject["network-name"],
+ "itemType": "l3-network",
+ "nodeId": l3NetworkObject["network-id"],
+ "nodeType": l3NetworkObject["network-type"],
+ "nodeStatus": l3NetworkObject["orchestration-status"],
+ "object": l3NetworkObject,
+ "nodes": []
+ };
+ $scope.service.instance["networks"].push(l3Network);
+ }
+
+ if (subInventoryResponseItem["generic-vnf"] != null) {
+ var genericVnfObject = subInventoryResponseItem["generic-vnf"];
+
+ var genericVnf = {
+ "name": genericVnfObject["vnf-name"],
+ "id": $scope.counter++,
+ "itemType": "vnf",
+ "nodeType": genericVnfObject["vnf-type"],
+ "nodeId": genericVnfObject["vnf-id"],
+ "nodeStatus": genericVnfObject["orchestration-status"],
+ "object": genericVnfObject,
+ "vfModules": [],
+ "volumeGroups": [],
+ "availableVolumeGroups": []
+ };
+ $scope.service.instance["vnfs"].push(genericVnf);
+
+ // look for volume-groups
+ if (subInventoryResponseItem["inventory-response-items"] != null) {
+ angular.forEach(subInventoryResponseItem["inventory-response-items"]["inventory-response-item"], function(vfmodules, key) {
+
+ if (vfmodules["volume-group"] != null) {
+ var volumeGroupObject = vfmodules["volume-group"];
+ var volumeGroup = { "id": $scope.counter++,
+ "name": volumeGroupObject["volume-group-name"],
+ "itemType": "volume-group",
+ "nodeId": volumeGroupObject["volume-group-id"],
+ "nodeType": volumeGroupObject["vnf-type"],
+ "nodeStatus": volumeGroupObject["orchestration-status"],
+ "object": volumeGroupObject,
+ "nodes": []
+ };
+ genericVnf["volumeGroups"].push(volumeGroup);
+ genericVnf["availableVolumeGroups"].push(volumeGroup);
+ }
+ });
+ }
+ // now we've loaded up the availableVolumeGroups, we can use it
+ if (subInventoryResponseItem["inventory-response-items"] != null) {
+ angular.forEach(subInventoryResponseItem["inventory-response-items"]["inventory-response-item"], function(vfmodules, key) {
+
+ if (vfmodules["vf-module"] != null) {
+ var vfModuleObject = vfmodules["vf-module"];
+ var vfModule = { "id": $scope.counter++,
+ "name": vfModuleObject["vf-module-name"],
+ "itemType": "vf-module",
+ "nodeType": "vf-module",
+ "nodeStatus": vfModuleObject["orchestration-status"],
+ "volumeGroups": [],
+ "object": vfModuleObject,
+ "networks": []
+ };
+ genericVnf["vfModules"].push(vfModule);
+ if (vfmodules["inventory-response-items"] != null) {
+ angular.forEach(vfmodules["inventory-response-items"]["inventory-response-item"], function(networks, key) {
+ if (networks["l3-network"] != null) {
+ var l3NetworkObject = networks["l3-network"];
+ var l3Network = { "id": $scope.counter++,
+ "name": l3NetworkObject["network-name"],
+ "itemType": "l3-network",
+ "nodeId": l3NetworkObject["network-id"],
+ "nodeType": l3NetworkObject["network-type"],
+ "nodeStatus": l3NetworkObject["orchestration-status"],
+ "object": l3NetworkObject,
+ "nodes": []
+ };
+ vfModule["networks"].push(l3Network);
+ }
+ if (networks["volume-group"] != null) {
+ var volumeGroupObject = networks["volume-group"];
+
+ var volumeGroup = { "id": $scope.counter++,
+ "name": volumeGroupObject["volume-group-name"],
+ "itemType": "volume-group",
+ "nodeId": volumeGroupObject["volume-group-id"],
+ "nodeType": volumeGroupObject["vnf-type"],
+ "nodeStatus": volumeGroupObject["orchestration-status"],
+ "object": volumeGroupObject,
+ "nodes": []
+ };
+ var tmpVolGroup = [];
+
+ angular.forEach(genericVnf["availableVolumeGroups"], function(avgroup, key) {
+ if (avgroup.name != volumeGroup.name) {
+ tmpVolGroup.push(avgroup);
+ }
+ });
+
+ genericVnf["availableVolumeGroups"] = tmpVolGroup;
+
+ vfModule["volumeGroups"].push(volumeGroup);
+ }
+
+ });
+ }
+ }
+ });
+ }
+ }
+ });
+ }
+ });
+
+ $scope.setProgress(100); // done
+ $scope.status = "Done";
+ $scope.isSpinnerVisible = false;
+ console.log("HERE!!!");
+ } catch (error) {
+ console.log(error);
+ }
+ }
+
+ $scope.handleInitialResponse = function(response) {
+ try {
+ $scope.enableCloseButton(true);
+ $scope.updateLog(response);
+ if (response.data.status < 200 || response.data.status > 202) {
+ $scope.showError("MSO failure - see log below for details")
+ return;
+ }
+
+ $scope.setProgress(100); // done
+ $scope.status = "Done";
+ $scope.isSpinnerVisible = false;
+
+ $scope.customer = response.data.customer; // get data from json
+
+ $scope.customerList = [];
+
+ $scope.serviceInstanceToCustomer = [];
+ //$scope.serviceIdList = [];
+ angular.forEach($scope.customer, function(subVal, subKey) {
+ var cust = { "globalCustomerId": subVal["global-customer-id"], "subscriberName": subVal["subscriber-name"] };
+ $scope.customerList.push(cust);
+ if (subVal["service-subscriptions"] != null) {
+
+
+ angular.forEach(subVal["service-subscriptions"]["service-subscription"], function(serviceSubscription, key) {
+ $scope.serviceInstanceId = [];
+ if (serviceSubscription["service-type"] != null) {
+// var newVal = { "id" : serviceSubscription["service-type"], "description" : serviceSubscription["service-type"] };
+// if ($scope.serviceIdList.indexOf(newVal) == -1) {
+// $scope.serviceIdList.push(newVal);
+// }
+ $scope.serviceType = serviceSubscription["service-type"];
+ } else {
+ $scope.serviceType = "No Service Subscription Found";
+ }
+ if (serviceSubscription["service-instances"] != null) {
+ angular.forEach(serviceSubscription["service-instances"]["service-instance"], function(instValue, instKey) {
+ var foo = { "serviceInstanceId": instValue["service-instance-id"],
+ "globalCustomerId": subVal["global-customer-id"],
+ "subscriberName": subVal["subscriber-name"] };
+ $scope.serviceInstanceToCustomer.push(foo);
+ });
+ }
+ });
+ }
+ });
+// DataService.setServiceIdList($scope.serviceIdList);
+ DataService.setServiceInstanceToCustomer($scope.serviceInstanceToCustomer);
+ } catch (error) {
+ $scope.showContentError(error);
+ }
+ }
+
+ $scope.autoGetSubs = function() {
+ /*
+ * Optionally comment in / out one of these method calls (or add a similar
+ * entry) to auto-invoke an entry when the test screen is redrawn.
+ */
+ $scope.getSubs();
+
+ }
+
+ $scope.pollStatus = function () {
+ /*
+ * The "?r=" argument overrides caching. This was needed for Internet Explorer 11.
+ *
+ * Ideally this should NOT be needed and appears to be an Angular bug.
+ */
+ $http.get($scope.baseUrl + "mso_get_orch_req/" + $scope.requestId + "?r=" + Math.random(), {
+ cache: false, // This alternative did NOT seem to disable caching but was retained as a reference
+ timeout: $scope.responseTimeoutMsec
+ }).then($scope.handlePollResponse)
+ ["catch"]($scope.handleServerError);
+ }
+
+ $scope.handlePollResponse = function(response) {
+ try {
+ // $log.debug("handlePollResponse: response contents:");
+ // $log.debug(response);
+ $scope.updateLog(response);
+
+ if (response.data.status < 200 || response.data.status > 202) {
+ $scope.showError("MSO failure - see log below for details")
+ return;
+ }
+
+// UtilityService.checkUndefined("request", response.data.entity.request);
+// UtilityService.checkUndefined("requestStatus", response.data.entity.request.requestStatus);
+
+// $scope.setProgress(response.data.entity.request.requestStatus.percentProgress);
+
+// var requestState = response.data.entity.request.requestStatus.requestState;
+// if (requestState == "InProgress") {
+// requestState = "In Progress";
+// }
+// var statusMessage = response.data.entity.request.requestStatus.statusMessage;
+// if (UtilityService.hasContents(statusMessage)) {
+// $scope.status = requestState + " - " + statusMessage;
+// } else {
+// $scope.status = requestState;
+// }
+// if (requestState == "Complete") {
+// $scope.isSpinnerVisible = false;
+// return;
+// }
+// if (requestState == "Failure") {
+// $scope.showError("MSO failure - see log below for details")
+// return;
+// }
+// if (++$scope.pollAttempts > $scope.properties.msoMaxPolls) {
+// $scope.showError("Maximum number of poll attempts exceeded");
+// } else {
+// $scope.timer = $timeout($scope.pollStatus, $scope.properties.msoMaxPollingIntervalMsec);
+// }
+ } catch (error) {
+ $scope.showContentError(error);
+ }
+ }
+
+ $scope.updateLog = function(response) {
+// $scope.log = UtilityService.getCurrentTime() + " HTTP Status: " +
+// UtilityService.getHttpStatusText(response.data.status) + "\n" +
+// angular.toJson(response.data.entity, true) + "\n\n" + $scope.log;
+// UtilityService.checkUndefined("entity", response.data.entity);
+// UtilityService.checkUndefined("status", response.data.status);
+ }
+
+ $scope.handleServerError = function(response, status) {
+ $scope.enableCloseButton(true);
+ var message = UtilityService.getHttpErrorMessage(response);
+ if (message != ""){
+ message = " (" + message + ")";
+ }
+ $scope.showError("System failure" + message);
+ }
+
+ $scope.showContentError = function(message) {
+ // $log.debug(message);
+ console.log(message);
+ if (UtilityService.hasContents(message)) {
+ $scope.showError("System failure (" + message + ")");
+ } else {
+ $scope.showError("System failure");
+ }
+ }
+
+ $scope.showError = function(message) {
+ $scope.isSpinnerVisible = false;
+ $scope.isProgressVisible = false;
+ $scope.error = message;
+ $scope.status = "Error";
+ }
+
+ $scope.close = function() {
+ if ($scope.timer != undefined) {
+ $timeout.cancel($scope.timer);
+ }
+ $scope.isPopupVisible = false;
+ }
+
+
+
+ /*
+ * Consider converting the progress bar mechanism, the disabled button handling
+ * and the following methods to generic Angular directive(s) and/or approach.
+ */
+
+ $scope.enableCloseButton = function(isEnabled) {
+ var selector = "div[ng-controller=msoCommitController] button";
+
+ $scope.isCloseEnabled = isEnabled;
+
+ if (isEnabled) {
+ $(selector).addClass("button--primary").removeClass("button--inactive").attr("btn-type", "primary");
+ } else {
+ $(selector).removeClass("button--primary").addClass("button--inactive").attr("btn-type", "disabled");
+ }
+ }
+
+ $scope.resetProgress = function() {
+ $scope.percentProgress = 0;
+ $scope.progressClass = "progress-bar progress-bar-info";
+ }
+
+ $scope.setProgress = function(percentProgress) {
+ percentProgress = parseInt(percentProgress);
+ if (percentProgress >= 100) {
+ $scope.progressClass = "progress-bar progress-bar-success";
+ }
+
+ if (percentProgress < $scope.percentProgress) {
+ return;
+ }
+
+ $scope.percentProgress = percentProgress;
+ $scope.progressWidth = {width: percentProgress + "%"};
+ if (percentProgress >= 5) {
+ $scope.progressText = percentProgress + " %";
+ } else {
+ // Hidden since color combination is barely visible when progress portion is narrow.
+ $scope.progressText = "";
+ }
+ }
+
+ $scope.reloadRoute = function() {
+ $route.reload();
+ }
+
+ $scope.prevPage = function() {
+ $scope.currentPage--;
+ }
+
+ $scope.nextPage = function() {
+ $scope.currentPage++;
+ }
+ $scope.getSubscriberDet = function(selectedCustomer,selectedServiceInstance){
+ if (selectedCustomer != null) {
+ window.location.href = '#/instances/subdetails?selectedSubscriber=' + selectedCustomer;
+ } else if (selectedServiceInstance != null) {
+ selectedServiceInstance.trim();
+ var serviceInstanceToCustomer = $scope.serviceInstanceToCustomer;
+ var notFound = true;
+ angular.forEach(serviceInstanceToCustomer, function(inst, key) {
+ if (inst.serviceInstanceId == selectedServiceInstance) {
+
+ notFound = false;
+ window.location.href = '#/instances/subdetails?selectedSubscriber=' + inst.globalCustomerId + '&selectedServiceInstance=' + selectedServiceInstance;
+ }
+ });
+ if (notFound) {
+ alert("That service instance does not exist. Please try again.");
+ }
+ } else {
+ alert("Please select a subscriber or enter a service instance");
+ }
+ };
+}
+]);
+
+
+app.controller('TreeCtrl', ['$scope', function ($scope) {
+ $scope.remove = function (scope) {
+ scope.remove();
+ };
+
+ $scope.toggle = function (scope) {
+ scope.toggle();
+ };
+
+ $scope.moveLastToTheBeginning = function () {
+ var a = $scope.data.pop();
+ $scope.data.splice(0, 0, a);
+ };
+
+ $scope.newSubItem = function (scope) {
+ var nodeData = scope.$modelValue;
+ nodeData.nodes.push({
+ id: nodeData.id * 10 + nodeData.nodes.length,
+ title: nodeData.title + '.' + (nodeData.nodes.length + 1),
+ nodes: []
+ });
+ };
+
+ $scope.collapseAll = function () {
+ $scope.$broadcast('angular-ui-tree:collapse-all');
+ };
+
+ $scope.expandAll = function () {
+ $scope.$broadcast('angular-ui-tree:expand-all');
+ };
+
+
+}]);
+
+
+
diff --git a/vid/src/main/webapp/app/vid/scripts/controller/creationDialogController.js b/vid/src/main/webapp/app/vid/scripts/controller/creationDialogController.js
new file mode 100644
index 000000000..5e5c51d6e
--- /dev/null
+++ b/vid/src/main/webapp/app/vid/scripts/controller/creationDialogController.js
@@ -0,0 +1,162 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * 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=========================================================
+ */
+
+"use strict";
+
+var creationDialogController = function( COMPONENT, FIELD, $scope, $http, $timeout, $log,
+ CreationService, UtilityService) {
+
+ $scope.isDialogVisible = false;
+ $scope.summaryControl = {};
+ $scope.userProvidedControl = {};
+
+ var callbackFunction = undefined;
+ var componentId = undefined;
+
+ $scope.$on("createComponent", function(event, request) {
+
+ $scope.isSpinnerVisible = true;
+ $scope.isErrorVisible = false;
+ $scope.isDataVisible = false;
+ $scope.isConfirmEnabled = false;
+ $scope.isDialogVisible = true;
+ $scope.popup.isVisible = true;
+
+ callbackFunction = request.callbackFunction;
+ componentId = request.componentId;
+ CreationService.initializeComponent(request.componentId);
+
+ CreationService.setHttpErrorHandler(function(response) {
+ showError("System failure", UtilityService
+ .getHttpErrorMessage(response));
+ });
+
+ $scope.componentName = CreationService.getComponentDisplayName();
+
+ CreationService.getParameters(handleGetParametersResponse);
+
+ });
+
+ var handleGetParametersResponse = function(parameters) {
+ $scope.summaryControl.setList(parameters.summaryList);
+ $scope.userProvidedControl.setList(parameters.userProvidedList);
+
+ $scope.isSpinnerVisible = false;
+ $scope.isDataVisible = true;
+ $scope.isConfirmEnabled = true;
+ };
+
+ var validateInstanceName = function(iname) {
+ var patt1 = /^([a-z])+([0-9a-z\-_]*)$/i;
+
+ if ( iname == null ){
+ return false;
+ }
+ if ( !iname.match(patt1) ) {
+ return false;
+ }
+ return true;
+ }
+
+ $scope.userParameterChanged = function(id) {
+ CreationService.updateUserParameterList(id, $scope.userProvidedControl);
+ }
+
+ $scope.confirm = function() {
+
+ var requiredFields = $scope.userProvidedControl.getRequiredFields();
+ if (requiredFields !== "") {
+ showError("Missing data", requiredFields);
+ return;
+ }
+ // validate the instance names for volumeGroup, vfModule, network
+
+ if ( componentId != COMPONENT.SERVICE ) {
+ var paramList = $scope.userProvidedControl.getList();
+ var instanceName = "";
+
+ if ( paramList != null ) {
+ for (var i = 0; i < paramList.length; i++) {
+ if (paramList[i].id === FIELD.ID.INSTANCE_NAME) {
+ instanceName = paramList[i].value;
+ break;
+ }
+ }
+ }
+ var isValid = validateInstanceName (instanceName);
+ if ( isValid ) {
+ $scope.isErrorVisible = false;
+ } else {
+ showError("Invalid instance name: " + instanceName,
+ "The instance name must contain only alphanumeric or \"_-.\" characters, and must start with an alphabetic character");
+ return;
+ }
+ }
+ var requestDetails = CreationService
+ .getMsoRequestDetails($scope.userProvidedControl.getList());
+
+ $scope.isDialogVisible = false;
+
+ $scope.$broadcast("createInstance", {
+ url : CreationService.getMsoUrl(),
+ requestDetails : requestDetails,
+ callbackFunction : function(response) {
+ if (response.isSuccessful) {
+ $scope.popup.isVisible = false;
+ runCallback(response);
+ } else {
+ $scope.isDialogVisible = true;
+ }
+ }
+ });
+ }
+
+ $scope.cancel = function() {
+ $scope.isDialogVisible = false;
+ $scope.popup.isVisible = false;
+ runCallback(false);
+ }
+
+ var runCallback = function(response) {
+ if (angular.isFunction(callbackFunction)) {
+ callbackFunction({
+ isSuccessful : response.isSuccessful,
+ control : $scope.userProvidedControl.getList(),
+ instanceId : response.instanceId
+ });
+ }
+ }
+
+ var showError = function(summary, details) {
+ var message = summary;
+ if (UtilityService.hasContents(details)) {
+ message += " (" + details + ")";
+ }
+ $scope.isSpinnerVisible = false;
+ $scope.isErrorVisible = true;
+ $scope.error = message;
+ }
+
+}
+
+app
+ .controller("creationDialogController", [ "COMPONENT", "FIELD", "$scope", "$http",
+ "$timeout", "$log", "CreationService", "UtilityService",
+ creationDialogController ]);
diff --git a/vid/src/main/webapp/app/vid/scripts/controller/deletionDialogController.js b/vid/src/main/webapp/app/vid/scripts/controller/deletionDialogController.js
new file mode 100644
index 000000000..caac6de9b
--- /dev/null
+++ b/vid/src/main/webapp/app/vid/scripts/controller/deletionDialogController.js
@@ -0,0 +1,117 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * 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=========================================================
+ */
+
+"use strict";
+
+var deletionDialogController = function($scope, $http, $timeout, $log,
+ DeletionService, UtilityService) {
+
+ $scope.isDialogVisible = false;
+ $scope.summaryControl = {};
+ $scope.userProvidedControl = {};
+
+ var callbackFunction = undefined;
+
+ $scope.$on("deleteComponent", function(event, request) {
+
+ $scope.isDataVisible = false;
+ $scope.isSpinnerVisible = false;
+ $scope.isErrorVisible = false;
+ $scope.isDialogVisible = true;
+ $scope.popup.isVisible = true;
+ $scope.isConfirmEnabled = false;
+
+ callbackFunction = request.callbackFunction;
+
+ DeletionService.initializeComponent(request.componentId);
+
+ $scope.componentName = DeletionService.getComponentDisplayName();
+
+ $scope.summaryControl.setList(DeletionService.getSummaryList());
+
+ DeletionService.getParameters(handleGetParametersResponse);
+
+ });
+
+ var handleGetParametersResponse = function(parameters, dontshow) {
+ $scope.summaryControl.setList(parameters.summaryList);
+ $scope.userProvidedControl.setList(parameters.userProvidedList);
+
+ $scope.isSpinnerVisible = false;
+ if (dontshow)
+ $scope.isDataVisible = false;
+ else
+ $scope.isDataVisible = true;
+ $scope.isConfirmEnabled = true;
+ };
+
+ $scope.userParameterChanged = function(id) {
+ DeletionService.updateUserParameterList(id, $scope.userProvidedControl);
+ }
+
+ $scope.confirm = function() {
+
+ var requiredFields = $scope.userProvidedControl.getRequiredFields();
+ if (requiredFields === "") {
+ $scope.isErrorVisible = false;
+ } else {
+ showError("Missing data", requiredFields);
+ return;
+ }
+
+
+ var requestDetails = DeletionService.getMsoRequestDetails($scope.userProvidedControl.getList());
+
+ $scope.isDialogVisible = false;
+
+ $scope.$broadcast("deleteInstance", {
+ url : DeletionService.getMsoUrl(),
+ requestDetails : requestDetails,
+ callbackFunction : function(isSuccessful) {
+ if (isSuccessful) {
+ $scope.popup.isVisible = false;
+ runCallback(true);
+ } else {
+ $scope.isDialogVisible = true;
+ }
+ }
+ });
+
+ }
+
+ $scope.cancel = function() {
+ $scope.isDialogVisible = false;
+ $scope.popup.isVisible = false;
+ runCallback(false);
+ }
+
+ var runCallback = function(isSuccessful) {
+ if (angular.isFunction(callbackFunction)) {
+ callbackFunction({
+ isSuccessful : isSuccessful
+ });
+ }
+ }
+}
+
+app
+ .controller("deletionDialogController", [ "$scope", "$http",
+ "$timeout", "$log", "DeletionService", "UtilityService",
+ deletionDialogController ]);
diff --git a/vid/src/main/webapp/app/vid/scripts/controller/detailsDialogController.js b/vid/src/main/webapp/app/vid/scripts/controller/detailsDialogController.js
new file mode 100644
index 000000000..5f58ae319
--- /dev/null
+++ b/vid/src/main/webapp/app/vid/scripts/controller/detailsDialogController.js
@@ -0,0 +1,84 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * 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=========================================================
+ */
+
+"use strict";
+
+var detailsDialogController = function($scope, $http, $timeout, $log,
+ MsoService, DetailsService, UtilityService) {
+
+ $scope.isDialogVisible = false;
+ $scope.summaryControl = {};
+ $scope.detailsControl = {};
+
+ $scope.$on("showComponentDetails", function(event, request) {
+
+ $scope.log = "";
+ $scope.isSpinnerVisible = true;
+ $scope.isErrorVisible = false;
+ $scope.isDialogVisible = true;
+ $scope.popup.isVisible = true;
+
+ DetailsService.initializeComponent(request.componentId);
+
+ $scope.componentName = DetailsService.getComponentDisplayName();
+
+ $scope.summaryControl.setList(DetailsService.getSummaryList());
+
+ $scope.detailsControl.setList(DetailsService.getDetailsList());
+
+ UtilityService.setHttpErrorHandler(function(response) {
+ showError("System failure", UtilityService
+ .getHttpErrorMessage(response));
+ });
+
+ MsoService.getOrchestrationRequests(
+ DetailsService.getMsoFilterString(), handleGetResponse);
+ });
+
+ var handleGetResponse = function(response) {
+ $scope.isSpinnerVisible = false;
+ try {
+ $scope.log = MsoService
+ .getFormattedGetOrchestrationRequestsResponse(response);
+ } catch (error) {
+ $scope.log = MsoService.getFormattedCommonResponse(response);
+ MsoService.showResponseContentError(error, showError);
+ }
+ }
+
+ $scope.close = function() {
+ $scope.isDialogVisible = false;
+ $scope.popup.isVisible = false;
+ }
+
+ var showError = function(summary, details) {
+ var message = summary;
+ if (UtilityService.hasContents(details)) {
+ message += " (" + details + ")";
+ }
+ $scope.isSpinnerVisible = false;
+ $scope.isErrorVisible = true;
+ $scope.error = message;
+ }
+}
+
+app.controller("detailsDialogController", [ "$scope", "$http", "$timeout",
+ "$log", "MsoService", "DetailsService", "UtilityService",
+ detailsDialogController ]);
diff --git a/vid/src/main/webapp/app/vid/scripts/controller/dummy.txt b/vid/src/main/webapp/app/vid/scripts/controller/dummy.txt
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/vid/src/main/webapp/app/vid/scripts/controller/dummy.txt
diff --git a/vid/src/main/webapp/app/vid/scripts/controller/msoCommitController.js b/vid/src/main/webapp/app/vid/scripts/controller/msoCommitController.js
new file mode 100644
index 000000000..ef3adeb32
--- /dev/null
+++ b/vid/src/main/webapp/app/vid/scripts/controller/msoCommitController.js
@@ -0,0 +1,249 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * 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=========================================================
+ */
+
+"use strict";
+
+/*
+ * "msoCommitController.js" provides controller code to commit MSO requests.
+ *
+ * HIGHLIGHTS:
+ *
+ * Parent HTML/JSP code is expected to include "msoCommit.htm" (via
+ * "ng-include") and this file (via "<script>"). "msoCommit.jsp" (displayed
+ * when the parent code includes "msoCommit.htm") renders a popup window, but
+ * initially hides the display.
+ *
+ * The parent controller code is expected to broadcast either the
+ * "createInstance" or "deleteInstance" events when it is ready to commit the
+ * code.
+ *
+ * This controller receives these events (via "$scope.on" declarations), calls
+ * "$scope.init()" to "unhide" and initialize the popup display and then makes a
+ * REST request to the appropriate server Java controller.
+ *
+ * The initial REST response is handled by "handleInitialResponse". This method
+ * then polls the server (via "getRequestStatus") if the request is successful.
+ *
+ * The subsequent "getRequestStatus" responses are handled by
+ * "handleGetResponse".
+ *
+ * "handleInitialResponse" and "handleGetResponse" primarily filter response
+ * data, manipulate the display and provide error handling.
+ *
+ * The mechanism has these dependencies (in addition to "msoCommit.htm"):
+ *
+ * 1) Three services: MsoService, PropertyService and UtilityService
+ *
+ * 2) The popup window directive found in "popupWindow.htm" and
+ * "popupWindowDirective.js"
+ *
+ * 2) Display styling defined in "dialogs.css"
+ *
+ * CAVEATS:
+ *
+ * The parent HTML is assumed to be the "popup-window" directive and the
+ * corresponding parent controller is assumed to define the object
+ * "$scope.popup".
+ */
+
+var msoCommitController = function($scope, $http, $timeout, $window, $log,
+ MsoService, PropertyService, UtilityService, DataService) {
+
+ $scope.isViewVisible = false;
+ $scope.progressBarControl = {};
+ $scope.popupWindowControl = {};
+
+ var _this = this;
+
+ $scope.$on("createInstance", function(event, request) {
+ init(request);
+ MsoService.createInstance(request, handleInitialResponse);
+ });
+
+ $scope.$on("deleteInstance", function(event, request) {
+ init(request);
+ MsoService.deleteInstance(request, handleInitialResponse);
+ });
+
+ var init = function(request) {
+ $scope.status = "Submitting Request";
+ $scope.isSpinnerVisible = true;
+ $scope.isProgressVisible = true;
+ $scope.error = "";
+ $scope.log = "";
+ $scope.isCloseEnabled = false;
+ $scope.isViewVisible = true;
+ $scope.popup.isVisible = true;
+
+ _this.pollAttempts = 0;
+ _this.callbackFunction = request.callbackFunction;
+
+ if (angular.isFunction($scope.progressBarControl.reset)) {
+ $scope.progressBarControl.reset();
+ }
+ $scope.percentProgress = 2; // Show "a little" progress
+
+ UtilityService.setHttpErrorHandler(function(response) {
+ $scope.isCloseEnabled = true;
+ showError("System failure", UtilityService
+ .getHttpErrorMessage(response));
+ });
+ }
+
+ var handleInitialResponse = function(response) {
+ try {
+ updateViewAfterInitialResponse(response);
+ _this.timer = $timeout(getRequestStatus, PropertyService
+ .getMsoMaxPollingIntervalMsec());
+
+ $scope.instanceId = response.data.entity.instanceId;
+ if ($scope.instanceId == null) {
+ $scope.instanceId = response.data.entity.requestReferences.instanceId;
+ }
+ } catch (error) {
+ MsoService.showResponseContentError(error, showError);
+ }
+ }
+
+ var getRequestStatus = function() {
+ MsoService.getOrchestrationRequest(_this.requestId, handleGetResponse);
+ }
+
+ var handleGetResponse = function(response) {
+ try {
+ if (isUpdateViewAfterGetResponseComplete(response)) {
+ return;
+ }
+ console.log ( "msoCommitController _this.pollAttempts=" + _this.pollAttempts + " max polls=" + PropertyService.getMsoMaxPolls());
+ if (++_this.pollAttempts > PropertyService.getMsoMaxPolls()) {
+ showError("Maximum number of poll attempts exceeded");
+ } else {
+ _this.timer = $timeout(getRequestStatus, PropertyService
+ .getMsoMaxPollingIntervalMsec());
+ }
+ } catch (error) {
+ MsoService.showResponseContentError(error, showError);
+ }
+ }
+
+ var updateViewAfterInitialResponse = function(response) {
+ $scope.isCloseEnabled = true;
+
+ updateLog(response);
+
+ _this.requestId = UtilityService.checkUndefined("requestId",
+ UtilityService.checkUndefined("requestReferences",
+ response.data.entity.requestReferences).requestId);
+
+ $scope.percentProgress = 4; // Show "a little more" progress
+ $scope.status = "In Progress";
+ }
+
+ /*
+ * Updates the view and returns "true" if the MSO operation has returned a
+ * "Complete" status.
+ */
+ var isUpdateViewAfterGetResponseComplete = function(response) {
+ console.log("msoCommitController isUpdateViewAfterGetResponseComplete");
+ updateLog(response);
+
+ var requestStatus = UtilityService.checkUndefined("requestStatus",
+ UtilityService.checkUndefined("request",
+ response.data.entity.request).requestStatus);
+
+ var requestState = requestStatus.requestState;
+ console.log("msoCommitController requestState=" + requestState);
+ // look for "progress" or "pending"
+ var patt1 = /progress/i;
+ var patt2 = /pending/i;
+ var result1 = patt1.test(requestState);
+ var result2 = patt2.test(requestState)
+ if (result1 || result2) {
+ requestState = "In Progress";
+ }
+ var statusMessage = requestStatus.statusMessage;
+ console.log("msoCommitController statusMessage=" + statusMessage);
+ if (UtilityService.hasContents(statusMessage)) {
+ $scope.status = requestState + " - " + statusMessage;
+ } else {
+ $scope.status = requestState;
+ }
+ if (UtilityService.hasContents(requestStatus.percentProgress)) {
+ $scope.percentProgress = requestStatus.percentProgress;
+ }
+
+ if (requestState.toLowerCase() === "Failed".toLowerCase()) {
+ throw {
+ type : "msoFailure"
+ };
+ }
+
+ if (requestState.toLowerCase() === "Complete".toLowerCase()) {
+ $scope.isSpinnerVisible = false;
+ return true;
+ }
+
+ return false;
+ }
+
+ var updateLog = function(response) {
+ $scope.log = MsoService.getFormattedCommonResponse(response)
+ + $scope.log;
+ UtilityService.checkUndefined("entity", response.data.entity);
+ UtilityService.checkUndefined("status", response.data.status);
+ MsoService.checkValidStatus(response);
+ }
+
+ $scope.close = function() {
+ if (_this.timer !== undefined) {
+ $timeout.cancel(_this.timer);
+ }
+ $scope.isViewVisible = false;
+ if (angular.isFunction(_this.callbackFunction)) {
+ if ($scope.error === "") {
+ _this.callbackFunction({
+ isSuccessful : true,
+ instanceId : $scope.instanceId
+ });
+ } else {
+ _this.callbackFunction({
+ isSuccessful : false
+ });
+ }
+ } else {
+ $scope.popup.isVisible = false;
+ }
+ }
+
+ var showError = function(summary, details) {
+ var message = summary;
+ if (UtilityService.hasContents(details)) {
+ message += " (" + details + ")";
+ }
+ $scope.isSpinnerVisible = false;
+ $scope.isProgressVisible = false;
+ $scope.error = message;
+ $scope.status = "Error";
+ }
+}
+
+app.controller("msoCommitController", [ "$scope", "$http", "$timeout",
+ "$window", "$log", "MsoService", "PropertyService", "UtilityService",
+ msoCommitController ]);
diff --git a/vid/src/main/webapp/app/vid/scripts/controller/sample-page-controller.js b/vid/src/main/webapp/app/vid/scripts/controller/sample-page-controller.js
new file mode 100644
index 000000000..0f5494556
--- /dev/null
+++ b/vid/src/main/webapp/app/vid/scripts/controller/sample-page-controller.js
@@ -0,0 +1,81 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * 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=========================================================
+ */
+
+app.controller('samplePageController', function($scope, $http,ProfileService,modalService){
+ $scope.tableData=[];
+ $scope.viewPerPage=20;
+ $scope.scrollViewPerPage=2;
+ $scope.currentPage=1;
+ $scope.totalPage;
+ $scope.searchCategory;
+ $scope.searchString="";
+ $scope.currentPageNum=1;
+ ProfileService.getProfilePagination(1,$scope.viewPerPage).then(function(data){
+ var j = data;
+ $scope.data = JSON.parse(j.data);
+ $scope.tableData =JSON.parse($scope.data.profileList);
+ $scope.totalPages =JSON.parse($scope.data.totalPage);
+ for(x in $scope.tableData){
+ if($scope.tableData[x].active_yn=='Y')
+ $scope.tableData[x].active_yn=true;
+ else
+ $scope.tableData[x].active_yn=false;
+ }
+ //$scope.resetMenu();
+ },function(error){
+ console.log("failed");
+ reloadPageOnce();
+ });
+
+ $scope.$watch('currentPageNum', function(val) {
+
+ ProfileService.getProfilePagination(val,$scope.viewPerPage).then(function(data){
+ var j = data;
+ $scope.data = JSON.parse(j.data);
+ $scope.tableData =JSON.parse($scope.data.profileList);
+ $scope.totalPages =JSON.parse($scope.data.totalPage);
+ for(x in $scope.tableData){
+ if($scope.tableData[x].active_yn=='Y')
+ $scope.tableData[x].active_yn=true;
+ else
+ $scope.tableData[x].active_yn=false;
+ }
+ //$scope.resetMenu();
+ },function(error){
+ console.log("failed");
+ });
+
+ });
+
+ $scope.editRow = function(profileId){
+ window.location = 'userProfile#/profile/' + profileId;
+ }
+
+ $scope.toggleProfileActive = function(rowData) {
+ modalService.popupConfirmWinWithCancel("Confirm","You are about to change user's active status. Do you want to continue?",
+ function(){
+ $http.get("profile/toggleProfileActive?profile_id="+rowData.id).success(function(){});
+ },
+ function(){
+ rowData.active=!rowData.active;
+ })
+ };
+
+});
diff --git a/vid/src/main/webapp/app/vid/scripts/controller/sample-page-iframe-controller.js b/vid/src/main/webapp/app/vid/scripts/controller/sample-page-iframe-controller.js
new file mode 100644
index 000000000..99f66de7e
--- /dev/null
+++ b/vid/src/main/webapp/app/vid/scripts/controller/sample-page-iframe-controller.js
@@ -0,0 +1,24 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * 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=========================================================
+ */
+
+app.controller('samplePageWithIframeController', function($scope, $http,ProfileService,modalService){
+
+
+});
diff --git a/vid/src/main/webapp/app/vid/scripts/controller/sampleController.js b/vid/src/main/webapp/app/vid/scripts/controller/sampleController.js
new file mode 100644
index 000000000..190ac301d
--- /dev/null
+++ b/vid/src/main/webapp/app/vid/scripts/controller/sampleController.js
@@ -0,0 +1,31 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * 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=========================================================
+ */
+
+app.config(function($routeProvider) {
+ $routeProvider
+ .when('/iframe', {
+ templateUrl: 'app/fusionapp/scripts/view-models/sampleWithIframe.html',
+ controller : "samplePageWithIframeController"
+ })
+ .otherwise({
+ templateUrl: 'app/fusionapp/scripts/view-models/sample.html',
+ controller : "samplePageController"
+ });
+});
diff --git a/vid/src/main/webapp/app/vid/scripts/controller/subscriberSearch.js b/vid/src/main/webapp/app/vid/scripts/controller/subscriberSearch.js
new file mode 100644
index 000000000..110c07ad1
--- /dev/null
+++ b/vid/src/main/webapp/app/vid/scripts/controller/subscriberSearch.js
@@ -0,0 +1,385 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * 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=========================================================
+ */
+
+"use strict";
+
+app.requires.push('ngRoute');
+app.requires.push('ui.tree');
+
+app.config(function($routeProvider) {
+ $routeProvider
+ .when("/subviewedit", {
+ templateUrl : "app/vid/scripts/view-models/aaiSubViewEdit.htm",
+ controller : "aaiSubscriberSearchController"
+
+ })
+ .when("/subdetails", {
+ templateUrl : "app/vid/scripts/view-models/aaiSubDetails.htm",
+ controller : "aaiSubscriberController"
+
+ })
+ .otherwise({
+ templateUrl : "app/vid/scripts/view-models/aaiGetSubs.htm",
+ controller : "aaiSubscriberSearchController"
+ });
+});
+
+app.config(function(treeConfig) {
+ treeConfig.defaultCollapsed = true; // collapse nodes by default
+ });
+
+app.factory("user",function(){
+ return {};
+});
+
+app.controller("aaiSubscriberSearchController", [ "$scope", "$timeout", "$log", "UtilityService", "user", "PropertyService",
+ function($scope, $timeout, $log, UtilityService, user, PropertyService) {
+
+ $scope.baseUrl = "";
+ $scope.responseTimeoutMsec = 10000;
+ $scope.msoMaxPollingIntervalMsec = 1000;
+ $scope.msoMaxPolls = 7;
+
+ $scope.init = function(properties) {
+ // takes a default value, retrieves the prop value from the file system and sets it
+ var msecs = PropertyService.retrieveMsoMaxPollingIntervalMsec(1000);
+ PropertyService.setMsoMaxPollingIntervalMsec(msecs);
+
+ // takes a default value, retrieves the prop value from the file system and sets it
+ var polls = PropertyService.retrieveMsoMaxPolls(7);
+ PropertyService.setMsoMaxPolls(polls);
+
+ PropertyService.setServerResponseTimeoutMsec(10000);
+
+ // These two properties only added for testing
+ properties.msoDefaultBaseUrl = $scope.baseUrl;
+ properties.responseTimeoutMsec = $scope.responseTimeoutMsec;
+
+ UtilityService.setProperties(properties);
+ }
+
+ $scope.autoGetSubs = function() {
+ /*
+ * Optionally comment in / out one of these method calls (or add a similar
+ * entry) to auto-invoke an entry when the test screen is redrawn.
+ */
+ $timeout(function() {
+ $scope.getSubscribers();
+ // $scope.deleteServiceInstance();
+ // $scope.generateInvalidUrl405();
+ }, 100);
+ }
+
+ $scope.autoGetSubDetails = function() {
+ /*
+ * Optionally comment in / out one of these method calls (or add a similar
+ * entry) to auto-invoke an entry when the test screen is redrawn.
+ */
+ $timeout(function() {
+ $scope.getSubDetails();
+ // $scope.deleteServiceInstance();
+ // $scope.generateInvalidUrl405();
+ }, 100);
+ }
+
+ $scope.autoPopulateViewEdit = function() {
+ /*
+ * Optionally comment in / out one of these method calls (or add a similar
+ * entry) to auto-invoke an entry when the test screen is redrawn.
+ */
+ $timeout(function() {
+ $scope.getComponentList();
+ // $scope.deleteServiceInstance();
+ // $scope.generateInvalidUrl405();
+ }, 100);
+ }
+
+ $scope.refreshSubs = function() {
+ /*
+ * Optionally comment in / out one of these method calls (or add a similar
+ * entry) to auto-invoke an entry when the test screen is redrawn.
+ */
+ $timeout(function() {
+ $scope.refreshSubscribers();
+ // $scope.deleteServiceInstance();
+ // $scope.generateInvalidUrl405();
+ }, 100);
+ }
+
+ $scope.autoStartQueryTest = function() {
+ /*
+ * Optionally comment in / out one of these method calls (or add a similar
+ * entry) to auto-invoke an entry when the test screen is redrawn.
+ */
+ $timeout(function() {
+ // $scope.queryServiceInstance();
+ }, 100);
+ }
+
+ $scope.queryServiceInstance = function() {
+ /*
+ * Example of method call needed to query a service instance.
+ */
+ $scope.$broadcast("queryServiceInstance", {
+ serviceInstanceId: "bc305d54-75b4-431b-adb2-eb6b9e546014"
+ });
+ }
+
+ $scope.getSubscribers = function() {
+ /*
+ * Example of method call needed to commit an instance creation request.
+ */
+ $scope.$broadcast("getSubs", {
+ url : "aai_get_subscribers",
+ requestDetails : createServiceRequestDetails
+ });
+ }
+
+ $scope.getSubDetails = function() {
+ /*
+ * Example of method call needed to commit an instance creation request.
+ */
+ $scope.$broadcast("getSubDetails", {
+ url : "aai_sub_details",
+ requestDetails : createServiceRequestDetails
+ });
+ }
+
+ $scope.getComponentList = function() {
+ /*
+ * Example of method call needed to commit an instance creation request.
+ */
+ $scope.$broadcast("getComponentList", {
+ url : "aai_sub_viewedit",
+ requestDetails : createServiceRequestDetails
+ });
+ }
+
+
+ $scope.refreshSubscribers = function() {
+ /*
+ * Example of method call needed to commit an instance creation request.
+ */
+ $scope.$broadcast("getSubs", {
+ url : "aai_refresh_subscribers",
+ requestDetails : createServiceRequestDetails
+ });
+ }
+
+ $scope.deleteServiceInstance = function() {
+ /*
+ * Example of method call needed to commit an instance deletion request.
+ */
+ $scope.$broadcast("deleteInstance", {
+ url : "mso_delete_svc_instance/bc305d54-75b4-431b-adb2-eb6b9e546014",
+ requestDetails : deleteServiceRequestDetails
+ });
+ }
+
+ $scope.createNetworkInstance = function() {
+ $scope.$broadcast("createInstance", {
+ url : "mso_create_nw_instance",
+ requestDetails : createNetworkRequestDetails
+ });
+ }
+
+ $scope.deleteNetworkInstance = function() {
+ $scope.$broadcast("deleteInstance", {
+ url : "mso_delete_nw_instance/bc305d54-75b4-431b-adb2-eb6b9e546014/networks/ff305d54-75b4-ff1b-fff1-eb6b9e5460ff",
+ requestDetails : deleteNetworkRequestDetails
+ });
+ }
+
+ $scope.generateError = function(testName) {
+ // Clone example request object
+ var request = JSON.parse(JSON.stringify(createServiceRequestDetails));
+ request.modelInfo.modelName = testName;
+ $scope.$broadcast("createInstance", {
+ url : "mso_create_svc_instance",
+ requestDetails : request
+ });
+ }
+
+ $scope.generateInvalidUrl404 = function() {
+ var properties = UtilityService.getProperties(properties);
+ properties.msoDefaultBaseUrl = "/INVALID_STRING/";
+ UtilityService.setProperties(properties);
+ $scope.$broadcast("refreshProperties");
+
+ $scope.$broadcast("createInstance", {
+ url : "mso_create_svc_instance",
+ requestDetails : createServiceRequestDetails
+ });
+
+ properties.msoDefaultBaseUrl = $scope.baseUrl;
+ UtilityService.setProperties(properties);
+ $scope.$broadcast("refreshProperties");
+ }
+
+ $scope.generateInvalidUrl405 = function() {
+ $scope.$broadcast("createInstance", {
+ url : "INVALID_STRING_mso_create_svc_instance",
+ requestDetails : createServiceRequestDetails
+ });
+ }
+
+ /*
+ * Test data objects:
+ */
+
+ var subscriberInfo = {
+ globalSubscriberId : "C12345",
+ subscriberName : "General Electric Division 12"
+ };
+
+ var createServiceRequestDetails = {
+ modelInfo : {
+ modelType : "service",
+ modelId : "sn5256d1-5a33-55df-13ab-12abad84e764",
+ modelNameVersionId : "ab6478e4-ea33-3346-ac12-ab121484a333",
+ modelName : "WanBonding",
+ modelVersion : "1"
+ },
+ subscriberInfo : subscriberInfo,
+ requestParameters : {
+ vpnId : "1a2b3c4d5e6f",
+ productName : "Trinity",
+ customerId : "icore9883749"
+ }
+ };
+
+ var deleteServiceRequestDetails = {
+ modelInfo : {
+ modelType : "service",
+ modelId : "sn5256d1-5a33-55df-13ab-12abad84e764",
+ modelNameVersionId : "ab6478e4-ea33-3346-ac12-ab121484a333",
+ modelName : "WanBonding",
+ modelVersion : "1"
+ }
+ };
+
+ var createNetworkRequestDetails = {
+ modelInfo : {
+ modelType : "network",
+ modelId : "ff5256d1-5a33-55df-aaaa-12abad84e7ff",
+ modelNameVersionId : "fe6478e4-ea33-3346-aaaa-ab121484a3fe",
+ modelName : "vIsbcOamNetwork",
+ modelVersion : "1"
+ },
+ relatedModelList : [
+ {
+ relatedModel : {
+ instanceId : "ff305d54-75b4-431b-adb2-eb6b9e5ff000",
+ modelInfo : {
+ modelType : "service",
+ modelId : "ff3514e3-5a33-55df-13ab-12abad84e7ff",
+ modelNameVersionId : "fe6985cd-ea33-3346-ac12-ab121484a3fe",
+ modelName : "Intercarrier Interconnect Session Border Controller",
+ modelVersion : "1"
+ }
+ }
+ },
+ {
+ relatedModel : {
+ instanceId : "ff305d54-75b4-ff1b-adb2-eb6b9e5460ff",
+ modelInfo : {
+ modelType : "vnf",
+ modelId : "ff5256d1-5a33-55df-13ab-12abad84e7ff",
+ modelNameVersionId : "fe6478e4-ea33-3346-ac12-ab121484a3fe",
+ modelName : "vIsbc",
+ modelVersion : "1"
+ }
+ }
+ },
+ {
+ relatedModel : {
+ instanceId : "ff305d54-75b4-ff1b-bdb2-eb6b9e5460ff",
+ modelInfo : {
+ modelType : "vfModule",
+ modelId : "ff5256d1-5a33-55df-13ab-22abad84e7ff",
+ modelNameVersionId : "fe6478e4-ea33-3346-bc12-ab121484a3fe",
+ modelName : "vIsbcRtpExpansionModule",
+ modelVersion : "1"
+ }
+ }
+ } ],
+ subscriberInfo : subscriberInfo,
+ requestParameters : {
+ /*
+ * FYI: quotes around field names are needed due to embedded "-"
+ * characters
+ */
+ "cidr-mask" : "255.255.255.000",
+ "gateway-address" : "10.10.125.1",
+ "dhcp-enabled" : "true"
+ }
+ };
+
+ var deleteNetworkRequestDetails = {
+ modelInfo : {
+ modelType : "network",
+ modelId : "ff5256d1-5a33-55df-aaaa-12abad84e7ff",
+ modelNameVersionId : "fe6478e4-ea33-3346-aaaa-ab121484a3fe",
+ modelName : "vIsbcOamNetwork",
+ modelVersion : "1"
+ },
+ relatedModelList : [
+ {
+ relatedModel : {
+ instanceId : "ff305d54-75b4-431b-adb2-eb6b9e5ff000",
+ modelInfo : {
+ modelType : "service",
+ modelId : "ff3514e3-5a33-55df-13ab-12abad84e7ff",
+ modelNameVersionId : "fe6985cd-ea33-3346-ac12-ab121484a3fe",
+ modelName : "Intercarrier Interconnect Session Border Controller",
+ modelVersion : "1"
+ }
+ }
+ },
+ {
+ relatedModel : {
+ instanceId : "ff305d54-75b4-ff1b-adb2-eb6b9e5460ff",
+ modelInfo : {
+ modelType : "vnf",
+ modelId : "ff5256d1-5a33-55df-13ab-12abad84e7ff",
+ modelNameVersionId : "fe6478e4-ea33-3346-ac12-ab121484a3fe",
+ modelName : "vIsbc",
+ modelVersion : "1"
+ }
+ }
+ },
+ {
+ relatedModel : {
+ instanceId : "ff305d54-75b4-ff1b-bdb2-eb6b9e5460ff",
+ modelInfo : {
+ modelType : "vfModule",
+ modelId : "ff5256d1-5a33-55df-13ab-22abad84e7ff",
+ modelNameVersionId : "fe6478e4-ea33-3346-bc12-ab121484a3fe",
+ modelName : "vIsbcRtpExpansionModule",
+ modelVersion : "1"
+ }
+ }
+ } ]
+ };
+ $scope.getSubscriberDet = function(selectedCustomer){
+ window.location.href = '#subdetails?selectedSubscriber=' + selectedCustomer;
+ };
+ }
+]);
diff --git a/vid/src/main/webapp/app/vid/scripts/directives/dummy.txt b/vid/src/main/webapp/app/vid/scripts/directives/dummy.txt
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/vid/src/main/webapp/app/vid/scripts/directives/dummy.txt
diff --git a/vid/src/main/webapp/app/vid/scripts/directives/extensionsDirective.js b/vid/src/main/webapp/app/vid/scripts/directives/extensionsDirective.js
new file mode 100644
index 000000000..1309a0f62
--- /dev/null
+++ b/vid/src/main/webapp/app/vid/scripts/directives/extensionsDirective.js
@@ -0,0 +1,79 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * 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=========================================================
+ */
+
+"use strict";
+
+/*
+ * Defines "extensions" to standard Angular directives. Provides attributes that
+ * can be included in HTML tags.
+ *
+ * SYNTAX: ngx-enabled="true | false"
+ *
+ * Enables / disables an element. Currently only supports button elements that
+ * include the "att-button" element. This extension was added since the similar
+ * standard Angular "ng-disabled" attribute does not handle buttons that use the
+ * ECOMP styling.
+ *
+ * SYNTAX: ngx-visible="true | false"
+ *
+ * Sets an element to visible / hidden. Different from ng-show / ng-hide as
+ * follows:
+ *
+ * ng-show=false or ng-hide=true - Element is completely hidden.
+ *
+ * ngx-visible=false - Element is not displayed. However, a blank area is
+ * displayed where the element would display if ngx-visible is set to true.
+ */
+
+app.directive('ngxEnabled', function() {
+ return {
+ restrict : "A",
+ link : function(scope, element, attrs) {
+ attrs.$observe("ngxEnabled", function(value) {
+ if (attrs.attButton === "") {
+ if (value === "true") {
+ element.attr("btn-type", "primary").removeClass(
+ "button--inactive").addClass("button--primary")
+ .prop('disabled', false);
+ } else {
+ element.attr("btn-type", "disabled").removeClass(
+ "button--primary").addClass("button--inactive")
+ .prop('disabled', true);
+ }
+ }
+ });
+ }
+ }
+});
+
+app.directive('ngxVisible', function() {
+ return {
+ restrict : "A",
+ link : function(scope, element, attrs) {
+ attrs.$observe("ngxVisible", function(value) {
+ if (value === "true") {
+ element.css("visibility", "visible");
+ } else {
+ element.css("visibility", "hidden");
+ }
+ });
+ }
+ }
+});
diff --git a/vid/src/main/webapp/app/vid/scripts/directives/parameterBlockDirective.js b/vid/src/main/webapp/app/vid/scripts/directives/parameterBlockDirective.js
new file mode 100644
index 000000000..16d2387c4
--- /dev/null
+++ b/vid/src/main/webapp/app/vid/scripts/directives/parameterBlockDirective.js
@@ -0,0 +1,309 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * 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=========================================================
+ */
+
+"use strict";
+
+var parameterBlockDirective = function($log, PARAMETER, UtilityService) {
+ /*
+ * If "IS_SINGLE_OPTION_AUTO_SELECTED" is set to "true" ...
+ *
+ * IF these 3 conditions all exist:
+ *
+ * 1) The parameter type is PARAMETER.SELECT
+ *
+ * 2) AND the "prompt" attribute is set to a string.
+ *
+ * 3) AND the optionList" only contains a single entry
+ *
+ * THEN the "prompt" will not be displayed as an initial select option.
+ */
+
+ var IS_SINGLE_OPTION_AUTO_SELECTED = false;
+
+ /*
+ * Optionally remove "nameStyle" and "valueStyle" "width" entries to set
+ * dynamic sizing.
+ */
+ var tableStyle = "width: auto; margin: 0 auto; border-collapse: collapse; border: none;";
+ var nameStyle = "width: 220px; text-align: left; vertical-align: middle; font-weight: bold; padding: 3px 5px; border: none;";
+ var valueStyle = "width: 400px; text-align: left; vertical-align: middle; padding: 3px 5px; border: none;";
+ var checkboxValueStyle = "width: 400px; text-align: center; vertical-align: middle; padding: 3px 5px; border: none;"
+ var textInputStyle = "height: 25px; padding: 2px 5px;";
+ var checkboxInputStyle = "height: 18px; width: 18px; padding: 2px 5px;";
+ var selectStyle = "height: 25px; padding: 2px; text-align: center;";
+ var requiredLabelStyle = "width: 25px; padding: 5px 10px 10px 5px;";
+ var textInputPrompt = "Enter data";
+
+ var getParameterHtml = function(parameter, editable) {
+ var style = valueStyle;
+ var attributeString = "";
+ if (parameter.type === PARAMETER.BOOLEAN) {
+ style = checkboxValueStyle;
+ }
+ if (UtilityService.hasContents(parameter.description)) {
+ attributeString += " title=' " + parameter.description + " '";
+ }
+ var html = "<tr><td style='" + nameStyle + "'" + attributeString + ">"
+ + getNameHtml(parameter) + "</td><td style='" + style + "'>";
+ if (editable === undefined) {
+ if (UtilityService.hasContents(parameter.value)) {
+ html += parameter.value;
+ }
+ } else {
+ html += getValueHtml(parameter);
+ }
+ html += "</td></tr>";
+ return html;
+ };
+
+ var updateParameter = function(parameter, element, editable) {
+ $(element).parent().parent().children("td").first().html(
+ getNameHtml(parameter));
+ if (editable === undefined) {
+ $(element).html(parameter.value);
+ } else {
+ $(element).parent().html(getValueHtml(parameter));
+ }
+ };
+
+ var getNameHtml = function(parameter) {
+ if (parameter.isVisible === false) {
+ return "";
+ }
+ var name = "";
+ if (UtilityService.hasContents(parameter.name)) {
+ name = parameter.name;
+ } else {
+ name = parameter.id;
+ }
+ var requiredLabel = "";
+ if (parameter.isRequired) {
+ requiredLabel = "<img src='app/vid/images/asterisk.png' style='"
+ + requiredLabelStyle + "'></img>";
+ }
+ return name + ":" + requiredLabel;
+ };
+
+ var getValueHtml = function(parameter) {
+ var attributeString = " parameter-id='" + parameter.id + "'";
+ var additionalStyle = "";
+ if (parameter.isEnabled === false) {
+ attributeString += " disabled='disabled'";
+ }
+ if (parameter.isRequired) {
+ attributeString += " is-required='true'";
+ }
+ if (UtilityService.hasContents(parameter.description)) {
+ attributeString += " title=' " + parameter.description + " '";
+ }
+ if (parameter.isVisible === false) {
+ additionalStyle = "visibility: hidden;";
+ }
+ var name = "";
+ if (UtilityService.hasContents(parameter.name)) {
+ name = parameter.name;
+ } else {
+ name = parameter.id;
+ }
+ attributeString += " parameter-name='" + name + "'";
+
+ switch (parameter.type) {
+ case PARAMETER.BOOLEAN:
+ if (parameter.value) {
+ attributeString += " checked='checked'";
+ }
+ return "<input type='checkbox'" + attributeString + " style='"
+ + checkboxInputStyle + additionalStyle + "'></input>";
+ break;
+ case PARAMETER.SELECT:
+ if (UtilityService.hasContents(parameter.prompt)) {
+ attributeString += " prompt='" + parameter.prompt + "'";
+ }
+ return "<select" + attributeString + " style='" + selectStyle
+ + additionalStyle + "'>" + getOptionListHtml(parameter)
+ + "</select>";
+ break;
+ case PARAMETER.STRING:
+ default:
+ var value = "";
+ if (UtilityService.hasContents(parameter.value)) {
+ value = " value='" + parameter.value + "'";
+ }
+ if (UtilityService.hasContents(parameter.prompt)) {
+ attributeString += " placeholder='" + parameter.prompt + "'";
+ } else if (textInputPrompt !== "") {
+ attributeString += " placeholder='" + textInputPrompt + "'";
+ }
+ return "<input type='text'" + attributeString + " style='"
+ + textInputStyle + additionalStyle + "'" + value
+ + "></input>";
+ }
+ };
+
+ var getOptionListHtml = function(parameter) {
+
+ var html = "";
+
+ if (!angular.isArray(parameter.optionList)
+ || parameter.optionList.length === 0) {
+ return "";
+ }
+
+ if (UtilityService.hasContents(parameter.prompt)) {
+ if (!(IS_SINGLE_OPTION_AUTO_SELECTED && parameter.optionList.length === 1)) {
+ html += "<option value=''>" + parameter.prompt + "</option>";
+ }
+ }
+
+ for (var i = 0; i < parameter.optionList.length; i++) {
+ var option = parameter.optionList[i];
+ var name = option.name;
+ var value = "";
+ if (option.id === undefined) {
+ value = option.name;
+ } else {
+ if (name === undefined) {
+ name = option.id;
+ }
+ value = option.id;
+ }
+ html += "<option value='" + value + "'>" + name + "</option>";
+ }
+ return html;
+ };
+
+ var getParameter = function(element, expectedId) {
+ var id = $(element).attr("parameter-id");
+ if (expectedId !== undefined && expectedId !== id) {
+ return undefined;
+ }
+ var parameter = {
+ id : id
+ };
+ if ($(element).prop("type") === "checkbox") {
+ parameter.value = $(element).prop("checked");
+ } else {
+ if ($(element).prop("type") === "text") {
+ $(element).val($(element).val().trim());
+ }
+ parameter.value = $(element).val();
+ }
+ if ($(element).prop("selectedIndex") === undefined) {
+ parameter.selectedIndex = -1;
+ } else {
+ parameter.selectedIndex = $(element).prop("selectedIndex");
+ if (UtilityService.hasContents($(element).attr("prompt"))) {
+ parameter.selectedIndex--;
+ }
+ }
+ return parameter;
+ };
+
+ var getRequiredField = function(element) {
+ if ($(element).prop("type") === "text") {
+ $(element).val($(element).val().trim());
+ }
+ if ($(element).val() === "" || $(element).val() === null) {
+ return '"' + $(element).attr("parameter-name") + '"';
+ } else {
+ return "";
+ }
+ };
+
+ var callback = function(element, scope) {
+ scope.callback({
+ id : $(element).attr("parameter-id")
+ });
+ };
+
+ return {
+ restrict : "EA",
+ replace : true,
+ template : "<div><table style='" + tableStyle + "'></table></div>",
+ scope : {
+ control : "=",
+ callback : "&"
+ },
+ link : function(scope, element, attrs) {
+
+ var control = scope.control || {};
+
+ control.setList = function(parameterList) {
+ var html = "";
+ for (var i = 0; i < parameterList.length; i++) {
+ html += getParameterHtml(parameterList[i], attrs.editable);
+ }
+ element.html(html);
+ element.find("input, select").bind("change", function() {
+ callback(this, scope);
+ });
+ }
+
+ control.updateList = function(parameterList) {
+ element.find("input, select").each(
+ function() {
+ for (var i = 0; i < parameterList.length; i++) {
+ if (parameterList[i].id === $(this).attr(
+ "parameter-id")) {
+ updateParameter(parameterList[i], this,
+ attrs.editable);
+ }
+ }
+ });
+ }
+
+ control.getList = function(expectedId) {
+ var parameterList = new Array();
+ element.find("input, select").each(function() {
+ var parameter = getParameter(this, expectedId);
+ if (parameter !== undefined) {
+ parameterList.push(parameter);
+ }
+ });
+ return parameterList;
+ }
+
+ control.getRequiredFields = function() {
+ var requiredFields = "";
+ var count = 0;
+ element.find("input, select").each(function() {
+ if ($(this).attr("is-required") === "true") {
+ var requiredField = getRequiredField(this);
+ if (requiredField !== "") {
+ if (++count == 1) {
+ requiredFields = requiredField;
+ }
+ }
+ }
+ });
+ if (--count <= 0) {
+ return requiredFields;
+ } else if (count == 1) {
+ return requiredFields + " and 1 other field";
+ } else {
+ return requiredFields + " and " + count + " other fields";
+ }
+ }
+ }
+ }
+}
+
+app.directive('parameterBlock', [ "$log", "PARAMETER", "UtilityService",
+ parameterBlockDirective ]);
diff --git a/vid/src/main/webapp/app/vid/scripts/directives/popupWindowDirective.js b/vid/src/main/webapp/app/vid/scripts/directives/popupWindowDirective.js
new file mode 100644
index 000000000..a52d5862a
--- /dev/null
+++ b/vid/src/main/webapp/app/vid/scripts/directives/popupWindowDirective.js
@@ -0,0 +1,88 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * 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=========================================================
+ */
+
+"use strict";
+
+var popupWindowDirective = function($log, $window) {
+
+ function getZIndex(element) {
+ var maxZIndex = 0;
+ $(window.document).find("*").each(function() {
+ var zIndex = parseInt($(this).css("z-index"));
+ if (zIndex > maxZIndex) {
+ maxZIndex = zIndex;
+ }
+ });
+
+ return maxZIndex;
+ }
+
+ var scrollPosition = {
+ x : 0,
+ y : 0
+ };
+
+ var link = function(scope, element, attrs, controller, transcludeFn) {
+
+ var zIndex = getZIndex(element.parent()) + 1;
+
+ element.css("z-index", zIndex + 1);
+
+ var backgroundStyle = "display: none; position: fixed; z-index:"
+ + zIndex + ";" + "top: 0; left: 0; width: 100%; height: 100%;"
+ + "background-color: #000000; opacity: 0.5";
+
+ var className = attrs["class"];
+ var classString = "";
+ if (className !== undefined && className !== null && className !== "") {
+ element.children().children().children().children().addClass(
+ className);
+ element.removeClass(className);
+ }
+
+ element.before("<div style='" + backgroundStyle + "'></div>");
+
+ attrs.$observe("ngxShow", function(value) {
+ if (value === "true") {
+ scrollPosition = {
+ x : $window.pageXOffset,
+ y : $window.pageYOffset
+ }
+ $window.scrollTo(0, 0);
+ element.css("display", "table");
+ element.prev().css("display", "block");
+ } else if (value === "false") {
+ element.css("display", "none");
+ element.prev().css("display", "none");
+ $window.scrollTo(scrollPosition.x, scrollPosition.y);
+ }
+ });
+ }
+
+ return {
+ restrict : "EA",
+ transclude : true,
+ replace : true,
+ link : link,
+ templateUrl : "app/vid/scripts/view-models/popupWindow.htm"
+ };
+}
+
+app.directive("popupWindow", [ "$log", "$window", popupWindowDirective ]);
diff --git a/vid/src/main/webapp/app/vid/scripts/directives/progressBarDirective.js b/vid/src/main/webapp/app/vid/scripts/directives/progressBarDirective.js
new file mode 100644
index 000000000..5ffada8a3
--- /dev/null
+++ b/vid/src/main/webapp/app/vid/scripts/directives/progressBarDirective.js
@@ -0,0 +1,173 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * 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=========================================================
+ */
+
+"use strict";
+
+/*
+ * "progressBarDirective.js" provides a progress bar directive.
+ *
+ * SYNTAX:
+ *
+ * <div progress-bar value="percentProgress"></div>
+ *
+ * "percentProgress" is the numeric percent progress to be displayed (0 to 100)
+ * expressed as a number only (i.e. no trailing "%"). An "scoped" Angular value
+ * can be used (e.g. "{{percentProgress}}").
+ *
+ * Two additional attributes can also be included:
+ *
+ * increases-only="true | false"
+ *
+ * Normally, the progress bar always updates the display with whatever value is
+ * set. Alternatively, if "increases-only" is set to "true", the display will
+ * only be updated if "percentProgress" is >= the previous value.
+ *
+ * control="control"
+ *
+ * Provides a method ... $scope.control.reset()" ... that a controller can call
+ * to reset the progress to it's initial zero state. This would only expected to
+ * be needed if A) increases-only is set to true and B) there is a need to reset
+ * the controller to 0. If increases-only is set to false or not present, an
+ * alternative method of resetting the progress is to just tset percentProgress
+ * to 0.
+ *
+ * CAVEATS:
+ *
+ * 1) The extended attribute "ngx-show" should be used instead of "ng-show" if
+ * the control needs to be conditionally visible. Example:
+ * ngx-show="{{isProgressVisible}}"
+ *
+ * 2) $scope.control.reset() should be conditionally called as follows IF it is
+ * called immediately after HTML is rendered. This is due to a timing-related
+ * behavior.
+ *
+ * 3) The progress bar displays values of "0" and "100" if precentProgress is,
+ * respectively, less than 0 or greater than 100.
+ *
+ * CUSTOM STYLING:
+ *
+ * The ECOMP portal styling uses the class named "progress". The class
+ * attributes can be overridden in CSS. This example was tested:
+ *
+ * .progress { margin: 0px 10px; height: 40px }
+ *
+ * Additional styling can be applied to the progress-bar element. Example:
+ *
+ * div[progress-bar=""] { padding-top: 10px; }
+ *
+ * if (angular.isFunction($scope.control.reset)) { $scope.control.reset(); }
+ *
+ * DEPENDENCIES:
+ *
+ * This code assumes dependency files provided by the ECOMP Portal framework are
+ * included. For example, ".../app/fusion/external/ebz/sandbox/styles/base.css"
+ * is one required dependency. There may also be others.
+ */
+
+var progressBarDirective = function() {
+
+ var style = "font-weight: bold;";
+ /*
+ * The 3 "aria-*" properties were added as per an Internet reference
+ * example. These appear to have no impact on current behavior but are
+ * retained for future reference.
+ */
+ var properties = "class='progress-bar' role='progressbar' "
+ + "aria-valuenow='' aria-valuemin='0' aria-valuemax='100'";
+ var previousValue = 0;
+
+ var updateProgress = function(element, attrs, valueAsString) {
+ if (valueAsString === undefined || valueAsString === null
+ || valueAsString === "") {
+ valueAsString = "0";
+ }
+ var valueAsInteger = parseInt(valueAsString);
+ if (valueAsInteger > 100) {
+ valueAsInteger = 100;
+ valueAsString = "100";
+ }
+ if (attrs.increasesOnly === "true") {
+ if (valueAsInteger >= previousValue) {
+ previousValue = valueAsInteger;
+ } else {
+ return;
+ }
+ }
+ element.css("width", valueAsString + "%");
+ if (valueAsInteger >= 100) {
+ element.removeClass("progress-bar-info").addClass(
+ "progress-bar-success");
+ } else {
+ element.removeClass("progress-bar-success").addClass(
+ "progress-bar-info");
+ }
+ if (valueAsInteger >= 5) {
+ element.html(valueAsString + " %");
+ } else {
+ /*
+ * Hide text since color combination is barely visible when progress
+ * portion is narrow.
+ */
+ element.html("");
+ }
+ }
+
+ return {
+ restrict : "EA",
+ transclude : true,
+ replace : true,
+ template : "<div ng-transclude " + properties + " style='" + style
+ + "'></div>",
+ scope : {
+ control : "=",
+ progressBar : "@"
+ },
+ link : function(scope, element, attrs) {
+
+ /*
+ * It should be possible to alternatively add this wrapper in the
+ * template instead of using "element.wrap". Some techniques were
+ * attempted but were unsuccessful.
+ */
+ element.wrap("<div class='progress'></div");
+
+ var control = scope.control || {};
+
+ control.reset = function() {
+ previousValue = 0;
+ updateProgress(element, attrs, 0);
+ }
+
+ attrs.$observe("value", function(valueString) {
+ updateProgress(element, attrs, valueString);
+ });
+
+ attrs.$observe("ngxShow", function(valueString) {
+ if (valueString === "false") {
+ element.parent().hide();
+ } else {
+ element.parent().show();
+ }
+ });
+ }
+ }
+}
+
+app.directive("progressBar", progressBarDirective);
diff --git a/vid/src/main/webapp/app/vid/scripts/services/aaiService.js b/vid/src/main/webapp/app/vid/scripts/services/aaiService.js
new file mode 100644
index 000000000..063f7a988
--- /dev/null
+++ b/vid/src/main/webapp/app/vid/scripts/services/aaiService.js
@@ -0,0 +1,111 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * 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=========================================================
+ */
+
+"use strict";
+
+var AaiService = function($http, $log, PropertyService, UtilityService) {
+ return {
+ getSubscriptionServiceTypeList : function(globalCustomerId,
+ successCallbackFunction) {
+ $log
+ .debug("AaiService:getSubscriptionServiceTypeList: globalCustomerId: "
+ + globalCustomerId);
+ $http.get(
+ PropertyService.getAaiBaseUrl()
+ + "/aai_sub_details/"
+ + globalCustomerId + "?r=" + Math.random(),
+ {
+ timeout : PropertyService
+ .getServerResponseTimeoutMsec()
+ }).then(function(response) {
+ if (response.data && response.data["service-subscriptions"]) {
+ var serviceTypes = [];
+ var serviceSubscriptions = response.data["service-subscriptions"]["service-subscription"];
+
+ for (var i = 0; i < serviceSubscriptions.length; i++) {
+ serviceTypes.push(serviceSubscriptions[i]["service-type"]);
+ }
+
+ successCallbackFunction(serviceTypes);
+ } else {
+ successCallbackFunction([]);
+ }
+ })["catch"]
+ (UtilityService.runHttpErrorHandler);
+ },
+ getLcpCloudRegionTenantList : function(globalCustomerId, serviceType,
+ successCallbackFunction) {
+ $log
+ .debug("AaiService:getLcpCloudRegionTenantList: globalCustomerId: "
+ + globalCustomerId);
+ var url = PropertyService.getAaiBaseUrl()
+ + "/aai_get_tenants/"
+ + globalCustomerId + "/" + serviceType + "?r=" + Math.random();
+
+ $http.get(url,
+ {
+ timeout : PropertyService
+ .getServerResponseTimeoutMsec()
+ }).then(function(response) {
+ var lcpCloudRegionTenants = [];
+ var aaiLcpCloudRegionTenants = response.data;
+
+ lcpCloudRegionTenants.push({
+ "cloudRegionId": "",
+ "tenantName": "Please choose a region",
+ "tenantId": ""
+ });
+
+ for (var i = 0; i < aaiLcpCloudRegionTenants.length; i++) {
+ lcpCloudRegionTenants.push({
+ "cloudRegionId": aaiLcpCloudRegionTenants[i]["cloudRegionID"],
+ "tenantName": aaiLcpCloudRegionTenants[i]["tenantName"],
+ "tenantId": aaiLcpCloudRegionTenants[i]["tenantID"]
+ });
+ }
+
+ successCallbackFunction(lcpCloudRegionTenants);
+ })["catch"]
+ (UtilityService.runHttpErrorHandler);
+ },
+ getSubscribers : function(successCallbackFunction) {
+ $log
+ .debug("AaiService:getSubscribers");
+ var url = PropertyService.getAaiBaseUrl()
+ + "/aai_get_subscribers?r=" + Math.random();
+
+ $http.get(url,
+ {
+ timeout : PropertyService
+ .getServerResponseTimeoutMsec()
+ }).then(function(response) {
+ if (response.data) {
+ successCallbackFunction(response.data.customer);
+ } else {
+ successCallbackFunction([]);
+ }
+ })["catch"]
+ (UtilityService.runHttpErrorHandler);
+ }
+ }
+}
+
+app.factory("AaiService", [ "$http", "$log", "PropertyService",
+ "UtilityService", AaiService ]);
diff --git a/vid/src/main/webapp/app/vid/scripts/services/asdcService.js b/vid/src/main/webapp/app/vid/scripts/services/asdcService.js
new file mode 100644
index 000000000..532b8f508
--- /dev/null
+++ b/vid/src/main/webapp/app/vid/scripts/services/asdcService.js
@@ -0,0 +1,40 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * 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=========================================================
+ */
+
+"use strict";
+
+var AsdcService = function($http, $log, PropertyService, UtilityService) {
+ return {
+ getModel : function(modelId, successCallbackFunction) {
+ $log.debug("SdcService:getModel: modelId: " + modelId);
+ $http.get(
+ PropertyService.getAsdcBaseUrl() + "/getModel/" + modelId
+ + "?r=" + Math.random(),
+ {
+ timeout : PropertyService
+ .getServerResponseTimeoutMsec()
+ }).then(successCallbackFunction)["catch"]
+ (UtilityService.runHttpErrorHandler);
+ }
+ }
+}
+
+app.factory("AsdcService", [ "$http", "$log", "PropertyService",
+ "UtilityService", AsdcService ]);
diff --git a/vid/src/main/webapp/app/vid/scripts/services/componentService.js b/vid/src/main/webapp/app/vid/scripts/services/componentService.js
new file mode 100644
index 000000000..7c1cfcb9c
--- /dev/null
+++ b/vid/src/main/webapp/app/vid/scripts/services/componentService.js
@@ -0,0 +1,148 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * 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=========================================================
+ */
+
+"use strict";
+
+var ComponentService = function($log, COMPONENT, UtilityService) {
+
+ var _this = this;
+
+ var componentList = [ {
+ id : COMPONENT.NETWORK,
+ displayName : "Network"
+ }, {
+ id : COMPONENT.SERVICE,
+ displayName : "Service Instance"
+ }, {
+ id : COMPONENT.VNF,
+ displayName : "Virtual Network Function"
+ }, {
+ id : COMPONENT.VF_MODULE,
+ displayName : "VF Module"
+ }, {
+ id : COMPONENT.VOLUME_GROUP,
+ displayName : "Volume Group"
+ } ];
+
+ var getInventoryInfo = function(suffix, inventoryItem) {
+ var pattern = new RegExp(suffix + "-");
+ for ( var key in inventoryItem) {
+ if (pattern.exec(key)) {
+ return inventoryItem[key];
+ }
+ }
+ };
+
+ /*
+ * Converts 'id' to a user friendly version.
+ *
+ * The algorithm used is:
+ *
+ * 1) If "id" found in COMPONENT.FULL_NAME_MAP, return the name found in the
+ * map.
+ *
+ * 2) Otherwise, if camel case, add "-" between camel case words.
+ *
+ * 3) Split id into multiple "partial names" assuming "-" is the delimiter.
+ *
+ * 4) Map any partial names found in COMPONENT.PARTIAL_NAME_MAP to the name
+ * found in the map.
+ *
+ * 5) Use partial names whenever not found in map.
+ *
+ * 5) Return name by combining all partial names with " " delimiter.
+ */
+ var getDisplayName = function(id) {
+ var tmp = COMPONENT.FULL_NAME_MAP[id.toLowerCase()];
+ if (UtilityService.hasContents(tmp)) {
+ return tmp;
+ }
+ /*
+ * Add "-" if camel case found.
+ */
+ var id = id.replace(/([a-z](?=[A-Z]))/g, '$1-');
+ var name = "";
+ var arg = id.split("-");
+ for (var i = 0; i < arg.length; i++) {
+ if (i > 0) {
+ name += " ";
+ }
+ var tmp = COMPONENT.PARTIAL_NAME_MAP[arg[i].toLowerCase()];
+ if (UtilityService.hasContents(tmp)) {
+ name += tmp;
+ } else {
+ name += arg[i].slice(0, 1).toUpperCase() + arg[i].slice(1);
+ }
+ }
+ return name;
+ };
+
+ return {
+ initialize : function(componentId) {
+ for (var i = 0; i < componentList.length; i++) {
+ if (componentList[i].id === componentId) {
+ _this.componentId = componentList[i].id;
+ return componentId;
+ }
+ }
+ throw "ComponentService:initializeComponent: componentId not found: "
+ + componentId;
+ },
+ getComponentDisplayName : function() {
+ for (var i = 0; i < componentList.length; i++) {
+ if (componentList[i].id === _this.componentId) {
+ return componentList[i].displayName;
+ }
+ }
+ },
+ getInventoryInfo : getInventoryInfo,
+ getInventoryParameterList : function(suffix, inventoryItem) {
+ var parameterList = new Array();
+ // var pattern = new RegExp("-[intv][a-z]*$");
+ // var inventoryInfo = getInventoryInfo(suffix, inventoryItem);
+ for ( var id in inventoryItem) {
+ //if (pattern.exec(id)) {
+ parameterList.push({
+ id : id,
+ value : inventoryItem[id]
+ });
+ //}
+ }
+ return parameterList;
+ },
+ getDisplayNames : function(inputList) {
+ var outputList = new Array();
+ for (var i = 0; i < inputList.length; i++) {
+ var entry = angular.copy(inputList[i]);
+ if (!UtilityService.hasContents(entry.name)) {
+ entry.name = getDisplayName(entry.id);
+ }
+ outputList.push(entry);
+ }
+ return outputList;
+ },
+ getFieldDisplayName : function(name) {
+ return getDisplayName(name);
+ }
+ }
+}
+
+app.factory("ComponentService", [ "$log", "COMPONENT", "UtilityService",
+ ComponentService ]);
diff --git a/vid/src/main/webapp/app/vid/scripts/services/creationService.js b/vid/src/main/webapp/app/vid/scripts/services/creationService.js
new file mode 100644
index 000000000..fda27eac3
--- /dev/null
+++ b/vid/src/main/webapp/app/vid/scripts/services/creationService.js
@@ -0,0 +1,683 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * 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=========================================================
+ */
+
+"use strict";
+
+/*
+ * "CreationService" isolates the "component-specific" logic required by the
+ * "CreationDialog" controller.
+ *
+ * "Components" are defined as the 5 element types managed by the dialogs: A)
+ * Service B) VNF C) VF Module D) Volume Group and E) Network.
+ *
+ */
+
+var CreationService = function($log, AaiService, AsdcService, DataService,
+ ComponentService, COMPONENT, FIELD, PARAMETER, UtilityService) {
+
+ var _this = this;
+
+ var getAsyncOperationList = function() {
+ switch (_this.componentId) {
+ case COMPONENT.SERVICE:
+ return [ getSubscribers ];
+ case COMPONENT.NETWORK:
+ return [];
+ case COMPONENT.VNF:
+ return [ getLcpCloudRegionTenantList ];
+ case COMPONENT.VF_MODULE:
+ return [ getLcpCloudRegionTenantList ];
+ case COMPONENT.VOLUME_GROUP:
+ return [ getLcpCloudRegionTenantList ];
+ }
+ };
+
+ /*
+ * "getSummaryList" and "getUserProvidedList" return parameters that should
+ * be displayed in the summary and user provided sections, respectively. The
+ * functions are expected to return lists that are in the format needed by
+ * the parameter-block directive.
+ */
+
+ var getSummaryList = function() {
+
+ /*
+ * These placeholders should be removed and their usage in
+ * "getSummaryList" should be replaced by appropriate code as the
+ * requirements and interfaces firm up.
+ */
+
+ var PLACEHOLDER_RESOURCE_DESCRIPTION = "Resource Description (PLACEHOLDER)";
+ var PLACEHOLDER_SERVICE_CATEGORY = "Service Category (PLACEHOLDER)";
+ var PLACEHOLDER_VF_MODULE_DESCRIPTION = "VF Module Description (PLACEHOLDER)";
+ var PLACEHOLDER_VF_MODULE_LABEL = "VF Module Label (PLACEHOLDER)";
+ var PLACEHOLDER_VF_MODULE_TYPE = "VF Module Type (PLACEHOLDER)";
+
+ _this.parameterList = new Array();
+
+ /*
+ * Common fields displayed at the top of all create instance screens.
+ */
+ addToList(FIELD.NAME.SERVICE_NAME, DataService.getServiceName());
+
+ switch (_this.componentId) {
+ case COMPONENT.SERVICE:
+ addToList(FIELD.NAME.SERVICE_INVARIANT_UUID, DataService
+ .getModelInfo(_this.componentId)["modelInvariantId"]);
+ addToList(FIELD.NAME.SERVICE_VERSION, DataService
+ .getModelInfo(_this.componentId)["modelVersion"]);
+ addToList(FIELD.NAME.SERVICE_UUID, DataService
+ .getModelInfo(_this.componentId)["modelNameVersionId"]);
+ addToList(FIELD.NAME.SERVICE_DESCRIPTION, DataService
+ .getModelInfo(_this.componentId)["description"]);
+ addToList(FIELD.NAME.SERVICE_CATEGORY, DataService
+ .getModelInfo(_this.componentId)["category"]);
+ break;
+ case COMPONENT.VF_MODULE:
+ addToList(FIELD.NAME.SUBSCRIBER_NAME, DataService
+ .getSubscriberName());
+ addToList(FIELD.NAME.SERVICE_INSTANCE_NAME, DataService
+ .getServiceInstanceName());
+ addToList(FIELD.NAME.MODEL_NAME, DataService
+ .getModelInfo(_this.componentId)["modelName"]);
+ addToList(FIELD.NAME.MODEL_INVARIANT_UUID, DataService
+ .getModelInfo(_this.componentId)["modelInvariantId"]);
+ addToList(FIELD.NAME.MODEL_VERSION, DataService
+ .getModelInfo(_this.componentId)["modelVersion"]);
+ addToList(FIELD.NAME.MODEL_UUID, DataService
+ .getModelInfo(_this.componentId)["modelNameVersionId"]);
+ break;
+ case COMPONENT.NETWORK:
+ case COMPONENT.VNF:
+ case COMPONENT.VOLUME_GROUP:
+ addToList(FIELD.NAME.SUBSCRIBER_NAME, DataService
+ .getSubscriberName());
+ addToList(FIELD.NAME.SERVICE_INSTANCE_NAME, DataService
+ .getServiceInstanceName());
+ addToList(FIELD.NAME.MODEL_NAME, DataService
+ .getModelInfo(_this.componentId)["modelName"]);
+ addToList(FIELD.NAME.MODEL_INVARIANT_UUID, DataService
+ .getModelInfo(_this.componentId)["modelInvariantId"]);
+ addToList(FIELD.NAME.MODEL_VERSION, DataService
+ .getModelInfo(_this.componentId)["modelVersion"]);
+ addToList(FIELD.NAME.MODEL_UUID, DataService
+ .getModelInfo(_this.componentId)["modelNameVersionId"]);
+ break;
+ }
+
+ return _this.parameterList;
+ };
+
+ var getUserProvidedList = function() {
+
+ var parameterList = [ FIELD.PARAMETER.INSTANCE_NAME ];
+
+ switch (_this.componentId) {
+ case COMPONENT.SERVICE:
+ parameterList = parameterList.concat([ getSubscribersParameter(),
+ FIELD.PARAMETER.SERVICE_TYPE_DISABLED ]);
+ break;
+ case COMPONENT.NETWORK:
+ case COMPONENT.VNF:
+ parameterList = parameterList.concat([ getServiceId(),
+ getLcpRegion(), FIELD.PARAMETER.LCP_REGION_TEXT_HIDDEN,
+ FIELD.PARAMETER.TENANT_DISABLED ]);
+ break;
+ case COMPONENT.VF_MODULE:
+ parameterList = parameterList.concat([
+ getLcpRegion(),
+ FIELD.PARAMETER.LCP_REGION_TEXT_HIDDEN,
+ FIELD.PARAMETER.TENANT_DISABLED
+ ]);
+
+ var availableVolumeGroupList = DataService.getAvailableVolumeGroupList();
+
+ if (availableVolumeGroupList && availableVolumeGroupList.length > 0) {
+ var availableVolumeGroupNames = ["None"];
+
+ for (var i = 0; i < availableVolumeGroupList.length; i++) {
+ availableVolumeGroupNames.push(availableVolumeGroupList[i].instance.name);
+ }
+
+ parameterList.push(addOptionList(
+ FIELD.PARAMETER.AVAILABLE_VOLUME_GROUP,
+ availableVolumeGroupNames));
+ }
+ break;
+ case COMPONENT.VOLUME_GROUP:
+ parameterList = parameterList.concat([ getLcpRegion(),
+ FIELD.PARAMETER.LCP_REGION_TEXT_HIDDEN,
+ FIELD.PARAMETER.TENANT_DISABLED ]);
+ }
+
+ parameterList.push(FIELD.PARAMETER.SUPPRESS_ROLLBACK);
+
+ addArbitraryParameters(parameterList);
+
+ return parameterList;
+ };
+
+ var addArbitraryParameters = function(parameterList) {
+ var inputs = DataService.getModelInfo(_this.componentId).inputs;
+ if (inputs) {
+ for ( var key in inputs) {
+ parameterList.push({
+ id : key,
+ /*
+ * "name" is the display name. The simplest option is to just
+ * display this value (e.g. "name: key"). An alternative used
+ * here is to use "getFieldDisplayName" to display a more "user
+ * friendly" value. See "componentService:getDisplayName" for
+ * mapping details.
+ */
+ name : ComponentService.getFieldDisplayName(key),
+ value : inputs[key]["default"],
+ isRequired : true,
+ /*
+ * If the field needs to be considered required, the attribute
+ * "isRequired: true" can be added here.
+ */
+ description : inputs[key]["description"]
+ });
+ }
+ }
+ };
+
+ var addToList = function(name, value) {
+ _this.parameterList.push({
+ name : name,
+ value : value
+ });
+ };
+
+ /*
+ * The "*Mso*" functions return URL and request details that can be passed
+ * to the MSO controller. The request details defines the info passed as
+ * part of the POST body.
+ */
+
+ var getMsoUrl = function() {
+ switch (_this.componentId) {
+ case COMPONENT.NETWORK:
+ return "mso_create_nw_instance/"
+ + DataService.getServiceInstanceId();
+ case COMPONENT.SERVICE:
+ return "mso_create_svc_instance";
+ case COMPONENT.VNF:
+ return "mso_create_vnf_instance/"
+ + DataService.getServiceInstanceId();
+ case COMPONENT.VF_MODULE:
+ return "mso_create_vfmodule_instance/"
+ + DataService.getServiceInstanceId() + "/vnfs/"
+ + DataService.getVnfInstanceId();
+ case COMPONENT.VOLUME_GROUP:
+ return "mso_create_volumegroup_instance/"
+ + DataService.getServiceInstanceId() + "/vnfs/"
+ + DataService.getVnfInstanceId();
+ }
+ };
+
+ var getMsoRequestDetails = function(parameterList) {
+ console.log("getMsoRequestDetails invoked");
+ var modelInfo = DataService.getModelInfo(_this.componentId);
+ var requestDetails = {
+ requestInfo : {
+ instanceName : getValueFromList(FIELD.ID.INSTANCE_NAME,
+ parameterList),
+ source : "VID",
+ suppressRollback : getValueFromList(FIELD.ID.SUPPRESS_ROLLBACK,
+ parameterList),
+ },
+ modelInfo : {
+ modelType : _this.componentId,
+ modelInvariantId : modelInfo.modelInvariantId,
+ modelNameVersionId : modelInfo.modelNameVersionId,
+ modelName : modelInfo.modelName,
+ modelVersion : modelInfo.modelVersion
+ },
+ requestParameters : {
+ userParams : getArbitraryParameters(parameterList)
+ }
+ };
+
+ switch (_this.componentId) {
+ case COMPONENT.SERVICE:
+ requestDetails.subscriberInfo = {
+ globalSubscriberId : DataService.getGlobalCustomerId(),
+ subscriberName : DataService.getSubscriberName()
+ };
+ requestDetails.requestParameters.subscriptionServiceType = getValueFromList(
+ FIELD.ID.SERVICE_TYPE, parameterList);
+ break;
+ case COMPONENT.NETWORK:
+ case COMPONENT.VNF:
+ console.log("getMsoRequestDetails COMPONENT.VNF");
+ var lcpRegion = getValueFromList(FIELD.ID.LCP_REGION, parameterList);
+ if (lcpRegion === FIELD.KEY.LCP_REGION_TEXT) {
+ lcpRegion = getValueFromList(FIELD.ID.LCP_REGION_TEXT,
+ parameterList);
+ }
+ requestDetails.cloudConfiguration = {
+ lcpCloudRegionId : lcpRegion,
+ tenantId : getValueFromList(FIELD.ID.TENANT, parameterList)
+ };
+ requestDetails.requestInfo.productFamilyId = getValueFromList(
+ FIELD.ID.PRODUCT_FAMILY, parameterList);
+ // override model info for VNF since it needs the customization name
+ var vnfModelInfo = {
+ modelType : _this.componentId,
+ modelInvariantId : modelInfo.modelInvariantId,
+ modelNameVersionId : modelInfo.modelNameVersionId,
+ modelName : modelInfo.modelName,
+ modelVersion : modelInfo.modelVersion,
+ modelCustomizationName : modelInfo.modelCustomizationName
+ };
+ requestDetails.modelInfo = vnfModelInfo;
+ break;
+ case COMPONENT.VF_MODULE:
+ var lcpRegion = getValueFromList(FIELD.ID.LCP_REGION, parameterList);
+ if (lcpRegion === FIELD.KEY.LCP_REGION_TEXT) {
+ lcpRegion = getValueFromList(FIELD.ID.LCP_REGION_TEXT,
+ parameterList);
+ }
+ requestDetails.cloudConfiguration = {
+ lcpCloudRegionId : lcpRegion,
+ tenantId : getValueFromList(FIELD.ID.TENANT, parameterList)
+ };
+ break;
+ case COMPONENT.VOLUME_GROUP:
+ var lcpRegion = getValueFromList(FIELD.ID.LCP_REGION, parameterList);
+ if (lcpRegion === FIELD.KEY.LCP_REGION_TEXT) {
+ lcpRegion = getValueFromList(FIELD.ID.LCP_REGION_TEXT,
+ parameterList);
+ }
+ requestDetails.cloudConfiguration = {
+ lcpCloudRegionId : lcpRegion,
+ tenantId : getValueFromList(FIELD.ID.TENANT, parameterList)
+ };
+
+ break;
+ }
+
+ var relatedInstanceList = getRelatedInstanceList(parameterList);
+
+ if (relatedInstanceList !== undefined) {
+ requestDetails.relatedInstanceList = relatedInstanceList;
+ }
+
+ return requestDetails;
+ };
+
+ var getRelatedInstanceList = function(parameterList) {
+ var relatedInstanceList = new Array();
+ switch (_this.componentId) {
+ case COMPONENT.SERVICE:
+ return undefined;
+ case COMPONENT.NETWORK:
+ case COMPONENT.VNF:
+ addRelatedInstance(relatedInstanceList, COMPONENT.SERVICE,
+ DataService.getServiceInstanceId());
+ break;
+ case COMPONENT.VF_MODULE:
+ addRelatedInstance(relatedInstanceList, COMPONENT.SERVICE,
+ DataService.getServiceInstanceId());
+ addRelatedInstance(relatedInstanceList, COMPONENT.VNF, DataService
+ .getVnfInstanceId());
+
+ var availableVolumeGroup = getValueFromList(
+ FIELD.ID.AVAILABLE_VOLUME_GROUP, parameterList);
+
+ if (UtilityService.hasContents(availableVolumeGroup) && availableVolumeGroup !== "None") {
+ var availableVolumeGroups = DataService.getAvailableVolumeGroupList();
+
+ for (var i = 0; i < availableVolumeGroups.length; i++) {
+ if (availableVolumeGroups[i].instance.name == availableVolumeGroup) {
+ DataService.setModelInfo(COMPONENT.VOLUME_GROUP, DataService.getModelInfo(COMPONENT.VF_MODULE));
+ DataService.setVolumeGroupInstanceId(availableVolumeGroups[i].instance.object["volume-group-id"]);
+ break;
+ }
+ }
+
+ addRelatedInstance(relatedInstanceList, COMPONENT.VOLUME_GROUP,
+ DataService.getVolumeGroupInstanceId());
+ }
+ break;
+ case COMPONENT.VOLUME_GROUP:
+ addRelatedInstance(relatedInstanceList, COMPONENT.SERVICE,
+ DataService.getServiceInstanceId());
+ addRelatedInstance(relatedInstanceList, COMPONENT.VNF, DataService
+ .getVnfInstanceId());
+ break;
+ }
+
+ return relatedInstanceList;
+ };
+
+ var addRelatedInstance = function(relatedInstanceList, componentId,
+ instanceId) {
+ var modelInfo = DataService.getModelInfo(componentId);
+ var relatedInstance;
+ if (modelInfo !== undefined) {
+ if (componentId === COMPONENT.VNF) {
+ relatedInstance = {
+ "instanceId" : instanceId,
+ "modelInfo" : {
+ "modelType" : componentId,
+ "modelName" : modelInfo.modelName,
+ "modelInvariantId" : modelInfo.modelInvariantId,
+ "modelVersion" : modelInfo.modelVersion,
+ "modelNameVersionId" : modelInfo.modelNameVersionId,
+ "modelCustomizationName" : modelInfo.modelCustomizationName
+ }
+ };
+ } else {
+ relatedInstance = {
+ "instanceId" : instanceId,
+ "modelInfo" : {
+ "modelType" : componentId,
+ "modelName" : modelInfo.modelName,
+ "modelInvariantId" : modelInfo.modelInvariantId,
+ "modelVersion" : modelInfo.modelVersion,
+ "modelNameVersionId" : modelInfo.modelNameVersionId
+ }
+ };
+ }
+ relatedInstanceList.push({
+ relatedInstance : relatedInstance
+ });
+ }
+ };
+
+ /*
+ * var getArbitraryParameters = function(parameterList) { var
+ * arbitraryParameters = new Object(); for (var i = 0; i <
+ * parameterList.length; i++) { var parameter = parameterList[i]; switch
+ * (parameter.id) { case FIELD.ID.INSTANCE_NAME: case
+ * FIELD.ID.PRODUCT_FAMILY: case FIELD.ID.LCP_REGION: case
+ * FIELD.ID.LCP_REGION_TEXT: case FIELD.ID.SERVICE_TYPE: case
+ * FIELD.ID.TENANT: case FIELD.ID.SUPPRESS_ROLLBACK: break; default:
+ * arbitraryParameters[parameter.id] = parameter.value; } } return
+ * arbitraryParameters; }
+ */
+ var getArbitraryParameters = function(parameterList) {
+ var arbitraryParameters = new Object();
+ var arbitraryArray = new Array();
+ for (var i = 0; i < parameterList.length; i++) {
+ var parameter = parameterList[i];
+ switch (parameter.id) {
+ case FIELD.ID.AVAILABLE_VOLUME_GROUP:
+ break;
+ case FIELD.ID.INSTANCE_NAME:
+ break;
+ case FIELD.ID.PRODUCT_FAMILY:
+ break;
+ case FIELD.ID.LCP_REGION:
+ break;
+ case FIELD.ID.LCP_REGION_TEXT:
+ break;
+ case FIELD.ID.SERVICE_TYPE:
+ break;
+ case FIELD.ID.TENANT:
+ break;
+ case FIELD.ID.SUPPRESS_ROLLBACK:
+ break;
+ case FIELD.ID.SUBSCRIBER_NAME:
+ break;
+ default:
+ arbitraryParameters = {
+ name : parameter.id,
+ value : parameter.value
+ }
+ arbitraryArray.push(arbitraryParameters);
+ }
+ }
+ return (arbitraryArray);
+ }
+
+ var getModel = function() {
+ AsdcService.getModel(DataService.getModelId(), function(response) {
+ DataService.setModelInfo(_this.componentId, {
+ modelInvariantId : response.data.invariantUUID,
+ modelNameVersionId : response.data.uuid,
+ modelName : response.data.name,
+ modelVersion : response.data.version,
+ inputs : response.data.inputs
+ });
+ UtilityService.startNextAsyncOperation();
+ });
+ };
+
+ var getSubscriptionServiceTypeList = function() {
+ AaiService.getSubscriptionServiceTypeList(DataService
+ .getGlobalCustomerId(), function(response) {
+ DataService.setSubscriptionServiceTypeList(response);
+ UtilityService.startNextAsyncOperation();
+ });
+ };
+
+ var getSubscribers = function() {
+ AaiService.getSubscribers(function(response) {
+ DataService.setSubscribers(response);
+ UtilityService.startNextAsyncOperation();
+ });
+ };
+
+ var getLcpCloudRegionTenantList = function() {
+ AaiService.getLcpCloudRegionTenantList(DataService
+ .getGlobalCustomerId(), DataService.getServiceType(), function(
+ response) {
+ DataService.setCloudRegionTenantList(response);
+ UtilityService.startNextAsyncOperation();
+ });
+ };
+
+ var internalGetParametersHandler = function() {
+ if (angular.isFunction(_this.getParametersHandler)) {
+ _this.getParametersHandler({
+ summaryList : getSummaryList(),
+ userProvidedList : getUserProvidedList()
+ });
+ }
+ };
+
+ var getSubscribersParameter = function() {
+ var subscribers = DataService.getSubscribers();
+ var parameter = FIELD.PARAMETER.SUBSCRIBER_NAME;
+ parameter.optionList = [];
+
+ for (var i = 0; i < subscribers.length; i++) {
+ parameter.optionList.push({
+ id : subscribers[i]["global-customer-id"],
+ name : subscribers[i]["subscriber-name"]
+ })
+ }
+ return parameter;
+ };
+
+ var getServiceId = function() {
+ var serviceIdList = DataService.getServiceIdList();
+ var serviceTypeList = DataService.getSubscriptionServiceTypeList();
+ var parameter = FIELD.PARAMETER.PRODUCT_FAMILY;
+ parameter.optionList = new Array();
+
+ if (serviceTypeList == null) {
+ getSubscriptionServiceTypeList();
+ serviceTypeList = DataService.getSubscriptionServiceTypeList();
+ }
+ var went = 0;
+ for (var i = 0; i < serviceIdList.length; i++) {
+ var go = 0;
+ var name = serviceIdList[i].id;
+
+ if (serviceTypeList != null) {
+ console.log("STL: " + serviceTypeList);
+ for (var k = 0; k < serviceTypeList.length; k++) {
+ if (angular.equals(name,serviceTypeList[k])) {
+ go = 1;
+ went = 1;
+ }
+ }
+ } else {
+ go = 1;
+ went = 1;
+ }
+ if (go == 1) {
+ parameter.optionList.push({
+ id : serviceIdList[i].id,
+ name : serviceIdList[i].description
+ });
+ }
+ } // load them all, ours wasn't in the list
+ if (went == 0) {
+ for (var i = 0; i < serviceIdList.length; i++) {
+ parameter.optionList.push({
+ id : serviceIdList[i].id,
+ name : serviceIdList[i].description
+ });
+ }
+ }
+ return parameter;
+ };
+
+ var getLcpRegion = function() {
+ var cloudRegionTenantList = DataService.getCloudRegionTenantList();
+ var parameter = FIELD.PARAMETER.LCP_REGION;
+ parameter.optionList = new Array();
+ for (var i = 0; i < cloudRegionTenantList.length; i++) {
+ for (var j = 0; j < parameter.optionList.length; j++) {
+ if (parameter.optionList[j].id === cloudRegionTenantList[i].cloudRegionId) {
+ break;
+ }
+ }
+ if (j < parameter.optionList.length) {
+ continue;
+ }
+ parameter.optionList.push({
+ id : cloudRegionTenantList[i].cloudRegionId
+ });
+ }
+ return parameter;
+ };
+
+ var getTenantList = function(cloudRegionId) {
+ var cloudRegionTenantList = DataService.getCloudRegionTenantList();
+ var parameter = FIELD.PARAMETER.TENANT_ENABLED;
+ parameter.optionList = new Array();
+ for (var i = 0; i < cloudRegionTenantList.length; i++) {
+ if (cloudRegionTenantList[i].cloudRegionId === cloudRegionId) {
+ parameter.optionList.push({
+ id : cloudRegionTenantList[i].tenantId,
+ name : cloudRegionTenantList[i].tenantName
+ });
+ }
+ }
+ return parameter;
+
+ };
+
+ var addOptionList = function(parameter, optionSimpleArray) {
+ var optionList = new Array();
+ if (!angular.isArray(optionSimpleArray)) {
+ return optionList;
+ }
+ for (var i = 0; i < optionSimpleArray.length; i++) {
+ optionList.push({
+ name : optionSimpleArray[i]
+ });
+ }
+ parameter.optionList = optionList;
+ return parameter;
+ };
+
+ var getValueFromList = function(id, parameterList) {
+ for (var i = 0; i < parameterList.length; i++) {
+ if (parameterList[i].id === id) {
+ return parameterList[i].value;
+ }
+ }
+ };
+
+ var updateUserParameterList = function(updatedId, parameterListControl) {
+ if (updatedId === FIELD.ID.LCP_REGION) {
+ var list = parameterListControl.getList(updatedId);
+ if (list[0].selectedIndex >= 0) {
+ parameterListControl
+ .updateList([ getTenantList(list[0].value) ]);
+ } else {
+ parameterListControl
+ .updateList([ FIELD.PARAMETER.TENANT_DISABLED ]);
+ }
+ if (list[0].value === FIELD.KEY.LCP_REGION_TEXT) {
+ parameterListControl
+ .updateList([ FIELD.PARAMETER.LCP_REGION_TEXT_VISIBLE ]);
+ } else {
+ parameterListControl
+ .updateList([ FIELD.PARAMETER.LCP_REGION_TEXT_HIDDEN ]);
+ }
+ } else if (updatedId === FIELD.ID.SUBSCRIBER_NAME) {
+ var list = parameterListControl.getList(updatedId);
+ if (list[0].selectedIndex >= 0) {
+ DataService.setGlobalCustomerId(list[0].value);
+
+ AaiService.getSubscriptionServiceTypeList(DataService
+ .getGlobalCustomerId(), function(response) {
+ DataService.setSubscriptionServiceTypeList(response);
+ var serviceTypeParameters = FIELD.PARAMETER.SERVICE_TYPE;
+ serviceTypeParameters.optionList = [];
+
+ for (var i = 0; i < response.length; i++) {
+ serviceTypeParameters.optionList.push({
+ "id" : response[i],
+ "name" : response[i]
+ });
+ }
+ parameterListControl.updateList([ serviceTypeParameters ]);
+ });
+
+ } else {
+ parameterListControl
+ .updateList([ FIELD.PARAMETER.SERVICE_TYPE_DISABLED ]);
+ }
+ }
+ };
+
+ return {
+ initializeComponent : function(componentId) {
+ _this.componentId = ComponentService.initialize(componentId);
+ },
+ setHttpErrorHandler : function(httpErrorHandler) {
+ _this.httpErrorHandler = httpErrorHandler;
+ },
+ getComponentDisplayName : ComponentService.getComponentDisplayName,
+ getParameters : function(getParametersHandler) {
+ _this.getParametersHandler = getParametersHandler;
+ UtilityService.setHttpErrorHandler(_this.httpErrorHandler);
+ UtilityService.startAsyncOperations(getAsyncOperationList(),
+ internalGetParametersHandler);
+ },
+ updateUserParameterList : updateUserParameterList,
+ getMsoRequestDetails : getMsoRequestDetails,
+ getMsoUrl : getMsoUrl
+ }
+}
+
+app.factory("CreationService", [ "$log", "AaiService", "AsdcService",
+ "DataService", "ComponentService", "COMPONENT", "FIELD", "PARAMETER",
+ "UtilityService", CreationService ]);
diff --git a/vid/src/main/webapp/app/vid/scripts/services/dataService.js b/vid/src/main/webapp/app/vid/scripts/services/dataService.js
new file mode 100644
index 000000000..724d4b12c
--- /dev/null
+++ b/vid/src/main/webapp/app/vid/scripts/services/dataService.js
@@ -0,0 +1,197 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * 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=========================================================
+ */
+
+"use strict";
+
+var DataService = function($log, DataService) {
+
+ var _this = this;
+
+ return {
+ getAvailableVolumeGroupList : function() {
+ return _this.availableVolumeGroupList;
+ },
+ setAvailableVolumeGroupList : function(availableVolumeGroupList) {
+ _this.availableVolumeGroupList = availableVolumeGroupList;
+ },
+ getCloudRegionTenantList : function() {
+ return _this.cloudRegionTenantList;
+ },
+ setCloudRegionTenantList : function(cloudRegionTenantList) {
+ _this.cloudRegionTenantList = cloudRegionTenantList;
+ },
+ getGlobalCustomerId : function() {
+ return _this.globalCustomerId;
+ },
+ setGlobalCustomerId : function(globalCustomerId) {
+ _this.globalCustomerId = globalCustomerId;
+ },
+ getInventoryItem : function() {
+ return _this.inventoryItem;
+ },
+ setInventoryItem : function(inventoryItem) {
+ _this.inventoryItem = inventoryItem;
+ },
+ getModelId : function() {
+ return _this.modelId;
+ },
+ setModelId : function(modelId) {
+ _this.modelId = modelId;
+ },
+ getModelInstanceName : function() {
+ return _this.modelInstanceName;
+ },
+ setModelInstanceName : function(modelInstanceName) {
+ _this.modelInstanceName = modelInstanceName;
+ },
+ getModelInfo : function(componentId) {
+ return _this.modelInfo[componentId];
+ },
+ setModelInfo : function(componentId, modelInfo) {
+ if (_this.modelInfo === undefined) {
+ _this.modelInfo = new Object;
+ }
+ _this.modelInfo[componentId] = modelInfo;
+ },
+ getNetworkInstanceId : function() {
+ return _this.networkInstanceId;
+ },
+ setNetworkInstanceId : function(networkInstanceId) {
+ _this.networkInstanceId = networkInstanceId;
+ },
+ getServiceIdList : function() {
+ return _this.serviceIdList;
+ },
+ setServiceIdList : function(serviceIdList) {
+ _this.serviceIdList = serviceIdList;
+ },
+ getServiceInstanceId : function() {
+ return _this.serviceInstanceId;
+ },
+ setServiceInstanceId : function(serviceInstanceId) {
+ _this.serviceInstanceId = serviceInstanceId;
+ },
+ getServiceInstanceName : function() {
+ return _this.serviceInstanceName;
+ },
+ setServiceInstanceName : function(serviceInstanceName) {
+ _this.serviceInstanceName = serviceInstanceName;
+ },
+ getServiceName : function() {
+ return _this.serviceName;
+ },
+ setServiceName : function(serviceName) {
+ _this.serviceName = serviceName;
+ },
+ getServiceType : function() {
+ return _this.serviceType;
+ },
+ setServiceType : function(serviceType) {
+ _this.serviceType = serviceType;
+ },
+ getServiceUuid : function() {
+ return _this.serviceUuid;
+ },
+ setServiceUuid : function(serviceUuid) {
+ _this.serviceUuid = serviceUuid;
+ },
+ getSubscriberId : function() {
+ return _this.subscriberId;
+ },
+ setSubscriberId : function(subscriberId) {
+ _this.subscriberId = subscriberId;
+ },
+ getSubscriberName : function() {
+ return _this.subscriberName;
+ },
+ setSubscriberName : function(subscriberName) {
+ _this.subscriberName = subscriberName;
+ },
+ getSubscribers : function() {
+ return _this.subscribers;
+ },
+ setSubscribers : function(subscribers) {
+ _this.subscribers = subscribers;
+ },
+ getSubscriptionServiceTypeList : function() {
+ return _this.subscriptionServiceTypeList;
+ },
+ setSubscriptionServiceTypeList : function(subscriptionServiceTypeList) {
+ _this.subscriptionServiceTypeList = subscriptionServiceTypeList;
+ },
+ getUserParams : function() {
+ return _this.userParams;
+ },
+ setUserParams : function(userParams) {
+ _this.userParams = userParams;
+ },
+ getUserServiceInstanceName : function() {
+ return _this.userServiceInstanceName;
+ },
+ setUserServiceInstanceName : function(userServiceInstanceName) {
+ _this.userServiceInstanceName = userServiceInstanceName;
+ },
+ getVfModuleInstanceId : function() {
+ return _this.vfModuleInstanceId;
+ },
+ setVfModuleInstanceId : function(vfModuleInstanceId) {
+ _this.vfModuleInstanceId = vfModuleInstanceId;
+ },
+ getVnfInstanceId : function() {
+ return _this.vnfInstanceId;
+ },
+ setVnfInstanceId : function(vnfInstanceId) {
+ _this.vnfInstanceId = vnfInstanceId;
+ },
+ getVolumeGroupInstanceId : function() {
+ return _this.volumeGroupInstanceId;
+ },
+ setVolumeGroupInstanceId : function(volumeGroupInstanceId) {
+ _this.volumeGroupInstanceId = volumeGroupInstanceId;
+ },
+ getLcpRegion : function() {
+ return _this.lcpRegion;
+ },
+ setLcpRegion : function(lcpRegion) {
+ _this.lcpRegion = lcpRegion;
+ },
+ getTenant : function() {
+ return _this.tenant;
+ },
+ setTenant : function(tenant) {
+ _this.tenant = tenant;
+ },
+ getTreeHandle : function() {
+ return _this.treeHandle;
+ },
+ setTreeHandle : function(treeHandle) {
+ _this.treeHandle = treeHandle;
+ },
+ setServiceInstanceToCustomer : function(serviceInstanceToCustomer) {
+ _this.serviceInstanceToCustomer = [];
+ _this.serviceInstanceToCustomer = serviceInstanceToCustomer;
+ },
+ getServiceInstanceToCustomer : function() {
+ return _this.serviceInstanceToCustomer;
+ }
+ }
+}
+
+app.factory("DataService", [ "$log", DataService ]);
diff --git a/vid/src/main/webapp/app/vid/scripts/services/deletionService.js b/vid/src/main/webapp/app/vid/scripts/services/deletionService.js
new file mode 100644
index 000000000..5ab5ee79b
--- /dev/null
+++ b/vid/src/main/webapp/app/vid/scripts/services/deletionService.js
@@ -0,0 +1,442 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * 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=========================================================
+ */
+
+"use strict";
+
+var DeletionService = function($log, AaiService, AsdcService, DataService,
+ ComponentService, COMPONENT, FIELD, UtilityService) {
+
+ var _this = this;
+
+ var getAsyncOperationList = function() {
+ switch (_this.componentId) {
+ case COMPONENT.SERVICE:
+ return [ getSubscribers ];
+ case COMPONENT.NETWORK:
+ return [];
+ case COMPONENT.VNF:
+ return [ getLcpCloudRegionTenantList ];
+ case COMPONENT.VF_MODULE:
+ return [ getLcpCloudRegionTenantList ];
+ case COMPONENT.VOLUME_GROUP:
+ return [ getLcpCloudRegionTenantList ];
+ }
+ };
+
+ var getLcpCloudRegionTenantList = function() {
+ AaiService.getLcpCloudRegionTenantList(DataService
+ .getGlobalCustomerId(), DataService.getServiceType(), function(
+ response) {
+ DataService.setCloudRegionTenantList(response);
+ UtilityService.startNextAsyncOperation();
+ });
+ };
+
+ var getSubscribers = function() {
+ AaiService.getSubscribers(function(response) {
+ DataService.setSubscribers(response);
+ UtilityService.startNextAsyncOperation();
+ });
+ };
+
+ var internalGetParametersHandler = function() {
+ if (angular.isFunction(_this.getParametersHandler)) {
+ if (_this.componentId == COMPONENT.SERVICE)
+ _this.getParametersHandler({
+ summaryList : getSummaryList(),
+ userProvidedList : getUserProvidedList()
+ }, true);
+ else
+ _this.getParametersHandler({
+ summaryList : getSummaryList(),
+ userProvidedList : getUserProvidedList()
+ }, false);
+ }
+ };
+
+ var getSubscribersParameter = function() {
+ var subscribers = DataService.getSubscribers();
+ var parameter = FIELD.PARAMETER.SUBSCRIBER_NAME;
+ parameter.optionList = [];
+
+ for (var i = 0; i < subscribers.length; i++) {
+ parameter.optionList.push({
+ id : subscribers[i]["global-customer-id"],
+ name : subscribers[i]["subscriber-name"]
+ })
+ }
+ return parameter;
+ };
+
+ var getServiceId = function() {
+ var serviceIdList = DataService.getServiceIdList();
+ var parameter = FIELD.PARAMETER.PRODUCT_FAMILY;
+ parameter.optionList = new Array();
+ for (var i = 0; i < serviceIdList.length; i++) {
+ parameter.optionList.push({
+ id : serviceIdList[i].id,
+ name : serviceIdList[i].description
+ });
+ }
+ return parameter;
+ };
+
+ var getUserProvidedList = function() {
+
+ //var parameterList = [ FIELD.PARAMETER.INSTANCE_NAME ];
+
+ var parameterList = [];
+
+ switch (_this.componentId) {
+ case COMPONENT.SERVICE:
+// parameterList = parameterList.concat([ getSubscribersParameter(),
+// FIELD.PARAMETER.SERVICE_TYPE_DISABLED ]);
+ parameterList = [];
+ break;
+ case COMPONENT.NETWORK:
+ case COMPONENT.VNF:
+ parameterList = parameterList.concat([ //getServiceId(),
+ getLcpRegion(), FIELD.PARAMETER.LCP_REGION_TEXT_HIDDEN,
+ FIELD.PARAMETER.TENANT_DISABLED ]);
+ break;
+ case COMPONENT.VF_MODULE:
+ parameterList = parameterList.concat([
+ getLcpRegion(),
+ FIELD.PARAMETER.LCP_REGION_TEXT_HIDDEN,
+ FIELD.PARAMETER.TENANT_DISABLED
+ ]);
+
+ break;
+ case COMPONENT.VOLUME_GROUP:
+ parameterList = parameterList.concat([ getLcpRegion(),
+ FIELD.PARAMETER.LCP_REGION_TEXT_HIDDEN,
+ FIELD.PARAMETER.TENANT_DISABLED ]);
+ }
+
+ parameterList.push(FIELD.PARAMETER.SUPPRESS_ROLLBACK);
+
+ //addArbitraryParameters(parameterList);
+
+ return parameterList;
+ };
+ var getSummaryList = function() {
+ switch (_this.componentId) {
+ case COMPONENT.NETWORK:
+ case COMPONENT.SERVICE:
+ case COMPONENT.VNF:
+ case COMPONENT.VF_MODULE:
+ case COMPONENT.VOLUME_GROUP:
+ var summaryList = [ {
+ name : FIELD.NAME.SUBSCRIBER_NAME,
+ value : DataService.getSubscriberName()
+ }, {
+ name : FIELD.NAME.CUSTOMER_ID,
+ value : DataService.getGlobalCustomerId()
+ }, {
+ name : FIELD.NAME.SERVICE_UUID,
+ value : DataService.getServiceUuid()
+ }, {
+ name : FIELD.NAME.SERVICE_NAME,
+ value : DataService.getServiceName()
+ /* }, {
+ name : FIELD.NAME.USER_SERVICE_INSTANCE_NAME,
+ value : DataService.getUserServiceInstanceName()*/
+ } ];
+
+ _this.parameterList = new Array();
+
+ addToList(FIELD.NAME.SERVICE_NAME, DataService.getServiceName());
+
+ switch (_this.componentId) {
+ case COMPONENT.SERVICE:
+ addToList(FIELD.NAME.SERVICE_INVARIANT_UUID, DataService
+ .getModelInfo(_this.componentId)["modelInvariantId"]);
+ addToList(FIELD.NAME.SERVICE_VERSION, DataService
+ .getModelInfo(_this.componentId)["modelVersion"]);
+ addToList(FIELD.NAME.SERVICE_UUID, DataService
+ .getModelInfo(_this.componentId)["modelNameVersionId"]);
+ addToList(FIELD.NAME.SERVICE_DESCRIPTION, DataService
+ .getModelInfo(_this.componentId)["description"]);
+ addToList(FIELD.NAME.SERVICE_CATEGORY, DataService
+ .getModelInfo(_this.componentId)["category"]);
+ break;
+ case COMPONENT.VF_MODULE:
+ addToList(FIELD.NAME.SUBSCRIBER_NAME, DataService
+ .getSubscriberName());
+ addToList(FIELD.NAME.SERVICE_INSTANCE_NAME, DataService
+ .getServiceInstanceName());
+ addToList(FIELD.NAME.MODEL_NAME, DataService
+ .getModelInfo(_this.componentId)["modelName"]);
+ addToList(FIELD.NAME.MODEL_INVARIANT_UUID, DataService
+ .getModelInfo(_this.componentId)["modelInvariantId"]);
+ addToList(FIELD.NAME.MODEL_VERSION, DataService
+ .getModelInfo(_this.componentId)["modelVersion"]);
+ addToList(FIELD.NAME.MODEL_UUID, DataService
+ .getModelInfo(_this.componentId)["modelNameVersionId"]);
+ break;
+ case COMPONENT.NETWORK:
+ case COMPONENT.VNF:
+ case COMPONENT.VOLUME_GROUP:
+ addToList(FIELD.NAME.SUBSCRIBER_NAME, DataService
+ .getSubscriberName());
+ addToList(FIELD.NAME.SERVICE_INSTANCE_NAME, DataService
+ .getServiceInstanceName());
+ addToList(FIELD.NAME.MODEL_NAME, DataService
+ .getModelInfo(_this.componentId)["modelName"]);
+ addToList(FIELD.NAME.MODEL_INVARIANT_UUID, DataService
+ .getModelInfo(_this.componentId)["modelInvariantId"]);
+ addToList(FIELD.NAME.MODEL_VERSION, DataService
+ .getModelInfo(_this.componentId)["modelVersion"]);
+ addToList(FIELD.NAME.MODEL_UUID, DataService
+ .getModelInfo(_this.componentId)["modelNameVersionId"]);
+ break;
+ }
+
+ var additionalList = ComponentService.getInventoryParameterList(
+ _this.componentId, DataService.getInventoryItem());
+
+ return summaryList.concat(ComponentService
+ .getDisplayNames(additionalList));
+ }
+ };
+
+ var getMsoUrl = function() {
+ switch (_this.componentId) {
+ case COMPONENT.NETWORK:
+ return "mso_delete_nw_instance/"
+ + DataService.getServiceInstanceId() + "/networks/"
+ + DataService.getNetworkInstanceId();
+ case COMPONENT.SERVICE:
+ return "mso_delete_svc_instance/"
+ + DataService.getServiceInstanceId();
+ case COMPONENT.VNF:
+ return "mso_delete_vnf_instance/"
+ + DataService.getServiceInstanceId() + "/vnfs/"
+ + DataService.getVnfInstanceId();
+ case COMPONENT.VF_MODULE:
+ return "mso_delete_vfmodule_instance/"
+ + DataService.getServiceInstanceId() + "/vnfs/"
+ + DataService.getVnfInstanceId() + "/vfModules/"
+ + DataService.getVfModuleInstanceId();
+ case COMPONENT.VOLUME_GROUP:
+ return "mso_delete_volumegroup_instance/"
+ + DataService.getServiceInstanceId() + "/vnfs/"
+ + DataService.getVnfInstanceId() + "/volumeGroups/"
+ + DataService.getVolumeGroupInstanceId();
+ }
+ }
+
+ var addToList = function(name, value) {
+ _this.parameterList.push({
+ name : name,
+ value : value
+ });
+ };
+
+ var getMsoRequestDetails = function(parameterList) {
+ console.log("getMsoRequestDetails invoked");
+ var inventoryInfo = ComponentService.getInventoryInfo(
+ _this.componentId, DataService.getInventoryItem());
+ var modelInfo = DataService.getModelInfo(_this.componentId);
+ var requestDetails = {
+ modelInfo : {
+ modelType : _this.componentId,
+ modelInvariantId : modelInfo.modelInvariantId,
+ modelNameVersionId : modelInfo.modelNameVersionId,
+ modelName : modelInfo.modelName,
+ modelCustomizationName : modelInfo.modelCustomizationName,
+ modelVersion : modelInfo.modelVersion
+ },
+ requestInfo : {
+ source : "VID"
+ }
+ };
+
+ switch (_this.componentId) {
+ case COMPONENT.SERVICE:
+ break;
+ case COMPONENT.VNF:
+ console.log("getMsoRequestDetails COMPONENT.VNF");
+ var lcpRegion = getValueFromList(FIELD.ID.LCP_REGION, parameterList);
+ if (lcpRegion === FIELD.KEY.LCP_REGION_TEXT) {
+ lcpRegion = getValueFromList(FIELD.ID.LCP_REGION_TEXT,
+ parameterList);
+ }
+ requestDetails.cloudConfiguration = {
+ lcpCloudRegionId : lcpRegion,
+ tenantId : getValueFromList(FIELD.ID.TENANT, parameterList)
+ };
+
+ break;
+ case COMPONENT.VF_MODULE:
+ var lcpRegion = getValueFromList(FIELD.ID.LCP_REGION, parameterList);
+ if (lcpRegion === FIELD.KEY.LCP_REGION_TEXT) {
+ lcpRegion = getValueFromList(FIELD.ID.LCP_REGION_TEXT,
+ parameterList);
+ }
+ requestDetails.cloudConfiguration = {
+ lcpCloudRegionId : lcpRegion,
+ tenantId : getValueFromList(FIELD.ID.TENANT, parameterList)
+ };
+ break;
+ case COMPONENT.VOLUME_GROUP:
+ var lcpRegion = getValueFromList(FIELD.ID.LCP_REGION, parameterList);
+ if (lcpRegion === FIELD.KEY.LCP_REGION_TEXT) {
+ lcpRegion = getValueFromList(FIELD.ID.LCP_REGION_TEXT,
+ parameterList);
+ }
+ requestDetails.cloudConfiguration = {
+ lcpCloudRegionId : lcpRegion,
+ tenantId : getValueFromList(FIELD.ID.TENANT, parameterList)
+ };
+
+ break;
+ default:
+ requestDetails.cloudConfiguration = {
+ lcpCloudRegionId : DataService.getLcpRegion(),
+ tenantId : DataService.getTenant()
+ };
+ }
+ return requestDetails;
+ }
+
+ var getLcpRegion = function() {
+ var cloudRegionTenantList = DataService.getCloudRegionTenantList();
+ var parameter = FIELD.PARAMETER.LCP_REGION;
+ parameter.optionList = new Array();
+ for (var i = 0; i < cloudRegionTenantList.length; i++) {
+ for (var j = 0; j < parameter.optionList.length; j++) {
+ if (parameter.optionList[j].id === cloudRegionTenantList[i].cloudRegionId) {
+ break;
+ }
+ }
+ if (j < parameter.optionList.length) {
+ continue;
+ }
+ parameter.optionList.push({
+ id : cloudRegionTenantList[i].cloudRegionId
+ });
+ }
+ return parameter;
+ };
+
+ var getTenantList = function(cloudRegionId) {
+ var cloudRegionTenantList = DataService.getCloudRegionTenantList();
+ var parameter = FIELD.PARAMETER.TENANT_ENABLED;
+ parameter.optionList = new Array();
+ for (var i = 0; i < cloudRegionTenantList.length; i++) {
+ if (cloudRegionTenantList[i].cloudRegionId === cloudRegionId) {
+ parameter.optionList.push({
+ id : cloudRegionTenantList[i].tenantId,
+ name : cloudRegionTenantList[i].tenantName
+ });
+ }
+ }
+ return parameter;
+
+ };
+
+ var addOptionList = function(parameter, optionSimpleArray) {
+ var optionList = new Array();
+ if (!angular.isArray(optionSimpleArray)) {
+ return optionList;
+ }
+ for (var i = 0; i < optionSimpleArray.length; i++) {
+ optionList.push({
+ name : optionSimpleArray[i]
+ });
+ }
+ parameter.optionList = optionList;
+ return parameter;
+ };
+
+ var getValueFromList = function(id, parameterList) {
+ for (var i = 0; i < parameterList.length; i++) {
+ if (parameterList[i].id === id) {
+ return parameterList[i].value;
+ }
+ }
+ };
+
+ var updateUserParameterList = function(updatedId, parameterListControl) {
+ if (updatedId === FIELD.ID.LCP_REGION) {
+ var list = parameterListControl.getList(updatedId);
+ if (list[0].selectedIndex >= 0) {
+ parameterListControl
+ .updateList([ getTenantList(list[0].value) ]);
+ } else {
+ parameterListControl
+ .updateList([ FIELD.PARAMETER.TENANT_DISABLED ]);
+ }
+ if (list[0].value === FIELD.KEY.LCP_REGION_TEXT) {
+ parameterListControl
+ .updateList([ FIELD.PARAMETER.LCP_REGION_TEXT_VISIBLE ]);
+ } else {
+ parameterListControl
+ .updateList([ FIELD.PARAMETER.LCP_REGION_TEXT_HIDDEN ]);
+ }
+ } else if (updatedId === FIELD.ID.SUBSCRIBER_NAME) {
+ var list = parameterListControl.getList(updatedId);
+ if (list[0].selectedIndex >= 0) {
+ DataService.setGlobalCustomerId(list[0].value);
+
+ AaiService.getSubscriptionServiceTypeList(DataService
+ .getGlobalCustomerId(), function(response) {
+ DataService.setSubscriptionServiceTypeList(response);
+ var serviceTypeParameters = FIELD.PARAMETER.SERVICE_TYPE;
+ serviceTypeParameters.optionList = [];
+
+ for (var i = 0; i < response.length; i++) {
+ serviceTypeParameters.optionList.push({
+ "id" : response[i],
+ "name" : response[i]
+ });
+ }
+ parameterListControl.updateList([ serviceTypeParameters ]);
+ });
+
+ } else {
+ parameterListControl
+ .updateList([ FIELD.PARAMETER.SERVICE_TYPE_DISABLED ]);
+ }
+ }
+ };
+
+ return {
+ initializeComponent : function(componentId) {
+ _this.componentId = ComponentService.initialize(componentId);
+ },
+ getComponentDisplayName : ComponentService.getComponentDisplayName,
+ getSummaryList : getSummaryList,
+ getParameters : function(getParametersHandler) {
+ _this.getParametersHandler = getParametersHandler;
+ UtilityService.setHttpErrorHandler(_this.httpErrorHandler);
+ UtilityService.startAsyncOperations(getAsyncOperationList(),
+ internalGetParametersHandler);
+ },
+ updateUserParameterList : updateUserParameterList,
+ getMsoRequestDetails : getMsoRequestDetails,
+ getMsoUrl : getMsoUrl
+ }
+}
+
+app.factory("DeletionService", [ "$log", "AaiService", "AsdcService",
+ "DataService", "ComponentService", "COMPONENT", "FIELD",
+ "UtilityService", DeletionService ]);
diff --git a/vid/src/main/webapp/app/vid/scripts/services/detailsService.js b/vid/src/main/webapp/app/vid/scripts/services/detailsService.js
new file mode 100644
index 000000000..38f161d05
--- /dev/null
+++ b/vid/src/main/webapp/app/vid/scripts/services/detailsService.js
@@ -0,0 +1,98 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * 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=========================================================
+ */
+
+"use strict";
+
+var DetailsService = function($log, DataService, ComponentService, COMPONENT,
+ FIELD, UtilityService) {
+
+ var _this = this;
+
+ var getSummaryList = function() {
+ switch (_this.componentId) {
+ case COMPONENT.NETWORK:
+ case COMPONENT.SERVICE:
+ case COMPONENT.VNF:
+ case COMPONENT.VF_MODULE:
+ case COMPONENT.VOLUME_GROUP:
+ return [ {
+ name : FIELD.NAME.SUBSCRIBER_NAME,
+ value : DataService.getSubscriberName()
+ }, {
+ name : FIELD.NAME.SERVICE_INSTANCE_ID,
+ value : DataService.getServiceInstanceId()
+ }, {
+ name : FIELD.NAME.SERVICE_TYPE,
+ value : DataService.getServiceType()
+ } ];
+ }
+ };
+
+ var getDetailsList = function() {
+ switch (_this.componentId) {
+ case COMPONENT.NETWORK:
+ case COMPONENT.SERVICE:
+ case COMPONENT.VNF:
+ case COMPONENT.VF_MODULE:
+ case COMPONENT.VOLUME_GROUP:
+ return ComponentService.getDisplayNames(ComponentService
+ .getInventoryParameterList(_this.componentId, DataService
+ .getInventoryItem()));
+ }
+ };
+
+ var getMsoFilterString = function() {
+
+ var instanceId = "";
+
+ switch (_this.componentId) {
+ case COMPONENT.NETWORK:
+ instanceId = DataService.getNetworkInstanceId();
+ break;
+ case COMPONENT.SERVICE:
+ instanceId = DataService.getServiceInstanceId();
+ break;
+ case COMPONENT.VNF:
+ instanceId = DataService.getVnfInstanceId();
+ break;
+ case COMPONENT.VF_MODULE:
+ instanceId = DataService.getVfModuleInstanceId();
+ break;
+ case COMPONENT.VOLUME_GROUP:
+ instanceId = DataService.getVolumeGroupInstanceId();
+ }
+
+ return "filter=" + _this.componentId + "InstanceId:EQUALS:"
+ + instanceId;
+ };
+
+ return {
+ initializeComponent : function(componentId) {
+ _this.componentId = ComponentService.initialize(componentId);
+ },
+ getComponentDisplayName : ComponentService.getComponentDisplayName,
+ getSummaryList : getSummaryList,
+ getDetailsList : getDetailsList,
+ getMsoFilterString : getMsoFilterString
+ }
+}
+
+app.factory("DetailsService", [ "$log", "DataService", "ComponentService",
+ "COMPONENT", "FIELD", "UtilityService", DetailsService ]);
diff --git a/vid/src/main/webapp/app/vid/scripts/services/msoService.js b/vid/src/main/webapp/app/vid/scripts/services/msoService.js
new file mode 100644
index 000000000..2d4344685
--- /dev/null
+++ b/vid/src/main/webapp/app/vid/scripts/services/msoService.js
@@ -0,0 +1,146 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * 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=========================================================
+ */
+
+"use strict";
+
+var MsoService = function($http, $log, PropertyService, UtilityService) {
+
+ var _this = this;
+
+ /*
+ * Common function to handle both create and delete instance requests
+ */
+ var requestInstanceUpdate = function(request, successCallbackFunction) {
+ $log.debug("MsoService:requestInstanceUpdate: request:");
+ $log.debug(request);
+ $http.post(PropertyService.getMsoBaseUrl() + "/" + request.url, {
+ requestDetails : request.requestDetails
+ }, {
+ timeout : PropertyService.getServerResponseTimeoutMsec()
+ }).then(successCallbackFunction)["catch"]
+ (UtilityService.runHttpErrorHandler);
+ }
+
+ var checkValidStatus = function(response) {
+ if (response.data.status < 200 || response.data.status > 202) {
+ throw {
+ type : "msoFailure"
+ }
+ }
+ }
+
+ var addListEntry = function(name, value) {
+ var entry = '"' + name + '": ';
+ if (value === undefined) {
+ return entry + "undefined";
+ } else {
+ return entry + '"' + value + '"';
+ }
+ }
+
+ return {
+ createInstance : requestInstanceUpdate,
+ deleteInstance : requestInstanceUpdate,
+ getOrchestrationRequest : function(requestId, successCallbackFunction) {
+ $log.debug("MsoService:getOrchestrationRequest: requestId: "
+ + requestId);
+ $http.get(
+ PropertyService.getMsoBaseUrl() + "/mso_get_orch_req/"
+ + requestId + "?r=" + Math.random(),
+ {
+ timeout : PropertyService
+ .getServerResponseTimeoutMsec()
+ }).then(successCallbackFunction)["catch"]
+ (UtilityService.runHttpErrorHandler);
+ },
+ getOrchestrationRequests : function(filterString,
+ successCallbackFunction) {
+ $log.debug("MsoService:getOrchestrationRequests: filterString: "
+ + filterString);
+ $http.get(
+ PropertyService.getMsoBaseUrl() + "/mso_get_orch_reqs/"
+ + encodeURIComponent(filterString) + "?r="
+ + Math.random(),
+ {
+ timeout : PropertyService
+ .getServerResponseTimeoutMsec()
+ }).then(successCallbackFunction)["catch"]
+ (UtilityService.runHttpErrorHandler);
+ },
+ getFormattedCommonResponse : function(response) {
+ return UtilityService.getCurrentTime() + " HTTP Status: "
+ + UtilityService.getHttpStatusText(response.data.status)
+ + "\n" + angular.toJson(response.data.entity, true)
+ + "\n\n";
+ },
+ checkValidStatus : checkValidStatus,
+ getFormattedGetOrchestrationRequestsResponse : function(response) {
+ UtilityService.checkUndefined("entity", response.data.entity);
+ UtilityService.checkUndefined("status", response.data.status);
+ checkValidStatus(response);
+
+ var list = response.data.entity.requestList
+ UtilityService.checkUndefined("requestList", list);
+
+ var message = "";
+
+ for (var i = 0; i < list.length; i++) {
+ var request = list[i].request;
+ message += addListEntry("requestId", request.requestId) + ",\n";
+ message += addListEntry("requestType", request.requestType)
+ + ",\n";
+ var status = request.requestStatus;
+ if (status === undefined) {
+ message += addListEntry("requestStatus", undefined) + "\n";
+ } else {
+ message += addListEntry("timestamp", status.timestamp)
+ + ",\n";
+ message += addListEntry("requestState", status.requestState)
+ + ",\n";
+ message += addListEntry("statusMessage",
+ status.statusMessage)
+ + ",\n";
+ message += addListEntry("percentProgress",
+ status.percentProgress)
+ + "\n";
+ }
+ if (i < (list.length - 1)) {
+ message += "\n";
+ }
+ }
+ return message;
+ },
+ showResponseContentError : function(error, showFunction) {
+ switch (error.type) {
+ case "undefinedObject":
+ showFunction("System failure", error.message);
+ break;
+ case "msoFailure":
+ showFunction("MSO failure", "see log below for details")
+ break;
+ default:
+ showFunction("System failure");
+ }
+ }
+ }
+}
+
+app.factory("MsoService", [ "$http", "$log", "PropertyService",
+ "UtilityService", MsoService ]);
diff --git a/vid/src/main/webapp/app/vid/scripts/services/propertyService.js b/vid/src/main/webapp/app/vid/scripts/services/propertyService.js
new file mode 100644
index 000000000..bfdc7ef33
--- /dev/null
+++ b/vid/src/main/webapp/app/vid/scripts/services/propertyService.js
@@ -0,0 +1,116 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * 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=========================================================
+ */
+
+"use strict";
+
+var PropertyService = function($location, $http) {
+
+ var RE = /.*?:\/\/.*?:.*?\/(.*?)\//g;
+ var BASE_PATH = RE.exec($location.absUrl())[1];
+ var DEFAULT_AAI_BASE_URL = "/" + BASE_PATH;
+ var DEFAULT_ASDC_BASE_URL = "asdc";
+ var DEFAULT_MSO_MAX_POLLING_INTERVAL_MSEC = 60000;
+ var DEFAULT_MSO_MAX_POLLS = 10;
+ var DEFAULT_MSO_BASE_URL = "/" + BASE_PATH + "/mso";
+ var DEFAULT_SERVER_RESPONSE_TIMEOUT_MSEC = 60000;
+ var MSO_POLLING_INTERVAL_MSECS = "mso_polling_interval_msecs";
+ var MSO_MAX_POLLS = "mso_max_polls";
+
+ var _this = this;
+
+ _this.asdcBaseUrl = DEFAULT_ASDC_BASE_URL;
+ _this.aaiBaseUrl = DEFAULT_AAI_BASE_URL;
+ _this.msoMaxPollingIntervalMsec = DEFAULT_MSO_MAX_POLLING_INTERVAL_MSEC;
+ _this.msoMaxPolls = DEFAULT_MSO_MAX_POLLS;
+ _this.msoBaseUrl = DEFAULT_MSO_BASE_URL;
+ _this.serverResponseTimeoutMsec = DEFAULT_SERVER_RESPONSE_TIMEOUT_MSEC;
+
+ return {
+ getAaiBaseUrl : function() {
+ return _this.aaiBaseUrl;
+ },
+ setAaiBaseUrl : function(aaiBaseUrl) {
+ _this.aaiBaseUrl = aaiBaseUrl;
+ },
+ getAsdcBaseUrl : function() {
+ return _this.asdcBaseUrl;
+ },
+ setAsdcBaseUrl : function(asdcBaseUrl) {
+ _this.asdcBaseUrl = asdcBaseUrl;
+ },
+ retrieveMsoMaxPollingIntervalMsec : function(defaultvalue) {
+ _this.msoMaxPollingIntervalMsec = defaultvalue;
+ $http.get( _this.aaiBaseUrl + "/get_property/" + MSO_POLLING_INTERVAL_MSECS + "/" + defaultvalue, {
+
+ },{
+ timeout: _this.serverResponseTimeoutMsec
+ }).then(function(response) {
+ //console.log ( "retrieveMsoMaxPollingIntervalMsec: " ); console.log ( JSON.stringify(response) );
+ //console.log ( "retrieveMsoMaxPollingIntervalMsec: " + response.data );
+ _this.msoMaxPollingIntervalMsec = response.data;
+ console.log ("retrieveMsoMaxPollingIntervalMsec: " + _this.msoMaxPollingIntervalMsec);
+ },function errorCallback(response) {
+ console.log ( "retrieveMsoMaxPollingIntervalMsec: " + response.status );
+ //console.log ( "retrieveMsoMaxPollingIntervalMsec: " ); console.log ( JSON.stringify(response) );
+ });
+ return _this.msoMaxPollingIntervalMsec;
+ },
+ getMsoMaxPollingIntervalMsec : function() {
+ return _this.msoMaxPollingIntervalMsec;
+ },
+ setMsoMaxPollingIntervalMsec : function(msoMaxPollingIntervalMsec) {
+ _this.msoMaxPollingIntervalMsec = msoMaxPollingIntervalMsec;
+ },
+ retrieveMsoMaxPolls : function(defaultvalue) {
+ _this.msoMaxPolls = defaultvalue;
+ $http.get( _this.aaiBaseUrl + "/get_property/" + MSO_MAX_POLLS + "/" + defaultvalue, {
+
+ },{
+ timeout: _this.serverResponseTimeoutMsec
+ }).then(function(response) {
+ //console.log ( "retrieveMsoMaxPolls: " ); console.log ( JSON.stringify(response) );
+ //console.log ( "retrieveMsoMaxPolls: " + response.data.entity );
+ _this.msoMaxPolls = response.data;
+ console.log ("retrieveMsoMaxPolls: " + _this.msoMaxPolls);
+ });
+ return _this.msoMaxPolls;
+ },
+ getMsoMaxPolls : function() {
+ return _this.msoMaxPolls;
+ },
+ setMsoMaxPolls : function(msoMaxPolls) {
+ _this.msoMaxPolls = msoMaxPolls;
+ },
+ getMsoBaseUrl : function() {
+ return _this.msoBaseUrl;
+ },
+ setMsoBaseUrl : function(msoBaseUrl) {
+ _this.msoBaseUrl = msoBaseUrl;
+ },
+ getServerResponseTimeoutMsec : function() {
+ return _this.serverResponseTimeoutMsec;
+ },
+ setServerResponseTimeoutMsec : function(serverResponseTimeoutMsec) {
+ _this.serverResponseTimeoutMsec = serverResponseTimeoutMsec;
+ }
+ };
+}
+
+app.factory("PropertyService", PropertyService);
diff --git a/vid/src/main/webapp/app/vid/scripts/services/utilityService.js b/vid/src/main/webapp/app/vid/scripts/services/utilityService.js
new file mode 100644
index 000000000..fc7d97123
--- /dev/null
+++ b/vid/src/main/webapp/app/vid/scripts/services/utilityService.js
@@ -0,0 +1,228 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * 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=========================================================
+ */
+
+"use strict";
+
+/*
+ * "UtilityService" contains various generic methods.
+ *
+ * (*** DEPRECATED - Use PropertyService instead ***) setProperties() and
+ * getProperties()
+ *
+ * SYNTAX: hasContents(object)
+ *
+ * Returns "true" if "object" contains contents (i.e. is NOT undefined, null or
+ * ""), "false" otherwise.
+ *
+ * SYNTAX: checkUndefined(name, value)
+ *
+ * Throws an exception if "value" is undefined. The exception includes "name" as
+ * the cause of the exception. Returns "value" if it is defined.
+ *
+ * SYNTAX: getCurrentTime()
+ *
+ * Returns the current local date and time in the format "MM/DD/YY HH:MM:SS"
+ *
+ * SYNTAX: setHttpErrorHandler(function)
+ *
+ * Sets the HTTP error handler to "function".
+ *
+ * SYNTAX: runHttpErrorHandler(response, status)
+ *
+ * Logs warning messages and the runs the HTTP error handler previously set by
+ * "setHttpErrorHandler". The intended usage is for "$http" calls. Example:
+ * $http.get(...).then(...)["catch"](UtilityService.runHttpErrorHandler);
+ *
+ * SYNTAX: getHttpStatusText(statusCode)
+ *
+ * Expects "statusCode" to be an HTTP response code (e.g. 404). The function
+ * returns a string that includes both the code and an equivalent text summary.
+ * Example: "Not found (404)"
+ *
+ * SYNTAX: getHttpErrorMessage(response)
+ *
+ * Expects "response" to be the response object generated by a "$http" error
+ * condition. "getHttpErrorMessage" examines the object and returns a summary
+ * string for some known conditions.
+ */
+
+var UtilityService = function($log) {
+
+ var _this = this;
+
+ function hasContents(object) {
+ if (object === undefined || object === null || object === "") {
+ return false;
+ }
+ return true;
+ }
+
+ function padZero(number) {
+ if (number < 10) {
+ return "0" + number;
+ } else {
+ return "" + number;
+ }
+ }
+
+ var httpErrorHandler = function(response, status) {
+ $log.warn("UtilityService:httpErrorHandler: response:");
+ $log.warn(response);
+ $log.warn("UtilityService:httpErrorHandler: status:");
+ $log.warn(status);
+ if (angular.isFunction(_this.httpErrorHandler)) {
+ _this.httpErrorHandler(response, status);
+ }
+ };
+
+ var startNextAsyncOperation = function() {
+ if (_this.asyncOperations.count < _this.asyncOperations.operationList.length) {
+ _this.asyncOperations.operationList[_this.asyncOperations.count++]
+ ();
+ } else {
+ if (angular.isFunction(_this.asyncOperations.callbackFunction)) {
+ _this.asyncOperations.callbackFunction();
+ }
+ }
+ };
+
+ return {
+ setProperties : function(properties) {
+ _this.properties = properties;
+ },
+ getProperties : function() {
+ return _this.properties;
+ },
+ hasContents : hasContents,
+ checkUndefined : function(name, value) {
+ if (value === undefined) {
+ throw {
+ type : "undefinedObject",
+ message : "undefined object: \"" + name + "\""
+ };
+ }
+ return value;
+ },
+ getCurrentTime : function() {
+ var time = new Date();
+ return padZero(time.getMonth() + 1) + "/"
+ + padZero(time.getDate() + 1) + "/"
+ + (time.getFullYear() - 2000) + " "
+ + padZero(time.getHours()) + ":"
+ + padZero(time.getMinutes()) + ":"
+ + padZero(time.getSeconds())
+ },
+ getHttpStatusText : function(statusCode) {
+ var statusMap = {
+ "200" : "OK",
+ "201" : "Created",
+ "202" : "Accepted",
+ "400" : "Bad Request",
+ "401" : "Unauthorized",
+ "404" : "Not Found",
+ "405" : "Method Not Allowed",
+ "409" : "Locked",
+ "500" : "Internal Server Error",
+ "503" : "Service Unavailable",
+ "504" : "Gateway Timeout"
+ }
+
+ if (status === undefined) {
+ return "Undefined";
+ }
+
+ var statusText = statusMap[statusCode];
+ if (statusText === undefined) {
+ statusText = "Unknown";
+ }
+
+ return statusText + " (" + statusCode + ")";
+ },
+ getHttpErrorMessage : function(response) {
+ var data = response.data;
+ if (response.status === 500 && hasContents(data.exception)) {
+ var summary = "exception: " + data.exception;
+ if (hasContents(data.message)) {
+ summary += " message: " + data.message;
+ }
+ return summary;
+ }
+ if (response.status === 0 && response.statusText === "") {
+ /*
+ * This logic is somewhat "fuzzy". Potential (brainstorming)
+ * enhancements if users find the message unreliable include:
+ *
+ * A) SERVER TIMEOUT: perhaps a newer version of Angular can
+ * reliably determine timeouts.
+ *
+ * B) SERVER TIMEOUT: recording start / end times and using that
+ * to determine if timeout occured
+ *
+ * C) SESSION TIMEOUT "Potentially" examine cookies, although
+ * that may not be feasible if cookies are set to "httponly".
+ */
+ if (data === null) {
+ return "possible server timeout";
+ }
+ if (data === "") {
+ return "Possible reasons include a session timeout or a server issue. "
+ + "A session timeout might be resolved by refreshing the screen and re-logging in";
+ }
+ }
+ var summary = "";
+ if (response.status !== undefined && response.status > 0) {
+ summary = "status: " + response.status;
+ }
+ if (hasContents(response.statusText)) {
+ if (summary !== "") {
+ summary += " ";
+ }
+ summary += "message: " + response.statusText;
+ }
+ return summary;
+ },
+ setHttpErrorHandler : function(httpErrorHandler) {
+ _this.httpErrorHandler = httpErrorHandler;
+ },
+ runHttpErrorHandler : function(response, status) {
+ httpErrorHandler(response, status);
+ },
+ startAsyncOperations : function(operationList, callbackFunction) {
+ for (var i = 0; i < operationList.length; i++) {
+ if (!angular.isFunction(operationList[i])) {
+ throw "UtilityService:startAsyncOperations: invalid function: index: "
+ + i;
+ }
+ }
+ _this.asyncOperations = {
+ operationList : operationList,
+ callbackFunction : callbackFunction,
+ count : 0
+ };
+ startNextAsyncOperation();
+ },
+ startNextAsyncOperation : startNextAsyncOperation,
+ stopAsyncOperations : function() {
+ _this.asyncOperations.count = _this.asyncOperations.operationList.length;
+ }
+ }
+}
+
+app.factory("UtilityService", UtilityService);
diff --git a/vid/src/main/webapp/app/vid/scripts/utils/dummy.txt b/vid/src/main/webapp/app/vid/scripts/utils/dummy.txt
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/vid/src/main/webapp/app/vid/scripts/utils/dummy.txt
diff --git a/vid/src/main/webapp/app/vid/scripts/view-models/aaiGetSubs.htm b/vid/src/main/webapp/app/vid/scripts/view-models/aaiGetSubs.htm
new file mode 100644
index 000000000..7d46e3dac
--- /dev/null
+++ b/vid/src/main/webapp/app/vid/scripts/view-models/aaiGetSubs.htm
@@ -0,0 +1,79 @@
+<!--
+ ============LICENSE_START=======================================================
+ VID
+ ================================================================================
+ 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=========================================================
+ -->
+
+<link rel="stylesheet" type="text/css" href="app/vid/styles/aaiGetSubs.css" />
+<link rel="stylesheet" type="text/css" href="app/vid/styles/aaiSubDetails.css" />
+<script src="app/vid/scripts/controller/aaiSubscriberController.js"></script>
+<div ng-controller="aaiSubscriberController" ng-cloak>
+
+ <div>
+ <div class="statusLine" ng-class="{true:'aaiVisible', false:'aaiHidden'}[isSpinnerVisible]">
+ <img src="app/vid/images/spinner.gif"></img>
+ <label>Status:</label><span class="status">{{status}}</span>
+ </div>
+
+ <h2 class="heading2"><center>Search Existing Service Instances</center></h2>
+ <br>
+ Please search by the Subscriber name or enter Service Instance Id below:&nbsp;<br><br>
+
+ <table>
+ <tr>
+ <td style="width:30%">
+ <div class="fn-ebz-container">
+ <label class="fn-ebz-text-label">Subscriber Name:</label>
+ </div>
+ </td>
+ <td style="width:60%" nowrap>
+ <div class="fn-ebz-container" ng-init="autoGetSubs();">
+ <select ng-model="selectedCustomer" ng-options="item.globalCustomerId as item.subscriberName for item in customerList | orderBy:'subscriberName'">
+ <option value="">Select a subscriber</option></select>
+ &nbsp;&nbsp;<a class="btn btn-primary" ng-click="refreshSubs();" ><span class="glyphicon glyphicon-refresh"></span></a>
+ </div>
+ </td>
+
+ </tr>
+ <tr>
+ <td style="width:30%">
+ <div class="fn-ebz-container">
+ <label class="fn-ebz-text-label">Service Instance Id:</label>
+ </div>
+ </td>
+ <td style="width:60%">
+ <div class="fn-ebz-container">
+ <input type="text" style="width: 350px;" name="selectedServiceInstance" ng-model="selectedServiceInstance"/>
+ </div>
+ </td>
+
+ </tr>
+ <tr>
+ <td>
+ <td style="width:30%">
+ <div class="fn-ebz-container">
+ <button type="submit" att-button size="small" ng-click="getSubscriberDet(selectedCustomer,selectedServiceInstance);">Submit</button></a>
+ </div>
+ </td>
+ </td>
+ </tr>
+ </table>
+
+
+ </div>
+
+</div>
diff --git a/vid/src/main/webapp/app/vid/scripts/view-models/aaiSubDetails.htm b/vid/src/main/webapp/app/vid/scripts/view-models/aaiSubDetails.htm
new file mode 100644
index 000000000..90932875a
--- /dev/null
+++ b/vid/src/main/webapp/app/vid/scripts/view-models/aaiSubDetails.htm
@@ -0,0 +1,93 @@
+<!--
+ ============LICENSE_START=======================================================
+ VID
+ ================================================================================
+ 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=========================================================
+ -->
+
+ <div ng-controller="aaiSubscriberController" ng-cloak>
+
+ <div>
+ <div class="statusLine" ng-class="{true:'aaiVisible', false:'aaiHidden'}[isSpinnerVisible]">
+ <img src="app/vid/images/spinner.gif">
+ </img>
+ <label>Status:</label><span class="status">{{status}}</span>
+ </div>
+
+ <h1 class="heading1"><center>Subscriber Details for {{selectedSubscriber}} ({{selectedSubscriberName}})</center></h1>
+ <br>
+ <div class="fn-ebz-container">
+ Filter:
+ <input class="fn-ebz-text" type="text" ng-model="searchString" size="20" style="width: 250px;">
+ </div>
+ <div ng-init="getSubDetails();">
+
+ <div style="margin-top: 30px">
+ <table att-table width="100%" table-data="displayData" view-per-page="viewPerPage" current-page="currentPage" search-category="searchCategory" search-string="searchString" total-page="totalPage" type="header">
+
+ <thead att-table-row>
+ <tr>
+ <th att-table-header sortable="true" key="viewSubDetails">View/Edit</th>
+ <th att-table-header sortable="true" key="globalCustomerId">Global Customer ID</th>
+ <th att-table-header sortable="true" key="subscriberName">Subscriber Name</th>
+ <th att-table-header sortable="true" key="serviceType">Service Type</th>
+ <th att-table-header default-sort="A" sortable="true" key="serviceInstanceName">Service Instance Name</th>
+ <th att-table-header sortable="true" key="serviceInstanceId">Service Instance ID</th>
+ </tr>
+ </thead>
+ <tbody att-table-row type="body" row-repeat="disData in displayData">
+ <tr>
+ <td att-table-body>
+ <div>
+ <a alt="View/Edit" ng-click="getAsdcModel(disData);"> View/Edit </a>
+ </div>
+ </td>
+ <!-- <td att-table-body ><button type=button ng-click="getAsdcModel(disData);" att-button btn-type="primary" size="small">View/Edit</button></td> --->
+ <td att-table-body ng-bind="disData['globalCustomerId']"></td>
+ <td att-table-body ng-bind="disData['subscriberName']"></td>
+ <td att-table-body ng-bind="disData['serviceType']"></td>
+ <td att-table-body ng-bind="disData['serviceInstanceName']"></td>
+ <td att-table-body ng-bind="disData['serviceInstanceId']"></td>
+ </tr>
+ </tbody>
+ </table>
+ <table width='100%'>
+ <tr>
+ <td width='33%' valign='middle'>
+ <span style="cursor: pointer" ng-if="currentPage>1"><button att-button size="small" ng-click="prevPage();">&lt; prev page</button></span>
+ </td>
+ <td width='33%' valign='middle'>
+ Jump to page:
+ <input class="fn-ebz-text" type="text" ng-model="currentPage" size="5" style="width: 47px;">
+ Results per page: <span style="cursor: pointer" ng-click="viewPerPage = 10" ng-style="viewPerPage === 10 && {'textDecoration':'underline','text-color':'black'}">10</span>
+ | <span style="cursor: pointer" ng-click="viewPerPage = 25" ng-style="viewPerPage === 25 && {'textDecoration':'underline','text-color':'black'}">25</span>
+ | <span style="cursor: pointer" ng-click="viewPerPage = 50" ng-style="viewPerPage === 50 && {'textDecoration':'underline','text-color':'black'}">50</span>
+ </td>
+ <td width='34%' align='right' valign='middle'>
+ <span style="cursor: pointer" ng-if="currentPage<totalPage"><button att-button ng-click="nextPage();">next page &gt;</button></span>
+ </td>
+ </tr>
+ </table>
+
+
+ </div>
+
+ </div>
+
+
+ </div>
+
+ </div>
diff --git a/vid/src/main/webapp/app/vid/scripts/view-models/aaiSubViewEdit.htm b/vid/src/main/webapp/app/vid/scripts/view-models/aaiSubViewEdit.htm
new file mode 100644
index 000000000..53c9a6b04
--- /dev/null
+++ b/vid/src/main/webapp/app/vid/scripts/view-models/aaiSubViewEdit.htm
@@ -0,0 +1,147 @@
+<!--
+ ============LICENSE_START=======================================================
+ VID
+ ================================================================================
+ 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=========================================================
+ -->
+
+<div ng-controller="aaiSubscriberController" ng-cloak>
+
+ <div popup-window class="popupContents" ngx-show="{{popup.isVisible}}"
+ ng-cloak>
+ <div ng-include="'app/vid/scripts/view-models/creationDialog.htm'"></div>
+ <div ng-include="'app/vid/scripts/view-models/deletionDialog.htm'"></div>
+ <div ng-include="'app/vid/scripts/view-models/detailsDialog.htm'"></div>
+ </div>
+
+ <div>
+ <div class="statusLine">
+ <img src="app/vid/images/spinner.gif"
+ ng-class="{true:'aaiVisible', false:'aaiHidden'}[isSpinnerVisible]"></img>
+ <label>Status:</label><span class="status">{{status}}</span>
+ </div>
+
+ <h2 class="heading2">
+ <center>VIEW/EDIT SERVICE INSTANCE <a class="btn btn-primary btn-xs pull-right" ng-click="reloadRoute();" ><span class="glyphicon glyphicon-refresh"></span></a></center>
+ </h2>
+ </center>
+ </h2>
+ <br>
+
+
+ <center>
+ <table border="1">
+ <tr>
+ <th style="text-align: center" width="33%">SUBSCRIBER:
+ {{globalCustomerId}}</th>
+ <th style="text-align: center" width="34%">SERVICE TYPE:
+ {{serviceType}}</th>
+ <th style="text-align: center" width="33%">SERVICE INSTANCE
+ ID: {{serviceInstanceId}}</th>
+ <tr>
+ <tr>
+ <td colspan='3' style="text-align: center">Service Instance
+ Name: {{serviceInstanceName || "Not defined"}}
+ </td>
+ <tr>
+ </table>
+
+ </center>
+
+
+ <br>
+
+ <div ng-init="autoPopulateViewEdit();">
+ <script type="text/ng-template" id="nodes_renderer.html">
+ <div ui-tree-handle data-drag-enabled="false" class="tree-node tree-node-content">
+ <a class="btn btn-success btn-xs" ng-if="node.nodes && node.nodes.length > 0" data-nodrag ng-click="toggle(this)"><span
+ class="glyphicon"
+ ng-class="{
+ 'glyphicon-chevron-right': collapsed,
+ 'glyphicon-chevron-down': !collapsed
+ }"></span></a>
+ <div class='btn'>{{node.nodeType}}</div><div class='btn'>{{node.nodeId}}</div><div class='btn'>{{node.nodeStatus}}</div>
+
+ <a class="pull-right btn btn-danger btn-xs" ng-if="node.delete != false" data-nodrag ng-click="showVnfDetails(node);"><span class="glyphicon glyphicon-remove"></a>
+ <a class="pull-right btn btn-primary btn-xs" ng-if="node.info != false" data-nodrag ng-click="showVnfDetails();"><span
+ class="glyphicon glyphicon-zoom-in"></span></a>
+
+ </div>
+ <ol ui-tree-nodes ng-model="node.nodes" ng-class="{hidden: collapsed}">
+ <li ng-repeat="node in node.nodes" ui-tree-node ng-include="'nodes_renderer.html'">
+ </li>
+ </ol>
+</script>
+ <b>EXISTING</b>
+ <div ng-controller="TreeCtrl">
+ <div>
+ <div ui-tree id="tree-root" >
+ <ol ui-tree-nodes ng-model="treeList"">
+ <li ng-repeat="node in treeList" ui-tree-node data-nodrag
+ ng-include="'nodes_renderer.html'"></li>
+ </ol>
+ </div>
+ </div>
+
+ </div>
+ <b>AVAILABLE</b>
+
+ <script type="text/ng-template" id="nodes_renderer2.html">
+ <div ui-tree-handle data-drag-enabled="false" class="tree-node tree-node-content" >
+ <a class="btn btn-success btn-xs" ng-if="node.nodes && node.nodes.length > 0" data-nodrag ng-click="toggle(this)"><span
+ class="glyphicon"
+ ng-class="{
+ 'glyphicon-chevron-right': collapsed,
+ 'glyphicon-chevron-down': !collapsed
+ }"></span></a>
+ <div class='btn'>{{node.nodeType}}</div><div class='btn'>{{node.nodeId}}</div><div class='btn'>{{node.nodeStatus}}</div>
+
+ <a class="pull-right btn btn-primary btn-xs" ng-if="node.delete != false" data-nodrag ng-click="callDelete(this)">
+ <span class="glyphicon glyphicon-plus"></span>
+ </a>
+
+ <a class="pull-right btn btn-primary btn-xs" ng-if="node.info != false" data-nodrag ng-click="showInfoDialog(node.itemType, node.nodeId, node.nodeType);">
+ <span class="glyphicon glyphicon-zoom-in"></span>
+ </a>
+
+ </div>
+ <ol ui-tree-nodes ng-model="node.nodes" ng-class="{hidden: collapsed}">
+ <li ng-repeat="node in node.nodes" ui-tree-node ng-include="'nodes_renderer2.html'">
+ </li>
+ </ol>
+</script>
+
+ <div ng-controller="TreeCtrl">
+ <div>
+ <div ui-tree id="tree-root">
+ <ol ui-tree-nodes ng-model="availableTreeList">
+ <li ng-repeat="node in availableTreeList" ui-tree-node
+ data-nodrag ng-include="'nodes_renderer2.html'"></li>
+ </ol>
+ </div>
+ </div>
+ </div>
+ </div>
+ <div>
+
+ <button type="button" " att-button
+ btn-type="primary" size="small">Show Details</button>
+
+ <pre>
+ {{inventoryResponseItem | json}}
+ </pre>
+ </div>
+ </div>
diff --git a/vid/src/main/webapp/app/vid/scripts/view-models/creationDialog.htm b/vid/src/main/webapp/app/vid/scripts/view-models/creationDialog.htm
new file mode 100644
index 000000000..d016b8f5d
--- /dev/null
+++ b/vid/src/main/webapp/app/vid/scripts/view-models/creationDialog.htm
@@ -0,0 +1,64 @@
+<!--
+ ============LICENSE_START=======================================================
+ VID
+ ================================================================================
+ 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=========================================================
+ -->
+
+<div ng-controller="creationDialogController">
+
+ <div ng-show="isDialogVisible">
+ <div class="titleLine">
+ <img src="app/vid/images/spinner.gif"
+ ngx-visible="{{isSpinnerVisible}}"></img>
+ <h3>Create {{componentName}}</h3>
+ </div>
+
+ <div class="error" ng-show="isErrorVisible">
+ <img src="app/vid/images/error.png"></img>{{error}}
+ </div>
+
+ <div ngx-visible="{{isDataVisible}}">
+ <parameter-block control="summaryControl"></parameter-block>
+ <h4>
+ User Provided Data (<img class="requiredIndicator"
+ src="app/vid/images/asterisk.png" height='10' width='10'></img> indicates required field)
+ </h4>
+ <parameter-block control="userProvidedControl"
+ callback="userParameterChanged(id);" editable></parameter-block>
+
+ <div class="prompt">
+ <p>
+ Enter Data and <span>Confirm</span> to<br />Create <span>{{componentName}}</span>
+ </p>
+ <p>
+ <span>Cancel</span> to Return to Previous Page.<br />Data entered
+ will be lost
+ </p>
+ </div>
+
+ </div>
+ <div class="buttonRow">
+ <button ngx-enabled="{{isConfirmEnabled}}" att-button size="small"
+ ng-click="confirm();">Confirm</button>
+ <button type="button" ng-click="cancel();" att-button
+ btn-type="primary" size="small">Cancel</button>
+ </div>
+ </div>
+
+ <div ng-include="'app/vid/scripts/view-models/msoCommit.htm'"></div>
+
+</div>
diff --git a/vid/src/main/webapp/app/vid/scripts/view-models/deletionDialog.htm b/vid/src/main/webapp/app/vid/scripts/view-models/deletionDialog.htm
new file mode 100644
index 000000000..029d6eaa8
--- /dev/null
+++ b/vid/src/main/webapp/app/vid/scripts/view-models/deletionDialog.htm
@@ -0,0 +1,80 @@
+<!--
+ ============LICENSE_START=======================================================
+ VID
+ ================================================================================
+ 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=========================================================
+ -->
+
+<div ng-controller="deletionDialogController">
+
+ <div ng-show="isDialogVisible">
+ <div class="titleLine">
+ <img src="app/vid/images/spinner.gif"
+ ngx-visible="{{isSpinnerVisible}}"></img>
+ <h3>Delete {{componentName}}</h3>
+ </div>
+
+ <div class="error" ng-show="isErrorVisible">
+ <img src="app/vid/images/error.png"></img>{{error}}
+ </div>
+
+ <parameter-block control="summaryControl"></parameter-block>
+
+ <div ngx-visible="{{isDataVisible}}">
+
+ <h4>
+ User Provided Data (<img class="requiredIndicator"
+ src="app/vid/images/asterisk.png" height='10' width='10'></img> indicates required field)
+ </h4>
+ <parameter-block control="userProvidedControl"
+ callback="userParameterChanged(id);" editable></parameter-block>
+
+ <div class="prompt">
+ <p>
+ Enter Data and <span>Confirm</span> to<br />Delete <span>{{componentName}}</span>
+ </p>
+ <p>
+ <span>Cancel</span> to Return to Previous Page.<br />Data entered
+ will be lost
+ </p>
+ </div>
+ </div>
+
+<!--
+ <div class="prompt">
+ <p>
+ <span>Confirm</span> to Request<br />DELETION of <span>{{componentName}}</span>
+ </p>
+ <p>
+ <span>Cancel</span> to Return to Previous Page
+ </p>
+ </div> -->
+
+ <div class="buttonRow">
+ <!-- <button type="button" ng-click="confirm();" att-button
+ btn-type="primary" size="small" class="confirm">Confirm</button>
+ <button type="button" ng-click="cancel();" att-button
+ btn-type="primary" size="small">Cancel</button> --->
+ <button ngx-enabled="{{isConfirmEnabled}}" att-button size="small"
+ ng-click="confirm();">Confirm</button>
+ <button type="button" ng-click="cancel();" att-button
+ btn-type="primary" size="small">Cancel</button>
+ </div>
+ </div>
+
+ <div ng-include="'app/vid/scripts/view-models/msoCommit.htm'"></div>
+
+</div>
diff --git a/vid/src/main/webapp/app/vid/scripts/view-models/detailsDialog.htm b/vid/src/main/webapp/app/vid/scripts/view-models/detailsDialog.htm
new file mode 100644
index 000000000..82afcbf50
--- /dev/null
+++ b/vid/src/main/webapp/app/vid/scripts/view-models/detailsDialog.htm
@@ -0,0 +1,48 @@
+<!--
+ ============LICENSE_START=======================================================
+ VID
+ ================================================================================
+ 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=========================================================
+ -->
+
+<div ng-controller="detailsDialogController" ng-show="isDialogVisible">
+
+ <div class="titleLine">
+ <img src="app/vid/images/spinner.gif"
+ ngx-visible="{{isSpinnerVisible}}"></img>
+ <h3>Service Instance Details</h3> <!-- {{componentName}} -->
+ </div>
+
+ <div class="error" ng-show="isErrorVisible">
+ <img src="app/vid/images/error.png"></img>{{error}}
+ </div>
+
+ <parameter-block control="summaryControl"></parameter-block>
+
+ <h4>{{componentName}} Details</h4>
+
+ <parameter-block control="detailsControl"></parameter-block>
+
+ <h4>Instantiation Transactions</h4>
+
+ <pre class="log">{{log}}</pre>
+
+ <div class="buttonRow">
+ <button type="button" ng-click="close();" att-button
+ btn-type="primary" size="small">Close</button>
+ </div>
+
+</div>
diff --git a/vid/src/main/webapp/app/vid/scripts/view-models/dummy.txt b/vid/src/main/webapp/app/vid/scripts/view-models/dummy.txt
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/vid/src/main/webapp/app/vid/scripts/view-models/dummy.txt
diff --git a/vid/src/main/webapp/app/vid/scripts/view-models/instantiate.htm b/vid/src/main/webapp/app/vid/scripts/view-models/instantiate.htm
new file mode 100644
index 000000000..1cfa4fb2d
--- /dev/null
+++ b/vid/src/main/webapp/app/vid/scripts/view-models/instantiate.htm
@@ -0,0 +1,204 @@
+<!--
+ ============LICENSE_START=======================================================
+ VID
+ ================================================================================
+ 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=========================================================
+ -->
+
+<div ng-controller="InstantiationController">
+
+ <div popup-window class="popupContents" ngx-show="{{popup.isVisible}}"
+ ng-cloak>
+ <div ng-include="'app/vid/scripts/view-models/creationDialog.htm'"></div>
+ <div ng-include="'app/vid/scripts/view-models/deletionDialog.htm'"></div>
+ <div ng-include="'app/vid/scripts/view-models/detailsDialog.htm'"></div>
+ </div>
+ <div ng-controller="aaiSubscriberController" ng-init="getComponentList() ">
+ <div class="statusLine" ng-class="{true:'aaiVisible', false:'aaiHidden'}[isSpinnerVisible]">
+ <img src="app/vid/images/spinner.gif"></img>
+ <label>Status:</label><span class="status">{{status}}</span>
+ </div>
+
+ <h1 class="heading1" style="margin-top: 20px;">View/Edit Service Instance</h1>
+ <a class="btn btn-primary btn-xs pull-right" ng-click="reloadRoute();" ><span class="glyphicon glyphicon-refresh"></span></a>
+
+ <br>
+
+ <center>
+ <table att-table border="1" ng-model="service">
+ <tr>
+ <th style="text-align: center" width="33%">SUBSCRIBER:
+ {{service.instance.globalCustomerId}}</th>
+ <th style="text-align: center" width="34%">SERVICE TYPE:
+ {{service.instance.serviceType}}</th>
+ <th style="text-align: center" width="33%">SERVICE INSTANCE
+ ID: {{service.instance.serviceInstanceId}}</th>
+ <tr>
+ <tr>
+ <td colspan='3' style="text-align: center">Service Instance
+ Name: {{service.instance.name || "Not defined"}}
+ </td>
+ <tr>
+ </table>
+
+ </center>
+
+ <div ui-tree data-drag-enabled="false" data-nodrop-enabled="true" style="margin: 30px">
+
+ <ol ui-tree-nodes="" ng-model="service" >
+ <li ng-repeat="aService in [service]" ui-tree-node>
+ <div ui-tree-handle class="tree-node tree-node-content">
+ <a class="btn btn-success btn-xs" ng-if="(aService.instance.vnfs && aService.instance.vnfs.length > 0) || (aService.instance.networks && aService.instance.networks.length > 0)" data-nodrag ng-click="this.toggle()">
+ <span class="glyphicon" ng-class="{'glyphicon-chevron-right': collapsed,'glyphicon-chevron-down': !collapsed}"></span>
+ </a>
+ SERVICE INSTANCE: {{aService.instance.name}}
+ <a ng-if="aService.instance.vnfs.length == 0" class="pull-right btn btn-danger btn-xs" data-nodrag ng-click="deleteService(aService.instance);">
+ <span class="glyphicon glyphicon-remove"></span>
+ </a>
+
+ <div class="pull-right btn-group" ng-if="aService.model.vnfs && !equals(aService.model.vnfs, {})">
+ <button type="button" class="btn btn-success btn-xs dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
+ Add VNF<span class="caret"></span>
+ </button>
+ <ul class="dropdown-menu" ng-model="aService.model.vnfs">
+ <li role="menuitem" ng-repeat="(vnfUuid, vnf) in aService.model.vnfs">
+ <!-- 9-21 -->
+ <!-- <a ng-click="addVnfInstance(this, aService.instance, vnf)">{{vnf.name}}</a>-->
+ <a ng-click="addVnfInstance(vnf)">{{vnf.name}}</a>
+ </li>
+ </ul>
+ </div>
+ <!-- <div class="pull-right btn-group" ng-if="aService.model.networks && !equals(aService.model.networks, {})">
+ <button type="button" class="btn btn-success btn-xs dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
+ Add Network<span class="caret"></span>
+ </button>
+ <ul class="dropdown-menu" ng-model="aService.model.networks">
+ <li ng-repeat="(networkUuid, network) in aService.model.networks">
+ <a ng-click="addNetworkInstance(network)">{{network.name}}</a>
+ </li>
+ </ul>
+ </div> -->
+ <a class="pull-right btn btn-primary btn-xs" data-nodrag ng-click="describeService(aService.instance)" style="margin-right: 8px;">
+ <span class="glyphicon glyphicon-info-sign"></span>
+ </a>
+ </div>
+ <ol ui-tree-nodes="" ng-model="aService.instance.vnfs" ng-class="{hidden: collapsed}">
+ <li ng-repeat="vnf in aService.instance.vnfs" ui-tree-node>
+ <div ui-tree-handle class="tree-node tree-node-content">
+ <a class="btn btn-success btn-xs" ng-if="(vnf.vfModules && vnf.vfModules.length > 0) || (vnf.volumeGroups && vnf.volumeGroups.length > 0)" data-nodrag ng-click="this.toggle()">
+ <span class="glyphicon" ng-class="{'glyphicon-chevron-right': collapsed,'glyphicon-chevron-down': !collapsed}"></span>
+ </a>
+ VNF: {{vnf.name}} | TYPE: {{vnf.nodeType}} | ORCH STATUS: {{vnf.nodeStatus}}
+ <a ng-if="(vnf.vfModules.length == 0) && (vnf.volumeGroups.length == 0)" class="pull-right btn btn-danger btn-xs" data-nodrag ng-click="deleteVnf(aService.instance, vnf)">
+ <span class="glyphicon glyphicon-remove"></span>
+ </a>
+ <div class="pull-right btn-group" ng-if="aService.modelByInvariantUuid.vnfs[vnf.object['persona-model-id']][vnf.object['persona-model-version']].vfModules">
+ <button type="button" class="btn btn-success btn-xs dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
+ Add VF-Module<span class="caret"></span>
+ </button>
+ <ul class="dropdown-menu" ng-model="vnf">
+ <li ng-repeat="(vfModuleInvariantUuid, vfModuleVersionModel) in aService.modelByInvariantUuid.vnfs[vnf.object['persona-model-id']][vnf.object['persona-model-version']].vfModules">
+ <a ng-repeat="(vfModuleVersion, vfModule) in vfModuleVersionModel" ng-click="addVfModuleInstance(vnf, vfModule)">{{vfModule.name}}</a>
+ </li>
+ </ul>
+ </div>
+ <div class="pull-right btn-group" ng-if="aService.modelByInvariantUuid.vnfs[vnf.object['persona-model-id']][vnf.object['persona-model-version']].volumeGroups">
+ <button type="button" class="btn btn-success btn-xs dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
+ Add Volume Group<span class="caret"></span>
+ </button>
+ <ul class="dropdown-menu" ng-model="vnf">
+ <li ng-repeat="(volumeGroupInvariantUuid, volumeGroupVersionModel) in aService.modelByInvariantUuid.vnfs[vnf.object['persona-model-id']][vnf.object['persona-model-version']].volumeGroups">
+ <a ng-repeat="(volumeGroupVersion, volumeGroup) in volumeGroupVersionModel" ng-click="addVolumeGroupInstance(vnf, volumeGroup)">{{volumeGroup.name}}</a>
+ </li>
+ </ul>
+ </div>
+ <a class="pull-right btn btn-primary btn-xs" data-nodrag ng-click="describeVnf(aService.instance, vnf)" style="margin-right: 8px;">
+ <span class="glyphicon glyphicon-info-sign"></span>
+ </a>
+ </div>
+ <ol ui-tree-nodes="" ng-model="vnf.vfModules" ng-class="{hidden: collapsed}">
+ <li ng-repeat="vfModule in vnf.vfModules" ui-tree-node>
+ <div ui-tree-handle class="tree-node tree-node-content">
+ <a class="btn btn-success btn-xs" ng-if="(vfModule.volumeGroups && vfModule.volumeGroups.length > 0)" data-nodrag ng-click="this.toggle()">
+ <span class="glyphicon" ng-class="{'glyphicon-chevron-right': collapsed,'glyphicon-chevron-down': !collapsed}"></span>
+ </a>
+ VFMODULE: {{vfModule.name}} | TYPE: {{vfModule.nodeType}} | ORCH STATUS: {{vfModule.nodeStatus}}
+ <!-- -->
+ <a class="pull-right btn btn-danger btn-xs" data-nodrag ng-click="deleteVfModule(aService.instance, vfModule, vnf)">
+ <span class="glyphicon glyphicon-remove"></span>
+ </a>
+ <div class="pull-right btn-group">
+ <!-- <button type="button" class="btn btn-success btn-xs dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
+ Attach Volume Group<span class="caret"></span>
+ </button>
+ <ul class="dropdown-menu" ng-model="vnf.volumeGroups">
+ <li ng-repeat="volumeGroup in vnf.availableVolumeGroups">
+ <a ng-click="attachVolumeGroupInstance(vfModule, volumeGroup)">{{volumeGroup.name}}</a>
+ </li>
+ </ul> -->
+ </div>
+ <a class="pull-right btn btn-primary btn-xs" data-nodrag ng-click="describeVfModule(aService.instance, vfModule)" style="margin-right: 8px;">
+ <span class="glyphicon glyphicon-info-sign"></span>
+ </a>
+ </div>
+ <ol ui-tree-nodes="" ng-model="vfModule.volumeGroups" ng-class="{hidden: collapsed}">
+ <li ng-repeat="volumeGroup in vfModule.volumeGroups" ui-tree-node>
+ <div ui-tree-handle class="tree-node tree-node-content">
+ VOLUME GROUP: {{volumeGroup.name}} | TYPE: {{volumeGroup.nodeType}} | ORCH STATUS: {{volumeGroup.nodeStatus}}
+ <!-- <a class="pull-right btn btn-danger btn-xs" data-nodrag ng-click="deleteVolumeGroup(aService.instance, vnf, vfModule, volumeGroup)">
+ <span class="glyphicon glyphicon-remove"></span>
+ </a> -->
+ <a class="pull-right btn btn-primary btn-xs" data-nodrag ng-click="describeVolumeGroup(aService.instance, volumeGroup)" style="margin-right: 8px;">
+ <span class="glyphicon glyphicon-info-sign"></span>
+ </a>
+ </div>
+ </li>
+ </ol>
+ </li>
+ </ol>
+ <ol ui-tree-nodes="" ng-model="vnf.availableVolumeGroups" ng-class="{hidden: collapsed}">
+ <li ng-repeat="volumeGroup in vnf.availableVolumeGroups" ui-tree-node>
+ <div ui-tree-handle class="tree-node tree-node-content">
+ VOLUME GROUP: {{volumeGroup.name}} | TYPE: {{volumeGroup.nodeType}} | ORCH STATUS: {{volumeGroup.nodeStatus}}
+ <a class="pull-right btn btn-danger btn-xs" data-nodrag ng-click="deleteVnfVolumeGroup(aService.instance, vnf, volumeGroup)">
+ <span class="glyphicon glyphicon-remove"></span>
+ </a>
+ <a class="pull-right btn btn-primary btn-xs" data-nodrag ng-click="describeVolumeGroup(aService.instance, volumeGroup)" style="margin-right: 8px;">
+ <span class="glyphicon glyphicon-info-sign"></span>
+ </a>
+ </div>
+ </li>
+ </ol>
+ </li>
+ </ol>
+ <ol ui-tree-nodes="" ng-model="aService.instance.networks" ng-class="{hidden: collapsed}">
+ <li ng-repeat="network in aService.instance.networks" ui-tree-node>
+ <div ui-tree-handle class="tree-node tree-node-content">
+ NETWORK: {{network.name}} | TYPE: {{network.nodeType}} | ORCH STATUS: {{network.nodeStatus}}
+ <!-- <a class="pull-right btn btn-danger btn-xs" data-nodrag ng-click="deleteNetwork(aService.instance, network)">
+ <span class="glyphicon glyphicon-remove"></span>
+ </a> -->
+ <a class="pull-right btn btn-primary btn-xs" data-nodrag ng-click="describeNetwork(aService.instance, network)" style="margin-right: 8px;">
+ <span class="glyphicon glyphicon-info-sign"></span>
+ </a>
+ </div>
+ </li>
+ </ol>
+ </li>
+ </ol>
+ </div>
+ </div>
+</div>
diff --git a/vid/src/main/webapp/app/vid/scripts/view-models/msoCommit.htm b/vid/src/main/webapp/app/vid/scripts/view-models/msoCommit.htm
new file mode 100644
index 000000000..a47b98323
--- /dev/null
+++ b/vid/src/main/webapp/app/vid/scripts/view-models/msoCommit.htm
@@ -0,0 +1,47 @@
+<!--
+ ============LICENSE_START=======================================================
+ VID
+ ================================================================================
+ 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=========================================================
+ -->
+
+<div ng-controller="msoCommitController" ng-show="isViewVisible">
+
+ <div class="statusLine">
+ <img src="app/vid/images/spinner.gif"
+ ngx-visible="{{isSpinnerVisible}}"> </img> <label>Status:</label><span
+ class="status">{{status}}</span>
+ </div>
+
+ <div class="feedback">
+
+ <div progress-bar control="progressBarControl"
+ value="{{percentProgress}}" increases-only="true"
+ ngx-show="{{isProgressVisible}}"></div>
+
+ <div class="error" ng-show="!isProgressVisible">
+ <img src="app/vid/images/error.png"></img>{{error}}
+ </div>
+
+ </div>
+
+ <pre class="log">{{log}}</pre>
+
+ <div class="buttonRow">
+ <button ngx-enabled="{{isCloseEnabled}}" att-button size="small"
+ ng-click="close();">Close</button>
+ </div>
+</div>
diff --git a/vid/src/main/webapp/app/vid/scripts/view-models/popupWindow.htm b/vid/src/main/webapp/app/vid/scripts/view-models/popupWindow.htm
new file mode 100644
index 000000000..57c40f3f6
--- /dev/null
+++ b/vid/src/main/webapp/app/vid/scripts/view-models/popupWindow.htm
@@ -0,0 +1,8 @@
+<table
+ style="display: none; position: absolute; left: 0; top: 0; width: 100%; height: 100%; border-collapse: collapse; margin: 0; padding: 0">
+ <tr>
+ <td align="center" style="vertical-align: top; padding: 10px"><div
+ style="display: inline-block; padding: 5px; background-color: white"
+ ng-transclude></div></td>
+ </tr>
+</table>
diff --git a/vid/src/main/webapp/app/vid/scripts/view-models/sample.html b/vid/src/main/webapp/app/vid/scripts/view-models/sample.html
new file mode 100644
index 000000000..9cfb10e49
--- /dev/null
+++ b/vid/src/main/webapp/app/vid/scripts/view-models/sample.html
@@ -0,0 +1,61 @@
+<!--
+ ============LICENSE_START=======================================================
+ VID
+ ================================================================================
+ 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=========================================================
+ -->
+
+<div ng-controller="samplePageController">
+
+ <h1 class="heading1" style="margin-top:10px;">Profile Search</h1>
+
+ <table att-table table-data="tableData" view-per-page="viewPerPage" current-page="currentPage" search-category="searchCategory" search-string="searchString" total-page="totalPage">
+
+ <thead att-table-row type="header">
+ <tr>
+ <th att-table-header sortable="true" key="id">User ID</th>
+ <th att-table-header sortable="true" key="lastName">Last Name</th>
+ <th att-table-header sortable="true" key="firstName">First Name</th>
+ <th att-table-header sortable="true" key="email">Email</th>
+ <th att-table-header sortable="true" key="orgUserId">User ID</th>
+ <th att-table-header sortable="true" key="org_manager_userid">Manager User ID</th>
+ </tr>
+ </thead>
+ <tbody att-table-row type="body" row-repeat="rowData in tableData">
+ <tr>
+ <td att-table-body ng-bind="rowData['id']"></td>
+ <td att-table-body ng-bind="rowData['lastName']"></td>
+ <td att-table-body ng-bind="rowData['firstName']"></td>
+ <td att-table-body ng-bind="rowData['email']"></td>
+ <td att-table-body ng-bind="rowData['orgUserId']"></td>
+ <td att-table-body ng-bind="rowData['managerId']"></td>
+ </tr>
+ </tbody>
+ </table>
+
+ <div class="fn-ebz-container">
+ Rows Per Page:
+ <input class="fn-ebz-text" readonly type="text" ng-model="viewPerPage" size="5" style="width: 47px;">
+ </div>
+ <div class="fn-ebz-container">
+ Current Page:
+ <input class="fn-ebz-text" type="text" ng-model="currentPageNum" size="5" style="width: 47px;">
+ </div>
+ <div class="fn-ebz-container">
+ Total Page(s):
+ <input class="fn-ebz-text" type="text" ng-model="totalPages" size="5" readonly="true" style="width: 47px;">
+ </div>
+</div>
diff --git a/vid/src/main/webapp/app/vid/scripts/view-models/sampleWithIframe.html b/vid/src/main/webapp/app/vid/scripts/view-models/sampleWithIframe.html
new file mode 100644
index 000000000..ea128ece8
--- /dev/null
+++ b/vid/src/main/webapp/app/vid/scripts/view-models/sampleWithIframe.html
@@ -0,0 +1,23 @@
+<!--
+ ============LICENSE_START=======================================================
+ VID
+ ================================================================================
+ 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=========================================================
+ -->
+
+<div ng-controller="samplePageWithIframeController" style="margin-left: auto;margin-right: auto;height:700px;">
+ <iframe style="margin-top:5px;width:100%;height:100%" frameBorder="0" vspace="0" src="user_profile"></iframe>
+</div>
diff --git a/vid/src/main/webapp/app/vid/scripts/view-models/serviceModels.htm b/vid/src/main/webapp/app/vid/scripts/view-models/serviceModels.htm
new file mode 100644
index 000000000..84f14ab6b
--- /dev/null
+++ b/vid/src/main/webapp/app/vid/scripts/view-models/serviceModels.htm
@@ -0,0 +1,90 @@
+<!--
+ ============LICENSE_START=======================================================
+ VID
+ ================================================================================
+ 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=========================================================
+ -->
+<link rel="stylesheet" type="text/css" href="app/vid/styles/serviceModels.css" />
+<div popup-window class="popupContents" ngx-show="{{popup.isVisible}}" ng-cloak>
+ <div ng-include="'app/vid/scripts/view-models/creationDialog.htm'"/>
+</div>
+<div>
+
+ <span class="statusLine" ng-class="{true:'smcVisible', false:'smcHidden'}[isSpinnerVisible]">
+ <img src="app/vid/images/spinner.gif"></img>
+ </span>
+ <span class="statusLine" ng-class="{true:'progVisible', false:'progHidden'}[isProgressVisible]">
+ <label>Status:</label><span class="status"><span ng-show="error"><font color='red'><b>Error: </b></font></span>{{status}}</span>
+ </span>
+ <br><br>
+
+ <div class="fn-ebz-container">
+ Filter:
+ <input class="fn-ebz-text" type="text" ng-model="searchString" size="20" style="width: 250px;">
+ </div>
+
+ <h1 class="heading1" style="margin-top:20px;">Browse SDC Service Models</h1>
+ <div style="margin-top:30px" ng-init="getServiceModels();">
+
+ <table att-table table-data="services" view-per-page="viewPerPage" current-page="currentPage" search-category="searchCategory" search-string="searchString" total-page="totalPage">
+ <thead att-table-row type="header">
+ <tr>
+ <th att-table-header key="action">Action</th>
+ <th att-table-header key="uuid">UUID</th>
+ <th att-table-header key="invariantUUID">Invariant UUID</th>
+ <th att-table-header default-sort="A" key="name">Name</th>
+ <th att-table-header key="version">Version</th>
+ <th att-table-header key="category">Category</th>
+ <th att-table-header key="distributionStatus">Distribution Status</th>
+ <th att-table-header key="lastUpdaterUserId">Last Updated By</th>
+ <th att-table-header key="toscaModelUrl">Tosca Model</th>
+ </tr>
+ </thead>
+ <tbody att-table-row type="body" row-repeat="service in services">
+ <tr>
+ <td att-table-body ><button type=button ng-click="deployService(service)" att-button btn-type="primary" size="small">Deploy</button></td>
+ <td att-table-body ng-bind="service['uuid']"></td>
+ <td att-table-body ng-bind="service['invariantUUID']"></td>
+ <td att-table-body ng-bind="service['name']"></td>
+ <td att-table-body ng-bind="service['version']"></td>
+ <td att-table-body ng-bind="service['category']"></td>
+ <td att-table-body ng-bind="service['distributionStatus']"></td>
+ <td att-table-body ng-bind="service['lastUpdaterUserId']"></td>
+ <td att-table-body ng-bind="service['toscaModelUrl']"></td>
+ </tr>
+ </tbody>
+ </table>
+ <table width='100%'>
+ <tr>
+ <td width='33%' valign='middle'>
+ <span style="cursor: pointer" ng-if="currentPage>1"><button att-button size="small" ng-click="prevPage();">&lt; prev page</button></span>
+ </td>
+ <td width='33%' valign='middle'>
+ Jump to page:
+ <input class="fn-ebz-text" type="text" ng-model="currentPage" size="5" style="width: 47px;">
+ Results per page: <span style="cursor: pointer" ng-click="viewPerPage = 10" ng-style="viewPerPage === 10 && {'textDecoration':'underline','text-color':'black'}">10</span>
+ | <span style="cursor: pointer" ng-click="viewPerPage = 25" ng-style="viewPerPage === 25 && {'textDecoration':'underline','text-color':'black'}">25</span>
+ | <span style="cursor: pointer" ng-click="viewPerPage = 50" ng-style="viewPerPage === 50 && {'textDecoration':'underline','text-color':'black'}">50</span>
+ </td>
+ <td width='34%' align='right' valign='middle'>
+ <span style="cursor: pointer" ng-if="currentPage<totalPage"><button att-button ng-click="nextPage();">next page &gt;</button></span>
+ </td>
+ </tr>
+ </table>
+
+ </div>
+ </div>
+
diff --git a/vid/src/main/webapp/app/vid/scripts/view-models/singlePageSample.html b/vid/src/main/webapp/app/vid/scripts/view-models/singlePageSample.html
new file mode 100644
index 000000000..0e6c6f2a4
--- /dev/null
+++ b/vid/src/main/webapp/app/vid/scripts/view-models/singlePageSample.html
@@ -0,0 +1,87 @@
+<!DOCTYPE html>
+<!--
+ ============LICENSE_START=======================================================
+ VID
+ ================================================================================
+ 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=========================================================
+ -->
+
+<html>
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=edge" />
+ <meta http-equiv="cache-control" content="max-age=0" />
+ <meta http-equiv="cache-control" content="no-cache" />
+ <meta http-equiv="expires" content="0" />
+ <meta http-equiv="expires" content="Tue, 01 Jan 1980 1:00:00 GMT" />
+ <meta http-equiv="pragma" content="no-cache" />
+ <!-- CSS -->
+ <link rel="stylesheet" type="text/css" href="app/fusion/external/ebz/fn-ebz.css" >
+ <link rel="stylesheet" type="text/css" href="app/fusion/external/ebz/sandbox/styles/demo.css" >
+ <link rel="stylesheet" type="text/css" href="app/fusion/external/ebz/sandbox/styles/base.css" >
+ <link rel="stylesheet" type="text/css" href="app/fusion/external/ebz/sandbox/styles/btn.css" >
+ <link rel="stylesheet" type="text/css" href="app/fusion/external/ebz/sandbox/styles/dtpk.css" >
+ <link rel="stylesheet" type="text/css" href="app/fusion/external/ebz/sandbox/styles/frms.css" >
+ <link rel="stylesheet" type="text/css" href="app/fusion/external/ebz/sandbox/styles/sldr.css" >
+ <link rel="stylesheet" type="text/css" href="app/fusion/external/ebz/sandbox/styles/style.css" >
+ <link rel="stylesheet" type="text/css" href="app/fusion/external/ebz/sandbox/styles/tbs.css" >
+ <link rel="stylesheet" type="text/css" href="app/fusion/external/ebz/ebz_header/portal_ebz_header.css">
+ <link rel="stylesheet" type="text/css" href="static/fusion/css/jquery-ui.css">
+ <!-- Basic AngularJS -->
+ <script src= "app/fusion/external/ebz/angular_js/angular.js"></script>
+ <script src= "app/fusion/external/ebz/angular_js/angular-sanitize.js"></script>
+ <script src= "app/fusion/external/ebz/angular_js/angular-route.min.js"></script>
+ <script src= "app/fusion/external/ebz/angular_js/app.js"></script>
+ <script src= "app/fusion/external/ebz/angular_js/gestures.js"></script>
+ <script src= "app/fusion/external/ebz/sandbox/att-abs-tpls.js" type="text/javascript"></script>
+ <!-- jQuery -->
+ <script src="static/js/jquery-1.10.2.js"></script>
+ <script src="static/js/jquery.mask.min.js" type="text/javascript"></script>
+ <script src="static/js/jquery-ui.js" type="text/javascript"></script>
+ <!-- AngularJS Gridster -->
+ <script src="static/fusion/js/att_angular_gridster/ui-gridster-tpls.js"></script>
+ <script src="static/fusion/js/att_angular_gridster/angular-gridster.js"></script>
+ <!-- AngularJS Config -->
+ <script src= "app/fusion/external/ebz/angular_js/app.js"></script>
+ <script src= "app/fusion/external/ebz/angular_js/checklist-model.js"></script>
+ <!-- Utility -->
+ <script src="app/fusion/scripts/modalService.js"></script>
+ <!-- Controller js -->
+ <script src="app/fusion/scripts/controllers/rolefunctionpopupController.js"></script>
+ <script src="app/fusion/scripts/controllers/modelpopupController.js"></script>
+ <script src="app/fusionapp/scripts/controller/sampleController.js"></script>
+ <script src="app/fusionapp/scripts/controller/sample-page-controller.js"></script>
+ <script src="app/fusionapp/scripts/controller/sample-page-iframe-controller.js"></script>
+ <!-- Header and Footer -->
+
+ <link rel="stylesheet" type="text/css" href="app/fusion/external/ebz/ebz_header/header.css">
+ <link rel="stylesheet" type="text/css" href="app/fusion/external/ebz/ebz_header/footer.css" >
+ <script src="app/fusion/scripts/directives/footer.js"></script>
+ <script src="app/fusion/external/ebz/js/footer.js"></script>
+ <script src="app/fusion/scripts/directives/header.js"></script>
+ <script src="app/fusion/scripts/directives/leftMenu.js"></script>
+ <!-- Services -->
+ <script src="app/fusion/scripts/services/profileService.js"></script>
+
+ </head>
+ <body class="appBody" ng-app="abs">
+ <div ng-include src="'app/fusion/scripts/view-models/profile-page/popup_modal_rolefunction.html'"></div>
+ <div ng-include src="'app/fusion/scripts/view-models/profile-page/popup_modal.html'"></div>
+ <div q-header></div>
+ <div q-menu class="appLeftMenu"></div>
+ <div ng-view style="min-height: 450px;margin-top:-50px;margin-left:210px;margin-right:10px;"></div>
+ <div q-footer class="appFooter"></div>
+ </body>
+</html>
diff --git a/vid/src/main/webapp/app/vid/scripts/view-models/vidhome.htm b/vid/src/main/webapp/app/vid/scripts/view-models/vidhome.htm
new file mode 100644
index 000000000..41b3b2a77
--- /dev/null
+++ b/vid/src/main/webapp/app/vid/scripts/view-models/vidhome.htm
@@ -0,0 +1,39 @@
+<!--
+ ============LICENSE_START=======================================================
+ VID
+ ================================================================================
+ 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=========================================================
+ -->
+
+<div>
+ <h1 class="heading1">OpenECOMP</h1>
+ <br>
+ <h1 class="heading1"><u>Welcome to VID</u></h1>
+ <br>
+ The Virtual Infrastructure Deployment (VID) application allows infrastructure service deployment operators
+ to instantiate service instances and their constituent parts for Distributed service models required by the
+ OpenECOMP service operations that manage them, such as Mobility Network Services, etc. The models are defined by OpenECOMP component SDC. The service
+ deployment operator selects the service operations owner and model that they wish to instantiate. After
+ entry of appropriate data, the operator instructs VID to direct another OpenECOMP component, MSO, to instantiate
+ the selected service model. Once the service instance has been instantiated, the service operator can instruct
+ VID to direct MSO to instantiate the service instance's component VNFs, VF Modules, Networks and Volume Groups.
+ The VID user can also search for, and display, existing service instances and direct the instantiation of
+ subsequent instance components.
+ <br><br>
+
+ <h1 class="heading1"><a href="mailto:portal@lists.openecomp.org" target="_top">Contact Us</a></h1>
+ <a href="mailto:portal@lists.openecomp.org" target="_top">Please click here to contact us.</a>
+</div>