@itwin/presentation-common 4.3.0-dev.9 → 4.4.0-dev.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,6 +1,33 @@
1
1
  # Change Log - @itwin/presentation-common
2
2
 
3
- This log was last generated on Mon, 16 Oct 2023 12:52:11 GMT and should not be manually modified.
3
+ This log was last generated on Thu, 30 Nov 2023 17:07:27 GMT and should not be manually modified.
4
+
5
+ ## 4.2.4
6
+ Mon, 20 Nov 2023 16:14:45 GMT
7
+
8
+ _Version update only_
9
+
10
+ ## 4.2.3
11
+ Mon, 06 Nov 2023 14:01:52 GMT
12
+
13
+ _Version update only_
14
+
15
+ ## 4.2.2
16
+ Thu, 02 Nov 2023 15:36:21 GMT
17
+
18
+ _Version update only_
19
+
20
+ ## 4.2.1
21
+ Tue, 24 Oct 2023 15:09:13 GMT
22
+
23
+ _Version update only_
24
+
25
+ ## 4.2.0
26
+ Tue, 17 Oct 2023 15:14:32 GMT
27
+
28
+ ### Updates
29
+
30
+ - Add `Field.matchesDescriptor` and `Descriptor.getFieldByDescriptor` to lookup fields by their field descriptor.
4
31
 
5
32
  ## 4.1.9
6
33
  Tue, 10 Oct 2023 18:48:12 GMT
@@ -116,6 +143,11 @@ Mon, 22 May 2023 15:34:14 GMT
116
143
  - Added `ContentPropertyValuesFormatter` for content values' formatting on either frontend or backend
117
144
  - Fix `@deprecated` messages
118
145
 
146
+ ## 3.7.17
147
+ Mon, 20 Nov 2023 18:24:23 GMT
148
+
149
+ _Version update only_
150
+
119
151
  ## 3.7.16
120
152
  Mon, 16 Oct 2023 12:49:08 GMT
121
153
 
@@ -1,8 +1,42 @@
1
1
  /** @packageDocumentation
2
2
  * @module Core
3
3
  */
4
- import { FormatterSpec, ParserSpec, UnitSystemKey } from "@itwin/core-quantity";
4
+ import { FormatProps, FormatterSpec, ParserSpec, UnitSystemKey } from "@itwin/core-quantity";
5
5
  import { SchemaContext } from "@itwin/ecschema-metadata";
6
+ /**
7
+ * A data structure that associates unit systems with property value formatting props. The associations are used for
8
+ * assigning formatting props for specific phenomenon and unit system combinations (see [[FormatsMap]]).
9
+ *
10
+ * @public
11
+ */
12
+ export interface UnitSystemFormat {
13
+ unitSystems: UnitSystemKey[];
14
+ format: FormatProps;
15
+ }
16
+ /**
17
+ * A data structure that associates specific phenomenon with one or more formatting props for specific unit system.
18
+ *
19
+ * Example:
20
+ * ```json
21
+ * {
22
+ * length: [{
23
+ * unitSystems: ["metric"],
24
+ * format: formatForCentimeters,
25
+ * }, {
26
+ * unitSystems: ["imperial", "usCustomary"],
27
+ * format: formatForInches,
28
+ * }, {
29
+ * unitSystems: ["usSurvey"],
30
+ * format: formatForUsSurveyInches,
31
+ * }]
32
+ * }
33
+ * ```
34
+ *
35
+ * @public
36
+ */
37
+ export interface FormatsMap {
38
+ [phenomenon: string]: UnitSystemFormat | UnitSystemFormat[];
39
+ }
6
40
  /** @alpha */
7
41
  export interface FormatOptions {
8
42
  koqName: string;
@@ -12,7 +46,8 @@ export interface FormatOptions {
12
46
  export declare class KoqPropertyValueFormatter {
13
47
  private _schemaContext;
14
48
  private _unitsProvider;
15
- constructor(_schemaContext: SchemaContext);
49
+ private _defaultFormats?;
50
+ constructor(_schemaContext: SchemaContext, defaultFormats?: FormatsMap);
16
51
  format(value: number, options: FormatOptions): Promise<string | undefined>;
17
52
  getFormatterSpec(options: FormatOptions): Promise<FormatterSpec | undefined>;
18
53
  getParserSpec(options: FormatOptions): Promise<ParserSpec | undefined>;
@@ -1 +1 @@
1
- {"version":3,"file":"KoqPropertyValueFormatter.d.ts","sourceRoot":"","sources":["../../../src/presentation-common/KoqPropertyValueFormatter.ts"],"names":[],"mappings":"AAIA;;GAEG;AAEH,OAAO,EAAuB,aAAa,EAAE,UAAU,EAAiB,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACpH,OAAO,EACyC,aAAa,EAE5D,MAAM,0BAA0B,CAAC;AAElC,aAAa;AACb,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,aAAa,CAAC;CAC5B;AAED,aAAa;AACb,qBAAa,yBAAyB;IAGxB,OAAO,CAAC,cAAc;IAFlC,OAAO,CAAC,cAAc,CAAgB;gBAElB,cAAc,EAAE,aAAa;IAIpC,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa;IAO5C,gBAAgB,CAAC,OAAO,EAAE,aAAa;IAUvC,aAAa,CAAC,OAAO,EAAE,aAAa;CASlD"}
1
+ {"version":3,"file":"KoqPropertyValueFormatter.d.ts","sourceRoot":"","sources":["../../../src/presentation-common/KoqPropertyValueFormatter.ts"],"names":[],"mappings":"AAIA;;GAEG;AAEH,OAAO,EAAU,WAAW,EAAE,aAAa,EAAE,UAAU,EAAiB,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACpH,OAAO,EAIL,aAAa,EAMd,MAAM,0BAA0B,CAAC;AAElC;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,aAAa,EAAE,CAAC;IAC7B,MAAM,EAAE,WAAW,CAAC;CACrB;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,WAAW,UAAU;IACzB,CAAC,UAAU,EAAE,MAAM,GAAG,gBAAgB,GAAG,gBAAgB,EAAE,CAAC;CAC7D;AAED,aAAa;AACb,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,aAAa,CAAC;CAC5B;AAED,aAAa;AACb,qBAAa,yBAAyB;IAIxB,OAAO,CAAC,cAAc;IAHlC,OAAO,CAAC,cAAc,CAAgB;IACtC,OAAO,CAAC,eAAe,CAAC,CAAa;gBAEjB,cAAc,EAAE,aAAa,EAAE,cAAc,CAAC,EAAE,UAAU;IAOjE,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa;IAQ5C,gBAAgB,CAAC,OAAO,EAAE,aAAa;IAWvC,aAAa,CAAC,OAAO,EAAE,aAAa;CAUlD"}
@@ -1,8 +1,8 @@
1
1
  "use strict";
2
2
  /*---------------------------------------------------------------------------------------------
3
- * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
4
- * See LICENSE.md in the project root for license terms and full copyright notice.
5
- *--------------------------------------------------------------------------------------------*/
3
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
4
+ * See LICENSE.md in the project root for license terms and full copyright notice.
5
+ *--------------------------------------------------------------------------------------------*/
6
6
  /** @packageDocumentation
7
7
  * @module Core
8
8
  */
@@ -12,29 +12,35 @@ const core_quantity_1 = require("@itwin/core-quantity");
12
12
  const ecschema_metadata_1 = require("@itwin/ecschema-metadata");
13
13
  /** @alpha */
14
14
  class KoqPropertyValueFormatter {
15
- constructor(_schemaContext) {
15
+ constructor(_schemaContext, defaultFormats) {
16
16
  this._schemaContext = _schemaContext;
17
17
  this._unitsProvider = new ecschema_metadata_1.SchemaUnitProvider(_schemaContext);
18
+ this._defaultFormats = defaultFormats
19
+ ? Object.entries(defaultFormats).reduce((acc, [phenomenon, unitSystemFormats]) => ({ ...acc, [phenomenon.toUpperCase()]: unitSystemFormats }), {})
20
+ : /* istanbul ignore next */ undefined;
18
21
  }
19
22
  async format(value, options) {
20
23
  const formatterSpec = await this.getFormatterSpec(options);
21
- if (!formatterSpec)
24
+ if (!formatterSpec) {
22
25
  return undefined;
26
+ }
23
27
  return formatterSpec.applyFormatting(value);
24
28
  }
25
29
  async getFormatterSpec(options) {
26
- const formattingProps = await getFormattingProps(this._schemaContext, options);
27
- if (!formattingProps)
30
+ const formattingProps = await getFormattingProps(this._schemaContext, this._defaultFormats, options);
31
+ if (!formattingProps) {
28
32
  return undefined;
33
+ }
29
34
  const { formatProps, persistenceUnitName } = formattingProps;
30
35
  const persistenceUnit = await this._unitsProvider.findUnitByName(persistenceUnitName);
31
36
  const format = await core_quantity_1.Format.createFromJSON("", this._unitsProvider, formatProps);
32
37
  return core_quantity_1.FormatterSpec.create("", format, this._unitsProvider, persistenceUnit);
33
38
  }
34
39
  async getParserSpec(options) {
35
- const formattingProps = await getFormattingProps(this._schemaContext, options);
36
- if (!formattingProps)
40
+ const formattingProps = await getFormattingProps(this._schemaContext, this._defaultFormats, options);
41
+ if (!formattingProps) {
37
42
  return undefined;
43
+ }
38
44
  const { formatProps, persistenceUnitName } = formattingProps;
39
45
  const persistenceUnit = await this._unitsProvider.findUnitByName(persistenceUnitName);
40
46
  const format = await core_quantity_1.Format.createFromJSON("", this._unitsProvider, formatProps);
@@ -42,53 +48,79 @@ class KoqPropertyValueFormatter {
42
48
  }
43
49
  }
44
50
  exports.KoqPropertyValueFormatter = KoqPropertyValueFormatter;
45
- async function getFormattingProps(schemaLocater, options) {
51
+ async function getFormattingProps(schemaLocater, defaultFormats, options) {
46
52
  const { koqName, unitSystem } = options;
47
53
  const koq = await getKoq(schemaLocater, koqName);
48
- if (!koq)
54
+ if (!koq) {
49
55
  return undefined;
56
+ }
50
57
  const persistenceUnit = await koq.persistenceUnit;
51
58
  // istanbul ignore if
52
- if (!persistenceUnit)
59
+ if (!persistenceUnit) {
53
60
  return undefined;
54
- const formatProps = await getKoqFormatProps(koq, persistenceUnit, unitSystem);
55
- if (!formatProps)
61
+ }
62
+ const formatProps = await getKoqFormatProps(koq, persistenceUnit, defaultFormats, unitSystem);
63
+ if (!formatProps) {
56
64
  return undefined;
65
+ }
57
66
  return { formatProps, persistenceUnitName: persistenceUnit.fullName };
58
67
  }
59
68
  async function getKoq(schemaLocater, fullName) {
60
69
  const [schemaName, propKoqName] = fullName.split(":");
61
70
  const schema = await schemaLocater.getSchema(new ecschema_metadata_1.SchemaKey(schemaName), ecschema_metadata_1.SchemaMatchType.Latest);
62
- if (!schema)
71
+ if (!schema) {
63
72
  return undefined;
73
+ }
64
74
  return schema.getItem(propKoqName);
65
75
  }
66
- async function getKoqFormatProps(koq, persistenceUnit, unitSystem) {
67
- const unitSystems = getUnitSystemGroupNames(unitSystem);
76
+ async function getKoqFormatProps(koq, persistenceUnit, defaultFormats, unitSystem) {
77
+ const unitSystemMatchers = getUnitSystemGroupMatchers(unitSystem);
68
78
  // use one of KOQ presentation format that matches requested unit system
69
- const presentationFormat = await getKoqPresentationFormat(koq, unitSystems);
70
- if (presentationFormat)
79
+ const presentationFormat = await getKoqPresentationFormat(koq, unitSystemMatchers);
80
+ if (presentationFormat) {
71
81
  return (0, ecschema_metadata_1.getFormatProps)(presentationFormat);
82
+ }
83
+ // use one of the formats in default formats map if there is one for matching phenomena and requested unit
84
+ // system combination
85
+ if (defaultFormats && unitSystem) {
86
+ const actualPersistenceUnit = persistenceUnit instanceof ecschema_metadata_1.InvertedUnit ? /* istanbul ignore next */ await persistenceUnit.invertsUnit : persistenceUnit;
87
+ const phenomenon = await actualPersistenceUnit?.phenomenon;
88
+ // istanbul ignore else
89
+ if (phenomenon && defaultFormats[phenomenon.name.toUpperCase()]) {
90
+ const defaultPhenomenonFormats = defaultFormats[phenomenon.name.toUpperCase()];
91
+ for (const defaultUnitSystemFormat of Array.isArray(defaultPhenomenonFormats)
92
+ ? /* istanbul ignore next */ defaultPhenomenonFormats
93
+ : [defaultPhenomenonFormats]) {
94
+ if (defaultUnitSystemFormat.unitSystems.includes(unitSystem)) {
95
+ return defaultUnitSystemFormat.format;
96
+ }
97
+ }
98
+ }
99
+ }
72
100
  // use persistence unit format if it matches requested unit system and matching presentation format was not found
73
101
  const persistenceUnitSystem = await persistenceUnit.unitSystem;
74
- if (persistenceUnitSystem && unitSystems.includes(persistenceUnitSystem.name.toUpperCase()))
102
+ if (persistenceUnitSystem && unitSystemMatchers.some((matcher) => matcher(persistenceUnitSystem))) {
75
103
  return getPersistenceUnitFormatProps(persistenceUnit);
104
+ }
76
105
  // use default presentation format if persistence unit does not match requested unit system
77
- if (koq.defaultPresentationFormat)
106
+ if (koq.defaultPresentationFormat) {
78
107
  return (0, ecschema_metadata_1.getFormatProps)(koq.defaultPresentationFormat);
108
+ }
79
109
  return undefined;
80
110
  }
81
- async function getKoqPresentationFormat(koq, unitSystems) {
111
+ async function getKoqPresentationFormat(koq, unitSystemMatchers) {
82
112
  const presentationFormats = koq.presentationFormats;
83
- for (const system of unitSystems) {
113
+ for (const matcher of unitSystemMatchers) {
84
114
  for (const format of presentationFormats) {
85
115
  const unit = format.units && format.units[0][0];
86
116
  // istanbul ignore if
87
- if (!unit)
117
+ if (!unit) {
88
118
  continue;
119
+ }
89
120
  const currentUnitSystem = await unit.unitSystem;
90
- if (currentUnitSystem && currentUnitSystem.name.toUpperCase() === system)
121
+ if (currentUnitSystem && matcher(currentUnitSystem)) {
91
122
  return format;
123
+ }
92
124
  }
93
125
  }
94
126
  return undefined;
@@ -102,23 +134,29 @@ function getPersistenceUnitFormatProps(persistenceUnit) {
102
134
  uomSeparator: " ",
103
135
  decimalSeparator: ".",
104
136
  composite: {
105
- units: [{
137
+ units: [
138
+ {
106
139
  name: persistenceUnit.fullName,
107
140
  label: persistenceUnit.label,
108
- }],
141
+ },
142
+ ],
109
143
  },
110
144
  };
111
145
  }
112
- function getUnitSystemGroupNames(unitSystem) {
113
- switch (unitSystem) {
146
+ function getUnitSystemGroupMatchers(groupKey) {
147
+ function createMatcher(name) {
148
+ const names = Array.isArray(name) ? name : [name];
149
+ return (unitSystem) => names.some((n) => n === unitSystem.name.toUpperCase());
150
+ }
151
+ switch (groupKey) {
114
152
  case "imperial":
115
- return ["IMPERIAL", "USCUSTOM", "INTERNATIONAL", "FINANCE"];
153
+ return ["IMPERIAL", "USCUSTOM", "INTERNATIONAL", "FINANCE"].map(createMatcher);
116
154
  case "metric":
117
- return ["SI", "METRIC", "INTERNATIONAL", "FINANCE"];
155
+ return [["SI", "METRIC"], "INTERNATIONAL", "FINANCE"].map(createMatcher);
118
156
  case "usCustomary":
119
- return ["USCUSTOM", "INTERNATIONAL", "FINANCE"];
157
+ return ["USCUSTOM", "INTERNATIONAL", "FINANCE"].map(createMatcher);
120
158
  case "usSurvey":
121
- return ["USSURVEY", "USCUSTOM", "INTERNATIONAL", "FINANCE"];
159
+ return ["USSURVEY", "USCUSTOM", "INTERNATIONAL", "FINANCE"].map(createMatcher);
122
160
  }
123
161
  return [];
124
162
  }
@@ -1 +1 @@
1
- {"version":3,"file":"KoqPropertyValueFormatter.js","sourceRoot":"","sources":["../../../src/presentation-common/KoqPropertyValueFormatter.ts"],"names":[],"mappings":";AAAA;;;+FAG+F;AAC/F;;GAEG;;;AAEH,wDAAoH;AACpH,gEAGkC;AAQlC,aAAa;AACb,MAAa,yBAAyB;IAGpC,YAAoB,cAA6B;QAA7B,mBAAc,GAAd,cAAc,CAAe;QAC/C,IAAI,CAAC,cAAc,GAAG,IAAI,sCAAkB,CAAC,cAAc,CAAC,CAAC;IAC/D,CAAC;IAEM,KAAK,CAAC,MAAM,CAAC,KAAa,EAAE,OAAsB;QACvD,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;QAC3D,IAAI,CAAC,aAAa;YAChB,OAAO,SAAS,CAAC;QACnB,OAAO,aAAa,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;IAC9C,CAAC;IAEM,KAAK,CAAC,gBAAgB,CAAC,OAAsB;QAClD,MAAM,eAAe,GAAG,MAAM,kBAAkB,CAAC,IAAI,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;QAC/E,IAAI,CAAC,eAAe;YAClB,OAAO,SAAS,CAAC;QACnB,MAAM,EAAE,WAAW,EAAE,mBAAmB,EAAE,GAAG,eAAe,CAAC;QAC7D,MAAM,eAAe,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,mBAAmB,CAAC,CAAC;QACtF,MAAM,MAAM,GAAG,MAAM,sBAAM,CAAC,cAAc,CAAC,EAAE,EAAE,IAAI,CAAC,cAAc,EAAE,WAAW,CAAC,CAAC;QACjF,OAAO,6BAAa,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,cAAc,EAAE,eAAe,CAAC,CAAC;IAChF,CAAC;IAEM,KAAK,CAAC,aAAa,CAAC,OAAsB;QAC/C,MAAM,eAAe,GAAG,MAAM,kBAAkB,CAAC,IAAI,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;QAC/E,IAAI,CAAC,eAAe;YAClB,OAAO,SAAS,CAAC;QACnB,MAAM,EAAE,WAAW,EAAE,mBAAmB,EAAE,GAAG,eAAe,CAAC;QAC7D,MAAM,eAAe,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,mBAAmB,CAAC,CAAC;QACtF,MAAM,MAAM,GAAG,MAAM,sBAAM,CAAC,cAAc,CAAC,EAAE,EAAE,IAAI,CAAC,cAAc,EAAE,WAAW,CAAC,CAAC;QACjF,OAAO,0BAAU,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,cAAc,EAAE,eAAe,CAAC,CAAC;IACzE,CAAC;CACF;AAjCD,8DAiCC;AAOD,KAAK,UAAU,kBAAkB,CAAC,aAA4B,EAAE,OAAsB;IACpF,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC;IAExC,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;IACjD,IAAI,CAAC,GAAG;QACN,OAAO,SAAS,CAAC;IAEnB,MAAM,eAAe,GAAG,MAAM,GAAG,CAAC,eAAe,CAAC;IAClD,qBAAqB;IACrB,IAAI,CAAC,eAAe;QAClB,OAAO,SAAS,CAAC;IAEnB,MAAM,WAAW,GAAG,MAAM,iBAAiB,CAAC,GAAG,EAAE,eAAe,EAAE,UAAU,CAAC,CAAC;IAC9E,IAAI,CAAC,WAAW;QACd,OAAO,SAAS,CAAC;IAEnB,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,eAAe,CAAC,QAAQ,EAAE,CAAC;AACxE,CAAC;AAED,KAAK,UAAU,MAAM,CAAC,aAA4B,EAAE,QAAgB;IAClE,MAAM,CAAC,UAAU,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACtD,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,SAAS,CAAC,IAAI,6BAAS,CAAC,UAAU,CAAC,EAAE,mCAAe,CAAC,MAAM,CAAC,CAAC;IAChG,IAAI,CAAC,MAAM;QACT,OAAO,SAAS,CAAC;IAEnB,OAAO,MAAM,CAAC,OAAO,CAAiB,WAAW,CAAC,CAAC;AACrD,CAAC;AAED,KAAK,UAAU,iBAAiB,CAAC,GAAmB,EAAE,eAAoC,EAAE,UAA0B;IACpH,MAAM,WAAW,GAAG,uBAAuB,CAAC,UAAU,CAAC,CAAC;IACxD,wEAAwE;IACxE,MAAM,kBAAkB,GAAG,MAAM,wBAAwB,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;IAC5E,IAAI,kBAAkB;QACpB,OAAO,IAAA,kCAAc,EAAC,kBAAkB,CAAC,CAAC;IAE5C,iHAAiH;IACjH,MAAM,qBAAqB,GAAG,MAAM,eAAe,CAAC,UAAU,CAAC;IAC/D,IAAI,qBAAqB,IAAI,WAAW,CAAC,QAAQ,CAAC,qBAAqB,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;QACzF,OAAO,6BAA6B,CAAC,eAAe,CAAC,CAAC;IAExD,2FAA2F;IAC3F,IAAI,GAAG,CAAC,yBAAyB;QAC/B,OAAO,IAAA,kCAAc,EAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;IAEvD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,KAAK,UAAU,wBAAwB,CAAC,GAAmB,EAAE,WAAqB;IAChF,MAAM,mBAAmB,GAAG,GAAG,CAAC,mBAAmB,CAAC;IACpD,KAAK,MAAM,MAAM,IAAI,WAAW,EAAE;QAChC,KAAK,MAAM,MAAM,IAAI,mBAAmB,EAAE;YACxC,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAChD,qBAAqB;YACrB,IAAI,CAAC,IAAI;gBACP,SAAS;YAEX,MAAM,iBAAiB,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC;YAChD,IAAI,iBAAiB,IAAI,iBAAiB,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,MAAM;gBACtE,OAAO,MAAM,CAAC;SACjB;KACF;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,6BAA6B,CAAC,eAAoC;IACzE,oDAAoD;IACpD,OAAO;QACL,YAAY,EAAE,CAAC,gBAAgB,EAAE,kBAAkB,EAAE,eAAe,CAAC;QACrE,SAAS,EAAE,CAAC;QACZ,IAAI,EAAE,SAAS;QACf,YAAY,EAAE,GAAG;QACjB,gBAAgB,EAAE,GAAG;QACrB,SAAS,EAAE;YACT,KAAK,EAAE,CAAC;oBACN,IAAI,EAAE,eAAe,CAAC,QAAQ;oBAC9B,KAAK,EAAE,eAAe,CAAC,KAAK;iBAC7B,CAAC;SACH;KACF,CAAC;AACJ,CAAC;AAED,SAAS,uBAAuB,CAAC,UAA0B;IACzD,QAAQ,UAAU,EAAE;QAClB,KAAK,UAAU;YACb,OAAO,CAAC,UAAU,EAAE,UAAU,EAAE,eAAe,EAAE,SAAS,CAAC,CAAC;QAC9D,KAAK,QAAQ;YACX,OAAO,CAAC,IAAI,EAAE,QAAQ,EAAE,eAAe,EAAE,SAAS,CAAC,CAAC;QACtD,KAAK,aAAa;YAChB,OAAO,CAAC,UAAU,EAAE,eAAe,EAAE,SAAS,CAAC,CAAC;QAClD,KAAK,UAAU;YACb,OAAO,CAAC,UAAU,EAAE,UAAU,EAAE,eAAe,EAAE,SAAS,CAAC,CAAC;KAC/D;IACD,OAAO,EAAE,CAAC;AACZ,CAAC","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n/** @packageDocumentation\r\n * @module Core\r\n */\r\n\r\nimport { Format, FormatProps, FormatterSpec, ParserSpec, UnitsProvider, UnitSystemKey } from \"@itwin/core-quantity\";\r\nimport {\r\n getFormatProps, InvertedUnit, KindOfQuantity, SchemaContext, SchemaKey, SchemaMatchType, SchemaUnitProvider,\r\n Unit,\r\n} from \"@itwin/ecschema-metadata\";\r\n\r\n/** @alpha */\r\nexport interface FormatOptions {\r\n koqName: string;\r\n unitSystem?: UnitSystemKey;\r\n}\r\n\r\n/** @alpha */\r\nexport class KoqPropertyValueFormatter {\r\n private _unitsProvider: UnitsProvider;\r\n\r\n constructor(private _schemaContext: SchemaContext) {\r\n this._unitsProvider = new SchemaUnitProvider(_schemaContext);\r\n }\r\n\r\n public async format(value: number, options: FormatOptions) {\r\n const formatterSpec = await this.getFormatterSpec(options);\r\n if (!formatterSpec)\r\n return undefined;\r\n return formatterSpec.applyFormatting(value);\r\n }\r\n\r\n public async getFormatterSpec(options: FormatOptions) {\r\n const formattingProps = await getFormattingProps(this._schemaContext, options);\r\n if (!formattingProps)\r\n return undefined;\r\n const { formatProps, persistenceUnitName } = formattingProps;\r\n const persistenceUnit = await this._unitsProvider.findUnitByName(persistenceUnitName);\r\n const format = await Format.createFromJSON(\"\", this._unitsProvider, formatProps);\r\n return FormatterSpec.create(\"\", format, this._unitsProvider, persistenceUnit);\r\n }\r\n\r\n public async getParserSpec(options: FormatOptions) {\r\n const formattingProps = await getFormattingProps(this._schemaContext, options);\r\n if (!formattingProps)\r\n return undefined;\r\n const { formatProps, persistenceUnitName } = formattingProps;\r\n const persistenceUnit = await this._unitsProvider.findUnitByName(persistenceUnitName);\r\n const format = await Format.createFromJSON(\"\", this._unitsProvider, formatProps);\r\n return ParserSpec.create(format, this._unitsProvider, persistenceUnit);\r\n }\r\n}\r\n\r\ninterface FormattingProps {\r\n formatProps: FormatProps;\r\n persistenceUnitName: string;\r\n}\r\n\r\nasync function getFormattingProps(schemaLocater: SchemaContext, options: FormatOptions): Promise<FormattingProps | undefined> {\r\n const { koqName, unitSystem } = options;\r\n\r\n const koq = await getKoq(schemaLocater, koqName);\r\n if (!koq)\r\n return undefined;\r\n\r\n const persistenceUnit = await koq.persistenceUnit;\r\n // istanbul ignore if\r\n if (!persistenceUnit)\r\n return undefined;\r\n\r\n const formatProps = await getKoqFormatProps(koq, persistenceUnit, unitSystem);\r\n if (!formatProps)\r\n return undefined;\r\n\r\n return { formatProps, persistenceUnitName: persistenceUnit.fullName };\r\n}\r\n\r\nasync function getKoq(schemaLocater: SchemaContext, fullName: string) {\r\n const [schemaName, propKoqName] = fullName.split(\":\");\r\n const schema = await schemaLocater.getSchema(new SchemaKey(schemaName), SchemaMatchType.Latest);\r\n if (!schema)\r\n return undefined;\r\n\r\n return schema.getItem<KindOfQuantity>(propKoqName);\r\n}\r\n\r\nasync function getKoqFormatProps(koq: KindOfQuantity, persistenceUnit: Unit | InvertedUnit, unitSystem?: UnitSystemKey) {\r\n const unitSystems = getUnitSystemGroupNames(unitSystem);\r\n // use one of KOQ presentation format that matches requested unit system\r\n const presentationFormat = await getKoqPresentationFormat(koq, unitSystems);\r\n if (presentationFormat)\r\n return getFormatProps(presentationFormat);\r\n\r\n // use persistence unit format if it matches requested unit system and matching presentation format was not found\r\n const persistenceUnitSystem = await persistenceUnit.unitSystem;\r\n if (persistenceUnitSystem && unitSystems.includes(persistenceUnitSystem.name.toUpperCase()))\r\n return getPersistenceUnitFormatProps(persistenceUnit);\r\n\r\n // use default presentation format if persistence unit does not match requested unit system\r\n if (koq.defaultPresentationFormat)\r\n return getFormatProps(koq.defaultPresentationFormat);\r\n\r\n return undefined;\r\n}\r\n\r\nasync function getKoqPresentationFormat(koq: KindOfQuantity, unitSystems: string[]) {\r\n const presentationFormats = koq.presentationFormats;\r\n for (const system of unitSystems) {\r\n for (const format of presentationFormats) {\r\n const unit = format.units && format.units[0][0];\r\n // istanbul ignore if\r\n if (!unit)\r\n continue;\r\n\r\n const currentUnitSystem = await unit.unitSystem;\r\n if (currentUnitSystem && currentUnitSystem.name.toUpperCase() === system)\r\n return format;\r\n }\r\n }\r\n return undefined;\r\n}\r\n\r\nfunction getPersistenceUnitFormatProps(persistenceUnit: Unit | InvertedUnit): FormatProps {\r\n // Same as Format \"DefaultRealU\" in Formats ecschema\r\n return {\r\n formatTraits: [\"keepSingleZero\", \"keepDecimalPoint\", \"showUnitLabel\"],\r\n precision: 6,\r\n type: \"Decimal\",\r\n uomSeparator: \" \",\r\n decimalSeparator: \".\",\r\n composite: {\r\n units: [{\r\n name: persistenceUnit.fullName,\r\n label: persistenceUnit.label,\r\n }],\r\n },\r\n };\r\n}\r\n\r\nfunction getUnitSystemGroupNames(unitSystem?: UnitSystemKey) {\r\n switch (unitSystem) {\r\n case \"imperial\":\r\n return [\"IMPERIAL\", \"USCUSTOM\", \"INTERNATIONAL\", \"FINANCE\"];\r\n case \"metric\":\r\n return [\"SI\", \"METRIC\", \"INTERNATIONAL\", \"FINANCE\"];\r\n case \"usCustomary\":\r\n return [\"USCUSTOM\", \"INTERNATIONAL\", \"FINANCE\"];\r\n case \"usSurvey\":\r\n return [\"USSURVEY\", \"USCUSTOM\", \"INTERNATIONAL\", \"FINANCE\"];\r\n }\r\n return [];\r\n}\r\n"]}
1
+ {"version":3,"file":"KoqPropertyValueFormatter.js","sourceRoot":"","sources":["../../../src/presentation-common/KoqPropertyValueFormatter.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n * See LICENSE.md in the project root for license terms and full copyright notice.\r\n *--------------------------------------------------------------------------------------------*/\r\n/** @packageDocumentation\r\n * @module Core\r\n */\r\n\r\nimport { Format, FormatProps, FormatterSpec, ParserSpec, UnitsProvider, UnitSystemKey } from \"@itwin/core-quantity\";\r\nimport {\r\n getFormatProps,\r\n InvertedUnit,\r\n KindOfQuantity,\r\n SchemaContext,\r\n SchemaKey,\r\n SchemaMatchType,\r\n SchemaUnitProvider,\r\n Unit,\r\n UnitSystem,\r\n} from \"@itwin/ecschema-metadata\";\r\n\r\n/**\r\n * A data structure that associates unit systems with property value formatting props. The associations are used for\r\n * assigning formatting props for specific phenomenon and unit system combinations (see [[FormatsMap]]).\r\n *\r\n * @public\r\n */\r\nexport interface UnitSystemFormat {\r\n unitSystems: UnitSystemKey[];\r\n format: FormatProps;\r\n}\r\n\r\n/**\r\n * A data structure that associates specific phenomenon with one or more formatting props for specific unit system.\r\n *\r\n * Example:\r\n * ```json\r\n * {\r\n * length: [{\r\n * unitSystems: [\"metric\"],\r\n * format: formatForCentimeters,\r\n * }, {\r\n * unitSystems: [\"imperial\", \"usCustomary\"],\r\n * format: formatForInches,\r\n * }, {\r\n * unitSystems: [\"usSurvey\"],\r\n * format: formatForUsSurveyInches,\r\n * }]\r\n * }\r\n * ```\r\n *\r\n * @public\r\n */\r\nexport interface FormatsMap {\r\n [phenomenon: string]: UnitSystemFormat | UnitSystemFormat[];\r\n}\r\n\r\n/** @alpha */\r\nexport interface FormatOptions {\r\n koqName: string;\r\n unitSystem?: UnitSystemKey;\r\n}\r\n\r\n/** @alpha */\r\nexport class KoqPropertyValueFormatter {\r\n private _unitsProvider: UnitsProvider;\r\n private _defaultFormats?: FormatsMap;\r\n\r\n constructor(private _schemaContext: SchemaContext, defaultFormats?: FormatsMap) {\r\n this._unitsProvider = new SchemaUnitProvider(_schemaContext);\r\n this._defaultFormats = defaultFormats\r\n ? Object.entries(defaultFormats).reduce((acc, [phenomenon, unitSystemFormats]) => ({ ...acc, [phenomenon.toUpperCase()]: unitSystemFormats }), {})\r\n : /* istanbul ignore next */ undefined;\r\n }\r\n\r\n public async format(value: number, options: FormatOptions) {\r\n const formatterSpec = await this.getFormatterSpec(options);\r\n if (!formatterSpec) {\r\n return undefined;\r\n }\r\n return formatterSpec.applyFormatting(value);\r\n }\r\n\r\n public async getFormatterSpec(options: FormatOptions) {\r\n const formattingProps = await getFormattingProps(this._schemaContext, this._defaultFormats, options);\r\n if (!formattingProps) {\r\n return undefined;\r\n }\r\n const { formatProps, persistenceUnitName } = formattingProps;\r\n const persistenceUnit = await this._unitsProvider.findUnitByName(persistenceUnitName);\r\n const format = await Format.createFromJSON(\"\", this._unitsProvider, formatProps);\r\n return FormatterSpec.create(\"\", format, this._unitsProvider, persistenceUnit);\r\n }\r\n\r\n public async getParserSpec(options: FormatOptions) {\r\n const formattingProps = await getFormattingProps(this._schemaContext, this._defaultFormats, options);\r\n if (!formattingProps) {\r\n return undefined;\r\n }\r\n const { formatProps, persistenceUnitName } = formattingProps;\r\n const persistenceUnit = await this._unitsProvider.findUnitByName(persistenceUnitName);\r\n const format = await Format.createFromJSON(\"\", this._unitsProvider, formatProps);\r\n return ParserSpec.create(format, this._unitsProvider, persistenceUnit);\r\n }\r\n}\r\n\r\ninterface FormattingProps {\r\n formatProps: FormatProps;\r\n persistenceUnitName: string;\r\n}\r\n\r\nasync function getFormattingProps(\r\n schemaLocater: SchemaContext,\r\n defaultFormats: FormatsMap | undefined,\r\n options: FormatOptions,\r\n): Promise<FormattingProps | undefined> {\r\n const { koqName, unitSystem } = options;\r\n\r\n const koq = await getKoq(schemaLocater, koqName);\r\n if (!koq) {\r\n return undefined;\r\n }\r\n\r\n const persistenceUnit = await koq.persistenceUnit;\r\n // istanbul ignore if\r\n if (!persistenceUnit) {\r\n return undefined;\r\n }\r\n\r\n const formatProps = await getKoqFormatProps(koq, persistenceUnit, defaultFormats, unitSystem);\r\n if (!formatProps) {\r\n return undefined;\r\n }\r\n\r\n return { formatProps, persistenceUnitName: persistenceUnit.fullName };\r\n}\r\n\r\nasync function getKoq(schemaLocater: SchemaContext, fullName: string) {\r\n const [schemaName, propKoqName] = fullName.split(\":\");\r\n const schema = await schemaLocater.getSchema(new SchemaKey(schemaName), SchemaMatchType.Latest);\r\n if (!schema) {\r\n return undefined;\r\n }\r\n return schema.getItem<KindOfQuantity>(propKoqName);\r\n}\r\n\r\nasync function getKoqFormatProps(\r\n koq: KindOfQuantity,\r\n persistenceUnit: Unit | InvertedUnit,\r\n defaultFormats: FormatsMap | undefined,\r\n unitSystem?: UnitSystemKey,\r\n) {\r\n const unitSystemMatchers = getUnitSystemGroupMatchers(unitSystem);\r\n // use one of KOQ presentation format that matches requested unit system\r\n const presentationFormat = await getKoqPresentationFormat(koq, unitSystemMatchers);\r\n if (presentationFormat) {\r\n return getFormatProps(presentationFormat);\r\n }\r\n\r\n // use one of the formats in default formats map if there is one for matching phenomena and requested unit\r\n // system combination\r\n if (defaultFormats && unitSystem) {\r\n const actualPersistenceUnit = persistenceUnit instanceof InvertedUnit ? /* istanbul ignore next */ await persistenceUnit.invertsUnit : persistenceUnit;\r\n const phenomenon = await actualPersistenceUnit?.phenomenon;\r\n // istanbul ignore else\r\n if (phenomenon && defaultFormats[phenomenon.name.toUpperCase()]) {\r\n const defaultPhenomenonFormats = defaultFormats[phenomenon.name.toUpperCase()];\r\n for (const defaultUnitSystemFormat of Array.isArray(defaultPhenomenonFormats)\r\n ? /* istanbul ignore next */ defaultPhenomenonFormats\r\n : [defaultPhenomenonFormats]) {\r\n if (defaultUnitSystemFormat.unitSystems.includes(unitSystem)) {\r\n return defaultUnitSystemFormat.format;\r\n }\r\n }\r\n }\r\n }\r\n\r\n // use persistence unit format if it matches requested unit system and matching presentation format was not found\r\n const persistenceUnitSystem = await persistenceUnit.unitSystem;\r\n if (persistenceUnitSystem && unitSystemMatchers.some((matcher) => matcher(persistenceUnitSystem))) {\r\n return getPersistenceUnitFormatProps(persistenceUnit);\r\n }\r\n\r\n // use default presentation format if persistence unit does not match requested unit system\r\n if (koq.defaultPresentationFormat) {\r\n return getFormatProps(koq.defaultPresentationFormat);\r\n }\r\n\r\n return undefined;\r\n}\r\n\r\nasync function getKoqPresentationFormat(koq: KindOfQuantity, unitSystemMatchers: Array<(unitSystem: UnitSystem) => boolean>) {\r\n const presentationFormats = koq.presentationFormats;\r\n for (const matcher of unitSystemMatchers) {\r\n for (const format of presentationFormats) {\r\n const unit = format.units && format.units[0][0];\r\n // istanbul ignore if\r\n if (!unit) {\r\n continue;\r\n }\r\n const currentUnitSystem = await unit.unitSystem;\r\n if (currentUnitSystem && matcher(currentUnitSystem)) {\r\n return format;\r\n }\r\n }\r\n }\r\n return undefined;\r\n}\r\n\r\nfunction getPersistenceUnitFormatProps(persistenceUnit: Unit | InvertedUnit): FormatProps {\r\n // Same as Format \"DefaultRealU\" in Formats ecschema\r\n return {\r\n formatTraits: [\"keepSingleZero\", \"keepDecimalPoint\", \"showUnitLabel\"],\r\n precision: 6,\r\n type: \"Decimal\",\r\n uomSeparator: \" \",\r\n decimalSeparator: \".\",\r\n composite: {\r\n units: [\r\n {\r\n name: persistenceUnit.fullName,\r\n label: persistenceUnit.label,\r\n },\r\n ],\r\n },\r\n };\r\n}\r\n\r\nfunction getUnitSystemGroupMatchers(groupKey?: UnitSystemKey) {\r\n function createMatcher(name: string | string[]) {\r\n const names = Array.isArray(name) ? name : [name];\r\n return (unitSystem: UnitSystem) => names.some((n) => n === unitSystem.name.toUpperCase());\r\n }\r\n switch (groupKey) {\r\n case \"imperial\":\r\n return [\"IMPERIAL\", \"USCUSTOM\", \"INTERNATIONAL\", \"FINANCE\"].map(createMatcher);\r\n case \"metric\":\r\n return [[\"SI\", \"METRIC\"], \"INTERNATIONAL\", \"FINANCE\"].map(createMatcher);\r\n case \"usCustomary\":\r\n return [\"USCUSTOM\", \"INTERNATIONAL\", \"FINANCE\"].map(createMatcher);\r\n case \"usSurvey\":\r\n return [\"USSURVEY\", \"USCUSTOM\", \"INTERNATIONAL\", \"FINANCE\"].map(createMatcher);\r\n }\r\n return [];\r\n}\r\n"]}
@@ -5,8 +5,7 @@ import { UnitSystemKey } from "@itwin/core-quantity";
5
5
  import { KoqPropertyValueFormatter } from "../KoqPropertyValueFormatter";
6
6
  import { Content } from "./Content";
7
7
  import { Field } from "./Fields";
8
- import { ArrayTypeDescription, PrimitiveTypeDescription, StructTypeDescription, TypeDescription } from "./TypeDescription";
9
- import { DisplayValue, DisplayValuesMap, Value } from "./Value";
8
+ import { DisplayValue, Value } from "./Value";
10
9
  /** @alpha */
11
10
  export declare class ContentFormatter {
12
11
  private _propertyValueFormatter;
@@ -21,9 +20,9 @@ export declare class ContentPropertyValueFormatter {
21
20
  private _koqValueFormatter;
22
21
  constructor(_koqValueFormatter: KoqPropertyValueFormatter);
23
22
  formatPropertyValue(field: Field, value: Value, unitSystem?: UnitSystemKey): Promise<DisplayValue>;
24
- formatValue(type: TypeDescription, value: Value): DisplayValue;
25
- formatPrimitiveValue(type: PrimitiveTypeDescription, value: Value): string;
26
- formatStructValue(type: StructTypeDescription, value: Value): DisplayValuesMap;
27
- formatArrayValue(type: ArrayTypeDescription, value: Value): DisplayValue[];
23
+ private formatValue;
24
+ private formatPrimitiveValue;
25
+ private formatStructValue;
26
+ private formatArrayValue;
28
27
  }
29
28
  //# sourceMappingURL=PropertyValueFormatter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"PropertyValueFormatter.d.ts","sourceRoot":"","sources":["../../../../src/presentation-common/content/PropertyValueFormatter.ts"],"names":[],"mappings":"AAIA;;GAEG;AAGH,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD,OAAO,EAAE,yBAAyB,EAAE,MAAM,8BAA8B,CAAC;AAEzE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,KAAK,EAAmB,MAAM,UAAU,CAAC;AAClD,OAAO,EAAE,oBAAoB,EAAE,wBAAwB,EAAuB,qBAAqB,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAChJ,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAsB,KAAK,EAAE,MAAM,SAAS,CAAC;AAEpF,aAAa;AACb,qBAAa,gBAAgB;IACf,OAAO,CAAC,uBAAuB;IAAiC,OAAO,CAAC,WAAW,CAAC;gBAA5E,uBAAuB,EAAE,6BAA6B,EAAU,WAAW,CAAC,2BAAe;IAElG,aAAa,CAAC,OAAO,EAAE,OAAO;YAQ7B,YAAY;YAqBZ,gCAAgC;CAM/C;AAED,aAAa;AACb,qBAAa,6BAA6B;IAC5B,OAAO,CAAC,kBAAkB;gBAAlB,kBAAkB,EAAE,yBAAyB;IAEpD,mBAAmB,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC;IAWxG,WAAW,CAAC,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,KAAK,GAAG,YAAY;IAW9D,oBAAoB,CAAC,IAAI,EAAE,wBAAwB,EAAE,KAAK,EAAE,KAAK;IAkCjE,iBAAiB,CAAC,IAAI,EAAE,qBAAqB,EAAE,KAAK,EAAE,KAAK;IAW3D,gBAAgB,CAAC,IAAI,EAAE,oBAAoB,EAAE,KAAK,EAAE,KAAK;CAMjE"}
1
+ {"version":3,"file":"PropertyValueFormatter.d.ts","sourceRoot":"","sources":["../../../../src/presentation-common/content/PropertyValueFormatter.ts"],"names":[],"mappings":"AAIA;;GAEG;AAGH,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD,OAAO,EAAE,yBAAyB,EAAE,MAAM,8BAA8B,CAAC;AAEzE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,KAAK,EAAmB,MAAM,UAAU,CAAC;AAElD,OAAO,EAAE,YAAY,EAAwC,KAAK,EAAE,MAAM,SAAS,CAAC;AAEpF,aAAa;AACb,qBAAa,gBAAgB;IACf,OAAO,CAAC,uBAAuB;IAAiC,OAAO,CAAC,WAAW,CAAC;gBAA5E,uBAAuB,EAAE,6BAA6B,EAAU,WAAW,CAAC,2BAAe;IAElG,aAAa,CAAC,OAAO,EAAE,OAAO;YAQ7B,YAAY;YAqBZ,gCAAgC;CAM/C;AAED,aAAa;AACb,qBAAa,6BAA6B;IAC5B,OAAO,CAAC,kBAAkB;gBAAlB,kBAAkB,EAAE,yBAAyB;IAEpD,mBAAmB,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC;YAcjG,WAAW;YAWX,oBAAoB;YAoCpB,iBAAiB;YAWjB,gBAAgB;CAM/B"}
@@ -54,32 +54,36 @@ class ContentPropertyValueFormatter {
54
54
  this._koqValueFormatter = _koqValueFormatter;
55
55
  }
56
56
  async formatPropertyValue(field, value, unitSystem) {
57
- if (isFieldWithKoq(field) && typeof value === "number") {
58
- const koq = field.properties[0].property.kindOfQuantity;
59
- const formattedValue = await this._koqValueFormatter.format(value, { koqName: koq.name, unitSystem });
60
- if (formattedValue !== undefined)
61
- return formattedValue;
62
- }
63
- return this.formatValue(field.type, value);
57
+ const doubleFormatter = isFieldWithKoq(field)
58
+ ? async (rawValue) => {
59
+ const koq = field.properties[0].property.kindOfQuantity;
60
+ const formattedValue = await this._koqValueFormatter.format(rawValue, { koqName: koq.name, unitSystem });
61
+ if (formattedValue !== undefined)
62
+ return formattedValue;
63
+ return formatDouble(rawValue);
64
+ }
65
+ : async (rawValue) => formatDouble(rawValue);
66
+ return this.formatValue(field.type, value, { doubleFormatter });
64
67
  }
65
- formatValue(type, value) {
68
+ async formatValue(type, value, ctx) {
66
69
  switch (type.valueFormat) {
67
70
  case TypeDescription_1.PropertyValueFormat.Primitive:
68
- return this.formatPrimitiveValue(type, value);
71
+ return this.formatPrimitiveValue(type, value, ctx);
69
72
  case TypeDescription_1.PropertyValueFormat.Array:
70
73
  return this.formatArrayValue(type, value);
71
74
  case TypeDescription_1.PropertyValueFormat.Struct:
72
75
  return this.formatStructValue(type, value);
73
76
  }
74
77
  }
75
- formatPrimitiveValue(type, value) {
78
+ async formatPrimitiveValue(type, value, ctx) {
76
79
  if (value === undefined)
77
80
  return "";
81
+ const formatDoubleValue = async (raw) => ctx ? ctx.doubleFormatter(raw) : formatDouble(raw);
78
82
  if (type.typeName === "point2d" && isPoint2d(value)) {
79
- return `X: ${formatDouble(value.x)} Y: ${formatDouble(value.y)}`;
83
+ return `X: ${await formatDoubleValue(value.x)}; Y: ${await formatDoubleValue(value.y)}`;
80
84
  }
81
85
  if (type.typeName === "point3d" && isPoint3d(value)) {
82
- return `X: ${formatDouble(value.x)} Y: ${formatDouble(value.y)} Z: ${formatDouble(value.z)}`;
86
+ return `X: ${await formatDoubleValue(value.x)}; Y: ${await formatDoubleValue(value.y)}; Z: ${await formatDoubleValue(value.z)}`;
83
87
  }
84
88
  if (type.typeName === "dateTime") {
85
89
  (0, core_bentley_1.assert)(typeof value === "string");
@@ -95,7 +99,7 @@ class ContentPropertyValueFormatter {
95
99
  }
96
100
  if (type.typeName === "double") {
97
101
  (0, core_bentley_1.assert)(isNumber(value));
98
- return formatDouble(value);
102
+ return formatDoubleValue(value);
99
103
  }
100
104
  if (type.typeName === "navigation") {
101
105
  (0, core_bentley_1.assert)(Value_1.Value.isNavigationValue(value));
@@ -103,19 +107,19 @@ class ContentPropertyValueFormatter {
103
107
  }
104
108
  return value.toString();
105
109
  }
106
- formatStructValue(type, value) {
110
+ async formatStructValue(type, value) {
107
111
  if (!Value_1.Value.isMap(value))
108
112
  return {};
109
113
  const formattedMember = {};
110
114
  for (const member of type.members) {
111
- formattedMember[member.name] = this.formatValue(member.type, value[member.name]);
115
+ formattedMember[member.name] = await this.formatValue(member.type, value[member.name]);
112
116
  }
113
117
  return formattedMember;
114
118
  }
115
- formatArrayValue(type, value) {
119
+ async formatArrayValue(type, value) {
116
120
  if (!Value_1.Value.isArray(value))
117
121
  return [];
118
- return value.map((arrayVal) => this.formatValue(type.memberType, arrayVal));
122
+ return Promise.all(value.map(async (arrayVal) => this.formatValue(type.memberType, arrayVal)));
119
123
  }
120
124
  }
121
125
  exports.ContentPropertyValueFormatter = ContentPropertyValueFormatter;
@@ -1 +1 @@
1
- {"version":3,"file":"PropertyValueFormatter.js","sourceRoot":"","sources":["../../../../src/presentation-common/content/PropertyValueFormatter.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n/** @packageDocumentation\r\n * @module Content\r\n */\r\n\r\nimport { assert } from \"@itwin/core-bentley\";\r\nimport { UnitSystemKey } from \"@itwin/core-quantity\";\r\nimport { KindOfQuantityInfo, PropertyInfo } from \"../EC\";\r\nimport { KoqPropertyValueFormatter } from \"../KoqPropertyValueFormatter\";\r\nimport { ValuesDictionary } from \"../Utils\";\r\nimport { Content } from \"./Content\";\r\nimport { Field, PropertiesField } from \"./Fields\";\r\nimport { ArrayTypeDescription, PrimitiveTypeDescription, PropertyValueFormat, StructTypeDescription, TypeDescription } from \"./TypeDescription\";\r\nimport { DisplayValue, DisplayValuesMap, NestedContentValue, Value } from \"./Value\";\r\n\r\n/** @alpha */\r\nexport class ContentFormatter {\r\n constructor(private _propertyValueFormatter: ContentPropertyValueFormatter, private _unitSystem?: UnitSystemKey) { }\r\n\r\n public async formatContent(content: Content) {\r\n const descriptor = content.descriptor;\r\n for (const item of content.contentSet) {\r\n await this.formatValues(item.values, item.displayValues, descriptor.fields, item.mergedFieldNames);\r\n }\r\n return content;\r\n }\r\n\r\n private async formatValues(values: ValuesDictionary<Value>, displayValues: ValuesDictionary<DisplayValue>, fields: Field[], mergedFields: string[]) {\r\n for (const field of fields) {\r\n const value = values[field.name];\r\n\r\n // format display value of merged values\r\n if (mergedFields.includes(field.name)) {\r\n displayValues[field.name] = \"@Presentation:label.varies@\";\r\n continue;\r\n }\r\n\r\n // format display values of nested content field\r\n if (field.isNestedContentField()) {\r\n assert(Value.isNestedContent(value));\r\n await this.formatNestedContentDisplayValues(value, field.nestedFields);\r\n continue;\r\n }\r\n\r\n displayValues[field.name] = await this._propertyValueFormatter.formatPropertyValue(field, value, this._unitSystem);\r\n }\r\n }\r\n\r\n private async formatNestedContentDisplayValues(nestedValues: NestedContentValue[], fields: Field[]) {\r\n for (const nestedValue of nestedValues) {\r\n await this.formatValues(nestedValue.values, nestedValue.displayValues, fields, nestedValue.mergedFieldNames);\r\n }\r\n }\r\n\r\n}\r\n\r\n/** @alpha */\r\nexport class ContentPropertyValueFormatter {\r\n constructor(private _koqValueFormatter: KoqPropertyValueFormatter) { }\r\n\r\n public async formatPropertyValue(field: Field, value: Value, unitSystem?: UnitSystemKey): Promise<DisplayValue> {\r\n if (isFieldWithKoq(field) && typeof value === \"number\") {\r\n const koq = field.properties[0].property.kindOfQuantity;\r\n const formattedValue = await this._koqValueFormatter.format(value, { koqName: koq.name, unitSystem });\r\n if (formattedValue !== undefined)\r\n return formattedValue;\r\n }\r\n\r\n return this.formatValue(field.type, value);\r\n }\r\n\r\n public formatValue(type: TypeDescription, value: Value): DisplayValue {\r\n switch (type.valueFormat) {\r\n case PropertyValueFormat.Primitive:\r\n return this.formatPrimitiveValue(type, value);\r\n case PropertyValueFormat.Array:\r\n return this.formatArrayValue(type, value);\r\n case PropertyValueFormat.Struct:\r\n return this.formatStructValue(type, value);\r\n }\r\n }\r\n\r\n public formatPrimitiveValue(type: PrimitiveTypeDescription, value: Value) {\r\n if (value === undefined)\r\n return \"\";\r\n\r\n if (type.typeName === \"point2d\" && isPoint2d(value)) {\r\n return `X: ${formatDouble(value.x)} Y: ${formatDouble(value.y)}`;\r\n }\r\n if (type.typeName === \"point3d\" && isPoint3d(value)) {\r\n return `X: ${formatDouble(value.x)} Y: ${formatDouble(value.y)} Z: ${formatDouble(value.z)}`;\r\n }\r\n if (type.typeName === \"dateTime\") {\r\n assert(typeof value === \"string\");\r\n return value;\r\n }\r\n if (type.typeName === \"bool\" || type.typeName === \"boolean\") {\r\n assert(typeof value === \"boolean\");\r\n return value ? \"@Presentation:value.true@\" : \"@Presentation:value.false@\";\r\n }\r\n if (type.typeName === \"int\" || type.typeName === \"long\") {\r\n assert(isNumber(value));\r\n return value.toFixed(0);\r\n }\r\n if (type.typeName === \"double\") {\r\n assert(isNumber(value));\r\n return formatDouble(value);\r\n }\r\n if (type.typeName === \"navigation\") {\r\n assert(Value.isNavigationValue(value));\r\n return value.label.displayValue;\r\n }\r\n\r\n return value.toString();\r\n }\r\n\r\n public formatStructValue(type: StructTypeDescription, value: Value) {\r\n if (!Value.isMap(value))\r\n return {};\r\n\r\n const formattedMember: DisplayValuesMap = {};\r\n for (const member of type.members) {\r\n formattedMember[member.name] = this.formatValue(member.type, value[member.name]);\r\n }\r\n return formattedMember;\r\n }\r\n\r\n public formatArrayValue(type: ArrayTypeDescription, value: Value) {\r\n if (!Value.isArray(value))\r\n return [];\r\n\r\n return value.map((arrayVal) => this.formatValue(type.memberType, arrayVal));\r\n }\r\n}\r\n\r\nfunction formatDouble(value: number) {\r\n return value.toFixed(2);\r\n}\r\n\r\ntype FieldWithKoq = PropertiesField & {\r\n properties: [{\r\n property: PropertyInfo & {\r\n kindOfQuantity: KindOfQuantityInfo;\r\n };\r\n }];\r\n};\r\n\r\nfunction isFieldWithKoq(field: Field): field is FieldWithKoq {\r\n return field.isPropertiesField()\r\n && field.properties.length > 0\r\n && field.properties[0].property.kindOfQuantity !== undefined;\r\n}\r\n\r\nfunction isPoint2d(obj: Value): obj is { x: number, y: number } {\r\n return obj !== undefined && isNumber((obj as any).x) && isNumber((obj as any).y);\r\n}\r\n\r\nfunction isPoint3d(obj: Value): obj is { x: number, y: number, z: number } {\r\n return isPoint2d(obj) && isNumber((obj as any).z);\r\n}\r\n\r\nfunction isNumber(obj: Value): obj is number {\r\n return !isNaN(Number(obj));\r\n}\r\n"]}
1
+ {"version":3,"file":"PropertyValueFormatter.js","sourceRoot":"","sources":["../../../../src/presentation-common/content/PropertyValueFormatter.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n/** @packageDocumentation\r\n * @module Content\r\n */\r\n\r\nimport { assert } from \"@itwin/core-bentley\";\r\nimport { UnitSystemKey } from \"@itwin/core-quantity\";\r\nimport { KindOfQuantityInfo, PropertyInfo } from \"../EC\";\r\nimport { KoqPropertyValueFormatter } from \"../KoqPropertyValueFormatter\";\r\nimport { ValuesDictionary } from \"../Utils\";\r\nimport { Content } from \"./Content\";\r\nimport { Field, PropertiesField } from \"./Fields\";\r\nimport { ArrayTypeDescription, PrimitiveTypeDescription, PropertyValueFormat, StructTypeDescription, TypeDescription } from \"./TypeDescription\";\r\nimport { DisplayValue, DisplayValuesMap, NestedContentValue, Value } from \"./Value\";\r\n\r\n/** @alpha */\r\nexport class ContentFormatter {\r\n constructor(private _propertyValueFormatter: ContentPropertyValueFormatter, private _unitSystem?: UnitSystemKey) { }\r\n\r\n public async formatContent(content: Content) {\r\n const descriptor = content.descriptor;\r\n for (const item of content.contentSet) {\r\n await this.formatValues(item.values, item.displayValues, descriptor.fields, item.mergedFieldNames);\r\n }\r\n return content;\r\n }\r\n\r\n private async formatValues(values: ValuesDictionary<Value>, displayValues: ValuesDictionary<DisplayValue>, fields: Field[], mergedFields: string[]) {\r\n for (const field of fields) {\r\n const value = values[field.name];\r\n\r\n // format display value of merged values\r\n if (mergedFields.includes(field.name)) {\r\n displayValues[field.name] = \"@Presentation:label.varies@\";\r\n continue;\r\n }\r\n\r\n // format display values of nested content field\r\n if (field.isNestedContentField()) {\r\n assert(Value.isNestedContent(value));\r\n await this.formatNestedContentDisplayValues(value, field.nestedFields);\r\n continue;\r\n }\r\n\r\n displayValues[field.name] = await this._propertyValueFormatter.formatPropertyValue(field, value, this._unitSystem);\r\n }\r\n }\r\n\r\n private async formatNestedContentDisplayValues(nestedValues: NestedContentValue[], fields: Field[]) {\r\n for (const nestedValue of nestedValues) {\r\n await this.formatValues(nestedValue.values, nestedValue.displayValues, fields, nestedValue.mergedFieldNames);\r\n }\r\n }\r\n\r\n}\r\n\r\n/** @alpha */\r\nexport class ContentPropertyValueFormatter {\r\n constructor(private _koqValueFormatter: KoqPropertyValueFormatter) { }\r\n\r\n public async formatPropertyValue(field: Field, value: Value, unitSystem?: UnitSystemKey): Promise<DisplayValue> {\r\n const doubleFormatter = isFieldWithKoq(field)\r\n ? async (rawValue: number) => {\r\n const koq = field.properties[0].property.kindOfQuantity;\r\n const formattedValue = await this._koqValueFormatter.format(rawValue, { koqName: koq.name, unitSystem });\r\n if (formattedValue !== undefined)\r\n return formattedValue;\r\n return formatDouble(rawValue);\r\n }\r\n : async (rawValue: number) => formatDouble(rawValue);\r\n\r\n return this.formatValue(field.type, value, { doubleFormatter });\r\n }\r\n\r\n private async formatValue(type: TypeDescription, value: Value, ctx?: { doubleFormatter: (raw: number) => Promise<string>}): Promise<DisplayValue> {\r\n switch (type.valueFormat) {\r\n case PropertyValueFormat.Primitive:\r\n return this.formatPrimitiveValue(type, value, ctx);\r\n case PropertyValueFormat.Array:\r\n return this.formatArrayValue(type, value);\r\n case PropertyValueFormat.Struct:\r\n return this.formatStructValue(type, value);\r\n }\r\n }\r\n\r\n private async formatPrimitiveValue(type: PrimitiveTypeDescription, value: Value, ctx?: { doubleFormatter: (raw: number) => Promise<string>}) {\r\n if (value === undefined)\r\n return \"\";\r\n\r\n const formatDoubleValue = async (raw: number) => ctx ? ctx.doubleFormatter(raw) : formatDouble(raw);\r\n\r\n if (type.typeName === \"point2d\" && isPoint2d(value)) {\r\n return `X: ${await formatDoubleValue(value.x)}; Y: ${await formatDoubleValue(value.y)}`;\r\n }\r\n if (type.typeName === \"point3d\" && isPoint3d(value)) {\r\n return `X: ${await formatDoubleValue(value.x)}; Y: ${await formatDoubleValue(value.y)}; Z: ${await formatDoubleValue(value.z)}`;\r\n }\r\n if (type.typeName === \"dateTime\") {\r\n assert(typeof value === \"string\");\r\n return value;\r\n }\r\n if (type.typeName === \"bool\" || type.typeName === \"boolean\") {\r\n assert(typeof value === \"boolean\");\r\n return value ? \"@Presentation:value.true@\" : \"@Presentation:value.false@\";\r\n }\r\n if (type.typeName === \"int\" || type.typeName === \"long\") {\r\n assert(isNumber(value));\r\n return value.toFixed(0);\r\n }\r\n if (type.typeName === \"double\") {\r\n assert(isNumber(value));\r\n return formatDoubleValue(value);\r\n }\r\n if (type.typeName === \"navigation\") {\r\n assert(Value.isNavigationValue(value));\r\n return value.label.displayValue;\r\n }\r\n\r\n return value.toString();\r\n }\r\n\r\n private async formatStructValue(type: StructTypeDescription, value: Value) {\r\n if (!Value.isMap(value))\r\n return {};\r\n\r\n const formattedMember: DisplayValuesMap = {};\r\n for (const member of type.members) {\r\n formattedMember[member.name] = await this.formatValue(member.type, value[member.name]);\r\n }\r\n return formattedMember;\r\n }\r\n\r\n private async formatArrayValue(type: ArrayTypeDescription, value: Value) {\r\n if (!Value.isArray(value))\r\n return [];\r\n\r\n return Promise.all(value.map(async (arrayVal) => this.formatValue(type.memberType, arrayVal)));\r\n }\r\n}\r\n\r\nfunction formatDouble(value: number) {\r\n return value.toFixed(2);\r\n}\r\n\r\ntype FieldWithKoq = PropertiesField & {\r\n properties: [{\r\n property: PropertyInfo & {\r\n kindOfQuantity: KindOfQuantityInfo;\r\n };\r\n }];\r\n};\r\n\r\nfunction isFieldWithKoq(field: Field): field is FieldWithKoq {\r\n return field.isPropertiesField()\r\n && field.properties.length > 0\r\n && field.properties[0].property.kindOfQuantity !== undefined;\r\n}\r\n\r\nfunction isPoint2d(obj: Value): obj is { x: number, y: number } {\r\n return obj !== undefined && isNumber((obj as any).x) && isNumber((obj as any).y);\r\n}\r\n\r\nfunction isPoint3d(obj: Value): obj is { x: number, y: number, z: number } {\r\n return isPoint2d(obj) && isNumber((obj as any).z);\r\n}\r\n\r\nfunction isNumber(obj: Value): obj is number {\r\n return !isNaN(Number(obj));\r\n}\r\n"]}
@@ -1,8 +1,42 @@
1
1
  /** @packageDocumentation
2
2
  * @module Core
3
3
  */
4
- import { FormatterSpec, ParserSpec, UnitSystemKey } from "@itwin/core-quantity";
4
+ import { FormatProps, FormatterSpec, ParserSpec, UnitSystemKey } from "@itwin/core-quantity";
5
5
  import { SchemaContext } from "@itwin/ecschema-metadata";
6
+ /**
7
+ * A data structure that associates unit systems with property value formatting props. The associations are used for
8
+ * assigning formatting props for specific phenomenon and unit system combinations (see [[FormatsMap]]).
9
+ *
10
+ * @public
11
+ */
12
+ export interface UnitSystemFormat {
13
+ unitSystems: UnitSystemKey[];
14
+ format: FormatProps;
15
+ }
16
+ /**
17
+ * A data structure that associates specific phenomenon with one or more formatting props for specific unit system.
18
+ *
19
+ * Example:
20
+ * ```json
21
+ * {
22
+ * length: [{
23
+ * unitSystems: ["metric"],
24
+ * format: formatForCentimeters,
25
+ * }, {
26
+ * unitSystems: ["imperial", "usCustomary"],
27
+ * format: formatForInches,
28
+ * }, {
29
+ * unitSystems: ["usSurvey"],
30
+ * format: formatForUsSurveyInches,
31
+ * }]
32
+ * }
33
+ * ```
34
+ *
35
+ * @public
36
+ */
37
+ export interface FormatsMap {
38
+ [phenomenon: string]: UnitSystemFormat | UnitSystemFormat[];
39
+ }
6
40
  /** @alpha */
7
41
  export interface FormatOptions {
8
42
  koqName: string;
@@ -12,7 +46,8 @@ export interface FormatOptions {
12
46
  export declare class KoqPropertyValueFormatter {
13
47
  private _schemaContext;
14
48
  private _unitsProvider;
15
- constructor(_schemaContext: SchemaContext);
49
+ private _defaultFormats?;
50
+ constructor(_schemaContext: SchemaContext, defaultFormats?: FormatsMap);
16
51
  format(value: number, options: FormatOptions): Promise<string | undefined>;
17
52
  getFormatterSpec(options: FormatOptions): Promise<FormatterSpec | undefined>;
18
53
  getParserSpec(options: FormatOptions): Promise<ParserSpec | undefined>;
@@ -1 +1 @@
1
- {"version":3,"file":"KoqPropertyValueFormatter.d.ts","sourceRoot":"","sources":["../../../src/presentation-common/KoqPropertyValueFormatter.ts"],"names":[],"mappings":"AAIA;;GAEG;AAEH,OAAO,EAAuB,aAAa,EAAE,UAAU,EAAiB,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACpH,OAAO,EACyC,aAAa,EAE5D,MAAM,0BAA0B,CAAC;AAElC,aAAa;AACb,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,aAAa,CAAC;CAC5B;AAED,aAAa;AACb,qBAAa,yBAAyB;IAGxB,OAAO,CAAC,cAAc;IAFlC,OAAO,CAAC,cAAc,CAAgB;gBAElB,cAAc,EAAE,aAAa;IAIpC,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa;IAO5C,gBAAgB,CAAC,OAAO,EAAE,aAAa;IAUvC,aAAa,CAAC,OAAO,EAAE,aAAa;CASlD"}
1
+ {"version":3,"file":"KoqPropertyValueFormatter.d.ts","sourceRoot":"","sources":["../../../src/presentation-common/KoqPropertyValueFormatter.ts"],"names":[],"mappings":"AAIA;;GAEG;AAEH,OAAO,EAAU,WAAW,EAAE,aAAa,EAAE,UAAU,EAAiB,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACpH,OAAO,EAIL,aAAa,EAMd,MAAM,0BAA0B,CAAC;AAElC;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,aAAa,EAAE,CAAC;IAC7B,MAAM,EAAE,WAAW,CAAC;CACrB;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,WAAW,UAAU;IACzB,CAAC,UAAU,EAAE,MAAM,GAAG,gBAAgB,GAAG,gBAAgB,EAAE,CAAC;CAC7D;AAED,aAAa;AACb,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,aAAa,CAAC;CAC5B;AAED,aAAa;AACb,qBAAa,yBAAyB;IAIxB,OAAO,CAAC,cAAc;IAHlC,OAAO,CAAC,cAAc,CAAgB;IACtC,OAAO,CAAC,eAAe,CAAC,CAAa;gBAEjB,cAAc,EAAE,aAAa,EAAE,cAAc,CAAC,EAAE,UAAU;IAOjE,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa;IAQ5C,gBAAgB,CAAC,OAAO,EAAE,aAAa;IAWvC,aAAa,CAAC,OAAO,EAAE,aAAa;CAUlD"}
@@ -1,90 +1,122 @@
1
1
  /*---------------------------------------------------------------------------------------------
2
- * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
3
- * See LICENSE.md in the project root for license terms and full copyright notice.
4
- *--------------------------------------------------------------------------------------------*/
2
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
3
+ * See LICENSE.md in the project root for license terms and full copyright notice.
4
+ *--------------------------------------------------------------------------------------------*/
5
5
  /** @packageDocumentation
6
6
  * @module Core
7
7
  */
8
8
  import { Format, FormatterSpec, ParserSpec } from "@itwin/core-quantity";
9
- import { getFormatProps, SchemaKey, SchemaMatchType, SchemaUnitProvider, } from "@itwin/ecschema-metadata";
9
+ import { getFormatProps, InvertedUnit, SchemaKey, SchemaMatchType, SchemaUnitProvider, } from "@itwin/ecschema-metadata";
10
10
  /** @alpha */
11
11
  export class KoqPropertyValueFormatter {
12
- constructor(_schemaContext) {
12
+ constructor(_schemaContext, defaultFormats) {
13
13
  this._schemaContext = _schemaContext;
14
14
  this._unitsProvider = new SchemaUnitProvider(_schemaContext);
15
+ this._defaultFormats = defaultFormats
16
+ ? Object.entries(defaultFormats).reduce((acc, [phenomenon, unitSystemFormats]) => ({ ...acc, [phenomenon.toUpperCase()]: unitSystemFormats }), {})
17
+ : /* istanbul ignore next */ undefined;
15
18
  }
16
19
  async format(value, options) {
17
20
  const formatterSpec = await this.getFormatterSpec(options);
18
- if (!formatterSpec)
21
+ if (!formatterSpec) {
19
22
  return undefined;
23
+ }
20
24
  return formatterSpec.applyFormatting(value);
21
25
  }
22
26
  async getFormatterSpec(options) {
23
- const formattingProps = await getFormattingProps(this._schemaContext, options);
24
- if (!formattingProps)
27
+ const formattingProps = await getFormattingProps(this._schemaContext, this._defaultFormats, options);
28
+ if (!formattingProps) {
25
29
  return undefined;
30
+ }
26
31
  const { formatProps, persistenceUnitName } = formattingProps;
27
32
  const persistenceUnit = await this._unitsProvider.findUnitByName(persistenceUnitName);
28
33
  const format = await Format.createFromJSON("", this._unitsProvider, formatProps);
29
34
  return FormatterSpec.create("", format, this._unitsProvider, persistenceUnit);
30
35
  }
31
36
  async getParserSpec(options) {
32
- const formattingProps = await getFormattingProps(this._schemaContext, options);
33
- if (!formattingProps)
37
+ const formattingProps = await getFormattingProps(this._schemaContext, this._defaultFormats, options);
38
+ if (!formattingProps) {
34
39
  return undefined;
40
+ }
35
41
  const { formatProps, persistenceUnitName } = formattingProps;
36
42
  const persistenceUnit = await this._unitsProvider.findUnitByName(persistenceUnitName);
37
43
  const format = await Format.createFromJSON("", this._unitsProvider, formatProps);
38
44
  return ParserSpec.create(format, this._unitsProvider, persistenceUnit);
39
45
  }
40
46
  }
41
- async function getFormattingProps(schemaLocater, options) {
47
+ async function getFormattingProps(schemaLocater, defaultFormats, options) {
42
48
  const { koqName, unitSystem } = options;
43
49
  const koq = await getKoq(schemaLocater, koqName);
44
- if (!koq)
50
+ if (!koq) {
45
51
  return undefined;
52
+ }
46
53
  const persistenceUnit = await koq.persistenceUnit;
47
54
  // istanbul ignore if
48
- if (!persistenceUnit)
55
+ if (!persistenceUnit) {
49
56
  return undefined;
50
- const formatProps = await getKoqFormatProps(koq, persistenceUnit, unitSystem);
51
- if (!formatProps)
57
+ }
58
+ const formatProps = await getKoqFormatProps(koq, persistenceUnit, defaultFormats, unitSystem);
59
+ if (!formatProps) {
52
60
  return undefined;
61
+ }
53
62
  return { formatProps, persistenceUnitName: persistenceUnit.fullName };
54
63
  }
55
64
  async function getKoq(schemaLocater, fullName) {
56
65
  const [schemaName, propKoqName] = fullName.split(":");
57
66
  const schema = await schemaLocater.getSchema(new SchemaKey(schemaName), SchemaMatchType.Latest);
58
- if (!schema)
67
+ if (!schema) {
59
68
  return undefined;
69
+ }
60
70
  return schema.getItem(propKoqName);
61
71
  }
62
- async function getKoqFormatProps(koq, persistenceUnit, unitSystem) {
63
- const unitSystems = getUnitSystemGroupNames(unitSystem);
72
+ async function getKoqFormatProps(koq, persistenceUnit, defaultFormats, unitSystem) {
73
+ const unitSystemMatchers = getUnitSystemGroupMatchers(unitSystem);
64
74
  // use one of KOQ presentation format that matches requested unit system
65
- const presentationFormat = await getKoqPresentationFormat(koq, unitSystems);
66
- if (presentationFormat)
75
+ const presentationFormat = await getKoqPresentationFormat(koq, unitSystemMatchers);
76
+ if (presentationFormat) {
67
77
  return getFormatProps(presentationFormat);
78
+ }
79
+ // use one of the formats in default formats map if there is one for matching phenomena and requested unit
80
+ // system combination
81
+ if (defaultFormats && unitSystem) {
82
+ const actualPersistenceUnit = persistenceUnit instanceof InvertedUnit ? /* istanbul ignore next */ await persistenceUnit.invertsUnit : persistenceUnit;
83
+ const phenomenon = await actualPersistenceUnit?.phenomenon;
84
+ // istanbul ignore else
85
+ if (phenomenon && defaultFormats[phenomenon.name.toUpperCase()]) {
86
+ const defaultPhenomenonFormats = defaultFormats[phenomenon.name.toUpperCase()];
87
+ for (const defaultUnitSystemFormat of Array.isArray(defaultPhenomenonFormats)
88
+ ? /* istanbul ignore next */ defaultPhenomenonFormats
89
+ : [defaultPhenomenonFormats]) {
90
+ if (defaultUnitSystemFormat.unitSystems.includes(unitSystem)) {
91
+ return defaultUnitSystemFormat.format;
92
+ }
93
+ }
94
+ }
95
+ }
68
96
  // use persistence unit format if it matches requested unit system and matching presentation format was not found
69
97
  const persistenceUnitSystem = await persistenceUnit.unitSystem;
70
- if (persistenceUnitSystem && unitSystems.includes(persistenceUnitSystem.name.toUpperCase()))
98
+ if (persistenceUnitSystem && unitSystemMatchers.some((matcher) => matcher(persistenceUnitSystem))) {
71
99
  return getPersistenceUnitFormatProps(persistenceUnit);
100
+ }
72
101
  // use default presentation format if persistence unit does not match requested unit system
73
- if (koq.defaultPresentationFormat)
102
+ if (koq.defaultPresentationFormat) {
74
103
  return getFormatProps(koq.defaultPresentationFormat);
104
+ }
75
105
  return undefined;
76
106
  }
77
- async function getKoqPresentationFormat(koq, unitSystems) {
107
+ async function getKoqPresentationFormat(koq, unitSystemMatchers) {
78
108
  const presentationFormats = koq.presentationFormats;
79
- for (const system of unitSystems) {
109
+ for (const matcher of unitSystemMatchers) {
80
110
  for (const format of presentationFormats) {
81
111
  const unit = format.units && format.units[0][0];
82
112
  // istanbul ignore if
83
- if (!unit)
113
+ if (!unit) {
84
114
  continue;
115
+ }
85
116
  const currentUnitSystem = await unit.unitSystem;
86
- if (currentUnitSystem && currentUnitSystem.name.toUpperCase() === system)
117
+ if (currentUnitSystem && matcher(currentUnitSystem)) {
87
118
  return format;
119
+ }
88
120
  }
89
121
  }
90
122
  return undefined;
@@ -98,23 +130,29 @@ function getPersistenceUnitFormatProps(persistenceUnit) {
98
130
  uomSeparator: " ",
99
131
  decimalSeparator: ".",
100
132
  composite: {
101
- units: [{
133
+ units: [
134
+ {
102
135
  name: persistenceUnit.fullName,
103
136
  label: persistenceUnit.label,
104
- }],
137
+ },
138
+ ],
105
139
  },
106
140
  };
107
141
  }
108
- function getUnitSystemGroupNames(unitSystem) {
109
- switch (unitSystem) {
142
+ function getUnitSystemGroupMatchers(groupKey) {
143
+ function createMatcher(name) {
144
+ const names = Array.isArray(name) ? name : [name];
145
+ return (unitSystem) => names.some((n) => n === unitSystem.name.toUpperCase());
146
+ }
147
+ switch (groupKey) {
110
148
  case "imperial":
111
- return ["IMPERIAL", "USCUSTOM", "INTERNATIONAL", "FINANCE"];
149
+ return ["IMPERIAL", "USCUSTOM", "INTERNATIONAL", "FINANCE"].map(createMatcher);
112
150
  case "metric":
113
- return ["SI", "METRIC", "INTERNATIONAL", "FINANCE"];
151
+ return [["SI", "METRIC"], "INTERNATIONAL", "FINANCE"].map(createMatcher);
114
152
  case "usCustomary":
115
- return ["USCUSTOM", "INTERNATIONAL", "FINANCE"];
153
+ return ["USCUSTOM", "INTERNATIONAL", "FINANCE"].map(createMatcher);
116
154
  case "usSurvey":
117
- return ["USSURVEY", "USCUSTOM", "INTERNATIONAL", "FINANCE"];
155
+ return ["USSURVEY", "USCUSTOM", "INTERNATIONAL", "FINANCE"].map(createMatcher);
118
156
  }
119
157
  return [];
120
158
  }
@@ -1 +1 @@
1
- {"version":3,"file":"KoqPropertyValueFormatter.js","sourceRoot":"","sources":["../../../src/presentation-common/KoqPropertyValueFormatter.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n/** @packageDocumentation\r\n * @module Core\r\n */\r\n\r\nimport { Format, FormatProps, FormatterSpec, ParserSpec, UnitsProvider, UnitSystemKey } from \"@itwin/core-quantity\";\r\nimport {\r\n getFormatProps, InvertedUnit, KindOfQuantity, SchemaContext, SchemaKey, SchemaMatchType, SchemaUnitProvider,\r\n Unit,\r\n} from \"@itwin/ecschema-metadata\";\r\n\r\n/** @alpha */\r\nexport interface FormatOptions {\r\n koqName: string;\r\n unitSystem?: UnitSystemKey;\r\n}\r\n\r\n/** @alpha */\r\nexport class KoqPropertyValueFormatter {\r\n private _unitsProvider: UnitsProvider;\r\n\r\n constructor(private _schemaContext: SchemaContext) {\r\n this._unitsProvider = new SchemaUnitProvider(_schemaContext);\r\n }\r\n\r\n public async format(value: number, options: FormatOptions) {\r\n const formatterSpec = await this.getFormatterSpec(options);\r\n if (!formatterSpec)\r\n return undefined;\r\n return formatterSpec.applyFormatting(value);\r\n }\r\n\r\n public async getFormatterSpec(options: FormatOptions) {\r\n const formattingProps = await getFormattingProps(this._schemaContext, options);\r\n if (!formattingProps)\r\n return undefined;\r\n const { formatProps, persistenceUnitName } = formattingProps;\r\n const persistenceUnit = await this._unitsProvider.findUnitByName(persistenceUnitName);\r\n const format = await Format.createFromJSON(\"\", this._unitsProvider, formatProps);\r\n return FormatterSpec.create(\"\", format, this._unitsProvider, persistenceUnit);\r\n }\r\n\r\n public async getParserSpec(options: FormatOptions) {\r\n const formattingProps = await getFormattingProps(this._schemaContext, options);\r\n if (!formattingProps)\r\n return undefined;\r\n const { formatProps, persistenceUnitName } = formattingProps;\r\n const persistenceUnit = await this._unitsProvider.findUnitByName(persistenceUnitName);\r\n const format = await Format.createFromJSON(\"\", this._unitsProvider, formatProps);\r\n return ParserSpec.create(format, this._unitsProvider, persistenceUnit);\r\n }\r\n}\r\n\r\ninterface FormattingProps {\r\n formatProps: FormatProps;\r\n persistenceUnitName: string;\r\n}\r\n\r\nasync function getFormattingProps(schemaLocater: SchemaContext, options: FormatOptions): Promise<FormattingProps | undefined> {\r\n const { koqName, unitSystem } = options;\r\n\r\n const koq = await getKoq(schemaLocater, koqName);\r\n if (!koq)\r\n return undefined;\r\n\r\n const persistenceUnit = await koq.persistenceUnit;\r\n // istanbul ignore if\r\n if (!persistenceUnit)\r\n return undefined;\r\n\r\n const formatProps = await getKoqFormatProps(koq, persistenceUnit, unitSystem);\r\n if (!formatProps)\r\n return undefined;\r\n\r\n return { formatProps, persistenceUnitName: persistenceUnit.fullName };\r\n}\r\n\r\nasync function getKoq(schemaLocater: SchemaContext, fullName: string) {\r\n const [schemaName, propKoqName] = fullName.split(\":\");\r\n const schema = await schemaLocater.getSchema(new SchemaKey(schemaName), SchemaMatchType.Latest);\r\n if (!schema)\r\n return undefined;\r\n\r\n return schema.getItem<KindOfQuantity>(propKoqName);\r\n}\r\n\r\nasync function getKoqFormatProps(koq: KindOfQuantity, persistenceUnit: Unit | InvertedUnit, unitSystem?: UnitSystemKey) {\r\n const unitSystems = getUnitSystemGroupNames(unitSystem);\r\n // use one of KOQ presentation format that matches requested unit system\r\n const presentationFormat = await getKoqPresentationFormat(koq, unitSystems);\r\n if (presentationFormat)\r\n return getFormatProps(presentationFormat);\r\n\r\n // use persistence unit format if it matches requested unit system and matching presentation format was not found\r\n const persistenceUnitSystem = await persistenceUnit.unitSystem;\r\n if (persistenceUnitSystem && unitSystems.includes(persistenceUnitSystem.name.toUpperCase()))\r\n return getPersistenceUnitFormatProps(persistenceUnit);\r\n\r\n // use default presentation format if persistence unit does not match requested unit system\r\n if (koq.defaultPresentationFormat)\r\n return getFormatProps(koq.defaultPresentationFormat);\r\n\r\n return undefined;\r\n}\r\n\r\nasync function getKoqPresentationFormat(koq: KindOfQuantity, unitSystems: string[]) {\r\n const presentationFormats = koq.presentationFormats;\r\n for (const system of unitSystems) {\r\n for (const format of presentationFormats) {\r\n const unit = format.units && format.units[0][0];\r\n // istanbul ignore if\r\n if (!unit)\r\n continue;\r\n\r\n const currentUnitSystem = await unit.unitSystem;\r\n if (currentUnitSystem && currentUnitSystem.name.toUpperCase() === system)\r\n return format;\r\n }\r\n }\r\n return undefined;\r\n}\r\n\r\nfunction getPersistenceUnitFormatProps(persistenceUnit: Unit | InvertedUnit): FormatProps {\r\n // Same as Format \"DefaultRealU\" in Formats ecschema\r\n return {\r\n formatTraits: [\"keepSingleZero\", \"keepDecimalPoint\", \"showUnitLabel\"],\r\n precision: 6,\r\n type: \"Decimal\",\r\n uomSeparator: \" \",\r\n decimalSeparator: \".\",\r\n composite: {\r\n units: [{\r\n name: persistenceUnit.fullName,\r\n label: persistenceUnit.label,\r\n }],\r\n },\r\n };\r\n}\r\n\r\nfunction getUnitSystemGroupNames(unitSystem?: UnitSystemKey) {\r\n switch (unitSystem) {\r\n case \"imperial\":\r\n return [\"IMPERIAL\", \"USCUSTOM\", \"INTERNATIONAL\", \"FINANCE\"];\r\n case \"metric\":\r\n return [\"SI\", \"METRIC\", \"INTERNATIONAL\", \"FINANCE\"];\r\n case \"usCustomary\":\r\n return [\"USCUSTOM\", \"INTERNATIONAL\", \"FINANCE\"];\r\n case \"usSurvey\":\r\n return [\"USSURVEY\", \"USCUSTOM\", \"INTERNATIONAL\", \"FINANCE\"];\r\n }\r\n return [];\r\n}\r\n"]}
1
+ {"version":3,"file":"KoqPropertyValueFormatter.js","sourceRoot":"","sources":["../../../src/presentation-common/KoqPropertyValueFormatter.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n * See LICENSE.md in the project root for license terms and full copyright notice.\r\n *--------------------------------------------------------------------------------------------*/\r\n/** @packageDocumentation\r\n * @module Core\r\n */\r\n\r\nimport { Format, FormatProps, FormatterSpec, ParserSpec, UnitsProvider, UnitSystemKey } from \"@itwin/core-quantity\";\r\nimport {\r\n getFormatProps,\r\n InvertedUnit,\r\n KindOfQuantity,\r\n SchemaContext,\r\n SchemaKey,\r\n SchemaMatchType,\r\n SchemaUnitProvider,\r\n Unit,\r\n UnitSystem,\r\n} from \"@itwin/ecschema-metadata\";\r\n\r\n/**\r\n * A data structure that associates unit systems with property value formatting props. The associations are used for\r\n * assigning formatting props for specific phenomenon and unit system combinations (see [[FormatsMap]]).\r\n *\r\n * @public\r\n */\r\nexport interface UnitSystemFormat {\r\n unitSystems: UnitSystemKey[];\r\n format: FormatProps;\r\n}\r\n\r\n/**\r\n * A data structure that associates specific phenomenon with one or more formatting props for specific unit system.\r\n *\r\n * Example:\r\n * ```json\r\n * {\r\n * length: [{\r\n * unitSystems: [\"metric\"],\r\n * format: formatForCentimeters,\r\n * }, {\r\n * unitSystems: [\"imperial\", \"usCustomary\"],\r\n * format: formatForInches,\r\n * }, {\r\n * unitSystems: [\"usSurvey\"],\r\n * format: formatForUsSurveyInches,\r\n * }]\r\n * }\r\n * ```\r\n *\r\n * @public\r\n */\r\nexport interface FormatsMap {\r\n [phenomenon: string]: UnitSystemFormat | UnitSystemFormat[];\r\n}\r\n\r\n/** @alpha */\r\nexport interface FormatOptions {\r\n koqName: string;\r\n unitSystem?: UnitSystemKey;\r\n}\r\n\r\n/** @alpha */\r\nexport class KoqPropertyValueFormatter {\r\n private _unitsProvider: UnitsProvider;\r\n private _defaultFormats?: FormatsMap;\r\n\r\n constructor(private _schemaContext: SchemaContext, defaultFormats?: FormatsMap) {\r\n this._unitsProvider = new SchemaUnitProvider(_schemaContext);\r\n this._defaultFormats = defaultFormats\r\n ? Object.entries(defaultFormats).reduce((acc, [phenomenon, unitSystemFormats]) => ({ ...acc, [phenomenon.toUpperCase()]: unitSystemFormats }), {})\r\n : /* istanbul ignore next */ undefined;\r\n }\r\n\r\n public async format(value: number, options: FormatOptions) {\r\n const formatterSpec = await this.getFormatterSpec(options);\r\n if (!formatterSpec) {\r\n return undefined;\r\n }\r\n return formatterSpec.applyFormatting(value);\r\n }\r\n\r\n public async getFormatterSpec(options: FormatOptions) {\r\n const formattingProps = await getFormattingProps(this._schemaContext, this._defaultFormats, options);\r\n if (!formattingProps) {\r\n return undefined;\r\n }\r\n const { formatProps, persistenceUnitName } = formattingProps;\r\n const persistenceUnit = await this._unitsProvider.findUnitByName(persistenceUnitName);\r\n const format = await Format.createFromJSON(\"\", this._unitsProvider, formatProps);\r\n return FormatterSpec.create(\"\", format, this._unitsProvider, persistenceUnit);\r\n }\r\n\r\n public async getParserSpec(options: FormatOptions) {\r\n const formattingProps = await getFormattingProps(this._schemaContext, this._defaultFormats, options);\r\n if (!formattingProps) {\r\n return undefined;\r\n }\r\n const { formatProps, persistenceUnitName } = formattingProps;\r\n const persistenceUnit = await this._unitsProvider.findUnitByName(persistenceUnitName);\r\n const format = await Format.createFromJSON(\"\", this._unitsProvider, formatProps);\r\n return ParserSpec.create(format, this._unitsProvider, persistenceUnit);\r\n }\r\n}\r\n\r\ninterface FormattingProps {\r\n formatProps: FormatProps;\r\n persistenceUnitName: string;\r\n}\r\n\r\nasync function getFormattingProps(\r\n schemaLocater: SchemaContext,\r\n defaultFormats: FormatsMap | undefined,\r\n options: FormatOptions,\r\n): Promise<FormattingProps | undefined> {\r\n const { koqName, unitSystem } = options;\r\n\r\n const koq = await getKoq(schemaLocater, koqName);\r\n if (!koq) {\r\n return undefined;\r\n }\r\n\r\n const persistenceUnit = await koq.persistenceUnit;\r\n // istanbul ignore if\r\n if (!persistenceUnit) {\r\n return undefined;\r\n }\r\n\r\n const formatProps = await getKoqFormatProps(koq, persistenceUnit, defaultFormats, unitSystem);\r\n if (!formatProps) {\r\n return undefined;\r\n }\r\n\r\n return { formatProps, persistenceUnitName: persistenceUnit.fullName };\r\n}\r\n\r\nasync function getKoq(schemaLocater: SchemaContext, fullName: string) {\r\n const [schemaName, propKoqName] = fullName.split(\":\");\r\n const schema = await schemaLocater.getSchema(new SchemaKey(schemaName), SchemaMatchType.Latest);\r\n if (!schema) {\r\n return undefined;\r\n }\r\n return schema.getItem<KindOfQuantity>(propKoqName);\r\n}\r\n\r\nasync function getKoqFormatProps(\r\n koq: KindOfQuantity,\r\n persistenceUnit: Unit | InvertedUnit,\r\n defaultFormats: FormatsMap | undefined,\r\n unitSystem?: UnitSystemKey,\r\n) {\r\n const unitSystemMatchers = getUnitSystemGroupMatchers(unitSystem);\r\n // use one of KOQ presentation format that matches requested unit system\r\n const presentationFormat = await getKoqPresentationFormat(koq, unitSystemMatchers);\r\n if (presentationFormat) {\r\n return getFormatProps(presentationFormat);\r\n }\r\n\r\n // use one of the formats in default formats map if there is one for matching phenomena and requested unit\r\n // system combination\r\n if (defaultFormats && unitSystem) {\r\n const actualPersistenceUnit = persistenceUnit instanceof InvertedUnit ? /* istanbul ignore next */ await persistenceUnit.invertsUnit : persistenceUnit;\r\n const phenomenon = await actualPersistenceUnit?.phenomenon;\r\n // istanbul ignore else\r\n if (phenomenon && defaultFormats[phenomenon.name.toUpperCase()]) {\r\n const defaultPhenomenonFormats = defaultFormats[phenomenon.name.toUpperCase()];\r\n for (const defaultUnitSystemFormat of Array.isArray(defaultPhenomenonFormats)\r\n ? /* istanbul ignore next */ defaultPhenomenonFormats\r\n : [defaultPhenomenonFormats]) {\r\n if (defaultUnitSystemFormat.unitSystems.includes(unitSystem)) {\r\n return defaultUnitSystemFormat.format;\r\n }\r\n }\r\n }\r\n }\r\n\r\n // use persistence unit format if it matches requested unit system and matching presentation format was not found\r\n const persistenceUnitSystem = await persistenceUnit.unitSystem;\r\n if (persistenceUnitSystem && unitSystemMatchers.some((matcher) => matcher(persistenceUnitSystem))) {\r\n return getPersistenceUnitFormatProps(persistenceUnit);\r\n }\r\n\r\n // use default presentation format if persistence unit does not match requested unit system\r\n if (koq.defaultPresentationFormat) {\r\n return getFormatProps(koq.defaultPresentationFormat);\r\n }\r\n\r\n return undefined;\r\n}\r\n\r\nasync function getKoqPresentationFormat(koq: KindOfQuantity, unitSystemMatchers: Array<(unitSystem: UnitSystem) => boolean>) {\r\n const presentationFormats = koq.presentationFormats;\r\n for (const matcher of unitSystemMatchers) {\r\n for (const format of presentationFormats) {\r\n const unit = format.units && format.units[0][0];\r\n // istanbul ignore if\r\n if (!unit) {\r\n continue;\r\n }\r\n const currentUnitSystem = await unit.unitSystem;\r\n if (currentUnitSystem && matcher(currentUnitSystem)) {\r\n return format;\r\n }\r\n }\r\n }\r\n return undefined;\r\n}\r\n\r\nfunction getPersistenceUnitFormatProps(persistenceUnit: Unit | InvertedUnit): FormatProps {\r\n // Same as Format \"DefaultRealU\" in Formats ecschema\r\n return {\r\n formatTraits: [\"keepSingleZero\", \"keepDecimalPoint\", \"showUnitLabel\"],\r\n precision: 6,\r\n type: \"Decimal\",\r\n uomSeparator: \" \",\r\n decimalSeparator: \".\",\r\n composite: {\r\n units: [\r\n {\r\n name: persistenceUnit.fullName,\r\n label: persistenceUnit.label,\r\n },\r\n ],\r\n },\r\n };\r\n}\r\n\r\nfunction getUnitSystemGroupMatchers(groupKey?: UnitSystemKey) {\r\n function createMatcher(name: string | string[]) {\r\n const names = Array.isArray(name) ? name : [name];\r\n return (unitSystem: UnitSystem) => names.some((n) => n === unitSystem.name.toUpperCase());\r\n }\r\n switch (groupKey) {\r\n case \"imperial\":\r\n return [\"IMPERIAL\", \"USCUSTOM\", \"INTERNATIONAL\", \"FINANCE\"].map(createMatcher);\r\n case \"metric\":\r\n return [[\"SI\", \"METRIC\"], \"INTERNATIONAL\", \"FINANCE\"].map(createMatcher);\r\n case \"usCustomary\":\r\n return [\"USCUSTOM\", \"INTERNATIONAL\", \"FINANCE\"].map(createMatcher);\r\n case \"usSurvey\":\r\n return [\"USSURVEY\", \"USCUSTOM\", \"INTERNATIONAL\", \"FINANCE\"].map(createMatcher);\r\n }\r\n return [];\r\n}\r\n"]}
@@ -5,8 +5,7 @@ import { UnitSystemKey } from "@itwin/core-quantity";
5
5
  import { KoqPropertyValueFormatter } from "../KoqPropertyValueFormatter";
6
6
  import { Content } from "./Content";
7
7
  import { Field } from "./Fields";
8
- import { ArrayTypeDescription, PrimitiveTypeDescription, StructTypeDescription, TypeDescription } from "./TypeDescription";
9
- import { DisplayValue, DisplayValuesMap, Value } from "./Value";
8
+ import { DisplayValue, Value } from "./Value";
10
9
  /** @alpha */
11
10
  export declare class ContentFormatter {
12
11
  private _propertyValueFormatter;
@@ -21,9 +20,9 @@ export declare class ContentPropertyValueFormatter {
21
20
  private _koqValueFormatter;
22
21
  constructor(_koqValueFormatter: KoqPropertyValueFormatter);
23
22
  formatPropertyValue(field: Field, value: Value, unitSystem?: UnitSystemKey): Promise<DisplayValue>;
24
- formatValue(type: TypeDescription, value: Value): DisplayValue;
25
- formatPrimitiveValue(type: PrimitiveTypeDescription, value: Value): string;
26
- formatStructValue(type: StructTypeDescription, value: Value): DisplayValuesMap;
27
- formatArrayValue(type: ArrayTypeDescription, value: Value): DisplayValue[];
23
+ private formatValue;
24
+ private formatPrimitiveValue;
25
+ private formatStructValue;
26
+ private formatArrayValue;
28
27
  }
29
28
  //# sourceMappingURL=PropertyValueFormatter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"PropertyValueFormatter.d.ts","sourceRoot":"","sources":["../../../../src/presentation-common/content/PropertyValueFormatter.ts"],"names":[],"mappings":"AAIA;;GAEG;AAGH,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD,OAAO,EAAE,yBAAyB,EAAE,MAAM,8BAA8B,CAAC;AAEzE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,KAAK,EAAmB,MAAM,UAAU,CAAC;AAClD,OAAO,EAAE,oBAAoB,EAAE,wBAAwB,EAAuB,qBAAqB,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAChJ,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAsB,KAAK,EAAE,MAAM,SAAS,CAAC;AAEpF,aAAa;AACb,qBAAa,gBAAgB;IACf,OAAO,CAAC,uBAAuB;IAAiC,OAAO,CAAC,WAAW,CAAC;gBAA5E,uBAAuB,EAAE,6BAA6B,EAAU,WAAW,CAAC,2BAAe;IAElG,aAAa,CAAC,OAAO,EAAE,OAAO;YAQ7B,YAAY;YAqBZ,gCAAgC;CAM/C;AAED,aAAa;AACb,qBAAa,6BAA6B;IAC5B,OAAO,CAAC,kBAAkB;gBAAlB,kBAAkB,EAAE,yBAAyB;IAEpD,mBAAmB,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC;IAWxG,WAAW,CAAC,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,KAAK,GAAG,YAAY;IAW9D,oBAAoB,CAAC,IAAI,EAAE,wBAAwB,EAAE,KAAK,EAAE,KAAK;IAkCjE,iBAAiB,CAAC,IAAI,EAAE,qBAAqB,EAAE,KAAK,EAAE,KAAK;IAW3D,gBAAgB,CAAC,IAAI,EAAE,oBAAoB,EAAE,KAAK,EAAE,KAAK;CAMjE"}
1
+ {"version":3,"file":"PropertyValueFormatter.d.ts","sourceRoot":"","sources":["../../../../src/presentation-common/content/PropertyValueFormatter.ts"],"names":[],"mappings":"AAIA;;GAEG;AAGH,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD,OAAO,EAAE,yBAAyB,EAAE,MAAM,8BAA8B,CAAC;AAEzE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,KAAK,EAAmB,MAAM,UAAU,CAAC;AAElD,OAAO,EAAE,YAAY,EAAwC,KAAK,EAAE,MAAM,SAAS,CAAC;AAEpF,aAAa;AACb,qBAAa,gBAAgB;IACf,OAAO,CAAC,uBAAuB;IAAiC,OAAO,CAAC,WAAW,CAAC;gBAA5E,uBAAuB,EAAE,6BAA6B,EAAU,WAAW,CAAC,2BAAe;IAElG,aAAa,CAAC,OAAO,EAAE,OAAO;YAQ7B,YAAY;YAqBZ,gCAAgC;CAM/C;AAED,aAAa;AACb,qBAAa,6BAA6B;IAC5B,OAAO,CAAC,kBAAkB;gBAAlB,kBAAkB,EAAE,yBAAyB;IAEpD,mBAAmB,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC;YAcjG,WAAW;YAWX,oBAAoB;YAoCpB,iBAAiB;YAWjB,gBAAgB;CAM/B"}
@@ -50,32 +50,36 @@ export class ContentPropertyValueFormatter {
50
50
  this._koqValueFormatter = _koqValueFormatter;
51
51
  }
52
52
  async formatPropertyValue(field, value, unitSystem) {
53
- if (isFieldWithKoq(field) && typeof value === "number") {
54
- const koq = field.properties[0].property.kindOfQuantity;
55
- const formattedValue = await this._koqValueFormatter.format(value, { koqName: koq.name, unitSystem });
56
- if (formattedValue !== undefined)
57
- return formattedValue;
58
- }
59
- return this.formatValue(field.type, value);
53
+ const doubleFormatter = isFieldWithKoq(field)
54
+ ? async (rawValue) => {
55
+ const koq = field.properties[0].property.kindOfQuantity;
56
+ const formattedValue = await this._koqValueFormatter.format(rawValue, { koqName: koq.name, unitSystem });
57
+ if (formattedValue !== undefined)
58
+ return formattedValue;
59
+ return formatDouble(rawValue);
60
+ }
61
+ : async (rawValue) => formatDouble(rawValue);
62
+ return this.formatValue(field.type, value, { doubleFormatter });
60
63
  }
61
- formatValue(type, value) {
64
+ async formatValue(type, value, ctx) {
62
65
  switch (type.valueFormat) {
63
66
  case PropertyValueFormat.Primitive:
64
- return this.formatPrimitiveValue(type, value);
67
+ return this.formatPrimitiveValue(type, value, ctx);
65
68
  case PropertyValueFormat.Array:
66
69
  return this.formatArrayValue(type, value);
67
70
  case PropertyValueFormat.Struct:
68
71
  return this.formatStructValue(type, value);
69
72
  }
70
73
  }
71
- formatPrimitiveValue(type, value) {
74
+ async formatPrimitiveValue(type, value, ctx) {
72
75
  if (value === undefined)
73
76
  return "";
77
+ const formatDoubleValue = async (raw) => ctx ? ctx.doubleFormatter(raw) : formatDouble(raw);
74
78
  if (type.typeName === "point2d" && isPoint2d(value)) {
75
- return `X: ${formatDouble(value.x)} Y: ${formatDouble(value.y)}`;
79
+ return `X: ${await formatDoubleValue(value.x)}; Y: ${await formatDoubleValue(value.y)}`;
76
80
  }
77
81
  if (type.typeName === "point3d" && isPoint3d(value)) {
78
- return `X: ${formatDouble(value.x)} Y: ${formatDouble(value.y)} Z: ${formatDouble(value.z)}`;
82
+ return `X: ${await formatDoubleValue(value.x)}; Y: ${await formatDoubleValue(value.y)}; Z: ${await formatDoubleValue(value.z)}`;
79
83
  }
80
84
  if (type.typeName === "dateTime") {
81
85
  assert(typeof value === "string");
@@ -91,7 +95,7 @@ export class ContentPropertyValueFormatter {
91
95
  }
92
96
  if (type.typeName === "double") {
93
97
  assert(isNumber(value));
94
- return formatDouble(value);
98
+ return formatDoubleValue(value);
95
99
  }
96
100
  if (type.typeName === "navigation") {
97
101
  assert(Value.isNavigationValue(value));
@@ -99,19 +103,19 @@ export class ContentPropertyValueFormatter {
99
103
  }
100
104
  return value.toString();
101
105
  }
102
- formatStructValue(type, value) {
106
+ async formatStructValue(type, value) {
103
107
  if (!Value.isMap(value))
104
108
  return {};
105
109
  const formattedMember = {};
106
110
  for (const member of type.members) {
107
- formattedMember[member.name] = this.formatValue(member.type, value[member.name]);
111
+ formattedMember[member.name] = await this.formatValue(member.type, value[member.name]);
108
112
  }
109
113
  return formattedMember;
110
114
  }
111
- formatArrayValue(type, value) {
115
+ async formatArrayValue(type, value) {
112
116
  if (!Value.isArray(value))
113
117
  return [];
114
- return value.map((arrayVal) => this.formatValue(type.memberType, arrayVal));
118
+ return Promise.all(value.map(async (arrayVal) => this.formatValue(type.memberType, arrayVal)));
115
119
  }
116
120
  }
117
121
  function formatDouble(value) {
@@ -1 +1 @@
1
- {"version":3,"file":"PropertyValueFormatter.js","sourceRoot":"","sources":["../../../../src/presentation-common/content/PropertyValueFormatter.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n/** @packageDocumentation\r\n * @module Content\r\n */\r\n\r\nimport { assert } from \"@itwin/core-bentley\";\r\nimport { UnitSystemKey } from \"@itwin/core-quantity\";\r\nimport { KindOfQuantityInfo, PropertyInfo } from \"../EC\";\r\nimport { KoqPropertyValueFormatter } from \"../KoqPropertyValueFormatter\";\r\nimport { ValuesDictionary } from \"../Utils\";\r\nimport { Content } from \"./Content\";\r\nimport { Field, PropertiesField } from \"./Fields\";\r\nimport { ArrayTypeDescription, PrimitiveTypeDescription, PropertyValueFormat, StructTypeDescription, TypeDescription } from \"./TypeDescription\";\r\nimport { DisplayValue, DisplayValuesMap, NestedContentValue, Value } from \"./Value\";\r\n\r\n/** @alpha */\r\nexport class ContentFormatter {\r\n constructor(private _propertyValueFormatter: ContentPropertyValueFormatter, private _unitSystem?: UnitSystemKey) { }\r\n\r\n public async formatContent(content: Content) {\r\n const descriptor = content.descriptor;\r\n for (const item of content.contentSet) {\r\n await this.formatValues(item.values, item.displayValues, descriptor.fields, item.mergedFieldNames);\r\n }\r\n return content;\r\n }\r\n\r\n private async formatValues(values: ValuesDictionary<Value>, displayValues: ValuesDictionary<DisplayValue>, fields: Field[], mergedFields: string[]) {\r\n for (const field of fields) {\r\n const value = values[field.name];\r\n\r\n // format display value of merged values\r\n if (mergedFields.includes(field.name)) {\r\n displayValues[field.name] = \"@Presentation:label.varies@\";\r\n continue;\r\n }\r\n\r\n // format display values of nested content field\r\n if (field.isNestedContentField()) {\r\n assert(Value.isNestedContent(value));\r\n await this.formatNestedContentDisplayValues(value, field.nestedFields);\r\n continue;\r\n }\r\n\r\n displayValues[field.name] = await this._propertyValueFormatter.formatPropertyValue(field, value, this._unitSystem);\r\n }\r\n }\r\n\r\n private async formatNestedContentDisplayValues(nestedValues: NestedContentValue[], fields: Field[]) {\r\n for (const nestedValue of nestedValues) {\r\n await this.formatValues(nestedValue.values, nestedValue.displayValues, fields, nestedValue.mergedFieldNames);\r\n }\r\n }\r\n\r\n}\r\n\r\n/** @alpha */\r\nexport class ContentPropertyValueFormatter {\r\n constructor(private _koqValueFormatter: KoqPropertyValueFormatter) { }\r\n\r\n public async formatPropertyValue(field: Field, value: Value, unitSystem?: UnitSystemKey): Promise<DisplayValue> {\r\n if (isFieldWithKoq(field) && typeof value === \"number\") {\r\n const koq = field.properties[0].property.kindOfQuantity;\r\n const formattedValue = await this._koqValueFormatter.format(value, { koqName: koq.name, unitSystem });\r\n if (formattedValue !== undefined)\r\n return formattedValue;\r\n }\r\n\r\n return this.formatValue(field.type, value);\r\n }\r\n\r\n public formatValue(type: TypeDescription, value: Value): DisplayValue {\r\n switch (type.valueFormat) {\r\n case PropertyValueFormat.Primitive:\r\n return this.formatPrimitiveValue(type, value);\r\n case PropertyValueFormat.Array:\r\n return this.formatArrayValue(type, value);\r\n case PropertyValueFormat.Struct:\r\n return this.formatStructValue(type, value);\r\n }\r\n }\r\n\r\n public formatPrimitiveValue(type: PrimitiveTypeDescription, value: Value) {\r\n if (value === undefined)\r\n return \"\";\r\n\r\n if (type.typeName === \"point2d\" && isPoint2d(value)) {\r\n return `X: ${formatDouble(value.x)} Y: ${formatDouble(value.y)}`;\r\n }\r\n if (type.typeName === \"point3d\" && isPoint3d(value)) {\r\n return `X: ${formatDouble(value.x)} Y: ${formatDouble(value.y)} Z: ${formatDouble(value.z)}`;\r\n }\r\n if (type.typeName === \"dateTime\") {\r\n assert(typeof value === \"string\");\r\n return value;\r\n }\r\n if (type.typeName === \"bool\" || type.typeName === \"boolean\") {\r\n assert(typeof value === \"boolean\");\r\n return value ? \"@Presentation:value.true@\" : \"@Presentation:value.false@\";\r\n }\r\n if (type.typeName === \"int\" || type.typeName === \"long\") {\r\n assert(isNumber(value));\r\n return value.toFixed(0);\r\n }\r\n if (type.typeName === \"double\") {\r\n assert(isNumber(value));\r\n return formatDouble(value);\r\n }\r\n if (type.typeName === \"navigation\") {\r\n assert(Value.isNavigationValue(value));\r\n return value.label.displayValue;\r\n }\r\n\r\n return value.toString();\r\n }\r\n\r\n public formatStructValue(type: StructTypeDescription, value: Value) {\r\n if (!Value.isMap(value))\r\n return {};\r\n\r\n const formattedMember: DisplayValuesMap = {};\r\n for (const member of type.members) {\r\n formattedMember[member.name] = this.formatValue(member.type, value[member.name]);\r\n }\r\n return formattedMember;\r\n }\r\n\r\n public formatArrayValue(type: ArrayTypeDescription, value: Value) {\r\n if (!Value.isArray(value))\r\n return [];\r\n\r\n return value.map((arrayVal) => this.formatValue(type.memberType, arrayVal));\r\n }\r\n}\r\n\r\nfunction formatDouble(value: number) {\r\n return value.toFixed(2);\r\n}\r\n\r\ntype FieldWithKoq = PropertiesField & {\r\n properties: [{\r\n property: PropertyInfo & {\r\n kindOfQuantity: KindOfQuantityInfo;\r\n };\r\n }];\r\n};\r\n\r\nfunction isFieldWithKoq(field: Field): field is FieldWithKoq {\r\n return field.isPropertiesField()\r\n && field.properties.length > 0\r\n && field.properties[0].property.kindOfQuantity !== undefined;\r\n}\r\n\r\nfunction isPoint2d(obj: Value): obj is { x: number, y: number } {\r\n return obj !== undefined && isNumber((obj as any).x) && isNumber((obj as any).y);\r\n}\r\n\r\nfunction isPoint3d(obj: Value): obj is { x: number, y: number, z: number } {\r\n return isPoint2d(obj) && isNumber((obj as any).z);\r\n}\r\n\r\nfunction isNumber(obj: Value): obj is number {\r\n return !isNaN(Number(obj));\r\n}\r\n"]}
1
+ {"version":3,"file":"PropertyValueFormatter.js","sourceRoot":"","sources":["../../../../src/presentation-common/content/PropertyValueFormatter.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n/** @packageDocumentation\r\n * @module Content\r\n */\r\n\r\nimport { assert } from \"@itwin/core-bentley\";\r\nimport { UnitSystemKey } from \"@itwin/core-quantity\";\r\nimport { KindOfQuantityInfo, PropertyInfo } from \"../EC\";\r\nimport { KoqPropertyValueFormatter } from \"../KoqPropertyValueFormatter\";\r\nimport { ValuesDictionary } from \"../Utils\";\r\nimport { Content } from \"./Content\";\r\nimport { Field, PropertiesField } from \"./Fields\";\r\nimport { ArrayTypeDescription, PrimitiveTypeDescription, PropertyValueFormat, StructTypeDescription, TypeDescription } from \"./TypeDescription\";\r\nimport { DisplayValue, DisplayValuesMap, NestedContentValue, Value } from \"./Value\";\r\n\r\n/** @alpha */\r\nexport class ContentFormatter {\r\n constructor(private _propertyValueFormatter: ContentPropertyValueFormatter, private _unitSystem?: UnitSystemKey) { }\r\n\r\n public async formatContent(content: Content) {\r\n const descriptor = content.descriptor;\r\n for (const item of content.contentSet) {\r\n await this.formatValues(item.values, item.displayValues, descriptor.fields, item.mergedFieldNames);\r\n }\r\n return content;\r\n }\r\n\r\n private async formatValues(values: ValuesDictionary<Value>, displayValues: ValuesDictionary<DisplayValue>, fields: Field[], mergedFields: string[]) {\r\n for (const field of fields) {\r\n const value = values[field.name];\r\n\r\n // format display value of merged values\r\n if (mergedFields.includes(field.name)) {\r\n displayValues[field.name] = \"@Presentation:label.varies@\";\r\n continue;\r\n }\r\n\r\n // format display values of nested content field\r\n if (field.isNestedContentField()) {\r\n assert(Value.isNestedContent(value));\r\n await this.formatNestedContentDisplayValues(value, field.nestedFields);\r\n continue;\r\n }\r\n\r\n displayValues[field.name] = await this._propertyValueFormatter.formatPropertyValue(field, value, this._unitSystem);\r\n }\r\n }\r\n\r\n private async formatNestedContentDisplayValues(nestedValues: NestedContentValue[], fields: Field[]) {\r\n for (const nestedValue of nestedValues) {\r\n await this.formatValues(nestedValue.values, nestedValue.displayValues, fields, nestedValue.mergedFieldNames);\r\n }\r\n }\r\n\r\n}\r\n\r\n/** @alpha */\r\nexport class ContentPropertyValueFormatter {\r\n constructor(private _koqValueFormatter: KoqPropertyValueFormatter) { }\r\n\r\n public async formatPropertyValue(field: Field, value: Value, unitSystem?: UnitSystemKey): Promise<DisplayValue> {\r\n const doubleFormatter = isFieldWithKoq(field)\r\n ? async (rawValue: number) => {\r\n const koq = field.properties[0].property.kindOfQuantity;\r\n const formattedValue = await this._koqValueFormatter.format(rawValue, { koqName: koq.name, unitSystem });\r\n if (formattedValue !== undefined)\r\n return formattedValue;\r\n return formatDouble(rawValue);\r\n }\r\n : async (rawValue: number) => formatDouble(rawValue);\r\n\r\n return this.formatValue(field.type, value, { doubleFormatter });\r\n }\r\n\r\n private async formatValue(type: TypeDescription, value: Value, ctx?: { doubleFormatter: (raw: number) => Promise<string>}): Promise<DisplayValue> {\r\n switch (type.valueFormat) {\r\n case PropertyValueFormat.Primitive:\r\n return this.formatPrimitiveValue(type, value, ctx);\r\n case PropertyValueFormat.Array:\r\n return this.formatArrayValue(type, value);\r\n case PropertyValueFormat.Struct:\r\n return this.formatStructValue(type, value);\r\n }\r\n }\r\n\r\n private async formatPrimitiveValue(type: PrimitiveTypeDescription, value: Value, ctx?: { doubleFormatter: (raw: number) => Promise<string>}) {\r\n if (value === undefined)\r\n return \"\";\r\n\r\n const formatDoubleValue = async (raw: number) => ctx ? ctx.doubleFormatter(raw) : formatDouble(raw);\r\n\r\n if (type.typeName === \"point2d\" && isPoint2d(value)) {\r\n return `X: ${await formatDoubleValue(value.x)}; Y: ${await formatDoubleValue(value.y)}`;\r\n }\r\n if (type.typeName === \"point3d\" && isPoint3d(value)) {\r\n return `X: ${await formatDoubleValue(value.x)}; Y: ${await formatDoubleValue(value.y)}; Z: ${await formatDoubleValue(value.z)}`;\r\n }\r\n if (type.typeName === \"dateTime\") {\r\n assert(typeof value === \"string\");\r\n return value;\r\n }\r\n if (type.typeName === \"bool\" || type.typeName === \"boolean\") {\r\n assert(typeof value === \"boolean\");\r\n return value ? \"@Presentation:value.true@\" : \"@Presentation:value.false@\";\r\n }\r\n if (type.typeName === \"int\" || type.typeName === \"long\") {\r\n assert(isNumber(value));\r\n return value.toFixed(0);\r\n }\r\n if (type.typeName === \"double\") {\r\n assert(isNumber(value));\r\n return formatDoubleValue(value);\r\n }\r\n if (type.typeName === \"navigation\") {\r\n assert(Value.isNavigationValue(value));\r\n return value.label.displayValue;\r\n }\r\n\r\n return value.toString();\r\n }\r\n\r\n private async formatStructValue(type: StructTypeDescription, value: Value) {\r\n if (!Value.isMap(value))\r\n return {};\r\n\r\n const formattedMember: DisplayValuesMap = {};\r\n for (const member of type.members) {\r\n formattedMember[member.name] = await this.formatValue(member.type, value[member.name]);\r\n }\r\n return formattedMember;\r\n }\r\n\r\n private async formatArrayValue(type: ArrayTypeDescription, value: Value) {\r\n if (!Value.isArray(value))\r\n return [];\r\n\r\n return Promise.all(value.map(async (arrayVal) => this.formatValue(type.memberType, arrayVal)));\r\n }\r\n}\r\n\r\nfunction formatDouble(value: number) {\r\n return value.toFixed(2);\r\n}\r\n\r\ntype FieldWithKoq = PropertiesField & {\r\n properties: [{\r\n property: PropertyInfo & {\r\n kindOfQuantity: KindOfQuantityInfo;\r\n };\r\n }];\r\n};\r\n\r\nfunction isFieldWithKoq(field: Field): field is FieldWithKoq {\r\n return field.isPropertiesField()\r\n && field.properties.length > 0\r\n && field.properties[0].property.kindOfQuantity !== undefined;\r\n}\r\n\r\nfunction isPoint2d(obj: Value): obj is { x: number, y: number } {\r\n return obj !== undefined && isNumber((obj as any).x) && isNumber((obj as any).y);\r\n}\r\n\r\nfunction isPoint3d(obj: Value): obj is { x: number, y: number, z: number } {\r\n return isPoint2d(obj) && isNumber((obj as any).z);\r\n}\r\n\r\nfunction isNumber(obj: Value): obj is number {\r\n return !isNaN(Number(obj));\r\n}\r\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@itwin/presentation-common",
3
- "version": "4.3.0-dev.9",
3
+ "version": "4.4.0-dev.1",
4
4
  "description": "Common pieces for iModel.js presentation packages",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -22,10 +22,10 @@
22
22
  "module": "lib/esm/presentation-common.js",
23
23
  "typings": "lib/cjs/presentation-common",
24
24
  "peerDependencies": {
25
- "@itwin/core-bentley": "^4.3.0-dev.9",
26
- "@itwin/core-common": "^4.3.0-dev.9",
27
- "@itwin/core-quantity": "^4.3.0-dev.9",
28
- "@itwin/ecschema-metadata": "^4.3.0-dev.9"
25
+ "@itwin/core-bentley": "^4.4.0-dev.1",
26
+ "@itwin/core-common": "^4.4.0-dev.1",
27
+ "@itwin/core-quantity": "^4.4.0-dev.1",
28
+ "@itwin/ecschema-metadata": "^4.4.0-dev.1"
29
29
  },
30
30
  "devDependencies": {
31
31
  "@itwin/eslint-plugin": "4.0.0-dev.44",
@@ -58,11 +58,11 @@
58
58
  "typescript": "~5.0.2",
59
59
  "typescript-json-schema": "^0.55.0",
60
60
  "yargs": "^17.4.0",
61
- "@itwin/core-bentley": "4.3.0-dev.9",
62
- "@itwin/ecschema-metadata": "4.3.0-dev.9",
63
- "@itwin/build-tools": "4.3.0-dev.9",
64
- "@itwin/core-common": "4.3.0-dev.9",
65
- "@itwin/core-quantity": "4.3.0-dev.9"
61
+ "@itwin/build-tools": "4.4.0-dev.1",
62
+ "@itwin/core-bentley": "4.4.0-dev.1",
63
+ "@itwin/core-common": "4.4.0-dev.1",
64
+ "@itwin/core-quantity": "4.4.0-dev.1",
65
+ "@itwin/ecschema-metadata": "4.4.0-dev.1"
66
66
  },
67
67
  "nyc": {
68
68
  "extends": "./node_modules/@itwin/build-tools/.nycrc"