Minor Api pane design and logic fixes (#3091)

This commit is contained in:
Hetu Nandu 2021-02-22 11:45:02 +05:30 committed by GitHub
parent 0dab943be2
commit 447f458656
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 223 additions and 172 deletions

View File

@ -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",

View File

@ -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};
}

View File

@ -118,7 +118,6 @@ const TextContainer = styled.div<{
border-bottom-style: solid;
border-bottom-width: 1px;
width: fit-content;
max-width: 194px;
`
: null}
}

View File

@ -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) => {
<TabList>
{props.tabs.map((tab) => (
<Tab key={tab.key}>
{tab.icon ? <Icon name={tab.icon} size={IconSize.XXXL} /> : null}
<TabTitle>{tab.title}</TabTitle>
<TabTitleWrapper>
{tab.icon ? (
<Icon name={tab.icon} size={IconSize.XXXL} />
) : null}
<TabTitle>{tab.title}</TabTitle>
{tab.count && tab.count > 0 ? (
<TabCount>{tab.count}</TabCount>
) : null}
</TabTitleWrapper>
</Tab>
))}
</TabList>

View File

@ -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

View File

@ -159,6 +159,7 @@ export const ActionNameEditor = (props: ActionNameEditorProps) => {
editInteractionKind={NewEditInteractionKind.SINGLE}
hideEditIcon
underline
fill
/>
) : (
<div

View File

@ -14,20 +14,15 @@ import { Colors } from "constants/Colors";
import _ from "lodash";
import { RequestView } from "./RequestView";
import { useLocalStorage } from "utils/hooks/localstorage";
import {
CHECK_REQUEST_BODY,
DONT_SHOW_THIS_AGAIN,
SHOW_REQUEST,
} from "constants/messages";
import { CHECK_REQUEST_BODY, SHOW_REQUEST } from "constants/messages";
import { TabComponent } from "components/ads/Tabs";
import Text, { Case, TextType } from "components/ads/Text";
import Icon from "components/ads/Icon";
import { Classes, Variant } from "components/ads/common";
import { EditorTheme } from "./CodeEditor/EditorConfig";
import Callout from "components/ads/Callout";
import Button from "components/ads/Button";
const ResponseWrapper = styled.div`
const ResponseContainer = styled.div`
position: relative;
flex: 1;
height: 50%;
@ -53,73 +48,13 @@ const ResponseMetaWrapper = styled.div`
top: ${(props) => 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<string, ActionResponse | undefined>;
isRunning: Record<string, boolean>;
}
// const ResponseHeadersView = (props: { data: Record<string, string[]> }) => {
// if (!props.data) return <div />;
// return (
// <TableWrapper>
// <table className="bp3-html-table bp3-html-table-striped bp3-html-table-condensed">
// <thead>
// <tr>
// <th>Key</th>
// <th>Value</th>
// </tr>
// </thead>
// <tbody>
// {Object.keys(props.data).map(k => (
// <tr key={k}>
// <td>{k}</td>
// <td>{props.data[k].join(", ")}</td>
// </tr>
// ))}
// </tbody>
// </table>
// </TableWrapper>
// );
// };
type Props = ReduxStateProps &
RouteComponentProps<APIEditorRouteParams> & { 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<string, ActionResponse | undefined>;
isRunning: Record<string, boolean>;
}
type Props = ReduxStateProps &
RouteComponentProps<APIEditorRouteParams> & { 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: (
<>
<ResponseTabWrapper>
{hasFailed && !isRunning && requestDebugVisible && (
<Callout
variant={Variant.warning}
fill
text={CHECK_REQUEST_BODY}
label={
<FailedMessage>
<Text type={TextType.P2}>{CHECK_REQUEST_BODY}</Text>
<ButtonContainer>
<Text
type={TextType.H6}
case={Case.UPPERCASE}
onClick={() => {
setRequestDebugVisible(false);
}}
>
{DONT_SHOW_THIS_AGAIN}
<ShowRequestText
href={"#!"}
onClick={() => {
setSelectedIndex(1);
}}
>
<Text type={TextType.H6} case={Case.UPPERCASE}>
{SHOW_REQUEST}
</Text>
<Button
tag="button"
text={SHOW_REQUEST}
variant={Variant.info}
onClick={() => {
setSelectedIndex(1);
}}
/>
</ButtonContainer>
<Icon name="right-arrow" />
</ShowRequestText>
</FailedMessage>
}
variant={Variant.warning}
fill
closeButton
onClose={() => setRequestDebugVisible(false)}
/>
)}
{_.isEmpty(response.body) ? (
{_.isEmpty(response.statusCode) ? (
<NoResponseContainer>
<Icon name="no-response" />
<Text type={TextType.P1}>Hit Run to get a Response</Text>
@ -265,7 +221,7 @@ const ApiResponseView = (props: Props) => {
height={"100%"}
/>
)}
</>
</ResponseTabWrapper>
),
},
{
@ -287,7 +243,7 @@ const ApiResponseView = (props: Props) => {
];
return (
<ResponseWrapper>
<ResponseContainer>
<SectionDivider />
{isRunning && (
<LoadingOverlayScreen theme={props.theme}>
@ -334,7 +290,7 @@ const ApiResponseView = (props: Props) => {
onSelect={setSelectedIndex}
/>
</TabbedViewWrapper>
</ResponseWrapper>
</ResponseContainer>
);
};

View File

@ -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;

View File

@ -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,

View File

@ -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) =>

View File

@ -103,7 +103,7 @@ const KeyValueRow = (props: Props & WrappedFieldArrayProps) => {
</Text>
</Flex>
</FlexContainer>
{props.fields.length && (
{props.fields.length > 0 && (
<React.Fragment>
{props.fields.map((field: any, index: number) => {
const otherProps: Record<string, any> = {};
@ -195,20 +195,18 @@ const KeyValueRow = (props: Props & WrappedFieldArrayProps) => {
</FormRowWithLabel>
);
})}
<AddMoreAction
onClick={() => props.fields.push({ key: "", value: "" })}
>
<Icon
name="add-more"
className="t--addApiHeader"
size={IconSize.LARGE}
/>
<Text type={TextType.H5} case={Case.UPPERCASE}>
Add more
</Text>
</AddMoreAction>
</React.Fragment>
)}
<AddMoreAction onClick={() => props.fields.push({ key: "", value: "" })}>
<Icon
name="add-more"
className="t--addApiHeader"
size={IconSize.LARGE}
/>
<Text type={TextType.H5} case={Case.UPPERCASE}>
Add more
</Text>
</AddMoreAction>
</KeyValueStackContainer>
);
};

View File

@ -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: {

View File

@ -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";

View File

@ -177,6 +177,8 @@ interface APIFormProps {
actionName: string;
apiId: string;
apiName: string;
headersCount: number;
paramsCount: number;
}
type Props = APIFormProps & InjectedFormProps<Action, APIFormProps>;
@ -227,6 +229,8 @@ const ApiEditorForm: React.FC<Props> = (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: Props) => {
</Text>
}
>
<IconContainer>
<IconContainer onClick={handleClose}>
<Icon
name="close-modal"
size={IconSize.LARGE}
className="close-modal-icon"
onClick={handleClose}
/>
</IconContainer>
</TooltipComponent>
@ -324,6 +327,7 @@ const ApiEditorForm: React.FC<Props> = (props: Props) => {
{
key: "headers",
title: "Headers",
count: headersCount,
panelComponent: (
<TabSection>
{apiBindHelpSectionVisible && (
@ -358,7 +362,6 @@ const ApiEditorForm: React.FC<Props> = (props: Props) => {
actionConfig={actionConfigurationHeaders}
placeholder="Value"
dataTreePath={`${actionName}.config.headers`}
pushFields
/>
</TabSection>
),
@ -366,6 +369,7 @@ const ApiEditorForm: React.FC<Props> = (props: Props) => {
{
key: "params",
title: "Params",
count: paramsCount,
panelComponent: (
<TabSection>
<KeyValueFieldArray
@ -373,7 +377,6 @@ const ApiEditorForm: React.FC<Props> = (props: Props) => {
name="actionConfiguration.queryParameters"
label="Params"
dataTreePath={`${actionName}.config.queryParameters`}
pushFields
/>
</TabSection>
),
@ -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<Action, APIFormProps>({

View File

@ -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);

View File

@ -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",

View File

@ -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<DropdownWidgetProps, WidgetState> {
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;

View File

@ -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"