import { FixedSizeList } from "react-window";
import AutoSizer from "react-virtualized-auto-sizer";
import servicesProvider from 'common/service-provider';
-import { CustomizeTableIcon, DownloadIcon } from 'components/icon/icon';
+import { CustomizeTableIcon, DownloadIcon, MoreOptionsIcon } from 'components/icon/icon';
import { SearchInput } from 'components/search-input/search-input';
import {
ListItemIcon,
| "pathPanelPathWrapper"
| "uploadButton"
| "uploadIcon"
+ | "moreOptionsButton"
+ | "moreOptions"
| "loader"
| "wrapper"
| "dataWrapper"
wrapper: {
display: 'flex',
minHeight: '600px',
- color: 'rgba(0, 0, 0, 0.87)',
+ color: 'rgba(0,0,0,0.87)',
fontSize: '0.875rem',
fontFamily: '"Roboto", "Helvetica", "Arial", sans-serif',
fontWeight: 400,
marginTop: '-15px',
},
pathPanel: {
- padding: '1rem',
- marginBottom: '1rem',
+ padding: '0.5rem',
+ marginBottom: '0.5rem',
backgroundColor: '#fff',
boxShadow: '0px 1px 3px 0px rgb(0 0 0 / 20%), 0px 1px 1px 0px rgb(0 0 0 / 14%), 0px 2px 1px -1px rgb(0 0 0 / 12%)',
},
},
leftPanel: {
flex: 0,
- padding: '1rem',
+ padding: '0 1rem 1rem',
marginRight: '1rem',
whiteSpace: 'nowrap',
position: 'relative',
rightPanel: {
flex: '50%',
padding: '1rem',
- paddingTop: '2rem',
- marginTop: '-1rem',
+ paddingTop: '0.5rem',
+ marginTop: '-0.5rem',
position: 'relative',
backgroundColor: '#fff',
boxShadow: '0px 3px 3px 0px rgb(0 0 0 / 20%), 0px 3px 1px 0px rgb(0 0 0 / 14%), 0px 3px 1px -1px rgb(0 0 0 / 12%)',
},
uploadButton: {
float: 'right',
- }
+ },
+ moreOptionsButton: {
+ width: theme.spacing.unit * 3,
+ height: theme.spacing.unit * 3,
+ marginRight: theme.spacing.unit,
+ marginTop: 'auto',
+ marginBottom: 'auto',
+ justifyContent: 'center',
+ },
+ moreOptions: {
+ position: 'absolute'
+ },
});
const pathPromise = {};
const { classes, onItemMenuOpen, onUploadDataClick, isWritable, dispatch, collectionPanelFiles, collectionPanel } = props;
const { apiToken, config } = props.auth;
- const webdavClient = new WebDAV();
- webdavClient.defaults.baseURL = config.keepWebServiceUrl;
- webdavClient.defaults.headers = {
- Authorization: `Bearer ${apiToken}`
- };
+ const webdavClient = new WebDAV({
+ baseURL: config.keepWebServiceUrl,
+ headers: {
+ Authorization: `Bearer ${apiToken}`
+ },
+ });
const webDAVRequestConfig: WebDAVRequestConfig = {
headers: {
}).reduce((prev, next) => {
return { ...next, ...prev };
}, {});
-
- setPathData({ ...pathData, ...newState });
+ setPathData((state) => ({ ...state, ...newState }));
})
.finally(() => {
setIsLoading(false);
const currentPDH = (collectionPanel.item || {}).portableDataHash;
React.useEffect(() => {
if (currentPDH) {
- // Avoid fetching the same content level twice
- if (leftKey !== rightKey) {
- fetchData([leftKey, rightKey], true);
- } else {
- fetchData(rightKey, true);
- }
+ fetchData([leftKey, rightKey], true);
}
}, [currentPDH]); // eslint-disable-line react-hooks/exhaustive-deps
const handleClick = React.useCallback(
(event: any) => {
let isCheckbox = false;
+ let isMoreButton = false;
let elem = event.target;
if (elem.type === 'checkbox') {
isCheckbox = true;
}
+ // The "More options" button click event could be triggered on its
+ // internal graphic element.
+ else if ((elem.dataset && elem.dataset.id === 'moreOptions') || (elem.parentNode && elem.parentNode.dataset && elem.parentNode.dataset.id === 'moreOptions')) {
+ isMoreButton = true;
+ }
while (elem && elem.dataset && !elem.dataset.item) {
elem = elem.parentNode;
}
- if (elem && elem.dataset && !isCheckbox) {
+ if (elem && elem.dataset && !isCheckbox && !isMoreButton) {
const { parentPath, subfolderPath, breadcrumbPath, type } = elem.dataset;
if (breadcrumbPath) {
const index = path.indexOf(breadcrumbPath);
- setPath([...path.slice(0, index + 1)]);
+ setPath((state) => ([...state.slice(0, index + 1)]));
}
if (parentPath && type === 'directory') {
path.pop()
}
- setPath([...path, parentPath]);
+ setPath((state) => ([...state, parentPath]));
}
if (subfolderPath && type === 'directory') {
- setPath([...path, subfolderPath]);
+ setPath((state) => ([...state, subfolderPath]));
}
if (elem.dataset.id && type === 'file') {
const item = collectionPanelFiles[id];
props.onSelectionToggle(event, item);
}
+ if (isMoreButton) {
+ const { id } = elem.dataset;
+ const item: any = {
+ id,
+ data: rightData.find((elem) => elem.id === id),
+ };
+ onItemMenuOpen(event, item, isWritable);
+ }
},
[path, setPath, collectionPanelFiles] // eslint-disable-line react-hooks/exhaustive-deps
);
<div className={classes.wrapper}>
<div className={classNames(classes.leftPanel, path.length > 1 ? classes.leftPanelVisible : classes.leftPanelHidden)} data-cy="collection-files-left-panel">
<Tooltip title="Go back" className={path.length > 1 ? classes.backButton : classes.backButtonHidden}>
- <IconButton onClick={() => setPath([...path.slice(0, path.length -1)])}>
+ <IconButton onClick={() => setPath((state) => ([...state.slice(0, state.length -1)]))}>
<BackIcon />
</IconButton>
</Tooltip>
: <div className={classes.rowEmpty}>No directories available</div>
}}
</AutoSizer>
- : <div className={classes.row}><CircularProgress className={classes.loader} size={30} /></div> }
+ : <div data-cy="collection-loader" className={classes.row}><CircularProgress className={classes.loader} size={30} /></div> }
</div>
</div>
<div className={classes.rightPanel} data-cy="collection-files-right-panel">
marginLeft: 'auto', marginRight: '1rem' }}>
{ formatFileSize(size) }
</span>
+ <Tooltip title="More options" disableFocusListener>
+ <IconButton data-id='moreOptions'
+ data-cy='file-item-options-btn'
+ className={classes.moreOptionsButton}>
+ <MoreOptionsIcon
+ data-id='moreOptions'
+ className={classes.moreOptions} />
+ </IconButton>
+ </Tooltip>
</div>
} }</FixedSizeList>
: <div className={classes.rowEmpty}>This collection is empty</div>