feat: added logic to show tags for viewer role (#2454)

This commit is contained in:
Piyush Gupta
2024-04-18 14:53:20 +05:30
committed by GitHub
parent b7299a6d31
commit e475179884
3 changed files with 92 additions and 75 deletions

View File

@@ -21,6 +21,7 @@ interface ResponseTagsWrapperProps {
responseId: string;
environmentTags: TTag[];
updateFetchedResponses: () => void;
isViewer?: boolean;
}
const ResponseTagsWrapper: React.FC<ResponseTagsWrapperProps> = ({
@@ -29,6 +30,7 @@ const ResponseTagsWrapper: React.FC<ResponseTagsWrapperProps> = ({
responseId,
environmentTags,
updateFetchedResponses,
isViewer,
}) => {
const router = useRouter();
const [searchValue, setSearchValue] = useState("");
@@ -57,15 +59,17 @@ const ResponseTagsWrapper: React.FC<ResponseTagsWrapperProps> = ({
return (
<div className="flex items-center gap-3 p-6">
<Button
variant="minimal"
size="sm"
className="cursor-pointer p-0"
onClick={() => {
router.push(`/environments/${environmentId}/settings/tags`);
}}>
<SettingsIcon className="h-5 w-5 text-slate-300 hover:text-slate-400" />
</Button>
{!isViewer && (
<Button
variant="minimal"
size="sm"
className="cursor-pointer p-0"
onClick={() => {
router.push(`/environments/${environmentId}/settings/tags`);
}}>
<SettingsIcon className="h-5 w-5 text-slate-300 hover:text-slate-400" />
</Button>
)}
<div className="flex flex-wrap items-center gap-2">
{tagsState?.map((tag) => (
<Tag
@@ -76,64 +80,67 @@ const ResponseTagsWrapper: React.FC<ResponseTagsWrapperProps> = ({
tags={tagsState}
setTagsState={setTagsState}
highlight={tagIdToHighlight === tag.tagId}
allowDelete={!isViewer}
/>
))}
<TagsCombobox
open={open}
setOpen={setOpen}
searchValue={searchValue}
setSearchValue={setSearchValue}
tags={environmentTags?.map((tag) => ({ value: tag.id, label: tag.name })) ?? []}
currentTags={tagsState.map((tag) => ({ value: tag.tagId, label: tag.tagName }))}
createTag={async (tagName) => {
await createTagAction(environmentId, tagName?.trim() ?? "")
.then((tag) => {
setTagsState((prevTags) => [
...prevTags,
{
tagId: tag.id,
tagName: tag.name,
},
]);
createTagToResponeAction(responseId, tag.id).then(() => {
updateFetchedResponses();
{!isViewer && (
<TagsCombobox
open={open}
setOpen={setOpen}
searchValue={searchValue}
setSearchValue={setSearchValue}
tags={environmentTags?.map((tag) => ({ value: tag.id, label: tag.name })) ?? []}
currentTags={tagsState.map((tag) => ({ value: tag.tagId, label: tag.tagName }))}
createTag={async (tagName) => {
await createTagAction(environmentId, tagName?.trim() ?? "")
.then((tag) => {
setTagsState((prevTags) => [
...prevTags,
{
tagId: tag.id,
tagName: tag.name,
},
]);
createTagToResponeAction(responseId, tag.id).then(() => {
updateFetchedResponses();
setSearchValue("");
setOpen(false);
});
})
.catch((err) => {
if (err?.message.includes("Unique constraint failed on the fields")) {
toast.error("Tag already exists", {
duration: 2000,
icon: <AlertCircleIcon className="h-5 w-5 text-orange-500" />,
});
} else {
toast.error(err?.message ?? "Something went wrong", {
duration: 2000,
});
}
setSearchValue("");
setOpen(false);
});
})
.catch((err) => {
if (err?.message.includes("Unique constraint failed on the fields")) {
toast.error("Tag already exists", {
duration: 2000,
icon: <AlertCircleIcon className="h-5 w-5 text-orange-500" />,
});
} else {
toast.error(err?.message ?? "Something went wrong", {
duration: 2000,
});
}
}}
addTag={(tagId) => {
setTagsState((prevTags) => [
...prevTags,
{
tagId,
tagName: environmentTags?.find((tag) => tag.id === tagId)?.name ?? "",
},
]);
createTagToResponeAction(responseId, tagId).then(() => {
updateFetchedResponses();
setSearchValue("");
setOpen(false);
});
}}
addTag={(tagId) => {
setTagsState((prevTags) => [
...prevTags,
{
tagId,
tagName: environmentTags?.find((tag) => tag.id === tagId)?.name ?? "",
},
]);
createTagToResponeAction(responseId, tagId).then(() => {
updateFetchedResponses();
setSearchValue("");
setOpen(false);
});
}}
/>
}}
/>
)}
</div>
</div>
);

View File

@@ -471,15 +471,14 @@ export default function SingleResponseCard({
)}
</div>
{user && !isViewer && (
<ResponseTagsWrapper
environmentId={environmentId}
responseId={response.id}
tags={response.tags.map((tag) => ({ tagId: tag.id, tagName: tag.name }))}
environmentTags={environmentTags}
updateFetchedResponses={updateFetchedResponses}
/>
)}
<ResponseTagsWrapper
environmentId={environmentId}
responseId={response.id}
tags={response.tags.map((tag) => ({ tagId: tag.id, tagName: tag.name }))}
environmentTags={environmentTags}
updateFetchedResponses={updateFetchedResponses}
isViewer={isViewer}
/>
<DeleteDialog
open={deleteDialogOpen}

View File

@@ -14,9 +14,18 @@ interface ResponseTagsWrapperProps {
tags?: Tag[];
setTagsState?: (tags: Tag[]) => void;
highlight?: boolean;
allowDelete?: boolean;
}
export function Tag({ tagId, tagName, onDelete, tags, setTagsState, highlight }: ResponseTagsWrapperProps) {
export function Tag({
tagId,
tagName,
onDelete,
tags,
setTagsState,
highlight,
allowDelete = true,
}: ResponseTagsWrapperProps) {
return (
<div
key={tagId}
@@ -28,14 +37,16 @@ export function Tag({ tagId, tagName, onDelete, tags, setTagsState, highlight }:
<span className="text-sm">{tagName}</span>
</div>
<span
className="cursor-pointer text-sm"
onClick={() => {
if (tags && setTagsState) setTagsState(tags.filter((tag) => tag.tagId !== tagId));
onDelete(tagId);
}}>
<XCircleIcon fontSize={24} className="h-4 w-4 text-slate-100 hover:text-slate-200" />
</span>
{allowDelete && (
<span
className="cursor-pointer text-sm"
onClick={() => {
if (tags && setTagsState) setTagsState(tags.filter((tag) => tag.tagId !== tagId));
onDelete(tagId);
}}>
<XCircleIcon fontSize={24} className="h-4 w-4 text-slate-100 hover:text-slate-200" />
</span>
)}
</div>
);
}