aboutsummaryrefslogtreecommitdiffstats
path: root/catalog-ui/app/scripts/view-models/workspace/tabs/inputs
diff options
context:
space:
mode:
Diffstat (limited to 'catalog-ui/app/scripts/view-models/workspace/tabs/inputs')
-rw-r--r--catalog-ui/app/scripts/view-models/workspace/tabs/inputs/inputs.less286
-rw-r--r--catalog-ui/app/scripts/view-models/workspace/tabs/inputs/resource-input/resource-inputs-view-model.ts145
-rw-r--r--catalog-ui/app/scripts/view-models/workspace/tabs/inputs/resource-input/resource-inputs-view.html136
-rw-r--r--catalog-ui/app/scripts/view-models/workspace/tabs/inputs/resource-input/resource-inputs.less9
-rw-r--r--catalog-ui/app/scripts/view-models/workspace/tabs/inputs/service-input/service-inputs-view-model.ts246
-rw-r--r--catalog-ui/app/scripts/view-models/workspace/tabs/inputs/service-input/service-inputs-view.html205
-rw-r--r--catalog-ui/app/scripts/view-models/workspace/tabs/inputs/service-input/service-inputs.less54
7 files changed, 1081 insertions, 0 deletions
diff --git a/catalog-ui/app/scripts/view-models/workspace/tabs/inputs/inputs.less b/catalog-ui/app/scripts/view-models/workspace/tabs/inputs/inputs.less
new file mode 100644
index 0000000000..76a82c69ee
--- /dev/null
+++ b/catalog-ui/app/scripts/view-models/workspace/tabs/inputs/inputs.less
@@ -0,0 +1,286 @@
+.workspace-inputs {
+
+ .sdc-workspace-container .w-sdc-main-right-container .w-sdc-main-container-body-content {
+ padding: 25px 8% 0px 8%;
+ }
+
+ width: 100%;
+ display: flex;
+
+ .text {
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ padding-left: 15px;
+ }
+
+ .title-text {
+ color: @main_color_m;
+ .f-type._13_m;
+ .bold;
+ }
+
+ .title-blue-text {
+ color: @main_color_a;
+ .f-type._13_m;
+
+ &.property-name-text {
+ padding-right: 13px;
+ border-right: 1px solid rgba(120, 136, 148, 0.26);
+ flex-grow: 1;
+ }
+ }
+
+ .instance-name-text {
+ flex-grow: 1;
+ }
+
+ ng-include {
+ width: 45%;
+ }
+
+ .w-sdc-inputs-search {
+ padding: 10px 20px 20px 0;
+ white-space: nowrap;
+ position: relative;
+ width: 60%;
+ height: 64px;
+
+ .inputs-search-icon {
+ top: 9px;
+ right: 11px;
+ }
+
+ .magnification-white {
+ .sprite-new;
+ .search-white-icon;
+ .hand;
+ }
+
+ .search-icon-container {
+ width: 35px;
+ height: 30px;
+ background-color: @main_color_a;
+ white-space: nowrap;
+ float: right;
+ position: relative;
+ bottom: 31px;
+ right: 1px;
+ border-radius: 0px 4px 4px 0px;
+ .hand
+ }
+ }
+
+ .total-inputs-count {
+ width: 100%;
+ font-weight: bold;
+ text-align: left;
+ }
+
+ .new-input-button {
+ margin: 9px 0 0 0;
+ }
+
+ .w-sdc-inputs-search-input {
+ border: 1px solid @color_e;
+ .border-radius(4px);
+ height: 32px;
+ margin: 0;
+ padding: 0px 28px 3px 10px;
+ vertical-align: 4px;
+ width: 100%;
+ outline: none;
+ font-style: italic;
+ }
+
+ .w-sdc-classic-btn {
+ float: right;
+ margin-bottom: 10px;
+ }
+
+ .prop-to-input-button {
+ position: absolute;
+ top: 50%;
+ margin-right: -20px;
+ margin-bottom: -10px;
+
+ }
+
+ .property-row {
+ border-bottom: 1px solid @border_color_d;
+ padding-left: 10px;
+ .property-name-container {
+ display: flex;
+ flex-grow: 4;
+ }
+
+ .type-schema-container {
+ flex-grow: 1;
+ border-left: 1px solid @border_color_d;
+ text-align: left;
+ line-height: 30px;
+ text-transform: capitalize;
+ width: 10px;
+ }
+
+ }
+
+ .table-container-flex {
+
+ .flex-item {
+ line-height: 22px;
+ }
+ .expand-collapse-table-row {
+
+ &.expanded {
+ .flex-container {
+ .expand-collapse-inputs-table-icon {
+ transform: rotate(180deg);
+ left: 0px;
+ }
+ }
+ }
+
+ .data-row {
+ background: @tlv_color_u;
+ .hand;
+ align-items: center;
+ padding: 0 12px;
+ margin: 1px 0px 1px 0px;
+ min-height: 40px;
+ }
+
+ .data-row:hover {
+ .bg_j;
+ }
+
+ .input-row {
+ padding-left: 45px;
+ background: @tlv_color_t;
+ border: @main_color_o solid 1px;
+ align-items: center;
+ .hand;
+ margin: 1px 0px 1px 0px;
+
+ &.service-input-row {
+ background: @tlv_color_u;
+ &.new-input {
+ background: @tlv_color_v;
+ }
+ }
+ &.selected {
+ background-color: @tlv_color_v;
+ }
+ .flex-item {
+ min-height: 60px;
+ padding: 0 15px;
+ }
+ .input-check-box {
+ padding-right: 10px;
+ margin-top: 9px;
+ }
+ &>.title-text{
+ text-align: start;
+ padding: 4px 0 0 35px;
+ }
+
+ .expand-collapse-inputs-table-icon{
+ margin-top: 15px;
+ }
+
+ }
+
+ .input-row:hover {
+ .bg_j;
+ }
+
+
+ }
+ }
+
+ .table {
+ height: 640px;
+ margin-bottom: 0;
+ clear: both;
+
+ .empty-row {
+ padding: 3px;
+ }
+
+ .flex-item {
+ line-height: 22px;
+ }
+
+ .table-header {
+
+ line-height: 14px;
+ background-color: @main_color_a;
+ color: @main_color_p;
+ text-align: left;
+ padding: 7px 5px 7px 10px;
+ .f-type._14_m;
+ }
+ .head {
+ background-color: #e6e6e6;
+ }
+
+ .property-row:hover{
+ background-color: @func_color_r;
+ }
+
+ .body {
+ .scrollbar-container {
+ .perfect-scrollbar;
+ max-height: 610px;
+ }
+
+ .expand-collapse-inputs-table-icon {
+ .hand;
+ .sprite-new;
+ .arrow-up;
+ transition: .3s all;
+ position: relative;
+ left: 8px;
+ border: none !important;
+ padding: 0px 10px 0px 10px;
+ }
+
+ .table-col-text {
+ margin-left: 14px;
+ }
+ }
+ }
+
+ .inputs-header {
+ width: 100%;
+ position: relative;
+ bottom: 31px;
+ }
+
+ .inputs-tables-container {
+ width: 100%;
+ min-width: 100%;
+ display: flex;
+ }
+
+ .inputs-button-container {
+ width: 8%;
+ min-width: 8%;
+ display: flex;
+
+ .right-arrow-btn {
+ .sprite-new;
+ .blue-right-arrow-circle;
+ margin: auto;
+ cursor: pointer;
+ }
+ }
+
+ .table-container-flex {
+ margin-top: 27px;
+ width: 46%;
+ min-width: 46%;
+ display: inline-block;
+ float: left;
+ }
+}
diff --git a/catalog-ui/app/scripts/view-models/workspace/tabs/inputs/resource-input/resource-inputs-view-model.ts b/catalog-ui/app/scripts/view-models/workspace/tabs/inputs/resource-input/resource-inputs-view-model.ts
new file mode 100644
index 0000000000..2dc1b1d9ff
--- /dev/null
+++ b/catalog-ui/app/scripts/view-models/workspace/tabs/inputs/resource-input/resource-inputs-view-model.ts
@@ -0,0 +1,145 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * 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=========================================================
+ */
+/// <reference path="../../../../../references"/>
+module Sdc.ViewModels {
+ 'use strict';
+ import Dictionary = Sdc.Utils.Dictionary;
+ import InputModel = Sdc.Models.InputModel;
+
+ export interface IInputsViewModelScope extends IWorkspaceViewModelScope {
+ InstanceInputsProperties:Models.InstanceInputsPropertiesMapData; //this is tha map object that hold the selected inputs and the inputs we already used
+ vfInstancesList: Array<Models.ComponentsInstances.ComponentInstance>;
+ component:Models.Components.Resource;
+
+ onArrowPressed():void;
+ getInputPropertiesForInstance(instanceId:string, instance:Models.ComponentsInstances.ComponentInstance): ng.IPromise<boolean> ;
+ loadInputPropertiesForInstance(instanceId:string, input:Models.InputModel): ng.IPromise<boolean> ;
+ loadInputInputs(input:Models.InputModel): ng.IPromise<boolean>;
+ }
+
+ export class ResourceInputsViewModel {
+
+ static '$inject' = [
+ '$scope',
+ '$q'
+ ];
+
+ constructor(private $scope:IInputsViewModelScope, private $q: ng.IQService) {
+ this.initScope();
+ }
+
+ private initScope = (): void => {
+
+ this.$scope.InstanceInputsProperties = new Models.InstanceInputsPropertiesMapData();
+ this.$scope.vfInstancesList = this.$scope.component.componentInstances;
+
+ // Need to cast all inputs to InputModel for the search to work
+ let tmpInputs:Array<Models.InputModel> = new Array<Models.InputModel>();
+ _.each(this.$scope.component.inputs, (input):void => {
+ tmpInputs.push(new Models.InputModel(input));
+ });
+ this.$scope.component.inputs = tmpInputs;
+ // This function is not supported for resource
+ //this.$scope.component.getComponentInputs();
+
+ /*
+ * When clicking on instance input in the left or right table, this function will load all properties of the selected input
+ */
+ this.$scope.getInputPropertiesForInstance = (instanceId:string, instance:Models.ComponentsInstances.ComponentInstance): ng.IPromise<boolean> => {
+ let deferred = this.$q.defer();
+ instance.properties = this.$scope.component.componentInstancesProperties[instanceId];
+ deferred.resolve(true);
+ return deferred.promise;
+ };
+
+ /*
+ * When clicking on input in the right table, this function will load all inputs of the selected input
+ */
+ this.$scope.loadInputInputs = (input:Models.InputModel): ng.IPromise<boolean> => {
+ let deferred = this.$q.defer();
+
+ let onSuccess = () => { deferred.resolve(true); };
+ let onError = () => { deferred.resolve(false); };
+
+ if(!input.inputs) {
+ this.$scope.component.getResourceInputInputs(input.uniqueId).then(onSuccess, onError);
+ } else {
+ deferred.resolve(true);
+ }
+ return deferred.promise;
+ };
+
+ /*
+ * When clicking on instance input in the left or right table, this function will load all properties of the selected input
+ */
+ this.$scope.loadInputPropertiesForInstance = (instanceId:string, input:Models.InputModel): ng.IPromise<boolean> => {
+ let deferred = this.$q.defer();
+
+ let onSuccess = (properties:Array<Models.PropertyModel>) => {
+ input.properties = properties;
+ deferred.resolve(true);
+ };
+
+ let onError = () => {
+ deferred.resolve(false)
+ };
+
+ if(!input.properties) {
+ this.$scope.component.getComponentInstanceInputProperties(instanceId, input.uniqueId).then(onSuccess, onError);
+ } else {
+ deferred.resolve(true);
+ }
+ return deferred.promise;
+ };
+
+ /*
+ * When pressing the arrow, we create service inputs from the inputs selected
+ */
+ this.$scope.onArrowPressed = ():void => {
+ let onSuccess = (inputsCreated: Array<Models.InputModel>) => {
+
+ //disabled all the inputs in the left table
+ _.forEach(this.$scope.InstanceInputsProperties, (properties:Array<Models.PropertyModel>) => {
+ _.forEach(properties, (property:Models.PropertyModel) => {
+ property.isAlreadySelected = true;
+ });
+ });
+
+ // Adding color to the new inputs (right table)
+ _.forEach(inputsCreated, (input) => {
+ input.isNew = true;
+ });
+
+ // Removing color to the new inputs (right table)
+ setTimeout(() => {
+ _.forEach(inputsCreated, (input) => {
+ input.isNew = false;
+ });
+ this.$scope.$apply();
+ }, 3000);
+ };
+
+ this.$scope.component.createInputsFormInstances(this.$scope.InstanceInputsProperties).then(onSuccess);
+ };
+
+ }
+
+ }
+}
diff --git a/catalog-ui/app/scripts/view-models/workspace/tabs/inputs/resource-input/resource-inputs-view.html b/catalog-ui/app/scripts/view-models/workspace/tabs/inputs/resource-input/resource-inputs-view.html
new file mode 100644
index 0000000000..7cdf5a2fa4
--- /dev/null
+++ b/catalog-ui/app/scripts/view-models/workspace/tabs/inputs/resource-input/resource-inputs-view.html
@@ -0,0 +1,136 @@
+<div class="workspace-inputs">
+ <div class="table-container-flex">
+ <div class="w-sdc-inputs-search pull-left hideme">
+ <input type="text" class="w-sdc-inputs-search-input" placeholder="Search"/>
+ <div class="search-icon-container">
+ <span class="w-sdc-search-icon inputs-search-icon magnification-white"></span>
+ </div>
+ </div>
+ <div class="table">
+ <div class="table-header">VFC instances inputs</div>
+ <div class="body">
+ <div class="table-loader" ng-class="{'tlv-loader large loader': isLoading}"></div>
+ <perfect-scrollbar scroll-y-margin-offset="0" class="scrollbar-container">
+
+ <expand-collapse expanded-selector=".vf-instance-list.{{$index}}"
+ class="expand-collapse-table-row"
+ load-data-function="getInputPropertiesForInstance(instance.uniqueId, instance)"
+ is-close-on-init="true"
+ data-ng-repeat-start="instance in vfInstancesList track by $index">
+ <div class="flex-container data-row">
+ <div class="expand-collapse-inputs-table-icon"></div>
+ <div class="table-col-general flex-item text">
+ <span class="title-text">{{instance.name}}</span>
+ </div>
+ </div>
+
+ </expand-collapse>
+
+ <div data-ng-repeat-end="" class="vf-instance-list {{$index}}">
+
+ <div class="empty-row" ng-if="instance.properties.length===0">No properties to display</div>
+
+ <div ng-repeat="property in instance.properties track by $index">
+ <div class="property-row flex-container">
+ <div class="flex-item text property-name-container">
+ <span class="title-blue-text property-name-text">{{property.name}}</span>
+ <span class="text instance-name-text">{{property.name}}</span>
+ </div>
+ <div class="type-schema-container">
+ <div class="text">
+ <span>{{property.type}}</span>
+ </div>
+ </div>
+ <div class="type-schema-container">
+ <div class="text">
+ <span>{{property.schema.property.type}} </span>
+ </div>
+ </div>
+ <!--<sdc-checkbox
+ class="type-schema-container input-check-box"
+ disabled ="property.isAlreadySelected"
+ sdc-checklist-model="InstanceInputsProperties[instance.uniqueId]"
+ sdc-checklist-value="property"
+ data-ng-click="$event.stopPropagation()"></sdc-checkbox>-->
+ </div>
+ </div>
+
+ </div>
+
+ </perfect-scrollbar>
+ </div>
+ </div>
+ </div>
+
+ <div class="inputs-button-container pull-left">
+ <!--<div ng-click="onArrowPressed()" class="right-arrow-btn"></div>-->
+ </div>
+
+ <div class="table-container-flex">
+ <div class="w-sdc-inputs-search pull-left">
+ <input type="text" class="w-sdc-inputs-search-input" data-ng-model="search.filterTerm" placeholder="Search" data-ng-model-options="{debounce: 200}"/>
+ <div class="search-icon-container">
+ <span class="w-sdc-search-icon inputs-search-icon magnification-white"></span>
+ </div>
+ </div>
+ <div class="table">
+ <div class="body">
+ <div class="table-header">Resource instance inputs</div>
+ <perfect-scrollbar scroll-y-margin-offset="0" include-padding="true" class="scrollbar-container">
+ <expand-collapse expanded-selector=".resource-inputs.{{$index}}"
+ class="expand-collapse-table-row"
+ load-data-function="loadInputPropertiesForInstance(resourceInput.uniqueId, resourceInput)"
+ is-close-on-init="true"
+ data-ng-repeat-start="resourceInput in component.inputs | filter:search track by $index ">
+ <div class="input-row service-input-row">
+ <div class="title-text">{{resourceInput.name}}</div>
+ <div class="flex-container" ng-class="resourceInput.isNew ? 'new-input': 'service-input-row'">
+ <div class="expand-collapse-inputs-table-icon"></div>
+ <div class="flex-item">
+ <div>
+ <span class="title-text">Description:</span>
+ <span>{{resourceInput.description}}</span>
+ </div>
+ </div>
+ <div class="flex-item ">
+ <div class="text">
+ <span class="title-text">VF Instance:</span>
+ <span>{{resourceInput.name}}</span>
+ </div>
+ <div class="text">
+ <span class="title-text">Type:</span>
+ <span>{{resourceInput.type}} </span>
+ </div>
+ </div>
+ </div>
+ </div>
+ </expand-collapse>
+
+ <div data-ng-repeat-end="" class="input-inputs-list resource-inputs {{$index}}">
+ <div class="empty-row" ng-if="resourceInput.properties.length===0">No properties to display</div>
+ <div ng-repeat="property in resourceInput.properties track by $index">
+ <div class="property-row flex-container">
+ <div class="flex-item text property-name-container">
+ <span
+ class="title-blue-text property-name-text">{{property.name}}</span>
+ <span class="text instance-name-text">{{property.name}}</span>
+ </div>
+ <div class="type-schema-container">
+ <div class="text">
+ <span>{{property.type}}</span>
+ </div>
+ </div>
+ <div class="type-schema-container">
+ <div class="text">
+ <span>{{property.schema.property.type}} </span>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ </perfect-scrollbar>
+ </div>
+ </div>
+ </div>
+</div>
diff --git a/catalog-ui/app/scripts/view-models/workspace/tabs/inputs/resource-input/resource-inputs.less b/catalog-ui/app/scripts/view-models/workspace/tabs/inputs/resource-input/resource-inputs.less
new file mode 100644
index 0000000000..ebb32fbdb2
--- /dev/null
+++ b/catalog-ui/app/scripts/view-models/workspace/tabs/inputs/resource-input/resource-inputs.less
@@ -0,0 +1,9 @@
+.workspace-inputs {
+
+ .property-row {
+ .input-check-box {
+ text-align: center;
+ }
+ }
+
+}
diff --git a/catalog-ui/app/scripts/view-models/workspace/tabs/inputs/service-input/service-inputs-view-model.ts b/catalog-ui/app/scripts/view-models/workspace/tabs/inputs/service-input/service-inputs-view-model.ts
new file mode 100644
index 0000000000..6c8391720a
--- /dev/null
+++ b/catalog-ui/app/scripts/view-models/workspace/tabs/inputs/service-input/service-inputs-view-model.ts
@@ -0,0 +1,246 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * 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=========================================================
+ */
+/// <reference path="../../../../../references"/>
+module Sdc.ViewModels {
+ 'use strict';
+ import IAngularEvent = angular.IAngularEvent;
+ import ComponentInstance = Sdc.Models.ComponentsInstances.ComponentInstance;
+
+
+ interface IServiceInputsViewModelScope extends IWorkspaceViewModelScope {
+
+ vfInstancesList: Array<ComponentInstance>;
+ selectedInputs:Array<Models.InputModel>;
+ instanceInputsMap:Models.InstancesInputsMapData; //this is tha map object that hold the selected inputs and the inputs we already used
+ component:Models.Components.Service;
+ sdcMenu:Models.IAppMenu;
+
+ onArrowPressed():void;
+ loadComponentInputs(): void;
+ loadInstanceInputs(instance:ComponentInstance): ng.IPromise<boolean> ;
+ loadInputPropertiesForInstance(instanceId:string, input:Models.InputModel): ng.IPromise<boolean> ;
+ loadInputInputs(input:Models.InputModel): ng.IPromise<boolean>;
+ deleteInput(input:Models.InputModel):void
+ }
+
+ export class ServiceInputsViewModel {
+
+ static '$inject' = [
+ '$scope',
+ '$q',
+ 'ModalsHandler'
+ ];
+
+ constructor(private $scope:IServiceInputsViewModelScope,
+ private $q: ng.IQService,
+ private ModalsHandler: Sdc.Utils.ModalsHandler) {
+ this.initScope();
+ }
+
+ /*
+ * When loading the screen again, we need to disabled the inputs that already created on the service,
+ * we do that by comparing the service input name, to the instance name + '_' + the resource instance input name.
+ */
+ private disableEnableSelectedInputs = (instance: ComponentInstance): void => {
+
+ let alreadySelectedInput = new Array<Models.InputModel>();
+ _.forEach(instance.inputs, (input:Models.InputModel) => {
+ let expectedServiceInputName = instance.normalizedName + '_' + input.name;
+ let inputAlreadyInService: Models.InputModel = _.find(this.$scope.component.inputs, (serviceInput: Models.InputModel) => {
+ return serviceInput.name === expectedServiceInputName;
+ });
+ if(inputAlreadyInService) {
+ input.isAlreadySelected = true;
+ alreadySelectedInput.push(input);
+ } else {
+ input.isAlreadySelected = false;
+ }
+ });
+ this.$scope.instanceInputsMap[instance.uniqueId] = alreadySelectedInput;
+ };
+
+ private initScope = (): void => {
+
+ this.$scope.instanceInputsMap = new Models.InstancesInputsMapData();
+ this.$scope.isLoading = true;
+ this.$scope.selectedInputs = new Array<Models.InputModel>();
+
+ // Why do we need this? we call this later.
+ //this.$scope.component.getComponentInputs();
+
+ let onSuccess = (componentInstances:Array<ComponentInstance>) => {
+ console.log("component instances loaded: ", componentInstances);
+ this.$scope.vfInstancesList = componentInstances;
+ this.$scope.isLoading = false;
+ };
+
+ //This function will get al component instance for the left table - in future the instances will be filter according to search text
+ this.$scope.component.getComponentInstancesFilteredByInputsAndProperties().then(onSuccess);
+
+ // This function will get the service inputs for the right table
+ this.$scope.component.getComponentInputs();
+
+
+ /*
+ * When clicking on instance in the left table, this function will load all instance inputs
+ */
+ this.$scope.loadInstanceInputs = (instance:ComponentInstance): ng.IPromise<boolean> => {
+ let deferred = this.$q.defer();
+
+ let onSuccess = (inputs:Array<Models.InputModel>) => {
+ instance.inputs = inputs;
+ this.disableEnableSelectedInputs(instance);
+ deferred.resolve(true);
+ };
+
+ let onError = () => {
+ deferred.resolve(false);
+ };
+
+ if(!instance.inputs) {
+ this.$scope.component.getComponentInstanceInputs(instance.uniqueId, instance.componentUid).then(onSuccess, onError);
+ this.disableEnableSelectedInputs(instance);
+ } else {
+ deferred.resolve(true);
+ }
+ return deferred.promise;
+ };
+
+ /*
+ * When clicking on instance input in the left or right table, this function will load all properties of the selected input
+ */
+ this.$scope.loadInputPropertiesForInstance = (instanceId:string, input:Models.InputModel): ng.IPromise<boolean> => {
+ let deferred = this.$q.defer();
+
+ let onSuccess = (properties:Array<Models.PropertyModel>) => {
+ input.properties = properties;
+ deferred.resolve(true);
+ };
+
+ let onError = () => {
+ deferred.resolve(false)
+ };
+
+ if(!input.properties) {
+ this.$scope.component.getComponentInstanceInputProperties(instanceId, input.uniqueId).then(onSuccess, onError);
+ } else {
+ deferred.resolve(true);
+ }
+ return deferred.promise;
+ };
+
+ /*
+ * When clicking on input in the right table, this function will load all inputs of the selected input
+ */
+ this.$scope.loadInputInputs = (input:Models.InputModel): ng.IPromise<boolean> => {
+ let deferred = this.$q.defer();
+
+ let onSuccess = () => { deferred.resolve(true); };
+ let onError = () => { deferred.resolve(false); };
+
+ if(!input.inputs) { // Caching, if exists do not get it.
+ this.$scope.component.getServiceInputInputs(input.uniqueId).then(onSuccess, onError);
+ } else {
+ deferred.resolve(true);
+ }
+ return deferred.promise;
+ };
+
+ /*
+ * When pressing the arrow, we create service inputs from the inputs selected
+ */
+ this.$scope.onArrowPressed = ():void => {
+ let onSuccess = (inputsCreated: Array<Models.InputModel>) => {
+
+ //disabled all the inputs in the left table
+ _.forEach(this.$scope.instanceInputsMap, (inputs:Array<Models.InputModel>, instanceId:string) => {
+ _.forEach(inputs, (input:Models.InputModel) => {
+ input.isAlreadySelected = true;
+ });
+ });
+
+ this.addColorToItems(inputsCreated);
+ };
+
+ this.$scope.component.createInputsFormInstances(this.$scope.instanceInputsMap).then(onSuccess);
+ };
+
+ this.$scope.deleteInput = (input: Models.InputModel):void => {
+
+ var onDelete = ():void => {
+ var onSuccess = (deletedInput: Models.InputModel, componentInstanceId:string):void => {
+ // Remove from component.inputs the deleted input (service inputs)
+ var remainingServiceInputs:Array<Models.InputModel> = _.filter(this.$scope.component.inputs, (input:Models.InputModel):boolean => {
+ return input.uniqueId !== deletedInput.uniqueId;
+ });
+ this.$scope.component.inputs = remainingServiceInputs;
+
+ // Find the instance that contains the deleted input, and set disable|enable the deleted input
+ var deletedInputComponentInstance:ComponentInstance = _.find(this.$scope.vfInstancesList, (instanceWithChildToDelete:ComponentInstance):boolean => {
+ return instanceWithChildToDelete.uniqueId === componentInstanceId;
+ });
+ this.disableEnableSelectedInputs(deletedInputComponentInstance);
+ };
+
+ var onFailed = (error:any) : void => {
+ console.log("Error deleting input");
+ };
+
+ this.addColorToItems([input]);
+
+ // Get service inputs of input (so after delete we will know the component instance)
+ this.$scope.loadInputInputs(input).then((result:boolean):void=>{
+ if (result && input.inputs.length>0) {
+ var componentInstanceId:string = input.inputs[0].componentInstanceId;
+ this.$scope.component.deleteServiceInput(input.uniqueId).then((deletedInput: Models.InputModel):void => {
+ onSuccess(deletedInput, componentInstanceId);
+ }, onFailed);
+ }
+ });
+ };
+
+ // Get confirmation modal text from menu.json
+ var state = "deleteInput";
+ var title:string = this.$scope.sdcMenu.alertMessages[state].title;
+ var message:string = this.$scope.sdcMenu.alertMessages[state].message.format([input.name]);
+
+ // Open confirmation modal
+ this.ModalsHandler.openAlertModal(title, message).then(onDelete);
+ }
+ };
+
+ private addColorToItems = (inputsCreated:Array<Models.InputModel>):void => {
+
+ // Adding color to the new inputs (right table)
+ _.forEach(inputsCreated, (input) => {
+ input.isNew = true;
+ });
+
+ // Removing color to the new inputs (right table)
+ setTimeout(() => {
+ _.forEach(inputsCreated, (input) => {
+ input.isNew = false;
+ });
+ this.$scope.$apply();
+ }, 3000);
+ };
+
+ }
+}
diff --git a/catalog-ui/app/scripts/view-models/workspace/tabs/inputs/service-input/service-inputs-view.html b/catalog-ui/app/scripts/view-models/workspace/tabs/inputs/service-input/service-inputs-view.html
new file mode 100644
index 0000000000..bf15a70322
--- /dev/null
+++ b/catalog-ui/app/scripts/view-models/workspace/tabs/inputs/service-input/service-inputs-view.html
@@ -0,0 +1,205 @@
+<div class="workspace-inputs">
+ <div class="table-container-flex">
+ <div class="w-sdc-inputs-search pull-left hideme">
+ <input type="text" class="w-sdc-inputs-search-input" placeholder="Search"/>
+ <div class="search-icon-container">
+ <span class="w-sdc-search-icon inputs-search-icon magnification-white"></span>
+ </div>
+ </div>
+ <div class="table">
+ <div class="table-header">Resource instance inputs</div>
+ <div class="body">
+ <div class="table-loader" ng-class="{'tlv-loader large loader': isLoading}"></div>
+ <perfect-scrollbar scroll-y-margin-offset="0" class="scrollbar-container">
+
+ <expand-collapse expanded-selector=".vf-instance-list.{{$index}}"
+ class="expand-collapse-table-row"
+ load-data-function="loadInstanceInputs(instance)"
+ is-close-on-init="true"
+ data-ng-repeat-start="instance in vfInstancesList track by $index">
+ <div class="flex-container data-row">
+ <div class="expand-collapse-inputs-table-icon"></div>
+ <div class="table-col-general flex-item text" data-tests-id="inputs-vf-instance-{{$index}}">
+ <span class="title-text">{{instance.name}}</span>
+ </div>
+ </div>
+
+ </expand-collapse>
+
+ <div data-ng-repeat-end="" class="vf-instance-list {{$index}}">
+
+ <expand-collapse expanded-selector=".input-list.{{$parent.$index}}-{{$index}}"
+ class="expand-collapse-table-row"
+ load-data-function="loadInputPropertiesForInstance(instance.uniqueId, input)"
+ is-close-on-init="true"
+ data-ng-repeat-start="input in instance.inputs track by $index">
+ <div class="input-row" ng-class="{'selected': selectedInput.uniqueId === input.uniqueId}">
+ <div class="title-text">{{input.name}}</div>
+ <div class="flex-container">
+ <div class="expand-collapse-inputs-table-icon"></div>
+ <div class="flex-item">
+
+ <div>
+ <span class="title-text">Description:</span>
+ <span tooltips tooltip-content="{{input.description}}">{{input.description}}</span>
+ </div>
+ </div>
+ <div class="flex-item ">
+ <div class="text">
+ <span class="title-text">VF Instance:</span>
+ <span tooltips tooltip-content="{{instance.name}}">{{instance.name}}</span>
+ </div>
+ <div class="text">
+ <span class="title-text">Type:</span>
+ <span tooltips tooltip-content="{{input.type}}">{{input.type}} </span>
+ </div>
+ </div>
+ <sdc-checkbox
+ class="input-check-box"
+ disabled ="input.isAlreadySelected || isViewMode()"
+ sdc-checklist-model="instanceInputsMap[instance.uniqueId]"
+ sdc-checklist-value="input"
+ data-tests-id="inputs-checkbox-{{$index}}"
+ data-ng-click=" $event.stopPropagation()"></sdc-checkbox>
+ </div>
+ </div>
+
+
+ </expand-collapse>
+
+ <div data-ng-repeat-end="" class="input-list {{$parent.$index}}-{{$index}}">
+ <div class="empty-row" ng-if="input.properties.length===0">No properties to display</div>
+
+ <div ng-repeat="property in input.properties track by $index">
+ <div class="property-row flex-container">
+ <div class="flex-item text property-name-container">
+ <span class="title-blue-text property-name-text" tooltips tooltip-content="{{property.name}}">{{property.name}}</span>
+ <span class="text instance-name-text" tooltips tooltip-content="{{property.name}}">{{property.name}}</span>
+ </div>
+ <div class="type-schema-container">
+ <div class="text">
+ <span tooltips tooltip-content="{{property.type}}">{{property.type}}</span>
+ </div>
+ </div>
+ <div class="type-schema-container">
+ <div class="text">
+ <span tooltips tooltip-content="{{property.schema.property.type}}">{{property.schema.property.type}} </span>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </perfect-scrollbar>
+ </div>
+ </div>
+ </div>
+
+ <div class="inputs-button-container pull-left">
+ <div ng-click="onArrowPressed()" class="right-arrow-btn" data-tests-id="add-inputs-to-service-button"></div>
+ </div>
+
+ <div class="table-container-flex">
+ <div class="w-sdc-inputs-search pull-left">
+ <input type="text" class="w-sdc-inputs-search-input" data-ng-model="search.filterTerm" placeholder="Search" data-ng-model-options="{debounce: 200}"/>
+ <div class="search-icon-container">
+ <span class="w-sdc-search-icon inputs-search-icon magnification-white"></span>
+ </div>
+ </div>
+ <div class="table">
+ <div class="body">
+ <div class="table-header">Service Inputs</div>
+ <perfect-scrollbar scroll-y-margin-offset="0" include-padding="true" class="scrollbar-container">
+ <expand-collapse expanded-selector=".service-inputs.{{$index}}"
+ class="expand-collapse-table-row"
+ load-data-function="loadInputInputs(serviceInput)"
+ is-close-on-init="true"
+ data-ng-repeat-start="serviceInput in component.inputs | filter:search track by $index ">
+ <div class="input-row service-input-row " data-tests-id="service-input-{{$index}}" ng-class="serviceInput.isNew ? 'new-input': ''">
+ <div class="title-text">{{serviceInput.name}}</div>
+ <div class="flex-container">
+ <div class="expand-collapse-inputs-table-icon"></div>
+ <div class="flex-item">
+ <div>
+ <span class="title-text">Description:</span>
+ <span tooltips tooltip-content="{{serviceInput.description}}">{{serviceInput.description}}</span>
+ </div>
+ </div>
+ <div class="flex-item ">
+ <div class="text">
+ <span class="title-text">VF Instance:</span>
+ <span tooltips tooltip-content="{{serviceInput.name}}">{{serviceInput.name}}</span>
+ </div>
+ <div class="text">
+ <span class="title-text">Type:</span>
+ <span tooltips tooltip-content="{{serviceInput.type}}">{{serviceInput.type}} </span>
+ </div>
+ </div>
+ <div class="delete">
+ <span class="sprite-new delete-icon remove-input-icon"
+ data-ng-class="{'disabled': isViewMode()}"
+ data-ng-click="deleteInput(serviceInput); $event.stopPropagation();"
+ data-tests-id="delete-input-{{$index}}"></span>
+ </div>
+ </div>
+ </div>
+ </expand-collapse>
+
+ <div data-ng-repeat-end="" class="service-inputs {{$index}}">
+ <expand-collapse expanded-selector=".input-inputs-list.{{$parent.$index}}-{{$index}}"
+ class="expand-collapse-table-row"
+ load-data-function="loadInputPropertiesForInstance(input.componentInstanceId, input)"
+ is-close-on-init="true"
+ data-ng-repeat-start="input in serviceInput.inputs track by $index">
+ <div class="input-row">
+ <div class="title-text">{{input.name}}</div>
+ <div class="flex-container">
+ <div class="expand-collapse-inputs-table-icon"></div>
+ <div class="flex-item">
+ <div>
+ <span class="title-text">Description:</span>
+ <span tooltips tooltip-content="{{input.description}}">{{input.description}}</span>
+ </div>
+ </div>
+ <div class="flex-item ">
+ <div class="text">
+ <span class="title-text">VF Instance:</span>
+ <span tooltips tooltip-content="{{instance.componentInstanceName}}">{{instance.componentInstanceName}}</span>
+ </div>
+ <div class="text">
+ <span class="title-text">Type:</span>
+ <span tooltips tooltip-content="{{input.type}}">{{input.type}} </span>
+ </div>
+ </div>
+ </div>
+ </div>
+ </expand-collapse>
+
+ <div data-ng-repeat-end="" class="input-inputs-list {{$parent.$index}}-{{$index}}">
+ <div class="empty-row" ng-if="input.properties.length===0">No properties to display</div>
+ <div ng-repeat="property in input.properties track by $index">
+ <div class="property-row flex-container">
+ <div class="flex-item text property-name-container">
+ <span
+ class="title-blue-text property-name-text" tooltips tooltips-content="{{property.name}}">{{property.name}}</span>
+ <span class="text instance-name-text" tooltips tooltips-content="{{property.name}}">{{property.name}}</span>
+ </div>
+ <div class="type-schema-container">
+ <div class="text">
+ <span tooltips tooltips-content="{{property.type}}">{{property.type}}</span>
+ </div>
+ </div>
+ <div class="type-schema-container">
+ <div class="text">
+ <span tooltips tooltips-content="{{property.schema.property.type}}">{{property.schema.property.type}} </span>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </perfect-scrollbar>
+ </div>
+ </div>
+ </div>
+</div>
diff --git a/catalog-ui/app/scripts/view-models/workspace/tabs/inputs/service-input/service-inputs.less b/catalog-ui/app/scripts/view-models/workspace/tabs/inputs/service-input/service-inputs.less
new file mode 100644
index 0000000000..11e613b56e
--- /dev/null
+++ b/catalog-ui/app/scripts/view-models/workspace/tabs/inputs/service-input/service-inputs.less
@@ -0,0 +1,54 @@
+.workspace-inputs {
+
+ .service-inputs-view {
+
+ .table-container-flex {
+ width:100% !important;
+ }
+
+ .table-loader {
+ position: relative;
+ top:215px;
+ }
+
+ }
+
+ .infinite-scroll {
+
+ overflow-y: scroll;
+ overflow-x: hidden;
+ max-height: 400px;
+ }
+
+ .class_with_css_props_leading_to_a_scroll {
+ height: 100%;
+ overflow-y: auto;
+ }
+
+ .table-container-flex {
+ .expand-collapse-table-row {
+ .service-input-row {
+ padding-left: 15px;
+ border: none;
+ border-bottom: rgba(120, 136, 148, 0.26) solid 1px;
+
+ .delete {
+ width: 50px;
+ padding: 0;
+ position: relative;
+ }
+
+ .remove-input-icon {
+ position: absolute;
+ top: 12px;
+ right: 18px;
+ }
+
+ .remove-input-icon:hover {
+ .delete-icon-hover;
+ }
+ }
+ }
+ }
+
+}