-
Notifications
You must be signed in to change notification settings - Fork 3.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore: refactor query duplication flow (#36915)
## Description This PR refactors the action duplication saga and action calls to remove dependency on pageID. As far as CE code is concerned, this PR doesn't change any functionality for the end user. Those changes are done for workflows editor in EE. Fixes #36886 ## Automation /test all ### 🔍 Cypress test results <!-- This is an auto-generated comment: Cypress test results --> > [!TIP] > 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉 > Workflow run: <https://github.com/appsmithorg/appsmith/actions/runs/11462274307> > Commit: 04dfbfb > <a href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=11462274307&attempt=2" target="_blank">Cypress dashboard</a>. > Tags: `@tag.All` > Spec: > <hr>Tue, 22 Oct 2024 16:21:32 UTC <!-- end of auto-generated comment: Cypress test results --> ## Communication Should the DevRel and Marketing teams inform users about this change? - [ ] Yes - [x] No <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Introduced a new hook, `useHandleDuplicateClick`, enhancing action duplication functionality. - Added a new interface and function for generating destination ID information. - **Bug Fixes** - Updated action request structure to use `destinationEntityId` for consistency across components. - **Documentation** - Enhanced success message flexibility for action copy notifications. - **Tests** - Added unit tests for the `ActionEntityContextMenu` component to ensure proper functionality and rendering. - **Refactor** - Improved context menu handling based on entity types for better user experience. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
- Loading branch information
1 parent
23a5772
commit 0b93768
Showing
10 changed files
with
304 additions
and
43 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 |
---|---|---|
@@ -1,5 +1,6 @@ | ||
export { useActionSettingsConfig } from "ee/PluginActionEditor/hooks/useActionSettingsConfig"; | ||
export { useHandleDeleteClick } from "ee/PluginActionEditor/hooks/useHandleDeleteClick"; | ||
export { useHandleDuplicateClick } from "./useHandleDuplicateClick"; | ||
export { useHandleRunClick } from "ee/PluginActionEditor/hooks/useHandleRunClick"; | ||
export { useBlockExecution } from "ee/PluginActionEditor/hooks/useBlockExecution"; | ||
export { useAnalyticsOnRunClick } from "ee/PluginActionEditor/hooks/useAnalyticsOnRunClick"; |
26 changes: 26 additions & 0 deletions
26
app/client/src/PluginActionEditor/hooks/useHandleDuplicateClick.ts
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,26 @@ | ||
import { copyActionRequest } from "actions/pluginActionActions"; | ||
import { usePluginActionContext } from "PluginActionEditor/PluginActionContext"; | ||
import { useCallback } from "react"; | ||
import { useDispatch } from "react-redux"; | ||
|
||
function useHandleDuplicateClick() { | ||
const { action } = usePluginActionContext(); | ||
const dispatch = useDispatch(); | ||
|
||
const handleDuplicateClick = useCallback( | ||
(destinationEntityId: string) => { | ||
dispatch( | ||
copyActionRequest({ | ||
id: action.id, | ||
destinationEntityId, | ||
name: action.name, | ||
}), | ||
); | ||
}, | ||
[action.id, action.name, dispatch], | ||
); | ||
|
||
return { handleDuplicateClick }; | ||
} | ||
|
||
export { useHandleDuplicateClick }; |
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
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
170 changes: 170 additions & 0 deletions
170
app/client/src/pages/Editor/Explorer/Actions/ActionEntityContextMenu.test.tsx
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,170 @@ | ||
import React from "react"; | ||
import { fireEvent, render, waitFor } from "@testing-library/react"; | ||
import "@testing-library/jest-dom/extend-expect"; | ||
import { Provider } from "react-redux"; | ||
import { lightTheme } from "selectors/themeSelectors"; | ||
import { ThemeProvider } from "styled-components"; | ||
import configureStore from "redux-mock-store"; | ||
import { PluginType } from "entities/Action"; | ||
import { | ||
ActionEntityContextMenu, | ||
type EntityContextMenuProps, | ||
} from "./ActionEntityContextMenu"; | ||
import { FilesContextProvider } from "../Files/FilesContextProvider"; | ||
import { ActionParentEntityType } from "ee/entities/Engine/actionHelpers"; | ||
import { act } from "react-dom/test-utils"; | ||
import { | ||
CONTEXT_COPY, | ||
CONTEXT_DELETE, | ||
CONTEXT_MOVE, | ||
CONTEXT_RENAME, | ||
CONTEXT_SHOW_BINDING, | ||
createMessage, | ||
} from "ee/constants/messages"; | ||
import { | ||
ReduxActionTypes, | ||
type ReduxAction, | ||
} from "ee/constants/ReduxActionConstants"; | ||
|
||
const mockStore = configureStore([]); | ||
|
||
const page1Id = "605c435a91dea93f0eaf91ba"; | ||
const page2Id = "605c435a91dea93f0eaf91bc"; | ||
const basePage2Id = "605c435a91dea93f0eaf91bc"; | ||
const defaultState = { | ||
ui: { | ||
selectedWorkspace: { | ||
workspace: {}, | ||
}, | ||
workspaces: { | ||
packagesList: [], | ||
}, | ||
users: { | ||
featureFlag: { | ||
data: {}, | ||
}, | ||
}, | ||
}, | ||
entities: { | ||
actions: [], | ||
pageList: { | ||
pages: [ | ||
{ | ||
pageId: page1Id, | ||
basePageId: page2Id, | ||
pageName: "Page1", | ||
isDefault: true, | ||
slug: "page-1", | ||
}, | ||
{ | ||
pageId: page2Id, | ||
basePageId: basePage2Id, | ||
pageName: "Page2", | ||
isDefault: false, | ||
slug: "page-2", | ||
}, | ||
], | ||
}, | ||
}, | ||
}; | ||
|
||
const defaultProps: EntityContextMenuProps = { | ||
id: "test-action-id", | ||
name: "test-action", | ||
canManageAction: true, | ||
canDeleteAction: true, | ||
pluginType: PluginType.DB, | ||
}; | ||
|
||
const defaultContext = { | ||
editorId: "test-editor-id", | ||
canCreateActions: true, | ||
parentEntityId: "test-parent-entity-id", | ||
parentEntityType: ActionParentEntityType.PAGE, | ||
}; | ||
|
||
describe("ActionEntityContextMenu", () => { | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
let store: any; | ||
|
||
beforeEach(() => { | ||
jest.clearAllMocks(); | ||
}); | ||
|
||
it("renders context menu with correct options for application editor", async () => { | ||
store = mockStore(defaultState); | ||
const { findByText, getByRole } = render( | ||
<Provider store={store}> | ||
<ThemeProvider theme={lightTheme}> | ||
<FilesContextProvider {...defaultContext}> | ||
<ActionEntityContextMenu {...defaultProps} /> | ||
</FilesContextProvider> | ||
</ThemeProvider> | ||
</Provider>, | ||
); | ||
const triggerToOpenMenu = getByRole("button"); | ||
|
||
act(() => { | ||
fireEvent.click(triggerToOpenMenu); | ||
}); | ||
|
||
await waitFor(() => { | ||
expect(triggerToOpenMenu.parentNode).toHaveAttribute( | ||
"aria-expanded", | ||
"true", | ||
); | ||
}); | ||
|
||
// In context of pages, the copy to page option will be shown | ||
const copyQueryToPageOptions = await findByText( | ||
createMessage(CONTEXT_COPY), | ||
); | ||
|
||
expect(await findByText(createMessage(CONTEXT_RENAME))).toBeInTheDocument(); | ||
expect(await findByText(createMessage(CONTEXT_DELETE))).toBeInTheDocument(); | ||
expect(await findByText(createMessage(CONTEXT_MOVE))).toBeInTheDocument(); | ||
expect( | ||
await findByText(createMessage(CONTEXT_SHOW_BINDING)), | ||
).toBeInTheDocument(); | ||
expect(copyQueryToPageOptions).toBeInTheDocument(); | ||
|
||
// Now we click on the copy to page option | ||
act(() => { | ||
fireEvent.click(copyQueryToPageOptions); | ||
}); | ||
|
||
// Now a menu with the list of pages will show up | ||
const copyQueryToPageSubOptionPage1 = await findByText("Page1"); | ||
|
||
expect(copyQueryToPageSubOptionPage1).toBeInTheDocument(); | ||
expect(await findByText("Page2")).toBeInTheDocument(); | ||
|
||
// Clicking on the page will trigger the correct action | ||
act(() => { | ||
fireEvent.click(copyQueryToPageSubOptionPage1); | ||
}); | ||
|
||
let actions: Array< | ||
ReduxAction<{ | ||
payload: { | ||
id: string; | ||
destinationEntityId: string; | ||
name: string; | ||
}; | ||
}> | ||
> = []; | ||
|
||
await waitFor(() => { | ||
actions = store.getActions(); | ||
}); | ||
|
||
expect(actions.length).toBe(1); | ||
expect(actions[0].type).toBe(ReduxActionTypes.COPY_ACTION_INIT); | ||
expect(actions[0].payload).toEqual({ | ||
destinationEntityId: page1Id, | ||
id: "test-action-id", | ||
name: "test-action", | ||
}); | ||
}); | ||
// TODO: add tests for all options rendered in the context menu | ||
}); |
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.