diff --git a/dist/js/context/providers/PointsGrid/PointsGridFormDataProvider.d.ts b/dist/js/context/providers/PointsGrid/PointsGridFormDataProvider.d.ts index bb1d3908..019c3afe 100644 --- a/dist/js/context/providers/PointsGrid/PointsGridFormDataProvider.d.ts +++ b/dist/js/context/providers/PointsGrid/PointsGridFormDataProvider.d.ts @@ -33,6 +33,9 @@ declare abstract class PointsGridFormDataProvider exte private initInstanceFields; private getDefaultGridMetricValue; private resolveGridMetricValue; + /** Keep gridMetricValue and dimensions consistent (both preferGridMetric modes). */ + private dataWithEffectiveGridMetric; + private applyGridMetricInstanceFields; getData(): Data; getDefaultData(): PointsGridDataProviderSchema; protected get jsonSchemaPatchConfig(): { diff --git a/dist/js/context/providers/PointsGrid/PointsGridFormDataProvider.js b/dist/js/context/providers/PointsGrid/PointsGridFormDataProvider.js index c9e345e9..d6c4dbe1 100644 --- a/dist/js/context/providers/PointsGrid/PointsGridFormDataProvider.js +++ b/dist/js/context/providers/PointsGrid/PointsGridFormDataProvider.js @@ -68,18 +68,39 @@ class PointsGridFormDataProvider extends JSONSchemaFormDataProvider_1.default { const isValid = gridMetricType === "KPPRA" ? gridMetricValue >= 1 : gridMetricValue > 0; return isValid ? gridMetricValue : this.getDefaultGridMetricValue(gridMetricType); } - getData() { - const data = super.getData(); - const { preferGridMetric, gridMetricType, gridMetricValue } = data; - if (!preferGridMetric || !gridMetricType) { - return data; + /** Keep gridMetricValue and dimensions consistent (both preferGridMetric modes). */ + dataWithEffectiveGridMetric(data) { + const { preferGridMetric, gridMetricType, gridMetricValue, dimensions } = data; + if (preferGridMetric && gridMetricType) { + const effectiveValue = this.resolveGridMetricValue(gridMetricType, gridMetricValue); + return { + ...data, + gridMetricValue: effectiveValue, + dimensions: this.calculateDimensions(gridMetricType, effectiveValue), + }; } - const effectiveValue = this.resolveGridMetricValue(gridMetricType, gridMetricValue); - return { - ...data, - gridMetricValue: effectiveValue, - dimensions: this.calculateDimensions(gridMetricType, effectiveValue), - }; + if (!preferGridMetric && gridMetricType && dimensions.every((d) => typeof d === "number")) { + return { + ...data, + gridMetricValue: this.calculateGridMetric(gridMetricType, dimensions), + }; + } + return data; + } + applyGridMetricInstanceFields(data) { + const { gridMetricType, preferGridMetric, gridMetricValue } = data; + if (preferGridMetric !== undefined) { + this.preferGridMetric = preferGridMetric; + } + if (gridMetricType !== undefined) { + this.gridMetricType = gridMetricType; + } + if (gridMetricValue !== undefined) { + this.gridMetricValue = gridMetricValue; + } + } + getData() { + return this.dataWithEffectiveGridMetric(super.getData()); } getDefaultData() { const defaultData = { @@ -236,34 +257,9 @@ class PointsGridFormDataProvider extends JSONSchemaFormDataProvider_1.default { } } setData(data) { - const { dimensions, gridMetricType, preferGridMetric, gridMetricValue } = data; - if (preferGridMetric !== undefined) { - this.preferGridMetric = preferGridMetric; - } - if (gridMetricType !== undefined) { - this.gridMetricType = gridMetricType; - } - if (preferGridMetric && gridMetricType) { - const effectiveValue = this.resolveGridMetricValue(gridMetricType, gridMetricValue); - this.gridMetricValue = effectiveValue; - return super.setData({ - ...data, - gridMetricValue: effectiveValue, - dimensions: this.calculateDimensions(gridMetricType, effectiveValue), - }); - } - if (!preferGridMetric && dimensions.every((d) => typeof d === "number")) { - const derivedMetric = this.calculateGridMetric(gridMetricType, dimensions); - this.gridMetricValue = derivedMetric; - return super.setData({ - ...data, - gridMetricValue: derivedMetric, - }); - } - if (gridMetricValue !== undefined) { - this.gridMetricValue = gridMetricValue; - } - return super.setData(data); + const synced = this.dataWithEffectiveGridMetric(data); + this.applyGridMetricInstanceFields(synced); + return super.setData(synced); } } (0, MaterialContextMixin_1.default)(PointsGridFormDataProvider.prototype); diff --git a/dist/js/context/providers/PointsGrid/kgridPrecision.d.ts b/dist/js/context/providers/PointsGrid/kgridPrecision.d.ts new file mode 100644 index 00000000..c74cd3cb --- /dev/null +++ b/dist/js/context/providers/PointsGrid/kgridPrecision.d.ts @@ -0,0 +1,12 @@ +import type { PointsGridDataProviderSchema } from "@mat3ra/esse/dist/js/types"; +import type { MaterialExternalContext } from "../../mixins/MaterialContextMixin"; +type UnitContext = Array<{ + name?: string; + data?: PointsGridDataProviderSchema; +}> | unknown; +export declare function getKgridDataFromUnitContext(context: UnitContext): PointsGridDataProviderSchema | undefined; +export declare function getEffectiveKgridPrecision(kgridData: PointsGridDataProviderSchema, externalContext: MaterialExternalContext): { + value: number; + metric: NonNullable; +}; +export {}; diff --git a/dist/js/context/providers/PointsGrid/kgridPrecision.js b/dist/js/context/providers/PointsGrid/kgridPrecision.js new file mode 100644 index 00000000..5e075f44 --- /dev/null +++ b/dist/js/context/providers/PointsGrid/kgridPrecision.js @@ -0,0 +1,31 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.getKgridDataFromUnitContext = getKgridDataFromUnitContext; +exports.getEffectiveKgridPrecision = getEffectiveKgridPrecision; +const KGridFormDataManager_1 = __importDefault(require("./KGridFormDataManager")); +function getKgridDataFromUnitContext(context) { + if (!context) { + return undefined; + } + if (Array.isArray(context)) { + const item = context.find((entry) => (entry === null || entry === void 0 ? void 0 : entry.name) === "kgrid"); + return item === null || item === void 0 ? void 0 : item.data; + } + if (typeof context === "object" && context !== null && "kgrid" in context) { + return context.kgrid; + } + return undefined; +} +function getEffectiveKgridPrecision(kgridData, externalContext) { + var _a, _b; + const provider = new KGridFormDataManager_1.default({ name: "kgrid", data: kgridData }, externalContext); + provider.setData(provider.getData()); + const normalized = provider.getData(); + return { + value: (_a = normalized.gridMetricValue) !== null && _a !== void 0 ? _a : -1, + metric: (_b = normalized.gridMetricType) !== null && _b !== void 0 ? _b : "KPPRA", + }; +} diff --git a/dist/js/context/providers/base/ContextProvider.d.ts b/dist/js/context/providers/base/ContextProvider.d.ts index eb15e835..351f59e4 100644 --- a/dist/js/context/providers/base/ContextProvider.d.ts +++ b/dist/js/context/providers/base/ContextProvider.d.ts @@ -58,6 +58,8 @@ DataForRendering = S["data"]> { setIsEdited(isEdited: boolean): void; getData(): S["data"]; setData(data: S["data"]): void; + /** Re-run `setData` normalization before persisting (e.g. derive grid metric from dimensions). */ + syncPersistentData(): void; /** * Derive template-facing `data` from persisted `data`. Override when the template needs fields * that must not be stored (e.g. coordinates from symmetry point names + lattice). diff --git a/dist/js/context/providers/base/ContextProvider.js b/dist/js/context/providers/base/ContextProvider.js index 133fbaa0..e553a987 100644 --- a/dist/js/context/providers/base/ContextProvider.js +++ b/dist/js/context/providers/base/ContextProvider.js @@ -50,6 +50,10 @@ class ContextProvider { setData(data) { this.data = utils_1.Utils.clone.deepClone(data); } + /** Re-run `setData` normalization before persisting (e.g. derive grid metric from dimensions). */ + syncPersistentData() { + this.setData(this.getData()); + } /** * Derive template-facing `data` from persisted `data`. Override when the template needs fields * that must not be stored (e.g. coordinates from symmetry point names + lattice). diff --git a/dist/js/units/ExecutionUnit.js b/dist/js/units/ExecutionUnit.js index 4cabca63..b5296c27 100644 --- a/dist/js/units/ExecutionUnit.js +++ b/dist/js/units/ExecutionUnit.js @@ -11,6 +11,8 @@ const enums_1 = require("../enums"); const ExecutionUnitSchemaMixin_1 = require("../generated/ExecutionUnitSchemaMixin"); const BaseUnit_1 = __importDefault(require("./BaseUnit")); const ExecutionUnitInput_1 = __importDefault(require("./ExecutionUnitInput")); +/** Context items always serialized on the unit so rupy can store them in scope after execution. */ +const CONTEXT_SCOPE_ITEMS = new Set(["kgrid"]); class ExecutionUnit extends BaseUnit_1.default { static get jsonSchema() { return JSONSchemasInterface_1.default.getSchemaById("workflow/unit/execution"); @@ -147,8 +149,11 @@ class ExecutionUnit extends BaseUnit_1.default { }); } savePersistentContext() { + this.contextProvidersInstances + .filter((p) => CONTEXT_SCOPE_ITEMS.has(p.name)) + .forEach((p) => p.syncPersistentData()); const persistentItems = this.contextProvidersInstances.map((p) => p.getContextItemData()); - this.context = persistentItems.filter((c) => c.isEdited); + this.context = persistentItems.filter((c) => c.isEdited || CONTEXT_SCOPE_ITEMS.has(c.name)); } saveRenderingContext(externalContext) { const renderingItems = this.contextProvidersInstances.map((p) => p.getContextItemDataForRendering()); diff --git a/src/js/context/providers/PointsGrid/PointsGridFormDataProvider.ts b/src/js/context/providers/PointsGrid/PointsGridFormDataProvider.ts index 386cd37b..467f3270 100644 --- a/src/js/context/providers/PointsGrid/PointsGridFormDataProvider.ts +++ b/src/js/context/providers/PointsGrid/PointsGridFormDataProvider.ts @@ -134,21 +134,44 @@ abstract class PointsGridFormDataProvider< return isValid ? gridMetricValue : this.getDefaultGridMetricValue(gridMetricType); } - getData(): Data { - const data = super.getData(); - const { preferGridMetric, gridMetricType, gridMetricValue } = data; + /** Keep gridMetricValue and dimensions consistent (both preferGridMetric modes). */ + private dataWithEffectiveGridMetric(data: Data): Data { + const { preferGridMetric, gridMetricType, gridMetricValue, dimensions } = data; - if (!preferGridMetric || !gridMetricType) { - return data; + if (preferGridMetric && gridMetricType) { + const effectiveValue = this.resolveGridMetricValue(gridMetricType, gridMetricValue); + return { + ...data, + gridMetricValue: effectiveValue, + dimensions: this.calculateDimensions(gridMetricType, effectiveValue), + }; } - const effectiveValue = this.resolveGridMetricValue(gridMetricType, gridMetricValue); + if (!preferGridMetric && gridMetricType && dimensions.every((d) => typeof d === "number")) { + return { + ...data, + gridMetricValue: this.calculateGridMetric(gridMetricType, dimensions), + }; + } - return { - ...data, - gridMetricValue: effectiveValue, - dimensions: this.calculateDimensions(gridMetricType, effectiveValue), - }; + return data; + } + + private applyGridMetricInstanceFields(data: Data) { + const { gridMetricType, preferGridMetric, gridMetricValue } = data; + if (preferGridMetric !== undefined) { + this.preferGridMetric = preferGridMetric; + } + if (gridMetricType !== undefined) { + this.gridMetricType = gridMetricType; + } + if (gridMetricValue !== undefined) { + this.gridMetricValue = gridMetricValue; + } + } + + getData(): Data { + return this.dataWithEffectiveGridMetric(super.getData()); } getDefaultData() { @@ -328,41 +351,9 @@ abstract class PointsGridFormDataProvider< } setData(data: Data) { - const { dimensions, gridMetricType, preferGridMetric, gridMetricValue } = data; - - if (preferGridMetric !== undefined) { - this.preferGridMetric = preferGridMetric; - } - if (gridMetricType !== undefined) { - this.gridMetricType = gridMetricType; - } - - if (preferGridMetric && gridMetricType) { - const effectiveValue = this.resolveGridMetricValue(gridMetricType, gridMetricValue); - this.gridMetricValue = effectiveValue; - - return super.setData({ - ...data, - gridMetricValue: effectiveValue, - dimensions: this.calculateDimensions(gridMetricType, effectiveValue), - }); - } - - if (!preferGridMetric && dimensions.every((d) => typeof d === "number")) { - const derivedMetric = this.calculateGridMetric(gridMetricType, dimensions); - this.gridMetricValue = derivedMetric; - - return super.setData({ - ...data, - gridMetricValue: derivedMetric, - }); - } - - if (gridMetricValue !== undefined) { - this.gridMetricValue = gridMetricValue; - } - - return super.setData(data); + const synced = this.dataWithEffectiveGridMetric(data); + this.applyGridMetricInstanceFields(synced); + return super.setData(synced); } } diff --git a/src/js/context/providers/base/ContextProvider.ts b/src/js/context/providers/base/ContextProvider.ts index f539594b..33c0ea0c 100644 --- a/src/js/context/providers/base/ContextProvider.ts +++ b/src/js/context/providers/base/ContextProvider.ts @@ -105,6 +105,11 @@ abstract class ContextProvider< this.data = Utils.clone.deepClone(data); } + /** Re-run `setData` normalization before persisting (e.g. derive grid metric from dimensions). */ + syncPersistentData() { + this.setData(this.getData()); + } + /** * Derive template-facing `data` from persisted `data`. Override when the template needs fields * that must not be stored (e.g. coordinates from symmetry point names + lattice). diff --git a/src/js/units/ExecutionUnit.ts b/src/js/units/ExecutionUnit.ts index 009d6786..91f8f474 100644 --- a/src/js/units/ExecutionUnit.ts +++ b/src/js/units/ExecutionUnit.ts @@ -34,6 +34,9 @@ type SetExecutableProps = { flavorName?: string; }; +/** Context items always serialized on the unit so rupy can store them in scope after execution. */ +const CONTEXT_SCOPE_ITEMS = new Set(["kgrid"]); + class ExecutionUnit extends (BaseUnit as Base) implements Schema { inputInstances: ExecutionUnitInput[] = []; @@ -228,8 +231,12 @@ class ExecutionUnit extends (BaseUnit as Base) implements Schema { } savePersistentContext() { + this.contextProvidersInstances + .filter((p) => CONTEXT_SCOPE_ITEMS.has(p.name)) + .forEach((p) => p.syncPersistentData()); + const persistentItems = this.contextProvidersInstances.map((p) => p.getContextItemData()); - this.context = persistentItems.filter((c) => c.isEdited); + this.context = persistentItems.filter((c) => c.isEdited || CONTEXT_SCOPE_ITEMS.has(c.name)); } saveRenderingContext(externalContext: ExternalContext) {