react-icons/fa#FaTrash TypeScript Examples
The following examples show how to use
react-icons/fa#FaTrash.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: ManagedTitle.tsx From personal-archive with MIT License | 5 votes |
Options: FC<{
onEdit: () => void,
onDelete: () => void,
}> = ({onEdit, onDelete}) => {
const [isOpened, setOpened] = useState(false)
return (
<ButtonWrapper>
<Popover
content={
<ButtonGroup>
<Button
iconLeft={<Edit/>}
type="secondary"
onClick={() => {
setOpened(false)
onEdit()
}}
size="small"
>
Edit
</Button>
<Button
iconLeft={<FaTrash/>}
type="secondary"
onClick={() => {
setOpened(false)
onDelete()
}}
size="small"
>
Delete
</Button>
</ButtonGroup>
}
opened={isOpened}
onClose={() => setOpened(false)}
>
<Button
iconLeft={<ChevronDown/>}
type="white"
size="small"
onClick={() => setOpened(!isOpened)}
/>
</Popover>
</ButtonWrapper>
)
}
Example #2
Source File: NoteParagraphButtons.tsx From personal-archive with MIT License | 5 votes |
NoteParagraphButtons: FC<Props> = ({paragraph, onMoveUp, onMoveDown, onReload}) => {
const [opened, setOpened] = useState(false)
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const [_, deleteParagraph] = useRequestDeleteParagraph()
const history = useHistory()
const onDelete = () => {
setOpened(false)
confirm({
message: 'delete paragraph?',
onOK: () =>
deleteParagraph(paragraph.id, paragraph.noteID)
.then(() => onReload())
})
}
return (
<Wrapper>
<Popover
preferredPosition="bottom"
opened={opened}
onClose={() => setOpened(false)}
content={
<ButtonGroup>
<Button
iconLeft={<ChevronUp/>}
onClick={() => onMoveUp(paragraph.seq)}
type="secondary"
size="small"
>
Up
</Button>
<Button
iconLeft={<ChevronDown/>}
onClick={() => onMoveDown(paragraph.seq)}
type="secondary"
size="small"
>
Down
</Button>
<Button
iconLeft={<Edit/>}
onClick={() => history.push(`/notes/${paragraph.noteID}/paragraphs/${paragraph.id}/edit`)}
type="secondary"
size="small"
>
Edit
</Button>
<Button
iconLeft={<FaTrash/>}
onClick={onDelete}
type="secondary"
size="small"
>
Delete
</Button>
</ButtonGroup>
}
>
<Button
iconLeft={<ChevronDown/>}
type="white"
onClick={() => setOpened(true)}
/>
</Popover>
</Wrapper>
)
}
Example #3
Source File: RoomLink.tsx From convoychat with GNU General Public License v3.0 | 5 votes |
RoomLink: React.FC<IRoomLink> = ({
name,
id,
isSelected,
onInviteMemberClick,
}) => {
const { dispatch } = useModalContext();
const [deleteRoom, { loading: isDeleting }] = useDeleteRoomMutation({
onError(err) {
console.log(err.message);
},
refetchQueries: [{ query: ListCurrentUserRoomsDocument }],
});
const handleDelete = () => {
deleteRoom({
variables: {
roomId: id,
},
}).catch(console.log);
};
const handleAddMembers = () => {
dispatch({ type: "OPEN", modal: "InviteMembers" });
onInviteMemberClick(id);
};
return (
<StyledRoomLink isSelected={isSelected}>
<Flex align="center" justify="space-between" nowrap>
<Link to={`/room/${id}`}>
<Flex gap="medium" align="center" nowrap>
<FaUsers />
<span>{name}</span>
</Flex>
</Link>
<Dropdown>
<Dropdown.Toggle>
<IconButton icon={<FiMoreVertical />} />
</Dropdown.Toggle>
<Dropdown.Content style={{ right: "initial" }}>
<Dropdown.Item>
<Button
variant="secondary"
onClick={handleAddMembers}
icon={FaUserPlus}
>
Add Members
</Button>
</Dropdown.Item>
<Dropdown.Item>
<Button
variant="danger"
isLoading={isDeleting}
onClick={handleDelete}
icon={FaTrash}
>
Delete
</Button>
</Dropdown.Item>
</Dropdown.Content>
</Dropdown>
</Flex>
</StyledRoomLink>
);
}
Example #4
Source File: IPMenu.tsx From iplocate with MIT License | 5 votes |
IPMenu: React.FC<Props> = (props) => {
const { ips, onSetCurrentIp, onToggleIpVisible, onRemoveIp } = props;
if (ips.length === 0) return null;
return (
<Wrapper>
{ips.map((ip) => (
<Row key={ip.traits.ipAddress}>
<RowText onClick={() => onSetCurrentIp(ip)}>
{ip.traits.ipAddress}
</RowText>
<div>
<RowAction
onClick={() => onRemoveIp(ip)}
aria-label="remove ip address"
>
<FaTrash />
</RowAction>
{ip.hidden ? (
<RowAction
onClick={() => onToggleIpVisible(ip)}
aria-label="toggle ip visibility on"
>
<FaEyeSlash />
</RowAction>
) : (
<RowAction
onClick={() => onToggleIpVisible(ip)}
aria-label="toggle ip visibility off"
>
<FaEye />
</RowAction>
)}
</div>
</Row>
))}
</Wrapper>
);
}
Example #5
Source File: MessageContainer.tsx From convoychat with GNU General Public License v3.0 | 4 votes |
MessageContainer: React.FC<IMessage> = ({
id,
content,
date,
author,
isAuthor,
}) => {
const client = useApolloClient();
const roomData = useRef<GetRoomQuery>();
const { roomId } = useParams();
const [isEditing, setIsEditing] = useState<boolean>(false);
const {
value,
setValue,
textareaRef,
handleChange,
handleEmojiClick,
} = useMessageInput({
defaultValue: content,
});
const [
deleteMessage,
{ loading: isDeleting, error },
] = useDeleteMessageMutation({
update: deleteMessageMutationUpdater,
});
const [
editMessage,
{ loading: editLoading, error: editError },
] = useEditMessageMutation({
onCompleted() {
setIsEditing(false);
},
});
const handleDelete = () => {
deleteMessage({ variables: { messageId: id } });
};
const handleEdit = (event: React.FormEvent<HTMLFormElement>) => {
editMessage({
variables: {
messageId: id,
content: (event.target as any).message.value,
},
});
};
const handleCancel = () => {
setIsEditing(false);
};
useEffect(() => {
try {
roomData.current = client.readQuery<GetRoomQuery>({
query: GetRoomDocument,
variables: { roomId: roomId, limit: MAX_MESSAGES },
});
} catch (err) {
console.log(err);
}
}, [roomId]);
return (
<Message>
<Message.MetaInfo author={author} date={date}>
<Message.Actions isAuthor={isAuthor}>
<Message.Action loading={editLoading}>
<FaPen onClick={() => setIsEditing(true)} />
</Message.Action>
<Message.Action loading={isDeleting}>
<FaTrash onClick={handleDelete} />
</Message.Action>
</Message.Actions>
</Message.MetaInfo>
<Message.Content
isEditing={isEditing}
onEditing={
<MessageInput
value={value}
setValue={setValue}
innerRef={textareaRef}
onCancel={handleCancel}
handleSubmit={handleEdit}
handleChange={handleChange}
onEmojiClick={handleEmojiClick}
mentionSuggestions={roomData.current?.room?.members}
/>
}
>
<MarkdownView
markdown={content}
sanitizeHtml={html => DOMPurify.sanitize(html)}
options={markdownSettings}
/>
</Message.Content>
</Message>
);
}
Example #6
Source File: Content.tsx From hub with Apache License 2.0 | 4 votes |
Content = (props: Props) => {
const history = useHistory();
const wrapper = useRef<HTMLDivElement>(null);
const versionsRef = useRef<Array<HTMLDivElement | null>>([]);
const [currentOffsets, setCurrentOffsets] = useState<number[]>([]);
const openPackagePage = (newVersion: string) => {
props.onCloseModal(false);
history.push({
pathname: buildPackageURL(props.normalizedName, props.repository, newVersion, true),
state: { searchUrlReferer: props.searchUrlReferer, fromStarredPage: props.fromStarredPage },
});
};
useLayoutEffect(() => {
const offsets: number[] = versionsRef.current.map((el) => (el ? el.offsetTop : 0));
setCurrentOffsets(offsets);
}, []);
useEffect(() => {
const handleScroll = (e: Event) => {
const scrollYPosition = e.target ? (e.target as HTMLDivElement).scrollTop : 0;
const index = findClosestNumberIndex(currentOffsets, scrollYPosition);
if (index >= 0 && props.activeVersionIndex !== index) {
props.setActiveVersionIndex(index);
}
};
if (wrapper && wrapper.current && currentOffsets.length > 0) {
const element = wrapper.current;
element.addEventListener('scroll', handleScroll, { passive: true });
return () => element.removeEventListener('scroll', handleScroll);
}
}, [currentOffsets, props]);
return (
<>
<div className="flex-grow-1 overflow-auto h-100" ref={wrapper}>
{props.changelog.map((item: ChangeLog, index: number) => {
if (isNull(item.changes) || isUndefined(item.changes)) return null;
const hasBadge = item.changes.some(
(change: Change) =>
change.hasOwnProperty('kind') && !isUndefined(change.kind) && change.kind.toString() !== ''
);
return (
<div
key={`v_${item.version}`}
data-testid="changelogBlock"
className={classnames({
[styles.lastVersion]: index === props.changelog.length - 1,
})}
>
<div
className="d-inline-block d-md-flex flex-row align-items-baseline border-bottom w-100 mb-3 pb-2"
id={`changelog-${index}`}
ref={(el) => (versionsRef.current[index] = el)}
>
<div className={`d-flex flex-row align-items-baseline ${styles.versionWrapper}`}>
<button
className={`btn btn-link btn-sm text-dark text-truncate mb-0 p-0 fs-5 ${styles.btnTitle}`}
onClick={() => openPackagePage(item.version)}
aria-label={`Open version ${item.version}`}
>
{item.version}
</button>
<button
className={`btn btn-link btn-sm text-dark py-0 position-relative ${styles.btnLink}`}
onClick={() => props.updateVersionInQueryString(item.version, index)}
aria-label={`Update active version in querystring to ${item.version}`}
>
<FaLink />
</button>
</div>
{(item.containsSecurityUpdates || item.prerelease) && (
<div className={styles.badgesWrapper}>
{item.prerelease && (
<span className={`badge badge-sm rounded-pill me-2 position-relative border ${styles.badge}`}>
Pre-release
</span>
)}
{item.containsSecurityUpdates && (
<span className={`badge badge-sm rounded-pill me-2 position-relative border ${styles.badge}`}>
Contains security updates
</span>
)}
</div>
)}
{!isFuture(item.ts) && (
<div className="ms-auto ps-0 ps-md-2 text-nowrap">
<small className="text-muted">Released {moment.unix(item.ts).fromNow()}</small>
</div>
)}
</div>
<div className={`d-flex flex-column mb-4 ${styles.list}`}>
{item.changes.map((change: Change, idx: number) => (
<div key={`change_${item.version}_${idx}`} className="mb-1 w-100 d-flex flex-row">
<div className="d-flex align-items-start flex-row w-100">
{change.kind ? (
<div className={`position-relative ${styles.changeBadgeWrapper}`}>
<div
className={classnames(
'd-flex flex-row align-items-center justify-content-center text-uppercase badge rounded-pill me-2 fw-normal px-1 py-0',
styles.changeBadge,
styles[`${change.kind.toString()}ChangeBadge`]
)}
>
<span className={`position-relative ${styles.badgeIcon}`}>
{(() => {
switch (change.kind) {
case ChangeKind.added:
return <TiPlus />;
case ChangeKind.changed:
return <TiArrowSync />;
case ChangeKind.removed:
return <FaTrash />;
case ChangeKind.fixed:
return <FaWrench />;
case ChangeKind.security:
return <MdSecurity />;
case ChangeKind.deprecated:
return <RiTimerFill />;
default:
return <>-</>;
}
})()}
</span>
<span className="d-none d-md-block ms-1">{change.kind.toString()}</span>
</div>
</div>
) : (
<>
{hasBadge ? (
<div className={`position-relative ${styles.changeBadgeWrapper}`}>
<div
className={classnames(
'd-flex flex-row align-items-center justify-content-center text-uppercase badge rounded-pill me-2',
styles.changeBadge
)}
>
-
</div>
</div>
) : (
<div className="me-1 me-md-2">
<BsDot />
</div>
)}
</>
)}
<div className="flex-grow-1">
<div>{change.description}</div>
{!isUndefined(change.links) && (
<div className={`d-flex flex-row ${styles.linksWrapper}`}>
{change.links.map((link: PackageLink, idx: number) => {
return (
<div key={`change_${index}_link${idx}`}>
<ExternalLink
className={`text-muted text-decoration-underline ${styles.link}`}
href={link.url}
label={`Open link ${link.name}`}
>
{link.name}
</ExternalLink>
{idx !== change.links!.length - 1 && <BsDot className="text-muted" />}
</div>
);
})}
</div>
)}
</div>
</div>
</div>
))}
</div>
</div>
);
})}
</div>
</>
);
}
Example #7
Source File: SlideViewer.tsx From slim with Apache License 2.0 | 4 votes |
render (): React.ReactNode {
const rois: dmv.roi.ROI[] = []
const segments: dmv.segment.Segment[] = []
const mappings: dmv.mapping.ParameterMapping[] = []
const annotationGroups: dmv.annotation.AnnotationGroup[] = []
rois.push(...this.volumeViewer.getAllROIs())
segments.push(...this.volumeViewer.getAllSegments())
mappings.push(...this.volumeViewer.getAllParameterMappings())
annotationGroups.push(...this.volumeViewer.getAllAnnotationGroups())
const openSubMenuItems = ['specimens', 'opticalpaths', 'annotations']
let report: React.ReactNode
const dataset = this.state.generatedReport
if (dataset !== undefined) {
report = <Report dataset={dataset} />
}
let annotationMenuItems: React.ReactNode
if (rois.length > 0) {
annotationMenuItems = (
<AnnotationList
rois={rois}
selectedRoiUIDs={this.state.selectedRoiUIDs}
visibleRoiUIDs={this.state.visibleRoiUIDs}
onSelection={this.handleAnnotationSelection}
onVisibilityChange={this.handleAnnotationVisibilityChange}
/>
)
}
const findingOptions = this.findingOptions.map(finding => {
return (
<Select.Option
key={finding.CodeValue}
value={finding.CodeValue}
>
{finding.CodeMeaning}
</Select.Option>
)
})
const geometryTypeOptionsMapping: { [key: string]: React.ReactNode } = {
point: <Select.Option key='point' value='point'>Point</Select.Option>,
circle: <Select.Option key='circle' value='circle'>Circle</Select.Option>,
box: <Select.Option key='box' value='box'>Box</Select.Option>,
polygon: <Select.Option key='polygon' value='polygon'>Polygon</Select.Option>,
line: <Select.Option key='line' value='line'>Line</Select.Option>,
freehandpolygon: (
<Select.Option key='freehandpolygon' value='freehandpolygon'>
Polygon (freehand)
</Select.Option>
),
freehandline: (
<Select.Option key='freehandline' value='freehandline'>
Line (freehand)
</Select.Option>
)
}
const selections: React.ReactNode[] = [
(
<Select
style={{ minWidth: 130 }}
onSelect={this.handleAnnotationFindingSelection}
key='annotation-finding'
defaultActiveFirstOption
>
{findingOptions}
</Select>
)
]
const selectedFinding = this.state.selectedFinding
if (selectedFinding !== undefined) {
const key = _buildKey(selectedFinding)
this.evaluationOptions[key].forEach(evaluation => {
const evaluationOptions = evaluation.values.map(code => {
return (
<Select.Option
key={code.CodeValue}
value={code.CodeValue}
label={evaluation.name}
>
{code.CodeMeaning}
</Select.Option>
)
})
selections.push(
<>
{evaluation.name.CodeMeaning}
<Select
style={{ minWidth: 130 }}
onSelect={this.handleAnnotationEvaluationSelection}
allowClear
onClear={this.handleAnnotationEvaluationClearance}
defaultActiveFirstOption={false}
>
{evaluationOptions}
</Select>
</>
)
})
const geometryTypeOptions = this.geometryTypeOptions[key].map(name => {
return geometryTypeOptionsMapping[name]
})
selections.push(
<Select
style={{ minWidth: 130 }}
onSelect={this.handleAnnotationGeometryTypeSelection}
key='annotation-geometry-type'
>
{geometryTypeOptions}
</Select>
)
selections.push(
<Checkbox
onChange={this.handleAnnotationMeasurementActivation}
key='annotation-measurement'
>
measure
</Checkbox>
)
}
const specimenMenu = (
<Menu.SubMenu key='specimens' title='Specimens'>
<SpecimenList
metadata={this.props.slide.volumeImages[0]}
showstain={false}
/>
</Menu.SubMenu>
)
const equipmentMenu = (
<Menu.SubMenu key='equipment' title='Equipment'>
<Equipment metadata={this.props.slide.volumeImages[0]} />
</Menu.SubMenu>
)
const defaultOpticalPathStyles: {
[identifier: string]: {
opacity: number
color?: number[]
limitValues?: number[]
}
} = {}
const opticalPathMetadata: {
[identifier: string]: dmv.metadata.VLWholeSlideMicroscopyImage[]
} = {}
const opticalPaths = this.volumeViewer.getAllOpticalPaths()
opticalPaths.sort((a, b) => {
if (a.identifier < b.identifier) {
return -1
} else if (a.identifier > b.identifier) {
return 1
}
return 0
})
opticalPaths.forEach(opticalPath => {
const identifier = opticalPath.identifier
const metadata = this.volumeViewer.getOpticalPathMetadata(identifier)
opticalPathMetadata[identifier] = metadata
const style = this.volumeViewer.getOpticalPathStyle(identifier)
defaultOpticalPathStyles[identifier] = style
})
const opticalPathMenu = (
<Menu.SubMenu key='opticalpaths' title='Optical Paths'>
<OpticalPathList
metadata={opticalPathMetadata}
opticalPaths={opticalPaths}
defaultOpticalPathStyles={defaultOpticalPathStyles}
visibleOpticalPathIdentifiers={this.state.visibleOpticalPathIdentifiers}
activeOpticalPathIdentifiers={this.state.activeOpticalPathIdentifiers}
onOpticalPathVisibilityChange={this.handleOpticalPathVisibilityChange}
onOpticalPathStyleChange={this.handleOpticalPathStyleChange}
onOpticalPathActivityChange={this.handleOpticalPathActivityChange}
selectedPresentationStateUID={this.state.selectedPresentationStateUID}
/>
</Menu.SubMenu>
)
let presentationStateMenu
console.log('DEBUG: ', this.state.presentationStates)
if (this.state.presentationStates.length > 0) {
const presentationStateOptions = this.state.presentationStates.map(
presentationState => {
return (
<Select.Option
key={presentationState.SOPInstanceUID}
value={presentationState.SOPInstanceUID}
dropdownMatchSelectWidth={false}
size='small'
>
{presentationState.ContentDescription}
</Select.Option>
)
}
)
presentationStateMenu = (
<Menu.SubMenu key='presentationStates' title='Presentation States'>
<Space align='center' size={20} style={{ padding: '14px' }}>
<Select
style={{ minWidth: 200, maxWidth: 200 }}
onSelect={this.handlePresentationStateSelection}
key='presentation-states'
defaultValue={this.props.selectedPresentationStateUID}
value={this.state.selectedPresentationStateUID}
>
{presentationStateOptions}
</Select>
<Tooltip title='Reset'>
<Btn
icon={<UndoOutlined />}
type='primary'
onClick={this.handlePresentationStateReset}
/>
</Tooltip>
</Space>
</Menu.SubMenu>
)
}
let segmentationMenu
if (segments.length > 0) {
const defaultSegmentStyles: {
[segmentUID: string]: {
opacity: number
}
} = {}
const segmentMetadata: {
[segmentUID: string]: dmv.metadata.Segmentation[]
} = {}
const segments = this.volumeViewer.getAllSegments()
segments.forEach(segment => {
defaultSegmentStyles[segment.uid] = this.volumeViewer.getSegmentStyle(
segment.uid
)
segmentMetadata[segment.uid] = this.volumeViewer.getSegmentMetadata(
segment.uid
)
})
segmentationMenu = (
<Menu.SubMenu key='segmentations' title='Segmentations'>
<SegmentList
segments={segments}
metadata={segmentMetadata}
defaultSegmentStyles={defaultSegmentStyles}
visibleSegmentUIDs={this.state.visibleSegmentUIDs}
onSegmentVisibilityChange={this.handleSegmentVisibilityChange}
onSegmentStyleChange={this.handleSegmentStyleChange}
/>
</Menu.SubMenu>
)
openSubMenuItems.push('segmentations')
}
let parametricMapMenu
if (mappings.length > 0) {
const defaultMappingStyles: {
[mappingUID: string]: {
opacity: number
}
} = {}
const mappingMetadata: {
[mappingUID: string]: dmv.metadata.ParametricMap[]
} = {}
mappings.forEach(mapping => {
defaultMappingStyles[mapping.uid] = this.volumeViewer.getParameterMappingStyle(
mapping.uid
)
mappingMetadata[mapping.uid] = this.volumeViewer.getParameterMappingMetadata(
mapping.uid
)
})
parametricMapMenu = (
<Menu.SubMenu key='parmetricmaps' title='Parametric Maps'>
<MappingList
mappings={mappings}
metadata={mappingMetadata}
defaultMappingStyles={defaultMappingStyles}
visibleMappingUIDs={this.state.visibleMappingUIDs}
onMappingVisibilityChange={this.handleMappingVisibilityChange}
onMappingStyleChange={this.handleMappingStyleChange}
/>
</Menu.SubMenu>
)
openSubMenuItems.push('parametricmaps')
}
let annotationGroupMenu
if (annotationGroups.length > 0) {
const defaultAnnotationGroupStyles: {
[annotationGroupUID: string]: {
opacity: number
}
} = {}
const annotationGroupMetadata: {
[annotationGroupUID: string]: dmv.metadata.MicroscopyBulkSimpleAnnotations
} = {}
const annotationGroups = this.volumeViewer.getAllAnnotationGroups()
annotationGroups.forEach(annotationGroup => {
defaultAnnotationGroupStyles[annotationGroup.uid] = this.volumeViewer.getAnnotationGroupStyle(
annotationGroup.uid
)
annotationGroupMetadata[annotationGroup.uid] = this.volumeViewer.getAnnotationGroupMetadata(
annotationGroup.uid
)
})
annotationGroupMenu = (
<Menu.SubMenu key='annotationGroups' title='Annotation Groups'>
<AnnotationGroupList
annotationGroups={annotationGroups}
metadata={annotationGroupMetadata}
defaultAnnotationGroupStyles={defaultAnnotationGroupStyles}
visibleAnnotationGroupUIDs={this.state.visibleAnnotationGroupUIDs}
onAnnotationGroupVisibilityChange={this.handleAnnotationGroupVisibilityChange}
onAnnotationGroupStyleChange={this.handleAnnotationGroupStyleChange}
/>
</Menu.SubMenu>
)
openSubMenuItems.push('annotationGroups')
}
let toolbar
let toolbarHeight = '0px'
if (this.props.enableAnnotationTools) {
toolbar = (
<Row>
<Button
tooltip='Draw ROI [d]'
icon={FaDrawPolygon}
onClick={this.handleRoiDrawing}
isSelected={this.state.isRoiDrawingActive}
/>
<Button
tooltip='Modify ROIs [m]'
icon={FaHandPointer}
onClick={this.handleRoiModification}
isSelected={this.state.isRoiModificationActive}
/>
<Button
tooltip='Translate ROIs [t]'
icon={FaHandPaper}
onClick={this.handleRoiTranslation}
isSelected={this.state.isRoiTranslationActive}
/>
<Button
tooltip='Remove selected ROI [r]'
onClick={this.handleRoiRemoval}
icon={FaTrash}
/>
<Button
tooltip='Show/Hide ROIs [v]'
icon={this.state.areRoisHidden ? FaEye : FaEyeSlash}
onClick={this.handleRoiVisibilityChange}
isSelected={this.state.areRoisHidden}
/>
<Button
tooltip='Save ROIs [s]'
icon={FaSave}
onClick={this.handleReportGeneration}
/>
</Row>
)
toolbarHeight = '50px'
}
/* It would be nicer to use the ant Spin component, but that causes issues
* with the positioning of the viewport.
*/
let loadingDisplay = 'none'
if (this.state.isLoading) {
loadingDisplay = 'block'
}
return (
<Layout style={{ height: '100%' }} hasSider>
<Layout.Content style={{ height: '100%' }}>
{toolbar}
<div className='dimmer' style={{ display: loadingDisplay }} />
<div className='spinner' style={{ display: loadingDisplay }} />
<div
style={{
height: `calc(100% - ${toolbarHeight})`,
overflow: 'hidden'
}}
ref={this.volumeViewportRef}
/>
<Modal
visible={this.state.isAnnotationModalVisible}
title='Configure annotations'
onOk={this.handleAnnotationConfigurationCompletion}
onCancel={this.handleAnnotationConfigurationCancellation}
okText='Select'
>
<Space align='start' direction='vertical'>
{selections}
</Space>
</Modal>
<Modal
visible={this.state.isReportModalVisible}
title='Verify and save report'
onOk={this.handleReportVerification}
onCancel={this.handleReportCancellation}
okText='Save'
>
{report}
</Modal>
</Layout.Content>
<Layout.Sider
width={300}
reverseArrow
style={{
borderLeft: 'solid',
borderLeftWidth: 0.25,
overflow: 'hidden',
background: 'none'
}}
>
<Menu
mode='inline'
defaultOpenKeys={openSubMenuItems}
style={{ height: '100%' }}
inlineIndent={14}
forceSubMenuRender
>
<Menu.SubMenu key='label' title='Slide label'>
<Menu.Item style={{ height: '100%' }}>
<div
style={{ height: '220px' }}
ref={this.labelViewportRef}
/>
</Menu.Item>
</Menu.SubMenu>
{specimenMenu}
{equipmentMenu}
{opticalPathMenu}
{presentationStateMenu}
<Menu.SubMenu key='annotations' title='Annotations'>
{annotationMenuItems}
</Menu.SubMenu>
{annotationGroupMenu}
{segmentationMenu}
{parametricMapMenu}
</Menu>
</Layout.Sider>
</Layout>
)
}