Handling subfileds as colunm in list
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { Observable } from "rxjs";
|
||||
import { Injectable } from "@angular/core";
|
||||
import { ApiService } from "./crud.service";
|
||||
import {JSONSchema7} from "json-schema";
|
||||
|
||||
|
||||
@Injectable({
|
||||
@@ -42,7 +43,7 @@ export class JsonschemasService {
|
||||
for (let i in prop.oneOf) {
|
||||
this.resolveReference(resource, prop.oneOf[i]);
|
||||
}
|
||||
} else if (prop.hasOwnProperty('items') && this.is_reference(prop.items)) {
|
||||
} else if (this.is_array(prop) && this.is_reference(prop.items)) {
|
||||
this.resolveReference(resource, prop.items);
|
||||
}
|
||||
}
|
||||
@@ -61,6 +62,10 @@ export class JsonschemasService {
|
||||
}
|
||||
}
|
||||
|
||||
getReferencedSchema() {
|
||||
|
||||
}
|
||||
|
||||
getCreateResource(resourceName: string): Observable<Schema> {
|
||||
return new Observable<Schema>((observer) => {
|
||||
this.getSchemas().subscribe(() => {
|
||||
@@ -91,10 +96,18 @@ export class JsonschemasService {
|
||||
})
|
||||
}
|
||||
|
||||
private is_object(prop: any) {
|
||||
return prop.hasOwnProperty('properties')
|
||||
}
|
||||
|
||||
private is_reference(prop: any) {
|
||||
return prop.hasOwnProperty('$ref');
|
||||
}
|
||||
|
||||
private is_array(prop: any) {
|
||||
return prop.hasOwnProperty('items');
|
||||
}
|
||||
|
||||
private is_union(prop: any) {
|
||||
return prop.hasOwnProperty('oneOf');
|
||||
}
|
||||
@@ -102,6 +115,67 @@ export class JsonschemasService {
|
||||
private get_reference_name(prop: any) {
|
||||
return prop['$ref'].substring(prop['$ref'].lastIndexOf('/')+1);
|
||||
}
|
||||
|
||||
has_descendant(resource: JSONSchema7, property_name: string): boolean {
|
||||
if (this.is_array(resource)) {
|
||||
return property_name == 'items';
|
||||
} else if (this.is_object(resource)) {
|
||||
return property_name in resource.properties!;
|
||||
} else if (this.is_reference(resource)) {
|
||||
let subresourceName = this.get_reference_name(resource);
|
||||
return this.has_descendant(this.buildResource(subresourceName), property_name);
|
||||
} else if (this.is_union(resource)) {
|
||||
for (const ref of resource.oneOf!) {
|
||||
// @ts-ignore
|
||||
if (this.has_descendant(ref, property_name)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
throw new Error("Jsonschema format not implemented in property finder");
|
||||
return false;
|
||||
}
|
||||
|
||||
get_descendant(resource: JSONSchema7, property_name: string): JSONSchema7 {
|
||||
if (this.is_array(resource) && property_name == 'items') {
|
||||
// @ts-ignore
|
||||
return resource.items;
|
||||
} else if (this.is_object(resource) && property_name in resource.properties!) {
|
||||
// @ts-ignore
|
||||
return resource.properties[property_name];
|
||||
} else if (this.is_reference(resource)) {
|
||||
let subresourceName = this.get_reference_name(resource);
|
||||
let subresource = this.buildResource(subresourceName);
|
||||
return this.get_descendant(subresource, property_name);
|
||||
} else if (this.is_union(resource)) {
|
||||
for (const ref of resource.oneOf!) {
|
||||
// @ts-ignore
|
||||
if (this.has_property(ref, property_name)) {
|
||||
// @ts-ignore
|
||||
return this.get_descendant(ref, property_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new Error("property not found or Jsonschema format not implemented");
|
||||
}
|
||||
|
||||
path_exists(resource: JSONSchema7, path: string): boolean{
|
||||
const pointFirstPosition = path.indexOf('.')
|
||||
if (pointFirstPosition == -1) {
|
||||
return this.has_descendant(resource, path);
|
||||
}
|
||||
|
||||
|
||||
return this.has_descendant(resource, path.substring(0, pointFirstPosition))
|
||||
&& this.path_exists(
|
||||
this.get_descendant(
|
||||
resource,
|
||||
path.substring(0, pointFirstPosition)
|
||||
),
|
||||
path.substring(pointFirstPosition + 1)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export interface Schema {
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<tbody>
|
||||
<tr *ngFor="let row of listData$ | async" (click)="onSelect(row._id)">
|
||||
<td *ngFor="let col of this.displayedColumns">
|
||||
<ngb-highlight [result]="row[col]" [term]="searchTerm"></ngb-highlight>
|
||||
<ngb-highlight [result]="getColumnValue(row,col)" [term]="searchTerm"></ngb-highlight>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
||||
@@ -1,39 +1,46 @@
|
||||
import { Component, ViewChildren, QueryList, Input, OnInit } from '@angular/core';
|
||||
import { BehaviorSubject } from "rxjs";
|
||||
import {JSONSchema7} from "json-schema";
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import {CrudService, Filters, SortBy} from "../crud.service";
|
||||
import { NgbdSortableHeader, SortColumn, SortDirection } from './sortable.directive';
|
||||
import { JsonschemasService } from "../jsonschemas.service";
|
||||
|
||||
|
||||
interface SearchResult {
|
||||
data: any[];
|
||||
total: number;
|
||||
}
|
||||
|
||||
interface State {
|
||||
page: number;
|
||||
pageSize: number;
|
||||
searchTerm: string;
|
||||
sortColumn: SortColumn;
|
||||
sortDirection: SortDirection;
|
||||
page: number;
|
||||
pageSize: number;
|
||||
searchTerm: string;
|
||||
sortColumn: SortColumn;
|
||||
sortDirection: SortDirection;
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'crud-list',
|
||||
templateUrl: './list.component.html',
|
||||
styleUrls: ['./list.component.css'],
|
||||
selector: 'crud-list',
|
||||
templateUrl: './list.component.html',
|
||||
styleUrls: ['./list.component.css'],
|
||||
})
|
||||
export class ListComponent implements OnInit {
|
||||
@Input() resource: string = "";
|
||||
@Input() columns: string[] = [];
|
||||
@Input() schema: string | undefined;
|
||||
@Input() resource: string = "";
|
||||
@Input() columns: string[] = [];
|
||||
@Input() schema: string | undefined;
|
||||
|
||||
public displayedColumns: string[] = [];
|
||||
@ViewChildren(NgbdSortableHeader) headers: QueryList<NgbdSortableHeader> = new QueryList<NgbdSortableHeader>();
|
||||
|
||||
loading: boolean = false;
|
||||
public displayedColumns: string[] = [];
|
||||
|
||||
@ViewChildren(NgbdSortableHeader) headers: QueryList<NgbdSortableHeader> = new QueryList<NgbdSortableHeader>();
|
||||
private _loading$ = new BehaviorSubject<boolean>(true);
|
||||
//private _search$ = new Subject<void>();
|
||||
private _listData$ = new BehaviorSubject<any[]>([]);
|
||||
private _total$ = new BehaviorSubject<number>(0);
|
||||
|
||||
private _state: State = {
|
||||
page: 1,
|
||||
pageSize: 15,
|
||||
searchTerm: '',
|
||||
sortColumn: '_id',
|
||||
sortDirection: 'asc',
|
||||
};
|
||||
|
||||
constructor(private service: CrudService,
|
||||
private jsonSchemasService: JsonschemasService,
|
||||
@@ -42,36 +49,35 @@ export class ListComponent implements OnInit {
|
||||
) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
this.jsonSchemasService.getUpdateResource(this.schema!).subscribe((schemas: any) => {
|
||||
if (this.columns.length == 0) {
|
||||
for (let param_name in schemas.properties) {
|
||||
this.jsonSchemasService.getUpdateResource(this.schema!).subscribe((schema: any) => {
|
||||
this.getColumnDefinition(schema)
|
||||
})
|
||||
this._search();
|
||||
}
|
||||
|
||||
getColumnDefinition(schema: JSONSchema7) {
|
||||
if (this.columns.length == 0) {
|
||||
for (let param_name in schema.properties) {
|
||||
if (param_name != "_id") {
|
||||
this.displayedColumns.push(param_name);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (let column of this.columns) {
|
||||
if (column in schemas.properties) {
|
||||
if (this.jsonSchemasService.path_exists(schema, column)) {
|
||||
this.displayedColumns.push(column);
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
this._search();
|
||||
}
|
||||
|
||||
private _loading$ = new BehaviorSubject<boolean>(true);
|
||||
//private _search$ = new Subject<void>();
|
||||
private _listData$ = new BehaviorSubject<any[]>([]);
|
||||
private _total$ = new BehaviorSubject<number>(0);
|
||||
|
||||
private _state: State = {
|
||||
page: 1,
|
||||
pageSize: 15,
|
||||
searchTerm: '',
|
||||
sortColumn: '_id',
|
||||
sortDirection: 'asc',
|
||||
};
|
||||
getColumnValue(row: any, col: string) {
|
||||
let parent = row;
|
||||
for (const key of col.split('.')) {
|
||||
parent = parent[key];
|
||||
}
|
||||
return parent;
|
||||
}
|
||||
|
||||
private _search() {
|
||||
this._loading$.next(true);
|
||||
@@ -104,7 +110,7 @@ export class ListComponent implements OnInit {
|
||||
}
|
||||
|
||||
onCreate() {
|
||||
this.router.navigate([`../new`], {relativeTo: this.route});
|
||||
this.router.navigate([`../new`], {relativeTo: this.route});
|
||||
}
|
||||
|
||||
get listData$() {
|
||||
|
||||
Reference in New Issue
Block a user