forked from winery/winery
-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
12 changed files
with
416 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
32 changes: 32 additions & 0 deletions
32
org.eclipse.winery.frontends/app/topologymodeler/src/app/enricher/enricher.component.css
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
/******************************************************************************** | ||
* Copyright (c) 2019 Contributors to the Eclipse Foundation | ||
* | ||
* See the NOTICE file(s) distributed with this work for additional | ||
* information regarding copyright ownership. | ||
* | ||
* This program and the accompanying materials are made available under the | ||
* terms of the Eclipse Public License 2.0 which is available at | ||
* http://www.eclipse.org/legal/epl-2.0, or the Apache Software License 2.0 | ||
* which is available at https://www.apache.org/licenses/LICENSE-2.0. | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 | ||
*******************************************************************************/ | ||
div.enrichmentContainer { | ||
margin-top: 1em; | ||
margin-left: 1em; | ||
margin-right: 1em; | ||
} | ||
|
||
a.title { | ||
font-weight: bold; | ||
} | ||
.innerContainer { | ||
margin: 1em auto; | ||
} | ||
|
||
button.btn.btn-sm { | ||
margin-left: 1em; | ||
margin-bottom: 1em; | ||
margin-right: 1em; | ||
width: 40%; | ||
} |
43 changes: 43 additions & 0 deletions
43
org.eclipse.winery.frontends/app/topologymodeler/src/app/enricher/enricher.component.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
~ Copyright (c) 2019 Contributors to the Eclipse Foundation | ||
~ | ||
~ See the NOTICE file(s) distributed with this work for additional | ||
~ information regarding copyright ownership. | ||
~ | ||
~ This program and the accompanying materials are made available under the | ||
~ terms of the Eclipse Public License 2.0 which is available at | ||
~ http://www.eclipse.org/legal/epl-2.0, or the Apache Software License 2.0 | ||
~ which is available at https://www.apache.org/licenses/LICENSE-2.0. | ||
~ | ||
~ SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 | ||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~--> | ||
|
||
<div id="EnricherView" *ngIf="availableFeatures" class="sidebar-root"> | ||
<div class="enrichmentContainer"> | ||
<a class="title">Management Feature Enrichment</a> | ||
<accordion> | ||
<accordion-group class="innerContainer" [isOpen]="i === 0" | ||
heading="{{availableFeatures[i].nodeTemplateId}}" | ||
panelClass="panel-info" | ||
(mouseover)="onHoverOver(entry)" | ||
(mouseleave)="hoverOut()" | ||
*ngFor="let entry of availableFeatures; let i = index;"> | ||
Available Enrichments: | ||
<div *ngFor="let feature of entry.features"> | ||
<input type="checkbox" (change)="featureSelectionChanged(feature, entry, $event)"> | ||
{{feature.featureName}} | ||
</div> | ||
</accordion-group> | ||
</accordion> | ||
</div> | ||
<div class="innerContainer"> | ||
<button type="button" class="btn btn-sm btn-primary" | ||
[disabled]="toApply.length===0" | ||
(click)="applyEnrichment()">Apply | ||
</button> | ||
<button type="button" class="btn btn-sm btn-danger" | ||
(click)="cancel()"> | ||
Cancel | ||
</button> | ||
</div> | ||
</div> |
214 changes: 214 additions & 0 deletions
214
org.eclipse.winery.frontends/app/topologymodeler/src/app/enricher/enricher.component.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,214 @@ | ||
/******************************************************************************* | ||
* Copyright (c) 2019 Contributors to the Eclipse Foundation | ||
* | ||
* See the NOTICE file(s) distributed with this work for additional | ||
* information regarding copyright ownership. | ||
* | ||
* This program and the accompanying materials are made available under the | ||
* terms of the Eclipse Public License 2.0 which is available at | ||
* http://www.eclipse.org/legal/epl-2.0, or the Apache Software License 2.0 | ||
* which is available at https://www.apache.org/licenses/LICENSE-2.0. | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 | ||
*******************************************************************************/ | ||
import { Component } from '@angular/core'; | ||
import { NgRedux } from '@angular-redux/store'; | ||
import { IWineryState } from '../redux/store/winery.store'; | ||
import { TopologyRendererActions } from '../redux/actions/topologyRenderer.actions'; | ||
import { WineryActions } from '../redux/actions/winery.actions'; | ||
import { TopologyRendererState } from '../redux/reducers/topologyRenderer.reducer'; | ||
import { HttpErrorResponse } from '@angular/common/http'; | ||
import { ToastrService } from 'ngx-toastr'; | ||
import { TTopologyTemplate } from '../models/ttopology-template'; | ||
import { Utils } from '../models/utils'; | ||
import { EnricherService } from './enricher.service'; | ||
import { Enrichment, FeatureEntity } from './enrichmentEntity'; | ||
|
||
@Component({ | ||
selector: 'winery-enricher', | ||
templateUrl: './enricher.component.html', | ||
styleUrls: ['./enricher.component.css'] | ||
}) | ||
export class EnricherComponent { | ||
|
||
// enrichment object containing available features | ||
availableFeatures: Enrichment; | ||
// array to store enrichment to be applied | ||
toApply = []; | ||
|
||
constructor(private ngRedux: NgRedux<IWineryState>, | ||
private actions: TopologyRendererActions, | ||
private wineryActions: WineryActions, | ||
private alert: ToastrService, | ||
private enricherService: EnricherService) { | ||
this.ngRedux.select(state => state.topologyRendererState) | ||
.subscribe(currentButtonsState => this.checkButtonsState(currentButtonsState)); | ||
} | ||
|
||
/** | ||
* This method checks the current button state of Winery UI to take action when the Enrichment Button was clicked. | ||
* @param currentButtonsState TopologyRendererState object containt state of Winery UI Buttons | ||
*/ | ||
private checkButtonsState(currentButtonsState: TopologyRendererState) { | ||
// check if Enrichment Button is clicked and available features are pulled | ||
if (currentButtonsState.buttonsState.enrichmentButton && !this.availableFeatures) { | ||
this.enricherService.getAvailableFeatures().subscribe( | ||
data => this.showAvailableFeatures(data), | ||
error => this.handleError(error) | ||
); | ||
// if button is unclicked, reset available features | ||
} else if (!currentButtonsState.buttonsState.enrichmentButton) { | ||
this.availableFeatures = null; | ||
} | ||
} | ||
|
||
/** | ||
* This method is called when the selection of a enrichment is changed. | ||
* It pushs/removes the selected/removed enrichment from the array of enrichments to be applied | ||
* @param feature: feature which changed | ||
* @param node: node template id where enrichment shall be applied later | ||
* @param event: selection changed event from checkbox | ||
*/ | ||
protected featureSelectionChanged(feature: FeatureEntity, node: Enrichment, event: any) { | ||
const isChecked = event.target.checked; | ||
const nodeTemplate = node.nodeTemplateId; | ||
// if a new feature was selected and to applicable enrichment array is empty or node template is not added yet | ||
if (isChecked && (this.toApply.length === 0) || !this.checkIfNodeTypeSelected(nodeTemplate)) { | ||
const selectedEnrichment = { | ||
nodeTemplateId: nodeTemplate, | ||
features: [] | ||
}; | ||
selectedEnrichment.features.push(feature); | ||
this.toApply.push(selectedEnrichment); | ||
// if feature was selected and node template id is already existing | ||
} else if (isChecked && this.checkIfNodeTypeSelected(nodeTemplate)) { | ||
this.toApply[this.checkWhichIndexNodeType(nodeTemplate)].features.push(feature); | ||
// if feature was unselected | ||
} else if (!event.target.checked && this.checkIfNodeTypeSelected(nodeTemplate)) { | ||
this.removeFeatureForNodeTemplate(feature, this.checkWhichIndexNodeType(nodeTemplate)); | ||
} | ||
} | ||
|
||
/** | ||
* This method checks whether to applicable enrichments array already contains an entry for a given node template. | ||
* @param nodeTemplateId: id of node template which shall be checked | ||
* @return boolean: true if array already contains node template, false else | ||
*/ | ||
private checkIfNodeTypeSelected(nodeTemplateId: string): boolean { | ||
for (const element of this.toApply) { | ||
// if entry node template matches node template we're searching for, return true | ||
if (element.nodeTemplateId === nodeTemplateId) { | ||
return true; | ||
} | ||
} | ||
// if node template id was not found after iterating over all entries, return false | ||
return false; | ||
} | ||
|
||
/** | ||
* This method returns the index of an node template entry in the to applicable enrichments array. | ||
* This is used to determine the entry which shall be removed when unselecting the last feature of a node template. | ||
* @param nodeTemplateId: id of node template to be checked | ||
* @return i: number of index of node template entry in to applicable enrichments array | ||
*/ | ||
private checkWhichIndexNodeType(nodeTemplateId: string): number { | ||
for (let i = 0; i < this.toApply.length; i++) { | ||
// if node template id is found, return the index of the entry | ||
if (this.toApply[i].nodeTemplateId === nodeTemplateId) { | ||
return i; | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* This method removes a feature of a node template entry in the to applicable enrichments array. | ||
* @param feature: feature entry which shall be modified | ||
* @param index: index of entry to be removed | ||
*/ | ||
private removeFeatureForNodeTemplate(feature: FeatureEntity, index: number): void { | ||
for (let i = 0; i < this.toApply[index].features.length; i++) { | ||
// check if feature is feature to be modified | ||
if (this.toApply[index].features[i] === feature) { | ||
this.toApply[index].features.splice(i, 1); | ||
} | ||
} | ||
// delete entry if no feature selected anymore | ||
if (this.toApply[index].features.length === 0) { | ||
this.toApply.splice(index, 1); | ||
} | ||
} | ||
|
||
/** | ||
* This method is called when clicking the "Apply" button. | ||
* It starts the Enricher Service to apply the selected enrichments. | ||
*/ | ||
protected applyEnrichment() { | ||
this.enricherService.applySelectedFeatures(this.toApply).subscribe( | ||
data => this.enrichmentApplied(data), | ||
error => this.handleError(error) | ||
); | ||
} | ||
|
||
/** | ||
* This method is called when available features are retrieved and fills the available features array with the | ||
* gathered data. | ||
* @param data: json response of backend containing available features for all node templates | ||
*/ | ||
private showAvailableFeatures(data: Enrichment): void { | ||
// check if array contains data at all (data != null does not work, as data is not null but an empty array) | ||
if (data.length > 0) { | ||
this.availableFeatures = data; | ||
} else { | ||
this.alert.info('No enrichment found!'); | ||
} | ||
} | ||
|
||
/** | ||
* This method is called when an error occurs durring fetching or pushing the enrichments. | ||
* It alerts the merror message in the UI. | ||
* @param error: error message | ||
*/ | ||
private handleError(error: HttpErrorResponse) { | ||
this.alert.error(error.message); | ||
} | ||
|
||
/** | ||
* This method is called when the User hovers over a node template in the enrichment sidebar | ||
* It highlights the respective node template in the topology modeler. | ||
* @param entry: entry of available features displayed in the UI | ||
*/ | ||
protected onHoverOver(entry: Enrichment) { | ||
const nodeTemplateIds: string[] = []; | ||
nodeTemplateIds.push(entry.nodeTemplateId); | ||
this.ngRedux.dispatch(this.actions.highlightNodes(nodeTemplateIds)); | ||
} | ||
|
||
/** | ||
* This method is called when the user hovers out of a node template. | ||
*/ | ||
protected hoverOut() { | ||
this.ngRedux.dispatch(this.actions.highlightNodes([])); | ||
} | ||
|
||
/** | ||
* This method is called when the User clicks "Cancel". | ||
* It resets the available features, which lets the enrichment sidebar disappear. | ||
*/ | ||
protected cancel() { | ||
this.availableFeatures = null; | ||
this.ngRedux.dispatch(this.actions.enrichNodeTemplates()); | ||
} | ||
|
||
/** | ||
* This method is called when the enrichment is successfully applied in the backend. | ||
* It updates the topology template then, resets the available features and displays an success message. | ||
* @param data: topology template that was updated | ||
*/ | ||
private enrichmentApplied(data: TTopologyTemplate) { | ||
Utils.updateTopologyTemplate(this.ngRedux, this.wineryActions, data); | ||
// reset available features since they are no longer valid | ||
this.availableFeatures = null; | ||
this.alert.success('Updated Topology Template!'); | ||
this.ngRedux.dispatch(this.actions.enrichNodeTemplates()); | ||
} | ||
} |
62 changes: 62 additions & 0 deletions
62
org.eclipse.winery.frontends/app/topologymodeler/src/app/enricher/enricher.service.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
/******************************************************************************* | ||
* Copyright (c) 2019 Contributors to the Eclipse Foundation | ||
* | ||
* See the NOTICE file(s) distributed with this work for additional | ||
* information regarding copyright ownership. | ||
* | ||
* This program and the accompanying materials are made available under the | ||
* terms of the Eclipse Public License 2.0 which is available at | ||
* http://www.eclipse.org/legal/epl-2.0, or the Apache Software License 2.0 | ||
* which is available at https://www.apache.org/licenses/LICENSE-2.0. | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 | ||
*******************************************************************************/ | ||
import { Injectable } from '@angular/core'; | ||
import { HttpClient, HttpHeaders } from '@angular/common/http'; | ||
import { BackendService } from '../services/backend.service'; | ||
import { TopologyModelerConfiguration } from '../models/topologyModelerConfiguration'; | ||
import { Observable } from 'rxjs'; | ||
import { Enrichment } from './enrichmentEntity'; | ||
import { TTopologyTemplate } from '../models/ttopology-template'; | ||
|
||
@Injectable({ | ||
providedIn: 'root' | ||
}) | ||
export class EnricherService { | ||
|
||
private readonly configuration: TopologyModelerConfiguration; | ||
private readonly httpHeaders: HttpHeaders; | ||
|
||
constructor(private http: HttpClient, | ||
backendService: BackendService) { | ||
this.configuration = backendService.configuration; | ||
this.httpHeaders = new HttpHeaders().set('Accept', 'application/json'); | ||
} | ||
|
||
/** | ||
* This method fetches available enrichments/features for a topology template. | ||
*/ | ||
getAvailableFeatures(): Observable<Enrichment> { | ||
const url = this.configuration.repositoryURL | ||
+ '/servicetemplates/' | ||
+ encodeURIComponent(encodeURIComponent(this.configuration.ns)) | ||
+ '/' | ||
+ encodeURIComponent(this.configuration.id) | ||
+ '/topologytemplate/availablefeatures'; | ||
return this.http.get<Enrichment>(url, { headers: this.httpHeaders }); | ||
} | ||
|
||
/** | ||
* This method applies selected enrichments/features for a topology template. | ||
* @param toApplyFeatures: Enrichment Object containing selected features for node templates. | ||
*/ | ||
applySelectedFeatures(toApplyFeatures: Enrichment[]): Observable<TTopologyTemplate> { | ||
const url = this.configuration.repositoryURL | ||
+ '/servicetemplates/' | ||
+ encodeURIComponent(encodeURIComponent(this.configuration.ns)) | ||
+ '/' | ||
+ encodeURIComponent(this.configuration.id) | ||
+ '/topologytemplate/availablefeatures'; | ||
return this.http.put<TTopologyTemplate>(url, toApplyFeatures, { headers: this.httpHeaders }); | ||
} | ||
} |
31 changes: 31 additions & 0 deletions
31
org.eclipse.winery.frontends/app/topologymodeler/src/app/enricher/enrichmentEntity.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
/******************************************************************************** | ||
* Copyright (c) 2019 Contributors to the Eclipse Foundation | ||
* | ||
* See the NOTICE file(s) distributed with this work for additional | ||
* information regarding copyright ownership. | ||
* | ||
* This program and the accompanying materials are made available under the | ||
* terms of the Eclipse Public License 2.0 which is available at | ||
* http://www.eclipse.org/legal/epl-2.0, or the Apache Software License 2.0 | ||
* which is available at https://www.apache.org/licenses/LICENSE-2.0. | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 | ||
*******************************************************************************/ | ||
import { QName } from '../models/qname'; | ||
|
||
/** | ||
* Enrichment interface containing features of FeatureEntity type and a node template id. | ||
*/ | ||
export interface Enrichment { | ||
features: FeatureEntity[]; | ||
nodeTemplateId: string; | ||
length: number; | ||
} | ||
|
||
/** | ||
* FeatureEntity interface containing type of the feature and the feature name. | ||
*/ | ||
export interface FeatureEntity { | ||
type: QName; | ||
featureName: string; | ||
} |
Oops, something went wrong.