From 7707c042da7589c28c38b39eecf9512dcc139933 Mon Sep 17 00:00:00 2001 From: jasquat Date: Wed, 16 Nov 2022 13:35:55 -0500 Subject: [PATCH 01/10] attempting to add a theme w/ burnettk cullerton --- spiffworkflow-frontend/package-lock.json | 66 +++++++++++++ spiffworkflow-frontend/package.json | 1 + .../src/routes/TaskShow.tsx | 3 +- .../src/themes/AddButton/AddButton.tsx | 20 ++++ .../src/themes/AddButton/index.ts | 2 + .../ArrayFieldItemTemplate.tsx | 77 +++++++++++++++ .../themes/ArrayFieldItemTemplate/index.ts | 2 + .../ArrayFieldTemplate/ArrayFieldTemplate.tsx | 97 +++++++++++++++++++ .../src/themes/ArrayFieldTemplate/index.ts | 2 + .../BaseInputTemplate/BaseInputTemplate.tsx | 67 +++++++++++++ .../src/themes/BaseInputTemplate/index.ts | 2 + .../themes/CheckboxWidget/CheckboxWidget.tsx | 53 ++++++++++ .../src/themes/CheckboxWidget/index.ts | 2 + .../CheckboxesWidget/CheckboxesWidget.tsx | 83 ++++++++++++++++ .../src/themes/CheckboxesWidget/index.ts | 2 + .../DescriptionField/DescriptionField.tsx | 18 ++++ .../src/themes/DescriptionField/index.ts | 2 + .../src/themes/ErrorList/ErrorList.tsx | 25 +++++ .../src/themes/ErrorList/index.ts | 2 + .../FieldErrorTemplate/FieldErrorTemplate.tsx | 27 ++++++ .../src/themes/FieldErrorTemplate/index.ts | 2 + .../FieldHelpTemplate/FieldHelpTemplate.tsx | 20 ++++ .../src/themes/FieldHelpTemplate/index.ts | 2 + .../themes/FieldTemplate/FieldTemplate.tsx | 73 ++++++++++++++ .../src/themes/FieldTemplate/index.ts | 2 + .../src/themes/FileWidget/FileWidget.tsx | 14 +++ .../src/themes/FileWidget/index.ts | 2 + .../src/themes/Form/Form.tsx | 7 ++ .../src/themes/Form/index.ts | 2 + .../src/themes/IconButton/IconButton.tsx | 43 ++++++++ .../src/themes/IconButton/index.ts | 2 + .../ObjectFieldTemplate.tsx | 91 +++++++++++++++++ .../src/themes/ObjectFieldTemplate/index.ts | 2 + .../src/themes/RadioWidget/RadioWidget.tsx | 65 +++++++++++++ .../src/themes/RadioWidget/index.ts | 2 + .../src/themes/RangeWidget/RangeWidget.tsx | 18 ++++ .../src/themes/RangeWidget/index.ts | 2 + .../src/themes/SelectWidget/SelectWidget.tsx | 89 +++++++++++++++++ .../src/themes/SelectWidget/index.ts | 2 + .../src/themes/SubmitButton/SubmitButton.tsx | 23 +++++ .../src/themes/SubmitButton/index.ts | 2 + .../src/themes/Templates/Templates.ts | 35 +++++++ .../src/themes/Templates/index.ts | 2 + .../themes/TextareaWidget/TextareaWidget.tsx | 56 +++++++++++ .../src/themes/TextareaWidget/index.ts | 2 + .../src/themes/Theme/Theme.tsx | 11 +++ .../src/themes/Theme/index.ts | 2 + .../src/themes/TitleField/TitleField.tsx | 13 +++ .../src/themes/TitleField/index.ts | 2 + .../src/themes/Widgets/Widgets.ts | 17 ++++ .../src/themes/Widgets/index.ts | 2 + .../WrapIfAdditionalTemplate.tsx | 69 +++++++++++++ .../themes/WrapIfAdditionalTemplate/index.ts | 2 + spiffworkflow-frontend/src/themes/index.ts | 8 ++ 54 files changed, 1238 insertions(+), 1 deletion(-) create mode 100644 spiffworkflow-frontend/src/themes/AddButton/AddButton.tsx create mode 100644 spiffworkflow-frontend/src/themes/AddButton/index.ts create mode 100644 spiffworkflow-frontend/src/themes/ArrayFieldItemTemplate/ArrayFieldItemTemplate.tsx create mode 100644 spiffworkflow-frontend/src/themes/ArrayFieldItemTemplate/index.ts create mode 100644 spiffworkflow-frontend/src/themes/ArrayFieldTemplate/ArrayFieldTemplate.tsx create mode 100644 spiffworkflow-frontend/src/themes/ArrayFieldTemplate/index.ts create mode 100644 spiffworkflow-frontend/src/themes/BaseInputTemplate/BaseInputTemplate.tsx create mode 100644 spiffworkflow-frontend/src/themes/BaseInputTemplate/index.ts create mode 100644 spiffworkflow-frontend/src/themes/CheckboxWidget/CheckboxWidget.tsx create mode 100644 spiffworkflow-frontend/src/themes/CheckboxWidget/index.ts create mode 100644 spiffworkflow-frontend/src/themes/CheckboxesWidget/CheckboxesWidget.tsx create mode 100644 spiffworkflow-frontend/src/themes/CheckboxesWidget/index.ts create mode 100644 spiffworkflow-frontend/src/themes/DescriptionField/DescriptionField.tsx create mode 100644 spiffworkflow-frontend/src/themes/DescriptionField/index.ts create mode 100644 spiffworkflow-frontend/src/themes/ErrorList/ErrorList.tsx create mode 100644 spiffworkflow-frontend/src/themes/ErrorList/index.ts create mode 100644 spiffworkflow-frontend/src/themes/FieldErrorTemplate/FieldErrorTemplate.tsx create mode 100644 spiffworkflow-frontend/src/themes/FieldErrorTemplate/index.ts create mode 100644 spiffworkflow-frontend/src/themes/FieldHelpTemplate/FieldHelpTemplate.tsx create mode 100644 spiffworkflow-frontend/src/themes/FieldHelpTemplate/index.ts create mode 100644 spiffworkflow-frontend/src/themes/FieldTemplate/FieldTemplate.tsx create mode 100644 spiffworkflow-frontend/src/themes/FieldTemplate/index.ts create mode 100644 spiffworkflow-frontend/src/themes/FileWidget/FileWidget.tsx create mode 100644 spiffworkflow-frontend/src/themes/FileWidget/index.ts create mode 100644 spiffworkflow-frontend/src/themes/Form/Form.tsx create mode 100644 spiffworkflow-frontend/src/themes/Form/index.ts create mode 100644 spiffworkflow-frontend/src/themes/IconButton/IconButton.tsx create mode 100644 spiffworkflow-frontend/src/themes/IconButton/index.ts create mode 100644 spiffworkflow-frontend/src/themes/ObjectFieldTemplate/ObjectFieldTemplate.tsx create mode 100644 spiffworkflow-frontend/src/themes/ObjectFieldTemplate/index.ts create mode 100644 spiffworkflow-frontend/src/themes/RadioWidget/RadioWidget.tsx create mode 100644 spiffworkflow-frontend/src/themes/RadioWidget/index.ts create mode 100644 spiffworkflow-frontend/src/themes/RangeWidget/RangeWidget.tsx create mode 100644 spiffworkflow-frontend/src/themes/RangeWidget/index.ts create mode 100644 spiffworkflow-frontend/src/themes/SelectWidget/SelectWidget.tsx create mode 100644 spiffworkflow-frontend/src/themes/SelectWidget/index.ts create mode 100644 spiffworkflow-frontend/src/themes/SubmitButton/SubmitButton.tsx create mode 100644 spiffworkflow-frontend/src/themes/SubmitButton/index.ts create mode 100644 spiffworkflow-frontend/src/themes/Templates/Templates.ts create mode 100644 spiffworkflow-frontend/src/themes/Templates/index.ts create mode 100644 spiffworkflow-frontend/src/themes/TextareaWidget/TextareaWidget.tsx create mode 100644 spiffworkflow-frontend/src/themes/TextareaWidget/index.ts create mode 100644 spiffworkflow-frontend/src/themes/Theme/Theme.tsx create mode 100644 spiffworkflow-frontend/src/themes/Theme/index.ts create mode 100644 spiffworkflow-frontend/src/themes/TitleField/TitleField.tsx create mode 100644 spiffworkflow-frontend/src/themes/TitleField/index.ts create mode 100644 spiffworkflow-frontend/src/themes/Widgets/Widgets.ts create mode 100644 spiffworkflow-frontend/src/themes/Widgets/index.ts create mode 100644 spiffworkflow-frontend/src/themes/WrapIfAdditionalTemplate/WrapIfAdditionalTemplate.tsx create mode 100644 spiffworkflow-frontend/src/themes/WrapIfAdditionalTemplate/index.ts create mode 100644 spiffworkflow-frontend/src/themes/index.ts diff --git a/spiffworkflow-frontend/package-lock.json b/spiffworkflow-frontend/package-lock.json index 0e242476d..5dc7f8027 100644 --- a/spiffworkflow-frontend/package-lock.json +++ b/spiffworkflow-frontend/package-lock.json @@ -19,6 +19,7 @@ "@ginkgo-bioworks/react-json-schema-form-builder": "^2.9.0", "@monaco-editor/react": "^4.4.5", "@rjsf/core": "^4.2.0", + "@rjsf/utils": "^5.0.0-beta.13", "@tanstack/react-table": "^8.2.2", "@testing-library/jest-dom": "^5.16.4", "@testing-library/react": "^13.3.0", @@ -4551,6 +4552,42 @@ "react": ">=16 || >=17" } }, + "node_modules/@rjsf/utils": { + "version": "5.0.0-beta.13", + "resolved": "https://registry.npmjs.org/@rjsf/utils/-/utils-5.0.0-beta.13.tgz", + "integrity": "sha512-hWWWFD2ifjSOhqWueML4OHrZe2HW5pE2nfKGhCObFbwtggHoQlj64xDBsJ1qfUG8DGvCHztJQ/sKIaOvXnpt7w==", + "dependencies": { + "json-schema-merge-allof": "^0.8.1", + "jsonpointer": "^5.0.1", + "lodash": "^4.17.15", + "lodash-es": "^4.17.15", + "react-is": "^18.2.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "react": "^16.14.0 || >=17" + } + }, + "node_modules/@rjsf/utils/node_modules/json-schema-merge-allof": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/json-schema-merge-allof/-/json-schema-merge-allof-0.8.1.tgz", + "integrity": "sha512-CTUKmIlPJbsWfzRRnOXz+0MjIqvnleIXwFTzz+t9T86HnYX/Rozria6ZVGLktAU9e+NygNljveP+yxqtQp/Q4w==", + "dependencies": { + "compute-lcm": "^1.1.2", + "json-schema-compare": "^0.2.2", + "lodash": "^4.17.20" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@rjsf/utils/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + }, "node_modules/@rollup/plugin-babel": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", @@ -34221,6 +34258,35 @@ "react-is": "16.9.0" } }, + "@rjsf/utils": { + "version": "5.0.0-beta.13", + "resolved": "https://registry.npmjs.org/@rjsf/utils/-/utils-5.0.0-beta.13.tgz", + "integrity": "sha512-hWWWFD2ifjSOhqWueML4OHrZe2HW5pE2nfKGhCObFbwtggHoQlj64xDBsJ1qfUG8DGvCHztJQ/sKIaOvXnpt7w==", + "requires": { + "json-schema-merge-allof": "^0.8.1", + "jsonpointer": "^5.0.1", + "lodash": "^4.17.15", + "lodash-es": "^4.17.15", + "react-is": "^18.2.0" + }, + "dependencies": { + "json-schema-merge-allof": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/json-schema-merge-allof/-/json-schema-merge-allof-0.8.1.tgz", + "integrity": "sha512-CTUKmIlPJbsWfzRRnOXz+0MjIqvnleIXwFTzz+t9T86HnYX/Rozria6ZVGLktAU9e+NygNljveP+yxqtQp/Q4w==", + "requires": { + "compute-lcm": "^1.1.2", + "json-schema-compare": "^0.2.2", + "lodash": "^4.17.20" + } + }, + "react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + } + } + }, "@rollup/plugin-babel": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", diff --git a/spiffworkflow-frontend/package.json b/spiffworkflow-frontend/package.json index 51d2c4855..6aeb83008 100644 --- a/spiffworkflow-frontend/package.json +++ b/spiffworkflow-frontend/package.json @@ -14,6 +14,7 @@ "@ginkgo-bioworks/react-json-schema-form-builder": "^2.9.0", "@monaco-editor/react": "^4.4.5", "@rjsf/core": "^4.2.0", + "@rjsf/utils": "^5.0.0-beta.13", "@tanstack/react-table": "^8.2.2", "@testing-library/jest-dom": "^5.16.4", "@testing-library/react": "^13.3.0", diff --git a/spiffworkflow-frontend/src/routes/TaskShow.tsx b/spiffworkflow-frontend/src/routes/TaskShow.tsx index 096f408dc..3373eb71d 100644 --- a/spiffworkflow-frontend/src/routes/TaskShow.tsx +++ b/spiffworkflow-frontend/src/routes/TaskShow.tsx @@ -1,11 +1,12 @@ import { useContext, useEffect, useState } from 'react'; import { Link, useNavigate, useParams } from 'react-router-dom'; -import Form from '@rjsf/core'; +// import Form from '@rjsf/core'; // @ts-ignore import { Button, Stack } from '@carbon/react'; import ReactMarkdown from 'react-markdown'; import remarkGfm from 'remark-gfm'; +import Form from '../themes'; import HttpService from '../services/HttpService'; import ErrorContext from '../contexts/ErrorContext'; import { modifyProcessModelPath } from '../helpers'; diff --git a/spiffworkflow-frontend/src/themes/AddButton/AddButton.tsx b/spiffworkflow-frontend/src/themes/AddButton/AddButton.tsx new file mode 100644 index 000000000..f88f7153c --- /dev/null +++ b/spiffworkflow-frontend/src/themes/AddButton/AddButton.tsx @@ -0,0 +1,20 @@ +import React from "react"; +import { IconButtonProps } from "@rjsf/utils"; +import Button from "react-bootstrap/Button"; +import { BsPlus } from "@react-icons/all-files/bs/BsPlus"; + +const AddButton: React.ComponentType = ({ + uiSchema, + ...props +}) => ( + +); + +export default AddButton; diff --git a/spiffworkflow-frontend/src/themes/AddButton/index.ts b/spiffworkflow-frontend/src/themes/AddButton/index.ts new file mode 100644 index 000000000..e41962705 --- /dev/null +++ b/spiffworkflow-frontend/src/themes/AddButton/index.ts @@ -0,0 +1,2 @@ +export { default } from "./AddButton"; +export * from "./AddButton"; diff --git a/spiffworkflow-frontend/src/themes/ArrayFieldItemTemplate/ArrayFieldItemTemplate.tsx b/spiffworkflow-frontend/src/themes/ArrayFieldItemTemplate/ArrayFieldItemTemplate.tsx new file mode 100644 index 000000000..7858b1cc0 --- /dev/null +++ b/spiffworkflow-frontend/src/themes/ArrayFieldItemTemplate/ArrayFieldItemTemplate.tsx @@ -0,0 +1,77 @@ +import React, { CSSProperties } from "react"; +import Row from "react-bootstrap/Row"; +import Col from "react-bootstrap/Col"; +import { ArrayFieldTemplateItemType } from "@rjsf/utils"; + +const ArrayFieldItemTemplate = (props: ArrayFieldTemplateItemType) => { + const { + children, + disabled, + hasToolbar, + hasMoveDown, + hasMoveUp, + hasRemove, + index, + onDropIndexClick, + onReorderClick, + readonly, + registry, + uiSchema, + } = props; + const { MoveDownButton, MoveUpButton, RemoveButton } = + registry.templates.ButtonTemplates; + const btnStyle: CSSProperties = { + flex: 1, + paddingLeft: 6, + paddingRight: 6, + fontWeight: "bold", + }; + return ( +
+ + + {children} + + + {hasToolbar && ( +
+ {(hasMoveUp || hasMoveDown) && ( +
+ +
+ )} + {(hasMoveUp || hasMoveDown) && ( +
+ +
+ )} + {hasRemove && ( +
+ +
+ )} +
+ )} + +
+
+ ); +}; + +export default ArrayFieldItemTemplate; diff --git a/spiffworkflow-frontend/src/themes/ArrayFieldItemTemplate/index.ts b/spiffworkflow-frontend/src/themes/ArrayFieldItemTemplate/index.ts new file mode 100644 index 000000000..f64828beb --- /dev/null +++ b/spiffworkflow-frontend/src/themes/ArrayFieldItemTemplate/index.ts @@ -0,0 +1,2 @@ +export { default } from "./ArrayFieldItemTemplate"; +export * from "./ArrayFieldItemTemplate"; diff --git a/spiffworkflow-frontend/src/themes/ArrayFieldTemplate/ArrayFieldTemplate.tsx b/spiffworkflow-frontend/src/themes/ArrayFieldTemplate/ArrayFieldTemplate.tsx new file mode 100644 index 000000000..01d2575e4 --- /dev/null +++ b/spiffworkflow-frontend/src/themes/ArrayFieldTemplate/ArrayFieldTemplate.tsx @@ -0,0 +1,97 @@ +import React from "react"; +import Row from "react-bootstrap/Row"; +import Col from "react-bootstrap/Col"; +import Container from "react-bootstrap/Container"; +import { + ArrayFieldTemplateItemType, + ArrayFieldTemplateProps, + getTemplate, + getUiOptions, +} from "@rjsf/utils"; + +const ArrayFieldTemplate = (props: ArrayFieldTemplateProps) => { + const { + canAdd, + disabled, + idSchema, + uiSchema, + items, + onAddClick, + readonly, + registry, + required, + schema, + title, + } = props; + const uiOptions = getUiOptions(uiSchema); + const ArrayFieldDescriptionTemplate = + getTemplate<"ArrayFieldDescriptionTemplate">( + "ArrayFieldDescriptionTemplate", + registry, + uiOptions + ); + const ArrayFieldItemTemplate = getTemplate<"ArrayFieldItemTemplate">( + "ArrayFieldItemTemplate", + registry, + uiOptions + ); + const ArrayFieldTitleTemplate = getTemplate<"ArrayFieldTitleTemplate">( + "ArrayFieldTitleTemplate", + registry, + uiOptions + ); + // Button templates are not overridden in the uiSchema + const { + ButtonTemplates: { AddButton }, + } = registry.templates; + return ( +
+ + + + + + {items && + items.map(({ key, ...itemProps }: ArrayFieldTemplateItemType) => ( + + ))} + {canAdd && ( + + + + + + + + + )} + + + +
+ ); +}; + +export default ArrayFieldTemplate; diff --git a/spiffworkflow-frontend/src/themes/ArrayFieldTemplate/index.ts b/spiffworkflow-frontend/src/themes/ArrayFieldTemplate/index.ts new file mode 100644 index 000000000..29cbde48e --- /dev/null +++ b/spiffworkflow-frontend/src/themes/ArrayFieldTemplate/index.ts @@ -0,0 +1,2 @@ +export { default } from "./ArrayFieldTemplate"; +export * from "./ArrayFieldTemplate"; diff --git a/spiffworkflow-frontend/src/themes/BaseInputTemplate/BaseInputTemplate.tsx b/spiffworkflow-frontend/src/themes/BaseInputTemplate/BaseInputTemplate.tsx new file mode 100644 index 000000000..68699d050 --- /dev/null +++ b/spiffworkflow-frontend/src/themes/BaseInputTemplate/BaseInputTemplate.tsx @@ -0,0 +1,67 @@ +import React from "react"; +import Form from "react-bootstrap/Form"; +import { getInputProps, WidgetProps } from "@rjsf/utils"; + +const BaseInputTemplate = ({ + id, + placeholder, + required, + readonly, + disabled, + type, + value, + onChange, + onBlur, + onFocus, + autofocus, + options, + schema, + rawErrors = [], + children, + extraProps, +}: WidgetProps) => { + const inputProps = { ...extraProps, ...getInputProps(schema, type, options) }; + const _onChange = ({ + target: { value }, + }: React.ChangeEvent) => + onChange(value === "" ? options.emptyValue : value); + const _onBlur = ({ target: { value } }: React.FocusEvent) => + onBlur(id, value); + const _onFocus = ({ + target: { value }, + }: React.FocusEvent) => onFocus(id, value); + + // const classNames = [rawErrors.length > 0 ? "is-invalid" : "", type === 'file' ? 'custom-file-label': ""] + return ( + <> + 0 ? "is-invalid" : ""} + list={schema.examples ? `examples_${id}` : undefined} + {...inputProps} + value={value || value === 0 ? value : ""} + onChange={_onChange} + onBlur={_onBlur} + onFocus={_onFocus} + /> + {children} + {schema.examples ? ( + + {(schema.examples as string[]) + .concat(schema.default ? ([schema.default] as string[]) : []) + .map((example: any) => { + return + ) : null} + + ); +}; + +export default BaseInputTemplate; diff --git a/spiffworkflow-frontend/src/themes/BaseInputTemplate/index.ts b/spiffworkflow-frontend/src/themes/BaseInputTemplate/index.ts new file mode 100644 index 000000000..37c3947ed --- /dev/null +++ b/spiffworkflow-frontend/src/themes/BaseInputTemplate/index.ts @@ -0,0 +1,2 @@ +export { default } from "./BaseInputTemplate"; +export * from "./BaseInputTemplate"; diff --git a/spiffworkflow-frontend/src/themes/CheckboxWidget/CheckboxWidget.tsx b/spiffworkflow-frontend/src/themes/CheckboxWidget/CheckboxWidget.tsx new file mode 100644 index 000000000..f2e665d41 --- /dev/null +++ b/spiffworkflow-frontend/src/themes/CheckboxWidget/CheckboxWidget.tsx @@ -0,0 +1,53 @@ +import React from "react"; + +import { WidgetProps } from "@rjsf/utils"; +import Form from "react-bootstrap/Form"; + +const CheckboxWidget = (props: WidgetProps) => { + const { + id, + value, + required, + disabled, + readonly, + label, + schema, + autofocus, + onChange, + onBlur, + onFocus, + } = props; + + const _onChange = ({ + target: { checked }, + }: React.FocusEvent) => onChange(checked); + const _onBlur = ({ + target: { checked }, + }: React.FocusEvent) => onBlur(id, checked); + const _onFocus = ({ + target: { checked }, + }: React.FocusEvent) => onFocus(id, checked); + + const desc = label || schema.description; + return ( + + + + ); +}; + +export default CheckboxWidget; diff --git a/spiffworkflow-frontend/src/themes/CheckboxWidget/index.ts b/spiffworkflow-frontend/src/themes/CheckboxWidget/index.ts new file mode 100644 index 000000000..9a6515772 --- /dev/null +++ b/spiffworkflow-frontend/src/themes/CheckboxWidget/index.ts @@ -0,0 +1,2 @@ +export { default } from "./CheckboxWidget"; +export * from "./CheckboxWidget"; diff --git a/spiffworkflow-frontend/src/themes/CheckboxesWidget/CheckboxesWidget.tsx b/spiffworkflow-frontend/src/themes/CheckboxesWidget/CheckboxesWidget.tsx new file mode 100644 index 000000000..71646084e --- /dev/null +++ b/spiffworkflow-frontend/src/themes/CheckboxesWidget/CheckboxesWidget.tsx @@ -0,0 +1,83 @@ +import React from "react"; +import Form from "react-bootstrap/Form"; +import { WidgetProps } from "@rjsf/utils"; + +const selectValue = (value: any, selected: any, all: any) => { + const at = all.indexOf(value); + const updated = selected.slice(0, at).concat(value, selected.slice(at)); + + // As inserting values at predefined index positions doesn't work with empty + // arrays, we need to reorder the updated selection to match the initial order + return updated.sort((a: any, b: any) => all.indexOf(a) > all.indexOf(b)); +}; + +const deselectValue = (value: any, selected: any) => { + return selected.filter((v: any) => v !== value); +}; + +const CheckboxesWidget = ({ + id, + disabled, + options, + value, + autofocus, + readonly, + required, + onChange, + onBlur, + onFocus, +}: WidgetProps) => { + const { enumOptions, enumDisabled, inline } = options; + + const _onChange = + (option: any) => + ({ target: { checked } }: React.ChangeEvent) => { + const all = (enumOptions as any).map(({ value }: any) => value); + + if (checked) { + onChange(selectValue(option.value, value, all)); + } else { + onChange(deselectValue(option.value, value)); + } + }; + + const _onBlur = ({ target: { value } }: React.FocusEvent) => + onBlur(id, value); + const _onFocus = ({ + target: { value }, + }: React.FocusEvent) => onFocus(id, value); + + return ( + + {Array.isArray(enumOptions) && + enumOptions.map((option, index: number) => { + const checked = value.indexOf(option.value) !== -1; + const itemDisabled = + Array.isArray(enumDisabled) && + enumDisabled.indexOf(option.value) !== -1; + + return ( + + ); + })} + + ); +}; + +export default CheckboxesWidget; diff --git a/spiffworkflow-frontend/src/themes/CheckboxesWidget/index.ts b/spiffworkflow-frontend/src/themes/CheckboxesWidget/index.ts new file mode 100644 index 000000000..c5acc6aa1 --- /dev/null +++ b/spiffworkflow-frontend/src/themes/CheckboxesWidget/index.ts @@ -0,0 +1,2 @@ +export { default } from "./CheckboxesWidget"; +export * from "./CheckboxesWidget"; diff --git a/spiffworkflow-frontend/src/themes/DescriptionField/DescriptionField.tsx b/spiffworkflow-frontend/src/themes/DescriptionField/DescriptionField.tsx new file mode 100644 index 000000000..1e6e0eccb --- /dev/null +++ b/spiffworkflow-frontend/src/themes/DescriptionField/DescriptionField.tsx @@ -0,0 +1,18 @@ +import React from "react"; +import { DescriptionFieldProps } from "@rjsf/utils"; + +const DescriptionField = ({ id, description }: DescriptionFieldProps) => { + if (description) { + return ( +
+
+ {description} +
+
+ ); + } + + return null; +}; + +export default DescriptionField; diff --git a/spiffworkflow-frontend/src/themes/DescriptionField/index.ts b/spiffworkflow-frontend/src/themes/DescriptionField/index.ts new file mode 100644 index 000000000..899add9fc --- /dev/null +++ b/spiffworkflow-frontend/src/themes/DescriptionField/index.ts @@ -0,0 +1,2 @@ +export { default } from "./DescriptionField"; +export * from "./DescriptionField"; diff --git a/spiffworkflow-frontend/src/themes/ErrorList/ErrorList.tsx b/spiffworkflow-frontend/src/themes/ErrorList/ErrorList.tsx new file mode 100644 index 000000000..61dd66312 --- /dev/null +++ b/spiffworkflow-frontend/src/themes/ErrorList/ErrorList.tsx @@ -0,0 +1,25 @@ +import React from "react"; + +import Card from "react-bootstrap/Card"; +import ListGroup from "react-bootstrap/ListGroup"; + +import { ErrorListProps } from "@rjsf/utils"; + +const ErrorList = ({ errors }: ErrorListProps) => ( + + Errors + + + {errors.map((error, i: number) => { + return ( + + {error.stack} + + ); + })} + + + +); + +export default ErrorList; diff --git a/spiffworkflow-frontend/src/themes/ErrorList/index.ts b/spiffworkflow-frontend/src/themes/ErrorList/index.ts new file mode 100644 index 000000000..af63a176f --- /dev/null +++ b/spiffworkflow-frontend/src/themes/ErrorList/index.ts @@ -0,0 +1,2 @@ +export { default } from "./ErrorList"; +export * from "./ErrorList"; diff --git a/spiffworkflow-frontend/src/themes/FieldErrorTemplate/FieldErrorTemplate.tsx b/spiffworkflow-frontend/src/themes/FieldErrorTemplate/FieldErrorTemplate.tsx new file mode 100644 index 000000000..f1709ddaf --- /dev/null +++ b/spiffworkflow-frontend/src/themes/FieldErrorTemplate/FieldErrorTemplate.tsx @@ -0,0 +1,27 @@ +import React from "react"; +import { FieldErrorProps } from "@rjsf/utils"; +import ListGroup from "react-bootstrap/ListGroup"; + +/** The `FieldErrorTemplate` component renders the errors local to the particular field + * + * @param props - The `FieldErrorProps` for the errors being rendered + */ +export default function FieldErrorTemplate(props: FieldErrorProps) { + const { errors = [], idSchema } = props; + if (errors.length === 0) { + return null; + } + const id = `${idSchema.$id}__error`; + + return ( + + {errors.map((error, i) => { + return ( + + {error} + + ); + })} + + ); +} diff --git a/spiffworkflow-frontend/src/themes/FieldErrorTemplate/index.ts b/spiffworkflow-frontend/src/themes/FieldErrorTemplate/index.ts new file mode 100644 index 000000000..dd9c569ff --- /dev/null +++ b/spiffworkflow-frontend/src/themes/FieldErrorTemplate/index.ts @@ -0,0 +1,2 @@ +export { default } from "./FieldErrorTemplate"; +export * from "./FieldErrorTemplate"; diff --git a/spiffworkflow-frontend/src/themes/FieldHelpTemplate/FieldHelpTemplate.tsx b/spiffworkflow-frontend/src/themes/FieldHelpTemplate/FieldHelpTemplate.tsx new file mode 100644 index 000000000..271923188 --- /dev/null +++ b/spiffworkflow-frontend/src/themes/FieldHelpTemplate/FieldHelpTemplate.tsx @@ -0,0 +1,20 @@ +import React from "react"; +import { FieldHelpProps } from "@rjsf/utils"; +import Form from "react-bootstrap/Form"; + +/** The `FieldHelpTemplate` component renders any help desired for a field + * + * @param props - The `FieldHelpProps` to be rendered + */ +export default function FieldHelpTemplate(props: FieldHelpProps) { + const { idSchema, help, hasErrors } = props; + if (!help) { + return null; + } + const id = `${idSchema.$id}__help`; + return ( + + {help} + + ); +} diff --git a/spiffworkflow-frontend/src/themes/FieldHelpTemplate/index.ts b/spiffworkflow-frontend/src/themes/FieldHelpTemplate/index.ts new file mode 100644 index 000000000..55b9f4a09 --- /dev/null +++ b/spiffworkflow-frontend/src/themes/FieldHelpTemplate/index.ts @@ -0,0 +1,2 @@ +export { default } from "./FieldHelpTemplate"; +export * from "./FieldHelpTemplate"; diff --git a/spiffworkflow-frontend/src/themes/FieldTemplate/FieldTemplate.tsx b/spiffworkflow-frontend/src/themes/FieldTemplate/FieldTemplate.tsx new file mode 100644 index 000000000..ace72557d --- /dev/null +++ b/spiffworkflow-frontend/src/themes/FieldTemplate/FieldTemplate.tsx @@ -0,0 +1,73 @@ +import React from "react"; +import { FieldTemplateProps, getTemplate, getUiOptions } from "@rjsf/utils"; +import Form from "react-bootstrap/Form"; + +const FieldTemplate = ({ + id, + children, + displayLabel, + rawErrors = [], + errors, + help, + rawDescription, + classNames, + disabled, + label, + hidden, + onDropPropertyClick, + onKeyChange, + readonly, + required, + schema, + uiSchema, + registry, +}: FieldTemplateProps) => { + const uiOptions = getUiOptions(uiSchema); + const WrapIfAdditionalTemplate = getTemplate<"WrapIfAdditionalTemplate">( + "WrapIfAdditionalTemplate", + registry, + uiOptions + ); + if (hidden) { + return
{children}
; + } + return ( + + + {displayLabel && ( + 0 ? "text-danger" : ""} + > + {label} + {required ? "*" : null} + + )} + {children} + {displayLabel && rawDescription && ( + 0 ? "text-danger" : "text-muted"} + > + {rawDescription} + + )} + {errors} + {help} + + + ); +}; + +export default FieldTemplate; diff --git a/spiffworkflow-frontend/src/themes/FieldTemplate/index.ts b/spiffworkflow-frontend/src/themes/FieldTemplate/index.ts new file mode 100644 index 000000000..290c188da --- /dev/null +++ b/spiffworkflow-frontend/src/themes/FieldTemplate/index.ts @@ -0,0 +1,2 @@ +export { default } from "./FieldTemplate"; +export * from "./FieldTemplate"; diff --git a/spiffworkflow-frontend/src/themes/FileWidget/FileWidget.tsx b/spiffworkflow-frontend/src/themes/FileWidget/FileWidget.tsx new file mode 100644 index 000000000..4bd934b4b --- /dev/null +++ b/spiffworkflow-frontend/src/themes/FileWidget/FileWidget.tsx @@ -0,0 +1,14 @@ +import React from "react"; +import { getTemplate, WidgetProps } from "@rjsf/utils"; + +const FileWidget = (props: WidgetProps) => { + const { options, registry } = props; + const BaseInputTemplate = getTemplate<"BaseInputTemplate">( + "BaseInputTemplate", + registry, + options + ); + return ; +}; + +export default FileWidget; diff --git a/spiffworkflow-frontend/src/themes/FileWidget/index.ts b/spiffworkflow-frontend/src/themes/FileWidget/index.ts new file mode 100644 index 000000000..e70174ced --- /dev/null +++ b/spiffworkflow-frontend/src/themes/FileWidget/index.ts @@ -0,0 +1,2 @@ +export { default } from "./FileWidget"; +export * from "./FileWidget"; diff --git a/spiffworkflow-frontend/src/themes/Form/Form.tsx b/spiffworkflow-frontend/src/themes/Form/Form.tsx new file mode 100644 index 000000000..e19361924 --- /dev/null +++ b/spiffworkflow-frontend/src/themes/Form/Form.tsx @@ -0,0 +1,7 @@ +import { withTheme, FormProps } from "@rjsf/core"; + +import Theme from "../Theme"; + +const Form: React.ComponentType = withTheme(Theme); + +export default Form; diff --git a/spiffworkflow-frontend/src/themes/Form/index.ts b/spiffworkflow-frontend/src/themes/Form/index.ts new file mode 100644 index 000000000..dbca2de64 --- /dev/null +++ b/spiffworkflow-frontend/src/themes/Form/index.ts @@ -0,0 +1,2 @@ +export { default } from "./Form"; +export * from "./Form"; diff --git a/spiffworkflow-frontend/src/themes/IconButton/IconButton.tsx b/spiffworkflow-frontend/src/themes/IconButton/IconButton.tsx new file mode 100644 index 000000000..6a8e00fe4 --- /dev/null +++ b/spiffworkflow-frontend/src/themes/IconButton/IconButton.tsx @@ -0,0 +1,43 @@ +import React from "react"; +import { IconButtonProps } from "@rjsf/utils"; +import Button, { ButtonProps } from "react-bootstrap/Button"; +import { IoIosRemove } from "@react-icons/all-files/io/IoIosRemove"; +import { AiOutlineArrowUp } from "@react-icons/all-files/ai/AiOutlineArrowUp"; +import { AiOutlineArrowDown } from "@react-icons/all-files/ai/AiOutlineArrowDown"; + +const IconButton = (props: IconButtonProps & ButtonProps) => { + const { icon, iconType, className, uiSchema, ...otherProps } = props; + return ( + + ); +}; + +export default IconButton; + +export function MoveDownButton(props: IconButtonProps) { + return ( + } /> + ); +} + +export function MoveUpButton(props: IconButtonProps) { + return } />; +} + +export function RemoveButton(props: IconButtonProps) { + return ( + } + /> + ); +} diff --git a/spiffworkflow-frontend/src/themes/IconButton/index.ts b/spiffworkflow-frontend/src/themes/IconButton/index.ts new file mode 100644 index 000000000..55447475b --- /dev/null +++ b/spiffworkflow-frontend/src/themes/IconButton/index.ts @@ -0,0 +1,2 @@ +export { default } from "./IconButton"; +export * from "./IconButton"; diff --git a/spiffworkflow-frontend/src/themes/ObjectFieldTemplate/ObjectFieldTemplate.tsx b/spiffworkflow-frontend/src/themes/ObjectFieldTemplate/ObjectFieldTemplate.tsx new file mode 100644 index 000000000..83008ec06 --- /dev/null +++ b/spiffworkflow-frontend/src/themes/ObjectFieldTemplate/ObjectFieldTemplate.tsx @@ -0,0 +1,91 @@ +import React from "react"; + +import Row from "react-bootstrap/Row"; +import Col from "react-bootstrap/Col"; +import Container from "react-bootstrap/Container"; + +import { + canExpand, + getTemplate, + getUiOptions, + ObjectFieldTemplateProps, +} from "@rjsf/utils"; + +const ObjectFieldTemplate = ({ + description, + title, + properties, + required, + uiSchema, + idSchema, + schema, + formData, + onAddClick, + disabled, + readonly, + registry, +}: ObjectFieldTemplateProps) => { + const uiOptions = getUiOptions(uiSchema); + const TitleFieldTemplate = getTemplate<"TitleFieldTemplate">( + "TitleFieldTemplate", + registry, + uiOptions + ); + const DescriptionFieldTemplate = getTemplate<"DescriptionFieldTemplate">( + "DescriptionFieldTemplate", + registry, + uiOptions + ); + // Button templates are not overridden in the uiSchema + const { + ButtonTemplates: { AddButton }, + } = registry.templates; + return ( + <> + {(uiOptions.title || title) && ( + + )} + {(uiOptions.description || description) && ( + + )} + + {properties.map((element: any, index: number) => ( + + {element.content} + + ))} + {canExpand(schema, uiSchema, formData) ? ( + + + + + + ) : null} + + + ); +}; + +export default ObjectFieldTemplate; diff --git a/spiffworkflow-frontend/src/themes/ObjectFieldTemplate/index.ts b/spiffworkflow-frontend/src/themes/ObjectFieldTemplate/index.ts new file mode 100644 index 000000000..b7e3ae624 --- /dev/null +++ b/spiffworkflow-frontend/src/themes/ObjectFieldTemplate/index.ts @@ -0,0 +1,2 @@ +export { default } from "./ObjectFieldTemplate"; +export * from "./ObjectFieldTemplate"; diff --git a/spiffworkflow-frontend/src/themes/RadioWidget/RadioWidget.tsx b/spiffworkflow-frontend/src/themes/RadioWidget/RadioWidget.tsx new file mode 100644 index 000000000..715a66e1d --- /dev/null +++ b/spiffworkflow-frontend/src/themes/RadioWidget/RadioWidget.tsx @@ -0,0 +1,65 @@ +import React from "react"; + +import Form from "react-bootstrap/Form"; + +import { WidgetProps } from "@rjsf/utils"; + +const RadioWidget = ({ + id, + schema, + options, + value, + required, + disabled, + readonly, + onChange, + onBlur, + onFocus, +}: WidgetProps) => { + const { enumOptions, enumDisabled } = options; + + const _onChange = ({ + target: { value }, + }: React.ChangeEvent) => + onChange(schema.type == "boolean" ? value !== "false" : value); + const _onBlur = ({ target: { value } }: React.FocusEvent) => + onBlur(id, value); + const _onFocus = ({ + target: { value }, + }: React.FocusEvent) => onFocus(id, value); + + const inline = Boolean(options && options.inline); + + return ( + + {Array.isArray(enumOptions) && + enumOptions.map((option) => { + const itemDisabled = + Array.isArray(enumDisabled) && + enumDisabled.indexOf(option.value) !== -1; + const checked = option.value == value; + + const radio = ( + + ); + return radio; + })} + + ); +}; + +export default RadioWidget; diff --git a/spiffworkflow-frontend/src/themes/RadioWidget/index.ts b/spiffworkflow-frontend/src/themes/RadioWidget/index.ts new file mode 100644 index 000000000..f0568f0d8 --- /dev/null +++ b/spiffworkflow-frontend/src/themes/RadioWidget/index.ts @@ -0,0 +1,2 @@ +export { default } from "./RadioWidget"; +export * from "./RadioWidget"; diff --git a/spiffworkflow-frontend/src/themes/RangeWidget/RangeWidget.tsx b/spiffworkflow-frontend/src/themes/RangeWidget/RangeWidget.tsx new file mode 100644 index 000000000..f75d3756c --- /dev/null +++ b/spiffworkflow-frontend/src/themes/RangeWidget/RangeWidget.tsx @@ -0,0 +1,18 @@ +import React from "react"; +import { getTemplate, WidgetProps } from "@rjsf/utils"; + +const RangeWidget = (props: WidgetProps) => { + const { value, label, options, registry } = props; + const BaseInputTemplate = getTemplate<"BaseInputTemplate">( + "BaseInputTemplate", + registry, + options + ); + return ( + + {value} + + ); +}; + +export default RangeWidget; diff --git a/spiffworkflow-frontend/src/themes/RangeWidget/index.ts b/spiffworkflow-frontend/src/themes/RangeWidget/index.ts new file mode 100644 index 000000000..70a8e7601 --- /dev/null +++ b/spiffworkflow-frontend/src/themes/RangeWidget/index.ts @@ -0,0 +1,2 @@ +export { default } from "./RangeWidget"; +export * from "./RangeWidget"; diff --git a/spiffworkflow-frontend/src/themes/SelectWidget/SelectWidget.tsx b/spiffworkflow-frontend/src/themes/SelectWidget/SelectWidget.tsx new file mode 100644 index 000000000..07864f0e6 --- /dev/null +++ b/spiffworkflow-frontend/src/themes/SelectWidget/SelectWidget.tsx @@ -0,0 +1,89 @@ +import React from "react"; + +import Form from "react-bootstrap/Form"; + +import { processSelectValue, WidgetProps } from "@rjsf/utils"; + +const SelectWidget = ({ + schema, + id, + options, + required, + disabled, + readonly, + value, + multiple, + autofocus, + onChange, + onBlur, + onFocus, + placeholder, + rawErrors = [], +}: WidgetProps) => { + const { enumOptions, enumDisabled } = options; + + const emptyValue = multiple ? [] : ""; + + function getValue( + event: React.FocusEvent | React.ChangeEvent | any, + multiple?: boolean + ) { + if (multiple) { + return [].slice + .call(event.target.options as any) + .filter((o: any) => o.selected) + .map((o: any) => o.value); + } else { + return event.target.value; + } + } + + return ( + 0 ? "is-invalid" : ""} + onBlur={ + onBlur && + ((event: React.FocusEvent) => { + const newValue = getValue(event, multiple); + onBlur(id, processSelectValue(schema, newValue, options)); + }) + } + onFocus={ + onFocus && + ((event: React.FocusEvent) => { + const newValue = getValue(event, multiple); + onFocus(id, processSelectValue(schema, newValue, options)); + }) + } + onChange={(event: React.ChangeEvent) => { + const newValue = getValue(event, multiple); + onChange(processSelectValue(schema, newValue, options)); + }} + > + {!multiple && schema.default === undefined && ( + + )} + {(enumOptions as any).map(({ value, label }: any, i: number) => { + const disabled: any = + Array.isArray(enumDisabled) && + (enumDisabled as any).indexOf(value) != -1; + return ( + + ); + })} + + ); +}; + +export default SelectWidget; diff --git a/spiffworkflow-frontend/src/themes/SelectWidget/index.ts b/spiffworkflow-frontend/src/themes/SelectWidget/index.ts new file mode 100644 index 000000000..91a604a36 --- /dev/null +++ b/spiffworkflow-frontend/src/themes/SelectWidget/index.ts @@ -0,0 +1,2 @@ +export { default } from "./SelectWidget"; +export * from "./SelectWidget"; diff --git a/spiffworkflow-frontend/src/themes/SubmitButton/SubmitButton.tsx b/spiffworkflow-frontend/src/themes/SubmitButton/SubmitButton.tsx new file mode 100644 index 000000000..fc88cc93f --- /dev/null +++ b/spiffworkflow-frontend/src/themes/SubmitButton/SubmitButton.tsx @@ -0,0 +1,23 @@ +import React from "react"; +import Button from "react-bootstrap/Button"; +import { getSubmitButtonOptions, SubmitButtonProps } from "@rjsf/utils"; + +const SubmitButton: React.ComponentType = (props) => { + const { + submitText, + norender, + props: submitButtonProps, + } = getSubmitButtonOptions(props.uiSchema); + if (norender) { + return null; + } + return ( +
+ +
+ ); +}; + +export default SubmitButton; diff --git a/spiffworkflow-frontend/src/themes/SubmitButton/index.ts b/spiffworkflow-frontend/src/themes/SubmitButton/index.ts new file mode 100644 index 000000000..467dba249 --- /dev/null +++ b/spiffworkflow-frontend/src/themes/SubmitButton/index.ts @@ -0,0 +1,2 @@ +export { default } from "./SubmitButton"; +export * from "./SubmitButton"; diff --git a/spiffworkflow-frontend/src/themes/Templates/Templates.ts b/spiffworkflow-frontend/src/themes/Templates/Templates.ts new file mode 100644 index 000000000..e8eef55a0 --- /dev/null +++ b/spiffworkflow-frontend/src/themes/Templates/Templates.ts @@ -0,0 +1,35 @@ +import AddButton from "../AddButton"; +import ArrayFieldItemTemplate from "../ArrayFieldItemTemplate"; +import ArrayFieldTemplate from "../ArrayFieldTemplate"; +import BaseInputTemplate from "../BaseInputTemplate/BaseInputTemplate"; +import DescriptionField from "../DescriptionField"; +import ErrorList from "../ErrorList"; +import { MoveDownButton, MoveUpButton, RemoveButton } from "../IconButton"; +import FieldErrorTemplate from "../FieldErrorTemplate"; +import FieldHelpTemplate from "../FieldHelpTemplate"; +import FieldTemplate from "../FieldTemplate"; +import ObjectFieldTemplate from "../ObjectFieldTemplate"; +import SubmitButton from "../SubmitButton"; +import TitleField from "../TitleField"; +import WrapIfAdditionalTemplate from "../WrapIfAdditionalTemplate"; + +export default { + ArrayFieldItemTemplate, + ArrayFieldTemplate, + BaseInputTemplate, + ButtonTemplates: { + AddButton, + MoveDownButton, + MoveUpButton, + RemoveButton, + SubmitButton, + }, + DescriptionFieldTemplate: DescriptionField, + ErrorListTemplate: ErrorList, + FieldErrorTemplate, + FieldHelpTemplate, + FieldTemplate, + ObjectFieldTemplate, + TitleFieldTemplate: TitleField, + WrapIfAdditionalTemplate, +}; diff --git a/spiffworkflow-frontend/src/themes/Templates/index.ts b/spiffworkflow-frontend/src/themes/Templates/index.ts new file mode 100644 index 000000000..0c3e935ca --- /dev/null +++ b/spiffworkflow-frontend/src/themes/Templates/index.ts @@ -0,0 +1,2 @@ +export { default } from "./Templates"; +export * from "./Templates"; diff --git a/spiffworkflow-frontend/src/themes/TextareaWidget/TextareaWidget.tsx b/spiffworkflow-frontend/src/themes/TextareaWidget/TextareaWidget.tsx new file mode 100644 index 000000000..afb2c98da --- /dev/null +++ b/spiffworkflow-frontend/src/themes/TextareaWidget/TextareaWidget.tsx @@ -0,0 +1,56 @@ +import React from "react"; + +import { WidgetProps } from "@rjsf/utils"; +import FormControl from "react-bootstrap/FormControl"; +import InputGroup from "react-bootstrap/InputGroup"; + +type CustomWidgetProps = WidgetProps & { + options: any; +}; + +const TextareaWidget = ({ + id, + placeholder, + value, + required, + disabled, + autofocus, + readonly, + onBlur, + onFocus, + onChange, + options, +}: CustomWidgetProps) => { + const _onChange = ({ + target: { value }, + }: React.ChangeEvent) => + onChange(value === "" ? options.emptyValue : value); + const _onBlur = ({ + target: { value }, + }: React.FocusEvent) => onBlur(id, value); + const _onFocus = ({ + target: { value }, + }: React.FocusEvent) => onFocus(id, value); + + return ( + + + + ); +}; + +export default TextareaWidget; diff --git a/spiffworkflow-frontend/src/themes/TextareaWidget/index.ts b/spiffworkflow-frontend/src/themes/TextareaWidget/index.ts new file mode 100644 index 000000000..1c7268c66 --- /dev/null +++ b/spiffworkflow-frontend/src/themes/TextareaWidget/index.ts @@ -0,0 +1,2 @@ +export { default } from "./TextareaWidget"; +export * from "./TextareaWidget"; diff --git a/spiffworkflow-frontend/src/themes/Theme/Theme.tsx b/spiffworkflow-frontend/src/themes/Theme/Theme.tsx new file mode 100644 index 000000000..ecfcdd572 --- /dev/null +++ b/spiffworkflow-frontend/src/themes/Theme/Theme.tsx @@ -0,0 +1,11 @@ +import { ThemeProps } from "@rjsf/core"; + +import Templates from "../Templates"; +import Widgets from "../Widgets"; + +const Theme: ThemeProps = { + templates: Templates, + widgets: Widgets, +}; + +export default Theme; diff --git a/spiffworkflow-frontend/src/themes/Theme/index.ts b/spiffworkflow-frontend/src/themes/Theme/index.ts new file mode 100644 index 000000000..491c3a07c --- /dev/null +++ b/spiffworkflow-frontend/src/themes/Theme/index.ts @@ -0,0 +1,2 @@ +export { default } from "./Theme"; +export * from "./Theme"; diff --git a/spiffworkflow-frontend/src/themes/TitleField/TitleField.tsx b/spiffworkflow-frontend/src/themes/TitleField/TitleField.tsx new file mode 100644 index 000000000..4606e0d15 --- /dev/null +++ b/spiffworkflow-frontend/src/themes/TitleField/TitleField.tsx @@ -0,0 +1,13 @@ +import React from "react"; +import { TitleFieldProps } from "@rjsf/utils"; + +const TitleField = ({ id, title, uiSchema }: TitleFieldProps) => ( + <> +
+
{(uiSchema && uiSchema["ui:title"]) || title}
+
+
+ +); + +export default TitleField; diff --git a/spiffworkflow-frontend/src/themes/TitleField/index.ts b/spiffworkflow-frontend/src/themes/TitleField/index.ts new file mode 100644 index 000000000..2e26cd18f --- /dev/null +++ b/spiffworkflow-frontend/src/themes/TitleField/index.ts @@ -0,0 +1,2 @@ +export { default } from "./TitleField"; +export * from "./TitleField"; diff --git a/spiffworkflow-frontend/src/themes/Widgets/Widgets.ts b/spiffworkflow-frontend/src/themes/Widgets/Widgets.ts new file mode 100644 index 000000000..543a05ec3 --- /dev/null +++ b/spiffworkflow-frontend/src/themes/Widgets/Widgets.ts @@ -0,0 +1,17 @@ +import CheckboxWidget from "../CheckboxWidget/CheckboxWidget"; +import CheckboxesWidget from "../CheckboxesWidget/CheckboxesWidget"; +import RadioWidget from "../RadioWidget/RadioWidget"; +import RangeWidget from "../RangeWidget/RangeWidget"; +import SelectWidget from "../SelectWidget/SelectWidget"; +import TextareaWidget from "../TextareaWidget/TextareaWidget"; +import FileWidget from "../FileWidget/FileWidget"; + +export default { + CheckboxWidget, + CheckboxesWidget, + RadioWidget, + RangeWidget, + SelectWidget, + TextareaWidget, + FileWidget, +}; diff --git a/spiffworkflow-frontend/src/themes/Widgets/index.ts b/spiffworkflow-frontend/src/themes/Widgets/index.ts new file mode 100644 index 000000000..595580b54 --- /dev/null +++ b/spiffworkflow-frontend/src/themes/Widgets/index.ts @@ -0,0 +1,2 @@ +export { default } from "./Widgets"; +export * from "./Widgets"; diff --git a/spiffworkflow-frontend/src/themes/WrapIfAdditionalTemplate/WrapIfAdditionalTemplate.tsx b/spiffworkflow-frontend/src/themes/WrapIfAdditionalTemplate/WrapIfAdditionalTemplate.tsx new file mode 100644 index 000000000..3eafe9069 --- /dev/null +++ b/spiffworkflow-frontend/src/themes/WrapIfAdditionalTemplate/WrapIfAdditionalTemplate.tsx @@ -0,0 +1,69 @@ +import React from "react"; + +import { + ADDITIONAL_PROPERTY_FLAG, + WrapIfAdditionalTemplateProps, +} from "@rjsf/utils"; + +import Row from "react-bootstrap/Row"; +import Col from "react-bootstrap/Col"; +import Form from "react-bootstrap/Form"; + +const WrapIfAdditionalTemplate = ({ + classNames, + children, + disabled, + id, + label, + onDropPropertyClick, + onKeyChange, + readonly, + required, + schema, + uiSchema, + registry, +}: WrapIfAdditionalTemplateProps) => { + // Button templates are not overridden in the uiSchema + const { RemoveButton } = registry.templates.ButtonTemplates; + const keyLabel = `${label} Key`; // i18n ? + const additional = ADDITIONAL_PROPERTY_FLAG in schema; + + if (!additional) { + return
{children}
; + } + + const handleBlur = ({ target }: React.FocusEvent) => + onKeyChange(target.value); + const keyId = `${id}-key`; + + return ( + + + + {keyLabel} + + + + {children} + + + + + ); +}; + +export default WrapIfAdditionalTemplate; diff --git a/spiffworkflow-frontend/src/themes/WrapIfAdditionalTemplate/index.ts b/spiffworkflow-frontend/src/themes/WrapIfAdditionalTemplate/index.ts new file mode 100644 index 000000000..95ba7de22 --- /dev/null +++ b/spiffworkflow-frontend/src/themes/WrapIfAdditionalTemplate/index.ts @@ -0,0 +1,2 @@ +export { default } from "./WrapIfAdditionalTemplate"; +export * from "./WrapIfAdditionalTemplate"; diff --git a/spiffworkflow-frontend/src/themes/index.ts b/spiffworkflow-frontend/src/themes/index.ts new file mode 100644 index 000000000..2f409639e --- /dev/null +++ b/spiffworkflow-frontend/src/themes/index.ts @@ -0,0 +1,8 @@ +import Form from './Form/Form'; + +export { default as Form } from './Form'; +export { default as Templates } from './Templates'; +export { default as Theme } from './Theme'; +export { default as Widgets } from './Widgets'; + +export default Form; From ddce5fcec1d7f8920f513318ec6c1369ff704655 Mon Sep 17 00:00:00 2001 From: jasquat Date: Wed, 16 Nov 2022 13:52:44 -0500 Subject: [PATCH 02/10] theme working with mui from the internet w/ burnettk cullerton --- spiffworkflow-frontend/package-lock.json | 834 +++++++++++++++--- spiffworkflow-frontend/package.json | 5 +- .../src/routes/TaskShow.tsx | 6 +- .../src/themes/AddButton/AddButton.tsx | 20 - .../src/themes/AddButton/index.ts | 2 - .../ArrayFieldItemTemplate.tsx | 77 -- .../themes/ArrayFieldItemTemplate/index.ts | 2 - .../ArrayFieldTemplate/ArrayFieldTemplate.tsx | 97 -- .../src/themes/ArrayFieldTemplate/index.ts | 2 - .../BaseInputTemplate/BaseInputTemplate.tsx | 67 -- .../src/themes/BaseInputTemplate/index.ts | 2 - .../themes/CheckboxWidget/CheckboxWidget.tsx | 53 -- .../src/themes/CheckboxWidget/index.ts | 2 - .../CheckboxesWidget/CheckboxesWidget.tsx | 83 -- .../src/themes/CheckboxesWidget/index.ts | 2 - .../DescriptionField/DescriptionField.tsx | 18 - .../src/themes/DescriptionField/index.ts | 2 - .../src/themes/ErrorList/ErrorList.tsx | 25 - .../src/themes/ErrorList/index.ts | 2 - .../FieldErrorTemplate/FieldErrorTemplate.tsx | 27 - .../src/themes/FieldErrorTemplate/index.ts | 2 - .../FieldHelpTemplate/FieldHelpTemplate.tsx | 20 - .../src/themes/FieldHelpTemplate/index.ts | 2 - .../themes/FieldTemplate/FieldTemplate.tsx | 73 -- .../src/themes/FieldTemplate/index.ts | 2 - .../src/themes/FileWidget/FileWidget.tsx | 14 - .../src/themes/FileWidget/index.ts | 2 - .../src/themes/Form/Form.tsx | 7 - .../src/themes/Form/index.ts | 2 - .../src/themes/IconButton/IconButton.tsx | 43 - .../src/themes/IconButton/index.ts | 2 - .../ObjectFieldTemplate.tsx | 91 -- .../src/themes/ObjectFieldTemplate/index.ts | 2 - .../src/themes/RadioWidget/RadioWidget.tsx | 65 -- .../src/themes/RadioWidget/index.ts | 2 - .../src/themes/RangeWidget/RangeWidget.tsx | 18 - .../src/themes/RangeWidget/index.ts | 2 - .../src/themes/SelectWidget/SelectWidget.tsx | 89 -- .../src/themes/SelectWidget/index.ts | 2 - .../src/themes/SubmitButton/SubmitButton.tsx | 23 - .../src/themes/SubmitButton/index.ts | 2 - .../src/themes/Templates/Templates.ts | 35 - .../src/themes/Templates/index.ts | 2 - .../themes/TextareaWidget/TextareaWidget.tsx | 56 -- .../src/themes/TextareaWidget/index.ts | 2 - .../src/themes/Theme/Theme.tsx | 11 - .../src/themes/Theme/index.ts | 2 - .../src/themes/TitleField/TitleField.tsx | 13 - .../src/themes/TitleField/index.ts | 2 - .../src/themes/Widgets/Widgets.ts | 17 - .../src/themes/Widgets/index.ts | 2 - .../WrapIfAdditionalTemplate.tsx | 69 -- .../themes/WrapIfAdditionalTemplate/index.ts | 2 - spiffworkflow-frontend/src/themes/index.ts | 8 - 54 files changed, 741 insertions(+), 1273 deletions(-) delete mode 100644 spiffworkflow-frontend/src/themes/AddButton/AddButton.tsx delete mode 100644 spiffworkflow-frontend/src/themes/AddButton/index.ts delete mode 100644 spiffworkflow-frontend/src/themes/ArrayFieldItemTemplate/ArrayFieldItemTemplate.tsx delete mode 100644 spiffworkflow-frontend/src/themes/ArrayFieldItemTemplate/index.ts delete mode 100644 spiffworkflow-frontend/src/themes/ArrayFieldTemplate/ArrayFieldTemplate.tsx delete mode 100644 spiffworkflow-frontend/src/themes/ArrayFieldTemplate/index.ts delete mode 100644 spiffworkflow-frontend/src/themes/BaseInputTemplate/BaseInputTemplate.tsx delete mode 100644 spiffworkflow-frontend/src/themes/BaseInputTemplate/index.ts delete mode 100644 spiffworkflow-frontend/src/themes/CheckboxWidget/CheckboxWidget.tsx delete mode 100644 spiffworkflow-frontend/src/themes/CheckboxWidget/index.ts delete mode 100644 spiffworkflow-frontend/src/themes/CheckboxesWidget/CheckboxesWidget.tsx delete mode 100644 spiffworkflow-frontend/src/themes/CheckboxesWidget/index.ts delete mode 100644 spiffworkflow-frontend/src/themes/DescriptionField/DescriptionField.tsx delete mode 100644 spiffworkflow-frontend/src/themes/DescriptionField/index.ts delete mode 100644 spiffworkflow-frontend/src/themes/ErrorList/ErrorList.tsx delete mode 100644 spiffworkflow-frontend/src/themes/ErrorList/index.ts delete mode 100644 spiffworkflow-frontend/src/themes/FieldErrorTemplate/FieldErrorTemplate.tsx delete mode 100644 spiffworkflow-frontend/src/themes/FieldErrorTemplate/index.ts delete mode 100644 spiffworkflow-frontend/src/themes/FieldHelpTemplate/FieldHelpTemplate.tsx delete mode 100644 spiffworkflow-frontend/src/themes/FieldHelpTemplate/index.ts delete mode 100644 spiffworkflow-frontend/src/themes/FieldTemplate/FieldTemplate.tsx delete mode 100644 spiffworkflow-frontend/src/themes/FieldTemplate/index.ts delete mode 100644 spiffworkflow-frontend/src/themes/FileWidget/FileWidget.tsx delete mode 100644 spiffworkflow-frontend/src/themes/FileWidget/index.ts delete mode 100644 spiffworkflow-frontend/src/themes/Form/Form.tsx delete mode 100644 spiffworkflow-frontend/src/themes/Form/index.ts delete mode 100644 spiffworkflow-frontend/src/themes/IconButton/IconButton.tsx delete mode 100644 spiffworkflow-frontend/src/themes/IconButton/index.ts delete mode 100644 spiffworkflow-frontend/src/themes/ObjectFieldTemplate/ObjectFieldTemplate.tsx delete mode 100644 spiffworkflow-frontend/src/themes/ObjectFieldTemplate/index.ts delete mode 100644 spiffworkflow-frontend/src/themes/RadioWidget/RadioWidget.tsx delete mode 100644 spiffworkflow-frontend/src/themes/RadioWidget/index.ts delete mode 100644 spiffworkflow-frontend/src/themes/RangeWidget/RangeWidget.tsx delete mode 100644 spiffworkflow-frontend/src/themes/RangeWidget/index.ts delete mode 100644 spiffworkflow-frontend/src/themes/SelectWidget/SelectWidget.tsx delete mode 100644 spiffworkflow-frontend/src/themes/SelectWidget/index.ts delete mode 100644 spiffworkflow-frontend/src/themes/SubmitButton/SubmitButton.tsx delete mode 100644 spiffworkflow-frontend/src/themes/SubmitButton/index.ts delete mode 100644 spiffworkflow-frontend/src/themes/Templates/Templates.ts delete mode 100644 spiffworkflow-frontend/src/themes/Templates/index.ts delete mode 100644 spiffworkflow-frontend/src/themes/TextareaWidget/TextareaWidget.tsx delete mode 100644 spiffworkflow-frontend/src/themes/TextareaWidget/index.ts delete mode 100644 spiffworkflow-frontend/src/themes/Theme/Theme.tsx delete mode 100644 spiffworkflow-frontend/src/themes/Theme/index.ts delete mode 100644 spiffworkflow-frontend/src/themes/TitleField/TitleField.tsx delete mode 100644 spiffworkflow-frontend/src/themes/TitleField/index.ts delete mode 100644 spiffworkflow-frontend/src/themes/Widgets/Widgets.ts delete mode 100644 spiffworkflow-frontend/src/themes/Widgets/index.ts delete mode 100644 spiffworkflow-frontend/src/themes/WrapIfAdditionalTemplate/WrapIfAdditionalTemplate.tsx delete mode 100644 spiffworkflow-frontend/src/themes/WrapIfAdditionalTemplate/index.ts delete mode 100644 spiffworkflow-frontend/src/themes/index.ts diff --git a/spiffworkflow-frontend/package-lock.json b/spiffworkflow-frontend/package-lock.json index 5dc7f8027..f03d57818 100644 --- a/spiffworkflow-frontend/package-lock.json +++ b/spiffworkflow-frontend/package-lock.json @@ -18,8 +18,11 @@ "@casl/react": "^3.1.0", "@ginkgo-bioworks/react-json-schema-form-builder": "^2.9.0", "@monaco-editor/react": "^4.4.5", - "@rjsf/core": "^4.2.0", + "@react-icons/all-files": "^4.1.0", + "@rjsf/core": "*", + "@rjsf/mui": "^5.0.0-beta.13", "@rjsf/utils": "^5.0.0-beta.13", + "@rjsf/validator-ajv8": "^5.0.0-beta.13", "@tanstack/react-table": "^8.2.2", "@testing-library/jest-dom": "^5.16.4", "@testing-library/react": "^13.3.0", @@ -1960,11 +1963,11 @@ } }, "node_modules/@babel/runtime": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.18.9.tgz", - "integrity": "sha512-lkqXDcvlFT5rvEjiu6+QYO+1GXrEHRo2LOtS7E4GtX5ESIZOgepqsZBVIj6Pv+a6zqsya9VCgiK1KAK4BvJDAw==", + "version": "7.20.1", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.1.tgz", + "integrity": "sha512-mrzLkl6U9YLF8qpqI7TB82PESyEGjm/0Ly91jG575eVxMMlb8fYfOXFZIJ8XfLrJZQbm7dlKry2bJmXBUEkdFg==", "dependencies": { - "regenerator-runtime": "^0.13.4" + "regenerator-runtime": "^0.13.10" }, "engines": { "node": ">=6.9.0" @@ -2749,22 +2752,22 @@ } }, "node_modules/@emotion/babel-plugin": { - "version": "11.10.2", - "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.10.2.tgz", - "integrity": "sha512-xNQ57njWTFVfPAc3cjfuaPdsgLp5QOSuRsj9MA6ndEhH/AzuZM86qIQzt6rq+aGBwj3n5/TkLmU5lhAfdRmogA==", + "version": "11.10.5", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.10.5.tgz", + "integrity": "sha512-xE7/hyLHJac7D2Ve9dKroBBZqBT7WuPQmWcq7HSGb84sUuP4mlOWoB8dvVfD9yk5DHkU1m6RW7xSoDtnQHNQeA==", "dependencies": { "@babel/helper-module-imports": "^7.16.7", "@babel/plugin-syntax-jsx": "^7.17.12", "@babel/runtime": "^7.18.3", "@emotion/hash": "^0.9.0", "@emotion/memoize": "^0.8.0", - "@emotion/serialize": "^1.1.0", + "@emotion/serialize": "^1.1.1", "babel-plugin-macros": "^3.1.0", "convert-source-map": "^1.5.0", "escape-string-regexp": "^4.0.0", "find-root": "^1.1.0", "source-map": "^0.5.7", - "stylis": "4.0.13" + "stylis": "4.1.3" }, "peerDependencies": { "@babel/core": "^7.0.0" @@ -2795,15 +2798,15 @@ } }, "node_modules/@emotion/cache": { - "version": "11.10.3", - "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.10.3.tgz", - "integrity": "sha512-Psmp/7ovAa8appWh3g51goxu/z3iVms7JXOreq136D8Bbn6dYraPnmL6mdM8GThEx9vwSn92Fz+mGSjBzN8UPQ==", + "version": "11.10.5", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.10.5.tgz", + "integrity": "sha512-dGYHWyzTdmK+f2+EnIGBpkz1lKc4Zbj2KHd4cX3Wi8/OWr5pKslNjc3yABKH4adRGCvSX4VDC0i04mrrq0aiRA==", "dependencies": { "@emotion/memoize": "^0.8.0", - "@emotion/sheet": "^1.2.0", + "@emotion/sheet": "^1.2.1", "@emotion/utils": "^1.2.0", "@emotion/weak-memoize": "^0.3.0", - "stylis": "4.0.13" + "stylis": "4.1.3" } }, "node_modules/@emotion/cache/node_modules/@emotion/memoize": { @@ -2856,9 +2859,9 @@ } }, "node_modules/@emotion/serialize": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.0.tgz", - "integrity": "sha512-F1ZZZW51T/fx+wKbVlwsfchr5q97iW8brAnXmsskz4d0hVB4O3M/SiA3SaeH06x02lSNzkkQv+n3AX3kCXKSFA==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.1.tgz", + "integrity": "sha512-Zl/0LFggN7+L1liljxXdsVSVlg6E/Z/olVWpfxUTxOAmi8NU7YoeWeLfi1RmnB2TATHoaWwIBRoL+FvAJiTUQA==", "dependencies": { "@emotion/hash": "^0.9.0", "@emotion/memoize": "^0.8.0", @@ -2873,15 +2876,66 @@ "integrity": "sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA==" }, "node_modules/@emotion/sheet": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.1.tgz", + "integrity": "sha512-zxRBwl93sHMsOj4zs+OslQKg/uhF38MB+OMKoCrVuS0nyTkqnau+BM3WGEoOptg9Oz45T/aIGs1qbVAsEFo3nA==" + }, + "node_modules/@emotion/styled": { + "version": "11.10.5", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.10.5.tgz", + "integrity": "sha512-8EP6dD7dMkdku2foLoruPCNkRevzdcBaY6q0l0OsbyJK+x8D9HWjX27ARiSIKNF634hY9Zdoedh8bJCiva8yZw==", + "peer": true, + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.10.5", + "@emotion/is-prop-valid": "^1.2.0", + "@emotion/serialize": "^1.1.1", + "@emotion/use-insertion-effect-with-fallbacks": "^1.0.0", + "@emotion/utils": "^1.2.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0", + "@emotion/react": "^11.0.0-rc.0", + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/styled/node_modules/@emotion/is-prop-valid": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.0.tgz", - "integrity": "sha512-OiTkRgpxescko+M51tZsMq7Puu/KP55wMT8BgpcXVG2hqXc0Vo0mfymJ/Uj24Hp0i083ji/o0aLddh08UEjq8w==" + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.0.tgz", + "integrity": "sha512-3aDpDprjM0AwaxGE09bOPkNxHpBd+kA6jty3RnaEXdweX1DF1U3VQpPYb0g1IStAuK7SVQ1cy+bNBBKp4W3Fjg==", + "peer": true, + "dependencies": { + "@emotion/memoize": "^0.8.0" + } + }, + "node_modules/@emotion/styled/node_modules/@emotion/memoize": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.0.tgz", + "integrity": "sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA==", + "peer": true }, "node_modules/@emotion/unitless": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.0.tgz", "integrity": "sha512-VINS5vEYAscRl2ZUDiT3uMPlrFQupiKgHz5AA4bCH1miKBg4qtwkim1qPmJj/4WG6TreYMY111rEFsjupcOKHw==" }, + "node_modules/@emotion/use-insertion-effect-with-fallbacks": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.0.tgz", + "integrity": "sha512-1eEgUGmkaljiBnRMTdksDV1W4kUnmwgp7X9G8B++9GYwl1lUdqSndSriIrTJ0N7LQaoauY9JJ2yhiOYK5+NI4A==", + "peer": true, + "peerDependencies": { + "react": ">=16.8.0" + } + }, "node_modules/@emotion/utils": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.0.tgz", @@ -4389,6 +4443,289 @@ "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, + "node_modules/@mui/base": { + "version": "5.0.0-alpha.106", + "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-alpha.106.tgz", + "integrity": "sha512-xJQQtwPCPwr6hGWTBdvDwHYwExn3Bw7nPQkN8Fuz8kHpZqoMVWQvvaFS557AIkkI2AFLV3DxVIMjbCvrIntBWg==", + "peer": true, + "dependencies": { + "@babel/runtime": "^7.20.1", + "@emotion/is-prop-valid": "^1.2.0", + "@mui/types": "^7.2.1", + "@mui/utils": "^5.10.14", + "@popperjs/core": "^2.11.6", + "clsx": "^1.2.1", + "prop-types": "^15.8.1", + "react-is": "^18.2.0" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "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/base/node_modules/@emotion/is-prop-valid": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.0.tgz", + "integrity": "sha512-3aDpDprjM0AwaxGE09bOPkNxHpBd+kA6jty3RnaEXdweX1DF1U3VQpPYb0g1IStAuK7SVQ1cy+bNBBKp4W3Fjg==", + "peer": true, + "dependencies": { + "@emotion/memoize": "^0.8.0" + } + }, + "node_modules/@mui/base/node_modules/@emotion/memoize": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.0.tgz", + "integrity": "sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA==", + "peer": true + }, + "node_modules/@mui/base/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "peer": true + }, + "node_modules/@mui/core-downloads-tracker": { + "version": "5.10.14", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.10.14.tgz", + "integrity": "sha512-qLgIJNOR9Dre8JiZ/neVzOf4jf88J6YtOkQqugtMrleLjbfRVUSS4LWl9CSOjNq76quYdmYWnSDgfQqOooT2cQ==", + "peer": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + } + }, + "node_modules/@mui/icons-material": { + "version": "5.10.14", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.10.14.tgz", + "integrity": "sha512-qtH60slQa+7MZRn6kyui8rKuoGDglPqaHX+pzBKNvd8JCOlrnfY5DmGGDdToTXyXl8xJ8nhANZbrbpg7UVKq/Q==", + "peer": true, + "dependencies": { + "@babel/runtime": "^7.20.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "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.10.14", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.10.14.tgz", + "integrity": "sha512-HWzKVAykePMx54WtxVwZyL1W4k3xlHYIqwMw0CaXAvgB3UE9yjABZuuGr8vG5Z6CSNWamzd+s1x8u7pQPFl9og==", + "peer": true, + "dependencies": { + "@babel/runtime": "^7.20.1", + "@mui/base": "5.0.0-alpha.106", + "@mui/core-downloads-tracker": "^5.10.14", + "@mui/system": "^5.10.14", + "@mui/types": "^7.2.1", + "@mui/utils": "^5.10.14", + "@types/react-transition-group": "^4.4.5", + "clsx": "^1.2.1", + "csstype": "^3.1.1", + "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" + }, + "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.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "peer": true + }, + "node_modules/@mui/private-theming": { + "version": "5.10.14", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.10.14.tgz", + "integrity": "sha512-3aIBe8WK65CwAPDY8nB11hYnzE1CZMymi76UnaFrA/DdGDwl5Y8F6uB+StKrkVmsqF1po7Mp2odqVkHj320gXw==", + "peer": true, + "dependencies": { + "@babel/runtime": "^7.20.1", + "@mui/utils": "^5.10.14", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "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.10.14", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.10.14.tgz", + "integrity": "sha512-bgKdM57ExogWpIfhL/ngSlzF4FhbH00vYF+Y5VALTob4uslFqje0xzoWmbfcCn4cZt2NXxZJIwhsq4vzo5itlw==", + "peer": true, + "dependencies": { + "@babel/runtime": "^7.20.1", + "@emotion/cache": "^11.10.5", + "csstype": "^3.1.1", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "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.10.14", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.10.14.tgz", + "integrity": "sha512-2de7XCjRb1j8Od0Stmo0LwFMLpOMNT4wzfINuExXI1TVSuyxXIXUxiC5FEgJW3GMvf/a7SUR8VOiMoKlKWzukw==", + "peer": true, + "dependencies": { + "@babel/runtime": "^7.20.1", + "@mui/private-theming": "^5.10.14", + "@mui/styled-engine": "^5.10.14", + "@mui/types": "^7.2.1", + "@mui/utils": "^5.10.14", + "clsx": "^1.2.1", + "csstype": "^3.1.1", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "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.1", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.1.tgz", + "integrity": "sha512-c5mSM7ivD8EsqK6HUi9hQPr5V7TJ/IRThUQ9nWNYPdhCGriTSQV4vL6DflT99LkM+wLiIS1rVjphpEWxERep7A==", + "peer": true, + "peerDependencies": { + "@types/react": "*" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/utils": { + "version": "5.10.14", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.10.14.tgz", + "integrity": "sha512-12p59+wDZpA++XVJmKwqsZmrA1nmUQ5d0a1yQWtcDjxNyER1EDzozYN/db+FY2i5ceQh2TynPTEwGms2mXDwFg==", + "peer": true, + "dependencies": { + "@babel/runtime": "^7.20.1", + "@types/prop-types": "^15.7.5", + "@types/react-is": "^16.7.1 || ^17.0.0", + "prop-types": "^15.8.1", + "react-is": "^18.2.0" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "peerDependencies": { + "react": "^17.0.0 || ^18.0.0" + } + }, + "node_modules/@mui/utils/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "peer": true + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -4498,6 +4835,14 @@ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" } }, + "node_modules/@react-icons/all-files": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@react-icons/all-files/-/all-files-4.1.0.tgz", + "integrity": "sha512-hxBI2UOuVaI3O/BhQfhtb4kcGn9ft12RWAFVMUeNjqqhLsHvFtzIkFaptBJpFDANTKoDfdVoHTKZDlwKCACbMQ==", + "peerDependencies": { + "react": "*" + } + }, "node_modules/@restart/hooks": { "version": "0.4.7", "resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.4.7.tgz", @@ -4530,26 +4875,38 @@ } }, "node_modules/@rjsf/core": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/@rjsf/core/-/core-4.2.3.tgz", - "integrity": "sha512-dRXhd1Tac/9OcG0VDrYDF2boNTyKINEEITEtJ4L1Yce2iMVk66U52BhWKIFp/WXDM27vwnOfwQo4NwGiqeQeHw==", + "version": "5.0.0-beta.13", + "resolved": "https://registry.npmjs.org/@rjsf/core/-/core-5.0.0-beta.13.tgz", + "integrity": "sha512-uQ3A9aJhMJsz9ct5tV3ogZkSFEkKUxrM9SJ9Hc8ijxmuaW7Jv8tNv5jiWZZsLvNXlIONX83s6JqkiOJf6IOAvg==", "dependencies": { - "@types/json-schema": "^7.0.7", - "ajv": "^6.7.0", - "core-js-pure": "^3.6.5", - "json-schema-merge-allof": "^0.6.0", - "jsonpointer": "^5.0.0", "lodash": "^4.17.15", "lodash-es": "^4.17.15", - "nanoid": "^3.1.23", - "prop-types": "^15.7.2", - "react-is": "16.9.0" + "nanoid": "^3.3.4", + "prop-types": "^15.7.2" }, "engines": { - "node": ">=12" + "node": ">=14" }, "peerDependencies": { - "react": ">=16 || >=17" + "@rjsf/utils": "^5.0.0-beta.1", + "react": "^16.14.0 || >=17" + } + }, + "node_modules/@rjsf/mui": { + "version": "5.0.0-beta.13", + "resolved": "https://registry.npmjs.org/@rjsf/mui/-/mui-5.0.0-beta.13.tgz", + "integrity": "sha512-hwCtADpjNssq/CsT3Wj1FDVJfdCN3gptKedGjbusLUEwQqXoVzkzl25e/IRfN8y/JxYu4lMXDU89bN9nJSKWLA==", + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@emotion/react": "^11.7.0", + "@emotion/styled": "^11.6.0", + "@mui/icons-material": "^5.2.0", + "@mui/material": "^5.2.2", + "@rjsf/core": "^5.0.0-beta.1", + "@rjsf/utils": "^5.0.0-beta.1", + "react": ">=17" } }, "node_modules/@rjsf/utils": { @@ -4588,6 +4945,23 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" }, + "node_modules/@rjsf/validator-ajv8": { + "version": "5.0.0-beta.13", + "resolved": "https://registry.npmjs.org/@rjsf/validator-ajv8/-/validator-ajv8-5.0.0-beta.13.tgz", + "integrity": "sha512-/hrYbiwgCvEqw1Z7YZTWvd+ZAiX5vSN0WAI2hJTJTqKuCTcIH0fqNDCaOg3FBR38BL7seZrUmibIUcPU66iJ1w==", + "dependencies": { + "ajv-formats": "^2.1.1", + "ajv8": "npm:ajv@^8.11.0", + "lodash": "^4.17.15", + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@rjsf/utils": "^5.0.0-beta.12" + } + }, "node_modules/@rollup/plugin-babel": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", @@ -5543,6 +5917,15 @@ "@types/react": "*" } }, + "node_modules/@types/react-is": { + "version": "17.0.3", + "resolved": "https://registry.npmjs.org/@types/react-is/-/react-is-17.0.3.tgz", + "integrity": "sha512-aBTIWg1emtu95bLTLx0cpkxwGW3ueZv71nE2YFBpL8k/z5czEW8yYpOo8Dp+UUAFAtKwNaOsh/ioSeQnWlZcfw==", + "peer": true, + "dependencies": { + "@types/react": "*" + } + }, "node_modules/@types/react-redux": { "version": "7.1.24", "resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.24.tgz", @@ -6453,6 +6836,27 @@ "ajv": "^6.9.1" } }, + "node_modules/ajv8": { + "name": "ajv", + "version": "8.11.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.2.tgz", + "integrity": "sha512-E4bfmKAhGiSTvMfL1Myyycaub+cUEU2/IvpylXkUu7CHBkBj1f/ikdzbD7YQ6FKUbixDxeYvB/xY4fvyroDlQg==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv8/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + }, "node_modules/ansi-align": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", @@ -8569,6 +8973,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/clsx": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", + "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==", + "peer": true, + "engines": { + "node": ">=6" + } + }, "node_modules/co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", @@ -9463,9 +9876,9 @@ "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==" }, "node_modules/csstype": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.0.tgz", - "integrity": "sha512-uX1KG+x9h5hIJsaKR9xHUeUraxf8IODOwq9JLNPq6BwB04a/xgpq3rcx47l5BZu5zBPlgD342tdke3Hom/nJRA==" + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz", + "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==" }, "node_modules/cyclist": { "version": "1.0.1", @@ -18733,16 +19146,6 @@ "lodash": "^4.17.4" } }, - "node_modules/json-schema-merge-allof": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/json-schema-merge-allof/-/json-schema-merge-allof-0.6.0.tgz", - "integrity": "sha512-LEw4VMQVRceOPLuGRWcxW5orTTiR9ZAtqTAe4rQUjNADTeR81bezBVFa0MqIwp0YmHIM1KkhSjZM7o+IQhaPbQ==", - "dependencies": { - "compute-lcm": "^1.1.0", - "json-schema-compare": "^0.2.2", - "lodash": "^4.17.4" - } - }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -24698,9 +25101,9 @@ } }, "node_modules/regenerator-runtime": { - "version": "0.13.9", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", - "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" + "version": "0.13.10", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.10.tgz", + "integrity": "sha512-KepLsg4dU12hryUO7bp/axHAKvwGOCV0sGloQtpagJ12ai+ojVDqkeGSiRX1zlq+kjIMZ1t7gpze+26QqtdGqw==" }, "node_modules/regenerator-transform": { "version": "0.15.0", @@ -26834,9 +27237,9 @@ } }, "node_modules/stylis": { - "version": "4.0.13", - "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.0.13.tgz", - "integrity": "sha512-xGPXiFVl4YED9Jh7Euv2V220mriG9u4B2TA6Ybjc1catrstKD2PpIdU3U0RKpkVBC2EhmL/F0sPCr9vrFTNRag==" + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.1.3.tgz", + "integrity": "sha512-GP6WDNWf+o403jrEp9c5jibKavrtLW+/qYGhFxFrG8maXhwTBI7gLLhiBb0o7uFccWN+EOS9aMO6cGHWAO07OA==" }, "node_modules/supports-color": { "version": "5.5.0", @@ -32296,11 +32699,11 @@ } }, "@babel/runtime": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.18.9.tgz", - "integrity": "sha512-lkqXDcvlFT5rvEjiu6+QYO+1GXrEHRo2LOtS7E4GtX5ESIZOgepqsZBVIj6Pv+a6zqsya9VCgiK1KAK4BvJDAw==", + "version": "7.20.1", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.1.tgz", + "integrity": "sha512-mrzLkl6U9YLF8qpqI7TB82PESyEGjm/0Ly91jG575eVxMMlb8fYfOXFZIJ8XfLrJZQbm7dlKry2bJmXBUEkdFg==", "requires": { - "regenerator-runtime": "^0.13.4" + "regenerator-runtime": "^0.13.10" } }, "@babel/runtime-corejs2": { @@ -32887,22 +33290,22 @@ } }, "@emotion/babel-plugin": { - "version": "11.10.2", - "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.10.2.tgz", - "integrity": "sha512-xNQ57njWTFVfPAc3cjfuaPdsgLp5QOSuRsj9MA6ndEhH/AzuZM86qIQzt6rq+aGBwj3n5/TkLmU5lhAfdRmogA==", + "version": "11.10.5", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.10.5.tgz", + "integrity": "sha512-xE7/hyLHJac7D2Ve9dKroBBZqBT7WuPQmWcq7HSGb84sUuP4mlOWoB8dvVfD9yk5DHkU1m6RW7xSoDtnQHNQeA==", "requires": { "@babel/helper-module-imports": "^7.16.7", "@babel/plugin-syntax-jsx": "^7.17.12", "@babel/runtime": "^7.18.3", "@emotion/hash": "^0.9.0", "@emotion/memoize": "^0.8.0", - "@emotion/serialize": "^1.1.0", + "@emotion/serialize": "^1.1.1", "babel-plugin-macros": "^3.1.0", "convert-source-map": "^1.5.0", "escape-string-regexp": "^4.0.0", "find-root": "^1.1.0", "source-map": "^0.5.7", - "stylis": "4.0.13" + "stylis": "4.1.3" }, "dependencies": { "@emotion/memoize": { @@ -32923,15 +33326,15 @@ } }, "@emotion/cache": { - "version": "11.10.3", - "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.10.3.tgz", - "integrity": "sha512-Psmp/7ovAa8appWh3g51goxu/z3iVms7JXOreq136D8Bbn6dYraPnmL6mdM8GThEx9vwSn92Fz+mGSjBzN8UPQ==", + "version": "11.10.5", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.10.5.tgz", + "integrity": "sha512-dGYHWyzTdmK+f2+EnIGBpkz1lKc4Zbj2KHd4cX3Wi8/OWr5pKslNjc3yABKH4adRGCvSX4VDC0i04mrrq0aiRA==", "requires": { "@emotion/memoize": "^0.8.0", - "@emotion/sheet": "^1.2.0", + "@emotion/sheet": "^1.2.1", "@emotion/utils": "^1.2.0", "@emotion/weak-memoize": "^0.3.0", - "stylis": "4.0.13" + "stylis": "4.1.3" }, "dependencies": { "@emotion/memoize": { @@ -32974,9 +33377,9 @@ } }, "@emotion/serialize": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.0.tgz", - "integrity": "sha512-F1ZZZW51T/fx+wKbVlwsfchr5q97iW8brAnXmsskz4d0hVB4O3M/SiA3SaeH06x02lSNzkkQv+n3AX3kCXKSFA==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.1.tgz", + "integrity": "sha512-Zl/0LFggN7+L1liljxXdsVSVlg6E/Z/olVWpfxUTxOAmi8NU7YoeWeLfi1RmnB2TATHoaWwIBRoL+FvAJiTUQA==", "requires": { "@emotion/hash": "^0.9.0", "@emotion/memoize": "^0.8.0", @@ -32993,15 +33396,53 @@ } }, "@emotion/sheet": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.0.tgz", - "integrity": "sha512-OiTkRgpxescko+M51tZsMq7Puu/KP55wMT8BgpcXVG2hqXc0Vo0mfymJ/Uj24Hp0i083ji/o0aLddh08UEjq8w==" + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.1.tgz", + "integrity": "sha512-zxRBwl93sHMsOj4zs+OslQKg/uhF38MB+OMKoCrVuS0nyTkqnau+BM3WGEoOptg9Oz45T/aIGs1qbVAsEFo3nA==" + }, + "@emotion/styled": { + "version": "11.10.5", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.10.5.tgz", + "integrity": "sha512-8EP6dD7dMkdku2foLoruPCNkRevzdcBaY6q0l0OsbyJK+x8D9HWjX27ARiSIKNF634hY9Zdoedh8bJCiva8yZw==", + "peer": true, + "requires": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.10.5", + "@emotion/is-prop-valid": "^1.2.0", + "@emotion/serialize": "^1.1.1", + "@emotion/use-insertion-effect-with-fallbacks": "^1.0.0", + "@emotion/utils": "^1.2.0" + }, + "dependencies": { + "@emotion/is-prop-valid": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.0.tgz", + "integrity": "sha512-3aDpDprjM0AwaxGE09bOPkNxHpBd+kA6jty3RnaEXdweX1DF1U3VQpPYb0g1IStAuK7SVQ1cy+bNBBKp4W3Fjg==", + "peer": true, + "requires": { + "@emotion/memoize": "^0.8.0" + } + }, + "@emotion/memoize": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.0.tgz", + "integrity": "sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA==", + "peer": true + } + } }, "@emotion/unitless": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.0.tgz", "integrity": "sha512-VINS5vEYAscRl2ZUDiT3uMPlrFQupiKgHz5AA4bCH1miKBg4qtwkim1qPmJj/4WG6TreYMY111rEFsjupcOKHw==" }, + "@emotion/use-insertion-effect-with-fallbacks": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.0.tgz", + "integrity": "sha512-1eEgUGmkaljiBnRMTdksDV1W4kUnmwgp7X9G8B++9GYwl1lUdqSndSriIrTJ0N7LQaoauY9JJ2yhiOYK5+NI4A==", + "peer": true, + "requires": {} + }, "@emotion/utils": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.0.tgz", @@ -34158,6 +34599,155 @@ "prop-types": "^15.7.2" } }, + "@mui/base": { + "version": "5.0.0-alpha.106", + "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-alpha.106.tgz", + "integrity": "sha512-xJQQtwPCPwr6hGWTBdvDwHYwExn3Bw7nPQkN8Fuz8kHpZqoMVWQvvaFS557AIkkI2AFLV3DxVIMjbCvrIntBWg==", + "peer": true, + "requires": { + "@babel/runtime": "^7.20.1", + "@emotion/is-prop-valid": "^1.2.0", + "@mui/types": "^7.2.1", + "@mui/utils": "^5.10.14", + "@popperjs/core": "^2.11.6", + "clsx": "^1.2.1", + "prop-types": "^15.8.1", + "react-is": "^18.2.0" + }, + "dependencies": { + "@emotion/is-prop-valid": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.0.tgz", + "integrity": "sha512-3aDpDprjM0AwaxGE09bOPkNxHpBd+kA6jty3RnaEXdweX1DF1U3VQpPYb0g1IStAuK7SVQ1cy+bNBBKp4W3Fjg==", + "peer": true, + "requires": { + "@emotion/memoize": "^0.8.0" + } + }, + "@emotion/memoize": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.0.tgz", + "integrity": "sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA==", + "peer": true + }, + "react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "peer": true + } + } + }, + "@mui/core-downloads-tracker": { + "version": "5.10.14", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.10.14.tgz", + "integrity": "sha512-qLgIJNOR9Dre8JiZ/neVzOf4jf88J6YtOkQqugtMrleLjbfRVUSS4LWl9CSOjNq76quYdmYWnSDgfQqOooT2cQ==", + "peer": true + }, + "@mui/icons-material": { + "version": "5.10.14", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.10.14.tgz", + "integrity": "sha512-qtH60slQa+7MZRn6kyui8rKuoGDglPqaHX+pzBKNvd8JCOlrnfY5DmGGDdToTXyXl8xJ8nhANZbrbpg7UVKq/Q==", + "peer": true, + "requires": { + "@babel/runtime": "^7.20.1" + } + }, + "@mui/material": { + "version": "5.10.14", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.10.14.tgz", + "integrity": "sha512-HWzKVAykePMx54WtxVwZyL1W4k3xlHYIqwMw0CaXAvgB3UE9yjABZuuGr8vG5Z6CSNWamzd+s1x8u7pQPFl9og==", + "peer": true, + "requires": { + "@babel/runtime": "^7.20.1", + "@mui/base": "5.0.0-alpha.106", + "@mui/core-downloads-tracker": "^5.10.14", + "@mui/system": "^5.10.14", + "@mui/types": "^7.2.1", + "@mui/utils": "^5.10.14", + "@types/react-transition-group": "^4.4.5", + "clsx": "^1.2.1", + "csstype": "^3.1.1", + "prop-types": "^15.8.1", + "react-is": "^18.2.0", + "react-transition-group": "^4.4.5" + }, + "dependencies": { + "react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "peer": true + } + } + }, + "@mui/private-theming": { + "version": "5.10.14", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.10.14.tgz", + "integrity": "sha512-3aIBe8WK65CwAPDY8nB11hYnzE1CZMymi76UnaFrA/DdGDwl5Y8F6uB+StKrkVmsqF1po7Mp2odqVkHj320gXw==", + "peer": true, + "requires": { + "@babel/runtime": "^7.20.1", + "@mui/utils": "^5.10.14", + "prop-types": "^15.8.1" + } + }, + "@mui/styled-engine": { + "version": "5.10.14", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.10.14.tgz", + "integrity": "sha512-bgKdM57ExogWpIfhL/ngSlzF4FhbH00vYF+Y5VALTob4uslFqje0xzoWmbfcCn4cZt2NXxZJIwhsq4vzo5itlw==", + "peer": true, + "requires": { + "@babel/runtime": "^7.20.1", + "@emotion/cache": "^11.10.5", + "csstype": "^3.1.1", + "prop-types": "^15.8.1" + } + }, + "@mui/system": { + "version": "5.10.14", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.10.14.tgz", + "integrity": "sha512-2de7XCjRb1j8Od0Stmo0LwFMLpOMNT4wzfINuExXI1TVSuyxXIXUxiC5FEgJW3GMvf/a7SUR8VOiMoKlKWzukw==", + "peer": true, + "requires": { + "@babel/runtime": "^7.20.1", + "@mui/private-theming": "^5.10.14", + "@mui/styled-engine": "^5.10.14", + "@mui/types": "^7.2.1", + "@mui/utils": "^5.10.14", + "clsx": "^1.2.1", + "csstype": "^3.1.1", + "prop-types": "^15.8.1" + } + }, + "@mui/types": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.1.tgz", + "integrity": "sha512-c5mSM7ivD8EsqK6HUi9hQPr5V7TJ/IRThUQ9nWNYPdhCGriTSQV4vL6DflT99LkM+wLiIS1rVjphpEWxERep7A==", + "peer": true, + "requires": {} + }, + "@mui/utils": { + "version": "5.10.14", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.10.14.tgz", + "integrity": "sha512-12p59+wDZpA++XVJmKwqsZmrA1nmUQ5d0a1yQWtcDjxNyER1EDzozYN/db+FY2i5ceQh2TynPTEwGms2mXDwFg==", + "peer": true, + "requires": { + "@babel/runtime": "^7.20.1", + "@types/prop-types": "^15.7.5", + "@types/react-is": "^16.7.1 || ^17.0.0", + "prop-types": "^15.8.1", + "react-is": "^18.2.0" + }, + "dependencies": { + "react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "peer": true + } + } + }, "@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -34217,6 +34807,12 @@ "@babel/runtime": "^7.6.2" } }, + "@react-icons/all-files": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@react-icons/all-files/-/all-files-4.1.0.tgz", + "integrity": "sha512-hxBI2UOuVaI3O/BhQfhtb4kcGn9ft12RWAFVMUeNjqqhLsHvFtzIkFaptBJpFDANTKoDfdVoHTKZDlwKCACbMQ==", + "requires": {} + }, "@restart/hooks": { "version": "0.4.7", "resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.4.7.tgz", @@ -34242,22 +34838,22 @@ } }, "@rjsf/core": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/@rjsf/core/-/core-4.2.3.tgz", - "integrity": "sha512-dRXhd1Tac/9OcG0VDrYDF2boNTyKINEEITEtJ4L1Yce2iMVk66U52BhWKIFp/WXDM27vwnOfwQo4NwGiqeQeHw==", + "version": "5.0.0-beta.13", + "resolved": "https://registry.npmjs.org/@rjsf/core/-/core-5.0.0-beta.13.tgz", + "integrity": "sha512-uQ3A9aJhMJsz9ct5tV3ogZkSFEkKUxrM9SJ9Hc8ijxmuaW7Jv8tNv5jiWZZsLvNXlIONX83s6JqkiOJf6IOAvg==", "requires": { - "@types/json-schema": "^7.0.7", - "ajv": "^6.7.0", - "core-js-pure": "^3.6.5", - "json-schema-merge-allof": "^0.6.0", - "jsonpointer": "^5.0.0", "lodash": "^4.17.15", "lodash-es": "^4.17.15", - "nanoid": "^3.1.23", - "prop-types": "^15.7.2", - "react-is": "16.9.0" + "nanoid": "^3.3.4", + "prop-types": "^15.7.2" } }, + "@rjsf/mui": { + "version": "5.0.0-beta.13", + "resolved": "https://registry.npmjs.org/@rjsf/mui/-/mui-5.0.0-beta.13.tgz", + "integrity": "sha512-hwCtADpjNssq/CsT3Wj1FDVJfdCN3gptKedGjbusLUEwQqXoVzkzl25e/IRfN8y/JxYu4lMXDU89bN9nJSKWLA==", + "requires": {} + }, "@rjsf/utils": { "version": "5.0.0-beta.13", "resolved": "https://registry.npmjs.org/@rjsf/utils/-/utils-5.0.0-beta.13.tgz", @@ -34287,6 +34883,17 @@ } } }, + "@rjsf/validator-ajv8": { + "version": "5.0.0-beta.13", + "resolved": "https://registry.npmjs.org/@rjsf/validator-ajv8/-/validator-ajv8-5.0.0-beta.13.tgz", + "integrity": "sha512-/hrYbiwgCvEqw1Z7YZTWvd+ZAiX5vSN0WAI2hJTJTqKuCTcIH0fqNDCaOg3FBR38BL7seZrUmibIUcPU66iJ1w==", + "requires": { + "ajv-formats": "^2.1.1", + "ajv8": "npm:ajv@^8.11.0", + "lodash": "^4.17.15", + "lodash-es": "^4.17.15" + } + }, "@rollup/plugin-babel": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", @@ -35016,6 +35623,15 @@ "@types/react": "*" } }, + "@types/react-is": { + "version": "17.0.3", + "resolved": "https://registry.npmjs.org/@types/react-is/-/react-is-17.0.3.tgz", + "integrity": "sha512-aBTIWg1emtu95bLTLx0cpkxwGW3ueZv71nE2YFBpL8k/z5czEW8yYpOo8Dp+UUAFAtKwNaOsh/ioSeQnWlZcfw==", + "peer": true, + "requires": { + "@types/react": "*" + } + }, "@types/react-redux": { "version": "7.1.24", "resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.24.tgz", @@ -35752,6 +36368,24 @@ "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", "requires": {} }, + "ajv8": { + "version": "npm:ajv@8.11.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.2.tgz", + "integrity": "sha512-E4bfmKAhGiSTvMfL1Myyycaub+cUEU2/IvpylXkUu7CHBkBj1f/ikdzbD7YQ6FKUbixDxeYvB/xY4fvyroDlQg==", + "requires": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "dependencies": { + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + } + } + }, "ansi-align": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", @@ -37305,6 +37939,12 @@ "mimic-response": "^1.0.0" } }, + "clsx": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", + "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==", + "peer": true + }, "co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", @@ -38028,9 +38668,9 @@ } }, "csstype": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.0.tgz", - "integrity": "sha512-uX1KG+x9h5hIJsaKR9xHUeUraxf8IODOwq9JLNPq6BwB04a/xgpq3rcx47l5BZu5zBPlgD342tdke3Hom/nJRA==" + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz", + "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==" }, "cyclist": { "version": "1.0.1", @@ -44999,16 +45639,6 @@ "lodash": "^4.17.4" } }, - "json-schema-merge-allof": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/json-schema-merge-allof/-/json-schema-merge-allof-0.6.0.tgz", - "integrity": "sha512-LEw4VMQVRceOPLuGRWcxW5orTTiR9ZAtqTAe4rQUjNADTeR81bezBVFa0MqIwp0YmHIM1KkhSjZM7o+IQhaPbQ==", - "requires": { - "compute-lcm": "^1.1.0", - "json-schema-compare": "^0.2.2", - "lodash": "^4.17.4" - } - }, "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -49196,9 +49826,9 @@ } }, "regenerator-runtime": { - "version": "0.13.9", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", - "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" + "version": "0.13.10", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.10.tgz", + "integrity": "sha512-KepLsg4dU12hryUO7bp/axHAKvwGOCV0sGloQtpagJ12ai+ojVDqkeGSiRX1zlq+kjIMZ1t7gpze+26QqtdGqw==" }, "regenerator-transform": { "version": "0.15.0", @@ -50892,9 +51522,9 @@ } }, "stylis": { - "version": "4.0.13", - "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.0.13.tgz", - "integrity": "sha512-xGPXiFVl4YED9Jh7Euv2V220mriG9u4B2TA6Ybjc1catrstKD2PpIdU3U0RKpkVBC2EhmL/F0sPCr9vrFTNRag==" + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.1.3.tgz", + "integrity": "sha512-GP6WDNWf+o403jrEp9c5jibKavrtLW+/qYGhFxFrG8maXhwTBI7gLLhiBb0o7uFccWN+EOS9aMO6cGHWAO07OA==" }, "supports-color": { "version": "5.5.0", diff --git a/spiffworkflow-frontend/package.json b/spiffworkflow-frontend/package.json index 6aeb83008..ebc77e74e 100644 --- a/spiffworkflow-frontend/package.json +++ b/spiffworkflow-frontend/package.json @@ -13,8 +13,11 @@ "@casl/react": "^3.1.0", "@ginkgo-bioworks/react-json-schema-form-builder": "^2.9.0", "@monaco-editor/react": "^4.4.5", - "@rjsf/core": "^4.2.0", + "@react-icons/all-files": "^4.1.0", + "@rjsf/core": "*", + "@rjsf/mui": "^5.0.0-beta.13", "@rjsf/utils": "^5.0.0-beta.13", + "@rjsf/validator-ajv8": "^5.0.0-beta.13", "@tanstack/react-table": "^8.2.2", "@testing-library/jest-dom": "^5.16.4", "@testing-library/react": "^13.3.0", diff --git a/spiffworkflow-frontend/src/routes/TaskShow.tsx b/spiffworkflow-frontend/src/routes/TaskShow.tsx index 3373eb71d..b64880a78 100644 --- a/spiffworkflow-frontend/src/routes/TaskShow.tsx +++ b/spiffworkflow-frontend/src/routes/TaskShow.tsx @@ -1,12 +1,15 @@ import { useContext, useEffect, useState } from 'react'; import { Link, useNavigate, useParams } from 'react-router-dom'; // import Form from '@rjsf/core'; +import Form from '@rjsf/mui'; +import validator from '@rjsf/validator-ajv8'; + // @ts-ignore import { Button, Stack } from '@carbon/react'; import ReactMarkdown from 'react-markdown'; import remarkGfm from 'remark-gfm'; -import Form from '../themes'; +// import Form from '../themes'; import HttpService from '../services/HttpService'; import ErrorContext from '../contexts/ErrorContext'; import { modifyProcessModelPath } from '../helpers'; @@ -145,6 +148,7 @@ export default function TaskShow() { onSubmit={handleFormSubmit} schema={jsonSchema} uiSchema={formUiSchema} + validator={validator} > {reactFragmentToHideSubmitButton} diff --git a/spiffworkflow-frontend/src/themes/AddButton/AddButton.tsx b/spiffworkflow-frontend/src/themes/AddButton/AddButton.tsx deleted file mode 100644 index f88f7153c..000000000 --- a/spiffworkflow-frontend/src/themes/AddButton/AddButton.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import React from "react"; -import { IconButtonProps } from "@rjsf/utils"; -import Button from "react-bootstrap/Button"; -import { BsPlus } from "@react-icons/all-files/bs/BsPlus"; - -const AddButton: React.ComponentType = ({ - uiSchema, - ...props -}) => ( - -); - -export default AddButton; diff --git a/spiffworkflow-frontend/src/themes/AddButton/index.ts b/spiffworkflow-frontend/src/themes/AddButton/index.ts deleted file mode 100644 index e41962705..000000000 --- a/spiffworkflow-frontend/src/themes/AddButton/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { default } from "./AddButton"; -export * from "./AddButton"; diff --git a/spiffworkflow-frontend/src/themes/ArrayFieldItemTemplate/ArrayFieldItemTemplate.tsx b/spiffworkflow-frontend/src/themes/ArrayFieldItemTemplate/ArrayFieldItemTemplate.tsx deleted file mode 100644 index 7858b1cc0..000000000 --- a/spiffworkflow-frontend/src/themes/ArrayFieldItemTemplate/ArrayFieldItemTemplate.tsx +++ /dev/null @@ -1,77 +0,0 @@ -import React, { CSSProperties } from "react"; -import Row from "react-bootstrap/Row"; -import Col from "react-bootstrap/Col"; -import { ArrayFieldTemplateItemType } from "@rjsf/utils"; - -const ArrayFieldItemTemplate = (props: ArrayFieldTemplateItemType) => { - const { - children, - disabled, - hasToolbar, - hasMoveDown, - hasMoveUp, - hasRemove, - index, - onDropIndexClick, - onReorderClick, - readonly, - registry, - uiSchema, - } = props; - const { MoveDownButton, MoveUpButton, RemoveButton } = - registry.templates.ButtonTemplates; - const btnStyle: CSSProperties = { - flex: 1, - paddingLeft: 6, - paddingRight: 6, - fontWeight: "bold", - }; - return ( -
- - - {children} - - - {hasToolbar && ( -
- {(hasMoveUp || hasMoveDown) && ( -
- -
- )} - {(hasMoveUp || hasMoveDown) && ( -
- -
- )} - {hasRemove && ( -
- -
- )} -
- )} - -
-
- ); -}; - -export default ArrayFieldItemTemplate; diff --git a/spiffworkflow-frontend/src/themes/ArrayFieldItemTemplate/index.ts b/spiffworkflow-frontend/src/themes/ArrayFieldItemTemplate/index.ts deleted file mode 100644 index f64828beb..000000000 --- a/spiffworkflow-frontend/src/themes/ArrayFieldItemTemplate/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { default } from "./ArrayFieldItemTemplate"; -export * from "./ArrayFieldItemTemplate"; diff --git a/spiffworkflow-frontend/src/themes/ArrayFieldTemplate/ArrayFieldTemplate.tsx b/spiffworkflow-frontend/src/themes/ArrayFieldTemplate/ArrayFieldTemplate.tsx deleted file mode 100644 index 01d2575e4..000000000 --- a/spiffworkflow-frontend/src/themes/ArrayFieldTemplate/ArrayFieldTemplate.tsx +++ /dev/null @@ -1,97 +0,0 @@ -import React from "react"; -import Row from "react-bootstrap/Row"; -import Col from "react-bootstrap/Col"; -import Container from "react-bootstrap/Container"; -import { - ArrayFieldTemplateItemType, - ArrayFieldTemplateProps, - getTemplate, - getUiOptions, -} from "@rjsf/utils"; - -const ArrayFieldTemplate = (props: ArrayFieldTemplateProps) => { - const { - canAdd, - disabled, - idSchema, - uiSchema, - items, - onAddClick, - readonly, - registry, - required, - schema, - title, - } = props; - const uiOptions = getUiOptions(uiSchema); - const ArrayFieldDescriptionTemplate = - getTemplate<"ArrayFieldDescriptionTemplate">( - "ArrayFieldDescriptionTemplate", - registry, - uiOptions - ); - const ArrayFieldItemTemplate = getTemplate<"ArrayFieldItemTemplate">( - "ArrayFieldItemTemplate", - registry, - uiOptions - ); - const ArrayFieldTitleTemplate = getTemplate<"ArrayFieldTitleTemplate">( - "ArrayFieldTitleTemplate", - registry, - uiOptions - ); - // Button templates are not overridden in the uiSchema - const { - ButtonTemplates: { AddButton }, - } = registry.templates; - return ( -
- - - - - - {items && - items.map(({ key, ...itemProps }: ArrayFieldTemplateItemType) => ( - - ))} - {canAdd && ( - - - - - - - - - )} - - - -
- ); -}; - -export default ArrayFieldTemplate; diff --git a/spiffworkflow-frontend/src/themes/ArrayFieldTemplate/index.ts b/spiffworkflow-frontend/src/themes/ArrayFieldTemplate/index.ts deleted file mode 100644 index 29cbde48e..000000000 --- a/spiffworkflow-frontend/src/themes/ArrayFieldTemplate/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { default } from "./ArrayFieldTemplate"; -export * from "./ArrayFieldTemplate"; diff --git a/spiffworkflow-frontend/src/themes/BaseInputTemplate/BaseInputTemplate.tsx b/spiffworkflow-frontend/src/themes/BaseInputTemplate/BaseInputTemplate.tsx deleted file mode 100644 index 68699d050..000000000 --- a/spiffworkflow-frontend/src/themes/BaseInputTemplate/BaseInputTemplate.tsx +++ /dev/null @@ -1,67 +0,0 @@ -import React from "react"; -import Form from "react-bootstrap/Form"; -import { getInputProps, WidgetProps } from "@rjsf/utils"; - -const BaseInputTemplate = ({ - id, - placeholder, - required, - readonly, - disabled, - type, - value, - onChange, - onBlur, - onFocus, - autofocus, - options, - schema, - rawErrors = [], - children, - extraProps, -}: WidgetProps) => { - const inputProps = { ...extraProps, ...getInputProps(schema, type, options) }; - const _onChange = ({ - target: { value }, - }: React.ChangeEvent) => - onChange(value === "" ? options.emptyValue : value); - const _onBlur = ({ target: { value } }: React.FocusEvent) => - onBlur(id, value); - const _onFocus = ({ - target: { value }, - }: React.FocusEvent) => onFocus(id, value); - - // const classNames = [rawErrors.length > 0 ? "is-invalid" : "", type === 'file' ? 'custom-file-label': ""] - return ( - <> - 0 ? "is-invalid" : ""} - list={schema.examples ? `examples_${id}` : undefined} - {...inputProps} - value={value || value === 0 ? value : ""} - onChange={_onChange} - onBlur={_onBlur} - onFocus={_onFocus} - /> - {children} - {schema.examples ? ( - - {(schema.examples as string[]) - .concat(schema.default ? ([schema.default] as string[]) : []) - .map((example: any) => { - return - ) : null} - - ); -}; - -export default BaseInputTemplate; diff --git a/spiffworkflow-frontend/src/themes/BaseInputTemplate/index.ts b/spiffworkflow-frontend/src/themes/BaseInputTemplate/index.ts deleted file mode 100644 index 37c3947ed..000000000 --- a/spiffworkflow-frontend/src/themes/BaseInputTemplate/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { default } from "./BaseInputTemplate"; -export * from "./BaseInputTemplate"; diff --git a/spiffworkflow-frontend/src/themes/CheckboxWidget/CheckboxWidget.tsx b/spiffworkflow-frontend/src/themes/CheckboxWidget/CheckboxWidget.tsx deleted file mode 100644 index f2e665d41..000000000 --- a/spiffworkflow-frontend/src/themes/CheckboxWidget/CheckboxWidget.tsx +++ /dev/null @@ -1,53 +0,0 @@ -import React from "react"; - -import { WidgetProps } from "@rjsf/utils"; -import Form from "react-bootstrap/Form"; - -const CheckboxWidget = (props: WidgetProps) => { - const { - id, - value, - required, - disabled, - readonly, - label, - schema, - autofocus, - onChange, - onBlur, - onFocus, - } = props; - - const _onChange = ({ - target: { checked }, - }: React.FocusEvent) => onChange(checked); - const _onBlur = ({ - target: { checked }, - }: React.FocusEvent) => onBlur(id, checked); - const _onFocus = ({ - target: { checked }, - }: React.FocusEvent) => onFocus(id, checked); - - const desc = label || schema.description; - return ( - - - - ); -}; - -export default CheckboxWidget; diff --git a/spiffworkflow-frontend/src/themes/CheckboxWidget/index.ts b/spiffworkflow-frontend/src/themes/CheckboxWidget/index.ts deleted file mode 100644 index 9a6515772..000000000 --- a/spiffworkflow-frontend/src/themes/CheckboxWidget/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { default } from "./CheckboxWidget"; -export * from "./CheckboxWidget"; diff --git a/spiffworkflow-frontend/src/themes/CheckboxesWidget/CheckboxesWidget.tsx b/spiffworkflow-frontend/src/themes/CheckboxesWidget/CheckboxesWidget.tsx deleted file mode 100644 index 71646084e..000000000 --- a/spiffworkflow-frontend/src/themes/CheckboxesWidget/CheckboxesWidget.tsx +++ /dev/null @@ -1,83 +0,0 @@ -import React from "react"; -import Form from "react-bootstrap/Form"; -import { WidgetProps } from "@rjsf/utils"; - -const selectValue = (value: any, selected: any, all: any) => { - const at = all.indexOf(value); - const updated = selected.slice(0, at).concat(value, selected.slice(at)); - - // As inserting values at predefined index positions doesn't work with empty - // arrays, we need to reorder the updated selection to match the initial order - return updated.sort((a: any, b: any) => all.indexOf(a) > all.indexOf(b)); -}; - -const deselectValue = (value: any, selected: any) => { - return selected.filter((v: any) => v !== value); -}; - -const CheckboxesWidget = ({ - id, - disabled, - options, - value, - autofocus, - readonly, - required, - onChange, - onBlur, - onFocus, -}: WidgetProps) => { - const { enumOptions, enumDisabled, inline } = options; - - const _onChange = - (option: any) => - ({ target: { checked } }: React.ChangeEvent) => { - const all = (enumOptions as any).map(({ value }: any) => value); - - if (checked) { - onChange(selectValue(option.value, value, all)); - } else { - onChange(deselectValue(option.value, value)); - } - }; - - const _onBlur = ({ target: { value } }: React.FocusEvent) => - onBlur(id, value); - const _onFocus = ({ - target: { value }, - }: React.FocusEvent) => onFocus(id, value); - - return ( - - {Array.isArray(enumOptions) && - enumOptions.map((option, index: number) => { - const checked = value.indexOf(option.value) !== -1; - const itemDisabled = - Array.isArray(enumDisabled) && - enumDisabled.indexOf(option.value) !== -1; - - return ( - - ); - })} - - ); -}; - -export default CheckboxesWidget; diff --git a/spiffworkflow-frontend/src/themes/CheckboxesWidget/index.ts b/spiffworkflow-frontend/src/themes/CheckboxesWidget/index.ts deleted file mode 100644 index c5acc6aa1..000000000 --- a/spiffworkflow-frontend/src/themes/CheckboxesWidget/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { default } from "./CheckboxesWidget"; -export * from "./CheckboxesWidget"; diff --git a/spiffworkflow-frontend/src/themes/DescriptionField/DescriptionField.tsx b/spiffworkflow-frontend/src/themes/DescriptionField/DescriptionField.tsx deleted file mode 100644 index 1e6e0eccb..000000000 --- a/spiffworkflow-frontend/src/themes/DescriptionField/DescriptionField.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import React from "react"; -import { DescriptionFieldProps } from "@rjsf/utils"; - -const DescriptionField = ({ id, description }: DescriptionFieldProps) => { - if (description) { - return ( -
-
- {description} -
-
- ); - } - - return null; -}; - -export default DescriptionField; diff --git a/spiffworkflow-frontend/src/themes/DescriptionField/index.ts b/spiffworkflow-frontend/src/themes/DescriptionField/index.ts deleted file mode 100644 index 899add9fc..000000000 --- a/spiffworkflow-frontend/src/themes/DescriptionField/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { default } from "./DescriptionField"; -export * from "./DescriptionField"; diff --git a/spiffworkflow-frontend/src/themes/ErrorList/ErrorList.tsx b/spiffworkflow-frontend/src/themes/ErrorList/ErrorList.tsx deleted file mode 100644 index 61dd66312..000000000 --- a/spiffworkflow-frontend/src/themes/ErrorList/ErrorList.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import React from "react"; - -import Card from "react-bootstrap/Card"; -import ListGroup from "react-bootstrap/ListGroup"; - -import { ErrorListProps } from "@rjsf/utils"; - -const ErrorList = ({ errors }: ErrorListProps) => ( - - Errors - - - {errors.map((error, i: number) => { - return ( - - {error.stack} - - ); - })} - - - -); - -export default ErrorList; diff --git a/spiffworkflow-frontend/src/themes/ErrorList/index.ts b/spiffworkflow-frontend/src/themes/ErrorList/index.ts deleted file mode 100644 index af63a176f..000000000 --- a/spiffworkflow-frontend/src/themes/ErrorList/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { default } from "./ErrorList"; -export * from "./ErrorList"; diff --git a/spiffworkflow-frontend/src/themes/FieldErrorTemplate/FieldErrorTemplate.tsx b/spiffworkflow-frontend/src/themes/FieldErrorTemplate/FieldErrorTemplate.tsx deleted file mode 100644 index f1709ddaf..000000000 --- a/spiffworkflow-frontend/src/themes/FieldErrorTemplate/FieldErrorTemplate.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import React from "react"; -import { FieldErrorProps } from "@rjsf/utils"; -import ListGroup from "react-bootstrap/ListGroup"; - -/** The `FieldErrorTemplate` component renders the errors local to the particular field - * - * @param props - The `FieldErrorProps` for the errors being rendered - */ -export default function FieldErrorTemplate(props: FieldErrorProps) { - const { errors = [], idSchema } = props; - if (errors.length === 0) { - return null; - } - const id = `${idSchema.$id}__error`; - - return ( - - {errors.map((error, i) => { - return ( - - {error} - - ); - })} - - ); -} diff --git a/spiffworkflow-frontend/src/themes/FieldErrorTemplate/index.ts b/spiffworkflow-frontend/src/themes/FieldErrorTemplate/index.ts deleted file mode 100644 index dd9c569ff..000000000 --- a/spiffworkflow-frontend/src/themes/FieldErrorTemplate/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { default } from "./FieldErrorTemplate"; -export * from "./FieldErrorTemplate"; diff --git a/spiffworkflow-frontend/src/themes/FieldHelpTemplate/FieldHelpTemplate.tsx b/spiffworkflow-frontend/src/themes/FieldHelpTemplate/FieldHelpTemplate.tsx deleted file mode 100644 index 271923188..000000000 --- a/spiffworkflow-frontend/src/themes/FieldHelpTemplate/FieldHelpTemplate.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import React from "react"; -import { FieldHelpProps } from "@rjsf/utils"; -import Form from "react-bootstrap/Form"; - -/** The `FieldHelpTemplate` component renders any help desired for a field - * - * @param props - The `FieldHelpProps` to be rendered - */ -export default function FieldHelpTemplate(props: FieldHelpProps) { - const { idSchema, help, hasErrors } = props; - if (!help) { - return null; - } - const id = `${idSchema.$id}__help`; - return ( - - {help} - - ); -} diff --git a/spiffworkflow-frontend/src/themes/FieldHelpTemplate/index.ts b/spiffworkflow-frontend/src/themes/FieldHelpTemplate/index.ts deleted file mode 100644 index 55b9f4a09..000000000 --- a/spiffworkflow-frontend/src/themes/FieldHelpTemplate/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { default } from "./FieldHelpTemplate"; -export * from "./FieldHelpTemplate"; diff --git a/spiffworkflow-frontend/src/themes/FieldTemplate/FieldTemplate.tsx b/spiffworkflow-frontend/src/themes/FieldTemplate/FieldTemplate.tsx deleted file mode 100644 index ace72557d..000000000 --- a/spiffworkflow-frontend/src/themes/FieldTemplate/FieldTemplate.tsx +++ /dev/null @@ -1,73 +0,0 @@ -import React from "react"; -import { FieldTemplateProps, getTemplate, getUiOptions } from "@rjsf/utils"; -import Form from "react-bootstrap/Form"; - -const FieldTemplate = ({ - id, - children, - displayLabel, - rawErrors = [], - errors, - help, - rawDescription, - classNames, - disabled, - label, - hidden, - onDropPropertyClick, - onKeyChange, - readonly, - required, - schema, - uiSchema, - registry, -}: FieldTemplateProps) => { - const uiOptions = getUiOptions(uiSchema); - const WrapIfAdditionalTemplate = getTemplate<"WrapIfAdditionalTemplate">( - "WrapIfAdditionalTemplate", - registry, - uiOptions - ); - if (hidden) { - return
{children}
; - } - return ( - - - {displayLabel && ( - 0 ? "text-danger" : ""} - > - {label} - {required ? "*" : null} - - )} - {children} - {displayLabel && rawDescription && ( - 0 ? "text-danger" : "text-muted"} - > - {rawDescription} - - )} - {errors} - {help} - - - ); -}; - -export default FieldTemplate; diff --git a/spiffworkflow-frontend/src/themes/FieldTemplate/index.ts b/spiffworkflow-frontend/src/themes/FieldTemplate/index.ts deleted file mode 100644 index 290c188da..000000000 --- a/spiffworkflow-frontend/src/themes/FieldTemplate/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { default } from "./FieldTemplate"; -export * from "./FieldTemplate"; diff --git a/spiffworkflow-frontend/src/themes/FileWidget/FileWidget.tsx b/spiffworkflow-frontend/src/themes/FileWidget/FileWidget.tsx deleted file mode 100644 index 4bd934b4b..000000000 --- a/spiffworkflow-frontend/src/themes/FileWidget/FileWidget.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import React from "react"; -import { getTemplate, WidgetProps } from "@rjsf/utils"; - -const FileWidget = (props: WidgetProps) => { - const { options, registry } = props; - const BaseInputTemplate = getTemplate<"BaseInputTemplate">( - "BaseInputTemplate", - registry, - options - ); - return ; -}; - -export default FileWidget; diff --git a/spiffworkflow-frontend/src/themes/FileWidget/index.ts b/spiffworkflow-frontend/src/themes/FileWidget/index.ts deleted file mode 100644 index e70174ced..000000000 --- a/spiffworkflow-frontend/src/themes/FileWidget/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { default } from "./FileWidget"; -export * from "./FileWidget"; diff --git a/spiffworkflow-frontend/src/themes/Form/Form.tsx b/spiffworkflow-frontend/src/themes/Form/Form.tsx deleted file mode 100644 index e19361924..000000000 --- a/spiffworkflow-frontend/src/themes/Form/Form.tsx +++ /dev/null @@ -1,7 +0,0 @@ -import { withTheme, FormProps } from "@rjsf/core"; - -import Theme from "../Theme"; - -const Form: React.ComponentType = withTheme(Theme); - -export default Form; diff --git a/spiffworkflow-frontend/src/themes/Form/index.ts b/spiffworkflow-frontend/src/themes/Form/index.ts deleted file mode 100644 index dbca2de64..000000000 --- a/spiffworkflow-frontend/src/themes/Form/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { default } from "./Form"; -export * from "./Form"; diff --git a/spiffworkflow-frontend/src/themes/IconButton/IconButton.tsx b/spiffworkflow-frontend/src/themes/IconButton/IconButton.tsx deleted file mode 100644 index 6a8e00fe4..000000000 --- a/spiffworkflow-frontend/src/themes/IconButton/IconButton.tsx +++ /dev/null @@ -1,43 +0,0 @@ -import React from "react"; -import { IconButtonProps } from "@rjsf/utils"; -import Button, { ButtonProps } from "react-bootstrap/Button"; -import { IoIosRemove } from "@react-icons/all-files/io/IoIosRemove"; -import { AiOutlineArrowUp } from "@react-icons/all-files/ai/AiOutlineArrowUp"; -import { AiOutlineArrowDown } from "@react-icons/all-files/ai/AiOutlineArrowDown"; - -const IconButton = (props: IconButtonProps & ButtonProps) => { - const { icon, iconType, className, uiSchema, ...otherProps } = props; - return ( - - ); -}; - -export default IconButton; - -export function MoveDownButton(props: IconButtonProps) { - return ( - } /> - ); -} - -export function MoveUpButton(props: IconButtonProps) { - return } />; -} - -export function RemoveButton(props: IconButtonProps) { - return ( - } - /> - ); -} diff --git a/spiffworkflow-frontend/src/themes/IconButton/index.ts b/spiffworkflow-frontend/src/themes/IconButton/index.ts deleted file mode 100644 index 55447475b..000000000 --- a/spiffworkflow-frontend/src/themes/IconButton/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { default } from "./IconButton"; -export * from "./IconButton"; diff --git a/spiffworkflow-frontend/src/themes/ObjectFieldTemplate/ObjectFieldTemplate.tsx b/spiffworkflow-frontend/src/themes/ObjectFieldTemplate/ObjectFieldTemplate.tsx deleted file mode 100644 index 83008ec06..000000000 --- a/spiffworkflow-frontend/src/themes/ObjectFieldTemplate/ObjectFieldTemplate.tsx +++ /dev/null @@ -1,91 +0,0 @@ -import React from "react"; - -import Row from "react-bootstrap/Row"; -import Col from "react-bootstrap/Col"; -import Container from "react-bootstrap/Container"; - -import { - canExpand, - getTemplate, - getUiOptions, - ObjectFieldTemplateProps, -} from "@rjsf/utils"; - -const ObjectFieldTemplate = ({ - description, - title, - properties, - required, - uiSchema, - idSchema, - schema, - formData, - onAddClick, - disabled, - readonly, - registry, -}: ObjectFieldTemplateProps) => { - const uiOptions = getUiOptions(uiSchema); - const TitleFieldTemplate = getTemplate<"TitleFieldTemplate">( - "TitleFieldTemplate", - registry, - uiOptions - ); - const DescriptionFieldTemplate = getTemplate<"DescriptionFieldTemplate">( - "DescriptionFieldTemplate", - registry, - uiOptions - ); - // Button templates are not overridden in the uiSchema - const { - ButtonTemplates: { AddButton }, - } = registry.templates; - return ( - <> - {(uiOptions.title || title) && ( - - )} - {(uiOptions.description || description) && ( - - )} - - {properties.map((element: any, index: number) => ( - - {element.content} - - ))} - {canExpand(schema, uiSchema, formData) ? ( - - - - - - ) : null} - - - ); -}; - -export default ObjectFieldTemplate; diff --git a/spiffworkflow-frontend/src/themes/ObjectFieldTemplate/index.ts b/spiffworkflow-frontend/src/themes/ObjectFieldTemplate/index.ts deleted file mode 100644 index b7e3ae624..000000000 --- a/spiffworkflow-frontend/src/themes/ObjectFieldTemplate/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { default } from "./ObjectFieldTemplate"; -export * from "./ObjectFieldTemplate"; diff --git a/spiffworkflow-frontend/src/themes/RadioWidget/RadioWidget.tsx b/spiffworkflow-frontend/src/themes/RadioWidget/RadioWidget.tsx deleted file mode 100644 index 715a66e1d..000000000 --- a/spiffworkflow-frontend/src/themes/RadioWidget/RadioWidget.tsx +++ /dev/null @@ -1,65 +0,0 @@ -import React from "react"; - -import Form from "react-bootstrap/Form"; - -import { WidgetProps } from "@rjsf/utils"; - -const RadioWidget = ({ - id, - schema, - options, - value, - required, - disabled, - readonly, - onChange, - onBlur, - onFocus, -}: WidgetProps) => { - const { enumOptions, enumDisabled } = options; - - const _onChange = ({ - target: { value }, - }: React.ChangeEvent) => - onChange(schema.type == "boolean" ? value !== "false" : value); - const _onBlur = ({ target: { value } }: React.FocusEvent) => - onBlur(id, value); - const _onFocus = ({ - target: { value }, - }: React.FocusEvent) => onFocus(id, value); - - const inline = Boolean(options && options.inline); - - return ( - - {Array.isArray(enumOptions) && - enumOptions.map((option) => { - const itemDisabled = - Array.isArray(enumDisabled) && - enumDisabled.indexOf(option.value) !== -1; - const checked = option.value == value; - - const radio = ( - - ); - return radio; - })} - - ); -}; - -export default RadioWidget; diff --git a/spiffworkflow-frontend/src/themes/RadioWidget/index.ts b/spiffworkflow-frontend/src/themes/RadioWidget/index.ts deleted file mode 100644 index f0568f0d8..000000000 --- a/spiffworkflow-frontend/src/themes/RadioWidget/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { default } from "./RadioWidget"; -export * from "./RadioWidget"; diff --git a/spiffworkflow-frontend/src/themes/RangeWidget/RangeWidget.tsx b/spiffworkflow-frontend/src/themes/RangeWidget/RangeWidget.tsx deleted file mode 100644 index f75d3756c..000000000 --- a/spiffworkflow-frontend/src/themes/RangeWidget/RangeWidget.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import React from "react"; -import { getTemplate, WidgetProps } from "@rjsf/utils"; - -const RangeWidget = (props: WidgetProps) => { - const { value, label, options, registry } = props; - const BaseInputTemplate = getTemplate<"BaseInputTemplate">( - "BaseInputTemplate", - registry, - options - ); - return ( - - {value} - - ); -}; - -export default RangeWidget; diff --git a/spiffworkflow-frontend/src/themes/RangeWidget/index.ts b/spiffworkflow-frontend/src/themes/RangeWidget/index.ts deleted file mode 100644 index 70a8e7601..000000000 --- a/spiffworkflow-frontend/src/themes/RangeWidget/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { default } from "./RangeWidget"; -export * from "./RangeWidget"; diff --git a/spiffworkflow-frontend/src/themes/SelectWidget/SelectWidget.tsx b/spiffworkflow-frontend/src/themes/SelectWidget/SelectWidget.tsx deleted file mode 100644 index 07864f0e6..000000000 --- a/spiffworkflow-frontend/src/themes/SelectWidget/SelectWidget.tsx +++ /dev/null @@ -1,89 +0,0 @@ -import React from "react"; - -import Form from "react-bootstrap/Form"; - -import { processSelectValue, WidgetProps } from "@rjsf/utils"; - -const SelectWidget = ({ - schema, - id, - options, - required, - disabled, - readonly, - value, - multiple, - autofocus, - onChange, - onBlur, - onFocus, - placeholder, - rawErrors = [], -}: WidgetProps) => { - const { enumOptions, enumDisabled } = options; - - const emptyValue = multiple ? [] : ""; - - function getValue( - event: React.FocusEvent | React.ChangeEvent | any, - multiple?: boolean - ) { - if (multiple) { - return [].slice - .call(event.target.options as any) - .filter((o: any) => o.selected) - .map((o: any) => o.value); - } else { - return event.target.value; - } - } - - return ( - 0 ? "is-invalid" : ""} - onBlur={ - onBlur && - ((event: React.FocusEvent) => { - const newValue = getValue(event, multiple); - onBlur(id, processSelectValue(schema, newValue, options)); - }) - } - onFocus={ - onFocus && - ((event: React.FocusEvent) => { - const newValue = getValue(event, multiple); - onFocus(id, processSelectValue(schema, newValue, options)); - }) - } - onChange={(event: React.ChangeEvent) => { - const newValue = getValue(event, multiple); - onChange(processSelectValue(schema, newValue, options)); - }} - > - {!multiple && schema.default === undefined && ( - - )} - {(enumOptions as any).map(({ value, label }: any, i: number) => { - const disabled: any = - Array.isArray(enumDisabled) && - (enumDisabled as any).indexOf(value) != -1; - return ( - - ); - })} - - ); -}; - -export default SelectWidget; diff --git a/spiffworkflow-frontend/src/themes/SelectWidget/index.ts b/spiffworkflow-frontend/src/themes/SelectWidget/index.ts deleted file mode 100644 index 91a604a36..000000000 --- a/spiffworkflow-frontend/src/themes/SelectWidget/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { default } from "./SelectWidget"; -export * from "./SelectWidget"; diff --git a/spiffworkflow-frontend/src/themes/SubmitButton/SubmitButton.tsx b/spiffworkflow-frontend/src/themes/SubmitButton/SubmitButton.tsx deleted file mode 100644 index fc88cc93f..000000000 --- a/spiffworkflow-frontend/src/themes/SubmitButton/SubmitButton.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import React from "react"; -import Button from "react-bootstrap/Button"; -import { getSubmitButtonOptions, SubmitButtonProps } from "@rjsf/utils"; - -const SubmitButton: React.ComponentType = (props) => { - const { - submitText, - norender, - props: submitButtonProps, - } = getSubmitButtonOptions(props.uiSchema); - if (norender) { - return null; - } - return ( -
- -
- ); -}; - -export default SubmitButton; diff --git a/spiffworkflow-frontend/src/themes/SubmitButton/index.ts b/spiffworkflow-frontend/src/themes/SubmitButton/index.ts deleted file mode 100644 index 467dba249..000000000 --- a/spiffworkflow-frontend/src/themes/SubmitButton/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { default } from "./SubmitButton"; -export * from "./SubmitButton"; diff --git a/spiffworkflow-frontend/src/themes/Templates/Templates.ts b/spiffworkflow-frontend/src/themes/Templates/Templates.ts deleted file mode 100644 index e8eef55a0..000000000 --- a/spiffworkflow-frontend/src/themes/Templates/Templates.ts +++ /dev/null @@ -1,35 +0,0 @@ -import AddButton from "../AddButton"; -import ArrayFieldItemTemplate from "../ArrayFieldItemTemplate"; -import ArrayFieldTemplate from "../ArrayFieldTemplate"; -import BaseInputTemplate from "../BaseInputTemplate/BaseInputTemplate"; -import DescriptionField from "../DescriptionField"; -import ErrorList from "../ErrorList"; -import { MoveDownButton, MoveUpButton, RemoveButton } from "../IconButton"; -import FieldErrorTemplate from "../FieldErrorTemplate"; -import FieldHelpTemplate from "../FieldHelpTemplate"; -import FieldTemplate from "../FieldTemplate"; -import ObjectFieldTemplate from "../ObjectFieldTemplate"; -import SubmitButton from "../SubmitButton"; -import TitleField from "../TitleField"; -import WrapIfAdditionalTemplate from "../WrapIfAdditionalTemplate"; - -export default { - ArrayFieldItemTemplate, - ArrayFieldTemplate, - BaseInputTemplate, - ButtonTemplates: { - AddButton, - MoveDownButton, - MoveUpButton, - RemoveButton, - SubmitButton, - }, - DescriptionFieldTemplate: DescriptionField, - ErrorListTemplate: ErrorList, - FieldErrorTemplate, - FieldHelpTemplate, - FieldTemplate, - ObjectFieldTemplate, - TitleFieldTemplate: TitleField, - WrapIfAdditionalTemplate, -}; diff --git a/spiffworkflow-frontend/src/themes/Templates/index.ts b/spiffworkflow-frontend/src/themes/Templates/index.ts deleted file mode 100644 index 0c3e935ca..000000000 --- a/spiffworkflow-frontend/src/themes/Templates/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { default } from "./Templates"; -export * from "./Templates"; diff --git a/spiffworkflow-frontend/src/themes/TextareaWidget/TextareaWidget.tsx b/spiffworkflow-frontend/src/themes/TextareaWidget/TextareaWidget.tsx deleted file mode 100644 index afb2c98da..000000000 --- a/spiffworkflow-frontend/src/themes/TextareaWidget/TextareaWidget.tsx +++ /dev/null @@ -1,56 +0,0 @@ -import React from "react"; - -import { WidgetProps } from "@rjsf/utils"; -import FormControl from "react-bootstrap/FormControl"; -import InputGroup from "react-bootstrap/InputGroup"; - -type CustomWidgetProps = WidgetProps & { - options: any; -}; - -const TextareaWidget = ({ - id, - placeholder, - value, - required, - disabled, - autofocus, - readonly, - onBlur, - onFocus, - onChange, - options, -}: CustomWidgetProps) => { - const _onChange = ({ - target: { value }, - }: React.ChangeEvent) => - onChange(value === "" ? options.emptyValue : value); - const _onBlur = ({ - target: { value }, - }: React.FocusEvent) => onBlur(id, value); - const _onFocus = ({ - target: { value }, - }: React.FocusEvent) => onFocus(id, value); - - return ( - - - - ); -}; - -export default TextareaWidget; diff --git a/spiffworkflow-frontend/src/themes/TextareaWidget/index.ts b/spiffworkflow-frontend/src/themes/TextareaWidget/index.ts deleted file mode 100644 index 1c7268c66..000000000 --- a/spiffworkflow-frontend/src/themes/TextareaWidget/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { default } from "./TextareaWidget"; -export * from "./TextareaWidget"; diff --git a/spiffworkflow-frontend/src/themes/Theme/Theme.tsx b/spiffworkflow-frontend/src/themes/Theme/Theme.tsx deleted file mode 100644 index ecfcdd572..000000000 --- a/spiffworkflow-frontend/src/themes/Theme/Theme.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import { ThemeProps } from "@rjsf/core"; - -import Templates from "../Templates"; -import Widgets from "../Widgets"; - -const Theme: ThemeProps = { - templates: Templates, - widgets: Widgets, -}; - -export default Theme; diff --git a/spiffworkflow-frontend/src/themes/Theme/index.ts b/spiffworkflow-frontend/src/themes/Theme/index.ts deleted file mode 100644 index 491c3a07c..000000000 --- a/spiffworkflow-frontend/src/themes/Theme/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { default } from "./Theme"; -export * from "./Theme"; diff --git a/spiffworkflow-frontend/src/themes/TitleField/TitleField.tsx b/spiffworkflow-frontend/src/themes/TitleField/TitleField.tsx deleted file mode 100644 index 4606e0d15..000000000 --- a/spiffworkflow-frontend/src/themes/TitleField/TitleField.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import React from "react"; -import { TitleFieldProps } from "@rjsf/utils"; - -const TitleField = ({ id, title, uiSchema }: TitleFieldProps) => ( - <> -
-
{(uiSchema && uiSchema["ui:title"]) || title}
-
-
- -); - -export default TitleField; diff --git a/spiffworkflow-frontend/src/themes/TitleField/index.ts b/spiffworkflow-frontend/src/themes/TitleField/index.ts deleted file mode 100644 index 2e26cd18f..000000000 --- a/spiffworkflow-frontend/src/themes/TitleField/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { default } from "./TitleField"; -export * from "./TitleField"; diff --git a/spiffworkflow-frontend/src/themes/Widgets/Widgets.ts b/spiffworkflow-frontend/src/themes/Widgets/Widgets.ts deleted file mode 100644 index 543a05ec3..000000000 --- a/spiffworkflow-frontend/src/themes/Widgets/Widgets.ts +++ /dev/null @@ -1,17 +0,0 @@ -import CheckboxWidget from "../CheckboxWidget/CheckboxWidget"; -import CheckboxesWidget from "../CheckboxesWidget/CheckboxesWidget"; -import RadioWidget from "../RadioWidget/RadioWidget"; -import RangeWidget from "../RangeWidget/RangeWidget"; -import SelectWidget from "../SelectWidget/SelectWidget"; -import TextareaWidget from "../TextareaWidget/TextareaWidget"; -import FileWidget from "../FileWidget/FileWidget"; - -export default { - CheckboxWidget, - CheckboxesWidget, - RadioWidget, - RangeWidget, - SelectWidget, - TextareaWidget, - FileWidget, -}; diff --git a/spiffworkflow-frontend/src/themes/Widgets/index.ts b/spiffworkflow-frontend/src/themes/Widgets/index.ts deleted file mode 100644 index 595580b54..000000000 --- a/spiffworkflow-frontend/src/themes/Widgets/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { default } from "./Widgets"; -export * from "./Widgets"; diff --git a/spiffworkflow-frontend/src/themes/WrapIfAdditionalTemplate/WrapIfAdditionalTemplate.tsx b/spiffworkflow-frontend/src/themes/WrapIfAdditionalTemplate/WrapIfAdditionalTemplate.tsx deleted file mode 100644 index 3eafe9069..000000000 --- a/spiffworkflow-frontend/src/themes/WrapIfAdditionalTemplate/WrapIfAdditionalTemplate.tsx +++ /dev/null @@ -1,69 +0,0 @@ -import React from "react"; - -import { - ADDITIONAL_PROPERTY_FLAG, - WrapIfAdditionalTemplateProps, -} from "@rjsf/utils"; - -import Row from "react-bootstrap/Row"; -import Col from "react-bootstrap/Col"; -import Form from "react-bootstrap/Form"; - -const WrapIfAdditionalTemplate = ({ - classNames, - children, - disabled, - id, - label, - onDropPropertyClick, - onKeyChange, - readonly, - required, - schema, - uiSchema, - registry, -}: WrapIfAdditionalTemplateProps) => { - // Button templates are not overridden in the uiSchema - const { RemoveButton } = registry.templates.ButtonTemplates; - const keyLabel = `${label} Key`; // i18n ? - const additional = ADDITIONAL_PROPERTY_FLAG in schema; - - if (!additional) { - return
{children}
; - } - - const handleBlur = ({ target }: React.FocusEvent) => - onKeyChange(target.value); - const keyId = `${id}-key`; - - return ( - - - - {keyLabel} - - - - {children} - - - - - ); -}; - -export default WrapIfAdditionalTemplate; diff --git a/spiffworkflow-frontend/src/themes/WrapIfAdditionalTemplate/index.ts b/spiffworkflow-frontend/src/themes/WrapIfAdditionalTemplate/index.ts deleted file mode 100644 index 95ba7de22..000000000 --- a/spiffworkflow-frontend/src/themes/WrapIfAdditionalTemplate/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { default } from "./WrapIfAdditionalTemplate"; -export * from "./WrapIfAdditionalTemplate"; diff --git a/spiffworkflow-frontend/src/themes/index.ts b/spiffworkflow-frontend/src/themes/index.ts deleted file mode 100644 index 2f409639e..000000000 --- a/spiffworkflow-frontend/src/themes/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -import Form from './Form/Form'; - -export { default as Form } from './Form'; -export { default as Templates } from './Templates'; -export { default as Theme } from './Theme'; -export { default as Widgets } from './Widgets'; - -export default Form; From 95442a03cf6d48df48952a5f32d3ab4203631343 Mon Sep 17 00:00:00 2001 From: jasquat Date: Wed, 16 Nov 2022 13:59:09 -0500 Subject: [PATCH 03/10] copied mui theme to use as base for carbon theme w/ burnettk cullerton --- spiffworkflow-frontend/package-lock.json | 51 +++------- spiffworkflow-frontend/package.json | 1 + .../src/routes/TaskShow.tsx | 4 +- .../src/themes/carbon/AddButton/AddButton.tsx | 17 ++++ .../src/themes/carbon/AddButton/index.ts | 2 + .../ArrayFieldItemTemplate.tsx | 72 ++++++++++++++ .../carbon/ArrayFieldItemTemplate/index.ts | 2 + .../ArrayFieldTemplate/ArrayFieldTemplate.tsx | 90 ++++++++++++++++++ .../themes/carbon/ArrayFieldTemplate/index.ts | 2 + .../BaseInputTemplate/BaseInputTemplate.tsx | 82 ++++++++++++++++ .../themes/carbon/BaseInputTemplate/index.ts | 2 + .../carbon/CheckboxWidget/CheckboxWidget.tsx | 52 +++++++++++ .../src/themes/carbon/CheckboxWidget/index.ts | 2 + .../CheckboxesWidget/CheckboxesWidget.tsx | 93 +++++++++++++++++++ .../themes/carbon/CheckboxesWidget/index.ts | 2 + .../carbon/DateTimeWidget/DateTimeWidget.tsx | 29 ++++++ .../src/themes/carbon/DateTimeWidget/index.ts | 2 + .../themes/carbon/DateWidget/DateWidget.tsx | 22 +++++ .../src/themes/carbon/DateWidget/index.ts | 2 + .../DescriptionField/DescriptionField.tsx | 17 ++++ .../themes/carbon/DescriptionField/index.ts | 2 + .../src/themes/carbon/ErrorList/ErrorList.tsx | 34 +++++++ .../src/themes/carbon/ErrorList/index.ts | 2 + .../FieldErrorTemplate/FieldErrorTemplate.tsx | 29 ++++++ .../themes/carbon/FieldErrorTemplate/index.ts | 2 + .../FieldHelpTemplate/FieldHelpTemplate.tsx | 16 ++++ .../themes/carbon/FieldHelpTemplate/index.ts | 2 + .../carbon/FieldTemplate/FieldTemplate.tsx | 64 +++++++++++++ .../src/themes/carbon/FieldTemplate/index.ts | 2 + .../themes/carbon/IconButton/IconButton.tsx | 55 +++++++++++ .../src/themes/carbon/IconButton/index.ts | 2 + .../src/themes/carbon/MuiForm/MuiForm.tsx | 8 ++ .../src/themes/carbon/MuiForm/index.ts | 2 + .../ObjectFieldTemplate.tsx | 89 ++++++++++++++++++ .../carbon/ObjectFieldTemplate/index.ts | 2 + .../themes/carbon/RadioWidget/RadioWidget.tsx | 73 +++++++++++++++ .../src/themes/carbon/RadioWidget/index.ts | 2 + .../themes/carbon/RangeWidget/RangeWidget.tsx | 47 ++++++++++ .../src/themes/carbon/RangeWidget/index.ts | 2 + .../carbon/SelectWidget/SelectWidget.tsx | 71 ++++++++++++++ .../src/themes/carbon/SelectWidget/index.ts | 2 + .../carbon/SubmitButton/SubmitButton.tsx | 29 ++++++ .../src/themes/carbon/SubmitButton/index.ts | 2 + .../src/themes/carbon/Templates/Templates.ts | 35 +++++++ .../src/themes/carbon/Templates/index.ts | 2 + .../carbon/TextareaWidget/TextareaWidget.tsx | 20 ++++ .../src/themes/carbon/TextareaWidget/index.ts | 2 + .../src/themes/carbon/Theme/Theme.tsx | 11 +++ .../src/themes/carbon/Theme/index.ts | 2 + .../themes/carbon/TitleField/TitleField.tsx | 16 ++++ .../src/themes/carbon/TitleField/index.ts | 2 + .../src/themes/carbon/Widgets/Widgets.ts | 19 ++++ .../src/themes/carbon/Widgets/index.ts | 2 + .../WrapIfAdditionalTemplate.tsx | 80 ++++++++++++++++ .../carbon/WrapIfAdditionalTemplate/index.ts | 2 + .../src/themes/carbon/index.ts | 8 ++ 56 files changed, 1243 insertions(+), 43 deletions(-) create mode 100644 spiffworkflow-frontend/src/themes/carbon/AddButton/AddButton.tsx create mode 100644 spiffworkflow-frontend/src/themes/carbon/AddButton/index.ts create mode 100644 spiffworkflow-frontend/src/themes/carbon/ArrayFieldItemTemplate/ArrayFieldItemTemplate.tsx create mode 100644 spiffworkflow-frontend/src/themes/carbon/ArrayFieldItemTemplate/index.ts create mode 100644 spiffworkflow-frontend/src/themes/carbon/ArrayFieldTemplate/ArrayFieldTemplate.tsx create mode 100644 spiffworkflow-frontend/src/themes/carbon/ArrayFieldTemplate/index.ts create mode 100644 spiffworkflow-frontend/src/themes/carbon/BaseInputTemplate/BaseInputTemplate.tsx create mode 100644 spiffworkflow-frontend/src/themes/carbon/BaseInputTemplate/index.ts create mode 100644 spiffworkflow-frontend/src/themes/carbon/CheckboxWidget/CheckboxWidget.tsx create mode 100644 spiffworkflow-frontend/src/themes/carbon/CheckboxWidget/index.ts create mode 100644 spiffworkflow-frontend/src/themes/carbon/CheckboxesWidget/CheckboxesWidget.tsx create mode 100644 spiffworkflow-frontend/src/themes/carbon/CheckboxesWidget/index.ts create mode 100644 spiffworkflow-frontend/src/themes/carbon/DateTimeWidget/DateTimeWidget.tsx create mode 100644 spiffworkflow-frontend/src/themes/carbon/DateTimeWidget/index.ts create mode 100644 spiffworkflow-frontend/src/themes/carbon/DateWidget/DateWidget.tsx create mode 100644 spiffworkflow-frontend/src/themes/carbon/DateWidget/index.ts create mode 100644 spiffworkflow-frontend/src/themes/carbon/DescriptionField/DescriptionField.tsx create mode 100644 spiffworkflow-frontend/src/themes/carbon/DescriptionField/index.ts create mode 100644 spiffworkflow-frontend/src/themes/carbon/ErrorList/ErrorList.tsx create mode 100644 spiffworkflow-frontend/src/themes/carbon/ErrorList/index.ts create mode 100644 spiffworkflow-frontend/src/themes/carbon/FieldErrorTemplate/FieldErrorTemplate.tsx create mode 100644 spiffworkflow-frontend/src/themes/carbon/FieldErrorTemplate/index.ts create mode 100644 spiffworkflow-frontend/src/themes/carbon/FieldHelpTemplate/FieldHelpTemplate.tsx create mode 100644 spiffworkflow-frontend/src/themes/carbon/FieldHelpTemplate/index.ts create mode 100644 spiffworkflow-frontend/src/themes/carbon/FieldTemplate/FieldTemplate.tsx create mode 100644 spiffworkflow-frontend/src/themes/carbon/FieldTemplate/index.ts create mode 100644 spiffworkflow-frontend/src/themes/carbon/IconButton/IconButton.tsx create mode 100644 spiffworkflow-frontend/src/themes/carbon/IconButton/index.ts create mode 100644 spiffworkflow-frontend/src/themes/carbon/MuiForm/MuiForm.tsx create mode 100644 spiffworkflow-frontend/src/themes/carbon/MuiForm/index.ts create mode 100644 spiffworkflow-frontend/src/themes/carbon/ObjectFieldTemplate/ObjectFieldTemplate.tsx create mode 100644 spiffworkflow-frontend/src/themes/carbon/ObjectFieldTemplate/index.ts create mode 100644 spiffworkflow-frontend/src/themes/carbon/RadioWidget/RadioWidget.tsx create mode 100644 spiffworkflow-frontend/src/themes/carbon/RadioWidget/index.ts create mode 100644 spiffworkflow-frontend/src/themes/carbon/RangeWidget/RangeWidget.tsx create mode 100644 spiffworkflow-frontend/src/themes/carbon/RangeWidget/index.ts create mode 100644 spiffworkflow-frontend/src/themes/carbon/SelectWidget/SelectWidget.tsx create mode 100644 spiffworkflow-frontend/src/themes/carbon/SelectWidget/index.ts create mode 100644 spiffworkflow-frontend/src/themes/carbon/SubmitButton/SubmitButton.tsx create mode 100644 spiffworkflow-frontend/src/themes/carbon/SubmitButton/index.ts create mode 100644 spiffworkflow-frontend/src/themes/carbon/Templates/Templates.ts create mode 100644 spiffworkflow-frontend/src/themes/carbon/Templates/index.ts create mode 100644 spiffworkflow-frontend/src/themes/carbon/TextareaWidget/TextareaWidget.tsx create mode 100644 spiffworkflow-frontend/src/themes/carbon/TextareaWidget/index.ts create mode 100644 spiffworkflow-frontend/src/themes/carbon/Theme/Theme.tsx create mode 100644 spiffworkflow-frontend/src/themes/carbon/Theme/index.ts create mode 100644 spiffworkflow-frontend/src/themes/carbon/TitleField/TitleField.tsx create mode 100644 spiffworkflow-frontend/src/themes/carbon/TitleField/index.ts create mode 100644 spiffworkflow-frontend/src/themes/carbon/Widgets/Widgets.ts create mode 100644 spiffworkflow-frontend/src/themes/carbon/Widgets/index.ts create mode 100644 spiffworkflow-frontend/src/themes/carbon/WrapIfAdditionalTemplate/WrapIfAdditionalTemplate.tsx create mode 100644 spiffworkflow-frontend/src/themes/carbon/WrapIfAdditionalTemplate/index.ts create mode 100644 spiffworkflow-frontend/src/themes/carbon/index.ts diff --git a/spiffworkflow-frontend/package-lock.json b/spiffworkflow-frontend/package-lock.json index f03d57818..bb88fc990 100644 --- a/spiffworkflow-frontend/package-lock.json +++ b/spiffworkflow-frontend/package-lock.json @@ -18,6 +18,7 @@ "@casl/react": "^3.1.0", "@ginkgo-bioworks/react-json-schema-form-builder": "^2.9.0", "@monaco-editor/react": "^4.4.5", + "@mui/material": "^5.10.14", "@react-icons/all-files": "^4.1.0", "@rjsf/core": "*", "@rjsf/mui": "^5.0.0-beta.13", @@ -4447,7 +4448,6 @@ "version": "5.0.0-alpha.106", "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-alpha.106.tgz", "integrity": "sha512-xJQQtwPCPwr6hGWTBdvDwHYwExn3Bw7nPQkN8Fuz8kHpZqoMVWQvvaFS557AIkkI2AFLV3DxVIMjbCvrIntBWg==", - "peer": true, "dependencies": { "@babel/runtime": "^7.20.1", "@emotion/is-prop-valid": "^1.2.0", @@ -4480,7 +4480,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.0.tgz", "integrity": "sha512-3aDpDprjM0AwaxGE09bOPkNxHpBd+kA6jty3RnaEXdweX1DF1U3VQpPYb0g1IStAuK7SVQ1cy+bNBBKp4W3Fjg==", - "peer": true, "dependencies": { "@emotion/memoize": "^0.8.0" } @@ -4488,20 +4487,17 @@ "node_modules/@mui/base/node_modules/@emotion/memoize": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.0.tgz", - "integrity": "sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA==", - "peer": true + "integrity": "sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA==" }, "node_modules/@mui/base/node_modules/react-is": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "peer": true + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" }, "node_modules/@mui/core-downloads-tracker": { "version": "5.10.14", "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.10.14.tgz", "integrity": "sha512-qLgIJNOR9Dre8JiZ/neVzOf4jf88J6YtOkQqugtMrleLjbfRVUSS4LWl9CSOjNq76quYdmYWnSDgfQqOooT2cQ==", - "peer": true, "funding": { "type": "opencollective", "url": "https://opencollective.com/mui" @@ -4537,7 +4533,6 @@ "version": "5.10.14", "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.10.14.tgz", "integrity": "sha512-HWzKVAykePMx54WtxVwZyL1W4k3xlHYIqwMw0CaXAvgB3UE9yjABZuuGr8vG5Z6CSNWamzd+s1x8u7pQPFl9og==", - "peer": true, "dependencies": { "@babel/runtime": "^7.20.1", "@mui/base": "5.0.0-alpha.106", @@ -4581,14 +4576,12 @@ "node_modules/@mui/material/node_modules/react-is": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "peer": true + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" }, "node_modules/@mui/private-theming": { "version": "5.10.14", "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.10.14.tgz", "integrity": "sha512-3aIBe8WK65CwAPDY8nB11hYnzE1CZMymi76UnaFrA/DdGDwl5Y8F6uB+StKrkVmsqF1po7Mp2odqVkHj320gXw==", - "peer": true, "dependencies": { "@babel/runtime": "^7.20.1", "@mui/utils": "^5.10.14", @@ -4615,7 +4608,6 @@ "version": "5.10.14", "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.10.14.tgz", "integrity": "sha512-bgKdM57ExogWpIfhL/ngSlzF4FhbH00vYF+Y5VALTob4uslFqje0xzoWmbfcCn4cZt2NXxZJIwhsq4vzo5itlw==", - "peer": true, "dependencies": { "@babel/runtime": "^7.20.1", "@emotion/cache": "^11.10.5", @@ -4647,7 +4639,6 @@ "version": "5.10.14", "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.10.14.tgz", "integrity": "sha512-2de7XCjRb1j8Od0Stmo0LwFMLpOMNT4wzfINuExXI1TVSuyxXIXUxiC5FEgJW3GMvf/a7SUR8VOiMoKlKWzukw==", - "peer": true, "dependencies": { "@babel/runtime": "^7.20.1", "@mui/private-theming": "^5.10.14", @@ -4687,7 +4678,6 @@ "version": "7.2.1", "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.1.tgz", "integrity": "sha512-c5mSM7ivD8EsqK6HUi9hQPr5V7TJ/IRThUQ9nWNYPdhCGriTSQV4vL6DflT99LkM+wLiIS1rVjphpEWxERep7A==", - "peer": true, "peerDependencies": { "@types/react": "*" }, @@ -4701,7 +4691,6 @@ "version": "5.10.14", "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.10.14.tgz", "integrity": "sha512-12p59+wDZpA++XVJmKwqsZmrA1nmUQ5d0a1yQWtcDjxNyER1EDzozYN/db+FY2i5ceQh2TynPTEwGms2mXDwFg==", - "peer": true, "dependencies": { "@babel/runtime": "^7.20.1", "@types/prop-types": "^15.7.5", @@ -4723,8 +4712,7 @@ "node_modules/@mui/utils/node_modules/react-is": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "peer": true + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", @@ -5921,7 +5909,6 @@ "version": "17.0.3", "resolved": "https://registry.npmjs.org/@types/react-is/-/react-is-17.0.3.tgz", "integrity": "sha512-aBTIWg1emtu95bLTLx0cpkxwGW3ueZv71nE2YFBpL8k/z5czEW8yYpOo8Dp+UUAFAtKwNaOsh/ioSeQnWlZcfw==", - "peer": true, "dependencies": { "@types/react": "*" } @@ -8977,7 +8964,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==", - "peer": true, "engines": { "node": ">=6" } @@ -34603,7 +34589,6 @@ "version": "5.0.0-alpha.106", "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-alpha.106.tgz", "integrity": "sha512-xJQQtwPCPwr6hGWTBdvDwHYwExn3Bw7nPQkN8Fuz8kHpZqoMVWQvvaFS557AIkkI2AFLV3DxVIMjbCvrIntBWg==", - "peer": true, "requires": { "@babel/runtime": "^7.20.1", "@emotion/is-prop-valid": "^1.2.0", @@ -34619,7 +34604,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.0.tgz", "integrity": "sha512-3aDpDprjM0AwaxGE09bOPkNxHpBd+kA6jty3RnaEXdweX1DF1U3VQpPYb0g1IStAuK7SVQ1cy+bNBBKp4W3Fjg==", - "peer": true, "requires": { "@emotion/memoize": "^0.8.0" } @@ -34627,22 +34611,19 @@ "@emotion/memoize": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.0.tgz", - "integrity": "sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA==", - "peer": true + "integrity": "sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA==" }, "react-is": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "peer": true + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" } } }, "@mui/core-downloads-tracker": { "version": "5.10.14", "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.10.14.tgz", - "integrity": "sha512-qLgIJNOR9Dre8JiZ/neVzOf4jf88J6YtOkQqugtMrleLjbfRVUSS4LWl9CSOjNq76quYdmYWnSDgfQqOooT2cQ==", - "peer": true + "integrity": "sha512-qLgIJNOR9Dre8JiZ/neVzOf4jf88J6YtOkQqugtMrleLjbfRVUSS4LWl9CSOjNq76quYdmYWnSDgfQqOooT2cQ==" }, "@mui/icons-material": { "version": "5.10.14", @@ -34657,7 +34638,6 @@ "version": "5.10.14", "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.10.14.tgz", "integrity": "sha512-HWzKVAykePMx54WtxVwZyL1W4k3xlHYIqwMw0CaXAvgB3UE9yjABZuuGr8vG5Z6CSNWamzd+s1x8u7pQPFl9og==", - "peer": true, "requires": { "@babel/runtime": "^7.20.1", "@mui/base": "5.0.0-alpha.106", @@ -34676,8 +34656,7 @@ "react-is": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "peer": true + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" } } }, @@ -34685,7 +34664,6 @@ "version": "5.10.14", "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.10.14.tgz", "integrity": "sha512-3aIBe8WK65CwAPDY8nB11hYnzE1CZMymi76UnaFrA/DdGDwl5Y8F6uB+StKrkVmsqF1po7Mp2odqVkHj320gXw==", - "peer": true, "requires": { "@babel/runtime": "^7.20.1", "@mui/utils": "^5.10.14", @@ -34696,7 +34674,6 @@ "version": "5.10.14", "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.10.14.tgz", "integrity": "sha512-bgKdM57ExogWpIfhL/ngSlzF4FhbH00vYF+Y5VALTob4uslFqje0xzoWmbfcCn4cZt2NXxZJIwhsq4vzo5itlw==", - "peer": true, "requires": { "@babel/runtime": "^7.20.1", "@emotion/cache": "^11.10.5", @@ -34708,7 +34685,6 @@ "version": "5.10.14", "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.10.14.tgz", "integrity": "sha512-2de7XCjRb1j8Od0Stmo0LwFMLpOMNT4wzfINuExXI1TVSuyxXIXUxiC5FEgJW3GMvf/a7SUR8VOiMoKlKWzukw==", - "peer": true, "requires": { "@babel/runtime": "^7.20.1", "@mui/private-theming": "^5.10.14", @@ -34724,14 +34700,12 @@ "version": "7.2.1", "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.1.tgz", "integrity": "sha512-c5mSM7ivD8EsqK6HUi9hQPr5V7TJ/IRThUQ9nWNYPdhCGriTSQV4vL6DflT99LkM+wLiIS1rVjphpEWxERep7A==", - "peer": true, "requires": {} }, "@mui/utils": { "version": "5.10.14", "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.10.14.tgz", "integrity": "sha512-12p59+wDZpA++XVJmKwqsZmrA1nmUQ5d0a1yQWtcDjxNyER1EDzozYN/db+FY2i5ceQh2TynPTEwGms2mXDwFg==", - "peer": true, "requires": { "@babel/runtime": "^7.20.1", "@types/prop-types": "^15.7.5", @@ -34743,8 +34717,7 @@ "react-is": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "peer": true + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" } } }, @@ -35627,7 +35600,6 @@ "version": "17.0.3", "resolved": "https://registry.npmjs.org/@types/react-is/-/react-is-17.0.3.tgz", "integrity": "sha512-aBTIWg1emtu95bLTLx0cpkxwGW3ueZv71nE2YFBpL8k/z5czEW8yYpOo8Dp+UUAFAtKwNaOsh/ioSeQnWlZcfw==", - "peer": true, "requires": { "@types/react": "*" } @@ -37942,8 +37914,7 @@ "clsx": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", - "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==", - "peer": true + "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==" }, "co": { "version": "4.6.0", diff --git a/spiffworkflow-frontend/package.json b/spiffworkflow-frontend/package.json index ebc77e74e..00a2cb747 100644 --- a/spiffworkflow-frontend/package.json +++ b/spiffworkflow-frontend/package.json @@ -13,6 +13,7 @@ "@casl/react": "^3.1.0", "@ginkgo-bioworks/react-json-schema-form-builder": "^2.9.0", "@monaco-editor/react": "^4.4.5", + "@mui/material": "^5.10.14", "@react-icons/all-files": "^4.1.0", "@rjsf/core": "*", "@rjsf/mui": "^5.0.0-beta.13", diff --git a/spiffworkflow-frontend/src/routes/TaskShow.tsx b/spiffworkflow-frontend/src/routes/TaskShow.tsx index b64880a78..818670952 100644 --- a/spiffworkflow-frontend/src/routes/TaskShow.tsx +++ b/spiffworkflow-frontend/src/routes/TaskShow.tsx @@ -1,7 +1,5 @@ import { useContext, useEffect, useState } from 'react'; import { Link, useNavigate, useParams } from 'react-router-dom'; -// import Form from '@rjsf/core'; -import Form from '@rjsf/mui'; import validator from '@rjsf/validator-ajv8'; // @ts-ignore @@ -9,7 +7,7 @@ import { Button, Stack } from '@carbon/react'; import ReactMarkdown from 'react-markdown'; import remarkGfm from 'remark-gfm'; -// import Form from '../themes'; +import Form from '../themes/carbon'; import HttpService from '../services/HttpService'; import ErrorContext from '../contexts/ErrorContext'; import { modifyProcessModelPath } from '../helpers'; diff --git a/spiffworkflow-frontend/src/themes/carbon/AddButton/AddButton.tsx b/spiffworkflow-frontend/src/themes/carbon/AddButton/AddButton.tsx new file mode 100644 index 000000000..d145a4c45 --- /dev/null +++ b/spiffworkflow-frontend/src/themes/carbon/AddButton/AddButton.tsx @@ -0,0 +1,17 @@ +import React from 'react'; +import AddIcon from '@mui/icons-material/Add'; +import IconButton from '@mui/material/IconButton'; +import { IconButtonProps } from '@rjsf/utils'; + +const AddButton: React.ComponentType = ({ + uiSchema, + ...props +}) => { + return ( + + + + ); +}; + +export default AddButton; diff --git a/spiffworkflow-frontend/src/themes/carbon/AddButton/index.ts b/spiffworkflow-frontend/src/themes/carbon/AddButton/index.ts new file mode 100644 index 000000000..752d720d3 --- /dev/null +++ b/spiffworkflow-frontend/src/themes/carbon/AddButton/index.ts @@ -0,0 +1,2 @@ +export { default } from './AddButton'; +export * from './AddButton'; diff --git a/spiffworkflow-frontend/src/themes/carbon/ArrayFieldItemTemplate/ArrayFieldItemTemplate.tsx b/spiffworkflow-frontend/src/themes/carbon/ArrayFieldItemTemplate/ArrayFieldItemTemplate.tsx new file mode 100644 index 000000000..b09acfb9d --- /dev/null +++ b/spiffworkflow-frontend/src/themes/carbon/ArrayFieldItemTemplate/ArrayFieldItemTemplate.tsx @@ -0,0 +1,72 @@ +import React, { CSSProperties } from 'react'; +import Box from '@mui/material/Box'; +import Grid from '@mui/material/Grid'; +import Paper from '@mui/material/Paper'; +import { ArrayFieldTemplateItemType } from '@rjsf/utils'; + +function ArrayFieldItemTemplate(props: ArrayFieldTemplateItemType) { + const { + children, + disabled, + hasToolbar, + hasMoveDown, + hasMoveUp, + hasRemove, + index, + onDropIndexClick, + onReorderClick, + readonly, + uiSchema, + registry, + } = props; + const { MoveDownButton, MoveUpButton, RemoveButton } = + registry.templates.ButtonTemplates; + const btnStyle: CSSProperties = { + flex: 1, + paddingLeft: 6, + paddingRight: 6, + fontWeight: 'bold', + minWidth: 0, + }; + return ( + + + + + {children} + + + + {hasToolbar && ( + + {(hasMoveUp || hasMoveDown) && ( + + )} + {(hasMoveUp || hasMoveDown) && ( + + )} + {hasRemove && ( + + )} + + )} + + ); +} + +export default ArrayFieldItemTemplate; diff --git a/spiffworkflow-frontend/src/themes/carbon/ArrayFieldItemTemplate/index.ts b/spiffworkflow-frontend/src/themes/carbon/ArrayFieldItemTemplate/index.ts new file mode 100644 index 000000000..f10443139 --- /dev/null +++ b/spiffworkflow-frontend/src/themes/carbon/ArrayFieldItemTemplate/index.ts @@ -0,0 +1,2 @@ +export { default } from './ArrayFieldItemTemplate'; +export * from './ArrayFieldItemTemplate'; diff --git a/spiffworkflow-frontend/src/themes/carbon/ArrayFieldTemplate/ArrayFieldTemplate.tsx b/spiffworkflow-frontend/src/themes/carbon/ArrayFieldTemplate/ArrayFieldTemplate.tsx new file mode 100644 index 000000000..03c88951e --- /dev/null +++ b/spiffworkflow-frontend/src/themes/carbon/ArrayFieldTemplate/ArrayFieldTemplate.tsx @@ -0,0 +1,90 @@ +import React from 'react'; +import Box from '@mui/material/Box'; +import Grid from '@mui/material/Grid'; +import Paper from '@mui/material/Paper'; +import { + ArrayFieldTemplateItemType, + ArrayFieldTemplateProps, + getTemplate, + getUiOptions, +} from '@rjsf/utils'; + +function ArrayFieldTemplate(props: ArrayFieldTemplateProps) { + const { + canAdd, + disabled, + idSchema, + uiSchema, + items, + onAddClick, + readonly, + registry, + required, + schema, + title, + } = props; + const uiOptions = getUiOptions(uiSchema); + const ArrayFieldDescriptionTemplate = + getTemplate<'ArrayFieldDescriptionTemplate'>( + 'ArrayFieldDescriptionTemplate', + registry, + uiOptions + ); + const ArrayFieldItemTemplate = getTemplate<'ArrayFieldItemTemplate'>( + 'ArrayFieldItemTemplate', + registry, + uiOptions + ); + const ArrayFieldTitleTemplate = getTemplate<'ArrayFieldTitleTemplate'>( + 'ArrayFieldTitleTemplate', + registry, + uiOptions + ); + // Button templates are not overridden in the uiSchema + const { + ButtonTemplates: { AddButton }, + } = registry.templates; + return ( + + + + + + {items && + items.map(({ key, ...itemProps }: ArrayFieldTemplateItemType) => ( + + ))} + {canAdd && ( + + + + + + + + )} + + + + ); +} + +export default ArrayFieldTemplate; diff --git a/spiffworkflow-frontend/src/themes/carbon/ArrayFieldTemplate/index.ts b/spiffworkflow-frontend/src/themes/carbon/ArrayFieldTemplate/index.ts new file mode 100644 index 000000000..ab908dec2 --- /dev/null +++ b/spiffworkflow-frontend/src/themes/carbon/ArrayFieldTemplate/index.ts @@ -0,0 +1,2 @@ +export { default } from './ArrayFieldTemplate'; +export * from './ArrayFieldTemplate'; diff --git a/spiffworkflow-frontend/src/themes/carbon/BaseInputTemplate/BaseInputTemplate.tsx b/spiffworkflow-frontend/src/themes/carbon/BaseInputTemplate/BaseInputTemplate.tsx new file mode 100644 index 000000000..1a9ad5a10 --- /dev/null +++ b/spiffworkflow-frontend/src/themes/carbon/BaseInputTemplate/BaseInputTemplate.tsx @@ -0,0 +1,82 @@ +import React from 'react'; +import TextField, { TextFieldProps } from '@mui/material/TextField'; +import { getInputProps, WidgetProps } from '@rjsf/utils'; + +function BaseInputTemplate({ + id, + placeholder, + required, + readonly, + disabled, + type, + label, + value, + onChange, + onBlur, + onFocus, + autofocus, + options, + schema, + uiSchema, + rawErrors = [], + formContext, + registry, + ...textFieldProps +}: WidgetProps) { + const inputProps = getInputProps(schema, type, options); + // Now we need to pull out the step, min, max into an inner `inputProps` for material-ui + const { step, min, max, ...rest } = inputProps; + const otherProps = { + inputProps: { + step, + min, + max, + ...(schema.examples ? { list: `examples_${id}` } : undefined), + }, + ...rest, + }; + const _onChange = ({ + target: { value }, + }: React.ChangeEvent) => + onChange(value === '' ? options.emptyValue : value); + const _onBlur = ({ target: { value } }: React.FocusEvent) => + onBlur(id, value); + const _onFocus = ({ + target: { value }, + }: React.FocusEvent) => onFocus(id, value); + + const { schemaUtils } = registry; + const displayLabel = schemaUtils.getDisplayLabel(schema, uiSchema); + + return ( + <> + 0} + onChange={_onChange} + onBlur={_onBlur} + onFocus={_onFocus} + {...(textFieldProps as TextFieldProps)} + /> + {schema.examples && ( + + {(schema.examples as string[]) + .concat(schema.default ? ([schema.default] as string[]) : []) + .map((example: any) => { + return + )} + + ); +} + +export default BaseInputTemplate; diff --git a/spiffworkflow-frontend/src/themes/carbon/BaseInputTemplate/index.ts b/spiffworkflow-frontend/src/themes/carbon/BaseInputTemplate/index.ts new file mode 100644 index 000000000..f7ef8d593 --- /dev/null +++ b/spiffworkflow-frontend/src/themes/carbon/BaseInputTemplate/index.ts @@ -0,0 +1,2 @@ +export { default } from './BaseInputTemplate'; +export * from './BaseInputTemplate'; diff --git a/spiffworkflow-frontend/src/themes/carbon/CheckboxWidget/CheckboxWidget.tsx b/spiffworkflow-frontend/src/themes/carbon/CheckboxWidget/CheckboxWidget.tsx new file mode 100644 index 000000000..6d2303a6e --- /dev/null +++ b/spiffworkflow-frontend/src/themes/carbon/CheckboxWidget/CheckboxWidget.tsx @@ -0,0 +1,52 @@ +import React from 'react'; +import Checkbox from '@mui/material/Checkbox'; +import FormControlLabel from '@mui/material/FormControlLabel'; +import { schemaRequiresTrueValue, WidgetProps } from '@rjsf/utils'; + +function CheckboxWidget(props: WidgetProps) { + const { + schema, + id, + value, + disabled, + readonly, + label, + autofocus, + onChange, + onBlur, + onFocus, + } = props; + // Because an unchecked checkbox will cause html5 validation to fail, only add + // the "required" attribute if the field value must be "true", due to the + // "const" or "enum" keywords + const required = schemaRequiresTrueValue(schema); + + const _onChange = (_: any, checked: boolean) => onChange(checked); + const _onBlur = ({ + target: { value }, + }: React.FocusEvent) => onBlur(id, value); + const _onFocus = ({ + target: { value }, + }: React.FocusEvent) => onFocus(id, value); + + return ( + + } + label={label || ''} + /> + ); +} + +export default CheckboxWidget; diff --git a/spiffworkflow-frontend/src/themes/carbon/CheckboxWidget/index.ts b/spiffworkflow-frontend/src/themes/carbon/CheckboxWidget/index.ts new file mode 100644 index 000000000..b9e3c318e --- /dev/null +++ b/spiffworkflow-frontend/src/themes/carbon/CheckboxWidget/index.ts @@ -0,0 +1,2 @@ +export { default } from './CheckboxWidget'; +export * from './CheckboxWidget'; diff --git a/spiffworkflow-frontend/src/themes/carbon/CheckboxesWidget/CheckboxesWidget.tsx b/spiffworkflow-frontend/src/themes/carbon/CheckboxesWidget/CheckboxesWidget.tsx new file mode 100644 index 000000000..6d821cdb6 --- /dev/null +++ b/spiffworkflow-frontend/src/themes/carbon/CheckboxesWidget/CheckboxesWidget.tsx @@ -0,0 +1,93 @@ +import React from 'react'; +import Checkbox from '@mui/material/Checkbox'; +import FormControlLabel from '@mui/material/FormControlLabel'; +import FormGroup from '@mui/material/FormGroup'; +import FormLabel from '@mui/material/FormLabel'; +import { WidgetProps } from '@rjsf/utils'; + +const selectValue = (value: any, selected: any, all: any) => { + const at = all.indexOf(value); + const updated = selected.slice(0, at).concat(value, selected.slice(at)); + + // As inserting values at predefined index positions doesn't work with empty + // arrays, we need to reorder the updated selection to match the initial order + return updated.sort((a: any, b: any) => all.indexOf(a) > all.indexOf(b)); +}; + +const deselectValue = (value: any, selected: any) => { + return selected.filter((v: any) => v !== value); +}; + +function CheckboxesWidget({ + schema, + label, + id, + disabled, + options, + value, + autofocus, + readonly, + required, + onChange, + onBlur, + onFocus, +}: WidgetProps) { + const { enumOptions, enumDisabled, inline } = options; + + const _onChange = + (option: any) => + ({ target: { checked } }: React.ChangeEvent) => { + const all = (enumOptions as any).map(({ value }: any) => value); + + if (checked) { + onChange(selectValue(option.value, value, all)); + } else { + onChange(deselectValue(option.value, value)); + } + }; + + const _onBlur = ({ + target: { value }, + }: React.FocusEvent) => onBlur(id, value); + const _onFocus = ({ + target: { value }, + }: React.FocusEvent) => onFocus(id, value); + + return ( + <> + + {label || schema.title} + + + {Array.isArray(enumOptions) && + enumOptions.map((option, index: number) => { + const checked = value.indexOf(option.value) !== -1; + const itemDisabled = + Array.isArray(enumDisabled) && + enumDisabled.indexOf(option.value) !== -1; + const checkbox = ( + + ); + return ( + + ); + })} + + + ); +} + +export default CheckboxesWidget; diff --git a/spiffworkflow-frontend/src/themes/carbon/CheckboxesWidget/index.ts b/spiffworkflow-frontend/src/themes/carbon/CheckboxesWidget/index.ts new file mode 100644 index 000000000..97152004f --- /dev/null +++ b/spiffworkflow-frontend/src/themes/carbon/CheckboxesWidget/index.ts @@ -0,0 +1,2 @@ +export { default } from './CheckboxesWidget'; +export * from './CheckboxesWidget'; diff --git a/spiffworkflow-frontend/src/themes/carbon/DateTimeWidget/DateTimeWidget.tsx b/spiffworkflow-frontend/src/themes/carbon/DateTimeWidget/DateTimeWidget.tsx new file mode 100644 index 000000000..df26f459b --- /dev/null +++ b/spiffworkflow-frontend/src/themes/carbon/DateTimeWidget/DateTimeWidget.tsx @@ -0,0 +1,29 @@ +import React from 'react'; +import { getTemplate, localToUTC, utcToLocal, WidgetProps } from '@rjsf/utils'; + +function DateTimeWidget(props: WidgetProps) { + const { options, registry } = props; + const BaseInputTemplate = getTemplate<'BaseInputTemplate'>( + 'BaseInputTemplate', + registry, + options + ); + const value = utcToLocal(props.value); + const onChange = (value: any) => { + props.onChange(localToUTC(value)); + }; + + return ( + + ); +} + +export default DateTimeWidget; diff --git a/spiffworkflow-frontend/src/themes/carbon/DateTimeWidget/index.ts b/spiffworkflow-frontend/src/themes/carbon/DateTimeWidget/index.ts new file mode 100644 index 000000000..0db366167 --- /dev/null +++ b/spiffworkflow-frontend/src/themes/carbon/DateTimeWidget/index.ts @@ -0,0 +1,2 @@ +export { default } from './DateTimeWidget'; +export * from './DateTimeWidget'; diff --git a/spiffworkflow-frontend/src/themes/carbon/DateWidget/DateWidget.tsx b/spiffworkflow-frontend/src/themes/carbon/DateWidget/DateWidget.tsx new file mode 100644 index 000000000..fcf7cfcfe --- /dev/null +++ b/spiffworkflow-frontend/src/themes/carbon/DateWidget/DateWidget.tsx @@ -0,0 +1,22 @@ +import React from 'react'; +import { getTemplate, WidgetProps } from '@rjsf/utils'; + +function DateWidget(props: WidgetProps) { + const { options, registry } = props; + const BaseInputTemplate = getTemplate<'BaseInputTemplate'>( + 'BaseInputTemplate', + registry, + options + ); + return ( + + ); +} + +export default DateWidget; diff --git a/spiffworkflow-frontend/src/themes/carbon/DateWidget/index.ts b/spiffworkflow-frontend/src/themes/carbon/DateWidget/index.ts new file mode 100644 index 000000000..923b0077f --- /dev/null +++ b/spiffworkflow-frontend/src/themes/carbon/DateWidget/index.ts @@ -0,0 +1,2 @@ +export { default } from './DateWidget'; +export * from './DateWidget'; diff --git a/spiffworkflow-frontend/src/themes/carbon/DescriptionField/DescriptionField.tsx b/spiffworkflow-frontend/src/themes/carbon/DescriptionField/DescriptionField.tsx new file mode 100644 index 000000000..a54657643 --- /dev/null +++ b/spiffworkflow-frontend/src/themes/carbon/DescriptionField/DescriptionField.tsx @@ -0,0 +1,17 @@ +import React from 'react'; +import Typography from '@mui/material/Typography'; +import { DescriptionFieldProps } from '@rjsf/utils'; + +function DescriptionField({ description, id }: DescriptionFieldProps) { + if (description) { + return ( + + {description} + + ); + } + + return null; +} + +export default DescriptionField; diff --git a/spiffworkflow-frontend/src/themes/carbon/DescriptionField/index.ts b/spiffworkflow-frontend/src/themes/carbon/DescriptionField/index.ts new file mode 100644 index 000000000..401540d99 --- /dev/null +++ b/spiffworkflow-frontend/src/themes/carbon/DescriptionField/index.ts @@ -0,0 +1,2 @@ +export { default } from './DescriptionField'; +export * from './DescriptionField'; diff --git a/spiffworkflow-frontend/src/themes/carbon/ErrorList/ErrorList.tsx b/spiffworkflow-frontend/src/themes/carbon/ErrorList/ErrorList.tsx new file mode 100644 index 000000000..95f410766 --- /dev/null +++ b/spiffworkflow-frontend/src/themes/carbon/ErrorList/ErrorList.tsx @@ -0,0 +1,34 @@ +import React from 'react'; +import ErrorIcon from '@mui/icons-material/Error'; +import Box from '@mui/material/Box'; +import List from '@mui/material/List'; +import ListItem from '@mui/material/ListItem'; +import ListItemIcon from '@mui/material/ListItemIcon'; +import ListItemText from '@mui/material/ListItemText'; +import Paper from '@mui/material/Paper'; +import Typography from '@mui/material/Typography'; +import { ErrorListProps } from '@rjsf/utils'; + +function ErrorList({ errors }: ErrorListProps) { + return ( + + + Errors + + {errors.map((error, i: number) => { + return ( + + + + + + + ); + })} + + + + ); +} + +export default ErrorList; diff --git a/spiffworkflow-frontend/src/themes/carbon/ErrorList/index.ts b/spiffworkflow-frontend/src/themes/carbon/ErrorList/index.ts new file mode 100644 index 000000000..79376ace1 --- /dev/null +++ b/spiffworkflow-frontend/src/themes/carbon/ErrorList/index.ts @@ -0,0 +1,2 @@ +export { default } from './ErrorList'; +export * from './ErrorList'; diff --git a/spiffworkflow-frontend/src/themes/carbon/FieldErrorTemplate/FieldErrorTemplate.tsx b/spiffworkflow-frontend/src/themes/carbon/FieldErrorTemplate/FieldErrorTemplate.tsx new file mode 100644 index 000000000..46f244ba4 --- /dev/null +++ b/spiffworkflow-frontend/src/themes/carbon/FieldErrorTemplate/FieldErrorTemplate.tsx @@ -0,0 +1,29 @@ +import React from 'react'; +import { FieldErrorProps } from '@rjsf/utils'; +import ListItem from '@mui/material/ListItem'; +import FormHelperText from '@mui/material/FormHelperText'; +import List from '@mui/material/List'; + +/** The `FieldErrorTemplate` component renders the errors local to the particular field + * + * @param props - The `FieldErrorProps` for the errors being rendered + */ +export default function FieldErrorTemplate(props: FieldErrorProps) { + const { errors = [], idSchema } = props; + if (errors.length === 0) { + return null; + } + const id = `${idSchema.$id}__error`; + + return ( + + {errors.map((error, i: number) => { + return ( + + {error} + + ); + })} + + ); +} diff --git a/spiffworkflow-frontend/src/themes/carbon/FieldErrorTemplate/index.ts b/spiffworkflow-frontend/src/themes/carbon/FieldErrorTemplate/index.ts new file mode 100644 index 000000000..2fbf1c353 --- /dev/null +++ b/spiffworkflow-frontend/src/themes/carbon/FieldErrorTemplate/index.ts @@ -0,0 +1,2 @@ +export { default } from './FieldErrorTemplate'; +export * from './FieldErrorTemplate'; diff --git a/spiffworkflow-frontend/src/themes/carbon/FieldHelpTemplate/FieldHelpTemplate.tsx b/spiffworkflow-frontend/src/themes/carbon/FieldHelpTemplate/FieldHelpTemplate.tsx new file mode 100644 index 000000000..08a61aeb4 --- /dev/null +++ b/spiffworkflow-frontend/src/themes/carbon/FieldHelpTemplate/FieldHelpTemplate.tsx @@ -0,0 +1,16 @@ +import React from 'react'; +import { FieldHelpProps } from '@rjsf/utils'; +import FormHelperText from '@mui/material/FormHelperText'; + +/** The `FieldHelpTemplate` component renders any help desired for a field + * + * @param props - The `FieldHelpProps` to be rendered + */ +export default function FieldHelpTemplate(props: FieldHelpProps) { + const { idSchema, help } = props; + if (!help) { + return null; + } + const id = `${idSchema.$id}__help`; + return {help}; +} diff --git a/spiffworkflow-frontend/src/themes/carbon/FieldHelpTemplate/index.ts b/spiffworkflow-frontend/src/themes/carbon/FieldHelpTemplate/index.ts new file mode 100644 index 000000000..b439bce3f --- /dev/null +++ b/spiffworkflow-frontend/src/themes/carbon/FieldHelpTemplate/index.ts @@ -0,0 +1,2 @@ +export { default } from './FieldHelpTemplate'; +export * from './FieldHelpTemplate'; diff --git a/spiffworkflow-frontend/src/themes/carbon/FieldTemplate/FieldTemplate.tsx b/spiffworkflow-frontend/src/themes/carbon/FieldTemplate/FieldTemplate.tsx new file mode 100644 index 000000000..44b687ea3 --- /dev/null +++ b/spiffworkflow-frontend/src/themes/carbon/FieldTemplate/FieldTemplate.tsx @@ -0,0 +1,64 @@ +import React from 'react'; +import FormControl from '@mui/material/FormControl'; +import Typography from '@mui/material/Typography'; +import { FieldTemplateProps, getTemplate, getUiOptions } from '@rjsf/utils'; + +function FieldTemplate({ + id, + children, + classNames, + disabled, + displayLabel, + hidden, + label, + onDropPropertyClick, + onKeyChange, + readonly, + required, + rawErrors = [], + errors, + help, + rawDescription, + schema, + uiSchema, + registry, +}: FieldTemplateProps) { + const uiOptions = getUiOptions(uiSchema); + const WrapIfAdditionalTemplate = getTemplate<'WrapIfAdditionalTemplate'>( + 'WrapIfAdditionalTemplate', + registry, + uiOptions + ); + + if (hidden) { + return
{children}
; + } + return ( + + + {children} + {displayLabel && rawDescription ? ( + + {rawDescription} + + ) : null} + {errors} + {help} + + + ); +} + +export default FieldTemplate; diff --git a/spiffworkflow-frontend/src/themes/carbon/FieldTemplate/index.ts b/spiffworkflow-frontend/src/themes/carbon/FieldTemplate/index.ts new file mode 100644 index 000000000..6f7dc3861 --- /dev/null +++ b/spiffworkflow-frontend/src/themes/carbon/FieldTemplate/index.ts @@ -0,0 +1,2 @@ +export { default } from './FieldTemplate'; +export * from './FieldTemplate'; diff --git a/spiffworkflow-frontend/src/themes/carbon/IconButton/IconButton.tsx b/spiffworkflow-frontend/src/themes/carbon/IconButton/IconButton.tsx new file mode 100644 index 000000000..825591061 --- /dev/null +++ b/spiffworkflow-frontend/src/themes/carbon/IconButton/IconButton.tsx @@ -0,0 +1,55 @@ +import React from 'react'; +import IconButton, { + IconButtonProps as MuiIconButtonProps, +} from '@mui/material/IconButton'; +import ArrowDownwardIcon from '@mui/icons-material/ArrowDownward'; +import ArrowUpwardIcon from '@mui/icons-material/ArrowUpward'; +import RemoveIcon from '@mui/icons-material/Remove'; +import { IconButtonProps } from '@rjsf/utils'; + +export default function MuiIconButton(props: IconButtonProps) { + const { icon, color, uiSchema, ...otherProps } = props; + return ( + + {icon} + + ); +} + +export function MoveDownButton(props: IconButtonProps) { + return ( + } + /> + ); +} + +export function MoveUpButton(props: IconButtonProps) { + return ( + } + /> + ); +} + +export function RemoveButton(props: IconButtonProps) { + const { iconType, ...otherProps } = props; + return ( + + } + /> + ); +} diff --git a/spiffworkflow-frontend/src/themes/carbon/IconButton/index.ts b/spiffworkflow-frontend/src/themes/carbon/IconButton/index.ts new file mode 100644 index 000000000..655ec4c48 --- /dev/null +++ b/spiffworkflow-frontend/src/themes/carbon/IconButton/index.ts @@ -0,0 +1,2 @@ +export { default } from './IconButton'; +export * from './IconButton'; diff --git a/spiffworkflow-frontend/src/themes/carbon/MuiForm/MuiForm.tsx b/spiffworkflow-frontend/src/themes/carbon/MuiForm/MuiForm.tsx new file mode 100644 index 000000000..c57e97e77 --- /dev/null +++ b/spiffworkflow-frontend/src/themes/carbon/MuiForm/MuiForm.tsx @@ -0,0 +1,8 @@ +import { ComponentType } from 'react'; +import { withTheme, FormProps } from '@rjsf/core'; + +import Theme from '../Theme'; + +const MuiForm: ComponentType = withTheme(Theme); + +export default MuiForm; diff --git a/spiffworkflow-frontend/src/themes/carbon/MuiForm/index.ts b/spiffworkflow-frontend/src/themes/carbon/MuiForm/index.ts new file mode 100644 index 000000000..f4609de60 --- /dev/null +++ b/spiffworkflow-frontend/src/themes/carbon/MuiForm/index.ts @@ -0,0 +1,2 @@ +export { default } from './MuiForm'; +export * from './MuiForm'; diff --git a/spiffworkflow-frontend/src/themes/carbon/ObjectFieldTemplate/ObjectFieldTemplate.tsx b/spiffworkflow-frontend/src/themes/carbon/ObjectFieldTemplate/ObjectFieldTemplate.tsx new file mode 100644 index 000000000..7d9557e81 --- /dev/null +++ b/spiffworkflow-frontend/src/themes/carbon/ObjectFieldTemplate/ObjectFieldTemplate.tsx @@ -0,0 +1,89 @@ +import React from 'react'; +import Grid from '@mui/material/Grid'; +import { + ObjectFieldTemplateProps, + canExpand, + getTemplate, + getUiOptions, +} from '@rjsf/utils'; + +function ObjectFieldTemplate({ + description, + title, + properties, + required, + disabled, + readonly, + uiSchema, + idSchema, + schema, + formData, + onAddClick, + registry, +}: ObjectFieldTemplateProps) { + const uiOptions = getUiOptions(uiSchema); + const TitleFieldTemplate = getTemplate<'TitleFieldTemplate'>( + 'TitleFieldTemplate', + registry, + uiOptions + ); + const DescriptionFieldTemplate = getTemplate<'DescriptionFieldTemplate'>( + 'DescriptionFieldTemplate', + registry, + uiOptions + ); + // Button templates are not overridden in the uiSchema + const { + ButtonTemplates: { AddButton }, + } = registry.templates; + return ( + <> + {(uiOptions.title || title) && ( + + )} + {(uiOptions.description || description) && ( + + )} + + {properties.map((element, index) => + // Remove the if the inner element is hidden as the + // itself would otherwise still take up space. + element.hidden ? ( + element.content + ) : ( + + {element.content} + + ) + )} + {canExpand(schema, uiSchema, formData) && ( + + + + + + )} + + + ); +} + +export default ObjectFieldTemplate; diff --git a/spiffworkflow-frontend/src/themes/carbon/ObjectFieldTemplate/index.ts b/spiffworkflow-frontend/src/themes/carbon/ObjectFieldTemplate/index.ts new file mode 100644 index 000000000..77c68a9a4 --- /dev/null +++ b/spiffworkflow-frontend/src/themes/carbon/ObjectFieldTemplate/index.ts @@ -0,0 +1,2 @@ +export { default } from './ObjectFieldTemplate'; +export * from './ObjectFieldTemplate'; diff --git a/spiffworkflow-frontend/src/themes/carbon/RadioWidget/RadioWidget.tsx b/spiffworkflow-frontend/src/themes/carbon/RadioWidget/RadioWidget.tsx new file mode 100644 index 000000000..de22cf1df --- /dev/null +++ b/spiffworkflow-frontend/src/themes/carbon/RadioWidget/RadioWidget.tsx @@ -0,0 +1,73 @@ +import React from 'react'; +import FormControlLabel from '@mui/material/FormControlLabel'; +import FormLabel from '@mui/material/FormLabel'; +import Radio from '@mui/material/Radio'; +import RadioGroup from '@mui/material/RadioGroup'; +import { WidgetProps } from '@rjsf/utils'; + +function RadioWidget({ + id, + schema, + options, + value, + required, + disabled, + readonly, + label, + onChange, + onBlur, + onFocus, +}: WidgetProps) { + const { enumOptions, enumDisabled } = options; + + const _onChange = (_: any, value: any) => + onChange(schema.type == 'boolean' ? value !== 'false' : value); + const _onBlur = ({ target: { value } }: React.FocusEvent) => + onBlur(id, value); + const _onFocus = ({ + target: { value }, + }: React.FocusEvent) => onFocus(id, value); + + const row = options ? options.inline : false; + + return ( + <> + + {label || schema.title} + + + {Array.isArray(enumOptions) && + enumOptions.map((option) => { + const itemDisabled = + Array.isArray(enumDisabled) && + enumDisabled.indexOf(option.value) !== -1; + return ( + + } + label={`${option.label}`} + value={`${option.value}`} + key={option.value} + disabled={disabled || itemDisabled || readonly} + /> + ); + })} + + + ); +} + +export default RadioWidget; diff --git a/spiffworkflow-frontend/src/themes/carbon/RadioWidget/index.ts b/spiffworkflow-frontend/src/themes/carbon/RadioWidget/index.ts new file mode 100644 index 000000000..10292dc56 --- /dev/null +++ b/spiffworkflow-frontend/src/themes/carbon/RadioWidget/index.ts @@ -0,0 +1,2 @@ +export { default } from './RadioWidget'; +export * from './RadioWidget'; diff --git a/spiffworkflow-frontend/src/themes/carbon/RangeWidget/RangeWidget.tsx b/spiffworkflow-frontend/src/themes/carbon/RangeWidget/RangeWidget.tsx new file mode 100644 index 000000000..a00d4a028 --- /dev/null +++ b/spiffworkflow-frontend/src/themes/carbon/RangeWidget/RangeWidget.tsx @@ -0,0 +1,47 @@ +import React from 'react'; +import FormLabel from '@mui/material/FormLabel'; +import Slider from '@mui/material/Slider'; +import { WidgetProps, rangeSpec } from '@rjsf/utils'; + +function RangeWidget({ + value, + readonly, + disabled, + onBlur, + onFocus, + options, + schema, + onChange, + required, + label, + id, +}: WidgetProps) { + const sliderProps = { value, label, id, name: id, ...rangeSpec(schema) }; + + const _onChange = (_: any, value?: number | number[]) => { + onChange(value ? options.emptyValue : value); + }; + const _onBlur = ({ target: { value } }: React.FocusEvent) => + onBlur(id, value); + const _onFocus = ({ + target: { value }, + }: React.FocusEvent) => onFocus(id, value); + + return ( + <> + + {label} + + + + ); +} + +export default RangeWidget; diff --git a/spiffworkflow-frontend/src/themes/carbon/RangeWidget/index.ts b/spiffworkflow-frontend/src/themes/carbon/RangeWidget/index.ts new file mode 100644 index 000000000..d8c49226c --- /dev/null +++ b/spiffworkflow-frontend/src/themes/carbon/RangeWidget/index.ts @@ -0,0 +1,2 @@ +export { default } from './RangeWidget'; +export * from './RangeWidget'; diff --git a/spiffworkflow-frontend/src/themes/carbon/SelectWidget/SelectWidget.tsx b/spiffworkflow-frontend/src/themes/carbon/SelectWidget/SelectWidget.tsx new file mode 100644 index 000000000..0aadcbe31 --- /dev/null +++ b/spiffworkflow-frontend/src/themes/carbon/SelectWidget/SelectWidget.tsx @@ -0,0 +1,71 @@ +import React from 'react'; +import MenuItem from '@mui/material/MenuItem'; +import TextField from '@mui/material/TextField'; +import { WidgetProps, processSelectValue } from '@rjsf/utils'; + +function SelectWidget({ + schema, + id, + options, + label, + required, + disabled, + readonly, + value, + multiple, + autofocus, + onChange, + onBlur, + onFocus, + rawErrors = [], +}: WidgetProps) { + const { enumOptions, enumDisabled } = options; + + const emptyValue = multiple ? [] : ''; + + const _onChange = ({ + target: { value }, + }: React.ChangeEvent<{ name?: string; value: unknown }>) => + onChange(processSelectValue(schema, value, options)); + const _onBlur = ({ target: { value } }: React.FocusEvent) => + onBlur(id, processSelectValue(schema, value, options)); + const _onFocus = ({ + target: { value }, + }: React.FocusEvent) => + onFocus(id, processSelectValue(schema, value, options)); + + return ( + 0} + onChange={_onChange} + onBlur={_onBlur} + onFocus={_onFocus} + InputLabelProps={{ + shrink: true, + }} + SelectProps={{ + multiple: typeof multiple === 'undefined' ? false : multiple, + }} + > + {(enumOptions as any).map(({ value, label }: any, i: number) => { + const disabled: any = + enumDisabled && (enumDisabled as any).indexOf(value) != -1; + return ( + + {label} + + ); + })} + + ); +} + +export default SelectWidget; diff --git a/spiffworkflow-frontend/src/themes/carbon/SelectWidget/index.ts b/spiffworkflow-frontend/src/themes/carbon/SelectWidget/index.ts new file mode 100644 index 000000000..e37ea725b --- /dev/null +++ b/spiffworkflow-frontend/src/themes/carbon/SelectWidget/index.ts @@ -0,0 +1,2 @@ +export { default } from './SelectWidget'; +export * from './SelectWidget'; diff --git a/spiffworkflow-frontend/src/themes/carbon/SubmitButton/SubmitButton.tsx b/spiffworkflow-frontend/src/themes/carbon/SubmitButton/SubmitButton.tsx new file mode 100644 index 000000000..b61d30c84 --- /dev/null +++ b/spiffworkflow-frontend/src/themes/carbon/SubmitButton/SubmitButton.tsx @@ -0,0 +1,29 @@ +import React from 'react'; +import Box from '@mui/material/Box'; +import Button from '@mui/material/Button'; +import { SubmitButtonProps, getSubmitButtonOptions } from '@rjsf/utils'; + +const SubmitButton: React.ComponentType = (props) => { + const { + submitText, + norender, + props: submitButtonProps, + } = getSubmitButtonOptions(props.uiSchema); + if (norender) { + return null; + } + return ( + + + + ); +}; + +export default SubmitButton; diff --git a/spiffworkflow-frontend/src/themes/carbon/SubmitButton/index.ts b/spiffworkflow-frontend/src/themes/carbon/SubmitButton/index.ts new file mode 100644 index 000000000..f676497ba --- /dev/null +++ b/spiffworkflow-frontend/src/themes/carbon/SubmitButton/index.ts @@ -0,0 +1,2 @@ +export { default } from './SubmitButton'; +export * from './SubmitButton'; diff --git a/spiffworkflow-frontend/src/themes/carbon/Templates/Templates.ts b/spiffworkflow-frontend/src/themes/carbon/Templates/Templates.ts new file mode 100644 index 000000000..dfa9229f3 --- /dev/null +++ b/spiffworkflow-frontend/src/themes/carbon/Templates/Templates.ts @@ -0,0 +1,35 @@ +import AddButton from '../AddButton'; +import ArrayFieldItemTemplate from '../ArrayFieldItemTemplate'; +import ArrayFieldTemplate from '../ArrayFieldTemplate'; +import BaseInputTemplate from '../BaseInputTemplate'; +import DescriptionField from '../DescriptionField'; +import ErrorList from '../ErrorList'; +import { MoveDownButton, MoveUpButton, RemoveButton } from '../IconButton'; +import FieldErrorTemplate from '../FieldErrorTemplate'; +import FieldHelpTemplate from '../FieldHelpTemplate'; +import FieldTemplate from '../FieldTemplate'; +import ObjectFieldTemplate from '../ObjectFieldTemplate'; +import SubmitButton from '../SubmitButton'; +import TitleField from '../TitleField'; +import WrapIfAdditionalTemplate from '../WrapIfAdditionalTemplate'; + +export default { + ArrayFieldItemTemplate, + ArrayFieldTemplate, + BaseInputTemplate, + ButtonTemplates: { + AddButton, + MoveDownButton, + MoveUpButton, + RemoveButton, + SubmitButton, + }, + DescriptionFieldTemplate: DescriptionField, + ErrorListTemplate: ErrorList, + FieldErrorTemplate, + FieldHelpTemplate, + FieldTemplate, + ObjectFieldTemplate, + TitleFieldTemplate: TitleField, + WrapIfAdditionalTemplate, +}; diff --git a/spiffworkflow-frontend/src/themes/carbon/Templates/index.ts b/spiffworkflow-frontend/src/themes/carbon/Templates/index.ts new file mode 100644 index 000000000..612ccf692 --- /dev/null +++ b/spiffworkflow-frontend/src/themes/carbon/Templates/index.ts @@ -0,0 +1,2 @@ +export { default } from './Templates'; +export * from './Templates'; diff --git a/spiffworkflow-frontend/src/themes/carbon/TextareaWidget/TextareaWidget.tsx b/spiffworkflow-frontend/src/themes/carbon/TextareaWidget/TextareaWidget.tsx new file mode 100644 index 000000000..79e91750f --- /dev/null +++ b/spiffworkflow-frontend/src/themes/carbon/TextareaWidget/TextareaWidget.tsx @@ -0,0 +1,20 @@ +import React from 'react'; +import { getTemplate, WidgetProps } from '@rjsf/utils'; + +function TextareaWidget(props: WidgetProps) { + const { options, registry } = props; + const BaseInputTemplate = getTemplate<'BaseInputTemplate'>( + 'BaseInputTemplate', + registry, + options + ); + + let rows: string | number = 5; + if (typeof options.rows === 'string' || typeof options.rows === 'number') { + rows = options.rows; + } + + return ; +} + +export default TextareaWidget; diff --git a/spiffworkflow-frontend/src/themes/carbon/TextareaWidget/index.ts b/spiffworkflow-frontend/src/themes/carbon/TextareaWidget/index.ts new file mode 100644 index 000000000..20e6d8e26 --- /dev/null +++ b/spiffworkflow-frontend/src/themes/carbon/TextareaWidget/index.ts @@ -0,0 +1,2 @@ +export { default } from './TextareaWidget'; +export * from './TextareaWidget'; diff --git a/spiffworkflow-frontend/src/themes/carbon/Theme/Theme.tsx b/spiffworkflow-frontend/src/themes/carbon/Theme/Theme.tsx new file mode 100644 index 000000000..ee71932bb --- /dev/null +++ b/spiffworkflow-frontend/src/themes/carbon/Theme/Theme.tsx @@ -0,0 +1,11 @@ +import { ThemeProps } from '@rjsf/core'; + +import Templates from '../Templates'; +import Widgets from '../Widgets'; + +const Theme: ThemeProps = { + templates: Templates, + widgets: Widgets, +}; + +export default Theme; diff --git a/spiffworkflow-frontend/src/themes/carbon/Theme/index.ts b/spiffworkflow-frontend/src/themes/carbon/Theme/index.ts new file mode 100644 index 000000000..6dfd7fa6e --- /dev/null +++ b/spiffworkflow-frontend/src/themes/carbon/Theme/index.ts @@ -0,0 +1,2 @@ +export { default } from './Theme'; +export * from './Theme'; diff --git a/spiffworkflow-frontend/src/themes/carbon/TitleField/TitleField.tsx b/spiffworkflow-frontend/src/themes/carbon/TitleField/TitleField.tsx new file mode 100644 index 000000000..8f0d3ae0b --- /dev/null +++ b/spiffworkflow-frontend/src/themes/carbon/TitleField/TitleField.tsx @@ -0,0 +1,16 @@ +import React from 'react'; +import Box from '@mui/material/Box'; +import Divider from '@mui/material/Divider'; +import Typography from '@mui/material/Typography'; +import { TitleFieldProps } from '@rjsf/utils'; + +function TitleField({ id, title }: TitleFieldProps) { + return ( + + {title} + + + ); +} + +export default TitleField; diff --git a/spiffworkflow-frontend/src/themes/carbon/TitleField/index.ts b/spiffworkflow-frontend/src/themes/carbon/TitleField/index.ts new file mode 100644 index 000000000..cfa479d03 --- /dev/null +++ b/spiffworkflow-frontend/src/themes/carbon/TitleField/index.ts @@ -0,0 +1,2 @@ +export { default } from './TitleField'; +export * from './TitleField'; diff --git a/spiffworkflow-frontend/src/themes/carbon/Widgets/Widgets.ts b/spiffworkflow-frontend/src/themes/carbon/Widgets/Widgets.ts new file mode 100644 index 000000000..6c34611da --- /dev/null +++ b/spiffworkflow-frontend/src/themes/carbon/Widgets/Widgets.ts @@ -0,0 +1,19 @@ +import CheckboxWidget from '../CheckboxWidget/CheckboxWidget'; +import CheckboxesWidget from '../CheckboxesWidget/CheckboxesWidget'; +import DateWidget from '../DateWidget/DateWidget'; +import DateTimeWidget from '../DateTimeWidget/DateTimeWidget'; +import RadioWidget from '../RadioWidget/RadioWidget'; +import RangeWidget from '../RangeWidget/RangeWidget'; +import SelectWidget from '../SelectWidget/SelectWidget'; +import TextareaWidget from '../TextareaWidget/TextareaWidget'; + +export default { + CheckboxWidget, + CheckboxesWidget, + DateWidget, + DateTimeWidget, + RadioWidget, + RangeWidget, + SelectWidget, + TextareaWidget, +}; diff --git a/spiffworkflow-frontend/src/themes/carbon/Widgets/index.ts b/spiffworkflow-frontend/src/themes/carbon/Widgets/index.ts new file mode 100644 index 000000000..de857bf55 --- /dev/null +++ b/spiffworkflow-frontend/src/themes/carbon/Widgets/index.ts @@ -0,0 +1,2 @@ +export { default } from './Widgets'; +export * from './Widgets'; diff --git a/spiffworkflow-frontend/src/themes/carbon/WrapIfAdditionalTemplate/WrapIfAdditionalTemplate.tsx b/spiffworkflow-frontend/src/themes/carbon/WrapIfAdditionalTemplate/WrapIfAdditionalTemplate.tsx new file mode 100644 index 000000000..954d82c45 --- /dev/null +++ b/spiffworkflow-frontend/src/themes/carbon/WrapIfAdditionalTemplate/WrapIfAdditionalTemplate.tsx @@ -0,0 +1,80 @@ +import React, { CSSProperties } from 'react'; +import FormControl from '@mui/material/FormControl'; +import Grid from '@mui/material/Grid'; +import InputLabel from '@mui/material/InputLabel'; +import Input from '@mui/material/OutlinedInput'; +import { + ADDITIONAL_PROPERTY_FLAG, + WrapIfAdditionalTemplateProps, +} from '@rjsf/utils'; + +function WrapIfAdditionalTemplate({ + children, + classNames, + disabled, + id, + label, + onDropPropertyClick, + onKeyChange, + readonly, + required, + schema, + uiSchema, + registry, +}: WrapIfAdditionalTemplateProps) { + // Button templates are not overridden in the uiSchema + const { RemoveButton } = registry.templates.ButtonTemplates; + const keyLabel = `${label} Key`; // i18n ? + const additional = ADDITIONAL_PROPERTY_FLAG in schema; + const btnStyle: CSSProperties = { + flex: 1, + paddingLeft: 6, + paddingRight: 6, + fontWeight: 'bold', + }; + + if (!additional) { + return
{children}
; + } + + const handleBlur = ({ target }: React.FocusEvent) => + onKeyChange(target.value); + + return ( + + + + {keyLabel} + + + + + {children} + + + + + + ); +} + +export default WrapIfAdditionalTemplate; diff --git a/spiffworkflow-frontend/src/themes/carbon/WrapIfAdditionalTemplate/index.ts b/spiffworkflow-frontend/src/themes/carbon/WrapIfAdditionalTemplate/index.ts new file mode 100644 index 000000000..7d7af6629 --- /dev/null +++ b/spiffworkflow-frontend/src/themes/carbon/WrapIfAdditionalTemplate/index.ts @@ -0,0 +1,2 @@ +export { default } from './WrapIfAdditionalTemplate'; +export * from './WrapIfAdditionalTemplate'; diff --git a/spiffworkflow-frontend/src/themes/carbon/index.ts b/spiffworkflow-frontend/src/themes/carbon/index.ts new file mode 100644 index 000000000..7da74d8f6 --- /dev/null +++ b/spiffworkflow-frontend/src/themes/carbon/index.ts @@ -0,0 +1,8 @@ +import MuiForm from './MuiForm/MuiForm'; + +export { default as Form } from './MuiForm'; +export { default as Templates } from './Templates'; +export { default as Theme } from './Theme'; +export { default as Widgets } from './Widgets'; + +export default MuiForm; From 625b0dd27ff74a8659ee1176b4b962cbbedbe485 Mon Sep 17 00:00:00 2001 From: jasquat Date: Wed, 16 Nov 2022 14:02:46 -0500 Subject: [PATCH 04/10] support ts and js for lint and format commands w/ burnettk cullerton --- spiffworkflow-frontend/package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spiffworkflow-frontend/package.json b/spiffworkflow-frontend/package.json index 00a2cb747..4829368a2 100644 --- a/spiffworkflow-frontend/package.json +++ b/spiffworkflow-frontend/package.json @@ -78,9 +78,9 @@ "test": "react-scripts test --coverage", "t": "npm test -- --watchAll=false", "eject": "craco eject", - "format": "prettier --write src/**/*.js{,x}", - "lint": "./node_modules/.bin/eslint src *.js", - "lint:fix": "./node_modules/.bin/eslint --fix src *.js" + "format": "prettier --write src/**/*.[tj]s{,x}", + "lint": "./node_modules/.bin/eslint src *.[tj]s{,x}", + "lint:fix": "./node_modules/.bin/eslint --fix src *.[tj]s{,x}" }, "eslintConfig": { "extends": [ From a6680b67687899cb6e920871405f42a79c03ae1b Mon Sep 17 00:00:00 2001 From: jasquat Date: Wed, 16 Nov 2022 14:46:04 -0500 Subject: [PATCH 05/10] updated a couple form components to work with carbon w/ burnettk cullerton --- .../src/components/ProcessGroupForm.tsx | 6 +--- .../BaseInputTemplate/BaseInputTemplate.tsx | 36 +++++++++++-------- .../carbon/SubmitButton/SubmitButton.tsx | 31 ++++++++-------- .../src/themes/carbon/index.css | 3 ++ .../src/themes/carbon/index.ts | 1 + 5 files changed, 42 insertions(+), 35 deletions(-) create mode 100644 spiffworkflow-frontend/src/themes/carbon/index.css diff --git a/spiffworkflow-frontend/src/components/ProcessGroupForm.tsx b/spiffworkflow-frontend/src/components/ProcessGroupForm.tsx index 3d51adeb9..e427f43b2 100644 --- a/spiffworkflow-frontend/src/components/ProcessGroupForm.tsx +++ b/spiffworkflow-frontend/src/components/ProcessGroupForm.tsx @@ -165,11 +165,7 @@ export default function ProcessGroupForm({ }; const formButtons = () => { - const buttons = [ - , - ]; + const buttons = []; if (mode === 'edit') { buttons.push( ) => + }: React.ChangeEvent) => { onChange(value === '' ? options.emptyValue : value); - const _onBlur = ({ target: { value } }: React.FocusEvent) => - onBlur(id, value); - const _onFocus = ({ + }; + const localOnBlur = ({ + // eslint-disable-next-line no-shadow + target: { value }, + }: React.FocusEvent) => onBlur(id, value); + const localOnFocus = ({ + // eslint-disable-next-line no-shadow target: { value }, }: React.FocusEvent) => onFocus(id, value); @@ -50,7 +55,7 @@ function BaseInputTemplate({ return ( <> - 0} - onChange={_onChange} - onBlur={_onBlur} - onFocus={_onFocus} - {...(textFieldProps as TextFieldProps)} + onChange={localOnChange} + onBlur={localOnBlur} + onFocus={localOnFocus} + // eslint-disable-next-line react/jsx-props-no-spreading + {...otherProps} /> {schema.examples && ( {(schema.examples as string[]) .concat(schema.default ? ([schema.default] as string[]) : []) .map((example: any) => { + // eslint-disable-next-line jsx-a11y/control-has-associated-label return diff --git a/spiffworkflow-frontend/src/themes/carbon/SubmitButton/SubmitButton.tsx b/spiffworkflow-frontend/src/themes/carbon/SubmitButton/SubmitButton.tsx index b61d30c84..07a6298d9 100644 --- a/spiffworkflow-frontend/src/themes/carbon/SubmitButton/SubmitButton.tsx +++ b/spiffworkflow-frontend/src/themes/carbon/SubmitButton/SubmitButton.tsx @@ -1,29 +1,30 @@ import React from 'react'; -import Box from '@mui/material/Box'; -import Button from '@mui/material/Button'; +// import Box from '@mui/material/Box'; +// @ts-ignore +import { Button } from '@carbon/react'; import { SubmitButtonProps, getSubmitButtonOptions } from '@rjsf/utils'; -const SubmitButton: React.ComponentType = (props) => { +// const SubmitButton: React.ComponentType = (props) => { +function SubmitButton(props: SubmitButtonProps) { + const { uiSchema } = props; const { submitText, norender, props: submitButtonProps, - } = getSubmitButtonOptions(props.uiSchema); + } = getSubmitButtonOptions(uiSchema); if (norender) { return null; } return ( - - - + ); -}; +} export default SubmitButton; diff --git a/spiffworkflow-frontend/src/themes/carbon/index.css b/spiffworkflow-frontend/src/themes/carbon/index.css new file mode 100644 index 000000000..d44ae7e5d --- /dev/null +++ b/spiffworkflow-frontend/src/themes/carbon/index.css @@ -0,0 +1,3 @@ +button.react-json-schema-form-submit-button { + margin-top: 1.5em; +} diff --git a/spiffworkflow-frontend/src/themes/carbon/index.ts b/spiffworkflow-frontend/src/themes/carbon/index.ts index 7da74d8f6..cc3d22544 100644 --- a/spiffworkflow-frontend/src/themes/carbon/index.ts +++ b/spiffworkflow-frontend/src/themes/carbon/index.ts @@ -1,4 +1,5 @@ import MuiForm from './MuiForm/MuiForm'; +import './index.css'; export { default as Form } from './MuiForm'; export { default as Templates } from './Templates'; From 1b175e65b13f2e41d885d3f9c9e8a48b0c2dcb5e Mon Sep 17 00:00:00 2001 From: jasquat Date: Wed, 16 Nov 2022 14:55:36 -0500 Subject: [PATCH 06/10] specify onRequestClose on modals w/ burnettk cullerton --- .../src/components/ButtonWithConfirmation.tsx | 1 + spiffworkflow-frontend/src/routes/ProcessModelEditDiagram.tsx | 3 +++ spiffworkflow-frontend/src/routes/ReactFormEditor.tsx | 1 + 3 files changed, 5 insertions(+) diff --git a/spiffworkflow-frontend/src/components/ButtonWithConfirmation.tsx b/spiffworkflow-frontend/src/components/ButtonWithConfirmation.tsx index a58dbe1ca..af2ec5eba 100644 --- a/spiffworkflow-frontend/src/components/ButtonWithConfirmation.tsx +++ b/spiffworkflow-frontend/src/components/ButtonWithConfirmation.tsx @@ -53,6 +53,7 @@ export default function ButtonWithConfirmation({ secondaryButtonText="Cancel" onSecondarySubmit={handleConfirmationPromptCancel} onRequestSubmit={handleConfirmation} + onRequestClose={handleConfirmationPromptCancel} /> ); }; diff --git a/spiffworkflow-frontend/src/routes/ProcessModelEditDiagram.tsx b/spiffworkflow-frontend/src/routes/ProcessModelEditDiagram.tsx index 06644e2e7..d182dbb7e 100644 --- a/spiffworkflow-frontend/src/routes/ProcessModelEditDiagram.tsx +++ b/spiffworkflow-frontend/src/routes/ProcessModelEditDiagram.tsx @@ -215,6 +215,7 @@ export default function ProcessModelEditDiagram() { secondaryButtonText="Cancel" onSecondarySubmit={handleFileNameCancel} onRequestSubmit={handleFileNameSave} + onRequestClose={handleFileNameCancel} > @@ -607,6 +608,7 @@ export default function ProcessModelEditDiagram() { primaryButtonText="Close" onRequestSubmit={handleScriptEditorClose} size="lg" + onRequestClose={handleScriptEditorClose} > From 87802a60b300e4aea1789c83c7c893e94731045f Mon Sep 17 00:00:00 2001 From: jasquat Date: Wed, 16 Nov 2022 15:43:11 -0500 Subject: [PATCH 07/10] added radio buttons w/ burnettk cullerton --- spiffworkflow-frontend/src/index.css | 2 +- .../src/routes/ProcessModelShow.tsx | 3 + .../BaseInputTemplate/BaseInputTemplate.tsx | 12 +++- .../themes/carbon/RadioWidget/RadioWidget.tsx | 71 ++++++++----------- 4 files changed, 43 insertions(+), 45 deletions(-) diff --git a/spiffworkflow-frontend/src/index.css b/spiffworkflow-frontend/src/index.css index c2e2e8028..6baa40d9c 100644 --- a/spiffworkflow-frontend/src/index.css +++ b/spiffworkflow-frontend/src/index.css @@ -31,7 +31,7 @@ h1{ border: 1px solid #393939; } .cds--btn.button-white-background:hover { - background: #525252; + background: lightgrey; } .cds--breadcrumb-item a.cds--link:hover { diff --git a/spiffworkflow-frontend/src/routes/ProcessModelShow.tsx b/spiffworkflow-frontend/src/routes/ProcessModelShow.tsx index e702fc863..47994b31f 100644 --- a/spiffworkflow-frontend/src/routes/ProcessModelShow.tsx +++ b/spiffworkflow-frontend/src/routes/ProcessModelShow.tsx @@ -388,6 +388,7 @@ export default function ProcessModelShow() { const handleFileUploadCancel = () => { setShowFileUploadModal(false); + setFilesToUpload(null); }; const handleFileUpload = (event: any) => { @@ -405,6 +406,7 @@ export default function ProcessModelShow() { }); } setShowFileUploadModal(false); + setFilesToUpload(null); }; const fileUploadModal = () => { @@ -432,6 +434,7 @@ export default function ProcessModelShow() { iconDescription="Delete file" name="" multiple={false} + onDelete={() => setFilesToUpload(null)} onChange={(event: any) => setFilesToUpload(event.target.files)} /> diff --git a/spiffworkflow-frontend/src/themes/carbon/BaseInputTemplate/BaseInputTemplate.tsx b/spiffworkflow-frontend/src/themes/carbon/BaseInputTemplate/BaseInputTemplate.tsx index 83aebacae..765fd7a9c 100644 --- a/spiffworkflow-frontend/src/themes/carbon/BaseInputTemplate/BaseInputTemplate.tsx +++ b/spiffworkflow-frontend/src/themes/carbon/BaseInputTemplate/BaseInputTemplate.tsx @@ -21,8 +21,8 @@ function BaseInputTemplate({ uiSchema, rawErrors = [], registry, -}: // ...textFieldProps -WidgetProps) { + ...textFieldProps +}: WidgetProps) { const inputProps = getInputProps(schema, type, options); // Now we need to pull out the step, min, max into an inner `inputProps` for material-ui const { step, min, max, ...rest } = inputProps; @@ -52,6 +52,12 @@ WidgetProps) { const { schemaUtils } = registry; const displayLabel = schemaUtils.getDisplayLabel(schema, uiSchema); + let labelToUse = label; + if (uiSchema && uiSchema['ui:title']) { + labelToUse = uiSchema['ui:title']; + } else if (schema && schema.title) { + labelToUse = schema.title; + } return ( <> @@ -59,7 +65,7 @@ WidgetProps) { id={id} name={id} placeholder={placeholder} - label={displayLabel ? label || schema.title : false} + labelText={displayLabel ? labelToUse : false} autoFocus={autofocus} required={required} disabled={disabled || readonly} diff --git a/spiffworkflow-frontend/src/themes/carbon/RadioWidget/RadioWidget.tsx b/spiffworkflow-frontend/src/themes/carbon/RadioWidget/RadioWidget.tsx index de22cf1df..70b8e3801 100644 --- a/spiffworkflow-frontend/src/themes/carbon/RadioWidget/RadioWidget.tsx +++ b/spiffworkflow-frontend/src/themes/carbon/RadioWidget/RadioWidget.tsx @@ -1,8 +1,6 @@ import React from 'react'; -import FormControlLabel from '@mui/material/FormControlLabel'; -import FormLabel from '@mui/material/FormLabel'; -import Radio from '@mui/material/Radio'; -import RadioGroup from '@mui/material/RadioGroup'; +// @ts-ignore +import { RadioButtonGroup, RadioButton } from '@carbon/react'; import { WidgetProps } from '@rjsf/utils'; function RadioWidget({ @@ -20,7 +18,7 @@ function RadioWidget({ }: WidgetProps) { const { enumOptions, enumDisabled } = options; - const _onChange = (_: any, value: any) => + const localOnChange = (_: any, value: any) => onChange(schema.type == 'boolean' ? value !== 'false' : value); const _onBlur = ({ target: { value } }: React.FocusEvent) => onBlur(id, value); @@ -31,42 +29,33 @@ function RadioWidget({ const row = options ? options.inline : false; return ( - <> - - {label || schema.title} - - - {Array.isArray(enumOptions) && - enumOptions.map((option) => { - const itemDisabled = - Array.isArray(enumDisabled) && - enumDisabled.indexOf(option.value) !== -1; - return ( - - } - label={`${option.label}`} - value={`${option.value}`} - key={option.value} - disabled={disabled || itemDisabled || readonly} - /> - ); - })} - - + + {Array.isArray(enumOptions) && + enumOptions.map((option) => { + const itemDisabled = + Array.isArray(enumDisabled) && + enumDisabled.indexOf(option.value) !== -1; + return ( + + ); + })} + ); } From f7aa497aa6b8720367ee61cee679634138089800 Mon Sep 17 00:00:00 2001 From: jasquat Date: Wed, 16 Nov 2022 15:45:54 -0500 Subject: [PATCH 08/10] added eslintignore file to ignore carbon theme for now w/ burnettk cullerton --- spiffworkflow-frontend/.eslintignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 spiffworkflow-frontend/.eslintignore diff --git a/spiffworkflow-frontend/.eslintignore b/spiffworkflow-frontend/.eslintignore new file mode 100644 index 000000000..0e223626f --- /dev/null +++ b/spiffworkflow-frontend/.eslintignore @@ -0,0 +1 @@ +/src/themes/carbon From 498292d35454b063facd862f2ab37a63c0823b01 Mon Sep 17 00:00:00 2001 From: jasquat Date: Wed, 16 Nov 2022 16:09:48 -0500 Subject: [PATCH 09/10] some updates for the carbon form theme w/ burnettk cullerton --- .../src/routes/ProcessGroupList.tsx | 5 ---- .../BaseInputTemplate/BaseInputTemplate.tsx | 5 +++- .../MuiForm.tsx => CarbonForm/CarbonForm.tsx} | 4 +-- .../src/themes/carbon/CarbonForm/index.ts | 2 ++ .../src/themes/carbon/MuiForm/index.ts | 2 -- .../carbon/SelectWidget/SelectWidget.tsx | 29 +++++++++++-------- .../src/themes/carbon/index.ts | 6 ++-- 7 files changed, 28 insertions(+), 25 deletions(-) rename spiffworkflow-frontend/src/themes/carbon/{MuiForm/MuiForm.tsx => CarbonForm/CarbonForm.tsx} (57%) create mode 100644 spiffworkflow-frontend/src/themes/carbon/CarbonForm/index.ts delete mode 100644 spiffworkflow-frontend/src/themes/carbon/MuiForm/index.ts diff --git a/spiffworkflow-frontend/src/routes/ProcessGroupList.tsx b/spiffworkflow-frontend/src/routes/ProcessGroupList.tsx index 1a5c59c3a..564a80dd2 100644 --- a/spiffworkflow-frontend/src/routes/ProcessGroupList.tsx +++ b/spiffworkflow-frontend/src/routes/ProcessGroupList.tsx @@ -3,11 +3,6 @@ import { Link, useNavigate, useSearchParams } from 'react-router-dom'; import { Button, Table, - // ExpandableTile, - // TileAboveTheFoldContent, - // TileBelowTheFoldContent, - // TextInput, - // ClickableTile, // @ts-ignore } from '@carbon/react'; import { Can } from '@casl/react'; diff --git a/spiffworkflow-frontend/src/themes/carbon/BaseInputTemplate/BaseInputTemplate.tsx b/spiffworkflow-frontend/src/themes/carbon/BaseInputTemplate/BaseInputTemplate.tsx index 765fd7a9c..a3d225e6b 100644 --- a/spiffworkflow-frontend/src/themes/carbon/BaseInputTemplate/BaseInputTemplate.tsx +++ b/spiffworkflow-frontend/src/themes/carbon/BaseInputTemplate/BaseInputTemplate.tsx @@ -52,12 +52,16 @@ function BaseInputTemplate({ const { schemaUtils } = registry; const displayLabel = schemaUtils.getDisplayLabel(schema, uiSchema); + let labelToUse = label; if (uiSchema && uiSchema['ui:title']) { labelToUse = uiSchema['ui:title']; } else if (schema && schema.title) { labelToUse = schema.title; } + if (required) { + labelToUse = `${labelToUse}*`; + } return ( <> @@ -67,7 +71,6 @@ function BaseInputTemplate({ placeholder={placeholder} labelText={displayLabel ? labelToUse : false} autoFocus={autofocus} - required={required} disabled={disabled || readonly} value={value || value === 0 ? value : ''} error={rawErrors.length > 0} diff --git a/spiffworkflow-frontend/src/themes/carbon/MuiForm/MuiForm.tsx b/spiffworkflow-frontend/src/themes/carbon/CarbonForm/CarbonForm.tsx similarity index 57% rename from spiffworkflow-frontend/src/themes/carbon/MuiForm/MuiForm.tsx rename to spiffworkflow-frontend/src/themes/carbon/CarbonForm/CarbonForm.tsx index c57e97e77..dfab951c6 100644 --- a/spiffworkflow-frontend/src/themes/carbon/MuiForm/MuiForm.tsx +++ b/spiffworkflow-frontend/src/themes/carbon/CarbonForm/CarbonForm.tsx @@ -3,6 +3,6 @@ import { withTheme, FormProps } from '@rjsf/core'; import Theme from '../Theme'; -const MuiForm: ComponentType = withTheme(Theme); +const CarbonForm: ComponentType = withTheme(Theme); -export default MuiForm; +export default CarbonForm; diff --git a/spiffworkflow-frontend/src/themes/carbon/CarbonForm/index.ts b/spiffworkflow-frontend/src/themes/carbon/CarbonForm/index.ts new file mode 100644 index 000000000..3b9f2d8dd --- /dev/null +++ b/spiffworkflow-frontend/src/themes/carbon/CarbonForm/index.ts @@ -0,0 +1,2 @@ +export { default } from './CarbonForm'; +export * from './CarbonForm'; diff --git a/spiffworkflow-frontend/src/themes/carbon/MuiForm/index.ts b/spiffworkflow-frontend/src/themes/carbon/MuiForm/index.ts deleted file mode 100644 index f4609de60..000000000 --- a/spiffworkflow-frontend/src/themes/carbon/MuiForm/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { default } from './MuiForm'; -export * from './MuiForm'; diff --git a/spiffworkflow-frontend/src/themes/carbon/SelectWidget/SelectWidget.tsx b/spiffworkflow-frontend/src/themes/carbon/SelectWidget/SelectWidget.tsx index 0aadcbe31..4da66bc75 100644 --- a/spiffworkflow-frontend/src/themes/carbon/SelectWidget/SelectWidget.tsx +++ b/spiffworkflow-frontend/src/themes/carbon/SelectWidget/SelectWidget.tsx @@ -1,6 +1,5 @@ -import React from 'react'; -import MenuItem from '@mui/material/MenuItem'; -import TextField from '@mui/material/TextField'; +// @ts-ignore +import { Select, SelectItem } from '@carbon/react'; import { WidgetProps, processSelectValue } from '@rjsf/utils'; function SelectWidget({ @@ -17,6 +16,7 @@ function SelectWidget({ onChange, onBlur, onFocus, + uiSchema, rawErrors = [], }: WidgetProps) { const { enumOptions, enumDisabled } = options; @@ -34,14 +34,23 @@ function SelectWidget({ }: React.FocusEvent) => onFocus(id, processSelectValue(schema, value, options)); + let labelToUse = label; + if (uiSchema && uiSchema['ui:title']) { + labelToUse = uiSchema['ui:title']; + } else if (schema && schema.title) { + labelToUse = schema.title; + } + if (required) { + labelToUse = `${labelToUse}*`; + } + return ( - 0} @@ -58,13 +67,9 @@ function SelectWidget({ {(enumOptions as any).map(({ value, label }: any, i: number) => { const disabled: any = enumDisabled && (enumDisabled as any).indexOf(value) != -1; - return ( - - {label} - - ); + return ; })} - + ); } diff --git a/spiffworkflow-frontend/src/themes/carbon/index.ts b/spiffworkflow-frontend/src/themes/carbon/index.ts index cc3d22544..0c96cf269 100644 --- a/spiffworkflow-frontend/src/themes/carbon/index.ts +++ b/spiffworkflow-frontend/src/themes/carbon/index.ts @@ -1,9 +1,9 @@ -import MuiForm from './MuiForm/MuiForm'; +import CarbonForm from './CarbonForm/CarbonForm'; import './index.css'; -export { default as Form } from './MuiForm'; +export { default as Form } from './CarbonForm'; export { default as Templates } from './Templates'; export { default as Theme } from './Theme'; export { default as Widgets } from './Widgets'; -export default MuiForm; +export default CarbonForm; From 17e660530631a93cf86386aaed1a3554939318ec Mon Sep 17 00:00:00 2001 From: jasquat Date: Wed, 16 Nov 2022 17:12:01 -0500 Subject: [PATCH 10/10] fixed error messaging a little bit for forms w/ burnettk cullerton --- .../BaseInputTemplate/BaseInputTemplate.tsx | 153 ++++++++++-------- .../src/themes/carbon/ErrorList/ErrorList.tsx | 38 ++--- .../FieldErrorTemplate/FieldErrorTemplate.tsx | 24 +-- 3 files changed, 97 insertions(+), 118 deletions(-) diff --git a/spiffworkflow-frontend/src/themes/carbon/BaseInputTemplate/BaseInputTemplate.tsx b/spiffworkflow-frontend/src/themes/carbon/BaseInputTemplate/BaseInputTemplate.tsx index a3d225e6b..eea1abe0e 100644 --- a/spiffworkflow-frontend/src/themes/carbon/BaseInputTemplate/BaseInputTemplate.tsx +++ b/spiffworkflow-frontend/src/themes/carbon/BaseInputTemplate/BaseInputTemplate.tsx @@ -1,57 +1,80 @@ -import React from 'react'; // @ts-ignore import { TextInput } from '@carbon/react'; -import { getInputProps, WidgetProps } from '@rjsf/utils'; +import { + getInputProps, + FormContextType, + RJSFSchema, + StrictRJSFSchema, + WidgetProps, +} from '@rjsf/utils'; -function BaseInputTemplate({ - id, - placeholder, - required, - readonly, - disabled, - type, - label, - value, - onChange, - onBlur, - onFocus, - autofocus, - options, - schema, - uiSchema, - rawErrors = [], - registry, - ...textFieldProps -}: WidgetProps) { - const inputProps = getInputProps(schema, type, options); - // Now we need to pull out the step, min, max into an inner `inputProps` for material-ui - const { step, min, max, ...rest } = inputProps; - const otherProps = { - inputProps: { - step, - min, - max, - ...(schema.examples ? { list: `examples_${id}` } : undefined), - }, +import { useCallback } from 'react'; + +/** The `BaseInputTemplate` is the template to use to render the basic `` component for the `core` theme. + * It is used as the template for rendering many of the based widgets that differ by `type` and callbacks only. + * It can be customized/overridden for other themes or individual implementations as needed. + * + * @param props - The `WidgetProps` for this template + */ +export default function BaseInputTemplate< + T = any, + S extends StrictRJSFSchema = RJSFSchema, + F extends FormContextType = any +>(props: WidgetProps) { + const { + id, + value, + readonly, + disabled, + autofocus, + label, + onBlur, + onFocus, + onChange, + required, + options, + schema, + uiSchema, + formContext, + registry, + rawErrors, + type, + ...rest + } = props; + + // Note: since React 15.2.0 we can't forward unknown element attributes, so we + // exclude the "options" and "schema" ones here. + if (!id) { + console.log('No id for', props); + throw new Error(`no id for props ${JSON.stringify(props)}`); + } + const inputProps = { ...rest, + ...getInputProps(schema, type, options), }; - const localOnChange = ({ - // eslint-disable-next-line no-shadow - target: { value }, - }: React.ChangeEvent) => { - onChange(value === '' ? options.emptyValue : value); - }; - const localOnBlur = ({ - // eslint-disable-next-line no-shadow - target: { value }, - }: React.FocusEvent) => onBlur(id, value); - const localOnFocus = ({ - // eslint-disable-next-line no-shadow - target: { value }, - }: React.FocusEvent) => onFocus(id, value); - const { schemaUtils } = registry; - const displayLabel = schemaUtils.getDisplayLabel(schema, uiSchema); + let inputValue; + if (inputProps.type === 'number' || inputProps.type === 'integer') { + inputValue = value || value === 0 ? value : ''; + } else { + inputValue = value == null ? '' : value; + } + + const _onChange = useCallback( + ({ target: { value } }: React.ChangeEvent) => + onChange(value === '' ? options.emptyValue : value), + [onChange, options] + ); + const _onBlur = useCallback( + ({ target: { value } }: React.FocusEvent) => + onBlur(id, value), + [onBlur, id] + ); + const _onFocus = useCallback( + ({ target: { value } }: React.FocusEvent) => + onFocus(id, value), + [onFocus, id] + ); let labelToUse = label; if (uiSchema && uiSchema['ui:title']) { @@ -59,39 +82,33 @@ function BaseInputTemplate({ } else if (schema && schema.title) { labelToUse = schema.title; } - if (required) { - labelToUse = `${labelToUse}*`; - } return ( <> 0} - onChange={localOnChange} - onBlur={localOnBlur} - onFocus={localOnFocus} + onChange={_onChange} + onBlur={_onBlur} + onFocus={_onFocus} // eslint-disable-next-line react/jsx-props-no-spreading - {...otherProps} + {...inputProps} /> - {schema.examples && ( - - {(schema.examples as string[]) - .concat(schema.default ? ([schema.default] as string[]) : []) - .map((example: any) => { - // eslint-disable-next-line jsx-a11y/control-has-associated-label - return