From 00182a3813abb25bffd413f26c8bee0d865c317b Mon Sep 17 00:00:00 2001 From: Chayanin Noramuttha Date: Thu, 3 Sep 2026 16:09:59 -0700 Subject: [PATCH 1/2] fix(notebooks): bind sample notebook paragraphs to the selected data source (#2454) Add sample notebooks collected the data source chosen in its modal and passed it to the sample data install, but dropped it before creating the notebooks. main.tsx posted only visIds, and addSampleNotes accepted only visIds, so the generated paragraphs carried no dataSourceMDSId or dataSourceMDSLabel. The per-paragraph selector gates defaultOption on paradataSourceMDSId !== undefined, so with nothing stored it fell through to handleDefaultDataSource and resolved the configured default data source instead. The sample data landed on the picked cluster while the notebook that reads it pointed somewhere else, so on a multi-cluster setup the PPL and SQL paragraphs query a cluster that has no sample indices. Thread the id and label from the modal through the route into addSampleNotes, which stamps both onto every paragraph before create. Stamped in addSampleNotes rather than in the four builder functions inside sample_notebooks.ts, which keeps that 1237-line file untouched. Both fields fall back to the empty string when nothing is selected, and that fallback is load-bearing rather than cosmetic. notebook.tsx blanks a QUERY paragraph's output and raises a danger toast when dataSourceMDSId is truthy while multiple data sources are disabled. Local cluster's id is already the empty string, so Local cluster and non-MDS installs keep their existing code path. Complementary to PR 2861 rather than dependent on it. That fix covers the Local cluster path with multiple data sources enabled, which is a different case from the real-data-source path this change addresses. Signed-off-by: Chayanin Noramuttha --- .../components/notebooks/components/main.tsx | 2 +- .../saved_objects_notebooks_router.tsx | 22 +++++++++++++++++-- server/routes/notebooks/noteRouter.ts | 6 ++++- 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/public/components/notebooks/components/main.tsx b/public/components/notebooks/components/main.tsx index c8234699b1..9087289fd1 100644 --- a/public/components/notebooks/components/main.tsx +++ b/public/components/notebooks/components/main.tsx @@ -408,7 +408,7 @@ export class Main extends React.Component { }); await this.props.http .post(`${NOTEBOOKS_API_PREFIX}/note/savedNotebook/addSampleNotebooks`, { - body: JSON.stringify({ visIds }), + body: JSON.stringify({ visIds, dataSourceMDSId, dataSourceMDSLabel }), }) .then((res) => { const newData = res.body.map((notebook: any) => ({ diff --git a/server/adaptors/notebooks/saved_objects_notebooks_router.tsx b/server/adaptors/notebooks/saved_objects_notebooks_router.tsx index 6a941fbf9a..f881147de1 100644 --- a/server/adaptors/notebooks/saved_objects_notebooks_router.tsx +++ b/server/adaptors/notebooks/saved_objects_notebooks_router.tsx @@ -68,13 +68,31 @@ export function renameNotebook(noteBookObj: { name: string; noteId: string }) { export async function addSampleNotes( opensearchNotebooksClient: SavedObjectsClientContract, - visIds: string[] + visIds: string[], + dataSourceMDSId?: string, + dataSourceMDSLabel?: string ) { const notebooks = getSampleNotebooks(visIds); const sampleNotebooks = []; try { + // Without a stored binding, each code block's selector falls back to the default data + // source rather than the one the sample data was just installed against. for (const item of notebooks) { - const createdNotebooks = await opensearchNotebooksClient.create(NOTEBOOK_SAVED_OBJECT, item); + const notebook = { + ...item, + savedNotebook: { + ...item.savedNotebook, + paragraphs: item.savedNotebook.paragraphs.map((paragraph) => ({ + ...paragraph, + dataSourceMDSId: dataSourceMDSId ?? '', + dataSourceMDSLabel: dataSourceMDSLabel ?? '', + })), + }, + }; + const createdNotebooks = await opensearchNotebooksClient.create( + NOTEBOOK_SAVED_OBJECT, + notebook + ); sampleNotebooks.push({ dateCreated: createdNotebooks.attributes.savedNotebook.dateCreated, dateModified: createdNotebooks.attributes.savedNotebook.dateModified, diff --git a/server/routes/notebooks/noteRouter.ts b/server/routes/notebooks/noteRouter.ts index dac07d9448..d1a4b39160 100644 --- a/server/routes/notebooks/noteRouter.ts +++ b/server/routes/notebooks/noteRouter.ts @@ -237,6 +237,8 @@ export function registerNoteRoute(router: IRouter) { validate: { body: schema.object({ visIds: schema.arrayOf(schema.string()), + dataSourceMDSId: schema.maybe(schema.string({ defaultValue: '' })), + dataSourceMDSLabel: schema.maybe(schema.string({ defaultValue: '' })), }), }, }, @@ -250,7 +252,9 @@ export function registerNoteRoute(router: IRouter) { try { const sampleNotebooks = await addSampleNotes( opensearchNotebooksClient, - request.body.visIds + request.body.visIds, + request.body.dataSourceMDSId, + request.body.dataSourceMDSLabel ); return response.ok({ body: sampleNotebooks, From 1a1bae3c00baa84898e1fece3c1270aaf1877d61 Mon Sep 17 00:00:00 2001 From: Chayanin Noramuttha Date: Fri, 4 Sep 2026 12:04:38 -0700 Subject: [PATCH 2/2] fix(notebooks): drop dead defaultValue from addSampleNotebooks schema Signed-off-by: Chayanin Noramuttha --- server/routes/notebooks/noteRouter.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/routes/notebooks/noteRouter.ts b/server/routes/notebooks/noteRouter.ts index d1a4b39160..c443d1877c 100644 --- a/server/routes/notebooks/noteRouter.ts +++ b/server/routes/notebooks/noteRouter.ts @@ -237,8 +237,8 @@ export function registerNoteRoute(router: IRouter) { validate: { body: schema.object({ visIds: schema.arrayOf(schema.string()), - dataSourceMDSId: schema.maybe(schema.string({ defaultValue: '' })), - dataSourceMDSLabel: schema.maybe(schema.string({ defaultValue: '' })), + dataSourceMDSId: schema.maybe(schema.string()), + dataSourceMDSLabel: schema.maybe(schema.string()), }), }, },