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

chore: Add redesign for JS Editor Form #36948

Merged
merged 1 commit into from
Oct 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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 @@ -54,14 +54,19 @@ export const EditorThemes: Record<EditorTheme, string> = {
[EditorTheme.DARK]: "duotone-dark",
};

export interface BlockCompletion {
parentPath: string;
subPath: string;
}

export interface FieldEntityInformation {
entityName?: string;
expectedType?: AutocompleteDataType;
entityType?: EntityTypeValue;
entityId?: string;
propertyPath?: string;
isTriggerPath?: boolean;
blockCompletions?: Array<{ parentPath: string; subPath: string }>;
blockCompletions?: Array<BlockCompletion>;
example?: ExpectedValueExample;
mode?: TEditorModes;
token?: CodeMirror.Token;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ import type {
Hinter,
HintHelper,
MarkHelper,
BlockCompletion,
} from "components/editorComponents/CodeEditor/EditorConfig";
import {
EditorModes,
Expand Down Expand Up @@ -199,7 +200,7 @@ export interface EditorStyleProps {
evaluationSubstitutionType?: EvaluationSubstitutionType;
popperPlacement?: Placement;
popperZIndex?: Indices;
blockCompletions?: FieldEntityInformation["blockCompletions"];
blockCompletions?: Array<BlockCompletion>;
}
/**
* line => Line to which the gutter is added
Expand Down
98 changes: 19 additions & 79 deletions app/client/src/pages/Editor/JSEditor/Form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,7 @@ import type { ChangeEvent } from "react";
import React, { useCallback, useEffect, useMemo, useState } from "react";
import type { JSAction } from "entities/JSCollection";
import type { DropdownOnSelect } from "@appsmith/ads-old";
import {
CodeEditorBorder,
EditorModes,
EditorSize,
EditorTheme,
TabBehaviour,
} from "components/editorComponents/CodeEditor/EditorConfig";
import { EditorTheme } from "components/editorComponents/CodeEditor/EditorConfig";
import type { JSObjectNameEditorProps } from "./JSObjectNameEditor";
import JSObjectNameEditor from "./JSObjectNameEditor";
import {
Expand Down Expand Up @@ -40,7 +34,6 @@ import {
getJSFunctionLineGutter,
getJSPropertyLineFromName,
} from "./utils";
import JSFunctionSettingsView from "./JSFunctionSettings";
import type { JSFunctionSettingsProps } from "./JSFunctionSettings";
import JSObjectHotKeys from "./JSObjectHotKeys";
import {
Expand All @@ -49,7 +42,6 @@ import {
FormWrapper,
NameWrapper,
StyledFormRow,
TabbedViewContainer,
} from "./styledComponents";
import { getJSPaneConfigSelectedTab } from "selectors/jsPaneSelectors";
import type { EventLocation } from "ee/utils/analyticsUtilTypes";
Expand All @@ -59,10 +51,8 @@ import {
} from "actions/editorContextActions";
import history from "utils/history";
import { CursorPositionOrigin } from "ee/reducers/uiReducers/editorContextReducer";
import LazyCodeEditor from "components/editorComponents/LazyCodeEditor";
import styled from "styled-components";
import { Tab, TabPanel, Tabs, TabsList } from "@appsmith/ads";
import { JSEditorTab } from "reducers/uiReducers/jsPaneReducer";
import type { JSEditorTab } from "reducers/uiReducers/jsPaneReducer";
import { useFeatureFlag } from "utils/hooks/useFeatureFlag";
import { FEATURE_FLAG } from "ee/entities/FeatureFlag";
import {
Expand All @@ -72,6 +62,7 @@ import {
import type { JSCollectionData } from "ee/reducers/entityReducers/jsActionsReducer";
import { DEBUGGER_TAB_KEYS } from "components/editorComponents/Debugger/constants";
import RunHistory from "ee/components/RunHistory";
import { JSEditorForm as EditorForm } from "./JSEditorForm";

interface JSFormProps {
jsCollectionData: JSCollectionData;
Expand Down Expand Up @@ -384,73 +375,22 @@ function JSEditorForm({
<Wrapper>
<div className="flex flex-1 w-full">
<SecondaryWrapper>
<TabbedViewContainer isExecuting={isExecutingCurrentJSAction}>
<Tabs
defaultValue={JSEditorTab.CODE}
onValueChange={(string) =>
setSelectedConfigTab(string as JSEditorTab)
}
value={selectedConfigTab}
>
<TabsList>
<Tab
data-testid={`t--js-editor-` + JSEditorTab.CODE}
value={JSEditorTab.CODE}
>
Code
</Tab>
{showSettings && (
<Tab
data-testid={`t--js-editor-` + JSEditorTab.SETTINGS}
value={JSEditorTab.SETTINGS}
>
Settings
</Tab>
)}
</TabsList>
<TabPanel value={JSEditorTab.CODE}>
<div className="js-editor-tab">
<LazyCodeEditor
AIAssisted
blockCompletions={blockCompletions}
border={CodeEditorBorder.NONE}
borderLess
className={"js-editor"}
customGutter={JSGutters}
dataTreePath={`${currentJSCollection.name}.body`}
disabled={!isChangePermitted}
folding
height={"100%"}
hideEvaluatedValue
input={{
value: currentJSCollection.body,
onChange: handleEditorChange,
}}
isJSObject
jsObjectName={currentJSCollection.name}
mode={EditorModes.JAVASCRIPT}
placeholder="Let's write some code!"
showLightningMenu={false}
showLineNumbers
size={EditorSize.EXTENDED}
tabBehaviour={TabBehaviour.INDENT}
theme={theme}
/>
</div>
</TabPanel>
{showSettings && (
<TabPanel value={JSEditorTab.SETTINGS}>
<div className="js-editor-tab">
<JSFunctionSettingsView
actions={jsActions}
disabled={!isChangePermitted}
onUpdateSettings={onUpdateSettings}
/>
</div>
</TabPanel>
)}
</Tabs>
</TabbedViewContainer>
<EditorForm
actions={jsActions}
blockCompletions={blockCompletions}
changePermitted={isChangePermitted}
currentJSCollection={currentJSCollection}
customGutter={JSGutters}
executing={isExecutingCurrentJSAction}
onChange={handleEditorChange}
onUpdateSettings={onUpdateSettings}
onValueChange={(string) =>
setSelectedConfigTab(string as JSEditorTab)
}
Comment on lines +387 to +389
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Refactor onValueChange to improve clarity and type safety.

Avoid using string as a parameter name and unnecessary type assertions.

Consider updating the function as follows:

-onValueChange={(string) =>
-  setSelectedConfigTab(string as JSEditorTab)
-}
+onValueChange={(tab: JSEditorTab) =>
+  setSelectedConfigTab(tab)
+}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
onValueChange={(string) =>
setSelectedConfigTab(string as JSEditorTab)
}
onValueChange={(tab: JSEditorTab) =>
setSelectedConfigTab(tab)
}

showSettings={showSettings}
theme={theme}
value={selectedConfigTab}
/>
<JSResponseView
currentFunction={activeResponse}
disabled={disableRunFunctionality || !isExecutePermitted}
Expand Down
89 changes: 89 additions & 0 deletions app/client/src/pages/Editor/JSEditor/JSEditorForm/JSEditorForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import React from "react";
import { FEATURE_FLAG } from "ee/entities/FeatureFlag";
import type { JSEditorTab } from "reducers/uiReducers/jsPaneReducer";
import { useFeatureFlag } from "utils/hooks/useFeatureFlag";
import {
type BlockCompletion,
CodeEditorBorder,
EditorModes,
EditorSize,
type EditorTheme,
TabBehaviour,
} from "components/editorComponents/CodeEditor/EditorConfig";
import type { CodeEditorGutter } from "components/editorComponents/CodeEditor";
import type { JSAction, JSCollection } from "entities/JSCollection";
import { OldJSEditorForm } from "./old/JSEditorForm";
import type { OnUpdateSettingsProps } from "../JSFunctionSettings";
import LazyCodeEditor from "components/editorComponents/LazyCodeEditor";
import { Flex } from "@appsmith/ads";

interface Props {
executing: boolean;
onValueChange: (value: string) => void;
value: JSEditorTab;
showSettings: undefined | boolean;
blockCompletions: Array<BlockCompletion>;
customGutter: CodeEditorGutter;
currentJSCollection: JSCollection;
changePermitted: boolean;
onChange: (valueOrEvent: React.ChangeEvent | string) => void;
theme: EditorTheme.LIGHT;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Correct the 'theme' prop type in 'Props' interface

The theme property in the Props interface is assigned a value EditorTheme.LIGHT instead of specifying its type. It should be typed as EditorTheme.

Apply this diff to fix the issue:

-  theme: EditorTheme.LIGHT;
+  theme: EditorTheme;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
theme: EditorTheme.LIGHT;
theme: EditorTheme;

actions: JSAction[];
onUpdateSettings?: (props: OnUpdateSettingsProps) => void;
}

export const JSEditorForm = (props: Props) => {
const isActionRedesignEnabled = useFeatureFlag(
FEATURE_FLAG.release_actions_redesign_enabled,
);

if (!isActionRedesignEnabled) {
return (
<OldJSEditorForm
actions={props.actions}
blockCompletions={props.blockCompletions}
changePermitted={props.changePermitted}
currentJSCollection={props.currentJSCollection}
customGutter={props.customGutter}
executing={props.executing}
onChange={props.onChange}
onUpdateSettings={props.onUpdateSettings}
onValueChange={props.onValueChange}
showSettings={props.showSettings}
theme={props.theme}
value={props.value}
/>
);
}

return (
<Flex flex="1" overflow="scroll">
<LazyCodeEditor
AIAssisted
blockCompletions={props.blockCompletions}
border={CodeEditorBorder.NONE}
borderLess
className={"js-editor"}
customGutter={props.customGutter}
dataTreePath={`${props.currentJSCollection.name}.body`}
disabled={!props.changePermitted}
folding
height={"100%"}
hideEvaluatedValue
input={{
value: props.currentJSCollection.body,
onChange: props.onChange,
}}
isJSObject
jsObjectName={props.currentJSCollection.name}
mode={EditorModes.JAVASCRIPT}
placeholder="Let's write some code!"
showLightningMenu={false}
showLineNumbers
size={EditorSize.EXTENDED}
tabBehaviour={TabBehaviour.INDENT}
theme={props.theme}
/>
</Flex>
);
};
1 change: 1 addition & 0 deletions app/client/src/pages/Editor/JSEditor/JSEditorForm/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { JSEditorForm } from "./JSEditorForm";
105 changes: 105 additions & 0 deletions app/client/src/pages/Editor/JSEditor/JSEditorForm/old/JSEditorForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import { JSEditorTab } from "reducers/uiReducers/jsPaneReducer";
import React from "react";
import type {
BlockCompletion,
EditorTheme,
} from "components/editorComponents/CodeEditor/EditorConfig";
import {
CodeEditorBorder,
EditorModes,
EditorSize,
TabBehaviour,
} from "components/editorComponents/CodeEditor/EditorConfig";
import { TabbedViewContainer } from "../../styledComponents";
import { Tab, TabPanel, Tabs, TabsList } from "@appsmith/ads";
import LazyCodeEditor from "components/editorComponents/LazyCodeEditor";
import JSFunctionSettingsView, {
type OnUpdateSettingsProps,
} from "../../JSFunctionSettings";
import type { CodeEditorGutter } from "components/editorComponents/CodeEditor";
import type { JSAction, JSCollection } from "entities/JSCollection";

interface Props {
executing: boolean;
onValueChange: (value: string) => void;
value: JSEditorTab;
showSettings: undefined | boolean;
blockCompletions: Array<BlockCompletion>;
customGutter: CodeEditorGutter;
currentJSCollection: JSCollection;
changePermitted: boolean;
onChange: (valueOrEvent: React.ChangeEvent | string) => void;
theme: EditorTheme.LIGHT;
actions: JSAction[];
onUpdateSettings?: (props: OnUpdateSettingsProps) => void;
}

export function OldJSEditorForm(props: Props) {
return (
<TabbedViewContainer isExecuting={props.executing}>
<Tabs
defaultValue={JSEditorTab.CODE}
onValueChange={props.onValueChange}
value={props.value}
>
<TabsList>
<Tab
data-testid={`t--js-editor-` + JSEditorTab.CODE}
value={JSEditorTab.CODE}
>
Code
</Tab>
{props.showSettings && (
<Tab
data-testid={`t--js-editor-` + JSEditorTab.SETTINGS}
value={JSEditorTab.SETTINGS}
>
Settings
</Tab>
)}
</TabsList>
<TabPanel value={JSEditorTab.CODE}>
<div className="js-editor-tab">
<LazyCodeEditor
AIAssisted
blockCompletions={props.blockCompletions}
border={CodeEditorBorder.NONE}
borderLess
className={"js-editor"}
customGutter={props.customGutter}
dataTreePath={`${props.currentJSCollection.name}.body`}
disabled={!props.changePermitted}
folding
height={"100%"}
hideEvaluatedValue
input={{
value: props.currentJSCollection.body,
onChange: props.onChange,
}}
isJSObject
jsObjectName={props.currentJSCollection.name}
mode={EditorModes.JAVASCRIPT}
placeholder="Let's write some code!"
showLightningMenu={false}
showLineNumbers
size={EditorSize.EXTENDED}
tabBehaviour={TabBehaviour.INDENT}
theme={props.theme}
/>
</div>
</TabPanel>
{props.showSettings && (
<TabPanel value={JSEditorTab.SETTINGS}>
<div className="js-editor-tab">
<JSFunctionSettingsView
actions={props.actions}
disabled={!props.changePermitted}
onUpdateSettings={props.onUpdateSettings}
/>
</div>
</TabPanel>
)}
</Tabs>
</TabbedViewContainer>
);
}
Loading