summaryrefslogtreecommitdiffstats
path: root/catalog-ui/app/scripts/view-models/wizard/artifact-deployment-step
diff options
context:
space:
mode:
Diffstat (limited to 'catalog-ui/app/scripts/view-models/wizard/artifact-deployment-step')
-rw-r--r--catalog-ui/app/scripts/view-models/wizard/artifact-deployment-step/artifact-deployment-step.html137
-rw-r--r--catalog-ui/app/scripts/view-models/wizard/artifact-deployment-step/artifact-deployment-step.less107
-rw-r--r--catalog-ui/app/scripts/view-models/wizard/artifact-deployment-step/artifact-deployment-step.ts228
3 files changed, 472 insertions, 0 deletions
diff --git a/catalog-ui/app/scripts/view-models/wizard/artifact-deployment-step/artifact-deployment-step.html b/catalog-ui/app/scripts/view-models/wizard/artifact-deployment-step/artifact-deployment-step.html
new file mode 100644
index 0000000000..97817d59f2
--- /dev/null
+++ b/catalog-ui/app/scripts/view-models/wizard/artifact-deployment-step/artifact-deployment-step.html
@@ -0,0 +1,137 @@
+<div class="artifact-deployment-step" data-ng-controller="Sdc.ViewModels.Wizard.ArtifactDeploymentStepViewModel">
+
+ <div data-tests-id="add-deployment-artifact-button" data-tests-id="addGrey" class="w-sdc-classic-btn gray" data-ng-click="addOrUpdate({})">Add</div>
+
+ <div class="table-container-flex">
+
+ <div class="table">
+
+ <div class="head flex-container">
+ <div class="table-header head-row hand flex-item" data-ng-repeat="header in tableHeadersList track by $index" data-ng-click="sort(header.property)">{{header.title}}
+ <span data-ng-if="sortBy === header.property" class="table-header-sort-arrow" data-ng-class="{'down': reverse, 'up':!reverse}"> </span>
+ </div>
+ <div class="table-no-text-header head-row flex-item"></div>
+ </div>
+
+ <form class="body" name="editForm">
+
+ <perfect-scrollbar scroll-y-margin-offset="0" include-padding="true" class="scrollbar-container">
+
+ <!-- Artifact row -->
+ <div ng-if="noArtifactsToShow()" class="no-row-text" translate="DEPLOYMENT_ARTIFACT_NO_ARTIFACTS_TO_DISPLAY"></div>
+ <div data-ng-repeat-start="artifact in artifacts | orderBy:sortBy:reverse track by $index"
+ class="flex-container data-row"
+ data-ng-class="{'selected': artifact.selected || undefined==artifact.selected && updateInProgress}"
+ data-ng-if="artifact.esId">
+
+ <div class="table-col-general flex-item" data-ng-click="update(artifact)">
+ <loader data-display="isLoading"></loader>
+ <span class="sprite table-arrow" data-tests-id="{{artifact.artifactDisplayName}}" data-ng-class="{'opened': artifact.selected || undefined==artifact.selected && updateInProgress}"></span>
+ {{artifact.artifactDisplayName}}
+ </div>
+
+ <div class="table-col-general flex-item" data-tests-id="{{artifact.artifactType}}">
+ {{artifact.artifactType}}
+ </div>
+ <div class="table-col-general flex-item" data-tests-id="{{artifact.timeout}}">
+ {{artifact.timeout? artifact.timeout:''}}
+ </div>
+
+ <div class="table-btn-col flex-item" sdc-keyboard-events>
+ <button class="table-edit-btn" data-ng-click="addOrUpdate(artifact)"></button>
+ <button class="table-delete-btn" data-ng-click="delete(artifact)"> </button>
+ </div>
+ </div>
+ <div data-ng-repeat-end="" data-ng-if="artifact.selected || undefined==artifact.selected && updateInProgress" class="w-sdc-form item-opened">
+ <!-- Artifact panel opened -->
+
+ <!-- Description field -->
+ <div class="w-sdc-form-item" ng-form="descriptionForm" data-ng-class="{error:(descriptionForm.$dirty && descriptionForm.$invalid)}">
+ <label class="i-sdc-env-form-label required">Description</label>
+ <textarea class="i-sdc-form-textarea {{$index}}"
+ data-ng-maxlength="256"
+ maxlength="256"
+ data-ng-required="true"
+ name="description"
+ data-ng-model="artifact.description"
+ data-ng-model-options="{ debounce: 200 }"
+ data-ng-pattern="getValidationPattern('string')"
+ data-tests-id="description">
+ </textarea>
+
+ <div class="input-error" data-ng-show="descriptionForm.$dirty && descriptionForm.$invalid">
+ <span ng-show="descriptionForm.$error.required" translate="ADD_ARTIFACT_ERROR_DESCRIPTION_REQUIRED"></span>
+ <span ng-show="descriptionForm.$error.maxlength" translate="VALIDATION_ERROR_MAX_LENGTH" translate-values="{'max': '256' }"></span>
+ <span ng-show="descriptionForm.$error.pattern" translate="VALIDATION_ERROR_SPECIAL_CHARS_NOT_ALLOWED"></span>
+ </div>
+
+ </div>
+
+ <!-- Parameters in 2 columns -->
+ <div class="w-sdc-form-columns-wrapper" data-ng-if="artifact.heatParameters">
+ <!-- Left column -->
+ <div class="w-sdc-form-column">
+ <div class="i-sdc-form-item" ng-form="parameterForm" data-ng-repeat="parameter in artifact.heatParameters.slice(0, artifact.heatParameters.length%2+artifact.heatParameters.length/2) | orderBy: 'name' track by $index">
+ <label class="i-sdc-env-form-label" data-ng-class="{required:parameter.defaultValue}" tooltip-side="top" sdc-smart-tooltip>{{parameter.name +' (' + parameter.type + ')'}}</label>
+ <span class="parameter-description" tooltips tooltip-side="top" tooltip-content="{{parameter.description}}">?</span>
+ <input class="i-sdc-form-input" data-ng-class="{error:(parameterForm.currentValue.$invalid)}"
+ data-ng-model-options="{ debounce: 200 }"
+ data-ng-model="parameter.currentValue"
+ type="text"
+ name="currentValue"
+ data-ng-pattern="getValidationPattern(parameter.type, 'heat')"
+ data-ng-required="parameter.defaultValue"
+ data-ng-change="'json'==parameter.type && parameterForm.currentValue.$setValidity('pattern', validateJson(parameter.currentValue))"
+ data-ng-blur="!parameterForm.currentValue.$error.pattern && resetValue(parameter)"
+ />
+
+ <div class="input-error" data-ng-show="parameterForm.currentValue.$invalid">
+ <span ng-show="parameterForm.currentValue.$error.required" translate="VALIDATION_ERROR_REQUIRED" translate-values="{'field': 'Value'}"></span>
+ <span ng-show="parameterForm.currentValue.$error.pattern && parameter.type==='string'" translate="VALIDATION_ERROR_SPECIAL_CHARS_NOT_ALLOWED"></span>
+ <span ng-show="parameterForm.currentValue.$error.pattern && !(parameter.type==='string')" translate="VALIDATION_ERROR_TYPE" translate-values="{'type': '{{parameter.type}}'}"></span>
+ </div>
+ </div>
+ </div>
+
+ <!-- Right column -->
+ <div class="w-sdc-form-column">
+ <div class="i-sdc-form-item" ng-form="parameterForm" data-ng-repeat="parameter in artifact.heatParameters.slice(artifact.heatParameters.length%2+artifact.heatParameters.length/2) | orderBy: 'name' track by $index">
+ <label class="i-sdc-env-form-label" data-ng-class="{required:parameter.defaultValue}" tooltip-side="top" sdc-smart-tooltip>{{parameter.name +' (' + parameter.type + ')'}}</label>
+ <span class="parameter-description" tooltips tooltip-side="top" tooltip-content="{{parameter.description}}">?</span>
+ <input class="i-sdc-form-input" data-ng-class="{error:(parameterForm.currentValue.$invalid)}"
+ data-ng-model-options="{ debounce: 200 }"
+ data-ng-model="parameter.currentValue"
+ type="text"
+ name="currentValue"
+ data-ng-pattern="getValidationPattern(parameter.type, 'heat')"
+ data-ng-required="parameter.defaultValue"
+ data-ng-change="'json'==parameter.type && parameterForm.currentValue.$setValidity('pattern', validateJson(parameter.currentValue))"
+ data-ng-blur="!parameterForm.currentValue.$error.pattern && resetValue(parameter)"
+ />
+
+ <div class="input-error" data-ng-show="parameterForm.currentValue.$invalid">
+ <span ng-show="parameterForm.currentValue.$error.required" translate="VALIDATION_ERROR_REQUIRED" translate-values="{'field': 'Value'}"></span>
+ <span ng-show="parameterForm.currentValue.$error.pattern && parameter.type==='string'" translate="VALIDATION_ERROR_SPECIAL_CHARS_NOT_ALLOWED"></span>
+ <span ng-show="parameterForm.currentValue.$error.pattern && !(parameter.type==='string')" translate="VALIDATION_ERROR_TYPE" translate-values="{'type': '{{parameter.type}}'}"></span>
+ </div>
+ </div>
+ </div>
+
+ </div><!-- Close: Parameters in 2 columns -->
+ </div><!-- Close: Artifact panel opened -->
+
+ <!-- Add artifacts buttons -->
+ <button class="add-button" data-ng-repeat="artifact in artifacts track by $index"
+ data-ng-show="!artifact.esId"
+ data-tests-id="{{artifact.artifactDisplayName}}"
+ translate="DEPLOYMENT_ARTIFACT_BUTTON_ADD_HEAT"
+ translate-values="{'name': '{{artifact.artifactDisplayName}}'}"
+ data-ng-click="addOrUpdate(artifact)"></button>
+
+ <!-- Top add button -->
+ <button class="add-button" translate="DEPLOYMENT_ARTIFACT_BUTTON_ADD_OTHER" data-ng-click="addOrUpdate({})"></button>
+ </perfect-scrollbar>
+ </form>
+ </div>
+ </div>
+</div>
diff --git a/catalog-ui/app/scripts/view-models/wizard/artifact-deployment-step/artifact-deployment-step.less b/catalog-ui/app/scripts/view-models/wizard/artifact-deployment-step/artifact-deployment-step.less
new file mode 100644
index 0000000000..043fba3277
--- /dev/null
+++ b/catalog-ui/app/scripts/view-models/wizard/artifact-deployment-step/artifact-deployment-step.less
@@ -0,0 +1,107 @@
+.artifact-deployment-step {
+
+ .table-container-flex .table .body .data-row + div.item-opened {
+ padding: 10px 40px 10px 30px;
+ }
+
+ .w-sdc-classic-btn {
+ float: right;
+ margin-bottom: 10px;
+ }
+
+ .table {
+ height:412px;
+ margin-bottom: 0;
+ }
+
+ .parameter-description {
+ .circle(18px, @color_p);
+ content: '?';
+ line-height: 18px;
+ vertical-align: middle;
+ margin-left: 5px;
+ cursor: default;
+ display: inline-block;
+ position: absolute;
+ top: 16px;
+ }
+
+ .table-container-flex {
+
+ margin-top: 0px;
+
+ .flex-item:nth-child(1) {
+ flex-grow: 15;
+ padding: 5px 4px;
+ .hand;
+ span.table-arrow {
+ margin-right: 7px;
+
+ }
+ }
+
+ .flex-item:nth-child(2) {
+ padding: 5px 4px;
+ flex-grow: 6;
+ }
+
+ .flex-item:nth-child(3) {
+ padding: 5px 4px;
+ flex-grow: 9;
+ }
+
+ .flex-item:nth-child(4) {
+ padding: 5px 4px;
+ flex-grow: 3;
+ padding-top: 10px;
+ }
+ }
+ .w-sdc-form{
+ text-align: left;
+
+ .w-sdc-env-params{
+ border-top: 1px solid #cdcdcd;
+ margin: 25px 0 10px 0;
+ }
+
+ .i-sdc-form-textarea {
+ border: 1px solid @color_e;
+ min-height: 60px;
+ padding: 10px 13px;
+ width: 100%;
+ resize: none;
+
+ &:disabled {
+ .disabled;
+ }
+ }
+
+ .w-sdc-form-item {
+ &.error {
+ .i-sdc-form-input,
+ .i-sdc-form-select,
+ .i-sdc-form-textarea {
+ border-color: @color_h;
+ outline: none;
+ box-sizing: border-box;
+ }
+ }
+ }
+
+ .i-sdc-env-form-label{
+ .p_9;
+ overflow: hidden;
+ max-width: 245px;
+ text-overflow: ellipsis;
+ display: inline-block;
+ white-space: nowrap;
+ margin-top: 14px;
+
+ &.required::before {
+ color: #f33;
+ content: '*';
+ margin-right: 4px;
+ }
+ }
+ }
+}
diff --git a/catalog-ui/app/scripts/view-models/wizard/artifact-deployment-step/artifact-deployment-step.ts b/catalog-ui/app/scripts/view-models/wizard/artifact-deployment-step/artifact-deployment-step.ts
new file mode 100644
index 0000000000..80f145b9b1
--- /dev/null
+++ b/catalog-ui/app/scripts/view-models/wizard/artifact-deployment-step/artifact-deployment-step.ts
@@ -0,0 +1,228 @@
+/*-
+ * ============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.Wizard {
+ 'use strict';
+ import ArtifactModel = Sdc.Models.ArtifactModel;
+
+ interface IArtifactDeploymentStepViewModelScope extends IWizardCreationStepScope {
+ tableHeadersList: Array<any>;
+ reverse: boolean;
+ sortBy:string;
+ component: Models.Components.Component;
+ artifacts: Array<Models.ArtifactModel>;
+ editForm:ng.IFormController;
+ isLoading:boolean;
+ artifactDescriptions:any;
+ updateInProgress:boolean;
+
+ addOrUpdate(artifact:Models.ArtifactModel): void;
+ update(artifact:Models.ArtifactModel): void;
+ delete(artifact:Models.ArtifactModel): void;
+ sort(sortBy:string): void;
+ noArtifactsToShow():boolean;
+ getValidationPattern(validationType:string, parameterType?:string):RegExp;
+ validateJson(json:string):boolean;
+ resetValue(parameter:any):void;
+ }
+
+ export class ArtifactDeploymentStepViewModel implements IWizardCreationStep {
+
+ static '$inject' = [
+ '$scope',
+ '$filter',
+ '$modal',
+ '$templateCache',
+ 'ValidationUtils',
+ 'ModalsHandler'
+ ];
+
+ constructor(
+ private $scope:IArtifactDeploymentStepViewModelScope,
+ private $filter:ng.IFilterService,
+ private $modal:ng.ui.bootstrap.IModalService,
+ private $templateCache:ng.ITemplateCacheService,
+ private validationUtils: Sdc.Utils.ValidationUtils,
+ private ModalsHandler: Utils.ModalsHandler
+ ){
+ this.$scope.registerChild(this);
+ this.$scope.setValidState(true);
+ this.initScope();
+ }
+
+ private initDescriptions = ():void =>{
+ this.$scope.artifactDescriptions = {};
+ _.forEach(this.$scope.component.deploymentArtifacts,(artifact:Models.ArtifactModel):void => {
+ this.$scope.artifactDescriptions[artifact.artifactLabel] = artifact.description;
+ });
+ };
+
+
+ private setArtifact = (artifact:Models.ArtifactModel):void =>{
+ if(artifact.heatParameters) {
+ artifact.heatParameters.forEach((parameter:any):void => {
+ if (!parameter.currentValue && parameter.defaultValue) {
+ parameter.currentValue = parameter.defaultValue;
+ } else if ("" === parameter.currentValue) {
+ parameter.currentValue = null;
+ }
+ });
+ }
+ if(!artifact.description || !this.$scope.getValidationPattern('string').test(artifact.description)){
+ artifact.description = this.$scope.artifactDescriptions[artifact.artifactLabel];
+ }
+ };
+
+ private updateAll = ():void =>{
+ let artifacts:Array<Models.ArtifactModel>= [];
+ _.forEach(this.$scope.component.deploymentArtifacts,(artifact:Models.ArtifactModel): void => {
+ if(artifact.selected) {
+ this.setArtifact(artifact);
+ artifacts.push(artifact);
+ }
+ });
+ this.$scope.component.updateMultipleArtifacts(artifacts);
+ };
+
+
+
+ private initScope = (): void => {
+ let self = this;
+ this.$scope.isLoading = false;
+ this.$scope.updateInProgress = false;
+ this.$scope.component = this.$scope.getComponent();
+ this.initDescriptions();
+ this.$scope.artifacts = <ArtifactModel[]>_.values(this.$scope.component.deploymentArtifacts);
+
+
+ this.$scope.tableHeadersList = [
+ {title:'Name', property: 'artifactDisplayName'},
+ {title:'Type', property: 'artifactType'},
+ {title:'Deployment timeout', property: 'timeout'}
+ ];
+
+ this.$scope.sort = (sortBy:string):void => {
+ this.$scope.reverse = (this.$scope.sortBy === sortBy) ? !this.$scope.reverse : false;
+ this.$scope.sortBy = sortBy;
+ };
+
+ this.$scope.getValidationPattern = (validationType:string, parameterType?:string):RegExp => {
+ return this.validationUtils.getValidationPattern(validationType, parameterType);
+ };
+
+ this.$scope.validateJson = (json:string):boolean => {
+ if(!json){
+ return true;
+ }
+ return this.validationUtils.validateJson(json);
+ };
+
+
+ this.$scope.addOrUpdate = (artifact:Models.ArtifactModel): void => {
+ artifact.artifactGroupType = 'DEPLOYMENT';
+ let artifactCopy = new Models.ArtifactModel(artifact);
+ this.ModalsHandler.openWizardArtifactModal(artifactCopy, this.$scope.component).then(() => {
+ this.$scope.artifactDescriptions[artifactCopy.artifactLabel]= artifactCopy.description;
+ this.$scope.artifacts = <ArtifactModel[]>_.values(this.$scope.component.deploymentArtifacts);
+ })
+ };
+
+ this.$scope.noArtifactsToShow = ():boolean =>{
+ return !_.some(this.$scope.artifacts, 'esId');
+ };
+
+ this.$scope.resetValue = (parameter:any):void => {
+ if(!parameter.currentValue && parameter.defaultValue){
+ parameter.currentValue = parameter.defaultValue;
+ }
+ else if('boolean'==parameter.type){
+ parameter.currentValue = parameter.currentValue.toUpperCase();
+ }
+ };
+
+
+ this.$scope.$watch('editForm.$valid', ():void => {
+ if(this.$scope.editForm) {
+ this.$scope.setValidState(this.$scope.editForm.$valid);
+ }
+ });
+
+ this.$scope.update = (artifact:Models.ArtifactModel):void =>{
+ if(false == this.$scope.isLoading) {
+ if(artifact.selected) {
+ this.$scope.isLoading = true;
+ this.$scope.updateInProgress = true;
+ let onSuccess = (responseArtifact:Models.ArtifactModel):void => {
+ this.$scope.artifactDescriptions[responseArtifact.artifactLabel] = responseArtifact.description;
+ this.$scope.artifacts = <ArtifactModel[]>_.values(this.$scope.component.deploymentArtifacts);
+ this.$scope.isLoading = false;
+ this.$scope.updateInProgress = false;
+ artifact.selected = !artifact.selected;
+ };
+
+ let onFailed = (error:any):void => {
+ console.log('Delete artifact returned error:', error);
+ this.$scope.isLoading = false;
+ this.$scope.updateInProgress = false;
+ artifact.selected = !artifact.selected;
+ };
+
+ this.setArtifact(artifact);
+ this.$scope.component.addOrUpdateArtifact(artifact).then(onSuccess, onFailed);
+ } else {
+ artifact.selected = !artifact.selected;
+ }
+ }
+ };
+
+ this.$scope.delete = (artifact:Models.ArtifactModel):void => {
+ let onOk = ():void => {
+ this.$scope.isLoading = true;
+ let onSuccess = ():void => {
+ this.$scope.isLoading = false;
+ this.$scope.artifacts = <ArtifactModel[]>_.values(this.$scope.component.deploymentArtifacts);
+ };
+
+ let onFailed = (error:any):void => {
+ this.$scope.isLoading = false;
+ console.log('Delete artifact returned error:', error);
+ };
+
+ this.$scope.component.deleteArtifact(artifact.uniqueId, artifact.artifactLabel).then(onSuccess, onFailed);
+ };
+
+ let title:string = self.$filter('translate')("ARTIFACT_VIEW_DELETE_MODAL_TITLE");
+ let message:string = self.$filter('translate')("ARTIFACT_VIEW_DELETE_MODAL_TEXT", "{'name': '" + artifact.artifactDisplayName + "'}");
+ this.ModalsHandler.openConfirmationModal(title, message, false).then(onOk);
+ };
+ };
+
+ public save = (callback:Function):void => {
+ this.updateAll();
+ this.$scope.setComponent(this.$scope.component);
+ callback(true);
+ };
+
+ public back = (callback:Function):void => {
+ this.$scope.setComponent(this.$scope.component);
+ callback(true);
+ }
+ }
+}