mirror of
https://github.com/garethgeorge/backrest.git
synced 2026-09-29 03:15:44 +00:00
fix: add virtual root node to snapshot browser
This commit is contained in:
@@ -32,8 +32,6 @@ jobs:
|
||||
with:
|
||||
node-version: "20"
|
||||
|
||||
- name: Check Formatting
|
||||
|
||||
- name: Generate
|
||||
run: go generate ./...
|
||||
|
||||
|
||||
@@ -351,7 +351,7 @@ func (s *BackrestHandler) Prune(ctx context.Context, req *connect.Request[types.
|
||||
|
||||
at := time.Now()
|
||||
wait := make(chan struct{})
|
||||
s.orchestrator.ScheduleTask(tasks.NewOneoffPruneTask(plan.Repo, plan.Id, 0, at, true), tasks.TaskPriorityInteractive+tasks.TaskPriorityPrune, func(e error) {
|
||||
s.orchestrator.ScheduleTask(tasks.NewOneoffPruneTask(plan.Repo, plan.Id, at, true), tasks.TaskPriorityInteractive+tasks.TaskPriorityPrune, func(e error) {
|
||||
err = e
|
||||
close(wait)
|
||||
})
|
||||
|
||||
@@ -116,7 +116,7 @@ func forgetHelper(ctx context.Context, st ScheduledTask, taskRunner TaskRunner)
|
||||
}
|
||||
|
||||
if len(forgot) > 0 {
|
||||
if err := taskRunner.ScheduleTask(NewOneoffPruneTask(t.RepoID(), t.PlanID(), st.Op.FlowId, time.Now(), false), TaskPriorityPrune); err != nil {
|
||||
if err := taskRunner.ScheduleTask(NewOneoffPruneTask(t.RepoID(), t.PlanID(), time.Now(), false), TaskPriorityPrune); err != nil {
|
||||
return fmt.Errorf("schedule prune task: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ type PruneTask struct {
|
||||
force bool
|
||||
}
|
||||
|
||||
func NewOneoffPruneTask(repoID, planID string, flowID int64, at time.Time, force bool) Task {
|
||||
func NewOneoffPruneTask(repoID, planID string, at time.Time, force bool) Task {
|
||||
return &PruneTask{
|
||||
BaseTask: BaseTask{
|
||||
TaskName: fmt.Sprintf("prune for plan %q in repo %q", planID, repoID),
|
||||
@@ -28,8 +28,7 @@ func NewOneoffPruneTask(repoID, planID string, flowID int64, at time.Time, force
|
||||
TaskPlanID: planID,
|
||||
},
|
||||
OneoffTask: OneoffTask{
|
||||
FlowID: flowID,
|
||||
RunAt: at,
|
||||
RunAt: at,
|
||||
ProtoOp: &v1.Operation{
|
||||
Op: &v1.Operation_OperationPrune{},
|
||||
},
|
||||
|
||||
@@ -30,7 +30,7 @@ const SnapshotBrowserContext = React.createContext<{
|
||||
const replaceKeyInTree = (
|
||||
curNode: DataNode,
|
||||
setKey: string,
|
||||
setValue: DataNode,
|
||||
setValue: DataNode
|
||||
): DataNode | null => {
|
||||
if (curNode.key === setKey) {
|
||||
return setValue;
|
||||
@@ -80,18 +80,20 @@ export const SnapshotBrowser = ({
|
||||
const [treeData, setTreeData] = useState<DataNode[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
(async () => {
|
||||
try {
|
||||
const resp = await backrestService.listSnapshotFiles({
|
||||
setTreeData(
|
||||
respToNodes(
|
||||
new ListSnapshotFilesResponse({
|
||||
entries: [
|
||||
{
|
||||
path: "/",
|
||||
type: "directory",
|
||||
name: "/",
|
||||
},
|
||||
],
|
||||
path: "/",
|
||||
repoId,
|
||||
snapshotId,
|
||||
});
|
||||
setTreeData(respToNodes(resp));
|
||||
} catch (e: any) {
|
||||
alertApi?.error("Failed to list snapshot files: " + e.message);
|
||||
}
|
||||
})();
|
||||
})
|
||||
)
|
||||
);
|
||||
}, [repoId, snapshotId]);
|
||||
|
||||
const onLoadData = async ({ key, children }: EventDataNode<DataNode>) => {
|
||||
@@ -131,10 +133,6 @@ export const SnapshotBrowser = ({
|
||||
});
|
||||
};
|
||||
|
||||
if (treeData.length === 0) {
|
||||
return <Spin />;
|
||||
}
|
||||
|
||||
return (
|
||||
<SnapshotBrowserContext.Provider
|
||||
value={{ snapshotId, repoId, planId, showModal }}
|
||||
@@ -146,12 +144,8 @@ export const SnapshotBrowser = ({
|
||||
|
||||
const respToNodes = (resp: ListSnapshotFilesResponse): DataNode[] => {
|
||||
const nodes = resp
|
||||
.entries!.filter((entry) => entry.path!.length > resp.path!.length)
|
||||
.entries!.filter((entry) => entry.path!.length >= resp.path!.length)
|
||||
.map((entry) => {
|
||||
const lastSlash = entry.path!.lastIndexOf("/");
|
||||
const title =
|
||||
lastSlash === -1 ? entry.path : entry.path!.slice(lastSlash + 1);
|
||||
|
||||
const node: DataNode = {
|
||||
key: entry.path!,
|
||||
title: <FileNode entry={entry} />,
|
||||
@@ -167,7 +161,7 @@ const respToNodes = (resp: ListSnapshotFilesResponse): DataNode[] => {
|
||||
const FileNode = ({ entry }: { entry: LsEntry }) => {
|
||||
const [dropdown, setDropdown] = useState<React.ReactNode>(null);
|
||||
const { snapshotId, repoId, planId, showModal } = React.useContext(
|
||||
SnapshotBrowserContext,
|
||||
SnapshotBrowserContext
|
||||
)!;
|
||||
|
||||
const showDropdown = () => {
|
||||
@@ -188,7 +182,7 @@ const FileNode = ({ entry }: { entry: LsEntry }) => {
|
||||
onOk={() => showModal(null)}
|
||||
>
|
||||
<pre>{JSON.stringify(entry, null, 2)}</pre>
|
||||
</Modal>,
|
||||
</Modal>
|
||||
);
|
||||
},
|
||||
},
|
||||
@@ -202,7 +196,7 @@ const FileNode = ({ entry }: { entry: LsEntry }) => {
|
||||
repoId={repoId}
|
||||
planId={planId}
|
||||
snapshotId={snapshotId}
|
||||
/>,
|
||||
/>
|
||||
);
|
||||
},
|
||||
},
|
||||
@@ -210,7 +204,7 @@ const FileNode = ({ entry }: { entry: LsEntry }) => {
|
||||
}}
|
||||
>
|
||||
<DownloadOutlined />
|
||||
</Dropdown>,
|
||||
</Dropdown>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user