Fully resource agnostic jsonschemas interpreter

This commit is contained in:
2023-01-18 16:04:01 +01:00
parent 6ccbb8ac00
commit 15f101eb9f
4 changed files with 114 additions and 31 deletions

View File

@@ -6,6 +6,7 @@ import { Router } from '@angular/router';
import { CrudService } from '../crud.service'
import {BehaviorSubject} from "rxjs";
import {JsonschemasService} from "../jsonschemas.service";
export interface Model {
email: string;
@@ -32,45 +33,44 @@ export class CardComponent implements OnInit {
}
constructor(private crudService: CrudService,
private jsonSchemasService: JsonschemasService,
private formlyJsonschema: FormlyJsonschema,
private router: Router
) { }
ngOnInit(): void {
this._loading$.next(true);
this.crudService.getSchema().subscribe((jsonSchemas: any) => {
this.schemas = jsonSchemas.components.schemas.EntityCreate
this.schemas.components = {
schemas: {
EntityType: jsonSchemas.components.schemas.EntityType
ngOnInit(): void {
this._loading$.next(true);
if (this.isCreateForm()) {
this.jsonSchemasService.getCreateResource(this.resource).subscribe((schemas: any) => {
this.fields = [this.formlyJsonschema.toFieldConfig(schemas)];
})
} else {
this.jsonSchemasService.getUpdateResource(this.resource).subscribe((schemas: any) => {
this.fields = [this.formlyJsonschema.toFieldConfig(schemas)];
})
this.crudService.get(this.resource_id!).subscribe((model: any) => {
this.model = model
this._loading$.next(false);
});
}
};
this.fields = [this.formlyJsonschema.toFieldConfig(this.schemas)];
});
if (this.resource_id !== null) {
this.crudService.get(this.resource_id!).subscribe((model: any) => {
this.model = model
});
this._loading$.next(false);
}
}
onSubmit(model: any) {
this._loading$.next(true);
if (this.resource_id !== null) {
this.crudService.update(model).subscribe((model: any) => {
this.model = model;
this._loading$.next(false);
});
} else {
if (this.isCreateForm()) {
this.crudService.create(model).subscribe((response: any) => {
this._loading$.next(false);
this.router.navigateByUrl('/entities/' + response.id);
});
} else {
this.crudService.update(model).subscribe((model: any) => {
this.model = model;
this._loading$.next(false);
});
}
console.log(model);
}
isCreateForm() {
return this.resource_id === null;
}
}

View File

@@ -14,6 +14,7 @@ import { ListComponent } from './list/list.component';
import { ObjectTypeComponent } from "./object.type";
import { CrudService } from "./crud.service";
import {NgbModule} from "@ng-bootstrap/ng-bootstrap";
import {JsonschemasService} from "./jsonschemas.service";
@NgModule({
@@ -22,7 +23,7 @@ import {NgbModule} from "@ng-bootstrap/ng-bootstrap";
ListComponent,
ObjectTypeComponent
],
providers: [ CrudService ],
providers: [ CrudService, JsonschemasService ],
imports: [
CommonModule,
HttpClientModule,

View File

@@ -1,11 +1,8 @@
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Schema } from "./jsonschemas.service";
export interface Schema {
components: { };
}
@Injectable()
export class CrudService {

View File

@@ -0,0 +1,85 @@
import {CrudService} from "./crud.service";
import {Observable} from "rxjs";
import {Injectable} from "@angular/core";
@Injectable({
providedIn: 'root',
})
export class JsonschemasService {
private rawSchemas: any | null = null;
constructor(private crudService: CrudService) {}
getSchemas(): Observable<Schema> {
return new Observable<Schema>((observer) => {
if (this.rawSchemas === null) {
this.crudService.getSchema().subscribe((jsonSchemas: any) => {
this.rawSchemas = jsonSchemas;
observer.next(this.rawSchemas)
});
} else {
observer.next(this.rawSchemas)
}
});
}
buildResource(resourceName: string) {
let resource;
resource = { ... this.rawSchemas.components.schemas[resourceName]};
resource.components = { schemas: {} };
for (let prop_name in resource.properties) {
let prop = resource.properties[prop_name];
if (this.is_reference(prop)) {
let subresourceName = this.get_reference_name(prop);
resource.components.schemas[subresourceName] = this.buildResource(subresourceName);
}
}
return resource;
}
getCreateResource(resourceName: string): Observable<Schema> {
return new Observable<Schema>((observer) => {
this.getSchemas().subscribe(() => {
observer.next(this.buildResource(resourceName + 'Create'))
})
})
}
getUpdateResource(resourceName: string): Observable<Schema> {
return new Observable<Schema>((observer) => {
this.getSchemas().subscribe(() => {
let resource = this.buildResource(resourceName + 'Read');
let updateResource = this.rawSchemas.components.schemas[resourceName + 'Update']
for (let prop_name in resource.properties) {
if (! updateResource.properties.hasOwnProperty(prop_name)) {
if (this.is_reference(resource.properties[prop_name])) {
let subresourceName = this.get_reference_name(resource.properties[prop_name]);
resource.components.schemas[subresourceName].readOnly = true;
} else {
resource.properties[prop_name].readOnly = true;
}
}
}
observer.next(resource);
})
})
}
private is_reference(prop: any) {
return prop.hasOwnProperty('$ref');
}
private get_reference_name(prop: any) {
return prop['$ref'].substring(prop['$ref'].lastIndexOf('/')+1);
}
}
export interface Schema {
components: { };
}