mirror of
https://github.com/QuivrHQ/quivr.git
synced 2024-12-15 01:21:48 +03:00
Shareable Brains - 2 (#601)
* feat(brains): add fetching indicator * feat: add brain share modal
This commit is contained in:
parent
22ea64e67c
commit
8749ffd0bd
@ -1,17 +1,17 @@
|
||||
import { useState } from "react";
|
||||
import { FaBrain } from "react-icons/fa";
|
||||
import { MdCheck, MdDelete } from "react-icons/md";
|
||||
import { MdCheck } from "react-icons/md";
|
||||
|
||||
import Button from "@/lib/components/ui/Button";
|
||||
import Field from "@/lib/components/ui/Field";
|
||||
import Popover from "@/lib/components/ui/Popover";
|
||||
import { useBrainContext } from "@/lib/context/BrainProvider/hooks/useBrainContext";
|
||||
|
||||
import { AddBrainModal } from "./AddBrainModal";
|
||||
import { AddBrainModal } from "./components/AddBrainModal";
|
||||
import { BrainActions } from "./components/BrainActions/BrainActions";
|
||||
|
||||
export const BrainsDropDown = (): JSX.Element => {
|
||||
const [searchQuery, setSearchQuery] = useState("");
|
||||
const { allBrains, setActiveBrain, currentBrain, deleteBrain } =
|
||||
const { allBrains, isFetchingBrains, setActiveBrain, currentBrain } =
|
||||
useBrainContext();
|
||||
|
||||
return (
|
||||
@ -41,6 +41,11 @@ export const BrainsDropDown = (): JSX.Element => {
|
||||
/>
|
||||
<div className="overflow-auto scrollbar flex flex-col h-48 mt-5">
|
||||
{/* List of brains */}
|
||||
{isFetchingBrains && (
|
||||
<div className="flex items-center justify-center h-full">
|
||||
<p className="text-gray-500">Loading...</p>
|
||||
</div>
|
||||
)}
|
||||
{allBrains.map((brain) => {
|
||||
if (brain.name.includes(searchQuery)) {
|
||||
return (
|
||||
@ -68,13 +73,7 @@ export const BrainsDropDown = (): JSX.Element => {
|
||||
</span>
|
||||
<span className="flex-1">{brain.name}</span>
|
||||
</button>
|
||||
<Button
|
||||
className="group-hover:visible invisible absolute right-0 hover:text-red-500 transition-[colors,opacity]"
|
||||
onClick={() => void deleteBrain(brain.id)}
|
||||
variant={"tertiary"}
|
||||
>
|
||||
<MdDelete className="text-xl" />
|
||||
</Button>
|
||||
<BrainActions brainId={brain.id} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ import Field from "@/lib/components/ui/Field";
|
||||
import Modal from "@/lib/components/ui/Modal";
|
||||
import { useBrainContext } from "@/lib/context/BrainProvider/hooks/useBrainContext";
|
||||
|
||||
const AddBrainModal = (): JSX.Element => {
|
||||
export const AddBrainModal = (): JSX.Element => {
|
||||
const [newBrainName, setNewBrainName] = useState("");
|
||||
const [isPending, setIsPending] = useState(false);
|
||||
|
||||
@ -56,5 +56,3 @@ const AddBrainModal = (): JSX.Element => {
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
export { AddBrainModal };
|
@ -0,0 +1,28 @@
|
||||
import { UUID } from "crypto";
|
||||
import { MdDelete } from "react-icons/md";
|
||||
|
||||
import Button from "@/lib/components/ui/Button";
|
||||
import { useBrainContext } from "@/lib/context/BrainProvider/hooks/useBrainContext";
|
||||
|
||||
import { ShareBrain } from "./ShareBrain";
|
||||
|
||||
type BrainActionsProps = {
|
||||
brainId: UUID;
|
||||
};
|
||||
|
||||
export const BrainActions = ({ brainId }: BrainActionsProps): JSX.Element => {
|
||||
const { deleteBrain } = useBrainContext();
|
||||
|
||||
return (
|
||||
<div className="absolute right-0 flex flex-row">
|
||||
<ShareBrain brainId={brainId} />
|
||||
<Button
|
||||
className="group-hover:visible invisible hover:text-red-500 transition-[colors,opacity] p-1"
|
||||
onClick={() => void deleteBrain(brainId)}
|
||||
variant={"tertiary"}
|
||||
>
|
||||
<MdDelete className="text-xl" />
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
};
|
@ -0,0 +1,47 @@
|
||||
import { UUID } from "crypto";
|
||||
import { MdContentPaste, MdShare } from "react-icons/md";
|
||||
|
||||
import Button from "@/lib/components/ui/Button";
|
||||
import Modal from "@/lib/components/ui/Modal";
|
||||
import { useToast } from "@/lib/hooks";
|
||||
|
||||
type ShareBrainModalProps = {
|
||||
brainId: UUID;
|
||||
};
|
||||
|
||||
export const ShareBrain = ({ brainId }: ShareBrainModalProps): JSX.Element => {
|
||||
const { publish } = useToast();
|
||||
|
||||
const baseUrl = window.location.origin;
|
||||
const brainShareLink = `${baseUrl}/brain_subscription_invitation=${brainId}`;
|
||||
|
||||
const handleCopyInvitationLink = async () => {
|
||||
await navigator.clipboard.writeText(brainShareLink);
|
||||
publish({
|
||||
variant: "success",
|
||||
text: "Copied to clipboard",
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<Modal
|
||||
Trigger={
|
||||
<Button
|
||||
className="group-hover:visible invisible hover:text-red-500 transition-[colors,opacity] p-1"
|
||||
onClick={() => void 0}
|
||||
variant={"tertiary"}
|
||||
>
|
||||
<MdShare className="text-xl" />
|
||||
</Button>
|
||||
}
|
||||
title="Share brain"
|
||||
>
|
||||
<div className="flex flex-row align-center my-5">
|
||||
<p>{brainShareLink}</p>
|
||||
<Button onClick={() => void handleCopyInvitationLink()}>
|
||||
<MdContentPaste />
|
||||
</Button>
|
||||
</div>
|
||||
</Modal>
|
||||
);
|
||||
};
|
@ -0,0 +1 @@
|
||||
export * from "./BrainActions";
|
@ -0,0 +1,2 @@
|
||||
export * from "./AddBrainModal";
|
||||
export * from "./BrainActions";
|
@ -1,4 +1 @@
|
||||
import { AddBrainModal } from "./AddBrainModal";
|
||||
import { BrainsDropDown } from "./BrainsDropDown";
|
||||
|
||||
export { BrainsDropDown, AddBrainModal };
|
||||
export * from "./BrainsDropDown";
|
||||
|
@ -12,6 +12,7 @@ interface ModalProps {
|
||||
children?: ReactNode;
|
||||
Trigger: ReactNode;
|
||||
CloseTrigger?: ReactNode;
|
||||
opened?: boolean;
|
||||
}
|
||||
|
||||
const Modal = ({
|
||||
@ -20,8 +21,9 @@ const Modal = ({
|
||||
children,
|
||||
Trigger,
|
||||
CloseTrigger,
|
||||
opened = false,
|
||||
}: ModalProps): JSX.Element => {
|
||||
const [open, setOpen] = useState(false);
|
||||
const [open, setOpen] = useState(opened);
|
||||
|
||||
return (
|
||||
<Dialog.Root onOpenChange={setOpen}>
|
||||
|
@ -103,6 +103,5 @@ export const useBrainProvider = () => {
|
||||
setDefaultBrain,
|
||||
fetchAndSetActiveBrain,
|
||||
isFetchingBrains,
|
||||
setIsFetchingBrains,
|
||||
};
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user