Skip to content

Commit

Permalink
Presentation: Fix enum values formatting (#7345)
Browse files Browse the repository at this point in the history
Co-authored-by: Grigas <[email protected]>
  • Loading branch information
MartynasStrazdas and grigasp authored Nov 13, 2024
1 parent 4a72723 commit 7749869
Show file tree
Hide file tree
Showing 3 changed files with 339 additions and 70 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@itwin/presentation-common",
"comment": "Fixed enum property values formatting issue, where raw value was used instead of enum's display value.",
"type": "none"
}
],
"packageName": "@itwin/presentation-common"
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import { Content } from "./Content";
import { Descriptor } from "./Descriptor";
import { ArrayPropertiesField, Field, PropertiesField, StructPropertiesField } from "./Fields";
import { Item } from "./Item";
import { ArrayTypeDescription, PrimitiveTypeDescription, PropertyValueFormat, StructTypeDescription, TypeDescription } from "./TypeDescription";
import { DisplayValue, DisplayValuesMap, NestedContentValue, Value, ValuesArray, ValuesMap } from "./Value";

/** @internal */
Expand Down Expand Up @@ -120,76 +119,90 @@ export class ContentPropertyValueFormatter {
}
: async (rawValue: number) => formatDouble(rawValue);

return this.formatValue(field.type, value, { doubleFormatter });
return this.formatValue(field, value, { doubleFormatter });
}

private async formatValue(type: TypeDescription, value: Value, ctx?: { doubleFormatter: (raw: number) => Promise<string> }): Promise<DisplayValue> {
switch (type.valueFormat) {
case PropertyValueFormat.Primitive:
return this.formatPrimitiveValue(type, value, ctx);
case PropertyValueFormat.Array:
return this.formatArrayValue(type, value);
case PropertyValueFormat.Struct:
return this.formatStructValue(type, value);
private async formatValue(field: Field, value: Value, ctx?: { doubleFormatter: (raw: number) => Promise<string> }): Promise<DisplayValue> {
if (field.isPropertiesField()) {
if (field.isArrayPropertiesField()) {
return this.formatArrayValue(field, value);
}

if (field.isStructPropertiesField()) {
return this.formatStructValue(field, value);
}
}

return this.formatPrimitiveValue(field, value, ctx);
}

private async formatPrimitiveValue(type: PrimitiveTypeDescription, value: Value, ctx?: { doubleFormatter: (raw: number) => Promise<string> }) {
private async formatPrimitiveValue(field: Field, value: Value, ctx?: { doubleFormatter: (raw: number) => Promise<string> }) {
if (value === undefined) {
return "";
}

const formatDoubleValue = async (raw: number) => (ctx ? ctx.doubleFormatter(raw) : formatDouble(raw));

if (type.typeName === "point2d" && isPoint2d(value)) {
if (field.type.typeName === "point2d" && isPoint2d(value)) {
return `X: ${await formatDoubleValue(value.x)}; Y: ${await formatDoubleValue(value.y)}`;
}
if (type.typeName === "point3d" && isPoint3d(value)) {
if (field.type.typeName === "point3d" && isPoint3d(value)) {
return `X: ${await formatDoubleValue(value.x)}; Y: ${await formatDoubleValue(value.y)}; Z: ${await formatDoubleValue(value.z)}`;
}
if (type.typeName === "dateTime") {
if (field.type.typeName === "dateTime") {
assert(typeof value === "string");
return value;
}
if (type.typeName === "bool" || type.typeName === "boolean") {
if (field.type.typeName === "bool" || field.type.typeName === "boolean") {
assert(typeof value === "boolean");
return value ? "@Presentation:value.true@" : "@Presentation:value.false@";
}
if (type.typeName === "int" || type.typeName === "long") {
if (field.type.typeName === "int" || field.type.typeName === "long") {
assert(isNumber(value));
return value.toFixed(0);
}
if (type.typeName === "double") {
if (field.type.typeName === "double") {
assert(isNumber(value));
return formatDoubleValue(value);
}
if (type.typeName === "navigation") {
if (field.type.typeName === "navigation") {
assert(Value.isNavigationValue(value));
return value.label.displayValue;
}

if (field.type.typeName === "enum" && field.isPropertiesField()) {
const defaultValue = !field.properties[0].property.enumerationInfo?.isStrict
? value.toString() // eslint-disable-line @typescript-eslint/no-base-to-string
: undefined;

return field.properties[0].property.enumerationInfo?.choices.find(({ value: enumValue }) => enumValue === value)?.label ?? defaultValue;
}
// eslint-disable-next-line @typescript-eslint/no-base-to-string
return value.toString();
}

private async formatStructValue(type: StructTypeDescription, value: Value) {
private async formatStructValue(field: StructPropertiesField, value: Value) {
if (!Value.isMap(value)) {
return {};
}

const formattedMember: DisplayValuesMap = {};
for (const member of type.members) {
formattedMember[member.name] = await this.formatValue(member.type, value[member.name]);
for (const member of field.memberFields) {
formattedMember[member.name] = await this.formatValue(member, value[member.name]);
}
return formattedMember;
}

private async formatArrayValue(type: ArrayTypeDescription, value: Value) {
private async formatArrayValue(field: ArrayPropertiesField, value: Value) {
if (!Value.isArray(value)) {
return [];
}

return Promise.all(value.map(async (arrayVal) => this.formatValue(type.memberType, arrayVal)));
return Promise.all(
value.map(async (arrayVal) => {
return this.formatValue(field.itemsField, arrayVal);
}),
);
}
}

Expand Down
Loading

0 comments on commit 7749869

Please sign in to comment.