From 6b01e09c22dcf813d7b5f1bc5b0051084c9e0bd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20B=C3=BC=C3=9Femeyer?= Date: Wed, 27 Nov 2024 17:39:18 +0100 Subject: [PATCH 1/7] allow dollar in layer and dataset name --- frontend/javascripts/admin/dataset/dataset_components.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/javascripts/admin/dataset/dataset_components.tsx b/frontend/javascripts/admin/dataset/dataset_components.tsx index ccbe40d7a3..6dbec1cdef 100644 --- a/frontend/javascripts/admin/dataset/dataset_components.tsx +++ b/frontend/javascripts/admin/dataset/dataset_components.tsx @@ -41,8 +41,8 @@ export const layerNameRules = [ }, // Note that these rules are also checked by the backend { - pattern: /^[0-9a-zA-Z_.-]+$/, - message: "Only letters, digits and the following characters are allowed: . _ -", + pattern: /^[0-9a-zA-Z_.\-$.]+$/, + message: "Only letters, digits and the following characters are allowed: . _ - $", }, { validator: syncValidator( From 69d9d793791a428777b916536c507de575e956ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20B=C3=BC=C3=9Femeyer?= Date: Mon, 2 Dec 2024 18:13:13 +0100 Subject: [PATCH 2/7] only allow $ layer names, not dataset names --- .../admin/dataset/dataset_components.tsx | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/frontend/javascripts/admin/dataset/dataset_components.tsx b/frontend/javascripts/admin/dataset/dataset_components.tsx index 6dbec1cdef..d6348b4694 100644 --- a/frontend/javascripts/admin/dataset/dataset_components.tsx +++ b/frontend/javascripts/admin/dataset/dataset_components.tsx @@ -35,15 +35,10 @@ export function CardContainer({ ); } } -export const layerNameRules = [ +const sharedRules = [ { min: 1, }, - // Note that these rules are also checked by the backend - { - pattern: /^[0-9a-zA-Z_.\-$.]+$/, - message: "Only letters, digits and the following characters are allowed: . _ - $", - }, { validator: syncValidator( (value: string | null) => !value || !value.startsWith("."), @@ -52,6 +47,14 @@ export const layerNameRules = [ }, ]; +export const layerNameRules = [ + ...sharedRules, + { + pattern: /^[0-9a-zA-Z_.\-$.]+$/, + message: "Only letters, digits and the following characters are allowed: . _ - $", + }, +]; + export const getDatasetNameRules = (activeUser: APIUser | null | undefined) => [ { required: true, @@ -59,6 +62,10 @@ export const getDatasetNameRules = (activeUser: APIUser | null | undefined) => [ }, { min: 3, message: messages["dataset.name_length"] }, ...layerNameRules, + { + pattern: /^[0-9a-zA-Z_.-]+$/, + message: "Only letters, digits and the following characters are allowed: . _ -", + }, { validator: async () => { if (!activeUser) throw new Error("Can't do operation if no user is logged in."); From 6ae0c67d28a0ca5f744c2fdb740eb8c17ed6abd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20B=C3=BC=C3=9Femeyer?= Date: Tue, 3 Dec 2024 10:59:58 +0100 Subject: [PATCH 3/7] add changelog entry --- CHANGELOG.unreleased.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.unreleased.md b/CHANGELOG.unreleased.md index 8a3c9a0f3d..fa80ed5207 100644 --- a/CHANGELOG.unreleased.md +++ b/CHANGELOG.unreleased.md @@ -17,6 +17,7 @@ For upgrade instructions, please check the [migration guide](MIGRATIONS.released ### Changed - Renamed "resolution" to "magnification" in more places within the codebase, including local variables. [#8168](https://github.com/scalableminds/webknossos/pull/8168) - Reading image files on datastore filesystem is now done asynchronously. [#8126](https://github.com/scalableminds/webknossos/pull/8126) +- Layer names are now allowed to contain `$` as special characters. [#8241](https://github.com/scalableminds/webknossos/pull/8241) - Datasets can now be renamed and can have duplicate names. [#8075](https://github.com/scalableminds/webknossos/pull/8075) - Improved error messages for starting jobs on datasets from other organizations. [#8181](https://github.com/scalableminds/webknossos/pull/8181) - Terms of Service for Webknossos are now accepted at registration, not afterward. [#8193](https://github.com/scalableminds/webknossos/pull/8193) From 3fd9ef69c4aa9518839c2a46c9867934e380c294 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20B=C3=BC=C3=9Femeyer?= Date: Thu, 5 Dec 2024 17:16:08 +0100 Subject: [PATCH 4/7] allow $ in annotation layer names --- conf/evolutions/125-allow-dollar-in-layer-names.sql | 11 +++++++++++ .../reversions/125-allow-dollar-in-layer-names.sql | 11 +++++++++++ .../modals/add_volume_layer_modal.tsx | 2 +- tools/postgres/schema.sql | 4 ++-- 4 files changed, 25 insertions(+), 3 deletions(-) create mode 100644 conf/evolutions/125-allow-dollar-in-layer-names.sql create mode 100644 conf/evolutions/reversions/125-allow-dollar-in-layer-names.sql diff --git a/conf/evolutions/125-allow-dollar-in-layer-names.sql b/conf/evolutions/125-allow-dollar-in-layer-names.sql new file mode 100644 index 0000000000..5600a13d85 --- /dev/null +++ b/conf/evolutions/125-allow-dollar-in-layer-names.sql @@ -0,0 +1,11 @@ +START TRANSACTION; + +do $$ begin ASSERT (select schemaVersion from webknossos.releaseInformation) = 124, 'Previous schema version mismatch'; end; $$ LANGUAGE plpgsql; + + +ALTER TABLE webknossos.annotation_layers DROP CONSTRAINT IF EXISTS annotation_layers_name_check; +ALTER TABLE webknossos.annotation_layers ADD CONSTRAINT annotation_layers_name_check CHECK (name ~* '^[A-Za-z0-9\-_\.\$]+$'); + +UPDATE webknossos.releaseInformation SET schemaVersion = 125; + +COMMIT TRANSACTION; diff --git a/conf/evolutions/reversions/125-allow-dollar-in-layer-names.sql b/conf/evolutions/reversions/125-allow-dollar-in-layer-names.sql new file mode 100644 index 0000000000..f357f3cc6d --- /dev/null +++ b/conf/evolutions/reversions/125-allow-dollar-in-layer-names.sql @@ -0,0 +1,11 @@ +START TRANSACTION; + +-- This reversion might take a while because it needs to search in all annotation layer names for '$' and replace it with '' +do $$ begin ASSERT (select schemaVersion from webknossos.releaseInformation) = 125, 'Previous schema version mismatch'; end; $$ LANGUAGE plpgsql; + +UPDATE webknossos.annotation_layers SET name = regexp_replace(name, '\$', '', 'g') WHERE name ~* '\$'; + +ALTER TABLE webknossos.annotation_layers DROP CONSTRAINT IF EXISTS annotation_layers_name_check; +ALTER TABLE webknossos.annotation_layers ADD CONSTRAINT annotation_layers_name_check CHECK (name ~* '^[A-Za-z0-9\-_\.]+$'); + +COMMIT TRANSACTION; diff --git a/frontend/javascripts/oxalis/view/left-border-tabs/modals/add_volume_layer_modal.tsx b/frontend/javascripts/oxalis/view/left-border-tabs/modals/add_volume_layer_modal.tsx index 29cf3d02ad..06fbb371a5 100644 --- a/frontend/javascripts/oxalis/view/left-border-tabs/modals/add_volume_layer_modal.tsx +++ b/frontend/javascripts/oxalis/view/left-border-tabs/modals/add_volume_layer_modal.tsx @@ -48,7 +48,7 @@ export function checkLayerNameForInvalidCharacters(readableLayerName: string): V message: messages["tracing.volume_layer_name_starts_with_dot"], }; } - const uriSafeCharactersRegex = /[0-9a-zA-Z-._]+/g; + const uriSafeCharactersRegex = /[0-9a-zA-Z-._$]+/g; // Removing all URISaveCharacters from readableLayerName. The leftover chars are all invalid. const allInvalidChars = readableLayerName.replace(uriSafeCharactersRegex, ""); const allUniqueInvalidCharsAsSet = new Set(allInvalidChars); diff --git a/tools/postgres/schema.sql b/tools/postgres/schema.sql index 1cceca2f1b..ed5c00bf4d 100644 --- a/tools/postgres/schema.sql +++ b/tools/postgres/schema.sql @@ -20,7 +20,7 @@ CREATE TABLE webknossos.releaseInformation ( schemaVersion BIGINT NOT NULL ); -INSERT INTO webknossos.releaseInformation(schemaVersion) values(124); +INSERT INTO webknossos.releaseInformation(schemaVersion) values(125); COMMIT TRANSACTION; @@ -56,7 +56,7 @@ CREATE TABLE webknossos.annotation_layers( _annotation CHAR(24) NOT NULL, tracingId CHAR(36) NOT NULL UNIQUE, typ webknossos.ANNOTATION_LAYER_TYPE NOT NULL, - name VARCHAR(256) NOT NULL CHECK (name ~* '^[A-Za-z0-9\-_\.]+$'), + name VARCHAR(256) NOT NULL CHECK (name ~* '^[A-Za-z0-9\-_\.\$]+$'), statistics JSONB NOT NULL, UNIQUE (name, _annotation), PRIMARY KEY (_annotation, tracingId), From 6149a054d96204c521dc686ee6838f2176fa87bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20B=C3=BC=C3=9Femeyer?= Date: Fri, 6 Dec 2024 09:47:54 +0100 Subject: [PATCH 5/7] add schema version reversion to db reversion & rename var --- .../evolutions/reversions/125-allow-dollar-in-layer-names.sql | 2 ++ .../view/left-border-tabs/modals/add_volume_layer_modal.tsx | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/conf/evolutions/reversions/125-allow-dollar-in-layer-names.sql b/conf/evolutions/reversions/125-allow-dollar-in-layer-names.sql index f357f3cc6d..cff9aa20a7 100644 --- a/conf/evolutions/reversions/125-allow-dollar-in-layer-names.sql +++ b/conf/evolutions/reversions/125-allow-dollar-in-layer-names.sql @@ -8,4 +8,6 @@ UPDATE webknossos.annotation_layers SET name = regexp_replace(name, '\$', '', 'g ALTER TABLE webknossos.annotation_layers DROP CONSTRAINT IF EXISTS annotation_layers_name_check; ALTER TABLE webknossos.annotation_layers ADD CONSTRAINT annotation_layers_name_check CHECK (name ~* '^[A-Za-z0-9\-_\.]+$'); +UPDATE webknossos.releaseInformation SET schemaVersion = 124; + COMMIT TRANSACTION; diff --git a/frontend/javascripts/oxalis/view/left-border-tabs/modals/add_volume_layer_modal.tsx b/frontend/javascripts/oxalis/view/left-border-tabs/modals/add_volume_layer_modal.tsx index 06fbb371a5..fad6a364a5 100644 --- a/frontend/javascripts/oxalis/view/left-border-tabs/modals/add_volume_layer_modal.tsx +++ b/frontend/javascripts/oxalis/view/left-border-tabs/modals/add_volume_layer_modal.tsx @@ -48,9 +48,9 @@ export function checkLayerNameForInvalidCharacters(readableLayerName: string): V message: messages["tracing.volume_layer_name_starts_with_dot"], }; } - const uriSafeCharactersRegex = /[0-9a-zA-Z-._$]+/g; + const validLayerNameCharactersRegex = /[0-9a-zA-Z-._$]+/g; // Removing all URISaveCharacters from readableLayerName. The leftover chars are all invalid. - const allInvalidChars = readableLayerName.replace(uriSafeCharactersRegex, ""); + const allInvalidChars = readableLayerName.replace(validLayerNameCharactersRegex, ""); const allUniqueInvalidCharsAsSet = new Set(allInvalidChars); const allUniqueInvalidCharsAsString = "".concat(...allUniqueInvalidCharsAsSet.values()); const isValid = allUniqueInvalidCharsAsString.length === 0; From 6f58f26256efe5eaf4820b329e886e1bd5e8a6c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20B=C3=BC=C3=9Femeyer?= Date: Fri, 6 Dec 2024 11:14:00 +0100 Subject: [PATCH 6/7] fix dataset setting form validation errors --- .../dataset/dataset_settings_data_tab.tsx | 5 +++-- .../dashboard/dataset/dataset_settings_view.tsx | 16 +++++++++++----- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/frontend/javascripts/dashboard/dataset/dataset_settings_data_tab.tsx b/frontend/javascripts/dashboard/dataset/dataset_settings_data_tab.tsx index 2650c4e136..e8bbe2aee2 100644 --- a/frontend/javascripts/dashboard/dataset/dataset_settings_data_tab.tsx +++ b/frontend/javascripts/dashboard/dataset/dataset_settings_data_tab.tsx @@ -398,8 +398,9 @@ function SimpleLayerForm({ { validator: syncValidator( (value: string) => - dataLayers.filter((someLayer: APIDataLayer) => someLayer.name === value) - .length <= 1, + form + .getFieldValue(["dataSource", "dataLayers"]) + .filter((someLayer: APIDataLayer) => someLayer.name === value).length <= 1, "Layer names must be unique.", ), }, diff --git a/frontend/javascripts/dashboard/dataset/dataset_settings_view.tsx b/frontend/javascripts/dashboard/dataset/dataset_settings_view.tsx index 4962055491..18552df7a7 100644 --- a/frontend/javascripts/dashboard/dataset/dataset_settings_view.tsx +++ b/frontend/javascripts/dashboard/dataset/dataset_settings_view.tsx @@ -339,12 +339,18 @@ class DatasetSettingsView extends React.PureComponent + const afterForceUpdateCallback = () => { // Trigger validation manually, because fields may have been updated - form - .validateFields() - .then((formValues) => this.submit(formValues)) - .catch((errorInfo) => this.handleValidationFailed(errorInfo)); + // and defer the validation as it is done asynchronously by antd or so. + setTimeout( + () => + form + .validateFields() + .then((formValues) => this.submit(formValues)) + .catch((errorInfo) => this.handleValidationFailed(errorInfo)), + 1, + ); + }; // Need to force update of the SimpleAdvancedDataForm as removing a layer in the advanced tab does not update // the form items in the simple tab (only the values are updated). The form items automatically update once From 6e41c813f15f568c6024e3034b8de00694e4f15c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20B=C3=BC=C3=9Femeyer?= Date: Fri, 6 Dec 2024 11:21:34 +0100 Subject: [PATCH 7/7] set timeout fixing form validation error to 0 ms --- .../javascripts/dashboard/dataset/dataset_settings_view.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/javascripts/dashboard/dataset/dataset_settings_view.tsx b/frontend/javascripts/dashboard/dataset/dataset_settings_view.tsx index 18552df7a7..da35dcef14 100644 --- a/frontend/javascripts/dashboard/dataset/dataset_settings_view.tsx +++ b/frontend/javascripts/dashboard/dataset/dataset_settings_view.tsx @@ -348,7 +348,7 @@ class DatasetSettingsView extends React.PureComponent this.submit(formValues)) .catch((errorInfo) => this.handleValidationFailed(errorInfo)), - 1, + 0, ); };