From 86392ead8f0a795e10c90a18656d3347f6a635d0 Mon Sep 17 00:00:00 2001 From: Hetu Nandu Date: Wed, 26 Jun 2024 12:58:41 +0530 Subject: [PATCH 01/13] Sync changes from EE excluding enterprise directory --- .../Components/Sidebar/SidebarButton.test.tsx | 22 +++++ .../IDE/Components/Sidebar/SidebarButton.tsx | 89 +++++++++++++++++++ .../src/IDE/Components/Sidebar/index.tsx | 75 ++++++++++++++++ app/client/src/IDE/index.ts | 9 ++ app/client/src/api/LibraryAPI.tsx | 2 +- app/client/src/ce/entities/IDE/constants.ts | 30 ++----- app/client/src/index.tsx | 3 + .../src/pages/Editor/IDE/Sidebar/index.tsx | 43 +++++++-- 8 files changed, 241 insertions(+), 32 deletions(-) create mode 100644 app/client/src/IDE/Components/Sidebar/SidebarButton.test.tsx create mode 100644 app/client/src/IDE/Components/Sidebar/SidebarButton.tsx create mode 100644 app/client/src/IDE/Components/Sidebar/index.tsx diff --git a/app/client/src/IDE/Components/Sidebar/SidebarButton.test.tsx b/app/client/src/IDE/Components/Sidebar/SidebarButton.test.tsx new file mode 100644 index 000000000000..0b6d718c7508 --- /dev/null +++ b/app/client/src/IDE/Components/Sidebar/SidebarButton.test.tsx @@ -0,0 +1,22 @@ +import { render } from "test/testUtils"; +import React from "react"; +import { Condition } from "./SidebarButton"; +import SidebarButton from "./SidebarButton"; +import { TopButtons } from "@appsmith/entities/IDE/constants"; + +const sidebarButtonProps = { + icon: TopButtons[1].icon, + onClick: () => {}, + selected: false, + title: TopButtons[1].title, + condition: Condition.Warn, +}; + +describe("SidebarButton", () => { + it("should render the warning icon in case the datasource list is empty", () => { + const { container } = render(); + + const svgs = container.querySelectorAll("svg"); + expect(svgs).toHaveLength(2); + }); +}); diff --git a/app/client/src/IDE/Components/Sidebar/SidebarButton.tsx b/app/client/src/IDE/Components/Sidebar/SidebarButton.tsx new file mode 100644 index 000000000000..a227aaa0afa5 --- /dev/null +++ b/app/client/src/IDE/Components/Sidebar/SidebarButton.tsx @@ -0,0 +1,89 @@ +import React from "react"; +import { Icon, Text, Tooltip } from "design-system"; +import styled from "styled-components"; + +export enum Condition { + Warn = "warning", + Error = "Error", + Success = "Success", +} + +export interface SidebarButtonProps { + title?: string; + selected: boolean; + icon: string; + onClick: () => void; + tooltip?: string; + condition?: Condition; +} + +const Container = styled.div` + display: flex; + justify-content: center; + flex-direction: column; + width: 50px; + text-align: center; + align-items: center; + padding: 8px 0; +`; + +const IconContainer = styled.div<{ selected: boolean }>` + padding: 2px; + background-color: ${(props) => + props.selected ? "var(--colors-raw-orange-100, #fbe6dc)" : "white"}; + border-radius: 3px; + width: 32px; + height: 32px; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + position: relative; + &:hover { + background: ${(props) => + props.selected + ? "var(--colors-raw-orange-100, #fbe6dc)" + : "var(--ads-v2-color-bg-subtle, #f1f5f9);"}; + } +`; + +const ConditionIcon = styled(Icon)` + position: absolute; + bottom: 3px; + right: -1px; + &.t--sidebar-${Condition.Warn}-condition-icon { + color: #ffe283; + } + // TODO add more condition colors here +`; + +function SidebarButton(props: SidebarButtonProps) { + return ( + + + + + {props.condition && ( + + )} + + + {props.title ? {props.title} : null} + + ); +} + +export default SidebarButton; diff --git a/app/client/src/IDE/Components/Sidebar/index.tsx b/app/client/src/IDE/Components/Sidebar/index.tsx new file mode 100644 index 000000000000..277f56d715f9 --- /dev/null +++ b/app/client/src/IDE/Components/Sidebar/index.tsx @@ -0,0 +1,75 @@ +import React from "react"; +import styled from "styled-components"; +import type { Condition } from "./SidebarButton"; +import SidebarButton from "./SidebarButton"; +import type { EditorState } from "@appsmith/entities/IDE/constants"; + +const Container = styled.div` + width: 50px; + border-right: 1px solid var(--ads-v2-color-border); + height: 100%; + display: flex; + flex-direction: column; + justify-content: space-between; + background-color: var(--ads-v2-color-bg); + position: relative; +`; + +export interface ISidebarButton { + state: EditorState; + icon: string; + title?: string; + urlSuffix: string; + condition?: Condition; + tooltip?: string; +} + +interface SidebarComponentProps { + topButtons: ISidebarButton[]; + bottomButtons: ISidebarButton[]; + appState: EditorState; + onClick: (suffix: string) => void; +} + +function SidebarComponent(props: SidebarComponentProps) { + const { appState, bottomButtons, onClick, topButtons } = props; + + return ( + +
+ {topButtons.map((b) => ( + { + if (appState !== b.state) { + onClick(b.urlSuffix); + } + }} + selected={appState === b.state} + title={b.title} + tooltip={b.tooltip} + /> + ))} +
+
+ {bottomButtons.map((b) => ( + { + if (appState !== b.state) { + onClick(b.urlSuffix); + } + }} + selected={appState === b.state} + title={b.title} + tooltip={b.tooltip} + /> + ))} +
+
+ ); +} + +export default SidebarComponent; diff --git a/app/client/src/IDE/index.ts b/app/client/src/IDE/index.ts index 5568b8167342..4aabeb5a814d 100644 --- a/app/client/src/IDE/index.ts +++ b/app/client/src/IDE/index.ts @@ -40,6 +40,15 @@ export { default as IDEHeaderDropdown } from "./Components/HeaderDropdown"; */ export { default as IDEBottomView } from "./Components/BottomView"; +/** + * + * + * + */ +export { default as IDESidebar } from "./Components/Sidebar"; +export type { ISidebarButton } from "./Components/Sidebar"; +export { Condition } from "./Components/Sidebar/SidebarButton"; + /* ==================================================== **** Interfaces **** Common types that are used by the different components of the IDE diff --git a/app/client/src/api/LibraryAPI.tsx b/app/client/src/api/LibraryAPI.tsx index a76a7a1fb207..73b5c0d879c7 100644 --- a/app/client/src/api/LibraryAPI.tsx +++ b/app/client/src/api/LibraryAPI.tsx @@ -21,7 +21,7 @@ export default class LibraryApi extends Api { library: Partial, ) { const url = LibraryApi.getUpdateLibraryBaseURL(applicationId) + "/remove"; - return Api.patch(url, { accessor: library.accessor, url: library.url }); + return Api.patch(url, library); } static async getLibraries(applicationId: string, mode: APP_MODE) { diff --git a/app/client/src/ce/entities/IDE/constants.ts b/app/client/src/ce/entities/IDE/constants.ts index 982b01243783..d0d3a828c552 100644 --- a/app/client/src/ce/entities/IDE/constants.ts +++ b/app/client/src/ce/entities/IDE/constants.ts @@ -21,11 +21,8 @@ import { SAAS_EDITOR_DATASOURCE_ID_PATH, } from "pages/Editor/SaaSEditor/constants"; import type { PluginType } from "entities/Action"; -import type { ReactNode, ComponentType } from "react"; -import { - EMPTY_DATASOURCE_TOOLTIP_SIDEBUTTON, - createMessage, -} from "@appsmith/constants/messages"; +import type { ComponentType, ReactNode } from "react"; +import type { ISidebarButton } from "IDE"; export enum EditorState { DATA = "DATA", @@ -61,20 +58,7 @@ export enum EditorViewMode { SplitScreen = "SplitScreen", } -export enum SideButtonType { - DATSOURCE = "DATASOURCE", -} - -export interface SidebarButton { - state: EditorState; - icon: string; - title?: string; - urlSuffix: string; - conditionType?: SideButtonType; - conditionTooltip?: string; -} - -export const TopButtons: SidebarButton[] = [ +export const TopButtons: ISidebarButton[] = [ { state: EditorState.EDITOR, icon: "editor-v3", @@ -86,22 +70,20 @@ export const TopButtons: SidebarButton[] = [ icon: "datasource-v3", title: SidebarTopButtonTitles.DATA, urlSuffix: "datasource", - conditionType: SideButtonType.DATSOURCE, - conditionTooltip: createMessage(EMPTY_DATASOURCE_TOOLTIP_SIDEBUTTON), }, ]; -export const BottomButtons: SidebarButton[] = [ +export const BottomButtons: ISidebarButton[] = [ { state: EditorState.LIBRARIES, icon: "packages-v3", - title: SidebarBottomButtonTitles.LIBRARIES, + tooltip: SidebarBottomButtonTitles.LIBRARIES, urlSuffix: "libraries", }, { state: EditorState.SETTINGS, icon: "settings-v3", - title: SidebarBottomButtonTitles.SETTINGS, + tooltip: SidebarBottomButtonTitles.SETTINGS, urlSuffix: "settings", }, ]; diff --git a/app/client/src/index.tsx b/app/client/src/index.tsx index 1c635ce32433..3291f0917ff5 100755 --- a/app/client/src/index.tsx +++ b/app/client/src/index.tsx @@ -56,6 +56,9 @@ if (enableNewRelic) { new BrowserAgent(newRelicBrowserAgentConfig); } +// @ts-expect-error __webpack_public_path__ might be set on runtime when the CDN is used in EE +__webpack_public_path__ = window.CDN_URL; + const shouldAutoFreeze = process.env.NODE_ENV === "development"; setAutoFreeze(shouldAutoFreeze); diff --git a/app/client/src/pages/Editor/IDE/Sidebar/index.tsx b/app/client/src/pages/Editor/IDE/Sidebar/index.tsx index 35968c3099e4..c7e0748f832a 100644 --- a/app/client/src/pages/Editor/IDE/Sidebar/index.tsx +++ b/app/client/src/pages/Editor/IDE/Sidebar/index.tsx @@ -1,20 +1,49 @@ -import React, { useCallback, useEffect } from "react"; -import { useSelector, useDispatch } from "react-redux"; +import React, { useCallback, useEffect, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; import { builderURL } from "@appsmith/RouteBuilder"; import { getCurrentPageId } from "selectors/editorSelectors"; import history, { NavigationMethod } from "utils/history"; import { useCurrentAppState } from "../hooks"; import { getCurrentWorkspaceId } from "@appsmith/selectors/selectedWorkspaceSelectors"; import { fetchWorkspace } from "@appsmith/actions/workspaceActions"; -import SidebarComponent from "./SidebarComponent"; -import { BottomButtons, TopButtons } from "@appsmith/entities/IDE/constants"; +import { IDESidebar, Condition } from "IDE"; +import { + BottomButtons, + EditorState, + TopButtons, +} from "@appsmith/entities/IDE/constants"; +import { getDatasources } from "@appsmith/selectors/entitiesSelector"; +import { + createMessage, + EMPTY_DATASOURCE_TOOLTIP_SIDEBUTTON, +} from "@appsmith/constants/messages"; function Sidebar() { + const [topButtons, setTopButtons] = useState(TopButtons); const dispatch = useDispatch(); const appState = useCurrentAppState(); const pageId = useSelector(getCurrentPageId); - const currentWorkspaceId = useSelector(getCurrentWorkspaceId); + const datasources = useSelector(getDatasources); + + useEffect(() => { + if (datasources.length === 0) { + setTopButtons( + TopButtons.map((button) => { + if (button.state === EditorState.DATA) { + return { + ...button, + condition: Condition.Warn, + tooltip: createMessage(EMPTY_DATASOURCE_TOOLTIP_SIDEBUTTON), + }; + } + return button; + }), + ); + } else { + setTopButtons(TopButtons); + } + }, [datasources]); useEffect(() => { dispatch(fetchWorkspace(currentWorkspaceId)); @@ -36,11 +65,11 @@ function Sidebar() { ); return ( - ); } From c796df71fcc044fcf063f4ab2ce75394c2a46d6d Mon Sep 17 00:00:00 2001 From: Hetu Nandu Date: Wed, 26 Jun 2024 14:44:02 +0530 Subject: [PATCH 02/13] Remove CDN Change --- app/client/src/index.tsx | 3 --- 1 file changed, 3 deletions(-) diff --git a/app/client/src/index.tsx b/app/client/src/index.tsx index 3291f0917ff5..1c635ce32433 100755 --- a/app/client/src/index.tsx +++ b/app/client/src/index.tsx @@ -56,9 +56,6 @@ if (enableNewRelic) { new BrowserAgent(newRelicBrowserAgentConfig); } -// @ts-expect-error __webpack_public_path__ might be set on runtime when the CDN is used in EE -__webpack_public_path__ = window.CDN_URL; - const shouldAutoFreeze = process.env.NODE_ENV === "development"; setAutoFreeze(shouldAutoFreeze); From cad6f3bcfef1f558fc8fb7a87bba2605e74286be Mon Sep 17 00:00:00 2001 From: Hetu Nandu Date: Wed, 26 Jun 2024 14:55:31 +0530 Subject: [PATCH 03/13] fix issue with sync --- .../Editor/IDE/Sidebar/SidebarButton.test.tsx | 23 ----- .../Editor/IDE/Sidebar/SidebarButton.tsx | 84 ------------------ .../Editor/IDE/Sidebar/SidebarComponent.tsx | 87 ------------------- 3 files changed, 194 deletions(-) delete mode 100644 app/client/src/pages/Editor/IDE/Sidebar/SidebarButton.test.tsx delete mode 100644 app/client/src/pages/Editor/IDE/Sidebar/SidebarButton.tsx delete mode 100644 app/client/src/pages/Editor/IDE/Sidebar/SidebarComponent.tsx diff --git a/app/client/src/pages/Editor/IDE/Sidebar/SidebarButton.test.tsx b/app/client/src/pages/Editor/IDE/Sidebar/SidebarButton.test.tsx deleted file mode 100644 index 15c2b9de9cd1..000000000000 --- a/app/client/src/pages/Editor/IDE/Sidebar/SidebarButton.test.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import { render } from "test/testUtils"; -import React from "react"; -import type { SidebarButtonProps } from "./SidebarButton"; -import SidebarButton from "./SidebarButton"; -import { TopButtons } from "@appsmith/entities/IDE/constants"; - -const sidebarButtonProps: SidebarButtonProps = { - icon: TopButtons[1].icon, - onClick: () => {}, - selected: false, - title: TopButtons[1].title, - conditionIcon: "warning", - tooltip: TopButtons[1].conditionTooltip, -}; - -describe("SidebarButton", () => { - it("should render the warning icon incase the datasource list is empty", () => { - const { container } = render(); - - const svgs = container.querySelectorAll("svg"); - expect(svgs).toHaveLength(2); - }); -}); diff --git a/app/client/src/pages/Editor/IDE/Sidebar/SidebarButton.tsx b/app/client/src/pages/Editor/IDE/Sidebar/SidebarButton.tsx deleted file mode 100644 index d53ef1fcb119..000000000000 --- a/app/client/src/pages/Editor/IDE/Sidebar/SidebarButton.tsx +++ /dev/null @@ -1,84 +0,0 @@ -import React from "react"; -import { Icon, Text, Tooltip } from "design-system"; -import styled from "styled-components"; -import { SidebarTopButtonTitles } from "@appsmith/entities/IDE/constants"; - -export interface SidebarButtonProps { - title?: string; - selected: boolean; - icon: string; - onClick: () => void; - tooltip?: string; - conditionIcon?: string; -} - -const Container = styled.div` - display: flex; - justify-content: center; - flex-direction: column; - width: 50px; - text-align: center; - align-items: center; - padding: 8px 0; -`; - -const IconContainer = styled.div<{ selected: boolean }>` - padding: 2px; - background-color: ${(props) => - props.selected ? "var(--colors-raw-orange-100, #fbe6dc)" : "white"}; - border-radius: 3px; - width: 32px; - height: 32px; - display: flex; - align-items: center; - justify-content: center; - cursor: pointer; - position: relative; - &:hover { - background: ${(props) => - props.selected - ? "var(--colors-raw-orange-100, #fbe6dc)" - : "var(--ads-v2-color-bg-subtle, #f1f5f9);"}; - } -`; - -const ConditionIcon = styled(Icon)` - position: absolute; - bottom: 3px; - right: -1px; - &.t--sidebar-${SidebarTopButtonTitles.DATA}-condition-icon { - color: #ffe283; - } -`; - -function SidebarButton(props: SidebarButtonProps) { - return ( - - {props.title === SidebarTopButtonTitles.DATA} - - - - {props.conditionIcon && ( - - )} - - - {props.title ? {props.title} : null} - - ); -} - -export default SidebarButton; diff --git a/app/client/src/pages/Editor/IDE/Sidebar/SidebarComponent.tsx b/app/client/src/pages/Editor/IDE/Sidebar/SidebarComponent.tsx deleted file mode 100644 index d5e9ccf2f4c0..000000000000 --- a/app/client/src/pages/Editor/IDE/Sidebar/SidebarComponent.tsx +++ /dev/null @@ -1,87 +0,0 @@ -import React from "react"; -import styled from "styled-components"; -import SidebarButton from "./SidebarButton"; -import type { SidebarButton as SidebarButtonType } from "@appsmith/entities/IDE/constants"; -import { SideButtonType } from "@appsmith/entities/IDE/constants"; -import { useSelector } from "react-redux"; -import { getDatasources } from "@appsmith/selectors/entitiesSelector"; - -const Container = styled.div` - width: 50px; - border-right: 1px solid var(--ads-v2-color-border); - height: 100%; - display: flex; - flex-direction: column; - justify-content: space-between; - background-color: var(--ads-v2-color-bg); - position: relative; -`; - -interface SidebarComponentProps { - topButtons: SidebarButtonType[]; - bottomButtons: SidebarButtonType[]; - appState: string; - onClick: (suffix: string) => void; -} - -function SidebarComponent(props: SidebarComponentProps) { - const { appState, bottomButtons, onClick, topButtons } = props; - const datasources = useSelector(getDatasources); - const getConditionalIconAndTooltip = ( - type?: SideButtonType, - conditionTooltip?: string, - ) => { - switch (type) { - case SideButtonType.DATSOURCE: - if (datasources.length === 0) - return { - conditionIcon: "warning", - tooltip: conditionTooltip, - }; - return {}; - default: - return {}; - } - }; - - return ( - -
- {topButtons.map((b) => ( - { - if (appState !== b.state) { - onClick(b.urlSuffix); - } - }} - selected={appState === b.state} - title={b.title} - {...getConditionalIconAndTooltip( - b.conditionType, - b.conditionTooltip, - )} - /> - ))} -
-
- {bottomButtons.map((b) => ( - { - if (appState !== b.state) { - onClick(b.urlSuffix); - } - }} - selected={appState === b.state} - tooltip={b.title} - /> - ))} -
-
- ); -} - -export default SidebarComponent; From 9b4c703ab593c64ef33632c22b1dc9e007f05ab7 Mon Sep 17 00:00:00 2001 From: Hetu Nandu Date: Wed, 26 Jun 2024 16:06:43 +0530 Subject: [PATCH 04/13] fix: Introduce new cyclical dependency --- app/client/src/IDE/Components/BottomView.tsx | 4 ++-- .../src/pages/Editor/JSEditor/constants.ts | 24 ------------------- 2 files changed, 2 insertions(+), 26 deletions(-) diff --git a/app/client/src/IDE/Components/BottomView.tsx b/app/client/src/IDE/Components/BottomView.tsx index fe5bbb9e41b1..19bddbe3d705 100644 --- a/app/client/src/IDE/Components/BottomView.tsx +++ b/app/client/src/IDE/Components/BottomView.tsx @@ -3,8 +3,8 @@ 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 { CodeEditorWithGutterStyles } from "pages/Editor/JSEditor/styledComponents"; +import { ViewDisplayMode, ViewHideBehaviour } from "IDE/Interfaces/View"; import { Button } from "design-system"; const VIEW_MIN_HEIGHT = 38; diff --git a/app/client/src/pages/Editor/JSEditor/constants.ts b/app/client/src/pages/Editor/JSEditor/constants.ts index ae9b8af8533c..da8b12eb319d 100644 --- a/app/client/src/pages/Editor/JSEditor/constants.ts +++ b/app/client/src/pages/Editor/JSEditor/constants.ts @@ -1,4 +1,3 @@ -import { css } from "styled-components"; import type { JSActionDropdownOption } from "./utils"; export const RUN_BUTTON_DEFAULTS = { @@ -52,26 +51,3 @@ export const ANIMATE_RUN_GUTTER = "animate-run-marker"; export const testLocators = { runJSAction: "run-js-action", }; - -export const CodeEditorWithGutterStyles = css` - .${RUN_GUTTER_ID} { - width: 0.5em; - background: #f0f0f0; - margin-left: 5px; - } - .${RUN_GUTTER_CLASSNAME} { - cursor: pointer; - color: var(--ads-v2-color-fg-brand); - } - .CodeMirror-linenumbers { - width: max-content; - } - .CodeMirror-linenumber { - text-align: right; - padding-left: 0; - } - - .cm-s-duotone-light.CodeMirror { - padding: 0; - } -`; From c86818abfcd8677b8871ec0aedaaf8860f12ec57 Mon Sep 17 00:00:00 2001 From: Hetu Nandu Date: Fri, 28 Jun 2024 12:29:13 +0530 Subject: [PATCH 05/13] improve splits --- .../Components/Sidebar/SidebarButton.test.tsx | 21 ++++++++++++------- .../IDE/Components/Sidebar/SidebarButton.tsx | 16 +++++++++++--- .../src/IDE/Components/Sidebar/index.tsx | 19 ++++++++++------- app/client/src/IDE/index.ts | 5 ++--- .../src/pages/Editor/IDE/Sidebar/index.tsx | 1 + 5 files changed, 40 insertions(+), 22 deletions(-) diff --git a/app/client/src/IDE/Components/Sidebar/SidebarButton.test.tsx b/app/client/src/IDE/Components/Sidebar/SidebarButton.test.tsx index 0b6d718c7508..9b2bd3d78888 100644 --- a/app/client/src/IDE/Components/Sidebar/SidebarButton.test.tsx +++ b/app/client/src/IDE/Components/Sidebar/SidebarButton.test.tsx @@ -1,20 +1,25 @@ import { render } from "test/testUtils"; import React from "react"; -import { Condition } from "./SidebarButton"; -import SidebarButton from "./SidebarButton"; -import { TopButtons } from "@appsmith/entities/IDE/constants"; +import SidebarButton, { + Condition, + type SidebarButtonProps, +} from "./SidebarButton"; -const sidebarButtonProps = { - icon: TopButtons[1].icon, +const sidebarButtonProps: SidebarButtonProps = { + icon: "down-arrow", onClick: () => {}, selected: false, - title: TopButtons[1].title, - condition: Condition.Warn, + title: "Test", }; describe("SidebarButton", () => { it("should render the warning icon in case the datasource list is empty", () => { - const { container } = render(); + const withWarningCondition = { + ...sidebarButtonProps, + condition: Condition.Warn, + }; + + const { container } = render(); const svgs = container.querySelectorAll("svg"); expect(svgs).toHaveLength(2); diff --git a/app/client/src/IDE/Components/Sidebar/SidebarButton.tsx b/app/client/src/IDE/Components/Sidebar/SidebarButton.tsx index a227aaa0afa5..518661e01889 100644 --- a/app/client/src/IDE/Components/Sidebar/SidebarButton.tsx +++ b/app/client/src/IDE/Components/Sidebar/SidebarButton.tsx @@ -3,11 +3,21 @@ import { Icon, Text, Tooltip } from "design-system"; import styled from "styled-components"; export enum Condition { - Warn = "warning", + Warn = "Warn", Error = "Error", Success = "Success", } +const ConditionConfig: Record = { + [Condition.Warn]: { + icon: "warning", + color: "#ffe283", + }, + // TODO add this information for further conditions + Error: { color: "", icon: "" }, + Success: { color: "", icon: "" }, +}; + export interface SidebarButtonProps { title?: string; selected: boolean; @@ -52,7 +62,7 @@ const ConditionIcon = styled(Icon)` bottom: 3px; right: -1px; &.t--sidebar-${Condition.Warn}-condition-icon { - color: #ffe283; + color: ${ConditionConfig[Condition.Warn].color}; } // TODO add more condition colors here `; @@ -75,7 +85,7 @@ function SidebarButton(props: SidebarButtonProps) { {props.condition && ( )} diff --git a/app/client/src/IDE/Components/Sidebar/index.tsx b/app/client/src/IDE/Components/Sidebar/index.tsx index 277f56d715f9..42d9d5b0d3eb 100644 --- a/app/client/src/IDE/Components/Sidebar/index.tsx +++ b/app/client/src/IDE/Components/Sidebar/index.tsx @@ -1,4 +1,4 @@ -import React from "react"; +import React, { useCallback } from "react"; import styled from "styled-components"; import type { Condition } from "./SidebarButton"; import SidebarButton from "./SidebarButton"; @@ -25,6 +25,7 @@ export interface ISidebarButton { } interface SidebarComponentProps { + id?: string; topButtons: ISidebarButton[]; bottomButtons: ISidebarButton[]; appState: EditorState; @@ -34,17 +35,21 @@ interface SidebarComponentProps { function SidebarComponent(props: SidebarComponentProps) { const { appState, bottomButtons, onClick, topButtons } = props; + const handleOnClick = useCallback((button: ISidebarButton) => { + if (appState !== button.state) { + onClick(button.urlSuffix); + } + }, []); + return ( - +
{topButtons.map((b) => ( { - if (appState !== b.state) { - onClick(b.urlSuffix); - } + handleOnClick(b); }} selected={appState === b.state} title={b.title} @@ -58,9 +63,7 @@ function SidebarComponent(props: SidebarComponentProps) { icon={b.icon} key={b.state} onClick={() => { - if (appState !== b.state) { - onClick(b.urlSuffix); - } + handleOnClick(b); }} selected={appState === b.state} title={b.title} diff --git a/app/client/src/IDE/index.ts b/app/client/src/IDE/index.ts index 4aabeb5a814d..537dcc69c892 100644 --- a/app/client/src/IDE/index.ts +++ b/app/client/src/IDE/index.ts @@ -41,9 +41,8 @@ export { default as IDEHeaderDropdown } from "./Components/HeaderDropdown"; export { default as IDEBottomView } from "./Components/BottomView"; /** - * - * - * + * IDESidebar is used inside the IDE to have a navigation menu on the left side of the screen. + * It switches between different editor states */ export { default as IDESidebar } from "./Components/Sidebar"; export type { ISidebarButton } from "./Components/Sidebar"; diff --git a/app/client/src/pages/Editor/IDE/Sidebar/index.tsx b/app/client/src/pages/Editor/IDE/Sidebar/index.tsx index c7e0748f832a..48f374fd06d1 100644 --- a/app/client/src/pages/Editor/IDE/Sidebar/index.tsx +++ b/app/client/src/pages/Editor/IDE/Sidebar/index.tsx @@ -68,6 +68,7 @@ function Sidebar() { From 1156e73fd18d11dd15b33d256a4b4e073fe7d13f Mon Sep 17 00:00:00 2001 From: Hetu Nandu Date: Fri, 28 Jun 2024 13:46:52 +0530 Subject: [PATCH 06/13] fix: Condition issue --- app/client/src/IDE/Components/Sidebar/index.tsx | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/app/client/src/IDE/Components/Sidebar/index.tsx b/app/client/src/IDE/Components/Sidebar/index.tsx index 42d9d5b0d3eb..7292585ad164 100644 --- a/app/client/src/IDE/Components/Sidebar/index.tsx +++ b/app/client/src/IDE/Components/Sidebar/index.tsx @@ -35,11 +35,14 @@ interface SidebarComponentProps { function SidebarComponent(props: SidebarComponentProps) { const { appState, bottomButtons, onClick, topButtons } = props; - const handleOnClick = useCallback((button: ISidebarButton) => { - if (appState !== button.state) { - onClick(button.urlSuffix); - } - }, []); + const handleOnClick = useCallback( + (button: ISidebarButton) => { + if (appState !== button.state) { + onClick(button.urlSuffix); + } + }, + [appState], + ); return ( From 0d560d15e146c6aaaffb7a636b76c09e440d84d3 Mon Sep 17 00:00:00 2001 From: Hetu Nandu Date: Fri, 28 Jun 2024 15:54:59 +0530 Subject: [PATCH 07/13] fix: File structure --- .../Components/Sidebar/SidebarButton.test.tsx | 6 ++---- .../IDE/Components/Sidebar/SidebarButton.tsx | 11 +++-------- app/client/src/IDE/Components/Sidebar/index.tsx | 17 ++++------------- app/client/src/IDE/Interfaces/Condition.ts | 5 +++++ app/client/src/IDE/Interfaces/ISidebarButton.ts | 12 ++++++++++++ app/client/src/IDE/index.ts | 4 ++-- .../IDE/{Sidebar/index.tsx => Sidebar.tsx} | 2 +- 7 files changed, 29 insertions(+), 28 deletions(-) create mode 100644 app/client/src/IDE/Interfaces/Condition.ts create mode 100644 app/client/src/IDE/Interfaces/ISidebarButton.ts rename app/client/src/pages/Editor/IDE/{Sidebar/index.tsx => Sidebar.tsx} (97%) diff --git a/app/client/src/IDE/Components/Sidebar/SidebarButton.test.tsx b/app/client/src/IDE/Components/Sidebar/SidebarButton.test.tsx index 9b2bd3d78888..49f184512233 100644 --- a/app/client/src/IDE/Components/Sidebar/SidebarButton.test.tsx +++ b/app/client/src/IDE/Components/Sidebar/SidebarButton.test.tsx @@ -1,9 +1,7 @@ import { render } from "test/testUtils"; import React from "react"; -import SidebarButton, { - Condition, - type SidebarButtonProps, -} from "./SidebarButton"; +import SidebarButton, { type SidebarButtonProps } from "./SidebarButton"; +import { Condition } from "../../Interfaces/Condition"; const sidebarButtonProps: SidebarButtonProps = { icon: "down-arrow", diff --git a/app/client/src/IDE/Components/Sidebar/SidebarButton.tsx b/app/client/src/IDE/Components/Sidebar/SidebarButton.tsx index 518661e01889..6ac85ef7f177 100644 --- a/app/client/src/IDE/Components/Sidebar/SidebarButton.tsx +++ b/app/client/src/IDE/Components/Sidebar/SidebarButton.tsx @@ -1,12 +1,7 @@ import React from "react"; import { Icon, Text, Tooltip } from "design-system"; import styled from "styled-components"; - -export enum Condition { - Warn = "Warn", - Error = "Error", - Success = "Success", -} +import { Condition } from "../../Interfaces/Condition"; const ConditionConfig: Record = { [Condition.Warn]: { @@ -14,8 +9,8 @@ const ConditionConfig: Record = { color: "#ffe283", }, // TODO add this information for further conditions - Error: { color: "", icon: "" }, - Success: { color: "", icon: "" }, + // Error: { color: "", icon: "" }, + // Success: { color: "", icon: "" }, }; export interface SidebarButtonProps { diff --git a/app/client/src/IDE/Components/Sidebar/index.tsx b/app/client/src/IDE/Components/Sidebar/index.tsx index 7292585ad164..fe530b147fc4 100644 --- a/app/client/src/IDE/Components/Sidebar/index.tsx +++ b/app/client/src/IDE/Components/Sidebar/index.tsx @@ -1,8 +1,8 @@ import React, { useCallback } from "react"; import styled from "styled-components"; -import type { Condition } from "./SidebarButton"; import SidebarButton from "./SidebarButton"; import type { EditorState } from "@appsmith/entities/IDE/constants"; +import type { ISidebarButton } from "../../Interfaces/ISidebarButton"; const Container = styled.div` width: 50px; @@ -15,16 +15,7 @@ const Container = styled.div` position: relative; `; -export interface ISidebarButton { - state: EditorState; - icon: string; - title?: string; - urlSuffix: string; - condition?: Condition; - tooltip?: string; -} - -interface SidebarComponentProps { +interface IDESidebarProps { id?: string; topButtons: ISidebarButton[]; bottomButtons: ISidebarButton[]; @@ -32,7 +23,7 @@ interface SidebarComponentProps { onClick: (suffix: string) => void; } -function SidebarComponent(props: SidebarComponentProps) { +function IDESidebar(props: IDESidebarProps) { const { appState, bottomButtons, onClick, topButtons } = props; const handleOnClick = useCallback( @@ -78,4 +69,4 @@ function SidebarComponent(props: SidebarComponentProps) { ); } -export default SidebarComponent; +export default IDESidebar; diff --git a/app/client/src/IDE/Interfaces/Condition.ts b/app/client/src/IDE/Interfaces/Condition.ts new file mode 100644 index 000000000000..2c62e72c91ad --- /dev/null +++ b/app/client/src/IDE/Interfaces/Condition.ts @@ -0,0 +1,5 @@ +export enum Condition { + Warn = "Warn", + // Error = "Error", + // Success = "Success", +} diff --git a/app/client/src/IDE/Interfaces/ISidebarButton.ts b/app/client/src/IDE/Interfaces/ISidebarButton.ts new file mode 100644 index 000000000000..fe95e8f7f1a6 --- /dev/null +++ b/app/client/src/IDE/Interfaces/ISidebarButton.ts @@ -0,0 +1,12 @@ +import type { EditorState } from "@appsmith/entities/IDE/constants"; + +import type { Condition } from "./Condition"; + +export interface ISidebarButton { + state: EditorState; + icon: string; + title?: string; + urlSuffix: string; + condition?: Condition; + tooltip?: string; +} diff --git a/app/client/src/IDE/index.ts b/app/client/src/IDE/index.ts index 537dcc69c892..ec7f91556f94 100644 --- a/app/client/src/IDE/index.ts +++ b/app/client/src/IDE/index.ts @@ -45,8 +45,6 @@ export { default as IDEBottomView } from "./Components/BottomView"; * It switches between different editor states */ export { default as IDESidebar } from "./Components/Sidebar"; -export type { ISidebarButton } from "./Components/Sidebar"; -export { Condition } from "./Components/Sidebar/SidebarButton"; /* ==================================================== **** Interfaces **** @@ -54,3 +52,5 @@ export { Condition } from "./Components/Sidebar/SidebarButton"; =======================================================**/ export { ViewHideBehaviour, ViewDisplayMode } from "./Interfaces/View"; +export type { ISidebarButton } from "./Interfaces/ISidebarButton"; +export { Condition } from "./Interfaces/Condition"; diff --git a/app/client/src/pages/Editor/IDE/Sidebar/index.tsx b/app/client/src/pages/Editor/IDE/Sidebar.tsx similarity index 97% rename from app/client/src/pages/Editor/IDE/Sidebar/index.tsx rename to app/client/src/pages/Editor/IDE/Sidebar.tsx index 48f374fd06d1..4289f89f8ff6 100644 --- a/app/client/src/pages/Editor/IDE/Sidebar/index.tsx +++ b/app/client/src/pages/Editor/IDE/Sidebar.tsx @@ -3,7 +3,7 @@ import { useDispatch, useSelector } from "react-redux"; import { builderURL } from "@appsmith/RouteBuilder"; import { getCurrentPageId } from "selectors/editorSelectors"; import history, { NavigationMethod } from "utils/history"; -import { useCurrentAppState } from "../hooks"; +import { useCurrentAppState } from "./hooks"; import { getCurrentWorkspaceId } from "@appsmith/selectors/selectedWorkspaceSelectors"; import { fetchWorkspace } from "@appsmith/actions/workspaceActions"; import { IDESidebar, Condition } from "IDE"; From 4c14038cf342cce19e2616789bce37e6cbfb7a0c Mon Sep 17 00:00:00 2001 From: Hetu Nandu Date: Tue, 2 Jul 2024 15:57:04 +0530 Subject: [PATCH 08/13] fix: File structure --- .../src/IDE/Components/Sidebar/Sidebar.tsx | 67 +++++++++++++++++ .../SidebarButton.test.tsx | 3 +- .../{ => SidebarButton}/SidebarButton.tsx | 12 ++- .../Components/Sidebar/SidebarButton/index.ts | 1 + .../src/IDE/Components/Sidebar/index.tsx | 74 +------------------ .../src/IDE/Interfaces/ISidebarButton.ts | 12 --- .../IDE/{Interfaces/Condition.ts => enums.ts} | 0 app/client/src/IDE/index.ts | 5 +- app/client/src/ce/entities/IDE/constants.ts | 6 +- app/client/src/pages/Editor/IDE/Sidebar.tsx | 16 ++-- 10 files changed, 96 insertions(+), 100 deletions(-) create mode 100644 app/client/src/IDE/Components/Sidebar/Sidebar.tsx rename app/client/src/IDE/Components/Sidebar/{ => SidebarButton}/SidebarButton.test.tsx (92%) rename app/client/src/IDE/Components/Sidebar/{ => SidebarButton}/SidebarButton.tsx (90%) create mode 100644 app/client/src/IDE/Components/Sidebar/SidebarButton/index.ts delete mode 100644 app/client/src/IDE/Interfaces/ISidebarButton.ts rename app/client/src/IDE/{Interfaces/Condition.ts => enums.ts} (100%) diff --git a/app/client/src/IDE/Components/Sidebar/Sidebar.tsx b/app/client/src/IDE/Components/Sidebar/Sidebar.tsx new file mode 100644 index 000000000000..c8d8e6c0c112 --- /dev/null +++ b/app/client/src/IDE/Components/Sidebar/Sidebar.tsx @@ -0,0 +1,67 @@ +import React from "react"; +import styled from "styled-components"; +import SidebarButton from "./SidebarButton"; +import type { EditorState } from "@appsmith/entities/IDE/constants"; +import type { SidebarButtonProps } from "./SidebarButton/SidebarButton"; + +const Container = styled.div` + width: 50px; + border-right: 1px solid var(--ads-v2-color-border); + height: 100%; + display: flex; + flex-direction: column; + justify-content: space-between; + background-color: var(--ads-v2-color-bg); + position: relative; +`; + +// Sidebar handles the correct handling of sidebar button. It will check if +// the button should be selected and only handle calling the onClick +export interface IDESidebarButton + extends Omit { + state: EditorState; + urlSuffix: string; +} + +interface IDESidebarProps { + id?: string; + topButtons: IDESidebarButton[]; + bottomButtons: IDESidebarButton[]; + editorState: EditorState; + onClick: (suffix: string) => void; +} + +function IDESidebar(props: IDESidebarProps) { + const { bottomButtons, editorState, onClick, topButtons } = props; + + return ( + +
+ {topButtons.map((button) => ( + + ))} +
+
+ {bottomButtons.map((button) => ( + + ))} +
+
+ ); +} + +export default IDESidebar; diff --git a/app/client/src/IDE/Components/Sidebar/SidebarButton.test.tsx b/app/client/src/IDE/Components/Sidebar/SidebarButton/SidebarButton.test.tsx similarity index 92% rename from app/client/src/IDE/Components/Sidebar/SidebarButton.test.tsx rename to app/client/src/IDE/Components/Sidebar/SidebarButton/SidebarButton.test.tsx index 49f184512233..5c03fa96588f 100644 --- a/app/client/src/IDE/Components/Sidebar/SidebarButton.test.tsx +++ b/app/client/src/IDE/Components/Sidebar/SidebarButton/SidebarButton.test.tsx @@ -1,7 +1,8 @@ import { render } from "test/testUtils"; import React from "react"; import SidebarButton, { type SidebarButtonProps } from "./SidebarButton"; -import { Condition } from "../../Interfaces/Condition"; + +import { Condition } from "../../../enums"; const sidebarButtonProps: SidebarButtonProps = { icon: "down-arrow", diff --git a/app/client/src/IDE/Components/Sidebar/SidebarButton.tsx b/app/client/src/IDE/Components/Sidebar/SidebarButton/SidebarButton.tsx similarity index 90% rename from app/client/src/IDE/Components/Sidebar/SidebarButton.tsx rename to app/client/src/IDE/Components/Sidebar/SidebarButton/SidebarButton.tsx index 6ac85ef7f177..72fb8a1c3d56 100644 --- a/app/client/src/IDE/Components/Sidebar/SidebarButton.tsx +++ b/app/client/src/IDE/Components/Sidebar/SidebarButton/SidebarButton.tsx @@ -1,7 +1,8 @@ -import React from "react"; +import React, { useCallback } from "react"; import { Icon, Text, Tooltip } from "design-system"; import styled from "styled-components"; -import { Condition } from "../../Interfaces/Condition"; + +import { Condition } from "../../../enums"; const ConditionConfig: Record = { [Condition.Warn]: { @@ -63,6 +64,11 @@ const ConditionIcon = styled(Icon)` `; function SidebarButton(props: SidebarButtonProps) { + const handleOnClick = useCallback(() => { + if (!props.selected) { + props.onClick(); + } + }, [props]); return ( diff --git a/app/client/src/IDE/Components/Sidebar/SidebarButton/index.ts b/app/client/src/IDE/Components/Sidebar/SidebarButton/index.ts new file mode 100644 index 000000000000..6b596087d7b6 --- /dev/null +++ b/app/client/src/IDE/Components/Sidebar/SidebarButton/index.ts @@ -0,0 +1 @@ +export { default } from "./SidebarButton"; diff --git a/app/client/src/IDE/Components/Sidebar/index.tsx b/app/client/src/IDE/Components/Sidebar/index.tsx index fe530b147fc4..9b2d7718b1a6 100644 --- a/app/client/src/IDE/Components/Sidebar/index.tsx +++ b/app/client/src/IDE/Components/Sidebar/index.tsx @@ -1,72 +1,2 @@ -import React, { useCallback } from "react"; -import styled from "styled-components"; -import SidebarButton from "./SidebarButton"; -import type { EditorState } from "@appsmith/entities/IDE/constants"; -import type { ISidebarButton } from "../../Interfaces/ISidebarButton"; - -const Container = styled.div` - width: 50px; - border-right: 1px solid var(--ads-v2-color-border); - height: 100%; - display: flex; - flex-direction: column; - justify-content: space-between; - background-color: var(--ads-v2-color-bg); - position: relative; -`; - -interface IDESidebarProps { - id?: string; - topButtons: ISidebarButton[]; - bottomButtons: ISidebarButton[]; - appState: EditorState; - onClick: (suffix: string) => void; -} - -function IDESidebar(props: IDESidebarProps) { - const { appState, bottomButtons, onClick, topButtons } = props; - - const handleOnClick = useCallback( - (button: ISidebarButton) => { - if (appState !== button.state) { - onClick(button.urlSuffix); - } - }, - [appState], - ); - - return ( - -
- {topButtons.map((b) => ( - { - handleOnClick(b); - }} - selected={appState === b.state} - title={b.title} - tooltip={b.tooltip} - /> - ))} -
-
- {bottomButtons.map((b) => ( - { - handleOnClick(b); - }} - selected={appState === b.state} - title={b.title} - tooltip={b.tooltip} - /> - ))} -
-
- ); -} - -export default IDESidebar; +export { default } from "./Sidebar"; +export { IDESidebarButton } from "./Sidebar"; diff --git a/app/client/src/IDE/Interfaces/ISidebarButton.ts b/app/client/src/IDE/Interfaces/ISidebarButton.ts deleted file mode 100644 index fe95e8f7f1a6..000000000000 --- a/app/client/src/IDE/Interfaces/ISidebarButton.ts +++ /dev/null @@ -1,12 +0,0 @@ -import type { EditorState } from "@appsmith/entities/IDE/constants"; - -import type { Condition } from "./Condition"; - -export interface ISidebarButton { - state: EditorState; - icon: string; - title?: string; - urlSuffix: string; - condition?: Condition; - tooltip?: string; -} diff --git a/app/client/src/IDE/Interfaces/Condition.ts b/app/client/src/IDE/enums.ts similarity index 100% rename from app/client/src/IDE/Interfaces/Condition.ts rename to app/client/src/IDE/enums.ts diff --git a/app/client/src/IDE/index.ts b/app/client/src/IDE/index.ts index ec7f91556f94..92b6554bc694 100644 --- a/app/client/src/IDE/index.ts +++ b/app/client/src/IDE/index.ts @@ -44,7 +44,7 @@ export { default as IDEBottomView } from "./Components/BottomView"; * IDESidebar is used inside the IDE to have a navigation menu on the left side of the screen. * It switches between different editor states */ -export { default as IDESidebar } from "./Components/Sidebar"; +export { default as IDESidebar, IDESidebarButton } from "./Components/Sidebar"; /* ==================================================== **** Interfaces **** @@ -52,5 +52,4 @@ export { default as IDESidebar } from "./Components/Sidebar"; =======================================================**/ export { ViewHideBehaviour, ViewDisplayMode } from "./Interfaces/View"; -export type { ISidebarButton } from "./Interfaces/ISidebarButton"; -export { Condition } from "./Interfaces/Condition"; +export { Condition } from "./enums"; diff --git a/app/client/src/ce/entities/IDE/constants.ts b/app/client/src/ce/entities/IDE/constants.ts index d0d3a828c552..a0a77714ce44 100644 --- a/app/client/src/ce/entities/IDE/constants.ts +++ b/app/client/src/ce/entities/IDE/constants.ts @@ -22,7 +22,7 @@ import { } from "pages/Editor/SaaSEditor/constants"; import type { PluginType } from "entities/Action"; import type { ComponentType, ReactNode } from "react"; -import type { ISidebarButton } from "IDE"; +import type { IDESidebarButton } from "IDE"; export enum EditorState { DATA = "DATA", @@ -58,7 +58,7 @@ export enum EditorViewMode { SplitScreen = "SplitScreen", } -export const TopButtons: ISidebarButton[] = [ +export const TopButtons: IDESidebarButton[] = [ { state: EditorState.EDITOR, icon: "editor-v3", @@ -73,7 +73,7 @@ export const TopButtons: ISidebarButton[] = [ }, ]; -export const BottomButtons: ISidebarButton[] = [ +export const BottomButtons: IDESidebarButton[] = [ { state: EditorState.LIBRARIES, icon: "packages-v3", diff --git a/app/client/src/pages/Editor/IDE/Sidebar.tsx b/app/client/src/pages/Editor/IDE/Sidebar.tsx index 4289f89f8ff6..e4eb71388a4a 100644 --- a/app/client/src/pages/Editor/IDE/Sidebar.tsx +++ b/app/client/src/pages/Editor/IDE/Sidebar.tsx @@ -25,9 +25,12 @@ function Sidebar() { const pageId = useSelector(getCurrentPageId); const currentWorkspaceId = useSelector(getCurrentWorkspaceId); const datasources = useSelector(getDatasources); + const datasourcesExist = datasources.length > 0; + // Updates the top button config based on datasource existence useEffect(() => { - if (datasources.length === 0) { + if (!datasourcesExist) { + // Update the data button to show a warning setTopButtons( TopButtons.map((button) => { if (button.state === EditorState.DATA) { @@ -40,14 +43,15 @@ function Sidebar() { return button; }), ); - } else { - setTopButtons(TopButtons); + return; } - }, [datasources]); + // Datasource exists, so reset to standard button config + setTopButtons(TopButtons); + }, [datasourcesExist]); useEffect(() => { dispatch(fetchWorkspace(currentWorkspaceId)); - }, [currentWorkspaceId]); + }, [currentWorkspaceId, dispatch]); const onClick = useCallback( (suffix) => { @@ -66,8 +70,8 @@ function Sidebar() { return ( Date: Tue, 2 Jul 2024 16:07:05 +0530 Subject: [PATCH 09/13] other minor fixes --- .../src/IDE/Components/Sidebar/SidebarButton/SidebarButton.tsx | 2 +- app/client/src/IDE/Components/Sidebar/index.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/client/src/IDE/Components/Sidebar/SidebarButton/SidebarButton.tsx b/app/client/src/IDE/Components/Sidebar/SidebarButton/SidebarButton.tsx index 72fb8a1c3d56..c32a4acd889f 100644 --- a/app/client/src/IDE/Components/Sidebar/SidebarButton/SidebarButton.tsx +++ b/app/client/src/IDE/Components/Sidebar/SidebarButton/SidebarButton.tsx @@ -68,7 +68,7 @@ function SidebarButton(props: SidebarButtonProps) { if (!props.selected) { props.onClick(); } - }, [props]); + }, [props.selected, props.onClick]); return ( Date: Tue, 2 Jul 2024 16:21:33 +0530 Subject: [PATCH 10/13] fix build issue --- app/client/src/IDE/index.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/client/src/IDE/index.ts b/app/client/src/IDE/index.ts index 92b6554bc694..0b765da22cea 100644 --- a/app/client/src/IDE/index.ts +++ b/app/client/src/IDE/index.ts @@ -44,7 +44,7 @@ export { default as IDEBottomView } from "./Components/BottomView"; * IDESidebar is used inside the IDE to have a navigation menu on the left side of the screen. * It switches between different editor states */ -export { default as IDESidebar, IDESidebarButton } from "./Components/Sidebar"; +export { default as IDESidebar } from "./Components/Sidebar"; /* ==================================================== **** Interfaces **** @@ -53,3 +53,4 @@ export { default as IDESidebar, IDESidebarButton } from "./Components/Sidebar"; export { ViewHideBehaviour, ViewDisplayMode } from "./Interfaces/View"; export { Condition } from "./enums"; +export type { IDESidebarButton } from "./Components/Sidebar"; From 71e57958cd2da0b5edd0aea5adef2422edd76db3 Mon Sep 17 00:00:00 2001 From: Hetu Nandu Date: Fri, 5 Jul 2024 12:42:38 +0530 Subject: [PATCH 11/13] fix review comments --- .../src/IDE/Components/Sidebar/Sidebar.tsx | 10 +++-- .../Sidebar/SidebarButton/SidebarButton.tsx | 39 +++++++++++-------- app/client/src/pages/Editor/IDE/Sidebar.tsx | 19 +++------ 3 files changed, 34 insertions(+), 34 deletions(-) diff --git a/app/client/src/IDE/Components/Sidebar/Sidebar.tsx b/app/client/src/IDE/Components/Sidebar/Sidebar.tsx index c8d8e6c0c112..5fedfd10d3c1 100644 --- a/app/client/src/IDE/Components/Sidebar/Sidebar.tsx +++ b/app/client/src/IDE/Components/Sidebar/Sidebar.tsx @@ -3,12 +3,12 @@ import styled from "styled-components"; import SidebarButton from "./SidebarButton"; import type { EditorState } from "@appsmith/entities/IDE/constants"; import type { SidebarButtonProps } from "./SidebarButton/SidebarButton"; +import { Flex } from "design-system"; -const Container = styled.div` +const Container = styled(Flex)` width: 50px; border-right: 1px solid var(--ads-v2-color-border); height: 100%; - display: flex; flex-direction: column; justify-content: space-between; background-color: var(--ads-v2-color-bg); @@ -41,10 +41,11 @@ function IDESidebar(props: IDESidebarProps) { ))}
@@ -53,10 +54,11 @@ function IDESidebar(props: IDESidebarProps) { ))} diff --git a/app/client/src/IDE/Components/Sidebar/SidebarButton/SidebarButton.tsx b/app/client/src/IDE/Components/Sidebar/SidebarButton/SidebarButton.tsx index c32a4acd889f..a794166b13b4 100644 --- a/app/client/src/IDE/Components/Sidebar/SidebarButton/SidebarButton.tsx +++ b/app/client/src/IDE/Components/Sidebar/SidebarButton/SidebarButton.tsx @@ -1,5 +1,5 @@ import React, { useCallback } from "react"; -import { Icon, Text, Tooltip } from "design-system"; +import { Flex, Icon, Text, Tooltip } from "design-system"; import styled from "styled-components"; import { Condition } from "../../../enums"; @@ -18,13 +18,13 @@ export interface SidebarButtonProps { title?: string; selected: boolean; icon: string; - onClick: () => void; + onClick: (urlSuffix: string) => void; + urlSuffix: string; tooltip?: string; condition?: Condition; } -const Container = styled.div` - display: flex; +const Container = styled(Flex)` justify-content: center; flex-direction: column; width: 50px; @@ -45,6 +45,7 @@ const IconContainer = styled.div<{ selected: boolean }>` justify-content: center; cursor: pointer; position: relative; + &:hover { background: ${(props) => props.selected @@ -57,42 +58,46 @@ const ConditionIcon = styled(Icon)` position: absolute; bottom: 3px; right: -1px; + &.t--sidebar-${Condition.Warn}-condition-icon { color: ${ConditionConfig[Condition.Warn].color}; } + // TODO add more condition colors here `; function SidebarButton(props: SidebarButtonProps) { + const { condition, icon, onClick, selected, title, tooltip, urlSuffix } = + props; const handleOnClick = useCallback(() => { - if (!props.selected) { - props.onClick(); + if (!selected) { + onClick(urlSuffix); } - }, [props.selected, props.onClick]); + }, [selected, onClick, urlSuffix]); return ( - - {props.condition && ( + + {condition && ( )} - {props.title ? {props.title} : null} + {title ? {title} : null} ); } diff --git a/app/client/src/pages/Editor/IDE/Sidebar.tsx b/app/client/src/pages/Editor/IDE/Sidebar.tsx index e4eb71388a4a..32c92e0a6393 100644 --- a/app/client/src/pages/Editor/IDE/Sidebar.tsx +++ b/app/client/src/pages/Editor/IDE/Sidebar.tsx @@ -1,4 +1,4 @@ -import React, { useCallback, useEffect, useState } from "react"; +import React, { useCallback, useEffect } from "react"; import { useDispatch, useSelector } from "react-redux"; import { builderURL } from "@appsmith/RouteBuilder"; import { getCurrentPageId } from "selectors/editorSelectors"; @@ -19,7 +19,6 @@ import { } from "@appsmith/constants/messages"; function Sidebar() { - const [topButtons, setTopButtons] = useState(TopButtons); const dispatch = useDispatch(); const appState = useCurrentAppState(); const pageId = useSelector(getCurrentPageId); @@ -28,11 +27,10 @@ function Sidebar() { const datasourcesExist = datasources.length > 0; // Updates the top button config based on datasource existence - useEffect(() => { - if (!datasourcesExist) { - // Update the data button to show a warning - setTopButtons( - TopButtons.map((button) => { + const topButtons = React.useMemo(() => { + return datasourcesExist + ? TopButtons + : TopButtons.map((button) => { if (button.state === EditorState.DATA) { return { ...button, @@ -41,12 +39,7 @@ function Sidebar() { }; } return button; - }), - ); - return; - } - // Datasource exists, so reset to standard button config - setTopButtons(TopButtons); + }); }, [datasourcesExist]); useEffect(() => { From e26ee7aeedab6989d581e6c264087037631dcac7 Mon Sep 17 00:00:00 2001 From: Hetu Nandu Date: Mon, 8 Jul 2024 11:59:14 +0530 Subject: [PATCH 12/13] Add missing prop in tests --- .../IDE/Components/Sidebar/SidebarButton/SidebarButton.test.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/app/client/src/IDE/Components/Sidebar/SidebarButton/SidebarButton.test.tsx b/app/client/src/IDE/Components/Sidebar/SidebarButton/SidebarButton.test.tsx index 5c03fa96588f..fe15152a2214 100644 --- a/app/client/src/IDE/Components/Sidebar/SidebarButton/SidebarButton.test.tsx +++ b/app/client/src/IDE/Components/Sidebar/SidebarButton/SidebarButton.test.tsx @@ -9,6 +9,7 @@ const sidebarButtonProps: SidebarButtonProps = { onClick: () => {}, selected: false, title: "Test", + urlSuffix: "/test", }; describe("SidebarButton", () => { From f2d0e9f5f9cef8d0452f74976834a473a14cacd9 Mon Sep 17 00:00:00 2001 From: Hetu Nandu Date: Mon, 8 Jul 2024 12:06:46 +0530 Subject: [PATCH 13/13] Add more button tests --- .../SidebarButton/SidebarButton.test.tsx | 24 +++++++++++++++++++ .../Sidebar/SidebarButton/SidebarButton.tsx | 1 + 2 files changed, 25 insertions(+) diff --git a/app/client/src/IDE/Components/Sidebar/SidebarButton/SidebarButton.test.tsx b/app/client/src/IDE/Components/Sidebar/SidebarButton/SidebarButton.test.tsx index fe15152a2214..ce8ad536826a 100644 --- a/app/client/src/IDE/Components/Sidebar/SidebarButton/SidebarButton.test.tsx +++ b/app/client/src/IDE/Components/Sidebar/SidebarButton/SidebarButton.test.tsx @@ -3,6 +3,7 @@ import React from "react"; import SidebarButton, { type SidebarButtonProps } from "./SidebarButton"; import { Condition } from "../../../enums"; +import userEvent from "@testing-library/user-event"; const sidebarButtonProps: SidebarButtonProps = { icon: "down-arrow", @@ -24,4 +25,27 @@ describe("SidebarButton", () => { const svgs = container.querySelectorAll("svg"); expect(svgs).toHaveLength(2); }); + + it("should call onClick with urlSuffix", async () => { + const checkOnClick = { + ...sidebarButtonProps, + onClick: jest.fn(), + }; + const { getByRole } = render(); + + await userEvent.click(getByRole("button")); + expect(checkOnClick.onClick).toHaveBeenCalledWith(checkOnClick.urlSuffix); + }); + + it("should not call onClick when button is already selected", async () => { + const withSelected = { + ...sidebarButtonProps, + selected: true, + onClick: jest.fn(), + }; + const { getByRole } = render(); + + await userEvent.click(getByRole("button")); + expect(withSelected.onClick).not.toHaveBeenCalled(); + }); }); diff --git a/app/client/src/IDE/Components/Sidebar/SidebarButton/SidebarButton.tsx b/app/client/src/IDE/Components/Sidebar/SidebarButton/SidebarButton.tsx index a794166b13b4..a5c57ff97d38 100644 --- a/app/client/src/IDE/Components/Sidebar/SidebarButton/SidebarButton.tsx +++ b/app/client/src/IDE/Components/Sidebar/SidebarButton/SidebarButton.tsx @@ -85,6 +85,7 @@ function SidebarButton(props: SidebarButtonProps) { className={`t--sidebar-${title || tooltip}`} data-selected={selected} onClick={handleOnClick} + role="button" selected={selected} >