Update new UI for mobile
This commit is contained in:
@@ -35,7 +35,7 @@
|
||||
"components.add_mails_workspace.text_area_placeholder": "Enter emails of your users*",
|
||||
"components.alert.confirm": "Confirm your action",
|
||||
"components.alert.confirm_click": "Confirm your action by clicking on OK.",
|
||||
"components.create_folder_modal.hint": "Choose a name for the new folder.",
|
||||
"components.create_folder_modal.hint": "Create a folder",
|
||||
"components.create_folder_modal.placeholder": "Folder name",
|
||||
"components.create_link_modal.button": "Create link",
|
||||
"components.create_link_modal.hint": "Link name",
|
||||
@@ -48,6 +48,7 @@
|
||||
"components.disk_usage.in_trash": "in trash",
|
||||
"components.disk_usage.of": "of",
|
||||
"components.disk_usage.used": "used",
|
||||
"components.disk_usage.title": "Storage",
|
||||
"components.dragndrop_info_move_to": "move to",
|
||||
"components.drive_dropzone.uploading": "Uploading...",
|
||||
"components.header_path.my_trash": "My Trash",
|
||||
|
||||
@@ -48,6 +48,7 @@
|
||||
"components.disk_usage.in_trash": "dans la corbeille",
|
||||
"components.disk_usage.of": "sur",
|
||||
"components.disk_usage.used": "utilisé(s)",
|
||||
"components.disk_usage.title": "Stockage",
|
||||
"components.dragndrop_info_move_to": "déplacé vers",
|
||||
"components.drive_dropzone.uploading": "Téléchargement...",
|
||||
"components.header_path.my_trash": "Ma corbeille",
|
||||
|
||||
@@ -48,6 +48,7 @@
|
||||
"components.disk_usage.in_trash": "в корзине",
|
||||
"components.disk_usage.of": "из",
|
||||
"components.disk_usage.used": "использовано",
|
||||
"components.disk_usage.title": "хранилище",
|
||||
"components.dragndrop_info_move_to": "move to",
|
||||
"components.drive_dropzone.uploading": "Загрузка...",
|
||||
"components.header_path.my_trash": "Корзина \"Моего диска\"",
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
"components.add_mails_workspace.text_area_placeholder": "Nhập email của người dùng của bạn*",
|
||||
"components.alert.confirm": "Xác nhận hành động của bạn",
|
||||
"components.alert.confirm_click": "Xác nhận hành động của bạn bằng cách nhấp vào OK.",
|
||||
"components.create_folder_modal.hint": "Chọn tên cho thư mục mới.",
|
||||
"components.create_folder_modal.hint": "Tạo folder",
|
||||
"components.create_folder_modal.placeholder": "Tên thư mục",
|
||||
"components.create_link_modal.button": "Tạo liên kết",
|
||||
"components.create_link_modal.hint": "Tên liên kết",
|
||||
@@ -46,6 +46,7 @@
|
||||
"components.create_modal.upload_folders": "Tải lên thư mục từ thiết bị",
|
||||
"components.disk_usage.in_trash": "trong thùng rác",
|
||||
"components.disk_usage.used": "đã sử dụng",
|
||||
"components.disk_usage.title": "Lưu trữ",
|
||||
"components.dragndrop_info_move_to": "di chuyển đến",
|
||||
"components.drive_dropzone.uploading": "Đang tải lên...",
|
||||
"components.header_path.my_trash": "Thùng rác của tôi",
|
||||
|
||||
@@ -64,7 +64,8 @@ export default class Menu extends React.Component {
|
||||
elementRect,
|
||||
this.props.position,
|
||||
undefined,
|
||||
this.props.testClassId
|
||||
this.props.testClassId,
|
||||
this.props.enableMobileMenu,
|
||||
);
|
||||
this.setState({ isMenuOpen: true }, () => this.open = true);
|
||||
this.open = true;
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
|
||||
import MenusManager from '@components/menus/menus-manager.jsx';
|
||||
import MenuComponent from './menu-component.jsx';
|
||||
import MenusManager from '@components/menus/menus-manager';
|
||||
import MenuComponent from './menu-component';
|
||||
import OutsideClickHandler from 'react-outside-click-handler';
|
||||
import MobileMenu from './mobile-menu';
|
||||
|
||||
/*
|
||||
Where the menu will be displayed, this component should be in app.js (menus should be over all elements of the page)
|
||||
@@ -194,6 +195,26 @@ export default class MenusBodyLayer extends React.Component {
|
||||
marginLeft: item.position.marginLeft,
|
||||
}}
|
||||
>
|
||||
{item.enableMobileMenu ? (
|
||||
<MobileMenu
|
||||
withFrame
|
||||
menu={item.menu}
|
||||
openAt={item.openAt}
|
||||
level={item.level}
|
||||
animationClass={
|
||||
this.state.menus_manager.willClose || item.willClose
|
||||
? 'fade_out'
|
||||
: item.level === 0 || item.positionType
|
||||
? item.positionType === 'bottom'
|
||||
? 'skew_in_bottom_nobounce'
|
||||
: item.left
|
||||
? 'skew_in_left_nobounce'
|
||||
: 'skew_in_right_nobounce'
|
||||
: 'fade_in'
|
||||
}
|
||||
testClassId={item.menuTestClassId}
|
||||
/>
|
||||
) : (
|
||||
<MenuComponent
|
||||
withFrame
|
||||
menu={item.menu}
|
||||
@@ -212,6 +233,7 @@ export default class MenusBodyLayer extends React.Component {
|
||||
}
|
||||
testClassId={item.menuTestClassId}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</OutsideClickHandler>
|
||||
);
|
||||
|
||||
@@ -57,7 +57,7 @@ class MenusManager extends Observable {
|
||||
|
||||
this.notify();
|
||||
}
|
||||
async openMenu(menu, domRect, positionType, options, menuTestClassId) {
|
||||
async openMenu(menu, domRect, positionType, options, menuTestClassId, enableMobileMenu) {
|
||||
this.isOpen = 1;
|
||||
if(typeof menu === 'function') {
|
||||
menu = await menu();
|
||||
@@ -86,6 +86,7 @@ class MenusManager extends Observable {
|
||||
id: Number.unid(),
|
||||
allowClickOut: options.allowClickOut !== undefined ? options.allowClickOut : true,
|
||||
menuTestClassId,
|
||||
enableMobileMenu,
|
||||
});
|
||||
this.last_opened_id = Number.unid();
|
||||
this.notify();
|
||||
|
||||
@@ -0,0 +1,161 @@
|
||||
import React, { Component } from 'react';
|
||||
|
||||
import Icon from '@components/icon/icon.jsx';
|
||||
import { Modal, ModalContent } from '@atoms/modal';
|
||||
import Emojione from 'components/emojione/emojione';
|
||||
import MenusManager from '@components/menus/menus-manager.jsx';
|
||||
import './menu.scss';
|
||||
|
||||
/*
|
||||
One menu
|
||||
*/
|
||||
export default class MobileMenu extends React.Component {
|
||||
constructor(props) {
|
||||
super();
|
||||
this.state = {
|
||||
menus_manager: MenusManager,
|
||||
};
|
||||
MenusManager.addListener(this);
|
||||
}
|
||||
componentWillUnmount() {
|
||||
MenusManager.removeListener(this);
|
||||
}
|
||||
openSubMenu(dom_element, menu, level) {
|
||||
var elementRect = window.getBoundingClientRect(dom_element);
|
||||
elementRect.x = elementRect.x || elementRect.left;
|
||||
elementRect.y = elementRect.y || elementRect.top;
|
||||
MenusManager.openSubMenu(menu, elementRect, level);
|
||||
}
|
||||
closeSubMenu(level) {
|
||||
MenusManager.closeSubMenu(level);
|
||||
}
|
||||
hoverMenu(dom_element, item) {
|
||||
if (item.submenu && !item.submenu_replace) {
|
||||
this.last_hovered = item;
|
||||
this.openSubMenu(dom_element, item.submenu, this.props.level || 0);
|
||||
} else {
|
||||
this.closeSubMenu(this.props.level || 0);
|
||||
}
|
||||
}
|
||||
clickMenu(dom_element, item, evt) {
|
||||
if(Date.now() - this.props.openAt < 200 ){
|
||||
// When a menu is open and another one opens above it, you have to block the buttons for a while. Otherwise, the hovered option of the new menu will be clicked
|
||||
return;
|
||||
}
|
||||
if (item.submenu_replace) {
|
||||
this.state.menus_manager.openMenu(item.submenu, { x: evt.clientX, y: evt.clientY }, 'center');
|
||||
return;
|
||||
}
|
||||
if (item.onClick) {
|
||||
var res = item.onClick(evt);
|
||||
if (res !== false) {
|
||||
this.state.menus_manager.closeMenu();
|
||||
}
|
||||
}
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
<Modal
|
||||
open={this.state.menus_manager.isOpen === 1}
|
||||
closable={true}
|
||||
onClose={() => this.state.menus_manager.closeMenu()}
|
||||
className={`md:!max-w-sm testid:${this.props.testClassId}`}
|
||||
disableCountVisibleModals={true}
|
||||
>
|
||||
<ModalContent title="">
|
||||
<div
|
||||
ref={node => (this.original_menu = node)}
|
||||
className={
|
||||
'menu-list sm:py-0 ' + (this.props.withFrame ? 'text-black bg-white dark:bg-zinc-900 dark:text-white rounded-lg ' : '') + this.props.animationClass
|
||||
}>
|
||||
{(this.props.menu || [])
|
||||
.filter(item => item && !item.hide)
|
||||
.map((item, index) => {
|
||||
if (item.type == 'separator') {
|
||||
return <div key={'menu_' + index} className="menu-separator" />;
|
||||
} else if (item.type == 'title') {
|
||||
return (
|
||||
<div key={'menu_' + index} className={'menu-title ' + item.className}>
|
||||
{item.text}
|
||||
</div>
|
||||
);
|
||||
} else if (item.type == 'text') {
|
||||
return (
|
||||
<div
|
||||
key={'menu_' + index}
|
||||
ref={node => (item.ref = node)}
|
||||
className={'menu-text ' + item.className + ' testid:menu-item'}
|
||||
onMouseEnter={evt => {
|
||||
this.hoverMenu(item.ref, item);
|
||||
}}
|
||||
>
|
||||
{item.icon && (
|
||||
<div className="icon">
|
||||
{typeof item.icon === 'string' ? <Icon type={item.icon} /> : item.icon}
|
||||
</div>
|
||||
)}
|
||||
<div className={`text testid:menu-item-${item.testClassId}`}>{item.text}</div>
|
||||
</div>
|
||||
);
|
||||
} else if (item.type == 'react-element') {
|
||||
return (
|
||||
<div
|
||||
key={'menu_' + index}
|
||||
className={'menu-custom ' + item.className + ' testid:menu-item'}
|
||||
onClick={item.onClick}
|
||||
>
|
||||
{typeof item.reactElement == 'function'
|
||||
? item.reactElement(this.props.level)
|
||||
: item.reactElement}
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<div
|
||||
key={'menu_' + index}
|
||||
ref={node => (item.ref = node)}
|
||||
className={
|
||||
'menu ' +
|
||||
item.className +
|
||||
' ' +
|
||||
(this.state.menus_manager.max_level > this.props.level &&
|
||||
this.last_hovered == item
|
||||
? 'hovered '
|
||||
: '') +
|
||||
(item.selected ? 'selected ' : '') +
|
||||
' testid:menu-item'
|
||||
}
|
||||
onMouseEnter={evt => {
|
||||
this.hoverMenu(item.ref, item);
|
||||
}}
|
||||
onClick={evt => {
|
||||
this.clickMenu(item.ref, item, evt);
|
||||
}}
|
||||
>
|
||||
{item.icon && (
|
||||
<div className="icon">
|
||||
{typeof item.icon === 'string' ? <Icon type={item.icon} /> : item.icon}
|
||||
</div>
|
||||
)}
|
||||
{item.emoji && (
|
||||
<div className="icon">
|
||||
<Emojione type={item.emoji} />
|
||||
</div>
|
||||
)}
|
||||
<div className={`text testid:menu-item-${item.testClassId}`}>{item.text}</div>
|
||||
<div className="more">
|
||||
{item.rightIcon && <Icon type={item.rightIcon} />}
|
||||
{item.submenu && !item.submenu_replace && <Icon type="angle-right" />}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
})
|
||||
}
|
||||
</div>
|
||||
|
||||
</ModalContent>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -224,7 +224,8 @@ export default memo(
|
||||
key: index,
|
||||
className:
|
||||
(index === 0 ? 'rounded-t-md ' : '-mt-px ') +
|
||||
(index === items.length - 1 ? 'rounded-b-md ' : ''),
|
||||
(index === items.length - 1 ? 'rounded-b-md ' : '') +
|
||||
'border-0 md:border',
|
||||
item: child,
|
||||
checked: checked[child.id] || false,
|
||||
onCheck: (v: boolean) => setChecked(_.pickBy({ ...checked, [child.id]: v }, _.identity)),
|
||||
@@ -358,7 +359,7 @@ export default memo(
|
||||
(loading && (!items?.length || loadingParentChange) ? 'opacity-50 ' : '')
|
||||
}
|
||||
>
|
||||
<div className={`flex flex-row shrink-0 items-center mb-4 ${!sharedWithMe ? 'flex-wrap' : ''}`}>
|
||||
<div className={`flex flex-row shrink-0 items-center mb-4 ${!sharedWithMe ? 'flex-wrap' : ''} border-b md:border-b-0 px-4 py-2 md:px-0 md:py-0`}>
|
||||
{sharedWithMe ? (
|
||||
<div>
|
||||
<Title className="mb-4 block">
|
||||
@@ -445,14 +446,14 @@ export default memo(
|
||||
<div className="grow" />
|
||||
|
||||
{access !== 'read' && (
|
||||
<BaseSmall>
|
||||
<BaseSmall className="hidden md:block">
|
||||
{formatBytes(item?.size || 0)} {Languages.t('scenes.app.drive.used')}
|
||||
</BaseSmall>
|
||||
)}
|
||||
|
||||
<Menu menu={() => onBuildSortContextMenu()} sortData={sortLabel} testClassId="browser-menu-sorting">
|
||||
{' '}
|
||||
<Button theme="outline" className="ml-4 flex flex-row items-center" testClassId="button-sorting">
|
||||
<Button theme="outline" className="ml-4 flex flex-row items-center border-0 md:border !text-gray-500 md:!text-blue-500 px-0 md:px-4" testClassId="button-sorting">
|
||||
<SortIcon
|
||||
className={`h-4 w-4 mr-2 -ml-1 ${
|
||||
sortLabel.order === 'asc' ? 'transform rotate-180' : ''
|
||||
@@ -467,7 +468,7 @@ export default memo(
|
||||
{viewId !== 'shared_with_me' && (
|
||||
<Menu menu={() => onBuildContextMenu(details)} testClassId="browser-menu-more">
|
||||
{' '}
|
||||
<Button theme="secondary" className="ml-4 flex flex-row items-center" testClassId="button-more">
|
||||
<Button theme="secondary" className="ml-4 flex flex-row items-center bg-transparent md:bg-blue-500 md:bg-opacity-25 !text-gray-500 md:!text-blue-500 px-0 md:px-4" testClassId="button-more">
|
||||
<span>
|
||||
{selectedCount > 1
|
||||
? `${selectedCount} items`
|
||||
@@ -510,7 +511,8 @@ export default memo(
|
||||
key={index}
|
||||
className={
|
||||
(index === 0 ? 'rounded-t-md ' : '-mt-px ') +
|
||||
(index === items.length - 1 ? 'rounded-b-md ' : '')
|
||||
(index === items.length - 1 ? 'rounded-b-md ' : '') +
|
||||
'border-0 md:border'
|
||||
}
|
||||
item={child}
|
||||
onClick={() => {
|
||||
|
||||
@@ -44,6 +44,8 @@ export const DocumentRow = ({
|
||||
// history.push(RouterServices.generateRouteFromState({ companyId: company, itemId: item.id }));
|
||||
};
|
||||
|
||||
const isMobile = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={
|
||||
@@ -78,17 +80,17 @@ export const DocumentRow = ({
|
||||
fallback={<DocumentIcon item={item} />}
|
||||
/>
|
||||
</div>
|
||||
<div className="md:grow text-ellipsis whitespace-nowrap">
|
||||
<Base className={`block text-ellipsis whitespace-nowrap overflow-hidden ${hasAnyPublicLinkAccess(item) ? 'w-[38px]' : 'w-[74px]'} md:w-full`}>{item.name}</Base>
|
||||
<div className="grow text-ellipsis whitespace-nowrap overflow-hidden">
|
||||
<Base className={`block text-ellipsis whitespace-nowrap overflow-hidden max-w-full`}>{item.name}</Base>
|
||||
</div>
|
||||
<div className="shrink-0 md:ml-4">
|
||||
{hasAnyPublicLinkAccess(item) && <PublicIcon className="h-5 w-5 text-blue-500 ml-4" />}
|
||||
{hasAnyPublicLinkAccess(item) && <PublicIcon className="h-5 w-5 ml-4 text-gray-500 md:text-blue-500" />}
|
||||
</div>
|
||||
<div className="shrink-0 ml-4 md:mr-12">
|
||||
<div className="shrink-0 ml-4 md:mr-12 hidden md:block">
|
||||
<BaseSmall>{formatDateShort(item?.last_version_cache?.date_added)}</BaseSmall>
|
||||
</div>
|
||||
<div className="shrink-0 ml-4 mr-4 md:mr-none text-right lg:w-24 sm:w-20 ">
|
||||
<BaseSmall>{formatBytes(item.size)}</BaseSmall>
|
||||
<BaseSmall className="text-gray-500 dark:md:text-white md:text-black">{formatBytes(item.size)}</BaseSmall>
|
||||
</div>
|
||||
{FeatureTogglesService.isActiveFeatureName(FeatureNames.COMPANY_AV_ENABLED) && (
|
||||
<div className="shrink-0 ml-4 text-right lg:w-24 sm:w-20 ">
|
||||
@@ -102,11 +104,11 @@ export const DocumentRow = ({
|
||||
</div>
|
||||
)}
|
||||
<div className="shrink-0 ml-auto md:ml-4">
|
||||
<Menu menu={onBuildContextMenu} testClassId="document-row-menu">
|
||||
<Menu menu={onBuildContextMenu} enableMobileMenu={isMobile} testClassId="document-row-menu">
|
||||
<Button
|
||||
theme={'secondary'}
|
||||
size="sm"
|
||||
className={'!rounded-full '}
|
||||
className={'!rounded-full !text-gray-500 md:!text-blue-500 bg-transparent md:bg-blue-500 md:bg-opacity-25 '}
|
||||
icon={DotsHorizontalIcon}
|
||||
testClassId="document-row-button-open-menu"
|
||||
/>
|
||||
|
||||
@@ -20,6 +20,8 @@ export const FolderRow = ({
|
||||
}: DriveItemProps) => {
|
||||
const [hover, setHover] = useState(false);
|
||||
|
||||
const isMobile = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={
|
||||
@@ -48,22 +50,22 @@ export const FolderRow = ({
|
||||
/>
|
||||
</div>
|
||||
<div className="grow whitespace-nowrap overflow-hidden">
|
||||
<Base className="!font-semibold text-ellipsis overflow-hidden block max-w-full">{item.name}</Base>
|
||||
<Base className="text-ellipsis overflow-hidden block max-w-full">{item.name}</Base>
|
||||
</div>
|
||||
<div className="shrink-0 ml-4">
|
||||
{hasAnyPublicLinkAccess(item) && (
|
||||
<PublicIcon className="h-5 w-5 text-blue-500" />
|
||||
<PublicIcon className="h-5 w-5 text-gray-500 md:text-blue-500" />
|
||||
)}
|
||||
</div>
|
||||
<div className="shrink-0 ml-4 text-right minWidth80">
|
||||
<BaseSmall>{formatBytes(item.size)}</BaseSmall>
|
||||
<BaseSmall className="text-gray-500 dark:md:text-white md:text-black">{formatBytes(item.size)}</BaseSmall>
|
||||
</div>
|
||||
<div className="shrink-0 ml-4">
|
||||
<Menu menu={onBuildContextMenu} testClassId="folder-row-menu">
|
||||
<Menu menu={onBuildContextMenu} enableMobileMenu={isMobile} testClassId="folder-row-menu">
|
||||
<Button
|
||||
theme={'secondary'}
|
||||
size="sm"
|
||||
className={'!rounded-full '}
|
||||
className={'!rounded-full !text-gray-500 md:!text-blue-500 bg-transparent md:bg-blue-500 md:bg-opacity-25 '}
|
||||
icon={DotsHorizontalIcon}
|
||||
testClassId="folder-row-button-open-menu"
|
||||
/>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Title } from '@atoms/text';
|
||||
import { DriveItem } from '@features/drive/types';
|
||||
import { ChevronDownIcon } from '@heroicons/react/solid';
|
||||
import { ChevronDownIcon, ChevronLeftIcon } from '@heroicons/react/solid';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { PublicIcon } from './components/public-icon';
|
||||
import MenusManager from '@components/menus/menus-manager.jsx';
|
||||
@@ -74,7 +74,8 @@ export const PathRender = ({
|
||||
const pathLength = (pathToRender || []).reduce((acc, curr) => acc + curr.name.length, 0);
|
||||
|
||||
return (
|
||||
<nav className="overflow-hidden whitespace-nowrap mr-2 pl-px inline-flex md:max-w-[50%] sm:max-w-[20%] testid:header-path">
|
||||
<>
|
||||
<nav className="overflow-hidden whitespace-nowrap mr-2 pl-px hidden md:inline-flex max-w-[50%] testid:header-path">
|
||||
{pathLength < 70 ? (
|
||||
(pathToRender || [])?.map((a, i) => (
|
||||
<PathItem
|
||||
@@ -114,6 +115,24 @@ export const PathRender = ({
|
||||
</>
|
||||
)}
|
||||
</nav>
|
||||
<nav className="overflow-hidden whitespace-nowrap mr-2 pl-px inline-flex md:hidden max-w-[50%] testid:header-path">
|
||||
<PathItem
|
||||
key={pathToRender[pathToRender.length - 2]?.id}
|
||||
item={pathToRender[pathToRender?.length - 2]}
|
||||
first={false}
|
||||
last={false}
|
||||
isPreviousItemInMobile={true}
|
||||
onClick={onClick}
|
||||
/>
|
||||
<PathItem
|
||||
key={pathToRender[pathToRender.length - 1]?.id}
|
||||
item={pathToRender[pathToRender?.length - 1]}
|
||||
first={false}
|
||||
last={true}
|
||||
onClick={onClick}
|
||||
/>
|
||||
</nav>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -121,11 +140,13 @@ const PathItem = ({
|
||||
item,
|
||||
first,
|
||||
last,
|
||||
isPreviousItemInMobile,
|
||||
onClick,
|
||||
}: {
|
||||
item: Partial<DriveItem>;
|
||||
last?: boolean;
|
||||
first?: boolean;
|
||||
isPreviousItemInMobile?: boolean;
|
||||
onClick: (viewId: string, dirId: string) => void;
|
||||
}) => {
|
||||
const { user } = useCurrentUser();
|
||||
@@ -181,11 +202,15 @@ const PathItem = ({
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Title noColor={last} className={!first ? 'text-blue-500 inline-block overflow-hidden text-ellipsis max-w-36' : ''}>
|
||||
<Title noColor={last} className={!first ? 'text-black dark:text-white md:text-blue-500 inline-block overflow-hidden text-ellipsis max-w-full' : ''}>
|
||||
{(() => {
|
||||
const isTrash = viewId?.includes('trash_') || viewId === 'trash';
|
||||
const fileName = cutFileName(item?.name) || '';
|
||||
|
||||
if (isPreviousItemInMobile && fileName) {
|
||||
return <ChevronLeftIcon className="w-6 h-6 mr-2 ml-[-6px]" />
|
||||
}
|
||||
|
||||
if (first) {
|
||||
if (isTrash) {
|
||||
return viewId?.includes('trash_')
|
||||
@@ -202,15 +227,15 @@ const PathItem = ({
|
||||
})()}
|
||||
</Title>
|
||||
</a>
|
||||
{hasAnyPublicLinkAccess(item) && (
|
||||
{hasAnyPublicLinkAccess(item) && !isPreviousItemInMobile && (
|
||||
<PublicIcon className="h-5 w-5 ml-2" />
|
||||
)}
|
||||
{first && !!user?.id && viewId?.includes('trash') && (
|
||||
{first && !!user?.id && viewId?.includes('trash') && !isPreviousItemInMobile && (
|
||||
<span className="ml-2 -mr-1 text-gray-700">
|
||||
<ChevronDownIcon className="w-4 h-4" />
|
||||
</span>
|
||||
)}
|
||||
{!last && (
|
||||
{!last && !isPreviousItemInMobile && (
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
className="w-6 h-6 text-gray-400 mx-1"
|
||||
|
||||
@@ -3,7 +3,7 @@ import { useRecoilState } from 'recoil';
|
||||
import { CreateModalAtom } from '.';
|
||||
import { Button } from '@atoms/button/button';
|
||||
import { Input } from '@atoms/input/input-text';
|
||||
import { Info } from '@atoms/text';
|
||||
import { Base } from '@atoms/text';
|
||||
import { useDriveActions } from '@features/drive/hooks/use-drive-actions';
|
||||
import Languages from "features/global/services/languages-service";
|
||||
|
||||
@@ -29,7 +29,7 @@ export const CreateFolder = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<Info>{ Languages.t('components.create_folder_modal.hint')}</Info>
|
||||
<Base className="!font-medium">{ Languages.t('components.create_folder_modal.hint')}</Base>
|
||||
<div ref={inputRef}>
|
||||
<Input
|
||||
disabled={loading}
|
||||
|
||||
@@ -45,12 +45,13 @@ export const CreateModal = ({
|
||||
return (
|
||||
<Modal
|
||||
open={state.open}
|
||||
closable={true}
|
||||
onClose={() => setState({ ...state, open: false })}
|
||||
className="!max-w-sm testid:create-modal"
|
||||
className="md:!max-w-sm testid:create-modal"
|
||||
>
|
||||
<ModalContent
|
||||
title={
|
||||
<div className="flex flex-row items-center justify-start">
|
||||
<div className="hidden md:flex flex-row items-center justify-start">
|
||||
{!!state.type && (
|
||||
<A onClick={() => setState({ ...state, type: '' })}>
|
||||
<ChevronLeftIcon className="w-6 h-6" />
|
||||
@@ -183,7 +184,7 @@ const CreateModalOption = (props: { testClassId?: string; icon: ReactNode; text:
|
||||
return (
|
||||
<div
|
||||
onClick={props.onClick}
|
||||
className={`flex flex-row p-4 dark:bg-zinc-900 dark:text-white bg-zinc-100 hover:bg-opacity-75 cursor-pointer rounded-md m-2 focus:bg-zinc-800 dark:focus:bg-zinc-800 outline-none focus:border-none ${testId}`}
|
||||
className={`flex flex-row py-2 md:p-4 md:dark:bg-zinc-900 dark:text-white md:bg-zinc-100 md:hover:bg-opacity-75 cursor-pointer rounded-md m-2 focus:bg-zinc-800 dark:focus:bg-zinc-800 outline-none focus:border-none ${testId}`}
|
||||
tabIndex={0}
|
||||
onKeyUp={handleKeyPress}
|
||||
>
|
||||
|
||||
@@ -39,12 +39,13 @@ export const UploadModal = ({
|
||||
return (
|
||||
<Modal
|
||||
open={state.open}
|
||||
closable={true}
|
||||
onClose={() => setState({ ...state, open: false })}
|
||||
className="!max-w-sm testid:upload-modal"
|
||||
className="md:!max-w-sm testid:upload-modal"
|
||||
>
|
||||
<ModalContent
|
||||
title={
|
||||
<div className="flex flex-row items-center justify-start">
|
||||
<div className="hidden md:flex flex-row items-center justify-start">
|
||||
{!!state.type && (
|
||||
<A onClick={() => setState({ ...state, type: '' })}>
|
||||
<ChevronLeftIcon className="w-6 h-6" />
|
||||
@@ -106,7 +107,7 @@ const CreateModalOption = (props: {
|
||||
return (
|
||||
<div
|
||||
onClick={props.onClick}
|
||||
className={`flex flex-row p-4 dark:bg-zinc-900 dark:text-white bg-zinc-100 hover:bg-opacity-75 cursor-pointer rounded-md m-2 focus:bg-zinc-800 dark:focus:bg-zinc-800 outline-none focus:border-none testid:${props.testClassId}`}
|
||||
className={`flex flex-row py-2 md:p-4 md:dark:bg-zinc-900 dark:text-white md:bg-zinc-100 md:hover:bg-opacity-75 cursor-pointer rounded-md m-2 focus:bg-zinc-800 dark:focus:bg-zinc-800 outline-none focus:border-none testid:${props.testClassId}`}
|
||||
tabIndex={0}
|
||||
onKeyUp={handleKeyPress}
|
||||
>
|
||||
|
||||
@@ -67,7 +67,8 @@ const DiskUsage = () => {
|
||||
</div>
|
||||
)}
|
||||
{!FeatureTogglesService.isActiveFeatureName(FeatureNames.COMPANY_USER_QUOTA) && (
|
||||
<div className="bg-zinc-500 dark:bg-zinc-900 bg-opacity-10 rounded-md p-4 w-auto max-w-md">
|
||||
<div className="md:bg-zinc-500 md:dark:bg-zinc-900 md:bg-opacity-10 rounded-md p-4 w-auto max-w-md">
|
||||
<Base className="!font-medium md:hidden">{Languages.t('components.disk_usage.title')}</Base>
|
||||
<div className="w-full">
|
||||
<Base className="testid:disk-usage-text">
|
||||
{formatBytesToInt(usedBytes)}
|
||||
|
||||
@@ -73,7 +73,7 @@ export default React.memo((): JSX.Element => {
|
||||
onClick={() => setMenuIsOpen(false)}
|
||||
className="absolute left-0 top-0 h-full w-full bg-black bg-opacity-50 transition-all z-40 opacity-0"
|
||||
></div>
|
||||
<div className="bg-white dark:bg-zinc-900 flex grow sm:rounded-lg p-4 sm:w-2/3 overflow-x-hidden">
|
||||
<div className="bg-white dark:bg-zinc-900 flex grow sm:rounded-lg sm:w-2/3 overflow-x-hidden p-0 md:p-4">
|
||||
<Suspense fallback={<></>}>
|
||||
<MainView className={classNames({ collapsed: menuIsOpen })} />
|
||||
</Suspense>
|
||||
|
||||
@@ -52,11 +52,25 @@ export default () => {
|
||||
<div className="grow">
|
||||
<div className="sm:hidden block mb-2">
|
||||
<div className="flex flex-row space-between w-full">
|
||||
<div className="grow">
|
||||
<div className="flex items-center order-1 grow">
|
||||
<img
|
||||
src="/public/img/logo/logo-text-black.svg"
|
||||
className="h-6 ml-1 dark:hidden block"
|
||||
alt="Tdrive"
|
||||
/>
|
||||
<img
|
||||
src="/public/img/logo/logo-text-white.svg"
|
||||
className="h-6 ml-1 dark:block hidden"
|
||||
alt="Tdrive"
|
||||
/>
|
||||
</div>
|
||||
<div className="md:grow order-3 md:order-2">
|
||||
<Account />
|
||||
</div>
|
||||
<div className="order-2 md:order-3 mr-2 md:mr-0">
|
||||
<AppGrid />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mt-6" />
|
||||
<Title>Actions</Title>
|
||||
|
||||
Reference in New Issue
Block a user