/**
* Step and Object Conversion Utilities
*
* This file contains utility functions for converting between different formats
* used in the investigation system, including steps and objects.
*/
/**
* Convert database steps (IStep[]) to simple steps (ISimpleStep[]) for API response
* @category Utils
* @param {IInvestigationBaseStepModel[]} steps - Database steps with EditableField structure
* @returns {IStep[]} - Simple steps for API response with empty strings instead of undefined
*/
export function convertStepsToSimple(steps) {
return steps.map((step) => ({
title: step.title?.value || "",
desiredOutcome: step.desiredOutcome?.value || "",
alternativeOutcome: step.alternativeOutcome?.value || "",
descriptionEn: step.descriptionEn?.value || "",
skippable: step.skippable?.value || null,
skippable_after_marking: step.skippable_after_marking?.value || null,
}));
}
/**
* Converts an array of `IObjectBase` objects with `EditableField` structures
* into a plain input format suitable for API requests or other processing.
*
* Extracts the `value` from each editable field and provides default fallbacks:
* - Empty string for `name` and `objectId`
* - `0` for position and rotation coordinates
* - `null` for size if not defined
* @category Utils
* @param {IObjectBase[]} objects - Array of objects with `EditableField` properties.
* @param {boolean} withCoordinates - If true, it converts with coordinates fields(position, rotation, size), otherwise converts without them.
* @returns {object[]} - Array of plain objects with `name`, `objectId`, `position`, `rotation`, and `size`.
*/
export function convertObjectsToInputFormat(objects, withCoordinates = true) {
return objects.map((object) => {
if (withCoordinates) {
return {
name: object.name?.value || "",
objectId: object.objectId?.value || "",
position: object.position
? {
x: object.position.x?.value || 0,
y: object.position.y?.value || 0,
z: object.position.z?.value || 0,
}
: null,
rotation: object.rotation
? {
x: object.rotation.x?.value || 0,
y: object.rotation.y?.value || 0,
z: object.rotation.z?.value || 0,
}
: null,
size: object?.size?.value || null,
};
}
else {
return {
name: object.name?.value || "",
objectId: object.objectId?.value || "",
};
}
});
}
/**
* Convert database objects (IObject[]) to simple objects (ISimpleObject[]) for API response
* @category Utils
* @param {IObjectBase[]} objects - Database objects with EditableField structure
* @returns {object[]} - Simple objects for API response with default values instead of null/undefined
*/
export function convertObjectsToSimple(objects) {
return objects.map((object) => {
return {
name: {
value: object.name?.value || "",
isContradicting: object.name?.isContradicting || "",
contradictionReason: object.name?.contradictionReason || "",
targetFieldName: object.name?.targetFieldName || null,
},
objectId: {
value: object.objectId?.value || "",
isContradicting: object.name?.isContradicting || "",
contradictionReason: object.name?.contradictionReason || "",
targetFieldName: object.name?.targetFieldName || null,
},
position: object.position
? {
x: object.position.x?.value || 0,
y: object.position.y?.value || 0,
z: object.position.z?.value || 0,
}
: null,
rotation: object.rotation
? {
x: object.rotation.x?.value || 0,
y: object.rotation.y?.value || 0,
z: object.rotation.z?.value || 0,
}
: null,
size: object?.size?.value || null,
};
});
}
/**
* Converts an array of simple objects (from AI response or plain format) to IUpdateObjectDto format.
* This is the reverse of convertObjectsToInputFormat - it converts from simple format to update DTO format.
* @category Utils
* @param {ISimpleObject[] | ISimpleResponseObject[]} objects - Array of simple objects with plain values.
* @returns {IUpdateObjectDto[]} - Array of objects in IUpdateObjectDto format suitable for update requests.
*/
export function convertObjectsToUpdateFormat(objects) {
return objects
.filter((obj) => obj && typeof obj === "object")
.map((obj) => {
const updateObj = {
name: obj.name ? { value: String(obj.name) } : undefined,
objectId: obj.objectId || obj.name ? { value: String(obj.objectId || obj.name || "") } : undefined,
position: obj.position && typeof obj.position === "object"
? {
x: Number(obj.position.x) || 0,
y: Number(obj.position.y) || 0,
z: Number(obj.position.z) || 0,
}
: undefined,
rotation: obj.rotation && typeof obj.rotation === "object"
? {
x: Number(obj.rotation.x) || 0,
y: Number(obj.rotation.y) || 0,
z: Number(obj.rotation.z) || 0,
}
: undefined,
size: obj.size ? Number(obj.size) : 1,
};
return updateObj;
});
}
/**
* Creates a helper function to extract a simplified version of an `EditableField`
* from an investigation object.
*
* The returned function allows retrieving a specific field by name and converts it into
* a plain `IEditableFieldSimple` object, providing default values for missing properties.
* @category Utils
* @param {IInvestigation} investigation - The investigation object containing `EditableField` properties.
* @returns {Function} - A function that accepts:
* - `fieldName`: The key of the field to extract.
* - `defaultValue`: The fallback value if the field's value is missing (default: "").
* Returns `IEditableFieldSimple` or `null` if the field does not exist.
*/
export function convertEditableFieldToSimple(investigation) {
return (fieldName, defaultValue = "") => {
const field = investigation[fieldName];
return field
? {
value: field.value || defaultValue,
isContradicting: field.isContradicting || false,
targetFieldName: field.targetFieldName || null,
contradictionReason: field.contradictionReason || null,
}
: null;
};
}
Source