Skip to content

Commit 6a07a9e

Browse files
add dashboard models into entities; also fix lastSQL generated in new-tab flow on dashboard page (#191)
1 parent 855cfbd commit 6a07a9e

File tree

4 files changed

+35
-10
lines changed

4 files changed

+35
-10
lines changed

apps/src/metabase/helpers/dashboard/appState.ts

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,16 @@ import { DashboardInfo, DashboardMetabaseState } from './types';
22
import _, { forEach, reduce, template, values } from 'lodash';
33
import { MetabaseAppStateDashboard, MetabaseAppStateType} from '../DOMToState';
44
import { getTablesWithFields } from '../getDatabaseSchema';
5-
import { getDatabaseInfo, getFieldResolvedName } from '../metabaseAPIHelpers';
5+
import { getAllRelevantModelsForSelectedDb, getDatabaseInfo, getFieldResolvedName } from '../metabaseAPIHelpers';
66
import { getDashboardState, getSelectedDbId } from '../metabaseStateAPI';
77
import { getParsedIframeInfo, RPCs } from 'web';
88
import { getSQLFromMBQL } from '../metabaseAPI';
99
import { metabaseToMarkdownTable } from '../operations';
1010
import { find, get } from 'lodash';
1111
import { getTablesFromSqlRegex, TableAndSchema } from '../parseSql';
1212
import { getTableContextYAML } from '../catalog';
13+
import { MetabaseModel } from '../metabaseAPITypes';
14+
import { getModelsFromSql, getModelsWithFields, modifySqlForMetabaseModels, replaceLLMFriendlyIdentifiersInSqlWithModels } from '../metabaseModels';
1315

1416
// Removed: const { getMetabaseState } = RPCs - using centralized state functions instead
1517

@@ -194,7 +196,8 @@ async function substituteParameters(
194196
sql: string,
195197
dashcard: DashboardMetabaseState['dashcards'][0],
196198
dashboardParamFields: DashboardMetabaseState['dashboards'][0]['param_fields'],
197-
parameterValues: DashboardMetabaseState['parameterValues']) {
199+
parameterValues: DashboardMetabaseState['parameterValues']
200+
) {
198201
// Algo:
199202
// transitivity is: template-tags -> dashcard parameters -> dashcard parameter mappings -> dashboard parameters -> parameter values
200203
// |-> parameter values
@@ -268,9 +271,9 @@ export async function getDashboardAppState(): Promise<MetabaseAppStateDashboard
268271
}
269272
const selectedTabDashcardIds = getSelectedTabDashcardIds(dashboardMetabaseState);
270273
// const dashboardParameters = _.get(dashboardMetabaseState, ['dashboards', dashboardId, 'parameters'], [])
271-
const cards = await Promise.all(selectedTabDashcardIds.map(async dashcardId => await getDashcardInfoWithSQLAndOutputTableMd(dashboardMetabaseState, dashcardId, dashboardId)))
272-
273-
const filteredCards = _.compact(cards);
274+
const allModels = dbId ? await getAllRelevantModelsForSelectedDb(dbId) : []
275+
const cards = await Promise.all(selectedTabDashcardIds.map(async dashcardId => await getDashcardInfoWithSQLAndOutputTableMd(dashboardMetabaseState, dashcardId, dashboardId, allModels)))
276+
let filteredCards = _.compact(cards);
274277
let sqlTables: TableAndSchema[] = []
275278
forEach(filteredCards, (card) => {
276279
if (card) {
@@ -284,9 +287,26 @@ export async function getDashboardAppState(): Promise<MetabaseAppStateDashboard
284287
})
285288
}
286289
})
290+
291+
287292
sqlTables = _.uniqBy(sqlTables, (table) => `${table.schema}::${table.name}`)
288293
const relevantTablesWithFields = await getTablesWithFields(appSettings.tableDiff, appSettings.drMode, !!selectedCatalog, sqlTables, [])
289-
const tableContextYAML = getTableContextYAML(relevantTablesWithFields, selectedCatalog, appSettings.drMode);
294+
// find a list of models from each native card using getModelsFromSql, and then merge them to get relevantModels
295+
const modelsFromAllCards = (await Promise.all(filteredCards.map(async card => {
296+
if (card.sql) {
297+
return await getModelsFromSql(card.sql, allModels)
298+
}
299+
return []
300+
}))).flat()
301+
const dedupedCardAndSelectedModels = _.uniqBy([...modelsFromAllCards, ...appSettings.selectedModels], 'modelId')
302+
const relevantModelsWithFields = await getModelsWithFields(dedupedCardAndSelectedModels)
303+
const allFormattedTables = [...relevantTablesWithFields, ...relevantModelsWithFields]
304+
const tableContextYAML = getTableContextYAML(allFormattedTables, selectedCatalog, appSettings.drMode);
305+
filteredCards = filteredCards.map(card => {
306+
// replace model identifiers with model ids
307+
card.sql = modifySqlForMetabaseModels(card.sql, allModels)
308+
return card
309+
})
290310
dashboardInfo.cards = filteredCards
291311
// filter out dashcards with null names or ids
292312
.filter(dashcard => dashcard.name !== null && dashcard.id !== null);

apps/src/metabase/helpers/metabaseModels.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ export const getModelsWithFields = async (models: MetabaseModel[]) => {
104104

105105
// get any models in the sql that look like {{#1234-some-model-name}}
106106
// verify that the model with that id exists in all models
107-
const getModelsFromSql = async (sql: string, allModels: MetabaseModel[]) => {
107+
export const getModelsFromSql = async (sql: string, allModels: MetabaseModel[]) => {
108108
const regex = /{{#(\d+)-.*?}}/g;
109109
const matches = [...sql.matchAll(regex)];
110110
const modelIds = matches.map(match => match[1])

apps/src/package.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@ export { applyTableDiffs } from "./common/utils";
33
export { getTableContextYAML, filterTablesByCatalog } from "./metabase/helpers/catalog";
44
export { getTableData } from "./metabase/helpers/metabaseAPIHelpers";
55
export { getAllTemplateTagsInQuery } from "./metabase/helpers/sqlQuery";
6-
export { getModelsWithFields, getSelectedAndRelevantModels } from "./metabase/helpers/metabaseModels";
6+
export { getModelsWithFields, getSelectedAndRelevantModels, modifySqlForMetabaseModels, replaceLLMFriendlyIdentifiersInSqlWithModels } from "./metabase/helpers/metabaseModels";
77
export { getCurrentQuery } from "./metabase/helpers/metabaseStateAPI";

web/src/components/common/Markdown.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ import { renderString } from '../../helpers/templatize'
1010
import { getOrigin } from '../../helpers/origin'
1111
import { getApp } from '../../helpers/app'
1212
import { processSQLWithCtesOrModels } from '../../helpers/catalogAsModels'
13-
import { getAllTemplateTagsInQuery } from 'apps'
13+
import { getAllTemplateTagsInQuery, replaceLLMFriendlyIdentifiersInSqlWithModels } from 'apps'
14+
import type { MetabaseModel } from 'apps/types'
1415
import { Badge } from "@chakra-ui/react";
1516

1617

@@ -159,9 +160,13 @@ export function Markdown({content, messageIndex}: {content: string, messageIndex
159160
if (content.includes('{{MX_LAST_SQL_URL}}')) {
160161
try {
161162
// Extract last SQL from messages before the current message
162-
const lastSQL = messageIndex !== undefined
163+
let lastSQL = messageIndex !== undefined
163164
? extractLastSQLFromMessages(currentThread?.messages || [], messageIndex)
164165
: null;
166+
if (lastSQL) {
167+
const allModels: MetabaseModel[] = toolContext?.dbInfo?.models || []
168+
lastSQL = replaceLLMFriendlyIdentifiersInSqlWithModels(lastSQL, allModels)
169+
}
165170

166171
if (lastSQL) {
167172
// Get Metabase origin from iframe info

0 commit comments

Comments
 (0)