From 39f19ddb50e3a8793b01d1e4069c343eea82db58 Mon Sep 17 00:00:00 2001 From: dcshzj <27919917+dcshzj@users.noreply.github.com> Date: Tue, 25 Jun 2024 16:57:38 +0800 Subject: [PATCH] feat: add placeholders for array, oneOf and prose inputs --- .../components/form-builder/FormBuilder.tsx | 9 +++ .../controls/JsonFormsArrayControl.tsx | 44 +++++++++++ .../controls/JsonFormsDropdownControl.tsx | 3 +- .../controls/JsonFormsOneOfControl.tsx | 74 +++++++++++++++++++ .../controls/JsonFormsProseControl.tsx | 42 +++++++++++ .../form-builder/renderers/controls/index.ts | 12 +++ 6 files changed, 183 insertions(+), 1 deletion(-) create mode 100644 apps/studio/src/features/editing-experience/components/form-builder/renderers/controls/JsonFormsArrayControl.tsx create mode 100644 apps/studio/src/features/editing-experience/components/form-builder/renderers/controls/JsonFormsOneOfControl.tsx create mode 100644 apps/studio/src/features/editing-experience/components/form-builder/renderers/controls/JsonFormsProseControl.tsx diff --git a/apps/studio/src/features/editing-experience/components/form-builder/FormBuilder.tsx b/apps/studio/src/features/editing-experience/components/form-builder/FormBuilder.tsx index cb33cefe7d..2fa92f3315 100644 --- a/apps/studio/src/features/editing-experience/components/form-builder/FormBuilder.tsx +++ b/apps/studio/src/features/editing-experience/components/form-builder/FormBuilder.tsx @@ -5,12 +5,18 @@ import { useState } from 'react' import IsomerSchema from '../../data/0.1.0.json' import { + JsonFormsArrayControl, + jsonFormsArrayControlTester, JsonFormsBooleanControl, jsonFormsBooleanControlTester, JsonFormsDropdownControl, jsonFormsDropdownControlTester, JsonFormsIntegerControl, jsonFormsIntegerControlTester, + JsonFormsOneOfControl, + jsonFormsOneOfControlTester, + JsonFormsProseControl, + jsonFormsProseControlTester, JsonFormsRadioControl, jsonFormsRadioControlTester, JsonFormsTextControl, @@ -20,6 +26,7 @@ import { } from './renderers' const renderers: JsonFormsRendererRegistryEntry[] = [ + { tester: jsonFormsArrayControlTester, renderer: JsonFormsArrayControl }, { tester: jsonFormsBooleanControlTester, renderer: JsonFormsBooleanControl }, { tester: jsonFormsDropdownControlTester, @@ -27,6 +34,8 @@ const renderers: JsonFormsRendererRegistryEntry[] = [ }, { tester: jsonFormsIntegerControlTester, renderer: JsonFormsIntegerControl }, { tester: jsonFormsTextControlTester, renderer: JsonFormsTextControl }, + { tester: jsonFormsOneOfControlTester, renderer: JsonFormsOneOfControl }, + { tester: jsonFormsProseControlTester, renderer: JsonFormsProseControl }, { tester: jsonFormsRadioControlTester, renderer: JsonFormsRadioControl }, { tester: jsonFormsVerticalLayoutTester, diff --git a/apps/studio/src/features/editing-experience/components/form-builder/renderers/controls/JsonFormsArrayControl.tsx b/apps/studio/src/features/editing-experience/components/form-builder/renderers/controls/JsonFormsArrayControl.tsx new file mode 100644 index 0000000000..4a08c40ebb --- /dev/null +++ b/apps/studio/src/features/editing-experience/components/form-builder/renderers/controls/JsonFormsArrayControl.tsx @@ -0,0 +1,44 @@ +import { Box, Heading } from '@chakra-ui/react' +import { + createDefaultValue, + isObjectArrayControl, + rankWith, + type ArrayLayoutProps, + type RankedTester, +} from '@jsonforms/core' +import { withJsonFormsArrayLayoutProps } from '@jsonforms/react' +import { Button } from '@opengovsg/design-system-react' + +export const jsonFormsArrayControlTester: RankedTester = rankWith( + 3, + isObjectArrayControl, +) + +export function JsonFormsArrayControl({ + path, + label, + addItem, + schema, + rootSchema, +}: ArrayLayoutProps) { + return ( + + + {label} + + +

Placeholder for drag-and-drop of objects

+ + +
+ ) +} + +export default withJsonFormsArrayLayoutProps(JsonFormsArrayControl) diff --git a/apps/studio/src/features/editing-experience/components/form-builder/renderers/controls/JsonFormsDropdownControl.tsx b/apps/studio/src/features/editing-experience/components/form-builder/renderers/controls/JsonFormsDropdownControl.tsx index f3a04dd12a..a51295338d 100644 --- a/apps/studio/src/features/editing-experience/components/form-builder/renderers/controls/JsonFormsDropdownControl.tsx +++ b/apps/studio/src/features/editing-experience/components/form-builder/renderers/controls/JsonFormsDropdownControl.tsx @@ -23,10 +23,11 @@ export function JsonFormsDropdownControl({ description, required, options, + schema, }: ControlProps & OwnPropsOfEnum) { const [dropdownValue, setDropdownValue] = useState(data || '') - if (!options) { + if (!options || (options.length === 1 && !!schema.default)) { return null } diff --git a/apps/studio/src/features/editing-experience/components/form-builder/renderers/controls/JsonFormsOneOfControl.tsx b/apps/studio/src/features/editing-experience/components/form-builder/renderers/controls/JsonFormsOneOfControl.tsx new file mode 100644 index 0000000000..8c3033db6c --- /dev/null +++ b/apps/studio/src/features/editing-experience/components/form-builder/renderers/controls/JsonFormsOneOfControl.tsx @@ -0,0 +1,74 @@ +import { Box, FormControl } from '@chakra-ui/react' +import { + createCombinatorRenderInfos, + isOneOfControl, + rankWith, + type CombinatorRendererProps, + type RankedTester, +} from '@jsonforms/core' +import { JsonFormsDispatch, withJsonFormsOneOfProps } from '@jsonforms/react' +import { FormLabel, SingleSelect } from '@opengovsg/design-system-react' +import { useState } from 'react' + +export const jsonFormsOneOfControlTester: RankedTester = rankWith( + 3, + isOneOfControl, +) + +export function JsonFormsOneOfControl({ + schema, + path, + renderers, + cells, + rootSchema, + uischema, + uischemas, + label, + description, +}: CombinatorRendererProps) { + const oneOfRenderInfos = createCombinatorRenderInfos( + schema.oneOf || [], + rootSchema, + 'oneOf', + uischema, + path, + uischemas, + ) + const variants = oneOfRenderInfos.map((oneOfRenderInfo) => ({ + label: oneOfRenderInfo.label, + value: oneOfRenderInfo.label, + })) + + const [variant, setVariant] = useState(oneOfRenderInfos[0]?.label || '') + + return ( + + + {label} + + + + {oneOfRenderInfos.map( + (oneOfRenderInfo) => + variant === oneOfRenderInfo.label && ( + + ), + )} + + ) +} + +export default withJsonFormsOneOfProps(JsonFormsOneOfControl) diff --git a/apps/studio/src/features/editing-experience/components/form-builder/renderers/controls/JsonFormsProseControl.tsx b/apps/studio/src/features/editing-experience/components/form-builder/renderers/controls/JsonFormsProseControl.tsx new file mode 100644 index 0000000000..03c5fdc0d1 --- /dev/null +++ b/apps/studio/src/features/editing-experience/components/form-builder/renderers/controls/JsonFormsProseControl.tsx @@ -0,0 +1,42 @@ +import { Box, FormControl } from '@chakra-ui/react' +import { + hasType, + rankWith, + schemaMatches, + type ControlProps, + type RankedTester, +} from '@jsonforms/core' +import { withJsonFormsControlProps } from '@jsonforms/react' +import { FormLabel, Textarea } from '@opengovsg/design-system-react' + +export const jsonFormsProseControlTester: RankedTester = rankWith( + 2, + schemaMatches( + (schema) => hasType(schema, 'array') && schema.format === 'prose', + ), +) + +// TODO: Replace this with the Tiptap editor +export function JsonFormsProseControl({ + data, + label, + handleChange, + path, + description, + required, +}: ControlProps) { + return ( + + + {label} +