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 { CustomStyleRulesCallback } from 'common/custom-theme';
+import { WithStyles } from '@mui/styles';
+import withStyles from '@mui/styles/withStyles';
import { ArvadosTheme } from 'common/custom-theme';
+import { ResourceKind } from 'models/resource';
+import { CollectionFileType } from 'models/collection-file';
+import { DefaultView } from 'components/default-view/default-view';
+import { ProjectDetailsComponent } from 'views-components/details-panel/project-details';
+import { CollectionDetailsAttributes } from 'views/collection-panel/collection-panel';
+import { RootProjectDetailsComponent } from 'views-components/details-panel/root-project-details';
+import { DetailsAttribute } from 'components/details-attribute/details-attribute';
+import { formatFileSize } from 'common/formatters';
export interface ToplevelPickerProps {
- currentUuid?: string;
+ currentUuids?: string[];
pickerId: string;
+ cascadeSelection: boolean;
includeCollections?: boolean;
includeDirectories?: boolean;
includeFiles?: boolean;
const { search } = getProjectsTreePickerIds(props.pickerId);
return {
...props,
- projectSearch: state.treePickerSearch.projectSearchValues[search],
+ projectSearch: state.treePickerSearch.projectSearchValues[search] || state.treePickerSearch.collectionFilterValues[search],
collectionFilter: state.treePickerSearch.collectionFilterValues[search],
};
};
}
};
-type CssRules = 'pickerHeight' | 'searchFlex' | 'scrolledBox';
+type CssRules = 'pickerHeight' | 'searchFlex' | 'scrolledBox' | 'detailsBox' | 'twoCol';
-const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
+const styles: CustomStyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
pickerHeight: {
height: "100%",
- display: "flex",
- flexDirection: "column",
},
searchFlex: {
display: "flex",
justifyContent: "space-around",
- paddingBottom: "1em"
+ height: "64px",
},
scrolledBox: {
- overflow: "scroll"
+ overflow: "scroll",
+ width: "calc(100% - 320px)",
+ marginRight: "8px",
+ height: "100%",
+ },
+ twoCol: {
+ display: "flex",
+ flexDirection: "row",
+ height: "calc(100% - 64px)",
+ },
+ detailsBox: {
+ width: "320px",
+ height: "100%",
+ overflow: "scroll",
+ borderLeft: "1px solid rgba(0, 0, 0, 0.12)",
+ paddingLeft: "4px",
}
});
type ProjectsTreePickerCombinedProps = ToplevelPickerProps & ProjectsTreePickerSearchProps & ProjectsTreePickerActionProps & DispatchProp & WithStyles<CssRules>;
+interface SelectionComponentState {
+ activeItem?: ProjectsTreePickerItem;
+}
+
+const Details = (props: { res?: ProjectsTreePickerItem }) => {
+ if (props.res) {
+ if ('kind' in props.res) {
+ switch (props.res.kind) {
+ case ResourceKind.PROJECT:
+ return <ProjectDetailsComponent project={props.res} hideEdit={true} />
+ case ResourceKind.COLLECTION:
+ return <CollectionDetailsAttributes item={props.res} />;
+ case ResourceKind.USER:
+ return <RootProjectDetailsComponent rootProject={props.res} />;
+ // case ResourceKind.PROCESS:
+ // return new ProcessDetails(res);
+ // case ResourceKind.WORKFLOW:
+ // return new WorkflowDetails(res);
+ }
+ } else if ('type' in props.res) {
+ if (props.res.type === CollectionFileType.FILE) {
+ return <>
+ <DetailsAttribute label='Type' value="File" />
+ <DetailsAttribute label='Size' value={formatFileSize(props.res.size)} />
+ </>;
+ } else {
+ return <DetailsAttribute label='Type' value="Directory" />
+ }
+ }
+ }
+ return <DefaultView messages={['Select a file or folder to view its details.']} />;
+};
+
+
export const ProjectsTreePicker = connect(mapStateToProps, mapDispatchToProps)(
withStyles(styles)(
class FileInputComponent extends React.Component<ProjectsTreePickerCombinedProps> {
+ state: SelectionComponentState = {
+ };
componentDidMount() {
const { home, shared, favorites, publicFavorites, search } = getProjectsTreePickerIds(this.props.pickerId);
- this.props.dispatch<any>(initProjectsTreePicker(this.props.pickerId, this.props.currentUuid));
+ 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<any>(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(treePickerActions.RESET_TREE_PICKER({ pickerId: publicFavorites }));
}
+ setSelection(event: React.MouseEvent<HTMLElement>,
+ item: TreeItem<ProjectsTreePickerItem>,
+ pickerId: string) {
+ this.setState({activeItem: item.data});
+ console.log(item.data);
+ }
+
render() {
const pickerId = this.props.pickerId;
const onProjectSearch = this.props.onProjectSearch;
const { home, shared, favorites, publicFavorites, search } = getProjectsTreePickerIds(pickerId);
const relatedTreePickers = getRelatedTreePickers(pickerId);
+ const _this = this;
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,
+ toggleItemActive: (event: React.MouseEvent<HTMLElement>,
+ item: TreeItem<ProjectsTreePickerItem>,
+ pickerId: string): void => {
+ _this.setSelection(event, item, pickerId);
+ if (_this.props.toggleItemActive) {
+ _this.props.toggleItemActive(event, item, pickerId);
+ }
+ },
toggleItemSelection: this.props.toggleItemSelection,
relatedTreePickers,
disableActivation,
};
- return <div className={this.props.classes.pickerHeight} >
- <span className={this.props.classes.searchFlex}>
- <SearchInput value="" label="Search for a Project" selfClearProp='' onSearch={onProjectSearch} debounce={500} />
- {this.props.includeCollections &&
- <SearchInput value="" label="Filter Collections list in Projects" selfClearProp='' onSearch={onCollectionFilter} debounce={500} />}
- </span>
+
+ return <>
+ <div className={this.props.classes.searchFlex}>
+ <span data-cy="picker-dialog-project-search"><SearchInput value="" label="Project search" selfClearProp='' onSearch={onProjectSearch} debounce={500} width="18rem" /></span>
+ {this.props.includeCollections &&
+ <span data-cy="picker-dialog-collection-search" ><SearchInput value="" label="Collection search" selfClearProp='' onSearch={onCollectionFilter} debounce={500} width="18rem" /></span>}
+ </div>
+
+ <div className={this.props.classes.twoCol}>
<div className={this.props.classes.scrolledBox}>
{this.props.projectSearch ?
- <div data-cy="projects-tree-search-picker">
- <SearchProjectsPicker {...p} pickerId={search} />
- </div>
- :
- <>
- <div data-cy="projects-tree-home-tree-picker">
- <HomeTreePicker {...p} pickerId={home} />
- </div>
- <div data-cy="projects-tree-shared-tree-picker">
- <SharedTreePicker {...p} pickerId={shared} />
- </div>
- <div data-cy="projects-tree-public-favourites-tree-picker">
- <PublicFavoritesTreePicker {...p} pickerId={publicFavorites} />
- </div>
- <div data-cy="projects-tree-favourites-tree-picker">
- <FavoritesTreePicker {...p} pickerId={favorites} />
- </div>
- </>}
+ <div data-cy="projects-tree-search-picker">
+ <SearchProjectsPicker {...p} pickerId={search} />
+ </div>
+ :
+ <>
+ <div data-cy="projects-tree-home-tree-picker">
+ <HomeTreePicker {...p} pickerId={home} />
+ </div>
+ <div data-cy="projects-tree-shared-tree-picker">
+ <SharedTreePicker {...p} pickerId={shared} />
+ </div>
+ <div data-cy="projects-tree-public-favourites-tree-picker">
+ <PublicFavoritesTreePicker {...p} pickerId={publicFavorites} />
+ </div>
+ <div data-cy="projects-tree-favourites-tree-picker">
+ <FavoritesTreePicker {...p} pickerId={favorites} />
+ </div>
+ </>}
+ </div>
+
+ <div className={this.props.classes.detailsBox} data-cy="picker-dialog-details">
+ <Details res={this.state.activeItem} />
</div>
- </div >;
+ </div>
+ </>;
}
- }));
+}));
const getRelatedTreePickers = pipe(getProjectsTreePickerIds, values);
const disableActivation = [SHARED_PROJECT_ID, FAVORITES_PROJECT_ID];