diff --git a/frontend/src/components/job-archive.tsx b/frontend/src/components/job-archive.tsx
index e9d4c43..fef8469 100644
--- a/frontend/src/components/job-archive.tsx
+++ b/frontend/src/components/job-archive.tsx
@@ -1,8 +1,8 @@
-import { Fragment, ChangeEvent, memo, useState, useMemo, useCallback, useContext } from "react";
+import { Fragment, ChangeEvent, useRef, useState, useMemo, useCallback, useContext, useEffect, memo } from "react";
import { assert } from "@protobuf-ts/runtime";
import format from "format-duration";
-import { Virtuoso } from "react-virtuoso";
+import { Virtuoso, VirtuosoHandle } from "react-virtuoso";
import Grid from "@mui/material/Grid";
import Box from "@mui/material/Box";
@@ -24,7 +24,7 @@ import { cli } from "../api";
import { Job, JobDispatchRequest, CopyStatus, SourceState, JobStatus } from "../entity";
import { JobArchiveCopyingParam, JobArchiveStep, JobArchiveDisplay, JobArchiveState } from "../entity";
-import { formatFilesize } from "../tools";
+import { formatFilesize, sleep } from "../tools";
import { JobCard } from "./job-card";
import { RefreshContext } from "../pages/jobs";
@@ -191,40 +191,63 @@ const ArchiveViewFilesDialog = ({ sources }: { sources: SourceState[] }) => {
- {open && (
-
- )}
+ {open && }
);
};
+const FileList = memo(({ handleClose, sources }: { handleClose: () => void; sources: SourceState[] }) => {
+ const virtuosoRef = useRef(null);
+ useEffect(() => {
+ (async () => {
+ const idx = sources.findIndex((src) => src.status !== CopyStatus.SUBMITED && src.status !== CopyStatus.STAGED);
+ if (idx < 0) {
+ return;
+ }
+
+ await sleep(100);
+ console.log(idx, virtuosoRef);
+
+ if (!virtuosoRef.current) {
+ return;
+ }
+ virtuosoRef.current.scrollToIndex({ index: idx - 5, align: "center", behavior: "smooth" });
+ })();
+ }, [sources]);
+
+ return (
+
+ );
+});
+
const RollbackDialog = ({ jobID, state }: { jobID: bigint; state: JobArchiveState }) => {
const refresh = useContext(RefreshContext);