import React, { useEffect, useRef } from 'react'; import { useToolbar } from '@ohif/core'; import { ToolboxUI } from './'; import { useToolbox } from '../../contextProviders'; /** * A toolbox is a collection of buttons and commands that they invoke, used to provide * custom control panels to users. This component is a generic UI component that * interacts with services and commands in a generic fashion. While it might * seem unconventional to import it from the UI and integrate it into the JSX, * it belongs in the UI components as there isn't anything in this component that * couldn't be used for a completely different type of app. It plays a crucial * role in enhancing the app with a toolbox by providing a way to integrate * and display various tools and their corresponding options */ function Toolbox({ servicesManager, buttonSectionId, commandsManager, title, ...props }) { const { state: toolboxState, api } = useToolbox(buttonSectionId); const { onInteraction, toolbarButtons } = useToolbar({ servicesManager, buttonSection: buttonSectionId, }); const prevButtonIdsRef = useRef(); useEffect(() => { const currentButtonIdsStr = JSON.stringify( toolbarButtons.map(button => { const { id, componentProps } = button; if (componentProps.items?.length) { return componentProps.items.map(item => `${item.id}-${item.disabled}`); } return `${id}-${componentProps.disabled}`; }) ); if (prevButtonIdsRef.current === currentButtonIdsStr) { return; } prevButtonIdsRef.current = currentButtonIdsStr; const initializeOptionsWithEnhancements = toolbarButtons.reduce( (accumulator, toolbarButton) => { const { id: buttonId, componentProps } = toolbarButton; const createEnhancedOptions = (options, parentId) => { const optionsToUse = Array.isArray(options) ? options : [options]; return optionsToUse.map(option => { if (typeof option.optionComponent === 'function') { return option; } return { ...option, value: toolboxState.toolOptions?.[parentId]?.find(prop => prop.id === option.id)?.value ?? option.value, commands: value => { api.handleToolOptionChange(parentId, option.id, value); const { isArray } = Array; const cmds = isArray(option.commands) ? option.commands : [option.commands]; cmds.forEach(command => { const isString = typeof command === 'string'; const isObject = typeof command === 'object'; if (isString) { commandsManager.run(command, { value }); } else if (isObject) { commandsManager.run({ ...command, commandOptions: { ...command.commandOptions, ...option, value }, }); } }); }, }; }); }; const { items, options } = componentProps; if (items?.length) { items.forEach(({ options, id }) => { accumulator[id] = createEnhancedOptions(options, id); }); } else if (options?.length) { accumulator[buttonId] = createEnhancedOptions(options, buttonId); } else if (options?.optionComponent) { accumulator[buttonId] = options.optionComponent; } return accumulator; }, {} ); api.initializeToolOptions(initializeOptionsWithEnhancements); }, [toolbarButtons, api]); const handleToolOptionChange = (toolName, optionName, newValue) => { api.handleToolOptionChange(toolName, optionName, newValue); }; return ( api.handleToolSelect(id)} handleToolOptionChange={handleToolOptionChange} onInteraction={onInteraction} /> ); } export default Toolbox;