fix: Edit icon in API editor and toggle transition issue (#9013)

This commit is contained in:
albinAppsmith 2021-11-17 12:06:18 +05:30 committed by GitHub
parent d3a491f0b3
commit 06ca32cd96
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 56 additions and 49 deletions

View File

@ -4,6 +4,7 @@ const widgetsPage = require("../../../../locators/Widgets.json");
const publish = require("../../../../locators/publishWidgetspage.json"); const publish = require("../../../../locators/publishWidgetspage.json");
const dsl = require("../../../../fixtures/basicTabledsl.json"); const dsl = require("../../../../fixtures/basicTabledsl.json");
const pages = require("../../../../locators/Pages.json"); const pages = require("../../../../locators/Pages.json");
const apiwidget = require("../../../../locators/apiWidgetslocator.json");
const tabname = "UpdatedTab"; const tabname = "UpdatedTab";
describe("Tab widget test", function() { describe("Tab widget test", function() {
@ -18,6 +19,10 @@ describe("Tab widget test", function() {
cy.NavigateToAPI_Panel(); cy.NavigateToAPI_Panel();
cy.log("Navigation to API Panel screen successful"); cy.log("Navigation to API Panel screen successful");
cy.CreateApiAndValidateUniqueEntityName(apiName); cy.CreateApiAndValidateUniqueEntityName(apiName);
cy.get(apiwidget.apiTxt)
.clear()
.type(tableName, { force: true })
.should("have.value", tableName);
}); });
it("Rename Table widget with api name validation test", function() { it("Rename Table widget with api name validation test", function() {

View File

@ -995,7 +995,7 @@ Cypress.Commands.add("CreationOfUniqueAPIcheck", (apiname) => {
.focus() .focus()
.type(apiname, { force: true, delay: 500 }) .type(apiname, { force: true, delay: 500 })
.should("have.value", apiname); .should("have.value", apiname);
cy.get(".error-message").should(($x) => { cy.get(".t--action-name-edit-error").should(($x) => {
expect($x).contain( expect($x).contain(
apiname.concat(" is already being used or is a restricted keyword."), apiname.concat(" is already being used or is a restricted keyword."),
); );
@ -1082,7 +1082,7 @@ Cypress.Commands.add("CreateApiAndValidateUniqueEntityName", (apiname) => {
.clear() .clear()
.type(apiname, { force: true }) .type(apiname, { force: true })
.should("have.value", apiname); .should("have.value", apiname);
cy.get(".t--nameOfApi .error-message").should(($x) => { cy.get(".t--action-name-edit-error").should(($x) => {
expect($x).contain( expect($x).contain(
apiname.concat(" is already being used or is a restricted keyword."), apiname.concat(" is already being used or is a restricted keyword."),
); );

View File

@ -145,8 +145,8 @@ const TextContainer = styled.div<{
height: ${(props) => props.theme.spaces[14] + 1}px; height: ${(props) => props.theme.spaces[14] + 1}px;
padding: ${(props) => props.theme.spaces[4]}px padding: ${(props) => props.theme.spaces[4]}px
${(props) => props.theme.spaces[5]}px; ${(props) => props.theme.spaces[5]}px;
width: calc(100% - 40px);
background-color: ${(props) => props.bgColor}; background-color: ${(props) => props.bgColor};
width: calc(100% - 40px);
} }
.icon-wrapper { .icon-wrapper {

View File

@ -28,13 +28,30 @@ export type TextInputProps = CommonComponentProps & {
const SearchInputWrapper = styled.div` const SearchInputWrapper = styled.div`
& > div { & > div {
border: none; border: none;
& > .left-icon {
margin-left: 8px;
& span {
margin-right: 0;
}
}
& > .right-icon {
position: relative;
right: 0;
}
& input {
padding: 0 8px;
}
} }
`; `;
const CloseIcon = styled.div` const CloseIcon = styled.div`
.${Classes.ICON} { .${Classes.ICON} {
margin-right: ${(props) => props.theme.spaces[4]}px; margin-right: ${(props) => props.theme.spaces[4]}px;
margin-left: ${(props) => props.theme.spaces[4]}px; margin-left: 0;
} }
`; `;

View File

@ -419,7 +419,7 @@ const TextInput = forwardRef(
props.helperText.length > 0 && props.helperText.length > 0 &&
HelperMessage} HelperMessage}
{ErrorMessage} {ErrorMessage}
<RightSideContainer ref={setRightSideRef}> <RightSideContainer className="right-icon" ref={setRightSideRef}>
{props.rightSideComponent} {props.rightSideComponent}
</RightSideContainer> </RightSideContainer>
</InputWrapper> </InputWrapper>

View File

@ -116,7 +116,7 @@ const StyledToggle = styled.label<{
`; `;
export default function Toggle(props: ToggleProps) { export default function Toggle(props: ToggleProps) {
const [value, setValue] = useState(false); const [value, setValue] = useState(props.value);
useEffect(() => { useEffect(() => {
setValue(props.value); setValue(props.value);

View File

@ -16,11 +16,6 @@ import { getExistingPageNames } from "sagas/selectors";
import { saveActionName } from "actions/pluginActionActions"; import { saveActionName } from "actions/pluginActionActions";
import { Spinner } from "@blueprintjs/core"; import { Spinner } from "@blueprintjs/core";
import { checkCurrentStep } from "sagas/OnboardingSagas"; import { checkCurrentStep } from "sagas/OnboardingSagas";
import {
EditableText as NewEditableText,
EditInteractionKind as NewEditInteractionKind,
SavingState,
} from "components/ads/EditableText";
import { Classes } from "@blueprintjs/core"; import { Classes } from "@blueprintjs/core";
import { OnboardingStep } from "constants/OnboardingConstants"; import { OnboardingStep } from "constants/OnboardingConstants";
import log from "loglevel"; import log from "loglevel";
@ -163,45 +158,29 @@ export function ActionNameEditor(props: ActionNameEditorProps) {
return ( return (
<ApiNameWrapper page={props.page}> <ApiNameWrapper page={props.page}>
{props.page === "API_PANE" ? ( <div
<NewEditableText style={{
display: "flex",
}}
>
<EditableText
className="t--action-name-edit-field" className="t--action-name-edit-field"
defaultValue={currentActionConfig ? currentActionConfig.name : ""} defaultValue={currentActionConfig ? currentActionConfig.name : ""}
editInteractionKind={NewEditInteractionKind.SINGLE} editInteractionKind={EditInteractionKind.SINGLE}
fill errorTooltipClass="t--action-name-edit-error"
forceDefault={forceUpdate} forceDefault={forceUpdate}
isEditingDefault={isNew && !hideEditIcon} isEditingDefault={
isInvalid={isInvalidActionName} props.page === "API_PANE" ? isNew && !hideEditIcon : isNew
onBlur={handleAPINameChange}
placeholder="Name of the API in camelCase"
savingState={
saveStatus.isSaving ? SavingState.STARTED : SavingState.NOT_STARTED
} }
underline isInvalid={isInvalidActionName}
onTextChanged={handleAPINameChange}
placeholder="Name of the API in camelCase"
type="text"
updating={saveStatus.isSaving}
valueTransform={removeSpecialChars} valueTransform={removeSpecialChars}
/> />
) : ( {saveStatus.isSaving && <Spinner size={16} />}
<div </div>
style={{
display: "flex",
}}
>
<EditableText
className="t--action-name-edit-field"
defaultValue={currentActionConfig ? currentActionConfig.name : ""}
editInteractionKind={EditInteractionKind.SINGLE}
forceDefault={forceUpdate}
isEditingDefault={isNew}
isInvalid={isInvalidActionName}
onTextChanged={handleAPINameChange}
placeholder="Name of the API in camelCase"
type="text"
updating={saveStatus.isSaving}
valueTransform={removeSpecialChars}
/>
{saveStatus.isSaving && <Spinner size={16} />}
</div>
)}
</ApiNameWrapper> </ApiNameWrapper>
); );
} }

View File

@ -31,6 +31,7 @@ type EditableTextProps = {
minimal?: boolean; minimal?: boolean;
onBlur?: (value?: string) => void; onBlur?: (value?: string) => void;
beforeUnmount?: (value?: string) => void; beforeUnmount?: (value?: string) => void;
errorTooltipClass?: string;
}; };
const EditableTextWrapper = styled.div<{ const EditableTextWrapper = styled.div<{
@ -84,6 +85,7 @@ export function EditableText(props: EditableTextProps) {
className, className,
defaultValue, defaultValue,
editInteractionKind, editInteractionKind,
errorTooltipClass,
forceDefault, forceDefault,
hideEditIcon, hideEditIcon,
isEditingDefault, isEditingDefault,
@ -171,7 +173,11 @@ export function EditableText(props: EditableTextProps) {
editInteractionKind === EditInteractionKind.DOUBLE ? edit : _.noop editInteractionKind === EditInteractionKind.DOUBLE ? edit : _.noop
} }
> >
<ErrorTooltip isOpen={!!error} message={errorMessage as string}> <ErrorTooltip
customClass={errorTooltipClass}
isOpen={!!error}
message={errorMessage as string}
>
<TextContainer isValid={!error} minimal={!!minimal}> <TextContainer isValid={!error} minimal={!!minimal}>
<BlueprintEditableText <BlueprintEditableText
className={className} className={className}

View File

@ -11,9 +11,9 @@ const TooltipStyles = createGlobalStyle`
} }
.bp3-popover-content { .bp3-popover-content {
padding: 8px; padding: 8px;
color: ${Colors.RED}; color: ${Colors.ERROR_RED};
text-align: center; text-align: center;
border-radius: 4px; border-radius: 0;
text-transform: initial; text-transform: initial;
font-weight: 500; font-weight: 500;
font-size: 12px; font-size: 12px;
@ -37,6 +37,7 @@ interface Props {
isOpen: boolean; isOpen: boolean;
message: string; message: string;
children: JSX.Element; children: JSX.Element;
customClass?: string;
} }
function ErrorTooltip(props: Props) { function ErrorTooltip(props: Props) {
@ -48,7 +49,7 @@ function ErrorTooltip(props: Props) {
canEscapeKeyClose canEscapeKeyClose
content={props.message} content={props.message}
isOpen={props.isOpen && !!props.message} isOpen={props.isOpen && !!props.message}
portalClassName="error-tooltip" portalClassName={`error-tooltip ${props.customClass || ""}`}
position="bottom" position="bottom"
usePortal usePortal
> >

View File

@ -255,7 +255,6 @@ interface APIFormProps {
type Props = APIFormProps & InjectedFormProps<Action, APIFormProps>; type Props = APIFormProps & InjectedFormProps<Action, APIFormProps>;
export const NameWrapper = styled.div` export const NameWrapper = styled.div`
width: 49%;
display: flex; display: flex;
align-items: center; align-items: center;
input { input {