From bb4a05e8dec22888108ccab456167a914123cd92 Mon Sep 17 00:00:00 2001 From: dcshzj <27919917+dcshzj@users.noreply.github.com> Date: Tue, 25 Jun 2024 15:05:11 +0800 Subject: [PATCH] feat: use JSONForms for complex block editing --- apps/studio/package.json | 6 - .../components/ComplexEditorStateDrawer.tsx | 12 + .../components/EditPageDrawer.tsx | 3 + .../components/FormBuilder.tsx | 166 ------- .../components/form-builder/FormBuilder.tsx | 66 +++ .../controls/JsonFormsBooleanControl.tsx | 48 ++ .../controls/JsonFormsDropdownControl.tsx | 57 +++ .../controls/JsonFormsIntegerControl.tsx | 82 +++ .../controls/JsonFormsRadioControl.tsx | 55 +++ .../controls/JsonFormsTextControl.tsx | 47 ++ .../form-builder/renderers/controls/index.ts | 20 + .../form-builder/renderers/index.ts | 2 + .../layouts/JsonFormsVerticalLayout.tsx | 44 ++ .../form-builder/renderers/layouts/index.ts | 4 + .../{components => data}/0.1.0.json | 252 +++++----- .../studio/src/pages/dashboard/edit/index.tsx | 2 +- apps/studio/src/utils/schema.ts | 34 -- package-lock.json | 466 +----------------- 18 files changed, 602 insertions(+), 764 deletions(-) create mode 100644 apps/studio/src/features/editing-experience/components/ComplexEditorStateDrawer.tsx delete mode 100644 apps/studio/src/features/editing-experience/components/FormBuilder.tsx create mode 100644 apps/studio/src/features/editing-experience/components/form-builder/FormBuilder.tsx create mode 100644 apps/studio/src/features/editing-experience/components/form-builder/renderers/controls/JsonFormsBooleanControl.tsx create mode 100644 apps/studio/src/features/editing-experience/components/form-builder/renderers/controls/JsonFormsDropdownControl.tsx create mode 100644 apps/studio/src/features/editing-experience/components/form-builder/renderers/controls/JsonFormsIntegerControl.tsx create mode 100644 apps/studio/src/features/editing-experience/components/form-builder/renderers/controls/JsonFormsRadioControl.tsx create mode 100644 apps/studio/src/features/editing-experience/components/form-builder/renderers/controls/JsonFormsTextControl.tsx create mode 100644 apps/studio/src/features/editing-experience/components/form-builder/renderers/controls/index.ts create mode 100644 apps/studio/src/features/editing-experience/components/form-builder/renderers/index.ts create mode 100644 apps/studio/src/features/editing-experience/components/form-builder/renderers/layouts/JsonFormsVerticalLayout.tsx create mode 100644 apps/studio/src/features/editing-experience/components/form-builder/renderers/layouts/index.ts rename apps/studio/src/features/editing-experience/{components => data}/0.1.0.json (92%) delete mode 100644 apps/studio/src/utils/schema.ts diff --git a/apps/studio/package.json b/apps/studio/package.json index bf7467dabc..475fa1f813 100644 --- a/apps/studio/package.json +++ b/apps/studio/package.json @@ -47,16 +47,10 @@ "@chakra-ui/styled-system": "^2.9.2", "@chakra-ui/theme-tools": "^2.1.2", "@chakra-ui/utils": "^2.0.15", - "@emotion/react": "^11.11.4", - "@emotion/styled": "^11.11.5", "@hello-pangea/dnd": "^16.6.0", "@hookform/resolvers": "^3.6.0", "@jsonforms/core": "^3.3.0", - "@jsonforms/material-renderers": "^3.3.0", "@jsonforms/react": "^3.3.0", - "@mui/icons-material": "^5.15.20", - "@mui/material": "^5.15.19", - "@mui/x-date-pickers": "^7.6.1", "@opengovsg/design-system-react": "^1.15.0", "@opengovsg/isomer-components": "*", "@opengovsg/sgid-client": "^2.2.0", diff --git a/apps/studio/src/features/editing-experience/components/ComplexEditorStateDrawer.tsx b/apps/studio/src/features/editing-experience/components/ComplexEditorStateDrawer.tsx new file mode 100644 index 0000000000..c3f5854a6f --- /dev/null +++ b/apps/studio/src/features/editing-experience/components/ComplexEditorStateDrawer.tsx @@ -0,0 +1,12 @@ +import React from 'react' +import { Box } from '@chakra-ui/react' +import FormBuilder from './form-builder/FormBuilder' + +export default function ComplexEditorStateDrawer(): JSX.Element { + return ( + +

Complex Editor State Drawer

+ +
+ ) +} diff --git a/apps/studio/src/features/editing-experience/components/EditPageDrawer.tsx b/apps/studio/src/features/editing-experience/components/EditPageDrawer.tsx index 45cc82af3b..5f5a4fc553 100644 --- a/apps/studio/src/features/editing-experience/components/EditPageDrawer.tsx +++ b/apps/studio/src/features/editing-experience/components/EditPageDrawer.tsx @@ -14,6 +14,7 @@ import { type DrawerState } from '~/types/editorDrawer' import { useEditorDrawerContext } from '~/contexts/EditorDrawerContext' import ComponentSelector from '~/components/PageEditor/ComponentSelector' import TipTapComponent from './TipTapComponent' +import ComplexEditorStateDrawer from "./ComplexEditorStateDrawer" type EditPageDrawerProps = { isOpen: boolean @@ -51,6 +52,8 @@ export function EditPageDrawer({ isOpen: open, state }: EditPageDrawerProps) { type="paragraph" /> ) + case 'complexEditor': + return default: return

Edit Page Drawer

} diff --git a/apps/studio/src/features/editing-experience/components/FormBuilder.tsx b/apps/studio/src/features/editing-experience/components/FormBuilder.tsx deleted file mode 100644 index 5d29535c29..0000000000 --- a/apps/studio/src/features/editing-experience/components/FormBuilder.tsx +++ /dev/null @@ -1,166 +0,0 @@ -import { - Box, - FormControl, - NumberDecrementStepper, - NumberIncrementStepper, - NumberInputField, - NumberInputStepper, - RadioGroup, - Select, -} from '@chakra-ui/react' -import { - Button, - FormLabel, - Input, - NumberInput, - Radio, - Switch, -} from '@opengovsg/design-system-react' -import { type IsomerComponent } from '@opengovsg/isomer-components' -import { useForm } from 'react-hook-form' -import IsomerSchema from './0.1.0.json' -import { getSchemaFieldType } from '~/utils/schema' - -// Utility type to get all keys from a union of objects -type UnionKeys = T extends T ? keyof T : never - -// TODO: Props here might not make sense, need to check again -export interface FormBuilderProps { - component: keyof typeof IsomerSchema.components.complex - data?: IsomerComponent -} - -// Strategy: -// - Read the sub-schema for the given component -// - For each prop inside the sub-schema, render the appropriate input field -// -// TODO: -// - Support type = 'array', format = 'prose' to be Tiptap editor -// - Support type = 'array' with items of type = 'object' to be sub-form (no drag and drop yet) -// - Support $ref to other parts of the schema -// - Handle grouping of fields -export function FormBuilder({ - component, - data, -}: FormBuilderProps): JSX.Element { - const schema = IsomerSchema.components.complex[component] - const { required, properties } = schema - const { register, handleSubmit } = useForm() - type ComplexComponentProps = UnionKeys - - // TODO: Remove or replace with proper submit function - const onSubmit = handleSubmit((data) => console.log(data)) - - return ( - -
- {Object.keys(properties) - .filter>( - (prop): prop is Exclude => - prop !== 'type', - ) - .map((prop) => { - const { - type, - format, - enum: options, - title, - description, - // @ts-expect-error this is safe because prop comes direct from properties - } = properties[prop] - const fieldType = getSchemaFieldType(type, format, options) - - if (fieldType === 'dropdown') { - return ( - - - {title} - - - - ) - } - - if (fieldType === 'radio') { - return ( - - - {title} - - {options.map((option: string) => ( - - {option.charAt(0).toUpperCase() + option.slice(1)} - - ))} - - - - ) - } - - if (fieldType === 'text') { - return ( - - - {title} - - - - ) - } - - if (fieldType === 'integer') { - // @ts-expect-error this is safe because prop comes direct from properties - const { minimum, maximum } = properties[prop] - - return ( - - - {title} - - - - - - - - - - ) - } - - if (fieldType === 'boolean') { - return ( - - - - {title} - - - - - ) - } - - return ( - - - - - ) - })} - - -
- ) -} 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 new file mode 100644 index 0000000000..cb33cefe7d --- /dev/null +++ b/apps/studio/src/features/editing-experience/components/form-builder/FormBuilder.tsx @@ -0,0 +1,66 @@ +import { type JsonFormsRendererRegistryEntry } from '@jsonforms/core' +import { JsonForms } from '@jsonforms/react' + +import { useState } from 'react' +import IsomerSchema from '../../data/0.1.0.json' + +import { + JsonFormsBooleanControl, + jsonFormsBooleanControlTester, + JsonFormsDropdownControl, + jsonFormsDropdownControlTester, + JsonFormsIntegerControl, + jsonFormsIntegerControlTester, + JsonFormsRadioControl, + jsonFormsRadioControlTester, + JsonFormsTextControl, + jsonFormsTextControlTester, + jsonFormsVerticalLayoutRenderer, + jsonFormsVerticalLayoutTester, +} from './renderers' + +const renderers: JsonFormsRendererRegistryEntry[] = [ + { tester: jsonFormsBooleanControlTester, renderer: JsonFormsBooleanControl }, + { + tester: jsonFormsDropdownControlTester, + renderer: JsonFormsDropdownControl, + }, + { tester: jsonFormsIntegerControlTester, renderer: JsonFormsIntegerControl }, + { tester: jsonFormsTextControlTester, renderer: JsonFormsTextControl }, + { tester: jsonFormsRadioControlTester, renderer: JsonFormsRadioControl }, + { + tester: jsonFormsVerticalLayoutTester, + renderer: jsonFormsVerticalLayoutRenderer, + }, +] + +export interface FormBuilderProps { + component: keyof typeof IsomerSchema.components.complex +} + +export default function FormBuilder({ + component, +}: FormBuilderProps): JSX.Element { + const { properties, ...rest } = IsomerSchema.components.complex[component] + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { type, ...props } = properties + const newSchema = { + ...rest, + properties: props, + components: IsomerSchema.components, + } + + const [formData, setFormData] = useState({}) + + return ( + { + console.log(data) + setFormData(data) + }} + /> + ) +} diff --git a/apps/studio/src/features/editing-experience/components/form-builder/renderers/controls/JsonFormsBooleanControl.tsx b/apps/studio/src/features/editing-experience/components/form-builder/renderers/controls/JsonFormsBooleanControl.tsx new file mode 100644 index 0000000000..0435b8078b --- /dev/null +++ b/apps/studio/src/features/editing-experience/components/form-builder/renderers/controls/JsonFormsBooleanControl.tsx @@ -0,0 +1,48 @@ +import { Box, FormControl } from '@chakra-ui/react' +import { + isBooleanControl, + rankWith, + type ControlProps, + type RankedTester, +} from '@jsonforms/core' +import { withJsonFormsControlProps } from '@jsonforms/react' +import { + FormErrorMessage, + FormLabel, + Switch, +} from '@opengovsg/design-system-react' + +export const jsonFormsBooleanControlTester: RankedTester = rankWith( + 2, + isBooleanControl, +) + +export function JsonFormsBooleanControl({ + data, + label, + id, + enabled, + handleChange, + errors, + path, + description, +}: ControlProps) { + return ( + + + + {label} + + handleChange(path, e.target.checked)} + /> + {errors} + + + ) +} + +export default withJsonFormsControlProps(JsonFormsBooleanControl) 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 new file mode 100644 index 0000000000..f3a04dd12a --- /dev/null +++ b/apps/studio/src/features/editing-experience/components/form-builder/renderers/controls/JsonFormsDropdownControl.tsx @@ -0,0 +1,57 @@ +import { Box, FormControl } from '@chakra-ui/react' +import { + isEnumControl, + rankWith, + type ControlProps, + type OwnPropsOfEnum, + type RankedTester, +} from '@jsonforms/core' +import { withJsonFormsEnumProps } from '@jsonforms/react' +import { FormLabel, SingleSelect } from '@opengovsg/design-system-react' +import { useState } from 'react' + +export const jsonFormsDropdownControlTester: RankedTester = rankWith( + 2, + isEnumControl, +) + +export function JsonFormsDropdownControl({ + data, + label, + handleChange, + path, + description, + required, + options, +}: ControlProps & OwnPropsOfEnum) { + const [dropdownValue, setDropdownValue] = useState(data || '') + + if (!options) { + return null + } + + const items = options.map((option) => ({ + label: option.label.charAt(0).toUpperCase() + option.label.slice(1), + value: option.value, + })) + + return ( + + + {label} + { + setDropdownValue(value) + handleChange(path, value) + }} + /> + + + ) +} + +export default withJsonFormsEnumProps(JsonFormsDropdownControl) diff --git a/apps/studio/src/features/editing-experience/components/form-builder/renderers/controls/JsonFormsIntegerControl.tsx b/apps/studio/src/features/editing-experience/components/form-builder/renderers/controls/JsonFormsIntegerControl.tsx new file mode 100644 index 0000000000..b97e1afd65 --- /dev/null +++ b/apps/studio/src/features/editing-experience/components/form-builder/renderers/controls/JsonFormsIntegerControl.tsx @@ -0,0 +1,82 @@ +import { + Box, + FormControl, + NumberDecrementStepper, + NumberIncrementStepper, + NumberInputField, + NumberInputStepper, +} from '@chakra-ui/react' +import { + and, + or, + rankWith, + schemaMatches, + schemaTypeIs, + uiTypeIs, + type ControlProps, + type RankedTester, +} from '@jsonforms/core' +import { withJsonFormsControlProps } from '@jsonforms/react' +import { + FormErrorMessage, + FormLabel, + NumberInput, +} from '@opengovsg/design-system-react' + +export const jsonFormsIntegerControlTester: RankedTester = rankWith( + 4, + and( + uiTypeIs('Control'), + or(schemaTypeIs('integer'), schemaTypeIs('number')), + schemaMatches( + (schema) => + (Object.prototype.hasOwnProperty.call(schema, 'maximum') || + Object.prototype.hasOwnProperty.call(schema, 'exclusiveMaximum')) && + (Object.prototype.hasOwnProperty.call(schema, 'minimum') || + Object.prototype.hasOwnProperty.call(schema, 'exclusiveMinimum')), + ), + ), +) + +export function JsonFormsIntegerControl({ + label, + schema, + handleChange, + errors, + path, + description, + required, +}: ControlProps) { + const { + exclusiveMaximum, + exclusiveMinimum, + maximum, + minimum, + default: defaultValue, + } = schema + const min = Number(exclusiveMinimum) + 1 || minimum || 0 + const max = Number(exclusiveMaximum) - 1 || maximum || 0 + + return ( + + + {label} + handleChange(path, e)} + > + + + + + + + {errors} + + + ) +} + +export default withJsonFormsControlProps(JsonFormsIntegerControl) diff --git a/apps/studio/src/features/editing-experience/components/form-builder/renderers/controls/JsonFormsRadioControl.tsx b/apps/studio/src/features/editing-experience/components/form-builder/renderers/controls/JsonFormsRadioControl.tsx new file mode 100644 index 0000000000..b446b20b65 --- /dev/null +++ b/apps/studio/src/features/editing-experience/components/form-builder/renderers/controls/JsonFormsRadioControl.tsx @@ -0,0 +1,55 @@ +import { Box, FormControl, RadioGroup } from '@chakra-ui/react' +import { + and, + isEnumControl, + rankWith, + schemaMatches, + type ControlProps, + type OwnPropsOfEnum, + type RankedTester, +} from '@jsonforms/core' +import { withJsonFormsEnumProps } from '@jsonforms/react' +import { FormLabel, Radio } from '@opengovsg/design-system-react' + +export const jsonFormsRadioControlTester: RankedTester = rankWith( + 3, + and( + isEnumControl, + schemaMatches((schema) => schema.format === 'radio'), + ), +) + +export function JsonFormsRadioControl({ + label, + handleChange, + path, + description, + required, + options, +}: ControlProps & OwnPropsOfEnum) { + if (!options) { + return null + } + + return ( + + + {label} + handleChange(path, value)}> + {options.map((option) => ( + + {option.label.charAt(0).toUpperCase() + option.label.slice(1)} + + ))} + + + + ) +} + +export default withJsonFormsEnumProps(JsonFormsRadioControl) diff --git a/apps/studio/src/features/editing-experience/components/form-builder/renderers/controls/JsonFormsTextControl.tsx b/apps/studio/src/features/editing-experience/components/form-builder/renderers/controls/JsonFormsTextControl.tsx new file mode 100644 index 0000000000..375481b1a9 --- /dev/null +++ b/apps/studio/src/features/editing-experience/components/form-builder/renderers/controls/JsonFormsTextControl.tsx @@ -0,0 +1,47 @@ +import { Box, FormControl } from '@chakra-ui/react' +import { + isStringControl, + rankWith, + type ControlProps, + type RankedTester, +} from '@jsonforms/core' +import { withJsonFormsControlProps } from '@jsonforms/react' +import { FormLabel, Input } from '@opengovsg/design-system-react' + +export const jsonFormsTextControlTester: RankedTester = rankWith( + 1, + isStringControl, +) + +export function JsonFormsTextControl({ + data, + visible, + label, + id, + enabled, + uischema, + schema, + rootSchema, + handleChange, + errors, + path, + config, + description, + required, +}: ControlProps) { + return ( + + + {label} + handleChange(path, e.target.value)} + placeholder={label} + /> + + + ) +} + +export default withJsonFormsControlProps(JsonFormsTextControl) diff --git a/apps/studio/src/features/editing-experience/components/form-builder/renderers/controls/index.ts b/apps/studio/src/features/editing-experience/components/form-builder/renderers/controls/index.ts new file mode 100644 index 0000000000..4a5a2e0505 --- /dev/null +++ b/apps/studio/src/features/editing-experience/components/form-builder/renderers/controls/index.ts @@ -0,0 +1,20 @@ +export { + default as JsonFormsBooleanControl, + jsonFormsBooleanControlTester, +} from './JsonFormsBooleanControl' +export { + default as JsonFormsDropdownControl, + jsonFormsDropdownControlTester, +} from './JsonFormsDropdownControl' +export { + default as JsonFormsIntegerControl, + jsonFormsIntegerControlTester, +} from './JsonFormsIntegerControl' +export { + default as JsonFormsRadioControl, + jsonFormsRadioControlTester, +} from './JsonFormsRadioControl' +export { + default as JsonFormsTextControl, + jsonFormsTextControlTester, +} from './JsonFormsTextControl' diff --git a/apps/studio/src/features/editing-experience/components/form-builder/renderers/index.ts b/apps/studio/src/features/editing-experience/components/form-builder/renderers/index.ts new file mode 100644 index 0000000000..5a7d212583 --- /dev/null +++ b/apps/studio/src/features/editing-experience/components/form-builder/renderers/index.ts @@ -0,0 +1,2 @@ +export * from './controls' +export * from './layouts' diff --git a/apps/studio/src/features/editing-experience/components/form-builder/renderers/layouts/JsonFormsVerticalLayout.tsx b/apps/studio/src/features/editing-experience/components/form-builder/renderers/layouts/JsonFormsVerticalLayout.tsx new file mode 100644 index 0000000000..00e0c4dda5 --- /dev/null +++ b/apps/studio/src/features/editing-experience/components/form-builder/renderers/layouts/JsonFormsVerticalLayout.tsx @@ -0,0 +1,44 @@ +import { Box, VStack } from '@chakra-ui/react' +import { + type VerticalLayout, + rankWith, + uiTypeIs, + type LayoutProps, + type RankedTester, +} from '@jsonforms/core' +import { JsonFormsDispatch, withJsonFormsLayoutProps } from '@jsonforms/react' + +export const jsonFormsVerticalLayoutTester: RankedTester = rankWith( + 1, + uiTypeIs('VerticalLayout'), +) + +export function JsonFormsVerticalLayoutRenderer({ + uischema, + schema, + path, + enabled, + renderers, + cells, +}: LayoutProps) { + const { elements } = uischema as VerticalLayout + + return ( + + {elements.map((element) => ( + + + + ))} + + ) +} + +export default withJsonFormsLayoutProps(JsonFormsVerticalLayoutRenderer) diff --git a/apps/studio/src/features/editing-experience/components/form-builder/renderers/layouts/index.ts b/apps/studio/src/features/editing-experience/components/form-builder/renderers/layouts/index.ts new file mode 100644 index 0000000000..5c00d6d3ba --- /dev/null +++ b/apps/studio/src/features/editing-experience/components/form-builder/renderers/layouts/index.ts @@ -0,0 +1,4 @@ +export { + default as jsonFormsVerticalLayoutRenderer, + jsonFormsVerticalLayoutTester, +} from './JsonFormsVerticalLayout' diff --git a/apps/studio/src/features/editing-experience/components/0.1.0.json b/apps/studio/src/features/editing-experience/data/0.1.0.json similarity index 92% rename from apps/studio/src/features/editing-experience/components/0.1.0.json rename to apps/studio/src/features/editing-experience/data/0.1.0.json index a60902a8e1..58a3bfa993 100644 --- a/apps/studio/src/features/editing-experience/components/0.1.0.json +++ b/apps/studio/src/features/editing-experience/data/0.1.0.json @@ -32,7 +32,7 @@ } ], "definitions": { - "content-components": { + "contentComponents": { "type": "array", "minItems": 1, "items": { @@ -52,6 +52,9 @@ { "$ref": "#/components/complex/iframe" }, + { + "$ref": "#/components/complex/image" + }, { "$ref": "#/components/complex/infobar" }, @@ -74,10 +77,7 @@ "$ref": "#/components/native/heading" }, { - "$ref": "#/components/native/image" - }, - { - "$ref": "#/components/native/orderedlist" + "$ref": "#/components/native/orderedList" }, { "$ref": "#/components/native/paragraph" @@ -86,12 +86,12 @@ "$ref": "#/components/native/table" }, { - "$ref": "#/components/native/unorderedlist" + "$ref": "#/components/native/unorderedList" } ] } }, - "page-metadata": { + "pageMetadata": { "type": "object", "required": ["title"], "properties": { @@ -125,14 +125,14 @@ "page": { "allOf": [ { - "$ref": "#/definitions/page-metadata" + "$ref": "#/definitions/pageMetadata" } ] }, "content": { "type": "array", "title": "Page content", - "$ref": "#/definitions/content-components" + "$ref": "#/definitions/contentComponents" } } }, @@ -149,14 +149,14 @@ "page": { "allOf": [ { - "$ref": "#/definitions/page-metadata" + "$ref": "#/definitions/pageMetadata" }, { "type": "object", "required": ["contentPageHeader"], "properties": { "contentPageHeader": { - "$ref": "#/components/internal/contentpageheader" + "$ref": "#/components/internal/contentPageHeader" } } } @@ -165,7 +165,7 @@ "content": { "type": "array", "title": "Page content", - "$ref": "#/definitions/content-components" + "$ref": "#/definitions/contentComponents" } } }, @@ -182,7 +182,7 @@ "page": { "allOf": [ { - "$ref": "#/definitions/page-metadata" + "$ref": "#/definitions/pageMetadata" }, { "type": "object", @@ -232,7 +232,7 @@ "page": { "allOf": [ { - "$ref": "#/definitions/page-metadata" + "$ref": "#/definitions/pageMetadata" }, { "type": "object", @@ -248,10 +248,10 @@ "title": "Date of the article" }, "image": { - "$ref": "#/components/internal/image-collection-card" + "$ref": "#/components/internal/imageCollectionCard" }, "articlePageHeader": { - "$ref": "#/components/internal/articlepageheader" + "$ref": "#/components/internal/articlePageHeader" } } } @@ -260,7 +260,7 @@ "content": { "type": "array", "title": "Page content", - "$ref": "#/definitions/content-components" + "$ref": "#/definitions/contentComponents" } } }, @@ -277,7 +277,7 @@ "page": { "allOf": [ { - "$ref": "#/definitions/page-metadata" + "$ref": "#/definitions/pageMetadata" }, { "required": ["ref", "category", "date"], @@ -297,7 +297,7 @@ "title": "Date of the file item" }, "image": { - "$ref": "#/components/internal/image-collection-card" + "$ref": "#/components/internal/imageCollectionCard" } } } @@ -329,7 +329,7 @@ "page": { "allOf": [ { - "$ref": "#/definitions/page-metadata" + "$ref": "#/definitions/pageMetadata" }, { "required": ["ref", "category", "date"], @@ -349,7 +349,7 @@ "title": "Date of the link item" }, "image": { - "$ref": "#/components/internal/image-collection-card" + "$ref": "#/components/internal/imageCollectionCard" } } } @@ -395,16 +395,16 @@ "items": { "anyOf": [ { - "$ref": "#/components/native/divider" + "$ref": "#/components/complex/image" }, { - "$ref": "#/components/native/heading" + "$ref": "#/components/native/divider" }, { - "$ref": "#/components/native/image" + "$ref": "#/components/native/heading" }, { - "$ref": "#/components/native/orderedlist" + "$ref": "#/components/native/orderedList" }, { "$ref": "#/components/native/paragraph" @@ -413,7 +413,7 @@ "$ref": "#/components/native/table" }, { - "$ref": "#/components/native/unorderedlist" + "$ref": "#/components/native/unorderedList" } ] } @@ -485,7 +485,6 @@ "type": "string", "title": "Callout variant", "description": "The variant of the callout to use", - "format": "radio", "enum": ["info", "success", "warning", "critical"] }, "content": { @@ -497,16 +496,16 @@ "items": { "anyOf": [ { - "$ref": "#/components/native/divider" + "$ref": "#/components/complex/image" }, { - "$ref": "#/components/native/heading" + "$ref": "#/components/native/divider" }, { - "$ref": "#/components/native/image" + "$ref": "#/components/native/heading" }, { - "$ref": "#/components/native/orderedlist" + "$ref": "#/components/native/orderedList" }, { "$ref": "#/components/native/paragraph" @@ -515,7 +514,7 @@ "$ref": "#/components/native/table" }, { - "$ref": "#/components/native/unorderedlist" + "$ref": "#/components/native/unorderedList" } ] } @@ -536,28 +535,28 @@ }, "oneOf": [ { - "$ref": "#/components/internal/hero-side" + "$ref": "#/components/internal/heroSide" }, { - "$ref": "#/components/internal/hero-image" + "$ref": "#/components/internal/heroImage" }, { - "$ref": "#/components/internal/hero-floating" + "$ref": "#/components/internal/heroFloating" }, { - "$ref": "#/components/internal/hero-center" + "$ref": "#/components/internal/heroCenter" }, { - "$ref": "#/components/internal/hero-gradient" + "$ref": "#/components/internal/heroGradient" }, { - "$ref": "#/components/internal/hero-split" + "$ref": "#/components/internal/heroSplit" }, { - "$ref": "#/components/internal/hero-copyled" + "$ref": "#/components/internal/heroCopyled" }, { - "$ref": "#/components/internal/hero-floatingimage" + "$ref": "#/components/internal/heroFloatingImage" } ] }, @@ -584,6 +583,40 @@ } } }, + "image": { + "type": "object", + "title": "Image component", + "required": ["type", "src", "alt"], + "properties": { + "type": { + "type": "string", + "enum": ["image"], + "default": "image" + }, + "src": { + "type": "string", + "title": "Image URL", + "description": "The URL to the image to display" + }, + "alt": { + "type": "string", + "title": "Image alt text", + "description": "The alt text for the image" + }, + "width": { + "type": "integer", + "title": "Image width", + "description": "The width of the image", + "exclusiveMinimum": 0, + "maximum": 100 + }, + "href": { + "type": "string", + "title": "URL Link", + "description": "The URL to link the image to" + } + } + }, "infobar": { "type": "object", "title": "Infobar component", @@ -645,7 +678,8 @@ "type": "string", "title": "Infocards variant", "description": "The variant of the Infocards component to use", - "enum": ["side", "top"] + "enum": ["side", "top"], + "format": "radio" }, "title": { "type": "string", @@ -880,7 +914,7 @@ } }, "internal": { - "articlepageheader": { + "articlePageHeader": { "type": "object", "title": "Article page header", "description": "The article page header is used to display the title, summary, breadcrumbs, category and date of an article page.", @@ -896,7 +930,7 @@ } } }, - "contentpageheader": { + "contentPageHeader": { "type": "object", "title": "Content page header", "description": "The content page header is used to display the title, summary, and breadcrumbs of a content page.", @@ -919,7 +953,20 @@ } } }, - "hero-side": { + "hardBreak": { + "type": "object", + "title": "Line break component", + "description": "A line break that forces a new line", + "required": ["type"], + "properties": { + "type": { + "type": "string", + "enum": ["hardBreak"], + "default": "hardBreak" + } + } + }, + "heroSide": { "type": "object", "title": "Hero side variant", "required": ["variant", "title", "backgroundUrl"], @@ -978,7 +1025,7 @@ "enum": ["sm", "md"] }, "dropdown": { - "$ref": "#/components/internal/hero-dropdown" + "$ref": "#/components/internal/heroDropdown" }, "backgroundUrl": { "type": "string", @@ -986,11 +1033,11 @@ "description": "The URL to the background image" }, "keyHighlights": { - "$ref": "#/components/internal/hero-key-highlights" + "$ref": "#/components/internal/heroKeyHighlights" } } }, - "hero-image": { + "heroImage": { "type": "object", "title": "Hero image variant", "required": ["image", "backgroundUrl"], @@ -1006,14 +1053,14 @@ "description": "The URL to the background image" }, "keyHighlights": { - "$ref": "#/components/internal/hero-key-highlights" + "$ref": "#/components/internal/heroKeyHighlights" }, "dropdown": { - "$ref": "#/components/internal/hero-dropdown" + "$ref": "#/components/internal/heroDropdown" } } }, - "hero-floating": { + "heroFloating": { "type": "object", "title": "Hero floating variant", "required": ["variant", "title", "backgroundUrl"], @@ -1072,7 +1119,7 @@ "enum": ["sm", "md"] }, "dropdown": { - "$ref": "#/components/internal/hero-dropdown" + "$ref": "#/components/internal/heroDropdown" }, "backgroundUrl": { "type": "string", @@ -1080,11 +1127,11 @@ "description": "The URL to the background image" }, "keyHighlights": { - "$ref": "#/components/internal/hero-key-highlights" + "$ref": "#/components/internal/heroKeyHighlights" } } }, - "hero-center": { + "heroCenter": { "type": "object", "title": "Hero center variant", "required": ["variant", "title", "backgroundUrl"], @@ -1130,14 +1177,14 @@ "description": "The URL to the background image" }, "keyHighlights": { - "$ref": "#/components/internal/hero-key-highlights" + "$ref": "#/components/internal/heroKeyHighlights" }, "dropdown": { - "$ref": "#/components/internal/hero-dropdown" + "$ref": "#/components/internal/heroDropdown" } } }, - "hero-gradient": { + "heroGradient": { "type": "object", "title": "Hero gradient variant", "required": ["variant", "title", "backgroundUrl"], @@ -1190,7 +1237,7 @@ } } }, - "hero-split": { + "heroSplit": { "type": "object", "title": "Hero split variant", "required": ["variant", "title", "backgroundUrl"], @@ -1249,7 +1296,7 @@ } } }, - "hero-copyled": { + "heroCopyled": { "type": "object", "title": "Hero copy-led variant", "required": ["variant", "title"], @@ -1296,7 +1343,7 @@ } } }, - "hero-floatingimage": { + "heroFloatingImage": { "type": "object", "title": "Hero floating image variant", "required": ["variant", "title", "backgroundUrl"], @@ -1343,7 +1390,7 @@ } } }, - "hero-dropdown": { + "heroDropdown": { "type": "object", "title": "Hero dropdown component", "required": ["options"], @@ -1375,7 +1422,7 @@ } } }, - "hero-key-highlights": { + "heroKeyHighlights": { "type": "array", "title": "Hero key highlights component", "required": ["title", "url"], @@ -1402,7 +1449,7 @@ } } }, - "image-collection-card": { + "imageCollectionCard": { "type": "object", "title": "Image for collection card", "description": "An optional image to include in the collection card.", @@ -1458,40 +1505,6 @@ } } }, - "image": { - "type": "object", - "title": "Image component", - "required": ["type", "src", "alt"], - "properties": { - "type": { - "type": "string", - "enum": ["image"], - "default": "image" - }, - "src": { - "type": "string", - "title": "Image URL", - "description": "The URL to the image to display" - }, - "alt": { - "type": "string", - "title": "Image alt text", - "description": "The alt text for the image" - }, - "width": { - "type": "number", - "title": "Image width", - "description": "The width of the image", - "exclusiveMinimum": 0, - "maximum": 100 - }, - "href": { - "type": "string", - "title": "URL Link", - "description": "The URL to link the image to" - } - } - }, "listItem": { "type": "object", "title": "List item component", @@ -1512,15 +1525,15 @@ } } }, - "orderedlist": { + "orderedList": { "type": "object", "title": "Ordered list component", "required": ["type", "content"], "properties": { "type": { "type": "string", - "enum": ["orderedlist"], - "default": "orderedlist" + "enum": ["orderedList"], + "default": "orderedList" }, "start": { "type": "integer", @@ -1537,10 +1550,10 @@ "$ref": "#/components/native/listItem" }, { - "$ref": "#/components/native/orderedlist" + "$ref": "#/components/native/orderedList" }, { - "$ref": "#/components/native/unorderedlist" + "$ref": "#/components/native/unorderedList" } ] } @@ -1562,7 +1575,14 @@ "title": "Paragraph content", "description": "The content of the paragraph", "items": { - "$ref": "#/components/native/text" + "anyOf": [ + { + "$ref": "#/components/internal/hardBreak" + }, + { + "$ref": "#/components/native/text" + } + ] } } } @@ -1602,7 +1622,7 @@ "title": "Table header cells", "minItems": 1, "items": { - "$ref": "#/components/native/table-header-cell" + "$ref": "#/components/native/tableHeaderCell" } } } @@ -1625,7 +1645,7 @@ "title": "Table header cells", "minItems": 1, "items": { - "$ref": "#/components/native/table-header-cell" + "$ref": "#/components/native/tableHeaderCell" } } } @@ -1645,7 +1665,7 @@ "title": "Table cells", "minItems": 1, "items": { - "$ref": "#/components/native/table-cell" + "$ref": "#/components/native/tableCell" } } } @@ -1655,7 +1675,7 @@ } } }, - "table-cell": { + "tableCell": { "type": "object", "title": "Table cell", "required": ["type", "content"], @@ -1673,19 +1693,19 @@ "items": { "anyOf": [ { - "$ref": "#/components/native/divider" + "$ref": "#/components/complex/image" }, { - "$ref": "#/components/native/image" + "$ref": "#/components/native/divider" }, { "$ref": "#/components/native/paragraph" }, { - "$ref": "#/components/native/orderedlist" + "$ref": "#/components/native/orderedList" }, { - "$ref": "#/components/native/unorderedlist" + "$ref": "#/components/native/unorderedList" } ] } @@ -1704,7 +1724,7 @@ } } }, - "table-header-cell": { + "tableHeaderCell": { "type": "object", "title": "Table header cell", "required": ["type", "content"], @@ -1762,15 +1782,15 @@ } } }, - "unorderedlist": { + "unorderedList": { "type": "object", "title": "Unordered list component", "required": ["type", "content"], "properties": { "type": { "type": "string", - "enum": ["unorderedlist"], - "default": "unorderedlist" + "enum": ["unorderedList"], + "default": "unorderedList" }, "content": { "type": "array", @@ -1782,10 +1802,10 @@ "$ref": "#/components/native/listItem" }, { - "$ref": "#/components/native/orderedlist" + "$ref": "#/components/native/orderedList" }, { - "$ref": "#/components/native/unorderedlist" + "$ref": "#/components/native/unorderedList" } ] } diff --git a/apps/studio/src/pages/dashboard/edit/index.tsx b/apps/studio/src/pages/dashboard/edit/index.tsx index 8eb473b85d..b6f97fae9b 100644 --- a/apps/studio/src/pages/dashboard/edit/index.tsx +++ b/apps/studio/src/pages/dashboard/edit/index.tsx @@ -178,7 +178,7 @@ const EditPage: NextPageWithLayout = () => { { - if (type === 'string' && options && format === 'select') { - return 'dropdown' - } - - if (type === 'string' && options && format === 'radio') { - return 'radio' - } - - if (type === 'string') { - return 'text' - } - - if (type === 'integer') { - return 'integer' - } - - if (type === 'boolean') { - return 'boolean' - } - - return null -} diff --git a/package-lock.json b/package-lock.json index 616b34f746..753e87f558 100644 --- a/package-lock.json +++ b/package-lock.json @@ -29,16 +29,10 @@ "@chakra-ui/styled-system": "^2.9.2", "@chakra-ui/theme-tools": "^2.1.2", "@chakra-ui/utils": "^2.0.15", - "@emotion/react": "^11.11.4", - "@emotion/styled": "^11.11.5", "@hello-pangea/dnd": "^16.6.0", "@hookform/resolvers": "^3.6.0", "@jsonforms/core": "^3.3.0", - "@jsonforms/material-renderers": "^3.3.0", "@jsonforms/react": "^3.3.0", - "@mui/icons-material": "^5.15.20", - "@mui/material": "^5.15.19", - "@mui/x-date-pickers": "^7.6.1", "@opengovsg/design-system-react": "^1.15.0", "@opengovsg/isomer-components": "*", "@opengovsg/sgid-client": "^2.2.0", @@ -515,71 +509,6 @@ "react": ">=16" } }, - "apps/studio/node_modules/@mui/x-date-pickers": { - "version": "7.6.1", - "resolved": "https://registry.npmjs.org/@mui/x-date-pickers/-/x-date-pickers-7.6.1.tgz", - "integrity": "sha512-erSq5cnOUyBgBmpHnMxIit5yhT3bl/lOaNZKpObvJtvEJetvNA9xWQ7dz/J/AufLzDuvThjusuRD0y+GmeXtiw==", - "dependencies": { - "@babel/runtime": "^7.24.6", - "@mui/base": "^5.0.0-beta.40", - "@mui/system": "^5.15.15", - "@mui/utils": "^5.15.14", - "@types/react-transition-group": "^4.4.10", - "clsx": "^2.1.1", - "prop-types": "^15.8.1", - "react-transition-group": "^4.4.5" - }, - "engines": { - "node": ">=14.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mui-org" - }, - "peerDependencies": { - "@emotion/react": "^11.9.0", - "@emotion/styled": "^11.8.1", - "@mui/material": "^5.15.14", - "date-fns": "^2.25.0 || ^3.2.0", - "date-fns-jalali": "^2.13.0-0 || ^3.2.0-0", - "dayjs": "^1.10.7", - "luxon": "^3.0.2", - "moment": "^2.29.4", - "moment-hijri": "^2.1.2", - "moment-jalaali": "^0.7.4 || ^0.8.0 || ^0.9.0 || ^0.10.0", - "react": "^17.0.0 || ^18.0.0", - "react-dom": "^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "@emotion/react": { - "optional": true - }, - "@emotion/styled": { - "optional": true - }, - "date-fns": { - "optional": true - }, - "date-fns-jalali": { - "optional": true - }, - "dayjs": { - "optional": true - }, - "luxon": { - "optional": true - }, - "moment": { - "optional": true - }, - "moment-hijri": { - "optional": true - }, - "moment-jalaali": { - "optional": true - } - } - }, "apps/studio/node_modules/@storybook/addon-a11y": { "version": "7.6.7", "resolved": "https://registry.npmjs.org/@storybook/addon-a11y/-/addon-a11y-7.6.7.tgz", @@ -6335,22 +6264,6 @@ "node": ">=0.1.90" } }, - "node_modules/@date-io/core": { - "version": "1.3.13", - "resolved": "https://registry.npmjs.org/@date-io/core/-/core-1.3.13.tgz", - "integrity": "sha512-AlEKV7TxjeK+jxWVKcCFrfYAk8spX9aCyiToFIiLPtfQbsjmRGLIhb5VZgptQcJdHtLXo7+m0DuurwFgUToQuA==" - }, - "node_modules/@date-io/dayjs": { - "version": "1.3.13", - "resolved": "https://registry.npmjs.org/@date-io/dayjs/-/dayjs-1.3.13.tgz", - "integrity": "sha512-nD39xWYwQjDMIdpUzHIcADHxY9m1hm1DpOaRn3bc2rBdgmwQC0PfW0WYaHyGGP/6LEzEguINRbHuotMhf+T9Sg==", - "dependencies": { - "@date-io/core": "^1.3.13" - }, - "peerDependencies": { - "dayjs": "^1.8.17" - } - }, "node_modules/@discoveryjs/json-ext": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", @@ -6364,6 +6277,7 @@ "version": "11.11.0", "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz", "integrity": "sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ==", + "peer": true, "dependencies": { "@babel/helper-module-imports": "^7.16.7", "@babel/runtime": "^7.18.3", @@ -6382,6 +6296,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "peer": true, "engines": { "node": ">=10" }, @@ -6393,6 +6308,7 @@ "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "peer": true, "engines": { "node": ">=0.10.0" } @@ -6401,6 +6317,7 @@ "version": "11.11.0", "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.11.0.tgz", "integrity": "sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ==", + "peer": true, "dependencies": { "@emotion/memoize": "^0.8.1", "@emotion/sheet": "^1.2.2", @@ -6412,12 +6329,14 @@ "node_modules/@emotion/hash": { "version": "0.9.1", "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.1.tgz", - "integrity": "sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ==" + "integrity": "sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ==", + "peer": true }, "node_modules/@emotion/is-prop-valid": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.2.tgz", "integrity": "sha512-uNsoYd37AFmaCdXlg6EYD1KaPOaRWRByMCYzbKUX4+hhMfrxdVSelShywL4JVaAeM/eHUOSprYBQls+/neX3pw==", + "peer": true, "dependencies": { "@emotion/memoize": "^0.8.1" } @@ -6425,12 +6344,14 @@ "node_modules/@emotion/memoize": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz", - "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==" + "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==", + "peer": true }, "node_modules/@emotion/react": { "version": "11.11.4", "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.11.4.tgz", "integrity": "sha512-t8AjMlF0gHpvvxk5mAtCqR4vmxiGHCeJBaQO6gncUSdklELOgtwjerNY2yuJNfwnc6vi16U/+uMF+afIawJ9iw==", + "peer": true, "dependencies": { "@babel/runtime": "^7.18.3", "@emotion/babel-plugin": "^11.11.0", @@ -6454,6 +6375,7 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.4.tgz", "integrity": "sha512-RIN04MBT8g+FnDwgvIUi8czvr1LU1alUMI05LekWB5DGyTm8cCBMCRpq3GqaiyEDRptEXOyXnvZ58GZYu4kBxQ==", + "peer": true, "dependencies": { "@emotion/hash": "^0.9.1", "@emotion/memoize": "^0.8.1", @@ -6465,12 +6387,14 @@ "node_modules/@emotion/sheet": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.2.tgz", - "integrity": "sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA==" + "integrity": "sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA==", + "peer": true }, "node_modules/@emotion/styled": { "version": "11.11.5", "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.11.5.tgz", "integrity": "sha512-/ZjjnaNKvuMPxcIiUkf/9SHoG4Q196DRl1w82hQ3WCsjo1IUR8uaGWrC6a87CrYAW0Kb/pK7hk8BnLgLRi9KoQ==", + "peer": true, "dependencies": { "@babel/runtime": "^7.18.3", "@emotion/babel-plugin": "^11.11.0", @@ -6492,7 +6416,8 @@ "node_modules/@emotion/unitless": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz", - "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==" + "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==", + "peer": true }, "node_modules/@emotion/use-insertion-effect-with-fallbacks": { "version": "1.0.1", @@ -6505,12 +6430,14 @@ "node_modules/@emotion/utils": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.1.tgz", - "integrity": "sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg==" + "integrity": "sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg==", + "peer": true }, "node_modules/@emotion/weak-memoize": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz", - "integrity": "sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==" + "integrity": "sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==", + "peer": true }, "node_modules/@esbuild/aix-ppc64": { "version": "0.20.2", @@ -8901,31 +8828,6 @@ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" }, - "node_modules/@jsonforms/material-renderers": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@jsonforms/material-renderers/-/material-renderers-3.3.0.tgz", - "integrity": "sha512-qyvPR7LVmvB6uiFjAGyv/MB9COOFwUc2PfRJfA1qpPx/aDBM03sCvWyw/M3XFHjyOJUxoMBVTbSz2t2gpCMnug==", - "dependencies": { - "@date-io/dayjs": "1.3.13", - "dayjs": "1.10.7", - "lodash": "^4.17.21" - }, - "peerDependencies": { - "@emotion/react": "^11.4.1", - "@emotion/styled": "^11.3.0", - "@jsonforms/core": "3.3.0", - "@jsonforms/react": "3.3.0", - "@mui/icons-material": "^5.11.16", - "@mui/material": "^5.13.0", - "@mui/x-date-pickers": "^6.0.0", - "react": "^16.12.0 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/@jsonforms/material-renderers/node_modules/dayjs": { - "version": "1.10.7", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.10.7.tgz", - "integrity": "sha512-P6twpd70BcPK34K26uJ1KT3wlhpuOAPoMwJzpsIWUxHZ7wpmbdZL/hQqBDfz7hGurYSa5PhzdhDHtt319hL3ig==" - }, "node_modules/@jsonforms/react": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/@jsonforms/react/-/react-3.3.0.tgz", @@ -9028,327 +8930,6 @@ "events": "^3.3.0" } }, - "node_modules/@mui/base": { - "version": "5.0.0-beta.40", - "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.40.tgz", - "integrity": "sha512-I/lGHztkCzvwlXpjD2+SNmvNQvB4227xBXhISPjEaJUXGImOQ9f3D2Yj/T3KasSI/h0MLWy74X0J6clhPmsRbQ==", - "dependencies": { - "@babel/runtime": "^7.23.9", - "@floating-ui/react-dom": "^2.0.8", - "@mui/types": "^7.2.14", - "@mui/utils": "^5.15.14", - "@popperjs/core": "^2.11.8", - "clsx": "^2.1.0", - "prop-types": "^15.8.1" - }, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mui-org" - }, - "peerDependencies": { - "@types/react": "^17.0.0 || ^18.0.0", - "react": "^17.0.0 || ^18.0.0", - "react-dom": "^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@mui/core-downloads-tracker": { - "version": "5.15.19", - "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.15.19.tgz", - "integrity": "sha512-tCHSi/Tomez9ERynFhZRvFO6n9ATyrPs+2N80DMDzp6xDVirbBjEwhPcE+x7Lj+nwYw0SqFkOxyvMP0irnm55w==", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mui-org" - } - }, - "node_modules/@mui/icons-material": { - "version": "5.15.20", - "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.15.20.tgz", - "integrity": "sha512-oGcKmCuHaYbAAoLN67WKSXtHmEgyWcJToT1uRtmPyxMj9N5uqwc/mRtEnst4Wj/eGr+zYH2FiZQ79v9k7kSk1Q==", - "dependencies": { - "@babel/runtime": "^7.23.9" - }, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mui-org" - }, - "peerDependencies": { - "@mui/material": "^5.0.0", - "@types/react": "^17.0.0 || ^18.0.0", - "react": "^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@mui/material": { - "version": "5.15.19", - "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.15.19.tgz", - "integrity": "sha512-lp5xQBbcRuxNtjpWU0BWZgIrv2XLUz4RJ0RqFXBdESIsKoGCQZ6P3wwU5ZPuj5TjssNiKv9AlM+vHopRxZhvVQ==", - "dependencies": { - "@babel/runtime": "^7.23.9", - "@mui/base": "5.0.0-beta.40", - "@mui/core-downloads-tracker": "^5.15.19", - "@mui/system": "^5.15.15", - "@mui/types": "^7.2.14", - "@mui/utils": "^5.15.14", - "@types/react-transition-group": "^4.4.10", - "clsx": "^2.1.0", - "csstype": "^3.1.3", - "prop-types": "^15.8.1", - "react-is": "^18.2.0", - "react-transition-group": "^4.4.5" - }, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mui-org" - }, - "peerDependencies": { - "@emotion/react": "^11.5.0", - "@emotion/styled": "^11.3.0", - "@types/react": "^17.0.0 || ^18.0.0", - "react": "^17.0.0 || ^18.0.0", - "react-dom": "^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "@emotion/react": { - "optional": true - }, - "@emotion/styled": { - "optional": true - }, - "@types/react": { - "optional": true - } - } - }, - "node_modules/@mui/material/node_modules/react-is": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==" - }, - "node_modules/@mui/private-theming": { - "version": "5.15.14", - "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.15.14.tgz", - "integrity": "sha512-UH0EiZckOWcxiXLX3Jbb0K7rC8mxTr9L9l6QhOZxYc4r8FHUkefltV9VDGLrzCaWh30SQiJvAEd7djX3XXY6Xw==", - "dependencies": { - "@babel/runtime": "^7.23.9", - "@mui/utils": "^5.15.14", - "prop-types": "^15.8.1" - }, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mui-org" - }, - "peerDependencies": { - "@types/react": "^17.0.0 || ^18.0.0", - "react": "^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@mui/styled-engine": { - "version": "5.15.14", - "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.15.14.tgz", - "integrity": "sha512-RILkuVD8gY6PvjZjqnWhz8fu68dVkqhM5+jYWfB5yhlSQKg+2rHkmEwm75XIeAqI3qwOndK6zELK5H6Zxn4NHw==", - "dependencies": { - "@babel/runtime": "^7.23.9", - "@emotion/cache": "^11.11.0", - "csstype": "^3.1.3", - "prop-types": "^15.8.1" - }, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mui-org" - }, - "peerDependencies": { - "@emotion/react": "^11.4.1", - "@emotion/styled": "^11.3.0", - "react": "^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "@emotion/react": { - "optional": true - }, - "@emotion/styled": { - "optional": true - } - } - }, - "node_modules/@mui/system": { - "version": "5.15.15", - "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.15.15.tgz", - "integrity": "sha512-aulox6N1dnu5PABsfxVGOZffDVmlxPOVgj56HrUnJE8MCSh8lOvvkd47cebIVQQYAjpwieXQXiDPj5pwM40jTQ==", - "dependencies": { - "@babel/runtime": "^7.23.9", - "@mui/private-theming": "^5.15.14", - "@mui/styled-engine": "^5.15.14", - "@mui/types": "^7.2.14", - "@mui/utils": "^5.15.14", - "clsx": "^2.1.0", - "csstype": "^3.1.3", - "prop-types": "^15.8.1" - }, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mui-org" - }, - "peerDependencies": { - "@emotion/react": "^11.5.0", - "@emotion/styled": "^11.3.0", - "@types/react": "^17.0.0 || ^18.0.0", - "react": "^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "@emotion/react": { - "optional": true - }, - "@emotion/styled": { - "optional": true - }, - "@types/react": { - "optional": true - } - } - }, - "node_modules/@mui/types": { - "version": "7.2.14", - "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.14.tgz", - "integrity": "sha512-MZsBZ4q4HfzBsywtXgM1Ksj6HDThtiwmOKUXH1pKYISI9gAVXCNHNpo7TlGoGrBaYWZTdNoirIN7JsQcQUjmQQ==", - "peerDependencies": { - "@types/react": "^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@mui/utils": { - "version": "5.15.14", - "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.15.14.tgz", - "integrity": "sha512-0lF/7Hh/ezDv5X7Pry6enMsbYyGKjADzvHyo3Qrc/SSlTsQ1VkbDMbH0m2t3OR5iIVLwMoxwM7yGd+6FCMtTFA==", - "dependencies": { - "@babel/runtime": "^7.23.9", - "@types/prop-types": "^15.7.11", - "prop-types": "^15.8.1", - "react-is": "^18.2.0" - }, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mui-org" - }, - "peerDependencies": { - "@types/react": "^17.0.0 || ^18.0.0", - "react": "^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@mui/utils/node_modules/react-is": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==" - }, - "node_modules/@mui/x-date-pickers": { - "version": "6.20.0", - "resolved": "https://registry.npmjs.org/@mui/x-date-pickers/-/x-date-pickers-6.20.0.tgz", - "integrity": "sha512-q/x3rNmPYMXnx75+3s9pQb1YDtws9y5bwxpxeB3EW88oCp33eS7bvJpeuoCA1LzW/PpVfIRhi5RCyAvrEeTL7Q==", - "peer": true, - "dependencies": { - "@babel/runtime": "^7.23.2", - "@mui/base": "^5.0.0-beta.22", - "@mui/utils": "^5.14.16", - "@types/react-transition-group": "^4.4.8", - "clsx": "^2.0.0", - "prop-types": "^15.8.1", - "react-transition-group": "^4.4.5" - }, - "engines": { - "node": ">=14.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mui" - }, - "peerDependencies": { - "@emotion/react": "^11.9.0", - "@emotion/styled": "^11.8.1", - "@mui/material": "^5.8.6", - "@mui/system": "^5.8.0", - "date-fns": "^2.25.0 || ^3.2.0", - "date-fns-jalali": "^2.13.0-0", - "dayjs": "^1.10.7", - "luxon": "^3.0.2", - "moment": "^2.29.4", - "moment-hijri": "^2.1.2", - "moment-jalaali": "^0.7.4 || ^0.8.0 || ^0.9.0 || ^0.10.0", - "react": "^17.0.0 || ^18.0.0", - "react-dom": "^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "@emotion/react": { - "optional": true - }, - "@emotion/styled": { - "optional": true - }, - "date-fns": { - "optional": true - }, - "date-fns-jalali": { - "optional": true - }, - "dayjs": { - "optional": true - }, - "luxon": { - "optional": true - }, - "moment": { - "optional": true - }, - "moment-hijri": { - "optional": true - }, - "moment-jalaali": { - "optional": true - } - } - }, "node_modules/@ndelangen/get-tarball": { "version": "3.0.9", "resolved": "https://registry.npmjs.org/@ndelangen/get-tarball/-/get-tarball-3.0.9.tgz", @@ -20039,6 +19620,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", + "peer": true, "dependencies": { "@babel/runtime": "^7.12.5", "cosmiconfig": "^7.0.0", @@ -25476,7 +25058,8 @@ "node_modules/find-root": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", - "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==" + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==", + "peer": true }, "node_modules/find-up": { "version": "5.0.0", @@ -37994,7 +37577,8 @@ "node_modules/stylis": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", - "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==" + "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==", + "peer": true }, "node_modules/sucrase": { "version": "3.35.0",