mirror of https://github.com/buster-so/buster.git
payment required bug fix
This commit is contained in:
parent
d67ccc27ab
commit
5212289ec5
|
@ -25,7 +25,7 @@ import { useBusterAssetsContextSelector } from '@/context/Assets/BusterAssetsPro
|
|||
import { create } from 'mutative';
|
||||
import type { BusterCollection } from '@/api/asset_interfaces/collection';
|
||||
import { RustApiError } from '../errors';
|
||||
import { isQueryStale } from '@/lib';
|
||||
import { hasOrganizationId, isQueryStale } from '@/lib';
|
||||
|
||||
export const useGetCollectionsList = (
|
||||
filters: Omit<Parameters<typeof collectionsGetList>[0], 'page_token' | 'page_size'>,
|
||||
|
@ -51,7 +51,7 @@ export const prefetchGetCollectionsList = async (
|
|||
) => {
|
||||
const options = collectionQueryKeys.collectionsGetList(params);
|
||||
const isStale = isQueryStale(options, queryClient);
|
||||
if (!isStale) return queryClient;
|
||||
if (!isStale || !hasOrganizationId(queryClient)) return queryClient;
|
||||
|
||||
const lastQueryKey = options.queryKey[options.queryKey.length - 1];
|
||||
const compiledParams = lastQueryKey as Parameters<typeof collectionsGetList>[0];
|
||||
|
|
|
@ -43,7 +43,7 @@ import { useGetLatestMetricVersionMemoized } from '../metrics';
|
|||
import { useBusterAssetsContextSelector } from '@/context/Assets/BusterAssetsProvider';
|
||||
import last from 'lodash/last';
|
||||
import { createDashboardFullConfirmModal } from './confirmModals';
|
||||
import { isQueryStale } from '@/lib';
|
||||
import { hasOrganizationId, isQueryStale } from '@/lib';
|
||||
|
||||
export const useGetDashboard = <TData = BusterDashboardResponse>(
|
||||
{
|
||||
|
@ -751,7 +751,7 @@ export const prefetchGetDashboardsList = async (
|
|||
) => {
|
||||
const options = dashboardQueryKeys.dashboardGetList(params);
|
||||
const isStale = isQueryStale(options, queryClient);
|
||||
if (!isStale) return queryClient;
|
||||
if (!isStale || !hasOrganizationId(queryClient)) return queryClient;
|
||||
|
||||
const lastQueryKey = options.queryKey[options.queryKey.length - 1];
|
||||
const compiledParams = lastQueryKey as Parameters<typeof dashboardsGetList>[0];
|
||||
|
|
|
@ -4,7 +4,8 @@ import { QueryClient, useQuery, UseQueryOptions } from '@tanstack/react-query';
|
|||
import { useMemoizedFn } from '@/hooks';
|
||||
import { metricsQueryKeys } from '@/api/query_keys/metric';
|
||||
import { RustApiError } from '../errors';
|
||||
import { isQueryStale } from '@/lib';
|
||||
import { hasOrganizationId, isQueryStale } from '@/lib';
|
||||
import { useUserConfigContextSelector } from '@/context/Users';
|
||||
|
||||
export const useGetMetricsList = (
|
||||
params: Omit<Parameters<typeof listMetrics>[0], 'page_token' | 'page_size'>,
|
||||
|
@ -13,17 +14,18 @@ export const useGetMetricsList = (
|
|||
'queryKey' | 'queryFn' | 'initialData'
|
||||
>
|
||||
) => {
|
||||
const organizationId = useUserConfigContextSelector((state) => state.userOrganizations?.id);
|
||||
const compiledParams: Parameters<typeof listMetrics>[0] = useMemo(
|
||||
() => ({ status: [], ...params, page_token: 0, page_size: 3500 }),
|
||||
[params]
|
||||
);
|
||||
|
||||
const queryFn = useMemoizedFn(() => listMetrics(compiledParams));
|
||||
|
||||
return useQuery({
|
||||
...metricsQueryKeys.metricsGetList(compiledParams),
|
||||
queryFn,
|
||||
select: options?.select,
|
||||
enabled: !!organizationId,
|
||||
...options
|
||||
});
|
||||
};
|
||||
|
@ -34,7 +36,7 @@ export const prefetchGetMetricsList = async (
|
|||
) => {
|
||||
const options = metricsQueryKeys.metricsGetList(params);
|
||||
const isStale = isQueryStale(options, queryClient);
|
||||
if (!isStale) return queryClient;
|
||||
if (!isStale || !hasOrganizationId(queryClient)) return queryClient;
|
||||
|
||||
const lastQueryKey = options.queryKey[options.queryKey.length - 1];
|
||||
const compiledParams = lastQueryKey as Parameters<typeof listMetrics>[0];
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
export * from './requests';
|
||||
export * from './queryRequests';
|
||||
export * from './permissions';
|
||||
export * from './queryRequestFavorites';
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
import { useMemoizedFn } from '@/hooks/useMemoizedFn';
|
||||
import {
|
||||
createUserFavorite,
|
||||
deleteUserFavorite,
|
||||
getUserFavorites,
|
||||
getUserFavorites_server,
|
||||
updateUserFavorites
|
||||
} from './requests';
|
||||
import { QueryClient, useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
|
||||
import { queryKeys } from '@/api/query_keys';
|
||||
import { useUserConfigContextSelector } from '@/context/Users';
|
||||
|
||||
export const useGetUserFavorites = () => {
|
||||
const queryFn = useMemoizedFn(async () => getUserFavorites());
|
||||
const organizationId = useUserConfigContextSelector((state) => state.userOrganizations?.id);
|
||||
return useQuery({
|
||||
...queryKeys.favoritesGetList,
|
||||
queryFn,
|
||||
enabled: !!organizationId
|
||||
});
|
||||
};
|
||||
|
||||
export const prefetchGetUserFavorites = async (queryClientProp?: QueryClient) => {
|
||||
const queryClient = queryClientProp || new QueryClient();
|
||||
await queryClient.prefetchQuery({
|
||||
...queryKeys.favoritesGetList,
|
||||
queryFn: () => getUserFavorites_server()
|
||||
});
|
||||
return queryClient;
|
||||
};
|
||||
|
||||
export const useAddUserFavorite = () => {
|
||||
const queryClient = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: createUserFavorite,
|
||||
onMutate: (params) => {
|
||||
queryClient.setQueryData(queryKeys.favoritesGetList.queryKey, (prev) => {
|
||||
const prevIds = prev?.map((p) => p.id) || [];
|
||||
const dedupedAdd = params.filter((p) => !prevIds.includes(p.id));
|
||||
return [...dedupedAdd, ...(prev || [])];
|
||||
});
|
||||
},
|
||||
onSuccess: (data) => {
|
||||
queryClient.setQueryData(queryKeys.favoritesGetList.queryKey, data);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export const useDeleteUserFavorite = () => {
|
||||
const queryClient = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: deleteUserFavorite,
|
||||
onMutate: (id) => {
|
||||
queryClient.setQueryData(queryKeys.favoritesGetList.queryKey, (prev) => {
|
||||
return prev?.filter((fav) => !id.includes(fav.id));
|
||||
});
|
||||
},
|
||||
onSuccess: (data) => {
|
||||
queryClient.setQueryData(queryKeys.favoritesGetList.queryKey, data);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export const useUpdateUserFavorites = () => {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation({
|
||||
mutationFn: updateUserFavorites,
|
||||
onMutate: (params) => {
|
||||
queryClient.setQueryData(queryKeys.favoritesGetList.queryKey, (prev) => {
|
||||
return prev?.filter((fav, index) => {
|
||||
const id = fav.id;
|
||||
const favorite = (prev || []).find((f) => f.id === id)!;
|
||||
return { ...favorite, index };
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
|
@ -33,11 +33,9 @@ export const prefetchGetMyUserInfo = async (
|
|||
queryClientProp?: QueryClient
|
||||
) => {
|
||||
const queryClient = queryClientProp || new QueryClient();
|
||||
const initialData = await getMyUserInfo_server(params);
|
||||
await queryClient.prefetchQuery({
|
||||
...queryKeys.userGetUserMyself,
|
||||
queryFn: () => initialData!,
|
||||
initialData
|
||||
queryFn: () => getMyUserInfo_server(params)
|
||||
});
|
||||
return queryClient;
|
||||
};
|
||||
|
@ -78,72 +76,6 @@ export const prefetchGetUser = async (userId: string, queryClientProp?: QueryCli
|
|||
return queryClient;
|
||||
};
|
||||
|
||||
export const useGetUserFavorites = () => {
|
||||
const queryFn = useMemoizedFn(async () => getUserFavorites());
|
||||
return useQuery({
|
||||
...queryKeys.favoritesGetList,
|
||||
queryFn
|
||||
});
|
||||
};
|
||||
|
||||
export const prefetchGetUserFavorites = async (queryClientProp?: QueryClient) => {
|
||||
const queryClient = queryClientProp || new QueryClient();
|
||||
await queryClient.prefetchQuery({
|
||||
...queryKeys.favoritesGetList,
|
||||
queryFn: () => getUserFavorites_server()
|
||||
});
|
||||
return queryClient;
|
||||
};
|
||||
|
||||
export const useAddUserFavorite = () => {
|
||||
const queryClient = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: createUserFavorite,
|
||||
onMutate: (params) => {
|
||||
queryClient.setQueryData(queryKeys.favoritesGetList.queryKey, (prev) => {
|
||||
const prevIds = prev?.map((p) => p.id) || [];
|
||||
const dedupedAdd = params.filter((p) => !prevIds.includes(p.id));
|
||||
return [...dedupedAdd, ...(prev || [])];
|
||||
});
|
||||
},
|
||||
onSuccess: (data) => {
|
||||
queryClient.setQueryData(queryKeys.favoritesGetList.queryKey, data);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export const useDeleteUserFavorite = () => {
|
||||
const queryClient = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: deleteUserFavorite,
|
||||
onMutate: (id) => {
|
||||
queryClient.setQueryData(queryKeys.favoritesGetList.queryKey, (prev) => {
|
||||
return prev?.filter((fav) => !id.includes(fav.id));
|
||||
});
|
||||
},
|
||||
onSuccess: (data) => {
|
||||
queryClient.setQueryData(queryKeys.favoritesGetList.queryKey, data);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export const useUpdateUserFavorites = () => {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation({
|
||||
mutationFn: updateUserFavorites,
|
||||
onMutate: (params) => {
|
||||
queryClient.setQueryData(queryKeys.favoritesGetList.queryKey, (prev) => {
|
||||
return prev?.filter((fav, index) => {
|
||||
const id = fav.id;
|
||||
const favorite = (prev || []).find((f) => f.id === id)!;
|
||||
return { ...favorite, index };
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export const useGetUserList = (params: Parameters<typeof getUserList>[0]) => {
|
||||
const queryFn = useMemoizedFn(() => getUserList(params));
|
||||
|
||||
|
|
|
@ -17,17 +17,12 @@ export const getMyUserInfo_server = async ({
|
|||
jwtToken
|
||||
}: {
|
||||
jwtToken: string | undefined;
|
||||
}): Promise<BusterUserResponse | undefined> => {
|
||||
}): Promise<BusterUserResponse | null> => {
|
||||
if (!jwtToken) {
|
||||
try {
|
||||
//If Anonymous user, it will fail, so we catch the error and return undefined
|
||||
const res = await serverFetch<BusterUserResponse>(`/users`, {
|
||||
method: 'GET'
|
||||
});
|
||||
return res;
|
||||
} catch (error) {
|
||||
return undefined;
|
||||
}
|
||||
//If Anonymous user, it will fail, so we catch the error and return undefined
|
||||
return await serverFetch<BusterUserResponse>(`/users`, {
|
||||
method: 'GET'
|
||||
});
|
||||
}
|
||||
|
||||
//use fetch instead of serverFetch because...
|
||||
|
@ -37,16 +32,17 @@ export const getMyUserInfo_server = async ({
|
|||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${jwtToken}`
|
||||
}
|
||||
})
|
||||
.then((response) => {
|
||||
if (!response.ok) {
|
||||
return undefined;
|
||||
}
|
||||
return response.json();
|
||||
})
|
||||
.catch((error) => {
|
||||
return undefined;
|
||||
});
|
||||
}).then(async (response) => {
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => null);
|
||||
throw {
|
||||
status: response.status,
|
||||
statusText: response.statusText,
|
||||
...errorData
|
||||
};
|
||||
}
|
||||
return response.json();
|
||||
});
|
||||
};
|
||||
|
||||
export const getUser = async ({ userId }: { userId: string }) => {
|
||||
|
|
|
@ -19,7 +19,7 @@ const favoritesGetList = queryOptions<BusterUserFavorite[]>({
|
|||
initialDataUpdatedAt: 0
|
||||
});
|
||||
|
||||
const userGetUserMyself = queryOptions<BusterUserResponse>({
|
||||
const userGetUserMyself = queryOptions<BusterUserResponse | null>({
|
||||
queryKey: ['myself'] as const,
|
||||
staleTime: 1000 * 60 * 60 // 1 hour
|
||||
});
|
||||
|
|
|
@ -10,6 +10,9 @@ import { AppProviders } from '@/context/AppProviders';
|
|||
import { headers } from 'next/headers';
|
||||
import { queryKeys } from '@/api/query_keys';
|
||||
|
||||
const newUserRoute = createBusterRoute({ route: BusterRoutes.NEW_USER });
|
||||
const loginRoute = createBusterRoute({ route: BusterRoutes.AUTH_LOGIN });
|
||||
|
||||
export default async function Layout({
|
||||
children
|
||||
}: Readonly<{
|
||||
|
@ -32,8 +35,6 @@ export default async function Layout({
|
|||
}
|
||||
|
||||
const userInfo = queryClient.getQueryData(queryKeys.userGetUserMyself.queryKey);
|
||||
const newUserRoute = createBusterRoute({ route: BusterRoutes.NEW_USER });
|
||||
const loginRoute = createBusterRoute({ route: BusterRoutes.AUTH_LOGIN });
|
||||
|
||||
if (
|
||||
(supabaseContext.user?.is_anonymous && pathname !== loginRoute) ||
|
||||
|
|
|
@ -13,6 +13,7 @@ import { useSupabaseContext } from '../../Supabase';
|
|||
import { createContext, useContextSelector } from 'use-context-selector';
|
||||
import { SupabaseContextReturnType } from '../../Supabase';
|
||||
import { useBusterNotifications } from '@/context/BusterNotifications';
|
||||
import { useUserConfigContextSelector } from '@/context/Users';
|
||||
|
||||
const BUSTER_WS_URL = `${process.env.NEXT_PUBLIC_WEB_SOCKET_URL}/api/v1/ws`;
|
||||
|
||||
|
@ -36,11 +37,13 @@ interface BusterSocket {
|
|||
const useBusterWebSocketHook = ({
|
||||
socketURL,
|
||||
accessToken,
|
||||
checkTokenValidity
|
||||
checkTokenValidity,
|
||||
organizationId
|
||||
}: {
|
||||
socketURL: string;
|
||||
accessToken: string | undefined;
|
||||
checkTokenValidity: SupabaseContextReturnType['checkTokenValidity'];
|
||||
organizationId: string | undefined;
|
||||
}) => {
|
||||
const { openErrorNotification } = useBusterNotifications();
|
||||
|
||||
|
@ -77,7 +80,7 @@ const useBusterWebSocketHook = ({
|
|||
const { sendJSONMessage, connectionStatus } = useWebSocket({
|
||||
url: socketURL,
|
||||
onMessage,
|
||||
canConnect: !!accessToken,
|
||||
canConnect: !!accessToken && !!organizationId,
|
||||
checkTokenValidity
|
||||
});
|
||||
|
||||
|
@ -198,11 +201,13 @@ export const BusterWebSocketProvider: React.FC<{
|
|||
}> = React.memo(({ children }) => {
|
||||
const accessToken = useSupabaseContext((state) => state.accessToken);
|
||||
const checkTokenValidity = useSupabaseContext((state) => state.checkTokenValidity);
|
||||
const organizationId = useUserConfigContextSelector((state) => state.userOrganizations?.id);
|
||||
|
||||
const busterSocketHook = useBusterWebSocketHook({
|
||||
socketURL: BUSTER_WS_URL,
|
||||
accessToken,
|
||||
checkTokenValidity
|
||||
checkTokenValidity,
|
||||
organizationId
|
||||
});
|
||||
|
||||
return <BusterWebSocket.Provider value={busterSocketHook}>{children}</BusterWebSocket.Provider>;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { RustApiError } from '@/api/buster_rest/errors';
|
||||
import { queryKeys } from '@/api/query_keys';
|
||||
import { QueryClient, queryOptions } from '@tanstack/react-query';
|
||||
|
||||
export const isQueryStale = (
|
||||
|
@ -15,3 +16,9 @@ export const isQueryStale = (
|
|||
|
||||
return isStale;
|
||||
};
|
||||
|
||||
export const hasOrganizationId = (queryClient: QueryClient): boolean => {
|
||||
const organizationId = queryClient.getQueryData(queryKeys.userGetUserMyself.queryKey)
|
||||
?.organizations?.[0]?.id;
|
||||
return !!organizationId;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue