From 4b46120ec125d56f8069c2703031e0da51f1bb54 Mon Sep 17 00:00:00 2001 From: Mathias Jakobsen Date: Tue, 28 Jan 2025 10:26:46 +0000 Subject: [PATCH] Merge pull request #22928 from overleaf/mj-ide-toolbar [web] Initial editor toolbar GitOrigin-RevId: 33658d886bf86cbaa22a161f2ff463ef608e5f6b --- .../web/frontend/extracted-translations.json | 4 + .../context/online-users-context.tsx | 2 +- .../ide-redesign/components/main-layout.tsx | 3 +- .../components/toolbar/menu-bar.tsx | 77 ++++++++++++ .../components/toolbar/online-users.tsx | 27 +++++ .../components/toolbar/project-title.tsx | 39 ++++++ .../components/toolbar/toolbar.tsx | 68 +++++++++++ .../stylesheets/bootstrap-5/pages/all.scss | 1 + .../bootstrap-5/pages/editor/rail.scss | 2 +- .../pages/editor/toolbar-redesign.scss | 113 ++++++++++++++++++ services/web/locales/en.json | 3 + 11 files changed, 336 insertions(+), 3 deletions(-) create mode 100644 services/web/frontend/js/features/ide-redesign/components/toolbar/menu-bar.tsx create mode 100644 services/web/frontend/js/features/ide-redesign/components/toolbar/online-users.tsx create mode 100644 services/web/frontend/js/features/ide-redesign/components/toolbar/project-title.tsx create mode 100644 services/web/frontend/js/features/ide-redesign/components/toolbar/toolbar.tsx create mode 100644 services/web/frontend/stylesheets/bootstrap-5/pages/editor/toolbar-redesign.scss diff --git a/services/web/frontend/extracted-translations.json b/services/web/frontend/extracted-translations.json index f595664679..d5229af9eb 100644 --- a/services/web/frontend/extracted-translations.json +++ b/services/web/frontend/extracted-translations.json @@ -507,6 +507,7 @@ "failed_to_send_sso_link_invite_to_email": "", "fast": "", "features_like_track_changes": "", + "file": "", "file_action_created": "", "file_action_deleted": "", "file_action_edited": "", @@ -1082,6 +1083,7 @@ "overleaf": "", "overleaf_history_system": "", "overleaf_labs": "", + "overleaf_logo": "", "overview": "", "overwrite": "", "overwriting_the_original_folder": "", @@ -1210,6 +1212,7 @@ "project_timed_out_intro": "", "project_timed_out_learn_more": "", "project_timed_out_optimize_images": "", + "project_title_options": "", "project_too_large": "", "project_too_large_please_reduce": "", "project_too_much_editable_text": "", @@ -1863,6 +1866,7 @@ "vat": "", "vat_number": "", "verify_email_address_before_enabling_managed_users": "", + "view": "", "view_all": "", "view_code": "", "view_configuration": "", diff --git a/services/web/frontend/js/features/ide-react/context/online-users-context.tsx b/services/web/frontend/js/features/ide-react/context/online-users-context.tsx index 137e0f7157..26508f2f87 100644 --- a/services/web/frontend/js/features/ide-react/context/online-users-context.tsx +++ b/services/web/frontend/js/features/ide-react/context/online-users-context.tsx @@ -21,7 +21,7 @@ import { debugConsole } from '@/utils/debugging' import { IdeEvents } from '@/features/ide-react/create-ide-event-emitter' import { getHueForUserId } from '@/shared/utils/colors' -type OnlineUser = { +export type OnlineUser = { id: string user_id: string email: string diff --git a/services/web/frontend/js/features/ide-redesign/components/main-layout.tsx b/services/web/frontend/js/features/ide-redesign/components/main-layout.tsx index 1f314ad702..229f570ca1 100644 --- a/services/web/frontend/js/features/ide-redesign/components/main-layout.tsx +++ b/services/web/frontend/js/features/ide-redesign/components/main-layout.tsx @@ -4,11 +4,12 @@ import { HorizontalResizeHandle } from '@/features/ide-react/components/resize/h import PdfPreview from '@/features/pdf-preview/components/pdf-preview' import { Editor } from './editor' import { RailLayout } from './rail' +import { Toolbar } from './toolbar/toolbar' export default function MainLayout() { return (
-
Toolbar
+
void +} + +type MenuBarDropdownProps = { + title: string + id: string +} + +export const ToolbarMenuBar = () => { + const { t } = useTranslation() + return ( +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ ) +} + +const MenuBarDropdown: FC = ({ title, children, id }) => { + return ( + + + {title} + + {children} + + ) +} + +const MenuBarOption = ({ title, onClick }: MenuBarOptionProps) => { + return {title} +} diff --git a/services/web/frontend/js/features/ide-redesign/components/toolbar/online-users.tsx b/services/web/frontend/js/features/ide-redesign/components/toolbar/online-users.tsx new file mode 100644 index 0000000000..d8fb314907 --- /dev/null +++ b/services/web/frontend/js/features/ide-redesign/components/toolbar/online-users.tsx @@ -0,0 +1,27 @@ +import OnlineUsersWidget from '@/features/editor-navigation-toolbar/components/online-users-widget' +import { useEditorManagerContext } from '@/features/ide-react/context/editor-manager-context' +import { + OnlineUser, + useOnlineUsersContext, +} from '@/features/ide-react/context/online-users-context' +import { useCallback } from 'react' + +export const OnlineUsers = () => { + const { openDoc } = useEditorManagerContext() + const { onlineUsersArray } = useOnlineUsersContext() + + const goToUser = useCallback( + (user: OnlineUser) => { + if (user.doc && typeof user.row === 'number') { + openDoc(user.doc, { gotoLine: user.row + 1 }) + } + }, + [openDoc] + ) + + return ( +
+ +
+ ) +} diff --git a/services/web/frontend/js/features/ide-redesign/components/toolbar/project-title.tsx b/services/web/frontend/js/features/ide-redesign/components/toolbar/project-title.tsx new file mode 100644 index 0000000000..4d98150e58 --- /dev/null +++ b/services/web/frontend/js/features/ide-redesign/components/toolbar/project-title.tsx @@ -0,0 +1,39 @@ +import { + Dropdown, + DropdownDivider, + DropdownMenu, + DropdownToggle, +} from '@/features/ui/components/bootstrap-5/dropdown-menu' +import OLDropdownMenuItem from '@/features/ui/components/ol/ol-dropdown-menu-item' +import MaterialIcon from '@/shared/components/material-icon' +import { useProjectContext } from '@/shared/context/project-context' +import { useTranslation } from 'react-i18next' + +export const ToolbarProjectTitle = () => { + const { name } = useProjectContext() + const { t } = useTranslation() + return ( + + + {name} + + + + TODO: Export + + {t('rename')} + {t('download')} + + {t('delete')} + + + + ) +} diff --git a/services/web/frontend/js/features/ide-redesign/components/toolbar/toolbar.tsx b/services/web/frontend/js/features/ide-redesign/components/toolbar/toolbar.tsx new file mode 100644 index 0000000000..d5ceee5dbf --- /dev/null +++ b/services/web/frontend/js/features/ide-redesign/components/toolbar/toolbar.tsx @@ -0,0 +1,68 @@ +import OLButton from '@/features/ui/components/ol/ol-button' +import MaterialIcon from '@/shared/components/material-icon' +import { useTranslation } from 'react-i18next' +import { ToolbarMenuBar } from './menu-bar' +import { ToolbarProjectTitle } from './project-title' +import { OnlineUsers } from './online-users' + +export const Toolbar = () => { + return ( +
+ + + +
+ ) +} + +const ToolbarMenus = () => { + const { t } = useTranslation() + return ( +
+ + +
+ ) +} + +const ToolbarButtons = () => { + const { t } = useTranslation() + return ( +
+ +
+ } + /> +
+
+ } + > + {t('submit_title')} + +
+
+ } + > + {t('share')} + +
+
+ ) +} diff --git a/services/web/frontend/stylesheets/bootstrap-5/pages/all.scss b/services/web/frontend/stylesheets/bootstrap-5/pages/all.scss index 7bf1668a7c..30b277a113 100644 --- a/services/web/frontend/stylesheets/bootstrap-5/pages/all.scss +++ b/services/web/frontend/stylesheets/bootstrap-5/pages/all.scss @@ -10,6 +10,7 @@ @import 'editor/rail'; @import 'editor/settings'; @import 'editor/toolbar'; +@import 'editor/toolbar-redesign'; @import 'editor/online-users'; @import 'editor/hotkeys'; @import 'editor/left-menu'; diff --git a/services/web/frontend/stylesheets/bootstrap-5/pages/editor/rail.scss b/services/web/frontend/stylesheets/bootstrap-5/pages/editor/rail.scss index ba7f5b8202..a0a7a1e707 100644 --- a/services/web/frontend/stylesheets/bootstrap-5/pages/editor/rail.scss +++ b/services/web/frontend/stylesheets/bootstrap-5/pages/editor/rail.scss @@ -54,11 +54,11 @@ height: 100%; padding: var(--spacing-02); background: var(--ide-rail-background); + border-right: 1px solid var(--border-divider); } .ide-rail-content { height: 100%; - border: 1px solid var(--border-divider); } .ide-rail-tabs-nav { diff --git a/services/web/frontend/stylesheets/bootstrap-5/pages/editor/toolbar-redesign.scss b/services/web/frontend/stylesheets/bootstrap-5/pages/editor/toolbar-redesign.scss new file mode 100644 index 0000000000..e220bf0667 --- /dev/null +++ b/services/web/frontend/stylesheets/bootstrap-5/pages/editor/toolbar-redesign.scss @@ -0,0 +1,113 @@ +@use 'sass:math'; + +:root { + --toolbar-home-button-hover-background: var(--neutral-20); +} + +.ide-redesign-toolbar { + $toolbar-height: 48px; + $home-button-size: 36px; + $ol-icon-height: 24px; + $home-icon-font-size: 24px; + + border-bottom: 1px solid var(--border-divider); + display: flex; + flex-direction: row; + justify-content: space-between; + box-sizing: border-box; + height: $toolbar-height; + + .ide-redesign-toolbar-menu { + display: flex; + gap: var(--spacing-05); + } + + .ide-redesign-toolbar-home-button { + width: $home-button-size; + height: $home-button-size; + margin: math.div($toolbar-height - $home-button-size, 2); + } + + .ide-redesign-toolbar-home-link { + display: flex; + height: 100%; + width: 100%; + justify-content: center; + flex-direction: column; + text-align: center; + border-radius: 100%; + + .toolbar-ol-home-button { + display: none; + font-size: $home-icon-font-size; + } + + .toolbar-ol-logo { + margin: 0 auto; + height: $ol-icon-height; + width: auto; + } + + &:hover { + background-color: var(--toolbar-home-button-hover-background); + + .toolbar-ol-home-button { + display: block; + } + + .toolbar-ol-logo { + display: none; + } + } + } + + .ide-redesign-toolbar-dropdown-toggle-subdued { + $height: 32px; + + border: none; + border-radius: var(--border-radius-base); + padding: var(--spacing-02); + height: $height; + font-size: var(--font-size-03); + line-height: var(--line-height-03); + font-weight: 400; + box-sizing: border-box; + margin: math.div($toolbar-height - $height, 2) 0; + + &.dropdown-toggle::after { + display: none; + } + + .material-symbols { + vertical-align: middle; + } + } +} + +.ide-redesign-toolbar-menu-bar { + display: flex; + justify-content: flex-start; + height: 100%; + gap: var(--spacing-05); +} + +.ide-redesign-toolbar-actions { + display: flex; + gap: var(--spacing-06); + padding: 0 var(--spacing-05); +} + +.ide-redesign-toolbar-button-container { + display: flex; + flex-direction: column; + justify-content: center; +} + +.ide-redesign-toolbar-button-subdued { + color: var(--neutral-90); + text-decoration: none; +} + +.ide-redesign-online-users { + display: flex; +} diff --git a/services/web/locales/en.json b/services/web/locales/en.json index 01575e5c69..268db06df5 100644 --- a/services/web/locales/en.json +++ b/services/web/locales/en.json @@ -679,6 +679,7 @@ "features_and_benefits": "Features & Benefits", "features_like_track_changes": "Features like real-time track changes", "february": "February", + "file": "File", "file_action_created": "Created", "file_action_deleted": "Deleted", "file_action_edited": "Edited", @@ -1454,6 +1455,7 @@ "overleaf_history_system": "Overleaf History System", "overleaf_individual_plans": "Overleaf individual plans", "overleaf_labs": "Overleaf Labs", + "overleaf_logo": "Overleaf logo", "overleaf_plans_and_pricing": "overleaf plans and pricing", "overleaf_template_gallery": "overleaf template gallery", "overview": "Overview", @@ -2407,6 +2409,7 @@ "vat": "VAT", "vat_number": "VAT Number", "verify_email_address_before_enabling_managed_users": "You need to verify your email address before enabling managed users.", + "view": "View", "view_all": "View All", "view_code": "View code", "view_configuration": "View configuration",