forked from github/plane
[WEB-720] chore: reaction tooltip added (#3945)
* chore: reaction tooltip added * chore: reaction tooltip updated * chore: issue reaction tooltip updated * chore: helper function updated
This commit is contained in:
parent
c97b994311
commit
8aca74c68d
@ -1,10 +1,11 @@
|
||||
import { FC, useMemo } from "react";
|
||||
import { observer } from "mobx-react-lite";
|
||||
// components
|
||||
import { TOAST_TYPE, setToast } from "@plane/ui";
|
||||
import { TOAST_TYPE, Tooltip, setToast } from "@plane/ui";
|
||||
import { renderEmoji } from "helpers/emoji.helper";
|
||||
import { useIssueDetail } from "hooks/store";
|
||||
// ui
|
||||
import { useIssueDetail, useMember } from "hooks/store";
|
||||
// helper
|
||||
import { formatTextList } from "helpers/issue.helper";
|
||||
// types
|
||||
import { IUser } from "@plane/types";
|
||||
import { ReactionSelector } from "./reaction-selector";
|
||||
@ -21,10 +22,11 @@ export const IssueCommentReaction: FC<TIssueCommentReaction> = observer((props)
|
||||
|
||||
// hooks
|
||||
const {
|
||||
commentReaction: { getCommentReactionsByCommentId, commentReactionsByUser },
|
||||
commentReaction: { getCommentReactionsByCommentId, commentReactionsByUser, getCommentReactionById },
|
||||
createCommentReaction,
|
||||
removeCommentReaction,
|
||||
} = useIssueDetail();
|
||||
const { getUserDetails } = useMember();
|
||||
|
||||
const reactionIds = getCommentReactionsByCommentId(commentId);
|
||||
const userReactions = commentReactionsByUser(commentId, currentUser.id).map((r) => r.reaction);
|
||||
@ -73,6 +75,17 @@ export const IssueCommentReaction: FC<TIssueCommentReaction> = observer((props)
|
||||
[workspaceSlug, projectId, commentId, currentUser, createCommentReaction, removeCommentReaction, userReactions]
|
||||
);
|
||||
|
||||
const getReactionUsers = (reaction: string): string => {
|
||||
const reactionUsers = (reactionIds?.[reaction] || [])
|
||||
.map((reactionId) => {
|
||||
const reactionDetails = getCommentReactionById(reactionId);
|
||||
return reactionDetails ? getUserDetails(reactionDetails.actor)?.display_name : null;
|
||||
})
|
||||
.filter((displayName): displayName is string => !!displayName);
|
||||
const formattedUsers = formatTextList(reactionUsers);
|
||||
return formattedUsers;
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="mt-4 relative flex items-center gap-1.5">
|
||||
<ReactionSelector
|
||||
@ -87,19 +100,21 @@ export const IssueCommentReaction: FC<TIssueCommentReaction> = observer((props)
|
||||
(reaction) =>
|
||||
reactionIds[reaction]?.length > 0 && (
|
||||
<>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => issueCommentReactionOperations.react(reaction)}
|
||||
key={reaction}
|
||||
className={`flex h-full items-center gap-1 rounded-md px-2 py-1 text-sm text-custom-text-100 ${
|
||||
userReactions.includes(reaction) ? "bg-custom-primary-100/10" : "bg-custom-background-80"
|
||||
}`}
|
||||
>
|
||||
<span>{renderEmoji(reaction)}</span>
|
||||
<span className={userReactions.includes(reaction) ? "text-custom-primary-100" : ""}>
|
||||
{(reactionIds || {})[reaction].length}{" "}
|
||||
</span>
|
||||
</button>
|
||||
<Tooltip tooltipContent={getReactionUsers(reaction)}>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => issueCommentReactionOperations.react(reaction)}
|
||||
key={reaction}
|
||||
className={`flex h-full items-center gap-1 rounded-md px-2 py-1 text-sm text-custom-text-100 ${
|
||||
userReactions.includes(reaction) ? "bg-custom-primary-100/10" : "bg-custom-background-80"
|
||||
}`}
|
||||
>
|
||||
<span>{renderEmoji(reaction)}</span>
|
||||
<span className={userReactions.includes(reaction) ? "text-custom-primary-100" : ""}>
|
||||
{(reactionIds || {})[reaction].length}{" "}
|
||||
</span>
|
||||
</button>
|
||||
</Tooltip>
|
||||
</>
|
||||
)
|
||||
)}
|
||||
|
@ -1,10 +1,12 @@
|
||||
import { FC, useMemo } from "react";
|
||||
import { observer } from "mobx-react-lite";
|
||||
// components
|
||||
import { TOAST_TYPE, setToast } from "@plane/ui";
|
||||
import { renderEmoji } from "helpers/emoji.helper";
|
||||
import { useIssueDetail } from "hooks/store";
|
||||
// hooks
|
||||
import { useIssueDetail, useMember } from "hooks/store";
|
||||
// ui
|
||||
import { TOAST_TYPE, Tooltip, setToast } from "@plane/ui";
|
||||
// helpers
|
||||
import { renderEmoji } from "helpers/emoji.helper";
|
||||
import { formatTextList } from "helpers/issue.helper";
|
||||
// types
|
||||
import { IUser } from "@plane/types";
|
||||
import { ReactionSelector } from "./reaction-selector";
|
||||
@ -20,10 +22,11 @@ export const IssueReaction: FC<TIssueReaction> = observer((props) => {
|
||||
const { workspaceSlug, projectId, issueId, currentUser } = props;
|
||||
// hooks
|
||||
const {
|
||||
reaction: { getReactionsByIssueId, reactionsByUser },
|
||||
reaction: { getReactionsByIssueId, reactionsByUser, getReactionById },
|
||||
createReaction,
|
||||
removeReaction,
|
||||
} = useIssueDetail();
|
||||
const { getUserDetails } = useMember();
|
||||
|
||||
const reactionIds = getReactionsByIssueId(issueId);
|
||||
const userReactions = reactionsByUser(issueId, currentUser.id).map((r) => r.reaction);
|
||||
@ -72,6 +75,18 @@ export const IssueReaction: FC<TIssueReaction> = observer((props) => {
|
||||
[workspaceSlug, projectId, issueId, currentUser, createReaction, removeReaction, userReactions]
|
||||
);
|
||||
|
||||
const getReactionUsers = (reaction: string): string => {
|
||||
const reactionUsers = (reactionIds?.[reaction] || [])
|
||||
.map((reactionId) => {
|
||||
const reactionDetails = getReactionById(reactionId);
|
||||
return reactionDetails ? getUserDetails(reactionDetails.actor_id)?.display_name : null;
|
||||
})
|
||||
.filter((displayName): displayName is string => !!displayName);
|
||||
|
||||
const formattedUsers = formatTextList(reactionUsers);
|
||||
return formattedUsers;
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="mt-4 relative flex items-center gap-1.5">
|
||||
<ReactionSelector size="md" position="top" value={userReactions} onSelect={issueReactionOperations.react} />
|
||||
@ -81,19 +96,21 @@ export const IssueReaction: FC<TIssueReaction> = observer((props) => {
|
||||
(reaction) =>
|
||||
reactionIds[reaction]?.length > 0 && (
|
||||
<>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => issueReactionOperations.react(reaction)}
|
||||
key={reaction}
|
||||
className={`flex h-full items-center gap-1 rounded-md px-2 py-1 text-sm text-custom-text-100 ${
|
||||
userReactions.includes(reaction) ? "bg-custom-primary-100/10" : "bg-custom-background-80"
|
||||
}`}
|
||||
>
|
||||
<span>{renderEmoji(reaction)}</span>
|
||||
<span className={userReactions.includes(reaction) ? "text-custom-primary-100" : ""}>
|
||||
{(reactionIds || {})[reaction].length}{" "}
|
||||
</span>
|
||||
</button>
|
||||
<Tooltip tooltipContent={getReactionUsers(reaction)}>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => issueReactionOperations.react(reaction)}
|
||||
key={reaction}
|
||||
className={`flex h-full items-center gap-1 rounded-md px-2 py-1 text-sm text-custom-text-100 ${
|
||||
userReactions.includes(reaction) ? "bg-custom-primary-100/10" : "bg-custom-background-80"
|
||||
}`}
|
||||
>
|
||||
<span>{renderEmoji(reaction)}</span>
|
||||
<span className={userReactions.includes(reaction) ? "text-custom-primary-100" : ""}>
|
||||
{(reactionIds || {})[reaction].length}{" "}
|
||||
</span>
|
||||
</button>
|
||||
</Tooltip>
|
||||
</>
|
||||
)
|
||||
)}
|
||||
|
@ -184,3 +184,21 @@ export function getChangedIssuefields(formData: Partial<TIssue>, dirtyFields: {
|
||||
|
||||
return changedFields;
|
||||
}
|
||||
|
||||
export const formatTextList = (TextArray: string[]): string => {
|
||||
const count = TextArray.length;
|
||||
switch (count) {
|
||||
case 0:
|
||||
return "";
|
||||
case 1:
|
||||
return TextArray[0];
|
||||
case 2:
|
||||
return `${TextArray[0]} and ${TextArray[1]}`;
|
||||
case 3:
|
||||
return `${TextArray.slice(0, 2).join(", ")}, and ${TextArray[2]}`;
|
||||
case 4:
|
||||
return `${TextArray.slice(0, 3).join(", ")}, and ${TextArray[3]}`;
|
||||
default:
|
||||
return `${TextArray.slice(0, 3).join(", ")}, and +${count - 3} more`;
|
||||
}
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user