From 3c0b33763ea657154aa790b635f2de8a0a4a20ce Mon Sep 17 00:00:00 2001 From: Pranav Kanade Date: Fri, 10 Sep 2021 16:17:17 +0530 Subject: [PATCH] fix: Collab feedback fixes (#7298) * 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 --- .../comments/AppComments/AppCommentThreads.tsx | 6 ++++++ .../src/comments/CommentCard/CommentCard.tsx | 2 ++ .../comments/CommentCard/ResolveCommentButton.tsx | 11 +++++++++-- .../WidgetNameComponent/index.tsx | 3 +++ app/client/src/constants/messages.ts | 1 + .../src/pages/Editor/WidgetsMultiSelectBox.tsx | 6 ++++-- .../src/pages/common/CanvasSelectionArena.tsx | 7 ++++++- .../uiReducers/commentsReducer/commentsReducer.ts | 1 + .../handleDeleteCommentThreadEvent.ts | 2 +- .../handleNewCommentThreadEvent.ts | 1 + .../handleUpdateCommentThreadEvent.ts | 2 +- .../uiReducers/commentsReducer/interfaces.ts | 1 + app/client/src/selectors/commentsSelectors.ts | 15 +++++++++++---- 13 files changed, 47 insertions(+), 11 deletions(-) diff --git a/app/client/src/comments/AppComments/AppCommentThreads.tsx b/app/client/src/comments/AppComments/AppCommentThreads.tsx index 11dc8311b2..15783df23b 100644 --- a/app/client/src/comments/AppComments/AppCommentThreads.tsx +++ b/app/client/src/comments/AppComments/AppCommentThreads.tsx @@ -10,6 +10,8 @@ import { getCommentThreadsFetched, getSortedAndFilteredAppCommentThreadIds, shouldShowResolved as shouldShowResolvedSelector, + getLastUpdatedCommentThreadId, + getUnreadCommentsCount, } from "selectors/commentsSelectors"; import { getCurrentApplicationId } from "selectors/editorSelectors"; @@ -38,6 +40,8 @@ export const useSortedCommentThreadIds = (commentThreadIds: string[]) => { const currentUser = useSelector(getCurrentUser); const currentUsername = currentUser?.username; + const unreadCommentsCount = useSelector(getUnreadCommentsCount); + const lastUpdatedCommentThreadId = useSelector(getLastUpdatedCommentThreadId); return useMemo( () => @@ -54,6 +58,8 @@ export const useSortedCommentThreadIds = (commentThreadIds: string[]) => { shouldShowResolved, appCommentsFilter, currentUsername, + lastUpdatedCommentThreadId, + unreadCommentsCount, ], ); }; diff --git a/app/client/src/comments/CommentCard/CommentCard.tsx b/app/client/src/comments/CommentCard/CommentCard.tsx index adc6fb6ecf..51021e84f7 100644 --- a/app/client/src/comments/CommentCard/CommentCard.tsx +++ b/app/client/src/comments/CommentCard/CommentCard.tsx @@ -91,11 +91,13 @@ const UserName = styled.span` display: -webkit-box; -webkit-line-clamp: 1; /* number of lines to show */ -webkit-box-orient: vertical; + word-break: break-word; `; const HeaderSection = styled.div` display: flex; align-items: center; + max-width: 100%; & ${Profile} { flex-shrink: 0; diff --git a/app/client/src/comments/CommentCard/ResolveCommentButton.tsx b/app/client/src/comments/CommentCard/ResolveCommentButton.tsx index a69e144b41..807b545c57 100644 --- a/app/client/src/comments/CommentCard/ResolveCommentButton.tsx +++ b/app/client/src/comments/CommentCard/ResolveCommentButton.tsx @@ -3,7 +3,11 @@ import styled, { withTheme } from "styled-components"; import Icon, { IconSize } from "components/ads/Icon"; import { Theme } from "constants/DefaultTheme"; import Tooltip from "components/ads/Tooltip"; -import { createMessage, RESOLVE_THREAD } from "constants/messages"; +import { + createMessage, + RESOLVE_THREAD, + RESOLVED_THREAD, +} from "constants/messages"; import { Colors } from "constants/Colors"; const Container = styled.div` @@ -64,7 +68,10 @@ const ResolveCommentButton = withTheme( return ( - + ` position: absolute; @@ -57,6 +58,7 @@ type WidgetNameComponentProps = { export function WidgetNameComponent(props: WidgetNameComponentProps) { const showPropertyPane = useShowPropertyPane(); const dispatch = useDispatch(); + const isCommentMode = useSelector(commentModeSelector); const isSnipingMode = useSelector(snipingModeSelector); const showTableFilterPane = useShowTableFilterPane(); // Dispatch hook handy to set a widget as focused/selected @@ -132,6 +134,7 @@ export function WidgetNameComponent(props: WidgetNameComponentProps) { selectedWidgets.includes(props.widgetId); const shouldShowWidgetName = () => { return ( + !isCommentMode && !isMultiSelectedWidget && (isSnipingMode ? focusedWidget === props.widgetId diff --git a/app/client/src/constants/messages.ts b/app/client/src/constants/messages.ts index b6d0f433e8..cab0557223 100644 --- a/app/client/src/constants/messages.ts +++ b/app/client/src/constants/messages.ts @@ -515,6 +515,7 @@ export const DOWNLOAD_FILE_NAME_ERROR = () => "File name was not provided"; export const MORE_OPTIONS = () => "More Options"; export const ADD_REACTION = () => "Add Reaction"; export const RESOLVE_THREAD = () => "Resolve Thread"; +export const RESOLVED_THREAD = () => "Resolved Thread"; export const EMOJI = () => "Emoji"; // Sniping mode messages diff --git a/app/client/src/pages/Editor/WidgetsMultiSelectBox.tsx b/app/client/src/pages/Editor/WidgetsMultiSelectBox.tsx index 09912a721d..4431b3bd4c 100644 --- a/app/client/src/pages/Editor/WidgetsMultiSelectBox.tsx +++ b/app/client/src/pages/Editor/WidgetsMultiSelectBox.tsx @@ -24,6 +24,7 @@ import { useWidgetSelection } from "utils/hooks/useWidgetSelection"; import WidgetFactory from "utils/WidgetFactory"; import { AppState } from "reducers"; import { useWidgetDragResize } from "utils/hooks/dragResizeHooks"; +import { commentModeSelector } from "selectors/commentsSelectors"; const WidgetTypes = WidgetFactory.widgetTypes; const StyledSelectionBox = styled.div` @@ -171,6 +172,7 @@ function WidgetsMultiSelectBox(props: { snapRowSpace: number; }): any { const dispatch = useDispatch(); + const isCommentMode = useSelector(commentModeSelector); const canvasWidgets = useSelector(getCanvasWidgets); const selectedWidgetIDs = useSelector(getSelectedWidgets); const selectedWidgets = selectedWidgetIDs.map( @@ -188,7 +190,7 @@ function WidgetsMultiSelectBox(props: { * 3. multiple widgets are selected */ const shouldRender = useMemo(() => { - if (isDragging) { + if (isDragging || isCommentMode) { return false; } const parentIDs = selectedWidgets @@ -203,7 +205,7 @@ function WidgetsMultiSelectBox(props: { hasCommonParent && get(selectedWidgets, "0.parentId") === props.widgetId ); - }, [selectedWidgets, isDragging]); + }, [selectedWidgets, isDragging, isCommentMode]); const draggableRef = useRef(null); const { setDraggingState } = useWidgetDragResize(); diff --git a/app/client/src/pages/common/CanvasSelectionArena.tsx b/app/client/src/pages/common/CanvasSelectionArena.tsx index 7f1b26c605..10d93570a8 100644 --- a/app/client/src/pages/common/CanvasSelectionArena.tsx +++ b/app/client/src/pages/common/CanvasSelectionArena.tsx @@ -19,6 +19,7 @@ import { useCanvasDragToScroll } from "utils/hooks/useCanvasDragToScroll"; import { MAIN_CONTAINER_WIDGET_ID } from "constants/WidgetConstants"; import { XYCord } from "utils/hooks/useCanvasDragging"; import { theme } from "constants/DefaultTheme"; +import { commentModeSelector } from "../../selectors/commentsSelectors"; const StyledSelectionCanvas = styled.canvas` position: absolute; @@ -56,6 +57,7 @@ export function CanvasSelectionArena({ snapRowSpace: number; }) { const dispatch = useDispatch(); + const isCommentMode = useSelector(commentModeSelector); const canvasRef = React.useRef(null); const parentWidget = useSelector((state: AppState) => getWidget(state, parentId || ""), @@ -439,7 +441,10 @@ export function CanvasSelectionArena({ snapRowSpace, ]); - return appMode === APP_MODE.EDIT && !(isDragging || isResizing) ? ( + const shouldShow = + appMode === APP_MODE.EDIT && !(isDragging || isResizing || isCommentMode); + + return shouldShow ? ( ; commentThreadsFetched: boolean; + lastUpdatedCommentThreadId: string | null; } diff --git a/app/client/src/selectors/commentsSelectors.ts b/app/client/src/selectors/commentsSelectors.ts index c38186b076..0ea5aabc8d 100644 --- a/app/client/src/selectors/commentsSelectors.ts +++ b/app/client/src/selectors/commentsSelectors.ts @@ -99,18 +99,20 @@ export const getSortedAndFilteredAppCommentThreadIds = ( if (!commentThreadsMap[a] || !commentThreadsMap[b]) return -1; const { + isViewed: isAViewed, pinnedState: isAPinned, updationTime: updationTimeA, } = commentThreadsMap[a]; const { + isViewed: isBViewed, pinnedState: isBPinned, updationTime: updationTimeB, } = commentThreadsMap[b]; - const sortIdx = getSortIndexBool( - !!isAPinned?.active, - !!isBPinned?.active, - ); + let sortIdx = getSortIndexBool(!!isAPinned?.active, !!isBPinned?.active); + if (sortIdx !== 0) return sortIdx; + + sortIdx = getSortIndexBool(!!isBViewed, !!isAViewed); if (sortIdx !== 0) return sortIdx; const result = getSortIndexTime(updationTimeA, updationTimeB); @@ -145,6 +147,11 @@ export const getSortedAndFilteredAppCommentThreadIds = ( return result; }; +export const getUnreadCommentsCount = (state: AppState) => + state.ui.comments.unreadCommentThreadsCount; + +export const getLastUpdatedCommentThreadId = (state: AppState) => + state.ui.comments.lastUpdatedCommentThreadId; export const shouldShowResolved = (state: AppState) => state.ui.comments.shouldShowResolvedAppCommentThreads;