summaryrefslogtreecommitdiffstats
path: root/catalog-ui/src/app
diff options
context:
space:
mode:
authorMichaelMorris <michael.morris@est.tech>2020-11-27 17:26:46 +0000
committerVasyl Razinkov <vasyl.razinkov@est.tech>2020-12-15 14:24:59 +0000
commit08fee6aa89ec2a0fd021c969af78ba422f86949f (patch)
treeffdb1001016bde3fdf265ad95db8f2ea21a564da /catalog-ui/src/app
parent3f816f6fdeb32061c77ab9799e18f2cb41ce8ea7 (diff)
Add metadata to topology inputs1.8.0
Change-Id: If57e16003532d59552fa0b5cacc69a792e5b877a Issue-ID: SDC-3399 Signed-off-by: MichaelMorris <michael.morris@est.tech>
Diffstat (limited to 'catalog-ui/src/app')
-rw-r--r--catalog-ui/src/app/models/metadata.ts31
-rw-r--r--catalog-ui/src/app/models/metadataEntry.ts25
-rw-r--r--catalog-ui/src/app/models/properties-inputs/input-fe-model.ts75
-rw-r--r--catalog-ui/src/app/models/properties-inputs/property-be-model.ts3
-rw-r--r--catalog-ui/src/app/ng2/components/logic/inputs-table/inputs-table.component.html49
-rw-r--r--catalog-ui/src/app/ng2/components/logic/inputs-table/inputs-table.component.less87
-rw-r--r--catalog-ui/src/app/ng2/components/logic/inputs-table/inputs-table.component.ts48
-rw-r--r--catalog-ui/src/app/ng2/pages/properties-assignment/properties-assignment.page.component.ts5
8 files changed, 308 insertions, 15 deletions
diff --git a/catalog-ui/src/app/models/metadata.ts b/catalog-ui/src/app/models/metadata.ts
new file mode 100644
index 0000000000..4db08006b4
--- /dev/null
+++ b/catalog-ui/src/app/models/metadata.ts
@@ -0,0 +1,31 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 Nordix Foundation
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+'use strict';
+import * as _ from "lodash";
+
+export class Metadata {
+
+ constructor(metaDataValues?:Metadata) {
+ _.forEach(metaDataValues, (metaDataValue:string, key) => {
+ this[key] = metaDataValue;
+ });
+ }
+}
+
diff --git a/catalog-ui/src/app/models/metadataEntry.ts b/catalog-ui/src/app/models/metadataEntry.ts
new file mode 100644
index 0000000000..c8dddc8d30
--- /dev/null
+++ b/catalog-ui/src/app/models/metadataEntry.ts
@@ -0,0 +1,25 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 Nordix Foundation
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+export class MetadataEntry {
+ public metaDataMapKey: string;
+ constructor(public key: string, public value: string) {
+ this.metaDataMapKey = key;
+ }
+} \ No newline at end of file
diff --git a/catalog-ui/src/app/models/properties-inputs/input-fe-model.ts b/catalog-ui/src/app/models/properties-inputs/input-fe-model.ts
index 85c514bcbc..909f712a4e 100644
--- a/catalog-ui/src/app/models/properties-inputs/input-fe-model.ts
+++ b/catalog-ui/src/app/models/properties-inputs/input-fe-model.ts
@@ -24,6 +24,8 @@ import {PropertyFEModel} from "../../models";
import {PROPERTY_DATA} from "../../utils/constants";
import {InputBEModel} from "./input-be-model";
import {DerivedPropertyType} from "./property-be-model";
+import { Metadata } from "app/models/metadata";
+import { MetadataEntry } from "app/models/metadataEntry";
export class InputFEModel extends InputBEModel {
isSimpleType: boolean;
@@ -35,6 +37,10 @@ export class InputFEModel extends InputBEModel {
defaultValueObjIsChanged:boolean;
derivedDataType: DerivedPropertyType;
requiredOrig: boolean;
+ metadataOrig: Metadata;
+ metadataIsValid:boolean;
+ metadataEntries: MetadataEntry[] = [];
+ metadataMapKeyError: string;
constructor(input?: InputBEModel) {
super(input);
@@ -50,6 +56,14 @@ export class InputFEModel extends InputBEModel {
this.updateDefaultValueObjOrig();
this.requiredOrig = this.required;
+ this.metadataOrig = _.cloneDeep(input.metadata);
+ this.metadataIsValid = true;
+
+ if (input.metadata){
+ for (let key of Object.keys(input.metadata)){
+ this.metadataEntries.push(new MetadataEntry(key, input.metadata[key]));
+ }
+ }
}
}
@@ -84,7 +98,66 @@ export class InputFEModel extends InputBEModel {
return this.required !== this.requiredOrig;
}
+ public updateMetadataKey(metadataEntry: MetadataEntry, newKey){
+ if (!newKey){
+ this.metadataIsValid = false;
+ this.metadataMapKeyError = 'Key cannot be empty.';
+ metadataEntry.key = newKey;
+ return;
+ } else if (metadataEntry.metaDataMapKey != newKey && this.metadata[newKey]){
+ this.metadataIsValid = false;
+ this.metadataMapKeyError = 'This key already exists!!.';
+ metadataEntry.key = newKey;
+ return;
+ }
+ this.metadataIsValid = true;
+ this.metadataMapKeyError = null;
+
+ if(metadataEntry.metaDataMapKey != newKey){
+ this.metadata[newKey] = _.cloneDeep(this.metadata[metadataEntry.metaDataMapKey]);
+ delete this.metadata[metadataEntry.metaDataMapKey];
+ metadataEntry.metaDataMapKey = newKey;
+ }
+ metadataEntry.key = newKey;
+ }
+
+ public updateMetadataValue(metadataEntry: MetadataEntry, value: string){
+ metadataEntry.value = value;
+ this.metadata[metadataEntry.key] = value;
+ }
+
+ public addMetadataEntry(metadataEntry: MetadataEntry){
+ this.metadataEntries.push(metadataEntry);
+ if (!this.metadata){
+ this.metadata = new Metadata;
+ }
+ this.metadata[metadataEntry.key] = metadataEntry.value;
+ }
+
+ public deleteMetadataEntry(metadataEntry: MetadataEntry){
+ let metadataEntryIndex = this.metadataEntries.findIndex(item => item.key === metadataEntry.key);
+ if (metadataEntryIndex != -1){
+ this.metadataEntries.splice(metadataEntryIndex, 1);
+ }
+ delete this.metadata[metadataEntry.key];
+ }
+
+ public resetMetadata = (): void => {
+ this.metadata = _.cloneDeep(this.metadataOrig);
+ this.metadataIsValid = true;
+
+ this.metadataEntries = [];
+ for (let key of Object.keys(this.metadata)){
+ this.metadataEntries.push(new MetadataEntry(key, this.metadata[key]));
+ }
+ }
+
+ hasMetadataChanged(): boolean {
+ return !_.isEqual(this.metadata, this.metadataOrig);
+ }
+
hasChanged(): boolean {
- return this.hasDefaultValueChanged() || this.hasRequiredChanged();
+ return this.hasDefaultValueChanged() || this.hasRequiredChanged() || this.hasMetadataChanged();
}
+
} \ No newline at end of file
diff --git a/catalog-ui/src/app/models/properties-inputs/property-be-model.ts b/catalog-ui/src/app/models/properties-inputs/property-be-model.ts
index 1d263bd8b0..b997ea4563 100644
--- a/catalog-ui/src/app/models/properties-inputs/property-be-model.ts
+++ b/catalog-ui/src/app/models/properties-inputs/property-be-model.ts
@@ -22,6 +22,7 @@ import { PROPERTY_DATA, PROPERTY_TYPES } from 'app/utils/constants';
import { SchemaProperty, SchemaPropertyGroupModel } from '../aschema-property';
import { ToscaPresentationData } from '../tosca-presentation';
import { PropertyInputDetail } from './property-input-detail';
+import { Metadata } from '../metadata';
export enum DerivedPropertyType {
SIMPLE,
@@ -63,6 +64,7 @@ export class PropertyBEModel {
subPropertyInputPath: string;
inputPath: string;
toscaPresentation: ToscaPresentationData;
+ metadata: Metadata;
constructor(property?: PropertyBEModel) {
if (property) {
@@ -87,6 +89,7 @@ export class PropertyBEModel {
this.toscaPresentation = property.toscaPresentation;
this.getPolicyValues = property.getPolicyValues;
this.inputPath = property.inputPath;
+ this.metadata = property.metadata;
}
if (!this.schema || !this.schema.property) {
diff --git a/catalog-ui/src/app/ng2/components/logic/inputs-table/inputs-table.component.html b/catalog-ui/src/app/ng2/components/logic/inputs-table/inputs-table.component.html
index d3db53aa43..ee090245f0 100644
--- a/catalog-ui/src/app/ng2/components/logic/inputs-table/inputs-table.component.html
+++ b/catalog-ui/src/app/ng2/components/logic/inputs-table/inputs-table.component.html
@@ -32,6 +32,9 @@
<div class="table-cell col4" (click)="sort('required')" *ngIf="componentType == 'SERVICE'">
<span tooltip="Required in Runtime" tooltipDelay="400">Req. in RT</span>
</div>
+ <div class="table-cell" [class.metadata-col-small]="!hasInputMetadata()" [class.metadata-col-wide]="hasInputMetadata()">
+ <div [class.metadata-col-wide-text]="hasInputMetadata()">Metadata</div>
+ </div>
<div class="table-cell valueCol">Value</div>
</div>
<div class="table-body">
@@ -65,8 +68,51 @@
(checkedChange)="onRequiredChanged(input, $event)"
[disabled]="readonly"></sdc-checkbox>
</div>
+ <!-- Metadata -->
+ <div class="table-cell" [class.metadata-col-small]="!hasInputMetadata()" [class.metadataCol]="hasInputMetadata()">
+ <div class="inner-cell-div metadata-add" tooltip="Add key value pair">
+ <a class="property-icon add-item" (click)="createNewMetadataEntry(input);" [ngClass]="{'disabled':readonly}">Add metadata</a>
+ </div>
+ <ng-container >
+ <div class="metadata-container">
+ <ng-container *ngFor="let metadataEntry of input.metadataEntries;">
+ <div class="metadata-entry">
+ <ng-container>
+ <div class="metadata-key-value metadata-key" >
+ <dynamic-element #metadataViewChildren
+ class="value-input"
+ pattern="validationUtils.getValidationPattern(string)"
+ [value]="metadataEntry.key"
+ type="string"
+ name="{{input.name}}_{{metadataEntry.key}}"
+ (elementChanged)="onMetadataKeyChanged(input, $event, metadataEntry)"
+ [readonly]="readonly"
+ [testId]="'prop-key-' + propertyTestsId"
+ ></dynamic-element>
+ </div>
+ </ng-container>
+ <ng-container>
+ <div class="metadata-key-value">
+ <dynamic-element
+ class="value-input"
+ pattern="validationUtils.getValidationPattern(string)"
+ [value]="metadataEntry.value"
+ type="string"
+ [name]="metadataEntry.key"
+ (elementChanged)="onMetadataValueChanged(input, $event, metadataEntry)"
+ [readonly]="readonly"
+ [testId]="'prop-key-' + propertyTestsId"
+ ></dynamic-element>
+ </div>
+ <span (click)="deleteMetadataEntry(input, metadataEntry);" class="delete-icon sprite-new delete-item-icon" [ngClass]="{'disabled':readonly}"></span>
+ </ng-container>
+ </div>
+ </ng-container>
+ </div>
+ </ng-container>
+ </div>
<!-- Value -->
- <div class="table-cell valueCol input-value-col" [class.inner-table-container]="input.childrenProperties || !input.isSimpleType">
+ <div class="table-cell valueCol" [class.inner-table-container]="input.childrenProperties || !input.isSimpleType">
<dynamic-element class="value-input"
*ngIf="checkInstanceFePropertiesMapIsFilled() && input.isSimpleType"
pattern="validationUtils.getValidationPattern(input.type)"
@@ -82,7 +128,6 @@
<span *ngIf="input.instanceUniqueId && !readonly" class="sprite-new delete-btn" (click)="openDeleteModal(input)" data-tests-id="delete-input-button"></span>
</div>
</div>
-
</div>
</div>
</div>
diff --git a/catalog-ui/src/app/ng2/components/logic/inputs-table/inputs-table.component.less b/catalog-ui/src/app/ng2/components/logic/inputs-table/inputs-table.component.less
index 77c002c899..74520b6314 100644
--- a/catalog-ui/src/app/ng2/components/logic/inputs-table/inputs-table.component.less
+++ b/catalog-ui/src/app/ng2/components/logic/inputs-table/inputs-table.component.less
@@ -3,6 +3,37 @@
:host /deep/ input { width:100%;}
+.metadata-container {
+ .metadata-entry {
+ border-top:solid 1px #d2d2d2;
+ flex: 1;
+ display:flex;
+ flex-direction:row;
+ align-items: stretch;
+
+ .metadata-key-value {
+ flex: 1;
+ padding:8px;
+ justify-content: center;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ }
+
+ .metadata-key {
+ flex: 0 0 50%;
+ border-right:#d2d2d2 solid 1px;
+ }
+
+ .delete-icon {
+ flex: 0 0 auto;
+ margin-right:10px;
+ align-self:center;
+ cursor:pointer;
+ }
+ }
+}
+
.properties-table {
display:flex;
flex-direction:column;
@@ -46,7 +77,22 @@
}
.valueCol {
justify-content: flex-start;
+ padding: 10px 8px 10px 8px;
+ }
+
+ .metadata-col-small {
padding: 10px;
+ flex: 0 0 115px;
+ }
+ .metadata-col-wide {
+ justify-content: flex-start;
+ padding: 0px;
+ flex: 1;
+
+ .metadata-col-wide-text {
+ justify-content: flex-start;
+ padding: 10px;
+ }
}
}
.table-header, .table-row {
@@ -85,6 +131,37 @@
.selected-row {
background-color:#e6f6fb;
}
+ .table-cell.valueCol {
+ padding:8px;
+ }
+ .table-cell.metadataCol {
+ padding:0px;
+ .value-input {
+ flex: 1;
+ border: none;
+ background-color: inherit;
+
+ &:focus, &:active {
+ border:none;
+ outline:none;
+ }
+ }
+ .metadata-add {
+ padding: 10px;
+ height: 40px;
+ }
+ }
+
+ .table-cell.metadata-col-small {
+ flex: 0 0 115px;
+ padding: 0px 10px 0px 10px;
+ .metadata-add {
+ padding: 10px 0px 10px 0px;
+ height: 40px;
+ margin-right: 0px;
+ }
+ }
+
}
.table-cell {
@@ -123,13 +200,13 @@
// Column: Type
&.col2 {
- flex: 0 0 140px;
+ flex: 0 1 140px;
max-width: 140px;
}
// Column: From Instance
&.col3 {
- flex: 0 0 120px;
+ flex: 0 1 120px;
max-width: 120px;
}
@@ -169,12 +246,6 @@
}
}
}
-
- &.input-value-col {
- padding: 8px;
- }
-
-
}
.filtered {
diff --git a/catalog-ui/src/app/ng2/components/logic/inputs-table/inputs-table.component.ts b/catalog-ui/src/app/ng2/components/logic/inputs-table/inputs-table.component.ts
index 682a3e2463..3fa7ab4a80 100644
--- a/catalog-ui/src/app/ng2/components/logic/inputs-table/inputs-table.component.ts
+++ b/catalog-ui/src/app/ng2/components/logic/inputs-table/inputs-table.component.ts
@@ -22,12 +22,14 @@
/**
* Created by rc2122 on 5/4/2017.
*/
-import { Component, Input, Output, EventEmitter } from "@angular/core";
+import { Component, Input, Output, EventEmitter, ViewChildren, QueryList } from "@angular/core";
import { InputFEModel } from "app/models";
import { ModalService } from "../../../services/modal.service";
import { InstanceFeDetails } from "app/models/instance-fe-details";
import { InstanceFePropertiesMap } from "../../../../models/properties-inputs/property-fe-map";
import { DataTypeService } from "../../../services/data-type.service";
+import { MetadataEntry } from "app/models/metadataEntry";
+import { DynamicElementComponent } from "../../ui/dynamic-element/dynamic-element.component";
@Component({
selector: 'inputs-table',
@@ -41,10 +43,13 @@ export class InputsTableComponent {
@Input() readonly: boolean;
@Input() isLoading: boolean;
@Input() componentType: string;
+
@Output() inputChanged: EventEmitter<any> = new EventEmitter<any>();
@Output() deleteInput: EventEmitter<any> = new EventEmitter<any>();
@Input() fePropertiesMap: InstanceFePropertiesMap;
+
+ @ViewChildren('metadataViewChildren') public metadataViewChildren: QueryList<DynamicElementComponent>;
sortBy: String;
reverse: boolean;
@@ -93,6 +98,35 @@ export class InputsTableComponent {
this.inputChanged.emit(input);
}
+ onMetadataKeyChanged = (input: InputFEModel, event, metadataEntry: MetadataEntry) => {
+ let dynamicElementComponent = this.metadataViewChildren.filter(element => element.name == input.name + "_" + metadataEntry.key).pop();
+
+ input.updateMetadataKey(metadataEntry, event.value);
+ this.inputChanged.emit(input);
+
+ var mapKeyError = input.metadataMapKeyError;
+ if(input.metadataMapKeyError){
+ dynamicElementComponent.cmpRef.instance.control.setErrors({mapKeyError});
+ }
+ };
+
+ onMetadataValueChanged = (input: InputFEModel, event, metadataEntry: MetadataEntry) => {
+ input.updateMetadataValue(metadataEntry, event.value);
+ this.inputChanged.emit(input);
+ };
+
+
+ createNewMetadataEntry = (input: InputFEModel): void => {
+ let metadataEntry = new MetadataEntry("", "");
+ input.addMetadataEntry(metadataEntry);
+ this.inputChanged.emit(input);
+ }
+
+ deleteMetadataEntry = (input: InputFEModel, metadataEntry: MetadataEntry) => {
+ input.deleteMetadataEntry(metadataEntry);
+ this.inputChanged.emit(input);
+ }
+
onDeleteInput = () => {
this.deleteInput.emit(this.selectedInputToDelete);
this.modalService.closeCurrentModal();
@@ -100,8 +134,6 @@ export class InputsTableComponent {
openDeleteModal = (input: InputFEModel) => {
console.log('exist inputs: ' + this.inputs)
-
-
this.selectedInputToDelete = input;
this.modalService.createActionModal("Delete Input", "Are you sure you want to delete this input?", "Delete", this.onDeleteInput, "Close").instance.open();
}
@@ -133,6 +165,16 @@ export class InputsTableComponent {
checkInstanceFePropertiesMapIsFilled(){
return _.keys(this.fePropertiesMap).length > 0
}
+
+ hasInputMetadata(){
+ for(let input of this.inputs){
+ if (input.metadataEntries.length > 0){
+ return true;
+ }
+ }
+ return false;
+ }
+
}
diff --git a/catalog-ui/src/app/ng2/pages/properties-assignment/properties-assignment.page.component.ts b/catalog-ui/src/app/ng2/pages/properties-assignment/properties-assignment.page.component.ts
index 83174fa87a..e4a8749386 100644
--- a/catalog-ui/src/app/ng2/pages/properties-assignment/properties-assignment.page.component.ts
+++ b/catalog-ui/src/app/ng2/pages/properties-assignment/properties-assignment.page.component.ts
@@ -367,7 +367,9 @@ export class PropertiesAssignmentComponent {
if (this.isPropertiesTabSelected) {
this.isValidChangedData = this.changedData.every((changedItem) => (<PropertyFEModel>changedItem).valueObjIsValid);
- } else if (this.isInputsTabSelected || this.isPoliciesTabSelected) {
+ } else if (this.isInputsTabSelected) {
+ this.isValidChangedData = this.changedData.every((changedItem) => (<InputFEModel>changedItem).defaultValueObjIsValid && (<InputFEModel>changedItem).metadataIsValid);
+ } else if (this.isPoliciesTabSelected) {
this.isValidChangedData = this.changedData.every((changedItem) => (<InputFEModel>changedItem).defaultValueObjIsValid);
}
this.updateHasChangedData();
@@ -846,6 +848,7 @@ export class PropertiesAssignmentComponent {
handleReverseItem = (changedItem) => {
changedItem = <InputFEModel>changedItem;
this.inputsUtils.resetInputDefaultValue(changedItem, changedItem.defaultValue);
+ changedItem.resetMetadata();
changedItem.required = changedItem.requiredOrig;
};
}