Vocabularies
This commit is contained in:
parent
78ca043213
commit
527a80c931
|
@ -29,7 +29,7 @@ import { MatSortModule } from '@angular/material/sort';
|
|||
import { ResourcesComponent, ResContentDialog, ResCreateNewDialog, ResMetadataDialog } from './resources/resources.component'
|
||||
import { MatSnackBarModule } from '@angular/material/snack-bar';
|
||||
import { ContextsComponent, ContextViewerComponent, ContextParamsDialog } from './contexts/contexts.component';
|
||||
import { VocabulariesComponent, VocabularyEditorComponent } from './vocabularies/vocabularies.component';
|
||||
import { VocabulariesComponent, VocabularyEditorComponent, VocDialog } from './vocabularies/vocabularies.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
|
@ -49,7 +49,8 @@ import { VocabulariesComponent, VocabularyEditorComponent } from './vocabularies
|
|||
ContextViewerComponent,
|
||||
ContextParamsDialog,
|
||||
VocabulariesComponent,
|
||||
VocabulariesComponent
|
||||
VocabularyEditorComponent,
|
||||
VocDialog
|
||||
],
|
||||
imports: [
|
||||
BrowserModule,
|
||||
|
|
|
@ -1,9 +1,3 @@
|
|||
.table-buttons { text-align: right; }
|
||||
.table-buttons button {
|
||||
font-size: 0.8em;
|
||||
padding: 0 !important;
|
||||
height: 2.5em !important;
|
||||
}
|
||||
|
||||
.context-node {
|
||||
padding-top: 1em;
|
||||
|
|
|
@ -53,7 +53,7 @@ export class ContextsComponent implements AfterViewInit ,OnInit {
|
|||
|
||||
@Component({
|
||||
selector: 'context-dialog',
|
||||
templateUrl: 'context-params.html',
|
||||
templateUrl: 'context-params-dialog.html',
|
||||
styleUrls: ['./contexts.component.css']
|
||||
})
|
||||
export class ContextParamsDialog {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http';
|
||||
import { ResourceType, Protocol, WfHistoryEntry, SimpleResource, Context, ContextNode } from './model/controller.model';
|
||||
import { ResourceType, Protocol, WfHistoryEntry, SimpleResource, Context, ContextNode, Vocabulary } from './model/controller.model';
|
||||
import { Observable, Observer } from 'rxjs';
|
||||
import { FormGroup } from '@angular/forms';
|
||||
import { MatSnackBar } from '@angular/material/snack-bar';
|
||||
|
@ -133,6 +133,27 @@ export class ISService {
|
|||
});
|
||||
}
|
||||
|
||||
loadVocabularies(onSuccess: Function): void {
|
||||
this.client.get<Vocabulary[]>('./ajax/vocs/').subscribe({
|
||||
next: data => onSuccess(data),
|
||||
error: error => this.showError(error)
|
||||
});
|
||||
}
|
||||
|
||||
saveVocabulary(voc:Vocabulary, onSuccess: Function, relatedForm?: FormGroup): void {
|
||||
this.client.post<void>('./ajax/vocs/', voc).subscribe({
|
||||
next: data => onSuccess(data),
|
||||
error: error => this.showError(error, relatedForm)
|
||||
});
|
||||
}
|
||||
|
||||
deleteVocabulary(vocId:string, onSuccess: Function): void {
|
||||
this.client.delete<void>('./ajax/vocs/' + encodeURIComponent(vocId)).subscribe({
|
||||
next: data => onSuccess(data),
|
||||
error: error => this.showError(error)
|
||||
});
|
||||
}
|
||||
|
||||
private showError(error: any, form?: FormGroup) {
|
||||
const msg = this.errorMessage(error);
|
||||
if (form) {
|
||||
|
|
|
@ -76,3 +76,9 @@ export interface ContextNode {
|
|||
populated?: boolean,
|
||||
childs?: ContextNode[]
|
||||
}
|
||||
|
||||
export interface Vocabulary {
|
||||
id: string,
|
||||
name: string,
|
||||
description?: string
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
<form [formGroup]="vocForm" (ngSubmit)="onSubmit()">
|
||||
<h1 mat-dialog-title *ngIf="data.id">Edit vocabulary</h1>
|
||||
<h1 mat-dialog-title *ngIf="!data.id">New vocabulary</h1>
|
||||
|
||||
<div mat-dialog-content>
|
||||
<mat-form-field appearance="fill" style="width: 100%;">
|
||||
<mat-label>ID</mat-label>
|
||||
<input matInput required formControlName="id" [readonly]="data.id.length > 0" />
|
||||
<mat-error *ngIf="vocForm.get('id')?.invalid">This field is <strong>required</strong></mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="fill" style="width: 100%;">
|
||||
<mat-label>Name</mat-label>
|
||||
<input matInput formControlName="name" required />
|
||||
<mat-error *ngIf="vocForm.get('name')?.invalid">This field is <strong>required</strong></mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="fill" style="width: 100%;">
|
||||
<mat-label>Description</mat-label>
|
||||
<textarea matInput formControlName="description" rows="4"></textarea>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div mat-dialog-actions>
|
||||
<button mat-stroked-button color="primary" type="submit" [disabled]="!vocForm.valid">Submit</button>
|
||||
<button mat-stroked-button color="primary" mat-dialog-close>Close</button>
|
||||
<mat-error *ngIf="vocForm.errors?.['serverError']">
|
||||
{{ vocForm.errors?.['serverError'] }}
|
||||
</mat-error>
|
||||
</div>
|
||||
|
||||
</form>
|
|
@ -1 +1,44 @@
|
|||
<p>vocabularies works!</p>
|
||||
<h2>Vocabularies</h2>
|
||||
|
||||
<button mat-stroked-button color="primary" (click)="newVocabularyDialog()">create a new vocabulary</button>
|
||||
|
||||
<mat-form-field style="width: 100%; margin-top: 10px;">
|
||||
<mat-label>Filter</mat-label>
|
||||
<input matInput (keyup)="applyFilter($event)" placeholder="Filter..." #input />
|
||||
</mat-form-field>
|
||||
|
||||
<table mat-table [dataSource]="vocsDatasource" matSort class="mat-elevation-z8">
|
||||
|
||||
<ng-container matColumnDef="id">
|
||||
<th mat-header-cell *matHeaderCellDef style="width: 20%;" mat-sort-header sortActionDescription="Sort by ID"> Id </th>
|
||||
<td mat-cell *matCellDef="let element">
|
||||
<a [routerLink]="['/voc_editor']" [queryParams]="{id: element.id}">{{element.id}}</a>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="name">
|
||||
<th mat-header-cell *matHeaderCellDef style="width: 20%;" mat-sort-header sortActionDescription="Sort by Name"> Name </th>
|
||||
<td mat-cell *matCellDef="let element"> {{element.name}} </td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="description">
|
||||
<th mat-header-cell *matHeaderCellDef style="width: 40%;" mat-sort-header sortActionDescription="Sort by Description"> Description </th>
|
||||
<td mat-cell *matCellDef="let element"> {{element.description}} </td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="buttons">
|
||||
<th mat-header-cell *matHeaderCellDef style="text-align: right;"></th>
|
||||
<td mat-cell *matCellDef="let element" class="table-buttons">
|
||||
<button mat-stroked-button color="primary" (click)="editVocabularyDialog(element)">edit</button>
|
||||
<button mat-stroked-button color="warn" (click)="deleteVocabularyDialog(element)">delete</button>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="colums"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: colums;"></tr>
|
||||
|
||||
<!-- Row shown when there is no matching data. -->
|
||||
<tr class="mat-row" *matNoDataRow>
|
||||
<td class="mat-cell" colspan="4" style="padding: 0 16px;">No data matching the filter "{{input.value}}"</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
|
|
@ -1,4 +1,14 @@
|
|||
import { Component } from '@angular/core';
|
||||
import { Component, Inject,AfterViewInit, OnInit, ViewChild } from '@angular/core';
|
||||
import { ISService } from '../is.service';
|
||||
import { MatTableDataSource } from '@angular/material/table';
|
||||
import { MatSort, Sort } from '@angular/material/sort';
|
||||
import { Vocabulary } from '../model/controller.model';
|
||||
import { ActivatedRoute, Params } from '@angular/router';
|
||||
import { Observable, combineLatest } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { MatDialog, MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
||||
import { KeyValue, ContextParam } from '../model/controller.model';
|
||||
import { FormControl, FormGroup, FormGroupDirective, NgForm, Validators } from '@angular/forms';
|
||||
|
||||
@Component({
|
||||
selector: 'app-vocabularies',
|
||||
|
@ -6,6 +16,60 @@ import { Component } from '@angular/core';
|
|||
styleUrls: ['./vocabularies.component.css']
|
||||
})
|
||||
export class VocabulariesComponent {
|
||||
vocsDatasource: MatTableDataSource<Vocabulary> = new MatTableDataSource<Vocabulary>([]);
|
||||
|
||||
colums: string[] = ['id', 'name', 'description', 'buttons'];
|
||||
|
||||
@ViewChild(MatSort) sort: MatSort | undefined
|
||||
|
||||
constructor(public service: ISService, public route: ActivatedRoute, public dialog: MatDialog) {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.reload();
|
||||
}
|
||||
|
||||
ngAfterViewInit() {
|
||||
if(this.sort) this.vocsDatasource.sort = this.sort;
|
||||
}
|
||||
|
||||
reload() {
|
||||
this.service.loadVocabularies((data: Vocabulary[]) => this.vocsDatasource.data = data);
|
||||
}
|
||||
|
||||
applyFilter(event: Event) {
|
||||
const filterValue = (event.target as HTMLInputElement).value.trim().toLowerCase();
|
||||
this.vocsDatasource.filter = filterValue;
|
||||
}
|
||||
|
||||
newVocabularyDialog(): void {
|
||||
const dialogRef = this.dialog.open(VocDialog, {
|
||||
data: { id: '', name: '', description: '' },
|
||||
width: '80%'
|
||||
});
|
||||
|
||||
dialogRef.afterClosed().subscribe(result => {
|
||||
if (result) this.reload();
|
||||
});
|
||||
}
|
||||
|
||||
editVocabularyDialog(vocabulary: Vocabulary): void {
|
||||
const dialogRef = this.dialog.open(VocDialog, {
|
||||
data: vocabulary,
|
||||
width: '80%'
|
||||
});
|
||||
|
||||
dialogRef.afterClosed().subscribe(result => {
|
||||
if (result) this.reload();
|
||||
});
|
||||
}
|
||||
|
||||
deleteVocabularyDialog(vocabulary: Vocabulary): void {
|
||||
if (confirm("Are you sure?")) {
|
||||
this.service.deleteVocabulary(vocabulary.id , (data:void) => this.reload());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@ -15,5 +79,32 @@ export class VocabulariesComponent {
|
|||
styleUrls: ['./vocabularies.component.css']
|
||||
})
|
||||
export class VocabularyEditorComponent {
|
||||
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'voc-dialog',
|
||||
templateUrl: 'voc-dialog.html',
|
||||
styleUrls: ['vocabularies.component.css']
|
||||
})
|
||||
export class VocDialog {
|
||||
vocForm = new FormGroup({
|
||||
id: new FormControl(''),
|
||||
name: new FormControl(''),
|
||||
description : new FormControl('')
|
||||
});
|
||||
|
||||
constructor(public dialogRef: MatDialogRef<VocDialog>, @Inject(MAT_DIALOG_DATA) public data: any, public service: ISService) {
|
||||
this.vocForm.get('id')?.setValue(data.id);
|
||||
this.vocForm.get('name')?.setValue(data.name);
|
||||
this.vocForm.get('description')?.setValue(data.description);
|
||||
}
|
||||
|
||||
onSubmit():void {
|
||||
const voc = Object.assign({}, this.data, this.vocForm.value);
|
||||
this.service.saveVocabulary(voc, (data: void) => this.dialogRef.close(1), this.vocForm);
|
||||
}
|
||||
|
||||
onNoClick(): void {
|
||||
this.dialogRef.close();
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
VOC EDITOR
|
|
@ -10,6 +10,13 @@ table {
|
|||
width: 100%;
|
||||
}
|
||||
|
||||
.table-buttons { text-align: right !important; }
|
||||
.table-buttons button {
|
||||
font-size: 0.8em !important;
|
||||
padding: 0 !important;
|
||||
height: 2.5em !important;
|
||||
}
|
||||
|
||||
.warning {
|
||||
background-color: darkorange;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue