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 (
-
-
-
- )
-}
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",