diff --git a/services/web/app/views/project/editor/pdf.pug b/services/web/app/views/project/editor/pdf.pug
index 7333dc6871..121468cec5 100644
--- a/services/web/app/views/project/editor/pdf.pug
+++ b/services/web/app/views/project/editor/pdf.pug
@@ -5,16 +5,16 @@ div.full-size.pdf(ng-controller="PdfController")
isAutoCompileOn: autocompile_enabled,
isCompiling: pdf.compiling,
isDraftModeOn: draft,
- isSyntaxCheckOn: stop_on_validation_error
+ isSyntaxCheckOn: stop_on_validation_error,
+ logEntries: pdf.logEntries ? pdf.logEntries : {}
}`
- log-entries="pdf.logEntries ? pdf.logEntries.all : []"
on-recompile="recompile"
on-run-syntax-check-now="runSyntaxCheckNow"
on-set-auto-compile="setAutoCompile"
on-set-draft-mode="setDraftMode"
on-set-syntax-check="setSyntaxCheck"
on-toggle-logs="toggleLogs"
- should-show-logs="shouldShowLogs"
+ show-logs="shouldShowLogs"
)
else
.toolbar.toolbar-pdf(ng-class="{ 'changes-to-autocompile': changesToAutoCompile && !autoCompileLintingError }")
diff --git a/services/web/frontend/extracted-translation-keys.json b/services/web/frontend/extracted-translation-keys.json
index 12aa76d6e8..2b66f41da2 100644
--- a/services/web/frontend/extracted-translation-keys.json
+++ b/services/web/frontend/extracted-translation-keys.json
@@ -21,5 +21,9 @@
"loading",
"no_messages",
"send_first_message",
- "your_message"
+ "your_message",
+ "your_project_has_errors",
+ "view_warnings",
+ "view_logs",
+ "view_pdf"
]
diff --git a/services/web/frontend/js/features/preview/components/preview-log-entry.js b/services/web/frontend/js/features/preview/components/preview-log-entry.js
index b1c66bd429..e0c57ddc24 100644
--- a/services/web/frontend/js/features/preview/components/preview-log-entry.js
+++ b/services/web/frontend/js/features/preview/components/preview-log-entry.js
@@ -1,6 +1,7 @@
import React from 'react'
import PropTypes from 'prop-types'
import classNames from 'classnames'
+import Icon from '../../../shared/components/icon'
function PreviewLogEntry({ file, line, message, content, raw, level }) {
const logEntryClasses = classNames('alert', {
@@ -11,7 +12,7 @@ function PreviewLogEntry({ file, line, message, content, raw, level }) {
return (
-
+
{file ? {file} : null}
{line ? , {line} : null}
diff --git a/services/web/frontend/js/features/preview/components/preview-logs-toggle-button.js b/services/web/frontend/js/features/preview/components/preview-logs-toggle-button.js
new file mode 100644
index 0000000000..f815dbbc02
--- /dev/null
+++ b/services/web/frontend/js/features/preview/components/preview-logs-toggle-button.js
@@ -0,0 +1,110 @@
+import React from 'react'
+import PropTypes from 'prop-types'
+import classNames from 'classnames'
+import { useTranslation } from 'react-i18next'
+import Icon from '../../../shared/components/icon'
+
+function PreviewLogsToggleButton({
+ onToggle,
+ showLogs,
+ logsState: { nErrors, nWarnings }
+}) {
+ const toggleButtonClasses = classNames('btn', 'btn-xs', 'btn-toggle-logs', {
+ 'btn-danger': !showLogs && nErrors,
+ 'btn-warning': !showLogs && !nErrors && nWarnings,
+ 'btn-default': showLogs || (!nErrors && !nWarnings)
+ })
+
+ function handleOnClick(e) {
+ e.currentTarget.blur()
+ onToggle()
+ }
+
+ return (
+
+ )
+}
+
+function CompilationResultIndicator({ nErrors, nWarnings }) {
+ if (nErrors) {
+ return
+ } else if (nWarnings) {
+ return
+ } else {
+ return
+ }
+}
+
+function ErrorsCompilationResultIndicator({ nErrors }) {
+ const { t } = useTranslation()
+ return (
+ <>
+
+
+ {`${t('your_project_has_errors')} (${nErrors > 9 ? '9+' : nErrors})`}
+
+ >
+ )
+}
+
+function WarningsCompilationResultIndicator({ nWarnings }) {
+ const { t } = useTranslation()
+ return (
+ <>
+
+
+ {`${t('view_warnings')} (${nWarnings > 9 ? '9+' : nWarnings})`}
+
+ >
+ )
+}
+
+function ViewLogsButton() {
+ const { t } = useTranslation()
+ return (
+ <>
+
+
{t('view_logs')}
+ >
+ )
+}
+
+function ViewPdfButton() {
+ const { t } = useTranslation()
+ return (
+ <>
+
+
{t('view_pdf')}
+ >
+ )
+}
+
+PreviewLogsToggleButton.propTypes = {
+ onToggle: PropTypes.func.isRequired,
+ logsState: PropTypes.shape({
+ nErrors: PropTypes.number.isRequired,
+ nWarnings: PropTypes.number.isRequired,
+ nLogEntries: PropTypes.number.isRequired
+ }),
+ showLogs: PropTypes.bool.isRequired
+}
+
+ErrorsCompilationResultIndicator.propTypes = {
+ nErrors: PropTypes.number.isRequired
+}
+
+WarningsCompilationResultIndicator.propTypes = {
+ nWarnings: PropTypes.number.isRequired
+}
+
+export default PreviewLogsToggleButton
diff --git a/services/web/frontend/js/features/preview/components/preview-pane.js b/services/web/frontend/js/features/preview/components/preview-pane.js
index bfde5698c1..6a7c12ab9e 100644
--- a/services/web/frontend/js/features/preview/components/preview-pane.js
+++ b/services/web/frontend/js/features/preview/components/preview-pane.js
@@ -5,19 +5,33 @@ import PreviewLogsPane from './preview-logs-pane'
function PreviewPane({
compilerState,
- logEntries,
onRecompile,
onRunSyntaxCheckNow,
onSetAutoCompile,
onSetDraftMode,
onSetSyntaxCheck,
onToggleLogs,
- shouldShowLogs
+ showLogs
}) {
+ const nErrors =
+ compilerState.logEntries && compilerState.logEntries.errors
+ ? compilerState.logEntries.errors.length
+ : 0
+ const nWarnings =
+ compilerState.logEntries && compilerState.logEntries.warnings
+ ? compilerState.logEntries.warnings.length
+ : 0
+ const nLogEntries =
+ compilerState.logEntries && compilerState.logEntries.all
+ ? compilerState.logEntries.all.length
+ : 0
+
return (
<>
- {shouldShowLogs ?
: null}
+ {showLogs ? (
+
+ ) : null}
>
)
}
@@ -35,16 +51,16 @@ PreviewPane.propTypes = {
isAutoCompileOn: PropTypes.bool.isRequired,
isCompiling: PropTypes.bool.isRequired,
isDraftModeOn: PropTypes.bool.isRequired,
- isSyntaxCheckOn: PropTypes.bool.isRequired
+ isSyntaxCheckOn: PropTypes.bool.isRequired,
+ logEntries: PropTypes.object.isRequired
}),
- logEntries: PropTypes.array,
onRecompile: PropTypes.func.isRequired,
onRunSyntaxCheckNow: PropTypes.func.isRequired,
onSetAutoCompile: PropTypes.func.isRequired,
onSetDraftMode: PropTypes.func.isRequired,
onSetSyntaxCheck: PropTypes.func.isRequired,
onToggleLogs: PropTypes.func.isRequired,
- shouldShowLogs: PropTypes.bool.isRequired
+ showLogs: PropTypes.bool.isRequired
}
export default PreviewPane
diff --git a/services/web/frontend/js/features/preview/components/preview-recompile-button.js b/services/web/frontend/js/features/preview/components/preview-recompile-button.js
index 6112653968..d715b22f9e 100644
--- a/services/web/frontend/js/features/preview/components/preview-recompile-button.js
+++ b/services/web/frontend/js/features/preview/components/preview-recompile-button.js
@@ -1,8 +1,8 @@
import React from 'react'
import PropTypes from 'prop-types'
-import classNames from 'classnames'
import { Dropdown, MenuItem } from 'react-bootstrap'
import { useTranslation } from 'react-i18next'
+import Icon from '../../../shared/components/icon'
function PreviewRecompileButton({
compilerState: {
@@ -19,20 +19,6 @@ function PreviewRecompileButton({
}) {
const { t } = useTranslation()
- const iconClasses = {
- recompile: classNames('fa', 'fa-refresh', {
- 'fa-spin': isCompiling
- }),
- autoCompileOn: classNames('fa', 'fa-fw', { 'fa-check': isAutoCompileOn }),
- autoCompileOff: classNames('fa', 'fa-fw', { 'fa-check': !isAutoCompileOn }),
- compileModeNormal: classNames('fa', 'fa-fw', {
- 'fa-check': !isDraftModeOn
- }),
- compileModeDraft: classNames('fa', 'fa-fw', { 'fa-check': isDraftModeOn }),
- syntaxCheckOn: classNames('fa', 'fa-fw', { 'fa-check': isSyntaxCheckOn }),
- syntaxCheckOff: classNames('fa', 'fa-fw', { 'fa-check': !isSyntaxCheckOn })
- }
-
function handleSelectAutoCompileOn() {
onSetAutoCompile(true)
}
@@ -60,7 +46,7 @@ function PreviewRecompileButton({
return (