diff --git a/services/web/app/views/layout-marketing.pug b/services/web/app/views/layout-marketing.pug index 1e11fefa15..c602bf240a 100644 --- a/services/web/app/views/layout-marketing.pug +++ b/services/web/app/views/layout-marketing.pug @@ -8,20 +8,20 @@ block entrypointVar block body if typeof suppressNavbar === 'undefined' - include layout/navbar-marketing-bootstrap-5 + include layout/navbar-marketing block content if typeof suppressFooter === 'undefined' if showThinFooter - include layout/thin-footer-bootstrap-5 + include layout/thin-footer else include layout/fat-footer if typeof suppressPugCookieBanner == 'undefined' include _cookie_banner - != moduleIncludes('contactModal-marketing-bootstrap-5', locals) + != moduleIncludes('contactModal-marketing', locals) block prepend foot-scripts +bootstrap-js diff --git a/services/web/app/views/layout-react.pug b/services/web/app/views/layout-react.pug index 23cd77c101..74ff5d0654 100644 --- a/services/web/app/views/layout-react.pug +++ b/services/web/app/views/layout-react.pug @@ -1,5 +1,5 @@ -//- This is used for pages that are migrated to Bootstrap 5 but don't use Bootstrap's own JS, instead using -//- react-bootstrap for all Bootstrap components +//- Avoids including Bootstrap's own JS to prevent conflicts with react-bootstrap, +//- since Bootstrap 5's JS and react-bootstrap should not be used together on the same page. extends ./layout-base include ./_mixins/formMessages @@ -59,15 +59,15 @@ block append meta block body if typeof suppressNavbar === 'undefined' - include layout/navbar-marketing-react-bootstrap-5 + include layout/navbar-marketing-react block content if typeof suppressFooter === 'undefined' if showThinFooter - include layout/thin-footer-bootstrap-5 + include layout/thin-footer else - include layout/fat-footer-react-bootstrap-5 + include layout/fat-footer-react if typeof suppressPugCookieBanner === 'undefined' include _cookie_banner diff --git a/services/web/app/views/layout-website-redesign.pug b/services/web/app/views/layout-website-redesign.pug index 599be45754..a1c36b6f84 100644 --- a/services/web/app/views/layout-website-redesign.pug +++ b/services/web/app/views/layout-website-redesign.pug @@ -11,13 +11,13 @@ block append meta block body if typeof suppressNavbar == 'undefined' - include layout/navbar-marketing-bootstrap-5 + include layout/navbar-marketing block content if typeof suppressFooter == 'undefined' if showThinFooter - include layout/thin-footer-bootstrap-5 + include layout/thin-footer else include layout/fat-footer-website-redesign @@ -25,7 +25,7 @@ block body include _cookie_banner block contactModal - != moduleIncludes('contactModal-marketing-bootstrap-5', locals) + != moduleIncludes('contactModal-marketing', locals) block prepend foot-scripts +bootstrap-js diff --git a/services/web/app/views/layout/fat-footer-base.pug b/services/web/app/views/layout/fat-footer-base.pug index 2f5759f3c3..33e1a8ebf4 100644 --- a/services/web/app/views/layout/fat-footer-base.pug +++ b/services/web/app/views/layout/fat-footer-base.pug @@ -5,7 +5,7 @@ a(href='/legal') #{translate('privacy_and_terms')} a(href='https://www.digital-science.com/security-certifications/') #{translate('compliance')} ul.fat-footer-base-item.list-unstyled.fat-footer-base-language - include language-picker-bootstrap-5 + include language-picker .fat-footer-base-section.fat-footer-base-social .fat-footer-base-item a.fat-footer-social.x-logo(href='https://x.com/overleaf') diff --git a/services/web/app/views/layout/fat-footer-react-bootstrap-5.pug b/services/web/app/views/layout/fat-footer-react.pug similarity index 100% rename from services/web/app/views/layout/fat-footer-react-bootstrap-5.pug rename to services/web/app/views/layout/fat-footer-react.pug diff --git a/services/web/app/views/layout/language-picker-bootstrap-5.pug b/services/web/app/views/layout/language-picker-bootstrap-5.pug deleted file mode 100644 index 312b13ea18..0000000000 --- a/services/web/app/views/layout/language-picker-bootstrap-5.pug +++ /dev/null @@ -1,35 +0,0 @@ -include ../_mixins/material_symbol - -li.dropdown.dropup.subdued.language-picker(dropdown) - button#language-picker-toggle.btn.btn-link.btn-inline-link( - dropdown-toggle - data-ol-lang-selector-tooltip - data-bs-toggle='dropdown' - aria-haspopup='true' - aria-expanded='false' - aria-label='Select ' + translate('language') - tooltip=translate('language') - title=translate('language') - ) - +material-symbol('translate') - |   - span.language-picker-text #{settings.translatedLanguages[currentLngCode]} - - ul.dropdown-menu.dropdown-menu-sm-width( - role='menu' - aria-labelledby='language-picker-toggle' - ) - li.dropdown-header #{translate("language")} - each subdomainDetails, subdomain in settings.i18n.subdomainLang - if !subdomainDetails.hide - - let isActive = subdomainDetails.lngCode === currentLngCode - li.lng-option - a.menu-indent( - href=subdomainDetails.url + currentUrlWithQueryParams - role='menuitem' - class=['dropdown-item', {active: isActive}] - aria-selected=isActive ? 'true' : 'false' - ) - | #{settings.translatedLanguages[subdomainDetails.lngCode]} - if subdomainDetails.lngCode === currentLngCode - +material-symbol('check', 'dropdown-item-trailing-icon') diff --git a/services/web/app/views/layout/language-picker.pug b/services/web/app/views/layout/language-picker.pug index e88ff716ec..312b13ea18 100644 --- a/services/web/app/views/layout/language-picker.pug +++ b/services/web/app/views/layout/language-picker.pug @@ -1,27 +1,35 @@ +include ../_mixins/material_symbol + li.dropdown.dropup.subdued.language-picker(dropdown) - a#language-picker-toggle.dropdown-toggle( - href='#' + button#language-picker-toggle.btn.btn-link.btn-inline-link( dropdown-toggle data-ol-lang-selector-tooltip - data-toggle='dropdown' - role='button' + data-bs-toggle='dropdown' aria-haspopup='true' aria-expanded='false' aria-label='Select ' + translate('language') tooltip=translate('language') title=translate('language') ) - i.fa.fa-fw.fa-language - | - | #{settings.translatedLanguages[currentLngCode]} + +material-symbol('translate') + |   + span.language-picker-text #{settings.translatedLanguages[currentLngCode]} - ul.dropdown-menu(role='menu' aria-labelledby='language-picker-toggle') + ul.dropdown-menu.dropdown-menu-sm-width( + role='menu' + aria-labelledby='language-picker-toggle' + ) li.dropdown-header #{translate("language")} each subdomainDetails, subdomain in settings.i18n.subdomainLang if !subdomainDetails.hide + - let isActive = subdomainDetails.lngCode === currentLngCode li.lng-option a.menu-indent( href=subdomainDetails.url + currentUrlWithQueryParams role='menuitem' + class=['dropdown-item', {active: isActive}] + aria-selected=isActive ? 'true' : 'false' ) | #{settings.translatedLanguages[subdomainDetails.lngCode]} + if subdomainDetails.lngCode === currentLngCode + +material-symbol('check', 'dropdown-item-trailing-icon') diff --git a/services/web/app/views/layout/navbar-marketing-bootstrap-5.pug b/services/web/app/views/layout/navbar-marketing-bootstrap-5.pug deleted file mode 100644 index f55c4f8867..0000000000 --- a/services/web/app/views/layout/navbar-marketing-bootstrap-5.pug +++ /dev/null @@ -1,212 +0,0 @@ -include ../_mixins/navbar -include ../_mixins/material_symbol - -nav.navbar.navbar-default.navbar-main.navbar-expand-lg( - class={ - 'website-redesign-navbar': isWebsiteRedesign, - } - aria-label=translate('primary') -) - .container-fluid.navbar-container - .navbar-header - if settings.nav.custom_logo - a.navbar-brand( - href='/' - aria-label=settings.appName - style='background-image:url("' + settings.nav.custom_logo + '")' - ) - else if nav.title - a.navbar-title(href='/' aria-label=settings.appName) #{nav.title} - else - a.navbar-brand(href='/' aria-label=settings.appName) - - - var enableUpgradeButton = projectDashboardReact && usersBestSubscription && (usersBestSubscription.type === 'free' || usersBestSubscription.type === 'standalone-ai-add-on') - if enableUpgradeButton - a.btn.btn-primary.me-2.d-md-none( - href='/user/subscription/plans' - event-tracking='upgrade-button-click' - event-tracking-mb='true' - event-tracking-label='upgrade' - event-tracking-trigger='click' - event-segmentation={source: 'dashboard-top', projectDashboardReact: 'enabled', isDashboardSidebarHidden: 'true', isScreenWidthLessThan768px: 'true'} - ) #{translate("upgrade")} - - - var canDisplayAdminMenu = hasAdminAccess() - - var canDisplayAdminRedirect = canRedirectToAdminDomain() - - var canDisplaySplitTestMenu = hasFeature('saas') && (canDisplayAdminMenu || (getSessionUser() && getSessionUser().staffAccess && (getSessionUser().staffAccess.splitTestMetrics || getSessionUser().staffAccess.splitTestManagement))) - - var canDisplaySurveyMenu = hasFeature('saas') && canDisplayAdminMenu - - var canDisplayScriptLogMenu = hasFeature('saas') && hasAdminCapability('view-script-log') && canDisplayAdminMenu - - if typeof suppressNavbarRight === 'undefined' - button#navbar-toggle-btn.navbar-toggler.collapsed( - type='button' - data-bs-toggle='collapse' - data-bs-target='#navbar-main-collapse' - aria-controls='navbar-main-collapse' - aria-expanded='false' - aria-label='Toggle ' + translate('navigation') - ) - +material-symbol('menu') - - #navbar-main-collapse.navbar-collapse.collapse - ul.nav.navbar-nav.navbar-right.ms-auto(role='menubar') - if canDisplayAdminMenu || canDisplayAdminRedirect || canDisplaySplitTestMenu - +nav-item.dropdown.subdued - button.dropdown-toggle( - aria-haspopup='true' - aria-expanded='false' - data-bs-toggle='dropdown' - role='menuitem' - event-tracking='menu-expand' - event-tracking-mb='true' - event-tracking-trigger='click' - event-segmentation={item: 'admin', location: 'top-menu'} - ) - | Admin - +dropdown-menu.dropdown-menu-end - if canDisplayAdminMenu - +dropdown-menu-link-item(href='/admin') Manage Site - +dropdown-menu-link-item(href='/admin/user') Manage Users - +dropdown-menu-link-item(href='/admin/project') Project URL Lookup - if canDisplayAdminRedirect - +dropdown-menu-link-item(href=settings.adminUrl) Switch to Admin - if canDisplaySplitTestMenu - +dropdown-menu-link-item(href='/admin/split-test') Manage Feature Flags - if canDisplaySurveyMenu - +dropdown-menu-link-item(href='/admin/survey') Manage Surveys - if canDisplayScriptLogMenu - +dropdown-menu-link-item(href='/admin/script-logs') View Script Logs - - // loop over header_extras - each item in nav.header_extras - - - if ((item.only_when_logged_in && getSessionUser()) - || (item.only_when_logged_out && (!getSessionUser())) - || (!item.only_when_logged_out && !item.only_when_logged_in && !item.only_content_pages) - || (item.only_content_pages && (typeof suppressNavContentLinks === "undefined" || !suppressNavContentLinks)) - ){ - var showNavItem = true - } else { - var showNavItem = false - } - - if showNavItem - if item.dropdown - +nav-item.dropdown(class=item.class) - button.dropdown-toggle( - aria-haspopup='true' - aria-expanded='false' - data-bs-toggle='dropdown' - role='menuitem' - event-tracking='menu-expand' - event-tracking-mb='true' - event-tracking-trigger='click' - event-segmentation={item: item.trackingKey, location: 'top-menu'} - ) - | !{translate(item.text)} - +dropdown-menu.dropdown-menu-end - each child in item.dropdown - if child.divider - +dropdown-menu-divider - else if child.isContactUs - +dropdown-menu-link-item( - data-ol-open-contact-form-modal='contact-us' - data-bs-target='#contactUsModal' - href - data-bs-toggle='modal' - event-tracking='menu-click' - event-tracking-mb='true' - event-tracking-trigger='click' - event-segmentation={item: 'contact', location: 'top-menu'} - ) - span - | #{translate("contact_us")} - else - if child.url - +dropdown-menu-link-item( - href=child.url - class=child.class - event-tracking='menu-click' - event-tracking-mb='true' - event-tracking-trigger='click' - event-segmentation={item: child.trackingKey, location: 'top-menu'} - ) !{translate(child.text)} - else - +dropdown-menu-item - | !{translate(child.text)} - else - +nav-item(class=item.class) - if item.url - +nav-link( - href=item.url - class=item.class - event-tracking='menu-click' - event-tracking-mb='true' - event-tracking-trigger='click' - event-segmentation={item: item.trackingKey, location: 'top-menu'} - ) !{translate(item.text)} - else - | !{translate(item.text)} - - // logged out - if !getSessionUser() - // register link - if hasFeature('registration-page') - +nav-item.primary - +nav-link( - href='/register' - event-tracking='menu-click' - event-tracking-action='clicked' - event-tracking-trigger='click' - event-tracking-mb='true' - event-segmentation={page: currentUrl, item: 'register', location: 'top-menu'} - ) #{translate('sign_up')} - - // login link - +nav-item - +nav-link( - href='/login' - event-tracking='menu-click' - event-tracking-action='clicked' - event-tracking-trigger='click' - event-tracking-mb='true' - event-segmentation={page: currentUrl, item: 'login', location: 'top-menu'} - ) #{translate('log_in')} - - // projects link and account menu - if getSessionUser() - +nav-item - +nav-link(href='/project') #{translate('Projects')} - +nav-item.dropdown - button.dropdown-toggle( - aria-haspopup='true' - aria-expanded='false' - data-bs-toggle='dropdown' - role='menuitem' - event-tracking='menu-expand' - event-tracking-mb='true' - event-tracking-trigger='click' - event-segmentation={item: 'account', location: 'top-menu'} - ) - | #{translate('Account')} - +dropdown-menu.dropdown-menu-end - +dropdown-menu-item - .disabled.dropdown-item #{getSessionUser().email} - +dropdown-menu-divider - +dropdown-menu-link-item(href='/user/settings') #{translate('account_settings')} - if nav.showSubscriptionLink - +dropdown-menu-link-item(href='/user/subscription') #{translate('subscription')} - +dropdown-menu-divider - +dropdown-menu-item - //- - The button is outside the form but still belongs to it via the form attribute. The reason to do - this is that if the button is inside the form, screen readers will not count it in the total - number of menu items. - button.btn-link.text-left.dropdown-menu-button.dropdown-item( - role='menuitem' - tabindex='-1' - form='logOutForm' - ) - | #{translate('log_out')} - form(method='POST' action='/logout' id='logOutForm') - input(name='_csrf' type='hidden' value=csrfToken) diff --git a/services/web/app/views/layout/navbar-marketing-react-bootstrap-5.pug b/services/web/app/views/layout/navbar-marketing-react.pug similarity index 100% rename from services/web/app/views/layout/navbar-marketing-react-bootstrap-5.pug rename to services/web/app/views/layout/navbar-marketing-react.pug diff --git a/services/web/app/views/layout/navbar-marketing.pug b/services/web/app/views/layout/navbar-marketing.pug index 1b946a8e13..f55c4f8867 100644 --- a/services/web/app/views/layout/navbar-marketing.pug +++ b/services/web/app/views/layout/navbar-marketing.pug @@ -1,35 +1,14 @@ -nav.navbar.navbar-default.navbar-main( +include ../_mixins/navbar +include ../_mixins/material_symbol + +nav.navbar.navbar-default.navbar-main.navbar-expand-lg( class={ 'website-redesign-navbar': isWebsiteRedesign, } aria-label=translate('primary') ) - .container-fluid + .container-fluid.navbar-container .navbar-header - if typeof suppressNavbarRight == 'undefined' - button.navbar-toggle.collapsed( - type='button' - data-toggle='collapse' - data-target='#navbar-main-collapse' - aria-label='Toggle ' + translate('navigation') - ) - i.fa.fa-bars(aria-hidden='true') - - var enableUpgradeButton = projectDashboardReact && usersBestSubscription && (usersBestSubscription.type === 'free' || usersBestSubscription.type === 'standalone-ai-add-on') - if enableUpgradeButton - //- prettier-ignore - a.btn.btn-primary.float-end.me-2.visible-xs( - href='/user/subscription/plans' - event-tracking='upgrade-button-click' - event-tracking-mb='true' - event-tracking-label='upgrade' - event-tracking-trigger='click' - event-segmentation={ - source: "dashboard-top", - "project-dashboard-react": "enabled", - "is-dashboard-sidebar-hidden": "true", - "is-screen-width-less-than-768px": "true" - } - ) #{translate("upgrade")} if settings.nav.custom_logo a.navbar-brand( href='/' @@ -41,50 +20,62 @@ nav.navbar.navbar-default.navbar-main( else a.navbar-brand(href='/' aria-label=settings.appName) + - var enableUpgradeButton = projectDashboardReact && usersBestSubscription && (usersBestSubscription.type === 'free' || usersBestSubscription.type === 'standalone-ai-add-on') + if enableUpgradeButton + a.btn.btn-primary.me-2.d-md-none( + href='/user/subscription/plans' + event-tracking='upgrade-button-click' + event-tracking-mb='true' + event-tracking-label='upgrade' + event-tracking-trigger='click' + event-segmentation={source: 'dashboard-top', projectDashboardReact: 'enabled', isDashboardSidebarHidden: 'true', isScreenWidthLessThan768px: 'true'} + ) #{translate("upgrade")} + - var canDisplayAdminMenu = hasAdminAccess() - var canDisplayAdminRedirect = canRedirectToAdminDomain() - var canDisplaySplitTestMenu = hasFeature('saas') && (canDisplayAdminMenu || (getSessionUser() && getSessionUser().staffAccess && (getSessionUser().staffAccess.splitTestMetrics || getSessionUser().staffAccess.splitTestManagement))) - var canDisplaySurveyMenu = hasFeature('saas') && canDisplayAdminMenu - var canDisplayScriptLogMenu = hasFeature('saas') && hasAdminCapability('view-script-log') && canDisplayAdminMenu - if typeof suppressNavbarRight == 'undefined' + if typeof suppressNavbarRight === 'undefined' + button#navbar-toggle-btn.navbar-toggler.collapsed( + type='button' + data-bs-toggle='collapse' + data-bs-target='#navbar-main-collapse' + aria-controls='navbar-main-collapse' + aria-expanded='false' + aria-label='Toggle ' + translate('navigation') + ) + +material-symbol('menu') + #navbar-main-collapse.navbar-collapse.collapse - ul.nav.navbar-nav.navbar-right + ul.nav.navbar-nav.navbar-right.ms-auto(role='menubar') if canDisplayAdminMenu || canDisplayAdminRedirect || canDisplaySplitTestMenu - li.dropdown.subdued - a.dropdown-toggle( - href='#' - role='button' + +nav-item.dropdown.subdued + button.dropdown-toggle( aria-haspopup='true' aria-expanded='false' - data-toggle='dropdown' + data-bs-toggle='dropdown' + role='menuitem' event-tracking='menu-expand' event-tracking-mb='true' event-tracking-trigger='click' event-segmentation={item: 'admin', location: 'top-menu'} ) | Admin - span.caret - ul.dropdown-menu + +dropdown-menu.dropdown-menu-end if canDisplayAdminMenu - li - a(href='/admin') Manage Site - li - a(href='/admin/user') Manage Users - li - a(href='/admin/project') Project URL Lookup + +dropdown-menu-link-item(href='/admin') Manage Site + +dropdown-menu-link-item(href='/admin/user') Manage Users + +dropdown-menu-link-item(href='/admin/project') Project URL Lookup if canDisplayAdminRedirect - li - a(href=settings.adminUrl) Switch to Admin + +dropdown-menu-link-item(href=settings.adminUrl) Switch to Admin if canDisplaySplitTestMenu - li - a(href='/admin/split-test') Manage Feature Flags + +dropdown-menu-link-item(href='/admin/split-test') Manage Feature Flags if canDisplaySurveyMenu - li - a(href='/admin/survey') Manage Surveys + +dropdown-menu-link-item(href='/admin/survey') Manage Surveys if canDisplayScriptLogMenu - li - a(href='/admin/script-logs') View Script Logs + +dropdown-menu-link-item(href='/admin/script-logs') View Script Logs // loop over header_extras each item in nav.header_extras @@ -92,8 +83,8 @@ nav.navbar.navbar-default.navbar-main( if ((item.only_when_logged_in && getSessionUser()) || (item.only_when_logged_out && (!getSessionUser())) || (!item.only_when_logged_out && !item.only_when_logged_in && !item.only_content_pages) - || (item.only_content_pages && (typeof (suppressNavContentLinks) == "undefined" || !suppressNavContentLinks)) - ) { + || (item.only_content_pages && (typeof suppressNavContentLinks === "undefined" || !suppressNavContentLinks)) + ){ var showNavItem = true } else { var showNavItem = false @@ -101,53 +92,52 @@ nav.navbar.navbar-default.navbar-main( if showNavItem if item.dropdown - li.dropdown(class=item.class) - a.dropdown-toggle( - href='#' - role='button' + +nav-item.dropdown(class=item.class) + button.dropdown-toggle( aria-haspopup='true' aria-expanded='false' - data-toggle='dropdown' + data-bs-toggle='dropdown' + role='menuitem' event-tracking='menu-expand' event-tracking-mb='true' event-tracking-trigger='click' event-segmentation={item: item.trackingKey, location: 'top-menu'} ) | !{translate(item.text)} - span.caret - ul.dropdown-menu + +dropdown-menu.dropdown-menu-end each child in item.dropdown if child.divider - li.divider + +dropdown-menu-divider else if child.isContactUs - li - a( - data-ol-open-contact-form-modal='contact-us' - href + +dropdown-menu-link-item( + data-ol-open-contact-form-modal='contact-us' + data-bs-target='#contactUsModal' + href + data-bs-toggle='modal' + event-tracking='menu-click' + event-tracking-mb='true' + event-tracking-trigger='click' + event-segmentation={item: 'contact', location: 'top-menu'} + ) + span + | #{translate("contact_us")} + else + if child.url + +dropdown-menu-link-item( + href=child.url + class=child.class event-tracking='menu-click' event-tracking-mb='true' event-tracking-trigger='click' - event-segmentation={item: 'contact', location: 'top-menu'} - ) - span - | #{translate("contact_us")} - else - li - if child.url - a( - href=child.url - class=child.class - event-tracking='menu-click' - event-tracking-mb='true' - event-tracking-trigger='click' - event-segmentation={item: item.trackingKey, location: 'top-menu'} - ) !{translate(child.text)} - else + event-segmentation={item: child.trackingKey, location: 'top-menu'} + ) !{translate(child.text)} + else + +dropdown-menu-item | !{translate(child.text)} else - li(class=item.class) + +nav-item(class=item.class) if item.url - a( + +nav-link( href=item.url class=item.class event-tracking='menu-click' @@ -162,8 +152,8 @@ nav.navbar.navbar-default.navbar-main( if !getSessionUser() // register link if hasFeature('registration-page') - li.primary - a( + +nav-item.primary + +nav-link( href='/register' event-tracking='menu-click' event-tracking-action='clicked' @@ -173,8 +163,8 @@ nav.navbar.navbar-default.navbar-main( ) #{translate('sign_up')} // login link - li - a( + +nav-item + +nav-link( href='/login' event-tracking='menu-click' event-tracking-action='clicked' @@ -185,33 +175,38 @@ nav.navbar.navbar-default.navbar-main( // projects link and account menu if getSessionUser() - li - a(href='/project') #{translate('Projects')} - li.dropdown - a.dropdown-toggle( - href='#' - role='button' + +nav-item + +nav-link(href='/project') #{translate('Projects')} + +nav-item.dropdown + button.dropdown-toggle( aria-haspopup='true' aria-expanded='false' - data-toggle='dropdown' + data-bs-toggle='dropdown' + role='menuitem' event-tracking='menu-expand' event-tracking-mb='true' event-tracking-trigger='click' event-segmentation={item: 'account', location: 'top-menu'} ) | #{translate('Account')} - span.caret - ul.dropdown-menu - li - .subdued #{getSessionUser().email} - li.divider.hidden-xs.hidden-sm - li - a(href='/user/settings') #{translate('account_settings')} + +dropdown-menu.dropdown-menu-end + +dropdown-menu-item + .disabled.dropdown-item #{getSessionUser().email} + +dropdown-menu-divider + +dropdown-menu-link-item(href='/user/settings') #{translate('account_settings')} if nav.showSubscriptionLink - li - a(href='/user/subscription') #{translate('subscription')} - li.divider.hidden-xs.hidden-sm - li - form(method='POST' action='/logout') + +dropdown-menu-link-item(href='/user/subscription') #{translate('subscription')} + +dropdown-menu-divider + +dropdown-menu-item + //- + The button is outside the form but still belongs to it via the form attribute. The reason to do + this is that if the button is inside the form, screen readers will not count it in the total + number of menu items. + button.btn-link.text-left.dropdown-menu-button.dropdown-item( + role='menuitem' + tabindex='-1' + form='logOutForm' + ) + | #{translate('log_out')} + form(method='POST' action='/logout' id='logOutForm') input(name='_csrf' type='hidden' value=csrfToken) - button.btn-link.text-left.dropdown-menu-button #{translate('log_out')} diff --git a/services/web/app/views/layout/thin-footer-bootstrap-5.pug b/services/web/app/views/layout/thin-footer-bootstrap-5.pug deleted file mode 100644 index 4c29933ab1..0000000000 --- a/services/web/app/views/layout/thin-footer-bootstrap-5.pug +++ /dev/null @@ -1,38 +0,0 @@ -footer.site-footer - - var showLanguagePicker = Object.keys(settings.i18n.subdomainLang).length > 1 - - var hasCustomLeftNav = nav.left_footer && nav.left_footer.length > 0 - .site-footer-content.hidden-print - .row - ul.site-footer-items.col-lg-9 - if !settings.nav.hide_powered_by - li - //- year of Server Pro release, static - | © 2025 - | - a(href='https://www.overleaf.com/for/enterprises') Powered by Overleaf - - if showLanguagePicker || hasCustomLeftNav - li - strong.text-muted | - - if showLanguagePicker - include language-picker-bootstrap-5 - - if showLanguagePicker && hasCustomLeftNav - li - strong.text-muted | - - each item in nav.left_footer - li - if item.url - a(href=item.url class=item.class) !{translate(item.text)} - else - | !{item.text} - - ul.site-footer-items.col-lg-3.text-end - each item in nav.right_footer - li - if item.url - a(href=item.url class=item.class aria-label=item.label) !{item.text} - else - | !{item.text} diff --git a/services/web/app/views/layout/thin-footer.pug b/services/web/app/views/layout/thin-footer.pug index 879e337983..a5670be0df 100644 --- a/services/web/app/views/layout/thin-footer.pug +++ b/services/web/app/views/layout/thin-footer.pug @@ -3,10 +3,8 @@ footer.site-footer - var hasCustomLeftNav = nav.left_footer && nav.left_footer.length > 0 .site-footer-content.hidden-print .row - ul.col-md-9 - if hasFeature('saas') - li © #{new Date().getFullYear()} Overleaf - else if !settings.nav.hide_powered_by + ul.site-footer-items.col-lg-9 + if !settings.nav.hide_powered_by li //- year of Server Pro release, static | © 2025 @@ -31,7 +29,7 @@ footer.site-footer else | !{item.text} - ul.col-md-3.text-right + ul.site-footer-items.col-lg-3.text-end each item in nav.right_footer li if item.url diff --git a/services/web/app/views/subscriptions/team/invite_logged_out.pug b/services/web/app/views/subscriptions/team/invite_logged_out.pug index 5db16ee082..2d4827089c 100644 --- a/services/web/app/views/subscriptions/team/invite_logged_out.pug +++ b/services/web/app/views/subscriptions/team/invite_logged_out.pug @@ -11,8 +11,7 @@ block content .card.text-center .card-body .page-header - // TODO: Remove `team-invite-name` once we fully migrated to Bootstrap 5 - h1.text-center !{translate("invited_to_group", {inviterName: inviterName, appName: appName }, [{name: 'span', attrs: {class: 'team-invite-name'}}])} + h1.text-center !{translate("invited_to_group", {inviterName: inviterName, appName: appName })} if accountExists div diff --git a/services/web/frontend/js/features/chat/components/chat-fallback-error.tsx b/services/web/frontend/js/features/chat/components/chat-fallback-error.tsx index b572722c9f..04dca10885 100644 --- a/services/web/frontend/js/features/chat/components/chat-fallback-error.tsx +++ b/services/web/frontend/js/features/chat/components/chat-fallback-error.tsx @@ -1,6 +1,6 @@ import { useTranslation } from 'react-i18next' -import OLNotification from '@/features/ui/components/ol/ol-notification' -import OLButton from '@/features/ui/components/ol/ol-button' +import OLNotification from '@/shared/components/ol/ol-notification' +import OLButton from '@/shared/components/ol/ol-button' interface ChatFallbackErrorProps { reconnect?: () => void diff --git a/services/web/frontend/js/features/clone-project-modal/components/clone-project-modal-content.tsx b/services/web/frontend/js/features/clone-project-modal/components/clone-project-modal-content.tsx index 5754522360..34b6e2ba35 100644 --- a/services/web/frontend/js/features/clone-project-modal/components/clone-project-modal-content.tsx +++ b/services/web/frontend/js/features/clone-project-modal/components/clone-project-modal-content.tsx @@ -8,13 +8,13 @@ import { OLModalFooter, OLModalHeader, OLModalTitle, -} from '@/features/ui/components/ol/ol-modal' +} from '@/shared/components/ol/ol-modal' import Notification from '@/shared/components/notification' -import OLForm from '@/features/ui/components/ol/ol-form' -import OLFormGroup from '@/features/ui/components/ol/ol-form-group' -import OLFormControl from '@/features/ui/components/ol/ol-form-control' -import OLFormLabel from '@/features/ui/components/ol/ol-form-label' -import OLButton from '@/features/ui/components/ol/ol-button' +import OLForm from '@/shared/components/ol/ol-form' +import OLFormGroup from '@/shared/components/ol/ol-form-group' +import OLFormControl from '@/shared/components/ol/ol-form-control' +import OLFormLabel from '@/shared/components/ol/ol-form-label' +import OLButton from '@/shared/components/ol/ol-button' import { Tag } from '../../../../../app/src/Features/Tags/types' export default function CloneProjectModalContent({ diff --git a/services/web/frontend/js/features/clone-project-modal/components/clone-project-modal.tsx b/services/web/frontend/js/features/clone-project-modal/components/clone-project-modal.tsx index 8c5793b87e..03efac1242 100644 --- a/services/web/frontend/js/features/clone-project-modal/components/clone-project-modal.tsx +++ b/services/web/frontend/js/features/clone-project-modal/components/clone-project-modal.tsx @@ -1,6 +1,6 @@ import React, { memo, useCallback, useState } from 'react' import CloneProjectModalContent from './clone-project-modal-content' -import OLModal from '@/features/ui/components/ol/ol-modal' +import OLModal from '@/shared/components/ol/ol-modal' import { ClonedProject } from '../../../../../types/project/dashboard/api' import { Tag } from '../../../../../app/src/Features/Tags/types' diff --git a/services/web/frontend/js/features/clone-project-modal/components/clone-project-tag.tsx b/services/web/frontend/js/features/clone-project-modal/components/clone-project-tag.tsx index 16b19d3683..df7db10b71 100644 --- a/services/web/frontend/js/features/clone-project-modal/components/clone-project-tag.tsx +++ b/services/web/frontend/js/features/clone-project-modal/components/clone-project-tag.tsx @@ -1,7 +1,7 @@ import { FC } from 'react' import { Tag as TagType } from '../../../../../app/src/Features/Tags/types' import { getTagColor } from '@/features/project-list/util/tag' -import Tag from '@/features/ui/components/bootstrap-5/tag' +import Tag from '@/shared/components/tag' export const CloneProjectTag: FC<{ tag: TagType diff --git a/services/web/frontend/js/features/compromised-password/components/compromised-password-root.tsx b/services/web/frontend/js/features/compromised-password/components/compromised-password-root.tsx index e16755f078..6c95fee528 100644 --- a/services/web/frontend/js/features/compromised-password/components/compromised-password-root.tsx +++ b/services/web/frontend/js/features/compromised-password/components/compromised-password-root.tsx @@ -1,5 +1,5 @@ import useWaitForI18n from '@/shared/hooks/use-wait-for-i18n' -import OLButton from '@/features/ui/components/ol/ol-button' +import OLButton from '@/shared/components/ol/ol-button' import { Trans, useTranslation } from 'react-i18next' import { Interstitial } from '@/shared/components/interstitial' diff --git a/services/web/frontend/js/features/dictionary/components/dictionary-modal-content.tsx b/services/web/frontend/js/features/dictionary/components/dictionary-modal-content.tsx index 52664de105..04735d8500 100644 --- a/services/web/frontend/js/features/dictionary/components/dictionary-modal-content.tsx +++ b/services/web/frontend/js/features/dictionary/components/dictionary-modal-content.tsx @@ -8,11 +8,11 @@ import { OLModalFooter, OLModalHeader, OLModalTitle, -} from '@/features/ui/components/ol/ol-modal' -import OLTooltip from '@/features/ui/components/ol/ol-tooltip' -import OLNotification from '@/features/ui/components/ol/ol-notification' -import OLButton from '@/features/ui/components/ol/ol-button' -import OLIconButton from '@/features/ui/components/ol/ol-icon-button' +} from '@/shared/components/ol/ol-modal' +import OLTooltip from '@/shared/components/ol/ol-tooltip' +import OLNotification from '@/shared/components/ol/ol-notification' +import OLButton from '@/shared/components/ol/ol-button' +import OLIconButton from '@/shared/components/ol/ol-icon-button' import { learnedWords as initialLearnedWords } from '@/features/source-editor/extensions/spelling/learned-words' type DictionaryModalContentProps = { diff --git a/services/web/frontend/js/features/dictionary/components/dictionary-modal.tsx b/services/web/frontend/js/features/dictionary/components/dictionary-modal.tsx index dc5415a403..1414e118a9 100644 --- a/services/web/frontend/js/features/dictionary/components/dictionary-modal.tsx +++ b/services/web/frontend/js/features/dictionary/components/dictionary-modal.tsx @@ -1,7 +1,7 @@ import React from 'react' import DictionaryModalContent from './dictionary-modal-content' import withErrorBoundary from '../../../infrastructure/error-boundary' -import OLModal from '@/features/ui/components/ol/ol-modal' +import OLModal from '@/shared/components/ol/ol-modal' type DictionaryModalProps = { show?: boolean diff --git a/services/web/frontend/js/features/editor-left-menu/components/download-pdf.tsx b/services/web/frontend/js/features/editor-left-menu/components/download-pdf.tsx index 406c2b4cc5..ae756190b3 100644 --- a/services/web/frontend/js/features/editor-left-menu/components/download-pdf.tsx +++ b/services/web/frontend/js/features/editor-left-menu/components/download-pdf.tsx @@ -4,7 +4,7 @@ import { useProjectContext } from '../../../shared/context/project-context' import * as eventTracking from '../../../infrastructure/event-tracking' import { isSmallDevice } from '../../../infrastructure/event-tracking' import MaterialIcon from '@/shared/components/material-icon' -import OLTooltip from '@/features/ui/components/ol/ol-tooltip' +import OLTooltip from '@/shared/components/ol/ol-tooltip' export default function DownloadPDF() { const { t } = useTranslation() diff --git a/services/web/frontend/js/features/editor-left-menu/components/editor-left-menu.tsx b/services/web/frontend/js/features/editor-left-menu/components/editor-left-menu.tsx index 183e4d1836..ea4c06bc5c 100644 --- a/services/web/frontend/js/features/editor-left-menu/components/editor-left-menu.tsx +++ b/services/web/frontend/js/features/editor-left-menu/components/editor-left-menu.tsx @@ -6,7 +6,7 @@ import { FullSizeLoadingSpinner } from '@/shared/components/loading-spinner' import { Offcanvas } from 'react-bootstrap' import { EditorLeftMenuProvider } from './editor-left-menu-context' import withErrorBoundary from '@/infrastructure/error-boundary' -import OLNotification from '@/features/ui/components/ol/ol-notification' +import OLNotification from '@/shared/components/ol/ol-notification' import { useTranslation } from 'react-i18next' const EditorLeftMenuBody = lazy(() => import('./editor-left-menu-body')) diff --git a/services/web/frontend/js/features/editor-left-menu/components/settings-menu.tsx b/services/web/frontend/js/features/editor-left-menu/components/settings-menu.tsx index 5085fb0f49..66c4901bce 100644 --- a/services/web/frontend/js/features/editor-left-menu/components/settings-menu.tsx +++ b/services/web/frontend/js/features/editor-left-menu/components/settings-menu.tsx @@ -18,7 +18,7 @@ import SettingsSyntaxValidation from './settings/settings-syntax-validation' import SettingsMathPreview from './settings/settings-math-preview' import importOverleafModules from '../../../../macros/import-overleaf-module.macro' import { ElementType } from 'react' -import OLForm from '@/features/ui/components/ol/ol-form' +import OLForm from '@/shared/components/ol/ol-form' const moduleSettings: Array<{ import: { default: ElementType } diff --git a/services/web/frontend/js/features/editor-left-menu/components/settings/settings-dictionary.tsx b/services/web/frontend/js/features/editor-left-menu/components/settings/settings-dictionary.tsx index 5659f7b50e..8e836b8ebc 100644 --- a/services/web/frontend/js/features/editor-left-menu/components/settings/settings-dictionary.tsx +++ b/services/web/frontend/js/features/editor-left-menu/components/settings/settings-dictionary.tsx @@ -1,9 +1,9 @@ import { useState } from 'react' import { useTranslation } from 'react-i18next' import DictionaryModal from '../../../dictionary/components/dictionary-modal' -import OLButton from '@/features/ui/components/ol/ol-button' -import OLFormGroup from '@/features/ui/components/ol/ol-form-group' -import OLFormLabel from '@/features/ui/components/ol/ol-form-label' +import OLButton from '@/shared/components/ol/ol-button' +import OLFormGroup from '@/shared/components/ol/ol-form-group' +import OLFormLabel from '@/shared/components/ol/ol-form-label' export default function SettingsDictionary() { const { t } = useTranslation() diff --git a/services/web/frontend/js/features/editor-left-menu/components/settings/settings-menu-select.tsx b/services/web/frontend/js/features/editor-left-menu/components/settings/settings-menu-select.tsx index c48486ec1c..9bba51e28a 100644 --- a/services/web/frontend/js/features/editor-left-menu/components/settings/settings-menu-select.tsx +++ b/services/web/frontend/js/features/editor-left-menu/components/settings/settings-menu-select.tsx @@ -1,6 +1,6 @@ -import OLFormGroup from '@/features/ui/components/ol/ol-form-group' -import OLFormLabel from '@/features/ui/components/ol/ol-form-label' -import OLFormSelect from '@/features/ui/components/ol/ol-form-select' +import OLFormGroup from '@/shared/components/ol/ol-form-group' +import OLFormLabel from '@/shared/components/ol/ol-form-label' +import OLFormSelect from '@/shared/components/ol/ol-form-select' import { ChangeEventHandler, useCallback, useEffect, useRef } from 'react' import { Spinner } from 'react-bootstrap' import { useEditorLeftMenuContext } from '@/features/editor-left-menu/components/editor-left-menu-context' diff --git a/services/web/frontend/js/features/editor-navigation-toolbar/components/back-to-editor-button.tsx b/services/web/frontend/js/features/editor-navigation-toolbar/components/back-to-editor-button.tsx index 7c242941dd..7e7956cbee 100644 --- a/services/web/frontend/js/features/editor-navigation-toolbar/components/back-to-editor-button.tsx +++ b/services/web/frontend/js/features/editor-navigation-toolbar/components/back-to-editor-button.tsx @@ -1,6 +1,6 @@ import { useTranslation } from 'react-i18next' import MaterialIcon from '@/shared/components/material-icon' -import OLButton from '@/features/ui/components/ol/ol-button' +import OLButton from '@/shared/components/ol/ol-button' function BackToEditorButton({ onClick }: { onClick: () => void }) { const { t } = useTranslation() diff --git a/services/web/frontend/js/features/editor-navigation-toolbar/components/back-to-projects-button.tsx b/services/web/frontend/js/features/editor-navigation-toolbar/components/back-to-projects-button.tsx index f37ec498d6..8185060cfc 100644 --- a/services/web/frontend/js/features/editor-navigation-toolbar/components/back-to-projects-button.tsx +++ b/services/web/frontend/js/features/editor-navigation-toolbar/components/back-to-projects-button.tsx @@ -1,6 +1,6 @@ import { useTranslation } from 'react-i18next' import * as eventTracking from '../../../infrastructure/event-tracking' -import OLTooltip from '@/features/ui/components/ol/ol-tooltip' +import OLTooltip from '@/shared/components/ol/ol-tooltip' import MaterialIcon from '@/shared/components/material-icon' function BackToProjectsButton() { diff --git a/services/web/frontend/js/features/editor-navigation-toolbar/components/chat-toggle-button.tsx b/services/web/frontend/js/features/editor-navigation-toolbar/components/chat-toggle-button.tsx index 3336d59aa6..490548b8a7 100644 --- a/services/web/frontend/js/features/editor-navigation-toolbar/components/chat-toggle-button.tsx +++ b/services/web/frontend/js/features/editor-navigation-toolbar/components/chat-toggle-button.tsx @@ -1,7 +1,7 @@ import classNames from 'classnames' import { useTranslation } from 'react-i18next' import MaterialIcon from '@/shared/components/material-icon' -import OLBadge from '@/features/ui/components/ol/ol-badge' +import OLBadge from '@/shared/components/ol/ol-badge' function ChatToggleButton({ chatIsOpen, diff --git a/services/web/frontend/js/features/editor-navigation-toolbar/components/layout-dropdown-button.tsx b/services/web/frontend/js/features/editor-navigation-toolbar/components/layout-dropdown-button.tsx index addd6a013e..7cd4c12b40 100644 --- a/services/web/frontend/js/features/editor-navigation-toolbar/components/layout-dropdown-button.tsx +++ b/services/web/frontend/js/features/editor-navigation-toolbar/components/layout-dropdown-button.tsx @@ -6,7 +6,7 @@ import { DropdownMenu, DropdownToggle, DropdownToggleCustom, -} from '@/features/ui/components/bootstrap-5/dropdown-menu' +} from '@/shared/components/dropdown/dropdown-menu' import { Trans, useTranslation } from 'react-i18next' import { IdeLayout, @@ -17,7 +17,7 @@ import * as eventTracking from '../../../infrastructure/event-tracking' import useEventListener from '../../../shared/hooks/use-event-listener' import { DetachRole } from '@/shared/context/detach-context' import MaterialIcon from '@/shared/components/material-icon' -import OLTooltip from '@/features/ui/components/ol/ol-tooltip' +import OLTooltip from '@/shared/components/ol/ol-tooltip' const isActiveDropdownItem = ({ iconFor, diff --git a/services/web/frontend/js/features/editor-navigation-toolbar/components/online-users-widget.tsx b/services/web/frontend/js/features/editor-navigation-toolbar/components/online-users-widget.tsx index e9d8f52506..a433c4bdc0 100644 --- a/services/web/frontend/js/features/editor-navigation-toolbar/components/online-users-widget.tsx +++ b/services/web/frontend/js/features/editor-navigation-toolbar/components/online-users-widget.tsx @@ -6,9 +6,9 @@ import { DropdownItem, DropdownMenu, DropdownToggle, -} from '@/features/ui/components/bootstrap-5/dropdown-menu' +} from '@/shared/components/dropdown/dropdown-menu' import { getBackgroundColorForUserId } from '@/shared/utils/colors' -import OLTooltip from '@/features/ui/components/ol/ol-tooltip' +import OLTooltip from '@/shared/components/ol/ol-tooltip' import MaterialIcon from '@/shared/components/material-icon' import { OnlineUser } from '@/features/ide-react/context/online-users-context' diff --git a/services/web/frontend/js/features/editor-navigation-toolbar/components/project-name-editable-label.tsx b/services/web/frontend/js/features/editor-navigation-toolbar/components/project-name-editable-label.tsx index 87d00402d0..04a0143962 100644 --- a/services/web/frontend/js/features/editor-navigation-toolbar/components/project-name-editable-label.tsx +++ b/services/web/frontend/js/features/editor-navigation-toolbar/components/project-name-editable-label.tsx @@ -1,8 +1,8 @@ import { useEffect, useState, useRef } from 'react' import { useTranslation } from 'react-i18next' import classNames from 'classnames' -import OLFormControl from '@/features/ui/components/ol/ol-form-control' -import OLTooltip from '@/features/ui/components/ol/ol-tooltip' +import OLFormControl from '@/shared/components/ol/ol-form-control' +import OLTooltip from '@/shared/components/ol/ol-tooltip' import MaterialIcon from '@/shared/components/material-icon' type ProjectNameEditableLabelProps = { diff --git a/services/web/frontend/js/features/editor-navigation-toolbar/components/upgrade-prompt.tsx b/services/web/frontend/js/features/editor-navigation-toolbar/components/upgrade-prompt.tsx index b5bbc1a0ba..d3cc775af9 100644 --- a/services/web/frontend/js/features/editor-navigation-toolbar/components/upgrade-prompt.tsx +++ b/services/web/frontend/js/features/editor-navigation-toolbar/components/upgrade-prompt.tsx @@ -1,6 +1,6 @@ import { useTranslation } from 'react-i18next' import * as eventTracking from '../../../infrastructure/event-tracking' -import OLButton from '@/features/ui/components/ol/ol-button' +import OLButton from '@/shared/components/ol/ol-button' function UpgradePrompt() { const { t } = useTranslation() diff --git a/services/web/frontend/js/features/editor-navigation-toolbar/try-new-editor-button.tsx b/services/web/frontend/js/features/editor-navigation-toolbar/try-new-editor-button.tsx index a852b49fa4..bb5b7c9187 100644 --- a/services/web/frontend/js/features/editor-navigation-toolbar/try-new-editor-button.tsx +++ b/services/web/frontend/js/features/editor-navigation-toolbar/try-new-editor-button.tsx @@ -1,5 +1,5 @@ import { useCallback } from 'react' -import OLButton from '../ui/components/ol/ol-button' +import OLButton from '../../shared/components/ol/ol-button' import { useIdeRedesignSwitcherContext } from '../ide-react/context/ide-redesign-switcher-context' import MaterialIcon from '@/shared/components/material-icon' import { useTranslation } from 'react-i18next' diff --git a/services/web/frontend/js/features/file-tree/components/file-tree-context-menu.tsx b/services/web/frontend/js/features/file-tree/components/file-tree-context-menu.tsx index 18b8ee117d..83288031c8 100644 --- a/services/web/frontend/js/features/file-tree/components/file-tree-context-menu.tsx +++ b/services/web/frontend/js/features/file-tree/components/file-tree-context-menu.tsx @@ -3,7 +3,7 @@ import ReactDOM from 'react-dom' import { Dropdown, DropdownMenu, -} from '@/features/ui/components/bootstrap-5/dropdown-menu' +} from '@/shared/components/dropdown/dropdown-menu' import { useFileTreeData } from '@/shared/context/file-tree-data-context' import { useFileTreeMainContext } from '../contexts/file-tree-main' diff --git a/services/web/frontend/js/features/file-tree/components/file-tree-create/danger-message.tsx b/services/web/frontend/js/features/file-tree/components/file-tree-create/danger-message.tsx index d6b7173cb0..25ec5aff58 100644 --- a/services/web/frontend/js/features/file-tree/components/file-tree-create/danger-message.tsx +++ b/services/web/frontend/js/features/file-tree/components/file-tree-create/danger-message.tsx @@ -1,4 +1,4 @@ -import OLNotification from '@/features/ui/components/ol/ol-notification' +import OLNotification from '@/shared/components/ol/ol-notification' export default function DangerMessage({ children, diff --git a/services/web/frontend/js/features/file-tree/components/file-tree-create/file-tree-create-name-input.tsx b/services/web/frontend/js/features/file-tree/components/file-tree-create/file-tree-create-name-input.tsx index 80c53f1b63..cccc1329d9 100644 --- a/services/web/frontend/js/features/file-tree/components/file-tree-create/file-tree-create-name-input.tsx +++ b/services/web/frontend/js/features/file-tree/components/file-tree-create/file-tree-create-name-input.tsx @@ -6,10 +6,10 @@ import { DuplicateFilenameError, InvalidFilenameError, } from '../../errors' -import OLFormGroup from '@/features/ui/components/ol/ol-form-group' -import OLFormLabel from '@/features/ui/components/ol/ol-form-label' -import OLFormControl from '@/features/ui/components/ol/ol-form-control' -import OLNotification from '@/features/ui/components/ol/ol-notification' +import OLFormGroup from '@/shared/components/ol/ol-form-group' +import OLFormLabel from '@/shared/components/ol/ol-form-label' +import OLFormControl from '@/shared/components/ol/ol-form-control' +import OLNotification from '@/shared/components/ol/ol-notification' /** * A form component that renders a text input with label, diff --git a/services/web/frontend/js/features/file-tree/components/file-tree-create/file-tree-modal-create-file-footer.tsx b/services/web/frontend/js/features/file-tree/components/file-tree-create/file-tree-modal-create-file-footer.tsx index d1966f1b5d..21903b771c 100644 --- a/services/web/frontend/js/features/file-tree/components/file-tree-create/file-tree-modal-create-file-footer.tsx +++ b/services/web/frontend/js/features/file-tree/components/file-tree-create/file-tree-modal-create-file-footer.tsx @@ -2,8 +2,8 @@ import { useTranslation } from 'react-i18next' import { useFileTreeCreateForm } from '../../contexts/file-tree-create-form' import { useFileTreeActionable } from '../../contexts/file-tree-actionable' import { useFileTreeData } from '../../../../shared/context/file-tree-data-context' -import OLButton from '@/features/ui/components/ol/ol-button' -import OLNotification from '@/features/ui/components/ol/ol-notification' +import OLButton from '@/shared/components/ol/ol-button' +import OLNotification from '@/shared/components/ol/ol-notification' export default function FileTreeModalCreateFileFooter() { const { valid } = useFileTreeCreateForm() diff --git a/services/web/frontend/js/features/file-tree/components/file-tree-create/file-tree-modal-create-file-mode.tsx b/services/web/frontend/js/features/file-tree/components/file-tree-create/file-tree-modal-create-file-mode.tsx index eb7e0466f4..403b333e7a 100644 --- a/services/web/frontend/js/features/file-tree/components/file-tree-create/file-tree-modal-create-file-mode.tsx +++ b/services/web/frontend/js/features/file-tree/components/file-tree-create/file-tree-modal-create-file-mode.tsx @@ -1,7 +1,7 @@ import classnames from 'classnames' import { useFileTreeActionable } from '../../contexts/file-tree-actionable' import * as eventTracking from '../../../../infrastructure/event-tracking' -import OLButton from '@/features/ui/components/ol/ol-button' +import OLButton from '@/shared/components/ol/ol-button' export default function FileTreeModalCreateFileMode({ mode, diff --git a/services/web/frontend/js/features/file-tree/components/file-tree-create/file-tree-upload-conflicts.tsx b/services/web/frontend/js/features/file-tree/components/file-tree-create/file-tree-upload-conflicts.tsx index c582edef23..ed44a56f54 100644 --- a/services/web/frontend/js/features/file-tree/components/file-tree-create/file-tree-upload-conflicts.tsx +++ b/services/web/frontend/js/features/file-tree/components/file-tree-create/file-tree-upload-conflicts.tsx @@ -4,7 +4,7 @@ import { useProjectContext } from '@/shared/context/project-context' import { useCallback } from 'react' import { syncDelete } from '@/features/file-tree/util/sync-mutation' import { TFunction } from 'i18next' -import OLButton from '@/features/ui/components/ol/ol-button' +import OLButton from '@/shared/components/ol/ol-button' export type Conflict = { entity: FileTreeEntity diff --git a/services/web/frontend/js/features/file-tree/components/file-tree-create/modes/file-tree-import-from-project.tsx b/services/web/frontend/js/features/file-tree/components/file-tree-create/modes/file-tree-import-from-project.tsx index 8084043af8..7272a0bab9 100644 --- a/services/web/frontend/js/features/file-tree/components/file-tree-create/modes/file-tree-import-from-project.tsx +++ b/services/web/frontend/js/features/file-tree/components/file-tree-create/modes/file-tree-import-from-project.tsx @@ -19,11 +19,11 @@ import * as eventTracking from '../../../../../infrastructure/event-tracking' import { File } from '@/features/source-editor/utils/file' import { Project } from '../../../../../../../types/project' import getMeta from '@/utils/meta' -import OLButton from '@/features/ui/components/ol/ol-button' -import OLFormGroup from '@/features/ui/components/ol/ol-form-group' -import OLFormLabel from '@/features/ui/components/ol/ol-form-label' -import OLForm from '@/features/ui/components/ol/ol-form' -import OLFormSelect from '@/features/ui/components/ol/ol-form-select' +import OLButton from '@/shared/components/ol/ol-button' +import OLFormGroup from '@/shared/components/ol/ol-form-group' +import OLFormLabel from '@/shared/components/ol/ol-form-label' +import OLForm from '@/shared/components/ol/ol-form' +import OLFormSelect from '@/shared/components/ol/ol-form-select' import { Spinner } from 'react-bootstrap' export default function FileTreeImportFromProject() { diff --git a/services/web/frontend/js/features/file-tree/components/file-tree-create/modes/file-tree-import-from-url.jsx b/services/web/frontend/js/features/file-tree/components/file-tree-create/modes/file-tree-import-from-url.jsx index 9a6f121abc..ad0cb7c6ac 100644 --- a/services/web/frontend/js/features/file-tree/components/file-tree-create/modes/file-tree-import-from-url.jsx +++ b/services/web/frontend/js/features/file-tree/components/file-tree-create/modes/file-tree-import-from-url.jsx @@ -6,9 +6,9 @@ import { useFileTreeCreateName } from '../../../contexts/file-tree-create-name' import { useFileTreeCreateForm } from '../../../contexts/file-tree-create-form' import ErrorMessage from '../error-message' import * as eventTracking from '../../../../../infrastructure/event-tracking' -import OLFormGroup from '@/features/ui/components/ol/ol-form-group' -import OLFormLabel from '@/features/ui/components/ol/ol-form-label' -import OLFormControl from '@/features/ui/components/ol/ol-form-control' +import OLFormGroup from '@/shared/components/ol/ol-form-group' +import OLFormLabel from '@/shared/components/ol/ol-form-label' +import OLFormControl from '@/shared/components/ol/ol-form-control' export default function FileTreeImportFromUrl() { const { t } = useTranslation() diff --git a/services/web/frontend/js/features/file-tree/components/file-tree-error.tsx b/services/web/frontend/js/features/file-tree/components/file-tree-error.tsx index 9093691210..67a2619894 100644 --- a/services/web/frontend/js/features/file-tree/components/file-tree-error.tsx +++ b/services/web/frontend/js/features/file-tree/components/file-tree-error.tsx @@ -1,6 +1,6 @@ import { useTranslation } from 'react-i18next' import { useLocation } from '../../../shared/hooks/use-location' -import OLButton from '@/features/ui/components/ol/ol-button' +import OLButton from '@/shared/components/ol/ol-button' function FileTreeError() { const { t } = useTranslation() diff --git a/services/web/frontend/js/features/file-tree/components/file-tree-item/file-tree-item-menu-items.tsx b/services/web/frontend/js/features/file-tree/components/file-tree-item/file-tree-item-menu-items.tsx index 571156a0a4..0bc02dfe99 100644 --- a/services/web/frontend/js/features/file-tree/components/file-tree-item/file-tree-item-menu-items.tsx +++ b/services/web/frontend/js/features/file-tree/components/file-tree-item/file-tree-item-menu-items.tsx @@ -6,7 +6,7 @@ import { useProjectContext } from '@/shared/context/project-context' import { DropdownDivider, DropdownItem, -} from '@/features/ui/components/bootstrap-5/dropdown-menu' +} from '@/shared/components/dropdown/dropdown-menu' import { useFileTreeActionable } from '../../contexts/file-tree-actionable' function FileTreeItemMenuItems() { diff --git a/services/web/frontend/js/features/file-tree/components/file-tree-toolbar.tsx b/services/web/frontend/js/features/file-tree/components/file-tree-toolbar.tsx index d25d1f36c8..a759452472 100644 --- a/services/web/frontend/js/features/file-tree/components/file-tree-toolbar.tsx +++ b/services/web/frontend/js/features/file-tree/components/file-tree-toolbar.tsx @@ -2,9 +2,9 @@ import { useTranslation } from 'react-i18next' import * as eventTracking from '../../../infrastructure/event-tracking' import { useFileTreeActionable } from '../contexts/file-tree-actionable' import { useFileTreeData } from '@/shared/context/file-tree-data-context' -import OLTooltip from '@/features/ui/components/ol/ol-tooltip' +import OLTooltip from '@/shared/components/ol/ol-tooltip' import MaterialIcon from '@/shared/components/material-icon' -import OLButtonToolbar from '@/features/ui/components/ol/ol-button-toolbar' +import OLButtonToolbar from '@/shared/components/ol/ol-button-toolbar' import importOverleafModules from '../../../../macros/import-overleaf-module.macro' import React, { ElementType } from 'react' diff --git a/services/web/frontend/js/features/file-tree/components/modals/file-tree-modal-create-file.jsx b/services/web/frontend/js/features/file-tree/components/modals/file-tree-modal-create-file.jsx index e61a6ba2c9..9d0b6fc9a0 100644 --- a/services/web/frontend/js/features/file-tree/components/modals/file-tree-modal-create-file.jsx +++ b/services/web/frontend/js/features/file-tree/components/modals/file-tree-modal-create-file.jsx @@ -8,7 +8,7 @@ import OLModal, { OLModalFooter, OLModalHeader, OLModalTitle, -} from '@/features/ui/components/ol/ol-modal' +} from '@/shared/components/ol/ol-modal' export default function FileTreeModalCreateFile() { const { t } = useTranslation() diff --git a/services/web/frontend/js/features/file-tree/components/modals/file-tree-modal-create-folder.tsx b/services/web/frontend/js/features/file-tree/components/modals/file-tree-modal-create-folder.tsx index 7342c1f752..4a5b37cfce 100644 --- a/services/web/frontend/js/features/file-tree/components/modals/file-tree-modal-create-folder.tsx +++ b/services/web/frontend/js/features/file-tree/components/modals/file-tree-modal-create-folder.tsx @@ -9,8 +9,8 @@ import OLModal, { OLModalFooter, OLModalHeader, OLModalTitle, -} from '@/features/ui/components/ol/ol-modal' -import OLButton from '@/features/ui/components/ol/ol-button' +} from '@/shared/components/ol/ol-modal' +import OLButton from '@/shared/components/ol/ol-button' function FileTreeModalCreateFolder() { const { t } = useTranslation() diff --git a/services/web/frontend/js/features/file-tree/components/modals/file-tree-modal-delete.jsx b/services/web/frontend/js/features/file-tree/components/modals/file-tree-modal-delete.jsx index 1d99d47c6a..fc8a5f4bbc 100644 --- a/services/web/frontend/js/features/file-tree/components/modals/file-tree-modal-delete.jsx +++ b/services/web/frontend/js/features/file-tree/components/modals/file-tree-modal-delete.jsx @@ -6,9 +6,9 @@ import OLModal, { OLModalFooter, OLModalHeader, OLModalTitle, -} from '@/features/ui/components/ol/ol-modal' -import OLButton from '@/features/ui/components/ol/ol-button' -import OLNotification from '@/features/ui/components/ol/ol-notification' +} from '@/shared/components/ol/ol-modal' +import OLButton from '@/shared/components/ol/ol-button' +import OLNotification from '@/shared/components/ol/ol-notification' import { useFileTreeSelectable } from '../../contexts/file-tree-selectable' function FileTreeModalDelete() { diff --git a/services/web/frontend/js/features/file-tree/components/modals/file-tree-modal-error.jsx b/services/web/frontend/js/features/file-tree/components/modals/file-tree-modal-error.jsx index 5215f6960a..96cd77f064 100644 --- a/services/web/frontend/js/features/file-tree/components/modals/file-tree-modal-error.jsx +++ b/services/web/frontend/js/features/file-tree/components/modals/file-tree-modal-error.jsx @@ -13,8 +13,8 @@ import OLModal, { OLModalFooter, OLModalHeader, OLModalTitle, -} from '@/features/ui/components/ol/ol-modal' -import OLButton from '@/features/ui/components/ol/ol-button' +} from '@/shared/components/ol/ol-modal' +import OLButton from '@/shared/components/ol/ol-button' function FileTreeModalError() { const { t } = useTranslation() diff --git a/services/web/frontend/js/features/file-view/components/file-view-header.tsx b/services/web/frontend/js/features/file-view/components/file-view-header.tsx index 0c9a218bc8..b6ec574f78 100644 --- a/services/web/frontend/js/features/file-view/components/file-view-header.tsx +++ b/services/web/frontend/js/features/file-view/components/file-view-header.tsx @@ -13,7 +13,7 @@ import { BinaryFile, hasProvider, LinkedFile } from '../types/binary-file' import FileViewRefreshButton from './file-view-refresh-button' import FileViewRefreshError from './file-view-refresh-error' import MaterialIcon from '@/shared/components/material-icon' -import OLButton from '@/features/ui/components/ol/ol-button' +import OLButton from '@/shared/components/ol/ol-button' const tprFileViewInfo = importOverleafModules('tprFileViewInfo') as { import: { TPRFileViewInfo: ElementType } diff --git a/services/web/frontend/js/features/file-view/components/file-view-refresh-button.tsx b/services/web/frontend/js/features/file-view/components/file-view-refresh-button.tsx index eafe369500..b032e8cd9f 100644 --- a/services/web/frontend/js/features/file-view/components/file-view-refresh-button.tsx +++ b/services/web/frontend/js/features/file-view/components/file-view-refresh-button.tsx @@ -11,7 +11,7 @@ import { useProjectContext } from '@/shared/context/project-context' import type { BinaryFile } from '../types/binary-file' import { Nullable } from '../../../../../types/utils' import importOverleafModules from '../../../../macros/import-overleaf-module.macro' -import OLButton from '@/features/ui/components/ol/ol-button' +import OLButton from '@/shared/components/ol/ol-button' import { sendMB } from '@/infrastructure/event-tracking' import useIsMounted from '@/shared/hooks/use-is-mounted' diff --git a/services/web/frontend/js/features/file-view/components/file-view-refresh-error.tsx b/services/web/frontend/js/features/file-view/components/file-view-refresh-error.tsx index 363c663988..767d7727a1 100644 --- a/services/web/frontend/js/features/file-view/components/file-view-refresh-error.tsx +++ b/services/web/frontend/js/features/file-view/components/file-view-refresh-error.tsx @@ -2,7 +2,7 @@ import type { ElementType } from 'react' import { useTranslation } from 'react-i18next' import importOverleafModules from '../../../../macros/import-overleaf-module.macro' import { BinaryFile } from '../types/binary-file' -import OLNotification from '@/features/ui/components/ol/ol-notification' +import OLNotification from '@/shared/components/ol/ol-notification' type FileViewRefreshErrorProps = { file: BinaryFile diff --git a/services/web/frontend/js/features/group-management/components/add-seats/add-seats.tsx b/services/web/frontend/js/features/group-management/components/add-seats/add-seats.tsx index f598ee9ddc..dda6f2a690 100644 --- a/services/web/frontend/js/features/group-management/components/add-seats/add-seats.tsx +++ b/services/web/frontend/js/features/group-management/components/add-seats/add-seats.tsx @@ -5,7 +5,7 @@ import withErrorBoundary from '@/infrastructure/error-boundary' import useAbortController from '@/shared/hooks/use-abort-controller' import LoadingSpinner from '@/shared/components/loading-spinner' import Notification from '@/shared/components/notification' -import IconButton from '@/features/ui/components/bootstrap-5/icon-button' +import IconButton from '@/shared/components/button/icon-button' import { Card, Row, @@ -14,8 +14,8 @@ import { FormLabel, FormControl, } from 'react-bootstrap' -import FormText from '@/features/ui/components/bootstrap-5/form/form-text' -import Button from '@/features/ui/components/bootstrap-5/button' +import FormText from '@/shared/components/form/form-text' +import Button from '@/shared/components/button/button' import PoNumber from '@/features/group-management/components/add-seats/po-number' import CostSummary from '@/features/group-management/components/add-seats/cost-summary' import RequestStatus from '@/features/group-management/components/request-status' diff --git a/services/web/frontend/js/features/group-management/components/add-seats/po-number.tsx b/services/web/frontend/js/features/group-management/components/add-seats/po-number.tsx index c6257553d6..580f8dbb11 100644 --- a/services/web/frontend/js/features/group-management/components/add-seats/po-number.tsx +++ b/services/web/frontend/js/features/group-management/components/add-seats/po-number.tsx @@ -1,8 +1,8 @@ import { useState } from 'react' import { useTranslation } from 'react-i18next' import { FormControl, FormGroup, FormLabel } from 'react-bootstrap' -import FormText from '@/features/ui/components/bootstrap-5/form/form-text' -import OLFormCheckbox from '@/features/ui/components/ol/ol-form-checkbox' +import FormText from '@/shared/components/form/form-text' +import OLFormCheckbox from '@/shared/components/ol/ol-form-checkbox' type PoNumberProps = { error: string | undefined diff --git a/services/web/frontend/js/features/group-management/components/back-button.tsx b/services/web/frontend/js/features/group-management/components/back-button.tsx index 2846fc7bc3..f1d01cfb54 100644 --- a/services/web/frontend/js/features/group-management/components/back-button.tsx +++ b/services/web/frontend/js/features/group-management/components/back-button.tsx @@ -1,4 +1,4 @@ -import IconButton from '@/features/ui/components/bootstrap-5/icon-button' +import IconButton from '@/shared/components/button/icon-button' type BackButtonProps = { href: string diff --git a/services/web/frontend/js/features/group-management/components/card.tsx b/services/web/frontend/js/features/group-management/components/card.tsx index ff51231f5a..8add309a2f 100644 --- a/services/web/frontend/js/features/group-management/components/card.tsx +++ b/services/web/frontend/js/features/group-management/components/card.tsx @@ -2,7 +2,7 @@ import { useTranslation } from 'react-i18next' import getMeta from '@/utils/meta' import useWaitForI18n from '@/shared/hooks/use-wait-for-i18n' import { Card as BSCard, CardBody, Col, Row } from 'react-bootstrap' -import IconButton from '@/features/ui/components/bootstrap-5/icon-button' +import IconButton from '@/shared/components/button/icon-button' type CardProps = { children: React.ReactNode diff --git a/services/web/frontend/js/features/group-management/components/error-alert.tsx b/services/web/frontend/js/features/group-management/components/error-alert.tsx index e96ded5d7c..bd31938cca 100644 --- a/services/web/frontend/js/features/group-management/components/error-alert.tsx +++ b/services/web/frontend/js/features/group-management/components/error-alert.tsx @@ -1,5 +1,5 @@ import { useTranslation } from 'react-i18next' -import OLNotification from '@/features/ui/components/ol/ol-notification' +import OLNotification from '@/shared/components/ol/ol-notification' export type APIError = { message?: string diff --git a/services/web/frontend/js/features/group-management/components/group-members.tsx b/services/web/frontend/js/features/group-management/components/group-members.tsx index d775e70511..73e6da8e7c 100644 --- a/services/web/frontend/js/features/group-management/components/group-members.tsx +++ b/services/web/frontend/js/features/group-management/components/group-members.tsx @@ -7,13 +7,13 @@ import ErrorAlert from './error-alert' import MembersList from './members-table/members-list' import { sendMB } from '../../../infrastructure/event-tracking' import BackButton from '@/features/group-management/components/back-button' -import OLRow from '@/features/ui/components/ol/ol-row' -import OLCol from '@/features/ui/components/ol/ol-col' -import OLCard from '@/features/ui/components/ol/ol-card' -import OLButton from '@/features/ui/components/ol/ol-button' -import OLFormControl from '@/features/ui/components/ol/ol-form-control' -import OLFormText from '@/features/ui/components/ol/ol-form-text' -import OLNotification from '@/features/ui/components/ol/ol-notification' +import OLRow from '@/shared/components/ol/ol-row' +import OLCol from '@/shared/components/ol/ol-col' +import OLCard from '@/shared/components/ol/ol-card' +import OLButton from '@/shared/components/ol/ol-button' +import OLFormControl from '@/shared/components/ol/ol-form-control' +import OLFormText from '@/shared/components/ol/ol-form-text' +import OLNotification from '@/shared/components/ol/ol-notification' export default function GroupMembers() { const { isReady } = useWaitForI18n() diff --git a/services/web/frontend/js/features/group-management/components/managers-table.tsx b/services/web/frontend/js/features/group-management/components/managers-table.tsx index d91b4acc67..6edf2490e6 100644 --- a/services/web/frontend/js/features/group-management/components/managers-table.tsx +++ b/services/web/frontend/js/features/group-management/components/managers-table.tsx @@ -8,16 +8,16 @@ import UserRow from './user-row' import useUserSelection from '../hooks/use-user-selection' import { User } from '../../../../../types/group-management/user' import { debugConsole } from '@/utils/debugging' -import OLRow from '@/features/ui/components/ol/ol-row' -import OLCol from '@/features/ui/components/ol/ol-col' +import OLRow from '@/shared/components/ol/ol-row' +import OLCol from '@/shared/components/ol/ol-col' import BackButton from '@/features/group-management/components/back-button' -import OLCard from '@/features/ui/components/ol/ol-card' -import OLButton from '@/features/ui/components/ol/ol-button' -import OLFormControl from '@/features/ui/components/ol/ol-form-control' -import OLFormText from '@/features/ui/components/ol/ol-form-text' -import OLTable from '@/features/ui/components/ol/ol-table' -import OLTooltip from '@/features/ui/components/ol/ol-tooltip' -import OLFormCheckbox from '@/features/ui/components/ol/ol-form-checkbox' +import OLCard from '@/shared/components/ol/ol-card' +import OLButton from '@/shared/components/ol/ol-button' +import OLFormControl from '@/shared/components/ol/ol-form-control' +import OLFormText from '@/shared/components/ol/ol-form-text' +import OLTable from '@/shared/components/ol/ol-table' +import OLTooltip from '@/shared/components/ol/ol-tooltip' +import OLFormCheckbox from '@/shared/components/ol/ol-form-checkbox' type ManagersPaths = { addMember: string diff --git a/services/web/frontend/js/features/group-management/components/manually-collected-subscription.tsx b/services/web/frontend/js/features/group-management/components/manually-collected-subscription.tsx index b2f2580b5f..633c2d23f8 100644 --- a/services/web/frontend/js/features/group-management/components/manually-collected-subscription.tsx +++ b/services/web/frontend/js/features/group-management/components/manually-collected-subscription.tsx @@ -1,5 +1,5 @@ import { Trans, useTranslation } from 'react-i18next' -import OLNotification from '@/features/ui/components/ol/ol-notification' +import OLNotification from '@/shared/components/ol/ol-notification' import Card from '@/features/group-management/components/card' import useWaitForI18n from '@/shared/hooks/use-wait-for-i18n' diff --git a/services/web/frontend/js/features/group-management/components/members-table/dropdown-button.tsx b/services/web/frontend/js/features/group-management/components/members-table/dropdown-button.tsx index 9e7038363a..016f557f01 100644 --- a/services/web/frontend/js/features/group-management/components/members-table/dropdown-button.tsx +++ b/services/web/frontend/js/features/group-management/components/members-table/dropdown-button.tsx @@ -10,7 +10,7 @@ import { DropdownItem, DropdownMenu, DropdownToggle, -} from '@/features/ui/components/bootstrap-5/dropdown-menu' +} from '@/shared/components/dropdown/dropdown-menu' import { User } from '../../../../../../types/group-management/user' import useAsync from '@/shared/hooks/use-async' import { type FetchError, postJSON } from '@/infrastructure/fetch-json' @@ -18,7 +18,7 @@ import { GroupUserAlert } from '../../utils/types' import { useGroupMembersContext } from '../../context/group-members-context' import getMeta from '@/utils/meta' import MaterialIcon from '@/shared/components/material-icon' -import DropdownListItem from '@/features/ui/components/bootstrap-5/dropdown-list-item' +import DropdownListItem from '@/shared/components/dropdown/dropdown-list-item' import { Spinner } from 'react-bootstrap' import { sendMB } from '@/infrastructure/event-tracking' diff --git a/services/web/frontend/js/features/group-management/components/members-table/list-alert.tsx b/services/web/frontend/js/features/group-management/components/members-table/list-alert.tsx index 295ba36fa3..a05ab4dbea 100644 --- a/services/web/frontend/js/features/group-management/components/members-table/list-alert.tsx +++ b/services/web/frontend/js/features/group-management/components/members-table/list-alert.tsx @@ -1,7 +1,7 @@ import { Trans } from 'react-i18next' import type { GroupUserAlertVariant } from '../../utils/types' import NotificationScrolledTo from '@/shared/components/notification-scrolled-to' -import OLNotification from '@/features/ui/components/ol/ol-notification' +import OLNotification from '@/shared/components/ol/ol-notification' type GroupUsersListAlertProps = { variant: GroupUserAlertVariant diff --git a/services/web/frontend/js/features/group-management/components/members-table/member-row.tsx b/services/web/frontend/js/features/group-management/components/members-table/member-row.tsx index d898494959..84d97b0767 100644 --- a/services/web/frontend/js/features/group-management/components/members-table/member-row.tsx +++ b/services/web/frontend/js/features/group-management/components/members-table/member-row.tsx @@ -8,8 +8,8 @@ import SSOStatus from './sso-status' import DropdownButton from './dropdown-button' import SelectUserCheckbox from './select-user-checkbox' import getMeta from '@/utils/meta' -import OLTooltip from '@/features/ui/components/ol/ol-tooltip' -import OLTag from '@/features/ui/components/ol/ol-tag' +import OLTooltip from '@/shared/components/ol/ol-tooltip' +import OLTag from '@/shared/components/ol/ol-tag' import MaterialIcon from '@/shared/components/material-icon' import classnames from 'classnames' diff --git a/services/web/frontend/js/features/group-management/components/members-table/members-list.tsx b/services/web/frontend/js/features/group-management/components/members-table/members-list.tsx index 415fa1c56e..9202315a31 100644 --- a/services/web/frontend/js/features/group-management/components/members-table/members-list.tsx +++ b/services/web/frontend/js/features/group-management/components/members-table/members-list.tsx @@ -11,15 +11,15 @@ import SelectAllCheckbox from './select-all-checkbox' import classNames from 'classnames' import getMeta from '@/utils/meta' import UnlinkUserModal from './unlink-user-modal' -import OLTable from '@/features/ui/components/ol/ol-table' -import OLTooltip from '@/features/ui/components/ol/ol-tooltip' +import OLTable from '@/shared/components/ol/ol-table' +import OLTooltip from '@/shared/components/ol/ol-tooltip' import Pagination from '@/shared/components/pagination' -import OLFormControl from '@/features/ui/components/ol/ol-form-control' -import OLForm from '@/features/ui/components/ol/ol-form' -import OLFormGroup from '@/features/ui/components/ol/ol-form-group' -import OLCol from '@/features/ui/components/ol/ol-col' +import OLFormControl from '@/shared/components/ol/ol-form-control' +import OLForm from '@/shared/components/ol/ol-form' +import OLFormGroup from '@/shared/components/ol/ol-form-group' +import OLCol from '@/shared/components/ol/ol-col' import MaterialIcon from '@/shared/components/material-icon' -import OLRow from '@/features/ui/components/ol/ol-row' +import OLRow from '@/shared/components/ol/ol-row' import { isNonEmptyString, NonEmptyString } from '@ol-types/helpers/string' const USERS_DISPLAY_LIMIT = 50 diff --git a/services/web/frontend/js/features/group-management/components/members-table/offboard-managed-user-modal.tsx b/services/web/frontend/js/features/group-management/components/members-table/offboard-managed-user-modal.tsx index d4709bf6c3..dbe51dc9da 100644 --- a/services/web/frontend/js/features/group-management/components/members-table/offboard-managed-user-modal.tsx +++ b/services/web/frontend/js/features/group-management/components/members-table/offboard-managed-user-modal.tsx @@ -10,13 +10,13 @@ import OLModal, { OLModalFooter, OLModalHeader, OLModalTitle, -} from '@/features/ui/components/ol/ol-modal' -import OLFormGroup from '@/features/ui/components/ol/ol-form-group' -import OLButton from '@/features/ui/components/ol/ol-button' -import OLNotification from '@/features/ui/components/ol/ol-notification' -import OLFormControl from '@/features/ui/components/ol/ol-form-control' -import OLFormLabel from '@/features/ui/components/ol/ol-form-label' -import OLFormSelect from '@/features/ui/components/ol/ol-form-select' +} from '@/shared/components/ol/ol-modal' +import OLFormGroup from '@/shared/components/ol/ol-form-group' +import OLButton from '@/shared/components/ol/ol-button' +import OLNotification from '@/shared/components/ol/ol-notification' +import OLFormControl from '@/shared/components/ol/ol-form-control' +import OLFormLabel from '@/shared/components/ol/ol-form-label' +import OLFormSelect from '@/shared/components/ol/ol-form-select' import { sendMB } from '@/infrastructure/event-tracking' type OffboardManagedUserModalProps = { diff --git a/services/web/frontend/js/features/group-management/components/members-table/remove-managed-user-modal.tsx b/services/web/frontend/js/features/group-management/components/members-table/remove-managed-user-modal.tsx index c3c6f8caa4..4c6969bf92 100644 --- a/services/web/frontend/js/features/group-management/components/members-table/remove-managed-user-modal.tsx +++ b/services/web/frontend/js/features/group-management/components/members-table/remove-managed-user-modal.tsx @@ -10,12 +10,12 @@ import OLModal, { OLModalFooter, OLModalHeader, OLModalTitle, -} from '@/features/ui/components/ol/ol-modal' -import OLFormGroup from '@/features/ui/components/ol/ol-form-group' -import OLButton from '@/features/ui/components/ol/ol-button' -import OLNotification from '@/features/ui/components/ol/ol-notification' -import OLFormControl from '@/features/ui/components/ol/ol-form-control' -import OLFormLabel from '@/features/ui/components/ol/ol-form-label' +} from '@/shared/components/ol/ol-modal' +import OLFormGroup from '@/shared/components/ol/ol-form-group' +import OLButton from '@/shared/components/ol/ol-button' +import OLNotification from '@/shared/components/ol/ol-notification' +import OLFormControl from '@/shared/components/ol/ol-form-control' +import OLFormLabel from '@/shared/components/ol/ol-form-label' import { sendMB } from '@/infrastructure/event-tracking' type RemoveManagedUserModalProps = { diff --git a/services/web/frontend/js/features/group-management/components/members-table/select-all-checkbox.tsx b/services/web/frontend/js/features/group-management/components/members-table/select-all-checkbox.tsx index 17aaa2d983..0d56e8e1e4 100644 --- a/services/web/frontend/js/features/group-management/components/members-table/select-all-checkbox.tsx +++ b/services/web/frontend/js/features/group-management/components/members-table/select-all-checkbox.tsx @@ -1,7 +1,7 @@ import React, { useCallback } from 'react' import { useTranslation } from 'react-i18next' import { useGroupMembersContext } from '../../context/group-members-context' -import OLFormCheckbox from '@/features/ui/components/ol/ol-form-checkbox' +import OLFormCheckbox from '@/shared/components/ol/ol-form-checkbox' export default function SelectAllCheckbox() { const { t } = useTranslation() diff --git a/services/web/frontend/js/features/group-management/components/members-table/select-user-checkbox.tsx b/services/web/frontend/js/features/group-management/components/members-table/select-user-checkbox.tsx index 19aec5d6c7..d9a3b63f3e 100644 --- a/services/web/frontend/js/features/group-management/components/members-table/select-user-checkbox.tsx +++ b/services/web/frontend/js/features/group-management/components/members-table/select-user-checkbox.tsx @@ -2,7 +2,7 @@ import { useTranslation } from 'react-i18next' import type { User } from '../../../../../../types/group-management/user' import { useGroupMembersContext } from '../../context/group-members-context' import { useCallback } from 'react' -import OLFormCheckbox from '@/features/ui/components/ol/ol-form-checkbox' +import OLFormCheckbox from '@/shared/components/ol/ol-form-checkbox' type ManagedUsersSelectUserCheckboxProps = { user: User diff --git a/services/web/frontend/js/features/group-management/components/members-table/unlink-user-modal.tsx b/services/web/frontend/js/features/group-management/components/members-table/unlink-user-modal.tsx index ce583a09e3..9b5fcb0725 100644 --- a/services/web/frontend/js/features/group-management/components/members-table/unlink-user-modal.tsx +++ b/services/web/frontend/js/features/group-management/components/members-table/unlink-user-modal.tsx @@ -13,8 +13,8 @@ import OLModal, { OLModalFooter, OLModalHeader, OLModalTitle, -} from '@/features/ui/components/ol/ol-modal' -import OLButton from '@/features/ui/components/ol/ol-button' +} from '@/shared/components/ol/ol-modal' +import OLButton from '@/shared/components/ol/ol-button' export type UnlinkUserModalProps = { onClose: () => void diff --git a/services/web/frontend/js/features/group-management/components/missing-billing-information.tsx b/services/web/frontend/js/features/group-management/components/missing-billing-information.tsx index cd8e8ef743..2f20f6970d 100644 --- a/services/web/frontend/js/features/group-management/components/missing-billing-information.tsx +++ b/services/web/frontend/js/features/group-management/components/missing-billing-information.tsx @@ -1,5 +1,5 @@ import { Trans, useTranslation } from 'react-i18next' -import OLNotification from '@/features/ui/components/ol/ol-notification' +import OLNotification from '@/shared/components/ol/ol-notification' import Card from '@/features/group-management/components/card' function MissingBillingInformation() { diff --git a/services/web/frontend/js/features/group-management/components/request-status.tsx b/services/web/frontend/js/features/group-management/components/request-status.tsx index 637380ac13..f86c99cf2b 100644 --- a/services/web/frontend/js/features/group-management/components/request-status.tsx +++ b/services/web/frontend/js/features/group-management/components/request-status.tsx @@ -1,9 +1,9 @@ import { useTranslation } from 'react-i18next' import { Card, CardBody, Row, Col } from 'react-bootstrap' -import Button from '@/features/ui/components/bootstrap-5/button' +import Button from '@/shared/components/button/button' import MaterialIcon from '@/shared/components/material-icon' import getMeta from '@/utils/meta' -import IconButton from '@/features/ui/components/bootstrap-5/icon-button' +import IconButton from '@/shared/components/button/icon-button' import classnames from 'classnames' type RequestStatusProps = { diff --git a/services/web/frontend/js/features/group-management/components/subtotal-limit-exceeded.tsx b/services/web/frontend/js/features/group-management/components/subtotal-limit-exceeded.tsx index b194d7528f..b721869336 100644 --- a/services/web/frontend/js/features/group-management/components/subtotal-limit-exceeded.tsx +++ b/services/web/frontend/js/features/group-management/components/subtotal-limit-exceeded.tsx @@ -1,5 +1,5 @@ import { Trans } from 'react-i18next' -import OLNotification from '@/features/ui/components/ol/ol-notification' +import OLNotification from '@/shared/components/ol/ol-notification' import Card from '@/features/group-management/components/card' function SubtotalLimitExceeded() { diff --git a/services/web/frontend/js/features/group-management/components/upgrade-subscription/upgrade-subscription.tsx b/services/web/frontend/js/features/group-management/components/upgrade-subscription/upgrade-subscription.tsx index b4ce898ecb..9eb39ccfb8 100644 --- a/services/web/frontend/js/features/group-management/components/upgrade-subscription/upgrade-subscription.tsx +++ b/services/web/frontend/js/features/group-management/components/upgrade-subscription/upgrade-subscription.tsx @@ -2,8 +2,8 @@ import getMeta from '@/utils/meta' import { FetchError, postJSON } from '@/infrastructure/fetch-json' import { useTranslation, Trans } from 'react-i18next' import { Card, Row, Col } from 'react-bootstrap' -import IconButton from '@/features/ui/components/bootstrap-5/icon-button' -import Button from '@/features/ui/components/bootstrap-5/button' +import IconButton from '@/shared/components/button/icon-button' +import Button from '@/shared/components/button/button' import UpgradeSubscriptionPlanDetails from './upgrade-subscription-plan-details' import RequestStatus from '../request-status' import UpgradeSummary, { diff --git a/services/web/frontend/js/features/group-management/components/user-row.tsx b/services/web/frontend/js/features/group-management/components/user-row.tsx index 505dd83e76..85c018a2da 100644 --- a/services/web/frontend/js/features/group-management/components/user-row.tsx +++ b/services/web/frontend/js/features/group-management/components/user-row.tsx @@ -2,7 +2,7 @@ import moment from 'moment' import { useCallback } from 'react' import { useTranslation } from 'react-i18next' import { User } from '../../../../../types/group-management/user' -import OLFormCheckbox from '@/features/ui/components/ol/ol-form-checkbox' +import OLFormCheckbox from '@/shared/components/ol/ol-form-checkbox' import MaterialIcon from '@/shared/components/material-icon' type GroupMemberRowProps = { diff --git a/services/web/frontend/js/features/header-footer-react/index.tsx b/services/web/frontend/js/features/header-footer-react/index.tsx index 94a43b65fa..0b40d148ed 100644 --- a/services/web/frontend/js/features/header-footer-react/index.tsx +++ b/services/web/frontend/js/features/header-footer-react/index.tsx @@ -1,7 +1,7 @@ import { createRoot } from 'react-dom/client' import getMeta from '@/utils/meta' -import { DefaultNavbarRoot } from '@/features/ui/components/bootstrap-5/navbar/default-navbar' -import Footer from '@/features/ui/components/bootstrap-5/footer/footer' +import { DefaultNavbarRoot } from '@/shared/components/navbar/default-navbar' +import Footer from '@/shared/components/footer/footer' import { SplitTestProvider } from '@/shared/context/split-test-context' const navbarElement = document.getElementById('navbar-container') diff --git a/services/web/frontend/js/features/history/components/change-list/add-label-modal.tsx b/services/web/frontend/js/features/history/components/change-list/add-label-modal.tsx index 0bf6a71f2c..bfd588e288 100644 --- a/services/web/frontend/js/features/history/components/change-list/add-label-modal.tsx +++ b/services/web/frontend/js/features/history/components/change-list/add-label-modal.tsx @@ -1,15 +1,15 @@ import { useTranslation } from 'react-i18next' import { useEffect, useState } from 'react' -import OLForm from '@/features/ui/components/ol/ol-form' -import OLFormGroup from '@/features/ui/components/ol/ol-form-group' +import OLForm from '@/shared/components/ol/ol-form' +import OLFormGroup from '@/shared/components/ol/ol-form-group' import ModalError from './modal-error' import OLModal, { OLModalBody, OLModalFooter, OLModalHeader, OLModalTitle, -} from '@/features/ui/components/ol/ol-modal' -import OLButton from '@/features/ui/components/ol/ol-button' +} from '@/shared/components/ol/ol-modal' +import OLButton from '@/shared/components/ol/ol-button' import useAsync from '../../../../shared/hooks/use-async' import useAbortController from '../../../../shared/hooks/use-abort-controller' import useAddOrRemoveLabels from '../../hooks/use-add-or-remove-labels' @@ -18,7 +18,7 @@ import { addLabel } from '../../services/api' import { Label } from '../../services/types/label' import { useRefWithAutoFocus } from '../../../../shared/hooks/use-ref-with-auto-focus' import { debugConsole } from '@/utils/debugging' -import OLFormControl from '@/features/ui/components/ol/ol-form-control' +import OLFormControl from '@/shared/components/ol/ol-form-control' type AddLabelModalProps = { show: boolean 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 2997fa96ea..0e38f79537 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 @@ -8,8 +8,8 @@ import { useUserContext } from '../../../../shared/context/user-context' import useDropdownActiveItem from '../../hooks/use-dropdown-active-item' import { useHistoryContext } from '../../context/history-context' import { useEditorContext } from '../../../../shared/context/editor-context' -import OLPopover from '@/features/ui/components/ol/ol-popover' -import OLOverlay from '@/features/ui/components/ol/ol-overlay' +import OLPopover from '@/shared/components/ol/ol-popover' +import OLOverlay from '@/shared/components/ol/ol-overlay' import Close from '@/shared/components/close' import { Trans, useTranslation } from 'react-i18next' import MaterialIcon from '@/shared/components/material-icon' diff --git a/services/web/frontend/js/features/history/components/change-list/dropdown/actions-dropdown.tsx b/services/web/frontend/js/features/history/components/change-list/dropdown/actions-dropdown.tsx index df31a6c58f..750bae7fa0 100644 --- a/services/web/frontend/js/features/history/components/change-list/dropdown/actions-dropdown.tsx +++ b/services/web/frontend/js/features/history/components/change-list/dropdown/actions-dropdown.tsx @@ -3,8 +3,8 @@ import { Dropdown, DropdownMenu, DropdownToggle, -} from '@/features/ui/components/bootstrap-5/dropdown-menu' -import OLTooltip from '@/features/ui/components/ol/ol-tooltip' +} from '@/shared/components/dropdown/dropdown-menu' +import OLTooltip from '@/shared/components/ol/ol-tooltip' type ActionDropdownProps = { id: string diff --git a/services/web/frontend/js/features/history/components/change-list/dropdown/menu-item/add-label.tsx b/services/web/frontend/js/features/history/components/change-list/dropdown/menu-item/add-label.tsx index 1381b620d4..4b54e0d071 100644 --- a/services/web/frontend/js/features/history/components/change-list/dropdown/menu-item/add-label.tsx +++ b/services/web/frontend/js/features/history/components/change-list/dropdown/menu-item/add-label.tsx @@ -1,7 +1,7 @@ import { useState } from 'react' import { useTranslation } from 'react-i18next' -import OLDropdownMenuItem from '@/features/ui/components/ol/ol-dropdown-menu-item' -import OLTagIcon from '@/features/ui/components/ol/icons/ol-tag-icon' +import OLDropdownMenuItem from '@/shared/components/ol/ol-dropdown-menu-item' +import OLTagIcon from '@/shared/components/ol/ol-tag-icon' import AddLabelModal from '../../add-label-modal' type AddLabelProps = { diff --git a/services/web/frontend/js/features/history/components/change-list/dropdown/menu-item/compare-dropdown-item.tsx b/services/web/frontend/js/features/history/components/change-list/dropdown/menu-item/compare-dropdown-item.tsx index 5b8d490ff9..e3b776a0bb 100644 --- a/services/web/frontend/js/features/history/components/change-list/dropdown/menu-item/compare-dropdown-item.tsx +++ b/services/web/frontend/js/features/history/components/change-list/dropdown/menu-item/compare-dropdown-item.tsx @@ -1,7 +1,7 @@ import { useHistoryContext } from '../../../../context/history-context' import { UpdateRange } from '../../../../services/types/update' import { ReactNode } from 'react' -import OLDropdownMenuItem from '@/features/ui/components/ol/ol-dropdown-menu-item' +import OLDropdownMenuItem from '@/shared/components/ol/ol-dropdown-menu-item' type CompareProps = { comparisonRange: UpdateRange diff --git a/services/web/frontend/js/features/history/components/change-list/dropdown/menu-item/compare.tsx b/services/web/frontend/js/features/history/components/change-list/dropdown/menu-item/compare.tsx index 92745579c3..ed564add99 100644 --- a/services/web/frontend/js/features/history/components/change-list/dropdown/menu-item/compare.tsx +++ b/services/web/frontend/js/features/history/components/change-list/dropdown/menu-item/compare.tsx @@ -1,7 +1,7 @@ import { useHistoryContext } from '../../../../context/history-context' import { UpdateRange } from '../../../../services/types/update' import { ReactNode } from 'react' -import OLTooltip from '@/features/ui/components/ol/ol-tooltip' +import OLTooltip from '@/shared/components/ol/ol-tooltip' type CompareProps = { comparisonRange: UpdateRange diff --git a/services/web/frontend/js/features/history/components/change-list/dropdown/menu-item/download.tsx b/services/web/frontend/js/features/history/components/change-list/dropdown/menu-item/download.tsx index 305d77efda..4899ea50bf 100644 --- a/services/web/frontend/js/features/history/components/change-list/dropdown/menu-item/download.tsx +++ b/services/web/frontend/js/features/history/components/change-list/dropdown/menu-item/download.tsx @@ -1,5 +1,5 @@ import { useTranslation } from 'react-i18next' -import OLDropdownMenuItem from '@/features/ui/components/ol/ol-dropdown-menu-item' +import OLDropdownMenuItem from '@/shared/components/ol/ol-dropdown-menu-item' import MaterialIcon from '@/shared/components/material-icon' type DownloadProps = { diff --git a/services/web/frontend/js/features/history/components/change-list/dropdown/menu-item/restore-project.tsx b/services/web/frontend/js/features/history/components/change-list/dropdown/menu-item/restore-project.tsx index d6399ddf30..2d59c46a55 100644 --- a/services/web/frontend/js/features/history/components/change-list/dropdown/menu-item/restore-project.tsx +++ b/services/web/frontend/js/features/history/components/change-list/dropdown/menu-item/restore-project.tsx @@ -1,5 +1,5 @@ import { useCallback, useState } from 'react' -import OLDropdownMenuItem from '@/features/ui/components/ol/ol-dropdown-menu-item' +import OLDropdownMenuItem from '@/shared/components/ol/ol-dropdown-menu-item' import { useTranslation } from 'react-i18next' import { RestoreProjectModal } from '../../../diff-view/modals/restore-project-modal' import { useSplitTestContext } from '@/shared/context/split-test-context' diff --git a/services/web/frontend/js/features/history/components/change-list/modal-error.tsx b/services/web/frontend/js/features/history/components/change-list/modal-error.tsx index e16660ea61..1cf2cbf7b1 100644 --- a/services/web/frontend/js/features/history/components/change-list/modal-error.tsx +++ b/services/web/frontend/js/features/history/components/change-list/modal-error.tsx @@ -1,5 +1,5 @@ import { useTranslation } from 'react-i18next' -import OLNotification from '@/features/ui/components/ol/ol-notification' +import OLNotification from '@/shared/components/ol/ol-notification' // Using this workaround due to inconsistent and improper error responses from the server type ModalErrorProps = { diff --git a/services/web/frontend/js/features/history/components/change-list/tag-tooltip.tsx b/services/web/frontend/js/features/history/components/change-list/tag-tooltip.tsx index c766c4e25b..43e2a9b8ee 100644 --- a/services/web/frontend/js/features/history/components/change-list/tag-tooltip.tsx +++ b/services/web/frontend/js/features/history/components/change-list/tag-tooltip.tsx @@ -5,8 +5,8 @@ import OLModal, { OLModalFooter, OLModalHeader, OLModalTitle, -} from '@/features/ui/components/ol/ol-modal' -import OLTooltip from '@/features/ui/components/ol/ol-tooltip' +} from '@/shared/components/ol/ol-modal' +import OLTooltip from '@/shared/components/ol/ol-tooltip' import ModalError from './modal-error' import useAbortController from '../../../../shared/hooks/use-abort-controller' import useAsync from '../../../../shared/hooks/use-async' @@ -18,9 +18,9 @@ import { LoadedLabel } from '../../services/types/label' import { debugConsole } from '@/utils/debugging' import { FormatTimeBasedOnYear } from '@/shared/components/format-time-based-on-year' import { useEditorContext } from '@/shared/context/editor-context' -import OLTag from '@/features/ui/components/ol/ol-tag' -import OLButton from '@/features/ui/components/ol/ol-button' -import OLTagIcon from '@/features/ui/components/ol/icons/ol-tag-icon' +import OLTag from '@/shared/components/ol/ol-tag' +import OLButton from '@/shared/components/ol/ol-button' +import OLTagIcon from '@/shared/components/ol/ol-tag-icon' type TagProps = { label: LoadedLabel diff --git a/services/web/frontend/js/features/history/components/diff-view/document-diff-viewer.tsx b/services/web/frontend/js/features/history/components/diff-view/document-diff-viewer.tsx index 324ad38935..b96d590ac0 100644 --- a/services/web/frontend/js/features/history/components/diff-view/document-diff-viewer.tsx +++ b/services/web/frontend/js/features/history/components/diff-view/document-diff-viewer.tsx @@ -20,7 +20,7 @@ import { } from '../../extensions/highlight-locations' import { useTranslation } from 'react-i18next' import { inlineBackground } from '../../../source-editor/extensions/inline-background' -import OLButton from '@/features/ui/components/ol/ol-button' +import OLButton from '@/shared/components/ol/ol-button' function extensions(themeOptions: Options): Extension[] { return [ diff --git a/services/web/frontend/js/features/history/components/diff-view/main.tsx b/services/web/frontend/js/features/history/components/diff-view/main.tsx index 29a82bc678..eef0424a10 100644 --- a/services/web/frontend/js/features/history/components/diff-view/main.tsx +++ b/services/web/frontend/js/features/history/components/diff-view/main.tsx @@ -3,7 +3,7 @@ import { Diff } from '../../services/types/doc' import DocumentDiffViewer from './document-diff-viewer' import LoadingSpinner from '../../../../shared/components/loading-spinner' import { useTranslation } from 'react-i18next' -import OLNotification from '@/features/ui/components/ol/ol-notification' +import OLNotification from '@/shared/components/ol/ol-notification' type MainProps = { diff: Nullable diff --git a/services/web/frontend/js/features/history/components/diff-view/modals/restore-file-confirm-modal.tsx b/services/web/frontend/js/features/history/components/diff-view/modals/restore-file-confirm-modal.tsx index 33d0ccd09b..45ffee3e11 100644 --- a/services/web/frontend/js/features/history/components/diff-view/modals/restore-file-confirm-modal.tsx +++ b/services/web/frontend/js/features/history/components/diff-view/modals/restore-file-confirm-modal.tsx @@ -5,8 +5,8 @@ import OLModal, { OLModalFooter, OLModalHeader, OLModalTitle, -} from '@/features/ui/components/ol/ol-modal' -import OLButton from '@/features/ui/components/ol/ol-button' +} from '@/shared/components/ol/ol-modal' +import OLButton from '@/shared/components/ol/ol-button' import { useTranslation } from 'react-i18next' type RestoreFileConfirmModalProps = { diff --git a/services/web/frontend/js/features/history/components/diff-view/modals/restore-file-error-modal.tsx b/services/web/frontend/js/features/history/components/diff-view/modals/restore-file-error-modal.tsx index c25c0ce14b..48c758e378 100644 --- a/services/web/frontend/js/features/history/components/diff-view/modals/restore-file-error-modal.tsx +++ b/services/web/frontend/js/features/history/components/diff-view/modals/restore-file-error-modal.tsx @@ -3,8 +3,8 @@ import OLModal, { OLModalFooter, OLModalHeader, OLModalTitle, -} from '@/features/ui/components/ol/ol-modal' -import OLButton from '@/features/ui/components/ol/ol-button' +} from '@/shared/components/ol/ol-modal' +import OLButton from '@/shared/components/ol/ol-button' import { useTranslation } from 'react-i18next' export function RestoreFileErrorModal({ diff --git a/services/web/frontend/js/features/history/components/diff-view/modals/restore-project-error-modal.tsx b/services/web/frontend/js/features/history/components/diff-view/modals/restore-project-error-modal.tsx index d03124a7b6..28044fabe6 100644 --- a/services/web/frontend/js/features/history/components/diff-view/modals/restore-project-error-modal.tsx +++ b/services/web/frontend/js/features/history/components/diff-view/modals/restore-project-error-modal.tsx @@ -3,8 +3,8 @@ import OLModal, { OLModalFooter, OLModalHeader, OLModalTitle, -} from '@/features/ui/components/ol/ol-modal' -import OLButton from '@/features/ui/components/ol/ol-button' +} from '@/shared/components/ol/ol-modal' +import OLButton from '@/shared/components/ol/ol-button' import { useTranslation } from 'react-i18next' export function RestoreProjectErrorModal({ diff --git a/services/web/frontend/js/features/history/components/diff-view/modals/restore-project-modal.tsx b/services/web/frontend/js/features/history/components/diff-view/modals/restore-project-modal.tsx index b6012cc174..8eaf722e0a 100644 --- a/services/web/frontend/js/features/history/components/diff-view/modals/restore-project-modal.tsx +++ b/services/web/frontend/js/features/history/components/diff-view/modals/restore-project-modal.tsx @@ -3,10 +3,10 @@ import OLModal, { OLModalFooter, OLModalHeader, OLModalTitle, -} from '@/features/ui/components/ol/ol-modal' +} from '@/shared/components/ol/ol-modal' import { formatDate } from '@/utils/dates' import { useCallback } from 'react' -import OLButton from '@/features/ui/components/ol/ol-button' +import OLButton from '@/shared/components/ol/ol-button' import { useTranslation } from 'react-i18next' type RestoreProjectModalProps = { diff --git a/services/web/frontend/js/features/history/components/diff-view/toolbar/toolbar-restore-file-button.tsx b/services/web/frontend/js/features/history/components/diff-view/toolbar/toolbar-restore-file-button.tsx index 559b09a3d0..1f85436094 100644 --- a/services/web/frontend/js/features/history/components/diff-view/toolbar/toolbar-restore-file-button.tsx +++ b/services/web/frontend/js/features/history/components/diff-view/toolbar/toolbar-restore-file-button.tsx @@ -1,4 +1,4 @@ -import OLButton from '@/features/ui/components/ol/ol-button' +import OLButton from '@/shared/components/ol/ol-button' import { useTranslation } from 'react-i18next' import { useRestoreDeletedFile } from '../../../context/hooks/use-restore-deleted-file' import type { HistoryContextValue } from '../../../context/types/history-context-value' diff --git a/services/web/frontend/js/features/history/components/diff-view/toolbar/toolbar-restore-file-to-version-button.tsx b/services/web/frontend/js/features/history/components/diff-view/toolbar/toolbar-restore-file-to-version-button.tsx index 7f8ad694ce..e1a31c97e2 100644 --- a/services/web/frontend/js/features/history/components/diff-view/toolbar/toolbar-restore-file-to-version-button.tsx +++ b/services/web/frontend/js/features/history/components/diff-view/toolbar/toolbar-restore-file-to-version-button.tsx @@ -1,4 +1,4 @@ -import OLButton from '@/features/ui/components/ol/ol-button' +import OLButton from '@/shared/components/ol/ol-button' import { useTranslation } from 'react-i18next' import type { HistoryContextValue } from '../../../context/types/history-context-value' import withErrorBoundary from '@/infrastructure/error-boundary' diff --git a/services/web/frontend/js/features/history/components/file-tree/history-file-tree-item.tsx b/services/web/frontend/js/features/history/components/file-tree/history-file-tree-item.tsx index 6f590c6b28..260fd87b3b 100644 --- a/services/web/frontend/js/features/history/components/file-tree/history-file-tree-item.tsx +++ b/services/web/frontend/js/features/history/components/file-tree/history-file-tree-item.tsx @@ -1,7 +1,7 @@ import classNames from 'classnames' import type { ReactNode } from 'react' import type { FileOperation } from '../../services/types/file-operation' -import OLTag from '@/features/ui/components/ol/ol-tag' +import OLTag from '@/shared/components/ol/ol-tag' type FileTreeItemProps = { name: string diff --git a/services/web/frontend/js/features/hotkeys-modal/components/hotkeys-modal.jsx b/services/web/frontend/js/features/hotkeys-modal/components/hotkeys-modal.jsx index e19aba8208..269b528397 100644 --- a/services/web/frontend/js/features/hotkeys-modal/components/hotkeys-modal.jsx +++ b/services/web/frontend/js/features/hotkeys-modal/components/hotkeys-modal.jsx @@ -6,10 +6,10 @@ import OLModal, { OLModalFooter, OLModalHeader, OLModalTitle, -} from '@/features/ui/components/ol/ol-modal' -import OLButton from '@/features/ui/components/ol/ol-button' -import OLRow from '@/features/ui/components/ol/ol-row' -import OLCol from '@/features/ui/components/ol/ol-col' +} from '@/shared/components/ol/ol-modal' +import OLButton from '@/shared/components/ol/ol-button' +import OLRow from '@/shared/components/ol/ol-row' +import OLCol from '@/shared/components/ol/ol-col' export default function HotkeysModal({ animation = true, diff --git a/services/web/frontend/js/features/ide-react/components/alerts/alerts.tsx b/services/web/frontend/js/features/ide-react/components/alerts/alerts.tsx index 4829913ade..13db236193 100644 --- a/services/web/frontend/js/features/ide-react/components/alerts/alerts.tsx +++ b/services/web/frontend/js/features/ide-react/components/alerts/alerts.tsx @@ -4,7 +4,7 @@ import { useConnectionContext } from '@/features/ide-react/context/connection-co import { debugging } from '@/utils/debugging' import { createPortal } from 'react-dom' import { useGlobalAlertsContainer } from '@/features/ide-react/context/global-alerts-context' -import OLNotification from '@/features/ui/components/ol/ol-notification' +import OLNotification from '@/shared/components/ol/ol-notification' export function Alerts() { const { t } = useTranslation() diff --git a/services/web/frontend/js/features/ide-react/components/alerts/lost-connection-alert.tsx b/services/web/frontend/js/features/ide-react/components/alerts/lost-connection-alert.tsx index a4780f8021..36271d9c3e 100644 --- a/services/web/frontend/js/features/ide-react/components/alerts/lost-connection-alert.tsx +++ b/services/web/frontend/js/features/ide-react/components/alerts/lost-connection-alert.tsx @@ -1,8 +1,8 @@ import { useTranslation } from 'react-i18next' import { useEffect, useState } from 'react' import { secondsUntil } from '@/features/ide-react/connection/utils' -import OLNotification from '@/features/ui/components/ol/ol-notification' -import OLButton from '@/features/ui/components/ol/ol-button' +import OLNotification from '@/shared/components/ol/ol-notification' +import OLButton from '@/shared/components/ol/ol-button' type LostConnectionAlertProps = { reconnectAt: number diff --git a/services/web/frontend/js/features/ide-react/components/editor-survey.tsx b/services/web/frontend/js/features/ide-react/components/editor-survey.tsx index e28aa7698d..edde0dd8da 100644 --- a/services/web/frontend/js/features/ide-react/components/editor-survey.tsx +++ b/services/web/frontend/js/features/ide-react/components/editor-survey.tsx @@ -1,10 +1,10 @@ -import OLButton from '@/features/ui/components/ol/ol-button' -import OLForm from '@/features/ui/components/ol/ol-form' -import OLFormCheckbox from '@/features/ui/components/ol/ol-form-checkbox' -import OLFormGroup from '@/features/ui/components/ol/ol-form-group' -import OLIconButton from '@/features/ui/components/ol/ol-icon-button' -import { OLToast } from '@/features/ui/components/ol/ol-toast' -import { OLToastContainer } from '@/features/ui/components/ol/ol-toast-container' +import OLButton from '@/shared/components/ol/ol-button' +import OLForm from '@/shared/components/ol/ol-form' +import OLFormCheckbox from '@/shared/components/ol/ol-form-checkbox' +import OLFormGroup from '@/shared/components/ol/ol-form-group' +import OLIconButton from '@/shared/components/ol/ol-icon-button' +import { OLToast } from '@/shared/components/ol/ol-toast' +import { OLToastContainer } from '@/shared/components/ol/ol-toast-container' import { useEditorContext } from '@/shared/context/editor-context' import useTutorial from '@/shared/hooks/promotions/use-tutorial' import { useCallback, useEffect, useMemo, useState } from 'react' diff --git a/services/web/frontend/js/features/ide-react/components/global-toasts.tsx b/services/web/frontend/js/features/ide-react/components/global-toasts.tsx index 021f5c5d90..8b2262aeaa 100644 --- a/services/web/frontend/js/features/ide-react/components/global-toasts.tsx +++ b/services/web/frontend/js/features/ide-react/components/global-toasts.tsx @@ -1,10 +1,10 @@ -import { OLToast, OLToastProps } from '@/features/ui/components/ol/ol-toast' +import { OLToast, OLToastProps } from '@/shared/components/ol/ol-toast' import useEventListener from '@/shared/hooks/use-event-listener' import { Fragment, ReactElement, useCallback, useState } from 'react' import { debugConsole } from '@/utils/debugging' import importOverleafModules from '../../../../macros/import-overleaf-module.macro' -import { OLToastContainer } from '@/features/ui/components/ol/ol-toast-container' +import { OLToastContainer } from '@/shared/components/ol/ol-toast-container' const moduleGeneratorsImport = importOverleafModules('toastGenerators') as { import: { default: GlobalToastGeneratorEntry[] } diff --git a/services/web/frontend/js/features/ide-react/components/modals/force-disconnected.tsx b/services/web/frontend/js/features/ide-react/components/modals/force-disconnected.tsx index 5b34675352..15e9de3abf 100644 --- a/services/web/frontend/js/features/ide-react/components/modals/force-disconnected.tsx +++ b/services/web/frontend/js/features/ide-react/components/modals/force-disconnected.tsx @@ -5,7 +5,7 @@ import OLModal, { OLModalBody, OLModalHeader, OLModalTitle, -} from '@/features/ui/components/ol/ol-modal' +} from '@/shared/components/ol/ol-modal' // show modal when editor is forcefully disconnected function ForceDisconnected() { diff --git a/services/web/frontend/js/features/ide-react/components/modals/generic-confirm-modal.tsx b/services/web/frontend/js/features/ide-react/components/modals/generic-confirm-modal.tsx index fd27985ba6..4bdf94d608 100644 --- a/services/web/frontend/js/features/ide-react/components/modals/generic-confirm-modal.tsx +++ b/services/web/frontend/js/features/ide-react/components/modals/generic-confirm-modal.tsx @@ -5,9 +5,9 @@ import OLModal, { OLModalFooter, OLModalHeader, OLModalTitle, -} from '@/features/ui/components/ol/ol-modal' -import OLButton from '@/features/ui/components/ol/ol-button' -import { ButtonProps } from '@/features/ui/components/types/button-props' +} from '@/shared/components/ol/ol-modal' +import OLButton from '@/shared/components/ol/ol-button' +import { ButtonProps } from '@/shared/components/types/button-props' export type GenericConfirmModalOwnProps = { title: string diff --git a/services/web/frontend/js/features/ide-react/components/modals/generic-message-modal.tsx b/services/web/frontend/js/features/ide-react/components/modals/generic-message-modal.tsx index 37bd91753a..2e5ec98f4a 100644 --- a/services/web/frontend/js/features/ide-react/components/modals/generic-message-modal.tsx +++ b/services/web/frontend/js/features/ide-react/components/modals/generic-message-modal.tsx @@ -5,8 +5,8 @@ import OLModal, { OLModalFooter, OLModalHeader, OLModalTitle, -} from '@/features/ui/components/ol/ol-modal' -import OLButton from '@/features/ui/components/ol/ol-button' +} from '@/shared/components/ol/ol-modal' +import OLButton from '@/shared/components/ol/ol-button' export type GenericMessageModalOwnProps = { title: string diff --git a/services/web/frontend/js/features/ide-react/components/modals/out-of-sync-modal.tsx b/services/web/frontend/js/features/ide-react/components/modals/out-of-sync-modal.tsx index 53aa73f6c3..afcf8ff346 100644 --- a/services/web/frontend/js/features/ide-react/components/modals/out-of-sync-modal.tsx +++ b/services/web/frontend/js/features/ide-react/components/modals/out-of-sync-modal.tsx @@ -1,13 +1,13 @@ import { Trans, useTranslation } from 'react-i18next' import { memo, useState } from 'react' import { useLocation } from '@/shared/hooks/use-location' -import OLButton from '@/features/ui/components/ol/ol-button' +import OLButton from '@/shared/components/ol/ol-button' import OLModal, { OLModalBody, OLModalFooter, OLModalHeader, OLModalTitle, -} from '@/features/ui/components/ol/ol-modal' +} from '@/shared/components/ol/ol-modal' export type OutOfSyncModalProps = { editorContent: string diff --git a/services/web/frontend/js/features/ide-react/components/resize/horizontal-toggler.tsx b/services/web/frontend/js/features/ide-react/components/resize/horizontal-toggler.tsx index a5079d397a..2eceb6fa3f 100644 --- a/services/web/frontend/js/features/ide-react/components/resize/horizontal-toggler.tsx +++ b/services/web/frontend/js/features/ide-react/components/resize/horizontal-toggler.tsx @@ -1,5 +1,5 @@ import classNames from 'classnames' -import OLTooltip from '@/features/ui/components/ol/ol-tooltip' +import OLTooltip from '@/shared/components/ol/ol-tooltip' import MaterialIcon from '@/shared/components/material-icon' type HorizontalTogglerType = 'west' | 'east' diff --git a/services/web/frontend/js/features/ide-react/components/unsaved-docs/unsaved-docs-alert.tsx b/services/web/frontend/js/features/ide-react/components/unsaved-docs/unsaved-docs-alert.tsx index 70d0d69885..8c08618bd7 100644 --- a/services/web/frontend/js/features/ide-react/components/unsaved-docs/unsaved-docs-alert.tsx +++ b/services/web/frontend/js/features/ide-react/components/unsaved-docs/unsaved-docs-alert.tsx @@ -1,7 +1,7 @@ import { FC, useEffect, useMemo, useRef } from 'react' import { useFileTreePathContext } from '@/features/file-tree/contexts/file-tree-path' import { useTranslation } from 'react-i18next' -import OLNotification from '@/features/ui/components/ol/ol-notification' +import OLNotification from '@/shared/components/ol/ol-notification' import { sendMB } from '@/infrastructure/event-tracking' import { useConnectionContext } from '@/features/ide-react/context/connection-context' diff --git a/services/web/frontend/js/features/ide-react/components/unsaved-docs/unsaved-docs-locked-alert.tsx b/services/web/frontend/js/features/ide-react/components/unsaved-docs/unsaved-docs-locked-alert.tsx index 18d5952435..ad67444cb1 100644 --- a/services/web/frontend/js/features/ide-react/components/unsaved-docs/unsaved-docs-locked-alert.tsx +++ b/services/web/frontend/js/features/ide-react/components/unsaved-docs/unsaved-docs-locked-alert.tsx @@ -1,6 +1,6 @@ import { FC, useEffect } from 'react' import { useTranslation } from 'react-i18next' -import OLNotification from '@/features/ui/components/ol/ol-notification' +import OLNotification from '@/shared/components/ol/ol-notification' import { useEditorManagerContext } from '@/features/ide-react/context/editor-manager-context' import { useIdeReactContext } from '@/features/ide-react/context/ide-react-context' diff --git a/services/web/frontend/js/features/ide-redesign/components/error-logs/error-logs-header.tsx b/services/web/frontend/js/features/ide-redesign/components/error-logs/error-logs-header.tsx index b2038ff58d..0a5136178f 100644 --- a/services/web/frontend/js/features/ide-redesign/components/error-logs/error-logs-header.tsx +++ b/services/web/frontend/js/features/ide-redesign/components/error-logs/error-logs-header.tsx @@ -1,15 +1,15 @@ import { useTranslation } from 'react-i18next' import RailPanelHeader from '../rail/rail-panel-header' -import OLIconButton from '@/features/ui/components/ol/ol-icon-button' +import OLIconButton from '@/shared/components/ol/ol-icon-button' import { useDetachCompileContext as useCompileContext } from '@/shared/context/detach-compile-context' import { Dropdown, DropdownMenu, DropdownToggle, -} from '@/features/ui/components/bootstrap-5/dropdown-menu' +} from '@/shared/components/dropdown/dropdown-menu' import PdfFileList from '@/features/pdf-preview/components/pdf-file-list' import { forwardRef } from 'react' -import OLTooltip from '@/features/ui/components/ol/ol-tooltip' +import OLTooltip from '@/shared/components/ol/ol-tooltip' export default function ErrorLogsHeader() { const { t } = useTranslation() diff --git a/services/web/frontend/js/features/ide-redesign/components/error-logs/log-entry-header.tsx b/services/web/frontend/js/features/ide-redesign/components/error-logs/log-entry-header.tsx index bb99fc90bd..323a34a52e 100644 --- a/services/web/frontend/js/features/ide-redesign/components/error-logs/log-entry-header.tsx +++ b/services/web/frontend/js/features/ide-redesign/components/error-logs/log-entry-header.tsx @@ -1,14 +1,14 @@ import classNames from 'classnames' import { useState, useRef, MouseEventHandler, ElementType } from 'react' import { useTranslation } from 'react-i18next' -import OLTooltip from '@/features/ui/components/ol/ol-tooltip' +import OLTooltip from '@/shared/components/ol/ol-tooltip' import { ErrorLevel, SourceLocation, LogEntry as LogEntryData, } from '@/features/pdf-preview/util/types' import useResizeObserver from '@/features/preview/hooks/use-resize-observer' -import OLIconButton from '@/features/ui/components/ol/ol-icon-button' +import OLIconButton from '@/shared/components/ol/ol-icon-button' import importOverleafModules from '../../../../../macros/import-overleaf-module.macro' import MaterialIcon from '@/shared/components/material-icon' import { useFileTreePathContext } from '@/features/file-tree/contexts/file-tree-path' diff --git a/services/web/frontend/js/features/ide-redesign/components/file-tree/file-tree-action-button.tsx b/services/web/frontend/js/features/ide-redesign/components/file-tree/file-tree-action-button.tsx index 5678db58c8..76a5bdce69 100644 --- a/services/web/frontend/js/features/ide-redesign/components/file-tree/file-tree-action-button.tsx +++ b/services/web/frontend/js/features/ide-redesign/components/file-tree/file-tree-action-button.tsx @@ -1,4 +1,4 @@ -import OLTooltip from '@/features/ui/components/ol/ol-tooltip' +import OLTooltip from '@/shared/components/ol/ol-tooltip' import MaterialIcon, { AvailableUnfilledIcon, } from '@/shared/components/material-icon' diff --git a/services/web/frontend/js/features/ide-redesign/components/integrations-panel/integration-card.tsx b/services/web/frontend/js/features/ide-redesign/components/integrations-panel/integration-card.tsx index 9067034ebb..81490781a2 100644 --- a/services/web/frontend/js/features/ide-redesign/components/integrations-panel/integration-card.tsx +++ b/services/web/frontend/js/features/ide-redesign/components/integrations-panel/integration-card.tsx @@ -1,4 +1,4 @@ -import OLBadge from '@/features/ui/components/ol/ol-badge' +import OLBadge from '@/shared/components/ol/ol-badge' import MaterialIcon from '@/shared/components/material-icon' import { useTranslation } from 'react-i18next' diff --git a/services/web/frontend/js/features/ide-redesign/components/labs-user-beta-promo.tsx b/services/web/frontend/js/features/ide-redesign/components/labs-user-beta-promo.tsx index 5d52ea5783..0e1de3c81c 100644 --- a/services/web/frontend/js/features/ide-redesign/components/labs-user-beta-promo.tsx +++ b/services/web/frontend/js/features/ide-redesign/components/labs-user-beta-promo.tsx @@ -1,4 +1,4 @@ -import OLButton from '@/features/ui/components/ol/ol-button' +import OLButton from '@/shared/components/ol/ol-button' import MaterialIcon from '@/shared/components/material-icon' import Notification from '@/shared/components/notification' import { useEditorContext } from '@/shared/context/editor-context' diff --git a/services/web/frontend/js/features/ide-redesign/components/online-users/online-users-widget.tsx b/services/web/frontend/js/features/ide-redesign/components/online-users/online-users-widget.tsx index 2d30297e51..f582885949 100644 --- a/services/web/frontend/js/features/ide-redesign/components/online-users/online-users-widget.tsx +++ b/services/web/frontend/js/features/ide-redesign/components/online-users/online-users-widget.tsx @@ -5,8 +5,8 @@ import { DropdownItem, DropdownMenu, DropdownToggle, -} from '@/features/ui/components/bootstrap-5/dropdown-menu' -import OLTooltip from '@/features/ui/components/ol/ol-tooltip' +} from '@/shared/components/dropdown/dropdown-menu' +import OLTooltip from '@/shared/components/ol/ol-tooltip' import { getBackgroundColorForUserId, hslStringToLuminance, diff --git a/services/web/frontend/js/features/ide-redesign/components/pdf-preview/pdf-error-state.tsx b/services/web/frontend/js/features/ide-redesign/components/pdf-preview/pdf-error-state.tsx index 4f2651e2df..444e778442 100644 --- a/services/web/frontend/js/features/ide-redesign/components/pdf-preview/pdf-error-state.tsx +++ b/services/web/frontend/js/features/ide-redesign/components/pdf-preview/pdf-error-state.tsx @@ -1,4 +1,4 @@ -import OLButton from '@/features/ui/components/ol/ol-button' +import OLButton from '@/shared/components/ol/ol-button' import MaterialIcon from '@/shared/components/material-icon' import { Trans, useTranslation } from 'react-i18next' import { useRailContext } from '../../contexts/rail-context' diff --git a/services/web/frontend/js/features/ide-redesign/components/pdf-preview/pdf-preview-hybrid-toolbar.tsx b/services/web/frontend/js/features/ide-redesign/components/pdf-preview/pdf-preview-hybrid-toolbar.tsx index b99547daf6..79d1042506 100644 --- a/services/web/frontend/js/features/ide-redesign/components/pdf-preview/pdf-preview-hybrid-toolbar.tsx +++ b/services/web/frontend/js/features/ide-redesign/components/pdf-preview/pdf-preview-hybrid-toolbar.tsx @@ -1,6 +1,6 @@ import { memo } from 'react' import { useTranslation } from 'react-i18next' -import OLButtonToolbar from '@/features/ui/components/ol/ol-button-toolbar' +import OLButtonToolbar from '@/shared/components/ol/ol-button-toolbar' import PdfCompileButton from '@/features/pdf-preview/components/pdf-compile-button' import PdfHybridDownloadButton from '@/features/pdf-preview/components/pdf-hybrid-download-button' import { DetachedSynctexControl } from '@/features/pdf-preview/components/detach-synctex-control' diff --git a/services/web/frontend/js/features/ide-redesign/components/rail.tsx b/services/web/frontend/js/features/ide-redesign/components/rail.tsx new file mode 100644 index 0000000000..b80cca35b9 --- /dev/null +++ b/services/web/frontend/js/features/ide-redesign/components/rail.tsx @@ -0,0 +1,494 @@ +import { FC, forwardRef, ReactElement, useCallback, useMemo } from 'react' +import { useTranslation } from 'react-i18next' +import { Nav, NavLink, Tab, TabContainer } from 'react-bootstrap' +import MaterialIcon, { + AvailableUnfilledIcon, +} from '@/shared/components/material-icon' +import { Panel } from 'react-resizable-panels' +import { useLayoutContext } from '@/shared/context/layout-context' +import ErrorIndicator from './error-logs/error-indicator' +import { + RailModalKey, + RailTabKey, + useRailContext, +} from '../contexts/rail-context' +import FileTreeOutlinePanel from './file-tree/file-tree-outline-panel' +import { ChatIndicator, ChatPane } from './chat/chat' +import getMeta from '@/utils/meta' +import { HorizontalResizeHandle } from '@/features/ide-react/components/resize/horizontal-resize-handle' +import { HorizontalToggler } from '@/features/ide-react/components/resize/horizontal-toggler' +import classNames from 'classnames' +import IntegrationsPanel from './integrations-panel/integrations-panel' +import { + Dropdown, + DropdownDivider, + DropdownItem, + DropdownMenu, + DropdownToggle, +} from '@/shared/components/dropdown/dropdown-menu' +import { RailHelpShowHotkeysModal } from './help/keyboard-shortcuts' +import { RailHelpContactUsModal } from './help/contact-us' +import { HistorySidebar } from '@/features/ide-react/components/history-sidebar' +import DictionarySettingsModal from './settings/editor-settings/dictionary-settings-modal' +import OLTooltip from '@/shared/components/ol/ol-tooltip' +import { useChatContext } from '@/features/chat/context/chat-context' +import { useEditorAnalytics } from '@/shared/hooks/use-editor-analytics' +import { + FullProjectSearchPanel, + hasFullProjectSearch, +} from './full-project-search-panel' +import { sendSearchEvent } from '@/features/event-tracking/search-events' +import ErrorLogsPanel from './error-logs/error-logs-panel' +import { useDetachCompileContext as useCompileContext } from '@/shared/context/detach-compile-context' +import OldErrorPane from './error-logs/old-error-pane' +import { useFeatureFlag } from '@/shared/context/split-test-context' +import { useSurveyUrl } from '../hooks/use-survey-url' +import { useProjectContext } from '@/shared/context/project-context' +import usePreviousValue from '@/shared/hooks/use-previous-value' +import { useCommandProvider } from '@/features/ide-react/hooks/use-command-provider' + +type RailElement = { + icon: AvailableUnfilledIcon + key: RailTabKey + component: ReactElement | null + indicator?: ReactElement + title: string + hide?: boolean + disabled?: boolean + mountOnFirstLoad?: boolean +} + +type RailActionButton = { + key: string + icon: AvailableUnfilledIcon + title: string + action: () => void +} +type RailDropdown = { + key: string + icon: AvailableUnfilledIcon + title: string + dropdown: ReactElement +} +type RailAction = RailDropdown | RailActionButton + +const RAIL_MODALS: { + key: RailModalKey + modalComponentFunction: FC<{ show: boolean }> +}[] = [ + { + key: 'keyboard-shortcuts', + modalComponentFunction: RailHelpShowHotkeysModal, + }, + { + key: 'contact-us', + modalComponentFunction: RailHelpContactUsModal, + }, + { + key: 'dictionary', + modalComponentFunction: DictionarySettingsModal, + }, +] + +export const RailLayout = () => { + const { sendEvent } = useEditorAnalytics() + const { t } = useTranslation() + const { + activeModal, + selectedTab, + openTab, + isOpen, + setIsOpen, + panelRef, + handlePaneCollapse, + handlePaneExpand, + togglePane, + setResizing, + } = useRailContext() + const { logEntries } = useCompileContext() + const { features } = useProjectContext() + const errorLogsDisabled = !logEntries + + const { view, setLeftMenuShown } = useLayoutContext() + + const { markMessagesAsRead } = useChatContext() + + const isHistoryView = view === 'history' + + const newErrorlogs = useFeatureFlag('new-editor-error-logs-redesign') + + const railTabs: RailElement[] = useMemo( + () => [ + { + key: 'file-tree', + icon: 'description', + title: t('file_tree'), + component: , + // NOTE: We always need to mount the file tree on first load + // since it is responsible for opening the initial document. + mountOnFirstLoad: true, + }, + { + key: 'full-project-search', + icon: 'search', + title: t('project_search'), + component: , + hide: !hasFullProjectSearch, + }, + { + key: 'integrations', + icon: 'integration_instructions', + title: t('integrations'), + component: , + }, + { + key: 'review-panel', + icon: 'rate_review', + title: t('review_panel'), + component: null, + hide: !features.trackChangesVisible, + disabled: view !== 'editor', + }, + { + key: 'chat', + icon: 'forum', + component: , + indicator: , + title: t('chat'), + hide: !getMeta('ol-capabilities')?.includes('chat'), + }, + { + key: 'errors', + icon: 'report', + title: t('error_log'), + component: newErrorlogs ? : , + indicator: , + disabled: errorLogsDisabled, + }, + ], + [t, features.trackChangesVisible, newErrorlogs, errorLogsDisabled, view] + ) + + const railActions: RailAction[] = useMemo( + () => [ + { + key: 'support', + icon: 'help', + title: t('help'), + dropdown: , + }, + { + key: 'settings', + icon: 'settings', + title: t('settings'), + action: () => { + sendEvent('rail-click', { tab: 'settings' }) + setLeftMenuShown(true) + }, + }, + ], + [setLeftMenuShown, t, sendEvent] + ) + + useCommandProvider( + () => [ + { + id: 'open-settings', + handler: () => { + setLeftMenuShown(true) + }, + label: t('settings'), + }, + ], + [t, setLeftMenuShown] + ) + + const onTabSelect = useCallback( + (key: string | null) => { + if (key === selectedTab) { + togglePane() + sendEvent('rail-click', { tab: key, type: 'toggle' }) + } else { + // HACK: Apparently the onSelect event is triggered with href attributes + // from DropdownItems + if (!railTabs.some(tab => !tab.hide && tab.key === key)) { + // Attempting to open a non-existent tab + return + } + const keyOrDefault = (key ?? 'file-tree') as RailTabKey + // Change the selected tab and make sure it's open + openTab(keyOrDefault) + sendEvent('rail-click', { tab: keyOrDefault }) + if (keyOrDefault === 'full-project-search') { + sendSearchEvent('search-open', { + searchType: 'full-project', + method: 'button', + location: 'rail', + }) + } + + if (key === 'chat') { + markMessagesAsRead() + } + } + }, + [openTab, togglePane, selectedTab, railTabs, sendEvent, markMessagesAsRead] + ) + + const isReviewPanelOpen = selectedTab === 'review-panel' + + const prevTab = usePreviousValue(selectedTab) + + const tabHasChanged = useMemo(() => { + return prevTab !== selectedTab + }, [prevTab, selectedTab]) + + const onCollapse = useCallback(() => { + if (!tabHasChanged) { + handlePaneCollapse() + } + }, [tabHasChanged, handlePaneCollapse]) + + return ( + + {/* The