chore: Refactor widget rename saga to extend for packages (#40243)
## Description This PR implements a flexible extension system for widget name updates by: - Creating a singleton WidgetNameUpdateExtension class for pluggable widget renaming handlers - Adding default implementation with handleWidgetNameUpdateDefault function - Refactoring UpdateWidgetNameRequest interface to support optional fields (pageId, moduleId, contextType) - Extracting widget name update logic to dedicated functions for better maintainability - Adding packageMiddleware to the Redux store configuration These changes enable customized widget naming behavior in different contexts without modifying core code, improving extensibility while maintaining backward compatibility. PR for https://github.com/appsmithorg/appsmith-ee/pull/7122 ## 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/14463310871> > Commit: 4b4433fa68479ada6426ee39d353abc3973a2864 > <a href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=14463310871&attempt=2" target="_blank">Cypress dashboard</a>. > Tags: `@tag.All` > Spec: > <hr>Tue, 15 Apr 2025 15:51:36 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 - **Refactor** - Modularized the widget name update process, allowing for extension or override of update behavior. - Improved the structure of widget name update logic for better maintainability. - **Chores** - Updated internal interfaces to support additional parameters and optional properties. - Added a new middleware to the Redux store setup. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
parent
c8a132f88d
commit
b5d22b8ba0
|
|
@ -135,10 +135,12 @@ export interface ClonePageRequest {
|
|||
}
|
||||
|
||||
export interface UpdateWidgetNameRequest {
|
||||
pageId: string;
|
||||
pageId?: string;
|
||||
layoutId: string;
|
||||
newName: string;
|
||||
oldName: string;
|
||||
moduleId?: string;
|
||||
contextType?: "MODULE" | "PAGE";
|
||||
}
|
||||
|
||||
export interface GenerateTemplatePageRequest {
|
||||
|
|
|
|||
|
|
@ -153,6 +153,11 @@ import {
|
|||
} from "selectors/gitModSelectors";
|
||||
import captureException from "instrumentation/sendFaroErrors";
|
||||
|
||||
export interface HandleWidgetNameUpdatePayload {
|
||||
newName: string;
|
||||
widgetName: string;
|
||||
}
|
||||
|
||||
export const checkIfMigrationIsNeeded = (
|
||||
fetchPageResponse?: FetchPageResponse,
|
||||
) => {
|
||||
|
|
@ -954,6 +959,96 @@ export function* clonePageSaga(
|
|||
}
|
||||
}
|
||||
|
||||
export class WidgetNameUpdateExtension {
|
||||
// Singleton instance
|
||||
private static instance = new WidgetNameUpdateExtension();
|
||||
|
||||
// The extension function storage
|
||||
private extensionFunction:
|
||||
| ((params: HandleWidgetNameUpdatePayload) => Generator)
|
||||
| null = null;
|
||||
|
||||
// Private constructor
|
||||
private constructor() {}
|
||||
|
||||
// Get the instance
|
||||
static getInstance() {
|
||||
return this.instance;
|
||||
}
|
||||
|
||||
// Set the extension function
|
||||
setExtension(fn: (params: HandleWidgetNameUpdatePayload) => Generator) {
|
||||
this.extensionFunction = fn;
|
||||
}
|
||||
|
||||
// Get the extension function
|
||||
getExtension() {
|
||||
return this.extensionFunction;
|
||||
}
|
||||
}
|
||||
|
||||
export function* updateWidgetNameAPISaga(
|
||||
requestParams: UpdateWidgetNameRequest,
|
||||
) {
|
||||
const response: UpdateWidgetNameResponse = yield call(
|
||||
PageApi.updateWidgetName,
|
||||
requestParams,
|
||||
);
|
||||
|
||||
const isValidResponse: boolean = yield validateResponse(response);
|
||||
|
||||
return { response, isValidResponse };
|
||||
}
|
||||
|
||||
export function* handleWidgetNameUpdateDefault(
|
||||
params: HandleWidgetNameUpdatePayload,
|
||||
) {
|
||||
const { newName, widgetName } = params;
|
||||
|
||||
const layoutId: string | undefined = yield select(getCurrentLayoutId);
|
||||
const pageId: string | undefined = yield select(getCurrentPageId);
|
||||
|
||||
const request: UpdateWidgetNameRequest = {
|
||||
newName: newName,
|
||||
oldName: widgetName,
|
||||
pageId,
|
||||
// @ts-expect-error: layoutId can be undefined
|
||||
layoutId,
|
||||
};
|
||||
const { isValidResponse, response } = yield call(
|
||||
updateWidgetNameAPISaga,
|
||||
request,
|
||||
);
|
||||
|
||||
if (isValidResponse) {
|
||||
// @ts-expect-error: pageId can be undefined
|
||||
yield updateCanvasWithDSL(response.data, pageId, layoutId);
|
||||
yield put(updateWidgetNameSuccess());
|
||||
// Add this to the page DSLs for entity explorer
|
||||
yield put({
|
||||
type: ReduxActionTypes.FETCH_PAGE_DSL_SUCCESS,
|
||||
payload: {
|
||||
pageId: pageId,
|
||||
dsl: response.data.dsl,
|
||||
layoutId,
|
||||
},
|
||||
});
|
||||
checkAndLogErrorsIfCyclicDependency(
|
||||
(response.data as PageLayout).layoutOnLoadActionErrors,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export function* handleWidgetNameUpdate(params: HandleWidgetNameUpdatePayload) {
|
||||
const extension = WidgetNameUpdateExtension.getInstance().getExtension();
|
||||
|
||||
if (extension) {
|
||||
yield call(extension, params);
|
||||
} else {
|
||||
yield call(handleWidgetNameUpdateDefault, params);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* this saga do two things
|
||||
*
|
||||
|
|
@ -967,8 +1062,6 @@ export function* updateWidgetNameSaga(
|
|||
) {
|
||||
try {
|
||||
const { widgetName } = yield select(getWidgetName, action.payload.id);
|
||||
const layoutId: string | undefined = yield select(getCurrentLayoutId);
|
||||
const pageId: string | undefined = yield select(getCurrentPageId);
|
||||
const getUsedNames: Record<string, true> = yield select(
|
||||
getUsedActionNames,
|
||||
"",
|
||||
|
|
@ -1058,37 +1151,10 @@ export function* updateWidgetNameSaga(
|
|||
// check if name is not conflicting with any
|
||||
// existing entity/api/queries/reserved words
|
||||
if (isNameValid(action.payload.newName, getUsedNames)) {
|
||||
const request: UpdateWidgetNameRequest = {
|
||||
yield call(handleWidgetNameUpdate, {
|
||||
newName: action.payload.newName,
|
||||
oldName: widgetName,
|
||||
// @ts-expect-error: pageId can be undefined
|
||||
pageId,
|
||||
// @ts-expect-error: layoutId can be undefined
|
||||
layoutId,
|
||||
};
|
||||
const response: UpdateWidgetNameResponse = yield call(
|
||||
PageApi.updateWidgetName,
|
||||
request,
|
||||
);
|
||||
const isValidResponse: boolean = yield validateResponse(response);
|
||||
|
||||
if (isValidResponse) {
|
||||
// @ts-expect-error: pageId can be undefined
|
||||
yield updateCanvasWithDSL(response.data, pageId, layoutId);
|
||||
yield put(updateWidgetNameSuccess());
|
||||
// Add this to the page DSLs for entity explorer
|
||||
yield put({
|
||||
type: ReduxActionTypes.FETCH_PAGE_DSL_SUCCESS,
|
||||
payload: {
|
||||
pageId: pageId,
|
||||
dsl: response.data.dsl,
|
||||
layoutId,
|
||||
},
|
||||
});
|
||||
checkAndLogErrorsIfCyclicDependency(
|
||||
(response.data as PageLayout).layoutOnLoadActionErrors,
|
||||
);
|
||||
}
|
||||
widgetName,
|
||||
});
|
||||
} else {
|
||||
yield put({
|
||||
type: ReduxActionErrorTypes.UPDATE_WIDGET_NAME_ERROR,
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import { composeWithDevTools } from "redux-devtools-extension/logOnlyInProductio
|
|||
import * as Sentry from "@sentry/react";
|
||||
import { ReduxActionTypes } from "ee/constants/ReduxActionConstants";
|
||||
import routeParamsMiddleware from "ee/middlewares/RouteParamsMiddleware";
|
||||
import packageMiddleware from "ee/middlewares/PackageMiddleware";
|
||||
|
||||
const sagaMiddleware = createSagaMiddleware();
|
||||
const ignoredSentryActionTypes = [
|
||||
|
|
@ -30,7 +31,7 @@ export default createStore(
|
|||
appReducer,
|
||||
composeWithDevTools(
|
||||
reduxBatch,
|
||||
applyMiddleware(sagaMiddleware, routeParamsMiddleware),
|
||||
applyMiddleware(packageMiddleware, sagaMiddleware, routeParamsMiddleware),
|
||||
reduxBatch,
|
||||
sentryReduxEnhancer,
|
||||
),
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user