aboutsummaryrefslogtreecommitdiffstats
path: root/catalog-ui/src/app/ng2/components/logic
diff options
context:
space:
mode:
authoraribeiro <anderson.ribeiro@est.tech>2020-07-02 14:42:40 +0100
committerSébastien Determe <sebastien.determe@intl.att.com>2020-08-07 10:32:02 +0000
commit6c3e38279e219b390e79d31fe8b5c78f053a4e88 (patch)
treee997f7f34357ec78c89a4ac52a59f273b8276aad /catalog-ui/src/app/ng2/components/logic
parent4591db74a7b358f2bbfa9f9e47ccf365b544412b (diff)
Add substitution filter UI support
Issue-ID: SDC-3195 Signed-off-by: aribeiro <anderson.ribeiro@est.tech> Change-Id: Idc6301a1ab7442f8d2d59931abf0a0741cc8e410
Diffstat (limited to 'catalog-ui/src/app/ng2/components/logic')
-rw-r--r--catalog-ui/src/app/ng2/components/logic/substitution-filter/substitution-filter.component.html50
-rw-r--r--catalog-ui/src/app/ng2/components/logic/substitution-filter/substitution-filter.component.less105
-rw-r--r--catalog-ui/src/app/ng2/components/logic/substitution-filter/substitution-filter.component.ts296
-rw-r--r--catalog-ui/src/app/ng2/components/logic/substitution-filter/substitution-filter.module.ts44
4 files changed, 495 insertions, 0 deletions
diff --git a/catalog-ui/src/app/ng2/components/logic/substitution-filter/substitution-filter.component.html b/catalog-ui/src/app/ng2/components/logic/substitution-filter/substitution-filter.component.html
new file mode 100644
index 0000000000..f781e6c89b
--- /dev/null
+++ b/catalog-ui/src/app/ng2/components/logic/substitution-filter/substitution-filter.component.html
@@ -0,0 +1,50 @@
+<!--
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2020 Nordix Foundation. 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=========================================================
+-->
+
+<div class="substitution-filter">
+
+ <div *ngIf="compositeService.isService()"
+ class="i-sdc-designer-sidebar-section-content-item-rules-section">
+
+ <div class="i-sdc-designer-sidebar-section-content-item-rule" [ngClass]="{'hand': !readonly}"
+ *ngFor="let constraint of constraintObjects; let i = index">
+ <div class="rule-details" [ngClass]="{'readonly': readonly}">
+ <div class="rule-desc" (click)="!readonly && onSelectFilter(i)" tooltips
+ tooltip="{{constraint.servicePropertyName + ' ' + getSymbol(constraint.constraintOperator) + ' '
+ + (constraint.sourceName ? constraint.sourceName + ':' : '') + constraint.value}}">
+ {{constraint.servicePropertyName + ' ' + getSymbol(constraint.constraintOperator) + ' '
+ + (constraint.sourceName ? constraint.sourceName + ':' : '') + constraint.value}}
+ </div>
+ <span *ngIf="!readonly" class="sprite-new delete-btn delete-icon"
+ (click)="openDeleteModal(i)" data-tests-id="delete-input-button"></span>
+ </div>
+ </div>
+
+ <div *ngIf="!isSubstitutionFilterSet()" class="w-sdc-designer-sidebar-section-footer">
+ <button
+ class="w-sdc-designer-sidebar-section-footer-action tlv-btn blue"
+ data-tests-id="add-rule-button"
+ (click)="onAddSubstitutionFilter()"
+ [disabled]="readonly">
+ {{'ADD_SUBSTITUTION_FILTER' | translate}}
+ </button>
+ </div>
+ </div>
+</div>
diff --git a/catalog-ui/src/app/ng2/components/logic/substitution-filter/substitution-filter.component.less b/catalog-ui/src/app/ng2/components/logic/substitution-filter/substitution-filter.component.less
new file mode 100644
index 0000000000..2d9b2646af
--- /dev/null
+++ b/catalog-ui/src/app/ng2/components/logic/substitution-filter/substitution-filter.component.less
@@ -0,0 +1,105 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2020 Nordix Foundation. 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=========================================================
+ */
+
+@import './../../../../../assets/styles/variables.less';
+@import './../../../../../assets/styles/variables-old.less';
+@import './../../../../../assets/styles/mixins_old.less';
+@import './../../../../../assets/styles/mixins.less';
+
+.substitution-filter {
+
+ /deep/ .checkbox-label-mark-as-dependent {
+ padding: 7px 18px;
+ position: relative;
+ height: 61px;
+ color: @main_color_a;
+ box-shadow: 0 2px 7px @main_color_o;
+ border-bottom: 1px solid @main_color_o;
+ .checkbox-label {
+ margin-top: 14px;
+ .checkbox-label-content {
+ font-size: 14px;
+ }
+ }
+ .checkbox-container input[type=checkbox].checkbox-hidden[disabled] ~ .checkbox-label-content {
+ opacity: 0.5;
+ }
+ .delete-btn {
+ background-position: -137px -415px;
+ width: 24px;
+ height: 24px
+ }
+
+ loader {
+ top: 20px;
+ }
+ }
+
+
+ .i-sdc-designer-sidebar-section-content-item-rules-section {
+ .i-sdc-designer-sidebar-section-content-item-rule {
+ border-bottom: 1px solid @main_color_o;
+ padding: 5px 10px 5px 18px;
+ position: relative;
+ height: 61px;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+
+ .rule-details {
+ // .s_1;
+ display: flex;
+ flex: 1;
+ align-items: center;
+ justify-content: space-between;
+ margin-left: 5px;
+ width: 180px;
+ .delete-icon {
+ visibility: hidden;
+ }
+ &:not(.readonly):hover {
+ .a_1;
+ }
+ &:hover .delete-icon{
+ visibility: visible;
+ }
+ &.readonly {
+ opacity: 0.5;
+ }
+ }
+ .rule-desc {
+ .sdc-ellipsis;
+ width: 220px;
+ position: relative;
+ padding-right: 1em;
+ }
+
+ }
+ }
+ .w-sdc-designer-sidebar-section-footer {
+ margin-top: 10px;
+ text-align: center;
+ width: 100%;
+ }
+ .w-sdc-designer-sidebar-section-footer-action {
+ width: 180px;
+ margin-top: 10px;
+ }
+}
diff --git a/catalog-ui/src/app/ng2/components/logic/substitution-filter/substitution-filter.component.ts b/catalog-ui/src/app/ng2/components/logic/substitution-filter/substitution-filter.component.ts
new file mode 100644
index 0000000000..a0fa2bb20b
--- /dev/null
+++ b/catalog-ui/src/app/ng2/components/logic/substitution-filter/substitution-filter.component.ts
@@ -0,0 +1,296 @@
+/*
+* ============LICENSE_START=======================================================
+* Copyright (C) 2020 Nordix Foundation. 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.
+*
+* SPDX-License-Identifier: Apache-2.0
+* ============LICENSE_END=========================================================
+*/
+
+import {Component, ComponentRef, EventEmitter, Input, Output} from '@angular/core';
+import {
+ ButtonModel,
+ ComponentInstance,
+ InputBEModel,
+ ModalModel,
+ PropertyBEModel,
+} from 'app/models';
+import {ModalComponent} from 'app/ng2/components/ui/modal/modal.component';
+import {ServiceDependenciesEditorComponent} from 'app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component';
+import {ModalService} from 'app/ng2/services/modal.service';
+import {ComponentGenericResponse} from 'app/ng2/services/responses/component-generic-response';
+import {TranslateService} from 'app/ng2/shared/translator/translate.service';
+import {ComponentMetadata} from '../../../../models/component-metadata';
+import {ServiceInstanceObject} from '../../../../models/service-instance-properties-and-interfaces';
+import {TopologyTemplateService} from '../../../services/component-services/topology-template.service';
+
+export class ConstraintObject {
+ servicePropertyName: string;
+ constraintOperator: string;
+ sourceType: string;
+ sourceName: string;
+ value: string;
+
+ constructor(input?: any) {
+ if (input) {
+ this.servicePropertyName = input.servicePropertyName;
+ this.constraintOperator = input.constraintOperator;
+ this.sourceType = input.sourceType;
+ this.sourceName = input.sourceName;
+ this.value = input.value;
+ }
+ }
+}
+
+export class ConstraintObjectUI extends ConstraintObject {
+ isValidValue: boolean;
+
+ constructor(input?: any) {
+ super(input);
+ if (input) {
+ this.isValidValue = input.isValidValue ? input.isValidValue : input.value !== '';
+ }
+ }
+
+ public updateValidity(isValidValue: boolean) {
+ this.isValidValue = isValidValue;
+ }
+
+ public isValidRule(isStatic) {
+ const isValidValue = isStatic ? this.isValidValue : true;
+ return this.servicePropertyName != null && this.servicePropertyName !== ''
+ && this.value != null && this.value !== '' && isValidValue;
+ }
+}
+
+export const OPERATOR_TYPES = {
+ EQUAL: 'equal',
+ GREATER_THAN: 'greater_than',
+ LESS_THAN: 'less_than'
+};
+
+class I18nTexts {
+ static addSubstitutionFilterTxt: string;
+ static updateSubstitutionFilterTxt: string;
+ static deleteSubstitutionFilterTxt: string;
+ static deleteSubstitutionFilterMsg: string;
+ static modalCancel: string;
+ static modalCreate: string;
+ static modalSave: string;
+ static modalDelete: string;
+
+ public static translateTexts(translateService) {
+ I18nTexts.modalCancel = translateService.translate('MODAL_CANCEL');
+ I18nTexts.modalCreate = translateService.translate('MODAL_CREATE');
+ I18nTexts.modalSave = translateService.translate('MODAL_SAVE');
+ I18nTexts.modalDelete = translateService.translate('MODAL_DELETE');
+
+ I18nTexts.addSubstitutionFilterTxt = translateService.translate('ADD_SUBSTITUTION_FILTER');
+ I18nTexts.updateSubstitutionFilterTxt = translateService.translate('UPDATE_SUBSTITUTION_FILTER');
+ I18nTexts.deleteSubstitutionFilterTxt = translateService.translate('DELETE_SUBSTITUTION_FILTER');
+ I18nTexts.deleteSubstitutionFilterMsg = translateService.translate('DELETE_SUBSTITUTION_FILTER_MSG');
+ }
+}
+
+@Component({
+ selector: 'substitution-filter',
+ templateUrl: './substitution-filter.component.html',
+ styleUrls: ['substitution-filter.component.less'],
+ providers: [ModalService, TranslateService]
+})
+
+export class SubstitutionFilterComponent {
+ modalInstance: ComponentRef<ModalComponent>;
+ isLoading: boolean;
+ parentServiceInputs: InputBEModel[] = [];
+ operatorTypes: any[];
+ constraintObjects: ConstraintObject[] = [];
+
+ @Input() readonly: boolean;
+ @Input() compositeService: ComponentMetadata;
+ @Input() currentServiceInstance: ComponentInstance;
+ @Input() selectedInstanceSiblings: ServiceInstanceObject[];
+ @Input() selectedInstanceConstraints: ConstraintObject[] = [];
+ @Input() selectedInstanceProperties: PropertyBEModel[] = [];
+ @Output() updateConstraintListEvent: EventEmitter<ConstraintObject[]> = new EventEmitter<ConstraintObject[]>();
+ @Output() loadConstraintListEvent: EventEmitter<any> = new EventEmitter();
+ @Output() hasSubstitutionFilter = new EventEmitter<boolean>();
+
+ constructor(private topologyTemplateService: TopologyTemplateService, private modalServiceNg2: ModalService, private translateService: TranslateService) {
+ }
+
+ ngOnInit() {
+ this.isLoading = false;
+ this.operatorTypes = [
+ {label: '>', value: OPERATOR_TYPES.GREATER_THAN},
+ {label: '<', value: OPERATOR_TYPES.LESS_THAN},
+ {label: '=', value: OPERATOR_TYPES.EQUAL}
+ ];
+ this.topologyTemplateService.getComponentInputsWithProperties(this.compositeService.componentType, this.compositeService.uniqueId).subscribe((result: ComponentGenericResponse) => {
+ this.parentServiceInputs = result.inputs;
+ });
+ this.loadAllInstances();
+ this.translateService.languageChangedObservable.subscribe((lang) => {
+ I18nTexts.translateTexts(this.translateService);
+ });
+ }
+
+ ngOnChanges(changes) {
+ if (changes.currentServiceInstance) {
+ this.currentServiceInstance = changes.currentServiceInstance.currentValue;
+ }
+ if (changes.selectedInstanceConstraints && changes.selectedInstanceConstraints.currentValue !== changes.selectedInstanceConstraints.previousValue) {
+ this.selectedInstanceConstraints = changes.selectedInstanceConstraints.currentValue;
+ this.loadAllInstances();
+ }
+ }
+
+ public loadAllInstances = (): void => {
+ this.topologyTemplateService.getComponentCompositionData(this.compositeService.uniqueId, this.compositeService.componentType).subscribe((response) => {
+ response.componentInstances.forEach(componentInstance => this.getSubstitutionFilter(componentInstance))
+ })
+ }
+
+ onAddSubstitutionFilter() {
+ const cancelButton: ButtonModel = new ButtonModel(I18nTexts.modalCancel, 'outline white', this.modalServiceNg2.closeCurrentModal);
+ const saveButton: ButtonModel = new ButtonModel(I18nTexts.modalCreate, 'blue', this.createSubstitutionFilter, this.getDisabled);
+ const modalModel: ModalModel = new ModalModel('l', I18nTexts.addSubstitutionFilterTxt, '', [saveButton, cancelButton], 'standard');
+ this.modalInstance = this.modalServiceNg2.createCustomModal(modalModel);
+ this.modalServiceNg2.addDynamicContentToModal(
+ this.modalInstance,
+ ServiceDependenciesEditorComponent,
+ {
+ currentServiceName: this.currentServiceInstance.name,
+ operatorTypes: this.operatorTypes,
+ compositeServiceName: this.compositeService.name,
+ parentServiceInputs: this.parentServiceInputs,
+ selectedInstanceProperties: this.selectedInstanceProperties,
+ selectedInstanceSiblings: this.selectedInstanceSiblings
+ }
+ );
+ this.modalInstance.instance.open();
+ }
+
+ createSubstitutionFilter = (): void => {
+ const newSubstitutionFilter: ConstraintObject = new ConstraintObject(this.modalInstance.instance.dynamicContent.instance.currentRule);
+ this.isLoading = true;
+ this.topologyTemplateService.createSubstitutionFilterConstraints(
+ this.compositeService.uniqueId,
+ this.currentServiceInstance.uniqueId,
+ newSubstitutionFilter,
+ this.compositeService.componentType
+ ).subscribe((response) => {
+ this.updateConstraintListEvent.emit(response.properties);
+ this.isLoading = false;
+ }, () => {
+ console.error("Failed to Create Substitution Filter on the component with id: ", this.compositeService.uniqueId);
+ this.isLoading = false;
+ });
+ this.modalServiceNg2.closeCurrentModal();
+ }
+
+ onSelectFilter(index: number) {
+ const cancelButton: ButtonModel = new ButtonModel(I18nTexts.modalCancel, 'outline white', this.modalServiceNg2.closeCurrentModal);
+ const updateButton: ButtonModel = new ButtonModel(I18nTexts.modalSave, 'blue', () => this.updateSubstitutionFilter(), this.getDisabled);
+ const modalModel: ModalModel = new ModalModel('l', I18nTexts.updateSubstitutionFilterTxt, '', [updateButton, cancelButton], 'standard');
+ this.modalInstance = this.modalServiceNg2.createCustomModal(modalModel);
+ this.modalServiceNg2.addDynamicContentToModal(
+ this.modalInstance,
+ ServiceDependenciesEditorComponent,
+ {
+ serviceRuleIndex: index,
+ serviceRules: _.map(this.constraintObjects, (constraint) => new ConstraintObjectUI(constraint)),
+ currentServiceName: this.currentServiceInstance.name,
+ operatorTypes: this.operatorTypes,
+ compositeServiceName: this.compositeService.name,
+ parentServiceInputs: this.parentServiceInputs,
+ selectedInstanceProperties: this.selectedInstanceProperties,
+ selectedInstanceSiblings: this.selectedInstanceSiblings
+ }
+ );
+ this.modalInstance.instance.open();
+ }
+
+ updateSubstitutionFilter = (): void => {
+ const constraintToUpdate: ConstraintObject = this.modalInstance.instance.dynamicContent.instance.serviceRulesList.map((rule) => new ConstraintObject(rule));
+ this.isLoading = true;
+ this.topologyTemplateService.updateSubstitutionFilterConstraints(
+ this.compositeService.uniqueId,
+ this.currentServiceInstance.uniqueId,
+ constraintToUpdate,
+ this.compositeService.componentType
+ ).subscribe((response) => {
+ this.hasSubstitutionFilter.emit(this.isSubstitutionFilterSet());
+ this.updateConstraintListEvent.emit(response.properties);
+ this.isLoading = false;
+ }, () => {
+ console.error("Failed to Update Substitution Filter on the component with id: ", this.compositeService.uniqueId);
+ this.isLoading = false;
+ });
+ this.modalServiceNg2.closeCurrentModal();
+ }
+
+ onDeleteSubstitutionFilter = (index: number) => {
+ this.isLoading = true;
+ this.topologyTemplateService.deleteSubstitutionFilterConstraints(
+ this.compositeService.uniqueId,
+ this.currentServiceInstance.uniqueId,
+ index,
+ this.compositeService.componentType
+ ).subscribe((response) => {
+ console.log("on Delete - Response Properties: ", response.properties);
+ this.updateConstraintListEvent.emit(response.properties);
+ this.isLoading = false;
+ }, () => {
+ console.error("Failed to Delete Substitution Filter on the component with id: ", this.compositeService.uniqueId);
+ this.isLoading = false;
+ });
+ this.constraintObjects = [];
+ this.modalServiceNg2.closeCurrentModal();
+ }
+
+ getDisabled = (): boolean => {
+ return !this.modalInstance.instance.dynamicContent.instance.checkFormValidForSubmit();
+ }
+
+ getSymbol(constraintOperator) {
+ switch (constraintOperator) {
+ case OPERATOR_TYPES.LESS_THAN:
+ return '<';
+ case OPERATOR_TYPES.EQUAL:
+ return '=';
+ case OPERATOR_TYPES.GREATER_THAN:
+ return '>';
+ }
+ }
+
+ openDeleteModal = (index: number) => {
+ this.modalServiceNg2.createActionModal(I18nTexts.deleteSubstitutionFilterTxt, I18nTexts.deleteSubstitutionFilterMsg,
+ I18nTexts.modalDelete, () => this.onDeleteSubstitutionFilter(index), I18nTexts.modalCancel).instance.open();
+ }
+
+ private getSubstitutionFilter = (componentInstance: ComponentInstance): void => {
+ this.topologyTemplateService.getSubstitutionFilterConstraints(this.compositeService.componentType, this.compositeService.uniqueId).subscribe((response) => {
+ const substitutionFilter: ConstraintObject[] = response.substitutionFilterForTopologyTemplate[componentInstance.uniqueId].properties;
+ if (substitutionFilter) {
+ this.currentServiceInstance = componentInstance;
+ this.constraintObjects = substitutionFilter;
+ }
+ });
+ }
+
+ private isSubstitutionFilterSet = (): boolean => {
+ return Array.isArray(this.constraintObjects) && this.constraintObjects.length > 0;
+ }
+
+}
diff --git a/catalog-ui/src/app/ng2/components/logic/substitution-filter/substitution-filter.module.ts b/catalog-ui/src/app/ng2/components/logic/substitution-filter/substitution-filter.module.ts
new file mode 100644
index 0000000000..9ea7c0c5a0
--- /dev/null
+++ b/catalog-ui/src/app/ng2/components/logic/substitution-filter/substitution-filter.module.ts
@@ -0,0 +1,44 @@
+/*
+* ============LICENSE_START=======================================================
+* Copyright (C) 2020 Nordix Foundation. 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.
+*
+* SPDX-License-Identifier: Apache-2.0
+* ============LICENSE_END=========================================================
+*/
+
+import { CommonModule } from '@angular/common';
+import { NgModule } from '@angular/core';
+import { UiElementsModule } from 'app/ng2/components/ui/ui-elements.module';
+import { TranslateModule } from 'app/ng2/shared/translator/translate.module';
+import { SubstitutionFilterComponent } from "./substitution-filter.component";
+
+@NgModule({
+ declarations: [
+ SubstitutionFilterComponent
+ ],
+ imports: [
+ CommonModule,
+ UiElementsModule,
+ TranslateModule
+ ],
+ exports: [
+ SubstitutionFilterComponent
+ ],
+ entryComponents: [
+ SubstitutionFilterComponent
+ ],
+ providers: []
+})
+export class SubstitutionFilterModule {
+}