mirror of
https://github.com/Noratrieb/haesli.git
synced 2026-01-16 04:35:03 +01:00
react app works
This commit is contained in:
parent
bd0a39dd7a
commit
5befe288e5
15 changed files with 187 additions and 109 deletions
87
amqp_dashboard/frontend/src/components/data-page.tsx
Normal file
87
amqp_dashboard/frontend/src/components/data-page.tsx
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
import React, { FC, useCallback, useEffect, useState } from 'react';
|
||||
import Table from './table';
|
||||
import type { Data } from '../types';
|
||||
|
||||
const fetchData = async (prefix: string): Promise<Data> => {
|
||||
const url = `${prefix}api/data`;
|
||||
return fetch(url).then((res) => res.json());
|
||||
};
|
||||
|
||||
type Props = {
|
||||
prefix: string;
|
||||
};
|
||||
|
||||
const DataPage: FC<Props> = ({ prefix }) => {
|
||||
const [data, setData] = useState<Data | null>(null);
|
||||
|
||||
const refresh = useCallback(async () => {
|
||||
const newData = await fetchData(prefix);
|
||||
setData(newData);
|
||||
}, [setData, prefix]);
|
||||
|
||||
useEffect(() => {
|
||||
const interval = setInterval(refresh, 1000);
|
||||
|
||||
return () => clearInterval(interval);
|
||||
}, [refresh]);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<section>
|
||||
<h2>Connections</h2>
|
||||
{data ? (
|
||||
<Table
|
||||
headers={['Connection ID', 'Client Address', 'Channels']}
|
||||
rows={data.connections.map((connection) => [
|
||||
connection.id,
|
||||
connection.peerAddr,
|
||||
connection.channels.length,
|
||||
])}
|
||||
/>
|
||||
) : (
|
||||
<div>Loading...</div>
|
||||
)}
|
||||
</section>
|
||||
<section>
|
||||
<h2>Queues</h2>
|
||||
{data ? (
|
||||
<Table
|
||||
headers={['Queue ID', 'Name', 'Durable']}
|
||||
rows={data.queues.map((queue) => [
|
||||
queue.id,
|
||||
queue.name,
|
||||
queue.durable ? 'Yes' : 'No',
|
||||
])}
|
||||
/>
|
||||
) : (
|
||||
<div>Loading...</div>
|
||||
)}
|
||||
</section>
|
||||
<section>
|
||||
<h2>Channels</h2>
|
||||
{data ? (
|
||||
<Table
|
||||
headers={['Channel ID', 'Connection ID', 'Number']}
|
||||
rows={data.connections
|
||||
.map((connection) =>
|
||||
connection.channels.map((channel) => ({
|
||||
...channel,
|
||||
connectionId: connection.id,
|
||||
}))
|
||||
)
|
||||
.flat()
|
||||
.map((channel) => [
|
||||
channel.id,
|
||||
channel.connectionId,
|
||||
channel.number,
|
||||
])}
|
||||
/>
|
||||
) : (
|
||||
<div>Loading...</div>
|
||||
)}
|
||||
</section>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default DataPage;
|
||||
31
amqp_dashboard/frontend/src/components/table.tsx
Normal file
31
amqp_dashboard/frontend/src/components/table.tsx
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
import React, { FC } from 'react';
|
||||
|
||||
type Cell = string | number;
|
||||
|
||||
type Row = ReadonlyArray<Cell>;
|
||||
|
||||
type Props = {
|
||||
headers: ReadonlyArray<string>;
|
||||
rows: ReadonlyArray<Row>;
|
||||
};
|
||||
|
||||
const Table: FC<Props> = ({ headers, rows }) => {
|
||||
return (
|
||||
<table>
|
||||
<tr>
|
||||
{headers.map((header) => (
|
||||
<th>{header}</th>
|
||||
))}
|
||||
</tr>
|
||||
{rows.map((row) => (
|
||||
<tr>
|
||||
{row.map((cell) => (
|
||||
<td>{cell}</td>
|
||||
))}
|
||||
</tr>
|
||||
))}
|
||||
</table>
|
||||
);
|
||||
};
|
||||
|
||||
export default Table;
|
||||
Loading…
Add table
Add a link
Reference in a new issue