♻️ some refactors

This commit is contained in:
Fred KISSIE
2025-12-02 19:08:35 +01:00
parent 06a31bb716
commit c93ab34021
4 changed files with 79 additions and 267 deletions

View File

@@ -1,60 +1,23 @@
"use client";
import {
flexRender,
getCoreRowModel,
useReactTable,
getPaginationRowModel,
SortingState,
getSortedRowModel,
ColumnFiltersState,
getFilteredRowModel,
VisibilityState
} from "@tanstack/react-table";
import ConfirmDeleteDialog from "@app/components/ConfirmDeleteDialog";
import CopyToClipboard from "@app/components/CopyToClipboard";
import { DataTablePagination } from "@app/components/DataTablePagination";
import { Button } from "@app/components/ui/button";
import { Card, CardContent, CardHeader } from "@app/components/ui/card";
import { ExtendedColumnDef } from "@app/components/ui/data-table";
import {
DropdownMenu,
DropdownMenuCheckboxItem,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuCheckboxItem
DropdownMenuTrigger
} from "@app/components/ui/dropdown-menu";
import { Button } from "@app/components/ui/button";
import {
ArrowRight,
ArrowUpDown,
MoreHorizontal,
ShieldOff,
ShieldCheck,
RefreshCw,
Columns,
Plus,
Search,
ChevronDown,
Clock,
CheckCircle2,
XCircle
} from "lucide-react";
import Link from "next/link";
import { useRouter } from "next/navigation";
import { useState, useEffect, useTransition } from "react";
import ConfirmDeleteDialog from "@app/components/ConfirmDeleteDialog";
import { formatAxiosError } from "@app/lib/api";
import { toast } from "@app/hooks/useToast";
import { createApiClient } from "@app/lib/api";
import { useEnvContext } from "@app/hooks/useEnvContext";
import CopyToClipboard from "@app/components/CopyToClipboard";
import { Switch } from "@app/components/ui/switch";
import { AxiosResponse } from "axios";
import { UpdateResourceResponse } from "@server/routers/resource";
import { ListSitesResponse } from "@server/routers/site";
import { useTranslations } from "next-intl";
import { InfoPopup } from "@app/components/ui/info-popup";
import { Input } from "@app/components/ui/input";
import { DataTablePagination } from "@app/components/DataTablePagination";
import { Card, CardContent, CardHeader } from "@app/components/ui/card";
import { Switch } from "@app/components/ui/switch";
import {
Table,
TableBody,
@@ -63,6 +26,42 @@ import {
TableHeader,
TableRow
} from "@app/components/ui/table";
import { useEnvContext } from "@app/hooks/useEnvContext";
import { useStoredColumnVisibility } from "@app/hooks/useStoredColumnVisibility";
import { useStoredPageSize } from "@app/hooks/useStoredPageSize";
import { toast } from "@app/hooks/useToast";
import { createApiClient, formatAxiosError } from "@app/lib/api";
import { UpdateResourceResponse } from "@server/routers/resource";
import {
ColumnFiltersState,
flexRender,
getCoreRowModel,
getFilteredRowModel,
getPaginationRowModel,
getSortedRowModel,
SortingState,
useReactTable
} from "@tanstack/react-table";
import { AxiosResponse } from "axios";
import {
ArrowRight,
ArrowUpDown,
CheckCircle2,
ChevronDown,
Clock,
Columns,
MoreHorizontal,
Plus,
RefreshCw,
Search,
ShieldCheck,
ShieldOff,
XCircle
} from "lucide-react";
import { useTranslations } from "next-intl";
import Link from "next/link";
import { useRouter } from "next/navigation";
import { useState, useTransition } from "react";
export type TargetHealth = {
targetId: number;
@@ -153,88 +152,6 @@ type ProxyResourcesTableProps = {
};
};
const STORAGE_KEYS = {
PAGE_SIZE: "datatable-page-size",
COLUMN_VISIBILITY: "datatable-column-visibility",
getTablePageSize: (tableId?: string) =>
tableId ? `datatable-${tableId}-page-size` : STORAGE_KEYS.PAGE_SIZE,
getTableColumnVisibility: (tableId?: string) =>
tableId
? `datatable-${tableId}-column-visibility`
: STORAGE_KEYS.COLUMN_VISIBILITY
};
const getStoredPageSize = (tableId?: string, defaultSize = 20): number => {
if (typeof window === "undefined") return defaultSize;
try {
const key = STORAGE_KEYS.getTablePageSize(tableId);
const stored = localStorage.getItem(key);
if (stored) {
const parsed = parseInt(stored, 10);
if (parsed > 0 && parsed <= 1000) {
return parsed;
}
}
} catch (error) {
console.warn("Failed to read page size from localStorage:", error);
}
return defaultSize;
};
const setStoredPageSize = (pageSize: number, tableId?: string): void => {
if (typeof window === "undefined") return;
try {
const key = STORAGE_KEYS.getTablePageSize(tableId);
localStorage.setItem(key, pageSize.toString());
} catch (error) {
console.warn("Failed to save page size to localStorage:", error);
}
};
const getStoredColumnVisibility = (
tableId?: string,
defaultVisibility?: Record<string, boolean>
): Record<string, boolean> => {
if (typeof window === "undefined") return defaultVisibility || {};
try {
const key = STORAGE_KEYS.getTableColumnVisibility(tableId);
const stored = localStorage.getItem(key);
if (stored) {
const parsed = JSON.parse(stored);
// Validate that it's an object
if (typeof parsed === "object" && parsed !== null) {
return parsed;
}
}
} catch (error) {
console.warn(
"Failed to read column visibility from localStorage:",
error
);
}
return defaultVisibility || {};
};
const setStoredColumnVisibility = (
visibility: Record<string, boolean>,
tableId?: string
): void => {
if (typeof window === "undefined") return;
try {
const key = STORAGE_KEYS.getTableColumnVisibility(tableId);
localStorage.setItem(key, JSON.stringify(visibility));
} catch (error) {
console.warn(
"Failed to save column visibility to localStorage:",
error
);
}
};
export default function ProxyResourcesTable({
resources,
orgId,
@@ -247,10 +164,10 @@ export default function ProxyResourcesTable({
const api = createApiClient({ env });
const [proxyPageSize, setProxyPageSize] = useState<number>(() =>
getStoredPageSize("proxy-resources", 20)
const [proxyPageSize, setProxyPageSize] = useStoredPageSize(
"proxy-resources",
20
);
const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false);
const [selectedResource, setSelectedResource] =
useState<ResourceRow | null>();
@@ -265,10 +182,7 @@ export default function ProxyResourcesTable({
const [isRefreshing, startTransition] = useTransition();
const [proxyColumnVisibility, setProxyColumnVisibility] =
useState<VisibilityState>(() =>
getStoredColumnVisibility("proxy-resources", {})
);
useStoredColumnVisibility("proxy-resources", {});
const refreshData = () => {
try {
router.refresh();
@@ -292,8 +206,10 @@ export default function ProxyResourcesTable({
});
})
.then(() => {
router.refresh();
setIsDeleteModalOpen(false);
startTransition(() => {
router.refresh();
setIsDeleteModalOpen(false);
});
});
};
@@ -734,16 +650,6 @@ export default function ProxyResourcesTable({
}
});
const handleProxyPageSizeChange = (newPageSize: number) => {
setProxyPageSize(newPageSize);
setStoredPageSize(newPageSize, "proxy-resources");
};
// Persist column visibility changes to localStorage
useEffect(() => {
setStoredColumnVisibility(proxyColumnVisibility, "proxy-resources");
}, [proxyColumnVisibility]);
return (
<>
{selectedResource && (
@@ -913,7 +819,7 @@ export default function ProxyResourcesTable({
<div className="mt-4">
<DataTablePagination
table={proxyTable}
onPageSizeChange={handleProxyPageSizeChange}
onPageSizeChange={setProxyPageSize}
/>
</div>
</CardContent>