import { memo, ReactNode, useCallback, forwardRef } from 'react'
import {
Dropdown as BS3Dropdown,
MenuItem,
MenuItemProps,
} from 'react-bootstrap'
import { Spinner } from 'react-bootstrap-5'
import {
Dropdown,
DropdownItem,
DropdownMenu,
DropdownToggle,
} from '@/features/ui/components/bootstrap-5/dropdown-menu'
import { Trans, useTranslation } from 'react-i18next'
import Tooltip from '../../../shared/components/tooltip'
import Icon from '../../../shared/components/icon'
import IconChecked from '../../../shared/components/icon-checked'
import ControlledDropdown from '../../../shared/components/controlled-dropdown'
import {
IdeLayout,
IdeView,
useLayoutContext,
} from '../../../shared/context/layout-context'
import * as eventTracking from '../../../infrastructure/event-tracking'
import useEventListener from '../../../shared/hooks/use-event-listener'
import { DetachRole } from '@/shared/context/detach-context'
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
import MaterialIcon from '@/shared/components/material-icon'
function IconPlaceholder() {
return
}
function IconRefresh() {
return
}
function IconLayout() {
return
}
function IconSplit() {
return
}
function IconDetach() {
return
}
function IconEditorOnly() {
return
}
function IconPdfOnly() {
return
}
const isActiveDropdownItem = ({
iconFor,
pdfLayout,
view,
detachRole,
}: {
iconFor: string
pdfLayout: IdeLayout
view: IdeView | null
detachRole?: DetachRole
}) => {
if (detachRole === 'detacher' || view === 'history') {
return false
}
if (
iconFor === 'editorOnly' &&
pdfLayout === 'flat' &&
(view === 'editor' || view === 'file')
) {
return true
} else if (iconFor === 'pdfOnly' && pdfLayout === 'flat' && view === 'pdf') {
return true
} else if (iconFor === 'sideBySide' && pdfLayout === 'sideBySide') {
return true
}
return false
}
function IconCheckmark(props: Parameters[0]) {
return isActiveDropdownItem(props) ? :
}
function LayoutMenuItem({
checkmark,
icon,
text,
...props
}: {
checkmark: ReactNode
icon: ReactNode
text: string | ReactNode
} & MenuItemProps) {
return (
)
}
function EnhancedDropdownItem({
active,
...props
}: React.ComponentProps) {
return (
)
}
const LayoutDropdownToggleButton = forwardRef<
HTMLButtonElement,
{
onClick: (e: React.MouseEvent) => void
}
>(({ onClick, ...props }, ref) => {
const handleClick = (e: React.MouseEvent) => {
eventTracking.sendMB('navigation-clicked-layout')
onClick(e)
}
return
})
LayoutDropdownToggleButton.displayName = 'LayoutDropdownToggleButton'
function DetachDisabled() {
const { t } = useTranslation()
return (
}
icon={}
text={t('pdf_in_separate_tab')}
/>
)
}
function LayoutDropdownButton() {
const { t } = useTranslation()
const {
reattach,
detach,
detachIsLinked,
detachRole,
changeLayout,
view,
pdfLayout,
} = useLayoutContext()
const handleDetach = useCallback(() => {
detach()
eventTracking.sendMB('project-layout-detach')
}, [detach])
const handleReattach = useCallback(() => {
if (detachRole !== 'detacher') {
return
}
reattach()
eventTracking.sendMB('project-layout-reattach')
}, [detachRole, reattach])
// reattach when the PDF pane opens
useEventListener('ui:pdf-open', handleReattach)
const handleChangeLayout = useCallback(
(newLayout: IdeLayout, newView?: IdeView) => {
handleReattach()
changeLayout(newLayout, newView)
eventTracking.sendMB('project-layout-change', {
layout: newLayout,
view: newView,
})
},
[changeLayout, handleReattach]
)
const processing = !detachIsLinked && detachRole === 'detacher'
// bsStyle is required for Dropdown.Toggle, but we will override style
return (
<>
{processing && (
{t('layout_processing')}
)}
{
eventTracking.sendMB('navigation-clicked-layout')
}}
className="toolbar-item layout-dropdown"
pullRight
>
{processing ? : }
{t('layout')}
handleChangeLayout('sideBySide')}
checkmark={
}
icon={}
text={t('editor_and_pdf')}
/>
handleChangeLayout('flat', 'editor')}
checkmark={
}
icon={}
text={
,
]}
/>
}
/>
handleChangeLayout('flat', 'pdf')}
checkmark={
}
icon={}
text={
,
]}
/>
}
/>
{'BroadcastChannel' in window ? (
handleDetach()}
checkmark={
detachRole === 'detacher' ? (
detachIsLinked ? (
) : (
)
) : (
)
}
icon={}
text={t('pdf_in_separate_tab')}
/>
) : (
)}
}
bs5={
{processing ? (
) : (
)}
{t('layout')}
handleChangeLayout('sideBySide')}
active={isActiveDropdownItem({
iconFor: 'sideBySide',
pdfLayout,
view,
detachRole,
})}
leadingIcon="dock_to_right"
>
{t('editor_and_pdf')}
handleChangeLayout('flat', 'editor')}
active={isActiveDropdownItem({
iconFor: 'editorOnly',
pdfLayout,
view,
detachRole,
})}
leadingIcon="code"
>
,
]}
/>
handleChangeLayout('flat', 'pdf')}
active={isActiveDropdownItem({
iconFor: 'pdfOnly',
pdfLayout,
view,
detachRole,
})}
leadingIcon="picture_as_pdf"
>
,
]}
/>
{'BroadcastChannel' in window ? (
handleDetach()}
active={detachRole === 'detacher' && detachIsLinked}
trailingIcon={
detachRole === 'detacher' ? (
detachIsLinked ? (
'check'
) : (
{t('loading')}
)
) : null
}
leadingIcon="select_window"
>
{t('pdf_in_separate_tab')}
) : (
)}
}
/>
>
)
}
export default memo(LayoutDropdownButton)