From 9aac1d3e3437632fdd555167858ea5f84af164ba Mon Sep 17 00:00:00 2001 From: ewandor Date: Tue, 13 May 2025 16:22:58 +0200 Subject: [PATCH] Minor refactoring of schema provider --- .../crud/providers/jsonschema-provider.tsx | 109 ++++++++++-------- 1 file changed, 58 insertions(+), 51 deletions(-) diff --git a/gui/rpk-gui/src/lib/crud/providers/jsonschema-provider.tsx b/gui/rpk-gui/src/lib/crud/providers/jsonschema-provider.tsx index 2c93d37..a2457be 100644 --- a/gui/rpk-gui/src/lib/crud/providers/jsonschema-provider.tsx +++ b/gui/rpk-gui/src/lib/crud/providers/jsonschema-provider.tsx @@ -78,6 +78,18 @@ export const jsonschemaProvider = { } } +const getResourceSchema = async (resourceName: string): Promise => { + return buildResource(await getJsonschema(), resourceName) +} + +const getColumns = async (resourceName: string): Promise => { + return buildColumns(await getJsonschema(), resourceName) +} + +const getFilters = async (resourceName: string, resourcePath: string): Promise => { + return buildFilters(await getJsonschema(), resourceName, resourcePath); +} + type PathParameter = { in: string, name:string @@ -87,10 +99,6 @@ type PathSchema = { parameters: PathParameter[] } -function shortenResourceName(resourceName: string) { - return convertCamelToSnake(resourceName.replace(/(-Input|-Output|Create|Update|Read)$/g, "")); -} - type FilterField = { name: string, label: string, @@ -98,6 +106,11 @@ type FilterField = { operators: { name: string, label: string }[] } +type Operator = { + operator: string, + fieldName: string, +} + async function hasSearch(resourcePath: string): Promise { const jst = new JsonSchemaTraverser(await getJsonschema()); const pathSchema = jst.getPath(resourcePath); @@ -110,9 +123,9 @@ async function hasSearch(resourcePath: string): Promise { return false } -async function getFilters(resourceName: string, resourcePath: string): Promise { +function buildFilters(rawSchema: RJSFSchema, resourceName: string, resourcePath: string): FilterField[] { const shortResourceName = shortenResourceName(resourceName); - const jst = new JsonSchemaTraverser(await getJsonschema()); + const jst = new JsonSchemaTraverser(rawSchema); const pathSchema = jst.getPath(resourcePath); const seen: { [k: string]: number } = {}; @@ -125,8 +138,8 @@ async function getFilters(resourceName: string, resourcePath: string): Promise { +const getFieldFilterType = (fieldName: string, field: RJSFSchema): string => { if (fieldName == "created_by" || fieldName == "updated_by") { return "author"; } else if (Array.isArray(field)) { @@ -180,17 +187,11 @@ const getFieldType = (fieldName: string, field: RJSFSchema): string => { throw "Unimplemented field type" } -const getColumns = async (resourceName: string): Promise => { - 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 = shortenResourceName(resourceName); + const jst = new JsonSchemaTraverser(rawSchemas); + let resource = structuredClone(jst.getResource(resourceName)); - 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]; @@ -264,42 +265,32 @@ function buildColumns (rawSchemas: RJSFSchema, resourceName: string, prefix: str return result; } -const getResourceSchema = async (resourceName: string): Promise => { - return buildResource(await getJsonschema(), resourceName) -} - -function convertCamelToSnake(str: string): string { - return str.replace(/([a-zA-Z])(?=[A-Z])/g,'$1_').toLowerCase() -} - function buildResource(rawSchemas: RJSFSchema, resourceName: string) { - if (rawSchemas.components.schemas[resourceName] === undefined) { - throw new Error(`Resource "${resourceName}" not found in schema.`); - } + const shortResourceName = shortenResourceName(resourceName); + const jst = new JsonSchemaTraverser(rawSchemas); + let resource = structuredClone(jst.getResource(resourceName)); - 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) { let prop = resource.properties[prop_name]; if (is_reference(prop)) { - resolveReference(rawSchemas, resource, prop); + buildReference(rawSchemas, resource, prop); } else if (is_union(prop)) { const union = prop.hasOwnProperty("oneOf") ? prop.oneOf : prop.anyOf; for (let i in union) { if (is_reference(union[i])) { - resolveReference(rawSchemas, resource, union[i]); + buildReference(rawSchemas, resource, union[i]); } } } else if (is_enum(prop)) { for (let i in prop.allOf) { if (is_reference(prop.allOf[i])) { - resolveReference(rawSchemas, resource, prop.allOf[i]); + buildReference(rawSchemas, resource, prop.allOf[i]); } } } else if (is_array(prop) && is_reference(prop.items)) { - resolveReference(rawSchemas, resource, prop.items); + buildReference(rawSchemas, resource, prop.items); } if (prop.hasOwnProperty("title")) { @@ -313,16 +304,7 @@ function buildResource(rawSchemas: RJSFSchema, resourceName: string) { return resource; } -let rawSchema: RJSFSchema; -const getJsonschema = async (): Promise => { - 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) { +function buildReference(rawSchemas: RJSFSchema, resource: any, prop_reference: any) { const subresourceName = get_reference_name(prop_reference); const subresource = buildResource(rawSchemas, subresourceName); resource.components.schemas[subresourceName] = subresource; @@ -391,6 +373,31 @@ function get_reference_name(prop: any) { return prop['$ref'].substring(prop['$ref'].lastIndexOf('/')+1); } +function convertCamelToSnake(str: string): string { + return str.replace(/([a-zA-Z])(?=[A-Z])/g,'$1_').toLowerCase() +} + +function shortenResourceName(resourceName: string) { + return convertCamelToSnake(resourceName.replace(/(-Input|-Output|Create|Update|Read)$/g, "")); +} + +function getPropertyI18nLabel(shortResourceName: string, fieldName: string): string { + if (meta_fields.indexOf(fieldName) > -1) { + return i18n.t(`schemas.${convertCamelToSnake(fieldName)}`); + } + const path = `schemas.${shortResourceName}.${convertCamelToSnake(fieldName)}` + return i18n.t(path) +} + +let rawSchema: RJSFSchema; +const getJsonschema = async (): Promise => { + if (rawSchema === undefined) { + const response = await fetch(`${API_URL}/openapi.json`,); + rawSchema = await response.json(); + } + return rawSchema; +} + const JsonSchemaTraverser = class { private rawSchemas: RJSFSchema;