mirror of
https://github.com/fosrl/pangolin.git
synced 2025-08-01 08:34:53 +02:00
add refresh sites button
This commit is contained in:
parent
073c318f12
commit
809a135721
5 changed files with 61 additions and 11 deletions
|
@ -776,6 +776,8 @@
|
|||
"orgPoliciesAdd": "Add Organization Policy",
|
||||
"orgRequired": "Organization is required",
|
||||
"error": "Error",
|
||||
"refreshError": "Failed to refresh data",
|
||||
"refresh": "Refresh",
|
||||
"success": "Success",
|
||||
"orgPolicyAddedDescription": "Policy added successfully",
|
||||
"orgPolicyUpdatedDescription": "Policy updated successfully",
|
||||
|
|
|
@ -8,12 +8,16 @@ interface DataTableProps<TData, TValue> {
|
|||
columns: ColumnDef<TData, TValue>[];
|
||||
data: TData[];
|
||||
createSite?: () => void;
|
||||
onRefresh?: () => void;
|
||||
isRefreshing?: boolean;
|
||||
}
|
||||
|
||||
export function SitesDataTable<TData, TValue>({
|
||||
columns,
|
||||
data,
|
||||
createSite
|
||||
createSite,
|
||||
onRefresh,
|
||||
isRefreshing
|
||||
}: DataTableProps<TData, TValue>) {
|
||||
|
||||
const t = useTranslations();
|
||||
|
@ -27,6 +31,8 @@ export function SitesDataTable<TData, TValue>({
|
|||
searchColumn="name"
|
||||
onAdd={createSite}
|
||||
addButtonText={t('siteAdd')}
|
||||
onRefresh={onRefresh}
|
||||
isRefreshing={isRefreshing}
|
||||
defaultSort={{
|
||||
id: "name",
|
||||
desc: false
|
||||
|
|
|
@ -19,7 +19,7 @@ import {
|
|||
import Link from "next/link";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { AxiosResponse } from "axios";
|
||||
import { useState } from "react";
|
||||
import { useState, useEffect } from "react";
|
||||
import CreateSiteForm from "./CreateSiteForm";
|
||||
import ConfirmDeleteDialog from "@app/components/ConfirmDeleteDialog";
|
||||
import { toast } from "@app/hooks/useToast";
|
||||
|
@ -53,10 +53,31 @@ export default function SitesTable({ sites, orgId }: SitesTableProps) {
|
|||
const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false);
|
||||
const [selectedSite, setSelectedSite] = useState<SiteRow | null>(null);
|
||||
const [rows, setRows] = useState<SiteRow[]>(sites);
|
||||
const [isRefreshing, setIsRefreshing] = useState(false);
|
||||
|
||||
const api = createApiClient(useEnvContext());
|
||||
const t = useTranslations();
|
||||
|
||||
// Update local state when props change (e.g., after refresh)
|
||||
useEffect(() => {
|
||||
setRows(sites);
|
||||
}, [sites]);
|
||||
|
||||
const refreshData = async () => {
|
||||
setIsRefreshing(true);
|
||||
try {
|
||||
router.refresh();
|
||||
} catch (error) {
|
||||
toast({
|
||||
title: t("error"),
|
||||
description: t("refreshError"),
|
||||
variant: "destructive"
|
||||
});
|
||||
} finally {
|
||||
setIsRefreshing(false);
|
||||
}
|
||||
};
|
||||
|
||||
const deleteSite = (siteId: number) => {
|
||||
api.delete(`/site/${siteId}`)
|
||||
.catch((e) => {
|
||||
|
@ -339,6 +360,8 @@ export default function SitesTable({ sites, orgId }: SitesTableProps) {
|
|||
createSite={() =>
|
||||
router.push(`/${orgId}/settings/sites/create`)
|
||||
}
|
||||
onRefresh={refreshData}
|
||||
isRefreshing={isRefreshing}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
|
|
@ -71,7 +71,7 @@ const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
|||
disabled={loading || props.disabled} // Disable button when loading
|
||||
{...props}
|
||||
>
|
||||
{loading && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
|
||||
{/* {loading && <Loader2 className="mr-2 h-4 w-4 animate-spin" />} */}
|
||||
{props.children}
|
||||
</Comp>
|
||||
);
|
||||
|
|
|
@ -23,13 +23,14 @@ import { Button } from "@app/components/ui/button";
|
|||
import { useState } from "react";
|
||||
import { Input } from "@app/components/ui/input";
|
||||
import { DataTablePagination } from "@app/components/DataTablePagination";
|
||||
import { Plus, Search } from "lucide-react";
|
||||
import { Plus, Search, RefreshCw } from "lucide-react";
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
CardHeader,
|
||||
CardTitle
|
||||
} from "@app/components/ui/card";
|
||||
import { useTranslations } from "next-intl";
|
||||
|
||||
type DataTableProps<TData, TValue> = {
|
||||
columns: ColumnDef<TData, TValue>[];
|
||||
|
@ -37,6 +38,8 @@ type DataTableProps<TData, TValue> = {
|
|||
title?: string;
|
||||
addButtonText?: string;
|
||||
onAdd?: () => void;
|
||||
onRefresh?: () => void;
|
||||
isRefreshing?: boolean;
|
||||
searchPlaceholder?: string;
|
||||
searchColumn?: string;
|
||||
defaultSort?: {
|
||||
|
@ -51,6 +54,8 @@ export function DataTable<TData, TValue>({
|
|||
title,
|
||||
addButtonText,
|
||||
onAdd,
|
||||
onRefresh,
|
||||
isRefreshing,
|
||||
searchPlaceholder = "Search...",
|
||||
searchColumn = "name",
|
||||
defaultSort
|
||||
|
@ -60,6 +65,7 @@ export function DataTable<TData, TValue>({
|
|||
);
|
||||
const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([]);
|
||||
const [globalFilter, setGlobalFilter] = useState<any>([]);
|
||||
const t = useTranslations();
|
||||
|
||||
const table = useReactTable({
|
||||
data,
|
||||
|
@ -99,12 +105,25 @@ export function DataTable<TData, TValue>({
|
|||
/>
|
||||
<Search className="h-4 w-4 absolute left-2 top-1/2 transform -translate-y-1/2 text-muted-foreground" />
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
{onRefresh && (
|
||||
<Button
|
||||
variant="outline"
|
||||
onClick={onRefresh}
|
||||
disabled={isRefreshing}
|
||||
loading={isRefreshing}
|
||||
>
|
||||
<RefreshCw className={`mr-2 h-4 w-4 ${isRefreshing ? 'animate-spin' : ''}`} />
|
||||
{t("refresh")}
|
||||
</Button>
|
||||
)}
|
||||
{onAdd && addButtonText && (
|
||||
<Button onClick={onAdd}>
|
||||
<Plus className="mr-2 h-4 w-4" />
|
||||
{addButtonText}
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<Table>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue