PromucFlow_constructor/app/client/src/sagas/layoutConversionSagas.ts
Hetu Nandu 723ad29d7a
chore: Cleanup Redux Actions file (#35720)
## Description

Cleans out and reorganises the Redux Actions Constants file

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.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/10489649733>
> Commit: 9fa7003f7c2d1b43a6c693cb1d34ba5cc2c11832
> <a
href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=10489649733&attempt=2"
target="_blank">Cypress dashboard</a>.
> Tags: `@tag.All`
> Spec:
> <hr>Wed, 21 Aug 2024 13:45:56 UTC
<!-- end of auto-generated comment: Cypress test results  -->


## Communication
Should the DevRel and Marketing teams inform users about this change?
- [ ] Yes
- [ ] No


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Introduced new interfaces for enhanced structured data handling
related to page management and property pane visibility.
- Added functionality to control widget panel visibility with a new
action.

- **Bug Fixes**
- Improved flexibility in closing property panes by adding an optional
parameter to the related function.

- **Refactor**
- Streamlined import statements for various types to improve
organization and maintainability.
- Removed unused functions and action handlers to simplify user and data
source management.
	- Updated action type constants for consistency across the application.
- Removed sagas related to URL redirection and history management,
simplifying navigation handling.

- **Chores**
- Cleaned up unused imports to reduce code clutter and improve
readability.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2024-08-22 09:49:30 +05:30

264 lines
7.7 KiB
TypeScript

import { setLayoutConversionStateAction } from "actions/autoLayoutActions";
import { ReduxActionTypes } from "ee/constants/ReduxActionConstants";
import type { Page } from "entities/Page";
import type { ReduxAction } from "ee/constants/ReduxActionConstants";
import type { AppState } from "ee/reducers";
import { LayoutSystemTypes } from "layoutSystems/types";
import type { SupportedLayouts } from "reducers/entityReducers/pageListReducer";
import { CONVERSION_STATES } from "reducers/uiReducers/layoutConversionReducer";
import type { PageWidgetsReduxState } from "reducers/uiReducers/pageWidgetsReducer";
import { all, call, put, select, takeLatest } from "redux-saga/effects";
import { getPageWidgets } from "ee/selectors/entitiesSelector";
import { convertNormalizedDSLToFixed } from "layoutSystems/common/DSLConversions/autoToFixedLayout";
import convertToAutoLayout from "layoutSystems/common/DSLConversions/fixedToAutoLayout";
import type { DSLWidget } from "WidgetProvider/constants";
import {
createSnapshotSaga,
deleteApplicationSnapshotSaga,
} from "./SnapshotSagas";
import * as Sentry from "@sentry/react";
import log from "loglevel";
import { saveAllPagesSaga } from "ee/sagas/PageSagas";
import { updateApplicationLayout } from "ee/actions/applicationActions";
import {
getCurrentApplicationId,
getPageList,
} from "selectors/editorSelectors";
import { updateApplicationLayoutType } from "./AutoLayoutUpdateSagas";
import AnalyticsUtil from "ee/utils/AnalyticsUtil";
import { nestDSL } from "@shared/dsl";
/**
* This method is used to convert from auto-layout to fixed layout
* @param action
*/
function* convertFromAutoToFixedSaga(action: ReduxAction<SupportedLayouts>) {
let appId = "";
let snapshotSaveSuccess = false;
try {
const pageList: Page[] = yield select(getPageList);
const pageWidgetsList: PageWidgetsReduxState = yield select(getPageWidgets);
appId = yield select(getCurrentApplicationId);
const notEmptyApp = isNotEmptyApp(pageWidgetsList);
if (notEmptyApp) {
yield call(createSnapshotSaga);
}
AnalyticsUtil.logEvent("CONVERT_AUTO_TO_FIXED", {
isNewApp: !notEmptyApp,
appId,
});
snapshotSaveSuccess = true;
//Set conversion form to indicated conversion loading state
yield put(
setLayoutConversionStateAction(CONVERSION_STATES.CONVERSION_SPINNER),
);
const pageLayouts = [];
//Convert all the pages into fixed layout by iterating over the list
for (const page of pageList) {
const pageId = page?.pageId;
const { dsl: normalizedDSL, layoutId } = pageWidgetsList[pageId];
const fixedLayoutDSL = convertNormalizedDSLToFixed(
normalizedDSL,
action.payload,
);
const dsl = nestDSL(fixedLayoutDSL);
pageLayouts.push({
pageId,
layoutId,
layout: {
dsl,
},
});
}
yield call(saveAllPagesSaga, pageLayouts);
//Set type of fixed layout
yield call(setLayoutTypePostConversion, action.payload);
yield call(updateApplicationLayoutType, LayoutSystemTypes.FIXED);
//update conversion form state to success
yield put(
setLayoutConversionStateAction(CONVERSION_STATES.COMPLETED_SUCCESS),
);
// TODO: Fix this the next time the file is edited
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (e: any) {
let error: Error = e;
if (error) {
error.message = `Layout conversion error - while converting from auto-layout to fixed layout: ${error.message}`;
} else {
error = new Error(
"Layout conversion error - while converting from auto-layout to fixed layout",
);
}
log.error(error);
if (snapshotSaveSuccess) {
yield call(deleteApplicationSnapshotSaga);
}
//update conversion form state to error
yield put(
setLayoutConversionStateAction(CONVERSION_STATES.COMPLETED_ERROR, error),
);
AnalyticsUtil.logEvent("CONVERSION_FAILURE", {
flow: "CONVERT_AUTO_TO_FIXED",
appId,
});
}
}
/**
* This method is used to convert from fixed layout to auto-layout
* @param action
*/
function* convertFromFixedToAutoSaga() {
let appId = "";
let snapshotSaveSuccess = false;
try {
const pageList: Page[] = yield select(getPageList);
const pageWidgetsList: PageWidgetsReduxState = yield select(getPageWidgets);
appId = yield select(getCurrentApplicationId);
const notEmptyApp = isNotEmptyApp(pageWidgetsList);
if (notEmptyApp) {
yield call(createSnapshotSaga);
}
AnalyticsUtil.logEvent("CONVERT_FIXED_TO_AUTO", {
isNewApp: !notEmptyApp,
appId,
});
snapshotSaveSuccess = true;
yield put(
setLayoutConversionStateAction(CONVERSION_STATES.CONVERSION_SPINNER),
);
const pageLayouts = [];
for (const page of pageList) {
const pageId = page?.pageId;
const { dsl: normalizedDSL, layoutId } = pageWidgetsList[pageId];
const fixedDSL = nestDSL(normalizedDSL);
const dsl: DSLWidget = convertToAutoLayout(fixedDSL);
pageLayouts.push({
pageId,
layoutId,
layout: {
dsl,
},
});
}
yield call(saveAllPagesSaga, pageLayouts);
yield call(updateApplicationLayoutType, LayoutSystemTypes.AUTO);
//update conversion form state to success
yield put(
setLayoutConversionStateAction(CONVERSION_STATES.COMPLETED_SUCCESS),
);
// TODO: Fix this the next time the file is edited
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (e: any) {
let error: Error = e;
if (error) {
error.message = `Layout conversion error - while converting from fixed layout to auto-layout: ${error.message}`;
} else {
error = new Error(
"Layout conversion error - while converting from fixed layout to auto-layout",
);
}
log.error(error);
//update conversion form state to error
if (snapshotSaveSuccess) {
yield call(deleteApplicationSnapshotSaga);
}
yield put(
setLayoutConversionStateAction(CONVERSION_STATES.COMPLETED_ERROR, error),
);
AnalyticsUtil.logEvent("CONVERSION_FAILURE", {
flow: "CONVERT_FIXED_TO_AUTO",
appId,
});
}
}
//Saga to log conversion sentry error when user reports it
function* logLayoutConversionErrorSaga() {
try {
const error: Error = yield select(
(state: AppState) => state.ui.layoutConversion.conversionError,
);
yield call(Sentry.captureException, error);
} catch (e) {
throw e;
}
}
/**
* Set layout type of Application based on user selection while converting
* @param selectedLayoutType
*/
function* setLayoutTypePostConversion(selectedLayoutType: SupportedLayouts) {
let convertToLayoutType: SupportedLayouts = selectedLayoutType;
const applicationId: string = yield select(getCurrentApplicationId);
if (selectedLayoutType === "DESKTOP") {
convertToLayoutType = "FLUID";
}
yield put(
updateApplicationLayout(applicationId, {
appLayout: {
type: convertToLayoutType,
},
}),
);
}
export default function* layoutConversionSagas() {
yield all([
takeLatest(
ReduxActionTypes.CONVERT_AUTO_TO_FIXED,
convertFromAutoToFixedSaga,
),
takeLatest(
ReduxActionTypes.CONVERT_FIXED_TO_AUTO,
convertFromFixedToAutoSaga,
),
takeLatest(
ReduxActionTypes.LOG_LAYOUT_CONVERSION_ERROR,
logLayoutConversionErrorSaga,
),
]);
}
//Function returns boolean, SnapShot should not be saved for a single empty canvas
function isNotEmptyApp(pageWidgetsList: PageWidgetsReduxState) {
const pageList = Object.values(pageWidgetsList);
if (pageList.length !== 1) return true;
const { dsl: pageDSL } = pageList[0];
return Object.keys(pageDSL).length !== 1;
}