indentation
This commit is contained in:
parent
5d861c406a
commit
73ade91f43
|
@ -10,23 +10,23 @@ import { DsmSearchComponent, DsmResultsComponent, DsmApiComponent } from './dsm/
|
||||||
import { MdstoreInspectorComponent, MdstoresComponent } from './mdstores/mdstores.component';
|
import { MdstoreInspectorComponent, MdstoresComponent } from './mdstores/mdstores.component';
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
{ path:"" , redirectTo:'info', pathMatch: 'full' },
|
{ path: "", redirectTo: 'info', pathMatch: 'full' },
|
||||||
{ path:"info" , component:InfoComponent },
|
{ path: "info", component: InfoComponent },
|
||||||
{ path:"resources/:type" , component:ResourcesComponent },
|
{ path: "resources/:type", component: ResourcesComponent },
|
||||||
{ path:"adv_resources/context" , component:ContextsComponent },
|
{ path: "adv_resources/context", component: ContextsComponent },
|
||||||
{ path:"adv_resources/vocabulary" , component:VocabulariesComponent },
|
{ path: "adv_resources/vocabulary", component: VocabulariesComponent },
|
||||||
{ path:"adv_resources/protocol" , component:ProtocolsComponent },
|
{ path: "adv_resources/protocol", component: ProtocolsComponent },
|
||||||
{ path:"wf_history" , component:WfHistoryComponent },
|
{ path: "wf_history", component: WfHistoryComponent },
|
||||||
{ path:"ctx_viewer" , component:ContextViewerComponent },
|
{ path: "ctx_viewer", component: ContextViewerComponent },
|
||||||
{ path:"voc_editor" , component:VocabularyEditorComponent },
|
{ path: "voc_editor", component: VocabularyEditorComponent },
|
||||||
{ path:"dsm/search" , component:DsmSearchComponent },
|
{ path: "dsm/search", component: DsmSearchComponent },
|
||||||
{ path:"dsm/results/:page/:size" , component:DsmResultsComponent },
|
{ path: "dsm/results/:page/:size", component: DsmResultsComponent },
|
||||||
{ path:"mdstores" , component:MdstoresComponent },
|
{ path: "mdstores", component: MdstoresComponent },
|
||||||
{ path:"mdrecords/:versionId/:limit" , component:MdstoreInspectorComponent }
|
{ path: "mdrecords/:versionId/:limit", component: MdstoreInspectorComponent }
|
||||||
];
|
];
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [RouterModule.forRoot(routes)],
|
imports: [RouterModule.forRoot(routes)],
|
||||||
exports: [RouterModule]
|
exports: [RouterModule]
|
||||||
})
|
})
|
||||||
export class AppRoutingModule { }
|
export class AppRoutingModule { }
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
.sidenav-container {
|
.sidenav-container {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidenav {
|
.sidenav {
|
||||||
width: 350px;
|
width: 350px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidenav .mat-toolbar {
|
.sidenav .mat-toolbar {
|
||||||
background: inherit;
|
background: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mat-toolbar.mat-primary {
|
.mat-toolbar.mat-primary {
|
||||||
position: sticky;
|
position: sticky;
|
||||||
top: 0;
|
top: 0;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,24 +1,23 @@
|
||||||
<div *ngIf="spinnerService.visibility | async" class="spinner">
|
<div *ngIf="spinnerService.visibility | async" class="spinner">
|
||||||
<mat-progress-spinner mode="indeterminate" [strokeWidth]="8" [diameter]="80" color="primary"></mat-progress-spinner>
|
<mat-progress-spinner mode="indeterminate" [strokeWidth]="8" [diameter]="80" color="primary"></mat-progress-spinner>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<mat-sidenav-container class="sidenav-container">
|
<mat-sidenav-container class="sidenav-container">
|
||||||
<mat-sidenav #drawer class="sidenav mat-elevation-z8" fixedInViewport
|
<mat-sidenav #drawer class="sidenav mat-elevation-z8" fixedInViewport
|
||||||
[attr.role]="(isHandset$ | async) ? 'dialog' : 'navigation'" [mode]="(isHandset$ | async) ? 'over' : 'side'"
|
[attr.role]="(isHandset$ | async) ? 'dialog' : 'navigation'" [mode]="(isHandset$ | async) ? 'over' : 'side'"
|
||||||
[opened]="(isHandset$ | async) === false">
|
[opened]="(isHandset$ | async) === false">
|
||||||
<app-main-menu-panels></app-main-menu-panels>
|
<app-main-menu-panels></app-main-menu-panels>
|
||||||
</mat-sidenav>
|
</mat-sidenav>
|
||||||
<mat-sidenav-content>
|
<mat-sidenav-content>
|
||||||
<mat-toolbar color="primary">
|
<mat-toolbar color="primary">
|
||||||
<button type="button" aria-label="Toggle sidenav" mat-icon-button (click)="drawer.toggle()">
|
<button type="button" aria-label="Toggle sidenav" mat-icon-button (click)="drawer.toggle()">
|
||||||
<mat-icon aria-label="Side nav toggle icon">menu</mat-icon>
|
<mat-icon aria-label="Side nav toggle icon">menu</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
<span>{{title}}</span>
|
<span>{{title}}</span>
|
||||||
</mat-toolbar>
|
</mat-toolbar>
|
||||||
<div style="padding: 20px;">
|
<div style="padding: 20px;">
|
||||||
<!-- The routed views render in the <router-outlet>-->
|
<!-- The routed views render in the <router-outlet>-->
|
||||||
<router-outlet></router-outlet>
|
<router-outlet></router-outlet>
|
||||||
</div>
|
</div>
|
||||||
</mat-sidenav-content>
|
</mat-sidenav-content>
|
||||||
</mat-sidenav-container>
|
</mat-sidenav-container>
|
||||||
|
|
||||||
|
|
|
@ -5,20 +5,19 @@ import { map, shareReplay } from 'rxjs/operators';
|
||||||
import { SpinnerService } from './common/spinner.service';
|
import { SpinnerService } from './common/spinner.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-root',
|
selector: 'app-root',
|
||||||
templateUrl: './app.component.html',
|
templateUrl: './app.component.html',
|
||||||
styleUrls: ['./app.component.css']
|
styleUrls: ['./app.component.css']
|
||||||
})
|
})
|
||||||
export class AppComponent {
|
export class AppComponent {
|
||||||
title = 'D-NET Information Service Application';
|
title = 'D-NET Information Service Application';
|
||||||
|
|
||||||
isHandset$: Observable<boolean> = this.breakpointObserver.observe(Breakpoints.Handset)
|
|
||||||
.pipe(
|
|
||||||
map(result => result.matches),
|
|
||||||
shareReplay()
|
|
||||||
);
|
|
||||||
|
|
||||||
constructor(private breakpointObserver: BreakpointObserver, public spinnerService: SpinnerService) {}
|
isHandset$: Observable<boolean> = this.breakpointObserver.observe(Breakpoints.Handset)
|
||||||
|
.pipe(
|
||||||
|
map(result => result.matches),
|
||||||
|
shareReplay()
|
||||||
|
);
|
||||||
|
|
||||||
|
constructor(private breakpointObserver: BreakpointObserver, public spinnerService: SpinnerService) { }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,69 +37,69 @@ import { SpinnerHttpInterceptor } from './common/spinner.service';
|
||||||
import { MdstoresComponent, MdstoreInspectorComponent, MDStoreVersionsDialog, AddMDStoreDialog } from './mdstores/mdstores.component';
|
import { MdstoresComponent, MdstoreInspectorComponent, MDStoreVersionsDialog, AddMDStoreDialog } from './mdstores/mdstores.component';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
AppComponent,
|
AppComponent,
|
||||||
FilterPipe,
|
FilterPipe,
|
||||||
MainMenuPanelsComponent,
|
MainMenuPanelsComponent,
|
||||||
InfoComponent,
|
InfoComponent,
|
||||||
ProtocolsComponent,
|
ProtocolsComponent,
|
||||||
WfHistoryComponent,
|
WfHistoryComponent,
|
||||||
WfDialog,
|
WfDialog,
|
||||||
ResourcesComponent,
|
ResourcesComponent,
|
||||||
ResContentDialog,
|
ResContentDialog,
|
||||||
ResCreateNewDialog,
|
ResCreateNewDialog,
|
||||||
ResMetadataDialog,
|
ResMetadataDialog,
|
||||||
ContextsComponent,
|
ContextsComponent,
|
||||||
ContextViewerComponent,
|
ContextViewerComponent,
|
||||||
ContextParamsDialog,
|
ContextParamsDialog,
|
||||||
VocabulariesComponent,
|
VocabulariesComponent,
|
||||||
VocabularyEditorComponent,
|
VocabularyEditorComponent,
|
||||||
VocDialog,
|
VocDialog,
|
||||||
VocTermDialog,
|
VocTermDialog,
|
||||||
DsmSearchComponent,
|
DsmSearchComponent,
|
||||||
DsmResultsComponent,
|
DsmResultsComponent,
|
||||||
DsmApiComponent,
|
DsmApiComponent,
|
||||||
DsmAddApiDialog,
|
DsmAddApiDialog,
|
||||||
DsmBrowseDialog,
|
DsmBrowseDialog,
|
||||||
MdstoresComponent,
|
MdstoresComponent,
|
||||||
MdstoreInspectorComponent,
|
MdstoreInspectorComponent,
|
||||||
MDStoreVersionsDialog,
|
MDStoreVersionsDialog,
|
||||||
AddMDStoreDialog
|
AddMDStoreDialog
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
BrowserModule,
|
BrowserModule,
|
||||||
BrowserAnimationsModule,
|
BrowserAnimationsModule,
|
||||||
HttpClientModule,
|
HttpClientModule,
|
||||||
BrowserModule,
|
BrowserModule,
|
||||||
AppRoutingModule,
|
AppRoutingModule,
|
||||||
FormsModule,
|
FormsModule,
|
||||||
HttpClientModule,
|
HttpClientModule,
|
||||||
LayoutModule,
|
LayoutModule,
|
||||||
MatToolbarModule,
|
MatToolbarModule,
|
||||||
MatButtonModule,
|
MatButtonModule,
|
||||||
MatSidenavModule,
|
MatSidenavModule,
|
||||||
MatIconModule,
|
MatIconModule,
|
||||||
MatListModule,
|
MatListModule,
|
||||||
MatTreeModule,
|
MatTreeModule,
|
||||||
MatBadgeModule,
|
MatBadgeModule,
|
||||||
MatCardModule,
|
MatCardModule,
|
||||||
MatFormFieldModule,
|
MatFormFieldModule,
|
||||||
MatInputModule,
|
MatInputModule,
|
||||||
MatSelectModule,
|
MatSelectModule,
|
||||||
MatTableModule,
|
MatTableModule,
|
||||||
MatExpansionModule,
|
MatExpansionModule,
|
||||||
MatDialogModule,
|
MatDialogModule,
|
||||||
MatSortModule,
|
MatSortModule,
|
||||||
ReactiveFormsModule,
|
ReactiveFormsModule,
|
||||||
MatSnackBarModule,
|
MatSnackBarModule,
|
||||||
MatPaginatorModule,
|
MatPaginatorModule,
|
||||||
MatProgressSpinnerModule
|
MatProgressSpinnerModule
|
||||||
],
|
],
|
||||||
providers: [{
|
providers: [{
|
||||||
provide: HTTP_INTERCEPTORS,
|
provide: HTTP_INTERCEPTORS,
|
||||||
useClass: SpinnerHttpInterceptor,
|
useClass: SpinnerHttpInterceptor,
|
||||||
multi: true
|
multi: true
|
||||||
}],
|
}],
|
||||||
bootstrap: [ AppComponent ]
|
bootstrap: [AppComponent]
|
||||||
})
|
})
|
||||||
export class AppModule { }
|
export class AppModule { }
|
||||||
|
|
|
@ -2,24 +2,24 @@ import { Pipe, PipeTransform } from '@angular/core';
|
||||||
|
|
||||||
@Pipe({ name: 'searchFilter' })
|
@Pipe({ name: 'searchFilter' })
|
||||||
export class FilterPipe implements PipeTransform {
|
export class FilterPipe implements PipeTransform {
|
||||||
/**
|
/**
|
||||||
* Pipe filters the list of elements based on the search text provided
|
* Pipe filters the list of elements based on the search text provided
|
||||||
*
|
*
|
||||||
* @param items list of elements to search in
|
* @param items list of elements to search in
|
||||||
* @param searchText search string
|
* @param searchText search string
|
||||||
* @returns list of elements filtered by search text or []
|
* @returns list of elements filtered by search text or []
|
||||||
*/
|
*/
|
||||||
|
|
||||||
transform(items: any[], searchText: string): any[] {
|
transform(items: any[], searchText: string): any[] {
|
||||||
if (!items) return [];
|
if (!items) return [];
|
||||||
if (!searchText) return items;
|
if (!searchText) return items;
|
||||||
|
|
||||||
searchText = searchText.trim().toLocaleLowerCase();
|
searchText = searchText.trim().toLocaleLowerCase();
|
||||||
|
|
||||||
return items.filter(obj => {
|
return items.filter(obj => {
|
||||||
return Object.keys(obj).reduce((acc, curr) => {
|
return Object.keys(obj).reduce((acc, curr) => {
|
||||||
return acc || JSON.stringify(obj[curr]).toLowerCase().includes(searchText);
|
return acc || JSON.stringify(obj[curr]).toLowerCase().includes(searchText);
|
||||||
}, false);
|
}, false);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -197,4 +197,4 @@ export interface MDStoreRecord {
|
||||||
dateOfCollection: string,
|
dateOfCollection: string,
|
||||||
dateOfTransformation: string,
|
dateOfTransformation: string,
|
||||||
provenance: any
|
provenance: any
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,30 +9,30 @@ import { tap } from 'rxjs/operators';
|
||||||
|
|
||||||
@Injectable({ providedIn: 'root' })
|
@Injectable({ providedIn: 'root' })
|
||||||
export class SpinnerService {
|
export class SpinnerService {
|
||||||
visibility: BehaviorSubject<boolean>;
|
visibility: BehaviorSubject<boolean>;
|
||||||
|
|
||||||
constructor() { this.visibility = new BehaviorSubject(false); }
|
constructor() { this.visibility = new BehaviorSubject(false); }
|
||||||
|
|
||||||
show() { this.visibility.next(true); }
|
show() { this.visibility.next(true); }
|
||||||
hide() { this.visibility.next(false);}
|
hide() { this.visibility.next(false); }
|
||||||
}
|
}
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class SpinnerHttpInterceptor implements HttpInterceptor {
|
export class SpinnerHttpInterceptor implements HttpInterceptor {
|
||||||
|
|
||||||
constructor(private spinnerService: SpinnerService) { }
|
constructor(private spinnerService: SpinnerService) { }
|
||||||
|
|
||||||
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
|
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
|
||||||
|
|
||||||
this.spinnerService.show();
|
this.spinnerService.show();
|
||||||
|
|
||||||
return next.handle(req)
|
return next.handle(req)
|
||||||
.pipe(tap((event: HttpEvent<any>) => {
|
.pipe(tap((event: HttpEvent<any>) => {
|
||||||
if (event instanceof HttpResponse) {
|
if (event instanceof HttpResponse) {
|
||||||
this.spinnerService.hide();
|
this.spinnerService.hide();
|
||||||
}
|
}
|
||||||
}, (error) => {
|
}, (error) => {
|
||||||
this.spinnerService.hide();
|
this.spinnerService.hide();
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
<h1 mat-dialog-title>Parameters</h1>
|
<h1 mat-dialog-title>Parameters</h1>
|
||||||
|
|
||||||
<div mat-dialog-content>
|
<div mat-dialog-content>
|
||||||
<p *ngIf="!data || data.length == 0">No parameters</p>
|
<p *ngIf="!data || data.length == 0">No parameters</p>
|
||||||
|
|
||||||
<div *ngFor="let p of data">
|
<div *ngFor="let p of data">
|
||||||
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%; font-size: 0.8em;">
|
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%; font-size: 0.8em;">
|
||||||
<mat-label>{{p.name}}</mat-label>
|
<mat-label>{{p.name}}</mat-label>
|
||||||
<input matInput required readonly value="{{p.value}}" />
|
<input matInput required readonly value="{{p.value}}" />
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div mat-dialog-actions>
|
<div mat-dialog-actions>
|
||||||
<button mat-stroked-button color="primary" mat-dialog-close>Close</button>
|
<button mat-stroked-button color="primary" mat-dialog-close>Close</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,44 +1,48 @@
|
||||||
<h2>Context Viewer</h2>
|
<h2>Context Viewer</h2>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<b>Context ID: </b>{{context?.id}}<br />
|
<b>Context ID: </b>{{context?.id}}<br />
|
||||||
<b>Label: </b>{{context?.label}}<br />
|
<b>Label: </b>{{context?.label}}<br />
|
||||||
<b>Type: </b>{{context?.type}}<br />
|
<b>Type: </b>{{context?.type}}<br />
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<a mat-stroked-button color="primary" [routerLink]="['/adv_resources/context']">Return to contexts list</a>
|
<a mat-stroked-button color="primary" [routerLink]="['/adv_resources/context']">Return to contexts list</a>
|
||||||
<button mat-stroked-button color="primary" (click)="showParamsDialog(context?.parameters)">Global parameters</button>
|
<button mat-stroked-button color="primary" (click)="showParamsDialog(context?.parameters)">Global parameters</button>
|
||||||
<a mat-stroked-button color="primary" href="/api/contexts/{{context?.id}}" target="_blank">Download</a>
|
<a mat-stroked-button color="primary" href="/api/contexts/{{context?.id}}" target="_blank">Download</a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li *ngFor="let cat of categories" class="context-node">
|
<li *ngFor="let cat of categories" class="context-node">
|
||||||
<a (click)="populateNode(0, cat)" *ngIf="!(cat.populated || cat.nChilds == 0)" style="margin-right: 0.5em;">[+{{cat.nChilds}}]</a>
|
<a (click)="populateNode(0, cat)" *ngIf="!(cat.populated || cat.nChilds == 0)"
|
||||||
<a title="{{cat.label}}" (click)="showParamsDialog(cat.parameters)" style="margin-right: 0.5em;">{{cat.id}}</a>
|
style="margin-right: 0.5em;">[+{{cat.nChilds}}]</a>
|
||||||
<span class="badge-label badge-info" *ngIf="cat.claim">claim</span>
|
<a title="{{cat.label}}" (click)="showParamsDialog(cat.parameters)" style="margin-right: 0.5em;">{{cat.id}}</a>
|
||||||
|
<span class="badge-label badge-info" *ngIf="cat.claim">claim</span>
|
||||||
|
|
||||||
<ul *ngIf="cat.childs && cat.childs.length > 0">
|
<ul *ngIf="cat.childs && cat.childs.length > 0">
|
||||||
<li *ngFor="let c0 of cat.childs" class="context-node">
|
<li *ngFor="let c0 of cat.childs" class="context-node">
|
||||||
<a (click)="populateNode(1, c0)" *ngIf="!(c0.populated || c0.nChilds == 0)" style="margin-right: 0.5em;">[+{{c0.nChilds}}]</a>
|
<a (click)="populateNode(1, c0)" *ngIf="!(c0.populated || c0.nChilds == 0)"
|
||||||
<a title="{{c0.label}" (click)="showParamsDialog(c0.parameters)" style="margin-right: 0.5em;">{{c0.id}}</a>
|
style="margin-right: 0.5em;">[+{{c0.nChilds}}]</a>
|
||||||
<span class="badge-label badge-info" *ngIf="c0.claim">claim</span>
|
<a title="{{c0.label}" (click)="showParamsDialog(c0.parameters)" style="margin-right: 0.5em;">{{c0.id}}</a>
|
||||||
|
<span class="badge-label badge-info" *ngIf="c0.claim">claim</span>
|
||||||
<ul *ngIf="c0.childs && c0.childs.length > 0">
|
|
||||||
<li *ngFor="let c1 of c0.childs" class="context-node">
|
|
||||||
<a (click)="populateNode(2, c1)" *ngIf="!(c1.populated || c1.nChilds == 0)" style="margin-right: 0.5em;">[+{{c1.nChilds}}]</a>
|
|
||||||
<a title="{{c1.label}}" (click)="showParamsDialog(c1.parameters)" style="margin-right: 0.5em;">{{c1.id}}</a>
|
|
||||||
<span class="badge-label badge-info" *ngIf="c1.claim">claim</span>
|
|
||||||
|
|
||||||
<ul *ngIf="c1.childs && c1.childs.length > 0">
|
<ul *ngIf="c0.childs && c0.childs.length > 0">
|
||||||
<li *ngFor="let c2 of c1.childs" class="context-node">
|
<li *ngFor="let c1 of c0.childs" class="context-node">
|
||||||
<a title="{{c2.label}}" (click)="showParamsDialog(c2.parameters)" style="margin-right: 0.5em;">{{c2.id}}</a>
|
<a (click)="populateNode(2, c1)" *ngIf="!(c1.populated || c1.nChilds == 0)"
|
||||||
<span class="badge-label badge-info" *ngIf="c2.claim">claim</span>
|
style="margin-right: 0.5em;">[+{{c1.nChilds}}]</a>
|
||||||
</li>
|
<a title="{{c1.label}}" (click)="showParamsDialog(c1.parameters)" style="margin-right: 0.5em;">{{c1.id}}</a>
|
||||||
</ul>
|
<span class="badge-label badge-info" *ngIf="c1.claim">claim</span>
|
||||||
</li>
|
|
||||||
</ul>
|
<ul *ngIf="c1.childs && c1.childs.length > 0">
|
||||||
</li>
|
<li *ngFor="let c2 of c1.childs" class="context-node">
|
||||||
</ul>
|
<a title="{{c2.label}}" (click)="showParamsDialog(c2.parameters)"
|
||||||
</li>
|
style="margin-right: 0.5em;">{{c2.id}}</a>
|
||||||
</ul>
|
<span class="badge-label badge-info" *ngIf="c2.claim">claim</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
|
|
||||||
.context-node {
|
.context-node {
|
||||||
padding-top: 1em;
|
padding-top: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.context-node a {
|
.context-node a {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.context-node a:hover {
|
.context-node a:hover {
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,41 +1,44 @@
|
||||||
<h2>Contexts</h2>
|
<h2>Contexts</h2>
|
||||||
|
|
||||||
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%; margin-top: 10px;">
|
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%; margin-top: 10px;">
|
||||||
<mat-label>Filter</mat-label>
|
<mat-label>Filter</mat-label>
|
||||||
<input matInput (keyup)="applyFilter($event)" placeholder="Filter..." #input />
|
<input matInput (keyup)="applyFilter($event)" placeholder="Filter..." #input />
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
<table mat-table [dataSource]="contextsDatasource" matSort class="mat-elevation-z8">
|
<table mat-table [dataSource]="contextsDatasource" matSort class="mat-elevation-z8">
|
||||||
|
|
||||||
<ng-container matColumnDef="id">
|
<ng-container matColumnDef="id">
|
||||||
<th mat-header-cell *matHeaderCellDef style="width: 20%;" mat-sort-header sortActionDescription="Sort by Context ID"> Id </th>
|
<th mat-header-cell *matHeaderCellDef style="width: 20%;" mat-sort-header
|
||||||
<td mat-cell *matCellDef="let element">
|
sortActionDescription="Sort by Context ID"> Id </th>
|
||||||
<a [routerLink]="['/ctx_viewer']" [queryParams]="{id: element.id}">{{element.id}}</a>
|
<td mat-cell *matCellDef="let element">
|
||||||
</td>
|
<a [routerLink]="['/ctx_viewer']" [queryParams]="{id: element.id}">{{element.id}}</a>
|
||||||
</ng-container>
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
<ng-container matColumnDef="label">
|
<ng-container matColumnDef="label">
|
||||||
<th mat-header-cell *matHeaderCellDef style="width: 40%;" mat-sort-header sortActionDescription="Sort by Context Label"> Label </th>
|
<th mat-header-cell *matHeaderCellDef style="width: 40%;" mat-sort-header
|
||||||
<td mat-cell *matCellDef="let element"> {{element.label}} </td>
|
sortActionDescription="Sort by Context Label"> Label </th>
|
||||||
</ng-container>
|
<td mat-cell *matCellDef="let element"> {{element.label}} </td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
<ng-container matColumnDef="type">
|
<ng-container matColumnDef="type">
|
||||||
<th mat-header-cell *matHeaderCellDef style="width: 10%;" mat-sort-header sortActionDescription="Sort by Context Type"> Type </th>
|
<th mat-header-cell *matHeaderCellDef style="width: 10%;" mat-sort-header
|
||||||
<td mat-cell *matCellDef="let element"> {{element.type}} </td>
|
sortActionDescription="Sort by Context Type"> Type </th>
|
||||||
</ng-container>
|
<td mat-cell *matCellDef="let element"> {{element.type}} </td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
<ng-container matColumnDef="buttons">
|
<ng-container matColumnDef="buttons">
|
||||||
<th mat-header-cell *matHeaderCellDef style="text-align: right;">Parameters</th>
|
<th mat-header-cell *matHeaderCellDef style="text-align: right;">Parameters</th>
|
||||||
<td mat-cell *matCellDef="let element" class="table-buttons">
|
<td mat-cell *matCellDef="let element" class="table-buttons">
|
||||||
<button mat-stroked-button color="primary" (click)="showParamsDialog(element)">show</button>
|
<button mat-stroked-button color="primary" (click)="showParamsDialog(element)">show</button>
|
||||||
</td>
|
</td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<tr mat-header-row *matHeaderRowDef="colums"></tr>
|
<tr mat-header-row *matHeaderRowDef="colums"></tr>
|
||||||
<tr mat-row *matRowDef="let row; columns: colums;"></tr>
|
<tr mat-row *matRowDef="let row; columns: colums;"></tr>
|
||||||
|
|
||||||
<!-- Row shown when there is no matching data. -->
|
<!-- Row shown when there is no matching data. -->
|
||||||
<tr class="mat-row" *matNoDataRow>
|
<tr class="mat-row" *matNoDataRow>
|
||||||
<td class="mat-cell" colspan="4" style="padding: 0 16px;">No data matching the filter "{{input.value}}"</td>
|
<td class="mat-cell" colspan="4" style="padding: 0 16px;">No data matching the filter "{{input.value}}"</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { Component, Inject,AfterViewInit, OnInit, ViewChild } from '@angular/core';
|
import { Component, Inject, AfterViewInit, OnInit, ViewChild } from '@angular/core';
|
||||||
import { ISService } from '../common/is.service';
|
import { ISService } from '../common/is.service';
|
||||||
import { MatTableDataSource } from '@angular/material/table';
|
import { MatTableDataSource } from '@angular/material/table';
|
||||||
import { MatSort } from '@angular/material/sort';
|
import { MatSort } from '@angular/material/sort';
|
||||||
|
@ -7,95 +7,95 @@ import { ActivatedRoute, Params } from '@angular/router';
|
||||||
import { MatDialog, MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
import { MatDialog, MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-contexts',
|
selector: 'app-contexts',
|
||||||
templateUrl: './contexts.component.html',
|
templateUrl: './contexts.component.html',
|
||||||
styleUrls: ['./contexts.component.css']
|
styleUrls: ['./contexts.component.css']
|
||||||
})
|
})
|
||||||
export class ContextsComponent implements AfterViewInit ,OnInit {
|
export class ContextsComponent implements AfterViewInit, OnInit {
|
||||||
contextsDatasource: MatTableDataSource<Context> = new MatTableDataSource<Context>([]);
|
contextsDatasource: MatTableDataSource<Context> = new MatTableDataSource<Context>([]);
|
||||||
|
|
||||||
colums: string[] = ['id', 'label', 'type', 'buttons'];
|
colums: string[] = ['id', 'label', 'type', 'buttons'];
|
||||||
|
|
||||||
@ViewChild(MatSort) sort: MatSort | undefined
|
@ViewChild(MatSort) sort: MatSort | undefined
|
||||||
|
|
||||||
constructor(public service: ISService, public route: ActivatedRoute, public dialog: MatDialog) {
|
constructor(public service: ISService, public route: ActivatedRoute, public dialog: MatDialog) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.reload();
|
this.reload();
|
||||||
}
|
}
|
||||||
|
|
||||||
ngAfterViewInit() {
|
ngAfterViewInit() {
|
||||||
if(this.sort) this.contextsDatasource.sort = this.sort;
|
if (this.sort) this.contextsDatasource.sort = this.sort;
|
||||||
}
|
}
|
||||||
|
|
||||||
reload() {
|
reload() {
|
||||||
this.service.loadContexts((data: Context[]) => this.contextsDatasource.data = data);
|
this.service.loadContexts((data: Context[]) => this.contextsDatasource.data = data);
|
||||||
}
|
}
|
||||||
|
|
||||||
applyFilter(event: Event) {
|
applyFilter(event: Event) {
|
||||||
const filterValue = (event.target as HTMLInputElement).value.trim().toLowerCase();
|
const filterValue = (event.target as HTMLInputElement).value.trim().toLowerCase();
|
||||||
this.contextsDatasource.filter = filterValue;
|
this.contextsDatasource.filter = filterValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
showParamsDialog(context: Context): void {
|
showParamsDialog(context: Context): void {
|
||||||
const dialogRef = this.dialog.open(ContextParamsDialog, {
|
const dialogRef = this.dialog.open(ContextParamsDialog, {
|
||||||
data: context.parameters,
|
data: context.parameters,
|
||||||
width: '80%'
|
width: '80%'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'context-dialog',
|
selector: 'context-dialog',
|
||||||
templateUrl: 'context-params-dialog.html',
|
templateUrl: 'context-params-dialog.html',
|
||||||
styleUrls: ['./contexts.component.css']
|
styleUrls: ['./contexts.component.css']
|
||||||
})
|
})
|
||||||
export class ContextParamsDialog {
|
export class ContextParamsDialog {
|
||||||
|
|
||||||
constructor(public dialogRef: MatDialogRef<ContextParamsDialog>, @Inject(MAT_DIALOG_DATA) public data: any, public service: ISService) {
|
constructor(public dialogRef: MatDialogRef<ContextParamsDialog>, @Inject(MAT_DIALOG_DATA) public data: any, public service: ISService) {
|
||||||
}
|
}
|
||||||
|
|
||||||
onNoClick(): void {
|
onNoClick(): void {
|
||||||
this.dialogRef.close();
|
this.dialogRef.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-context-editor',
|
selector: 'app-context-editor',
|
||||||
templateUrl: './context-viewer.component.html',
|
templateUrl: './context-viewer.component.html',
|
||||||
styleUrls: ['./contexts.component.css']
|
styleUrls: ['./contexts.component.css']
|
||||||
})
|
})
|
||||||
export class ContextViewerComponent implements OnInit {
|
export class ContextViewerComponent implements OnInit {
|
||||||
|
|
||||||
context?:Context
|
|
||||||
categories:ContextNode[] = [];
|
|
||||||
|
|
||||||
constructor(public service: ISService, public route: ActivatedRoute, public dialog: MatDialog) {
|
context?: Context
|
||||||
}
|
categories: ContextNode[] = [];
|
||||||
|
|
||||||
ngOnInit() {
|
constructor(public service: ISService, public route: ActivatedRoute, public dialog: MatDialog) {
|
||||||
this.route.queryParams.subscribe((params) => {
|
}
|
||||||
this.service.loadContext(params['id'], (data: Context) => this.context = data);
|
|
||||||
this.service.loadContextCategories(params['id'], (data:ContextNode[]) => this.categories = data);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
populateNode(level:number, node:ContextNode): void {
|
ngOnInit() {
|
||||||
this.service.loadContextConcepts(level, node.id, (data:ContextNode[]) => {
|
this.route.queryParams.subscribe((params) => {
|
||||||
node.populated = true;
|
this.service.loadContext(params['id'], (data: Context) => this.context = data);
|
||||||
node.childs = data
|
this.service.loadContextCategories(params['id'], (data: ContextNode[]) => this.categories = data);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
showParamsDialog(params:ContextParam[] | undefined): void {
|
populateNode(level: number, node: ContextNode): void {
|
||||||
if (params) {
|
this.service.loadContextConcepts(level, node.id, (data: ContextNode[]) => {
|
||||||
this.dialog.open(ContextParamsDialog, {
|
node.populated = true;
|
||||||
data: params,
|
node.childs = data
|
||||||
width: '80%'
|
});
|
||||||
});
|
}
|
||||||
}
|
|
||||||
}
|
showParamsDialog(params: ContextParam[] | undefined): void {
|
||||||
|
if (params) {
|
||||||
|
this.dialog.open(ContextParamsDialog, {
|
||||||
|
data: params,
|
||||||
|
width: '80%'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,126 +1,126 @@
|
||||||
<form [formGroup]="addApiForm" (ngSubmit)="onSubmit()">
|
<form [formGroup]="addApiForm" (ngSubmit)="onSubmit()">
|
||||||
<h1 mat-dialog-title>Add a new API</h1>
|
<h1 mat-dialog-title>Add a new API</h1>
|
||||||
|
|
||||||
<div mat-dialog-content>
|
<div mat-dialog-content>
|
||||||
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%;">
|
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%;">
|
||||||
<mat-label>Protocol</mat-label>
|
<mat-label>Protocol</mat-label>
|
||||||
<mat-select matInput formControlName="protocol" (selectionChange)="onChangeProtocol($event)">
|
<mat-select matInput formControlName="protocol" (selectionChange)="onChangeProtocol($event)">
|
||||||
<mat-option *ngFor="let i of protocols" [value]="i">{{i}}</mat-option>
|
<mat-option *ngFor="let i of protocols" [value]="i">{{i}}</mat-option>
|
||||||
</mat-select>
|
</mat-select>
|
||||||
<mat-error *ngIf="addApiForm.get('protocol')?.invalid">This field is <strong>required</strong></mat-error>
|
<mat-error *ngIf="addApiForm.get('protocol')?.invalid">This field is <strong>required</strong></mat-error>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
<mat-card style="margin-top: 10px;" *ngIf="selectedProtocol">
|
<mat-card style="margin-top: 10px;" *ngIf="selectedProtocol">
|
||||||
<mat-card-header>
|
<mat-card-header>
|
||||||
<mat-card-title>API Description</mat-card-title>
|
<mat-card-title>API Description</mat-card-title>
|
||||||
</mat-card-header>
|
</mat-card-header>
|
||||||
<mat-card-content style="padding-top: 1em;">
|
<mat-card-content style="padding-top: 1em;">
|
||||||
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%;">
|
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%;">
|
||||||
<mat-label>Datasource (ID: {{data.dsId}})</mat-label>
|
<mat-label>Datasource (ID: {{data.dsId}})</mat-label>
|
||||||
<input matInput readonly value="{{data.dsName}}" />
|
<input matInput readonly value="{{data.dsName}}" />
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
<mat-form-field appearance="fill" floatLabel="always" style="width: 30%;">
|
<mat-form-field appearance="fill" floatLabel="always" style="width: 30%;">
|
||||||
<mat-label>Api ID (prefix)</mat-label>
|
<mat-label>Api ID (prefix)</mat-label>
|
||||||
<input matInput readonly value="{{apiPrefix}}" />
|
<input matInput readonly value="{{apiPrefix}}" />
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
<mat-form-field appearance="fill" floatLabel="always" style="width: 70%;">
|
<mat-form-field appearance="fill" floatLabel="always" style="width: 70%;">
|
||||||
<mat-label>Api ID (suffix)</mat-label>
|
<mat-label>Api ID (suffix)</mat-label>
|
||||||
<input matInput formControlName="apiIdSuffix" placeholder="example: {{selectedProtocol}}_01" />
|
<input matInput formControlName="apiIdSuffix" placeholder="example: {{selectedProtocol}}_01" />
|
||||||
<mat-error *ngIf="addApiForm.get('apiIdSuffix')?.invalid">This field is
|
<mat-error *ngIf="addApiForm.get('apiIdSuffix')?.invalid">This field is
|
||||||
<strong>required</strong></mat-error>
|
<strong>required</strong></mat-error>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
<mat-form-field appearance="fill" floatLabel="always" style="width: 50%;">
|
<mat-form-field appearance="fill" floatLabel="always" style="width: 50%;">
|
||||||
<mat-label>Compatibility level</mat-label>
|
<mat-label>Compatibility level</mat-label>
|
||||||
<mat-select matInput formControlName="compatibility">
|
<mat-select matInput formControlName="compatibility">
|
||||||
<mat-option *ngFor="let i of compatibilityLevels" [value]="i">{{i}}</mat-option>
|
<mat-option *ngFor="let i of compatibilityLevels" [value]="i">{{i}}</mat-option>
|
||||||
</mat-select>
|
</mat-select>
|
||||||
<mat-error *ngIf="addApiForm.get('compatibility')?.invalid">This field is
|
<mat-error *ngIf="addApiForm.get('compatibility')?.invalid">This field is
|
||||||
<strong>required</strong></mat-error>
|
<strong>required</strong></mat-error>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
<mat-form-field appearance="fill" floatLabel="always" style="width: 50%;">
|
<mat-form-field appearance="fill" floatLabel="always" style="width: 50%;">
|
||||||
<mat-label>Content description</mat-label>
|
<mat-label>Content description</mat-label>
|
||||||
<mat-select matInput formControlName="contentdescription">
|
<mat-select matInput formControlName="contentdescription">
|
||||||
<mat-option *ngFor="let i of contentDescTypes" [value]="i">{{i}}</mat-option>
|
<mat-option *ngFor="let i of contentDescTypes" [value]="i">{{i}}</mat-option>
|
||||||
</mat-select>
|
</mat-select>
|
||||||
<mat-error *ngIf="addApiForm.get('contentdescription')?.invalid">This field is
|
<mat-error *ngIf="addApiForm.get('contentdescription')?.invalid">This field is
|
||||||
<strong>required</strong></mat-error>
|
<strong>required</strong></mat-error>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</mat-card-content>
|
</mat-card-content>
|
||||||
</mat-card>
|
</mat-card>
|
||||||
|
|
||||||
<mat-card style="margin-top: 10px;" *ngIf="selectedProtocol">
|
<mat-card style="margin-top: 10px;" *ngIf="selectedProtocol">
|
||||||
<mat-card-header>
|
<mat-card-header>
|
||||||
<mat-card-title>Configuration Parameters</mat-card-title>
|
<mat-card-title>Configuration Parameters</mat-card-title>
|
||||||
</mat-card-header>
|
</mat-card-header>
|
||||||
<mat-card-content style="padding-top: 1em;">
|
<mat-card-content style="padding-top: 1em;">
|
||||||
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%;">
|
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%;">
|
||||||
<mat-label>Base URL</mat-label>
|
<mat-label>Base URL</mat-label>
|
||||||
<input matInput formControlName="baseurl" />
|
<input matInput formControlName="baseurl" />
|
||||||
<mat-error *ngIf="addApiForm.get('baseurl')?.invalid">
|
<mat-error *ngIf="addApiForm.get('baseurl')?.invalid">
|
||||||
Invalid URL
|
Invalid URL
|
||||||
<span *ngIf="addApiForm.get('baseurl')?.hasError('required')">: This field is <strong>required</strong></span>
|
<span *ngIf="addApiForm.get('baseurl')?.hasError('required')">: This field is
|
||||||
</mat-error>
|
<strong>required</strong></span>
|
||||||
</mat-form-field>
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
<ng-container *ngFor="let p of selProtParams">
|
<ng-container *ngFor="let p of selProtParams">
|
||||||
<ng-container *ngIf="!p.hasSelFunction">
|
<ng-container *ngIf="!p.hasSelFunction">
|
||||||
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%;"
|
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%;" *ngIf="p.type != 'BOOLEAN'">
|
||||||
*ngIf="p.type != 'BOOLEAN'">
|
<mat-label>
|
||||||
<mat-label>
|
<b>{{selectedProtocol}}</b> - {{p.label}}
|
||||||
<b>{{selectedProtocol}}</b> - {{p.label}}
|
<b *ngIf="p.type == 'LIST'">(Comma separeted values)</b>
|
||||||
<b *ngIf="p.type == 'LIST'">(Comma separeted values)</b>
|
<b *ngIf="p.type == 'INT'">(Numeric)</b>
|
||||||
<b *ngIf="p.type == 'INT'">(Numeric)</b>
|
</mat-label>
|
||||||
</mat-label>
|
<input matInput [formControlName]="paramPrefix + p.name" />
|
||||||
<input matInput [formControlName]="paramPrefix + p.name" />
|
<mat-error *ngIf="addApiForm.get(paramPrefix + p.name)?.invalid">Invalid value</mat-error>
|
||||||
<mat-error *ngIf="addApiForm.get(paramPrefix + p.name)?.invalid">Invalid value</mat-error>
|
</mat-form-field>
|
||||||
</mat-form-field>
|
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%;" *ngIf="p.type == 'BOOLEAN'">
|
||||||
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%;"
|
<mat-label><b>{{selectedProtocol}}</b> - {{p.label}} <b>(true/false)</b></mat-label>
|
||||||
*ngIf="p.type == 'BOOLEAN'">
|
<mat-select matInput [formControlName]="paramPrefix + p.name">
|
||||||
<mat-label><b>{{selectedProtocol}}</b> - {{p.label}} <b>(true/false)</b></mat-label>
|
<mat-option></mat-option>
|
||||||
<mat-select matInput [formControlName]="paramPrefix + p.name">
|
<mat-option value="true">true</mat-option>
|
||||||
<mat-option></mat-option>
|
<mat-option value="false">false</mat-option>
|
||||||
<mat-option value="true">true</mat-option>
|
</mat-select>
|
||||||
<mat-option value="false">false</mat-option>
|
<mat-error *ngIf="addApiForm.get(paramPrefix + p.name)?.invalid">Invalid value</mat-error>
|
||||||
</mat-select>
|
</mat-form-field>
|
||||||
<mat-error *ngIf="addApiForm.get(paramPrefix + p.name)?.invalid">Invalid value</mat-error>
|
</ng-container>
|
||||||
</mat-form-field>
|
|
||||||
</ng-container>
|
|
||||||
|
|
||||||
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%;" *ngIf="p.hasSelFunction">
|
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%;" *ngIf="p.hasSelFunction">
|
||||||
<mat-label><b>{{selectedProtocol}}</b> - {{p.label}} <b *ngIf="p.type == 'LIST'">(multiple choice)</b></mat-label>
|
<mat-label><b>{{selectedProtocol}}</b> - {{p.label}} <b *ngIf="p.type == 'LIST'">(multiple
|
||||||
<mat-select matInput [formControlName]="paramPrefix + p.name" [multiple]="p.type == 'LIST'">
|
choice)</b></mat-label>
|
||||||
<mat-option *ngIf="p.type != 'LIST'"></mat-option>
|
<mat-select matInput [formControlName]="paramPrefix + p.name" [multiple]="p.type == 'LIST'">
|
||||||
<mat-option value="0">0 - TODO</mat-option>
|
<mat-option *ngIf="p.type != 'LIST'"></mat-option>
|
||||||
<mat-option value="1">1 - TODO</mat-option>
|
<mat-option value="0">0 - TODO</mat-option>
|
||||||
<mat-option value="2">2 - TODO</mat-option>
|
<mat-option value="1">1 - TODO</mat-option>
|
||||||
<mat-option value="3">3 - TODO</mat-option>
|
<mat-option value="2">2 - TODO</mat-option>
|
||||||
</mat-select>
|
<mat-option value="3">3 - TODO</mat-option>
|
||||||
<mat-error *ngIf="addApiForm.get(paramPrefix + p.name)?.invalid">Invalid value</mat-error>
|
</mat-select>
|
||||||
</mat-form-field>
|
<mat-error *ngIf="addApiForm.get(paramPrefix + p.name)?.invalid">Invalid value</mat-error>
|
||||||
</ng-container>
|
</mat-form-field>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
|
||||||
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%;">
|
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%;">
|
||||||
<mat-label>XPath for Metatadata Identifier</mat-label>
|
<mat-label>XPath for Metatadata Identifier</mat-label>
|
||||||
<input matInput formControlName="metadataIdentifierPath" />
|
<input matInput formControlName="metadataIdentifierPath" />
|
||||||
<mat-error *ngIf="addApiForm.get('metadataIdentifierPath')?.invalid">This field is
|
<mat-error *ngIf="addApiForm.get('metadataIdentifierPath')?.invalid">This field is
|
||||||
<strong>required</strong></mat-error>
|
<strong>required</strong></mat-error>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</mat-card-content>
|
</mat-card-content>
|
||||||
</mat-card>
|
</mat-card>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div mat-dialog-actions>
|
<div mat-dialog-actions>
|
||||||
<button mat-stroked-button color="primary" type="submit" [disabled]="!addApiForm.valid">Submit</button>
|
<button mat-stroked-button color="primary" type="submit" [disabled]="!addApiForm.valid">Submit</button>
|
||||||
<button mat-stroked-button color="primary" mat-dialog-close>Close</button>
|
<button mat-stroked-button color="primary" mat-dialog-close>Close</button>
|
||||||
<mat-error *ngIf="addApiForm.errors?.['serverError']">
|
<mat-error *ngIf="addApiForm.errors?.['serverError']">
|
||||||
{{ addApiForm.errors?.['serverError'] }}
|
{{ addApiForm.errors?.['serverError'] }}
|
||||||
</mat-error>
|
</mat-error>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
|
@ -139,4 +139,4 @@
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
<button type="submit" class="btn btn-sm btn-primary">Add API</button>
|
<button type="submit" class="btn btn-sm btn-primary">Add API</button>
|
||||||
-->
|
-->
|
||||||
|
|
|
@ -1,36 +1,39 @@
|
||||||
<h1 mat-dialog-title>{{data.label}}</h1>
|
<h1 mat-dialog-title>{{data.label}}</h1>
|
||||||
|
|
||||||
<div mat-dialog-content>
|
<div mat-dialog-content>
|
||||||
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%; margin-top: 10px;">
|
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%; margin-top: 10px;">
|
||||||
<mat-label>Filter</mat-label>
|
<mat-label>Filter</mat-label>
|
||||||
<input matInput (keyup)="applyFilter($event)" placeholder="Filter..." #input />
|
<input matInput (keyup)="applyFilter($event)" placeholder="Filter..." #input />
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
<table mat-table [dataSource]="datasource" matSort class="mat-elevation-z8">
|
<table mat-table [dataSource]="datasource" matSort class="mat-elevation-z8">
|
||||||
|
|
||||||
<ng-container matColumnDef="name">
|
<ng-container matColumnDef="name">
|
||||||
<th mat-header-cell *matHeaderCellDef style="width: 70%;" mat-sort-header sortActionDescription="Sort by Term">Name</th>
|
<th mat-header-cell *matHeaderCellDef style="width: 70%;" mat-sort-header sortActionDescription="Sort by Term">
|
||||||
<td mat-cell *matCellDef="let element">
|
Name</th>
|
||||||
<a [routerLink]="['/dsm/results/0/50']" [queryParams]="{field: data.field, value: element.term}" mat-dialog-close>{{element.name}}</a>
|
<td mat-cell *matCellDef="let element">
|
||||||
</td>
|
<a [routerLink]="['/dsm/results/0/50']" [queryParams]="{field: data.field, value: element.term}"
|
||||||
</ng-container>
|
mat-dialog-close>{{element.name}}</a>
|
||||||
|
</td>
|
||||||
<ng-container matColumnDef="total">
|
</ng-container>
|
||||||
<th mat-header-cell *matHeaderCellDef style="width: 30%;" mat-sort-header sortActionDescription="Sort by Total"> # datasources </th>
|
|
||||||
<td mat-cell *matCellDef="let element"> {{element.total}} </td>
|
<ng-container matColumnDef="total">
|
||||||
</ng-container>
|
<th mat-header-cell *matHeaderCellDef style="width: 30%;" mat-sort-header sortActionDescription="Sort by Total"> #
|
||||||
|
datasources </th>
|
||||||
<tr mat-header-row *matHeaderRowDef="colums"></tr>
|
<td mat-cell *matCellDef="let element"> {{element.total}} </td>
|
||||||
<tr mat-row *matRowDef="let row; columns: colums;"></tr>
|
</ng-container>
|
||||||
|
|
||||||
<!-- Row shown when there is no matching data. -->
|
<tr mat-header-row *matHeaderRowDef="colums"></tr>
|
||||||
<tr class="mat-row" *matNoDataRow>
|
<tr mat-row *matRowDef="let row; columns: colums;"></tr>
|
||||||
<td class="mat-cell" colspan="2" style="padding: 0 16px;">No data matching the filter "{{input.value}}"</td>
|
|
||||||
</tr>
|
<!-- Row shown when there is no matching data. -->
|
||||||
</table>
|
<tr class="mat-row" *matNoDataRow>
|
||||||
|
<td class="mat-cell" colspan="2" style="padding: 0 16px;">No data matching the filter "{{input.value}}"</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div mat-dialog-actions>
|
<div mat-dialog-actions>
|
||||||
<button mat-stroked-button color="primary" mat-dialog-close>Close</button>
|
<button mat-stroked-button color="primary" mat-dialog-close>Close</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,92 +1,89 @@
|
||||||
<h2>Datasource Manager: Results</h2>
|
<h2>Datasource Manager: Results</h2>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<span *ngIf="field">Searching for <b>{{field}}</b> = <i>"{{value}}"</i></span>
|
<span *ngIf="field">Searching for <b>{{field}}</b> = <i>"{{value}}"</i></span>
|
||||||
<span *ngIf="!field && value">Searching for <i>"{{value}}"</i></span>
|
<span *ngIf="!field && value">Searching for <i>"{{value}}"</i></span>
|
||||||
<span *ngIf="!field && !value">Returning all the datasources</span>
|
<span *ngIf="!field && !value">Returning all the datasources</span>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%; margin-top: 10px;">
|
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%; margin-top: 10px;">
|
||||||
<mat-label><b>Filter in current page</b> (Total: {{(results | searchFilter: filterText).length}})</mat-label>
|
<mat-label><b>Filter in current page</b> (Total: {{(results | searchFilter: filterText).length}})</mat-label>
|
||||||
<input matInput [(ngModel)]="filterText" placeholder="Filter..." autofocus />
|
<input matInput [(ngModel)]="filterText" placeholder="Filter..." autofocus />
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
<mat-paginator (page)="changePage($event)"
|
<mat-paginator (page)="changePage($event)" [pageIndex]="currPage" [pageSize]="pageSize" [length]="nResults"
|
||||||
[pageIndex]="currPage"
|
[pageSize]="pageSize" [pageSizeOptions]="[10, 25, 50, 100]" aria-label="Select page">
|
||||||
[pageSize]="pageSize"
|
|
||||||
[length]="nResults"
|
|
||||||
[pageSize]="pageSize"
|
|
||||||
[pageSizeOptions]="[10, 25, 50, 100]"
|
|
||||||
aria-label="Select page">
|
|
||||||
</mat-paginator>
|
</mat-paginator>
|
||||||
|
|
||||||
<mat-card *ngFor="let r of results | searchFilter: filterText" style="margin-top: 10px;">
|
<mat-card *ngFor="let r of results | searchFilter: filterText" style="margin-top: 10px;">
|
||||||
<mat-card-header>
|
<mat-card-header>
|
||||||
<mat-card-title>{{r.name}}</mat-card-title>
|
<mat-card-title>{{r.name}}</mat-card-title>
|
||||||
<mat-card-subtitle *ngIf="r.otherName && r.name != r.otherName">{{r.otherName}}</mat-card-subtitle>
|
<mat-card-subtitle *ngIf="r.otherName && r.name != r.otherName">{{r.otherName}}</mat-card-subtitle>
|
||||||
</mat-card-header>
|
</mat-card-header>
|
||||||
<mat-card-content>
|
<mat-card-content>
|
||||||
<table class="dsm-result-table">
|
<table class="dsm-result-table">
|
||||||
<tr>
|
<tr>
|
||||||
<th>Id</th>
|
<th>Id</th>
|
||||||
<td>{{r.id}}</td>
|
<td>{{r.id}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Type</th>
|
<th>Type</th>
|
||||||
<td>{{r.type}}</td>
|
<td>{{r.type}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Namespace Prefix</th>
|
<th>Namespace Prefix</th>
|
||||||
<td>{{r.nsprefix}}</td>
|
<td>{{r.nsprefix}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Collected From</th>
|
<th>Collected From</th>
|
||||||
<td>{{r.collectedFrom}}</td>
|
<td>{{r.collectedFrom}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr *ngIf="r.websiteUrl">
|
<tr *ngIf="r.websiteUrl">
|
||||||
<th>URL</th><td><a href="{{r.websiteUrl}}" target="_blank">{{r.websiteUrl}}</a></td>
|
<th>URL</th>
|
||||||
</tr>
|
<td><a href="{{r.websiteUrl}}" target="_blank">{{r.websiteUrl}}</a></td>
|
||||||
<tr *ngIf="r.organizations && r.organizations.length > 0">
|
</tr>
|
||||||
<th>Organization(s)</th>
|
<tr *ngIf="r.organizations && r.organizations.length > 0">
|
||||||
<td>
|
<th>Organization(s)</th>
|
||||||
<span *ngFor="let o of r.organizations">
|
<td>
|
||||||
{{o.name}}
|
<span *ngFor="let o of r.organizations">
|
||||||
<img src="assets/images/flags/{{o.country}}.gif" title="{{o.country}}" alt="{{o.country}}" *ngIf="o.country"/>
|
{{o.name}}
|
||||||
<br />
|
<img src="assets/images/flags/{{o.country}}.gif" title="{{o.country}}" alt="{{o.country}}"
|
||||||
</span>
|
*ngIf="o.country" />
|
||||||
</td>
|
<br />
|
||||||
</tr>
|
</span>
|
||||||
<tr>
|
</td>
|
||||||
<th>APIs</th>
|
</tr>
|
||||||
<td>
|
<tr>
|
||||||
<ng-container *ngFor="let a of r.apis">
|
<th>APIs</th>
|
||||||
<p *ngIf="a.id" style="border-bottom: 1px solid lightgrey;">
|
<td>
|
||||||
<a [routerLink]="['/dsm/api']" [queryParams]="{id: a.id}" style="margin-right: 0.5em;">{{a.id}}</a>
|
<ng-container *ngFor="let a of r.apis">
|
||||||
<span class="badge-label badge-default" title="protocol">{{a.protocol}}</span>
|
<p *ngIf="a.id" style="border-bottom: 1px solid lightgrey;">
|
||||||
<span class="badge-label badge-info" title="compliance">{{a.compliance}}</span>
|
<a [routerLink]="['/dsm/api']" [queryParams]="{id: a.id}" style="margin-right: 0.5em;">{{a.id}}</a>
|
||||||
<span class="badge-label badge-success" *ngIf="a.active">active</span>
|
<span class="badge-label badge-default" title="protocol">{{a.protocol}}</span>
|
||||||
<span class="badge-label badge-failure" *ngIf="!a.active">not active</span>
|
<span class="badge-label badge-info" title="compliance">{{a.compliance}}</span>
|
||||||
<span *ngIf="a.aggrDate">
|
<span class="badge-label badge-success" *ngIf="a.active">active</span>
|
||||||
<br/>
|
<span class="badge-label badge-failure" *ngIf="!a.active">not active</span>
|
||||||
<b>Last aggregation:</b>
|
<span *ngIf="a.aggrDate">
|
||||||
{{a.aggrDate}}
|
<br />
|
||||||
<b>(total: {{a.aggrTotal}})</b>
|
<b>Last aggregation:</b>
|
||||||
</span>
|
{{a.aggrDate}}
|
||||||
</p>
|
<b>(total: {{a.aggrTotal}})</b>
|
||||||
</ng-container>
|
</span>
|
||||||
<button mat-raised-button color="primary" (click)="openAddApiDialog(r.id, r.name)">add api</button>
|
</p>
|
||||||
</td>
|
</ng-container>
|
||||||
</tr>
|
<button mat-raised-button color="primary" (click)="openAddApiDialog(r.id, r.name)">add api</button>
|
||||||
<tr *ngIf="r.consenttermsofuse">
|
</td>
|
||||||
<th>Consent Terms of Use</th>
|
</tr>
|
||||||
<td>YES</td>
|
<tr *ngIf="r.consenttermsofuse">
|
||||||
</tr>
|
<th>Consent Terms of Use</th>
|
||||||
<tr *ngIf="r.fulltextdownload">
|
<td>YES</td>
|
||||||
<th>Fulltext Download</th>
|
</tr>
|
||||||
<td>YES</td>
|
<tr *ngIf="r.fulltextdownload">
|
||||||
</tr>
|
<th>Fulltext Download</th>
|
||||||
</table>
|
<td>YES</td>
|
||||||
</mat-card-content>
|
</tr>
|
||||||
|
</table>
|
||||||
|
</mat-card-content>
|
||||||
</mat-card>
|
</mat-card>
|
||||||
|
|
||||||
|
|
||||||
|
@ -97,11 +94,6 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<mat-paginator (page)="changePage($event)"
|
<mat-paginator (page)="changePage($event)" [pageIndex]="currPage" [pageSize]="pageSize" [length]="nResults"
|
||||||
[pageIndex]="currPage"
|
[pageSize]="pageSize" [pageSizeOptions]="[10, 25, 50, 100]" aria-label="Select page">
|
||||||
[pageSize]="pageSize"
|
</mat-paginator>
|
||||||
[length]="nResults"
|
|
||||||
[pageSize]="pageSize"
|
|
||||||
[pageSizeOptions]="[10, 25, 50, 100]"
|
|
||||||
aria-label="Select page">
|
|
||||||
</mat-paginator>
|
|
||||||
|
|
|
@ -1,18 +1,17 @@
|
||||||
<h2>Datasource Manager: Search</h2>
|
<h2>Datasource Manager: Search</h2>
|
||||||
|
|
||||||
<form (ngSubmit)="search()">
|
<form (ngSubmit)="search()">
|
||||||
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%;">
|
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%;">
|
||||||
<mat-label>Search...</mat-label>
|
<mat-label>Search...</mat-label>
|
||||||
<input matInput [(ngModel)]="searchText" name="searchText" autofocus />
|
<input matInput [(ngModel)]="searchText" name="searchText" autofocus />
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<h4>Or browse using:</h4>
|
<h4>Or browse using:</h4>
|
||||||
<ul>
|
<ul>
|
||||||
<li *ngFor="let f of browsableFields">
|
<li *ngFor="let f of browsableFields">
|
||||||
<a (click)="browseField(f.k, f.v)">{{f.v}}</a>
|
<a (click)="browseField(f.k, f.v)">{{f.v}}</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -1,20 +1,21 @@
|
||||||
.dsm-result-table {
|
.dsm-result-table {
|
||||||
margin-top: 1em;
|
margin-top: 1em;
|
||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dsm-result-table tr:not(:last-child) {
|
.dsm-result-table tr:not(:last-child) {
|
||||||
border-bottom: 1pt solid lightgrey;
|
border-bottom: 1pt solid lightgrey;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dsm-result-table th, .dsm-result-table td{
|
.dsm-result-table th,
|
||||||
text-align: left;
|
.dsm-result-table td {
|
||||||
font-size: 0.9em;
|
text-align: left;
|
||||||
vertical-align: top;
|
font-size: 0.9em;
|
||||||
|
vertical-align: top;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dsm-result-table td button {
|
.dsm-result-table td button {
|
||||||
font-size: 0.8em !important;
|
font-size: 0.8em !important;
|
||||||
padding: 0 !important;
|
padding: 0 !important;
|
||||||
height: 2.5em !important;
|
height: 2.5em !important;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,240 +12,240 @@ import { FormBuilder, FormControl, FormGroup, ValidatorFn, Validators } from '@a
|
||||||
import { MatSelectChange } from '@angular/material/select';
|
import { MatSelectChange } from '@angular/material/select';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-dsm-search',
|
selector: 'app-dsm-search',
|
||||||
templateUrl: './dsm-search.component.html',
|
templateUrl: './dsm-search.component.html',
|
||||||
styleUrls: ['./dsm.component.css']
|
styleUrls: ['./dsm.component.css']
|
||||||
})
|
})
|
||||||
export class DsmSearchComponent implements OnInit {
|
export class DsmSearchComponent implements OnInit {
|
||||||
searchText:string = '';
|
searchText: string = '';
|
||||||
browsableFields:KeyValue[] = [];
|
browsableFields: KeyValue[] = [];
|
||||||
|
|
||||||
constructor(public service: ISService, public route: ActivatedRoute, public router: Router, public dialog: MatDialog) {
|
constructor(public service: ISService, public route: ActivatedRoute, public router: Router, public dialog: MatDialog) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.service.dsmBrowsableFields((data: KeyValue[]) => this.browsableFields = data);
|
this.service.dsmBrowsableFields((data: KeyValue[]) => this.browsableFields = data);
|
||||||
}
|
}
|
||||||
|
|
||||||
search() {
|
search() {
|
||||||
this.router.navigate(['/dsm/results/0/50'], {
|
this.router.navigate(['/dsm/results/0/50'], {
|
||||||
queryParams: { value: this.searchText }
|
queryParams: { value: this.searchText }
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
browseField(field:string, label:string) {
|
browseField(field: string, label: string) {
|
||||||
const dialogRef = this.dialog.open(DsmBrowseDialog, {
|
const dialogRef = this.dialog.open(DsmBrowseDialog, {
|
||||||
data: { field: field, label: label },
|
data: { field: field, label: label },
|
||||||
width: '80%'
|
width: '80%'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-dsm-results',
|
selector: 'app-dsm-results',
|
||||||
templateUrl: './dsm-results.component.html',
|
templateUrl: './dsm-results.component.html',
|
||||||
styleUrls: ['./dsm.component.css']
|
styleUrls: ['./dsm.component.css']
|
||||||
})
|
})
|
||||||
export class DsmResultsComponent implements OnInit {
|
export class DsmResultsComponent implements OnInit {
|
||||||
filterText:string = '';
|
filterText: string = '';
|
||||||
results:Datasource[] = [];
|
results: Datasource[] = [];
|
||||||
nResults:number = 0;
|
nResults: number = 0;
|
||||||
currPage:number = 0;
|
currPage: number = 0;
|
||||||
nPages:number = 0;
|
nPages: number = 0;
|
||||||
pageSize:number = 0;
|
pageSize: number = 0;
|
||||||
field?:string;
|
field?: string;
|
||||||
value:string = '';
|
value: string = '';
|
||||||
|
|
||||||
constructor(public service: ISService, public route: ActivatedRoute, public router: Router, public dialog: MatDialog) {
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
constructor(public service: ISService, public route: ActivatedRoute, public router: Router, public dialog: MatDialog) {
|
||||||
combineLatest([ this.route.params, this.route.queryParams ],
|
}
|
||||||
(params: Params, queryParams: Params) => ({ params, queryParams })
|
|
||||||
).subscribe((res: { params: Params; queryParams: Params }) => {
|
|
||||||
const { params, queryParams} = res;
|
|
||||||
this.currPage = parseInt(params['page']);
|
|
||||||
this.pageSize = parseInt(params['size']);
|
|
||||||
this.field = queryParams['field'];
|
|
||||||
this.value = queryParams['value'];
|
|
||||||
this.reload();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
reload() {
|
ngOnInit(): void {
|
||||||
if (this.field) {
|
combineLatest([this.route.params, this.route.queryParams],
|
||||||
this.service.dsmSearchByField(this.field, this.value, this.currPage, this.pageSize, (page:Page<Datasource>) => {
|
(params: Params, queryParams: Params) => ({ params, queryParams })
|
||||||
this.results = page.content;
|
).subscribe((res: { params: Params; queryParams: Params }) => {
|
||||||
this.nResults = page.totalElements;
|
const { params, queryParams } = res;
|
||||||
this.nPages = page.totalPages;
|
this.currPage = parseInt(params['page']);
|
||||||
});
|
this.pageSize = parseInt(params['size']);
|
||||||
} else {
|
this.field = queryParams['field'];
|
||||||
this.service.dsmSearch(this.value, this.currPage, this.pageSize, (page:Page<Datasource>) => {
|
this.value = queryParams['value'];
|
||||||
this.results = page.content;
|
this.reload();
|
||||||
this.nResults = page.totalElements;
|
});
|
||||||
this.nPages = page.totalPages;
|
}
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
changePage(event: PageEvent) {
|
reload() {
|
||||||
let path = '/dsm/results/' + event.pageIndex + '/' + event.pageSize;
|
if (this.field) {
|
||||||
let qp = this.field ?
|
this.service.dsmSearchByField(this.field, this.value, this.currPage, this.pageSize, (page: Page<Datasource>) => {
|
||||||
{ field: this.field, value: this.value } :
|
this.results = page.content;
|
||||||
{ value: this.value };
|
this.nResults = page.totalElements;
|
||||||
|
this.nPages = page.totalPages;
|
||||||
this.router.navigate([path], {
|
});
|
||||||
queryParams: qp
|
} else {
|
||||||
});
|
this.service.dsmSearch(this.value, this.currPage, this.pageSize, (page: Page<Datasource>) => {
|
||||||
}
|
this.results = page.content;
|
||||||
|
this.nResults = page.totalElements;
|
||||||
|
this.nPages = page.totalPages;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
openAddApiDialog(dsId:string, dsName:string) {
|
changePage(event: PageEvent) {
|
||||||
const dialogRef = this.dialog.open(DsmAddApiDialog, {
|
let path = '/dsm/results/' + event.pageIndex + '/' + event.pageSize;
|
||||||
data: { dsId: dsId, dsName: dsName },
|
let qp = this.field ?
|
||||||
width: '80%'
|
{ field: this.field, value: this.value } :
|
||||||
});
|
{ value: this.value };
|
||||||
|
|
||||||
dialogRef.afterClosed().subscribe(result => {
|
this.router.navigate([path], {
|
||||||
if (result) this.reload();
|
queryParams: qp
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
openAddApiDialog(dsId: string, dsName: string) {
|
||||||
|
const dialogRef = this.dialog.open(DsmAddApiDialog, {
|
||||||
|
data: { dsId: dsId, dsName: dsName },
|
||||||
|
width: '80%'
|
||||||
|
});
|
||||||
|
|
||||||
|
dialogRef.afterClosed().subscribe(result => {
|
||||||
|
if (result) this.reload();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-dsm-api',
|
selector: 'app-dsm-api',
|
||||||
templateUrl: './dsm-api.component.html',
|
templateUrl: './dsm-api.component.html',
|
||||||
styleUrls: ['./dsm.component.css']
|
styleUrls: ['./dsm.component.css']
|
||||||
})
|
})
|
||||||
export class DsmApiComponent {
|
export class DsmApiComponent {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'dsm-browse-dialog',
|
selector: 'dsm-browse-dialog',
|
||||||
templateUrl: 'dsm-browse-dialog.html',
|
templateUrl: 'dsm-browse-dialog.html',
|
||||||
styleUrls: ['./dsm.component.css']
|
styleUrls: ['./dsm.component.css']
|
||||||
})
|
})
|
||||||
export class DsmBrowseDialog implements OnInit {
|
export class DsmBrowseDialog implements OnInit {
|
||||||
|
|
||||||
datasource: MatTableDataSource<BrowseTerm> = new MatTableDataSource<BrowseTerm>([]);
|
datasource: MatTableDataSource<BrowseTerm> = new MatTableDataSource<BrowseTerm>([]);
|
||||||
colums: string[] = ['name', 'total'];
|
colums: string[] = ['name', 'total'];
|
||||||
|
|
||||||
@ViewChild(MatSort) sort: MatSort | undefined
|
|
||||||
|
|
||||||
constructor(public dialogRef: MatDialogRef<DsmBrowseDialog>, @Inject(MAT_DIALOG_DATA) public data: any, public service: ISService) {
|
@ViewChild(MatSort) sort: MatSort | undefined
|
||||||
}
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
constructor(public dialogRef: MatDialogRef<DsmBrowseDialog>, @Inject(MAT_DIALOG_DATA) public data: any, public service: ISService) {
|
||||||
this.service.dsmBrowse(this.data.field, (res:BrowseTerm[]) => this.datasource.data = res);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
ngAfterViewInit() {
|
ngOnInit(): void {
|
||||||
if (this.sort) this.datasource.sort = this.sort;
|
this.service.dsmBrowse(this.data.field, (res: BrowseTerm[]) => this.datasource.data = res);
|
||||||
}
|
}
|
||||||
|
|
||||||
applyFilter(event: Event) {
|
ngAfterViewInit() {
|
||||||
const filterValue = (event.target as HTMLInputElement).value.trim().toLowerCase();
|
if (this.sort) this.datasource.sort = this.sort;
|
||||||
this.datasource.filter = filterValue;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
onNoClick(): void {
|
applyFilter(event: Event) {
|
||||||
this.dialogRef.close();
|
const filterValue = (event.target as HTMLInputElement).value.trim().toLowerCase();
|
||||||
}
|
this.datasource.filter = filterValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
onNoClick(): void {
|
||||||
|
this.dialogRef.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'dsm-add-api-dialog',
|
selector: 'dsm-add-api-dialog',
|
||||||
templateUrl: './dsm-add-api.dialog.html',
|
templateUrl: './dsm-add-api.dialog.html',
|
||||||
styleUrls: ['./dsm.component.css']
|
styleUrls: ['./dsm.component.css']
|
||||||
})
|
})
|
||||||
export class DsmAddApiDialog {
|
export class DsmAddApiDialog {
|
||||||
selectedProtocol:string = '';
|
selectedProtocol: string = '';
|
||||||
|
|
||||||
apiPrefix:string = '';
|
apiPrefix: string = '';
|
||||||
paramPrefix:string = '__PARAM_';
|
paramPrefix: string = '__PARAM_';
|
||||||
|
|
||||||
protocols:string[] = [];
|
protocols: string[] = [];
|
||||||
compatibilityLevels:string[] = [];
|
compatibilityLevels: string[] = [];
|
||||||
contentDescTypes:string[] = [];
|
contentDescTypes: string[] = [];
|
||||||
|
|
||||||
protocolsMap:any = {};
|
protocolsMap: any = {};
|
||||||
selProtParams:ProtocolParam[] = [];
|
selProtParams: ProtocolParam[] = [];
|
||||||
|
|
||||||
addApiForm:FormGroup = new FormGroup({
|
addApiForm: FormGroup = new FormGroup({
|
||||||
apiIdSuffix: new FormControl('', [Validators.required]),
|
apiIdSuffix: new FormControl('', [Validators.required]),
|
||||||
compatibility : new FormControl('', [Validators.required]),
|
compatibility: new FormControl('', [Validators.required]),
|
||||||
contentdescription : new FormControl('', [Validators.required]),
|
contentdescription: new FormControl('', [Validators.required]),
|
||||||
protocol : new FormControl('', [Validators.required]),
|
protocol: new FormControl('', [Validators.required]),
|
||||||
baseurl : new FormControl('', [Validators.required, Validators.pattern('^(http|https|ftp|file|sftp|jar|mongodb):\/\/')]),
|
baseurl: new FormControl('', [Validators.required, Validators.pattern('^(http|https|ftp|file|sftp|jar|mongodb):\/\/')]),
|
||||||
metadataIdentifierPath : new FormControl('', [Validators.required])
|
metadataIdentifierPath: new FormControl('', [Validators.required])
|
||||||
});
|
});
|
||||||
|
|
||||||
constructor(public dialogRef: MatDialogRef<DsmAddApiDialog>, @Inject(MAT_DIALOG_DATA) public data: any, public service: ISService) {
|
constructor(public dialogRef: MatDialogRef<DsmAddApiDialog>, @Inject(MAT_DIALOG_DATA) public data: any, public service: ISService) {
|
||||||
this.apiPrefix = 'api_________::' + data.dsId + '::';
|
this.apiPrefix = 'api_________::' + data.dsId + '::';
|
||||||
this.service.dsmConf((conf:DsmConf) => {
|
this.service.dsmConf((conf: DsmConf) => {
|
||||||
this.compatibilityLevels = conf.compatibilityLevels;
|
this.compatibilityLevels = conf.compatibilityLevels;
|
||||||
this.contentDescTypes = conf.contentDescTypes;
|
this.contentDescTypes = conf.contentDescTypes;
|
||||||
conf.protocols.forEach((p) => {
|
conf.protocols.forEach((p) => {
|
||||||
this.protocols.push(p.id);
|
this.protocols.push(p.id);
|
||||||
this.protocolsMap[p.id] = p.params;
|
this.protocolsMap[p.id] = p.params;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
onChangeProtocol(e:MatSelectChange):void {
|
onChangeProtocol(e: MatSelectChange): void {
|
||||||
this.selectedProtocol = e.value;
|
this.selectedProtocol = e.value;
|
||||||
|
|
||||||
Object.keys(this.addApiForm.controls).forEach(k => {
|
Object.keys(this.addApiForm.controls).forEach(k => {
|
||||||
if (k.startsWith(this.paramPrefix)) {
|
if (k.startsWith(this.paramPrefix)) {
|
||||||
this.addApiForm.removeControl(k);
|
this.addApiForm.removeControl(k);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (this.protocolsMap[e.value]) {
|
|
||||||
this.selProtParams = this.protocolsMap[e.value];
|
|
||||||
this.selProtParams.forEach(p => {
|
|
||||||
let validations:ValidatorFn[] = [];
|
|
||||||
if (!p.optional) { validations.push(Validators.required); }
|
|
||||||
if (p.type == 'INT') { validations.push(Validators.pattern('^[0-9]*$')); }
|
|
||||||
this.addApiForm.addControl(this.paramPrefix + p.name, new FormControl('', validations));
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
this.selProtParams = [];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onSubmit():void {
|
if (this.protocolsMap[e.value]) {
|
||||||
let api:ApiInsert = {
|
this.selProtParams = this.protocolsMap[e.value];
|
||||||
id: this.apiPrefix + this.addApiForm.get('apiIdSuffix')?.value,
|
this.selProtParams.forEach(p => {
|
||||||
protocol: this.selectedProtocol,
|
let validations: ValidatorFn[] = [];
|
||||||
datasource: this.data.dsId,
|
if (!p.optional) { validations.push(Validators.required); }
|
||||||
contentdescription: this.addApiForm.get('contentdescription')?.value,
|
if (p.type == 'INT') { validations.push(Validators.pattern('^[0-9]*$')); }
|
||||||
removable: true,
|
this.addApiForm.addControl(this.paramPrefix + p.name, new FormControl('', validations));
|
||||||
compatibility: this.addApiForm.get('compatibility')?.value,
|
});
|
||||||
metadataIdentifierPath: this.addApiForm.get('metadataIdentifierPath')?.value,
|
} else {
|
||||||
baseurl: this.addApiForm.get('baseurl')?.value,
|
this.selProtParams = [];
|
||||||
apiParams : []
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
Object.keys(this.addApiForm.controls).forEach(k => {
|
onSubmit(): void {
|
||||||
if (k.startsWith(this.paramPrefix)) {
|
let api: ApiInsert = {
|
||||||
let val = this.addApiForm.get(k)?.value;
|
id: this.apiPrefix + this.addApiForm.get('apiIdSuffix')?.value,
|
||||||
if (val) {
|
protocol: this.selectedProtocol,
|
||||||
api.apiParams.push({
|
datasource: this.data.dsId,
|
||||||
param: k.substring(this.paramPrefix.length),
|
contentdescription: this.addApiForm.get('contentdescription')?.value,
|
||||||
value: (Array.isArray(val)) ? val.join() : val
|
removable: true,
|
||||||
});
|
compatibility: this.addApiForm.get('compatibility')?.value,
|
||||||
}
|
metadataIdentifierPath: this.addApiForm.get('metadataIdentifierPath')?.value,
|
||||||
}
|
baseurl: this.addApiForm.get('baseurl')?.value,
|
||||||
});
|
apiParams: []
|
||||||
console.log(api);
|
};
|
||||||
//this.service.dsmAddApi(api, (data: void) => this.dialogRef.close(1), this.metadataForm);
|
|
||||||
}
|
Object.keys(this.addApiForm.controls).forEach(k => {
|
||||||
|
if (k.startsWith(this.paramPrefix)) {
|
||||||
onNoClick(): void {
|
let val = this.addApiForm.get(k)?.value;
|
||||||
this.dialogRef.close();
|
if (val) {
|
||||||
}
|
api.apiParams.push({
|
||||||
|
param: k.substring(this.paramPrefix.length),
|
||||||
|
value: (Array.isArray(val)) ? val.join() : val
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
console.log(api);
|
||||||
|
//this.service.dsmAddApi(api, (data: void) => this.dialogRef.close(1), this.metadataForm);
|
||||||
|
}
|
||||||
|
|
||||||
|
onNoClick(): void {
|
||||||
|
this.dialogRef.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,66 +1,66 @@
|
||||||
<h2>Container Info</h2>
|
<h2>Container Info</h2>
|
||||||
|
|
||||||
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%;">
|
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%;">
|
||||||
<mat-label>Filter</mat-label>
|
<mat-label>Filter</mat-label>
|
||||||
<input matInput (keyup)="applyFilter($event)" placeholder="Filter..." #input />
|
<input matInput (keyup)="applyFilter($event)" placeholder="Filter..." #input />
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
<div *ngFor="let section of kvDatasources">
|
<div *ngFor="let section of kvDatasources">
|
||||||
<div style="margin-top: 2em;" *ngIf="section.datasource.filteredData.length > 0">
|
<div style="margin-top: 2em;" *ngIf="section.datasource.filteredData.length > 0">
|
||||||
<h3>{{section.name}}</h3>
|
<h3>{{section.name}}</h3>
|
||||||
<table mat-table [dataSource]="section.datasource" class="mat-elevation-z8">
|
<table mat-table [dataSource]="section.datasource" class="mat-elevation-z8">
|
||||||
|
|
||||||
<ng-container matColumnDef="k">
|
<ng-container matColumnDef="k">
|
||||||
<th mat-header-cell *matHeaderCellDef> Property </th>
|
<th mat-header-cell *matHeaderCellDef> Property </th>
|
||||||
<td mat-cell *matCellDef="let element" style="width: 30%"> {{element.k}} </td>
|
<td mat-cell *matCellDef="let element" style="width: 30%"> {{element.k}} </td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<ng-container matColumnDef="v">
|
<ng-container matColumnDef="v">
|
||||||
<th mat-header-cell *matHeaderCellDef> Value </th>
|
<th mat-header-cell *matHeaderCellDef> Value </th>
|
||||||
<td mat-cell *matCellDef="let element" style="width: 70%"> {{element.v}} </td>
|
<td mat-cell *matCellDef="let element" style="width: 70%"> {{element.v}} </td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<tr mat-row *matRowDef="let row; columns: displayedKVColumns;"></tr>
|
<tr mat-row *matRowDef="let row; columns: displayedKVColumns;"></tr>
|
||||||
|
|
||||||
<!-- Row shown when there is no matching data. -->
|
<!-- Row shown when there is no matching data. -->
|
||||||
<tr class="mat-row" *matNoDataRow>
|
<tr class="mat-row" *matNoDataRow>
|
||||||
<td class="mat-cell" colspan="2" style="padding: 0 16px;">No data matching the filter "{{input.value}}"</td>
|
<td class="mat-cell" colspan="2" style="padding: 0 16px;">No data matching the filter "{{input.value}}"</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div style="margin-top: 3em;" *ngIf="moduleDatasource.filteredData.length > 0">
|
<div style="margin-top: 3em;" *ngIf="moduleDatasource.filteredData.length > 0">
|
||||||
<h3>Modules</h3>
|
<h3>Modules</h3>
|
||||||
<table mat-table [dataSource]="moduleDatasource" class="mat-elevation-z8">
|
<table mat-table [dataSource]="moduleDatasource" class="mat-elevation-z8">
|
||||||
|
|
||||||
<ng-container matColumnDef="group">
|
<ng-container matColumnDef="group">
|
||||||
<th mat-header-cell *matHeaderCellDef style="width: 15%;"> Group </th>
|
<th mat-header-cell *matHeaderCellDef style="width: 15%;"> Group </th>
|
||||||
<td mat-cell *matCellDef="let element"> {{element.group}} </td>
|
<td mat-cell *matCellDef="let element"> {{element.group}} </td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<ng-container matColumnDef="name">
|
<ng-container matColumnDef="name">
|
||||||
<th mat-header-cell *matHeaderCellDef style="width: 15%;"> Name </th>
|
<th mat-header-cell *matHeaderCellDef style="width: 15%;"> Name </th>
|
||||||
<td mat-cell *matCellDef="let element"> {{element.name}} </td>
|
<td mat-cell *matCellDef="let element"> {{element.name}} </td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<ng-container matColumnDef="versions">
|
<ng-container matColumnDef="versions">
|
||||||
<th mat-header-cell *matHeaderCellDef style="width: 10%;"> Versions </th>
|
<th mat-header-cell *matHeaderCellDef style="width: 10%;"> Versions </th>
|
||||||
<td mat-cell *matCellDef="let element"> <span *ngFor="let v of element.versions">{{v}}<br /></span> </td>
|
<td mat-cell *matCellDef="let element"> <span *ngFor="let v of element.versions">{{v}}<br /></span> </td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<ng-container matColumnDef="files">
|
<ng-container matColumnDef="files">
|
||||||
<th mat-header-cell *matHeaderCellDef style="width: 60%;"> Files </th>
|
<th mat-header-cell *matHeaderCellDef style="width: 60%;"> Files </th>
|
||||||
<td mat-cell *matCellDef="let element"> <span *ngFor="let f of element.files">{{f}}<br /></span> </td>
|
<td mat-cell *matCellDef="let element"> <span *ngFor="let f of element.files">{{f}}<br /></span> </td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<tr mat-header-row *matHeaderRowDef="displayedModuleColumns"></tr>
|
<tr mat-header-row *matHeaderRowDef="displayedModuleColumns"></tr>
|
||||||
<tr mat-row *matRowDef="let row; columns: displayedModuleColumns;"></tr>
|
<tr mat-row *matRowDef="let row; columns: displayedModuleColumns;"></tr>
|
||||||
|
|
||||||
<!-- Row shown when there is no matching data. -->
|
<!-- Row shown when there is no matching data. -->
|
||||||
<tr class="mat-row" *matNoDataRow>
|
<tr class="mat-row" *matNoDataRow>
|
||||||
<td class="mat-cell" colspan="4" style="padding: 0 16px;">No data matching the filter "{{input.value}}"</td>
|
<td class="mat-cell" colspan="4" style="padding: 0 16px;">No data matching the filter "{{input.value}}"</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -4,42 +4,42 @@ import { MatTableDataSource } from '@angular/material/table';
|
||||||
import { Module } from '../common/is.model';
|
import { Module } from '../common/is.model';
|
||||||
|
|
||||||
export interface KeyValueDatasource {
|
export interface KeyValueDatasource {
|
||||||
name: string;
|
name: string;
|
||||||
datasource: MatTableDataSource<any>;
|
datasource: MatTableDataSource<any>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-info',
|
selector: 'app-info',
|
||||||
templateUrl: './info.component.html',
|
templateUrl: './info.component.html',
|
||||||
styleUrls: ['./info.component.css']
|
styleUrls: ['./info.component.css']
|
||||||
})
|
})
|
||||||
export class InfoComponent {
|
export class InfoComponent {
|
||||||
|
|
||||||
kvDatasources:KeyValueDatasource[] = [];
|
|
||||||
moduleDatasource:MatTableDataSource<Module> = new MatTableDataSource<Module>([]);
|
|
||||||
|
|
||||||
displayedKVColumns: string[] = ['k', 'v'];
|
kvDatasources: KeyValueDatasource[] = [];
|
||||||
displayedModuleColumns: string[] = ['group', 'name', 'versions', 'files'];
|
moduleDatasource: MatTableDataSource<Module> = new MatTableDataSource<Module>([]);
|
||||||
|
|
||||||
constructor(public service:ISService) {
|
|
||||||
this.service.loadInfo((data:any[]) => {
|
|
||||||
data.forEach(section => {
|
|
||||||
if (section['name'] == 'Modules') {
|
|
||||||
this.moduleDatasource.data = section['data'];
|
|
||||||
} else {
|
|
||||||
this.kvDatasources.push({
|
|
||||||
name: section['name'],
|
|
||||||
datasource : new MatTableDataSource(section['data'])
|
|
||||||
});
|
|
||||||
}
|
|
||||||
})
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
applyFilter(event: Event) {
|
displayedKVColumns: string[] = ['k', 'v'];
|
||||||
const filterValue = (event.target as HTMLInputElement).value.trim().toLowerCase();
|
displayedModuleColumns: string[] = ['group', 'name', 'versions', 'files'];
|
||||||
this.kvDatasources.forEach(s => s.datasource.filter = filterValue)
|
|
||||||
this.moduleDatasource.filter = filterValue;
|
constructor(public service: ISService) {
|
||||||
}
|
this.service.loadInfo((data: any[]) => {
|
||||||
|
data.forEach(section => {
|
||||||
|
if (section['name'] == 'Modules') {
|
||||||
|
this.moduleDatasource.data = section['data'];
|
||||||
|
} else {
|
||||||
|
this.kvDatasources.push({
|
||||||
|
name: section['name'],
|
||||||
|
datasource: new MatTableDataSource(section['data'])
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
applyFilter(event: Event) {
|
||||||
|
const filterValue = (event.target as HTMLInputElement).value.trim().toLowerCase();
|
||||||
|
this.kvDatasources.forEach(s => s.datasource.filter = filterValue)
|
||||||
|
this.moduleDatasource.filter = filterValue;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,37 +1,45 @@
|
||||||
.menu-count {
|
.menu-count {
|
||||||
padding-top: 0.1em;
|
padding-top: 0.1em;
|
||||||
padding-bottom: 0.1em;
|
padding-bottom: 0.1em;
|
||||||
padding-left: 0.4em;
|
padding-left: 0.4em;
|
||||||
padding-right: 0.4em;
|
padding-right: 0.4em;
|
||||||
border-radius: 1em;
|
border-radius: 1em;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
background-color:cornflowerblue;
|
background-color: cornflowerblue;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.collapse-buttons { text-align: right; }
|
.collapse-buttons {
|
||||||
.collapse-buttons button { font-size: 0.6em; }
|
text-align: right;
|
||||||
.mat-expansion-panel-spacing { margin: 0; }
|
}
|
||||||
|
|
||||||
|
.collapse-buttons button {
|
||||||
|
font-size: 0.6em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mat-expansion-panel-spacing {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.menu-item {
|
.menu-item {
|
||||||
padding-top: 0.3em;
|
padding-top: 0.3em;
|
||||||
padding-bottom: 0.3em;
|
padding-bottom: 0.3em;
|
||||||
padding-left: 7%;
|
padding-left: 7%;
|
||||||
padding-right: 3%;
|
padding-right: 3%;
|
||||||
font-size: 0.9em;
|
font-size: 0.9em;
|
||||||
width: 90%;
|
width: 90%;
|
||||||
color: #696969;
|
color: #696969;
|
||||||
text-decoration: none !important;
|
text-decoration: none !important;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu-item:hover {
|
.menu-item:hover {
|
||||||
color: #999;
|
color: #999;
|
||||||
background-color: #eaeaea;
|
background-color: #eaeaea;
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu-item .badge-label {
|
.menu-item .badge-label {
|
||||||
font-size: 0.6em;
|
font-size: 0.6em;
|
||||||
float: right;
|
float: right;
|
||||||
width: 2em;
|
width: 2em;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,80 +1,80 @@
|
||||||
<div class="collapse-buttons">
|
<div class="collapse-buttons">
|
||||||
<button mat-button color="primary" (click)="accordion.openAll()">Expand All</button>
|
<button mat-button color="primary" (click)="accordion.openAll()">Expand All</button>
|
||||||
<button mat-button color="primary" (click)="accordion.closeAll()">Collapse All</button>
|
<button mat-button color="primary" (click)="accordion.closeAll()">Collapse All</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<mat-accordion multi>
|
<mat-accordion multi>
|
||||||
<mat-expansion-panel>
|
<mat-expansion-panel>
|
||||||
<mat-expansion-panel-header>
|
<mat-expansion-panel-header>
|
||||||
<mat-panel-title>Home</mat-panel-title>
|
<mat-panel-title>Home</mat-panel-title>
|
||||||
</mat-expansion-panel-header>
|
</mat-expansion-panel-header>
|
||||||
<a class="menu-item" [routerLink]="['']">Home</a>
|
<a class="menu-item" [routerLink]="['']">Home</a>
|
||||||
</mat-expansion-panel>
|
</mat-expansion-panel>
|
||||||
<mat-expansion-panel>
|
<mat-expansion-panel>
|
||||||
<mat-expansion-panel-header>
|
<mat-expansion-panel-header>
|
||||||
<mat-panel-title>Datasources</mat-panel-title>
|
<mat-panel-title>Datasources</mat-panel-title>
|
||||||
</mat-expansion-panel-header>
|
</mat-expansion-panel-header>
|
||||||
<div>
|
<div>
|
||||||
<a class="menu-item" [routerLink]="['dsm/search']">Search</a>
|
<a class="menu-item" [routerLink]="['dsm/search']">Search</a>
|
||||||
</div>
|
</div>
|
||||||
</mat-expansion-panel>
|
</mat-expansion-panel>
|
||||||
|
|
||||||
<mat-expansion-panel>
|
<mat-expansion-panel>
|
||||||
<mat-expansion-panel-header>
|
<mat-expansion-panel-header>
|
||||||
<mat-panel-title>Simple Resources</mat-panel-title>
|
<mat-panel-title>Simple Resources</mat-panel-title>
|
||||||
</mat-expansion-panel-header>
|
</mat-expansion-panel-header>
|
||||||
<div>
|
<div>
|
||||||
<ng-container *ngFor="let r of resTypes">
|
<ng-container *ngFor="let r of resTypes">
|
||||||
<div *ngIf="r.simple">
|
<div *ngIf="r.simple">
|
||||||
<a class="menu-item" [routerLink]="['resources/' + r.id]">
|
<a class="menu-item" [routerLink]="['resources/' + r.id]">
|
||||||
{{r.name}}
|
{{r.name}}
|
||||||
<span class="badge-label badge-info">{{r.count}}</span>
|
<span class="badge-label badge-info">{{r.count}}</span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</div>
|
</div>
|
||||||
</mat-expansion-panel>
|
</mat-expansion-panel>
|
||||||
|
|
||||||
<mat-expansion-panel>
|
<mat-expansion-panel>
|
||||||
<mat-expansion-panel-header>
|
<mat-expansion-panel-header>
|
||||||
<mat-panel-title>Advanced Resources</mat-panel-title>
|
<mat-panel-title>Advanced Resources</mat-panel-title>
|
||||||
</mat-expansion-panel-header>
|
</mat-expansion-panel-header>
|
||||||
<div>
|
<div>
|
||||||
<ng-container *ngFor="let r of resTypes">
|
<ng-container *ngFor="let r of resTypes">
|
||||||
<div *ngIf="!r.simple">
|
<div *ngIf="!r.simple">
|
||||||
<a class="menu-item" [routerLink]="['adv_resources/' + r.id]">
|
<a class="menu-item" [routerLink]="['adv_resources/' + r.id]">
|
||||||
{{r.name}}
|
{{r.name}}
|
||||||
<span class="badge-label badge-info">{{r.count}}</span>
|
<span class="badge-label badge-info">{{r.count}}</span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</div>
|
</div>
|
||||||
</mat-expansion-panel>
|
</mat-expansion-panel>
|
||||||
|
|
||||||
<mat-expansion-panel>
|
<mat-expansion-panel>
|
||||||
<mat-expansion-panel-header>
|
<mat-expansion-panel-header>
|
||||||
<mat-panel-title>Tools</mat-panel-title>
|
<mat-panel-title>Tools</mat-panel-title>
|
||||||
</mat-expansion-panel-header>
|
</mat-expansion-panel-header>
|
||||||
<div>
|
<div>
|
||||||
<a class="menu-item" [routerLink]="['mdstores']">MDStore Inspector</a>
|
<a class="menu-item" [routerLink]="['mdstores']">MDStore Inspector</a>
|
||||||
</div>
|
</div>
|
||||||
</mat-expansion-panel>
|
</mat-expansion-panel>
|
||||||
|
|
||||||
<mat-expansion-panel>
|
<mat-expansion-panel>
|
||||||
<mat-expansion-panel-header>
|
<mat-expansion-panel-header>
|
||||||
<mat-panel-title>Logs</mat-panel-title>
|
<mat-panel-title>Logs</mat-panel-title>
|
||||||
</mat-expansion-panel-header>
|
</mat-expansion-panel-header>
|
||||||
<div>
|
<div>
|
||||||
<a class="menu-item" [routerLink]="['wf_history']">Workflow History</a>
|
<a class="menu-item" [routerLink]="['wf_history']">Workflow History</a>
|
||||||
</div>
|
</div>
|
||||||
</mat-expansion-panel>
|
</mat-expansion-panel>
|
||||||
|
|
||||||
<mat-expansion-panel>
|
<mat-expansion-panel>
|
||||||
<mat-expansion-panel-header>
|
<mat-expansion-panel-header>
|
||||||
<mat-panel-title>Info</mat-panel-title>
|
<mat-panel-title>Info</mat-panel-title>
|
||||||
</mat-expansion-panel-header>
|
</mat-expansion-panel-header>
|
||||||
<div>
|
<div>
|
||||||
<a class="menu-item" [routerLink]="['info']">Container Info</a>
|
<a class="menu-item" [routerLink]="['info']">Container Info</a>
|
||||||
</div>
|
</div>
|
||||||
</mat-expansion-panel>
|
</mat-expansion-panel>
|
||||||
</mat-accordion>
|
</mat-accordion>
|
||||||
|
|
|
@ -5,18 +5,18 @@ import { MatAccordion } from '@angular/material/expansion';
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-main-menu-panels',
|
selector: 'app-main-menu-panels',
|
||||||
templateUrl: './main-menu-panels.component.html',
|
templateUrl: './main-menu-panels.component.html',
|
||||||
styleUrls: ['./main-menu-panels.component.css']
|
styleUrls: ['./main-menu-panels.component.css']
|
||||||
})
|
})
|
||||||
export class MainMenuPanelsComponent {
|
export class MainMenuPanelsComponent {
|
||||||
|
|
||||||
@ViewChild(MatAccordion)
|
@ViewChild(MatAccordion)
|
||||||
accordion!:MatAccordion;
|
accordion!: MatAccordion;
|
||||||
|
|
||||||
resTypes:ResourceType[] = [];
|
resTypes: ResourceType[] = [];
|
||||||
|
|
||||||
constructor(public service:ISService) {
|
constructor(public service: ISService) {
|
||||||
this.service.loadResourceTypes((data:ResourceType[]) => this.resTypes = data);
|
this.service.loadResourceTypes((data: ResourceType[]) => this.resTypes = data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,4 +48,4 @@
|
||||||
</mat-error>
|
</mat-error>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -82,4 +82,4 @@
|
||||||
</table>
|
</table>
|
||||||
<pre class="small">{{rec.body}}</pre>
|
<pre class="small">{{rec.body}}</pre>
|
||||||
</mat-card-content>
|
</mat-card-content>
|
||||||
</mat-card>
|
</mat-card>
|
||||||
|
|
|
@ -42,4 +42,4 @@
|
||||||
|
|
||||||
<div mat-dialog-actions>
|
<div mat-dialog-actions>
|
||||||
<button mat-stroked-button color="primary" mat-dialog-close>Close</button>
|
<button mat-stroked-button color="primary" mat-dialog-close>Close</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -31,4 +31,4 @@
|
||||||
width: 1em;
|
width: 1em;
|
||||||
height: 1em;
|
height: 1em;
|
||||||
font-size: 1em;
|
font-size: 1em;
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,4 +58,4 @@
|
||||||
<button mat-stroked-button color="warn" (click)="deleteMdstore(md)">delete</button>
|
<button mat-stroked-button color="warn" (click)="deleteMdstore(md)">delete</button>
|
||||||
<button mat-stroked-button color="info">zeppelin</button>
|
<button mat-stroked-button color="info">zeppelin</button>
|
||||||
</mat-card-actions>
|
</mat-card-actions>
|
||||||
</mat-card>
|
</mat-card>
|
||||||
|
|
|
@ -174,4 +174,4 @@ export class AddMDStoreDialog {
|
||||||
onNoClick(): void {
|
onNoClick(): void {
|
||||||
this.dialogRef.close();
|
this.dialogRef.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,45 +1,45 @@
|
||||||
<h2>Harvesting Protocols</h2>
|
<h2>Harvesting Protocols</h2>
|
||||||
|
|
||||||
<div style="margin-top: 3em;" *ngFor="let prot of protDatasources">
|
<div style="margin-top: 3em;" *ngFor="let prot of protDatasources">
|
||||||
<h3>{{prot.protocol}}</h3>
|
<h3>{{prot.protocol}}</h3>
|
||||||
|
|
||||||
<table mat-table [dataSource]="prot.datasource" class="mat-elevation-z8">
|
<table mat-table [dataSource]="prot.datasource" class="mat-elevation-z8">
|
||||||
|
|
||||||
<ng-container matColumnDef="name">
|
<ng-container matColumnDef="name">
|
||||||
<th mat-header-cell *matHeaderCellDef> Name </th>
|
<th mat-header-cell *matHeaderCellDef> Name </th>
|
||||||
<td mat-cell *matCellDef="let element"> {{element.name}} </td>
|
<td mat-cell *matCellDef="let element"> {{element.name}} </td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<ng-container matColumnDef="label">
|
<ng-container matColumnDef="label">
|
||||||
<th mat-header-cell *matHeaderCellDef> Label </th>
|
<th mat-header-cell *matHeaderCellDef> Label </th>
|
||||||
<td mat-cell *matCellDef="let element"> {{element.label}} </td>
|
<td mat-cell *matCellDef="let element"> {{element.label}} </td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<ng-container matColumnDef="type">
|
<ng-container matColumnDef="type">
|
||||||
<th mat-header-cell *matHeaderCellDef> Type </th>
|
<th mat-header-cell *matHeaderCellDef> Type </th>
|
||||||
<td mat-cell *matCellDef="let element"> {{element.type}} </td>
|
<td mat-cell *matCellDef="let element"> {{element.type}} </td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<ng-container matColumnDef="optional">
|
<ng-container matColumnDef="optional">
|
||||||
<th mat-header-cell *matHeaderCellDef> Required </th>
|
<th mat-header-cell *matHeaderCellDef> Required </th>
|
||||||
<td mat-cell *matCellDef="let element">
|
<td mat-cell *matCellDef="let element">
|
||||||
<mat-icon fontIcon="check" *ngIf="!element.optional"></mat-icon>
|
<mat-icon fontIcon="check" *ngIf="!element.optional"></mat-icon>
|
||||||
</td>
|
</td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<ng-container matColumnDef="hasSelFunction">
|
<ng-container matColumnDef="hasSelFunction">
|
||||||
<th mat-header-cell *matHeaderCellDef> Has Sel Function </th>
|
<th mat-header-cell *matHeaderCellDef> Has Sel Function </th>
|
||||||
<td mat-cell *matCellDef="let element">
|
<td mat-cell *matCellDef="let element">
|
||||||
<mat-icon fontIcon="check" *ngIf="element.hasSelFunction"></mat-icon>
|
<mat-icon fontIcon="check" *ngIf="element.hasSelFunction"></mat-icon>
|
||||||
</td>
|
</td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<tr mat-header-row *matHeaderRowDef="colums"></tr>
|
<tr mat-header-row *matHeaderRowDef="colums"></tr>
|
||||||
<tr mat-row *matRowDef="let row; columns: colums;"></tr>
|
<tr mat-row *matRowDef="let row; columns: colums;"></tr>
|
||||||
|
|
||||||
<!-- Row shown when there is no matching data. -->
|
<!-- Row shown when there is no matching data. -->
|
||||||
<tr class="mat-row" *matNoDataRow>
|
<tr class="mat-row" *matNoDataRow>
|
||||||
<td class="mat-cell" colspan="5" style="padding: 0 16px;">No parameters</td>
|
<td class="mat-cell" colspan="5" style="padding: 0 16px;">No parameters</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -4,28 +4,28 @@ import { MatTableDataSource } from '@angular/material/table';
|
||||||
import { Protocol, ProtocolParam } from '../common/is.model';
|
import { Protocol, ProtocolParam } from '../common/is.model';
|
||||||
|
|
||||||
export interface ProtocolDatasource {
|
export interface ProtocolDatasource {
|
||||||
protocol: string;
|
protocol: string;
|
||||||
datasource: MatTableDataSource<ProtocolParam>;
|
datasource: MatTableDataSource<ProtocolParam>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-protocols',
|
selector: 'app-protocols',
|
||||||
templateUrl: './protocols.component.html',
|
templateUrl: './protocols.component.html',
|
||||||
styleUrls: ['./protocols.component.css']
|
styleUrls: ['./protocols.component.css']
|
||||||
})
|
})
|
||||||
export class ProtocolsComponent {
|
export class ProtocolsComponent {
|
||||||
protDatasources: ProtocolDatasource[] = [];
|
protDatasources: ProtocolDatasource[] = [];
|
||||||
colums: string[] = ['name', 'label', 'type', 'optional', 'hasSelFunction'];
|
colums: string[] = ['name', 'label', 'type', 'optional', 'hasSelFunction'];
|
||||||
|
|
||||||
constructor(public service: ISService) {
|
constructor(public service: ISService) {
|
||||||
this.service.loadProtocols((data: Protocol[]) =>
|
this.service.loadProtocols((data: Protocol[]) =>
|
||||||
data.forEach(p => {
|
data.forEach(p => {
|
||||||
this.protDatasources.push({
|
this.protDatasources.push({
|
||||||
protocol: p.id,
|
protocol: p.id,
|
||||||
datasource: new MatTableDataSource(p.params)
|
datasource: new MatTableDataSource(p.params)
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,27 +1,27 @@
|
||||||
<form [formGroup]="contentForm" (ngSubmit)="onSubmit()">
|
<form [formGroup]="contentForm" (ngSubmit)="onSubmit()">
|
||||||
|
|
||||||
<h1 mat-dialog-title>Edit content</h1>
|
<h1 mat-dialog-title>Edit content</h1>
|
||||||
|
|
||||||
<div mat-dialog-content>
|
<div mat-dialog-content>
|
||||||
|
|
||||||
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%;">
|
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%;">
|
||||||
<mat-label>ID</mat-label>
|
<mat-label>ID</mat-label>
|
||||||
<input matInput readonly value="{{data.id}}"/>
|
<input matInput readonly value="{{data.id}}" />
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%;">
|
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%;">
|
||||||
<mat-label>Content ({{data.contentType}})</mat-label>
|
<mat-label>Content ({{data.contentType}})</mat-label>
|
||||||
<textarea matInput formControlName="content" required rows="16" style="font-size: 0.8em;"></textarea>
|
<textarea matInput formControlName="content" required rows="16" style="font-size: 0.8em;"></textarea>
|
||||||
<mat-error *ngIf="contentForm.get('content')?.invalid">This field is <strong>required</strong></mat-error>
|
<mat-error *ngIf="contentForm.get('content')?.invalid">This field is <strong>required</strong></mat-error>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div mat-dialog-actions>
|
<div mat-dialog-actions>
|
||||||
<button mat-stroked-button color="primary" type="submit" [disabled]="!contentForm.valid">Submit</button>
|
<button mat-stroked-button color="primary" type="submit" [disabled]="!contentForm.valid">Submit</button>
|
||||||
<button mat-stroked-button color="primary" mat-dialog-close>Close</button>
|
<button mat-stroked-button color="primary" mat-dialog-close>Close</button>
|
||||||
<mat-error *ngIf="contentForm.errors?.['serverError']">
|
<mat-error *ngIf="contentForm.errors?.['serverError']">
|
||||||
{{ contentForm.errors?.['serverError'] }}
|
{{ contentForm.errors?.['serverError'] }}
|
||||||
</mat-error>
|
</mat-error>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -1,36 +1,36 @@
|
||||||
<form [formGroup]="metadataForm" (ngSubmit)="onSubmit()">
|
<form [formGroup]="metadataForm" (ngSubmit)="onSubmit()">
|
||||||
<h1 mat-dialog-title>Edit metadata</h1>
|
<h1 mat-dialog-title>Edit metadata</h1>
|
||||||
|
|
||||||
<div mat-dialog-content>
|
<div mat-dialog-content>
|
||||||
|
|
||||||
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%;">
|
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%;">
|
||||||
<mat-label>ID</mat-label>
|
<mat-label>ID</mat-label>
|
||||||
<input matInput readonly value="{{data.id}}"/>
|
<input matInput readonly value="{{data.id}}" />
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%;">
|
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%;">
|
||||||
<mat-label>Type</mat-label>
|
<mat-label>Type</mat-label>
|
||||||
<input matInput readonly value="{{data.type}}" />
|
<input matInput readonly value="{{data.type}}" />
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%;">
|
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%;">
|
||||||
<mat-label>Name</mat-label>
|
<mat-label>Name</mat-label>
|
||||||
<input matInput formControlName="name" required />
|
<input matInput formControlName="name" required />
|
||||||
<mat-error *ngIf="metadataForm.get('name')?.invalid">This field is <strong>required</strong></mat-error>
|
<mat-error *ngIf="metadataForm.get('name')?.invalid">This field is <strong>required</strong></mat-error>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%;">
|
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%;">
|
||||||
<mat-label>Description</mat-label>
|
<mat-label>Description</mat-label>
|
||||||
<textarea matInput formControlName="description" rows="8"></textarea>
|
<textarea matInput formControlName="description" rows="8"></textarea>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div mat-dialog-actions>
|
<div mat-dialog-actions>
|
||||||
<button mat-stroked-button color="primary" type="submit" [disabled]="!metadataForm.valid">Submit</button>
|
<button mat-stroked-button color="primary" type="submit" [disabled]="!metadataForm.valid">Submit</button>
|
||||||
<button mat-stroked-button color="primary" mat-dialog-close>Close</button>
|
<button mat-stroked-button color="primary" mat-dialog-close>Close</button>
|
||||||
<mat-error *ngIf="metadataForm.errors?.['serverError']">
|
<mat-error *ngIf="metadataForm.errors?.['serverError']">
|
||||||
{{ metadataForm.errors?.['serverError'] }}
|
{{ metadataForm.errors?.['serverError'] }}
|
||||||
</mat-error>
|
</mat-error>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -1,33 +1,33 @@
|
||||||
<form [formGroup]="newResourceForm" (ngSubmit)="onSubmit()">
|
<form [formGroup]="newResourceForm" (ngSubmit)="onSubmit()">
|
||||||
<h1 mat-dialog-title>New Resource</h1>
|
<h1 mat-dialog-title>New Resource</h1>
|
||||||
|
|
||||||
<div mat-dialog-content>
|
<div mat-dialog-content>
|
||||||
|
|
||||||
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%;">
|
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%;">
|
||||||
<mat-label>Name</mat-label>
|
<mat-label>Name</mat-label>
|
||||||
<input matInput formControlName="name" required />
|
<input matInput formControlName="name" required />
|
||||||
<mat-error *ngIf="newResourceForm.get('name')?.invalid">This field is <strong>required</strong></mat-error>
|
<mat-error *ngIf="newResourceForm.get('name')?.invalid">This field is <strong>required</strong></mat-error>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%;">
|
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%;">
|
||||||
<mat-label>Description</mat-label>
|
<mat-label>Description</mat-label>
|
||||||
<textarea matInput formControlName="description" rows="2"></textarea>
|
<textarea matInput formControlName="description" rows="2"></textarea>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%;">
|
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%;">
|
||||||
<mat-label>Content ({{data.contentType}})</mat-label>
|
<mat-label>Content ({{data.contentType}})</mat-label>
|
||||||
<textarea matInput formControlName="content" required rows="10" style="font-size: 0.8em;"></textarea>
|
<textarea matInput formControlName="content" required rows="10" style="font-size: 0.8em;"></textarea>
|
||||||
<mat-error *ngIf="newResourceForm.get('content')?.invalid">This field is <strong>required</strong></mat-error>
|
<mat-error *ngIf="newResourceForm.get('content')?.invalid">This field is <strong>required</strong></mat-error>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div mat-dialog-actions>
|
<div mat-dialog-actions>
|
||||||
<button mat-stroked-button color="primary" type="submit" [disabled]="!newResourceForm.valid">Submit</button>
|
<button mat-stroked-button color="primary" type="submit" [disabled]="!newResourceForm.valid">Submit</button>
|
||||||
<button mat-stroked-button color="primary" mat-dialog-close>Close</button>
|
<button mat-stroked-button color="primary" mat-dialog-close>Close</button>
|
||||||
<mat-error *ngIf="newResourceForm.errors?.['serverError']">
|
<mat-error *ngIf="newResourceForm.errors?.['serverError']">
|
||||||
{{ newResourceForm.errors?.['serverError'] }}
|
{{ newResourceForm.errors?.['serverError'] }}
|
||||||
</mat-error>
|
</mat-error>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -3,27 +3,26 @@
|
||||||
<button mat-stroked-button color="primary" (click)="openNewDialog()">create a new resource</button>
|
<button mat-stroked-button color="primary" (click)="openNewDialog()">create a new resource</button>
|
||||||
|
|
||||||
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%; margin-top: 10px;">
|
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%; margin-top: 10px;">
|
||||||
<mat-label><b>Filter</b> (Total: {{(resources | searchFilter: searchText).length}})</mat-label>
|
<mat-label><b>Filter</b> (Total: {{(resources | searchFilter: searchText).length}})</mat-label>
|
||||||
<input matInput [(ngModel)]="searchText" placeholder="Filter..." autofocus />
|
<input matInput [(ngModel)]="searchText" placeholder="Filter..." autofocus />
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
<mat-card *ngFor="let r of resources | searchFilter: searchText" style="margin-top: 10px;">
|
<mat-card *ngFor="let r of resources | searchFilter: searchText" style="margin-top: 10px;">
|
||||||
<mat-card-header>
|
<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-title title="{{r.id}}">{{r.name}} <span class="badge-label badge-info"
|
||||||
</mat-card-header>
|
style="font-size: 0.7em;">{{type.contentType}}</span></mat-card-title>
|
||||||
<mat-card-content>
|
</mat-card-header>
|
||||||
<p>{{r.description}}</p>
|
<mat-card-content>
|
||||||
<p class="muted small">
|
<p>{{r.description}}</p>
|
||||||
<b>Id:</b> {{r.id}}<br /> <b>Creation date:</b> {{r.creationDate}}<br /> <b>Modification date:</b> {{r.modificationDate}}
|
<p class="muted small">
|
||||||
</p>
|
<b>Id:</b> {{r.id}}<br /> <b>Creation date:</b> {{r.creationDate}}<br /> <b>Modification date:</b>
|
||||||
</mat-card-content>
|
{{r.modificationDate}}
|
||||||
<mat-card-actions>
|
</p>
|
||||||
<button mat-stroked-button color="primary" (click)="openMetadataDialog(r)">edit metadata</button>
|
</mat-card-content>
|
||||||
<button mat-stroked-button color="primary" (click)="openContentDialog(r)">edit content</button>
|
<mat-card-actions>
|
||||||
<a href="./api/resources/{{r.id}}/content" mat-stroked-button color="link" target="_blank">raw content</a>
|
<button mat-stroked-button color="primary" (click)="openMetadataDialog(r)">edit metadata</button>
|
||||||
<button mat-stroked-button color="warn" (click)="deleteResource(r)">delete</button>
|
<button mat-stroked-button color="primary" (click)="openContentDialog(r)">edit content</button>
|
||||||
</mat-card-actions>
|
<a href="./api/resources/{{r.id}}/content" mat-stroked-button color="link" target="_blank">raw content</a>
|
||||||
</mat-card>
|
<button mat-stroked-button color="warn" (click)="deleteResource(r)">delete</button>
|
||||||
|
</mat-card-actions>
|
||||||
|
</mat-card>
|
||||||
|
|
||||||
|
|
|
@ -6,159 +6,159 @@ import { ResourceType, SimpleResource } from '../common/is.model';
|
||||||
import { FormControl, FormGroup } from '@angular/forms';
|
import { FormControl, FormGroup } from '@angular/forms';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-resources',
|
selector: 'app-resources',
|
||||||
templateUrl: './resources.component.html',
|
templateUrl: './resources.component.html',
|
||||||
styleUrls: ['./resources.component.css']
|
styleUrls: ['./resources.component.css']
|
||||||
})
|
})
|
||||||
export class ResourcesComponent implements OnInit {
|
export class ResourcesComponent implements OnInit {
|
||||||
typeId:string = '';
|
typeId: string = '';
|
||||||
type:ResourceType = { id: '', name: '', contentType: '', count: 0, simple: true };
|
type: ResourceType = { id: '', name: '', contentType: '', count: 0, simple: true };
|
||||||
resources:SimpleResource[] = [];
|
resources: SimpleResource[] = [];
|
||||||
searchText:string = '';
|
searchText: string = '';
|
||||||
|
|
||||||
constructor(public service: ISService, public route: ActivatedRoute, public dialog: MatDialog) {
|
constructor(public service: ISService, public route: ActivatedRoute, public dialog: MatDialog) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.route.params.subscribe(params => {
|
this.route.params.subscribe(params => {
|
||||||
this.typeId = params['type'];
|
this.typeId = params['type'];
|
||||||
this.service.loadResourceType(this.typeId, (data: ResourceType) => this.type = data);
|
this.service.loadResourceType(this.typeId, (data: ResourceType) => this.type = data);
|
||||||
this.reload()
|
this.reload()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
reload() {
|
reload() {
|
||||||
if (this.typeId) {
|
if (this.typeId) {
|
||||||
this.service.loadSimpleResources(this.typeId, (data: SimpleResource[]) => this.resources = data);
|
this.service.loadSimpleResources(this.typeId, (data: SimpleResource[]) => this.resources = data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
openNewDialog(): void {
|
openNewDialog(): void {
|
||||||
const dialogRef = this.dialog.open(ResCreateNewDialog, {
|
const dialogRef = this.dialog.open(ResCreateNewDialog, {
|
||||||
data: this.type,
|
data: this.type,
|
||||||
width: '80%'
|
width: '80%'
|
||||||
});
|
});
|
||||||
|
|
||||||
dialogRef.afterClosed().subscribe(result => {
|
dialogRef.afterClosed().subscribe(result => {
|
||||||
if (result) this.reload();
|
if (result) this.reload();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
openMetadataDialog(r:SimpleResource): void {
|
openMetadataDialog(r: SimpleResource): void {
|
||||||
const dialogRef = this.dialog.open(ResMetadataDialog, {
|
const dialogRef = this.dialog.open(ResMetadataDialog, {
|
||||||
data: r,
|
data: r,
|
||||||
width: '80%'
|
width: '80%'
|
||||||
});
|
});
|
||||||
|
|
||||||
dialogRef.afterClosed().subscribe(result => {
|
dialogRef.afterClosed().subscribe(result => {
|
||||||
if (result) this.reload();
|
if (result) this.reload();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
openContentDialog(r:SimpleResource): void {
|
openContentDialog(r: SimpleResource): void {
|
||||||
this.service.loadSimpleResourceContent(r.id, (data: string) => {
|
this.service.loadSimpleResourceContent(r.id, (data: string) => {
|
||||||
const dialogRef = this.dialog.open(ResContentDialog, {
|
const dialogRef = this.dialog.open(ResContentDialog, {
|
||||||
data: {
|
data: {
|
||||||
id: r.id,
|
id: r.id,
|
||||||
contentType: this.type.contentType,
|
contentType: this.type.contentType,
|
||||||
content: data
|
content: data
|
||||||
},
|
},
|
||||||
width: '80%'
|
width: '80%'
|
||||||
});
|
});
|
||||||
|
|
||||||
dialogRef.afterClosed().subscribe(result => {
|
|
||||||
if (result) this.reload();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
deleteResource(r:SimpleResource) {
|
dialogRef.afterClosed().subscribe(result => {
|
||||||
if (confirm('Are you sure?')) {
|
if (result) this.reload();
|
||||||
this.service.deleteSimpleResource(r.id, (data: void) => this.reload());
|
});
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
deleteResource(r: SimpleResource) {
|
||||||
|
if (confirm('Are you sure?')) {
|
||||||
|
this.service.deleteSimpleResource(r.id, (data: void) => this.reload());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'res-content-dialog',
|
selector: 'res-content-dialog',
|
||||||
templateUrl: 'content-dialog.html',
|
templateUrl: 'content-dialog.html',
|
||||||
styleUrls: ['resources.component.css']
|
styleUrls: ['resources.component.css']
|
||||||
})
|
})
|
||||||
export class ResContentDialog {
|
export class ResContentDialog {
|
||||||
contentFormControl = new FormControl('');
|
contentFormControl = new FormControl('');
|
||||||
|
|
||||||
contentForm = new FormGroup({
|
|
||||||
content : this.contentFormControl
|
|
||||||
});
|
|
||||||
|
|
||||||
constructor(public dialogRef: MatDialogRef<ResContentDialog>, @Inject(MAT_DIALOG_DATA) public data: any, public service: ISService) {
|
contentForm = new FormGroup({
|
||||||
this.contentFormControl.setValue(data.content);
|
content: this.contentFormControl
|
||||||
}
|
});
|
||||||
|
|
||||||
onSubmit():void {
|
constructor(public dialogRef: MatDialogRef<ResContentDialog>, @Inject(MAT_DIALOG_DATA) public data: any, public service: ISService) {
|
||||||
let content = this.contentFormControl.value;
|
this.contentFormControl.setValue(data.content);
|
||||||
if (content) {
|
}
|
||||||
this.service.saveSimpleResourceContent(this.data.id, content, (data: void) => this.dialogRef.close(1), this.contentForm)
|
|
||||||
}
|
onSubmit(): void {
|
||||||
}
|
let content = this.contentFormControl.value;
|
||||||
|
if (content) {
|
||||||
onNoClick(): void {
|
this.service.saveSimpleResourceContent(this.data.id, content, (data: void) => this.dialogRef.close(1), this.contentForm)
|
||||||
this.dialogRef.close();
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onNoClick(): void {
|
||||||
|
this.dialogRef.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'res-metadata-dialog',
|
selector: 'res-metadata-dialog',
|
||||||
templateUrl: 'metadata-dialog.html',
|
templateUrl: 'metadata-dialog.html',
|
||||||
styleUrls: ['resources.component.css']
|
styleUrls: ['resources.component.css']
|
||||||
})
|
})
|
||||||
export class ResMetadataDialog {
|
export class ResMetadataDialog {
|
||||||
metadataForm = new FormGroup({
|
metadataForm = new FormGroup({
|
||||||
name: new FormControl(''),
|
name: new FormControl(''),
|
||||||
description : new FormControl('')
|
description: new FormControl('')
|
||||||
});
|
});
|
||||||
|
|
||||||
constructor(public dialogRef: MatDialogRef<ResMetadataDialog>, @Inject(MAT_DIALOG_DATA) public data: any, public service: ISService) {
|
constructor(public dialogRef: MatDialogRef<ResMetadataDialog>, @Inject(MAT_DIALOG_DATA) public data: any, public service: ISService) {
|
||||||
this.metadataForm.get('name')?.setValue(data.name);
|
this.metadataForm.get('name')?.setValue(data.name);
|
||||||
if (data.description) {
|
if (data.description) {
|
||||||
this.metadataForm.get('description')?.setValue(data.description);
|
this.metadataForm.get('description')?.setValue(data.description);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onSubmit():void {
|
onSubmit(): void {
|
||||||
const res = Object.assign({}, this.data, this.metadataForm.value);
|
const res = Object.assign({}, this.data, this.metadataForm.value);
|
||||||
this.service.saveSimpleResourceMedatata(res, (data: void) => this.dialogRef.close(1), this.metadataForm);
|
this.service.saveSimpleResourceMedatata(res, (data: void) => this.dialogRef.close(1), this.metadataForm);
|
||||||
}
|
}
|
||||||
|
|
||||||
onNoClick(): void {
|
onNoClick(): void {
|
||||||
this.dialogRef.close();
|
this.dialogRef.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'res-new-dialog',
|
selector: 'res-new-dialog',
|
||||||
templateUrl: 'new-dialog.html',
|
templateUrl: 'new-dialog.html',
|
||||||
styleUrls: ['resources.component.css']
|
styleUrls: ['resources.component.css']
|
||||||
})
|
})
|
||||||
export class ResCreateNewDialog {
|
export class ResCreateNewDialog {
|
||||||
newResourceForm = new FormGroup({
|
newResourceForm = new FormGroup({
|
||||||
name: new FormControl(''),
|
name: new FormControl(''),
|
||||||
description : new FormControl(''),
|
description: new FormControl(''),
|
||||||
content : new FormControl('')
|
content: new FormControl('')
|
||||||
});
|
});
|
||||||
|
|
||||||
constructor(public dialogRef: MatDialogRef<ResCreateNewDialog>, @Inject(MAT_DIALOG_DATA) public data: any, public service: ISService) {}
|
constructor(public dialogRef: MatDialogRef<ResCreateNewDialog>, @Inject(MAT_DIALOG_DATA) public data: any, public service: ISService) { }
|
||||||
|
|
||||||
onSubmit():void {
|
onSubmit(): void {
|
||||||
let name:string = this.newResourceForm.get('name')?.value!;
|
let name: string = this.newResourceForm.get('name')?.value!;
|
||||||
let type:string = this.data.id!;
|
let type: string = this.data.id!;
|
||||||
let description:string = this.newResourceForm.get('description')?.value!;
|
let description: string = this.newResourceForm.get('description')?.value!;
|
||||||
let content:string = this.newResourceForm.get('content')?.value!;
|
let content: string = this.newResourceForm.get('content')?.value!;
|
||||||
|
|
||||||
this.service.addSimpleResource(name, type, description, content, (data: void) => this.dialogRef.close(1), this.newResourceForm);
|
this.service.addSimpleResource(name, type, description, content, (data: void) => this.dialogRef.close(1), this.newResourceForm);
|
||||||
}
|
}
|
||||||
onNoClick(): void {
|
onNoClick(): void {
|
||||||
this.dialogRef.close();
|
this.dialogRef.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,32 +1,32 @@
|
||||||
<form [formGroup]="vocForm" (ngSubmit)="onSubmit()">
|
<form [formGroup]="vocForm" (ngSubmit)="onSubmit()">
|
||||||
<h1 mat-dialog-title *ngIf="data.id">Edit vocabulary</h1>
|
<h1 mat-dialog-title *ngIf="data.id">Edit vocabulary</h1>
|
||||||
<h1 mat-dialog-title *ngIf="!data.id">New vocabulary</h1>
|
<h1 mat-dialog-title *ngIf="!data.id">New vocabulary</h1>
|
||||||
|
|
||||||
<div mat-dialog-content>
|
<div mat-dialog-content>
|
||||||
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%;">
|
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%;">
|
||||||
<mat-label>ID</mat-label>
|
<mat-label>ID</mat-label>
|
||||||
<input matInput required formControlName="id" [readonly]="data.id.length > 0" />
|
<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-error *ngIf="vocForm.get('id')?.invalid">This field is <strong>required</strong></mat-error>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%;">
|
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%;">
|
||||||
<mat-label>Name</mat-label>
|
<mat-label>Name</mat-label>
|
||||||
<input matInput formControlName="name" required />
|
<input matInput formControlName="name" required />
|
||||||
<mat-error *ngIf="vocForm.get('name')?.invalid">This field is <strong>required</strong></mat-error>
|
<mat-error *ngIf="vocForm.get('name')?.invalid">This field is <strong>required</strong></mat-error>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%;">
|
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%;">
|
||||||
<mat-label>Description</mat-label>
|
<mat-label>Description</mat-label>
|
||||||
<textarea matInput formControlName="description" rows="4"></textarea>
|
<textarea matInput formControlName="description" rows="4"></textarea>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div mat-dialog-actions>
|
<div mat-dialog-actions>
|
||||||
<button mat-stroked-button color="primary" type="submit" [disabled]="!vocForm.valid">Submit</button>
|
<button mat-stroked-button color="primary" type="submit" [disabled]="!vocForm.valid">Submit</button>
|
||||||
<button mat-stroked-button color="primary" mat-dialog-close>Close</button>
|
<button mat-stroked-button color="primary" mat-dialog-close>Close</button>
|
||||||
<mat-error *ngIf="vocForm.errors?.['serverError']">
|
<mat-error *ngIf="vocForm.errors?.['serverError']">
|
||||||
{{ vocForm.errors?.['serverError'] }}
|
{{ vocForm.errors?.['serverError'] }}
|
||||||
</mat-error>
|
</mat-error>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -1,82 +1,76 @@
|
||||||
<form [formGroup]="termForm" (ngSubmit)="onSubmit()">
|
<form [formGroup]="termForm" (ngSubmit)="onSubmit()">
|
||||||
<h1 mat-dialog-title *ngIf="data.code">Edit term</h1>
|
<h1 mat-dialog-title *ngIf="data.code">Edit term</h1>
|
||||||
<h1 mat-dialog-title *ngIf="!data.code">New term</h1>
|
<h1 mat-dialog-title *ngIf="!data.code">New term</h1>
|
||||||
|
|
||||||
<div mat-dialog-content>
|
<div mat-dialog-content>
|
||||||
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%;">
|
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%;">
|
||||||
<mat-label>Code</mat-label>
|
<mat-label>Code</mat-label>
|
||||||
<input matInput formControlName="code" required />
|
<input matInput formControlName="code" required />
|
||||||
<mat-error *ngIf="termForm.get('id')?.invalid">This field is <strong>required</strong></mat-error>
|
<mat-error *ngIf="termForm.get('id')?.invalid">This field is <strong>required</strong></mat-error>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%;">
|
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%;">
|
||||||
<mat-label>Name</mat-label>
|
<mat-label>Name</mat-label>
|
||||||
<input matInput formControlName="name" required />
|
<input matInput formControlName="name" required />
|
||||||
<mat-error *ngIf="termForm.get('name')?.invalid">This field is <strong>required</strong></mat-error>
|
<mat-error *ngIf="termForm.get('name')?.invalid">This field is <strong>required</strong></mat-error>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%;">
|
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%;">
|
||||||
<mat-label>Encoding</mat-label>
|
<mat-label>Encoding</mat-label>
|
||||||
<input matInput formControlName="encoding" />
|
<input matInput formControlName="encoding" />
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
<table mat-table [dataSource]="synonymsDatasource" class="mat-elevation-z8">
|
<table mat-table [dataSource]="synonymsDatasource" class="mat-elevation-z8">
|
||||||
|
|
||||||
<ng-container matColumnDef="term">
|
<ng-container matColumnDef="term">
|
||||||
<th mat-header-cell *matHeaderCellDef>Term</th>
|
<th mat-header-cell *matHeaderCellDef>Term</th>
|
||||||
<td mat-cell *matCellDef="let element">{{element.term}}</td>
|
<td mat-cell *matCellDef="let element">{{element.term}}</td>
|
||||||
<td mat-footer-cell *matFooterCellDef>
|
<td mat-footer-cell *matFooterCellDef>
|
||||||
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%;">
|
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%;">
|
||||||
<mat-label>New term</mat-label>
|
<mat-label>New term</mat-label>
|
||||||
<input matInput formControlName="tmpSynonymTerm" />
|
<input matInput formControlName="tmpSynonymTerm" />
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</td>
|
</td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<ng-container matColumnDef="encoding">
|
|
||||||
<th mat-header-cell *matHeaderCellDef style="width: 20%;">Encoding</th>
|
|
||||||
<td mat-cell *matCellDef="let element">{{element.encoding}}</td>
|
|
||||||
<td mat-footer-cell *matFooterCellDef>
|
|
||||||
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%;">
|
|
||||||
<mat-label>New encoding</mat-label>
|
|
||||||
<input matInput formControlName="tmpSynonymEncoding" />
|
|
||||||
</mat-form-field>
|
|
||||||
</td>
|
|
||||||
</ng-container>
|
|
||||||
|
|
||||||
<ng-container matColumnDef="buttons">
|
<ng-container matColumnDef="encoding">
|
||||||
<th mat-header-cell *matHeaderCellDef style="text-align: right; width: 8em;"></th>
|
<th mat-header-cell *matHeaderCellDef style="width: 20%;">Encoding</th>
|
||||||
<td mat-cell *matCellDef="let index = index" class="table-buttons">
|
<td mat-cell *matCellDef="let element">{{element.encoding}}</td>
|
||||||
<button mat-stroked-button
|
<td mat-footer-cell *matFooterCellDef>
|
||||||
color="warn"
|
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%;">
|
||||||
type="button"
|
<mat-label>New encoding</mat-label>
|
||||||
(click)="removeSynonym(index)">
|
<input matInput formControlName="tmpSynonymEncoding" />
|
||||||
delete
|
</mat-form-field>
|
||||||
</button>
|
</td>
|
||||||
</td>
|
</ng-container>
|
||||||
<td mat-footer-cell *matFooterCellDef class="table-buttons">
|
|
||||||
<button mat-stroked-button
|
|
||||||
color="primary"
|
|
||||||
type="button"
|
|
||||||
(click)="addSynonym()"
|
|
||||||
[disabled]="!isNewSynonymValid()">
|
|
||||||
add
|
|
||||||
</button>
|
|
||||||
</td>
|
|
||||||
</ng-container>
|
|
||||||
|
|
||||||
<tr mat-header-row *matHeaderRowDef="synonymColums"></tr>
|
|
||||||
<tr mat-row *matRowDef="let row; columns: synonymColums;"></tr>
|
|
||||||
|
|
||||||
<!-- Row shown when there is no matching data. -->
|
|
||||||
<tr class="mat-row" *matNoDataRow>
|
|
||||||
<td class="mat-cell" colspan="3" style="padding: 0 16px;">No synonyms</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr mat-footer-row *matFooterRowDef="synonymColums"></tr>
|
<ng-container matColumnDef="buttons">
|
||||||
</table>
|
<th mat-header-cell *matHeaderCellDef style="text-align: right; width: 8em;"></th>
|
||||||
|
<td mat-cell *matCellDef="let index = index" class="table-buttons">
|
||||||
|
<button mat-stroked-button color="warn" type="button" (click)="removeSynonym(index)">
|
||||||
|
delete
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
<td mat-footer-cell *matFooterCellDef class="table-buttons">
|
||||||
|
<button mat-stroked-button color="primary" type="button" (click)="addSynonym()"
|
||||||
|
[disabled]="!isNewSynonymValid()">
|
||||||
|
add
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
<!--
|
<tr mat-header-row *matHeaderRowDef="synonymColums"></tr>
|
||||||
|
<tr mat-row *matRowDef="let row; columns: synonymColums;"></tr>
|
||||||
|
|
||||||
|
<!-- Row shown when there is no matching data. -->
|
||||||
|
<tr class="mat-row" *matNoDataRow>
|
||||||
|
<td class="mat-cell" colspan="3" style="padding: 0 16px;">No synonyms</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr mat-footer-row *matFooterRowDef="synonymColums"></tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<!--
|
||||||
<table style="border: 1px solid gray; font-size: 0.9em;">
|
<table style="border: 1px solid gray; font-size: 0.9em;">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -124,14 +118,14 @@
|
||||||
</tfoot>
|
</tfoot>
|
||||||
</table>
|
</table>
|
||||||
-->
|
-->
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div mat-dialog-actions>
|
<div mat-dialog-actions>
|
||||||
<button mat-stroked-button color="primary" type="submit" [disabled]="!termForm.valid">Submit</button>
|
<button mat-stroked-button color="primary" type="submit" [disabled]="!termForm.valid">Submit</button>
|
||||||
<button mat-stroked-button color="primary" mat-dialog-close>Close</button>
|
<button mat-stroked-button color="primary" mat-dialog-close>Close</button>
|
||||||
<mat-error *ngIf="termForm.errors?.['serverError']">
|
<mat-error *ngIf="termForm.errors?.['serverError']">
|
||||||
{{ termForm.errors?.['serverError'] }}
|
{{ termForm.errors?.['serverError'] }}
|
||||||
</mat-error>
|
</mat-error>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -3,42 +3,45 @@
|
||||||
<button mat-stroked-button color="primary" (click)="newVocabularyDialog()">create a new vocabulary</button>
|
<button mat-stroked-button color="primary" (click)="newVocabularyDialog()">create a new vocabulary</button>
|
||||||
|
|
||||||
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%; margin-top: 10px;">
|
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%; margin-top: 10px;">
|
||||||
<mat-label>Filter</mat-label>
|
<mat-label>Filter</mat-label>
|
||||||
<input matInput (keyup)="applyFilter($event)" placeholder="Filter..." #input />
|
<input matInput (keyup)="applyFilter($event)" placeholder="Filter..." #input />
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
<table mat-table [dataSource]="vocsDatasource" matSort class="mat-elevation-z8">
|
<table mat-table [dataSource]="vocsDatasource" matSort class="mat-elevation-z8">
|
||||||
|
|
||||||
<ng-container matColumnDef="id">
|
<ng-container matColumnDef="id">
|
||||||
<th mat-header-cell *matHeaderCellDef style="width: 20%;" mat-sort-header sortActionDescription="Sort by ID"> Id </th>
|
<th mat-header-cell *matHeaderCellDef style="width: 20%;" mat-sort-header sortActionDescription="Sort by ID"> Id
|
||||||
<td mat-cell *matCellDef="let element">
|
</th>
|
||||||
<a [routerLink]="['/voc_editor']" [queryParams]="{id: element.id}">{{element.id}}</a>
|
<td mat-cell *matCellDef="let element">
|
||||||
</td>
|
<a [routerLink]="['/voc_editor']" [queryParams]="{id: element.id}">{{element.id}}</a>
|
||||||
</ng-container>
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
<ng-container matColumnDef="name">
|
<ng-container matColumnDef="name">
|
||||||
<th mat-header-cell *matHeaderCellDef style="width: 20%;" mat-sort-header sortActionDescription="Sort by Name"> Name </th>
|
<th mat-header-cell *matHeaderCellDef style="width: 20%;" mat-sort-header sortActionDescription="Sort by Name"> Name
|
||||||
<td mat-cell *matCellDef="let element"> {{element.name}} </td>
|
</th>
|
||||||
</ng-container>
|
<td mat-cell *matCellDef="let element"> {{element.name}} </td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
<ng-container matColumnDef="description">
|
<ng-container matColumnDef="description">
|
||||||
<th mat-header-cell *matHeaderCellDef style="width: 40%;" mat-sort-header sortActionDescription="Sort by Description"> Description </th>
|
<th mat-header-cell *matHeaderCellDef style="width: 40%;" mat-sort-header
|
||||||
<td mat-cell *matCellDef="let element"> {{element.description}} </td>
|
sortActionDescription="Sort by Description"> Description </th>
|
||||||
</ng-container>
|
<td mat-cell *matCellDef="let element"> {{element.description}} </td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
<ng-container matColumnDef="buttons">
|
<ng-container matColumnDef="buttons">
|
||||||
<th mat-header-cell *matHeaderCellDef style="text-align: right;"></th>
|
<th mat-header-cell *matHeaderCellDef style="text-align: right;"></th>
|
||||||
<td mat-cell *matCellDef="let element" class="table-buttons">
|
<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="primary" (click)="editVocabularyDialog(element)">edit</button>
|
||||||
<button mat-stroked-button color="warn" (click)="deleteVocabulary(element)">delete</button>
|
<button mat-stroked-button color="warn" (click)="deleteVocabulary(element)">delete</button>
|
||||||
</td>
|
</td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<tr mat-header-row *matHeaderRowDef="colums"></tr>
|
<tr mat-header-row *matHeaderRowDef="colums"></tr>
|
||||||
<tr mat-row *matRowDef="let row; columns: colums;"></tr>
|
<tr mat-row *matRowDef="let row; columns: colums;"></tr>
|
||||||
|
|
||||||
<!-- Row shown when there is no matching data. -->
|
<!-- Row shown when there is no matching data. -->
|
||||||
<tr class="mat-row" *matNoDataRow>
|
<tr class="mat-row" *matNoDataRow>
|
||||||
<td class="mat-cell" colspan="4" style="padding: 0 16px;">No data matching the filter "{{input.value}}"</td>
|
<td class="mat-cell" colspan="4" style="padding: 0 16px;">No data matching the filter "{{input.value}}"</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
|
@ -8,238 +8,238 @@ import { MatDialog, MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dial
|
||||||
import { FormControl, FormGroup } from '@angular/forms';
|
import { FormControl, FormGroup } from '@angular/forms';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-vocabularies',
|
selector: 'app-vocabularies',
|
||||||
templateUrl: './vocabularies.component.html',
|
templateUrl: './vocabularies.component.html',
|
||||||
styleUrls: ['./vocabularies.component.css']
|
styleUrls: ['./vocabularies.component.css']
|
||||||
})
|
})
|
||||||
export class VocabulariesComponent implements OnInit, AfterViewInit {
|
export class VocabulariesComponent implements OnInit, AfterViewInit {
|
||||||
vocsDatasource: MatTableDataSource<Vocabulary> = new MatTableDataSource<Vocabulary>([]);
|
vocsDatasource: MatTableDataSource<Vocabulary> = new MatTableDataSource<Vocabulary>([]);
|
||||||
|
|
||||||
colums: string[] = ['id', 'name', 'description', 'buttons'];
|
colums: string[] = ['id', 'name', 'description', 'buttons'];
|
||||||
|
|
||||||
@ViewChild(MatSort) sort: MatSort | undefined
|
@ViewChild(MatSort) sort: MatSort | undefined
|
||||||
|
|
||||||
constructor(public service: ISService, public route: ActivatedRoute, public dialog: MatDialog) {
|
constructor(public service: ISService, public route: ActivatedRoute, public dialog: MatDialog) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.reload();
|
this.reload();
|
||||||
}
|
}
|
||||||
|
|
||||||
ngAfterViewInit() {
|
ngAfterViewInit() {
|
||||||
if (this.sort) this.vocsDatasource.sort = this.sort;
|
if (this.sort) this.vocsDatasource.sort = this.sort;
|
||||||
}
|
}
|
||||||
|
|
||||||
reload() {
|
reload() {
|
||||||
this.service.loadVocabularies((data: Vocabulary[]) => this.vocsDatasource.data = data);
|
this.service.loadVocabularies((data: Vocabulary[]) => this.vocsDatasource.data = data);
|
||||||
}
|
}
|
||||||
|
|
||||||
applyFilter(event: Event) {
|
applyFilter(event: Event) {
|
||||||
const filterValue = (event.target as HTMLInputElement).value.trim().toLowerCase();
|
const filterValue = (event.target as HTMLInputElement).value.trim().toLowerCase();
|
||||||
this.vocsDatasource.filter = filterValue;
|
this.vocsDatasource.filter = filterValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
newVocabularyDialog(): void {
|
newVocabularyDialog(): void {
|
||||||
const dialogRef = this.dialog.open(VocDialog, {
|
const dialogRef = this.dialog.open(VocDialog, {
|
||||||
data: { id: '', name: '', description: '' },
|
data: { id: '', name: '', description: '' },
|
||||||
width: '80%'
|
width: '80%'
|
||||||
});
|
});
|
||||||
|
|
||||||
dialogRef.afterClosed().subscribe(result => {
|
dialogRef.afterClosed().subscribe(result => {
|
||||||
if (result) this.reload();
|
if (result) this.reload();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
editVocabularyDialog(vocabulary: Vocabulary): void {
|
editVocabularyDialog(vocabulary: Vocabulary): void {
|
||||||
const dialogRef = this.dialog.open(VocDialog, {
|
const dialogRef = this.dialog.open(VocDialog, {
|
||||||
data: vocabulary,
|
data: vocabulary,
|
||||||
width: '80%'
|
width: '80%'
|
||||||
});
|
});
|
||||||
|
|
||||||
dialogRef.afterClosed().subscribe(result => {
|
dialogRef.afterClosed().subscribe(result => {
|
||||||
if (result) this.reload();
|
if (result) this.reload();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteVocabulary(vocabulary: Vocabulary): void {
|
deleteVocabulary(vocabulary: Vocabulary): void {
|
||||||
if (confirm("Are you sure?")) {
|
if (confirm("Are you sure?")) {
|
||||||
this.service.deleteVocabulary(vocabulary.id, (data: void) => this.reload());
|
this.service.deleteVocabulary(vocabulary.id, (data: void) => this.reload());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-vocabulary-editor',
|
selector: 'app-vocabulary-editor',
|
||||||
templateUrl: './vocabulary-editor.component.html',
|
templateUrl: './vocabulary-editor.component.html',
|
||||||
styleUrls: ['./vocabularies.component.css']
|
styleUrls: ['./vocabularies.component.css']
|
||||||
})
|
})
|
||||||
export class VocabularyEditorComponent implements OnInit, AfterViewInit {
|
export class VocabularyEditorComponent implements OnInit, AfterViewInit {
|
||||||
|
|
||||||
voc?: Vocabulary
|
voc?: Vocabulary
|
||||||
|
|
||||||
termsDatasource: MatTableDataSource<VocabularyTerm> = new MatTableDataSource<VocabularyTerm>([]);
|
termsDatasource: MatTableDataSource<VocabularyTerm> = new MatTableDataSource<VocabularyTerm>([]);
|
||||||
colums: string[] = ['code', 'name', 'encoding', 'synonyms', 'buttons'];
|
colums: string[] = ['code', 'name', 'encoding', 'synonyms', 'buttons'];
|
||||||
|
|
||||||
@ViewChild(MatSort) sort: MatSort | undefined
|
@ViewChild(MatSort) sort: MatSort | undefined
|
||||||
|
|
||||||
constructor(public service: ISService, public route: ActivatedRoute, public dialog: MatDialog) {
|
constructor(public service: ISService, public route: ActivatedRoute, public dialog: MatDialog) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.reload();
|
this.reload();
|
||||||
}
|
}
|
||||||
|
|
||||||
ngAfterViewInit() {
|
ngAfterViewInit() {
|
||||||
if (this.sort) this.termsDatasource.sort = this.sort;
|
if (this.sort) this.termsDatasource.sort = this.sort;
|
||||||
}
|
}
|
||||||
|
|
||||||
reload() {
|
reload() {
|
||||||
this.route.queryParams.subscribe((params) => {
|
this.route.queryParams.subscribe((params) => {
|
||||||
this.service.loadVocabulary(params['id'], (data: Vocabulary) => this.voc = data);
|
this.service.loadVocabulary(params['id'], (data: Vocabulary) => this.voc = data);
|
||||||
this.service.loadVocabularyTerms(params['id'], (data: VocabularyTerm[]) => this.termsDatasource.data = data);
|
this.service.loadVocabularyTerms(params['id'], (data: VocabularyTerm[]) => this.termsDatasource.data = data);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
applyFilter(event: Event) {
|
applyFilter(event: Event) {
|
||||||
const filterValue = (event.target as HTMLInputElement).value.trim().toLowerCase();
|
const filterValue = (event.target as HTMLInputElement).value.trim().toLowerCase();
|
||||||
this.termsDatasource.filter = filterValue;
|
this.termsDatasource.filter = filterValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
newVocabularyTermDialog(): void {
|
newVocabularyTermDialog(): void {
|
||||||
if (this.voc?.id) {
|
if (this.voc?.id) {
|
||||||
const dialogRef = this.dialog.open(VocTermDialog, {
|
const dialogRef = this.dialog.open(VocTermDialog, {
|
||||||
data: { vocabulary: this.voc.id, code: '', name: '', encoding: 'OPENAIRE', synonyms: []},
|
data: { vocabulary: this.voc.id, code: '', name: '', encoding: 'OPENAIRE', synonyms: [] },
|
||||||
width: '80%'
|
width: '80%'
|
||||||
});
|
});
|
||||||
|
|
||||||
dialogRef.afterClosed().subscribe(result => {
|
dialogRef.afterClosed().subscribe(result => {
|
||||||
if (result) this.reload();
|
if (result) this.reload();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
editVocabularyTermDialog(term: VocabularyTerm): void {
|
editVocabularyTermDialog(term: VocabularyTerm): void {
|
||||||
const dialogRef = this.dialog.open(VocTermDialog, {
|
const dialogRef = this.dialog.open(VocTermDialog, {
|
||||||
data: term,
|
data: term,
|
||||||
width: '80%'
|
width: '80%'
|
||||||
});
|
});
|
||||||
|
|
||||||
dialogRef.afterClosed().subscribe(result => {
|
dialogRef.afterClosed().subscribe(result => {
|
||||||
if (result) this.reload();
|
if (result) this.reload();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteVocabularyTerm(term: VocabularyTerm): void {
|
deleteVocabularyTerm(term: VocabularyTerm): void {
|
||||||
if (confirm("Are you sure?") && this.voc?.id && term.code) {
|
if (confirm("Are you sure?") && this.voc?.id && term.code) {
|
||||||
this.service.deleteVocabularyTerm(this.voc.id, term.code, (data: void) => this.reload());
|
this.service.deleteVocabularyTerm(this.voc.id, term.code, (data: void) => this.reload());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'voc-dialog',
|
selector: 'voc-dialog',
|
||||||
templateUrl: 'voc-dialog.html',
|
templateUrl: 'voc-dialog.html',
|
||||||
styleUrls: ['vocabularies.component.css']
|
styleUrls: ['vocabularies.component.css']
|
||||||
})
|
})
|
||||||
export class VocDialog {
|
export class VocDialog {
|
||||||
vocForm = new FormGroup({
|
vocForm = new FormGroup({
|
||||||
id: new FormControl(''),
|
id: new FormControl(''),
|
||||||
name: new FormControl(''),
|
name: new FormControl(''),
|
||||||
description: new FormControl('')
|
description: new FormControl('')
|
||||||
});
|
});
|
||||||
|
|
||||||
constructor(public dialogRef: MatDialogRef<VocDialog>, @Inject(MAT_DIALOG_DATA) public data: any, public service: ISService) {
|
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('id')?.setValue(data.id);
|
||||||
this.vocForm.get('name')?.setValue(data.name);
|
this.vocForm.get('name')?.setValue(data.name);
|
||||||
this.vocForm.get('description')?.setValue(data.description);
|
this.vocForm.get('description')?.setValue(data.description);
|
||||||
}
|
}
|
||||||
|
|
||||||
onSubmit(): void {
|
onSubmit(): void {
|
||||||
const voc = Object.assign({}, this.data, this.vocForm.value);
|
const voc = Object.assign({}, this.data, this.vocForm.value);
|
||||||
this.service.saveVocabulary(voc, (data: void) => this.dialogRef.close(1), this.vocForm);
|
this.service.saveVocabulary(voc, (data: void) => this.dialogRef.close(1), this.vocForm);
|
||||||
}
|
}
|
||||||
|
|
||||||
onNoClick(): void {
|
onNoClick(): void {
|
||||||
this.dialogRef.close();
|
this.dialogRef.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'voc-term-dialog',
|
selector: 'voc-term-dialog',
|
||||||
templateUrl: 'voc-term-dialog.html',
|
templateUrl: 'voc-term-dialog.html',
|
||||||
styleUrls: ['vocabularies.component.css']
|
styleUrls: ['vocabularies.component.css']
|
||||||
})
|
})
|
||||||
export class VocTermDialog {
|
export class VocTermDialog {
|
||||||
|
|
||||||
termForm = new FormGroup({
|
termForm = new FormGroup({
|
||||||
code: new FormControl(''),
|
code: new FormControl(''),
|
||||||
name: new FormControl(''),
|
name: new FormControl(''),
|
||||||
encoding: new FormControl('OPENAIRE'),
|
encoding: new FormControl('OPENAIRE'),
|
||||||
tmpSynonymTerm: new FormControl(''),
|
tmpSynonymTerm: new FormControl(''),
|
||||||
tmpSynonymEncoding: new FormControl('OPENAIRE')
|
tmpSynonymEncoding: new FormControl('OPENAIRE')
|
||||||
});
|
});
|
||||||
|
|
||||||
synonymsDatasource: MatTableDataSource<VocabularyTermSynonym> = new MatTableDataSource<VocabularyTermSynonym>([]);
|
synonymsDatasource: MatTableDataSource<VocabularyTermSynonym> = new MatTableDataSource<VocabularyTermSynonym>([]);
|
||||||
synonymColums: string[] = ['term', 'encoding', 'buttons'];
|
synonymColums: string[] = ['term', 'encoding', 'buttons'];
|
||||||
@ViewChild(MatTable) synonymsTable: MatTable<VocabularyTermSynonym> | undefined;
|
@ViewChild(MatTable) synonymsTable: MatTable<VocabularyTermSynonym> | undefined;
|
||||||
|
|
||||||
constructor(public dialogRef: MatDialogRef<VocDialog>, @Inject(MAT_DIALOG_DATA) public data: any, public service: ISService) {
|
constructor(public dialogRef: MatDialogRef<VocDialog>, @Inject(MAT_DIALOG_DATA) public data: any, public service: ISService) {
|
||||||
this.termForm.get('code')?.setValue(data.code);
|
this.termForm.get('code')?.setValue(data.code);
|
||||||
this.termForm.get('name')?.setValue(data.name);
|
this.termForm.get('name')?.setValue(data.name);
|
||||||
this.termForm.get('encoding')?.setValue(data.encoding);
|
this.termForm.get('encoding')?.setValue(data.encoding);
|
||||||
this.synonymsDatasource.data = data.synonyms;
|
this.synonymsDatasource.data = data.synonyms;
|
||||||
}
|
}
|
||||||
|
|
||||||
onSubmit(): void {
|
onSubmit(): void {
|
||||||
console.log('SUBMIT');
|
console.log('SUBMIT');
|
||||||
|
|
||||||
let oldCode = this.data.code;
|
let oldCode = this.data.code;
|
||||||
let voc = this.data.vocabulary;
|
let voc = this.data.vocabulary;
|
||||||
|
|
||||||
let term:VocabularyTerm = {
|
let term: VocabularyTerm = {
|
||||||
code : this.termForm.get('code')?.value!,
|
code: this.termForm.get('code')?.value!,
|
||||||
name : this.termForm.get('name')?.value!,
|
name: this.termForm.get('name')?.value!,
|
||||||
encoding : this.termForm.get('encoding')?.value!,
|
encoding: this.termForm.get('encoding')?.value!,
|
||||||
synonyms: this.synonymsDatasource.data,
|
synonyms: this.synonymsDatasource.data,
|
||||||
vocabulary: voc
|
vocabulary: voc
|
||||||
}
|
}
|
||||||
|
|
||||||
this.service.saveVocabularyTerm(voc, term, (data: void) => {
|
this.service.saveVocabularyTerm(voc, term, (data: void) => {
|
||||||
if (oldCode && oldCode != term.code) {
|
if (oldCode && oldCode != term.code) {
|
||||||
this.service.deleteVocabularyTerm(voc, oldCode, (data: void) => this.dialogRef.close(1))
|
this.service.deleteVocabularyTerm(voc, oldCode, (data: void) => this.dialogRef.close(1))
|
||||||
} else { this.dialogRef.close(1) }
|
} else { this.dialogRef.close(1) }
|
||||||
}, this.termForm);
|
}, this.termForm);
|
||||||
}
|
}
|
||||||
|
|
||||||
removeSynonym(pos:number) {
|
removeSynonym(pos: number) {
|
||||||
this.synonymsDatasource.data.splice(pos, 1);
|
this.synonymsDatasource.data.splice(pos, 1);
|
||||||
this.synonymsTable?.renderRows();
|
this.synonymsTable?.renderRows();
|
||||||
}
|
}
|
||||||
|
|
||||||
isNewSynonymValid(): boolean {
|
isNewSynonymValid(): boolean {
|
||||||
if (!this.termForm.get('tmpSynonymTerm')) return false;
|
if (!this.termForm.get('tmpSynonymTerm')) return false;
|
||||||
if (!this.termForm.get('tmpSynonymEncoding')) return false;
|
if (!this.termForm.get('tmpSynonymEncoding')) return false;
|
||||||
if (this.termForm.get('tmpSynonymTerm')?.value?.trim().length == 0) return false;
|
if (this.termForm.get('tmpSynonymTerm')?.value?.trim().length == 0) return false;
|
||||||
if (this.termForm.get('tmpSynonymEncoding')?.value?.trim().length == 0) return false;
|
if (this.termForm.get('tmpSynonymEncoding')?.value?.trim().length == 0) return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
addSynonym() {
|
addSynonym() {
|
||||||
this.synonymsDatasource.data.push({
|
this.synonymsDatasource.data.push({
|
||||||
term: this.termForm.get('tmpSynonymTerm')?.value!,
|
term: this.termForm.get('tmpSynonymTerm')?.value!,
|
||||||
encoding: this.termForm.get('tmpSynonymEncoding')?.value!
|
encoding: this.termForm.get('tmpSynonymEncoding')?.value!
|
||||||
});
|
});
|
||||||
this.termForm.get('tmpSynonymTerm')?.setValue('');
|
this.termForm.get('tmpSynonymTerm')?.setValue('');
|
||||||
this.termForm.get('tmpSynonymEncoding')?.setValue('OPENAIRE');
|
this.termForm.get('tmpSynonymEncoding')?.setValue('OPENAIRE');
|
||||||
this.synonymsTable?.renderRows();
|
this.synonymsTable?.renderRows();
|
||||||
}
|
}
|
||||||
|
|
||||||
onNoClick(): void {
|
onNoClick(): void {
|
||||||
this.dialogRef.close();
|
this.dialogRef.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,66 +1,66 @@
|
||||||
<h2>Vocabulary Editor</h2>
|
<h2>Vocabulary Editor</h2>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<b>Vocabulary ID: </b>{{voc?.id}}<br />
|
<b>Vocabulary ID: </b>{{voc?.id}}<br />
|
||||||
<b>Vocabulary Name: </b>{{voc?.name}}<br />
|
<b>Vocabulary Name: </b>{{voc?.name}}<br />
|
||||||
<b>Description: </b>{{voc?.description}}
|
<b>Description: </b>{{voc?.description}}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<a mat-stroked-button color="primary" [routerLink]="['/adv_resources/vocabulary']">return to vocabulary list</a>
|
<a mat-stroked-button color="primary" [routerLink]="['/adv_resources/vocabulary']">return to vocabulary list</a>
|
||||||
<button mat-stroked-button color="primary" (click)="newVocabularyTermDialog()">create a new term</button>
|
<button mat-stroked-button color="primary" (click)="newVocabularyTermDialog()">create a new term</button>
|
||||||
<a mat-stroked-button color="primary" href="/api/vocs/{{voc?.id}}/terms" target="_blank">Download</a>
|
<a mat-stroked-button color="primary" href="/api/vocs/{{voc?.id}}/terms" target="_blank">Download</a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%; margin-top: 10px;">
|
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%; margin-top: 10px;">
|
||||||
<mat-label>Filter</mat-label>
|
<mat-label>Filter</mat-label>
|
||||||
<input matInput (keyup)="applyFilter($event)" placeholder="Filter..." #input />
|
<input matInput (keyup)="applyFilter($event)" placeholder="Filter..." #input />
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
<table mat-table [dataSource]="termsDatasource" matSort class="mat-elevation-z8">
|
<table mat-table [dataSource]="termsDatasource" matSort class="mat-elevation-z8">
|
||||||
|
|
||||||
<ng-container matColumnDef="code">
|
<ng-container matColumnDef="code">
|
||||||
<th mat-header-cell *matHeaderCellDef style="width: 15%;" mat-sort-header sortActionDescription="Sort by Code"> Code
|
<th mat-header-cell *matHeaderCellDef style="width: 15%;" mat-sort-header sortActionDescription="Sort by Code"> Code
|
||||||
</th>
|
</th>
|
||||||
<td mat-cell *matCellDef="let element"><b>{{element.code}}</b></td>
|
<td mat-cell *matCellDef="let element"><b>{{element.code}}</b></td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<ng-container matColumnDef="name">
|
<ng-container matColumnDef="name">
|
||||||
<th mat-header-cell *matHeaderCellDef style="width: 15%;" mat-sort-header sortActionDescription="Sort by Name"> Name
|
<th mat-header-cell *matHeaderCellDef style="width: 15%;" mat-sort-header sortActionDescription="Sort by Name"> Name
|
||||||
</th>
|
</th>
|
||||||
<td mat-cell *matCellDef="let element"> {{element.name}} </td>
|
<td mat-cell *matCellDef="let element"> {{element.name}} </td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<ng-container matColumnDef="encoding">
|
<ng-container matColumnDef="encoding">
|
||||||
<th mat-header-cell *matHeaderCellDef style="width: 10%;" mat-sort-header sortActionDescription="Sort by Encoding">
|
<th mat-header-cell *matHeaderCellDef style="width: 10%;" mat-sort-header sortActionDescription="Sort by Encoding">
|
||||||
Encoding </th>
|
Encoding </th>
|
||||||
<td mat-cell *matCellDef="let element">{{element.encoding}}</td>
|
<td mat-cell *matCellDef="let element">{{element.encoding}}</td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<ng-container matColumnDef="synonyms">
|
<ng-container matColumnDef="synonyms">
|
||||||
<th mat-header-cell *matHeaderCellDef style="width: 40%;" mat-sort-header sortActionDescription="Sort by Synonyms">
|
<th mat-header-cell *matHeaderCellDef style="width: 40%;" mat-sort-header sortActionDescription="Sort by Synonyms">
|
||||||
Description </th>
|
Description </th>
|
||||||
<td mat-cell *matCellDef="let element" style="font-size: 0,7em;">
|
<td mat-cell *matCellDef="let element" style="font-size: 0,7em;">
|
||||||
<span class="muted" *ngIf="element.synonyms.length == 0">0 synonym(s)</span>
|
<span class="muted" *ngIf="element.synonyms.length == 0">0 synonym(s)</span>
|
||||||
<span *ngFor="let s of element.synonyms" class="badge-label badge-info">
|
<span *ngFor="let s of element.synonyms" class="badge-label badge-info">
|
||||||
{{s.term}}
|
{{s.term}}
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<ng-container matColumnDef="buttons">
|
<ng-container matColumnDef="buttons">
|
||||||
<th mat-header-cell *matHeaderCellDef style="text-align: right;"></th>
|
<th mat-header-cell *matHeaderCellDef style="text-align: right;"></th>
|
||||||
<td mat-cell *matCellDef="let element" class="table-buttons">
|
<td mat-cell *matCellDef="let element" class="table-buttons">
|
||||||
<button mat-stroked-button color="primary" (click)="editVocabularyTermDialog(element)">edit</button>
|
<button mat-stroked-button color="primary" (click)="editVocabularyTermDialog(element)">edit</button>
|
||||||
<button mat-stroked-button color="warn" (click)="deleteVocabularyTerm(element)">delete</button>
|
<button mat-stroked-button color="warn" (click)="deleteVocabularyTerm(element)">delete</button>
|
||||||
</td>
|
</td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<tr mat-header-row *matHeaderRowDef="colums"></tr>
|
<tr mat-header-row *matHeaderRowDef="colums"></tr>
|
||||||
<tr mat-row *matRowDef="let row; columns: colums;"></tr>
|
<tr mat-row *matRowDef="let row; columns: colums;"></tr>
|
||||||
|
|
||||||
<!-- Row shown when there is no matching data. -->
|
<!-- Row shown when there is no matching data. -->
|
||||||
<tr class="mat-row" *matNoDataRow>
|
<tr class="mat-row" *matNoDataRow>
|
||||||
<td class="mat-cell" colspan="5" style="padding: 0 16px;">No data matching the filter "{{input.value}}"</td>
|
<td class="mat-cell" colspan="5" style="padding: 0 16px;">No data matching the filter "{{input.value}}"</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
|
@ -1,40 +1,41 @@
|
||||||
<h1 mat-dialog-title>Details</h1>
|
<h1 mat-dialog-title>Details</h1>
|
||||||
|
|
||||||
<div mat-dialog-content>
|
<div mat-dialog-content>
|
||||||
<p style="font-size: 0.8em;">
|
<p style="font-size: 0.8em;">
|
||||||
<b>Started at: </b>{{startDate}}<br />
|
<b>Started at: </b>{{startDate}}<br />
|
||||||
<b>Finished at: </b>{{endDate}}<br />
|
<b>Finished at: </b>{{endDate}}<br />
|
||||||
<b>Duration: </b>{{duration}}<br />
|
<b>Duration: </b>{{duration}}<br />
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%;">
|
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%;">
|
||||||
<mat-label>Filter</mat-label>
|
<mat-label>Filter</mat-label>
|
||||||
<input matInput (keyup)="applyFilter($event)" placeholder="Filter..." #filterParams />
|
<input matInput (keyup)="applyFilter($event)" placeholder="Filter..." #filterParams />
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
<table mat-table [dataSource]="wfDatasource" class="mat-elevation-z8">
|
<table mat-table [dataSource]="wfDatasource" class="mat-elevation-z8">
|
||||||
|
|
||||||
<ng-container matColumnDef="k">
|
<ng-container matColumnDef="k">
|
||||||
<th mat-header-cell *matHeaderCellDef>k</th>
|
<th mat-header-cell *matHeaderCellDef>k</th>
|
||||||
<td mat-cell *matCellDef="let element" style="width: 30%;">{{element.k}}</td>
|
<td mat-cell *matCellDef="let element" style="width: 30%;">{{element.k}}</td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<ng-container matColumnDef="v">
|
<ng-container matColumnDef="v">
|
||||||
<th mat-header-cell *matHeaderCellDef>v</th>
|
<th mat-header-cell *matHeaderCellDef>v</th>
|
||||||
<td mat-cell *matCellDef="let element" style="width: 70%;"> {{element.v}} </td>
|
<td mat-cell *matCellDef="let element" style="width: 70%;"> {{element.v}} </td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<!-- <tr mat-header-row *matHeaderRowDef="colums"></tr> -->
|
<!-- <tr mat-header-row *matHeaderRowDef="colums"></tr> -->
|
||||||
<tr mat-row *matRowDef="let row; columns: colums;"></tr>
|
<tr mat-row *matRowDef="let row; columns: colums;"></tr>
|
||||||
|
|
||||||
<!-- Row shown when there is no matching data. -->
|
<!-- Row shown when there is no matching data. -->
|
||||||
<tr class="mat-row" *matNoDataRow>
|
<tr class="mat-row" *matNoDataRow>
|
||||||
<td class="mat-cell" colspan="2" style="padding: 0 16px;">No data matching the filter "{{filterParams.value}}"</td>
|
<td class="mat-cell" colspan="2" style="padding: 0 16px;">No data matching the filter "{{filterParams.value}}"
|
||||||
</tr>
|
</td>
|
||||||
</table>
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div mat-dialog-actions>
|
<div mat-dialog-actions>
|
||||||
<button mat-stroked-button color="primary" mat-dialog-close>Close</button>
|
<button mat-stroked-button color="primary" mat-dialog-close>Close</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,66 +1,75 @@
|
||||||
<h2>Workflow History</h2>
|
<h2>Workflow History</h2>
|
||||||
|
|
||||||
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%;">
|
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%;">
|
||||||
<mat-label>Filter</mat-label>
|
<mat-label>Filter</mat-label>
|
||||||
<input matInput (keyup)="applyFilter($event)" placeholder="Filter..." #input />
|
<input matInput (keyup)="applyFilter($event)" placeholder="Filter..." #input />
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<span *ngIf="from < 0 && to < 0"><b>Recent workflows</b> (max {{total}})</span>
|
<span *ngIf="from < 0 && to < 0"><b>Recent workflows</b> (max {{total}})</span>
|
||||||
<span *ngIf="from >= 0 && to >= 0"><b>Workflows from </b>{{from | date:"yyyy-MM-dd HH:mm:ss"}} <b>to</b> {{to |
|
<span *ngIf="from >= 0 && to >= 0"><b>Workflows from </b>{{from | date:"yyyy-MM-dd HH:mm:ss"}} <b>to</b> {{to |
|
||||||
date:"yyyy-MM-dd HH:mm:ss"}}</span>
|
date:"yyyy-MM-dd HH:mm:ss"}}</span>
|
||||||
<span *ngIf="from >= 0 && to < 0"><b>Workflows from </b>{{from | date:"yyyy-MM-dd HH:mm:ss"}} <b>to</b>
|
<span *ngIf="from >= 0 && to < 0"><b>Workflows from </b>{{from | date:"yyyy-MM-dd HH:mm:ss"}} <b>to</b>
|
||||||
<i>undefined</i></span>
|
<i>undefined</i></span>
|
||||||
<span *ngIf="from < 0 && to >= 0"><b>Workflows from </b><i>undefined</i> <b>to</b> {{to | date:"yyyy-MM-dd
|
<span *ngIf="from < 0 && to >= 0"><b>Workflows from </b><i>undefined</i> <b>to</b> {{to | date:"yyyy-MM-dd
|
||||||
HH:mm:ss"}}</span>
|
HH:mm:ss"}}</span>
|
||||||
<br />
|
<br />
|
||||||
<span><b>Count :</b> {{historyDatasource.filteredData.length}}</span>
|
<span><b>Count :</b> {{historyDatasource.filteredData.length}}</span>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<table mat-table [dataSource]="historyDatasource" matSort class="mat-elevation-z8">
|
<table mat-table [dataSource]="historyDatasource" matSort class="mat-elevation-z8">
|
||||||
|
|
||||||
<ng-container matColumnDef="processId">
|
<ng-container matColumnDef="processId">
|
||||||
<th mat-header-cell *matHeaderCellDef style="width: 15%;" mat-sort-header sortActionDescription="Sort by Process ID"> Process Id </th>
|
<th mat-header-cell *matHeaderCellDef style="width: 15%;" mat-sort-header
|
||||||
<td mat-cell *matCellDef="let element">
|
sortActionDescription="Sort by Process ID"> Process Id </th>
|
||||||
<a (click)="openWfDialog(element)">{{element.processId}}</a>
|
<td mat-cell *matCellDef="let element">
|
||||||
</td>
|
<a (click)="openWfDialog(element)">{{element.processId}}</a>
|
||||||
</ng-container>
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
<ng-container matColumnDef="name">
|
<ng-container matColumnDef="name">
|
||||||
<th mat-header-cell *matHeaderCellDef style="width: 15%;" mat-sort-header sortActionDescription="Sort by WF Name"> Workflow Name </th>
|
<th mat-header-cell *matHeaderCellDef style="width: 15%;" mat-sort-header sortActionDescription="Sort by WF Name">
|
||||||
<td mat-cell *matCellDef="let element"> {{element.name}} </td>
|
Workflow Name </th>
|
||||||
</ng-container>
|
<td mat-cell *matCellDef="let element"> {{element.name}} </td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
<ng-container matColumnDef="family">
|
<ng-container matColumnDef="family">
|
||||||
<th mat-header-cell *matHeaderCellDef style="width: 10%;" mat-sort-header sortActionDescription="Sort by WF Family"> Workflow Family </th>
|
<th mat-header-cell *matHeaderCellDef style="width: 10%;" mat-sort-header sortActionDescription="Sort by WF Family">
|
||||||
<td mat-cell *matCellDef="let element"> {{element.family}} </td>
|
Workflow Family </th>
|
||||||
</ng-container>
|
<td mat-cell *matCellDef="let element"> {{element.family}} </td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
<ng-container matColumnDef="dsName">
|
<ng-container matColumnDef="dsName">
|
||||||
<th mat-header-cell *matHeaderCellDef style="width: 20%;" mat-sort-header sortActionDescription="Sort by Datasource"> Datasource </th>
|
<th mat-header-cell *matHeaderCellDef style="width: 20%;" mat-sort-header
|
||||||
<td mat-cell *matCellDef="let element"> {{element.dsName}} </td>
|
sortActionDescription="Sort by Datasource"> Datasource </th>
|
||||||
</ng-container>
|
<td mat-cell *matCellDef="let element"> {{element.dsName}} </td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
<ng-container matColumnDef="status">
|
<ng-container matColumnDef="status">
|
||||||
<th mat-header-cell *matHeaderCellDef style="width: 10%;" mat-sort-header sortActionDescription="Sort by Status"> Status </th>
|
<th mat-header-cell *matHeaderCellDef style="width: 10%;" mat-sort-header sortActionDescription="Sort by Status">
|
||||||
<td mat-cell *matCellDef="let element"><span class="badge-label" [ngClass]="{'badge-success' : element.status === 'success', 'badge-failure' : element.status === 'failure'}">{{element.status}}</span> </td>
|
Status </th>
|
||||||
</ng-container>
|
<td mat-cell *matCellDef="let element"><span class="badge-label"
|
||||||
|
[ngClass]="{'badge-success' : element.status === 'success', 'badge-failure' : element.status === 'failure'}">{{element.status}}</span>
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
<ng-container matColumnDef="startDate">
|
<ng-container matColumnDef="startDate">
|
||||||
<th mat-header-cell *matHeaderCellDef style="width: 15%;" mat-sort-header sortActionDescription="Sort by Start Date"> Start Date </th>
|
<th mat-header-cell *matHeaderCellDef style="width: 15%;" mat-sort-header
|
||||||
<td mat-cell *matCellDef="let element"> {{element.startDate}} </td>
|
sortActionDescription="Sort by Start Date"> Start Date </th>
|
||||||
</ng-container>
|
<td mat-cell *matCellDef="let element"> {{element.startDate}} </td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
<ng-container matColumnDef="endDate">
|
<ng-container matColumnDef="endDate">
|
||||||
<th mat-header-cell *matHeaderCellDef style="width: 15%;" mat-sort-header sortActionDescription="Sort by End Date"> End Date </th>
|
<th mat-header-cell *matHeaderCellDef style="width: 15%;" mat-sort-header sortActionDescription="Sort by End Date">
|
||||||
<td mat-cell *matCellDef="let element"> {{element.endDate}} </td>
|
End Date </th>
|
||||||
</ng-container>
|
<td mat-cell *matCellDef="let element"> {{element.endDate}} </td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
<tr mat-header-row *matHeaderRowDef="colums"></tr>
|
<tr mat-header-row *matHeaderRowDef="colums"></tr>
|
||||||
<tr mat-row *matRowDef="let row; columns: colums;"></tr>
|
<tr mat-row *matRowDef="let row; columns: colums;"></tr>
|
||||||
|
|
||||||
<!-- Row shown when there is no matching data. -->
|
<!-- Row shown when there is no matching data. -->
|
||||||
<tr class="mat-row" *matNoDataRow>
|
<tr class="mat-row" *matNoDataRow>
|
||||||
<td class="mat-cell" colspan="4" style="padding: 0 16px;">No data matching the filter "{{input.value}}"</td>
|
<td class="mat-cell" colspan="4" style="padding: 0 16px;">No data matching the filter "{{input.value}}"</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { Component, Inject,AfterViewInit, OnInit, ViewChild } from '@angular/core';
|
import { Component, Inject, AfterViewInit, OnInit, ViewChild } from '@angular/core';
|
||||||
import { ISService } from '../common/is.service';
|
import { ISService } from '../common/is.service';
|
||||||
import { MatTableDataSource } from '@angular/material/table';
|
import { MatTableDataSource } from '@angular/material/table';
|
||||||
import { MatSort } from '@angular/material/sort';
|
import { MatSort } from '@angular/material/sort';
|
||||||
|
@ -8,148 +8,148 @@ import { combineLatest } from 'rxjs';
|
||||||
import { MatDialog, MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
import { MatDialog, MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-wf-history',
|
selector: 'app-wf-history',
|
||||||
templateUrl: './wf-history.component.html',
|
templateUrl: './wf-history.component.html',
|
||||||
styleUrls: ['./wf-history.component.css']
|
styleUrls: ['./wf-history.component.css']
|
||||||
})
|
})
|
||||||
export class WfHistoryComponent implements AfterViewInit , OnInit{
|
export class WfHistoryComponent implements AfterViewInit, OnInit {
|
||||||
|
|
||||||
historyDatasource: MatTableDataSource<WfHistoryEntry> = new MatTableDataSource<WfHistoryEntry>([]);
|
historyDatasource: MatTableDataSource<WfHistoryEntry> = new MatTableDataSource<WfHistoryEntry>([]);
|
||||||
|
|
||||||
colums: string[] = ['processId', 'name', 'family', 'dsName', 'status', 'startDate', 'endDate'];
|
colums: string[] = ['processId', 'name', 'family', 'dsName', 'status', 'startDate', 'endDate'];
|
||||||
|
|
||||||
total: number = 100
|
total: number = 100
|
||||||
from: number = -1
|
from: number = -1
|
||||||
to: 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) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
combineLatest([ this.route.params, this.route.queryParams ],
|
combineLatest([this.route.params, this.route.queryParams],
|
||||||
(params: Params, queryParams: Params) => ({ params, queryParams })
|
(params: Params, queryParams: Params) => ({ params, queryParams })
|
||||||
).subscribe((res: { params: Params; queryParams: Params }) => {
|
).subscribe((res: { params: Params; queryParams: Params }) => {
|
||||||
const { params, queryParams} = res;
|
const { params, queryParams } = res;
|
||||||
let totalP = queryParams['total'];
|
let totalP = queryParams['total'];
|
||||||
let fromP = queryParams['from'];
|
let fromP = queryParams['from'];
|
||||||
let toP = queryParams['to'];
|
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, (data: WfHistoryEntry[]) => this.historyDatasource.data = data);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@ViewChild(MatSort) sort: MatSort | undefined
|
if (totalP) { this.total = parseInt(totalP); }
|
||||||
|
if (fromP) { this.from = parseInt(fromP); }
|
||||||
|
if (toP) { this.to = parseInt(toP); }
|
||||||
|
|
||||||
ngAfterViewInit() {
|
this.service.loadWfHistory(this.total, this.from, this.to, (data: WfHistoryEntry[]) => this.historyDatasource.data = data);
|
||||||
if(this.sort) this.historyDatasource.sort = this.sort;
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
applyFilter(event: Event) {
|
@ViewChild(MatSort) sort: MatSort | undefined
|
||||||
const filterValue = (event.target as HTMLInputElement).value.trim().toLowerCase();
|
|
||||||
this.historyDatasource.filter = filterValue;
|
ngAfterViewInit() {
|
||||||
}
|
if (this.sort) this.historyDatasource.sort = this.sort;
|
||||||
|
}
|
||||||
|
|
||||||
|
applyFilter(event: Event) {
|
||||||
|
const filterValue = (event.target as HTMLInputElement).value.trim().toLowerCase();
|
||||||
|
this.historyDatasource.filter = filterValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
openWfDialog(wf: WfHistoryEntry): void {
|
||||||
|
const wfDialogRef = this.dialog.open(WfDialog, {
|
||||||
|
data: wf
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
openWfDialog(wf: WfHistoryEntry): void {
|
|
||||||
const wfDialogRef = this.dialog.open(WfDialog, {
|
|
||||||
data: wf
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'wf-dialog',
|
selector: 'wf-dialog',
|
||||||
templateUrl: 'wf-dialog.html',
|
templateUrl: 'wf-dialog.html',
|
||||||
styleUrls: ['wf-history.component.css']
|
styleUrls: ['wf-history.component.css']
|
||||||
|
|
||||||
})
|
})
|
||||||
export class WfDialog {
|
export class WfDialog {
|
||||||
startDate:string = '';
|
startDate: string = '';
|
||||||
endDate:string = '';
|
endDate: string = '';
|
||||||
duration:string = '';
|
duration: string = '';
|
||||||
|
|
||||||
|
wfDatasource: MatTableDataSource<KeyValue> = new MatTableDataSource<KeyValue>([]);
|
||||||
|
colums: string[] = ['k', 'v'];
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
public dialogRef: MatDialogRef<WfDialog>,
|
||||||
|
@Inject(MAT_DIALOG_DATA) public data: WfHistoryEntry,
|
||||||
|
) {
|
||||||
|
let list: KeyValue[] = [];
|
||||||
|
let map = new Map(Object.entries(data.details));
|
||||||
|
for (let [key, value] of map) {
|
||||||
|
list.push({ k: key, v: value });
|
||||||
|
}
|
||||||
|
this.wfDatasource.data = list;
|
||||||
|
this.startDate = data.startDate;
|
||||||
|
this.endDate = data.endDate;
|
||||||
|
this.duration = this.calculateDateDiff(
|
||||||
|
parseInt(map.get('system:startDate')),
|
||||||
|
parseInt(map.get('system:endDate'))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
applyFilter(event: Event) {
|
||||||
|
const filterValue = (event.target as HTMLInputElement).value.trim().toLowerCase();
|
||||||
|
this.wfDatasource.filter = filterValue;
|
||||||
|
}
|
||||||
|
onNoClick(): void {
|
||||||
|
this.dialogRef.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
calculateDateDiff(start: number, end: number): string {
|
||||||
|
if (start <= 0 || end <= 0) {
|
||||||
|
return '-';
|
||||||
|
}
|
||||||
|
var seconds = 0;
|
||||||
|
var minutes = 0;
|
||||||
|
var hours = 0;
|
||||||
|
var days = 0;
|
||||||
|
|
||||||
|
if (end > start) {
|
||||||
|
seconds = Math.round((end - start) / 1000);
|
||||||
|
if (seconds > 60) {
|
||||||
|
minutes = Math.floor(seconds / 60);
|
||||||
|
seconds = seconds % 60;
|
||||||
|
if (minutes > 60) {
|
||||||
|
hours = Math.floor(minutes / 60);
|
||||||
|
minutes = minutes % 60;
|
||||||
|
if (hours > 24) {
|
||||||
|
days = Math.floor(hours / 24);
|
||||||
|
hours = hours % 24;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var res = '';
|
||||||
|
if (days > 0) {
|
||||||
|
if (res) { res += ', '; }
|
||||||
|
res += days + " day(s)"
|
||||||
|
}
|
||||||
|
if (hours > 0) {
|
||||||
|
if (res) { res += ', '; }
|
||||||
|
res += hours + " hour(s)"
|
||||||
|
}
|
||||||
|
if (minutes > 0) {
|
||||||
|
if (res) { res += ', '; }
|
||||||
|
res += minutes + " minute(s)"
|
||||||
|
}
|
||||||
|
if (seconds > 0) {
|
||||||
|
if (res) { res += ', '; }
|
||||||
|
res += seconds + " second(s)"
|
||||||
|
}
|
||||||
|
if (!res) {
|
||||||
|
res = '0 seconds';
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
wfDatasource: MatTableDataSource<KeyValue> = new MatTableDataSource<KeyValue>([]);
|
|
||||||
colums: string[] = ['k', 'v'];
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
public dialogRef: MatDialogRef<WfDialog>,
|
|
||||||
@Inject(MAT_DIALOG_DATA) public data: WfHistoryEntry,
|
|
||||||
) {
|
|
||||||
let list:KeyValue[] = [];
|
|
||||||
let map = new Map(Object.entries(data.details));
|
|
||||||
for (let [key, value] of map) {
|
|
||||||
list.push({k: key, v: value});
|
|
||||||
}
|
|
||||||
this.wfDatasource.data = list;
|
|
||||||
this.startDate = data.startDate;
|
|
||||||
this.endDate = data.endDate;
|
|
||||||
this.duration = this.calculateDateDiff(
|
|
||||||
parseInt(map.get('system:startDate')),
|
|
||||||
parseInt(map.get('system:endDate'))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
applyFilter(event: Event) {
|
|
||||||
const filterValue = (event.target as HTMLInputElement).value.trim().toLowerCase();
|
|
||||||
this.wfDatasource.filter = filterValue;
|
|
||||||
}
|
|
||||||
onNoClick(): void {
|
|
||||||
this.dialogRef.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
calculateDateDiff(start:number, end:number):string {
|
|
||||||
if (start <= 0 || end <= 0) {
|
|
||||||
return '-';
|
|
||||||
}
|
|
||||||
var seconds = 0;
|
|
||||||
var minutes = 0;
|
|
||||||
var hours = 0;
|
|
||||||
var days = 0;
|
|
||||||
|
|
||||||
if (end > start) {
|
|
||||||
seconds = Math.round((end - start) / 1000);
|
|
||||||
if (seconds > 60) {
|
|
||||||
minutes = Math.floor(seconds / 60);
|
|
||||||
seconds = seconds % 60;
|
|
||||||
if (minutes > 60) {
|
|
||||||
hours = Math.floor(minutes / 60);
|
|
||||||
minutes = minutes % 60;
|
|
||||||
if (hours > 24) {
|
|
||||||
days = Math.floor(hours / 24);
|
|
||||||
hours = hours % 24;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var res = '';
|
|
||||||
if (days > 0) {
|
|
||||||
if (res) { res += ', '; }
|
|
||||||
res += days + " day(s)"
|
|
||||||
}
|
|
||||||
if (hours > 0) {
|
|
||||||
if (res) { res += ', '; }
|
|
||||||
res += hours + " hour(s)"
|
|
||||||
}
|
|
||||||
if (minutes > 0) {
|
|
||||||
if (res) { res += ', '; }
|
|
||||||
res += minutes + " minute(s)"
|
|
||||||
}
|
|
||||||
if (seconds > 0) {
|
|
||||||
if (res) { res += ', '; }
|
|
||||||
res += seconds + " second(s)"
|
|
||||||
}
|
|
||||||
if (!res) {
|
|
||||||
res = '0 seconds';
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,16 +1,19 @@
|
||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<title>DnetIsApplication</title>
|
<title>DnetIsApplication</title>
|
||||||
<base href="/">
|
<base href="/">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
||||||
<link rel="preconnect" href="https://fonts.gstatic.com">
|
<link rel="preconnect" href="https://fonts.gstatic.com">
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap" rel="stylesheet">
|
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap" rel="stylesheet">
|
||||||
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
|
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="mat-typography">
|
<body class="mat-typography">
|
||||||
<app-root></app-root>
|
<app-root></app-root>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
{
|
{
|
||||||
"/ajax": {
|
"/ajax": {
|
||||||
"target": "http://localhost:8280",
|
"target": "http://localhost:8280",
|
||||||
"secure": false
|
"secure": false
|
||||||
},
|
},
|
||||||
"/api": {
|
"/api": {
|
||||||
"target": "http://localhost:8280",
|
"target": "http://localhost:8280",
|
||||||
"secure": false
|
"secure": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,108 +1,129 @@
|
||||||
/* You can add global styles to this file, and also import other style files */
|
/* You can add global styles to this file, and also import other style files */
|
||||||
|
|
||||||
html, body { height: 100%; }
|
html,
|
||||||
body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; }
|
body {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.small { font-size: 0.9em !important; }
|
body {
|
||||||
.muted { color: darkgray; }
|
margin: 0;
|
||||||
|
font-family: Roboto, "Helvetica Neue", sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
table {
|
.small {
|
||||||
width: 100%;
|
font-size: 0.9em !important;
|
||||||
table-layout: fixed !important;
|
}
|
||||||
|
|
||||||
|
.muted {
|
||||||
|
color: darkgray;
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
width: 100%;
|
||||||
|
table-layout: fixed !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
tr {
|
tr {
|
||||||
height: auto !important;
|
height: auto !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
th.mat-sort-header-sorted { color: black !important; }
|
th.mat-sort-header-sorted {
|
||||||
|
color: black !important;
|
||||||
th, td {
|
|
||||||
white-space: nowrap !important;
|
|
||||||
overflow: hidden !important;
|
|
||||||
text-overflow: ellipsis !important;
|
|
||||||
font-size: 0.9em !important;
|
|
||||||
padding-top: 0.5em !important;
|
|
||||||
padding-bottom: 0.5em !important;
|
|
||||||
text-align: left;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.table-buttons { text-align: right !important; }
|
th,
|
||||||
.table-buttons button {
|
td {
|
||||||
font-size: 0.8em !important;
|
white-space: nowrap !important;
|
||||||
padding: 0 !important;
|
overflow: hidden !important;
|
||||||
height: 2.5em !important;
|
text-overflow: ellipsis !important;
|
||||||
|
font-size: 0.9em !important;
|
||||||
|
padding-top: 0.5em !important;
|
||||||
|
padding-bottom: 0.5em !important;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-buttons {
|
||||||
|
text-align: right !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-buttons button {
|
||||||
|
font-size: 0.8em !important;
|
||||||
|
padding: 0 !important;
|
||||||
|
height: 2.5em !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.warning {
|
.warning {
|
||||||
background-color: darkorange;
|
background-color: darkorange;
|
||||||
}
|
}
|
||||||
|
|
||||||
.text-monospace {
|
.text-monospace {
|
||||||
font-family: monospace;
|
font-family: monospace;
|
||||||
}
|
}
|
||||||
|
|
||||||
a, a:not([href]) {
|
a,
|
||||||
cursor: pointer;
|
a:not([href]) {
|
||||||
-webkit-user-select: none;
|
cursor: pointer;
|
||||||
-moz-user-select: none;
|
-webkit-user-select: none;
|
||||||
user-select: none;
|
-moz-user-select: none;
|
||||||
text-decoration: none;
|
user-select: none;
|
||||||
text-underline-offset: 3px;
|
text-decoration: none;
|
||||||
color: #336699;
|
text-underline-offset: 3px;
|
||||||
|
color: #336699;
|
||||||
}
|
}
|
||||||
|
|
||||||
a:hover, a:not([href]):hover {
|
a:hover,
|
||||||
text-decoration: underline;
|
a:not([href]):hover {
|
||||||
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
|
|
||||||
.badge-label {
|
.badge-label {
|
||||||
padding-top: 0.3em;
|
padding-top: 0.3em;
|
||||||
padding-bottom: 0.3em;
|
padding-bottom: 0.3em;
|
||||||
padding-left: 0.5em;
|
padding-left: 0.5em;
|
||||||
padding-right: 0.5em;
|
padding-right: 0.5em;
|
||||||
border-radius: 0.7em;
|
border-radius: 0.7em;
|
||||||
font-size: 0.9em;
|
font-size: 0.9em;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.badge-default {
|
.badge-default {
|
||||||
background-color:#336699;
|
background-color: #336699;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.badge-success {
|
.badge-success {
|
||||||
background-color:darkgreen;
|
background-color: darkgreen;
|
||||||
}
|
}
|
||||||
|
|
||||||
.badge-failure {
|
.badge-failure {
|
||||||
background-color:red;
|
background-color: red;
|
||||||
}
|
}
|
||||||
|
|
||||||
.badge-warning {
|
.badge-warning {
|
||||||
background-color:darkorange;
|
background-color: darkorange;
|
||||||
}
|
}
|
||||||
|
|
||||||
.badge-info {
|
.badge-info {
|
||||||
background-color: cornflowerblue
|
background-color: cornflowerblue
|
||||||
}
|
}
|
||||||
|
|
||||||
.mat-mdc-dialog-actions .mat-mdc-form-field-error {
|
.mat-mdc-dialog-actions .mat-mdc-form-field-error {
|
||||||
margin-left: 2em !important;
|
margin-left: 2em !important;
|
||||||
margin-right: 2em !important;
|
margin-right: 2em !important;
|
||||||
font-size: 0.75em !important;
|
font-size: 0.75em !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.spinner {
|
.spinner {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
width: 300px;
|
width: 300px;
|
||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
top: 40%;
|
top: 40%;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
z-index: 10000;
|
z-index: 10000;
|
||||||
}
|
}
|
||||||
|
|
||||||
.spinner * { margin: auto; }
|
.spinner * {
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue