From 23045368444e832423dbc065d06bfb39716989ed Mon Sep 17 00:00:00 2001 From: Alf Eaton Date: Mon, 12 Aug 2024 10:50:54 +0100 Subject: [PATCH] Add review panel context providers and components (#19490) * Tidy up review panel components * Add ReviewPanel providers * [web] new design for review panel track change (#19544) * [web] new design for review panel track change * fixed mini view * mini icon style change * fix icon size * format date * useRangesUserContext hook * remove useRangesUserContext hook * using full class names * fix action icons hover * change wording for tooltips * added ReviewPanelChangeUser component * Update header in new review panel * Extract ReviewPanelTrackChangesMenuButton as a separate component * Remove wrapper div * Replace h2 with div for review panel label * Rename ReviewPanelTools to ReviewPanelHeader * Rename trackChangesExpanded -> trackChangesMenuExpanded * Dont break memoisation of ReviewPanelTrackChangesMenuButton * Fix the width of the track changes arrow icon * Update how prop types are declared * Remove new empty state from old review panel * Add empty state to new review panel * Add project members and owner to ChangesUsers context (#19624) --------- Co-authored-by: Alf Eaton * Redesign comment entry in review panel (#19678) * Redesign comment entry in review panel * ReviewPanelCommentOptions component * remove unused prop * Tidying * Add conditional import * Optional changeManager * Add more split test compatibility * More split test compatibility * Fixes * Improve overview scrolling * Fix overview scrolling * Fix & simplify track changes toggle * Fix overview scrolling * Fix current file container * ExpandableContent component for messages in review panel (#19738) * ExpandableContent component for messages in review panel * remove isExpanded dependancy * Delete comment option for new review panel (#19772) * Delete comment option for new review panel * dont show thread warning if there are no replies * fix hasReplies issue * Implement initial collapsing overview files * Fix positioning of overview panel * Small styling changes * Add count of unresolved comments and tracked chanegs * More style adjustments * Move review-panel-overview styles into css file * Remove unused var --------- Co-authored-by: Domagoj Kriskovic Co-authored-by: David Powell Co-authored-by: David <33458145+davidmcpowell@users.noreply.github.com> GitOrigin-RevId: e67463443d541f88445a86eed5e2b6ec6040f9c7 --- .../web/frontend/extracted-translations.json | 10 + .../js/features/chat/components/chat-pane.tsx | 2 +- .../change-list/all-history-list.tsx | 2 +- .../components/change-list/labels-list.tsx | 2 +- .../hooks/use-review-panel-state.ts | 8 +- .../review-panel/review-panel-provider.tsx | 19 - .../components/review-panel-add-comment.tsx | 61 +++ .../components/review-panel-change-user.tsx | 16 + .../components/review-panel-change.tsx | 172 +++++++++ .../review-panel-comment-options.tsx | 30 ++ .../components/review-panel-comment.tsx | 115 ++++++ .../components/review-panel-container.tsx | 22 ++ .../components/review-panel-current-file.tsx | 257 +++++++++++++ .../review-panel-delete-comment-modal.tsx | 32 ++ .../components/review-panel-empty-state.tsx} | 10 +- .../review-panel-expandable-content.tsx | 72 ++++ .../components/review-panel-header.tsx | 43 +++ .../components/review-panel-message.tsx | 135 +++++++ .../components/review-panel-overview-file.tsx | 94 +++++ .../components/review-panel-overview.tsx | 99 +++++ .../review-panel-resolved-threads.tsx | 87 +++++ .../components/review-panel-tabs.tsx | 31 ++ ...review-panel-track-changes-menu-button.tsx | 34 ++ .../review-panel-track-changes-menu.tsx | 112 ++++++ .../components/review-panel.tsx | 74 ++++ .../context/changes-users-context.tsx | 56 +++ .../context/ranges-context.tsx | 141 +++++++ .../context/review-panel-providers.tsx | 22 ++ .../context/threads-context.tsx | 291 ++++++++++++++ .../context/track-changes-state-context.tsx | 43 +++ .../hooks/use-overview-file-collapsed.ts | 22 ++ .../review-panel-new/utils/build-name.ts | 15 + .../review-panel-new/utils/can-aggregate.ts | 15 + .../review-panel-new/utils/is-focused.ts | 7 + .../review-panel-new/utils/is-in-viewport.tsx | 7 + .../review-panel-new/utils/position-items.ts | 77 ++++ .../components/codemirror-editor.tsx | 39 +- .../review-panel/current-file-container.tsx | 11 - .../review-panel/overview-container.tsx | 20 +- .../review-panel/review-panel-content.tsx | 37 ++ .../review-panel/review-panel-migration.tsx | 19 + .../components/review-panel/review-panel.tsx | 67 +--- .../review-panel/review-panel-context.tsx | 13 + .../extensions/changes/change-manager.ts | 13 +- .../source-editor/extensions/track-changes.ts | 217 +++++++++-- .../extensions/vertical-overflow.ts | 6 +- .../hooks/use-codemirror-scope.ts | 30 +- .../shared/context/types/project-context.tsx | 9 +- services/web/frontend/js/utils/operations.ts | 27 ++ .../web/frontend/stylesheets/app/editor.less | 1 + .../app/editor/review-panel-new.less | 361 ++++++++++++++++++ .../stylesheets/app/editor/review-panel.less | 60 ++- services/web/locales/en.json | 9 + .../codemirror-editor-autocomplete.spec.tsx | 5 +- services/web/types/user.ts | 2 +- 55 files changed, 2970 insertions(+), 211 deletions(-) delete mode 100644 services/web/frontend/js/features/ide-react/context/review-panel/review-panel-provider.tsx create mode 100644 services/web/frontend/js/features/review-panel-new/components/review-panel-add-comment.tsx create mode 100644 services/web/frontend/js/features/review-panel-new/components/review-panel-change-user.tsx create mode 100644 services/web/frontend/js/features/review-panel-new/components/review-panel-change.tsx create mode 100644 services/web/frontend/js/features/review-panel-new/components/review-panel-comment-options.tsx create mode 100644 services/web/frontend/js/features/review-panel-new/components/review-panel-comment.tsx create mode 100644 services/web/frontend/js/features/review-panel-new/components/review-panel-container.tsx create mode 100644 services/web/frontend/js/features/review-panel-new/components/review-panel-current-file.tsx create mode 100644 services/web/frontend/js/features/review-panel-new/components/review-panel-delete-comment-modal.tsx rename services/web/frontend/js/features/{source-editor/components/review-panel/empty-state.tsx => review-panel-new/components/review-panel-empty-state.tsx} (63%) create mode 100644 services/web/frontend/js/features/review-panel-new/components/review-panel-expandable-content.tsx create mode 100644 services/web/frontend/js/features/review-panel-new/components/review-panel-header.tsx create mode 100644 services/web/frontend/js/features/review-panel-new/components/review-panel-message.tsx create mode 100644 services/web/frontend/js/features/review-panel-new/components/review-panel-overview-file.tsx create mode 100644 services/web/frontend/js/features/review-panel-new/components/review-panel-overview.tsx create mode 100644 services/web/frontend/js/features/review-panel-new/components/review-panel-resolved-threads.tsx create mode 100644 services/web/frontend/js/features/review-panel-new/components/review-panel-tabs.tsx create mode 100644 services/web/frontend/js/features/review-panel-new/components/review-panel-track-changes-menu-button.tsx create mode 100644 services/web/frontend/js/features/review-panel-new/components/review-panel-track-changes-menu.tsx create mode 100644 services/web/frontend/js/features/review-panel-new/components/review-panel.tsx create mode 100644 services/web/frontend/js/features/review-panel-new/context/changes-users-context.tsx create mode 100644 services/web/frontend/js/features/review-panel-new/context/ranges-context.tsx create mode 100644 services/web/frontend/js/features/review-panel-new/context/review-panel-providers.tsx create mode 100644 services/web/frontend/js/features/review-panel-new/context/threads-context.tsx create mode 100644 services/web/frontend/js/features/review-panel-new/context/track-changes-state-context.tsx create mode 100644 services/web/frontend/js/features/review-panel-new/hooks/use-overview-file-collapsed.ts create mode 100644 services/web/frontend/js/features/review-panel-new/utils/build-name.ts create mode 100644 services/web/frontend/js/features/review-panel-new/utils/can-aggregate.ts create mode 100644 services/web/frontend/js/features/review-panel-new/utils/is-focused.ts create mode 100644 services/web/frontend/js/features/review-panel-new/utils/is-in-viewport.tsx create mode 100644 services/web/frontend/js/features/review-panel-new/utils/position-items.ts create mode 100644 services/web/frontend/js/features/source-editor/components/review-panel/review-panel-content.tsx create mode 100644 services/web/frontend/js/features/source-editor/components/review-panel/review-panel-migration.tsx create mode 100644 services/web/frontend/stylesheets/app/editor/review-panel-new.less diff --git a/services/web/frontend/extracted-translations.json b/services/web/frontend/extracted-translations.json index c8d7e350fb..6797120695 100644 --- a/services/web/frontend/extracted-translations.json +++ b/services/web/frontend/extracted-translations.json @@ -20,6 +20,7 @@ "accept": "", "accept_all": "", "accept_and_continue": "", + "accept_change": "", "accept_invitation": "", "accept_or_reject_each_changes_individually": "", "accept_terms_and_conditions": "", @@ -281,6 +282,10 @@ "delete_authentication_token": "", "delete_authentication_token_info": "", "delete_certificate": "", + "delete_comment": "", + "delete_comment_message": "", + "delete_comment_thread": "", + "delete_comment_thread_message": "", "delete_figure": "", "delete_projects": "", "delete_row_or_column": "", @@ -822,6 +827,7 @@ "more": "", "more_actions": "", "more_info": "", + "more_options": "", "more_options_for_border_settings_coming_soon": "", "my_library": "", "n_items": "", @@ -1080,6 +1086,7 @@ "regards": "", "reject": "", "reject_all": "", + "reject_change": "", "relink_your_account": "", "reload_editor": "", "remind_before_trial_ends": "", @@ -1118,6 +1125,7 @@ "resending_confirmation_email": "", "resize": "", "resolve": "", + "resolve_comment": "", "resolved_comments": "", "restore": "", "restore_file": "", @@ -1242,6 +1250,7 @@ "show_in_pdf": "", "show_less": "", "show_local_file_contents": "", + "show_more": "", "show_outline": "", "show_x_more_projects": "", "showing_1_result": "", @@ -1479,6 +1488,7 @@ "track_any_change_in_real_time": "", "track_changes": "", "track_changes_for_everyone": "", + "track_changes_for_guests": "", "track_changes_for_x": "", "track_changes_is_off": "", "track_changes_is_on": "", diff --git a/services/web/frontend/js/features/chat/components/chat-pane.tsx b/services/web/frontend/js/features/chat/components/chat-pane.tsx index 6f812b1c77..d9cb21f8f5 100644 --- a/services/web/frontend/js/features/chat/components/chat-pane.tsx +++ b/services/web/frontend/js/features/chat/components/chat-pane.tsx @@ -67,7 +67,7 @@ const ChatPane = React.memo(function ChatPane() { throw error } - if (!user) { + if (!user?.id) { return null } if (!chatOpenedOnce) { diff --git a/services/web/frontend/js/features/history/components/change-list/all-history-list.tsx b/services/web/frontend/js/features/history/components/change-list/all-history-list.tsx index a2ded4fcc6..6cc979685b 100644 --- a/services/web/frontend/js/features/history/components/change-list/all-history-list.tsx +++ b/services/web/frontend/js/features/history/components/change-list/all-history-list.tsx @@ -225,7 +225,7 @@ function AllHistoryList() { showDivider={showDivider} setSelection={setSelection} selectionState={selectionState} - currentUserId={currentUserId} + currentUserId={currentUserId!} selectable={selectable} projectId={projectId} setActiveDropdownItem={setActiveDropdownItem} diff --git a/services/web/frontend/js/features/history/components/change-list/labels-list.tsx b/services/web/frontend/js/features/history/components/change-list/labels-list.tsx index 17935beef0..90793690eb 100644 --- a/services/web/frontend/js/features/history/components/change-list/labels-list.tsx +++ b/services/web/frontend/js/features/history/components/change-list/labels-list.tsx @@ -33,7 +33,7 @@ function LabelsList() { key={version} labels={labels} version={version} - currentUserId={currentUserId} + currentUserId={currentUserId!} projectId={projectId} selectionState={selectionState} selectable={selectionState !== 'selected'} diff --git a/services/web/frontend/js/features/ide-react/context/review-panel/hooks/use-review-panel-state.ts b/services/web/frontend/js/features/ide-react/context/review-panel/hooks/use-review-panel-state.ts index 3c066d8d21..c21bc5a08c 100644 --- a/services/web/frontend/js/features/ide-react/context/review-panel/hooks/use-review-panel-state.ts +++ b/services/web/frontend/js/features/ide-react/context/review-panel/hooks/use-review-panel-state.ts @@ -282,7 +282,7 @@ function useReviewPanelState(): ReviewPanel.ReviewPanelState { const tempUsers = {} as ReviewPanel.Value<'users'> // Always include ourself, since if we submit an op, we might need to display info // about it locally before it has been flushed through the server - if (user) { + if (user?.id) { tempUsers[user.id] = formatUser(user) } @@ -724,7 +724,7 @@ function useReviewPanelState(): ReviewPanel.ReviewPanelState { ) const applyTrackChangesStateToClient = useCallback( - (state: boolean | ReviewPanel.Value<'trackChangesState'>) => { + (state: boolean | Record) => { if (typeof state === 'boolean') { setEveryoneTCState(state) setGuestsTCState(state) @@ -1189,8 +1189,8 @@ function useReviewPanelState(): ReviewPanel.ReviewPanelState { // listen for events from the CodeMirror 6 track changes extension useEffect(() => { const toggleTrackChangesFromKbdShortcut = () => { - if (trackChangesVisible && trackChanges) { - const userId: UserId = user.id + const userId = user.id + if (trackChangesVisible && trackChanges && userId) { const state = trackChangesState[userId] if (state) { toggleTrackChangesForUser(!state.value, userId) diff --git a/services/web/frontend/js/features/ide-react/context/review-panel/review-panel-provider.tsx b/services/web/frontend/js/features/ide-react/context/review-panel/review-panel-provider.tsx deleted file mode 100644 index 611ed0cb35..0000000000 --- a/services/web/frontend/js/features/ide-react/context/review-panel/review-panel-provider.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import useReviewPanelState from '@/features/ide-react/context/review-panel/hooks/use-review-panel-state' -import { - ReviewPanelUpdaterFnsContext, - ReviewPanelValueContext, -} from '@/features/source-editor/context/review-panel/review-panel-context' - -const ReviewPanelReactIdeProvider: React.FC = ({ children }) => { - const { values, updaterFns } = useReviewPanelState() - - return ( - - - {children} - - - ) -} - -export default ReviewPanelReactIdeProvider diff --git a/services/web/frontend/js/features/review-panel-new/components/review-panel-add-comment.tsx b/services/web/frontend/js/features/review-panel-new/components/review-panel-add-comment.tsx new file mode 100644 index 0000000000..583c545f27 --- /dev/null +++ b/services/web/frontend/js/features/review-panel-new/components/review-panel-add-comment.tsx @@ -0,0 +1,61 @@ +import { FC, FormEventHandler, useCallback, useState } from 'react' +import { + useCodeMirrorStateContext, + useCodeMirrorViewContext, +} from '@/features/source-editor/components/codemirror-editor' +import { EditorSelection } from '@codemirror/state' +import { PANEL_WIDTH } from './review-panel' +import { useTranslation } from 'react-i18next' +import { useThreadsActionsContext } from '../context/threads-context' + +export const ReviewPanelAddComment: FC = () => { + const { t } = useTranslation() + const view = useCodeMirrorViewContext() + // eslint-disable-next-line no-unused-vars + const _state = useCodeMirrorStateContext() + const { addComment } = useThreadsActionsContext() + const [error, setError] = useState() + const [showForm, setShowForm] = useState(false) + + const handleSubmit = useCallback( + event => { + event.preventDefault() + + const { from, to } = view.state.selection.main + const content = view.state.sliceDoc(from, to) + + const formData = new FormData(event.target as HTMLFormElement) + const message = formData.get('message') as string + + addComment(from, content, message).catch(setError) + + view.dispatch({ + selection: EditorSelection.cursor(view.state.selection.main.anchor), + }) + }, + [addComment, view] + ) + + const handleElement = useCallback((element: HTMLElement | null) => { + if (element) { + element.dispatchEvent(new Event('review-panel:position')) + } + }, []) + + if (!showForm) { + return + } + + return ( +
+ {/* eslint-disable-next-line jsx-a11y/no-autofocus */} +