Skip to content

Commit bf7bcc2

Browse files
Enhance project settings and webhooks functionality
- Introduced default values for project details in the project settings dialog. - Added a 'disabled' state to webhooks endpoints, improving status visibility in the UI. - Updated the SmartForm component to support default values and handle form resets more effectively.
1 parent c4d68dd commit bf7bcc2

4 files changed

Lines changed: 44 additions & 10 deletions

File tree

apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/project-settings/page-client.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,11 @@ export default function PageClient() {
168168
await project.update(values);
169169
}, [project]);
170170

171+
const projectDetailsDefaultValues = useMemo(() => ({
172+
displayName: project.displayName,
173+
description: project.description || undefined,
174+
}), [project.displayName, project.description]);
175+
171176
// Memoize project delete callback
172177
const handleProjectDelete = useCallback(async () => {
173178
await project.delete();
@@ -272,6 +277,7 @@ export default function PageClient() {
272277
onOpenChange={setIsProjectDetailsDialogOpen}
273278
title="Edit Project Details"
274279
formSchema={projectInformationSchema}
280+
defaultValues={projectDetailsDefaultValues}
275281
onSubmit={handleProjectDetailsSubmit}
276282
okButton={{ label: "Save" }}
277283
cancelButton

apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/webhooks/page-client.tsx

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ type Endpoint = {
7474
id: string,
7575
url: string,
7676
description?: string,
77+
disabled: boolean,
7778
};
7879

7980
function CreateDialog(props: {
@@ -114,6 +115,7 @@ function CreateDialog(props: {
114115
id: created.id,
115116
url: created.url,
116117
description: created.description,
118+
disabled: created.disabled ?? false,
117119
});
118120
});
119121

@@ -415,10 +417,10 @@ function Endpoints(props: { updateFn: () => void, onTestRequested: (endpoint: En
415417
{
416418
id: "status",
417419
header: "Status",
418-
cell: () => (
420+
cell: ({ row }) => (
419421
<DesignBadge
420-
label="Active"
421-
color="green"
422+
label={row.original.disabled ? "Disabled" : "Active"}
423+
color={row.original.disabled ? "red" : "green"}
422424
size="sm"
423425
/>
424426
),
@@ -438,6 +440,12 @@ function Endpoints(props: { updateFn: () => void, onTestRequested: (endpoint: En
438440
},
439441
];
440442

443+
const endpointRows: Endpoint[] = endpoints.data.map((endpoint) => ({
444+
...endpoint,
445+
description: endpoint.description,
446+
disabled: endpoint.disabled ?? false,
447+
}));
448+
441449
return (
442450
<DesignCard
443451
title="Endpoints"
@@ -453,7 +461,7 @@ function Endpoints(props: { updateFn: () => void, onTestRequested: (endpoint: En
453461
)}
454462
>
455463
<DesignDataTable
456-
data={endpoints.data}
464+
data={endpointRows}
457465
columns={columns}
458466
defaultColumnFilters={[]}
459467
defaultSorting={[]}

apps/dashboard/src/components/form-dialog.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { SmartForm } from "./smart-form";
1111
export function SmartFormDialog<S extends yup.ObjectSchema<any, any, any, any>>(
1212
props: Omit<ActionDialogProps, 'children'> & {
1313
formSchema: S,
14+
defaultValues?: Partial<yup.InferType<S>>,
1415
onSubmit: (values: yup.InferType<S>) => Promise<void | 'prevent-close'> | void | 'prevent-close',
1516
},
1617
) {
@@ -45,7 +46,14 @@ export function SmartFormDialog<S extends yup.ObjectSchema<any, any, any, any>>(
4546
},
4647
}}
4748
>
48-
<SmartForm formSchema={props.formSchema} onSubmit={handleSubmit} onChangeIsSubmitting={setSubmitting} formId={formId} />
49+
<SmartForm
50+
formSchema={props.formSchema}
51+
onSubmit={handleSubmit}
52+
onChangeIsSubmitting={setSubmitting}
53+
formId={formId}
54+
defaultValues={props.defaultValues}
55+
isOpen={props.open ?? openState}
56+
/>
4957
</ActionDialog>
5058
);
5159
}

apps/dashboard/src/components/smart-form.tsx

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { yupResolver } from "@hookform/resolvers/yup";
44
import { StackAssertionError } from "@stackframe/stack-shared/dist/utils/errors";
55
import { runAsynchronously } from "@stackframe/stack-shared/dist/utils/promises";
66
import { Form } from "@/components/ui";
7-
import React, { useCallback, useState } from "react";
7+
import React, { useCallback, useEffect, useRef, useState } from "react";
88
import { useForm } from "react-hook-form";
99
import * as yup from "yup";
1010
import { CheckboxField, DateField, InputField, NumberField, TextAreaField } from "./form-fields";
@@ -26,10 +26,13 @@ export function SmartForm<S extends yup.ObjectSchema<any>>(props: {
2626
onSubmit: (values: yup.InferType<S>) => Promise<void>,
2727
formId?: string,
2828
onChangeIsSubmitting?: (isSubmitting: boolean) => void,
29+
defaultValues?: Partial<yup.InferType<S>>,
30+
isOpen?: boolean,
2931
}) {
32+
const resolvedDefaultValues = props.defaultValues ?? props.formSchema.getDefault();
3033
const form = useForm({
3134
resolver: yupResolver(props.formSchema),
32-
defaultValues: props.formSchema.getDefault(),
35+
defaultValues: resolvedDefaultValues,
3336
mode: "onChange",
3437
});
3538
const [isSubmitting, setIsSubmitting] = useState(false);
@@ -40,16 +43,25 @@ export function SmartForm<S extends yup.ObjectSchema<any>>(props: {
4043
await form.handleSubmit(async (values: yup.InferType<S>, e?: React.BaseSyntheticEvent) => {
4144
e!.preventDefault();
4245
await props.onSubmit(values);
43-
form.reset();
46+
form.reset(resolvedDefaultValues);
4447
})(e);
4548
} finally {
4649
props.onChangeIsSubmitting?.(false);
4750
setIsSubmitting(false);
4851
}
49-
}, [props, form]);
52+
}, [props, form, resolvedDefaultValues]);
53+
54+
const prevOpen = useRef(props.isOpen ?? false);
55+
useEffect(() => {
56+
const currentOpen = props.isOpen ?? false;
57+
if (currentOpen && !prevOpen.current) {
58+
form.reset(resolvedDefaultValues);
59+
}
60+
prevOpen.current = currentOpen;
61+
}, [props.isOpen, resolvedDefaultValues, form]);
5062

5163
const details = props.formSchema.describe();
52-
const defaults = props.formSchema.getDefault();
64+
const defaults = resolvedDefaultValues;
5365

5466
return (
5567
<Form {...form}>

0 commit comments

Comments
 (0)