Explorar o código

Merge pull request #3558 from overleaf/pr-logs-ui-beta-icon

Logs UI beta icons

GitOrigin-RevId: 2d22dea3625ed24b87a1ae9e48cbbe77ad8a1827
Eric Mc Sween %!s(int64=5) %!d(string=hai) anos
pai
achega
78b7c8de9b

+ 1 - 1
services/web/app/views/beta_program/opt_in.pug

@@ -21,7 +21,7 @@ block content
 
 										p #[strong How it works:]
 										ul
-											li #{translate("beta_program_badge_description")}#[span(aria-label=translate("beta_feature_badge") role="img").beta-feature-badge]
+											li #{translate("beta_program_badge_description")} #[span(aria-label=translate("beta_feature_badge") role="img").beta-badge]
 											li #{translate("you_will_be_able_to_contact_us_any_time_to_share_your_feedback")}.
 											li #{translate("we_may_also_contact_you_from_time_to_time_by_email_with_a_survey")}.
 											li #{translate("you_can_opt_in_and_out_of_the_program_at_any_time_on_this_page")}.

+ 4 - 0
services/web/frontend/extracted-translation-keys.json

@@ -28,6 +28,7 @@
   "delete",
   "deleting",
   "dismiss_error_popup",
+  "dismiss",
   "done",
   "download_file",
   "download_pdf",
@@ -49,6 +50,7 @@
   "full_doc_history",
   "full_screen",
   "generic_something_went_wrong",
+  "give_feedback",
   "go_to_error_location",
   "headers",
   "hide_outline",
@@ -60,6 +62,8 @@
   "loading",
   "log_entry_description",
   "log_hint_extra_info",
+  "logs_pane_beta_message",
+  "logs_pane_beta_message_popup",
   "main_file_not_found",
   "math_display",
   "math_inline",

+ 23 - 0
services/web/frontend/js/features/preview/components/preview-first-error-pop-up.js

@@ -3,6 +3,7 @@ import PropTypes from 'prop-types'
 import { useTranslation } from 'react-i18next'
 import Icon from '../../../shared/components/icon'
 import PreviewLogsPaneEntry from './preview-logs-pane-entry'
+import { OverlayTrigger, Tooltip } from 'react-bootstrap'
 
 function PreviewFirstErrorPopUp({
   logEntry,
@@ -25,6 +26,7 @@ function PreviewFirstErrorPopUp({
     >
       <PreviewLogsPaneEntry
         headerTitle={logEntry.message}
+        headerIcon={<FirstErrorPopUpBetaBadge />}
         rawContent={logEntry.content}
         formattedContent={logEntry.humanReadableHintComponent}
         extraInfoURL={logEntry.extraInfoURL}
@@ -58,6 +60,27 @@ function PreviewFirstErrorPopUp({
   )
 }
 
+function FirstErrorPopUpBetaBadge() {
+  const { t } = useTranslation()
+  const logsPaneBetaMessage = t('logs_pane_beta_message_popup')
+  const tooltip = (
+    <Tooltip id="file-tree-badge-tooltip">{logsPaneBetaMessage}</Tooltip>
+  )
+
+  return (
+    <OverlayTrigger placement="bottom" overlay={tooltip} delayHide={100}>
+      <a
+        href="/beta/participate"
+        target="_blank"
+        rel="noopener noreferrer"
+        className="beta-badge"
+      >
+        <span className="sr-only">{logsPaneBetaMessage}</span>
+      </a>
+    </OverlayTrigger>
+  )
+}
+
 PreviewFirstErrorPopUp.propTypes = {
   logEntry: PropTypes.object.isRequired,
   onGoToErrorLocation: PropTypes.func.isRequired,

+ 8 - 0
services/web/frontend/js/features/preview/components/preview-logs-pane-entry.js

@@ -9,6 +9,7 @@ import Icon from '../../../shared/components/icon'
 
 function PreviewLogsPaneEntry({
   headerTitle,
+  headerIcon,
   rawContent,
   logType,
   formattedContent,
@@ -35,6 +36,7 @@ function PreviewLogsPaneEntry({
         level={level}
         sourceLocation={sourceLocation}
         headerTitle={headerTitle}
+        headerIcon={headerIcon}
         logType={logType}
         showSourceLocationLink={showSourceLocationLink}
         onSourceLocationClick={handleLogEntryLinkClick}
@@ -56,6 +58,7 @@ function PreviewLogEntryHeader({
   sourceLocation,
   level,
   headerTitle,
+  headerIcon,
   logType,
   showSourceLocationLink = true,
   showCloseButton = false,
@@ -139,6 +142,9 @@ function PreviewLogEntryHeader({
 
   return (
     <header className={logEntryHeaderClasses}>
+      {headerIcon ? (
+        <div className="log-entry-header-icon-container">{headerIcon}</div>
+      ) : null}
       <h3 className="log-entry-header-title">{headerTitleText}</h3>
       {showLocationTooltip ? (
         <OverlayTrigger placement="left" overlay={locationTooltip}>
@@ -237,6 +243,7 @@ PreviewLogEntryHeader.propTypes = {
   }),
   level: PropTypes.string.isRequired,
   headerTitle: PropTypes.string,
+  headerIcon: PropTypes.element,
   logType: PropTypes.string,
   showSourceLocationLink: PropTypes.bool,
   showCloseButton: PropTypes.bool,
@@ -253,6 +260,7 @@ PreviewLogEntryContent.propTypes = {
 PreviewLogsPaneEntry.propTypes = {
   sourceLocation: PreviewLogEntryHeader.propTypes.sourceLocation,
   headerTitle: PropTypes.string,
+  headerIcon: PropTypes.element,
   rawContent: PropTypes.string,
   logType: PropTypes.string,
   formattedContent: PropTypes.node,

+ 45 - 0
services/web/frontend/js/features/preview/components/preview-logs-pane.js

@@ -7,6 +7,7 @@ import PreviewValidationIssue from './preview-validation-issue'
 import PreviewDownloadFileList from './preview-download-file-list'
 import PreviewError from './preview-error'
 import Icon from '../../../shared/components/icon'
+import usePersistedState from '../../../infrastructure/persisted-state-hook'
 
 function PreviewLogsPane({
   logEntries = { all: [], errors: [], warnings: [], typesetting: [] },
@@ -111,6 +112,7 @@ function PreviewLogsPane({
   return (
     <div className="logs-pane">
       <div className="logs-pane-content">
+        <LogsPaneBetaNotice />
         {errors ? errorsUI : null}
         {validationIssues ? validationIssuesUI : null}
         {allCompilerIssues.length > 0 ? logEntriesUI : null}
@@ -121,6 +123,49 @@ function PreviewLogsPane({
   )
 }
 
+function LogsPaneBetaNotice() {
+  const { t } = useTranslation()
+  const [dismissedBetaNotice, setDismissedBetaNotice] = usePersistedState(
+    `logs_pane.dismissed_beta_notice`,
+    false
+  )
+
+  function handleDismissButtonClick() {
+    setDismissedBetaNotice(true)
+  }
+
+  return dismissedBetaNotice ? null : (
+    <div className="log-entry">
+      <div className="log-entry-header log-entry-header-raw">
+        <div className="log-entry-header-icon-container">
+          <span className="beta-badge" />
+        </div>
+        <h3 className="log-entry-header-title">
+          {t('logs_pane_beta_message')}
+        </h3>
+        <a
+          href="/beta/participate"
+          target="_blank"
+          rel="noopener noreferrer"
+          className="log-entry-header-link log-entry-header-link-raw"
+        >
+          <span className="log-entry-header-link-location">
+            {t('give_feedback')}
+          </span>
+        </a>
+        <button
+          className="btn-inline-link log-entry-header-link"
+          type="button"
+          aria-label={t('dismiss')}
+          onClick={handleDismissButtonClick}
+        >
+          <span aria-hidden="true">&times;</span>
+        </button>
+      </div>
+    </div>
+  )
+}
+
 PreviewLogsPane.propTypes = {
   logEntries: PropTypes.shape({
     all: PropTypes.array,

+ 45 - 37
services/web/frontend/stories/preview-logs-pane-entry.stories.js

@@ -1,77 +1,85 @@
 import React from 'react'
 import PreviewLogsPaneEntry from '../js/features/preview/components/preview-logs-pane-entry.js'
+import Icon from '../js/shared/components/icon.js'
 
-export const ErrorWithCompilerOutput = args => (
+export const EntryWithCompilerOutput = args => (
   <PreviewLogsPaneEntry {...args} />
 )
-ErrorWithCompilerOutput.args = {
+EntryWithCompilerOutput.args = {
+  title: 'PreviewLogsPaneEntry/bar/baz',
   level: 'error'
 }
 
-export const ErrorWithCompilerOutputAndHumanReadableHint = args => (
+export const EntryWithCompilerOutputAndHumanReadableHint = args => (
   <PreviewLogsPaneEntry {...args} />
 )
-ErrorWithCompilerOutputAndHumanReadableHint.args = {
+EntryWithCompilerOutputAndHumanReadableHint.args = {
   level: 'error',
   formattedContent: <SampleHumanReadableHintComponent />,
   extraInfoURL:
     'https://www.overleaf.com/learn/latex/Errors/Extra_alignment_tab_has_been_changed_to_%5Ccr'
 }
 
-export const ErrorWithoutCompilerOutput = args => (
+export const EntryWithoutCompilerOutput = args => (
   <PreviewLogsPaneEntry {...args} />
 )
-ErrorWithoutCompilerOutput.args = {
+EntryWithoutCompilerOutput.args = {
   level: 'error',
   rawContent: null
 }
 
-export const WarningWithCompilerOutput = args => (
+export const EntryWithoutSourceLocationLink = args => (
   <PreviewLogsPaneEntry {...args} />
 )
-WarningWithCompilerOutput.args = {
+EntryWithoutSourceLocationLink.args = {
+  level: 'error',
+  showSourceLocationLink: false
+}
+
+export const EntryWithLevelError = args => <PreviewLogsPaneEntry {...args} />
+EntryWithLevelError.args = {
+  level: 'error'
+}
+
+export const EntryWithLevelWarning = args => <PreviewLogsPaneEntry {...args} />
+EntryWithLevelWarning.args = {
   level: 'warning'
 }
 
-export const WarningWithCompilerOutputAndHumanReadableHint = args => (
+export const EntryWithLevelTypesetting = args => (
   <PreviewLogsPaneEntry {...args} />
 )
-WarningWithCompilerOutputAndHumanReadableHint.args = {
-  level: 'warning',
-  formattedContent: <SampleHumanReadableHintComponent />,
-  extraInfoURL:
-    'https://www.overleaf.com/learn/latex/Errors/Extra_alignment_tab_has_been_changed_to_%5Ccr'
+EntryWithLevelTypesetting.args = {
+  level: 'typesetting'
 }
 
-export const WarningWithoutCompilerOutput = args => (
-  <PreviewLogsPaneEntry {...args} />
-)
-WarningWithoutCompilerOutput.args = {
-  level: 'warning',
-  rawContent: null
+export const EntryWithLevelRaw = args => <PreviewLogsPaneEntry {...args} />
+EntryWithLevelRaw.args = {
+  level: 'raw'
 }
 
-export const InfoWithCompilerOutput = args => <PreviewLogsPaneEntry {...args} />
-InfoWithCompilerOutput.args = {
-  level: 'typesetting'
+export const EntryWithLevelSuccess = args => <PreviewLogsPaneEntry {...args} />
+EntryWithLevelSuccess.args = {
+  level: 'success'
 }
 
-export const InfoWithCompilerOutputAndHumanReadableHint = args => (
-  <PreviewLogsPaneEntry {...args} />
-)
-InfoWithCompilerOutputAndHumanReadableHint.args = {
-  level: 'typesetting',
-  formattedContent: <SampleHumanReadableHintComponent />,
-  extraInfoURL:
-    'https://www.overleaf.com/learn/latex/Errors/Extra_alignment_tab_has_been_changed_to_%5Ccr'
+export const EntryWithButtonToClose = args => <PreviewLogsPaneEntry {...args} />
+EntryWithButtonToClose.args = {
+  level: 'error',
+  showCloseButton: true,
+  onClose: () => window.alert('You clicked "×"')
 }
 
-export const InfoWithoutCompilerOutput = args => (
-  <PreviewLogsPaneEntry {...args} />
-)
-InfoWithoutCompilerOutput.args = {
+export const EntryWithIcon = args => <PreviewLogsPaneEntry {...args} />
+EntryWithIcon.args = {
+  level: 'error',
+  headerIcon: <Icon type="taxi" />
+}
+
+export const EntryWithBetaIcon = args => <PreviewLogsPaneEntry {...args} />
+EntryWithBetaIcon.args = {
   level: 'typesetting',
-  rawContent: null
+  headerIcon: <span className="beta-badge" />
 }
 
 function SampleHumanReadableHintComponent() {
@@ -100,7 +108,7 @@ export default {
       line: 10,
       column: 20
     },
-    headerTitle: 'Lorem ipsum',
+    headerTitle: 'Entry title',
     rawContent: `
 The LaTeX compiler output
   * With a lot of details

+ 0 - 12
services/web/frontend/stylesheets/app/beta-program.less

@@ -3,15 +3,3 @@
     margin-top: 15px;
   }
 }
-
-.beta-feature-badge {
-  &:extend(.label);
-  &:extend(.label-warning);
-  vertical-align: 11%;
-  padding-bottom: 4px;
-  padding-top: 2px;
-  margin-left: 12px;
-  &:before {
-    content: 'β';
-  }
-}

+ 6 - 0
services/web/frontend/stylesheets/app/editor/logs.less

@@ -95,6 +95,10 @@
   color: #fff;
 }
 
+.log-entry-header-icon-container {
+  margin-right: @margin-sm;
+}
+
 .log-entry-header-link {
   display: flex;
   align-items: center;
@@ -104,8 +108,10 @@
   text-align: right;
   margin-left: @margin-sm;
   max-width: 33%;
+  padding: 0 @padding-xs;
   &:hover,
   &:focus {
+    text-decoration: none;
     outline: 0;
     color: #fff;
   }

+ 1 - 2
services/web/frontend/stylesheets/components/beta-badges.less

@@ -1,11 +1,10 @@
 .info-badge,
 .beta-badge {
-  display: block;
+  display: inline-block;
   width: @line-height-computed * 0.75;
   height: @line-height-computed * 0.75;
   line-height: @line-height-computed * 0.75;
   text-align: center;
-  cursor: pointer;
   color: #fff;
 
   &:hover,

+ 3 - 1
services/web/locales/en.json

@@ -1,5 +1,7 @@
 {
   "reload_editor": "Reload editor",
+  "logs_pane_beta_message": "We are beta testing a new logs pane",
+  "logs_pane_beta_message_popup": "We are beta testing a new logs pane. Click here to give feedback and manage your beta program membership.",
   "compile_error_description": "This project did not compile because of an error",
   "validation_issue_description": "This project did not compile because of a validation issue",
   "compile_error_entry_description": "An error which prevented this project from compiling",
@@ -1337,4 +1339,4 @@
   "add_affiliation": "Add Affiliation",
   "did_you_know_institution_providing_professional": "Did you know that __institutionName__ is providing <0>free __appName__ Professional features</0> to everyone at __institutionName__?",
   "add_email_to_claim_features": "Add an institutional email address to claim your features."
-}
+}