fix: assign tags created from the project dialog

The tag dialog's form is nested inside the project dialog's form in the
React tree, and React propagates events along the React tree rather than
the DOM tree, so submitting the tag form also submitted the project form.
The project was created immediately with no tags and the dialog closed
before more than one tag could be picked.

Stop propagation in the tag form's onSubmit, and select the new tag in
the selector so it is included when the project is saved.

Fixes #5117
This commit is contained in:
andwati
2026-08-18 14:18:39 +03:00
parent fa788b00a6
commit 0ea7de7d31
2 changed files with 27 additions and 4 deletions
@@ -53,9 +53,14 @@ type Tag = z.infer<typeof TagSchema>;
interface HandleTagProps {
tagId?: string;
/**
* Called with the new tag's id after it is created, so callers embedding
* this dialog (e.g. the tag selector) can select the tag right away.
*/
onCreated?: (tagId: string) => void;
}
export const HandleTag = ({ tagId }: HandleTagProps) => {
export const HandleTag = ({ tagId, onCreated }: HandleTagProps) => {
const utils = api.useUtils();
const [isOpen, setIsOpen] = useState(false);
const colorInputRef = useRef<HTMLInputElement>(null);
@@ -101,8 +106,11 @@ export const HandleTag = ({ tagId }: HandleTagProps) => {
color: data.color,
tagId: tagId || "",
})
.then(async () => {
.then(async (result) => {
await utils.tag.all.invalidate();
if (!tagId && result?.tagId) {
onCreated?.(result.tagId);
}
toast.success(tagId ? "Tag Updated" : "Tag Created");
setIsOpen(false);
form.reset();
@@ -139,9 +147,18 @@ export const HandleTag = ({ tagId }: HandleTagProps) => {
</DialogHeader>
{isError && <AlertBlock type="error">{error?.message}</AlertBlock>}
<Form {...form}>
{/*
* This dialog can be rendered inside another form (e.g. the tag
* selector in the project dialog). React propagates events through the
* React tree, not the DOM tree, so without stopPropagation submitting
* this form would also submit the outer one.
*/}
<form
id="hook-form-tag"
onSubmit={form.handleSubmit(onSubmit)}
onSubmit={(e) => {
e.stopPropagation();
form.handleSubmit(onSubmit)(e);
}}
className="grid w-full gap-4"
>
<FormField
@@ -147,7 +147,13 @@ export function TagSelector({
})}
</CommandGroup>
<div className="flex items-center justify-center p-2 border-t">
<HandleTag />
<HandleTag
onCreated={(tagId) => {
if (!selectedTags.includes(tagId)) {
onTagsChange([...selectedTags, tagId]);
}
}}
/>
</div>
</CommandList>
</Command>