summaryrefslogtreecommitdiffstats
path: root/catalog-ui/app/scripts/directives/property-types/type-map
diff options
context:
space:
mode:
Diffstat (limited to 'catalog-ui/app/scripts/directives/property-types/type-map')
-rw-r--r--catalog-ui/app/scripts/directives/property-types/type-map/type-map-directive.html70
-rw-r--r--catalog-ui/app/scripts/directives/property-types/type-map/type-map-directive.less83
-rw-r--r--catalog-ui/app/scripts/directives/property-types/type-map/type-map-directive.ts157
3 files changed, 310 insertions, 0 deletions
diff --git a/catalog-ui/app/scripts/directives/property-types/type-map/type-map-directive.html b/catalog-ui/app/scripts/directives/property-types/type-map/type-map-directive.html
new file mode 100644
index 0000000000..ed82b840dc
--- /dev/null
+++ b/catalog-ui/app/scripts/directives/property-types/type-map/type-map-directive.html
@@ -0,0 +1,70 @@
+<div>
+ <div data-ng-repeat="i in getNumber(mapKeys.length) track by $index" class="map-item" data-ng-class="{'primitive-value-map':!isSchemaTypeDataType}">
+ <div class="i-sdc-form-item map-item-field" data-ng-class="{error:(parentFormObj['mapKey'+fieldsPrefixName+$index].$dirty && parentFormObj['mapKey'+fieldsPrefixName+$index].$invalid)}">
+ <label class="i-sdc-form-label required">Key</label>
+ <input class="i-sdc-form-input"
+ data-tests-id="mapKey{{fieldsPrefixName}}{{$index}}"
+ data-ng-model="mapKeys[$index]"
+ type="text"
+ name="mapKey{{fieldsPrefixName}}{{$index}}"
+ data-ng-pattern="propertyNameValidationPattern"
+ data-ng-model-options="{ debounce: 200 }"
+ data-ng-change="changeKeyOfMap(mapKeys[$index], $index,'mapKey'+fieldsPrefixName+$index);$event.stopPropagation();"
+ data-ng-disabled="readOnly"
+ data-required
+ autofocus/>
+ <div class="input-error" data-ng-show="parentFormObj['mapKey'+fieldsPrefixName+$index].$dirty && parentFormObj['mapKey'+fieldsPrefixName+$index].$invalid">
+ <span ng-show="parentFormObj['mapKey'+fieldsPrefixName+$index].$error.keyExist" translate="PROPERTY_EDIT_MAP_UNIQUE_KEYS"></span>
+ <span ng-show="parentFormObj['mapKey'+fieldsPrefixName+$index].$error.required" translate="VALIDATION_ERROR_REQUIRED" translate-values="{'field': 'Key' }"></span>
+ </div>
+ </div>
+ <div data-ng-if="!isSchemaTypeDataType" class="i-sdc-form-item map-item-field" data-ng-class="{error:(parentFormObj['mapValue'+fieldsPrefixName+$index].$dirty && parentFormObj['mapValue'+fieldsPrefixName+$index].$invalid)}">
+ <label class="i-sdc-form-label required">Value</label>
+ <input class="i-sdc-form-input"
+ ng-if="!((schemaProperty.simpleType||schemaProperty.type) == 'boolean')"
+ data-ng-disabled="readOnly"
+ data-ng-model="valueObjRef[mapKeys[$index]]"
+ type="text"
+ name="mapValue{{fieldsPrefixName}}{{$index}}"
+ data-tests-id="mapValue{{fieldsPrefixName}}{{$index}}"
+ data-ng-pattern="getValidationPattern((schemaProperty.simpleType||schemaProperty.type))"
+ data-ng-change="!parentFormObj['mapValue'+fieldsPrefixName+$index].$error.pattern && parseToCorrectType(valueObjRef, key, (schemaProperty.simpleType||schemaProperty.type))"
+ data-ng-model-options="{ debounce: 200 }"
+ data-ng-maxlength="maxLength"
+ maxlength="{{maxLength}}"
+ data-required
+ autofocus />
+ <select class="i-sdc-form-select"
+ data-tests-id="mapValue{{fieldsPrefixName}}{{$index}}"
+ ng-if="(schemaProperty.simpleType||schemaProperty.type) == 'boolean'"
+ data-ng-disabled="readOnly"
+ name="mapValue{{fieldsPrefixName}}{{$index}}"
+ data-ng-model="valueObjRef[mapKeys[$index]]"
+ data-required>
+ <option value="true">true</option>
+ <option value="false">false</option>
+ </select>
+ <div class="input-error" data-ng-show="parentFormObj['mapValue'+fieldsPrefixName+$index].$dirty && parentFormObj['mapValue'+fieldsPrefixName+$index].$invalid">
+ <span ng-show="parentFormObj['mapValue'+fieldsPrefixName+$index].$error.required" translate="VALIDATION_ERROR_REQUIRED" translate-values="{'field': 'Value' }"></span>
+ <span ng-show="parentFormObj['mapValue'+fieldsPrefixName+$index].$error.pattern" translate="PROPERTY_EDIT_PATTERN"></span>
+ <span ng-show="parentFormObj['mapValue'+fieldsPrefixName+$index].$error.maxlength" translate="VALIDATION_ERROR_MAX_LENGTH" translate-values="{'max': '{{maxLength}}' }"></span>
+ </div>
+ </div>
+ <div data-ng-if="isSchemaTypeDataType" class="i-sdc-form-item map-item-field">
+ <label class="i-sdc-form-label">Value</label>
+ <fields-structure value-obj-ref="valueObjRef[mapKeys[$index]]"
+ type-name="schemaProperty.type"
+ parent-form-obj="parentFormObj"
+ fields-prefix-name="'mapValue'+fieldsPrefixName+''+$index"
+ read-only="readOnly"
+ types="types"
+ ></fields-structure>
+ </div>
+ <span ng-click="deleteMapItem($index)" class="delete-map-item" data-tests-id="delete-map-item{{fieldsPrefixName}}{{$index}}" data-ng-class="{'disabled': readOnly}"></span>
+ </div>
+ <div class="add-map-item" data-ng-class="{'schema-data-type':isSchemaTypeDataType}">
+ <div class="add-btn" data-tests-id="add-map-item"
+ data-ng-class="{'disabled': readOnly || !schemaProperty.type || mapKeys.indexOf('')>-1}" data-ng-click="addMapItemFields()">Add</div>
+ </div>
+</div>
+
diff --git a/catalog-ui/app/scripts/directives/property-types/type-map/type-map-directive.less b/catalog-ui/app/scripts/directives/property-types/type-map/type-map-directive.less
new file mode 100644
index 0000000000..2480b626f2
--- /dev/null
+++ b/catalog-ui/app/scripts/directives/property-types/type-map/type-map-directive.less
@@ -0,0 +1,83 @@
+.add-map-item{
+ &:nth-child(odd){
+ float: right;
+ }
+ &:nth-child(1){
+ float: none;
+ .add-btn{
+ float: none;
+ }
+ }
+ width: 400px;
+ .add-btn{
+ width: 44px;
+ float: right;
+ }
+ &.schema-data-type{
+ float:none;
+ .add-btn{
+ float: none;
+ }
+ }
+}
+
+.add-btn {
+ .f-color.a;
+ .f-type._14_m;
+ .hand;
+
+ &:before {
+ .sprite-new;
+ .plus-icon;
+ margin-right: 5px;
+ content: "";
+
+ }
+ &:hover {
+ .f-color.b;
+ &:before {
+ .sprite-new;
+ .plus-icon-hover;
+ }
+ }
+
+}
+
+.map-item{
+ min-width: 389px;
+ min-height: 65px;
+ background-color: @tlv_color_v;
+ border-radius: 3px;
+ margin-bottom: 8px;
+ float: left;
+ display: flex;
+ &:nth-child(even).primitive-value-map{
+ float: right;
+ }
+ .delete-map-item {
+ float: right;
+ position: relative;
+ top: 5px;
+ right: 5px;
+ .sprite-new;
+ .delete-icon;
+ &:hover{
+ .delete-icon-hover;
+ }
+ }
+ .map-item-field {
+ margin: 7px 12px !important;
+ float: left;
+ min-width: 170px;
+ min-height: 50px;
+ select{
+ width:171px;
+ }
+ input[type="text"]{
+ width: 170px;
+ }
+ &>.data-type-fields-structure{
+ padding: 0;
+ }
+ }
+}
diff --git a/catalog-ui/app/scripts/directives/property-types/type-map/type-map-directive.ts b/catalog-ui/app/scripts/directives/property-types/type-map/type-map-directive.ts
new file mode 100644
index 0000000000..d94ccf3886
--- /dev/null
+++ b/catalog-ui/app/scripts/directives/property-types/type-map/type-map-directive.ts
@@ -0,0 +1,157 @@
+/*-
+ * ============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=========================================================
+ */
+/**
+ * Created by rcohen on 9/15/2016.
+ */
+/// <reference path="../../../references"/>
+module Sdc.Directives {
+ 'use strict';
+
+ export interface ITypeMapScope extends ng.IScope {
+ parentFormObj:ng.IFormController;
+ schemaProperty:Models.SchemaProperty;
+ isSchemaTypeDataType:boolean;
+ valueObjRef:any;
+ mapKeys:Array<string>;//array of map keys
+ propertyNameValidationPattern: RegExp;
+ fieldsPrefixName:string;
+ readOnly:boolean;
+ mapDefaultValue:any;
+ types:Models.DataTypesMap;
+ maxLength:number;
+
+ getValidationPattern(type:string):RegExp;
+ validateIntRange(value:string):boolean;
+ changeKeyOfMap(newKey:string, index:number, fieldName:string):void;
+ deleteMapItem(index:number):void;
+ addMapItemFields():void;
+ parseToCorrectType(objectOfValues:any, locationInObj:string, type:string):void;
+ getNumber(num:number):Array<any>;
+ }
+
+
+ export class TypeMapDirective implements ng.IDirective {
+
+ constructor(private $templateCache:ng.ITemplateCacheService,
+ private DataTypesService:Sdc.Services.DataTypesService,
+ private PropertyNameValidationPattern: RegExp,
+ private ValidationUtils:Sdc.Utils.ValidationUtils,
+ private $timeout: ng.ITimeoutService) {
+ }
+
+ scope = {
+ valueObjRef: '=',//ref to map object in the parent value object
+ schemaProperty: '=',//get the schema.property object
+ parentFormObj: '=',//ref to parent form (get angular form object)
+ fieldsPrefixName: '=',//prefix for form fields names
+ readOnly: '=',//is form read only
+ defaultValue: '@',//this map default value
+ types: '=',//data types list
+ maxLength: '='
+ };
+
+ restrict = 'E';
+ replace = true;
+ template = ():string => {
+ return this.$templateCache.get('/app/scripts/directives/property-types/type-map/type-map-directive.html');
+ };
+
+ link = (scope:ITypeMapScope, element:any, $attr:any) => {
+ scope.propertyNameValidationPattern = this.PropertyNameValidationPattern;
+
+ //reset valueObjRef and mapKeys when schema type is changed
+ scope.$watchCollection('schemaProperty.type', (newData:any):void => {
+ scope.isSchemaTypeDataType = this.DataTypesService.isDataTypeForSchemaType(scope.schemaProperty,scope.types);
+ if(scope.valueObjRef){
+ scope.mapKeys = Object.keys(scope.valueObjRef);
+ }
+ });
+
+ //when user brows between properties in "edit property form"
+ scope.$watchCollection('fieldsPrefixName', (newData:any):void => {
+ if(!scope.valueObjRef) {
+ scope.valueObjRef={};
+ }
+ scope.mapKeys = Object.keys(scope.valueObjRef);
+
+ if($attr.defaultValue){
+ scope.mapDefaultValue = JSON.parse($attr.defaultValue);
+ }
+ });
+
+ //return dummy array in order to prevent rendering map-keys ng-repeat again when a map key is changed
+ scope.getNumber = (num:number):Array<any> => {
+ return new Array(num);
+ };
+
+ scope.getValidationPattern = (type:string):RegExp => {
+ return this.ValidationUtils.getValidationPattern(type);
+ };
+
+ scope.validateIntRange = (value:string):boolean => {
+ return !value || this.ValidationUtils.validateIntRange(value);
+ };
+
+ scope.changeKeyOfMap = (newKey:string, index:number, fieldName:string) : void => {
+ let oldKey = Object.keys(scope.valueObjRef)[index];
+ if(Object.keys(scope.valueObjRef).indexOf(newKey)>-1){
+ scope.parentFormObj[fieldName].$setValidity('keyExist', false);
+ }else{
+ scope.parentFormObj[fieldName].$setValidity('keyExist', true);
+ if(!scope.parentFormObj[fieldName].$invalid){
+ angular.copy(JSON.parse(JSON.stringify(scope.valueObjRef).replace('"'+oldKey+'":', '"'+newKey+'":')),scope.valueObjRef);//update key
+ }
+ }
+ };
+
+ scope.deleteMapItem=(index:number):void=>{
+ delete scope.valueObjRef[scope.mapKeys[index]];
+ scope.mapKeys.splice(index,1);
+ if (!scope.mapKeys.length) {//only when user removes all pairs of key-value fields - put the default
+ if ( scope.mapDefaultValue ) {
+ angular.copy(scope.mapDefaultValue, scope.valueObjRef);
+ scope.mapKeys = Object.keys(scope.valueObjRef);
+ }
+ }
+ };
+
+ scope.addMapItemFields = ():void => {
+ scope.valueObjRef['']= null;
+ scope.mapKeys = Object.keys(scope.valueObjRef);
+ };
+
+ scope.parseToCorrectType = (objectOfValues:any, locationInObj:string, type:string):void => {
+ if(objectOfValues[locationInObj] && type != Utils.Constants.PROPERTY_TYPES.STRING){
+ objectOfValues[locationInObj] = JSON.parse(objectOfValues[locationInObj]);
+ }
+ }
+ };
+
+ public static factory = ($templateCache:ng.ITemplateCacheService,
+ DataTypesService:Sdc.Services.DataTypesService,
+ PropertyNameValidationPattern:RegExp,
+ ValidationUtils:Sdc.Utils.ValidationUtils,
+ $timeout: ng.ITimeoutService)=> {
+ return new TypeMapDirective($templateCache,DataTypesService,PropertyNameValidationPattern,ValidationUtils,$timeout);
+ };
+ }
+
+ TypeMapDirective.factory.$inject = ['$templateCache','Sdc.Services.DataTypesService','PropertyNameValidationPattern','ValidationUtils','$timeout'];
+}