diff --git a/.github/workflows/build-on-pr.yml b/.github/workflows/build-on-pr.yml
new file mode 100644
index 0000000..d4c2ba5
--- /dev/null
+++ b/.github/workflows/build-on-pr.yml
@@ -0,0 +1,25 @@
+name: Build on Pull Request
+
+on:
+ pull_request:
+ branches: ['main']
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+
+ - name: Set up Node.js
+ uses: actions/setup-node@v3
+ with:
+ node-version: '20' # Use the Node.js version you're working with
+ cache: 'npm' # Use the Node.js version you're working with
+
+ - name: Install dependencies
+ run: npm ci
+
+ - name: Build
+ run: npm run build
diff --git a/package-lock.json b/package-lock.json
index e6dc4b3..fb7752b 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -3857,11 +3857,10 @@
"license": "MIT"
},
"node_modules/cookie": {
- "version": "0.6.0",
- "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz",
- "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==",
+ "version": "0.7.1",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz",
+ "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==",
"dev": true,
- "license": "MIT",
"engines": {
"node": ">= 0.6"
}
@@ -4781,18 +4780,17 @@
}
},
"node_modules/express": {
- "version": "4.21.0",
- "resolved": "https://registry.npmjs.org/express/-/express-4.21.0.tgz",
- "integrity": "sha512-VqcNGcj/Id5ZT1LZ/cfihi3ttTn+NJmkli2eZADigjq29qTlWi/hAQ43t/VLPq8+UX06FCEx3ByOYet6ZFblng==",
+ "version": "4.21.1",
+ "resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz",
+ "integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==",
"dev": true,
- "license": "MIT",
"dependencies": {
"accepts": "~1.3.8",
"array-flatten": "1.1.1",
"body-parser": "1.20.3",
"content-disposition": "0.5.4",
"content-type": "~1.0.4",
- "cookie": "0.6.0",
+ "cookie": "0.7.1",
"cookie-signature": "1.0.6",
"debug": "2.6.9",
"depd": "2.0.0",
@@ -7321,7 +7319,6 @@
"version": "6.27.0",
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.27.0.tgz",
"integrity": "sha512-+bvtFWMC0DgAFrfKXKG9Fc+BcXWRUO1aJIihbB79xaeq0v5UzfvnM5houGUm1Y461WVRcgAQ+Clh5rdb1eCx4g==",
- "license": "MIT",
"dependencies": {
"@remix-run/router": "1.20.0",
"react-router": "6.27.0"
diff --git a/src/components/DataTable.tsx b/src/components/DataTable.tsx
index 2e7d999..133f598 100644
--- a/src/components/DataTable.tsx
+++ b/src/components/DataTable.tsx
@@ -57,7 +57,7 @@ export default function DataTable({
);
return (
-
+
0}
diff --git a/src/components/FileUpload.tsx b/src/components/FileUpload.tsx
new file mode 100644
index 0000000..fa86f4d
--- /dev/null
+++ b/src/components/FileUpload.tsx
@@ -0,0 +1,106 @@
+import React, { useState } from 'react';
+import { Modal, Button, Notification, FileInput } from '@mantine/core';
+import '@/css/FileUpload.css';
+
+interface FileUploadProps {
+ uploadUrl: string;
+}
+
+const FileUpload: React.FC = ({ uploadUrl }) => {
+ const [showModal, setShowModal] = useState(false);
+ const [selectedFiles, setSelectedFiles] = useState([]);
+ const [error, setError] = useState(null);
+
+ const handleFileChange = (files: File[]) => {
+ if (files.length > 0) {
+ setSelectedFiles((prevFiles) => [...prevFiles, ...files]);
+ }
+ };
+
+ const handleUpload = async () => {
+ if (selectedFiles.length > 0) {
+ const formData = new FormData();
+ selectedFiles.forEach((file) => {
+ formData.append('files', file);
+ });
+
+ try {
+ const response = await fetch(uploadUrl, {
+ method: 'POST',
+ body: formData,
+ });
+
+ if (!response.ok) {
+ setError('Upload failed. Network response was not ok.');
+ return;
+ }
+
+ const data = await response.json();
+ console.log('Upload successful:', data);
+
+ setSelectedFiles([]);
+ handleClose();
+ } catch (error) {
+ console.error('Upload failed:', error);
+ setError('An error occurred while uploading. Please try again.');
+ }
+ } else {
+ setError('Please select files to upload.');
+ }
+ };
+
+ const toggleModal = () => {
+ setShowModal(!showModal);
+ };
+
+ const handleClose = () => {
+ setShowModal(false);
+ setSelectedFiles([]);
+ setError(null);
+ };
+
+ return (
+
+
+
+
+
+
+ {selectedFiles.length > 0 && (
+
+
Chosen Files:
+
+ {selectedFiles.map((file, index) => (
+ - {file.name}
+ ))}
+
+
+ )}
+
+
+
+
+ {error && (
+ setError(null)} style={{ marginTop: 10 }}>
+ {error}
+
+ )}
+
+
+ );
+};
+
+export default FileUpload;
diff --git a/src/components/Navbar.tsx b/src/components/Navbar.tsx
index 4e0b40e..2b028c8 100644
--- a/src/components/Navbar.tsx
+++ b/src/components/Navbar.tsx
@@ -1,6 +1,7 @@
import "@mantine/core/styles.css";
import "@/css/Navbar.css";
import { NavLink } from "react-router-dom";
+import FileUpload from "@/components/FileUpload"
const mainLinksData = [
{ name: "Files", url: "/" },
@@ -25,6 +26,10 @@ export default function Navbar() {
className="navbar-icon"
/>
{links}
+
+ {/* Once POST API is out -- Currently WIP */}
+
+
{/* Optionally render active link or other content here */}
{hytechName}
diff --git a/src/components/PreviewCard.tsx b/src/components/PreviewCard.tsx
index 5a4976a..0a43646 100644
--- a/src/components/PreviewCard.tsx
+++ b/src/components/PreviewCard.tsx
@@ -226,7 +226,6 @@ export const SchemaTable = () => {
handleSearch(e.target.value);
}}
/>
-
{" "}
{/* Scrollable area with height limit */}
diff --git a/src/components/SchemaSearch.tsx b/src/components/SchemaSearch.tsx
new file mode 100644
index 0000000..9577c88
--- /dev/null
+++ b/src/components/SchemaSearch.tsx
@@ -0,0 +1,64 @@
+import React, { useState } from "react";
+import { Autocomplete, Button } from "@mantine/core";
+import "@/css/SchemaSearch.css";
+
+interface SchemaSearch {
+ schemas: string[];
+}
+
+const SchemaSearch: React.FC = ({ schemas }) => {
+ const [value, setValue] = useState("");
+ const [selectedSchema, setSelected] = useState([]);
+
+ const filteredSchemas = schemas.filter((schema) =>
+ schema.toLowerCase().includes(value.toLowerCase()),
+ );
+
+ const addSchema = (newSchema: string) => {
+ if (!selectedSchema.includes(newSchema)) {
+ setSelected([...selectedSchema, newSchema]);
+ } else {
+ alert("Schema already selected!");
+ }
+ };
+
+ const clearSchema = () => {
+ setSelected([]);
+ };
+
+ const handleKeyDown = (event: React.KeyboardEvent) => {
+ if (event.key === "Enter" && filteredSchemas.length > 0) {
+ setValue(filteredSchemas[0]);
+ addSchema(filteredSchemas[0]);
+ }
+ };
+
+ return (
+
+
+
+ {selectedSchema.length > 0 && (
+
+
+
+ {selectedSchema.map((str, index) => (
+ - {str}
+ ))}
+
+
+
+ )}
+
+ );
+};
+
+export default SchemaSearch;
diff --git a/src/components/SearchBar.tsx b/src/components/SearchBar.tsx
index ef6bde4..5b553d2 100644
--- a/src/components/SearchBar.tsx
+++ b/src/components/SearchBar.tsx
@@ -1,6 +1,7 @@
import React, { useState } from "react";
import { eventType, location } from "@/data/dataFilters";
import "@/css/SearchBar.css";
+import SchemaSearch from "@/components/SchemaSearch";
interface SearchBarWithFilterProps {
setFilteredData: React.Dispatch<
@@ -34,6 +35,8 @@ function SearchBarWithFilter({ setSearchFilters }: SearchBarWithFilterProps) {
// return true;
// };
+ const schemas = ["Schema1", "Schema2", "Schema3", "Schema4"];
+
// Filter logic
// const handleSearch = () => {
// const filtered = data.filter((item) => {
@@ -171,6 +174,8 @@ function SearchBarWithFilter({ setSearchFilters }: SearchBarWithFilterProps) {
placeholder="Filter by date"
/>
+
+
diff --git a/src/css/FileUpload.css b/src/css/FileUpload.css
new file mode 100644
index 0000000..d02a437
--- /dev/null
+++ b/src/css/FileUpload.css
@@ -0,0 +1,30 @@
+button {
+ padding: 10px 10px;
+ margin: 3px 3px;
+ border: none;
+ border-radius: 5px;
+ background-color: #b39e63;
+ color: white;
+ cursor: pointer;
+ transition: background-color 0.3s;
+}
+
+button:hover {
+ background-color: #d4bc79;
+}
+
+ul {
+ list-style-type: none;
+ padding: 0;
+}
+
+h3 {
+ margin-top: 20px;
+}
+
+.files {
+ display: flex;
+ flex-direction: column;
+ text-align: center;
+ justify-content: center;
+}
\ No newline at end of file
diff --git a/src/css/PreviewCard.css b/src/css/PreviewCard.css
index 7d0a795..2c4e75e 100644
--- a/src/css/PreviewCard.css
+++ b/src/css/PreviewCard.css
@@ -23,3 +23,11 @@
height: auto; /* Maintains aspect ratio */
margin: 20px;
}
+
+@media (max-width: 600px) {
+ .previewFileButtons {
+ display: flex;
+ flex-direction: column;
+
+ }
+ }
\ No newline at end of file
diff --git a/src/css/Root.css b/src/css/Root.css
index cfa9c85..ea633f3 100644
--- a/src/css/Root.css
+++ b/src/css/Root.css
@@ -8,18 +8,13 @@
background-color: #f0f0f0;
width: 100%;
position: fixed;
- /*so table doesn't cover it - make sure it stays on top of other elements*/
z-index: 1000;
}
-.search-bar {
- background-color: #e0e0e0;
- border-radius: 0;
-}
-
.main-content {
display: flex;
flex: 1;
+ overflow: hidden;
height: 500px;
padding-top: 50px;
flex-direction: column;
@@ -27,12 +22,19 @@
.results-container {
display: flex;
+ flex: 1;
+ overflow: hidden;
flex-direction: row;
}
+.table-contain-result {
+ flex-grow: 1;
+ overflow-y: auto;
+ padding-bottom: 10px;
+ }
+
.footer {
text-align: center;
background: #9b8b5de5;
color: white;
}
-
diff --git a/src/css/SchemaSearch.css b/src/css/SchemaSearch.css
new file mode 100644
index 0000000..b0ccd00
--- /dev/null
+++ b/src/css/SchemaSearch.css
@@ -0,0 +1,10 @@
+.schema-autocomplete {
+ padding: 10px;
+ border-radius: 10px;
+ border: 1px solid #ddd;
+ background-color: #fff;
+ }
+.cancel-button {
+ background-color: #978750;
+
+}
\ No newline at end of file
diff --git a/src/css/SearchBar.css b/src/css/SearchBar.css
index 8e18898..d0cb8a7 100644
--- a/src/css/SearchBar.css
+++ b/src/css/SearchBar.css
@@ -1,27 +1,8 @@
-.results-container {
- flex: 1;
- display: flex;
- flex-direction: column;
- outline-color: #DEE2E6;
- outline-width: 2px;
- outline-style: solid;
-}
-
-
-.table-contain-result {
- text-align: center;
- flex: 1;
-}
-
-.preview-contain-result {
- text-align: center;
-}
-
.Search {
display: flex;
max-width: 360px;
font-size: 15px;
-
+ overflow: auto;
}
diff --git a/src/data/sampledata.ts b/src/data/sampledata.ts
index 2cf53ba..7f40535 100644
--- a/src/data/sampledata.ts
+++ b/src/data/sampledata.ts
@@ -13,6 +13,62 @@ export const data: MCAPFileInformation[] = [
notes: "car ran!",
event_type: "acceleration",
},
+ {
+ id: "0723984238489-21312-4e75e6f76",
+ mcap_file_name: "file5.3.mcap",
+ matlab_file_name: "file5.3.mat",
+ aws_bucket: "bucket",
+ mcap_path: "/path/to/s3/object",
+ mat_path: "/path/to/s3/object",
+ vn_lat_lon_path: "/path/to/s3/object",
+ velocity_plot_path: "/path/to/s3/object",
+ date: "08-16-2024",
+ location: "rome",
+ notes: "car performed nice",
+ event_type: "autocross",
+ },
+ {
+ id: "091823792-2321312-a081",
+ mcap_file_name: "file7.1.mcap",
+ matlab_file_name: "file7.1.mat",
+ aws_bucket: "bucket",
+ mcap_path: "/path/to/s3/object",
+ mat_path: "/path/to/s3/object",
+ vn_lat_lon_path: "/path/to/s3/object",
+ velocity_plot_path: "/path/to/s3/object",
+ date: "08-29-2024",
+ location: "MRDC",
+ notes: "car did jk turn on",
+ event_type: null,
+ },
+ {
+ id: "07a0sdjwne-597f-4637-8b61-6134e75e6f76",
+ mcap_file_name: "file2.3.mcap",
+ matlab_file_name: "file2.3.mat",
+ aws_bucket: "bucket",
+ mcap_path: "/path/to/s3/object",
+ mat_path: "/path/to/s3/object",
+ vn_lat_lon_path: "/path/to/s3/object",
+ velocity_plot_path: "/path/to/s3/object",
+ date: "08-16-2024",
+ location: "rome",
+ notes: "car did not latch",
+ event_type: "autocross",
+ },
+ {
+ id: "605deb4b-44a8-4801-9da6-a671c1d3eccd",
+ mcap_file_name: "file1.3.mcap",
+ matlab_file_name: "file1.3.mat",
+ aws_bucket: "bucket",
+ mcap_path: "/path/to/s3/object",
+ mat_path: "/path/to/s3/object",
+ vn_lat_lon_path: "/path/to/s3/object",
+ velocity_plot_path: "/path/to/s3/object",
+ date: "08-22-2024",
+ location: "MRDC",
+ notes: "car failed",
+ event_type: "acceleration",
+ },
{
id: "fb48f265-a44a-4fd5-a873-26cd581950a0",
mcap_file_name: "file2.mcap",
@@ -96,4 +152,4 @@ export const data: MCAPFileInformation[] = [
location: "MRDC",
notes: "car did not turn on",
},
-];
+];
\ No newline at end of file