Merge pull request #18682 from overleaf/jdt-ai-labs

Re-Release Labs Page for AI Error-Correction

GitOrigin-RevId: 2eef85dd3b5f86bedcf3339559a5fbbae2d4da87
This commit is contained in:
Jimmy Domagala-Tang 2024-06-20 12:59:19 -04:00 committed by Copybot
parent ac7916fb29
commit e5aa917f54
13 changed files with 302 additions and 47 deletions

View file

@ -23,6 +23,8 @@ function make(listName, listId) {
subscribe: callbackify(provider.subscribe),
unsubscribe: callbackify(provider.unsubscribe),
changeEmail: callbackify(provider.changeEmail),
tag: callbackify(provider.tag),
removeTag: callbackify(provider.removeTag),
promises: provider,
}
}
@ -266,6 +268,8 @@ function makeNullProvider(listName) {
subscribe,
unsubscribe,
changeEmail,
tag,
removeTag,
}
async function subscribed(user) {
@ -296,4 +300,16 @@ function makeNullProvider(listName) {
'Not changing email in newsletter for user because no newsletter provider is configured'
)
}
async function tag(user, tag) {
logger.debug(
{ userId: user._id, tag, listName },
'Not tagging user because no newsletter provider is configured'
)
}
async function removeTag(user, tag) {
logger.debug(
{ userId: user._id, tag, listName },
'Not removing tag for user because no newsletter provider is configured'
)
}
}

View file

@ -602,6 +602,11 @@ const _ProjectController = {
!showPersonalAccessToken &&
splitTestAssignments['personal-access-token'].variant === 'enabled' // `?personal-access-token=enabled`
const showAiErrorAssistant =
userId &&
(!Features.hasFeature('saas') ||
(user.features && user.features.aiErrorAssistant))
const template =
detachRole === 'detached'
? 'project/ide-react-detached'
@ -670,7 +675,7 @@ const _ProjectController = {
debugPdfDetach,
showSymbolPalette,
symbolPaletteAvailable: Features.hasFeature('symbol-palette'),
showAiErrorAssistant: user.alphaProgram, // TODO: labs experiment
showAiErrorAssistant,
detachRole,
metadata: { viewport: false },
showUpgradePrompt,

View file

@ -126,6 +126,10 @@ const UserSchema = new Schema(
type: Boolean,
default: Settings.defaultFeatures.symbolPalette,
},
// labs feature, which shouldnt have a default as we havent decided pricing model yet
aiErrorAssistant: {
type: Boolean,
},
},
featuresOverrides: [
{
@ -138,6 +142,7 @@ const UserSchema = new Schema(
expiresAt: { type: Date },
note: { type: String },
features: {
aiErrorAssistant: { type: Boolean },
collaborators: { type: Number },
versioning: { type: Boolean },
dropbox: { type: Boolean },

View file

@ -882,6 +882,7 @@ module.exports = {
sourceEditorToolbarComponents: [],
editorPromotions: [],
langFeedbackLinkingWidgets: [],
labsExperiments: [],
integrationLinkingWidgets: [],
referenceLinkingWidgets: [],
importProjectFromGithubModalWrapper: [],

View file

@ -80,6 +80,7 @@
"all_premium_features_including": "",
"all_projects": "",
"all_projects_will_be_transferred_immediately": "",
"all_these_experiments_are_available_exclusively": "",
"already_subscribed_try_refreshing_the_page": "",
"also": "",
"an_email_has_already_been_sent_to": "",
@ -174,6 +175,7 @@
"checking_project_github_status": "",
"choose_a_custom_color": "",
"choose_from_group_members": "",
"choose_which_experiments": "",
"clear_cached_files": "",
"clear_search": "",
"click_here_to_view_sl_in_lng": "",
@ -380,6 +382,7 @@
"enable_single_sign_on": "",
"enable_sso": "",
"enable_stop_on_first_error_under_recompile_dropdown_menu": "",
"enabled": "",
"enabling": "",
"end_of_document": "",
"enter_6_digit_code": "",
@ -458,12 +461,14 @@
"get_collaborative_benefits": "",
"get_discounted_plan": "",
"get_dropbox_sync": "",
"get_exclusive_access_to_labs": "",
"get_full_project_history": "",
"get_git_integration": "",
"get_github_sync": "",
"get_in_touch": "",
"get_more_compile_time": "",
"get_most_subscription_by_checking_features": "",
"get_some_texnical_assistance": "",
"get_symbol_palette": "",
"get_track_changes": "",
"git": "",
@ -651,6 +656,7 @@
"is_email_affiliated": "",
"issued_on": "",
"join_now": "",
"join_overleaf_labs": "",
"join_project": "",
"join_team_explanation": "",
"joined_team": "",
@ -662,9 +668,6 @@
"keybindings": "",
"labels_help_you_to_easily_reference_your_figures": "",
"labels_help_you_to_reference_your_tables": "",
"labs_program_already_participating": "",
"labs_program_benefits": "",
"labs_program_not_participating": "",
"language_feedback": "",
"large_or_high-resolution_images_taking_too_long": "",
"last_active": "",
@ -755,7 +758,6 @@
"manage_group_settings_subtext_group_sso": "",
"manage_group_settings_subtext_managed_users": "",
"manage_institution_managers": "",
"manage_labs_program_membership": "",
"manage_managers_subtext": "",
"manage_members": "",
"manage_newsletter": "",
@ -1229,6 +1231,7 @@
"somthing_went_wrong_compiling": "",
"sorry_it_looks_like_that_didnt_work_this_time": "",
"sorry_the_connection_to_the_server_is_down": "",
"sorry_there_are_no_experiments": "",
"sorry_your_table_cant_be_displayed_at_the_moment": "",
"sort_by": "",
"sort_by_x": "",
@ -1556,6 +1559,7 @@
"view_hub_subtext": "",
"view_in_template_gallery": "",
"view_invitation": "",
"view_labs_experiments": "",
"view_less": "",
"view_logs": "",
"view_metrics": "",
@ -1569,6 +1573,7 @@
"visual_editor": "",
"visual_editor_is_only_available_for_tex_files": "",
"want_change_to_apply_before_plan_end": "",
"we_are_unable_to_opt_you_into_this_experiment": "",
"we_cant_find_any_sections_or_subsections_in_this_file": "",
"we_do_not_share_personal_information": "",
"we_logged_you_in": "",
@ -1658,6 +1663,7 @@
"your_role": "",
"your_subscription": "",
"your_subscription_has_expired": "",
"youre_a_member_of_overleaf_labs": "",
"youre_about_to_disable_single_sign_on": "",
"youre_about_to_enable_single_sign_on": "",
"youre_about_to_enable_single_sign_on_sso_only": "",

View file

@ -1,25 +1,30 @@
import { Trans, useTranslation } from 'react-i18next'
import { useTranslation } from 'react-i18next'
import { useUserContext } from '../../../shared/context/user-context'
function LabsProgramSection() {
const { t } = useTranslation()
const { labsProgram } = useUserContext()
const { labsProgram, alphaProgram } = useUserContext()
// keeping alpha only as we test AI experiment in preparation for general labs release
if (!alphaProgram) {
return null
}
const labsStatusText = labsProgram
? t('youre_a_member_of_overleaf_labs')
: t('get_exclusive_access_to_labs')
const labsRedirectText = labsProgram
? t('view_labs_experiments')
: t('join_overleaf_labs')
return (
<>
<h3>{t('overleaf_labs')}</h3>
{labsProgram ? null : (
<p className="small">
{/* eslint-disable-next-line react/jsx-key */}
<Trans i18nKey="labs_program_benefits" components={[<span />]} />
</p>
)}
<p className="small">
{labsProgram
? t('labs_program_already_participating')
: t('labs_program_not_participating')}
</p>
<a href="/labs/participate">{t('manage_labs_program_membership')}</a>
<p className="small">{labsStatusText}</p>
<a href="/labs/participate">{labsRedirectText}</a>
<hr />
</>
)
}

View file

@ -80,7 +80,6 @@ function SettingsPageContent() {
{labsEnabled ? (
<>
<LabsProgramSection />
<hr />
</>
) : null}
<SessionsSection />

View file

@ -0,0 +1,127 @@
import { ReactNode, useCallback, useState } from 'react'
import { useTranslation } from 'react-i18next'
import Badge from '@/shared/components/badge'
import { postJSON } from '@/infrastructure/fetch-json'
import { Button } from 'react-bootstrap'
import getMeta from '@/utils/meta'
export type UserFeatures = {
[key: string]: boolean
}
type IntegrationLinkingWidgetProps = {
logo: ReactNode
title: string
description: string
helpPath?: string
labsEnabled?: boolean
experimentName: string
setErrorMessage: (message: string) => void
}
export function LabsExperimentWidget({
logo,
title,
description,
helpPath,
labsEnabled,
experimentName,
setErrorMessage,
}: IntegrationLinkingWidgetProps) {
const { t } = useTranslation()
const userFeatures = getMeta('ol-features') as UserFeatures
const [enabled, setEnabled] = useState(() => {
return userFeatures[experimentName] === true
})
const experimentsErrorMessage = t(
'we_are_unable_to_opt_you_into_this_experiment'
)
const handleEnable = useCallback(async () => {
try {
const enablePath = `/labs/participate/experiments/${experimentName}/opt-in`
await postJSON(enablePath)
setEnabled(true)
} catch (err) {
setErrorMessage(experimentsErrorMessage)
}
}, [experimentName, setErrorMessage, experimentsErrorMessage])
const handleDisable = useCallback(async () => {
try {
const disablePath = `/labs/participate/experiments/${experimentName}/opt-out`
await postJSON(disablePath)
setEnabled(false)
} catch (err) {
setErrorMessage(experimentsErrorMessage)
}
}, [experimentName, setErrorMessage, experimentsErrorMessage])
return (
<div className="labs-experiment-widget-container">
<div className="p-2">{logo}</div>
<div className="description-container">
<div className="title-row">
<h3 className="h4">{title}</h3>
{enabled && <Badge bsStyle="info">{t('enabled')}</Badge>}
</div>
<p className="small">
{description}{' '}
{helpPath && (
<a href={helpPath} target="_blank" rel="noreferrer">
{t('learn_more')}
</a>
)}
</p>
</div>
<div>
{labsEnabled && (
<ActionButton
enabled={enabled}
handleDisable={handleDisable}
handleEnable={handleEnable}
/>
)}
</div>
</div>
)
}
type ActionButtonProps = {
enabled?: boolean
handleEnable: () => void
handleDisable: () => void
}
function ActionButton({
enabled,
handleEnable,
handleDisable,
}: ActionButtonProps) {
const { t } = useTranslation()
if (enabled) {
return (
<Button
bsStyle="secondary"
onClick={handleDisable}
className="btn btn-secondary"
>
{t('turn_off')}
</Button>
)
} else {
return (
<Button
bsStyle="primary"
onClick={handleEnable}
className="btn btn-primary"
>
{t('turn_on')}
</Button>
)
}
}
export default LabsExperimentWidget

View file

@ -1,4 +1,4 @@
import { User } from '../../../types/user'
import { User, Features } from '../../../types/user'
import { User as MinimalUser } from '../../../types/admin/user'
import { User as ManagedUser } from '../../../types/group-management/user'
import { UserSettings } from '../../../types/user-settings'
@ -82,6 +82,7 @@ export interface Meta {
'ol-emailAddressLimit': number
'ol-error': { name: string } | undefined
'ol-expired': boolean
'ol-features': Features
'ol-fromPlansPage': boolean
'ol-gitBridgeEnabled': boolean
'ol-gitBridgePublicBaseUrl': string
@ -118,6 +119,7 @@ export interface Meta {
'ol-itm_campaign': string
'ol-itm_content': string
'ol-itm_referrer': string
'ol-labs': boolean
'ol-languages': SpellCheckLanguage[]
'ol-learnedWords': string[]
'ol-legacyEditorThemes': string[]

View file

@ -158,3 +158,4 @@
@import 'modules/overleaf-integration.less';
@import 'modules/writefull.less';
@import 'modules/third-party-references.less';
@import 'modules/labs.less';

View file

@ -0,0 +1,78 @@
.labs-opt-in-wrapper {
color: @ol-blue-gray-3;
h1,
h2,
h3,
h4 {
color: @ol-blue-gray-3;
}
#experiments-container {
.title-row {
display: flex;
}
.labs-experiment-widget-container {
border: 1px solid @gray-lighter;
}
}
.labs-icon {
background-color: @green-50;
color: @white;
border-radius: 20%;
vertical-align: text-bottom;
}
p {
font-size: @font-size-small;
}
strong {
font-size: @font-size-small;
}
.labs-experiment-widget-container {
display: grid;
grid-template-columns: 40px 1fr auto;
gap: 20px;
align-items: center;
padding: 10px;
> div {
display: flex;
flex-direction: column;
padding-right: 20px;
&:last-child {
padding-right: 0px;
}
}
img {
width: 36px;
height: 36px;
}
.title-row {
margin: 0;
margin-bottom: 10px;
> h3 {
margin: 0;
margin-right: 10px;
}
}
p {
margin-bottom: 10px;
&:last-child {
margin-bottom: 0;
}
}
}
@media (max-width: @screen-xs-max) {
.labs-experiment-widget-container {
grid-template-columns: 1fr;
}
}
}

View file

@ -190,6 +190,7 @@
"bulk_reject_confirm": "Are you sure you want to reject the selected __nChanges__ changes?",
"buy_now_no_exclamation_mark": "Buy now",
"by": "by",
"by_joining_labs": "By joining Labs, you agree to receive occasional emails and updates from Overleaf—for example, to request your feedback. You also agree to our <0>terms of service</0> and <1>privacy notice</1>.",
"by_registering_you_agree_to_our_terms_of_service": "By registering, you agree to our <0>terms of service</0> and <1>privacy notice</1>.",
"by_subscribing_you_agree_to_our_terms_of_service": "By subscribing, you agree to our <0>terms of service</0>.",
"can_edit": "Can Edit",
@ -248,6 +249,7 @@
"checking_project_github_status": "Checking project status in GitHub",
"choose_a_custom_color": "Choose a custom color",
"choose_from_group_members": "Choose from group members",
"choose_which_experiments": "Choose which experiments youd like to try.",
"choose_your_plan": "Choose your plan",
"city": "City",
"clear_cached_files": "Clear cached files",
@ -363,7 +365,6 @@
"credit_card": "Credit Card",
"cs": "Czech",
"currency": "Currency",
"current_experiments": "Current Experiments",
"current_file": "Current file",
"current_password": "Current Password",
"current_session": "Current Session",
@ -537,6 +538,7 @@
"enable_single_sign_on": "Enable single sign-on",
"enable_sso": "Enable SSO",
"enable_stop_on_first_error_under_recompile_dropdown_menu": "Enable <0>“Stop on first error”</0> under the <1>Recompile</1> drop-down menu to help you find and fix errors right away.",
"enabled": "Enabled",
"enabling": "Enabling",
"end_of_document": "End of document",
"enter_6_digit_code": "Enter 6-digit code",
@ -560,6 +562,7 @@
"example": "Example",
"example_project": "Example Project",
"examples": "Examples",
"exclusive_access_with_labs": "Exclusive access to early-stage experiments",
"existing_plan_active_until_term_end": "Your existing plan and its features will remain active until the end of the current billing period.",
"expand": "Expand",
"expired": "Expired",
@ -691,6 +694,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_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",
"get_github_sync": "Get GitHub Sync",
@ -699,6 +703,7 @@
"get_involved": "Get involved",
"get_more_compile_time": "Get more compile time",
"get_most_subscription_by_checking_features": "Get the most out of your __appName__ subscription by checking out <0>__appName__s features</0>.",
"get_some_texnical_assistance": "Get some TeXnical assistance from AI to fix errors in your project.",
"get_symbol_palette": "Get Symbol Palette",
"get_the_best_overleaf_experience": "Get the best Overleaf experience",
"get_the_best_writing_experience": "Get the best writing experience",
@ -953,7 +958,9 @@
"ja": "Japanese",
"january": "January",
"join_beta_program": "Join beta program",
"join_labs": "Join Labs",
"join_now": "Join now",
"join_overleaf_labs": "Join Overleaf Labs",
"join_project": "Join Project",
"join_sl_to_view_project": "Join __appName__ to view this project",
"join_team_explanation": "Please click the button below to join the group subscription and enjoy the benefits of an upgraded __appName__ account",
@ -973,10 +980,7 @@
"ko": "Korean",
"labels_help_you_to_easily_reference_your_figures": "Labels help you to easily reference your figures throughout your document. To reference a figure within the text, reference the label using the <0>\\ref{...}</0> command. This makes it easy to reference figures without needing to manually remember the figure numbering. <1>Learn more</1>",
"labels_help_you_to_reference_your_tables": "Labels help you to reference your tables throughout your document easily. To reference a table within the text, reference the label using the <0>\\ref{...}</0> command. This makes it easy to reference tables without manually remembering the table numbering. <1>Read about labels and cross-references</1>.",
"labs_program_already_participating": "You are enrolled in Labs",
"labs_program_badge_description": "While using __appName__, you will see Labs features marked with this badge:",
"labs_program_benefits": "__appName__ is always looking for new ways to help users work more quickly and effectively. By joining Overleaf Labs, you can participate in experiments that explore innovative ideas in the space of collaborative writing and publishing.",
"labs_program_not_participating": "You are not enrolled in Labs",
"labs_program_benefits": "By signing up for Overleaf Labs you can get your hands on in-development features and try them out as much as you like. All we ask in return is your honest feedback to help us develop and improve. Its important to note that features available in this program are still being tested and actively developed. This means they could change, be removed, or become part of a premium plan.",
"language": "Language",
"language_feedback": "Language Feedback",
"large_or_high-resolution_images_taking_too_long": "Large or high-resolution images taking too long to process. You may be able to <0>optimize them</0>.",
@ -1016,6 +1020,7 @@
"leave": "Leave",
"leave_any_group_subscriptions": "Leave any group subscriptions other than the one that will be managing your account. <0>Leave them from the Subscription page.</0>",
"leave_group": "Leave group",
"leave_labs": "Leave Overleaf Labs",
"leave_now": "Leave now",
"leave_projects": "Leave Projects",
"left": "Left",
@ -1113,7 +1118,6 @@
"manage_group_settings_subtext_group_sso": "Configure and manage SSO",
"manage_group_settings_subtext_managed_users": "Turn on Managed Users",
"manage_institution_managers": "Manage institution managers",
"manage_labs_program_membership": "Manage Labs Program Membership",
"manage_managers_subtext": "Assign or remove manager privileges",
"manage_members": "Manage members",
"manage_newsletter": "Manage Your Newsletter Preferences",
@ -1250,7 +1254,6 @@
"not_managed": "Not managed",
"not_now": "Not now",
"not_registered": "Not registered",
"note_experiments_under_development": "<0>Please note</0> that experiments in this program are still being tested and actively developed. This means that they might <0>change</0>, be <0>removed</0> or <0>become part of a paid plan</0>",
"note_features_under_development": "<0>Please note</0> that features in this program are still being tested and actively developed. This means that they might <0>change</0>, be <0>removed</0> or <0>become part of a premium plan</0>",
"notification_features_upgraded_by_affiliation": "Good news! Your affiliated organization __institutionName__ has an Overleaf subscription, and you now have access to all of Overleafs Professional features.",
"notification_ieee_collabratec_retirement_message": "As of April 2, 2024, free access to Overleaf Professional subscriptions via Collabratec or IEEE accounts has ended. Need to upgrade? <0>View our plans</0>. Contact <1>authors@ieee.org</1> with any questions.",
@ -1279,6 +1282,7 @@
"one_per_project": "1 per project",
"one_step_away_from_professional_features": "You are one step away from accessing <0>Overleaf Professional features</0>!",
"one_user": "1 user",
"ongoing_experiments": "Ongoing experiments",
"online_latex_editor": "Online LaTeX Editor",
"only_group_admin_or_managers_can_delete_your_account_1": "By becoming a managed user, your organization will have admin rights over your account and control over your stuff, including the right to close your account and access, delete and share your stuff. As a result:",
"only_group_admin_or_managers_can_delete_your_account_2": "Only your group admin or group managers will be able to delete your account.",
@ -1773,6 +1777,7 @@
"sorry_it_looks_like_that_didnt_work_this_time": "Sorry! It looks like that didnt work this time. Please try again.",
"sorry_something_went_wrong_opening_the_document_please_try_again": "Sorry, an unexpected error occurred when trying to open this content on Overleaf. Please try again.",
"sorry_the_connection_to_the_server_is_down": "Sorry, the connection to the server is down.",
"sorry_there_are_no_experiments": "Sorry, there are no experiments currently running in Overleaf Labs.",
"sorry_this_account_has_been_suspended": "Sorry, this account has been suspended.",
"sorry_your_table_cant_be_displayed_at_the_moment": "Sorry, your table cant be displayed at the moment.",
"sorry_your_token_expired": "Sorry, your token expired",
@ -1932,7 +1937,6 @@
"thank_you_email_confirmed": "Thank you, your email is now confirmed",
"thank_you_exclamation": "Thank you!",
"thank_you_for_being_part_of_our_beta_program": "Thank you for being part of our Beta Program, where you can have <0>early access to new features</0> and help us understand your needs better",
"thank_you_for_being_part_of_our_labs_program": "Thank you for being part of our Labs program, where you can have <0>early access to experimental features</0> and help us explore innovative ideas that help you work more quickly and effectively",
"thank_you_for_your_feedback": "Thank you for your feedback!",
"thanks": "Thanks",
"thanks_for_confirming_your_email_address": "Thanks for confirming your email address",
@ -2185,6 +2189,7 @@
"view_hub_subtext": "Access and download subscription statistics and a list of users",
"view_in_template_gallery": "View it in the template gallery",
"view_invitation": "View Invitation",
"view_labs_experiments": "View Labs Experiments",
"view_less": "View less",
"view_logs": "View logs",
"view_metrics": "View metrics",
@ -2199,6 +2204,7 @@
"visual_editor": "Visual Editor",
"visual_editor_is_only_available_for_tex_files": "Visual Editor is only available for TeX files",
"want_change_to_apply_before_plan_end": "If you wish this change to apply before the end of your current billing period, please contact us.",
"we_are_unable_to_opt_you_into_this_experiment": "We are unable to opt you into this experiment at this time, please ensure your organization has allowed this feature, or try again later.",
"we_cant_confirm_this_email": "We cant confirm this email",
"we_cant_find_any_sections_or_subsections_in_this_file": "We cant find any sections or subsections in this file",
"we_do_not_share_personal_information": "See our <0>Privacy Notice</0> for details of how we treat your personal data",
@ -2218,6 +2224,7 @@
"what_does_this_mean_for_you": "This means:",
"what_happens_when_sso_is_enabled": "What happens when SSO is enabled?",
"what_should_we_call_you": "What should we call you?",
"when_you_join_labs": "When you join Labs, you can choose which experiments you want to be part of. Once youve done that, you can use Overleaf as normal, but youll see any labs features marked with this badge:",
"when_you_tick_the_include_caption_box": "When you tick the box “Include caption” the image will be inserted into your document with a placeholder caption. To edit it, you simply select the placeholder text and type to replace it with your own.",
"why_latex": "Why LaTeX?",
"wide": "Wide",
@ -2270,9 +2277,7 @@
"you_are_on_x_plan_as_member_of_group_subscription_y_administered_by_z": "You are on our <0>__planName__</0> plan as a <1>member</1> of the group subscription <1>__groupName__</1> administered by <1>__adminEmail__</1>",
"you_can_now_enable_sso": "You can now enable SSO on your Group settings page.",
"you_can_now_log_in_sso": "You can now log in through your institution and if eligible you will receive <0>__appName__ Professional features</0>.",
"you_can_opt_in_and_out_of_overleaf_labs_at_any_time_on_this_page": "You can <0>opt in and out</0> of Overleaf Labs at any time on this page",
"you_can_opt_in_and_out_of_the_program_at_any_time_on_this_page": "You can <0>opt in and out</0> of the program at any time on this page",
"you_can_opt_in_to_individual_experiments": "You will be asked to opt in and out of individual experiments; each experiment may have unique partners, requirements, terms and conditions, etc. that must be opted in to for that specific experiment",
"you_can_request_a_maximum_of_limit_fixes_per_day": "You can request a maximum of __limit__ fixes per day. Please try again tomorrow.",
"you_cant_add_or_change_password_due_to_sso": "You cant add or change your password because your group or organization uses <0>single sign-on (SSO)</0>.",
"you_cant_join_this_group_subscription": "You cant join this group subscription",
@ -2320,12 +2325,14 @@
"your_sessions": "Your Sessions",
"your_subscription": "Your Subscription",
"your_subscription_has_expired": "Your subscription has expired.",
"youre_a_member_of_overleaf_labs": "Youre a member of Overleaf Labs. Dont forget to check in regularly to see what experiments you can sign up to.",
"youre_about_to_disable_single_sign_on": "Youre about to disable single sign-on for all group members.",
"youre_about_to_enable_single_sign_on": "Youre about to enable single sign-on (SSO). Before you do this, you should ensure youre confident the SSO configuration is correct and all your group members have managed user accounts.",
"youre_about_to_enable_single_sign_on_sso_only": "Youre about to enable single sign-on (SSO). Before you do this, you should ensure youre confident the SSO configuration is correct.",
"youre_already_setup_for_sso": "Youre already set up for SSO",
"youre_on_free_trial_which_ends_on": "Youre on a free trial which ends on <0>__date__</0>.",
"youre_signed_in_as_logout": "Youre signed in as <0>__email__</0>. <1>Log out.</1>",
"youre_signed_up": "Youre signed up",
"youve_unlinked_all_users": "Youve unlinked all users",
"zh-CN": "Chinese",
"zip_contents_too_large": "Zip contents too large",

View file

@ -7,6 +7,24 @@ export type RefProviders = {
export type UserId = Brand<string, 'UserId'>
export type Features = {
aiErrorAssistant?: boolean
collaborators?: number
compileGroup?: 'standard' | 'priority'
compileTimeout?: number
dropbox?: boolean
gitBridge?: boolean
github?: boolean
mendeley?: boolean
references?: boolean
referencesSearch?: boolean
symbolPalette?: boolean
templates?: boolean
trackChanges?: boolean
versioning?: boolean
zotero?: boolean
}
export type User = {
id: UserId
isAdmin?: boolean
@ -18,22 +36,7 @@ export type User = {
betaProgram?: boolean
labsProgram?: boolean
signUpDate?: string // date string
features?: {
collaborators?: number
compileGroup?: 'standard' | 'priority'
compileTimeout?: number
dropbox?: boolean
gitBridge?: boolean
github?: boolean
mendeley?: boolean
references?: boolean
referencesSearch?: boolean
symbolPalette?: boolean
templates?: boolean
trackChanges?: boolean
versioning?: boolean
zotero?: boolean
}
features?: Features
refProviders?: RefProviders
writefull?: {
enabled: boolean