Commit 0a402eff authored by Alexander Philipp Nowosad's avatar Alexander Philipp Nowosad
Browse files

Merge branch 'develop'

parents 59ce8828 27ffce5b
Pipeline #139491 canceled with stages
in 39 seconds
......@@ -54,7 +54,7 @@ def db(ctx, server, name):
@click.argument('initdata', type=click.File('rb'), nargs=-1)
@click.make_pass_decorator(Database)
def init(database, initdata):
management.init_db(database, initdata)
management.init_db(database, initdata=initdata)
click.secho(
'Sucessfully initialized database {}.'.format(database.name),
fg='green'
......
......@@ -21,14 +21,16 @@ def check_server_maintenance_mode(server):
def set_server_maintenance(server, value):
server.maintenance(value)
def init_db(database, initdata):
def init_db(database, initdata=None, docs=None):
if not Expressions.GROUP.match(database.name):
raise ManagementException(
'Database for group should have the form "group[0-9]+"'
)
database.create_if_not_exists()
if len(initdata) > 0:
if initdata is not None and len(initdata) > 0:
database.bulk_create(utils.import_docs(initdata))
if docs is not None:
database.bulk_create(docs)
database.security({
'members': { 'roles': ['_admin', database.name, 'mgmt_backup'] },
'admins': { 'roles': ['_admin'] }
......@@ -81,6 +83,7 @@ def init_server(server, usersfile, passwordsfile, initdata):
writer = utils.csv_writer(passwordsfile)
users = utils.import_csv(usersfile)
groups = defaultdict(list)
docs = utils.import_docs(initdata)
for i, (username, group) in enumerate(users):
if not Expressions.GROUP.match(group):
raise ManagementException(
......@@ -94,7 +97,7 @@ def init_server(server, usersfile, passwordsfile, initdata):
database.server = server
database.name = group
if not database.exists():
init_db(database, initdata)
init_db(database, docs=docs)
for username in users:
user = User()
user.server = server
......
......@@ -2,7 +2,7 @@ import { Injectable } from '@angular/core';
import { FeatureModel } from './feature-model';
import { Feature, FeatureType, SubfeatureConnectionsType } from './feature';
import { Instance } from './instance';
import { ConformanceReport } from './conformance-report';
import { ConformanceReport, PatternHint } from './conformance-report';
@Injectable({
providedIn: 'root',
......@@ -574,12 +574,12 @@ export class CanvasModelConsistencyService {
patterns: Instance[]
): {
patternHintFeatureIds: string[];
patternHints: string[];
usedPatterns: string[];
patternHints: PatternHint[];
usedPatterns: Instance[];
} {
const patternHintFeatureIds = new Set<string>();
const patternHints: string[] = [];
const usedPatterns: string[] = [];
const patternHints: PatternHint[] = [];
const usedPatterns: Instance[] = [];
patterns.forEach((pattern) => {
let leafFeatures = 0;
......@@ -607,11 +607,11 @@ export class CanvasModelConsistencyService {
if (usedLeafFeatures / leafFeatures >= 0.5) {
let hasMissingFeatures = false;
let isPossible = true;
let hint =
'You could add the pattern ' +
pattern.name +
' by adding the following features: ';
const featureIds = new Set<string>();
const hint: PatternHint = {
pattern: pattern,
missingFeatures: [],
};
const features = new Set<Feature>();
featureModel.iterateFeatures(
(feature) => {
if (!instance.usedFeatures.includes(feature.id)) {
......@@ -619,8 +619,7 @@ export class CanvasModelConsistencyService {
isPossible = false;
return true;
} else {
featureIds.add(feature.id);
hint += feature.name + ', ';
features.add(feature);
hasMissingFeatures = true;
}
}
......@@ -630,11 +629,13 @@ export class CanvasModelConsistencyService {
);
if (isPossible) {
if (hasMissingFeatures) {
hint = hint.substring(0, hint.length - 2);
hint.missingFeatures.push(...Array.from(features));
patternHints.push(hint);
featureIds.forEach((id) => patternHintFeatureIds.add(id));
features.forEach((feature) =>
patternHintFeatureIds.add(feature.id)
);
} else {
usedPatterns.push(pattern.name);
usedPatterns.push(pattern);
}
}
}
......
import { Instance } from './instance';
import { Feature } from './feature';
export interface PatternHint {
pattern: Instance;
missingFeatures: Feature[];
}
export class ConformanceReport {
errorFeatureIds: string[] = [];
errors: string[] = [];
......@@ -8,8 +16,8 @@ export class ConformanceReport {
hintFeatureIds: string[] = [];
hints: string[] = [];
patternHintFeatureIds: string[] = [];
patternHints: string[] = [];
usedPatterns: string[] = [];
patternHints: PatternHint[] = [];
usedPatterns: Instance[] = [];
constructor(conformanceReport: Partial<ConformanceReport> = {}) {
Object.assign(this, conformanceReport);
......
......@@ -168,7 +168,7 @@
<h6>Pattern Hints</h6>
<ul>
<li *ngFor="let hint of conformance.patternHints">
{{ hint }}
<app-pattern-hint [patternHint]="hint"></app-pattern-hint>
</li>
</ul>
</div>
......@@ -176,7 +176,7 @@
<h6>Used Patterns</h6>
<ul>
<li *ngFor="let pattern of conformance.usedPatterns">
{{ pattern }}
<app-pattern-view [pattern]="pattern"></app-pattern-view>
</li>
</ul>
</div>
......
......@@ -61,6 +61,9 @@ import { ApiNavigationComponent } from './api/api-navigation/api-navigation.comp
import { CanvasDefinitionRelationshipsFormComponent } from './canvas-definition/canvas-definition-relationships-form/canvas-definition-relationships-form.component';
import { CanvasElementsComponent } from './elements/canvas-elements/canvas-elements.component';
import { CanvasDefinitionOverviewComponent } from './canvas-definition/canvas-definition-overview/canvas-definition-overview.component';
import { PatternDescriptionModalComponent } from './instances/pattern-description-modal/pattern-description-modal.component';
import { PatternViewComponent } from './instances/pattern-view/pattern-view.component';
import { PatternHintComponent } from './instances/pattern-hint/pattern-hint.component';
@NgModule({
providers: [
......@@ -138,6 +141,9 @@ import { CanvasDefinitionOverviewComponent } from './canvas-definition/canvas-de
InstanceListComponent,
InstanceSelectPatternFormComponent,
PatternComponent,
PatternDescriptionModalComponent,
PatternHintComponent,
PatternViewComponent,
// merge
MergeExpertModelsComponent,
......
......@@ -49,7 +49,7 @@
</li>
<li ngbNavItem="stepHints" #stepHints="ngbNavItem">
<a ngbNavLink>2. Hints</a>
<ng-template ngbNavContent> Adapt the example with hints </ng-template>
<ng-template ngbNavContent> Adapt the example with hints</ng-template>
</li>
<li ngbNavItem="stepCompare" #stepCompare="ngbNavItem">
<a ngbNavLink>3. Compare & Adaption</a>
......@@ -59,7 +59,7 @@
</li>
<li ngbNavItem="stepView">
<a ngbNavLink>4. View</a>
<ng-template ngbNavContent> Just view the example </ng-template>
<ng-template ngbNavContent> Just view the example</ng-template>
</li>
</ul>
<div class="mt-1" [ngbNavOutlet]="nav"></div>
......@@ -228,7 +228,7 @@
<h6>Pattern Hints</h6>
<ul>
<li *ngFor="let hint of conformance.patternHints">
{{ hint }}
<app-pattern-hint [patternHint]="hint"></app-pattern-hint>
</li>
</ul>
</div>
......@@ -236,7 +236,7 @@
<h6>Used Patterns</h6>
<ul>
<li *ngFor="let pattern of conformance.usedPatterns">
{{ pattern }}
<app-pattern-view [pattern]="pattern"></app-pattern-view>
</li>
</ul>
</div>
......@@ -270,7 +270,9 @@
<div *ngIf="usedPatterns" style="margin-top: 20px">
<h6>Used Patterns</h6>
<ul>
<li *ngFor="let pattern of usedPatterns">{{ pattern }}</li>
<li *ngFor="let pattern of usedPatterns">
<app-pattern-view [pattern]="pattern"></app-pattern-view>
</li>
</ul>
</div>
</div>
......
......@@ -31,7 +31,7 @@ export class ExampleComponent implements OnInit {
});
// used patterns
usedPatterns: string[] = null;
usedPatterns: Instance[] = null;
// Compare / Heatmap
selectOtherInstanceForm: FormGroup = this.fb.group({
......@@ -59,7 +59,7 @@ export class ExampleComponent implements OnInit {
private router: Router
) {}
ngOnInit() {
ngOnInit(): void {
this.routeSubscription = this.route.paramMap.subscribe((paramMap) => {
const expertModelId = paramMap.get('id');
const exampleId = +paramMap.get('exampleId');
......@@ -73,7 +73,7 @@ export class ExampleComponent implements OnInit {
});
}
async load(expertModelId, exampleId) {
async load(expertModelId, exampleId): Promise<void> {
const expertModel = await this.expertModelService.get(expertModelId);
this.expertModel = expertModel;
this.example = expertModel.getInstance(exampleId);
......@@ -93,7 +93,7 @@ export class ExampleComponent implements OnInit {
}
}
async updateExpertModel() {
async updateExpertModel(): Promise<void> {
await this.expertModelService.save(this.expertModel);
await this.load(this.expertModel._id, this.example.id);
}
......@@ -101,7 +101,7 @@ export class ExampleComponent implements OnInit {
/**
* Create adaptation of the business model.
*/
async createAdaptation() {
async createAdaptation(): Promise<void> {
const adaptationName = this.instanceService.getAdaptionName(
this.example.name
);
......@@ -117,12 +117,12 @@ export class ExampleComponent implements OnInit {
]);
}
switchView(event: NgbNavChangeEvent) {
switchView(event: NgbNavChangeEvent): void {
this.clearView();
this.initConformanceOptionsForm(event.nextId);
}
private clearView() {
private clearView(): void {
this.uncheckConformance();
this.clearCompare();
this.clearPattern();
......@@ -132,7 +132,7 @@ export class ExampleComponent implements OnInit {
/**
* Uncheck the conformance.
*/
uncheckConformance() {
uncheckConformance(): void {
this.conformanceIsChecked = false;
this.conformance = new ConformanceReport();
}
......@@ -140,7 +140,7 @@ export class ExampleComponent implements OnInit {
/**
* Check the conformance.
*/
checkConformance() {
checkConformance(): void {
this.clearCompare();
this.clearPattern();
this.conformance =
......@@ -155,7 +155,7 @@ export class ExampleComponent implements OnInit {
/**
* Compare this instance with another instance and generate a heatmap
*/
compare() {
compare(): void {
this.uncheckConformance();
this.clearPattern();
const id = this.selectOtherInstanceForm.value.instance;
......@@ -171,7 +171,7 @@ export class ExampleComponent implements OnInit {
/**
* Clear comparison and remove heatmap
*/
clearCompare() {
clearCompare(): void {
this.compareInstance = null;
this.percentages = null;
this.selectOtherInstanceForm.get('instance').enable();
......@@ -180,7 +180,7 @@ export class ExampleComponent implements OnInit {
/**
* Show pattern in business model canvas
*/
showPattern() {
showPattern(): void {
this.uncheckConformance();
this.clearCompare();
const id = this.selectPatternForm.value.pattern;
......@@ -191,12 +191,12 @@ export class ExampleComponent implements OnInit {
/**
* Do not show pattern in business model canvas any longer
*/
clearPattern() {
clearPattern(): void {
this.patternInstance = null;
this.selectPatternForm.get('pattern').enable();
}
showUsedPatterns() {
showUsedPatterns(): void {
this.usedPatterns = this.canvasModelConsistencyService.getPatternHints(
this.expertModel,
this.example,
......@@ -204,11 +204,11 @@ export class ExampleComponent implements OnInit {
).usedPatterns;
}
hideUsedPatterns() {
hideUsedPatterns(): void {
this.usedPatterns = null;
}
private initConformanceOptionsForm(activeId: string) {
private initConformanceOptionsForm(activeId: string): void {
if (activeId === 'stepHints') {
this.conformanceOptionsForm.setValue({
showWarnings: true,
......
<div class="modal-header">
<h4 class="modal-title">Description of pattern {{ pattern.name }}</h4>
<button type="button" class="close" aria-label="Close" (click)="dismiss()">
<span aria-hidden="true">&times;</span>
<span class="sr-only">Close Window</span>
</button>
</div>
<div class="modal-body">
{{ pattern.description }}
</div>
<div class="modal-footer d-flex">
<button type="button" class="btn btn-dark ml-auto" (click)="dismiss()">
Close
</button>
</div>
import { Component, Input } from '@angular/core';
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
import { Instance } from '../../../canvas-meta-model/instance';
@Component({
selector: 'app-pattern-description-modal',
templateUrl: './pattern-description-modal.component.html',
styleUrls: ['./pattern-description-modal.component.css'],
})
export class PatternDescriptionModalComponent {
@Input() pattern: Instance;
constructor(private activeModal: NgbActiveModal) {}
dismiss(): void {
this.activeModal.dismiss();
}
}
You could add the pattern
<app-pattern-view [pattern]="patternHint.pattern"></app-pattern-view> by adding
the following features: {{ missingFeaturesInfo }}
import { Component, Input, OnChanges, SimpleChanges } from '@angular/core';
import { PatternHint } from '../../../canvas-meta-model/conformance-report';
@Component({
selector: 'app-pattern-hint',
templateUrl: './pattern-hint.component.html',
styleUrls: ['./pattern-hint.component.css'],
})
export class PatternHintComponent implements OnChanges {
@Input() patternHint: PatternHint;
missingFeaturesInfo: string;
ngOnChanges(changes: SimpleChanges): void {
if (changes.patternHint) {
this.buildMissingFeaturesInfo();
}
}
private buildMissingFeaturesInfo(): void {
this.missingFeaturesInfo = this.patternHint.missingFeatures
.map((feature) => feature.name)
.join(', ');
}
}
<span
class="btn btn-link p-0 border-0 align-baseline"
(click)="openDescription()"
>{{ pattern.name }}</span
>
import { Component, Input } from '@angular/core';
import { Instance } from '../../../canvas-meta-model/instance';
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
import { PatternDescriptionModalComponent } from '../pattern-description-modal/pattern-description-modal.component';
@Component({
selector: 'app-pattern-view',
templateUrl: './pattern-view.component.html',
styleUrls: ['./pattern-view.component.css'],
})
export class PatternViewComponent {
@Input() pattern: Instance;
constructor(private modalService: NgbModal) {}
openDescription(): void {
const modal = this.modalService.open(PatternDescriptionModalComponent, {
size: 'lg',
});
modal.componentInstance.pattern = this.pattern;
}
}
......@@ -251,7 +251,7 @@ export class PouchdbService {
const response = await this.getDb().find(request);
if ('bookmark' in response) {
const couchDbResponse = response as CouchDBFindResponse;
let docCount = 1;
let docCount = couchDbResponse.docs.length;
while (docCount > 0 && couchDbResponse.bookmark != null) {
const nextPage = await this.getDb().find({
...request,
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment