fix: revert "fix: canvas resizing issues" (#35129)
## Description
This reverts commit cbe1f5821d.
## 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/10072532868>
> Commit: 9ab856d46e621ea2073decfb5eb96378a83bd2f7
> <a
href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=10072532868&attempt=2"
target="_blank">Cypress dashboard</a>.
> Tags: `@tag.All`
> Spec:
> <hr>Wed, 24 Jul 2024 09:06:01 UTC
<!-- end of auto-generated comment: Cypress test results -->
## Communication
Should the DevRel and Marketing teams inform users about this change?
- [ ] Yes
- [x] No
This commit is contained in:
parent
30a372a688
commit
ddc2304e77
|
|
@ -4,9 +4,9 @@ import { useDispatch, useSelector } from "react-redux";
|
|||
import { getCurrentApplicationLayout } from "selectors/editorSelectors";
|
||||
import { setAutoCanvasResizing } from "actions/autoLayoutActions";
|
||||
import styled from "styled-components";
|
||||
import { AUTOLAYOUT_RESIZER_WIDTH_BUFFER } from "utils/hooks/useDynamicAppLayout";
|
||||
import { importSvg } from "design-system-old";
|
||||
import { CANVAS_VIEWPORT } from "constants/componentClassNameConstants";
|
||||
import { AUTOLAYOUT_RESIZER_WIDTH_BUFFER } from "./constants";
|
||||
|
||||
const CanvasResizerIcon = importSvg(
|
||||
async () => import("assets/icons/ads/app-icons/canvas-resizer.svg"),
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
export const AUTOLAYOUT_RESIZER_WIDTH_BUFFER = 40;
|
||||
|
|
@ -1,18 +1,15 @@
|
|||
import React, { useEffect, useMemo, useRef } from "react";
|
||||
import React, { useEffect, useMemo } from "react";
|
||||
import AnalyticsUtil from "@appsmith/utils/AnalyticsUtil";
|
||||
import { useDynamicAppLayout } from "utils/hooks/useDynamicAppLayout";
|
||||
import type { CanvasWidgetStructure } from "WidgetProvider/constants";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { useSelector } from "react-redux";
|
||||
import { getAppMode } from "@appsmith/selectors/applicationSelectors";
|
||||
import { PageView, PageViewWrapper } from "./AppPage.styled";
|
||||
import { APP_MODE } from "entities/App";
|
||||
import { renderAppsmithCanvas } from "layoutSystems/CanvasFactory";
|
||||
import type { WidgetProps } from "widgets/BaseWidget";
|
||||
import { useAppViewerSidebarProperties } from "utils/hooks/useAppViewerSidebarProperties";
|
||||
import { getIsAnvilLayout } from "layoutSystems/anvil/integrations/selectors";
|
||||
import { debounce } from "lodash";
|
||||
import { updateCanvasLayoutAction } from "actions/editorActions";
|
||||
|
||||
import { PageView, PageViewWrapper } from "./AppPage.styled";
|
||||
import { RESIZE_DEBOUNCE_THRESHOLD } from "./constants";
|
||||
|
||||
interface AppPageProps {
|
||||
appName?: string;
|
||||
|
|
@ -23,61 +20,35 @@ interface AppPageProps {
|
|||
}
|
||||
|
||||
export function AppPage(props: AppPageProps) {
|
||||
const { appName, canvasWidth, pageId, pageName, widgetsStructure } = props;
|
||||
|
||||
const dispatch = useDispatch();
|
||||
const appMode = useSelector(getAppMode);
|
||||
const isPublished = appMode === APP_MODE.PUBLISHED;
|
||||
const isAnvilLayout = useSelector(getIsAnvilLayout);
|
||||
const { hasSidebarPinned, sidebarWidth } = useAppViewerSidebarProperties();
|
||||
|
||||
const width: string = useMemo(() => {
|
||||
return isAnvilLayout ? "100%" : `${canvasWidth}px`;
|
||||
}, [isAnvilLayout, canvasWidth]);
|
||||
return isAnvilLayout ? "100%" : `${props.canvasWidth}px`;
|
||||
}, [isAnvilLayout, props.canvasWidth]);
|
||||
|
||||
const pageViewWrapperRef = useRef<HTMLDivElement>(null);
|
||||
useEffect(() => {
|
||||
const wrapperElement = pageViewWrapperRef.current;
|
||||
if (wrapperElement) {
|
||||
const debouncedResize = debounce(
|
||||
([
|
||||
{
|
||||
contentRect: { width },
|
||||
},
|
||||
]) => {
|
||||
dispatch(updateCanvasLayoutAction(width - sidebarWidth));
|
||||
},
|
||||
RESIZE_DEBOUNCE_THRESHOLD,
|
||||
);
|
||||
|
||||
const resizeObserver = new ResizeObserver(debouncedResize);
|
||||
resizeObserver.observe(wrapperElement);
|
||||
|
||||
return () => {
|
||||
resizeObserver.unobserve(wrapperElement);
|
||||
};
|
||||
}
|
||||
}, [dispatch, sidebarWidth]);
|
||||
useDynamicAppLayout();
|
||||
|
||||
useEffect(() => {
|
||||
AnalyticsUtil.logEvent("PAGE_LOAD", {
|
||||
pageName: pageName,
|
||||
pageId: pageId,
|
||||
appName: appName,
|
||||
pageName: props.pageName,
|
||||
pageId: props.pageId,
|
||||
appName: props.appName,
|
||||
mode: "VIEW",
|
||||
});
|
||||
}, [appName, pageId, pageName]);
|
||||
}, [props.pageId, props.pageName]);
|
||||
|
||||
return (
|
||||
<PageViewWrapper
|
||||
hasPinnedSidebar={hasSidebarPinned}
|
||||
isPublished={isPublished}
|
||||
ref={pageViewWrapperRef}
|
||||
sidebarWidth={sidebarWidth}
|
||||
>
|
||||
<PageView data-testid="t--app-viewer-page" width={width}>
|
||||
{widgetsStructure.widgetId &&
|
||||
renderAppsmithCanvas(widgetsStructure as WidgetProps)}
|
||||
{props.widgetsStructure.widgetId &&
|
||||
renderAppsmithCanvas(props.widgetsStructure as WidgetProps)}
|
||||
</PageView>
|
||||
</PageViewWrapper>
|
||||
);
|
||||
|
|
@ -1 +0,0 @@
|
|||
export const RESIZE_DEBOUNCE_THRESHOLD = 100;
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
export { AppPage as default } from "./AppPage";
|
||||
export { PageViewWrapper } from "./AppPage.styled";
|
||||
|
|
@ -22,7 +22,7 @@ import { UpdatedEditor } from "test/testMockedWidgets";
|
|||
import { act, fireEvent, render } from "test/testUtils";
|
||||
import { generateReactKey } from "utils/generators";
|
||||
import { getAbsolutePixels } from "utils/helpers";
|
||||
import * as useCanvasWidthAutoResize from "pages/Editor/WidgetsEditor/components/MainContainerWrapper";
|
||||
import * as useDynamicAppLayoutHook from "utils/hooks/useDynamicAppLayout";
|
||||
import * as widgetRenderUtils from "utils/widgetRenderUtils";
|
||||
import GlobalHotKeys from "../GlobalHotKeys";
|
||||
import * as uiSelectors from "selectors/ui";
|
||||
|
|
@ -106,7 +106,7 @@ describe("Drag and Drop widgets into Main container", () => {
|
|||
.spyOn(utilities, "computeMainContainerWidget")
|
||||
.mockImplementation((widget) => widget as any);
|
||||
jest
|
||||
.spyOn(useCanvasWidthAutoResize, "useCanvasWidthAutoResize")
|
||||
.spyOn(useDynamicAppLayoutHook, "useDynamicAppLayout")
|
||||
.mockImplementation(() => true);
|
||||
|
||||
const pushState = jest.spyOn(window.history, "pushState");
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import type { ReactNode } from "react";
|
||||
import React, { useEffect, useRef } from "react";
|
||||
import React, { useEffect } from "react";
|
||||
import { useSelector } from "react-redux";
|
||||
|
||||
import {
|
||||
|
|
@ -22,13 +22,13 @@ import {
|
|||
getSelectedAppTheme,
|
||||
} from "selectors/appThemingSelectors";
|
||||
import { getCanvasWidgetsStructure } from "@appsmith/selectors/entitiesSelector";
|
||||
import { useDynamicAppLayout } from "utils/hooks/useDynamicAppLayout";
|
||||
import Canvas from "pages/Editor/Canvas";
|
||||
import type { AppState } from "@appsmith/reducers";
|
||||
import { getIsAnonymousDataPopupVisible } from "selectors/onboardingSelectors";
|
||||
import { MainContainerResizer } from "layoutSystems/common/mainContainerResizer/MainContainerResizer";
|
||||
import { useMainContainerResizer } from "layoutSystems/common/mainContainerResizer/useMainContainerResizer";
|
||||
import { getIsAnvilLayout } from "layoutSystems/anvil/integrations/selectors";
|
||||
import { useCanvasWidthAutoResize } from "./hooks";
|
||||
|
||||
interface MainCanvasWrapperProps {
|
||||
isPreviewMode: boolean;
|
||||
|
|
@ -107,7 +107,7 @@ const Wrapper = styled.section<{
|
|||
* @prop currentPageId, current page id in string
|
||||
* @returns
|
||||
*/
|
||||
export function MainContainerWrapper(props: MainCanvasWrapperProps) {
|
||||
function MainContainerWrapper(props: MainCanvasWrapperProps) {
|
||||
const { isAppSettingsPaneWithNavigationTabOpen, navigationHeight } = props;
|
||||
const dispatch = useDispatch();
|
||||
const {
|
||||
|
|
@ -128,10 +128,8 @@ export function MainContainerWrapper(props: MainCanvasWrapperProps) {
|
|||
const isAppThemeChanging = useSelector(getAppThemeIsChanging);
|
||||
const showCanvasTopSection = useSelector(showCanvasTopSectionSelector);
|
||||
const showAnonymousDataPopup = useSelector(getIsAnonymousDataPopupVisible);
|
||||
|
||||
const wrapperRef = useRef<HTMLDivElement>(null);
|
||||
const isCanvasInitialized = useCanvasWidthAutoResize(wrapperRef);
|
||||
const isPageInitializing = isFetchingPage || !isCanvasInitialized;
|
||||
const isLayoutingInitialized = useDynamicAppLayout();
|
||||
const isPageInitializing = isFetchingPage || !isLayoutingInitialized;
|
||||
const { canShowResizer, enableMainContainerResizer } =
|
||||
useMainContainerResizer();
|
||||
const isAnvilLayout = useSelector(getIsAnvilLayout);
|
||||
|
|
@ -140,7 +138,7 @@ export function MainContainerWrapper(props: MainCanvasWrapperProps) {
|
|||
return () => {
|
||||
dispatch(forceOpenWidgetPanel(false));
|
||||
};
|
||||
}, [dispatch]);
|
||||
}, []);
|
||||
|
||||
const fontFamily = `${selectedTheme.properties.fontFamily.appFont}, sans-serif`;
|
||||
const isAutoCanvasResizing = useSelector(
|
||||
|
|
@ -205,7 +203,6 @@ export function MainContainerWrapper(props: MainCanvasWrapperProps) {
|
|||
}
|
||||
isPreviewingNavigation={isPreviewingNavigation}
|
||||
navigationHeight={navigationHeight}
|
||||
ref={wrapperRef}
|
||||
style={{
|
||||
height: isPreviewMode ? `calc(100% - ${navigationHeight})` : "auto",
|
||||
fontFamily: fontFamily,
|
||||
|
|
@ -235,3 +232,5 @@ export function MainContainerWrapper(props: MainCanvasWrapperProps) {
|
|||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default MainContainerWrapper;
|
||||
|
|
@ -1 +0,0 @@
|
|||
export const RESIZE_DEBOUNCE_THRESHOLD = 100;
|
||||
|
|
@ -1 +0,0 @@
|
|||
export { useCanvasWidthAutoResize } from "./useCanvasWidthAutoResize";
|
||||
|
|
@ -1,60 +0,0 @@
|
|||
import { useEffect } from "react";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { debounce } from "lodash";
|
||||
|
||||
import { updateCanvasLayoutAction } from "actions/editorActions";
|
||||
import { DefaultLayoutType } from "constants/WidgetConstants";
|
||||
import { getCurrentApplicationLayout } from "selectors/editorSelectors";
|
||||
|
||||
import { resolveCanvasWidth } from "../utils/resolveCanvasWidth";
|
||||
import { RESIZE_DEBOUNCE_THRESHOLD } from "./constants";
|
||||
import { getIsCanvasInitialized } from "selectors/mainCanvasSelectors";
|
||||
|
||||
export const useCanvasWidthAutoResize = (ref: React.RefObject<HTMLElement>) => {
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const isCanvasInitialized = useSelector(getIsCanvasInitialized);
|
||||
const { type: appLayoutType = DefaultLayoutType } = useSelector(
|
||||
getCurrentApplicationLayout,
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isCanvasInitialized && ref.current) {
|
||||
const resolvedCanvasWidth = resolveCanvasWidth({
|
||||
appLayoutType,
|
||||
containerWidth: ref.current.offsetWidth,
|
||||
});
|
||||
dispatch(updateCanvasLayoutAction(resolvedCanvasWidth));
|
||||
}
|
||||
}, [appLayoutType, dispatch, isCanvasInitialized, ref]);
|
||||
|
||||
useEffect(() => {
|
||||
const canvasContainerElement = ref.current;
|
||||
if (canvasContainerElement) {
|
||||
const debouncedResize = debounce(
|
||||
([
|
||||
{
|
||||
contentRect: { width },
|
||||
},
|
||||
]) => {
|
||||
const resolvedCanvasWidth = resolveCanvasWidth({
|
||||
appLayoutType,
|
||||
containerWidth: width,
|
||||
});
|
||||
|
||||
dispatch(updateCanvasLayoutAction(resolvedCanvasWidth));
|
||||
},
|
||||
RESIZE_DEBOUNCE_THRESHOLD,
|
||||
);
|
||||
|
||||
const resizeObserver = new ResizeObserver(debouncedResize);
|
||||
resizeObserver.observe(canvasContainerElement);
|
||||
|
||||
return () => {
|
||||
resizeObserver.unobserve(canvasContainerElement);
|
||||
};
|
||||
}
|
||||
}, [ref, dispatch, appLayoutType]);
|
||||
|
||||
return isCanvasInitialized;
|
||||
};
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
export { MainContainerWrapper as default } from "./MainContainerWrapper";
|
||||
export { useCanvasWidthAutoResize } from "./hooks/useCanvasWidthAutoResize";
|
||||
|
|
@ -1 +0,0 @@
|
|||
export { resolveCanvasWidth } from "./resolveCanvasWidth";
|
||||
|
|
@ -1,92 +0,0 @@
|
|||
import { layoutConfigurations } from "constants/WidgetConstants";
|
||||
import { resolveCanvasWidth } from "./resolveCanvasWidth";
|
||||
import type { SupportedLayouts } from "reducers/entityReducers/pageListReducer";
|
||||
|
||||
const layoutTestConfigs = Object.entries(layoutConfigurations)
|
||||
.filter(([key]) => key !== "FLUID")
|
||||
.map(([key, widths]) => {
|
||||
const appLayoutType = key as SupportedLayouts;
|
||||
return [
|
||||
appLayoutType,
|
||||
{
|
||||
...widths,
|
||||
},
|
||||
] as const;
|
||||
});
|
||||
|
||||
describe("resolveCanvasWidth", () => {
|
||||
test.each(layoutTestConfigs)(
|
||||
"results are within range for %s",
|
||||
(appLayoutType, { maxWidth, minWidth }) => {
|
||||
expect(
|
||||
resolveCanvasWidth({
|
||||
appLayoutType,
|
||||
containerWidth: maxWidth,
|
||||
}),
|
||||
).toBe(maxWidth);
|
||||
|
||||
expect(
|
||||
resolveCanvasWidth({
|
||||
appLayoutType,
|
||||
containerWidth: minWidth,
|
||||
}),
|
||||
).toBe(minWidth);
|
||||
|
||||
expect(
|
||||
resolveCanvasWidth({
|
||||
appLayoutType,
|
||||
containerWidth: maxWidth - 1,
|
||||
}),
|
||||
).toBe(maxWidth - 1);
|
||||
|
||||
expect(
|
||||
resolveCanvasWidth({
|
||||
appLayoutType,
|
||||
containerWidth: minWidth + 1,
|
||||
}),
|
||||
).toBe(minWidth + 1);
|
||||
|
||||
expect(
|
||||
resolveCanvasWidth({
|
||||
appLayoutType,
|
||||
containerWidth: -1,
|
||||
}),
|
||||
).toBe(minWidth);
|
||||
|
||||
expect(
|
||||
resolveCanvasWidth({
|
||||
appLayoutType,
|
||||
containerWidth: layoutConfigurations[appLayoutType].minWidth - 1,
|
||||
}),
|
||||
).toBe(minWidth);
|
||||
|
||||
expect(
|
||||
resolveCanvasWidth({
|
||||
appLayoutType,
|
||||
containerWidth: Infinity,
|
||||
}),
|
||||
).toBe(maxWidth);
|
||||
},
|
||||
);
|
||||
|
||||
it("results are within range for FLUID", () => {
|
||||
const appLayoutType = "FLUID";
|
||||
|
||||
const widths = {
|
||||
min: 0,
|
||||
sm: 576,
|
||||
md: 768,
|
||||
lg: 1200,
|
||||
max: Infinity,
|
||||
};
|
||||
|
||||
for (const width of Object.values(widths)) {
|
||||
expect(
|
||||
resolveCanvasWidth({
|
||||
appLayoutType,
|
||||
containerWidth: width,
|
||||
}),
|
||||
).toEqual(width);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
import { layoutConfigurations } from "constants/WidgetConstants";
|
||||
import type { SupportedLayouts } from "reducers/entityReducers/pageListReducer";
|
||||
|
||||
interface CalculateCanvasWidthProps {
|
||||
appLayoutType: SupportedLayouts;
|
||||
containerWidth: number;
|
||||
}
|
||||
|
||||
export const resolveCanvasWidth = ({
|
||||
appLayoutType,
|
||||
containerWidth,
|
||||
}: CalculateCanvasWidthProps) => {
|
||||
const { maxWidth, minWidth } = layoutConfigurations[appLayoutType];
|
||||
|
||||
switch (true) {
|
||||
case maxWidth < 0:
|
||||
case containerWidth >= minWidth && containerWidth <= maxWidth:
|
||||
return containerWidth;
|
||||
case containerWidth < minWidth:
|
||||
return minWidth;
|
||||
case containerWidth > maxWidth:
|
||||
return maxWidth;
|
||||
default:
|
||||
return minWidth;
|
||||
}
|
||||
};
|
||||
|
|
@ -8,7 +8,7 @@ import {
|
|||
combinedPreviewModeSelector,
|
||||
getCurrentApplication,
|
||||
} from "selectors/editorSelectors";
|
||||
import { PageViewWrapper } from "pages/AppViewer/AppPage";
|
||||
import { PageViewWrapper } from "pages/AppViewer/AppPage.styled";
|
||||
import classNames from "classnames";
|
||||
import { APP_MODE } from "entities/App";
|
||||
import { getAppMode } from "@appsmith/selectors/entitiesSelector";
|
||||
|
|
|
|||
292
app/client/src/utils/hooks/useDynamicAppLayout.tsx
Normal file
292
app/client/src/utils/hooks/useDynamicAppLayout.tsx
Normal file
|
|
@ -0,0 +1,292 @@
|
|||
import { debounce, get } from "lodash";
|
||||
import { useEffect, useMemo, useRef, useState } from "react";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
|
||||
import { updateLayoutForMobileBreakpointAction } from "actions/autoLayoutActions";
|
||||
import { updateCanvasLayoutAction } from "actions/editorActions";
|
||||
import { APP_SIDEBAR_WIDTH } from "constants/AppConstants";
|
||||
import {
|
||||
DefaultLayoutType,
|
||||
layoutConfigurations,
|
||||
MAIN_CONTAINER_WIDGET_ID,
|
||||
} from "constants/WidgetConstants";
|
||||
import { APP_MODE } from "entities/App";
|
||||
import { LayoutSystemTypes } from "layoutSystems/types";
|
||||
import {
|
||||
combinedPreviewModeSelector,
|
||||
getCurrentApplicationLayout,
|
||||
getCurrentPageId,
|
||||
getMainCanvasProps,
|
||||
} from "selectors/editorSelectors";
|
||||
import { getAppMode } from "@appsmith/selectors/entitiesSelector";
|
||||
import { getExplorerWidth } from "selectors/explorerSelector";
|
||||
import { getIsCanvasInitialized } from "selectors/mainCanvasSelectors";
|
||||
import { getIsAppSettingsPaneWithNavigationTabOpen } from "selectors/appSettingsPaneSelectors";
|
||||
import {
|
||||
getAppSidebarPinned,
|
||||
getCurrentApplication,
|
||||
getSidebarWidth,
|
||||
} from "@appsmith/selectors/applicationSelectors";
|
||||
import { useIsMobileDevice } from "./useDeviceDetect";
|
||||
import { getPropertyPaneWidth } from "selectors/propertyPaneSelectors";
|
||||
import { scrollbarWidth } from "utils/helpers";
|
||||
import { useWindowSizeHooks } from "./dragResizeHooks";
|
||||
import type { AppState } from "@appsmith/reducers";
|
||||
import { ReduxActionTypes } from "@appsmith/constants/ReduxActionConstants";
|
||||
import { useLocation } from "react-router";
|
||||
import { CANVAS_VIEWPORT } from "constants/componentClassNameConstants";
|
||||
import { getLayoutSystemType } from "selectors/layoutSystemSelectors";
|
||||
|
||||
const GUTTER_WIDTH = 72;
|
||||
export const AUTOLAYOUT_RESIZER_WIDTH_BUFFER = 40;
|
||||
|
||||
export const useDynamicAppLayout = () => {
|
||||
const dispatch = useDispatch();
|
||||
const explorerWidth = useSelector(getExplorerWidth);
|
||||
const propertyPaneWidth = useSelector(getPropertyPaneWidth);
|
||||
const appMode: APP_MODE | undefined = useSelector(getAppMode);
|
||||
const { width: screenWidth } = useWindowSizeHooks();
|
||||
const mainCanvasProps = useSelector(getMainCanvasProps);
|
||||
const isPreviewMode = useSelector(combinedPreviewModeSelector);
|
||||
const currentPageId = useSelector(getCurrentPageId);
|
||||
const isCanvasInitialized = useSelector(getIsCanvasInitialized);
|
||||
const appLayout = useSelector(getCurrentApplicationLayout);
|
||||
const layoutSystemType = useSelector(getLayoutSystemType);
|
||||
const isAppSidebarPinned = useSelector(getAppSidebarPinned);
|
||||
const sidebarWidth = useSelector(getSidebarWidth);
|
||||
const isAppSettingsPaneWithNavigationTabOpen = useSelector(
|
||||
getIsAppSettingsPaneWithNavigationTabOpen,
|
||||
);
|
||||
const currentApplicationDetails = useSelector(getCurrentApplication);
|
||||
const isMobile = useIsMobileDevice();
|
||||
const isAutoCanvasResizing = useSelector(
|
||||
(state: AppState) => state.ui.widgetDragResize.isAutoCanvasResizing,
|
||||
);
|
||||
const [isCanvasResizing, setIsCanvasResizing] = useState<boolean>(false);
|
||||
const { search } = useLocation();
|
||||
const queryParams = new URLSearchParams(search);
|
||||
const isEmbed = queryParams.get("embed");
|
||||
const isNavbarVisibleInEmbeddedApp = queryParams.get("navbar");
|
||||
|
||||
const isPreviewing = isPreviewMode;
|
||||
|
||||
/**
|
||||
* app layout range i.e minWidth and maxWidth for the current layout
|
||||
* if there is no config for the current layout, use default layout i.e desktop
|
||||
*/
|
||||
const layoutWidthRange = useMemo(() => {
|
||||
let minWidth = -1;
|
||||
let maxWidth = -1;
|
||||
|
||||
if (appLayout) {
|
||||
const { type } = appLayout;
|
||||
const currentLayoutConfig = get(
|
||||
layoutConfigurations,
|
||||
type,
|
||||
layoutConfigurations[DefaultLayoutType],
|
||||
);
|
||||
|
||||
if (currentLayoutConfig.minWidth) minWidth = currentLayoutConfig.minWidth;
|
||||
if (currentLayoutConfig.maxWidth) maxWidth = currentLayoutConfig.maxWidth;
|
||||
}
|
||||
|
||||
return { minWidth, maxWidth };
|
||||
}, [appLayout]);
|
||||
|
||||
/**
|
||||
* calculate the width for the canvas
|
||||
*
|
||||
* cases:
|
||||
* - if max width is negative, use calculated width
|
||||
* - if calculated width is in range of min/max widths of layout, use calculated width
|
||||
* - if calculated width is less then min width, use min Width
|
||||
* - if calculated width is larger than max width, use max width
|
||||
* - by default use min width
|
||||
*
|
||||
* @returns
|
||||
*/
|
||||
const calculateCanvasWidth = () => {
|
||||
let { maxWidth } = layoutWidthRange;
|
||||
const { minWidth } = layoutWidthRange;
|
||||
let calculatedWidth = screenWidth - scrollbarWidth();
|
||||
|
||||
const gutterWidth =
|
||||
layoutSystemType === LayoutSystemTypes.AUTO ? 0 : GUTTER_WIDTH;
|
||||
|
||||
// if preview mode is not on and the app setting pane is not opened, we need to subtract the width of the property pane
|
||||
if (!isPreviewing && appMode === APP_MODE.EDIT) {
|
||||
calculatedWidth -= propertyPaneWidth;
|
||||
}
|
||||
|
||||
// if explorer is closed or its preview mode, we don't need to subtract the EE width
|
||||
if (!isPreviewing && appMode === APP_MODE.EDIT) {
|
||||
calculatedWidth -= explorerWidth;
|
||||
}
|
||||
|
||||
if (appMode === APP_MODE.EDIT) {
|
||||
calculatedWidth -= APP_SIDEBAR_WIDTH;
|
||||
}
|
||||
|
||||
/**
|
||||
* If there is
|
||||
* 1. a sidebar for navigation,
|
||||
* 2. it is pinned,
|
||||
* 3. device is not mobile
|
||||
* 4. and it is not an embedded app
|
||||
* we need to subtract the sidebar width as well in the following modes -
|
||||
* 1. Preview
|
||||
* 2. App settings open with navigation tab
|
||||
* 3. Published
|
||||
*/
|
||||
const isEmbeddedAppWithNavVisible = isEmbed && isNavbarVisibleInEmbeddedApp;
|
||||
if (
|
||||
(appMode === APP_MODE.PUBLISHED ||
|
||||
isPreviewing ||
|
||||
isAppSettingsPaneWithNavigationTabOpen) &&
|
||||
!isMobile &&
|
||||
(!isEmbed || isEmbeddedAppWithNavVisible) &&
|
||||
sidebarWidth
|
||||
) {
|
||||
calculatedWidth -= sidebarWidth;
|
||||
}
|
||||
if (isMobile) {
|
||||
maxWidth += sidebarWidth;
|
||||
}
|
||||
const ele: any = document.getElementById(CANVAS_VIEWPORT);
|
||||
if (
|
||||
appMode === APP_MODE.EDIT &&
|
||||
appLayout?.type === "FLUID" &&
|
||||
ele &&
|
||||
calculatedWidth > ele.clientWidth
|
||||
) {
|
||||
calculatedWidth = ele.clientWidth;
|
||||
}
|
||||
|
||||
switch (true) {
|
||||
case maxWidth < 0:
|
||||
case appLayout?.type === "FLUID":
|
||||
case calculatedWidth < maxWidth && calculatedWidth > minWidth:
|
||||
const totalWidthToSubtract = gutterWidth;
|
||||
// NOTE: gutter + border width will be only substracted when theme mode and preview mode are off
|
||||
return (
|
||||
calculatedWidth -
|
||||
(appMode === APP_MODE.EDIT &&
|
||||
!isPreviewing &&
|
||||
!isAppSettingsPaneWithNavigationTabOpen
|
||||
? totalWidthToSubtract
|
||||
: 0)
|
||||
);
|
||||
case calculatedWidth < minWidth:
|
||||
return minWidth;
|
||||
case calculatedWidth > maxWidth:
|
||||
return maxWidth;
|
||||
default:
|
||||
return minWidth;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* resizes the layout based on the layout type
|
||||
*/
|
||||
const resizeToLayout = () => {
|
||||
const calculatedWidth = calculateCanvasWidth();
|
||||
const { width: rightColumn } = mainCanvasProps || {};
|
||||
if (rightColumn !== calculatedWidth || !isCanvasInitialized) {
|
||||
dispatch(updateCanvasLayoutAction(calculatedWidth));
|
||||
}
|
||||
return calculatedWidth;
|
||||
};
|
||||
|
||||
const debouncedResize = useRef(debounce(resizeToLayout, 250));
|
||||
const immediateDebouncedResize = useRef(debounce(resizeToLayout));
|
||||
|
||||
useEffect(() => {
|
||||
const resizeObserver = new ResizeObserver(immediateDebouncedResize.current);
|
||||
const canvasViewportElement = document.getElementById(CANVAS_VIEWPORT);
|
||||
|
||||
if (
|
||||
canvasViewportElement &&
|
||||
canvasViewportElement instanceof HTMLElement &&
|
||||
appLayout?.type === "FLUID"
|
||||
) {
|
||||
resizeObserver.observe(canvasViewportElement);
|
||||
|
||||
return () => {
|
||||
resizeObserver.unobserve(canvasViewportElement);
|
||||
};
|
||||
}
|
||||
}, [appLayout, currentPageId, immediateDebouncedResize, isPreviewing]);
|
||||
|
||||
useEffect(() => {
|
||||
if (isCanvasInitialized) debouncedResize.current();
|
||||
}, [isCanvasInitialized, screenWidth]);
|
||||
|
||||
/**
|
||||
* resize the layout if any of the following thing changes:
|
||||
* - app layout
|
||||
* - page
|
||||
* - container right column
|
||||
* - preview mode
|
||||
* - explorer width
|
||||
* - explorer is pinned
|
||||
* - theme mode is turned on
|
||||
* - sidebar pin/unpin
|
||||
* - app settings pane open with navigation tab
|
||||
* - any of the following navigation settings changes
|
||||
* - orientation
|
||||
* - nav style
|
||||
* - device changes to/from mobile
|
||||
*/
|
||||
useEffect(() => {
|
||||
resizeToLayout();
|
||||
}, [
|
||||
appLayout,
|
||||
mainCanvasProps?.width,
|
||||
isPreviewing,
|
||||
isAppSettingsPaneWithNavigationTabOpen,
|
||||
explorerWidth,
|
||||
sidebarWidth,
|
||||
propertyPaneWidth,
|
||||
propertyPaneWidth,
|
||||
isAppSidebarPinned,
|
||||
currentApplicationDetails?.applicationDetail?.navigationSetting
|
||||
?.orientation,
|
||||
currentApplicationDetails?.applicationDetail?.navigationSetting?.navStyle,
|
||||
isMobile,
|
||||
currentPageId, //TODO: preet - remove this after first merge.
|
||||
]);
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(
|
||||
updateLayoutForMobileBreakpointAction(
|
||||
MAIN_CONTAINER_WIDGET_ID,
|
||||
layoutSystemType === LayoutSystemTypes.AUTO
|
||||
? mainCanvasProps?.isMobile
|
||||
: false,
|
||||
calculateCanvasWidth(),
|
||||
),
|
||||
);
|
||||
}, [mainCanvasProps?.isMobile]);
|
||||
|
||||
useEffect(() => {
|
||||
if (isAutoCanvasResizing) setIsCanvasResizing(true);
|
||||
else if (isCanvasResizing) {
|
||||
setIsCanvasResizing(false);
|
||||
const canvasWidth: number = resizeToLayout();
|
||||
dispatch(
|
||||
updateLayoutForMobileBreakpointAction(
|
||||
MAIN_CONTAINER_WIDGET_ID,
|
||||
layoutSystemType === LayoutSystemTypes.AUTO
|
||||
? mainCanvasProps?.isMobile
|
||||
: false,
|
||||
canvasWidth,
|
||||
),
|
||||
);
|
||||
dispatch({
|
||||
type: ReduxActionTypes.PROCESS_AUTO_LAYOUT_DIMENSION_UPDATES,
|
||||
});
|
||||
}
|
||||
}, [isAutoCanvasResizing]);
|
||||
|
||||
return isCanvasInitialized;
|
||||
};
|
||||
|
|
@ -2,7 +2,7 @@ import GlobalHotKeys from "pages/Editor/GlobalHotKeys";
|
|||
import React from "react";
|
||||
import { MemoryRouter } from "react-router-dom";
|
||||
import * as utilities from "selectors/editorSelectors";
|
||||
import * as useCanvasWidthAutoResize from "pages/Editor/WidgetsEditor/components/MainContainerWrapper";
|
||||
import * as useDynamicAppLayoutHook from "utils/hooks/useDynamicAppLayout";
|
||||
|
||||
import * as useCanvasDraggingHook from "layoutSystems/fixedlayout/editor/FixedLayoutCanvasArenas/hooks/useCanvasDragging";
|
||||
import store from "store";
|
||||
|
|
@ -20,9 +20,8 @@ const pageId = "0123456789abcdef00000000";
|
|||
describe("ContainerWidget tests", () => {
|
||||
const mockGetIsFetchingPage = jest.spyOn(utilities, "getIsFetchingPage");
|
||||
jest
|
||||
.spyOn(useCanvasWidthAutoResize, "useCanvasWidthAutoResize")
|
||||
.spyOn(useDynamicAppLayoutHook, "useDynamicAppLayout")
|
||||
.mockImplementation(() => true);
|
||||
|
||||
const pushState = jest.spyOn(window.history, "pushState");
|
||||
|
||||
pushState.mockImplementation((state: any, title: any, url: any) => {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user