fix: UI refresh timing bugs

This commit is contained in:
garethgeorge
2024-05-27 14:06:13 -07:00
parent 311b09fdd4
commit 14df2b05d7
7 changed files with 72 additions and 64 deletions
+1 -1
View File
@@ -40,7 +40,7 @@ export const ActivityBar = () => {
return () => {
unsubscribeFromOperations(callback);
};
});
}, []);
const details = activeOperations.map((op) => {
return {
+3 -3
View File
@@ -71,7 +71,7 @@ export const OperationList = ({
setBackups(backups);
},
100,
{ leading: true, trailing: true }
{ trailing: true }
)
);
@@ -108,11 +108,11 @@ export const OperationList = ({
itemLayout="horizontal"
size="small"
dataSource={operations}
renderItem={(op) => {
renderItem={(op, index) => {
return (
<OperationRow
alertApi={alertApi!}
key={op.id}
key={op.id + "-" + index}
operation={op}
showPlan={showPlan || false}
/>
+1 -1
View File
@@ -329,7 +329,7 @@ export const OperationRow = ({
children.push(body);
return (
<List.Item>
<List.Item key={operation.id}>
<List.Item.Meta title={title} avatar={avatar} description={children} />
</List.Item>
);
+39 -35
View File
@@ -22,6 +22,7 @@ import {
BackupInfoCollector,
getOperations,
subscribeToOperations,
unsubscribeFromOperations,
} from "../state/oplog";
import { MAX_OPERATION_HISTORY } from "../constants";
import { GetOperationsRequest, OpSelector } from "../../gen/ts/v1/service_pb";
@@ -36,38 +37,42 @@ const StatsPanel = ({ repoId }: { repoId: string }) => {
return;
}
const refreshOperations = _.debounce(() => {
const backupCollector = new BackupInfoCollector((op) => {
return (
op.status === OperationStatus.STATUS_SUCCESS &&
op.op.case === "operationStats" &&
!!op.op.value.stats
);
});
getOperations(
new GetOperationsRequest({
selector: new OpSelector({
repoId: repoId,
}),
lastN: BigInt(MAX_OPERATION_HISTORY),
})
)
.then((ops) => {
backupCollector.bulkAddOperations(ops);
const operations = backupCollector
.getAll()
.flatMap((b) => b.operations);
operations.sort((a, b) => {
return Number(b.unixTimeEndMs - a.unixTimeEndMs);
});
setOperations(operations);
})
.catch((e) => {
alertApi!.error("Failed to fetch operations: " + e.message);
const refreshOperations = _.debounce(
() => {
const backupCollector = new BackupInfoCollector((op) => {
return (
op.status === OperationStatus.STATUS_SUCCESS &&
op.op.case === "operationStats" &&
!!op.op.value.stats
);
});
}, 1000);
getOperations(
new GetOperationsRequest({
selector: new OpSelector({
repoId: repoId,
}),
lastN: BigInt(MAX_OPERATION_HISTORY),
})
)
.then((ops) => {
backupCollector.bulkAddOperations(ops);
const operations = backupCollector
.getAll()
.flatMap((b) => b.operations);
operations.sort((a, b) => {
return Number(b.unixTimeEndMs - a.unixTimeEndMs);
});
setOperations(() => operations);
})
.catch((e) => {
alertApi!.error("Failed to fetch operations: " + e.message);
});
},
100,
{ trailing: true }
);
refreshOperations();
@@ -82,7 +87,9 @@ const StatsPanel = ({ repoId }: { repoId: string }) => {
subscribeToOperations(handler);
return () => {}; // cleanup
return () => {
unsubscribeFromOperations(handler);
};
}, [repoId]);
if (operations.length === 0) {
@@ -108,9 +115,6 @@ const StatsPanel = ({ repoId }: { repoId: string }) => {
};
});
const minTime = Math.min(...dataset.map((d) => d.time));
const maxTime = Math.max(...dataset.map((d) => d.time));
return (
<>
<Row>
+2
View File
@@ -45,6 +45,7 @@ export const subscribeToOperations = (
callback: (event: OperationEvent) => void,
) => {
subscribers.push(callback);
console.log("subscribed to operations, subscriber count: ", subscribers.length);
};
export const unsubscribeFromOperations = (
@@ -55,6 +56,7 @@ export const unsubscribeFromOperations = (
subscribers[index] = subscribers[subscribers.length - 1];
subscribers.pop();
}
console.log("unsubscribed from operations, subscriber count: ", subscribers.length);
};
export const getStatusForSelector = async (sel: OpSelector) => {
+23 -21
View File
@@ -64,28 +64,30 @@ export const GettingStartedGuide = () => {
configured either at the plan or repo level.
</li>
</ul>
<Divider orientation="left">Config View</Divider>
{isDevBuild && (
<Collapse
size="small"
items={[
{
key: "1",
label: "Config JSON hidden for security",
children: config ? (
<Typography>
<pre>
{config.toJsonString({
prettySpaces: 2,
})}
</pre>
</Typography>
) : (
<Spin />
),
},
]}
/>
<>
<Divider orientation="left">Config View</Divider>
<Collapse
size="small"
items={[
{
key: "1",
label: "Config JSON hidden for security",
children: config ? (
<Typography>
<pre>
{config.toJsonString({
prettySpaces: 2,
})}
</pre>
</Typography>
) : (
<Spin />
),
},
]}
/>
</>
)}
</Typography.Text>
</>
+3 -3
View File
@@ -17,12 +17,12 @@ export const LoginModal = () => {
new LoginRequest({
username: "default",
password: "password",
}),
})
)
.then((loginResponse) => {
alertApi.success(
"No users configured yet, logged in with default credentials",
5,
5
);
setAuthToken(loginResponse.token);
setTimeout(() => {
@@ -30,7 +30,7 @@ export const LoginModal = () => {
}, 500);
})
.catch((e) => {});
});
}, []);
const onFinish = async (values: any) => {
const loginReq = new LoginRequest({