diff --git a/app/client/package.json b/app/client/package.json
index 2db914ece2..581f4e07b2 100644
--- a/app/client/package.json
+++ b/app/client/package.json
@@ -47,7 +47,7 @@
"algoliasearch": "^4.2.0",
"axios": "^0.21.1",
"chance": "^1.1.3",
- "codemirror": "^5.55.0",
+ "codemirror": "^5.59.2",
"copy-to-clipboard": "^3.3.1",
"craco-alias": "^2.1.1",
"cypress-log-to-output": "^1.1.2",
diff --git a/app/client/src/components/ads/Dropdown.tsx b/app/client/src/components/ads/Dropdown.tsx
index e42bcb2c36..8adb2a0bed 100644
--- a/app/client/src/components/ads/Dropdown.tsx
+++ b/app/client/src/components/ads/Dropdown.tsx
@@ -95,6 +95,8 @@ const OptionWrapper = styled.div<{ selected: boolean }>`
}
&:hover {
+ background: ${(props) => props.theme.colors.dropdown.hovered.bg};
+ color: ${(props) => props.theme.colors.dropdown.hovered.text};
.${Classes.TEXT} {
color: ${(props) => props.theme.colors.dropdown.selected.text};
}
diff --git a/app/client/src/components/ads/EditableText.tsx b/app/client/src/components/ads/EditableText.tsx
index eadbefd189..1fa96ee130 100644
--- a/app/client/src/components/ads/EditableText.tsx
+++ b/app/client/src/components/ads/EditableText.tsx
@@ -118,7 +118,6 @@ const TextContainer = styled.div<{
border-bottom-style: solid;
border-bottom-width: 1px;
width: fit-content;
- max-width: 194px;
`
: null}
}
diff --git a/app/client/src/components/ads/Tabs.tsx b/app/client/src/components/ads/Tabs.tsx
index e6bcc590d6..b5b9b40e80 100644
--- a/app/client/src/components/ads/Tabs.tsx
+++ b/app/client/src/components/ads/Tabs.tsx
@@ -8,6 +8,7 @@ import { Classes, CommonComponentProps } from "./common";
export type TabProp = {
key: string;
title: string;
+ count?: number;
panelComponent: JSX.Element;
icon?: IconName;
};
@@ -100,11 +101,26 @@ const TabsWrapper = styled.div<{ shouldOverflow?: boolean }>`
}
`;
+const TabTitleWrapper = styled.div`
+ display: flex;
+ align-items: center;
+`;
+
const TabTitle = styled.span`
font-size: ${(props) => props.theme.typography.h5.fontSize}px;
font-weight: ${(props) => props.theme.typography.h5.fontWeight};
line-height: ${(props) => props.theme.typography.h5.lineHeight - 3}px;
letter-spacing: ${(props) => props.theme.typography.h5.letterSpacing}px;
+ margin: 0 5px;
+`;
+
+const TabCount = styled.div`
+ background-color: ${(props) => props.theme.colors.tabs.countBg};
+ border-radius: 8px;
+ width: 17px;
+ height: 14px;
+ font-size: 9px;
+ line-height: 14px;
`;
type TabbedViewComponentType = CommonComponentProps & {
@@ -129,8 +145,15 @@ export const TabComponent = (props: TabbedViewComponentType) => {
{props.tabs.map((tab) => (
- {tab.icon ? : null}
- {tab.title}
+
+ {tab.icon ? (
+
+ ) : null}
+ {tab.title}
+ {tab.count && tab.count > 0 ? (
+ {tab.count}
+ ) : null}
+
))}
diff --git a/app/client/src/components/ads/TreeDropdown.tsx b/app/client/src/components/ads/TreeDropdown.tsx
index f930014425..6b50d018a0 100644
--- a/app/client/src/components/ads/TreeDropdown.tsx
+++ b/app/client/src/components/ads/TreeDropdown.tsx
@@ -191,7 +191,7 @@ export default function TreeDropdown(props: TreeDropdownProps) {
className={option.className || "single-select"}
active={isSelected}
key={option.value}
- icon={option.id === "create" ? "plus" : undefined}
+ icon={option.icon}
onClick={
option.children
? noop
diff --git a/app/client/src/components/editorComponents/ActionNameEditor.tsx b/app/client/src/components/editorComponents/ActionNameEditor.tsx
index 840e036bed..fb59e37002 100644
--- a/app/client/src/components/editorComponents/ActionNameEditor.tsx
+++ b/app/client/src/components/editorComponents/ActionNameEditor.tsx
@@ -159,6 +159,7 @@ export const ActionNameEditor = (props: ActionNameEditorProps) => {
editInteractionKind={NewEditInteractionKind.SINGLE}
hideEditIcon
underline
+ fill
/>
) : (
props.theme.spaces[4]}px;
`;
-const StatusCodeText = styled(BaseText)<{ code: string }>`
- color: ${(props) =>
- props.code.match(/2\d\d/) ? props.theme.colors.primaryOld : Colors.RED};
+const ResponseTabWrapper = styled.div`
+ display: flex;
+ flex-direction: column;
+ height: 100%;
+ width: 100%;
`;
-// const TableWrapper = styled.div`
-// &&& {
-// table {
-// table-layout: fixed;
-// width: 100%;
-// td {
-// font-size: 12px;
-// width: 50%;
-// white-space: nowrap;
-// overflow: hidden;
-// text-overflow: ellipsis;
-// }
-// }
-// }
-// `;
-
-interface ReduxStateProps {
- responses: Record
;
- isRunning: Record;
-}
-
-// const ResponseHeadersView = (props: { data: Record }) => {
-// if (!props.data) return ;
-// return (
-//
-//
-//
-//
-// | Key |
-// Value |
-//
-//
-//
-// {Object.keys(props.data).map(k => (
-//
-// | {k} |
-// {props.data[k].join(", ")} |
-//
-// ))}
-//
-//
-//
-// );
-// };
-
-type Props = ReduxStateProps &
- RouteComponentProps & { theme?: EditorTheme };
-
-export const EMPTY_RESPONSE: ActionResponse = {
- statusCode: "",
- duration: "",
- body: {},
- headers: {},
- request: {
- headers: {},
- body: {},
- httpMethod: "",
- url: "",
- },
- size: "",
-};
-
const TabbedViewWrapper = styled.div<{ isCentered: boolean }>`
height: calc(100% - 30px);
@@ -160,6 +95,12 @@ const Flex = styled.div`
`;
const NoResponseContainer = styled.div`
+ height: 100%;
+ width: 100%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ flex-direction: column;
.${Classes.ICON} {
margin-right: 0px;
svg {
@@ -176,22 +117,43 @@ const NoResponseContainer = styled.div`
const FailedMessage = styled.div`
display: flex;
align-items: center;
- justify-content: space-between;
- width: 100%;
`;
-const ButtonContainer = styled.div`
+const ShowRequestText = styled.a`
display: flex;
- align-items: center;
- span {
- color: ${Colors.Galliano};
- cursor: pointer;
- }
- button {
- margin-left: ${(props) => props.theme.spaces[9]}px;
+ margin-left: ${(props) => props.theme.spaces[1] + 1}px;
+ .${Classes.ICON} {
+ margin-left: ${(props) => props.theme.spaces[1] + 1}px;
}
`;
+interface ReduxStateProps {
+ responses: Record;
+ isRunning: Record;
+}
+
+type Props = ReduxStateProps &
+ RouteComponentProps & { theme?: EditorTheme };
+
+export const EMPTY_RESPONSE: ActionResponse = {
+ statusCode: "",
+ duration: "",
+ body: {},
+ headers: {},
+ request: {
+ headers: {},
+ body: {},
+ httpMethod: "",
+ url: "",
+ },
+ size: "",
+};
+
+const StatusCodeText = styled(BaseText)<{ code: string }>`
+ color: ${(props) =>
+ props.code.startsWith("2") ? props.theme.colors.primaryOld : Colors.RED};
+`;
+
const ApiResponseView = (props: Props) => {
const {
match: {
@@ -219,38 +181,32 @@ const ApiResponseView = (props: Props) => {
key: "body",
title: "Response Body",
panelComponent: (
- <>
+
{hasFailed && !isRunning && requestDebugVisible && (
- {CHECK_REQUEST_BODY}
-
- {
- setRequestDebugVisible(false);
- }}
- >
- {DONT_SHOW_THIS_AGAIN}
+ {
+ setSelectedIndex(1);
+ }}
+ >
+
+ {SHOW_REQUEST}
-
+
+
}
+ variant={Variant.warning}
+ fill
+ closeButton
+ onClose={() => setRequestDebugVisible(false)}
/>
)}
- {_.isEmpty(response.body) ? (
+ {_.isEmpty(response.statusCode) ? (
Hit Run to get a Response
@@ -265,7 +221,7 @@ const ApiResponseView = (props: Props) => {
height={"100%"}
/>
)}
- >
+
),
},
{
@@ -287,7 +243,7 @@ const ApiResponseView = (props: Props) => {
];
return (
-
+
{isRunning && (
@@ -334,7 +290,7 @@ const ApiResponseView = (props: Props) => {
onSelect={setSelectedIndex}
/>
-
+
);
};
diff --git a/app/client/src/components/editorComponents/CodeEditor/BindingPrompt.tsx b/app/client/src/components/editorComponents/CodeEditor/BindingPrompt.tsx
index 5bcd3f3737..371b984b6f 100644
--- a/app/client/src/components/editorComponents/CodeEditor/BindingPrompt.tsx
+++ b/app/client/src/components/editorComponents/CodeEditor/BindingPrompt.tsx
@@ -1,6 +1,5 @@
import React, { useRef } from "react";
import styled from "styled-components";
-import { Colors } from "constants/Colors";
import { EditorTheme } from "./EditorConfig";
const Wrapper = styled.span<{
@@ -11,15 +10,11 @@ const Wrapper = styled.span<{
}>`
padding: ${(props) => (props.customMessage ? 6 : 8)}px;
font-size: 12px;
- color: #858282;
+ color: #ffffff;
box-shadow: 0px 12px 34px -6px rgba(0, 0, 0, 0.75);
border-radius: 0px;
background-color: ${(props) =>
- props.editorTheme === EditorTheme.DARK
- ? Colors.MINE_SHAFT
- : props.editorTheme === EditorTheme.LIGHT
- ? Colors.MERCURY
- : Colors.BLUE_CHARCOAL};
+ props.theme.colors.codeMirror.background.hoverState};
position: absolute;
bottom: ${(props) => -props.bottomOffset}px;
width: 100%;
@@ -29,8 +24,8 @@ const Wrapper = styled.span<{
`;
const CurlyBraces = styled.span`
- color: white;
- background-color: #f3672a;
+ color: ${(props) => props.theme.colors.codeMirror.background.hoverState};
+ background-color: #ffffff;
border-radius: 2px;
padding: 2px;
margin: 0px 2px;
diff --git a/app/client/src/components/editorComponents/CodeEditor/styledComponents.ts b/app/client/src/components/editorComponents/CodeEditor/styledComponents.ts
index 8af747b974..dce5b987ae 100644
--- a/app/client/src/components/editorComponents/CodeEditor/styledComponents.ts
+++ b/app/client/src/components/editorComponents/CodeEditor/styledComponents.ts
@@ -45,6 +45,15 @@ export const HintStyles = createGlobalStyle<{
font-size: 12px;
line-height: 15px;
letter-spacing: -0.24px;
+ &:hover {
+ background: ${(props) =>
+ props.theme.colors.codeMirror.background.hoverState};
+ border-radius: 0px;
+ color: #fff;
+ &:after {
+ color: #fff;
+ }
+ }
}
.datasource-hint {
@@ -56,12 +65,6 @@ export const HintStyles = createGlobalStyle<{
overflow: hidden;
text-overflow: ellipsis;
}
-
- li.CodeMirror-hint-active {
- background: ${(props) =>
- props.theme.colors.codeMirror.background.hoverState};
- border-radius: 0px;
- }
.CodeMirror-Tern-completion {
padding-left: ${(props) => props.theme.spaces[11]}px !important;
&:hover{
@@ -132,6 +135,15 @@ export const HintStyles = createGlobalStyle<{
.CodeMirror-Tern-tooltip {
z-index: 20 !important;
}
+ li.CodeMirror-hint-active {
+ background: ${(props) =>
+ props.theme.colors.codeMirror.background.hoverState};
+ border-radius: 0px;
+ color: #fff;
+ &:after {
+ color: #fff;
+ }
+ }
.CodeMirror-Tern-hint-doc {
display: none;
&.visible {
@@ -176,7 +188,7 @@ const getBorderStyle = (
};
const editorBackground = (theme?: EditorTheme) => {
- let bg = "#FFFFFF";
+ let bg = "#FAFAFA";
switch (theme) {
case EditorTheme.DARK:
bg = "#1A191C";
@@ -269,7 +281,9 @@ export const EditorWrapper = styled.div<{
? `border-bottom: 1px solid ${Colors.MERCURY}`
: `border: 1px solid ${Colors.MERCURY}`};
background: ${(props) =>
- props.isFocused || props.fill ? Colors.MERCURY : Colors.WHITE};
+ props.isFocused || props.fill
+ ? Colors.MERCURY
+ : props.theme.colors.codeMirror.background.defaultState};
color: ${Colors.CHARCOAL};
& {
span.cm-operator {
@@ -289,7 +303,9 @@ export const EditorWrapper = styled.div<{
? `border-bottom: 1px solid ${Colors.NERO}`
: `border: 1px solid ${Colors.NERO}`};
background: ${(props) =>
- props.isFocused || props.fill ? Colors.NERO : Colors.BALTIC_SEA};
+ props.isFocused || props.fill
+ ? Colors.NERO
+ : props.theme.colors.codeMirror.background.defaultState};
color: ${Colors.LIGHT_GREY};
}
.cm-s-duotone-light .CodeMirror-linenumber,
diff --git a/app/client/src/components/editorComponents/LoadingOverlayScreen.tsx b/app/client/src/components/editorComponents/LoadingOverlayScreen.tsx
index b8db6a05d5..03bd62ea12 100644
--- a/app/client/src/components/editorComponents/LoadingOverlayScreen.tsx
+++ b/app/client/src/components/editorComponents/LoadingOverlayScreen.tsx
@@ -9,8 +9,8 @@ export default styled.div<{ theme?: EditorTheme }>`
left: 0;
background-color: ${(props) =>
props.theme === EditorTheme.DARK
- ? "rgba(0, 0, 0, 0.6)"
- : "rgba(255, 255, 255, 0.6)"};
+ ? "rgba(0, 0, 0, 0.8)"
+ : "rgba(255, 255, 255, 0.8)"};
pointer-events: none;
z-index: 10;
color: ${(props) =>
diff --git a/app/client/src/components/editorComponents/form/fields/KeyValueFieldArray.tsx b/app/client/src/components/editorComponents/form/fields/KeyValueFieldArray.tsx
index 7dd75e5858..3dd3a6621d 100644
--- a/app/client/src/components/editorComponents/form/fields/KeyValueFieldArray.tsx
+++ b/app/client/src/components/editorComponents/form/fields/KeyValueFieldArray.tsx
@@ -103,7 +103,7 @@ const KeyValueRow = (props: Props & WrappedFieldArrayProps) => {
- {props.fields.length && (
+ {props.fields.length > 0 && (
{props.fields.map((field: any, index: number) => {
const otherProps: Record = {};
@@ -195,20 +195,18 @@ const KeyValueRow = (props: Props & WrappedFieldArrayProps) => {
);
})}
- props.fields.push({ key: "", value: "" })}
- >
-
-
- Add more
-
-
)}
+ props.fields.push({ key: "", value: "" })}>
+
+
+ Add more
+
+
);
};
diff --git a/app/client/src/constants/DefaultTheme.tsx b/app/client/src/constants/DefaultTheme.tsx
index 787253e95d..3d53682e0b 100644
--- a/app/client/src/constants/DefaultTheme.tsx
+++ b/app/client/src/constants/DefaultTheme.tsx
@@ -507,6 +507,7 @@ const darkShades = [
"#D4D4D4",
"#E9E9E9",
"#FFFFFF",
+ "#157A96",
] as const;
const lightShades = [
@@ -522,6 +523,7 @@ const lightShades = [
"#302D2D",
"#090707",
"#FFFFFF",
+ "#6A86CE",
] as const;
type ShadeColor = typeof darkShades[number] | typeof lightShades[number];
@@ -604,6 +606,11 @@ type ColorType = {
bg: ShadeColor;
icon: ShadeColor;
};
+ hovered: {
+ text: ShadeColor;
+ bg: ShadeColor;
+ icon: ShadeColor;
+ };
icon: ShadeColor;
};
toggle: {
@@ -672,6 +679,7 @@ type ColorType = {
normal: ShadeColor;
hover: ShadeColor;
border: ShadeColor;
+ countBg: ShadeColor;
};
settingHeading: ShadeColor;
table: {
@@ -793,6 +801,7 @@ type ColorType = {
text: ShadeColor;
dividerBg: ShadeColor;
iconHoverBg: ShadeColor;
+ tabBg: ShadeColor;
requestTree: {
bg: string;
header: {
@@ -1019,6 +1028,11 @@ export const dark: ColorType = {
bg: darkShades[4],
icon: darkShades[8],
},
+ hovered: {
+ text: darkShades[9],
+ bg: darkShades[10],
+ icon: darkShades[8],
+ },
icon: darkShades[6],
},
toggle: {
@@ -1087,6 +1101,7 @@ export const dark: ColorType = {
normal: darkShades[6],
hover: darkShades[7],
border: darkShades[3],
+ countBg: darkShades[4],
},
settingHeading: darkShades[9],
table: {
@@ -1205,6 +1220,7 @@ export const dark: ColorType = {
},
apiPane: {
bg: darkShades[0],
+ tabBg: lightShades[10],
text: darkShades[6],
dividerBg: darkShades[4],
iconHoverBg: darkShades[1],
@@ -1262,7 +1278,7 @@ export const dark: ColorType = {
codeMirror: {
background: {
defaultState: "#262626",
- hoverState: "#1A191C",
+ hoverState: darkShades[10],
},
text: "#FFFFFF",
dataType: {
@@ -1398,6 +1414,11 @@ export const light: ColorType = {
bg: lightShades[2],
icon: lightShades[8],
},
+ hovered: {
+ text: lightShades[11],
+ bg: lightShades[12],
+ icon: lightShades[8],
+ },
icon: lightShades[7],
},
toggle: {
@@ -1466,6 +1487,7 @@ export const light: ColorType = {
normal: lightShades[6],
hover: lightShades[10],
border: lightShades[3],
+ countBg: lightShades[3],
},
settingHeading: lightShades[9],
table: {
@@ -1583,7 +1605,8 @@ export const light: ColorType = {
border: "#E0DEDE",
},
apiPane: {
- bg: lightShades[11],
+ bg: lightShades[0],
+ tabBg: lightShades[11],
text: lightShades[6],
dividerBg: lightShades[3],
iconHoverBg: lightShades[1],
@@ -1640,8 +1663,8 @@ export const light: ColorType = {
},
codeMirror: {
background: {
- defaultState: "#EBEBEB",
- hoverState: "#FAFAFA",
+ defaultState: lightShades[0],
+ hoverState: lightShades[12],
},
text: "#090707",
dataType: {
diff --git a/app/client/src/constants/messages.ts b/app/client/src/constants/messages.ts
index 18ac765667..9ca3f8cf96 100644
--- a/app/client/src/constants/messages.ts
+++ b/app/client/src/constants/messages.ts
@@ -159,7 +159,7 @@ export const LIGHTNING_MENU_API_CREATE_NEW = "Create new API";
export const LIGHTNING_MENU_OPTION_TEXT = "Plain Text";
export const LIGHTNING_MENU_OPTION_JS = "Write JS";
export const LIGHTNING_MENU_OPTION_HTML = "Write HTML";
-export const CHECK_REQUEST_BODY = "Please check request body to debug?";
+export const CHECK_REQUEST_BODY = "Please check request body to debug";
export const DONT_SHOW_THIS_AGAIN = "Don't show this again";
export const SHOW_REQUEST = "Show Request";
diff --git a/app/client/src/pages/Editor/APIEditor/Form.tsx b/app/client/src/pages/Editor/APIEditor/Form.tsx
index e8fb7c5a35..a93cf35ce2 100644
--- a/app/client/src/pages/Editor/APIEditor/Form.tsx
+++ b/app/client/src/pages/Editor/APIEditor/Form.tsx
@@ -177,6 +177,8 @@ interface APIFormProps {
actionName: string;
apiId: string;
apiName: string;
+ headersCount: number;
+ paramsCount: number;
}
type Props = APIFormProps & InjectedFormProps;
@@ -227,6 +229,8 @@ const ApiEditorForm: React.FC = (props: Props) => {
actionConfigurationBody,
httpMethodFromForm,
actionName,
+ headersCount,
+ paramsCount,
} = props;
const allowPostBody =
httpMethodFromForm && httpMethodFromForm !== HTTP_METHODS[0];
@@ -269,12 +273,11 @@ const ApiEditorForm: React.FC = (props: Props) => {
}
>
-
+
@@ -324,6 +327,7 @@ const ApiEditorForm: React.FC = (props: Props) => {
{
key: "headers",
title: "Headers",
+ count: headersCount,
panelComponent: (
{apiBindHelpSectionVisible && (
@@ -358,7 +362,6 @@ const ApiEditorForm: React.FC = (props: Props) => {
actionConfig={actionConfigurationHeaders}
placeholder="Value"
dataTreePath={`${actionName}.config.headers`}
- pushFields
/>
),
@@ -366,6 +369,7 @@ const ApiEditorForm: React.FC = (props: Props) => {
{
key: "params",
title: "Params",
+ count: paramsCount,
panelComponent: (
= (props: Props) => {
name="actionConfiguration.queryParameters"
label="Params"
dataTreePath={`${actionName}.config.queryParameters`}
- pushFields
/>
),
@@ -448,6 +451,11 @@ export default connect((state: AppState) => {
);
const apiId = selector(state, "id");
const actionName = getApiName(state, apiId) || "";
+ const headers = selector(state, "actionConfiguration.headers");
+ const headersCount = Array.isArray(headers) ? headers.length : 0;
+
+ const params = selector(state, "actionConfiguration.queryParameters");
+ const paramsCount = Array.isArray(params) ? params.length : 0;
return {
actionName,
@@ -455,6 +463,8 @@ export default connect((state: AppState) => {
httpMethodFromForm,
actionConfigurationBody,
actionConfigurationHeaders,
+ headersCount,
+ paramsCount,
};
})(
reduxForm({
diff --git a/app/client/src/pages/Editor/APIEditor/PostBodyData.tsx b/app/client/src/pages/Editor/APIEditor/PostBodyData.tsx
index 5794c490be..dfba605669 100644
--- a/app/client/src/pages/Editor/APIEditor/PostBodyData.tsx
+++ b/app/client/src/pages/Editor/APIEditor/PostBodyData.tsx
@@ -21,6 +21,7 @@ import {
TabBehaviour,
} from "components/editorComponents/CodeEditor/EditorConfig";
import MultiSwitch from "components/ads/MultiSwitch";
+import { BodyFormData } from "entities/Action";
const PostBodyContainer = styled.div`
padding: 12px 0px 0px;
@@ -49,6 +50,8 @@ interface PostDataProps {
) => void;
dataTreePath: string;
theme?: EditorTheme;
+ bodyFormData?: BodyFormData[];
+ addBodyFormData: () => void;
}
type Props = PostDataProps;
@@ -61,6 +64,8 @@ const PostBodyData = (props: Props) => {
setDisplayFormat,
apiId,
dataTreePath,
+ bodyFormData,
+ addBodyFormData,
} = props;
return (
@@ -95,7 +100,6 @@ const PostBodyData = (props: Props) => {
name="actionConfiguration.bodyFormData"
dataTreePath={`${dataTreePath}.bodyFormData`}
label=""
- pushFields
theme={props.theme}
/>
);
@@ -123,29 +127,40 @@ const PostBodyData = (props: Props) => {
displayFormatObject &&
displayFormatObject.value === POST_BODY_FORMATS[3]
) {
+ // Dont update the content type header if raw has been selected
setDisplayFormat(apiId, POST_BODY_FORMAT_OPTIONS[3]);
return;
}
- const elementsIndex = actionConfigurationHeaders.findIndex(
+ const contentTypeHeaderIndex = actionConfigurationHeaders.findIndex(
(element: { key: string; value: string }) =>
element &&
element.key &&
element.key.trim().toLowerCase() === CONTENT_TYPE,
);
- if (elementsIndex >= 0 && displayFormatObject) {
- const updatedHeaders = [...actionConfigurationHeaders];
+ // If there is an existing header with content type, use that or
+ // create a new header
+ const indexToUpdate =
+ contentTypeHeaderIndex > -1
+ ? contentTypeHeaderIndex
+ : actionConfigurationHeaders.length;
- updatedHeaders[elementsIndex] = {
- ...updatedHeaders[elementsIndex],
- key: CONTENT_TYPE,
- value: displayFormatObject.value,
- };
+ const updatedHeaders = [...actionConfigurationHeaders];
- onDisplayFormatChange(updatedHeaders);
- } else {
- setDisplayFormat(apiId, POST_BODY_FORMAT_OPTIONS[3]);
+ updatedHeaders[indexToUpdate] = {
+ key: CONTENT_TYPE,
+ value: displayFormatObject.value,
+ };
+
+ onDisplayFormatChange(updatedHeaders);
+ if (
+ displayFormatObject &&
+ displayFormatObject.value === POST_BODY_FORMATS[1]
+ ) {
+ if (!bodyFormData) {
+ addBodyFormData();
+ }
}
}}
/>
@@ -167,6 +182,13 @@ const mapDispatchToProps = (dispatch: any) => ({
dispatch(
change(API_EDITOR_FORM_NAME, "actionConfiguration.headers", value),
),
+ addBodyFormData: () =>
+ dispatch(
+ change(API_EDITOR_FORM_NAME, "actionConfiguration.bodyFormData", [
+ { key: "", value: "" },
+ { key: "", value: "" },
+ ]),
+ ),
setDisplayFormat: (
id: string,
displayFormat: { label: string; value: string },
@@ -187,6 +209,7 @@ export default connect((state: AppState) => {
const apiId = selector(state, "id");
const extraFormData = state.ui.apiPane.extraformData[apiId] || {};
const headers = selector(state, "actionConfiguration.headers");
+ const bodyFormData = selector(state, "actionConfiguration.bodyFormData");
let contentType;
if (headers) {
contentType = headers.find(
@@ -200,5 +223,6 @@ export default connect((state: AppState) => {
extraFormData["displayFormat"] || POST_BODY_FORMAT_OPTIONS[3],
contentType,
apiId,
+ bodyFormData,
};
}, mapDispatchToProps)(PostBodyData);
diff --git a/app/client/src/pages/Editor/Explorer/Actions/MoreActionsMenu.tsx b/app/client/src/pages/Editor/Explorer/Actions/MoreActionsMenu.tsx
index 37ddca23a8..e8a416a779 100644
--- a/app/client/src/pages/Editor/Explorer/Actions/MoreActionsMenu.tsx
+++ b/app/client/src/pages/Editor/Explorer/Actions/MoreActionsMenu.tsx
@@ -82,6 +82,7 @@ export const MoreActionsMenu = (props: EntityContextMenuProps) => {
selectedValue=""
optionTree={[
{
+ icon: "duplicate",
value: "copy",
onSelect: noop,
label: "Copy to page",
@@ -93,6 +94,7 @@ export const MoreActionsMenu = (props: EntityContextMenuProps) => {
}),
},
{
+ icon: "swap-horizontal",
value: "move",
onSelect: noop,
label: "Move to page",
@@ -110,6 +112,7 @@ export const MoreActionsMenu = (props: EntityContextMenuProps) => {
: [{ value: "No Pages", onSelect: noop, label: "No Pages" }],
},
{
+ icon: "trash",
value: "delete",
onSelect: () => deleteActionFromPage(props.id, props.name),
label: "Delete",
diff --git a/app/client/src/widgets/DropdownWidget.tsx b/app/client/src/widgets/DropdownWidget.tsx
index a543650226..10dd74251c 100644
--- a/app/client/src/widgets/DropdownWidget.tsx
+++ b/app/client/src/widgets/DropdownWidget.tsx
@@ -13,6 +13,7 @@ import { TriggerPropertiesMap } from "utils/WidgetFactory";
import { Intent as BlueprintIntent } from "@blueprintjs/core";
import * as Sentry from "@sentry/react";
import withMeta, { WithMeta } from "./MetaHOC";
+import { IconName } from "@blueprintjs/icons";
class DropdownWidget extends BaseWidget {
static getPropertyPaneConfig() {
@@ -260,7 +261,7 @@ export type SelectionType = "SINGLE_SELECT" | "MULTI_SELECT";
export interface DropdownOption {
label: string;
value: string;
- icon?: string;
+ icon?: IconName;
subText?: string;
id?: string;
onSelect?: (option: DropdownOption) => void;
diff --git a/app/client/yarn.lock b/app/client/yarn.lock
index de1f267268..3df3909fd6 100644
--- a/app/client/yarn.lock
+++ b/app/client/yarn.lock
@@ -6848,10 +6848,10 @@ code-point-at@^1.0.0:
resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=
-codemirror@^5.55.0:
- version "5.58.1"
- resolved "https://registry.yarnpkg.com/codemirror/-/codemirror-5.58.1.tgz#ec6bf38ad2a17f74c61bd00cc6dc5a69bd167854"
- integrity sha512-UGb/ueu20U4xqWk8hZB3xIfV2/SFqnSLYONiM3wTMDqko0bsYrsAkGGhqUzbRkYm89aBKPyHtuNEbVWF9FTFzw==
+codemirror@^5.59.2:
+ version "5.59.2"
+ resolved "https://registry.yarnpkg.com/codemirror/-/codemirror-5.59.2.tgz#ee674d3a4a8d241af38d52afc482625ba7393922"
+ integrity sha512-/D5PcsKyzthtSy2NNKCyJi3b+htRkoKv3idswR/tR6UAvMNKA7SrmyZy6fOONJxSRs1JlUWEDAbxqfdArbK8iA==
collapse-white-space@^1.0.2:
version "1.0.6"