diff --git a/apps/studio/components/interfaces/Realtime/RealtimeSettings.tsx b/apps/studio/components/interfaces/Realtime/RealtimeSettings.tsx index 14062bd82ad..5781d3f5a24 100644 --- a/apps/studio/components/interfaces/Realtime/RealtimeSettings.tsx +++ b/apps/studio/components/interfaces/Realtime/RealtimeSettings.tsx @@ -85,23 +85,43 @@ export const RealtimeSettings = () => { }, }) - const FormSchema = z.object({ - connection_pool: z.coerce - .number() - .min(1) - .max(maxConn?.maxConnections ?? 100), - max_concurrent_users: z.coerce.number().min(1).max(50000), - max_events_per_second: z.coerce.number().min(1).max(10000), - max_presence_events_per_second: z.coerce.number().min(1).max(10000), - max_payload_size_in_kb: z.coerce.number().min(1).max(3000), - suspend: z.boolean(), - // [Joshen] These fields are temporarily hidden from the UI - // max_bytes_per_second: z.coerce.number().min(1).max(10000000), - // max_channels_per_client: z.coerce.number().min(1).max(10000), - // max_joins_per_second: z.coerce.number().min(1).max(5000), + const FormSchema = z.discriminatedUnion('suspend', [ + z.object({ + suspend: z.literal(true), + connection_pool: z.coerce + .number() + .min(1) + .max(maxConn?.maxConnections ?? 100) + .optional(), + max_concurrent_users: z.coerce.number().min(1).max(50000).optional(), + max_events_per_second: z.coerce.number().min(1).max(10000).optional(), + max_presence_events_per_second: z.coerce.number().min(1).max(10000).optional(), + max_payload_size_in_kb: z.coerce.number().min(1).max(3000).optional(), + // [Joshen] These fields are temporarily hidden from the UI + // max_bytes_per_second: z.coerce.number().min(1).max(10000000).optional(), + // max_channels_per_client: z.coerce.number().min(1).max(10000).optional(), + // max_joins_per_second: z.coerce.number().min(1).max(5000).optional(), - allow_public: z.boolean(), - }) + allow_public: z.boolean().optional(), + }), + z.object({ + suspend: z.literal(false), + connection_pool: z.coerce + .number() + .min(1) + .max(maxConn?.maxConnections ?? 100), + max_concurrent_users: z.coerce.number().min(1).max(50000), + max_events_per_second: z.coerce.number().min(1).max(10000), + max_presence_events_per_second: z.coerce.number().min(1).max(10000), + max_payload_size_in_kb: z.coerce.number().min(1).max(3000), + // [Joshen] These fields are temporarily hidden from the UI + // max_bytes_per_second: z.coerce.number().min(1).max(10000000), + // max_channels_per_client: z.coerce.number().min(1).max(10000), + // max_joins_per_second: z.coerce.number().min(1).max(5000), + + allow_public: z.boolean(), + }), + ]) const form = useForm>({ resolver: zodResolver(FormSchema), @@ -127,19 +147,37 @@ export const RealtimeSettings = () => { const onConfirmSave = () => { if (!projectRef) return console.error('Project ref is required') - const data = form.getValues() + const values = form.getValues() // [Joshen] Casting to `Number` here as the values are being set as string when edited in the form // and returned in form.getValues() - I might be missing some easy util function from RHF though updateRealtimeConfig({ ref: projectRef, - private_only: !data.allow_public, - connection_pool: Number(data.connection_pool), - max_concurrent_users: Number(data.max_concurrent_users), - max_events_per_second: Number(data.max_events_per_second), - max_presence_events_per_second: Number(data.max_presence_events_per_second), - max_payload_size_in_kb: Number(data.max_payload_size_in_kb), - suspend: data.suspend, + private_only: !values.allow_public, + connection_pool: Number( + values.connection_pool ?? data?.connection_pool ?? REALTIME_DEFAULT_CONFIG.connection_pool + ), + max_concurrent_users: Number( + values.max_concurrent_users ?? + data?.max_concurrent_users ?? + REALTIME_DEFAULT_CONFIG.max_concurrent_users + ), + max_events_per_second: Number( + values.max_events_per_second ?? + data?.max_events_per_second ?? + REALTIME_DEFAULT_CONFIG.max_events_per_second + ), + max_presence_events_per_second: Number( + values.max_presence_events_per_second ?? + data?.max_presence_events_per_second ?? + REALTIME_DEFAULT_CONFIG.max_presence_events_per_second + ), + max_payload_size_in_kb: Number( + values.max_payload_size_in_kb ?? + data?.max_payload_size_in_kb ?? + REALTIME_DEFAULT_CONFIG.max_payload_size_in_kb + ), + suspend: values.suspend, }) } @@ -158,12 +196,14 @@ export const RealtimeSettings = () => { render={({ field }) => ( <> field.onChange(!checked)} disabled={!canUpdateConfig} @@ -214,12 +254,14 @@ export const RealtimeSettings = () => { render={({ field }) => ( <> { render={({ field }) => ( <> { { - {!!maxConn && field.value > maxConn.maxConnections * 0.5 && ( - - )} + {!!maxConn && + field.value && + field.value > maxConn.maxConnections * 0.5 && ( + + )} )} /> @@ -302,6 +348,7 @@ export const RealtimeSettings = () => { name="max_concurrent_users" render={({ field }) => ( { { name="max_events_per_second" render={({ field }) => ( { { name="max_presence_events_per_second" render={({ field }) => ( { { name="max_payload_size_in_kb" render={({ field }) => ( {