mirror of
https://github.com/apache/superset.git
synced 2026-07-09 00:05:36 +00:00
Compare commits
1 Commits
chore/ci/s
...
geido/fix/
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3a21559acd |
@@ -518,7 +518,7 @@ export function syncQueryEditor(queryEditor) {
|
|||||||
...localStorageQueries.map(query =>
|
...localStorageQueries.map(query =>
|
||||||
migrateQuery(query.id, newQueryEditor.tabViewId, dispatch),
|
migrateQuery(query.id, newQueryEditor.tabViewId, dispatch),
|
||||||
),
|
),
|
||||||
]);
|
]).then(() => newQueryEditor); // Return the newQueryEditor for chaining
|
||||||
})
|
})
|
||||||
.catch(() =>
|
.catch(() =>
|
||||||
dispatch(
|
dispatch(
|
||||||
@@ -649,7 +649,7 @@ export function loadQueryEditor(queryEditor) {
|
|||||||
return { type: LOAD_QUERY_EDITOR, queryEditor };
|
return { type: LOAD_QUERY_EDITOR, queryEditor };
|
||||||
}
|
}
|
||||||
|
|
||||||
export function setTables(tableSchemas) {
|
export function setTables(tableSchemas, queryEditorId = null) {
|
||||||
const tables = tableSchemas
|
const tables = tableSchemas
|
||||||
.filter(tableSchema => tableSchema.description !== null)
|
.filter(tableSchema => tableSchema.description !== null)
|
||||||
.map(tableSchema => {
|
.map(tableSchema => {
|
||||||
@@ -661,9 +661,12 @@ export function setTables(tableSchemas) {
|
|||||||
indexes,
|
indexes,
|
||||||
dataPreviewQueryId,
|
dataPreviewQueryId,
|
||||||
} = tableSchema.description;
|
} = tableSchema.description;
|
||||||
|
// Use the provided queryEditorId if available, otherwise use tab_state_id
|
||||||
|
const tableQueryEditorId = queryEditorId || tableSchema.tab_state_id.toString();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
dbId: tableSchema.database_id,
|
dbId: tableSchema.database_id,
|
||||||
queryEditorId: tableSchema.tab_state_id.toString(),
|
queryEditorId: tableQueryEditorId,
|
||||||
catalog: tableSchema.catalog,
|
catalog: tableSchema.catalog,
|
||||||
schema: tableSchema.schema,
|
schema: tableSchema.schema,
|
||||||
name: tableSchema.table,
|
name: tableSchema.table,
|
||||||
@@ -706,7 +709,8 @@ export function fetchQueryEditor(queryEditor, displayLimit) {
|
|||||||
hideLeftBar: json.hide_left_bar,
|
hideLeftBar: json.hide_left_bar,
|
||||||
};
|
};
|
||||||
dispatch(loadQueryEditor(loadedQueryEditor));
|
dispatch(loadQueryEditor(loadedQueryEditor));
|
||||||
dispatch(setTables(json.table_schemas || []));
|
// Pass the queryEditor.id to setTables to ensure correct queryEditorId
|
||||||
|
dispatch(setTables(json.table_schemas || [], loadedQueryEditor.id));
|
||||||
if (json.latest_query && json.latest_query.resultsKey) {
|
if (json.latest_query && json.latest_query.resultsKey) {
|
||||||
dispatch(fetchQueryResults(json.latest_query, displayLimit));
|
dispatch(fetchQueryResults(json.latest_query, displayLimit));
|
||||||
}
|
}
|
||||||
@@ -953,13 +957,17 @@ export function mergeTable(table, query, prepend) {
|
|||||||
export function addTable(queryEditor, tableName, catalogName, schemaName) {
|
export function addTable(queryEditor, tableName, catalogName, schemaName) {
|
||||||
return function (dispatch, getState) {
|
return function (dispatch, getState) {
|
||||||
const { dbId } = getUpToDateQuery(getState(), queryEditor, queryEditor.id);
|
const { dbId } = getUpToDateQuery(getState(), queryEditor, queryEditor.id);
|
||||||
|
|
||||||
|
// Always use the actual queryEditor.id for consistency
|
||||||
|
// The syncTable function will handle converting to tabViewId when syncing to backend
|
||||||
const table = {
|
const table = {
|
||||||
dbId,
|
dbId,
|
||||||
queryEditorId: queryEditor.tabViewId ?? queryEditor.id,
|
queryEditorId: queryEditor.id,
|
||||||
catalog: catalogName,
|
catalog: catalogName,
|
||||||
schema: schemaName,
|
schema: schemaName,
|
||||||
name: tableName,
|
name: tableName,
|
||||||
};
|
};
|
||||||
|
|
||||||
dispatch(
|
dispatch(
|
||||||
mergeTable({
|
mergeTable({
|
||||||
...table,
|
...table,
|
||||||
@@ -1016,13 +1024,54 @@ export function runTablePreviewQuery(newTable, runPreviewOnly) {
|
|||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function syncTable(table, tableMetadata) {
|
export function syncTable(table, tableMetadata) {
|
||||||
return function (dispatch) {
|
return function (dispatch, getState) {
|
||||||
|
// Get the current queryEditor to use its tabViewId if available
|
||||||
|
const { queryEditors } = getState().sqlLab;
|
||||||
|
const queryEditor = queryEditors.find(qe => qe.id === table.queryEditorId);
|
||||||
|
|
||||||
|
// If queryEditor is still in localStorage (not synced), wait for sync first
|
||||||
|
if (queryEditor?.inLocalStorage) {
|
||||||
|
return dispatch(syncQueryEditor(queryEditor)).then((syncedEditor) => {
|
||||||
|
// After syncing, update the table with the new queryEditorId
|
||||||
|
const updatedTable = {
|
||||||
|
...table,
|
||||||
|
queryEditorId: syncedEditor?.tabViewId || queryEditor.tabViewId || table.queryEditorId
|
||||||
|
};
|
||||||
|
return dispatch(syncTable(updatedTable, tableMetadata));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use tabViewId if available, otherwise use the current queryEditorId
|
||||||
|
const correctQueryEditorId = queryEditor?.tabViewId || table.queryEditorId;
|
||||||
|
|
||||||
|
// Only sync to backend if we have a valid integer tabViewId
|
||||||
|
const canSyncToBackend = Boolean(queryEditor?.tabViewId && Number.isInteger(queryEditor.tabViewId));
|
||||||
|
|
||||||
|
if (!canSyncToBackend) {
|
||||||
|
// If we can't sync to backend, store in localStorage as fallback
|
||||||
|
dispatch(
|
||||||
|
mergeTable({
|
||||||
|
...table,
|
||||||
|
...tableMetadata,
|
||||||
|
expanded: true,
|
||||||
|
initialized: true,
|
||||||
|
inLocalStorage: true, // Mark as stored in localStorage
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
const sync = isFeatureEnabled(FeatureFlag.SqllabBackendPersistence)
|
const sync = isFeatureEnabled(FeatureFlag.SqllabBackendPersistence)
|
||||||
? SupersetClient.post({
|
? SupersetClient.post({
|
||||||
endpoint: encodeURI('/tableschemaview/'),
|
endpoint: encodeURI('/tableschemaview/'),
|
||||||
postPayload: { table: { ...tableMetadata, ...table } },
|
postPayload: {
|
||||||
|
table: {
|
||||||
|
...tableMetadata,
|
||||||
|
...table,
|
||||||
|
queryEditorId: correctQueryEditorId
|
||||||
|
}
|
||||||
|
},
|
||||||
})
|
})
|
||||||
: Promise.resolve({ json: { id: table.id } });
|
: Promise.resolve({ json: { id: table.id } });
|
||||||
|
|
||||||
|
|||||||
@@ -74,11 +74,6 @@ const SqlEditorLeftBar = ({
|
|||||||
queryEditorId,
|
queryEditorId,
|
||||||
height = 500,
|
height = 500,
|
||||||
}: SqlEditorLeftBarProps) => {
|
}: SqlEditorLeftBarProps) => {
|
||||||
const allSelectedTables = useSelector<SqlLabRootState, Table[]>(
|
|
||||||
({ sqlLab }) =>
|
|
||||||
sqlLab.tables.filter(table => table.queryEditorId === queryEditorId),
|
|
||||||
shallowEqual,
|
|
||||||
);
|
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const queryEditor = useQueryEditor(queryEditorId, [
|
const queryEditor = useQueryEditor(queryEditorId, [
|
||||||
'dbId',
|
'dbId',
|
||||||
@@ -87,6 +82,32 @@ const SqlEditorLeftBar = ({
|
|||||||
'tabViewId',
|
'tabViewId',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
const allSelectedTables = useSelector<SqlLabRootState, Table[]>(
|
||||||
|
({ sqlLab }) => {
|
||||||
|
// Find the current queryEditor to get its tabViewId
|
||||||
|
const currentQueryEditor = sqlLab.queryEditors.find(
|
||||||
|
qe => qe.id === queryEditorId
|
||||||
|
);
|
||||||
|
const tabViewId = currentQueryEditor?.tabViewId;
|
||||||
|
const filtered = sqlLab.tables.filter(table => {
|
||||||
|
// Match tables that belong to this queryEditor
|
||||||
|
// Handle both cases: when queryEditor has a tabViewId (synced) or not (unsaved)
|
||||||
|
const matchesCurrentId = table.queryEditorId === queryEditorId;
|
||||||
|
const matchesTabViewId = tabViewId && (
|
||||||
|
table.queryEditorId === tabViewId ||
|
||||||
|
table.queryEditorId === String(tabViewId)
|
||||||
|
);
|
||||||
|
// Also check if the table's queryEditorId matches the tabViewId as a string
|
||||||
|
const matchesTabViewIdString = tabViewId && table.queryEditorId === String(tabViewId);
|
||||||
|
|
||||||
|
return matchesCurrentId || matchesTabViewId || matchesTabViewIdString;
|
||||||
|
});
|
||||||
|
|
||||||
|
return filtered;
|
||||||
|
},
|
||||||
|
shallowEqual,
|
||||||
|
);
|
||||||
|
|
||||||
const [_emptyResultsWithSearch, setEmptyResultsWithSearch] = useState(false);
|
const [_emptyResultsWithSearch, setEmptyResultsWithSearch] = useState(false);
|
||||||
const [userSelectedDb, setUserSelected] = useState<DatabaseObject | null>(
|
const [userSelectedDb, setUserSelected] = useState<DatabaseObject | null>(
|
||||||
null,
|
null,
|
||||||
@@ -151,6 +172,7 @@ const SqlEditorLeftBar = ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
tablesToAdd.forEach(tableName => {
|
tablesToAdd.forEach(tableName => {
|
||||||
|
// Use the actual queryEditor object with its current id
|
||||||
dispatch(addTable(queryEditor, tableName, catalogName, schemaName));
|
dispatch(addTable(queryEditor, tableName, catalogName, schemaName));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -125,9 +125,11 @@ export default function getInitialState({
|
|||||||
.filter(tableSchema => tableSchema.description !== null)
|
.filter(tableSchema => tableSchema.description !== null)
|
||||||
.forEach(tableSchema => {
|
.forEach(tableSchema => {
|
||||||
const { dataPreviewQueryId, ...persistData } = tableSchema.description;
|
const { dataPreviewQueryId, ...persistData } = tableSchema.description;
|
||||||
|
// Use the active tab ID (which corresponds to the queryEditor.id) for consistency
|
||||||
|
const queryEditorId = activeTab.id.toString();
|
||||||
const table = {
|
const table = {
|
||||||
dbId: tableSchema.database_id ?? 0,
|
dbId: tableSchema.database_id ?? 0,
|
||||||
queryEditorId: tableSchema.tab_state_id.toString(),
|
queryEditorId, // Use the activeTab.id which corresponds to queryEditor.id
|
||||||
catalog: tableSchema.catalog,
|
catalog: tableSchema.catalog,
|
||||||
schema: tableSchema.schema,
|
schema: tableSchema.schema,
|
||||||
name: tableSchema.table,
|
name: tableSchema.table,
|
||||||
|
|||||||
@@ -480,12 +480,29 @@ export default function sqlLabReducer(state = {}, action) {
|
|||||||
// continue regardless of error
|
// continue regardless of error
|
||||||
}
|
}
|
||||||
// replace localStorage query editor with the server backed one
|
// replace localStorage query editor with the server backed one
|
||||||
return alterInArr(
|
let newState = alterInArr(
|
||||||
state,
|
state,
|
||||||
'queryEditors',
|
'queryEditors',
|
||||||
action.oldQueryEditor,
|
action.oldQueryEditor,
|
||||||
action.newQueryEditor,
|
action.newQueryEditor,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Update queryEditorId for all tables that reference the old queryEditor
|
||||||
|
const updatedTables = newState.tables.map(table => {
|
||||||
|
if (table.queryEditorId === action.oldQueryEditor.id) {
|
||||||
|
const newQueryEditorId = action.newQueryEditor.tabViewId || action.newQueryEditor.id;
|
||||||
|
return {
|
||||||
|
...table,
|
||||||
|
queryEditorId: newQueryEditorId,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return table;
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
...newState,
|
||||||
|
tables: updatedTables,
|
||||||
|
};
|
||||||
},
|
},
|
||||||
[actions.MIGRATE_TABLE]() {
|
[actions.MIGRATE_TABLE]() {
|
||||||
try {
|
try {
|
||||||
|
|||||||
Reference in New Issue
Block a user