From 38aafb5027115a018ca7a06632dd54dcf5d4256d Mon Sep 17 00:00:00 2001 From: Hetu Nandu Date: Wed, 1 Jul 2020 15:31:07 +0530 Subject: [PATCH] Fix embedded datasource path (#2) * Refactor CodeMirror component to be more configurable and testable (hints, markings) * Update the existing datasource path component * Better text highlighting for JSON fields * Case insensitive hinting in autocomplete --- app/client/jest.config.js | 4 + app/client/package.json | 4 +- app/client/src/api/DatasourcesApi.ts | 4 +- .../designSystems/appsmith/TabbedView.tsx | 6 +- .../editorComponents/ApiResponseView.tsx | 4 +- .../editorComponents/CodeEditor.tsx | 66 -- .../CodeEditor/EditorConfig.ts | 47 ++ .../{ => CodeEditor}/EvaluatedValuePopup.tsx | 8 +- .../CodeEditor/hintHelpers.test.ts | 87 ++ .../CodeEditor/hintHelpers.ts | 75 ++ .../editorComponents/CodeEditor/index.tsx | 371 +++++++++ .../CodeEditor/markHelpers.ts | 21 + .../editorComponents/CodeEditor/modes.ts | 51 ++ .../CodeEditor/styledComponents.ts | 256 ++++++ .../DynamicAutocompleteInput.tsx | 762 ------------------ .../editorComponents/ReadOnlyEditor.tsx | 37 + .../editorComponents/RequestView.tsx | 4 +- .../editorComponents/StoreAsDatasource.tsx | 85 ++ .../form/fields/DatasourcesField.tsx | 315 -------- .../form/fields/DynamicTextField.tsx | 27 +- .../fields/EmbeddedDatasourcePathField.tsx | 278 +++++++ .../form/fields/KeyValueFieldArray.tsx | 169 ++-- .../formControls/KeyValueArrayControl.tsx | 126 +-- .../propertyControls/ChartDataControl.tsx | 24 +- .../propertyControls/CodeEditorControl.tsx | 17 +- .../propertyControls/InputTextControl.tsx | 16 +- app/client/src/entities/Datasource/index.ts | 13 + .../src/pages/Editor/APIEditor/Form.tsx | 9 +- .../src/pages/Editor/APIEditor/Pagination.tsx | 2 - .../pages/Editor/APIEditor/PostBodyData.tsx | 20 +- .../Editor/APIEditor/RapidApiEditorForm.tsx | 3 +- .../src/pages/Editor/QueryEditor/Form.tsx | 27 +- app/client/src/sagas/DatasourcesSagas.ts | 2 +- .../src/utils/autocomplete/TernServer.ts | 2 + .../test/__mocks__/CodeMirrorEditorMock.ts | 11 + app/client/test/__mocks__/styleMock.js | 1 + app/client/test/__mocks__/svgMock.js | 9 + app/client/yarn.lock | 14 +- 38 files changed, 1624 insertions(+), 1353 deletions(-) delete mode 100644 app/client/src/components/editorComponents/CodeEditor.tsx create mode 100644 app/client/src/components/editorComponents/CodeEditor/EditorConfig.ts rename app/client/src/components/editorComponents/{ => CodeEditor}/EvaluatedValuePopup.tsx (96%) create mode 100644 app/client/src/components/editorComponents/CodeEditor/hintHelpers.test.ts create mode 100644 app/client/src/components/editorComponents/CodeEditor/hintHelpers.ts create mode 100644 app/client/src/components/editorComponents/CodeEditor/index.tsx create mode 100644 app/client/src/components/editorComponents/CodeEditor/markHelpers.ts create mode 100644 app/client/src/components/editorComponents/CodeEditor/modes.ts create mode 100644 app/client/src/components/editorComponents/CodeEditor/styledComponents.ts delete mode 100644 app/client/src/components/editorComponents/DynamicAutocompleteInput.tsx create mode 100644 app/client/src/components/editorComponents/ReadOnlyEditor.tsx create mode 100644 app/client/src/components/editorComponents/StoreAsDatasource.tsx delete mode 100644 app/client/src/components/editorComponents/form/fields/DatasourcesField.tsx create mode 100644 app/client/src/components/editorComponents/form/fields/EmbeddedDatasourcePathField.tsx create mode 100644 app/client/src/entities/Datasource/index.ts create mode 100644 app/client/test/__mocks__/CodeMirrorEditorMock.ts create mode 100644 app/client/test/__mocks__/styleMock.js create mode 100644 app/client/test/__mocks__/svgMock.js diff --git a/app/client/jest.config.js b/app/client/jest.config.js index 0de7abd9d0..fee6632cf0 100644 --- a/app/client/jest.config.js +++ b/app/client/jest.config.js @@ -7,4 +7,8 @@ module.exports = { moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json", "node", "css"], moduleDirectories: ["node_modules", "src"], transformIgnorePatterns: ["/node_modules/(?!codemirror)"], + moduleNameMapper: { + "\\.(css|less)$": "/test/__mocks__/styleMock.js", + "\\.svg$": "/test/__mocks__/svgMock.js", + }, }; diff --git a/app/client/package.json b/app/client/package.json index 8cbebaff0a..60fe291661 100644 --- a/app/client/package.json +++ b/app/client/package.json @@ -46,7 +46,7 @@ "algoliasearch": "^4.2.0", "axios": "^0.18.0", "chance": "^1.1.3", - "codemirror": "^5.50.0", + "codemirror": "^5.55.0", "eslint": "^6.4.0", "fast-deep-equal": "^3.1.1", "flow-bin": "^0.91.0", @@ -149,7 +149,7 @@ "@storybook/addons": "^5.2.6", "@storybook/preset-create-react-app": "^1.3.1", "@storybook/react": "^5.2.6", - "@types/codemirror": "^0.0.82", + "@types/codemirror": "^0.0.96", "@types/jest": "^24.0.22", "@types/react-beautiful-dnd": "^11.0.4", "@types/react-select": "^3.0.5", diff --git a/app/client/src/api/DatasourcesApi.ts b/app/client/src/api/DatasourcesApi.ts index e06a9bf2af..86e5054fd2 100644 --- a/app/client/src/api/DatasourcesApi.ts +++ b/app/client/src/api/DatasourcesApi.ts @@ -21,8 +21,8 @@ export interface Datasource { headers?: Record; databaseName?: string; }; - invalids: string[]; - isValid: boolean; + invalids?: string[]; + isValid?: boolean; } export interface CreateDatasourceConfig { diff --git a/app/client/src/components/designSystems/appsmith/TabbedView.tsx b/app/client/src/components/designSystems/appsmith/TabbedView.tsx index 8eaae536d0..78bdc800b0 100644 --- a/app/client/src/components/designSystems/appsmith/TabbedView.tsx +++ b/app/client/src/components/designSystems/appsmith/TabbedView.tsx @@ -3,7 +3,7 @@ import { Tab, Tabs, TabList, TabPanel } from "react-tabs"; import "react-tabs/style/react-tabs.css"; import styled from "styled-components"; -const TabsWrapper = styled.div<{ overflow?: boolean }>` +const TabsWrapper = styled.div<{ shouldOverflow?: boolean }>` height: 100%; .react-tabs { height: 100%; @@ -16,7 +16,7 @@ const TabsWrapper = styled.div<{ overflow?: boolean }>` border-bottom-color: #d0d7dd; color: #a3b3bf; ${props => - props.overflow && + props.shouldOverflow && ` overflow-y: hidden; overflow-x: auto; @@ -51,7 +51,7 @@ type TabbedViewComponentType = { export const BaseTabbedView = (props: TabbedViewComponentType) => { return ( - + { diff --git a/app/client/src/components/editorComponents/ApiResponseView.tsx b/app/client/src/components/editorComponents/ApiResponseView.tsx index bd6f2b569d..17c957e65f 100644 --- a/app/client/src/components/editorComponents/ApiResponseView.tsx +++ b/app/client/src/components/editorComponents/ApiResponseView.tsx @@ -10,7 +10,7 @@ import { ActionResponse } from "api/ActionAPI"; import { formatBytes } from "utils/helpers"; import { APIEditorRouteParams } from "constants/routes"; import LoadingOverlayScreen from "components/editorComponents/LoadingOverlayScreen"; -import CodeEditor from "components/editorComponents/CodeEditor"; +import ReadOnlyEditor from "components/editorComponents/ReadOnlyEditor"; import { getActionResponses } from "selectors/entitiesSelector"; import { Colors } from "constants/Colors"; import _ from "lodash"; @@ -201,7 +201,7 @@ const ApiResponseView = (props: Props) => { )} - ` - height: ${props => - typeof props.height === "number" ? props.height + "px" : props.height}; - color: white; - .CodeMirror { - height: 100%; - } -`; - -interface Props { - input: { - value: string; - onChange?: (event: ChangeEvent) => void; - }; - height: number | string; -} - -class CodeEditor extends React.Component { - textArea = React.createRef(); - editor: any; - componentDidMount(): void { - if (this.textArea.current) { - const readOnly = !this.props.input.onChange; - - this.editor = cm.fromTextArea(this.textArea.current, { - mode: { name: "javascript", json: true }, - value: this.props.input.value, - readOnly, - tabSize: 2, - indentWithTabs: true, - lineNumbers: true, - lineWrapping: true, - }); - } - } - - componentDidUpdate( - prevProps: Readonly, - prevState: Readonly<{}>, - snapshot?: any, - ): void { - this.editor.setValue(this.props.input.value); - } - - render(): React.ReactNode { - return ( - -