PromucFlow_constructor/app/client/src/layoutSystems/common/selectors.ts
Abhinav Jha 3d42333539
fix: Fix widget name canvas issues (#28314)
## Description
Fixes the following from #28310
- Use LayoutSystemType or LayoutSystemFeatures instead of feature flags
in
[app/client/src/pages/Editor/CanvasPropertyPane/index.tsx](e7603fd213 (diff-6ffc62fd8fff7633da84c1bbf822394ff49f1d89dc4ad073fff16e2f5e5d41fd))
- In WidgetNamesCanvas use SetDragginStateFnType or
SetDraggingStateActionPayload and remove the other from the codebase.

#### PR fixes following issue(s)
Fixes #28312
Fixes #28310

#### Type of change
- Bug fix (non-breaking change which fixes an issue)

#### How Has This Been Tested?
- [x] Manual
- [ ] JUnit
- [x] Jest
- [ ] Cypress

## Checklist:
#### Dev activity
- [ ] My code follows the style guidelines of this project
- [ ] I have performed a self-review of my own code
- [ ] I have commented my code, particularly in hard-to-understand areas
- [ ] I have made corresponding changes to the documentation
- [ ] My changes generate no new warnings
- [ ] I have added tests that prove my fix is effective or that my
feature works
- [ ] New and existing unit tests pass locally with my changes
- [ ] PR is being merged under a feature flag


#### QA activity:
- [ ] [Speedbreak
features](https://github.com/appsmithorg/TestSmith/wiki/Guidelines-for-test-plans#speedbreakers-)
have been covered
- [ ] Test plan covers all impacted features and [areas of
interest](https://github.com/appsmithorg/TestSmith/wiki/Guidelines-for-test-plans#areas-of-interest-)
- [ ] Test plan has been peer reviewed by project stakeholders and other
QA members
- [ ] Manually tested functionality on DP
- [ ] We had an implementation alignment call with stakeholders post QA
Round 2
- [ ] Cypress test cases have been added and approved by SDET/manual QA
- [ ] Added `Test Plan Approved` label after Cypress tests were reviewed
- [ ] Added `Test Plan Approved` label after JUnit tests were reviewed
2023-10-25 11:10:43 +05:30

126 lines
4.2 KiB
TypeScript

import type { AppState } from "@appsmith/reducers";
import { createSelector } from "reselect";
import { getFocusedWidget, getSelectedWidgets } from "selectors/ui";
import { getDataTree } from "selectors/dataTreeSelectors";
import { getWidgets } from "sagas/selectors";
import { getShouldShowWidgetName } from "@appsmith/selectors/entitiesSelector";
import { WidgetNameState } from "./WidgetNamesCanvas/WidgetNameConstants";
import { MAIN_CONTAINER_WIDGET_ID } from "constants/WidgetConstants";
import { EVAL_ERROR_PATH } from "utils/DynamicBindingUtils";
import get from "lodash/get";
import { getErrorCount } from "layoutSystems/common/widgetName/utils";
import type { LayoutElementPositions } from "./types";
import type { WidgetProps } from "widgets/BaseWidget";
import type { WidgetNameData } from "./WidgetNamesCanvas/WidgetNameTypes";
import type { DataTree } from "entities/DataTree/dataTreeTypes";
export const getLayoutElementPositions = (state: AppState) =>
state.entities.layoutElementPositions;
/**
* method to get the widget data required to draw widget name component on canvas
* @param widget widget whose widget name will be drawn on canvas
* @param dataTree contains evaluated widget information that is used to check of the widget has any errors
* @param positions positions of all the widgets in pixels
* @param isFocused boolean to indicate if the widget is focused
* @returns WidgetNameData object which contains information regarding the widget to draw it's widget name on canvas
*/
const getWidgetNameState = (
widget: WidgetProps,
dataTree: DataTree,
positions: LayoutElementPositions,
isFocused = false,
): WidgetNameData => {
let nameState = isFocused
? WidgetNameState.FOCUSED
: WidgetNameState.SELECTED;
const widgetName = widget.widgetName;
const widgetEntity = dataTree[widgetName];
const parentId = widget.parentId || MAIN_CONTAINER_WIDGET_ID;
if (widgetEntity) {
const errorObj = get(widgetEntity, EVAL_ERROR_PATH, {});
const errorCount = getErrorCount(errorObj);
if (errorCount > 0) {
nameState = WidgetNameState.ERROR;
}
}
const widgetNameData = {
id: widget.widgetId,
position: positions[widget.widgetId],
widgetName: widgetName,
parentId,
dragDisabled: widget.dragDisabled,
nameState,
};
return widgetNameData;
};
/**
* selector to get information regarding the selected widget to draw it's widget name on canvas
*/
export const getSelectedWidgetNameData = createSelector(
getLayoutElementPositions,
getSelectedWidgets,
getWidgets,
getDataTree,
getShouldShowWidgetName,
(
positions,
selectedWidgets,
widgets,
dataTree,
shouldShowWidgetName,
): WidgetNameData[] | undefined => {
// This way, we know that we're dragging so we'll clear the canvas, but keep existing references
// Then, we can prevent a redraw until the widget positions change
if (!shouldShowWidgetName) return [];
// This way, we know that we're supposed to clear all the widget names
// This would happen if there are no selected widgets and we need to clear the canvas
if (!selectedWidgets || selectedWidgets.length === 0) return;
const result: WidgetNameData[] = [];
for (const selectedWidgetId of selectedWidgets) {
const selectedWidget = widgets[selectedWidgetId];
if (!selectedWidget) continue;
result.push(getWidgetNameState(selectedWidget, dataTree, positions));
}
if (result.length > 0) return result;
else return;
},
);
/**
* selector to get information regarding the focused widget to draw it's widget name on canvas
*/
export const getFocusedWidgetNameData = createSelector(
getLayoutElementPositions,
getFocusedWidget,
getSelectedWidgets,
getWidgets,
getDataTree,
getShouldShowWidgetName,
(
positions,
focusedWidgetId,
selectedWidgets,
widgets,
dataTree,
shouldShowWidgetName,
): WidgetNameData | undefined => {
if (!focusedWidgetId || !widgets || !shouldShowWidgetName) return;
const focusedWidget = widgets[focusedWidgetId];
if (!focusedWidget || selectedWidgets.indexOf(focusedWidgetId) > -1) return;
return getWidgetNameState(focusedWidget, dataTree, positions, true);
},
);