Add more test id to elements based on test case e2e

This commit is contained in:
lethemanh
2024-12-10 21:59:55 +07:00
parent 217e683269
commit 86e3661508
36 changed files with 128 additions and 55 deletions
@@ -13,6 +13,7 @@ interface AvatarProps extends React.InputHTMLAttributes<HTMLInputElement> {
icon?: JSX.Element | false; icon?: JSX.Element | false;
title?: string; title?: string;
nogradient?: boolean; nogradient?: boolean;
testClassId?: string;
} }
const sizes = { xl: 24, lg: 14, md: 10, sm: 9, xs: 6 }; const sizes = { xl: 24, lg: 14, md: 10, sm: 9, xs: 6 };
@@ -68,12 +69,13 @@ export default function Avatar(props: AvatarProps) {
className += ' '; className += ' ';
return ( return (
<div <div
{...restProps} {..._.omit(restProps, 'testClassId')}
style={style} style={style}
className={ className={
className + className +
' text-white overflow-hidden flex items-center justify-center ' + ' text-white overflow-hidden flex items-center justify-center ' +
addedClassName addedClassName + ' ' +
(props.testClassId ? `testid:${props.testClassId}` : '')
} }
> >
{props.icon} {props.icon}
@@ -83,18 +85,18 @@ export default function Avatar(props: AvatarProps) {
if (props.avatar) { if (props.avatar) {
return ( return (
<div {...restProps}> <div {..._.omit(restProps, 'testClassId')}>
<img <img
alt={props.title} alt={props.title}
src={props.avatar} src={props.avatar}
className={className + ' object-cover ' + addedClassName} className={className + ' object-cover ' + addedClassName + ' ' + (props.testClassId ? `testid:${props.testClassId}` : '')}
/> />
</div> </div>
); );
} }
return ( return (
<div className={className + ' ' + addedClassName} {...restProps} style={style}> <div className={className + ' ' + addedClassName + ' ' + (props.testClassId ? `testid:${props.testClassId}` : '')} {..._.omit(restProps, 'testClassId')} style={style}>
<div className={lettersClass}>{letters.toUpperCase()}</div> <div className={lettersClass}>{letters.toUpperCase()}</div>
</div> </div>
); );
@@ -59,6 +59,8 @@ export const Button = (props: ButtonProps) => {
else className = className + ' w-9 !p-0 justify-center'; else className = className + ' w-9 !p-0 justify-center';
} }
const testId = props.testClassId ? `testid:${props.testClassId}` : '';
return ( return (
<button <button
type="button" type="button"
@@ -68,7 +70,7 @@ export const Button = (props: ButtonProps) => {
' ' + ' ' +
props.className + props.className +
' ' + ' ' +
`testid:${props.testClassId}` testId
} }
disabled={disabled} disabled={disabled}
{..._.omit(props, 'loading', 'children', 'className', 'icon', 'iconSize', 'testClassId')} {..._.omit(props, 'loading', 'children', 'className', 'icon', 'iconSize', 'testClassId')}
@@ -24,10 +24,9 @@ export const CheckboxSlider = (props: CheckboxSliderProps) => {
// @author https://tw-elements.com/docs/react/forms/switch/ // @author https://tw-elements.com/docs/react/forms/switch/
className={[ className={[
"!bg-none mr-2 mt-[0.3rem] h-7 w-14 appearance-none rounded-[0.9rem] bg-neutral-300 before:pointer-events-none before:absolute before:h-7 before:w-5 before:rounded-full before:bg-transparent before:content-[''] after:absolute after:z-[2] after:mt-[0.2rem] after:ml-[0.2rem] after:h-5 after:w-5 after:rounded-full after:border-none after:bg-neutral-100 after:shadow-[0_0px_3px_0_rgb(0_0_0_/_7%),_0_2px_2px_0_rgb(0_0_0_/_4%)] after:transition-[background-color_0.2s,transform_0.2s] after:content-[''] checked:bg-primary checked:after:absolute checked:after:z-[2] checked:after:ml-[1.9625rem] checked:after:w-5 checked:after:rounded-full checked:after:border-none checked:after:bg-primary checked:after:shadow-[0_3px_1px_-2px_rgba(0,0,0,0.2),_0_2px_2px_0_rgba(0,0,0,0.14),_0_1px_5px_0_rgba(0,0,0,0.12)] checked:after:transition-[background-color_0.2s,transform_0.2s] checked:after:content-[''] hover:cursor-pointer dark:bg-neutral-600 dark:after:bg-white dark:checked:bg-primary dark:checked:after:bg-primary disabled:cursor-default disabled:opacity-25 !focus:shadow-none", "!bg-none mr-2 mt-[0.3rem] h-7 w-14 appearance-none rounded-[0.9rem] bg-neutral-300 before:pointer-events-none before:absolute before:h-7 before:w-5 before:rounded-full before:bg-transparent before:content-[''] after:absolute after:z-[2] after:mt-[0.2rem] after:ml-[0.2rem] after:h-5 after:w-5 after:rounded-full after:border-none after:bg-neutral-100 after:shadow-[0_0px_3px_0_rgb(0_0_0_/_7%),_0_2px_2px_0_rgb(0_0_0_/_4%)] after:transition-[background-color_0.2s,transform_0.2s] after:content-[''] checked:bg-primary checked:after:absolute checked:after:z-[2] checked:after:ml-[1.9625rem] checked:after:w-5 checked:after:rounded-full checked:after:border-none checked:after:bg-primary checked:after:shadow-[0_3px_1px_-2px_rgba(0,0,0,0.2),_0_2px_2px_0_rgba(0,0,0,0.14),_0_1px_5px_0_rgba(0,0,0,0.12)] checked:after:transition-[background-color_0.2s,transform_0.2s] checked:after:content-[''] hover:cursor-pointer dark:bg-neutral-600 dark:after:bg-white dark:checked:bg-primary dark:checked:after:bg-primary disabled:cursor-default disabled:opacity-25 !focus:shadow-none",
`testid:${props.testClassId}` props.testClassId ? `testid:${props.testClassId}` : ''
].join(' ')} ].join(' ')}
checked={!!props.checked} checked={!!props.checked}
disabled={props.disabled} disabled={props.disabled}
data-checkbox-id={props.testClassId}
/>) />)
} }
@@ -60,15 +60,16 @@ export const Input = (props: InputProps) => {
else inputClassName = inputClassName + ' h-9'; else inputClassName = inputClassName + ' h-9';
} }
const testId = props.testClassId ? `testid:${props.testClassId}` : '';
return ( return (
<> <>
{props.inputComponent || {props.inputComponent ||
(props.multiline ? ( (props.multiline ? (
<textarea <textarea
ref={props.inputRef as React.Ref<HTMLTextAreaElement>} ref={props.inputRef as React.Ref<HTMLTextAreaElement>}
className={inputClassName + ' ' + props.inputClassName + ' ' + props.className} className={inputClassName + ' ' + props.inputClassName + ' ' + props.className + ' ' + testId}
{..._.omit(props as any, 'label', 'inputClassName', 'inputRef', 'className', 'value', 'size', 'testClassId')} {..._.omit(props as any, 'label', 'inputClassName', 'inputRef', 'className', 'value', 'size', 'testClassId')}
data-input-id={props.testClassId}
> >
{props.value} {props.value}
</textarea> </textarea>
@@ -76,7 +77,7 @@ export const Input = (props: InputProps) => {
<input <input
ref={props.inputRef as React.Ref<HTMLInputElement>} ref={props.inputRef as React.Ref<HTMLInputElement>}
type="text" type="text"
className={`${inputClassName} ${props.inputClassName} ${props.className} testid:${props.testClassId}`} className={`${inputClassName} ${props.inputClassName} ${props.className} ${props.testClassId ? `testid:${props.testClassId}` : ''}`}
{..._.omit(props, 'label', 'inputClassName', 'inputRef', 'className', 'size', 'testClassId')} {..._.omit(props, 'label', 'inputClassName', 'inputRef', 'className', 'size', 'testClassId')}
/> />
))} ))}
@@ -23,11 +23,14 @@ export default class Button extends React.Component {
) { ) {
className += ' small'; className += ' small';
} }
const testId = this.props.testClassId ? `testid:${this.props.testClassId}` : '';
return ( return (
<button <button
ref={this.props.refButton} ref={this.props.refButton}
{...this.props} {...this.props}
className={'button no-tw ' + className + ` testid:${this.props.testClassId}`} className={'button no-tw ' + className + ' ' + testId}
onClick={evt => { onClick={evt => {
evt.target.blur(); evt.target.blur();
this.props.onClick && this.props.onClick(evt); this.props.onClick && this.props.onClick(evt);
@@ -58,6 +58,7 @@ export default ({ pendingFileState, pendingFile }: PropsType) => {
}} }}
> >
<Row <Row
className="testid:pending-files-row"
justify="space-between" justify="space-between"
align="middle" align="middle"
wrap={false} wrap={false}
@@ -75,6 +76,7 @@ export default ({ pendingFileState, pendingFile }: PropsType) => {
maxWidth: isPendingFileStatusPause(pendingFile.status) ? 130 : 160, maxWidth: isPendingFileStatusPause(pendingFile.status) ? 130 : 160,
verticalAlign: 'middle', verticalAlign: 'middle',
}} }}
className="testid:pending-file-name"
> >
{capitalize(pendingFile?.originalFile.name)} {capitalize(pendingFile?.originalFile.name)}
</Text> </Text>
@@ -156,6 +158,7 @@ export default ({ pendingFileState, pendingFile }: PropsType) => {
alignItems: 'center', alignItems: 'center',
justifyContent: 'center', justifyContent: 'center',
}} }}
className="testid:pending-file-button-status"
/> />
</Tooltip> </Tooltip>
) : ( ) : (
@@ -191,6 +194,7 @@ export default ({ pendingFileState, pendingFile }: PropsType) => {
icon={<Trash2 size={16} color={'var(--black)'} />} icon={<Trash2 size={16} color={'var(--black)'} />}
onClick={() => cancelUpload(pendingFileState.id)} onClick={() => cancelUpload(pendingFileState.id)}
style={{ display: 'flex', alignItems: 'center', justifyContent: 'center' }} style={{ display: 'flex', alignItems: 'center', justifyContent: 'center' }}
className="testid:pending-file-button-cancel"
/> />
</Tooltip> </Tooltip>
) : ( ) : (
@@ -198,7 +202,7 @@ export default ({ pendingFileState, pendingFile }: PropsType) => {
)} )}
</Col> </Col>
</Row> </Row>
<div className="file-progress-bar-container"> <div className="file-progress-bar-container testid:pending-file-progress-bar">
<Progress <Progress
type="line" type="line"
className="file-progress-bar" className="file-progress-bar"
@@ -63,6 +63,8 @@ export default class Input extends Component {
); );
} }
const testId = this.props.testClassId ? `testid:${this.props.testClassId}` : '';
return ( return (
<input <input
ref={node => { ref={node => {
@@ -76,7 +78,7 @@ export default class Input extends Component {
} }
this.onKeyDown(evt); this.onKeyDown(evt);
}} }}
className={'input ' + (className || '') + ` testid:${this.props.testClassId}`} className={'input ' + (className || '') + ' ' + testId}
onBlur={this.props.onBlur} onBlur={this.props.onBlur}
onChange={this.props.onChange} onChange={this.props.onChange}
/> />
@@ -58,7 +58,7 @@ export default class MenuComponent extends React.Component {
ref={node => (this.original_menu = node)} ref={node => (this.original_menu = node)}
className={ className={
'menu-list ' + (this.props.withFrame ? 'as_frame text-black bg-white dark:bg-zinc-900 dark:text-white rounded-lg ' : '') + this.props.animationClass + ' ' + 'menu-list ' + (this.props.withFrame ? 'as_frame text-black bg-white dark:bg-zinc-900 dark:text-white rounded-lg ' : '') + this.props.animationClass + ' ' +
`testid:${this.props.testClassId}` `${this.props.testClassId ? `testid:${this.props.testClassId}` : ''}`
} }
> >
{(this.props.menu || []) {(this.props.menu || [])
@@ -77,7 +77,7 @@ export default class MenuComponent extends React.Component {
<div <div
key={'menu_' + index} key={'menu_' + index}
ref={node => (item.ref = node)} ref={node => (item.ref = node)}
className={'menu-text ' + item.className} className={'menu-text ' + item.className + ' testid:menu-item'}
onMouseEnter={evt => { onMouseEnter={evt => {
this.hoverMenu(item.ref, item); this.hoverMenu(item.ref, item);
}} }}
@@ -87,14 +87,14 @@ export default class MenuComponent extends React.Component {
{typeof item.icon === 'string' ? <Icon type={item.icon} /> : item.icon} {typeof item.icon === 'string' ? <Icon type={item.icon} /> : item.icon}
</div> </div>
)} )}
<div className="text">{item.text}</div> <div className={`text testid:menu-item-${item.id}`}>{item.text}</div>
</div> </div>
); );
} else if (item.type == 'react-element') { } else if (item.type == 'react-element') {
return ( return (
<div <div
key={'menu_' + index} key={'menu_' + index}
className={'menu-custom ' + item.className} className={'menu-custom ' + item.className + ' testid:menu-item'}
onClick={item.onClick} onClick={item.onClick}
> >
{typeof item.reactElement == 'function' {typeof item.reactElement == 'function'
@@ -115,7 +115,8 @@ export default class MenuComponent extends React.Component {
this.last_hovered == item this.last_hovered == item
? 'hovered ' ? 'hovered '
: '') + : '') +
(item.selected ? 'selected ' : '') (item.selected ? 'selected ' : '') +
' testid:menu-item'
} }
onMouseEnter={evt => { onMouseEnter={evt => {
this.hoverMenu(item.ref, item); this.hoverMenu(item.ref, item);
@@ -134,7 +135,7 @@ export default class MenuComponent extends React.Component {
<Emojione type={item.emoji} /> <Emojione type={item.emoji} />
</div> </div>
)} )}
<div className="text">{item.text}</div> <div className={`text testid:menu-item-${item.id}`}>{item.text}</div>
<div className="more"> <div className="more">
{item.rightIcon && <Icon type={item.rightIcon} />} {item.rightIcon && <Icon type={item.rightIcon} />}
{item.submenu && !item.submenu_replace && <Icon type="angle-right" />} {item.submenu && !item.submenu_replace && <Icon type="angle-right" />}
@@ -51,7 +51,7 @@ export default (props: { driveItem: DriveItem & { user?: UserType }}) => {
textToHighlight={name} textToHighlight={name}
/> />
</Text.Base> </Text.Base>
<Text.Info className="block"> <Text.Info className="block testid:drive-item-file">
{extension?.toLocaleUpperCase()} {formatDate(parseInt(file?.last_modified))} {' '} {extension?.toLocaleUpperCase()} {formatDate(parseInt(file?.last_modified))} {' '}
{formatSize(file?.size)} {formatSize(file?.size)}
</Text.Info> </Text.Info>
@@ -69,6 +69,7 @@ export default (props: { driveItem: DriveItem & { user?: UserType }}) => {
theme="outline" theme="outline"
className="w-9 !p-0 flex items-center justify-center ml-2 rounded-full border-none" className="w-9 !p-0 flex items-center justify-center ml-2 rounded-full border-none"
onClick={() => onDriveItemDownloadClick(file)} onClick={() => onDriveItemDownloadClick(file)}
testClassId="drive-item-button-download"
> >
<DownloadIcon className="text-blue-500 w-6 h-6" /> <DownloadIcon className="text-blue-500 w-6 h-6" />
</Button> </Button>
@@ -4,7 +4,7 @@ import { UserType } from '@features/users/types/user';
export default ({ user }: { user?: UserType }) => { export default ({ user }: { user?: UserType }) => {
return ( return (
<div className="flex overflow-hidden whitespace-nowrap text-ellipsis"> <div className="flex overflow-hidden whitespace-nowrap text-ellipsis testid:result-context">
{!!user && <>{UsersService.getFullName(user)}</>} {!!user && <>{UsersService.getFullName(user)}</>}
</div> </div>
); );
@@ -38,6 +38,7 @@ export const SearchInput = () => {
value={input.query} value={input.query}
className={className} className={className}
placeholder={Languages.t('scenes.app.mainview.quick_search_placeholder')} placeholder={Languages.t('scenes.app.mainview.quick_search_placeholder')}
testClassId="search-input-quick-search"
/> />
)} )}
/> />
@@ -8,7 +8,7 @@ export default () => {
const { open, setOpen } = useSearchModal(); const { open, setOpen } = useSearchModal();
return ( return (
<Modal open={open} onClose={() => setOpen(false)} className="sm:w-[80vw] sm:max-w-4xl"> <Modal open={open} onClose={() => setOpen(false)} className="sm:w-[80vw] sm:max-w-4xl testid:search-popup">
<SearchBox/> <SearchBox/>
</Modal> </Modal>
); );
@@ -16,7 +16,7 @@ export default () => {
return ( return (
<div> <div>
{!!isRecent && ( {!!isRecent && (
<Text.Subtitle className="block"> <Text.Subtitle className="block testid:drive-recent-files">
{Languages.t('components.searchpopup.recent_files')} {Languages.t('components.searchpopup.recent_files')}
</Text.Subtitle> </Text.Subtitle>
)} )}
@@ -191,7 +191,7 @@ export default class UploadZone extends React.Component<PropsType, StateType> {
<div <div
ref={node => node && (this.node = node)} ref={node => node && (this.node = node)}
style={this.props.style} style={this.props.style}
className={classNames('upload_drop_zone', this.props.className, `testid:${this.props.testClassId}`)} className={classNames('upload_drop_zone', this.props.className, this.props.testClassId ? `testid:${this.props.testClassId}` : '')}
onClick={() => { onClick={() => {
if (!this.props.disableClick) { if (!this.props.disableClick) {
this.open(); this.open();
@@ -40,11 +40,14 @@ export const AccessLevelDropdown = ({
}) => { }) => {
const createOption = (level: DriveFileAccessLevelOrRemove) => const createOption = (level: DriveFileAccessLevelOrRemove) =>
!hiddenLevels?.includes(level) && <option value={level}>{(labelOverrides || {})[level] || translateAccessLevel(level)}</option>; !hiddenLevels?.includes(level) && <option value={level}>{(labelOverrides || {})[level] || translateAccessLevel(level)}</option>;
const testId = testClassId ? `testid:${testClassId}` : '';
return ( return (
<Select <Select
disabled={disabled} disabled={disabled}
size={size} size={size}
className={className + ' w-auto' + ` testid:${testClassId}`} className={className + ' w-auto' + ' ' + testId}
theme={(!noRedWhenLevelNone && level === 'none') ? 'rose' : 'outline'} theme={(!noRedWhenLevelNone && level === 'none') ? 'rose' : 'outline'}
value={level || 'none'} value={level || 'none'}
onChange={e => onChange(e.target.value as DriveFileAccessLevel & 'remove')} onChange={e => onChange(e.target.value as DriveFileAccessLevel & 'remove')}
@@ -85,6 +85,7 @@ export const useOnBuildContextMenu = (
!FeatureTogglesService.isActiveFeatureName(FeatureNames.COMPANY_MANAGE_ACCESS); !FeatureTogglesService.isActiveFeatureName(FeatureNames.COMPANY_MANAGE_ACCESS);
const newMenuActions = [ const newMenuActions = [
{ {
id: 'share',
type: 'menu', type: 'menu',
icon: 'share-alt', icon: 'share-alt',
text: Languages.t('components.item_context_menu.share'), text: Languages.t('components.item_context_menu.share'),
@@ -92,6 +93,7 @@ export const useOnBuildContextMenu = (
onClick: () => setPublicLinkModalState({ open: true, id: item.id }), onClick: () => setPublicLinkModalState({ open: true, id: item.id }),
}, },
{ {
id: 'manage-access',
type: 'menu', type: 'menu',
icon: 'users-alt', icon: 'users-alt',
text: Languages.t('components.item_context_menu.manage_access'), text: Languages.t('components.item_context_menu.manage_access'),
@@ -99,6 +101,7 @@ export const useOnBuildContextMenu = (
onClick: () => setAccessModalState({ open: true, id: item.id }), onClick: () => setAccessModalState({ open: true, id: item.id }),
}, },
{ {
id: 'rescan-document',
type: 'menu', type: 'menu',
icon: 'shield-check', icon: 'shield-check',
text: Languages.t('components.item_context_menu.rescan_document'), text: Languages.t('components.item_context_menu.rescan_document'),
@@ -115,6 +118,7 @@ export const useOnBuildContextMenu = (
(notSafe && !(item.av_status === 'scan_failed')), (notSafe && !(item.av_status === 'scan_failed')),
}, },
{ {
id: 'download',
type: 'menu', type: 'menu',
icon: 'download-alt', icon: 'download-alt',
text: Languages.t('components.item_context_menu.download'), text: Languages.t('components.item_context_menu.download'),
@@ -141,6 +145,7 @@ export const useOnBuildContextMenu = (
}, // */ }, // */
{ type: 'separator', hide: notSafe }, { type: 'separator', hide: notSafe },
{ {
id: 'move',
type: 'menu', type: 'menu',
icon: 'folder-question', icon: 'folder-question',
text: Languages.t('components.item_context_menu.move'), text: Languages.t('components.item_context_menu.move'),
@@ -166,6 +171,7 @@ export const useOnBuildContextMenu = (
}), }),
}, },
{ {
id: 'rename',
type: 'menu', type: 'menu',
icon: 'file-edit-alt', icon: 'file-edit-alt',
text: Languages.t('components.item_context_menu.rename'), text: Languages.t('components.item_context_menu.rename'),
@@ -173,6 +179,7 @@ export const useOnBuildContextMenu = (
onClick: () => setPropertiesModalState({ open: true, id: item.id, inPublicSharing }), onClick: () => setPropertiesModalState({ open: true, id: item.id, inPublicSharing }),
}, },
{ {
id: 'copy-link',
type: 'menu', type: 'menu',
icon: 'link', icon: 'link',
text: Languages.t('components.item_context_menu.copy_link'), text: Languages.t('components.item_context_menu.copy_link'),
@@ -189,6 +196,7 @@ export const useOnBuildContextMenu = (
}, },
}, },
{ {
id: 'version',
type: 'menu', type: 'menu',
icon: 'history', icon: 'history',
text: Languages.t('components.item_context_menu.versions'), text: Languages.t('components.item_context_menu.versions'),
@@ -197,6 +205,7 @@ export const useOnBuildContextMenu = (
}, },
{ type: 'separator', hide: access !== 'manage' || inTrash || notSafe }, { type: 'separator', hide: access !== 'manage' || inTrash || notSafe },
{ {
id: 'move-to-trash',
type: 'menu', type: 'menu',
icon: 'trash', icon: 'trash',
text: Languages.t('components.item_context_menu.move_to_trash'), text: Languages.t('components.item_context_menu.move_to_trash'),
@@ -205,6 +214,7 @@ export const useOnBuildContextMenu = (
onClick: () => setConfirmTrashModalState({ open: true, items: [item] }), onClick: () => setConfirmTrashModalState({ open: true, items: [item] }),
}, },
{ {
id: 'restore',
type: 'menu', type: 'menu',
text: Languages.t('components.item_context_menu.restore'), text: Languages.t('components.item_context_menu.restore'),
className: 'error', className: 'error',
@@ -215,6 +225,7 @@ export const useOnBuildContextMenu = (
}, },
}, },
{ {
id: 'delete',
type: 'menu', type: 'menu',
text: Languages.t('components.item_context_menu.delete'), text: Languages.t('components.item_context_menu.delete'),
className: 'error', className: 'error',
@@ -231,6 +242,7 @@ export const useOnBuildContextMenu = (
// Add selected items related menus // Add selected items related menus
const newMenuActions: any[] = [ const newMenuActions: any[] = [
{ {
id: 'move-multiple',
type: 'menu', type: 'menu',
text: Languages.t('components.item_context_menu.move_multiple'), text: Languages.t('components.item_context_menu.move_multiple'),
hide: parent.access === 'read' || inTrash, hide: parent.access === 'read' || inTrash,
@@ -255,6 +267,7 @@ export const useOnBuildContextMenu = (
}), }),
}, },
{ {
id: 'download-multiple',
type: 'menu', type: 'menu',
text: Languages.t('components.item_context_menu.download_multiple'), text: Languages.t('components.item_context_menu.download_multiple'),
hide: inTrash, hide: inTrash,
@@ -272,12 +285,14 @@ export const useOnBuildContextMenu = (
}, },
}, },
{ {
id: 'clear-selection',
type: 'menu', type: 'menu',
text: Languages.t('components.item_context_menu.clear_selection'), text: Languages.t('components.item_context_menu.clear_selection'),
onClick: () => setChecked({}), onClick: () => setChecked({}),
}, },
{ type: 'separator', hide: parent.access === 'read' || notSafe }, { type: 'separator', hide: parent.access === 'read' || notSafe },
{ {
id: 'delete-multiple',
type: 'menu', type: 'menu',
text: Languages.t('components.item_context_menu.delete_multiple'), text: Languages.t('components.item_context_menu.delete_multiple'),
hide: !inTrash || parent.access !== 'manage', hide: !inTrash || parent.access !== 'manage',
@@ -290,6 +305,7 @@ export const useOnBuildContextMenu = (
}, },
}, },
{ {
id: 'move-to-trash-multiple',
type: 'menu', type: 'menu',
text: Languages.t('components.item_context_menu.to_trash_multiple'), text: Languages.t('components.item_context_menu.to_trash_multiple'),
hide: inTrash || parent.access !== 'manage', hide: inTrash || parent.access !== 'manage',
@@ -310,6 +326,7 @@ export const useOnBuildContextMenu = (
const newMenuActions: any[] = inTrash const newMenuActions: any[] = inTrash
? [ ? [
{ {
id: 'empty-trash',
type: 'menu', type: 'menu',
text: Languages.t('components.item_context_menu.trash.empty'), text: Languages.t('components.item_context_menu.trash.empty'),
className: 'error', className: 'error',
@@ -324,6 +341,7 @@ export const useOnBuildContextMenu = (
] ]
: [ : [
{ {
id: 'add-documents',
type: 'menu', type: 'menu',
text: Languages.t('components.item_context_menu.add_documents'), text: Languages.t('components.item_context_menu.add_documents'),
hide: inTrash || parent.access === 'read', hide: inTrash || parent.access === 'read',
@@ -332,6 +350,7 @@ export const useOnBuildContextMenu = (
setUploadModalState({ open: true, parent_id: parent?.item?.id }), setUploadModalState({ open: true, parent_id: parent?.item?.id }),
}, },
{ {
id: 'download-folder',
type: 'menu', type: 'menu',
text: Languages.t('components.item_context_menu.download_folder'), text: Languages.t('components.item_context_menu.download_folder'),
hide: inTrash, hide: inTrash,
@@ -349,6 +368,7 @@ export const useOnBuildContextMenu = (
}, },
}, },
{ {
id: 'copy-link',
type: 'menu', type: 'menu',
text: Languages.t('components.item_context_menu.copy_link'), text: Languages.t('components.item_context_menu.copy_link'),
hide: !hasAnyPublicLinkAccess(item), hide: !hasAnyPublicLinkAccess(item),
@@ -361,6 +381,7 @@ export const useOnBuildContextMenu = (
}, },
{ type: 'separator', hide: parent.item!.id != 'root' }, { type: 'separator', hide: parent.item!.id != 'root' },
{ {
id: 'manage-users',
type: 'menu', type: 'menu',
text: Languages.t('components.item_context_menu.manage_users'), text: Languages.t('components.item_context_menu.manage_users'),
hide: parent.item!.id != 'root', hide: parent.item!.id != 'root',
@@ -419,6 +440,7 @@ export const useOnBuildFileTypeContextMenu = () => {
return useCallback(() => { return useCallback(() => {
const menuItems = mimeTypes.map(item => { const menuItems = mimeTypes.map(item => {
return { return {
id: item.key,
type: 'menu', type: 'menu',
text: item.key, text: item.key,
onClick: () => { onClick: () => {
@@ -444,6 +466,7 @@ export const useOnBuildPeopleContextMenu = () => {
return useCallback(() => { return useCallback(() => {
const menuItems = userList.map(user => { const menuItems = userList.map(user => {
return { return {
id: user.first_name,
type: 'menu', type: 'menu',
text: user.first_name, text: user.first_name,
onClick: () => { onClick: () => {
@@ -466,6 +489,7 @@ export const useOnBuildDateContextMenu = () => {
return useCallback(() => { return useCallback(() => {
const menuItems = [ const menuItems = [
{ {
id: 'all-date',
type: 'menu', type: 'menu',
text: Languages.t('components.item_context_menu.all'), text: Languages.t('components.item_context_menu.all'),
onClick: () => { onClick: () => {
@@ -482,6 +506,7 @@ export const useOnBuildDateContextMenu = () => {
}, },
}, },
{ {
id: 'today',
type: 'menu', type: 'menu',
text: Languages.t('components.item_context_menu.today'), text: Languages.t('components.item_context_menu.today'),
onClick: () => { onClick: () => {
@@ -498,6 +523,7 @@ export const useOnBuildDateContextMenu = () => {
}, },
}, },
{ {
id: 'last-week',
type: 'menu', type: 'menu',
text: Languages.t('components.item_context_menu.last_week'), text: Languages.t('components.item_context_menu.last_week'),
onClick: () => { onClick: () => {
@@ -514,6 +540,7 @@ export const useOnBuildDateContextMenu = () => {
}, },
}, },
{ {
id: 'last-month',
type: 'menu', type: 'menu',
text: Languages.t('components.item_context_menu.last_month'), text: Languages.t('components.item_context_menu.last_month'),
onClick: () => { onClick: () => {
@@ -540,11 +567,13 @@ export const useOnBuildFileContextMenu = () => {
(item: DriveItem) => { (item: DriveItem) => {
const menuItems = [ const menuItems = [
{ {
id: 'preview',
type: 'menu', type: 'menu',
text: Languages.t('components.item_context_menu.preview'), text: Languages.t('components.item_context_menu.preview'),
onClick: () => preview(item), onClick: () => preview(item),
}, },
{ {
id: 'download',
type: 'menu', type: 'menu',
text: Languages.t('components.item_context_menu.download'), text: Languages.t('components.item_context_menu.download'),
onClick: () => { onClick: () => {
@@ -563,6 +592,7 @@ export const useOnBuildSortContextMenu = () => {
return useCallback(() => { return useCallback(() => {
const menuItems = [ const menuItems = [
{ {
id: 'sorting-by-date',
type: 'menu', type: 'menu',
text: Languages.t('components.item_context_menu.sorting.by.date'), text: Languages.t('components.item_context_menu.sorting.by.date'),
icon: sortItem.by === 'date' ? 'check' : 'sort-check', icon: sortItem.by === 'date' ? 'check' : 'sort-check',
@@ -578,6 +608,7 @@ export const useOnBuildSortContextMenu = () => {
}, },
}, },
{ {
id: 'sorting-by-name',
type: 'menu', type: 'menu',
text: Languages.t('components.item_context_menu.sorting.by.name'), text: Languages.t('components.item_context_menu.sorting.by.name'),
icon: sortItem.by === 'name' ? 'check' : 'sort-check', icon: sortItem.by === 'name' ? 'check' : 'sort-check',
@@ -592,6 +623,7 @@ export const useOnBuildSortContextMenu = () => {
}, },
}, },
{ {
id: 'sorting-by-size',
type: 'menu', type: 'menu',
text: Languages.t('components.item_context_menu.sorting.by.size'), text: Languages.t('components.item_context_menu.sorting.by.size'),
icon: sortItem.by === 'size' ? 'check' : 'sort-check', icon: sortItem.by === 'size' ? 'check' : 'sort-check',
@@ -607,6 +639,7 @@ export const useOnBuildSortContextMenu = () => {
}, },
{type:"separator"}, {type:"separator"},
{ {
id: 'sorting-order-asc',
type: 'menu', type: 'menu',
text: Languages.t('components.item_context_menu.sorting.order.asc'), text: Languages.t('components.item_context_menu.sorting.order.asc'),
icon: sortItem.order === 'asc' ? 'check' : 'sort-check', icon: sortItem.order === 'asc' ? 'check' : 'sort-check',
@@ -621,6 +654,7 @@ export const useOnBuildSortContextMenu = () => {
}, },
}, },
{ {
id: 'sorting-order-desc',
type: 'menu', type: 'menu',
text: Languages.t('components.item_context_menu.sorting.order.desc'), text: Languages.t('components.item_context_menu.sorting.order.desc'),
icon: sortItem.order === 'desc' ? 'check' : 'sort-check', icon: sortItem.order === 'desc' ? 'check' : 'sort-check',
@@ -45,6 +45,8 @@ export const DocumentRow = ({
// history.push(RouterServices.generateRouteFromState({ companyId: company, itemId: item.id })); // history.push(RouterServices.generateRouteFromState({ companyId: company, itemId: item.id }));
}; };
const testId = testClassId ? `testid:${testClassId}` : '';
return ( return (
<div <div
className={ className={
@@ -52,8 +54,8 @@ export const DocumentRow = ({
(checked (checked
? (notSafe ? 'bg-rose-500' : 'bg-blue-500') + ' bg-opacity-10 hover:bg-opacity-25' ? (notSafe ? 'bg-rose-500' : 'bg-blue-500') + ' bg-opacity-10 hover:bg-opacity-25'
: 'hover:bg-zinc-500 hover:bg-opacity-10 ') + : 'hover:bg-zinc-500 hover:bg-opacity-10 ') +
(className || '') + (className || '') + ' ' +
` testid:${testClassId}` testId
} }
id={`DR-${item.id}`} id={`DR-${item.id}`}
onMouseEnter={() => setHover(true)} onMouseEnter={() => setHover(true)}
@@ -21,6 +21,8 @@ export const FolderRow = ({
}: DriveItemProps) => { }: DriveItemProps) => {
const [hover, setHover] = useState(false); const [hover, setHover] = useState(false);
const testId = testClassId ? ` testid:${testClassId}` : '';
return ( return (
<div <div
className={ className={
@@ -29,8 +31,8 @@ export const FolderRow = ({
(checked (checked
? 'bg-blue-500 bg-opacity-10 hover:bg-opacity-25 ' ? 'bg-blue-500 bg-opacity-10 hover:bg-opacity-25 '
: 'hover:bg-zinc-500 hover:bg-opacity-10 ') + : 'hover:bg-zinc-500 hover:bg-opacity-10 ') +
(className || '') + (className || '') + ' ' +
` testid:${testClassId}` testId
} }
onMouseEnter={() => setHover(true)} onMouseEnter={() => setHover(true)}
onMouseLeave={() => setHover(false)} onMouseLeave={() => setHover(false)}
@@ -27,7 +27,7 @@ export const ConfirmDeleteModal = () => {
return ( return (
<> <>
{state.items.length > 0 && ( {state.items.length > 0 && (
<Modal open={state.open} onClose={() => setState({ ...state, open: false })}> <Modal className="testid:confirm-delete-modal" open={state.open} onClose={() => setState({ ...state, open: false })}>
<ConfirmDeleteModalContent items={state.items} /> <ConfirmDeleteModalContent items={state.items} />
</Modal> </Modal>
)} )}
@@ -68,7 +68,7 @@ export const ConfirmModal = () => {
}; };
return ( return (
<Modal open={state.open} onClose={handleClose}> <Modal className="testid:confirm-modal" open={state.open} onClose={handleClose}>
<ConfirmModalContent key={state.parent_id} /> <ConfirmModalContent key={state.parent_id} />
</Modal> </Modal>
); );
@@ -28,7 +28,7 @@ export const ConfirmTrashModal = () => {
const [state, setState] = useRecoilState(ConfirmTrashModalAtom); const [state, setState] = useRecoilState(ConfirmTrashModalAtom);
return ( return (
<Modal open={state.open} onClose={() => setState({ ...state, open: false })}> <Modal className="confirm-trash-modal" open={state.open} onClose={() => setState({ ...state, open: false })}>
{!!state.items.length && <ConfirmTrashModalContent items={state.items} />} {!!state.items.length && <ConfirmTrashModalContent items={state.items} />}
</Modal> </Modal>
); );
@@ -46,7 +46,7 @@ export const CreateModal = ({
<Modal <Modal
open={state.open} open={state.open}
onClose={() => setState({ ...state, open: false })} onClose={() => setState({ ...state, open: false })}
className="!max-w-sm" className="!max-w-sm testid:create-modal"
> >
<ModalContent <ModalContent
title={ title={
@@ -171,10 +171,12 @@ export const CreateModal = ({
}; };
const CreateModalOption = (props: { testClassId?: string; icon: ReactNode; text: string; onClick: () => void }) => { const CreateModalOption = (props: { testClassId?: string; icon: ReactNode; text: string; onClick: () => void }) => {
const testId = props.testClassId ? `testid:${props.testClassId}` : '';
return ( return (
<div <div
onClick={props.onClick} 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 testid:${props.testClassId}`} 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 ${testId}`}
> >
<div className="flex items-center justify-center">{props.icon}</div> <div className="flex items-center justify-center">{props.icon}</div>
<div className="grow flex items-center ml-2"> <div className="grow flex items-center ml-2">
@@ -27,7 +27,7 @@ export const PropertiesModal = () => {
const [state, setState] = useRecoilState(PropertiesModalAtom); const [state, setState] = useRecoilState(PropertiesModalAtom);
return ( return (
<Modal open={state.open} onClose={() => setState({ ...state, open: false })}> <Modal className="testid:properties-modal" open={state.open} onClose={() => setState({ ...state, open: false })}>
{!!state.id && ( {!!state.id && (
<PropertiesModalContent <PropertiesModalContent
id={state.id} id={state.id}
@@ -41,6 +41,7 @@ export const PublicLinkModal = () => {
setIsOnAdvancedScreen(false); setIsOnAdvancedScreen(false);
setState({ ...state, open: false }); setState({ ...state, open: false });
}} }}
className="testid:public-link-modal"
> >
{!!state.id && {!!state.id &&
<PublicLinkModalContent <PublicLinkModalContent
@@ -155,6 +156,7 @@ const PublicLinkModalContent = (props: {
<Modal <Modal
open={props.isOnAdvancedScreen} open={props.isOnAdvancedScreen}
onClose={() => { props.onShowAdvancedScreen(false); }} onClose={() => { props.onShowAdvancedScreen(false); }}
className="testid:public-link-advance-setting-modal"
> >
<ModalContent <ModalContent
title={ title={
@@ -28,7 +28,7 @@ export const AccessModal = () => {
return ( return (
<Modal <Modal
open={state.open} open={state.open}
className='!overflow-visible' className='!overflow-visible testid:access-modal'
onClose={closeModal} onClose={closeModal}
> >
{!!state.id && <AccessModalContent id={state.id} onCloseModal={closeModal} />} {!!state.id && <AccessModalContent id={state.id} onCloseModal={closeModal} />}
@@ -181,7 +181,7 @@ export const InternalUsersAccessManager = ({
size="sm" size="sm"
className='text-center' className='text-center'
onClick={onCloseModal} onClick={onCloseModal}
testClassId="access-management-public-link-security-field-confirm-edit" testClassId="public-link-button-confirm-edit"
> >
{Languages.t('components.public-link-security_field_confirm_edit')} {Languages.t('components.public-link-security_field_confirm_edit')}
</Button> </Button>
@@ -40,7 +40,7 @@ export const UploadModal = ({
<Modal <Modal
open={state.open} open={state.open}
onClose={() => setState({ ...state, open: false })} onClose={() => setState({ ...state, open: false })}
className="!max-w-sm" className="!max-w-sm testid:upload-modal"
> >
<ModalContent <ModalContent
title={ title={
@@ -29,7 +29,7 @@ export const VersionsModal = () => {
const [state, setState] = useRecoilState(VersionsModalAtom); const [state, setState] = useRecoilState(VersionsModalAtom);
return ( return (
<Modal open={state.open} onClose={() => setState({ ...state, open: false })}> <Modal className="testid:version-modal" open={state.open} onClose={() => setState({ ...state, open: false })}>
{!!state.id && <VersionModalContent id={state.id} />} {!!state.id && <VersionModalContent id={state.id} />}
</Modal> </Modal>
); );
@@ -29,7 +29,7 @@ export const SharedFilesTable = () => {
return formattedDate; return formattedDate;
}; };
return ( return (
<div> <div className="testid:shared-file-table">
<Title className="mb-4 block">{Languages.t('scenes.app.shared_with_me.shared_with_me')}</Title> <Title className="mb-4 block">{Languages.t('scenes.app.shared_with_me.shared_with_me')}</Title>
{/* Filters */} {/* Filters */}
<div className="flex items-center space-x-4 mb-6"> <div className="flex items-center space-x-4 mb-6">
@@ -69,7 +69,7 @@ export default () => {
<div className="flex flex-row items-center justify-center bg-blue-500 px-4 py-2"> <div className="flex flex-row items-center justify-center bg-blue-500 px-4 py-2">
<div className="grow flex flex-row items-center"> <div className="grow flex flex-row items-center">
{group.logo && ( {group.logo && (
<Avatar avatar={group.logo} className="inline-block mr-3" size="sm" type="square" /> <Avatar avatar={group.logo} className="inline-block mr-3" size="sm" type="square" testClassId="shared-view-avatar" />
)} )}
<span className="text-white font-semibold" style={{ lineHeight: '32px' }}> <span className="text-white font-semibold" style={{ lineHeight: '32px' }}>
Twake Drive Twake Drive
@@ -162,6 +162,7 @@ const AccessChecker = ({
className="-mr-px rounded-r-none border-r-none" className="-mr-px rounded-r-none border-r-none"
value={password} value={password}
onChange={e => setPassword(e.target.value)} onChange={e => setPassword(e.target.value)}
testClassId="access-checker-input-password"
/> />
<Button <Button
className="rounded-l-none" className="rounded-l-none"
@@ -170,6 +171,7 @@ const AccessChecker = ({
await setPublicToken(token || '', password); await setPublicToken(token || '', password);
await refresh(folderId); await refresh(folderId);
}} }}
testClassId="access-checker-button-submit"
> >
Submit Submit
</Button> </Button>
@@ -23,11 +23,13 @@ export default (): JSX.Element => {
menu={[ menu={[
// user name / email // user name / email
{ {
id: 'username',
type: 'text', type: 'text',
className: "username", className: "username",
text: currentUserService.getFullName(user), text: currentUserService.getFullName(user),
}, },
{ {
id: 'email',
type: 'text', type: 'text',
text: user.email, text: user.email,
className: 'email', className: 'email',
@@ -36,6 +38,7 @@ export default (): JSX.Element => {
}, },
{ type: 'separator' }, { type: 'separator' },
{ {
id: 'account-setting',
type: 'menu', type: 'menu',
className: 'account-menu', className: 'account-menu',
icon: <Icon type="user-circle" className="text-black dark:text-white" />, icon: <Icon type="user-circle" className="text-black dark:text-white" />,
@@ -46,6 +49,7 @@ export default (): JSX.Element => {
}, },
}, },
{ {
id: 'logout',
type: 'menu', type: 'menu',
className: 'account-menu', className: 'account-menu',
icon: <Icon type="sign-out-alt" className="text-black dark:text-white" />, icon: <Icon type="sign-out-alt" className="text-black dark:text-white" />,
@@ -61,6 +65,7 @@ export default (): JSX.Element => {
className="shrink-0 border-0" className="shrink-0 border-0"
avatar={user.thumbnail} avatar={user.thumbnail}
title={currentUserService.getFullName(user)} title={currentUserService.getFullName(user)}
testClassId="account-avatar"
/> />
</Menu> </Menu>
); );
@@ -27,7 +27,7 @@ export default ({ className }: { className?: string }): JSX.Element => {
target="_blank" target="_blank"
rel="noreferrer" rel="noreferrer"
href={app.url} href={app.url}
className="inline-block flex flex-col items-center justify-center cursor-pointer hover:bg-zinc-100 dark:hover:bg-zinc-800 rounded-md p-2 pb-1" className={`inline-block flex flex-col items-center justify-center cursor-pointer hover:bg-zinc-100 dark:hover:bg-zinc-800 rounded-md p-2 pb-1 testid:app-${app.name}`}
> >
<img src={app.logo} className="w-11 h-11 mb-1" /> <img src={app.logo} className="w-11 h-11 mb-1" />
<Base style={{ <Base style={{
@@ -47,6 +47,7 @@ export default ({ className }: { className?: string }): JSX.Element => {
size="md" size="md"
className={'!rounded-full border-0 ' + className} className={'!rounded-full border-0 ' + className}
icon={() => <ViewGridIcon className="w-6 h-6 text-blue-500" />} icon={() => <ViewGridIcon className="w-6 h-6 text-blue-500" />}
testClassId="app-grid-button"
/> />
</Menu> </Menu>
); );
@@ -44,19 +44,19 @@ const DiskUsage = () => {
<div className="w-full"> <div className="w-full">
<div className="overflow-hidden h-4 mb-4 text-xs flex rounded bg-emerald-200"> <div className="overflow-hidden h-4 mb-4 text-xs flex rounded bg-emerald-200">
{used > 90 && ( {used > 90 && (
<div style={{ width: used + '%',}} className="shadow-none flex flex-col text-center whitespace-nowrap text-white justify-center bg-red-500"></div> <div style={{ width: used + '%',}} className="shadow-none flex flex-col text-center whitespace-nowrap text-white justify-center bg-red-500 testid:disk-usage-over-90"></div>
)} )}
{used < 80 && ( {used < 80 && (
<div style={{ width: used + '%',}} className="shadow-none flex flex-col text-center whitespace-nowrap text-white justify-center bg-green-500"></div> <div style={{ width: used + '%',}} className="shadow-none flex flex-col text-center whitespace-nowrap text-white justify-center bg-green-500 testid:disk-usage-less-than-80"></div>
)} )}
{ (used >= 80 && used <= 90 )&& ( { (used >= 80 && used <= 90 )&& (
<div style={{ width: used + '%',}} className="shadow-none flex flex-col text-center whitespace-nowrap text-white justify-center bg-yellow-500"></div> <div style={{ width: used + '%',}} className="shadow-none flex flex-col text-center whitespace-nowrap text-white justify-center bg-yellow-500 testid:disk-usage-80-to-90"></div>
)} )}
<div style={{ width: (100 - used) + '%' }} className="shadow-none flex flex-col text-center whitespace-nowrap text-white justify-center bg-grey-500"></div> <div style={{ width: (100 - used) + '%' }} className="shadow-none flex flex-col text-center whitespace-nowrap text-white justify-center bg-grey-500 testid:disk-usage-100"></div>
</div> </div>
{/*<div className="bg-blue-600 h-1.5 rounded-full dark:bg-blue-500" style={usedStyle}></div>*/} {/*<div className="bg-blue-600 h-1.5 rounded-full dark:bg-blue-500" style={usedStyle}></div>*/}
<Base> <Base className="testid:disk-usage-text">
{formatBytesToInt(usedBytes)} {formatBytesToInt(usedBytes)}
<Base> { Languages.t('components.disk_usage.of')} </Base> <Base> { Languages.t('components.disk_usage.of')} </Base>
{formatBytesToInt(totalBytes || 0)} {formatBytesToInt(totalBytes || 0)}
@@ -69,7 +69,7 @@ const DiskUsage = () => {
{!FeatureTogglesService.isActiveFeatureName(FeatureNames.COMPANY_USER_QUOTA) && ( {!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="bg-zinc-500 dark:bg-zinc-900 bg-opacity-10 rounded-md p-4 w-auto max-w-md">
<div className="w-full"> <div className="w-full">
<Base> <Base className="testid:disk-usage-text">
{formatBytesToInt(usedBytes)} {formatBytesToInt(usedBytes)}
<Base> { Languages.t('components.disk_usage.used')} </Base> <Base> { Languages.t('components.disk_usage.used')} </Base>
</Base> </Base>
@@ -170,7 +170,7 @@ export default () => {
theme="primary" theme="primary"
className="w-full mb-2 justify-center" className="w-full mb-2 justify-center"
style={{ boxShadow: '0 0 10px 0 rgba(0, 122, 255, 0.5)' }} style={{ boxShadow: '0 0 10px 0 rgba(0, 122, 255, 0.5)' }}
testClassId="sidebar-action-button-empty-trash" testClassId="sidebar-action-button-upload"
> >
<UploadIcon className="w-5 h-5 mr-2" /> {Languages.t('components.side_menu.buttons.upload')} <UploadIcon className="w-5 h-5 mr-2" /> {Languages.t('components.side_menu.buttons.upload')}
</Button> </Button>
@@ -179,7 +179,7 @@ export default () => {
size="lg" size="lg"
theme="secondary" theme="secondary"
className="w-full mb-2 justify-center" className="w-full mb-2 justify-center"
testClassId="sidebar-action-button-open-modal" testClassId="sidebar-action-button-open-create-modal"
> >
<PlusIcon className="w-5 h-5 mr-2" /> {Languages.t('components.side_menu.buttons.create')} <PlusIcon className="w-5 h-5 mr-2" /> {Languages.t('components.side_menu.buttons.create')}
</Button> </Button>
@@ -86,6 +86,7 @@ export default () => {
? activeClass ? activeClass
: '') : '')
} }
testClassId="sidebar-menu-my-drive"
> >
<UserIcon className="w-5 h-5 mr-4" /> {Languages.t('components.side_menu.my_drive')} <UserIcon className="w-5 h-5 mr-4" /> {Languages.t('components.side_menu.my_drive')}
</Button> </Button>
@@ -107,6 +108,7 @@ export default () => {
className={ className={
'w-full mb-1 ' + (folderType === 'home' && viewId == 'root' ? activeClass : '') 'w-full mb-1 ' + (folderType === 'home' && viewId == 'root' ? activeClass : '')
} }
testClassId="sidebar-menu-shared-drive"
> >
<CloudIcon className="w-5 h-5 mr-4" /> {Languages.t('components.side_menu.home')} <CloudIcon className="w-5 h-5 mr-4" /> {Languages.t('components.side_menu.home')}
</Button> </Button>
@@ -130,6 +132,7 @@ export default () => {
'w-full mb-1 ' + 'w-full mb-1 ' +
(folderType === 'shared' && viewId == 'shared_with_me' ? activeClass : '') (folderType === 'shared' && viewId == 'shared_with_me' ? activeClass : '')
} }
testClassId="sidebar-menu-share-with-me"
> >
<UserGroupIcon className="w-5 h-5 mr-4" />{' '} <UserGroupIcon className="w-5 h-5 mr-4" />{' '}
{Languages.t('components.side_menu.shared_with_me')} {Languages.t('components.side_menu.shared_with_me')}
@@ -168,6 +171,7 @@ export default () => {
size="lg" size="lg"
theme="white" theme="white"
className={'w-full mb-1 ' + (viewId?.includes('trash') ? activeClass : '')} className={'w-full mb-1 ' + (viewId?.includes('trash') ? activeClass : '')}
testClassId="sidebar-menu-trash"
> >
<TrashIcon className="w-5 h-5 mr-4 text-rose-500" />{' '} <TrashIcon className="w-5 h-5 mr-4 text-rose-500" />{' '}
{Languages.t('components.side_menu.trash')} {Languages.t('components.side_menu.trash')}
@@ -102,12 +102,12 @@ export const DrivePreview: React.FC<DrivePreviewProps> = ({ items }) => {
<Modal <Modal
open={isOpen} open={isOpen}
closable={false} 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:preview-modal"
style={{ maxWidth: 'none', margin: 0, left: 0, top: 0, height: '100vh' }} style={{ maxWidth: 'none', margin: 0, left: 0, top: 0, height: '100vh' }}
positioned={false} positioned={false}
> >
<XIcon <XIcon
className="z-10 cursor-pointer absolute right-5 top-5 w-20 h-20 text-white hover:text-black rounded-full p-1 bg-gray-500 hover:bg-white bg-opacity-25" className="z-10 cursor-pointer absolute right-5 top-5 w-20 h-20 text-white hover:text-black rounded-full p-1 bg-gray-500 hover:bg-white bg-opacity-25 testid:preview-button-close"
onClick={() => { onClick={() => {
close(); close();
// small delay to allow the modal to close // small delay to allow the modal to close
@@ -135,10 +135,10 @@ export const DrivePreview: React.FC<DrivePreviewProps> = ({ items }) => {
</div> </div>
<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">
<div className="grow overflow-hidden text-ellipsis"> <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:preview-file-name">
{name} {name}
</Text.Base> </Text.Base>
<Text.Info className="whitespace-nowrap"> <Text.Info className="whitespace-nowrap testid:preview-file-info">
{formatDate( {formatDate(
+(status.details?.item.added || '') || +(status.details?.item.added || '') ||
status.details?.item.last_version_cache.date_added, status.details?.item.last_version_cache.date_added,