Fix updating categories
This commit is contained in:
parent
020b75b72e
commit
cd0ac2bf43
@ -68,7 +68,11 @@ export default function CategoriesView() {
|
|||||||
>
|
>
|
||||||
<Trash size={16} color="red" />
|
<Trash size={16} color="red" />
|
||||||
</ActionButtonWithTooltip>
|
</ActionButtonWithTooltip>
|
||||||
<EditCategoryDialog categoryId={c.id} >
|
<EditCategoryDialog category={{
|
||||||
|
...c,
|
||||||
|
categoryId: c.id
|
||||||
|
}
|
||||||
|
} >
|
||||||
<ButtonWithTooltip
|
<ButtonWithTooltip
|
||||||
tooltip="Edit"
|
tooltip="Edit"
|
||||||
variant="outline"
|
variant="outline"
|
||||||
|
|||||||
@ -33,22 +33,25 @@ import { TRPCClientError } from "@trpc/client";
|
|||||||
import { useForm } from "react-hook-form";
|
import { useForm } from "react-hook-form";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
import { zCategorySchema } from "@lifetracker/shared/types/categories";
|
import { zUpdateCategoryRequestSchema, ZUpdateCategoryRequest } from "@lifetracker/shared/types/categories";
|
||||||
|
|
||||||
type CreateCategorySchema = z.infer<typeof zCategorySchema>;
|
|
||||||
|
|
||||||
export default function EditCategoryDialog({
|
export default function EditCategoryDialog({
|
||||||
|
category: initialCategory,
|
||||||
children,
|
children,
|
||||||
}: {
|
}: {
|
||||||
|
category: ZUpdateCategoryRequest;
|
||||||
children?: React.ReactNode;
|
children?: React.ReactNode;
|
||||||
}) {
|
}) {
|
||||||
const apiUtils = api.useUtils();
|
const apiUtils = api.useUtils();
|
||||||
const [isOpen, onOpenChange] = useState(false);
|
const [isOpen, onOpenChange] = useState(false);
|
||||||
const form = useForm<CreateCategorySchema>({
|
|
||||||
resolver: zodResolver(zCategorySchema),
|
const form = useForm<ZUpdateCategoryRequest>({
|
||||||
|
resolver: zodResolver(zUpdateCategoryRequestSchema),
|
||||||
|
defaultValues: initialCategory,
|
||||||
});
|
});
|
||||||
const { mutate, isPending } = api.categories.update.useMutation({
|
const { mutate, isPending } = api.categories.update.useMutation({
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
|
apiUtils.categories.list.invalidate();
|
||||||
toast({
|
toast({
|
||||||
description: "Category updated successfully",
|
description: "Category updated successfully",
|
||||||
});
|
});
|
||||||
@ -139,9 +142,9 @@ export default function EditCategoryDialog({
|
|||||||
</FormItem>
|
</FormItem>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
<FormField
|
{/* <FormField
|
||||||
control={form.control}
|
control={form.control}
|
||||||
name="color"
|
name="colorId"
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<FormItem>
|
<FormItem>
|
||||||
<FormLabel>Color</FormLabel>
|
<FormLabel>Color</FormLabel>
|
||||||
@ -156,7 +159,7 @@ export default function EditCategoryDialog({
|
|||||||
<FormMessage />
|
<FormMessage />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
)}
|
)}
|
||||||
/>
|
/> */}
|
||||||
<DialogFooter className="sm:justify-end">
|
<DialogFooter className="sm:justify-end">
|
||||||
<DialogClose asChild>
|
<DialogClose asChild>
|
||||||
<Button type="button" variant="secondary">
|
<Button type="button" variant="secondary">
|
||||||
|
|||||||
@ -32,7 +32,11 @@ export const zGetCategoryResponseSchema = z.object({
|
|||||||
export type ZGetCategoryResponse = z.infer<typeof zGetCategoryResponseSchema>;
|
export type ZGetCategoryResponse = z.infer<typeof zGetCategoryResponseSchema>;
|
||||||
|
|
||||||
export const zUpdateCategoryRequestSchema = z.object({
|
export const zUpdateCategoryRequestSchema = z.object({
|
||||||
labelId: z.string(),
|
code: z.number().nullish(),
|
||||||
code: z.number(),
|
|
||||||
name: z.string().optional(),
|
name: z.string().optional(),
|
||||||
|
description: z.string().optional(),
|
||||||
|
colorId: z.string().nullish(),
|
||||||
|
parentId: z.string().nullish(),
|
||||||
|
categoryId: z.string(),
|
||||||
});
|
});
|
||||||
|
export type ZUpdateCategoryRequest = z.infer<typeof zUpdateCategoryRequestSchema>;
|
||||||
@ -17,8 +17,9 @@ import { authedProcedure, router } from "../index";
|
|||||||
import { zColorSchema } from "@lifetracker/shared/types/colors";
|
import { zColorSchema } from "@lifetracker/shared/types/colors";
|
||||||
|
|
||||||
|
|
||||||
function conditionFromInput(input: { categoryCode: string }, userId: string) {
|
function conditionFromInput(input: { categoryCode?: string, categoryId?: string }, userId: string) {
|
||||||
return and(eq(categories.code, input.categoryCode), eq(categories.userId, userId));
|
const queryType = input.categoryCode ? eq(categories.code, input.categoryCode) : eq(categories.id, input.categoryId);
|
||||||
|
return and(queryType, eq(categories.userId, userId));
|
||||||
}
|
}
|
||||||
|
|
||||||
async function createCategory(
|
async function createCategory(
|
||||||
@ -221,55 +222,22 @@ export const categoriesAppRouter = router({
|
|||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
try {
|
console.log("Updating");
|
||||||
const res = await ctx.db
|
const res = await ctx.db
|
||||||
.update(bookmarkTags)
|
.update(categories)
|
||||||
.set({
|
.set({
|
||||||
name: input.name,
|
name: input.name,
|
||||||
|
description: input.description,
|
||||||
|
code: input.code,
|
||||||
})
|
})
|
||||||
.where(
|
.where(
|
||||||
and(
|
and(
|
||||||
eq(bookmarkTags.id, input.tagId),
|
conditionFromInput({ categoryId: input.categoryId }, ctx.user.id),
|
||||||
eq(bookmarkTags.userId, ctx.user.id),
|
eq(categories.userId, ctx.user.id),
|
||||||
),
|
),
|
||||||
)
|
).returning();
|
||||||
.returning();
|
console.log(res);
|
||||||
|
|
||||||
if (res.length == 0) {
|
|
||||||
throw new TRPCError({ code: "NOT_FOUND" });
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
const affectedBookmarks = await ctx.db.query.tagsOnBookmarks.findMany(
|
|
||||||
{
|
|
||||||
where: eq(tagsOnBookmarks.tagId, input.tagId),
|
|
||||||
columns: {
|
|
||||||
bookmarkId: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
);
|
|
||||||
await Promise.all(
|
|
||||||
affectedBookmarks
|
|
||||||
.map((b) => b.bookmarkId)
|
|
||||||
.map((id) => triggerSearchReindex(id)),
|
|
||||||
);
|
|
||||||
} catch (e) {
|
|
||||||
console.error("Something ELSE Went Wrong", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
return res[0];
|
return res[0];
|
||||||
} catch (e) {
|
|
||||||
if (e instanceof SqliteError) {
|
|
||||||
if (e.code == "SQLITE_CONSTRAINT_UNIQUE") {
|
|
||||||
throw new TRPCError({
|
|
||||||
code: "BAD_REQUEST",
|
|
||||||
message:
|
|
||||||
"Label name already exists.",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
}),
|
}),
|
||||||
delete: authedProcedure
|
delete: authedProcedure
|
||||||
.input(
|
.input(
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user