refactor: tighten backend, flows, frontend, tests; push flows to Langflow
This commit is contained in:
parent
6688fb08c6
commit
06ab25fb47
31 changed files with 783 additions and 358 deletions
|
|
@ -202,10 +202,10 @@ export const api = {
|
|||
method: "POST",
|
||||
body: JSON.stringify({ name, email, reason }),
|
||||
}),
|
||||
listAccessRequests: (status?: string) =>
|
||||
req<AccessRequest[]>(
|
||||
`/api/access/requests${status ? `?status=${status}` : ""}`,
|
||||
),
|
||||
listAccessRequests: (status?: string) => {
|
||||
const qs = new URLSearchParams(status ? { status } : {}).toString();
|
||||
return req<AccessRequest[]>(`/api/access/requests${qs ? `?${qs}` : ""}`);
|
||||
},
|
||||
decideAccess: (id: string, approve: boolean) =>
|
||||
req<{ request: AccessRequest; email_sent: boolean }>(
|
||||
`/api/access/requests/${id}/${approve ? "approve" : "reject"}`,
|
||||
|
|
|
|||
11
frontend/src/components/ErrorAlert.tsx
Normal file
11
frontend/src/components/ErrorAlert.tsx
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
import { Alert } from "@mantine/core";
|
||||
import { IconAlertCircle } from "@tabler/icons-react";
|
||||
|
||||
export function ErrorAlert({ message }: { message: string | null }) {
|
||||
if (!message) return null;
|
||||
return (
|
||||
<Alert color="red" icon={<IconAlertCircle size={18} />}>
|
||||
{message}
|
||||
</Alert>
|
||||
);
|
||||
}
|
||||
30
frontend/src/components/RunsTable.tsx
Normal file
30
frontend/src/components/RunsTable.tsx
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
import { Code, Table } from "@mantine/core";
|
||||
import StatusBadge from "./StatusBadge";
|
||||
import type { Run } from "../api";
|
||||
|
||||
export function RunsTable({ runs }: { runs: Run[] }) {
|
||||
return (
|
||||
<Table>
|
||||
<Table.Thead>
|
||||
<Table.Tr>
|
||||
<Table.Th>Status</Table.Th>
|
||||
<Table.Th>Ergebnis</Table.Th>
|
||||
<Table.Th>Erstellt</Table.Th>
|
||||
</Table.Tr>
|
||||
</Table.Thead>
|
||||
<Table.Tbody>
|
||||
{runs.map((r) => (
|
||||
<Table.Tr key={r.id}>
|
||||
<Table.Td>
|
||||
<StatusBadge status={r.status} />
|
||||
</Table.Td>
|
||||
<Table.Td>
|
||||
<Code>{r.output?.result ?? r.output?.error ?? "–"}</Code>
|
||||
</Table.Td>
|
||||
<Table.Td>{new Date(r.created_at).toLocaleString("de-DE")}</Table.Td>
|
||||
</Table.Tr>
|
||||
))}
|
||||
</Table.Tbody>
|
||||
</Table>
|
||||
);
|
||||
}
|
||||
|
|
@ -3,19 +3,19 @@ import Form from "@rjsf/mantine";
|
|||
import validator from "@rjsf/validator-ajv8";
|
||||
import type { RJSFSchema, UiSchema } from "@rjsf/utils";
|
||||
import {
|
||||
Alert,
|
||||
Button,
|
||||
Card,
|
||||
Code,
|
||||
Select,
|
||||
Table,
|
||||
Text,
|
||||
Textarea,
|
||||
Title,
|
||||
} from "@mantine/core";
|
||||
import { IconAlertCircle, IconPlayerPlay } from "@tabler/icons-react";
|
||||
import { IconPlayerPlay } from "@tabler/icons-react";
|
||||
import { ApiError, api, type FlowDefinition, type InputSchema, type Run } from "../api";
|
||||
import StatusBadge from "../components/StatusBadge";
|
||||
import { RunsTable } from "../components/RunsTable";
|
||||
import { ErrorAlert } from "../components/ErrorAlert";
|
||||
import { formatApiError } from "../utils";
|
||||
|
||||
export default function WorkflowsPage() {
|
||||
const [flows, setFlows] = useState<FlowDefinition[]>([]);
|
||||
|
|
@ -29,7 +29,7 @@ export default function WorkflowsPage() {
|
|||
const [busy, setBusy] = useState(false);
|
||||
|
||||
const fail = useCallback((e: unknown) => {
|
||||
setError(e instanceof ApiError ? `${e.status}: ${e.message}` : String(e));
|
||||
setError(formatApiError(e));
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
|
|
@ -85,9 +85,9 @@ export default function WorkflowsPage() {
|
|||
Workflows
|
||||
</Title>
|
||||
{error && (
|
||||
<Alert color="red" icon={<IconAlertCircle size={18} />} mb="md">
|
||||
{error}
|
||||
</Alert>
|
||||
<div style={{ marginBottom: 12 }}>
|
||||
<ErrorAlert message={error} />
|
||||
</div>
|
||||
)}
|
||||
<Select
|
||||
label="Flow"
|
||||
|
|
@ -154,28 +154,7 @@ export default function WorkflowsPage() {
|
|||
{runs.length === 0 ? (
|
||||
<Text c="dimmed">Noch keine Läufe.</Text>
|
||||
) : (
|
||||
<Table striped highlightOnHover>
|
||||
<Table.Thead>
|
||||
<Table.Tr>
|
||||
<Table.Th>Status</Table.Th>
|
||||
<Table.Th>Mandant</Table.Th>
|
||||
<Table.Th>Ergebnis</Table.Th>
|
||||
</Table.Tr>
|
||||
</Table.Thead>
|
||||
<Table.Tbody>
|
||||
{runs.map((r) => (
|
||||
<Table.Tr key={r.id}>
|
||||
<Table.Td>
|
||||
<StatusBadge status={r.status} />
|
||||
</Table.Td>
|
||||
<Table.Td>{r.tenant_id}</Table.Td>
|
||||
<Table.Td>
|
||||
<Code>{r.output?.result ?? r.output?.error ?? "–"}</Code>
|
||||
</Table.Td>
|
||||
</Table.Tr>
|
||||
))}
|
||||
</Table.Tbody>
|
||||
</Table>
|
||||
<RunsTable runs={runs} />
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
9
frontend/src/utils.ts
Normal file
9
frontend/src/utils.ts
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
/* Shared frontend helpers: error formatting, config (was scattered). */
|
||||
import { ApiError } from "./api";
|
||||
|
||||
export function formatApiError(e: unknown): string {
|
||||
if (e instanceof ApiError) return `${e.status}: ${e.message}`;
|
||||
return String(e);
|
||||
}
|
||||
|
||||
export const LANGFLOW_URL_FALLBACK = "http://localhost:7860";
|
||||
Loading…
Add table
Add a link
Reference in a new issue