* hide the widget names * blocking multiselect in comment mode * wrapped the name * the latest comment will be on top * isolated a condition for selection canvas * added unresolve tooltip * added resolved thread tooltip * updated sorted comment cards when user gets the update/insert/delete events
129 lines
4.2 KiB
TypeScript
129 lines
4.2 KiB
TypeScript
import React, { useEffect, useMemo } from "react";
|
|
import { useDispatch, useSelector } from "react-redux";
|
|
import styled from "styled-components";
|
|
|
|
import {
|
|
allCommentThreadsMap,
|
|
appCommentsFilter as appCommentsFilterSelector,
|
|
applicationCommentsSelector,
|
|
getAppCommentThreads,
|
|
getCommentThreadsFetched,
|
|
getSortedAndFilteredAppCommentThreadIds,
|
|
shouldShowResolved as shouldShowResolvedSelector,
|
|
getLastUpdatedCommentThreadId,
|
|
getUnreadCommentsCount,
|
|
} from "selectors/commentsSelectors";
|
|
import { getCurrentApplicationId } from "selectors/editorSelectors";
|
|
|
|
import CommentThread from "comments/CommentThread/connectedCommentThread";
|
|
import AppCommentsPlaceholder from "./AppCommentsPlaceholder";
|
|
import { getCurrentUser } from "selectors/usersSelectors";
|
|
|
|
import { Virtuoso } from "react-virtuoso";
|
|
import { setShouldShowResolvedComments } from "actions/commentActions";
|
|
import { useSelectCommentThreadUsingQuery } from "../inlineComments/Comments";
|
|
import { Toaster } from "components/ads/Toast";
|
|
import { Variant } from "components/ads/common";
|
|
import { COMMENT_HAS_BEEN_DELETED, createMessage } from "constants/messages";
|
|
|
|
const Container = styled.div`
|
|
display: flex;
|
|
flex-direction: column;
|
|
flex: 1;
|
|
overflow: auto;
|
|
`;
|
|
|
|
export const useSortedCommentThreadIds = (commentThreadIds: string[]) => {
|
|
const commentThreadsMap = useSelector(allCommentThreadsMap);
|
|
const shouldShowResolved = useSelector(shouldShowResolvedSelector);
|
|
const appCommentsFilter = useSelector(appCommentsFilterSelector);
|
|
|
|
const currentUser = useSelector(getCurrentUser);
|
|
const currentUsername = currentUser?.username;
|
|
const unreadCommentsCount = useSelector(getUnreadCommentsCount);
|
|
const lastUpdatedCommentThreadId = useSelector(getLastUpdatedCommentThreadId);
|
|
|
|
return useMemo(
|
|
() =>
|
|
getSortedAndFilteredAppCommentThreadIds(
|
|
commentThreadIds,
|
|
commentThreadsMap,
|
|
shouldShowResolved,
|
|
appCommentsFilter,
|
|
currentUsername,
|
|
),
|
|
[
|
|
commentThreadIds,
|
|
commentThreadsMap,
|
|
shouldShowResolved,
|
|
appCommentsFilter,
|
|
currentUsername,
|
|
lastUpdatedCommentThreadId,
|
|
unreadCommentsCount,
|
|
],
|
|
);
|
|
};
|
|
|
|
function AppCommentThreads() {
|
|
const dispatch = useDispatch();
|
|
const commentThreadIdFromUrl = useSelectCommentThreadUsingQuery();
|
|
const applicationId = useSelector(getCurrentApplicationId) as string;
|
|
const appCommentThreadsByRefMap = useSelector(
|
|
applicationCommentsSelector(applicationId),
|
|
);
|
|
const appCommentThreadIds = getAppCommentThreads(appCommentThreadsByRefMap);
|
|
|
|
const commentThreadIds = useSortedCommentThreadIds(appCommentThreadIds);
|
|
|
|
const commentThreadsMap = useSelector(allCommentThreadsMap);
|
|
|
|
// TODO (rishabh s) Update this when adding pagination to comments
|
|
const appCommentThreadsFetched = useSelector(getCommentThreadsFetched);
|
|
|
|
useEffect(() => {
|
|
// if user is visiting a comment thread link which is already resolved,
|
|
// we'll activate the resolved comments filter
|
|
if (commentThreadIdFromUrl && appCommentThreadsFetched) {
|
|
const commentInStore = commentThreadsMap[commentThreadIdFromUrl];
|
|
|
|
if (commentInStore) {
|
|
if (commentInStore.resolvedState?.active) {
|
|
dispatch(setShouldShowResolvedComments(true));
|
|
}
|
|
} else {
|
|
Toaster.show({
|
|
text: createMessage(COMMENT_HAS_BEEN_DELETED),
|
|
variant: Variant.warning,
|
|
});
|
|
}
|
|
}
|
|
}, [commentThreadIdFromUrl, appCommentThreadsFetched]);
|
|
|
|
return (
|
|
<Container>
|
|
{commentThreadIds.length > 0 && (
|
|
<Virtuoso
|
|
data={commentThreadIds}
|
|
itemContent={(_index, commentThreadId) => (
|
|
/** Keeping this as a fail safe: since zero
|
|
* height elements throw an error
|
|
* */
|
|
<div style={{ minHeight: 1 }}>
|
|
<CommentThread
|
|
commentThreadId={commentThreadId}
|
|
hideChildren
|
|
hideInput
|
|
key={commentThreadId}
|
|
showSubheader
|
|
/>
|
|
</div>
|
|
)}
|
|
/>
|
|
)}
|
|
{commentThreadIds.length === 0 && <AppCommentsPlaceholder />}
|
|
</Container>
|
|
);
|
|
}
|
|
|
|
export default AppCommentThreads;
|