+
+
+
+ {t('learn_more')}
+
+
+ {t('ok')}
+
+
+ >
+ )
+}
diff --git a/services/web/frontend/js/features/share-project-modal/components/restricted-link-sharing/editor-over-limit-modal.tsx b/services/web/frontend/js/features/share-project-modal/components/restricted-link-sharing/editor-over-limit-modal.tsx
new file mode 100644
index 0000000000..c76f2ed290
--- /dev/null
+++ b/services/web/frontend/js/features/share-project-modal/components/restricted-link-sharing/editor-over-limit-modal.tsx
@@ -0,0 +1,65 @@
+import { useEffect, useState } from 'react'
+import AccessibleModal from '@/shared/components/accessible-modal'
+import EditorOverLimitModalContent from './editor-over-limit-modal-content'
+import customLocalStorage from '@/infrastructure/local-storage'
+import { useProjectContext } from '@/shared/context/project-context'
+import { useEditorContext } from '@/shared/context/editor-context'
+
+const EditorOverLimitModal = () => {
+ const [show, setShow] = useState(false)
+
+ const { isProjectOwner, permissionsLevel } = useEditorContext()
+ const { members, features, _id: projectId } = useProjectContext()
+
+ const handleHide = () => {
+ setShow(false)
+ }
+
+ // split test: link-sharing-warning
+ // show the over-limit warning if user
+ // is editor on a project over
+ // collaborator limit (once every 24 hours)
+ useEffect(() => {
+ const showModalCooldownHours = 24
+ const hasExceededCollaboratorLimit = () => {
+ if (isProjectOwner || !features || permissionsLevel === 'readOnly') {
+ return false
+ }
+
+ if (features.collaborators === -1) {
+ return false
+ }
+ return (
+ members.filter(member => member.privileges === 'readAndWrite').length >
+ (features.collaborators ?? 1)
+ )
+ }
+
+ if (hasExceededCollaboratorLimit()) {
+ const localStorageKey = `last-shown-need-edit-modal.${projectId}`
+ const lastShownNeedEditModalTime =
+ customLocalStorage.getItem(localStorageKey)
+ if (
+ !lastShownNeedEditModalTime ||
+ lastShownNeedEditModalTime + showModalCooldownHours * 60 * 60 * 1000 <
+ Date.now()
+ ) {
+ setShow(true)
+ customLocalStorage.setItem(localStorageKey, Date.now())
+ }
+ }
+ }, [features, isProjectOwner, members, permissionsLevel, projectId])
+
+ return show ? (
+
+
+
+ ) : null
+}
+
+export default EditorOverLimitModal
diff --git a/services/web/frontend/js/features/share-project-modal/utils/link-sharing.ts b/services/web/frontend/js/features/share-project-modal/utils/link-sharing.ts
new file mode 100644
index 0000000000..62368a24ff
--- /dev/null
+++ b/services/web/frontend/js/features/share-project-modal/utils/link-sharing.ts
@@ -0,0 +1,6 @@
+import { formatDate } from '@/utils/dates'
+
+export const linkSharingEnforcementDate = formatDate(
+ new Date(2024, 6, 29),
+ 'MMMM Do'
+) // July 29th 2024
diff --git a/services/web/locales/en.json b/services/web/locales/en.json
index 27f5ae8a0e..6e51592850 100644
--- a/services/web/locales/en.json
+++ b/services/web/locales/en.json
@@ -435,6 +435,7 @@
"display_deleted_user": "Display deleted users",
"do_not_have_acct_or_do_not_want_to_link": "If you don’t have an __appName__ account, or if you don’t want to link to your __institutionName__ account, please click __clickText__.",
"do_not_link_accounts": "Don’t link accounts",
+ "do_you_need_edit_access": "Do you need edit access?",
"do_you_want_to_change_your_primary_email_address_to": "Do you want to change your primary email address to __email__?",
"do_you_want_to_overwrite_it": "Do you want to overwrite it?",
"do_you_want_to_overwrite_it_plural": "Do you want to overwrite them?",
@@ -676,6 +677,7 @@
"free_plan_tooltip": "Click to find out how you could benefit from Overleaf premium features.",
"frequently_asked_questions": "frequently asked questions",
"from_another_project": "From another project",
+ "from_enforcement_date": "From __enforcementDate__ any additional editors on this project will be made viewers.",
"from_external_url": "From external URL",
"from_project_files": "From project files",
"from_provider": "From __provider__",
@@ -1040,7 +1042,8 @@
"license": "License",
"license_for_educational_purposes": "This license is for educational purposes (applies to students or faculty using __appName__ for teaching)",
"limited_offer": "Limited offer",
- "limited_to_n_editors_per_project": "Limited to n editors per project",
+ "limited_to_n_editors_per_project": "Limited to __count__ editor per project",
+ "limited_to_n_editors_per_project_plural": "Limited to __count__ editors per project",
"line_height": "Line Height",
"line_width_is_the_width_of_the_line_in_the_current_environment": "Line width is the width of the line in the current environment. e.g. a full page width in single-column layout or half a page width in a two-column layout.",
"link": "Link",
@@ -1987,6 +1990,7 @@
"this_is_a_labs_experiment": "This is a Labs experiment",
"this_is_your_template": "This is your template from your project",
"this_project_exceeded_compile_timeout_limit_on_free_plan": "This project exceeded the compile timeout limit on our free plan.",
+ "this_project_has_more_than_max_collabs": "This project has more than the maximum number of collaborators allowed on the project owner’s Overleaf plan. This means you could lose edit access from __linkSharingDate__.",
"this_project_is_public": "This project is public and can be edited by anyone with the URL.",
"this_project_is_public_read_only": "This project is public and can be viewed but not edited by anyone with the URL",
"this_project_will_appear_in_your_dropbox_folder_at": "This project will appear in your Dropbox folder at ",
@@ -2009,6 +2013,7 @@
"to_fix_this_you_can": "To fix this, you can:",
"to_fix_this_you_can_ask_the_github_repository_owner": "To fix this, you can ask the GitHub repository owner (<0>__repoOwnerEmail__0>) to renew their __appName__ subscription and reconnect the project.",
"to_insert_or_move_a_caption_make_sure_tabular_is_directly_within_table": "To insert or move a caption, make sure \\begin{tabular} is directly within a table environment",
+ "to_keep_edit_access": "To keep edit access, ask the project owner to upgrade their plan or reduce the number of people with edit access.",
"to_many_login_requests_2_mins": "This account has had too many login requests. Please wait 2 minutes before trying to log in again",
"to_modify_your_subscription_go_to": "To modify your subscription go to",
"to_use_text_wrapping_in_your_table_make_sure_you_include_the_array_package": "<0>Please note:0> To use text wrapping in your table, make sure you include the <1>array1> package in your document preamble:",
@@ -2297,7 +2302,8 @@
"you_can_also_choose_to_view_anonymously_or_leave_the_project": "You can also choose to <0>view anonymously0> (you will lose edit access) or <1>leave the project1>.",
"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 features0>.",
- "you_can_only_add_n_people_to_edit_a_project": "You can only add X people to edit a project with you on your current plan. Upgrade to add more.",
+ "you_can_only_add_n_people_to_edit_a_project": "You can only add __count__ person to edit a project with you on your current plan. Upgrade to add more.",
+ "you_can_only_add_n_people_to_edit_a_project_plural": "You can only add __count__ people to edit a project with you on your current plan. Upgrade to add more.",
"you_can_opt_in_and_out_of_the_program_at_any_time_on_this_page": "You can <0>opt in and out0> of the program at any time on this page",
"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 can’t add or change your password because your group or organization uses <0>single sign-on (SSO)0>.",
@@ -2339,7 +2345,8 @@
"your_password_was_detected": "Your password is on a <0>public list of known compromised passwords0>. Keep your account safe by changing your password now.",
"your_plan": "Your plan",
"your_plan_is_changing_at_term_end": "Your plan is changing to <0>__pendingPlanName__0> at the end of the current billing period.",
- "your_plan_is_limited_to_n_editors": "Your plan allows [n] collaborators with edit access and unlimited viewers. From [date] any additional editors on this project will be made viewers.",
+ "your_plan_is_limited_to_n_editors": "Your plan allows __count__ collaborator with edit access and unlimited viewers.",
+ "your_plan_is_limited_to_n_editors_plural": "Your plan allows __count__ collaborators with edit access and unlimited viewers.",
"your_project_exceeded_compile_timeout_limit_on_free_plan": "Your project exceeded the compile timeout limit on our free plan.",
"your_project_near_compile_timeout_limit": "Your project is near the compile timeout limit for our free plan.",
"your_projects": "Your Projects",