diff --git a/api.planx.uk/modules/analytics/metabase/dashboard/dashboard.test.ts b/api.planx.uk/modules/analytics/metabase/dashboard/dashboard.test.ts index 11334c53b0..2b051dacf7 100644 --- a/api.planx.uk/modules/analytics/metabase/dashboard/dashboard.test.ts +++ b/api.planx.uk/modules/analytics/metabase/dashboard/dashboard.test.ts @@ -97,9 +97,9 @@ describe("Dashboard Operations", () => { .reply(200, { parameters: [ { - name: filterName, + filter: filterName, type: "string/=", - default: ["old_value"], + value: ["old_value"], }, ], }); @@ -108,30 +108,33 @@ describe("Dashboard Operations", () => { .put(`/api/dashboard/${dashboardId}`, { parameters: [ { - name: filterName, + filter: filterName, type: "string/=", - default: [filterValue], + value: [filterValue], }, ], }) .reply(200, { parameters: [ { - name: filterName, + filter: filterName, type: "string/=", - default: [filterValue], + value: [filterValue], }, ], param_fields: {}, }); - await expect( - updateFilter({ - dashboardId: dashboardId, - filter: filterName, - value: filterValue, - }), - ).resolves.not.toThrow(); + const result = await updateFilter({ + dashboardId: dashboardId, + filter: filterName, + value: filterValue, + }); + + expect(result).toEqual({ + success: true, + updatedFilter: filterName, + }); }); test("handles non-string filter type appropriately", async () => { @@ -140,19 +143,16 @@ describe("Dashboard Operations", () => { .reply(200, { parameters: [ { - name: filterName, - slug: "event", - id: "30a24538", + filter: filterName, type: "number/=", - sectionId: "number", - default: [42], + value: [42], }, ], }); - nock(BASE_URL!).put(`/api/dashboard/${dashboardId}`).reply(400, { - message: "Invalid parameter type. Expected number, got string.", - }); + // nock(BASE_URL!).put(`/api/dashboard/${dashboardId}`).reply(400, { + // message: "Invalid parameter type. Expected number, got string.", + // }); await expect( updateFilter({ diff --git a/api.planx.uk/modules/analytics/metabase/dashboard/types.ts b/api.planx.uk/modules/analytics/metabase/dashboard/types.ts index 9ea42b4d14..081ce9f582 100644 --- a/api.planx.uk/modules/analytics/metabase/dashboard/types.ts +++ b/api.planx.uk/modules/analytics/metabase/dashboard/types.ts @@ -38,7 +38,6 @@ export type MetabaseCopyDashboardParams = { is_deep_copy?: boolean; }; -// Convert to Metabase API structure export function toMetabaseParams( params: CopyDashboardParams, ): MetabaseCopyDashboardParams { @@ -77,10 +76,11 @@ export type NewDashboardHandler = ValidatedRequestHandler< ApiResponse >; -export interface GetDashboardResponse { +export interface MetabaseDashboardResponse { name: string; id: number; collection_id: number; + parameters: FilterParam[]; } export interface UpdateFilterResponse { @@ -89,6 +89,20 @@ export interface UpdateFilterResponse { } export interface FilterParam { - name: string; + filter: string; type: string; + // The Metabase API expects filter default values as arrays, even if there's only one (eg for multi-select filters) + value: string[]; +} + +export type GetDashboardResponse = Pick< + MetabaseDashboardResponse, + "name" | "id" | "collection_id" +>; + +export type GetFilterResponse = Pick; + +export interface UpdatedFilterResponse { + parameter: FilterParam; + updatedValue: string | undefined; } diff --git a/api.planx.uk/modules/analytics/metabase/dashboard/updateFilter.ts b/api.planx.uk/modules/analytics/metabase/dashboard/updateFilter.ts index 3d636a12ad..84237c3c54 100644 --- a/api.planx.uk/modules/analytics/metabase/dashboard/updateFilter.ts +++ b/api.planx.uk/modules/analytics/metabase/dashboard/updateFilter.ts @@ -3,33 +3,55 @@ import type { UpdateFilterParams, UpdateFilterResponse, FilterParam, + UpdatedFilterResponse, + GetFilterResponse, } from "./types.js"; +function populateUpdatedFilterResponse( + param: FilterParam, + filterName: string, + filterValue: string, +): UpdatedFilterResponse { + if (param.filter === filterName) { + if (!param.type.startsWith("string/")) { + throw new Error( + `Filter type '${param.type}' is not supported. Only string filters are currently supported.`, + ); + } + return { + parameter: { ...param, value: [filterValue] }, + updatedValue: param.filter, + }; + } + return { + parameter: param, + updatedValue: undefined, + }; +} + /** Takes the ID of the dashboard to be updated, the name of the filter (a string, must be an exact match), and the new value to be filtered on. * Currently only works for strings. */ export async function updateFilter( params: UpdateFilterParams, ): Promise { // Get existing dashboard data - const response = await $metabase.get(`/api/dashboard/${params.dashboardId}`); + const response = await $metabase.get( + `/api/dashboard/${params.dashboardId}`, + ); // Update filter default value parameter - let updatedFilter; - const updatedParameters = response.data.parameters.map( - (param: FilterParam) => { - if (param.name === params.filter) { - // Check if the filter is a string type - if (!param.type.startsWith("string/")) { - throw new Error( - `Filter type '${param.type}' is not supported. Only string filters are currently supported.`, - ); - } - updatedFilter = param.name; - return { ...param, default: [params.value] }; - } - return param; - }, - ); + let updatedFilter: string | undefined; + const updatedParameters = response.data.parameters.map((param) => { + const result = populateUpdatedFilterResponse( + param, + params.filter, + params.value, + ); + if (result.updatedValue) { + updatedFilter = result.updatedValue; + } + return result.parameter; + }); if (!updatedFilter) { throw new Error(