Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Overflow tabs list view #34150

Merged
merged 21 commits into from
Jun 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
4f2ef49
feat: New ui for overflow tabs
albinAppsmith Jun 10, 2024
4eec56e
Merge branch 'release' of https://github.com/appsmithorg/appsmith int…
albinAppsmith Jun 10, 2024
3031920
fix: new tab click fix
albinAppsmith Jun 10, 2024
914614d
Merge branch 'release' of https://github.com/appsmithorg/appsmith int…
albinAppsmith Jun 10, 2024
1a499f3
Merge branch 'release' of https://github.com/appsmithorg/appsmith int…
albinAppsmith Jun 17, 2024
f98571d
fix: optmised editortab component
albinAppsmith Jun 17, 2024
22b2dfb
chore: Optimisations
albinAppsmith Jun 19, 2024
000cde8
removed refs
albinAppsmith Jun 20, 2024
ad3f4e7
Merge branch 'release' of https://github.com/appsmithorg/appsmith int…
albinAppsmith Jun 20, 2024
d31c64f
fix: seperated add button and tab
albinAppsmith Jun 20, 2024
8b98201
added border for sticky button
albinAppsmith Jun 21, 2024
e14a985
Merge branch 'release' of https://github.com/appsmithorg/appsmith int…
albinAppsmith Jun 21, 2024
c1d0795
added missing dependency
albinAppsmith Jun 21, 2024
f89cecc
fix: removed scrollbar defer
albinAppsmith Jun 21, 2024
2703067
Merge branch 'release' of https://github.com/appsmithorg/appsmith int…
albinAppsmith Jun 24, 2024
77611ad
fix: show list issues
albinAppsmith Jun 24, 2024
7d07044
Merge branch 'release' of https://github.com/appsmithorg/appsmith int…
albinAppsmith Jun 24, 2024
43b8219
Merge branch 'release' of https://github.com/appsmithorg/appsmith int…
albinAppsmith Jun 25, 2024
296c976
fix: cypress failures
albinAppsmith Jun 25, 2024
1c829af
Merge branch 'release' of https://github.com/appsmithorg/appsmith int…
albinAppsmith Jun 25, 2024
fb8addb
fix: jest test fix
albinAppsmith Jun 25, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ describe("IDE add pane interactions", { tags: ["@tag.IDE"] }, () => {
// check add pane
PageLeftPane.assertInAddView();
// close add tab
FileTabs.closeTab("new");
FileTabs.closeTab("new_query");
// open add pane to add item
PageLeftPane.switchToAddNew();
// add item
Expand Down
4 changes: 3 additions & 1 deletion app/client/cypress/support/Pages/IDE/FileTabs.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { ObjectsRegistry } from "../../Objects/Registry";
import { sanitizeString } from "../../../../src/utils/URLUtils";
class FileTabs {
locators = {
container: "[data-testid='t--editor-tabs']",
tabName: (name: string) => `[data-testid='t--ide-tab-${name}']`,
tabName: (name: string) =>
`[data-testid='t--ide-tab-${sanitizeString(name)}']`,
tabs: ".editor-tab",
addItem: "[data-testid='t--ide-tabs-add-button']",
closeTab: "[data-testid='t--tab-close-btn']",
Expand Down
98 changes: 98 additions & 0 deletions app/client/src/IDE/Components/FileTab.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import React from "react";
import styled from "styled-components";
import clsx from "classnames";

import { Flex, Icon } from "design-system";
import { sanitizeString } from "utils/URLUtils";

interface FileTabProps {
isActive: boolean;
title: string;
onClick: () => void;
onClose: (e: React.MouseEvent) => void;
icon?: React.ReactNode;
}

export const StyledTab = styled(Flex)`
position: relative;
height: 100%;
font-size: 12px;
color: var(--ads-v2-colors-text-default);
cursor: pointer;
gap: var(--ads-v2-spaces-2);
border-top: 1px solid transparent;
border-top-left-radius: var(--ads-v2-border-radius);
border-top-right-radius: var(--ads-v2-border-radius);
align-items: center;
justify-content: center;
padding: var(--ads-v2-spaces-3);
border-left: 1px solid transparent;
border-right: 1px solid transparent;
border-top: 2px solid transparent;

&.active {
background: var(--ads-v2-colors-control-field-default-bg);
border-top-color: var(--ads-v2-color-bg-brand);
border-left-color: var(--ads-v2-color-border-muted);
border-right-color: var(--ads-v2-color-border-muted);
}

& > .tab-close {
position: relative;
right: -2px;
visibility: hidden;
}

&:hover > .tab-close {
visibility: visible;
}

&.active > .tab-close {
visibility: visible;
}
`;

export const TabTextContainer = styled.span`
width: 100%;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
`;

export const TabIconContainer = styled.div`
height: 12px;
width: 12px;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
img {
width: 12px;
}
`;

export const FileTab = ({
icon,
isActive,
onClick,
onClose,
title,
}: FileTabProps) => {
return (
<StyledTab
className={clsx("editor-tab", isActive && "active")}
data-testid={`t--ide-tab-${sanitizeString(title)}`}
onClick={onClick}
>
{icon ? <TabIconContainer>{icon}</TabIconContainer> : null}
<TabTextContainer>{title}</TabTextContainer>
{/* not using button component because of the size not matching design */}
<Icon
className="tab-close rounded-[4px] hover:bg-[var(--ads-v2-colors-action-tertiary-surface-hover-bg)] cursor-pointer p-[2px]"
data-testid="t--tab-close-btn"
name="close-line"
onClick={onClose}
/>
</StyledTab>
);
};
3 changes: 2 additions & 1 deletion app/client/src/ce/pages/Editor/IDE/EditorPane/JS/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import history from "utils/history";
import { FocusEntity, identifyEntityFromPath } from "navigation/FocusEntity";
import { useModuleOptions } from "@appsmith/utils/moduleInstanceHelpers";
import { getJSUrl } from "@appsmith/pages/Editor/IDE/EditorPane/JS/utils";
import { JSBlankState } from "pages/Editor/JSEditor/JSBlankState";

export const useJSAdd = () => {
const pageId = useSelector(getCurrentPageId);
Expand Down Expand Up @@ -95,7 +96,7 @@ export const useJSSegmentRoutes = (path: string): UseRoutes => {
},
{
key: "JSEmpty",
component: ListJS,
component: JSBlankState,
exact: true,
path: [path],
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import { Tag, type ListItemProps } from "design-system";
import { useCurrentEditorState } from "pages/Editor/IDE/hooks";
import CurlImportEditor from "pages/Editor/APIEditor/CurlImportEditor";
import { createAddClassName } from "pages/Editor/IDE/EditorPane/utils";
import { QueriesBlankState } from "pages/Editor/QueryEditor/QueriesBlankState";

export const useQueryAdd = () => {
const location = useLocation();
Expand Down Expand Up @@ -161,7 +162,7 @@ export const useQuerySegmentRoutes = (path: string): UseRoutes => {
},
{
key: "QueryEmpty",
component: ListQuery,
component: QueriesBlankState,
albinAppsmith marked this conversation as resolved.
Show resolved Hide resolved
exact: true,
path: [path],
},
Expand Down
43 changes: 19 additions & 24 deletions app/client/src/ce/selectors/appIDESelectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
getQuerySegmentItems,
} from "@appsmith/selectors/entitiesSelector";
import { getJSTabs, getQueryTabs } from "selectors/ideSelectors";
import type { AppState } from "@appsmith/reducers";

export type EditorSegmentList = Array<{
group: string | "NA";
Expand Down Expand Up @@ -45,28 +46,22 @@ export const selectJSSegmentEditorList = createSelector(
},
);

export const selectJSSegmentEditorTabs = createSelector(
getJSSegmentItems,
getJSTabs,
(items, tabs) => {
const keyedItems = keyBy(items, "key");
return tabs
.map((tab) => {
return keyedItems[tab];
})
.filter(Boolean);
},
);
export const selectJSSegmentEditorTabs = (state: AppState) => {
const items = getJSSegmentItems(state);
const tabs = getJSTabs(state);

export const selectQuerySegmentEditorTabs = createSelector(
getQuerySegmentItems,
getQueryTabs,
(items, tabs) => {
const keyedItems = keyBy(items, "key");
return tabs
.map((tab) => {
return keyedItems[tab];
})
.filter(Boolean);
},
);
const keyedItems = keyBy(items, "key");
return tabs
.map((tab) => {
return keyedItems[tab];
})
.filter(Boolean);
};

export const selectQuerySegmentEditorTabs = (state: AppState) => {
const items = getQuerySegmentItems(state);
const tabs = getQueryTabs(state);

const keyedItems = keyBy(items, "key");
return tabs.map((tab) => keyedItems[tab]).filter(Boolean);
};
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import QueriesSegment from "./Query";
import WidgetsSegment from "./UI";
import JSSegment from "./JS";
import SegmentedHeader from "./components/SegmentedHeader";
import EditorTabs from "../EditorTabs/SplitScreenTabs";
import EditorTabs from "../EditorTabs";
import {
jsSegmentRoutes,
querySegmentRoutes,
Expand All @@ -17,19 +17,23 @@ import {
BUILDER_PATH,
BUILDER_PATH_DEPRECATED,
} from "@appsmith/constants/routes/appRoutes";
import { useSelector } from "react-redux";
import { getIDEViewMode } from "selectors/ideSelectors";
import { EditorViewMode } from "@appsmith/entities/IDE/constants";

const EditorPaneSegments = () => {
const { path } = useRouteMatch();
const ideViewMode = useSelector(getIDEViewMode);

return (
<Flex
className="relative"
flexDirection="column"
gap="spacing-2"
height="100%"
overflow="hidden"
>
<SegmentedHeader />
<EditorTabs />
{ideViewMode === EditorViewMode.SplitScreen ? <EditorTabs /> : null}
<Flex
className="ide-editor-left-pane__content"
flexDirection="column"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ describe("IDE Render: JS", () => {
).toBe(true);
// Tabs active state
expect(
getByTestId("t--ide-tab-JSObject1").classList.contains("active"),
getByTestId("t--ide-tab-jsobject1").classList.contains("active"),
).toBe(true);
// Check if the form is rendered
expect(container.querySelector(".js-editor-tab")).not.toBeNull();
Expand Down Expand Up @@ -201,7 +201,7 @@ describe("IDE Render: JS", () => {
expect(getAllByText("JSObject2").length).toBe(2);
// Tabs active state
expect(
getByTestId("t--ide-tab-JSObject2").classList.contains("active"),
getByTestId("t--ide-tab-jsobject2").classList.contains("active"),
).toBe(true);

// Check if the form is rendered
Expand Down Expand Up @@ -245,7 +245,7 @@ describe("IDE Render: JS", () => {
expect(getAllByText("JSObject3").length).toEqual(2);
// Tabs active state
expect(
getByTestId("t--ide-tab-JSObject3").classList.contains("active"),
getByTestId("t--ide-tab-jsobject3").classList.contains("active"),
).toBe(false);
// Check js object is not rendered. Instead new tab should render
expect(container.querySelector(".js-editor-tab")).toBeNull();
Expand Down Expand Up @@ -283,7 +283,7 @@ describe("IDE Render: JS", () => {
expect(getAllByText("JSObject4").length).toEqual(1);
// Tabs active state
expect(
getByTestId("t--ide-tab-JSObject4").classList.contains("active"),
getByTestId("t--ide-tab-jsobject4").classList.contains("active"),
).toBe(false);

// Check if the form is not rendered
Expand Down
2 changes: 1 addition & 1 deletion app/client/src/pages/Editor/IDE/EditorPane/JS/List.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ const ListJSObjects = () => {
return (
<JSContainer
className="ide-editor-left-pane__content-js"
flex="1"
flexDirection="column"
gap="spaces-3"
overflow="hidden"
Expand All @@ -77,7 +78,6 @@ const ListJSObjects = () => {
>
<Flex
data-testid="t--ide-list"
flex="1"
flexDirection="column"
gap="spaces-4"
overflowY="auto"
Expand Down
Loading
Loading