fix: Reverting Anvil currently open modal state implementation (#33067)

[![workerB](https://img.shields.io/endpoint?url=https%3A%2F%2Fworkerb.linearb.io%2Fv2%2Fbadge%2Fprivate%2FU2FsdGVkX1p4H4db8lSv1xTwGoYFAZnRwWdBNC5Y%2Fcollaboration.svg%3FcacheSeconds%3D60)](https://workerb.linearb.io/v2/badge/collaboration-page?magicLinkId=MA2NqRe)
## Description
> [!TIP]  
> _Add a TL;DR when the description is longer than 500 words or
extremely technical (helps the content, marketing, and DevRel team)._
>
> _Please also include relevant motivation and context. List any
dependencies that are required for this change. Add links to Notion,
Figma or any other documents that might be relevant to the PR._

In #33040 we added a state exclusively to capture modals that are
opened/closed to avoid computing which modal is open based on meta
state.
However the problem with this approach that I had understood after
testing it with deployed apps is that closing a modal is not done only
via the saga, but is done via actions and the modal itself without
dispatching the common saga.
Obviously the above implementation dunked.

Reverting to the previous implementation of relying on meta state to
select visible detached widgets.


Fixes #`Issue Number`  
_or_  
Fixes `Issue URL`
> [!WARNING]  
> _If no issue exists, please create an issue first, and check with the
maintainers if the issue is valid._

## Automation

/ok-to-test tags="@tag.Anvil"

### 🔍 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/8895170744>
> Commit: 517ffc6ac5302bae6940b17b76774a963a18f773
> Cypress dashboard url: <a
href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=8895170744&attempt=1"
target="_blank">Click here!</a>

<!-- end of auto-generated comment: Cypress test results  -->




## Communication
Should the DevRel and Marketing teams inform users about this change?
- [ ] Yes
- [ ] No
This commit is contained in:
Ashok Kumar M 2024-04-30 19:27:18 +05:30 committed by GitHub
parent 225fa5da29
commit 3f222e5002
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 28 additions and 125 deletions

View File

@ -81,7 +81,6 @@ import type { ActiveField } from "reducers/uiReducers/activeFieldEditorReducer";
import type { SelectedWorkspaceReduxState } from "@appsmith/reducers/uiReducers/selectedWorkspaceReducer";
import type { ConsolidatedPageLoadState } from "reducers/uiReducers/consolidatedPageLoadReducer";
import type { BuildingBlocksReduxState } from "reducers/uiReducers/buildingBlockReducer";
import type { AnvilDetachedWidgetsReduxState } from "layoutSystems/anvil/integrations/reducers/anvilDetachedWidgetsReducer";
export const reducerObject = {
entities: entityReducer,
@ -147,7 +146,6 @@ export interface AppState {
oneClickBinding: OneClickBindingState;
activeField: ActiveField;
ide: IDEState;
anvilDetachedWidgets: AnvilDetachedWidgetsReduxState;
};
entities: {
canvasWidgetsStructure: CanvasWidgetStructure;

View File

@ -50,7 +50,6 @@ import activeFieldReducer from "reducers/uiReducers/activeFieldEditorReducer";
import selectedWorkspaceReducer from "@appsmith/reducers/uiReducers/selectedWorkspaceReducer";
import ideReducer from "../../../reducers/uiReducers/ideReducer";
import consolidatedPageLoadReducer from "reducers/uiReducers/consolidatedPageLoadReducer";
import anvilDetachedWidgetsReducer from "layoutSystems/anvil/integrations/reducers/anvilDetachedWidgetsReducer";
export const uiReducerObject = {
analytics: analyticsReducer,
@ -105,5 +104,4 @@ export const uiReducerObject = {
activeField: activeFieldReducer,
ide: ideReducer,
consolidatedPageLoad: consolidatedPageLoadReducer,
anvilDetachedWidgets: anvilDetachedWidgetsReducer,
};

View File

@ -1,4 +1,5 @@
.detachedWidgetsDropOverlay {
z-index: var(--z-index-99);
background-color: var(--modal-overlay-color);
position: fixed;
padding: 40px;

View File

@ -40,7 +40,4 @@ export enum AnvilReduxActionTypes {
ANVIL_SPACE_DISTRIBUTION_STOP = "ANVIL_SPACE_DISTRIBUTION_STOP",
ANVIL_SET_HIGHLIGHT_SHOWN = "ANVIL_SET_HIGHLIGHT_SHOWN",
ANVIL_WIDGET_SELECTION_CLICK = "ANVIL_WIDGET_SELECTION_CLICK",
SHOW_DETACHED_WIDGET = "SHOW_DETACHED_WIDGET",
HIDE_DETACHED_WIDGET = "HIDE_DETACHED_WIDGET",
RESET_DETACHED_WIDGETS = "RESET_DETACHED_WIDGETS",
}

View File

@ -1,21 +0,0 @@
import { AnvilReduxActionTypes } from "./actionTypes";
export const showDetachedWidgetAction = (widgetId: string) => {
return {
type: AnvilReduxActionTypes.SHOW_DETACHED_WIDGET,
payload: widgetId,
};
};
export const hideDetachedWidgetAction = (widgetId: string) => {
return {
type: AnvilReduxActionTypes.HIDE_DETACHED_WIDGET,
payload: widgetId,
};
};
export const resetDetachedWidgetsAction = () => {
return {
type: AnvilReduxActionTypes.RESET_DETACHED_WIDGETS,
};
};

View File

@ -1,5 +1,15 @@
import type { AppState } from "@appsmith/reducers";
import { getAllDetachedWidgetIds, getWidgetsMeta } from "sagas/selectors";
export const getCurrentlyOpenAnvilDetachedWidgets = (state: AppState) => {
return state.ui.anvilDetachedWidgets.currentlyOpenDetachedWidgets;
const allExistingDetachedWidgets = getAllDetachedWidgetIds(state);
if (allExistingDetachedWidgets.length === 0) {
return [];
}
const metaWidgets = getWidgetsMeta(state);
const currentlyOpenWidgets = allExistingDetachedWidgets.filter((modalId) => {
const modal = metaWidgets[modalId];
return modal && modal.isVisible;
});
return currentlyOpenWidgets;
};

View File

@ -1,36 +0,0 @@
import { createImmerReducer } from "utils/ReducerUtils";
import {
AnvilReduxActionTypes,
type AnvilReduxAction,
} from "../actions/actionTypes";
export interface AnvilDetachedWidgetsReduxState {
currentlyOpenDetachedWidgets: string[];
}
const initialState: AnvilDetachedWidgetsReduxState = {
currentlyOpenDetachedWidgets: [],
};
const anvilDetachedWidgetsReducer = createImmerReducer(initialState, {
[AnvilReduxActionTypes.SHOW_DETACHED_WIDGET]: (
state: AnvilDetachedWidgetsReduxState,
action: AnvilReduxAction<string>,
) => {
state.currentlyOpenDetachedWidgets.push(action.payload);
},
[AnvilReduxActionTypes.HIDE_DETACHED_WIDGET]: (
state: AnvilDetachedWidgetsReduxState,
action: AnvilReduxAction<string>,
) => {
state.currentlyOpenDetachedWidgets =
state.currentlyOpenDetachedWidgets.filter(
(widgetId) => widgetId !== action.payload,
);
},
[AnvilReduxActionTypes.RESET_DETACHED_WIDGETS]: (
state: AnvilDetachedWidgetsReduxState,
) => {
state.currentlyOpenDetachedWidgets = [];
},
});
export default anvilDetachedWidgetsReducer;

View File

@ -1,46 +0,0 @@
import type { ReduxAction } from "@appsmith/constants/ReduxActionConstants";
import { ReduxActionTypes } from "@appsmith/constants/ReduxActionConstants";
import { all, put, select, takeEvery, takeLatest } from "redux-saga/effects";
import { callSagaOnlyForAnvil } from "./utils";
import {
hideDetachedWidgetAction,
resetDetachedWidgetsAction,
showDetachedWidgetAction,
} from "../actions/detachedWidgetActions";
import { getWidgetByName } from "sagas/selectors";
import type { FlattenedWidgetProps } from "WidgetProvider/constants";
function* closeAnvilModalSaga(action: ReduxAction<{ modalName?: string }>) {
const { modalName } = action.payload;
if (modalName) {
const widget: FlattenedWidgetProps | undefined = yield select(
getWidgetByName,
modalName,
);
if (widget) {
hideDetachedWidgetAction(widget.widgetId);
}
} else {
yield put(resetDetachedWidgetsAction());
}
}
function* showAnvilModalSaga(action: ReduxAction<{ modalId: string }>) {
yield put(showDetachedWidgetAction(action.payload.modalId));
}
export default function* anvilDetachedWidgetSagas() {
yield all([
takeEvery(
ReduxActionTypes.CLOSE_MODAL,
callSagaOnlyForAnvil,
closeAnvilModalSaga,
),
takeLatest(
ReduxActionTypes.SHOW_MODAL,
callSagaOnlyForAnvil,
showAnvilModalSaga,
),
]);
}

View File

@ -5,7 +5,6 @@ import anvilSectionSagas from "./sectionSagas";
import anvilSpaceDistributionSagas from "./anvilSpaceDistributionSagas";
import anvilWidgetSelectionSaga from "./anvilWidgetSelectionSaga";
import pasteSagas from "./pasteSagas";
import anvilDetachedWidgetSagas from "./anvilDetachedWidgetSagas";
export default function* anvilSagas() {
yield fork(LayoutElementPositionsSaga);
@ -14,5 +13,4 @@ export default function* anvilSagas() {
yield fork(anvilSpaceDistributionSagas);
yield fork(anvilWidgetSelectionSaga);
yield fork(pasteSagas);
yield fork(anvilDetachedWidgetSagas);
}

View File

@ -7,6 +7,7 @@ import { updateAndSaveAnvilLayout } from "../../utils/anvilChecksUtils";
import { builderURL } from "@appsmith/RouteBuilder";
import { getCurrentPageId } from "selectors/editorSelectors";
import {
type ReduxAction,
ReduxActionErrorTypes,
ReduxActionTypes,
} from "@appsmith/constants/ReduxActionConstants";
@ -23,7 +24,7 @@ import { getDestinedParent } from "layoutSystems/anvil/utils/paste/destinationUt
import { pasteWidgetsIntoMainCanvas } from "layoutSystems/anvil/utils/paste/mainCanvasPasteUtils";
import { MAIN_CONTAINER_WIDGET_ID } from "constants/WidgetConstants";
import WidgetFactory from "WidgetProvider/factory";
import { callSagaOnlyForAnvil } from "./utils";
import { getIsAnvilLayout } from "../selectors";
function* pasteWidgetSagas() {
try {
@ -121,11 +122,18 @@ function* pasteWidgetSagas() {
}
}
function* shouldCallSaga(saga: any, action: ReduxAction<unknown>) {
const isAnvilLayout: boolean = yield select(getIsAnvilLayout);
if (isAnvilLayout) {
yield call(saga, action);
}
}
export default function* pasteSagas() {
yield all([
takeLeading(
ReduxActionTypes.PASTE_COPIED_WIDGET_INIT,
callSagaOnlyForAnvil,
shouldCallSaga,
pasteWidgetSagas,
),
]);

View File

@ -1,10 +0,0 @@
import type { ReduxAction } from "@appsmith/constants/ReduxActionConstants";
import { call, select } from "redux-saga/effects";
import { getIsAnvilLayout } from "../selectors";
export function* callSagaOnlyForAnvil(saga: any, action: ReduxAction<unknown>) {
const isAnvilLayout: boolean = yield select(getIsAnvilLayout);
if (isAnvilLayout) {
yield call(saga, action);
}
}

View File

@ -77,6 +77,12 @@ export const getWidgetIdsByType = (state: AppState, type: WidgetType) => {
.map((widget: FlattenedWidgetProps) => widget.widgetId);
};
export const getAllDetachedWidgetIds = (state: AppState) => {
return Object.values(state.entities.canvasWidgets)
.filter((widget: FlattenedWidgetProps) => !!widget.detachFromLayout)
.map((widget: FlattenedWidgetProps) => widget.widgetId);
};
export const getWidgetOptionsTree = memoize((state: AppState) =>
Object.values(state.entities.canvasWidgets)
.filter((w) => w.type !== "CANVAS_WIDGET" && w.type !== "BUTTON_WIDGET")