refactor: pr feedbacks
This commit is contained in:
parent
d5284d9450
commit
7746cf3608
7 changed files with 67 additions and 19 deletions
|
|
@ -1,4 +1,4 @@
|
|||
import { useEffect, useRef } from "react";
|
||||
import { useCallback, useEffect, useRef } from "react";
|
||||
import { useQueryClient } from "@tanstack/react-query";
|
||||
import type {
|
||||
BackupCompletedEventDto,
|
||||
|
|
@ -205,7 +205,7 @@ export function useServerEvents() {
|
|||
};
|
||||
}, [queryClient]);
|
||||
|
||||
const addEventListener = (event: ServerEventType, handler: EventHandler) => {
|
||||
const addEventListener = useCallback((event: ServerEventType, handler: EventHandler) => {
|
||||
if (!handlersRef.current.has(event)) {
|
||||
handlersRef.current.set(event, new Set());
|
||||
}
|
||||
|
|
@ -214,7 +214,7 @@ export function useServerEvents() {
|
|||
return () => {
|
||||
handlersRef.current.get(event)?.delete(handler);
|
||||
};
|
||||
};
|
||||
}, []);
|
||||
|
||||
return { addEventListener };
|
||||
}
|
||||
|
|
|
|||
|
|
@ -356,7 +356,7 @@ export const ScheduleMirrorsConfig = ({ scheduleId, primaryRepositoryId, reposit
|
|||
<StatusDot
|
||||
variant={getStatusVariant(assignment.lastCopyStatus)}
|
||||
label={getStatusLabel(assignment)}
|
||||
animated={isSyncing(assignment) ? true : undefined}
|
||||
animated={isSyncing(assignment)}
|
||||
/>
|
||||
<span className="text-sm text-muted-foreground">{getLabel(assignment)}</span>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -49,8 +49,25 @@ export function BackupsPage() {
|
|||
if (over && active.id !== over.id) {
|
||||
setLocalItems((currentItems) => {
|
||||
const baseItems = currentItems ?? schedules?.map((s) => s.id) ?? [];
|
||||
const oldIndex = baseItems.indexOf(active.id as number);
|
||||
const newIndex = baseItems.indexOf(over.id as number);
|
||||
const activeId = active.id as number;
|
||||
const overId = over.id as number;
|
||||
let oldIndex = baseItems.indexOf(activeId);
|
||||
let newIndex = baseItems.indexOf(overId);
|
||||
|
||||
if (oldIndex === -1 || newIndex === -1) {
|
||||
const freshItems = schedules?.map((s) => s.id) ?? [];
|
||||
oldIndex = freshItems.indexOf(activeId);
|
||||
newIndex = freshItems.indexOf(overId);
|
||||
|
||||
if (oldIndex === -1 || newIndex === -1) {
|
||||
return currentItems;
|
||||
}
|
||||
|
||||
const newItems = arrayMove(freshItems, oldIndex, newIndex);
|
||||
reorderMutation.mutate({ body: { scheduleIds: newItems } });
|
||||
return newItems;
|
||||
}
|
||||
|
||||
const newItems = arrayMove(baseItems, oldIndex, newIndex);
|
||||
reorderMutation.mutate({ body: { scheduleIds: newItems } });
|
||||
|
||||
|
|
|
|||
|
|
@ -6,13 +6,6 @@ import { RepositoryInfoTabContent } from "../tabs/info";
|
|||
import { RepositorySnapshotsTabContent } from "../tabs/snapshots";
|
||||
import { useNavigate, useSearch } from "@tanstack/react-router";
|
||||
|
||||
export const handle = {
|
||||
breadcrumb: (match: Route.MetaArgs) => [
|
||||
{ label: "Repositories", href: "/repositories" },
|
||||
{ label: match.loaderData?.name || match.params.id },
|
||||
],
|
||||
};
|
||||
|
||||
export default function RepositoryDetailsPage({ repositoryId }: { repositoryId: string }) {
|
||||
const navigate = useNavigate();
|
||||
const { tab } = useSearch({ from: "/(dashboard)/repositories/$repositoryId" });
|
||||
|
|
|
|||
|
|
@ -296,6 +296,37 @@ describe("mirror operations", () => {
|
|||
expect(updatedMirror?.lastCopyAt).not.toBeNull();
|
||||
});
|
||||
|
||||
test("should finalize mirror status when mirror settings are updated during copy", async () => {
|
||||
// arrange
|
||||
const volume = await createTestVolume();
|
||||
const sourceRepository = await createTestRepository();
|
||||
const mirrorRepository = await createTestRepository();
|
||||
const schedule = await createTestBackupSchedule({
|
||||
volumeId: volume.id,
|
||||
repositoryId: sourceRepository.id,
|
||||
});
|
||||
|
||||
const originalMirror = await createTestBackupScheduleMirror(schedule.id, mirrorRepository.id);
|
||||
|
||||
resticCopyMock.mockImplementationOnce(async () => {
|
||||
await backupsService.updateMirrors(schedule.id, {
|
||||
mirrors: [{ repositoryId: mirrorRepository.id, enabled: true }],
|
||||
});
|
||||
return { success: true, output: "" };
|
||||
});
|
||||
|
||||
// act
|
||||
await backupsExecutionService.copyToMirrors(schedule.id, sourceRepository, null);
|
||||
|
||||
// assert
|
||||
const mirrors = await backupsService.getMirrors(schedule.id);
|
||||
expect(mirrors).toHaveLength(1);
|
||||
expect(mirrors[0]?.id).not.toBe(originalMirror.id);
|
||||
expect(mirrors[0]?.lastCopyStatus).toBe("success");
|
||||
expect(mirrors[0]?.lastCopyError).toBeNull();
|
||||
expect(mirrors[0]?.lastCopyAt).not.toBeNull();
|
||||
});
|
||||
|
||||
test("should update mirror status on failure", async () => {
|
||||
// arrange
|
||||
const volume = await createTestVolume();
|
||||
|
|
|
|||
|
|
@ -367,7 +367,6 @@ const copyToSingleMirror = async (
|
|||
schedule: BackupSchedule,
|
||||
sourceRepository: Repository,
|
||||
mirror: {
|
||||
id: number;
|
||||
repositoryId: string;
|
||||
repository: Repository;
|
||||
},
|
||||
|
|
@ -384,7 +383,7 @@ const copyToSingleMirror = async (
|
|||
repositoryName: mirror.repository.name,
|
||||
});
|
||||
|
||||
await mirrorQueries.updateStatus(mirror.id, {
|
||||
await mirrorQueries.updateStatus(scheduleId, mirror.repositoryId, {
|
||||
lastCopyStatus: "in_progress",
|
||||
lastCopyError: null,
|
||||
});
|
||||
|
|
@ -408,7 +407,7 @@ const copyToSingleMirror = async (
|
|||
});
|
||||
}
|
||||
|
||||
await mirrorQueries.updateStatus(mirror.id, {
|
||||
await mirrorQueries.updateStatus(scheduleId, mirror.repositoryId, {
|
||||
lastCopyAt: Date.now(),
|
||||
lastCopyStatus: "success",
|
||||
lastCopyError: null,
|
||||
|
|
@ -427,7 +426,7 @@ const copyToSingleMirror = async (
|
|||
const errorMessage = toMessage(error);
|
||||
logger.error(`[Background] Failed to copy to mirror repository ${mirror.repository.name}: ${errorMessage}`);
|
||||
|
||||
await mirrorQueries.updateStatus(mirror.id, {
|
||||
await mirrorQueries.updateStatus(scheduleId, mirror.repositoryId, {
|
||||
lastCopyAt: Date.now(),
|
||||
lastCopyStatus: "error",
|
||||
lastCopyError: errorMessage,
|
||||
|
|
|
|||
|
|
@ -59,8 +59,16 @@ export const mirrorQueries = {
|
|||
});
|
||||
},
|
||||
|
||||
updateStatus: async (mirrorId: number, status: MirrorStatusUpdate) => {
|
||||
return db.update(backupScheduleMirrorsTable).set(status).where(eq(backupScheduleMirrorsTable.id, mirrorId));
|
||||
updateStatus: async (scheduleId: number, repositoryId: string, status: MirrorStatusUpdate) => {
|
||||
return db
|
||||
.update(backupScheduleMirrorsTable)
|
||||
.set(status)
|
||||
.where(
|
||||
and(
|
||||
eq(backupScheduleMirrorsTable.scheduleId, scheduleId),
|
||||
eq(backupScheduleMirrorsTable.repositoryId, repositoryId),
|
||||
),
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue