Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { getImageUrl } from "@/utils";
import getCaretCoordinates from "textarea-caret";

type Props = {
handleTagAdd: (userId: number, fullName: string) => void;
handleTagAdd: (userId: number, fullName: string, personId: number) => void;
newCommentText: string;
textAreaRef: React.RefObject<HTMLTextAreaElement | null>;
activeRowIndex: number;
Expand Down Expand Up @@ -42,7 +42,7 @@ export default function Autocomplete({

const filteredUsers = useMemo(() => {
if (userFilter === null) return;
return users?.filter((user) => user?.fullName?.toLowerCase().includes(userFilter));
return users?.filter((user) => user?.fullName?.toLowerCase().includes(userFilter) && user?.personId != null);
}, [userFilter, users]);

useEffect(() => {
Expand All @@ -55,7 +55,10 @@ export default function Autocomplete({
if (!filteredUsers) return;
const activeUser = filteredUsers[activeRowIndex];
if (activeUser) {
setOnSelectTrigger(() => () => handleTagAdd(activeUser.id, activeUser.fullName.replaceAll(/ /g, "")));
setOnSelectTrigger(() => () => {
if (activeUser.personId == null) return;
handleTagAdd(activeUser.id, activeUser.fullName.replaceAll(/ /g, ""), activeUser.personId);
});
} else {
setOnSelectTrigger(null);
}
Expand Down Expand Up @@ -83,8 +86,8 @@ export default function Autocomplete({
}
}, [activeRowIndex, filteredUsers]);

const handleUserSelect = (userId: number, fullName: string) => {
handleTagAdd(userId, fullName.replaceAll(/ /g, ""));
const handleUserSelect = (userId: number, fullName: string, personId: number) => {
handleTagAdd(userId, fullName.replaceAll(/ /g, ""), personId);
};

const resolvedAvatarUrl = (url: string | null | undefined) => {
Expand Down Expand Up @@ -127,7 +130,10 @@ export default function Autocomplete({
key={user.id}
role="option"
aria-selected={isActive}
onClick={() => handleUserSelect(user.id, user.fullName)}
onClick={() => {
if (user.personId == null) return;
handleUserSelect(user.id, user.fullName, user.personId);
}}
style={{
backgroundColor: isActive ? "var(--editableField-optionRow-selectedBg)" : "transparent",
cursor: "pointer",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ type EditState = {
text: string;
canSave: boolean;
isUpdating: boolean;
isTagFetch: boolean;
onTextChange: (text: string) => void;
onKeyPress: (e: React.KeyboardEvent<HTMLTextAreaElement>) => void;
onSave: () => void;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ type EditState = {
text: string;
canSave: boolean;
isUpdating: boolean;
isTagFetch: boolean;
onTextChange: (text: string) => void;
onKeyPress: (e: React.KeyboardEvent<HTMLTextAreaElement>) => void;
onSave: () => void;
Expand Down Expand Up @@ -86,7 +85,7 @@ export function CommentEdit({ commentId, edit }: Props) {
</EditCancelButton>
<EditSaveButton
onClick={edit.onSave}
disabled={!edit.canSave || edit.isUpdating || edit.isTagFetch}
disabled={!edit.canSave || edit.isUpdating}
data-testid={`save-edit-${commentId}`}
>
{t("dashboard.commentsSection.saveEdit")}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import { useCommentMenu } from "./hooks/useCommentMenu";
import { AddCommentButton, Container, NewCommentSection, TagOverlay, TextArea } from "./styles";
import { useCommentTag } from "./hooks/useCommentTag";
import Autocomplete from "./Autocomplete";
import { getPersonIds } from "./helpers";

type Props = {
entityId: Id;
Expand All @@ -27,7 +26,6 @@ export function EntityComments({ entityId, entityType, comments, testId }: Props
const { t } = useTranslation();
const { mutate: createComment, isPending: isCreating } = useCreateComment(entityId, entityType);
const [newCommentText, setNewCommentText] = useState("");
const [isTagFetch, setIsTagFetch] = useState(false);
const textAreaRef = useRef<HTMLTextAreaElement>(null);
const overlayRef = useRef<HTMLDivElement>(null);

Expand Down Expand Up @@ -62,16 +60,15 @@ export function EntityComments({ entityId, entityType, comments, testId }: Props
if (!newCommentText.trim()) return;

let formattedText = newCommentText;
const taggedUserIds: number[] = [];
const taggedPersonIds: number[] = [];

tags.forEach((tag) => {
formattedText = formattedText.replace(`@${tag.name}`, `<@${tag.id}>`);
if (formattedText.includes(`<@${tag.id}>`) && !taggedUserIds.includes(tag.id)) {
taggedUserIds.push(tag.id);
if (formattedText.includes(`<@${tag.id}>`) && !taggedPersonIds.includes(tag.personId)) {
taggedPersonIds.push(tag.personId);
}
});

const taggedPersonIds = await getPersonIds(taggedUserIds, setIsTagFetch, t);
createComment(
{
text: formattedText.trim(),
Expand Down Expand Up @@ -104,17 +101,16 @@ export function EntityComments({ entityId, entityType, comments, testId }: Props
if (!edit.editText.trim() || !edit.editingCommentId) return;

const currentTags = initTags(edit.editText);
const taggedUserIds: number[] = [];
const taggedPersonIds: number[] = [];

let formattedText = edit.editText;
currentTags?.forEach((tag) => {
formattedText = formattedText.replace(`@${tag.name}`, `<@${tag.id}>`);
if (formattedText.includes(`<@${tag.id}>`) && !taggedUserIds.includes(tag.id)) {
taggedUserIds.push(tag.id);
if (formattedText.includes(`<@${tag.id}>`) && !taggedPersonIds.includes(tag.personId)) {
taggedPersonIds.push(tag.personId);
}
});

const taggedPersonIds = await getPersonIds(taggedUserIds, setIsTagFetch, t);
updateComment(
{ text: formattedText.trim(), taggedPersonIds },

Expand Down Expand Up @@ -154,7 +150,6 @@ export function EntityComments({ entityId, entityType, comments, testId }: Props
text: edit.editText,
canSave: edit.canSave,
isUpdating,
isTagFetch,
onTextChange: edit.updateEditText,
onKeyPress: (e) => edit.handleKeyPress(e, handleSaveEdit),
onSave: handleSaveEdit,
Expand Down Expand Up @@ -203,7 +198,7 @@ export function EntityComments({ entityId, entityType, comments, testId }: Props
</NewCommentSection>
<AddCommentButton
onClick={handleAddComment}
disabled={!newCommentText.trim() || isCreating || isTagFetch}
disabled={!newCommentText.trim() || isCreating}
data-testid="add-comment-button"
>
{t("dashboard.commentsSection.addComment")}
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export function useCommentTag(
setNewCommentText?: (text: string) => void,
textAreaRef?: React.RefObject<HTMLTextAreaElement | null> | null,
) {
const [tags, setTags] = useState<{ id: number; name: string }[]>([]);
const [tags, setTags] = useState<{ id: number; name: string; personId: number }[]>([]);
const [showAutocomplete, setShowAutocomplete] = useState(false);
const [activeRowIndex, setActiveRowIndex] = useState(0);
const [filteredListLength, setFilteredListLength] = useState(0);
Expand Down Expand Up @@ -76,7 +76,7 @@ export function useCommentTag(
return elements;
}, [value, tags, users]);

const handleTagAdd = (userId: number, fullName: string) => {
const handleTagAdd = (userId: number, fullName: string, personId: number) => {
if (!value || !textAreaRef?.current) return null;
const cursorPosition = textAreaRef.current.selectionStart;
const textBeforeCaret = value.substring(0, cursorPosition);
Expand All @@ -85,7 +85,7 @@ export function useCommentTag(

const newText = textBeforeCaret.substring(0, lastAtIndex) + `@${fullName} ` + textAfterCaret;
setNewCommentText?.(newText);
setTags((prev) => [...prev, { id: userId, name: fullName }]);
setTags((prev) => [...prev, { id: userId, name: fullName, personId }]);
setShowAutocomplete(false);
};

Expand All @@ -112,24 +112,24 @@ export function useCommentTag(
if (!text || !users) return text;
return text.replace(/<@(\d+)>/g, (match, userId) => {
const user = users.find((u) => u.id === Number(userId));
return user ? `@${user.fullName.replaceAll(/ /g, "")}` : "@user";
return user ? `@${user.fullName.replaceAll(/ /g, "")}` : `@user:${userId}`;
});
},
[users],
);

const initTags = (value: string) => {
if (!value || !users) return;
const regexTag = /(<@\d+>)|((?<=^|\s)@[\w\s]+?)(?=\s|$)/g;
const regexTag = /(<@\d+>)|((?<=^|\s)@[\w\s]+?(?::\d+)?)(?=\s|$)/g;
const matches = Array.from(value.matchAll(regexTag));
const freshlyFoundTags: { id: number; name: string }[] = [];
const freshlyFoundTags: { id: number; name: string; personId: number }[] = [];

matches.forEach((match) => {
const username = match[0];
const user = users.find((u) => `@${u.fullName.replaceAll(/ /g, "")}` === username);
if (user) {
if (user && user.personId != null) {
const cleanName = user.fullName.replace(/\s/g, "");
freshlyFoundTags.push({ id: user.id, name: cleanName });
freshlyFoundTags.push({ id: user.id, name: cleanName, personId: user.personId });
}
});
if (freshlyFoundTags.length > 0) {
Expand Down
Loading