diff --git a/pyflask/manageNeuroconv/manage_neuroconv.py b/pyflask/manageNeuroconv/manage_neuroconv.py
index e6d2fabc9..27727640b 100644
--- a/pyflask/manageNeuroconv/manage_neuroconv.py
+++ b/pyflask/manageNeuroconv/manage_neuroconv.py
@@ -258,7 +258,11 @@ def get_metadata_schema(source_data: Dict[str, dict], interfaces: dict) -> Dict[
"""Function used to fetch the metadata schema from a CustomNWBConverter instantiated from the source_data."""
from neuroconv.utils import NWBMetaDataEncoder
- converter = instantiate_custom_converter(source_data, interfaces)
+ resolved_source_data = replace_none_with_nan(
+ source_data, resolve_references(get_custom_converter(interfaces).get_source_schema())
+ )
+
+ converter = instantiate_custom_converter(resolved_source_data, interfaces)
schema = converter.get_metadata_schema()
metadata = converter.get_metadata()
@@ -423,7 +427,11 @@ def convert_to_nwb(info: dict) -> str:
resolved_output_path.parent.mkdir(exist_ok=True, parents=True) # Ensure all parent directories exist
- converter = instantiate_custom_converter(info["source_data"], info["interfaces"])
+ resolved_source_data = replace_none_with_nan(
+ info["source_data"], resolve_references(get_custom_converter(info["interfaces"]).get_source_schema())
+ )
+
+ converter = instantiate_custom_converter(resolved_source_data, info["interfaces"])
def update_conversion_progress(**kwargs):
announcer.announce(dict(**kwargs, nwbfile_path=nwbfile_path), "conversion_progress")
diff --git a/src/renderer/src/stories/JSONSchemaForm.js b/src/renderer/src/stories/JSONSchemaForm.js
index 36060fd91..c7e4d865f 100644
--- a/src/renderer/src/stories/JSONSchemaForm.js
+++ b/src/renderer/src/stories/JSONSchemaForm.js
@@ -23,7 +23,7 @@ const encode = (str) => {
const additionalPropPattern = "additional";
-const provideNaNMessage = `
Type NaN to represent an unknown value.`;
+const templateNaNMessage = `
Type NaN to represent an unknown value.`;
import { Validator } from "jsonschema";
import { successHue, warningHue, errorHue } from "./globals";
@@ -378,8 +378,8 @@ export class JSONSchemaForm extends LitElement {
throw new Error(message);
};
- validateSchema = async (resolved, schema, name) => {
- return await validator
+ validateSchema = (resolved, schema, name) => {
+ return validator
.validate(resolved, schema)
.errors.map((e) => {
const propName = e.path.slice(-1)[0] ?? name ?? e.property;
@@ -399,8 +399,8 @@ export class JSONSchemaForm extends LitElement {
// Allow referring to floats as null (i.e. JSON NaN representation)
if (e.message === "is not of a type(s) number") {
- if (resolvedValue === "NaN") return;
- else e.message = `${e.message}. ${provideNaNMessage}`;
+ if ((resolvedValue === "NaN") | (resolvedValue === null)) return;
+ else if (isRow) e.message = `${e.message}. ${templateNaNMessage}`;
}
const prevHeader = name ? header(name) : "Row";
@@ -422,7 +422,7 @@ export class JSONSchemaForm extends LitElement {
const copy = structuredClone(resolved);
delete copy.__disabled;
- const result = await this.validateSchema(copy, this.schema);
+ const result = this.validateSchema(copy, this.schema);
const resolvedErrors = this.#resolveErrors(result, this.base, resolved);
@@ -815,7 +815,7 @@ export class JSONSchemaForm extends LitElement {
const skipValidation = !this.validateEmptyValues && value === undefined;
const validateArgs = input.pattern || skipValidation ? [] : [value, schema];
- const jsonSchemaErrors = validateArgs.length === 2 ? await this.validateSchema(...validateArgs, name) : [];
+ const jsonSchemaErrors = validateArgs.length === 2 ? this.validateSchema(...validateArgs, name) : [];
const valid = skipValidation ? true : await this.validateOnChange(name, parent, pathToValidate, value);
@@ -860,9 +860,16 @@ export class JSONSchemaForm extends LitElement {
// Throw at least a basic warning if a non-linked property is required and missing
if (!hasLinks && isRequired) {
if (this.validateEmptyValues) {
+ const rowName = pathToValidate.slice(-1)[0];
+ const isRow = typeof rowName === "number";
+
errors.push({
message: `${schema.title ?? header(name)} ${this.#isARequiredPropertyString}. ${
- schema.type === "number" ? provideNaNMessage : ""
+ schema.type === "number"
+ ? isRow
+ ? templateNaNMessage
+ : "
Use the 'I Don't Know' checkbox if unsure."
+ : ""
}`,
type: "error",
missing: true,
diff --git a/src/renderer/src/stories/JSONSchemaInput.js b/src/renderer/src/stories/JSONSchemaInput.js
index 3c61f412b..aae940a4b 100644
--- a/src/renderer/src/stories/JSONSchemaInput.js
+++ b/src/renderer/src/stories/JSONSchemaInput.js
@@ -435,7 +435,7 @@ export class JSONSchemaInput extends LitElement {
white-space: nowrap;
}
- .nan-handler label {
+ .nan-handler span {
margin-left: 5px;
font-size: 12px;
}
@@ -1074,12 +1074,14 @@ export class JSONSchemaInput extends LitElement {
// const isBlank = value === '';
- if (isInteger) newValue = parseInt(value);
- else if (isNumber) newValue = parseFloat(value);
+ if (isInteger) value = newValue = parseInt(value);
+ else if (isNumber) value = newValue = parseFloat(value);
if (isNumber) {
if ("min" in schema && newValue < schema.min) newValue = schema.min;
else if ("max" in schema && newValue > schema.max) newValue = schema.max;
+
+ if (isNaN(newValue)) newValue = undefined;
}
if (schema.transform) newValue = schema.transform(newValue, this.value, schema);
@@ -1090,7 +1092,7 @@ export class JSONSchemaInput extends LitElement {
// if (!regex.test(isNaN(newValue) ? value : newValue)) newValue = this.value // revert to last value
// }
- if (!isNaN(newValue) && newValue !== value) {
+ if (isNumber && newValue !== value) {
ev.target.value = newValue;
value = newValue;
}
@@ -1108,19 +1110,20 @@ export class JSONSchemaInput extends LitElement {
${isRequiredNumber
? html`