Skip to content

Commit 73adc1a

Browse files
author
FalkWolsky
committed
Enabling Single-Level & Multi-Level JSON Schema Form definitions
1 parent 39b0370 commit 73adc1a

File tree

1 file changed

+89
-19
lines changed

1 file changed

+89
-19
lines changed

client/packages/lowcoder/src/comps/comps/jsonSchemaFormComp/ObjectFieldTemplate.tsx

+89-19
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import React, { useEffect, useRef, useState } from "react";
2-
import { Row, Col } from 'antd';
2+
import { Row, Col, Tabs } from 'antd';
33
import { ObjectFieldTemplateProps, getTemplate, getUiOptions, descriptionId, titleId, canExpand } from '@rjsf/utils';
44
import { ConfigConsumer } from 'antd/es/config-provider/context';
55
import { useContainerWidth } from "./jsonSchemaFormComp";
66
import styled from "styled-components";
7+
import TabPane from "antd/es/tabs/TabPane";
8+
import { is } from "core-js/core/object";
79

810
const DESCRIPTION_COL_STYLE = {
911
paddingBottom: '8px',
@@ -98,6 +100,67 @@ const ObjectFieldTemplate = (props: ObjectFieldTemplateProps) => {
98100
return fieldName ? registry.fields[fieldName] : undefined;
99101
};
100102

103+
const renderSingleLevel = (level : number) => {
104+
return (
105+
<Row gutter={rowGutter}>
106+
{properties.map((prop) => {
107+
const isArray = prop.content.props.schema.type === "array";
108+
const colSpan = isArray
109+
? { span: 24 }
110+
: calculateResponsiveColSpan(uiSchema?.[prop.name] || {});
111+
112+
return (
113+
<Col key={prop.name} {...colSpan}>
114+
{/* Render legend for array fields */}
115+
{isArray && (
116+
<><br /><legend style={getLegendStyle(level)}>
117+
{prop.content.props.schema.title}
118+
</legend></>
119+
)}
120+
{/* Render field content */}
121+
{prop.content}
122+
</Col>
123+
);
124+
})}
125+
</Row>
126+
);
127+
};
128+
129+
const renderCategorization = (elements: any[]) => {
130+
return (
131+
<Tabs>
132+
{elements.map((category, index) => (
133+
<TabPane tab={category.label || `Category ${index + 1}`} key={category.label || index}>
134+
{category.elements.map((element: any, elementIndex: number) => {
135+
if (element.type === "HorizontalLayout") {
136+
return (
137+
<Row key={elementIndex} gutter={rowGutter}>
138+
{element.elements.map((field: any, fieldIndex: number) => {
139+
const colSpan = calculateResponsiveColSpan(field.uiSchema);
140+
return (
141+
<Col key={fieldIndex} {...colSpan}>
142+
{properties.find((prop) => prop.name === field.scope.replace("#/properties/", ""))
143+
?.content}
144+
</Col>
145+
);
146+
})}
147+
</Row>
148+
);
149+
}
150+
151+
if (element.type === "Control") {
152+
return properties.find((prop) => prop.name === element.scope.replace("#/properties/", ""))
153+
?.content;
154+
}
155+
156+
return null;
157+
})}
158+
</TabPane>
159+
))}
160+
</Tabs>
161+
);
162+
};
163+
101164
const renderFieldsFromSection = (section: any, level: number = 0) => {
102165
const { formData, schema, uiSchema } = section.content.props;
103166

@@ -192,31 +255,38 @@ const ObjectFieldTemplate = (props: ObjectFieldTemplateProps) => {
192255
};
193256

194257
const renderSections = (properties: any[], level: number) => {
258+
259+
const isMultiLevel = properties.some(
260+
(prop) => prop.content.props.schema?.type === "object" && prop.content.props.schema?.properties
261+
);
262+
263+
if (!isMultiLevel) {
264+
return renderSingleLevel(level);
265+
}
266+
195267
return properties.map((section) => {
196268
const schema = section.content.props.schema;
197269
const isArray = typeof section.content.props.index === 'number';
198270
const sectionTitle = schema.title || section.name;
199271

200-
console.log("Section", sectionTitle, isArray, section);
201-
202272
return (
203-
<Row
204-
key={section.name}
205-
gutter={rowGutter}
206-
style={{ marginBottom: "16px", width: "100%" }}
207-
>
208-
<Col span={24}>
209-
<fieldset>
210-
{/* Always render the legend for the section itself */}
211-
{level === 0 && !isArray ? (
212-
<legend style={getLegendStyle(level)}>{sectionTitle}</legend>
213-
) : null}
273+
<Row
274+
key={section.name}
275+
gutter={rowGutter}
276+
style={{ marginBottom: "16px", width: "100%" }}
277+
>
278+
<Col span={24}>
279+
<fieldset>
280+
{/* Always render the legend for the section itself */}
281+
{level === 0 && !isArray ? (
282+
<legend style={getLegendStyle(level)}>{sectionTitle}</legend>
283+
) : null}
214284

215-
{/* Render the section content */}
216-
{renderFieldsFromSection(section, level + 1)}
217-
</fieldset>
218-
</Col>
219-
</Row>
285+
{/* Render the section content */}
286+
{renderFieldsFromSection(section, level + 1)}
287+
</fieldset>
288+
</Col>
289+
</Row>
220290
);
221291
});
222292
};

0 commit comments

Comments
 (0)