Kaynağa Gözat

Merge pull request #19150 from overleaf/jdt-ai-promo

feat: add labs ai experiment promo
GitOrigin-RevId: 9bf039635b487339caa277b501a8cd99c7c7613f
Jimmy Domagala-Tang 2 yıl önce
ebeveyn
işleme
c0f39267a9

+ 2 - 1
services/web/app/src/Features/Project/ProjectListController.js

@@ -117,7 +117,7 @@ async function projectListPage(req, res, next) {
   })
   const user = await User.findById(
     userId,
-    `email emails features alphaProgram betaProgram lastPrimaryEmailCheck signUpDate${
+    `email emails features alphaProgram betaProgram lastPrimaryEmailCheck labsProgram signUpDate${
       isSaas ? ' enrollment writefull' : ''
     }`
   )
@@ -462,6 +462,7 @@ async function projectListPage(req, res, next) {
         groupName: subscription.teamName,
       })),
     hasIndividualRecurlySubscription,
+    userRestrictions: Array.from(req.userRestrictions || []),
   })
 }
 

+ 1 - 0
services/web/app/src/router.js

@@ -483,6 +483,7 @@ function initialize(webRouter, privateApiRouter, publicApiRouter) {
     '/project',
     AuthenticationController.requireLogin(),
     RateLimiterMiddleware.rateLimit(rateLimiters.openDashboard),
+    PermissionsController.useCapabilities(),
     ProjectListController.projectListPage
   )
   webRouter.post(

+ 1 - 0
services/web/frontend/extracted-translations.json

@@ -468,6 +468,7 @@
   "get_collaborative_benefits": "",
   "get_discounted_plan": "",
   "get_dropbox_sync": "",
+  "get_early_access_to_ai": "",
   "get_exclusive_access_to_labs": "",
   "get_full_project_history": "",
   "get_git_integration": "",

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

@@ -0,0 +1,66 @@
+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)

+ 2 - 0
services/web/frontend/js/features/project-list/components/notifications/user-notifications.tsx

@@ -12,6 +12,7 @@ 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'
@@ -79,6 +80,7 @@ function UserNotifications() {
             setDismissedWritefull(true)
           }}
         />
+        <LabsAiPromoBanner />
       </ul>
     </div>
   )

+ 1 - 0
services/web/locales/en.json

@@ -702,6 +702,7 @@
   "get_collaborative_benefits": "Get the collaborative benefits from __appName__, even if you prefer to work offline",
   "get_discounted_plan": "Get discounted plan",
   "get_dropbox_sync": "Get Dropbox Sync",
+  "get_early_access_to_ai": "Get early access to the new AI Error Assistant in Overleaf Labs",
   "get_exclusive_access_to_labs": "Get exclusive access to early-stage experiments when you join Overleaf Labs. All we ask in return is your honest feedback to help us develop and improve.",
   "get_full_project_history": "Get full project history",
   "get_git_integration": "Get Git integration",