items: Array<TreeItem<FileTreeData>>;
isWritable: boolean;
isLoading: boolean;
+ tooManyFiles: boolean;
onUploadDataClick: () => 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;
onCollapseToggle: (id: string, status: TreeItemStatus) => void;
onFileClick: (id: string) => void;
+ loadFilesFunc: () => void;
currentItemUuid?: string;
}
export const CollectionPanelFiles =
withStyles(styles)(
({ onItemMenuOpen, onOptionsMenuOpen, onUploadDataClick, classes,
- isWritable, isLoading, ...treeProps }: CollectionPanelFilesProps & WithStyles<CssRules>) =>
+ isWritable, isLoading, tooManyFiles, loadFilesFunc, ...treeProps }: CollectionPanelFilesProps & WithStyles<CssRules>) =>
<Card data-cy='collection-files-panel' className={classes.root}>
<CardHeader
title="Files"
Upload data
</Button>
} />
- <CardHeader
- className={classes.cardSubheader}
- action={
- <Tooltip title="More options" disableFocusListener>
- <IconButton
- data-cy='collection-files-panel-options-btn'
- onClick={(ev) => onOptionsMenuOpen(ev, isWritable)}>
- <CustomizeTableIcon />
- </IconButton>
- </Tooltip>
- } />
- <Grid container justify="space-between">
- <Typography variant="caption" className={classes.nameHeader}>
- Name
- </Typography>
- <Typography variant="caption" className={classes.fileSizeHeader}>
- File size
- </Typography>
- </Grid>
- { isLoading
- ? <div className={classes.centeredLabel}>(loading files...)</div>
- : <FileTree onMenuOpen={(ev, item) => onItemMenuOpen(ev, item, isWritable)} {...treeProps} /> }
+ { tooManyFiles
+ ? <div className={classes.centeredLabel}>
+ File listing may take some time, please click to browse: <Button onClick={loadFilesFunc}><DownloadIcon/>Show files</Button>
+ </div>
+ : <>
+ <CardHeader
+ className={classes.cardSubheader}
+ action={
+ <Tooltip title="More options" disableFocusListener>
+ <IconButton
+ data-cy='collection-files-panel-options-btn'
+ onClick={(ev) => onOptionsMenuOpen(ev, isWritable)}>
+ <CustomizeTableIcon />
+ </IconButton>
+ </Tooltip>
+ } />
+ <Grid container justify="space-between">
+ <Typography variant="caption" className={classes.nameHeader}>
+ Name
+ </Typography>
+ <Typography variant="caption" className={classes.fileSizeHeader}>
+ File size
+ </Typography>
+ </Grid>
+ { isLoading
+ ? <div className={classes.centeredLabel}>(loading files...)</div>
+ : <FileTree onMenuOpen={(ev, item) => onItemMenuOpen(ev, item, isWritable)} {...treeProps} /> }
+ </>
+ }
</Card>);
// SPDX-License-Identifier: AGPL-3.0
import { Dispatch } from "redux";
-import { loadCollectionFiles } from "./collection-panel-files/collection-panel-files-actions";
+import { loadCollectionFiles, COLLECTION_PANEL_LOAD_FILES_THRESHOLD } from "./collection-panel-files/collection-panel-files-actions";
import { CollectionResource } from '~/models/collection';
import { collectionPanelFilesAction } from "./collection-panel-files/collection-panel-files-actions";
import { createTree } from "~/models/tree";
export const collectionPanelActions = unionize({
SET_COLLECTION: ofType<CollectionResource>(),
LOAD_COLLECTION: ofType<{ uuid: string }>(),
- LOAD_COLLECTION_SUCCESS: ofType<{ item: CollectionResource }>()
+ LOAD_COLLECTION_SUCCESS: ofType<{ item: CollectionResource }>(),
+ LOAD_BIG_COLLECTIONS: ofType<boolean>(),
});
export type CollectionPanelAction = UnionOf<typeof collectionPanelActions>;
dispatch(loadDetailsPanel(collection.uuid));
dispatch(collectionPanelActions.LOAD_COLLECTION_SUCCESS({ item: collection }));
dispatch(resourcesActions.SET_RESOURCES([collection]));
- dispatch<any>(loadCollectionFiles(collection.uuid));
+ if (collection.fileCount <= COLLECTION_PANEL_LOAD_FILES_THRESHOLD &&
+ !getState().collectionPanel.loadBigCollections) {
+ dispatch<any>(loadCollectionFiles(collection.uuid));
+ }
return collection;
};
export type CollectionPanelFilesAction = UnionOf<typeof collectionPanelFilesAction>;
export const COLLECTION_PANEL_LOAD_FILES = 'collectionPanelLoadFiles';
+export const COLLECTION_PANEL_LOAD_FILES_THRESHOLD = 40000;
export const loadCollectionFiles = (uuid: string) =>
async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
export interface CollectionPanelState {
item: CollectionResource | null;
+ loadBigCollections: boolean;
}
const initialState = {
- item: null
+ item: null,
+ loadBigCollections: false,
};
export const collectionPanelReducer = (state: CollectionPanelState = initialState, action: CollectionPanelAction) =>
collectionPanelActions.match(action, {
default: () => state,
- SET_COLLECTION: (item) => ({ ...state, item }),
- LOAD_COLLECTION_SUCCESS: ({ item }) => ({ ...state, item })
+ SET_COLLECTION: (item) => ({
+ ...state,
+ item,
+ loadBigCollections: false,
+ }),
+ LOAD_COLLECTION_SUCCESS: ({ item }) => ({ ...state, item }),
+ LOAD_BIG_COLLECTIONS: (loadBigCollections) => ({ ...state, loadBigCollections}),
});
import { CollectionResource } from '~/models/collection';
import { CollectionPanelFiles } from '~/views-components/collection-panel-files/collection-panel-files';
import { CollectionTagForm } from './collection-tag-form';
-import { deleteCollectionTag, navigateToProcess } from '~/store/collection-panel/collection-panel-action';
+import { deleteCollectionTag, navigateToProcess, collectionPanelActions } from '~/store/collection-panel/collection-panel-action';
import { getResource } from '~/store/resources/resources';
import { openContextMenu } from '~/store/context-menu/context-menu-actions';
import { ContextMenuKind } from '~/views-components/context-menu/context-menu';
import { UserResource } from '~/models/user';
import { getUserUuid } from '~/common/getuser';
import { getProgressIndicator } from '~/store/progress-indicator/progress-indicator-reducer';
-import { COLLECTION_PANEL_LOAD_FILES } from '~/store/collection-panel/collection-panel-files/collection-panel-files-actions';
+import { COLLECTION_PANEL_LOAD_FILES, loadCollectionFiles, COLLECTION_PANEL_LOAD_FILES_THRESHOLD } from '~/store/collection-panel/collection-panel-files/collection-panel-files-actions';
type CssRules = 'card' | 'iconHeader' | 'tag' | 'label' | 'value' | 'link' | 'centeredLabel' | 'readOnlyIcon';
item: CollectionResource;
isWritable: boolean;
isLoadingFiles: boolean;
+ tooManyFiles: boolean;
}
type CollectionPanelProps = CollectionPanelDataProps & DispatchProp
}
const loadingFilesIndicator = getProgressIndicator(COLLECTION_PANEL_LOAD_FILES)(state.progressIndicator);
const isLoadingFiles = loadingFilesIndicator && loadingFilesIndicator!.working || false;
- return { item, isWritable, isLoadingFiles };
+ const tooManyFiles = !state.collectionPanel.loadBigCollections && item && item.fileCount > COLLECTION_PANEL_LOAD_FILES_THRESHOLD || false;
+ return { item, isWritable, isLoadingFiles, tooManyFiles };
})(
class extends React.Component<CollectionPanelProps> {
render() {
- const { classes, item, dispatch, isWritable, isLoadingFiles } = this.props;
+ const { classes, item, dispatch, isWritable, isLoadingFiles, tooManyFiles } = this.props;
return item
? <>
<Card data-cy='collection-info-panel' className={classes.card}>
</CardContent>
</Card>
<div className={classes.card}>
- <CollectionPanelFiles isWritable={isWritable} isLoading={isLoadingFiles} />
+ <CollectionPanelFiles
+ isWritable={isWritable}
+ isLoading={isLoadingFiles}
+ tooManyFiles={tooManyFiles}
+ loadFilesFunc={() => {
+ dispatch(collectionPanelActions.LOAD_BIG_COLLECTIONS(true));
+ dispatch<any>(loadCollectionFiles(this.props.item.uuid));
+ }
+ } />
</div>
</>
: null;