Skip to content

Commit f6de6aa

Browse files
committed
feat: Add loading indicators and state management for database connection and quick exploration actions.
1 parent 0cd1f0a commit f6de6aa

1 file changed

Lines changed: 31 additions & 5 deletions

File tree

frontend/pages/QueryGeneratorPage.tsx

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,8 @@ const QueryGeneratorPage: React.FC<QueryGeneratorPageProps> = ({ name, email, on
346346
const [connectedResource, setConnectedResource] = useState<SelectedResource | null>(null);
347347
const [connectedDbInfo, setConnectedDbInfo] = useState<DbInfo | null>(null);
348348
const [dbError, setDbError] = useState<string | null>(null);
349+
const [isConnectingToDb, setIsConnectingToDb] = useState<string | null>(null);
350+
const [quickExploringAccountId, setQuickExploringAccountId] = useState<string | null>(null);
349351

350352
// State for AI query generation
351353
const [queryResult, setQueryResult] = useState<QueryResultData | null>(null);
@@ -574,16 +576,21 @@ const QueryGeneratorPage: React.FC<QueryGeneratorPageProps> = ({ name, email, on
574576
}
575577
}, [selectedAccountId, connectedResource, azureAccounts, handleDisconnect]);
576578

577-
const handleConnectDatabase = useCallback((dbInfo: DbInfo) => {
579+
const handleConnectDatabase = useCallback(async (dbInfo: DbInfo) => {
578580
const account = azureAccounts.find(acc => acc.id === selectedAccountId);
579581
if (!account) return;
580582

583+
setIsConnectingToDb(dbInfo.name);
584+
// Simulate connection delay for better UX
585+
await new Promise(resolve => setTimeout(resolve, 800));
586+
581587
setConnectedResource({
582588
accountId: account.id,
583589
databaseName: dbInfo.name,
584590
});
585591
setConnectedDbInfo(dbInfo);
586592
clearQueryState();
593+
setIsConnectingToDb(null);
587594
}, [selectedAccountId, azureAccounts, clearQueryState]);
588595

589596
const handleGenerateQuery = useCallback(async (prompt: string, collectionCtx?: CollectionInfo) => {
@@ -992,6 +999,7 @@ const QueryGeneratorPage: React.FC<QueryGeneratorPageProps> = ({ name, email, on
992999
return;
9931000
}
9941001

1002+
setQuickExploringAccountId(account.id);
9951003
try {
9961004
const dbs = await getDatabasesForAccount(account.id);
9971005
if (dbs.length > 0) {
@@ -1002,6 +1010,8 @@ const QueryGeneratorPage: React.FC<QueryGeneratorPageProps> = ({ name, email, on
10021010
} catch (e) {
10031011
console.error("Quick explorer failed", e);
10041012
setError(`Failed to load databases for '${account.name}'.`);
1013+
} finally {
1014+
setQuickExploringAccountId(null);
10051015
}
10061016
}, [selectedAccountId, accountDatabases, handleLaunchExplorer]);
10071017

@@ -1387,13 +1397,21 @@ const QueryGeneratorPage: React.FC<QueryGeneratorPageProps> = ({ name, email, on
13871397
>
13881398
<CloudIcon className="w-5 h-5 text-slate-500" />
13891399
{account.name}
1400+
{selectedAccountId === account.id && isLoadingDatabases && (
1401+
<SpinnerIcon className="w-4 h-4 animate-spin text-blue-500 ml-2" />
1402+
)}
13901403
</button>
13911404
<button
13921405
onClick={(e) => { e.stopPropagation(); handleQuickExploreAccount(account); }}
1393-
className="flex items-center gap-1.5 px-2 py-1.5 text-xs font-medium text-blue-600 dark:text-blue-400 bg-white dark:bg-slate-700 hover:bg-blue-50 dark:hover:bg-slate-600 border border-slate-200 dark:border-slate-600 rounded-md transition-colors shadow-sm ml-2"
1406+
disabled={quickExploringAccountId !== null}
1407+
className={`flex items-center gap-1.5 px-2 py-1.5 text-xs font-medium text-blue-600 dark:text-blue-400 bg-white dark:bg-slate-700 hover:bg-blue-50 dark:hover:bg-slate-600 border border-slate-200 dark:border-slate-600 rounded-md transition-colors shadow-sm ml-2 ${quickExploringAccountId !== null && quickExploringAccountId !== account.id ? 'opacity-50' : ''}`}
13941408
title={`Quickly open Data Explorer for ${account.name} (first database)`}
13951409
>
1396-
<DataGridIcon className="w-4 h-4" />
1410+
{quickExploringAccountId === account.id ? (
1411+
<SpinnerIcon className="w-4 h-4 animate-spin" />
1412+
) : (
1413+
<DataGridIcon className="w-4 h-4" />
1414+
)}
13971415
<span className="hidden sm:inline">Explorer</span>
13981416
</button>
13991417
</div>
@@ -1412,10 +1430,18 @@ const QueryGeneratorPage: React.FC<QueryGeneratorPageProps> = ({ name, email, on
14121430
key={db.name}
14131431
type="button"
14141432
onClick={() => handleConnectDatabase(db)}
1415-
className="px-4 py-2 border border-blue-600 dark:border-blue-500 text-sm font-medium rounded-md text-white bg-blue-600 hover:bg-blue-700 dark:bg-blue-600 dark:hover:bg-blue-500 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-slate-50 dark:focus:ring-offset-slate-800 focus:ring-blue-500 transition-colors"
1433+
disabled={isConnectingToDb !== null}
1434+
className={`px-4 py-2 border border-blue-600 dark:border-blue-500 text-sm font-medium rounded-md text-white bg-blue-600 hover:bg-blue-700 dark:bg-blue-600 dark:hover:bg-blue-500 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-slate-50 dark:focus:ring-offset-slate-800 focus:ring-blue-500 transition-colors flex items-center gap-2 ${isConnectingToDb !== null && isConnectingToDb !== db.name ? 'opacity-50 cursor-not-allowed' : ''}`}
14161435
title={`Connect to the ${db.name} database`}
14171436
>
1418-
{db.name}
1437+
{isConnectingToDb === db.name ? (
1438+
<>
1439+
<SpinnerIcon className="w-4 h-4 animate-spin" />
1440+
Connecting...
1441+
</>
1442+
) : (
1443+
db.name
1444+
)}
14191445
</button>
14201446
))}
14211447
</div>

0 commit comments

Comments
 (0)