chore: Transitions for IDE (#35714)

## Description

Uses `AnimatedGridLayout` component to introduce transitions for the
IDE. This is behind a feature flag

Fixes #34538
Fixes #30863 
Fixes #34544 

## Automation

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

### 🔍 Cypress test results
<!-- This is an auto-generated comment: Cypress test results  -->
> [!CAUTION]
> 🔴 🔴 🔴 Some tests have failed.
> Workflow run:
<https://github.com/appsmithorg/appsmith/actions/runs/10737363879>
> Commit: a912f5c52366abe48768727a1c605cd72b48752c
> <a
href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=10737363879&attempt=2&selectiontype=test&testsstatus=failed&specsstatus=fail"
target="_blank">Cypress dashboard</a>.
> Tags: @tag.All
> Spec: 
> The following are new failures, please fix them before merging the PR:
<ol>
>
<li>cypress/e2e/Regression/ServerSide/OnLoadTests/ExecuteAction_Spec.ts</ol>
> <a
href="https://internal.appsmith.com/app/cypress-dashboard/identified-flaky-tests-65890b3c81d7400d08fa9ee3?branch=master"
target="_blank">List of identified flaky tests</a>.
> <hr>Fri, 06 Sep 2024 16:32:30 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

## Summary by CodeRabbit

- **New Features**
- Introduced two new layout components: `AnimatedLayout` and
`UnanimatedLayout` for improved editor interface structuring.
- Added TypeScript type definitions for the DOM View Transitions API to
enhance type safety and developer experience.
- Implemented custom hooks, `useGridLayoutTemplate` and
`useEditorStateLeftPaneWidth`, for dynamic grid management and left pane
width calculation in the IDE layout.

- **Improvements**
- Enhanced layout responsiveness with the addition of dynamic grid
management.
- Updated the `Editor` component to use a centralized constant for
height calculations, improving maintainability and consistency.
- Enhanced test accuracy by refining assertions in the Git Branch
Protection test suite.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Sagar Khalasi <sagar@appsmith.com>
This commit is contained in:
Hetu Nandu 2024-09-09 16:25:50 +05:30 committed by GitHub
parent 1b16be896d
commit 60dbda49e7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
46 changed files with 517 additions and 243 deletions

View File

@ -36,10 +36,7 @@ describe("Git Branch Protection", { tags: ["@tag.Git"] }, function () {
cy.wait("@gitProtectApi").then((res1) => {
_.agHelper.GetNClick(_.gitSync._closeGitSettingsModal);
expect(res1.response).to.have.property("statusCode", 200);
_.agHelper.AssertElementVisibility(
AppSidebar.locators.sidebar,
false,
);
_.agHelper.AssertElementAbsence(AppSidebar.locators.sidebar);
_.agHelper.AssertElementVisibility(
PageLeftPane.locators.selector,
false,

View File

@ -269,6 +269,7 @@
"@types/codemirror": "^0.0.96",
"@types/deep-diff": "^1.0.0",
"@types/dom-mediacapture-record": "^1.0.11",
"@types/dom-view-transitions": "^1.0.5",
"@types/downloadjs": "^1.4.2",
"@types/jest": "^27.4.1",
"@types/js-beautify": "^1.13.2",

View File

@ -1,6 +1,7 @@
import React from "react";
import { Divider, Flex } from "@appsmith/ads";
import { AppsmithLink } from "pages/Editor/AppsmithLink";
import { IDE_HEADER_HEIGHT } from "./constants";
interface ChildrenProps {
children: React.ReactNode | React.ReactNode[];
@ -59,7 +60,7 @@ const Header = (props: ChildrenProps) => {
alignItems="center"
border="1px solid var(--ads-v2-color-border)"
className="t--editor-header"
height="40px"
height={IDE_HEADER_HEIGHT + "px"}
overflow="hidden"
width="100%"
>

View File

@ -0,0 +1 @@
export const IDE_HEADER_HEIGHT = 40;

View File

@ -9,6 +9,7 @@
* These are composable components that you can use to spread the content of the header
* It is possible to use the IDE Header without using these subsections
*/
export { IDE_HEADER_HEIGHT } from "./Structure/constants";
export { default as IDEHeader } from "./Structure/Header";
/* ====================================================

View File

@ -45,6 +45,7 @@ export const FEATURE_FLAG = {
"ab_learnability_discoverability_collapse_all_except_data_enabled",
release_layout_conversion_enabled: "release_layout_conversion_enabled",
release_anvil_toggle_enabled: "release_anvil_toggle_enabled",
release_ide_animations_enabled: "release_ide_animations_enabled",
} as const;
export type FeatureFlag = keyof typeof FEATURE_FLAG;
@ -82,6 +83,7 @@ export const DEFAULT_FEATURE_FLAG_VALUE: FeatureFlags = {
ab_learnability_discoverability_collapse_all_except_data_enabled: true,
release_layout_conversion_enabled: false,
release_anvil_toggle_enabled: false,
release_ide_animations_enabled: false,
};
export const AB_TESTING_EVENT_KEYS = {

View File

@ -41,7 +41,7 @@ export function LayoutArea(props: LayoutAreaProps) {
>
<div
style={{
minWidth: dimensions?.width || "100%",
width: dimensions?.width || "100%",
height: "100%",
position: "absolute",
overflow: "auto",

View File

@ -1,9 +1,11 @@
import { easings } from "@react-spring/web";
import type { AnimatedGridUnit } from "./types";
/** Default rows config. */
export const DEFAULT_ROWS: AnimatedGridUnit[] = ["1fr"];
export const SPRING_ANIMATION_CONFIG = {
easing: easings.easeInCirc,
duration: 375,
friction: 32,
mass: 1,
tension: 205,
};

View File

@ -1,9 +1,10 @@
import styled from "styled-components";
import { Layers } from "constants/Layers";
import { BOTTOM_BAR_HEIGHT } from "./constants";
export const Container = styled.div`
width: 100%;
height: ${(props) => props.theme.bottomBarHeight};
height: ${BOTTOM_BAR_HEIGHT}px;
display: flex;
position: fixed;
justify-content: space-between;

View File

@ -0,0 +1 @@
export const BOTTOM_BAR_HEIGHT = 37;

View File

@ -7,14 +7,18 @@ import { Button } from "@appsmith/ads";
import SwitchEnvironment from "ee/components/SwitchEnvironment";
import { Container, Wrapper } from "./components";
import { useSelector } from "react-redux";
import { getCurrentApplicationId } from "selectors/editorSelectors";
import {
getCurrentApplicationId,
previewModeSelector,
} from "selectors/editorSelectors";
import { useDispatch } from "react-redux";
import { softRefreshActions } from "actions/pluginActionActions";
import { START_SWITCH_ENVIRONMENT } from "ee/constants/messages";
import { getIsAnvilEnabledInCurrentApplication } from "layoutSystems/anvil/integrations/selectors";
export default function BottomBar({ viewMode }: { viewMode: boolean }) {
export default function BottomBar() {
const appId = useSelector(getCurrentApplicationId) || "";
const isPreviewMode = useSelector(previewModeSelector);
const dispatch = useDispatch();
// We check if the current application is an Anvil application.
// If it is an Anvil application, we remove the Git features from the bottomBar
@ -28,17 +32,17 @@ export default function BottomBar({ viewMode }: { viewMode: boolean }) {
return (
<Container>
<Wrapper>
{!viewMode && (
{!isPreviewMode && (
<SwitchEnvironment
editorId={appId}
onChangeEnv={onChangeEnv}
startSwitchEnvMessage={START_SWITCH_ENVIRONMENT}
viewMode={viewMode}
viewMode={isPreviewMode}
/>
)}
{!viewMode && !isAnvilEnabled && <QuickGitActions />}
{!isPreviewMode && !isAnvilEnabled && <QuickGitActions />}
</Wrapper>
{!viewMode && (
{!isPreviewMode && (
<Wrapper>
<ManualUpgrades showTooltip>
<Button

View File

@ -1,51 +1,28 @@
import classNames from "classnames";
import React, {
memo,
useCallback,
useContext,
useEffect,
useMemo,
useRef,
} from "react";
import * as Sentry from "@sentry/react";
import { useSelector } from "react-redux";
import React, { memo, useContext, useEffect, useMemo, useRef } from "react";
import { getSelectedWidgets } from "selectors/ui";
import { tailwindLayers } from "constants/Layers";
import WidgetPropertyPane from "pages/Editor/PropertyPane";
import CanvasPropertyPane from "pages/Editor/CanvasPropertyPane";
import useHorizontalResize from "utils/hooks/useHorizontalResize";
import { getIsDraggingForSelection } from "selectors/canvasSelectors";
import MultiSelectPropertyPane from "pages/Editor/MultiSelectPropertyPane";
import { getIsDraggingOrResizing } from "selectors/widgetSelectors";
import { selectedWidgetsPresentInCanvas } from "selectors/propertyPaneSelectors";
import styled from "styled-components";
import WalkthroughContext from "components/featureWalkthrough/walkthroughContext";
import { MAIN_CONTAINER_WIDGET_ID } from "constants/WidgetConstants";
export const PROPERTY_PANE_ID = "t--property-pane-sidebar";
const StyledResizer = styled.div<{ resizing: boolean }>`
${(props) =>
props.resizing &&
`
& > div {
background-color: var(--ads-v2-color-outline);
}
`}
:hover {
& > div {
background-color: var(--ads-v2-color-bg-emphasis);
}
}
`;
interface Props {
width: number;
onDragEnd?: () => void;
onWidthChange: (width: number) => void;
}
export const PropertyPaneSidebar = memo((props: Props) => {
export const PropertyPaneSidebar = memo(() => {
const sidebarRef = useRef<HTMLDivElement>(null);
const prevSelectedWidgetId = useRef<string | undefined>();
const { onMouseDown, onMouseUp, onTouchStart, resizing } =
useHorizontalResize(sidebarRef, props.onWidthChange, props.onDragEnd, true);
const selectedWidgetIds = useSelector(getSelectedWidgets);
const isDraggingOrResizing = useSelector(getIsDraggingOrResizing);
const { isOpened: isWalkthroughOpened, popFeature } =
@ -58,17 +35,10 @@ export const PropertyPaneSidebar = memo((props: Props) => {
selectedWidgetIds[0] !== prevSelectedWidgetId.current) ||
selectedWidgetIds[0] === MAIN_CONTAINER_WIDGET_ID;
// This is to keep the theming properties from changing,
// while dragging a widget when no other widgets were selected
const keepThemeWhileDragging =
prevSelectedWidgetId.current === undefined && shouldNotRenderPane;
const selectedWidgetsLength = useSelector(
(state) => selectedWidgetsPresentInCanvas(state).length,
);
const isDraggingForSelection = useSelector(getIsDraggingForSelection);
prevSelectedWidgetId.current =
selectedWidgetIds.length === 1 ? selectedWidgetIds[0] : undefined;
@ -91,27 +61,24 @@ export const PropertyPaneSidebar = memo((props: Props) => {
default:
return <CanvasPropertyPane />;
}
}, [
selectedWidgetsLength,
isDraggingForSelection,
shouldNotRenderPane,
keepThemeWhileDragging,
]);
}, [selectedWidgetsLength, shouldNotRenderPane]);
const closeWalkthrough = () => {
const closeWalkthrough = useCallback(() => {
if (popFeature) {
popFeature("PROPERTY_PANE");
sidebarRef.current?.removeEventListener("click", closeWalkthrough);
}
};
}, [popFeature]);
useEffect(() => {
if (isWalkthroughOpened)
sidebarRef.current?.addEventListener("click", closeWalkthrough);
const currentSidebar = sidebarRef.current;
if (isWalkthroughOpened) {
currentSidebar?.addEventListener("click", closeWalkthrough);
}
return () => {
sidebarRef.current?.removeEventListener("click", closeWalkthrough);
currentSidebar?.removeEventListener("click", closeWalkthrough);
};
}, [isWalkthroughOpened]);
}, [closeWalkthrough, isWalkthroughOpened]);
return (
<div className="relative h-full">
@ -122,28 +89,7 @@ export const PropertyPaneSidebar = memo((props: Props) => {
id={PROPERTY_PANE_ID}
ref={sidebarRef}
>
{/* RESIZER */}
<StyledResizer
className={`absolute top-0 left-0 w-2 h-full -ml-1 group cursor-ew-resize ${tailwindLayers.resizer}`}
onMouseDown={onMouseDown}
onTouchEnd={onMouseUp}
onTouchStart={onTouchStart}
resizing={resizing}
>
<div
className={classNames({
"w-1 h-full bg-transparent transform transition flex items-center":
true,
})}
/>
</StyledResizer>
<div
className={classNames({
"h-full p-0 overflow-y-auto min-w-72 max-w-104": true,
"transition-all duration-400": !resizing,
})}
style={{ width: props.width }}
>
<div className={"h-full p-0 overflow-y-auto min-w-72 max-w-104 w-full"}>
{propertyPane}
</div>
</div>

View File

@ -4,12 +4,12 @@ import React, { useEffect, useState } from "react";
import type { ReactNode } from "react";
import styled from "styled-components";
import { Layers } from "constants/Layers";
import { theme } from "constants/DefaultTheme";
import { useDispatch, useSelector } from "react-redux";
import { getAppViewHeaderHeight } from "selectors/appViewSelectors";
import { ReduxActionTypes } from "ee/constants/ReduxActionConstants";
import { useMaxModalWidth } from "widgets/ModalWidget/component/useModalWidth";
import { useAppViewerSidebarProperties } from "utils/hooks/useAppViewerSidebarProperties";
const Container = styled.div<{
width?: number;
height?: number;
@ -22,7 +22,6 @@ const Container = styled.div<{
minSize?: number;
isEditMode?: boolean;
headerHeight?: number;
smallHeaderHeight?: string;
leftSidebarWidth?: string;
}>`
&&& {
@ -152,7 +151,6 @@ export function ModalOverlayLayer(props: BaseWidgetProps) {
maxWidth={maxModalWidth}
minSize={props.minSize}
right={props.bottom}
smallHeaderHeight={theme.smallHeaderHeight}
top={props.top}
width={props.width}
zIndex={

View File

@ -1,6 +1,7 @@
import styled from "styled-components";
import { Classes } from "@blueprintjs/core";
import { Link, Text } from "@appsmith/ads";
import { IDE_HEADER_HEIGHT } from "IDE";
export const Wrapper = styled.div`
flex-basis: calc(100% - ${(props) => props.theme.homePage.leftPane.width}px);
@ -37,7 +38,7 @@ export const BottomSpace = styled.div`
export const ContentWrapper = styled.div``;
export const LoaderContainer = styled.div`
height: ${(props) => `calc(100vh - ${props.theme.smallHeaderHeight})`};
height: calc(100vh - ${IDE_HEADER_HEIGHT}px);
display: flex;
justify-content: center;
width: 100%;

View File

@ -30,11 +30,12 @@ import {
StyledMenuContainer,
StyledSidebar,
} from "./Sidebar.styled";
import { getCurrentThemeDetails } from "selectors/themeSelectors";
import { getIsAppSettingsPaneWithNavigationTabOpen } from "selectors/appSettingsPaneSelectors";
import NavigationLogo from "ee/pages/AppViewer/NavigationLogo";
import MenuItemContainer from "./components/MenuItemContainer";
import BackToAppsButton from "./components/BackToAppsButton";
import { IDE_HEADER_HEIGHT } from "IDE";
import { BOTTOM_BAR_HEIGHT } from "components/BottomBar/constants";
interface SidebarProps {
currentApplicationDetails?: ApplicationPayload;
@ -80,7 +81,6 @@ export function Sidebar(props: SidebarProps) {
const isPinned = useSelector(getAppSidebarPinned);
const [isOpen, setIsOpen] = useState(true);
const { x } = useMouse();
const theme = useSelector(getCurrentThemeDetails);
const isPreviewMode = useSelector(combinedPreviewModeSelector);
const isAppSettingsPaneWithNavigationTabOpen = useSelector(
getIsAppSettingsPaneWithNavigationTabOpen,
@ -127,10 +127,10 @@ export function Sidebar(props: SidebarProps) {
const suffix = ")";
if (isPreviewMode) {
prefix += `${theme.smallHeaderHeight} - ${theme.bottomBarHeight}`;
prefix += `${IDE_HEADER_HEIGHT}px - ${BOTTOM_BAR_HEIGHT}px`;
} else if (isAppSettingsPaneWithNavigationTabOpen) {
// We deduct 64px as well since it is the margin coming from "m-8" class from tailwind
prefix += `${theme.smallHeaderHeight} - ${theme.bottomBarHeight} - 64px`;
prefix += `${IDE_HEADER_HEIGHT}px - ${BOTTOM_BAR_HEIGHT}px - 64px`;
} else {
prefix += "0px";
}

View File

@ -94,7 +94,7 @@ const Canvas = (props: CanvasProps) => {
<Wrapper
$enableMainCanvasResizer={!!props.enableMainCanvasResizer}
background={isAnvilLayout ? "" : backgroundForCanvas}
className={`relative t--canvas-artboard ${paddingBottomClass} transition-all duration-400 ${marginHorizontalClass} ${getViewportClassName(
className={`relative t--canvas-artboard ${paddingBottomClass} ${marginHorizontalClass} ${getViewportClassName(
canvasWidth,
)}`}
data-testid={"t--canvas-artboard"}

View File

@ -2,6 +2,7 @@ import styled from "styled-components";
import { Classes } from "@blueprintjs/core";
import { getTypographyByKey } from "@appsmith/ads-old";
import { Icon } from "@appsmith/ads";
import { IDE_HEADER_HEIGHT } from "IDE";
export const Container = styled.div`
display: flex;
@ -10,7 +11,7 @@ export const Container = styled.div`
background-color: var(--ads-v2-color-bg-subtle);
}
& .${Classes.EDITABLE_TEXT} {
height: ${(props) => props.theme.smallHeaderHeight} !important;
height: ${IDE_HEADER_HEIGHT} !important;
display: block;
cursor: pointer;
}
@ -21,9 +22,9 @@ export const Container = styled.div`
&&&& .${Classes.EDITABLE_TEXT_CONTENT}, &&&& .${Classes.EDITABLE_TEXT_INPUT} {
display: block;
${getTypographyByKey("h5")};
line-height: ${(props) => props.theme.smallHeaderHeight} !important;
line-height: ${IDE_HEADER_HEIGHT} !important;
padding: 0 ${(props) => props.theme.spaces[2]}px;
height: ${(props) => props.theme.smallHeaderHeight} !important;
height: ${IDE_HEADER_HEIGHT} !important;
}
&&&& .${Classes.EDITABLE_TEXT_INPUT} {
margin-right: 20px;

View File

@ -16,11 +16,11 @@ import { ENTITY_TYPE } from "entities/DataTree/dataTreeFactory";
import {
APP_SIDEBAR_WIDTH,
DEFAULT_EXPLORER_PANE_WIDTH,
} from "../../../../constants/AppConstants";
} from "constants/AppConstants";
import { BOTTOM_BAR_HEIGHT } from "components/BottomBar/constants";
const BindingContainerMaxHeight = 300;
const EntityHeight = 36;
const BottomBarHeight = 34;
const EntityInfoContainer = styled.div`
min-width: 220px;
@ -108,7 +108,7 @@ export function EntityProperties() {
let bottom;
if (
top + BindingContainerMaxHeight >
window.innerHeight - BottomBarHeight
window.innerHeight - BOTTOM_BAR_HEIGHT
) {
bottom = window.innerHeight - rect?.bottom - EntityHeight;
}

View File

@ -11,6 +11,14 @@ import { QueryEditor } from "./Query";
import EditorTabs from "../EditorTabs";
import { useCurrentEditorState } from "../hooks";
import { EditorEntityTab } from "ee/entities/IDE/constants";
import styled from "styled-components";
const Container = styled(Flex)`
// Animating using https://developer.mozilla.org/en-US/docs/Web/API/View_Transitions_API
& {
view-transition-name: editor-pane;
}
`;
const Editor = () => {
const { path } = useRouteMatch();
@ -19,7 +27,7 @@ const Editor = () => {
return null;
}
return (
<Flex
<Container
className="relative"
flex={1}
flexDirection="column"
@ -37,7 +45,7 @@ const Editor = () => {
path={querySegmentRoutes.map((route) => `${path}${route}`)}
/>
</Switch>
</Flex>
</Container>
);
};

View File

@ -1,6 +1,5 @@
import React from "react";
import { Flex } from "@appsmith/ads";
import { useEditorPaneWidth } from "../hooks";
import EditorPaneExplorer from "./Explorer";
import Editor from "./Editor";
import { useSelector } from "react-redux";
@ -9,7 +8,6 @@ import { EditorViewMode } from "ee/entities/IDE/constants";
import EntityProperties from "pages/Editor/Explorer/Entity/EntityProperties";
const EditorPane = () => {
const width = useEditorPaneWidth();
const ideViewMode = useSelector(getIDEViewMode);
return (
@ -26,7 +24,7 @@ const EditorPane = () => {
// @ts-expect-error Fix this the next time the file is edited
gap="spacing-2"
height="100%"
width={width}
width={"100%"}
>
{/** Entity Properties component is necessary to render
the Bindings popover in the context menu.

View File

@ -11,24 +11,48 @@ import {
createMessage,
} from "ee/constants/messages";
import { setIdeEditorViewMode } from "actions/ideActions";
import type { AppState } from "ee/reducers";
import { selectFeatureFlagCheck } from "ee/selectors/featureFlagsSelectors";
import { FEATURE_FLAG } from "ee/entities/FeatureFlag";
export const ScreenModeToggle = () => {
const dispatch = useDispatch();
const ideViewMode = useSelector(getIDEViewMode);
const isAnimatedIDEEnabled = useSelector((state: AppState) => {
return selectFeatureFlagCheck(
state,
FEATURE_FLAG.release_ide_animations_enabled,
);
});
const switchToFullScreen = useCallback(() => {
AnalyticsUtil.logEvent("EDITOR_MODE_CHANGE", {
to: EditorViewMode.FullScreen,
});
dispatch(setIdeEditorViewMode(EditorViewMode.FullScreen));
}, [dispatch]);
// Animating using https://developer.mozilla.org/en-US/docs/Web/API/View_Transitions_API
// this has limited availability right now
if ("startViewTransition" in document && isAnimatedIDEEnabled) {
document.startViewTransition(() => {
dispatch(setIdeEditorViewMode(EditorViewMode.FullScreen));
});
} else {
dispatch(setIdeEditorViewMode(EditorViewMode.FullScreen));
}
}, [dispatch, isAnimatedIDEEnabled]);
const switchToSplitScreen = useCallback(() => {
AnalyticsUtil.logEvent("EDITOR_MODE_CHANGE", {
to: EditorViewMode.SplitScreen,
});
dispatch(setIdeEditorViewMode(EditorViewMode.SplitScreen));
}, [dispatch]);
if ("startViewTransition" in document && isAnimatedIDEEnabled) {
document.startViewTransition(() => {
dispatch(setIdeEditorViewMode(EditorViewMode.SplitScreen));
});
} else {
dispatch(setIdeEditorViewMode(EditorViewMode.SplitScreen));
}
}, [dispatch, isAnimatedIDEEnabled]);
if (ideViewMode === EditorViewMode.SplitScreen) {
return (

View File

@ -0,0 +1,51 @@
import React from "react";
import { useGridLayoutTemplate } from "./hooks/useGridLayoutTemplate";
import EditorWrapperContainer from "pages/Editor/commons/EditorWrapperContainer";
import { AnimatedGridLayout, LayoutArea } from "components/AnimatedGridLayout";
import { useSelector } from "react-redux";
import BottomBar from "components/BottomBar";
import Sidebar from "../Sidebar";
import LeftPane from "../LeftPane";
import MainPane from "../MainPane";
import RightPane from "../RightPane";
import { Areas } from "./constants";
import ProtectedCallout from "../ProtectedCallout";
import { protectedModeSelector } from "selectors/gitSyncSelectors";
function AnimatedLayout() {
const isProtectedMode = useSelector(protectedModeSelector);
const { areas, columns, rows } = useGridLayoutTemplate();
if (columns.length === 0) {
return null;
}
return (
<>
{isProtectedMode && <ProtectedCallout />}
<EditorWrapperContainer>
<AnimatedGridLayout
areas={areas}
columns={columns}
height="100%"
rows={rows}
width="100vw"
>
<LayoutArea name={Areas.Sidebar}>
<Sidebar />
</LayoutArea>
<LayoutArea name={Areas.Explorer}>
<LeftPane />
</LayoutArea>
<LayoutArea name={Areas.WidgetEditor}>
<MainPane id="app-body" />
</LayoutArea>
<LayoutArea name={Areas.PropertyPane}>
<RightPane />
</LayoutArea>
</AnimatedGridLayout>
</EditorWrapperContainer>
<BottomBar />
</>
);
}
export { AnimatedLayout };

View File

@ -0,0 +1,67 @@
import React from "react";
import { useSelector } from "react-redux";
import BottomBar from "components/BottomBar";
import EditorWrapperContainer from "../../commons/EditorWrapperContainer";
import Sidebar from "pages/Editor/IDE/Sidebar";
import LeftPane from "../LeftPane";
import MainPane from "../MainPane";
import RightPane from "../RightPane";
import { protectedModeSelector } from "selectors/gitSyncSelectors";
import ProtectedCallout from "../ProtectedCallout";
import { useGridLayoutTemplate } from "./hooks/useGridLayoutTemplate";
import styled from "styled-components";
import { Areas } from "./constants";
const GridContainer = styled.div`
display: grid;
width: 100vw;
height: 100%;
`;
const LayoutContainer = styled.div<{ name: string }>`
position: relative;
grid-area: ${(props) => props.name};
`;
function UnanimatedLayout() {
const isProtectedMode = useSelector(protectedModeSelector);
const { areas, columns } = useGridLayoutTemplate();
const isSidebarVisible = columns[0] !== "0px";
return (
<>
{isProtectedMode && <ProtectedCallout />}
<EditorWrapperContainer>
<GridContainer
style={{
gridTemplateRows: "100%",
gridTemplateAreas: areas
.map((area) => `"${area.join(" ")}"`)
.join("\n"),
gridTemplateColumns: columns.join(" "),
}}
>
<LayoutContainer name={Areas.Sidebar}>
{isSidebarVisible ? <Sidebar /> : <div />}
</LayoutContainer>
<LayoutContainer name={Areas.Explorer}>
<LeftPane />
</LayoutContainer>
<LayoutContainer name={Areas.WidgetEditor}>
<MainPane id="app-body" />
</LayoutContainer>
<LayoutContainer name={Areas.PropertyPane}>
<RightPane />
</LayoutContainer>
</GridContainer>
</EditorWrapperContainer>
<BottomBar />
</>
);
}
const MemoUanimatedLayout = React.memo(UnanimatedLayout);
export { MemoUanimatedLayout as UnanimatedLayout };

View File

@ -0,0 +1,15 @@
import { APP_SIDEBAR_WIDTH } from "constants/AppConstants";
import type { AnimatedGridUnit } from "components/AnimatedGridLayout";
export const Areas = {
Sidebar: "Sidebar",
Explorer: "Explorer",
CodeEditor: "CodeEditor",
WidgetEditor: "WidgetEditor",
PropertyPane: "PropertyPane",
BottomBar: "BottomBar",
} as const;
export type Area = keyof typeof Areas;
export const SIDEBAR_WIDTH = (APP_SIDEBAR_WIDTH + "px") as AnimatedGridUnit;

View File

@ -0,0 +1,49 @@
import useWindowDimensions from "utils/hooks/useWindowDimensions";
import { useEffect, useState } from "react";
import {
APP_SIDEBAR_WIDTH,
DEFAULT_EXPLORER_PANE_WIDTH,
SPLIT_SCREEN_RATIO,
} from "constants/AppConstants";
import { useSelector } from "react-redux";
import { getIDEViewMode } from "selectors/ideSelectors";
import { getPropertyPaneWidth } from "selectors/propertyPaneSelectors";
import { EditorEntityTab, EditorViewMode } from "ee/entities/IDE/constants";
import { useCurrentEditorState } from "../../hooks";
import { previewModeSelector } from "selectors/editorSelectors";
import { protectedModeSelector } from "selectors/gitSyncSelectors";
export const useEditorStateLeftPaneWidth = (): number => {
const [windowWidth] = useWindowDimensions();
const [width, setWidth] = useState(windowWidth - APP_SIDEBAR_WIDTH);
const editorMode = useSelector(getIDEViewMode);
const { segment } = useCurrentEditorState();
const propertyPaneWidth = useSelector(getPropertyPaneWidth);
const isPreviewMode = useSelector(previewModeSelector);
const isProtectedMode = useSelector(protectedModeSelector);
useEffect(
function updateWidth() {
if (isPreviewMode || isProtectedMode) {
setWidth(0);
} else if (segment !== EditorEntityTab.UI) {
if (editorMode === EditorViewMode.SplitScreen) {
setWidth(windowWidth * SPLIT_SCREEN_RATIO);
} else {
setWidth(windowWidth - APP_SIDEBAR_WIDTH);
}
} else {
setWidth(DEFAULT_EXPLORER_PANE_WIDTH);
}
},
[
editorMode,
segment,
propertyPaneWidth,
windowWidth,
isPreviewMode,
isProtectedMode,
],
);
return width;
};

View File

@ -0,0 +1,164 @@
import React from "react";
import type { AnimatedGridUnit } from "components/AnimatedGridLayout";
import { useSelector } from "react-redux";
import useWindowDimensions from "utils/hooks/useWindowDimensions";
import { useCurrentAppState, useCurrentEditorState } from "../../hooks";
import { getPropertyPaneWidth } from "selectors/propertyPaneSelectors";
import { previewModeSelector } from "selectors/editorSelectors";
import { getIDEViewMode } from "selectors/ideSelectors";
import { protectedModeSelector } from "selectors/gitSyncSelectors";
import {
EditorEntityTab,
EditorState,
EditorViewMode,
} from "ee/entities/IDE/constants";
import {
APP_SETTINGS_PANE_WIDTH,
APP_SIDEBAR_WIDTH,
} from "constants/AppConstants";
import { useEditorStateLeftPaneWidth } from "./useEditorStateLeftPaneWidth";
import { type Area, Areas, SIDEBAR_WIDTH } from "../constants";
interface ReturnValue {
areas: Area[][];
rows: AnimatedGridUnit[];
columns: AnimatedGridUnit[];
}
function useGridLayoutTemplate(): ReturnValue {
const areas = React.useMemo(function initialiseAreas() {
return [
[Areas.Sidebar, Areas.Explorer, Areas.WidgetEditor, Areas.PropertyPane],
];
}, []);
const [columns, setColumns] = React.useState<AnimatedGridUnit[]>([]);
const [rows] = React.useState<AnimatedGridUnit[]>(["1fr"]);
const [windowWidth] = useWindowDimensions();
const editorStateLeftPaneWidth = useEditorStateLeftPaneWidth();
const PropertyPaneWidth = useSelector(getPropertyPaneWidth);
const { segment } = useCurrentEditorState();
const appState = useCurrentAppState();
const isPreviewMode = useSelector(previewModeSelector);
const editorMode = useSelector(getIDEViewMode);
const isProtectedMode = useSelector(protectedModeSelector);
React.useEffect(
function updateIDEColumns() {
switch (appState) {
case EditorState.DATA:
if (isPreviewMode || isProtectedMode) {
setColumns([
"0px",
"0px",
(windowWidth + "px") as AnimatedGridUnit,
"0px",
]);
} else {
setColumns([
SIDEBAR_WIDTH,
"300px",
(windowWidth - 300 - 50 + "px") as AnimatedGridUnit,
"0px",
]);
}
break;
case EditorState.SETTINGS:
if (isPreviewMode || isProtectedMode) {
setColumns([
"0px",
"0px",
(windowWidth + "px") as AnimatedGridUnit,
"0px",
]);
} else {
setColumns([
SIDEBAR_WIDTH,
(APP_SETTINGS_PANE_WIDTH + "px") as AnimatedGridUnit,
(windowWidth -
APP_SIDEBAR_WIDTH -
APP_SETTINGS_PANE_WIDTH +
"px") as AnimatedGridUnit,
"0px",
]);
}
break;
case EditorState.LIBRARIES:
if (isPreviewMode || isProtectedMode) {
setColumns([
"0px",
"0px",
(windowWidth + "px") as AnimatedGridUnit,
"0px",
]);
} else {
setColumns([
SIDEBAR_WIDTH,
"255px",
(windowWidth -
APP_SIDEBAR_WIDTH -
255 +
"px") as AnimatedGridUnit,
"0px",
]);
}
break;
case EditorState.EDITOR:
if (isPreviewMode || isProtectedMode) {
setColumns([
"0px",
(editorStateLeftPaneWidth + "px") as AnimatedGridUnit,
(windowWidth + "px") as AnimatedGridUnit,
"0px",
]);
} else if (segment !== EditorEntityTab.UI) {
if (editorMode === EditorViewMode.SplitScreen) {
setColumns([
SIDEBAR_WIDTH,
(editorStateLeftPaneWidth + "px") as AnimatedGridUnit,
(windowWidth -
APP_SIDEBAR_WIDTH -
editorStateLeftPaneWidth +
"px") as AnimatedGridUnit,
"0px",
]);
} else {
setColumns([
SIDEBAR_WIDTH,
(editorStateLeftPaneWidth + "px") as AnimatedGridUnit,
"0px",
"0px",
]);
}
} else {
setColumns([
SIDEBAR_WIDTH,
(editorStateLeftPaneWidth + "px") as AnimatedGridUnit,
(windowWidth -
APP_SIDEBAR_WIDTH -
editorStateLeftPaneWidth -
PropertyPaneWidth +
1 +
"px") as AnimatedGridUnit,
(PropertyPaneWidth + 1 + "px") as AnimatedGridUnit,
]);
}
}
},
[
appState,
isPreviewMode,
isProtectedMode,
editorStateLeftPaneWidth,
PropertyPaneWidth,
segment,
editorMode,
windowWidth,
],
);
return { areas, columns, rows };
}
export { useGridLayoutTemplate };

View File

@ -0,0 +1,2 @@
export { AnimatedLayout } from "./AnimatedLayout";
export { UnanimatedLayout } from "./UnanimatedLayout";

View File

@ -98,7 +98,7 @@ const DataSidePane = (props: DataSidePaneProps) => {
borderRight="1px solid var(--ads-v2-color-border)"
flexDirection="column"
height="100%"
width="300px"
width="100%"
>
<PaneHeader
rightIcon={

View File

@ -6,7 +6,6 @@ import { selectLibrariesForExplorer } from "ee/selectors/entitiesSelector";
import { animated, useTransition } from "react-spring";
import { LibraryEntity } from "pages/Editor/Explorer/Libraries";
import { Flex } from "@appsmith/ads";
import { DEFAULT_EXPLORER_PANE_WIDTH } from "constants/AppConstants";
const LibrarySidePane = () => {
const libraries = useSelector(selectLibrariesForExplorer);
@ -21,7 +20,7 @@ const LibrarySidePane = () => {
borderRight="1px solid var(--ads-v2-color-border)"
flexDirection="column"
height="100%"
width={DEFAULT_EXPLORER_PANE_WIDTH + "px"}
width={"100%"}
>
<PaneHeader
rightIcon={<AddLibraryPopover />}

View File

@ -20,6 +20,7 @@ export const LeftPaneContainer = styled.div<{ showRightBorder?: boolean }>`
border-right: ${({ showRightBorder = true }) =>
showRightBorder ? "1px solid var(--ads-v2-color-border)" : "none"};
background: var(--ads-v2-color-bg);
overflow: hidden;
`;
const LeftPane = () => {

View File

@ -12,7 +12,7 @@ export const MainPane = (props: { id: string }) => {
return (
<div
className="relative flex flex-col flex-1 overflow-auto z-2"
className="relative flex flex-col flex-1 overflow-auto z-2 h-full"
data-testid="t--ide-main-pane"
id={props.id}
>

View File

@ -7,12 +7,15 @@ import IDE from ".";
import { BrowserRouter } from "react-router-dom";
import "@testing-library/jest-dom";
import { ReduxActionTypes } from "ee/constants/ReduxActionConstants";
import store from "store";
// TODO: Fix this the next time the file is edited
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const getMockStore = (override: Record<string, any> = {}): any => {
const initialState = store.getState();
const slice = {
ui: {
...initialState.ui,
applications: {
currentApplication: {
gitApplicationMetadata: {
@ -32,6 +35,7 @@ const getMockStore = (override: Record<string, any> = {}): any => {
const mockStore = configureStore([]);
const newSlice = merge(slice, override);
return mockStore({
...initialState,
...newSlice,
});
};

View File

@ -19,8 +19,10 @@ import {
createMessage,
} from "ee/constants/messages";
export const PROTECTED_CALLOUT_HEIGHT = 70;
const StyledCallout = styled(Callout)`
height: 70px;
height: ${PROTECTED_CALLOUT_HEIGHT}px;
overflow-y: hidden;
`;

View File

@ -4,13 +4,10 @@ import {
EditorEntityTab,
EditorEntityTabState,
EditorState,
EditorViewMode,
} from "ee/entities/IDE/constants";
import { useLocation } from "react-router";
import { FocusEntity, identifyEntityFromPath } from "navigation/FocusEntity";
import { useDispatch, useSelector } from "react-redux";
import { getIDEViewMode } from "selectors/ideSelectors";
import { getPropertyPaneWidth } from "selectors/propertyPaneSelectors";
import history, { NavigationMethod } from "utils/history";
import {
builderURL,
@ -20,11 +17,6 @@ import {
} from "ee/RouteBuilder";
import { getCurrentFocusInfo } from "selectors/focusHistorySelectors";
import { getCurrentGitBranch } from "selectors/gitSyncSelectors";
import {
APP_SIDEBAR_WIDTH,
DEFAULT_EXPLORER_PANE_WIDTH,
SPLIT_SCREEN_RATIO,
} from "constants/AppConstants";
import { getIsAltFocusWidget, getWidgetSelectionBlock } from "selectors/ui";
import { altFocusWidget, setWidgetSelectionBlock } from "actions/widgetActions";
import { useJSAdd } from "ee/pages/Editor/IDE/EditorPane/JS/hooks";
@ -36,7 +28,6 @@ import { closeJSActionTab } from "actions/jsActionActions";
import { closeQueryActionTab } from "actions/pluginActionActions";
import { getCurrentBasePageId } from "selectors/editorSelectors";
import { getCurrentEntityInfo } from "../utils";
import useWindowDimensions from "../../../utils/hooks/useWindowDimensions";
export const useCurrentAppState = () => {
const [appState, setAppState] = useState(EditorState.EDITOR);
@ -75,32 +66,6 @@ export const useCurrentEditorState = () => {
};
};
export const useEditorPaneWidth = (): string => {
const [windowWidth] = useWindowDimensions();
const [width, setWidth] = useState(windowWidth - APP_SIDEBAR_WIDTH + "px");
const editorMode = useSelector(getIDEViewMode);
const { segment } = useCurrentEditorState();
const propertyPaneWidth = useSelector(getPropertyPaneWidth);
useEffect(() => {
if (editorMode === EditorViewMode.SplitScreen) {
if (segment !== EditorEntityTab.UI) {
// 1px is propertypane border width
setWidth(windowWidth * SPLIT_SCREEN_RATIO + "px");
} else {
setWidth(DEFAULT_EXPLORER_PANE_WIDTH + "px");
}
} else {
if (segment !== EditorEntityTab.UI) {
setWidth(windowWidth - APP_SIDEBAR_WIDTH + "px");
} else {
setWidth(DEFAULT_EXPLORER_PANE_WIDTH + "px");
}
}
}, [editorMode, segment, propertyPaneWidth, windowWidth]);
return width;
};
export const useSegmentNavigation = (): {
onSegmentChange: (value: string) => void;
} => {

View File

@ -1,61 +1,28 @@
import React from "react";
import { selectFeatureFlagCheck } from "ee/selectors/featureFlagsSelectors";
import { AnimatedLayout, UnanimatedLayout } from "./Layout";
import { useSelector } from "react-redux";
import type { AppState } from "ee/reducers";
import { FEATURE_FLAG } from "ee/entities/FeatureFlag";
import BottomBar from "components/BottomBar";
import {
combinedPreviewModeSelector,
previewModeSelector,
} from "selectors/editorSelectors";
import EditorWrapperContainer from "../commons/EditorWrapperContainer";
import Sidebar from "pages/Editor/IDE/Sidebar";
import LeftPane from "./LeftPane";
import MainPane from "./MainPane";
import RightPane from "./RightPane";
import classNames from "classnames";
import { tailwindLayers } from "constants/Layers";
import { protectedModeSelector } from "selectors/gitSyncSelectors";
import ProtectedCallout from "./ProtectedCallout";
const checkAnimatedIDEFlagValue = (state: AppState) => {
return selectFeatureFlagCheck(
state,
FEATURE_FLAG.release_ide_animations_enabled,
);
};
/**
* OldName: MainContainer
*/
function IDE() {
const isPreviewMode = useSelector(previewModeSelector);
const isCombinedPreviewMode = useSelector(combinedPreviewModeSelector);
const isProtectedMode = useSelector(protectedModeSelector);
return (
<>
{isProtectedMode && <ProtectedCallout />}
<EditorWrapperContainer>
<div
className={classNames({
[`transition-transform transform duration-400 flex h-full ${tailwindLayers.entityExplorer}`]:
true,
relative: !isCombinedPreviewMode,
"-translate-x-full fixed": isCombinedPreviewMode,
})}
>
<Sidebar />
<LeftPane />
</div>
<MainPane id="app-body" />
<div
className={classNames({
[`transition-transform transform duration-400 h-full ${tailwindLayers.propertyPane}`]:
true,
relative: !isCombinedPreviewMode,
"translate-x-full fixed right-0": isCombinedPreviewMode,
})}
>
<RightPane />
</div>
</EditorWrapperContainer>
<BottomBar viewMode={isPreviewMode} />
</>
);
const isAnimatedIDEEnabled = useSelector(checkAnimatedIDEFlagValue);
if (isAnimatedIDEEnabled) {
return <AnimatedLayout />;
}
return <UnanimatedLayout />;
}
IDE.displayName = "AppsmithIDE";
IDE.displayName = "AppIDE";
export default React.memo(IDE);

View File

@ -6,6 +6,7 @@ import {
RUN_GUTTER_ID,
} from "./constants";
import { thinScrollbar } from "constants/DefaultTheme";
import { IDE_HEADER_HEIGHT } from "IDE";
export const CodeEditorWithGutterStyles = css`
.${RUN_GUTTER_ID} {
@ -31,7 +32,7 @@ export const CodeEditorWithGutterStyles = css`
`;
export const FormWrapper = styled.div`
height: ${({ theme }) => `calc(100vh - ${theme.smallHeaderHeight})`};
height: calc(100vh - ${IDE_HEADER_HEIGHT}px);
overflow: hidden;
.${JS_OBJECT_HOTKEYS_CLASSNAME} {
width: 100%;

View File

@ -19,7 +19,10 @@ import useInteractionAnalyticsEvent from "utils/hooks/useInteractionAnalyticsEve
import type { WidgetType } from "constants/WidgetConstants";
import { ReduxActionTypes } from "ee/constants/ReduxActionConstants";
import { getIsCurrentWidgetRecentlyAdded } from "selectors/propertyPaneSelectors";
import {
getIsCurrentWidgetRecentlyAdded,
getPropertyPaneWidth,
} from "selectors/propertyPaneSelectors";
interface PropertyPaneTitleProps {
title: string;
@ -63,6 +66,7 @@ const PropertyPaneTitle = memo(function PropertyPaneTitle(
const isCurrentWidgetRecentlyAdded = useSelector(
getIsCurrentWidgetRecentlyAdded,
);
const width = useSelector(getPropertyPaneWidth);
const { dispatchInteractionAnalyticsEvent, eventEmitterRef } =
useInteractionAnalyticsEvent<HTMLDivElement>();
@ -160,8 +164,9 @@ const PropertyPaneTitle = memo(function PropertyPaneTitle(
return props.widgetId || props.isPanelTitle ? (
<div
className="flex items-center w-full px-4 py-3 space-x-1 fixed bg-white z-3"
className="flex items-center px-4 py-3 space-x-1 fixed bg-white z-3"
ref={eventEmitterRef}
style={{ width: width + "px" }}
>
{/* BACK BUTTON */}
{props.isPanelTitle && (

View File

@ -7,6 +7,13 @@ import { useSelector } from "react-redux";
import { getIsAppSettingsPaneWithNavigationTabOpen } from "selectors/appSettingsPaneSelectors";
import { EditorState } from "ee/entities/IDE/constants";
import { RenderModes } from "constants/WidgetConstants";
import styled from "styled-components";
import { IDE_HEADER_HEIGHT } from "IDE";
import { BOTTOM_BAR_HEIGHT } from "components/BottomBar/constants";
const Container = styled.div`
height: calc(100vh - ${IDE_HEADER_HEIGHT} - ${BOTTOM_BAR_HEIGHT});
`;
/**
* WidgetEditorContainer
@ -21,7 +28,7 @@ export const WidgetEditorContainer = (props: { children: ReactNode }) => {
appState === EditorState.SETTINGS && isNavigationSelectedInSettings;
return (
<EditorContextProvider renderMode={RenderModes.CANVAS}>
<div className="relative flex flex-row h-full w-full overflow-hidden">
<Container className="relative flex flex-row h-full w-full overflow-hidden">
<div
className={classNames({
"relative flex flex-col w-full overflow-hidden": true,
@ -31,7 +38,7 @@ export const WidgetEditorContainer = (props: { children: ReactNode }) => {
>
{props.children}
</div>
</div>
</Container>
</EditorContextProvider>
);
};

View File

@ -1,8 +1,5 @@
import { setPropertyPaneWidthAction } from "actions/propertyPaneActions";
import React from "react";
import PropertyPaneSidebar from "components/editorComponents/PropertyPaneSidebar";
import React, { useCallback } from "react";
import { useDispatch, useSelector } from "react-redux";
import { getPropertyPaneWidth } from "selectors/propertyPaneSelectors";
import { CreateNewQueryModal } from "pages/Editor/IDE/RightPane/components/CreateNewQueryModal";
/**
@ -12,32 +9,9 @@ import { CreateNewQueryModal } from "pages/Editor/IDE/RightPane/components/Creat
* It is used to handle the width of the property pane sidebar.
*/
function PropertyPaneWrapper() {
const dispatch = useDispatch();
const propertyPaneWidth = useSelector(getPropertyPaneWidth);
/**
* on property pane sidebar drag end
*
* @return void
*/
const onRightSidebarDragEnd = useCallback(() => {
dispatch(setPropertyPaneWidthAction(propertyPaneWidth));
}, [propertyPaneWidth]);
/**
* on property pane sidebar width change
*/
const onRightSidebarWidthChange = useCallback((newWidth) => {
dispatch(setPropertyPaneWidthAction(newWidth));
}, []);
return (
<>
<PropertyPaneSidebar
onDragEnd={onRightSidebarDragEnd}
onWidthChange={onRightSidebarWidthChange}
width={propertyPaneWidth}
/>
<PropertyPaneSidebar />
<CreateNewQueryModal />
</>
);

View File

@ -1,6 +1,7 @@
import styled from "styled-components";
import { Profile } from "pages/common/ProfileImage";
import { getTypographyByKey } from "@appsmith/ads-old";
import { IDE_HEADER_HEIGHT } from "IDE";
export const HeaderWrapper = styled.div`
width: 100%;
@ -10,7 +11,7 @@ export const HeaderWrapper = styled.div`
flex-direction: row;
box-shadow: none;
border-bottom: 1px solid var(--ads-v2-color-border);
height: ${(props) => props.theme.smallHeaderHeight};
height: ${IDE_HEADER_HEIGHT}px;
& .editable-application-name {
${getTypographyByKey("h4")}
color: ${(props) => props.theme.colors.header.appName};

View File

@ -1,4 +1,3 @@
import { APP_SETTINGS_PANE_WIDTH } from "constants/AppConstants";
import React from "react";
import styled from "styled-components";
import PaneHeader from "../IDE/LeftPane/PaneHeader";
@ -10,7 +9,7 @@ type EditorSettingsPaneContainerProps = React.PropsWithChildren<{
const SettingsPageWrapper = styled.div`
display: flex;
flex-direction: column;
width: ${APP_SETTINGS_PANE_WIDTH}px;
width: 100%;
&:nth-child(2) {
height: 100%;

View File

@ -4,6 +4,9 @@ import classNames from "classnames";
import { useSelector } from "react-redux";
import { combinedPreviewModeSelector } from "../../../selectors/editorSelectors";
import { protectedModeSelector } from "selectors/gitSyncSelectors";
import { IDE_HEADER_HEIGHT } from "../../../IDE";
import { BOTTOM_BAR_HEIGHT } from "../../../components/BottomBar/constants";
import { PROTECTED_CALLOUT_HEIGHT } from "../IDE/ProtectedCallout";
interface EditorWrapperContainerProps {
children: React.ReactNode;
@ -14,9 +17,9 @@ const Wrapper = styled.div<{
}>`
display: flex;
height: calc(
100vh - ${(props) => props.theme.smallHeaderHeight} -
${(props) => props.theme.bottomBarHeight} -
${(props) => (props.isProtectedMode ? "70px" : "0px")}
100vh - ${IDE_HEADER_HEIGHT}px - ${BOTTOM_BAR_HEIGHT}px -
${(props) =>
props.isProtectedMode ? PROTECTED_CALLOUT_HEIGHT + "px" : "0px"}
);
background-color: ${(props) => props.theme.appBackground};
`;

View File

@ -3,13 +3,14 @@ import styled from "styled-components";
import { snipingModeSelector } from "selectors/editorSelectors";
import { retryPromise } from "utils/AppsmithUtils";
import { useSelector } from "react-redux";
import { IDE_HEADER_HEIGHT } from "IDE";
const BindingBanner = styled.div`
position: fixed;
width: 199px;
height: 36px;
left: 50%;
top: ${(props) => props.theme.smallHeaderHeight};
top: ${IDE_HEADER_HEIGHT}px;
transform: translate(-50%, 0);
text-align: center;
background: var(--ads-v2-color-fg-information);

View File

@ -17,6 +17,7 @@ import { Colors } from "constants/Colors";
import ConflictInfo from "../components/ConflictInfo";
import { getCurrentAppGitMetaData } from "ee/selectors/applicationSelectors";
import { Button } from "@appsmith/ads";
import { BOTTOM_BAR_HEIGHT } from "../../../../components/BottomBar/constants";
const StyledGitErrorPopup = styled.div`
& {
@ -31,7 +32,7 @@ const StyledGitErrorPopup = styled.div`
.${Classes.OVERLAY_CONTENT} {
overflow: hidden;
bottom: ${(props) =>
`calc(${props.theme.bottomBarHeight} + ${props.theme.spaces[3]}px)`};
`calc(${BOTTOM_BAR_HEIGHT}px + ${props.theme.spaces[3]}px)`};
left: ${(props) => props.theme.spaces[3]}px;
background-color: ${Colors.WHITE};
}

View File

@ -50,6 +50,7 @@ import { PartialExportModal } from "components/editorComponents/PartialImportExp
import { PartialImportModal } from "components/editorComponents/PartialImportExport/PartialImportModal";
import type { Page } from "entities/Page";
import { AppCURLImportModal } from "ee/pages/Editor/CurlImport";
import { IDE_HEADER_HEIGHT } from "IDE";
interface EditorProps {
currentApplicationId?: string;
@ -175,7 +176,7 @@ class Editor extends Component<Props> {
if (!this.props.isEditorInitialized || this.props.loadingGuidedTour) {
return (
<CenteredWrapper
style={{ height: `calc(100vh - ${theme.smallHeaderHeight})` }}
style={{ height: `calc(100vh - ${IDE_HEADER_HEIGHT}px)` }}
>
<Spinner size="lg" />
</CenteredWrapper>

View File

@ -10631,6 +10631,13 @@ __metadata:
languageName: node
linkType: hard
"@types/dom-view-transitions@npm:^1.0.5":
version: 1.0.5
resolution: "@types/dom-view-transitions@npm:1.0.5"
checksum: 4190915a3d4c63d4c590d5e64d14ca1d1140496a75adb5af64b0ef13e075cc7676bff926f5c5c60305c4f6d46965a196c119a7960cbe0ff40e95e17e82334c22
languageName: node
linkType: hard
"@types/dom4@npm:^2.0.1":
version: 2.0.2
resolution: "@types/dom4@npm:2.0.2"
@ -13214,6 +13221,7 @@ __metadata:
"@types/d3-geo": ^3.1.0
"@types/deep-diff": ^1.0.0
"@types/dom-mediacapture-record": ^1.0.11
"@types/dom-view-transitions": ^1.0.5
"@types/downloadjs": ^1.4.2
"@types/google.maps": ^3.51.0
"@types/jest": ^27.4.1