aboutsummaryrefslogtreecommitdiffstats
path: root/catalog-ui/src/app/ng2
diff options
context:
space:
mode:
authormiriame <miriam.eini@amdocs.com>2019-02-13 15:17:26 +0200
committermiriame <miriam.eini@amdocs.com>2019-02-14 10:45:13 +0200
commitc2ce914541e694c7d1c8853b88936095e8b9ede4 (patch)
treed9d6dfa4b011c6868048d83a2116743b283b1cb1 /catalog-ui/src/app/ng2
parentd72aaa18d4dbfb8017dce566d9c41ccc00985528 (diff)
Add 'Service Dependencies' tab in composition page
Issue-ID: SDC-1987 Change-Id: Ib5b688c12234c81fe6f89b2b5d37dd16a75b0db9 Signed-off-by: miriame <miriam.eini@amdocs.com>
Diffstat (limited to 'catalog-ui/src/app/ng2')
-rw-r--r--catalog-ui/src/app/ng2/app.module.ts6
-rw-r--r--catalog-ui/src/app/ng2/components/logic/service-dependencies/service-dependencies.component.html35
-rw-r--r--catalog-ui/src/app/ng2/components/logic/service-dependencies/service-dependencies.component.less70
-rw-r--r--catalog-ui/src/app/ng2/components/logic/service-dependencies/service-dependencies.component.ts325
-rw-r--r--catalog-ui/src/app/ng2/components/logic/service-dependencies/service-dependencies.module.ts24
-rw-r--r--catalog-ui/src/app/ng2/components/ui/dynamic-element/dynamic-element.component.ts8
-rw-r--r--catalog-ui/src/app/ng2/components/ui/form-components/checkbox/checkbox.component.less13
-rw-r--r--catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component.html56
-rw-r--r--catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component.less43
-rw-r--r--catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component.ts192
-rw-r--r--catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.module.ts25
-rw-r--r--catalog-ui/src/app/ng2/services/component-services/component.service.ts44
-rw-r--r--catalog-ui/src/app/ng2/services/responses/component-generic-response.ts4
13 files changed, 835 insertions, 10 deletions
diff --git a/catalog-ui/src/app/ng2/app.module.ts b/catalog-ui/src/app/ng2/app.module.ts
index 750563b092..1ae2df2d82 100644
--- a/catalog-ui/src/app/ng2/app.module.ts
+++ b/catalog-ui/src/app/ng2/app.module.ts
@@ -60,6 +60,8 @@ import { ServicePathCreatorModule } from './pages/service-path-creator/service-p
import { ServicePathsListModule } from './pages/service-paths-list/service-paths-list.module';
import { ServicePathModule } from 'app/ng2/components/logic/service-path/service-path.module';
import { ServicePathSelectorModule } from 'app/ng2/components/logic/service-path-selector/service-path-selector.module';
+import {ServiceDependenciesModule} from 'app/ng2/components/logic/service-dependencies/service-dependencies.module';
+import {ServiceDependenciesEditorModule} from './pages/service-dependencies-editor/service-dependencies-editor.module';
import { CompositionPanelModule } from 'app/ng2/pages/composition/panel/panel.module';
import { WindowRef } from "./services/window.service";
import {ArchiveService} from "./services/archive.service";
@@ -110,7 +112,9 @@ export function configServiceFactory(config: ConfigService) {
ServicePathCreatorModule,
ServicePathsListModule,
ServicePathModule,
- ServicePathSelectorModule
+ ServicePathSelectorModule,
+ ServiceDependenciesModule,
+ ServiceDependenciesEditorModule
],
exports: [],
entryComponents: [
diff --git a/catalog-ui/src/app/ng2/components/logic/service-dependencies/service-dependencies.component.html b/catalog-ui/src/app/ng2/components/logic/service-dependencies/service-dependencies.component.html
new file mode 100644
index 0000000000..d71a4fbecb
--- /dev/null
+++ b/catalog-ui/src/app/ng2/components/logic/service-dependencies/service-dependencies.component.html
@@ -0,0 +1,35 @@
+<div class="service-dependencies">
+ <loader [display]="isLoading" [size]="'medium'" [relative]="true"></loader>
+ <div class="checkbox-label-mark-as-dependent">
+ <checkbox
+ class="checkbox-label"
+ data-tests-id="checkbox-mark-as-dependent"
+ [label]="'Mark as Dependent'"
+ (checkedChange)="onMarkAsDependent()"
+ [(checked)]="isDependent"
+ [disabled]="readonly">
+ </checkbox>
+ </div>
+ <div class="i-sdc-designer-sidebar-section-content-item-rules-section" *ngIf="isDependent">
+
+ <div class="i-sdc-designer-sidebar-section-content-item-rule" [ngClass]="{'hand': !readonly}"
+ *ngFor="let rule of rulesList; let i = index">
+ <div class="rule-details" [ngClass]="{'readonly': readonly}">
+ <div class="rule-desc" (click)="!readonly && onSelectRule(i)" tooltips tooltip="{{rule.servicePropertyName + ' ' + getSymbol(rule.constraintOperator) + ' ' + (rule.sourceName ? rule.sourceName + ':' : '') + rule.value}}">
+ {{rule.servicePropertyName + ' ' + getSymbol(rule.constraintOperator) + ' ' + (rule.sourceName ? rule.sourceName + ':' : '') + rule.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 class="w-sdc-designer-sidebar-section-footer" >
+ <button
+ class="w-sdc-designer-sidebar-section-footer-action add-rule-btn tlv-btn blue"
+ data-tests-id="add-rule-button"
+ (click)="onAddRule()"
+ [disabled]="readonly">
+ {{'SERVICE_DEPENDENCY_ADD_RULE' | translate}}
+ </button>
+ </div>
+ </div>
+</div> \ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/components/logic/service-dependencies/service-dependencies.component.less b/catalog-ui/src/app/ng2/components/logic/service-dependencies/service-dependencies.component.less
new file mode 100644
index 0000000000..ae990dc85f
--- /dev/null
+++ b/catalog-ui/src/app/ng2/components/logic/service-dependencies/service-dependencies.component.less
@@ -0,0 +1,70 @@
+@import './../../../../../assets/styles/variables.less';
+@import './../../../../../assets/styles/variables-old.less';
+@import './../../../../../assets/styles/mixins_old.less';
+@import './../../../../../assets/styles/mixins.less';
+
+.service-dependencies {
+
+ /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;
+ }
+
+ 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;
+ }
+
+ }
+ }
+} \ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/components/logic/service-dependencies/service-dependencies.component.ts b/catalog-ui/src/app/ng2/components/logic/service-dependencies/service-dependencies.component.ts
new file mode 100644
index 0000000000..ac87576540
--- /dev/null
+++ b/catalog-ui/src/app/ng2/components/logic/service-dependencies/service-dependencies.component.ts
@@ -0,0 +1,325 @@
+/*!
+ * Copyright © 2016-2018 European Support Limited
+ *
+ * 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.
+ */
+import {Component, Input, Output, EventEmitter, ComponentRef} from '@angular/core';
+import {ModalService} from 'app/ng2/services/modal.service';
+import {Service, ComponentInstance, ModalModel, ButtonModel, PropertyBEModel, ServiceInstanceObject} from 'app/models';
+import {ServiceDependenciesEditorComponent} from 'app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component';
+import {ModalComponent} from 'app/ng2/components/ui/modal/modal.component';
+import {ComponentServiceNg2} from 'app/ng2/services/component-services/component.service';
+import {TranslateService} from 'app/ng2/shared/translator/translate.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) {
+ let 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 uncheckModalTitle: string;
+ static uncheckModalText: string;
+ static modalApprove: string;
+ static modalCancel: string;
+ static modalCreate: string;
+ static modalSave: string;
+ static modalDelete: string;
+ static addRuleTxt: string;
+ static updateRuleTxt: string;
+ static deleteRuleTxt: string;
+ static deleteRuleMsg: string;
+
+ public static translateTexts(translateService) {
+ I18nTexts.uncheckModalTitle = translateService.translate("SERVICE_DEPENDENCY_UNCHECK_TITLE");
+ I18nTexts.uncheckModalText = translateService.translate("SERVICE_DEPENDENCY_UNCHECK_TEXT");
+ I18nTexts.modalApprove = translateService.translate("MODAL_APPROVE");
+ 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.addRuleTxt = translateService.translate("SERVICE_DEPENDENCY_ADD_RULE");
+ I18nTexts.updateRuleTxt = translateService.translate("SERVICE_DEPENDENCY_UPDATE_RULE");
+ I18nTexts.deleteRuleTxt = translateService.translate("SERVICE_DEPENDENCY_DELETE_RULE");
+ I18nTexts.deleteRuleMsg = translateService.translate("SERVICE_DEPENDENCY_DELETE_RULE_MSG");
+ }
+}
+
+
+@Component({
+ selector: 'service-dependencies',
+ templateUrl: './service-dependencies.component.html',
+ styleUrls: ['service-dependencies.component.less'],
+ providers: [ModalService, TranslateService]
+})
+
+export class ServiceDependenciesComponent {
+ modalInstance: ComponentRef<ModalComponent>;
+ isDependent: boolean;
+ isLoading: boolean;
+ compositeServiceProperties: Array<PropertyBEModel> = [];
+ rulesList: Array<ConstraintObject> = [];
+ operatorTypes: Array<any>;
+
+ @Input() readonly: boolean;
+ @Input() compositeService: Service;
+ @Input() currentServiceInstance: ComponentInstance;
+ @Input() selectedInstanceSiblings: Array<ServiceInstanceObject>;
+ @Input() selectedInstanceConstraints: Array<ConstraintObject> = [];
+ @Input() selectedInstanceProperties: Array<PropertyBEModel> = [];
+ @Output() updateRulesListEvent:EventEmitter<Array<ConstraintObject>> = new EventEmitter<Array<ConstraintObject>>();
+ @Output() loadRulesListEvent:EventEmitter<any> = new EventEmitter();
+ @Output() dependencyStatus = new EventEmitter<boolean>();
+
+
+ constructor(private componentServiceNg2: ComponentServiceNg2, 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.componentServiceNg2.getServiceProperties(this.compositeService).subscribe((properties: Array<PropertyBEModel>) => {
+ this.compositeServiceProperties = properties;
+ });
+ this.loadRules();
+ this.translateService.languageChangedObservable.subscribe(lang => {
+ I18nTexts.translateTexts(this.translateService);
+ });
+ }
+
+ ngOnChanges(changes) {
+ if(changes.currentServiceInstance) {
+ this.currentServiceInstance = changes.currentServiceInstance.currentValue;
+ this.isDependent = this.currentServiceInstance.isDependent();
+ }
+ if(changes.selectedInstanceConstraints && changes.selectedInstanceConstraints.currentValue !== changes.selectedInstanceConstraints.previousValue) {
+ this.selectedInstanceConstraints = changes.selectedInstanceConstraints.currentValue;
+ this.loadRules();
+ }
+ }
+
+ public openRemoveDependencyModal = (): ComponentRef<ModalComponent> => {
+ let actionButton: ButtonModel = new ButtonModel(I18nTexts.modalApprove, 'blue', this.onUncheckDependency);
+ let cancelButton: ButtonModel = new ButtonModel(I18nTexts.modalCancel, 'grey', this.onCloseRemoveDependencyModal);
+ let modalModel: ModalModel = new ModalModel('sm', I18nTexts.uncheckModalTitle, I18nTexts.uncheckModalText, [actionButton, cancelButton]);
+ return this.ModalServiceNg2.createCustomModal(modalModel);
+ }
+
+ loadRules() {
+ this.rulesList = this.selectedInstanceConstraints && this.selectedInstanceConstraints.map((co: ConstraintObject) => ({
+ servicePropertyName: co.servicePropertyName,
+ constraintOperator: co.constraintOperator,
+ sourceType: co.sourceType,
+ sourceName: co.sourceName !== 'SELF' ? co.sourceName : this.compositeService.name,
+ value: co.value,
+ }));
+ }
+
+ onUncheckDependency = () => {
+ this.ModalServiceNg2.closeCurrentModal();
+ this.isLoading = true;
+ let isDepOrig = this.isDependent;
+ let rulesListOrig = this.rulesList;
+ this.currentServiceInstance.unmarkAsDependent();
+ this.updateComponentInstance(isDepOrig, rulesListOrig);
+ }
+
+ onCloseRemoveDependencyModal = () => {
+ this.isDependent = true;
+ this.ModalServiceNg2.closeCurrentModal();
+ }
+
+ onCheckDependency = () => {
+ let isDepOrig = this.isDependent;
+ let rulesListOrig = this.rulesList;
+ this.currentServiceInstance.markAsDependent();
+ this.rulesList = [];
+ this.updateComponentInstance(isDepOrig, rulesListOrig);
+ }
+
+ onMarkAsDependent() {
+ if(!this.currentServiceInstance.isDependent()) {
+ this.onCheckDependency();
+ }
+ else {
+ this.openRemoveDependencyModal().instance.open();
+ }
+ }
+
+ updateComponentInstance(isDependent_origVal : boolean, rulesList_orig: Array<ConstraintObject>) {
+ this.isLoading = true;
+ this.componentServiceNg2.updateComponentInstance(this.compositeService, this.currentServiceInstance).subscribe((updatedServiceIns: ComponentInstance) => {
+ this.currentServiceInstance = new ComponentInstance(updatedServiceIns);
+ this.isDependent = this.currentServiceInstance.isDependent();
+ this.dependencyStatus.emit(this.isDependent);
+ if(this.isDependent) {
+ this.loadRulesListEvent.emit();
+ }
+ this.isLoading = false;
+ }, err=> {
+ this.isDependent = isDependent_origVal;
+ this.rulesList = rulesList_orig;
+ this.isLoading = false;
+ console.log('An error has occurred.');
+ });
+ }
+
+ onAddRule () {
+ let cancelButton: ButtonModel = new ButtonModel(I18nTexts.modalCancel, 'outline white', this.ModalServiceNg2.closeCurrentModal);
+ let saveButton: ButtonModel = new ButtonModel(I18nTexts.modalCreate, 'blue', this.createRule, this.getDisabled);
+ let modalModel: ModalModel = new ModalModel('l', I18nTexts.addRuleTxt, '', [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,
+ compositeServiceProperties: this.compositeServiceProperties,
+ selectedInstanceProperties: this.selectedInstanceProperties,
+ selectedInstanceSiblings: this.selectedInstanceSiblings
+ }
+ );
+ this.modalInstance.instance.open();
+ }
+
+ onSelectRule(index: number) {
+ let cancelButton: ButtonModel = new ButtonModel(I18nTexts.modalCancel, 'outline white', this.ModalServiceNg2.closeCurrentModal);
+ let saveButton: ButtonModel = new ButtonModel(I18nTexts.modalSave, 'blue', () => this.updateRules(), this.getDisabled);
+ let modalModel: ModalModel = new ModalModel('l', I18nTexts.updateRuleTxt, '', [saveButton, cancelButton], 'standard');
+ this.modalInstance = this.ModalServiceNg2.createCustomModal(modalModel);
+ this.ModalServiceNg2.addDynamicContentToModal(
+ this.modalInstance,
+ ServiceDependenciesEditorComponent,
+ {
+ serviceRuleIndex: index,
+ serviceRules: _.map(this.rulesList, rule => new ConstraintObjectUI(rule)),
+ currentServiceName: this.currentServiceInstance.name,
+ operatorTypes: this.operatorTypes,
+ compositeServiceName: this.compositeService.name,
+ compositeServiceProperties: this.compositeServiceProperties,
+ selectedInstanceProperties: this.selectedInstanceProperties,
+ selectedInstanceSiblings: this.selectedInstanceSiblings
+ }
+ );
+ this.modalInstance.instance.open();
+ }
+
+ getDisabled = ():boolean => {
+ return !this.modalInstance.instance.dynamicContent.instance.checkFormValidForSubmit();
+ };
+
+ createRule = ():void => {
+ let newRuleToCreate: ConstraintObject = new ConstraintObject(this.modalInstance.instance.dynamicContent.instance.currentRule);
+ this.isLoading = true;
+ this.componentServiceNg2.createServiceFilterConstraints(
+ this.compositeService,
+ this.currentServiceInstance,
+ newRuleToCreate
+ ).subscribe( (response) => {
+ this.updateRulesListEvent.emit(response.properties);
+ this.isLoading = false;
+ }, err=> {
+ this.isLoading = false;
+ });
+ this.ModalServiceNg2.closeCurrentModal();
+ };
+
+ updateRules = ():void => {
+ let allRulesToUpdate: Array<ConstraintObject> = this.modalInstance.instance.dynamicContent.instance.serviceRulesList.map(rule => new ConstraintObject(rule));
+ this.isLoading = true;
+ this.componentServiceNg2.updateServiceFilterConstraints(
+ this.compositeService,
+ this.currentServiceInstance,
+ allRulesToUpdate
+ ).subscribe((response) => {
+ this.updateRulesListEvent.emit(response.properties);
+ this.isLoading = false;
+ }, err => {
+ this.isLoading = false;
+ });
+ this.ModalServiceNg2.closeCurrentModal();
+ }
+
+ getSymbol(constraintOperator) {
+ switch (constraintOperator) {
+ case OPERATOR_TYPES.LESS_THAN: return '<';
+ case OPERATOR_TYPES.EQUAL: return '=';
+ case OPERATOR_TYPES.GREATER_THAN: return '>';
+ }
+ }
+
+ onDeleteRule = (index:number) => {
+ this.isLoading = true;
+ this.componentServiceNg2.deleteServiceFilterConstraints(
+ this.compositeService,
+ this.currentServiceInstance,
+ index
+ ).subscribe( (response) => {
+ this.updateRulesListEvent.emit(response.properties);
+ this.isLoading = false;
+ }, err=> {
+ this.isLoading = false;
+ });
+ this.ModalServiceNg2.closeCurrentModal();
+ };
+
+ openDeleteModal = (index:number) => {
+ this.ModalServiceNg2.createActionModal(I18nTexts.deleteRuleTxt, I18nTexts.deleteRuleMsg,
+ I18nTexts.modalDelete, () => this.onDeleteRule(index), I18nTexts.modalCancel).instance.open();
+ }
+} \ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/components/logic/service-dependencies/service-dependencies.module.ts b/catalog-ui/src/app/ng2/components/logic/service-dependencies/service-dependencies.module.ts
new file mode 100644
index 0000000000..7e66ed99c7
--- /dev/null
+++ b/catalog-ui/src/app/ng2/components/logic/service-dependencies/service-dependencies.module.ts
@@ -0,0 +1,24 @@
+
+import { NgModule } from "@angular/core";
+import {CommonModule} from "@angular/common";
+import {ServiceDependenciesComponent} from "./service-dependencies.component";
+import {UiElementsModule} from "app/ng2/components/ui/ui-elements.module";
+import {TranslateModule} from 'app/ng2/shared/translator/translate.module';
+
+@NgModule({
+ declarations: [
+ ServiceDependenciesComponent
+ ],
+ imports: [
+ CommonModule,
+ UiElementsModule,
+ TranslateModule
+ ],
+ exports: [],
+ entryComponents: [
+ ServiceDependenciesComponent
+ ],
+ providers: []
+})
+export class ServiceDependenciesModule {
+} \ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/components/ui/dynamic-element/dynamic-element.component.ts b/catalog-ui/src/app/ng2/components/ui/dynamic-element/dynamic-element.component.ts
index 76b0b9ec2b..4f283fb3f1 100644
--- a/catalog-ui/src/app/ng2/components/ui/dynamic-element/dynamic-element.component.ts
+++ b/catalog-ui/src/app/ng2/components/ui/dynamic-element/dynamic-element.component.ts
@@ -175,8 +175,12 @@ export class DynamicElementComponent {
tmp.push(new DropdownValue(true,'TRUE'));
tmp.push(new DropdownValue(false,'FALSE'));
this.cmpRef.instance.values = tmp;
- if(!_.isUndefined(this.value)){//contains the real value (and not a string)
- this.value = JSON.parse(this.value);
+ try {
+ if (typeof this.value === 'string') {
+ this.value = JSON.parse(this.value);
+ }
+ } catch(err) {
+ this.value = null;
}
break;
diff --git a/catalog-ui/src/app/ng2/components/ui/form-components/checkbox/checkbox.component.less b/catalog-ui/src/app/ng2/components/ui/form-components/checkbox/checkbox.component.less
index 9df2680b6f..5c061a4b5e 100644
--- a/catalog-ui/src/app/ng2/components/ui/form-components/checkbox/checkbox.component.less
+++ b/catalog-ui/src/app/ng2/components/ui/form-components/checkbox/checkbox.component.less
@@ -38,11 +38,16 @@
width:0;
height:0;
display:none;
- &:checked ~ .checkbox-icon::before{
- .sprite-new;
- .filled-checkbox-icon
+ &:checked {
+ ~ .checkbox-icon::before{
+ .sprite-new;
+ .filled-checkbox-icon
+ }
+ &[disabled] ~ .checkbox-icon::before {
+ opacity: 0.5;
+ }
}
- &[disabled] ~ .checkbox-icon::before {
+ &[disabled]:not(:checked) ~ .checkbox-icon::before {
/* TODO: add disabled styles here */
background-image: none;
background-color: #EFEFEF;
diff --git a/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component.html b/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component.html
new file mode 100644
index 0000000000..f22e454332
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component.html
@@ -0,0 +1,56 @@
+<div class="service-dependencies-editor">
+ <form class="w-sdc-form">
+
+ <div class="sdc-modal-top-bar">
+ <div class="sdc-modal-top-bar-buttons" *ngIf="currentIndex >= 0">
+ <span (click)="onChangePage(currentIndex - 1)" [ngClass]="{'disabled' : currentIndex === 0}" class="sprite-new left-arrow" data-tests-id="get-prev-rule" tooltip="Previous"></span>
+ <span (click)="onChangePage(currentIndex + 1)" [ngClass]="{'disabled' : currentIndex === input.serviceRules.length - 1}" class="sprite-new right-arrow" data-tests-id="get-next-rule" tooltip="Next"></span>
+ </div>
+ </div>
+
+ <loader [display]="isLoading" [size]="'large'" [relative]="true"></loader>
+
+ <div class="i-sdc-form-content">
+ <div class="rule-builder-content">
+ <div class="i-sdc-form-item rule-input-field">
+ <label class="i-sdc-form-label required">Service {{currentServiceName}} Property</label>
+ <ui-element-dropdown
+ class="i-sdc-form-select"
+ data-tests-id="servicePropertyName"
+ [values]="ddValueSelectedServicePropertiesNames"
+ [(value)]="currentRule.servicePropertyName"
+ (change)="onServicePropertyChanged()">
+ </ui-element-dropdown>
+ </div>
+
+ <div class="i-sdc-form-item rule-input-field operator">
+ <ui-element-dropdown class="i-sdc-form-select" data-tests-id="constraintOperator" [values]="operatorTypes" [(value)]="currentRule.constraintOperator"></ui-element-dropdown>
+ </div>
+
+ <div class="i-sdc-form-item rule-input-field">
+ <label class="i-sdc-form-label required" >Source</label>
+ <ui-element-dropdown class="i-sdc-form-select" data-tests-id="sourceType" [values]="sourceTypes" [(value)]="currentRule.sourceName" (change)="onSelectSourceType($event)"></ui-element-dropdown>
+ </div>
+
+ <div class="rule-input-field assigned-value-field">
+ <label class="i-sdc-form-label required" >{{assignedValueLabel}}</label>
+ <dynamic-element
+ *ngIf="currentRule.sourceType === SOURCE_TYPES.STATIC.value"
+ [(value)]="currentRule.value"
+ class="rule-assigned-value"
+ data-tests-id="ruleAssignedValue"
+ (elementChanged)="onValueChange($event.isValid)"
+ [type]="selectedPropertyObj ? selectedPropertyObj.type : 'string'">
+ </dynamic-element>
+ <ui-element-dropdown *ngIf="currentRule.sourceType !== SOURCE_TYPES.STATIC.value"
+ class="rule-assigned-value"
+ data-tests-id="ruleAssignedValue"
+ [(value)]="currentRule.value"
+ [values]="listOfValuesToAssign">
+ </ui-element-dropdown>
+ </div>
+ </div>
+ </div>
+ </form>
+
+</div> \ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component.less b/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component.less
new file mode 100644
index 0000000000..e03b73c8c0
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component.less
@@ -0,0 +1,43 @@
+@import './../../../../assets/styles/variables.less';
+
+.sdc-modal-top-bar {
+ display: flex;
+ justify-content: flex-end;
+}
+
+.i-sdc-form-content {
+ display: flex;
+ flex-direction: column;
+ margin-top: 10px;
+ padding-bottom: 20px;
+
+ .i-sdc-form-item {
+ width: 250px;
+ &.operation {
+ width: 60px;
+ }
+ }
+
+ .rule-builder-content {
+ display: flex;
+ align-items: flex-end;
+ .rule-input-field {
+ flex: 1;
+ &:not(:last-of-type) {
+ margin-right: 20px;
+ }
+ &.operator{
+ width: 55px;
+ flex: 0 1 auto;
+ }
+ &.assigned-value-field {
+ margin-bottom: 10px;
+ }
+ /deep/ ui-element-dropdown select,
+ /deep/ ui-element-input input {
+ height: 30px;
+ }
+ }
+
+ }
+} \ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component.ts b/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component.ts
new file mode 100644
index 0000000000..db5e7a9a31
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component.ts
@@ -0,0 +1,192 @@
+/*!
+ * Copyright © 2016-2018 European Support Limited
+ *
+ * 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.
+ */
+import { Component } from '@angular/core';
+import {ServiceServiceNg2} from "app/ng2/services/component-services/service.service";
+import {ConstraintObjectUI, OPERATOR_TYPES} from 'app/ng2/components/logic/service-dependencies/service-dependencies.component';
+import {ServiceInstanceObject, PropertyBEModel} from 'app/models';
+import { PROPERTY_DATA } from 'app/utils';
+import {DropdownValue} from 'app/ng2/components/ui/form-components/dropdown/ui-element-dropdown.component';
+
+export class UIDropDownSourceTypesElement extends DropdownValue{
+ options: Array<any>;
+ assignedLabel: string;
+ type: string;
+ constructor(input?: any){
+ if(input) {
+ let value = input.value || '';
+ let label = input.label || '';
+ super(value, label);
+ this.options = input.options;
+ this.assignedLabel = input.assignedLabel;
+ this.type = input.type;
+ }
+ }
+}
+
+@Component({
+ selector: 'service-dependencies-editor',
+ templateUrl: './service-dependencies-editor.component.html',
+ styleUrls:['./service-dependencies-editor.component.less'],
+ providers: [ServiceServiceNg2]
+})
+
+export class ServiceDependenciesEditorComponent {
+
+ input: {
+ serviceRuleIndex: number,
+ serviceRules: Array<ConstraintObjectUI>,
+ compositeServiceName: string,
+ currentServiceName: string,
+ compositeServiceProperties: Array<PropertyBEModel>,
+ selectedInstanceProperties: Array<PropertyBEModel>,
+ operatorTypes: Array<DropdownValue>,
+ selectedInstanceSiblings: Array<ServiceInstanceObject>
+ };
+ currentServiceName: string;
+ selectedServiceProperties: Array<PropertyBEModel>;
+ selectedPropertyObj: PropertyBEModel;
+ ddValueSelectedServicePropertiesNames: Array<DropdownValue>;
+ operatorTypes: Array<DropdownValue>;
+ sourceTypes: Array<UIDropDownSourceTypesElement> = [];
+ currentRule: ConstraintObjectUI;
+ currentIndex: number;
+ listOfValuesToAssign: Array<DropdownValue>;
+ listOfSourceOptions: Array<PropertyBEModel>;
+ assignedValueLabel: string;
+ serviceRulesList: Array<ConstraintObjectUI>;
+
+
+ SOURCE_TYPES = {
+ STATIC: {label: 'Static', value: 'static'},
+ SERVICE_PROPERTY: {label: 'Service Property', value: 'property'}
+ };
+
+
+ ngOnInit() {
+ this.currentIndex = this.input.serviceRuleIndex;
+ this.serviceRulesList = this.input.serviceRules;
+ this.currentRule = this.serviceRulesList && this.input.serviceRuleIndex >= 0 ?
+ this.serviceRulesList[this.input.serviceRuleIndex]:
+ new ConstraintObjectUI({sourceName: this.SOURCE_TYPES.STATIC.value, sourceType: this.SOURCE_TYPES.STATIC.value, value: "", constraintOperator: OPERATOR_TYPES.EQUAL});
+ this.currentServiceName = this.input.currentServiceName;
+ this.operatorTypes = this.input.operatorTypes;
+ this.selectedServiceProperties = this.input.selectedInstanceProperties;
+ this.ddValueSelectedServicePropertiesNames = _.map(this.input.selectedInstanceProperties, prop => new DropdownValue(prop.name, prop.name));
+ this.initSourceTypes();
+ this.syncRuleData();
+ this.updateSourceTypesRelatedValues();
+ }
+
+ initSourceTypes() {
+ this.sourceTypes.push({label: this.SOURCE_TYPES.STATIC.label, value: this.SOURCE_TYPES.STATIC.value,
+ options: [], assignedLabel: this.SOURCE_TYPES.STATIC.label, type: this.SOURCE_TYPES.STATIC.value});
+ this.sourceTypes.push({
+ label: this.input.compositeServiceName,
+ value: this.input.compositeServiceName,
+ assignedLabel: this.SOURCE_TYPES.SERVICE_PROPERTY.label,
+ type: this.SOURCE_TYPES.SERVICE_PROPERTY.value,
+ options: this.input.compositeServiceProperties
+ });
+ _.forEach(this.input.selectedInstanceSiblings, sib =>
+ this.sourceTypes.push({
+ label: sib.name,
+ value: sib.name,
+ options: sib.properties || [],
+ assignedLabel: this.SOURCE_TYPES.SERVICE_PROPERTY.label,
+ type: this.SOURCE_TYPES.SERVICE_PROPERTY.value
+ })
+ );
+ }
+
+ syncRuleData() {
+ if(!this.currentRule.sourceName && this.currentRule.sourceType === this.SOURCE_TYPES.STATIC.value) {
+ this.currentRule.sourceName = this.SOURCE_TYPES.STATIC.value;
+ }
+ this.selectedPropertyObj = _.find(this.selectedServiceProperties, prop => prop.name === this.currentRule.servicePropertyName);
+ this.updateOperatorTypesList();
+ this.updateSourceTypesRelatedValues();
+ }
+
+ updateOperatorTypesList() {
+ if (this.selectedPropertyObj && PROPERTY_DATA.SIMPLE_TYPES_COMPARABLE.indexOf(this.selectedPropertyObj.type) === -1) {
+ this.operatorTypes = [{label: "=", value: OPERATOR_TYPES.EQUAL}];
+ this.currentRule.constraintOperator = OPERATOR_TYPES.EQUAL;
+ }
+ else {
+ this.operatorTypes = this.input.operatorTypes;
+ }
+ }
+
+ updateSourceTypesRelatedValues() {
+ if(this.currentRule.sourceName) {
+ let selectedSourceType: UIDropDownSourceTypesElement = this.sourceTypes.find(
+ t => t.value === this.currentRule.sourceName && t.type === this.currentRule.sourceType
+ );
+ this.listOfSourceOptions = selectedSourceType.options || [];
+ this.assignedValueLabel = selectedSourceType.assignedLabel || this.SOURCE_TYPES.STATIC.label;
+ this.filterOptionsByType();
+ }
+ }
+
+ onChangePage(newIndex) {
+ if (newIndex >= 0 && newIndex < this.input.serviceRules.length) {
+ this.currentIndex = newIndex;
+ this.currentRule = this.serviceRulesList[newIndex];
+ this.syncRuleData();
+ }
+ }
+
+ onServicePropertyChanged() {
+ this.selectedPropertyObj = _.find(this.selectedServiceProperties, prop => prop.name === this.currentRule.servicePropertyName);
+ this.updateOperatorTypesList();
+ this.filterOptionsByType();
+ this.currentRule.value = '';
+ }
+
+ onSelectSourceType() {
+ this.currentRule.sourceType = this.currentRule.sourceName === this.SOURCE_TYPES.STATIC.value ?
+ this.SOURCE_TYPES.STATIC.value :
+ this.SOURCE_TYPES.SERVICE_PROPERTY.value;
+ this.updateSourceTypesRelatedValues();
+ this.currentRule.value = '';
+ }
+
+ filterOptionsByType() {
+ if(!this.selectedPropertyObj) {
+ this.listOfValuesToAssign = [];
+ return;
+ }
+ this.listOfValuesToAssign = this.listOfSourceOptions.reduce((result, op:PropertyBEModel) => {
+ if(op.type === this.selectedPropertyObj.type && op.schemaType === this.selectedPropertyObj.schemaType) {
+ result.push(new DropdownValue(op.name, op.name));
+ }
+ return result;
+ }, []);
+ }
+
+ onValueChange(isValidValue) {
+ this.currentRule.updateValidity(isValidValue);
+ }
+
+ checkFormValidForSubmit() {
+ if(!this.serviceRulesList) { //for create modal
+ let isStatic = this.currentRule.sourceName === this.SOURCE_TYPES.STATIC.value;
+ return this.currentRule.isValidRule(isStatic);
+ }
+ //for update all rules
+ return this.serviceRulesList.every(rule => rule.isValidRule(rule.sourceName === this.SOURCE_TYPES.STATIC.value));
+ }
+} \ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.module.ts b/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.module.ts
new file mode 100644
index 0000000000..98ac997bf7
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.module.ts
@@ -0,0 +1,25 @@
+import { NgModule } from "@angular/core";
+import {CommonModule} from "@angular/common";
+import {ServiceDependenciesEditorComponent} from "./service-dependencies-editor.component";
+import {FormsModule} from "@angular/forms";
+import {FormElementsModule} from "app/ng2/components/ui/form-components/form-elements.module";
+import {UiElementsModule} from "app/ng2/components/ui/ui-elements.module";
+
+@NgModule({
+ declarations: [
+ ServiceDependenciesEditorComponent
+ ],
+ imports: [
+ CommonModule,
+ FormsModule,
+ FormElementsModule,
+ UiElementsModule
+ ],
+ exports: [],
+ entryComponents: [
+ ServiceDependenciesEditorComponent
+ ],
+ providers: []
+})
+export class ServiceDependenciesEditorModule {
+} \ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/services/component-services/component.service.ts b/catalog-ui/src/app/ng2/services/component-services/component.service.ts
index 69871abe04..e9036a805d 100644
--- a/catalog-ui/src/app/ng2/services/component-services/component.service.ts
+++ b/catalog-ui/src/app/ng2/services/component-services/component.service.ts
@@ -24,15 +24,17 @@ import {Observable} from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/toPromise';
import {Response, URLSearchParams} from '@angular/http';
-import { Component, InputBEModel, InstancePropertiesAPIMap, FilterPropertiesAssignmentData, PropertyBEModel, OperationModel, BEOperationModel, CreateOperationResponse} from "app/models";
+import { Component, ComponentInstance, InputBEModel, InstancePropertiesAPIMap, FilterPropertiesAssignmentData,
+ PropertyBEModel, OperationModel, BEOperationModel, CreateOperationResponse} from "app/models";
import {downgradeInjectable} from '@angular/upgrade/static';
-import {COMPONENT_FIELDS, CommonUtils} from "app/utils";
+import {COMPONENT_FIELDS, CommonUtils, SERVICE_FIELDS} from "app/utils";
import {ComponentGenericResponse} from "../responses/component-generic-response";
import {InstanceBePropertiesMap} from "../../../models/properties-inputs/property-fe-map";
import {API_QUERY_PARAMS} from "app/utils";
import { ComponentType, ServerTypeUrl } from "../../../utils/constants";
import { HttpService } from '../http.service';
import {SdcConfigToken, ISdcConfig} from "../../config/sdc-config.config";
+import {ConstraintObject} from 'app/ng2/components/logic/service-dependencies/service-dependencies.component';
import {IDependenciesServerResponse} from "../responses/dependencies-server-response";
import {AutomatedUpgradeGenericResponse} from "../responses/automated-upgrade-response";
import {IAutomatedUpgradeRequestObj} from "../../pages/automated-upgrade/automated-upgrade.service";
@@ -82,6 +84,10 @@ export class ComponentServiceNg2 {
return this.getComponentDataByFieldsName(component.componentType, component.uniqueId, [COMPONENT_FIELDS.COMPONENT_INSTANCES_PROPERTIES, COMPONENT_FIELDS.COMPONENT_INSTANCES_ATTRIBUTES]);
}
+ getComponentInstanceProperties(component:Component):Observable<ComponentGenericResponse> {
+ return this.getComponentDataByFieldsName(component.componentType, component.uniqueId, [COMPONENT_FIELDS.COMPONENT_INSTANCES_PROPERTIES]);
+ }
+
getComponentAttributes(component:Component):Observable<ComponentGenericResponse> {
return this.getComponentDataByFieldsName(component.componentType, component.uniqueId, [COMPONENT_FIELDS.COMPONENT_ATTRIBUTES]);
}
@@ -226,7 +232,7 @@ export class ComponentServiceNg2 {
return this.http.delete(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/delete/' + input.uniqueId + '/input')
.map((res:Response) => {
return new InputBEModel(res.json());
- })
+ });
}
updateComponentInputs(component:Component, inputs:InputBEModel[]):Observable<InputBEModel[]> {
@@ -297,5 +303,37 @@ export class ComponentServiceNg2 {
return res.json();
});
}
+
+ updateComponentInstance(component:Component, componentInstance:ComponentInstance):Observable<ComponentInstance> {
+ return this.http.post(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/resourceInstance/' + componentInstance.uniqueId, componentInstance)
+ .map((res:Response) => {
+ return res.json();
+ });
+ }
+
+ getServiceFilterConstraints(component:Component):Observable<ComponentGenericResponse> {
+ return this.getComponentDataByFieldsName(component.componentType, component.uniqueId, [SERVICE_FIELDS.NODE_FILTER]);
+ }
+
+ createServiceFilterConstraints(component:Component, componentInstance:ComponentInstance, constraint:ConstraintObject):Observable<any> {
+ return this.http.post(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/resourceInstances/' + componentInstance.uniqueId + '/nodeFilter', constraint)
+ .map((res:Response) => {
+ return res.json();
+ });
+ }
+
+ updateServiceFilterConstraints(component:Component, componentInstance:ComponentInstance, constraints:Array<ConstraintObject>):Observable<any> {
+ return this.http.put(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/resourceInstances/' + componentInstance.uniqueId + '/nodeFilter/', constraints)
+ .map((res:Response) => {
+ return res.json();
+ });
+ }
+
+ deleteServiceFilterConstraints(component:Component, componentInstance:ComponentInstance, constraintIndex:number) {
+ return this.http.delete(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/resourceInstances/' + componentInstance.uniqueId + '/nodeFilter/' + constraintIndex)
+ .map((res:Response) => {
+ return res.json();
+ });
+ }
}
diff --git a/catalog-ui/src/app/ng2/services/responses/component-generic-response.ts b/catalog-ui/src/app/ng2/services/responses/component-generic-response.ts
index 647cc927f7..37ccf381c9 100644
--- a/catalog-ui/src/app/ng2/services/responses/component-generic-response.ts
+++ b/catalog-ui/src/app/ng2/services/responses/component-generic-response.ts
@@ -52,6 +52,7 @@ export class ComponentGenericResponse implements Serializable<ComponentGenericR
public interfaceOperations:Array<OperationModel>;
public additionalInformation:any;
public derivedList:Array<any>;
+ public nodeFilterData: Array<any>;
deserialize (response): ComponentGenericResponse {
@@ -105,6 +106,9 @@ export class ComponentGenericResponse implements Serializable<ComponentGenericR
if(response.policies) {
this.policies = CommonUtils.initPolicies(response.policies);
}
+ if(response.nodeFilterData) {
+ this.nodeFilterData = response.nodeFilterData;
+ }
return this;
}
}