11"use client" ;
22
3- import { Fragment , Ref , useState , useMemo } from "react" ;
3+ import { Fragment , Ref , useState } from "react" ;
44import { observer } from "mobx-react" ;
55import Link from "next/link" ;
6- import { useParams } from "next/navigation" ;
76import { usePopper } from "react-popper" ;
87// icons
9- import { Check , ChevronDown , LogOut , Mails , PlusSquare , Settings } from "lucide-react" ;
8+ import { ChevronDown , CirclePlus , LogOut , Mails , Settings } from "lucide-react" ;
109// ui
1110import { Menu , Transition } from "@headlessui/react" ;
1211// types
13- import { EUserPermissions , EUserPermissionsLevel } from "@plane/constants" ;
1412import { useTranslation } from "@plane/i18n" ;
1513import { IWorkspace } from "@plane/types" ;
1614// plane ui
@@ -19,36 +17,16 @@ import { GOD_MODE_URL, cn } from "@/helpers/common.helper";
1917// helpers
2018import { getFileURL } from "@/helpers/file.helper" ;
2119// hooks
22- import { useAppTheme , useUser , useUserPermissions , useUserProfile , useWorkspace } from "@/hooks/store" ;
23- // plane web constants
20+ import { useAppTheme , useUser , useUserProfile , useWorkspace } from "@/hooks/store" ;
2421// plane web helpers
2522import { getIsWorkspaceCreationDisabled } from "@/plane-web/helpers/instance.helper" ;
2623// components
2724import { WorkspaceLogo } from "../logo" ;
25+ import SidebarDropdownItem from "./dropdown-item" ;
2826
2927export const SidebarDropdown = observer ( ( ) => {
3028 const { t } = useTranslation ( ) ;
31- const userLinks = useMemo (
32- ( ) => ( workspaceSlug : string ) => [
33- {
34- key : "workspace_invites" ,
35- name : t ( "workspace_invites" ) ,
36- href : "/invitations" ,
37- icon : Mails ,
38- access : [ EUserPermissions . ADMIN , EUserPermissions . MEMBER , EUserPermissions . GUEST ] ,
39- } ,
40- {
41- key : "settings" ,
42- name : t ( "workspace_settings.label" ) ,
43- href : `/${ workspaceSlug } /settings` ,
44- icon : Settings ,
45- access : [ EUserPermissions . ADMIN ] ,
46- } ,
47- ] ,
48- [ t ]
49- ) ;
50- // router params
51- const { workspaceSlug } = useParams ( ) ;
29+
5230 // store hooks
5331 const { sidebarCollapsed, toggleSidebar } = useAppTheme ( ) ;
5432 const { data : currentUser } = useUser ( ) ;
@@ -58,8 +36,6 @@ export const SidebarDropdown = observer(() => {
5836 signOut,
5937 } = useUser ( ) ;
6038 const { updateUserProfile } = useUserProfile ( ) ;
61- const { allowPermissions } = useUserPermissions ( ) ;
62- // derived values
6339 const isWorkspaceCreationEnabled = getIsWorkspaceCreationDisabled ( ) === false ;
6440
6541 const isUserInstanceAdmin = false ;
@@ -150,57 +126,26 @@ export const SidebarDropdown = observer(() => {
150126 >
151127 < Menu . Items as = { Fragment } >
152128 < div className = "fixed top-12 left-4 z-[21] mt-1 flex w-full max-w-[19rem] origin-top-left flex-col divide-y divide-custom-border-100 rounded-md border-[0.5px] border-custom-sidebar-border-300 bg-custom-sidebar-background-100 shadow-custom-shadow-rg outline-none" >
153- < div className = "vertical-scrollbar scrollbar-sm mb-2 flex max-h-96 flex-col items-start justify-start gap-2 overflow-y-scroll px-4 " >
154- < h6 className = "sticky top-0 z-[21] h-full w-full bg-custom-sidebar-background-100 pb-1 pt-3 text-sm font-medium text-custom-sidebar- text-400" >
129+ < div className = "overflow-x-hidden vertical-scrollbar scrollbar-sm flex max-h-96 flex-col items-start justify-start overflow-y-scroll" >
130+ < span className = "rounded-md px-4 sticky top-0 z-[21] h-full w-full bg-custom-sidebar-background-100 pb-1 pt-3 text-sm font-medium text-custom-text-400 truncate flex-shrink-0 " >
155131 { currentUser ?. email }
156- </ h6 >
132+ </ span >
157133 { workspacesList ? (
158- < div className = "size-full flex flex-col items-start justify-start gap-1.5" >
159- { workspacesList . map ( ( workspace ) => (
160- < Link
134+ < div className = "size-full flex flex-col items-start justify-start" >
135+ { ( activeWorkspace
136+ ? [
137+ activeWorkspace ,
138+ ...workspacesList . filter ( ( workspace ) => workspace . id !== activeWorkspace ?. id ) ,
139+ ]
140+ : workspacesList
141+ ) . map ( ( workspace ) => (
142+ < SidebarDropdownItem
161143 key = { workspace . id }
162- href = { `/${ workspace . slug } ` }
163- onClick = { ( ) => {
164- handleWorkspaceNavigation ( workspace ) ;
165- handleItemClick ( ) ;
166- } }
167- className = "w-full"
168- >
169- < Menu . Item
170- as = "div"
171- className = "flex items-center justify-between gap-1 rounded p-1 text-sm text-custom-sidebar-text-100 hover:bg-custom-sidebar-background-80"
172- >
173- < div className = "flex items-center justify-start gap-2.5 truncate" >
174- < span
175- className = { `relative flex h-6 w-6 flex-shrink-0 items-center justify-center p-2 text-xs uppercase ${
176- ! workspace ?. logo_url && "rounded bg-custom-primary-500 text-white"
177- } `}
178- >
179- { workspace ?. logo_url && workspace . logo_url !== "" ? (
180- < img
181- src = { getFileURL ( workspace . logo_url ) }
182- className = "absolute left-0 top-0 h-full w-full rounded object-cover"
183- alt = { t ( "workspace_logo" ) }
184- />
185- ) : (
186- ( workspace ?. name ?. [ 0 ] ?? "..." )
187- ) }
188- </ span >
189- < h5
190- className = { `truncate text-sm font-medium ${
191- workspaceSlug === workspace . slug ? "" : "text-custom-text-200"
192- } `}
193- >
194- { workspace . name }
195- </ h5 >
196- </ div >
197- { workspace . id === activeWorkspace ?. id && (
198- < span className = "flex-shrink-0 p-1" >
199- < Check className = "h-5 w-5 text-custom-sidebar-text-100" />
200- </ span >
201- ) }
202- </ Menu . Item >
203- </ Link >
144+ workspace = { workspace }
145+ activeWorkspace = { activeWorkspace }
146+ handleItemClick = { handleItemClick }
147+ handleWorkspaceNavigation = { handleWorkspaceNavigation }
148+ />
204149 ) ) }
205150 </ div >
206151 ) : (
@@ -219,43 +164,33 @@ export const SidebarDropdown = observer(() => {
219164 as = "div"
220165 className = "flex items-center gap-2 rounded px-2 py-1 text-sm font-medium text-custom-sidebar-text-200 hover:bg-custom-sidebar-background-80"
221166 >
222- < PlusSquare strokeWidth = { 1.75 } className = "h-4 w -4 flex-shrink-0" />
167+ < CirclePlus className = "size -4 flex-shrink-0" />
223168 { t ( "create_workspace" ) }
224169 </ Menu . Item >
225170 </ Link >
226171 ) }
227- { userLinks ( workspaceSlug ?. toString ( ) ?? "" ) . map (
228- ( link , index ) =>
229- allowPermissions ( link . access , EUserPermissionsLevel . WORKSPACE ) && (
230- < Link
231- key = { link . key }
232- href = { link . href }
233- className = "w-full"
234- onClick = { ( ) => {
235- if ( index > 0 ) handleItemClick ( ) ;
236- } }
237- >
238- < Menu . Item
239- as = "div"
240- className = "flex items-center gap-2 rounded px-2 py-1 text-sm font-medium text-custom-sidebar-text-200 hover:bg-custom-sidebar-background-80"
241- >
242- < link . icon className = "h-4 w-4 flex-shrink-0" />
243- { link . name }
244- </ Menu . Item >
245- </ Link >
246- )
247- ) }
248- </ div >
249- < div className = "w-full px-4 py-2" >
250- < Menu . Item
251- as = "button"
252- type = "button"
253- className = "flex w-full items-center gap-2 rounded px-2 py-1 text-sm font-medium text-red-600 hover:bg-custom-sidebar-background-80"
254- onClick = { handleSignOut }
255- >
256- < LogOut className = "size-4 flex-shrink-0" />
257- { t ( "sign_out" ) }
258- </ Menu . Item >
172+
173+ < Link href = "/invitations" className = "w-full" onClick = { handleItemClick } >
174+ < Menu . Item
175+ as = "div"
176+ className = "flex items-center gap-2 rounded px-2 py-1 text-sm font-medium text-custom-sidebar-text-200 hover:bg-custom-sidebar-background-80"
177+ >
178+ < Mails className = "h-4 w-4 flex-shrink-0" />
179+ { t ( "workspace_invites" ) }
180+ </ Menu . Item >
181+ </ Link >
182+
183+ < div className = "w-full" >
184+ < Menu . Item
185+ as = "button"
186+ type = "button"
187+ className = "flex w-full items-center gap-2 rounded px-2 py-1 text-sm font-medium text-red-600 hover:bg-custom-sidebar-background-80"
188+ onClick = { handleSignOut }
189+ >
190+ < LogOut className = "size-4 flex-shrink-0" />
191+ { t ( "sign_out" ) }
192+ </ Menu . Item >
193+ </ div >
259194 </ div >
260195 </ div >
261196 </ Menu . Items >
0 commit comments