From 5a7ca5b542f873b76c84fc1aa0516e9d93722c54 Mon Sep 17 00:00:00 2001 From: miloschwartz Date: Wed, 1 Jul 2026 12:38:45 -0400 Subject: [PATCH] add refresh button --- messages/en-US.json | 1 + .../LauncherRefreshButton.tsx | 31 +++++++++++++++ .../resource-launcher/LauncherViewTabs.tsx | 15 +++++++- .../resource-launcher/ResourceLauncher.tsx | 38 ++++++++++++++++++- 4 files changed, 81 insertions(+), 4 deletions(-) create mode 100644 src/components/resource-launcher/LauncherRefreshButton.tsx diff --git a/messages/en-US.json b/messages/en-US.json index 3663c8c59..2c938639a 100644 --- a/messages/en-US.json +++ b/messages/en-US.json @@ -3551,6 +3551,7 @@ "resourceLauncherDefaultView": "Default", "resourceLauncherSaveView": "Save View", "resourceLauncherSaveToCurrentView": "Save to Current View", + "resourceLauncherResetView": "Reset View", "resourceLauncherSaveAsNewView": "Save as New View", "resourceLauncherSaveAsNewViewDescription": "Give this view a name to save your current filters and layout.", "resourceLauncherSaveForEveryone": "Save for Everyone", diff --git a/src/components/resource-launcher/LauncherRefreshButton.tsx b/src/components/resource-launcher/LauncherRefreshButton.tsx new file mode 100644 index 000000000..854128736 --- /dev/null +++ b/src/components/resource-launcher/LauncherRefreshButton.tsx @@ -0,0 +1,31 @@ +"use client"; + +import { Button } from "@app/components/ui/button"; +import { useTranslations } from "next-intl"; +import { RefreshCw } from "lucide-react"; + +type LauncherRefreshButtonProps = { + onRefresh: () => void; + isRefreshing: boolean; +}; + +export function LauncherRefreshButton({ + onRefresh, + isRefreshing +}: LauncherRefreshButtonProps) { + const t = useTranslations(); + + return ( + + ); +} diff --git a/src/components/resource-launcher/LauncherViewTabs.tsx b/src/components/resource-launcher/LauncherViewTabs.tsx index 474d04e67..e23aaf0b4 100644 --- a/src/components/resource-launcher/LauncherViewTabs.tsx +++ b/src/components/resource-launcher/LauncherViewTabs.tsx @@ -5,6 +5,7 @@ import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, + DropdownMenuSeparator, DropdownMenuTrigger } from "@app/components/ui/dropdown-menu"; import { useTranslations } from "next-intl"; @@ -71,6 +72,7 @@ type LauncherSaveViewMenuProps = { onSaveAsNew: () => void; onSaveForEveryone: () => void; onMakePersonal: () => void; + onResetView: () => void; }; export function LauncherSaveViewMenu({ @@ -81,7 +83,8 @@ export function LauncherSaveViewMenu({ onSaveToCurrent, onSaveAsNew, onSaveForEveryone, - onMakePersonal + onMakePersonal, + onResetView }: LauncherSaveViewMenuProps) { const t = useTranslations(); @@ -97,7 +100,15 @@ export function LauncherSaveViewMenu({ - {!isDefaultView ? ( + {hasUnsavedChanges ? ( + <> + + {t("resourceLauncherResetView")} + + + + ) : null} + {!isDefaultView && (isAdmin || !isOrgWideView) ? ( {t("resourceLauncherSaveToCurrentView")} diff --git a/src/components/resource-launcher/ResourceLauncher.tsx b/src/components/resource-launcher/ResourceLauncher.tsx index 979d67b54..7b0628d07 100644 --- a/src/components/resource-launcher/ResourceLauncher.tsx +++ b/src/components/resource-launcher/ResourceLauncher.tsx @@ -39,12 +39,20 @@ import { useMutation } from "@tanstack/react-query"; import { Search } from "lucide-react"; import { useTranslations } from "next-intl"; import { useRouter } from "next/navigation"; -import { useCallback, useEffect, useMemo, useRef, useState } from "react"; +import { + useCallback, + useEffect, + useMemo, + useRef, + useState, + useTransition +} from "react"; import { useDebouncedCallback } from "use-debounce"; import type { Selectedsite } from "@app/components/site-selector"; import type { SelectedLabel } from "@app/components/labels-selector"; import { LauncherFilterPopover } from "./LauncherFilterPopover"; import { LauncherGroupList } from "./LauncherGroupList"; +import { LauncherRefreshButton } from "./LauncherRefreshButton"; import { LauncherSettingsMenu } from "./LauncherSettingsMenu"; import { LauncherSortButton } from "./LauncherSortButton"; import { LauncherSaveViewMenu, LauncherViewTabs } from "./LauncherViewTabs"; @@ -83,6 +91,7 @@ export default function ResourceLauncher({ const api = createApiClient({ env }); const router = useRouter(); const { navigate, isNavigating, searchParams } = useNavigationContext(); + const [isRefreshing, startRefreshTransition] = useTransition(); const hasRestoredLastView = useRef(false); const [searchInputResetKey, setSearchInputResetKey] = useState(0); @@ -312,8 +321,28 @@ export default function ResourceLauncher({ }); }, [navigateToConfig]); + const handleResetView = useCallback(() => { + searchInputRef.current = savedConfig.query; + setSearchInputResetKey((key) => key + 1); + navigateToConfig(activeViewIdRef.current, savedConfig); + }, [navigateToConfig, savedConfig]); + + const refreshData = () => { + startRefreshTransition(async () => { + try { + router.refresh(); + } catch { + toast({ + title: t("error"), + description: t("refreshError"), + variant: "destructive" + }); + } + }); + }; + const handleSaveToCurrent = () => { - if (isDefaultView) { + if (isDefaultView || (isOrgWideView && !isAdmin)) { return; } updateViewMutation.mutate({ @@ -408,6 +437,7 @@ export default function ResourceLauncher({ onSaveAsNew={handleSaveAsNew} onSaveForEveryone={handleSaveForEveryone} onMakePersonal={handleMakePersonal} + onResetView={handleResetView} /> +