Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bbebf494bb | ||
|
|
d9873355b7 | ||
|
|
bac28d9e1c |
@@ -2,10 +2,10 @@
|
|||||||
|
|
||||||
import type { MutableRefObject, ReactNode } from "react";
|
import type { MutableRefObject, ReactNode } from "react";
|
||||||
import { useCallback, useEffect, useMemo, useState } from "react";
|
import { useCallback, useEffect, useMemo, useState } from "react";
|
||||||
import { Group, Menu, Switch, Text } from "@mantine/core";
|
import { Group, Loader, Menu, Switch, Text } from "@mantine/core";
|
||||||
import { IconCopy, IconLayoutKanban, IconRefresh, IconSettings, IconTrash } from "@tabler/icons-react";
|
import { IconCopy, IconLayoutKanban, IconRefresh, IconSettings, IconTrash } from "@tabler/icons-react";
|
||||||
import type { QueryClient } from "@tanstack/react-query";
|
import type { QueryClient } from "@tanstack/react-query";
|
||||||
import { useQueryClient } from "@tanstack/react-query";
|
import { useIsFetching, useQueryClient } from "@tanstack/react-query";
|
||||||
|
|
||||||
import { clientApi } from "@homarr/api/client";
|
import { clientApi } from "@homarr/api/client";
|
||||||
import { useSession } from "@homarr/auth/client";
|
import { useSession } from "@homarr/auth/client";
|
||||||
@@ -50,8 +50,9 @@ export const WidgetContextMenu = ({ item, widgetStateRef, children }: WidgetCont
|
|||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
const widgetQueryKey = useMemo(() => [["widget", item.kind]], [item.kind]);
|
const widgetQueryKey = useMemo(() => [["widget", item.kind]], [item.kind]);
|
||||||
|
const isWidgetFetching = useIsFetching({ queryKey: widgetQueryKey }) > 0;
|
||||||
const handleRefetch = useCallback(() => {
|
const handleRefetch = useCallback(() => {
|
||||||
void queryClient.invalidateQueries({ queryKey: widgetQueryKey });
|
void queryClient.refetchQueries({ queryKey: widgetQueryKey, type: "all" });
|
||||||
}, [queryClient, widgetQueryKey]);
|
}, [queryClient, widgetQueryKey]);
|
||||||
|
|
||||||
const options = useMemo(
|
const options = useMemo(
|
||||||
@@ -223,11 +224,15 @@ export const WidgetContextMenu = ({ item, widgetStateRef, children }: WidgetCont
|
|||||||
|
|
||||||
<>
|
<>
|
||||||
{(toggleOptions.length > 0 || visibleWidgetActions.length > 0 || isEditMode) && <Menu.Divider />}
|
{(toggleOptions.length > 0 || visibleWidgetActions.length > 0 || isEditMode) && <Menu.Divider />}
|
||||||
<Menu.Item closeMenuOnClick leftSection={<IconRefresh size={16} />} onClick={handleRefetch}>
|
<Menu.Item
|
||||||
|
leftSection={isWidgetFetching ? <Loader size={16} /> : <IconRefresh size={16} />}
|
||||||
|
onClick={handleRefetch}
|
||||||
|
disabled={isWidgetFetching}
|
||||||
|
>
|
||||||
<Group justify="space-between" wrap="nowrap">
|
<Group justify="space-between" wrap="nowrap">
|
||||||
{tMenu("refresh")}
|
{tMenu("refresh")}
|
||||||
<Text size="xs" c="dimmed">
|
<Text size="xs" c="dimmed">
|
||||||
<WidgetCacheAge queryClient={queryClient} queryKey={widgetQueryKey} />
|
<WidgetCacheAge queryClient={queryClient} queryKey={widgetQueryKey} isFetching={isWidgetFetching} />
|
||||||
</Text>
|
</Text>
|
||||||
</Group>
|
</Group>
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
@@ -265,13 +270,24 @@ export const WidgetContextMenu = ({ item, widgetStateRef, children }: WidgetCont
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const WidgetCacheAge = ({ queryClient, queryKey }: { queryClient: QueryClient; queryKey: unknown[] }) => {
|
const WidgetCacheAge = ({
|
||||||
|
queryClient,
|
||||||
|
queryKey,
|
||||||
|
isFetching,
|
||||||
|
}: {
|
||||||
|
queryClient: QueryClient;
|
||||||
|
queryKey: unknown[];
|
||||||
|
isFetching: boolean;
|
||||||
|
}) => {
|
||||||
|
// 1s tick for "just now" → "1s ago" label transition; isFetching prop handles refetch reactivity
|
||||||
const [, setTick] = useState(0);
|
const [, setTick] = useState(0);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const id = setInterval(() => setTick((n) => n + 1), 1000);
|
const id = setInterval(() => setTick((n) => n + 1), 1000);
|
||||||
return () => clearInterval(id);
|
return () => clearInterval(id);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
if (isFetching) return <Loader size={12} />;
|
||||||
|
|
||||||
const timestamps = queryClient
|
const timestamps = queryClient
|
||||||
.getQueryCache()
|
.getQueryCache()
|
||||||
.findAll({ queryKey })
|
.findAll({ queryKey })
|
||||||
|
|||||||
Reference in new issue
Block a user