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

feat(client):ask jovu and create with jovu buttons #8398

Merged
merged 3 commits into from
May 6, 2024
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
33 changes: 33 additions & 0 deletions packages/amplication-client/src/Assistant/AskJovuButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { EnumButtonStyle } from "@amplication/ui/design-system";
import "./JovuLogo.scss";
import { useAssistantContext } from "./context/AssistantContext";
import { Button } from "../Components/Button";
import { AnalyticsEventNames } from "../util/analytics-events.types";

const CLASS_NAME = "ask-jovu-button";

const AskJovuButton = () => {
const { setOpen, open } = useAssistantContext();

if (open) {
return null;
}

return (
<Button
className={CLASS_NAME}
buttonStyle={EnumButtonStyle.GradientFull}
icon="ai"
eventData={{
eventName: AnalyticsEventNames.AskJovuClick,
}}
onClick={() => {
setOpen(true);
}}
>
Ask Jovu (Beta)
</Button>
);
};

export default AskJovuButton;
27 changes: 14 additions & 13 deletions packages/amplication-client/src/Assistant/Assistant.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { BillingFeature } from "@amplication/util-billing-types";
import { useQuery } from "@apollo/client";
import { useStiggContext } from "@stigg/react-sdk";
import classNames from "classnames";
import { useEffect, useRef, useState } from "react";
import { useEffect, useRef } from "react";
import { Link } from "react-router-dom";
import { Button, EnumButtonStyle } from "../Components/Button";
import { GET_CONTACT_US_LINK } from "../Workspaces/queries/workspaceQueries";
Expand All @@ -25,7 +25,7 @@ import "./Assistant.scss";
import AssistantChatInput from "./AssistantChatInput";
import AssistantMessage from "./AssistantMessage";
import JovuLogo from "./JovuLogo";
import useAssistant from "./hooks/useAssistant";
import { useAssistantContext } from "./context/AssistantContext";

const DIRECTION = "sw";

Expand All @@ -36,7 +36,7 @@ const WIDTH_STATE_WIDE = "wide";

const WIDTH_STATE_SETTINGS: Record<
string,
{ icon: string; tooltip: string; nextState: string }
{ icon: string; tooltip: string; nextState: "default" | "wide" }
> = {
[WIDTH_STATE_DEFAULT]: {
icon: "chevrons_right",
Expand All @@ -53,6 +53,17 @@ const WIDTH_STATE_SETTINGS: Record<
const Assistant = () => {
const { currentWorkspace } = useAppContext();

const {
open,
setOpen,
widthState,
setWidthState,
sendMessage,
messages,
processingMessage: loading,
streamError,
} = useAssistantContext();

const { stigg } = useStiggContext();

const { hasAccess } = stigg.getMeteredEntitlement({
Expand All @@ -63,23 +74,13 @@ const Assistant = () => {
variables: { id: currentWorkspace.id },
});

const [open, setOpen] = useState(true);
const [widthState, setWidthState] = useState(WIDTH_STATE_DEFAULT);

const messagesEndRef = useRef<null | HTMLDivElement>(null);
const scrollToBottom = () => {
if (messagesEndRef.current) {
messagesEndRef.current.scrollIntoView({ behavior: "smooth" });
}
};

const {
sendMessage,
messages,
processingMessage: loading,
streamError,
} = useAssistant();

useEffect(() => {
scrollToBottom();
}, [messages]);
Expand Down
48 changes: 48 additions & 0 deletions packages/amplication-client/src/Assistant/CreateWithJovuButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { EnumButtonStyle } from "@amplication/ui/design-system";
import "./JovuLogo.scss";
import { useAssistantContext } from "./context/AssistantContext";
import { Button } from "../Components/Button";
import { AnalyticsEventNames } from "../util/analytics-events.types";
import { useCallback } from "react";

const CLASS_NAME = "ask-jovu-button";

type Props = {
message: string;
onClick: () => void;
disabled?: boolean;
eventOriginLocation: string;
};

const CreateWithJovuButton = ({
message,
onClick,
disabled,
eventOriginLocation,
}: Props) => {
const { setOpen, sendMessage, processingMessage } = useAssistantContext();

const handleClick = useCallback(() => {
sendMessage(message);
setOpen(true);
onClick && onClick();
}, [message, onClick, sendMessage, setOpen]);

return (
<Button
disabled={processingMessage || disabled}
className={CLASS_NAME}
buttonStyle={EnumButtonStyle.GradientFull}
icon="ai"
eventData={{
eventName: AnalyticsEventNames.AskJovuClick,
eventOriginLocation,
}}
onClick={handleClick}
>
Create with Jovu
</Button>
);
};

export default CreateWithJovuButton;
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import React, { useState } from "react";
import useAssistant, {
AssistantMessageWithOptions,
} from "../hooks/useAssistant";
import { ApolloError } from "@apollo/client";

export interface AssistantContextInterface {
open: boolean;
setOpen: (open: boolean) => void;
widthState: string;
setWidthState: (widthState: "default" | "wide") => void;
sendMessage: (message: string) => void;
messages: AssistantMessageWithOptions[];
streamError: ApolloError;
processingMessage: boolean;
}

const initialContext: AssistantContextInterface = {
open: false,
setOpen: () => {},
widthState: "default",
setWidthState: () => {},
sendMessage: () => {},
messages: [],
streamError: null,
processingMessage: false,
};

export const AssistantContext =
React.createContext<AssistantContextInterface>(initialContext);

export const AssistantContextProvider: React.FC<{
children: React.ReactNode;
}> = ({ children }) => {
const [open, setOpen] = useState<boolean>(false);
const [widthState, setWidthState] = useState<string>("default");

const { sendMessage, messages, streamError, processingMessage } =
useAssistant();

const contextValue = {
open,
setOpen,
widthState,
setWidthState,
sendMessage,
messages,
streamError,
processingMessage,
};

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

export const useAssistantContext = () => {
const context = React.useContext(AssistantContext);
if (context === undefined)
throw Error(
"useAssistantContext must be used within a AssistantContextProvider"
);

return context;
};
25 changes: 19 additions & 6 deletions packages/amplication-client/src/Entity/NewEntity.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
Text,
TextField,
EnumTextAlign,
EnumFlexDirection,
} from "@amplication/ui/design-system";
import { Reference, useMutation } from "@apollo/client";
import { Form, Formik } from "formik";
Expand All @@ -32,6 +33,7 @@ import { CROSS_OS_CTRL_ENTER } from "../util/hotkeys";
import "./NewEntity.scss";
import { USER_ENTITY } from "./constants";
import useModule from "../Modules/hooks/useModule";
import CreateWithJovuButton from "../Assistant/CreateWithJovuButton";

type CreateEntityType = Omit<models.EntityCreateInput, "resource">;

Expand Down Expand Up @@ -295,13 +297,24 @@ const NewEntity = ({ resourceId, onSuccess }: Props) => {
placeholder="Type New Entity Name"
autoComplete="off"
/>
<Button
type="submit"
buttonStyle={EnumButtonStyle.Primary}
disabled={!formik.isValid || loading}
<FlexItem
direction={EnumFlexDirection.Row}
margin={EnumFlexItemMargin.Top}
>
Create Entity
</Button>
<Button
type="submit"
buttonStyle={EnumButtonStyle.Primary}
disabled={!formik.isValid || loading}
>
Create Entity
</Button>
<CreateWithJovuButton
message={`Create a new entity ${formik.values.displayName}. Include common fields, and relations to other entities when needed.`}
onClick={handleDismissConfirmationInstall}
disabled={!formik.isValid || loading}
eventOriginLocation="New Entity Dialog"
/>
</FlexItem>
</Form>
);
}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,6 @@ const NewModuleAction = ({
[
createModuleAction,
resourceId,
moduleId,
mulygottlieb marked this conversation as resolved.
Show resolved Hide resolved
onActionCreated,
history,
currentWorkspace?.id,
Expand Down
2 changes: 1 addition & 1 deletion packages/amplication-client/src/Modules/NewModuleChild.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ const NewModuleChild = <T,>({
}, [findModulesData]);

const initialValueWithModuleId = useMemo(() => {
const firstModule = findModulesData?.modules[0].id;
const firstModule = findModulesData?.modules[0]?.id;

return {
...initialValues,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ const ResourceOverview = () => {
<BtmButton
openInFullScreen
location={EnumButtonLocation.Resource}
ButtonStyle={EnumButtonStyle.GradientFull}
ButtonStyle={EnumButtonStyle.GradientOutline}
/>
{currentResource?.resourceType === EnumResourceType.Service && (
<AddResourceFunctionalityButton
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ import UpgradeCtaButton from "./UpgradeCtaButton";
import WorkspaceBanner from "./WorkspaceBanner";
import "./WorkspaceHeader.scss";
import styles from "./notificationStyle";
import AskJovuButton from "../../Assistant/AskJovuButton";

const CLASS_NAME = "workspace-header";
const AMP_GITHUB_URL = "https://github.com/amplication/amplication";
Expand Down Expand Up @@ -220,6 +221,7 @@ const WorkspaceHeader: React.FC = () => {
<div className={`${CLASS_NAME}__center`}></div>
<div className={`${CLASS_NAME}__right`}>
<div className={`${CLASS_NAME}__links`}>
<AskJovuButton />
<UpgradeCtaButton />
</div>
<hr className={`${CLASS_NAME}__vertical_border`} />
Expand Down
Loading
Loading