diff --git a/app/client/packages/design-system/widgets/src/components/AIChat/src/AIChat.tsx b/app/client/packages/design-system/widgets/src/components/AIChat/src/AIChat.tsx index 40a50d43754f..4fbadd4aaad5 100644 --- a/app/client/packages/design-system/widgets/src/components/AIChat/src/AIChat.tsx +++ b/app/client/packages/design-system/widgets/src/components/AIChat/src/AIChat.tsx @@ -1,6 +1,7 @@ -import { Button, Text, TextArea } from "@appsmith/wds"; +import { Button, Flex, Text, TextArea } from "@appsmith/wds"; import type { FormEvent, ForwardedRef, KeyboardEvent } from "react"; import React, { forwardRef, useCallback } from "react"; +import { ChatDescriptionModal } from "./ChatDescriptionModal"; import { ChatTitle } from "./ChatTitle"; import styles from "./styles.module.css"; import { ThreadMessage } from "./ThreadMessage"; @@ -12,6 +13,7 @@ const MIN_PROMPT_LENGTH = 3; const _AIChat = (props: AIChatProps, ref: ForwardedRef) => { const { // assistantName, + chatDescription, chatTitle, isWaitingForResponse = false, onApplyAssistantSuggestion, @@ -23,6 +25,8 @@ const _AIChat = (props: AIChatProps, ref: ForwardedRef) => { username, ...rest } = props; + const [isChatDescriptionModalOpen, setIsChatDescriptionModalOpen] = + React.useState(false); const handleFormSubmit = useCallback( (event: FormEvent) => { @@ -44,15 +48,31 @@ const _AIChat = (props: AIChatProps, ref: ForwardedRef) => { return (
+ + setIsChatDescriptionModalOpen(!isChatDescriptionModalOpen) + } + > + {chatDescription} + +
- + + +
    diff --git a/app/client/packages/design-system/widgets/src/components/AIChat/src/ChatDescriptionModal/ChatDescriptionModal.tsx b/app/client/packages/design-system/widgets/src/components/AIChat/src/ChatDescriptionModal/ChatDescriptionModal.tsx new file mode 100644 index 000000000000..06b983a1e32f --- /dev/null +++ b/app/client/packages/design-system/widgets/src/components/AIChat/src/ChatDescriptionModal/ChatDescriptionModal.tsx @@ -0,0 +1,17 @@ +import { Modal, ModalBody, ModalContent, ModalHeader } from "@appsmith/wds"; +import React from "react"; +import type { ChatDescriptionModalProps } from "./types"; + +export const ChatDescriptionModal = ({ + children, + ...rest +}: ChatDescriptionModalProps) => { + return ( + + + + {children} + + + ); +}; diff --git a/app/client/packages/design-system/widgets/src/components/AIChat/src/ChatDescriptionModal/index.ts b/app/client/packages/design-system/widgets/src/components/AIChat/src/ChatDescriptionModal/index.ts new file mode 100644 index 000000000000..e16a07a5b8f4 --- /dev/null +++ b/app/client/packages/design-system/widgets/src/components/AIChat/src/ChatDescriptionModal/index.ts @@ -0,0 +1,2 @@ +export * from "./ChatDescriptionModal"; +export * from "./types"; diff --git a/app/client/packages/design-system/widgets/src/components/AIChat/src/ChatDescriptionModal/types.ts b/app/client/packages/design-system/widgets/src/components/AIChat/src/ChatDescriptionModal/types.ts new file mode 100644 index 000000000000..41e2f9c04360 --- /dev/null +++ b/app/client/packages/design-system/widgets/src/components/AIChat/src/ChatDescriptionModal/types.ts @@ -0,0 +1,3 @@ +import type { ModalProps } from "@appsmith/wds"; + +export interface ChatDescriptionModalProps extends ModalProps {} diff --git a/app/client/packages/design-system/widgets/src/components/AIChat/src/ChatTitle/styles.module.css b/app/client/packages/design-system/widgets/src/components/AIChat/src/ChatTitle/styles.module.css index a952c30dbf76..f231c0590300 100644 --- a/app/client/packages/design-system/widgets/src/components/AIChat/src/ChatTitle/styles.module.css +++ b/app/client/packages/design-system/widgets/src/components/AIChat/src/ChatTitle/styles.module.css @@ -1,6 +1,6 @@ .root { display: flex; - gap: 12px; + gap: var(--inner-spacing-3); align-items: center; /* TODO: --type-title doesn't exists. Define it */ font-size: var(--type-title, 22.499px); @@ -15,7 +15,7 @@ width: 48px; min-width: 48px; height: 48px; - border-radius: 8px; + border-radius: var(--border-radius-elevation-2); /* TODO: --bd-neutral doesn't exists. Define it */ border: 1px solid var(--bd-neutral, #81858b); background: #f8f8f8; diff --git a/app/client/packages/design-system/widgets/src/components/AIChat/src/ThreadMessage/ThreadMessage.tsx b/app/client/packages/design-system/widgets/src/components/AIChat/src/ThreadMessage/ThreadMessage.tsx index 7b827d3f576d..9be3e3b7cec3 100644 --- a/app/client/packages/design-system/widgets/src/components/AIChat/src/ThreadMessage/ThreadMessage.tsx +++ b/app/client/packages/design-system/widgets/src/components/AIChat/src/ThreadMessage/ThreadMessage.tsx @@ -57,7 +57,7 @@ export const ThreadMessage = ({ {promptSuggestions.length > 0 && ( diff --git a/app/client/packages/design-system/widgets/src/components/AIChat/src/ThreadMessage/styles.module.css b/app/client/packages/design-system/widgets/src/components/AIChat/src/ThreadMessage/styles.module.css index e8081ecad004..198d74d9cca0 100644 --- a/app/client/packages/design-system/widgets/src/components/AIChat/src/ThreadMessage/styles.module.css +++ b/app/client/packages/design-system/widgets/src/components/AIChat/src/ThreadMessage/styles.module.css @@ -1,12 +1,12 @@ .root { display: flex; - gap: 16px; - padding: 12px 0; + gap: var(--inner-spacing-4); + padding: var(--inner-spacing-3) 0; } @container (min-width: 700px) { .root { - padding: 24px 0; + padding: var(--inner-spacing-5) 0; } } @@ -19,7 +19,7 @@ } .sentTime { - margin: 0 0 8px; + margin: 0 0 var(--outer-spacing-3); /* TODO: --type-caption doesn't exists. Define it */ font-size: var(--type-caption, 12.247px); /* TODO: --type-caption-lineheight doesn't exists. Define it */ diff --git a/app/client/packages/design-system/widgets/src/components/AIChat/src/styles.module.css b/app/client/packages/design-system/widgets/src/components/AIChat/src/styles.module.css index 3c0780cf6209..b1905d1daf5a 100644 --- a/app/client/packages/design-system/widgets/src/components/AIChat/src/styles.module.css +++ b/app/client/packages/design-system/widgets/src/components/AIChat/src/styles.module.css @@ -9,8 +9,8 @@ .header { display: flex; flex-direction: column; - gap: 8px; - padding: 22px 40px; + gap: var(--inner-spacing-2); + padding: var(--inner-spacing-5) var(--inner-spacing-6); align-items: flex-start; border-bottom: 1px solid var(--color-bd-elevation-1); background: rgba(255, 255, 255, 0.45); @@ -24,18 +24,13 @@ } } -.username { - display: flex; - align-items: center; - gap: 8px; -} - .thread { display: flex; flex-direction: column; - gap: 12px; + gap: var(--inner-spacing-3); align-self: stretch; - padding: 0px 40px var(--inner-spacing-5) 40px; + padding: 0px var(--inner-spacing-6) var(--inner-spacing-5) + var(--inner-spacing-6); } .promptForm { diff --git a/app/client/packages/design-system/widgets/src/components/Modal/src/index.ts b/app/client/packages/design-system/widgets/src/components/Modal/src/index.ts index 8f811e192d44..d92e4cafc9c6 100644 --- a/app/client/packages/design-system/widgets/src/components/Modal/src/index.ts +++ b/app/client/packages/design-system/widgets/src/components/Modal/src/index.ts @@ -3,3 +3,4 @@ export * from "./ModalHeader"; export * from "./ModalFooter"; export * from "./ModalBody"; export * from "./ModalContent"; +export * from "./types"; diff --git a/app/client/src/modules/ui-builder/ui/wds/WDSAIChatWidget/widget/index.tsx b/app/client/src/modules/ui-builder/ui/wds/WDSAIChatWidget/widget/index.tsx index 0c2d773abae5..99126ca71667 100644 --- a/app/client/src/modules/ui-builder/ui/wds/WDSAIChatWidget/widget/index.tsx +++ b/app/client/src/modules/ui-builder/ui/wds/WDSAIChatWidget/widget/index.tsx @@ -249,6 +249,7 @@ class WDSAIChatWidget extends BaseWidget { return ( { + let chartWidget: ChartWidget; + + const seriesData1: ChartData = { + seriesName: "series1", + data: [{ x: "x1", y: 1 }], + color: "series1color", + }; + const seriesData2: ChartData = { + seriesName: "series2", + data: [{ x: "x1", y: 2 }], + color: "series2color", + }; + const defaultProps: ChartWidgetProps = { + allowScroll: true, + showDataPointLabel: true, + chartData: { + seriesID1: seriesData1, + seriesID2: seriesData2, + }, + chartName: "chart name", + type: "CHART_WIDGET", + chartType: "AREA_CHART", + customEChartConfig: {}, + customFusionChartConfig: { type: "type", dataSource: undefined }, + hasOnDataPointClick: true, + isVisible: true, + isLoading: false, + setAdaptiveYMin: false, + labelOrientation: LabelOrientation.AUTO, + onDataPointClick: "", + widgetId: "widgetID", + xAxisName: "xaxisname", + yAxisName: "yaxisname", + borderRadius: "1", + boxShadow: "1", + primaryColor: "primarycolor", + fontFamily: "fontfamily", + dimensions: { componentWidth: 11, componentHeight: 11 }, + parentColumnSpace: 1, + parentRowSpace: 1, + topRow: 0, + bottomRow: 0, + leftColumn: 0, + rightColumn: 0, + widgetName: "widgetName", + version: 1, + renderMode: RenderModes.CANVAS, + }; + const errors: WidgetError[] = [ + { + name: "error", + type: "configuration", + message: "We have a error", + }, + ]; + + describe("loading state", () => { + it("isLoading: true", () => { + chartWidget = new ChartWidget({ ...defaultProps, isLoading: true }); + + const view = chartWidget.getWidgetView(); + + expect(view.props.children.props.isLoading).toBe(true); + }); + + it("isLoading: true + errors", () => { + chartWidget = new ChartWidget({ + ...defaultProps, + isLoading: true, + errors, + }); + + const view = chartWidget.getWidgetView(); + + expect(view.props.children.props.isLoading).toBe(true); + }); + it("isLoading: true + emptyChartData", () => { + chartWidget = new ChartWidget({ + ...defaultProps, + isLoading: true, + chartData: {}, + }); + + const view = chartWidget.getWidgetView(); + + expect(view.props.children.props.isLoading).toBe(true); + }); + }); + + it("renders error state", () => { + chartWidget = new ChartWidget({ + ...defaultProps, + errors, + }); + + const view = chartWidget.getWidgetView(); + + expect(view.props.error.message).toBe("We have a error"); + }); + + it("renders empty chart data state", () => { + chartWidget = new ChartWidget({ ...defaultProps, chartData: {} }); + + const view = chartWidget.getWidgetView(); + + expect(view.type).toEqual(EmptyChartData); + }); + + it("renders chart with data", () => { + chartWidget = new ChartWidget(defaultProps); + const view = chartWidget.getWidgetView(); + + expect(view.props.children.props.chartData).toEqual({ + seriesID1: seriesData1, + seriesID2: seriesData2, + }); + }); +}); diff --git a/app/client/src/widgets/ChartWidget/widget/index.tsx b/app/client/src/widgets/ChartWidget/widget/index.tsx index db04a5f907dc..9b95ed665182 100644 --- a/app/client/src/widgets/ChartWidget/widget/index.tsx +++ b/app/client/src/widgets/ChartWidget/widget/index.tsx @@ -226,42 +226,50 @@ class ChartWidget extends BaseWidget { getWidgetView() { const errors = syntaxErrorsFromProps(this.props); - if (errors.length == 0) { - if (emptyChartData(this.props)) { - return ; - } else { - return ( - }> - - - ); - } - } else { + if (this.props.isLoading) { + return this.renderChartWithData(); + } + + if (errors.length > 0) { return ; } + + if (emptyChartData(this.props)) { + return ; + } + + return this.renderChartWithData(); + } + + renderChartWithData() { + return ( + }> + + + ); } }