refactor: pr feedbacks
This commit is contained in:
parent
0da4b45d67
commit
b7e98deca1
9 changed files with 44 additions and 31 deletions
|
|
@ -14,7 +14,6 @@ import { useState, useEffect } from "react";
|
|||
import { EmptyState } from "~/client/components/empty-state";
|
||||
import { Button } from "~/client/components/ui/button";
|
||||
import { Card, CardContent } from "~/client/components/ui/card";
|
||||
import { listBackupSchedules } from "~/client/api-client";
|
||||
import {
|
||||
listBackupSchedulesOptions,
|
||||
reorderBackupSchedulesMutation,
|
||||
|
|
@ -23,12 +22,6 @@ import { SortableCard } from "~/client/components/sortable-card";
|
|||
import { BackupCard } from "../components/backup-card";
|
||||
import { Link } from "@tanstack/react-router";
|
||||
|
||||
export const clientLoader = async () => {
|
||||
const jobs = await listBackupSchedules();
|
||||
if (jobs.data) return jobs.data;
|
||||
return [];
|
||||
};
|
||||
|
||||
export function BackupsPage() {
|
||||
const { data: schedules } = useSuspenseQuery({
|
||||
...listBackupSchedulesOptions(),
|
||||
|
|
|
|||
|
|
@ -110,10 +110,6 @@ export function SnapshotDetailsPage({ repositoryId, snapshotId }: { repositoryId
|
|||
<span className="text-muted-foreground">Snapshot ID:</span>
|
||||
<p className="font-mono break-all">{data.short_id}</p>
|
||||
</div>
|
||||
<div>
|
||||
<span className="text-muted-foreground">Short ID:</span>
|
||||
<p className="font-mono break-all">{data.short_id}</p>
|
||||
</div>
|
||||
<div>
|
||||
<span className="text-muted-foreground">Hostname:</span>
|
||||
<p>{data.hostname}</p>
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ type AsyncLocalStorageConstructor = new <T>() => {
|
|||
};
|
||||
|
||||
let requestClientStore: RequestClientStore | undefined;
|
||||
let requestClientStorePromise: Promise<RequestClientStore | undefined> | undefined;
|
||||
|
||||
const ASYNC_HOOKS_MODULE = "node:async_hooks";
|
||||
|
||||
|
|
@ -22,14 +23,17 @@ const loadRequestClientStore = async (): Promise<RequestClientStore | undefined>
|
|||
return undefined;
|
||||
}
|
||||
|
||||
if (!requestClientStore) {
|
||||
const asyncHooksModule = (await import(/* @vite-ignore */ ASYNC_HOOKS_MODULE)) as {
|
||||
AsyncLocalStorage: AsyncLocalStorageConstructor;
|
||||
};
|
||||
requestClientStore = new asyncHooksModule.AsyncLocalStorage<RequestClient>();
|
||||
if (!requestClientStorePromise) {
|
||||
requestClientStorePromise = (async () => {
|
||||
const asyncHooksModule = (await import(/* @vite-ignore */ ASYNC_HOOKS_MODULE)) as {
|
||||
AsyncLocalStorage: AsyncLocalStorageConstructor;
|
||||
};
|
||||
requestClientStore = new asyncHooksModule.AsyncLocalStorage<RequestClient>();
|
||||
return requestClientStore;
|
||||
})();
|
||||
}
|
||||
|
||||
return requestClientStore;
|
||||
return requestClientStorePromise;
|
||||
};
|
||||
|
||||
export function getRequestClient(): RequestClient {
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import { getStatus } from "~/client/api-client";
|
||||
import { createMiddleware } from "@tanstack/react-start";
|
||||
import { redirect } from "@tanstack/react-router";
|
||||
import { auth } from "~/server/lib/auth";
|
||||
import { getRequestHeaders } from "@tanstack/react-start/server";
|
||||
import { authService } from "~/server/modules/auth/auth.service";
|
||||
|
||||
export const authMiddleware = createMiddleware().server(async ({ next, request }) => {
|
||||
const headers = getRequestHeaders();
|
||||
|
|
@ -11,8 +11,8 @@ export const authMiddleware = createMiddleware().server(async ({ next, request }
|
|||
const isAuthRoute = ["/login", "/onboarding"].includes(new URL(request.url).pathname);
|
||||
|
||||
if (!session?.user?.id && !isAuthRoute) {
|
||||
const status = await getStatus().catch(() => ({ data: { hasUsers: false } }));
|
||||
if (!status.data?.hasUsers) {
|
||||
const hasUsers = await authService.hasUsers();
|
||||
if (!hasUsers) {
|
||||
throw redirect({ to: "/onboarding" });
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -21,6 +21,15 @@ export const Route = createFileRoute("/(dashboard)/backups/$backupId/$snapshotId
|
|||
|
||||
return { snapshot, repository, schedule: schedule.data };
|
||||
},
|
||||
head: ({ params }) => ({
|
||||
meta: [
|
||||
{ title: `Zerobyte - Restore Snapshot ${params.snapshotId}` },
|
||||
{
|
||||
name: "description",
|
||||
content: "Restore files from a backup snapshot.",
|
||||
},
|
||||
],
|
||||
}),
|
||||
staticData: {
|
||||
breadcrumb: (match) => [
|
||||
{ label: "Backup Jobs", href: "/backups" },
|
||||
|
|
|
|||
|
|
@ -12,11 +12,7 @@ export const Route = createRootRouteWithContext<{ queryClient: QueryClient }>()(
|
|||
middleware: [apiClientMiddleware],
|
||||
},
|
||||
head: () => ({
|
||||
meta: [
|
||||
{ charSet: "utf-8" },
|
||||
{ name: "viewport", content: "width=device-width, initial-scale=1" },
|
||||
{ title: "Zerobyte - Open Source Backup Solution" },
|
||||
],
|
||||
meta: [{ title: "Zerobyte - Open Source Backup Solution" }],
|
||||
links: [
|
||||
{
|
||||
rel: "stylesheet",
|
||||
|
|
|
|||
|
|
@ -32,12 +32,22 @@ export default createServerEntry({
|
|||
|
||||
process.on("SIGTERM", async () => {
|
||||
logger.info("SIGTERM received, starting graceful shutdown...");
|
||||
await shutdown();
|
||||
process.exit(0);
|
||||
try {
|
||||
await shutdown();
|
||||
} catch (err) {
|
||||
logger.error("Error during shutdown", err);
|
||||
} finally {
|
||||
process.exit(0);
|
||||
}
|
||||
});
|
||||
|
||||
process.on("SIGINT", async () => {
|
||||
logger.info("SIGINT received, starting graceful shutdown...");
|
||||
await shutdown();
|
||||
process.exit(0);
|
||||
try {
|
||||
await shutdown();
|
||||
} catch (err) {
|
||||
logger.error("Error during shutdown", err);
|
||||
} finally {
|
||||
process.exit(0);
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import { format } from "date-fns";
|
||||
import { createConsola, type ConsolaReporter } from "consola";
|
||||
import { formatWithOptions } from "node:util";
|
||||
import { sanitizeSensitiveData } from "./sanitize";
|
||||
|
|
@ -50,17 +51,18 @@ const reporter: ConsolaReporter = {
|
|||
log(logObj, ctx) {
|
||||
const level = resolveLevel(logObj.type);
|
||||
|
||||
const timestamp = colorize("\x1b[90m", format(new Date(), "HH:mm:ss"));
|
||||
const style = levelStyles[level];
|
||||
const prefix = colorize(style.color, style.label);
|
||||
const tag = logObj.tag ? `[${logObj.tag}]` : "";
|
||||
const message = formatWithOptions(
|
||||
{
|
||||
colors: useColor,
|
||||
...ctx.options.formatOptions,
|
||||
colors: useColor,
|
||||
},
|
||||
...logObj.args,
|
||||
);
|
||||
const line = [prefix, tag, message].filter(Boolean).join(" ");
|
||||
const line = [timestamp, prefix, tag, message].filter(Boolean).join(" ");
|
||||
const stream = logObj.level < 2 ? (ctx.options.stderr ?? process.stderr) : (ctx.options.stdout ?? process.stdout);
|
||||
stream.write(line + "\n");
|
||||
},
|
||||
|
|
|
|||
|
|
@ -6,6 +6,9 @@ import tsconfigPaths from "vite-tsconfig-paths";
|
|||
import viteReact from "@vitejs/plugin-react";
|
||||
|
||||
export default defineConfig({
|
||||
define: {
|
||||
"process.env.NODE_ENV": "production",
|
||||
},
|
||||
plugins: [
|
||||
tsconfigPaths(),
|
||||
tanstackStart({
|
||||
|
|
|
|||
Loading…
Reference in a new issue