Create new ToolbarButton type for Layout Selector; wire up custom UI; prep for viewportGridService usage
This commit is contained in:
parent
83eb24337c
commit
9146a9ee32
41
extensions/default/src/Toolbar/ToolbarLayoutSelector.jsx
Normal file
41
extensions/default/src/Toolbar/ToolbarLayoutSelector.jsx
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
import React, { useEffect, useState } from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import { LayoutSelector as OHIFLayoutSelector, ToolbarButton } from '@ohif/ui';
|
||||||
|
|
||||||
|
function LayoutSelector() {
|
||||||
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
function LayoutSelector() {
|
||||||
|
if (isOpen) {
|
||||||
|
setIsOpen(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
window.addEventListener('click', LayoutSelector);
|
||||||
|
return () => {
|
||||||
|
window.removeEventListener('click', LayoutSelector);
|
||||||
|
};
|
||||||
|
}, [isOpen]);
|
||||||
|
|
||||||
|
const dropdownContent = isOpen ? OHIFLayoutSelector : undefined;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ToolbarButton
|
||||||
|
id="Layout"
|
||||||
|
label="Grid Layout"
|
||||||
|
icon="tool-layout"
|
||||||
|
onClick={() => {
|
||||||
|
setIsOpen(!isOpen);
|
||||||
|
}}
|
||||||
|
dropdownContent={dropdownContent}
|
||||||
|
isActive={isOpen}
|
||||||
|
type="primary"
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
LayoutSelector.propTypes = {
|
||||||
|
children: PropTypes.any.isRequired,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default LayoutSelector;
|
||||||
@ -2,18 +2,18 @@ import React, { useEffect, useState } from 'react';
|
|||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { ToolbarButton } from '@ohif/ui';
|
import { ToolbarButton } from '@ohif/ui';
|
||||||
|
|
||||||
function NestedToolbar({ children }) {
|
function NestedMenu({ children }) {
|
||||||
const [isOpen, setIsOpen] = useState(false);
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
function closeNestedToolbar() {
|
function closeNestedMenu() {
|
||||||
if (isOpen) {
|
if (isOpen) {
|
||||||
setIsOpen(false);
|
setIsOpen(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
window.addEventListener('click', closeNestedToolbar);
|
window.addEventListener('click', closeNestedMenu);
|
||||||
return () => {
|
return () => {
|
||||||
window.removeEventListener('click', closeNestedToolbar);
|
window.removeEventListener('click', closeNestedMenu);
|
||||||
};
|
};
|
||||||
}, [isOpen]);
|
}, [isOpen]);
|
||||||
|
|
||||||
@ -34,8 +34,8 @@ function NestedToolbar({ children }) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
NestedToolbar.propTypes = {
|
NestedMenu.propTypes = {
|
||||||
children: PropTypes.any.isRequired,
|
children: PropTypes.any.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default NestedToolbar;
|
export default NestedMenu;
|
||||||
@ -3,7 +3,7 @@ import classnames from 'classnames';
|
|||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { SidePanel } from '@ohif/ui';
|
import { SidePanel } from '@ohif/ui';
|
||||||
import Header from './Header.jsx';
|
import Header from './Header.jsx';
|
||||||
import NestedToolbar from './NestedToolbar.jsx';
|
import NestedMenu from './ToolbarButtonNestedMenu.jsx';
|
||||||
|
|
||||||
function ViewerLayout({
|
function ViewerLayout({
|
||||||
// From Extension Module Params
|
// From Extension Module Params
|
||||||
@ -90,14 +90,14 @@ function ViewerLayout({
|
|||||||
return <Component key={id} id={id} {...componentProps} />;
|
return <Component key={id} id={id} {...componentProps} />;
|
||||||
} else {
|
} else {
|
||||||
return (
|
return (
|
||||||
<NestedToolbar>
|
<NestedMenu>
|
||||||
<div className="flex">
|
<div className="flex">
|
||||||
{toolDef.map(x => {
|
{toolDef.map(x => {
|
||||||
const { id, Component, componentProps } = x;
|
const { id, Component, componentProps } = x;
|
||||||
return <Component key={id} id={id} {...componentProps} />;
|
return <Component key={id} id={id} {...componentProps} />;
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
</NestedToolbar>
|
</NestedMenu>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
})}
|
})}
|
||||||
|
|||||||
@ -1,68 +0,0 @@
|
|||||||
// SEE:
|
|
||||||
// https://github.com/OHIF/Viewers/blob/b58aa4575ab72fe3f493cc5a4261b4f8256516ab/platform/viewer/src/appExtensions/MeasurementsPanel/index.js#L18-L49
|
|
||||||
import React from 'react';
|
|
||||||
import { useViewportGrid } from '@ohif/ui';
|
|
||||||
|
|
||||||
function getCommandsModule({ servicesManager }) {
|
|
||||||
const { UIDialogService } = servicesManager.services;
|
|
||||||
|
|
||||||
const definitions = {
|
|
||||||
toggleLayoutSelectionDialog: {
|
|
||||||
commandFn: () => {
|
|
||||||
if (!UIDialogService) {
|
|
||||||
window.alert(
|
|
||||||
'Unable to show dialog; no UI Dialog Service available.'
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: use SimpleDialog component
|
|
||||||
// TODO: update position on window resize
|
|
||||||
// TODO: Expand service API to check if dialog w/ ID is already open
|
|
||||||
// TODO: Import and call `useViewportGrid`
|
|
||||||
UIDialogService.dismiss({ id: 'layoutSelection' });
|
|
||||||
UIDialogService.create({
|
|
||||||
id: 'layoutSelection',
|
|
||||||
centralize: true,
|
|
||||||
isDraggable: false,
|
|
||||||
showOverlay: true,
|
|
||||||
content: Test,
|
|
||||||
});
|
|
||||||
},
|
|
||||||
storeContexts: [],
|
|
||||||
options: {},
|
|
||||||
context: 'VIEWER',
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
return {
|
|
||||||
definitions,
|
|
||||||
defaultContext: 'VIEWER',
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function Test() {
|
|
||||||
const [
|
|
||||||
{ numCols, numRows, activeViewportIndex, viewports },
|
|
||||||
dispatch,
|
|
||||||
] = useViewportGrid();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
onClick={() => {
|
|
||||||
dispatch({
|
|
||||||
type: 'SET_LAYOUT',
|
|
||||||
payload: {
|
|
||||||
numCols: 2,
|
|
||||||
numRows: 2,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
style={{ color: 'white' }}
|
|
||||||
>
|
|
||||||
Hello World!
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default getCommandsModule;
|
|
||||||
@ -1,5 +1,6 @@
|
|||||||
import { ToolbarButton } from '@ohif/ui';
|
import { ToolbarButton } from '@ohif/ui';
|
||||||
import ToolbarDivider from './Toolbar/ToolbarDivider.jsx';
|
import ToolbarDivider from './Toolbar/ToolbarDivider.jsx';
|
||||||
|
import ToolbarLayoutSelector from './Toolbar/ToolbarLayoutSelector.jsx';
|
||||||
|
|
||||||
export default function getToolbarModule({ commandsManager, servicesManager }) {
|
export default function getToolbarModule({ commandsManager, servicesManager }) {
|
||||||
const toolbarService = servicesManager.services.ToolBarService;
|
const toolbarService = servicesManager.services.ToolBarService;
|
||||||
@ -59,6 +60,15 @@ export default function getToolbarModule({ commandsManager, servicesManager }) {
|
|||||||
toolbarService.setButtons(allButtons);
|
toolbarService.setButtons(allButtons);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'ohif.layoutSelector',
|
||||||
|
defaultComponent: ToolbarLayoutSelector,
|
||||||
|
requiredConfig: [],
|
||||||
|
optionalConfig: [],
|
||||||
|
requiredProps: [],
|
||||||
|
optionalProps: [],
|
||||||
|
clickHandler: (evt, clickedBtn, btnSectionName) => {},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'ohif.toggle',
|
name: 'ohif.toggle',
|
||||||
defaultComponent: ToolbarButton,
|
defaultComponent: ToolbarButton,
|
||||||
@ -76,7 +86,9 @@ export default function getToolbarModule({ commandsManager, servicesManager }) {
|
|||||||
|
|
||||||
// Run button logic/command
|
// Run button logic/command
|
||||||
// MAKE SURE THIS SUPPORTS TOGGLE!
|
// MAKE SURE THIS SUPPORTS TOGGLE!
|
||||||
commandsManager.runCommand(props.commandName, props.commandOptions);
|
// commandsManager.runCommand(props.commandName, props.commandOptions);
|
||||||
|
// What if just toggled "content"?
|
||||||
|
// commandName OR content?
|
||||||
|
|
||||||
// Set buttons & trigger notification
|
// Set buttons & trigger notification
|
||||||
toolbarService.setButtons(allButtons);
|
toolbarService.setButtons(allButtons);
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
import getCommandsModule from './getCommandsModule.js';
|
|
||||||
import getContextModule from './getContextModule.js';
|
import getContextModule from './getContextModule.js';
|
||||||
import getDataSourcesModule from './getDataSourcesModule.js';
|
import getDataSourcesModule from './getDataSourcesModule.js';
|
||||||
import getLayoutTemplateModule from './getLayoutTemplateModule.js';
|
import getLayoutTemplateModule from './getLayoutTemplateModule.js';
|
||||||
@ -12,7 +11,6 @@ export default {
|
|||||||
* Only required property. Should be a unique value across all extensions.
|
* Only required property. Should be a unique value across all extensions.
|
||||||
*/
|
*/
|
||||||
id,
|
id,
|
||||||
getCommandsModule,
|
|
||||||
getContextModule,
|
getContextModule,
|
||||||
getDataSourcesModule,
|
getDataSourcesModule,
|
||||||
getLayoutTemplateModule,
|
getLayoutTemplateModule,
|
||||||
|
|||||||
@ -1,68 +0,0 @@
|
|||||||
// SEE:
|
|
||||||
// https://github.com/OHIF/Viewers/blob/b58aa4575ab72fe3f493cc5a4261b4f8256516ab/platform/viewer/src/appExtensions/MeasurementsPanel/index.js#L18-L49
|
|
||||||
import React from 'react';
|
|
||||||
import { useViewportGrid } from '@ohif/ui';
|
|
||||||
|
|
||||||
function getCommandsModule({ servicesManager }) {
|
|
||||||
const { UIDialogService } = servicesManager.services;
|
|
||||||
|
|
||||||
const definitions = {
|
|
||||||
toggleLayoutSelectionDialog: {
|
|
||||||
commandFn: () => {
|
|
||||||
if (!UIDialogService) {
|
|
||||||
window.alert(
|
|
||||||
'Unable to show dialog; no UI Dialog Service available.'
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: use SimpleDialog component
|
|
||||||
// TODO: update position on window resize
|
|
||||||
// TODO: Expand service API to check if dialog w/ ID is already open
|
|
||||||
// TODO: Import and call `useViewportGrid`
|
|
||||||
UIDialogService.dismiss({ id: 'layoutSelection' });
|
|
||||||
UIDialogService.create({
|
|
||||||
id: 'layoutSelection',
|
|
||||||
centralize: true,
|
|
||||||
isDraggable: false,
|
|
||||||
showOverlay: true,
|
|
||||||
content: Test,
|
|
||||||
});
|
|
||||||
},
|
|
||||||
storeContexts: [],
|
|
||||||
options: {},
|
|
||||||
context: 'VIEWER',
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
return {
|
|
||||||
definitions,
|
|
||||||
defaultContext: 'VIEWER',
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function Test() {
|
|
||||||
const [
|
|
||||||
{ numCols, numRows, activeViewportIndex, viewports },
|
|
||||||
dispatch,
|
|
||||||
] = useViewportGrid();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
onClick={() => {
|
|
||||||
dispatch({
|
|
||||||
type: 'SET_LAYOUT',
|
|
||||||
payload: {
|
|
||||||
numCols: 2,
|
|
||||||
numRows: 2,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
style={{ color: 'white' }}
|
|
||||||
>
|
|
||||||
Hello World!
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default getCommandsModule;
|
|
||||||
@ -1,4 +1,3 @@
|
|||||||
import getCommandsModule from './getCommandsModule.js';
|
|
||||||
import getContextModule from './getContextModule.js';
|
import getContextModule from './getContextModule.js';
|
||||||
import getPanelModule from './getPanelModule.js';
|
import getPanelModule from './getPanelModule.js';
|
||||||
import getViewportModule from './getViewportModule.js';
|
import getViewportModule from './getViewportModule.js';
|
||||||
@ -8,7 +7,6 @@ export default {
|
|||||||
* Only required property. Should be a unique value across all extensions.
|
* Only required property. Should be a unique value across all extensions.
|
||||||
*/
|
*/
|
||||||
id: 'org.ohif.measurement-tracking',
|
id: 'org.ohif.measurement-tracking',
|
||||||
getCommandsModule,
|
|
||||||
getContextModule,
|
getContextModule,
|
||||||
getPanelModule,
|
getPanelModule,
|
||||||
getViewportModule,
|
getViewportModule,
|
||||||
|
|||||||
@ -128,7 +128,9 @@ const definitions = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
export default {
|
export default [];
|
||||||
definitions,
|
|
||||||
defaultContext: 'ACTIVE_VIEWPORT::VTK',
|
// export default {
|
||||||
};
|
// definitions,
|
||||||
|
// defaultContext: 'ACTIVE_VIEWPORT::VTK',
|
||||||
|
// };
|
||||||
|
|||||||
@ -35,7 +35,7 @@ export default function mode({ modeConfiguration }) {
|
|||||||
'Wwwc',
|
'Wwwc',
|
||||||
'Pan',
|
'Pan',
|
||||||
'Capture',
|
'Capture',
|
||||||
// 'Layout', // toggle --> command to open layout dialog? needs to know when it should be off? (promise?)
|
'Layout',
|
||||||
'Divider',
|
'Divider',
|
||||||
['Zoom', 'Wwwc'],
|
['Zoom', 'Wwwc'],
|
||||||
]);
|
]);
|
||||||
|
|||||||
@ -1,3 +1,6 @@
|
|||||||
|
// TODO: torn, can either bake this here; or have to create a whole new button type
|
||||||
|
// Only ways that you can pass in a custom React component for render :l
|
||||||
|
|
||||||
export default [
|
export default [
|
||||||
// Divider
|
// Divider
|
||||||
{
|
{
|
||||||
@ -60,8 +63,11 @@ export default [
|
|||||||
type: 'primary',
|
type: 'primary',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// Layout
|
{
|
||||||
// Expanded/Nested?
|
id: 'Layout',
|
||||||
|
type: 'ohif.layoutSelector',
|
||||||
|
},
|
||||||
|
// ~~ Primary: NESTED
|
||||||
// ~~ Secondary
|
// ~~ Secondary
|
||||||
{
|
{
|
||||||
id: 'Annotate',
|
id: 'Annotate',
|
||||||
|
|||||||
@ -154,8 +154,6 @@ export default class ToolBarService {
|
|||||||
if (btn.props.clickHandler) {
|
if (btn.props.clickHandler) {
|
||||||
btn.clickHandler(evt, btn, btnSection);
|
btn.clickHandler(evt, btn, btnSection);
|
||||||
}
|
}
|
||||||
|
|
||||||
this._trySetButtonActive(id);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@ -41,6 +41,7 @@ export {
|
|||||||
InputMultiSelect,
|
InputMultiSelect,
|
||||||
InputText,
|
InputText,
|
||||||
Label,
|
Label,
|
||||||
|
LayoutSelector,
|
||||||
MeasurementTable,
|
MeasurementTable,
|
||||||
Modal,
|
Modal,
|
||||||
NavBar,
|
NavBar,
|
||||||
|
|||||||
80
platform/ui/src/components/LayoutSelector/LayoutSelector.jsx
Normal file
80
platform/ui/src/components/LayoutSelector/LayoutSelector.jsx
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
// // SEE:
|
||||||
|
// // https://github.com/OHIF/Viewers/blob/b58aa4575ab72fe3f493cc5a4261b4f8256516ab/platform/viewer/src/appExtensions/MeasurementsPanel/index.js#L18-L49
|
||||||
|
// import React from 'react';
|
||||||
|
// import { useViewportGrid } from '@ohif/ui';
|
||||||
|
|
||||||
|
// function getCommandsModule({ servicesManager }) {
|
||||||
|
// const { UIDialogService } = servicesManager.services;
|
||||||
|
|
||||||
|
// const definitions = {
|
||||||
|
// toggleLayoutSelectionDialog: {
|
||||||
|
// commandFn: () => {
|
||||||
|
// if (!UIDialogService) {
|
||||||
|
// window.alert(
|
||||||
|
// 'Unable to show dialog; no UI Dialog Service available.'
|
||||||
|
// );
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // TODO: use SimpleDialog component
|
||||||
|
// // TODO: update position on window resize
|
||||||
|
// // TODO: Expand service API to check if dialog w/ ID is already open
|
||||||
|
// // TODO: Import and call `useViewportGrid`
|
||||||
|
// UIDialogService.dismiss({ id: 'layoutSelection' });
|
||||||
|
// UIDialogService.create({
|
||||||
|
// id: 'layoutSelection',
|
||||||
|
// centralize: true,
|
||||||
|
// isDraggable: false,
|
||||||
|
// showOverlay: true,
|
||||||
|
// content: Test,
|
||||||
|
// });
|
||||||
|
// },
|
||||||
|
// storeContexts: [],
|
||||||
|
// options: {},
|
||||||
|
// context: 'VIEWER',
|
||||||
|
// },
|
||||||
|
// };
|
||||||
|
|
||||||
|
// return {
|
||||||
|
// definitions,
|
||||||
|
// defaultContext: 'VIEWER',
|
||||||
|
// };
|
||||||
|
// }
|
||||||
|
|
||||||
|
// function Test() {
|
||||||
|
// const [
|
||||||
|
// { numCols, numRows, activeViewportIndex, viewports },
|
||||||
|
// dispatch,
|
||||||
|
// ] = useViewportGrid();
|
||||||
|
|
||||||
|
// return (
|
||||||
|
// <div
|
||||||
|
// onClick={() => {
|
||||||
|
// dispatch({
|
||||||
|
// type: 'SET_LAYOUT',
|
||||||
|
// payload: {
|
||||||
|
// numCols: 2,
|
||||||
|
// numRows: 2,
|
||||||
|
// },
|
||||||
|
// });
|
||||||
|
// }}
|
||||||
|
// style={{ color: 'white' }}
|
||||||
|
// >
|
||||||
|
// Hello World!
|
||||||
|
// </div>
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
|
||||||
|
// export default getCommandsModule;
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
function LayoutSelector() {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div>LAYOUT SELECTOR PLACEHOLDER!</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default LayoutSelector;
|
||||||
2
platform/ui/src/components/LayoutSelector/index.js
Normal file
2
platform/ui/src/components/LayoutSelector/index.js
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
import LayoutSelector from './LayoutSelector';
|
||||||
|
export default LayoutSelector;
|
||||||
@ -60,7 +60,7 @@ ToolbarButton.propTypes = {
|
|||||||
icon: PropTypes.string.isRequired,
|
icon: PropTypes.string.isRequired,
|
||||||
label: PropTypes.string.isRequired,
|
label: PropTypes.string.isRequired,
|
||||||
/** Tooltip content can be replaced for a customized content by passing a node to this value. */
|
/** Tooltip content can be replaced for a customized content by passing a node to this value. */
|
||||||
dropdownContent: PropTypes.node,
|
dropdownContent: PropTypes.oneOfType([PropTypes.node, PropTypes.func]),
|
||||||
};
|
};
|
||||||
|
|
||||||
export default ToolbarButton;
|
export default ToolbarButton;
|
||||||
|
|||||||
@ -65,7 +65,7 @@ const Tooltip = ({ content, isSticky, position, tight, children }) => {
|
|||||||
}
|
}
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{content}
|
{typeof content === 'function' ? content() : content}
|
||||||
<svg
|
<svg
|
||||||
className="absolute h-4 text-primary-dark stroke-secondary-main"
|
className="absolute h-4 text-primary-dark stroke-secondary-main"
|
||||||
style={arrowPositionStyle[position]}
|
style={arrowPositionStyle[position]}
|
||||||
@ -87,7 +87,7 @@ Tooltip.defaultProps = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
Tooltip.propTypes = {
|
Tooltip.propTypes = {
|
||||||
content: PropTypes.node.isRequired,
|
content: PropTypes.oneOfType([PropTypes.node, PropTypes.func]).isRequired,
|
||||||
position: PropTypes.oneOf([
|
position: PropTypes.oneOf([
|
||||||
'bottom',
|
'bottom',
|
||||||
'bottom-left',
|
'bottom-left',
|
||||||
|
|||||||
@ -12,6 +12,7 @@ import InputLabelWrapper from './InputLabelWrapper';
|
|||||||
import InputMultiSelect from './InputMultiSelect';
|
import InputMultiSelect from './InputMultiSelect';
|
||||||
import InputText from './InputText';
|
import InputText from './InputText';
|
||||||
import Label from './Label';
|
import Label from './Label';
|
||||||
|
import LayoutSelector from './LayoutSelector';
|
||||||
import MeasurementTable from './MeasurementTable';
|
import MeasurementTable from './MeasurementTable';
|
||||||
import Modal from './Modal';
|
import Modal from './Modal';
|
||||||
import NavBar from './NavBar';
|
import NavBar from './NavBar';
|
||||||
@ -60,6 +61,7 @@ export {
|
|||||||
InputMultiSelect,
|
InputMultiSelect,
|
||||||
InputText,
|
InputText,
|
||||||
Label,
|
Label,
|
||||||
|
LayoutSelector,
|
||||||
MeasurementTable,
|
MeasurementTable,
|
||||||
Modal,
|
Modal,
|
||||||
NavBar,
|
NavBar,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user