Просмотр исходного кода

Merge pull request #19317 from overleaf/jdt-fake-foor-test

AI error assistant fake door test

GitOrigin-RevId: 9ba5480a50d9881fa0ce2f3632f94ffe57d7a152
Jimmy Domagala-Tang 2 лет назад
Родитель
Сommit
ffad592f8d

+ 6 - 0
services/web/app/src/Features/Project/ProjectListController.js

@@ -433,6 +433,12 @@ async function projectListPage(req, res, next) {
     'bootstrap-5-project-dashboard'
   )
 
+  await SplitTestHandler.promises.getAssignment(
+    req,
+    res,
+    'ai-fake-door-offering-test'
+  )
+
   res.render('project/list-react', {
     title: 'your_projects',
     usersBestSubscription,

+ 1 - 0
services/web/config/settings.defaults.js

@@ -892,6 +892,7 @@ module.exports = {
     editorLeftMenuManageTemplate: [],
     oauth2Server: [],
     managedGroupSubscriptionEnrollmentNotification: [],
+    userNotifications: [],
     managedGroupEnrollmentInvite: [],
     ssoCertificateInfo: [],
   },

+ 0 - 66
services/web/frontend/js/features/project-list/components/notifications/labs-ai-promo-banner.tsx

@@ -1,66 +0,0 @@
-import { memo, useCallback, useState } from 'react'
-import Notification from './notification'
-import customLocalStorage from '@/infrastructure/local-storage'
-import OLButton from '@/features/ui/components/ol/ol-button'
-import getMeta from '@/utils/meta'
-import * as eventTracking from '../../../../infrastructure/event-tracking'
-import { useTranslation } from 'react-i18next'
-
-function LabsAiPromoBanner() {
-  const user = getMeta('ol-user')
-  const cannotUseAi = getMeta('ol-cannot-use-ai')
-  const { t } = useTranslation()
-
-  const [show, setShow] = useState(() => {
-    const dismissed = customLocalStorage.getItem(
-      'has_dismissed_labs_ai_promo_banner'
-    )
-    if (dismissed || cannotUseAi) {
-      return false
-    }
-
-    const show = user?.labsProgram === true && !user?.features?.aiErrorAssistant
-    return show
-  })
-
-  const handleClose = useCallback(() => {
-    eventTracking.sendMB('promo-dismiss', {
-      name: 'labs-ai-experiment-promo',
-    })
-    customLocalStorage.setItem('has_dismissed_labs_ai_promo_banner', true)
-    setShow(false)
-  }, [setShow])
-
-  const handleClick = useCallback(() => {
-    eventTracking.sendMB('promo-click', {
-      name: 'labs-ai-experiment-promo',
-      content: 'try-now',
-    })
-    customLocalStorage.setItem('has_dismissed_labs_ai_promo_banner', true)
-  }, [])
-
-  if (!show) {
-    return null
-  }
-
-  return (
-    <div>
-      <Notification
-        type="info"
-        onDismiss={handleClose}
-        content={<span>{t('get_early_access_to_ai')}</span>}
-        action={
-          <OLButton
-            variant="secondary"
-            href="/labs/participate"
-            onClick={handleClick}
-          >
-            {t('try_now')}
-          </OLButton>
-        }
-      />
-    </div>
-  )
-}
-
-export default memo(LabsAiPromoBanner)

+ 12 - 3
services/web/frontend/js/features/project-list/components/notifications/user-notifications.tsx

@@ -1,4 +1,4 @@
-import { JSXElementConstructor, useState } from 'react'
+import { JSXElementConstructor, useState, ElementType } from 'react'
 import Common from './groups/common'
 import Institution from './groups/institution'
 import ConfirmEmail from './groups/confirm-email'
@@ -12,11 +12,16 @@ import customLocalStorage from '../../../../infrastructure/local-storage'
 import { sendMB } from '../../../../infrastructure/event-tracking'
 import GeoBanners from './geo-banners'
 import AccessibilitySurveyBanner from './accessibility-survey-banner'
-import LabsAiPromoBanner from './labs-ai-promo-banner'
 
 const [enrollmentNotificationModule] = importOverleafModules(
   'managedGroupSubscriptionEnrollmentNotification'
 )
+
+const moduleNotifications = importOverleafModules('userNotifications') as {
+  import: { default: ElementType }
+  path: string
+}[]
+
 const EnrollmentNotification: JSXElementConstructor<{
   groupId: string
   groupName: string
@@ -80,7 +85,11 @@ function UserNotifications() {
             setDismissedWritefull(true)
           }}
         />
-        <LabsAiPromoBanner />
+        {moduleNotifications.map(({ import: { default: Component }, path }) => (
+          <li key={path}>
+            <Component />
+          </li>
+        ))}
       </ul>
     </div>
   )

+ 5 - 0
services/web/frontend/stylesheets/modules/labs.less

@@ -76,3 +76,8 @@
     }
   }
 }
+
+.fake-door-container {
+  margin-top: 8em;
+  margin-bottom: 12em;
+}

+ 4 - 1
services/web/test/frontend/features/project-list/components/notifications.test.tsx

@@ -28,6 +28,7 @@ import ConfirmEmail from '../../../../../frontend/js/features/project-list/compo
 import ReconfirmationInfo from '../../../../../frontend/js/features/project-list/components/notifications/groups/affiliation/reconfirmation-info'
 import UserNotifications from '../../../../../frontend/js/features/project-list/components/notifications/user-notifications'
 import { ProjectListProvider } from '../../../../../frontend/js/features/project-list/context/project-list-context'
+import { SplitTestProvider } from '@/shared/context/split-test-context'
 import {
   Notification,
   Institution as InstitutionType,
@@ -50,7 +51,9 @@ const renderWithinProjectListProvider = (Component: React.ComponentType) => {
   render(<Component />, {
     wrapper: ({ children }) => (
       <ProjectListProvider>
-        <ul className="list-unstyled">{children}</ul>
+        <SplitTestProvider>
+          <ul className="list-unstyled">{children}</ul>
+        </SplitTestProvider>
       </ProjectListProvider>
     ),
   })

+ 1 - 0
services/web/types/assets.d.ts

@@ -1 +1,2 @@
 declare module '*.svg'
+declare module '*.png'