Skip to content

Commit 37c4c29

Browse files
authored
Merge pull request #96 from makasim/ui-control-refresh
ui: control refresh
2 parents 7807c8b + 6815ff7 commit 37c4c29

File tree

7 files changed

+114
-30
lines changed

7 files changed

+114
-30
lines changed

ui/dist/assets/index-DJtn1QwC.css

Lines changed: 0 additions & 1 deletion
This file was deleted.

ui/dist/assets/index-PP3_TCe_.js renamed to ui/dist/assets/index-DcLIE6TD.js

Lines changed: 23 additions & 23 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ui/dist/assets/index-f3gViWLA.css

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ui/dist/index.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
66
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
77
<title>Vite + React + TS</title>
8-
<script type="module" crossorigin src="/assets/index-PP3_TCe_.js"></script>
9-
<link rel="stylesheet" crossorigin href="/assets/index-DJtn1QwC.css">
8+
<script type="module" crossorigin src="/assets/index-DcLIE6TD.js"></script>
9+
<link rel="stylesheet" crossorigin href="/assets/index-f3gViWLA.css">
1010
</head>
1111
<body>
1212
<div id="root"></div>

ui/src/StatesPage.tsx

Lines changed: 69 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@ import "./App.css";
22
import { DataTable } from "./components/data-table";
33
import React, { useEffect, useState } from "react";
44
import { State } from "./gen/flowstate/v1/messages_pb";
5+
import { Select } from "./components/ui/select";
56

67
import { ColumnDef } from "@tanstack/react-table";
78
import { createDriverClient } from "./api";
89
import { Badge } from "./components/ui/badge";
10+
import { Button } from "./components/ui/button";
911
import {
1012
Dialog,
1113
DialogContent,
@@ -127,11 +129,43 @@ type DriverClient = ReturnType<typeof createDriverClient>;
127129

128130
export const StatesPage = () => {
129131
const [states, setStates] = useState<State[]>([]);
132+
const [refreshInterval, setRefreshInterval] = useState<number>(5000);
130133
const client = React.useContext(ApiContext);
131134

135+
const manualRefresh = async () => {
136+
if (!client) return;
137+
138+
const getStatesCommand = new GetStatesCommand({
139+
limit: BigInt(100),
140+
latestOnly: false,
141+
sinceRev: BigInt(0),
142+
});
143+
144+
const anyCommand = new Command({
145+
getStates: getStatesCommand
146+
});
147+
148+
try {
149+
const anyCommandResp = await client.getStates(anyCommand);
150+
const getStatesCommand = anyCommandResp.getStates
151+
if (getStatesCommand && getStatesCommand.result) {
152+
const getStatesResult = getStatesCommand.result;
153+
if (getStatesResult.states.length > 0) {
154+
const sortedStates = getStatesResult.states.sort((a, b) => Number(b.rev - a.rev));
155+
setStates(sortedStates);
156+
}
157+
}
158+
} catch (error) {
159+
console.log("Manual refresh error", error);
160+
}
161+
};
162+
132163
useEffect(() => {
133164
if (!client) return;
134165

166+
// Clear existing states when refresh interval changes
167+
setStates([]);
168+
135169
const abortController = new AbortController();
136170

137171
listenToStates(client, abortController.signal).catch((error) =>
@@ -141,7 +175,7 @@ export const StatesPage = () => {
141175
return () => {
142176
abortController.abort();
143177
};
144-
}, [client]);
178+
}, [client, refreshInterval]);
145179

146180
const listenToStates = async (client: DriverClient, signal: AbortSignal) => {
147181
let sinceRev = BigInt(0);
@@ -185,10 +219,14 @@ export const StatesPage = () => {
185219

186220
await pollStates();
187221

188-
intervalId = setInterval(pollStates, 1000);
222+
if (refreshInterval > 0) {
223+
intervalId = setInterval(pollStates, refreshInterval);
224+
}
189225

190226
signal.addEventListener('abort', () => {
191-
clearInterval(intervalId);
227+
if (intervalId) {
228+
clearInterval(intervalId);
229+
}
192230
});
193231
};
194232

@@ -208,6 +246,34 @@ export const StatesPage = () => {
208246

209247
return (
210248
<div className="container mx-auto py-10">
249+
<div className="flex justify-between items-center mb-4">
250+
<h1 className="text-2xl font-semibold">States</h1>
251+
<div className="flex items-center gap-2">
252+
<label htmlFor="refresh-interval" className="text-sm font-medium">
253+
Refresh:
254+
</label>
255+
<Select
256+
id="refresh-interval"
257+
value={refreshInterval.toString()}
258+
onChange={(e) => setRefreshInterval(Number(e.target.value))}
259+
className="w-24"
260+
>
261+
<option value="1000">1s</option>
262+
<option value="5000">5s</option>
263+
<option value="10000">10s</option>
264+
<option value="20000">20s</option>
265+
<option value="30000">30s</option>
266+
<option value="0">Off</option>
267+
</Select>
268+
<Button
269+
onClick={manualRefresh}
270+
variant="outline"
271+
size="sm"
272+
>
273+
Refresh
274+
</Button>
275+
</div>
276+
</div>
211277
<DataTable columns={columns} data={data} />
212278
</div>
213279
);

ui/src/components/ui/select.tsx

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import * as React from "react"
2+
3+
export interface SelectProps extends React.SelectHTMLAttributes<HTMLSelectElement> {}
4+
5+
const Select = React.forwardRef<HTMLSelectElement, SelectProps>(
6+
({ className = "", ...props }, ref) => {
7+
return (
8+
<select
9+
className={`flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 ${className}`}
10+
ref={ref}
11+
{...props}
12+
/>
13+
)
14+
}
15+
)
16+
Select.displayName = "Select"
17+
18+
export { Select }

ui/tsconfig.app.tsbuildinfo

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"root":["./src/annotationdetails.tsx","./src/apicontext.tsx","./src/app.tsx","./src/statespage.tsx","./src/api.ts","./src/main.tsx","./src/vite-env.d.ts","./src/components/serverindicator.tsx","./src/components/data-table.tsx","./src/components/ui/badge.tsx","./src/components/ui/button.tsx","./src/components/ui/dialog.tsx","./src/components/ui/input.tsx","./src/components/ui/table.tsx","./src/gen/flowstate/v1/messages_pb.ts","./src/gen/flowstate/v1/services_connect.ts","./src/hooks/uselocalstorage.ts","./src/lib/utils.ts"],"version":"5.8.3"}
1+
{"root":["./src/annotationdetails.tsx","./src/apicontext.tsx","./src/app.tsx","./src/statespage.tsx","./src/api.ts","./src/main.tsx","./src/vite-env.d.ts","./src/components/serverindicator.tsx","./src/components/data-table.tsx","./src/components/ui/badge.tsx","./src/components/ui/button.tsx","./src/components/ui/dialog.tsx","./src/components/ui/input.tsx","./src/components/ui/select.tsx","./src/components/ui/table.tsx","./src/gen/flowstate/v1/messages_pb.ts","./src/gen/flowstate/v1/services_connect.ts","./src/hooks/uselocalstorage.ts","./src/lib/utils.ts"],"version":"5.8.3"}

0 commit comments

Comments
 (0)