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

Merge pull request #20080 from overleaf/rh-lost-edit-access-modal

[web] Show modal to pending editors

GitOrigin-RevId: 63dfed45a1483e835978dc7ac76cd0f37b4e1f50
roo hutton 1 год назад
Родитель
Сommit
db4d23d2df

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

@@ -1660,6 +1660,7 @@
   "view_metrics_commons_subtext": "",
   "view_metrics_group_subtext": "",
   "view_more": "",
+  "view_only_access": "",
   "view_only_downgraded": "",
   "view_options": "",
   "view_pdf": "",

+ 2 - 1
services/web/frontend/js/features/ide-react/components/editor-navigation-toolbar.tsx

@@ -6,7 +6,7 @@ import EditorNavigationToolbarRoot from '@/features/editor-navigation-toolbar/co
 import NewShareProjectModal from '@/features/share-project-modal/components/restricted-link-sharing/share-project-modal'
 import ShareProjectModal from '@/features/share-project-modal/components/share-project-modal'
 import EditorOverLimitModal from '@/features/share-project-modal/components/restricted-link-sharing/editor-over-limit-modal'
-
+import ViewOnlyAccessModal from '@/features/share-project-modal/components/restricted-link-sharing/view-only-access-modal'
 import getMeta from '@/utils/meta'
 
 function EditorNavigationToolbar() {
@@ -35,6 +35,7 @@ function EditorNavigationToolbar() {
       {showNewShareModal ? (
         <>
           <EditorOverLimitModal />
+          <ViewOnlyAccessModal />
           <NewShareProjectModal
             show={showShareModal}
             handleOpen={handleOpenShareModal}

+ 55 - 0
services/web/frontend/js/features/share-project-modal/components/restricted-link-sharing/view-only-access-modal-content.tsx

@@ -0,0 +1,55 @@
+import { Button, Modal } from 'react-bootstrap'
+import { useTranslation } from 'react-i18next'
+import { sendMB } from '@/infrastructure/event-tracking'
+
+type ViewOnlyAccessModalContentProps = {
+  handleHide: () => void
+}
+
+export default function ViewOnlyAccessModalContent({
+  handleHide,
+}: ViewOnlyAccessModalContentProps) {
+  const { t } = useTranslation()
+
+  return (
+    <>
+      <Modal.Header closeButton>
+        <Modal.Title>{t('view_only_access')}</Modal.Title>
+      </Modal.Header>
+
+      <Modal.Body>
+        <p>{t('this_project_already_has_maximum_editors')}</p>
+        <p>{t('please_ask_the_project_owner_to_upgrade_more_editors')}</p>
+      </Modal.Body>
+      <Modal.Footer>
+        <Button
+          bsStyle={null}
+          className="btn-secondary"
+          href="/blog/changes-to-project-sharing"
+          target="_blank"
+          rel="noreferrer"
+          onClick={() => {
+            sendMB('notification-click', {
+              name: 'link-sharing-collaborator-limit',
+              button: 'learn',
+            })
+          }}
+        >
+          {t('learn_more')}
+        </Button>
+        <Button
+          className="btn-primary"
+          onClick={() => {
+            sendMB('notification-click', {
+              name: 'link-sharing-collaborator-limit',
+              button: 'ok',
+            })
+            handleHide()
+          }}
+        >
+          {t('ok')}
+        </Button>
+      </Modal.Footer>
+    </>
+  )
+}

+ 79 - 0
services/web/frontend/js/features/share-project-modal/components/restricted-link-sharing/view-only-access-modal.tsx

@@ -0,0 +1,79 @@
+import { useEffect, useState } from 'react'
+import AccessibleModal from '@/shared/components/accessible-modal'
+import ViewOnlyAccessModalContent from './view-only-access-modal-content'
+import customLocalStorage from '@/infrastructure/local-storage'
+import { useProjectContext } from '@/shared/context/project-context'
+import { useEditorContext } from '@/shared/context/editor-context'
+import { sendMB } from '@/infrastructure/event-tracking'
+
+const ViewOnlyAccessModal = () => {
+  const [show, setShow] = useState(false)
+
+  const { isProjectOwner, isPendingEditor, permissionsLevel } =
+    useEditorContext()
+  const { members, features, _id: projectId } = useProjectContext()
+
+  const handleHide = () => {
+    setShow(false)
+  }
+
+  // split test: link-sharing-enforcement
+  // show the view-only access modal if
+  // is editor on a project over
+  // collaborator limit (once every week)
+  useEffect(() => {
+    const showModalCooldownHours = 24 * 7 // 7 days
+    const shouldShowToPendingEditor = () => {
+      if (isProjectOwner || !features) {
+        return false
+      }
+
+      if (features.collaborators === -1) {
+        return false
+      }
+      return isPendingEditor
+    }
+
+    if (shouldShowToPendingEditor()) {
+      const localStorageKey = `last-shown-view-only-access-modal.${projectId}`
+      const lastShownNeedEditModalTime =
+        customLocalStorage.getItem(localStorageKey)
+      if (
+        !lastShownNeedEditModalTime ||
+        lastShownNeedEditModalTime + showModalCooldownHours * 60 * 60 * 1000 <
+          Date.now()
+      ) {
+        setShow(true)
+        customLocalStorage.setItem(localStorageKey, Date.now())
+        sendMB('notification-prompt', {
+          name: 'link-sharing-collaborator-limit',
+        })
+      }
+    }
+  }, [
+    features,
+    isProjectOwner,
+    isPendingEditor,
+    members,
+    permissionsLevel,
+    projectId,
+  ])
+
+  return show ? (
+    <AccessibleModal
+      animation
+      show={show}
+      onHide={() => {
+        sendMB('notification-dismiss', {
+          name: 'link-sharing-collaborator-limit',
+        })
+        handleHide()
+      }}
+      id="editor-over-limit-modal"
+    >
+      <ViewOnlyAccessModalContent handleHide={handleHide} />
+    </AccessibleModal>
+  ) : null
+}
+
+export default ViewOnlyAccessModal

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

@@ -2308,6 +2308,7 @@
   "view_metrics_commons_subtext": "Monitor and download usage metrics for your Commons subscription",
   "view_metrics_group_subtext": "Monitor and download usage metrics for your group subscription",
   "view_more": "View more",
+  "view_only_access": "View-only access",
   "view_only_downgraded": "View only. Upgrade to restore edit access.",
   "view_options": "View options",
   "view_pdf": "View PDF",