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: add new actions modal #1870

Merged
merged 7 commits into from
Dec 13, 2023
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
@@ -0,0 +1,42 @@
import { PopoverAnchor } from "@radix-ui/react-popover";
import { useState } from "react";
import { LuPlusCircle, LuXCircle } from "react-icons/lu";

import Button from "@/lib/components/ui/Button";
import {
Popover,
PopoverContent,
PopoverTrigger,
} from "@/lib/components/ui/Popover";

import { ConfigModal } from "./components/ConfigModal";

export const ActionsModal = (): JSX.Element => {
const [isActionsModalOpened, setIsActionsModalOpened] = useState(false);

const Icon = isActionsModalOpened ? LuXCircle : LuPlusCircle;

return (
<div className="flex items-center">
<Popover
open={isActionsModalOpened}
onOpenChange={(isOpened) => setIsActionsModalOpened(isOpened)}
>
<PopoverTrigger>
<PopoverAnchor asChild>
<Button variant="tertiary" type="button" className="p-0">
<Icon className="text-accent font-bold" size={30} />
</Button>
</PopoverAnchor>
</PopoverTrigger>
<PopoverContent
align="end"
sideOffset={15}
className="min-h-[200px] w-[200px]"
>
<ConfigModal />
</PopoverContent>
</Popover>
</div>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { forwardRef } from "react";

import CoreButton, {
ButtonProps as CoreButtonProps,
} from "@/lib/components/ui/Button";
import { cn } from "@/lib/utils";

type ButtonProps = CoreButtonProps & {
onClick?: () => void;
className?: string;
label?: string;
startIcon?: JSX.Element;
endIcon?: JSX.Element;
};

export const Button = forwardRef(
(
{ onClick, className, label, startIcon, endIcon, ...props }: ButtonProps,
forwardedRef
): JSX.Element => {
return (
<CoreButton
className={cn("p-2 sm:px-3 text-primary focus:ring-0 ", className)}
variant={"tertiary"}
data-testid="config-button"
ref={forwardedRef}
onClick={onClick}
{...props}
>
<div className="flex flex-row justify-between w-full items-center">
<div className="flex flex-row gap-2 items-center">
{startIcon}
<span className="hidden sm:block">{label}</span>
</div>
{endIcon}
</div>
</CoreButton>
);
}
);

Button.displayName = CoreButton.displayName;
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
/* eslint-disable max-lines */
import { useTranslation } from "react-i18next";
import { MdCheck, MdSettings } from "react-icons/md";
import { LuChevronRight, LuSettings } from "react-icons/lu";
import { MdCheck } from "react-icons/md";

import Button from "@/lib/components/ui/Button";
import { Modal } from "@/lib/components/ui/Modal";
import { defineMaxTokens } from "@/lib/helpers/defineMaxTokens";

import { useConfigModal } from "./hooks/useConfigModal";
import { Button } from "../Button";

export const ConfigModal = (): JSX.Element => {
const {
Expand All @@ -24,12 +24,11 @@ export const ConfigModal = (): JSX.Element => {
<Modal
Trigger={
<Button
className="p-2 sm:px-3"
variant={"tertiary"}
data-testid="config-button"
>
<MdSettings className="text-lg sm:text-xl lg:text-2xl" />
</Button>
label={"Parametres"}
startIcon={<LuSettings size={18} />}
endIcon={<LuChevronRight size={18} />}
className="w-full"
/>
}
title="Chat configuration"
desc="Adjust your chat settings"
Expand Down Expand Up @@ -68,16 +67,16 @@ export const ConfigModal = (): JSX.Element => {
</fieldset>

<Button
className="mt-12 self-end"
className="mt-12 self-end text-white"
type="button"
onClick={() => {
handleSubmit();
setIsConfigModalOpen(false);
}}
>
Save
<MdCheck className="text-xl" />
</Button>
variant={"primary"}
label="Save"
endIcon={<MdCheck className="text-xl" />}
/>
</form>
</Modal>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
export * from "./ConfigModal";
export * from "./OnboardingQuestions";
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import { useKnowledgeToFeedContext } from "@/lib/context/KnowledgeToFeedProvider
import { getBrainIconFromBrainType } from "@/lib/helpers/getBrainIconFromBrainType";

import { OnboardingQuestions } from "./components";
import { ActionsModal } from "./components/ActionsModal/ActionsModal";
import { ChatEditor } from "./components/ChatEditor/ChatEditor";
import { ConfigModal } from "./components/ConfigModal";
import { useChatInput } from "./hooks/useChatInput";

type ChatInputProps = {
Expand Down Expand Up @@ -58,9 +58,9 @@ export const ChatInput = ({
/>
</div>

<div className="flex flex-row items-end">
<div className="flex flex-row items-center gap-4">
<Button
className="px-3 py-2 sm:px-4 sm:py-2"
className="px-3 py-2 sm:px-4 sm:py-2 bg-primary border-0"
type="submit"
isLoading={generatingAnswer}
data-testid="submit-button"
Expand All @@ -69,9 +69,7 @@ export const ChatInput = ({
? t("thinking", { ns: "chat" })
: t("chat", { ns: "chat" })}
</Button>
<div className="hidden md:flex items-center">
<ConfigModal />
</div>
<ActionsModal />
</div>
</form>
</div>
Expand Down
4 changes: 2 additions & 2 deletions frontend/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { createServerComponentSupabaseClient } from "@supabase/auth-helpers-nextjs";
import { Analytics as VercelAnalytics } from "@vercel/analytics/react";
import { Inter } from "next/font/google";
import { Outfit } from "next/font/google";
import { cookies, headers } from "next/headers";

import { ToastProvider } from "@/lib/components/ui/Toast";
Expand All @@ -10,7 +10,7 @@ import { SupabaseProvider } from "@/lib/context/SupabaseProvider";
import { App } from "./App";
import "./globals.css";

const inter = Inter({ subsets: ["latin"] });
const inter = Outfit({ subsets: ["latin"], weight: "400" });

export const metadata = {
title: "Quivr - Get a Second Brain with Generative AI",
Expand Down
59 changes: 0 additions & 59 deletions frontend/app/user/components/LanguageDropDown/LanguageDropDown.tsx

This file was deleted.

1 change: 0 additions & 1 deletion frontend/app/user/components/LanguageDropDown/index.ts

This file was deleted.

2 changes: 1 addition & 1 deletion frontend/app/user/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { redirectToLogin } from "@/lib/router/redirectToLogin";

import { StripePricingOrManageButton, UserStatistics } from "./components";
import { ApiKeyConfig } from "./components/ApiKeyConfig";
import LanguageSelect from "./components/LanguageDropDown/LanguageSelect";
import LanguageSelect from "./components/LanguageSelect/LanguageSelect";
import { LogoutModal } from "./components/LogoutCard/LogoutModal";
import ThemeSelect from "./components/ThemeSelect/ThemeSelect";

Expand Down
2 changes: 2 additions & 0 deletions frontend/lib/components/UserToInvite.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ export const UserToInvite = ({
onChange={setSelectedRole}
value={selectedRole}
options={translatedOptions}
popoverSide="bottom"
popoverClassName="w-36"
/>
</div>
);
Expand Down
1 change: 0 additions & 1 deletion frontend/lib/components/ui/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ const Button = forwardRef(
{children} {isLoading && <FaSpinner className="animate-spin" />}
</>
);
const buttonElement = <button {...buttonProps}>buttonChildren</button>;

if (tooltip !== undefined) {
return (
Expand Down
88 changes: 23 additions & 65 deletions frontend/lib/components/ui/Popover.tsx
Original file line number Diff line number Diff line change
@@ -1,71 +1,29 @@
"use client";
import * as PopoverPrimitive from "@radix-ui/react-popover";
import { AnimatePresence, motion } from "framer-motion";
import { ReactNode, useState } from "react";
import * as React from "react";

import Button from "./Button";
import { cn } from "@/lib/utils";

interface PopoverProps {
children?: ReactNode;
Trigger: ReactNode;
ActionTrigger?: ReactNode;
CloseTrigger?: ReactNode;
}
const Popover = PopoverPrimitive.Root;

const Popover = ({
children,
Trigger,
ActionTrigger,
CloseTrigger,
}: PopoverProps): JSX.Element => {
const [open, setOpen] = useState(false);
const PopoverTrigger = PopoverPrimitive.Trigger;

return (
<PopoverPrimitive.Root open={open} onOpenChange={setOpen}>
<PopoverPrimitive.Trigger asChild>{Trigger}</PopoverPrimitive.Trigger>
<AnimatePresence>
{open && (
<PopoverPrimitive.Portal forceMount>
<PopoverPrimitive.Content forceMount asChild sideOffset={5}>
<motion.div
initial={{ opacity: 0, y: -32 }}
animate={{
opacity: 1,
y: 0,
}}
exit={{ opacity: 0, y: -32 }}
transition={{ duration: 0.2, ease: "easeInOut" }}
className="relative flex flex-col p-4 bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-700 rounded-lg shadow-lg z-50 md:z-40"
>
<div className="flex-1">{children}</div>
<div className="mt-4 self-end flex gap-4">
{ActionTrigger !== undefined && (
<PopoverPrimitive.Close asChild>
{ActionTrigger}
</PopoverPrimitive.Close>
)}
<PopoverPrimitive.Close asChild>
{CloseTrigger === undefined ? (
<Button
variant={"secondary"}
className="px-3 py-2"
aria-label="Close"
>
Close
</Button>
) : (
CloseTrigger
)}
</PopoverPrimitive.Close>
</div>
<PopoverPrimitive.Arrow className="fill-white stroke-gray-300 stroke-2" />
</motion.div>
</PopoverPrimitive.Content>
</PopoverPrimitive.Portal>
)}
</AnimatePresence>
</PopoverPrimitive.Root>
);
};
const PopoverContent = React.forwardRef<
React.ElementRef<typeof PopoverPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Content>
>(({ className, align = "center", sideOffset = 4, ...props }, ref) => (
<PopoverPrimitive.Portal>
<PopoverPrimitive.Content
ref={ref}
align={align}
sideOffset={sideOffset}
className={cn(
"z-50 w-72 rounded-md border bg-white p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
className
)}
{...props}
/>
</PopoverPrimitive.Portal>
));
PopoverContent.displayName = PopoverPrimitive.Content.displayName;

export default Popover;
export { Popover, PopoverContent, PopoverTrigger };
Loading