From 09ab19323998845b65adc43bfa907fb979c1d75b Mon Sep 17 00:00:00 2001 From: Davinder Singh Date: Mon, 10 Feb 2025 12:15:37 +0000 Subject: [PATCH] Compile timeout Paywall - Adding the second component that will be displayed after paywall dismissal (#23413) * copy pasting the code into new redesign file from old paywall file * creating a new file for redesign - pdf-log-entry-redesign and copy pasting the old file content for now * adding redesign file for header and copy pasting old file content for now * using pdf-log-entry-redesign * adding first round of styling for headint title under BS5 styling * adding hasBorder property on the inhouse button component * adding a cta container for 2 buttons * adding the icon and fixing the class hierarchy * fixing the spacing so spacing matches the figma design * adding a translation for heading * adding bg color and spacing for heading * removing no thanks button * changing the font size * adding the link colors * adding the required spacing on the new website redesign logs pane components * seperating the whole component into a new component TimeoutMessageAfterPaywallDismissal for easy display later in * removing the class that I had added earlier * deleting the website redesign folder because files dupliocated in that folder did not have any content changes, redesign only needs styling changes for now * adding try for free translation * adding the unfilled icon and ficing the heading sizew * fixing the padding of log-entry-formatted-content * running npm run extract-translations GitOrigin-RevId: 810ddd6037cbad0761ea23a9a2e0693a7ad7130a --- .../web/frontend/extracted-translations.json | 2 + ...alSymbolsRoundedUnfilledPartialSlice.woff2 | Bin 3860 -> 3704 bytes .../material-symbols/unfilled-symbols.mjs | 1 + ...imeout-message-after-paywall-dismissal.tsx | 196 ++++++++++++++++++ .../timeout-upgrade-paywall-prompt.tsx | 4 +- .../bootstrap-5/pages/editor/logs.scss | 55 +++++ services/web/locales/en.json | 1 + 7 files changed, 258 insertions(+), 1 deletion(-) create mode 100644 services/web/frontend/js/features/pdf-preview/components/timeout-message-after-paywall-dismissal.tsx diff --git a/services/web/frontend/extracted-translations.json b/services/web/frontend/extracted-translations.json index 8cf14cc2e3..7ba5f47b3f 100644 --- a/services/web/frontend/extracted-translations.json +++ b/services/web/frontend/extracted-translations.json @@ -1198,6 +1198,7 @@ "professional": "", "progress_bar_percentage": "", "project_approaching_file_limit": "", + "project_failed_to_compile": "", "project_figure_modal": "", "project_files": "", "project_flagged_too_many_compiles": "", @@ -1777,6 +1778,7 @@ "tried_to_register_with_email": "", "troubleshooting_tip": "", "try_again": "", + "try_for_free": "", "try_it_for_free": "", "try_now": "", "try_premium_for_free": "", diff --git a/services/web/frontend/fonts/material-symbols/MaterialSymbolsRoundedUnfilledPartialSlice.woff2 b/services/web/frontend/fonts/material-symbols/MaterialSymbolsRoundedUnfilledPartialSlice.woff2 index fb158e5ea1ae7ea123f89aa8e94b14e21a53828d..549c7c10aba7ad78a1a77db9da15ea01571a5a46 100644 GIT binary patch literal 3704 zcmV-;4u|n~Pew8T0RR9101kKn4gdfE032)p01hAk0RR9100000000000000000000 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 Wi+ukpmT`-f?xwwyp&GrBJqrM$#QX{X literal 3860 zcmV+v59{!EPew8T0RR9101p%Z4gdfE03KKX01mnU0RR9100000000000000000000 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 Wg8vA+TxZ#1Js&0002y7H8Z5 diff --git a/services/web/frontend/fonts/material-symbols/unfilled-symbols.mjs b/services/web/frontend/fonts/material-symbols/unfilled-symbols.mjs index 1c551ebdbd..c727e77cf0 100644 --- a/services/web/frontend/fonts/material-symbols/unfilled-symbols.mjs +++ b/services/web/frontend/fonts/material-symbols/unfilled-symbols.mjs @@ -21,4 +21,5 @@ export default /** @type {const} */ ([ 'table_chart', 'upload_file', 'web_asset', + 'error', ]) diff --git a/services/web/frontend/js/features/pdf-preview/components/timeout-message-after-paywall-dismissal.tsx b/services/web/frontend/js/features/pdf-preview/components/timeout-message-after-paywall-dismissal.tsx new file mode 100644 index 0000000000..07ba254b55 --- /dev/null +++ b/services/web/frontend/js/features/pdf-preview/components/timeout-message-after-paywall-dismissal.tsx @@ -0,0 +1,196 @@ +import getMeta from '@/utils/meta' +import { Trans, useTranslation } from 'react-i18next' +import { memo, useCallback } from 'react' +import { useDetachCompileContext } from '@/shared/context/detach-compile-context' +import StartFreeTrialButton from '@/shared/components/start-free-trial-button' +import { useFeatureFlag } from '@/shared/context/split-test-context' +import MaterialIcon from '@/shared/components/material-icon' +import OLButton from '@/features/ui/components/ol/ol-button' +import { useStopOnFirstError } from '@/shared/hooks/use-stop-on-first-error' +import PdfLogEntry from './pdf-log-entry' + +function TimeoutMessageAfterPaywallDismissal() { + const { + startCompile, + lastCompileOptions, + setAnimateCompileDropdownArrow, + isProjectOwner, + } = useDetachCompileContext() + + const { enableStopOnFirstError } = useStopOnFirstError({ + eventSource: 'timeout-new', + }) + + const handleEnableStopOnFirstErrorClick = useCallback(() => { + enableStopOnFirstError() + startCompile({ stopOnFirstError: true }) + setAnimateCompileDropdownArrow(true) + }, [enableStopOnFirstError, startCompile, setAnimateCompileDropdownArrow]) + + return ( +
+ + {getMeta('ol-ExposedSettings').enableSubscriptions && ( + + )} +
+ ) +} + +type CompileTimeoutProps = { + isProjectOwner: boolean +} + +const CompileTimeout = memo(function CompileTimeout({ + isProjectOwner, +}: CompileTimeoutProps) { + const { t } = useTranslation() + + const hasNewPaywallCta = useFeatureFlag('paywall-cta') + + return ( + + } + formattedContent={ + getMeta('ol-ExposedSettings').enableSubscriptions && ( + <> +

+ {isProjectOwner + ? t('your_project_exceeded_compile_timeout_limit_on_free_plan') + : t('this_project_exceeded_compile_timeout_limit_on_free_plan')} +

+ + {isProjectOwner === false && ( + , + ]} + /> + )} + + {isProjectOwner && ( +
+ + {hasNewPaywallCta + ? t('get_more_compile_time') + : t('try_for_free')} + +
+ )} + + ) + } + // @ts-ignore + entryAriaLabel={t('your_compile_timed_out')} + level="error" + /> + ) +}) + +type PreventTimeoutHelpMessageProps = { + lastCompileOptions: any + handleEnableStopOnFirstErrorClick: () => void + isProjectOwner: boolean +} + +const PreventTimeoutHelpMessage = memo(function PreventTimeoutHelpMessage({ + lastCompileOptions, + handleEnableStopOnFirstErrorClick, + isProjectOwner, +}: PreventTimeoutHelpMessageProps) { + const { t } = useTranslation() + + return ( + +

{t('common_causes_of_compile_timeouts_include')}:

+
    +
  • + , + ]} + /> +
  • +
  • + , + ]} + /> + {!lastCompileOptions.stopOnFirstError && ( + <> + {' '} + , + // eslint-disable-next-line react/jsx-key + , + ]} + />{' '} + + )} +
  • +
+

+ , + ]} + /> +

+ + } + // @ts-ignore + entryAriaLabel={t('reasons_for_compile_timeouts')} + level="raw" + /> + ) +}) + +export default memo(TimeoutMessageAfterPaywallDismissal) diff --git a/services/web/frontend/js/features/pdf-preview/components/timeout-upgrade-paywall-prompt.tsx b/services/web/frontend/js/features/pdf-preview/components/timeout-upgrade-paywall-prompt.tsx index c89e9e2f3b..2a56a76774 100644 --- a/services/web/frontend/js/features/pdf-preview/components/timeout-upgrade-paywall-prompt.tsx +++ b/services/web/frontend/js/features/pdf-preview/components/timeout-upgrade-paywall-prompt.tsx @@ -1,5 +1,6 @@ import getMeta from '@/utils/meta' import { useMemo } from 'react' +import TimeoutMessageAfterPaywallDismissal from './timeout-message-after-paywall-dismissal' const studentRoles = [ 'High-school student', @@ -8,14 +9,15 @@ const studentRoles = [ 'Doctoral student (e.g. PhD, MD, EngD)', ] +// We can display TimeoutMessageAfterPaywallDismissal after the user has dismissed the paywall. That logic can be implemented in this file or somewhere else? function TimeoutUpgradePaywallPrompt() { const odcRole = getMeta('ol-odcRole') const isStudent = useMemo(() => studentRoles.includes(odcRole), [odcRole]) return (
-

Hello world from new paywall component

Current user is {!isStudent && 'not'} a student.

+
) } diff --git a/services/web/frontend/stylesheets/bootstrap-5/pages/editor/logs.scss b/services/web/frontend/stylesheets/bootstrap-5/pages/editor/logs.scss index 7f792ffe2d..e296a19658 100644 --- a/services/web/frontend/stylesheets/bootstrap-5/pages/editor/logs.scss +++ b/services/web/frontend/stylesheets/bootstrap-5/pages/editor/logs.scss @@ -209,3 +209,58 @@ text-align: left; } } + +// As part of compile time paywall redesign, we are only migrating the necessary classes needed for the split test +// Other classes should be migrated too as a part of website redesign project later on. + +.timeout-upgrade-paywall-prompt { + display: flex; + flex-direction: column; + gap: 10px; // adding this value to match existing spacing in logs pane, there is no variable for 10px +} + +.website-redesign { + .log-entry-header { + @include heading-sm; + + font-weight: 600; + padding: var(--spacing-05) var(--spacing-06); + } + + .log-entry-content { + padding: 0; + } + + .log-entry-formatted-content { + @include body-sm; + + padding: var(--spacing-06); + color: var(--neutral-70); + + a, + .btn-inline-link { + color: var(--blue-50); + } + } + + .log-entry-cta-container { + padding-top: var(--spacing-06); + display: flex; + justify-content: flex-end; + } + + .log-entry-header-error { + background-color: var(--red-10); + + .log-entry-header-title { + @include heading-sm; + + color: var(--red-50); + } + } + + .log-entry-header-raw { + background-color: var(--neutral-60); + padding: var(--spacing-04) var(--spacing-06); + } +} diff --git a/services/web/locales/en.json b/services/web/locales/en.json index cb6de95b04..e1471471d2 100644 --- a/services/web/locales/en.json +++ b/services/web/locales/en.json @@ -1617,6 +1617,7 @@ "progress_bar_percentage": "Progress bar from 0 to 100%", "project": "project", "project_approaching_file_limit": "This project is approaching the file limit", + "project_failed_to_compile": "Your project failed to compile", "project_figure_modal": "Project", "project_files": "Project files", "project_flagged_too_many_compiles": "This project has been flagged for compiling too often. The limit will be lifted shortly.",