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
This commit is contained in:
Pranav Kanade 2021-09-10 16:17:17 +05:30 committed by GitHub
parent 594e0ef2e1
commit 3c0b33763e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 47 additions and 11 deletions

View File

@ -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,
],
);
};

View File

@ -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;

View File

@ -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 (
<Container onClick={_handleClick}>
<Tooltip content={createMessage(RESOLVE_THREAD)} hoverOpenDelay={1000}>
<Tooltip
content={createMessage(resolved ? RESOLVED_THREAD : RESOLVE_THREAD)}
hoverOpenDelay={1000}
>
<StyledResolveIcon
fillColor={fillColor}
keepColors

View File

@ -21,6 +21,7 @@ const WidgetTypes = WidgetFactory.widgetTypes;
import { snipingModeSelector } from "selectors/editorSelectors";
import { bindDataToWidget } from "../../../actions/propertyPaneActions";
import { hideErrors } from "selectors/debuggerSelectors";
import { commentModeSelector } from "../../../selectors/commentsSelectors";
const PositionStyle = styled.div<{ topRow: number; isSnipingMode: boolean }>`
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

View File

@ -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

View File

@ -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<HTMLDivElement>(null);
const { setDraggingState } = useWidgetDragResize();

View File

@ -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<HTMLCanvasElement>(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 ? (
<StyledSelectionCanvas
data-testid={`canvas-${widgetId}`}
id={`canvas-${widgetId}`}

View File

@ -45,6 +45,7 @@ const initialState: CommentsReduxState = {
draftComments: {},
unpublishedThreadDraftComment: null,
commentThreadsFetched: false,
lastUpdatedCommentThreadId: null,
};
/**

View File

@ -15,7 +15,7 @@ const handleUpdateCommentThreadEvent = (
applicationId,
);
return { ...updatedState };
return { ...updatedState, lastUpdatedCommentThreadId: commentThreadId };
};
export default handleUpdateCommentThreadEvent;

View File

@ -49,6 +49,7 @@ const handleNewCommentThreadEvent = (
return {
...state,
lastUpdatedCommentThreadId: thread.id,
showUnreadIndicator,
};
};

View File

@ -41,7 +41,7 @@ const handleUpdateCommentThreadEvent = (
const showUnreadIndicator = !state.isCommentMode;
return { ...state, showUnreadIndicator };
return { ...state, showUnreadIndicator, lastUpdatedCommentThreadId: id };
};
export default handleUpdateCommentThreadEvent;

View File

@ -23,4 +23,5 @@ export interface CommentsReduxState {
unpublishedThreadDraftComment: EditorState | null;
draftComments: Record<string, EditorState>;
commentThreadsFetched: boolean;
lastUpdatedCommentThreadId: string | null;
}

View File

@ -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;