Skip to content

Commit

Permalink
fix(react-formio): fix onAsyncSubmit on useForm hook
Browse files Browse the repository at this point in the history
  • Loading branch information
Romakita committed Jan 6, 2025
1 parent 6025ce5 commit c1de308
Show file tree
Hide file tree
Showing 17 changed files with 3,952 additions and 341 deletions.
3 changes: 2 additions & 1 deletion .storybook/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ const config: StorybookConfig = {
"@storybook/addon-mdx-gfm",
"@storybook/addon-links",
"@storybook/addon-interactions",
"@chromatic-com/storybook"
"@chromatic-com/storybook",
"storybook-addon-mock"
],

framework: {
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@
"semantic-release": "23.0.5",
"semantic-release-slack-bot": "4.0.2",
"storybook": "^8.4.7",
"storybook-addon-mock": "5.0.0",
"typescript": "5.7.2",
"vite": "5.4.11",
"vite-plugin-dts": "4.4.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,32 +4,180 @@
"tags": [],
"components": [
{
"key": "firstName",
"label": "First name",
"labelPosition": "top",
"placeholder": "",
"description": "",
"tooltip": "",
"prefix": "",
"suffix": "",
"widget": {
"type": "input"
},
"inputMask": "",
"displayMask": "",
"applyMaskOn": "change",
"allowMultipleMasks": false,
"customClass": "",
"tabindex": "",
"autocomplete": "",
"hidden": false,
"hideLabel": false,
"showWordCount": false,
"showCharCount": false,
"mask": false,
"autofocus": false,
"spellcheck": true,
"disabled": false,
"tableView": true,
"modalEdit": false,
"multiple": false,
"persistent": true,
"inputFormat": "plain",
"protected": false,
"dbIndex": false,
"case": "",
"truncateMultipleSpaces": false,
"encrypted": false,
"redrawOn": "",
"clearOnHide": true,
"customDefaultValue": "",
"calculateValue": "",
"calculateServer": false,
"allowCalculateOverride": false,
"validateOn": "change",
"validate": {
"required": false,
"pattern": "",
"customMessage": "",
"custom": "",
"customPrivate": false,
"json": "",
"minLength": "",
"maxLength": "",
"strictDateValidation": false,
"multiple": false,
"unique": false
},
"unique": false,
"validateWhenHidden": false,
"errorLabel": "",
"inputType": "text",
"errors": "",
"key": "firstName",
"tags": [],
"properties": {},
"conditional": {
"show": null,
"when": null,
"eq": "",
"json": ""
},
"customConditional": "",
"logic": [],
"attributes": {},
"overlay": {
"style": "",
"page": "",
"left": "",
"top": "",
"width": "",
"height": ""
},
"type": "textfield",
"defaultValue": "",
"validate": {
"required": true
}
"dataGridLabel": false,
"input": true,
"refreshOn": "",
"addons": [],
"inputType": "text",
"defaultValue": ""
},
{
"key": "lastName",
"label": "Last name",
"labelPosition": "top",
"placeholder": "",
"description": "",
"tooltip": "",
"prefix": "",
"suffix": "",
"widget": {
"type": "input"
},
"inputMask": "",
"displayMask": "",
"applyMaskOn": "change",
"allowMultipleMasks": false,
"customClass": "",
"tabindex": "",
"autocomplete": "",
"hidden": false,
"hideLabel": false,
"showWordCount": false,
"showCharCount": false,
"mask": false,
"autofocus": false,
"spellcheck": true,
"disabled": false,
"tableView": true,
"modalEdit": false,
"multiple": false,
"persistent": true,
"inputFormat": "plain",
"protected": false,
"dbIndex": false,
"case": "",
"truncateMultipleSpaces": false,
"encrypted": false,
"redrawOn": "",
"clearOnHide": true,
"customDefaultValue": "",
"calculateValue": "",
"calculateServer": false,
"allowCalculateOverride": false,
"validateOn": "change",
"validate": {
"required": false,
"pattern": "",
"customMessage": "",
"custom": "",
"customPrivate": false,
"json": "",
"minLength": "",
"maxLength": "",
"strictDateValidation": false,
"multiple": false,
"unique": false
},
"unique": false,
"validateWhenHidden": false,
"errorLabel": "",
"inputType": "text",
"errors": "",
"key": "lastName",
"tags": [],
"properties": {},
"conditional": {
"show": null,
"when": null,
"eq": "",
"json": ""
},
"customConditional": "",
"logic": [],
"attributes": {},
"overlay": {
"style": "",
"page": "",
"left": "",
"top": "",
"width": "",
"height": ""
},
"type": "textfield",
"defaultValue": "",
"validate": {
"required": true
}
"dataGridLabel": false,
"input": true,
"refreshOn": "",
"addons": [],
"inputType": "text",
"defaultValue": ""
},
{
"type": "button",
Expand Down Expand Up @@ -101,7 +249,8 @@
"allowMultipleMasks": false,
"leftIcon": "",
"rightIcon": "",
"dataGridLabel": true
"dataGridLabel": true,
"addons": []
}
]
}
84 changes: 84 additions & 0 deletions packages/react-formio/src/components/__fixtures__/useEditForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import { useEffect, useState } from "react";

import { SubmissionType } from "../../interfaces";

function useFetch(url: string, opts: any) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);

function fetchData() {
fetch(url, opts)
.then((res) => res.json())
.then((data) => {
setData(data);
setLoading(false);
})
.catch((err) => {
setError(err);
setLoading(false);
});
}

useEffect(() => {
fetchData();
}, [url, opts.method]);

Check warning on line 25 in packages/react-formio/src/components/__fixtures__/useEditForm.tsx

View workflow job for this annotation

GitHub Actions / lint

React Hook useEffect has a missing dependency: 'fetchData'. Either include it or remove the dependency array

return { data, loading, error, fetchData };
}

async function updateSubmission(model: string, submissionId: string, submission: SubmissionType["data"]) {
const response = await fetch(`https://local.dev/form/${model}/submissions/${submissionId}`, {
method: "PUT",
headers: {
"Content-Type": "application/json",
Accept: "application/json"
},
body: JSON.stringify(submission)
});

const data = await response.json();

if (!response.ok) {
const error: any = new Error("Update submission failed");
error.errors = [data];
throw error;
}

return data;
}

export function useEditForm({ model, submissionId }: any) {
const form = useFetch(`https://local.dev/form/${model}`, {
method: "GET",
headers: {
"Content-Type": "application/json",
Accept: "application/json"
}
});

const submission = useFetch(`https://local.dev/form/${model}/submissions/${submissionId}`, {
method: "GET",
headers: {
"Content-Type": "application/json",
Accept: "application/json"
}
});

function onSubmit(submission: any) {
return updateSubmission(model, submissionId, submission.data).then((data) => {
return {
...submission,
data
};
});
}

return {
form: form.data,
data: submission.data,
loading: form.loading || submission.loading,
error: form.error || submission.error,
onSubmit
};
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { ComponentSchema } from "formiojs";
import AllComponents from "formiojs/components";
import Components from "formiojs/components/Components";
import FormioFormBuilder from "formiojs/FormBuilder";
import cloneDeep from "lodash/cloneDeep";
import noop from "lodash/noop";
import { Component } from "react";

import { ComponentType } from "../../interfaces";
import { callLast } from "../../utils/callLast";

Components.setComponents(AllComponents);
Expand Down Expand Up @@ -53,11 +53,11 @@ async function createBuilder(el: Element, { components = [], display, options, o
}

export interface FormBuilderProps {
components: ComponentSchema[];
components: ComponentType[];
display?: string;
options?: any;
builder?: any;
onChange?: (components: ComponentSchema[]) => void;
onChange?: (components: ComponentType[]) => void;
onAddComponent?: Function;
onUpdateComponent?: Function;
onRemoveComponent?: Function;
Expand Down Expand Up @@ -154,7 +154,7 @@ export class FormBuilder extends Component<FormBuilderProps, any> {
}
}

whenComponentsChange(components: ComponentSchema[]) {
whenComponentsChange(components: ComponentType[]) {
this.setState({ components }, () => {
this.props?.onChange && this.props.onChange(components);
});
Expand Down
21 changes: 17 additions & 4 deletions packages/react-formio/src/components/form/form.component.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,29 @@
import { JSON } from "../../interfaces";
import { useForm, UseFormHookProps } from "./useForm.hook";
import { useForm, UseFormProps } from "./useForm.hook";

export interface FormProps<Data extends { [key: string]: JSON } = { [key: string]: JSON }> extends UseFormHookProps<Data> {
class CSSProperties {}

export interface FormProps<Data extends { [key: string]: JSON } = { [key: string]: JSON }> extends UseFormProps<Data> {
["data-testid"]?: string;
/**
*
*/
className?: string;

style?: CSSProperties;
}

export function Form<Data extends { [key: string]: JSON } = { [key: string]: JSON }>(props: Partial<FormProps<Data>>) {
export function Form<Data extends { [key: string]: JSON } = { [key: string]: JSON }>({
style,
className,
"data-testid": dataTestId = "formio-container",
...props
}: Partial<FormProps<Data>>) {
const { element } = useForm<Data>(props);

return <div data-testid={props["data-testid"]} className={props.className} ref={element} />;
return (
<div>
<div data-testid={dataTestId} style={style} className={className} ref={element} />
</div>
);
}
Loading

0 comments on commit c1de308

Please sign in to comment.