From 24381dd1638278dc78cde1bd1386a5f73e0cbb4a Mon Sep 17 00:00:00 2001 From: Trisha Anand Date: Thu, 23 May 2024 11:38:07 +0530 Subject: [PATCH] Revert "feat: Collapsible Bottom View (#33441)" This reverts commit dbb07b879f6b093a85854edc689d90673aee0bc9. --- .../cypress/support/Pages/DebuggerHelper.ts | 7 +- .../src/IDE/Components/BottomView.test.tsx | 227 ------------------ app/client/src/IDE/Components/BottomView.tsx | 153 ------------ app/client/src/IDE/Interfaces/View.ts | 26 -- app/client/src/IDE/index.ts | 36 +-- .../editorComponents/ApiResponseView.tsx | 94 ++++++-- .../Debugger/DebuggerTabs.tsx | 70 +++++- .../Debugger/Resizer/index.tsx | 6 +- .../editorComponents/EntityBottomTabs.tsx | 20 +- .../editorComponents/JSResponseView.tsx | 98 ++++++-- .../Editor/APIEditor/CommonEditorForm.tsx | 2 +- .../pages/Editor/DataSourceEditor/DBForm.tsx | 3 +- .../Editor/DataSourceEditor/Debugger.tsx | 73 +++++- app/client/src/pages/Editor/JSEditor/Form.tsx | 2 +- .../pages/Editor/JSEditor/styledComponents.ts | 5 +- .../Editor/QueryEditor/QueryDebuggerTabs.tsx | 62 +++-- 16 files changed, 340 insertions(+), 544 deletions(-) delete mode 100644 app/client/src/IDE/Components/BottomView.test.tsx delete mode 100644 app/client/src/IDE/Components/BottomView.tsx delete mode 100644 app/client/src/IDE/Interfaces/View.ts diff --git a/app/client/cypress/support/Pages/DebuggerHelper.ts b/app/client/cypress/support/Pages/DebuggerHelper.ts index 2dabfb707112..9be425333064 100644 --- a/app/client/cypress/support/Pages/DebuggerHelper.ts +++ b/app/client/cypress/support/Pages/DebuggerHelper.ts @@ -12,12 +12,17 @@ export class DebuggerHelper { private agHelper = ObjectsRegistry.AggregateHelper; private commonLocators = ObjectsRegistry.CommonLocators; + // ActionExecutionResizerHeight -> in repo + private readonly bottomPaneHeight = 360; + // from design system + private readonly TAB_MIN_HEIGHT = 36; + public readonly locators = { _debuggerIcon: ".t--debugger-count", _debuggerToggle: "[data-testid=t--debugger-toggle]", _debuggerDownStreamErrMsg: "[data-testid=t--debugger-downStreamErrorMsg]", _tabsContainer: ".t--debugger-tabs-container", - _closeButton: "[data-testid=t--view-hide-button]", + _closeButton: ".t--close-debugger", _logMessage: ".t--debugger-log-message", _logEntityLink: ".t--debugger-log-entity-link", _logState: ".t--debugger-log-state", diff --git a/app/client/src/IDE/Components/BottomView.test.tsx b/app/client/src/IDE/Components/BottomView.test.tsx deleted file mode 100644 index 83d1a36aa5d1..000000000000 --- a/app/client/src/IDE/Components/BottomView.test.tsx +++ /dev/null @@ -1,227 +0,0 @@ -import React from "react"; -import { act, fireEvent, render } from "@testing-library/react"; -import BottomView from "./BottomView"; -import { ViewHideBehaviour } from "../Interfaces/View"; -import { noop } from "lodash"; -import "@testing-library/jest-dom"; -import "jest-styled-components"; - -describe("BottomView", () => { - describe("ViewHideBehaviour.COLLAPSE", () => { - // HIDDEN = FALSE - it("it is visible when hidden = false", () => { - const { getByText } = render( - , - ); - - expect(getByText("Hey test")).toBeTruthy(); - }); - it("it can be toggled when hidden = false", () => { - const onViewHideToggle = jest.fn(); - const { getByRole } = render( - , - ); - - const viewHideToggle = getByRole("button"); - act(() => { - fireEvent.click(viewHideToggle); - }); - expect(onViewHideToggle).toBeCalled(); - }); - - it("assert container height when hidden = false", () => { - const { container } = render( - , - ); - - expect(container.children[0]).toHaveAttribute("style", "height: 300px;"); - }); - - // HIDDEN = TRUE - it("it is visible when hidden = true", () => { - const { getByText } = render( - , - ); - - expect(getByText("Hey test")).toBeTruthy(); - }); - - it("it can be toggled when hidden = true", () => { - const onViewHideToggle = jest.fn(); - const { getByRole } = render( - , - ); - - const viewHideToggle = getByRole("button"); - act(() => { - fireEvent.click(viewHideToggle); - }); - expect(onViewHideToggle).toBeCalled(); - }); - - it("assert container height when hidden = true", () => { - const { container } = render( - , - ); - - expect(container.children[0]).toHaveAttribute("style", "height: 38px;"); - }); - }); - - describe("ViewHideBehaviour.CLOSE", () => { - // HIDDEN = FALSE - it("it is visible when hidden = false", () => { - const { getByText } = render( - , - ); - - expect(getByText("Hey test")).toBeTruthy(); - }); - it("it can be toggled when hidden = false", () => { - const onViewHideToggle = jest.fn(); - const { getByRole } = render( - , - ); - - const viewHideToggle = getByRole("button"); - act(() => { - fireEvent.click(viewHideToggle); - }); - expect(onViewHideToggle).toBeCalled(); - }); - - it("assert container height when hidden = false", () => { - const { container } = render( - , - ); - - expect(container.children[0]).toHaveAttribute("style", "height: 300px;"); - }); - - // HIDDEN = TRUE - it("it is visible when hidden = true", () => { - const { getByText } = render( - , - ); - - expect(getByText("Hey test")).toBeTruthy(); - }); - - it("it can be toggled when hidden = true", () => { - const onViewHideToggle = jest.fn(); - const { getByRole } = render( - , - ); - - const viewHideToggle = getByRole("button"); - act(() => { - fireEvent.click(viewHideToggle); - }); - expect(onViewHideToggle).toBeCalled(); - }); - - it("assert container height when hidden = true", () => { - const { container } = render( - , - ); - - expect(container.children[0]).toHaveAttribute("style", "height: 0px;"); - }); - }); -}); diff --git a/app/client/src/IDE/Components/BottomView.tsx b/app/client/src/IDE/Components/BottomView.tsx deleted file mode 100644 index fe5bbb9e41b1..000000000000 --- a/app/client/src/IDE/Components/BottomView.tsx +++ /dev/null @@ -1,153 +0,0 @@ -import React, { useEffect, useRef, useState } from "react"; -import styled from "styled-components"; -import Resizer, { - ResizerCSS, -} from "components/editorComponents/Debugger/Resizer"; -import { CodeEditorWithGutterStyles } from "pages/Editor/JSEditor/constants"; -import { ViewHideBehaviour, ViewDisplayMode } from "IDE/Interfaces/View"; -import { Button } from "design-system"; - -const VIEW_MIN_HEIGHT = 38; - -const Container = styled.div<{ displayMode: ViewDisplayMode }>` - ${ResizerCSS}; - width: 100%; - background-color: var(--ads-v2-color-bg); - border-top: 1px solid var(--ads-v2-color-border); - ${(props) => { - switch (props.displayMode) { - case ViewDisplayMode.OVERLAY: - return ` - position: absolute; - bottom: 0; - `; - } - }} -`; - -const ViewWrapper = styled.div` - height: 100%; - &&& { - ul.ads-v2-tabs__list { - margin: 0 var(--ads-v2-spaces-8); - height: ${VIEW_MIN_HEIGHT}px; - } - } - - & { - .ads-v2-tabs__list { - padding: var(--ads-v2-spaces-1) var(--ads-v2-spaces-7); - } - } - - & { - .ads-v2-tabs__panel { - ${CodeEditorWithGutterStyles}; - overflow-y: auto; - height: 100%; - } - } -`; - -const MIN_HEIGHT = { - [ViewHideBehaviour.COLLAPSE]: `${VIEW_MIN_HEIGHT}px`, - [ViewHideBehaviour.CLOSE]: "0px", -}; - -interface Props { - className?: string; - behaviour: ViewHideBehaviour; - displayMode?: ViewDisplayMode; - height: number; - setHeight: (height: number) => void; - hidden: boolean; - onHideClick: () => void; - children: React.ReactNode; -} - -const ViewHideButton = styled(Button)` - &.view-hide-button { - position: absolute; - top: 3px; - right: 0; - padding: 9px 11px; - } -`; - -interface ViewHideProps { - hideBehaviour: ViewHideBehaviour; - isHidden: boolean; - onToggle: () => void; -} - -const ViewHide = (props: ViewHideProps) => { - const [icon, setIcon] = useState(() => { - return props.hideBehaviour === ViewHideBehaviour.CLOSE - ? "close-modal" - : "arrow-down-s-line"; - }); - - useEffect(() => { - if (props.hideBehaviour === ViewHideBehaviour.COLLAPSE) { - if (props.isHidden) { - setIcon("arrow-up-s-line"); - } else { - setIcon("arrow-down-s-line"); - } - } - }, [props.isHidden]); - - return ( - - ); -}; - -const BottomView = (props: Props) => { - const panelRef = useRef(null); - - // Handle the height of the view when toggling the hidden state - useEffect(() => { - const panel = panelRef.current; - if (!panel) return; - if (props.hidden) { - panel.style.height = MIN_HEIGHT[props.behaviour]; - } else { - panel.style.height = `${props.height}px`; - } - }, [props.hidden, props.behaviour]); - - return ( - - {!props.hidden && ( - - )} - - {props.children} - - - - ); -}; - -export default BottomView; diff --git a/app/client/src/IDE/Interfaces/View.ts b/app/client/src/IDE/Interfaces/View.ts deleted file mode 100644 index 0bfbff7391bb..000000000000 --- a/app/client/src/IDE/Interfaces/View.ts +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Close: - * - View is not visible at all - * - View is not interactable till opened again - * - * Collapse: - * - View is visible but cannot be resized - * - Top part of the view is visible with open to reopen it - * - Children can have extra view that changes when hidden that can have different behaviours - */ -export enum ViewHideBehaviour { - CLOSE = "CLOSE", - COLLAPSE = "COLLAPSE", -} - -/** - * OVERLAY: - * - Sets an absolute position to make the view render on top of other components - * - * BLOCK: - * - Sets a block position to make the view rendered next to other components - */ -export enum ViewDisplayMode { - OVERLAY = "OVERLAY", - BLOCK = "BLOCK", -} diff --git a/app/client/src/IDE/index.ts b/app/client/src/IDE/index.ts index 5568b8167342..1c44b527e457 100644 --- a/app/client/src/IDE/index.ts +++ b/app/client/src/IDE/index.ts @@ -1,7 +1,7 @@ -/* ==================================================== - **** Structural Components **** - Components that are part of the main structure of the IDE experience -====================================================**/ +/** + **** Structural Components **** + * Components that are part of the main structure of the IDE experience + **/ /** * The IDEHeader gets exported with 3 layout subsections. @@ -11,18 +11,18 @@ */ export { default as IDEHeader } from "./Structure/Header"; -/* ==================================================== - **** UI Components **** - Components that are smaller UI abstractions for easy use and standardisation within the IDE -=======================================================**/ +/** + **** UI Components **** + * Components that are smaller UI abstractions for easy use and standardisation within the IDE + **/ /** * IDEHeaderTitle is a small text styled wrapper that is suitable to be used inside IDEHeader */ export { default as IDEHeaderTitle } from "./Components/HeaderTitle"; /** - * IDEHeaderEditorSwitcher can be used for a trigger component to show a dropdown for pages, modules - * or any list of elements in the header E.g., Pages / Page 1 + * IDEHeaderEditorSwitcher can be used for trigger component to show a drop down for pages, modules + * or any list of elements in the header. Eg. Pages / Page 1 */ export { default as IDEHeaderEditorSwitcher } from "./Components/HeaderEditorSwitcher"; /** @@ -33,16 +33,6 @@ export { default as IDEHeaderEditorSwitcher } from "./Components/HeaderEditorSwi */ export { default as IDEHeaderDropdown } from "./Components/HeaderDropdown"; /** - * IDEBottomView is a versatile view meant to be at the bottom of the screen. - * It is resizable and can be hidden or collapsed based on the behavior configured - * The view is designed for showing tabs, but this component does not assume this can - * accept any view to be rendered - */ -export { default as IDEBottomView } from "./Components/BottomView"; - -/* ==================================================== - **** Interfaces **** - Common types that are used by the different components of the IDE -=======================================================**/ - -export { ViewHideBehaviour, ViewDisplayMode } from "./Interfaces/View"; + **** Interfaces **** + * Common types that are used by the different components of the IDE + **/ diff --git a/app/client/src/components/editorComponents/ApiResponseView.tsx b/app/client/src/components/editorComponents/ApiResponseView.tsx index bb5d065f3e23..7d4db11998d2 100644 --- a/app/client/src/components/editorComponents/ApiResponseView.tsx +++ b/app/client/src/components/editorComponents/ApiResponseView.tsx @@ -1,4 +1,5 @@ -import React, { useCallback, useState } from "react"; +import type { RefObject } from "react"; +import React, { useCallback, useRef, useState } from "react"; import { useDispatch, useSelector } from "react-redux"; import ReactJson from "react-json-view"; import styled from "styled-components"; @@ -21,8 +22,9 @@ import { EditorTheme } from "./CodeEditor/EditorConfig"; import NoResponseSVG from "assets/images/no-response.svg"; import DebuggerLogs from "./Debugger/DebuggerLogs"; import ErrorLogs from "./Debugger/Errors"; +import Resizer, { ResizerCSS } from "./Debugger/Resizer"; import AnalyticsUtil from "@appsmith/utils/AnalyticsUtil"; -import { Classes, Text, TextType } from "design-system-old"; +import { Classes, TAB_MIN_HEIGHT, Text, TextType } from "design-system-old"; import { Button, Callout, Flex, SegmentedControl } from "design-system"; import type { BottomTab } from "./EntityBottomTabs"; import EntityBottomTabs from "./EntityBottomTabs"; @@ -43,6 +45,7 @@ import { getUpdateTimestamp } from "./Debugger/ErrorLogs/ErrorLogItem"; import type { Action } from "entities/Action"; import { SegmentedControlContainer } from "../../pages/Editor/QueryEditor/EditorJSONtoForm"; import ActionExecutionInProgressView from "./ActionExecutionInProgressView"; +import { CloseDebugger } from "./Debugger/DebuggerTabs"; import { EMPTY_RESPONSE } from "./emptyResponse"; import { setApiPaneDebuggerState } from "actions/apiPaneActions"; import { getApiPaneDebuggerState } from "selectors/apiPaneSelectors"; @@ -50,7 +53,18 @@ import { getIDEViewMode } from "selectors/ideSelectors"; import { EditorViewMode } from "@appsmith/entities/IDE/constants"; import ApiResponseMeta from "./ApiResponseMeta"; import useDebuggerTriggerClick from "./Debugger/hooks/useDebuggerTriggerClick"; -import { IDEBottomView, ViewHideBehaviour } from "IDE"; + +const ResponseContainer = styled.div` + ${ResizerCSS}; + width: 100%; + // Minimum height of bottom tabs as it can be resized + min-height: 36px; + background-color: var(--ads-v2-color-bg); + border-top: 1px solid var(--ads-v2-color-border); + .CodeMirror-code { + font-size: 12px; + } +`; const ResponseTabWrapper = styled.div` display: flex; @@ -63,6 +77,28 @@ const ResponseTabWrapper = styled.div` } `; +const TabbedViewWrapper = styled.div` + height: 100%; + &&& { + ul.ads-v2-tabs__list { + margin: 0 ${(props) => props.theme.spaces[11]}px; + height: ${TAB_MIN_HEIGHT}; + } + } + + & { + .ads-v2-tabs__list { + padding: var(--ads-v2-spaces-1) var(--ads-v2-spaces-7); + } + } + + & { + .ads-v2-tabs__panel { + height: calc(100% - ${TAB_MIN_HEIGHT}); + } + } +`; + const NoResponseContainer = styled.div` flex: 1; width: 100%; @@ -214,6 +250,7 @@ function ApiResponseView(props: Props) { ? actionResponse.statusCode[0] !== "2" : false; + const panelRef: RefObject = useRef(null); const dispatch = useDispatch(); const errorCount = useSelector(getErrorCount); const { open, responseTabHeight, selectedTab } = useSelector( @@ -312,7 +349,7 @@ function ApiResponseView(props: Props) { source: "API_PANE", }); } - dispatch(setApiPaneDebuggerState({ open: true, selectedTab: tabKey })); + dispatch(setApiPaneDebuggerState({ selectedTab: tabKey })); }, []); // update the height of the response pane on resize. @@ -499,28 +536,41 @@ function ApiResponseView(props: Props) { // close the debugger //TODO: move this to a common place - const toggleHide = useCallback( - () => dispatch(setApiPaneDebuggerState({ open: !open })), - [open], - ); + const onClose = () => dispatch(setApiPaneDebuggerState({ open: false })); + + if (!open) return null; return ( - + + + + + ); } diff --git a/app/client/src/components/editorComponents/Debugger/DebuggerTabs.tsx b/app/client/src/components/editorComponents/Debugger/DebuggerTabs.tsx index 38ebc0a2c0a5..490454018920 100644 --- a/app/client/src/components/editorComponents/Debugger/DebuggerTabs.tsx +++ b/app/client/src/components/editorComponents/Debugger/DebuggerTabs.tsx @@ -1,4 +1,6 @@ -import React, { useCallback } from "react"; +import type { RefObject } from "react"; +import React, { useRef, useCallback } from "react"; +import styled from "styled-components"; import DebuggerLogs from "./DebuggerLogs"; import { useDispatch, useSelector } from "react-redux"; import { @@ -13,6 +15,7 @@ import { } from "selectors/debuggerSelectors"; import AnalyticsUtil from "@appsmith/utils/AnalyticsUtil"; import Errors from "./Errors"; +import Resizer, { ResizerCSS } from "./Resizer"; import EntityDeps from "./EntityDependecies"; import { createMessage, @@ -20,13 +23,44 @@ import { DEBUGGER_LOGS, INSPECT_ENTITY, } from "@appsmith/constants/messages"; +import { stopEventPropagation } from "utils/AppsmithUtils"; import { DEBUGGER_TAB_KEYS } from "./helpers"; +import { Colors } from "constants/Colors"; import EntityBottomTabs from "../EntityBottomTabs"; import { ActionExecutionResizerHeight } from "pages/Editor/APIEditor/constants"; -import { IDEBottomView, ViewHideBehaviour, ViewDisplayMode } from "IDE"; +import { Button } from "design-system"; + +const TABS_HEADER_HEIGHT = 36; + +export const CloseDebugger = styled(Button)` + &.close-debugger { + position: absolute; + top: 3px; + right: 0px; + padding: 9px 11px; + } +`; + +const Container = styled.div` + ${ResizerCSS}; + position: absolute; + bottom: 0; + height: ${ActionExecutionResizerHeight}px; + min-height: ${TABS_HEADER_HEIGHT}px; + background-color: ${(props) => props.theme.colors.debugger.background}; + border-top: 1px solid ${Colors.ALTO}; + + ul.ads-v2-tabs__list { + padding: 0px ${(props) => props.theme.spaces[12]}px; + } + .ads-v2-tabs__panel { + height: calc(100% - ${TABS_HEADER_HEIGHT}px); + } +`; function DebuggerTabs() { const dispatch = useDispatch(); + const panelRef: RefObject = useRef(null); const selectedTab = useSelector(getDebuggerSelectedTab); // fetch the error count from the store. const errorCount = useSelector(getErrorCount); @@ -72,24 +106,36 @@ function DebuggerTabs() { selectedTab === DEBUGGER_TAB_KEYS.SCHEMA_TAB ); - return ( - - ); + + + ) : null; } export default DebuggerTabs; diff --git a/app/client/src/components/editorComponents/Debugger/Resizer/index.tsx b/app/client/src/components/editorComponents/Debugger/Resizer/index.tsx index 12310a3b96c4..6bb3e102540e 100644 --- a/app/client/src/components/editorComponents/Debugger/Resizer/index.tsx +++ b/app/client/src/components/editorComponents/Debugger/Resizer/index.tsx @@ -24,7 +24,6 @@ interface ResizerProps { snapToHeight?: number; openResizer?: boolean; initialHeight?: number; - minHeight?: number; } function Resizer(props: ResizerProps) { @@ -53,10 +52,13 @@ function Resizer(props: ResizerProps) { const { height } = panel.getBoundingClientRect(); const updatedHeight = height - movementY; const headerHeightNumber = 35; + const minHeight = parseInt( + window.getComputedStyle(panel).minHeight.replace("px", ""), + ); if ( updatedHeight < window.innerHeight - headerHeightNumber && - updatedHeight > (props.minHeight || 0) + updatedHeight > minHeight ) { panel.style.height = `${height - movementY}px`; setHeight(height - movementY); diff --git a/app/client/src/components/editorComponents/EntityBottomTabs.tsx b/app/client/src/components/editorComponents/EntityBottomTabs.tsx index e31b3b802f33..cd6e69463d8f 100644 --- a/app/client/src/components/editorComponents/EntityBottomTabs.tsx +++ b/app/client/src/components/editorComponents/EntityBottomTabs.tsx @@ -37,7 +37,6 @@ interface EntityBottomTabsProps { tabs: Array; onSelect?: (tab: string) => void; selectedTabKey: string; - isCollapsed?: boolean; } type CollapsibleEntityBottomTabsProps = EntityBottomTabsProps & @@ -60,29 +59,12 @@ function EntityBottomTabs( } }; - // if (props.isCollapsed) { - // return ( - // - // {props.tabs.map((tab) => ( - // - // ))} - // - // ); - // } - return ( {props.tabs.map((tab) => { diff --git a/app/client/src/components/editorComponents/JSResponseView.tsx b/app/client/src/components/editorComponents/JSResponseView.tsx index 0cb6867524cf..d8e292b1fbfc 100644 --- a/app/client/src/components/editorComponents/JSResponseView.tsx +++ b/app/client/src/components/editorComponents/JSResponseView.tsx @@ -1,4 +1,11 @@ -import React, { useCallback, useEffect, useMemo, useState } from "react"; +import type { RefObject } from "react"; +import React, { + useCallback, + useEffect, + useMemo, + useRef, + useState, +} from "react"; import { connect, useDispatch, useSelector } from "react-redux"; import type { RouteComponentProps } from "react-router"; import { withRouter } from "react-router"; @@ -17,18 +24,22 @@ import { } from "@appsmith/constants/messages"; import type { EditorTheme } from "./CodeEditor/EditorConfig"; import DebuggerLogs from "./Debugger/DebuggerLogs"; +import Resizer, { ResizerCSS } from "./Debugger/Resizer"; import type { JSAction } from "entities/JSCollection"; import ReadOnlyEditor from "components/editorComponents/ReadOnlyEditor"; -import { Flex, Text } from "design-system"; +import { Text } from "design-system"; import LoadingOverlayScreen from "components/editorComponents/LoadingOverlayScreen"; import type { JSCollectionData } from "@appsmith/reducers/entityReducers/jsActionsReducer"; import type { EvaluationError } from "utils/DynamicBindingUtils"; import { DEBUGGER_TAB_KEYS } from "./Debugger/helpers"; import type { BottomTab } from "./EntityBottomTabs"; import EntityBottomTabs from "./EntityBottomTabs"; +import { TAB_MIN_HEIGHT } from "design-system-old"; +import { CodeEditorWithGutterStyles } from "pages/Editor/JSEditor/constants"; import { getIsSavingEntity } from "selectors/editorSelectors"; import { getJSResponseViewState } from "./utils"; import { getFilteredErrors } from "selectors/debuggerSelectors"; +import { ActionExecutionResizerHeight } from "pages/Editor/APIEditor/constants"; import { NoResponse, ResponseTabErrorContainer, @@ -36,8 +47,9 @@ import { } from "./ApiResponseView"; import LogHelper from "./Debugger/ErrorLogs/components/LogHelper"; import LOG_TYPE from "entities/AppsmithConsole/logtype"; -import type { Log, SourceEntity } from "entities/AppsmithConsole"; +import type { SourceEntity, Log } from "entities/AppsmithConsole"; import { ENTITY_TYPE } from "@appsmith/entities/AppsmithConsole/utils"; +import { CloseDebugger } from "./Debugger/DebuggerTabs"; import { getJsPaneDebuggerState } from "selectors/jsPaneSelectors"; import { setJsPaneDebuggerState } from "actions/jsPaneActions"; import { getIDEViewMode } from "selectors/ideSelectors"; @@ -45,7 +57,22 @@ import { EditorViewMode } from "@appsmith/entities/IDE/constants"; import ErrorLogs from "./Debugger/Errors"; import { isBrowserExecutionAllowed } from "@appsmith/utils/actionExecutionUtils"; import JSRemoteExecutionView from "@appsmith/components/JSRemoteExecutionView"; -import { IDEBottomView, ViewHideBehaviour } from "../../IDE"; + +const ResponseContainer = styled.div` + ${ResizerCSS}; + width: 100%; + // Minimum height of bottom tabs as it can be resized + min-height: ${TAB_MIN_HEIGHT}; + background-color: var(--ads-v2-color-bg); + height: ${ActionExecutionResizerHeight}px; + border-top: 1px solid var(--ads-v2-color-border); + + .ads-v2-tabs__panel { + ${CodeEditorWithGutterStyles}; + overflow-y: auto; + height: calc(100% - ${TAB_MIN_HEIGHT}); + } +`; const ResponseTabWrapper = styled.div` display: flex; @@ -61,6 +88,15 @@ const ResponseTabWrapper = styled.div` } `; +const TabbedViewWrapper = styled.div` + height: 100%; +`; + +const ResponseViewer = styled.div` + width: 100%; + padding: 0 var(--ads-v2-spaces-7); +`; + const NoReturnValueWrapper = styled.div` padding-left: ${(props) => props.theme.spaces[12]}px; padding-top: ${(props) => props.theme.spaces[6]}px; @@ -107,6 +143,7 @@ function JSResponseView(props: Props) { const responses = (jsCollectionData && jsCollectionData.data) || {}; const isDirty = (jsCollectionData && jsCollectionData.isDirty) || {}; const isExecuting = (jsCollectionData && jsCollectionData.isExecuting) || {}; + const panelRef: RefObject = useRef(null); const dispatch = useDispatch(); const response = currentFunction && currentFunction.id && currentFunction.id in responses @@ -211,7 +248,7 @@ function JSResponseView(props: Props) { )} - + <> {localExecutionAllowed && ( <> @@ -259,7 +296,7 @@ function JSResponseView(props: Props) { )} - + ), @@ -287,7 +324,7 @@ function JSResponseView(props: Props) { // set the selected tab in the store. const setSelectedResponseTab = useCallback((selectedTab: string) => { - dispatch(setJsPaneDebuggerState({ open: true, selectedTab })); + dispatch(setJsPaneDebuggerState({ selectedTab })); }, []); // set the height of the response pane on resize. const setResponseHeight = useCallback((height: number) => { @@ -295,29 +332,38 @@ function JSResponseView(props: Props) { }, []); // close the debugger - const onToggle = useCallback( - () => dispatch(setJsPaneDebuggerState({ open: !open })), - [open], - ); + const onClose = () => dispatch(setJsPaneDebuggerState({ open: false })); // Do not render if header tab is selected in the bottom bar. - return ( - - ); + + + + + + + ) : null; } const mapStateToProps = (state: AppState) => { diff --git a/app/client/src/pages/Editor/APIEditor/CommonEditorForm.tsx b/app/client/src/pages/Editor/APIEditor/CommonEditorForm.tsx index 7b668668fe35..732b343e38ed 100644 --- a/app/client/src/pages/Editor/APIEditor/CommonEditorForm.tsx +++ b/app/client/src/pages/Editor/APIEditor/CommonEditorForm.tsx @@ -155,7 +155,7 @@ const SettingsWrapper = styled.div` const Wrapper = styled.div` display: flex; flex-direction: row; - height: 100%; + height: calc(100% - 135px); position: relative; `; diff --git a/app/client/src/pages/Editor/DataSourceEditor/DBForm.tsx b/app/client/src/pages/Editor/DataSourceEditor/DBForm.tsx index 67cbba792d1b..52e55f7a0778 100644 --- a/app/client/src/pages/Editor/DataSourceEditor/DBForm.tsx +++ b/app/client/src/pages/Editor/DataSourceEditor/DBForm.tsx @@ -41,7 +41,8 @@ export const Form = styled.form<{ }>` display: flex; flex-direction: column; - ${(props) => !props.viewMode && `height: 100%`} + ${(props) => + !props.viewMode && `height: ${`calc(100% - ${props?.theme.backBanner})`};`} padding-bottom: var(--ads-v2-spaces-6); overflow-y: auto; margin-left: ${(props) => (props.viewMode ? "0px" : "24px")}; diff --git a/app/client/src/pages/Editor/DataSourceEditor/Debugger.tsx b/app/client/src/pages/Editor/DataSourceEditor/Debugger.tsx index ff04caa1e4af..b4e9ef1bbd47 100644 --- a/app/client/src/pages/Editor/DataSourceEditor/Debugger.tsx +++ b/app/client/src/pages/Editor/DataSourceEditor/Debugger.tsx @@ -1,4 +1,5 @@ -import React, { useCallback } from "react"; +import React, { useRef, useCallback } from "react"; +import type { RefObject } from "react"; import { useDispatch, useSelector } from "react-redux"; import styled from "styled-components"; import { @@ -12,10 +13,15 @@ import { setResponsePaneHeight, showDebugger, } from "actions/debuggerActions"; +import Resizable, { + ResizerCSS, +} from "components/editorComponents/Debugger/Resizer"; import EntityBottomTabs from "components/editorComponents/EntityBottomTabs"; import { DEBUGGER_TAB_KEYS } from "components/editorComponents/Debugger/helpers"; import Errors from "components/editorComponents/Debugger/Errors"; -import DebuggerLogs from "components/editorComponents/Debugger/DebuggerLogs"; +import DebuggerLogs, { + LIST_HEADER_HEIGHT, +} from "components/editorComponents/Debugger/DebuggerLogs"; import EntityDeps from "components/editorComponents/Debugger/EntityDependecies"; import { getDebuggerSelectedTab, @@ -23,7 +29,33 @@ import { getResponsePaneHeight, } from "selectors/debuggerSelectors"; import { ActionExecutionResizerHeight } from "../APIEditor/constants"; -import { IDEBottomView, ViewHideBehaviour } from "IDE"; +import { CloseDebugger } from "components/editorComponents/Debugger/DebuggerTabs"; + +export const TabbedViewContainer = styled.div` + ${ResizerCSS} + height: ${ActionExecutionResizerHeight}px; + // Minimum height of bottom tabs as it can be resized + min-height: 36px; + width: 100%; + .ads-v2-tabs__panel { + overflow: hidden; + } + .ads-v2-tabs__list { + margin: 0px; + } + &&& { + ul.ads-v2-tabs__list { + margin: 0px ${(props) => props.theme.spaces[11]}px; + background-color: ${(props) => + props.theme.colors.apiPane.responseBody.bg}; + } + .ads-v2-tabs__panel { + height: calc(100% - ${LIST_HEADER_HEIGHT}); + } + } + background-color: ${(props) => props.theme.colors.apiPane.responseBody.bg}; + border-top: 1px solid var(--ads-v2-color-border); +`; export const ResizerMainContainer = styled.div` display: flex; @@ -70,6 +102,8 @@ export const ResizerContentContainer = styled.div` export default function Debugger() { const dispatch = useDispatch(); + const panelRef: RefObject = useRef(null); + // fetch the height of the response pane from the store const responsePaneHeight = useSelector(getResponsePaneHeight); @@ -120,21 +154,34 @@ export default function Debugger() { selectedResponseTab === DEBUGGER_TAB_KEYS.SCHEMA_TAB ); - return ( - - ); + + + + ) : null; } diff --git a/app/client/src/pages/Editor/JSEditor/Form.tsx b/app/client/src/pages/Editor/JSEditor/Form.tsx index 0bed695763c8..2c6ce6031bf1 100644 --- a/app/client/src/pages/Editor/JSEditor/Form.tsx +++ b/app/client/src/pages/Editor/JSEditor/Form.tsx @@ -88,7 +88,7 @@ type Props = JSFormProps; const Wrapper = styled.div` display: flex; flex-direction: row; - height: 100%; + height: calc(100% - 64px); width: 100%; `; diff --git a/app/client/src/pages/Editor/JSEditor/styledComponents.ts b/app/client/src/pages/Editor/JSEditor/styledComponents.ts index 7281f698a0b0..9af05e866036 100644 --- a/app/client/src/pages/Editor/JSEditor/styledComponents.ts +++ b/app/client/src/pages/Editor/JSEditor/styledComponents.ts @@ -31,7 +31,8 @@ export const CodeEditorWithGutterStyles = css` `; export const FormWrapper = styled.div` - height: ${({ theme }) => `calc(100vh - ${theme.smallHeaderHeight})`}; + height: ${({ theme }) => + `calc(100vh - ${theme.smallHeaderHeight} - ${theme.backBanner})`}; overflow: hidden; .${JS_OBJECT_HOTKEYS_CLASSNAME} { width: 100%; @@ -42,7 +43,7 @@ export const FormWrapper = styled.div` export const Form = styled.form` display: flex; flex-direction: column; - height: 100%; + height: ${({ theme }) => `calc(100% - ${theme.backBanner})`}; overflow: hidden; .t--no-binding-prompt { display: none; diff --git a/app/client/src/pages/Editor/QueryEditor/QueryDebuggerTabs.tsx b/app/client/src/pages/Editor/QueryEditor/QueryDebuggerTabs.tsx index 8903a0d1a91a..4933c42c9409 100644 --- a/app/client/src/pages/Editor/QueryEditor/QueryDebuggerTabs.tsx +++ b/app/client/src/pages/Editor/QueryEditor/QueryDebuggerTabs.tsx @@ -1,10 +1,15 @@ +import { CloseDebugger } from "components/editorComponents/Debugger/DebuggerTabs"; import type { BottomTab } from "components/editorComponents/EntityBottomTabs"; import EntityBottomTabs from "components/editorComponents/EntityBottomTabs"; -import React, { useCallback, useEffect, useState } from "react"; +import React, { useCallback, useEffect, useRef, useState } from "react"; import { useDispatch, useSelector } from "react-redux"; import styled from "styled-components"; +import { ActionExecutionResizerHeight } from "pages/Editor/APIEditor/constants"; import { getErrorCount } from "selectors/debuggerSelectors"; import { Text, TextType } from "design-system-old"; +import Resizable, { + ResizerCSS, +} from "components/editorComponents/Debugger/Resizer"; import { DEBUGGER_TAB_KEYS } from "components/editorComponents/Debugger/helpers"; import { DEBUGGER_ERRORS, @@ -32,7 +37,6 @@ import { setQueryPaneDebuggerState } from "actions/queryPaneActions"; import { actionResponseDisplayDataFormats } from "../utils"; import { getIDEViewMode } from "selectors/ideSelectors"; import { EditorViewMode } from "@appsmith/entities/IDE/constants"; -import { IDEBottomView, ViewHideBehaviour } from "../../../IDE"; const ResultsCount = styled.div` position: absolute; @@ -41,6 +45,16 @@ const ResultsCount = styled.div` color: var(--ads-v2-color-fg); `; +export const TabbedViewContainer = styled.div` + ${ResizerCSS}; + height: ${ActionExecutionResizerHeight}px; + // Minimum height of bottom tabs as it can be resized + min-height: 36px; + width: 100%; + background-color: var(--ads-v2-color-bg); + border-top: 1px solid var(--ads-v2-color-border); +`; + interface QueryDebuggerTabsProps { actionSource: SourceEntity; currentActionConfig?: Action; @@ -63,6 +77,8 @@ function QueryDebuggerTabs({ showSchema, }: QueryDebuggerTabsProps) { let output: Record[] | null = null; + + const panelRef = useRef(null); const dispatch = useDispatch(); const { open, responseTabHeight, selectedTab } = useSelector( @@ -170,12 +186,12 @@ function QueryDebuggerTabs({ dispatch(setQueryPaneDebuggerState({ responseTabHeight: height })); }, []); - const onToggle = useCallback(() => { - dispatch(setQueryPaneDebuggerState({ open: !open })); - }, [open]); + const onClose = useCallback(() => { + dispatch(setQueryPaneDebuggerState({ open: false })); + }, []); const setSelectedResponseTab = useCallback((tabKey: string) => { - dispatch(setQueryPaneDebuggerState({ open: true, selectedTab: tabKey })); + dispatch(setQueryPaneDebuggerState({ selectedTab: tabKey })); }, []); const ideViewMode = useSelector(getIDEViewMode); @@ -228,15 +244,23 @@ function QueryDebuggerTabs({ }); } + if (!open) return null; + return ( - + + ); }