Dynamics list columns with a lot of work ahead
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { RJSFSchema } from '@rjsf/utils';
|
||||
import i18n from '../../../i18n'
|
||||
import { JSONSchema7Definition } from "json-schema";
|
||||
import { GridColDef } from "@mui/x-data-grid";
|
||||
|
||||
const API_URL = "/api/v1";
|
||||
|
||||
@@ -51,6 +52,10 @@ export const jsonschemaProvider = {
|
||||
return readSchema
|
||||
},
|
||||
|
||||
getReadResourceSchema: async (resourceName: string): Promise<CrudRJSFSchema> => {
|
||||
return getResourceSchema(`${resourceName}Read`)
|
||||
},
|
||||
|
||||
getUpdateResourceSchema: async (resourceName: string): Promise<CrudRJSFSchema> => {
|
||||
return getResourceSchema(`${resourceName}Update`)
|
||||
},
|
||||
@@ -58,21 +63,88 @@ export const jsonschemaProvider = {
|
||||
getCreateResourceSchema: async (resourceName: string): Promise<CrudRJSFSchema> => {
|
||||
return getResourceSchema(`${resourceName}Create`)
|
||||
},
|
||||
|
||||
getReadResourceColumns: async (resourceName: string): Promise<GridColDef[]> => {
|
||||
return getColumns(`${resourceName}Read`)
|
||||
},
|
||||
}
|
||||
|
||||
const getColumns = async (resourceName: string): Promise<GridColDef[]> => {
|
||||
return buildColumns(await getJsonschema(), resourceName)
|
||||
}
|
||||
|
||||
function buildColumns (rawSchemas: RJSFSchema, resourceName: string, prefix: string|undefined = undefined): GridColDef[] {
|
||||
if (rawSchemas.components.schemas[resourceName] === undefined) {
|
||||
throw new Error(`Resource "${resourceName}" not found in schema.`);
|
||||
}
|
||||
|
||||
const shortResourceName = convertCamelToSnake(resourceName.replace(/(-Input|-Output|Create|Update|Read)$/g, ""));
|
||||
let resource = rawSchemas.components.schemas[resourceName];
|
||||
let result: GridColDef[] = [];
|
||||
for (const prop_name in resource.properties) {
|
||||
let prop = resource.properties[prop_name];
|
||||
|
||||
if (is_reference(prop)) {
|
||||
const subresourceName = get_reference_name(prop);
|
||||
result = result.concat(buildColumns(rawSchemas, subresourceName, prefix ? `${prefix}.${prop_name}` : prop_name))
|
||||
} else if (is_union(prop)) {
|
||||
const union = prop.hasOwnProperty("oneOf") ? prop.oneOf : prop.anyOf;
|
||||
let seen = new Set<string>();
|
||||
for (let i in union) {
|
||||
if (is_reference(union[i])) {
|
||||
const subresourceName = get_reference_name(union[i]);
|
||||
const subcolumns = buildColumns(rawSchemas, subresourceName, prefix ? `${prefix}.${prop_name}` : prop_name);
|
||||
for (const s of subcolumns) {
|
||||
if (! seen.has(s.field)) {
|
||||
result.push(s);
|
||||
seen.add(s.field);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (is_enum(prop)) {
|
||||
let seen = new Set<string>();
|
||||
for (let i in prop.allOf) {
|
||||
if (is_reference(prop.allOf[i])) {
|
||||
const subresourceName = get_reference_name(prop.allOf[i]);
|
||||
const subcolumns = buildColumns(rawSchemas, subresourceName, prefix ? `${prefix}.${prop_name}` : prop_name);
|
||||
for (const s of subcolumns) {
|
||||
if (! seen.has(s.field)) {
|
||||
result.push(s);
|
||||
seen.add(s.field);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (is_array(prop) && is_reference(prop.items)) {
|
||||
const subresourceName = get_reference_name(prop.items);
|
||||
result = result.concat(buildColumns(rawSchemas, subresourceName, prefix ? `${prefix}.${prop_name}` : prop_name))
|
||||
} else {
|
||||
let column: GridColDef = {
|
||||
field: prefix ? `${prefix}.${prop_name}` : prop_name,
|
||||
headerName: i18n.t(`schemas.${shortResourceName}.${convertCamelToSnake(prop_name)}`, prop.title) as string,
|
||||
valueGetter: (value: any, row: any ) => {
|
||||
if (prefix === undefined) {
|
||||
return value;
|
||||
}
|
||||
|
||||
let parent = row;
|
||||
for (const column of prefix.split(".")) {
|
||||
parent = parent[column];
|
||||
}
|
||||
return parent ? parent[prop_name] : "";
|
||||
}
|
||||
}
|
||||
result.push(column);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
const getResourceSchema = async (resourceName: string): Promise<CrudRJSFSchema> => {
|
||||
return buildResource(await getJsonschema(), resourceName)
|
||||
}
|
||||
|
||||
let rawSchema: RJSFSchema;
|
||||
const getJsonschema = async (): Promise<RJSFSchema> => {
|
||||
if (rawSchema === undefined) {
|
||||
const response = await fetch(`${API_URL}/openapi.json`,);
|
||||
rawSchema = await response.json();
|
||||
}
|
||||
return rawSchema;
|
||||
}
|
||||
|
||||
function convertCamelToSnake(str: string): string {
|
||||
return str.replace(/([a-zA-Z])(?=[A-Z])/g,'$1_').toLowerCase()
|
||||
}
|
||||
@@ -82,7 +154,7 @@ function buildResource(rawSchemas: RJSFSchema, resourceName: string) {
|
||||
throw new Error(`Resource "${resourceName}" not found in schema.`);
|
||||
}
|
||||
|
||||
const shortResourceName = convertCamelToSnake(resourceName.replace(/(-Input|Create|Update)$/g, ""));
|
||||
const shortResourceName = convertCamelToSnake(resourceName.replace(/(-Input|-Output|Create|Update|Read)$/g, ""));
|
||||
let resource = structuredClone(rawSchemas.components.schemas[resourceName]);
|
||||
resource.components = { schemas: {} };
|
||||
for (let prop_name in resource.properties) {
|
||||
@@ -118,6 +190,15 @@ function buildResource(rawSchemas: RJSFSchema, resourceName: string) {
|
||||
return resource;
|
||||
}
|
||||
|
||||
let rawSchema: RJSFSchema;
|
||||
const getJsonschema = async (): Promise<RJSFSchema> => {
|
||||
if (rawSchema === undefined) {
|
||||
const response = await fetch(`${API_URL}/openapi.json`,);
|
||||
rawSchema = await response.json();
|
||||
}
|
||||
return rawSchema;
|
||||
}
|
||||
|
||||
function resolveReference(rawSchemas: RJSFSchema, resource: any, prop_reference: any) {
|
||||
const subresourceName = get_reference_name(prop_reference);
|
||||
const subresource = buildResource(rawSchemas, subresourceName);
|
||||
|
||||
Reference in New Issue
Block a user