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

chore: Move Toolbar to IDE #36214

Merged
merged 14 commits into from
Sep 12, 2024
49 changes: 49 additions & 0 deletions app/client/src/IDE/Components/Toolbar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import React from "react";
import { Flex } from "@appsmith/ads";

interface ToolbarProps {
children?: React.ReactNode[] | React.ReactNode;
}

const Toolbar = (props: ToolbarProps) => {
return (
<Flex
alignItems="center"
borderBottom="1px solid var(--ads-v2-color-border-muted);"
flexDirection="row"
height="32px"
justifyContent="space-between"
padding="spaces-2"
>
{props.children}
</Flex>
);
};

const ToolbarLeft = (props: ToolbarProps) => {
return (
<Flex
alignItems="center"
flexDirection="row"
gap="spaces-2"
justifySelf="flex-start"
>
{props.children}
</Flex>
);
};

const ToolbarRight = (props: ToolbarProps) => {
return (
<Flex
alignItems="center"
flexDirection="row"
gap="spaces-2"
justifySelf="flex-end"
>
{props.children}
</Flex>
);
};

export { Toolbar, ToolbarLeft, ToolbarRight };
62 changes: 62 additions & 0 deletions app/client/src/PluginActionEditor/PluginActionContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import React, {
type ReactNode,
createContext,
useContext,
useMemo,
} from "react";
import type { Action } from "entities/Action";
import type { Plugin } from "api/PluginApi";
import type { Datasource } from "entities/Datasource";

interface PluginActionContext {
action: Action;
editorConfig: unknown[];
settingsConfig: unknown[];
plugin: Plugin;
datasource?: Datasource;
}

// No need to export this context to use it. Use the hook defined below instead
const PluginActionContext = createContext<PluginActionContext | null>(null);

interface ChildrenProps {
children: ReactNode[];
}

export const PluginActionContextProvider = (
props: ChildrenProps & PluginActionContext,
) => {
const { action, children, datasource, editorConfig, plugin, settingsConfig } =
props;

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

return (
<PluginActionContext.Provider value={contextValue}>
{children}
</PluginActionContext.Provider>
);
};

// By using this hook, you are guaranteed that the states are correctly
// typed and set.
// Without this, consumers of the context would need to keep doing a null check
export const usePluginActionContext = () => {
const context = useContext(PluginActionContext);
if (!context) {
throw new Error(
"usePluginActionContext must be used within usePluginActionContextProvider",
);
}
return context;
};
72 changes: 72 additions & 0 deletions app/client/src/PluginActionEditor/PluginActionEditor.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import React from "react";
import { useLocation } from "react-router";
import { identifyEntityFromPath } from "../navigation/FocusEntity";
import { useSelector } from "react-redux";
import {
getActionByBaseId,
getDatasource,
getEditorConfig,
getPlugin,
getPluginSettingConfigs,
} from "ee/selectors/entitiesSelector";
import { PluginActionContextProvider } from "./PluginActionContext";
import { get } from "lodash";
import EntityNotFoundPane from "pages/Editor/EntityNotFoundPane";
import { getIsEditorInitialized } from "selectors/editorSelectors";
import Spinner from "components/editorComponents/Spinner";
import CenteredWrapper from "components/designSystems/appsmith/CenteredWrapper";

interface ChildrenProps {
children: React.ReactNode[];
}

const PluginActionEditor = (props: ChildrenProps) => {
const { pathname } = useLocation();

const isEditorInitialized = useSelector(getIsEditorInitialized);

const entity = identifyEntityFromPath(pathname);
const action = useSelector((state) => getActionByBaseId(state, entity.id));

const pluginId = get(action, "pluginId", "");
const plugin = useSelector((state) => getPlugin(state, pluginId));

const datasourceId = get(action, "datasource.id", "");
const datasource = useSelector((state) => getDatasource(state, datasourceId));

const settingsConfig = useSelector((state) =>
getPluginSettingConfigs(state, pluginId),
);

const editorConfig = useSelector((state) => getEditorConfig(state, pluginId));

if (!isEditorInitialized) {
return (
<CenteredWrapper>
<Spinner size={30} />
</CenteredWrapper>
);
}

if (!action || !plugin) {
// Handle not found
return <EntityNotFoundPane />;
}
if (!settingsConfig || !editorConfig) {
throw Error("Plugin config for action not found");
}

return (
<PluginActionContextProvider
action={action}
datasource={datasource}
editorConfig={editorConfig}
plugin={plugin}
settingsConfig={settingsConfig}
>
{props.children}
</PluginActionContextProvider>
);
};

export default PluginActionEditor;
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import React from "react";

const PluginActionForm = () => {
return <div />;
};

export default PluginActionForm;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from "./PluginActionForm";
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import React from "react";

const PluginActionResponsePane = () => {
return <div />;
};

export default PluginActionResponsePane;
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import React from "react";
import { Toolbar, ToolbarLeft, ToolbarRight } from "IDE/Components/Toolbar";
import { Button, Tooltip } from "@appsmith/ads";

interface PluginActionToolbarProps {
runOptions?: React.ReactNode;
children?: React.ReactNode[] | React.ReactNode;
}

const PluginActionToolbar = (props: PluginActionToolbarProps) => {
return (
<Toolbar>
<ToolbarLeft>{props.children}</ToolbarLeft>
<ToolbarRight>
{props.runOptions}
<Tooltip content={"⌘ + ⏎"} placement="topRight" showArrow={false}>
hetunandu marked this conversation as resolved.
Show resolved Hide resolved
<Button kind="primary" size="sm">
Run
</Button>
</Tooltip>
<Button
isIconButton
kind="secondary"
size="sm"
startIcon="settings-2-line"
/>
<Button
isIconButton
kind="tertiary"
size="sm"
startIcon="more-2-fill"
/>
</ToolbarRight>
</Toolbar>
);
};

export default PluginActionToolbar;
8 changes: 8 additions & 0 deletions app/client/src/PluginActionEditor/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export { default as PluginActionEditor } from "./PluginActionEditor";
export {
PluginActionContextProvider,
usePluginActionContext,
} from "./PluginActionContext";
export { default as PluginActionToolbar } from "./components/PluginActionToolbar";
export { default as PluginActionForm } from "./components/PluginActionForm";
export { default as PluginActionResponsePane } from "./components/PluginActionResponsePane";
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import React from "react";
import {
PluginActionEditor,
PluginActionToolbar,
PluginActionForm,
PluginActionResponsePane,
} from "PluginActionEditor";

const AppPluginActionEditor = () => {
return (
<PluginActionEditor>
<PluginActionToolbar />
<PluginActionForm />
<PluginActionResponsePane />
</PluginActionEditor>
);
};

export default AppPluginActionEditor;
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { default as CE_AppPluginActionEditor } from "ce/pages/Editor/AppPluginActionEditor/AppPluginActionEditor";

export default CE_AppPluginActionEditor;
9 changes: 9 additions & 0 deletions app/client/src/pages/Editor/APIEditor/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import { resolveIcon } from "../utils";
import { ENTITY_ICON_SIZE, EntityIcon } from "../Explorer/ExplorerIcons";
import { getIDEViewMode } from "selectors/ideSelectors";
import { EditorViewMode } from "ee/entities/IDE/constants";
import { AppPluginActionEditor } from "pages/Editor/AppPluginActionEditor";

type ApiEditorWrapperProps = RouteComponentProps<APIEditorRouteParams>;

Expand Down Expand Up @@ -177,6 +178,14 @@ function ApiEditorWrapper(props: ApiEditorWrapperProps) {
return <ConvertEntityNotification icon={icon} name={action?.name || ""} />;
}, [action?.name, isConverting]);

const isActionRedesignEnabled = useFeatureFlag(
FEATURE_FLAG.release_actions_redesign_enabled,
);

if (isActionRedesignEnabled) {
return <AppPluginActionEditor />;
}

return (
<ApiEditorContextProvider
actionRightPaneBackLink={actionRightPaneBackLink}
Expand Down
1 change: 1 addition & 0 deletions app/client/src/pages/Editor/AppPluginActionEditor/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as AppPluginActionEditor } from "ee/pages/Editor/AppPluginActionEditor/AppPluginActionEditor";

This file was deleted.

Loading
Loading