edit metadata of simple resources
This commit is contained in:
parent
085c3123de
commit
0a8a1ec118
|
@ -3,7 +3,7 @@ import { BrowserModule } from '@angular/platform-browser';
|
|||
|
||||
import { AppRoutingModule } from './app-routing.module';
|
||||
import { AppComponent } from './app.component';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { FormsModule,ReactiveFormsModule } from '@angular/forms';
|
||||
import { HttpClientModule } from '@angular/common/http';
|
||||
import { InfoComponent } from './info/info.component';
|
||||
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
||||
|
@ -26,8 +26,7 @@ import { MatExpansionModule } from '@angular/material/expansion';
|
|||
import { WfDialog, WfHistoryComponent } from './wf-history/wf-history.component';
|
||||
import { MatDialogModule } from '@angular/material/dialog';
|
||||
import {MatSortModule} from '@angular/material/sort';
|
||||
import { ResourcesComponent } from './resources/resources.component'
|
||||
|
||||
import { ResourcesComponent, ResContentDialog, ResCreateNewDialog, ResMetadataDialog } from './resources/resources.component'
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
|
@ -38,7 +37,10 @@ import { ResourcesComponent } from './resources/resources.component'
|
|||
ProtocolsComponent,
|
||||
WfHistoryComponent,
|
||||
WfDialog,
|
||||
ResourcesComponent
|
||||
ResourcesComponent,
|
||||
ResContentDialog,
|
||||
ResCreateNewDialog,
|
||||
ResMetadataDialog
|
||||
],
|
||||
imports: [
|
||||
BrowserModule,
|
||||
|
@ -60,7 +62,8 @@ import { ResourcesComponent } from './resources/resources.component'
|
|||
MatTableModule,
|
||||
MatExpansionModule,
|
||||
MatDialogModule,
|
||||
MatSortModule
|
||||
MatSortModule,
|
||||
ReactiveFormsModule
|
||||
],
|
||||
providers: [],
|
||||
bootstrap: [AppComponent]
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { HttpClient, HttpParams } from '@angular/common/http';
|
||||
import { ResourceType,Protocol,WfHistoryEntry } from './model/controller.model';
|
||||
import { ResourceType,Protocol,WfHistoryEntry,SimpleResource } from './model/controller.model';
|
||||
import { Observable, Observer } from 'rxjs';
|
||||
|
||||
@Injectable({
|
||||
|
@ -15,6 +15,10 @@ export class ISService {
|
|||
return this.client.get<ResourceType[]>("/ajax/resourceTypes");
|
||||
}
|
||||
|
||||
loadResourceType(id:string):Observable<ResourceType> {
|
||||
return this.client.get<ResourceType>("/ajax/resourceTypes/" + encodeURIComponent(id));
|
||||
}
|
||||
|
||||
loadInfo():Observable<any[]> {
|
||||
return this.client.get<any[]>("/ajax/info/");
|
||||
}
|
||||
|
@ -23,14 +27,25 @@ export class ISService {
|
|||
return this.client.get<Protocol[]>("/ajax/protocols/");
|
||||
}
|
||||
|
||||
loadSimpleResources(type:string):Observable<SimpleResource[]> {
|
||||
return this.client.get<SimpleResource[]>("/ajax/resources/" + encodeURIComponent(type));
|
||||
}
|
||||
|
||||
saveSimpleResourceMedatata(res:SimpleResource):Observable<void> {
|
||||
return this.client.post<void>('/ajax/resources/' + encodeURIComponent(res.id) + '/metadata', res);
|
||||
}
|
||||
|
||||
deleteSimpleResource(res:SimpleResource):Observable<void> {
|
||||
return this.client.delete<void>('/ajax/resources/' + encodeURIComponent(res.id));
|
||||
}
|
||||
|
||||
loadWfHistory(total?:number, from?:number, to?:number):Observable<WfHistoryEntry[]> {
|
||||
let params = new HttpParams();
|
||||
|
||||
if (total && total > 0) { params = params.append('total', total); }
|
||||
if (from && from > 0) { params = params.append('from', from); }
|
||||
if (to && to > 0) { params = params.append('to', to); }
|
||||
|
||||
|
||||
|
||||
return this.client.get<WfHistoryEntry[]>('/ajax/wfs/', {params: params});
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
<div class="collapse-buttons">
|
||||
<button mat-button (click)="accordion.openAll()">Expand All</button>
|
||||
<button mat-button (click)="accordion.closeAll()">Collapse All</button>
|
||||
<button mat-button color="primary" (click)="accordion.openAll()">Expand All</button>
|
||||
<button mat-button color="primary" (click)="accordion.closeAll()">Collapse All</button>
|
||||
</div>
|
||||
|
||||
<mat-accordion multi>
|
||||
|
|
|
@ -11,12 +11,12 @@ export interface KeyValue {
|
|||
v: string;
|
||||
}
|
||||
|
||||
export interface Module {
|
||||
export interface Module {
|
||||
group: string;
|
||||
name: string;
|
||||
versions: string[];
|
||||
files: string[];
|
||||
}
|
||||
}
|
||||
|
||||
export interface ProtocolParams {
|
||||
name:string
|
||||
|
@ -42,4 +42,13 @@ export interface WfHistoryEntry {
|
|||
dsName?: string,
|
||||
dsApi?: string,
|
||||
details: Map<string,string>
|
||||
}
|
||||
}
|
||||
|
||||
export interface SimpleResource {
|
||||
id: string,
|
||||
name: string,
|
||||
type: string,
|
||||
description?: string,
|
||||
creationDate?: string,
|
||||
modificationDate?: string
|
||||
}
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
<h1 mat-dialog-title>Edit content</h1>
|
||||
|
||||
<div mat-dialog-content>
|
||||
CONTENT FORM HERE
|
||||
</div>
|
||||
|
||||
<div mat-dialog-actions>
|
||||
<button mat-stroked-button color="primary" mat-dialog-close>Close</button>
|
||||
</div>
|
|
@ -0,0 +1,35 @@
|
|||
<form [formGroup]="metadataForm" (ngSubmit)="onSubmit()">
|
||||
<h1 mat-dialog-title>Edit metadata</h1>
|
||||
|
||||
<div mat-dialog-content>
|
||||
|
||||
<mat-form-field appearance="fill" style="width: 100%;">
|
||||
<mat-label>ID</mat-label>
|
||||
<input matInput formControlName="id" required readonly />
|
||||
<mat-error *ngIf="metadataForm.get('id')?.invalid">This field should not be empty</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="fill" style="width: 100%;">
|
||||
<mat-label>Type</mat-label>
|
||||
<input matInput formControlName="type" required readonly />
|
||||
<mat-error *ngIf="metadataForm.get('type')?.invalid">This field should not be empty</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="metadataForm.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="8"></textarea>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div mat-dialog-actions>
|
||||
<button mat-stroked-button color="primary" type="submit" [disabled]="!metadataForm.valid">Submit</button>
|
||||
<button mat-stroked-button color="primary" mat-dialog-close>Close</button>
|
||||
</div>
|
||||
|
||||
</form>
|
|
@ -0,0 +1,9 @@
|
|||
<h1 mat-dialog-title>New resource</h1>
|
||||
|
||||
<div mat-dialog-content>
|
||||
NEW RESOURCE FORM HERE
|
||||
</div>
|
||||
|
||||
<div mat-dialog-actions>
|
||||
<button mat-stroked-button color="primary" mat-dialog-close>Close</button>
|
||||
</div>
|
|
@ -1 +1,29 @@
|
|||
<p>resources works!</p>
|
||||
<h2>{{type.name}}</h2>
|
||||
|
||||
<button mat-stroked-button color="primary" (click)="openNewDialog()">create a new resource</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>
|
||||
|
||||
<mat-card class="example-card" *ngFor="let r of resources" style="margin-top: 10px;">
|
||||
<mat-card-header>
|
||||
<mat-card-title title="{{r.id}}">{{r.name}} <span class="badge-label badge-info" style="font-size: 0.7em;">{{type.contentType}}</span></mat-card-title>
|
||||
</mat-card-header>
|
||||
<mat-card-content>
|
||||
<p>{{r.description}}</p>
|
||||
<p class="muted small">
|
||||
<b>Id:</b> {{r.id}}<br /> <b>Creation date:</b> {{r.creationDate}}<br /> <b>Modification date:</b> {{r.modificationDate}}
|
||||
</p>
|
||||
</mat-card-content>
|
||||
<mat-card-actions>
|
||||
<button mat-stroked-button color="primary" (click)="openMetadataDialog(r)">edit metadata</button>
|
||||
<button mat-stroked-button color="primary" (click)="openContentDialog(r)">edit content</button>
|
||||
<a href="./api/resources/{{r.id}}/content" mat-stroked-button color="link" target="_blank">raw content</a>
|
||||
<button mat-stroked-button color="warn" (click)="deleteResource(r)">delete</button>
|
||||
</mat-card-actions>
|
||||
</mat-card>
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,10 +1,170 @@
|
|||
import { Component } from '@angular/core';
|
||||
import { Component, Inject,AfterViewInit, ViewChild, OnInit } from '@angular/core';
|
||||
import { ISService } from '../is.service';
|
||||
import { MatTableDataSource } from '@angular/material/table';
|
||||
import { MatSort, Sort } from '@angular/material/sort';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { MatDialog, MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
||||
import { ResourceType, SimpleResource } from '../model/controller.model';
|
||||
import {FormControl, FormGroup, FormGroupDirective, NgForm, Validators} from '@angular/forms';
|
||||
import { ResourceLoader } from '@angular/compiler';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'app-resources',
|
||||
templateUrl: './resources.component.html',
|
||||
styleUrls: ['./resources.component.css']
|
||||
})
|
||||
export class ResourcesComponent {
|
||||
export class ResourcesComponent implements OnInit {
|
||||
typeId:string = '';
|
||||
type:ResourceType = { id: '', name: '', contentType: '', count: 0, simple: true };
|
||||
resources:SimpleResource[] = [];
|
||||
|
||||
constructor(public service: ISService, public route: ActivatedRoute, public newDialog: MatDialog, public contentDialog: MatDialog, public metadataDialog: MatDialog) {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.route.params.subscribe(params => {
|
||||
this.typeId = params['type'];
|
||||
this.service.loadResourceType(this.typeId).subscribe({
|
||||
next: (data: ResourceType) => this.type = data,
|
||||
error: error => console.log(error),
|
||||
complete: () => console.log("Completed")
|
||||
});
|
||||
this.reload()
|
||||
});
|
||||
}
|
||||
|
||||
reload() {
|
||||
if (this.typeId) {
|
||||
console.log('reload');
|
||||
this.service.loadSimpleResources(this.typeId).subscribe({
|
||||
next: (data: SimpleResource[]) => this.resources = data,
|
||||
error: error => console.log(error),
|
||||
complete: () => console.log("Completed")
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
applyFilter(event: Event) {
|
||||
const filterValue = (event.target as HTMLInputElement).value.trim().toLowerCase();
|
||||
//this.historyDatasource.filter = filterValue;
|
||||
}
|
||||
|
||||
openNewDialog(): void {
|
||||
const dialogRef = this.newDialog.open(ResCreateNewDialog, {
|
||||
data: {
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
dialogRef.afterClosed().subscribe(result => {
|
||||
if (result) this.reload();
|
||||
});
|
||||
}
|
||||
|
||||
openMetadataDialog(r:SimpleResource): void {
|
||||
const dialogRef = this.metadataDialog.open(ResMetadataDialog, {
|
||||
data: r
|
||||
});
|
||||
|
||||
dialogRef.afterClosed().subscribe(result => {
|
||||
if (result) this.reload();
|
||||
});
|
||||
}
|
||||
|
||||
openContentDialog(r:SimpleResource): void {
|
||||
const dialogRef = this.contentDialog.open(ResContentDialog, {
|
||||
data: r
|
||||
});
|
||||
|
||||
dialogRef.afterClosed().subscribe(result => {
|
||||
if (result) this.reload();
|
||||
});
|
||||
}
|
||||
|
||||
deleteResource(r:SimpleResource) {
|
||||
if (confirm('Are you sure?')) {
|
||||
this.service.deleteSimpleResource(r).subscribe({
|
||||
next: (data: void) => this.reload(),
|
||||
error: error => console.log(error),
|
||||
complete: () => console.log("Completed")
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'res-content-dialog',
|
||||
templateUrl: 'content-dialog.html',
|
||||
styleUrls: ['resources.component.css']
|
||||
|
||||
})
|
||||
export class ResContentDialog {
|
||||
constructor(public dialogRef: MatDialogRef<ResContentDialog>, @Inject(MAT_DIALOG_DATA) public data: SimpleResource, public service: ISService) {
|
||||
|
||||
}
|
||||
|
||||
onNoClick(): void {
|
||||
this.dialogRef.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'res-metadata-dialog',
|
||||
templateUrl: 'metadata-dialog.html',
|
||||
styleUrls: ['resources.component.css']
|
||||
|
||||
})
|
||||
export class ResMetadataDialog {
|
||||
metadataForm = new FormGroup({
|
||||
id: new FormControl('', [Validators.required]),
|
||||
type: new FormControl('', [Validators.required]),
|
||||
name: new FormControl('', [Validators.required]),
|
||||
description : new FormControl('', [])
|
||||
});
|
||||
|
||||
constructor(public dialogRef: MatDialogRef<ResMetadataDialog>, @Inject(MAT_DIALOG_DATA) public data: SimpleResource, public service: ISService) {
|
||||
this.metadataForm.get('id')?.setValue(data.id);
|
||||
this.metadataForm.get('type')?.setValue(data.type);
|
||||
this.metadataForm.get('name')?.setValue(data.name);
|
||||
if (data.description) {
|
||||
this.metadataForm.get('description')?.setValue(data.description);
|
||||
}
|
||||
}
|
||||
|
||||
onSubmit():void {
|
||||
const res = Object.assign({}, this.data, this.metadataForm.value);
|
||||
|
||||
this.service.saveSimpleResourceMedatata(res).subscribe({
|
||||
next: (data: void) => {
|
||||
this.dialogRef.close(1)
|
||||
},
|
||||
error: error => console.log(error),
|
||||
complete: () => console.log("Completed")
|
||||
});
|
||||
}
|
||||
|
||||
onNoClick(): void {
|
||||
this.dialogRef.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'res-new-dialog',
|
||||
templateUrl: 'new-dialog.html',
|
||||
styleUrls: ['resources.component.css']
|
||||
|
||||
})
|
||||
export class ResCreateNewDialog {
|
||||
constructor(public dialogRef: MatDialogRef<ResCreateNewDialog>, @Inject(MAT_DIALOG_DATA) public resource: string, public service: ISService) {
|
||||
|
||||
}
|
||||
|
||||
onNoClick(): void {
|
||||
this.dialogRef.close();
|
||||
}
|
||||
}
|
|
@ -36,5 +36,5 @@
|
|||
</div>
|
||||
|
||||
<div mat-dialog-actions>
|
||||
<button mat-button mat-dialog-close>Close</button>
|
||||
<button mat-stroked-button color="primary" mat-dialog-close>Close</button>
|
||||
</div>
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import { Component, Inject,AfterViewInit, ViewChild } 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 { WfHistoryEntry } from '../model/controller.model';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { Observable } from 'rxjs';
|
||||
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 } from '../model/controller.model';
|
||||
|
@ -14,7 +14,7 @@ import { KeyValue } from '../model/controller.model';
|
|||
templateUrl: './wf-history.component.html',
|
||||
styleUrls: ['./wf-history.component.css']
|
||||
})
|
||||
export class WfHistoryComponent implements AfterViewInit {
|
||||
export class WfHistoryComponent implements AfterViewInit , OnInit{
|
||||
|
||||
historyDatasource: MatTableDataSource<WfHistoryEntry> = new MatTableDataSource<WfHistoryEntry>([]);
|
||||
|
||||
|
@ -24,21 +24,28 @@ export class WfHistoryComponent implements AfterViewInit {
|
|||
from: number = -1
|
||||
to: number = -1
|
||||
|
||||
constructor(public service: ISService, public route: ActivatedRoute, public dialog: MatDialog) {
|
||||
constructor(public service: ISService, public route: ActivatedRoute, public dialog: MatDialog) {
|
||||
}
|
||||
|
||||
let totalP = route.snapshot.paramMap.get('total');
|
||||
let fromP = route.snapshot.queryParamMap.get('from');
|
||||
let toP = route.snapshot.queryParamMap.get('to');
|
||||
|
||||
if (totalP) { this.total = parseInt(totalP); }
|
||||
if (fromP) { this.from = parseInt(fromP); }
|
||||
if (toP) { this.to = parseInt(toP); }
|
||||
|
||||
this.service.loadWfHistory(this.total, this.from, this.to).subscribe({
|
||||
next: (data: WfHistoryEntry[]) => this.historyDatasource.data = data,
|
||||
error: error => console.log(error),
|
||||
complete: () => console.log("Completed")
|
||||
})
|
||||
ngOnInit() {
|
||||
combineLatest([ this.route.params, this.route.queryParams ],
|
||||
(params: Params, queryParams: Params) => ({ params, queryParams })
|
||||
).subscribe((res: { params: Params; queryParams: Params }) => {
|
||||
const { params, queryParams} = res;
|
||||
let totalP = queryParams['total'];
|
||||
let fromP = queryParams['from'];
|
||||
let toP = queryParams['to'];
|
||||
|
||||
if (totalP) { this.total = parseInt(totalP); }
|
||||
if (fromP) { this.from = parseInt(fromP); }
|
||||
if (toP) { this.to = parseInt(toP); }
|
||||
|
||||
this.service.loadWfHistory(this.total, this.from, this.to).subscribe({
|
||||
next: (data: WfHistoryEntry[]) => this.historyDatasource.data = data,
|
||||
error: error => console.log(error),
|
||||
complete: () => console.log("Completed")
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
@ViewChild(MatSort) sort: MatSort | undefined
|
||||
|
|
|
@ -3,6 +3,9 @@
|
|||
html, body { height: 100%; }
|
||||
body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; }
|
||||
|
||||
.small { font-size: 0.9em !important; }
|
||||
.muted { color: darkgray; }
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
}
|
||||
|
@ -44,8 +47,6 @@ th, td {
|
|||
padding-bottom: 0.5em !important;
|
||||
}
|
||||
|
||||
.muted { color: darkgray; }
|
||||
|
||||
.badge-label {
|
||||
padding-top: 0.3em;
|
||||
padding-bottom: 0.3em;
|
||||
|
|
Loading…
Reference in New Issue