From 7dd684e514733def38980db4ebbc4cf19d290ecc Mon Sep 17 00:00:00 2001 From: ewandor Date: Sun, 22 Jan 2023 04:39:11 +0100 Subject: [PATCH] Adding Date and working on fereign keys --- back/app/entity/models.py | 12 +- .../src/common/crud/card/card.component.ts | 19 ++- .../crud/crud-formly-jsonschema.service.ts | 34 +++++ front/app/src/common/crud/crud.module.ts | 11 +- front/app/src/common/crud/crud.service.ts | 2 + .../src/common/crud/jsonschemas.service.ts | 14 +- front/app/src/common/crud/types/date.type.ts | 72 +++++++++ .../src/common/crud/types/datetime.type.ts | 4 +- .../src/common/crud/types/foreignkey.type.ts | 142 ++++++++++++++++++ 9 files changed, 289 insertions(+), 21 deletions(-) create mode 100644 front/app/src/common/crud/crud-formly-jsonschema.service.ts create mode 100644 front/app/src/common/crud/types/date.type.ts create mode 100644 front/app/src/common/crud/types/foreignkey.type.ts diff --git a/back/app/entity/models.py b/back/app/entity/models.py index 8ac90301..17cc5ab2 100644 --- a/back/app/entity/models.py +++ b/back/app/entity/models.py @@ -24,8 +24,13 @@ class Individual(BaseModel): class Employee(BaseModel): - entity_id: str role: str + entity_id: str = Field(foreignKey={ + "reference": { + "resource": "entity", + "fields": "_id" + } + }) class Corporation(BaseModel): @@ -46,6 +51,7 @@ class Entity(Document): class Settings: bson_encoders = { - date: lambda dt: datetime(year=dt.year, month=dt.month, day=dt.day, hour=0, minute=0, second=0) \ - if not hasattr(dt, 'hour') else dt + date: lambda dt: dt if hasattr(dt, 'hour') + else datetime(year=dt.year, month=dt.month, day=dt.day, + hour=0, minute=0, second=0) } diff --git a/front/app/src/common/crud/card/card.component.ts b/front/app/src/common/crud/card/card.component.ts index 2f36edb7..676c1516 100644 --- a/front/app/src/common/crud/card/card.component.ts +++ b/front/app/src/common/crud/card/card.component.ts @@ -1,12 +1,11 @@ import { Component, Input, OnInit } from '@angular/core'; import { FormGroup } from '@angular/forms'; import { FormlyFieldConfig } from '@ngx-formly/core' -import { FormlyJsonschema } from '@ngx-formly/core/json-schema'; import { ActivatedRoute, Router } from '@angular/router'; import { CrudService } from '../crud.service' import { BehaviorSubject } from "rxjs"; -import { JsonschemasService } from "../jsonschemas.service"; +import {CrudFormlyJsonschemaService} from "../crud-formly-jsonschema.service"; export interface Model { email: string; @@ -33,27 +32,27 @@ export class CardComponent implements OnInit { } constructor(private crudService: CrudService, - private jsonSchemasService: JsonschemasService, - private formlyJsonschema: FormlyJsonschema, + private formlyJsonschema: CrudFormlyJsonschemaService, private router: Router, private route: ActivatedRoute, ) { } ngOnInit(): void { this._loading$.next(true); + let fields$; if (this.isCreateForm()) { - this.jsonSchemasService.getCreateResource(this.resource!).subscribe((schemas: any) => { - this.fields = [this.formlyJsonschema.toFieldConfig(schemas)]; - }) + fields$ = this.formlyJsonschema.getCreateFields(this.resource!); } else { - this.jsonSchemasService.getUpdateResource(this.resource!).subscribe((schemas: any) => { - this.fields = [this.formlyJsonschema.toFieldConfig(schemas)]; - }) this.crudService.get(this.resource!, this.resource_id!).subscribe((model: any) => { this.model = model this._loading$.next(false); }); + fields$ = this.formlyJsonschema.getUpdateFields(this.resource!); } + + fields$.subscribe((fields: any) => { + this.fields = [fields] + }); } onSubmit(model: any) { diff --git a/front/app/src/common/crud/crud-formly-jsonschema.service.ts b/front/app/src/common/crud/crud-formly-jsonschema.service.ts new file mode 100644 index 00000000..07dff9f1 --- /dev/null +++ b/front/app/src/common/crud/crud-formly-jsonschema.service.ts @@ -0,0 +1,34 @@ +import { FormlyJsonschema } from "@ngx-formly/core/json-schema"; +import { FormlyJsonschemaOptions } from "@ngx-formly/core/json-schema/formly-json-schema.service"; +import { FormlyFieldConfig } from "@ngx-formly/core"; +import { JSONSchema7 } from 'json-schema'; +import {JsonschemasService } from "./jsonschemas.service"; +import {Observable, map, tap} from "rxjs"; +import {Injectable} from "@angular/core"; + +@Injectable({ + providedIn: 'root', +}) +export class CrudFormlyJsonschemaService extends FormlyJsonschema { + constructor(private jsonSchemasService: JsonschemasService) { + super(); + } + + override toFieldConfig(schema: JSONSchema7, options?: FormlyJsonschemaOptions): FormlyFieldConfig { + return super.toFieldConfig(schema, options); + } + + getCreateFields(resourceName: string): Observable { + return this.jsonSchemasService.getCreateResource(resourceName).pipe( + map((schemas: any) => this.toFieldConfig(schemas)), + tap(console.log), + ) + } + + getUpdateFields(resourceName: string): Observable { + return this.jsonSchemasService.getUpdateResource(resourceName).pipe( + map((schemas: any) => this.toFieldConfig(schemas)), + tap(console.log), + ) + } +} diff --git a/front/app/src/common/crud/crud.module.ts b/front/app/src/common/crud/crud.module.ts index bfa5d5fa..aa34385f 100644 --- a/front/app/src/common/crud/crud.module.ts +++ b/front/app/src/common/crud/crud.module.ts @@ -12,10 +12,13 @@ import { ListComponent } from './list/list.component'; import { ArrayTypeComponent } from "./types/array.type"; import { ObjectTypeComponent } from "./types/object.type"; import { DatetimeTypeComponent } from "./types/datetime.type"; +import { DateTypeComponent } from "./types/date.type"; import { ApiService, CrudService } from "./crud.service"; +import { CrudFormlyJsonschemaService } from "./crud-formly-jsonschema.service"; import { NgbModule} from "@ng-bootstrap/ng-bootstrap"; import { JsonschemasService } from "./jsonschemas.service"; import { MultiSchemaTypeComponent } from "./types/multischema.type"; +import { ForeignkeyTypeComponent } from "./types/foreignkey.type"; @NgModule({ @@ -24,10 +27,12 @@ import { MultiSchemaTypeComponent } from "./types/multischema.type"; ListComponent, ObjectTypeComponent, DatetimeTypeComponent, + DateTypeComponent, ArrayTypeComponent, - MultiSchemaTypeComponent + MultiSchemaTypeComponent, + ForeignkeyTypeComponent, ], - providers: [ JsonschemasService, ApiService, CrudService ], + providers: [ JsonschemasService, ApiService, CrudService, CrudFormlyJsonschemaService ], imports: [ CommonModule, HttpClientModule, @@ -39,8 +44,10 @@ import { MultiSchemaTypeComponent } from "./types/multischema.type"; types: [ { name: 'object', component: ObjectTypeComponent }, { name: 'datetime', component: DatetimeTypeComponent }, + { name: 'date', component: DateTypeComponent }, { name: 'array', component: ArrayTypeComponent }, { name: 'multischema', component: MultiSchemaTypeComponent }, + { name: 'foreign-key', component: ForeignkeyTypeComponent }, ] }), FormlyBootstrapModule diff --git a/front/app/src/common/crud/crud.service.ts b/front/app/src/common/crud/crud.service.ts index d0a539c2..d6484cf9 100644 --- a/front/app/src/common/crud/crud.service.ts +++ b/front/app/src/common/crud/crud.service.ts @@ -1,6 +1,8 @@ import { HttpClient } from '@angular/common/http'; import { Injectable, Inject } from '@angular/core'; import { Schema } from "./jsonschemas.service"; +import {catchError} from "rxjs/operators"; +import {from} from "rxjs"; @Injectable() diff --git a/front/app/src/common/crud/jsonschemas.service.ts b/front/app/src/common/crud/jsonschemas.service.ts index e35d6021..8aaec9a0 100644 --- a/front/app/src/common/crud/jsonschemas.service.ts +++ b/front/app/src/common/crud/jsonschemas.service.ts @@ -1,6 +1,6 @@ -import {ApiService} from "./crud.service"; -import {Observable} from "rxjs"; -import {Injectable} from "@angular/core"; +import { Observable } from "rxjs"; +import { Injectable } from "@angular/core"; +import { ApiService } from "./crud.service"; @Injectable({ @@ -9,7 +9,9 @@ import {Injectable} from "@angular/core"; export class JsonschemasService { private rawSchemas: any | null = null; - constructor(private apiService: ApiService) {} + constructor( + private apiService: ApiService + ) {} getSchemas(): Observable { return new Observable((observer) => { @@ -44,6 +46,10 @@ export class JsonschemasService { this.resolveReference(resource, prop.items); } else if (prop.format === 'date-time') { prop.type = "datetime"; + } else if (prop.format === 'date') { + prop.type = "date"; + } else if (prop.hasOwnProperty('foreignKey')) { + prop.type = "foreign-key"; } } diff --git a/front/app/src/common/crud/types/date.type.ts b/front/app/src/common/crud/types/date.type.ts new file mode 100644 index 00000000..c58c25f3 --- /dev/null +++ b/front/app/src/common/crud/types/date.type.ts @@ -0,0 +1,72 @@ + +import { Component, ElementRef, OnInit, ViewChild} from '@angular/core'; +import { formatDate } from "@angular/common"; +import { NgbDateStruct, NgbTimeStruct } from '@ng-bootstrap/ng-bootstrap'; +import { FieldType, FieldTypeConfig } from '@ngx-formly/core'; + + +@Component({ + selector: 'app-form-datepicker-type', + template: ` + +
+ + + +
+
+ +
+ `, +}) +export class DateTypeComponent extends FieldType implements OnInit +{ + public time : NgbTimeStruct = { hour: 12, minute: 0, second: 0 } + public date : NgbDateStruct = { year: 2023, month: 1, day: 9 } + public datetime : Date = new Date() + + + constructor() { + super(); + } + + ngOnInit() { + this.formControl.valueChanges.subscribe(value => { + this.datetime = new Date(value) + this.date = this.getDateStruct(this.datetime); + }) + } + + getDateStruct(d: Date) { + return { + year: d.getFullYear(), + month: d.getMonth() + 1, + day: d.getDate(), + } + } + + changeDatetime(event: any) { + this.datetime.setFullYear(this.date.year) + this.datetime.setMonth(this.date.month - 1) + this.datetime.setDate(this.date.day) + + this.formControl.setValue( + formatDate(this.datetime, 'YYYY-MM-dd', 'EN_US', 'CET') + ) + } +} diff --git a/front/app/src/common/crud/types/datetime.type.ts b/front/app/src/common/crud/types/datetime.type.ts index b7900879..28cfc110 100644 --- a/front/app/src/common/crud/types/datetime.type.ts +++ b/front/app/src/common/crud/types/datetime.type.ts @@ -6,14 +6,14 @@ import { FieldType, FieldTypeConfig } from '@ngx-formly/core'; @Component({ - selector: 'app-form-datepicker-type', + selector: 'app-form-datetimepicker-type', template: `
- + + + + + + +
+ +
+ +
+
+
+ `, +}) +export class ForeignkeyTypeComponent extends FieldType implements OnInit +{ + public foreignId: string = "" + public foreignResource : string = ""; + public errorMsg: string = ""; + + constructor(private crudService: CrudService) { + super(); + } + + asyncSelected: string = "toto"; + typeaheadLoading: boolean = false; + typeaheadNoResults: boolean = true; + dataSource: Observable = new Observable(); + + + ngOnInit() { + this.foreignResource = this.field.key!.toString().split('_')[0]; + this.dataSource = new Observable((observer: any) => { + observer.next(this.asyncSelected); + }) + } + + // fired every time search string is changed + search: OperatorFunction = (text$: Observable) => { + return text$.pipe( + debounceTime(200), + distinctUntilChanged(), + map((term) => this.getList(term)), + concatAll(), + ) + } + + getList(term: string) : Observable { + return this.crudService.getList(this.foreignResource, 0, 10, '_id', 'asc') + .pipe( + map((result: any) => result["items"]), + tap(console.log), + ); + } +}