Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Issue with Api Body content type selection #38597

Merged
merged 3 commits into from
Jan 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions app/client/cypress/support/Pages/ApiPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,7 @@ export class ApiPage {
"')]";
private _bodyTypeSelect = `//div[@data-testid="t--api-body-tab-switch"]`;
private _bodyTypeToSelect = (subTab: string) =>
"//div[contains(@class, 'rc-select-item-option')]//div[contains(text(),'" +
subTab +
"')]";
".rc-select-item-option:contains(" + subTab + ")";
private _rightPaneTab = (tab: string) =>
"//span[contains(text(), '" + tab + "')]/parent::button";
_visibleTextSpan = (spanText: string) => "//span[text()='" + spanText + "']";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { useCallback } from "react";
import { useDispatch, useSelector } from "react-redux";
import React from "react";
import { useSelector } from "react-redux";
import styled from "styled-components";
import {
POST_BODY_FORMAT_OPTIONS,
Expand All @@ -16,21 +16,22 @@ import {
TabBehaviour,
} from "components/editorComponents/CodeEditor/EditorConfig";
import { Classes } from "@appsmith/ads-old";
import {
getPostBodyFormat,
updatePostBodyContentType,
} from "../../../../store";
import type { CodeEditorExpected } from "components/editorComponents/CodeEditor";
import { AutocompleteDataType } from "utils/autocomplete/AutocompleteDataType";
import { createMessage, API_PANE_NO_BODY } from "ee/constants/messages";
import { Select, Option } from "@appsmith/ads";
import SelectField from "components/editorComponents/form/fields/SelectField";
import { getFormValues } from "redux-form";
import { API_EDITOR_FORM_NAME } from "ee/constants/forms";
import type { Action } from "entities/Action";
import { get } from "lodash";

const PostBodyContainer = styled.div`
display: flex;
flex-direction: column;
background-color: var(--ads-v2-color-bg);
height: 100%;
gap: var(--ads-v2-spaces-4);

.ads-v2-select {
max-width: 250px;
width: 100%;
Expand All @@ -40,6 +41,7 @@ const PostBodyContainer = styled.div`
const JSONEditorFieldWrapper = styled.div`
/* margin: 0 30px;
width: 65%; */

.CodeMirror {
height: auto;
min-height: 250px;
Expand Down Expand Up @@ -70,12 +72,12 @@ const expectedPostBody: CodeEditorExpected = {
};

function PostBodyData(props: Props) {
const postBodyFormat = useSelector(getPostBodyFormat);
const dispatch = useDispatch();

const updateBodyContentType = useCallback((tab: string) => {
dispatch(updatePostBodyContentType(tab));
}, []);
const formValues = useSelector(getFormValues(API_EDITOR_FORM_NAME)) as Action;
const postBodyFormat = get(
formValues,
"actionConfiguration.formData.apiContentType",
POST_BODY_FORMAT_OPTIONS.NONE,
);

Comment on lines +75 to +80
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Add null check for form values retrieval.

The form values retrieval could return undefined. Consider adding a null check or providing a fallback.

-  const formValues = useSelector(getFormValues(API_EDITOR_FORM_NAME)) as Action;
+  const formValues = useSelector(getFormValues(API_EDITOR_FORM_NAME)) as Action || {};
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const formValues = useSelector(getFormValues(API_EDITOR_FORM_NAME)) as Action;
const postBodyFormat = get(
formValues,
"actionConfiguration.formData.apiContentType",
POST_BODY_FORMAT_OPTIONS.NONE,
);
const formValues = useSelector(getFormValues(API_EDITOR_FORM_NAME)) as Action || {};
const postBodyFormat = get(
formValues,
"actionConfiguration.formData.apiContentType",
POST_BODY_FORMAT_OPTIONS.NONE,
);

const { dataTreePath, theme } = props;

Expand Down Expand Up @@ -171,19 +173,14 @@ function PostBodyData(props: Props) {

return (
<PostBodyContainer>
<Select
data-testid="t--api-body-tab-switch"
defaultValue={postBodyFormat.value}
onSelect={updateBodyContentType}
value={postBodyFormat.value}
>
{options.map((option) => (
<Option key={option.value} value={option.value}>
{option.label}
</Option>
))}
</Select>
{tabComponentsMap(postBodyFormat.value)}
<SelectField
name="actionConfiguration.formData.apiContentType"
options={options}
placeholder="Select Body Type"
showLabelOnly
testId="t--api-body-tab-switch"
/>
{tabComponentsMap(postBodyFormat)}
</PostBodyContainer>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,6 @@ export const openPluginActionSettings = (payload: boolean) => ({
},
});

export const updatePostBodyContentType = (
title: string,
): ReduxAction<{ title: string }> => ({
type: ReduxActionTypes.UPDATE_API_ACTION_BODY_CONTENT_TYPE,
payload: { title },
});

export const setExtraFormData = (
values: Record<string, { label: string; value: string }>,
) => ({
type: ReduxActionTypes.SET_EXTRA_FORMDATA,
payload: { values },
});

export const changeApi = (
id: string,
isSaas: boolean,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
import type { AppState } from "ee/reducers";
import { createSelector } from "reselect";

import { POST_BODY_FORM_DATA_KEY } from "./constants";
import { POST_BODY_FORMAT_OPTIONS } from "../constants/CommonApiConstants";

export const getActionEditorSavingMap = (state: AppState) =>
state.ui.pluginActionEditor.isSaving;

Expand Down Expand Up @@ -38,26 +35,6 @@ export const isActionDeleting = (id: string) =>
(deletingMap) => id in deletingMap && deletingMap[id],
);

export const getFormData = (state: AppState) =>
state.ui.pluginActionEditor.formData;

type GetFormPostBodyFormat = (state: AppState) => {
label: string;
value: string;
};

export const getPostBodyFormat: GetFormPostBodyFormat = (state) => {
const formData = getFormData(state);

if (POST_BODY_FORM_DATA_KEY in formData) {
return formData[POST_BODY_FORM_DATA_KEY];
}

return {
label: POST_BODY_FORMAT_OPTIONS.NONE,
value: POST_BODY_FORMAT_OPTIONS.NONE,
};
};
export const getPluginActionConfigSelectedTab = (state: AppState) =>
state.ui.pluginActionEditor.selectedConfigTab;

Expand Down
17 changes: 0 additions & 17 deletions app/client/src/PluginActionEditor/store/pluginEditorReducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ export interface PluginActionEditorState {
isDirty: Record<string, boolean>;
runErrorMessage: Record<string, string>;
selectedConfigTab?: string;
formData: Record<string, { label: string; value: string }>;
debugger: PluginEditorDebuggerState;
settingsOpen?: boolean;
}
Expand All @@ -38,7 +37,6 @@ const initialState: PluginActionEditorState = {
isDeleting: {},
isDirty: {},
runErrorMessage: {},
formData: {},
debugger: {
open: false,
responseTabHeight: ActionExecutionResizerHeight,
Expand Down Expand Up @@ -136,21 +134,6 @@ export const handlers = {
set(state, ["isRunning", id], false);
set(state, ["runErrorMessage", id], error.message);
},
/**
* This redux action sets the extra form data field for an action. This is used to select the
* appropriate body type tab selection in the Rest API plugin based on the content-type.
* This redux action can be extended to other functionalities as well in the future.
*/
[ReduxActionTypes.SET_EXTRA_FORMDATA]: (
state: PluginActionEditorState,
action: ReduxAction<{
values: Record<string, { label: string; value: string }>;
}>,
) => {
const { values } = action.payload;

set(state, ["formData"], values);
},
[ReduxActionTypes.SET_PLUGIN_ACTION_EDITOR_FORM_SELECTED_TAB]: (
state: PluginActionEditorState,
action: ReduxAction<{ selectedTab: string }>,
Expand Down
2 changes: 0 additions & 2 deletions app/client/src/ce/constants/ReduxActionConstants.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -769,7 +769,6 @@ const ActionActionTypes = {
UPDATE_ACTION_SUCCESS: "UPDATE_ACTION_SUCCESS",
DELETE_ACTION_INIT: "DELETE_ACTION_INIT",
DELETE_ACTION_SUCCESS: "DELETE_ACTION_SUCCESS",
SET_EXTRA_FORMDATA: "SET_EXTRA_FORMDATA",
MOVE_ACTION_INIT: "MOVE_ACTION_INIT",
MOVE_ACTION_SUCCESS: "MOVE_ACTION_SUCCESS",
COPY_ACTION_INIT: "COPY_ACTION_INIT",
Expand All @@ -787,7 +786,6 @@ const ActionActionTypes = {
TOGGLE_ACTION_EXECUTE_ON_LOAD_SUCCESS:
"TOGGLE_ACTION_EXECUTE_ON_LOAD_SUCCESS",
TOGGLE_ACTION_EXECUTE_ON_LOAD_INIT: "TOGGLE_ACTION_EXECUTE_ON_LOAD_INIT",
UPDATE_API_ACTION_BODY_CONTENT_TYPE: "UPDATE_API_ACTION_BODY_CONTENT_TYPE",
};

const ActionActionErrorTypes = {
Expand Down
17 changes: 1 addition & 16 deletions app/client/src/ce/navigation/FocusElements/AppIDE.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,16 +77,11 @@ import { ActionExecutionResizerHeight } from "PluginActionEditor/components/Plug
import {
getPluginActionConfigSelectedTab,
getPluginActionDebuggerState,
getFormData,
setExtraFormData,
setPluginActionEditorDebuggerState,
setPluginActionEditorSelectedTab,
} from "PluginActionEditor/store";
import { EDITOR_TABS } from "constants/QueryEditorConstants";
import {
API_EDITOR_TABS,
POST_BODY_FORMAT_OPTIONS,
} from "PluginActionEditor/constants/CommonApiConstants";
import { API_EDITOR_TABS } from "PluginActionEditor/constants/CommonApiConstants";

export const AppIDEFocusElements: FocusElementsConfigList = {
[FocusEntity.DATASOURCE_LIST]: [
Expand Down Expand Up @@ -155,16 +150,6 @@ export const AppIDEFocusElements: FocusElementsConfigList = {
},
},
},
{
type: FocusElementConfigType.Redux,
name: FocusElement.PluginActionFormData,
selector: getFormData,
setter: setExtraFormData,
defaultValue: {
label: POST_BODY_FORMAT_OPTIONS.NONE,
value: POST_BODY_FORMAT_OPTIONS.NONE,
},
},
{
type: FocusElementConfigType.Redux,
name: FocusElement.PluginActionDebugger,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ function DropdownFieldWrapper(props: DropdownFieldWrapperProps) {
>
{props.options.map((option: SelectOptionProps) => {
return (
<Option key={option.id} value={option.value}>
<Option key={option.value} value={option.value}>
{option.label || option.value}
</Option>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ interface DropdownWrapperProps {
disabled?: boolean;
dropdownMaxHeight?: string;
enableSearch?: boolean;
testId?: string;
}

function DropdownWrapper(props: DropdownWrapperProps) {
Expand Down Expand Up @@ -79,6 +80,7 @@ function DropdownWrapper(props: DropdownWrapperProps) {

return (
<Select
data-testId={props.testId}
defaultValue={props.isMultiSelect ? selectedOption : selectedOption[0]}
isDisabled={props.disabled}
isMultiSelect={props.isMultiSelect}
Expand All @@ -90,7 +92,9 @@ function DropdownWrapper(props: DropdownWrapperProps) {
>
{props.options.map((option: Partial<SelectOptionProps>) => (
<Option key={option.value} value={option.id}>
<Text renderAs="p">{option.value}</Text>
{props.showLabelOnly ? null : (
<Text renderAs="p">{option.value}</Text>
)}
{option.label && <Text renderAs="p">{option.label}</Text>}
</Option>
))}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ interface SelectFieldProps {
disabled?: boolean;
dropdownMaxHeight?: string;
enableSearch?: boolean;
testId?: string;
}

export function SelectField(props: SelectFieldProps) {
Expand All @@ -58,6 +59,7 @@ export function SelectField(props: SelectFieldProps) {
selected={props.selected}
showLabelOnly={props.showLabelOnly}
size={props.size}
testId={props.testId}
/>
);
}
Expand Down
1 change: 0 additions & 1 deletion app/client/src/navigation/FocusElements.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import type { AppState } from "ee/reducers";

export enum FocusElement {
PluginActionConfigTabs = "PluginActionConfigTabs",
PluginActionFormData = "PluginActionFormData",
CodeEditorHistory = "CodeEditorHistory",
EntityCollapsibleState = "EntityCollapsibleState",
EntityExplorerWidth = "EntityExplorerWidth",
Expand Down
Loading
Loading