forked from refinedev/refine
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor(core): useForm improvements (refinedev#5714)
* chore: bind to RK-563 * chore(core): add defer execution helper * chore(core): export missing create params type * feat(core): add `useRefineOptions` hook * feat(core): add `useId` internal hook * chore(core): update naming for use-form * chore(core): separate types from the main file * chore(core): add submitAutoSave to autosave props * test(core-use-form): add submit rejection cases * refactor(core-use-form): update submission handling and deprecate `onFinish` * chore(core): add changeset * chore(core): add exports of missing use form types * chore(use-id): update resource from props usage * chore(antd): fix use-modal-form return type * chore(antd): fix use-steps-form return type * chore(core-use-form): check for values before resolving submission * chore(core): update use id hook usage * test(core): add missing id case to use-id * test(core): update use-form cases * chore(core): mutation response callback calling conditions * fix(autosave): catch autosave errors silently * fix(core-use-form): autosave submission should not throw * fix(autosave): fix debounced catch * fix(mantine): catch error on save button click * chore(core-use-form): update variable naming * test(core-use-form): update missing id case * chore(core): add async-debounce helper * fix(core-use-form): debounced auto save as promise * fix(auto-save): catch autosave errors silently * test(core): add missing cases for async-debounce * chore(use-form): revert type change * chore(core-use-form): revert submit/onFinish changes * chore(use-form): update onFinish second argument to an object * chore(save-and-continue): disable form redirect * fix(core-use-form): add autosave edit action check * chore(form-core-use-form): add autosave and use formdata * test(e2e): add e2e tests for form-core-use-form * chore: update changesets * test(e2e): update test conditions --------- Co-authored-by: Batuhan Wilhelm <[email protected]>
- Loading branch information
Showing
28 changed files
with
1,553 additions
and
781 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
--- | ||
"@refinedev/mantine": patch | ||
--- | ||
|
||
Due to the bug fix made in the `@refinedev/core`, `onFinishAutoSave`'s returned promise can now reject and should be handled accordingly. Updated `useForm`'s auto save handler to catch the rejection without breaking the application. | ||
|
||
Additionally due to the same changes, `onFinish` should also be handled accordingly. Updated `useForm`'s `saveButtonProps.onClick` to catch the rejection without breaking the application. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
--- | ||
"@refinedev/react-hook-form": patch | ||
--- | ||
|
||
Due to the bug fix made in the `@refinedev/core`, `onFinishAutoSave`'s returned promise can now reject and should be handled accordingly. Updated `useForm`'s auto save handler to catch the rejection without breaking the application. | ||
|
||
Additionally due to the same changes, `onFinish` should also be handled accordingly. Updated `useForm`'s `saveButtonProps.onClick` to catch the rejection without breaking the application. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
--- | ||
"@refinedev/core": patch | ||
--- | ||
|
||
Refactored the internal logic of `useForm` to be more efficient and readable, along with few bug fixes and improvements to the `useForm` hook. | ||
|
||
These changes are related to the issue [#5702](https://github.com/refinedev/refine/issues/5702) and resolves [#5460](https://github.com/refinedev/refine/issues/5460). | ||
|
||
- `onFinish` now rejects when; - `values` is not provided, - `resource` is not defined, - `id` is required but not provided. | ||
previously these cases were silently ignored. | ||
- Same changes also applies to `onFinishAutoSave`. | ||
- `onFinishAutoSave` had an issue with returning the appropriate promise after being called. This resulted in unhandled promise rejections and uncontrollable resolved promises. Now it is fixed, `onFinishAutoSave` will resolve and reject based on the response of the mutation. | ||
- When using auto save, debounced calls will now be cancelled and the respective promises will be rejected with `"cancelled by debounce"` message. These changes might require an update to the code bases that uses `onFinishAutoSave` to handle the rejection of the promise to avoid unhandled promise rejections. | ||
- Combined the separated submit functions into one for sake of simplicity and consistency. (internal) | ||
- `onFinish` rejects and resolved regardless of the `onMutationSuccess` and `onMutationError` hooks are provided or not. (Resolves [#5460](https://github.com/refinedev/refine/issues/5460)) | ||
- `meta` values were concatenated multiple times causing confusion and unexpected behavior, now it is fixed. (internal) | ||
- Moved the `id` determination/inference logic to a separate hook. (internal) | ||
- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
"@refinedev/antd": patch | ||
--- | ||
|
||
Due to the bug fix made in the `@refinedev/core`, `onFinishAutoSave`'s returned promise can now reject and should be handled accordingly. Updated `useForm`'s auto save handler to catch the rejection without breaking the application. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import { defineConfig } from "cypress"; | ||
|
||
export default defineConfig({ | ||
projectId: "sq5j3e", | ||
retries: 3, | ||
e2e: { | ||
fixturesFolder: "../../cypress/fixtures", | ||
supportFile: "../../cypress/support/e2e.ts", | ||
}, | ||
chromeWebSecurity: false, | ||
experimentalMemoryManagement: true, | ||
numTestsKeptInMemory: 1, | ||
viewportWidth: 1920, | ||
viewportHeight: 1080, | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,186 @@ | ||
/// <reference types="cypress" /> | ||
/// <reference types="../../cypress/support" /> | ||
|
||
Cypress.on("uncaught:exception", () => { | ||
return false; | ||
}); | ||
|
||
describe("form-core-use-form", () => { | ||
const BASE_URL = "http://localhost:5173"; | ||
|
||
beforeEach(() => { | ||
cy.clearAllCookies(); | ||
cy.clearAllLocalStorage(); | ||
cy.clearAllSessionStorage(); | ||
|
||
cy.interceptGETPosts(); | ||
cy.visit(BASE_URL); | ||
}); | ||
|
||
it("should edit resource with autosave", () => { | ||
cy.interceptGETCategories(); | ||
cy.interceptGETPost(); | ||
|
||
cy.wait("@getPosts"); | ||
|
||
cy.get("button:contains('Edit')").first().click(); | ||
|
||
cy.wait("@getPost"); | ||
|
||
cy.get("input[name='title']") | ||
.first() | ||
.should("have.value", "Ut Voluptatem Est"); | ||
cy.get("textarea[name='content']") | ||
.first() | ||
.should( | ||
"have.value", | ||
"Repellendus temporibus provident nobis. Non adipisci quod et est dolorem sed qui. A ut omnis. Et perspiciatis quibusdam maiores aliquid est fugit nam odit. Aut aliquam consectetur deleniti commodi velit. Eum eum aperiam voluptate quos quo. Ut quia doloribus a. Molestiae non est fugit enim fugiat non ea quas accusamus. Consequuntur voluptatem nesciunt dolorum expedita optio deserunt. Illo dolorem et similique.", | ||
); | ||
cy.get("button[type='submit']").first().should("not.be.disabled"); | ||
|
||
cy.get("span:has(+ form)").should("have.text", "waiting for changes"); | ||
|
||
cy.interceptPATCHPost(); | ||
|
||
cy.fixture("mock-post").then((mockPost) => { | ||
cy.get("input[name='title']").type(`{selectAll}${mockPost.title}`); | ||
cy.get("textarea[name='content']").type(`{selectAll}${mockPost.content}`); | ||
}); | ||
|
||
cy.wait("@patchPost").then((interception) => { | ||
const response = interception?.response; | ||
|
||
cy.get("span:has(+ form)").should("have.text", "saved"); | ||
|
||
cy.get("button[type='submit']").first().should("not.be.disabled"); | ||
|
||
cy.location("pathname").should("include", "/posts/edit/1"); | ||
|
||
cy.get("input[name='title']").should("have.value", response?.body?.title); | ||
cy.get("textarea[name='content']").should( | ||
"have.value", | ||
response?.body?.content, | ||
); | ||
}); | ||
}); | ||
|
||
it("should clone resource", () => { | ||
cy.interceptGETCategories(); | ||
cy.interceptGETPost(); | ||
|
||
cy.wait("@getPosts"); | ||
|
||
cy.get("button:contains('Clone')").first().click(); | ||
|
||
cy.wait("@getPost"); | ||
|
||
cy.get("input[name='title']") | ||
.first() | ||
.should("have.value", "Ut Voluptatem Est"); | ||
cy.get("textarea[name='content']") | ||
.first() | ||
.should( | ||
"have.value", | ||
"Repellendus temporibus provident nobis. Non adipisci quod et est dolorem sed qui. A ut omnis. Et perspiciatis quibusdam maiores aliquid est fugit nam odit. Aut aliquam consectetur deleniti commodi velit. Eum eum aperiam voluptate quos quo. Ut quia doloribus a. Molestiae non est fugit enim fugiat non ea quas accusamus. Consequuntur voluptatem nesciunt dolorum expedita optio deserunt. Illo dolorem et similique.", | ||
); | ||
cy.get("button[type='submit']").first().should("not.be.disabled"); | ||
|
||
cy.fixture("mock-post").then((mockPost) => { | ||
cy.get("input[name='title']").type(`{selectAll}${mockPost.title}`); | ||
cy.get("textarea[name='content']").type(`{selectAll}${mockPost.content}`); | ||
|
||
cy.interceptPOSTPost(); | ||
|
||
cy.get("button[type='submit']").first().click(); | ||
|
||
cy.wait("@postPost").then((interception) => { | ||
const response = interception?.response; | ||
const body = response?.body; | ||
|
||
expect(body?.title).to.eq(mockPost.title); | ||
expect(body?.content).to.eq(mockPost.content); | ||
|
||
cy.location("pathname").should((loc) => { | ||
expect(loc).to.eq("/posts"); | ||
}); | ||
}); | ||
}); | ||
}); | ||
|
||
it("should edit resource with save button", () => { | ||
cy.interceptGETCategories(); | ||
cy.interceptGETPost(); | ||
|
||
cy.wait("@getPosts"); | ||
|
||
cy.get("button:contains('Edit')").first().click(); | ||
|
||
cy.wait("@getPost"); | ||
|
||
cy.get("input[name='title']") | ||
.first() | ||
.should("have.value", "Ut Voluptatem Est"); | ||
cy.get("textarea[name='content']") | ||
.first() | ||
.should( | ||
"have.value", | ||
"Repellendus temporibus provident nobis. Non adipisci quod et est dolorem sed qui. A ut omnis. Et perspiciatis quibusdam maiores aliquid est fugit nam odit. Aut aliquam consectetur deleniti commodi velit. Eum eum aperiam voluptate quos quo. Ut quia doloribus a. Molestiae non est fugit enim fugiat non ea quas accusamus. Consequuntur voluptatem nesciunt dolorum expedita optio deserunt. Illo dolorem et similique.", | ||
); | ||
cy.get("button[type='submit']").first().should("not.be.disabled"); | ||
|
||
cy.fixture("mock-post").then((mockPost) => { | ||
cy.get("input[name='title']").type(`{selectAll}${mockPost.title}`); | ||
cy.get("textarea[name='content']").type(`{selectAll}${mockPost.content}`); | ||
|
||
cy.interceptPATCHPost(); | ||
|
||
cy.wait(1100); | ||
|
||
cy.get("button[type='submit']").first().click(); | ||
|
||
cy.wait("@patchPost").then((interception) => { | ||
const response = interception?.response; | ||
const body = response?.body; | ||
|
||
expect(body?.title).to.eq(mockPost.title); | ||
expect(body?.content).to.eq(mockPost.content); | ||
|
||
cy.location("pathname").should((loc) => { | ||
expect(loc).to.eq("/posts"); | ||
}); | ||
}); | ||
}); | ||
}); | ||
|
||
it("should create resource", () => { | ||
cy.interceptGETCategories(); | ||
cy.interceptGETPost(); | ||
|
||
cy.wait("@getPosts"); | ||
|
||
cy.get("button:contains('Create Post')").first().click(); | ||
|
||
cy.get("button[type='submit']").first().should("not.be.disabled"); | ||
|
||
cy.fixture("mock-post").then((mockPost) => { | ||
cy.get("input[name='title']").type(`${mockPost.title}`); | ||
cy.get("textarea[name='content']").type(`${mockPost.content}`); | ||
|
||
cy.interceptPOSTPost(); | ||
|
||
cy.get("button[type='submit']").first().click(); | ||
|
||
cy.wait("@postPost").then((interception) => { | ||
const response = interception?.response; | ||
const body = response?.body; | ||
|
||
expect(body?.title).to.eq(mockPost.title); | ||
expect(body?.content).to.eq(mockPost.content); | ||
|
||
cy.location("pathname").should((loc) => { | ||
expect(loc).to.eq("/posts"); | ||
}); | ||
}); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.