From 25540f32e0fca718d18738c27ebcb4b108ed6088 Mon Sep 17 00:00:00 2001 From: jasquat <2487833+jasquat@users.noreply.github.com> Date: Thu, 7 Sep 2023 11:51:24 -0400 Subject: [PATCH] added a widget to allow markdown fields for rjsf (#461) Co-authored-by: jasquat --- .../src/components/CustomForm.tsx | 2 + .../MarkDownFieldWidget.tsx | 75 +++++++++++++++++++ 2 files changed, 77 insertions(+) create mode 100644 spiffworkflow-frontend/src/rjsf/custom_widgets/MarkDownFieldWidget/MarkDownFieldWidget.tsx diff --git a/spiffworkflow-frontend/src/components/CustomForm.tsx b/spiffworkflow-frontend/src/components/CustomForm.tsx index 5c41709f1..50085cc93 100644 --- a/spiffworkflow-frontend/src/components/CustomForm.tsx +++ b/spiffworkflow-frontend/src/components/CustomForm.tsx @@ -4,6 +4,7 @@ import { Form } from '../rjsf/carbon_theme'; import { DATE_RANGE_DELIMITER } from '../config'; import DateRangePickerWidget from '../rjsf/custom_widgets/DateRangePicker/DateRangePickerWidget'; import TypeaheadWidget from '../rjsf/custom_widgets/TypeaheadWidget/TypeaheadWidget'; +import MarkDownFieldWidget from '../rjsf/custom_widgets/MarkDownFieldWidget/MarkDownFieldWidget'; type OwnProps = { id: string; @@ -32,6 +33,7 @@ export default function CustomForm({ const rjsfWidgets = { typeahead: TypeaheadWidget, 'date-range': DateRangePickerWidget, + markdown: MarkDownFieldWidget, }; const formatDateString = (dateString?: string) => { diff --git a/spiffworkflow-frontend/src/rjsf/custom_widgets/MarkDownFieldWidget/MarkDownFieldWidget.tsx b/spiffworkflow-frontend/src/rjsf/custom_widgets/MarkDownFieldWidget/MarkDownFieldWidget.tsx new file mode 100644 index 000000000..009adc021 --- /dev/null +++ b/spiffworkflow-frontend/src/rjsf/custom_widgets/MarkDownFieldWidget/MarkDownFieldWidget.tsx @@ -0,0 +1,75 @@ +import MDEditor from '@uiw/react-md-editor'; +import React, { useCallback } from 'react'; + +interface widgetArgs { + id: string; + value: any; + schema?: any; + uiSchema?: any; + disabled?: boolean; + readonly?: boolean; + rawErrors?: any; + onChange?: any; + autofocus?: any; + label?: string; +} + +// NOTE: To properly validate that both start and end dates are specified +// use this pattern in schemaJson for that field: +// "pattern": "\\d{4}-\\d{2}-\\d{2}:::\\d{4}-\\d{2}-\\d{2}" + +// eslint-disable-next-line sonarjs/cognitive-complexity +export default function MarkDownFieldWidget({ + id, + value, + schema, + uiSchema, + disabled, + readonly, + onChange, + autofocus, + label, + rawErrors = [], +}: widgetArgs) { + let invalid = false; + let errorMessageForField = null; + + let labelToUse = label; + if (uiSchema && uiSchema['ui:title']) { + labelToUse = uiSchema['ui:title']; + } else if (schema && schema.title) { + labelToUse = schema.title; + } + + const onChangeLocal = useCallback( + (newValue: any) => { + onChange(newValue); + }, + [onChange] + ); + + let helperText = null; + if (uiSchema && uiSchema['ui:help']) { + helperText = uiSchema['ui:help']; + } + + if (!invalid && rawErrors && rawErrors.length > 0) { + invalid = true; + if ('validationErrorMessage' in schema) { + errorMessageForField = (schema as any).validationErrorMessage; + } else { + errorMessageForField = `${(labelToUse || '').replace(/\*$/, '')} ${ + rawErrors[0] + }`; + } + } + + return ( + + ); +}