From 9c61a80bde7cd590e33e82b7a9005c7cc881c4dc Mon Sep 17 00:00:00 2001 From: Charlie Meister Date: Fri, 6 Dec 2024 17:54:39 +0100 Subject: [PATCH 01/20] very much WIP: add form item to select mag per annotation --- .../admin/voxelytics/ai_model_list_view.tsx | 8 +- .../javascripts/components/mag_selection.tsx | 34 ++++++++ .../oxalis/view/jobs/train_ai_model.tsx | 78 ++++++++++--------- 3 files changed, 81 insertions(+), 39 deletions(-) create mode 100644 frontend/javascripts/components/mag_selection.tsx diff --git a/frontend/javascripts/admin/voxelytics/ai_model_list_view.tsx b/frontend/javascripts/admin/voxelytics/ai_model_list_view.tsx index 7962e955660..722452c249e 100644 --- a/frontend/javascripts/admin/voxelytics/ai_model_list_view.tsx +++ b/frontend/javascripts/admin/voxelytics/ai_model_list_view.tsx @@ -109,7 +109,7 @@ function TrainNewAiJobModal({ onClose }: { onClose: () => void }) { AnnotationInfoForAIJob[] >([]); - const getMagForSegmentationLayer = async (annotationId: string, layerName: string) => { + const getMagsForSegmentationLayer = async (annotationId: string, layerName: string) => { // The layer name is a human-readable one. It can either belong to an annotationLayer // (therefore, also to a volume tracing) or to the actual dataset. // Both are checked below. This won't be ambiguous because annotationLayers must not @@ -130,10 +130,10 @@ function TrainNewAiJobModal({ onClose }: { onClose: () => void }) { (tracing) => tracing.tracingId === annotationLayer.tracingId, ); const mags = volumeTracingMags[volumeTracingIndex] || ([[1, 1, 1]] as Vector3[]); - return getMagInfo(mags).getFinestMag(); + return getMagInfo(mags); } else { const segmentationLayer = getSegmentationLayerByName(dataset, layerName); - return getMagInfo(segmentationLayer.resolutions).getFinestMag(); + return getMagInfo(segmentationLayer.resolutions); } }; @@ -152,7 +152,7 @@ function TrainNewAiJobModal({ onClose }: { onClose: () => void }) { maskClosable={false} > { diff --git a/frontend/javascripts/components/mag_selection.tsx b/frontend/javascripts/components/mag_selection.tsx new file mode 100644 index 00000000000..facf533079e --- /dev/null +++ b/frontend/javascripts/components/mag_selection.tsx @@ -0,0 +1,34 @@ +import { Form, Select } from "antd"; +import type { Vector3 } from "oxalis/constants"; + +export function MagSelectionFormItem({ mags }: { mags: Vector3[] }): JSX.Element { + return ( + + + + ); +} + +function MagSelection({ mags }: { mags: Vector3[] }): JSX.Element { + return ( + + ); +} diff --git a/frontend/javascripts/oxalis/view/jobs/train_ai_model.tsx b/frontend/javascripts/oxalis/view/jobs/train_ai_model.tsx index af01e2885bf..aea1c0d05b5 100644 --- a/frontend/javascripts/oxalis/view/jobs/train_ai_model.tsx +++ b/frontend/javascripts/oxalis/view/jobs/train_ai_model.tsx @@ -39,6 +39,9 @@ import type { Vector3, Vector6 } from "oxalis/constants"; import { serverVolumeToClientVolumeTracing } from "oxalis/model/reducers/volumetracing_reducer"; import { convertUserBoundingBoxesFromServerToFrontend } from "oxalis/model/reducers/reducer_helpers"; import { computeArrayFromBoundingBox } from "libs/utils"; +import { MagSelectionFormItem } from "components/mag_selection"; +import type { MagInfo } from "oxalis/model/helpers/mag_info"; +import { useFetch } from "libs/react_helpers"; const { TextArea } = Input; const FormItem = Form.Item; @@ -126,15 +129,15 @@ export function TrainAiModelFromAnnotationTab({ onClose }: { onClose: () => void const tracing = useSelector((state: OxalisState) => state.tracing); const dataset = useSelector((state: OxalisState) => state.dataset); - const getMagForSegmentationLayer = async (_annotationId: string, layerName: string) => { + const getMagsForSegmentationLayer = async (_annotationId: string, layerName: string) => { const segmentationLayer = getSegmentationLayerByHumanReadableName(dataset, tracing, layerName); - return getMagInfo(segmentationLayer.resolutions).getFinestMag(); + return getMagInfo(segmentationLayer.resolutions); }; const userBoundingBoxes = getSomeTracing(tracing).userBoundingBoxes; return ( Model.ensureSavedState()} onClose={onClose} annotationInfos={[ @@ -151,13 +154,13 @@ export function TrainAiModelFromAnnotationTab({ onClose }: { onClose: () => void } export function TrainAiModelTab({ - getMagForSegmentationLayer, + getMagsForSegmentationLayer, onClose, ensureSavedState, annotationInfos, onAddAnnotationsInfos, }: { - getMagForSegmentationLayer: (annotationId: string, layerName: string) => Promise; + getMagsForSegmentationLayer: (annotationId: string, layerName: string) => Promise; // TODO_c rename method onClose: () => void; ensureSavedState?: (() => Promise) | null; annotationInfos: Array>; @@ -165,6 +168,7 @@ export function TrainAiModelTab await getMagsForSegmentationLayer(annotationId, layerName)); // TODO_c const getTrainingAnnotations = async (values: any) => { return Promise.all( @@ -179,7 +183,7 @@ export function TrainAiModelTab - + - + - + + + + ( - - )) + + )) : null} {hasWarnings ? warnings.map((warning) => ( - - )) + + )) : null} @@ -614,10 +622,10 @@ function AnnotationsCsvInput({ return valid ? Promise.resolve() : Promise.reject( - new Error( - "Each line should only contain an annotation ID or URL (without # or ,)", - ), - ); + new Error( + "Each line should only contain an annotation ID or URL (without # or ,)", + ), + ); }, }), ]} From 6305026969504b6c1edaea0ad1de4eacdce49832 Mon Sep 17 00:00:00 2001 From: Charlie Meister Date: Mon, 9 Dec 2024 11:10:32 +0100 Subject: [PATCH 02/20] pass mags to form --- conf/application.conf | 4 +- .../admin/voxelytics/ai_model_list_view.tsx | 2 +- .../javascripts/components/mag_selection.tsx | 6 +- .../oxalis/view/jobs/train_ai_model.tsx | 63 +++++++++---------- 4 files changed, 38 insertions(+), 37 deletions(-) diff --git a/conf/application.conf b/conf/application.conf index 751fcd1e5aa..6c871ef6283 100644 --- a/conf/application.conf +++ b/conf/application.conf @@ -151,8 +151,8 @@ features { taskReopenAllowedInSeconds = 30 allowDeleteDatasets = true # to enable jobs for local development, use "yarn enable-jobs" to also activate it in the database - jobsEnabled = false - voxelyticsEnabled = false + jobsEnabled = true + voxelyticsEnabled = true # For new users, the dashboard will show a banner which encourages the user to check out the following dataset. # If isWkorgInstance == true, `/createExplorative/hybrid/true` is appended to the URL so that a new tracing is opened. # If isWkorgInstance == false, `/view` is appended to the URL so that it's opened in view mode (since the user might not diff --git a/frontend/javascripts/admin/voxelytics/ai_model_list_view.tsx b/frontend/javascripts/admin/voxelytics/ai_model_list_view.tsx index 722452c249e..83b34bdc296 100644 --- a/frontend/javascripts/admin/voxelytics/ai_model_list_view.tsx +++ b/frontend/javascripts/admin/voxelytics/ai_model_list_view.tsx @@ -109,7 +109,7 @@ function TrainNewAiJobModal({ onClose }: { onClose: () => void }) { AnnotationInfoForAIJob[] >([]); - const getMagsForSegmentationLayer = async (annotationId: string, layerName: string) => { + const getMagsForSegmentationLayer = (annotationId: string, layerName: string) => { // The layer name is a human-readable one. It can either belong to an annotationLayer // (therefore, also to a volume tracing) or to the actual dataset. // Both are checked below. This won't be ambiguous because annotationLayers must not diff --git a/frontend/javascripts/components/mag_selection.tsx b/frontend/javascripts/components/mag_selection.tsx index facf533079e..40c9f40b7c0 100644 --- a/frontend/javascripts/components/mag_selection.tsx +++ b/frontend/javascripts/components/mag_selection.tsx @@ -1,9 +1,13 @@ import { Form, Select } from "antd"; import type { Vector3 } from "oxalis/constants"; -export function MagSelectionFormItem({ mags }: { mags: Vector3[] }): JSX.Element { +export function MagSelectionFormItem({ + name, + mags, +}: { name: string; mags: Vector3[] }): JSX.Element { return ( void const tracing = useSelector((state: OxalisState) => state.tracing); const dataset = useSelector((state: OxalisState) => state.dataset); - const getMagsForSegmentationLayer = async (_annotationId: string, layerName: string) => { + const getMagsForSegmentationLayer = (_annotationId: string, layerName: string) => { const segmentationLayer = getSegmentationLayerByHumanReadableName(dataset, tracing, layerName); return getMagInfo(segmentationLayer.resolutions); }; @@ -160,7 +159,7 @@ export function TrainAiModelTab Promise; // TODO_c rename method + getMagsForSegmentationLayer: (annotationId: string, layerName: string) => MagInfo; // TODO_c rename method onClose: () => void; ensureSavedState?: (() => Promise) | null; annotationInfos: Array>; @@ -168,7 +167,6 @@ export function TrainAiModelTab await getMagsForSegmentationLayer(annotationId, layerName)); // TODO_c const getTrainingAnnotations = async (values: any) => { return Promise.all( @@ -183,7 +181,6 @@ export function TrainAiModelTab @@ -319,8 +317,7 @@ export function TrainAiModelTab - + ( - - )) + + )) : null} {hasWarnings ? warnings.map((warning) => ( - - )) + + )) : null} @@ -622,10 +619,10 @@ function AnnotationsCsvInput({ return valid ? Promise.resolve() : Promise.reject( - new Error( - "Each line should only contain an annotation ID or URL (without # or ,)", - ), - ); + new Error( + "Each line should only contain an annotation ID or URL (without # or ,)", + ), + ); }, }), ]} From 19a1666e0d86a491a93d55b138b5445480eac314 Mon Sep 17 00:00:00 2001 From: Charlie Meister Date: Mon, 9 Dec 2024 20:55:33 +0100 Subject: [PATCH 03/20] pass mags through to parent form --- .../admin/voxelytics/ai_model_list_view.tsx | 1 + .../javascripts/components/mag_selection.tsx | 14 +++++++++++--- .../oxalis/view/jobs/train_ai_model.tsx | 16 ++++++++++------ 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/frontend/javascripts/admin/voxelytics/ai_model_list_view.tsx b/frontend/javascripts/admin/voxelytics/ai_model_list_view.tsx index 83b34bdc296..503745f10a8 100644 --- a/frontend/javascripts/admin/voxelytics/ai_model_list_view.tsx +++ b/frontend/javascripts/admin/voxelytics/ai_model_list_view.tsx @@ -131,6 +131,7 @@ function TrainNewAiJobModal({ onClose }: { onClose: () => void }) { ); const mags = volumeTracingMags[volumeTracingIndex] || ([[1, 1, 1]] as Vector3[]); return getMagInfo(mags); + // TODO_c check that they exist in ground truth layer and image data layer. } else { const segmentationLayer = getSegmentationLayerByName(dataset, layerName); return getMagInfo(segmentationLayer.resolutions); diff --git a/frontend/javascripts/components/mag_selection.tsx b/frontend/javascripts/components/mag_selection.tsx index 40c9f40b7c0..820c66826fb 100644 --- a/frontend/javascripts/components/mag_selection.tsx +++ b/frontend/javascripts/components/mag_selection.tsx @@ -4,7 +4,7 @@ import type { Vector3 } from "oxalis/constants"; export function MagSelectionFormItem({ name, mags, -}: { name: string; mags: Vector3[] }): JSX.Element { +}: { name: string | Array; mags: Vector3[] }): JSX.Element { return ( void }): JSX.Element { return ( - {mags.map((mag) => { const readableName = mag.join("-"); return ( diff --git a/frontend/javascripts/oxalis/view/jobs/train_ai_model.tsx b/frontend/javascripts/oxalis/view/jobs/train_ai_model.tsx index 89166ce2569..a84b95306ed 100644 --- a/frontend/javascripts/oxalis/view/jobs/train_ai_model.tsx +++ b/frontend/javascripts/oxalis/view/jobs/train_ai_model.tsx @@ -175,12 +175,14 @@ export function TrainAiModelTab { - const { annotationId, imageDataLayer, layerName } = trainingAnnotation; + const { annotationId, imageDataLayer, layerName, mag } = trainingAnnotation; return { annotationId, colorLayerName: imageDataLayer, segmentationLayerName: layerName, + mag, }; }, ), @@ -241,7 +243,6 @@ export function TrainAiModelTab onFinish(form, useCustomWorkflow, values)} @@ -282,7 +283,7 @@ export function TrainAiModelTab @@ -316,9 +317,6 @@ export function TrainAiModelTab - - - + + + ); })} From 5d3151f2dee38cf4704db97eb681c392b77ac072 Mon Sep 17 00:00:00 2001 From: Charlie Meister Date: Thu, 12 Dec 2024 21:39:22 +0100 Subject: [PATCH 04/20] remove default value --- .../javascripts/components/mag_selection.tsx | 37 +++++++++++++------ .../oxalis/view/jobs/train_ai_model.tsx | 5 +-- 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/frontend/javascripts/components/mag_selection.tsx b/frontend/javascripts/components/mag_selection.tsx index 820c66826fb..784355dcc72 100644 --- a/frontend/javascripts/components/mag_selection.tsx +++ b/frontend/javascripts/components/mag_selection.tsx @@ -1,10 +1,14 @@ import { Form, Select } from "antd"; +import { V3 } from "libs/mjs"; +import { clamp } from "libs/utils"; +import _ from "lodash"; import type { Vector3 } from "oxalis/constants"; +import type { MagInfo } from "oxalis/model/helpers/mag_info"; export function MagSelectionFormItem({ name, - mags, -}: { name: string | Array; mags: Vector3[] }): JSX.Element { + magInfo, +}: { name: string | Array; magInfo: MagInfo }): JSX.Element { return ( - + ); } function MagSelection({ - mags, + magInfo, value, onChange, -}: { mags: Vector3[]; value?: string | null; onChange?: (a: string) => void }): JSX.Element { +}: { magInfo: MagInfo; value?: Vector3 | null; onChange?: (a: Vector3) => void }): JSX.Element { + const allMags = magInfo.getMagsWithIndices(); + return ( { const readableName = mag[1].join("-"); const index = mag[0]; + console.log("mag", mag); return ( {readableName} diff --git a/frontend/javascripts/oxalis/view/jobs/train_ai_model.tsx b/frontend/javascripts/oxalis/view/jobs/train_ai_model.tsx index 15cdddbd5b3..4d36e92dacb 100644 --- a/frontend/javascripts/oxalis/view/jobs/train_ai_model.tsx +++ b/frontend/javascripts/oxalis/view/jobs/train_ai_model.tsx @@ -167,6 +167,14 @@ export function TrainAiModelTab(); + const [chosenMag, setChosenMag] = useState(); + + const getAvailableMags = (groundTruthLayerName: string, annotationId: string) => { + console.log("getAvailableMags", groundTruthLayerName, annotationId); + setChosenMag(undefined); // TODO_c doesnt work + return getMagsForSegmentationLayer(annotationId, groundTruthLayerName); + }; const getTrainingAnnotations = async (values: any) => { return Promise.all( @@ -175,7 +183,7 @@ export function TrainAiModelTab { const { annotationId, imageDataLayer, layerName, mag } = trainingAnnotation; return { @@ -283,7 +291,7 @@ export function TrainAiModelTab @@ -327,10 +335,18 @@ export function TrainAiModelTab { + setMags(getAvailableMags(newLayerName, annotationId)); + setChosenMag(undefined); + }} /> - + ); From 5fc98f08942527563318f156c1fc7760c729d030 Mon Sep 17 00:00:00 2001 From: Charlie Meister Date: Fri, 13 Dec 2024 18:18:37 +0100 Subject: [PATCH 06/20] WIP: update mags --- .../admin/voxelytics/ai_model_list_view.tsx | 1 - .../javascripts/components/mag_selection.tsx | 4 +- .../oxalis/view/jobs/train_ai_model.tsx | 104 +++++++++++------- 3 files changed, 63 insertions(+), 46 deletions(-) diff --git a/frontend/javascripts/admin/voxelytics/ai_model_list_view.tsx b/frontend/javascripts/admin/voxelytics/ai_model_list_view.tsx index 503745f10a8..83b34bdc296 100644 --- a/frontend/javascripts/admin/voxelytics/ai_model_list_view.tsx +++ b/frontend/javascripts/admin/voxelytics/ai_model_list_view.tsx @@ -131,7 +131,6 @@ function TrainNewAiJobModal({ onClose }: { onClose: () => void }) { ); const mags = volumeTracingMags[volumeTracingIndex] || ([[1, 1, 1]] as Vector3[]); return getMagInfo(mags); - // TODO_c check that they exist in ground truth layer and image data layer. } else { const segmentationLayer = getSegmentationLayerByName(dataset, layerName); return getMagInfo(segmentationLayer.resolutions); diff --git a/frontend/javascripts/components/mag_selection.tsx b/frontend/javascripts/components/mag_selection.tsx index 75e890c5431..4acf371b772 100644 --- a/frontend/javascripts/components/mag_selection.tsx +++ b/frontend/javascripts/components/mag_selection.tsx @@ -8,11 +8,9 @@ import type { MagInfo } from "oxalis/model/helpers/mag_info"; export function MagSelectionFormItem({ name, magInfo, - value, }: { name: string | Array; magInfo: MagInfo | undefined; - value?: Vector3; }): JSX.Element { return ( - + ); } diff --git a/frontend/javascripts/oxalis/view/jobs/train_ai_model.tsx b/frontend/javascripts/oxalis/view/jobs/train_ai_model.tsx index 4d36e92dacb..494ab9300b3 100644 --- a/frontend/javascripts/oxalis/view/jobs/train_ai_model.tsx +++ b/frontend/javascripts/oxalis/view/jobs/train_ai_model.tsx @@ -1,4 +1,4 @@ -import React, { useState } from "react"; +import React, { useEffect, useState } from "react"; import { Alert, Form, @@ -40,7 +40,7 @@ import { serverVolumeToClientVolumeTracing } from "oxalis/model/reducers/volumet import { convertUserBoundingBoxesFromServerToFrontend } from "oxalis/model/reducers/reducer_helpers"; import { computeArrayFromBoundingBox } from "libs/utils"; import { MagSelectionFormItem } from "components/mag_selection"; -import type { MagInfo } from "oxalis/model/helpers/mag_info"; +import { MagInfo } from "oxalis/model/helpers/mag_info"; const { TextArea } = Input; const FormItem = Form.Item; @@ -167,12 +167,23 @@ export function TrainAiModelTab(); - const [chosenMag, setChosenMag] = useState(); - - const getAvailableMags = (groundTruthLayerName: string, annotationId: string) => { - console.log("getAvailableMags", groundTruthLayerName, annotationId); - setChosenMag(undefined); // TODO_c doesnt work + const [mags, setMags] = useState>(); // maps annotationId to MagInfo + const [groundTruthLayerMags, setGroundTruthLayerMags] = useState(); + const [dataLayerMags, setDataLayerMags] = useState(); + + useEffect(() => { + // TODO make this mag specific + const intersectingMags = groundTruthLayerMags + ?.getMagList() + .filter((mag) => dataLayerMags?.includes(mag)); + console.log("updating", dataLayerMags, groundTruthLayerMags); + setMags(intersectingMags != null ? new MagInfo(intersectingMags) : undefined); + }, [dataLayerMags, groundTruthLayerMags]); + + const getAvailableMagsForGroundTruthLayer = ( + groundTruthLayerName: string, + annotationId: string, + ) => { return getMagsForSegmentationLayer(annotationId, groundTruthLayerName); }; @@ -291,7 +302,9 @@ export function TrainAiModelTab @@ -322,6 +335,12 @@ export function TrainAiModelTab layer.name} fixedLayerName={fixedSelectedColorLayer?.name || undefined} style={{ width: "100%" }} + onChange={(newLayerName) => { + setDataLayerMags( + colorLayers.filter((layer) => layer.name === newLayerName)[0].resolutions, + ); + form.setFieldValue(["trainingAnnotations", idx, "mag"], undefined); + }} /> @@ -332,21 +351,22 @@ export function TrainAiModelTab { return layer.name; + //TODO_c fix that fallback layers are shown at least with the correct name? + // eg. name (fallbacklayer) + // remember to check-in with P }} fixedLayerName={fixedSelectedSegmentationLayer?.name || undefined} label="Ground Truth Layer" onChange={(newLayerName) => { - setMags(getAvailableMags(newLayerName, annotationId)); - setChosenMag(undefined); + setGroundTruthLayerMags( + getAvailableMagsForGroundTruthLayer(newLayerName, annotationId), + ); + form.setFieldValue(["trainingAnnotations", idx, "mag"], undefined); }} /> - + ); @@ -368,31 +388,31 @@ export function TrainAiModelTab ( - - )) + + )) : null} {hasWarnings ? warnings.map((warning) => ( - - )) + + )) : null} @@ -636,10 +656,10 @@ function AnnotationsCsvInput({ return valid ? Promise.resolve() : Promise.reject( - new Error( - "Each line should only contain an annotation ID or URL (without # or ,)", - ), - ); + new Error( + "Each line should only contain an annotation ID or URL (without # or ,)", + ), + ); }, }), ]} From 9011674d2a9c50fb090d5b5647e23011456d37e9 Mon Sep 17 00:00:00 2001 From: Charlie Meister Date: Mon, 16 Dec 2024 13:01:51 +0100 Subject: [PATCH 07/20] select intersection of data and segmentation layer mags --- .../javascripts/components/mag_selection.tsx | 22 +-- .../oxalis/view/jobs/train_ai_model.tsx | 146 +++++++++++------- 2 files changed, 106 insertions(+), 62 deletions(-) diff --git a/frontend/javascripts/components/mag_selection.tsx b/frontend/javascripts/components/mag_selection.tsx index 4acf371b772..37140f9f8f6 100644 --- a/frontend/javascripts/components/mag_selection.tsx +++ b/frontend/javascripts/components/mag_selection.tsx @@ -1,7 +1,6 @@ import { Form, Select } from "antd"; import { V3 } from "libs/mjs"; import { clamp } from "libs/utils"; -import _ from "lodash"; import type { Vector3 } from "oxalis/constants"; import type { MagInfo } from "oxalis/model/helpers/mag_info"; @@ -37,27 +36,32 @@ function MagSelection({ value?: Vector3; onChange?: (a: Vector3) => void; }): JSX.Element { - const allMags = magInfo != null ? magInfo.getMagsWithIndices() : []; + const allMags = magInfo != null ? magInfo.getMagList() : []; + + const onSelect = (index: number | undefined) => { + if (onChange == null || index == null) return; + const newMag = allMags[index]; + if (newMag != null) onChange(newMag); + }; return ( From 0dea8e552265e3ed1164e9d2d6850e844fd611ed Mon Sep 17 00:00:00 2001 From: Charlie Meister Date: Mon, 16 Dec 2024 16:30:57 +0100 Subject: [PATCH 10/20] add changelog --- CHANGELOG.unreleased.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.unreleased.md b/CHANGELOG.unreleased.md index e4e02843cd7..cf99ca81466 100644 --- a/CHANGELOG.unreleased.md +++ b/CHANGELOG.unreleased.md @@ -13,6 +13,7 @@ For upgrade instructions, please check the [migration guide](MIGRATIONS.released ### Added - Added the total volume of a dataset to a tooltip in the dataset info tab. [#8229](https://github.com/scalableminds/webknossos/pull/8229) - Optimized performance of data loading with “fill value“ chunks. [#8271](https://github.com/scalableminds/webknossos/pull/8271) +- It is now possible to select the magnification of the layers on which an AI model will be trained. [#8266](https://github.com/scalableminds/webknossos/pull/8266) ### Changed - Renamed "resolution" to "magnification" in more places within the codebase, including local variables. [#8168](https://github.com/scalableminds/webknossos/pull/8168) From 3f4bcaf27456f2da4ca407760256ed01562d39d4 Mon Sep 17 00:00:00 2001 From: Charlie Meister Date: Mon, 16 Dec 2024 16:58:04 +0100 Subject: [PATCH 11/20] remove dev edits --- .../javascripts/components/mag_selection.tsx | 6 +++--- .../oxalis/view/jobs/train_ai_model.tsx | 19 ++++++------------- 2 files changed, 9 insertions(+), 16 deletions(-) diff --git a/frontend/javascripts/components/mag_selection.tsx b/frontend/javascripts/components/mag_selection.tsx index 37140f9f8f6..965a6848e03 100644 --- a/frontend/javascripts/components/mag_selection.tsx +++ b/frontend/javascripts/components/mag_selection.tsx @@ -34,7 +34,7 @@ function MagSelection({ }: { magInfo: MagInfo | undefined; value?: Vector3; - onChange?: (a: Vector3) => void; + onChange?: (newValue: Vector3) => void; }): JSX.Element { const allMags = magInfo != null ? magInfo.getMagList() : []; @@ -48,8 +48,8 @@ function MagSelection({