diff --git a/adminSiteServer/apiRouter.ts b/adminSiteServer/apiRouter.ts index faa2569fe03..1398884bbbc 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" @@ -3283,7 +3285,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 @@ -3308,8 +3310,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) => { @@ -3370,10 +3374,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( @@ -3388,7 +3393,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 @@ -3408,6 +3414,9 @@ getRouteWithROTransaction( configFull: parseChartConfig(row.configFull), configPatch: parseChartConfig(row.configPatch), parentConfigFull: parseChartConfig(row.parentConfigFull), + queryParamsForParentChart: JSON.parse( + row.queryParamsForParentChart + ), } return chartView @@ -3424,8 +3433,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 @@ -3444,6 +3453,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 @@ -3473,8 +3483,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 @@ -3488,10 +3498,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