Skip to content

Commit

Permalink
Adding a function to get assistants' author on popover opening (#8972)
Browse files Browse the repository at this point in the history
* Adding a function to get assistants' author on popover opening for feedback

* Make getLastAuthor not mandatory

* Add getPopoverInfo to the FeedbackSelector component

* Rename feedbackselector

* Feedbackselector rename bis

* Cleaner spinner

* Stories change

* Bump version
  • Loading branch information
albandum authored Dec 2, 2024
1 parent 5c5d539 commit fb32c4b
Show file tree
Hide file tree
Showing 6 changed files with 162 additions and 129 deletions.
4 changes: 2 additions & 2 deletions sparkle/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion sparkle/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@dust-tt/sparkle",
"version": "0.2.329",
"version": "0.2.330",
"scripts": {
"build": "rm -rf dist && npm run tailwind && npm run build:esm && npm run build:cjs",
"tailwind": "tailwindcss -i ./src/styles/tailwind.css -o dist/sparkle.css",
Expand Down
121 changes: 0 additions & 121 deletions sparkle/src/components/ConversationMessageFeedbackSelector.tsx

This file was deleted.

153 changes: 153 additions & 0 deletions sparkle/src/components/FeedbackSelector.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
import React, { useEffect, useRef } from "react";

import { Button } from "@sparkle/components/Button";
import { Page } from "@sparkle/components/Page";
import {
PopoverContent,
PopoverRoot,
PopoverTrigger,
} from "@sparkle/components/Popover";
import Spinner from "@sparkle/components/Spinner";
import { TextArea } from "@sparkle/components/TextArea";
import { Tooltip } from "@sparkle/components/Tooltip";
import { HandThumbDownIcon, HandThumbUpIcon } from "@sparkle/icons/solid";

export type FeedbackAssistantBuilder = {
name: string;
pictureUrl: string;
};
export type ThumbReaction = "up" | "down";
export type FeedbackType = {
thumb: ThumbReaction;
feedbackContent: string | null;
};
export interface FeedbackSelectorProps {
feedback: FeedbackType | null;
onSubmitThumb: (
p: FeedbackType & {
isToRemove: boolean;
}
) => Promise<void>;
isSubmittingThumb: boolean;
getPopoverInfo?: () => JSX.Element | null;
}

export function FeedbackSelector({
feedback,
onSubmitThumb,
isSubmittingThumb,
getPopoverInfo,
}: FeedbackSelectorProps) {
const [isPopoverOpen, setIsPopoverOpen] = React.useState(false);
const containerRef = useRef<HTMLDivElement>(null);
const [localFeedbackContent, setLocalFeedbackContent] = React.useState<
string | null
>(null);
const [popOverInfo, setPopoverInfo] = React.useState<JSX.Element | null>(
null
);

// Reset local feedback content when popup opens
useEffect(() => {
if (isPopoverOpen) {
if (getPopoverInfo) {
setPopoverInfo(getPopoverInfo());
}
setLocalFeedbackContent(feedback?.feedbackContent ?? null);
}
}, [isPopoverOpen, feedback?.feedbackContent]);

const selectThumb = async (thumb: ThumbReaction) => {
const isToRemove = feedback?.thumb === thumb;
setIsPopoverOpen(!isToRemove);

await onSubmitThumb({
feedbackContent: localFeedbackContent,
thumb,
isToRemove,
});
};

return (
<div ref={containerRef} className="s-flex s-items-center">
<PopoverRoot open={isPopoverOpen}>
<PopoverTrigger asChild>
<div className="s-flex s-items-center">
<Tooltip
label="I found this helpful"
trigger={
<Button
variant={feedback?.thumb === "up" ? "highlight" : "outline"}
size="xs"
disabled={isSubmittingThumb}
onClick={() => selectThumb("up")}
className={"s-rounded-r-none s-border-r-0"}
icon={HandThumbUpIcon}
/>
}
/>
<Tooltip
label="Report an issue with this answer"
trigger={
<Button
variant={feedback?.thumb === "down" ? "highlight" : "outline"}
size="xs"
disabled={isSubmittingThumb}
onClick={() => selectThumb("down")}
className={"s-rounded-l-none s-border-l-0"}
icon={HandThumbDownIcon}
/>
}
/>
</div>
</PopoverTrigger>
<PopoverContent fullWidth={true}>
{isSubmittingThumb ? (
<div className="m-3 s-flex s-items-center s-justify-center">
<Spinner size="sm" />
</div>
) : (
<div className="s-w-80 s-p-4">
<Page.H variant="h6">
{feedback?.thumb === "up"
? "🎉 Glad you liked it! Tell us more?"
: "🫠 Help make the answers better!"}
</Page.H>
{popOverInfo}
<TextArea
placeholder={
feedback?.thumb === "up"
? "What did you like?"
: "Tell us what went wrong so we can make this assistant better."
}
className="s-mt-4"
rows={3}
value={localFeedbackContent ?? ""}
onChange={(e) => setLocalFeedbackContent(e.target.value)}
/>
<div className="s-mt-4 s-flex s-justify-between s-gap-2">
<Button
variant="primary"
label="Submit feedback"
onClick={async () => {
await onSubmitThumb({
thumb: feedback?.thumb ?? "up",
isToRemove: false,
feedbackContent: localFeedbackContent,
});
setIsPopoverOpen(false);
}}
/>
<Button
variant="ghost"
label="Skip"
onClick={() => setIsPopoverOpen(false)}
/>
</div>
</div>
)}
</PopoverContent>
</PopoverRoot>
</div>
);
}
4 changes: 2 additions & 2 deletions sparkle/src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@ export { ContextItem } from "./ContextItem";
export type { ConversationMessageSizeType } from "./ConversationMessage";
export { ConversationMessage } from "./ConversationMessage";
export { ConversationMessageContent } from "./ConversationMessageContent";
export type { ConversationMessageFeedbackSelectorProps } from "./ConversationMessageFeedbackSelector";
export { FeedbackSelector } from "./ConversationMessageFeedbackSelector";
export { ConversationMessageHeader } from "./ConversationMessageHeader";
export { DataTable } from "./DataTable";
export { Dialog } from "./Dialog";
Expand Down Expand Up @@ -56,6 +54,8 @@ export { ElementModal } from "./ElementModal";
export type { EmojiMartData } from "./EmojiPicker";
export { DataEmojiMart, EmojiPicker } from "./EmojiPicker";
export { EmptyCTA, EmptyCTAButton } from "./EmptyCTA";
export type { FeedbackSelectorProps } from "./FeedbackSelector";
export { FeedbackSelector } from "./FeedbackSelector";
export { FilterChips } from "./FilterChips";
export { Div3D, Hover3D } from "./Hover3D";
export { Hoverable } from "./Hoverable";
Expand Down
7 changes: 4 additions & 3 deletions sparkle/src/stories/FeedbackSelector.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import type { Meta, StoryObj } from "@storybook/react";
import React from "react";

import {
ConversationMessageFeedbackSelectorProps,
FeedbackSelector,
} from "@sparkle/components/ConversationMessageFeedbackSelector";
FeedbackSelectorProps,
} from "@sparkle/components/FeedbackSelector";

const meta = {
title: "Primitives/FeedbackSelector",
Expand Down Expand Up @@ -35,7 +35,7 @@ type Story = StoryObj<typeof meta>;
// Wrap the story in a component that can use hooks
const ExampleFeedbackComponent = () => {
const [messageFeedback, setMessageFeedback] =
React.useState<ConversationMessageFeedbackSelectorProps>({
React.useState<FeedbackSelectorProps>({
feedback: {
thumb: "up",
feedbackContent: null,
Expand All @@ -50,6 +50,7 @@ const ExampleFeedbackComponent = () => {
}));
},
isSubmittingThumb: false,
getPopoverInfo: () => <div>Some info here, like the last author</div>,
});

return <FeedbackSelector {...messageFeedback} />;
Expand Down

0 comments on commit fb32c4b

Please sign in to comment.