From 61ad7e10b04248d71d4d2ca7dd54dab7034b5637 Mon Sep 17 00:00:00 2001 From: Nouzbe Date: Fri, 3 May 2024 16:41:53 +0200 Subject: [PATCH 1/6] UI-9384 - Preserve KPI titles when migrated KPI widgets from 4.3 to 5.0 --- .../legacyComparisonValues.ts | 11 +- .../__test_resources__/legacyKpi.ts | 10 +- src/4.3_to_5.0/getMigratedKpiTitles.test.ts | 30 ++++++ src/4.3_to_5.0/getMigratedKpiTitles.ts | 101 ++++++++++++++++++ src/4.3_to_5.0/migrateKpi.test.ts | 6 ++ src/4.3_to_5.0/migrateKpi.ts | 32 +++++- 6 files changed, 185 insertions(+), 5 deletions(-) create mode 100644 src/4.3_to_5.0/getMigratedKpiTitles.test.ts create mode 100644 src/4.3_to_5.0/getMigratedKpiTitles.ts diff --git a/src/4.3_to_5.0/__test_resources__/legacyComparisonValues.ts b/src/4.3_to_5.0/__test_resources__/legacyComparisonValues.ts index e0802c2d..5bea850e 100644 --- a/src/4.3_to_5.0/__test_resources__/legacyComparisonValues.ts +++ b/src/4.3_to_5.0/__test_resources__/legacyComparisonValues.ts @@ -9,8 +9,7 @@ export const legacyComparisonValues = { showTitleBar: true, body: { serverUrl: "http://localhost:9090", - mdx: - "SELECT NON EMPTY Hierarchize(DrilldownLevel([Currency].[Currency].[ALL].[AllMember])) ON ROWS, NON EMPTY [Measures].[pnl.FOREX] ON COLUMNS, {[Booking].[Desk].[ALL].[AllMember].[LegalEntityA], [Booking].[Desk].[ALL].[AllMember].[LegalEntityB]} ON PAGES FROM [EquityDerivativesCube] CELL PROPERTIES VALUE, FORMATTED_VALUE, BACK_COLOR, FORE_COLOR, FONT_FLAGS", + mdx: "SELECT NON EMPTY Hierarchize(DrilldownLevel([Currency].[Currency].[ALL].[AllMember])) ON ROWS, NON EMPTY [Measures].[pnl.FOREX] ON COLUMNS, {[Booking].[Desk].[ALL].[AllMember].[LegalEntityA], [Booking].[Desk].[ALL].[AllMember].[LegalEntityB]} ON PAGES FROM [EquityDerivativesCube] CELL PROPERTIES VALUE, FORMATTED_VALUE, BACK_COLOR, FORE_COLOR, FONT_FLAGS", contextValues: {}, updateMode: "once", ranges: { @@ -24,7 +23,13 @@ export const legacyComparisonValues = { }, }, configuration: { - featuredValues: {}, + featuredValues: { + locations: { + "[Currency].[Currency].[AllMember].[GBP],[Measures].[pnl.FOREX]": { + title: "Hello World", + }, + }, + }, }, }, containerKey: "featured-values", diff --git a/src/4.3_to_5.0/__test_resources__/legacyKpi.ts b/src/4.3_to_5.0/__test_resources__/legacyKpi.ts index 52dcb4d6..e32e9a9b 100644 --- a/src/4.3_to_5.0/__test_resources__/legacyKpi.ts +++ b/src/4.3_to_5.0/__test_resources__/legacyKpi.ts @@ -29,7 +29,15 @@ export const legacyKpi: LegacyWidgetState = { }, }, configuration: { - featuredValues: {}, + featuredValues: { + locations: { + // "EUR, USD" is not a member of the sandbox, but it is used here to check that the script supports member names including ",". + "[Currency].[Currency].[AllMember].[EUR, USD],[Measures].[contributors.COUNT]": + { + title: "Hello World", + }, + }, + }, }, }, containerKey: "featured-values", diff --git a/src/4.3_to_5.0/getMigratedKpiTitles.test.ts b/src/4.3_to_5.0/getMigratedKpiTitles.test.ts new file mode 100644 index 00000000..35ecc393 --- /dev/null +++ b/src/4.3_to_5.0/getMigratedKpiTitles.test.ts @@ -0,0 +1,30 @@ +import { dataModelsForTests } from "@activeviam/data-model-5.0"; +import { getMigratedKpiTitles } from "./getMigratedKpiTitles"; +import { legacyKpi } from "./__test_resources__/legacyKpi"; + +const cube = dataModelsForTests.sandbox.catalogs[0].cubes[0]; + +describe("getMigratedKpiTitles", () => { + it("returns the migrated KPI titles corresponding to the legacy KPI state, ready to be used in Atoti UI 5.0", () => { + const migratedKpiTitles = getMigratedKpiTitles(legacyKpi, { + cube, + mapping: { + columns: [{ type: "allMeasures" }], + measures: [{ type: "measure", measureName: "contributors.COUNT" }], + rows: [ + { + type: "hierarchy", + dimensionName: "Currency", + hierarchyName: "Currency", + levelName: "Currency", + }, + ], + }, + }); + expect(migratedKpiTitles).toMatchInlineSnapshot(` + { + "[Measures].[contributors.COUNT],[Currency].[Currency].[AllMember].[EUR, USD]": "Hello World", + } + `); + }); +}); diff --git a/src/4.3_to_5.0/getMigratedKpiTitles.ts b/src/4.3_to_5.0/getMigratedKpiTitles.ts new file mode 100644 index 00000000..6089852b --- /dev/null +++ b/src/4.3_to_5.0/getMigratedKpiTitles.ts @@ -0,0 +1,101 @@ +import { + Cube, + DataVisualizationWidgetMapping, + KpiWidgetState, + MdxUnknownCompoundIdentifier, + parse, +} from "@activeviam/activeui-sdk-5.0"; +import { getSpecificCompoundIdentifier, quote } from "@activeviam/mdx-5.0"; + +interface LegacyKpiTitle { + title: string; + tuple: { [hierarchyUniqueName: string]: string[] }; +} + +/** + * Returns the legacy KPI titles attached to `legacyKpiState`. + */ +function _getLegacyKpiTitles( + // Legacy widget states are not typed. + // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types + legacyKpiState: any, + { cube }: { cube: Cube }, +): LegacyKpiTitle[] { + const locations = + legacyKpiState?.value?.body?.configuration?.featuredValues?.locations; + + if (!locations) { + return []; + } + + const legacyTitles: LegacyKpiTitle[] = []; + + for (const tupleKey in locations) { + const { title } = locations[tupleKey]; + const tuple: { + [hierarchyUniqueName: string]: string[]; + } = {}; + const memberUniqueNames = tupleKey.split(/,(?![^\[]*\])/); + for (const memberUniqueName of memberUniqueNames) { + const compoundIdentifier = + parse(memberUniqueName); + const specificCompoundIdentifier = getSpecificCompoundIdentifier( + compoundIdentifier, + { cube }, + ); + if (specificCompoundIdentifier.type === "measure") { + tuple[`[Measures].[Measures]`] = [ + specificCompoundIdentifier.measureName, + ]; + } else if (specificCompoundIdentifier.type === "member") { + tuple[ + `[${specificCompoundIdentifier.dimensionName}].[${specificCompoundIdentifier.hierarchyName}]` + ] = specificCompoundIdentifier.path; + } + } + legacyTitles.push({ title, tuple }); + } + + return legacyTitles; +} + +/** + * Returns the migrated KPI widget titles corresponding to legacyKpiState. + */ +export function getMigratedKpiTitles( + // Legacy widget states are not typed. + // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types + legacyKpiState: any, + { mapping, cube }: { mapping: DataVisualizationWidgetMapping; cube: Cube }, +): KpiWidgetState["titles"] { + const legacyTitles = _getLegacyKpiTitles(legacyKpiState, { cube }); + const migratedTitles: KpiWidgetState["titles"] = {}; + + const memberUniqueNames: string[] = []; + legacyTitles.forEach(({ title, tuple }) => { + // Atoti UI 5.0 KPI widgets expect tuple keys to express members in the following order: + // - column fields first + // - then row fields + const fields = [...(mapping.columns ?? []), ...(mapping.rows ?? [])]; + fields.forEach((field) => { + if (field.type === "allMeasures") { + const measureName = tuple[`[Measures].[Measures]`]?.[0]; + if (measureName) { + memberUniqueNames.push(`[Measures].[${measureName}]`); + } + } else if (field.type === "hierarchy") { + const hierarchyUniqueName = `[${field.dimensionName}].[${field.hierarchyName}]`; + const namePath = tuple[hierarchyUniqueName]; + if (namePath) { + memberUniqueNames.push( + `${hierarchyUniqueName}.${quote(...namePath)}`, + ); + } + } + }); + const tupleKey = memberUniqueNames.join(","); + migratedTitles[tupleKey] = title; + }); + + return migratedTitles; +} diff --git a/src/4.3_to_5.0/migrateKpi.test.ts b/src/4.3_to_5.0/migrateKpi.test.ts index 412e8938..7519e845 100644 --- a/src/4.3_to_5.0/migrateKpi.test.ts +++ b/src/4.3_to_5.0/migrateKpi.test.ts @@ -39,6 +39,9 @@ describe("migrateKpi", () => { }, ], "serverKey": "my-server", + "titles": { + "[Measures].[contributors.COUNT],[Currency].[Currency].[AllMember].[EUR, USD]": "Hello World", + }, "widgetKey": "kpi", } `); @@ -81,6 +84,9 @@ describe("migrateKpi", () => { }, "queryContext": [], "serverKey": "my-server", + "titles": { + "[Measures].[pnl.FOREX],[Currency].[Currency].[AllMember].[GBP]": "Hello World", + }, "widgetKey": "kpi", } `); diff --git a/src/4.3_to_5.0/migrateKpi.ts b/src/4.3_to_5.0/migrateKpi.ts index a9ebf847..14ea0a1d 100644 --- a/src/4.3_to_5.0/migrateKpi.ts +++ b/src/4.3_to_5.0/migrateKpi.ts @@ -29,6 +29,7 @@ import { _getQueryInLegacyWidgetState } from "./_getQueryInLegacyWidgetState"; import { _getTargetCubeFromServerUrl } from "./_getTargetCubeFromServerUrl"; import { _migrateQuery } from "./_migrateQuery"; import { produce } from "immer"; +import { getMigratedKpiTitles } from "./getMigratedKpiTitles"; const moveExpressionToWithClause = ( draft: any, @@ -189,7 +190,13 @@ export function migrateKpi( const mapping = deriveMappingFromMdx({ mdx: query.mdx, cube, - widgetPlugin: pluginWidgetKpi, + widgetPlugin: { + ...pluginWidgetKpi, + // This makes the "allMeasures" tile part of the generated mapping. + // This tile indicates the position of the measures on the queries axes, necessary to migrate KPI titles. + // It is then removed from the mapping, as Atoti UI 5.0 does not expect it. + doesSupportMeasuresRedirection: true, + }, }); const migratedWidgetState: KpiWidgetState = { @@ -206,6 +213,29 @@ export function migrateKpi( }), }; + try { + const migratedTitles = getMigratedKpiTitles(legacyKpiState, { + cube, + mapping, + }); + if (migratedTitles && Object.keys(migratedTitles).length > 0) { + migratedWidgetState.titles = migratedTitles; + } + } catch (error) { + // Migrating the KPI titles is a best effort. + // The migration script should not fail if this part errors. + console.warn( + `Could not migrate the titles of the featured values widget named "${legacyKpiState.name}". Underlying error:\n`, + error, + ); + } + + Object.keys(mapping).forEach((attributeName) => { + mapping[attributeName] = mapping[attributeName].filter( + (field) => field.type !== "allMeasures", + ); + }); + const serializedWidgetState = serializeWidgetState(migratedWidgetState); if (isUsingUnsupportedUpdateMode) { From 22c597c3ae5460bd2b7af62c25e7e281a5833cf5 Mon Sep 17 00:00:00 2001 From: Nouzbe Date: Fri, 17 May 2024 10:16:28 +0200 Subject: [PATCH 2/6] Use quote --- src/4.3_to_5.0/getMigratedKpiTitles.ts | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/4.3_to_5.0/getMigratedKpiTitles.ts b/src/4.3_to_5.0/getMigratedKpiTitles.ts index 6089852b..b5cd0719 100644 --- a/src/4.3_to_5.0/getMigratedKpiTitles.ts +++ b/src/4.3_to_5.0/getMigratedKpiTitles.ts @@ -48,9 +48,11 @@ function _getLegacyKpiTitles( specificCompoundIdentifier.measureName, ]; } else if (specificCompoundIdentifier.type === "member") { - tuple[ - `[${specificCompoundIdentifier.dimensionName}].[${specificCompoundIdentifier.hierarchyName}]` - ] = specificCompoundIdentifier.path; + const hierarchyUniqueName = quote( + specificCompoundIdentifier.dimensionName, + specificCompoundIdentifier.hierarchyName, + ); + tuple[hierarchyUniqueName] = specificCompoundIdentifier.path; } } legacyTitles.push({ title, tuple }); @@ -84,7 +86,10 @@ export function getMigratedKpiTitles( memberUniqueNames.push(`[Measures].[${measureName}]`); } } else if (field.type === "hierarchy") { - const hierarchyUniqueName = `[${field.dimensionName}].[${field.hierarchyName}]`; + const hierarchyUniqueName = quote( + field.dimensionName, + field.hierarchyName, + ); const namePath = tuple[hierarchyUniqueName]; if (namePath) { memberUniqueNames.push( From 027dea4b64230b10a8c02ef534b92496c1514796 Mon Sep 17 00:00:00 2001 From: Nouzbe Date: Fri, 17 May 2024 11:07:57 +0200 Subject: [PATCH 3/6] Add error to report --- src/4.3_to_5.0/migrateKpi.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/4.3_to_5.0/migrateKpi.ts b/src/4.3_to_5.0/migrateKpi.ts index 14ea0a1d..b33bfd0b 100644 --- a/src/4.3_to_5.0/migrateKpi.ts +++ b/src/4.3_to_5.0/migrateKpi.ts @@ -30,6 +30,7 @@ import { _getTargetCubeFromServerUrl } from "./_getTargetCubeFromServerUrl"; import { _migrateQuery } from "./_migrateQuery"; import { produce } from "immer"; import { getMigratedKpiTitles } from "./getMigratedKpiTitles"; +import { PartialMigrationError } from "../PartialMigrationError"; const moveExpressionToWithClause = ( draft: any, @@ -224,9 +225,9 @@ export function migrateKpi( } catch (error) { // Migrating the KPI titles is a best effort. // The migration script should not fail if this part errors. - console.warn( - `Could not migrate the titles of the featured values widget named "${legacyKpiState.name}". Underlying error:\n`, - error, + throw new PartialMigrationError( + `Could not migrate the titles of the featured values widget named "${legacyKpiState.name}"`, + serializeWidgetState(migratedWidgetState), ); } From 6c22730018e3cc433ea371912da13db44fe21fdd Mon Sep 17 00:00:00 2001 From: Nouzbe Date: Fri, 17 May 2024 17:54:55 +0200 Subject: [PATCH 4/6] Explicitly re-add the allMeasures tile at the correct position outside of deriveMappingFromMdx --- src/4.3_to_5.0/migrateKpi.ts | 56 +++++++++++++++++++++++------------- 1 file changed, 36 insertions(+), 20 deletions(-) diff --git a/src/4.3_to_5.0/migrateKpi.ts b/src/4.3_to_5.0/migrateKpi.ts index b33bfd0b..6d5b45b1 100644 --- a/src/4.3_to_5.0/migrateKpi.ts +++ b/src/4.3_to_5.0/migrateKpi.ts @@ -23,6 +23,8 @@ import { import { getSpecificCompoundIdentifier, findDescendant, + getMeasuresPositionOnAxis, + getMeasuresAxisName, } from "@activeviam/mdx-5.0"; import { UnsupportedLegacyQueryUpdateModeError } from "./errors/UnsupportedLegacyQueryUpdateModeError"; import { _getQueryInLegacyWidgetState } from "./_getQueryInLegacyWidgetState"; @@ -188,16 +190,12 @@ export function migrateKpi( shouldUpdateFiltersMdx, }); + const { mdx } = query; + const mapping = deriveMappingFromMdx({ - mdx: query.mdx, + mdx, cube, - widgetPlugin: { - ...pluginWidgetKpi, - // This makes the "allMeasures" tile part of the generated mapping. - // This tile indicates the position of the measures on the queries axes, necessary to migrate KPI titles. - // It is then removed from the mapping, as Atoti UI 5.0 does not expect it. - doesSupportMeasuresRedirection: true, - }, + widgetPlugin: pluginWidgetKpi, }); const migratedWidgetState: KpiWidgetState = { @@ -215,12 +213,36 @@ export function migrateKpi( }; try { - const migratedTitles = getMigratedKpiTitles(legacyKpiState, { - cube, - mapping, - }); - if (migratedTitles && Object.keys(migratedTitles).length > 0) { - migratedWidgetState.titles = migratedTitles; + // Migrate manually entered KPI titles. + if (mdx && mapping.measures.length > 0) { + const measuresAxisName = getMeasuresAxisName(mdx); + const measuresAxis = mdx.axes.find( + (axis) => axis.name === measuresAxisName, + ); + if (measuresAxis) { + const positionOfAllMeasuresWithinAxis = + getMeasuresPositionOnAxis(measuresAxis); + + // pluginWidgetKpi has `doesSupportMeasuresRedirection: false`. + // For this reason, its "allMeasures" tile is omitted from the mapping generated from `deriveMappingFromMdx`. + // But the position of this tile needs to be known here, as the order of the members in the tuple matters for manually entered KPI titles to work in Atoti UI 5.0. + const mappingWithAllMeasuresTile = produce(mapping, (draft) => { + const attribute = ["ROWS", "1"].includes(measuresAxisName) + ? draft.rows + : draft.columns; + attribute.splice(positionOfAllMeasuresWithinAxis, 0, { + type: "allMeasures", + }); + }); + + const migratedTitles = getMigratedKpiTitles(legacyKpiState, { + cube, + mapping: mappingWithAllMeasuresTile, + }); + if (migratedTitles && Object.keys(migratedTitles).length > 0) { + migratedWidgetState.titles = migratedTitles; + } + } } } catch (error) { // Migrating the KPI titles is a best effort. @@ -231,12 +253,6 @@ export function migrateKpi( ); } - Object.keys(mapping).forEach((attributeName) => { - mapping[attributeName] = mapping[attributeName].filter( - (field) => field.type !== "allMeasures", - ); - }); - const serializedWidgetState = serializeWidgetState(migratedWidgetState); if (isUsingUnsupportedUpdateMode) { From 999513ebc157117ac5d89cca1f22ff0b06fd0a42 Mon Sep 17 00:00:00 2001 From: Benjamin Amelot Date: Tue, 21 May 2024 10:40:24 +0200 Subject: [PATCH 5/6] Antoine's way --- src/4.3_to_5.0/getMigratedKpiTitles.test.ts | 12 +++- src/4.3_to_5.0/getMigratedKpiTitles.ts | 63 ++++++++++++++++----- src/4.3_to_5.0/migrateKpi.ts | 40 +++---------- 3 files changed, 68 insertions(+), 47 deletions(-) diff --git a/src/4.3_to_5.0/getMigratedKpiTitles.test.ts b/src/4.3_to_5.0/getMigratedKpiTitles.test.ts index 35ecc393..f720a443 100644 --- a/src/4.3_to_5.0/getMigratedKpiTitles.test.ts +++ b/src/4.3_to_5.0/getMigratedKpiTitles.test.ts @@ -1,15 +1,25 @@ import { dataModelsForTests } from "@activeviam/data-model-5.0"; import { getMigratedKpiTitles } from "./getMigratedKpiTitles"; import { legacyKpi } from "./__test_resources__/legacyKpi"; +import { _getQueryInLegacyWidgetState } from "./_getQueryInLegacyWidgetState"; +import { MdxSelect, parse } from "@activeviam/mdx-5.0"; const cube = dataModelsForTests.sandbox.catalogs[0].cubes[0]; describe("getMigratedKpiTitles", () => { it("returns the migrated KPI titles corresponding to the legacy KPI state, ready to be used in Atoti UI 5.0", () => { + const legacyQuery = _getQueryInLegacyWidgetState(legacyKpi); + + if (!legacyQuery || !legacyQuery.mdx) { + throw new Error("Expected the legacy KPI state to contain a query"); + } + + const legacyMdx = parse(legacyQuery.mdx); const migratedKpiTitles = getMigratedKpiTitles(legacyKpi, { cube, + legacyMdx, mapping: { - columns: [{ type: "allMeasures" }], + columns: [], measures: [{ type: "measure", measureName: "contributors.COUNT" }], rows: [ { diff --git a/src/4.3_to_5.0/getMigratedKpiTitles.ts b/src/4.3_to_5.0/getMigratedKpiTitles.ts index b5cd0719..11b21ebb 100644 --- a/src/4.3_to_5.0/getMigratedKpiTitles.ts +++ b/src/4.3_to_5.0/getMigratedKpiTitles.ts @@ -5,7 +5,13 @@ import { MdxUnknownCompoundIdentifier, parse, } from "@activeviam/activeui-sdk-5.0"; -import { getSpecificCompoundIdentifier, quote } from "@activeviam/mdx-5.0"; +import { + getSpecificCompoundIdentifier, + quote, + getMeasuresAxisName, + getMeasuresPositionOnAxis, + MdxSelect, +} from "@activeviam/mdx-5.0"; interface LegacyKpiTitle { title: string; @@ -68,24 +74,43 @@ export function getMigratedKpiTitles( // Legacy widget states are not typed. // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types legacyKpiState: any, - { mapping, cube }: { mapping: DataVisualizationWidgetMapping; cube: Cube }, + { + legacyMdx, + mapping, + cube, + }: { + legacyMdx: MdxSelect; + mapping: DataVisualizationWidgetMapping; + cube: Cube; + }, ): KpiWidgetState["titles"] { const legacyTitles = _getLegacyKpiTitles(legacyKpiState, { cube }); const migratedTitles: KpiWidgetState["titles"] = {}; - const memberUniqueNames: string[] = []; + const numberOfColumnFields = mapping.columns?.length ?? 0; + + const measuresAxisName = getMeasuresAxisName(legacyMdx); + const measuresAxis = legacyMdx.axes.find( + (axis) => axis.name === measuresAxisName, + ); + let measuresPositionInTuple = -1; + if (measuresAxis) { + const measuresPositionOnAxis = getMeasuresPositionOnAxis(measuresAxis); + measuresPositionInTuple = ["0", "COLUMNS"].includes(measuresAxisName) + ? measuresPositionOnAxis + : numberOfColumnFields + measuresPositionOnAxis; + } + + // Atoti UI 5.0 KPI widgets expect tuple keys to express members in the following order: + // - column fields first + // - then row fields + const ordinalFields = [...(mapping.columns ?? []), ...(mapping.rows ?? [])]; + legacyTitles.forEach(({ title, tuple }) => { - // Atoti UI 5.0 KPI widgets expect tuple keys to express members in the following order: - // - column fields first - // - then row fields - const fields = [...(mapping.columns ?? []), ...(mapping.rows ?? [])]; - fields.forEach((field) => { - if (field.type === "allMeasures") { - const measureName = tuple[`[Measures].[Measures]`]?.[0]; - if (measureName) { - memberUniqueNames.push(`[Measures].[${measureName}]`); - } - } else if (field.type === "hierarchy") { + const memberUniqueNames: string[] = []; + + ordinalFields.forEach((field) => { + if (field.type === "hierarchy") { const hierarchyUniqueName = quote( field.dimensionName, field.hierarchyName, @@ -98,6 +123,16 @@ export function getMigratedKpiTitles( } } }); + + if (measuresPositionInTuple > -1) { + const measureName = tuple[quote("Measures", "Measures")][0]; + memberUniqueNames.splice( + measuresPositionInTuple, + 0, + quote("Measures", measureName), + ); + } + const tupleKey = memberUniqueNames.join(","); migratedTitles[tupleKey] = title; }); diff --git a/src/4.3_to_5.0/migrateKpi.ts b/src/4.3_to_5.0/migrateKpi.ts index 6d5b45b1..79f01f20 100644 --- a/src/4.3_to_5.0/migrateKpi.ts +++ b/src/4.3_to_5.0/migrateKpi.ts @@ -23,8 +23,6 @@ import { import { getSpecificCompoundIdentifier, findDescendant, - getMeasuresPositionOnAxis, - getMeasuresAxisName, } from "@activeviam/mdx-5.0"; import { UnsupportedLegacyQueryUpdateModeError } from "./errors/UnsupportedLegacyQueryUpdateModeError"; import { _getQueryInLegacyWidgetState } from "./_getQueryInLegacyWidgetState"; @@ -213,36 +211,14 @@ export function migrateKpi( }; try { - // Migrate manually entered KPI titles. - if (mdx && mapping.measures.length > 0) { - const measuresAxisName = getMeasuresAxisName(mdx); - const measuresAxis = mdx.axes.find( - (axis) => axis.name === measuresAxisName, - ); - if (measuresAxis) { - const positionOfAllMeasuresWithinAxis = - getMeasuresPositionOnAxis(measuresAxis); - - // pluginWidgetKpi has `doesSupportMeasuresRedirection: false`. - // For this reason, its "allMeasures" tile is omitted from the mapping generated from `deriveMappingFromMdx`. - // But the position of this tile needs to be known here, as the order of the members in the tuple matters for manually entered KPI titles to work in Atoti UI 5.0. - const mappingWithAllMeasuresTile = produce(mapping, (draft) => { - const attribute = ["ROWS", "1"].includes(measuresAxisName) - ? draft.rows - : draft.columns; - attribute.splice(positionOfAllMeasuresWithinAxis, 0, { - type: "allMeasures", - }); - }); - - const migratedTitles = getMigratedKpiTitles(legacyKpiState, { - cube, - mapping: mappingWithAllMeasuresTile, - }); - if (migratedTitles && Object.keys(migratedTitles).length > 0) { - migratedWidgetState.titles = migratedTitles; - } - } + if (legacyMdx) { + // Migrate manually entered KPI titles. + const migratedTitles = getMigratedKpiTitles(legacyKpiState, { + cube, + mapping, + legacyMdx, + }); + migratedWidgetState.titles = migratedTitles; } } catch (error) { // Migrating the KPI titles is a best effort. From 28d43d71a0f237b91a39062b2d1c72595f830edc Mon Sep 17 00:00:00 2001 From: Benjamin Amelot Date: Tue, 21 May 2024 11:10:07 +0200 Subject: [PATCH 6/6] Antoine's suggestion and fix test --- src/4.3_to_5.0/migrateKpi.ts | 7 ++++++- src/PartialMigrationError.ts | 3 ++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/4.3_to_5.0/migrateKpi.ts b/src/4.3_to_5.0/migrateKpi.ts index 79f01f20..96c799a9 100644 --- a/src/4.3_to_5.0/migrateKpi.ts +++ b/src/4.3_to_5.0/migrateKpi.ts @@ -218,7 +218,9 @@ export function migrateKpi( mapping, legacyMdx, }); - migratedWidgetState.titles = migratedTitles; + if (migratedTitles && Object.keys(migratedTitles).length > 0) { + migratedWidgetState.titles = migratedTitles; + } } } catch (error) { // Migrating the KPI titles is a best effort. @@ -226,6 +228,9 @@ export function migrateKpi( throw new PartialMigrationError( `Could not migrate the titles of the featured values widget named "${legacyKpiState.name}"`, serializeWidgetState(migratedWidgetState), + { + cause: error, + }, ); } diff --git a/src/PartialMigrationError.ts b/src/PartialMigrationError.ts index 6f4400db..5327675e 100644 --- a/src/PartialMigrationError.ts +++ b/src/PartialMigrationError.ts @@ -10,8 +10,9 @@ export class PartialMigrationError extends Error { constructor( message: string, migratedWidgetState: AWidgetState<"serialized">, + options?: ErrorOptions, ) { - super(message); + super(message, options); this.migratedWidgetState = migratedWidgetState; } }