3 * ============LICENSE_START=======================================================
4 * Copyright (C) 2022 Nordix Foundation.
5 * ================================================================================
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
18 * SPDX-License-Identifier: Apache-2.0
19 * ============LICENSE_END=========================================================
22 import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
23 import {DataTypeModel} from '../../../../../../../models/data-types';
24 import {SchemaPropertyGroupModel} from '../../../../../../../models/schema-property';
25 import {DerivedPropertyType, PropertyBEModel} from '../../../../../../../models/properties-inputs/property-be-model';
26 import {PROPERTY_DATA, PROPERTY_TYPES} from '../../../../../../../utils/constants';
29 selector: 'app-input-list-item',
30 templateUrl: './input-list-item.component.html',
31 styleUrls: ['./input-list-item.component.less']
33 export class InputListItemComponent implements OnInit {
35 @Input() valueObjRef: any;
36 @Input() name: string;
37 @Input() dataTypeMap: Map<string, DataTypeModel>;
38 @Input() type: DataTypeModel;
39 @Input() schema: SchemaPropertyGroupModel;
40 @Input() nestingLevel: number;
41 @Input() isListChild: boolean = false;
42 @Input() isMapChild: boolean = false;
43 @Input() listIndex: number;
44 @Input() isViewOnly: boolean;
45 @Input() allowDeletion: boolean = false;
46 @Output('onValueChange') onValueChangeEvent: EventEmitter<any> = new EventEmitter<any>();
47 @Output('onDelete') onDeleteEvent: EventEmitter<string> = new EventEmitter<string>();
48 @Output('onChildListItemDelete') onChildListItemDeleteEvent: EventEmitter<number> = new EventEmitter<number>();
50 isExpanded: boolean = false;
54 if (!this.nestingLevel) {
55 this.nestingLevel = 0;
57 if (this.type.properties) {
58 this.type.properties.forEach(property => {
59 this.initEmptyPropertyInValueObjRef(property);
64 private initEmptyPropertyInValueObjRef(property: PropertyBEModel) {
65 if (this.valueObjRef[property.name] == undefined) {
66 if (this.isTypeComplex(property.type) || this.isTypeMap(property.type)) {
67 this.valueObjRef[property.name] = {};
68 } else if (this.isTypeList(property.type)) {
69 this.valueObjRef[property.name] = [];
71 this.valueObjRef[property.name] = null;
76 getType(typeName: string): DerivedPropertyType {
77 if (PROPERTY_DATA.SIMPLE_TYPES.indexOf(typeName) > -1) {
78 return DerivedPropertyType.SIMPLE;
79 } else if (typeName === PROPERTY_TYPES.LIST) {
80 return DerivedPropertyType.LIST;
81 } else if (typeName === PROPERTY_TYPES.MAP) {
82 return DerivedPropertyType.MAP;
84 return DerivedPropertyType.COMPLEX;
88 isTypeSimple(typeName: string): boolean {
89 return this.getType(typeName) == DerivedPropertyType.SIMPLE;
92 isTypeList(typeName: string): boolean {
93 return this.getType(typeName) == DerivedPropertyType.LIST;
96 isTypeMap(typeName: string): boolean {
97 return this.getType(typeName) == DerivedPropertyType.MAP;
100 isTypeComplex(typeName: string): boolean {
101 return !this.isTypeSimple(typeName) && !this.isTypeList(typeName) && !this.isTypeMap(typeName);
104 expandAndCollapse() {
105 this.isExpanded = !this.isExpanded;
108 getDataType(type: string) {
109 return this.dataTypeMap.get(type);
112 onValueChange(value: any): void {
113 if (this.type.name == PROPERTY_TYPES.INTEGER || this.type.name == PROPERTY_TYPES.FLOAT) {
114 this.emitValueChangeEvent(this.parseNumber(value));
117 if (this.type.name == PROPERTY_TYPES.BOOLEAN) {
118 this.emitValueChangeEvent(this.parseBoolean(value));
121 this.emitValueChangeEvent(value);
124 onListValueChange(): void {
125 this.emitValueChangeEvent(this.valueObjRef);
128 onPropertyValueChange($event: any) {
129 this.valueObjRef[$event.name] = $event.value;
130 this.emitValueChangeEvent(this.valueObjRef);
133 private emitValueChangeEvent(value: any) {
134 this.onValueChangeEvent.emit({
141 return this.nestingLevel === 0;
144 showListItemDelete(): boolean {
145 return !this.isViewOnly && (this.isListChild && this.nestingLevel > 0);
148 showInputDelete(): boolean {
149 return this.allowDeletion && !this.isViewOnly && (this.isRoot() || this.isMapChild);
152 resolveType(): string {
153 if (this.isTypeList(this.type.name)) {
154 return `list of value type ${this.schema.property.type}`
156 if (this.isTypeMap(this.type.name)) {
157 return `map of 'string' keys and '${this.schema.property.type}' values`
159 return this.type.name;
163 this.onDeleteEvent.emit(this.name);
166 onListItemDelete(index: number): void {
167 this.valueObjRef.splice(index, 1);
168 this.emitValueChangeEvent(this.valueObjRef);
172 if (this.isTypeSimple(this.schema.property.type)) {
173 this.valueObjRef.push('');
174 } else if (this.isTypeComplex(this.schema.property.type) || this.isTypeMap(this.schema.property.type)) {
175 this.valueObjRef.push({});
176 } else if (this.isTypeList(this.schema.property.type)) {
177 this.valueObjRef.push([]);
181 trackByIndex(index: number, value: string): number {
185 onChildListItemDelete() {
186 this.onChildListItemDeleteEvent.emit(this.listIndex);
189 getObjectEntries(valueObjRef: object) {
190 return Object.keys(valueObjRef);
194 this.emitValueChangeEvent(this.valueObjRef);
197 onMapKeyDelete(key: string) {
198 delete this.valueObjRef[key]
199 this.emitValueChangeEvent(this.valueObjRef);
204 if (this.mapEntryName) {
205 newKey = this.mapEntryName.trim();
210 if (Object.keys(this.valueObjRef).indexOf(newKey) !== -1) {
213 this.mapEntryName = '';
214 if (this.isTypeSimple(this.schema.property.type)) {
215 this.valueObjRef[newKey] = '';
216 } else if (this.isTypeComplex(this.schema.property.type) || this.isTypeMap(this.schema.property.type)) {
217 this.valueObjRef[newKey] = {};
218 } else if (this.isTypeList(this.schema.property.type)) {
219 this.valueObjRef[newKey] = [];
221 this.emitValueChangeEvent(this.valueObjRef);
224 getSimpleValueInputType() {
225 if (this.type.name == PROPERTY_TYPES.INTEGER || this.type.name == PROPERTY_TYPES.FLOAT) {
231 private parseBoolean(value: any) {
232 if (value === 'true') {
235 if (value === 'false') {
241 private parseNumber(value: any) {
242 const number = parseInt(value);
243 return isNaN(number) ? null : number;