refactor(create-volume-form): move to volumes module

This commit is contained in:
Nicolas Meienberger
2025-11-19 19:25:54 +01:00
parent 14dadc85e7
commit b70f973c12
5 changed files with 372 additions and 33 deletions

View File

@@ -2,7 +2,7 @@
import type { Client, Options as Options2, TDataShape } from './client';
import { client } from './client.gen';
import type { BrowseFilesystemData, BrowseFilesystemResponses, ChangePasswordData, ChangePasswordResponses, CreateBackupScheduleData, CreateBackupScheduleResponses, CreateRepositoryData, CreateRepositoryResponses, CreateVolumeData, CreateVolumeResponses, DeleteBackupScheduleData, DeleteBackupScheduleResponses, DeleteRepositoryData, DeleteRepositoryResponses, DeleteVolumeData, DeleteVolumeResponses, DoctorRepositoryData, DoctorRepositoryResponses, DownloadResticPasswordData, DownloadResticPasswordResponses, GetBackupScheduleData, GetBackupScheduleForVolumeData, GetBackupScheduleForVolumeResponses, GetBackupScheduleResponses, GetContainersUsingVolumeData, GetContainersUsingVolumeErrors, GetContainersUsingVolumeResponses, GetMeData, GetMeResponses, GetRepositoryData, GetRepositoryResponses, GetSnapshotDetailsData, GetSnapshotDetailsResponses, GetStatusData, GetStatusResponses, GetSystemInfoData, GetSystemInfoResponses, GetVolumeData, GetVolumeErrors, GetVolumeResponses, HealthCheckVolumeData, HealthCheckVolumeErrors, HealthCheckVolumeResponses, ListBackupSchedulesData, ListBackupSchedulesResponses, ListFilesData, ListFilesResponses, ListRcloneRemotesData, ListRcloneRemotesResponses, ListRepositoriesData, ListRepositoriesResponses, ListSnapshotFilesData, ListSnapshotFilesResponses, ListSnapshotsData, ListSnapshotsResponses, ListVolumesData, ListVolumesResponses, LoginData, LoginResponses, LogoutData, LogoutResponses, MountVolumeData, MountVolumeResponses, RegisterData, RegisterResponses, RestoreSnapshotData, RestoreSnapshotResponses, RunBackupNowData, RunBackupNowResponses, RunForgetData, RunForgetErrors, RunForgetResponses, StopBackupData, StopBackupErrors, StopBackupResponses, TestConnectionData, TestConnectionResponses, UnmountVolumeData, UnmountVolumeResponses, UpdateBackupScheduleData, UpdateBackupScheduleResponses, UpdateVolumeData, UpdateVolumeErrors, UpdateVolumeResponses } from './types.gen';
import type { BrowseFilesystemData, BrowseFilesystemResponses, ChangePasswordData, ChangePasswordResponses, CreateBackupScheduleData, CreateBackupScheduleResponses, CreateRepositoryData, CreateRepositoryResponses, CreateVolumeData, CreateVolumeResponses, DeleteBackupScheduleData, DeleteBackupScheduleResponses, DeleteRepositoryData, DeleteRepositoryResponses, DeleteVolumeData, DeleteVolumeResponses, DoctorRepositoryData, DoctorRepositoryResponses, DownloadResticPasswordData, DownloadResticPasswordResponses, GetBackupScheduleData, GetBackupScheduleForVolumeData, GetBackupScheduleForVolumeResponses, GetBackupScheduleResponses, GetContainersUsingVolumeData, GetContainersUsingVolumeErrors, GetContainersUsingVolumeResponses, GetMeData, GetMeResponses, GetRepositoryData, GetRepositoryResponses, GetSnapshotDetailsData, GetSnapshotDetailsResponses, GetStatusData, GetStatusResponses, GetSystemInfoData, GetSystemInfoResponses, GetVolumeData, GetVolumeErrors, GetVolumeResponses, HealthCheckVolumeData, HealthCheckVolumeErrors, HealthCheckVolumeResponses, ListBackupSchedulesData, ListBackupSchedulesResponses, ListFilesData, ListFilesResponses, ListRcloneRemotesData, ListRcloneRemotesResponses, ListRepositoriesData, ListRepositoriesResponses, ListSnapshotFilesData, ListSnapshotFilesResponses, ListSnapshotsData, ListSnapshotsResponses, ListVolumesData, ListVolumesResponses, LoginData, LoginResponses, LogoutData, LogoutResponses, MountVolumeData, MountVolumeResponses, RegisterData, RegisterResponses, RestoreSnapshotData, RestoreSnapshotResponses, RunBackupNowData, RunBackupNowResponses, RunForgetData, RunForgetResponses, StopBackupData, StopBackupErrors, StopBackupResponses, TestConnectionData, TestConnectionResponses, UnmountVolumeData, UnmountVolumeResponses, UpdateBackupScheduleData, UpdateBackupScheduleResponses, UpdateVolumeData, UpdateVolumeErrors, UpdateVolumeResponses } from './types.gen';
export type Options<TData extends TDataShape = TDataShape, ThrowOnError extends boolean = boolean> = Options2<TData, ThrowOnError> & {
/**
@@ -422,7 +422,7 @@ export const stopBackup = <ThrowOnError extends boolean = false>(options: Option
* Manually apply retention policy to clean up old snapshots
*/
export const runForget = <ThrowOnError extends boolean = false>(options: Options<RunForgetData, ThrowOnError>) => {
return (options.client ?? client).post<RunForgetResponses, RunForgetErrors, ThrowOnError>({
return (options.client ?? client).post<RunForgetResponses, unknown, ThrowOnError>({
url: '/api/v1/backups/{scheduleId}/forget',
...options
});

View File

@@ -157,6 +157,22 @@ export type ListVolumesResponses = {
backend: 'directory';
path: string;
readOnly?: false;
} | {
backend: 'mariadb';
database: string;
host: string;
password: string;
username: string;
port?: number;
dumpOptions?: Array<string>;
} | {
backend: 'mysql';
database: string;
host: string;
password: string;
username: string;
port?: number;
dumpOptions?: Array<string>;
} | {
backend: 'nfs';
exportPath: string;
@@ -164,6 +180,15 @@ export type ListVolumesResponses = {
version: '3' | '4' | '4.1';
port?: number;
readOnly?: boolean;
} | {
backend: 'postgres';
database: string;
host: string;
password: string;
username: string;
dumpFormat?: 'custom' | 'directory' | 'plain';
port?: number;
dumpOptions?: Array<string>;
} | {
backend: 'smb';
password: string;
@@ -190,7 +215,7 @@ export type ListVolumesResponses = {
lastHealthCheck: number;
name: string;
status: 'error' | 'mounted' | 'unmounted';
type: 'directory' | 'nfs' | 'smb' | 'webdav';
type: 'directory' | 'mariadb' | 'mysql' | 'nfs' | 'postgres' | 'smb' | 'webdav';
updatedAt: number;
}>;
};
@@ -203,6 +228,22 @@ export type CreateVolumeData = {
backend: 'directory';
path: string;
readOnly?: false;
} | {
backend: 'mariadb';
database: string;
host: string;
password: string;
username: string;
port?: number;
dumpOptions?: Array<string>;
} | {
backend: 'mysql';
database: string;
host: string;
password: string;
username: string;
port?: number;
dumpOptions?: Array<string>;
} | {
backend: 'nfs';
exportPath: string;
@@ -210,6 +251,15 @@ export type CreateVolumeData = {
version: '3' | '4' | '4.1';
port?: number;
readOnly?: boolean;
} | {
backend: 'postgres';
database: string;
host: string;
password: string;
username: string;
dumpFormat?: 'custom' | 'directory' | 'plain';
port?: number;
dumpOptions?: Array<string>;
} | {
backend: 'smb';
password: string;
@@ -247,6 +297,22 @@ export type CreateVolumeResponses = {
backend: 'directory';
path: string;
readOnly?: false;
} | {
backend: 'mariadb';
database: string;
host: string;
password: string;
username: string;
port?: number;
dumpOptions?: Array<string>;
} | {
backend: 'mysql';
database: string;
host: string;
password: string;
username: string;
port?: number;
dumpOptions?: Array<string>;
} | {
backend: 'nfs';
exportPath: string;
@@ -254,6 +320,15 @@ export type CreateVolumeResponses = {
version: '3' | '4' | '4.1';
port?: number;
readOnly?: boolean;
} | {
backend: 'postgres';
database: string;
host: string;
password: string;
username: string;
dumpFormat?: 'custom' | 'directory' | 'plain';
port?: number;
dumpOptions?: Array<string>;
} | {
backend: 'smb';
password: string;
@@ -280,7 +355,7 @@ export type CreateVolumeResponses = {
lastHealthCheck: number;
name: string;
status: 'error' | 'mounted' | 'unmounted';
type: 'directory' | 'nfs' | 'smb' | 'webdav';
type: 'directory' | 'mariadb' | 'mysql' | 'nfs' | 'postgres' | 'smb' | 'webdav';
updatedAt: number;
};
};
@@ -293,6 +368,22 @@ export type TestConnectionData = {
backend: 'directory';
path: string;
readOnly?: false;
} | {
backend: 'mariadb';
database: string;
host: string;
password: string;
username: string;
port?: number;
dumpOptions?: Array<string>;
} | {
backend: 'mysql';
database: string;
host: string;
password: string;
username: string;
port?: number;
dumpOptions?: Array<string>;
} | {
backend: 'nfs';
exportPath: string;
@@ -300,6 +391,15 @@ export type TestConnectionData = {
version: '3' | '4' | '4.1';
port?: number;
readOnly?: boolean;
} | {
backend: 'postgres';
database: string;
host: string;
password: string;
username: string;
dumpFormat?: 'custom' | 'directory' | 'plain';
port?: number;
dumpOptions?: Array<string>;
} | {
backend: 'smb';
password: string;
@@ -390,6 +490,22 @@ export type GetVolumeResponses = {
backend: 'directory';
path: string;
readOnly?: false;
} | {
backend: 'mariadb';
database: string;
host: string;
password: string;
username: string;
port?: number;
dumpOptions?: Array<string>;
} | {
backend: 'mysql';
database: string;
host: string;
password: string;
username: string;
port?: number;
dumpOptions?: Array<string>;
} | {
backend: 'nfs';
exportPath: string;
@@ -397,6 +513,15 @@ export type GetVolumeResponses = {
version: '3' | '4' | '4.1';
port?: number;
readOnly?: boolean;
} | {
backend: 'postgres';
database: string;
host: string;
password: string;
username: string;
dumpFormat?: 'custom' | 'directory' | 'plain';
port?: number;
dumpOptions?: Array<string>;
} | {
backend: 'smb';
password: string;
@@ -423,7 +548,7 @@ export type GetVolumeResponses = {
lastHealthCheck: number;
name: string;
status: 'error' | 'mounted' | 'unmounted';
type: 'directory' | 'nfs' | 'smb' | 'webdav';
type: 'directory' | 'mariadb' | 'mysql' | 'nfs' | 'postgres' | 'smb' | 'webdav';
updatedAt: number;
};
};
@@ -438,6 +563,22 @@ export type UpdateVolumeData = {
backend: 'directory';
path: string;
readOnly?: false;
} | {
backend: 'mariadb';
database: string;
host: string;
password: string;
username: string;
port?: number;
dumpOptions?: Array<string>;
} | {
backend: 'mysql';
database: string;
host: string;
password: string;
username: string;
port?: number;
dumpOptions?: Array<string>;
} | {
backend: 'nfs';
exportPath: string;
@@ -445,6 +586,15 @@ export type UpdateVolumeData = {
version: '3' | '4' | '4.1';
port?: number;
readOnly?: boolean;
} | {
backend: 'postgres';
database: string;
host: string;
password: string;
username: string;
dumpFormat?: 'custom' | 'directory' | 'plain';
port?: number;
dumpOptions?: Array<string>;
} | {
backend: 'smb';
password: string;
@@ -490,6 +640,22 @@ export type UpdateVolumeResponses = {
backend: 'directory';
path: string;
readOnly?: false;
} | {
backend: 'mariadb';
database: string;
host: string;
password: string;
username: string;
port?: number;
dumpOptions?: Array<string>;
} | {
backend: 'mysql';
database: string;
host: string;
password: string;
username: string;
port?: number;
dumpOptions?: Array<string>;
} | {
backend: 'nfs';
exportPath: string;
@@ -497,6 +663,15 @@ export type UpdateVolumeResponses = {
version: '3' | '4' | '4.1';
port?: number;
readOnly?: boolean;
} | {
backend: 'postgres';
database: string;
host: string;
password: string;
username: string;
dumpFormat?: 'custom' | 'directory' | 'plain';
port?: number;
dumpOptions?: Array<string>;
} | {
backend: 'smb';
password: string;
@@ -523,7 +698,7 @@ export type UpdateVolumeResponses = {
lastHealthCheck: number;
name: string;
status: 'error' | 'mounted' | 'unmounted';
type: 'directory' | 'nfs' | 'smb' | 'webdav';
type: 'directory' | 'mariadb' | 'mysql' | 'nfs' | 'postgres' | 'smb' | 'webdav';
updatedAt: number;
};
};
@@ -711,30 +886,42 @@ export type ListRepositoriesResponses = {
bucket: string;
endpoint: string;
secretAccessKey: string;
customPassword?: string;
isExistingRepository?: boolean;
} | {
accessKeyId: string;
backend: 's3';
bucket: string;
endpoint: string;
secretAccessKey: string;
customPassword?: string;
isExistingRepository?: boolean;
} | {
accountKey: string;
accountName: string;
backend: 'azure';
container: string;
customPassword?: string;
endpointSuffix?: string;
isExistingRepository?: boolean;
} | {
backend: 'gcs';
bucket: string;
credentialsJson: string;
projectId: string;
customPassword?: string;
isExistingRepository?: boolean;
} | {
backend: 'local';
name: string;
customPassword?: string;
isExistingRepository?: boolean;
} | {
backend: 'rclone';
path: string;
remote: string;
customPassword?: string;
isExistingRepository?: boolean;
};
createdAt: number;
id: string;
@@ -757,30 +944,42 @@ export type CreateRepositoryData = {
bucket: string;
endpoint: string;
secretAccessKey: string;
customPassword?: string;
isExistingRepository?: boolean;
} | {
accessKeyId: string;
backend: 's3';
bucket: string;
endpoint: string;
secretAccessKey: string;
customPassword?: string;
isExistingRepository?: boolean;
} | {
accountKey: string;
accountName: string;
backend: 'azure';
container: string;
customPassword?: string;
endpointSuffix?: string;
isExistingRepository?: boolean;
} | {
backend: 'gcs';
bucket: string;
credentialsJson: string;
projectId: string;
customPassword?: string;
isExistingRepository?: boolean;
} | {
backend: 'local';
name: string;
customPassword?: string;
isExistingRepository?: boolean;
} | {
backend: 'rclone';
path: string;
remote: string;
customPassword?: string;
isExistingRepository?: boolean;
};
name: string;
compressionMode?: 'auto' | 'better' | 'fastest' | 'max' | 'off';
@@ -865,30 +1064,42 @@ export type GetRepositoryResponses = {
bucket: string;
endpoint: string;
secretAccessKey: string;
customPassword?: string;
isExistingRepository?: boolean;
} | {
accessKeyId: string;
backend: 's3';
bucket: string;
endpoint: string;
secretAccessKey: string;
customPassword?: string;
isExistingRepository?: boolean;
} | {
accountKey: string;
accountName: string;
backend: 'azure';
container: string;
customPassword?: string;
endpointSuffix?: string;
isExistingRepository?: boolean;
} | {
backend: 'gcs';
bucket: string;
credentialsJson: string;
projectId: string;
customPassword?: string;
isExistingRepository?: boolean;
} | {
backend: 'local';
name: string;
customPassword?: string;
isExistingRepository?: boolean;
} | {
backend: 'rclone';
path: string;
remote: string;
customPassword?: string;
isExistingRepository?: boolean;
};
createdAt: number;
id: string;
@@ -1079,30 +1290,42 @@ export type ListBackupSchedulesResponses = {
bucket: string;
endpoint: string;
secretAccessKey: string;
customPassword?: string;
isExistingRepository?: boolean;
} | {
accessKeyId: string;
backend: 's3';
bucket: string;
endpoint: string;
secretAccessKey: string;
customPassword?: string;
isExistingRepository?: boolean;
} | {
accountKey: string;
accountName: string;
backend: 'azure';
container: string;
customPassword?: string;
endpointSuffix?: string;
isExistingRepository?: boolean;
} | {
backend: 'gcs';
bucket: string;
credentialsJson: string;
projectId: string;
customPassword?: string;
isExistingRepository?: boolean;
} | {
backend: 'local';
name: string;
customPassword?: string;
isExistingRepository?: boolean;
} | {
backend: 'rclone';
path: string;
remote: string;
customPassword?: string;
isExistingRepository?: boolean;
};
createdAt: number;
id: string;
@@ -1130,6 +1353,22 @@ export type ListBackupSchedulesResponses = {
backend: 'directory';
path: string;
readOnly?: false;
} | {
backend: 'mariadb';
database: string;
host: string;
password: string;
username: string;
port?: number;
dumpOptions?: Array<string>;
} | {
backend: 'mysql';
database: string;
host: string;
password: string;
username: string;
port?: number;
dumpOptions?: Array<string>;
} | {
backend: 'nfs';
exportPath: string;
@@ -1137,6 +1376,15 @@ export type ListBackupSchedulesResponses = {
version: '3' | '4' | '4.1';
port?: number;
readOnly?: boolean;
} | {
backend: 'postgres';
database: string;
host: string;
password: string;
username: string;
dumpFormat?: 'custom' | 'directory' | 'plain';
port?: number;
dumpOptions?: Array<string>;
} | {
backend: 'smb';
password: string;
@@ -1163,7 +1411,7 @@ export type ListBackupSchedulesResponses = {
lastHealthCheck: number;
name: string;
status: 'error' | 'mounted' | 'unmounted';
type: 'directory' | 'nfs' | 'smb' | 'webdav';
type: 'directory' | 'mariadb' | 'mysql' | 'nfs' | 'postgres' | 'smb' | 'webdav';
updatedAt: number;
};
volumeId: number;
@@ -1280,30 +1528,42 @@ export type GetBackupScheduleResponses = {
bucket: string;
endpoint: string;
secretAccessKey: string;
customPassword?: string;
isExistingRepository?: boolean;
} | {
accessKeyId: string;
backend: 's3';
bucket: string;
endpoint: string;
secretAccessKey: string;
customPassword?: string;
isExistingRepository?: boolean;
} | {
accountKey: string;
accountName: string;
backend: 'azure';
container: string;
customPassword?: string;
endpointSuffix?: string;
isExistingRepository?: boolean;
} | {
backend: 'gcs';
bucket: string;
credentialsJson: string;
projectId: string;
customPassword?: string;
isExistingRepository?: boolean;
} | {
backend: 'local';
name: string;
customPassword?: string;
isExistingRepository?: boolean;
} | {
backend: 'rclone';
path: string;
remote: string;
customPassword?: string;
isExistingRepository?: boolean;
};
createdAt: number;
id: string;
@@ -1331,6 +1591,22 @@ export type GetBackupScheduleResponses = {
backend: 'directory';
path: string;
readOnly?: false;
} | {
backend: 'mariadb';
database: string;
host: string;
password: string;
username: string;
port?: number;
dumpOptions?: Array<string>;
} | {
backend: 'mysql';
database: string;
host: string;
password: string;
username: string;
port?: number;
dumpOptions?: Array<string>;
} | {
backend: 'nfs';
exportPath: string;
@@ -1338,6 +1614,15 @@ export type GetBackupScheduleResponses = {
version: '3' | '4' | '4.1';
port?: number;
readOnly?: boolean;
} | {
backend: 'postgres';
database: string;
host: string;
password: string;
username: string;
dumpFormat?: 'custom' | 'directory' | 'plain';
port?: number;
dumpOptions?: Array<string>;
} | {
backend: 'smb';
password: string;
@@ -1364,7 +1649,7 @@ export type GetBackupScheduleResponses = {
lastHealthCheck: number;
name: string;
status: 'error' | 'mounted' | 'unmounted';
type: 'directory' | 'nfs' | 'smb' | 'webdav';
type: 'directory' | 'mariadb' | 'mysql' | 'nfs' | 'postgres' | 'smb' | 'webdav';
updatedAt: number;
};
volumeId: number;
@@ -1462,30 +1747,42 @@ export type GetBackupScheduleForVolumeResponses = {
bucket: string;
endpoint: string;
secretAccessKey: string;
customPassword?: string;
isExistingRepository?: boolean;
} | {
accessKeyId: string;
backend: 's3';
bucket: string;
endpoint: string;
secretAccessKey: string;
customPassword?: string;
isExistingRepository?: boolean;
} | {
accountKey: string;
accountName: string;
backend: 'azure';
container: string;
customPassword?: string;
endpointSuffix?: string;
isExistingRepository?: boolean;
} | {
backend: 'gcs';
bucket: string;
credentialsJson: string;
projectId: string;
customPassword?: string;
isExistingRepository?: boolean;
} | {
backend: 'local';
name: string;
customPassword?: string;
isExistingRepository?: boolean;
} | {
backend: 'rclone';
path: string;
remote: string;
customPassword?: string;
isExistingRepository?: boolean;
};
createdAt: number;
id: string;
@@ -1513,6 +1810,22 @@ export type GetBackupScheduleForVolumeResponses = {
backend: 'directory';
path: string;
readOnly?: false;
} | {
backend: 'mariadb';
database: string;
host: string;
password: string;
username: string;
port?: number;
dumpOptions?: Array<string>;
} | {
backend: 'mysql';
database: string;
host: string;
password: string;
username: string;
port?: number;
dumpOptions?: Array<string>;
} | {
backend: 'nfs';
exportPath: string;
@@ -1520,6 +1833,15 @@ export type GetBackupScheduleForVolumeResponses = {
version: '3' | '4' | '4.1';
port?: number;
readOnly?: boolean;
} | {
backend: 'postgres';
database: string;
host: string;
password: string;
username: string;
dumpFormat?: 'custom' | 'directory' | 'plain';
port?: number;
dumpOptions?: Array<string>;
} | {
backend: 'smb';
password: string;
@@ -1546,7 +1868,7 @@ export type GetBackupScheduleForVolumeResponses = {
lastHealthCheck: number;
name: string;
status: 'error' | 'mounted' | 'unmounted';
type: 'directory' | 'nfs' | 'smb' | 'webdav';
type: 'directory' | 'mariadb' | 'mysql' | 'nfs' | 'postgres' | 'smb' | 'webdav';
updatedAt: number;
};
volumeId: number;
@@ -1611,13 +1933,6 @@ export type RunForgetData = {
url: '/api/v1/backups/{scheduleId}/forget';
};
export type RunForgetErrors = {
/**
* No retention policy configured for this schedule
*/
400: unknown;
};
export type RunForgetResponses = {
/**
* Retention policy applied successfully

View File

@@ -6,15 +6,31 @@ import { useEffect, useState } from "react";
import { useForm } from "react-hook-form";
import { cn, slugify } from "~/client/lib/utils";
import { deepClean } from "~/utils/object";
import { DirectoryBrowser } from "./directory-browser";
import { Button } from "./ui/button";
import { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage } from "./ui/form";
import { Input } from "./ui/input";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "./ui/select";
import { volumeConfigSchema } from "~/schemas/volumes";
import { testConnectionMutation } from "../api-client/@tanstack/react-query.gen";
import { testConnectionMutation } from "~/client/api-client/@tanstack/react-query.gen";
import {
Form,
FormControl,
FormDescription,
FormField,
FormItem,
FormLabel,
FormMessage,
} from "~/client/components/ui/form";
import { Input } from "~/client/components/ui/input";
import {
Select,
SelectContent,
SelectGroup,
SelectItem,
SelectLabel,
SelectTrigger,
SelectValue,
} from "~/client/components/ui/select";
import { Button } from "~/client/components/ui/button";
import { DirectoryBrowser } from "~/client/components/directory-browser";
const SUPPORTS_CONNECTION_TEST = ["nfs", "smb", "webdav", "mariadb", "mysql", "postgres"] as const;
const SUPPORTS_CONNECTION_TEST = ["nfs", "smb", "webdav", "mariadb", "mysql", "postgres"];
export const formSchema = type({
name: "2<=string<=32",
@@ -126,18 +142,26 @@ export const CreateVolumeForm = ({ onSubmit, mode = "create", initialValues, for
<FormLabel>Backend</FormLabel>
<Select onValueChange={field.onChange} defaultValue={field.value} value={field.value}>
<FormControl>
<SelectTrigger>
<SelectTrigger className="w-[280px]">
<SelectValue placeholder="Select a backend" />
</SelectTrigger>
</FormControl>
<SelectContent>
<SelectItem value="directory">Directory</SelectItem>
<SelectItem value="nfs">NFS</SelectItem>
<SelectItem value="smb">SMB</SelectItem>
<SelectItem value="webdav">WebDAV</SelectItem>
<SelectItem value="mariadb">MariaDB</SelectItem>
<SelectItem value="mysql">MySQL</SelectItem>
<SelectItem value="postgres">PostgreSQL</SelectItem>
<SelectGroup>
<SelectItem value="directory">Directory</SelectItem>
</SelectGroup>
<SelectGroup>
<SelectLabel>Network Storage</SelectLabel>
<SelectItem value="nfs">NFS</SelectItem>
<SelectItem value="smb">SMB</SelectItem>
<SelectItem value="webdav">WebDAV</SelectItem>
</SelectGroup>
<SelectGroup>
<SelectLabel>Databases</SelectLabel>
<SelectItem value="mariadb">MariaDB</SelectItem>
<SelectItem value="mysql">MySQL</SelectItem>
<SelectItem value="postgres">PostgreSQL</SelectItem>
</SelectGroup>
</SelectContent>
</Select>
<FormDescription>Choose the storage backend for this volume.</FormDescription>

View File

@@ -4,12 +4,12 @@ import { useId } from "react";
import { useNavigate } from "react-router";
import { toast } from "sonner";
import { createVolumeMutation } from "~/client/api-client/@tanstack/react-query.gen";
import { CreateVolumeForm, type FormValues } from "~/client/components/create-volume-form";
import { Button } from "~/client/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "~/client/components/ui/card";
import { parseError } from "~/client/lib/errors";
import type { Route } from "./+types/create-volume";
import { Alert, AlertDescription } from "~/client/components/ui/alert";
import { CreateVolumeForm, type FormValues } from "../components/create-volume-form";
export const handle = {
breadcrumb: () => [{ label: "Volumes", href: "/volumes" }, { label: "Create" }],

View File

@@ -1,7 +1,6 @@
import { useMutation } from "@tanstack/react-query";
import { useState } from "react";
import { toast } from "sonner";
import { CreateVolumeForm, type FormValues } from "~/client/components/create-volume-form";
import {
AlertDialog,
AlertDialogAction,
@@ -17,6 +16,7 @@ import type { StatFs, Volume } from "~/client/lib/types";
import { HealthchecksCard } from "../components/healthchecks-card";
import { StorageChart } from "../components/storage-chart";
import { updateVolumeMutation } from "~/client/api-client/@tanstack/react-query.gen";
import { CreateVolumeForm, type FormValues } from "../components/create-volume-form";
type Props = {
volume: Volume;