diff --git a/adminSiteServer/apiRouter.ts b/adminSiteServer/apiRouter.ts index 8079aa1f503..22f84b82d41 100644 --- a/adminSiteServer/apiRouter.ts +++ b/adminSiteServer/apiRouter.ts @@ -111,6 +111,7 @@ import { DbInsertChartView, CHART_VIEW_PROPS_TO_PERSIST, CHART_VIEW_PROPS_TO_OMIT, + JsonString, } from "@ourworldindata/types" import { uuidv7 } from "uuidv7" import { @@ -118,6 +119,7 @@ import { getVariableDataRoute, getVariableMetadataRoute, defaultGrapherConfig, + grapherConfigToQueryParams, } from "@ourworldindata/grapher" import { getDatasetById, setTagsForDataset } from "../db/model/Dataset.js" import { getUserById, insertUser, updateUser } from "../db/model/User.js" @@ -3291,7 +3293,7 @@ postRouteWithRWTransaction(apiRouter, "/tagGraph", async (req, res, trx) => { res.send({ success: true }) }) -const createPatchConfigAndFullConfigForChartView = async ( +const createPatchConfigAndQueryParamsForChartView = async ( knex: db.KnexReadonlyTransaction, parentChartId: number, config: GrapherInterface @@ -3316,8 +3318,10 @@ const createPatchConfigAndFullConfigForChartView = async ( ...pick(fullConfigIncludingDefaults, CHART_VIEW_PROPS_TO_PERSIST), } + const queryParams = grapherConfigToQueryParams(config) + const fullConfig = mergeGrapherConfigs(parentChartConfig, patchConfigToSave) - return { patchConfig: patchConfigToSave, fullConfig } + return { patchConfig: patchConfigToSave, fullConfig, queryParams } } getRouteWithROTransaction(apiRouter, "/chartViews", async (req, res, trx) => { @@ -3378,10 +3382,11 @@ getRouteWithROTransaction( > & { lastEditedByUser: string chartConfigId: string - configFull: string - configPatch: string + configFull: JsonString + configPatch: JsonString parentChartId: number - parentConfigFull: string + parentConfigFull: JsonString + queryParamsForParentChart: JsonString } const row = await db.knexRawFirst( @@ -3396,7 +3401,8 @@ getRouteWithROTransaction( cc.full as configFull, cc.patch as configPatch, cv.parentChartId, - pcc.full as parentConfigFull + pcc.full as parentConfigFull, + cv.queryParamsForParentChart FROM chart_views cv JOIN chart_configs cc ON cv.chartConfigId = cc.id JOIN charts pc ON cv.parentChartId = pc.id @@ -3416,6 +3422,9 @@ getRouteWithROTransaction( configFull: parseChartConfig(row.configFull), configPatch: parseChartConfig(row.configPatch), parentConfigFull: parseChartConfig(row.parentConfigFull), + queryParamsForParentChart: JSON.parse( + row.queryParamsForParentChart + ), } return chartView @@ -3432,8 +3441,8 @@ postRouteWithRWTransaction(apiRouter, "/chartViews", async (req, res, trx) => { throw new JsonError("Invalid request", 400) } - const { patchConfig, fullConfig } = - await createPatchConfigAndFullConfigForChartView( + const { patchConfig, fullConfig, queryParams } = + await createPatchConfigAndQueryParamsForChartView( trx, parentChartId, rawConfig @@ -3452,6 +3461,7 @@ postRouteWithRWTransaction(apiRouter, "/chartViews", async (req, res, trx) => { parentChartId, lastEditedByUserId: res.locals.user.id, chartConfigId: chartConfigId, + queryParamsForParentChart: JSON.stringify(queryParams), } const result = await trx.table(ChartViewsTableName).insert(insertRow) const [resultId] = result @@ -3481,8 +3491,8 @@ putRouteWithRWTransaction( throw new JsonError(`No chart view found for id ${id}`, 404) } - const { patchConfig, fullConfig } = - await createPatchConfigAndFullConfigForChartView( + const { patchConfig, fullConfig, queryParams } = + await createPatchConfigAndQueryParamsForChartView( trx, existingRow.parentChartId, rawConfig @@ -3496,10 +3506,14 @@ putRouteWithRWTransaction( ) // update chart_views - await trx.table(ChartViewsTableName).where({ id }).update({ - updatedAt: new Date(), - lastEditedByUserId: res.locals.user.id, - }) + await trx + .table(ChartViewsTableName) + .where({ id }) + .update({ + updatedAt: new Date(), + lastEditedByUserId: res.locals.user.id, + queryParamsForParentChart: JSON.stringify(queryParams), + }) return { success: true } } diff --git a/db/migration/1733151294656-ChartViewsAddQueryParam.ts b/db/migration/1733151294656-ChartViewsAddQueryParam.ts new file mode 100644 index 00000000000..30efc1e9d22 --- /dev/null +++ b/db/migration/1733151294656-ChartViewsAddQueryParam.ts @@ -0,0 +1,17 @@ +import { MigrationInterface, QueryRunner } from "typeorm" + +export class ChartViewsAddQueryParam1733151294656 + implements MigrationInterface +{ + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`-- sql + ALTER TABLE chart_views ADD COLUMN queryParamsForParentChart JSON NULL AFTER parentChartId; + `) + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`-- sql + ALTER TABLE chart_views DROP COLUMN queryParamsForParentChart; + `) + } +} diff --git a/packages/@ourworldindata/grapher/src/index.ts b/packages/@ourworldindata/grapher/src/index.ts index 0e4edc0f45a..b9b100cdf1e 100644 --- a/packages/@ourworldindata/grapher/src/index.ts +++ b/packages/@ourworldindata/grapher/src/index.ts @@ -78,6 +78,7 @@ export { getSelectedEntityNamesParam, generateSelectedEntityNamesParam, } from "./core/EntityUrlBuilder" +export { grapherConfigToQueryParams } from "./core/GrapherUrl.js" export { type SlideShowManager, SlideShowController, diff --git a/packages/@ourworldindata/types/src/dbTypes/ChartViews.ts b/packages/@ourworldindata/types/src/dbTypes/ChartViews.ts index e08437d5fbf..5a5ad5d92be 100644 --- a/packages/@ourworldindata/types/src/dbTypes/ChartViews.ts +++ b/packages/@ourworldindata/types/src/dbTypes/ChartViews.ts @@ -1,3 +1,4 @@ +import { JsonString } from "../domainTypes/Various.js" import { GrapherInterface } from "../grapherTypes/GrapherTypes.js" export const ChartViewsTableName = "chart_views" @@ -6,6 +7,7 @@ export interface DbInsertChartView { name: string chartConfigId: string parentChartId: number + queryParamsForParentChart?: JsonString | null createdAt?: Date | null updatedAt?: Date | null lastEditedByUserId: number