Skip to content
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
Original file line number Diff line number Diff line change
@@ -1,33 +1,31 @@
import { Button, Flex } from "@appsmith/ads";
import type { ActionResponse } from "api/ActionAPI";
import { type Action } from "entities/Action";
import { ErrorBoundary } from "@sentry/react";
import { type VisualizationElements } from "entities/Action";
import React, { useState } from "react";
import { parseActionResponse } from "../Response/utils";
import { EmptyVisualization } from "./components/EmptyVisualization";
import { LoadingOverlay } from "./components/LoadingOverlay";
import { PromptInput } from "./components/PromptInput";
import { Result } from "./components/Result";
import { SuggestionButtons } from "./components/SuggestionButtons";
import { useGenerateVisualization } from "./useGenerateVisualization";
import { useSaveVisualization } from "./useSaveVisualization";
import { ErrorBoundary } from "@sentry/react";

interface VisualizationProps {
action: Action;
actionResponse?: ActionResponse;
entityId: string;
visualizationElements?: VisualizationElements;
response?: string | Record<string, unknown>[];
}

const BOTTOM_BAR_HEIGHT = 37;

export const Visualization = (props: VisualizationProps) => {
const { action, actionResponse } = props;
const { entityId, response, visualizationElements } = props;
const [prompt, setPrompt] = useState("");
const { response } = parseActionResponse(actionResponse);
const generateVisualization = useGenerateVisualization(
action.id,
action.visualization?.result,
entityId,
visualizationElements,
);
const saveVisualization = useSaveVisualization(action.id);
const saveVisualization = useSaveVisualization(entityId);

return (
// TODO: Remove the hardcoded height
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { Button, Input } from "@appsmith/ads";
import { Button, Flex, Input } from "@appsmith/ads";
import React from "react";
import styled from "styled-components";

interface PromptInputProps {
value: string;
Expand All @@ -10,25 +9,20 @@ interface PromptInputProps {
isDisabled: boolean;
}

const PromptForm = styled.form`
display: flex;
flex: 1;
gap: var(--ads-v2-spaces-3);
`;

export const PromptInput = (props: PromptInputProps) => {
const { isDisabled, isLoading, onChange, onSubmit, value } = props;

return (
<PromptForm
onSubmit={(e) => {
e.preventDefault();
onSubmit();
}}
>
// We can't use a form here because editor already wrapped in a form
<Flex flex="1" gap="spaces-3">
<Input
isDisabled={isDisabled}
onChange={onChange}
onKeyDown={(e) => {
if (e.key === "Enter") {
onSubmit();
}
}}
placeholder="Describe the data visualisation you want"
size="md"
value={value}
Expand All @@ -38,10 +32,10 @@ export const PromptInput = (props: PromptInputProps) => {
isIconButton
isLoading={isLoading}
kind="primary"
onClick={onSubmit}
size="md"
startIcon="arrow-up-line"
type="submit"
/>
</PromptForm>
</Flex>
);
};
23 changes: 22 additions & 1 deletion app/client/src/components/editorComponents/JSResponseView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ import { StateInspector } from "./Debugger/StateInspector";
import { getErrorCount } from "selectors/debuggerSelectors";
import { getIDETypeByUrl } from "ee/entities/IDE/utils";
import { useLocation } from "react-router";
import { getReleaseFnCallingEnabled } from "layoutSystems/anvil/integrations/selectors";
import { Visualization } from "../../PluginActionEditor/components/PluginActionResponse/components/Visualization";

const ResponseTabWrapper = styled.div`
display: flex;
Expand Down Expand Up @@ -212,16 +214,35 @@ function JSResponseView(props: Props) {

const ideViewMode = useSelector(getIDEViewMode);
const location = useLocation();
const isFnCallingEnabled = useSelector(getReleaseFnCallingEnabled);

const ideType = getIDETypeByUrl(location.pathname);

const tabs = useMemo(() => {
const jsTabs: BottomTab[] = [
const responseTabs: BottomTab[] = [
{
key: DEBUGGER_TAB_KEYS.RESPONSE_TAB,
title: createMessage(DEBUGGER_RESPONSE),
panelComponent: JSResponseTab,
},
];

if (isFnCallingEnabled) {
responseTabs.push({
key: DEBUGGER_TAB_KEYS.VISUALIZATION_TAB,
title: "AI Response Visualizer",
panelComponent: currentFunction && (
<Visualization
entityId={currentFunction.id}
response={response.value}
visualizationElements={currentFunction.visualization?.result}
/>
),
});
}

const jsTabs: BottomTab[] = [
...responseTabs,
{
key: DEBUGGER_TAB_KEYS.LOGS_TAB,
title: createMessage(DEBUGGER_LOGS),
Expand Down
Loading