Przeglądaj źródła

feat(ui): add refresh functionality to layout configurations table

Added refresh buttons to both the empty state and populated table views
in LayoutConfigurationsTable component. Also implemented a page-level
refresh mechanism in LayoutConfigurationsPage using a key prop to force
re-render and refresh data. Includes loading states with spinning icons
during refresh operations.
vtugulan 6 miesięcy temu
rodzic
commit
1e0bf5e4e6

+ 31 - 2
app/components/layout-configurations/LayoutConfigurationsTable.tsx

@@ -9,7 +9,7 @@ import { Badge } from "@/components/ui/badge";
 import { Skeleton } from "@/components/ui/skeleton";
 import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger } from "@/components/ui/alert-dialog";
 import { toast } from "@/hooks/use-toast";
-import { Trash2, Eye, Edit } from "lucide-react";
+import { Trash2, Eye, Edit, RefreshCw } from "lucide-react";
 
 interface LayoutConfiguration {
   id: number;
@@ -37,6 +37,7 @@ interface LayoutSectionField {
 export function LayoutConfigurationsTable() {
   const [configurations, setConfigurations] = useState<LayoutConfiguration[]>([]);
   const [loading, setLoading] = useState(true);
+  const [isRefreshing, setIsRefreshing] = useState(false);
   const router = useRouter();
 
   useEffect(() => {
@@ -68,9 +69,15 @@ export function LayoutConfigurationsTable() {
       });
     } finally {
       setLoading(false);
+      setIsRefreshing(false);
     }
   }
 
+  async function refreshConfigurations() {
+    setIsRefreshing(true);
+    await loadConfigurations();
+  }
+
   async function handleDelete(id: number) {
     try {
       const result = await deleteLayoutConfiguration(id);
@@ -117,13 +124,35 @@ export function LayoutConfigurationsTable() {
   if (configurations.length === 0) {
     return (
       <div className="p-8 text-center">
-        <p className="text-muted-foreground">No layout configurations found</p>
+        <p className="text-muted-foreground mb-4">No layout configurations found</p>
+        <Button
+          variant="outline"
+          size="sm"
+          onClick={refreshConfigurations}
+          disabled={isRefreshing}
+          className="flex items-center gap-2 mx-auto"
+        >
+          <RefreshCw className={`h-4 w-4 ${isRefreshing ? 'animate-spin' : ''}`} />
+          {isRefreshing ? "Refreshing..." : "Refresh"}
+        </Button>
       </div>
     );
   }
 
   return (
     <div className="p-4 space-y-4">
+      <div className="flex justify-end">
+        <Button
+          variant="outline"
+          size="sm"
+          onClick={refreshConfigurations}
+          disabled={isRefreshing}
+          className="flex items-center gap-2"
+        >
+          <RefreshCw className={`h-4 w-4 ${isRefreshing ? 'animate-spin' : ''}`} />
+          {isRefreshing ? "Refreshing..." : "Refresh"}
+        </Button>
+      </div>
       {configurations.map((config) => (
         <Card key={config.id} className="hover:shadow-md transition-shadow">
           <CardHeader>

+ 24 - 3
app/layout-configurations/page.tsx

@@ -1,19 +1,40 @@
-import { Suspense } from "react";
+"use client";
+
+import { Suspense, useState, useCallback } from "react";
 import { LayoutConfigurationsTable } from "@/app/components/layout-configurations/LayoutConfigurationsTable";
 import { CreateLayoutConfigurationDialog } from "@/app/components/layout-configurations/CreateLayoutConfigurationDialog";
 import { Skeleton } from "@/components/ui/skeleton";
+import { Button } from "@/components/ui/button";
+import { RefreshCw } from "lucide-react";
 
 export default function LayoutConfigurationsPage() {
+  const [refreshKey, setRefreshKey] = useState(0);
+
+  const handleRefresh = useCallback(() => {
+    setRefreshKey(prev => prev + 1);
+  }, []);
+
   return (
     <div className="container mx-auto py-8 px-4">
       <div className="flex justify-between items-center mb-6">
         <h1 className="text-3xl font-bold">Layout Configurations</h1>
-        <CreateLayoutConfigurationDialog />
+        <div className="flex gap-2">
+          <Button
+            variant="outline"
+            size="sm"
+            onClick={handleRefresh}
+            className="flex items-center gap-2"
+          >
+            <RefreshCw className="h-4 w-4" />
+            Refresh
+          </Button>
+          <CreateLayoutConfigurationDialog />
+        </div>
       </div>
       
       <div className="bg-white rounded-lg shadow">
         <Suspense fallback={<LayoutConfigurationsSkeleton />}>
-          <LayoutConfigurationsTable />
+          <LayoutConfigurationsTable key={refreshKey} />
         </Suspense>
       </div>
     </div>