chore: Updating some states related to action execution (#36801)
This commit is contained in:
parent
a0814e1438
commit
e03522fd29
|
|
@ -28,19 +28,27 @@ interface ChildrenProps {
|
||||||
export const PluginActionContextProvider = (
|
export const PluginActionContextProvider = (
|
||||||
props: ChildrenProps & PluginActionContextType,
|
props: ChildrenProps & PluginActionContextType,
|
||||||
) => {
|
) => {
|
||||||
const { action, children, datasource, editorConfig, plugin, settingsConfig } =
|
const {
|
||||||
props;
|
action,
|
||||||
|
actionResponse,
|
||||||
|
children,
|
||||||
|
datasource,
|
||||||
|
editorConfig,
|
||||||
|
plugin,
|
||||||
|
settingsConfig,
|
||||||
|
} = props;
|
||||||
|
|
||||||
// using useMemo to avoid unnecessary renders
|
// using useMemo to avoid unnecessary renders
|
||||||
const contextValue = useMemo(
|
const contextValue = useMemo(
|
||||||
() => ({
|
() => ({
|
||||||
action,
|
action,
|
||||||
|
actionResponse,
|
||||||
datasource,
|
datasource,
|
||||||
editorConfig,
|
editorConfig,
|
||||||
plugin,
|
plugin,
|
||||||
settingsConfig,
|
settingsConfig,
|
||||||
}),
|
}),
|
||||||
[action, datasource, editorConfig, plugin, settingsConfig],
|
[action, actionResponse, datasource, editorConfig, plugin, settingsConfig],
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,16 @@
|
||||||
import React from "react";
|
import React, { useCallback } from "react";
|
||||||
import { IDEToolbar } from "IDE";
|
import { IDEToolbar } from "IDE";
|
||||||
import { Button, Menu, MenuContent, MenuTrigger, Tooltip } from "@appsmith/ads";
|
import { Button, Menu, MenuContent, MenuTrigger, Tooltip } from "@appsmith/ads";
|
||||||
import { modText } from "utils/helpers";
|
import { modText } from "utils/helpers";
|
||||||
import { usePluginActionContext } from "../PluginActionContext";
|
import { usePluginActionContext } from "../PluginActionContext";
|
||||||
import {
|
import {
|
||||||
|
useBlockExecution,
|
||||||
useHandleRunClick,
|
useHandleRunClick,
|
||||||
useAnalyticsOnRunClick,
|
useAnalyticsOnRunClick,
|
||||||
} from "PluginActionEditor/hooks";
|
} from "PluginActionEditor/hooks";
|
||||||
import { useToggle } from "@mantine/hooks";
|
import { useToggle } from "@mantine/hooks";
|
||||||
|
import { useSelector } from "react-redux";
|
||||||
|
import { isActionRunning } from "PluginActionEditor/store";
|
||||||
|
|
||||||
interface PluginActionToolbarProps {
|
interface PluginActionToolbarProps {
|
||||||
runOptions?: React.ReactNode;
|
runOptions?: React.ReactNode;
|
||||||
|
|
@ -20,11 +23,13 @@ const PluginActionToolbar = (props: PluginActionToolbarProps) => {
|
||||||
const { handleRunClick } = useHandleRunClick();
|
const { handleRunClick } = useHandleRunClick();
|
||||||
const { callRunActionAnalytics } = useAnalyticsOnRunClick();
|
const { callRunActionAnalytics } = useAnalyticsOnRunClick();
|
||||||
const [isMenuOpen, toggleMenuOpen] = useToggle([false, true]);
|
const [isMenuOpen, toggleMenuOpen] = useToggle([false, true]);
|
||||||
|
const blockExecution = useBlockExecution();
|
||||||
|
const isRunning = useSelector(isActionRunning(action.id));
|
||||||
|
|
||||||
const onRunClick = () => {
|
const onRunClick = useCallback(() => {
|
||||||
callRunActionAnalytics();
|
callRunActionAnalytics();
|
||||||
handleRunClick();
|
handleRunClick();
|
||||||
};
|
}, [callRunActionAnalytics, handleRunClick]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<IDEToolbar>
|
<IDEToolbar>
|
||||||
|
|
@ -36,7 +41,13 @@ const PluginActionToolbar = (props: PluginActionToolbarProps) => {
|
||||||
placement="topRight"
|
placement="topRight"
|
||||||
showArrow={false}
|
showArrow={false}
|
||||||
>
|
>
|
||||||
<Button kind="primary" onClick={onRunClick} size="sm">
|
<Button
|
||||||
|
isDisabled={blockExecution}
|
||||||
|
isLoading={isRunning}
|
||||||
|
kind="primary"
|
||||||
|
onClick={onRunClick}
|
||||||
|
size="sm"
|
||||||
|
>
|
||||||
Run
|
Run
|
||||||
</Button>
|
</Button>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
export { useActionSettingsConfig } from "ee/PluginActionEditor/hooks/useActionSettingsConfig";
|
export { useActionSettingsConfig } from "ee/PluginActionEditor/hooks/useActionSettingsConfig";
|
||||||
export { useHandleDeleteClick } from "ee/PluginActionEditor/hooks/useHandleDeleteClick";
|
export { useHandleDeleteClick } from "ee/PluginActionEditor/hooks/useHandleDeleteClick";
|
||||||
export { useHandleRunClick } from "ee/PluginActionEditor/hooks/useHandleRunClick";
|
export { useHandleRunClick } from "ee/PluginActionEditor/hooks/useHandleRunClick";
|
||||||
|
export { useBlockExecution } from "ee/PluginActionEditor/hooks/useBlockExecution";
|
||||||
export { useAnalyticsOnRunClick } from "ee/PluginActionEditor/hooks/useAnalyticsOnRunClick";
|
export { useAnalyticsOnRunClick } from "ee/PluginActionEditor/hooks/useAnalyticsOnRunClick";
|
||||||
|
|
|
||||||
|
|
@ -17,10 +17,12 @@ import DebuggerLogs from "components/editorComponents/Debugger/DebuggerLogs";
|
||||||
import { PluginType } from "entities/Action";
|
import { PluginType } from "entities/Action";
|
||||||
import { ApiResponse } from "PluginActionEditor/components/PluginActionResponse/components/ApiResponse";
|
import { ApiResponse } from "PluginActionEditor/components/PluginActionResponse/components/ApiResponse";
|
||||||
import { ApiResponseHeaders } from "PluginActionEditor/components/PluginActionResponse/components/ApiResponseHeaders";
|
import { ApiResponseHeaders } from "PluginActionEditor/components/PluginActionResponse/components/ApiResponseHeaders";
|
||||||
import { noop } from "lodash";
|
|
||||||
import { EditorTheme } from "components/editorComponents/CodeEditor/EditorConfig";
|
import { EditorTheme } from "components/editorComponents/CodeEditor/EditorConfig";
|
||||||
import { getErrorCount } from "selectors/debuggerSelectors";
|
import { getErrorCount } from "selectors/debuggerSelectors";
|
||||||
import { getPluginActionDebuggerState } from "PluginActionEditor/store";
|
import {
|
||||||
|
getPluginActionDebuggerState,
|
||||||
|
isActionRunning,
|
||||||
|
} from "PluginActionEditor/store";
|
||||||
import { doesPluginRequireDatasource } from "ee/entities/Engine/actionHelpers";
|
import { doesPluginRequireDatasource } from "ee/entities/Engine/actionHelpers";
|
||||||
import useShowSchema from "components/editorComponents/ActionRightPane/useShowSchema";
|
import useShowSchema from "components/editorComponents/ActionRightPane/useShowSchema";
|
||||||
import Schema from "components/editorComponents/Debugger/Schema";
|
import Schema from "components/editorComponents/Debugger/Schema";
|
||||||
|
|
@ -28,9 +30,11 @@ import QueryResponseTab from "pages/Editor/QueryEditor/QueryResponseTab";
|
||||||
import type { SourceEntity } from "entities/AppsmithConsole";
|
import type { SourceEntity } from "entities/AppsmithConsole";
|
||||||
import { ENTITY_TYPE as SOURCE_ENTITY_TYPE } from "ee/entities/AppsmithConsole/utils";
|
import { ENTITY_TYPE as SOURCE_ENTITY_TYPE } from "ee/entities/AppsmithConsole/utils";
|
||||||
import {
|
import {
|
||||||
|
useBlockExecution,
|
||||||
useHandleRunClick,
|
useHandleRunClick,
|
||||||
useAnalyticsOnRunClick,
|
useAnalyticsOnRunClick,
|
||||||
} from "PluginActionEditor/hooks";
|
} from "PluginActionEditor/hooks";
|
||||||
|
import useDebuggerTriggerClick from "components/editorComponents/Debugger/hooks/useDebuggerTriggerClick";
|
||||||
|
|
||||||
function usePluginActionResponseTabs() {
|
function usePluginActionResponseTabs() {
|
||||||
const { action, actionResponse, datasource, plugin } =
|
const { action, actionResponse, datasource, plugin } =
|
||||||
|
|
@ -46,6 +50,10 @@ function usePluginActionResponseTabs() {
|
||||||
|
|
||||||
const { responseTabHeight } = useSelector(getPluginActionDebuggerState);
|
const { responseTabHeight } = useSelector(getPluginActionDebuggerState);
|
||||||
|
|
||||||
|
const onDebugClick = useDebuggerTriggerClick();
|
||||||
|
const isRunning = useSelector(isActionRunning(action.id));
|
||||||
|
const blockExecution = useBlockExecution();
|
||||||
|
|
||||||
const tabs: BottomTab[] = [];
|
const tabs: BottomTab[] = [];
|
||||||
|
|
||||||
const onRunClick = () => {
|
const onRunClick = () => {
|
||||||
|
|
@ -78,8 +86,8 @@ function usePluginActionResponseTabs() {
|
||||||
<ApiResponse
|
<ApiResponse
|
||||||
action={action}
|
action={action}
|
||||||
actionResponse={actionResponse}
|
actionResponse={actionResponse}
|
||||||
isRunDisabled={false}
|
isRunDisabled={blockExecution}
|
||||||
isRunning={false}
|
isRunning={isRunning}
|
||||||
onRunClick={onRunClick}
|
onRunClick={onRunClick}
|
||||||
responseTabHeight={responseTabHeight}
|
responseTabHeight={responseTabHeight}
|
||||||
theme={EditorTheme.LIGHT}
|
theme={EditorTheme.LIGHT}
|
||||||
|
|
@ -92,9 +100,9 @@ function usePluginActionResponseTabs() {
|
||||||
panelComponent: (
|
panelComponent: (
|
||||||
<ApiResponseHeaders
|
<ApiResponseHeaders
|
||||||
actionResponse={actionResponse}
|
actionResponse={actionResponse}
|
||||||
isRunDisabled={false}
|
isRunDisabled={blockExecution}
|
||||||
isRunning={false}
|
isRunning={isRunning}
|
||||||
onDebugClick={noop}
|
onDebugClick={onDebugClick}
|
||||||
onRunClick={onRunClick}
|
onRunClick={onRunClick}
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
|
|
@ -141,7 +149,7 @@ function usePluginActionResponseTabs() {
|
||||||
actionName={action.name}
|
actionName={action.name}
|
||||||
actionSource={actionSource}
|
actionSource={actionSource}
|
||||||
currentActionConfig={action}
|
currentActionConfig={action}
|
||||||
isRunning={false}
|
isRunning={isRunning}
|
||||||
onRunClick={onRunClick}
|
onRunClick={onRunClick}
|
||||||
runErrorMessage={""} // TODO
|
runErrorMessage={""} // TODO
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -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 };
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
export * from "ce/PluginActionEditor/hooks/useBlockExecution";
|
||||||
Loading…
Reference in New Issue
Block a user