diff --git a/CHANGELOG.unreleased.md b/CHANGELOG.unreleased.md
index 3801966ac48..212087a38d9 100644
--- a/CHANGELOG.unreleased.md
+++ b/CHANGELOG.unreleased.md
@@ -39,6 +39,7 @@ For upgrade instructions, please check the [migration guide](MIGRATIONS.released
- Fixed loading agglomeate skeletons for agglomerate ids larger than 2^31. [#6472](https://github.com/scalableminds/webknossos/pull/6472)
- Fixed bug which could lead to conflict-warnings even though there weren't any. [#6477](https://github.com/scalableminds/webknossos/pull/6477)
- Fixed that one could not change the color of a segment or tree in Firefox. [#6488](https://github.com/scalableminds/webknossos/pull/6488)
+- Fixed validation of layer selection when trying to start globalization of floodfills. [#6497](https://github.com/scalableminds/webknossos/pull/6497)
- Fixed filtering for public datasets in dataset table. [#6496](https://github.com/scalableminds/webknossos/pull/6496)
### Removed
diff --git a/frontend/javascripts/oxalis/view/action-bar/download_modal_view.tsx b/frontend/javascripts/oxalis/view/action-bar/download_modal_view.tsx
index 164dbfbab52..6213621c979 100644
--- a/frontend/javascripts/oxalis/view/action-bar/download_modal_view.tsx
+++ b/frontend/javascripts/oxalis/view/action-bar/download_modal_view.tsx
@@ -424,7 +424,7 @@ with wk.webknossos_context(
diff --git a/frontend/javascripts/oxalis/view/right-border-tabs/bounding_box_tab.tsx b/frontend/javascripts/oxalis/view/right-border-tabs/bounding_box_tab.tsx
index c2cc813ee94..b6fd55e2cc7 100644
--- a/frontend/javascripts/oxalis/view/right-border-tabs/bounding_box_tab.tsx
+++ b/frontend/javascripts/oxalis/view/right-border-tabs/bounding_box_tab.tsx
@@ -18,6 +18,7 @@ import ExportBoundingBoxModal from "oxalis/view/right-border-tabs/export_boundin
import * as Utils from "libs/utils";
import features from "features";
import { OxalisState, UserBoundingBox } from "oxalis/store";
+import { APISegmentationLayer, APIUser } from "types/api_flow_types";
// NOTE: The regexp and getBBoxNameForPartialFloodfill need to stay in sync.
// That way, bboxes created by the floodfill can be detected as such and
@@ -100,11 +101,11 @@ export default function BoundingBoxTab() {
setPosition(center);
}
- const showGlobalizeFloodfillsButton =
- features().jobsEnabled &&
- activeUser != null &&
- activeSegmentationTracingLayer != null &&
- userBoundingBoxes.some((bbox) => bbox.name.match(GLOBALIZE_FLOODFILL_REGEX) != null);
+ const globalizeFloodfillsButtonDisabledReason = getInfoForGlobalizeFloodfill(
+ userBoundingBoxes,
+ activeSegmentationTracingLayer,
+ activeUser,
+ );
const isViewMode = useSelector(
(state: OxalisState) => state.temporaryConfiguration.controlMode === ControlModeEnum.VIEW,
@@ -125,27 +126,27 @@ export default function BoundingBoxTab() {
minWidth: 300,
}}
>
- {showGlobalizeFloodfillsButton ? (
-
-
-
-
-
- ) : null}
+
+
+
+
+
+
{/* In view mode, it's okay to render an empty list, since there will be
an explanation below, anyway.
*/}
@@ -204,3 +205,38 @@ export default function BoundingBoxTab() {
);
}
+
+function getInfoForGlobalizeFloodfill(
+ userBoundingBoxes: UserBoundingBox[],
+ activeSegmentationTracingLayer: APISegmentationLayer | null | undefined,
+ activeUser: APIUser | null | undefined,
+) {
+ if (!userBoundingBoxes.some((bbox) => bbox.name.match(GLOBALIZE_FLOODFILL_REGEX) != null)) {
+ return { disabled: true, title: "No partial floodfills to globalize." };
+ }
+ if (activeSegmentationTracingLayer == null) {
+ return {
+ disabled: true,
+ title:
+ "Partial floodfills can only be globalized when a segmentation annotation layer exists.",
+ };
+ }
+ if (activeUser == null) {
+ return {
+ disabled: true,
+ title: "Partial floodfills can only be globalized as a registered user.",
+ };
+ }
+ if (!features().jobsEnabled) {
+ return {
+ disabled: true,
+ title: "Partial floodfills can only be globalized when a webknossos-worker was set up.",
+ };
+ }
+
+ return {
+ disabled: false,
+ title:
+ "For this annotation some floodfill operations have not run to completion, because they covered a too large volume. webKnossos can finish these operations via a long-running job.",
+ };
+}
diff --git a/frontend/javascripts/oxalis/view/right-border-tabs/starting_job_modals.tsx b/frontend/javascripts/oxalis/view/right-border-tabs/starting_job_modals.tsx
index 7a6c8d1ef28..ac3f9afcf23 100644
--- a/frontend/javascripts/oxalis/view/right-border-tabs/starting_job_modals.tsx
+++ b/frontend/javascripts/oxalis/view/right-border-tabs/starting_job_modals.tsx
@@ -81,19 +81,21 @@ export function LayerSelection({
tracing,
fixedLayerName,
layerType,
- setSelectedLayerName,
+ onChange,
style,
+ value,
}: {
layers: APIDataLayer[];
tracing: HybridTracing;
fixedLayerName?: string;
layerType?: string;
- setSelectedLayerName?: React.Dispatch>;
style?: React.CSSProperties;
+ // onChange and value should not be renamed, because these are the
+ // default property names for controlled antd FormItems.
+ onChange?: React.Dispatch>;
+ value?: string | null;
}): JSX.Element {
- const onSelect = setSelectedLayerName
- ? (layerName: string) => setSelectedLayerName(layerName)
- : undefined;
+ const onSelect = onChange ? (layerName: string) => onChange(layerName) : undefined;
const maybeLayerType = layerType || "";
const maybeSpace = layerType != null ? " " : "";
return (
@@ -108,6 +110,7 @@ export function LayerSelection({
disabled={fixedLayerName != null}
onSelect={onSelect}
style={style}
+ value={value}
>
{layers.map((layer) => {
const readableName = getReadableNameOfVolumeLayer(layer, tracing) || layer.name;
@@ -135,7 +138,7 @@ function LayerSelectionFormItem({
rules={[
{
required: true,
- message: `Please select the ${layerType} that should be used for this job.`,
+ message: `Please select the ${layerType} layer that should be used for this job.`,
},
]}
hidden={layers.length === 1 && fixedLayerName == null}