Skip to content

Commit bacbae1

Browse files
committed
fix: Database tab refresh
We’ll use query keys more consistently now, busting the right thing at the right time. I also simplified the database/table to be a single route with optional params, and a component render-time route replacement. This makes the caching more consistent. Restarting the cluster now properly invalidates the database page’s cache, as a result. https://harperdb.atlassian.net/browse/STUDIO-478
1 parent 31c85b8 commit bacbae1

File tree

25 files changed

+108
-169
lines changed

25 files changed

+108
-169
lines changed

src/features/auth/ClusterInstanceSignIn.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { Input } from '@/components/ui/input';
1010
import { activeClusterStatuses } from '@/config/clusterStatuses';
1111
import { defaultInstanceRoute, defaultInstanceRouteUpOne, isLocalStudio } from '@/config/constants';
1212
import { useInstanceClientIdParams } from '@/config/useInstanceClient';
13+
import { currentUserQueryKey } from '@/features/auth/queries/getCurrentUser';
1314
import { getClusterInfoQueryOptions } from '@/features/cluster/queries/getClusterInfoQuery';
1415
import { useInstanceLoginMutation } from '@/features/instance/operations/mutations/useInstanceLoginMutation';
1516
import { getInstanceHealthQueryOptions } from '@/features/instance/operations/queries/getInstanceHealth';
@@ -19,7 +20,6 @@ import { authStore, OverallAppSignIn } from '@/lib/authStore';
1920
import { CrossLocalhostIssueType, detectCrossLocalhostUrls } from '@/lib/urls/detectCrossLocalhostUrls';
2021
import { getOperationsUrlForCluster } from '@/lib/urls/getOperationsUrlForCluster';
2122
import { getOperationsUrlForInstance } from '@/lib/urls/getOperationsUrlForInstance';
22-
import { queryKeys } from '@/react-query/constants';
2323
import { zodResolver } from '@hookform/resolvers/zod';
2424
import { useQuery, useQueryClient } from '@tanstack/react-query';
2525
import { Navigate, useNavigate, useParams, useRouter, useSearch } from '@tanstack/react-router';
@@ -97,7 +97,7 @@ export function ClusterInstanceSignIn() {
9797
}
9898
}
9999
authStore.setUserForEntity(instance || cluster || OverallAppSignIn, user);
100-
void queryClient.invalidateQueries({ queryKey: [queryKeys.user], refetchType: 'none' });
100+
void queryClient.invalidateQueries({ queryKey: currentUserQueryKey, refetchType: 'none' });
101101
void router.invalidate();
102102
await navigate({
103103
to: redirect?.startsWith('/')

src/features/auth/SignIn.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@ import { FormLabel } from '@/components/ui/form/FormLabel';
77
import { FormMessage } from '@/components/ui/form/FormMessage';
88
import { Input } from '@/components/ui/input';
99
import { useLoginMutation } from '@/features/auth/hooks/useSignIn';
10+
import { currentUserQueryKey } from '@/features/auth/queries/getCurrentUser';
1011
import { reoClient } from '@/integrations/reo/reo';
1112
import { authStore, OverallAppSignIn } from '@/lib/authStore';
1213
import { parseCompanyFromEmail } from '@/lib/string/parseCompanyFromEmail';
1314
import { getDefaultSignedInCloudRouteForUser } from '@/lib/urls/getDefaultSignedInCloudRouteForUser';
1415
import { zodRequireEmail } from '@/lib/zod/email';
1516
import { zodRequirePassword } from '@/lib/zod/password';
16-
import { queryKeys } from '@/react-query/constants';
1717
import { zodResolver } from '@hookform/resolvers/zod';
1818
import { useQueryClient } from '@tanstack/react-query';
1919
import { Link, useNavigate, useRouter, useSearch } from '@tanstack/react-router';
@@ -65,7 +65,7 @@ export function SignIn() {
6565
type: 'email',
6666
...(company ? { company } : {}),
6767
});
68-
await queryClient.invalidateQueries({ queryKey: [queryKeys.user], refetchType: 'none' });
68+
await queryClient.invalidateQueries({ queryKey: currentUserQueryKey, refetchType: 'none' });
6969
void router.invalidate();
7070
await navigate({ to: redirect?.startsWith('/') ? redirect : defaultCloudRoute });
7171
},

src/features/auth/queries/getCurrentUser.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { User } from '@/lib/api.patch';
22
import { apiClient } from '@/config/apiClient';
3-
import { queryKeys } from '@/react-query/constants';
43
import { queryOptions } from '@tanstack/react-query';
54

65
export async function getCurrentUser(): Promise<User> {
@@ -9,9 +8,11 @@ export async function getCurrentUser(): Promise<User> {
98
return data as unknown as User;
109
}
1110

11+
export const currentUserQueryKey = ['current-user'];
12+
1213
export function getCurrentUserQueryOptions() {
1314
return queryOptions({
14-
queryKey: [queryKeys.user],
15+
queryKey: currentUserQueryKey,
1516
queryFn: getCurrentUser,
1617
retry: false,
1718
});

src/features/cluster/queries/getClusterInfoQuery.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { apiClient } from '@/config/apiClient';
22
import { Cluster } from '@/lib/api.patch';
3-
import { queryKeys } from '@/react-query/constants';
43
import { queryOptions } from '@tanstack/react-query';
54

65
export async function getClusterInfo(clusterId: string) {
@@ -10,7 +9,7 @@ export async function getClusterInfo(clusterId: string) {
109

1110
export function getClusterInfoQueryOptions(clusterId?: string | false, refetch?: boolean | number) {
1211
return queryOptions({
13-
queryKey: [queryKeys.cluster, clusterId],
12+
queryKey: [clusterId],
1413
queryFn: () => getClusterInfo(clusterId as string),
1514
retry: false,
1615
enabled: !!clusterId,

src/features/cluster/queries/getInstanceInfoQuery.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { isLocalStudio } from '@/config/constants';
2-
import { queryKeys } from '@/react-query/constants';
32
import { queryOptions } from '@tanstack/react-query';
43
import { getClusterInfo } from './getClusterInfoQuery';
54

@@ -28,7 +27,7 @@ async function getInstanceInfo({ clusterId, instanceId }: GetInstanceInfoParams)
2827

2928
export function getInstanceInfoQueryOptions(params: GetInstanceInfoParams) {
3029
return queryOptions({
31-
queryKey: [queryKeys.cluster, params.clusterId, queryKeys.instance, params.instanceId] as const,
30+
queryKey: [params.clusterId, params.instanceId] as const,
3231
queryFn: () => getInstanceInfo(params),
3332
retry: false,
3433
});

src/features/cluster/queries/getPlanTypesQuery.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { apiClient } from '@/config/apiClient';
2-
import { queryKeys } from '@/react-query/constants';
32
import { queryOptions } from '@tanstack/react-query';
43

54
async function getPlanTypes(organizationId: string) {
@@ -13,7 +12,7 @@ async function getPlanTypes(organizationId: string) {
1312

1413
export function getPlanTypesOptions(organizationId: string) {
1514
return queryOptions({
16-
queryKey: [queryKeys.organization, organizationId, 'instancePlan'],
15+
queryKey: [organizationId, 'instancePlan'],
1716
queryFn: () => getPlanTypes(organizationId),
1817
retry: false,
1918
});

src/features/clusters/components/ClusterCard.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ import { Cluster } from '@/lib/api.patch';
2323
import { excludeFalsy } from '@/lib/arrays/excludeFalsy';
2424
import { authStore } from '@/lib/authStore';
2525
import { getOperationsUrlForCluster } from '@/lib/urls/getOperationsUrlForCluster';
26-
import { queryKeys } from '@/react-query/constants';
2726
import { useQueryClient } from '@tanstack/react-query';
2827
import { Link } from '@tanstack/react-router';
2928
import { CopyIcon, Ellipsis } from 'lucide-react';
@@ -68,6 +67,7 @@ export function ClusterCard({ cluster }: { cluster: Cluster; }) {
6867
const onTerminateClick = useCallback(() => setIsTerminateClusterModalOpen(true), []);
6968

7069
const handleTerminatedCluster = useCallback(() => {
70+
const organizationId = cluster.organizationId;
7171
terminateCluster(cluster.id, {
7272
onSuccess: () => {
7373
toast.success('Success', {
@@ -81,7 +81,7 @@ export function ClusterCard({ cluster }: { cluster: Cluster; }) {
8181
},
8282
});
8383
void queryClient.invalidateQueries({
84-
queryKey: [queryKeys.organization],
84+
queryKey: [organizationId],
8585
refetchType: 'active',
8686
});
8787
setIsTerminateClusterModalOpen(false);

src/features/clusters/queries/getRegionLocationsQuery.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { apiClient } from '@/config/apiClient';
2-
import { queryKeys } from '@/react-query/constants';
32

43
export interface GetRegionLocationsParams {
54
organizationId?: string;
@@ -18,7 +17,7 @@ async function getRegionLocations({ organizationId, availableHosts }: GetRegionL
1817

1918
export function getRegionLocationsOptions({ organizationId, availableHosts }: GetRegionLocationsParams = {}) {
2019
return {
21-
queryKey: [queryKeys.cluster, 'regionLocations', organizationId, availableHosts],
20+
queryKey: [organizationId, 'regionLocations', availableHosts],
2221
queryFn: () => getRegionLocations({ organizationId, availableHosts }),
2322
retry: false,
2423
};

src/features/clusters/upsert/ClusterForm.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ import { groupThenKeyBy } from '@/lib/groupThenKeyBy';
1818
import { collapseKebabsToMaxLength } from '@/lib/string/collapseKebabsToMaxLength';
1919
import { stringsShareAPrefix } from '@/lib/string/stringsShareAPrefix';
2020
import { toKebabCase } from '@/lib/string/to-kebab-case';
21-
import { queryKeys } from '@/react-query/constants';
2221
import { zodResolver } from '@hookform/resolvers/zod';
2322
import { useQueryClient } from '@tanstack/react-query';
2423
import { useNavigate, useRouter } from '@tanstack/react-router';
@@ -280,9 +279,9 @@ export function ClusterForm({
280279
isSelfManaged: boolean;
281280
toastId: string | number;
282281
}) => {
283-
void queryClient.invalidateQueries({ queryKey: [queryKeys.organization], refetchType: 'active' });
282+
void queryClient.invalidateQueries({ queryKey: [organizationId], refetchType: 'active' });
284283
if (!creating) {
285-
void queryClient.invalidateQueries({ queryKey: [queryKeys.cluster, clusterId], refetchType: 'active' });
284+
void queryClient.invalidateQueries({ queryKey: [clusterId], refetchType: 'active' });
286285
}
287286

288287
void router.invalidate();

src/features/instance/databases/DatabaseTableView.tsx renamed to src/features/instance/databases/components/DatabaseTableView.tsx

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,6 @@ import {
66
DropdownMenuTrigger,
77
} from '@/components/ui/dropdownMenu';
88
import { useInstanceClientIdParams } from '@/config/useInstanceClient';
9-
import { ColumnFiltersSchema } from '@/features/instance/databases/components/ColumnFilters';
10-
import { PickColumnsDropdown } from '@/features/instance/databases/components/PickColumnsDropdown';
11-
import { TableView } from '@/features/instance/databases/components/TableView';
129
import { formatBrowseDataTableHeader } from '@/features/instance/databases/functions/formatBrowseDataTableHeader';
1310
import { AddTableRowModal } from '@/features/instance/databases/modals/AddTableRowModal';
1411
import { DeleteDatabaseModal } from '@/features/instance/databases/modals/DeleteDatabaseModal';
@@ -36,7 +33,7 @@ import { useSetWatchedValue } from '@/lib/events/watcher';
3633
import { keyBy } from '@/lib/keyBy';
3734
import { zodResolver } from '@hookform/resolvers/zod';
3835
import { useQuery, useSuspenseQuery } from '@tanstack/react-query';
39-
import { useLoaderData, useNavigate, useParams } from '@tanstack/react-router';
36+
import { useNavigate, useParams } from '@tanstack/react-router';
4037
import { Row, VisibilityState } from '@tanstack/react-table';
4138
import {
4239
EllipsisIcon,
@@ -52,8 +49,11 @@ import {
5249
import { useCallback, useEffect, useMemo, useState } from 'react';
5350
import { useForm } from 'react-hook-form';
5451
import { toast } from 'sonner';
52+
import { ColumnFiltersSchema } from './ColumnFilters';
53+
import { PickColumnsDropdown } from './PickColumnsDropdown';
54+
import { TableView } from './TableView';
5555

56-
export function DatabaseTableView() {
56+
export function DatabaseTableView({ instanceDatabaseMap }: { instanceDatabaseMap: InstanceDatabaseMap }) {
5757
const allParams: {
5858
clusterId?: string;
5959
instanceId?: string;
@@ -81,7 +81,6 @@ export function DatabaseTableView() {
8181
const [selectedIds, setSelectedIds] = useEffectedState<null | unknown[]>(null, allParams);
8282
const [isEditModalOpen, setIsEditModalOpen] = useState(false);
8383

84-
const instanceDatabaseMap = useLoaderData({ strict: false }) as InstanceDatabaseMap;
8584
const isLastTableInDatabase = useMemo(() => {
8685
const tableNames = databaseName ? Object.keys(instanceDatabaseMap[databaseName] || []).sort() : [];
8786
return tableNames?.length === 1;

0 commit comments

Comments
 (0)