Skip to content

Commit f7b40aa

Browse files
Merge pull request #414 from AutomatingSciencePipeline/340-add-report-button
340 - Added Report Button & Filename for an Experiment Downloaded
2 parents 9161766 + 7f75f4f commit f7b40aa

File tree

2 files changed

+55
-5
lines changed

2 files changed

+55
-5
lines changed

apps/frontend/app/dashboard/page.tsx

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,14 @@ import { signOut, useSession } from "next-auth/react";
2727
import toast, { Toaster } from 'react-hot-toast';
2828
import { useRouter, useSearchParams } from 'next/navigation';
2929

30-
const GLADOS_DOCS_LINK = 'https://automatingsciencepipeline.github.io/Monorepo/tutorial/usage/'
30+
const REPORT_GOOGLE_FORM_LINK = 'https://docs.google.com/forms/d/1sLjV6x_R8C80mviEcrZv9wiDPe5nOxt47g_pE_7xCyE';
31+
const GLADOS_DOCS_LINK = 'https://automatingsciencepipeline.github.io/Monorepo/tutorial/usage/';
32+
33+
const REPORT_DESCRIPT = 'Report an issue you have encountered to our Google Forms.';
34+
const HELP_DESCRIPT = 'Open the GLADOS docs to learn how to use the application.';
3135

3236
const navigation = [
37+
{ name: 'Report', href: REPORT_GOOGLE_FORM_LINK, current: false },
3338
{ name: 'Help', href: GLADOS_DOCS_LINK, current: false }
3439
];
3540
const userNavigation = [
@@ -91,9 +96,16 @@ const Navbar = (props) => {
9196
<a
9297
key={item.name}
9398
href={item.href}
94-
target={item.name === 'Help' ? '_blank' : '_self'}
99+
target={['Help', 'Report'].includes(item.name) ? '_blank' : '_self'}
95100
className='px-3 py-2 rounded-md text-sm font-medium text-blue-200 hover:text-white'
96101
aria-current={item.current ? 'page' : undefined}
102+
title={
103+
item.name === 'Help'
104+
? HELP_DESCRIPT
105+
: item.name === 'Report'
106+
? REPORT_DESCRIPT
107+
: ''
108+
}
97109
>
98110
{item.name}
99111
</a>
@@ -164,14 +176,21 @@ const Navbar = (props) => {
164176
key={item.name}
165177
as='a'
166178
href={item.href}
167-
target={item.name === 'Help' ? '_blank' : '_self'}
179+
target={['Help', 'Report'].includes(item.name) ? '_blank' : '_self'}
168180
className={classNames(
169181
item.current ?
170182
'text-white bg-blue-800' :
171183
'text-blue-200 hover:text-blue-100 hover:bg-blue-600',
172184
'block px-3 py-2 rounded-md text-base font-medium'
173185
)}
174186
aria-current={item.current ? 'page' : undefined}
187+
title={
188+
item.name === 'Help'
189+
? HELP_DESCRIPT
190+
: item.name === 'Report'
191+
? REPORT_DESCRIPT
192+
: ''
193+
}
175194
>
176195
{item.name}
177196
</Disclosure.Button>

apps/frontend/lib/db.ts

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/* eslint-disable no-mixed-spaces-and-tabs */
22
import { ExperimentData } from './db_types';
33
import { ResultsCsv, ProjectZip } from '../lib/mongodb_types';
4+
import {getDocumentFromId} from "./mongodb_funcs";
45

56
export const DB_COLLECTION_EXPERIMENTS = 'Experiments';
67

@@ -31,8 +32,31 @@ const downloadArbitraryFile = (url: string, name: string) => {
3132
document.body.removeChild(anchor);
3233
};
3334

35+
const formatFilename = (name: string, timestamp: string, extension: string) => {
36+
const formattedName = name.replace(/[^a-zA-Z0-9-_]/g, '_');
37+
const formattedTimestamp = formatTimestamp(timestamp);
38+
return `${formattedName}=>${formattedTimestamp}.${extension}`;
39+
};
40+
41+
const formatTimestamp = (timestamp: string) => {
42+
const partiallyFormattedTimestamp = new Date(timestamp).toISOString().replace(/[:.]/g, '-');
43+
let formatted = partiallyFormattedTimestamp.replace(/Z$/, '');
44+
formatted = formatted.replace('T', '_');
45+
const [date, time] = formatted.split('_');
46+
const timeParts = time.split('-');
47+
let hours = parseInt(timeParts[0], 10) - 5;
48+
timeParts[0] = hours.toString();
49+
const formattedTime = timeParts.join('-');
50+
return `${date}_${formattedTime}`;
51+
};
52+
3453
export const downloadExperimentResults = async (expId: string) => {
3554
console.log(`Downloading results for ${expId}...`);
55+
56+
const expDoc = await getDocumentFromId(expId);
57+
const expName = expDoc['name'];
58+
const expCreated = expDoc['created'];
59+
3660
await fetch(`/api/download/csv/${expId}`).then((response) => {
3761
if (response?.ok) {
3862
return response.json();
@@ -42,7 +66,8 @@ export const downloadExperimentResults = async (expId: string) => {
4266
console.log(record);
4367
const csvContents = record.resultContent;
4468
const url = `data:text/plain;charset=utf-8,${encodeURIComponent(csvContents)}`;
45-
downloadArbitraryFile(url, `result${expId}.csv`);
69+
const filename = formatFilename(expName, expCreated, 'csv');
70+
downloadArbitraryFile(url, filename);
4671
}).catch((response: Response) => {
4772
console.warn('Error downloading results', response.status);
4873
response.json().then((json: any) => {
@@ -57,6 +82,11 @@ export const downloadExperimentResults = async (expId: string) => {
5782

5883
export const downloadExperimentProjectZip = async (expId: string) => {
5984
console.log(`Downloading project zip for ${expId}...`);
85+
86+
const expDoc = await getDocumentFromId(expId);
87+
const expName = expDoc['name'];
88+
const expCreated = expDoc['created'];
89+
6090
await fetch(`/api/download/zip/${expId}`).then((response) => {
6191
if (response?.ok) {
6292
return response.json();
@@ -66,7 +96,8 @@ export const downloadExperimentProjectZip = async (expId: string) => {
6696
console.log(record);
6797
const zipContents = record.fileContent;
6898
const url = `data:text/plain;base64,${encodeURIComponent(zipContents)}`;
69-
downloadArbitraryFile(url, `project_${expId}.zip`);
99+
const filename = formatFilename(expName, expCreated, 'zip');
100+
downloadArbitraryFile(url, filename);
70101
}).catch((response: Response) => {
71102
console.warn('Error downloading results', response.status);
72103
response.json().then((json: any) => {

0 commit comments

Comments
 (0)