diff --git a/package-lock.json b/package-lock.json index 3a0915f..a9fb743 100644 --- a/package-lock.json +++ b/package-lock.json @@ -28,6 +28,7 @@ "@ngx-translate/core": "14.0.0", "@ngx-translate/http-loader": "7.0.0", "@popperjs/core": "2.11.6", + "angular-in-memory-web-api": "^0.11.0", "bootstrap": "5.2.0", "bootstrap-icons": "^1.11.1", "cytoscape": "3.25.0", @@ -8090,6 +8091,16 @@ "ajv": "^8.8.2" } }, + "node_modules/angular-in-memory-web-api": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/angular-in-memory-web-api/-/angular-in-memory-web-api-0.11.0.tgz", + "integrity": "sha512-QV1qYHm+Zd+wrvlcPLnAcqqGpOmCN1EUj4rRuYHpek8+QqFFdxBNuPZOJCKvU7I97z5QSKHsdc6PNKlpUQr3UA==", + "peerDependencies": { + "@angular/common": ">=8.0.0", + "@angular/core": ">=8.0.0", + "rxjs": "^6.0.0" + } + }, "node_modules/ansi-colors": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", @@ -12875,9 +12886,9 @@ } }, "node_modules/follow-redirects": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", - "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "version": "1.15.5", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz", + "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==", "dev": true, "funding": [ { @@ -31992,6 +32003,11 @@ "fast-deep-equal": "^3.1.3" } }, + "angular-in-memory-web-api": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/angular-in-memory-web-api/-/angular-in-memory-web-api-0.11.0.tgz", + "integrity": "sha512-QV1qYHm+Zd+wrvlcPLnAcqqGpOmCN1EUj4rRuYHpek8+QqFFdxBNuPZOJCKvU7I97z5QSKHsdc6PNKlpUQr3UA==" + }, "ansi-colors": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", @@ -35509,9 +35525,9 @@ } }, "follow-redirects": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", - "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "version": "1.15.5", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz", + "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==", "dev": true }, "for-each": { diff --git a/package.json b/package.json index 9594d82..bc0291e 100644 --- a/package.json +++ b/package.json @@ -92,6 +92,7 @@ "@ngx-translate/core": "14.0.0", "@ngx-translate/http-loader": "7.0.0", "@popperjs/core": "2.11.6", + "angular-in-memory-web-api": "^0.11.0", "bootstrap": "5.2.0", "bootstrap-icons": "^1.11.1", "cytoscape": "3.25.0", diff --git a/src/main/java/org/gcube/informationsystem/service/InformationSystemService.java b/src/main/java/org/gcube/informationsystem/service/InformationSystemService.java index bb94f30..5acc112 100644 --- a/src/main/java/org/gcube/informationsystem/service/InformationSystemService.java +++ b/src/main/java/org/gcube/informationsystem/service/InformationSystemService.java @@ -265,10 +265,21 @@ public class InformationSystemService { return instancesAsObject; } + //retrieve available facets for a given resource Type + public void getFacetsPerType(String resourceType) throws Exception { + String currentCtx = SecretManagerProvider.instance.get().getContext(); + ResourceRegistryClient resourceRegistryClient= ResourceRegistryClientFactory.create(currentCtx); + //publisher.createResource(new Resource) + + } + + //CRUD - 1 public void createResourceInstance(String resourceType) throws Exception { String currentCtx = SecretManagerProvider.instance.get().getContext(); ResourceRegistryPublisher publisher = ResourceRegistryPublisherFactory.create(currentCtx); + String jsonDescription=""; + publisher.createResource(jsonDescription); //publisher.createResource(new Resource) } diff --git a/src/main/webapp/app/add-resource/add-resource.component.html b/src/main/webapp/app/add-resource/add-resource.component.html new file mode 100644 index 0000000..33cac95 --- /dev/null +++ b/src/main/webapp/app/add-resource/add-resource.component.html @@ -0,0 +1,8 @@ +

Modular Form:

+ + + diff --git a/src/main/webapp/app/add-resource/add-resource.component.scss b/src/main/webapp/app/add-resource/add-resource.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/main/webapp/app/add-resource/add-resource.component.ts b/src/main/webapp/app/add-resource/add-resource.component.ts new file mode 100644 index 0000000..dd55483 --- /dev/null +++ b/src/main/webapp/app/add-resource/add-resource.component.ts @@ -0,0 +1,57 @@ +/* eslint-disable @typescript-eslint/no-empty-function */ +import { CommonModule } from '@angular/common'; +import { Component, OnInit } from '@angular/core'; +import { FormArray, FormBuilder, FormGroup, ReactiveFormsModule,Validators } from '@angular/forms'; +import { Router, RouterModule } from '@angular/router'; +import { DynamicFormComponent } from 'app/dynamic-form/dynamic-form.component'; +import { DynamicFormQuestionComponent } from 'app/dynamic-form/dynamic-form-question.component'; +import { QuestionService } from 'app/dynamic-form/question.service'; +import { Observable } from 'rxjs'; +import { QuestionBase } from 'app/dynamic-form/question-base'; +import { MatDialogModule } from '@angular/material/dialog'; + + +@Component({ + standalone:true, + selector: 'jhi-add-resource', + templateUrl: './add-resource.component.html', + styleUrls: ['./add-resource.component.scss'], + providers: [QuestionService], + imports:[CommonModule,DynamicFormComponent,DynamicFormQuestionComponent, + ReactiveFormsModule,RouterModule, + MatDialogModule] +}) + +export class AddResourceComponent implements OnInit { + + myForm: FormGroup | any; + + //PER FORM DINAMICA + questions$: Observable[]>; + + constructor(private router:Router, private formService: QuestionService, private fb: FormBuilder) { + this.questions$ = formService.getQuestions('HostingNode'); + } + + ngOnInit(): void { + this.myForm = this.fb.group({ + items: this.fb.array([]) // Initialize an empty FormArray + }); + } + + //TO ADD FORM ITEMS DYNAMICALLY + addItem():void { + const item = this.fb.group({ + name: ['', Validators.required], + quantity: [1, [Validators.required, Validators.min(1)]], + // Add more form controls as needed + }); + this.items.push(item); +} + + // Helper method to get the 'items' FormArray + get items():FormArray { + return this.myForm.get('items') as FormArray; + } + +} diff --git a/src/main/webapp/app/add-resource/add-resource.route.ts b/src/main/webapp/app/add-resource/add-resource.route.ts new file mode 100644 index 0000000..53810c6 --- /dev/null +++ b/src/main/webapp/app/add-resource/add-resource.route.ts @@ -0,0 +1,13 @@ +import { Routes } from '@angular/router'; +import { AddResourceComponent } from './add-resource.component'; + + +export const addResourceRoutes: Routes = [ + { + path: '', + component: AddResourceComponent, + data: { + pageTitle: 'Test Modular Form', + }, + }, +]; \ No newline at end of file diff --git a/src/main/webapp/app/app-routing.module.ts b/src/main/webapp/app/app-routing.module.ts index b9bcb9c..b8b4c9f 100644 --- a/src/main/webapp/app/app-routing.module.ts +++ b/src/main/webapp/app/app-routing.module.ts @@ -1,5 +1,5 @@ import { NgModule } from '@angular/core'; -import { RouterModule } from '@angular/router'; +import { RouterModule, Routes } from '@angular/router'; import { errorRoute } from './layouts/error/error.route'; import { navbarRoute } from './layouts/navbar/navbar.route'; @@ -7,9 +7,14 @@ import { DEBUG_INFO_ENABLED } from 'app/app.constants'; import { Authority } from 'app/config/authority.constants'; import { UserRouteAccessService } from 'app/core/auth/user-route-access.service'; +import { CommonModule } from '@angular/common'; +import { AddResourceComponent } from './add-resource/add-resource.component'; + +const routes: Routes =[{path:'addResource', component: AddResourceComponent}]; @NgModule({ imports: [ + CommonModule, RouterModule.forRoot( [ { @@ -21,11 +26,17 @@ import { UserRouteAccessService } from 'app/core/auth/user-route-access.service' loadChildren: () => import('./admin/admin-routing.module').then(m => m.AdminRoutingModule), }, + { + path: 'addResource', + component: AddResourceComponent + }, + navbarRoute, ...errorRoute, ], { enableTracing: DEBUG_INFO_ENABLED } ), + //RouterModule.forChild() ], exports: [RouterModule], }) diff --git a/src/main/webapp/app/app.module.ts b/src/main/webapp/app/app.module.ts index 0dd338e..f798fb5 100644 --- a/src/main/webapp/app/app.module.ts +++ b/src/main/webapp/app/app.module.ts @@ -33,7 +33,8 @@ import { ResourceAddComponent } from './resource-add/resource-add.component'; import { ResourceDeleteComponent } from './resource-delete/resource-delete.component'; import { MatDialogModule } from '@angular/material/dialog'; import { TypeHeadlineComponent } from './type-headline/type-headline.component'; -import { UserDialogComponent } from './user-dialog/user-dialog.component'; + +//TODO: PER ORA USIAMO DB IN MEMORY COME MOCK @NgModule({ imports: [ @@ -52,6 +53,8 @@ import { UserDialogComponent } from './user-dialog/user-dialog.component'; ClipboardModule, BrowserAnimationsModule, MatDialogModule, + ResourceAddComponent + // InMemoryWebApiModule.forRoot ], providers: [ Title, @@ -60,9 +63,10 @@ import { UserDialogComponent } from './user-dialog/user-dialog.component'; {provide:HTTP_INTERCEPTORS,useClass:SpinnercontrolInterceptor, multi: true} ], declarations: [MainComponent, NavbarComponent, ErrorComponent, PageRibbonComponent, ActiveMenuDirective, FooterComponent, - ResourceAddComponent, ResourceDeleteComponent, UserDialogComponent], + ResourceDeleteComponent], bootstrap: [MainComponent], }) + export class AppModule { constructor(applicationConfigService: ApplicationConfigService, iconLibrary: FaIconLibrary, dpConfig: NgbDatepickerConfig) { applicationConfigService.setEndpointPrefix(SERVER_API_URL); diff --git a/src/main/webapp/app/dynamic-form/dynamic-form-question.component.html b/src/main/webapp/app/dynamic-form/dynamic-form-question.component.html new file mode 100644 index 0000000..d08baf8 --- /dev/null +++ b/src/main/webapp/app/dynamic-form/dynamic-form-question.component.html @@ -0,0 +1,16 @@ +
+ + +
+ + + + + +
+ +
{{question.label}} is required
+
\ No newline at end of file diff --git a/src/main/webapp/app/dynamic-form/dynamic-form-question.component.scss b/src/main/webapp/app/dynamic-form/dynamic-form-question.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/main/webapp/app/dynamic-form/dynamic-form-question.component.ts b/src/main/webapp/app/dynamic-form/dynamic-form-question.component.ts new file mode 100644 index 0000000..b144bcf --- /dev/null +++ b/src/main/webapp/app/dynamic-form/dynamic-form-question.component.ts @@ -0,0 +1,26 @@ +/* eslint-disable @typescript-eslint/member-ordering */ +/* eslint-disable @angular-eslint/no-empty-lifecycle-method */ +/* eslint-disable @typescript-eslint/no-empty-function */ +import { Component, Input } from '@angular/core'; +import { QuestionBase } from './question-base'; +import { FormGroup, ReactiveFormsModule } from '@angular/forms'; +import { CommonModule } from '@angular/common'; +import { MaterialModule } from 'app/shared/material/material.module'; + +@Component({ + standalone:true, + selector: 'jhi-dynamic-form-question', + templateUrl: './dynamic-form-question.component.html', + styleUrls: ['./dynamic-form-question.component.scss'], + imports:[CommonModule, ReactiveFormsModule,MaterialModule] +}) + +export class DynamicFormQuestionComponent { + + @Input() question!: QuestionBase; + @Input() form!: FormGroup; + get isValid():boolean { + return this.form.controls[this.question.key].valid; + } + +} diff --git a/src/main/webapp/app/dynamic-form/dynamic-form.component.html b/src/main/webapp/app/dynamic-form/dynamic-form.component.html new file mode 100644 index 0000000..bbeb2e9 --- /dev/null +++ b/src/main/webapp/app/dynamic-form/dynamic-form.component.html @@ -0,0 +1,49 @@ + + + + NetworkingFacet (isIdentifiedBy) + + + Description: The network ID characterizing the Hosting Node. + + +

+

+ +
+ +
+ + + +
+ +
+ Saved the following values
{{payLoad}} +
+
+ + + + CPUFacet (consistsOf) + + + Description: The CPU equipping the Hosting Node. + + +

+

+ +
+ +
+ + + +
+ +
+ Saved the following values
{{payLoad}} +
+
+ diff --git a/src/main/webapp/app/dynamic-form/dynamic-form.component.scss b/src/main/webapp/app/dynamic-form/dynamic-form.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/main/webapp/app/dynamic-form/dynamic-form.component.ts b/src/main/webapp/app/dynamic-form/dynamic-form.component.ts new file mode 100644 index 0000000..4ff6c3e --- /dev/null +++ b/src/main/webapp/app/dynamic-form/dynamic-form.component.ts @@ -0,0 +1,41 @@ +/* eslint-disable @typescript-eslint/explicit-function-return-type */ +/* eslint-disable @angular-eslint/no-empty-lifecycle-method */ +/* eslint-disable @typescript-eslint/no-empty-function */ +import { Component, OnInit, Input } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { QuestionControlService } from './question-control.service'; +import { DynamicFormQuestionComponent } from './dynamic-form-question.component'; +import { FormGroup, ReactiveFormsModule } from '@angular/forms'; +import { QuestionBase } from './question-base'; +/* +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatButtonModule } from '@angular/material/button'; +import { MatInputModule } from '@angular/material/input'; +*/ +import { MaterialModule } from 'app/shared/material/material.module'; + +@Component({ + standalone:true, + selector: 'jhi-dynamic-form', + templateUrl: './dynamic-form.component.html', + styleUrls: ['./dynamic-form.component.scss'], + providers: [QuestionControlService], + imports:[CommonModule,DynamicFormQuestionComponent,ReactiveFormsModule,MaterialModule] + }) + +export class DynamicFormComponent implements OnInit { + @Input() questions: QuestionBase[] | null = []; + form!: FormGroup; + payLoad = ''; + + constructor(private qcs: QuestionControlService) {} + + ngOnInit() { + this.form = this.qcs.toFormGroup(this.questions as QuestionBase[]); + } + + onSubmit() { + this.payLoad = JSON.stringify(this.form.getRawValue()); + } + +} diff --git a/src/main/webapp/app/dynamic-form/question-base.ts b/src/main/webapp/app/dynamic-form/question-base.ts new file mode 100644 index 0000000..71c908c --- /dev/null +++ b/src/main/webapp/app/dynamic-form/question-base.ts @@ -0,0 +1,38 @@ +/* eslint-disable @typescript-eslint/prefer-nullish-coalescing */ +export class QuestionBase { + value: T|undefined; + key: string; + label: string; + required: boolean; + order: number; + controlType: string; + type: string; + options: {key: string, value: string}[]; + title: string; + description:string; + + constructor(options: { + value?: T; + key?: string; + label?: string; + required?: boolean; + order?: number; + controlType?: string; + type?: string; + options?: {key: string, value: string}[]; + title?: string; + description?: string; + + } = {}) { + this.value = options.value; + this.key = options.key || ''; + this.label = options.label || ''; + this.required = !!options.required; + this.order = options.order === undefined ? 1 : options.order; + this.controlType = options.controlType || ''; + this.type = options.type || ''; + this.options = options.options || []; + this.title = options.title || ''; + this.description = options.description || ''; + } +} \ No newline at end of file diff --git a/src/main/webapp/app/dynamic-form/question-control.service.ts b/src/main/webapp/app/dynamic-form/question-control.service.ts new file mode 100644 index 0000000..06209e4 --- /dev/null +++ b/src/main/webapp/app/dynamic-form/question-control.service.ts @@ -0,0 +1,25 @@ +/* eslint-disable @typescript-eslint/prefer-nullish-coalescing */ +/* eslint-disable @typescript-eslint/no-empty-function */ +import { Injectable } from '@angular/core'; +import { FormControl, FormGroup, Validators } from '@angular/forms'; +import { QuestionBase } from './question-base'; + +@Injectable({ + providedIn: 'root' +}) + + @Injectable() +export class QuestionControlService { + + constructor() { } + + toFormGroup(questions: QuestionBase[] ): FormGroup { + const group: any = {}; + + questions.forEach(question => { + group[question.key] = question.required ? new FormControl(question.value || '', Validators.required) + : new FormControl(question.value || ''); + }); + return new FormGroup(group); + } +} diff --git a/src/main/webapp/app/dynamic-form/question-dropdown.ts b/src/main/webapp/app/dynamic-form/question-dropdown.ts new file mode 100644 index 0000000..e39c1de --- /dev/null +++ b/src/main/webapp/app/dynamic-form/question-dropdown.ts @@ -0,0 +1,5 @@ +import { QuestionBase } from './question-base'; + +export class DropdownQuestion extends QuestionBase { + override controlType = 'dropdown'; +} \ No newline at end of file diff --git a/src/main/webapp/app/dynamic-form/question-textbox.ts b/src/main/webapp/app/dynamic-form/question-textbox.ts new file mode 100644 index 0000000..4ac0958 --- /dev/null +++ b/src/main/webapp/app/dynamic-form/question-textbox.ts @@ -0,0 +1,5 @@ +import { QuestionBase } from './question-base'; + +export class TextboxQuestion extends QuestionBase { + override controlType = 'textbox'; +} \ No newline at end of file diff --git a/src/main/webapp/app/dynamic-form/question.service.ts b/src/main/webapp/app/dynamic-form/question.service.ts new file mode 100644 index 0000000..ca87e17 --- /dev/null +++ b/src/main/webapp/app/dynamic-form/question.service.ts @@ -0,0 +1,60 @@ +import { Injectable } from '@angular/core'; + +import { QuestionBase } from './question-base'; +import { TextboxQuestion } from './question-textbox'; +import { of } from 'rxjs'; + +@Injectable({ + providedIn: 'root' +}) +export class QuestionService { + + getQuestions(resourceType:string):any { + +// HOSTINGNODE + const questions: QuestionBase[] = [ + + //NETWORKING FACET + new TextboxQuestion({ + key: 'hostNode', + label: 'Host Node', + value: '', + required: true, + order: 1 + }), + + new TextboxQuestion({ + key: 'domainName', + label: 'domain name', + order: 2 + }), + + new TextboxQuestion({ + key: 'Port', + label: 'Port', + type: 'number', //'text', 'email', 'password', 'number', 'date', etc., which corresponds to the types of HTML input elements. + order: 3 + }), + + new TextboxQuestion({ + key: 'IPAddress', + label: 'IP Address', + order: 4 + }), + new TextboxQuestion({ + key: 'mask', + label: 'mask', + order: 5 + }), + new TextboxQuestion({ + key: 'broadcastAddress', + label: 'broadcast address', + order: 6 + }), + + ]; + + //questo è un observable + return of(questions.sort((a, b) => a.order - b.order)); + } +} \ No newline at end of file diff --git a/src/main/webapp/app/home/home.module.ts b/src/main/webapp/app/home/home.module.ts index 2dec23b..ed1f0d0 100644 --- a/src/main/webapp/app/home/home.module.ts +++ b/src/main/webapp/app/home/home.module.ts @@ -11,11 +11,11 @@ import { ClipboardModule } from '@angular/cdk/clipboard'; import { MatTabsModule } from '@angular/material/tabs'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { MatSelectFilterModule } from 'mat-select-filter'; -import { TableScreenModule } from 'app/table-screen/table-screen.module'; import { TableScreenEsModule } from 'app/table-screen-es/table-screen-es.module'; import { AsyncPipe, NgSwitchCase, NgSwitchDefault } from '@angular/common'; import { MatProgressBarModule } from '@angular/material/progress-bar'; import { TypeHeadlineModule } from 'app/type-headline/type-headline.module'; +import { TableScreenModule } from 'app/table-screen/table-screen.module'; @NgModule({ diff --git a/src/main/webapp/app/model/resource.ts b/src/main/webapp/app/model/resource.ts new file mode 100644 index 0000000..146d96e --- /dev/null +++ b/src/main/webapp/app/model/resource.ts @@ -0,0 +1,5 @@ +export interface Resource { + uid: string; + type: string; + name: string; +} \ No newline at end of file diff --git a/src/main/webapp/app/resource-add/resource-add.component.html b/src/main/webapp/app/resource-add/resource-add.component.html index 97ad35d..1827d18 100644 --- a/src/main/webapp/app/resource-add/resource-add.component.html +++ b/src/main/webapp/app/resource-add/resource-add.component.html @@ -1,8 +1,27 @@ -
-

Tipo: {{data.type.name}}

-

Contesto: {{data.context.path}}

-
+

New {{titleType}} ({{titlePath}})

+ + + +

Name: + + + +

+

UUID: + + + +

+
- - - \ No newline at end of file + + + + diff --git a/src/main/webapp/app/resource-add/resource-add.component.spec.ts b/src/main/webapp/app/resource-add/resource-add.component.spec.ts deleted file mode 100644 index 7897594..0000000 --- a/src/main/webapp/app/resource-add/resource-add.component.spec.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { ResourceAddComponent } from './resource-add.component'; - -describe('ResourceAddComponent', () => { - let component: ResourceAddComponent; - let fixture: ComponentFixture; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - declarations: [ ResourceAddComponent ] - }) - .compileComponents(); - - fixture = TestBed.createComponent(ResourceAddComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/src/main/webapp/app/resource-add/resource-add.component.ts b/src/main/webapp/app/resource-add/resource-add.component.ts index f711d61..88baa64 100644 --- a/src/main/webapp/app/resource-add/resource-add.component.ts +++ b/src/main/webapp/app/resource-add/resource-add.component.ts @@ -1,19 +1,64 @@ -import { Component, Inject } from '@angular/core'; -import {MAT_DIALOG_DATA} from '@angular/material/dialog'; +/* eslint-disable @typescript-eslint/no-unnecessary-condition */ +/* eslint-disable no-console */ +import { CommonModule } from '@angular/common'; +import { Component, Inject, OnInit } from '@angular/core'; +import { FormBuilder, FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms'; +import { MatButtonModule } from '@angular/material/button'; +import {MAT_DIALOG_DATA, MAT_DIALOG_DEFAULT_OPTIONS, MatDialogModule, MatDialogRef} from '@angular/material/dialog'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatInputModule } from '@angular/material/input'; +import { Resource } from 'app/model/resource'; import { IContextNode } from 'app/services/i-context-node'; import { IResource } from 'app/services/i-resource'; @Component({ + standalone:true, selector: 'jhi-resource-add', templateUrl: './resource-add.component.html', styleUrls: ['./resource-add.component.scss'], + imports:[CommonModule,MatFormFieldModule, + ReactiveFormsModule,MatButtonModule, + MatDialogModule,MatInputModule], }) +// Dialog creazione risorsa -export class ResourceAddComponent { +export class ResourceAddComponent implements OnInit { + + form: FormGroup | any; + titleType:string | any; + titlePath:string | any; + myModel:Resource | any; + + constructor( + private fb: FormBuilder, + private dialogRef:MatDialogRef, + @Inject(MAT_DIALOG_DATA) data: {type: IResource,myObject: Resource ,context:IContextNode}){ + //TODO: cambiare questo + this.titleType = data.type.name; + this.titlePath = data.context.path; + //TODO: check this + this.myModel = data.myObject; + } ; + - // eslint-disable-next-line @typescript-eslint/no-empty-function - constructor(@Inject(MAT_DIALOG_DATA) public data: {type: IResource,context:IContextNode}) { } - - -} \ No newline at end of file + ngOnInit():void { + //IMPORTANTE: I NOMI DELLE FORMCONTROL DEVONO CORRISPONDERE A QUELLI DEI CAMPI NELL'OGGETTO MAPPATO + this.form = this.fb.group({ + type: new FormControl({ value:this.titleType,disabled: true}), + name: new FormControl({ value:'',disabled: false }), + uid: new FormControl({ value:'',disabled: false }), + }); + } + + //chiude e passa i dati al component chiamante + doAction():void { + this.dialogRef.close({event:'add',data:this.form.value}); + } + + //chiude e basta + close():void { + this.dialogRef.close({event:'cancel'}); + } + +} diff --git a/src/main/webapp/app/resource-add/resource-add.module.ts b/src/main/webapp/app/resource-add/resource-add.module.ts deleted file mode 100644 index f1d032e..0000000 --- a/src/main/webapp/app/resource-add/resource-add.module.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { NgModule } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { MatFormFieldModule } from '@angular/material/form-field'; -import { MatInputModule } from '@angular/material/input'; -import { FormsModule } from '@angular/forms'; -import { MatButtonModule } from '@angular/material/button'; - - -@NgModule({ - imports: [ - CommonModule, - MatFormFieldModule, - MatInputModule, - FormsModule, - MatButtonModule, - ], -}) - -export class ResourceAddModule { - - - -} diff --git a/src/main/webapp/app/services/dummy.service.ts b/src/main/webapp/app/services/dummy.service.ts new file mode 100644 index 0000000..ba8d19b --- /dev/null +++ b/src/main/webapp/app/services/dummy.service.ts @@ -0,0 +1,80 @@ +/* eslint-disable @typescript-eslint/no-inferrable-types */ +/* eslint-disable @typescript-eslint/no-empty-function */ +/* eslint-disable @typescript-eslint/explicit-function-return-type */ +/* eslint-disable no-console */ +import { Injectable } from '@angular/core'; +import { InMemoryDbService, RequestInfo } from 'angular-in-memory-web-api'; +import { Observable } from 'rxjs'; +import { HttpClient } from '@angular/common/http'; +import { Resource } from 'app/model/resource'; +/* +import { Observable, catchError, map, throwError } from 'rxjs'; +import { HttpClient, HttpHeaders } from '@angular/common/http'; +import { ApplicationConfigService } from 'app/core/config/application-config.service'; +import { Resource } from 'app/model/resource'; +*/ + +@Injectable({ + providedIn: 'root' +}) + +export class DummyService implements InMemoryDbService { + + SERVER_URL: string = "dummyservice/api/"; + + createDb() { + const resources = [ + { uid: 1, type:'HostingNode',name: 'HostingNode One', }, + { uid: 2, type:'HostingNode',name: 'HostingNode Two', }, + { uid: 3, type:'HostingNode',name: 'HostingNode Three', } + ]; + return { resources }; + } + + + // eslint-disable-next-line @typescript-eslint/member-ordering + constructor(private httpClient: HttpClient) { } + + public getDummies():Observable{ + return this.httpClient.get(this.SERVER_URL + 'resources'); + } + + public getDummy(uid:string):Observable{ + return this.httpClient.get(`${this.SERVER_URL + 'resources'}/${uid}`); + } + public createDummy(dummy: Resource){ + return this.httpClient.post(`${this.SERVER_URL + 'resources'}`, dummy) + } + + public deleteDummy(uid:string){ + return this.httpClient.delete(`${this.SERVER_URL + 'resources'}/${uid}`) + } + public updateDummy(dummy: Resource):Observable{ + return this.httpClient.put(`${this.SERVER_URL + 'resources'}/${dummy.uid}`, dummy) + } + +} + +/* + +httpOptions = { + headers: new HttpHeaders({ 'Content-Type': 'application/json' }) + }; + + constructor(private http: HttpClient) { } + + getEmployeePositions(): Observable { + return this.http.get(this.positionsUrl).pipe( + tap(_ => this.log('fetched positions')), + catchError(this.handleError('getEmployeePositions', [])) + ); + } + + addEmployeePosition(position: employeePosition): Observable { + return this.http.post(this.positionsUrl, position, this.httpOptions).pipe( + tap((newPosition: employeePosition) => this.log(`added position with id=${newPosition}`)), + catchError(this.handleError('addEmployeePosition')) + ); + } + + */ diff --git a/src/main/webapp/app/services/hnSample.json b/src/main/webapp/app/services/hnSample.json new file mode 100644 index 0000000..ca3ad0b --- /dev/null +++ b/src/main/webapp/app/services/hnSample.json @@ -0,0 +1,485 @@ +{ + "type": "HostingNode", + "supertypes": [ + "Service", + "GCubeResource", + "Resource" + ], + "id": "34498fb5-e184-473b-ad2f-08f7ab1afd35", + "consistsOf": [ + { + "type": "HasPersistentMemory", + "supertypes": [ + "HasMemory", + "ConsistsOf" + ], + "id": "950c9212-d98e-4137-b1ba-dd2c4017785e", + "propagationConstraint": { + "type": "PropagationConstraint", + "add": "propagate", + "delete": "cascade", + "remove": "cascade", + "supertypes": [ + "Property" + ] + }, + "target": { + "type": "MemoryFacet", + "supertypes": [ + "Facet" + ], + "id": "38f4c88b-d18b-4309-82f9-c1fc436fddd5", + "unit": "MB", + "size": "12278", + "used": "6378", + "message": "Unable to detect disk space information." + } + }, + { + "type": "IsIdentifiedBy", + "supertypes": [ + "ConsistsOf" + ], + "id": "2a52dc4b-a997-4b0e-aae1-d43175269ab2", + "propagationConstraint": { + "type": "PropagationConstraint", + "add": "propagate", + "delete": "cascade", + "remove": "cascade", + "supertypes": [ + "Property" + ] + }, + "target": { + "type": "NetworkingFacet", + "supertypes": [ + "Facet" + ], + "id": "124967c5-e1c6-4c27-877d-18d564e57c43", + "hostName": "storagehub2.dev.int.d4science.net", + "domainName": "dev.int.d4science.net", + "Port": "80", + "IPAddress": "10.122.0.166", + "mask": null, + "broadcastAddress": null + } + }, + { + "type": "ConsistsOf", + "id": "9c005448-1b18-4477-b799-49d167ad4c47", + "propagationConstraint": { + "type": "PropagationConstraint", + "add": "propagate", + "delete": "cascade", + "remove": "cascade", + "supertypes": [ + "Property" + ] + }, + "target": { + "type": "CPUFacet", + "supertypes": [ + "Facet" + ], + "id": "6b6db989-cffc-4872-bf60-e51c789d1826", + "siblings": "2", + "apicid": "18", + "physical_id": "0", + "flags": "fpu de tsc msr pae cx8 apic sep cmov pat clflush mmx fxsr sse sse2 ss ht syscall nx lm constant_tsc rep_good nopl cpuid pni pclmulqdq ssse3 sdbg cx16 sse4_1 sse4_2 movbe popcnt tsc_deadline_timer aes f16c rdrand hypervisor lahf_lm abm 3dnowprefetch cpuid_fault epb fsgsbase erms dtherm ida arat pln pts", + "clflush_size": "64", + "stepping": "1", + "bogomips": "4395.04", + "address_sizes": "46 bits physical, 48 bits virtual", + "bugs": "null_seg cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass l1tf", + "cpu_family": "6", + "core_id": "9", + "clockSpeed": "2197.522", + "vendor": "GenuineIntel", + "wp": "yes", + "model": "Intel(R) Xeon(R) CPU E5-2650 v4 @ 2.20GHz", + "initial_apicid": "18", + "cache_size": "30720 KB", + "cpuid_level": "20", + "cpu_cores": "1", + "fpu": "yes", + "microcode": "0xb00001e", + "processor": "0", + "cache_alignment": "64", + "fpu_exception": "yes", + "modelNumber": "79" + } + }, + { + "type": "ConsistsOf", + "id": "93d9fa8d-ae0c-4393-9020-3e1243a8c65d", + "propagationConstraint": { + "type": "PropagationConstraint", + "add": "propagate", + "delete": "cascade", + "remove": "cascade", + "supertypes": [ + "Property" + ] + }, + "target": { + "type": "CPUFacet", + "supertypes": [ + "Facet" + ], + "id": "b15df23e-04fe-4528-97ae-f4d729a0c8e4", + "siblings": "2", + "apicid": "18", + "physical_id": "0", + "flags": "fpu de tsc msr pae cx8 apic sep cmov pat clflush mmx fxsr sse sse2 ss ht syscall nx lm constant_tsc rep_good nopl cpuid pni pclmulqdq ssse3 sdbg cx16 sse4_1 sse4_2 movbe popcnt tsc_deadline_timer aes f16c rdrand hypervisor lahf_lm abm 3dnowprefetch cpuid_fault epb fsgsbase erms dtherm ida arat pln pts", + "clflush_size": "64", + "stepping": "1", + "bogomips": "4395.04", + "address_sizes": "46 bits physical, 48 bits virtual", + "bugs": "null_seg cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass l1tf", + "cpu_family": "6", + "core_id": "9", + "clockSpeed": "2197.522", + "vendor": "GenuineIntel", + "wp": "yes", + "model": "Intel(R) Xeon(R) CPU E5-2650 v4 @ 2.20GHz", + "initial_apicid": "18", + "cache_size": "30720 KB", + "cpuid_level": "20", + "cpu_cores": "1", + "fpu": "yes", + "microcode": "0xb00001e", + "processor": "1", + "cache_alignment": "64", + "fpu_exception": "yes", + "modelNumber": "79" + } + }, + { + "type": "ConsistsOf", + "id": "89de1226-e7b1-4b08-a26e-46a13b551c57", + "propagationConstraint": { + "type": "PropagationConstraint", + "add": "propagate", + "delete": "cascade", + "remove": "cascade", + "supertypes": [ + "Property" + ] + }, + "target": { + "type": "SoftwareFacet", + "supertypes": [ + "Facet" + ], + "id": "56c5e755-0631-4419-8362-e961e6b91743", + "Description": "Ubuntu 18.04.5 LTS", + "description": null, + "optional": false, + "version": "4.15.0-38-generic", + "Codename": "bionic", + "qualifier": null, + "name": "amd64", + "Distributor ID": "Ubuntu", + "Release": "18.04", + "group": "Linux" + } + }, + { + "type": "ConsistsOf", + "id": "6a91074f-8ff1-4284-a1f1-5feeb1418782", + "propagationConstraint": { + "type": "PropagationConstraint", + "add": "propagate", + "delete": "cascade", + "remove": "cascade", + "supertypes": [ + "Property" + ] + }, + "target": { + "type": "SoftwareFacet", + "supertypes": [ + "Facet" + ], + "id": "e57f33ef-89e0-4de1-a3f2-79963eb6aff9", + "qualifier": null, + "name": "SmartGears", + "description": null, + "optional": false, + "version": "4.0.0-SNAPSHOT", + "group": "gCube" + } + }, + { + "type": "ConsistsOf", + "id": "9a95cb44-7d5b-40ae-99ed-fc29bed014a4", + "propagationConstraint": { + "type": "PropagationConstraint", + "add": "propagate", + "delete": "cascade", + "remove": "cascade", + "supertypes": [ + "Property" + ] + }, + "target": { + "type": "SoftwareFacet", + "supertypes": [ + "Facet" + ], + "id": "c4e55779-7e85-46af-8ca5-bfe0f718660a", + "qualifier": null, + "name": "SmartGearsDistribution", + "description": null, + "optional": false, + "version": "4.0.0-SNAPSHOT", + "group": "gCube", + "publication-frequency": "300" + } + }, + { + "type": "ConsistsOf", + "id": "6c7b85f6-b438-4745-ace3-81cd9285bbee", + "propagationConstraint": { + "type": "PropagationConstraint", + "add": "propagate", + "delete": "cascade", + "remove": "cascade", + "supertypes": [ + "Property" + ] + }, + "target": { + "type": "SoftwareFacet", + "supertypes": [ + "Facet" + ], + "id": "cc566b3c-06b5-4fb7-90aa-7770a943c3a5", + "java.specification.version": "11", + "description": null, + "optional": false, + "version": "11.0.18", + "java.vendor.url": "https://ubuntu.com/", + "qualifier": null, + "name": "Java", + "group": "Ubuntu" + } + }, + { + "type": "ConsistsOf", + "id": "7e188a04-baa5-4ac1-a46a-1e42970667a0", + "propagationConstraint": { + "type": "PropagationConstraint", + "add": "propagate", + "delete": "cascade", + "remove": "cascade", + "supertypes": [ + "Property" + ] + }, + "target": { + "type": "SimplePropertyFacet", + "supertypes": [ + "Facet" + ], + "id": "fdcdba83-1392-431b-bc70-bb268904a8ca", + "TOMCAT_USER": "gcube", + "INVOCATION_ID": "776b2c3c50234e9eb059af65c692645c", + "CATALINA_PID": "/var/run/tomcat-instance-8080.pid", + "CATALINA_TMPDIR": "/tomcat/temp", + "JAVA_HOME": "/usr/lib/jvm/java-11-openjdk-amd64", + "LC_MESSAGES": "C.UTF-8", + "JAVA_OPTS": "-XX:+UseConcMarkSweepGC -XX:+CrashOnOutOfMemoryError -server -Djava.awt.headless=true -Dfile.encoding=UTF-8 -Xms3000m -Xmx3000m -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=8186 -Dcom.sun.management.jmxremote.ssl=false -Djava.rmi.server.hostname=10.122.0.166 -Dcom.sun.management.jmxremote.authenticate=false -XX:+DisableAttachMechanism -Dcom.sun.management.jmxremote.rmi.port=8186 -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dorg.apache.catalina.security.SecurityListener.UMASK=0027", + "JSSE_HOME": "", + "LANG": "", + "JVM_TMP": "/tomcat/temp/jvm_tmp", + "WEB_CONTAINER_HOME": "/home/gcube/tomcat", + "CATALINA_BASE": "/home/gcube/tomcat", + "JOURNAL_STREAM": "9:121955156", + "PWD": "/home/gcube/tomcat", + "value": "", + "SmartGearsDistributionBundle": "UnBundled", + "TOMCAT_GROUP": "gcube", + "CATALINA_HOME": "/usr/share/tomcat8", + "JDK_JAVA_OPTIONS": " --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED", + "OLDPWD": "/tomcat/temp", + "name": "ENVIRONMENT_VARIABLES", + "SmartGearsDistribution": "4.0.0-SNAPSHOT", + "JAVA_HEAP": "-Xms3000m -Xmx3000m", + "GHN_HOME": "/home/gcube/SmartGears", + "JAVA_PERMGEN": "", + "HOME": "/home/gcube", + "SHLVL": "1" + } + }, + { + "type": "ConsistsOf", + "id": "eac90912-ae1b-4ff8-86f0-a44c2aed673c", + "propagationConstraint": { + "type": "PropagationConstraint", + "add": "propagate", + "delete": "cascade", + "remove": "cascade", + "supertypes": [ + "Property" + ] + }, + "target": { + "type": "StateFacet", + "supertypes": [ + "Facet" + ], + "id": "b0f10d58-25d9-4022-a264-ca5c2f888f91", + "date": "2024-01-29 13:06:07.981 +0100", + "value": "certified" + } + }, + { + "type": "ConsistsOf", + "id": "7c68bc64-bb54-41bc-a0f8-14e7a0c85443", + "propagationConstraint": { + "type": "PropagationConstraint", + "add": "propagate", + "delete": "cascade", + "remove": "cascade", + "supertypes": [ + "Property" + ] + }, + "target": { + "type": "EventFacet", + "supertypes": [ + "Facet" + ], + "id": "a243ddd3-8ac5-4097-8568-813f76143f66", + "date": "2024-01-29 13:06:07.981 +0100", + "event": "certified" + } + }, + { + "type": "ConsistsOf", + "id": "cd03d1da-f8d4-455a-b086-1039456ab515", + "propagationConstraint": { + "type": "PropagationConstraint", + "add": "propagate", + "delete": "cascade", + "remove": "cascade", + "supertypes": [ + "Property" + ] + }, + "target": { + "type": "LocationFacet", + "supertypes": [ + "Facet" + ], + "id": "e3db10ef-a9ca-4cd1-8cd0-985bb82497ec", + "country": "it", + "latitude": null, + "location": "rome", + "longitude": null + } + }, + { + "type": "ConsistsOf", + "id": "9ea0a9fc-abe9-423c-8c41-b89b0926007c", + "propagationConstraint": { + "type": "PropagationConstraint", + "add": "propagate", + "delete": "cascade", + "remove": "cascade", + "supertypes": [ + "Property" + ] + }, + "target": { + "type": "EventFacet", + "supertypes": [ + "Facet" + ], + "id": "a7a69c32-4c8a-46f2-8fdc-321d96e51f0d", + "date": "2024-01-26 09:50:57.514 +0100", + "event": "down" + } + }, + { + "type": "ConsistsOf", + "id": "8d618031-0c51-4243-befd-dc0427d26dfc", + "propagationConstraint": { + "type": "PropagationConstraint", + "add": "propagate", + "delete": "cascade", + "remove": "cascade", + "supertypes": [ + "Property" + ] + }, + "target": { + "type": "EventFacet", + "supertypes": [ + "Facet" + ], + "id": "cf7436e2-bf58-46c0-8d65-c59a8308cf05", + "date": "2024-01-26 09:50:47.054 +0100", + "event": "ready" + } + }, + { + "type": "HasVolatileMemory", + "supertypes": [ + "HasMemory", + "ConsistsOf" + ], + "id": "a1f4d155-4688-4426-aa03-dc2a3cd834ec", + "propagationConstraint": { + "type": "PropagationConstraint", + "add": "propagate", + "delete": "cascade", + "remove": "cascade", + "supertypes": [ + "Property" + ] + }, + "memoryType": "RAM", + "target": { + "type": "MemoryFacet", + "supertypes": [ + "Facet" + ], + "id": "ff63f5b7-f58b-4110-8208-b2060fa6f728", + "unit": "MB", + "size": "5860", + "used": "2082" + } + }, + { + "type": "HasVolatileMemory", + "supertypes": [ + "HasMemory", + "ConsistsOf" + ], + "id": "9cb50edd-5ae0-4f2e-bc34-bd99c8d0572e", + "propagationConstraint": { + "type": "PropagationConstraint", + "add": "propagate", + "delete": "cascade", + "remove": "cascade", + "supertypes": [ + "Property" + ] + }, + "memoryType": "JVM", + "target": { + "type": "MemoryFacet", + "supertypes": [ + "Facet" + ], + "id": "69629225-1a54-4f0f-aebc-54465b3a5660", + "unit": "MB", + "size": "2983", + "used": "96", + "jvmMaxMemory": "2983" + } + } + ] +} \ No newline at end of file diff --git a/src/main/webapp/app/services/hnodes.ts b/src/main/webapp/app/services/hnodes.ts deleted file mode 100644 index 486f65f..0000000 --- a/src/main/webapp/app/services/hnodes.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { IHostingNode } from "./i-hosting-node"; - -export const HNODES: IHostingNode[] = [{ - "type": "Hosting Node", - "id": "id-ckan", - "name": "ckan-d-d4s.d4science.org", - "status": "certified", - "lastmod": "Tue Jul 25 10:20:17 GMT 2023", - "memavailable": "1% (137 MB)", - "hdspace": "59 MB" -}, { - "type": "Hosting Node", - "id": "id-geoportal", - "name": "geoportal.dev.int.d4science.net", - "status": "certified", - "lastmod": "Tue Jul 25 10:19:35 GMT 2023", - "memavailable": "0% (18 MB)", - "hdspace": "5 MB" -}, { - "type": "Hosting Node", - "id": "id-dataminer2", - "name": "dataminer2.dev.int.d4science.net", - "status": "certified", - "lastmod": "Tue Jul 25 10:20:17 GMT 2023", - "memavailable": "5% (430 MB)", - "hdspace": "21 MB" -}, { - "type": "Hosting Node", - "id":"id-dataminer1", - "name": "dataminer1.dev.d4science.org", - "status": "certified", - "lastmod": "Tue Jul 25 10:20:18 GMT 2023", - "memavailable": "41% (2.035 MB)", - "hdspace": "8 MB" -}] \ No newline at end of file diff --git a/src/main/webapp/app/services/resources-crud.service.ts b/src/main/webapp/app/services/resources-crud.service.ts deleted file mode 100644 index d445b95..0000000 --- a/src/main/webapp/app/services/resources-crud.service.ts +++ /dev/null @@ -1,10 +0,0 @@ -/* eslint-disable @typescript-eslint/no-empty-function */ -import { Injectable } from '@angular/core'; - -@Injectable({ - providedIn: 'root' -}) -export class ResourcesCrudService { - - constructor() { } -} diff --git a/src/main/webapp/app/services/resources-impl.service.ts b/src/main/webapp/app/services/resources-impl.service.ts index 1ac272a..01472b9 100644 --- a/src/main/webapp/app/services/resources-impl.service.ts +++ b/src/main/webapp/app/services/resources-impl.service.ts @@ -1,10 +1,12 @@ +/* eslint-disable @typescript-eslint/explicit-function-return-type */ /* eslint-disable no-console */ import { Injectable } from '@angular/core'; -import { BehaviorSubject, Observable, Subject } from 'rxjs'; +import { BehaviorSubject, Observable, Subject, catchError, map, throwError } from 'rxjs'; import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http'; import { IHostingNode } from './i-hosting-node'; import { IEService } from './i-e-service'; import { ApplicationConfigService } from 'app/core/config/application-config.service'; +import { Resource } from 'app/model/resource'; @Injectable({ providedIn: 'root' @@ -24,7 +26,7 @@ export class ResourcesImplService { return this.loading; } - //TODO: paginate when APIs are ready + //TODO: paginate (when pagination APIs will be ready) fetchResourceImpls(ctxPath:string, type:string): Observable { const resourceUrl = this.applicationConfigService.getEndpointFor('api/is/resourceinstances'); let queryParams = new HttpParams(); @@ -49,5 +51,5 @@ export class ResourcesImplService { queryParams = queryParams.append("currentContext",ctx).append("resourceType",type).append("uid",uid); return this.http.get(resourceUrl,{params:queryParams}); } - + } diff --git a/src/main/webapp/app/shared/shared.module.ts b/src/main/webapp/app/shared/shared.module.ts index c394836..39b082d 100644 --- a/src/main/webapp/app/shared/shared.module.ts +++ b/src/main/webapp/app/shared/shared.module.ts @@ -17,6 +17,8 @@ import { ContextTransformPipe } from './pipe/contexttransform.pipe'; import { NgbPagination, NgbTypeahead } from '@ng-bootstrap/ng-bootstrap'; //import { SortableDirective } from 'app/table-nodes/sortable.directive'; import { MaterialModule } from './material/material.module'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { FormArray, FormBuilder, FormGroup } from '@angular/forms'; @NgModule({ //imports: [SharedLibsModule,SortableDirective], @@ -35,7 +37,7 @@ import { MaterialModule } from './material/material.module'; ItemCountComponent, FilterComponent, ContextTransformPipe, - + // ], exports: [ SharedLibsModule, @@ -55,7 +57,8 @@ import { MaterialModule } from './material/material.module'; NgbPagination, NgbTypeahead, /*SortableDirective,*/ - MaterialModule + MaterialModule, + MatFormFieldModule, ], }) export class SharedModule {} diff --git a/src/main/webapp/app/table-screen/table-screen.component.html b/src/main/webapp/app/table-screen/table-screen.component.html index 26a5776..7f6c648 100644 --- a/src/main/webapp/app/table-screen/table-screen.component.html +++ b/src/main/webapp/app/table-screen/table-screen.component.html @@ -1,5 +1,4 @@
-
Search by Name @@ -11,15 +10,30 @@ -
+
+ + +------- +

Form da dialog:

+
    +
  • + Id: {{dm.uid}}, Name: {{dm.name}}, Type: {{dm.type}} +
  • +
+------- + + +
diff --git a/src/main/webapp/app/table-screen/table-screen.component.ts b/src/main/webapp/app/table-screen/table-screen.component.ts index 576848c..98712ca 100644 --- a/src/main/webapp/app/table-screen/table-screen.component.ts +++ b/src/main/webapp/app/table-screen/table-screen.component.ts @@ -25,17 +25,21 @@ import { ITabbedEntity } from 'app/i-tabbed-entity'; import { IHostingNode } from 'app/services/i-hosting-node'; import { ResourcesImplService } from 'app/services/resources-impl.service'; import { ResourceAddComponent } from 'app/resource-add/resource-add.component'; -import { GenericInfoComponent } from 'app/generic-info/generic-info.component'; import { IResource } from 'app/services/i-resource'; import { IResourceType } from 'app/services/i-resource-type'; -import { GenericJsonComponent } from 'app/generic-json/generic-json.component'; +import { DummyService } from 'app/services/dummy.service'; +import { Resource } from 'app/model/resource'; +import { MatFormFieldControl } from '@angular/material/form-field'; +import { Router } from '@angular/router'; @Component({ selector: 'jhi-table-screen', templateUrl: './table-screen.component.html', styleUrls: ['./table-screen.component.scss'], - providers: [ResourcesImplService], + //NB->dialog form is a provider + providers: [{provide:MatFormFieldControl,useExisting:ResourceAddComponent}, + ResourcesImplService, DummyService], }) export class TableScreenComponent implements OnInit, AfterViewInit, OnChanges { @@ -45,8 +49,8 @@ export class TableScreenComponent implements OnInit, AfterViewInit, OnChanges { dataSource = new MatTableDataSource(); tableDetail: IHostingNode; dialogAddRef: MatDialogRef |undefined; - dialogInfoRef: MatDialogRef |undefined; - dialogJsonRef: MatDialogRef |undefined; + //dialog di test per creazione risorse + errorMessage = ''; @Input() currentCtx: IContextNode; //fetching event from parent @Input() currentCtxPath: string; //fetching event from parent @@ -64,12 +68,16 @@ export class TableScreenComponent implements OnInit, AfterViewInit, OnChanges { public tabs: ITabbedEntity[] = [{ title: 'JSON View', content: '', type: 0, id: '' }]; selectedIdx = 0; chosenIds: string[] = []; - //TODO: a regime questa sarà la nuova resource creata (visualizzerò il titolo) rawJson: string; - dummyRes :string; - ////////// fine tabbed view + ////////// fine tabbed view + //TODO: a regime questa sarà la nuova resource creata (visualizzerò il titolo) + dummyResource :Resource; + dummies : Resource[]; - constructor(private myDataService: ResourcesImplService, private myDialog: MatDialog) { + constructor(private myDataService: ResourcesImplService, + private myDialog: MatDialog, + private router:Router + ) { this.currentCtx = {} as IContextNode; this.tableDetail = {} as IHostingNode; this.dataFromService = []; @@ -79,7 +87,8 @@ export class TableScreenComponent implements OnInit, AfterViewInit, OnChanges { this.typeObject = {} as IResourceType; this.currentCtxPath = ''; this.rawJson = ''; - this.dummyRes = ''; + this.dummyResource = {} as Resource; + this.dummies = []; } ngAfterViewInit(): void { @@ -104,8 +113,13 @@ export class TableScreenComponent implements OnInit, AfterViewInit, OnChanges { return record.name.indexOf(filter)!==-1; } }); - - + //this.fetchDummies(); + /* + this.dialogAddRef?.afterClosed().subscribe(res=>{ + this.dummyRes = res;} + ); + */ + } @@ -178,40 +192,71 @@ export class TableScreenComponent implements OnInit, AfterViewInit, OnChanges { const dialogConfig = new MatDialogConfig(); dialogConfig.disableClose = true; dialogConfig.autoFocus = true; + dialogConfig.data= {type: this.typeObject, myObject: this.dummyResource, context: this.currentCtx}; + //questa qua sotto serve? + this.myDialog.open(ResourceAddComponent,dialogConfig); - this.dialogAddRef = this.myDialog.open(ResourceAddComponent, { - //TODO: passare tipo e contesto - data: {type: this.typeObject, context: this.currentCtx}, + const dialogRef = this.myDialog.open(ResourceAddComponent,dialogConfig); + + dialogRef.afterClosed().subscribe(result => { + if(result.event === 'add'){ + this.addNewData(result.data); + }else if(result.event ==='update'){ + //TODO + //this.updateRowData(result.data); + }else if(result.event === 'delete'){ + //TODO + // this.deleteRowData(result.data); + } }); } - openDialogTest(): void { + openDialogTest(): void { const dialogConfig = new MatDialogConfig(); dialogConfig.disableClose = true; dialogConfig.autoFocus = true; + dialogConfig.data= {type: this.typeObject, myObject: this.dummyResource, context: this.currentCtx}; + //questa qua sotto serve? + this.myDialog.open(ResourceAddComponent,dialogConfig); - this.dialogAddRef = this.myDialog.open(ResourceAddComponent, { - //TODO: passare tipo e contesto - data: {type: this.typeObject, context: this.currentCtx}, + const dialogRef = this.myDialog.open(ResourceAddComponent,dialogConfig); + + dialogRef.afterClosed().subscribe(result => { + if(result.event === 'add'){ + this.addNewData(result.data); + }else if(result.event ==='update'){ + //TODO + //this.updateRowData(result.data); + }else if(result.event === 'delete'){ + //TODO + // this.deleteRowData(result.data); + } }); } - openDialogDescription(): void { - this.dialogInfoRef = this.myDialog.open(GenericInfoComponent, { - data: {description: this.typeObject.description} - }); - } - openDialogJson(): void { - this.dialogJsonRef = this.myDialog.open(GenericJsonComponent, { - data: {type: this.typeObject.name} - }); - } + - - /* - emitDataItem(node: IHostingNode):void { - this.jsonEmitter.emit(node); + //TODO: cambiare qui per mettere timestamp a uuid (e visualizzare oggetto nuovo) + addNewData(data: any):void{ + const rsc = {} as Resource; + rsc.type = this.typeObject.name; + rsc.uid = data.uid; + rsc.name = data.name; + this.dummies.push(rsc); + } + + updateData(uid: string, data:any):void{ + //TODO: recupera resource con uid passato come parametro e type=this.typeObject.name + //TODO: chiama il metodo delle API per fare la update + const rsc = {} as Resource; + rsc.type = this.typeObject.name; + rsc.uid = data.uid; + rsc.name = data.name; + this.dummies.push(rsc); + } + + removeData(uid: string):void{ + //TODO: chiama il metodo delle API per fare la remove + } + } - */ - -} diff --git a/src/main/webapp/app/table-screen/table-screen.module.ts b/src/main/webapp/app/table-screen/table-screen.module.ts index f756a80..58463f5 100644 --- a/src/main/webapp/app/table-screen/table-screen.module.ts +++ b/src/main/webapp/app/table-screen/table-screen.module.ts @@ -9,15 +9,19 @@ import { RawjsonPaneComponent } from 'app/rawjson-pane/rawjson-pane.component'; import { MAT_DIALOG_DEFAULT_OPTIONS, MatDialogModule } from '@angular/material/dialog'; import { ResourceAddComponent } from 'app/resource-add/resource-add.component'; import { TypeHeadlineModule } from 'app/type-headline/type-headline.module'; +import { AsyncPipe } from '@angular/common'; +import { DynamicFormComponent } from 'app/dynamic-form/dynamic-form.component'; +import { RouterModule } from '@angular/router'; @NgModule({ imports: [ SharedModule,MatTableModule,MatIconModule,MatSortModule, MatPaginatorModule, MatDialogModule, RawjsonPaneComponent, - TypeHeadlineModule + TypeHeadlineModule, AsyncPipe, RouterModule, DynamicFormComponent ], declarations:[TableScreenComponent], - exports: [TableScreenComponent,], + exports: [TableScreenComponent], + //NB: QUI VA DICHIARATO IL DIALOG DI DATAENTRY COME COMPONENT entryComponents: [ResourceAddComponent], bootstrap: [TableScreenComponent], /*