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

[web] Fix FileTreeModalCreateFile modal style on "too many files" error (#28995)

* Temporarily update `maxEntitiesPerProject` to test `FileTreeModalCreateFile`

* Remove unused CSS

* Move project_has_too_many_files Notification to the modal body

* Turn project_approaching_file_limit message into a Notification

* Update project_has_too_many_files translation with `fileCount.limit`

* Update other project_has_too_many_files with limit parameter

* Add translations for project_has_too_many_files_limit

* Revert "Temporarily update `maxEntitiesPerProject` to test `FileTreeModalCreateFile`"

This reverts commit 704996aa96c9ba592c7e44d165def0b97d30bed1.

* Fix unit tests

* Move the warning notification to the modal's body

---------

Co-authored-by: Rebeka <o.dekany@gmail.com>
GitOrigin-RevId: 0f54db7021e4cd4537a14e4f9e1d8ef54337778c
Antoine Clausse 10 месяцев назад
Родитель
Сommit
8c15af1a70

+ 10 - 2
services/web/app/src/Features/Editor/EditorHttpController.mjs

@@ -152,7 +152,11 @@ async function addDoc(req, res, next) {
     res.json(doc)
   } catch (err) {
     if (err.message === 'project_has_too_many_files') {
-      res.status(400).json(req.i18n.translate('project_has_too_many_files'))
+      res.status(400).json(
+        req.i18n.translate('project_has_too_many_files_limit', {
+          limit: Settings.maxEntitiesPerProject,
+        })
+      )
     } else {
       next(err)
     }
@@ -178,7 +182,11 @@ async function addFolder(req, res, next) {
     res.json(doc)
   } catch (err) {
     if (err.message === 'project_has_too_many_files') {
-      res.status(400).json(req.i18n.translate('project_has_too_many_files'))
+      res.status(400).json(
+        req.i18n.translate('project_has_too_many_files_limit', {
+          limit: Settings.maxEntitiesPerProject,
+        })
+      )
     } else if (err.message === 'invalid element name') {
       res.status(400).json(req.i18n.translate('invalid_file_name'))
     } else {

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

@@ -1341,7 +1341,7 @@
   "project_files_history": "",
   "project_files_outline": "",
   "project_flagged_too_many_compiles": "",
-  "project_has_too_many_files": "",
+  "project_has_too_many_files_limit": "",
   "project_history_labels": "",
   "project_last_published_at": "",
   "project_linked_to": "",

+ 8 - 2
services/web/frontend/js/features/file-tree/components/file-tree-create/error-message.tsx

@@ -16,7 +16,7 @@ export default function ErrorMessage({
   error: string | Record<string, any>
 }) {
   const { t } = useTranslation()
-  const { isOverleaf } = getMeta('ol-ExposedSettings')
+  const { isOverleaf, maxEntitiesPerProject } = getMeta('ol-ExposedSettings')
   const fileNameLimit = 150
 
   // the error is a string
@@ -27,7 +27,13 @@ export default function ErrorMessage({
         return <DangerMessage>{t('file_already_exists')}</DangerMessage>
 
       case 'too-many-files':
-        return <DangerMessage>{t('project_has_too_many_files')}</DangerMessage>
+        return (
+          <DangerMessage>
+            {t('project_has_too_many_files_limit', {
+              limit: maxEntitiesPerProject,
+            })}
+          </DangerMessage>
+        )
 
       case 'remote-service-error':
         return <DangerMessage>{t('remote_service_error')}</DangerMessage>

+ 28 - 4
services/web/frontend/js/features/file-tree/components/file-tree-create/file-tree-modal-create-file-body.tsx

@@ -11,6 +11,7 @@ import importOverleafModules from '../../../../../macros/import-overleaf-module.
 import { ElementType, lazy, Suspense } from 'react'
 import { FullSizeLoadingSpinner } from '@/shared/components/loading-spinner'
 import getMeta from '@/utils/meta'
+import OLNotification from '@/shared/components/ol/ol-notification'
 
 const createFileModeModules = importOverleafModules('createFileModes') as {
   import: { CreateFilePane: ElementType; CreateFileMode: ElementType }
@@ -30,10 +31,20 @@ export default function FileTreeModalCreateFileBody() {
     hasLinkUrlFeature,
   } = getMeta('ol-ExposedSettings')
 
-  if (
-    !fileCount ||
-    (typeof fileCount === 'object' && fileCount.status === 'error')
-  ) {
+  if (typeof fileCount !== 'number' && fileCount.status === 'error') {
+    return (
+      <div className="p-4">
+        <OLNotification
+          type="error"
+          content={t('project_has_too_many_files_limit', {
+            limit: fileCount.limit,
+          })}
+        />
+      </div>
+    )
+  }
+
+  if (!fileCount) {
     return null
   }
 
@@ -83,6 +94,19 @@ export default function FileTreeModalCreateFileBody() {
           <td
             className={`modal-new-file-body modal-new-file-body-${newFileCreateMode}`}
           >
+            {typeof fileCount !== 'number' &&
+              fileCount.status === 'warning' && (
+                <OLNotification
+                  type="warning"
+                  className={`mb-3 ${newFileCreateMode === 'upload' ? 'mt-0' : 'mt-3'}`}
+                  content={
+                    <>
+                      {t('project_approaching_file_limit')} ({fileCount.value}/
+                      {fileCount.limit})
+                    </>
+                  }
+                />
+              )}
             {newFileCreateMode === 'doc' && (
               <FileTreeCreateNameProvider initialName="name.tex">
                 <FileTreeCreateNewDoc />

+ 0 - 29
services/web/frontend/js/features/file-tree/components/file-tree-create/file-tree-modal-create-file-footer.tsx

@@ -1,14 +1,11 @@
 import { useTranslation } from 'react-i18next'
 import { useFileTreeCreateForm } from '../../contexts/file-tree-create-form'
 import { useFileTreeActionable } from '../../contexts/file-tree-actionable'
-import { useFileTreeData } from '../../../../shared/context/file-tree-data-context'
 import OLButton from '@/shared/components/ol/ol-button'
-import OLNotification from '@/shared/components/ol/ol-notification'
 
 export default function FileTreeModalCreateFileFooter() {
   const { valid } = useFileTreeCreateForm()
   const { newFileCreateMode, inFlight, cancel } = useFileTreeActionable()
-  const { fileCount } = useFileTreeData()
 
   return (
     <FileTreeModalCreateFileFooterContent
@@ -16,26 +13,17 @@ export default function FileTreeModalCreateFileFooter() {
       cancel={cancel}
       newFileCreateMode={newFileCreateMode}
       inFlight={inFlight}
-      fileCount={fileCount}
     />
   )
 }
 
 export function FileTreeModalCreateFileFooterContent({
   valid,
-  fileCount,
   inFlight,
   cancel,
   newFileCreateMode,
 }: {
   valid: boolean
-  fileCount:
-    | {
-        limit: number
-        status: string
-        value: number
-      }
-    | number
   inFlight: boolean
   cancel: () => void
   newFileCreateMode?: string
@@ -44,23 +32,6 @@ export function FileTreeModalCreateFileFooterContent({
 
   return (
     <>
-      {typeof fileCount !== 'number' && fileCount.status === 'warning' && (
-        <div className="modal-footer-left approaching-file-limit">
-          {t('project_approaching_file_limit')} ({fileCount.value}/
-          {fileCount.limit})
-        </div>
-      )}
-
-      {typeof fileCount !== 'number' && fileCount.status === 'error' && (
-        <OLNotification
-          type="error"
-          className="at-file-limit"
-          content={t('project_has_too_many_files')}
-        >
-          {/* TODO: add parameter for fileCount.limit */}
-        </OLNotification>
-      )}
-
       <OLButton
         variant="secondary"
         type="button"

+ 0 - 10
services/web/frontend/stylesheets/pages/editor/file-tree.scss

@@ -779,16 +779,6 @@
   padding: var(--spacing-05);
 }
 
-.modal-footer {
-  .approaching-file-limit {
-    font-weight: bold;
-  }
-
-  .at-file-limit {
-    text-align: left;
-  }
-}
-
 /* stylelint-disable selector-class-pattern */
 .modal-new-file-body-upload .uppy-Root {
   font-family: inherit;

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

@@ -1387,6 +1387,7 @@
   "project_files": "Projektfiler",
   "project_flagged_too_many_compiles": "Dette projekt er blevet markeret for at kompilere for ofte. Grænsen bliver snart løftet.",
   "project_has_too_many_files": "Dette projekt har nået grænsen på 2000 filer",
+  "project_has_too_many_files_limit": "Dette projekt har nået grænsen på __limit__ filer",
   "project_last_published_at": "Dit projekt var sidst blevet offentliggjort den",
   "project_layout_sharing_submission": "Projektlayout, deling og indsendelse",
   "project_name": "Projektnavn",

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

@@ -976,6 +976,7 @@
   "project_approaching_file_limit": "Dieses Projekt nähert sich dem Dateilimit",
   "project_flagged_too_many_compiles": "Dieses Projekt wurde zu häufig zum Kompilieren vermerkt. Das Limit wird in Kürze aufgehoben.",
   "project_has_too_many_files": "Dieses Projekt hat das Limit von 2000 Dateien erreicht",
+  "project_has_too_many_files_limit": "Dieses Projekt hat das Limit von __limit__ Dateien erreicht",
   "project_last_published_at": "Dein Projekt wurde zuletzt veröffentlicht am",
   "project_layout_sharing_submission": "Projektlayout, Freigabe und Einreichung",
   "project_name": "Projektname",

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

@@ -1754,6 +1754,7 @@
   "project_files_outline": "Project files and outline",
   "project_flagged_too_many_compiles": "This project has been flagged for compiling too often. The limit will be lifted shortly.",
   "project_has_too_many_files": "This project has reached the 2000 file limit",
+  "project_has_too_many_files_limit": "This project has reached the __limit__ file limit",
   "project_history_labels": "Project history and labels",
   "project_last_published_at": "Your project was last published at",
   "project_linked_to": "This project is linked to",

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

@@ -880,6 +880,7 @@
   "project_approaching_file_limit": "Ce projet approche la limite de fichiers",
   "project_flagged_too_many_compiles": "Ce projet a été compilé trop fréquemment. Cette limite sera levée sous peu.",
   "project_has_too_many_files": "La limite des 2 000 fichiers a été atteinte pour ce projet",
+  "project_has_too_many_files_limit": "La limite des __limit__ fichiers a été atteinte pour ce projet",
   "project_last_published_at": "Votre projet a été édité pour la dernière fois le",
   "project_name": "Nom du projet",
   "project_not_linked_to_github": "Ce projet n’est pas lié à un dépôt GitHub. Vous pouvez lui créer un dépôt dans GitHub :",

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

@@ -634,6 +634,7 @@
   "project_approaching_file_limit": "Detta projekt närmar sig gränsen för antalet filer",
   "project_flagged_too_many_compiles": "Detta projekt har kompilerats för ofta. Begränsningen kommer snart tas bort igen.",
   "project_has_too_many_files": "Detta projekt har nått gränsen på 2000 filer",
+  "project_has_too_many_files_limit": "Detta projekt har nått gränsen på __limit__ filer",
   "project_last_published_at": "Ditt projekt blev publicerat senast den",
   "project_name": "Projekt namn",
   "project_not_linked_to_github": "Detta projekt är inte länkat till ett GitHub repo. Du kan skapa ett repo för det på GitHub:",

+ 1 - 0
services/web/locales/zh-CN.json

@@ -1643,6 +1643,7 @@
   "project_files": "项目文件",
   "project_flagged_too_many_compiles": "因频繁编译,项目被标旗。编译上限会稍后解除。",
   "project_has_too_many_files": "此项目已达到 2000 个文件限制",
+  "project_has_too_many_files_limit": "此项目已达到 __limit__ 个文件限制",
   "project_last_published_at": "您的项目最近一次被发布在",
   "project_layout_sharing_submission": "项目布局、分享和提交",
   "project_linked_to": "该项目链接到",

+ 2 - 2
services/web/test/unit/src/Editor/EditorHttpController.test.mjs

@@ -524,7 +524,7 @@ describe('EditorHttpController', function () {
         )
         await new Promise(resolve => {
           ctx.res.callback = () => {
-            expect(ctx.res.body).to.equal('"project_has_too_many_files"')
+            expect(ctx.res.body).to.equal('"project_has_too_many_files_limit"')
             expect(ctx.res.status).to.have.been.calledWith(400)
             resolve()
           }
@@ -584,7 +584,7 @@ describe('EditorHttpController', function () {
             new Error('project_has_too_many_files')
           )
           ctx.res.callback = () => {
-            expect(ctx.res.body).to.equal('"project_has_too_many_files"')
+            expect(ctx.res.body).to.equal('"project_has_too_many_files_limit"')
             expect(ctx.res.statusCode).to.equal(400)
             resolve()
           }