From 9afcf871565fc514f071efd1dd1e701a59523c9e Mon Sep 17 00:00:00 2001 From: akash-codemonk <67054171+akash-codemonk@users.noreply.github.com> Date: Tue, 3 Nov 2020 09:40:07 +0530 Subject: [PATCH 1/5] Show binding prompt when there is no binding in the editor (#1478) --- .../Binding/No_Binding_Prompt_spec.js | 18 +++++++ .../DisplayWidgets/video_spec.js | 3 ++ app/client/cypress/locators/DynamicInput.json | 3 +- .../CodeEditor/BindingPrompt.tsx | 48 +++++++++++++++++++ .../editorComponents/CodeEditor/index.tsx | 10 ++-- .../CodeEditor/styledComponents.ts | 2 +- 6 files changed, 79 insertions(+), 5 deletions(-) create mode 100644 app/client/cypress/integration/Smoke_TestSuite/Binding/No_Binding_Prompt_spec.js create mode 100644 app/client/src/components/editorComponents/CodeEditor/BindingPrompt.tsx diff --git a/app/client/cypress/integration/Smoke_TestSuite/Binding/No_Binding_Prompt_spec.js b/app/client/cypress/integration/Smoke_TestSuite/Binding/No_Binding_Prompt_spec.js new file mode 100644 index 0000000000..b8317bb468 --- /dev/null +++ b/app/client/cypress/integration/Smoke_TestSuite/Binding/No_Binding_Prompt_spec.js @@ -0,0 +1,18 @@ +const dsl = require("../../../fixtures/inputdsl.json"); +const widgetsPage = require("../../../locators/Widgets.json"); +const dynamicInput = require("../../../locators/DynamicInput.json"); + +describe("Binding prompt", function() { + before(() => { + cy.addDsl(dsl); + }); + + it("Show binding prompt when there are no bindings in the editor", () => { + cy.openPropertyPane("inputwidget"); + cy.get(widgetsPage.defaultInput).type(" "); + cy.get(dynamicInput.bindingPrompt).should("be.visible"); + + cy.get(widgetsPage.defaultInput).type("{{"); + cy.get(dynamicInput.bindingPrompt).should("not.be.visible"); + }); +}); diff --git a/app/client/cypress/integration/Smoke_TestSuite/DisplayWidgets/video_spec.js b/app/client/cypress/integration/Smoke_TestSuite/DisplayWidgets/video_spec.js index d447fcb5f6..243a441c3b 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/DisplayWidgets/video_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/DisplayWidgets/video_spec.js @@ -48,6 +48,9 @@ describe("Video Widget Functionality", function() { it("Update video url and check play and pause functionality validation", function() { cy.testCodeMirror(testdata.videoUrl); + cy.get(".CodeMirror textarea") + .first() + .blur(); cy.get(widgetsPage.autoPlay).click(); cy.wait("@updateLayout").should( "have.nested.property", diff --git a/app/client/cypress/locators/DynamicInput.json b/app/client/cypress/locators/DynamicInput.json index 5c3eb61356..8f34ce8219 100644 --- a/app/client/cypress/locators/DynamicInput.json +++ b/app/client/cypress/locators/DynamicInput.json @@ -1,5 +1,6 @@ { "input": ".CodeMirror textarea", "hints": "ul.CodeMirror-hints", - "evaluatedValue": ".t--CodeEditor-evaluatedValue" + "evaluatedValue": ".t--CodeEditor-evaluatedValue", + "bindingPrompt": ".t--no-binding-prompt" } diff --git a/app/client/src/components/editorComponents/CodeEditor/BindingPrompt.tsx b/app/client/src/components/editorComponents/CodeEditor/BindingPrompt.tsx new file mode 100644 index 0000000000..4efb6526f9 --- /dev/null +++ b/app/client/src/components/editorComponents/CodeEditor/BindingPrompt.tsx @@ -0,0 +1,48 @@ +import React, { useRef } from "react"; +import styled from "styled-components"; +import { Colors } from "constants/Colors"; + +const Wrapper = styled.span<{ visible: boolean; bottomOffset: number }>` + padding: 8px; + font-size: 12px; + color: ${Colors.GRAY_CHATEAU}; + border-radius: 2px; + background-color: ${Colors.BLUE_CHARCOAL}; + position: absolute; + bottom: ${props => -props.bottomOffset}px; + width: 100%; + line-height: 13px; + visibility: ${props => (props.visible ? "visible" : "hidden")}; + z-index: 1; +`; + +const CurlyBraces = styled.span` + color: white; + background-color: #f3672a; + border-radius: 2px; + padding: 2px; + margin: 0px 2px; +`; + +const BindingPrompt = (props: { isOpen: boolean }): JSX.Element => { + const promptRef = useRef(null); + let bottomOffset = 30; + + if (promptRef.current) { + const boundingRect = promptRef.current.getBoundingClientRect(); + bottomOffset = boundingRect.height; + } + + return ( + + Type {"{{"} to see a list of variables + + ); +}; + +export default BindingPrompt; diff --git a/app/client/src/components/editorComponents/CodeEditor/index.tsx b/app/client/src/components/editorComponents/CodeEditor/index.tsx index 7c64d1dfe4..8cdbbc56dc 100644 --- a/app/client/src/components/editorComponents/CodeEditor/index.tsx +++ b/app/client/src/components/editorComponents/CodeEditor/index.tsx @@ -36,6 +36,7 @@ import { import { bindingMarker } from "components/editorComponents/CodeEditor/markHelpers"; import { bindingHint } from "components/editorComponents/CodeEditor/hintHelpers"; import { retryPromise } from "utils/AppsmithUtils"; +import BindingPrompt from "./BindingPrompt"; const LightningMenu = lazy(() => retryPromise(() => import("components/editorComponents/LightningMenu")), @@ -91,9 +92,7 @@ class CodeEditor extends Component { }; textArea = React.createRef(); - // eslint-disable-next-line @typescript-eslint/ban-ts-ignore - // @ts-ignore - editor: CodeMirror.Editor; + editor!: CodeMirror.Editor; hinters: Hinter[] = []; constructor(props: Props) { @@ -291,6 +290,10 @@ class CodeEditor extends Component { ("evaluatedValue" in this.props || ("dataTreePath" in this.props && !!this.props.dataTreePath)); + const showBindingPrompt = + (!this.props.input.value?.includes("{{") || !this.props.input.value) && + showEvaluatedValue; + return ( { {this.props.rightIcon && ( {this.props.rightIcon} )} + diff --git a/app/client/src/components/editorComponents/CodeEditor/styledComponents.ts b/app/client/src/components/editorComponents/CodeEditor/styledComponents.ts index 0b121afb60..5b8d195fca 100644 --- a/app/client/src/components/editorComponents/CodeEditor/styledComponents.ts +++ b/app/client/src/components/editorComponents/CodeEditor/styledComponents.ts @@ -124,7 +124,7 @@ export const EditorWrapper = styled.div<{ left: 0; top: 0; ` - : `z-index: 0; position: relative;`} + : `position: relative;`} min-height: 32px; height: ${props => props.height || "auto"}; background-color: ${props => From 1c4adf84a1f0d12ac04d0cf8707b76df10d81b8a Mon Sep 17 00:00:00 2001 From: vicky-primathon <67091118+vicky-primathon@users.noreply.github.com> Date: Tue, 3 Nov 2020 10:49:27 +0530 Subject: [PATCH 2/5] Fix/multi select dropdown (#1295) * Cypress test locator fix * Multi select dropdown values initialization fixed * Reverted test case selector change * Using lodash isEqual since values can be object --- app/client/src/widgets/DropdownWidget.tsx | 1 - app/client/src/widgets/MetaHOC.tsx | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/app/client/src/widgets/DropdownWidget.tsx b/app/client/src/widgets/DropdownWidget.tsx index c50828fd67..2bd9966ee3 100644 --- a/app/client/src/widgets/DropdownWidget.tsx +++ b/app/client/src/widgets/DropdownWidget.tsx @@ -24,7 +24,6 @@ class DropdownWidget extends BaseWidget { selectionType: VALIDATION_TYPES.TEXT, isRequired: VALIDATION_TYPES.BOOLEAN, // onOptionChange: VALIDATION_TYPES.ACTION_SELECTOR, - selectedOptionValueArr: VALIDATION_TYPES.ARRAY, selectedOptionValues: VALIDATION_TYPES.ARRAY, defaultOptionValue: VALIDATION_TYPES.DEFAULT_OPTION_VALUE, }; diff --git a/app/client/src/widgets/MetaHOC.tsx b/app/client/src/widgets/MetaHOC.tsx index d370cefa79..29ae322107 100644 --- a/app/client/src/widgets/MetaHOC.tsx +++ b/app/client/src/widgets/MetaHOC.tsx @@ -51,8 +51,8 @@ const withMeta = (WrappedWidget: typeof BaseWidget) => { Object.keys(metaProperties).forEach(metaProperty => { const defaultProperty = defaultProperties[metaProperty]; if ( - prevProps[metaProperty] !== this.props[metaProperty] && - this.props[defaultProperty] === this.props[metaProperty] + !_.isEqual(prevProps[metaProperty], this.props[metaProperty]) && + _.isEqual(this.props[defaultProperty], this.props[metaProperty]) ) { this.setState({ [metaProperty]: this.props[metaProperty] }); } From 87a2effbc5cc228ebebb0d09f58181f8e35acfdc Mon Sep 17 00:00:00 2001 From: Sumanth Yedoti <30371888+sumanthyedoti@users.noreply.github.com> Date: Tue, 3 Nov 2020 12:21:02 +0530 Subject: [PATCH 3/5] Fix/api URL field twitch (#1495) Fixes: #1248 Co-authored-by: Yedoti Sumanth --- .../src/components/editorComponents/CodeEditor/index.tsx | 4 ++-- app/client/src/components/editorComponents/FormRow.tsx | 1 + .../form/fields/EmbeddedDatasourcePathField.tsx | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/app/client/src/components/editorComponents/CodeEditor/index.tsx b/app/client/src/components/editorComponents/CodeEditor/index.tsx index 8cdbbc56dc..c3fb0a30f2 100644 --- a/app/client/src/components/editorComponents/CodeEditor/index.tsx +++ b/app/client/src/components/editorComponents/CodeEditor/index.tsx @@ -271,6 +271,7 @@ class CodeEditor extends Component { theme, disabled, className, + placeholder, showLightningMenu, dataTreePath, dynamicData, @@ -349,12 +350,11 @@ class CodeEditor extends Component { className="leftImageStyles" /> )} -