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:
parent
594e0ef2e1
commit
3c0b33763e
|
|
@ -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,
|
||||
],
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
|
|
@ -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}`}
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ const initialState: CommentsReduxState = {
|
|||
draftComments: {},
|
||||
unpublishedThreadDraftComment: null,
|
||||
commentThreadsFetched: false,
|
||||
lastUpdatedCommentThreadId: null,
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ const handleUpdateCommentThreadEvent = (
|
|||
applicationId,
|
||||
);
|
||||
|
||||
return { ...updatedState };
|
||||
return { ...updatedState, lastUpdatedCommentThreadId: commentThreadId };
|
||||
};
|
||||
|
||||
export default handleUpdateCommentThreadEvent;
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ const handleNewCommentThreadEvent = (
|
|||
|
||||
return {
|
||||
...state,
|
||||
lastUpdatedCommentThreadId: thread.id,
|
||||
showUnreadIndicator,
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ const handleUpdateCommentThreadEvent = (
|
|||
|
||||
const showUnreadIndicator = !state.isCommentMode;
|
||||
|
||||
return { ...state, showUnreadIndicator };
|
||||
return { ...state, showUnreadIndicator, lastUpdatedCommentThreadId: id };
|
||||
};
|
||||
|
||||
export default handleUpdateCommentThreadEvent;
|
||||
|
|
|
|||
|
|
@ -23,4 +23,5 @@ export interface CommentsReduxState {
|
|||
unpublishedThreadDraftComment: EditorState | null;
|
||||
draftComments: Record<string, EditorState>;
|
||||
commentThreadsFetched: boolean;
|
||||
lastUpdatedCommentThreadId: string | null;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user