schema + asset menu fixes

- configs/machineGroupControl.json: drop prioritypercentagecontrol mode
  (unused — set.demand became unit-self-describing, so percentage-vs-absolute
  is decided per-message, not by a node-wide scaling mode). Add output.process
  / output.dbase enums + functionality.distance{,Unit,Description} so the
  editor's distance offset persists. Fixes the runtime warnings 'Unknown key
  optimization/scaling/movement/curvePressureUnit etc.' the validator was
  logging on every MGC instantiation.
- configs/measurement.json: same output.process/dbase block + nullable
  position.x for the rare case a measurement has no parent yet.
- datasets/assetData/machine.json -> rotatingmachine.json: rename so
  AssetMenu's softwareType lookup matches. AssetMenu.getActiveCategoryKey
  no longer silently falls back to keys[0] (which mis-showed diffuser models
  for rotatingMachine nodes) — returns null with a console.warn instead.
- menu/asset.js: re-derive supplier/assetType from saved model id on reopen.
  The save handler intentionally discards the denormalized registry copies
  to keep the persisted node small, so the cascade dropdown booted at
  'Select...' even when a model was saved. Walk the registry tree to
  reconstitute.
- predict/predict_class.js: minor.
- configs/index.js: minor.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
znetsixe
2026-05-14 22:51:57 +02:00
parent c59da5ca98
commit f8f71a4f1c
7 changed files with 167 additions and 74 deletions

View File

@@ -55,7 +55,17 @@ class AssetMenu {
}
}
return keys[0];
// Previously fell back to keys[0] (alphabetically first category),
// which meant a softwareType mismatch silently showed the wrong asset
// tree — e.g. rotatingMachine (softwareType='rotatingmachine') with
// no matching registry file saw 'diffuser' models in the dropdown.
// Return null so the menu renders empty and the operator sees a clear
// 'No suppliers available' placeholder instead of a wrong category.
console.warn(
`[AssetMenu] No asset category matches softwareType='${this.softwareType}' or nodeName='${nodeName}'. ` +
`Available categories: [${keys.join(', ')}]. Menu will render empty.`
);
return null;
}
getAllMenuData(nodeName) {
@@ -253,6 +263,26 @@ class AssetMenu {
}
const suppliers = activeCategory ? activeCategory.suppliers : [];
// The save handler intentionally discards node.supplier / node.assetType
// (denormalized copies of registry data — only node.model + node.unit
// are persisted identity). So on reopen we re-derive them from the
// saved model id by walking the registry tree. Without this the
// cascade always boots at "Select..." even when a model is saved.
if (node.model && (!node.supplier || !node.assetType)) {
for (const supplier of suppliers) {
const match = (supplier.types || []).find((type) =>
(type.models || []).some((model) =>
String(model.id || model.name) === String(node.model))
);
if (match) {
node.supplier = supplier.id || supplier.name;
node.assetType = match.id || match.name;
break;
}
}
}
populate(
elems.supplier,
suppliers,