Merge branch 'develop' into feature/VDR-room

# Conflicts:
#	packages/client/src/components/dialogs/CreateEditRoomDialog/sub-components/SetRoomParams.js
This commit is contained in:
Nikita Gopienko 2023-10-13 18:33:32 +03:00
commit 0eba7d8c22
499 changed files with 4029 additions and 3810 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

@ -141,6 +141,8 @@
"RoomPinned": "Room pinned",
"RoomRemoved": "Room removed",
"RoomsRemoved": "Rooms removed",
"RoomsPinned": "Rooms pinned: {{count}}",
"RoomsUnpinned": "Rooms unpinned: {{count}}",
"RoomUnpinned": "Room unpinned",
"SearchByContent": "Search by file contents",
"SelectorEmptyScreenHeader": "No files and folders here yet",

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

@ -186,7 +186,6 @@
"RestoreBackupDescription": "Use this option to restore your space from the previously saved backup file.",
"RestoreBackupResetInfoWarningText": "All current passwords will be reset. DocSpace users will get an email with the access restoration link.",
"RestoreBackupWarningText": "DocSpace will become unavailable during the restore process. After the restore is complete all the changes made after the date of the selected restore point will be lost.",
"RestoreDefaultButton": "Restore to default",
"RoomsModule": "Backup room",
"RoomsModuleDescription": "You may create a new room specifically for the backup, choose one of the existing rooms, or save the copy in their {{roomName}} room.",
"SelectFileInGZFormat": "Select the file in .GZ format",

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

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

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

@ -21,8 +21,7 @@ import PreviewTile from "@docspace/components/ImageEditor/PreviewTile";
import VirtualDataRoomBlock from "./VirtualDataRoomBlock";
import { RoomsType } from "@docspace/common/constants";
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;
@ -40,31 +39,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 = ({
@ -81,9 +55,7 @@ const SetRoomParams = ({
setIsValidTitle,
onKeyUp,
enableThirdParty,
currentColorScheme,
setChangeRoomOwnerIsVisible,
userId,
isAdmin,
}) => {
const [previewIcon, setPreviewIcon] = React.useState(null);
@ -109,11 +81,8 @@ const SetRoomParams = ({
);
};
const isMe = userId === roomParams?.roomOwner?.id;
const canOwnerChange = isAdmin || isMe;
return (
<StyledSetRoomParams currentColorScheme={currentColorScheme}>
<StyledSetRoomParams>
{isEdit ? (
<RoomType t={t} roomType={roomParams.type} type="displayItem" />
) : (
@ -153,6 +122,7 @@ const SetRoomParams = ({
setIsScrollLocked={setIsScrollLocked}
isDisabled={isDisabled}
/>
{/* //TODO: Uncomment when private rooms are done
{!isEdit && (
<IsPrivateParam
@ -162,6 +132,13 @@ const SetRoomParams = ({
/>
)} */}
{(isAdmin || isMe) && roomParams.roomOwner && (
<ChangeRoomOwner
roomOwner={roomParams.roomOwner}
onOwnerChange={onOwnerChange}
/>
)}
{isVDRRoom && <VirtualDataRoomBlock t={t} />}
{canOwnerChange && roomParams.roomOwner && (
@ -209,6 +186,7 @@ const SetRoomParams = ({
isDisabled={isDisabled}
/>
)}
<div>
<Text fontWeight={600} className="icon-editor_text">
{t("Icon")}
@ -240,13 +218,10 @@ const SetRoomParams = ({
};
export default inject(({ auth, dialogsStore }) => {
const { currentColorScheme } = auth.settingsStore;
const { user } = auth.userStore;
const { setChangeRoomOwnerIsVisible } = dialogsStore;
return {
currentColorScheme,
setChangeRoomOwnerIsVisible,
userId: user.id,
isAdmin: user.isAdmin || user.isOwner,
};
})(

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