X-Git-Url: https://git.arvados.org/arvados-workbench2.git/blobdiff_plain/172ba18e43743d90b8a1110d62209be2ab7627d1..198ae2eb95d997550d1d647916b38bb8b3f536e9:/src/components/collection-panel-files/collection-panel-files.tsx diff --git a/src/components/collection-panel-files/collection-panel-files.tsx b/src/components/collection-panel-files/collection-panel-files.tsx index a7001a61..0fa06682 100644 --- a/src/components/collection-panel-files/collection-panel-files.tsx +++ b/src/components/collection-panel-files/collection-panel-files.tsx @@ -22,20 +22,18 @@ import { setCollectionFiles } from 'store/collection-panel/collection-panel-file 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 { items: any; isWritable: boolean; - isLoading: boolean; - tooManyFiles: boolean; - onUploadDataClick: () => void; + onUploadDataClick: (targetLocation?: string) => void; onSearchChange: (searchValue: string) => void; onItemMenuOpen: (event: React.MouseEvent, item: TreeItem, isWritable: boolean) => void; onOptionsMenuOpen: (event: React.MouseEvent, isWritable: boolean) => void; onSelectionToggle: (event: React.MouseEvent, item: TreeItem) => void; onCollapseToggle: (id: string, status: TreeItemStatus) => void; onFileClick: (id: string) => void; - loadFilesFunc: () => void; currentItemUuid: any; dispatch: Function; collectionPanelFiles: any; @@ -48,7 +46,6 @@ const styles: StyleRulesCallback = (theme: Theme) => ({ wrapper: { display: 'flex', minHeight: '600px', - marginBottom: '1rem', color: 'rgba(0, 0, 0, 0.87)', fontSize: '0.875rem', fontFamily: '"Roboto", "Helvetica", "Arial", sans-serif', @@ -178,11 +175,25 @@ const styles: StyleRulesCallback = (theme: Theme) => ({ 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 & { auth: AuthState }) => { + const diff = difference(props, prevState); + prevState = props; + console.log('---> render CollectionPanel <------', diff); const { classes, onItemMenuOpen, onUploadDataClick, isWritable, dispatch, collectionPanelFiles, collectionPanel } = props; const { apiToken, config } = props.auth; @@ -202,7 +213,6 @@ export const CollectionPanelFiles = withStyles(styles)(connect((state: RootState const [path, setPath]: any = React.useState([]); const [pathData, setPathData]: any = React.useState({}); const [isLoading, setIsLoading] = React.useState(false); - const [collectionAutofetchEnabled, setCollectionAutofetchEnabled] = React.useState(false); const [leftSearch, setLeftSearch] = React.useState(''); const [rightSearch, setRightSearch] = React.useState(''); @@ -214,15 +224,17 @@ export const CollectionPanelFiles = withStyles(styles)(connect((state: RootState 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 + Promise.all(keyArray.filter(key => !!key) .map((key) => { const dataExists = !!pathData[key]; const runningRequest = pathPromise[key]; @@ -234,6 +246,7 @@ export const CollectionPanelFiles = withStyles(styles)(connect((state: RootState pathPromise[key] = true; + console.log('>>> fetching data for key', key); return webdavClient.propfind(`c=${key}`, webDAVRequestConfig); } @@ -241,54 +254,62 @@ export const CollectionPanelFiles = withStyles(styles)(connect((state: RootState }) .filter((promise) => !!promise) ) - .then((requests) => { - const newState = requests.map((request, index) => { - if (request && request.responseXML != null) { - const key = keyArray[index]; - const result: any = extractFilesData(request.responseXML); - const sortedResult = sortBy(result, (n) => n.name).sort((n1, n2) => { - if (n1.type === 'directory' && n2.type !== 'directory') { - return -1; - } - if (n1.type !== 'directory' && n2.type === 'directory') { - return 1; - } - return 0; - }); - - return { [key]: sortedResult }; - } - return {}; - }).reduce((prev, next) => { - return { ...next, ...prev }; - }, {}); + .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) => { + if (n1.type === 'directory' && n2.type !== 'directory') { + return -1; + } + if (n1.type !== 'directory' && n2.type === 'directory') { + return 1; + } + return 0; + }); - setPathData({ ...pathData, ...newState }); - }) - .finally(() => { - setIsLoading(false); - keyArray.forEach(key => delete pathPromise[key]); - }); + return { [key]: sortedResult }; + } + return {}; + }).reduce((prev, next) => { + return { ...next, ...prev }; + }, {}); + + setPathData({ ...pathData, ...newState }); + }) + .finally(() => { + setIsLoading(false); + keyArray.forEach(key => delete pathPromise[key]); + }); }; React.useEffect(() => { if (rightKey) { + console.log('---> useEffect rightKey:', rightKey); fetchData(rightKey); setLeftSearch(''); setRightSearch(''); } }, [rightKey]); // eslint-disable-line react-hooks/exhaustive-deps + const currentPDH = (collectionPanel.item || {}).portableDataHash; React.useEffect(() => { - const hash = (collectionPanel.item || {}).portableDataHash; - - if (hash && collectionAutofetchEnabled) { - fetchData([leftKey, rightKey], true); + 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); + } } - }, [(collectionPanel.item || {}).portableDataHash]); // eslint-disable-line react-hooks/exhaustive-deps + }, [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); } @@ -316,10 +337,6 @@ export const CollectionPanelFiles = withStyles(styles)(connect((state: RootState if (id) { onItemMenuOpen(event, item, isWritable); - - if (!collectionAutofetchEnabled) { - setCollectionAutofetchEnabled(true); - } } }, [onItemMenuOpen, isWritable, rightData] // eslint-disable-line react-hooks/exhaustive-deps @@ -329,6 +346,7 @@ export const CollectionPanelFiles = withStyles(styles)(connect((state: RootState let node = null; if (parentRef && parentRef.current) { + console.log('---> useEffect parentRef:', parentRef); node = parentRef.current; (node as any).addEventListener('contextmenu', handleRightClick); } @@ -426,44 +444,45 @@ export const CollectionPanelFiles = withStyles(styles)(connect((state: RootState [props.onOptionsMenuOpen] // eslint-disable-line react-hooks/exhaustive-deps ); - return ( -
-
-
- { - path - .map((p: string, index: number) => - {index === 0 ? 'Home' : p} /  - ) - } -
- - { - if (!collectionAutofetchEnabled) { - setCollectionAutofetchEnabled(true); - } - onOptionsMenuOpen(ev, isWritable); - }}> - + return
+
+
+ { path.map((p: string, index: number) => + {index === 0 ? 'Home' : p} /  + ) } +
+ + { + onOptionsMenuOpen(ev, isWritable); + }}> + + + +
+
+
1 ? classes.leftPanelVisible : classes.leftPanelHidden)} data-cy="collection-files-left-panel"> + 1 ? classes.backButton : classes.backButtonHidden}> + setPath([...path.slice(0, path.length -1)])}> +
-
1 ? classes.leftPanelVisible : classes.leftPanelHidden)}> +
1 ? classes.leftPanelVisible : classes.leftPanelHidden)} data-cy="collection-files-left-panel"> 1 ? classes.backButton : classes.backButtonHidden}> setPath([...path.slice(0, path.length -1)])}>
1 ? classes.searchWrapper : classes.searchWrapperHidden}> - +
{ @@ -490,7 +509,7 @@ export const CollectionPanelFiles = withStyles(styles)(connect((state: RootState data-parent-path={name} className={classNames(classes.row, getActiveClass(name))} key={id}> - {getItemIcon(type, getActiveClass(name))} + {getItemIcon(type, getActiveClass(name))}
{name}
@@ -508,9 +527,9 @@ export const CollectionPanelFiles = withStyles(styles)(connect((state: RootState
-
+
- +
{ isWritable && @@ -518,10 +537,7 @@ export const CollectionPanelFiles = withStyles(styles)(connect((state: RootState className={classes.uploadButton} data-cy='upload-button' onClick={() => { - if (!collectionAutofetchEnabled) { - setCollectionAutofetchEnabled(true); - } - onUploadDataClick(); + onUploadDataClick(rightKey === leftKey ? undefined : rightKey); }} variant='contained' color='primary' @@ -537,44 +553,81 @@ export const CollectionPanelFiles = withStyles(styles)(connect((state: RootState {({ height, width }) => { const filtered = rightData.filter(({ name }) => name.indexOf(rightSearch) > -1); - return !!filtered.length ? - { - ({ index, style }) => { - const { id, type, name, size } = filtered[index]; - - return
-   - {getItemIcon(type, null)}
- {name} -
- - {formatFileSize(size)} - -
- } - } -
:
No data available
- }} - :
- } -
+ return !!filtered.length + ? { ({ index, style }) => { + console.log("Left Data ROW: ", filtered[index]); + const { id, type, name } = filtered[index]; + + return
+ { getItemIcon(type, getActiveClass(name)) } +
+ {name} +
+ { getActiveClass(name) + ? + : null } +
; + } }
+ :
No directories available
+ } } + :
+ +
} +
+
+
+
+ +
+ { isWritable && + } +
{ rightData && !isLoading + ? {({ height, width }) => { + const filtered = rightData.filter(({ name }) => name.indexOf(rightSearch) > -1); + console.log("Right Data: ", filtered); + + return !!filtered.length + ? { ({ index, style }) => { + console.log("Right Data ROW: ", filtered[index]); + const { id, type, name, size } = filtered[index]; + + return
+   + {getItemIcon(type, null)} +
+ {name} +
+ + { formatFileSize(size) } + +
+ } }
+ :
This collection is empty
+ }}
+ :
+ +
}
- ); -})); +
}));