From 621761aeb67e4511527644f8910dbcfd7325e675 Mon Sep 17 00:00:00 2001 From: Adekabang Date: Thu, 31 Jul 2025 15:42:59 -0400 Subject: [PATCH] feat: update bucket types and management logic for website access and quotas - Refactored `Bucket` and `UpdateBucket` types to include detailed website configuration and quota properties. - Updated hooks to utilize the new `UpdateBucket` type for mutation functions. - Adjusted form schemas and management logic to reflect changes in website access and quota handling. - Enhanced default values and reset logic in forms for better user experience. --- src/pages/buckets/manage/hooks.ts | 9 ++-- .../manage/overview/overview-quota.tsx | 37 ++++++++----- .../overview/overview-website-access.tsx | 53 ++++++++++++------- src/pages/buckets/manage/schema.ts | 5 +- src/pages/buckets/types.ts | 28 ++++++++-- 5 files changed, 89 insertions(+), 43 deletions(-) diff --git a/src/pages/buckets/manage/hooks.ts b/src/pages/buckets/manage/hooks.ts index eb6e8fe..f3812f0 100644 --- a/src/pages/buckets/manage/hooks.ts +++ b/src/pages/buckets/manage/hooks.ts @@ -5,7 +5,7 @@ import { UseMutationOptions, useQuery, } from "@tanstack/react-query"; -import { Bucket, Permissions } from "../types"; +import { Bucket, Permissions, UpdateBucket } from "../types"; export const useBucket = (id?: string | null) => { return useQuery({ @@ -17,8 +17,11 @@ export const useBucket = (id?: string | null) => { export const useUpdateBucket = (id?: string | null) => { return useMutation({ - mutationFn: (values: Partial) => { - return api.put("/v2/UpdateBucket", { params: { id }, body: values }); + mutationFn: (values: Partial) => { + return api.post("/v2/UpdateBucket", { + params: { id }, + body: values, + }); }, }); }; diff --git a/src/pages/buckets/manage/overview/overview-quota.tsx b/src/pages/buckets/manage/overview/overview-quota.tsx index 9b0061b..0c83e8f 100644 --- a/src/pages/buckets/manage/overview/overview-quota.tsx +++ b/src/pages/buckets/manage/overview/overview-quota.tsx @@ -13,35 +13,48 @@ const QuotaSection = () => { const form = useForm({ resolver: zodResolver(quotaSchema), + defaultValues: { + enabled: false, + maxObjects: null, + maxSize: null, + }, }); const isEnabled = useWatch({ control: form.control, name: "enabled" }); const updateMutation = useUpdateBucket(data?.id); - const onChange = useDebounce((values: DeepPartial) => { + const handleChange = useDebounce((values: DeepPartial) => { const { enabled } = values; const maxObjects = Number(values.maxObjects); const maxSize = Math.round(Number(values.maxSize) * 1024 ** 3); - const data = { + const quotaData = { maxObjects: enabled && maxObjects > 0 ? maxObjects : null, maxSize: enabled && maxSize > 0 ? maxSize : null, }; - updateMutation.mutate({ quotas: data }); + updateMutation.mutate({ quotas: quotaData }); }); + // Reset form when data changes without triggering watch useEffect(() => { - form.reset({ - enabled: - data?.quotas?.maxSize != null || data?.quotas?.maxObjects != null, - maxSize: data?.quotas?.maxSize ? data?.quotas?.maxSize / 1024 ** 3 : null, - maxObjects: data?.quotas?.maxObjects || null, - }); + if (!data) return; - const { unsubscribe } = form.watch((values) => onChange(values)); - return unsubscribe; - }, [data]); + const formValues = { + enabled: + data.quotas?.maxSize != null || data.quotas?.maxObjects != null, + maxSize: data.quotas?.maxSize ? data.quotas?.maxSize / 1024 ** 3 : null, + maxObjects: data.quotas?.maxObjects || null, + }; + + form.reset(formValues, { keepDirty: false }); + }, [data, form]); + + // Set up form watcher + useEffect(() => { + const subscription = form.watch(handleChange); + return () => subscription.unsubscribe(); + }, [form, handleChange]); return (
diff --git a/src/pages/buckets/manage/overview/overview-website-access.tsx b/src/pages/buckets/manage/overview/overview-website-access.tsx index d7691df..ddcd1f4 100644 --- a/src/pages/buckets/manage/overview/overview-website-access.tsx +++ b/src/pages/buckets/manage/overview/overview-website-access.tsx @@ -16,6 +16,11 @@ const WebsiteAccessSection = () => { const { data: config } = useConfig(); const form = useForm({ resolver: zodResolver(websiteConfigSchema), + defaultValues: { + websiteAccess: false, + indexDocument: "index.html", + errorDocument: "error/400.html", + }, }); const isEnabled = useWatch({ control: form.control, name: "websiteAccess" }); @@ -24,38 +29,46 @@ const WebsiteAccessSection = () => { const updateMutation = useUpdateBucket(data?.id); - const onChange = useDebounce((values: DeepPartial) => { + const handleChange = useDebounce((values: DeepPartial) => { const websiteData = { enabled: values.websiteAccess, indexDocument: values.websiteAccess - ? values.websiteConfig?.indexDocument + ? values.indexDocument : undefined, errorDocument: values.websiteAccess - ? values.websiteConfig?.errorDocument + ? values.errorDocument : undefined, }; updateMutation.mutate({ - websiteAccess: values.websiteAccess, - websiteConfig: values.websiteAccess && websiteData.indexDocument && websiteData.errorDocument ? { - indexDocument: websiteData.indexDocument, - errorDocument: websiteData.errorDocument, - } : null, + websiteAccess: { + enabled: values.websiteAccess ?? false, + indexDocument: values.websiteAccess + ? websiteData.indexDocument ?? "index.html" + : null, + errorDocument: values.websiteAccess + ? websiteData.errorDocument ?? "error/400.html" + : null, + } }); }); + // Reset form when data changes without triggering watch useEffect(() => { - form.reset({ - websiteAccess: data?.websiteAccess, - websiteConfig: { - indexDocument: data?.websiteConfig?.indexDocument || "index.html", - errorDocument: data?.websiteConfig?.errorDocument || "error/400.html", - }, - }); + if (!data) return; - const { unsubscribe } = form.watch((values) => onChange(values)); - return unsubscribe; - }, [data, form, onChange]); + form.reset({ + websiteAccess: data?.websiteAccess ?? false, + indexDocument: data?.websiteConfig?.indexDocument || "index.html", + errorDocument: data?.websiteConfig?.errorDocument || "error/400.html", + }, { keepDirty: false }); + }, [data, form]); + + // Set up form watcher + useEffect(() => { + const subscription = form.watch(handleChange); + return () => subscription.unsubscribe(); + }, [form, handleChange]); return (
@@ -79,12 +92,12 @@ const WebsiteAccessSection = () => {
diff --git a/src/pages/buckets/manage/schema.ts b/src/pages/buckets/manage/schema.ts index 0338e17..2aae6bc 100644 --- a/src/pages/buckets/manage/schema.ts +++ b/src/pages/buckets/manage/schema.ts @@ -8,9 +8,8 @@ export type AddAliasSchema = z.infer; export const websiteConfigSchema = z.object({ websiteAccess: z.boolean(), - websiteConfig: z - .object({ indexDocument: z.string(), errorDocument: z.string() }) - .nullish(), + indexDocument: z.string().nullish(), + errorDocument: z.string().nullish(), }); export type WebsiteConfigSchema = z.infer; diff --git a/src/pages/buckets/types.ts b/src/pages/buckets/types.ts index 682da20..dbda00a 100644 --- a/src/pages/buckets/types.ts +++ b/src/pages/buckets/types.ts @@ -7,7 +7,29 @@ export type Bucket = { globalAliases: string[]; localAliases: LocalAlias[]; websiteAccess: boolean; - websiteConfig?: WebsiteConfig | null; + websiteConfig: { + indexDocument: string | null; + errorDocument: string | null; + }; + keys: Key[]; + objects: number; + bytes: number; + unfinishedUploads: number; + unfinishedMultipartUploads: number; + unfinishedMultipartUploadParts: number; + unfinishedMultipartUploadBytes: number; + quotas: Quotas; +}; + +export type UpdateBucket = { + id: string; + globalAliases: string[]; + localAliases: LocalAlias[]; + websiteAccess: { + enabled: boolean; + indexDocument: string | null; + errorDocument: string | null; + }; keys: Key[]; objects: number; bytes: number; @@ -36,10 +58,6 @@ export type Permissions = { owner: boolean; }; -export type WebsiteConfig = { - indexDocument: string; - errorDocument: string; -}; export type Quotas = { maxSize: number | null;