Merge branch 'develop' into feature/oauth2-client

This commit is contained in:
Timofey Boyko 2023-10-27 11:34:56 +03:00
commit b5c55da859
603 changed files with 8038 additions and 6735 deletions

View File

@ -1,6 +1,6 @@
{
"name": "docspace",
"version": "1.1.3",
"version": "2.0.0",
"private": true,
"workspaces": {
"packages": [

View File

@ -1,6 +1,6 @@
{
"name": "@docspace/client",
"version": "1.1.3",
"version": "2.0.0",
"private": true,
"homepage": "",
"scripts": {

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

@ -1,6 +1,5 @@
{
"AddMembersDescription": "Sie können neue Teammitglieder manuell hinzufügen oder sie über einen Link einladen.",
"AddNewExternalLink": "Neuen externen Link hinzufügen",
"AddNewLink": "Neuen Link hinzufügen",
"All": "Alle",
"AllFiles": "Alle Dateien",
@ -31,7 +30,6 @@
"DaysRemaining": "Verbleibende Tage: {{daysRemaining}}",
"DeleteLink": "Link löschen",
"DeleteLinkNote": "Der Link wird dauerhaft gelöscht. Sie können diesen Vorgang nicht rückgängig machen.",
"DisableDownload": "Download-Funktion deaktivieren",
"DisableLink": "Link deaktivieren",
"DisableNotifications": "Benachrichtigungen deaktivieren",
"Document": "Dokument",
@ -72,12 +70,10 @@
"LinkAddedSuccessfully": "Link erfolgreich hinzugefügt",
"LinkDeletedSuccessfully": "Link erfolgreich gelöscht",
"LinkDisabledSuccessfully": "Link erfolgreich deaktiviert",
"LinkEditedSuccessfully": "Link erfolgreich geändert",
"LinkEnabledSuccessfully": "Link erfolgreich aktiviert",
"LinkForPortalUsers": "Link für DocSpace-Benutzer",
"LinkForRoomMembers": "Link für Mitglieder im Raum",
"Links": "Links",
"LinkSuccessfullyCopied": "Link erfolgreich kopiert",
"LinkValidUntil": "Dieser Link ist gültig bis",
"MarkAsFavorite": "Als Favorit kennzeichnen",
"MarkAsRevision": "Als Revision markieren",
@ -107,7 +103,6 @@
"Pin": "Anstecken",
"PinToTop": "Oben anstecken",
"Presentation": "Präsentation",
"PreventDownloadFilesAndFolders": "Deaktivieren Sie Downloads von Dateien und Ordnern aus diesem Raum, um Ihre Daten zu schützen. ",
"PrivateRoomDescriptionEncrypted": "Verschlüsselte Bearbeitung und Zusammenarbeit in Echtzeit.",
"PrivateRoomDescriptionSafest": "Der sicherste Speicher für DOCX-, XLSX- und PPTX-Dateien.",
"PrivateRoomDescriptionSecure": "Sichere Freigabe für Teammitglieder.",

View File

@ -29,7 +29,6 @@
"HistoryEmptyScreenText": "Aktivitätsverlauf wird hier angezeigt",
"ItemsSelected": "Ausgewählte Elemente",
"LastModifiedBy": "Zuletzt geändert von",
"LinksToViewingIcon": "Links zur Ansicht",
"PendingInvitations": "Ausstehende Einladungen",
"Properties": "Eigenschaften",
"RoomsEmptyScreenTent": "Siehe Details von Räumen hier",

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

@ -1,7 +1,6 @@
{
"AddedToClipboard": "Items added to clipboard",
"AddMembersDescription": "You can add new team members manually or invite them via link.",
"AddNewExternalLink": "Add new external link",
"AddNewLink": "Add new link",
"All": "All",
"AllFiles": "All files",
@ -29,14 +28,18 @@
"CopyItem": "<strong>{{title}}</strong> copied",
"CopyItems": "<strong>{{qty}}</strong> elements copied",
"CopyLinkPassword": "Copy link password",
"CopyLink": "Copy link",
"CopyGeneralLink": "Copy general link",
"CopyPassword": "Copy password",
"CreateNewLink": "Create new link",
"CreateAndCopy": "Create and copy",
"CreateRoom": "Create room",
"CustomRooms": "Custom",
"DaysRemaining": "Days remaining: {{daysRemaining}}",
"DeleteLink": "Delete link",
"DeleteLinkNote": "The link will be deleted permanently. You will not be able to undo this action.",
"DisableDownload": "Disable download feature",
"DeleteGeneralLink": "The previous link will become unavailable. A new general link will be created.",
"DisableDownload": "Restrict file content copy, file download and printing",
"DisableLink": "Disable link",
"DisableNotifications": "Disable notifications",
"Document": "Document",
@ -77,16 +80,19 @@
"LeaveTheRoom": "Leave the room",
"LeftAndAppointNewOwner": "You have left the room and appointed a new owner",
"LimitByTimePeriod": "Limit by time period",
"EditGeneralLink": "Edit general link",
"EditAdditionalLink": "Edit additional link",
"LinkAddedSuccessfully": "Link added successfully",
"LinkCreatedSuccessfully": "Link successfully created",
"LinkDeletedSuccessfully": "Link deleted successfully",
"GeneralLinkDeletedSuccessfully": "New general link created successfully",
"LinkDisabledSuccessfully": "Link disabled successfully",
"LinkEditedSuccessfully": "Link edited successfully",
"LinkEditedSuccessfully": "Link successfully edited and copied",
"LinkEnabledSuccessfully": "Link enabled successfully",
"LinkForPortalUsers": "Link for DocSpace users",
"LinkForRoomMembers": "Link for room members",
"Links": "Links",
"LinkSuccessfullyCopied": "Link successfully copied",
"LinkSuccessfullyCopied": "Link successfully copied to clipboard",
"LinkSuccessfullyCreatedAndCopied": "Link successfully created and copied to clipboard",
"LinkValidUntil": "This link will be valid until",
"MarkAsFavorite": "Mark as favorite",
"MarkAsRevision": "Mark as revision",
@ -116,7 +122,7 @@
"Pin": "Pin",
"PinToTop": "Pin to top",
"Presentation": "Presentation",
"PreventDownloadFilesAndFolders": "Disable downloads of files and folders from this room to secure your data.",
"PreventDownloadFilesAndFolders": "Enable this setting to disable downloads of files and folders from this room shared via a link",
"PrivateRoomDescriptionEncrypted": "Encrypted editing and real-time collaboration.",
"PrivateRoomDescriptionSafest": "The safest storage for docx, xlsx and pptx.",
"PrivateRoomDescriptionSecure": "Secure sharing with trusted teammates.",
@ -140,6 +146,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",
@ -168,5 +176,7 @@
"WantToRestoreTheRoom": "All external links in this room will become active, and its contents will be available to everyone with the link. Do you want to restore the room?",
"WantToRestoreTheRooms": "All external links in restored rooms will become active, and their contents will be available to everyone with the room links. Do you want to restore the rooms?",
"WithSubfolders": "With subfolders",
"YouLeftTheRoom": "You have left the room"
"YouLeftTheRoom": "You have left the room",
"GeneralLink": "General link",
"AdditionalLinks": "Additional links"
}

View File

@ -32,7 +32,6 @@
"InfoBanner": "The list of invited users includes the owner and/or admins of this DocSpace with full access to all rooms. The owner and/or administrator cannot be assigned other access rights. Once added to the room, they will be notified of all changes.",
"ItemsSelected": "Items selected",
"LastModifiedBy": "Last modified by",
"LinksToViewingIcon": "Links to Viewing",
"PendingInvitations": "Pending invitations",
"Properties": "Properties",
"RoomsEmptyScreenTent": "See rooms details here",

View File

@ -5,10 +5,12 @@
"EmailErrorMessage": "Email address is not valid. You can edit the email by clicking on it.",
"InviteAccountSearchPlaceholder": "Invite people by email",
"Invited": "Invited",
"InvitationLanguage": "Invitation language",
"InviteRoomSearchPlaceholder": "Invite people by name or email",
"InviteViaLink": "Invite via link",
"InviteViaLinkDescriptionAccounts": "Create a universal link for self-authorization in DocSpace",
"InviteViaLinkDescriptionRoom": "Create a universal link for self-authorization in the room",
"LinkCopySuccess": "Link has been copied",
"ResetChange": "Reset change",
"SendInvitation": "Send invitation"
}
}

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

@ -5,6 +5,8 @@
"ConnectSocialNetworks": "Connect your social networks",
"DarkTheme": "Dark theme",
"DescriptionForSecurity": "For more security, you need to change your password.",
"DesktopTheme": "Sync with desktop Editor settings",
"DesktopThemeDescription": "Automatically switch between light and dark themes when your desktop editor.",
"EditPhoto": "Edit photo",
"EmailNotVerified": "Email is not verified",
"FileManagement": "File management",

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",
@ -242,7 +241,6 @@
"TwoFactorAuthEnableDescription": "Enable two-factor authentication for a more secure DocSpace access for users.",
"TwoFactorAuthHelper": "Note: SMS messages can be sent if you have a positive balance only. You can always check your current balance in your SMS provider account. Do not forget to replenish your balance in good time.",
"TwoFactorAuthMobileDescription": "Two-factor authentication is a more secure way for the users to enter the portal. After the credentials are entered, the user will have to enter the code from the SMS received to the mobile phone with the number which was specified at the first portal login or the code from an authentication application.",
"TwoFactorAuthNote": "<strong>Note:</strong> make sure to always have positive balance when SMS message option is chosen.",
"TwoFactorAuthSave": "Click the <strong>Save</strong> button below to apply.",
"UnsavedChangesBody": "If you close the link settings menu right now, your changes will not be saved.",
"UseAsLogoButton": "Use as logo",

View File

@ -1,6 +1,5 @@
{
"AddMembersDescription": "Puede añadir nuevos miembros del equipo manualmente o invitarlos a través de un enlace.",
"AddNewExternalLink": "Añadir nuevo enlace externo",
"AddNewLink": "Añadir nuevo enlace",
"All": "Todos",
"AllFiles": "Todos los archivos",
@ -31,7 +30,6 @@
"DaysRemaining": "Días restantes: {{daysRemaining}}",
"DeleteLink": "Eliminar enlace",
"DeleteLinkNote": "El enlace se eliminará de forma permanente. Usted no podrá deshacer esta acción.",
"DisableDownload": "Desactivar la función de descarga",
"DisableLink": "Desactivar enlace",
"DisableNotifications": "Deshabilitar notificaciones",
"Document": "Documento",
@ -72,12 +70,10 @@
"LinkAddedSuccessfully": "El enlace se ha añadido correctamente",
"LinkDeletedSuccessfully": "El enlace se ha eliminado correctamente",
"LinkDisabledSuccessfully": "El enlace se ha desactivado correctamente",
"LinkEditedSuccessfully": "El enlace se ha editado correctamente",
"LinkEnabledSuccessfully": "El enlace se ha activado correctamente",
"LinkForPortalUsers": "Enlace para los usuarios de DocSpace",
"LinkForRoomMembers": "Enlace para los miembros de la sala",
"Links": "Enlaces",
"LinkSuccessfullyCopied": "El enlace se ha copiado correctamente",
"LinkValidUntil": "Este enlace será válido hasta",
"MarkAsFavorite": "Marcar como favorito",
"MarkAsRevision": "Marcar como revisión",
@ -107,7 +103,6 @@
"Pin": "Anclar",
"PinToTop": "Anclar al principio",
"Presentation": "Presentación",
"PreventDownloadFilesAndFolders": "Desactive las descargas de archivos y carpetas desde esta sala para proteger sus datos.",
"PrivateRoomDescriptionEncrypted": "Edición y colaboración cifradas en tiempo real.",
"PrivateRoomDescriptionSafest": "El almacenamiento más seguro para docx, xlsx y pptx.",
"PrivateRoomDescriptionSecure": "Intercambio seguro con compañeros de equipo de confianza.",

View File

@ -29,7 +29,6 @@
"HistoryEmptyScreenText": "El historial de actividad se mostrará aquí",
"ItemsSelected": "Elementos seleccionados",
"LastModifiedBy": "Ultima modificación por",
"LinksToViewingIcon": "Enlaces para visualización",
"PendingInvitations": "Invitaciones pendientes",
"Properties": "Propiedades",
"RoomsEmptyScreenTent": "Vea los detalles de las salas aquí",

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

@ -1,6 +1,5 @@
{
"AddMembersDescription": "Vous pouvez ajouter de nouveaux membres de léquipe manuellement ou les inviter via un lien.",
"AddNewExternalLink": "Ajouter un nouveau lien externe",
"AddNewLink": "Ajouter un nouveau lien",
"All": "Tout",
"AllFiles": "Tous les fichiers",
@ -31,7 +30,6 @@
"DaysRemaining": "Jours restants : {{daysRemaining}}",
"DeleteLink": "Supprimer le lien",
"DeleteLinkNote": "Le lien sera définitivement supprimé. Vous ne pourrez pas annuler cette action.",
"DisableDownload": "Désactiver la fonction de téléchargement",
"DisableLink": "Désactiver le lien",
"DisableNotifications": "Désactiver les notifications",
"Document": "Document",
@ -72,12 +70,10 @@
"LinkAddedSuccessfully": "Le lien a été ajouté avec succès",
"LinkDeletedSuccessfully": "Le lien a été supprimé avec succès",
"LinkDisabledSuccessfully": "Le lien a été désactivé avec succès",
"LinkEditedSuccessfully": "Le lien a été modifié avec succès",
"LinkEnabledSuccessfully": "Le lien a été activé avec succès",
"LinkForPortalUsers": "Lien pour les utilisateurs de DocSpace",
"LinkForRoomMembers": "Lien pour les membres de la salle",
"Links": "Liens",
"LinkSuccessfullyCopied": "Le lien a été copié avec succès",
"LinkValidUntil": "Ce lien est valable jusqu'à",
"MarkAsFavorite": "Marquer en tant que favori",
"MarkAsRevision": "Marquer comme révision",
@ -107,7 +103,6 @@
"Pin": "Épingler",
"PinToTop": "Épingler en haut de page",
"Presentation": "Présentation",
"PreventDownloadFilesAndFolders": "Désactivez les téléchargements de fichiers et de dossiers à partir de cette salle pour sécuriser vos données.",
"PrivateRoomDescriptionEncrypted": "Édition cryptée et collaboration en temps réel.",
"PrivateRoomDescriptionSafest": "Le stockage le plus sûr pour les docx, xlsx et pptx.",
"PrivateRoomDescriptionSecure": "Partage sécurisé avec des coéquipiers de confiance.",

View File

@ -29,7 +29,6 @@
"HistoryEmptyScreenText": "L'historique des activités sera affiché ici",
"ItemsSelected": "Éléments sélectionnés",
"LastModifiedBy": "Dernière modification par",
"LinksToViewingIcon": "Liens vers l'affichage",
"PendingInvitations": "Invitations en attente",
"Properties": "Propriétés",
"RoomsEmptyScreenTent": "Voir les détails des salles ici",

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

@ -1,6 +1,5 @@
{
"AddMembersDescription": "Դուք կարող եք ձեռքով ավելացնել թիմի նոր անդամներ կամ հրավիրել նրանց հղման միջոցով:",
"AddNewExternalLink": "Ավելացնել նոր արտաքին հղում",
"AddNewLink": "Ավելացնել նոր հղում",
"All": "Բոլոր",
"AllFiles": "Բոլոր ֆայլերը",
@ -31,7 +30,6 @@
"DaysRemaining": "Մնացած օր: {{daysRemaining}}",
"DeleteLink": "Ջնջել հղումը",
"DeleteLinkNote": "Հղումը ընդմիշտ կջնջվի: Դուք չեք կարողանա հետարկել այս գործողությունը:",
"DisableDownload": "Անջատել ներբեռնման հնարավորությունը",
"DisableLink": "Անջատել հղումը",
"DisableNotifications": "Անջատել ծանուցումները",
"Document": "Փաստաթուղթ",
@ -72,12 +70,10 @@
"LinkAddedSuccessfully": "Հղումը հաջողությամբ ավելացվեց",
"LinkDeletedSuccessfully": "Հղումը հաջողությամբ ջնջվեց",
"LinkDisabledSuccessfully": "Հղումը հաջողությամբ անջատվեց",
"LinkEditedSuccessfully": "Հղումը հաջողությամբ խմբագրվել է",
"LinkEnabledSuccessfully": "Հղումը հաջողությամբ միացված է",
"LinkForPortalUsers": "Հղում DocSpace-ի օգտագործողների համար",
"LinkForRoomMembers": "Հղում սենյակի անդամների համար",
"Links": "Հղումներ",
"LinkSuccessfullyCopied": "Հղումը հաջողությամբ պատճենվեց",
"LinkValidUntil": "Այս հղումը կգործի մինչև",
"MarkAsFavorite": "Նշել որպես ընտրյալ",
"MarkAsRevision": "Նշել որպես վերանայում",
@ -107,7 +103,6 @@
"Pin": "Ամրացնել",
"PinToTop": "Ամրացնել վերին մասում",
"Presentation": "Ներկայացում",
"PreventDownloadFilesAndFolders": "Անջատեք ֆայլերի և պանակների ներբեռնումն այս սենյակից՝ ձեր տվյալները պաշտպանելու համար:",
"PrivateRoomDescriptionEncrypted": "Գաղտնագրված խմբագրում և իրական ժամանակի համագործակցություն.",
"PrivateRoomDescriptionSafest": "Ամենաանվտանգ պահեստը` docx, xlsx and pptx-ի համար.",
"PrivateRoomDescriptionSecure": "Անվտանգ համօգտագործում վստահելի թիմակիցների հետ.",

View File

@ -29,7 +29,6 @@
"HistoryEmptyScreenText": "Գործողությունների պատմությունը կցուցադրվի այստեղ",
"ItemsSelected": "Ընտրված միավորները",
"LastModifiedBy": "Վերջին անգամ փոփոխվել է՝",
"LinksToViewingIcon": "Հղումներ դեպի դիտում",
"PendingInvitations": "Սպասվող հրավերներ",
"Properties": "Հատկություններ",
"RoomsEmptyScreenTent": "Սենյակների մանրամասները տես ",

View File

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

View File

@ -1,6 +1,5 @@
{
"AddMembersDescription": "Puoi aggiungere nuovi membri del team manualmente o invitarli tramite link.",
"AddNewExternalLink": "Aggiungi nuovo link esterno",
"AddNewLink": "Aggiungi nuovo link",
"All": "Tutti",
"AllFiles": "Tutti i file",
@ -31,7 +30,6 @@
"DaysRemaining": "Giorni rimanenti: {{daysRemaining}}",
"DeleteLink": "Elimina il link",
"DeleteLinkNote": "Il link verrà eliminato definitivamente. Non potrai annullare questa azione.",
"DisableDownload": "Disabilita la funzione di download",
"DisableLink": "Disabilita il link",
"DisableNotifications": "Disattiva notifiche",
"Document": "Documento",
@ -72,12 +70,10 @@
"LinkAddedSuccessfully": "Link aggiunto con successo",
"LinkDeletedSuccessfully": "Link eliminato con successo",
"LinkDisabledSuccessfully": "Link disabilitato con successo",
"LinkEditedSuccessfully": "Link modificato con successo",
"LinkEnabledSuccessfully": "Link abilitato con successo",
"LinkForPortalUsers": "Collegamento per gli utenti di DocSpace",
"LinkForRoomMembers": "Collegamento per i membri della stanza",
"Links": "Link",
"LinkSuccessfullyCopied": "Link copiato con successo",
"LinkValidUntil": "Questo link sarà valido fino al",
"MarkAsFavorite": "Segna come preferito",
"MarkAsRevision": "Contrassegna come revisione",
@ -107,7 +103,6 @@
"Pin": "Fissa",
"PinToTop": "Fissa in alto",
"Presentation": "Presentazione",
"PreventDownloadFilesAndFolders": "Disabilita i download di file e cartelle da questa stanza per proteggere i tuoi dati.",
"PrivateRoomDescriptionEncrypted": "Modifica collaborativa in tempo reale con crittografia.",
"PrivateRoomDescriptionSafest": "L'archiviazione più sicura per docx, xlsx e pptx.",
"PrivateRoomDescriptionSecure": "Condivisione sicura con gli utenti del gruppo fidato.",

View File

@ -29,7 +29,6 @@
"HistoryEmptyScreenText": "La cronologia delle attività verrà visualizzata qui",
"ItemsSelected": "Elementi selezionati",
"LastModifiedBy": "Ultima modifica di",
"LinksToViewingIcon": "Link alla visualizzazione",
"PendingInvitations": "Inviti in sospeso",
"Properties": "Proprietà",
"RoomsEmptyScreenTent": "Vedi i dettagli delle stanze qui",

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

@ -1,6 +1,5 @@
{
"AddMembersDescription": "Você pode adicionar novos membros da equipe manualmente ou convidá-los por meio do link.",
"AddNewExternalLink": "Adicionar novo link externo",
"AddNewLink": "Adicionar novo link",
"All": "Todos",
"AllFiles": "Todos os arquivos",
@ -31,7 +30,6 @@
"DaysRemaining": "Dias restantes: {{daysRemaining}}",
"DeleteLink": "Excluir link",
"DeleteLinkNote": "O link será excluído permanentemente. Você não poderá desfazer esta ação.",
"DisableDownload": "Desativar recurso de download",
"DisableLink": "Desativar link",
"DisableNotifications": "Desativar as notificações",
"Document": "Documento",
@ -72,12 +70,10 @@
"LinkAddedSuccessfully": "Link adicionado com sucesso",
"LinkDeletedSuccessfully": "Link excluído com sucesso",
"LinkDisabledSuccessfully": "Link desativado com sucesso",
"LinkEditedSuccessfully": "Link editado com sucesso",
"LinkEnabledSuccessfully": "Link ativado com sucesso",
"LinkForPortalUsers": "Link para usuários do DocSpace",
"LinkForRoomMembers": "Link para membros da sala",
"Links": "Links",
"LinkSuccessfullyCopied": "Link copiado com sucesso",
"LinkValidUntil": "Este link será válido até",
"MarkAsFavorite": "Marcar como favorito",
"MarkAsRevision": "Marcar como revisão",
@ -107,7 +103,6 @@
"Pin": "Fixar",
"PinToTop": "Fixar no topo",
"Presentation": "Apresentação",
"PreventDownloadFilesAndFolders": "Desative downloads de arquivos e pastas desta sala para proteger seus dados.",
"PrivateRoomDescriptionEncrypted": "Edição criptografada e colaboração em tempo real.",
"PrivateRoomDescriptionSafest": "O armazenamento mais seguro para docx, xlsx e pptx.",
"PrivateRoomDescriptionSecure": "Compartilhamento seguro com colegas de equipe de confiança.",

View File

@ -29,7 +29,6 @@
"HistoryEmptyScreenText": "O histórico de atividades será mostrado aqui",
"ItemsSelected": "Itens selecionados",
"LastModifiedBy": "Última Modificação Por",
"LinksToViewingIcon": "Links para visualização",
"PendingInvitations": "Convites pendentes",
"Properties": "Propriedades",
"RoomsEmptyScreenTent": "Veja os detalhes dos quartos aqui",

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

@ -1,6 +1,5 @@
{
"AddMembersDescription": "Вы можете добавить новых участников команды вручную или пригласить их по ссылке.",
"AddNewExternalLink": "Добавить новую внешнюю ссылку",
"AddNewLink": "Добавить новую ссылку",
"All": "Все",
"AllFiles": "Все файлы",
@ -31,7 +30,6 @@
"DaysRemaining": "Дней осталось: {{daysRemaining}}",
"DeleteLink": "Удалить ссылку",
"DeleteLinkNote": "Ссылка будет удалена окончательно. Вы не сможете отменить это действие.",
"DisableDownload": "Отключить функцию скачивания",
"DisableLink": "Отключить ссылку",
"DisableNotifications": "Выключить уведомления",
"Document": "Документ",
@ -72,12 +70,10 @@
"LinkAddedSuccessfully": "Ссылка успешно добавлена",
"LinkDeletedSuccessfully": "Ссылка успешно удалена",
"LinkDisabledSuccessfully": "Ссылка успешно отключена",
"LinkEditedSuccessfully": "Ссылка успешно отредактирована",
"LinkEnabledSuccessfully": "Ссылка успешно активирована",
"LinkForPortalUsers": "Ссылка для пользователей портала",
"LinkForRoomMembers": "Ссылка для участников комнаты",
"Links": "Ссылки",
"LinkSuccessfullyCopied": "Ссылка успешно скопирована",
"LinkValidUntil": "Эта ссылка действительна до",
"MarkAsFavorite": "Добавить в избранное",
"MarkAsRevision": "Отметить как ревизию",
@ -107,7 +103,6 @@
"Pin": "Закрепить",
"PinToTop": "Закрепить наверху",
"Presentation": "Презентация",
"PreventDownloadFilesAndFolders": "Заблокировать скачивание файлов и папок из этой комнаты для безопасности ваших данных.",
"PrivateRoomDescriptionEncrypted": "Зашифрованное редактирование и совместная работа в режиме реального времени.",
"PrivateRoomDescriptionSafest": "Самое безопасное хранилище для файлов docx, xlsx и pptx.",
"PrivateRoomDescriptionSecure": "Безопасное предоставление доступа доверенным участникам команды.",
@ -116,7 +111,7 @@
"PrivateRoomSupport": "Работа в Приватной комнате доступна через десктопное приложение {{organizationName}}. <3>Инструкции</3>",
"PublicRoom": "Публичная комната",
"RecentEmptyContainerDescription": "В этом разделе будут отображаться ваши последние просмотренные или отредактированные документы.",
"RecycleBinAction": "Пустая корзина",
"RecycleBinAction": "Очистить корзину",
"RemovedFromFavorites": "Удалено из избранного",
"RemoveFromFavorites": "Удалить из избранного",
"RemoveFromList": "Убрать из списка",

View File

@ -29,7 +29,6 @@
"HistoryEmptyScreenText": "Здесь будет отображаться история активности",
"ItemsSelected": "Выбрано элементов",
"LastModifiedBy": "Автор последнего корректива",
"LinksToViewingIcon": "Ссылки на просмотр",
"PendingInvitations": "Приглашения в ожидании",
"Properties": "Cвойства",
"RoomsEmptyScreenTent": "Здесь будут представлены подробности о комнатах",

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();
@ -137,12 +144,20 @@ const ClientContent = (props) => {
<GlobalEvents />
{!isFormGallery ? (
isFrame ? (
showMenu && <ClientArticle />
showMenu && (
<ClientArticle
withMainButton={withMainButton}
setIsHeaderLoading={setIsHeaderLoading}
setIsFilterLoading={setIsFilterLoading}
showArticleLoader={showArticleLoader}
/>
)
) : (
<ClientArticle
withMainButton={withMainButton}
setIsHeaderLoading={setIsHeaderLoading}
setIsFilterLoading={setIsFilterLoading}
showArticleLoader={showArticleLoader}
/>
)
) : (
@ -171,8 +186,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 +214,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

@ -5,6 +5,9 @@ import { combineUrl } from "@docspace/common/utils";
import Badges from "../components/Badges";
import config from "PACKAGE_FILE";
import copy from "copy-to-clipboard";
import toastr from "@docspace/components/toast/toastr";
import { isMobileOnly } from "react-device-detect";
export default function withBadges(WrappedComponent) {
class WithBadges extends React.Component {
@ -73,6 +76,17 @@ export default function withBadges(WrappedComponent) {
this.props.setConvertDialogVisible(true);
};
onCopyPrimaryLink = async () => {
if (isMobileOnly) return;
const { t, item, getPrimaryLink } = this.props;
const primaryLink = await getPrimaryLink(item.id);
if (primaryLink) {
copy(primaryLink.sharedTo.shareLink);
toastr.success(t("Files:LinkSuccessfullyCopied"));
}
};
render() {
const {
t,
@ -88,6 +102,7 @@ export default function withBadges(WrappedComponent) {
viewAs,
isMutedBadge,
isArchiveFolderRoot,
isArchiveFolder,
} = this.props;
const { fileStatus, access, mute } = item;
@ -122,6 +137,8 @@ export default function withBadges(WrappedComponent) {
onFilesClick={onFilesClick}
viewAs={viewAs}
isMutedBadge={isMutedBadge}
onCopyPrimaryLink={this.onCopyPrimaryLink}
isArchiveFolder={isArchiveFolder}
/>
);
@ -140,11 +157,16 @@ export default function withBadges(WrappedComponent) {
versionHistoryStore,
dialogsStore,
filesStore,
publicRoomStore,
},
{ item }
) => {
const { isRecycleBinFolder, isPrivacyFolder, isArchiveFolderRoot } =
treeFoldersStore;
const {
isRecycleBinFolder,
isPrivacyFolder,
isArchiveFolderRoot,
isArchiveFolder,
} = treeFoldersStore;
const { markAsRead, setPinAction } = filesActionsStore;
const { isTabletView, isDesktopClient, theme } = auth.settingsStore;
const { setIsVerHistoryPanel, fetchFileVersions } = versionHistoryStore;
@ -153,7 +175,8 @@ export default function withBadges(WrappedComponent) {
setConvertDialogVisible,
setConvertItem,
} = dialogsStore;
const { setIsLoading, isMuteCurrentRoomNotifications } = filesStore;
const { setIsLoading, isMuteCurrentRoomNotifications, getPrimaryLink } =
filesStore;
const { roomType, mute } = item;
const isRoom = !!roomType;
@ -178,6 +201,8 @@ export default function withBadges(WrappedComponent) {
isDesktopClient,
setPinAction,
isMutedBadge,
getPrimaryLink,
isArchiveFolder,
};
}
)(observer(WithBadges));

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
) {
@ -176,6 +177,7 @@ export default function withFileActions(WrappedFileItem) {
item,
openFileAction,
setParentId,
setRoomType,
isTrashFolder,
isArchiveFolder,
} = this.props;
@ -198,6 +200,7 @@ export default function withFileActions(WrappedFileItem) {
item.foldersCount === 0
) {
setParentId(item.parentId);
setRoomType(item.roomType);
}
openFileAction(item);
@ -230,6 +233,7 @@ export default function withFileActions(WrappedFileItem) {
isFolder,
itemIndex,
currentDeviceType,
} = this.props;
const { access, id } = item;
@ -249,7 +253,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 +293,7 @@ export default function withFileActions(WrappedFileItem) {
return inject(
(
{
auth,
filesActionsStore,
dialogsStore,
treeFoldersStore,
@ -404,6 +409,7 @@ export default function withFileActions(WrappedFileItem) {
isSelected: !!selectedItem,
//parentFolder: selectedFolderStore.parentId,
setParentId: selectedFolderStore.setParentId,
setRoomType: selectedFolderStore.setRoomType,
isTrashFolder: isRecycleBinFolder,
getFolderInfo,
viewAs,
@ -420,6 +426,7 @@ export default function withFileActions(WrappedFileItem) {
withShiftSelect,
setSelection,
currentDeviceType: auth.settingsStore.currentDeviceType,
};
}
)(observer(WithFileActions));

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

@ -2,6 +2,7 @@ import React from "react";
import { inject, observer } from "mobx-react";
import toastr from "@docspace/components/toast/toastr";
import QuickButtons from "../components/QuickButtons";
import copy from "copy-to-clipboard";
export default function withQuickButtons(WrappedComponent) {
class WithQuickButtons extends React.Component {
@ -52,6 +53,15 @@ export default function withQuickButtons(WrappedComponent) {
.catch((err) => toastr.error(err));
};
onCopyPrimaryLink = async () => {
const { t, item, getPrimaryLink } = this.props;
const primaryLink = await getPrimaryLink(item.id);
if (primaryLink) {
copy(primaryLink.sharedTo.shareLink);
toastr.success(t("Files:LinkSuccessfullyCopied"));
}
};
render() {
const { isLoading } = this.state;
@ -64,6 +74,7 @@ export default function withQuickButtons(WrappedComponent) {
viewAs,
folderCategory,
isPublicRoom,
isArchiveFolder,
} = this.props;
const quickButtonsComponent = (
@ -80,6 +91,8 @@ export default function withQuickButtons(WrappedComponent) {
onClickDownload={this.onClickDownload}
onClickFavorite={this.onClickFavorite}
folderCategory={folderCategory}
onCopyPrimaryLink={this.onCopyPrimaryLink}
isArchiveFolder={isArchiveFolder}
/>
);
@ -99,11 +112,17 @@ export default function withQuickButtons(WrappedComponent) {
dialogsStore,
publicRoomStore,
treeFoldersStore,
filesStore,
}) => {
const { lockFileAction, setFavoriteAction, onSelectItem } =
filesActionsStore;
const { isPersonalFolderRoot, isArchiveFolderRoot, isTrashFolder } =
treeFoldersStore;
const {
isPersonalFolderRoot,
isArchiveFolderRoot,
isTrashFolder,
isArchiveFolder,
} = treeFoldersStore;
const { setSharingPanelVisible } = dialogsStore;
const folderCategory =
@ -120,6 +139,8 @@ export default function withQuickButtons(WrappedComponent) {
setSharingPanelVisible,
folderCategory,
isPublicRoom,
getPrimaryLink: filesStore.getPrimaryLink,
isArchiveFolder,
};
}
)(observer(WithQuickButtons));

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,8 +52,21 @@ const Shell = ({ items = [], page = "home", ...rest }) => {
whiteLabelLogoUrls,
standalone,
userId,
currentDeviceType,
showArticleLoader,
} = rest;
useEffect(() => {
const regex = /(\/){2,}/g;
const replaceRegex = /(\/)+/g;
const pathname = window.location.pathname;
if (regex.test(pathname)) {
window.location.replace(pathname.replace(replaceRegex, "$1"));
}
}, []);
useEffect(() => {
try {
loadBaseInfo();
@ -102,7 +116,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 +347,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} />
<Main isDesktop={isDesktop}>
{!isMobileOnly && <MainBar />}
{currentDeviceType !== DeviceType.mobile && <MainBar />}
<div className="main-container">
<Outlet />
</div>
@ -358,7 +374,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 +392,7 @@ const ShellWrapper = inject(({ auth, backup }) => {
setTheme,
whiteLabelLogoUrls,
standalone,
currentDeviceType,
} = settingsStore;
const isBase = settingsStore.theme.isBase;
@ -389,7 +408,7 @@ const ShellWrapper = inject(({ auth, backup }) => {
return {
loadBaseInfo: async () => {
await init();
await init(false, i18n);
setModuleInfo(config.homepage, "home");
setProductVersion(config.version);
@ -416,6 +435,9 @@ const ShellWrapper = inject(({ auth, backup }) => {
userId: auth?.userStore?.user?.id,
whiteLabelLogoUrls,
standalone,
currentDeviceType,
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) => {
@ -267,7 +269,8 @@ const Items = ({
if (isAdmin) {
if (
(item.pathParts &&
(item.pathParts[0] === myId || item.pathParts[0] === commonId)) ||
(item.pathParts[0].id === myId ||
item.pathParts[0].id === commonId)) ||
item.rootFolderType === FolderType.USER ||
item.rootFolderType === FolderType.COMMON ||
(item.rootFolderType === FolderType.TRASH && startDrag && !isArchive)
@ -276,7 +279,7 @@ const Items = ({
}
} else {
if (
(item.pathParts && item.pathParts[0] === myId) ||
(item.pathParts && item.pathParts[0].id === myId) ||
item.rootFolderType === FolderType.USER
) {
return true;
@ -311,7 +314,7 @@ const Items = ({
}, [deleteAction]);
const onEmptyTrashAction = () => {
isMobile && onHide();
currentDeviceType === DeviceType.mobile && onHide();
setEmptyTrashDialogVisible(true);
};
@ -425,7 +428,12 @@ export default inject(
dialogsStore,
clientLoadingStore,
}) => {
const { settingsStore, isCommunity, isPaymentPageAvailable } = auth;
const {
settingsStore,
isCommunity,
isPaymentPageAvailable,
currentDeviceType,
} = auth;
const { showText, docSpace } = settingsStore;
const {
@ -486,6 +494,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();
@ -76,6 +77,7 @@ const ArticleBodyContent = (props) => {
const state = {
title,
isRoot: true,
isPublicRoomType: false,
rootFolderType,
};
@ -120,6 +122,7 @@ const ArticleBodyContent = (props) => {
params = accountsFilter.toUrlParams();
path = getCategoryUrl(CategoryType.Accounts);
withTimer = false;
if (activeItemId === "accounts" && isAccounts) return;
break;
@ -129,7 +132,7 @@ const ArticleBodyContent = (props) => {
path = getCategoryUrl(CategoryType.Settings);
navigate(path);
if (isMobileOnly || isMobile()) {
if (currentDeviceType === DeviceType.mobile) {
toggleArticleOpen();
}
return;
@ -149,7 +152,7 @@ const ArticleBodyContent = (props) => {
navigate(path, { state });
if (isMobileOnly || isMobile()) {
if (currentDeviceType === DeviceType.mobile) {
toggleArticleOpen();
}
},
@ -297,6 +300,7 @@ export default inject(
FirebaseHelper,
theme,
setIsBurgerLoading,
currentDeviceType,
} = auth.settingsStore;
return {
@ -324,6 +328,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 = ({
@ -67,6 +54,7 @@ const MobileView = ({
clearPrimaryProgressData,
secondaryProgressDataStoreVisible,
secondaryProgressDataStorePercent,
secondaryProgressDataStoreIsDownload,
secondaryProgressDataStoreCurrentFile,
secondaryProgressDataStoreCurrentFilesCount,
clearSecondaryProgressData,
@ -82,7 +70,7 @@ const MobileView = ({
const primaryCurrentFile = React.useRef(null);
const openButtonToggler = React.useCallback(() => {
setIsOpenButton(prevState => !prevState);
setIsOpenButton((prevState) => !prevState);
}, []);
const showUploadPanel = React.useCallback(() => {
@ -98,9 +86,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;
@ -121,6 +109,12 @@ const MobileView = ({
secondaryProgressDataStorePercent) /
100;
const secondaryProgressStatus = secondaryProgressDataStoreIsDownload
? `${Math.floor(secondaryProgressDataStorePercent)}%`
: `${Math.floor(
currentSecondaryProgressItem
)}/${secondaryProgressDataStoreCurrentFilesCount}`;
const newProgressOptions = [
{
key: "primary-progress",
@ -141,9 +135,7 @@ const MobileView = ({
label: t("Common:OtherOperations"),
icon: MobileActionsRemoveReactSvgUrl,
percent: secondaryProgressDataStorePercent,
status: `${Math.round(
currentSecondaryProgressItem
)}/${secondaryProgressDataStoreCurrentFilesCount}`,
status: secondaryProgressStatus,
onCancel: clearSecondaryProgressData,
},
];
@ -176,6 +168,7 @@ const MobileView = ({
primaryProgressDataErrors,
secondaryProgressDataStoreVisible,
secondaryProgressDataStorePercent,
secondaryProgressDataStoreIsDownload,
secondaryProgressDataStoreCurrentFile,
secondaryProgressDataStoreCurrentFilesCount,
]);
@ -229,6 +222,7 @@ export default inject(({ uploadDataStore, treeFoldersStore }) => {
currentFile: secondaryProgressDataStoreCurrentFile,
filesCount: secondaryProgressDataStoreCurrentFilesCount,
clearSecondaryProgressData,
isDownload: secondaryProgressDataStoreIsDownload,
} = secondaryProgressDataStore;
return {
@ -243,6 +237,7 @@ export default inject(({ uploadDataStore, treeFoldersStore }) => {
clearPrimaryProgressData,
secondaryProgressDataStoreVisible,
secondaryProgressDataStorePercent,
secondaryProgressDataStoreIsDownload,
secondaryProgressDataStoreCurrentFile,
secondaryProgressDataStoreCurrentFilesCount,
clearSecondaryProgressData,

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();
@ -420,10 +421,18 @@ const ArticleMainButtonContent = (props) => {
},
];
const menuModel = [...actions];
if (pluginItems.length > 0) {
menuModel.push({
// menuModel.push({
// id: "actions_more-plugins",
// className: "main-button_drop-down",
// icon: PluginMoreReactSvgUrl,
// label: t("Common:More"),
// disabled: false,
// key: "more-plugins",
// items: pluginItems,
// });
actions.push({
id: "actions_more-plugins",
className: "main-button_drop-down",
icon: PluginMoreReactSvgUrl,
@ -434,6 +443,8 @@ const ArticleMainButtonContent = (props) => {
});
}
const menuModel = [...actions];
menuModel.push({
isSeparator: true,
key: "separator",
@ -479,9 +490,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 +584,7 @@ export default inject(
selectedFolderStore,
clientLoadingStore,
pluginStore,
versionHistoryStore,
}) => {
const { showArticleLoader } = clientLoadingStore;
const { mainButtonMobileVisible } = filesStore;
@ -592,7 +607,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 +655,9 @@ export default inject(
mainButtonMobileVisible,
moveToPanelVisible,
copyPanelVisible,
versionHistoryPanelVisible,
security,
currentDeviceType,
};
}
)(

View File

@ -2,17 +2,21 @@
import FormFillRectSvgUrl from "PUBLIC_DIR/images/form.fill.rect.svg?url";
import AccessEditFormReactSvgUrl from "PUBLIC_DIR/images/access.edit.form.react.svg?url";
import FileActionsConvertEditDocReactSvgUrl from "PUBLIC_DIR/images/file.actions.convert.edit.doc.react.svg?url";
import LinkReactSvgUrl from "PUBLIC_DIR/images/link.react.svg?url";
import TabletLinkReactSvgUrl from "PUBLIC_DIR/images/tablet-link.reat.svg?url";
import RefreshReactSvgUrl from "PUBLIC_DIR/images/refresh.react.svg?url";
import React, { useState } from "react";
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 { FileStatus, RoomsType } from "@docspace/common/constants";
import { Base } from "@docspace/components/themes";
import { ColorTheme, ThemeType } from "@docspace/components/ColorTheme";
import { isTablet } from "@docspace/components/utils/device";
import { classNames } from "@docspace/components/utils/classNames";
const StyledWrapper = styled.div`
display: flex;
@ -73,6 +77,8 @@ const Badges = ({
isMutedBadge,
isArchiveFolderRoot,
isVisitor,
onCopyPrimaryLink,
isArchiveFolder,
}) => {
const {
id,
@ -83,6 +89,7 @@ const Badges = ({
isEditing,
isRoom,
pinned,
isFolder,
} = item;
const showEditBadge = !locked || item.access === 0;
@ -94,14 +101,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";
@ -145,8 +151,15 @@ const Badges = ({
? { onClick: onShowVersionHistory }
: {};
const showCopyLinkIcon =
(item.roomType === RoomsType.PublicRoom ||
item.roomType === RoomsType.CustomRoom) &&
item.shared &&
!isArchiveFolder &&
!isTile;
return fileExst ? (
<div className="badges additional-badges">
<div className="badges additional-badges file__badges">
{isEditing && !isVisitor && (
<ColorTheme
themeId={ThemeType.IconButton}
@ -198,7 +211,34 @@ const Badges = ({
)}
</div>
) : (
<>
<div
className={classNames("badges", {
["folder__badges"]: isFolder && !isRoom,
["room__badges"]: isRoom,
})}
>
{showCopyLinkIcon && (
<ColorTheme
themeId={ThemeType.IconButton}
iconName={LinkReactSvgUrl}
className="badge row-copy-link icons-group tablet-badge"
size={sizeBadge}
onClick={onCopyPrimaryLink}
title={t("Files:CopyGeneralLink")}
/>
)}
{showCopyLinkIcon && (
<ColorTheme
themeId={ThemeType.IconButton}
iconName={TabletLinkReactSvgUrl}
className="badge tablet-row-copy-link icons-group tablet-badge"
size={sizeBadge}
onClick={onCopyPrimaryLink}
title={t("Files:CopyGeneralLink")}
/>
)}
{isRoom && pinned && (
<ColorTheme
themeId={ThemeType.IconButtonPin}
@ -217,7 +257,7 @@ const Badges = ({
onClick={onBadgeClick}
/>
)}
</>
</div>
);
};

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

@ -1,185 +1,58 @@
import React from "react";
import styled, { css } from "styled-components";
import EmptyScreenContainer from "@docspace/components/empty-screen-container";
import NoUserSelect from "@docspace/components/utils/commonStyles";
import {
tablet,
smallTablet,
desktop,
size,
} from "@docspace/components/utils/device";
import { isMobile, isMobileOnly } from "react-device-detect";
import { classNames } from "@docspace/components/utils/classNames";
const EmptyPageStyles = css`
padding: 44px 0px 64px 0px;
grid-column-gap: 40px;
grid-template-columns: 100px 1fr;
.empty-folder_link:not(:last-child) {
margin-bottom: 10px;
}
.empty-folder_link {
${props =>
props.theme.interfaceDirection === "rtl"
? css`
margin-left: 9px;
`
: css`
margin-right: 9px;
`}
}
@media ${desktop} {
.empty-folder_link:not(:last-child) {
margin-bottom: 2px;
}
}
@media ${tablet} {
padding: 44px 0px 64px 0px;
grid-column-gap: 33px;
}
@media ${smallTablet} {
${props =>
props.theme.interfaceDirection === "rtl"
? css`
padding-left: 44px;
`
: css`
padding-right: 44px;
`}
}
`;
const EmptyFolderWrapper = styled.div`
.empty-folder_container {
.empty-folder_link {
${props =>
props.theme.interfaceDirection === "rtl"
? css`
margin-left: 7px;
`
: css`
margin-right: 7px;
`}
}
.empty-folder_container-links {
display: grid;
margin: 13px 0;
grid-template-columns: 12px 1fr;
grid-column-gap: 8px;
.flex-wrapper_container {
display: flex;
flex-wrap: wrap;
row-gap: 16px;
column-gap: 8px;
justify-content: center;
}
}
.empty-folder_container-links:last-child {
margin-bottom: 0;
}
.second-description {
display: grid;
grid-template-columns: 1fr;
margin: 32px 0 26px !important;
}
.flex-wrapper_container {
display: flex;
flex-wrap: wrap;
row-gap: 16px;
margin: 32px 0 24px;
text-align: center;
}
.empty-folder_container-image {
margin-top: 3px;
cursor: pointer;
}
.empty-folder_container_up-image,
.empty-folder_container_plus-image {
${props =>
props.theme.interfaceDirection === "rtl"
? css`
margin: 4px 0 0 8px;
`
: css`
margin: 4px 8px 0 0;
`}
cursor: pointer;
width: 10px;
height: 10px;
}
.empty-folder_container_plus-image {
display: flex;
line-height: unset;
${NoUserSelect}
}
.empty-folder_container_up-image {
${NoUserSelect}
}
.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;
`}
cursor: pointer;
}
.empty-connect_container-links {
position: relative;
bottom: 16px;
.empty-folder_room-not-found {
margin-top: 70px;
}
${props => props.isEmptyPage && `${EmptyPageStyles}`}
${props =>
props.isEmptyPage &&
isMobileOnly &&
css`
${props =>
props.theme.interfaceDirection === "rtl"
? css`
padding: 20px 11px 64px 42px !important;
`
: css`
padding: 20px 42px 64px 11px !important;
`}
`}
${props =>
(props.isEmptyPage || props.isEmptyFolderContainer) &&
props.sectionWidth <= size.smallTablet &&
!isMobileOnly &&
css`
${props =>
props.theme.interfaceDirection === "rtl"
? css`
padding-right: 12px !important;
`
: css`
padding-left: 12px !important;
`}
.empty-folder_link {
margin-bottom: 0 !important;
}
`}
}
.empty-folder_room-not-found {
margin-top: 70px;
}
`;
const EmptyFoldersContainer = props => {
const EmptyFoldersContainer = (props) => {
const imageAlt = "Empty folder image";
const {
imageSrc,
@ -187,24 +60,18 @@ const EmptyFoldersContainer = props => {
subheadingText,
descriptionText,
buttons,
style,
imageStyle,
buttonStyle,
isEmptyPage,
sectionWidth,
isEmptyFolderContainer,
className,
isEmptyPage,
} = props;
return (
<EmptyFolderWrapper
sectionWidth={sectionWidth}
isEmptyPage={isEmptyPage}
isEmptyFolderContainer={isEmptyFolderContainer}>
<EmptyFolderWrapper>
<EmptyScreenContainer
sectionWidth={sectionWidth}
className={classNames("empty-folder_container", className)}
style={style}
imageStyle={imageStyle}
imageSrc={imageSrc}
imageAlt={imageAlt}
@ -213,8 +80,7 @@ const EmptyFoldersContainer = props => {
subheadingText={subheadingText}
descriptionText={descriptionText}
buttons={buttons}
isEmptyPage={isEmptyPage}
isEmptyFolderContainer={isEmptyFolderContainer}
withoutFilter={isEmptyPage}
/>
</EmptyFolderWrapper>
);

View File

@ -1,207 +1,60 @@
import PlusSvgUrl from "PUBLIC_DIR/images/plus.svg?url";
import UpSvgUrl from "PUBLIC_DIR/images/up.svg?url";
import EmptyScreenAltSvgUrl from "PUBLIC_DIR/images/empty_screen_alt.svg?url";
import EmptyScreenAltSvgDarkUrl from "PUBLIC_DIR/images/empty_screen_alt_dark.svg?url";
import EmptyScreenPersonalUrl from "PUBLIC_DIR/images/empty_screen_personal.svg?url";
import EmptyScreenPersonalDarkUrl from "PUBLIC_DIR/images/empty_screen_personal_dark.svg?url";
import EmptyScreenCorporateSvgUrl from "PUBLIC_DIR/images/empty_screen_corporate.svg?url";
import EmptyScreenCorporateDarkSvgUrl from "PUBLIC_DIR/images/empty_screen_corporate_dark.svg?url";
import { inject, observer } from "mobx-react";
import React, { useEffect } from "react";
import { useNavigate, useLocation } from "react-router-dom";
import { withTranslation } from "react-i18next";
import EmptyContainer from "./EmptyContainer";
import Link from "@docspace/components/link";
import Box from "@docspace/components/box";
import { Text } from "@docspace/components";
import { ReactSVG } from "react-svg";
import FilesFilter from "@docspace/common/api/files/filter";
import RoomsFilter from "@docspace/common/api/rooms/filter";
import Loaders from "@docspace/common/components/Loaders";
import { showLoader, hideLoader } from "./EmptyFolderContainerUtils";
import { FolderType, RoomSearchArea } from "@docspace/common/constants";
import { getCategoryUrl, getCategoryType } from "SRC_DIR/helpers/utils";
import { CategoryType } from "SRC_DIR/helpers/constants";
import CommonButtons from "./sub-components/CommonButtons";
const EmptyFolderContainer = ({
t,
onCreate,
setIsLoading,
parentId,
linkStyles,
editAccess,
sectionWidth,
canCreateFiles,
onClickInviteUsers,
folderId,
theme,
navigationPath,
rootFolderType,
roomType,
isLoading,
//isLoading,
isArchiveFolderRoot,
isEmptyPage,
}) => {
const navigate = useNavigate();
const location = useLocation();
//const location = useLocation();
const isRoom =
isLoading && location?.state?.isRoom ? location?.state?.isRoom : !!roomType;
// const isRoom =
// isLoading && location?.state?.isRoom ? location?.state?.isRoom : !!roomType;
const isRoom = !!roomType;
const displayRoomCondition = isRoom && !isArchiveFolderRoot;
const canInviteUsers = isRoom && editAccess;
const onBackToParentFolder = () => {
setIsLoading(true);
if (isRoom) {
const path =
rootFolderType === FolderType.Archive
? getCategoryUrl(CategoryType.Archive)
: getCategoryUrl(CategoryType.Shared);
const newFilter = RoomsFilter.getDefault();
newFilter.searchArea =
rootFolderType === FolderType.Archive
? RoomSearchArea.Archive
: RoomSearchArea.Active;
const state = {
title: navigationPath[0].title,
isRoot: true,
rootFolderType,
};
navigate(`${path}?${newFilter.toUrlParams()}`, {
state,
});
} else {
const categoryType = getCategoryType(location);
const newFilter = FilesFilter.getDefault();
newFilter.folder = parentId;
const parentIdx = navigationPath.findIndex((v) => v.id === parentId);
const parentItem = navigationPath[parentIdx];
const state = {
title: parentItem.title,
isRoot: navigationPath.length === 1,
rootFolderType,
};
const path = getCategoryUrl(categoryType, parentId);
navigate(`${path}?${newFilter.toUrlParams()}`, {
state,
});
}
};
const onInviteUsersClick = () => {
if (!isRoom) return;
onClickInviteUsers && onClickInviteUsers(folderId, roomType);
};
const buttons = canCreateFiles ? (
<>
<div className="empty-folder_container-links">
<ReactSVG
className="empty-folder_container_plus-image"
src={PlusSvgUrl}
data-format="docx"
onClick={onCreate}
/>
<Box className="flex-wrapper_container">
<Link data-format="docx" onClick={onCreate} {...linkStyles}>
{t("Document")},
</Link>
<Link data-format="xlsx" onClick={onCreate} {...linkStyles}>
{t("Spreadsheet")},
</Link>
<Link data-format="pptx" onClick={onCreate} {...linkStyles}>
{t("Presentation")},
</Link>
<Link data-format="docxf" onClick={onCreate} {...linkStyles}>
{t("Translations:NewForm")}
</Link>
</Box>
</div>
<div className="empty-folder_container-links">
<ReactSVG
className="empty-folder_container_plus-image"
onClick={onCreate}
src={PlusSvgUrl}
/>
<Link {...linkStyles} onClick={onCreate}>
{t("Folder")}
</Link>
</div>
{isRoom ? (
canInviteUsers ? (
<>
<div className="empty-folder_container-links second-description">
<Text as="span" color="#6A7378" fontSize="12px" noSelect>
{t("AddMembersDescription")}
</Text>
</div>
<div className="empty-folder_container-links">
<ReactSVG
className="empty-folder_container_plus-image"
onClick={onInviteUsersClick}
src={PlusSvgUrl}
/>
<Link onClick={onInviteUsersClick} {...linkStyles}>
{t("InviteUsersInRoom")}
</Link>
</div>
</>
) : (
<></>
)
) : (
<div className="empty-folder_container-links">
<ReactSVG
className="empty-folder_container_up-image"
src={UpSvgUrl}
onClick={onBackToParentFolder}
/>
<Link onClick={onBackToParentFolder} {...linkStyles}>
{t("BackToParentFolderButton")}
</Link>
</div>
)}
</>
) : (
<></>
);
const buttons = <CommonButtons onCreate={onCreate} linkStyles={linkStyles} />;
const emptyScreenCorporateSvg = theme.isBase
? EmptyScreenCorporateSvgUrl
: EmptyScreenCorporateDarkSvgUrl;
const emptyScreenAltSvg = theme.isBase
? EmptyScreenAltSvgUrl
: EmptyScreenAltSvgDarkUrl;
? EmptyScreenPersonalUrl
: EmptyScreenPersonalDarkUrl;
return (
<EmptyContainer
headerText={isRoom ? t("RoomCreated") : t("EmptyScreenFolder")}
style={{ gridColumnGap: "39px", marginTop: 32 }}
headerText={
displayRoomCondition ? t("RoomCreated") : t("EmptyScreenFolder")
}
descriptionText={
canCreateFiles
? t("EmptyFolderDecription")
: t("EmptyFolderDescriptionUser")
}
imageSrc={isRoom ? emptyScreenCorporateSvg : emptyScreenAltSvg}
imageSrc={
displayRoomCondition ? emptyScreenCorporateSvg : emptyScreenAltSvg
}
buttons={buttons}
sectionWidth={sectionWidth}
isEmptyFolderContainer={true}
isEmptyPage={isEmptyPage}
/>
);
};
@ -210,53 +63,28 @@ export default inject(
({
auth,
accessRightsStore,
selectedFolderStore,
contextOptionsStore,
clientLoadingStore,
treeFoldersStore,
filesStore,
}) => {
const {
navigationPath,
parentId,
id: folderId,
security,
rootFolderType,
roomType,
} = selectedFolderStore;
let id;
if (navigationPath?.length) {
const elem = navigationPath[0];
id = elem.id;
}
const { roomType } = selectedFolderStore;
const { canCreateFiles } = accessRightsStore;
const { onClickInviteUsers } = contextOptionsStore;
const { isLoading } = clientLoadingStore;
const { isArchiveFolderRoot } = treeFoldersStore;
const { setIsSectionFilterLoading, isLoading } = clientLoadingStore;
const setIsLoading = (param) => {
setIsSectionFilterLoading(param);
};
const { isEmptyPage } = filesStore;
return {
setIsLoading,
isLoading,
parentId: id ?? parentId,
roomType,
canCreateFiles,
navigationPath,
rootFolderType,
editAccess: security?.EditAccess,
onClickInviteUsers,
folderId,
isArchiveFolderRoot,
theme: auth.settingsStore.theme,
isEmptyPage,
};
}
)(withTranslation(["Files", "Translations"])(observer(EmptyFolderContainer)));

View File

@ -2,9 +2,8 @@
import PersonSvgUrl from "PUBLIC_DIR/images/person.svg?url";
import PlusSvgUrl from "PUBLIC_DIR/images/plus.svg?url";
import RoomsReactSvgUrl from "PUBLIC_DIR/images/rooms.react.svg?url";
import React, { useEffect } from "react";
import { useNavigate, useLocation } from "react-router-dom";
import styled from "styled-components";
import { FolderType, RoomSearchArea } from "@docspace/common/constants";
import { inject, observer } from "mobx-react";
import { withTranslation, Trans } from "react-i18next";
@ -13,14 +12,12 @@ import Link from "@docspace/components/link";
import Text from "@docspace/components/text";
import Box from "@docspace/components/box";
import IconButton from "@docspace/components/icon-button";
import Loaders from "@docspace/common/components/Loaders";
import RoomsFilter from "@docspace/common/api/rooms/filter";
import FilesFilter from "@docspace/common/api/files/filter";
import { getCategoryUrl } from "SRC_DIR/helpers/utils";
import { CategoryType } from "SRC_DIR/helpers/constants";
import PlusIcon from "PUBLIC_DIR/images/plus.react.svg";
import EmptyScreenPersonalUrl from "PUBLIC_DIR/images/empty_screen_personal.svg?url";
import EmptyScreenPersonalDarkUrl from "PUBLIC_DIR/images/empty_screen_personal_dark.svg?url";
import EmptyScreenCorporateSvgUrl from "PUBLIC_DIR/images/empty_screen_corporate.svg?url";
@ -36,13 +33,7 @@ import EmptyScreenTrashSvgDarkUrl from "PUBLIC_DIR/images/empty_screen_trash_dar
import EmptyScreenArchiveUrl from "PUBLIC_DIR/images/empty_screen_archive.svg?url";
import EmptyScreenArchiveDarkUrl from "PUBLIC_DIR/images/empty_screen_archive_dark.svg?url";
import { showLoader, hideLoader } from "./EmptyFolderContainerUtils";
const StyledPlusIcon = styled(PlusIcon)`
path {
fill: #657077;
}
`;
import CommonButtons from "./sub-components/CommonButtons";
const RootFolderContainer = (props) => {
const {
@ -249,72 +240,19 @@ const RootFolderContainer = (props) => {
);
const commonButtons = (
<span>
<div className="empty-folder_container-links">
<StyledPlusIcon
className="plus-document empty-folder_container-image"
data-format="docx"
onClick={onCreate}
alt="plus_icon"
/>
<Box className="flex-wrapper_container">
<Link
id="document"
data-format="docx"
onClick={onCreate}
{...linkStyles}
>
{t("Document")},
</Link>
<Link
id="spreadsheet"
data-format="xlsx"
onClick={onCreate}
{...linkStyles}
>
{t("Spreadsheet")},
</Link>
<Link
id="presentation"
data-format="pptx"
onClick={onCreate}
{...linkStyles}
>
{t("Presentation")},
</Link>
<Link
id="form-template"
data-format="docxf"
onClick={onCreate}
{...linkStyles}
>
{t("Translations:NewForm")}
</Link>
</Box>
</div>
<div className="empty-folder_container-links">
<StyledPlusIcon
className="plus-folder empty-folder_container-image"
onClick={onCreate}
alt="plus_icon"
/>
<Link id="folder" {...linkStyles} onClick={onCreate}>
{t("Folder")}
</Link>
</div>
</span>
<CommonButtons onCreate={onCreate} linkStyles={linkStyles} isRoot />
);
const trashButtons = (
<div className="empty-folder_container-links">
<img
className="empty-folder_container-image"
src={PersonSvgUrl}
alt="person_icon"
<IconButton
className="empty-folder_container-icon"
size="12"
onClick={onGoToPersonal}
iconName={PersonSvgUrl}
isFill
/>
<Link onClick={onGoToPersonal} {...linkStyles}>
{t("GoToPersonal")}
</Link>
@ -323,12 +261,14 @@ const RootFolderContainer = (props) => {
const roomsButtons = (
<div className="empty-folder_container-links">
<img
className="empty-folder_container_plus-image"
src={PlusSvgUrl}
<IconButton
className="empty-folder_container-icon"
size="12"
onClick={onCreateRoom}
alt="plus_icon"
iconName={PlusSvgUrl}
isFill
/>
<Link onClick={onCreateRoom} {...linkStyles}>
{t("CreateRoom")}
</Link>
@ -383,7 +323,6 @@ const RootFolderContainer = (props) => {
headerText={headerText}
isEmptyPage={isEmptyPage}
sectionWidth={sectionWidth}
style={{ marginTop: 32 }}
{...emptyFolderProps}
/>
)

View File

@ -1,12 +1,9 @@
import React from "react";
import { observer, inject } from "mobx-react";
import { useLocation } from "react-router-dom";
//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";
@ -20,7 +17,7 @@ const linkStyles = {
const EmptyContainer = ({
isFiltered,
isLoading,
//isLoading,
parentId,
theme,
@ -29,7 +26,7 @@ const EmptyContainer = ({
isGracePeriod,
setInviteUsersWarningDialogVisible,
}) => {
const location = useLocation();
//const location = useLocation();
linkStyles.color = theme.filesEmptyContainer.linkColor;
@ -66,8 +63,8 @@ const EmptyContainer = ({
);
}
const isRootEmptyPage =
isLoading && location?.state ? location.state?.isRoot : parentId === 0;
const isRootEmptyPage = parentId === 0;
//isLoading && location?.state ? location.state?.isRoot : parentId === 0;
return isFiltered ? (
<EmptyFilterContainer linkStyles={linkStyles} />

View File

@ -0,0 +1,282 @@
import PlusSvgUrl from "PUBLIC_DIR/images/plus.svg?url";
import UpSvgUrl from "PUBLIC_DIR/images/up.svg?url";
import { inject, observer } from "mobx-react";
import { useNavigate, useLocation } from "react-router-dom";
import { withTranslation } from "react-i18next";
import Link from "@docspace/components/link";
import Box from "@docspace/components/box";
import { Text } from "@docspace/components";
import IconButton from "@docspace/components/icon-button";
import { FolderType, RoomSearchArea } from "@docspace/common/constants";
import RoomsFilter from "@docspace/common/api/rooms/filter";
import FilesFilter from "@docspace/common/api/files/filter";
import { getCategoryUrl, getCategoryType } from "SRC_DIR/helpers/utils";
import { CategoryType } from "SRC_DIR/helpers/constants";
const OptionsComponent = (props) => {
const { onCreate, t, linkStyles } = props;
return (
<>
<div className="empty-folder_container-links">
<IconButton
data-format="docx"
className="empty-folder_container-icon"
size={12}
onClick={onCreate}
iconName={PlusSvgUrl}
isFill
/>
<Box className="flex-wrapper_container">
<Link data-format="docx" onClick={onCreate} {...linkStyles}>
{t("Document")},
</Link>
<Link data-format="xlsx" onClick={onCreate} {...linkStyles}>
{t("Spreadsheet")},
</Link>
<Link data-format="pptx" onClick={onCreate} {...linkStyles}>
{t("Presentation")},
</Link>
<Link data-format="docxf" onClick={onCreate} {...linkStyles}>
{t("Translations:NewForm")}
</Link>
</Box>
</div>
<div className="empty-folder_container-links">
<IconButton
className="empty-folder_container-icon"
size={12}
onClick={onCreate}
iconName={PlusSvgUrl}
isFill
/>
<Link {...linkStyles} onClick={onCreate}>
{t("Folder")}
</Link>
</div>
</>
);
};
const InviteUsersComponent = (props) => {
const { onInviteUsersClick, t, linkStyles } = props;
return (
<>
<div className="second-description">
<Text as="span" color="#6A7378" fontSize="12px" noSelect>
{t("AddMembersDescription")}
</Text>
</div>
<div className="empty-folder_container-links">
<IconButton
className="empty-folder_container-icon"
size={12}
onClick={onInviteUsersClick}
iconName={PlusSvgUrl}
isFill
/>
<Link onClick={onInviteUsersClick} {...linkStyles}>
{t("InviteUsersInRoom")}
</Link>
</div>
</>
);
};
const ButtonsComponent = (props) => {
const {
isRoom,
isArchiveFolderRoot,
editAccess,
onInviteUsersClick,
onBackToParentFolder,
linkStyles,
t,
isRoot,
} = props;
const displayRoomCondition = isRoom && !isArchiveFolderRoot;
const canInviteUsers = isRoom && editAccess;
if (displayRoomCondition) {
return canInviteUsers ? (
<InviteUsersComponent
{...props}
onInviteUsersClick={onInviteUsersClick}
/>
) : (
<></>
);
}
if (!isRoot) {
return (
<div className="empty-folder_container-links">
<IconButton
className="empty-folder_container-icon"
size={12}
onClick={onBackToParentFolder}
iconName={UpSvgUrl}
isFill={false}
/>
<Link onClick={onBackToParentFolder} {...linkStyles}>
{t("BackToParentFolderButton")}
</Link>
</div>
);
}
return <></>;
};
const CommonButtons = (props) => {
const {
canCreateFiles,
roomType,
navigationPath,
rootFolderType,
setIsLoading,
folderId,
onClickInviteUsers,
parentId,
} = props;
const navigate = useNavigate();
const location = useLocation();
const isRoom = !!roomType;
const onBackToParentFolder = () => {
setIsLoading(true);
if (isRoom) {
const path =
rootFolderType === FolderType.Archive
? getCategoryUrl(CategoryType.Archive)
: getCategoryUrl(CategoryType.Shared);
const newFilter = RoomsFilter.getDefault();
newFilter.searchArea =
rootFolderType === FolderType.Archive
? RoomSearchArea.Archive
: RoomSearchArea.Active;
const state = {
title: navigationPath[0].title,
isRoot: true,
rootFolderType,
};
navigate(`${path}?${newFilter.toUrlParams()}`, {
state,
});
} else {
const categoryType = getCategoryType(location);
const newFilter = FilesFilter.getDefault();
newFilter.folder = parentId;
const parentIdx = navigationPath.findIndex((v) => v.id === parentId);
const parentItem = navigationPath[parentIdx];
const state = {
title: parentItem.title,
isRoot: navigationPath.length === 1,
rootFolderType,
};
const path = getCategoryUrl(categoryType, parentId);
navigate(`${path}?${newFilter.toUrlParams()}`, {
state,
});
}
};
const onInviteUsersClick = () => {
if (!isRoom) return;
onClickInviteUsers && onClickInviteUsers(folderId, roomType);
};
if (canCreateFiles) {
return (
<>
<OptionsComponent {...props} />
<ButtonsComponent
isRoom={isRoom}
onInviteUsersClick={onInviteUsersClick}
onBackToParentFolder={onBackToParentFolder}
{...props}
/>
</>
);
}
return <></>;
};
export default inject(
({
auth,
accessRightsStore,
treeFoldersStore,
selectedFolderStore,
contextOptionsStore,
clientLoadingStore,
}) => {
const {
navigationPath,
parentId,
id: folderId,
security,
rootFolderType,
roomType,
} = selectedFolderStore;
const { isArchiveFolderRoot } = treeFoldersStore;
let id;
if (navigationPath?.length) {
const elem = navigationPath[0];
id = elem.id;
}
const { canCreateFiles } = accessRightsStore;
const { onClickInviteUsers } = contextOptionsStore;
const { setIsSectionFilterLoading, isLoading } = clientLoadingStore;
const setIsLoading = (param) => {
setIsSectionFilterLoading(param);
};
return {
setIsLoading,
isLoading,
parentId: id ?? parentId,
roomType,
canCreateFiles,
navigationPath,
rootFolderType,
editAccess: security?.EditAccess,
onClickInviteUsers,
folderId,
theme: auth.settingsStore.theme,
isArchiveFolderRoot,
};
}
)(withTranslation(["Files", "Translations"])(observer(CommonButtons)));

View File

@ -66,6 +66,9 @@ export type useRootHelperProps = {
treeFolders?: Item[];
setIsNextPageLoading: (value: boolean) => void;
setHasNextPage: (value: boolean) => void;
onSetBaseFolderPath?: (
value: number | string | undefined | BreadCrumb[]
) => void;
};
export type useRoomsHelperProps = {
@ -79,7 +82,9 @@ export type useRoomsHelperProps = {
setIsRoot: (value: boolean) => void;
searchValue?: string;
isRoomsOnly: boolean;
onSetBaseFolderPath?: (value: number | string | undefined) => void;
onSetBaseFolderPath?: (
value: number | string | undefined | BreadCrumb[]
) => void;
};
export type useFilesHelpersProps = {
@ -100,7 +105,9 @@ export type useFilesHelpersProps = {
setSelectedTreeNode: (treeNode: any) => void;
filterParam?: string;
getRootData?: () => Promise<void>;
onSetBaseFolderPath?: (value: number | string | undefined) => void;
onSetBaseFolderPath?: (
value: number | string | undefined | BreadCrumb[]
) => void;
isRoomsOnly: boolean;
rootThirdPartyId?: string;
getRoomList?: (
@ -126,6 +133,7 @@ export type FilesSelectorProps = {
isMove?: boolean;
isCopy?: boolean;
isRestoreAll?: boolean;
isSelect?: boolean;
filterParam?: string;
@ -158,9 +166,14 @@ export type FilesSelectorProps = {
fileIds: string[] | number[]
) => Promise<any>;
onSetBaseFolderPath?: (value: number | string | undefined) => void;
onSetBaseFolderPath?: (
value: number | string | undefined | BreadCrumb[]
) => 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 +181,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 +205,7 @@ export type FilesSelectorProps = {
socketHelper: any;
socketSubscribersId: Set<string>;
currentDeviceType: "mobile" | "tablet" | "desktop";
embedded: boolean;
};

View File

@ -21,6 +21,7 @@ import {
FilterType,
FolderType,
} from "@docspace/common/constants";
//@ts-ignore
import toastr from "@docspace/components/toast/toastr";
const getIconUrl = (extension: string, isImage: boolean, isMedia: boolean) => {
@ -316,6 +317,10 @@ export const useFilesHelper = ({
case FilesSelectorFilterTypes.DOCXF:
filter.filterType = FilterType.OFormTemplateOnly;
break;
case FilesSelectorFilterTypes.XLSX:
filter.filterType = FilterType.SpreadsheetsOnly;
break;
}
}
@ -323,15 +328,17 @@ export const useFilesHelper = ({
filter.folder = id.toString();
const setSettings = async (folderId, isErrorPath = false) => {
const setSettings = async (
folderId: string | number,
isErrorPath = false
) => {
if (isInit && getRootData) {
const folder = await getFolderInfo(folderId);
if (
folder.rootFolderType === FolderType.TRASH ||
folder.rootFolderType === FolderType.Archive
) {
if (isRoomsOnly) {
const isArchive = folder.rootFolderType === FolderType.Archive;
if (folder.rootFolderType === FolderType.TRASH || isArchive) {
if (isRoomsOnly && getRoomList) {
await getRoomList(0, true, null, true);
toastr.error(
t("Files:ArchivedRoomAction", { name: folder.title })
@ -339,6 +346,14 @@ export const useFilesHelper = ({
return;
}
await getRootData();
if (onSetBaseFolderPath && isArchive) {
onSetBaseFolderPath && onSetBaseFolderPath([]);
toastr.error(
t("Files:ArchivedRoomAction", { name: folder.title })
);
}
return;
}
}
@ -366,20 +381,28 @@ export const useFilesHelper = ({
setSelectedTreeNode({ ...current, path: pathParts });
if (isInit) {
const breadCrumbs: BreadCrumb[] = await Promise.all(
pathParts.map(async (folderId: number | string) => {
const folderInfo: any = await getFolderInfo(folderId);
const breadCrumbs: BreadCrumb[] = pathParts.map(
({
id,
title,
roomType,
}: {
id: number | string;
title: string;
roomType?: number;
}) => {
// const folderInfo: any = await getFolderInfo(folderId);
const { title, id, parentId, rootFolderType, roomType } =
folderInfo;
// const { title, id, parentId, rootFolderType, roomType } =
// folderInfo;
return {
label: title,
id: id,
isRoom: parentId === 0 && rootFolderType === FolderType.Rooms,
isRoom: !!roomType,
roomType,
};
})
}
);
!isThirdParty &&
@ -409,20 +432,26 @@ export const useFilesHelper = ({
try {
await setSettings(id);
} catch (e) {
if (isThirdParty) {
if (isThirdParty && rootThirdPartyId) {
await setSettings(rootThirdPartyId, true);
toastr.error(e);
return;
}
if (isRoomsOnly) {
if (isRoomsOnly && getRoomList) {
await getRoomList(0, true, null, true);
toastr.error(e);
return;
}
getRootData && getRootData();
if (onSetBaseFolderPath) {
onSetBaseFolderPath([]);
toastr.error(e);
}
}
},
[selectedItemId, searchValue, isFirstLoad, disabledItems]

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"]);
@ -148,6 +155,7 @@ const FilesSelector = ({
treeFolders,
setHasNextPage,
setIsNextPageLoading,
onSetBaseFolderPath,
});
const { getRoomList } = useRoomsHelper({
@ -292,6 +300,7 @@ const FilesSelector = ({
};
const onCloseAction = () => {
setInfoPanelIsMobileHidden(false);
if (onClose) {
onClose();
@ -427,6 +436,7 @@ const FilesSelector = ({
isCopy,
isRestoreAll,
isMove,
isSelect,
filterParam
);
@ -435,6 +445,7 @@ const FilesSelector = ({
isCopy,
isRestoreAll,
isMove,
isSelect,
filterParam
);
@ -453,13 +464,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 +544,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 +609,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 +674,12 @@ export default inject(
setRestoreAllPanelVisible,
setIsFolderActions,
setSelectedItems,
setInfoPanelIsMobileHidden,
includeFolder,
socketHelper,
socketSubscribersId,
setMoveToPublicRoomVisible,
currentDeviceType,
};
}
)(observer(FilesSelector));

View File

@ -17,11 +17,14 @@ export const getHeaderLabel = (
isCopy?: boolean,
isRestoreAll?: boolean,
isMove?: boolean,
isSelect?: boolean,
filterParam?: string
) => {
if (isMove) return t("Common:MoveTo");
if (isCopy) return t("Common:Copy");
if (isRestoreAll) return t("Common:Restore");
if (isSelect) return t("Common:SelectFile");
if (filterParam === FilesSelectorFilterTypes.DOCX)
return t("Translations:CreateMasterFormFromFile");
if (!!filterParam) return t("Common:SelectFile");
@ -34,11 +37,14 @@ export const getAcceptButtonLabel = (
isCopy?: boolean,
isRestoreAll?: boolean,
isMove?: boolean,
isSelect?: boolean,
filterParam?: string
) => {
if (isMove) return t("Translations:MoveHere");
if (isCopy) return t("Translations:CopyHere");
if (isRestoreAll) return t("Common:RestoreHere");
if (isSelect) return t("Common:SelectAction");
if (filterParam === FilesSelectorFilterTypes.DOCX) return t("Common:Create");
// if (filterParam === FilesSelectorFilterTypes.DOCXF) return t("Common:SubmitToGallery");
if (!!filterParam) return t("Common:SaveButton");

View File

@ -27,6 +27,7 @@ const FilesSelectorInput = (props) => {
filterParam,
descriptionText,
className,
} = props;
const isFilesSelection = !!filterParam;
@ -47,22 +48,17 @@ const FilesSelectorInput = (props) => {
};
const onSetBasePath = (folders) => {
console.log("onSetBasePath", withoutInitPath);
!withoutInitPath && setBasePath(folders);
isLoading && setIsLoading(false);
};
const onSelectFolder = (folderId, folders) => {
console.log("onSelectFolder", folderId, folders);
setSelectedFolder && setSelectedFolder(folderId);
folders && setNewPath(folders);
};
const onSelectFile = (fileInfo, folders) => {
console.log("onSelectFile", fileInfo, folders);
setSelectedFile && setSelectedFile(fileInfo);
folders && setNewPath(folders, fileInfo?.title);
};
@ -78,7 +74,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}
@ -119,7 +122,7 @@ const Dialog = ({
<TextInput
id="create-text-input"
name="create"
type="text"
type="search"
scale={true}
value={value}
isAutoFocussed={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

@ -1,5 +1,6 @@
import FileActionsLockedReactSvgUrl from "PUBLIC_DIR/images/file.actions.locked.react.svg?url";
import FileActionsDownloadReactSvgUrl from "PUBLIC_DIR/images/download.react.svg?url";
import LinkReactSvgUrl from "PUBLIC_DIR/images/link.react.svg?url";
import LockedReactSvgUrl from "PUBLIC_DIR/images/locked.react.svg?url";
import FileActionsFavoriteReactSvgUrl from "PUBLIC_DIR/images/file.actions.favorite.react.svg?url";
import FavoriteReactSvgUrl from "PUBLIC_DIR/images/favorite.react.svg?url";
@ -7,8 +8,8 @@ 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 { FileStatus } from "@docspace/common/constants";
import { isTablet } from "@docspace/components/utils/device";
import { FileStatus, RoomsType } from "@docspace/common/constants";
import { ColorTheme, ThemeType } from "@docspace/components/ColorTheme";
@ -20,11 +21,13 @@ const QuickButtons = (props) => {
sectionWidth,
onClickLock,
onClickDownload,
onCopyPrimaryLink,
isDisabled,
onClickFavorite,
viewAs,
folderCategory,
isPublicRoom,
isArchiveFolder,
} = props;
const { id, locked, fileStatus, title, fileExst } = item;
@ -48,8 +51,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";
@ -62,8 +64,15 @@ const QuickButtons = (props) => {
const isAvailableDownloadFile =
isPublicRoom && item.security.Download && viewAs === "tile";
const showCopyLinkIcon =
(item.roomType === RoomsType.PublicRoom ||
item.roomType === RoomsType.CustomRoom) &&
item.shared &&
!isArchiveFolder &&
!isTile;
return (
<div className="badges additional-badges">
<div className="badges additional-badges badges__quickButtons">
{isAvailableLockFile && (
<ColorTheme
themeId={ThemeType.IconButton}
@ -92,6 +101,19 @@ const QuickButtons = (props) => {
title={t("Common:Download")}
/>
)}
{showCopyLinkIcon && (
<ColorTheme
themeId={ThemeType.IconButton}
iconName={LinkReactSvgUrl}
className="badge copy-link icons-group"
size={sizeQuickButton}
onClick={onCopyPrimaryLink}
color={colorLock}
isDisabled={isDisabled}
hoverColor={theme.filesQuickButtons.sharedColor}
title={t("Files:CopyGeneralLink")}
/>
)}
{/* {fileExst && !isTrashFolder && displayBadges && (
<ColorTheme
themeId={ThemeType.IconButton}

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}

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