Adding Date and working on fereign keys

This commit is contained in:
2023-01-22 04:39:11 +01:00
parent 70d5a6e752
commit 7dd684e514
9 changed files with 289 additions and 21 deletions

View File

@@ -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)
}

View File

@@ -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) {

View File

@@ -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<FormlyFieldConfig> {
return this.jsonSchemasService.getCreateResource(resourceName).pipe(
map((schemas: any) => this.toFieldConfig(schemas)),
tap(console.log),
)
}
getUpdateFields(resourceName: string): Observable<FormlyFieldConfig> {
return this.jsonSchemasService.getUpdateResource(resourceName).pipe(
map((schemas: any) => this.toFieldConfig(schemas)),
tap(console.log),
)
}
}

View File

@@ -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

View File

@@ -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()

View File

@@ -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<Schema> {
return new Observable<Schema>((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";
}
}

View File

@@ -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: `
<label *ngIf="props.label && props['hideLabel'] !== true" [attr.for]="id"
class="form-label">{{ props.label }}
<span *ngIf="props.required && props['hideRequiredMarker'] !== true" aria-hidden="true">*</span>
</label>
<div class="input-group" *ngIf="! this.field.props.readonly">
<input type="hidden"
[formControl]="formControl"
[formlyAttributes]="field"
[class.is-invalid]="showError"
/>
<input
class="form-control"
placeholder="yyyy-mm-dd"
name="dp"
[(ngModel)]="date"
(ngModelChange)="changeDatetime($event)"
ngbDatepicker
#d="ngbDatepicker"
/>
<button class="btn btn-outline-secondary bi bi-calendar3" (click)="d.toggle()" type="button"></button>
</div>
<div class="input-group" *ngIf="this.field.props.readonly">
<input class="form-control" value="{{ this.datetime.toLocaleString() }}" disabled=""/>
</div>
`,
})
export class DateTypeComponent extends FieldType<FieldTypeConfig> 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')
)
}
}

View File

@@ -6,14 +6,14 @@ import { FieldType, FieldTypeConfig } from '@ngx-formly/core';
@Component({
selector: 'app-form-datepicker-type',
selector: 'app-form-datetimepicker-type',
template: `
<label *ngIf="props.label && props['hideLabel'] !== true" [attr.for]="id"
class="form-label">{{ props.label }}
<span *ngIf="props.required && props['hideRequiredMarker'] !== true" aria-hidden="true">*</span>
</label>
<div class="input-group" *ngIf="! this.field.props.readonly">
<input type="text"
<input type="hidden"
[formControl]="formControl"
[formlyAttributes]="field"
[class.is-invalid]="showError"

View File

@@ -0,0 +1,142 @@
import {Component, OnInit} from '@angular/core';
import {Observable, OperatorFunction, switchMapTo, of, from, exhaustAll, mergeAll, concatAll} from 'rxjs';
import { catchError } from 'rxjs/operators';
import { debounceTime, distinctUntilChanged, map, tap, merge } from 'rxjs/operators';
import { FieldType, FieldTypeConfig} from '@ngx-formly/core';
import {CrudService} from "../crud.service";
const states = [
'Alabama',
'Alaska',
'American Samoa',
'Arizona',
'Arkansas',
'California',
'Colorado',
'Connecticut',
'Delaware',
'District Of Columbia',
'Federated States Of Micronesia',
'Florida',
'Georgia',
'Guam',
'Hawaii',
'Idaho',
'Illinois',
'Indiana',
'Iowa',
'Kansas',
'Kentucky',
'Louisiana',
'Maine',
'Marshall Islands',
'Maryland',
'Massachusetts',
'Michigan',
'Minnesota',
'Mississippi',
'Missouri',
'Montana',
'Nebraska',
'Nevada',
'New Hampshire',
'New Jersey',
'New Mexico',
'New York',
'North Carolina',
'North Dakota',
'Northern Mariana Islands',
'Ohio',
'Oklahoma',
'Oregon',
'Palau',
'Pennsylvania',
'Puerto Rico',
'Rhode Island',
'South Carolina',
'South Dakota',
'Tennessee',
'Texas',
'Utah',
'Vermont',
'Virgin Islands',
'Virginia',
'Washington',
'West Virginia',
'Wisconsin',
'Wyoming',
];
@Component({
selector: 'formly-array-type',
template: `
<div class="mb-3">
<label *ngIf="props.label && props['hideLabel'] !== true" [attr.for]="id"
class="form-label">{{ props.label }}
<span *ngIf="props.required && props['hideRequiredMarker'] !== true" aria-hidden="true">*</span>
</label>
<div class="alert alert-danger" role="alert" *ngIf="showError && formControl.errors">
<formly-validation-message [field]="field"></formly-validation-message>
</div>
<input
class="form-control"
name="autocomplete"
[(ngModel)]="foreignId"
/>
<div class="input-group">
<input type="text"
class="form-control"
placeholder="Type the first letters..."
[(ngModel)]="foreignId"
[ngbTypeahead]="search" >
<div class="input-group-append">
<button class="btn btn-outline-secondary cil-plus" type="button">Button</button>
</div>
</div>
</div>
`,
})
export class ForeignkeyTypeComponent extends FieldType<FieldTypeConfig> 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<any> = 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<string, readonly string[]> = (text$: Observable<string>) => {
return text$.pipe(
debounceTime(200),
distinctUntilChanged(),
map((term) => this.getList(term)),
concatAll(),
)
}
getList(term: string) : Observable<readonly string[]> {
return this.crudService.getList(this.foreignResource, 0, 10, '_id', 'asc')
.pipe(
map((result: any) => result["items"]),
tap(console.log),
);
}
}