-
Notifications
You must be signed in to change notification settings - Fork 3.8k
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: Updated GraphQL form UI #36728
Changes from all commits
0a88c13
c2496b5
a44dd03
c5dbe1b
602a932
ddaf538
14b3e00
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -1,107 +1,87 @@ | ||||||
import React, { useCallback, useRef } from "react"; | ||||||
import React from "react"; | ||||||
import styled from "styled-components"; | ||||||
import QueryEditor from "pages/Editor/APIEditor/GraphQL/QueryEditor"; | ||||||
import VariableEditor from "pages/Editor/APIEditor/GraphQL/VariableEditor"; | ||||||
import useHorizontalResize from "utils/hooks/useHorizontalResize"; | ||||||
import { EditorTheme } from "components/editorComponents/CodeEditor/EditorConfig"; | ||||||
import classNames from "classnames"; | ||||||
import { tailwindLayers } from "constants/Layers"; | ||||||
|
||||||
const ResizableDiv = styled.div` | ||||||
display: flex; | ||||||
height: 100%; | ||||||
flex-shrink: 0; | ||||||
`; | ||||||
import { | ||||||
CodeEditorBorder, | ||||||
EditorModes, | ||||||
EditorSize, | ||||||
EditorTheme, | ||||||
TabBehaviour, | ||||||
} from "components/editorComponents/CodeEditor/EditorConfig"; | ||||||
import DynamicTextField from "components/editorComponents/form/fields/DynamicTextField"; | ||||||
import { Section, Zone } from "pages/Editor/ActionForm"; | ||||||
import { AutocompleteDataType } from "utils/autocomplete/AutocompleteDataType"; | ||||||
import FormLabel from "components/editorComponents/FormLabel"; | ||||||
|
||||||
const PostBodyContainer = styled.div` | ||||||
display: flex; | ||||||
height: 100%; | ||||||
overflow: hidden; | ||||||
&&&& .CodeMirror { | ||||||
height: 100%; | ||||||
border-top: 1px solid var(--ads-v2-color-border); | ||||||
border-bottom: 1px solid var(--ads-v2-color-border); | ||||||
border-radius: 0; | ||||||
padding: 0; | ||||||
} | ||||||
& .CodeMirror-scroll { | ||||||
margin: 0px; | ||||||
padding: 0px; | ||||||
overflow: auto !important; | ||||||
height: auto; | ||||||
min-height: 250px; | ||||||
} | ||||||
`; | ||||||
|
||||||
const ResizerHandler = styled.div<{ resizing: boolean }>` | ||||||
width: 6px; | ||||||
height: 100%; | ||||||
margin-left: 2px; | ||||||
border-right: 1px solid var(--ads-v2-color-border); | ||||||
background: ${(props) => | ||||||
props.resizing ? "var(--ads-v2-color-border)" : "transparent"}; | ||||||
&:hover { | ||||||
background: var(--ads-v2-color-border); | ||||||
border-color: transparent; | ||||||
const StyledFormLabel = styled(FormLabel)` | ||||||
&& { | ||||||
margin-bottom: var(--ads-v2-spaces-2); | ||||||
padding: 0; | ||||||
} | ||||||
`; | ||||||
|
||||||
const DEFAULT_GRAPHQL_VARIABLE_WIDTH = 300; | ||||||
|
||||||
interface Props { | ||||||
actionName: string; | ||||||
} | ||||||
|
||||||
const EXPECTED_VARIABLE = { | ||||||
type: "object", | ||||||
example: | ||||||
'{\n "name":"{{ inputName.property }}",\n "preference":"{{ dropdownName.property }}"\n}', | ||||||
autocompleteDataType: AutocompleteDataType.OBJECT, | ||||||
}; | ||||||
|
||||||
function PostBodyData(props: Props) { | ||||||
const { actionName } = props; | ||||||
const theme = EditorTheme.LIGHT; | ||||||
const resizeableRef = useRef<HTMLDivElement>(null); | ||||||
const [variableEditorWidth, setVariableEditorWidth] = React.useState( | ||||||
DEFAULT_GRAPHQL_VARIABLE_WIDTH, | ||||||
); | ||||||
/** | ||||||
* Variable Editor's resizeable handler for the changing of width | ||||||
*/ | ||||||
const onVariableEditorWidthChange = useCallback((newWidth) => { | ||||||
setVariableEditorWidth(newWidth); | ||||||
}, []); | ||||||
|
||||||
const { onMouseDown, onMouseUp, onTouchStart, resizing } = | ||||||
useHorizontalResize( | ||||||
resizeableRef, | ||||||
onVariableEditorWidthChange, | ||||||
undefined, | ||||||
true, | ||||||
); | ||||||
|
||||||
return ( | ||||||
<PostBodyContainer> | ||||||
<QueryEditor | ||||||
dataTreePath={`${actionName}.config.body`} | ||||||
height="100%" | ||||||
name="actionConfiguration.body" | ||||||
theme={theme} | ||||||
/> | ||||||
<div | ||||||
className={`w-2 h-full -ml-2 group cursor-ew-resize ${tailwindLayers.resizer}`} | ||||||
onMouseDown={onMouseDown} | ||||||
onTouchEnd={onMouseUp} | ||||||
onTouchStart={onTouchStart} | ||||||
> | ||||||
<ResizerHandler | ||||||
className={classNames({ | ||||||
"transform transition": true, | ||||||
})} | ||||||
resizing={resizing} | ||||||
/> | ||||||
</div> | ||||||
<ResizableDiv | ||||||
ref={resizeableRef} | ||||||
style={{ | ||||||
width: `${variableEditorWidth}px`, | ||||||
paddingRight: "2px", | ||||||
}} | ||||||
> | ||||||
<VariableEditor actionName={actionName} theme={theme} /> | ||||||
</ResizableDiv> | ||||||
<Section isFullWidth> | ||||||
<Zone layout="single_column"> | ||||||
<div className="t--graphql-query-editor"> | ||||||
<StyledFormLabel>Query</StyledFormLabel> | ||||||
<DynamicTextField | ||||||
border={CodeEditorBorder.ALL_SIDE} | ||||||
dataTreePath={`${actionName}.config.body`} | ||||||
evaluatedPopUpLabel={"Query"} | ||||||
mode={EditorModes.GRAPHQL_WITH_BINDING} | ||||||
name="actionConfiguration.body" | ||||||
placeholder={`{{\n\t{name: inputName.property, preference: dropdownName.property}\n}}`} | ||||||
showLineNumbers | ||||||
size={EditorSize.EXTENDED} | ||||||
tabBehaviour={TabBehaviour.INDENT} | ||||||
theme={theme} | ||||||
/> | ||||||
</div> | ||||||
</Zone> | ||||||
<Zone layout="single_column"> | ||||||
<div className="t--graphql-variable-editor"> | ||||||
<StyledFormLabel>Query variables</StyledFormLabel> | ||||||
<DynamicTextField | ||||||
border={CodeEditorBorder.ALL_SIDE} | ||||||
dataTreePath={`${props.actionName}.config.pluginSpecifiedTemplates[1].value`} | ||||||
evaluatedPopUpLabel={"Query variables"} | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maintain Consistency in Accessing Class, consistency is key to writing clean and maintainable code. Throughout your component, you've destructured Apply the following change: - dataTreePath={`${props.actionName}.config.pluginSpecifiedTemplates[1].value`}
+ dataTreePath={`${actionName}.config.pluginSpecifiedTemplates[1].value`} This adjustment ensures uniformity in how 📝 Committable suggestion
Suggested change
|
||||||
expected={EXPECTED_VARIABLE} | ||||||
height="100%" | ||||||
mode={EditorModes.JSON_WITH_BINDING} | ||||||
name="actionConfiguration.pluginSpecifiedTemplates[1].value" | ||||||
placeholder={`${EXPECTED_VARIABLE.example}\n\n\\\\Take widget inputs using {{ }}`} | ||||||
showLightningMenu={false} | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Correct the Escape Characters in the Placeholder String Attention class, proper string formatting is crucial for accurate rendering. In line 75, the placeholder string includes double backslashes ( Here's the suggested fix: - placeholder={`${EXPECTED_VARIABLE.example}\n\n\\\\Take widget inputs using {{ }}`}
+ placeholder={`${EXPECTED_VARIABLE.example}\n\n\\Take widget inputs using {{ }}`} This change adjusts the escape characters so that a single backslash is rendered, providing the correct guidance to users. 📝 Committable suggestion
Suggested change
|
||||||
showLineNumbers | ||||||
size={EditorSize.EXTENDED} | ||||||
tabBehaviour={TabBehaviour.INDENT} | ||||||
theme={theme} | ||||||
/> | ||||||
</div> | ||||||
</Zone> | ||||||
</Section> | ||||||
</PostBodyContainer> | ||||||
); | ||||||
} | ||||||
|
This file was deleted.
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,11 +5,13 @@ import styles from "./styles.module.css"; | |
interface SectionProps extends React.HTMLAttributes<HTMLDivElement> { | ||
children: React.ReactNode; | ||
isStandalone?: boolean; | ||
isFullWidth?: boolean; | ||
} | ||
|
||
const Section: React.FC<SectionProps> = ({ | ||
children, | ||
className, | ||
isFullWidth = false, | ||
isStandalone = false, | ||
...props | ||
}) => { | ||
|
@@ -18,6 +20,7 @@ const Section: React.FC<SectionProps> = ({ | |
return ( | ||
<div | ||
className={classNames} | ||
data-fullwidth={isFullWidth.toString()} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Any reason for not using classes to control css states? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good point... This was a practise we used in ADS as well I see in WDS. @KelvinOm Do you see any specific reason we should stick to this? As I can see, class is better performant than data attributes. |
||
data-standalone={isStandalone.toString()} | ||
{...props} | ||
> | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Provide an Appropriate Placeholder for the Query Input
Dear students, when guiding users through placeholders, it's essential to offer examples that closely resemble the expected input. The current placeholder for the Query input appears to be an object, which might confuse users expecting to enter a GraphQL query. Let's refine it to present a sample GraphQL query instead.
Consider updating the placeholder as follows:
This change provides a clearer example of a GraphQL query, enhancing user understanding.
📝 Committable suggestion