## Description QA branch for mobile responsiveness --------- Co-authored-by: Aswath K <aswath@appsmith.com> Co-authored-by: Arsalan Yaldram <arsalanyaldram0211@outlook.com> Co-authored-by: Aswath K <aswath.sana@gmail.com> Co-authored-by: Ashok Kumar M <35134347+marks0351@users.noreply.github.com> Co-authored-by: rahulramesha <rahul@appsmith.com>
546 lines
11 KiB
TypeScript
546 lines
11 KiB
TypeScript
import type { WidgetType } from "constants/WidgetConstants";
|
|
import type {
|
|
EvaluationReduxAction,
|
|
ReduxAction,
|
|
UpdateCanvasPayload,
|
|
AnyReduxAction,
|
|
} from "@appsmith/constants/ReduxActionConstants";
|
|
import {
|
|
ReduxActionTypes,
|
|
ReduxActionErrorTypes,
|
|
WidgetReduxActionTypes,
|
|
ReplayReduxActionTypes,
|
|
} from "@appsmith/constants/ReduxActionConstants";
|
|
import type { DynamicPath } from "utils/DynamicBindingUtils";
|
|
import AnalyticsUtil from "utils/AnalyticsUtil";
|
|
import type { WidgetOperation } from "widgets/BaseWidget";
|
|
import type {
|
|
FetchPageRequest,
|
|
PageLayout,
|
|
SavePageResponse,
|
|
UpdatePageRequest,
|
|
UpdatePageResponse,
|
|
} from "api/PageApi";
|
|
import type { UrlDataState } from "reducers/entityReducers/appReducer";
|
|
import type { APP_MODE } from "entities/App";
|
|
import type { CanvasWidgetsReduxState } from "reducers/entityReducers/canvasWidgetsReducer";
|
|
import type { GenerateTemplatePageRequest } from "api/PageApi";
|
|
import type { ENTITY_TYPE } from "entities/AppsmithConsole";
|
|
import type { Replayable } from "entities/Replay/ReplayEntity/ReplayEditor";
|
|
import * as Sentry from "@sentry/react";
|
|
|
|
export interface FetchPageListPayload {
|
|
applicationId: string;
|
|
mode: APP_MODE;
|
|
}
|
|
|
|
export interface ClonePageActionPayload {
|
|
id: string;
|
|
blockNavigation?: boolean;
|
|
}
|
|
|
|
export interface CreatePageActionPayload {
|
|
applicationId: string;
|
|
name: string;
|
|
layouts: Partial<PageLayout>[];
|
|
blockNavigation?: boolean;
|
|
}
|
|
|
|
export type updateLayoutOptions = {
|
|
isRetry?: boolean;
|
|
shouldReplay?: boolean;
|
|
updatedWidgetIds?: string[];
|
|
};
|
|
|
|
export const fetchPage = (
|
|
pageId: string,
|
|
isFirstLoad = false,
|
|
): ReduxAction<FetchPageRequest> => {
|
|
return {
|
|
type: ReduxActionTypes.FETCH_PAGE_INIT,
|
|
payload: {
|
|
id: pageId,
|
|
isFirstLoad,
|
|
},
|
|
};
|
|
};
|
|
|
|
export const fetchPublishedPage = (
|
|
pageId: string,
|
|
bustCache = false,
|
|
firstLoad = false,
|
|
) => ({
|
|
type: ReduxActionTypes.FETCH_PUBLISHED_PAGE_INIT,
|
|
payload: {
|
|
pageId,
|
|
bustCache,
|
|
firstLoad,
|
|
},
|
|
});
|
|
|
|
export const fetchPageSuccess = (): EvaluationReduxAction<undefined> => {
|
|
return {
|
|
type: ReduxActionTypes.FETCH_PAGE_SUCCESS,
|
|
payload: undefined,
|
|
};
|
|
};
|
|
|
|
export const fetchPublishedPageSuccess =
|
|
(): EvaluationReduxAction<undefined> => ({
|
|
type: ReduxActionTypes.FETCH_PUBLISHED_PAGE_SUCCESS,
|
|
payload: undefined,
|
|
});
|
|
|
|
/**
|
|
* After all page entities are fetched like DSL, actions and JsObjects,
|
|
* we trigger evaluation using this redux action, here we supply postEvalActions
|
|
* to trigger action after evaluation has been completed like executeOnPageLoadAction
|
|
*
|
|
* @param {Array<AnyReduxAction>} postEvalActions
|
|
*/
|
|
export const fetchAllPageEntityCompletion = (
|
|
postEvalActions: Array<AnyReduxAction>,
|
|
) => ({
|
|
type: ReduxActionTypes.FETCH_ALL_PAGE_ENTITY_COMPLETION,
|
|
postEvalActions,
|
|
payload: undefined,
|
|
});
|
|
|
|
export const updateCurrentPage = (
|
|
id: string,
|
|
slug?: string,
|
|
permissions?: string[],
|
|
) => ({
|
|
type: ReduxActionTypes.SWITCH_CURRENT_PAGE_ID,
|
|
payload: { id, slug, permissions },
|
|
});
|
|
|
|
export const initCanvasLayout = (
|
|
payload: UpdateCanvasPayload,
|
|
): ReduxAction<UpdateCanvasPayload> => {
|
|
return {
|
|
type: ReduxActionTypes.INIT_CANVAS_LAYOUT,
|
|
payload,
|
|
};
|
|
};
|
|
|
|
export const setLastUpdatedTime = (payload: number): ReduxAction<number> => ({
|
|
type: ReduxActionTypes.SET_LAST_UPDATED_TIME,
|
|
payload,
|
|
});
|
|
|
|
export const savePageSuccess = (payload: SavePageResponse) => {
|
|
return {
|
|
type: ReduxActionTypes.SAVE_PAGE_SUCCESS,
|
|
payload,
|
|
};
|
|
};
|
|
|
|
export const updateWidgetNameSuccess = () => {
|
|
return {
|
|
type: ReduxActionTypes.UPDATE_WIDGET_NAME_SUCCESS,
|
|
};
|
|
};
|
|
|
|
export const deletePageSuccess = () => {
|
|
return {
|
|
type: ReduxActionTypes.DELETE_PAGE_SUCCESS,
|
|
};
|
|
};
|
|
|
|
export const updateAndSaveLayout = (
|
|
widgets: CanvasWidgetsReduxState,
|
|
options: updateLayoutOptions = {},
|
|
) => {
|
|
const { isRetry, shouldReplay, updatedWidgetIds } = options;
|
|
return {
|
|
type: ReduxActionTypes.UPDATE_LAYOUT,
|
|
payload: { widgets, isRetry, shouldReplay, updatedWidgetIds },
|
|
};
|
|
};
|
|
|
|
export const saveLayout = (isRetry?: boolean) => {
|
|
return {
|
|
type: ReduxActionTypes.SAVE_PAGE_INIT,
|
|
payload: { isRetry },
|
|
};
|
|
};
|
|
|
|
export const createPage = (
|
|
applicationId: string,
|
|
pageName: string,
|
|
layouts: Partial<PageLayout>[],
|
|
blockNavigation?: boolean,
|
|
) => {
|
|
AnalyticsUtil.logEvent("CREATE_PAGE", {
|
|
pageName,
|
|
});
|
|
return {
|
|
type: ReduxActionTypes.CREATE_PAGE_INIT,
|
|
payload: {
|
|
applicationId,
|
|
name: pageName,
|
|
layouts,
|
|
blockNavigation,
|
|
},
|
|
};
|
|
};
|
|
|
|
export const createNewPageFromEntities = (
|
|
applicationId: string,
|
|
pageName: string,
|
|
blockNavigation?: boolean,
|
|
) => {
|
|
AnalyticsUtil.logEvent("CREATE_PAGE", {
|
|
pageName,
|
|
});
|
|
return {
|
|
type: ReduxActionTypes.CREATE_NEW_PAGE_FROM_ENTITIES,
|
|
payload: {
|
|
applicationId,
|
|
name: pageName,
|
|
blockNavigation,
|
|
},
|
|
};
|
|
};
|
|
|
|
/**
|
|
* action to clone page
|
|
*
|
|
* @param pageId
|
|
* @param blockNavigation
|
|
* @returns
|
|
*/
|
|
export const clonePageInit = (pageId: string, blockNavigation?: boolean) => {
|
|
return {
|
|
type: ReduxActionTypes.CLONE_PAGE_INIT,
|
|
payload: {
|
|
id: pageId,
|
|
blockNavigation,
|
|
},
|
|
};
|
|
};
|
|
|
|
export const clonePageSuccess = (
|
|
pageId: string,
|
|
pageName: string,
|
|
layoutId: string,
|
|
pageSlug: string,
|
|
) => {
|
|
return {
|
|
type: ReduxActionTypes.CLONE_PAGE_SUCCESS,
|
|
payload: {
|
|
pageId,
|
|
pageName,
|
|
layoutId,
|
|
pageSlug,
|
|
},
|
|
};
|
|
};
|
|
|
|
export const updatePage = (payload: UpdatePageRequest) => {
|
|
// Update page *needs* id to be there. We found certain scenarios
|
|
// where this was not happening and capturing the error to know gather
|
|
// more info: https://github.com/appsmithorg/appsmith/issues/16435
|
|
if (!payload.id) {
|
|
Sentry.captureException(
|
|
new Error("Attempting to update page without page id"),
|
|
);
|
|
}
|
|
return {
|
|
type: ReduxActionTypes.UPDATE_PAGE_INIT,
|
|
payload,
|
|
};
|
|
};
|
|
|
|
export const updatePageSuccess = (payload: UpdatePageResponse) => {
|
|
return {
|
|
type: ReduxActionTypes.UPDATE_PAGE_SUCCESS,
|
|
payload,
|
|
};
|
|
};
|
|
|
|
export const updatePageError = (payload: UpdatePageErrorPayload) => {
|
|
return {
|
|
type: ReduxActionErrorTypes.UPDATE_PAGE_ERROR,
|
|
payload,
|
|
};
|
|
};
|
|
|
|
export type UpdatePageErrorPayload = {
|
|
request: UpdatePageRequest;
|
|
error: unknown;
|
|
};
|
|
|
|
export type WidgetAddChild = {
|
|
widgetId: string;
|
|
widgetName?: string;
|
|
type: WidgetType;
|
|
leftColumn: number;
|
|
topRow: number;
|
|
columns: number;
|
|
rows: number;
|
|
parentRowSpace: number;
|
|
parentColumnSpace: number;
|
|
newWidgetId: string;
|
|
tabId: string;
|
|
props?: Record<string, any>;
|
|
dynamicBindingPathList?: DynamicPath[];
|
|
};
|
|
|
|
export type WidgetRemoveChild = {
|
|
widgetId: string;
|
|
childWidgetId: string;
|
|
};
|
|
|
|
export type WidgetDelete = {
|
|
widgetId?: string;
|
|
parentId?: string;
|
|
disallowUndo?: boolean;
|
|
isShortcut?: boolean;
|
|
};
|
|
|
|
export type MultipleWidgetDeletePayload = {
|
|
widgetIds: string[];
|
|
disallowUndo?: boolean;
|
|
isShortcut?: boolean;
|
|
};
|
|
|
|
export type WidgetResize = {
|
|
widgetId: string;
|
|
parentId: string;
|
|
leftColumn?: number;
|
|
rightColumn?: number;
|
|
topRow?: number;
|
|
bottomRow?: number;
|
|
mobileLeftColumn?: number;
|
|
mobileRightColumn?: number;
|
|
mobileTopRow?: number;
|
|
mobileBottomRow?: number;
|
|
snapColumnSpace: number;
|
|
snapRowSpace: number;
|
|
};
|
|
|
|
export type ModalWidgetResize = {
|
|
height: number;
|
|
width: number;
|
|
widgetId: string;
|
|
canvasWidgetId: string;
|
|
};
|
|
|
|
export type WidgetAddChildren = {
|
|
widgetId: string;
|
|
children: Array<{
|
|
type: WidgetType;
|
|
widgetId: string;
|
|
parentId: string;
|
|
parentRowSpace: number;
|
|
parentColumnSpace: number;
|
|
leftColumn: number;
|
|
rightColumn: number;
|
|
topRow: number;
|
|
bottomRow: number;
|
|
isLoading: boolean;
|
|
}>;
|
|
};
|
|
|
|
export type WidgetUpdateProperty = {
|
|
widgetId: string;
|
|
propertyPath: string;
|
|
propertyValue: any;
|
|
};
|
|
|
|
export const updateWidget = (
|
|
operation: WidgetOperation,
|
|
widgetId: string,
|
|
payload: any,
|
|
): ReduxAction<
|
|
| WidgetAddChild
|
|
| WidgetResize
|
|
| WidgetDelete
|
|
| WidgetAddChildren
|
|
| WidgetUpdateProperty
|
|
> => {
|
|
return {
|
|
type: WidgetReduxActionTypes["WIDGET_" + operation],
|
|
payload: { widgetId, ...payload },
|
|
};
|
|
};
|
|
|
|
export const setUrlData = (
|
|
payload: UrlDataState,
|
|
): ReduxAction<UrlDataState> => {
|
|
return {
|
|
type: ReduxActionTypes.SET_URL_DATA,
|
|
payload,
|
|
};
|
|
};
|
|
|
|
export const setAppMode = (payload: APP_MODE): ReduxAction<APP_MODE> => {
|
|
return {
|
|
type: ReduxActionTypes.SET_APP_MODE,
|
|
payload,
|
|
};
|
|
};
|
|
|
|
export const updateAppStore = (
|
|
payload: Record<string, unknown>,
|
|
): EvaluationReduxAction<Record<string, unknown>> => {
|
|
return {
|
|
type: ReduxActionTypes.UPDATE_APP_STORE,
|
|
payload,
|
|
};
|
|
};
|
|
|
|
export interface ReduxActionWithExtraParams<T> extends ReduxAction<T> {
|
|
extraParams: Record<any, any>;
|
|
}
|
|
|
|
export type GenerateCRUDSuccess = {
|
|
page: {
|
|
layouts: Array<any>;
|
|
id: string;
|
|
name: string;
|
|
isDefault?: boolean;
|
|
slug: string;
|
|
description?: string;
|
|
};
|
|
isNewPage: boolean;
|
|
};
|
|
|
|
export const generateTemplateSuccess = (payload: GenerateCRUDSuccess) => {
|
|
return {
|
|
type: ReduxActionTypes.GENERATE_TEMPLATE_PAGE_SUCCESS,
|
|
payload,
|
|
};
|
|
};
|
|
|
|
export const generateTemplateError = () => {
|
|
return {
|
|
type: ReduxActionErrorTypes.GENERATE_TEMPLATE_PAGE_ERROR,
|
|
};
|
|
};
|
|
|
|
export const generateTemplateToUpdatePage = ({
|
|
applicationId,
|
|
columns,
|
|
datasourceId,
|
|
mode,
|
|
pageId,
|
|
pluginSpecificParams,
|
|
searchColumn,
|
|
tableName,
|
|
}: GenerateTemplatePageRequest): ReduxActionWithExtraParams<GenerateTemplatePageRequest> => {
|
|
return {
|
|
type: ReduxActionTypes.GENERATE_TEMPLATE_PAGE_INIT,
|
|
payload: {
|
|
pageId,
|
|
tableName,
|
|
datasourceId,
|
|
applicationId,
|
|
columns,
|
|
searchColumn,
|
|
pluginSpecificParams,
|
|
},
|
|
extraParams: {
|
|
mode,
|
|
},
|
|
};
|
|
};
|
|
|
|
export function updateReplayEntity(
|
|
entityId: string,
|
|
entity: Replayable,
|
|
entityType: ENTITY_TYPE,
|
|
) {
|
|
return {
|
|
type: ReduxActionTypes.UPDATE_REPLAY_ENTITY,
|
|
payload: { entityId, entity, entityType },
|
|
};
|
|
}
|
|
|
|
export function undoAction() {
|
|
return {
|
|
type: ReduxActionTypes.UNDO_REDO_OPERATION,
|
|
payload: {
|
|
operation: ReplayReduxActionTypes.UNDO,
|
|
},
|
|
};
|
|
}
|
|
|
|
export function redoAction() {
|
|
return {
|
|
type: ReduxActionTypes.UNDO_REDO_OPERATION,
|
|
payload: {
|
|
operation: ReplayReduxActionTypes.REDO,
|
|
},
|
|
};
|
|
}
|
|
|
|
/**
|
|
* action for delete page
|
|
*
|
|
* @param pageId
|
|
* @param pageName
|
|
* @returns
|
|
*/
|
|
export const deletePage = (pageId: string) => {
|
|
return {
|
|
type: ReduxActionTypes.DELETE_PAGE_INIT,
|
|
payload: {
|
|
id: pageId,
|
|
},
|
|
};
|
|
};
|
|
|
|
/**
|
|
* action for set page as default
|
|
*
|
|
* @param pageId
|
|
* @param applicationId
|
|
* @returns
|
|
*/
|
|
export const setPageAsDefault = (pageId: string, applicationId?: string) => {
|
|
return {
|
|
type: ReduxActionTypes.SET_DEFAULT_APPLICATION_PAGE_INIT,
|
|
payload: {
|
|
id: pageId,
|
|
applicationId,
|
|
},
|
|
};
|
|
};
|
|
|
|
/**
|
|
* action for updating order of a page
|
|
*
|
|
* @param pageId
|
|
* @param applicationId
|
|
* @returns
|
|
*/
|
|
export const setPageOrder = (
|
|
applicationId: string,
|
|
pageId: string,
|
|
order: number,
|
|
) => {
|
|
return {
|
|
type: ReduxActionTypes.SET_PAGE_ORDER_INIT,
|
|
payload: {
|
|
pageId: pageId,
|
|
order: order,
|
|
applicationId,
|
|
},
|
|
};
|
|
};
|
|
|
|
export const resetPageList = () => ({
|
|
type: ReduxActionTypes.RESET_PAGE_LIST,
|
|
});
|
|
|
|
export const resetApplicationWidgets = () => ({
|
|
type: ReduxActionTypes.RESET_APPLICATION_WIDGET_STATE_REQUEST,
|
|
});
|
|
|
|
export const fetchPageDSLs = () => ({
|
|
type: ReduxActionTypes.POPULATE_PAGEDSLS_INIT,
|
|
});
|