diff --git a/src/components/Files/FileTable.jsx b/src/components/Files/FileTable.jsx new file mode 100644 index 00000000..6a6a43bf --- /dev/null +++ b/src/components/Files/FileTable.jsx @@ -0,0 +1,206 @@ +import React, {Component} from 'react'; +import {connect} from 'react-redux'; +import Obstruction from 'obstruction'; + +import {withStyles, Divider, Typography, Button, Modal, Paper} from '@material-ui/core'; +import {DataGrid} from '@mui/x-data-grid'; + +import DownloadIcon from '@material-ui/icons/FileDownload'; +import Colors from '../../colors'; +import Theme from '../../theme'; +import ResizeHandler from '../ResizeHandler'; + +const styles = (theme) => ({ + modal: { + position: 'absolute', + padding: theme.spacing.unit * 2, + width: 'max-content', + maxWidth: '90%', + left: '50%', + top: '50%', + transform: 'translate(-50%, -50%)', + outline: 'none', + }, + titleContainer: { + display: 'flex', + justifyContent: 'space-between', + alignItems: 'baseline', + marginBottom: 5, + }, + titleIcon: { + marginRight: 8, + }, + buttonGroup: { + textAlign: 'right', + }, + uploadContainer: { + margin: `${theme.spacing.unit}px 0`, + color: Colors.white90, + textAlign: 'left', + overflowY: 'auto', + }, + uploadButton: { + color: Colors.white, + borderRadius: 13, + fontSize: '0.8rem', + padding: '4px 12px', + minHeight: 19, + backgroundColor: Colors.white05, + '&:hover': { + backgroundColor: Colors.white10, + }, + }, + dataGrid: { + border: 'none', + '& .MuiDataGrid-row': { + color: theme.palette.common.white, + '--DataGrid-row-border-color': 'transparent', + }, + '& .MuiDataGrid-columnHeader': { + backgroundColor: theme.palette.grey[300], + color: theme.palette.common.white, + textAlign: 'center', + }, + '& .MuiDataGrid-columnHeaderTitle': { + lineSpacing: 1.5, + whiteSpace: 'normal', + }, + '& .MuiDataGrid-footerContainer': { + color: theme.palette.common.white, + borderColor: theme.palette.common.white, + }, + '& .MuiTablePagination-root, & .MuiTablePagination-selectIcon': { + color: theme.palette.common.white, + }, + '& .MuiDataGrid-cell:focus, & .MuiDataGrid-cell:focus-within': { + outline: 'none', + }, + }, +}); + + +const FILE_NAMES = { + qcameras: { filename: 'qcamera.ts', label: "Road Camera (Lo-Res)" }, + cameras: { filename: 'fcamera.hevc', label: 'Road Camera' }, + dcameras: { filename: 'dcamera.hevc', label: "Driver Camera" }, + ecameras: { filename: 'ecamera.hevc', label: "Wide Road Camera" }, + qlogs: { filename: 'qlog.bz2', label: 'Logs (Decimated)' }, + logs: { filename: 'rlog.bz2', label: 'Logs' }, +}; + +class FileTable extends Component { + constructor(props) { + super(props); + + this.state = { + windowWidth: window.innerWidth, + windowHeight: window.innerHeight + }; + } + + getSegmentIndex(segmentName) { + return segmentName.split("--").slice(-1)[0] + } + + filesToRows(files) { + if (files) { + const segments = {}; + for (let [key, data] of Object.entries(files)) { + const [segment, file_type] = key.split("/"); + segments[segment] = { ...segments[segment], ...{ [file_type]: data.url } }; + } + + const sortedSegments = Object.entries(segments).sort((a, b) => { + // Sort the entries by segment number + const aSegmentIndex = parseInt(this.getSegmentIndex(a[0])); + const bSegmentIndex = parseInt(this.getSegmentIndex(b[0])); + if (aSegmentIndex < bSegmentIndex) return -1; + if (aSegmentIndex > bSegmentIndex) return 1; + return 0; + }); + + const rows = [] + + for (let [segmentName, segmentFiles] of sortedSegments) { + rows.push({ + id: this.getSegmentIndex(segmentName), + segmentName: segmentName, + ...segmentFiles + }); + } + + return rows; + } + } + + render() { + const { classes, currentRoute, files } = this.props; + const { windowWidth, windowHeight } = this.state; + + const columns = [ + { field: 'id', headerName: "#", type: 'number', width: 5 }, + { field: 'segmentName', headerName: 'Segment', width: 325 }, + ]; + + columns.push(...Object.entries(FILE_NAMES).map(([key, { filename, label }]) => { + return { + field: key, + headerName: label, + headerAlign: 'center', + align: 'center', + display: 'flex', + minWidth: label.includes("Camera") ? 120 : 100, + sortable: false, + filterable: false, + renderCell: (params) => ( + + ), + } + })); + columns.slice(-1)[0].width = null; + columns.slice(-1)[0].flex = 1; + + const rows = this.filesToRows(files); + + return ( + <> + this.setState({ windowWidth: ww, windowHeight: wh })}/> + + +
+ Route Files + {currentRoute.fullname} +
+ +
+ + params.indexRelativeToCurrentPage % 2 === 0 ? 'even' : 'odd' + } + sx={styles(Theme).dataGrid} + /> +
+
+ +
+
+
+ + ); + } +} + +const stateToProps = Obstruction({ + files: 'files', + currentRoute: 'currentRoute' +}); + +export default connect(stateToProps)(withStyles(styles)(FileTable));