Skip to content

Commit

Permalink
feat(frontend): interaction with brain items (#3106)
Browse files Browse the repository at this point in the history
# Description

Please include a summary of the changes and the related issue. Please
also include relevant motivation and context.

## Checklist before requesting a review

Please delete options that are not relevant.

- [ ] My code follows the style guidelines of this project
- [ ] I have performed a self-review of my code
- [ ] I have commented hard-to-understand areas
- [ ] I have ideally added tests that prove my fix is effective or that
my feature works
- [ ] New and existing unit tests pass locally with my changes
- [ ] Any dependent changes have been merged

## Screenshots (if appropriate):
  • Loading branch information
Zewed authored Aug 28, 2024
1 parent b968ed5 commit b7a081e
Show file tree
Hide file tree
Showing 16 changed files with 191 additions and 75 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,10 @@
}

.brain_snippet {
width: 18px;
height: 18px;
min-width: 18px;
min-height: 18px;
max-width: 18px;
max-height: 18px;
border-radius: Radius.$normal;
display: flex;
justify-content: center;
Expand Down
53 changes: 35 additions & 18 deletions frontend/app/search/BrainsList/BrainButton/BrainButton.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

.brain_button_container {
display: flex;
padding: Spacings.$spacing03;
padding: Spacings.$spacing04;
border: 1px solid var(--border-0);
border-radius: Radius.$normal;
cursor: pointer;
Expand All @@ -19,30 +19,47 @@
border-color: var(--primary-0);
}

&.not_hovered {
&:hover {
border-color: var(--border-0);
}
}

.header {
display: flex;
gap: Spacings.$spacing03;
gap: Spacings.$spacing05;
width: 100%;
align-items: center;
overflow: hidden;
justify-content: space-between;

.brain_image {
border-radius: Radius.$normal;
}

.name {
@include Typography.EllipsisOverflow;
font-size: Typography.$small;
font-weight: 500;
}

.brain_snippet {
width: 24px;
height: 24px;
border-radius: Radius.$normal;
.left {
display: flex;
justify-content: center;
gap: Spacings.$spacing03;
align-items: center;
font-size: Typography.$tiny;
overflow: hidden;

.brain_image {
border-radius: Radius.$normal;
}

.name {
@include Typography.EllipsisOverflow;
font-size: Typography.$small;
font-weight: 500;
}

.brain_snippet {
min-width: 24px;
min-height: 24px;
max-width: 24px;
max-height: 24px;
border-radius: Radius.$normal;
display: flex;
justify-content: center;
align-items: center;
font-size: Typography.$tiny;
}
}
}

Expand Down
56 changes: 40 additions & 16 deletions frontend/app/search/BrainsList/BrainButton/BrainButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

import { UUID } from "crypto";
import Image from "next/image";
import { useState } from "react";

import { Icon } from "@/lib/components/ui/Icon/Icon";
import { useBrainContext } from "@/lib/context/BrainProvider/hooks/useBrainContext";
import { BrainType } from "@/lib/types/BrainConfig";

Expand All @@ -28,36 +30,58 @@ const BrainButton = ({
brainOrModel,
newBrain,
}: BrainButtonProps): JSX.Element => {
const [optionsHovered, setOptionsHovered] = useState(false);
const { setCurrentBrainId } = useBrainContext();

return (
<div
className={styles.brain_button_container}
className={`${styles.brain_button_container} ${
optionsHovered ? styles.not_hovered : ""
}`}
onClick={() => {
setCurrentBrainId(brainOrModel.id);
newBrain();
}}
>
<div className={styles.header}>
{brainOrModel.image_url ? (
<Image
className={styles.brain_image}
src={brainOrModel.image_url}
alt="Brain or Model"
width={24}
height={24}
/>
) : (
<div className={styles.left}>
{brainOrModel.image_url ? (
<Image
className={styles.brain_image}
src={brainOrModel.image_url}
alt="Brain or Model"
width={24}
height={24}
/>
) : (
<div
className={styles.brain_snippet}
style={{ backgroundColor: brainOrModel.snippet_color }}
>
<span>{brainOrModel.snippet_emoji}</span>
</div>
)}
<span className={styles.name}>
{brainOrModel.display_name ?? brainOrModel.name}
</span>
</div>
{brainOrModel.brain_type === "doc" && (
<div
className={styles.brain_snippet}
style={{ backgroundColor: brainOrModel.snippet_color }}
onClick={(event) => {
event.stopPropagation();
window.location.href = `/studio/${brainOrModel.id}`;
}}
onMouseEnter={() => setOptionsHovered(true)}
onMouseLeave={() => setOptionsHovered(false)}
>
<span>{brainOrModel.snippet_emoji}</span>
<Icon
name="options"
size="small"
color="black"
handleHover={true}
/>
</div>
)}
<span className={styles.name}>
{brainOrModel.display_name ?? brainOrModel.name}
</span>
</div>
<span className={styles.description}>{brainOrModel.description}</span>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@

.brain_item_wrapper {
padding-inline: Spacings.$spacing05;
overflow: hidden;
display: flex;
flex-direction: column;
gap: Spacings.$spacing03;
Expand All @@ -18,7 +17,6 @@
padding-block: Spacings.$spacing04;
position: relative;
overflow: visible;
overflow: hidden;
height: 100%;
box-shadow: BoxShadow.$small;

Expand All @@ -27,6 +25,12 @@
color: var(--text-3);
}

&.not_hovered {
&:hover {
border-color: var(--border-1);
}
}

.brain_header {
display: flex;
justify-content: space-between;
Expand All @@ -43,8 +47,10 @@
overflow: hidden;

.brain_snippet {
width: 24px;
height: 24px;
min-width: 24px;
min-height: 24px;
max-width: 24px;
max-height: 24px;
border-radius: Radius.$normal;
display: flex;
justify-content: center;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { Icon } from "@/lib/components/ui/Icon/Icon";
import { OptionsModal } from "@/lib/components/ui/OptionsModal/OptionsModal";
import { useBrainContext } from "@/lib/context/BrainProvider/hooks/useBrainContext";
import { MinimalBrainForUser } from "@/lib/context/BrainProvider/types";
import { useSearchModalContext } from "@/lib/context/SearchModalProvider/hooks/useSearchModalContext";
import { useUserSettingsContext } from "@/lib/context/UserSettingsProvider/hooks/useUserSettingsContext";
import { Option } from "@/lib/types/Options";

Expand All @@ -20,20 +21,22 @@ type BrainItemProps = {

export const BrainItem = ({ brain, even }: BrainItemProps): JSX.Element => {
const [optionsOpened, setOptionsOpened] = useState<boolean>(false);
const [optionsHovered, setOptionsHovered] = useState<boolean>(false);

const {
handleUnsubscribeOrDeleteBrain,
isDeleteOrUnsubscribeModalOpened,
setIsDeleteOrUnsubscribeModalOpened,
isDeleteOrUnsubscribeRequestPending,
} = useBrainManagementTabs(brain.id);
const { allBrains } = useBrainContext();
const { allBrains, setCurrentBrainId } = useBrainContext();
const { isOwnedByCurrentUser } = getBrainPermissions({
brainId: brain.id,
userAccessibleBrains: allBrains,
});
const { brain: fetchedBrain } = useBrainFetcher({ brainId: brain.id });
const { isDarkMode } = useUserSettingsContext();
const { setIsVisible } = useSearchModalContext();

const iconRef = useRef<HTMLDivElement | null>(null);
const optionsRef = useRef<HTMLDivElement | null>(null);
Expand All @@ -45,6 +48,16 @@ export const BrainItem = ({ brain, even }: BrainItemProps): JSX.Element => {
iconName: "edit",
iconColor: "primary",
},
{
label: "Talk to Brain",
onClick: () => {
setOptionsOpened(false);
setIsVisible(true);
setTimeout(() => setCurrentBrainId(brain.id));
},
iconName: "chat",
iconColor: "primary",
},
{
label: "Delete",
onClick: () => void setIsDeleteOrUnsubscribeModalOpened(true),
Expand Down Expand Up @@ -76,7 +89,7 @@ export const BrainItem = ({ brain, even }: BrainItemProps): JSX.Element => {
<a
className={`
${even ? styles.even : styles.odd}
${styles.brain_item_wrapper}
${styles.brain_item_wrapper} ${optionsHovered ? styles.not_hovered : ""}
`}
href={`/studio/${brain.id}`}
>
Expand All @@ -100,12 +113,17 @@ export const BrainItem = ({ brain, even }: BrainItemProps): JSX.Element => {
}}
className={styles.icon}
>
<Icon
name="options"
size="small"
color="black"
handleHover={true}
/>
<div
onMouseEnter={() => setOptionsHovered(true)}
onMouseLeave={() => setOptionsHovered(false)}
>
<Icon
name="options"
size="small"
color="black"
handleHover={true}
/>
</div>
</div>
</div>
<div className={styles.model}>
Expand All @@ -127,7 +145,12 @@ export const BrainItem = ({ brain, even }: BrainItemProps): JSX.Element => {
}
/>
</div>
<div ref={optionsRef} className={styles.options_modal}>
<div
ref={optionsRef}
className={styles.options_modal}
onMouseEnter={() => setOptionsHovered(true)}
onMouseLeave={() => setOptionsHovered(false)}
>
{optionsOpened && <OptionsModal options={options} />}
</div>
</a>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,12 @@
width: 100%;
gap: Spacings.$spacing05;
padding-block: Spacings.$spacing05;

.message {
display: inline-flex;
flex-wrap: wrap;
align-items: center;
gap: Spacings.$spacing03;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,16 @@ export const KnowledgeTab = ({
<div className={styles.knowledge_tab_container}>
<div className={styles.knowledge_tab_wrapper}>
<MessageInfoBox type="warning">
This brain is empty! You can add knowledge by clicking on
<QuivrButton
label="Add knowledge"
color="primary"
iconName="add"
onClick={() => setShouldDisplayFeedCard(true)}
/>
.
<div className={styles.message}>
This brain is empty! You can add knowledge by clicking on
<QuivrButton
label="Add knowledge"
color="primary"
iconName="add"
onClick={() => setShouldDisplayFeedCard(true)}
/>
.
</div>
</MessageInfoBox>
</div>
</div>
Expand Down
13 changes: 13 additions & 0 deletions frontend/app/studio/[brainId]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { PageHeader } from "@/lib/components/PageHeader/PageHeader";
import { UploadDocumentModal } from "@/lib/components/UploadDocumentModal/UploadDocumentModal";
import { useBrainContext } from "@/lib/context/BrainProvider/hooks/useBrainContext";
import { useKnowledgeToFeedContext } from "@/lib/context/KnowledgeToFeedProvider/hooks/useKnowledgeToFeedContext";
import { useSearchModalContext } from "@/lib/context/SearchModalProvider/hooks/useSearchModalContext";
import { ButtonType } from "@/lib/types/QuivrButton";

import { BrainManagementTabs } from "./BrainManagementTabs/BrainManagementTabs";
Expand All @@ -17,6 +18,7 @@ import styles from "./page.module.scss";

const BrainsManagement = (): JSX.Element => {
const { brain } = useBrainManagement();
const { setIsVisible } = useSearchModalContext();
const {
handleUnsubscribeOrDeleteBrain,
isDeleteOrUnsubscribeModalOpened,
Expand All @@ -32,6 +34,17 @@ const BrainsManagement = (): JSX.Element => {
const { setCurrentBrainId } = useBrainContext();

const buttons: ButtonType[] = [
{
label: "Talk to Brain",
color: "primary",
onClick: () => {
if (brain) {
setIsVisible(true);
setTimeout(() => setCurrentBrainId(brain.id));
}
},
iconName: "chat",
},
{
label: "Add knowledge",
color: "primary",
Expand Down
6 changes: 4 additions & 2 deletions frontend/lib/components/CurrentBrain/CurrentBrain.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,10 @@
}

.brain_snippet {
width: 18px;
height: 18px;
min-width: 18px;
min-height: 18px;
max-width: 18px;
max-height: 18px;
border-radius: Radius.$normal;
display: flex;
justify-content: center;
Expand Down
Loading

0 comments on commit b7a081e

Please sign in to comment.