fix(ui): import agent button
This commit is contained in:
parent
c440f98381
commit
184d86c58a
|
|
@ -9,9 +9,25 @@ import { useAuth } from "@/auth/clerk";
|
|||
import { useQueryClient } from "@tanstack/react-query";
|
||||
|
||||
import { AgentsTable } from "@/components/agents/AgentsTable";
|
||||
import { GatewayAgentImportDialog } from "@/components/gateways/GatewayAgentImportDialog";
|
||||
import { DashboardPageLayout } from "@/components/templates/DashboardPageLayout";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { ConfirmActionDialog } from "@/components/ui/confirm-action-dialog";
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogDescription,
|
||||
DialogFooter,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
} from "@/components/ui/dialog";
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
SelectItem,
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from "@/components/ui/select";
|
||||
|
||||
import { ApiError } from "@/api/mutator";
|
||||
import {
|
||||
|
|
@ -25,7 +41,12 @@ import {
|
|||
getListBoardsApiV1BoardsGetQueryKey,
|
||||
useListBoardsApiV1BoardsGet,
|
||||
} from "@/api/generated/boards/boards";
|
||||
import { type AgentRead } from "@/api/generated/model";
|
||||
import {
|
||||
type listGatewaysApiV1GatewaysGetResponse,
|
||||
getListGatewaysApiV1GatewaysGetQueryKey,
|
||||
useListGatewaysApiV1GatewaysGet,
|
||||
} from "@/api/generated/gateways/gateways";
|
||||
import { type AgentRead, type GatewayRead } from "@/api/generated/model";
|
||||
import { createOptimisticListDeleteMutation } from "@/lib/list-delete";
|
||||
import { useOrganizationMembership } from "@/lib/use-organization-membership";
|
||||
import { useUrlSorting } from "@/lib/use-url-sorting";
|
||||
|
|
@ -52,9 +73,13 @@ export default function AgentsPage() {
|
|||
});
|
||||
|
||||
const [deleteTarget, setDeleteTarget] = useState<AgentRead | null>(null);
|
||||
const [importGatewayPickerOpen, setImportGatewayPickerOpen] = useState(false);
|
||||
const [selectedGatewayId, setSelectedGatewayId] = useState<string>("");
|
||||
const [importTarget, setImportTarget] = useState<GatewayRead | null>(null);
|
||||
|
||||
const boardsKey = getListBoardsApiV1BoardsGetQueryKey();
|
||||
const agentsKey = getListAgentsApiV1AgentsGetQueryKey();
|
||||
const gatewaysKey = getListGatewaysApiV1GatewaysGetQueryKey();
|
||||
|
||||
const boardsQuery = useListBoardsApiV1BoardsGet<
|
||||
listBoardsApiV1BoardsGetResponse,
|
||||
|
|
@ -77,6 +102,16 @@ export default function AgentsPage() {
|
|||
refetchOnMount: "always",
|
||||
},
|
||||
});
|
||||
const gatewaysQuery = useListGatewaysApiV1GatewaysGet<
|
||||
listGatewaysApiV1GatewaysGetResponse,
|
||||
ApiError
|
||||
>(undefined, {
|
||||
query: {
|
||||
enabled: Boolean(isSignedIn && isAdmin),
|
||||
refetchInterval: 30_000,
|
||||
refetchOnMount: "always",
|
||||
},
|
||||
});
|
||||
|
||||
const boards = useMemo(
|
||||
() =>
|
||||
|
|
@ -92,6 +127,13 @@ export default function AgentsPage() {
|
|||
: [],
|
||||
[agentsQuery.data],
|
||||
);
|
||||
const gateways = useMemo(
|
||||
() =>
|
||||
gatewaysQuery.data?.status === 200
|
||||
? (gatewaysQuery.data.data.items ?? [])
|
||||
: [],
|
||||
[gatewaysQuery.data],
|
||||
);
|
||||
|
||||
const deleteMutation = useDeleteAgentApiV1AgentsAgentIdDelete<
|
||||
ApiError,
|
||||
|
|
@ -121,6 +163,26 @@ export default function AgentsPage() {
|
|||
deleteMutation.mutate({ agentId: deleteTarget.id });
|
||||
};
|
||||
|
||||
const handleImportAgentsClick = () => {
|
||||
if (gateways.length === 1) {
|
||||
setImportTarget(gateways[0]);
|
||||
return;
|
||||
}
|
||||
setImportGatewayPickerOpen(true);
|
||||
};
|
||||
|
||||
const handleOpenImportForSelectedGateway = () => {
|
||||
const gateway = gateways.find((item) => item.id === selectedGatewayId);
|
||||
if (!gateway) return;
|
||||
setImportGatewayPickerOpen(false);
|
||||
setImportTarget(gateway);
|
||||
};
|
||||
|
||||
const handleImported = async () => {
|
||||
await queryClient.invalidateQueries({ queryKey: agentsKey });
|
||||
await queryClient.invalidateQueries({ queryKey: gatewaysKey });
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<DashboardPageLayout
|
||||
|
|
@ -133,9 +195,18 @@ export default function AgentsPage() {
|
|||
description={`${agents.length} agent${agents.length === 1 ? "" : "s"} total.`}
|
||||
headerActions={
|
||||
agents.length > 0 ? (
|
||||
<Button onClick={() => router.push("/agents/new")}>
|
||||
New agent
|
||||
</Button>
|
||||
<div className="flex items-center gap-2">
|
||||
<Button
|
||||
variant="outline"
|
||||
onClick={handleImportAgentsClick}
|
||||
disabled={gateways.length === 0}
|
||||
>
|
||||
Import agents
|
||||
</Button>
|
||||
<Button onClick={() => router.push("/agents/new")}>
|
||||
New agent
|
||||
</Button>
|
||||
</div>
|
||||
) : null
|
||||
}
|
||||
isAdmin={isAdmin}
|
||||
|
|
@ -187,6 +258,65 @@ export default function AgentsPage() {
|
|||
onConfirm={handleDelete}
|
||||
isConfirming={deleteMutation.isPending}
|
||||
/>
|
||||
|
||||
<Dialog
|
||||
open={importGatewayPickerOpen}
|
||||
onOpenChange={(open) => {
|
||||
setImportGatewayPickerOpen(open);
|
||||
if (!open) {
|
||||
setSelectedGatewayId("");
|
||||
}
|
||||
}}
|
||||
>
|
||||
<DialogContent>
|
||||
<DialogHeader>
|
||||
<DialogTitle>Import Agents</DialogTitle>
|
||||
<DialogDescription>
|
||||
Select a gateway to open the agent import screen.
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
<div className="space-y-2">
|
||||
<p className="text-sm font-medium text-foreground">Gateway</p>
|
||||
<Select value={selectedGatewayId} onValueChange={setSelectedGatewayId}>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="Select a gateway" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{gateways.map((gateway) => (
|
||||
<SelectItem key={gateway.id} value={gateway.id}>
|
||||
{gateway.name}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<DialogFooter>
|
||||
<Button
|
||||
variant="outline"
|
||||
onClick={() => setImportGatewayPickerOpen(false)}
|
||||
>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button
|
||||
onClick={handleOpenImportForSelectedGateway}
|
||||
disabled={!selectedGatewayId}
|
||||
>
|
||||
Continue
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
<GatewayAgentImportDialog
|
||||
open={Boolean(importTarget)}
|
||||
onOpenChange={(open) => {
|
||||
if (!open) {
|
||||
setImportTarget(null);
|
||||
}
|
||||
}}
|
||||
gateway={importTarget}
|
||||
onImported={handleImported}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue