diff options
Diffstat (limited to 'catalog-ui/app/scripts/view-models/forms/artifact-form')
3 files changed, 567 insertions, 0 deletions
diff --git a/catalog-ui/app/scripts/view-models/forms/artifact-form/artifact-form-view-model.ts b/catalog-ui/app/scripts/view-models/forms/artifact-form/artifact-form-view-model.ts new file mode 100644 index 0000000000..092594b0d5 --- /dev/null +++ b/catalog-ui/app/scripts/view-models/forms/artifact-form/artifact-form-view-model.ts @@ -0,0 +1,354 @@ +/*- + * ============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 Resource = Sdc.Models.Components.Resource; + + export interface IEditArtifactModel { + artifactResource: Models.ArtifactModel; + artifactTypes: Array<string>; + artifactFile: any; + } + + export interface IArtifactResourceFormViewModelScope extends ng.IScope { + forms:any; + $$childTail: any; + isNew: boolean; + isLoading: boolean; + validationPattern: RegExp; + urlValidationPattern: RegExp; + labelValidationPattern: RegExp; + integerValidationPattern: RegExp; + commentValidationPattern: RegExp; + artifactType: string; + editArtifactResourceModel: IEditArtifactModel; + defaultHeatTimeout: number; + validExtensions: any; + originalArtifactName: string; + editForm: ng.IFormController; + footerButtons: Array<any>; + modalInstanceArtifact:ng.ui.bootstrap.IModalServiceInstance; + + fileExtensions():string; + save(doNotCloseModal?:boolean): void; + saveAndAnother(): void; + close(): void; + getOptions(): Array<string>; + isDeploymentHeat(): boolean; + onFileChange(): void; + setDefaultTimeout(): void; + openEditEnvParametersModal(artifact:Models.ArtifactModel):void; + getFormTitle():string; + fileUploadRequired():string; + isArtifactOwner():boolean; + } + + export class ArtifactResourceFormViewModel { + + private artifactArr:Array<Models.ArtifactModel>; + + static '$inject' = [ + '$scope', + '$modalInstance', + 'artifact', + 'Sdc.Services.CacheService', + 'ValidationPattern', + 'UrlValidationPattern', + 'LabelValidationPattern', + 'IntegerValidationPattern', + 'CommentValidationPattern', + 'ValidationUtils', + '$base64', + '$state', + 'ArtifactsUtils', + '$modal', + '$templateCache', + 'component' + ]; + + private formState:Utils.Constants.FormState; + private entityId:string; + + constructor(private $scope:IArtifactResourceFormViewModelScope, + private $modalInstance:ng.ui.bootstrap.IModalServiceInstance, + private artifact:Models.ArtifactModel, + private cacheService:Services.CacheService, + private ValidationPattern:RegExp, + private UrlValidationPattern:RegExp, + private LabelValidationPattern:RegExp, + private IntegerValidationPattern : RegExp, + private CommentValidationPattern: RegExp, + private ValidationUtils: Sdc.Utils.ValidationUtils, + private $base64:any, + private $state:any, + private artifactsUtils:Sdc.Utils.ArtifactsUtils, + private $modal:ng.ui.bootstrap.IModalService, + private $templateCache:ng.ITemplateCacheService, + private component:Models.Components.Component) { + + + this.entityId = this.component.uniqueId; + this.artifactArr = []; + this.formState = angular.isDefined(artifact.artifactLabel) ? Utils.Constants.FormState.UPDATE : Utils.Constants.FormState.CREATE; + this.initScope(); + } + + private initEntity = ():void => { + this.$scope.editArtifactResourceModel.artifactResource = this.artifact; + this.$scope.originalArtifactName = this.artifact.artifactName; + }; + + + private initFooterButtons = ():void =>{ + + this.$scope.footerButtons = [ + {'name': 'Done', 'css': 'blue', 'callback': this.$scope.save} + ]; + if (this.$scope.isNew){ + this.$scope.footerButtons.push( {'name': 'Add Another', 'css': 'grey', 'disabled': !this.$scope.isNew && 'deployment' === this.$scope.artifactType, 'callback': this.$scope.saveAndAnother}); + } + + }; + + + private initArtifactTypes = ():void => { + + let artifactTypes:any = this.cacheService.get('UIConfiguration'); + + if('deployment' === this.$scope.artifactType) { + + this.$scope.validExtensions = ('HEAT_ENV' == this.artifact.artifactType||this.component.selectedInstance)?//to remove the first condition? + artifactTypes.artifacts.deployment.resourceInstanceDeploymentArtifacts + : this.component.isResource() ? artifactTypes.artifacts.deployment.resourceDeploymentArtifacts + : artifactTypes.artifacts.deployment.serviceDeploymentArtifacts; + + if(this.$scope.validExtensions) { + this.$scope.editArtifactResourceModel.artifactTypes = Object.keys(this.$scope.validExtensions); + } + this.$scope.defaultHeatTimeout = artifactTypes.defaultHeatTimeout; + if(this.$scope.isNew) { + let isHeat='HEAT_ENV' == this.artifact.artifactType; + _.remove(this.$scope.editArtifactResourceModel.artifactTypes, (item:string)=> { + return 'HEAT' == item.substring(0,4)||(!isHeat && item == "VF_MODULES_METADATA") || + _.has(Utils.Constants.ArtifactType.THIRD_PARTY_RESERVED_TYPES, item); + }); + } + + }if (this.$scope.artifactType === 'normal') { + this.$scope.editArtifactResourceModel.artifactTypes = artifactTypes.artifacts.other.map((element:any)=> { + return element.name; + }); + _.remove(this.$scope.editArtifactResourceModel.artifactTypes, (item:string)=> { + return _.has(Utils.Constants.ArtifactType.THIRD_PARTY_RESERVED_TYPES, item) || + _.has(Utils.Constants.ArtifactType.TOSCA, item); + }) + } + + if(this.component.isResource() && (<Resource>this.component).isCsarComponent()) { + _.remove(this.$scope.editArtifactResourceModel.artifactTypes, (item:string) => { + return this.artifactsUtils.isLicenseType(item); + }) + } + + }; + + private initEditArtifactResourceModel = ():void => { + this.$scope.editArtifactResourceModel = { + artifactResource: null, + artifactTypes: null, + artifactFile:{} + }; + + this.initEntity(); + }; + + private initScope = ():void => { + + this.$scope.validationPattern = this.ValidationPattern; + this.$scope.urlValidationPattern = this.UrlValidationPattern; + this.$scope.labelValidationPattern = this.LabelValidationPattern; + this.$scope.integerValidationPattern = this.IntegerValidationPattern; + this.$scope.commentValidationPattern = this.CommentValidationPattern; + this.$scope.isLoading = false; + this.$scope.isNew = (this.formState === Utils.Constants.FormState.CREATE); + this.$scope.artifactType = this.artifactsUtils.getArtifactTypeByState(this.$state.current.name); + this.$scope.modalInstanceArtifact = this.$modalInstance; + + this.initEditArtifactResourceModel(); + this.initArtifactTypes(); + + // In case of edit, show the file name in browse. + if (this.artifact.artifactName!=="" && 'HEAT_ENV'!==this.artifact.artifactType){ + this.$scope.editArtifactResourceModel.artifactFile = {}; + this.$scope.editArtifactResourceModel.artifactFile.filename = this.artifact.artifactName; + } + + //scope methods + this.$scope.isDeploymentHeat = ():boolean => { + return !this.$scope.isNew && this.$scope.artifactType === 'deployment' && + 'HEAT' === this.$scope.editArtifactResourceModel.artifactResource.artifactType.substring(0,4); + }; + this.$scope.onFileChange = ():void => { + if(this.$scope.editArtifactResourceModel.artifactFile && this.$scope.editArtifactResourceModel.artifactFile.filename) { + this.$scope.editArtifactResourceModel.artifactResource.artifactName = this.$scope.editArtifactResourceModel.artifactFile.filename; + } else { + this.$scope.editArtifactResourceModel.artifactResource.artifactName = this.$scope.originalArtifactName; + } + }; + this.$scope.setDefaultTimeout = ():void => { + if(this.$scope.isDeploymentHeat() && !this.$scope.editArtifactResourceModel.artifactResource.timeout) { + this.$scope.editArtifactResourceModel.artifactResource.timeout = this.$scope.defaultHeatTimeout; + } + }; + + this.$scope.fileExtensions = ():string => { + let type:string = this.$scope.editArtifactResourceModel.artifactResource.artifactType; + return type && this.$scope.validExtensions && this.$scope.validExtensions[type].acceptedTypes ? + this.$scope.validExtensions[type].acceptedTypes.join(',') : ""; + }; + + this.$scope.save = (doNotCloseModal?:boolean):void => { + this.$scope.isLoading = true; + this.$scope.editArtifactResourceModel.artifactResource.description = this.ValidationUtils.stripAndSanitize(this.$scope.editArtifactResourceModel.artifactResource.description); + + if (!this.$scope.isDeploymentHeat()) { + this.$scope.editArtifactResourceModel.artifactResource.timeout = null; + } + + if (this.$scope.editArtifactResourceModel.artifactFile) { + this.$scope.editArtifactResourceModel.artifactResource.payloadData = this.$scope.editArtifactResourceModel.artifactFile.base64; + this.$scope.editArtifactResourceModel.artifactResource.artifactName = this.$scope.editArtifactResourceModel.artifactFile.filename; + } + + let onFaild = (response):void => { + this.$scope.isLoading = false; + console.info('onFaild', response); + }; + + let onSuccess = (artifactResource:Models.ArtifactModel):void => { + this.$scope.isLoading = false; + this.$scope.originalArtifactName = ""; + + if(this.$scope.isDeploymentHeat()){ + if(artifactResource.heatParameters) { + this.$scope.openEditEnvParametersModal(artifactResource); + } + } + + if (!doNotCloseModal) { + this.$modalInstance.close(); + //this.artifactArr = []; + } else { + this.$scope.editArtifactResourceModel.artifactFile = null; + angular.element("input[type='file']").val(null); // for support chrome when upload the same file + this.artifactsUtils.addAnotherAfterSave(this.$scope); + } + + }; + + if('HEAT_ENV' == this.artifact.artifactType){ + this.component.uploadInstanceEnvFile(this.$scope.editArtifactResourceModel.artifactResource).then(onSuccess, onFaild); + }else if(this.$scope.isArtifactOwner()){ + this.component.addOrUpdateInstanceArtifact(this.$scope.editArtifactResourceModel.artifactResource).then(onSuccess, onFaild); + }else { + this.component.addOrUpdateArtifact(this.$scope.editArtifactResourceModel.artifactResource).then(onSuccess, onFaild); + } + }; + + this.$scope.isArtifactOwner = ():boolean=> { + return this.component.isService() && !!this.component.selectedInstance; + }; + + this.$scope.saveAndAnother = ():void => { + this.$scope.save(true); + }; + + this.$scope.close = ():void => { + this.$modalInstance.close(); + this.artifactArr = []; + }; + + this.$scope.fileUploadRequired = ():string => { + if (this.$scope.editArtifactResourceModel.artifactFile.filename){ + // This is edit mode + return 'false'; + } else { + return 'true'; + } + }; + + this.$scope.getFormTitle =(): string =>{ + if('HEAT_ENV' == this.artifact.artifactType){ + return 'Update HEAT ENV'; + } + if(this.$scope.isDeploymentHeat()){ + if(!this.$scope.editArtifactResourceModel.artifactResource.artifactChecksum){ + return 'Add HEAT Template'; + } + return 'Update HEAT Template'; + } + if(this.$scope.isNew){ + return 'Add Artifact'; + } + return 'Update Artifact'; + }; + + this.$scope.openEditEnvParametersModal = (artifactResource:Models.ArtifactModel):void => { + + let modalOptions:ng.ui.bootstrap.IModalSettings = { + template: this.$templateCache.get('/app/scripts/view-models/forms/env-parameters-form/env-parameters-form.html'), + controller: 'Sdc.ViewModels.EnvParametersFormViewModel', + size: 'sdc-md', + backdrop: 'static', + resolve: { + artifact: ():Models.ArtifactModel => { + return artifactResource; + }, + component: ():Models.Components.Component => { + return this.component; + } + } + }; + + let modalInstance:ng.ui.bootstrap.IModalServiceInstance = this.$modal.open(modalOptions); + modalInstance + .result + .then(():void => { + }); + }; + + this.$scope.forms = {}; + + this.initFooterButtons(); + + + this.$scope.$watch("forms.editForm.$invalid", (newVal, oldVal) => { + this.$scope.footerButtons[0].disabled = this.$scope.forms.editForm.$invalid; + if(this.$scope.isNew){ + this.$scope.footerButtons[1].disabled = this.$scope.forms.editForm.$invalid; + } + }); + + } + + } +} diff --git a/catalog-ui/app/scripts/view-models/forms/artifact-form/artifact-form-view.html b/catalog-ui/app/scripts/view-models/forms/artifact-form/artifact-form-view.html new file mode 100644 index 0000000000..74a19c8776 --- /dev/null +++ b/catalog-ui/app/scripts/view-models/forms/artifact-form/artifact-form-view.html @@ -0,0 +1,169 @@ +<sdc-modal modal="modalInstanceArtifact" type="classic" class="sdc-add-artifact" buttons="footerButtons" header="{{getFormTitle()}}" show-close-button="true" get-close-modal-response="close"> + + <loader data-display="isLoading"></loader> + + <div class="sdc-edit-artifact-form-container" + data-ng-class="{'mandatory-artifact': (editArtifactResourceModel.artifactResource.mandatory && artifactType !=='deployment') || artifactType === 'api'}"> + <form novalidate class="w-sdc-form" name="forms.editForm"> + + <!--------------------- ARTIFACT FILE START--------------------> + <div class="i-sdc-form-item"> + <label class="required">Upload File</label> + <file-upload id="fileUploadElement" + form-element="forms.editForm" + element-required="{{::fileUploadRequired()}}" + element-name="myArtifactFile" + file-model="editArtifactResourceModel.artifactFile" + extensions="{{fileExtensions()}}" + element-disabled="{{!editArtifactResourceModel.artifactResource.artifactType}}" + data-ng-class="{'error': forms.editForm.myArtifactFile.$dirty && forms.editForm.myArtifactFile.$invalid}"></file-upload> + + <div class="input-error-file-upload" data-ng-show="forms.editForm.myArtifactFile.$dirty && forms.editForm.myArtifactFile.$invalid"> + <span ng-show="forms.editForm.myArtifactFile.$error.required && !forms.editForm.myArtifactFile.$error.emptyFile" translate="ADD_ARTIFACT_ERROR_FILE_REQUIRED"></span> + <span ng-show="forms.editForm.myArtifactFile.$error.maxsize" translate="VALIDATION_ERROR_MAX_FILE_SIZE"></span> + <span ng-if="artifactType === 'deployment'" ng-show="forms.editForm.myArtifactFile.$error.filetype" translate="ADD_ARTIFACT_ERROR_VALID_EXTENSIONS" translate-values="{'extensions': '{{fileExtensions()}}' }"></span> + <span ng-show="forms.editForm.myArtifactFile.$error.emptyFile" translate="VALIDATION_ERROR_EMPTY_FILE"></span> + </div> + </div> + <!--------------------- ARTIFACT FILE END --------------------> + + <div class="w-sdc-form-columns-wrapper"> + + <div class="w-sdc-form-column" data-ng-if="artifactType === 'deployment' || (!editArtifactResourceModel.artifactResource.mandatory && artifactType !== 'api')"> + + <div class="i-sdc-form-item" + data-ng-class="{error:(forms.editForm.artifactLabel.$dirty && forms.editForm.artifactLabel.$invalid)}" + data-ng-if="!isDeploymentHeat()"> + <label class="i-sdc-form-label required">Artifact Label</label> + <input class="i-sdc-form-input" + data-ng-maxlength="25" + data-ng-model="editArtifactResourceModel.artifactResource.artifactLabel" + type="text" + name="artifactLabel" + data-required + data-ng-model-options="{ debounce: 200 }" + data-ng-pattern="labelValidationPattern" + maxlength="25" + data-ng-disabled="!isNew" + data-tests-id="artifact-label" + autofocus/> + + <div class="input-error" data-ng-show="forms.editForm.artifactLabel.$dirty && forms.editForm.artifactLabel.$invalid"> + <span ng-show="forms.editForm.artifactLabel.$error.required" translate="ADD_ARTIFACT_ERROR_LABEL_REQUIRED"></span> + <span ng-show="forms.editForm.artifactLabel.$error.maxlength" translate="VALIDATION_ERROR_MAX_LENGTH" translate-values="{'max': '25' }"></span> + <span ng-show="forms.editForm.artifactLabel.$error.pattern" translate="VALIDATION_ERROR_SPECIAL_CHARS_NOT_ALLOWED"></span> + </div> + + </div> + + <div class="i-sdc-form-item" data-ng-class="{error:(forms.editForm.type.$dirty && forms.editForm.type.$invalid)}"> + <label class="i-sdc-form-label required">Type</label> + <select class="i-sdc-form-select" + data-required + name="type" + data-ng-disabled="!isNew" + data-ng-change="setDefaultTimeout()" + data-ng-model="editArtifactResourceModel.artifactResource.artifactType" + data-ng-options="type as type for type in editArtifactResourceModel.artifactTypes track by type | uppercase" + data-tests-id="artifacttype"> + <option value="">Choose Type</option> + </select> + + <div class="input-error" data-ng-show="forms.editForm.type.$dirty && forms.editForm.type.$invalid"> + <span ng-show="forms.editForm.type.$error.required" translate="ADD_ARTIFACT_ERROR_TYPE_REQUIRED"></span> + </div> + + </div> + + <div class="i-sdc-form-item" data-ng-class="{error:(forms.editForm.timeout.$dirty && forms.editForm.timeout.$invalid)}" data-ng-if="isDeploymentHeat()"> + <label class="i-sdc-form-label">Deployment Timeout (minutes)</label> + <input class="i-sdc-form-input" + data-ng-maxlength="25" + data-ng-model="editArtifactResourceModel.artifactResource.timeout" + type="number" + name="timeout" + min="1" + max="2147483647" + data-ng-disabled="'HEAT_ENV'==editArtifactResourceModel.artifactResource.artifactType" + data-ng-model-options="{ debounce: 200 }" + data-ng-pattern="integerValidationPattern" + data-ng-init="setDefaultTimeout()" + data-ng-change="setDefaultTimeout()" + maxlength="25" + data-tests-id="timeout" /> + + <div class="input-error" data-ng-show="forms.editForm.timeout.$dirty && forms.editForm.timeout.$invalid"> + <span ng-show="forms.editForm.timeout.$error.maxlength" translate="VALIDATION_ERROR_MAX_LENGTH" translate-values="{'max': '25' }"></span> + <span ng-show="forms.editForm.timeout.$error.pattern" translate="ADD_ARTIFACT_ERROR_TIMEOUT_PATTERN"></span> + <span ng-show="forms.editForm.timeout.$error.min" translate="ADD_ARTIFACT_ERROR_TIMEOUT_MIN"></span> + </div> + + </div> + + </div><!-- w-sdc-form-column --> + + <div class="w-sdc-form-column i-sdc-form-url" data-ng-if="artifactType==='api'"> + + <div class="i-sdc-form-item" + data-ng-class="{error:(forms.editForm.apiUrl.$dirty && forms.editForm.apiUrl.$invalid)}"> + <label class="i-sdc-form-label required">URL</label> + <input class="i-sdc-form-input" + data-ng-maxlength="100" + data-ng-model="editArtifactResourceModel.artifactResource.apiUrl" + data-ng-model-options="{ debounce: 200 }" + type="url" + name="apiUrl" + data-required + ng-pattern="urlValidationPattern" + maxlength="100" + autofocus + invalid-characters=',#?&@$<>~^`\[]{}|")(*!+=;%' /> + + <div class="input-error" data-ng-show="forms.editForm.apiUrl.$dirty && forms.editForm.apiUrl.$invalid"> + <span ng-show="forms.editForm.apiUrl.$error.required" translate="ADD_ARTIFACT_ERROR_APIURL_REQUIRED"></span> + <span ng-show="forms.editForm.apiUrl.$error.maxlength" translate="VALIDATION_ERROR_MAX_LENGTH" translate-values="{'max': '100' }"></span> + <span ng-show="forms.editForm.apiUrl.$error.url || forms.editForm.apiUrl.$error.pattern || forms.editForm.apiUrl.$error.invalidCharacters" translate="ADD_ARTIFACT_ERROR_APIURL_URL"></span> + </div> + + </div> + + </div><!-- w-sdc-form-column --> + + <div class="w-sdc-form-column"> + + <div class="i-sdc-form-item" + data-ng-class="{error:(forms.editForm.description.$dirty && forms.editForm.description.$invalid)}"> + <label class="i-sdc-form-label required">Description</label> + <textarea class="i-sdc-form-textarea" + data-ng-maxlength="256" + maxlength="256" + data-required + name="description" + data-ng-model="editArtifactResourceModel.artifactResource.description" + data-ng-model-options="{ debounce: 200 }" + data-ng-pattern="commentValidationPattern" + data-tests-id="description"></textarea> + + <div class="input-error" data-ng-show="forms.editForm.description.$dirty && forms.editForm.description.$invalid"> + <span ng-show="forms.editForm.description.$error.required" translate="ADD_ARTIFACT_ERROR_DESCRIPTION_REQUIRED"></span> + <span ng-show="forms.editForm.description.$error.maxlength" translate="VALIDATION_ERROR_MAX_LENGTH" translate-values="{'max': '256' }"></span> + <span ng-show="forms.editForm.description.$error.pattern" translate="ADD_ARTIFACT_ERROR_DESCRIPTION_PATTERN"></span> + </div> + + <div class="w-sdc-form-column artifact-info" data-ng-show="!isNew && editArtifactResourceModel.artifactResource.esId"> + UUID <span data-ng-bind="editArtifactResourceModel.artifactResource.artifactUUID"></span> + <br /> + Version <span data-ng-bind="editArtifactResourceModel.artifactResource.artifactVersion"></span> + </div> + </div> + + </div><!-- w-sdc-form-column --> + + </div><!-- w-sdc-form-columns-wrapper --> + + <span class="w-sdc-form-note" data-ng-show="forms.editForm.$invalid && false" translate="LABEL_ALL_FIELDS_ARE_MANDATORY"></span> + + </form> + </div> +</sdc-modal> + diff --git a/catalog-ui/app/scripts/view-models/forms/artifact-form/artifact-form.less b/catalog-ui/app/scripts/view-models/forms/artifact-form/artifact-form.less new file mode 100644 index 0000000000..1f77958c88 --- /dev/null +++ b/catalog-ui/app/scripts/view-models/forms/artifact-form/artifact-form.less @@ -0,0 +1,44 @@ +.sdc-edit-artifact-form-container { + + .w-sdc-form-note { + .h_9; + display: block; + position: relative; + top: 13px; + } + + .i-sdc-form-textarea{ + min-height: 95px; + } + + .i-sdc-form-url { + padding-bottom: 0px; + } + + &.mandatory-artifact { + .w-sdc-form-column { + width: 100%; + padding: 0; + min-height: initial; + } + } + .w-sdc-form .i-sdc-form-item.upload input[type="file"] { + display: none + } + + .artifact-info { + text-align: left; + color: rgb(140, 140, 140); + font-size: 13px; + margin-top: -10px; + margin-bottom: 5px; + width: 100%; + min-height: initial; + + span { + color: #666666; + padding-left: 4px; + } + } + +} |