Skip to content

Commit

Permalink
feat(RV-417): Use local storage as fallback from api (#418)
Browse files Browse the repository at this point in the history
* feat(RV-417): Use local storage as fallback from api

* feat(RV-417): Use local storage as fallback from api

* feat(RV-417): Use local storage as fallback from api
  • Loading branch information
knguyenrise8 authored Nov 21, 2024
1 parent 15bfdac commit 2ff6aa4
Show file tree
Hide file tree
Showing 3 changed files with 157 additions and 65 deletions.
79 changes: 34 additions & 45 deletions frontend/e2e/App.spec.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
import { test, expect } from '@playwright/test';


test.beforeEach(async ({ page }) => {
await page.route("*/**/templates", async (route) => {
route.fulfill({});
})
});

test('has STLT Name', async ({ page }) => {

await page.goto('/');
Expand All @@ -24,45 +18,40 @@ test('has new template button', async ({ page , baseURL}) => {

test.describe('when templates exist', async () => {
test.beforeEach(async ({page}) => {
await page.route("*/**/templates", async (route) => {
route.fulfill({
status: 200,
body: JSON.stringify({
_embedded: {
templates: [
{
name: "MumpsQuestV1",
lab: "Quest",
createdBy: "J.Smith",
status: "Completed",
updatedAt: new Date(Date.parse("2025-03-24T12:00:00.000-05:00"))
},
{
name: "LBTIRadar",
lab: "Radar",
createdBy: "C.Alex",
status: "Completed",
updatedAt: new Date(Date.parse("2025-05-30T12:00:00.000-05:00"))
},
{
name: "COVIDBaylor1",
lab: "Emory",
createdBy: "A.Bryant",
status: "Completed",
updatedAt: new Date(Date.parse("2025-06-21T12:00:00.000-05:00"))
},
{
name: "COVIDEMory",
lab: "Baylor",
createdBy: "D.Smith",
status: "Completed",
updatedAt: new Date(Date.parse("2024-06-21T12:00:00.000-05:00"))
},
]
}
})
})
});
await page.goto('/')
await page.evaluate(() => {
const templates = [
{
name: "MumpsQuestV1",
lab: "Quest",
createdBy: "J.Smith",
status: "Completed",
lastUpdated: new Date(Date.parse("2025-03-24T12:00:00.000-05:00"))
},
{
name: "LBTIRadar",
lab: "Radar",
createdBy: "C.Alex",
status: "Completed",
lastUpdated: new Date(Date.parse("2025-05-30T12:00:00.000-05:00"))
},
{
name: "COVIDBaylor1",
lab: "Emory",
createdBy: "A.Bryant",
status: "Completed",
lastUpdated: new Date(Date.parse("2025-06-21T12:00:00.000-05:00"))
},
{
name: "COVIDEMory",
lab: "Baylor",
createdBy: "D.Smith",
status: "Completed",
lastUpdated: new Date(Date.parse("2024-06-21T12:00:00.000-05:00"))
},
];
localStorage.setItem('templates', JSON.stringify(templates))
})
})
test('displays list of templates if they exist and sorting functions', async ({page}) => {
await page.goto('/')
Expand Down
67 changes: 55 additions & 12 deletions frontend/src/components/ExtractUploadFile.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { ChangeEvent, useId, useState } from "react";
import React, { ChangeEvent, useEffect, useId, useState } from "react";
import { Button, Select } from "@trussworks/react-uswds";
import { useFiles } from "../contexts/FilesContext";
import { useNavigate } from "react-router-dom";
Expand All @@ -24,23 +24,23 @@ interface IFilesObj {
files: File[];
}

// interface Template {
// name: string;
// description: string;
// pages: {
// image: string;
// fieldNames: string[];
// }[];
// }
interface Template {
name: string;
description: string;
pages: {
image: string;
fieldNames: string[];
}[];
}

export const ExtractUploadFile: React.FC<ExtractUploadFileProps> = ({
onUploadComplete,
}) => {
const id = useId();
const { addFile, files, setSelectedTemplates, selectedTemplates , clearTemplates} = useFiles();
const { addFile, files, setSelectedTemplates, selectedTemplates , clearTemplates,} = useFiles();
const navigate = useNavigate();
// const [templates, setTemplates] = useState<Template[]>([]);
const templates = useQuery(
const [templates, setTemplates] = useState<Template[]>([]);
const _templates = useQuery(
{
queryKey: ['templates'],
queryFn: TemplateAPI.getTemplates
Expand All @@ -49,6 +49,49 @@ export const ExtractUploadFile: React.FC<ExtractUploadFileProps> = ({
const [isUploadComplete, setIsUploadComplete] = useState<boolean>(false);
const [uploadedFile, setUploadedFile] = useState<File[]>([]);

const loadTemplatesTestData = () => {
const sampleTemplates: Template[] = [
{
name: "Test Template COVID",
description: "This is the first sample template.",
pages: [
{
image: "base64encodedimage1",
fieldNames: ["patient_name", "patient_dob"],
},
],
},
{
name: "Test Template Syph",
description: "This is the second sample template.",
pages: [
{
image: "base64encodedimage2",
fieldNames: ["patient_name", "address"],
},
],
},
];
setTemplates(sampleTemplates);
};


useEffect(() => {
// Load templates from local storage, and if none are found, load test data
const loadTemplatesFromLocalStorage = () => {
const storedTemplates = localStorage.getItem("templates");
if (_templates.length > 0) {
setTemplates(_templates);
} else if (storedTemplates) {
const parsedTemplates = JSON.parse(storedTemplates);
setTemplates(parsedTemplates);
} else {
loadTemplatesTestData();
}
};
loadTemplatesFromLocalStorage();

}, []);
const simulateFileUpload = async(files: File[]) => {
onUploadComplete(true);
files.forEach(file => addFile(file));
Expand Down
76 changes: 68 additions & 8 deletions frontend/src/components/TemplatesIndex/TemplatesIndex.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,25 @@ export const TemplatesIndex: FC<TemplateIndexProps> = () => {
}
)
useEffect(() => {
const templatesJSON = localStorage.getItem("templates")
setTemplates(JSON.parse(templatesJSON))
}, []);

const getTemplates = async () => {
const templatesJSON = localStorage.getItem("templates") || "[]"
if (templateQuery.data && templateQuery.data?.length > 0) {
setTemplates(templateQuery.data as [])
} else if (templatesJSON) {
setTemplates(JSON.parse(templatesJSON).map(template => ({ ...template, updatedAt: template.lastUpdated })))
} else {
setTemplates([])
}
}
getTemplates();
}, [templateQuery.data]);

useEffect(() => {

const localStorageEvent = (event) => {
if (event.storageArea === localStorage) {
const templatesJSON = localStorage.getItem("templates")
setTemplates(JSON.parse(templatesJSON))
setTemplates(JSON.parse(templatesJSON || '[]'))
}
}
window.addEventListener("storage", localStorageEvent, false)
Expand All @@ -42,6 +51,8 @@ export const TemplatesIndex: FC<TemplateIndexProps> = () => {
const templateColumnNames = {
'name': 'Name',
'labName': 'Lab',
'lab': 'Lab',
'createdBy': 'Creator',
'status': 'Status',
'updatedAt': 'Updated On'
}
Expand All @@ -55,15 +66,64 @@ export const TemplatesIndex: FC<TemplateIndexProps> = () => {
}
return new Date(date).toLocaleDateString()

},
'lastUpdated': (d) => {
const date = Date.parse(d)
if (isNaN(date)) {
return new Date().toLocaleDateString()
}
return new Date(date).toLocaleDateString()

}
}

const templateColumns = [
'name', 'updatedAt', 'createdBy', 'labName', 'status'
'name', 'updatedAt', 'createdBy', 'lab', 'status', 'labName'
]

useEffect(() => {
console.debug(`
The following methods have been added to the window:
LoadNiceTemplates - this will load some pre-formatted templates that display nicely
SaveTemplates - this will save the current templates to 'oldTemplates'
LoadSavedTemplates - this will load the templates saved in 'oldTemplates'
ClearTemplates - this will delete the current templates
`)
window.LoadNiceTemplates = () => {
const oldTemplates = localStorage.getItem('templates')
localStorage.setItem('oldTemplates', oldTemplates)
localStorage.setItem('templates', JSON.stringify(templates2))
setTemplates(templates2)
}
window.SaveTemplates = () => {
const oldTemplates = localStorage.getItem('templates')
if (!oldTemplates) {
return
}
localStorage.setItem('oldTemplates', oldTemplates)
}
window.ClearTemplates = () => {
localStorage.removeItem('templates')
setTemplates([])
}
window.LoadSavedTemplates = () => {
const oldTemplates = localStorage.getItem('oldTemplates')
if (oldTemplates) {
localStorage.setItem('templates', oldTemplates)
setTemplates(JSON.parse(oldTemplates))
}
}
return () => {
delete window.LoadNiceTemplates
delete window.SaveTemplates
delete window.ClearTemplates
delete window.LoadSavedTemplates
}
});

if (!templateQuery.data || templateQuery.data.length === 0) {
if (!templates || templates.length === 0) {
return (
<><img
className="display-block margin-left-auto margin-right-auto padding-top-8"
Expand Down Expand Up @@ -98,7 +158,7 @@ export const TemplatesIndex: FC<TemplateIndexProps> = () => {
</div>
<div className="padding-1 border-1px border-gray-5 bg-white">
<h2>Saved Templates</h2>
<SortableTable columns={templateColumns} data={templateQuery.data || []}
<SortableTable columns={templateColumns} data={templates}
formatters={templateColumnFormatters}
columnNames={templateColumnNames}
/>
Expand Down

0 comments on commit 2ff6aa4

Please sign in to comment.