From 22821296e913d4be63d4a40c33e7c28c5582cdd5 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Daniel=20Kuty=C5=82a?= Date: Fri, 11 Sep 2020 20:50:24 +0200 Subject: [PATCH] 16243: Added filtering for collection files MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Arvados-DCO-1.1-Signed-off-by: Daniel Kutyła --- .../collection-panel-files.tsx | 116 ++++++++++++------ .../collection-panel-files-actions.ts | 1 + .../collection-panel-files-reducer.ts | 19 ++- .../collection-panel-files.ts | 5 +- 4 files changed, 98 insertions(+), 43 deletions(-) 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>; @@ -16,6 +18,7 @@ export interface CollectionPanelFilesProps { isLoading: boolean; tooManyFiles: boolean; onUploadDataClick: () => 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; @@ -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 = theme => ({ root: { @@ -34,7 +37,18 @@ const styles: StyleRulesCallback = 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 = theme => ({ }, button: { marginRight: -theme.spacing.unit, - marginTop: '0px' + marginTop: '8px' }, centeredLabel: { fontSize: '0.875rem', @@ -55,52 +69,80 @@ const styles: StyleRulesCallback = theme => ({ }, }); + + export const CollectionPanelFiles = withStyles(styles)( - ({ onItemMenuOpen, onOptionsMenuOpen, onUploadDataClick, classes, - isWritable, isLoading, tooManyFiles, loadFilesFunc, ...treeProps }: CollectionPanelFilesProps & WithStyles) => - + ({ onItemMenuOpen, onSearchChange, onOptionsMenuOpen, onUploadDataClick, classes, + isWritable, isLoading, tooManyFiles, loadFilesFunc, ...treeProps }: CollectionPanelFilesProps & WithStyles) => { + const { useState, useEffect } = React; + const [searchValue, setSearchValue] = useState(''); + + useEffect(() => { + onSearchChange(searchValue); + }, [searchValue]); + + return ( + Files + + + } className={classes.cardSubheader} classes={{ action: classes.button }} action={<> {isWritable && - } {!tooManyFiles && - - onOptionsMenuOpen(ev, isWritable)}> - - - } + + onOptionsMenuOpen(ev, isWritable)}> + + + } - } /> - { tooManyFiles - ?
- File listing may take some time, please click to browse: -
- : <> - - - Name + } /> + {tooManyFiles + ?
+ File listing may take some time, please click to browse: +
+ : <> + + + Name - - File size + + File size - - { isLoading - ?
- :
onItemMenuOpen(ev, item, isWritable)} {...treeProps} />
} - +
+ {isLoading + ?
+ :
+ 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; + })} />
} + }
); + } + ); 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(), }); export type CollectionPanelFilesAction = UnionOf; 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 => ({ +const mapDispatchToProps = (dispatch: Dispatch): Pick => ({ onUploadDataClick: () => { dispatch(openUploadCollectionFilesDialog()); }, @@ -68,6 +68,9 @@ const mapDispatchToProps = (dispatch: Dispatch): Pick { + dispatch(collectionPanelFilesAction.ON_SEARCH_CHANGE(searchValue)); + }, onOptionsMenuOpen: (event, isWritable) => { dispatch(openCollectionFilesContextMenu(event, isWritable)); }, -- 2.30.2