diff options
author | Michael Lando <ml636r@att.com> | 2017-02-19 10:28:42 +0200 |
---|---|---|
committer | Michael Lando <ml636r@att.com> | 2017-02-19 10:51:01 +0200 |
commit | 451a3400b76511393c62a444f588a4ed15f4a549 (patch) | |
tree | e4f5873a863d1d3e55618eab48b83262f874719d /catalog-ui/app/scripts/view-models/workspace/tabs/inputs | |
parent | 5abfe4e1fb5fae4bbd5fbc340519f52075aff3ff (diff) |
Initial OpenECOMP SDC commit
Change-Id: I0924d5a6ae9cdc161ae17c68d3689a30d10f407b
Signed-off-by: Michael Lando <ml636r@att.com>
Diffstat (limited to 'catalog-ui/app/scripts/view-models/workspace/tabs/inputs')
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; + } + } + } + } + +} |