🎨 [element-identifier]: Update test id convention

This commit is contained in:
lethemanh
2024-12-12 13:33:58 +07:00
parent 6d3be1fa28
commit c59545aff1
52 changed files with 220 additions and 180 deletions
@@ -40,7 +40,8 @@ export default function Avatar(props: AvatarProps) {
const fontSize = fontSizes[props.size || 'md'];
const addedClassName = props.className || '';
const avatarTitle = props.title || '';
const restProps = _.omit(props, 'size', 'type', 'avatar', 'title', 'className', 'icon');
const testClassId = props.testClassId;
const restProps = _.omit(props, 'size', 'type', 'avatar', 'title', 'className', 'icon', 'testClassId');
let className = `w-${avatarSize} h-${avatarSize} ${
avatarType === 'circle' ? 'rounded-full' : 'rounded-sm'
@@ -65,17 +66,19 @@ export default function Avatar(props: AvatarProps) {
? {}
: { backgroundImage: `url('${getGradient(props.title || '')}')` };
const testId = testClassId ? `testid:${testClassId}` : ''
if (props.icon) {
className += ' ';
return (
<div
{..._.omit(restProps, 'testClassId')}
{...restProps}
style={style}
className={
className +
' text-white overflow-hidden flex items-center justify-center ' +
addedClassName + ' ' +
(props.testClassId ? `testid:${props.testClassId}` : '')
testId
}
>
{props.icon}
@@ -85,18 +88,18 @@ export default function Avatar(props: AvatarProps) {
if (props.avatar) {
return (
<div {..._.omit(restProps, 'testClassId')}>
<div {...restProps}>
<img
alt={props.title}
src={props.avatar}
className={className + ' object-cover ' + addedClassName + ' ' + (props.testClassId ? `testid:${props.testClassId}` : '')}
className={className + ' object-cover ' + addedClassName + ' ' + testId}
/>
</div>
);
}
return (
<div className={className + ' ' + addedClassName + ' ' + (props.testClassId ? `testid:${props.testClassId}` : '')} {..._.omit(restProps, 'testClassId')} style={style}>
<div className={className + ' ' + addedClassName + ' ' + testId} {...restProps} style={style}>
<div className={lettersClass}>{letters.toUpperCase()}</div>
</div>
);
@@ -8,10 +8,13 @@ export const Checkbox = (props: {
value?: boolean;
className?: string;
disabled?: boolean;
testClassId?: string;
}) => {
const renderSwitch = () => {
const className = props.className || '';
const testId = props.testClassId ? `testid:${props.testClassId}` : '';
return (
<div
className={
@@ -22,7 +25,8 @@ export const Checkbox = (props: {
' ' +
(props.disabled ? 'opacity-50' : 'cursor-pointer') +
' ' +
(className || '')
(className || '') + ' ' +
testId
}
onClick={() =>
!props.label && !props.disabled && props.onChange && props.onChange(!props.value)
@@ -1,7 +1,7 @@
export const Loader = (props: { className?: string }) => {
return (
<svg
className={'animate-spin text-gray-400 inline ' + (props.className || '')}
className={'animate-spin text-gray-400 inline ' + (props.className || '') + ' testid:loader'}
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
@@ -30,7 +30,7 @@ export const ConfirmModal = (props: ConfirmModalProps) => {
};
}
return <>
<Modal open={props.open} onClose={dialogCloseHandler()}>
<Modal className="testid:confirm-modal" open={props.open} onClose={dialogCloseHandler()}>
<ModalContent
title={props.title}
text={props.text}
@@ -42,14 +42,14 @@ export const ConfirmModal = (props: ConfirmModalProps) => {
className="ml-2"
theme={props.buttonOkTheme || "danger"}
onClick={dialogCloseHandler(true)}
testClassId="confirm-modal-button-confirm"
testClassId="button-confirm"
>
{Languages.t(props.buttonOkLabel)}
</Button>
<Button
theme='default'
onClick={dialogCloseHandler(false)}
testClassId="confirm-modal-button-cancel"
testClassId="button-cancel"
>
{Languages.t(props.buttonCancelLabel || "general.cancel")}
</Button>
@@ -15,6 +15,7 @@ type PropsType = {
contentColumnStyle?: CSSProperties;
className?: string;
children?: JSX.Element | JSX.Element[];
testClassId?: string;
};
const Banner: FC<PropsType> = ({
@@ -27,6 +28,7 @@ const Banner: FC<PropsType> = ({
style,
contentColumnStyle,
className,
testClassId,
}) => {
const headerStyle = {
height: height ? height : 68,
@@ -34,13 +36,15 @@ const Banner: FC<PropsType> = ({
...style,
};
const testId = testClassId ? `testid:${testClassId}` : ''
return (
<Layout.Header className={`banner-container ${type} ${className || ''}`} style={headerStyle}>
<Layout.Header className={`banner-container ${type} ${className || ''} ${testId}`} style={headerStyle}>
<Row align="middle" justify="space-between" gutter={[0, 0]} style={headerStyle}>
<Col /* ghost column */></Col>
<Col style={contentColumnStyle}>{content || children || ''}</Col>
<Col className="banner-col-icon">
{closable && <X size={16} className="icon" onClick={onClose} />}
{closable && <X size={16} className="icon testid:button-close" onClick={onClose} />}
</Col>
</Row>
</Layout.Header>
@@ -12,19 +12,19 @@ export default () => {
const [{ connected, reconnecting }] = useRecoilState(ConnectedState);
return (
<div className={'connection_indicator ' + (connected === false ? 'visible' : '')}>
<div className={'connection_indicator ' + (connected === false ? 'visible' : '') + ' testid:connection-indicator'}>
{connected === false && reconnecting !== true && (
<div>
<div className="testid:disconnected-status">
<ErrorOutlinedIcon /> <span>{Languages.t('general.connexion_status.disconnected')}</span>
</div>
)}
{connected === false && reconnecting === true && (
<div>
<div className="testid:reconnect-status">
<HourglassEmpty /> <span>{Languages.t('general.connexion_status.connecting')}</span>
</div>
)}
{connected === true && (
<div>
<div className="testid:connected-status">
<CheckCircleIcon /> <span>{Languages.t('general.connexion_status.connected')}</span>
</div>
)}
@@ -76,7 +76,7 @@ export default ({ pendingFileState, pendingFile }: PropsType) => {
maxWidth: isPendingFileStatusPause(pendingFile.status) ? 130 : 160,
verticalAlign: 'middle',
}}
className="testid:pending-file-name"
className="testid:file-name"
>
{capitalize(pendingFile?.originalFile.name)}
</Text>
@@ -100,6 +100,7 @@ export default ({ pendingFileState, pendingFile }: PropsType) => {
{pendingFile?.label ? (
<Row justify="start" align="middle" wrap={false}>
<Text
className="testid:file-label"
ellipsis
style={{
maxWidth: isPendingFileStatusPause(pendingFile.status) ? 130 : 160,
@@ -140,6 +141,7 @@ export default ({ pendingFileState, pendingFile }: PropsType) => {
? Languages.t('general.resume')
: Languages.t('general.pause')
}
className="pending-file-row-tooltip-file-status"
>
<Button
type="link"
@@ -158,7 +160,7 @@ export default ({ pendingFileState, pendingFile }: PropsType) => {
alignItems: 'center',
justifyContent: 'center',
}}
className="testid:pending-file-button-status"
className="testid:button-toggle-tooltip-status"
/>
</Tooltip>
) : (
@@ -187,14 +189,14 @@ export default ({ pendingFileState, pendingFile }: PropsType) => {
>
{!isPendingFileStatusSuccess(pendingFileState.status) &&
!isPendingFileStatusError(pendingFileState.status) ? (
<Tooltip title={Languages.t('general.cancel')} placement="top">
<Tooltip title={Languages.t('general.cancel')} placement="top" className="testid:pending-file-row-tooltip-cancel">
<Button
type="link"
shape="circle"
icon={<Trash2 size={16} color={'var(--black)'} />}
onClick={() => cancelUpload(pendingFileState.id)}
style={{ display: 'flex', alignItems: 'center', justifyContent: 'center' }}
className="testid:pending-file-button-cancel"
className="testid:button-toggle-tooltip-cancel"
/>
</Tooltip>
) : (
@@ -202,7 +204,7 @@ export default ({ pendingFileState, pendingFile }: PropsType) => {
)}
</Col>
</Row>
<div className="file-progress-bar-container testid:pending-file-progress-bar">
<div className="file-progress-bar-container testid:progress-bar">
<Progress
type="line"
className="file-progress-bar"
@@ -49,7 +49,7 @@ export default ({ pendingFilesState, visible }: PropsType) => {
}, [getOnePendingFile, pendingFilesState]);
return pendingFilesState.length > 0 ? (
<Layout className={'pending-files-list-layout ' + (visible ? 'visible' : '')}>
<Layout className={'pending-files-list-layout ' + (visible ? 'visible' : '') + ' testid:pending-file-list'}>
<Header
className={classNames('pending-files-list-header')}
onClick={() => setHiddenPendingFiles(!hiddenPendingFiles)}
@@ -44,6 +44,7 @@ export default () => {
footer={null}
destroyOnClose={true}
width={ModalManager.getPosition()?.size?.width || '700px'}
className={`testid:${ModalManager.getModalTestClassId()}`}
>
{component}
</Modal>
@@ -20,7 +20,7 @@ class ModalManagerService extends Observable {
this.notify();
}
open(component: any, position: any, canClose?: boolean, clearState?: any) {
open(component: any, position: any, canClose?: boolean, clearState?: any, modalTestClassId?: string) {
this.close();
this.mountedComponent = null;
@@ -33,7 +33,7 @@ class ModalManagerService extends Observable {
if (clearState) {
delete this.popupStates[clearState];
}
this.component.push({ component: component, canClose: canClose !== false });
this.component.push({ component: component, canClose: canClose !== false, modalTestClassId });
this.notify();
}, 100);
}
@@ -76,6 +76,9 @@ class ModalManagerService extends Observable {
getComponent() {
return this.component[this.component.length - 1]?.component || '';
}
getModalTestClassId() {
return this.component[this.component.length - 1]?.modalTestClassId || '';
}
}
const ModalManager = ModalManagerService.service;
@@ -57,6 +57,8 @@ const NewVersionComponent = (): JSX.Element => {
size: { width: '600px' },
},
false,
undefined,
'modal-new-version'
);
}
@@ -80,9 +82,10 @@ const NewVersionComponent = (): JSX.Element => {
<Banner
height={32}
type="primary"
testClassId="new-version-banner"
content={
<Row align="middle" gutter={[8, 0]}>
<Col>
<Col className="testid:new-version-text">
<b>{Languages.t('components.newversion.new_version_component.row.part_1')}</b>,{' '}
{Languages.t('components.newversion.new_version_component.row.part_2')}{' '}
<Emojione type="rocket" />
@@ -92,6 +95,7 @@ const NewVersionComponent = (): JSX.Element => {
style={{ color: 'var(--white)' }}
underline
onClick={() => window.location.reload()}
className="testid:button-reload"
>
{Languages.t('components.newversion.new_version_component.link')}
</Typography.Link>
@@ -17,7 +17,7 @@ const NewVersionModal = () => {
</>
}
footer={
<Button type="primary" onClick={onClickBtn}>
<Button type="primary" onClick={onClickBtn} className="testid:button-reload">
{Languages.t('scenes.app.header.disconnected.reload')}
</Button>
}
@@ -38,7 +38,7 @@ const ObjectModal: FC<PropsType> = (props: PropsType) => {
hasSider={false}
style={props.style || {}}
>
<Header className="modal-layout-header" style={props.headerStyle || {}}>
<Header className="modal-layout-header testid:modal-header" style={props.headerStyle || {}}>
<Row justify="space-between" align="middle" className="modal-layout-row" wrap={false}>
{props.titleCenter && <Col style={{ width: 32 }}></Col>}
{props.title && (
@@ -62,7 +62,7 @@ const ObjectModal: FC<PropsType> = (props: PropsType) => {
type="times"
className={`m-icon-small square-button ${
props.headerStyle?.backgroundColor ? 'red' : ''
}`}
} testid:button-close-modal`}
onClick={() => (props?.onClose ? props.onClose() : ModalManager.closeAll())}
/>
</Col>
@@ -71,7 +71,7 @@ const ObjectModal: FC<PropsType> = (props: PropsType) => {
</Header>
{props.children && <Content style={props.contentStyle}>{props.children}</Content>}
{props.footer && (
<Footer className="modal-layout-footer">
<Footer className="modal-layout-footer testid:modal-footer">
{!props.hideFooterDivider && (
<Divider className="y-margin" style={props.footerDividerStyle} />
)}
@@ -69,7 +69,7 @@ export default (props: { driveItem: DriveItem & { user?: UserType }}) => {
theme="outline"
className="w-9 !p-0 flex items-center justify-center ml-2 rounded-full border-none"
onClick={() => onDriveItemDownloadClick(file)}
testClassId="drive-item-button-download"
testClassId="button-download"
>
<DownloadIcon className="text-blue-500 w-6 h-6" />
</Button>
@@ -96,21 +96,21 @@ export const FileResultMedia = (props: {
if (file.is_directory) {
return (
<div className={'relative flex bg-blue-100 rounded-md ' + (props.className || '')}>
<FolderIcon className="w-10 h-10 m-auto text-blue-500" />
<div className={'relative flex bg-blue-100 rounded-md ' + (props.className || '') + ' testid:folder-result-media'}>
<FolderIcon className="w-10 h-10 m-auto text-blue-500 testid:folder-icon" />
</div>
);
}
return (
<div className={'relative flex bg-zinc-200 rounded-md ' + (props.className || '')}>
<div className={'relative flex bg-zinc-200 rounded-md ' + (props.className || '') + ' testid:file-result-media'}>
<Media
size={props.size || 'md'}
url={url}
duration={type === 'video' ? extension : undefined}
/>
{(!['image', 'video'].includes(type) || !url) && (
<DocumentIcon item={file} fileType={type} className={iconClassName} />
<DocumentIcon item={file} fileType={type} className={iconClassName} />
)}
</div>
);
@@ -38,7 +38,7 @@ export const SearchInput = () => {
value={input.query}
className={className}
placeholder={Languages.t('scenes.app.mainview.quick_search_placeholder')}
testClassId="search-input-quick-search"
testClassId="input-quick-search"
/>
)}
/>
@@ -19,7 +19,7 @@ interface UserBlockProps {
export default function UserBlock(props: UserBlockProps) {
return <BaseBlock
className={props.className}
className={props.className + ' testid:user-block'}
suffix={props.suffix}
title_suffix={props.title_suffix}
subtitle_suffix={props.subtitle_suffix}
@@ -29,7 +29,8 @@ export default function UserBlock(props: UserBlockProps) {
avatar={props.user?.thumbnail || ''}
title={props.user ? getFullName(props.user) : '-'}
size="sm"
/>
testClassId="avatar"
/>
}
title={
<>
@@ -40,5 +41,5 @@ export default function UserBlock(props: UserBlockProps) {
subtitle={
<div className='text-sm text-slate-500'>{props.user?.email || ""}</div>
}
/>
/>
}
@@ -10,7 +10,7 @@ import { useDriveUpload } from '@features/drive/hooks/use-drive-upload';
import { DriveItemSelectedList, DriveItemSort } from '@features/drive/state/store';
import { formatBytes } from '@features/drive/utils';
import useRouterCompany from '@features/router/hooks/use-router-company';
import _, { get, set } from 'lodash';
import _ from 'lodash';
import { memo, Suspense, useCallback, useEffect, useRef, useState } from 'react';
import { atomFamily, useRecoilState, useSetRecoilState } from 'recoil';
import { DrivePreview } from '../../viewer/drive-preview';
@@ -232,10 +232,10 @@ export default memo(
inPublicSharing,
};
return isMobile ? (
<DocumentRow {...commonProps} testClassId="browser-document-row" />
<DocumentRow {...commonProps} />
) : (
<Draggable id={index} key={index}>
<DocumentRow {...commonProps} testClassId="browser-document-row" />
<DocumentRow {...commonProps} />
</Draggable>
);
}
@@ -379,7 +379,7 @@ export default memo(
"browser-share-with-me-menu-file-type"
);
}}
testClassId="browser-share-with-me-button-file-type"
testClassId="button-open-menu-file-type"
>
<span>
{filter.mimeType.key && filter.mimeType.key != 'All'
@@ -402,7 +402,7 @@ export default memo(
"browser-share-with-me-menu-people"
);
}}
testClassId="browser-share-with-me-button-people"
testClassId="button-open-menu-people"
>
<span>{Languages.t('scenes.app.shared_with_me.people')}</span>
<ChevronDownIcon className="h-4 w-4 ml-2 -mr-1" />
@@ -422,7 +422,7 @@ export default memo(
"browser-share-with-me-menu-last-modified"
);
}}
testClassId="browser-share-with-me-button-last-modified"
testClassId="button-open-menu-last-modified"
>
<span>
{filter.date.key && filter.date.key != 'All'
@@ -452,7 +452,7 @@ export default memo(
<Menu menu={() => onBuildSortContextMenu()} sortData={sortLabel} testClassId="browser-menu-sorting">
{' '}
<Button theme="outline" className="ml-4 flex flex-row items-center" testClassId="browser-button-sorting">
<Button theme="outline" className="ml-4 flex flex-row items-center" testClassId="button-sorting">
<SortIcon
className={`h-4 w-4 mr-2 -ml-1 ${
sortLabel.order === 'asc' ? 'transform rotate-180' : ''
@@ -467,7 +467,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="browser-button-more">
<Button theme="secondary" className="ml-4 flex flex-row items-center" testClassId="button-more">
<span>
{selectedCount > 1
? `${selectedCount} items`
@@ -495,7 +495,7 @@ export default memo(
onClick={() => uploadItemModal()}
theme="primary"
className="mt-4"
testClassId="browser-button-add-doc"
testClassId="button-add-doc"
>
{Languages.t('scenes.app.drive.add_doc')}
</Button>
@@ -525,7 +525,6 @@ export default memo(
setChecked(_.pickBy({ ...checked, [child.id]: v }, _.identity))
}
onBuildContextMenu={() => onBuildContextMenu(details, child)}
testClassId="browser-folder-row"
/>
</Droppable>
) : (
@@ -9,7 +9,6 @@ export type DriveItemProps = {
checked: boolean;
onClick?: () => void;
onBuildContextMenu: () => Promise<any[]>;
testClassId?: string;
};
export type DriveItemOverlayProps = {
@@ -45,9 +45,10 @@ export const DocumentIcon = (props: {
size="xs"
type="square"
title={metadata.name}
testClassId="avatar"
/>
: props.item?.is_directory
? <FolderIcon className={className + (props.blueiffyFolders || props.blueiffyFolders == null ? ' text-blue-500' : '')} />
: <SpecificFileTypeIcon className={className} />
? <FolderIcon className={className + (props.blueiffyFolders || props.blueiffyFolders == null ? ' text-blue-500' : '') + ' testid:folder-icon'} />
: <SpecificFileTypeIcon className={className + ' testid:specific-file-type-icon'} />
);
};
@@ -31,7 +31,6 @@ export const DocumentRow = ({
checked,
onClick,
onBuildContextMenu,
testClassId,
}: DriveItemProps) => {
const history = useHistory();
const [hover, setHover] = useState(false);
@@ -45,8 +44,6 @@ export const DocumentRow = ({
// history.push(RouterServices.generateRouteFromState({ companyId: company, itemId: item.id }));
};
const testId = testClassId ? `testid:${testClassId}` : '';
return (
<div
className={
@@ -55,7 +52,7 @@ export const DocumentRow = ({
? (notSafe ? 'bg-rose-500' : 'bg-blue-500') + ' bg-opacity-10 hover:bg-opacity-25'
: 'hover:bg-zinc-500 hover:bg-opacity-10 ') +
(className || '') + ' ' +
testId
'testid:document-row'
}
id={`DR-${item.id}`}
onMouseEnter={() => setHover(true)}
@@ -17,12 +17,9 @@ export const FolderRow = ({
checked,
onClick,
onBuildContextMenu,
testClassId,
}: DriveItemProps) => {
const [hover, setHover] = useState(false);
const testId = testClassId ? ` testid:${testClassId}` : '';
return (
<div
className={
@@ -32,7 +29,7 @@ export const FolderRow = ({
? 'bg-blue-500 bg-opacity-10 hover:bg-opacity-25 '
: 'hover:bg-zinc-500 hover:bg-opacity-10 ') +
(className || '') + ' ' +
testId
'testid:folder-row'
}
onMouseEnter={() => setHover(true)}
onMouseLeave={() => setHover(false)}
@@ -133,20 +133,22 @@ const PathItem = ({
const { access: trashAccess } = useDriveItem('trash');
const isInSharedWithMe = viewId === 'shared_with_me';
return (
<div className={`flex items-center ${!first ? 'overflow-hidden' : ''}`}>
<div className={`flex items-center ${!first ? 'overflow-hidden' : ''} testid:header-path-item`}>
<a
href="#"
className={`text-sm font-medium text-gray-700 hover:text-blue-600 dark:text-gray-400 dark:hover:text-white ${!first ? 'overflow-hidden' : ''} testid:header-path-item`}
className={`text-sm font-medium text-gray-700 hover:text-blue-600 dark:text-gray-400 dark:hover:text-white ${!first ? 'overflow-hidden' : ''} testid:item-link`}
onClick={evt => {
evt.preventDefault();
const trashMenuItems = [
{
testClassId: 'my-trash',
type: 'menu',
text: Languages.t('components.header_path.my_trash'),
onClick: () => onClick('trash_' + user?.id, ''),
},
{
testClassId: 'shared-trash',
type: 'menu',
text: Languages.t('components.header_path.shared_trash'),
onClick: () => onClick('trash', ''),
@@ -160,7 +162,13 @@ const PathItem = ({
if (first && user?.id) {
if (viewId?.includes('trash')) {
MenusManager.openMenu(trashMenuItems, { x: evt.clientX, y: evt.clientY }, 'center');
MenusManager.openMenu(
trashMenuItems,
{ x: evt.clientX, y: evt.clientY },
'center',
undefined,
'menu-trash'
);
} else {
if (viewId === 'root') {
onClick('root', '');
@@ -71,7 +71,7 @@ const ConfirmDeleteModalContent = ({ items }: { items: DriveItem[] }) => {
setSelected({});
setState({ ...state, open: false });
}}
testClassId="confirm-delete-modal-button-delete"
testClassId="button-delete"
>
Delete
</Button>
@@ -52,7 +52,7 @@ const ConfirmModalContent = () => {
theme="primary"
className="float-right"
onClick={handleClose}
testClassId="confirm-modal-button-move"
testClassId="button-move"
>
<>{Languages.t('components.SelectorModalContent_move_to')} '{selected[0]?.name}'</>
</Button>
@@ -68,7 +68,7 @@ export const ConfirmModal = () => {
};
return (
<Modal className="testid:confirm-modal" open={state.open} onClose={handleClose}>
<Modal className="testid:confirm-move-modal" open={state.open} onClose={handleClose}>
<ConfirmModalContent key={state.parent_id} />
</Modal>
);
@@ -74,7 +74,7 @@ const ConfirmTrashModalContent = ({ items }: { items: DriveItem[] }) => {
await refresh("trash");
setState({ ...state, open: false });
}}
testClassId="cofirm-trash-modal-button-remove"
testClassId="button-remove"
>
{Languages.t('components.ConfirmTrashModalContent_move_to_trash')}
</Button>
@@ -19,7 +19,8 @@ export const AccessLevel = ({
className={
className +
' w-auto ' +
(level === 'none' ? '!text-rose-500 !bg-rose-100 dark-bg-rose-800' : '')
(level === 'none' ? '!text-rose-500 !bg-rose-100 dark-bg-rose-800' : '') +
' testid:select-access-level'
}
value={level || 'read'}
onChange={e => onChange(e.target.value as DriveFileAccessLevel & 'remove')}
@@ -27,7 +27,7 @@ export const UsersModal = () => {
const [state, setState] = useRecoilState(UsersModalAtom);
const userList = useUserCompanyList();
return (
<Modal open={state.open} onClose={() => setState({ open: false })}>
<Modal className="testid:manage-users-modal" open={state.open} onClose={() => setState({ open: false })}>
<Base className="block mt-4 mb-1">
{Languages.t('components.internal-manage_root_users')}
</Base>
@@ -59,15 +59,16 @@ const UserAccessLevel = ({
//const level = role == "admin" ? "manage" : "read";
return (
<div className="p-4 border-t flex flex-row items-center justify-center">
<div className="p-4 border-t flex flex-row items-center justify-center testid:user-access-level">
<div className="shrink-0">
<Avatar
avatar={user?.thumbnail || ''}
title={!user ? '-' : currentUserService.getFullName(user)}
size="sm"
testClassId="avatar"
/>
</div>
<div className="grow ml-2">
<div className="grow ml-2 testid:username">
<Base>{username} </Base>{' '}
{user?.id === currentUser?.id && (
<Info>{Languages.t('components.internal-access_specific_rules_you')}</Info>
@@ -105,7 +105,7 @@ const PropertiesModalContent = ({ id, onClose, inPublicSharing }: { id: string;
}
}}
placeholder={Languages.t('components.PropertiesModalContent_place_holder')}
testClassId="properties-modal-input-update-name"
testClassId="input-update-name"
/>
}
/>
@@ -116,7 +116,7 @@ const PropertiesModalContent = ({ id, onClose, inPublicSharing }: { id: string;
theme="primary"
loading={loading}
onClick={doSave}
testClassId="properties-modal-button-update-name"
testClassId="button-update-name"
>
{Languages.t('components.PropertiesModalContent_update_button')}
</Button>
@@ -81,7 +81,7 @@ export const ExpiryEditorRow = (props: {
return <>
<BaseBlock
className={"m-4" + (disabled ? Styles.Disabled.Yes : "")}
className={"m-4" + (disabled ? Styles.Disabled.Yes : "") + ' testid:expiry-editor-row'}
disabled={disabled}
avatar={<CalendarIcon className={Styles.SmallIconClasses} />}
title={
@@ -90,7 +90,7 @@ export const ExpiryEditorRow = (props: {
{!!props.value && !isEditing &&
<>
<a
className={disabled ? Styles.Disabled.Yes : ""}
className={(disabled ? Styles.Disabled.Yes : "") + ' testid:button-edit'}
onClick={() => {
if (!disabled) {
setCurrentEditedValue(props.value);
@@ -130,7 +130,7 @@ export const ExpiryEditorRow = (props: {
else if (e.key == 'Enter')
confirmSaveExpiry(currentEditedValue);
}}
testClassId="expiry-editor-row-expired-date"
testClassId="input-expired-date"
/>
<Button
disabled={disabled}
@@ -138,7 +138,7 @@ export const ExpiryEditorRow = (props: {
size="sm"
className="max-w-xs mr-2 mt-1"
onClick={() => confirmSaveExpiry(currentEditedValue)}
testClassId="expiry-editor-row-button-confirm"
testClassId="button-confirm"
>
{Languages.t('components.public-link-security_field_confirm_edit')}
</Button>
@@ -155,7 +155,7 @@ export const ExpiryEditorRow = (props: {
} else
confirmSaveExpiry(0);
}}
testClassId="expiry-editor-row-checkbox"
testClassId="checkbox"
/>
}
/>
@@ -79,7 +79,7 @@ const ChangePublicLinkAccessLevelRow = (props: {
level={props.level}
hiddenLevels={['remove']}
onChange={props.onChange}
testClassId="public-link-access-level-dropdown"
testClassId="level-dropdown"
/>
}
/>
@@ -103,7 +103,7 @@ const SwitchToAdvancedSettingsRow = (props: {
if (!props.disabled)
props.onShowAdvancedScreen(true);
}}
testClassId="public-link-access-advance-switcher"
testClassId="advance-switcher"
>
{Languages.t("components.public-link-security-change")}
</A>
@@ -75,7 +75,7 @@ export const PasswordEditorRow = (props: {
return <>
<BaseBlock
className={"m-4" + (disabled ? Styles.Disabled.Yes : "")}
className={"m-4" + (disabled ? Styles.Disabled.Yes : "") + ' testid:password-editor-row'}
disabled={disabled}
avatar={<ShieldCheckIcon className={Styles.SmallIconClasses} />}
title={
@@ -83,7 +83,7 @@ return <>
<label htmlFor={chkPasswordId}>{Languages.t('components.public-link-security_password')}</label>
{!!props.password?.length && !isEditingPassword &&
<a
className={disabled ? Styles.Disabled.Yes : "!text-zinc-800"}
className={(disabled ? Styles.Disabled.Yes : "!text-zinc-800") + ' testid:button-edit'}
onClick={() => {
if (!disabled) {
setCurrentEditedPassword(props.password!);
@@ -112,7 +112,7 @@ return <>
else if (e.key == 'Enter')
confirmSavePassword(currentEditedPassword);
}}
testClassId="pasword-editor-row-editting-password"
testClassId="input-edit-password"
/>
<Button
disabled={disabled}
@@ -120,7 +120,7 @@ return <>
size="sm"
className="max-w-xs mr-2 mt-1"
onClick={() => confirmSavePassword(currentEditedPassword)}
testClassId="password-editor-row-button-confirm"
testClassId="button-confirm"
>
{Languages.t('components.public-link-security_field_confirm_edit')}
</Button>
@@ -137,7 +137,7 @@ return <>
} else
confirmSavePassword("");
}}
testClassId="password-editor-row-checkbox"
testClassId="checkbox"
/>
}
/>
@@ -32,7 +32,7 @@ export const SelectorModal = () => {
const [state, setState] = useRecoilState(SelectorModalAtom);
return (
<Modal open={state.open} onClose={() => setState({ ...state, open: false })}>
<Modal className="testid:modal-selector" open={state.open} onClose={() => setState({ ...state, open: false })}>
<SelectorModalContent key={state.parent_id} showfiles={false}/>
</Modal>
);
@@ -78,7 +78,8 @@ const SelectorModalContent = (key: any) => {
key={folder.id}
className={
'flex flex-row items-center border-t -mt-px px-4 py-2 cursor-pointer ' +
'hover:bg-zinc-500 hover:bg-opacity-10 '
'hover:bg-zinc-500 hover:bg-opacity-10 ' +
'testid:folder'
}
onClick={() => {
setParentId(folder.id);
@@ -93,35 +94,36 @@ const SelectorModalContent = (key: any) => {
{key.showfiles && (
<>
{files.map(file => (
<div
key={file.id}
className={
'flex flex-row items-center border-t -mt-px px-4 py-2 cursor-pointer ' +
'hover:bg-zinc-500 hover:bg-opacity-10 '
}
onClick={() => {
if (state.mode === 'select-files') {
if (!selected.some(i => i.id === file.id)) {
setSelected([...selected, file]);
} else {
setSelected(selected.filter(i => i.id !== file.id));
{files.map(file => (
<div
key={file.id}
className={
'flex flex-row items-center border-t -mt-px px-4 py-2 cursor-pointer ' +
'hover:bg-zinc-500 hover:bg-opacity-10 ' +
'testid:file'
}
} else if (state.mode === 'select-file') {
setSelected([file]);
}
}}
>
<div className="grow flex flex-row items-center dark:text-white">
<DocumentIcon className="h-5 w-5 shrink-0 text-gray-400 mr-2" />
{file.name}
</div>
{(state.mode === 'select-file' || state.mode === 'select-files') && (
<div className="shrink-0" onClick={e => e.stopPropagation()}>
<Checkbox value={selected.some(i => i.id === file.id)} />
onClick={() => {
if (state.mode === 'select-files') {
if (!selected.some(i => i.id === file.id)) {
setSelected([...selected, file]);
} else {
setSelected(selected.filter(i => i.id !== file.id));
}
} else if (state.mode === 'select-file') {
setSelected([file]);
}
}}
>
<div className="grow flex flex-row items-center dark:text-white">
<DocumentIcon className="h-5 w-5 shrink-0 text-gray-400 mr-2" />
{file.name}
</div>
{(state.mode === 'select-file' || state.mode === 'select-files') && (
<div className="shrink-0" onClick={e => e.stopPropagation()}>
<Checkbox value={selected.some(i => i.id === file.id)} testClassId="checkbox-select-file" />
</div>
)}
</div>
)}
</div>
))}
</>
)}
@@ -138,7 +140,7 @@ const SelectorModalContent = (key: any) => {
setState({ ...state, open: false });
setLoading(false);
}}
testClassId="selector-modal-button"
testClassId="button-select"
>
{selected.length === 0 ? (
<>{Languages.t('components.SelectorModalContent_no_items')}</>
@@ -145,7 +145,7 @@ export const InternalUsersAccessManager = ({
onAddSearchResult={(userId) => {
item && update(changeUserAccess(item, userId, level));
}}
/>
/>
)}
{!loading && resultFooterText && <>
<div className={(result.length == 0 ? 'rounded-md' : 'rounded-b-md') + ' grow text-center text-zinc-700 dark:text-white dark:opacity-75 py-2 dark:border-zinc-700 border-t bg-zinc-100 dark:bg-zinc-900'}>
@@ -163,8 +163,8 @@ export const InternalUsersAccessManager = ({
userId={user?.id}
disabled={disabled}
className={(showResults ? '!rounded-none' : '') + (index === usersWithAccess.length - 1 ? ' !rounded-b-md border-y' : ' border-t')}
/>
)}
/>
)}
{(usersWithAccess?.length ?? 0) < minUserHeight &&
[...Array(minUserHeight - (usersWithAccess?.length ?? 0))].map((_, i) =>
<div key={i} className="p-4 flex flex-row">
@@ -181,7 +181,7 @@ export const InternalUsersAccessManager = ({
size="sm"
className='text-center'
onClick={onCloseModal}
testClassId="public-link-button-confirm-edit"
testClassId="button-confirm-edit"
>
{Languages.t('components.public-link-security_field_confirm_edit')}
</Button>
@@ -212,7 +212,7 @@ const UserAccessLevel = (props: {
? <Button
disabled={loading || props.disabled || user?.id === currentUser?.id}
size="sm"
testClassId={`user-access-button-${props.isSearchResultAdd}`}
testClassId="button-grant-access"
>
{Languages.t('components.user_picker.modal.result_add.' + props.isSearchResultAdd)}
</Button>
@@ -69,20 +69,20 @@ export const UploadModal = ({
as="div"
{...(!state.type ? slideXTransitionReverted : slideXTransition)}
>
<div className="-m-2" >
<CreateModalOption
icon={<DocumentDownloadIcon className="w-5 h-5" />}
text={Languages.t('components.create_modal.upload_files')}
onClick={() => selectFromDevice()}
testClassId="upload-file-from-device"
/>
<CreateModalOption
icon={<FolderDownloadIcon className="w-5 h-5" />}
text={Languages.t('components.create_modal.upload_folders')}
onClick={() => selectFolderFromDevice()}
testClassId="upload-folder-from-device"
/>
</div>
<div className="-m-2" >
<CreateModalOption
icon={<DocumentDownloadIcon className="w-5 h-5" />}
text={Languages.t('components.create_modal.upload_files')}
onClick={() => selectFromDevice()}
testClassId="upload-file-from-device"
/>
<CreateModalOption
icon={<FolderDownloadIcon className="w-5 h-5" />}
text={Languages.t('components.create_modal.upload_folders')}
onClick={() => selectFolderFromDevice()}
testClassId="upload-folder-from-device"
/>
</div>
</Transition>
</div>
</ModalContent>
@@ -64,7 +64,7 @@ const VersionModalContent = ({ id }: { id: string }) => {
await uploadVersion(file);
await refresh(id);
}}
testClassId="version-modal-upload-zone"
testClassId="upload-zone"
>
{access !== 'read' && (
<div
@@ -29,7 +29,7 @@ export const SharedFilesTable = () => {
return formattedDate;
};
return (
<div className="testid:shared-file-table">
<div className="testid:shared-file">
<Title className="mb-4 block">{Languages.t('scenes.app.shared_with_me.shared_with_me')}</Title>
{/* Filters */}
<div className="flex items-center space-x-4 mb-6">
@@ -42,8 +42,11 @@ export const SharedFilesTable = () => {
buildFileTypeContextMenu(),
{ x: evt.clientX, y: evt.clientY },
'center',
undefined,
'shared-file-menu-file-types'
);
}}
testClassId="button-open-menu-file-types"
>
<span>{filter.mimeType ? filter.mimeType : Languages.t('scenes.app.shared_with_me.file_type')}</span>
<ChevronDownIcon className="h-4 w-4 ml-2 -mr-1" />
@@ -58,8 +61,11 @@ export const SharedFilesTable = () => {
buildPeopleContextMen(),
{ x: evt.clientX, y: evt.clientY },
'center',
undefined,
'shared-file-menu-people'
);
}}
testClassId="button-open-menu-people"
>
<span>{Languages.t('scenes.app.shared_with_me.people')}</span>
<ChevronDownIcon className="h-4 w-4 ml-2 -mr-1" />
@@ -75,8 +81,11 @@ export const SharedFilesTable = () => {
buildDateContextMenu(),
{ x: evt.clientX, y: evt.clientY },
'center',
undefined,
'shared-file-menu-last-modified'
);
}}
testClassId="button-open-menu-last-modified"
>
<span>{Languages.t('scenes.app.shared_with_me.last_modified')}</span>
<ChevronDownIcon className="h-4 w-4 ml-2 -mr-1" />
@@ -85,7 +94,7 @@ export const SharedFilesTable = () => {
</div>
<Title className="mb-4 block">{Languages.t('scenes.app.drive.documents')}:</Title>
<div className="relative overflow-x-auto shadow-md sm:rounded-lg">
<table className="w-full text-sm text-left text-gray-500 dark:text-gray-400">
<table className="w-full text-sm text-left text-gray-500 dark:text-gray-400 testid:shared-file-table">
<thead className="text-xs text-gray-700 uppercase bg-gray-50 dark:bg-blue-500 dark:text-white">
<tr>
<th scope="col" className="px-6 py-3">
@@ -107,7 +116,7 @@ export const SharedFilesTable = () => {
driveItems.map((file: any, index: any) => (
<tr
key={index}
className="bg-white border-b dark:bg-gray-800 dark:border-gray-700 hover:bg-gray-50 dark:hover:bg-gray-600"
className="bg-white border-b dark:bg-gray-800 dark:border-gray-700 hover:bg-gray-50 dark:hover:bg-gray-600 testid:table-row"
>
<th
scope="row"
@@ -65,18 +65,18 @@ export default () => {
return (
<FeatureToggles features={activeFeatureNames}>
<>
<div className="flex flex-col h-full w-full dark:bg-zinc-900">
<div className="flex flex-col h-full w-full dark:bg-zinc-900 testid:shared-view">
<div className="flex flex-row items-center justify-center bg-blue-500 px-4 py-2">
<div className="grow flex flex-row items-center">
{group.logo && (
<Avatar avatar={group.logo} className="inline-block mr-3" size="sm" type="square" testClassId="shared-view-avatar" />
<Avatar avatar={group.logo} className="inline-block mr-3" size="sm" type="square" testClassId="avatar" />
)}
<span className="text-white font-semibold" style={{ lineHeight: '32px' }}>
Twake Drive
</span>
</div>
<div className="shrink-0">
<a href="https://twake.app" target="_BLANK" rel="noreferrer" className="!text-white">
<a href="https://twake.app" target="_BLANK" rel="noreferrer" className="!text-white testid:create-account-link">
<span className="nomobile text-white">
{Languages.t('scenes.app.mainview.create_account')}
</span>
@@ -145,7 +145,7 @@ const AccessChecker = ({
if ((!details?.item?.id && !loading) || accessGranted === false) {
return (
<div className="text-center">
<div className="text-center testid:access-checker">
<div style={{ height: '20vh' }} />
<div className="inline-block text-left max-w-sm margin-auto bg-zinc-50 dark:bg-zinc-900 rounded-md p-4">
<Title>You don't have access to this document or folder.</Title>
@@ -162,7 +162,7 @@ const AccessChecker = ({
className="-mr-px rounded-r-none border-r-none"
value={password}
onChange={e => setPassword(e.target.value)}
testClassId="access-checker-input-password"
testClassId="input-password"
/>
<Button
className="rounded-l-none"
@@ -171,7 +171,7 @@ const AccessChecker = ({
await setPublicToken(token || '', password);
await refresh(folderId);
}}
testClassId="access-checker-button-submit"
testClassId="button-submit"
>
Submit
</Button>
@@ -59,6 +59,7 @@ export default (): JSX.Element => {
},
},
]}
testClassId="menu-account"
>
<Avatar
size="md"
@@ -41,6 +41,7 @@ export default ({ className }: { className?: string }): JSX.Element => {
),
},
]}
testClassId="menu-apps"
>
<Button
theme="default"
@@ -25,16 +25,16 @@ export default (): JSX.Element => {
return (
<>
<div className="w-full max-w-lg">
<div className="w-full max-w-lg testid:header-search">
<InputDecorationIcon
prefix={() => (
<SearchIcon className={'h-5 w-5 absolute m-auto top-0 bottom-0 left-3 text-blue-500'} />
)}
suffix={() =>
<XIcon
className={'h-4 w-4 absolute m-auto top-0 bottom-0 right-3 cursor-pointer text-zinc-500 ' + (searchState.query?.length ? '' : 'hidden')}
className={'h-4 w-4 absolute m-auto top-0 bottom-0 right-3 cursor-pointer text-zinc-500 ' + (searchState.query?.length ? '' : 'hidden') + ' testid:button-clear'}
onClick={() => setSearchState({ ...searchState, query: '' }) }
/>
/>
}
input={({ className }) => (
<Input
@@ -44,7 +44,7 @@ export default (): JSX.Element => {
readOnly
placeholder={Languages.t('scenes.client.main_view.main_header.search_input')}
onClick={() => setOpen()}
testClassId="header-search-input"
testClassId="input-search"
/>
)}
/>
@@ -8,7 +8,7 @@ import version from '../../../environment/version';
export default ({ openSideMenu }: { openSideMenu: () => void }) => {
return (
<div
className="bg-white dark:bg-zinc-900 h-16 sm:h-20 p-4 sm:p-6 flex space-between items-center"
className="bg-white dark:bg-zinc-900 h-16 sm:h-20 p-4 sm:p-6 flex space-between items-center testid:header"
style={{
paddingLeft: '1.875rem',
paddingRight: '1.875rem',
@@ -28,14 +28,14 @@ export default ({ openSideMenu }: { openSideMenu: () => void }) => {
/>
</div>
<div className="sm:inline-grid pl-3">
<Info className="font-bold overflow-hidden text-ellipsis whitespace-nowrap w-full block -mb-1">
<Info className="font-bold overflow-hidden text-ellipsis whitespace-nowrap w-full block -mb-1 testid:version">
&nbsp;v{version.version}
</Info>
</div>
</div>
<div
onClick={() => openSideMenu()}
className="sm:hidden block shrink-0 w-10 hover:text-zinc-600 text-zinc-500 cursor-pointer -mx-2 px-2"
className="sm:hidden block shrink-0 w-10 hover:text-zinc-600 text-zinc-500 cursor-pointer -mx-2 px-2 testid:button-open-side-menu"
>
<MenuIcon className="w-6 h-6" />
</div>
@@ -38,7 +38,7 @@ export default React.memo((): JSX.Element => {
if (user?.id) {
page = (
<DesktopRedirect>
<div className="fade_in bg-zinc-100 dark:bg-black flex flex-col gap-2 h-full">
<div className="fade_in bg-zinc-100 dark:bg-black flex flex-col gap-2 h-full testid:header">
<DownloadAppBanner/>
<NewVersionComponent />
@@ -79,18 +79,18 @@ export const CreateModalWithUploadZones = ({ initialParentId }: { initialParentI
parentId,
});
}}
/>
<UploadModal
/>
<UploadModal
selectFolderFromDevice={() => uploadFolderZoneRef.current?.open()}
selectFromDevice={() => uploadZoneRef.current?.open()}
addFromUrl={(url, name) => {
setUploadModalState({ parent_id: '', open: false });
uploadFromUrl(url, name, {
companyId,
parentId,
});
setUploadModalState({ parent_id: '', open: false });
uploadFromUrl(url, name, {
companyId,
parentId,
});
}}
/>
/>
</>
);
};
@@ -119,7 +119,7 @@ export default () => {
}, [item?.id, setUploadModalState]);
return (
<div className="-m-4 overflow-hidden">
<div className="-m-4 overflow-hidden testid:sidebar-actions">
<AnimatedHeight>
<div className="p-4">
<CreateModalWithUploadZones initialParentId={parentId} />
@@ -170,7 +170,7 @@ export default () => {
theme="primary"
className="w-full mb-2 justify-center"
style={{ boxShadow: '0 0 10px 0 rgba(0, 122, 255, 0.5)' }}
testClassId="sidebar-action-button-upload"
testClassId="button-upload"
>
<UploadIcon className="w-5 h-5 mr-2" /> {Languages.t('components.side_menu.buttons.upload')}
</Button>
@@ -179,7 +179,7 @@ export default () => {
size="lg"
theme="secondary"
className="w-full mb-2 justify-center"
testClassId="sidebar-action-button-open-create-modal"
testClassId="button-open-create-modal"
>
<PlusIcon className="w-5 h-5 mr-2" /> {Languages.t('components.side_menu.buttons.create')}
</Button>
@@ -48,7 +48,7 @@ export default () => {
dirId && viewId && setParentId(dirId);
}, [viewId, itemId, dirId]);
return (
<div className="grow flex flex-col overflow-auto -m-4 p-4 relative">
<div className="grow flex flex-col overflow-auto -m-4 p-4 relative testid:sidebar">
<div className="grow">
<div className="sm:hidden block mb-2">
<div className="flex flex-row space-between w-full">
@@ -4,12 +4,12 @@ import Languages from '@features/global/services/languages-service';
export default (props: { download: string; name: string }) => {
return (
<>
<div className="text-white m-auto w-full text-center block h-full flex items-center">
<div className="text-white m-auto w-full text-center block h-full flex items-center testid:archive-display">
<span className="block w-full text-center mt-16">
{props.name}
<br />
<br />
<Button theme="dark">{Languages.t('scenes.apps.drive.download_button')}</Button>
<Button theme="dark" testClassId="button-download">{Languages.t('scenes.apps.drive.download_button')}</Button>
</span>
</div>
</>
@@ -9,7 +9,7 @@ export default (props: { download: string; name: string }) => {
return (
<>
<iframe
className="w-full h-full left-0 right-0 absolute bottom-0 top-0"
className="w-full h-full left-0 right-0 absolute bottom-0 top-0 testid:code-display"
title={props.name}
src={url}
/>
@@ -45,7 +45,7 @@ export default () => {
}
return (
<div className="text-white m-auto w-full text-center block h-full flex items-center">
<div className="text-white m-auto w-full text-center block h-full flex items-center testid:cannot-display">
<span className="block w-full text-center">We can't display this document.</span>
</div>
);
@@ -35,7 +35,7 @@ export default ({ download, loading, setLoading}: PropsType) => {
return (
<TransformComponent wrapperClass="absolute w-full h-full top-0 left-0 right-0 bottom-0">
<img
className="object-contain"
className="object-contain testid:image-display"
style={{
transform: `rotate(${rotated}deg)`,
transition: 'transform 200ms',
@@ -13,7 +13,7 @@ export default (props: { download: string; name: string; id: string }) => {
if (!(props.id && previewUrl)) {
return (
<>
<div className="text-white m-auto w-full text-center block h-full flex items-center">
<div className="text-white m-auto w-full text-center block h-full flex items-center testid:cannot-display">
<span className="block w-full text-center">We can't display this document.</span>
</div>
</>
@@ -24,7 +24,7 @@ export default (props: { download: string; name: string; id: string }) => {
<>
{props.id && previewUrl && (
<iframe
className="w-full h-full left-0 right-0 absolute bottom-0 top-0"
className="w-full h-full left-0 right-0 absolute bottom-0 top-0 testid:preview-url"
title={props.name}
src={previewUrl}
/>
@@ -4,7 +4,7 @@ export default (props: { download: string; name: string }) => {
return (
<>
<iframe
className="w-full h-full left-0 right-0 absolute bottom-0 top-0"
className="w-full h-full left-0 right-0 absolute bottom-0 top-0 testid:pdf-display"
title={props.name}
src={url}
/>
@@ -4,7 +4,7 @@ export default (props: { download: string }) => {
return (
<ReactPlayer
url={props.download}
className="max-w-full max-h-full m-auto absolute left-0 top-0 bottom-0 right-0"
className="max-w-full max-h-full m-auto absolute left-0 top-0 bottom-0 right-0 testid:video-display"
controls
/>
);
@@ -42,7 +42,7 @@ export default () => {
<Modal
open={isOpen}
closable={false}
className="bg-black bg-opacity-50 !sm:max-w-none !w-full !rounded-none !p-0"
className="bg-black bg-opacity-50 !sm:max-w-none !w-full !rounded-none !p-0 testid:modal-viewer"
style={{ maxWidth: 'none', margin: 0, left: 0, top: 0, height: '100vh' }}
positioned={false}
>
@@ -92,7 +92,7 @@ const Navigation = () => {
return (
<>
<XIcon
className="z-10 cursor-pointer absolute right-5 top-5 w-12 h-12 text-zinc-300 hover:text-white rounded-full p-1 hover:bg-black hover:bg-opacity-25"
className="z-10 cursor-pointer absolute right-5 top-5 w-12 h-12 text-zinc-300 hover:text-white rounded-full p-1 hover:bg-black hover:bg-opacity-25 testid:button-close"
onClick={() => close()}
/>
@@ -103,7 +103,7 @@ const Navigation = () => {
{...fadeZoomTransition}
>
<ChevronLeftIcon
className="cursor-pointer w-10 h-10 text-zinc-300 hover:text-white"
className="cursor-pointer w-10 h-10 text-zinc-300 hover:text-white testid:button-previous"
onClick={() => previous()}
/>
</Transition>
@@ -115,7 +115,7 @@ const Navigation = () => {
{...fadeZoomTransition}
>
<ChevronRightIcon
className="cursor-pointer w-10 h-10 text-zinc-300 hover:text-white"
className="cursor-pointer w-10 h-10 text-zinc-300 hover:text-white testid:button-next"
onClick={() => next()}
/>
</Transition>
@@ -133,18 +133,19 @@ const Footer = () => {
return (
<>
<div className="z-10 p-5 bg-black w-full flex text-white">
<div className="z-10 p-5 bg-black w-full flex text-white testid:footer">
<div className="mr-4 w-12">
<Avatar
title={currentUserService.getFullName(user)}
src={currentUserService.getThumbnail(user)}
testClassId="avatar"
/>
</div>
<div className="grow overflow-hidden text-ellipsis">
<Text.Base noColor className="w-full block text-white whitespace-nowrap">
<Text.Base noColor className="w-full block text-white whitespace-nowrap testid:text-name">
{name}
</Text.Base>
<Text.Info className="whitespace-nowrap">
<Text.Info className="whitespace-nowrap testid:file-info">
{currentUserService.getFullName(user)} {extension?.toLocaleUpperCase()},{' '}
{formatSize(status.details?.metadata?.size)}
</Text.Info>
@@ -162,6 +163,7 @@ const Footer = () => {
onClick={() => {
download && (window.location.href = download);
}}
testClassId="button-download"
/>
</div>
</div>