fix: rework inconsistencies in split button implementation(#3086)

* feat: Combine the layout grid selector tool with the toggle MPR button into a split button.
The primary button will always be the layout grid selector and the MPR toggle is in the drop down menu.
This is the first step to later adding other (e.g. 3D) layout HPs to the menu.

Summary of changes/fixes:
- SplitButton now allows for its primary button to be any button component specified by a UI type.
- SplitButton passes a className to its primary button component to dictate how it should be rendered
based on its active/toggle status, hovering, menu visibility etc.
- The default menu item renderer for the SplitButton, renders acitve toggle items correctly.
- Items/buttons in the toolbar are now all the correct and same size.
- Added ToolbarService.getButtonComponentForUIType to fetch a button component for a given UI type.
- Spacing between toolbar items is now done at the Toolbar level to avoid double spacing and to ensure
uniform spacing.
- The drop down menu closes when clicking the primary button.
- Show a mouse down click effect when clicking the primary button.

Items to investigate still:
The following are all slightly contrary to the design specs of the UI:
- Is the click effect on the primary button satisfactory because with the hover border effect, the
button appears slightly smaller during the mouse down/up operation? (MEDIUM)
- On hover over the drop down button, the right-hand-side corners of the primary button appear
rounded and NOT square. Also the hover over the drop down button border effects make the primary
button appear smaller. (MEDIUM)
- Should there be hover effects when hovering over either tooltip of the SplitButton? (LOW)

* feat: Combine the layout grid selector tool with the toggle MPR button into a split button.

Fixed broken e2e tests.
data-cy and data-tool properties now passed down to primary button component.

* feat: Combine the layout grid selector tool with the toggle MPR button into a split button.

On drop down button hover, the primary button now stretches all the way right with no right border
and with square corners in the top and bottom right as per the toolbar spec.

The mouse down effect gives a full button look (i.e. no borders) with rounded corners all around and black text icon.

* feat: Combine the layout grid selector tool with the toggle MPR button into a split button.

Documented that the primary button of a split button can specify a UI type.

* feat: Combine the layout grid selector tool with the toggle MPR button into a split button.

Feedback from PR review to fix prettier formatting issue.

* feat: Combine the layout grid selector tool with the toggle MPR button into a split button.

Added TODOs as per Bill's request in the PR.

* feat: Combine the layout grid selector tool with the toggle MPR button into a split button.

Feedback from Alireza: reverted the layout selector and MPR tools to be separate toolbar items.

Co-authored-by: Joe Boccanfuso <joe.boccanfuso@radicalimaging.com>
This commit is contained in:
Joe BoccanfusoandJoe Boccanfuso authored and GitHub committed 2023-01-06 15:00:23 -05:00
1 parent fb2a60ae19
commit 9b0d542526
10 files changed
+155 -127

No files matched your search

+13 -9
View File
@@ -1,4 +1,5 @@
import React, { useEffect, useState } from 'react';
import classnames from 'classnames';
export default function Toolbar({ servicesManager }) {
const { ToolBarService } = servicesManager.services;
@@ -46,15 +47,18 @@ export default function Toolbar({ servicesManager }) {
// These can... Trigger toolbar events based on updates?
// Then sync using useEffect, or simply modify the state here?
return (
<Component
key={id}
id={id}
{...componentProps}
bState={buttonState}
isActive={isActive}
onInteraction={args => ToolBarService.recordInteraction(args)}
servicesManager={servicesManager}
/>
// The margin for separating the tools on the toolbar should go here and NOT in each individual component (button) item.
// This allows for the individual items to be included in other UI components where perhaps alternative margins are desired.
<div key={id} className={classnames('mr-1')}>
<Component
id={id}
{...componentProps}
bState={buttonState}
isActive={isActive}
onInteraction={args => ToolBarService.recordInteraction(args)}
servicesManager={servicesManager}
/>
</div>
);
})}
</>
@@ -6,12 +6,18 @@ import {
useViewportGrid,
} from '@ohif/ui';
function LayoutSelector({ rows, columns, servicesManager }) {
function LayoutSelector({
rows,
columns,
className,
servicesManager,
...rest
}) {
const [isOpen, setIsOpen] = useState(false);
const [disableSelector, setDisableSelector] = useState(false);
const [viewportGridState, viewportGridService] = useViewportGrid();
const { HangingProtocolService } = servicesManager.services;
const { HangingProtocolService, ToolBarService } = servicesManager.services;
const closeOnOutsideClick = () => {
if (isOpen) {
@@ -24,12 +30,6 @@ function LayoutSelector({ rows, columns, servicesManager }) {
HangingProtocolService.EVENTS.PROTOCOL_CHANGED,
evt => {
const { protocol } = evt;
if (protocol.id === 'mpr') {
setDisableSelector(true);
} else {
setDisableSelector(false);
}
}
);
@@ -55,20 +55,42 @@ function LayoutSelector({ rows, columns, servicesManager }) {
const onInteractionHandler = () => setIsOpen(!isOpen);
const DropdownContent = isOpen ? OHIFLayoutSelector : null;
const onSelectionHandler = ({ numRows, numCols }) => {
// TODO Introduce a service to persist the state of the current hanging protocol/app.
// TODO Here the layout change will amount to a change of hanging protocol as specified by the extension for this layout selector tool
// followed by the change of the grid itself.
if (HangingProtocolService.getActiveProtocol().protocol.id === 'mpr') {
ToolBarService.recordInteraction({
groupId: 'MPR',
itemId: 'MPR',
interactionType: 'toggle',
commands: [
{
commandName: 'toggleMPR',
commandOptions: {},
context: 'CORNERSTONE',
},
],
});
}
viewportGridService.setLayout({ numRows, numCols });
};
return (
<ToolbarButton
id="Layout"
label="Grid Layout"
icon="tool-layout"
onInteraction={onInteractionHandler}
className={className}
rounded={rest.rounded}
dropdownContent={
DropdownContent !== null && (
<DropdownContent
rows={rows}
columns={columns}
onSelection={({ numRows, numCols }) => {
viewportGridService.setLayout({ numRows, numCols });
}}
onSelection={onSelectionHandler}
/>
)
}
+1 -21
View File
@@ -35,27 +35,7 @@ export default function getToolbarModule({ commandsManager, servicesManager }) {
{
name: 'ohif.toggle',
defaultComponent: ToolbarButton,
requiredConfig: [],
optionalConfig: [],
requiredProps: [],
optionalProps: [],
clickHandler: (evt, clickedBtn, btnSectionName) => {
const { props } = clickedBtn;
const allButtons = toolbarService.getButtons();
const thisButton = allButtons[clickedBtn.id];
// Set our clicked button to active
thisButton.props.isActive = !thisButton.props.isActive;
// Run button logic/command
commandsManager.runCommand(props.commandName, props.commandOptions);
// What if just toggled "content"?
// commandName OR content?
// Set buttons & trigger notification
toolbarService.setButtons(allButtons);
},
clickHandler: () => {},
},
];
}