From ff7393e441c6202a827ff0589839528d82245d58 Mon Sep 17 00:00:00 2001 From: Antoine Dewez <44063631+Zewed@users.noreply.github.com> Date: Wed, 14 Feb 2024 20:08:58 -0800 Subject: [PATCH] feat(frontend): new design for brain table (#2193) # 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): --- .../BrainItem/BrainItem.module.scss | 38 ++++++++- .../components/BrainItem/BrainItem.tsx | 84 +++++++++++++++---- .../BrainsList/BrainsList.module.scss | 4 +- frontend/lib/helpers/iconList.ts | 2 + 4 files changed, 106 insertions(+), 22 deletions(-) diff --git a/frontend/app/studio/components/BrainsTabs/components/BrainItem/BrainItem.module.scss b/frontend/app/studio/components/BrainsTabs/components/BrainItem/BrainItem.module.scss index 4246a0956..7d407a59c 100644 --- a/frontend/app/studio/components/BrainsTabs/components/BrainItem/BrainItem.module.scss +++ b/frontend/app/studio/components/BrainsTabs/components/BrainItem/BrainItem.module.scss @@ -1,20 +1,25 @@ @use "@/styles/Colors.module.scss"; +@use "@/styles/Radius.module.scss"; @use "@/styles/ScreenSizes.module.scss"; @use "@/styles/Spacings.module.scss"; @use "@/styles/Typography.module.scss"; .brain_item_wrapper { padding-inline: Spacings.$spacing05; - border-top: 1px solid Colors.$primary-lightest; overflow: hidden; display: flex; gap: Spacings.$spacing02; justify-content: space-between; align-items: center; cursor: pointer; + margin-block: Spacings.$spacing03; + border: 1px solid Colors.$lightest-black; + border-radius: Radius.$normal; + padding-block: Spacings.$spacing03; &:hover { - background-color: Colors.$lightest-black; + border-color: Colors.$primary; + background-color: Colors.$primary-lightest; } .brain_info_wrapper { @@ -28,6 +33,7 @@ .name { @include Typography.EllipsisOverflow; width: 200px; + color: Colors.$black; } .description { @@ -46,4 +52,32 @@ } } } + + .options_menu { + position: absolute; + background-color: Colors.$highlight; + border-radius: Radius.$normal; + right: Spacings.$spacing07; + border-radius: Radius.$normal; + box-shadow: 0 1px 2px rgb(0, 0, 0, 0.25); + + .option { + padding: Spacings.$spacing03; + padding-inline: Spacings.$spacing05; + display: flex; + gap: Spacings.$spacing05; + align-items: center; + cursor: pointer; + justify-content: space-between; + overflow: hidden; + + &:not(:first-child) { + border-top: 1px solid Colors.$light-grey; + } + + &:hover { + background-color: Colors.$primary-lightest; + } + } + } } diff --git a/frontend/app/studio/components/BrainsTabs/components/BrainItem/BrainItem.tsx b/frontend/app/studio/components/BrainsTabs/components/BrainItem/BrainItem.tsx index f5b5685b8..23937edae 100644 --- a/frontend/app/studio/components/BrainsTabs/components/BrainItem/BrainItem.tsx +++ b/frontend/app/studio/components/BrainsTabs/components/BrainItem/BrainItem.tsx @@ -1,5 +1,5 @@ import Link from "next/link"; -import { useState } from "react"; +import { useEffect, useRef, useState } from "react"; import { DeleteOrUnsubscribeConfirmationModal } from "@/app/studio/[brainId]/components/BrainManagementTabs/components/Modals/DeleteOrUnsubscribeConfirmationModal"; import { useBrainManagementTabs } from "@/app/studio/[brainId]/components/BrainManagementTabs/hooks/useBrainManagementTabs"; @@ -16,13 +16,15 @@ type BrainItemProps = { }; export const BrainItem = ({ brain, even }: BrainItemProps): JSX.Element => { + const [optionsOpened, setOptionsOpened] = useState(false); + const [deleteHovered, setDeleteHovered] = useState(false); + const [editHovered, setEditHovered] = useState(false); const { handleUnsubscribeOrDeleteBrain, isDeleteOrUnsubscribeModalOpened, setIsDeleteOrUnsubscribeModalOpened, isDeleteOrUnsubscribeRequestPending, } = useBrainManagementTabs(brain.id); - const [isHovered, setIsHovered] = useState(false); const { allBrains } = useBrainContext(); @@ -31,33 +33,79 @@ export const BrainItem = ({ brain, even }: BrainItemProps): JSX.Element => { userAccessibleBrains: allBrains, }); + const optionsRef = useRef(null); + + useEffect(() => { + const handleClickOutside = (event: MouseEvent) => { + if ( + optionsRef.current && + !optionsRef.current.contains(event.target as Node) + ) { + setOptionsOpened(false); + } + }; + + document.addEventListener("mousedown", handleClickOutside); + + return () => { + document.removeEventListener("mousedown", handleClickOutside); + }; + }, []); + return (
setIsHovered(true)} - onMouseLeave={() => setIsHovered(false)} > {brain.name} {brain.description} - (window.location.href = `/studio/${brain.id}`)} - /> - setIsDeleteOrUnsubscribeModalOpened(true)} - /> + +
+
) => { + event.stopPropagation(); + setOptionsOpened(!optionsOpened); + }} + > + +
+ {optionsOpened && ( +
+
setIsDeleteOrUnsubscribeModalOpened(true)} + onMouseEnter={() => setDeleteHovered(true)} + onMouseLeave={() => setDeleteHovered(false)} + > + Delete + +
+
(window.location.href = `/studio/${brain.id}`)} + onMouseEnter={() => setEditHovered(true)} + onMouseLeave={() => setEditHovered(false)} + > + Edit + +
+
+ )} +