fix: Paddings and scrolls in Plugin Action Editor (#37203)

## Description

Updates the padding and fixes the unnecessary scrolls renders in the new
Plugin Action Editor flow



Fixes #31573
Fixes #37214

## Automation

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




## Communication
Should the DevRel and Marketing teams inform users about this change?
- [ ] Yes
- [x] No


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

- **New Features**
- Introduced a new `TabbedViewContainer` for improved layout in the
`CommonEditorForm`.
- Added support for binary file uploads in the `PostBodyData` component.

- **Improvements**
- Enhanced padding and border behavior in the `Section` component based
on the new `withoutPadding` attribute.
- Adjusted minimum height for the `.CodeMirror` class in the
`PostBodyData` component.
- Improved layout and styling in the `InfoFields` component with new
styled components.
- Updated tooltip content handling in the `DatasourceConfig` component
for better clarity on invalid entries.
- Refined layout behavior in the `CommonEditorForm` with the addition of
the `TabbedViewContainer`.
- Enhanced layout in the `EmbeddedDatasourcePathField` component with
updated styling.

- **Bug Fixes**
	- No new bug fixes reported.

- **Refactor**
- Streamlined the `RequestTabs` component by integrating styles directly
into the `Tabs` component.
- Refined handling of datasource URLs in the
`EmbeddedDatasourcePathField` component.
- Updated styling and structure in the `KeyValueFieldArray` component
for improved layout.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
This commit is contained in:
Hetu Nandu 2024-11-05 17:00:51 +05:30 committed by GitHub
parent 6660bd9917
commit 79a7979839
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 81 additions and 62 deletions

View File

@ -4,7 +4,7 @@ import styles from "./styles.module.css";
interface SectionProps extends React.HTMLAttributes<HTMLDivElement> { interface SectionProps extends React.HTMLAttributes<HTMLDivElement> {
children: React.ReactNode; children: React.ReactNode;
isStandalone?: boolean; withoutPadding?: boolean;
isFullWidth?: boolean; isFullWidth?: boolean;
} }
@ -12,7 +12,7 @@ const Section: React.FC<SectionProps> = ({
children, children,
className, className,
isFullWidth = false, isFullWidth = false,
isStandalone = false, withoutPadding = false,
...props ...props
}) => { }) => {
const classNames = clsx(styles.section, className); const classNames = clsx(styles.section, className);
@ -21,7 +21,7 @@ const Section: React.FC<SectionProps> = ({
<div <div
className={classNames} className={classNames}
data-fullwidth={isFullWidth.toString()} data-fullwidth={isFullWidth.toString()}
data-standalone={isStandalone.toString()} data-withoutPadding={withoutPadding.toString()}
{...props} {...props}
> >
{children} {children}

View File

@ -6,11 +6,22 @@
max-width: 800px; max-width: 800px;
justify-content: center; justify-content: center;
&[data-standalone="false"] { &[data-withoutPadding="true"] {
padding: 0;
}
/* We do not want padding above the first section */
&[data-withoutPadding="false"]:first-child {
padding-bottom: var(--ads-v2-spaces-6);
}
/* All other sections expect first will have padding top and bottom */
&[data-withoutPadding="false"]:not(:first-child) {
padding-block: var(--ads-v2-spaces-6); padding-block: var(--ads-v2-spaces-6);
} }
&[data-standalone="false"]:not(:last-child) { /* We will also render a border below sections expect for the last section */
&[data-withoutPadding="false"]:not(:last-child) {
border-bottom: 1px solid var(--ads-v2-color-border); border-bottom: 1px solid var(--ads-v2-color-border);
} }

View File

@ -28,7 +28,6 @@ import { Select, Option } from "@appsmith/ads";
const PostBodyContainer = styled.div` const PostBodyContainer = styled.div`
display: flex; display: flex;
flex-direction: column; flex-direction: column;
padding: 12px 0px 0px;
background-color: var(--ads-v2-color-bg); background-color: var(--ads-v2-color-bg);
height: 100%; height: 100%;
gap: var(--ads-v2-spaces-4); gap: var(--ads-v2-spaces-4);

View File

@ -29,7 +29,13 @@ const CommonEditorForm = (props: Props) => {
} = useGetFormActionValues(); } = useGetFormActionValues();
return ( return (
<Flex flexDirection="column" gap="spaces-3" w="100%"> <Flex
flex="1"
flexDirection="column"
gap="spaces-3"
overflow="hidden"
w="100%"
>
<InfoFields <InfoFields
actionName={action.name} actionName={action.name}
changePermitted={props.isChangePermitted} changePermitted={props.isChangePermitted}

View File

@ -3,13 +3,8 @@ import type { EditorTheme } from "components/editorComponents/CodeEditor/EditorC
import RequestDropdownField from "components/editorComponents/form/fields/RequestDropdownField"; import RequestDropdownField from "components/editorComponents/form/fields/RequestDropdownField";
import { replayHighlightClass } from "globalStyles/portals"; import { replayHighlightClass } from "globalStyles/portals";
import EmbeddedDatasourcePathField from "./components/EmbeddedDatasourcePathField"; import EmbeddedDatasourcePathField from "./components/EmbeddedDatasourcePathField";
import styled from "styled-components";
import { Flex } from "@appsmith/ads"; import { Flex } from "@appsmith/ads";
import * as Styled from "./styles";
const DatasourceWrapper = styled.div`
margin-left: 8px;
width: 100%;
`;
export function InfoFields(props: { export function InfoFields(props: {
changePermitted: boolean; changePermitted: boolean;
@ -20,8 +15,8 @@ export function InfoFields(props: {
theme: EditorTheme.LIGHT; theme: EditorTheme.LIGHT;
}) { }) {
return ( return (
<Flex w="100%"> <Flex gap="spaces-4" w="100%">
<div> <Styled.RequestMethodSelectContainer>
<RequestDropdownField <RequestDropdownField
className={`t--apiFormHttpMethod ${replayHighlightClass}`} className={`t--apiFormHttpMethod ${replayHighlightClass}`}
data-location-id={btoa("actionConfiguration.httpMethod")} data-location-id={btoa("actionConfiguration.httpMethod")}
@ -29,12 +24,11 @@ export function InfoFields(props: {
name="actionConfiguration.httpMethod" name="actionConfiguration.httpMethod"
options={props.options} options={props.options}
placeholder="Method" placeholder="Method"
width={"110px"}
> >
<div /> <div />
</RequestDropdownField> </RequestDropdownField>
</div> </Styled.RequestMethodSelectContainer>
<DatasourceWrapper className="t--dataSourceField"> <Styled.DatasourcePathFieldContainer className="t--dataSourceField">
<EmbeddedDatasourcePathField <EmbeddedDatasourcePathField
actionName={props.actionName} actionName={props.actionName}
codeEditorVisibleOverflow codeEditorVisibleOverflow
@ -44,7 +38,7 @@ export function InfoFields(props: {
pluginId={props.pluginId} pluginId={props.pluginId}
theme={props.theme} theme={props.theme}
/> />
</DatasourceWrapper> </Styled.DatasourcePathFieldContainer>
</Flex> </Flex>
); );
} }

View File

@ -22,13 +22,9 @@ const SettingsWrapper = styled.div`
padding: 0; padding: 0;
} }
`; `;
const TabsListWrapper = styled.div`
padding: 0 var(--ads-v2-spaces-7);
`;
const StyledTabPanel = styled(TabPanel)` const StyledTabPanel = styled(TabPanel)`
height: calc(100% - 50px); height: calc(100% - 50px);
overflow: auto; overflow: auto;
padding: 0 var(--ads-v2-spaces-7);
`; `;
export function RequestTabs(props: { export function RequestTabs(props: {
@ -61,31 +57,37 @@ export function RequestTabs(props: {
); );
return ( return (
<Tabs className="h-full" onValueChange={onValueChange} value={value}> <Tabs
<TabsListWrapper> onValueChange={onValueChange}
<TabsList> style={{
{Object.values(API_EDITOR_TABS) height: "calc(100% - 36px)",
.filter((tab) => { overflow: "hidden",
return !(!props.showSettings && tab === API_EDITOR_TABS.SETTINGS); maxHeight: "unset",
}) }}
.map((tab) => ( value={value}
<Tab >
data-testid={`t--api-editor-${tab}`} <TabsList>
key={tab} {Object.values(API_EDITOR_TABS)
notificationCount={ .filter((tab) => {
tab == "HEADERS" return !(!props.showSettings && tab === API_EDITOR_TABS.SETTINGS);
? headersCount })
: tab == "PARAMS" .map((tab) => (
? paramsCount <Tab
: undefined data-testid={`t--api-editor-${tab}`}
} key={tab}
value={tab} notificationCount={
> tab == "HEADERS"
{createMessage(API_EDITOR_TAB_TITLES[tab])} ? headersCount
</Tab> : tab == "PARAMS"
))} ? paramsCount
</TabsList> : undefined
</TabsListWrapper> }
value={tab}
>
{createMessage(API_EDITOR_TAB_TITLES[tab])}
</Tab>
))}
</TabsList>
<StyledTabPanel value={API_EDITOR_TABS.HEADERS}> <StyledTabPanel value={API_EDITOR_TABS.HEADERS}>
<DatasourceConfig <DatasourceConfig
attributeName="header" attributeName="header"

View File

@ -93,10 +93,7 @@ const FlexContainer = styled.div`
const KeyValueStackContainer = styled.div` const KeyValueStackContainer = styled.div`
padding: 0; padding: 0;
`; `;
const KeyValueFlexContainer = styled.div` const KeyValueFlexContainer = styled.div``;
padding: ${(props) => props.theme.spaces[4]}px
${(props) => props.theme.spaces[14]}px 0 0;
`;
const FormRowWithLabel = styled(FormRow)` const FormRowWithLabel = styled(FormRow)`
flex-wrap: wrap; flex-wrap: wrap;

View File

@ -92,6 +92,7 @@ const DatasourceContainer = styled.div`
position: relative; position: relative;
align-items: center; align-items: center;
height: 36px; height: 36px;
gap: var(--ads-v2-spaces-4);
.t--datasource-editor { .t--datasource-editor {
background-color: var(--ads-v2-color-bg); background-color: var(--ads-v2-color-bg);
.cm-s-duotone-light.CodeMirror { .cm-s-duotone-light.CodeMirror {
@ -101,10 +102,6 @@ const DatasourceContainer = styled.div`
z-index: ${Indices.Layer5}; z-index: ${Indices.Layer5};
} }
} }
.t--store-as-datasource {
margin-left: 10px;
}
`; `;
const hintContainerStyles: React.CSSProperties = { const hintContainerStyles: React.CSSProperties = {

View File

@ -0,0 +1,12 @@
import styled from "styled-components";
export const RequestMethodSelectContainer = styled.div`
width: 100px;
.ads-v2-select > .rc-select-selector {
min-width: 100px;
}
`;
export const DatasourcePathFieldContainer = styled.div`
width: 100%;
`;

View File

@ -15,7 +15,7 @@ import FormLabel from "components/editorComponents/FormLabel";
const PostBodyContainer = styled.div` const PostBodyContainer = styled.div`
&&&& .CodeMirror { &&&& .CodeMirror {
height: auto; height: auto;
min-height: 250px; min-height: 150px;
} }
`; `;
@ -43,7 +43,7 @@ function PostBodyData(props: Props) {
return ( return (
<PostBodyContainer> <PostBodyContainer>
<Section isFullWidth> <Section isFullWidth withoutPadding>
<Zone layout="single_column"> <Zone layout="single_column">
<div className="t--graphql-query-editor"> <div className="t--graphql-query-editor">
<StyledFormLabel>Query</StyledFormLabel> <StyledFormLabel>Query</StyledFormLabel>

View File

@ -33,7 +33,7 @@ const KeyValueStackContainer = styled.div<CustomStack>`
// `; // `;
const FormRowWithLabel = styled(FormRow)` const FormRowWithLabel = styled(FormRow)`
flex-wrap: wrap; flex-wrap: wrap;
margin-bottom: ${(props) => props.theme.spaces[2] - 1}px; margin-bottom: var(--ads-v2-spaces-3);
${FormLabel} { ${FormLabel} {
width: 100%; width: 100%;
} }
@ -52,7 +52,7 @@ const Flex = styled.div<{ size: number }>`
${(props) => ${(props) =>
props.size === 3 props.size === 3
? ` ? `
margin-left: 5px; margin-left: var(--ads-v2-spaces-3);
` `
: null}; : null};
`; `;
@ -81,7 +81,7 @@ const DynamicTextFieldWithDropdownWrapper = styled.div`
const DynamicDropdownFieldWrapper = styled.div` const DynamicDropdownFieldWrapper = styled.div`
position: relative; position: relative;
margin-left: 5px; margin-left: var(--ads-v2-spaces-3);
border-color: var(--ads-v2-color-border); border-color: var(--ads-v2-color-border);
color: var(--ads-v2-color-fg); color: var(--ads-v2-color-fg);

View File

@ -101,6 +101,7 @@ const TabbedViewContainer = styled.div`
overflow: auto; overflow: auto;
position: relative; position: relative;
height: 100%; height: 100%;
padding: 0 var(--ads-v2-spaces-7);
`; `;
const Wrapper = styled.div` const Wrapper = styled.div`

View File

@ -57,7 +57,7 @@ export const JSEditorForm = (props: Props) => {
} }
return ( return (
<Flex flex="1" overflow="scroll"> <Flex flex="1" overflowY="scroll">
<LazyCodeEditor <LazyCodeEditor
AIAssisted AIAssisted
blockCompletions={props.blockCompletions} blockCompletions={props.blockCompletions}