diff --git a/packages/client/public/locales/ar-SA/People.json b/packages/client/public/locales/ar-SA/People.json index bf80ea801a..6e32f3b349 100644 --- a/packages/client/public/locales/ar-SA/People.json +++ b/packages/client/public/locales/ar-SA/People.json @@ -1,6 +1,6 @@ { "LblInviteAgain": "ادعوه مرة أخرى", - "MessageEmailActivationInstuctionsSentOnEmail": "The email activation instructions have been sent to the <1>{{email}} email address.", + "MessageEmailActivationInstuctionsSentOnEmail": "The email activation instructions have been sent to the {{email}} email address.", "NotFoundUsers": "لم يتم العثور على مستخدمين", "UserStatus": "الحالة" } diff --git a/packages/client/public/locales/ar-SA/Settings.json b/packages/client/public/locales/ar-SA/Settings.json index 82fba1710b..07e4b325f8 100644 --- a/packages/client/public/locales/ar-SA/Settings.json +++ b/packages/client/public/locales/ar-SA/Settings.json @@ -150,7 +150,6 @@ "RecoveryFileNotSelected": "خطأ في الاسترداد. لم يتم تحديد ملف الاسترداد.", "RestoreBackup": "استرجاع", "RestoreBackupDescription": "استخدم هذا الخيار لاستعادة إستضافتك من ملف النسخ الاحتياطي المحفوظ مسبقًا.", - "RestoreDefaultButton": "استعادة الى الافتراضي", "RoomsModule": "غرفة النسخ الاحتياطي", "RoomsModuleDescription": "يمكنك إنشاء غرفة جديدة خصيصًا للنسخ الاحتياطي ، أو اختيار إحدى الغرف الموجودة ، أو حفظ النسخة في غرفة {{roomName}} الخاصة بهم.", "SelectFileInGZFormat": "حدد الملف بتنسيق ملف مضغوط", diff --git a/packages/client/public/locales/az/Settings.json b/packages/client/public/locales/az/Settings.json index 2149004a06..ab229a7f46 100644 --- a/packages/client/public/locales/az/Settings.json +++ b/packages/client/public/locales/az/Settings.json @@ -159,7 +159,6 @@ "RecoveryFileNotSelected": "Bərpa xətası. Bərpa olunacaq fayl seçilməyib.", "RestoreBackup": "Məlumatların bərpası", "RestoreBackupDescription": "Sahənizi əvvəllər saxlanmış ehtiyat faylından bərpa etmək üçün bu seçimdən istifadə edin.", - "RestoreDefaultButton": "İlkin vəziyyətə bərpa edin", "RoomsModule": "Ehtiyat otaq", "RoomsModuleDescription": "Yedəkləmə üçün xüsusi olaraq yeni otaq yarada, mövcud otaqlardan birini seçə və ya nüsxəni onların {{roomName}} otağında saxlaya bilərsiniz.", "SelectFileInGZFormat": ".GZ formatında qovluq seçin", diff --git a/packages/client/public/locales/bg/Settings.json b/packages/client/public/locales/bg/Settings.json index c7b8274785..dea5458bdc 100644 --- a/packages/client/public/locales/bg/Settings.json +++ b/packages/client/public/locales/bg/Settings.json @@ -159,7 +159,6 @@ "RecoveryFileNotSelected": "Грешка при възстановяване. Файлът за възстановяване не е избран.", "RestoreBackup": "Възстановяване на данни", "RestoreBackupDescription": "Използвайте тази опция, за да възстановите портала от предварително записания архивен файл.", - "RestoreDefaultButton": "Възстановяване по Подразбиране", "RoomsModule": "Резервна стая", "RoomsModuleDescription": "Можете да създадете нова стая специално за резервното копие, да изберете една от съществуващите стаи или да запазите копието в тяхната стая {{roomName}}.", "SelectFileInGZFormat": "Изберете файла във формат .GZ", diff --git a/packages/client/public/locales/cs/Settings.json b/packages/client/public/locales/cs/Settings.json index 69946d2483..1c1f928bfa 100644 --- a/packages/client/public/locales/cs/Settings.json +++ b/packages/client/public/locales/cs/Settings.json @@ -156,7 +156,6 @@ "RecoveryFileNotSelected": "Chyba při obnově. Soubor pro obnovení nebyl vybrán.", "RestoreBackup": "Obnova dat", "RestoreBackupDescription": "Použijte tuto možnost pro obnovu Vašeho prostoru z předchozího souboru obnovy.", - "RestoreDefaultButton": "Obnovit do původního stavu", "RoomsModule": "Záložní místnost", "RoomsModuleDescription": "Můžete vytvořit novou místnost speciálně pro zálohu, vybrat jednu z existujících místností nebo uložit kopii do jejich místnosti {{roomName}}.", "SelectFileInGZFormat": "Vyberte soubor ve formátu .GZ", diff --git a/packages/client/public/locales/de/Settings.json b/packages/client/public/locales/de/Settings.json index 827e524c0a..a11a58ec78 100644 --- a/packages/client/public/locales/de/Settings.json +++ b/packages/client/public/locales/de/Settings.json @@ -169,7 +169,6 @@ "RecoveryFileNotSelected": "Fehler bei der Wiederherstellung. Datei zur Wiederherstellung nicht ausgewählt.", "RestoreBackup": "Datenwiederherstellung", "RestoreBackupDescription": "Nutzen Sie diese Option, um Ihr Bereich aus der vorher gespeicherten Sicherungsdatei wiederherzustellen.", - "RestoreDefaultButton": "Standardmäßige Einstellungen", "RoomsModule": "Ersatzraum", "RoomsModuleDescription": "Sie können einen neuen Raum speziell für die Sicherung erstellen, einen der vorhandenen Räume wählen oder die Kopie in ihrem {{roomName}}-Raum speichern.", "SelectFileInGZFormat": "Die Datei im GZ-Format auswählen", diff --git a/packages/client/public/locales/el-GR/Settings.json b/packages/client/public/locales/el-GR/Settings.json index 6c20c1bac7..497ea39202 100644 --- a/packages/client/public/locales/el-GR/Settings.json +++ b/packages/client/public/locales/el-GR/Settings.json @@ -152,7 +152,6 @@ "RecoveryFileNotSelected": "Σφάλμα ανάκτησης. Το αρχείο ανάκτησης δεν έχει επιλεγεί.", "RestoreBackup": "Επαναφορά Δεδομένων", "RestoreBackupDescription": "Χρησιμοποιήστε αυτήν την επιλογή για να επαναφέρετε την DocSpace σας από το αρχείο αντιγράφων ασφαλείας που είχε αποθηκευτεί προηγουμένως.", - "RestoreDefaultButton": "Επαναφορά στην προεπιλογή", "RoomsModule": "Δημιουργία αντιγράφου ασφαλείας δωματίου", "RoomsModuleDescription": "Μπορείτε να δημιουργήσετε ένα νέο δωμάτιο ειδικά για το αντίγραφο ασφαλείας, να επιλέξετε ένα από τα υπάρχοντα δωμάτια ή να αποθηκεύσετε το αντίγραφο στο δωμάτιό τους {{roomName}}.", "SelectFileInGZFormat": "Επιλογή αρχείου σε μορφή .GZ", diff --git a/packages/client/public/locales/en/Files.json b/packages/client/public/locales/en/Files.json index cae3a1d1cf..ce6fb58642 100644 --- a/packages/client/public/locales/en/Files.json +++ b/packages/client/public/locales/en/Files.json @@ -141,6 +141,8 @@ "RoomPinned": "Room pinned", "RoomRemoved": "Room removed", "RoomsRemoved": "Rooms removed", + "RoomsPinned": "Rooms pinned: {{count}}", + "RoomsUnpinned": "Rooms unpinned: {{count}}", "RoomUnpinned": "Room unpinned", "SearchByContent": "Search by file contents", "SelectorEmptyScreenHeader": "No files and folders here yet", diff --git a/packages/client/public/locales/en/People.json b/packages/client/public/locales/en/People.json index 3284b305b5..c634024860 100644 --- a/packages/client/public/locales/en/People.json +++ b/packages/client/public/locales/en/People.json @@ -1,6 +1,6 @@ { "LblInviteAgain": "Invite again", - "MessageEmailActivationInstuctionsSentOnEmail": "The email activation instructions have been sent to the <1>{{email}} email address.", + "MessageEmailActivationInstuctionsSentOnEmail": "The email activation instructions have been sent to the {{email}} email address.", "NotFoundUsers": "No users found", "NotFoundUsersDescription": "No users match your search. Please adjust your search parameters or clear the search field to view the full list of users.", "UserStatus": "Status" diff --git a/packages/client/public/locales/en/Settings.json b/packages/client/public/locales/en/Settings.json index 83210394ce..0320ddb813 100644 --- a/packages/client/public/locales/en/Settings.json +++ b/packages/client/public/locales/en/Settings.json @@ -186,7 +186,6 @@ "RestoreBackupDescription": "Use this option to restore your space from the previously saved backup file.", "RestoreBackupResetInfoWarningText": "All current passwords will be reset. DocSpace users will get an email with the access restoration link.", "RestoreBackupWarningText": "DocSpace will become unavailable during the restore process. After the restore is complete all the changes made after the date of the selected restore point will be lost.", - "RestoreDefaultButton": "Restore to default", "RoomsModule": "Backup room", "RoomsModuleDescription": "You may create a new room specifically for the backup, choose one of the existing rooms, or save the copy in their {{roomName}} room.", "SelectFileInGZFormat": "Select the file in .GZ format", diff --git a/packages/client/public/locales/es/Settings.json b/packages/client/public/locales/es/Settings.json index 9420ecf224..f968eba7b9 100644 --- a/packages/client/public/locales/es/Settings.json +++ b/packages/client/public/locales/es/Settings.json @@ -160,7 +160,6 @@ "RecoveryFileNotSelected": "Error de recuperación. No se ha seleccionado el archivo de recuperación.", "RestoreBackup": "Restauración de datos", "RestoreBackupDescription": "Use esta opción para restaurar su espacio de la copia de seguridad guardada anteriormente.", - "RestoreDefaultButton": "Restablecer como predeterminado", "RoomsModule": "Sala de copia de seguridad", "RoomsModuleDescription": "Puede crear una nueva sala específicamente para la copia de seguridad, elegir una de las salas existentes o guardar la copia en su sala {{roomName}}.", "SelectFileInGZFormat": "Seleccione el archivo en formato .GZ", diff --git a/packages/client/public/locales/fi/Settings.json b/packages/client/public/locales/fi/Settings.json index 4581f12828..28b6480625 100644 --- a/packages/client/public/locales/fi/Settings.json +++ b/packages/client/public/locales/fi/Settings.json @@ -156,7 +156,6 @@ "RecoveryFileNotSelected": "Palautusvirhe. Palautustiedostoa ei ole valittu.", "RestoreBackup": "Tiedon Palautus", "RestoreBackupDescription": "Käytä tätä, jos haluat palauttaa sivuston sisällön aiemmin tehdyltä varmuuskopiolta.", - "RestoreDefaultButton": "Palauta oletus", "RoomsModule": "Varmuuskopioi huone", "RoomsModuleDescription": "Voit luoda uuden huoneen erityisesti varmuuskopiolle, valita yhden olemassa olevista huoneista, tai tallentaa kopioin heidän {{roomName}} huoneeseen.", "SelectFileInGZFormat": "Valitse tiedosto .GZ-muodossa", diff --git a/packages/client/public/locales/fr/Settings.json b/packages/client/public/locales/fr/Settings.json index bf6d65b4c7..069456ebc5 100644 --- a/packages/client/public/locales/fr/Settings.json +++ b/packages/client/public/locales/fr/Settings.json @@ -160,7 +160,6 @@ "RecoveryFileNotSelected": "Erreur de récupération. Fichier de récupération non sélectionné.", "RestoreBackup": "Restauration des données", "RestoreBackupDescription": "Utilisez cette option pour restaurer votre espace du fichier de sauvegarde enregistré précédemment.", - "RestoreDefaultButton": "Restaurer les paramètres par défaut", "RoomsModule": "Salle de sauvegarde", "RoomsModuleDescription": "Vous pouvez créer une nouvelle salle spécialement pour la sauvegarde, choisir l’une des salles existantes ou enregistrer la copie dans la salle {{roomName}}.", "SelectFileInGZFormat": "Sélectionnez le fichier au format .GZ", diff --git a/packages/client/public/locales/hy-AM/Settings.json b/packages/client/public/locales/hy-AM/Settings.json index b2cd14c6b0..9e69ba280a 100644 --- a/packages/client/public/locales/hy-AM/Settings.json +++ b/packages/client/public/locales/hy-AM/Settings.json @@ -153,7 +153,6 @@ "RecoveryFileNotSelected": "Վերականգնման սխալ. Վերականգնման ֆայլը ընտրված չէ:", "RestoreBackup": "Տվյալների վերականգնում", "RestoreBackupDescription": "Օգտագործեք այս տարբերակը՝ Ձեր կայքէջը նախկինում պահված պահուստային ֆայլից վերականգնելու համար:", - "RestoreDefaultButton": "Վերականգնել լռելյայն", "RoomsModule": "Պահուստավորման սենյակ", "RoomsModuleDescription": "Դուք կարող եք ստեղծել նոր սենյակ հատուկ պահուստավորման համար, ընտրել առկա սենյակներից մեկը կամ պատճենը պահել իր {{roomName}} սենյակում:", "SelectFileInGZFormat": "Ընտրեք ֆայլը .GZ ձևաչափով", diff --git a/packages/client/public/locales/it/Settings.json b/packages/client/public/locales/it/Settings.json index ba75ced1f8..d4f686cab7 100644 --- a/packages/client/public/locales/it/Settings.json +++ b/packages/client/public/locales/it/Settings.json @@ -169,7 +169,6 @@ "RecoveryFileNotSelected": "Errore di ripristino. File di ripristino non selezionato.", "RestoreBackup": "Ripristino dati", "RestoreBackupDescription": "Utilizza questa opzione per ripristinare il tuo spazio dal file di backup precedentemente salvato.", - "RestoreDefaultButton": "Ripristina le impostazioni predefinite", "RoomsModule": "Stanza di backup", "RoomsModuleDescription": "Puoi creare una nuova stanza appositamente per il backup, scegliere una delle stanze esistenti o salvare la copia nella loro stanza {{roomName}}.", "SelectFileInGZFormat": "Selezionare il file in formato .GZ", diff --git a/packages/client/public/locales/ja-JP/Settings.json b/packages/client/public/locales/ja-JP/Settings.json index c733eaaf4b..2168811474 100644 --- a/packages/client/public/locales/ja-JP/Settings.json +++ b/packages/client/public/locales/ja-JP/Settings.json @@ -159,7 +159,6 @@ "RecoveryFileNotSelected": "回復エラー。回復ファイルが選択されていません。", "RestoreBackup": "データ復元", "RestoreBackupDescription": "バックアップ・ファイルからスペースを復するためにこの操作を使用してください。", - "RestoreDefaultButton": "デフォルトに戻す", "RoomsModule": "ルームをバックアップする", "RoomsModuleDescription": "バックアップのために特別に新しいルームを作るか、既存のルームの一つを選ぶか、その {{roomName}} ルムにコピーを保存することができます。", "SelectFileInGZFormat": "「.GZ」形式ファイルを選択してください。", diff --git a/packages/client/public/locales/ko-KR/Settings.json b/packages/client/public/locales/ko-KR/Settings.json index 919ce7c79c..2c5684d743 100644 --- a/packages/client/public/locales/ko-KR/Settings.json +++ b/packages/client/public/locales/ko-KR/Settings.json @@ -151,7 +151,6 @@ "RecoveryFileNotSelected": "복원 오류입니다. 복원 파일이 선택되지 않았습니다", "RestoreBackup": "데이터 복원", "RestoreBackupDescription": "이전에 저장한 백업 파일에서 스페이스를 복원하기 위해 이 옵션을 사용하세요.", - "RestoreDefaultButton": "기본값으로 복원", "RoomsModule": "백업 방", "RoomsModuleDescription": "특별히 백업용으로 새 방을 만들거나 기존 방 중 하나를 선택하거나 {{roomName}} 방에 사본을 저장할 수 있습니다.", "SelectFileInGZFormat": ".GZ 형식의 파일을 선택해주세요", diff --git a/packages/client/public/locales/lo-LA/Settings.json b/packages/client/public/locales/lo-LA/Settings.json index 1fe6022d8a..98b639f516 100644 --- a/packages/client/public/locales/lo-LA/Settings.json +++ b/packages/client/public/locales/lo-LA/Settings.json @@ -151,7 +151,6 @@ "RecoveryFileNotSelected": "ການ​ຟື້ນ​ຕົວ​ຄວາມ​ຜິດ​ພາດ​. ການ​ຟື້ນ​ຕົວ​ໄຟລ​໌​ບໍ່​ໄດ້​ເລືອກ.", "RestoreBackup": "ຂໍ້ມູນ ຟື້ນຟູ", "RestoreBackupDescription": "ໃຊ້ຕົວເລືອກນີ້ເພື່ອຟື້ນຟູປະຕູຂອງເຈົ້າຈາກໄຟລ໌ສຳຮອງທີ່ບັນທຶກໄວ້ໃນເມື່ອກ່ອນ. ", - "RestoreDefaultButton": "ກູ້ຄືນເປັນຄ່າເລີ່ມຕົ້ນ", "RoomsModule": "ສຳຮອງຂໍ້ມູນຫ້ອງ", "RoomsModuleDescription": "ທ່ານອາດຈະສ້າງຫ້ອງໃຫມ່ໂດຍສະເພາະສໍາລັບການ ສໍາຮອງຂໍ້ມູນ, ເລືອກຫນຶ່ງຂອງຫ້ອງທີ່ມີຢູ່ແລ້ວ, ຫຼືບັນທຶກສໍາເນົາຢູ່ໃນ ຫ້ອງ {{ roomName }} ຂອງເຂົາເຈົ້າ.", "SelectFileInGZFormat": "ເລືອກໄຟລ໌ໃນຮູບແບບ . GZ", diff --git a/packages/client/public/locales/lv/Settings.json b/packages/client/public/locales/lv/Settings.json index cbc3fb9176..125f6d98af 100644 --- a/packages/client/public/locales/lv/Settings.json +++ b/packages/client/public/locales/lv/Settings.json @@ -157,7 +157,6 @@ "RecoveryFileNotSelected": "Atkopšanas kļūda. Atkopšanas fails nav atlasīts.", "RestoreBackup": "Datu atjaunošana", "RestoreBackupDescription": "Izmantojiet šo iespēju, lai atjaunotu portālu no iepriekš noglabāta rezerves faila.", - "RestoreDefaultButton": "Atjaunot uz noklusējumu", "RoomsModule": "Dublējuma telpa", "RoomsModuleDescription": "Jūs varat izveidot jaunu telpu tieši dublēšanai, izvēlēties vienu no esošajām telpām vai saglabāt kopiju savā {{roomName}} telpā.", "SelectFileInGZFormat": "Izvēlieties failu .GZ formātā", diff --git a/packages/client/public/locales/nl/Settings.json b/packages/client/public/locales/nl/Settings.json index c8859cc867..8161aefd9a 100644 --- a/packages/client/public/locales/nl/Settings.json +++ b/packages/client/public/locales/nl/Settings.json @@ -156,7 +156,6 @@ "RecoveryFileNotSelected": "Herstelfout. Herstelbestand niet geselecteerd.", "RestoreBackup": "Dataherstel", "RestoreBackupDescription": "Gebruik deze optie om uw ruimte te herstellen vanaf het voorgaande opgeslagen back-up bestand.", - "RestoreDefaultButton": "Terugzetten naar Standaardwaarden", "RoomsModule": "Backup kamer", "RoomsModuleDescription": "U kunt een nieuwe kamer aanmaken speciaal voor de back-up, een van de bestaande kamers kiezen, of de kopie opslaan in hun {{roomName}} kamer.", "SelectFileInGZFormat": "Selecteer het bestand in .GZ formaat", diff --git a/packages/client/public/locales/pl/Settings.json b/packages/client/public/locales/pl/Settings.json index a7800d5cf4..e3d94e9352 100644 --- a/packages/client/public/locales/pl/Settings.json +++ b/packages/client/public/locales/pl/Settings.json @@ -156,7 +156,6 @@ "RecoveryFileNotSelected": "Błąd odzyskiwania. Nie wybrano pliku odzyskiwania.", "RestoreBackup": "Odzyskiwanie danych", "RestoreBackupDescription": "Użyj tej opcji do przywrócenia portalu z wcześniej zapisanego pliku kopii zapasowej.", - "RestoreDefaultButton": "Przywróć ustawienia domyślne", "RoomsModule": "Stwórz kopię zapasową pokoju", "RoomsModuleDescription": "Możesz utworzyć nowy pokój specjalnie do kopii zapasowej, wybrać jeden z istniejących pokoi lub zapisać kopię w jej pokoju {{roomName}}.", "SelectFileInGZFormat": "Wybierz plik w formacie .GZ", diff --git a/packages/client/public/locales/pt-BR/Settings.json b/packages/client/public/locales/pt-BR/Settings.json index ec565421b6..91649ebc70 100644 --- a/packages/client/public/locales/pt-BR/Settings.json +++ b/packages/client/public/locales/pt-BR/Settings.json @@ -160,7 +160,6 @@ "RecoveryFileNotSelected": "Erro de recuperação. Arquivo de recuperação não selecionado.", "RestoreBackup": "Restauração de dados", "RestoreBackupDescription": "Use esta opção para restaurar seu espaço a partir do arquivo de backup salvo anteriormente.", - "RestoreDefaultButton": "Restaurar padrão", "RoomsModule": "Sala de backup", "RoomsModuleDescription": "Você pode criar uma nova sala especificamente para o backup, escolher uma das salas existentes ou salvar a cópia em sua sala {{roomName}}.", "SelectFileInGZFormat": "Selecione o arquivo no formato .GZ", diff --git a/packages/client/public/locales/pt/Settings.json b/packages/client/public/locales/pt/Settings.json index 4d4d76fe07..71af1180e2 100644 --- a/packages/client/public/locales/pt/Settings.json +++ b/packages/client/public/locales/pt/Settings.json @@ -152,7 +152,6 @@ "RecoveryFileNotSelected": "Erro na recuperação. O ficheiro de Recuperação não foi selecionado.", "RestoreBackup": "Restaurar Dados", "RestoreBackupDescription": "Utilize esta opção para restaurar o seu espaço através de uma cópia de segurança guardada anteriormente.", - "RestoreDefaultButton": "Restaurar para a Predefinição", "RoomsModule": "Sala de Apoio", "RoomsModuleDescription": "Pode criar uma nova sala especificamente para a cópia de segurança, escolher uma das salas existentes, ou guardar a cópia na sua sala {{roomName}}.", "SelectFileInGZFormat": "Selecione o ficheiro no formato .GZ", diff --git a/packages/client/public/locales/ro/Settings.json b/packages/client/public/locales/ro/Settings.json index ebe37a7bb1..b51b7b055d 100644 --- a/packages/client/public/locales/ro/Settings.json +++ b/packages/client/public/locales/ro/Settings.json @@ -152,7 +152,6 @@ "RecoveryFileNotSelected": "Eroare la recuperarea. Fișierul de recuperare nu a fost selectat.", "RestoreBackup": "Restaurarea datelor", "RestoreBackupDescription": "Utilizați această opțiune pentru a restaura spațiul dvs dintr-o copie de rezervă existentă.", - "RestoreDefaultButton": "Restabilirea setărilor implicite", "RoomsModule": "Copiere de rezervă a sălii", "RoomsModuleDescription": "Puteți crea o sală nouă destinată special pentru copiere de rezervă, alege una dintre sălile existente sau salva copia în sala {{roomName}}.", "SelectFileInGZFormat": "Alegeți format de fișier .GZ", diff --git a/packages/client/public/locales/ru/Settings.json b/packages/client/public/locales/ru/Settings.json index 13d00c1397..0b1d4bbb47 100644 --- a/packages/client/public/locales/ru/Settings.json +++ b/packages/client/public/locales/ru/Settings.json @@ -169,7 +169,6 @@ "RecoveryFileNotSelected": "Ошибка восстановления. Файл восстановления не выбран.", "RestoreBackup": "Восстановление", "RestoreBackupDescription": "Используйте эту опцию, чтобы восстановить портал из ранее сохраненного резервного файла.", - "RestoreDefaultButton": "Настройки по умолчанию", "RoomsModule": "Резервная комната", "RoomsModuleDescription": "Вы можете создать новую комнату специально для резервного копирования, выбрать одну из существующих комнат или сохранить копию в {{roomName}}.", "SelectFileInGZFormat": "Выбрать файл в формате .GZ", diff --git a/packages/client/public/locales/sk/Settings.json b/packages/client/public/locales/sk/Settings.json index 15e3a87340..5e23287d4f 100644 --- a/packages/client/public/locales/sk/Settings.json +++ b/packages/client/public/locales/sk/Settings.json @@ -156,7 +156,6 @@ "RecoveryFileNotSelected": "Vyskytla sa chyba. Nie je vybratý zálohový súbor.", "RestoreBackup": "Obnova dát", "RestoreBackupDescription": "Túto možnosť použite na obnovenie Vášho priestoru z predtým uloženého záložného súboru.", - "RestoreDefaultButton": "Obnoviť predvolené", "RoomsModule": "Zálohovať miestnosť", "RoomsModuleDescription": "Môžete vytvoriť novú miestnosť špeciálne na zálohovanie, vybrať jednu z existujúcich miestností alebo uložiť kópiu do svojej miestnosti {{roomName}}.", "SelectFileInGZFormat": "Vyberte súbor vo formáte .GZ", diff --git a/packages/client/public/locales/sl/Settings.json b/packages/client/public/locales/sl/Settings.json index 4c7d97022f..a8512b88f3 100644 --- a/packages/client/public/locales/sl/Settings.json +++ b/packages/client/public/locales/sl/Settings.json @@ -152,7 +152,6 @@ "RecoveryFileNotSelected": "Napaka pri obnovitvi. Datoteka za obnovitev ni izbrana.", "RestoreBackup": "Obnovitev podatkov", "RestoreBackupDescription": "S to opcijo obnovite svoj prostor iz predhodno shranjene varnostne kopije.", - "RestoreDefaultButton": "Obnovi na privzeto", "RoomsModule": "Varnostno kopiranje sobe", "RoomsModuleDescription": "Ustvarite lahko novo sobo posebej za varnostno kopijo, izberete eno od obstoječih sob ali shranite kopijo v njihovo {{roomName}} sobo.", "SelectFileInGZFormat": "Izberite datoteko v .GZ formatu", diff --git a/packages/client/public/locales/tr/Settings.json b/packages/client/public/locales/tr/Settings.json index a34e56774f..ee0fd197cb 100644 --- a/packages/client/public/locales/tr/Settings.json +++ b/packages/client/public/locales/tr/Settings.json @@ -156,7 +156,6 @@ "RecoveryFileNotSelected": "Kurtarma hatası. Kurtarma dosyası seçilmedi.", "RestoreBackup": "Veri Geri Yükleme", "RestoreBackupDescription": "Alanda bulunan tüm verileri dosya olarak almak istiyorsanız bu seçeneği kullanın.", - "RestoreDefaultButton": "Fabrika ayarlarına geri dön", "RoomsModule": "Odayı yedekle", "RoomsModuleDescription": "Yedekleme için özel olarak yeni bir oda oluşturabilir, mevcut odalardan birini seçebilir veya kopyayı onların {{roomName}} odasına kaydedebilirsiniz.", "SelectFileInGZFormat": ".GZ formatındaki dosyayı seçin", diff --git a/packages/client/public/locales/uk-UA/Settings.json b/packages/client/public/locales/uk-UA/Settings.json index 4c090411c6..01ef6fad82 100644 --- a/packages/client/public/locales/uk-UA/Settings.json +++ b/packages/client/public/locales/uk-UA/Settings.json @@ -156,7 +156,6 @@ "RecoveryFileNotSelected": "Помилка відновлення. Файл відновлення не вибрано.", "RestoreBackup": "Відновити дані", "RestoreBackupDescription": "Використовуйте цю опцію, щоб відновити раніше збережений файл резервної копії вашого порталу.", - "RestoreDefaultButton": "Відновити значення за замовчуванням", "RoomsModule": "Резервна кімната", "RoomsModuleDescription": "Ви можете створити нову кімнату спеціально для резервного копіювання, вибрати одну з наявних кімнат або зберегти копію в їхній кімнаті {{roomName}}.", "SelectFileInGZFormat": "Виберіть файл у форматі.GZ", diff --git a/packages/client/public/locales/vi/Settings.json b/packages/client/public/locales/vi/Settings.json index a466c81110..edf0417065 100644 --- a/packages/client/public/locales/vi/Settings.json +++ b/packages/client/public/locales/vi/Settings.json @@ -156,7 +156,6 @@ "RecoveryFileNotSelected": "Lỗi khôi phục. Tập tin khôi phục không được chọn.", "RestoreBackup": "Khôi phục dữ liệu", "RestoreBackupDescription": "Sử dụng tùy chọn này để khôi phục lại không gian của bạn từ tập tin đã sao lưu trước đó.", - "RestoreDefaultButton": "Khôi phục về mặc định", "RoomsModule": "Phòng dự phòng", "RoomsModuleDescription": "Bạn có thể tạo một phòng mới chuyên dùng để sao lưu, chọn một trong các phòng hiện có hoặc lưu bản sao trong phòng {{roomName}} của họ.", "SelectFileInGZFormat": "Chọn tập tin có định dạng GZ", diff --git a/packages/client/public/locales/zh-CN/Settings.json b/packages/client/public/locales/zh-CN/Settings.json index 4cf6628326..2fe821c858 100644 --- a/packages/client/public/locales/zh-CN/Settings.json +++ b/packages/client/public/locales/zh-CN/Settings.json @@ -156,7 +156,6 @@ "RecoveryFileNotSelected": "恢复错误。未选择恢复文件", "RestoreBackup": "数据恢复", "RestoreBackupDescription": "设置此选项,从之前保存的备份文件中恢复门户数据。", - "RestoreDefaultButton": "恢复至默认", "RoomsModule": "备份房间", "RoomsModuleDescription": "您可为备份专门新建一个房间,也可选择现有房间或将副本保存在其 {{roomName}} 房间中。", "SelectFileInGZFormat": "选择 .GZ 格式的文件", diff --git a/packages/client/src/Client.jsx b/packages/client/src/Client.jsx index 67f3ec3fb5..d98afd92d3 100644 --- a/packages/client/src/Client.jsx +++ b/packages/client/src/Client.jsx @@ -23,7 +23,12 @@ import { } from "./components/Article"; const ClientArticle = React.memo( - ({ withMainButton, setIsHeaderLoading, setIsFilterLoading }) => { + ({ + withMainButton, + setIsHeaderLoading, + setIsFilterLoading, + showArticleLoader, + }) => { return (
@@ -69,6 +75,7 @@ const ClientContent = (props) => { setIsHeaderLoading, isDesktopClientInit, setIsDesktopClientInit, + showArticleLoader, } = props; const location = useLocation(); @@ -143,6 +150,7 @@ const ClientContent = (props) => { withMainButton={withMainButton} setIsHeaderLoading={setIsHeaderLoading} setIsFilterLoading={setIsFilterLoading} + showArticleLoader={showArticleLoader} /> ) ) : ( @@ -171,8 +179,12 @@ const Client = inject( const { isVisitor } = auth.userStore.user; - const { isLoading, setIsSectionFilterLoading, setIsSectionHeaderLoading } = - clientLoadingStore; + const { + isLoading, + setIsSectionFilterLoading, + setIsSectionHeaderLoading, + showArticleLoader, + } = clientLoadingStore; const withMainButton = !isVisitor; @@ -195,6 +207,7 @@ const Client = inject( setIsHeaderLoading: setIsSectionHeaderLoading, isLoading, setEncryptionKeys: setEncryptionKeys, + showArticleLoader, loadClientInfo: async () => { const actions = []; actions.push(filesStore.initFiles()); diff --git a/packages/client/src/DocspaceLogo/index.js b/packages/client/src/DocspaceLogo/index.js index bc1d0596dc..19f1cab699 100644 --- a/packages/client/src/DocspaceLogo/index.js +++ b/packages/client/src/DocspaceLogo/index.js @@ -1,7 +1,7 @@ import React from "react"; import styled from "styled-components"; import { ReactSVG } from "react-svg"; -import { hugeMobile } from "@docspace/components/utils/device"; +import { mobile } from "@docspace/components/utils/device"; import { inject, observer } from "mobx-react"; import { getLogoFromPath } from "@docspace/common/utils"; @@ -11,7 +11,7 @@ const StyledWrapper = styled.div` height: 44px; } - @media ${hugeMobile} { + @media ${mobile} { display: none; } `; diff --git a/packages/client/src/HOCs/withContent.js b/packages/client/src/HOCs/withContent.js index f0b01f6d55..78dbaf5498 100644 --- a/packages/client/src/HOCs/withContent.js +++ b/packages/client/src/HOCs/withContent.js @@ -14,7 +14,7 @@ import config from "PACKAGE_FILE"; import { getTitleWithoutExtension } from "SRC_DIR/helpers/filesUtils"; //import { getDefaultFileName } from "@docspace/client/src/helpers/filesUtils"; //import ItemIcon from "../components/ItemIcon"; -import { getCookie } from "@docspace/common/utils"; +import { getCookie } from "@docspace/components/utils/cookie"; export default function withContent(WrappedContent) { class WithContent extends React.Component { diff --git a/packages/client/src/HOCs/withFileActions.js b/packages/client/src/HOCs/withFileActions.js index 05e2ad9f5e..b0a0804bc9 100644 --- a/packages/client/src/HOCs/withFileActions.js +++ b/packages/client/src/HOCs/withFileActions.js @@ -1,6 +1,7 @@ import React from "react"; import { inject, observer } from "mobx-react"; -import { isMobile } from "react-device-detect"; + +import { DeviceType } from "@docspace/common/constants"; export default function withFileActions(WrappedFileItem) { class WithFileActions extends React.Component { @@ -79,6 +80,7 @@ export default function withFileActions(WrappedFileItem) { inProgress, isSelected, setSelection, + currentDeviceType, } = this.props; const { isThirdPartyFolder } = item; @@ -97,9 +99,8 @@ export default function withFileActions(WrappedFileItem) { isRoomsFolder || isArchiveFolder || (!draggable && !isFileName && !isActive) || - window.innerWidth < 1025 || + currentDeviceType !== DeviceType.desktop || notSelectable || - isMobile || isThirdPartyFolder || inProgress ) { @@ -230,6 +231,7 @@ export default function withFileActions(WrappedFileItem) { isFolder, itemIndex, + currentDeviceType, } = this.props; const { access, id } = item; @@ -249,7 +251,7 @@ export default function withFileActions(WrappedFileItem) { const isShareable = allowShareIn && item.canShare; - const isMobileView = sectionWidth < 500; + const isMobileView = currentDeviceType === DeviceType.mobile; const displayShareButton = isMobileView ? "26px" @@ -289,6 +291,7 @@ export default function withFileActions(WrappedFileItem) { return inject( ( { + auth, filesActionsStore, dialogsStore, treeFoldersStore, @@ -420,6 +423,7 @@ export default function withFileActions(WrappedFileItem) { withShiftSelect, setSelection, + currentDeviceType: auth.settingsStore.currentDeviceType, }; } )(observer(WithFileActions)); diff --git a/packages/client/src/HOCs/withLoader.js b/packages/client/src/HOCs/withLoader.js index bc33a19411..1d76f4dad9 100644 --- a/packages/client/src/HOCs/withLoader.js +++ b/packages/client/src/HOCs/withLoader.js @@ -20,8 +20,13 @@ const withLoader = (WrappedComponent) => (Loader) => { showBodyLoader, isLoadingFilesFind, accountsViewAs, + setBodyRendered, } = props; + React.useEffect(() => { + setBodyRendered(true); + }, []); + const location = useLocation(); const currentViewAs = location.pathname.includes("/accounts/filter") @@ -61,7 +66,7 @@ const withLoader = (WrappedComponent) => (Loader) => { const { firstLoad, isLoading, showBodyLoader } = clientLoadingStore; const { settingsStore } = auth; - const { setIsBurgerLoading } = settingsStore; + const { setIsBurgerLoading, setBodyRendered } = settingsStore; const { isPublicRoom } = publicRoomStore; return { @@ -74,6 +79,7 @@ const withLoader = (WrappedComponent) => (Loader) => { isInit: isPublicRoom ? true : isInit, showBodyLoader, accountsViewAs, + setBodyRendered, }; } )(observer(withLoader)); diff --git a/packages/client/src/HOCs/withLoading.js b/packages/client/src/HOCs/withLoading.js index 6bca6748b2..b8023b24ab 100644 --- a/packages/client/src/HOCs/withLoading.js +++ b/packages/client/src/HOCs/withLoading.js @@ -1,6 +1,6 @@ import React, { useEffect, useState } from "react"; import { observer, inject } from "mobx-react"; -import { isSmallTablet } from "@docspace/components/utils/device"; +import { isMobile } from "@docspace/components/utils/device"; const withLoading = (WrappedComponent) => { const withLoading = (props) => { @@ -21,6 +21,14 @@ const withLoading = (WrappedComponent) => { const [mobileView, setMobileView] = useState(true); useEffect(() => { + if (window.location.pathname.includes("profile")) { + if (!isLoadedArticleBody) { + setIsBurgerLoading(true); + } else { + setIsBurgerLoading(false); + } + } + if (isLoadedArticleBody) { setIsBurgerLoading(false); } else { @@ -35,7 +43,7 @@ const withLoading = (WrappedComponent) => { }, []); const checkInnerWidth = () => { - if (isSmallTablet()) { + if (isMobile()) { setMobileView(true); } else { setMobileView(false); @@ -46,7 +54,7 @@ const withLoading = (WrappedComponent) => { const index = pathname.lastIndexOf("/"); const setting = pathname.slice(index + 1); - const viewMobile = !!(isSmallTablet() && mobileView); + const viewMobile = !!(isMobile() && mobileView); const isLoadedCustomizationSettings = isLoadedCustomization && diff --git a/packages/client/src/Shell.jsx b/packages/client/src/Shell.jsx index e8a1e5dfe5..b8a7846466 100644 --- a/packages/client/src/Shell.jsx +++ b/packages/client/src/Shell.jsx @@ -1,4 +1,4 @@ -import React, { useEffect } from "react"; +import React, { useEffect, useState } from "react"; import { useLocation, useNavigate, Outlet } from "react-router-dom"; import { inject, observer, Provider as MobxProvider } from "mobx-react"; import NavMenu from "./components/NavMenu"; @@ -19,15 +19,16 @@ import i18n from "./i18n"; import Snackbar from "@docspace/components/snackbar"; import moment from "moment"; -import ReactSmartBanner from "./components/SmartBanner"; +//import ReactSmartBanner from "./components/SmartBanner"; import { useThemeDetector } from "@docspace/common/utils/useThemeDetector"; -import { isMobileOnly, isMobile, isIOS, isFirefox } from "react-device-detect"; +import { isMobile, isIOS, isFirefox } from "react-device-detect"; import IndicatorLoader from "./components/IndicatorLoader"; import DialogsWrapper from "./components/dialogs/DialogsWrapper"; import MainBar from "./components/MainBar"; import { Portal } from "@docspace/components"; import indexedDbHelper from "@docspace/common/utils/indexedDBHelper"; -import { IndexedDBStores } from "@docspace/common/constants"; +import { DeviceType, IndexedDBStores } from "@docspace/common/constants"; +import AppLoader from "@docspace/common/components/AppLoader"; const Shell = ({ items = [], page = "home", ...rest }) => { const { @@ -51,6 +52,9 @@ const Shell = ({ items = [], page = "home", ...rest }) => { whiteLabelLogoUrls, standalone, userId, + currentDeviceType, + bodyRendered, + showArticleLoader, } = rest; useEffect(() => { @@ -102,7 +106,7 @@ const Shell = ({ items = [], page = "home", ...rest }) => { }); }, [socketHelper]); - const { t, ready } = useTranslation(["Common", "SmartBanner"]); + const { t, ready } = useTranslation(["Common"]); //TODO: if enable banner ["Common", "SmartBanner"] let snackTimer = null; let fbInterval = null; @@ -333,23 +337,25 @@ const Shell = ({ items = [], page = "home", ...rest }) => { const rootElement = document.getElementById("root"); - const toast = isMobileOnly ? ( - } appendTo={rootElement} visible={true} /> - ) : ( - - ); + const toast = + currentDeviceType === DeviceType.mobile ? ( + } appendTo={rootElement} visible={true} /> + ) : ( + + ); return ( {toast} - + {/* */} {isEditor ? <> : } - {isMobileOnly && } + {currentDeviceType === DeviceType.mobile && } + {/* {!bodyRendered && } */}
- {!isMobileOnly && } + {currentDeviceType !== DeviceType.mobile && }
@@ -358,7 +364,9 @@ const Shell = ({ items = [], page = "home", ...rest }) => { ); }; -const ShellWrapper = inject(({ auth, backup }) => { +const ShellWrapper = inject(({ auth, backup, clientLoadingStore }) => { + const { i18n } = useTranslation(); + const { init, isLoaded, settingsStore, setProductVersion, language } = auth; const { @@ -374,6 +382,8 @@ const ShellWrapper = inject(({ auth, backup }) => { setTheme, whiteLabelLogoUrls, standalone, + currentDeviceType, + bodyRendered, } = settingsStore; const isBase = settingsStore.theme.isBase; @@ -389,7 +399,7 @@ const ShellWrapper = inject(({ auth, backup }) => { return { loadBaseInfo: async () => { - await init(); + await init(false, i18n); setModuleInfo(config.homepage, "home"); setProductVersion(config.version); @@ -416,6 +426,9 @@ const ShellWrapper = inject(({ auth, backup }) => { userId: auth?.userStore?.user?.id, whiteLabelLogoUrls, standalone, + currentDeviceType, + bodyRendered, + showArticleLoader: clientLoadingStore.showArticleLoader, }; })(observer(Shell)); diff --git a/packages/client/src/components/Article/Body/AccountsItem.js b/packages/client/src/components/Article/Body/AccountsItem.js index 88a066fdae..cd11b04202 100644 --- a/packages/client/src/components/Article/Body/AccountsItem.js +++ b/packages/client/src/components/Article/Body/AccountsItem.js @@ -6,8 +6,6 @@ import CatalogItem from "@docspace/components/catalog-item"; import CatalogAccountsReactSvgUrl from "PUBLIC_DIR/images/catalog.accounts.react.svg?url"; -import withLoader from "../../../HOCs/withLoader"; - const PureAccountsItem = ({ showText, isActive, onClick, t }) => { const onClickAction = React.useCallback(() => { onClick && onClick("accounts"); diff --git a/packages/client/src/components/Article/Body/Banner.js b/packages/client/src/components/Article/Body/Banner.js index 886110b656..e3ff986a95 100644 --- a/packages/client/src/components/Article/Body/Banner.js +++ b/packages/client/src/components/Article/Body/Banner.js @@ -2,7 +2,8 @@ import React, { useState, useEffect } from "react"; import CampaignsBanner from "@docspace/components/campaigns-banner"; import { ADS_TIMEOUT } from "@docspace/client/src/helpers/filesConstants"; import { LANGUAGE } from "@docspace/common/constants"; -import { getLanguage, getCookie } from "@docspace/common/utils"; +import { getLanguage } from "@docspace/common/utils"; +import { getCookie } from "@docspace/components/utils/cookie"; const Banner = () => { const [campaignImage, setCampaignImage] = useState(); diff --git a/packages/client/src/components/Article/Body/Items.js b/packages/client/src/components/Article/Body/Items.js index 7615c403c2..6a98223192 100644 --- a/packages/client/src/components/Article/Body/Items.js +++ b/packages/client/src/components/Article/Body/Items.js @@ -18,10 +18,11 @@ import { FolderType, ShareAccessRights, FolderNames, + DeviceType, } from "@docspace/common/constants"; import { withTranslation } from "react-i18next"; import DragAndDrop from "@docspace/components/drag-and-drop"; -import { isMobile } from "react-device-detect"; + import SettingsItem from "./SettingsItem"; import AccountsItem from "./AccountsItem"; import BonusItem from "./BonusItem"; @@ -186,6 +187,7 @@ const Items = ({ isCommunity, isPaymentPageAvailable, + currentDeviceType, }) => { const getEndOfBlock = React.useCallback( (item) => { @@ -311,7 +313,7 @@ const Items = ({ }, [deleteAction]); const onEmptyTrashAction = () => { - isMobile && onHide(); + currentDeviceType === DeviceType.mobile && onHide(); setEmptyTrashDialogVisible(true); }; @@ -425,7 +427,12 @@ export default inject( dialogsStore, clientLoadingStore, }) => { - const { settingsStore, isCommunity, isPaymentPageAvailable } = auth; + const { + settingsStore, + isCommunity, + isPaymentPageAvailable, + currentDeviceType, + } = auth; const { showText, docSpace } = settingsStore; const { @@ -486,6 +493,7 @@ export default inject( emptyTrashInProgress, isCommunity, isPaymentPageAvailable, + currentDeviceType, }; } )(withTranslation(["Files", "Common", "Translations"])(observer(Items))); diff --git a/packages/client/src/components/Article/Body/index.js b/packages/client/src/components/Article/Body/index.js index d644ab6f42..9b42fb2275 100644 --- a/packages/client/src/components/Article/Body/index.js +++ b/packages/client/src/components/Article/Body/index.js @@ -2,12 +2,12 @@ import React from "react"; import styled from "styled-components"; import { inject, observer } from "mobx-react"; import { withTranslation } from "react-i18next"; -import { isDesktop, isTablet, isMobileOnly } from "react-device-detect"; + import { useNavigate, useLocation } from "react-router-dom"; -import { RoomSearchArea } from "@docspace/common/constants"; +import { DeviceType, RoomSearchArea } from "@docspace/common/constants"; import Items from "./Items"; -import { isMobile, tablet } from "@docspace/components/utils/device"; +import { tablet } from "@docspace/components/utils/device"; import FilesFilter from "@docspace/common/api/files/filter"; import RoomsFilter from "@docspace/common/api/rooms/filter"; @@ -52,6 +52,7 @@ const ArticleBodyContent = (props) => { showArticleLoader, setIsBurgerLoading, setSelection, + currentDeviceType, } = props; const navigate = useNavigate(); @@ -120,6 +121,7 @@ const ArticleBodyContent = (props) => { params = accountsFilter.toUrlParams(); path = getCategoryUrl(CategoryType.Accounts); + withTimer = false; if (activeItemId === "accounts" && isAccounts) return; break; @@ -129,7 +131,7 @@ const ArticleBodyContent = (props) => { path = getCategoryUrl(CategoryType.Settings); navigate(path); - if (isMobileOnly || isMobile()) { + if (currentDeviceType === DeviceType.mobile) { toggleArticleOpen(); } return; @@ -149,7 +151,7 @@ const ArticleBodyContent = (props) => { navigate(path, { state }); - if (isMobileOnly || isMobile()) { + if (currentDeviceType === DeviceType.mobile) { toggleArticleOpen(); } }, @@ -297,6 +299,7 @@ export default inject( FirebaseHelper, theme, setIsBurgerLoading, + currentDeviceType, } = auth.settingsStore; return { @@ -324,6 +327,7 @@ export default inject( selectedFolderId, setIsBurgerLoading, setSelection, + currentDeviceType, }; } )(withTranslation([])(observer(ArticleBodyContent))); diff --git a/packages/client/src/components/Article/MainButton/MobileView.js b/packages/client/src/components/Article/MainButton/MobileView.js index 684f4d3713..5155b2dce8 100644 --- a/packages/client/src/components/Article/MainButton/MobileView.js +++ b/packages/client/src/components/Article/MainButton/MobileView.js @@ -3,7 +3,6 @@ import MobileActionsRemoveReactSvgUrl from "PUBLIC_DIR/images/mobile.actions.rem import React from "react"; import styled, { css } from "styled-components"; import { inject, observer } from "mobx-react"; -import { isMobileOnly } from "react-device-detect"; import { mobile } from "@docspace/components/utils/device"; @@ -11,10 +10,9 @@ import MainButtonMobile from "@docspace/components/main-button-mobile"; const StyledMainButtonMobile = styled(MainButtonMobile)` position: fixed; - z-index: 200; - ${props => + ${(props) => props.theme.interfaceDirection === "rtl" ? css` left: 24px; @@ -22,10 +20,12 @@ const StyledMainButtonMobile = styled(MainButtonMobile)` : css` right: 24px; `} + bottom: 24px; @media ${mobile} { - ${props => + position: absolute; + ${(props) => props.theme.interfaceDirection === "rtl" ? css` left: 16px; @@ -35,19 +35,6 @@ const StyledMainButtonMobile = styled(MainButtonMobile)` `} bottom: 16px; } - - ${isMobileOnly && - css` - ${props => - props.theme.interfaceDirection === "rtl" - ? css` - left: 16px; - ` - : css` - right: 16px; - `} - bottom: 16px; - `} `; const MobileView = ({ @@ -82,7 +69,7 @@ const MobileView = ({ const primaryCurrentFile = React.useRef(null); const openButtonToggler = React.useCallback(() => { - setIsOpenButton(prevState => !prevState); + setIsOpenButton((prevState) => !prevState); }, []); const showUploadPanel = React.useCallback(() => { @@ -98,9 +85,9 @@ const MobileView = ({ let currentPrimaryNumEl = primaryNumEl; const uploadedFileCount = files.filter( - item => item.percent === 100 && !item.cancel + (item) => item.percent === 100 && !item.cancel ).length; - const fileLength = files.filter(item => !item.cancel).length; + const fileLength = files.filter((item) => !item.cancel).length; if (primaryCurrentFile.current === null && primaryProgressDataLoadingFile) { primaryCurrentFile.current = primaryProgressDataLoadingFile.uniqueId; diff --git a/packages/client/src/components/Article/MainButton/index.js b/packages/client/src/components/Article/MainButton/index.js index 91450b25a5..cb34d031c7 100644 --- a/packages/client/src/components/Article/MainButton/index.js +++ b/packages/client/src/components/Article/MainButton/index.js @@ -15,7 +15,6 @@ import InviteAgainReactSvgUrl from "PUBLIC_DIR/images/invite.again.react.svg?url import PluginMoreReactSvgUrl from "PUBLIC_DIR/images/plugin.more.react.svg?url"; import React from "react"; -import { isMobileOnly } from "react-device-detect"; import { inject, observer } from "mobx-react"; import MainButton from "@docspace/components/main-button"; @@ -26,7 +25,7 @@ import { useNavigate, useLocation } from "react-router-dom"; import MobileView from "./MobileView"; -import { Events, EmployeeType } from "@docspace/common/constants"; +import { Events, EmployeeType, DeviceType } from "@docspace/common/constants"; import toastr from "@docspace/components/toast/toastr"; import styled, { css } from "styled-components"; import Button from "@docspace/components/button"; @@ -119,12 +118,14 @@ const ArticleMainButtonContent = (props) => { setInvitePanelOptions, mainButtonMobileVisible, + versionHistoryPanelVisible, moveToPanelVisible, copyPanelVisible, security, isGracePeriod, setInviteUsersWarningDialogVisible, + currentDeviceType, } = props; const navigate = useNavigate(); @@ -479,9 +480,12 @@ const ArticleMainButtonContent = (props) => { let mainButtonVisible = true; - if (isMobileOnly) { + if (currentDeviceType === DeviceType.mobile) { mainButtonVisible = - moveToPanelVisible || copyPanelVisible || selectFileDialogVisible + moveToPanelVisible || + copyPanelVisible || + selectFileDialogVisible || + versionHistoryPanelVisible ? false : true; } @@ -570,6 +574,7 @@ export default inject( selectedFolderStore, clientLoadingStore, pluginStore, + versionHistoryStore, }) => { const { showArticleLoader } = clientLoadingStore; const { mainButtonMobileVisible } = filesStore; @@ -592,7 +597,9 @@ export default inject( selectFileDialogVisible, } = dialogsStore; - const { enablePlugins, currentColorScheme } = auth.settingsStore; + const { enablePlugins, currentColorScheme, currentDeviceType } = + auth.settingsStore; + const { isVisible: versionHistoryPanelVisible } = versionHistoryStore; const security = selectedFolderStore.security; @@ -638,7 +645,9 @@ export default inject( mainButtonMobileVisible, moveToPanelVisible, copyPanelVisible, + versionHistoryPanelVisible, security, + currentDeviceType, }; } )( diff --git a/packages/client/src/components/Badges.js b/packages/client/src/components/Badges.js index 4e8d1635a7..2a1200b73b 100644 --- a/packages/client/src/components/Badges.js +++ b/packages/client/src/components/Badges.js @@ -8,11 +8,12 @@ import styled from "styled-components"; import Badge from "@docspace/components/badge"; import IconButton from "@docspace/components/icon-button"; import commonIconsStyles from "@docspace/components/utils/common-icons-style"; -import { isTablet } from "react-device-detect"; + import { FileStatus } from "@docspace/common/constants"; import { Base } from "@docspace/components/themes"; import { ColorTheme, ThemeType } from "@docspace/components/ColorTheme"; +import { isTablet } from "@docspace/components/utils/device"; const StyledWrapper = styled.div` display: flex; @@ -46,8 +47,7 @@ const BadgeWrapper = ({ onClick, isTile, children: badge }) => { + onMouseLeave={onMouseLeave}> {newBadge} ); @@ -94,14 +94,13 @@ const Badges = ({ const contentNewItems = newItems > 999 ? "999+" : newItems; - const tabletViewBadge = - !isTile && ((sectionWidth > 500 && sectionWidth <= 1024) || isTablet); + const tabletViewBadge = !isTile && isTablet(); const sizeBadge = isTile || tabletViewBadge ? "medium" : "small"; const lineHeightBadge = isTile || tabletViewBadge ? "1.46" : "1.34"; - const paddingBadge = isTile || tabletViewBadge ? "0 3px" : "0 5px"; + const paddingBadge = isTile || tabletViewBadge ? "0 5px" : "0 5px"; const fontSizeBadge = isTile || tabletViewBadge ? "11px" : "9px"; diff --git a/packages/client/src/components/BreakpointWarning/sub-components/StyledBreakpointWarning.js b/packages/client/src/components/BreakpointWarning/sub-components/StyledBreakpointWarning.js index 33b8350495..77c54b876d 100644 --- a/packages/client/src/components/BreakpointWarning/sub-components/StyledBreakpointWarning.js +++ b/packages/client/src/components/BreakpointWarning/sub-components/StyledBreakpointWarning.js @@ -1,5 +1,6 @@ import styled from "styled-components"; import { getCorrectFourValuesStyle } from "@docspace/components/utils/rtlUtils"; +import { mobileMore } from "@docspace/components/utils/device"; const StyledBreakpointWarning = styled.div` padding: ${({ theme }) => @@ -33,7 +34,7 @@ const StyledBreakpointWarning = styled.div` height: 72px; } - @media (min-width: 600px) { + @media ${mobileMore} { flex-direction: row; padding: ${({ theme }) => diff --git a/packages/client/src/components/BreakpointWarning/sub-components/loader.js b/packages/client/src/components/BreakpointWarning/sub-components/loader.js index 6a83721bf3..b194d374b7 100644 --- a/packages/client/src/components/BreakpointWarning/sub-components/loader.js +++ b/packages/client/src/components/BreakpointWarning/sub-components/loader.js @@ -1,8 +1,9 @@ import React, { useState, useEffect } from "react"; import styled from "styled-components"; import Loaders from "@docspace/common/components/Loaders"; -import { isMobileOnly } from "react-device-detect"; + import { getCorrectFourValuesStyle } from "@docspace/components/utils/rtlUtils"; +import { isMobile, mobileMore } from "@docspace/components/utils/device"; const StyledLoader = styled.div` padding-top: 25px; @@ -31,7 +32,7 @@ const StyledLoader = styled.div` display: block; } - @media (min-width: 600px) { + @media ${mobileMore} { flex-direction: row; padding: ${({ theme }) => getCorrectFourValuesStyle("65px 0 0 104px", theme.interfaceDirection)}; @@ -54,7 +55,7 @@ const Loader = () => { }, []); const onCheckView = () => { - if (isMobileOnly || window.innerWidth < 600) { + if (isMobile()) { setViewMobile(true); } else { setViewMobile(false); diff --git a/packages/client/src/components/EmptyContainer/EmptyContainer.js b/packages/client/src/components/EmptyContainer/EmptyContainer.js index 677a800f93..f28b73077c 100644 --- a/packages/client/src/components/EmptyContainer/EmptyContainer.js +++ b/packages/client/src/components/EmptyContainer/EmptyContainer.js @@ -4,11 +4,11 @@ import EmptyScreenContainer from "@docspace/components/empty-screen-container"; import NoUserSelect from "@docspace/components/utils/commonStyles"; import { tablet, - smallTablet, + mobile, desktop, size, } from "@docspace/components/utils/device"; -import { isMobile, isMobileOnly } from "react-device-detect"; +import { isMobileOnly } from "react-device-detect"; import { classNames } from "@docspace/components/utils/classNames"; const EmptyPageStyles = css` @@ -22,12 +22,12 @@ const EmptyPageStyles = css` } .empty-folder_link { - ${props => - props.theme.interfaceDirection === "rtl" - ? css` + ${(props) => + props.theme.interfaceDirection === "rtl" + ? css` margin-left: 9px; ` - : css` + : css` margin-right: 9px; `} } @@ -43,13 +43,13 @@ const EmptyPageStyles = css` grid-column-gap: 33px; } - @media ${smallTablet} { - ${props => - props.theme.interfaceDirection === "rtl" - ? css` + @media ${mobile} { + ${(props) => + props.theme.interfaceDirection === "rtl" + ? css` padding-left: 44px; ` - : css` + : css` padding-right: 44px; `} } @@ -58,12 +58,12 @@ const EmptyPageStyles = css` const EmptyFolderWrapper = styled.div` .empty-folder_container { .empty-folder_link { - ${props => - props.theme.interfaceDirection === "rtl" - ? css` + ${(props) => + props.theme.interfaceDirection === "rtl" + ? css` margin-left: 7px; ` - : css` + : css` margin-right: 7px; `} } @@ -96,12 +96,12 @@ const EmptyFolderWrapper = styled.div` .empty-folder_container_up-image, .empty-folder_container_plus-image { - ${props => - props.theme.interfaceDirection === "rtl" - ? css` + ${(props) => + props.theme.interfaceDirection === "rtl" + ? css` margin: 4px 0 0 8px; ` - : css` + : css` margin: 4px 8px 0 0; `} cursor: pointer; @@ -121,12 +121,12 @@ const EmptyFolderWrapper = styled.div` .empty-folder_container-icon { height: 20px; width: 12px; - ${props => - props.theme.interfaceDirection === "rtl" - ? css` + ${(props) => + props.theme.interfaceDirection === "rtl" + ? css` margin: 4px 0 0 4px; ` - : css` + : css` margin: 4px 4px 0 0; `} @@ -138,33 +138,33 @@ const EmptyFolderWrapper = styled.div` bottom: 16px; } - ${props => props.isEmptyPage && `${EmptyPageStyles}`} + ${(props) => props.isEmptyPage && `${EmptyPageStyles}`} - ${props => + ${(props) => props.isEmptyPage && isMobileOnly && css` - ${props => - props.theme.interfaceDirection === "rtl" - ? css` + ${(props) => + props.theme.interfaceDirection === "rtl" + ? css` padding: 20px 11px 64px 42px !important; ` - : css` + : css` padding: 20px 42px 64px 11px !important; `} `} - ${props => + ${(props) => (props.isEmptyPage || props.isEmptyFolderContainer) && - props.sectionWidth <= size.smallTablet && + props.sectionWidth <= size.mobile && !isMobileOnly && css` - ${props => - props.theme.interfaceDirection === "rtl" - ? css` + ${(props) => + props.theme.interfaceDirection === "rtl" + ? css` padding-right: 12px !important; ` - : css` + : css` padding-left: 12px !important; `} @@ -179,7 +179,7 @@ const EmptyFolderWrapper = styled.div` } `; -const EmptyFoldersContainer = props => { +const EmptyFoldersContainer = (props) => { const imageAlt = "Empty folder image"; const { imageSrc, @@ -200,7 +200,8 @@ const EmptyFoldersContainer = props => { + isEmptyFolderContainer={isEmptyFolderContainer} + > void; onSetNewFolderPath?: (value: number | string | undefined) => void; - onSelectFolder?: (value: number | string | undefined) => void; + onSelectFolder?: ( + value: number | string | undefined, + breadCrumbs: BreadCrumb[] + ) => void; onSelectTreeNode?: (treeNode: any) => void; onSave?: ( e: any, @@ -168,11 +172,16 @@ export type FilesSelectorProps = { fileTitle: string, openNewTab: boolean ) => void; - onSelectFile?: (fileInfo: { - id: string | number; - title: string; - path?: string[]; - }) => void; + onSelectFile?: ( + fileInfo: { + id: string | number; + title: string; + path?: string[]; + }, + breadCrumbs: BreadCrumb[] + ) => void; + + setInfoPanelIsMobileHidden: (arg: boolean) => void; withFooterInput?: boolean; withFooterCheckbox?: boolean; @@ -187,4 +196,7 @@ export type FilesSelectorProps = { socketHelper: any; socketSubscribersId: Set; + currentDeviceType: "mobile" | "tablet" | "desktop"; + + embedded: boolean; }; diff --git a/packages/client/src/components/FilesSelector/helpers/useRoomsHelper.ts b/packages/client/src/components/FilesSelector/helpers/useRoomsHelper.ts index faca35fae3..6a05e8cff5 100644 --- a/packages/client/src/components/FilesSelector/helpers/useRoomsHelper.ts +++ b/packages/client/src/components/FilesSelector/helpers/useRoomsHelper.ts @@ -60,6 +60,7 @@ export const convertRoomsToItems = (rooms: any) => { rootFolderType, isFolder: true, roomType, + color: logo.color, }; }); diff --git a/packages/client/src/components/FilesSelector/i18n.js b/packages/client/src/components/FilesSelector/i18n.js index 06ecc24336..0d095d37ba 100644 --- a/packages/client/src/components/FilesSelector/i18n.js +++ b/packages/client/src/components/FilesSelector/i18n.js @@ -3,12 +3,13 @@ import { initReactI18next } from "react-i18next"; import Backend from "@docspace/common/utils/i18next-http-backend"; import { LANGUAGE } from "@docspace/common/constants"; import config from "PACKAGE_FILE"; -import { getLtrLanguageForEditor, getCookie } from "@docspace/common/utils"; +import { getLtrLanguageForEditor } from "@docspace/common/utils"; +import { getCookie } from "@docspace/components/utils/cookie"; import { loadLanguagePath } from "SRC_DIR/helpers/utils"; const newInstance = i18n.createInstance(); const userLng = getCookie(LANGUAGE) || "en"; -const portalLng = window?.__ASC_INITIAL_EDITOR_STATE__?.portalSettings.culture; +const portalLng = window?.__ASC_INITIAL_EDITOR_STATE__?.portalSettings?.culture; newInstance .use(Backend) diff --git a/packages/client/src/components/FilesSelector/index.tsx b/packages/client/src/components/FilesSelector/index.tsx index 50a311cfa1..9c0ae8b6cc 100644 --- a/packages/client/src/components/FilesSelector/index.tsx +++ b/packages/client/src/components/FilesSelector/index.tsx @@ -5,10 +5,12 @@ import { useTranslation } from "react-i18next"; // @ts-ignore import Loaders from "@docspace/common/components/Loaders"; import { FolderType, RoomsType } from "@docspace/common/constants"; +import { DeviceType } from "@docspace/common/constants"; import Aside from "@docspace/components/aside"; import Backdrop from "@docspace/components/backdrop"; import Selector from "@docspace/components/selector"; +import Portal from "@docspace/components/portal"; // @ts-ignore import toastr from "@docspace/components/toast/toastr"; @@ -46,6 +48,7 @@ const FilesSelector = ({ isMove, isCopy, isRestoreAll, + isSelect, currentFolderId, fromFolderId, @@ -90,6 +93,10 @@ const FilesSelector = ({ socketHelper, socketSubscribersId, setMoveToPublicRoomVisible, + setInfoPanelIsMobileHidden, + currentDeviceType, + + embedded, }: FilesSelectorProps) => { const { t } = useTranslation(["Files", "Common", "Translations"]); @@ -292,6 +299,7 @@ const FilesSelector = ({ }; const onCloseAction = () => { + setInfoPanelIsMobileHidden(false); if (onClose) { onClose(); @@ -427,6 +435,7 @@ const FilesSelector = ({ isCopy, isRestoreAll, isMove, + isSelect, filterParam ); @@ -435,6 +444,7 @@ const FilesSelector = ({ isCopy, isRestoreAll, isMove, + isSelect, filterParam ); @@ -453,13 +463,78 @@ const FilesSelector = ({ includeFolder ); - return ( + const SelectorBody = ( + 0 : !isRoot && isFirstLoad} + rowLoader={ + + } + searchLoader={} + breadCrumbsLoader={} + alwaysShowFooter={true} + isNextPageLoading={isNextPageLoading} + hasNextPage={hasNextPage} + totalItems={total} + loadNextPage={ + isRoot ? null : selectedItemType === "rooms" ? getRoomList : getFileList + } + disableAcceptButton={isDisabled} + withFooterInput={withFooterInput} + withFooterCheckbox={withFooterCheckbox} + footerInputHeader={footerInputHeader} + currentFooterInputValue={currentFooterInputValue} + footerCheckboxLabel={footerCheckboxLabel} + descriptionText={ + !filterParam ? "" : descriptionText ?? t("Common:SelectDOCXFormat") + } + acceptButtonId={isMove || isCopy ? "select-file-modal-submit" : ""} + cancelButtonId={isMove || isCopy ? "select-file-modal-cancel" : ""} + /> + ); + + const selectorComponent = embedded ? ( + SelectorBody + ) : ( <> ); + + return currentDeviceType === DeviceType.mobile ? ( + {selectorComponent}} /> + ) : ( + selectorComponent + ); }; export default inject( @@ -592,7 +608,10 @@ export default inject( setMoveToPublicRoomVisible, } = dialogsStore; - const { theme, socketHelper } = auth.settingsStore; + const { setIsMobileHidden: setInfoPanelIsMobileHidden } = + auth.infoPanelStore; + + const { theme, socketHelper, currentDeviceType } = auth.settingsStore; const { selection, @@ -654,10 +673,12 @@ export default inject( setRestoreAllPanelVisible, setIsFolderActions, setSelectedItems, + setInfoPanelIsMobileHidden, includeFolder, socketHelper, socketSubscribersId, setMoveToPublicRoomVisible, + currentDeviceType, }; } )(observer(FilesSelector)); diff --git a/packages/client/src/components/FilesSelector/utils.ts b/packages/client/src/components/FilesSelector/utils.ts index 172a700c2e..46ed980746 100644 --- a/packages/client/src/components/FilesSelector/utils.ts +++ b/packages/client/src/components/FilesSelector/utils.ts @@ -17,6 +17,7 @@ export const getHeaderLabel = ( isCopy?: boolean, isRestoreAll?: boolean, isMove?: boolean, + isSelect?: boolean, filterParam?: string ) => { if (isMove) return t("Common:MoveTo"); @@ -25,6 +26,7 @@ export const getHeaderLabel = ( if (filterParam === FilesSelectorFilterTypes.DOCX) return t("Translations:CreateMasterFormFromFile"); if (!!filterParam) return t("Common:SelectFile"); + if (isSelect) return t("Common:SelectFile"); return t("Common:SaveButton"); }; @@ -34,6 +36,7 @@ export const getAcceptButtonLabel = ( isCopy?: boolean, isRestoreAll?: boolean, isMove?: boolean, + isSelect?: boolean, filterParam?: string ) => { if (isMove) return t("Translations:MoveHere"); @@ -42,6 +45,7 @@ export const getAcceptButtonLabel = ( if (filterParam === FilesSelectorFilterTypes.DOCX) return t("Common:Create"); // if (filterParam === FilesSelectorFilterTypes.DOCXF) return t("Common:SubmitToGallery"); if (!!filterParam) return t("Common:SaveButton"); + if (isSelect) return t("Common:SelectAction"); return t("Common:SaveHereButton"); }; diff --git a/packages/client/src/components/FilesSelectorInput/index.js b/packages/client/src/components/FilesSelectorInput/index.js index 665ed0702e..c0fb80f6c4 100644 --- a/packages/client/src/components/FilesSelectorInput/index.js +++ b/packages/client/src/components/FilesSelectorInput/index.js @@ -27,6 +27,7 @@ const FilesSelectorInput = (props) => { filterParam, descriptionText, + className, } = props; const isFilesSelection = !!filterParam; @@ -78,7 +79,7 @@ const FilesSelectorInput = (props) => { }; return ( - + { if (e.keyCode === 27) onCloseAction(); if (e.keyCode === 13) onChangeUserType(); diff --git a/packages/client/src/components/GlobalEvents/CreateEvent.js b/packages/client/src/components/GlobalEvents/CreateEvent.js index ffdfd9c40a..3b4e420b64 100644 --- a/packages/client/src/components/GlobalEvents/CreateEvent.js +++ b/packages/client/src/components/GlobalEvents/CreateEvent.js @@ -281,6 +281,7 @@ const CreateEvent = ({ return ( { const [value, setValue] = useState(""); const [isDisabled, setIsDisabled] = useState(false); @@ -47,7 +48,8 @@ const Dialog = ({ const onKeyUpHandler = useCallback( (e) => { if (e.keyCode === 27) onCancelAction(e); - if (e.keyCode === 13) onSaveAction(e); + + if (e.keyCode === 13 && !withForm) onSaveAction(e); }, [value] ); @@ -109,6 +111,7 @@ const Dialog = ({ return ( 0 ? this.customScrollElm.scrollTop : 0; if ( - isTablet && + !isDesktop() && document.getElementsByClassName("backdrop-active").length > 0 && !this.props.isArticleVisibleOnUnpin ) { diff --git a/packages/client/src/components/Layout/index.js b/packages/client/src/components/Layout/index.js index 82db298aba..3a00b1d75c 100644 --- a/packages/client/src/components/Layout/index.js +++ b/packages/client/src/components/Layout/index.js @@ -1,9 +1,14 @@ import React, { useEffect, useState } from "react"; -import styled, { css } from "styled-components"; +import styled from "styled-components"; import PropTypes from "prop-types"; import MobileLayout from "./MobileLayout"; import { useNavigate, useLocation } from "react-router-dom"; -import { size } from "@docspace/components/utils/device"; +import { + size as deviceSize, + isTablet as isTabletUtils, + isMobile as isMobileUtils, + tablet, +} from "@docspace/components/utils/device"; import { isIOS, isFirefox, @@ -20,7 +25,7 @@ const StyledContainer = styled.div` user-select: none; width: 100%; height: ${(props) => - isMobileOnly && isIOS ? "calc(var(--vh, 1vh) * 100)" : props.contentHeight}; + isMobile && isIOS ? "calc(var(--vh, 1vh) * 100)" : props.contentHeight}; /* height: ${(props) => (props.isTabletView || isMobileOnly) && !isFirefox ? `${props.contentHeight}px` @@ -35,7 +40,7 @@ const StyledContainer = styled.div` `; const Layout = (props) => { - const { children, isTabletView, setIsTabletView } = props; + const { children, isTabletView, setIsTabletView, setWindowWidth } = props; const [contentHeight, setContentHeight] = useState(); const [isPortrait, setIsPortrait] = useState(); @@ -56,10 +61,9 @@ const Layout = (props) => { setIsPortrait(window.innerHeight > window.innerWidth); }); useEffect(() => { - const isTablet = window.innerWidth <= size.tablet; - setIsTabletView(isTablet); + setIsTabletView(isTabletUtils()); - let mediaQuery = window.matchMedia("(max-width: 1024px)"); + let mediaQuery = window.matchMedia(tablet); mediaQuery.addEventListener("change", onWidthChange); return () => { @@ -70,18 +74,27 @@ const Layout = (props) => { }, []); useEffect(() => { - if (isTabletView || isMobile) { - if (isIOS && isSafari) window.addEventListener("resize", onResize); - else window.addEventListener("orientationchange", onOrientationChange); + window.addEventListener("resize", onResize); + + if (isTabletUtils() || isMobileUtils()) { + window.addEventListener("orientationchange", onOrientationChange); + + if (isMobile) { + window?.visualViewport?.addEventListener("resize", onOrientationChange); + window.addEventListener("scroll", onScroll); + } + changeRootHeight(); } return () => { - if (isTabletView || isMobile) { - if (isIOS && isSafari) window.removeEventListener("resize", onResize); - else - window.removeEventListener("orientationchange", onOrientationChange); - } + window.removeEventListener("resize", onResize); + window.removeEventListener("orientationchange", onOrientationChange); + window?.visualViewport?.removeEventListener( + "resize", + onOrientationChange + ); + window.removeEventListener("scroll", onScroll); }; }, [isTabletView]); @@ -89,32 +102,34 @@ const Layout = (props) => { const htmlEl = document.getElementsByTagName("html")[0]; const bodyEl = document.getElementsByTagName("body")[0]; - if (isMobileOnly || (isTablet && isChrome)) { - htmlEl.style.height = bodyEl.style.height = "100%"; - htmlEl.style.overflow = "hidden"; - } - - if (isMobileOnly) { - bodyEl.style.overflow = "auto"; - } - - if (isTablet) { - bodyEl.style.overflow = "hidden"; - } + htmlEl.style.height = bodyEl.style.height = "100%"; + htmlEl.style.overflow = "hidden"; }, []); const onWidthChange = (e) => { const { matches } = e; + setIsTabletView(matches); }; + const onScroll = (e) => { + e.preventDefault(); + e.stopPropagation(); + window.scrollTo(0, 0); + }; + const onResize = () => { changeRootHeight(); + setWindowWidth(window.innerWidth); }; - const onOrientationChange = () => { - changeRootHeight(); + const onOrientationChange = (e) => { + e.preventDefault(); + e.stopPropagation(); + + setWindowWidth(window.innerWidth); + changeRootHeight(e); }; - const changeRootHeight = () => { + const changeRootHeight = (e) => { intervalHandler && clearInterval(intervalHandler); timeoutHandler && clearTimeout(timeoutHandler); @@ -131,16 +146,17 @@ const Layout = (props) => { timeoutHandler = null; let height = "100vh"; - const windowHeight = window.innerHeight; + let windowHeight = window.innerHeight; - if (isMobileOnly && isIOS && isChrome) { + if (isMobileUtils() && isIOS && isChrome) { if (window.innerHeight < window.innerWidth && isPortrait) { height = window.screen.availWidth - correctorMobileChrome + "px"; } } - if (isMobileOnly && isAndroid && isChrome) { - height = `calc(100vh - ${correctorMobileChrome}px)`; + if (isMobileUtils() && isAndroid && isChrome) { + // height = `calc(100vh - ${correctorMobileChrome}px)`; + height = `100%`; } // if (isTablet && isIOS && isSafari) { @@ -152,8 +168,45 @@ const Layout = (props) => { // } // } + if (isIOS && isMobile && e?.type === "resize" && e?.target?.height) { + const diff = window.innerHeight - e.target.height; + + windowHeight -= diff; + + const root = document.getElementById("root"); + if (!isMobileUtils()) { + const article = document.getElementsByTagName("article")[0]; + } + + root.style.height = `calc(var(--vh,1vh) * 100)`; + root.style.maxHeight = `calc(var(--vh,1vh) * 100)`; + root.style.minHeight = `calc(var(--vh,1vh) * 100)`; + + document.body.style.height = `calc(var(--vh,1vh) * 100)`; + document.body.style.maxHeight = `calc(var(--vh,1vh) * 100)`; + document.body.style.minHeight = `calc(var(--vh,1vh) * 100)`; + document.body.style.top = "0px"; + document.body.style.position = `fixed`; + document.body.style.overflow = `hidden`; + } else { + const root = document.getElementById("root"); + + root.style.height = `100%`; + root.style.maxHeight = `100%`; + root.style.minHeight = `100%`; + + document.body.style.height = `100%`; + document.body.style.maxHeight = `100%`; + document.body.style.minHeight = `100%`; + document.body.style.removeProperty("top"); + document.body.style.removeProperty("position"); + document.body.style.removeProperty("overflow"); + } + let vh = windowHeight * 0.01; + document.documentElement.style.setProperty("--vh", `${vh}px`); + setContentHeight(height); }; intervalHandler = setInterval(() => { @@ -178,10 +231,10 @@ const Layout = (props) => { return ( - {isMobileOnly ? : children} + {isMobileUtils() ? : children} ); }; @@ -196,5 +249,6 @@ export default inject(({ auth, bannerStore }) => { return { isTabletView: auth.settingsStore.isTabletView, setIsTabletView: auth.settingsStore.setIsTabletView, + setWindowWidth: auth.settingsStore.setWindowWidth, }; })(observer(Layout)); diff --git a/packages/client/src/components/Main/index.js b/packages/client/src/components/Main/index.js index 1f992c6e75..f7209cbbe5 100644 --- a/packages/client/src/components/Main/index.js +++ b/packages/client/src/components/Main/index.js @@ -1,11 +1,15 @@ import React from "react"; +import { inject, observer } from "mobx-react"; import styled, { css } from "styled-components"; -import { isIOS, isFirefox, isMobileOnly } from "react-device-detect"; +import { isMobile, isIOS, isFirefox } from "react-device-detect"; -import { mobile } from "@docspace/components/utils/device"; +import { + mobile, + isMobile as isMobileUtils, +} from "@docspace/components/utils/device"; const StyledMain = styled.main` - height: ${isIOS && !isFirefox ? "calc(var(--vh, 1vh) * 100)" : "100vh"}; + height: ${(props) => props.mainHeight && `${props.mainHeight}px`}; width: 100vw; z-index: 0; display: flex; @@ -21,29 +25,90 @@ const StyledMain = styled.main` box-sizing: border-box; } - ${!isMobileOnly && - css` - @media ${mobile} { - height: ${isIOS && !isFirefox - ? "calc(var(--vh, 1vh) * 100)" - : "calc(100vh - 64px)"}; - } - `} - - ${isMobileOnly && - css` - height: auto; - max-height: 100%; - width: 100%; - `} + /** @media ${mobile} { + height: ${isIOS && !isFirefox + ? "calc(var(--vh, 1vh) * 100)" + : "calc(100vh - 64px)"}; + } */ `; -const Main = React.memo((props) => { +const Main = (props) => { + const { mainBarVisible, isBannerVisible } = props; //console.log("Main render"); + const [mainHeight, setMainHeight] = React.useState(window.innerHeight); + const updateSizeRef = React.useRef(null); - return ; -}); + React.useEffect(() => { + window.addEventListener("resize", onResize); + window.visualViewport.addEventListener("resize", onResize); + + return () => { + window.addEventListener("resize", onResize); + window.visualViewport.removeEventListener("resize", onResize); + clearTimeout(updateSizeRef.current); + }; + }, [onResize]); + + React.useEffect(() => { + onResize(); + }, [mainBarVisible, isBannerVisible]); + + const onResize = React.useCallback( + (e) => { + let correctHeight = window.innerHeight; + + if (mainBarVisible && isMobileUtils()) { + const mainBar = document.getElementById("main-bar"); + + if (!mainBar.offsetHeight) + return (updateSizeRef.current = setTimeout(() => onResize(), 0)); + + correctHeight -= mainBar.offsetHeight; + } + + const isTouchDevice = + "ontouchstart" in window || + navigator.maxTouchPoints > 0 || + navigator.msMaxTouchPoints > 0; + + const path = window.location.pathname.toLowerCase(); + + if ( + isBannerVisible && + isMobile && + isTouchDevice && + (path.includes("rooms") || path.includes("files")) + ) { + correctHeight -= 80; + + if (e?.target?.height) { + const diff = window.innerHeight - e.target.height; + + correctHeight -= diff; + } + } + + // 48 - its nav menu with burger, logo and user avatar + if (isMobileUtils()) { + correctHeight -= 48; + } + + setMainHeight(correctHeight); + }, + [mainBarVisible, isBannerVisible] + ); + + return ; +}; Main.displayName = "Main"; -export default Main; +export default inject(({ auth }) => { + const { isBannerVisible } = auth.bannerStore; + + const { mainBarVisible } = auth.settingsStore; + return { + mainBarVisible, + isBannerVisible, + }; +})(observer(Main)); diff --git a/packages/client/src/components/MainBar/index.js b/packages/client/src/components/MainBar/index.js index 7ff60bf8a5..e447b07689 100644 --- a/packages/client/src/components/MainBar/index.js +++ b/packages/client/src/components/MainBar/index.js @@ -1,33 +1,23 @@ import React from "react"; import { inject, observer } from "mobx-react"; import styled, { css } from "styled-components"; -import { isMobileOnly } from "react-device-detect"; -import { hugeMobile, mobile } from "@docspace/components/utils/device"; + +import { mobile } from "@docspace/components/utils/device"; import Bar from "./Bar"; const StyledContainer = styled.div` width: 100%; max-width: 100%; - ${isMobileOnly && - css` - @media ${hugeMobile} { - width: calc(100% + 16px); - max-width: calc(100% + 16px); - } + @media ${mobile} { + width: calc(100% + 8px); + max-width: calc(100% + 8px); + } - @media ${mobile} { - width: calc(100% + 8px); - max-width: calc(100% + 8px); - } - - ${({ theme }) => - theme.interfaceDirection === "rtl" - ? `margin-left: -16px;` - : `margin-right: -16px;`} - - margin-top: 48px; - `} + ${({ theme }) => + theme.interfaceDirection === "rtl" + ? `margin-left: -16px;` + : `margin-right: -16px;`} #bar-banner { margin-bottom: -3px; diff --git a/packages/client/src/components/NavMenu/i18n.js b/packages/client/src/components/NavMenu/i18n.js index aac0d02a7e..d5e4f4dbd7 100644 --- a/packages/client/src/components/NavMenu/i18n.js +++ b/packages/client/src/components/NavMenu/i18n.js @@ -3,7 +3,7 @@ import { initReactI18next } from "react-i18next"; import Backend from "@docspace/common/utils/i18next-http-backend"; import { LANGUAGE } from "@docspace/common/constants"; import config from "PACKAGE_FILE"; -import { getCookie } from "@docspace/common/utils"; +import { getCookie } from "@docspace/components/utils/cookie"; import { loadLanguagePath } from "SRC_DIR/helpers/utils"; diff --git a/packages/client/src/components/NavMenu/index.js b/packages/client/src/components/NavMenu/index.js index b51b67124c..4cefbb9bed 100644 --- a/packages/client/src/components/NavMenu/index.js +++ b/packages/client/src/components/NavMenu/index.js @@ -1,11 +1,8 @@ import React from "react"; import PropTypes from "prop-types"; import styled, { css } from "styled-components"; -import { - isMobileOnly, - isDesktop as isDesktopDevice, -} from "react-device-detect"; -import { isMobile as isMobileUtils } from "@docspace/components/utils/device"; + +import { isMobile, mobile } from "@docspace/components/utils/device"; import Backdrop from "@docspace/components/backdrop"; import Aside from "@docspace/components/aside"; @@ -22,6 +19,7 @@ import { inject, observer } from "mobx-react"; import i18n from "./i18n"; import PreparationPortalDialog from "../dialogs/PreparationPortalDialog"; import { Base } from "@docspace/components/themes"; +import { DeviceType } from "@docspace/common/constants"; const StyledContainer = styled.header` position: relative; @@ -30,34 +28,32 @@ const StyledContainer = styled.header` ${(props) => !props.isLoaded - ? isMobileOnly && - css` - position: static; - - ${({ theme }) => - theme.interfaceDirection === "rtl" - ? `margin-left: -16px;` - : `margin-right: -16px;`}/* It is a opposite value of padding-right of custom scroll bar, - so that there is no white bar in the header on loading. (padding-right: 16px)*/ - ` - : isMobileOnly && - css` - .navMenuHeader, - .profileMenuIcon, - .navMenuHeaderUnAuth { - position: absolute; - z-index: 160; - top: 0; - // top: ${(props) => (props.isVisible ? "0" : "-48px")}; - - transition: top 0.3s cubic-bezier(0, 0, 0.8, 1); - -moz-transition: top 0.3s cubic-bezier(0, 0, 0.8, 1); - -ms-transition: top 0.3s cubic-bezier(0, 0, 0.8, 1); - -webkit-transition: top 0.3s cubic-bezier(0, 0, 0.8, 1); - -o-transition: top 0.3s cubic-bezier(0, 0, 0.8, 1); + ? css` + @media ${mobile} { + width: 100vw; // fixes space between header loader and screen edge } + ` + : css` + @media ${mobile} { + .navMenuHeader, + .profileMenuIcon, + .navMenuHeaderUnAuth { + position: absolute; + z-index: 160; + top: 0; + // top: ${(props) => (props.isVisible ? "0" : "-48px")}; - width: 100%; + transition: top 0.3s cubic-bezier(0, 0, 0.8, 1); + -moz-transition: top 0.3s cubic-bezier(0, 0, 0.8, 1); + -ms-transition: top 0.3s cubic-bezier(0, 0, 0.8, 1); + -webkit-transition: top 0.3s cubic-bezier(0, 0, 0.8, 1); + -o-transition: top 0.3s cubic-bezier(0, 0, 0.8, 1); + } + + width: 100vw; + + margin-bottom: 48px; + } `} `; @@ -69,10 +65,6 @@ const NavMenu = (props) => { const navigate = useNavigate(); const location = useLocation(); - const [showNavMenu, setShowNavMenu] = React.useState( - isMobileOnly || isMobileUtils() - ); - const [isBackdropVisible, setIsBackdropVisible] = React.useState( props.isBackdropVisible ); @@ -127,16 +119,6 @@ const NavMenu = (props) => { setIsNavHoverEnabled(false); }; - const onResize = React.useCallback(() => { - setShowNavMenu(isMobileUtils() || isMobileOnly); - }, []); - - React.useEffect(() => { - if (isDesktopDevice) window.addEventListener("resize", onResize); - - return () => window.removeEventListener("resize", onResize); - }, []); - const { isAuthenticated, isLoaded, @@ -145,12 +127,13 @@ const NavMenu = (props) => { isDesktop, isFrame, showHeader, + currentDeviceType, } = props; const isAsideAvailable = !!asideContent; const hideHeader = isDesktop || (!showHeader && isFrame); - if (!showNavMenu) return <>; + if (currentDeviceType !== DeviceType.mobile || !isMobile()) return <>; const isPreparationPortal = location.pathname === "/preparation-portal"; return ( @@ -165,6 +148,7 @@ const NavMenu = (props) => { visible={isBackdropVisible} onClick={backdropClick} withBackground={true} + withBlur={true} /> {!hideHeader && @@ -224,7 +208,12 @@ NavMenu.defaultProps = { const NavMenuWrapper = inject(({ auth }) => { const { settingsStore, isAuthenticated, isLoaded, language } = auth; - const { isDesktopClient: isDesktop, frameConfig, isFrame } = settingsStore; + const { + isDesktopClient: isDesktop, + frameConfig, + isFrame, + currentDeviceType, + } = settingsStore; return { isAuthenticated, @@ -234,6 +223,7 @@ const NavMenuWrapper = inject(({ auth }) => { showHeader: frameConfig?.showHeader, isFrame, + currentDeviceType, }; })(observer(withTranslation(["NavMenu", "Common"])(NavMenu))); diff --git a/packages/client/src/components/NavMenu/sub-components/header-catalog-burger.js b/packages/client/src/components/NavMenu/sub-components/header-catalog-burger.js index 54126216a0..3c7ab6cd9e 100644 --- a/packages/client/src/components/NavMenu/sub-components/header-catalog-burger.js +++ b/packages/client/src/components/NavMenu/sub-components/header-catalog-burger.js @@ -1,16 +1,18 @@ import React from "react"; import styled from "styled-components"; import PropTypes from "prop-types"; -import { isMobileOnly } from "react-device-detect"; + import MenuIcon from "PUBLIC_DIR/images/menu.react.svg"; import { mobile } from "@docspace/components/utils/device"; import { Base } from "@docspace/components/themes"; const StyledIconBox = styled.div` + display: none; + @media ${mobile} { display: flex; } - display: ${isMobileOnly ? "flex" : "none"}; + align-items: center; ${({ theme }) => diff --git a/packages/client/src/components/NavMenu/sub-components/header-nav.js b/packages/client/src/components/NavMenu/sub-components/header-nav.js index fce1e905b8..459e05d169 100644 --- a/packages/client/src/components/NavMenu/sub-components/header-nav.js +++ b/packages/client/src/components/NavMenu/sub-components/header-nav.js @@ -5,7 +5,7 @@ import ProfileActions from "./profile-actions"; import { useTranslation } from "react-i18next"; import { mobile, tablet } from "@docspace/components/utils/device"; import { inject, observer } from "mobx-react"; -import { isMobile, isMobileOnly } from "react-device-detect"; + import { getCorrectFourValuesStyle } from "@docspace/components/utils/rtlUtils"; const StyledNav = styled.nav` @@ -23,37 +23,19 @@ const StyledNav = styled.nav` z-index: 180 !important; & > div { - margin: ${({ theme }) => - getCorrectFourValuesStyle("0 0 0 16px", theme.interfaceDirection)}; + margin: 0 16px; padding: 0; min-width: 24px; } @media ${tablet} { - padding: 0 16px; + padding: ${({ theme }) => + getCorrectFourValuesStyle("0 0px 0 16px", theme.interfaceDirection)}; } .icon-profile-menu { cursor: pointer; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); } - - ${isMobile && - css` - padding: 0 16px 0 16px !important; - `} - - @media ${mobile} { - padding: 0 16px 0 16px; - } - - ${isMobileOnly && - css` - padding: ${({ theme }) => - getCorrectFourValuesStyle( - "0 0 0 16px", - theme.interfaceDirection - )} !important; - `} `; const HeaderNav = ({ user, diff --git a/packages/client/src/components/NavMenu/sub-components/header-unauth.js b/packages/client/src/components/NavMenu/sub-components/header-unauth.js index 62b4f004d7..e82c68ad17 100644 --- a/packages/client/src/components/NavMenu/sub-components/header-unauth.js +++ b/packages/client/src/components/NavMenu/sub-components/header-unauth.js @@ -4,9 +4,8 @@ import styled from "styled-components"; import Box from "@docspace/components/box"; import { useTranslation } from "react-i18next"; import { inject, observer } from "mobx-react"; -import { combineUrl } from "@docspace/common/utils"; import { Base } from "@docspace/components/themes"; -import { hugeMobile } from "@docspace/components/utils/device"; +import { mobile } from "@docspace/components/utils/device"; const Header = styled.header` align-items: left; @@ -19,10 +18,8 @@ const Header = styled.header` .header-items-wrapper { width: 960px; - @media (max-width: 768px) { + @media ${mobile} { width: 475px; - } - @media ${hugeMobile} { display: flex; align-items: center; justify-content: center; diff --git a/packages/client/src/components/NavMenu/sub-components/header.js b/packages/client/src/components/NavMenu/sub-components/header.js index 42ef7df252..82f67de7e0 100644 --- a/packages/client/src/components/NavMenu/sub-components/header.js +++ b/packages/client/src/components/NavMenu/sub-components/header.js @@ -137,6 +137,8 @@ const HeaderComponent = ({ const location = useLocation(); + const isFormGallery = location.pathname.includes("/form-gallery"); + //const isNavAvailable = mainModules.length > 0; // const onLogoClick = () => { @@ -202,15 +204,6 @@ const HeaderComponent = ({ return () => window.removeEventListener("resize", onResize); }); - const [isFormGallery, setIsFormGallery] = useState( - location.pathname.includes("/form-gallery") - ); - useEffect(() => { - return () => { - setIsFormGallery(location.pathname.includes("/form-gallery")); - }; - }, [location]); - const logo = getLogoFromPath( !theme.isBase ? logoUrl?.path?.dark : logoUrl?.path?.light ); diff --git a/packages/client/src/components/NavMenu/sub-components/profile-actions.js b/packages/client/src/components/NavMenu/sub-components/profile-actions.js index 26580a0935..3f1c5f7136 100644 --- a/packages/client/src/components/NavMenu/sub-components/profile-actions.js +++ b/packages/client/src/components/NavMenu/sub-components/profile-actions.js @@ -1,7 +1,6 @@ import React from "react"; import PropTypes from "prop-types"; import styled, { css } from "styled-components"; -import { isMobileOnly } from "react-device-detect"; import Avatar from "@docspace/components/avatar"; import DropDownItem from "@docspace/components/drop-down-item"; @@ -15,26 +14,22 @@ import Button from "@docspace/components/button"; const StyledDiv = styled.div` width: 32px; height: 32px; - - ${isMobileOnly && - css` - @media (min-width: 428px) { - .backdrop-active { - background-color: unset; - backdrop-filter: unset; - } - } - `} `; const StyledButtonWrapper = styled.div` width: 100%; - padding: 12px 16px; - box-sizing: border-box; `; +const StyledDropDownItem = styled(DropDownItem)` + padding: 0px 16px; + .drop-down-icon { + margin-right: 12px; + height: 22px; + } +`; + class ProfileActions extends React.PureComponent { constructor(props) { super(props); @@ -171,7 +166,7 @@ class ProfileActions extends React.PureComponent { href={action.url} onClick={this.onClickItemLink} > - + )) )} diff --git a/packages/client/src/components/NavMenu/sub-components/profile-menu.js b/packages/client/src/components/NavMenu/sub-components/profile-menu.js index 7ba51569e3..cfb26100a6 100644 --- a/packages/client/src/components/NavMenu/sub-components/profile-menu.js +++ b/packages/client/src/components/NavMenu/sub-components/profile-menu.js @@ -7,20 +7,13 @@ import DropDown from "@docspace/components/drop-down"; import styled, { css, withTheme } from "styled-components"; import DropDownItem from "@docspace/components/drop-down-item"; -import { isMobileOnly } from "react-device-detect"; + import { Base } from "@docspace/components/themes"; import { mobile, tablet } from "@docspace/components/utils/device"; import CrossIcon from "PUBLIC_DIR/images/cross.react.svg"; import Portal from "@docspace/components/portal"; -const StyledWrapper = styled.div` - @media (min-width: 428px) { - .backdrop-active { - background-color: unset; - backdrop-filter: unset; - } - } -`; +const StyledWrapper = styled.div``; const StyledDropDown = styled(DropDown)` z-index: 500 !important; @@ -40,7 +33,7 @@ const StyledDropDown = styled(DropDown)` : `right: 16px !important;`} } - @media (max-width: 428px) { + @media ${mobile} { position: fixed; top: unset !important; @@ -69,7 +62,7 @@ const StyledControlContainer = styled.div` justify-content: center; z-index: 290; - @media (max-width: 428px) { + @media ${mobile} { display: flex; } `; @@ -106,6 +99,7 @@ export const StyledProfileMenu = styled(DropDownItem)` cursor: pointer; display: inline-block; margin-top: -6px; + max-width: 600px; `; export const MenuContainer = styled.div` @@ -121,8 +115,11 @@ export const MenuContainer = styled.div` cursor: default; box-sizing: border-box; + background: red; + @media ${mobile} { max-width: 100vw; + background: ${(props) => props.theme.menuContainer.background}; } .avatar { @@ -176,20 +173,19 @@ class ProfileMenu extends React.Component { forwardedRef, isBannerVisible, } = this.props; - console.log('Current theme: ', this.props.theme) + // console.log("Current theme: ", this.props.theme); return ( @@ -219,15 +215,11 @@ class ProfileMenu extends React.Component { const element = this.renderDropDown(); - if (isMobileOnly) { - const root = document.getElementById("root"); + const root = document.getElementById("root"); - const wrapper = {element}; + const wrapper = {element}; - return <>{}; - } - - return <>{element}; + return <>{}; } } diff --git a/packages/client/src/components/PeopleSelector/i18n.js b/packages/client/src/components/PeopleSelector/i18n.js index c6394afad7..1c77e610e0 100644 --- a/packages/client/src/components/PeopleSelector/i18n.js +++ b/packages/client/src/components/PeopleSelector/i18n.js @@ -3,7 +3,7 @@ import { initReactI18next } from "react-i18next"; import Backend from "@docspace/common/utils/i18next-http-backend"; import { LANGUAGE } from "@docspace/common/constants"; import config from "PACKAGE_FILE"; -import { getCookie } from "@docspace/common/utils"; +import { getCookie } from "@docspace/components/utils/cookie"; import { loadLanguagePath } from "SRC_DIR/helpers/utils"; const newInstance = i18n.createInstance(); diff --git a/packages/client/src/components/QuickButtons.js b/packages/client/src/components/QuickButtons.js index 2daf90d720..3a9e742d39 100644 --- a/packages/client/src/components/QuickButtons.js +++ b/packages/client/src/components/QuickButtons.js @@ -7,7 +7,7 @@ import React from "react"; import styled from "styled-components"; import IconButton from "@docspace/components/icon-button"; import commonIconsStyles from "@docspace/components/utils/common-icons-style"; -import { isMobile, isTablet } from "react-device-detect"; +import { isTablet } from "@docspace/components/utils/device"; import { FileStatus } from "@docspace/common/constants"; import { ColorTheme, ThemeType } from "@docspace/components/ColorTheme"; @@ -48,8 +48,7 @@ const QuickButtons = (props) => { ? theme.filesQuickButtons.sharedColor : theme.filesQuickButtons.color; - const tabletViewQuickButton = - (sectionWidth > 500 && sectionWidth <= 1024) || isTablet; + const tabletViewQuickButton = isTablet(); const sizeQuickButton = isTile || tabletViewQuickButton ? "medium" : "small"; diff --git a/packages/client/src/components/RoomSelector/index.js b/packages/client/src/components/RoomSelector/index.js index d9d42decf5..2521dbb710 100644 --- a/packages/client/src/components/RoomSelector/index.js +++ b/packages/client/src/components/RoomSelector/index.js @@ -41,8 +41,9 @@ const convertToItems = (folders) => { const { id, title, roomType, logo } = folder; const icon = logo.medium ? logo.medium : getRoomLogo(roomType); + const color = logo.color; - return { id, label: title, icon }; + return { id, label: title, icon, color }; }); return items; diff --git a/packages/client/src/components/SmartBanner/index.js b/packages/client/src/components/SmartBanner/index.js index eb1f09ed0b..746450a1dd 100644 --- a/packages/client/src/components/SmartBanner/index.js +++ b/packages/client/src/components/SmartBanner/index.js @@ -15,8 +15,6 @@ const ReactSmartBanner = (props) => { const force = isIOS ? "ios" : "android"; const location = useLocation(); - const [isDocuments, setIsDocuments] = useState(false); - const getCookie = (name) => { let matches = document.cookie.match( new RegExp( @@ -28,23 +26,26 @@ const ReactSmartBanner = (props) => { return matches ? decodeURIComponent(matches[1]) : undefined; }; - const hideBanner = () => { - setIsBannerVisible(false); + const checkBanner = () => { + const cookieClosed = getCookie("smartbanner-closed"); + const cookieInstalled = getCookie("smartbanner-installed"); + const path = window.location.pathname.toLowerCase(); + if ( + (path.includes("rooms") || path.includes("files")) && + !(cookieClosed || cookieInstalled) + ) { + setIsBannerVisible(true); + } else { + setIsBannerVisible(false); + } }; useEffect(() => { - const cookieClosed = getCookie("smartbanner-closed"); - const cookieInstalled = getCookie("smartbanner-installed"); - if (cookieClosed || cookieInstalled) hideBanner(); + checkBanner(); }, []); useEffect(() => { - const path = window.location.pathname.toLowerCase(); - if (path.includes("rooms") || path.includes("files")) { - setIsDocuments(true); - } else { - setIsDocuments(false); - } + checkBanner(); }, [location]); const storeText = { @@ -73,19 +74,15 @@ const ReactSmartBanner = (props) => { navigator.maxTouchPoints > 0 || navigator.msMaxTouchPoints > 0; - return isMobile && - isBannerVisible && - ready && - isTouchDevice && - isDocuments ? ( + return isMobile && isBannerVisible && ready && isTouchDevice ? ( setIsBannerVisible(false)} + onInstall={() => setIsBannerVisible(false)} storeText={storeText} price={priceText} appMeta={appMeta} diff --git a/packages/client/src/components/dialogs/BackupCodesDialog/index.js b/packages/client/src/components/dialogs/BackupCodesDialog/index.js index f331917281..fabc2e7800 100644 --- a/packages/client/src/components/dialogs/BackupCodesDialog/index.js +++ b/packages/client/src/components/dialogs/BackupCodesDialog/index.js @@ -8,7 +8,9 @@ import { withTranslation } from "react-i18next"; import ModalDialogContainer from "../ModalDialogContainer"; import toastr from "@docspace/components/toast/toastr"; import Link from "@docspace/components/link"; -import { isMobile } from "react-device-detect"; + +import { DeviceType } from "@docspace/common/constants"; +import { isDesktop } from "@docspace/components/utils/device"; const StyledModal = styled(ModalDialogContainer)` .backup-codes-counter { @@ -116,7 +118,7 @@ class BackupCodesDialogComponent extends React.Component { size="normal" onClick={this.props.onClose} /> - {!isMobile && ( + {isDesktop() && (
{
{t("OverwriteTitle")} - {" "} {t("OverwriteDescription")}
@@ -196,12 +199,6 @@ const ConflictResolveDialog = (props) => { }, ]; - const filesCount = items.length; - const singleFile = filesCount === 1; - const file = items[0].title; - - const obj = { file, folder: folderTitle }; - return ( { {t("ConflictResolveTitle")} - {singleFile ? ( + {items.length === 1 ? ( + i18nKey="ConflictResolveDescription" + values={{ file: items[0].title, folder: folderTitle }} + components={{ 1: }} + /> ) : ( + i18nKey="ConflictResolveDescriptionFiles" + values={{ filesCount: items.length, folder: folderTitle }} + components={{ 1: }} + /> )} diff --git a/packages/client/src/components/dialogs/CreateEditRoomDialog/sub-components/ChangeRoomOwner/index.js b/packages/client/src/components/dialogs/CreateEditRoomDialog/sub-components/ChangeRoomOwner/index.js new file mode 100644 index 0000000000..df47431186 --- /dev/null +++ b/packages/client/src/components/dialogs/CreateEditRoomDialog/sub-components/ChangeRoomOwner/index.js @@ -0,0 +1,60 @@ +import { inject } from "mobx-react"; +import { withTranslation } from "react-i18next"; + +import Text from "@docspace/components/text"; +import Link from "@docspace/components/link"; +import Avatar from "@docspace/components/avatar"; + +import * as Styled from "./index.styled"; + +const ChangeRoomOwner = ({ + t, + currentUserId, + roomOwner, + onOwnerChange, + currentColorScheme, +}) => { + return ( + + + {t("Files:RoomOwner")} + + +
+ +
+ + {roomOwner.displayName} + + {roomOwner?.id === currentUserId && ( + ({t("Common:MeLabel")}) + )} +
+
+ + + {t("Common:ChangeButton")} + +
+ ); +}; + +export default inject(({ auth, dialogsStore }) => ({ + currentUserId: auth.userStore.user.id, + currentColorScheme: auth.settingsStore.currentColorScheme, +}))(withTranslation(["Common"])(ChangeRoomOwner)); diff --git a/packages/client/src/components/dialogs/CreateEditRoomDialog/sub-components/ChangeRoomOwner/index.styled.js b/packages/client/src/components/dialogs/CreateEditRoomDialog/sub-components/ChangeRoomOwner/index.styled.js new file mode 100644 index 0000000000..f883196540 --- /dev/null +++ b/packages/client/src/components/dialogs/CreateEditRoomDialog/sub-components/ChangeRoomOwner/index.styled.js @@ -0,0 +1,23 @@ +import { Base } from "@docspace/components/themes"; +import styled from "styled-components"; + +export const ChangeRoomOwner = styled.div` + .change-owner-display { + display: flex; + align-items: center; + gap: 8px; + margin: 8px 0; + + .change-owner-display-name { + display: flex; + align-items: center; + gap: 4px; + + .me-label { + color: ${({ theme }) => theme.text.disableColor}; + } + } + } +`; + +ChangeRoomOwner.defaultProps = { theme: Base }; diff --git a/packages/client/src/components/dialogs/CreateEditRoomDialog/sub-components/RoomTypeDropdown/index.js b/packages/client/src/components/dialogs/CreateEditRoomDialog/sub-components/RoomTypeDropdown/index.js index 6cba474b4d..7ba3dc4ee7 100644 --- a/packages/client/src/components/dialogs/CreateEditRoomDialog/sub-components/RoomTypeDropdown/index.js +++ b/packages/client/src/components/dialogs/CreateEditRoomDialog/sub-components/RoomTypeDropdown/index.js @@ -1,4 +1,4 @@ -import { isHugeMobile } from "@docspace/components/utils/device"; +import { isMobile } from "@docspace/components/utils/device"; import React, { useState } from "react"; import styled from "styled-components"; import RoomType from "../RoomType"; @@ -53,7 +53,7 @@ const RoomTypeDropdown = ({ isOpen={isOpen} onClick={toggleDropdown} /> - {isHugeMobile() ? ( + {isMobile() ? ( props.currentColorScheme.main.accent}; - } - - .me-label { - color: ${(props) => props.theme.text.disableColor}; - } -`; - -const StyledIcon = styled.img` - ${NoUserSelect} `; const SetRoomParams = ({ @@ -81,9 +55,7 @@ const SetRoomParams = ({ setIsValidTitle, onKeyUp, enableThirdParty, - currentColorScheme, setChangeRoomOwnerIsVisible, - userId, isAdmin, }) => { const [previewIcon, setPreviewIcon] = React.useState(null); @@ -109,11 +81,8 @@ const SetRoomParams = ({ ); }; - const isMe = userId === roomParams?.roomOwner?.id; - const canOwnerChange = isAdmin || isMe; - return ( - + {isEdit ? ( ) : ( @@ -153,6 +122,7 @@ const SetRoomParams = ({ setIsScrollLocked={setIsScrollLocked} isDisabled={isDisabled} /> + {/* //TODO: Uncomment when private rooms are done {!isEdit && ( )} */} + {(isAdmin || isMe) && roomParams.roomOwner && ( + + )} + {isVDRRoom && } {canOwnerChange && roomParams.roomOwner && ( @@ -209,6 +186,7 @@ const SetRoomParams = ({ isDisabled={isDisabled} /> )} +
{t("Icon")} @@ -240,13 +218,10 @@ const SetRoomParams = ({ }; export default inject(({ auth, dialogsStore }) => { - const { currentColorScheme } = auth.settingsStore; const { user } = auth.userStore; const { setChangeRoomOwnerIsVisible } = dialogsStore; return { - currentColorScheme, setChangeRoomOwnerIsVisible, - userId: user.id, isAdmin: user.isAdmin || user.isOwner, }; })( diff --git a/packages/client/src/components/dialogs/CreateEditRoomDialog/sub-components/StyledDropdown.js b/packages/client/src/components/dialogs/CreateEditRoomDialog/sub-components/StyledDropdown.js index e23dd44b43..833dc3b694 100644 --- a/packages/client/src/components/dialogs/CreateEditRoomDialog/sub-components/StyledDropdown.js +++ b/packages/client/src/components/dialogs/CreateEditRoomDialog/sub-components/StyledDropdown.js @@ -1,6 +1,6 @@ import styled from "styled-components"; -import { smallTablet } from "@docspace/components/utils/device"; +import { mobile } from "@docspace/components/utils/device"; import DropDown from "@docspace/components/drop-down"; import { Base } from "@docspace/components/themes"; @@ -28,7 +28,7 @@ const StyledDropDown = styled(DropDown)` max-width: 446px; } - @media ${smallTablet} { + @media ${mobile} { width: calc(100vw - 34px); max-width: calc(100vw - 34px); div { diff --git a/packages/client/src/components/dialogs/CreateEditRoomDialog/sub-components/TagInput/TagDropdown.js b/packages/client/src/components/dialogs/CreateEditRoomDialog/sub-components/TagInput/TagDropdown.js index 93b83f91d7..76884bb575 100644 --- a/packages/client/src/components/dialogs/CreateEditRoomDialog/sub-components/TagInput/TagDropdown.js +++ b/packages/client/src/components/dialogs/CreateEditRoomDialog/sub-components/TagInput/TagDropdown.js @@ -3,7 +3,7 @@ import React, { useRef, useState, useEffect } from "react"; import { StyledDropDown, StyledDropDownWrapper } from "../StyledDropdown"; import DropDownItem from "@docspace/components/drop-down-item"; -import { isHugeMobile } from "@docspace/components/utils/device"; +import { isMobile } from "@docspace/components/utils/device"; import DomHelpers from "@docspace/components/utils/domHelpers"; const TagDropdown = ({ @@ -97,7 +97,7 @@ const TagDropdown = ({ const { top: offsetTop } = DomHelpers.getOffset(dropdownRef.current); const offsetBottom = window.innerHeight - offsetTop; const maxHeight = Math.floor((offsetBottom - 22) / 32) * 32 - 2; - const result = isHugeMobile() + const result = isMobile() ? Math.min(maxHeight, 158) : Math.min(maxHeight, 382); setDropdownMaxHeight(result); diff --git a/packages/client/src/components/dialogs/CreateEditRoomDialog/sub-components/ThirdPartyStorage/ThirdPartyComboBox.js b/packages/client/src/components/dialogs/CreateEditRoomDialog/sub-components/ThirdPartyStorage/ThirdPartyComboBox.js index eb54d54e99..a1b0cdd5eb 100644 --- a/packages/client/src/components/dialogs/CreateEditRoomDialog/sub-components/ThirdPartyStorage/ThirdPartyComboBox.js +++ b/packages/client/src/components/dialogs/CreateEditRoomDialog/sub-components/ThirdPartyStorage/ThirdPartyComboBox.js @@ -5,7 +5,7 @@ import { ReactSVG } from "react-svg"; import { StyledDropDown, StyledDropDownWrapper } from "../StyledDropdown"; -import { isHugeMobile } from "@docspace/components/utils/device"; +import { isMobile } from "@docspace/components/utils/device"; import DomHelpers from "@docspace/components/utils/domHelpers"; import Text from "@docspace/components/text"; @@ -157,9 +157,7 @@ const ThirdPartyComboBox = ({ const neededHeightDesktop = Math.min(thirdparties.length * 32 + 16, 404); const neededHeightMobile = Math.min(thirdparties.length * 32 + 16, 180); - const neededheight = isHugeMobile() - ? neededHeightMobile - : neededHeightDesktop; + const neededheight = isMobile() ? neededHeightMobile : neededHeightDesktop; setDropdownDirection(neededheight > offsetBottom ? "top" : "bottom"); }; @@ -262,7 +260,7 @@ const ThirdPartyComboBox = ({ open={isOpen} forwardedRef={dropdownRef} clickOutsideAction={toggleIsOpen} - maxHeight={isHugeMobile() ? 158 : 382} + maxHeight={isMobile() ? 158 : 382} directionY={dropdownDirection} marginTop={dropdownDirection === "bottom" ? "4px" : "-36px"} hasItems={isOpen} diff --git a/packages/client/src/components/dialogs/DeleteDialog/index.js b/packages/client/src/components/dialogs/DeleteDialog/index.js index fdb8cf7901..4e86492a9d 100644 --- a/packages/client/src/components/dialogs/DeleteDialog/index.js +++ b/packages/client/src/components/dialogs/DeleteDialog/index.js @@ -134,14 +134,14 @@ const DeleteDialogComponent = (props) => { <> <>{t("DeleteFile")} <>{t("FilePermanentlyDeleted")} - <>{t("WantToContinue")} + <>{t("Common:WantToContinue")} ) ) : ( <> <>{t("DeleteItems")} <>{t("ItemsPermanentlyDeleted")} - <>{t("WantToContinue")} + <>{t("Common:WantToContinue")} ); } @@ -152,20 +152,20 @@ const DeleteDialogComponent = (props) => { <> <>{t("DeleteFolder")} <>{t("FolderPermanentlyDeleted")} - <>{t("WantToContinue")} + <>{t("Common:WantToContinue")} ) : ( <> <>{t("DeleteFile")} <>{t("FilePermanentlyDeleted")} - <>{t("WantToContinue")} + <>{t("Common:WantToContinue")} ) ) : ( <> <>{t("DeleteItems")} <>{t("ItemsPermanentlyDeleted")} - <>{t("WantToContinue")} + <>{t("Common:WantToContinue")} ); } @@ -177,7 +177,7 @@ const DeleteDialogComponent = (props) => { <>{t("DeleteFolder")} <>{t("DeleteSharedNote")} <>{t("FolderPermanentlyDeleted")} - <>{t("WantToContinue")} + <>{t("Common:WantToContinue")} ) : ( t("MoveToTrashFile") @@ -187,7 +187,7 @@ const DeleteDialogComponent = (props) => { <>{t("DeleteItems")} <>{t("DeleteItemsSharedNote")} <>{t("ItemsPermanentlyDeleted")} - <>{t("WantToContinue")} + <>{t("Common:WantToContinue")} ); } diff --git a/packages/client/src/components/dialogs/DeleteProfileEverDialog/index.js b/packages/client/src/components/dialogs/DeleteProfileEverDialog/index.js index 84e9bac785..a297317db4 100644 --- a/packages/client/src/components/dialogs/DeleteProfileEverDialog/index.js +++ b/packages/client/src/components/dialogs/DeleteProfileEverDialog/index.js @@ -11,7 +11,7 @@ import ModalDialogContainer from "../ModalDialogContainer"; import Link from "@docspace/components/link"; import { inject, observer } from "mobx-react"; import styled, { css } from "styled-components"; -import { size } from "@docspace/components/utils/device"; +import { mobileMore } from "@docspace/components/utils/device"; const { deleteUser } = api.people; const { Filter } = api; @@ -23,7 +23,7 @@ const StyledModalDialogContainer = styled(ModalDialogContainer)` css` width: auto; - @media (min-width: ${size.smallTablet}px) { + @media ${mobileMore} { .delete-button, .cancel-button { width: auto; diff --git a/packages/client/src/components/dialogs/PreparationPortalDialog/i18n.js b/packages/client/src/components/dialogs/PreparationPortalDialog/i18n.js index e917e1e116..8763c222f5 100644 --- a/packages/client/src/components/dialogs/PreparationPortalDialog/i18n.js +++ b/packages/client/src/components/dialogs/PreparationPortalDialog/i18n.js @@ -3,7 +3,7 @@ import { initReactI18next } from "react-i18next"; import Backend from "@docspace/common/utils/i18next-http-backend"; import { LANGUAGE } from "@docspace/common/constants"; import config from "PACKAGE_FILE"; -import { getCookie } from "@docspace/common/utils"; +import { getCookie } from "@docspace/components/utils/cookie"; import { loadLanguagePath } from "SRC_DIR/helpers/utils"; const newInstance = i18n.createInstance(); diff --git a/packages/client/src/components/dialogs/ReportDialog/index.js b/packages/client/src/components/dialogs/ReportDialog/index.js index baf799ecf4..98d9905849 100644 --- a/packages/client/src/components/dialogs/ReportDialog/index.js +++ b/packages/client/src/components/dialogs/ReportDialog/index.js @@ -5,7 +5,6 @@ import React, { useEffect, useState } from "react"; import styled from "styled-components"; import { useTranslation } from "react-i18next"; import { inject, observer } from "mobx-react"; -import { isMobileOnly } from "react-device-detect"; import ModalDialog from "@docspace/components/modal-dialog"; import Text from "@docspace/components/text"; @@ -19,6 +18,7 @@ import { downloadJson, getCurrentDate, } from "SRC_DIR/helpers/crashReport"; +import { DeviceType } from "@docspace/common/constants"; const ModalDialogContainer = styled(ModalDialog)` #modal-dialog { @@ -55,7 +55,15 @@ const ModalDialogContainer = styled(ModalDialog)` const ReportDialog = (props) => { const { t, ready } = useTranslation(["Common"]); - const { visible, onClose, error, user, version, FirebaseHelper } = props; + const { + visible, + onClose, + error, + user, + version, + FirebaseHelper, + currentDeviceType, + } = props; const [report, setReport] = useState({}); const [description, setDescription] = useState(""); @@ -138,14 +146,14 @@ const ReportDialog = (props) => { label={t("SendButton")} size="normal" primary - scale={isMobileOnly} + scale={currentDeviceType === DeviceType.mobile} onClick={onClickSend} />
); @@ -87,8 +95,13 @@ const MembersList = (props) => { itemCount, onRepeatInvitation, loadNextPage, + membersFilter, + setMembersFilter, + fetchMembers, } = props; + const { interfaceDirection } = useTheme(); + const itemsCount = hasNextPage ? members.length + 1 : members.length; const canInviteUserInRoomAbility = security?.EditAccess; @@ -147,7 +160,7 @@ const MembersList = (props) => { {({ height, width }) => ( {({ onItemsRendered, ref }) => { @@ -155,6 +168,7 @@ const MembersList = (props) => { return ( { setMembers, canInviteUserInRoomAbility, onRepeatInvitation, + membersFilter, + setMembersFilter, + fetchMembers, + hasNextPage, }} outerElementType={CustomScrollbarsVirtualList} onItemsRendered={onItemsRendered} diff --git a/packages/client/src/pages/Home/InfoPanel/Body/views/Members/User.js b/packages/client/src/pages/Home/InfoPanel/Body/views/Members/User.js index 6b987785ab..d327c81e1c 100644 --- a/packages/client/src/pages/Home/InfoPanel/Body/views/Members/User.js +++ b/packages/client/src/pages/Home/InfoPanel/Body/views/Members/User.js @@ -29,6 +29,10 @@ const User = ({ isTitle, onRepeatInvitation, showInviteIcon, + membersFilter, + setMembersFilter, + fetchMembers, + hasNextPage, }) => { if (!selectionParentRoom) return null; if (!user.displayName && !user.email) return null; @@ -54,29 +58,84 @@ const User = ({ notify: false, sharingMessage: "", }) - .then(() => { + .then(async () => { setIsLoading(false); const users = selectionParentRoom.members.users; const administrators = selectionParentRoom.members.administrators; const expectedMembers = selectionParentRoom.members.expected; if (option.key === "remove") { - setMembers({ + const newMembersFilter = JSON.parse(JSON.stringify(membersFilter)); + + const newMembers = { users: users?.filter((m) => m.id !== user.id), administrators: administrators?.filter((m) => m.id !== user.id), expected: expectedMembers?.filter((m) => m.id !== user.id), + }; + + const roomId = selectionParentRoom.id; + const newUsers = newMembers.users.length > 1 ? newMembers?.users : []; + const newAdministrators = + newMembers.administrators.length > 1 + ? newMembers?.administrators + : []; + const newExpected = + newMembers.expected.length > 1 ? newMembers?.expected : []; + + setMembers({ + roomId, + users: newUsers, + administrators: newAdministrators, + expected: newExpected, }); + newMembersFilter.total -= 1; + setSelectionParentRoom({ ...selectionParentRoom, members: { - users: users?.filter((m) => m.id !== user.id), - administrators: administrators?.filter((m) => m.id !== user.id), - expected: expectedMembers?.filter((m) => m.id !== user.id), + users: newUsers, + administrators: newAdministrators, + expected: newExpected, }, }); + + if (hasNextPage) { + newMembersFilter.startIndex = + (newMembersFilter.page + 1) * newMembersFilter.pageCount - 1; + newMembersFilter.pageCount = 1; + + const fetchedMembers = await fetchMembers( + selectionParentRoom.id, + false, + newMembersFilter + ); + + const newMembers = { + administrators: [ + ...newAdministrators, + ...fetchedMembers.administrators, + ], + users: [...newUsers, ...fetchedMembers.users], + expected: [...newExpected, ...fetchedMembers.expected], + }; + + setMembers({ + roomId: selectionParentRoom.id, + ...newMembers, + }); + + setSelectionParentRoom({ + ...selectionParentRoom, + members: newMembers, + }); + } + + setMembersFilter(newMembersFilter); + //setUserIsRemoved(true); } else { setMembers({ + roomId: selectionParentRoom.id, users: users?.map((m) => m.id === user.id ? { ...m, access: option.access } : m ), diff --git a/packages/client/src/pages/Home/InfoPanel/Body/views/Members/index.js b/packages/client/src/pages/Home/InfoPanel/Body/views/Members/index.js index 602974393e..f243ca1c85 100644 --- a/packages/client/src/pages/Home/InfoPanel/Body/views/Members/index.js +++ b/packages/client/src/pages/Home/InfoPanel/Body/views/Members/index.js @@ -37,6 +37,7 @@ const Members = ({ setExternalLinks, membersFilter, + setMembersFilter, externalLinks, members, setMembersList, @@ -67,7 +68,7 @@ const Members = ({ const users = []; const administrators = []; const expectedMembers = []; - data.map((fetchedMember) => { + data?.map((fetchedMember) => { const member = { access: fetchedMember.access, canEditAccess: fetchedMember.canEditAccess, @@ -88,7 +89,7 @@ const Members = ({ }); let hasPrevAdminsTitle = - members?.roomId === roomId + members?.roomId === roomId && !clearFilter ? getHasPrevTitle(members?.administrators, "administration") : false; @@ -101,7 +102,7 @@ const Members = ({ } let hasPrevUsersTitle = - members?.roomId === roomId + members?.roomId === roomId && !clearFilter ? getHasPrevTitle(members?.users, "user") : false; @@ -110,7 +111,7 @@ const Members = ({ } let hasPrevExpectedTitle = - members?.roomId === roomId + members?.roomId === roomId && !clearFilter ? getHasPrevTitle(members?.expected, "expected") : false; @@ -191,6 +192,7 @@ const Members = ({ const { users, administrators, expected } = fetchedMembers; const newMembers = { + roomId: roomId, administrators: [...members.administrators, ...administrators], users: [...members.users, ...users], expected: [...members.expected, ...expected], @@ -230,6 +232,8 @@ const Members = ({ setSelectionParentRoom={setSelectionParentRoom} changeUserType={changeUserType} setIsScrollLocked={setIsScrollLocked} + membersFilter={membersFilter} + setMembersFilter={setMembersFilter} hasNextPage={membersList.length - headersCount < membersFilter.total} itemCount={membersFilter.total + headersCount} onRepeatInvitation={onRepeatInvitation} @@ -262,6 +266,7 @@ export default inject( updateRoomMemberRole, resendEmailInvitations, membersFilter, + setMembersFilter, } = filesStore; const { id: selfId } = auth.userStore.user; @@ -296,6 +301,7 @@ export default inject( isPublicRoomType, setExternalLinks, membersFilter, + setMembersFilter, externalLinks: roomLinks, members: membersList, setMembersList, diff --git a/packages/client/src/pages/Home/InfoPanel/Header/index.js b/packages/client/src/pages/Home/InfoPanel/Header/index.js index 31f6fe2e7f..669e9adec5 100644 --- a/packages/client/src/pages/Home/InfoPanel/Header/index.js +++ b/packages/client/src/pages/Home/InfoPanel/Header/index.js @@ -2,23 +2,19 @@ import React, { useState, useEffect } from "react"; import { inject, observer } from "mobx-react"; import { withTranslation } from "react-i18next"; -import { isMobile as isMobileRDD } from "react-device-detect"; import IconButton from "@docspace/components/icon-button"; import Text from "@docspace/components/text"; -import Loaders from "@docspace/common/components/Loaders"; -import withLoader from "@docspace/client/src/HOCs/withLoader"; + import Submenu from "@docspace/components/submenu"; import { isDesktop as isDesktopUtils, - isSmallTablet as isSmallTabletUtils, + isMobile as isMobileUtils, isTablet as isTabletUtils, } from "@docspace/components/utils/device"; -import { ColorTheme, ThemeType } from "@docspace/components/ColorTheme"; - import { StyledInfoPanelHeader } from "./styles/common"; -import { FolderType } from "@docspace/common/constants"; + import { PluginFileType } from "SRC_DIR/helpers/plugins/constants"; const InfoPanelHeaderContent = (props) => { @@ -58,8 +54,7 @@ const InfoPanelHeaderContent = (props) => { }, []); const checkWidth = () => { - const isTablet = - isTabletUtils() || isSmallTabletUtils() || !isDesktopUtils(); + const isTablet = isTabletUtils() || isMobileUtils() || !isDesktopUtils(); setIsTablet(isTablet); }; @@ -181,14 +176,12 @@ const InfoPanelHeaderContent = (props) => { style={{ width: "100%" }} data={roomsSubmenu} forsedActiveItemId={roomsView} - size="scale" /> ) : ( )}
diff --git a/packages/client/src/pages/Home/Section/AccountsBody/RowView/PeopleRowContainer.js b/packages/client/src/pages/Home/Section/AccountsBody/RowView/PeopleRowContainer.js index 8d6df63ea6..7b3ab87a36 100644 --- a/packages/client/src/pages/Home/Section/AccountsBody/RowView/PeopleRowContainer.js +++ b/packages/client/src/pages/Home/Section/AccountsBody/RowView/PeopleRowContainer.js @@ -1,7 +1,6 @@ import React, { useEffect } from "react"; import styled, { css } from "styled-components"; import { inject, observer } from "mobx-react"; -import { isMobile } from "react-device-detect"; import RowContainer from "@docspace/components/row-container"; @@ -9,6 +8,8 @@ import EmptyScreen from "../EmptyScreen"; import SimpleUserRow from "./SimpleUserRow"; import withLoader from "SRC_DIR/HOCs/withLoader"; +import { mobile, size, tablet } from "@docspace/components/utils/device"; +import { DeviceType } from "@docspace/common/constants"; const marginStyles = css` margin-left: -24px; @@ -16,43 +17,18 @@ const marginStyles = css` padding-left: 24px; padding-right: 24px; - ${isMobile && - css` - margin-left: -20px; - margin-right: -20px; - padding-left: 20px; - padding-right: 20px; - `} - - @media (max-width: 1024px) { + @media ${tablet} { margin-left: -16px; margin-right: -16px; padding-left: 16px; padding-right: 16px; } - - @media (max-width: 375px) { - ${props => - props.theme.interfaceDirection === "rtl" - ? css` - margin-right: -16px; - margin-left: -8px; - padding-right: 16px; - padding-left: 8px; - ` - : css` - margin-left: -16px; - margin-right: -8px; - padding-left: 16px; - padding-right: 8px; - `} - } `; const StyledRowContainer = styled(RowContainer)` .row-selected + .row-wrapper:not(.row-selected) { .user-row { - border-top: ${props => + border-top: ${(props) => `1px ${props.theme.filesSection.tableView.row.borderColor} solid`}; margin-top: -3px; @@ -62,7 +38,7 @@ const StyledRowContainer = styled(RowContainer)` .row-wrapper:not(.row-selected) + .row-selected { .user-row { - border-top: ${props => + border-top: ${(props) => `1px ${props.theme.filesSection.tableView.row.borderColor} solid`}; margin-top: -3px; @@ -78,7 +54,7 @@ const StyledRowContainer = styled(RowContainer)` .row-selected:last-child { .user-row { - border-bottom: ${props => + border-bottom: ${(props) => `1px ${props.theme.filesSection.tableView.row.borderColor} solid`}; padding-bottom: 1px; @@ -90,7 +66,7 @@ const StyledRowContainer = styled(RowContainer)` } .row-selected:first-child { .user-row { - border-top: ${props => + border-top: ${(props) => `1px ${props.theme.filesSection.tableView.row.borderColor} solid`}; margin-top: -3px; @@ -111,6 +87,7 @@ const PeopleRowContainer = ({ hasMoreAccounts, filterTotal, withPaging, + currentDeviceType, }) => { useEffect(() => { const width = window.innerWidth; @@ -120,18 +97,18 @@ const PeopleRowContainer = ({ !sectionWidth ) return; - // 400 - it is desktop info panel width + if ( (width < 1025 && !infoPanelVisible) || ((width < 625 || (accountsViewAs === "row" && width < 1025)) && infoPanelVisible) || - isMobile + currentDeviceType !== DeviceType.desktop ) { accountsViewAs !== "row" && setViewAs("row"); } else { accountsViewAs !== "table" && setViewAs("table"); } - }, [sectionWidth]); + }, [sectionWidth, currentDeviceType]); return peopleList.length !== 0 || !isFiltered ? ( + itemHeight={58} + > {peopleList.map((item, index) => ( { viewAs: accountsViewAs, setViewAs, } = peopleStore; - const { theme, withPaging } = auth.settingsStore; + const { theme, withPaging, currentDeviceType } = auth.settingsStore; const { peopleList, hasMoreAccounts, fetchMoreAccounts } = usersStore; const { filterTotal, isFiltered } = filterStore; @@ -182,5 +160,6 @@ export default inject(({ peopleStore, auth, filesStore }) => { hasMoreAccounts, filterTotal, isFiltered, + currentDeviceType, }; })(observer(PeopleRowContainer)); diff --git a/packages/client/src/pages/Home/Section/AccountsBody/RowView/SimpleUserRow.js b/packages/client/src/pages/Home/Section/AccountsBody/RowView/SimpleUserRow.js index 50b49d9ce6..70a83a5c0f 100644 --- a/packages/client/src/pages/Home/Section/AccountsBody/RowView/SimpleUserRow.js +++ b/packages/client/src/pages/Home/Section/AccountsBody/RowView/SimpleUserRow.js @@ -8,6 +8,7 @@ import { Base } from "@docspace/components/themes"; import withContent from "SRC_DIR/HOCs/withPeopleContent"; import UserContent from "./userContent"; +import { mobile, tablet } from "@docspace/components/utils/device"; const marginStyles = css` margin-left: -24px; @@ -15,41 +16,16 @@ const marginStyles = css` padding-left: 24px; padding-right: 24px; - ${isMobile && - css` - margin-left: -20px; - margin-right: -20px; - padding-left: 20px; - padding-right: 20px; - `} - - @media (max-width: 1024px) { + @media ${tablet} { margin-left: -16px; margin-right: -16px; padding-left: 16px; padding-right: 16px; } - - @media (max-width: 375px) { - ${props => - props.theme.interfaceDirection === "rtl" - ? css` - margin-right: -16px; - margin-left: -8px; - padding-right: 16px; - padding-left: 8px; - ` - : css` - margin-left: -16px; - margin-right: -8px; - padding-left: 16px; - padding-right: 8px; - `} - } `; const checkedStyle = css` - background: ${props => props.theme.filesSection.rowView.checkedBackground}; + background: ${(props) => props.theme.filesSection.rowView.checkedBackground}; ${marginStyles} `; @@ -58,7 +34,7 @@ const StyledWrapper = styled.div` border: 1px solid transparent; border-left: none; border-right: none; - ${props => + ${(props) => props.theme.interfaceDirection === "rtl" ? css` margin-right: 0; @@ -78,7 +54,7 @@ const StyledWrapper = styled.div` StyledWrapper.defaultProps = { theme: Base }; const StyledSimpleUserRow = styled(Row)` - ${props => (props.checked || props.isActive) && checkedStyle}; + ${(props) => (props.checked || props.isActive) && checkedStyle}; ${!isMobile && css` @@ -88,9 +64,9 @@ const StyledSimpleUserRow = styled(Row)` margin-top: -3px; padding-bottom: 1px; - border-top: ${props => + border-top: ${(props) => `1px ${props.theme.filesSection.tableView.row.borderColor} solid`}; - border-bottom: ${props => + border-bottom: ${(props) => `1px ${props.theme.filesSection.tableView.row.borderColor} solid`}; } `} @@ -101,7 +77,7 @@ const StyledSimpleUserRow = styled(Row)` .styled-element { height: 32px; - ${props => + ${(props) => props.theme.interfaceDirection === "rtl" ? css` margin-left: 12px; @@ -112,7 +88,7 @@ const StyledSimpleUserRow = styled(Row)` } `; -const SimpleUserRow = props => { +const SimpleUserRow = (props) => { const { item, sectionWidth, @@ -142,7 +118,8 @@ const SimpleUserRow = props => { className={`user-item row-wrapper ${ isChecked || isActive ? "row-selected" : "" }`} - value={value}> + value={value} + >
{ mode={"modern"} className={"user-row"} onRowClick={onRowClick} - onContextClick={onRowContextClick}> + onContextClick={onRowContextClick} + >
diff --git a/packages/client/src/pages/Home/Section/AccountsBody/RowView/userContent.js b/packages/client/src/pages/Home/Section/AccountsBody/RowView/userContent.js index 687c107fda..b0296c2bcf 100644 --- a/packages/client/src/pages/Home/Section/AccountsBody/RowView/userContent.js +++ b/packages/client/src/pages/Home/Section/AccountsBody/RowView/userContent.js @@ -1,50 +1,49 @@ import React from "react"; import styled, { css } from "styled-components"; -import { isTablet } from "react-device-detect"; + import { withTranslation } from "react-i18next"; import RowContent from "@docspace/components/row-content"; import Link from "@docspace/components/link"; import Badges from "../Badges"; +import { tablet } from "@docspace/components/utils/device"; const StyledRowContent = styled(RowContent)` - ${props => - ((props.sectionWidth <= 1024 && props.sectionWidth > 500) || isTablet) && - css` - .row-main-container-wrapper { - width: 100%; - display: flex; - justify-content: space-between; - max-width: inherit; - } + @media ${tablet} { + .row-main-container-wrapper { + width: 100%; + display: flex; + justify-content: space-between; + max-width: inherit; + } - .badges { - flex-direction: row-reverse; - margin-top: 9px; - ${props => + .badges { + flex-direction: row-reverse; + margin-top: 9px; + ${(props) => + props.theme.interfaceDirection === "rtl" + ? css` + margin-left: 12px; + ` + : css` + margin-right: 12px; + `} + + .paid-badge { + ${(props) => props.theme.interfaceDirection === "rtl" ? css` - margin-left: 12px; + margin-right: 8px; + margin-left: 0px; ` : css` - margin-right: 12px; + margin-left: 8px; + margin-right: 0px; `} - - .paid-badge { - ${props => - props.theme.interfaceDirection === "rtl" - ? css` - margin-right: 8px; - margin-left: 0px; - ` - : css` - margin-left: 8px; - margin-right: 0px; - `} - } } - `} + } + } `; const UserContent = ({ @@ -89,7 +88,8 @@ const UserContent = ({ sideColor={sideInfoColor} sectionWidth={sectionWidth} nameColor={nameColor} - sideInfoColor={sideInfoColor}> + sideInfoColor={sideInfoColor} + > + noHover + > {statusType === "pending" ? email : displayName?.trim() @@ -116,7 +117,8 @@ const UserContent = ({ fontSize="12px" fontWeight={400} color={sideInfoColor} - isTextOverflow={true}> + isTextOverflow={true} + > {roleLabel} + isTextOverflow={true} + > {email} diff --git a/packages/client/src/pages/Home/Section/AccountsBody/TableView/TableContainer.js b/packages/client/src/pages/Home/Section/AccountsBody/TableView/TableContainer.js index d8e28b9a93..8bac4f9f1b 100644 --- a/packages/client/src/pages/Home/Section/AccountsBody/TableView/TableContainer.js +++ b/packages/client/src/pages/Home/Section/AccountsBody/TableView/TableContainer.js @@ -1,7 +1,6 @@ import React, { useEffect, useRef } from "react"; import styled, { css } from "styled-components"; import { inject, observer } from "mobx-react"; -import { isMobile } from "react-device-detect"; import { useNavigate, useLocation } from "react-router-dom"; import TableContainer from "@docspace/components/table-container"; @@ -13,18 +12,19 @@ import TableRow from "./TableRow"; import TableHeader from "./TableHeader"; import { Base } from "@docspace/components/themes"; import { TableVersions } from "SRC_DIR/helpers/constants"; +import { DeviceType } from "@docspace/common/constants"; const COLUMNS_SIZE = `peopleColumnsSize_ver-${TableVersions.Accounts}`; const INFO_PANEL_COLUMNS_SIZE = `infoPanelPeopleColumnsSize_ver-${TableVersions.Accounts}`; const marginCss = css` margin-top: -1px; - border-top: ${props => + border-top: ${(props) => `1px solid ${props.theme.filesSection.tableView.row.borderColor}`}; `; const userNameCss = css` - ${props => + ${(props) => props.theme.interfaceDirection === "rtl" ? css` margin-right: -24px; @@ -39,7 +39,7 @@ const userNameCss = css` `; const contextCss = css` - ${props => + ${(props) => props.theme.interfaceDirection === "rtl" ? css` margin-left: -20px; @@ -77,13 +77,13 @@ const StyledTableContainer = styled(TableContainer)` border-left: 0; //for Safari macOS border-right: 0; //for Safari macOS - border-image-source: ${props => `linear-gradient(to right, + border-image-source: ${(props) => `linear-gradient(to right, ${props.theme.filesSection.tableView.row.borderColorTransition} 17px, ${props.theme.filesSection.tableView.row.borderColor} 31px)`}; } .table-container_row-context-menu-wrapper { ${contextCss} - border-image-source: ${props => `linear-gradient(to left, + border-image-source: ${(props) => `linear-gradient(to left, ${props.theme.filesSection.tableView.row.borderColorTransition} 17px, ${props.theme.filesSection.tableView.row.borderColor} 31px)`}; } } @@ -101,7 +101,7 @@ const StyledTableContainer = styled(TableContainer)` .table-container_user-name-cell, .table-container_row-context-menu-wrapper { - border-bottom: ${props => + border-bottom: ${(props) => `1px solid ${props.theme.filesSection.tableView.row.borderColor}`}; } } @@ -128,6 +128,7 @@ const Table = ({ withPaging, canChangeUserType, isFiltered, + currentDeviceType, }) => { const ref = useRef(null); const [hideColumns, setHideColumns] = React.useState(false); @@ -144,18 +145,18 @@ const Table = ({ !sectionWidth) ) return; - // 400 - it is desktop info panel width + if ( (width < 1025 && !infoPanelVisible) || ((width < 625 || (accountsViewAs === "row" && width < 1025)) && infoPanelVisible) || - isMobile + currentDeviceType !== DeviceType.desktop ) { accountsViewAs !== "row" && setViewAs("row"); } else { accountsViewAs !== "table" && setViewAs("table"); } - }, [sectionWidth]); + }, [sectionWidth, currentDeviceType]); const columnStorageName = `${COLUMNS_SIZE}=${userId}`; const columnInfoPanelStorageName = `${INFO_PANEL_COLUMNS_SIZE}=${userId}`; @@ -180,7 +181,8 @@ const Table = ({ itemCount={filterTotal} filesLength={peopleList.length} itemHeight={49} - useReactWindow={!withPaging}> + useReactWindow={!withPaging} + > {peopleList.map((item, index) => ( - props.theme.interfaceDirection === "rtl" - ? css` - margin-right: -16px; - margin-left: -8px; - padding-right: 16px; - padding-left: 8px; - ` - : css` - margin-left: -16px; - margin-right: -8px; - padding-left: 16px; - padding-right: 8px; - `} - } `; export default marginStyles; diff --git a/packages/client/src/pages/Home/Section/Body/RowsView/FilesRowContainer.js b/packages/client/src/pages/Home/Section/Body/RowsView/FilesRowContainer.js index b0a3a97459..0ef91c62e4 100644 --- a/packages/client/src/pages/Home/Section/Body/RowsView/FilesRowContainer.js +++ b/packages/client/src/pages/Home/Section/Body/RowsView/FilesRowContainer.js @@ -2,18 +2,19 @@ import React, { useEffect, useMemo } from "react"; import { inject, observer } from "mobx-react"; import RowContainer from "@docspace/components/row-container"; import SimpleFilesRow from "./SimpleFilesRow"; -import { isMobile } from "react-device-detect"; + import styled, { css } from "styled-components"; import marginStyles from "./CommonStyles"; import { isTablet } from "@docspace/components/utils/device"; import { Base } from "@docspace/components/themes"; +import { DeviceType } from "@docspace/common/constants"; const StyledRowContainer = styled(RowContainer)` .row-list-item:first-child { .row-selected { .files-row { border-top: ${(props) => - `1px ${props.theme.filesSection.tableView.row.borderColor} solid`}; + `1px ${props.theme.filesSection.tableView.row.borderColor} solid`}; margin-top: -1px; padding-top: 0px; padding-bottom: 1px; @@ -24,7 +25,7 @@ const StyledRowContainer = styled(RowContainer)` .row-selected + .row-wrapper:not(.row-selected) { .files-row { border-top: ${(props) => - `1px ${props.theme.filesSection.tableView.row.borderColor} solid`}; + `1px ${props.theme.filesSection.tableView.row.borderColor} solid`}; margin-top: -3px; ${marginStyles} } @@ -35,7 +36,7 @@ const StyledRowContainer = styled(RowContainer)` + .row-selected { .files-row { border-top: ${(props) => - `1px ${props.theme.filesSection.tableView.row.borderColor} solid`}; + `1px ${props.theme.filesSection.tableView.row.borderColor} solid`}; margin-top: -3px; ${marginStyles} } @@ -50,7 +51,7 @@ const StyledRowContainer = styled(RowContainer)` .row-selected:last-child { .files-row { border-bottom: ${(props) => - `1px ${props.theme.filesSection.tableView.row.borderColor} solid`}; + `1px ${props.theme.filesSection.tableView.row.borderColor} solid`}; ${marginStyles} } .files-row::after { @@ -60,7 +61,7 @@ const StyledRowContainer = styled(RowContainer)` .row-selected:first-child { .files-row { border-top: ${(props) => - `1px ${props.theme.filesSection.tableView.row.borderColor} solid`}; + `1px ${props.theme.filesSection.tableView.row.borderColor} solid`}; margin-top: -2px; padding-top: 1px; padding-bottom: 1px; @@ -84,24 +85,24 @@ const FilesRowContainer = ({ isTrashFolder, withPaging, highlightFile, + currentDeviceType, }) => { useEffect(() => { const width = window.innerWidth; - if ((viewAs !== "table" && viewAs !== "row") || !sectionWidth) return; // 400 - it is desktop info panel width if ( (width < 1025 && !infoPanelVisible) || ((width < 625 || (viewAs === "row" && width < 1025)) && infoPanelVisible) || - isMobile + currentDeviceType !== DeviceType.desktop ) { viewAs !== "row" && setViewAs("row"); } else { viewAs !== "table" && setViewAs("table"); } - }, [sectionWidth]); + }, [sectionWidth, currentDeviceType]); const filesListNode = useMemo(() => { return filesList.map((item, index) => ( @@ -158,7 +159,7 @@ export default inject(({ filesStore, auth, treeFoldersStore }) => { } = filesStore; const { isVisible: infoPanelVisible } = auth.infoPanelStore; const { isRoomsFolder, isArchiveFolder, isTrashFolder } = treeFoldersStore; - const { withPaging } = auth.settingsStore; + const { withPaging, currentDeviceType } = auth.settingsStore; const isRooms = isRoomsFolder || isArchiveFolder; @@ -174,5 +175,6 @@ export default inject(({ filesStore, auth, treeFoldersStore }) => { isTrashFolder, withPaging, highlightFile, + currentDeviceType, }; })(observer(FilesRowContainer)); diff --git a/packages/client/src/pages/Home/Section/Body/RowsView/FilesRowContent.js b/packages/client/src/pages/Home/Section/Body/RowsView/FilesRowContent.js index df0ed25d54..15409eaba4 100644 --- a/packages/client/src/pages/Home/Section/Body/RowsView/FilesRowContent.js +++ b/packages/client/src/pages/Home/Section/Body/RowsView/FilesRowContent.js @@ -2,7 +2,7 @@ import React from "react"; import { inject, observer } from "mobx-react"; import { withTranslation } from "react-i18next"; import styled, { css } from "styled-components"; -import { isMobile, isTablet, isMobileOnly } from "react-device-detect"; +import { isMobile, isTablet, tablet } from "@docspace/components/utils/device"; import Link from "@docspace/components/link"; import Text from "@docspace/components/text"; @@ -21,7 +21,7 @@ const SimpleFilesRowContent = styled(RowContent)` width: 100%; max-width: min-content; min-width: inherit; - ${props => + ${(props) => props.theme.interfaceDirection === "rtl" ? css` margin-left: 0px; @@ -48,7 +48,7 @@ const SimpleFilesRowContent = styled(RowContent)` .badge-version { width: max-content; - ${props => + ${(props) => props.theme.interfaceDirection === "rtl" ? css` margin: -2px -2px -2px 6px; @@ -62,62 +62,60 @@ const SimpleFilesRowContent = styled(RowContent)` width: max-content; } - ${props => - ((props.sectionWidth <= 1024 && props.sectionWidth > 500) || isTablet) && - css` - .row-main-container-wrapper { - display: flex; - justify-content: space-between; - max-width: inherit; - } + @media ${tablet} { + .row-main-container-wrapper { + display: flex; + justify-content: space-between; + max-width: inherit; + } - .badges { - flex-direction: row-reverse; - } + .badges { + flex-direction: row-reverse; + } - .tablet-badge { - margin-top: 5px; - } + .tablet-badge { + margin-top: 5px; + } - .tablet-edit, - .can-convert { - margin-top: 6px; - ${props => - props.theme.interfaceDirection === "rtl" - ? css` - margin-left: 24px !important; - ` - : css` - margin-right: 24px !important; - `} - } + .tablet-edit, + .can-convert { + margin-top: 6px; + ${(props) => + props.theme.interfaceDirection === "rtl" + ? css` + margin-left: 24px !important; + ` + : css` + margin-right: 24px !important; + `} + } - .badge-version { - ${props => - props.theme.interfaceDirection === "rtl" - ? css` - margin-left: 22px; - ` - : css` - margin-right: 22px; - `} - } + .badge-version { + ${(props) => + props.theme.interfaceDirection === "rtl" + ? css` + margin-left: 22px; + ` + : css` + margin-right: 22px; + `} + } - .new-items { - min-width: 16px; - ${props => - props.theme.interfaceDirection === "rtl" - ? css` - margin: 5px 0 0 24px; - ` - : css` - margin: 5px 24px 0 0; - `} - } - `} + .new-items { + min-width: 16px; + ${(props) => + props.theme.interfaceDirection === "rtl" + ? css` + margin: 5px 0 0 24px; + ` + : css` + margin: 5px 24px 0 0; + `} + } + } .row-content-link { - ${props => + ${(props) => props.theme.interfaceDirection === "rtl" ? css` padding: 12px 0px 0px 12px; @@ -177,7 +175,7 @@ const FilesRowContent = ({ case SortByFieldName.Tags: if (tags?.length === 0) return "—"; - return tags?.map(elem => { + return tags?.map((elem) => { return elem; }); @@ -195,9 +193,10 @@ const FilesRowContent = ({ <> + sideColor={theme.filesSection.rowView.sideColor} + > + isTextOverflow={true} + > {titleWithoutExt}
@@ -220,7 +220,8 @@ const FilesRowContent = ({ containerWidth="15%" fontSize="12px" fontWeight={400} - className="row_update-text"> + className="row_update-text" + > {contentComponent()} @@ -231,10 +232,11 @@ const FilesRowContent = ({ className="row-content-text" fontSize="12px" fontWeight={400} - truncate={true}> + truncate={true} + > {isRooms ? t(RoomsTypeTranslations[item.roomType]) - : !fileExst && !contentLength && !providerKey && !isMobileOnly + : !fileExst && !contentLength && !providerKey && !isMobile() ? `${foldersCount} ${t("Translations:Folders")} | ${filesCount} ${t( "Translations:Files" )}` diff --git a/packages/client/src/pages/Home/Section/Body/RowsView/SimpleFilesRow.js b/packages/client/src/pages/Home/Section/Body/RowsView/SimpleFilesRow.js index c6afb80d8a..acae9a2b1a 100644 --- a/packages/client/src/pages/Home/Section/Body/RowsView/SimpleFilesRow.js +++ b/packages/client/src/pages/Home/Section/Body/RowsView/SimpleFilesRow.js @@ -4,7 +4,7 @@ import { withTranslation } from "react-i18next"; import DragAndDrop from "@docspace/components/drag-and-drop"; import Row from "@docspace/components/row"; import FilesRowContent from "./FilesRowContent"; -import { isTablet, isMobile } from "react-device-detect"; +import { isMobile } from "react-device-detect"; import withFileActions from "../../../../../HOCs/withFileActions"; import withQuickButtons from "../../../../../HOCs/withQuickButtons"; diff --git a/packages/client/src/pages/Home/Section/Body/TableView/TableContainer.js b/packages/client/src/pages/Home/Section/Body/TableView/TableContainer.js index 8b730f17c0..6e24c2ccea 100644 --- a/packages/client/src/pages/Home/Section/Body/TableView/TableContainer.js +++ b/packages/client/src/pages/Home/Section/Body/TableView/TableContainer.js @@ -6,18 +6,19 @@ import { useNavigate, useLocation } from "react-router-dom"; import TableRow from "./TableRow"; import TableHeader from "./TableHeader"; import TableBody from "@docspace/components/table-container/TableBody"; -import { isMobile } from "react-device-detect"; + import styled, { css } from "styled-components"; import { Base } from "@docspace/components/themes"; +import { DeviceType } from "@docspace/common/constants"; const marginCss = css` margin-top: -1px; - border-top: ${props => + border-top: ${(props) => `1px solid ${props.theme.filesSection.tableView.row.borderColor}`}; `; const fileNameCss = css` - ${props => + ${(props) => props.theme.interfaceDirection === "rtl" ? css` margin-right: -24px; @@ -32,7 +33,7 @@ const fileNameCss = css` `; const contextCss = css` - ${props => + ${(props) => props.theme.interfaceDirection === "rtl" ? css` margin-left: -20px; @@ -70,13 +71,13 @@ const StyledTableContainer = styled(TableContainer)` border-left: 0; //for Safari macOS border-right: 0; //for Safari macOS - border-image-source: ${props => `linear-gradient(to right, + border-image-source: ${(props) => `linear-gradient(to right, ${props.theme.filesSection.tableView.row.borderColorTransition} 17px, ${props.theme.filesSection.tableView.row.borderColor} 31px)`}; } .table-container_row-context-menu-wrapper { ${contextCss} - border-image-source: ${props => `linear-gradient(to left, + border-image-source: ${(props) => `linear-gradient(to left, ${props.theme.filesSection.tableView.row.borderColorTransition} 17px, ${props.theme.filesSection.tableView.row.borderColor} 31px)`}; } } @@ -108,7 +109,7 @@ const StyledTableContainer = styled(TableContainer)` .table-container_file-name-cell, .table-container_row-context-menu-wrapper { - border-bottom: ${props => + border-bottom: ${(props) => `1px solid ${props.theme.filesSection.tableView.row.borderColor}`}; } } @@ -140,6 +141,7 @@ const Table = ({ columnStorageName, columnInfoPanelStorageName, highlightFile, + currentDeviceType, }) => { const [tagCount, setTagCount] = React.useState(null); const [hideColumns, setHideColumns] = React.useState(false); @@ -159,13 +161,13 @@ const Table = ({ (width < 1025 && !infoPanelVisible) || ((width < 625 || (viewAs === "row" && width < 1025)) && infoPanelVisible) || - isMobile + currentDeviceType !== DeviceType.desktop ) { viewAs !== "row" && setViewAs("row"); } else { viewAs !== "table" && setViewAs("table"); } - }, [sectionWidth]); + }, [sectionWidth, currentDeviceType]); useEffect(() => { return () => { @@ -176,7 +178,7 @@ const Table = ({ }, []); const onResize = useCallback( - node => { + (node) => { const element = tagRef?.current ? tagRef?.current : node; if (element) { @@ -190,7 +192,7 @@ const Table = ({ [tagCount] ); - const onSetTagRef = useCallback(node => { + const onSetTagRef = useCallback((node) => { if (node) { tagRef.current = node; onResize(node); @@ -258,7 +260,8 @@ const Table = ({ useReactWindow={!withPaging} infoPanelVisible={infoPanelVisible} columnInfoPanelStorageName={columnInfoPanelStorageName} - itemHeight={49}> + itemHeight={49} + > {filesListNode} @@ -286,7 +289,7 @@ export default inject(({ filesStore, treeFoldersStore, auth, tableStore }) => { highlightFile, } = filesStore; - const { withPaging, theme } = auth.settingsStore; + const { withPaging, theme, currentDeviceType } = auth.settingsStore; return { filesList, @@ -306,5 +309,6 @@ export default inject(({ filesStore, treeFoldersStore, auth, tableStore }) => { columnStorageName, columnInfoPanelStorageName, highlightFile, + currentDeviceType, }; })(observer(Table)); diff --git a/packages/client/src/pages/Home/Section/Body/TableView/TableHeader.js b/packages/client/src/pages/Home/Section/Body/TableView/TableHeader.js index 9e2640b971..f716ea113f 100644 --- a/packages/client/src/pages/Home/Section/Body/TableView/TableHeader.js +++ b/packages/client/src/pages/Home/Section/Body/TableView/TableHeader.js @@ -256,7 +256,7 @@ class FilesTableHeader extends React.Component { componentDidMount() { this.customScrollElm = document.getElementsByClassName("section-scroll")[0]; - this.customScrollElm.addEventListener("scroll", this.onBeginScroll); + this.customScrollElm?.addEventListener("scroll", this.onBeginScroll); } onBeginScroll = () => { @@ -319,7 +319,7 @@ class FilesTableHeader extends React.Component { } componentWillUnmount() { - this.customScrollElm.removeEventListener("scroll", this.onBeginScroll); + this.customScrollElm?.removeEventListener("scroll", this.onBeginScroll); } onColumnChange = (key) => { diff --git a/packages/client/src/pages/Home/Section/Body/TilesView/FilesTileContent.js b/packages/client/src/pages/Home/Section/Body/TilesView/FilesTileContent.js index 3e1a04d7c7..c6a0f53ddc 100644 --- a/packages/client/src/pages/Home/Section/Body/TilesView/FilesTileContent.js +++ b/packages/client/src/pages/Home/Section/Body/TilesView/FilesTileContent.js @@ -8,7 +8,9 @@ import Link from "@docspace/components/link"; import TileContent from "./sub-components/TileContent"; import withContent from "../../../../../HOCs/withContent"; import withBadges from "../../../../../HOCs/withBadges"; -import { isMobile } from "react-device-detect"; + +import { DeviceType } from "@docspace/common/constants"; +import { tablet } from "@docspace/components/utils/device"; const SimpleFilesTileContent = styled(TileContent)` .row-main-container { @@ -22,7 +24,7 @@ const SimpleFilesTileContent = styled(TileContent)` } .badge { - ${props => + ${(props) => props.theme.interfaceDirection === "rtl" ? css` margin-left: 8px; @@ -37,7 +39,7 @@ const SimpleFilesTileContent = styled(TileContent)` .new-items { position: absolute; - ${props => + ${(props) => props.theme.interfaceDirection === "rtl" ? css` left: 29px; @@ -55,7 +57,7 @@ const SimpleFilesTileContent = styled(TileContent)` .share-icon { margin-top: -4px; - ${props => + ${(props) => props.theme.interfaceDirection === "rtl" ? css` padding-left: 8px; @@ -93,7 +95,7 @@ const SimpleFilesTileContent = styled(TileContent)` } `} - @media (max-width: 1024px) { + @media ${tablet} { display: inline-flex; height: auto; @@ -109,6 +111,7 @@ const FilesTileContent = ({ linkStyles, theme, isRooms, + currentDeviceType, }) => { const { fileExst, title, viewAccessability } = item; @@ -119,18 +122,20 @@ const FilesTileContent = ({ + isRooms={isRooms} + > + isTextOverflow + > {titleWithoutExt} @@ -143,7 +148,11 @@ export default inject(({ auth, treeFoldersStore }) => { const isRooms = isRoomsFolder || isArchiveFolder; - return { theme: auth.settingsStore.theme, isRooms }; + return { + theme: auth.settingsStore.theme, + currentDeviceType: auth.settingsStore.currentDeviceType, + isRooms, + }; })( observer( withTranslation(["Files", "Translations", "Notifications"])( diff --git a/packages/client/src/pages/Home/Section/Body/TilesView/sub-components/Tile.js b/packages/client/src/pages/Home/Section/Body/TilesView/sub-components/Tile.js index 8f5c7a40da..ee5d8b7e2f 100644 --- a/packages/client/src/pages/Home/Section/Body/TilesView/sub-components/Tile.js +++ b/packages/client/src/pages/Home/Section/Body/TilesView/sub-components/Tile.js @@ -368,7 +368,7 @@ const StyledContent = styled.div` margin-left: 12px; } - @media (max-width: 1024px) { + @media ${tablet} { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; @@ -641,6 +641,7 @@ class Tile extends React.PureComponent { const contextMenuHeader = { icon: children[0].props.item.icon, title: children[0].props.item.title, + color: children[0].props.item.logo?.color, }; const title = item.isFolder diff --git a/packages/client/src/pages/Home/Section/Body/TilesView/sub-components/TileContent.js b/packages/client/src/pages/Home/Section/Body/TilesView/sub-components/TileContent.js index 740433023a..4ada4a08db 100644 --- a/packages/client/src/pages/Home/Section/Body/TilesView/sub-components/TileContent.js +++ b/packages/client/src/pages/Home/Section/Body/TilesView/sub-components/TileContent.js @@ -1,6 +1,7 @@ import React from "react"; import styled, { css } from "styled-components"; import PropTypes from "prop-types"; +import { tablet } from "@docspace/components/utils/device"; const truncateCss = css` white-space: nowrap; @@ -36,7 +37,7 @@ const MainContainerWrapper = styled.div` const MainContainer = styled.div` height: 20px; - @media (max-width: 1024px) { + @media ${tablet} { ${truncateCss}; } `; diff --git a/packages/client/src/pages/Home/Section/Body/index.js b/packages/client/src/pages/Home/Section/Body/index.js index 75a7186f1e..bf66622e93 100644 --- a/packages/client/src/pages/Home/Section/Body/index.js +++ b/packages/client/src/pages/Home/Section/Body/index.js @@ -1,7 +1,6 @@ import React, { useEffect } from "react"; import { withTranslation } from "react-i18next"; import { useLocation } from "react-router-dom"; -import { isMobile, isMobileOnly } from "react-device-detect"; import { observer, inject } from "mobx-react"; import FilesRowContainer from "./RowsView/FilesRowContainer"; @@ -12,6 +11,8 @@ import TableView from "./TableView/TableContainer"; import withHotkeys from "../../../../HOCs/withHotkeys"; import { Consumer } from "@docspace/components/utils/context"; import { isElementInViewport } from "@docspace/common/utils"; +import { isMobile, isTablet } from "@docspace/components/utils/device"; +import { DeviceType } from "@docspace/common/constants"; let currentDroppable = null; let isDragActive = false; @@ -43,6 +44,7 @@ const SectionBodyContent = (props) => { onClickBack, movingInProgress, + currentDeviceType, } = props; useEffect(() => { @@ -54,7 +56,7 @@ const SectionBodyContent = (props) => { "#customScrollBar > .scroll-wrapper > .scroller" ); - if (isMobile) { + if (isTablet() || isMobile() || currentDeviceType !== DeviceType.desktop) { customScrollElm && customScrollElm.scrollTo(0, 0); } @@ -85,6 +87,7 @@ const SectionBodyContent = (props) => { folderId, viewAs, uploaded, + currentDeviceType, ]); useEffect(() => { @@ -98,21 +101,26 @@ const SectionBodyContent = (props) => { let isInViewport = isElementInViewport(targetElement); if (!isInViewport || viewAs === "table") { - const bodyScroll = isMobileOnly - ? document.querySelector( - "#customScrollBar > .scroll-wrapper > .scroller" - ) - : document.querySelector(".section-scroll"); + const bodyScroll = + isMobile() || currentDeviceType === DeviceType.mobile + ? document.querySelector( + "#customScrollBar > .scroll-wrapper > .scroller" + ) + : document.querySelector(".section-scroll"); const count = filesList.findIndex((elem) => elem.id === scrollToItem.id) * - (isMobileOnly ? 57 : viewAs === "table" ? 40 : 48); + (isMobile() || currentDeviceType === DeviceType.mobile + ? 57 + : viewAs === "table" + ? 40 + : 48); bodyScroll.scrollTo(0, count); } setScrollToItem(null); } - }, [scrollToItem]); + }, [scrollToItem, currentDeviceType]); const onBeforeunload = (e) => { if (!uploaded) { @@ -287,6 +295,7 @@ const SectionBodyContent = (props) => { export default inject( ({ + auth, filesStore, selectedFolderStore, treeFoldersStore, @@ -337,6 +346,7 @@ export default inject( uploaded: uploadDataStore.uploaded, onClickBack: filesActionsStore.onClickBack, movingInProgress, + currentDeviceType: auth.settingsStore, }; } )( diff --git a/packages/client/src/pages/Home/Section/Filter/index.js b/packages/client/src/pages/Home/Section/Filter/index.js index 31ac284a88..f3573bd9d1 100644 --- a/packages/client/src/pages/Home/Section/Filter/index.js +++ b/packages/client/src/pages/Home/Section/Filter/index.js @@ -1,7 +1,7 @@ import React, { useCallback, useEffect } from "react"; import { inject, observer } from "mobx-react"; import { useLocation, useNavigate } from "react-router-dom"; -import { isMobile, isMobileOnly } from "react-device-detect"; + import { withTranslation } from "react-i18next"; import find from "lodash/find"; import result from "lodash/result"; @@ -26,6 +26,7 @@ import { EmployeeStatus, PaymentsType, AccountLoginType, + DeviceType, } from "@docspace/common/constants"; import { getDefaultRoomName } from "SRC_DIR/helpers/filesUtils"; @@ -251,6 +252,7 @@ const SectionFilterContent = ({ publicRoomKey, setRoomsFilter, standalone, + currentDeviceType, }) => { const location = useLocation(); const navigate = useNavigate(); @@ -522,7 +524,7 @@ const SectionFilterContent = ({ if ( (sectionWidth < 1025 && !infoPanelVisible) || (sectionWidth < 625 && infoPanelVisible) || - isMobile + currentDeviceType !== DeviceType.desktop ) { setViewAs("row"); } else { @@ -532,7 +534,7 @@ const SectionFilterContent = ({ setViewAs(view); } }, - [sectionWidth, infoPanelVisible, setViewAs] + [sectionWidth, infoPanelVisible, setViewAs, currentDeviceType] ); const getSelectedInputValue = React.useCallback(() => { @@ -1214,6 +1216,13 @@ const SectionFilterContent = ({ group: FilterGroups.roomFilterType, label: t("ViewOnlyRooms"), }; + case RoomsType.PublicRoom: + return { + id: "filter_type-public", + key: RoomsType.PublicRoom, + group: FilterGroups.roomFilterType, + label: t("PublicRoom"), + }; case RoomsType.CustomRoom: default: return { @@ -1967,7 +1976,7 @@ const SectionFilterContent = ({ ); const onSortButtonClick = (isOpen) => { - if (isMobileOnly) { + if (currentDeviceType === DeviceType.mobile) { setMainButtonMobileVisible(isOpen); } }; @@ -2032,6 +2041,7 @@ const SectionFilterContent = ({ clearSearch={clearSearch} setClearSearch={setClearSearch} onSortButtonClick={onSortButtonClick} + currentDeviceType={currentDeviceType} /> ); }; @@ -2069,7 +2079,7 @@ export default inject( const { fetchTags } = tagsStore; const { user } = auth.userStore; - const { personal, standalone } = auth.settingsStore; + const { personal, standalone, currentDeviceType } = auth.settingsStore; const { isFavoritesFolder, isRecentFolder, @@ -2144,6 +2154,7 @@ export default inject( publicRoomKey, setRoomsFilter, standalone, + currentDeviceType, }; } )( diff --git a/packages/client/src/pages/Home/Section/Header/index.js b/packages/client/src/pages/Home/Section/Header/index.js index 20b4bfcc0c..8f3a622c8d 100644 --- a/packages/client/src/pages/Home/Section/Header/index.js +++ b/packages/client/src/pages/Home/Section/Header/index.js @@ -31,7 +31,7 @@ import PublicRoomIconUrl from "PUBLIC_DIR/images/public-room.react.svg?url"; import React from "react"; import { inject, observer } from "mobx-react"; import { withTranslation } from "react-i18next"; -import { isMobile, isTablet, isMobileOnly } from "react-device-detect"; +import { isMobile, isTablet } from "react-device-detect"; import styled, { css } from "styled-components"; import copy from "copy-to-clipboard"; import { useNavigate, useLocation } from "react-router-dom"; @@ -46,7 +46,12 @@ import { tablet, mobile } from "@docspace/components/utils/device"; import { Consumer } from "@docspace/components/utils/context"; import toastr from "@docspace/components/toast/toastr"; import TableGroupMenu from "@docspace/components/table-container/TableGroupMenu"; -import { Events, EmployeeType, RoomsType } from "@docspace/common/constants"; +import { + Events, + EmployeeType, + RoomsType, + DeviceType, +} from "@docspace/common/constants"; import { CategoryType } from "SRC_DIR/helpers/constants"; import { @@ -74,7 +79,7 @@ const StyledContainer = styled.div` height: 68px; @media ${tablet} { - height: 60px; + height: 61px; ${(props) => props.theme.interfaceDirection === "rtl" ? css` @@ -86,22 +91,8 @@ const StyledContainer = styled.div` width: calc(100% + 32px); } - ${isMobile && - css` - height: 60px; - ${(props) => - props.theme.interfaceDirection === "rtl" - ? css` - margin: 0 -16px 0 0; - ` - : css` - margin: 0 0 0 -16px; - `} - width: calc(100% + 32px); - `} - @media ${mobile} { - height: 52px; + height: 52px !important; ${(props) => props.theme.interfaceDirection === "rtl" @@ -113,20 +104,6 @@ const StyledContainer = styled.div` `} width: calc(100% + 32px); } - - ${isMobileOnly && - css` - height: 52px; - ${(props) => - props.theme.interfaceDirection === "rtl" - ? css` - margin: 0 -16px 0 0; - ` - : css` - margin: 0 0 0 -16px; - `} - width: calc(100% + 32px); - `} } .header-container { @@ -138,7 +115,11 @@ const StyledContainer = styled.div` display: none;}`} @media ${tablet} { - height: 60px; + height: 61px; + } + + @media ${mobile} { + height: 53px; } } `; @@ -237,6 +218,8 @@ const SectionHeaderContent = (props) => { isPublicRoomType, externalLinks, moveToPublicRoom, + currentDeviceType, + isFrame, } = props; const navigate = useNavigate(); @@ -947,7 +930,7 @@ const SectionHeaderContent = (props) => { headerMenu, isInfoPanelVisible, toggleInfoPanel: onToggleInfoPanel, - isMobileView: isMobileOnly, + isMobileView: currentDeviceType === DeviceType.mobile, }; if (isAccountsPage) { @@ -1030,7 +1013,6 @@ const SectionHeaderContent = (props) => { onClose={onClose} onClickFolder={onClickFolder} isTrashFolder={isRecycleBinFolder} - isRecycleBinFolder={isRecycleBinFolder || isArchiveFolder} isEmptyFilesList={ isArchiveFolder ? isEmptyArchive : isEmptyFilesList } @@ -1059,6 +1041,8 @@ const SectionHeaderContent = (props) => { isPublicRoomType && !isPublicRoom && PublicRoomIconUrl } showRootFolderTitle={insideTheRoom} + currentDeviceType={currentDeviceType} + isFrame={isFrame} />
)} @@ -1168,8 +1152,13 @@ export default inject( const selectedFolder = { ...selectedFolderStore }; - const { enablePlugins, theme, whiteLabelLogoUrls, isFrame } = - auth.settingsStore; + const { + enablePlugins, + theme, + whiteLabelLogoUrls, + isFrame, + currentDeviceType, + } = auth.settingsStore; const { isGracePeriod } = auth.currentTariffStatusStore; const isRoom = !!roomType; @@ -1328,6 +1317,7 @@ export default inject( whiteLabelLogoUrls, setRoomSharingPanelVisible, isFrame, + currentDeviceType, }; } )( diff --git a/packages/client/src/pages/Home/Section/SettingsBody/StyledSettings.js b/packages/client/src/pages/Home/Section/SettingsBody/StyledSettings.js index 3975286456..6c7db6475c 100644 --- a/packages/client/src/pages/Home/Section/SettingsBody/StyledSettings.js +++ b/packages/client/src/pages/Home/Section/SettingsBody/StyledSettings.js @@ -1,6 +1,5 @@ import styled, { css } from "styled-components"; import { tablet } from "@docspace/components/utils/device"; -import { isMobile } from "react-device-detect"; const StyledSettings = styled.div` margin-top: ${(props) => @@ -21,11 +20,6 @@ const StyledSettings = styled.div` `} } - ${isMobile && - css` - margin-top: 8px; - `} - width: 100%; display: grid; diff --git a/packages/client/src/pages/Home/Section/SettingsBody/index.js b/packages/client/src/pages/Home/Section/SettingsBody/index.js index 018d59819e..7e36abb0a5 100644 --- a/packages/client/src/pages/Home/Section/SettingsBody/index.js +++ b/packages/client/src/pages/Home/Section/SettingsBody/index.js @@ -10,7 +10,6 @@ import Submenu from "@docspace/components/submenu"; import PersonalSettings from "./CommonSettings"; import GeneralSettings from "./AdminSettings"; import { tablet } from "@docspace/components/utils/device"; -import { isMobile } from "react-device-detect"; const StyledContainer = styled.div` margin-top: -22px; @@ -18,11 +17,6 @@ const StyledContainer = styled.div` @media ${tablet} { margin-top: 0px; } - - ${isMobile && - css` - margin-top: 0px; - `} `; const SectionBodyContent = ({ isErrorSettings, user }) => { diff --git a/packages/client/src/pages/Home/Section/Warning/index.js b/packages/client/src/pages/Home/Section/Warning/index.js new file mode 100644 index 0000000000..bba7167c15 --- /dev/null +++ b/packages/client/src/pages/Home/Section/Warning/index.js @@ -0,0 +1,12 @@ +import React from "react"; +import { useTranslation } from "react-i18next"; + +import TrashWarning from "@docspace/common/components/Navigation/sub-components/trash-warning"; + +const Warning = () => { + const { t } = useTranslation("Files"); + + return ; +}; + +export default Warning; diff --git a/packages/client/src/pages/Home/Section/index.js b/packages/client/src/pages/Home/Section/index.js index c92018135e..57eeb8c911 100644 --- a/packages/client/src/pages/Home/Section/index.js +++ b/packages/client/src/pages/Home/Section/index.js @@ -4,3 +4,4 @@ export { default as AccountsSectionBodyContent } from "./AccountsBody"; export { default as SettingsSectionBodyContent } from "./SettingsBody"; export { default as SectionFilterContent } from "./Filter"; export { default as SectionPagingContent } from "./Paging"; +export { default as SectionWarningContent } from "./Warning"; diff --git a/packages/client/src/pages/Home/index.js b/packages/client/src/pages/Home/index.js index 30dc3485a0..9e4fdb7415 100644 --- a/packages/client/src/pages/Home/index.js +++ b/packages/client/src/pages/Home/index.js @@ -14,6 +14,7 @@ import { SectionFilterContent, SectionHeaderContent, SectionPagingContent, + SectionWarningContent, } from "./Section"; import AccountsDialogs from "./Section/AccountsBody/Dialogs"; @@ -295,6 +296,12 @@ const PureHome = (props) => { )} + {isRecycleBinFolder && !isEmptyPage && ( + + + + )} + {(((!isEmptyPage || showFilterLoader) && !isErrorRoomNotAvailable) || isAccountsPage) && !isSettingsPage && ( @@ -352,6 +359,7 @@ export default inject( const { firstLoad, + setIsSectionHeaderLoading, setIsSectionBodyLoading, setIsSectionFilterLoading, isLoading, @@ -359,9 +367,10 @@ export default inject( showFilterLoader, } = clientLoadingStore; - const setIsLoading = (param) => { - setIsSectionFilterLoading(param); - setIsSectionBodyLoading(param); + const setIsLoading = (param, withoutTimer, withHeaderLoader) => { + if (withHeaderLoader) setIsSectionHeaderLoading(param, !withoutTimer); + setIsSectionFilterLoading(param, !withoutTimer); + setIsSectionBodyLoading(param, !withoutTimer); }; const { diff --git a/packages/client/src/pages/PortalSettings/Layout/Article/Body/index.js b/packages/client/src/pages/PortalSettings/Layout/Article/Body/index.js index 454c7889c3..3df924838d 100644 --- a/packages/client/src/pages/PortalSettings/Layout/Article/Body/index.js +++ b/packages/client/src/pages/PortalSettings/Layout/Article/Body/index.js @@ -6,10 +6,9 @@ import { withTranslation } from "react-i18next"; import { isArrayEqual } from "@docspace/components/utils/array"; -import { isMobileOnly } from "react-device-detect"; - import { isMobile } from "@docspace/components/utils/device"; import withLoading from "SRC_DIR/HOCs/withLoading"; +import { DeviceType } from "@docspace/common/constants"; import { //getKeyByLink, @@ -115,6 +114,8 @@ const ArticleBodyContent = (props) => { standalone, isEnterprise, isCommunity, + currentDeviceType, + isProfileLoading, } = props; const [selectedKeys, setSelectedKeys] = React.useState([]); @@ -160,7 +161,7 @@ const ArticleBodyContent = (props) => { }, []); React.useEffect(() => { - if (tReady) setIsLoadedArticleBody(true); + if (tReady && !isProfileLoading) setIsLoadedArticleBody(true); if (prevLocation.current.pathname !== location.pathname) { if (location.pathname.includes("common")) { @@ -198,7 +199,13 @@ const ArticleBodyContent = (props) => { this.setState({ selectedKeys: ["8-0"] }); } } - }, [tReady, setIsLoadedArticleBody, location.pathname, selectedKeys]); + }, [ + tReady, + isProfileLoading, + setIsLoadedArticleBody, + location.pathname, + selectedKeys, + ]); const onSelect = (value) => { if (isArrayEqual([value], selectedKeys)) { @@ -207,7 +214,7 @@ const ArticleBodyContent = (props) => { setSelectedKeys([value + "-0"]); - if (isMobileOnly || isMobile()) { + if (currentDeviceType === DeviceType.mobile) { toggleArticleOpen(); } @@ -333,10 +340,14 @@ const ArticleBodyContent = (props) => { const items = catalogItems(); - return !isLoadedArticleBody ? : <>{items}; + return !isLoadedArticleBody || isProfileLoading ? ( + + ) : ( + <>{items} + ); }; -export default inject(({ auth, common }) => { +export default inject(({ auth, common, clientLoadingStore }) => { const { isLoadedArticleBody, setIsLoadedArticleBody } = common; const { currentTariffStatusStore, @@ -348,7 +359,13 @@ export default inject(({ auth, common }) => { const { isNotPaidPeriod } = currentTariffStatusStore; const { user } = userStore; const { isOwner } = user; - const { standalone, showText, toggleArticleOpen } = settingsStore; + const { standalone, showText, toggleArticleOpen, currentDeviceType } = + settingsStore; + + const isProfileLoading = + window.location.pathname.includes("profile") && + clientLoadingStore.showProfileLoader && + !isLoadedArticleBody; return { standalone, @@ -360,6 +377,8 @@ export default inject(({ auth, common }) => { isNotPaidPeriod, isOwner, isCommunity, + currentDeviceType, + isProfileLoading, }; })( withLoading( diff --git a/packages/client/src/pages/PortalSettings/Layout/Article/Body/loaderArticleBody.js b/packages/client/src/pages/PortalSettings/Layout/Article/Body/loaderArticleBody.js index 2a2a53e2e1..a1461cc5c7 100644 --- a/packages/client/src/pages/PortalSettings/Layout/Article/Body/loaderArticleBody.js +++ b/packages/client/src/pages/PortalSettings/Layout/Article/Body/loaderArticleBody.js @@ -1,19 +1,10 @@ import React, { useEffect, useState } from "react"; import styled, { css } from "styled-components"; import Loaders from "@docspace/common/components/Loaders"; -import { isTablet as isTabletUtils } from "@docspace/components/utils/device"; -import { isTablet } from "react-device-detect"; + +import { isDesktop, desktop } from "@docspace/components/utils/device"; const StyledLoader = styled.div` - ${props => - props.theme.interfaceDirection === "rtl" - ? css` - padding-right: 8px; - ` - : css` - padding-left: 8px; - `} - .loader { padding-bottom: 12px; } @@ -32,15 +23,7 @@ const StyledLoader = styled.div` margin: 0px; } - @media (min-width: 1024px) { - ${props => - props.theme.interfaceDirection === "rtl" - ? css` - padding-right: 10px; - ` - : css` - padding-left: 10px; - `} + @media ${desktop} { padding-top: 7px; display: flex; flex-direction: column; @@ -59,7 +42,7 @@ const LoaderArticleBody = () => { const [isTabletView, setIsTabletView] = useState(false); const checkInnerWidth = () => { - const isTabletView = window.innerWidth <= 1024 || isTablet; + const isTabletView = !isDesktop(); if (isTabletView) { setIsTabletView(true); @@ -76,21 +59,10 @@ const LoaderArticleBody = () => { }); const height = isTabletView ? "28px" : "20px"; - const width = isTabletView ? "28px" : "187px"; + const width = isTabletView ? "28px" : "210px"; return ( - {isTabletView ? ( -
-

-
- ) : ( - - )} diff --git a/packages/client/src/pages/PortalSettings/Layout/Section/Header/index.js b/packages/client/src/pages/PortalSettings/Layout/Section/Header/index.js index 891e361b2d..877ce5de0b 100644 --- a/packages/client/src/pages/PortalSettings/Layout/Section/Header/index.js +++ b/packages/client/src/pages/PortalSettings/Layout/Section/Header/index.js @@ -11,7 +11,7 @@ import IconButton from "@docspace/components/icon-button"; import TableGroupMenu from "@docspace/components/table-container/TableGroupMenu"; import DropDownItem from "@docspace/components/drop-down-item"; import LoaderSectionHeader from "../loaderSectionHeader"; -import { tablet } from "@docspace/components/utils/device"; +import { tablet, desktop } from "@docspace/components/utils/device"; import withLoading from "SRC_DIR/HOCs/withLoading"; import Badge from "@docspace/components/badge"; import { @@ -21,7 +21,6 @@ import { checkPropertyByLink, } from "../../../utils"; import { combineUrl } from "@docspace/common/utils"; -import { isMobile, isTablet, isMobileOnly } from "react-device-detect"; const HeaderContainer = styled.div` position: relative; @@ -30,7 +29,7 @@ const HeaderContainer = styled.div` max-width: calc(100vw - 32px); .settings-section_header { display: flex; - align-items: baseline; + align-items: center; .settings-section_badge { ${(props) => props.theme.interfaceDirection === "rtl" @@ -93,22 +92,14 @@ const HeaderContainer = styled.div` } } - ${isTablet && - css` - h1 { - line-height: 61px; - font-size: 21px; - } - `}; - - @media (min-width: 600px) and (max-width: 1024px) { + @media ${tablet} { h1 { line-height: 61px; font-size: 21px; } } - @media (min-width: 1024px) { + @media ${desktop} { h1 { font-size: 18px; line-height: 59px !important; @@ -133,18 +124,6 @@ const StyledContainer = styled.div` margin: 0 -16px; width: calc(100% + 32px); } - - ${isMobile && - css` - margin: 0 -16px; - width: calc(100% + 32px); - `} - - ${isMobileOnly && - css` - margin: 0 -16px; - width: calc(100% + 32px); - `} } `; @@ -172,6 +151,12 @@ const SectionHeaderContent = (props) => { return isBrandingAndCustomizationAvailable; case "RestoreBackup": return isRestoreAndAutoBackupAvailable; + case "WhiteLabel": + return isBrandingAndCustomizationAvailable; + case "CompanyInfoSettings": + return isBrandingAndCustomizationAvailable; + case "AdditionalResources": + return isBrandingAndCustomizationAvailable; default: return true; } diff --git a/packages/client/src/pages/PortalSettings/Layout/Section/loaderSectionHeader.js b/packages/client/src/pages/PortalSettings/Layout/Section/loaderSectionHeader.js index 6b656dfc20..ac44e8c2f9 100644 --- a/packages/client/src/pages/PortalSettings/Layout/Section/loaderSectionHeader.js +++ b/packages/client/src/pages/PortalSettings/Layout/Section/loaderSectionHeader.js @@ -1,14 +1,14 @@ import React, { useEffect, useState } from "react"; import styled, { css } from "styled-components"; import Loaders from "@docspace/common/components/Loaders"; -import { isTablet, isMobileOnly } from "react-device-detect"; +import { isTablet, isDesktop } from "@docspace/components/utils/device"; const StyledLoader = styled.div` display: flex; align-items: center; .arrow { - ${props => + ${(props) => props.theme.interfaceDirection === "rtl" ? css` padding-left: 12px; @@ -18,7 +18,7 @@ const StyledLoader = styled.div` `} } - padding: ${props => + padding: ${(props) => props.isTabletView ? "16px 0 17px" : props.isDesktopView @@ -36,12 +36,9 @@ const LoaderSectionHeader = () => { const levelSettings = location.pathname.split("/").length - 1; const checkInnerWidth = () => { - const isTabletView = - (window.innerWidth >= 600 && window.innerWidth <= 1024) || - (isTablet && !isMobileOnly); - - const isDesktopView = window.innerWidth > 1024; + const isTabletView = isTablet(); + const isDesktopView = isDesktop(); if (isTabletView) { setIsTabletView(true); } else { diff --git a/packages/client/src/pages/PortalSettings/Layout/index.js b/packages/client/src/pages/PortalSettings/Layout/index.js index 01ac71d6cb..def7dd9c8a 100644 --- a/packages/client/src/pages/PortalSettings/Layout/index.js +++ b/packages/client/src/pages/PortalSettings/Layout/index.js @@ -11,9 +11,9 @@ import { useParams } from "react-router-dom"; import HistoryHeader from "../categories/developer-tools/Webhooks/WebhookHistory/sub-components/HistoryHeader"; import DetailsNavigationHeader from "../categories/developer-tools/Webhooks/WebhookEventDetails/sub-components/DetailsNavigationHeader"; -const ArticleSettings = React.memo(() => { +const ArticleSettings = React.memo(({ showArticleLoader }) => { return ( -
+
@@ -35,7 +35,17 @@ const Layout = ({ enablePlugins, isInitPlugins, initPlugins, + setBodyRendered, + isLoadedArticleBody, }) => { + useEffect(() => { + setBodyRendered(true); + + return () => { + setBodyRendered(false); + }; + }, []); + useEffect(() => { currentProductId !== "settings" && setCurrentProductId("settings"); }, [language, currentProductId, setCurrentProductId]); @@ -52,9 +62,13 @@ const Layout = ({ return ( <> - + {!isGeneralPage && ( -
+
{currentPath === webhookHistoryPath ? ( @@ -81,7 +95,12 @@ export default inject(({ auth, setup, pluginStore }) => { const { language, settingsStore } = auth; const { addUsers } = setup.headerAction; - const { setCurrentProductId, enablePlugins } = settingsStore; + const { + setCurrentProductId, + enablePlugins, + setBodyRendered, + isLoadedArticleBody, + } = settingsStore; const { isInit: isInitPlugins, initPlugins } = pluginStore; @@ -93,5 +112,7 @@ export default inject(({ auth, setup, pluginStore }) => { enablePlugins, isInitPlugins, initPlugins, + setBodyRendered, + isLoadedArticleBody, }; })(withLoading(observer(Layout))); diff --git a/packages/client/src/pages/PortalSettings/categories/common/Appearance/StyledApperance.js b/packages/client/src/pages/PortalSettings/categories/common/Appearance/StyledApperance.js index 717f84f733..5f44918164 100644 --- a/packages/client/src/pages/PortalSettings/categories/common/Appearance/StyledApperance.js +++ b/packages/client/src/pages/PortalSettings/categories/common/Appearance/StyledApperance.js @@ -1,4 +1,4 @@ -import { smallTablet } from "@docspace/components/utils/device"; +import { mobile } from "@docspace/components/utils/device"; import PlusThemeSvgUrl from "PUBLIC_DIR/images/plus.theme.svg?url"; import styled, { css } from "styled-components"; @@ -80,7 +80,7 @@ const StyledComponent = styled.div` margin-right: 8px; `} } - @media ${smallTablet} { + @media ${mobile} { .button { width: 100%; } @@ -89,7 +89,7 @@ const StyledComponent = styled.div` ${({ isShowDeleteButton }) => isShowDeleteButton && css` - @media ${smallTablet} { + @media ${mobile} { flex-direction: column; gap: 8px; margin: 0; diff --git a/packages/client/src/pages/PortalSettings/categories/common/Appearance/StyledPreview.js b/packages/client/src/pages/PortalSettings/categories/common/Appearance/StyledPreview.js index aaf2999df9..7deb572e87 100644 --- a/packages/client/src/pages/PortalSettings/categories/common/Appearance/StyledPreview.js +++ b/packages/client/src/pages/PortalSettings/categories/common/Appearance/StyledPreview.js @@ -101,12 +101,10 @@ const StyledComponent = styled.div` ${(props) => props.theme.interfaceDirection === "rtl" ? css` - margin-right: 12px; border-radius: 16px 0px 0px 16px; border-right-style: none; ` : css` - margin-left: 12px; border-radius: 0px 16px 16px 0px; border-left-style: none; `} @@ -444,7 +442,7 @@ const StyledMobilePreview = styled.div` themePreview === "Light" ? "#FFFFFF" : "#333333"}; border: ${({ themePreview }) => - themePreview === "Light" ? "1px solid #d0d5da" : "1px solid transparent"}; + themePreview === "Light" ? "1px solid #d0d5da" : "1px solid #474747"}; .section-search { height: 30px; @@ -452,7 +450,7 @@ const StyledMobilePreview = styled.div` align-items: center; border: 1px solid; border-radius: 3px; - padding-left: 8px; + padding-inline-start: 8px; } .main-button-preview { @@ -541,7 +539,7 @@ const StyledMobilePreview = styled.div` .tablet-tile-name { width: 44% !important; - margin-left: 16px; + margin-inline-start: 16px; border-right: none !important; border-radius: 12px 0 16px 0 !important; } @@ -567,7 +565,8 @@ const StyledMobilePreview = styled.div` display: flex; border-top-width: 1px; border-top-style: solid; - padding: 16px 0px 16px 16px; + padding-block: 16px; + padding-inline: 16px 0; } .tile-container { @@ -576,7 +575,7 @@ const StyledMobilePreview = styled.div` } .pin { - padding-right: 14px; + padding-inline-end: 14px; path { fill: ${(props) => @@ -623,17 +622,17 @@ const StyledMobilePreview = styled.div` : colorPreview} !important; } .section-badge { - padding-right: 12px; + padding-inline-end: 12px; } .tile-icon { - padding-right: 12px; + padding-inline-end: 12px; } .floating-button { position: relative; - margin-left: auto; - right: 0px; + margin-inline-start: auto; + inset-inline-end: 0; bottom: 48px; } diff --git a/packages/client/src/pages/PortalSettings/categories/common/Appearance/preview.js b/packages/client/src/pages/PortalSettings/categories/common/Appearance/preview.js index af298ae2e4..0c571853cf 100644 --- a/packages/client/src/pages/PortalSettings/categories/common/Appearance/preview.js +++ b/packages/client/src/pages/PortalSettings/categories/common/Appearance/preview.js @@ -1,8 +1,8 @@ import PlusPreviewSvgUrl from "PUBLIC_DIR/images/plus.preview.svg?url"; -import React, { useState, useEffect } from "react"; +import React, { useState, useEffect, useLayoutEffect } from "react"; import Loaders from "@docspace/common/components/Loaders"; import ContextMenuButton from "@docspace/components/context-menu-button"; -import { isTablet } from "react-device-detect"; + import { StyledComponent, StyledFloatingButton, @@ -12,7 +12,8 @@ import { import ButtonPlusIcon from "PUBLIC_DIR/images/actions.button.plus.react.svg"; import { saveToSessionStorage, getFromSessionStorage } from "../../../utils"; -import { isMobileOnly, isDesktop } from "react-device-detect"; + +import { isMobile, isTablet } from "@docspace/components/utils/device"; const Preview = (props) => { const { @@ -30,11 +31,10 @@ const Preview = (props) => { const [isSmallWindow, setIsSmallWindow] = useState(false); const onCheckView = () => { - const tablet = - isTablet || (window.innerWidth > 600 && window.innerWidth <= 1024); + const tablet = isTablet(); setIsViewTablet(tablet); - if (isDesktop && window.innerWidth < 600) { + if (isMobile()) { setIsSmallWindow(true); } else { setIsSmallWindow(false); @@ -60,7 +60,7 @@ const Preview = (props) => { saveToSessionStorage("selectColorAccent", colorPreview); }, [colorPreview]); - useEffect(() => { + useLayoutEffect(() => { onCheckView(); window.addEventListener("resize", onCheckView); @@ -69,7 +69,7 @@ const Preview = (props) => { }; }); - return isSmallWindow || isMobileOnly ? ( + return isSmallWindow || isMobile() ? ( { +const MobileView = ({ isSettingPaid }) => { const { t } = useTranslation(["Settings"]); const navigate = useNavigate(); @@ -24,18 +24,24 @@ const MobileView = () => { title={t("WhiteLabel")} subtitle={t("BrandingSubtitle")} url="/portal-settings/customization/branding/white-label" + withPaidBadge={!isSettingPaid} + badgeLabel={t("Common:Paid")} onClickLink={onClickLink} /> diff --git a/packages/client/src/pages/PortalSettings/categories/common/Branding/StyledWhitelabel.js b/packages/client/src/pages/PortalSettings/categories/common/Branding/StyledWhitelabel.js index 6772669901..84f761e6e8 100644 --- a/packages/client/src/pages/PortalSettings/categories/common/Branding/StyledWhitelabel.js +++ b/packages/client/src/pages/PortalSettings/categories/common/Branding/StyledWhitelabel.js @@ -1,6 +1,6 @@ import styled from "styled-components"; import { Base } from "@docspace/components/themes"; -import { smallTablet } from "@docspace/components/utils/device"; +import { mobile } from "@docspace/components/utils/device"; const WhiteLabelWrapper = styled.div` .subtitle { @@ -61,7 +61,7 @@ const WhiteLabelWrapper = styled.div` flex-direction: row; gap: 20px; - @media ${smallTablet} { + @media ${mobile} { flex-direction: column; } } @@ -78,7 +78,7 @@ const WhiteLabelWrapper = styled.div` gap: 8px; margin-bottom: 8px; - @media ${smallTablet} { + @media ${mobile} { flex-direction: column; } } @@ -113,7 +113,7 @@ const WhiteLabelWrapper = styled.div` height: 42px; padding: 12px 20px; - @media ${smallTablet} { + @media ${mobile} { width: 310px; height: 35px; } @@ -182,7 +182,7 @@ const WhiteLabelWrapper = styled.div` margin-top: 24px; } - @media ${smallTablet} { + @media ${mobile} { .subtitle, .header-container { display: none; diff --git a/packages/client/src/pages/PortalSettings/categories/common/Branding/additionalResources.js b/packages/client/src/pages/PortalSettings/categories/common/Branding/additionalResources.js index c6359db606..43a834c233 100644 --- a/packages/client/src/pages/PortalSettings/categories/common/Branding/additionalResources.js +++ b/packages/client/src/pages/PortalSettings/categories/common/Branding/additionalResources.js @@ -11,12 +11,12 @@ import toastr from "@docspace/components/toast/toastr"; import LoaderAdditionalResources from "../sub-components/loaderAdditionalResources"; import isEqual from "lodash/isEqual"; import { saveToSessionStorage, getFromSessionStorage } from "../../../utils"; -import { smallTablet, size } from "@docspace/components/utils/device"; +import { mobile, size } from "@docspace/components/utils/device"; const StyledComponent = styled.div` margin-top: 40px; - @media ${smallTablet} { + @media ${mobile} { margin-top: 0px; .header { @@ -44,8 +44,6 @@ const StyledComponent = styled.div` } .checkbox { - width: max-content; - ${(props) => props.theme.interfaceDirection === "rtl" ? css` @@ -110,7 +108,7 @@ const AdditionalResources = (props) => { }, []); const checkWidth = () => { - window.innerWidth > size.smallTablet && + window.innerWidth > size.mobile && location.pathname.includes("additional-resources") && navigate("/portal-settings/customization/branding"); }; @@ -272,7 +270,7 @@ const AdditionalResources = (props) => { onSaveClick={onSave} onCancelClick={onRestore} saveButtonLabel={t("Common:SaveButton")} - cancelButtonLabel={t("Settings:RestoreDefaultButton")} + cancelButtonLabel={t("Common:Restore")} displaySettings={true} reminderTest={t("YouHaveUnsavedChanges")} showReminder={(isSettingPaid && hasChange) || isLoading} diff --git a/packages/client/src/pages/PortalSettings/categories/common/Branding/companyInfoSettings.js b/packages/client/src/pages/PortalSettings/categories/common/Branding/companyInfoSettings.js index 529c87a5d7..073116b060 100644 --- a/packages/client/src/pages/PortalSettings/categories/common/Branding/companyInfoSettings.js +++ b/packages/client/src/pages/PortalSettings/categories/common/Branding/companyInfoSettings.js @@ -14,7 +14,7 @@ import Link from "@docspace/components/link"; import LoaderCompanyInfoSettings from "../sub-components/loaderCompanyInfoSettings"; import AboutDialog from "../../../../About/AboutDialog"; import { saveToSessionStorage, getFromSessionStorage } from "../../../utils"; -import { smallTablet, size } from "@docspace/components/utils/device"; +import { mobile, size } from "@docspace/components/utils/device"; const StyledComponent = styled.div` .link { @@ -40,7 +40,7 @@ const StyledComponent = styled.div` padding-bottom: 16px; } - @media ${smallTablet} { + @media ${mobile} { .header { display: none; } @@ -99,7 +99,7 @@ const CompanyInfoSettings = (props) => { }, []); const checkWidth = () => { - window.innerWidth > size.smallTablet && + window.innerWidth > size.mobile && location.pathname.includes("company-info-settings") && navigate("/portal-settings/customization/branding"); }; @@ -440,7 +440,7 @@ const CompanyInfoSettings = (props) => { onSaveClick={onSave} onCancelClick={onRestore} saveButtonLabel={t("Common:SaveButton")} - cancelButtonLabel={t("Settings:RestoreDefaultButton")} + cancelButtonLabel={t("Common:Restore")} reminderTest={t("YouHaveUnsavedChanges")} displaySettings={true} showReminder={(isSettingPaid && showReminder) || isLoading} diff --git a/packages/client/src/pages/PortalSettings/categories/common/Branding/sub-components/logo.js b/packages/client/src/pages/PortalSettings/categories/common/Branding/sub-components/logo.js index d362f52da7..afb62d474d 100644 --- a/packages/client/src/pages/PortalSettings/categories/common/Branding/sub-components/logo.js +++ b/packages/client/src/pages/PortalSettings/categories/common/Branding/sub-components/logo.js @@ -1,9 +1,10 @@ import React from "react"; -import { isMobileOnly } from "react-device-detect"; + import { getLogoFromPath } from "@docspace/common/utils"; import Text from "@docspace/components/text"; import Link from "@docspace/components/link"; +import { isMobile } from "@docspace/components/utils/device"; const Logo = (props) => { const { @@ -21,7 +22,7 @@ const Logo = (props) => { const currentLogo = getLogoFromPath(src); const onLogoClick = () => { - isMobileOnly && document.getElementById(inputId).click(); + isMobile() && document.getElementById(inputId).click(); }; return ( diff --git a/packages/client/src/pages/PortalSettings/categories/common/Branding/whitelabel.js b/packages/client/src/pages/PortalSettings/categories/common/Branding/whitelabel.js index 4c6094e11e..47d5850f3e 100644 --- a/packages/client/src/pages/PortalSettings/categories/common/Branding/whitelabel.js +++ b/packages/client/src/pages/PortalSettings/categories/common/Branding/whitelabel.js @@ -65,7 +65,7 @@ const WhiteLabel = (props) => { }, []); const checkWidth = () => { - window.innerWidth > size.smallTablet && + window.innerWidth > size.mobile && location.pathname.includes("white-label") && navigate("/portal-settings/customization/branding"); }; @@ -488,8 +488,9 @@ const WhiteLabel = (props) => { onSaveClick={onSave} onCancelClick={onRestoreDefault} saveButtonLabel={t("Common:SaveButton")} - cancelButtonLabel={t("RestoreDefaultButton")} + cancelButtonLabel={t("Common:Restore")} displaySettings={true} + hasScroll={true} showReminder={isSettingPaid} saveButtonDisabled={isEqualLogo && isEqualText} isSaving={isSaving} diff --git a/packages/client/src/pages/PortalSettings/categories/common/Customization/StyledSettings.js b/packages/client/src/pages/PortalSettings/categories/common/Customization/StyledSettings.js index ecff1c20b7..6545a4c40c 100644 --- a/packages/client/src/pages/PortalSettings/categories/common/Customization/StyledSettings.js +++ b/packages/client/src/pages/PortalSettings/categories/common/Customization/StyledSettings.js @@ -5,7 +5,7 @@ import ArrowRightIcon from "PUBLIC_DIR/images/arrow.right.react.svg"; import commonIconsStyles from "@docspace/components/utils/common-icons-style"; import { Base } from "@docspace/components/themes"; import { UnavailableStyles } from "../../../utils/commonSettingsStyles"; -import { mobile } from "@docspace/components/utils/device"; +import { mobile, desktop, mobileMore } from "@docspace/components/utils/device"; const menuHeight = "48px"; const sectionHeight = "50px"; @@ -16,7 +16,7 @@ const flex = "4px"; const StyledArrowRightIcon = styled(ArrowRightIcon)` ${commonIconsStyles} path { - fill: ${props => props.theme.client.settings.common.arrowColor}; + fill: ${(props) => props.theme.client.settings.common.arrowColor}; } `; @@ -35,7 +35,7 @@ const StyledScrollbar = styled(Scrollbar)` const StyledSettingsComponent = styled.div` .dns-setting_helpbutton { - ${props => + ${(props) => props.theme.interfaceDirection === "rtl" ? css` margin-left: 4px; @@ -51,9 +51,9 @@ const StyledSettingsComponent = styled.div` .dns-textarea { textarea { - color: ${props => props.theme.text.disableColor}; + color: ${(props) => props.theme.text.disableColor}; } - ${props => props.standalone && "margin-top: 14px"}; + ${(props) => props.standalone && "margin-top: 14px"}; } .combo-button-label { @@ -74,15 +74,12 @@ const StyledSettingsComponent = styled.div` .settings-block-description { line-height: 20px; - color: ${props => props.theme.client.settings.security.descriptionColor}; + color: ${(props) => props.theme.client.settings.security.descriptionColor}; padding-bottom: 12px; } - .send-request-button { - height: 40px; - } - .combo-box-settings { + padding: 0px; .combo-button { justify-content: space-between !important; } @@ -114,12 +111,12 @@ const StyledSettingsComponent = styled.div` } } - @media (max-width: 599px) { - ${props => + @media ${mobile} { + ${(props) => props.hasScroll && css` width: ${isMobileOnly ? "100vw" : "calc(100vw - 52px)"}; - ${props => + ${(props) => props.theme.interfaceDirection === "rtl" ? css` right: -16px; @@ -132,7 +129,7 @@ const StyledSettingsComponent = styled.div` .settings-block { width: ${isMobileOnly ? "calc(100vw - 32px)" : "calc(100vw - 84px)"}; max-width: none; - ${props => + ${(props) => props.theme.interfaceDirection === "rtl" ? css` padding-right: 16px; @@ -147,7 +144,7 @@ const StyledSettingsComponent = styled.div` box-sizing: border-box; position: absolute; bottom: 0; - ${props => + ${(props) => props.theme.interfaceDirection === "rtl" ? css` right: 0; @@ -164,7 +161,7 @@ const StyledSettingsComponent = styled.div` } } - @media (min-width: 600px) { + @media ${mobileMore} { .settings-block { max-width: 350px; height: auto; @@ -176,13 +173,7 @@ const StyledSettingsComponent = styled.div` } } - @media (min-width: 1024px) { - .send-request-button { - height: 32px; - } - } - - @media (orientation: landscape) and (max-width: 600px) { + @media (orientation: landscape) and ${mobile} { ${isMobileOnly && css` .settings-block { @@ -190,7 +181,7 @@ const StyledSettingsComponent = styled.div` } `} } - ${props => !props.isSettingPaid && UnavailableStyles} + ${(props) => !props.isSettingPaid && UnavailableStyles} `; export { StyledSettingsComponent, StyledScrollbar, StyledArrowRightIcon }; diff --git a/packages/client/src/pages/PortalSettings/categories/common/Customization/dns-settings.js b/packages/client/src/pages/PortalSettings/categories/common/Customization/dns-settings.js index fbedd655f0..ae66d228de 100644 --- a/packages/client/src/pages/PortalSettings/categories/common/Customization/dns-settings.js +++ b/packages/client/src/pages/PortalSettings/categories/common/Customization/dns-settings.js @@ -8,8 +8,7 @@ import Button from "@docspace/components/button"; import { inject, observer } from "mobx-react"; import { useNavigate } from "react-router-dom"; -import { isMobileOnly } from "react-device-detect"; -import { isSmallTablet } from "@docspace/components/utils/device"; +import { isMobile } from "@docspace/components/utils/device"; import checkScrollSettingsBlock from "../utils"; import { StyledSettingsComponent, StyledScrollbar } from "./StyledSettings"; import { setDocumentTitle } from "SRC_DIR/helpers/utils"; @@ -20,6 +19,7 @@ import toastr from "@docspace/components/toast/toastr"; import ToggleButton from "@docspace/components/toggle-button"; import Text from "@docspace/components/text"; import Link from "@docspace/components/link"; +import { DeviceType } from "@docspace/common/constants"; const toggleStyle = { position: "static", @@ -36,7 +36,6 @@ const buttonProps = { tabIndex: 9, className: "save-cancel-buttons send-request-button", primary: true, - size: "small", }; let timerId = null; const DNSSettings = (props) => { @@ -60,6 +59,7 @@ const DNSSettings = (props) => { enable, isDefaultDNS, dnsSettingsUrl, + currentDeviceType, } = props; const [hasScroll, setHasScroll] = useState(false); const isLoadedSetting = isLoaded && tReady; @@ -128,7 +128,7 @@ const DNSSettings = (props) => { setDNSName(value); }; const checkInnerWidth = useCallback(() => { - if (!isSmallTablet()) { + if (!isMobile()) { setIsCustomizationView(true); const currentUrl = window.location.href.replace( @@ -144,7 +144,7 @@ const DNSSettings = (props) => { } else { setIsCustomizationView(false); } - }, [isSmallTablet, setIsCustomizationView]); + }, [isMobile, setIsCustomizationView]); const settingsBlock = (
@@ -191,6 +191,7 @@ const DNSSettings = (props) => { const buttonContainer = standalone ? (
diff --git a/packages/client/src/pages/PortalSettings/categories/common/Customization/portal-renaming.js b/packages/client/src/pages/PortalSettings/categories/common/Customization/portal-renaming.js index 79b349dcd5..9d6497be03 100644 --- a/packages/client/src/pages/PortalSettings/categories/common/Customization/portal-renaming.js +++ b/packages/client/src/pages/PortalSettings/categories/common/Customization/portal-renaming.js @@ -6,8 +6,7 @@ import TextInput from "@docspace/components/text-input"; import SaveCancelButtons from "@docspace/components/save-cancel-buttons"; import { inject, observer } from "mobx-react"; import { useNavigate } from "react-router-dom"; -import { isMobileOnly } from "react-device-detect"; -import { isSmallTablet } from "@docspace/components/utils/device"; +import { isMobile } from "@docspace/components/utils/device"; import checkScrollSettingsBlock from "../utils"; import { StyledSettingsComponent, StyledScrollbar } from "./StyledSettings"; import { saveToSessionStorage, getFromSessionStorage } from "../../../utils"; @@ -240,7 +239,7 @@ const PortalRenaming = (props) => { }; const checkInnerWidth = useCallback(() => { - if (!isSmallTablet()) { + if (!isMobile()) { setIsCustomizationView(true); const currentUrl = window.location.href.replace( @@ -255,7 +254,7 @@ const PortalRenaming = (props) => { } else { setIsCustomizationView(false); } - }, [isSmallTablet, setIsCustomizationView]); + }, [isMobile, setIsCustomizationView]); const onOpenModal = () => { setIsShowModal(true); diff --git a/packages/client/src/pages/PortalSettings/categories/common/Customization/welcome-page-settings.js b/packages/client/src/pages/PortalSettings/categories/common/Customization/welcome-page-settings.js index 888ec86ba5..bb476573c5 100644 --- a/packages/client/src/pages/PortalSettings/categories/common/Customization/welcome-page-settings.js +++ b/packages/client/src/pages/PortalSettings/categories/common/Customization/welcome-page-settings.js @@ -4,17 +4,14 @@ import { withTranslation } from "react-i18next"; import FieldContainer from "@docspace/components/field-container"; import toastr from "@docspace/components/toast/toastr"; import TextInput from "@docspace/components/text-input"; -import HelpButton from "@docspace/components/help-button"; import SaveCancelButtons from "@docspace/components/save-cancel-buttons"; import { saveToSessionStorage, getFromSessionStorage } from "../../../utils"; import { setDocumentTitle } from "SRC_DIR/helpers/utils"; import { inject, observer } from "mobx-react"; -import config from "PACKAGE_FILE"; import { useNavigate } from "react-router-dom"; -import { isMobileOnly } from "react-device-detect"; -import { isSmallTablet } from "@docspace/components/utils/device"; +import { isMobile } from "@docspace/components/utils/device"; import checkScrollSettingsBlock from "../utils"; -import { StyledSettingsComponent, StyledScrollbar } from "./StyledSettings"; +import { StyledSettingsComponent } from "./StyledSettings"; import LoaderCustomization from "../sub-components/loaderCustomization"; import withLoading from "SRC_DIR/HOCs/withLoading"; import Text from "@docspace/components/text"; @@ -135,10 +132,6 @@ const WelcomePageSettings = (props) => { setState((val) => ({ ...val, hasScroll: scrollLngTZSettings })); } - if (greetingSettings !== prevProps.greetingSettings) { - setState((val) => ({ ...val, greetingTitle: greetingSettings })); - } - if (state.greetingTitleDefault || state.greetingTitle) { checkChanges(); } @@ -156,7 +149,6 @@ const WelcomePageSettings = (props) => { isLoaded, setIsLoadedWelcomePageSettings, tReady, - greetingSettings, getSettings, getGreetingSettingsIsDefault, state.hasScroll, @@ -165,6 +157,19 @@ const WelcomePageSettings = (props) => { state.isLoadingGreetingRestore, ]); + React.useEffect(() => { + greetingTitleFromSessionStorage = getFromSessionStorage("greetingTitle"); + const emptyGreetingTitleFromSessionStorage = + greetingTitleFromSessionStorage === null || + greetingTitleFromSessionStorage === "none"; + + if (!emptyGreetingTitleFromSessionStorage) return; + + if (greetingSettings !== state.greetingTitle) { + setState((val) => ({ ...val, greetingTitle: greetingSettings })); + } + }, [greetingSettings]); + React.useEffect(() => { prevProps.current = { isLoaded, tReady, greetingSettings }; }, [isLoaded, tReady, greetingSettings]); @@ -217,8 +222,6 @@ const WelcomePageSettings = (props) => { .then(() => { setState((val) => ({ ...val, - greetingTitle: greetingSettings, - greetingTitleDefault: greetingSettings, showReminder: false, })); @@ -262,7 +265,7 @@ const WelcomePageSettings = (props) => { }; const checkInnerWidth = () => { - if (!isSmallTablet()) { + if (!isMobile()) { setState((val) => ({ ...val, isCustomizationView: true })); const currentUrl = window.location.href.replace( diff --git a/packages/client/src/pages/PortalSettings/categories/common/appearance.js b/packages/client/src/pages/PortalSettings/categories/common/appearance.js index 2b79a812e7..a432c8813c 100644 --- a/packages/client/src/pages/PortalSettings/categories/common/appearance.js +++ b/packages/client/src/pages/PortalSettings/categories/common/appearance.js @@ -15,7 +15,6 @@ import DropDownItem from "@docspace/components/drop-down-item"; import DropDownContainer from "@docspace/components/drop-down"; import HexColorPickerComponent from "./sub-components/hexColorPicker"; -import { isMobileOnly, isDesktop } from "react-device-detect"; import Loader from "./sub-components/loaderAppearance"; @@ -23,6 +22,8 @@ import { StyledComponent, StyledTheme } from "./Appearance/StyledApperance.js"; import { ReactSVG } from "react-svg"; import ModalDialogDelete from "./sub-components/modalDialogDelete"; import hexToRgba from "hex-to-rgba"; +import { isMobile } from "@docspace/components/utils/device"; +import { DeviceType } from "@docspace/common/constants"; const Appearance = (props) => { const { @@ -34,6 +35,7 @@ const Appearance = (props) => { deleteAppearanceTheme, tReady, t, + currentDeviceType, } = props; const defaultAppliedColorAccent = currentColorScheme.main.accent; @@ -287,7 +289,7 @@ const Appearance = (props) => { ); const onCheckView = () => { - if (isDesktop && window.innerWidth < 600) { + if (isMobile()) { setIsSmallWindow(true); } else { setIsSmallWindow(false); @@ -458,36 +460,40 @@ const Appearance = (props) => { return textColor; }; - const onAppliedColorAccent = useCallback(() => { - if (appliedColorAccent.toUpperCase() !== currentColorAccent) { - setChangeCurrentColorAccent(true); - } + const onAppliedColorAccent = useCallback( + (color) => { + if (color.toUpperCase() !== currentColorAccent) { + setChangeCurrentColorAccent(true); + } - setCurrentColorAccent(appliedColorAccent); - saveToSessionStorage("selectColorAccent", appliedColorAccent); + setCurrentColorAccent(color); + saveToSessionStorage("selectColorAccent", color); - setOpenHexColorPickerAccent(false); - }, [ - appliedColorAccent, - currentColorAccent, - setChangeCurrentColorAccent, - setOpenHexColorPickerAccent, - ]); + setOpenHexColorPickerAccent(false); + }, + [ + currentColorAccent, + setChangeCurrentColorAccent, + setOpenHexColorPickerAccent, + ] + ); - const onAppliedColorButtons = useCallback(() => { - if (appliedColorButtons.toUpperCase() !== currentColorButtons) { - setChangeCurrentColorButtons(true); - } + const onAppliedColorButtons = useCallback( + (color) => { + if (color.toUpperCase() !== currentColorButtons) { + setChangeCurrentColorButtons(true); + } - setCurrentColorButtons(appliedColorButtons); + setCurrentColorButtons(color); - setOpenHexColorPickerButtons(false); - }, [ - appliedColorButtons, - currentColorButtons, - setChangeCurrentColorButtons, - setOpenHexColorPickerButtons, - ]); + setOpenHexColorPickerButtons(false); + }, + [ + currentColorButtons, + setChangeCurrentColorButtons, + setOpenHexColorPickerButtons, + ] + ); const onSaveNewThemes = useCallback( async (theme) => { @@ -588,8 +594,7 @@ const Appearance = (props) => { id="buttons-hex" onCloseHexColorPicker={onCloseHexColorPickerButtons} onAppliedColor={onAppliedColorButtons} - color={appliedColorButtons} - setColor={setAppliedColorButtons} + appliedColor={appliedColorButtons} /> @@ -609,8 +614,7 @@ const Appearance = (props) => { id="accent-hex" onCloseHexColorPicker={onCloseHexColorPickerAccent} onAppliedColor={onAppliedColorAccent} - color={appliedColorAccent} - setColor={setAppliedColorAccent} + appliedColor={appliedColorAccent} /> @@ -624,6 +628,9 @@ const Appearance = (props) => { ); }; + const buttonSize = + currentDeviceType === DeviceType.desktop ? "small" : "normal"; + return !tReady ? ( ) : ( @@ -734,7 +741,7 @@ const Appearance = (props) => { label={t("Common:SaveButton")} onClick={onSave} primary - size="small" + size={buttonSize} isDisabled={isDisabledSaveButton} /> @@ -742,7 +749,7 @@ const Appearance = (props) => { className="edit-current-theme button" label={t("Common:EditButton")} onClick={onClickEdit} - size="small" + size={buttonSize} isDisabled={isDisabledEditButton} /> {isShowDeleteButton && ( @@ -750,7 +757,7 @@ const Appearance = (props) => { className="delete-theme button" label={t("Settings:DeleteTheme")} onClick={onOpenDialogDelete} - size="small" + size={buttonSize} isDisabled={isDisabledDeleteButton} /> )} @@ -770,6 +777,7 @@ export default inject(({ auth }) => { currentColorScheme, deleteAppearanceTheme, theme, + currentDeviceType, } = settingsStore; return { @@ -779,6 +787,7 @@ export default inject(({ auth }) => { getAppearanceTheme, currentColorScheme, deleteAppearanceTheme, + currentDeviceType, theme, }; })(withTranslation(["Profile", "Common", "Settings"])(observer(Appearance))); diff --git a/packages/client/src/pages/PortalSettings/categories/common/branding.js b/packages/client/src/pages/PortalSettings/categories/common/branding.js index 28bd9c5fdb..fb5e447089 100644 --- a/packages/client/src/pages/PortalSettings/categories/common/branding.js +++ b/packages/client/src/pages/PortalSettings/categories/common/branding.js @@ -75,7 +75,7 @@ const Branding = ({ }; }, []); - if (isMobileView) return ; + if (isMobileView) return ; return ( diff --git a/packages/client/src/pages/PortalSettings/categories/common/customization.js b/packages/client/src/pages/PortalSettings/categories/common/customization.js index 7024fbf07c..7045ccd908 100644 --- a/packages/client/src/pages/PortalSettings/categories/common/customization.js +++ b/packages/client/src/pages/PortalSettings/categories/common/customization.js @@ -2,7 +2,7 @@ import React, { useEffect, useState } from "react"; import { withTranslation } from "react-i18next"; import styled, { css } from "styled-components"; import { inject, observer } from "mobx-react"; -import withCultureNames from "@docspace/common/hoc/withCultureNames"; +//import withCultureNames from "@docspace/common/hoc/withCultureNames"; import LanguageAndTimeZone from "./Customization/language-and-time-zone"; import WelcomePageSettings from "./Customization/welcome-page-settings"; import PortalRenaming from "./Customization/portal-renaming"; @@ -13,6 +13,7 @@ import { setDocumentTitle } from "SRC_DIR/helpers/utils"; import LoaderDescriptionCustomization from "./sub-components/loaderDescriptionCustomization"; import withLoading from "SRC_DIR/HOCs/withLoading"; import StyledSettingsSeparator from "SRC_DIR/pages/PortalSettings/StyledSettingsSeparator"; +import { mobileMore } from "@docspace/components/utils/device"; const StyledComponent = styled.div` width: 100%; @@ -58,7 +59,7 @@ const StyledComponent = styled.div` margin-bottom: 24px; } - @media (min-width: 600px) { + @media ${mobileMore} { .settings-block { max-width: 350px; height: auto; diff --git a/packages/client/src/pages/PortalSettings/categories/common/index.js b/packages/client/src/pages/PortalSettings/categories/common/index.js index 0d14923843..913cd64df1 100644 --- a/packages/client/src/pages/PortalSettings/categories/common/index.js +++ b/packages/client/src/pages/PortalSettings/categories/common/index.js @@ -11,6 +11,7 @@ import Appearance from "./appearance"; import withLoading from "SRC_DIR/HOCs/withLoading"; import LoaderSubmenu from "./sub-components/loaderSubmenu"; import { resetSessionStorage } from "../../utils"; +import { DeviceType } from "@docspace/common/constants"; const SubmenuCommon = (props) => { const { @@ -21,6 +22,7 @@ const SubmenuCommon = (props) => { loadBaseInfo, isLoadedSubmenu, getWhiteLabelLogoUrls, + currentDeviceType, } = props; const navigate = useNavigate(); @@ -85,11 +87,18 @@ const SubmenuCommon = (props) => { data={data} startSelect={currentTab} onSelect={(e) => onSelect(e)} + topProps={ + currentDeviceType === DeviceType.desktop + ? 0 + : currentDeviceType === DeviceType.mobile + ? "53px" + : "61px" + } /> ); }; -export default inject(({ common }) => { +export default inject(({ auth, common }) => { const { isLoaded, setIsLoadedSubmenu, @@ -105,5 +114,6 @@ export default inject(({ common }) => { setIsLoadedSubmenu, isLoadedSubmenu, getWhiteLabelLogoUrls, + currentDeviceType: auth.settingsStore.currentDeviceType, }; })(withLoading(withTranslation("Settings")(observer(SubmenuCommon)))); diff --git a/packages/client/src/pages/PortalSettings/categories/common/sub-components/hexColorPicker.js b/packages/client/src/pages/PortalSettings/categories/common/sub-components/hexColorPicker.js index 66705642b5..a9c79f9405 100644 --- a/packages/client/src/pages/PortalSettings/categories/common/sub-components/hexColorPicker.js +++ b/packages/client/src/pages/PortalSettings/categories/common/sub-components/hexColorPicker.js @@ -1,4 +1,4 @@ -import React from "react"; +import React, { useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; import styled, { css } from "styled-components"; import Button from "@docspace/components/button"; @@ -7,7 +7,7 @@ import { isMobileOnly } from "react-device-detect"; const StyledComponent = styled.div` .save-button { - ${props => + ${(props) => props.theme.interfaceDirection === "rtl" ? css` margin-left: 10px; @@ -59,12 +59,12 @@ const StyledComponent = styled.div` height: 32px; outline: none; padding: 6px 8px; - border: 1px solid ${props => (props.theme.isBase ? "#d0d5da" : "#474747")}; + border: 1px solid ${(props) => (props.theme.isBase ? "#d0d5da" : "#474747")}; border-radius: 3px; width: 100%; box-sizing: border-box; - background: ${props => !props.theme.isBase && "#282828"}; - color: ${props => !props.theme.isBase && "#5C5C5C"}; + background: ${(props) => !props.theme.isBase && "#282828"}; + color: ${(props) => !props.theme.isBase && "#5C5C5C"}; } .hex-value-label { @@ -75,7 +75,7 @@ const StyledComponent = styled.div` display: flex; .apply-button { - ${props => + ${(props) => props.theme.interfaceDirection === "rtl" ? css` margin-left: 8px; @@ -112,11 +112,19 @@ const StyledComponent = styled.div` } `; -const HexColorPickerComponent = props => { - const { onCloseHexColorPicker, onAppliedColor, setColor, color } = props; +const HexColorPickerComponent = (props) => { + const { onCloseHexColorPicker, onAppliedColor, appliedColor } = props; + + const [color, setColor] = useState(appliedColor); const { t } = useTranslation("Common"); + useEffect(() => { + if (color !== appliedColor) { + setColor(appliedColor); + } + }, [appliedColor]); + return (
@@ -140,7 +148,7 @@ const HexColorPickerComponent = props => { className="apply-button" primary={true} scale={true} - onClick={onAppliedColor} + onClick={() => onAppliedColor(color)} />