[ARVADOS-WORKBENCH2] created: 1.4.1-424-g22821296
Git user
git at public.arvados.org
Fri Sep 11 18:51:41 UTC 2020
at 22821296e913d4be63d4a40c33e7c28c5582cdd5 (commit)
commit 22821296e913d4be63d4a40c33e7c28c5582cdd5
Author: Daniel Kutyła <daniel.kutyla at contractors.roche.com>
Date: Fri Sep 11 20:50:24 2020 +0200
16243: Added filtering for collection files
Arvados-DCO-1.1-Signed-off-by: Daniel Kutyła <daniel.kutyla at contractors.roche.com>
diff --git a/src/components/collection-panel-files/collection-panel-files.tsx b/src/components/collection-panel-files/collection-panel-files.tsx
index c7db48c4..f9c24b62 100644
--- a/src/components/collection-panel-files/collection-panel-files.tsx
+++ b/src/components/collection-panel-files/collection-panel-files.tsx
@@ -6,9 +6,11 @@ import * as React from 'react';
import { TreeItem, TreeItemStatus } from '~/components/tree/tree';
import { FileTreeData } from '~/components/file-tree/file-tree-data';
import { FileTree } from '~/components/file-tree/file-tree';
+import { CollectionFileType } from "~/models/collection-file";
import { IconButton, Grid, Typography, StyleRulesCallback, withStyles, WithStyles, CardHeader, Card, Button, Tooltip, CircularProgress } from '@material-ui/core';
import { CustomizeTableIcon } from '~/components/icon/icon';
import { DownloadIcon } from '~/components/icon/icon';
+import { SearchInput } from '../search-input/search-input';
export interface CollectionPanelFilesProps {
items: Array<TreeItem<FileTreeData>>;
@@ -16,6 +18,7 @@ export interface CollectionPanelFilesProps {
isLoading: boolean;
tooManyFiles: boolean;
onUploadDataClick: () => void;
+ onSearchChange: (searchValue: string) => void;
onItemMenuOpen: (event: React.MouseEvent<HTMLElement>, item: TreeItem<FileTreeData>, isWritable: boolean) => void;
onOptionsMenuOpen: (event: React.MouseEvent<HTMLElement>, isWritable: boolean) => void;
onSelectionToggle: (event: React.MouseEvent<HTMLElement>, item: TreeItem<FileTreeData>) => void;
@@ -25,7 +28,7 @@ export interface CollectionPanelFilesProps {
currentItemUuid?: string;
}
-type CssRules = 'root' | 'cardSubheader' | 'nameHeader' | 'fileSizeHeader' | 'uploadIcon' | 'button' | 'centeredLabel';
+type CssRules = 'root' | 'cardSubheader' | 'nameHeader' | 'fileSizeHeader' | 'uploadIcon' | 'button' | 'centeredLabel' | 'cardHeaderContent' | 'cardHeaderContentTitle';
const styles: StyleRulesCallback<CssRules> = theme => ({
root: {
@@ -34,7 +37,18 @@ const styles: StyleRulesCallback<CssRules> = theme => ({
},
cardSubheader: {
paddingTop: 0,
- paddingBottom: 0
+ paddingBottom: 0,
+ minHeight: 8 * theme.spacing.unit,
+ },
+ cardHeaderContent: {
+ display: 'flex',
+ paddingRight: 2 * theme.spacing.unit,
+ justifyContent: 'space-between',
+ },
+ cardHeaderContentTitle: {
+ paddingLeft: theme.spacing.unit,
+ paddingTop: 2 * theme.spacing.unit,
+ paddingRight: 2 * theme.spacing.unit,
},
nameHeader: {
marginLeft: '75px'
@@ -47,7 +61,7 @@ const styles: StyleRulesCallback<CssRules> = theme => ({
},
button: {
marginRight: -theme.spacing.unit,
- marginTop: '0px'
+ marginTop: '8px'
},
centeredLabel: {
fontSize: '0.875rem',
@@ -55,52 +69,80 @@ const styles: StyleRulesCallback<CssRules> = theme => ({
},
});
+
+
export const CollectionPanelFiles =
withStyles(styles)(
- ({ onItemMenuOpen, onOptionsMenuOpen, onUploadDataClick, classes,
- isWritable, isLoading, tooManyFiles, loadFilesFunc, ...treeProps }: CollectionPanelFilesProps & WithStyles<CssRules>) =>
- <Card data-cy='collection-files-panel' className={classes.root}>
+ ({ onItemMenuOpen, onSearchChange, onOptionsMenuOpen, onUploadDataClick, classes,
+ isWritable, isLoading, tooManyFiles, loadFilesFunc, ...treeProps }: CollectionPanelFilesProps & WithStyles<CssRules>) => {
+ const { useState, useEffect } = React;
+ const [searchValue, setSearchValue] = useState('');
+
+ useEffect(() => {
+ onSearchChange(searchValue);
+ }, [searchValue]);
+
+ return (<Card data-cy='collection-files-panel' className={classes.root}>
<CardHeader
- title="Files"
+ title={
+ <div className={classes.cardHeaderContent}>
+ <span className={classes.cardHeaderContentTitle}>Files</span>
+ <SearchInput
+ value={searchValue}
+ onSearch={setSearchValue} />
+ </div>
+ }
className={classes.cardSubheader}
classes={{ action: classes.button }}
action={<>
{isWritable &&
- <Button
- data-cy='upload-button'
- onClick={onUploadDataClick}
- variant='contained'
- color='primary'
- size='small'>
- <DownloadIcon className={classes.uploadIcon} />
+ <Button
+ data-cy='upload-button'
+ onClick={onUploadDataClick}
+ variant='contained'
+ color='primary'
+ size='small'>
+ <DownloadIcon className={classes.uploadIcon} />
Upload data
</Button>}
{!tooManyFiles &&
- <Tooltip title="More options" disableFocusListener>
- <IconButton
- data-cy='collection-files-panel-options-btn'
- onClick={(ev) => onOptionsMenuOpen(ev, isWritable)}>
- <CustomizeTableIcon />
- </IconButton>
- </Tooltip>}
+ <Tooltip title="More options" disableFocusListener>
+ <IconButton
+ data-cy='collection-files-panel-options-btn'
+ onClick={(ev) => onOptionsMenuOpen(ev, isWritable)}>
+ <CustomizeTableIcon />
+ </IconButton>
+ </Tooltip>}
</>
- } />
- { tooManyFiles
- ? <div className={classes.centeredLabel}>
- File listing may take some time, please click to browse: <Button onClick={loadFilesFunc}><DownloadIcon/>Show files</Button>
- </div>
- : <>
- <Grid container justify="space-between">
- <Typography variant="caption" className={classes.nameHeader}>
- Name
+ } />
+ {tooManyFiles
+ ? <div className={classes.centeredLabel}>
+ File listing may take some time, please click to browse: <Button onClick={loadFilesFunc}><DownloadIcon />Show files</Button>
+ </div>
+ : <>
+ <Grid container justify="space-between">
+ <Typography variant="caption" className={classes.nameHeader}>
+ Name
</Typography>
- <Typography variant="caption" className={classes.fileSizeHeader}>
- File size
+ <Typography variant="caption" className={classes.fileSizeHeader}>
+ File size
</Typography>
- </Grid>
- { isLoading
- ? <div className={classes.centeredLabel}><CircularProgress /></div>
- : <div style={{height: 'calc(100% - 60px)'}}><FileTree onMenuOpen={(ev, item) => onItemMenuOpen(ev, item, isWritable)} {...treeProps} /></div> }
- </>
+ </Grid>
+ {isLoading
+ ? <div className={classes.centeredLabel}><CircularProgress /></div>
+ : <div style={{ height: 'calc(100% - 60px)' }}>
+ <FileTree
+ onMenuOpen={(ev, item) => onItemMenuOpen(ev, item, isWritable)}
+ {...treeProps}
+ items={treeProps.items.filter((item) => {
+ if (item.data.type === CollectionFileType.FILE) {
+ return item.data.name.toLowerCase().indexOf(searchValue.toLowerCase()) > -1;
+ }
+
+ return true;
+ })} /></div>}
+ </>
}
</Card>);
+ }
+ );
diff --git a/src/store/collection-panel/collection-panel-files/collection-panel-files-actions.ts b/src/store/collection-panel/collection-panel-files/collection-panel-files-actions.ts
index 204d4c0e..704e2999 100644
--- a/src/store/collection-panel/collection-panel-files/collection-panel-files-actions.ts
+++ b/src/store/collection-panel/collection-panel-files/collection-panel-files-actions.ts
@@ -22,6 +22,7 @@ export const collectionPanelFilesAction = unionize({
TOGGLE_COLLECTION_FILE_SELECTION: ofType<{ id: string }>(),
SELECT_ALL_COLLECTION_FILES: ofType<{}>(),
UNSELECT_ALL_COLLECTION_FILES: ofType<{}>(),
+ ON_SEARCH_CHANGE: ofType<string>(),
});
export type CollectionPanelFilesAction = UnionOf<typeof collectionPanelFilesAction>;
diff --git a/src/store/collection-panel/collection-panel-files/collection-panel-files-reducer.ts b/src/store/collection-panel/collection-panel-files/collection-panel-files-reducer.ts
index 08a71759..01f41f0e 100644
--- a/src/store/collection-panel/collection-panel-files/collection-panel-files-reducer.ts
+++ b/src/store/collection-panel/collection-panel-files/collection-panel-files-reducer.ts
@@ -12,21 +12,30 @@ export const collectionPanelFilesReducer = (state: CollectionPanelFilesState = c
// for performance reasons, so we pass a copy of 'state' to avoid side effects.
return collectionPanelFilesAction.match(action, {
SET_COLLECTION_FILES: files =>
- mergeCollectionPanelFilesStates({...state}, mapTree(mapCollectionFileToCollectionPanelFile)(files)),
+ mergeCollectionPanelFilesStates({ ...state }, mapTree(mapCollectionFileToCollectionPanelFile)(files)),
TOGGLE_COLLECTION_FILE_COLLAPSE: data =>
- toggleCollapse(data.id)({...state}),
+ toggleCollapse(data.id)({ ...state }),
- TOGGLE_COLLECTION_FILE_SELECTION: data => [{...state}]
+ TOGGLE_COLLECTION_FILE_SELECTION: data => [{ ...state }]
.map(toggleSelected(data.id))
.map(toggleAncestors(data.id))
.map(toggleDescendants(data.id))[0],
+ ON_SEARCH_CHANGE: (data) =>
+ mapTreeValues((v: CollectionPanelDirectory | CollectionPanelFile) => {
+ if (v.type === CollectionFileType.DIRECTORY) {
+ return ({ ...v, collapsed: data.length === 0 });
+ }
+
+ return ({ ...v });
+ })({ ...state }),
+
SELECT_ALL_COLLECTION_FILES: () =>
- mapTreeValues(v => ({ ...v, selected: true }))({...state}),
+ mapTreeValues(v => ({ ...v, selected: true }))({ ...state }),
UNSELECT_ALL_COLLECTION_FILES: () =>
- mapTreeValues(v => ({ ...v, selected: false }))({...state}),
+ mapTreeValues(v => ({ ...v, selected: false }))({ ...state }),
default: () => state
}) as CollectionPanelFilesState;
diff --git a/src/views-components/collection-panel-files/collection-panel-files.ts b/src/views-components/collection-panel-files/collection-panel-files.ts
index 79970003..9859f84b 100644
--- a/src/views-components/collection-panel-files/collection-panel-files.ts
+++ b/src/views-components/collection-panel-files/collection-panel-files.ts
@@ -44,7 +44,7 @@ const memoizedMapStateToProps = () => {
};
};
-const mapDispatchToProps = (dispatch: Dispatch): Pick<CollectionPanelFilesProps, 'onFileClick' | 'onUploadDataClick' | 'onCollapseToggle' | 'onSelectionToggle' | 'onItemMenuOpen' | 'onOptionsMenuOpen'> => ({
+const mapDispatchToProps = (dispatch: Dispatch): Pick<CollectionPanelFilesProps, 'onSearchChange' | 'onFileClick' | 'onUploadDataClick' | 'onCollapseToggle' | 'onSelectionToggle' | 'onItemMenuOpen' | 'onOptionsMenuOpen'> => ({
onUploadDataClick: () => {
dispatch<any>(openUploadCollectionFilesDialog());
},
@@ -68,6 +68,9 @@ const mapDispatchToProps = (dispatch: Dispatch): Pick<CollectionPanelFilesProps,
}
));
},
+ onSearchChange: (searchValue: string) => {
+ dispatch(collectionPanelFilesAction.ON_SEARCH_CHANGE(searchValue));
+ },
onOptionsMenuOpen: (event, isWritable) => {
dispatch<any>(openCollectionFilesContextMenu(event, isWritable));
},
-----------------------------------------------------------------------
hooks/post-receive
--
More information about the arvados-commits
mailing list