mirror of
https://github.com/Syngnat/GoNavi.git
synced 2026-07-10 06:52:18 +08:00
🐛 fix(sql-editor): 修复新建查询关闭应用未提示保存
This commit is contained in:
@@ -57,7 +57,7 @@ describe('sqlEditorApplicationQuit', () => {
|
||||
})]);
|
||||
});
|
||||
|
||||
it('collects dirty saved-query tabs and ignores unnamed temporary query tabs', async () => {
|
||||
it('collects dirty saved-query tabs and unnamed temporary query tabs', async () => {
|
||||
const savedQuery = createSavedQuery();
|
||||
const savedTab = createQueryTab({
|
||||
id: 'tab-2',
|
||||
@@ -75,7 +75,7 @@ describe('sqlEditorApplicationQuit', () => {
|
||||
|
||||
const targets = await collectApplicationQuitUnsavedSQLTargets([savedTab, unnamedTab], [savedQuery], vi.fn());
|
||||
|
||||
expect(targets).toHaveLength(1);
|
||||
expect(targets).toHaveLength(2);
|
||||
expect(targets[0]).toMatchObject({
|
||||
kind: 'saved-query',
|
||||
tabId: 'tab-2',
|
||||
@@ -84,9 +84,30 @@ describe('sqlEditorApplicationQuit', () => {
|
||||
connectionId: 'conn-1',
|
||||
dbName: 'main',
|
||||
});
|
||||
expect(targets[1]).toMatchObject({
|
||||
kind: 'unsaved-query',
|
||||
tabId: 'tab-3',
|
||||
title: 'New query',
|
||||
draft: 'select * from draft_only;',
|
||||
connectionId: 'conn-1',
|
||||
dbName: 'main',
|
||||
});
|
||||
});
|
||||
|
||||
it('saves external SQL files and existing saved queries before application quit', async () => {
|
||||
it('ignores blank unnamed temporary query tabs', async () => {
|
||||
const unnamedTab = createQueryTab({
|
||||
id: 'tab-3',
|
||||
title: 'New query',
|
||||
query: '',
|
||||
});
|
||||
setQueryTabDraft('tab-3', ' ');
|
||||
|
||||
const targets = await collectApplicationQuitUnsavedSQLTargets([unnamedTab], [], vi.fn());
|
||||
|
||||
expect(targets).toEqual([]);
|
||||
});
|
||||
|
||||
it('saves external SQL files, existing saved queries, and unnamed query drafts before application quit', async () => {
|
||||
const saveQuery = vi.fn(async (query: SavedQuery) => query);
|
||||
const writeSQLFile = vi.fn(async () => ({ success: true }));
|
||||
|
||||
@@ -107,6 +128,14 @@ describe('sqlEditorApplicationQuit', () => {
|
||||
connectionId: 'conn-2',
|
||||
dbName: 'reporting',
|
||||
},
|
||||
{
|
||||
kind: 'unsaved-query',
|
||||
tabId: 'tab-3',
|
||||
title: 'New query',
|
||||
draft: 'select 3;',
|
||||
connectionId: 'conn-3',
|
||||
dbName: 'scratch',
|
||||
},
|
||||
], saveQuery, writeSQLFile);
|
||||
|
||||
expect(writeSQLFile).toHaveBeenCalledWith('/tmp/file.sql', 'select 1;');
|
||||
@@ -116,5 +145,11 @@ describe('sqlEditorApplicationQuit', () => {
|
||||
connectionId: 'conn-2',
|
||||
dbName: 'reporting',
|
||||
}));
|
||||
expect(saveQuery).toHaveBeenCalledWith(expect.objectContaining({
|
||||
name: 'New query',
|
||||
sql: 'select 3;',
|
||||
connectionId: 'conn-3',
|
||||
dbName: 'scratch',
|
||||
}));
|
||||
});
|
||||
});
|
||||
|
||||
@@ -31,6 +31,14 @@ export type ApplicationQuitUnsavedSQLTarget =
|
||||
draft: string;
|
||||
connectionId: string;
|
||||
dbName: string;
|
||||
}
|
||||
| {
|
||||
kind: 'unsaved-query';
|
||||
tabId: string;
|
||||
title: string;
|
||||
draft: string;
|
||||
connectionId: string;
|
||||
dbName: string;
|
||||
};
|
||||
|
||||
export type ReadSQLFileForQuit = (filePath: string) => Promise<QueryResultLike>;
|
||||
@@ -64,6 +72,13 @@ const hasSavedQueryUnsavedChanges = (
|
||||
|| dbName !== toTrimmedString(savedQuery.dbName);
|
||||
};
|
||||
|
||||
let applicationQuitSavedQueryIdSeed = 0;
|
||||
|
||||
const createApplicationQuitSavedQueryId = (): string => {
|
||||
applicationQuitSavedQueryIdSeed += 1;
|
||||
return `saved-${Date.now()}-${applicationQuitSavedQueryIdSeed}`;
|
||||
};
|
||||
|
||||
export const buildApplicationQuitUnsavedSQLLabel = (
|
||||
targets: ApplicationQuitUnsavedSQLTarget[],
|
||||
): string => {
|
||||
@@ -105,9 +120,20 @@ export const collectApplicationQuitUnsavedSQLTargets = async (
|
||||
continue;
|
||||
}
|
||||
|
||||
const savedQuery = resolveSavedQueryForTab(tab, savedQueries);
|
||||
if (!savedQuery) continue;
|
||||
const draft = getQueryTabDraft(tab.id, String(tab.query ?? ''));
|
||||
const savedQuery = resolveSavedQueryForTab(tab, savedQueries);
|
||||
if (!savedQuery) {
|
||||
if (!draft.trim()) continue;
|
||||
targets.push({
|
||||
kind: 'unsaved-query',
|
||||
tabId: tab.id,
|
||||
title: resolveTabTitle(tab, 'SQL Query'),
|
||||
draft,
|
||||
connectionId: toTrimmedString(tab.connectionId),
|
||||
dbName: toTrimmedString(tab.dbName),
|
||||
});
|
||||
continue;
|
||||
}
|
||||
if (!hasSavedQueryUnsavedChanges(tab, savedQuery, draft)) continue;
|
||||
targets.push({
|
||||
kind: 'saved-query',
|
||||
@@ -137,11 +163,23 @@ export const saveApplicationQuitUnsavedSQLTargets = async (
|
||||
continue;
|
||||
}
|
||||
|
||||
if (target.kind === 'saved-query') {
|
||||
await saveQuery({
|
||||
...target.savedQuery,
|
||||
sql: target.draft,
|
||||
connectionId: target.connectionId,
|
||||
dbName: target.dbName,
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
await saveQuery({
|
||||
...target.savedQuery,
|
||||
id: createApplicationQuitSavedQueryId(),
|
||||
name: target.title,
|
||||
sql: target.draft,
|
||||
connectionId: target.connectionId,
|
||||
dbName: target.dbName,
|
||||
createdAt: Date.now(),
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user