X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/fc84a3f3932af503d3afd04a58af52270c8fc3b6..099468843d687fdc8c6fbb0f0e3dc54f59d0de15:/src/views-components/projects-tree-picker/projects-tree-picker.tsx diff --git a/src/views-components/projects-tree-picker/projects-tree-picker.tsx b/src/views-components/projects-tree-picker/projects-tree-picker.tsx index ee8ce1d5ea..16f6cceb71 100644 --- a/src/views-components/projects-tree-picker/projects-tree-picker.tsx +++ b/src/views-components/projects-tree-picker/projects-tree-picker.tsx @@ -3,18 +3,31 @@ // SPDX-License-Identifier: AGPL-3.0 import React from 'react'; -import { values, memoize, pipe } from 'lodash/fp'; +import { Dispatch } from 'redux'; +import { connect, DispatchProp } from 'react-redux'; +import { RootState } from 'store/store'; +import { values, pipe } from 'lodash/fp'; import { HomeTreePicker } from 'views-components/projects-tree-picker/home-tree-picker'; import { SharedTreePicker } from 'views-components/projects-tree-picker/shared-tree-picker'; import { FavoritesTreePicker } from 'views-components/projects-tree-picker/favorites-tree-picker'; -import { getProjectsTreePickerIds, SHARED_PROJECT_ID, FAVORITES_PROJECT_ID } from 'store/tree-picker/tree-picker-actions'; +import { SearchProjectsPicker } from 'views-components/projects-tree-picker/search-projects-picker'; +import { + getProjectsTreePickerIds, treePickerActions, treePickerSearchActions, initProjectsTreePicker, + SHARED_PROJECT_ID, FAVORITES_PROJECT_ID +} from 'store/tree-picker/tree-picker-actions'; import { TreeItem } from 'components/tree/tree'; -import { ProjectsTreePickerItem } from './generic-projects-tree-picker'; +import { ProjectsTreePickerItem } from 'store/tree-picker/tree-picker-middleware'; import { PublicFavoritesTreePicker } from './public-favorites-tree-picker'; +import { SearchInput } from 'components/search-input/search-input'; +import { withStyles, StyleRulesCallback, WithStyles } from '@material-ui/core'; +import { ArvadosTheme } from 'common/custom-theme'; -export interface ProjectsTreePickerProps { +export interface ToplevelPickerProps { + currentUuids?: string[]; pickerId: string; + cascadeSelection: boolean; includeCollections?: boolean; + includeDirectories?: boolean; includeFiles?: boolean; showSelection?: boolean; options?: { showOnlyOwned: boolean, showOnlyWritable: boolean }; @@ -22,29 +35,155 @@ export interface ProjectsTreePickerProps { toggleItemSelection?: (event: React.MouseEvent, item: TreeItem, pickerId: string) => void; } -export const ProjectsTreePicker = ({ pickerId, ...props }: ProjectsTreePickerProps) => { - const { home, shared, favorites, publicFavorites } = getProjectsTreePickerIds(pickerId); - const relatedTreePickers = getRelatedTreePickers(pickerId); - const p = { +interface ProjectsTreePickerSearchProps { + projectSearch: string; + collectionFilter: string; +} + +interface ProjectsTreePickerActionProps { + onProjectSearch: (value: string) => void; + onCollectionFilter: (value: string) => void; +} + +const mapStateToProps = (state: RootState, props: ToplevelPickerProps): ProjectsTreePickerSearchProps => { + const { search } = getProjectsTreePickerIds(props.pickerId); + return { ...props, - relatedTreePickers, - disableActivation + projectSearch: state.treePickerSearch.projectSearchValues[search], + collectionFilter: state.treePickerSearch.collectionFilterValues[search], + }; +}; + +const mapDispatchToProps = (dispatch: Dispatch, props: ToplevelPickerProps): (ProjectsTreePickerActionProps & DispatchProp) => { + const { home, shared, favorites, publicFavorites, search } = getProjectsTreePickerIds(props.pickerId); + const params = { + includeCollections: props.includeCollections, + includeDirectories: props.includeDirectories, + includeFiles: props.includeFiles, + options: props.options }; - return
-
- -
-
- -
-
- -
-
- -
-
; + dispatch(treePickerSearchActions.SET_TREE_PICKER_LOAD_PARAMS({ pickerId: home, params })); + dispatch(treePickerSearchActions.SET_TREE_PICKER_LOAD_PARAMS({ pickerId: shared, params })); + dispatch(treePickerSearchActions.SET_TREE_PICKER_LOAD_PARAMS({ pickerId: favorites, params })); + dispatch(treePickerSearchActions.SET_TREE_PICKER_LOAD_PARAMS({ pickerId: publicFavorites, params })); + dispatch(treePickerSearchActions.SET_TREE_PICKER_LOAD_PARAMS({ pickerId: search, params })); + + return { + onProjectSearch: (projectSearchValue: string) => dispatch(treePickerSearchActions.SET_TREE_PICKER_PROJECT_SEARCH({ pickerId: search, projectSearchValue })), + onCollectionFilter: (collectionFilterValue: string) => { + dispatch(treePickerSearchActions.SET_TREE_PICKER_COLLECTION_FILTER({ pickerId: home, collectionFilterValue })); + dispatch(treePickerSearchActions.SET_TREE_PICKER_COLLECTION_FILTER({ pickerId: shared, collectionFilterValue })); + dispatch(treePickerSearchActions.SET_TREE_PICKER_COLLECTION_FILTER({ pickerId: favorites, collectionFilterValue })); + dispatch(treePickerSearchActions.SET_TREE_PICKER_COLLECTION_FILTER({ pickerId: publicFavorites, collectionFilterValue })); + dispatch(treePickerSearchActions.SET_TREE_PICKER_COLLECTION_FILTER({ pickerId: search, collectionFilterValue })); + }, + dispatch + } }; -const getRelatedTreePickers = memoize(pipe(getProjectsTreePickerIds, values)); +type CssRules = 'pickerHeight' | 'searchFlex' | 'scrolledBox'; + +const styles: StyleRulesCallback = (theme: ArvadosTheme) => ({ + pickerHeight: { + height: "100%", + display: "flex", + flexDirection: "column", + }, + searchFlex: { + display: "flex", + justifyContent: "space-around", + paddingBottom: "1em" + }, + scrolledBox: { + overflow: "scroll" + } +}); + +type ProjectsTreePickerCombinedProps = ToplevelPickerProps & ProjectsTreePickerSearchProps & ProjectsTreePickerActionProps & DispatchProp & WithStyles; + +export const ProjectsTreePicker = connect(mapStateToProps, mapDispatchToProps)( + withStyles(styles)( + class FileInputComponent extends React.Component { + + componentDidMount() { + const { home, shared, favorites, publicFavorites, search } = getProjectsTreePickerIds(this.props.pickerId); + + const preloadParams = this.props.currentUuids ? { + selectedItemUuids: this.props.currentUuids, + includeDirectories: !!this.props.includeDirectories, + includeFiles: !!this.props.includeFiles, + multi: !!this.props.showSelection, + } : undefined; + this.props.dispatch(initProjectsTreePicker(this.props.pickerId, preloadParams)); + + this.props.dispatch(treePickerSearchActions.SET_TREE_PICKER_PROJECT_SEARCH({ pickerId: search, projectSearchValue: "" })); + this.props.dispatch(treePickerSearchActions.SET_TREE_PICKER_COLLECTION_FILTER({ pickerId: search, collectionFilterValue: "" })); + this.props.dispatch(treePickerSearchActions.SET_TREE_PICKER_COLLECTION_FILTER({ pickerId: home, collectionFilterValue: "" })); + this.props.dispatch(treePickerSearchActions.SET_TREE_PICKER_COLLECTION_FILTER({ pickerId: shared, collectionFilterValue: "" })); + this.props.dispatch(treePickerSearchActions.SET_TREE_PICKER_COLLECTION_FILTER({ pickerId: favorites, collectionFilterValue: "" })); + this.props.dispatch(treePickerSearchActions.SET_TREE_PICKER_COLLECTION_FILTER({ pickerId: publicFavorites, collectionFilterValue: "" })); + } + + componentWillUnmount() { + const { home, shared, favorites, publicFavorites, search } = getProjectsTreePickerIds(this.props.pickerId); + // Release all the state, we don't need it to hang around forever. + this.props.dispatch(treePickerActions.RESET_TREE_PICKER({ pickerId: search })); + this.props.dispatch(treePickerActions.RESET_TREE_PICKER({ pickerId: home })); + this.props.dispatch(treePickerActions.RESET_TREE_PICKER({ pickerId: shared })); + this.props.dispatch(treePickerActions.RESET_TREE_PICKER({ pickerId: favorites })); + this.props.dispatch(treePickerActions.RESET_TREE_PICKER({ pickerId: publicFavorites })); + } + + render() { + const pickerId = this.props.pickerId; + const onProjectSearch = this.props.onProjectSearch; + const onCollectionFilter = this.props.onCollectionFilter; + + const { home, shared, favorites, publicFavorites, search } = getProjectsTreePickerIds(pickerId); + const relatedTreePickers = getRelatedTreePickers(pickerId); + const p = { + cascadeSelection: this.props.cascadeSelection, + includeCollections: this.props.includeCollections, + includeDirectories: this.props.includeDirectories, + includeFiles: this.props.includeFiles, + showSelection: this.props.showSelection, + options: this.props.options, + toggleItemActive: this.props.toggleItemActive, + toggleItemSelection: this.props.toggleItemSelection, + relatedTreePickers, + disableActivation, + }; + return
+ + + {this.props.includeCollections && + } + + +
+ {this.props.projectSearch ? +
+ +
+ : + <> +
+ +
+
+ +
+
+ +
+
+ +
+ } +
+
; + } + })); + +const getRelatedTreePickers = pipe(getProjectsTreePickerIds, values); const disableActivation = [SHARED_PROJECT_ID, FAVORITES_PROJECT_ID];