Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhance Vertical Icons Panel: Show All Plugin Names on Hover and Add "Close Others" Functionality #5846

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ const Icon = ({ iconRecord, verticalIconPlugin, contextMenuAction, theme }: Icon
const [links, setLinks] = useState<{
Documentation: string
CanDeactivate: boolean
}>({} as {Documentation: string; CanDeactivate: boolean})
CloseOthers: boolean
}>({} as {Documentation: string; CanDeactivate: boolean; CloseOthers: boolean})
const [badgeStatus, dispatchStatusUpdate] = useReducer(iconBadgeReducer, initialState)
// @ts-ignore
const [pageX, setPageX] = useState<number>(null)
Expand All @@ -57,9 +58,9 @@ const Icon = ({ iconRecord, verticalIconPlugin, contextMenuAction, theme }: Icon
const handleContextMenu = (e: SyntheticEvent & PointerEvent) => {
const deactivationState = iconRecord.canbeDeactivated
if (documentation && documentation.length > 0 && deactivationState) {
setLinks({ Documentation: documentation, CanDeactivate: deactivationState })
setLinks({ Documentation: documentation, CanDeactivate: deactivationState, CloseOthers: true })
} else {
setLinks({ Documentation: documentation, CanDeactivate: deactivationState })
setLinks({ Documentation: documentation, CanDeactivate: deactivationState, CloseOthers: true })
}
setShowContext(false)
setPageX(e.pageX)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,3 +149,23 @@
list-style: none;
margin: 0px;
}

.remixui_plugins-list-tooltip {
min-width: 200px;
max-width: 300px;
word-wrap: break-word;
animation: fadeIn 0.3s ease-in-out;
}

.remixui_plugin-names-tooltip ul li {
text-transform: capitalize;
}

@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ const RemixUiVerticalIconsPanel = ({ verticalIconsPlugin, icons }: RemixUiVertic
const iconPanelRef = useRef<any>()
const [activateScroll, dispatchScrollAction] = useReducer(verticalScrollReducer, initialState)
const [theme, setTheme] = useState<string>('dark')
const [isPanelHovered, setIsPanelHovered] = useState<boolean>(false)
const [tooltipPosition, setTooltipPosition] = useState({ top: 0, left: 0 })
const online = useContext(onLineContext)

const evaluateScrollability = () => {
Expand Down Expand Up @@ -67,9 +69,64 @@ const RemixUiVerticalIconsPanel = ({ verticalIconsPlugin, icons }: RemixUiVertic
verticalIconsPlugin.call('manager', 'deactivatePlugin', name)
}

const handlePanelMouseEnter = (e: React.MouseEvent) => {
const rect = iconPanelRef.current.getBoundingClientRect()
setTooltipPosition({ top: rect.top, left: rect.right + 10 })
setIsPanelHovered(true)
}

const handlePanelMouseLeave = () => {
setIsPanelHovered(false)
}

const renderAllPluginNames = () => {
return (
<div className="remixui_plugin-names-tooltip">
<h6 className="mb-2">Plugins</h6>
<ul className="list-unstyled mb-0">
{icons.map((icon) => (
<li key={icon.profile.name} className="mb-1 d-flex justify-content-between align-items-center">
<span>{icon.profile.displayName || icon.profile.name}</span>
{icon.active && (
<button
className="btn btn-sm btn-secondary pl-2 pr-2 py-0 ml-2"
style={{ fontSize: '0.7rem' }}
onClick={(e) => {
e.stopPropagation()
closeOtherPlugins(icon.profile.name)
}}
>
Close Others
</button>
)}
</li>
))}
</ul>
<div className="mt-2 text-muted small">
<em>Click any icon to open a plugin</em>
<br />
<em>Use "Close Others" to keep only that plugin open</em>
</div>
</div>
)
}

const closeOtherPlugins = (exceptName: string) => {
icons.forEach((icon) => {
if (icon.profile.name !== exceptName && icon.active) {
verticalIconsPlugin.call('manager', 'togglePlugin', icon.profile.name)
}
})
}

return (
<div id="iconsP" className="h-100">
<div className="remixui_icons d-flex flex-column remixui_icons_height" ref={iconPanelRef}>
<div
className="remixui_icons d-flex flex-column remixui_icons_height"
ref={iconPanelRef}
onMouseEnter={handlePanelMouseEnter}
onMouseLeave={handlePanelMouseLeave}
>
<Home verticalIconPlugin={verticalIconsPlugin} />
<div
className={
Expand Down Expand Up @@ -138,6 +195,25 @@ const RemixUiVerticalIconsPanel = ({ verticalIconsPlugin, icons }: RemixUiVertic
) : null }
</div>
</div>
{isPanelHovered && (
<div
className="position-fixed remixui_plugins-list-tooltip"
style={{
top: tooltipPosition.top,
left: tooltipPosition.left,
zIndex: 1000,
backgroundColor: theme === 'dark' ? '#2a2a2a' : '#f8f9fa',
color: theme === 'dark' ? '#f8f9fa' : '#212529',
boxShadow: '0 0 10px rgba(0,0,0,0.2)',
padding: '8px 12px',
borderRadius: '4px',
maxHeight: '80vh',
overflowY: 'auto'
}}
>
{renderAllPluginNames()}
</div>
)}
</div>
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@ export interface VerticalIconsContextMenuProps extends React.DetailedHTMLProps<R
pageX: number
pageY: number
profileName: string
links: {Documentation: string; CanDeactivate: boolean}
links: {Documentation: string; CanDeactivate: boolean; CloseOthers: boolean}
canBeDeactivated: boolean
verticalIconPlugin: any
hideContextMenu: () => void
contextMenuAction: (evt: any, profileName: string, documentation: string) => void
}

interface MenuLinksProps {
listItems: {Documentation: string; CanDeactivate: boolean}
listItems: {Documentation: string; CanDeactivate: boolean; CloseOthers: boolean}
hide: () => void
profileName: string
canBeDeactivated: boolean
Expand Down Expand Up @@ -64,10 +64,22 @@ const VerticalIconsContextMenu = (props: VerticalIconsContextMenuProps) => {
)
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars
const MenuForLinks = ({ listItems, hide, profileName, contextMenuAction }: MenuLinksProps) => {
const MenuForLinks = ({ listItems, hide, profileName, contextMenuAction, verticalIconPlugin, toggle }: MenuLinksProps) => {
return (
<Fragment>
{listItems.CloseOthers && (
<li
id="menuitemcloseothers"
onClick={() => {
closeOtherPlugins(profileName, verticalIconPlugin)
hide()
}}
className="remixui_liitem"
key="menuitemcloseothers"
>
<FormattedMessage id="pluginManager.closeOthers" defaultMessage="Close Others" />
</li>
)}
{listItems.CanDeactivate ? (
<li
id="menuitemdeactivate"
Expand All @@ -92,6 +104,17 @@ const MenuForLinks = ({ listItems, hide, profileName, contextMenuAction }: MenuL
)
}

function closeOtherPlugins(exceptName: string, verticalIconPlugin: any) {
// Get all active plugins from the verticalIconPlugin
const icons = verticalIconPlugin.verticalIconsPlugin?.icons || {}
Object.keys(icons).forEach((iconName) => {
const icon = icons[iconName]
if (iconName !== exceptName && icon.active) {
verticalIconPlugin.call('manager', 'togglePlugin', iconName)
}
})
}

function ClickOutside(ref: React.MutableRefObject<HTMLElement>, hideFn: () => void) {
useEffect(() => {
function handleClickOutside(event: any) {
Expand Down