Skip to content

Commit

Permalink
Merge pull request #414 from AutomatingSciencePipeline/340-add-report…
Browse files Browse the repository at this point in the history
…-button

340 - Added Report Button & Filename for an Experiment Downloaded
  • Loading branch information
rhit-windsors authored Jan 22, 2025
2 parents 9161766 + 7f75f4f commit f7b40aa
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 5 deletions.
25 changes: 22 additions & 3 deletions apps/frontend/app/dashboard/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,14 @@ import { signOut, useSession } from "next-auth/react";
import toast, { Toaster } from 'react-hot-toast';
import { useRouter, useSearchParams } from 'next/navigation';

const GLADOS_DOCS_LINK = 'https://automatingsciencepipeline.github.io/Monorepo/tutorial/usage/'
const REPORT_GOOGLE_FORM_LINK = 'https://docs.google.com/forms/d/1sLjV6x_R8C80mviEcrZv9wiDPe5nOxt47g_pE_7xCyE';
const GLADOS_DOCS_LINK = 'https://automatingsciencepipeline.github.io/Monorepo/tutorial/usage/';

const REPORT_DESCRIPT = 'Report an issue you have encountered to our Google Forms.';
const HELP_DESCRIPT = 'Open the GLADOS docs to learn how to use the application.';

const navigation = [
{ name: 'Report', href: REPORT_GOOGLE_FORM_LINK, current: false },
{ name: 'Help', href: GLADOS_DOCS_LINK, current: false }
];
const userNavigation = [
Expand Down Expand Up @@ -91,9 +96,16 @@ const Navbar = (props) => {
<a
key={item.name}
href={item.href}
target={item.name === 'Help' ? '_blank' : '_self'}
target={['Help', 'Report'].includes(item.name) ? '_blank' : '_self'}
className='px-3 py-2 rounded-md text-sm font-medium text-blue-200 hover:text-white'
aria-current={item.current ? 'page' : undefined}
title={
item.name === 'Help'
? HELP_DESCRIPT
: item.name === 'Report'
? REPORT_DESCRIPT
: ''
}
>
{item.name}
</a>
Expand Down Expand Up @@ -164,14 +176,21 @@ const Navbar = (props) => {
key={item.name}
as='a'
href={item.href}
target={item.name === 'Help' ? '_blank' : '_self'}
target={['Help', 'Report'].includes(item.name) ? '_blank' : '_self'}
className={classNames(
item.current ?
'text-white bg-blue-800' :
'text-blue-200 hover:text-blue-100 hover:bg-blue-600',
'block px-3 py-2 rounded-md text-base font-medium'
)}
aria-current={item.current ? 'page' : undefined}
title={
item.name === 'Help'
? HELP_DESCRIPT
: item.name === 'Report'
? REPORT_DESCRIPT
: ''
}
>
{item.name}
</Disclosure.Button>
Expand Down
35 changes: 33 additions & 2 deletions apps/frontend/lib/db.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/* eslint-disable no-mixed-spaces-and-tabs */
import { ExperimentData } from './db_types';
import { ResultsCsv, ProjectZip } from '../lib/mongodb_types';
import {getDocumentFromId} from "./mongodb_funcs";

export const DB_COLLECTION_EXPERIMENTS = 'Experiments';

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

const formatFilename = (name: string, timestamp: string, extension: string) => {
const formattedName = name.replace(/[^a-zA-Z0-9-_]/g, '_');
const formattedTimestamp = formatTimestamp(timestamp);
return `${formattedName}=>${formattedTimestamp}.${extension}`;
};

const formatTimestamp = (timestamp: string) => {
const partiallyFormattedTimestamp = new Date(timestamp).toISOString().replace(/[:.]/g, '-');
let formatted = partiallyFormattedTimestamp.replace(/Z$/, '');
formatted = formatted.replace('T', '_');
const [date, time] = formatted.split('_');
const timeParts = time.split('-');
let hours = parseInt(timeParts[0], 10) - 5;
timeParts[0] = hours.toString();
const formattedTime = timeParts.join('-');
return `${date}_${formattedTime}`;
};

export const downloadExperimentResults = async (expId: string) => {
console.log(`Downloading results for ${expId}...`);

const expDoc = await getDocumentFromId(expId);
const expName = expDoc['name'];
const expCreated = expDoc['created'];

await fetch(`/api/download/csv/${expId}`).then((response) => {
if (response?.ok) {
return response.json();
Expand All @@ -42,7 +66,8 @@ export const downloadExperimentResults = async (expId: string) => {
console.log(record);
const csvContents = record.resultContent;
const url = `data:text/plain;charset=utf-8,${encodeURIComponent(csvContents)}`;
downloadArbitraryFile(url, `result${expId}.csv`);
const filename = formatFilename(expName, expCreated, 'csv');
downloadArbitraryFile(url, filename);
}).catch((response: Response) => {
console.warn('Error downloading results', response.status);
response.json().then((json: any) => {
Expand All @@ -57,6 +82,11 @@ export const downloadExperimentResults = async (expId: string) => {

export const downloadExperimentProjectZip = async (expId: string) => {
console.log(`Downloading project zip for ${expId}...`);

const expDoc = await getDocumentFromId(expId);
const expName = expDoc['name'];
const expCreated = expDoc['created'];

await fetch(`/api/download/zip/${expId}`).then((response) => {
if (response?.ok) {
return response.json();
Expand All @@ -66,7 +96,8 @@ export const downloadExperimentProjectZip = async (expId: string) => {
console.log(record);
const zipContents = record.fileContent;
const url = `data:text/plain;base64,${encodeURIComponent(zipContents)}`;
downloadArbitraryFile(url, `project_${expId}.zip`);
const filename = formatFilename(expName, expCreated, 'zip');
downloadArbitraryFile(url, filename);
}).catch((response: Response) => {
console.warn('Error downloading results', response.status);
response.json().then((json: any) => {
Expand Down

0 comments on commit f7b40aa

Please sign in to comment.