mirror of
https://github.com/coder/coder.git
synced 2026-10-16 06:37:58 +08:00
chore: reduce dashboard requests from seeded data (#13034)
* chore: reduce requests the dashboard makes from seeded data We already inject all of this content in `index.html`. There was also a bug with displaying a loading indicator when the workspace proxies endpoint 404s. * Fix first user fetch * Add util * Add cached query for entitlements and experiments * Fix authmethods unnecessary request * Fix unnecessary region request * Fix fmt * Debug * Fix test
This commit is contained in:
@@ -2,14 +2,17 @@ import type { QueryClient, UseQueryOptions } from "react-query";
|
||||
import * as API from "api/api";
|
||||
import type { AppearanceConfig } from "api/typesGenerated";
|
||||
import { getMetadataAsJSON } from "utils/metadata";
|
||||
import { cachedQuery } from "./util";
|
||||
|
||||
const initialAppearanceData = getMetadataAsJSON<AppearanceConfig>("appearance");
|
||||
const appearanceConfigKey = ["appearance"] as const;
|
||||
|
||||
export const appearance = (): UseQueryOptions<AppearanceConfig> => {
|
||||
return {
|
||||
// We either have our initial data or should immediately
|
||||
// fetch and never again!
|
||||
...cachedQuery(initialAppearanceData),
|
||||
queryKey: ["appearance"],
|
||||
initialData: initialAppearanceData,
|
||||
queryFn: () => API.getAppearance(),
|
||||
};
|
||||
};
|
||||
|
||||
@@ -2,14 +2,17 @@ import type { UseQueryOptions } from "react-query";
|
||||
import * as API from "api/api";
|
||||
import type { BuildInfoResponse } from "api/typesGenerated";
|
||||
import { getMetadataAsJSON } from "utils/metadata";
|
||||
import { cachedQuery } from "./util";
|
||||
|
||||
const initialBuildInfoData = getMetadataAsJSON<BuildInfoResponse>("build-info");
|
||||
const buildInfoKey = ["buildInfo"] as const;
|
||||
|
||||
export const buildInfo = (): UseQueryOptions<BuildInfoResponse> => {
|
||||
return {
|
||||
// We either have our initial data or should immediately
|
||||
// fetch and never again!
|
||||
...cachedQuery(initialBuildInfoData),
|
||||
queryKey: buildInfoKey,
|
||||
initialData: initialBuildInfoData,
|
||||
queryFn: () => API.getBuildInfo(),
|
||||
};
|
||||
};
|
||||
|
||||
@@ -2,15 +2,16 @@ import type { QueryClient, UseQueryOptions } from "react-query";
|
||||
import * as API from "api/api";
|
||||
import type { Entitlements } from "api/typesGenerated";
|
||||
import { getMetadataAsJSON } from "utils/metadata";
|
||||
import { cachedQuery } from "./util";
|
||||
|
||||
const initialEntitlementsData = getMetadataAsJSON<Entitlements>("entitlements");
|
||||
const ENTITLEMENTS_QUERY_KEY = ["entitlements"] as const;
|
||||
const entitlementsQueryKey = ["entitlements"] as const;
|
||||
|
||||
export const entitlements = (): UseQueryOptions<Entitlements> => {
|
||||
return {
|
||||
queryKey: ENTITLEMENTS_QUERY_KEY,
|
||||
...cachedQuery(initialEntitlementsData),
|
||||
queryKey: entitlementsQueryKey,
|
||||
queryFn: () => API.getEntitlements(),
|
||||
initialData: initialEntitlementsData,
|
||||
};
|
||||
};
|
||||
|
||||
@@ -19,7 +20,7 @@ export const refreshEntitlements = (queryClient: QueryClient) => {
|
||||
mutationFn: API.refreshEntitlements,
|
||||
onSuccess: async () => {
|
||||
await queryClient.invalidateQueries({
|
||||
queryKey: ENTITLEMENTS_QUERY_KEY,
|
||||
queryKey: entitlementsQueryKey,
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
@@ -2,14 +2,15 @@ import type { UseQueryOptions } from "react-query";
|
||||
import * as API from "api/api";
|
||||
import type { Experiments } from "api/typesGenerated";
|
||||
import { getMetadataAsJSON } from "utils/metadata";
|
||||
import { cachedQuery } from "./util";
|
||||
|
||||
const initialExperimentsData = getMetadataAsJSON<Experiments>("experiments");
|
||||
const experimentsKey = ["experiments"] as const;
|
||||
|
||||
export const experiments = (): UseQueryOptions<Experiments> => {
|
||||
return {
|
||||
...cachedQuery(initialExperimentsData),
|
||||
queryKey: experimentsKey,
|
||||
initialData: initialExperimentsData,
|
||||
queryFn: () => API.getExperiments(),
|
||||
} satisfies UseQueryOptions<Experiments>;
|
||||
};
|
||||
|
||||
@@ -19,6 +19,7 @@ import type { UsePaginatedQueryOptions } from "hooks/usePaginatedQuery";
|
||||
import { prepareQuery } from "utils/filters";
|
||||
import { getMetadataAsJSON } from "utils/metadata";
|
||||
import { getAuthorizationKey } from "./authCheck";
|
||||
import { cachedQuery } from "./util";
|
||||
|
||||
export function usersKey(req: UsersRequest) {
|
||||
return ["users", req] as const;
|
||||
@@ -112,6 +113,8 @@ export const updateRoles = (queryClient: QueryClient) => {
|
||||
};
|
||||
};
|
||||
|
||||
const initialUserData = getMetadataAsJSON<User>("user");
|
||||
|
||||
export const authMethods = () => {
|
||||
return {
|
||||
// Even the endpoint being /users/authmethods we don't want to revalidate it
|
||||
@@ -121,16 +124,14 @@ export const authMethods = () => {
|
||||
};
|
||||
};
|
||||
|
||||
const initialUserData = getMetadataAsJSON<User>("user");
|
||||
|
||||
const meKey = ["me"];
|
||||
|
||||
export const me = (): UseQueryOptions<User> & {
|
||||
queryKey: QueryKey;
|
||||
} => {
|
||||
return {
|
||||
...cachedQuery(initialUserData),
|
||||
queryKey: meKey,
|
||||
initialData: initialUserData,
|
||||
queryFn: API.getAuthenticatedUser,
|
||||
};
|
||||
};
|
||||
@@ -142,8 +143,10 @@ export function apiKey(): UseQueryOptions<GenerateAPIKeyResponse> {
|
||||
};
|
||||
}
|
||||
|
||||
export const hasFirstUser = () => {
|
||||
export const hasFirstUser = (): UseQueryOptions<boolean> => {
|
||||
return {
|
||||
// This cannot be false otherwise it will not fetch!
|
||||
...cachedQuery(typeof initialUserData !== "undefined" ? true : undefined),
|
||||
queryKey: ["hasFirstUser"],
|
||||
queryFn: API.hasFirstUser,
|
||||
};
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
import type { UseQueryOptions } from "react-query";
|
||||
|
||||
// cachedQuery allows the caller to only make a request
|
||||
// a single time, and use `initialData` if it is provided.
|
||||
//
|
||||
// This is particularly helpful for passing values injected
|
||||
// via metadata. We do this for the initial user fetch, buildinfo,
|
||||
// and a few others to reduce page load time.
|
||||
export const cachedQuery = <T>(initialData?: T): Partial<UseQueryOptions<T>> =>
|
||||
// Only do this if there is initial data,
|
||||
// otherwise it can conflict with tests.
|
||||
initialData
|
||||
? {
|
||||
cacheTime: Infinity,
|
||||
staleTime: Infinity,
|
||||
refetchOnMount: false,
|
||||
refetchOnReconnect: false,
|
||||
refetchOnWindowFocus: false,
|
||||
initialData,
|
||||
}
|
||||
: {
|
||||
initialData,
|
||||
};
|
||||
Reference in New Issue
Block a user