chore: Refactor getSelectedWidget selector (#16647)

* Widget layer optimization
Fix positioned and snipeable component wasted renders

* Some cleanup

* - Few more rough optimization

* Remove console logs

* Clean imports

* Prevent wasted renders of draggable component.

* Add new selector

* - Some code reorganization
- Reduce wasted renders of resizable component

* Clean up positioned container

* Final clean up

* Remove unused import

* Some cleanup based on review comments

* Some code refactoring

* Reduce wasted renderes when dragging and resizing

* Rename getSelectedWidget to getLastSelectedWidget in selectors/ui

Co-authored-by: Satish Gandham <satish@appsmith.com>
This commit is contained in:
Satish Gandham 2022-09-15 11:14:11 +05:30 committed by GitHub
parent d543bbf648
commit 12f9a005ae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 35 additions and 29 deletions

View File

@ -141,7 +141,9 @@ describe("JSON Form Widget Field Change", () => {
.find(".t--jsonformfield-array-add-btn") .find(".t--jsonformfield-array-add-btn")
.should("exist"); .should("exist");
*/ */
cy.get('button span:contains("Add New")').first().should("be.visible"); cy.get('button span:contains("Add New")')
.first()
.should("be.visible");
cy.selectDropdownValue(commonlocators.jsonFormFieldType, /^Text Input/); cy.selectDropdownValue(commonlocators.jsonFormFieldType, /^Text Input/);
cy.closePropertyPane(); cy.closePropertyPane();
}); });

View File

@ -190,7 +190,7 @@ describe("Table Widget property pane feature validation", function() {
const color1 = "rgb(255, 255, 0)"; const color1 = "rgb(255, 255, 0)";
cy.get(widgetsPage.menuColor) cy.get(widgetsPage.menuColor)
.clear() .clear()
.click({force:true}) .click({ force: true })
.type(color1); .type(color1);
cy.get(widgetsPage.tableBtn).should("have.css", "background-color", color1); cy.get(widgetsPage.tableBtn).should("have.css", "background-color", color1);
@ -198,7 +198,7 @@ describe("Table Widget property pane feature validation", function() {
const color2 = "rgb(255, 0, 0)"; const color2 = "rgb(255, 0, 0)";
cy.get(widgetsPage.menuColor) cy.get(widgetsPage.menuColor)
.clear() .clear()
.click({force:true}) .click({ force: true })
// following wait is required to reproduce #9526 // following wait is required to reproduce #9526
.wait(500) .wait(500)
.type(color2); .type(color2);

View File

@ -240,7 +240,7 @@ describe("Table Widget V2 property pane feature validation", function() {
.children() .children()
.contains("URL") .contains("URL")
.click(); .click();
// cy.get(".t--property-control-visible span.bp3-control-indicator").click(); // cy.get(".t--property-control-visible span.bp3-control-indicator").click();
cy.wait("@updateLayout"); cy.wait("@updateLayout");
cy.moveToStyleTab(); cy.moveToStyleTab();
// Verifying Center Alignment // Verifying Center Alignment

View File

@ -14,7 +14,7 @@ import {
getAllWidgetsMap, getAllWidgetsMap,
getDatasource, getDatasource,
} from "selectors/entitiesSelector"; } from "selectors/entitiesSelector";
import { getSelectedWidget } from "selectors/ui"; import { getLastSelectedWidget } from "selectors/ui";
import AnalyticsUtil from "utils/AnalyticsUtil"; import AnalyticsUtil from "utils/AnalyticsUtil";
import history from "utils/history"; import history from "utils/history";
import { getQueryParams } from "utils/URLUtils"; import { getQueryParams } from "utils/URLUtils";
@ -79,7 +79,7 @@ function JSCollectionLink(props: EntityLinkProps) {
function WidgetLink(props: EntityLinkProps) { function WidgetLink(props: EntityLinkProps) {
const widgetMap = useSelector(getAllWidgetsMap); const widgetMap = useSelector(getAllWidgetsMap);
const selectedWidgetId = useSelector(getSelectedWidget); const selectedWidgetId = useSelector(getLastSelectedWidget);
const { navigateToWidget } = useNavigateToWidget(); const { navigateToWidget } = useNavigateToWidget();
const onClick = useCallback(() => { const onClick = useCallback(() => {

View File

@ -10,7 +10,7 @@ import {
} from "selectors/editorSelectors"; } from "selectors/editorSelectors";
import { getAction, getPlugins } from "selectors/entitiesSelector"; import { getAction, getPlugins } from "selectors/entitiesSelector";
import { onApiEditor, onQueryEditor, onCanvas } from "../helpers"; import { onApiEditor, onQueryEditor, onCanvas } from "../helpers";
import { getSelectedWidget } from "selectors/ui"; import { getLastSelectedWidget } from "selectors/ui";
import { getDataTree } from "selectors/dataTreeSelectors"; import { getDataTree } from "selectors/dataTreeSelectors";
import { useNavigateToWidget } from "pages/Editor/Explorer/Widgets/useNavigateToWidget"; import { useNavigateToWidget } from "pages/Editor/Explorer/Widgets/useNavigateToWidget";
import { getActionConfig } from "pages/Editor/Explorer/Actions/helpers"; import { getActionConfig } from "pages/Editor/Explorer/Actions/helpers";
@ -97,7 +97,7 @@ export const useSelectedEntity = () => {
return null; return null;
}); });
const selectedWidget = useSelector(getSelectedWidget); const selectedWidget = useSelector(getLastSelectedWidget);
const widget = useSelector((state: AppState) => { const widget = useSelector((state: AppState) => {
if (onCanvas()) { if (onCanvas()) {
return selectedWidget ? getWidget(state, selectedWidget) : null; return selectedWidget ? getWidget(state, selectedWidget) : null;

View File

@ -52,7 +52,7 @@ import {
import { getActionConfig } from "pages/Editor/Explorer/Actions/helpers"; import { getActionConfig } from "pages/Editor/Explorer/Actions/helpers";
import { HelpBaseURL } from "constants/HelpConstants"; import { HelpBaseURL } from "constants/HelpConstants";
import { ExplorerURLParams } from "pages/Editor/Explorer/helpers"; import { ExplorerURLParams } from "pages/Editor/Explorer/helpers";
import { getSelectedWidget } from "selectors/ui"; import { getLastSelectedWidget } from "selectors/ui";
import AnalyticsUtil from "utils/AnalyticsUtil"; import AnalyticsUtil from "utils/AnalyticsUtil";
import useRecentEntities from "./useRecentEntities"; import useRecentEntities from "./useRecentEntities";
import { get, noop } from "lodash"; import { get, noop } from "lodash";
@ -274,7 +274,7 @@ function GlobalSearch() {
); );
const resetSearchQuery = useSelector(searchQuerySelector); const resetSearchQuery = useSelector(searchQuerySelector);
const selectedWidgetId = useSelector(getSelectedWidget); const lastSelectedWidgetId = useSelector(getLastSelectedWidget);
// keeping query in component state until we can figure out fixed for the perf issues // keeping query in component state until we can figure out fixed for the perf issues
// this is used to update query from outside the component, for ex. using the help button within prop. pane // this is used to update query from outside the component, for ex. using the help button within prop. pane
@ -398,7 +398,7 @@ function GlobalSearch() {
activeItem.widgetId, activeItem.widgetId,
activeItem.type, activeItem.type,
activeItem.pageId, activeItem.pageId,
selectedWidgetId === activeItem.widgetId, lastSelectedWidgetId === activeItem.widgetId,
activeItem.parentModalId, activeItem.parentModalId,
); );
}; };

View File

@ -7,7 +7,7 @@ import { AppState } from "@appsmith/reducers";
import WidgetContextMenu from "./WidgetContextMenu"; import WidgetContextMenu from "./WidgetContextMenu";
import { updateWidgetName } from "actions/propertyPaneActions"; import { updateWidgetName } from "actions/propertyPaneActions";
import { CanvasStructure } from "reducers/uiReducers/pageCanvasStructureReducer"; import { CanvasStructure } from "reducers/uiReducers/pageCanvasStructureReducer";
import { getSelectedWidget, getSelectedWidgets } from "selectors/ui"; import { getLastSelectedWidget, getSelectedWidgets } from "selectors/ui";
import { useNavigateToWidget } from "./useNavigateToWidget"; import { useNavigateToWidget } from "./useNavigateToWidget";
import WidgetIcon from "./WidgetIcon"; import WidgetIcon from "./WidgetIcon";
import AnalyticsUtil from "utils/AnalyticsUtil"; import AnalyticsUtil from "utils/AnalyticsUtil";
@ -26,7 +26,7 @@ const useWidget = (
parentModalId?: string, parentModalId?: string,
) => { ) => {
const selectedWidgets = useSelector(getSelectedWidgets); const selectedWidgets = useSelector(getSelectedWidgets);
const lastSelectedWidget = useSelector(getSelectedWidget); const lastSelectedWidget = useSelector(getLastSelectedWidget);
const isWidgetSelected = selectedWidgets.includes(widgetId); const isWidgetSelected = selectedWidgets.includes(widgetId);
const multipleWidgetsSelected = selectedWidgets.length > 1; const multipleWidgetsSelected = selectedWidgets.length > 1;

View File

@ -18,7 +18,7 @@ import {
} from "actions/widgetSelectionActions"; } from "actions/widgetSelectionActions";
import { setGlobalSearchCategory } from "actions/globalSearchActions"; import { setGlobalSearchCategory } from "actions/globalSearchActions";
import { isMacOrIOS } from "utils/helpers"; import { isMacOrIOS } from "utils/helpers";
import { getSelectedWidget, getSelectedWidgets } from "selectors/ui"; import { getLastSelectedWidget, getSelectedWidgets } from "selectors/ui";
import { MAIN_CONTAINER_WIDGET_ID } from "constants/WidgetConstants"; import { MAIN_CONTAINER_WIDGET_ID } from "constants/WidgetConstants";
import { getSelectedText } from "utils/helpers"; import { getSelectedText } from "utils/helpers";
import AnalyticsUtil from "utils/AnalyticsUtil"; import AnalyticsUtil from "utils/AnalyticsUtil";
@ -383,7 +383,7 @@ class GlobalHotKeys extends React.Component<Props> {
} }
const mapStateToProps = (state: AppState) => ({ const mapStateToProps = (state: AppState) => ({
selectedWidget: getSelectedWidget(state), selectedWidget: getLastSelectedWidget(state),
selectedWidgets: getSelectedWidgets(state), selectedWidgets: getSelectedWidgets(state),
isDebuggerOpen: state.ui.debugger.isOpen, isDebuggerOpen: state.ui.debugger.isOpen,
appMode: getAppMode(state), appMode: getAppMode(state),

View File

@ -24,7 +24,7 @@ import {
SELECT_ALL_WIDGETS_MSG, SELECT_ALL_WIDGETS_MSG,
} from "@appsmith/constants/messages"; } from "@appsmith/constants/messages";
import { Variant } from "components/ads/common"; import { Variant } from "components/ads/common";
import { getSelectedWidget, getSelectedWidgets } from "selectors/ui"; import { getLastSelectedWidget, getSelectedWidgets } from "selectors/ui";
import { import {
CanvasWidgetsReduxState, CanvasWidgetsReduxState,
FlattenedWidgetProps, FlattenedWidgetProps,
@ -105,7 +105,7 @@ function* getDroppingCanvasOfWidget(widgetLastSelected: FlattenedWidgetProps) {
} }
function* getLastSelectedCanvas() { function* getLastSelectedCanvas() {
const lastSelectedWidget: string = yield select(getSelectedWidget); const lastSelectedWidget: string = yield select(getLastSelectedWidget);
const canvasWidgets: CanvasWidgetsReduxState = yield select(getWidgets); const canvasWidgets: CanvasWidgetsReduxState = yield select(getWidgets);
const widgetLastSelected = const widgetLastSelected =
lastSelectedWidget && canvasWidgets[lastSelectedWidget]; lastSelectedWidget && canvasWidgets[lastSelectedWidget];
@ -131,7 +131,7 @@ const isChildOfDropDisabledCanvas = (
}; };
function* getAllSelectableChildren() { function* getAllSelectableChildren() {
const lastSelectedWidget: string = yield select(getSelectedWidget); const lastSelectedWidget: string = yield select(getLastSelectedWidget);
const canvasWidgets: CanvasWidgetsReduxState = yield select(getWidgets); const canvasWidgets: CanvasWidgetsReduxState = yield select(getWidgets);
const widgetLastSelected = canvasWidgets[lastSelectedWidget]; const widgetLastSelected = canvasWidgets[lastSelectedWidget];
const canvasId: string = yield call(getLastSelectedCanvas); const canvasId: string = yield call(getLastSelectedCanvas);
@ -258,7 +258,7 @@ function* shiftSelectWidgetsSaga(
try { try {
const { siblingWidgets, widgetId } = action.payload; const { siblingWidgets, widgetId } = action.payload;
const selectedWidgets: string[] = yield select(getSelectedWidgets); const selectedWidgets: string[] = yield select(getSelectedWidgets);
const lastSelectedWidget: string = yield select(getSelectedWidget); const lastSelectedWidget: string = yield select(getLastSelectedWidget);
const lastSelectedWidgetIndex = siblingWidgets.indexOf(lastSelectedWidget); const lastSelectedWidgetIndex = siblingWidgets.indexOf(lastSelectedWidget);
const isWidgetSelected = selectedWidgets.includes(widgetId); const isWidgetSelected = selectedWidgets.includes(widgetId);
if (!isWidgetSelected && lastSelectedWidgetIndex > -1) { if (!isWidgetSelected && lastSelectedWidgetIndex > -1) {

View File

@ -11,7 +11,7 @@ import {
getActions, getActions,
getCanvasWidgets, getCanvasWidgets,
} from "./entitiesSelector"; } from "./entitiesSelector";
import { getSelectedWidget } from "./ui"; import { getLastSelectedWidget } from "./ui";
import { GuidedTourEntityNames } from "pages/Editor/GuidedTour/constants"; import { GuidedTourEntityNames } from "pages/Editor/GuidedTour/constants";
// Signposting selectors // Signposting selectors
@ -126,7 +126,7 @@ export const isQueryExecutionSuccessful = createSelector(
export const isTableWidgetSelected = createSelector( export const isTableWidgetSelected = createSelector(
getTableWidget, getTableWidget,
getSelectedWidget, getLastSelectedWidget,
wasTableWidgetSelected, wasTableWidgetSelected,
(tableWidget, selectedWidgetId, tableWidgetWasSelected) => { (tableWidget, selectedWidgetId, tableWidgetWasSelected) => {
if (!tableWidgetWasSelected) { if (!tableWidgetWasSelected) {
@ -196,7 +196,7 @@ export const nameInputSelector = createSelector(getWidgets, (widgets) => {
// Check if CountryInput is selected // Check if CountryInput is selected
export const countryInputSelector = createSelector( export const countryInputSelector = createSelector(
getWidgets, getWidgets,
getSelectedWidget, getLastSelectedWidget,
(widgets, selectedWidgetId) => { (widgets, selectedWidgetId) => {
const widgetValues = Object.values(widgets); const widgetValues = Object.values(widgets);
const countryInput = widgetValues.find((widget) => { const countryInput = widgetValues.find((widget) => {

View File

@ -8,7 +8,7 @@ import { getDataTree } from "selectors/dataTreeSelectors";
import { DataTree, DataTreeWidget } from "entities/DataTree/dataTreeFactory"; import { DataTree, DataTreeWidget } from "entities/DataTree/dataTreeFactory";
import { PropertyPaneReduxState } from "reducers/uiReducers/propertyPaneReducer"; import { PropertyPaneReduxState } from "reducers/uiReducers/propertyPaneReducer";
import { CanvasWidgetsReduxState } from "reducers/entityReducers/canvasWidgetsReducer"; import { CanvasWidgetsReduxState } from "reducers/entityReducers/canvasWidgetsReducer";
import { getSelectedWidget, getSelectedWidgets } from "./ui"; import { getLastSelectedWidget, getSelectedWidgets } from "./ui";
import { EVALUATION_PATH } from "utils/DynamicBindingUtils"; import { EVALUATION_PATH } from "utils/DynamicBindingUtils";
import { DataTreeEntity } from "entities/DataTree/dataTreeFactory"; import { DataTreeEntity } from "entities/DataTree/dataTreeFactory";
import { generateClassName } from "utils/generators"; import { generateClassName } from "utils/generators";
@ -201,7 +201,7 @@ const isResizingorDragging = (state: AppState) =>
export const getIsPropertyPaneVisible = createSelector( export const getIsPropertyPaneVisible = createSelector(
getPropertyPaneState, getPropertyPaneState,
isResizingorDragging, isResizingorDragging,
getSelectedWidget, getLastSelectedWidget,
getSelectedWidgets, getSelectedWidgets,
( (
pane: PropertyPaneReduxState, pane: PropertyPaneReduxState,

View File

@ -2,7 +2,7 @@ import { AppState } from "@appsmith/reducers";
import { createSelector } from "reselect"; import { createSelector } from "reselect";
import { TableFilterPaneReduxState } from "reducers/uiReducers/tableFilterPaneReducer"; import { TableFilterPaneReduxState } from "reducers/uiReducers/tableFilterPaneReducer";
import { getSelectedWidget, getSelectedWidgets } from "./ui"; import { getLastSelectedWidget, getSelectedWidgets } from "./ui";
export const getTableFilterState = ( export const getTableFilterState = (
state: AppState, state: AppState,
@ -14,7 +14,7 @@ const isResizingorDragging = (state: AppState) =>
export const getIsTableFilterPaneVisible = createSelector( export const getIsTableFilterPaneVisible = createSelector(
getTableFilterState, getTableFilterState,
isResizingorDragging, isResizingorDragging,
getSelectedWidget, getLastSelectedWidget,
getSelectedWidgets, getSelectedWidgets,
( (
pane: TableFilterPaneReduxState, pane: TableFilterPaneReduxState,

View File

@ -1,6 +1,6 @@
import { AppState } from "@appsmith/reducers"; import { AppState } from "@appsmith/reducers";
export const getSelectedWidget = (state: AppState) => export const getLastSelectedWidget = (state: AppState) =>
state.ui.widgetDragResize.lastSelectedWidget; state.ui.widgetDragResize.lastSelectedWidget;
export const getSelectedWidgets = (state: AppState) => export const getSelectedWidgets = (state: AppState) =>

View File

@ -8,7 +8,11 @@ import { getExistingWidgetNames } from "sagas/selectors";
import { getNextEntityName } from "utils/AppsmithUtils"; import { getNextEntityName } from "utils/AppsmithUtils";
import WidgetFactory from "utils/WidgetFactory"; import WidgetFactory from "utils/WidgetFactory";
import { getFocusedWidget, getSelectedWidget, getSelectedWidgets } from "./ui"; import {
getFocusedWidget,
getLastSelectedWidget,
getSelectedWidgets,
} from "./ui";
import { MAIN_CONTAINER_WIDGET_ID } from "constants/WidgetConstants"; import { MAIN_CONTAINER_WIDGET_ID } from "constants/WidgetConstants";
import { get } from "lodash"; import { get } from "lodash";
import { getAppMode } from "selectors/applicationSelectors"; import { getAppMode } from "selectors/applicationSelectors";
@ -96,7 +100,7 @@ export const isCurrentWidgetFocused = (widgetId: string) => {
// Check if current widget is the last selected widget // Check if current widget is the last selected widget
export const isCurrentWidgetLastSelected = (widgetId: string) => { export const isCurrentWidgetLastSelected = (widgetId: string) => {
return createSelector( return createSelector(
getSelectedWidget, getLastSelectedWidget,
(widget): boolean => widget === widgetId, (widget): boolean => widget === widgetId,
); );
}; };