import { MouseEvent } from 'react'; import { useTheme } from '@emotion/react'; import styled from '@emotion/styled'; import { useRecoilCallback } from 'recoil'; import { IconChevronDown, IconList, IconPencil, IconPlus, IconTrash, } from '@/ui/display/icon'; import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown'; import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer'; import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator'; import { StyledDropdownButtonContainer } from '@/ui/layout/dropdown/components/StyledDropdownButtonContainer'; import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown'; import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope'; import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem'; import { MOBILE_VIEWPORT } from '@/ui/theme/constants/theme'; import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope'; import { assertNotNull } from '~/utils/assert'; import { ViewsDropdownId } from '../constants/ViewsDropdownId'; import { useView } from '../hooks/useView'; import { useViewGetStates } from '../hooks/useViewGetStates'; const StyledBoldDropdownMenuItemsContainer = styled(DropdownMenuItemsContainer)` font-weight: ${({ theme }) => theme.font.weight.regular}; `; const StyledDropdownLabelAdornments = styled.span` align-items: center; color: ${({ theme }) => theme.grayScale.gray35}; display: inline-flex; gap: ${({ theme }) => theme.spacing(1)}; margin-left: ${({ theme }) => theme.spacing(1)}; `; const StyledViewIcon = styled(IconList)` margin-right: ${({ theme }) => theme.spacing(1)}; `; const StyledViewName = styled.span` display: inline-block; max-width: 130px; @media (max-width: 375px) { max-width: 90px; } @media (min-width: 376px) and (max-width: ${MOBILE_VIEWPORT}px) { max-width: 110px; } overflow: hidden; text-overflow: ellipsis; vertical-align: middle; white-space: nowrap; `; export type ViewsDropdownButtonProps = { hotkeyScope: HotkeyScope; onViewEditModeChange?: () => void; optionsDropdownScopeId: string; }; export const ViewsDropdownButton = ({ hotkeyScope, onViewEditModeChange, optionsDropdownScopeId, }: ViewsDropdownButtonProps) => { const theme = useTheme(); const { scopeId, removeView, currentViewId, changeViewInUrl } = useView(); const { views, currentView, entityCountInCurrentView } = useViewGetStates( scopeId, currentViewId, ); const { setViewEditMode } = useView(); const { isDropdownOpen: isViewsDropdownOpen, closeDropdown: closeViewsDropdown, } = useDropdown({ dropdownScopeId: ViewsDropdownId, }); const { openDropdown: openOptionsDropdown } = useDropdown({ dropdownScopeId: optionsDropdownScopeId, }); const handleViewSelect = useRecoilCallback( () => async (viewId: string) => { changeViewInUrl(viewId); closeViewsDropdown(); }, [changeViewInUrl, closeViewsDropdown], ); const handleAddViewButtonClick = () => { setViewEditMode('create'); onViewEditModeChange?.(); closeViewsDropdown(); openOptionsDropdown(); }; const handleEditViewButtonClick = ( event: MouseEvent, viewId: string, ) => { event.stopPropagation(); changeViewInUrl(viewId); setViewEditMode('edit'); onViewEditModeChange?.(); closeViewsDropdown(); openOptionsDropdown(); }; const handleDeleteViewButtonClick = async ( event: MouseEvent, viewId: string, ) => { event.stopPropagation(); await removeView(viewId); closeViewsDropdown(); }; return ( {currentView?.name} ยท {entityCountInCurrentView}{' '} } dropdownComponents={ <> {views.map((view) => ( ) => handleEditViewButtonClick(event, view.id), }, views.length > 1 ? { Icon: IconTrash, onClick: (event: MouseEvent) => handleDeleteViewButtonClick(event, view.id), } : null, ].filter(assertNotNull)} onClick={() => handleViewSelect(view.id)} LeftIcon={IconList} text={view.name} /> ))} } /> ); };