diff --git a/services/web/.storybook/preview.tsx b/services/web/.storybook/preview.tsx index bc86ff301b..8707cde5f3 100644 --- a/services/web/.storybook/preview.tsx +++ b/services/web/.storybook/preview.tsx @@ -177,7 +177,11 @@ const preview: Preview = { return ( <> {activeStyle && } - + ) }, diff --git a/services/web/.storybook/utils/with-bootstrap-switcher.tsx b/services/web/.storybook/utils/with-bootstrap-switcher.tsx index ce7c512ea3..2d6b6a5609 100644 --- a/services/web/.storybook/utils/with-bootstrap-switcher.tsx +++ b/services/web/.storybook/utils/with-bootstrap-switcher.tsx @@ -9,6 +9,9 @@ export const bsVersionDecorator: Meta = { description: 'Bootstrap version for components', control: { type: 'inline-radio' }, options: ['3', '5'], + table: { + defaultValue: { summary: '3' }, + }, }, }, args: { diff --git a/services/web/frontend/js/features/pdf-preview/components/pdf-clear-cache-button.jsx b/services/web/frontend/js/features/pdf-preview/components/pdf-clear-cache-button.jsx index 368ff74416..dfaef0548e 100644 --- a/services/web/frontend/js/features/pdf-preview/components/pdf-clear-cache-button.jsx +++ b/services/web/frontend/js/features/pdf-preview/components/pdf-clear-cache-button.jsx @@ -1,8 +1,9 @@ import Icon from '../../../shared/components/icon' -import { Button } from 'react-bootstrap' +import OLButton from '@/features/ui/components/ol/ol-button' import { useTranslation } from 'react-i18next' import { memo } from 'react' import { useDetachCompileContext as useCompileContext } from '../../../shared/context/detach-compile-context' +import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher' function PdfClearCacheButton() { const { compiling, clearCache, clearingCache } = useCompileContext() @@ -10,17 +11,29 @@ function PdfClearCacheButton() { const { t } = useTranslation() return ( - + ) } diff --git a/services/web/frontend/js/features/pdf-preview/components/pdf-code-check-failed-notice.jsx b/services/web/frontend/js/features/pdf-preview/components/pdf-code-check-failed-notice.jsx index e0d1455b49..555116ea24 100644 --- a/services/web/frontend/js/features/pdf-preview/components/pdf-code-check-failed-notice.jsx +++ b/services/web/frontend/js/features/pdf-preview/components/pdf-code-check-failed-notice.jsx @@ -1,21 +1,29 @@ import { memo } from 'react' import { useTranslation } from 'react-i18next' import Icon from '../../../shared/components/icon' +import OLNotification from '@/features/ui/components/ol/ol-notification' +import { bsVersion } from '@/features/utils/bootstrap-5' +import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher' function PdfCodeCheckFailedNotice() { const { t } = useTranslation() - return ( -
-
-
- -
-

+ + + {' '} + + } + /> {t('code_check_failed_explanation')} -

-
-
+ + } + className={bsVersion({ bs5: 'm-0', bs3: 'mb-2' })} + /> ) } diff --git a/services/web/frontend/js/features/pdf-preview/components/pdf-download-files-button.jsx b/services/web/frontend/js/features/pdf-preview/components/pdf-download-files-button.jsx index 10ff09890f..f3c2b74846 100644 --- a/services/web/frontend/js/features/pdf-preview/components/pdf-download-files-button.jsx +++ b/services/web/frontend/js/features/pdf-preview/components/pdf-download-files-button.jsx @@ -1,9 +1,16 @@ -import { Dropdown } from 'react-bootstrap' +import { Dropdown as BS3Dropdown } from 'react-bootstrap' + +import { + Dropdown, + DropdownMenu, + DropdownToggle, +} from '@/features/ui/components/bootstrap-5/dropdown-menu' import PdfFileList from './pdf-file-list' import ControlledDropdown from '../../../shared/components/controlled-dropdown' import { memo } from 'react' import { useTranslation } from 'react-i18next' import { useDetachCompileContext as useCompileContext } from '../../../shared/context/detach-compile-context' +import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher' function PdfDownloadFilesButton() { const { compiling, fileList } = useCompileContext() @@ -11,22 +18,42 @@ function PdfDownloadFilesButton() { const { t } = useTranslation() return ( - - - - - - + + + + + + + } + bs5={ + + + {t('other_logs_and_files')} + + + + + + } + /> ) } diff --git a/services/web/frontend/js/features/pdf-preview/components/pdf-file-list.jsx b/services/web/frontend/js/features/pdf-preview/components/pdf-file-list.jsx index 4661805854..5eebb3c4e0 100644 --- a/services/web/frontend/js/features/pdf-preview/components/pdf-file-list.jsx +++ b/services/web/frontend/js/features/pdf-preview/components/pdf-file-list.jsx @@ -1,7 +1,13 @@ -import { MenuItem } from 'react-bootstrap' +import { MenuItem as BS3MenuItem } from 'react-bootstrap' import { useTranslation } from 'react-i18next' import { memo } from 'react' import PropTypes from 'prop-types' +import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher' +import { + DropdownDivider, + DropdownHeader, + DropdownItem, +} from '@/features/ui/components/bootstrap-5/dropdown-menu' function PdfFileList({ fileList }) { const { t } = useTranslation() @@ -15,37 +21,93 @@ function PdfFileList({ fileList }) { } return ( - <> - {t('other_output_files')} + + {t('other_output_files')} - {fileList.top.map(file => ( - - {file.path} - - ))} + {fileList.top.map(file => ( + + {file.path} + + ))} - {fileList.other.length > 0 && fileList.top.length > 0 && ( - - )} + {fileList.other.length > 0 && fileList.top.length > 0 && ( + + )} - {fileList.other.map(file => ( - - {file.path} - - ))} + {fileList.other.map(file => ( + + {file.path} + + ))} - {fileList.archive?.fileCount > 0 && ( - - - {t('download_all')} ({fileList.archive.fileCount}) - - - )} - + {fileList.archive?.fileCount && fileList.archive?.fileCount > 0 && ( + + + {t('download_all')} ({fileList.archive.fileCount}) + + + )} + + } + bs5={ + <> + {t('other_output_files')} + + {fileList.top.map(file => ( +
  • + + {file.path} + +
  • + ))} + + {fileList.other.length > 0 && fileList.top.length > 0 && ( + + )} + + {fileList.other.map(file => ( +
  • + + {file.path} + +
  • + ))} + + {fileList.archive?.fileCount > 0 && ( +
  • + + {t('download_all')} ({fileList.archive.fileCount}) + +
  • + )} + + } + /> ) } diff --git a/services/web/frontend/js/features/pdf-preview/components/pdf-log-entry-raw-content.jsx b/services/web/frontend/js/features/pdf-preview/components/pdf-log-entry-raw-content.jsx index b8cc1c20a1..3e0a80c67d 100644 --- a/services/web/frontend/js/features/pdf-preview/components/pdf-log-entry-raw-content.jsx +++ b/services/web/frontend/js/features/pdf-preview/components/pdf-log-entry-raw-content.jsx @@ -2,7 +2,7 @@ import { useCallback, useState } from 'react' import { useResizeObserver } from '../../../shared/hooks/use-resize-observer' import { useTranslation } from 'react-i18next' import classNames from 'classnames' -import { Button } from 'react-bootstrap' +import OLButton from '@/features/ui/components/ol/ol-button' import Icon from '../../../shared/components/icon' import PropTypes from 'prop-types' @@ -44,10 +44,13 @@ export default function PdfLogEntryRawContent({ 'log-entry-content-button-container-collapsed': !expanded, })} > - + )} diff --git a/services/web/frontend/js/features/pdf-preview/components/pdf-preview-error.jsx b/services/web/frontend/js/features/pdf-preview/components/pdf-preview-error.jsx index 9a0dcd4064..c168062810 100644 --- a/services/web/frontend/js/features/pdf-preview/components/pdf-preview-error.jsx +++ b/services/web/frontend/js/features/pdf-preview/components/pdf-preview-error.jsx @@ -1,7 +1,7 @@ import PropTypes from 'prop-types' import { useTranslation, Trans } from 'react-i18next' import { memo, useCallback } from 'react' -import { Button } from 'react-bootstrap' +import OLButton from '@/features/ui/components/ol/ol-button' import PdfLogEntry from './pdf-log-entry' import { useDetachCompileContext as useCompileContext } from '../../../shared/context/detach-compile-context' import { useStopOnFirstError } from '../../../shared/hooks/use-stop-on-first-error' @@ -23,9 +23,10 @@ function PdfPreviewError({ error }) { i18nKey="something_went_wrong_rendering_pdf_expected" components={[ // eslint-disable-next-line react/jsx-key - + } level="info" diff --git a/services/web/frontend/js/features/pdf-preview/components/timeout-upgrade-prompt-new.tsx b/services/web/frontend/js/features/pdf-preview/components/timeout-upgrade-prompt-new.tsx index 54712c5427..1572eb95a0 100644 --- a/services/web/frontend/js/features/pdf-preview/components/timeout-upgrade-prompt-new.tsx +++ b/services/web/frontend/js/features/pdf-preview/components/timeout-upgrade-prompt-new.tsx @@ -4,7 +4,7 @@ import StartFreeTrialButton from '../../../shared/components/start-free-trial-bu import { memo, useCallback } from 'react' import PdfLogEntry from './pdf-log-entry' import { useStopOnFirstError } from '../../../shared/hooks/use-stop-on-first-error' -import { Button } from 'react-bootstrap' +import OLButton from '@/features/ui/components/ol/ol-button' import * as eventTracking from '../../../infrastructure/event-tracking' import { useFeatureFlag } from '@/shared/context/split-test-context' import getMeta from '@/utils/meta' @@ -84,13 +84,7 @@ const CompileTimeout = memo(function CompileTimeout({

    {hasNewPaywallCta ? t('get_more_compile_time') @@ -178,10 +172,12 @@ const PreventTimeoutHelpMessage = memo(function PreventTimeoutHelpMessage({ i18nKey="enable_stop_on_first_error_under_recompile_dropdown_menu" components={[ // eslint-disable-next-line react/jsx-key - + ) : null const headerTitleText = logType ? `${logType} ${headerTitle}` : headerTitle @@ -95,26 +105,26 @@ function PreviewLogEntryHeader({ ) : null}

    {headerTitleText}

    {locationSpanOverflown && locationLinkText ? ( - {locationLink} - + ) : ( locationLink )} {showCloseButton ? ( - + ) : null} ) diff --git a/services/web/frontend/js/features/preview/components/preview-logs-pane-max-entries.jsx b/services/web/frontend/js/features/preview/components/preview-logs-pane-max-entries.jsx index daaaca7091..82fd59195c 100644 --- a/services/web/frontend/js/features/preview/components/preview-logs-pane-max-entries.jsx +++ b/services/web/frontend/js/features/preview/components/preview-logs-pane-max-entries.jsx @@ -1,11 +1,13 @@ import { useCallback } from 'react' import PropTypes from 'prop-types' import { Trans, useTranslation } from 'react-i18next' -import { Button } from 'react-bootstrap' +import OLButton from '@/features/ui/components/ol/ol-button' import PreviewLogEntryHeader from './preview-log-entry-header' import Icon from '../../../shared/components/icon' import { useDetachCompileContext as useCompileContext } from '../../../shared/context/detach-compile-context' import { useStopOnFirstError } from '../../../shared/hooks/use-stop-on-first-error' +import MaterialIcon from '@/shared/components/material-icon' +import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher' function PreviewLogsPaneMaxEntries({ totalEntries, entriesShown, hasErrors }) { const { t } = useTranslation() @@ -34,16 +36,22 @@ function PreviewLogsPaneMaxEntries({ totalEntries, entriesShown, hasErrors }) { {hasErrors && !stoppedOnFirstError ? ( <>

    - + } + bs5={ + + } + />   {t('tip')}: , // eslint-disable-next-line jsx-a11y/anchor-has-content @@ -58,7 +66,10 @@ function PreviewLogsPaneMaxEntries({ totalEntries, entriesShown, hasErrors }) { ) : (

    - + } + bs5={} + />   {t('tip')}: {t('log_entry_maximum_entries_see_full_logs')} diff --git a/services/web/frontend/js/ide/human-readable-logs/HumanReadableLogsHints.jsx b/services/web/frontend/js/ide/human-readable-logs/HumanReadableLogsHints.jsx index a5f0d2a8ec..8c26517468 100644 --- a/services/web/frontend/js/ide/human-readable-logs/HumanReadableLogsHints.jsx +++ b/services/web/frontend/js/ide/human-readable-logs/HumanReadableLogsHints.jsx @@ -508,6 +508,8 @@ const hints = { }, } +export const ruleIds = Object.keys(hints) + if (!getMeta('ol-wikiEnabled')) { Object.keys(hints).forEach(ruleId => { hints[ruleId].extraInfoURL = null diff --git a/services/web/frontend/stories/pdf-log-entry.stories.tsx b/services/web/frontend/stories/pdf-log-entry.stories.tsx new file mode 100644 index 0000000000..0e4823a520 --- /dev/null +++ b/services/web/frontend/stories/pdf-log-entry.stories.tsx @@ -0,0 +1,75 @@ +import PdfLogEntry from '@/features/pdf-preview/components/pdf-log-entry' +import type { Meta, StoryObj } from '@storybook/react' +import { bsVersionDecorator } from '../../.storybook/utils/with-bootstrap-switcher' +import { ruleIds } from '@/ide/human-readable-logs/HumanReadableLogsHints' +import { ScopeDecorator } from './decorators/scope' +import { useMeta } from './hooks/use-meta' +import { FC, ReactNode } from 'react' +import { useScope } from './hooks/use-scope' +import { EditorView } from '@codemirror/view' + +const fakeSourceLocation = { + file: 'file.tex', + line: 12, + column: 5, +} + +const fakeLogEntry = { + key: 'fake', + ruleId: 'hint_misplaced_alignment_tab_character', + message: 'Fake message', + messageComponent: 'Fake message component', + content: 'Fake content', + type: 'Error: ', + level: 'error', + contentDetails: ['Fake detail 1', 'Fake detail 2'], + file: 'fake.tex', + line: 12, + column: 5, + raw: 'Fake raw', +} + +const fakeArgs = { + headerTitle: 'PDF Preview', + formattedContent: 'This is a log entry', + level: 'error' as const, + extraInfoURL: 'https://example.com', + showCloseButton: true, + showSourceLocationLink: true, + rawContent: 'This is a raw log entry', + contentDetails: ['detail 1', 'detail 2'], + ruleId: 'hint_misplaced_alignment_tab_character' as const, + sourceLocation: fakeSourceLocation, + logEntry: fakeLogEntry, + logType: 'Fake type', +} + +const meta: Meta = { + title: 'Editor / PDF Preview / Logs', + component: PdfLogEntry, + // @ts-ignore + decorators: [ScopeDecorator], + argTypes: { + ruleId: { control: 'select', options: [...ruleIds, 'other'] }, + ...bsVersionDecorator.argTypes, + }, + args: fakeArgs, +} + +export default meta + +type Story = StoryObj + +const Provider: FC<{ children: ReactNode }> = ({ children }) => { + useMeta({ 'ol-showAiErrorAssistant': true }) + useScope({ 'editor.view': new EditorView({ doc: '\\begin{document' }) }) + return

    {children}
    +} + +export const PdfLogEntryWithControls: Story = { + render: args => ( + + + + ), +} diff --git a/services/web/frontend/stories/pdf-preview.stories.jsx b/services/web/frontend/stories/pdf-preview.stories.jsx index 992e2b6e2e..69b6daa9a6 100644 --- a/services/web/frontend/stories/pdf-preview.stories.jsx +++ b/services/web/frontend/stories/pdf-preview.stories.jsx @@ -23,6 +23,11 @@ import { cloneDeep } from 'lodash' import { ScopeDecorator } from './decorators/scope' import { PdfPreviewProvider } from '@/features/pdf-preview/components/pdf-preview-provider' import { bsVersionDecorator } from '../../.storybook/utils/with-bootstrap-switcher' +import { + Dropdown, + DropdownMenu, +} from '@/features/ui/components/bootstrap-5/dropdown-menu' +import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher' export default { title: 'Editor / PDF Preview', @@ -286,7 +291,7 @@ export const DisplayError = () => { }) return ( - <> +
    {compileErrors.map(error => (
    {
    ))} - +
    ) } @@ -320,11 +325,22 @@ export const FileList = () => { }, []) return ( -
    -
    - -
    -
    + +
    + +
    + + } + bs5={ + + + + + + } + /> ) } diff --git a/services/web/frontend/stylesheets/app/editor/logs.less b/services/web/frontend/stylesheets/app/editor/logs.less index 32573a2d56..6362e453c4 100644 --- a/services/web/frontend/stylesheets/app/editor/logs.less +++ b/services/web/frontend/stylesheets/app/editor/logs.less @@ -32,11 +32,6 @@ overflow: hidden; } -.log-entry-first-error-popup { - border-radius: 0; - overflow: auto; -} - .log-entry-header { padding: 3px @padding-sm; display: flex; @@ -182,40 +177,6 @@ } } -.log-entry-formatted-content-list { - margin: @margin-xs 0; - padding-left: @padding-md; -} - -.first-error-popup { - position: absolute; - z-index: 1; - top: @toolbar-small-height + 2px; - right: @padding-xs; - width: 90%; - max-width: 450px; - box-shadow: 0 4px 4px rgba(0, 0, 0, 0.25); - animation: fade-in 0.15s linear 0s 1 none; - background-color: #fff; - &::before { - content: ''; - .triangle(top, @padding-sm, @padding-xs, @ol-red); - top: -@padding-xs; - right: @padding-xl; - } -} - -.first-error-popup-actions { - display: flex; - justify-content: space-between; - padding: 0 @padding-sm @padding-sm @padding-sm; - border-radius: 0 0 @border-radius-base @border-radius-base; -} - -.first-error-btn { - .no-outline-ring-on-click; -} - .log-location-tooltip { word-break: break-all; &.tooltip.in { diff --git a/services/web/frontend/stylesheets/app/editor/pdf.less b/services/web/frontend/stylesheets/app/editor/pdf.less index 5bd72b00fe..e3a4d38a23 100644 --- a/services/web/frontend/stylesheets/app/editor/pdf.less +++ b/services/web/frontend/stylesheets/app/editor/pdf.less @@ -113,14 +113,12 @@ } .pdf-viewer, -.pdf-logs, .pdf-errors, .pdf-uncompiled { .full-size; top: @pdf-top-offset; } -.pdf-logs, .pdf-errors, .pdf-uncompiled, .pdf-validation-problems { @@ -327,72 +325,6 @@ } } -.pdf-logs { - overflow: auto; - .alert { - font-size: 0.9rem; - margin-bottom: @line-height-computed / 2; - cursor: pointer; - .line-no { - float: right; - color: @log-line-no-color; - font-weight: 700; - - .fa { - opacity: 0; - } - } - .entry-message { - font-weight: 700; - //font-family: @font-family-monospace; - } - .entry-content { - white-space: pre-wrap; - font-size: 0.8rem; - //font-family: @font-family-monospace; - } - - &:hover .line-no { - color: inherit; - .fa { - opacity: 1; - } - } - - &.alert-danger { - background-color: tint(@alert-danger-bg, 15%); - &:hover { - background-color: @alert-danger-bg; - } - } - - &.alert-warning { - background-color: tint(@alert-warning-bg, 15%); - &:hover { - background-color: @alert-warning-bg; - } - } - - &.alert-info { - background-color: tint(@alert-info-bg, 15%); - &:hover { - background-color: @alert-info-bg; - } - } - } - pre { - font-size: 12px; - white-space: pre-wrap; - } - .dropdown { - position: relative; - } - .force-recompile { - margin-top: 10px; - text-align: right; - } -} - .synctex-controls { margin-right: -8px; position: absolute; @@ -443,9 +375,6 @@ } .editor-dark { - .pdf-logs { - background-color: lighten(@editor-dark-background-color, 10%); - } .pdfjs-viewer { background-color: lighten(@editor-dark-background-color, 10%); } @@ -604,21 +533,13 @@ @editor-and-logs-pane-toolbars-height: @toolbar-small-height + @toolbar-height; @btn-small-height: (@padding-small-vertical * 2)+ (@font-size-small * - @line-height-small); + @line-height-small); // 5px * 2 + 14px * 1.5 = 31px -#download-dropdown-list, #dropdown-files-logs-pane-list { overflow-y: auto; .dropdown-header { white-space: nowrap; } -} -#download-dropdown-list { - max-height: calc( - ~'100vh - ' @editor-and-logs-pane-toolbars-height ~' - ' @margin-md - ); -} -#dropdown-files-logs-pane-list { max-height: calc( ~'100vh - ' @editor-and-logs-pane-toolbars-height ~' - ' @btn-small-height ~' - ' @margin-md diff --git a/services/web/frontend/stylesheets/bootstrap-5/abstracts/variables.scss b/services/web/frontend/stylesheets/bootstrap-5/abstracts/variables.scss index ad92e08c3c..cd2fc630da 100644 --- a/services/web/frontend/stylesheets/bootstrap-5/abstracts/variables.scss +++ b/services/web/frontend/stylesheets/bootstrap-5/abstracts/variables.scss @@ -3,6 +3,8 @@ $footer-height: 50px; // Header $header-height: 68px; +$toolbar-height: 40px; +$toolbar-small-height: 32px; // Forms $form-group-margin-bottom: $spacing-06; diff --git a/services/web/frontend/stylesheets/bootstrap-5/pages/all.scss b/services/web/frontend/stylesheets/bootstrap-5/pages/all.scss index 67ad493407..a8057b2401 100644 --- a/services/web/frontend/stylesheets/bootstrap-5/pages/all.scss +++ b/services/web/frontend/stylesheets/bootstrap-5/pages/all.scss @@ -9,6 +9,7 @@ @import 'editor/hotkeys'; @import 'editor/left-menu'; @import 'editor/loading-screen'; +@import 'editor/logs'; @import 'editor/outline'; @import 'editor/file-tree'; @import 'editor/file-view'; diff --git a/services/web/frontend/stylesheets/bootstrap-5/pages/editor/logs.scss b/services/web/frontend/stylesheets/bootstrap-5/pages/editor/logs.scss new file mode 100644 index 0000000000..d3be1e2960 --- /dev/null +++ b/services/web/frontend/stylesheets/bootstrap-5/pages/editor/logs.scss @@ -0,0 +1,203 @@ +@import '../../foundations/colors'; + +.logs-pane { + position: absolute; + inset: 0; + overflow-y: auto; + background-color: var(--bg-dark-secondary); + z-index: 11; // above the PDF viewer + controls + top: var(--toolbar-small-height); + + .logs-pane-content { + display: flex; + flex-direction: column; + padding: 10px; + gap: 10px; + min-height: 100%; + } + + .logs-pane-actions { + display: flex; + flex-wrap: wrap; + place-content: flex-end flex-end; + padding: var(--spacing-03) 0; + flex-grow: 1; + align-items: flex-end; + gap: var(--spacing-04); + } + + .log-entry { + border-radius: var(--border-radius-base); + overflow: hidden; + } + + .log-entry-header { + padding: var(--spacing-02) var(--spacing-04); + display: flex; + align-items: flex-start; + gap: var(--spacing-04); + border-radius: var(--border-radius-base) var(--border-radius-base) 0 0; + color: var(--content-primary-dark); + + .material-symbols { + @include body-base; + } + } + + .log-entry-header-error { + background-color: var(--content-danger); + } + + .log-entry-header-link-error { + @include ol-button-variant( + $color: var(--content-primary-dark), + $background: var(--bg-danger-02), + $hover-background: var(--red-70) + ); + } + + .log-entry-header-warning { + background-color: var(--content-warning-dark); + } + + .log-entry-header-link-warning { + @include ol-button-variant( + $color: var(--content-primary-dark), + $background: var(--bg-warning-01), + $hover-background: var(--bg-warning-02) + ); + } + + .log-entry-header-typesetting { + background-color: var(--blue-50); + } + + .log-entry-header-link-typesetting { + @include ol-button-variant( + $color: var(--content-primary-dark), + $background: var(--blue-60), + $hover-background: var(--blue-70) + ); + } + + .log-entry-header-raw, + .log-entry-header-info { + background-color: var(--bg-dark-tertiary); + } + + .log-entry-header-link-raw, + .log-entry-header-link-info { + @include ol-button-variant( + $color: var(--content-primary-dark), + $background: var(--bg-dark-secondary), + $hover-background: var(--bg-dark-primary) + ); + } + + .log-entry-header-success { + background-color: var(--green-50); + } + + .log-entry-header-link-success { + @include ol-button-variant( + $color: var(--content-primary-dark), + $background: var(--green-60), + $hover-background: var(--green-70) + ); + } + + .log-entry-header-title { + @include body-base; + + flex-grow: 1; + font-weight: bold; + margin: 0; + color: var(--content-primary-dark); + } + + .log-entry-header-link { + color: var(--content-primary-dark); + border-width: 0; + max-width: 33%; + text-decoration: none; // needed for the "close button" + padding: 0 var(--spacing-03); + + .button-content { + min-width: 0; // needed to display the ellipsis on overflow + } + } + + .log-entry-header-link-location { + white-space: nowrap; + direction: rtl; + text-overflow: ellipsis; + overflow: hidden; + } + + .log-entry-content { + background-color: var(--bg-light-primary); + padding: var(--spacing-04); + } + + .log-entry-content-raw { + font-size: var(--font-size-01); + color: var(--content-secondary); + padding: var(--spacing-03); + margin: 0; + white-space: pre-wrap; + } + + .log-entry-content-button-container { + position: relative; + height: 40px; + margin-top: 0; + transition: + margin 0.15s ease-in-out, + opacity 0.15s ease-in-out; + padding-bottom: var(--spacing-04); + text-align: center; + background-image: linear-gradient( + 0deg, + var(--bg-light-tertiary) 0%, + transparent 100% + ); + border-radius: 0 0 var(--border-radius-base) var(--border-radius-base); + } + + .log-entry-content-button-container-collapsed { + margin-top: -40px; + } + + .log-entry-content-raw-container { + background-color: var(--bg-light-tertiary); + border-radius: var(--border-radius-base); + overflow: hidden; + margin-top: var(--spacing-03); + } +} + +.btn-secondary-compile-timeout-override { + color: var(--content-primary); + background-color: var(--bg-light-primary); + border-color: var(--border-primary); + border-width: 1px; +} + +.log-entry-formatted-content, +.log-entry-content-link { + font-size: var(--font-size-02); + margin-top: var(--spacing-02); + + &:first-of-type { + margin-top: 0; + } +} + +.log-location-tooltip { + word-break: break-all; + + & > .tooltip-inner { + max-width: 450px; + text-align: left; + } +} diff --git a/services/web/frontend/stylesheets/bootstrap-5/pages/editor/pdf.scss b/services/web/frontend/stylesheets/bootstrap-5/pages/editor/pdf.scss index 50416dcd95..e21a19adf7 100644 --- a/services/web/frontend/stylesheets/bootstrap-5/pages/editor/pdf.scss +++ b/services/web/frontend/stylesheets/bootstrap-5/pages/editor/pdf.scss @@ -136,7 +136,6 @@ } .pdf-viewer, -.pdf-logs, .pdf-errors, .pdf-uncompiled { @extend .full-size; @@ -378,3 +377,17 @@ max-width: none; } } + +#dropdown-files-logs-pane-list { + overflow-y: auto; + + .dropdown-header { + white-space: nowrap; + } + + // This keeps the dropdown menu inside the Logs div. + // "spacing-11" is there to compensate the button height and the margin around the logs. + max-height: calc( + 100vh - #{$toolbar-small-height + $toolbar-height + $spacing-11} + ); +} diff --git a/services/web/frontend/stylesheets/bootstrap-5/pages/editor/toolbar.scss b/services/web/frontend/stylesheets/bootstrap-5/pages/editor/toolbar.scss index 2eb210dce8..0e13fea449 100644 --- a/services/web/frontend/stylesheets/bootstrap-5/pages/editor/toolbar.scss +++ b/services/web/frontend/stylesheets/bootstrap-5/pages/editor/toolbar.scss @@ -1,3 +1,5 @@ +@import '../../abstracts/variables'; + :root { --toolbar-border-color: var(--neutral-80); --toolbar-header-bg-color: var(--neutral-90); @@ -7,7 +9,8 @@ --toolbar-btn-hover-color: var(--white); --toolbar-btn-active-color: var(--white); --toolbar-btn-active-bg-color: var(--green-50); - --toolbar-small-height: 32px; + --toolbar-height: #{$toolbar-height}; + --toolbar-small-height: #{$toolbar-small-height}; --toolbar-alt-bg-color: var(--neutral-80); --formatting-btn-color: var(--white); --formatting-btn-bg: var(--neutral-80); @@ -208,8 +211,6 @@ } &.toolbar-header { - --toolbar-height: 40px; - align-items: stretch; background-color: var(--toolbar-header-bg-color); position: absolute; @@ -315,7 +316,7 @@ } .toolbar-editor { - height: 32px; + height: var(--toolbar-small-height); background-color: var(--editor-toolbar-bg); padding: 0 5px; overflow: hidden;