Implementing UI

This commit is contained in:
Luca Frosini 2019-10-11 18:16:14 +02:00
parent ac8be3648b
commit a5c881fc22
10 changed files with 320 additions and 226 deletions

View File

@ -11,6 +11,14 @@
"port": 9261,
"webRoot": "${workspaceFolder}",
"url": "http://localhost:4200/#"
},
{
"name": "Launch Chrome localhost",
"type": "chrome",
"request": "launch",
"port": 9276,
"webRoot": "${workspaceFolder}",
"url": "http://localhost:4200/"
}
]
}

View File

@ -0,0 +1,7 @@
export interface ISType {
name: string;
description: string | null;
abstract: boolean;
superClasses?: string[];
properties?: any[];
}

View File

@ -1,6 +1,8 @@
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HttpClientModule } from '@angular/common/http';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import { AppComponent } from './app.component';
@ -17,7 +19,8 @@ import { ResourceTypesTreeComponent } from './resource-types-tree/resource-types
],
imports: [
NgbModule,
BrowserModule
BrowserModule,
HttpClientModule
],
providers: [],
bootstrap: [AppComponent]

View File

@ -0,0 +1,12 @@
import { TestBed } from '@angular/core/testing';
import { IsService } from './is.service';
describe('IsService', () => {
beforeEach(() => TestBed.configureTestingModule({}));
it('should be created', () => {
const service: IsService = TestBed.get(IsService);
expect(service).toBeTruthy();
});
});

View File

@ -0,0 +1,48 @@
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable, of } from 'rxjs';
import { catchError, tap } from 'rxjs/operators';
import { ISType } from './ISType';
import { types } from './types';
@Injectable({
providedIn: 'root'
})
export class IsService {
constructor(private httpClient: HttpClient) { }
/* NextNext Token */
private token = '';
/**
* Handle Http operation that failed.
* Let the app continue.
* @param operation - name of the operation that failed
* @param result - optional value to return as the observable result
*/
private handleError<T>(operation = 'operation', result?: T) {
return (error: any): Observable<T> => {
console.error(error);
console.error(`${operation} failed: ${error.message}`); // log to console instead
// Let the app keep running by returning an empty result.
return of(result as T);
};
}
public getResourceTypes(): Observable<ISType[]> {
const url = 'http://pc-frosini.isti.cnr.it:8080/resource-registry/types/Resource?polymorphic=true&gcube-token=' + this.token;
// const observable: Observable<ISType[]> = of(types);
const observable: Observable<ISType[]> = this.httpClient.get<ISType[]>(url);
/*
observable.pipe(
tap(_ => console.info('Fetched Resource Types')),
catchError(this.handleError<ISType[]>('getResourceTypes()', types))
);
*/
return observable
}
}

View File

@ -1,7 +1,7 @@
<ul id="resource-tree" class="list-group">
<ng-template #recursiveList let-resources>
<li *ngFor="let type of resources" class="list-group-item">
<a class="nav-link" href="#" [title]="type.description">{{ type.name }}</a>
<a class="nav-link" href="#" [title]="type.description" (click)="loadResources(type.name)">{{ type.name }}</a>
<ul *ngIf="type.children.length > 0">
<ng-container *ngTemplateOutlet="recursiveList; context:{ $implicit: type.children }"></ng-container>
</ul>

View File

@ -1,28 +1,7 @@
import { Component, OnInit } from '@angular/core';
import { types } from './types';
export class Type {
name: string;
description: string;
abstract: boolean;
parent: Type;
children: Type[];
constructor(type: { name: string; description: string; superClasses?: string[]; properties?: any; abstract: boolean; }) {
this.name = type.name;
this.description = type.description;
this.abstract = type.abstract;
this.children = new Array();
}
addChild(type: Type) {
type.parent = this;
this.children.push(type);
}
}
import { IsService } from '../is.service';
import { Type } from '../type';
import { ISType } from '../ISType';
@Component({
selector: 'app-resource-types-tree',
@ -33,53 +12,65 @@ export class ResourceTypesTreeComponent implements OnInit {
resources: Type[];
map = new Map<string, Type>();
unassociated = new Map<string, {
name: string; description: string; superClasses?: string[];
properties?: any[]; abstract: boolean;
}>();
constructor() { }
analyseUnassociated(type: Type) {
const associated: string[] = new Array();
for (const name of this.unassociated.keys()) {
const t = this.unassociated.get(name);
const parent = t.superClasses[0];
if (parent === type.name) {
type.addChild(this.map.get(t.name));
associated.push(t.name);
}
}
for (const a of associated) {
this.unassociated.delete(a);
}
}
constructor(private isService: IsService) { }
ngOnInit() {
this.getResourceTypes();
}
for (const t of types) {
const type: Type = new Type(t);
private analyseTypes(isTypes: ISType[]): void {
this.map.set(type.name, type);
const map = new Map<string, Type>();
const unassociated = new Map<string, ISType>();
if (type.name !== 'Resource') {
const analyseUnassociated = function(type: Type) {
const associated: string[] = new Array();
for (const name of unassociated.keys()) {
const t = unassociated.get(name);
const parent = t.superClasses[0];
if (this.map.has(parent)) {
this.map.get(parent).addChild(type);
} else {
this.analyseUnassociated(type);
this.unassociated.set(type.name, t);
if (parent === type.name) {
type.addChild(map.get(t.name));
associated.push(t.name);
}
}
for (const a of associated) {
unassociated.delete(a);
}
};
const analyseType = function(isType: ISType) {
const type: Type = new Type(isType);
map.set(type.name, type);
if (type.name !== 'Resource') {
const parent = isType.superClasses[0];
if (map.has(parent)) {
map.get(parent).addChild(type);
} else {
analyseUnassociated(type);
unassociated.set(type.name, isType);
}
}
};
for (const isType of isTypes) {
analyseType(isType);
}
this.resources = this.map.get('Resource').children;
this.resources = map.get('Resource').children;
}
private getResourceTypes(): void {
this.isService.getResourceTypes().subscribe(this.analyseTypes);
}
loadResources(typeName: string) {
window.alert('Loading ' + typeName + ' resources');
}
}

View File

@ -1,164 +0,0 @@
export const types = [
{
name: 'Resource',
description: '',
superClasses: [
'Entity'
],
properties: null,
abstract: true
},
{
name: 'Service',
description: 'Collect Service information through the list of its facets',
superClasses: [
'Resource'
],
properties: null,
abstract: true
},
{
name: 'HostingNode',
description: 'Collect Hosting Node information through the list of its facets',
superClasses: [
'Service'
],
properties: null,
abstract: false
},
{
name: 'Software',
description: 'Collect Software information through the list of its facets',
superClasses: [
'Resource'
],
properties: null,
abstract: false
},
{
name: 'Plugin',
description: 'Collect Plugin information through the list of its facets',
superClasses: [
'Software'
],
properties: null,
abstract: false
},
{
name: 'Actor',
description: 'Any entity (human or machine) playing an active role.',
superClasses: [
'Resource'
],
properties: null,
abstract: true
},
{
name: 'LegalBody',
description: 'Actor',
superClasses: [
'Actor'
],
properties: null,
abstract: false
},
{
name: 'Dataset',
description: 'Collect Dataset information through the list of its facets',
superClasses: [
'Resource'
],
properties: null,
abstract: false
},
{
name: 'Person',
description: 'Person',
superClasses: [
'Actor'
],
properties: null,
abstract: false
},
{
name: 'Schema',
description: 'Collect Schema information through the list of its facets',
superClasses: [
'Resource'
],
properties: null,
abstract: false
},
{
name: 'Site',
description: 'Collect Site information through the list of its facets',
superClasses: [
'Resource'
],
properties: null,
abstract: false
},
{
name: 'ConcreteDataset',
description: 'Collect Dataset information through the list of its facets',
superClasses: [
'Dataset'
],
properties: null,
abstract: false
},
{
name: 'VirtualMachine',
description: 'Collect Hosting Node information through the list of its facets',
superClasses: [
'Service'
],
properties: null,
abstract: false
},
{
name: 'ConfigurationTemplate',
description: 'It represents a template for a configuration. It describe how a configuration has to be realized. E.g. Used to define the accounting configuration parameters template.',
superClasses: [
'Resource'
],
properties: null,
abstract: false
},
{
name: 'Configuration',
description: 'Collect Configuration information through the list of its facets',
superClasses: [
'ConfigurationTemplate'
],
properties: null,
abstract: false
},
{
name: 'EService',
description: 'Collect Electronic Service (aka Running Service) information through the list of its facets',
superClasses: [
'Service'
],
properties: null,
abstract: false
},
{
name: 'VirtualService',
description: 'Collect Virtual Service information through the list of its facets',
superClasses: [
'Service'
],
properties: null,
abstract: false
},
{
name: 'RunningPlugin',
description: 'Collect Running Plugin information through the list of its facets',
superClasses: [
'EService'
],
properties: null,
abstract: false
}
];

View File

@ -0,0 +1,23 @@
import { ISType } from './ISType';
export class Type {
name: string;
description: string;
abstract: boolean;
parent: Type;
children: Type[];
constructor(isType: ISType) {
this.name = isType.name;
this.description = isType.description;
this.abstract = isType.abstract;
this.children = new Array();
}
addChild(type: Type) {
type.parent = this;
this.children.push(type);
}
}

View File

@ -0,0 +1,166 @@
import { ISType } from './ISType';
export const types: ISType[] = [
{
"name": "Resource",
"description": null,
"superClasses": [
"Entity"
],
"properties": [],
"abstract": true
},
{
"name": "Service",
"description": null,
"superClasses": [
"Resource"
],
"properties": [],
"abstract": true
},
{
"name": "ConfigurationTemplate",
"description": null,
"superClasses": [
"Resource"
],
"properties": [],
"abstract": false
},
{
"name": "Dataset",
"description": null,
"superClasses": [
"Resource"
],
"properties": [],
"abstract": false
},
{
"name": "ConcreteDataset",
"description": null,
"superClasses": [
"Dataset"
],
"properties": [],
"abstract": false
},
{
"name": "HostingNode",
"description": null,
"superClasses": [
"Service"
],
"properties": [],
"abstract": false
},
{
"name": "VirtualService",
"description": null,
"superClasses": [
"Service"
],
"properties": [],
"abstract": false
},
{
"name": "EService",
"description": null,
"superClasses": [
"Service"
],
"properties": [],
"abstract": false
},
{
"name": "RunningPlugin",
"description": null,
"superClasses": [
"EService"
],
"properties": [],
"abstract": false
},
{
"name": "Software",
"description": null,
"superClasses": [
"Resource"
],
"properties": [],
"abstract": false
},
{
"name": "Schema",
"description": null,
"superClasses": [
"Resource"
],
"properties": [],
"abstract": false
},
{
"name": "Configuration",
"description": null,
"superClasses": [
"ConfigurationTemplate"
],
"properties": [],
"abstract": false
},
{
"name": "LegalBody",
"description": null,
"superClasses": [
"Actor"
],
"properties": [],
"abstract": false
},
{
"name": "VirtualMachine",
"description": null,
"superClasses": [
"Service"
],
"properties": [],
"abstract": false
},
{
"name": "Site",
"description": null,
"superClasses": [
"Resource"
],
"properties": [],
"abstract": false
},
{
"name": "Person",
"description": null,
"superClasses": [
"Actor"
],
"properties": [],
"abstract": false
},
{
"name": "Plugin",
"description": null,
"superClasses": [
"Software"
],
"properties": [],
"abstract": false
},
{
"name": "Actor",
"description": null,
"superClasses": [
"Resource"
],
"properties": [],
"abstract": true
}
];