metadata-based-explorer1
Version:
Box UI Elements
136 lines (116 loc) • 4.23 kB
Flow
/**
* @flow
* @file Item list component
* @author Box
*/
import React from 'react';
import classNames from 'classnames';
import { injectIntl } from 'react-intl';
import MultiGrid from 'react-virtualized/dist/es/MultiGrid/MultiGrid';
import AutoSizer from 'react-virtualized/dist/es/AutoSizer';
import { getFileExtension } from '../../utils/file';
import FileIcon from '../../icons/file-icon';
import '../../elements/content-explorer/ItemList.scss';
import './MetadataBasedItemList.scss';
type Props = {
currentCollection: Collection,
metadataColumnsToShow: Array<string>,
};
type CellRendererArgs = {
columnIndex: number,
key: string,
rowIndex: number,
style: Object,
};
const FILENAME_COLUMN_WIDTH = 350;
const METADATA_MIN_COLUMN_WIDTH = 250;
let itemCollection;
let metadataColumns;
const getFileIcon = (filename: string = '') => {
const ext = getFileExtension(filename);
return ext ? <FileIcon dimension={32} extension={ext} /> : <FileIcon dimension={32} />;
};
const getColumnWidth = width => {
const availableWidth = width - FILENAME_COLUMN_WIDTH;
// Maintain min column width, else occupy the rest of the space equally
const mdColumnWidth = Math.max(availableWidth / metadataColumns.length, METADATA_MIN_COLUMN_WIDTH);
return ({ index }) => {
return index === 0 ? 350 : mdColumnWidth;
};
};
const getGridHeader = columnIndex => {
if (columnIndex === 0) {
// fixed column filename header
return <span>Name</span>;
}
return <span>{metadataColumns[columnIndex - 1]}</span>;
};
const getGridCell = (columnIndex, rowIndex) => {
const items = itemCollection.items;
const item = items[rowIndex];
if (columnIndex === 0) {
// fixed column for filename
return (
<div className="mv-grid-cell-fileinfo">
{getFileIcon(item.name)}
<span>{item.name}</span>
</div>
);
}
const { metadata = {} } = items[rowIndex];
const { data } = metadata;
const mdFieldName = metadataColumns[columnIndex - 1];
return <div>{data[mdFieldName]}</div>;
};
const cellRenderer = ({ columnIndex, key, rowIndex, style }: CellRendererArgs) => {
if (rowIndex === 0) {
// Render Header
const displayName = getGridHeader(columnIndex);
const headerClass = classNames('mv-column-header', { 'mv-column-header-filename': columnIndex === 0 });
return (
<button className={headerClass} type="button" style={style}>
{displayName}
</button>
);
}
// Render data
const cellData = getGridCell(columnIndex, rowIndex - 1);
return (
<div key={key} className="mv-grid-cell" style={style}>
{cellData}
</div>
);
};
const MetadataBasedItemList = ({ currentCollection, metadataColumnsToShow }: Props) => {
const rowCount = currentCollection.items ? currentCollection.items.length : 0;
itemCollection = currentCollection;
metadataColumns = metadataColumnsToShow;
return (
<AutoSizer>
{({ width, height }) => (
<div className="mv-item-grid">
<MultiGrid
cellRenderer={cellRenderer}
classNameBottomLeftGrid="mv-bottom-left-grid"
classNameTopLeftGrid="mv-top-left-grid"
classNameTopRightGrid="mv-top-right-grid"
columnCount={metadataColumnsToShow.length + 1}
columnWidth={getColumnWidth(width)}
enableFixedColumnScroll
fixedColumnCount={1}
fixedRowCount={1}
height={height}
hideBottomLeftGridScrollbar
hideTopRightGridScrollbar
rowCount={rowCount + 1}
rowHeight={50}
scrollToColumn={0}
scrollToRow={0}
width={width}
/>
</div>
)}
</AutoSizer>
);
};
export default injectIntl(MetadataBasedItemList);