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,
import { sortBy } from 'lodash';
import { formatFileSize } from 'common/formatters';
import { getInlineFileUrl, sanitizeToken } from 'views-components/context-menu/actions/helpers';
-import _ from 'lodash';
export interface CollectionPanelFilesProps {
isWritable: boolean;
| "pathPanelPathWrapper"
| "uploadButton"
| "uploadIcon"
+ | "moreOptionsButton"
+ | "moreOptions"
| "loader"
| "wrapper"
| "dataWrapper"
},
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 = {};
-let prevState = {};
-function difference(object, base) {
- function changes(object, base) {
- return _.transform(object, function(result, value, key) {
- if (!_.isEqual(value, base[key])) {
- result[key] = (_.isObject(value) && _.isObject(base[key])) ? changes(value, base[key]) : value;
- }
- });
- }
- return changes(object, base);
-}
export const CollectionPanelFiles = withStyles(styles)(connect((state: RootState) => ({
auth: state.auth,
collectionPanel: state.collectionPanel,
collectionPanelFiles: state.collectionPanelFiles,
}))((props: CollectionPanelFilesProps & WithStyles<CssRules> & { auth: AuthState }) => {
- const diff = difference(props, prevState);
- prevState = props;
- console.log('---> render CollectionPanelFiles <------', diff);
const { classes, onItemMenuOpen, onUploadDataClick, isWritable, dispatch, collectionPanelFiles, collectionPanel } = props;
const { apiToken, config } = props.auth;
React.useEffect(() => {
if (props.currentItemUuid) {
- console.log(' --> useEffect current UUID: ', props.currentItemUuid);
setPathData({});
setPath([props.currentItemUuid]);
}
}, [props.currentItemUuid]);
const fetchData = (keys, ignoreCache = false) => {
- console.log('---> fetchData', keys);
const keyArray = Array.isArray(keys) ? keys : [keys];
Promise.all(keyArray.filter(key => !!key)
pathPromise[key] = true;
- console.log('>>> fetching data for key', key);
return webdavClient.propfind(`c=${key}`, webDAVRequestConfig);
}
.then((requests) => {
const newState = requests.map((request, index) => {
if (request && request.responseXML != null) {
- console.log(">>> got data for key", keyArray[index]);
const key = keyArray[index];
const result: any = extractFilesData(request.responseXML);
const sortedResult = sortBy(result, (n) => n.name).sort((n1, n2) => {
React.useEffect(() => {
if (rightKey) {
- console.log('---> useEffect rightKey:', rightKey);
fetchData(rightKey);
setLeftSearch('');
setRightSearch('');
const currentPDH = (collectionPanel.item || {}).portableDataHash;
React.useEffect(() => {
if (currentPDH) {
- console.log('---> useEffect PDH change:', 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
React.useEffect(() => {
if (rightData) {
- console.log('---> useEffect rightData:', rightData, 'search:', rightSearch);
const filtered = rightData.filter(({ name }) => name.indexOf(rightSearch) > -1);
setCollectionFiles(filtered, false)(dispatch);
}
let node = null;
if (parentRef?.current) {
- console.log('---> useEffect parentRef:', parentRef);
node = parentRef.current;
(node as any).addEventListener('contextmenu', handleRightClick);
}
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 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
);
return !!filtered.length
? <FixedSizeList height={height} itemCount={filtered.length}
itemSize={35} width={width}>{ ({ index, style }) => {
- console.log("Left Data ROW: ", filtered[index]);
const { id, type, name } = filtered[index];
return <div data-id={id} style={style} data-item="true"
data-type={type} data-parent-path={name}
: <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">
<div className={classes.dataWrapper}>{ rightData && !isLoading
? <AutoSizer defaultHeight={500}>{({ height, width }) => {
const filtered = rightData.filter(({ name }) => name.indexOf(rightSearch) > -1);
- console.log("Right Data: ", filtered);
return !!filtered.length
? <FixedSizeList height={height} itemCount={filtered.length}
itemSize={35} width={width}>{ ({ index, style }) => {
- console.log("Right Data ROW: ", filtered[index]);
const { id, type, name, size } = filtered[index];
return <div style={style} data-id={id} data-item="true"
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>