diff --git a/services/web/frontend/stories/decorators/scope.tsx b/services/web/frontend/stories/decorators/scope.tsx
index 9bde1eebfa..85785743d0 100644
--- a/services/web/frontend/stories/decorators/scope.tsx
+++ b/services/web/frontend/stories/decorators/scope.tsx
@@ -21,7 +21,7 @@ import { ReactContextRoot } from '@/features/ide-react/context/react-context-roo
const scopeWatchers: [string, (value: any) => void][] = []
-const user: User = {
+export const user: User = {
id: 'story-user' as UserId,
email: 'story-user@example.com',
allowedFreeTrial: true,
diff --git a/services/web/frontend/stories/pdf-error-state.stories.tsx b/services/web/frontend/stories/pdf-error-state.stories.tsx
new file mode 100644
index 0000000000..4e61768788
--- /dev/null
+++ b/services/web/frontend/stories/pdf-error-state.stories.tsx
@@ -0,0 +1,90 @@
+import useFetchMock from './hooks/use-fetch-mock'
+import { mockCompile } from './fixtures/compile'
+import { ScopeDecorator, user } from './decorators/scope'
+import PdfErrorState from '@/features/ide-redesign/components/pdf-preview/pdf-error-state'
+import { useDetachCompileContext as useCompileContext } from '@/shared/context/detach-compile-context'
+import { useEffect } from 'react'
+import PdfPreview from '@/features/pdf-preview/components/pdf-preview'
+
+export default {
+ title: 'Editor / PDF Error States',
+ component: PdfErrorState,
+}
+
+const compileErrors = [
+ 'autocompile-backoff',
+ 'clear-cache',
+ 'clsi-maintenance',
+ 'compile-in-progress',
+ 'exited',
+ 'failure',
+ 'generic',
+ 'project-too-large',
+ 'rate-limited',
+ 'success',
+ 'terminated',
+ 'timedout',
+ 'too-recently-compiled',
+ 'unavailable',
+ 'validation-problems',
+ 'foo',
+] as const
+
+const ErrorPane = ({ error }: { error: (typeof compileErrors)[number] }) => {
+ window.metaAttributesCache.set('ol-splitTestVariants', {
+ 'editor-redesign': 'enabled',
+ })
+ useFetchMock(fetchMock => {
+ mockCompile(fetchMock)
+ })
+ const { setError } = useCompileContext()
+ useEffect(() => {
+ setError(error)
+ }, [setError, error])
+
+ return (
+
+ )
+}
+
+const story = {
+ render: (args: { error: (typeof compileErrors)[number] }) => {
+ return
+ },
+ argTypes: {
+ error: {
+ options: compileErrors,
+ control: {
+ type: 'select',
+ },
+ },
+ },
+ args: {
+ error: compileErrors[0],
+ },
+}
+
+export const PremiumUser = {
+ ...story,
+ decorators: [ScopeDecorator],
+}
+
+export const FreeUser = {
+ ...story,
+ decorators: [
+ (Story: any) =>
+ ScopeDecorator(
+ Story,
+ { mockCompileOnLoad: false },
+ {
+ 'ol-user': {
+ ...user,
+ features: { ...user.features, compileTimeout: 20 },
+ },
+ }
+ ),
+ ],
+}
diff --git a/services/web/frontend/stylesheets/abstracts/mixins.scss b/services/web/frontend/stylesheets/abstracts/mixins.scss
index 1a79a1221c..0b8ebff3e5 100644
--- a/services/web/frontend/stylesheets/abstracts/mixins.scss
+++ b/services/web/frontend/stylesheets/abstracts/mixins.scss
@@ -156,6 +156,12 @@
--link-visited-color: var(--link-visited-color-dark);
}
+@mixin themed-links {
+ --link-color: var(--link-ui-themed);
+ --link-hover-color: var(--link-ui-hover-themed);
+ --link-visited-color: var(--link-ui-visited-themed);
+}
+
@mixin triangle($direction, $width, $height, $color) {
position: absolute;
border-color: transparent;
diff --git a/services/web/frontend/stylesheets/pages/editor/pdf-error-state.scss b/services/web/frontend/stylesheets/pages/editor/pdf-error-state.scss
index aee036f775..8b1566df0e 100644
--- a/services/web/frontend/stylesheets/pages/editor/pdf-error-state.scss
+++ b/services/web/frontend/stylesheets/pages/editor/pdf-error-state.scss
@@ -1,19 +1,3 @@
-:root {
- --pdf-error-state-info-box-color: var(--content-primary-dark);
- --pdf-error-state-info-box-background: var(--bg-dark-primary);
- --pdf-error-state-info-box-border: var(--border-divider-dark);
- --pdf-error-state-label-color: var(--content-primary-dark);
- --pdf-error-state-description-color: var(--content-secondary-dark);
-}
-
-@include theme('light') {
- --pdf-error-state-info-box-color: var(--content-primary);
- --pdf-error-state-info-box-background: var(--bg-light-primary);
- --pdf-error-state-info-box-border: var(--border-divider);
- --pdf-error-state-label-color: var(--content-primary);
- --pdf-error-state-description-color: var(--content-secondary);
-}
-
.pdf-error-state {
position: absolute;
inset: var(--toolbar-small-height) 0 0 0;
@@ -34,6 +18,7 @@
}
.pdf-error-state-icon {
+ color: var(--content-primary-themed);
width: 80px;
height: 80px;
display: flex;
@@ -44,14 +29,14 @@
.material-symbols {
font-size: 80px;
}
-}
-.pdf-error-state-warning-icon {
- background-color: var(--bg-danger-03);
- color: var(--content-danger);
+ &.pdf-error-state-warning-icon {
+ background-color: var(--bg-danger-03);
+ color: var(--content-danger);
- .material-symbols {
- font-size: 32px;
+ .material-symbols {
+ font-size: 32px;
+ }
}
}
@@ -64,23 +49,25 @@
.pdf-error-state-label {
font-size: var(--font-size-02);
- color: var(--pdf-error-state-label-color);
+ color: var(--content-primary-themed);
font-weight: 600;
margin-bottom: 0;
}
.pdf-error-state-description {
- color: var(--pdf-error-state-description-color);
+ color: var(--content-secondary-themed);
font-size: var(--font-size-02);
margin-bottom: 0;
}
.pdf-error-state-info-box {
- background-color: var(--pdf-error-state-info-box-background);
- color: var(--pdf-error-state-info-box-color);
+ background-color: var(--bg-primary-themed);
+ color: var(--content-primary-themed);
padding: var(--spacing-06);
- border: 1px solid var(--pdf-error-state-info-box-border);
+ border: 1px solid var(--border-divider-themed);
border-radius: var(--border-radius-base);
+
+ @include themed-links;
}
.pdf-error-state-info-box-title {
@@ -94,8 +81,12 @@
.pdf-error-state-info-box-text {
font-size: var(--font-size-02);
- display: flex;
- flex-direction: column;
- gap: var(--spacing-02);
- margin-bottom: 0;
+}
+
+.pdf-error-state-info-box-list {
+ margin-bottom: 0;
+
+ li + li {
+ margin-top: var(--spacing-02);
+ }
}
diff --git a/services/web/locales/en.json b/services/web/locales/en.json
index 0f694d0572..67801974d7 100644
--- a/services/web/locales/en.json
+++ b/services/web/locales/en.json
@@ -1753,9 +1753,11 @@
"project_search_result_count": "__count__ result",
"project_search_result_count_plural": "__count__ results",
"project_synchronisation": "Project synchronisation",
+ "project_timed_out_common_causes": "Most common causes of timeouts are:",
"project_timed_out_enable_stop_on_first_error": "<0>Enable “Stop on first error”0> to help you find and fix errors right away.",
"project_timed_out_fatal_error": "A <0>fatal compile error0> may be completely blocking compilation.",
"project_timed_out_intro": "Sorry, your compile took too long to run and timed out. The most common causes of timeouts are:",
+ "project_timed_out_intro_short": "Sorry, your compile took too long to run and timed out",
"project_timed_out_learn_more": "<0>Learn more0> about other causes of compile timeouts and how to fix them.",
"project_timed_out_optimize_images": "Large or high-resolution images are taking too long to process. You may be able to <0>optimize them0>.",
"project_too_large": "Project too large",