fix: remove unnecessary re-renders on JS Object context menu in explorer (#14866)
* Fixes rerenders on JS context menu * Fixed warnings * Fix review comments * Perf adjustments * Replace entityName hook with a function that reads from store. * Use menuOptions selectors to populate options
This commit is contained in:
parent
1ca40f9eeb
commit
bed2a02fdd
|
|
@ -1,7 +1,6 @@
|
|||
import React, { useCallback, useState } from "react";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import TreeDropdown from "pages/Editor/Explorer/TreeDropdown";
|
||||
import { AppState } from "reducers";
|
||||
import ContextMenuTrigger from "../ContextMenuTrigger";
|
||||
import {
|
||||
moveJSCollectionRequest,
|
||||
|
|
@ -9,8 +8,8 @@ import {
|
|||
deleteJSCollection,
|
||||
} from "actions/jsActionActions";
|
||||
import { ContextMenuPopoverModifiers } from "../helpers";
|
||||
import { noop } from "lodash";
|
||||
import { useNewJSCollectionName } from "./helpers";
|
||||
import noop from "lodash/noop";
|
||||
import { getJSEntityName } from "./helpers";
|
||||
import { initExplorerEntityNameEdit } from "actions/explorerActions";
|
||||
import { ReduxActionTypes } from "@appsmith/constants/ReduxActionConstants";
|
||||
import { ENTITY_TYPE } from "entities/DataTree/dataTreeFactory";
|
||||
|
|
@ -24,6 +23,7 @@ import {
|
|||
CONTEXT_SHOW_BINDING,
|
||||
createMessage,
|
||||
} from "@appsmith/constants/messages";
|
||||
import { getPageListAsOptions } from "selectors/entitiesSelector";
|
||||
|
||||
type EntityContextMenuProps = {
|
||||
id: string;
|
||||
|
|
@ -32,9 +32,7 @@ type EntityContextMenuProps = {
|
|||
pageId: string;
|
||||
};
|
||||
export function JSCollectionEntityContextMenu(props: EntityContextMenuProps) {
|
||||
const nextEntityName = useNewJSCollectionName();
|
||||
const [confirmDelete, setConfirmDelete] = useState(false);
|
||||
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const showBinding = useCallback(
|
||||
|
|
@ -52,26 +50,30 @@ export function JSCollectionEntityContextMenu(props: EntityContextMenuProps) {
|
|||
);
|
||||
|
||||
const copyJSCollectionToPage = useCallback(
|
||||
(actionId: string, actionName: string, pageId: string) =>
|
||||
(actionId: string, actionName: string, pageId: string) => {
|
||||
const nextEntityName = getJSEntityName();
|
||||
dispatch(
|
||||
copyJSCollectionRequest({
|
||||
id: actionId,
|
||||
destinationPageId: pageId,
|
||||
name: nextEntityName(actionName, pageId, true),
|
||||
}),
|
||||
),
|
||||
[dispatch, nextEntityName],
|
||||
);
|
||||
},
|
||||
[dispatch],
|
||||
);
|
||||
const moveJSCollectionToPage = useCallback(
|
||||
(actionId: string, actionName: string, destinationPageId: string) =>
|
||||
(actionId: string, actionName: string, destinationPageId: string) => {
|
||||
const nextEntityName = getJSEntityName();
|
||||
dispatch(
|
||||
moveJSCollectionRequest({
|
||||
id: actionId,
|
||||
destinationPageId,
|
||||
name: nextEntityName(actionName, destinationPageId, false),
|
||||
}),
|
||||
),
|
||||
[dispatch, nextEntityName, props.pageId],
|
||||
);
|
||||
},
|
||||
[dispatch, props.pageId],
|
||||
);
|
||||
const deleteJSCollectionFromPage = useCallback(
|
||||
(actionId: string, actionName: string) =>
|
||||
|
|
@ -79,13 +81,7 @@ export function JSCollectionEntityContextMenu(props: EntityContextMenuProps) {
|
|||
[dispatch],
|
||||
);
|
||||
|
||||
const menuPages = useSelector((state: AppState) => {
|
||||
return state.entities.pageList.pages.map((page) => ({
|
||||
label: page.pageName,
|
||||
id: page.pageId,
|
||||
value: page.pageName,
|
||||
}));
|
||||
});
|
||||
const menuPages = useSelector(getPageListAsOptions);
|
||||
const editJSCollectionName = useCallback(
|
||||
() => dispatch(initExplorerEntityNameEdit(props.id)),
|
||||
[dispatch, props.id],
|
||||
|
|
|
|||
|
|
@ -1,18 +1,14 @@
|
|||
import React, { useCallback, useState } from "react";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
|
||||
import { AppState } from "reducers";
|
||||
|
||||
import {
|
||||
moveJSCollectionRequest,
|
||||
copyJSCollectionRequest,
|
||||
deleteJSCollection,
|
||||
} from "actions/jsActionActions";
|
||||
|
||||
import { ContextMenuPopoverModifiers } from "../helpers";
|
||||
import { noop } from "lodash";
|
||||
import noop from "lodash/noop";
|
||||
import TreeDropdown from "pages/Editor/Explorer/TreeDropdown";
|
||||
import { useNewJSCollectionName } from "./helpers";
|
||||
import { getJSEntityName } from "./helpers";
|
||||
import styled from "styled-components";
|
||||
import Icon, { IconSize } from "components/ads/Icon";
|
||||
import { Position } from "@blueprintjs/core";
|
||||
|
|
@ -23,6 +19,7 @@ import {
|
|||
CONTEXT_MOVE,
|
||||
createMessage,
|
||||
} from "@appsmith/constants/messages";
|
||||
import { getPageListAsOptions } from "selectors/entitiesSelector";
|
||||
|
||||
type EntityContextMenuProps = {
|
||||
id: string;
|
||||
|
|
@ -70,31 +67,35 @@ export const MoreActionablesContainer = styled.div<{ isOpen?: boolean }>`
|
|||
|
||||
export function MoreJSCollectionsMenu(props: EntityContextMenuProps) {
|
||||
const [isMenuOpen, setIsMenuOpen] = useState(false);
|
||||
const nextEntityName = useNewJSCollectionName();
|
||||
const [confirmDelete, setConfirmDelete] = useState(false);
|
||||
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const copyJSCollectionToPage = useCallback(
|
||||
(actionId: string, actionName: string, pageId: string) =>
|
||||
(actionId: string, actionName: string, pageId: string) => {
|
||||
const nextEntityName = getJSEntityName();
|
||||
dispatch(
|
||||
copyJSCollectionRequest({
|
||||
id: actionId,
|
||||
destinationPageId: pageId,
|
||||
name: nextEntityName(`${actionName}Copy`, pageId),
|
||||
}),
|
||||
),
|
||||
[dispatch, nextEntityName],
|
||||
);
|
||||
},
|
||||
[dispatch],
|
||||
);
|
||||
|
||||
const moveJSCollectionToPage = useCallback(
|
||||
(actionId: string, actionName: string, destinationPageId: string) =>
|
||||
(actionId: string, actionName: string, destinationPageId: string) => {
|
||||
const nextEntityName = getJSEntityName();
|
||||
dispatch(
|
||||
moveJSCollectionRequest({
|
||||
id: actionId,
|
||||
destinationPageId,
|
||||
name: nextEntityName(actionName, destinationPageId, false),
|
||||
}),
|
||||
),
|
||||
[dispatch, nextEntityName, props.pageId],
|
||||
);
|
||||
},
|
||||
[dispatch],
|
||||
);
|
||||
const deleteJSCollectionFromPage = useCallback(
|
||||
(actionId: string, actionName: string) =>
|
||||
|
|
@ -102,13 +103,7 @@ export function MoreJSCollectionsMenu(props: EntityContextMenuProps) {
|
|||
[dispatch],
|
||||
);
|
||||
|
||||
const menuPages = useSelector((state: AppState) => {
|
||||
return state.entities.pageList.pages.map((page) => ({
|
||||
label: page.pageName,
|
||||
id: page.pageId,
|
||||
value: page.pageName,
|
||||
}));
|
||||
});
|
||||
const menuPages = useSelector(getPageListAsOptions);
|
||||
|
||||
return (
|
||||
<TreeDropdown
|
||||
|
|
|
|||
|
|
@ -1,26 +1,22 @@
|
|||
import { useMemo } from "react";
|
||||
import { useSelector } from "react-redux";
|
||||
import { AppState } from "reducers";
|
||||
import { getNextEntityName } from "utils/AppsmithUtils";
|
||||
import { groupBy } from "lodash";
|
||||
import { JSCollectionData } from "reducers/entityReducers/jsActionsReducer";
|
||||
import { selectJSCollections } from "selectors/editorSelectors";
|
||||
import store from "store";
|
||||
|
||||
export const useNewJSCollectionName = () => {
|
||||
const jsactions = useSelector((state: AppState) => state.entities.jsActions);
|
||||
const groupedActions = useMemo(() => {
|
||||
return groupBy(jsactions, "config.pageId");
|
||||
}, [jsactions]);
|
||||
export const getJSEntityName = () => {
|
||||
const state = store.getState();
|
||||
const jsCollections = selectJSCollections(state);
|
||||
return (
|
||||
name: string,
|
||||
destinationPageId: string,
|
||||
isCopyOperation?: boolean,
|
||||
) => {
|
||||
const pageActions = groupedActions[destinationPageId];
|
||||
// Get action names of the destination page only
|
||||
const actionNames = pageActions
|
||||
? pageActions.map((action: JSCollectionData) => action.config.name)
|
||||
: [];
|
||||
|
||||
const groupedActions = groupBy(jsCollections, "config.pageId");
|
||||
const pageActions = groupedActions[destinationPageId] || [];
|
||||
const actionNames = pageActions.map(
|
||||
(action: JSCollectionData) => action.config.name,
|
||||
);
|
||||
return actionNames.indexOf(name) > -1
|
||||
? getNextEntityName(
|
||||
isCopyOperation ? `${name}Copy` : name,
|
||||
|
|
|
|||
|
|
@ -532,3 +532,6 @@ export const getEditorURL = createSelector(
|
|||
pageId,
|
||||
}),
|
||||
);
|
||||
|
||||
export const selectJSCollections = (state: AppState) =>
|
||||
state.entities.jsActions;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user