Skip to content

Commit

Permalink
wip: JSON Forms middleware support
Browse files Browse the repository at this point in the history
Showcase of middleware support in JSON Forms React. Not tested at all.
  • Loading branch information
sdirix committed Nov 7, 2023
1 parent f905c82 commit e8bb2fd
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 14 deletions.
5 changes: 5 additions & 0 deletions packages/react/src/JsonForms.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import type Ajv from 'ajv';
import type { ErrorObject } from 'ajv';
import { UnknownRenderer } from './UnknownRenderer';
import {
CoreActions,
createId,
Generate,
isControl,
Expand All @@ -45,6 +46,7 @@ import {
} from '@jsonforms/core';
import {
JsonFormsStateProvider,
Middleware,
withJsonFormsRendererProps,
} from './JsonFormsContext';

Expand All @@ -54,6 +56,7 @@ interface JsonFormsRendererState {

export interface JsonFormsReactProps {
onChange?(state: Pick<JsonFormsCore, 'data' | 'errors'>): void;
middleware?: Middleware;
}

export class JsonFormsDispatchRenderer extends React.Component<
Expand Down Expand Up @@ -203,6 +206,7 @@ export const JsonForms = (
validationMode,
i18n,
additionalErrors,
middleware,
} = props;
const schemaToUse = useMemo(
() => (schema !== undefined ? schema : Generate.jsonSchema(data)),
Expand Down Expand Up @@ -233,6 +237,7 @@ export const JsonForms = (
i18n,
}}
onChange={onChange}
middleware={middleware}
>
<JsonFormsDispatch />
</JsonFormsStateProvider>
Expand Down
61 changes: 47 additions & 14 deletions packages/react/src/JsonFormsContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ import {
OwnPropsOfLabel,
LabelProps,
mapStateToLabelProps,
CoreActions,
} from '@jsonforms/core';
import debounce from 'lodash/debounce';
import React, {
Expand All @@ -87,6 +88,7 @@ import React, {
useMemo,
useReducer,
useRef,
useState,
} from 'react';

const initialCoreState: JsonFormsCore = {
Expand Down Expand Up @@ -126,33 +128,59 @@ const useEffectAfterFirstRender = (
}, dependencies);
};

export interface Middleware {
(
state: JsonFormsCore,
action: CoreActions,
defaultDispatch: (
state: JsonFormsCore,
action: CoreActions
) => JsonFormsCore
): JsonFormsCore;
}

const defaultMiddleware: Middleware = (state, action, defaultDispatch) =>
defaultDispatch(state, action);

export const JsonFormsStateProvider = ({
children,
initState,
onChange,
middleware,
}: any) => {
const { data, schema, uischema, ajv, validationMode, additionalErrors } =
initState.core;

const [core, coreDispatch] = useReducer(coreReducer, undefined, () =>
coreReducer(
const middlewareRef = useRef<Middleware>(middleware ?? defaultMiddleware);
middlewareRef.current = middleware ?? defaultMiddleware;

const [core, setCore] = useState<JsonFormsCore>(() =>
middlewareRef.current(
initState.core,
Actions.init(data, schema, uischema, {
ajv,
validationMode,
additionalErrors,
})
}),
coreReducer
)
);
useEffect(() => {
coreDispatch(
Actions.updateCore(data, schema, uischema, {
ajv,
validationMode,
additionalErrors,
})
);
}, [data, schema, uischema, ajv, validationMode, additionalErrors]);

useEffect(
() =>
setCore((currentCore) =>
middlewareRef.current(
currentCore,
Actions.updateCore(data, schema, uischema, {
ajv,
validationMode,
additionalErrors,
}),
coreReducer
)
),
[data, schema, uischema, ajv, validationMode, additionalErrors]
);

const [config, configDispatch] = useReducer(configReducer, undefined, () =>
configReducer(undefined, Actions.setConfig(initState.config))
Expand Down Expand Up @@ -185,6 +213,12 @@ export const JsonFormsStateProvider = ({
initState.i18n?.translateError,
]);

const dispatch = useCallback((action: CoreActions) => {
setCore((currentCore) =>
middlewareRef.current(currentCore, action, coreReducer)
);
}, []);

const contextValue = useMemo(
() => ({
core,
Expand All @@ -194,8 +228,7 @@ export const JsonFormsStateProvider = ({
uischemas: initState.uischemas,
readonly: initState.readonly,
i18n: i18n,
// only core dispatch available
dispatch: coreDispatch,
dispatch: dispatch,
}),
[
core,
Expand Down

0 comments on commit e8bb2fd

Please sign in to comment.