From 1b4cbd4efb2b582e4dbf3a69261e9b9fe49e18b9 Mon Sep 17 00:00:00 2001 From: Rebeka Dekany <50901361+rebekadekany@users.noreply.github.com> Date: Wed, 23 Jul 2025 09:25:12 +0200 Subject: [PATCH] Improve landmarks on the Project dashboard and Editor pages (#26751) * Improve landmarks for the Project Dasbhboard * Improve landmarks for the IDE page * Improve landmarks for the new redesigned IDE page * Sort locales * Fix typo OlButtonToolbar -> OLButtonToolbar * Update project navbar translation * Update labels * Redundant main landmark * Fix failing test * Descriptive name for the rails tab * Header should not be in a button * Update translation to Account and help * Update translation to Project categories and tags * Add explanations GitOrigin-RevId: 96712b37bb1306b552de510d9fd8ae890f24309f --- server-ce/test/git-bridge.spec.ts | 24 +++- server-ce/test/sandboxed-compiles.spec.ts | 18 ++- server-ce/test/templates.spec.ts | 36 +++++- server-ce/test/upgrading.spec.ts | 10 +- .../layout/fat-footer-website-redesign.pug | 5 +- services/web/app/views/layout/fat-footer.pug | 5 +- .../layout/navbar-marketing-bootstrap-5.pug | 1 + .../web/app/views/layout/navbar-marketing.pug | 1 + .../views/layout/navbar-website-redesign.pug | 4 +- services/web/app/views/project/ide-react.pug | 2 +- .../web/frontend/extracted-translations.json | 17 ++- .../js/features/chat/components/chat-pane.tsx | 2 +- .../components/toolbar-header.tsx | 8 +- .../components/change-list/change-list.tsx | 2 +- .../ide-react/components/editor-and-pdf.tsx | 4 + .../ide-react/components/editor-sidebar.tsx | 6 +- .../ide-react/components/history-sidebar.tsx | 5 +- .../ide-redesign/components/chat/chat.tsx | 2 +- .../integrations-panel/integration-card.tsx | 4 +- .../ide-redesign/components/main-layout.tsx | 4 + .../pdf-preview-hybrid-toolbar.tsx | 11 +- .../components/rail-panel-header.tsx | 4 +- .../features/ide-redesign/components/rail.tsx | 18 ++- .../components/toolbar/toolbar.tsx | 10 +- .../outline/components/outline-pane.tsx | 4 +- .../pdf-preview/components/pdf-js-viewer.tsx | 15 +++ .../components/pdf-preview-hybrid-toolbar.tsx | 11 +- .../components/preview-log-entry-header.tsx | 4 +- .../notifications/user-notifications.tsx | 9 +- .../components/project-list-ds-nav.tsx | 104 +++++++++--------- .../components/project-list-root.tsx | 2 +- .../components/sidebar/sidebar-ds-nav.tsx | 41 ++++--- .../components/sidebar/sidebar.tsx | 0 .../components/title/project-list-title.tsx | 6 +- .../bootstrap-5/footer/fat-footer-base.tsx | 4 +- .../bootstrap-5/footer/fat-footer.tsx | 6 +- .../bootstrap-5/navbar/default-navbar.tsx | 3 +- .../bootstrap-5/pages/project-list.scss | 13 +-- services/web/locales/en.json | 16 ++- .../pdf-preview/pdf-js-viewer.spec.tsx | 14 ++- .../history/components/change-list.spec.tsx | 42 ++++++- 41 files changed, 331 insertions(+), 166 deletions(-) create mode 100644 services/web/frontend/js/features/project-list/components/sidebar/sidebar.tsx diff --git a/server-ce/test/git-bridge.spec.ts b/server-ce/test/git-bridge.spec.ts index 1f114574ac..53b1bae54c 100644 --- a/server-ce/test/git-bridge.spec.ts +++ b/server-ce/test/git-bridge.spec.ts @@ -85,7 +85,11 @@ describe('git-bridge', function () { it('should render the git-bridge UI in the editor', function () { maybeClearAllTokens() createProject('git').as('projectId') - cy.get('header').findByText('Menu').click() + cy.findByRole('navigation', { + name: /Project actions/i, + }) + .findByRole('button', { name: /Menu/i }) + .click() cy.findByText('Sync') cy.findByText('Git').click() cy.findByTestId('git-bridge-modal').within(() => { @@ -100,7 +104,11 @@ describe('git-bridge', function () { // Re-open cy.url().then(url => cy.visit(url)) - cy.get('header').findByText('Menu').click() + cy.findByRole('navigation', { + name: /Project actions/i, + }) + .findByRole('button', { name: /Menu/i }) + .click() cy.findByText('Git').click() cy.findByTestId('git-bridge-modal').within(() => { cy.get('@projectId').then(id => { @@ -188,7 +196,11 @@ describe('git-bridge', function () { function checkGitAccess(access: 'readOnly' | 'readAndWrite') { const recompile = throttledRecompile() - cy.get('header').findByText('Menu').click() + cy.findByRole('navigation', { + name: /Project actions/i, + }) + .findByRole('button', { name: /Menu/i }) + .click() cy.findByText('Sync') cy.findByText('Git').click() cy.get('@projectId').then(projectId => { @@ -370,7 +382,11 @@ Hello world it('should not render the git-bridge UI in the editor', function () { login('user@example.com') createProject('maybe git') - cy.get('header').findByText('Menu').click() + cy.findByRole('navigation', { + name: /Project actions/i, + }) + .findByRole('button', { name: /Menu/i }) + .click() cy.findByText('Word Count') // wait for lazy loading cy.findByText('Sync').should('not.exist') cy.findByText('Git').should('not.exist') diff --git a/server-ce/test/sandboxed-compiles.spec.ts b/server-ce/test/sandboxed-compiles.spec.ts index 71f5b43392..a8772c6599 100644 --- a/server-ce/test/sandboxed-compiles.spec.ts +++ b/server-ce/test/sandboxed-compiles.spec.ts @@ -37,7 +37,11 @@ describe('SandboxedCompiles', function () { cy.findByText(/This is pdfTeX, Version .+ \(TeX Live 2023\) /) cy.log('Switch TeXLive version from 2023 to 2022') - cy.get('header').findByText('Menu').click() + cy.findByRole('navigation', { + name: /Project actions/i, + }) + .findByRole('button', { name: /Menu/i }) + .click() cy.findByText(LABEL_TEX_LIVE_VERSION) .parent() .findByText('2023') @@ -213,7 +217,11 @@ describe('SandboxedCompiles', function () { cy.findByText(/This is pdfTeX/) cy.log('Switch compiler to from pdfLaTeX to XeLaTeX') - cy.get('header').findByText('Menu').click() + cy.findByRole('navigation', { + name: /Project actions/i, + }) + .findByRole('button', { name: /Menu/i }) + .click() cy.findByText('Compiler') .parent() .findByText('pdfLaTeX') @@ -245,7 +253,11 @@ describe('SandboxedCompiles', function () { cy.findByText(/This is pdfTeX, Version .+ \(TeX Live 2025\) /) cy.log('Check that there is no TeX Live version toggle') - cy.get('header').findByText('Menu').click() + cy.findByRole('navigation', { + name: /Project actions/i, + }) + .findByRole('button', { name: /Menu/i }) + .click() cy.findByText('Word Count') // wait for lazy loading cy.findByText(LABEL_TEX_LIVE_VERSION).should('not.exist') }) diff --git a/server-ce/test/templates.spec.ts b/server-ce/test/templates.spec.ts index 4959e149fc..93ee1b5079 100644 --- a/server-ce/test/templates.spec.ts +++ b/server-ce/test/templates.spec.ts @@ -57,7 +57,11 @@ describe('Templates', () => { cy.visit('/') createProject(name).as('templateProjectId') - cy.get('header').findByText('Menu').click() + cy.findByRole('navigation', { + name: /Project actions/i, + }) + .findByRole('button', { name: /Menu/i }) + .click() cy.findByText('Manage Template').click() cy.findByText('Template Description') @@ -136,7 +140,11 @@ describe('Templates', () => { cy.get('@templateProjectId').then(projectId => cy.visit(`/project/${projectId}`) ) - cy.get('header').findByText('Menu').click() + cy.findByRole('navigation', { + name: /Project actions/i, + }) + .findByRole('button', { name: /Menu/i }) + .click() cy.findByText('Manage Template').click() cy.findByText('Publish').click() cy.findByText('Unpublish', { timeout: 10_000 }) @@ -161,7 +169,11 @@ describe('Templates', () => { cy.findByText('Open as Template').click() cy.url().should('match', /\/project\/[a-f0-9]{24}$/) cy.get('.project-name').findByText(name) - cy.get('header').findByText('Menu').click() + cy.findByRole('navigation', { + name: /Project actions/i, + }) + .findByRole('button', { name: /Menu/i }) + .click() cy.findByText('Word Count') // wait for lazy loading cy.findByText('Manage Template').should('not.exist') @@ -180,7 +192,11 @@ describe('Templates', () => { cy.get('@templateProjectId').then(projectId => cy.visit(`/project/${projectId}`) ) - cy.get('header').findByText('Menu').click() + cy.findByRole('navigation', { + name: /Project actions/i, + }) + .findByRole('button', { name: /Menu/i }) + .click() cy.findByText('Manage Template').click() cy.findByText('Unpublish') @@ -191,7 +207,11 @@ describe('Templates', () => { cy.get('@templateProjectId').then(projectId => cy.visit(`/project/${projectId}`) ) - cy.get('header').findByText('Menu').click() + cy.findByRole('navigation', { + name: /Project actions/i, + }) + .findByRole('button', { name: /Menu/i }) + .click() cy.findByText('Manage Template').click() cy.findByText('Unpublish').click() cy.findByText('Publish') @@ -217,7 +237,11 @@ describe('Templates', () => { cy.visit('/') createProject('maybe templates') - cy.get('header').findByText('Menu').click() + cy.findByRole('navigation', { + name: /Project actions/i, + }) + .findByRole('button', { name: /Menu/i }) + .click() cy.findByText('Word Count') // wait for lazy loading cy.findByText('Manage Template').should('not.exist') diff --git a/server-ce/test/upgrading.spec.ts b/server-ce/test/upgrading.spec.ts index 16e0320dcc..00390cd80e 100644 --- a/server-ce/test/upgrading.spec.ts +++ b/server-ce/test/upgrading.spec.ts @@ -55,7 +55,11 @@ describe('Upgrading', function () { cy.log('Trigger full flush') recompile() - cy.get('header').findByText('Menu').click() + cy.findByRole('navigation', { + name: /Project Layout, Sharing, and Submission/i, + }) + .findByRole('button', { name: /Menu/i }) + .click() cy.findByText('Source').click() cy.get('.left-menu-modal-backdrop').click({ force: true }) } @@ -116,7 +120,9 @@ describe('Upgrading', function () { openProjectByName(PROJECT_NAME) cy.url().should('match', /\/project\/[a-fA-F0-9]{24}/) - cy.findByRole('navigation').within(() => { + cy.findByRole('navigation', { + name: /Project actions/i, + }).within(() => { cy.findByText(PROJECT_NAME) }) const recompile = throttledRecompile() diff --git a/services/web/app/views/layout/fat-footer-website-redesign.pug b/services/web/app/views/layout/fat-footer-website-redesign.pug index 5a613df44a..760faffe74 100644 --- a/services/web/app/views/layout/fat-footer-website-redesign.pug +++ b/services/web/app/views/layout/fat-footer-website-redesign.pug @@ -1,8 +1,5 @@ footer.fat-footer.hidden-print.website-redesign-fat-footer - .fat-footer-container( - role='navigation' - aria-label=translate('footer_navigation') - ) + .fat-footer-container .fat-footer-sections(class={hidden: hideFatFooter}) #footer-brand.footer-section a.footer-brand(href='/' aria-label=settings.appName) diff --git a/services/web/app/views/layout/fat-footer.pug b/services/web/app/views/layout/fat-footer.pug index 518511b11f..2e88643abf 100644 --- a/services/web/app/views/layout/fat-footer.pug +++ b/services/web/app/views/layout/fat-footer.pug @@ -1,8 +1,5 @@ footer.fat-footer.hidden-print - .fat-footer-container( - role='navigation' - aria-label=translate('footer_navigation') - ) + .fat-footer-container .fat-footer-sections(class={hidden: hideFatFooter}) #footer-brand.footer-section a.footer-brand(href='/' aria-label=settings.appName) diff --git a/services/web/app/views/layout/navbar-marketing-bootstrap-5.pug b/services/web/app/views/layout/navbar-marketing-bootstrap-5.pug index 75cc065e73..76693744bc 100644 --- a/services/web/app/views/layout/navbar-marketing-bootstrap-5.pug +++ b/services/web/app/views/layout/navbar-marketing-bootstrap-5.pug @@ -5,6 +5,7 @@ nav.navbar.navbar-default.navbar-main.navbar-expand-lg( class={ 'website-redesign-navbar': isWebsiteRedesign, } + aria-label=translate('primary') ) .container-fluid.navbar-container .navbar-header diff --git a/services/web/app/views/layout/navbar-marketing.pug b/services/web/app/views/layout/navbar-marketing.pug index bb26ff8d40..de147df23c 100644 --- a/services/web/app/views/layout/navbar-marketing.pug +++ b/services/web/app/views/layout/navbar-marketing.pug @@ -2,6 +2,7 @@ nav.navbar.navbar-default.navbar-main( class={ 'website-redesign-navbar': isWebsiteRedesign, } + aria-label=translate('primary') ) .container-fluid .navbar-header diff --git a/services/web/app/views/layout/navbar-website-redesign.pug b/services/web/app/views/layout/navbar-website-redesign.pug index 210cf3a120..67d7fe704a 100644 --- a/services/web/app/views/layout/navbar-website-redesign.pug +++ b/services/web/app/views/layout/navbar-website-redesign.pug @@ -1,4 +1,6 @@ -nav.navbar.navbar-default.navbar-main.website-redesign-navbar +nav.navbar.navbar-default.navbar-main.website-redesign-navbar( + aria-label=translate('primary') +) .container-fluid .navbar-header if typeof suppressNavbarRight == 'undefined' diff --git a/services/web/app/views/project/ide-react.pug b/services/web/app/views/project/ide-react.pug index 8af9de8296..135e28f0f0 100644 --- a/services/web/app/views/project/ide-react.pug +++ b/services/web/app/views/project/ide-react.pug @@ -12,7 +12,7 @@ block entrypointVar - entrypoint = 'pages/ide' block content - main#ide-root + #ide-root .loading-screen .loading-screen-brand-container .loading-screen-brand(style='height: 20%') diff --git a/services/web/frontend/extracted-translations.json b/services/web/frontend/extracted-translations.json index 639c9fcdfc..e76317d33f 100644 --- a/services/web/frontend/extracted-translations.json +++ b/services/web/frontend/extracted-translations.json @@ -53,6 +53,7 @@ "account_billed_manually": "", "account_has_been_link_to_institution_account": "", "account_has_past_due_invoice_change_plan_warning": "", + "account_help": "", "account_managed_by_group_administrator": "", "account_not_linked_to_dropbox": "", "account_settings": "", @@ -566,6 +567,7 @@ "fast": "", "fast_draft": "", "features_like_track_changes": "", + "feedback": "", "figure": "", "file": "", "file_action_created": "", @@ -585,6 +587,7 @@ "file_size": "", "file_tree": "", "files_cannot_include_invalid_characters": "", + "files_collaboration_integrations_logs": "", "files_selected": "", "filter_projects": "", "find": "", @@ -605,7 +608,6 @@ "font_size": "", "footer_about_us": "", "footer_contact_us": "", - "footer_navigation": "", "footnotes": "", "for_business": "", "for_government": "", @@ -729,6 +731,7 @@ "headers": "", "help": "", "help_articles_matching": "", + "help_editor_settings": "", "help_improve_overleaf_fill_out_this_survey": "", "help_improve_screen_reader_fill_out_this_survey": "", "help_shape_the_future_of_overleaf": "", @@ -997,7 +1000,6 @@ "main_bibliography_file_for_this_project": "", "main_document": "", "main_file_not_found": "", - "main_navigation": "", "make_a_copy": "", "make_email_primary_description": "", "make_owner": "", @@ -1136,6 +1138,7 @@ "not_a_student": "", "not_managed": "", "not_now": "", + "notification": "", "notification_personal_and_group_subscriptions": "", "notification_project_invite_accepted_message": "", "notification_project_invite_message": "", @@ -1220,6 +1223,7 @@ "payment_error_update_payment_method": "", "payment_provider_unreachable_error": "", "payment_summary": "", + "pdf": "", "pdf_compile_in_progress_error": "", "pdf_compile_rate_limit_hit": "", "pdf_compile_try_again": "", @@ -1229,6 +1233,7 @@ "pdf_only_hide_editor": "", "pdf_preview": "", "pdf_preview_error": "", + "pdf_preview_logs": "", "pdf_rendering_error": "", "pdf_unavailable_for_download": "", "pdf_viewer": "", @@ -1290,6 +1295,7 @@ "primarily_work_study_question_nonprofit_ngo": "", "primarily_work_study_question_other": "", "primarily_work_study_question_university_school": "", + "primary": "", "primary_certificate": "", "priority_support": "", "privacy_and_terms": "", @@ -1302,14 +1308,17 @@ "processing_uppercase": "", "professional": "", "progress_bar_percentage": "", + "project_actions": "", "project_approaching_file_limit": "", + "project_categories_tags": "", "project_figure_modal": "", "project_files": "", + "project_files_history": "", + "project_files_outline": "", "project_flagged_too_many_compiles": "", "project_has_too_many_files": "", - "project_history_list": "", + "project_history_labels": "", "project_last_published_at": "", - "project_layout_sharing_submission": "", "project_linked_to": "", "project_name": "", "project_not_linked_to_github": "", 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 1ef4d46a31..48ae6b6f6e 100644 --- a/services/web/frontend/js/features/chat/components/chat-pane.tsx +++ b/services/web/frontend/js/features/chat/components/chat-pane.tsx @@ -72,7 +72,7 @@ const ChatPane = React.memo(function ChatPane() { } return ( -