Skip to content

Commit

Permalink
chore: Updating some states related to action execution (#36801)
Browse files Browse the repository at this point in the history
  • Loading branch information
ankitakinger authored Oct 11, 2024
1 parent a0814e1 commit e03522f
Show file tree
Hide file tree
Showing 6 changed files with 107 additions and 15 deletions.
14 changes: 11 additions & 3 deletions app/client/src/PluginActionEditor/PluginActionContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,19 +28,27 @@ interface ChildrenProps {
export const PluginActionContextProvider = (
props: ChildrenProps & PluginActionContextType,
) => {
const { action, children, datasource, editorConfig, plugin, settingsConfig } =
props;
const {
action,
actionResponse,
children,
datasource,
editorConfig,
plugin,
settingsConfig,
} = props;

// using useMemo to avoid unnecessary renders
const contextValue = useMemo(
() => ({
action,
actionResponse,
datasource,
editorConfig,
plugin,
settingsConfig,
}),
[action, datasource, editorConfig, plugin, settingsConfig],
[action, actionResponse, datasource, editorConfig, plugin, settingsConfig],
);

return (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import React from "react";
import React, { useCallback } from "react";
import { IDEToolbar } from "IDE";
import { Button, Menu, MenuContent, MenuTrigger, Tooltip } from "@appsmith/ads";
import { modText } from "utils/helpers";
import { usePluginActionContext } from "../PluginActionContext";
import {
useBlockExecution,
useHandleRunClick,
useAnalyticsOnRunClick,
} from "PluginActionEditor/hooks";
import { useToggle } from "@mantine/hooks";
import { useSelector } from "react-redux";
import { isActionRunning } from "PluginActionEditor/store";

interface PluginActionToolbarProps {
runOptions?: React.ReactNode;
Expand All @@ -20,11 +23,13 @@ const PluginActionToolbar = (props: PluginActionToolbarProps) => {
const { handleRunClick } = useHandleRunClick();
const { callRunActionAnalytics } = useAnalyticsOnRunClick();
const [isMenuOpen, toggleMenuOpen] = useToggle([false, true]);
const blockExecution = useBlockExecution();
const isRunning = useSelector(isActionRunning(action.id));

const onRunClick = () => {
const onRunClick = useCallback(() => {
callRunActionAnalytics();
handleRunClick();
};
}, [callRunActionAnalytics, handleRunClick]);

return (
<IDEToolbar>
Expand All @@ -36,7 +41,13 @@ const PluginActionToolbar = (props: PluginActionToolbarProps) => {
placement="topRight"
showArrow={false}
>
<Button kind="primary" onClick={onRunClick} size="sm">
<Button
isDisabled={blockExecution}
isLoading={isRunning}
kind="primary"
onClick={onRunClick}
size="sm"
>
Run
</Button>
</Tooltip>
Expand Down
1 change: 1 addition & 0 deletions app/client/src/PluginActionEditor/hooks/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export { useActionSettingsConfig } from "ee/PluginActionEditor/hooks/useActionSettingsConfig";
export { useHandleDeleteClick } from "ee/PluginActionEditor/hooks/useHandleDeleteClick";
export { useHandleRunClick } from "ee/PluginActionEditor/hooks/useHandleRunClick";
export { useBlockExecution } from "ee/PluginActionEditor/hooks/useBlockExecution";
export { useAnalyticsOnRunClick } from "ee/PluginActionEditor/hooks/useAnalyticsOnRunClick";
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,24 @@ import DebuggerLogs from "components/editorComponents/Debugger/DebuggerLogs";
import { PluginType } from "entities/Action";
import { ApiResponse } from "PluginActionEditor/components/PluginActionResponse/components/ApiResponse";
import { ApiResponseHeaders } from "PluginActionEditor/components/PluginActionResponse/components/ApiResponseHeaders";
import { noop } from "lodash";
import { EditorTheme } from "components/editorComponents/CodeEditor/EditorConfig";
import { getErrorCount } from "selectors/debuggerSelectors";
import { getPluginActionDebuggerState } from "PluginActionEditor/store";
import {
getPluginActionDebuggerState,
isActionRunning,
} from "PluginActionEditor/store";
import { doesPluginRequireDatasource } from "ee/entities/Engine/actionHelpers";
import useShowSchema from "components/editorComponents/ActionRightPane/useShowSchema";
import Schema from "components/editorComponents/Debugger/Schema";
import QueryResponseTab from "pages/Editor/QueryEditor/QueryResponseTab";
import type { SourceEntity } from "entities/AppsmithConsole";
import { ENTITY_TYPE as SOURCE_ENTITY_TYPE } from "ee/entities/AppsmithConsole/utils";
import {
useBlockExecution,
useHandleRunClick,
useAnalyticsOnRunClick,
} from "PluginActionEditor/hooks";
import useDebuggerTriggerClick from "components/editorComponents/Debugger/hooks/useDebuggerTriggerClick";

function usePluginActionResponseTabs() {
const { action, actionResponse, datasource, plugin } =
Expand All @@ -46,6 +50,10 @@ function usePluginActionResponseTabs() {

const { responseTabHeight } = useSelector(getPluginActionDebuggerState);

const onDebugClick = useDebuggerTriggerClick();
const isRunning = useSelector(isActionRunning(action.id));
const blockExecution = useBlockExecution();

const tabs: BottomTab[] = [];

const onRunClick = () => {
Expand Down Expand Up @@ -78,8 +86,8 @@ function usePluginActionResponseTabs() {
<ApiResponse
action={action}
actionResponse={actionResponse}
isRunDisabled={false}
isRunning={false}
isRunDisabled={blockExecution}
isRunning={isRunning}
onRunClick={onRunClick}
responseTabHeight={responseTabHeight}
theme={EditorTheme.LIGHT}
Expand All @@ -92,9 +100,9 @@ function usePluginActionResponseTabs() {
panelComponent: (
<ApiResponseHeaders
actionResponse={actionResponse}
isRunDisabled={false}
isRunning={false}
onDebugClick={noop}
isRunDisabled={blockExecution}
isRunning={isRunning}
onDebugClick={onDebugClick}
onRunClick={onRunClick}
/>
),
Expand Down Expand Up @@ -141,7 +149,7 @@ function usePluginActionResponseTabs() {
actionName={action.name}
actionSource={actionSource}
currentActionConfig={action}
isRunning={false}
isRunning={isRunning}
onRunClick={onRunClick}
runErrorMessage={""} // TODO
/>
Expand Down
63 changes: 63 additions & 0 deletions app/client/src/ce/PluginActionEditor/hooks/useBlockExecution.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { getHasExecuteActionPermission } from "ee/utils/BusinessFeatures/permissionPageHelpers";
import { FEATURE_FLAG } from "ee/entities/FeatureFlag";
import { useFeatureFlag } from "utils/hooks/useFeatureFlag";
import { DEFAULT_DATASOURCE_NAME } from "constants/ApiEditorConstants/ApiEditorConstants";
import { UIComponentTypes } from "api/PluginApi";
import { SQL_DATASOURCES } from "constants/QueryEditorConstants";
import { usePluginActionContext } from "PluginActionEditor/PluginActionContext";

const useBlockExecution = () => {
const { action, plugin } = usePluginActionContext();
const isFeatureEnabled = useFeatureFlag(FEATURE_FLAG.license_gac_enabled);
const isExecutePermitted = getHasExecuteActionPermission(
isFeatureEnabled,
action?.userPermissions,
);

let actionBody = "";
let blockExecution = false;

// API Editor Constants
// this gets the url of the current action's datasource
const actionDatasourceUrl =
action.datasource.datasourceConfiguration?.url || "";
const actionDatasourceUrlPath = action.actionConfiguration.path || "";
// this gets the name of the current action's datasource
const actionDatasourceName = action.datasource.name || "";

// Query Editor Constants
if (!!action.actionConfiguration) {
if ("formData" in action.actionConfiguration) {
// if the action has a formData (the action is postUQI e.g. Oracle)
actionBody = action.actionConfiguration.formData?.body?.data || "";
} else {
// if the action is pre UQI, the path is different e.g. mySQL
actionBody = action.actionConfiguration?.body || "";
}
}

if (
[
UIComponentTypes.ApiEditorForm,
UIComponentTypes.GraphQLEditorForm,
].includes(plugin.uiComponent)
) {
// if the url is empty and the action's datasource name is the default datasource name (this means the api does not have a datasource attached)
// or the user does not have permission,
// we block action execution.
blockExecution =
(!actionDatasourceUrl &&
!actionDatasourceUrlPath &&
actionDatasourceName === DEFAULT_DATASOURCE_NAME) ||
!isExecutePermitted;
} else {
// if (the body is empty and the action is an sql datasource) or the user does not have permission, block action execution.
blockExecution =
(!actionBody && SQL_DATASOURCES.includes(plugin.name)) ||
!isExecutePermitted;
}

return blockExecution;
};

export { useBlockExecution };
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "ce/PluginActionEditor/hooks/useBlockExecution";

0 comments on commit e03522f

Please sign in to comment.