feat: add generate schema button (#39751)
## Description Update JS and Plugin Action Toolbar to add new Schema generation CTA in them https://www.figma.com/design/mVEbXXryqv2oBxMcNg8yjC/Anvil-AI?node-id=3891-34025&t=AVP3gbWu07WzPfwc-0 Fixes #39726 ## Automation /ok-to-test tags="@tag.JS, @tag.Datasource" ### 🔍 Cypress test results <!-- This is an auto-generated comment: Cypress test results --> > [!TIP] > 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉 > Workflow run: <https://github.com/appsmithorg/appsmith/actions/runs/13920663021> > Commit: c0b76039714bf64155c0d41c6f72cda881bcd968 > <a href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=13920663021&attempt=2" target="_blank">Cypress dashboard</a>. > Tags: `@tag.JS, @tag.Datasource` > Spec: > <hr>Tue, 18 Mar 2025 11:30:10 UTC <!-- end of auto-generated comment: Cypress test results --> ## Communication Should the DevRel and Marketing teams inform users about this change? - [ ] Yes - [ ] No <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Introduced real-time tracking of schema generation processes with clear UI indicators and error messaging. - Expanded actionable events to support improved feedback during schema creation for plugin actions and JavaScript functions. - **Refactor** - Streamlined component exports and updated import paths for enhanced organization and consistency in the editor toolbars. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Hetu Nandu <hetunandu@gmail.com>
This commit is contained in:
parent
2b703c9746
commit
d494ca4ee1
|
|
@ -3,7 +3,7 @@ export {
|
|||
PluginActionContextProvider,
|
||||
usePluginActionContext,
|
||||
} from "./PluginActionContext";
|
||||
export { default as PluginActionToolbar } from "./components/PluginActionToolbar";
|
||||
export { PluginActionToolbar } from "ee/PluginActionEditor/components/PluginActionToolbar";
|
||||
export { default as PluginActionForm } from "./components/PluginActionForm";
|
||||
export { default as PluginActionResponse } from "./components/PluginActionResponse";
|
||||
export type {
|
||||
|
|
|
|||
|
|
@ -20,6 +20,16 @@ export const isActionDirty = (id: string) =>
|
|||
const getActionRunningState = (state: AppState) =>
|
||||
state.ui.pluginActionEditor.isRunning;
|
||||
|
||||
const getActionSchemaGeneratingState = (state: AppState) =>
|
||||
state.ui.pluginActionEditor.isSchemaGenerating;
|
||||
|
||||
export const isActionSchemaGenerating = (id: string) =>
|
||||
createSelector(
|
||||
[getActionSchemaGeneratingState],
|
||||
(isSchemaGeneratingMap) =>
|
||||
id in isSchemaGeneratingMap && isSchemaGeneratingMap[id],
|
||||
);
|
||||
|
||||
export const isActionRunning = (id: string) =>
|
||||
createSelector(
|
||||
[getActionRunningState],
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ export interface PluginActionEditorState {
|
|||
isCreating: boolean;
|
||||
isRunning: Record<string, boolean>;
|
||||
isSaving: Record<string, boolean>;
|
||||
isSchemaGenerating: Record<string, boolean>;
|
||||
isDeleting: Record<string, boolean>;
|
||||
isDirty: Record<string, boolean>;
|
||||
runErrorMessage: Record<string, string>;
|
||||
|
|
@ -34,6 +35,7 @@ const initialState: PluginActionEditorState = {
|
|||
isCreating: false,
|
||||
isRunning: {},
|
||||
isSaving: {},
|
||||
isSchemaGenerating: {},
|
||||
isDeleting: {},
|
||||
isDirty: {},
|
||||
runErrorMessage: {},
|
||||
|
|
@ -141,6 +143,26 @@ export const handlers = {
|
|||
set(state, ["isRunning", id], false);
|
||||
set(state, ["runErrorMessage", id], error.message);
|
||||
},
|
||||
[ReduxActionTypes.GENERATE_PLUGIN_ACTION_SCHEMA_REQUEST]: (
|
||||
state: PluginActionEditorState,
|
||||
action: ReduxAction<{
|
||||
id: string;
|
||||
}>,
|
||||
) => {
|
||||
set(state, ["isSchemaGenerating", action.payload.id], true);
|
||||
},
|
||||
[ReduxActionTypes.GENERATE_PLUGIN_ACTION_SCHEMA_SUCCESS]: (
|
||||
state: PluginActionEditorState,
|
||||
action: ReduxAction<{ id: string }>,
|
||||
) => {
|
||||
set(state, ["isSchemaGenerating", action.payload.id], false);
|
||||
},
|
||||
[ReduxActionErrorTypes.GENERATE_PLUGIN_ACTION_SCHEMA_ERROR]: (
|
||||
state: PluginActionEditorState,
|
||||
action: ReduxAction<{ id: string }>,
|
||||
) => {
|
||||
set(state, ["isSchemaGenerating", action.payload.id], false);
|
||||
},
|
||||
[ReduxActionTypes.SET_PLUGIN_ACTION_EDITOR_FORM_SELECTED_TAB]: (
|
||||
state: PluginActionEditorState,
|
||||
action: ReduxAction<{ selectedTab: string }>,
|
||||
|
|
|
|||
|
|
@ -2,16 +2,16 @@ import React, { useCallback } from "react";
|
|||
import { IDEToolbar } from "IDE";
|
||||
import { Button, Tooltip } from "@appsmith/ads";
|
||||
import { modText } from "utils/helpers";
|
||||
import { usePluginActionContext } from "../PluginActionContext";
|
||||
import { usePluginActionContext } from "PluginActionEditor/PluginActionContext";
|
||||
import {
|
||||
useBlockExecution,
|
||||
useHandleRunClick,
|
||||
useAnalyticsOnRunClick,
|
||||
} from "../hooks";
|
||||
} from "PluginActionEditor/hooks";
|
||||
import { useSelector } from "react-redux";
|
||||
import { isActionRunning } from "../store";
|
||||
import PluginActionSettings from "./PluginActionSettings";
|
||||
import { PluginActionContextMenu } from "./PluginActionContextMenu";
|
||||
import { isActionRunning } from "PluginActionEditor/store";
|
||||
import PluginActionSettings from "PluginActionEditor/components/PluginActionSettings";
|
||||
import { PluginActionContextMenu } from "PluginActionEditor/components/PluginActionContextMenu";
|
||||
|
||||
interface PluginActionToolbarProps {
|
||||
runOptions?: React.ReactNode;
|
||||
|
|
@ -19,7 +19,7 @@ interface PluginActionToolbarProps {
|
|||
menuContent?: React.ReactNode[] | React.ReactNode;
|
||||
}
|
||||
|
||||
const PluginActionToolbar = (props: PluginActionToolbarProps) => {
|
||||
export const PluginActionToolbar = (props: PluginActionToolbarProps) => {
|
||||
const { action } = usePluginActionContext();
|
||||
const { handleRunClick } = useHandleRunClick();
|
||||
const { callRunActionAnalytics } = useAnalyticsOnRunClick();
|
||||
|
|
@ -63,5 +63,3 @@ const PluginActionToolbar = (props: PluginActionToolbarProps) => {
|
|||
</IDEToolbar>
|
||||
);
|
||||
};
|
||||
|
||||
export default PluginActionToolbar;
|
||||
|
|
@ -710,6 +710,16 @@ const ActionExecutionTypes = {
|
|||
RUN_ACTION_REQUEST: "RUN_ACTION_REQUEST",
|
||||
RUN_ACTION_CANCELLED: "RUN_ACTION_CANCELLED",
|
||||
RUN_ACTION_SUCCESS: "RUN_ACTION_SUCCESS",
|
||||
GENERATE_JS_FUNCTION_SCHEMA_REQUEST: "GENERATE_JS_FUNCTION_SCHEMA_REQUEST",
|
||||
GENERATE_JS_FUNCTION_SCHEMA_CANCELLED:
|
||||
"GENERATE_JS_FUNCTION_SCHEMA_CANCELLED",
|
||||
GENERATE_JS_FUNCTION_SCHEMA_SUCCESS: "GENERATE_JS_FUNCTION_SCHEMA_SUCCESS",
|
||||
GENERATE_PLUGIN_ACTION_SCHEMA_REQUEST:
|
||||
"GENERATE_PLUGIN_ACTION_SCHEMA_REQUEST",
|
||||
GENERATE_PLUGIN_ACTION_SCHEMA_CANCELLED:
|
||||
"GENERATE_PLUGIN_ACTION_SCHEMA_CANCELLED",
|
||||
GENERATE_PLUGIN_ACTION_SCHEMA_SUCCESS:
|
||||
"GENERATE_PLUGIN_ACTION_SCHEMA_SUCCESS",
|
||||
CLEAR_ACTION_RESPONSE: "CLEAR_ACTION_RESPONSE",
|
||||
SHOW_ACTION_MODAL: "SHOW_ACTION_MODAL",
|
||||
CANCEL_ACTION_MODAL: "CANCEL_ACTION_MODAL",
|
||||
|
|
@ -722,6 +732,8 @@ const ActionExecutionTypes = {
|
|||
|
||||
const ActionExecutionErrorTypes = {
|
||||
RUN_ACTION_ERROR: "RUN_ACTION_ERROR",
|
||||
GENERATE_JS_FUNCTION_SCHEMA_ERROR: "GENERATE_JS_FUNCTION_SCHEMA_ERROR",
|
||||
GENERATE_PLUGIN_ACTION_SCHEMA_ERROR: "GENERATE_PLUGIN_ACTION_SCHEMA_ERROR",
|
||||
EXECUTE_PLUGIN_ACTION_ERROR: "EXECUTE_PLUGIN_ACTION_ERROR",
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -647,6 +647,7 @@ export const EXPORT_DEFAULT_BEGINNING = () =>
|
|||
`Start object with export default`;
|
||||
export const ACTION_EXECUTION_FAILED = (actionName: string) =>
|
||||
`The action "${actionName}" has failed.`;
|
||||
export const CANNOT_GENERATE_SCHEMA = () => "Can't generate schema";
|
||||
export const JS_EXECUTION_TRIGGERED = () => "Function triggered";
|
||||
export const JS_EXECUTION_SUCCESS = () => "Function executed";
|
||||
export const JS_EXECUTION_FAILURE = () => "Function execution failed";
|
||||
|
|
|
|||
|
|
@ -1,15 +1,18 @@
|
|||
import React, { useState } from "react";
|
||||
import { IDEToolbar, ToolbarSettingsPopover } from "IDE";
|
||||
import { JSFunctionRun } from "./components/JSFunctionRun";
|
||||
import type { JSActionDropdownOption, OnUpdateSettingsProps } from "./types";
|
||||
import { JSFunctionRun } from "pages/Editor/JSEditor/JSEditorToolbar/components/JSFunctionRun";
|
||||
import type {
|
||||
JSActionDropdownOption,
|
||||
OnUpdateSettingsProps,
|
||||
} from "pages/Editor/JSEditor/JSEditorToolbar/types";
|
||||
import type { SaveActionNameParams } from "PluginActionEditor";
|
||||
import type { ReduxAction } from "actions/ReduxActionTypes";
|
||||
import type { JSAction, JSCollection } from "entities/JSCollection";
|
||||
import type { DropdownOnSelect } from "@appsmith/ads-old";
|
||||
import { createMessage, JS_EDITOR_SETTINGS } from "ee/constants/messages";
|
||||
import { JSFunctionSettings } from "./components/JSFunctionSettings";
|
||||
import { convertJSActionsToDropdownOptions } from "./utils";
|
||||
import { JSObjectNameEditor } from "./JSObjectNameEditor";
|
||||
import { JSFunctionSettings } from "pages/Editor/JSEditor/JSEditorToolbar/components/JSFunctionSettings";
|
||||
import { convertJSActionsToDropdownOptions } from "pages/Editor/JSEditor/JSEditorToolbar/utils";
|
||||
import { JSObjectNameEditor } from "pages/Editor/JSEditor/JSEditorToolbar/JSObjectNameEditor";
|
||||
|
||||
interface Props {
|
||||
changePermitted: boolean;
|
||||
|
|
@ -0,0 +1 @@
|
|||
export * from "ce/PluginActionEditor/components/PluginActionToolbar";
|
||||
|
|
@ -0,0 +1 @@
|
|||
export * from "ce/pages/Editor/JSEditor/JSEditorToolbar/JSEditorToolbar";
|
||||
|
|
@ -8,6 +8,7 @@ export const RUN_BUTTON_DEFAULTS = {
|
|||
export const testLocators = {
|
||||
runJSAction: "run-js-action",
|
||||
runJSActionTestID: "t--run-js-action",
|
||||
generateSchemaJSActionTestID: "t--generate-schema-js-action",
|
||||
};
|
||||
export const NO_FUNCTION_DROPDOWN_OPTION = {
|
||||
label: "No function available",
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
export { JSEditorToolbar } from "./JSEditorToolbar";
|
||||
export { JSEditorToolbar } from "ee/pages/Editor/JSEditor/JSEditorToolbar/JSEditorToolbar";
|
||||
|
||||
export {
|
||||
type OnUpdateSettingsProps,
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import {
|
|||
ReduxActionTypes,
|
||||
ReduxActionErrorTypes,
|
||||
} from "ee/constants/ReduxActionConstants";
|
||||
import type { JSCollection } from "entities/JSCollection";
|
||||
import type { JSAction, JSCollection } from "entities/JSCollection";
|
||||
import { ActionExecutionResizerHeight } from "PluginActionEditor/components/PluginActionResponse/constants";
|
||||
|
||||
export enum JSEditorTab {
|
||||
|
|
@ -23,6 +23,7 @@ export interface JsPaneReduxState {
|
|||
isSaving: Record<string, boolean>;
|
||||
isDeleting: Record<string, boolean>;
|
||||
isDirty: Record<string, boolean>;
|
||||
isSchemaGenerating: Record<string, boolean>;
|
||||
selectedConfigTab: JSEditorTab;
|
||||
debugger: JSPaneDebuggerState;
|
||||
}
|
||||
|
|
@ -32,6 +33,7 @@ const initialState: JsPaneReduxState = {
|
|||
isSaving: {},
|
||||
isDeleting: {},
|
||||
isDirty: {},
|
||||
isSchemaGenerating: {},
|
||||
selectedConfigTab: JSEditorTab.CODE,
|
||||
debugger: {
|
||||
open: false,
|
||||
|
|
@ -175,6 +177,50 @@ const jsPaneReducer = createReducer(initialState, {
|
|||
isSaving: false,
|
||||
};
|
||||
},
|
||||
[ReduxActionTypes.GENERATE_JS_FUNCTION_SCHEMA_REQUEST]: (
|
||||
state: JsPaneReduxState,
|
||||
action: ReduxAction<{
|
||||
action: JSAction;
|
||||
}>,
|
||||
) => {
|
||||
if (!action.payload.action.collectionId) return state;
|
||||
|
||||
return {
|
||||
...state,
|
||||
isSchemaGenerating: {
|
||||
...state.isSchemaGenerating,
|
||||
[action.payload.action.collectionId]: true,
|
||||
},
|
||||
};
|
||||
},
|
||||
[ReduxActionTypes.GENERATE_JS_FUNCTION_SCHEMA_SUCCESS]: (
|
||||
state: JsPaneReduxState,
|
||||
action: ReduxAction<{ action: JSAction }>,
|
||||
) => {
|
||||
if (!action.payload.action.collectionId) return state;
|
||||
|
||||
return {
|
||||
...state,
|
||||
isSchemaGenerating: {
|
||||
...state.isSchemaGenerating,
|
||||
[action.payload.action.collectionId]: false,
|
||||
},
|
||||
};
|
||||
},
|
||||
[ReduxActionErrorTypes.GENERATE_JS_FUNCTION_SCHEMA_ERROR]: (
|
||||
state: JsPaneReduxState,
|
||||
action: ReduxAction<{ action: JSAction }>,
|
||||
) => {
|
||||
if (!action.payload.action.collectionId) return state;
|
||||
|
||||
return {
|
||||
...state,
|
||||
isSchemaGenerating: {
|
||||
...state.isSchemaGenerating,
|
||||
[action.payload.action.collectionId]: false,
|
||||
},
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
export default jsPaneReducer;
|
||||
|
|
|
|||
|
|
@ -22,3 +22,11 @@ export const getLastJSTab = (state: AppState): FocusEntityInfo | undefined => {
|
|||
return identifyEntityFromPath(urlWithoutQueryParams);
|
||||
}
|
||||
};
|
||||
|
||||
export const getIsGeneratingSchema = (state: AppState, collectionId: string) =>
|
||||
state.ui.jsPane.isSchemaGenerating[collectionId];
|
||||
|
||||
export const getIsJSCollectionSaving = (
|
||||
state: AppState,
|
||||
collectionId: string,
|
||||
) => state.ui.jsPane.isSaving[collectionId];
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user