mirror of
https://github.com/formbricks/formbricks.git
synced 2026-04-24 06:28:49 -05:00
Improve Tags UI/UX (#563)
* fix: fixes tag merging logic * fix: moves tag merge logic into transactions * update tags settings icon --------- Co-authored-by: Johannes <johannes@formbricks.com>
This commit is contained in:
+13
-2
@@ -6,8 +6,9 @@ import { useTagsForEnvironment } from "@/lib/tags/tags";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { toast } from "react-hot-toast";
|
||||
import { Tag } from "./Tag";
|
||||
import { ExclamationCircleIcon } from "@heroicons/react/24/solid";
|
||||
import { ExclamationCircleIcon, Cog6ToothIcon } from "@heroicons/react/24/solid";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { Button } from "@formbricks/ui";
|
||||
|
||||
interface ResponseTagsWrapperProps {
|
||||
tags: {
|
||||
@@ -57,7 +58,7 @@ const ResponseTagsWrapper: React.FC<ResponseTagsWrapperProps> = ({
|
||||
}, [tagIdToHighlight]);
|
||||
|
||||
return (
|
||||
<div className="flex items-start gap-3 p-6">
|
||||
<div className="flex items-center justify-between gap-3 p-6">
|
||||
<div className="flex flex-wrap items-center gap-2">
|
||||
{tagsState?.map((tag) => (
|
||||
<Tag
|
||||
@@ -159,6 +160,16 @@ const ResponseTagsWrapper: React.FC<ResponseTagsWrapperProps> = ({
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Button
|
||||
variant="minimal"
|
||||
size="sm"
|
||||
className="cursor-pointer p-0"
|
||||
onClick={() => {
|
||||
router.push(`/environments/${environmentId}/settings/tags`);
|
||||
}}>
|
||||
<Cog6ToothIcon className="h-5 w-5 text-slate-300 hover:text-slate-400" />
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
+1
-2
@@ -34,7 +34,7 @@ export function Tag({
|
||||
<div
|
||||
key={tagId}
|
||||
className={cn(
|
||||
"relative flex items-center justify-between gap-2 rounded-full border bg-slate-600 px-2 py-1 text-slate-100",
|
||||
"relative flex items-center justify-between gap-2 rounded-full bg-slate-600 px-2 py-1 text-slate-100",
|
||||
highlight && "animate-shake"
|
||||
)}>
|
||||
<div className="flex items-center gap-2">
|
||||
@@ -45,7 +45,6 @@ export function Tag({
|
||||
className="cursor-pointer text-sm"
|
||||
onClick={() => {
|
||||
setTagsState(tags.filter((tag) => tag.tagId !== tagId));
|
||||
|
||||
onDelete(tagId);
|
||||
}}>
|
||||
<XCircleIcon fontSize={24} className="h-4 w-4 text-slate-100 hover:text-slate-200" />
|
||||
|
||||
@@ -92,31 +92,44 @@ export default async function handle(req: NextApiRequest, res: NextApiResponse)
|
||||
|
||||
if (!!responsesWithBothTags?.length) {
|
||||
try {
|
||||
responsesWithBothTags.map(async (response) => {
|
||||
await prisma.$transaction([
|
||||
prisma.tagsOnResponses.deleteMany({
|
||||
where: {
|
||||
responseId: response.id,
|
||||
tagId: {
|
||||
in: [originalTagId, newTagId],
|
||||
await Promise.all(
|
||||
responsesWithBothTags.map(async (response) => {
|
||||
await prisma.$transaction([
|
||||
prisma.tagsOnResponses.deleteMany({
|
||||
where: {
|
||||
responseId: response.id,
|
||||
tagId: {
|
||||
in: [originalTagId, newTagId],
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
}),
|
||||
|
||||
prisma.tagsOnResponses.create({
|
||||
data: {
|
||||
responseId: response.id,
|
||||
tagId: newTagId,
|
||||
},
|
||||
}),
|
||||
]);
|
||||
});
|
||||
prisma.tagsOnResponses.create({
|
||||
data: {
|
||||
responseId: response.id,
|
||||
tagId: newTagId,
|
||||
},
|
||||
}),
|
||||
]);
|
||||
})
|
||||
);
|
||||
|
||||
await prisma.tag.delete({
|
||||
where: {
|
||||
id: originalTagId,
|
||||
},
|
||||
});
|
||||
await prisma.$transaction([
|
||||
prisma.tagsOnResponses.updateMany({
|
||||
where: {
|
||||
tagId: originalTagId,
|
||||
},
|
||||
data: {
|
||||
tagId: newTagId,
|
||||
},
|
||||
}),
|
||||
|
||||
prisma.tag.delete({
|
||||
where: {
|
||||
id: originalTagId,
|
||||
},
|
||||
}),
|
||||
]);
|
||||
|
||||
return res.json({
|
||||
success: true,
|
||||
|
||||
Reference in New Issue
Block a user