Merge branch 'develop' into 'feature/data-migration' | conflict components/paging/styled-paging.js

This commit is contained in:
Vladimir Khvan 2023-10-16 20:05:15 +05:00
commit ea7b067e7f
498 changed files with 4025 additions and 3841 deletions

View File

@ -1,6 +1,6 @@
{
"LblInviteAgain": "ادعوه مرة أخرى",
"MessageEmailActivationInstuctionsSentOnEmail": "The email activation instructions have been sent to the <1>{{email}}</1> email address.",
"MessageEmailActivationInstuctionsSentOnEmail": "The email activation instructions have been sent to the <strong>{{email}}</strong> email address.",
"NotFoundUsers": "لم يتم العثور على مستخدمين",
"UserStatus": "الحالة"
}

View File

@ -150,7 +150,6 @@
"RecoveryFileNotSelected": "خطأ في الاسترداد. لم يتم تحديد ملف الاسترداد.",
"RestoreBackup": "استرجاع",
"RestoreBackupDescription": "استخدم هذا الخيار لاستعادة إستضافتك من ملف النسخ الاحتياطي المحفوظ مسبقًا.",
"RestoreDefaultButton": "استعادة الى الافتراضي",
"RoomsModule": "غرفة النسخ الاحتياطي",
"RoomsModuleDescription": "يمكنك إنشاء غرفة جديدة خصيصًا للنسخ الاحتياطي ، أو اختيار إحدى الغرف الموجودة ، أو حفظ النسخة في غرفة {{roomName}} الخاصة بهم.",
"SelectFileInGZFormat": "حدد الملف بتنسيق ملف مضغوط",

View File

@ -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",

View File

@ -159,7 +159,6 @@
"RecoveryFileNotSelected": "Грешка при възстановяване. Файлът за възстановяване не е избран.",
"RestoreBackup": "Възстановяване на данни",
"RestoreBackupDescription": "Използвайте тази опция, за да възстановите портала от предварително записания архивен файл.",
"RestoreDefaultButton": "Възстановяване по Подразбиране",
"RoomsModule": "Резервна стая",
"RoomsModuleDescription": "Можете да създадете нова стая специално за резервното копие, да изберете една от съществуващите стаи или да запазите копието в тяхната стая {{roomName}}.",
"SelectFileInGZFormat": "Изберете файла във формат .GZ",

View File

@ -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",

View File

@ -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",

View File

@ -152,7 +152,6 @@
"RecoveryFileNotSelected": "Σφάλμα ανάκτησης. Το αρχείο ανάκτησης δεν έχει επιλεγεί.",
"RestoreBackup": "Επαναφορά Δεδομένων",
"RestoreBackupDescription": "Χρησιμοποιήστε αυτήν την επιλογή για να επαναφέρετε την DocSpace σας από το αρχείο αντιγράφων ασφαλείας που είχε αποθηκευτεί προηγουμένως.",
"RestoreDefaultButton": "Επαναφορά στην προεπιλογή",
"RoomsModule": "Δημιουργία αντιγράφου ασφαλείας δωματίου",
"RoomsModuleDescription": "Μπορείτε να δημιουργήσετε ένα νέο δωμάτιο ειδικά για το αντίγραφο ασφαλείας, να επιλέξετε ένα από τα υπάρχοντα δωμάτια ή να αποθηκεύσετε το αντίγραφο στο δωμάτιό τους {{roomName}}.",
"SelectFileInGZFormat": "Επιλογή αρχείου σε μορφή .GZ",

View File

@ -140,6 +140,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",

View File

@ -1,6 +1,6 @@
{
"LblInviteAgain": "Invite again",
"MessageEmailActivationInstuctionsSentOnEmail": "The email activation instructions have been sent to the <1>{{email}}</1> email address.",
"MessageEmailActivationInstuctionsSentOnEmail": "The email activation instructions have been sent to the <strong>{{email}}</strong> 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",

View File

@ -219,7 +219,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.",
"SelectFileDescription": "Select the Google Workspace backup files to start the data import. Multiple files can be selected. Once the data upload and analysis are complete, the next step will be initiated automatically.",

View File

@ -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",

View File

@ -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",

View File

@ -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 lune des salles existantes ou enregistrer la copie dans la salle {{roomName}}.",
"SelectFileInGZFormat": "Sélectionnez le fichier au format .GZ",

View File

@ -153,7 +153,6 @@
"RecoveryFileNotSelected": "Վերականգնման սխալ. Վերականգնման ֆայլը ընտրված չէ:",
"RestoreBackup": "Տվյալների վերականգնում",
"RestoreBackupDescription": "Օգտագործեք այս տարբերակը՝ Ձեր կայքէջը նախկինում պահված պահուստային ֆայլից վերականգնելու համար:",
"RestoreDefaultButton": "Վերականգնել լռելյայն",
"RoomsModule": "Պահուստավորման սենյակ",
"RoomsModuleDescription": "Դուք կարող եք ստեղծել նոր սենյակ հատուկ պահուստավորման համար, ընտրել առկա սենյակներից մեկը կամ պատճենը պահել իր {{roomName}} սենյակում:",
"SelectFileInGZFormat": "Ընտրեք ֆայլը .GZ ձևաչափով",

View File

@ -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",

View File

@ -159,7 +159,6 @@
"RecoveryFileNotSelected": "回復エラー。回復ファイルが選択されていません。",
"RestoreBackup": "データ復元",
"RestoreBackupDescription": "バックアップ・ファイルからスペースを復するためにこの操作を使用してください。",
"RestoreDefaultButton": "デフォルトに戻す",
"RoomsModule": "ルームをバックアップする",
"RoomsModuleDescription": "バックアップのために特別に新しいルームを作るか、既存のルームの一つを選ぶか、その {{roomName}} ルムにコピーを保存することができます。",
"SelectFileInGZFormat": "「.GZ」形式ファイルを選択してください。",

View File

@ -151,7 +151,6 @@
"RecoveryFileNotSelected": "복원 오류입니다. 복원 파일이 선택되지 않았습니다",
"RestoreBackup": "데이터 복원",
"RestoreBackupDescription": "이전에 저장한 백업 파일에서 스페이스를 복원하기 위해 이 옵션을 사용하세요.",
"RestoreDefaultButton": "기본값으로 복원",
"RoomsModule": "백업 방",
"RoomsModuleDescription": "특별히 백업용으로 새 방을 만들거나 기존 방 중 하나를 선택하거나 {{roomName}} 방에 사본을 저장할 수 있습니다.",
"SelectFileInGZFormat": ".GZ 형식의 파일을 선택해주세요",

View File

@ -151,7 +151,6 @@
"RecoveryFileNotSelected": "ການ​ຟື້ນ​ຕົວ​ຄວາມ​ຜິດ​ພາດ​. ການ​ຟື້ນ​ຕົວ​ໄຟລ​໌​ບໍ່​ໄດ້​ເລືອກ.",
"RestoreBackup": "ຂໍ້ມູນ ຟື້ນຟູ",
"RestoreBackupDescription": "ໃຊ້ຕົວເລືອກນີ້ເພື່ອຟື້ນຟູປະຕູຂອງເຈົ້າຈາກໄຟລ໌ສຳຮອງທີ່ບັນທຶກໄວ້ໃນເມື່ອກ່ອນ. ",
"RestoreDefaultButton": "ກູ້ຄືນເປັນຄ່າເລີ່ມຕົ້ນ",
"RoomsModule": "ສຳຮອງຂໍ້ມູນຫ້ອງ",
"RoomsModuleDescription": "ທ່ານອາດຈະສ້າງຫ້ອງໃຫມ່ໂດຍສະເພາະສໍາລັບການ ສໍາຮອງຂໍ້ມູນ, ເລືອກຫນຶ່ງຂອງຫ້ອງທີ່ມີຢູ່ແລ້ວ, ຫຼືບັນທຶກສໍາເນົາຢູ່ໃນ ຫ້ອງ {{ roomName }} ຂອງເຂົາເຈົ້າ.",
"SelectFileInGZFormat": "ເລືອກໄຟລ໌ໃນຮູບແບບ . GZ",

View File

@ -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ā",

View File

@ -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",

View File

@ -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",

View File

@ -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",

View File

@ -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",

View File

@ -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",

View File

@ -199,7 +199,6 @@
"RecoveryFileNotSelected": "Ошибка восстановления. Файл восстановления не выбран.",
"RestoreBackup": "Восстановление",
"RestoreBackupDescription": "Используйте эту опцию, чтобы восстановить портал из ранее сохраненного резервного файла.",
"RestoreDefaultButton": "Настройки по умолчанию",
"RoomsModule": "Резервная комната",
"RoomsModuleDescription": "Вы можете создать новую комнату специально для резервного копирования, выбрать одну из существующих комнат или сохранить копию в {{roomName}}.",
"SelectFileDescription": "Выберите файлы резервных копий Google Workspace, чтобы начать импорт данных. Можно выбрать несколько файлов. После завершения загрузки и анализа данных следующий шаг будет инициирован автоматически.",

View File

@ -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",

View File

@ -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",

View File

@ -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",

View File

@ -156,7 +156,6 @@
"RecoveryFileNotSelected": "Помилка відновлення. Файл відновлення не вибрано.",
"RestoreBackup": "Відновити дані",
"RestoreBackupDescription": "Використовуйте цю опцію, щоб відновити раніше збережений файл резервної копії вашого порталу.",
"RestoreDefaultButton": "Відновити значення за замовчуванням",
"RoomsModule": "Резервна кімната",
"RoomsModuleDescription": "Ви можете створити нову кімнату спеціально для резервного копіювання, вибрати одну з наявних кімнат або зберегти копію в їхній кімнаті {{roomName}}.",
"SelectFileInGZFormat": "Виберіть файл у форматі.GZ",

View File

@ -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",

View File

@ -156,7 +156,6 @@
"RecoveryFileNotSelected": "恢复错误。未选择恢复文件",
"RestoreBackup": "数据恢复",
"RestoreBackupDescription": "设置此选项,从之前保存的备份文件中恢复门户数据。",
"RestoreDefaultButton": "恢复至默认",
"RoomsModule": "备份房间",
"RoomsModuleDescription": "您可为备份专门新建一个房间,也可选择现有房间或将副本保存在其 {{roomName}} 房间中。",
"SelectFileInGZFormat": "选择 .GZ 格式的文件",

View File

@ -23,7 +23,12 @@ import {
} from "./components/Article";
const ClientArticle = React.memo(
({ withMainButton, setIsHeaderLoading, setIsFilterLoading }) => {
({
withMainButton,
setIsHeaderLoading,
setIsFilterLoading,
showArticleLoader,
}) => {
return (
<Article
withMainButton={withMainButton}
@ -31,6 +36,7 @@ const ClientArticle = React.memo(
setIsFilterLoading(true, false);
setIsHeaderLoading(true, false);
}}
showArticleLoader={showArticleLoader}
>
<Article.Header>
<ArticleHeaderContent />
@ -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());

View File

@ -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;
}
`;

View File

@ -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 {

View File

@ -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));

View File

@ -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));

View File

@ -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 &&

View File

@ -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 ? (
<Portal element={<Toast />} appendTo={rootElement} visible={true} />
) : (
<Toast />
);
const toast =
currentDeviceType === DeviceType.mobile ? (
<Portal element={<Toast />} appendTo={rootElement} visible={true} />
) : (
<Toast />
);
return (
<Layout>
{toast}
<ReactSmartBanner t={t} ready={ready} />
{/* <ReactSmartBanner t={t} ready={ready} /> */}
{isEditor ? <></> : <NavMenu />}
{isMobileOnly && <MainBar />}
{currentDeviceType === DeviceType.mobile && <MainBar />}
<IndicatorLoader />
<ScrollToTop />
<DialogsWrapper t={t} />
{/* {!bodyRendered && <AppLoader />} */}
<Main isDesktop={isDesktop}>
{!isMobileOnly && <MainBar />}
{currentDeviceType !== DeviceType.mobile && <MainBar />}
<div className="main-container">
<Outlet />
</div>
@ -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));

View File

@ -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");

View File

@ -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();

View File

@ -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)));

View File

@ -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)));

View File

@ -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;

View File

@ -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,
};
}
)(

View File

@ -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 }) => {
<StyledWrapper
onClick={onClick}
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
>
onMouseLeave={onMouseLeave}>
{newBadge}
</StyledWrapper>
);
@ -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";

View File

@ -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 }) =>

View File

@ -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);

View File

@ -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 => {
<EmptyFolderWrapper
sectionWidth={sectionWidth}
isEmptyPage={isEmptyPage}
isEmptyFolderContainer={isEmptyFolderContainer}>
isEmptyFolderContainer={isEmptyFolderContainer}
>
<EmptyScreenContainer
sectionWidth={sectionWidth}
className={classNames("empty-folder_container", className)}

View File

@ -5,8 +5,6 @@ import { useLocation } from "react-router-dom";
import RootFolderContainer from "./RootFolderContainer";
import EmptyFilterContainer from "./EmptyFilterContainer";
import EmptyFolderContainer from "./EmptyFolderContainer";
import { FileAction } from "@docspace/common/constants";
import { isMobile } from "react-device-detect";
import { Events } from "@docspace/common/constants";
import RoomNoAccessContainer from "./RoomNoAccessContainer";

View File

@ -126,6 +126,7 @@ export type FilesSelectorProps = {
isMove?: boolean;
isCopy?: boolean;
isRestoreAll?: boolean;
isSelect?: boolean;
filterParam?: string;
@ -160,7 +161,10 @@ export type FilesSelectorProps = {
onSetBaseFolderPath?: (value: number | string | undefined) => 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<string>;
currentDeviceType: "mobile" | "tablet" | "desktop";
embedded: boolean;
};

View File

@ -60,6 +60,7 @@ export const convertRoomsToItems = (rooms: any) => {
rootFolderType,
isFolder: true,
roomType,
color: logo.color,
};
});

View File

@ -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)

View File

@ -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 = (
<Selector
headerLabel={headerLabel}
withoutBackButton
searchPlaceholder={t("Common:Search")}
searchValue={searchValue}
onSearch={onSearchAction}
onClearSearch={onClearSearchAction}
items={items ? items : []}
onSelect={onSelectAction}
acceptButtonLabel={acceptButtonLabel}
onAccept={onAcceptAction}
withCancelButton
cancelButtonLabel={t("Common:CancelButton")}
onCancel={onCloseAction}
emptyScreenImage={
theme.isBase ? EmptyScreenAltSvgUrl : EmptyScreenAltSvgDarkUrl
}
emptyScreenHeader={t("SelectorEmptyScreenHeader")}
emptyScreenDescription=""
searchEmptyScreenImage={
theme.isBase
? EmptyScreenFilterAltSvgUrl
: EmptyScreenFilterAltDarkSvgUrl
}
searchEmptyScreenHeader={t("Common:NotFoundTitle")}
searchEmptyScreenDescription={t("EmptyFilterDescriptionText")}
withBreadCrumbs
breadCrumbs={breadCrumbs}
onSelectBreadCrumb={onClickBreadCrumb}
isLoading={showLoader}
isBreadCrumbsLoading={showBreadCrumbsLoader}
withSearch={!isRoot && items ? items.length > 0 : !isRoot && isFirstLoad}
rowLoader={
<Loaders.SelectorRowLoader
isMultiSelect={false}
isUser={isRoot}
isContainer={showLoader}
/>
}
searchLoader={<Loaders.SelectorSearchLoader />}
breadCrumbsLoader={<Loaders.SelectorBreadCrumbsLoader />}
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
) : (
<>
<Backdrop
visible={isPanelVisible}
isAside
withBackground
zIndex={210}
zIndex={309}
onClick={onCloseAction}
/>
<Aside
@ -468,75 +543,16 @@ const FilesSelector = ({
zIndex={310}
onClose={onCloseAction}
>
<Selector
headerLabel={headerLabel}
withoutBackButton
searchPlaceholder={t("Common:Search")}
searchValue={searchValue}
onSearch={onSearchAction}
onClearSearch={onClearSearchAction}
items={items ? items : []}
onSelect={onSelectAction}
acceptButtonLabel={acceptButtonLabel}
onAccept={onAcceptAction}
withCancelButton
cancelButtonLabel={t("Common:CancelButton")}
onCancel={onCloseAction}
emptyScreenImage={
theme.isBase ? EmptyScreenAltSvgUrl : EmptyScreenAltSvgDarkUrl
}
emptyScreenHeader={t("SelectorEmptyScreenHeader")}
emptyScreenDescription=""
searchEmptyScreenImage={
theme.isBase
? EmptyScreenFilterAltSvgUrl
: EmptyScreenFilterAltDarkSvgUrl
}
searchEmptyScreenHeader={t("Common:NotFoundTitle")}
searchEmptyScreenDescription={t("EmptyFilterDescriptionText")}
withBreadCrumbs
breadCrumbs={breadCrumbs}
onSelectBreadCrumb={onClickBreadCrumb}
isLoading={showLoader}
isBreadCrumbsLoading={showBreadCrumbsLoader}
withSearch={
!isRoot && items ? items.length > 0 : !isRoot && isFirstLoad
}
rowLoader={
<Loaders.SelectorRowLoader
isMultiSelect={false}
isUser={isRoot}
isContainer={showLoader}
/>
}
searchLoader={<Loaders.SelectorSearchLoader />}
breadCrumbsLoader={<Loaders.SelectorBreadCrumbsLoader />}
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" : ""}
/>
{SelectorBody}
</Aside>
</>
);
return currentDeviceType === DeviceType.mobile ? (
<Portal visible={isPanelVisible} element={<div>{selectorComponent}</div>} />
) : (
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));

View File

@ -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");
};

View File

@ -27,6 +27,7 @@ const FilesSelectorInput = (props) => {
filterParam,
descriptionText,
className,
} = props;
const isFilesSelection = !!filterParam;
@ -78,7 +79,7 @@ const FilesSelectorInput = (props) => {
};
return (
<StyledBodyWrapper maxWidth={maxWidth}>
<StyledBodyWrapper maxWidth={maxWidth} className={className}>
<FileInput
onClick={onClick}
fromStorage

View File

@ -1,13 +1,13 @@
import React, { useState, useEffect } from "react";
import { inject, observer } from "mobx-react";
import { useTranslation } from "react-i18next";
import { useNavigate } from "react-router-dom";
import { ChangeUserTypeDialog } from "../dialogs";
import toastr from "@docspace/components/toast/toastr";
import Link from "@docspace/components/link";
import Text from "@docspace/components/text";
import { combineUrl } from "@docspace/common/utils";
import { useNavigate } from "react-router-dom";
const ChangeUserTypeEvent = ({
setVisible,
@ -26,6 +26,8 @@ const ChangeUserTypeEvent = ({
peopleDialogData;
const { t } = useTranslation(["ChangeUserTypeDialog", "Common", "Payments"]);
const navigate = useNavigate();
const onKeyUpHandler = (e) => {
if (e.keyCode === 27) onCloseAction();
if (e.keyCode === 13) onChangeUserType();

View File

@ -281,6 +281,7 @@ const CreateEvent = ({
return (
<Dialog
t={t}
withForm
visible={eventDialogVisible}
title={headerTitle}
startValue={startValue}

View File

@ -2,7 +2,6 @@ import React, { useState, useEffect, useCallback } from "react";
import { inject, observer } from "mobx-react";
import { useTranslation } from "react-i18next";
import { CreateRoomDialog } from "../dialogs";
import { isMobile } from "react-device-detect";
const CreateRoomEvent = ({
visible,

View File

@ -25,6 +25,7 @@ const Dialog = ({
extension,
keepNewFileName,
setKeepNewFileName,
withForm,
}) => {
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 (
<ModalDialog
withForm={withForm}
visible={visible}
displayType={"modal"}
scale={true}
@ -155,6 +158,7 @@ const Dialog = ({
key="GlobalSendBtn"
label={isCreateDialog ? t("Common:Create") : t("Common:SaveButton")}
size="normal"
type="submit"
scale
primary
isLoading={isDisabled}

View File

@ -4,7 +4,7 @@ import { inject, observer } from "mobx-react";
import styled, { css } from "styled-components";
import Base from "@docspace/components/themes/base";
import NoUserSelect from "@docspace/components/utils/commonStyles";
import RoomIcon from "./RoomIcon";
import RoomIcon from "@docspace/components/room-icon";
const StyledIcon = styled.img`
${NoUserSelect}

View File

@ -1,5 +1,5 @@
import React, { Component, createRef } from "react";
import { isTouchDevice } from "@docspace/components/utils/device";
import { isDesktop, isTouchDevice } from "@docspace/components/utils/device";
import Scrollbar from "@docspace/components/scrollbar";
import { LayoutContextProvider } from "./context";
import { getBannerAttribute } from "@docspace/components/utils/banner";
@ -53,7 +53,7 @@ class MobileLayout extends Component {
this.customScrollElm.scrollTop > 0 ? this.customScrollElm.scrollTop : 0;
if (
isTablet &&
!isDesktop() &&
document.getElementsByClassName("backdrop-active").length > 0 &&
!this.props.isArticleVisibleOnUnpin
) {

View File

@ -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 (
<StyledContainer
className="Layout"
isTabletView={isTabletView}
isTabletView={isTabletUtils()}
contentHeight={contentHeight}
>
{isMobileOnly ? <MobileLayout {...props} /> : children}
{isMobileUtils() ? <MobileLayout {...props} /> : children}
</StyledContainer>
);
};
@ -196,5 +249,6 @@ export default inject(({ auth, bannerStore }) => {
return {
isTabletView: auth.settingsStore.isTabletView,
setIsTabletView: auth.settingsStore.setIsTabletView,
setWindowWidth: auth.settingsStore.setWindowWidth,
};
})(observer(Layout));

View File

@ -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 <StyledMain className="main" {...props} />;
});
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 <StyledMain className="main" mainHeight={mainHeight} {...props} />;
};
Main.displayName = "Main";
export default Main;
export default inject(({ auth }) => {
const { isBannerVisible } = auth.bannerStore;
const { mainBarVisible } = auth.settingsStore;
return {
mainBarVisible,
isBannerVisible,
};
})(observer(Main));

View File

@ -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;

View File

@ -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";

View File

@ -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)));

View File

@ -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 }) =>

View File

@ -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,

View File

@ -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;

View File

@ -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
);

View File

@ -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}
>
<DropDownItem {...action} />
<StyledDropDownItem {...action} noHover={true} />
</Link>
))
)}

View File

@ -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 (
<StyledDropDown
className={className}
directionX="right"
open={open}
clickOutsideAction={clickOutsideAction}
forwardedRef={forwardedRef}
isDefaultMode={false}
withBlur={isMobileOnly}
withBlur={true}
isBannerVisible={isBannerVisible}
withPortal={isMobileOnly}
withPortal={true}
>
<StyledProfileMenu>
<MenuContainer>
@ -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 = <StyledWrapper>{element}</StyledWrapper>;
const wrapper = <StyledWrapper>{element}</StyledWrapper>;
return <>{<Portal element={wrapper} appendTo={root} visible={open} />}</>;
}
return <>{element}</>;
return <>{<Portal element={wrapper} appendTo={root} visible={open} />}</>;
}
}

View File

@ -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();

View File

@ -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";

View File

@ -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;

View File

@ -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 ? (
<Wrapper>
<SmartBanner
title={t("SmartBanner:AppName")}
author="Ascensio System SIA"
button={t("Common:View")}
force={force}
onClose={hideBanner}
onInstall={hideBanner}
onClose={() => setIsBannerVisible(false)}
onInstall={() => setIsBannerVisible(false)}
storeText={storeText}
price={priceText}
appMeta={appMeta}

View File

@ -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() && (
<div className="backup-codes-print-link-wrapper">
<Link
type="action"

View File

@ -16,6 +16,10 @@ const StyledModalDialog = styled(ModalDialog)`
.message {
margin-bottom: 16px;
.bold {
font-weight: 600;
}
}
.select-action {
@ -162,7 +166,6 @@ const ConflictResolveDialog = (props) => {
<div>
<Text className="radio-option-title">{t("OverwriteTitle")}</Text>
<Text className="radio-option-description">
{" "}
{t("OverwriteDescription")}
</Text>
</div>
@ -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 (
<StyledModalDialog
isLoading={!tReady}
@ -213,20 +210,22 @@ const ConflictResolveDialog = (props) => {
<ModalDialog.Header>{t("ConflictResolveTitle")}</ModalDialog.Header>
<ModalDialog.Body>
<Text className="message">
{singleFile ? (
{items.length === 1 ? (
<Trans
t={t}
i18nKey="ConflictResolveDescription"
ns="ConflictResolveDialog"
values={obj}
></Trans>
i18nKey="ConflictResolveDescription"
values={{ file: items[0].title, folder: folderTitle }}
components={{ 1: <span className="bold" /> }}
/>
) : (
<Trans
t={t}
i18nKey="ConflictResolveDescriptionFiles"
ns="ConflictResolveDialog"
values={{ filesCount, folder: folderTitle }}
></Trans>
i18nKey="ConflictResolveDescriptionFiles"
values={{ filesCount: items.length, folder: folderTitle }}
components={{ 1: <span className="bold" /> }}
/>
)}
</Text>
<Text className="select-action">

View File

@ -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 (
<Styled.ChangeRoomOwner>
<Text className="change-owner-label" fontWeight={600} fontSize="13px">
{t("Files:RoomOwner")}
</Text>
<div className="change-owner-display">
<Avatar
className={"change-owner-display-avatar"}
size="base"
role={""}
isDefaultSource={roomOwner.hasAvatar}
source={roomOwner.avatarSmall}
userName={roomOwner.displayName}
/>
<div className="change-owner-display-name">
<Text fontWeight={600} fontSize="13px">
{roomOwner.displayName}
</Text>
{roomOwner?.id === currentUserId && (
<Text className="me-label">({t("Common:MeLabel")})</Text>
)}
</div>
</div>
<Link
className="change-owner-link"
isHovered
type="action"
fontWeight={600}
fontSize="13px"
color={currentColorScheme.main.accent}
onClick={onOwnerChange}
>
{t("Common:ChangeButton")}
</Link>
</Styled.ChangeRoomOwner>
);
};
export default inject(({ auth, dialogsStore }) => ({
currentUserId: auth.userStore.user.id,
currentColorScheme: auth.settingsStore.currentColorScheme,
}))(withTranslation(["Common"])(ChangeRoomOwner));

View File

@ -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 };

View File

@ -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() ? (
<DropdownMobile
t={t}
open={isOpen}

View File

@ -19,8 +19,7 @@ import { getRoomTypeDefaultTagTranslation } from "../data";
import ImageEditor from "@docspace/components/ImageEditor";
import PreviewTile from "@docspace/components/ImageEditor/PreviewTile";
import Text from "@docspace/components/text";
import Link from "@docspace/components/link";
import NoUserSelect from "@docspace/components/utils/commonStyles";
import ChangeRoomOwner from "./ChangeRoomOwner";
const StyledSetRoomParams = styled.div`
display: flex;
@ -38,31 +37,6 @@ const StyledSetRoomParams = styled.div`
justify-content: start;
gap: 16px;
}
.room-owner-block {
display: flex;
align-items: center;
gap: 8px;
margin: 8px 0;
}
.owner-display-name-block {
display: flex;
align-items: center;
gap: 4px;
}
.change-owner-link {
color: ${(props) => props.currentColorScheme.main.accent};
}
.me-label {
color: ${(props) => props.theme.text.disableColor};
}
`;
const StyledIcon = styled.img`
${NoUserSelect}
`;
const SetRoomParams = ({
@ -79,9 +53,7 @@ const SetRoomParams = ({
setIsValidTitle,
onKeyUp,
enableThirdParty,
currentColorScheme,
setChangeRoomOwnerIsVisible,
userId,
isAdmin,
}) => {
const [previewIcon, setPreviewIcon] = React.useState(null);
@ -105,11 +77,8 @@ const SetRoomParams = ({
);
};
const isMe = userId === roomParams?.roomOwner?.id;
const canOwnerChange = isAdmin || isMe;
return (
<StyledSetRoomParams currentColorScheme={currentColorScheme}>
<StyledSetRoomParams>
{isEdit ? (
<RoomType t={t} roomType={roomParams.type} type="displayItem" />
) : (
@ -149,6 +118,7 @@ const SetRoomParams = ({
setIsScrollLocked={setIsScrollLocked}
isDisabled={isDisabled}
/>
{/* //TODO: Uncomment when private rooms are done
{!isEdit && (
<IsPrivateParam
@ -158,38 +128,11 @@ const SetRoomParams = ({
/>
)} */}
{canOwnerChange && roomParams.roomOwner && (
<div>
<Text fontWeight={600} fontSize="13px">
{t("Files:RoomOwner")}
</Text>
<div className="room-owner-block">
<StyledIcon
className="react-svg-icon"
src={roomParams.roomOwner.avatarSmall}
/>
<div className="owner-display-name-block">
<Text fontWeight={600} fontSize="13px">
{roomParams.roomOwner.displayName}
</Text>
{isMe && (
<Text className="me-label">({t("Common:MeLabel")})</Text>
)}
</div>
</div>
<Link
isHovered
type="action"
fontWeight={600}
fontSize="13px"
className="change-owner-link"
onClick={onOwnerChange}
>
{t("Common:ChangeButton")}
</Link>
</div>
{(isAdmin || isMe) && roomParams.roomOwner && (
<ChangeRoomOwner
roomOwner={roomParams.roomOwner}
onOwnerChange={onOwnerChange}
/>
)}
{!isEdit && enableThirdParty && (
@ -203,6 +146,7 @@ const SetRoomParams = ({
isDisabled={isDisabled}
/>
)}
<div>
<Text fontWeight={600} className="icon-editor_text">
{t("Icon")}
@ -234,13 +178,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,
};
})(

View File

@ -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 {

View File

@ -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);

View File

@ -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}

View File

@ -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")}</>
</>
);
}

View File

@ -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;

View File

@ -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();

View File

@ -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}
/>
<Button
key="CancelButton"
label={t("CancelButton")}
size="normal"
scale={isMobileOnly}
scale={currentDeviceType === DeviceType.mobile}
onClick={onCloseAction}
/>
</ModalDialog.Footer>
@ -154,7 +162,7 @@ const ReportDialog = (props) => {
};
export default inject(({ auth }) => {
const { user } = auth.userStore;
const { user, currentDeviceType } = auth.userStore;
const { firebaseHelper } = auth.settingsStore;
return {

View File

@ -1,20 +1,19 @@
import React, { useState } from "react";
import PropTypes from "prop-types";
import styled from "styled-components";
import { I18nextProvider, useTranslation } from "react-i18next";
import { useTranslation } from "react-i18next";
import Button from "@docspace/components/button";
import TextInput from "@docspace/components/text-input";
import Text from "@docspace/components/text";
import ModalDialog from "@docspace/components/modal-dialog";
import Textarea from "@docspace/components/textarea";
import FieldContainer from "@docspace/components/field-container";
import { smallTablet } from "@docspace/components/utils/device";
import toastr from "@docspace/components/toast/toastr";
import { inject, observer } from "mobx-react";
import { tablet } from "@docspace/components/utils/device";
const ModalDialogContainer = styled(ModalDialog)`
.modal-dialog-aside-footer {
@media (max-width: 1024px) {
@media ${tablet} {
width: 90%;
}
}

View File

@ -1,7 +1,7 @@
import React from "react";
import styled, { css } from "styled-components";
import { getCookie } from "@docspace/common/utils";
import { getCookie } from "@docspace/components/utils/cookie";
import { LANGUAGE } from "@docspace/common/constants";
import Text from "@docspace/components/text";

View File

@ -124,8 +124,9 @@ const SubmitToFormGallery = ({
approval in our
<Link
color={currentColorScheme.main.accent}
href="#"
href="https://www.onlyoffice.com/blog/2022/07/when-design-matters-how-to-create-beautiful-forms-with-oforms"
type={"page"}
target={"_blank"}
isBold
isHovered
>

View File

@ -8,6 +8,8 @@ import { withTranslation } from "react-i18next";
import Filter from "@docspace/common/api/people/filter";
import { EmployeeType, ShareAccessRights } from "@docspace/common/constants";
import toastr from "@docspace/components/toast/toastr";
import { DeviceType } from "@docspace/common/constants";
import Portal from "@docspace/components/portal";
const StyledChangeRoomOwner = styled.div`
display: contents;
@ -51,6 +53,7 @@ const ChangeRoomOwner = (props) => {
removeFiles,
folders,
setFolders,
currentDeviceType,
} = props;
const [isLoading, setIsLoading] = useState(false);
@ -124,7 +127,7 @@ const ChangeRoomOwner = (props) => {
const backClickProp = showBackButton ? { onBackClick } : {};
return (
const asideComponent = (
<StyledChangeRoomOwner showBackButton={showBackButton}>
<Backdrop
onClick={onClose}
@ -133,6 +136,7 @@ const ChangeRoomOwner = (props) => {
isAside={true}
/>
<Aside
currentDeviceType={currentDeviceType}
className="header_aside-panel"
visible={visible}
onClose={onClose}
@ -154,6 +158,12 @@ const ChangeRoomOwner = (props) => {
</Aside>
</StyledChangeRoomOwner>
);
return currentDeviceType === DeviceType.mobile ? (
<Portal visible={visible} element={asideComponent} />
) : (
asideComponent
);
};
export default inject(
@ -163,6 +173,8 @@ export default inject(
setChangeRoomOwnerIsVisible,
changeRoomOwnerData,
} = dialogsStore;
const { settingsStore } = auth;
const { user } = auth.userStore;
const {
setRoomOwner,
@ -181,6 +193,8 @@ export default inject(
? bufferSelection.id
: selectedFolderStore.id;
const { currentDeviceType } = settingsStore;
return {
visible: changeRoomOwnerIsVisible,
setIsVisible: setChangeRoomOwnerIsVisible,
@ -195,6 +209,7 @@ export default inject(
removeFiles,
folders,
setFolders,
currentDeviceType,
};
}
)(observer(withTranslation(["Files"])(ChangeRoomOwner)));

View File

@ -146,7 +146,7 @@ const StyledEditLinkPanel = styled.div`
const StyledScrollbar = styled(Scrollbar)`
position: relative;
padding: 16px 0;
height: calc(100vh - 87px) !important;
height: calc(100% - 150px) !important;
`;
const StyledButtons = styled(Box)`

View File

@ -21,7 +21,8 @@ import LinkBlock from "./LinkBlock";
import ToggleBlock from "./ToggleBlock";
import PasswordAccessBlock from "./PasswordAccessBlock";
import LimitTimeBlock from "./LimitTimeBlock";
import { isMobileOnly } from "react-device-detect";
import { DeviceType } from "@docspace/common/constants";
const EditLinkPanel = (props) => {
const {
@ -41,6 +42,7 @@ const EditLinkPanel = (props) => {
link,
date,
language,
currentDeviceType,
} = props;
const [isLoading, setIsLoading] = useState(false);
@ -174,6 +176,7 @@ const EditLinkPanel = (props) => {
visible={visible}
onClose={onClosePanel}
zIndex={310}
withoutBodyScroll
>
<div className="edit-link_header">
<Heading className="edit-link_heading">
@ -257,7 +260,9 @@ const EditLinkPanel = (props) => {
);
};
return isMobileOnly ? renderPortal() : editLinkPanelComponent;
return currentDeviceType === DeviceType.mobile
? renderPortal()
: editLinkPanelComponent;
};
export default inject(({ auth, dialogsStore, publicRoomStore }) => {
@ -295,6 +300,7 @@ export default inject(({ auth, dialogsStore, publicRoomStore }) => {
setUnsavedChangesDialog,
link,
language: auth.language,
currentDeviceType: auth.settingsStore.currentDeviceType,
};
})(
withTranslation(["SharingPanel", "Common", "Files"])(observer(EditLinkPanel))

View File

@ -1,4 +1,4 @@
import styled from "styled-components";
import styled, { css } from "styled-components";
import Scrollbar from "@docspace/components/scrollbar";
import { Base } from "@docspace/components/themes";

View File

@ -1,12 +1,12 @@
import styled, { css } from "styled-components";
import Scrollbar from "@docspace/components/scrollbar";
import { Base } from "@docspace/components/themes";
import { tablet } from "@docspace/components/utils/device";
import { tablet, mobile } from "@docspace/components/utils/device";
const StyledHotkeysPanel = styled.div`
.hotkeys-panel {
.scroll-body {
${props =>
${(props) =>
props.theme.interfaceDirection === "rtl"
? css`
padding-left: 0 !important;
@ -19,7 +19,7 @@ const StyledHotkeysPanel = styled.div`
.hotkeys_header {
padding: 0 16px;
border-bottom: ${props => props.theme.filesPanels.sharing.borderBottom};
border-bottom: ${(props) => props.theme.filesPanels.sharing.borderBottom};
.hotkeys_heading {
font-weight: 700;
@ -30,7 +30,7 @@ const StyledHotkeysPanel = styled.div`
.hotkeys_sub-header {
font-weight: 700;
font-size: 16px;
${props =>
${(props) =>
props.theme.interfaceDirection === "rtl"
? css`
padding-right: 16px;
@ -61,7 +61,11 @@ const StyledHotkeysPanel = styled.div`
max-width: 320px;
width: 100%;
@media (max-width: 550px) {
text-overflow: ellipsis;
white-space: normal;
word-break: break-word;
@media ${mobile} {
max-width: 140px;
word-wrap: break-word;
white-space: normal;
@ -69,7 +73,7 @@ const StyledHotkeysPanel = styled.div`
}
.hotkeys-key {
${props =>
${(props) =>
props.theme.interfaceDirection === "rtl"
? css`
margin: 0 0 0 auto;
@ -78,8 +82,8 @@ const StyledHotkeysPanel = styled.div`
margin: 0 auto 0 0;
`}
@media (max-width: 550px) {
${props =>
@media ${mobile} {
${(props) =>
props.theme.interfaceDirection === "rtl"
? css`
margin: 0 auto 0 0;

View File

@ -10,7 +10,7 @@ import HelpButton from "@docspace/components/help-button";
import Link from "@docspace/components/link";
import ToggleButton from "@docspace/components/toggle-button";
import { isMobileOnly, isTablet } from "react-device-detect";
import { hugeMobile } from "@docspace/components/utils/device";
import { mobile } from "@docspace/components/utils/device";
import CheckIcon from "PUBLIC_DIR/images/check.edit.react.svg";
import CrossIcon from "PUBLIC_DIR/images/cross.edit.react.svg";
import CrossIconMobile from "PUBLIC_DIR/images/cross.react.svg";
@ -28,7 +28,7 @@ const fillAvailableWidth = css`
`;
const StyledInvitePanel = styled.div`
@media ${hugeMobile} {
@media ${mobile} {
user-select: none;
height: auto;
width: auto;
@ -401,7 +401,7 @@ const StyledControlContainer = styled.div`
justify-content: center;
z-index: 450;
@media (max-width: 428px) {
@media ${mobile} {
display: flex;
top: -27px;

View File

@ -1,14 +1,13 @@
import React, { useEffect, useState, useMemo, useRef } from "react";
import { observer, inject } from "mobx-react";
import { withTranslation } from "react-i18next";
import { isMobileOnly } from "react-device-detect";
import Backdrop from "@docspace/components/backdrop";
import Aside from "@docspace/components/aside";
import Button from "@docspace/components/button";
import toastr from "@docspace/components/toast/toastr";
import Portal from "@docspace/components/portal";
import { size } from "@docspace/components/utils/device";
import { isDesktop, isMobile, size } from "@docspace/components/utils/device";
import {
StyledBlock,
@ -26,6 +25,7 @@ import Scrollbar from "@docspace/components/scrollbar";
import { LinkType } from "../../../helpers/constants";
import InfoBar from "./sub-components/InfoBar";
import { DeviceType } from "@docspace/common/constants";
const InvitePanel = ({
folders,
@ -51,6 +51,7 @@ const InvitePanel = ({
roomsView,
getUsersList,
filter,
currentDeviceType,
}) => {
const [selectedRoom, setSelectedRoom] = useState(null);
const [hasErrors, setHasErrors] = useState(false);
@ -61,7 +62,7 @@ const InvitePanel = ({
const [activeLink, setActiveLink] = useState({});
const [infoBarIsVisible, setInfoBarIsVisible] = useState(true);
const [addUsersPanelVisible, setAddUsersPanelVisible] = useState(false);
const [isMobileView, setIsMobileView] = useState(isMobileOnly);
const [isMobileView, setIsMobileView] = useState(isMobile());
const onCloseBar = () => setInfoBarIsVisible(false);
@ -86,7 +87,7 @@ const InvitePanel = ({
const getInfo = () => {
getRoomSecurityInfo(roomId).then((links) => {
const link = links[0];
const link = links && links[0];
if (link) {
const { shareLink, id, title, expirationDate } = link.sharedTo;
@ -169,8 +170,8 @@ const InvitePanel = ({
};
const onCheckHeight = () => {
setScrollAllPanelContent(window.innerHeight < 1024);
setIsMobileView(window.innerWidth <= size.hugeMobile);
setScrollAllPanelContent(!isDesktop());
setIsMobileView(isMobile());
};
const onClose = () => {
@ -357,7 +358,7 @@ const InvitePanel = ({
onClick={onClose}
visible={visible}
isAside={true}
zIndex={isMobileOnly ? 10 : 210}
zIndex={currentDeviceType === DeviceType.mobile ? 10 : 210}
/>
<Aside
className="invite_panel"
@ -385,11 +386,13 @@ const InvitePanel = ({
);
};
return isMobileOnly ? renderPortalInvitePanel() : invitePanelComponent;
return currentDeviceType === DeviceType.mobile
? renderPortalInvitePanel()
: invitePanelComponent;
};
export default inject(({ auth, peopleStore, filesStore, dialogsStore }) => {
const { theme } = auth.settingsStore;
const { theme, currentDeviceType } = auth.settingsStore;
const { getUsersByQuery, inviteUsers, getUsersList } = peopleStore.usersStore;
const { filter } = peopleStore.filterStore;
@ -444,6 +447,7 @@ export default inject(({ auth, peopleStore, filesStore, dialogsStore }) => {
roomsView,
getUsersList,
filter,
currentDeviceType,
};
})(
withTranslation([

View File

@ -3,10 +3,9 @@ import { inject, observer } from "mobx-react";
import AccessRightSelect from "@docspace/components/access-right-select";
import { getAccessOptions } from "../utils";
import { isMobileOnly } from "react-device-detect";
import { StyledAccessSelector } from "../StyledInvitePanel";
import { isSmallTablet } from "@docspace/components/utils/device";
import { isMobile } from "@docspace/components/utils/device";
const AccessSelector = ({
t,
@ -46,20 +45,20 @@ const AccessSelector = ({
}, []);
const checkWidth = () => {
if (!isMobileOnly) return;
if (!isMobile()) return;
if (!isSmallTablet()) {
if (!isMobile()) {
setHorizontalOrientation(true);
} else {
setHorizontalOrientation(false);
}
};
const isMobileHorizontalOrientation = isMobileOnly && horizontalOrientation;
const isMobileHorizontalOrientation = isMobile() && horizontalOrientation;
return (
<StyledAccessSelector className="invite-panel_access-selector">
{!(isMobileOnly && !isMobileHorizontalOrientation) && (
{!(isMobile() && !isMobileHorizontalOrientation) && (
<AccessRightSelect
className={className}
selectedOption={selectedOption}
@ -77,7 +76,7 @@ const AccessSelector = ({
/>
)}
{isMobileOnly && !isMobileHorizontalOrientation && (
{isMobile() && !isMobileHorizontalOrientation && (
<AccessRightSelect
className={className}
selectedOption={selectedOption}

Some files were not shown because too many files have changed in this diff Show More