From 0a8a1ec118f731d0b84f3f0166c3559e7604ee85 Mon Sep 17 00:00:00 2001 From: "michele.artini" Date: Wed, 25 Jan 2023 16:08:32 +0100 Subject: [PATCH] edit metadata of simple resources --- .../dnet-is-application/src/app/app.module.ts | 13 +- .../dnet-is-application/src/app/is.service.ts | 21 ++- .../main-menu-panels.component.html | 4 +- .../src/app/model/controller.model.ts | 15 +- .../src/app/resources/content-dialog.html | 9 + .../src/app/resources/metadata-dialog.html | 35 ++++ .../src/app/resources/new-dialog.html | 9 + .../app/resources/resources.component.html | 30 +++- .../src/app/resources/resources.component.ts | 164 +++++++++++++++++- .../src/app/wf-history/wf-dialog.html | 2 +- .../app/wf-history/wf-history.component.ts | 43 +++-- frontends/dnet-is-application/src/styles.css | 5 +- 12 files changed, 313 insertions(+), 37 deletions(-) create mode 100644 frontends/dnet-is-application/src/app/resources/content-dialog.html create mode 100644 frontends/dnet-is-application/src/app/resources/metadata-dialog.html create mode 100644 frontends/dnet-is-application/src/app/resources/new-dialog.html diff --git a/frontends/dnet-is-application/src/app/app.module.ts b/frontends/dnet-is-application/src/app/app.module.ts index 5b183555..a8557902 100644 --- a/frontends/dnet-is-application/src/app/app.module.ts +++ b/frontends/dnet-is-application/src/app/app.module.ts @@ -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] diff --git a/frontends/dnet-is-application/src/app/is.service.ts b/frontends/dnet-is-application/src/app/is.service.ts index 3b2dcb77..41d2f72d 100644 --- a/frontends/dnet-is-application/src/app/is.service.ts +++ b/frontends/dnet-is-application/src/app/is.service.ts @@ -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("/ajax/resourceTypes"); } + loadResourceType(id:string):Observable { + return this.client.get("/ajax/resourceTypes/" + encodeURIComponent(id)); + } + loadInfo():Observable { return this.client.get("/ajax/info/"); } @@ -23,14 +27,25 @@ export class ISService { return this.client.get("/ajax/protocols/"); } + loadSimpleResources(type:string):Observable { + return this.client.get("/ajax/resources/" + encodeURIComponent(type)); + } + + saveSimpleResourceMedatata(res:SimpleResource):Observable { + return this.client.post('/ajax/resources/' + encodeURIComponent(res.id) + '/metadata', res); + } + + deleteSimpleResource(res:SimpleResource):Observable { + return this.client.delete('/ajax/resources/' + encodeURIComponent(res.id)); + } + loadWfHistory(total?:number, from?:number, to?:number):Observable { 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('/ajax/wfs/', {params: params}); } diff --git a/frontends/dnet-is-application/src/app/main-menu-panels/main-menu-panels.component.html b/frontends/dnet-is-application/src/app/main-menu-panels/main-menu-panels.component.html index 903b5073..07cac31a 100644 --- a/frontends/dnet-is-application/src/app/main-menu-panels/main-menu-panels.component.html +++ b/frontends/dnet-is-application/src/app/main-menu-panels/main-menu-panels.component.html @@ -1,7 +1,7 @@
- - + +
diff --git a/frontends/dnet-is-application/src/app/model/controller.model.ts b/frontends/dnet-is-application/src/app/model/controller.model.ts index ae71bdaf..80a686e4 100644 --- a/frontends/dnet-is-application/src/app/model/controller.model.ts +++ b/frontends/dnet-is-application/src/app/model/controller.model.ts @@ -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 -} \ No newline at end of file +} + +export interface SimpleResource { + id: string, + name: string, + type: string, + description?: string, + creationDate?: string, + modificationDate?: string +} diff --git a/frontends/dnet-is-application/src/app/resources/content-dialog.html b/frontends/dnet-is-application/src/app/resources/content-dialog.html new file mode 100644 index 00000000..bfd3c108 --- /dev/null +++ b/frontends/dnet-is-application/src/app/resources/content-dialog.html @@ -0,0 +1,9 @@ +

Edit content

+ +
+ CONTENT FORM HERE +
+ +
+ +
diff --git a/frontends/dnet-is-application/src/app/resources/metadata-dialog.html b/frontends/dnet-is-application/src/app/resources/metadata-dialog.html new file mode 100644 index 00000000..8d86b8ed --- /dev/null +++ b/frontends/dnet-is-application/src/app/resources/metadata-dialog.html @@ -0,0 +1,35 @@ +
+

Edit metadata

+ +
+ + + ID + + This field should not be empty + + + + Type + + This field should not be empty + + + + Name + + This field is required + + + + Description + + +
+ +
+ + +
+ +
diff --git a/frontends/dnet-is-application/src/app/resources/new-dialog.html b/frontends/dnet-is-application/src/app/resources/new-dialog.html new file mode 100644 index 00000000..9f20b5fd --- /dev/null +++ b/frontends/dnet-is-application/src/app/resources/new-dialog.html @@ -0,0 +1,9 @@ +

New resource

+ +
+ NEW RESOURCE FORM HERE +
+ +
+ +
diff --git a/frontends/dnet-is-application/src/app/resources/resources.component.html b/frontends/dnet-is-application/src/app/resources/resources.component.html index f081ce30..1b390ce4 100644 --- a/frontends/dnet-is-application/src/app/resources/resources.component.html +++ b/frontends/dnet-is-application/src/app/resources/resources.component.html @@ -1 +1,29 @@ -

resources works!

+

{{type.name}}

+ + + + + Filter + + + + + + {{r.name}} {{type.contentType}} + + +

{{r.description}}

+

+ Id: {{r.id}}
Creation date: {{r.creationDate}}
Modification date: {{r.modificationDate}} +

+
+ + + + raw content + + +
+ + + diff --git a/frontends/dnet-is-application/src/app/resources/resources.component.ts b/frontends/dnet-is-application/src/app/resources/resources.component.ts index 4e313a7e..922c0a26 100644 --- a/frontends/dnet-is-application/src/app/resources/resources.component.ts +++ b/frontends/dnet-is-application/src/app/resources/resources.component.ts @@ -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, @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, @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, @Inject(MAT_DIALOG_DATA) public resource: string, public service: ISService) { + + } + + onNoClick(): void { + this.dialogRef.close(); + } +} \ No newline at end of file diff --git a/frontends/dnet-is-application/src/app/wf-history/wf-dialog.html b/frontends/dnet-is-application/src/app/wf-history/wf-dialog.html index a68c3ffa..9e3a7347 100644 --- a/frontends/dnet-is-application/src/app/wf-history/wf-dialog.html +++ b/frontends/dnet-is-application/src/app/wf-history/wf-dialog.html @@ -36,5 +36,5 @@
- +
diff --git a/frontends/dnet-is-application/src/app/wf-history/wf-history.component.ts b/frontends/dnet-is-application/src/app/wf-history/wf-history.component.ts index ea83eed5..fa6077e3 100644 --- a/frontends/dnet-is-application/src/app/wf-history/wf-history.component.ts +++ b/frontends/dnet-is-application/src/app/wf-history/wf-history.component.ts @@ -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 = new MatTableDataSource([]); @@ -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 diff --git a/frontends/dnet-is-application/src/styles.css b/frontends/dnet-is-application/src/styles.css index 4f8289b6..f08e01a5 100644 --- a/frontends/dnet-is-application/src/styles.css +++ b/frontends/dnet-is-application/src/styles.css @@ -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;