From 6758b82c09e8bddd5e325627083f96e19995c0d3 Mon Sep 17 00:00:00 2001 From: Philipp Otto Date: Wed, 9 Nov 2022 11:25:10 +0100 Subject: [PATCH] Fix importing a dataset from disk (#6615) * fix importing a dataset that hasn't got a datasource-properties.json yet * remove unnecessary import * update changelog * fix missing largest segment id input for segmentation layers when importing a dataset from disk without pre-existing datasource-properties.json Co-authored-by: Florian M --- CHANGELOG.unreleased.md | 1 + .../admin/dataset/dataset_add_zarr_view.tsx | 2 +- .../admin/dataset/dataset_components.tsx | 5 ++- .../dataset/dataset_settings_data_tab.tsx | 25 +++++------ .../dataset/dataset_settings_view.tsx | 43 +++++++++++++------ frontend/javascripts/types/api_flow_types.ts | 4 +- 6 files changed, 49 insertions(+), 31 deletions(-) diff --git a/CHANGELOG.unreleased.md b/CHANGELOG.unreleased.md index 597d189c45c..798d5c4bc69 100644 --- a/CHANGELOG.unreleased.md +++ b/CHANGELOG.unreleased.md @@ -26,6 +26,7 @@ For upgrade instructions, please check the [migration guide](MIGRATIONS.released - Re-phrased some backend (error) messages to improve clarity and provide helping hints. [#6616](https://github.com/scalableminds/webknossos/pull/6616) ### Fixed +- Fixed importing a dataset from disk. [#6615](https://github.com/scalableminds/webknossos/pull/6615) ### Removed diff --git a/frontend/javascripts/admin/dataset/dataset_add_zarr_view.tsx b/frontend/javascripts/admin/dataset/dataset_add_zarr_view.tsx index 31dc1ae6edb..06d93f22c16 100644 --- a/frontend/javascripts/admin/dataset/dataset_add_zarr_view.tsx +++ b/frontend/javascripts/admin/dataset/dataset_add_zarr_view.tsx @@ -169,8 +169,8 @@ function DatasetAddZarrView(props: Props) { {/* Only the component's visibility is changed, so that the form is always rendered. This is necessary so that the form's structure is always populated. */} { diff --git a/frontend/javascripts/admin/dataset/dataset_components.tsx b/frontend/javascripts/admin/dataset/dataset_components.tsx index 04bd5210800..4f0e68a1be3 100644 --- a/frontend/javascripts/admin/dataset/dataset_components.tsx +++ b/frontend/javascripts/admin/dataset/dataset_components.tsx @@ -52,7 +52,7 @@ export const layerNameRules = [ export const getDatasetNameRules = ( activeUser: APIUser | null | undefined, - isEditing: boolean = false, + allowRenaming: boolean = true, ) => [ { required: true, @@ -61,7 +61,8 @@ export const getDatasetNameRules = ( ...layerNameRules, { validator: async (_rule: any, value: string) => { - if (isEditing) { + if (!allowRenaming) { + // Renaming is not allowed. No need to validate the (existing) name then. return Promise.resolve(); } if (!activeUser) throw new Error("Can't do operation if no user is logged in."); diff --git a/frontend/javascripts/dashboard/dataset/dataset_settings_data_tab.tsx b/frontend/javascripts/dashboard/dataset/dataset_settings_data_tab.tsx index 400f1a24f19..307a2d62e43 100644 --- a/frontend/javascripts/dashboard/dataset/dataset_settings_data_tab.tsx +++ b/frontend/javascripts/dashboard/dataset/dataset_settings_data_tab.tsx @@ -33,6 +33,7 @@ import { useSelector } from "react-redux"; import { DeleteOutlined } from "@ant-design/icons"; import { APIDataLayer, APIDatasetId } from "types/api_flow_types"; import { useStartAndPollJob } from "admin/job/job_hooks"; +import { Vector3 } from "oxalis/constants"; const FormItem = Form.Item; @@ -62,7 +63,7 @@ export const syncDataSourceFields = ( }; export default function DatasetSettingsDataTab({ - isEditingMode, + allowRenamingDataset, isReadOnlyDataset, form, activeDataSourceEditMode, @@ -70,7 +71,7 @@ export default function DatasetSettingsDataTab({ additionalAlert, datasetId, }: { - isEditingMode: boolean; + allowRenamingDataset: boolean; isReadOnlyDataset: boolean; form: FormInstance; activeDataSourceEditMode: "simple" | "advanced"; @@ -131,7 +132,7 @@ export default function DatasetSettingsDataTab({ ; form: FormInstance; @@ -213,11 +214,11 @@ function SimpleDatasetForm({ label="Name" info="The name of the dataset" validateFirst - rules={getDatasetNameRules(activeUser, isEditingMode)} + rules={getDatasetNameRules(activeUser, allowRenamingDataset)} > value && value.every((el) => el > 0), + (value: Vector3) => value && value.every((el) => el > 0), "Each component of the scale must be greater than 0", ), }, @@ -504,8 +504,7 @@ function SimpleLayerForm({ - {/* The in-condition is only necessary to satisfy TypeScript */} - {isSegmentation && "largestSegmentId" in layer ? ( + {isSegmentation ? (
; hasNoAllowedTeams: boolean; @@ -110,25 +111,35 @@ export type FormData = { }; function ensureValidScaleOnInferredDataSource( - savedDataSourceOnServer: APIDataSource | null | undefined, + savedDataSourceOnServer: APIDataSource | APIUnimportedDatasource | null | undefined, inferredDataSource: APIDataSource | null | undefined, ): APIDataSource | null | undefined { if (savedDataSourceOnServer == null || inferredDataSource == null) { // If one of the data sources is null, return the other. - return savedDataSourceOnServer || inferredDataSource; + const potentialSource = savedDataSourceOnServer || inferredDataSource; + if (potentialSource && "dataLayers" in potentialSource) { + return potentialSource; + } else { + return null; + } } const inferredDataSourceClone = _.cloneDeep(inferredDataSource) as any as MutableAPIDataSource; - if ( - _.isEqual(inferredDataSource.scale, [0, 0, 0]) && - !_.isEqual(savedDataSourceOnServer.scale, [0, 0, 0]) - ) { - inferredDataSourceClone.scale = savedDataSourceOnServer.scale; + const savedScale = + "dataLayers" in savedDataSourceOnServer + ? savedDataSourceOnServer.scale + : ([0, 0, 0] as Vector3); + if (_.isEqual(inferredDataSource.scale, [0, 0, 0]) && !_.isEqual(savedScale, [0, 0, 0])) { + inferredDataSourceClone.scale = savedScale; } // Trying to use the saved value for largestSegmentId instead of 0. - if (savedDataSourceOnServer.dataLayers != null && inferredDataSourceClone.dataLayers != null) { + if ( + "dataLayers" in savedDataSourceOnServer && + savedDataSourceOnServer.dataLayers != null && + inferredDataSourceClone.dataLayers != null + ) { const segmentationLayerSettings = inferredDataSourceClone.dataLayers.find( (layer) => layer.category === "segmentation", ); @@ -250,7 +261,11 @@ class DatasetSettingsView extends React.PureComponent The current datasource-properties.json on the server seems to be in an invalid JSON format - and webKnossos could not parse this file. The settings below are suggested by webKnossos - and should be adjusted.
+ (or is missing completely). The settings below are suggested by webKnossos and should be + adjusted.
Be aware that webKnossos cannot guess properties like the voxel size or the largest segment id. You must set them yourself.
@@ -854,7 +869,7 @@ class DatasetSettingsView extends React.PureComponent; -type APIUnimportedDatasource = APIDataSourceBase; +export type APIUnimportedDatasource = APIDataSourceBase; export type MutableAPIDataSource = MutableAPIDataSourceBase & { dataLayers: Array; scale: Vector3; @@ -148,7 +148,7 @@ type APIUnimportedDataset = APIDatasetBase & { export type APIMaybeUnimportedDataset = APIUnimportedDataset | APIDataset; export type APIDataSourceWithMessages = { readonly dataSource?: APIDataSource; - readonly previousDataSource?: APIDataSource; + readonly previousDataSource?: APIDataSource | APIUnimportedDatasource; readonly messages: Array; }; export type APITeamMembership = {