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

Refactor deprecated antd Dropdown menus #6898

Merged
merged 39 commits into from
Mar 23, 2023
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
6072fcd
fix navbar Menu deprecatation warning (WIP)
hotzenklotz Feb 20, 2023
d1c9353
restored more navbar items (WIP)
hotzenklotz Feb 20, 2023
eb629d8
more navbar fixes
hotzenklotz Feb 20, 2023
29dff48
refactor FolderTree menu
hotzenklotz Feb 20, 2023
c987ebf
remove data-group-id attributes
hotzenklotz Feb 20, 2023
026c6de
updated changelog
hotzenklotz Feb 20, 2023
1f2d96c
makes changes compatible with antd v4.23.x
hotzenklotz Feb 21, 2023
218c4d2
Merge branch 'master' of github.com:scalableminds/webknossos into nav…
hotzenklotz Feb 21, 2023
3077818
fix linter
hotzenklotz Feb 21, 2023
1f8844e
applied PR feedback
hotzenklotz Feb 22, 2023
ef89a0e
Merge branch 'master' of github.com:scalableminds/webknossos into nav…
hotzenklotz Feb 22, 2023
6b9a901
more PR feedback
hotzenklotz Feb 22, 2023
5db33fb
Merge branch 'master' of github.com:scalableminds/webknossos into nav…
hotzenklotz Feb 22, 2023
87a5382
upgrade antd to v4.24.8
hotzenklotz Feb 21, 2023
434377d
updated changelog
hotzenklotz Feb 21, 2023
0bc7d59
Merge branch 'master' of github.com:scalableminds/webknossos into ant…
hotzenklotz Feb 22, 2023
8320f9d
Merge branch 'master' of github.com:scalableminds/webknossos into ant…
hotzenklotz Mar 2, 2023
8b776ec
apply PR feedback
hotzenklotz Mar 3, 2023
80af2d4
upgrade antd to v 4.28.x
hotzenklotz Feb 20, 2023
87d154b
refactor all occurances of <Dropdown menu>
hotzenklotz Feb 20, 2023
00285bc
changed more dropdown menus (WIP)
hotzenklotz Feb 21, 2023
ba1803e
more menu conversions (WIP)
hotzenklotz Feb 22, 2023
8f40925
more menu crazyiness (WIP)
hotzenklotz Feb 22, 2023
21e539d
upgrade antd to v 4.28.x
hotzenklotz Feb 20, 2023
d38ea55
restored context menu (WIP)
hotzenklotz Mar 3, 2023
0c4ac9e
restore layout menu
hotzenklotz Mar 3, 2023
bfe3fef
Merge branch 'master' of github.com:scalableminds/webknossos into dro…
hotzenklotz Mar 3, 2023
964fbb4
updated changelog
hotzenklotz Mar 6, 2023
d95cc01
restore context menu position styling
hotzenklotz Mar 6, 2023
17bcd86
Merge branch 'master' of github.com:scalableminds/webknossos into dro…
hotzenklotz Mar 13, 2023
2dc8aa1
fix typechecking
hotzenklotz Mar 13, 2023
0879f2e
Merge branch 'master' of github.com:scalableminds/webknossos into dro…
hotzenklotz Mar 20, 2023
0e3827b
applied PR feedback
hotzenklotz Mar 20, 2023
757f0f3
fix menu crash in dashboard
hotzenklotz Mar 20, 2023
e2e51ed
reactivated mapping warnings
hotzenklotz Mar 21, 2023
f9990b1
Merge branch 'master' of github.com:scalableminds/webknossos into dro…
hotzenklotz Mar 21, 2023
d289ba0
fix rules of hooks error in context menu
hotzenklotz Mar 22, 2023
e5686f2
Merge branch 'master' of github.com:scalableminds/webknossos into dro…
hotzenklotz Mar 23, 2023
5ea2eb9
applied PR feedback
hotzenklotz Mar 23, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 6 additions & 7 deletions CHANGELOG.unreleased.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,12 @@ For upgrade instructions, please check the [migration guide](MIGRATIONS.released
- Improved Terms-of-Service modal (e.g., allow to switch organization even when modal was blocking the remaining usage of WEBKNOSSOS). [#6930](https://github.com/scalableminds/webknossos/pull/6930)

### Fixed
- Fixed a bug where N5 datasets reading with end-chunks that have a chunk size differing from the metadata-supplied chunk size would fail for some areas. [#6890](https://github.com/scalableminds/webknossos/pull/6890)
- Fixed potential crash when trying to edit certain annotation properties of a shared annotation. [#6892](https://github.com/scalableminds/webknossos/pull/6892)
- Fixed a bug where merging multiple volume annotations would result in inconsistent segment lists. [#6882](https://github.com/scalableminds/webknossos/pull/6882)
- Fixed a bug where uploading multiple annotations with volume layers at once would fail. [#6882](https://github.com/scalableminds/webknossos/pull/6882)
- Fixed a bug where dates were formatted incorrectly in Voxelytics reports. [#6908](https://github.com/scalableminds/webknossos/pull/6908)
- Fix antd deprecation warning for Dropdown menus. [#6898](https://github.com/scalableminds/webknossos/pull/6898)

- Fixed an issue with text hints not being visible on the logout page for dark mode users. [#6916](https://github.com/scalableminds/webknossos/pull/6916)
- Fixed creating task types with a selected preferred mode. [#6928](https://github.com/scalableminds/webknossos/pull/6928)
- Fixed support for rendering of negative floats. [#6895](https://github.com/scalableminds/webknossos/pull/6895)
- Fixed caching issues with webworkers. [#6932](https://github.com/scalableminds/webknossos/pull/6932)
- Fixed download button for annotations which was disabled in some cases. [#6931](https://github.com/scalableminds/webknossos/pull/6931)
- Fixed antd deprecation warning for Dropdown menus. [#6898](https://github.com/scalableminds/webknossos/pull/6898)
### Removed

### Breaking Changes
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { FolderOpenOutlined, PlusOutlined, WarningOutlined } from "@ant-design/icons";
import { Link } from "react-router-dom";
import { Dropdown, Table, Tag, Tooltip } from "antd";
import { Dropdown, MenuProps, Table, Tag, Tooltip } from "antd";
import type { FilterValue, SorterResult, TablePaginationConfig } from "antd/lib/table/interface";
import * as React from "react";
import _ from "lodash";
Expand Down Expand Up @@ -68,7 +68,7 @@ type ContextMenuProps = {
function ContextMenuInner(propsWithInputRef: ContextMenuProps) {
const inputRef = React.useContext(ContextMenuContext);
const { datasets, reloadDataset, contextMenuPosition, hideContextMenu } = propsWithInputRef;
let menu = {};
let menu: MenuProps = { items: [] };

if (contextMenuPosition != null) {
// getDatasetActionContextMenu should not be turned into <DatasetActionMenu />
Expand All @@ -91,7 +91,6 @@ function ContextMenuInner(propsWithInputRef: ContextMenuProps) {
overlayClassName="dropdown-overlay-container-for-context-menu"
open={contextMenuPosition != null}
getPopupContainer={() => refContent}
// @ts-ignore
destroyPopupOnHide
>
<div />
Expand Down
10 changes: 2 additions & 8 deletions frontend/javascripts/dashboard/folders/folder_tree.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -188,10 +188,7 @@ export function FolderTreeSidebar({
<Dropdown
menu={createMenu()}
placement="bottom"
// The overlay is generated lazily. By default, this would make the overlay
// re-render on each parent's render() after it was shown for the first time.
// The reason for this is that it's not destroyed after closing.
// Therefore, autoDestroy is passed.
// AutoDestroy is used to remove the menu from DOM and keep up the performance.
// destroyPopupOnHide should also be an option according to the docs, but
// does not work properly. See https://github.com/react-component/trigger/issues/106#issuecomment-948532990
// @ts-expect-error ts-migrate(2322) FIXME: Type '{ children: Element; overlay: () => Element;... Remove this comment to see the full error message
Expand Down Expand Up @@ -259,10 +256,7 @@ function generateTitle(
<Dropdown
menu={createMenu()}
placement="bottom"
// The overlay is generated lazily. By default, this would make the overlay
// re-render on each parent's render() after it was shown for the first time.
// The reason for this is that it's not destroyed after closing.
// Therefore, autoDestroy is passed.
// AutoDestroy is used to remove the menu from DOM and keep up the performance.
// destroyPopupOnHide should also be an option according to the docs, but
// does not work properly. See https://github.com/react-component/trigger/issues/106#issuecomment-948532990
// @ts-expect-error ts-migrate(2322) FIXME: Type '{ children: Element; overlay: () => Element;... Remove this comment to see the full error message
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ export function getLayoutMenu(props: LayoutMenuProps): SubMenuType {
title: "Save current layout",
icon: <SaveOutlined />,
},
{ key: "dividier", type: "divider" },
{ key: "divider", type: "divider" },
{
key: "available-layouts",
type: "group",
Expand Down
128 changes: 53 additions & 75 deletions frontend/javascripts/oxalis/view/context_menu.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { CopyOutlined } from "@ant-design/icons";
import { CopyOutlined, PushpinOutlined } from "@ant-design/icons";
import type { Dispatch } from "redux";
import { Dropdown, Empty, notification, Tooltip, Popover, Input, MenuProps } from "antd";
import { connect, useDispatch, useSelector } from "react-redux";
import React, { createContext, MouseEvent, useContext, useEffect } from "react";
import { connect } from "react-redux";
import React, { createContext, MouseEvent, useContext } from "react";
import type {
APIConnectomeFile,
APIDataset,
Expand Down Expand Up @@ -168,12 +168,6 @@ type NoNodeContextMenuProps = Props & {
infoRows: ItemType[];
};

const MenuLabel: React.FunctionComponent = ({ children }) => <span>{children}</span>;
export const MenuItemWithMappingActivationConfirmation = withMappingActivationConfirmation<
{ children: React.ReactNode },
typeof MenuLabel
>(MenuLabel);

function copyIconWithTooltip(value: string | number, title: string) {
return (
<Tooltip title={title}>
Expand Down Expand Up @@ -363,7 +357,7 @@ function getMaybeMinCutItem(
};
}

function getMaybeMeshItems(
function getMeshItems(
maybeClickedMeshId: number | null | undefined,
maybeMeshIntersectionPosition: Vector3 | null | undefined,
visibleSegmentationLayer: APIDataLayer | null | undefined,
Expand All @@ -372,13 +366,13 @@ function getMaybeMeshItems(
hideMesh: (segmentationLayerName: string, meshId: number) => void,
setPosition: (position: Vector3) => void,
refreshMesh: (segmentationLayerName: string, meshId: number) => void,
): MenuItemType[] | null {
): MenuItemType[] {
if (
maybeClickedMeshId == null ||
maybeMeshIntersectionPosition == null ||
visibleSegmentationLayer == null
) {
return null;
return [];
}

return [
Expand Down Expand Up @@ -408,7 +402,7 @@ function getMaybeMeshItems(
];
}

function NodeContextMenuOptions({
function getNodeContextMenuOptions({
skeletonTracing,
clickedNodeId,
maybeClickedMeshId,
Expand All @@ -433,9 +427,8 @@ function NodeContextMenuOptions({
infoRows,
allowUpdate,
}: NodeContextMenuOptionsProps): ItemType[] {
const isProofreadingActive = useSelector(
(state: OxalisState) => state.uiInformation.activeTool === AnnotationToolEnum.PROOFREAD,
);
const state = Store.getState();
const isProofreadingActive = state.uiInformation.activeTool === AnnotationToolEnum.PROOFREAD;

if (skeletonTracing == null) {
throw new Error(
Expand Down Expand Up @@ -463,7 +456,7 @@ function NodeContextMenuOptions({
);
}

const maybeMeshItems = getMaybeMeshItems(
const meshItems = getMeshItems(
maybeClickedMeshId,
maybeMeshIntersectionPosition,
visibleSegmentationLayer,
Expand Down Expand Up @@ -561,7 +554,7 @@ function NodeContextMenuOptions({
},
]
: []),
...(maybeMeshItems ? maybeMeshItems : []),
...meshItems,
isTheSameNode
? null
: {
Expand Down Expand Up @@ -738,7 +731,7 @@ function getBoundingBoxMenuOptions({
];
}

function NoNodeContextMenuOptions(props: NoNodeContextMenuProps): ItemType[] {
function getNoNodeContextMenuOptions(props: NoNodeContextMenuProps): ItemType[] {
const {
skeletonTracing,
volumeTracing,
Expand All @@ -763,17 +756,16 @@ function NoNodeContextMenuOptions(props: NoNodeContextMenuProps): ItemType[] {
infoRows,
allowUpdate,
} = props;
const dispatch = useDispatch();
const isAgglomerateMappingEnabled = useSelector(hasAgglomerateMapping);
const isConnectomeMappingEnabled = useSelector(hasConnectomeFile);

const isProofreadingActive = useSelector(
(state: OxalisState) => state.uiInformation.activeTool === AnnotationToolEnum.PROOFREAD,
);
const state = Store.getState();
const isAgglomerateMappingEnabled = hasAgglomerateMapping(state);
const isConnectomeMappingEnabled = hasConnectomeFile(state);

const isProofreadingActive = state.uiInformation.activeTool === AnnotationToolEnum.PROOFREAD;

useEffect(() => {
dispatch(maybeFetchMeshFilesAction(visibleSegmentationLayer, dataset, false));
}, [visibleSegmentationLayer, dataset]);
// useEffect(() => {
hotzenklotz marked this conversation as resolved.
Show resolved Hide resolved
Store.dispatch(maybeFetchMeshFilesAction(visibleSegmentationLayer, dataset, false));
// }, [visibleSegmentationLayer, dataset]);

const loadPrecomputedMesh = async () => {
if (!currentMeshFile || !visibleSegmentationLayer || globalPosition == null) return;
Expand All @@ -786,7 +778,9 @@ function NoNodeContextMenuOptions(props: NoNodeContextMenuProps): ItemType[] {
return;
}

dispatch(loadPrecomputedMeshAction(segmentId, globalPosition, currentMeshFile.meshFileName));
Store.dispatch(
loadPrecomputedMeshAction(segmentId, globalPosition, currentMeshFile.meshFileName),
);
};

const computeMeshAdHoc = () => {
Expand All @@ -801,7 +795,7 @@ function NoNodeContextMenuOptions(props: NoNodeContextMenuProps): ItemType[] {
return;
}

dispatch(loadAdHocMeshAction(segmentId, globalPosition));
Store.dispatch(loadAdHocMeshAction(segmentId, globalPosition));
};

const isVolumeBasedToolActive = VolumeTools.includes(activeTool);
Expand Down Expand Up @@ -891,22 +885,17 @@ function NoNodeContextMenuOptions(props: NoNodeContextMenuProps): ItemType[] {
className: "node-context-menu-item",
key: "load-synapses",
disabled: !isConnectomeMappingEnabled.value,
label: (
<MenuItemWithMappingActivationConfirmation
onClick={() => loadSynapsesOfAgglomerateAtPosition(globalPosition)}
mappingName={connectomeFileMappingName}
descriptor="connectome file"
layerName={segmentationLayerName}
mappingInfo={mappingInfo}
>
{isConnectomeMappingEnabled.value ? (
"Import Agglomerate and Synapses"
) : (
<Tooltip title={isConnectomeMappingEnabled.reason}>
Import Agglomerate and Synapses
</Tooltip>
)}
</MenuItemWithMappingActivationConfirmation>
onClick: withMappingActivationConfirmation(
() => loadSynapsesOfAgglomerateAtPosition(globalPosition),
connectomeFileMappingName,
"connectome file",
segmentationLayerName,
mappingInfo,
),
label: isConnectomeMappingEnabled.value ? (
"Import Agglomerate and Synapses"
) : (
<Tooltip title={isConnectomeMappingEnabled.reason}>Import Agglomerate and Synapses</Tooltip>
),
};
// This action doesn't need a skeleton tracing but is conceptually related to the "Import Agglomerate Skeleton" action
Expand All @@ -917,17 +906,14 @@ function NoNodeContextMenuOptions(props: NoNodeContextMenuProps): ItemType[] {
const loadPrecomputedMeshItem: MenuItemType = {
key: "load-precomputed-mesh",
disabled: !currentMeshFile,
label: (
<MenuItemWithMappingActivationConfirmation
onClick={loadPrecomputedMesh}
mappingName={meshFileMappingName}
descriptor="mesh file"
layerName={segmentationLayerName}
mappingInfo={mappingInfo}
>
Load Mesh (precomputed)
</MenuItemWithMappingActivationConfirmation>
onClick: withMappingActivationConfirmation(
loadPrecomputedMesh,
meshFileMappingName,
"mesh file",
segmentationLayerName,
mappingInfo,
),
label: "Load Mesh (precomputed)",
};
const computeMeshAdHocItem = {
key: "compute-mesh-adhc",
Expand Down Expand Up @@ -973,7 +959,7 @@ function NoNodeContextMenuOptions(props: NoNodeContextMenuProps): ItemType[] {
const isSkeletonToolActive = activeTool === AnnotationToolEnum.SKELETON;
let allActions: ItemType[] = [];

const maybeMeshRelatedItems = getMaybeMeshItems(
const meshRelatedItems = getMeshItems(
maybeClickedMeshId,
maybeMeshIntersectionPosition,
visibleSegmentationLayer,
Expand All @@ -991,8 +977,8 @@ function NoNodeContextMenuOptions(props: NoNodeContextMenuProps): ItemType[] {
} else {
allActions = [...nonSkeletonActions, ...skeletonActions, ...boundingBoxActions];
}
if (maybeMeshRelatedItems) {
allActions = allActions.concat(maybeMeshRelatedItems);
if (meshRelatedItems) {
allActions = allActions.concat(meshRelatedItems);
}

const empty: ItemType = {
Expand Down Expand Up @@ -1091,13 +1077,9 @@ function getInfoMenuItem(
label: MenuItemType["label"],
): MenuItemGroupType {
/*
* This component can be used within an antd Menu, even though
* the docs dictate to always use a <Menu.Item /> or <Menu.Divider />.
* However, we want non-clickable info rows with a special styling here.
* Note that we must not pass along all props here, since antd will pass
* an eventKey prop to this component. Delegating this to <div /> will
* produce a "React does not recognize the `eventKey` prop on a DOM element"
* warning.
* This component is a work-around. We want antd menu entries that can not be selected
* or otherwise interacted with. An "empty" menu group will only display the group header
* which gives us the desired behavior.
*/

return { key, label, type: "group" };
hotzenklotz marked this conversation as resolved.
Show resolved Hide resolved
Expand Down Expand Up @@ -1172,7 +1154,8 @@ function ContextMenuInner(propsWithInputRef: Props) {
getInfoMenuItem(
"positionInfo",
<>
<i className="fas fa-map-marker-alt" /> Position: {nodePositionAsString}
<PushpinOutlined style={{ transform: "rotate(-45deg)" }} /> Position:{" "}
{nodePositionAsString}
{copyIconWithTooltip(nodePositionAsString, "Copy node position")}
</>,
),
Expand All @@ -1183,7 +1166,7 @@ function ContextMenuInner(propsWithInputRef: Props) {
getInfoMenuItem(
"positionInfo",
<>
<i className="fa-solid fa-location-dot" /> Position: {positionAsString}
<PushpinOutlined style={{ transform: "rotate(-45deg)" }} /> Position: {positionAsString}
{copyIconWithTooltip(positionAsString, "Copy position")}
</>,
),
Expand Down Expand Up @@ -1250,11 +1233,6 @@ function ContextMenuInner(propsWithInputRef: Props) {
});
}

// It's important to not use <NodeContextMenuOptions ...>
// or <NoNodeContextMenuOptions ... />
// for the following two expressions, since this breaks
// antd's internal population of the correct class names
// for the menu.
const menu: MenuProps = {
onClick: hideContextMenu,
style: {
Expand All @@ -1263,13 +1241,13 @@ function ContextMenuInner(propsWithInputRef: Props) {
mode: "vertical",
items:
maybeClickedNodeId != null
? NodeContextMenuOptions({
? getNodeContextMenuOptions({
clickedNodeId: maybeClickedNodeId,
infoRows,
viewport: maybeViewport,
...props,
})
: NoNodeContextMenuOptions({
: getNoNodeContextMenuOptions({
segmentIdAtPosition,
infoRows,
viewport: maybeViewport,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -217,8 +217,9 @@ class SynapseTree extends React.Component<Props, State> {
title = node.title;
} else {
title = (
<Dropdown // Lazily create the dropdown menu and destroy it again, afterwards
<Dropdown
menu={this.createSegmentDropdownMenu(data.id)}
// AutoDestroy is used to remove the menu from DOM and keep up the performance.
autoDestroy
placement="bottom"
open={this.state.activeSegmentDropdownKey === key}
Expand Down
Loading