11import { Avatar , Icon } from "@appsmith/ads" ;
2- import type { Organization } from "ce /api/OrganizationApi" ;
3- import { createMessage , PENDING_INVITATIONS } from "ce /constants/messages" ;
2+ import type { Organization } from "ee /api/OrganizationApi" ;
3+ import { createMessage , PENDING_INVITATIONS } from "ee /constants/messages" ;
44import React , { useCallback , useEffect , useRef , useState } from "react" ;
55import styled from "styled-components" ;
66
@@ -36,7 +36,9 @@ const TriggerContent = styled.div`
3636` ;
3737
3838const TriggerText = styled . span `
39- truncate: true;
39+ overflow: hidden;
40+ text-overflow: ellipsis;
41+ white-space: nowrap;
4042 font-weight: 400;
4143` ;
4244
@@ -136,28 +138,30 @@ export interface PendingInvitation {
136138}
137139
138140export interface OrganizationDropdownProps {
139- selectedOrganization : Organization ;
140- organizations : Organization [ ] ;
141141 "data-testid" ?: string ;
142+ organizations : Organization [ ] ;
143+ selectedOrganization : Organization ;
142144}
143145
144146const OrganizationDropdown : React . FC < OrganizationDropdownProps > = ( {
145- selectedOrganization,
146- organizations = [ ] ,
147147 "data-testid" : testId ,
148+ organizations = [ ] ,
149+ selectedOrganization,
148150} ) => {
149151 const [ isOpen , setIsOpen ] = useState ( false ) ;
150152 const dropdownRef = useRef < HTMLDivElement > ( null ) ;
151153 const triggerRef = useRef < HTMLButtonElement > ( null ) ;
152- const activeOrganizations = organizations . filter (
154+ const safeOrganizations = organizations || [ ] ;
155+ const activeOrganizations = safeOrganizations . filter (
153156 ( org ) => org . state === "ACTIVE" ,
154157 ) ;
155- const pendingInvitations = organizations . filter (
158+ const pendingInvitations = safeOrganizations . filter (
156159 ( org ) => org . state === "INVITED" ,
157160 ) ;
158161
159162 const generateInitials = ( name : string ) : string => {
160163 if ( ! name ) return "" ;
164+
161165 return name . charAt ( 0 ) . toUpperCase ( ) ;
162166 } ;
163167
@@ -171,6 +175,7 @@ const OrganizationDropdown: React.FC<OrganizationDropdownProps> = ({
171175
172176 window . open ( url , "_blank" , "noopener,noreferrer" ) ;
173177 }
178+
174179 setIsOpen ( false ) ;
175180 } , [ ] ) ;
176181
@@ -193,8 +198,10 @@ const OrganizationDropdown: React.FC<OrganizationDropdownProps> = ({
193198
194199 if ( isOpen ) {
195200 document . addEventListener ( "mousedown" , handleClickOutside ) ;
196- return ( ) =>
201+
202+ return ( ) => {
197203 document . removeEventListener ( "mousedown" , handleClickOutside ) ;
204+ } ;
198205 }
199206 } , [ isOpen ] ) ;
200207
@@ -203,23 +210,23 @@ const OrganizationDropdown: React.FC<OrganizationDropdownProps> = ({
203210 const renderOrgAvatar = ( orgName : string ) => {
204211 return (
205212 < Avatar
206- label = { generateInitials ( orgName ) }
207213 firstLetter = { generateInitials ( orgName ) }
214+ label = { generateInitials ( orgName ) }
208215 size = "sm"
209216 />
210217 ) ;
211218 } ;
212219
213220 return (
214- < DropdownContainer ref = { dropdownRef } data-testid = { testId } >
221+ < DropdownContainer data-testid = { testId } ref = { dropdownRef } >
215222 < DropdownTrigger
216- ref = { triggerRef }
217- type = "button"
218- onClick = { handleToggle }
219- onKeyDown = { handleKeyDown }
220223 aria-expanded = { isOpen }
221224 aria-haspopup = "listbox"
222225 aria-label = { `Current organization: ${ displayText } ` }
226+ onClick = { handleToggle }
227+ onKeyDown = { handleKeyDown }
228+ ref = { triggerRef }
229+ type = "button"
223230 >
224231 < TriggerContent >
225232 { renderOrgAvatar ( displayText ) }
@@ -228,28 +235,30 @@ const OrganizationDropdown: React.FC<OrganizationDropdownProps> = ({
228235 < Icon name = "dropdown" size = "md" />
229236 </ DropdownTrigger >
230237
231- < DropdownMenu isOpen = { isOpen } role = "listbox" aria-label = "Organizations ">
238+ < DropdownMenu aria-label = "Organizations" isOpen = { isOpen } role = "listbox" >
232239 { activeOrganizations
233240 . slice ( )
234241 . sort ( ( a , b ) => {
235242 const aIsSelected =
236243 a . organizationId === selectedOrganization ?. organizationId ;
244+
237245 const bIsSelected =
238246 b . organizationId === selectedOrganization ?. organizationId ;
239247
240248 if ( aIsSelected && ! bIsSelected ) return - 1 ;
249+
241250 if ( ! aIsSelected && bIsSelected ) return 1 ;
251+
242252 return 0 ;
243253 } )
244254 . map ( ( org ) => {
245255 const isSelected =
246256 org . organizationId === selectedOrganization ?. organizationId ;
247257 return (
248258 < MenuItem
249- key = { org . organizationId }
250- role = "option"
251- tabIndex = { 0 }
259+ aria-selected = { isSelected }
252260 isSelected = { isSelected }
261+ key = { org . organizationId }
253262 onClick = { ! isSelected ? ( ) => handleSelect ( org ) : undefined }
254263 onKeyDown = {
255264 ! isSelected
@@ -261,7 +270,8 @@ const OrganizationDropdown: React.FC<OrganizationDropdownProps> = ({
261270 }
262271 : undefined
263272 }
264- aria-selected = { isSelected }
273+ role = "option"
274+ tabIndex = { 0 }
265275 >
266276 { renderOrgAvatar ( org . organizationName ) }
267277 < MenuItemText >
@@ -272,9 +282,9 @@ const OrganizationDropdown: React.FC<OrganizationDropdownProps> = ({
272282
273283 { ! isSelected && (
274284 < MenuItemIcon
285+ className = "hover-icon color-fg-muted"
275286 name = "share-box-line"
276287 size = "md"
277- className = "hover-icon color-fg-muted"
278288 />
279289 ) }
280290 </ MenuItem >
@@ -295,9 +305,9 @@ const OrganizationDropdown: React.FC<OrganizationDropdownProps> = ({
295305 < MenuItemText > { invitation . organizationName } </ MenuItemText >
296306
297307 < MenuItemIcon
308+ className = "hover-icon color-fg-muted"
298309 name = "share-box-line"
299310 size = "md"
300- className = "hover-icon color-fg-muted"
301311 />
302312 </ MenuItem >
303313 ) ) }
0 commit comments