mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-05-23 17:19:37 +02:00
feat: add in-editor notification when rolling image has updated (#28529)
GitOrigin-RevId: 771773ba1914ef609b6ac84799bdda2d7ae4affa
This commit is contained in:
committed by
Copybot
parent
0200ad7515
commit
07166bff73
@@ -167,6 +167,7 @@ function getAllowedImagesForUser(user) {
|
||||
return {
|
||||
...image,
|
||||
allowed: _imageAllowed(user, image),
|
||||
rolling: image.monthlyExperimental,
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ const VALID_KEYS = [
|
||||
'ide-redesign-new-survey-promo',
|
||||
'ide-redesign-beta-intro',
|
||||
'ide-redesign-labs-user-beta-promo',
|
||||
'rolling-compile-image-changed',
|
||||
]
|
||||
|
||||
async function completeTutorial(req, res, next) {
|
||||
|
||||
@@ -1006,6 +1006,7 @@ module.exports = {
|
||||
v1ImportDataScreen: [],
|
||||
snapshotUtils: [],
|
||||
usGovBanner: [],
|
||||
rollingBuildsUpdatedAlert: [],
|
||||
offlineModeToolbarButtons: [],
|
||||
settingsEntries: [],
|
||||
autoCompleteExtensions: [],
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
"a_new_reference_was_added_from_provider": "",
|
||||
"a_new_reference_was_added_to_file": "",
|
||||
"a_new_reference_was_added_to_file_from_provider": "",
|
||||
"a_new_version_of_the_rolling_texlive_build_released": "",
|
||||
"about_to_archive_projects": "",
|
||||
"about_to_delete_cert": "",
|
||||
"about_to_delete_projects": "",
|
||||
@@ -1616,6 +1617,7 @@
|
||||
"showing_x_results_of_total": "",
|
||||
"sign_up": "",
|
||||
"simple_search_mode": "",
|
||||
"since_this_project_is_set_to_the_rolling_build": "",
|
||||
"single_sign_on_sso": "",
|
||||
"size": "",
|
||||
"something_not_right": "",
|
||||
|
||||
@@ -2,9 +2,16 @@ import { useTranslation } from 'react-i18next'
|
||||
import { LostConnectionAlert } from './lost-connection-alert'
|
||||
import { useConnectionContext } from '@/features/ide-react/context/connection-context'
|
||||
import { debugging } from '@/utils/debugging'
|
||||
import { ElementType } from 'react'
|
||||
import { createPortal } from 'react-dom'
|
||||
import { useGlobalAlertsContainer } from '@/features/ide-react/context/global-alerts-context'
|
||||
import OLNotification from '@/shared/components/ol/ol-notification'
|
||||
import importOverleafModules from '../../../../../macros/import-overleaf-module.macro'
|
||||
|
||||
const rollingBuildsUpdatedAlert: Array<{
|
||||
import: { default: ElementType }
|
||||
path: string
|
||||
}> = importOverleafModules('rollingBuildsUpdatedAlert')
|
||||
|
||||
export function Alerts() {
|
||||
const { t } = useTranslation()
|
||||
@@ -23,6 +30,12 @@ export function Alerts() {
|
||||
|
||||
return createPortal(
|
||||
<>
|
||||
{rollingBuildsUpdatedAlert.map(
|
||||
({ import: { default: Component }, path }) => (
|
||||
<Component key={path} />
|
||||
)
|
||||
)}
|
||||
|
||||
{connectionState.forceDisconnected &&
|
||||
// hide "disconnected" banner when displaying out of sync modal
|
||||
connectionState.error !== 'out-of-sync' ? (
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
import { useState } from 'react'
|
||||
import { useCallback, useState } from 'react'
|
||||
import LabsExperimentWidget from '../../shared/components/labs/labs-experiments-widget'
|
||||
import { isInExperiment } from '@/utils/labs-utils'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import MaterialIcon from '@/shared/components/material-icon'
|
||||
import { isSplitTestEnabled } from '@/utils/splitTestUtils'
|
||||
import { postJSON } from '@/infrastructure/fetch-json'
|
||||
import { debugConsole } from '@/utils/debugging'
|
||||
|
||||
export const TUTORIAL_KEY = 'rolling-compile-image-changed'
|
||||
|
||||
const MonthlyTexliveLabsWidget = ({
|
||||
labsProgram,
|
||||
@@ -15,6 +19,18 @@ const MonthlyTexliveLabsWidget = ({
|
||||
const { t } = useTranslation()
|
||||
const [optedIn, setOptedIn] = useState(isInExperiment('monthly-texlive'))
|
||||
|
||||
const optInWithCompletedTutorial = useCallback(
|
||||
async (shouldOptIn: boolean) => {
|
||||
try {
|
||||
await postJSON(`/tutorial/${TUTORIAL_KEY}/complete`)
|
||||
} catch (err) {
|
||||
debugConsole.error(err)
|
||||
}
|
||||
setOptedIn(shouldOptIn)
|
||||
},
|
||||
[setOptedIn]
|
||||
)
|
||||
|
||||
const monthlyTexLiveSplitTestEnabled = isSplitTestEnabled('monthly-texlive')
|
||||
if (!monthlyTexLiveSplitTestEnabled) {
|
||||
return null
|
||||
@@ -35,7 +51,7 @@ const MonthlyTexliveLabsWidget = ({
|
||||
labsEnabled={labsProgram}
|
||||
setErrorMessage={setErrorMessage}
|
||||
optedIn={optedIn}
|
||||
setOptedIn={setOptedIn}
|
||||
setOptedIn={optInWithCompletedTutorial}
|
||||
title={t('rolling_texlive_build')}
|
||||
/>
|
||||
)
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
import { useTutorial } from '@/shared/hooks/promotions/use-tutorial'
|
||||
|
||||
import { useEditorContext } from '@/shared/context/editor-context'
|
||||
import { useProjectSettingsContext } from '../editor-left-menu/context/project-settings-context'
|
||||
|
||||
import OLNotification from '@/shared/components/ol/ol-notification'
|
||||
import getMeta from '@/utils/meta'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useCallback } from 'react'
|
||||
|
||||
export const TUTORIAL_KEY = 'rolling-compile-image-changed'
|
||||
const rollingImages = getMeta('ol-imageNames')
|
||||
.filter(img => img.rolling)
|
||||
.map(img => img.imageName)
|
||||
|
||||
const RollingCompileImageChangedAlert = () => {
|
||||
const { completeTutorial } = useTutorial(TUTORIAL_KEY)
|
||||
|
||||
const { inactiveTutorials } = useEditorContext()
|
||||
const { imageName } = useProjectSettingsContext()
|
||||
const { t } = useTranslation()
|
||||
|
||||
const onClose = useCallback(() => {
|
||||
completeTutorial({ event: 'promo-click', action: 'complete' })
|
||||
}, [completeTutorial])
|
||||
|
||||
const onRollingBuild = imageName && rollingImages.includes(imageName)
|
||||
if (inactiveTutorials.includes(TUTORIAL_KEY) || !onRollingBuild) {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<OLNotification
|
||||
className="mt-5"
|
||||
isDismissible
|
||||
onDismiss={onClose}
|
||||
content={t('since_this_project_is_set_to_the_rolling_build')}
|
||||
type="info"
|
||||
title={t('a_new_version_of_the_rolling_texlive_build_released')}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
export default RollingCompileImageChangedAlert
|
||||
@@ -22,6 +22,7 @@
|
||||
"a_new_reference_was_added_from_provider": "A new reference was added from __provider__",
|
||||
"a_new_reference_was_added_to_file": "A new reference was added to <0>__filePath__</0>",
|
||||
"a_new_reference_was_added_to_file_from_provider": "A new reference was added to <0>__filePath__</0> from __provider__",
|
||||
"a_new_version_of_the_rolling_texlive_build_released": "A new version of the Rolling TeX Live build has been released.",
|
||||
"about": "About",
|
||||
"about_to_archive_projects": "You are about to archive the following projects:",
|
||||
"about_to_delete_cert": "You are about to delete the following certificate:",
|
||||
@@ -1936,7 +1937,6 @@
|
||||
"right": "Right",
|
||||
"ro": "Romanian",
|
||||
"role": "Role",
|
||||
"rolling_texlive_build": "Rolling TexLive Build",
|
||||
"ru": "Russian",
|
||||
"saml": "SAML",
|
||||
"saml_auth_error": "Sorry, your identity provider responded with an error. Please contact your administrator for more information.",
|
||||
@@ -2087,6 +2087,7 @@
|
||||
"sign_up_for_free": "Sign up for free",
|
||||
"sign_up_for_free_account": "Sign up for a free account and receive regular updates",
|
||||
"simple_search_mode": "Simple search",
|
||||
"since_this_project_is_set_to_the_rolling_build": "Since this project is set to use the rolling build, new compiles will automatically use the newest version.",
|
||||
"single_sign_on_sso": "Single Sign-On (SSO)",
|
||||
"site_description": "An online LaTeX editor that’s easy to use. No installation, real-time collaboration, version control, hundreds of LaTeX templates, and more.",
|
||||
"site_wide_option_available": "Site-wide option available",
|
||||
@@ -2291,7 +2292,6 @@
|
||||
"test": "Test",
|
||||
"test_configuration": "Test configuration",
|
||||
"test_configuration_successful": "Test configuration successful",
|
||||
"test_more_recent_versions_of_texlive": "Test more recent versions of TexLive before they get turned into our annual release. This experiment adds the compiler option for a monthly build of the current TexLive version. This experimental version is primarily for testing changes to TexLive, packages, and previewing new accessibility features before they’re compiled into our annual TexLive release. Note that these images change month to month, and are untested by our team. Important projects should continue to be built on our yearly release to avoid issues that may occur when the monthly build changes.",
|
||||
"tex_live_version": "TeX Live version",
|
||||
"texgpt": "TeXGPT",
|
||||
"text": "Text",
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
import { scriptRunner } from './lib/ScriptRunner.mjs'
|
||||
import { db } from '../app/src/infrastructure/mongodb.js'
|
||||
import minimist from 'minimist'
|
||||
const argv = minimist(process.argv.slice(2))
|
||||
|
||||
async function resetTutorials() {
|
||||
const commit = argv.commit !== undefined
|
||||
|
||||
const users = await db.users
|
||||
.find(
|
||||
{
|
||||
'completedTutorials.rolling-compile-image-changed.state': 'completed',
|
||||
},
|
||||
{ readPreference: 'secondaryPreferred' }
|
||||
)
|
||||
.toArray()
|
||||
|
||||
if (!commit) {
|
||||
console.log(
|
||||
`would have removed rolling-compile-image-changed tutorial for ${users.length} users`
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
await db.users.updateMany(
|
||||
{ _id: { $in: users.map(user => user._id) } },
|
||||
{
|
||||
$unset: { 'completedTutorials.rolling-compile-image-changed': '' },
|
||||
}
|
||||
)
|
||||
console.log(`updated ${users.length} users`)
|
||||
}
|
||||
|
||||
try {
|
||||
await scriptRunner(resetTutorials)
|
||||
process.exit(0)
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
process.exit(1)
|
||||
}
|
||||
@@ -5,6 +5,7 @@ export type ImageName = {
|
||||
imageDesc: string
|
||||
imageName: string
|
||||
allowed: boolean
|
||||
rolling?: boolean
|
||||
}
|
||||
|
||||
export type DocId = Brand<string, 'DocId'>
|
||||
|
||||
Reference in New Issue
Block a user