forked from mirrors/thatmattlove-hyperglass
fixes #267: fix response caching
This commit is contained in:
parent
3b0abd5ba8
commit
b617df24d1
8 changed files with 39 additions and 28 deletions
|
|
@ -1,6 +1,7 @@
|
|||
"""API Routes."""
|
||||
|
||||
# Standard Library
|
||||
import json
|
||||
import time
|
||||
import typing as t
|
||||
from datetime import UTC, datetime
|
||||
|
|
@ -119,7 +120,10 @@ async def query(_state: HyperglassState, request: Request, data: Query) -> Query
|
|||
json_output = is_type(output, OutputDataModel)
|
||||
|
||||
if json_output:
|
||||
raw_output = output.export_dict()
|
||||
# Export structured output as JSON string to guarantee value
|
||||
# is serializable, then convert it back to a dict.
|
||||
as_json = output.export_json()
|
||||
raw_output = json.loads(as_json)
|
||||
else:
|
||||
raw_output = str(output)
|
||||
|
||||
|
|
@ -138,8 +142,6 @@ async def query(_state: HyperglassState, request: Request, data: Query) -> Query
|
|||
response_format = "text/plain"
|
||||
|
||||
if json_output:
|
||||
if cache_response.get("level") != "success":
|
||||
cache.delete(cache_key)
|
||||
response_format = "application/json"
|
||||
_log.info("Execution completed")
|
||||
|
||||
|
|
|
|||
|
|
@ -144,7 +144,7 @@ export const Title = (props: FlexProps): JSX.Element => {
|
|||
variant="link"
|
||||
flexWrap="wrap"
|
||||
flexDir="column"
|
||||
onClick={() => reset()}
|
||||
onClick={async () => await reset()}
|
||||
_focus={{ boxShadow: 'none' }}
|
||||
_hover={{ textDecoration: 'none' }}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import { useCallback, useRef } from 'react';
|
||||
import { Flex } from '@chakra-ui/react';
|
||||
import { useCallback, useRef } from 'react';
|
||||
import { isSafari } from 'react-device-detect';
|
||||
import { If, Then } from 'react-if';
|
||||
import { Debugger, Greeting, Footer, Header, ResetButton } from '~/components';
|
||||
import { Debugger, Footer, Greeting, Header, ResetButton } from '~/components';
|
||||
import { useConfig } from '~/context';
|
||||
import { motionChakra } from '~/elements';
|
||||
import { useFormState } from '~/hooks';
|
||||
|
|
@ -31,7 +31,7 @@ export const Layout = (props: FlexProps): JSX.Element => {
|
|||
|
||||
const containerRef = useRef<HTMLDivElement>({} as HTMLDivElement);
|
||||
|
||||
function handleReset(): void {
|
||||
async function handleReset() {
|
||||
containerRef.current.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
||||
setStatus('form');
|
||||
reset();
|
||||
|
|
|
|||
|
|
@ -40,7 +40,9 @@ export const Path = (props: PathProps): JSX.Element => {
|
|||
<ModalHeader>{`Path to ${displayTarget}`}</ModalHeader>
|
||||
<ModalCloseButton />
|
||||
<ModalBody>
|
||||
{response !== null ? <Chart data={output} /> : <Skeleton w="500px" h="300px" />}
|
||||
<Skeleton isLoaded={response != null}>
|
||||
<Chart data={output} />
|
||||
</Skeleton>
|
||||
</ModalBody>
|
||||
</ModalContent>
|
||||
</Modal>
|
||||
|
|
|
|||
|
|
@ -1,23 +1,23 @@
|
|||
import { forwardRef } from 'react';
|
||||
import {
|
||||
Modal,
|
||||
Popover,
|
||||
ModalBody,
|
||||
IconButton,
|
||||
PopoverBody,
|
||||
ModalOverlay,
|
||||
ModalContent,
|
||||
PopoverArrow,
|
||||
PopoverTrigger,
|
||||
PopoverContent,
|
||||
Modal,
|
||||
ModalBody,
|
||||
ModalCloseButton,
|
||||
ModalContent,
|
||||
ModalOverlay,
|
||||
Popover,
|
||||
PopoverArrow,
|
||||
PopoverBody,
|
||||
PopoverCloseButton,
|
||||
PopoverContent,
|
||||
PopoverTrigger,
|
||||
} from '@chakra-ui/react';
|
||||
import { forwardRef } from 'react';
|
||||
import { useFormContext } from 'react-hook-form';
|
||||
import { If, Then, Else } from 'react-if';
|
||||
import { Else, If, Then } from 'react-if';
|
||||
import { ResolvedTarget } from '~/components';
|
||||
import { DynamicIcon } from '~/elements';
|
||||
import { useFormState, useMobile, useColorValue } from '~/hooks';
|
||||
import { useColorValue, useFormState, useMobile } from '~/hooks';
|
||||
|
||||
import type { IconButtonProps } from '@chakra-ui/react';
|
||||
|
||||
|
|
@ -114,7 +114,7 @@ export const SubmitButton = (props: SubmitButtonProps): JSX.Element => {
|
|||
|
||||
const { reset } = useFormContext();
|
||||
|
||||
function handleClose(): void {
|
||||
async function handleClose() {
|
||||
reset();
|
||||
resetForm();
|
||||
resolvedClose();
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { createContext, useContext, useMemo } from 'react';
|
||||
import { ChakraProvider, localStorageManager } from '@chakra-ui/react';
|
||||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
||||
import { createContext, useContext, useMemo } from 'react';
|
||||
import { makeTheme } from '~/util';
|
||||
|
||||
import type { Config } from '~/types';
|
||||
|
|
@ -12,7 +12,7 @@ interface HyperglassProviderProps {
|
|||
|
||||
export const HyperglassContext = createContext<Config>({} as Config);
|
||||
|
||||
const queryClient = new QueryClient();
|
||||
export const queryClient = new QueryClient();
|
||||
|
||||
export const HyperglassProvider = (props: HyperglassProviderProps): JSX.Element => {
|
||||
const { config, children } = props;
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import plur from 'plur';
|
|||
import { useMemo } from 'react';
|
||||
import isEqual from 'react-fast-compare';
|
||||
import create from 'zustand';
|
||||
import { queryClient } from '~/context';
|
||||
import { all, andJoin, dedupObjectArray, withDev } from '~/util';
|
||||
|
||||
import type { UseFormClearErrors, UseFormSetError } from 'react-hook-form';
|
||||
|
|
@ -61,10 +62,13 @@ interface FormStateType<Opt extends SingleOption = SingleOption> {
|
|||
setSelection<
|
||||
Opt extends SingleOption,
|
||||
K extends keyof FormSelections<Opt> = keyof FormSelections<Opt>,
|
||||
>(field: K, value: FormSelections[K]): void;
|
||||
>(
|
||||
field: K,
|
||||
value: FormSelections[K],
|
||||
): void;
|
||||
setTarget(update: Partial<Target>): void;
|
||||
getDirective(): Directive | null;
|
||||
reset(): void;
|
||||
reset(): Promise<void>;
|
||||
setFormValue<K extends keyof FormValues>(field: K, value: FormValues[K]): void;
|
||||
locationChange(
|
||||
locations: string[],
|
||||
|
|
@ -198,7 +202,8 @@ const formState: StateCreator<FormStateType> = (set, get) => ({
|
|||
return null;
|
||||
},
|
||||
|
||||
reset(): void {
|
||||
async reset(): Promise<void> {
|
||||
const { form } = get();
|
||||
set({
|
||||
filtered: { types: [], groups: [] },
|
||||
form: { queryLocation: [], queryTarget: [], queryType: '' },
|
||||
|
|
@ -209,6 +214,10 @@ const formState: StateCreator<FormStateType> = (set, get) => ({
|
|||
target: { display: '' },
|
||||
resolvedIsOpen: false,
|
||||
});
|
||||
for (const queryLocation of form.queryLocation) {
|
||||
const query = { queryLocation, queryTarget: form.queryTarget, queryType: form.queryType };
|
||||
queryClient.removeQueries({ queryKey: ['/api/query', query] });
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -72,8 +72,6 @@ export function useLGQuery(
|
|||
return useQuery<QueryResponse, Response | QueryResponse | Error, QueryResponse, LGQueryKey>({
|
||||
queryKey: ['/api/query', query],
|
||||
queryFn: runQuery,
|
||||
// Invalidate react-query's cache just shy of the configured cache timeout.
|
||||
cacheTime: cache.timeout * 1000 * 0.95,
|
||||
// Don't refetch when window refocuses.
|
||||
refetchOnWindowFocus: false,
|
||||
// Don't automatically refetch query data (queries should be on-off).
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue