feat: Queries and JS tabs redesign (#31006)

## Description

This PR introduces significant enhancements to the queries and JS tabs
design, aimed at improving user experience.


#### PR fixes following issue(s)
Fixes https://github.com/appsmithorg/appsmith/issues/30862

#### Media


https://github.com/appsmithorg/appsmith/assets/87797149/8453de14-ee78-4835-8528-8a94cd84d660



#### Type of change

- Bug fix (non-breaking change which fixes an issue)
- New feature (non-breaking change which adds functionality)


## Testing
>
#### How Has This Been Tested?
> Please describe the tests that you ran to verify your changes. Also
list any relevant details for your test configuration.
> Delete anything that is not relevant
- [ ] Manual
- [ ] JUnit
- [ ] Jest
- [ ] Cypress
>
>
#### Test Plan
> Add Testsmith test cases links that relate to this PR
>
>
#### Issues raised during DP testing
> Link issues raised during DP testing for better visiblity and tracking
(copy link from comments dropped on this PR)
>
>
>
## Checklist:
#### Dev activity
- [x] My code follows the style guidelines of this project
- [x] I have performed a self-review of my own code
- [x] I have commented my code, particularly in hard-to-understand areas
- [ ] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [ ] I have added tests that prove my fix is effective or that my
feature works
- [x] New and existing unit tests pass locally with my changes
- [ ] PR is being merged under a feature flag


#### QA activity:
- [ ] [Speedbreak
features](https://github.com/appsmithorg/TestSmith/wiki/Guidelines-for-test-plans#speedbreakers-)
have been covered
- [ ] Test plan covers all impacted features and [areas of
interest](https://github.com/appsmithorg/TestSmith/wiki/Guidelines-for-test-plans#areas-of-interest-)
- [ ] Test plan has been peer reviewed by project stakeholders and other
QA members
- [ ] Manually tested functionality on DP
- [ ] We had an implementation alignment call with stakeholders post QA
Round 2
- [ ] Cypress test cases have been added and approved by SDET/manual QA
- [ ] Added `Test Plan Approved` label after Cypress tests were reviewed
- [ ] Added `Test Plan Approved` label after JUnit tests were reviewed


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Enhanced UI with a new icon and tooltip for better visual cues in the
editor tabs.
- Introduced a styled icon container in the `QueryTab` for displaying
the current plugin icon next to the tab title.
- Added a new constant for default split screen width, improving layout
responsiveness.
- **Style**
- Updated styling properties across various components for improved
alignment, background color, and overall aesthetics.
- Introduced a `StyledButton` component for a more customized button
appearance in split-screen tabs.
- Adjusted tab width and styling for a cleaner, more organized tab
display.
- **Refactor**
- Improved layout behavior of editor tabs by adjusting height properties
and removing unnecessary overflow and padding.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
albinAppsmith 2024-02-09 12:44:41 +05:30 committed by GitHub
parent ca5631e02c
commit bc8e77be9a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 108 additions and 26 deletions

View File

@ -108,7 +108,7 @@
"cypress-log-to-output": "^1.1.2",
"dayjs": "^1.10.6",
"deep-diff": "^1.0.2",
"design-system": "npm:@appsmithorg/design-system@2.1.31",
"design-system": "npm:@appsmithorg/design-system@2.1.32",
"design-system-old": "npm:@appsmithorg/design-system-old@1.1.14",
"downloadjs": "^1.4.7",
"echarts": "^5.4.2",

View File

@ -13,6 +13,7 @@ export const DEFAULT_ENTITY_EXPLORER_WIDTH = 256;
export const DEFAULT_PROPERTY_PANE_WIDTH = 288;
export const APP_SETTINGS_PANE_WIDTH = 525;
export const DEFAULT_EDITOR_PANE_WIDTH = 255;
export const DEFAULT_SPLIT_SCREEN_WIDTH = "40.4vw";
const APP_STORE_NAMESPACE = "APPSMITH_LOCAL_STORE";

View File

@ -81,12 +81,13 @@ const SegmentedHeader = () => {
) : null}
{isSideBySideEnabled && editorMode === EditorViewMode.SplitScreen ? (
<Button
id="editor-mode-maximize"
isIconButton
kind="tertiary"
onClick={() =>
dispatch(setIdeEditorViewMode(EditorViewMode.FullScreen))
}
startIcon="icon-align-right"
startIcon="maximize"
/>
) : null}
</Container>

View File

@ -5,10 +5,13 @@ import { Flex } from "design-system";
const Container = (props: { children: ReactNode }) => {
return (
<Flex
alignItems="center"
backgroundColor="#F8FAFC"
borderBottom="#F1F5F9"
borderBottom="1px solid var(--ads-v2-color-border)"
gap="spaces-2"
padding="spaces-2"
maxHeight="32px"
minHeight="32px"
px="spaces-2"
width="100%"
>
{props.children}

View File

@ -29,13 +29,7 @@ const FileTabs = () => {
}
return (
<Flex
className="editor-tabs"
flex="1"
gap="spaces-2"
overflow="hidden"
paddingBottom="spaces-2"
>
<Flex data-test-id="editor-tabs" flex="1" gap="spaces-2" height="100%">
{files.map((tab: EntityItem) =>
segment === EditorEntityTab.JS ? (
<JSTab data={tab} key={tab.key} />

View File

@ -26,10 +26,11 @@ const FullScreenTabs = () => {
<Container>
<FileTabs />
<Button
id="editor-mode-minimize"
isIconButton
kind="tertiary"
onClick={setSplitScreenMode}
startIcon="icon-align-left"
startIcon="minimize"
/>
</Container>
);

View File

@ -7,7 +7,9 @@ import { getCurrentPageId } from "@appsmith/selectors/entitiesSelector";
import { useActiveAction } from "@appsmith/pages/Editor/Explorer/hooks";
import { jsCollectionIdURL } from "@appsmith/RouteBuilder";
import history, { NavigationMethod } from "utils/history";
import { StyledTab } from "./StyledComponents";
import { StyledTab, TabTextContainer } from "./StyledComponents";
import { JsFileIconV2 } from "pages/Editor/Explorer/ExplorerIcons";
import { Tooltip } from "design-system";
const JSTab = ({ data }: { data: EntityItem }) => {
const activeActionId = useActiveAction();
@ -30,7 +32,10 @@ const JSTab = ({ data }: { data: EntityItem }) => {
className={clsx("editor-tab", activeActionId === data.key && "active")}
onClick={navigateToJSCollection}
>
{data.title}
{JsFileIconV2(12, 12)}
<Tooltip content={data.title} mouseEnterDelay={1}>
<TabTextContainer>{data.title}</TabTextContainer>
</Tooltip>
</StyledTab>
);
};

View File

@ -1,19 +1,36 @@
import React, { useMemo } from "react";
import clsx from "classnames";
import { useSelector } from "react-redux";
import { Tooltip } from "design-system";
import styled from "styled-components";
import type { EntityItem } from "@appsmith/entities/IDE/constants";
import {
getAction,
getPlugins,
getCurrentPageId,
getPlugin,
} from "@appsmith/selectors/entitiesSelector";
import { useActiveAction } from "@appsmith/pages/Editor/Explorer/hooks";
import history, { NavigationMethod } from "utils/history";
import { getActionConfig } from "pages/Editor/Explorer/Actions/helpers";
import type { Action } from "entities/Action";
import keyBy from "lodash/keyBy";
import { StyledTab } from "./StyledComponents";
import { StyledTab, TabTextContainer } from "./StyledComponents";
import { getAssetUrl } from "@appsmith/utils/airgapHelpers";
const StyledIconContainer = styled.div`
height: 12px;
width: 12px;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
img {
width: 12px;
}
`;
const QueryTab = ({ data }: { data: EntityItem }) => {
const activeActionId = useActiveAction();
@ -21,6 +38,9 @@ const QueryTab = ({ data }: { data: EntityItem }) => {
const plugins = useSelector(getPlugins);
const pluginGroups = useMemo(() => keyBy(plugins, "id"), [plugins]);
const action = useSelector((state) => getAction(state, data.key)) as Action;
const currentPlugin = useSelector((state) =>
getPlugin(state, action?.pluginId || ""),
);
const config = getActionConfig(data.type);
const url = config?.getURL(
@ -39,7 +59,17 @@ const QueryTab = ({ data }: { data: EntityItem }) => {
className={clsx("editor-tab", activeActionId === data.key && "active")}
onClick={navigateToQuery}
>
{data.title}
{currentPlugin && (
<StyledIconContainer>
<img
alt={currentPlugin.name}
src={getAssetUrl(currentPlugin?.iconLocation)}
/>
</StyledIconContainer>
)}
<Tooltip content={data.title} mouseEnterDelay={1}>
<TabTextContainer>{data.title}</TabTextContainer>
</Tooltip>
</StyledTab>
);
};

View File

@ -1,8 +1,9 @@
import React, { useCallback } from "react";
import { Button } from "design-system";
import FileTabs from "./FileTabs";
import { useSelector } from "react-redux";
import { getIDEViewMode, getIsSideBySideEnabled } from "selectors/ideSelectors";
import { Button } from "design-system";
import Container from "./Container";
import { useCurrentEditorState } from "../hooks";
import {

View File

@ -1,16 +1,59 @@
import styled from "styled-components";
import { Flex } from "design-system";
import { DEFAULT_SPLIT_SCREEN_WIDTH } from "constants/AppConstants";
/**
* Logic for 54px in max width
*
* 4px tabs + add icon container left padding
* 4px tabs + add icon container right padding
* 4px gap between tabs and add icon
* 4px gap between every tabs * 4 (since max tab count is 5,
* there will be 5 gaps)
* 26px Add button width
* ======================================
* 54px
*
*/
export const StyledTab = styled(Flex)`
border-radius: var(--ads-v2-border-radius);
position: relative;
top: 1px;
padding: var(--ads-v2-spaces-2) var(--ads-v2-spaces-4);
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;
max-width: calc((${DEFAULT_SPLIT_SCREEN_WIDTH} - 54px) / 5);
// After element - the seperator in between tabs
&:not(&.active):not(:has(+ .active)):not(:last-child):after {
content: "";
position: absolute;
right: 0;
top: 8px;
width: 1px;
height: 40%;
background-color: var(--ads-v2-color-border);
}
&.active {
background-color: var(--ads-v2-colors-control-knob-default-bg);
color: var(--ads-v2-colors-text-default);
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.12);
border-top: 1px solid var(--ads-v2-color-bg-brand);
box-shadow:
1px 0px 0px 0px var(--ads-v2-color-border) inset,
-1px 0px 0px 0px var(--ads-v2-color-border) inset;
}
`;
export const TabTextContainer = styled.span`
width: 100%;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
`;

View File

@ -22,7 +22,10 @@ import isEmpty from "lodash/isEmpty";
import pickBy from "lodash/pickBy";
import { getFocusInfo } from "selectors/focusHistorySelectors";
import { getCurrentGitBranch } from "selectors/gitSyncSelectors";
import { DEFAULT_EDITOR_PANE_WIDTH } from "constants/AppConstants";
import {
DEFAULT_EDITOR_PANE_WIDTH,
DEFAULT_SPLIT_SCREEN_WIDTH,
} from "constants/AppConstants";
import { useFeatureFlag } from "utils/hooks/useFeatureFlag";
import { FEATURE_FLAG } from "@appsmith/entities/FeatureFlag";
@ -118,7 +121,7 @@ export const useEditorPaneWidth = (): string => {
segment !== EditorEntityTab.UI
) {
// 1px is propertypane border width
setWidth("40.4vw");
setWidth(DEFAULT_SPLIT_SCREEN_WIDTH);
} else {
setWidth(DEFAULT_EDITOR_PANE_WIDTH + "px");
}

View File

@ -13202,7 +13202,7 @@ __metadata:
cypress-xpath: ^1.6.0
dayjs: ^1.10.6
deep-diff: ^1.0.2
design-system: "npm:@appsmithorg/design-system@2.1.31"
design-system: "npm:@appsmithorg/design-system@2.1.32"
design-system-old: "npm:@appsmithorg/design-system-old@1.1.14"
diff: ^5.0.0
dotenv: ^8.1.0
@ -17199,9 +17199,9 @@ __metadata:
languageName: node
linkType: hard
"design-system@npm:@appsmithorg/design-system@2.1.31":
version: 2.1.31
resolution: "@appsmithorg/design-system@npm:2.1.31"
"design-system@npm:@appsmithorg/design-system@2.1.32":
version: 2.1.32
resolution: "@appsmithorg/design-system@npm:2.1.32"
dependencies:
"@radix-ui/react-dialog": ^1.0.2
"@radix-ui/react-dropdown-menu": ^2.0.4
@ -17231,7 +17231,7 @@ __metadata:
react-dom: ^17.0.2
react-router-dom: ^5.0.0
styled-components: ^5.3.6
checksum: 4fc89bbb7f4403a9583960dd410c722ed3469e22c3e3d3bc256b3024ce6a7288f46308ef89386d931c264e9179cf22141f673f1c0ed9675dc60e8401c3845be8
checksum: b7c4b8e9ce0c70bf1d53082a42f7efeac4f7e913d445aee79a310c9904351c8640b42fdf17d75cb8a1bcec3635a5fce4badd1f60085408044019cd38c9080997
languageName: node
linkType: hard