Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta
http-equiv="Content-Security-Policy"
content="upgrade-insecure-requests"
/>
<title>Template Designer</title>
</head>
Expand Down
27 changes: 14 additions & 13 deletions src/StartScreenComp/StartScreenComp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -208,20 +208,21 @@ export default function StartScreenComp({}) {
<Button disabled={!idShosen} label="Generate Excel Template" />
</div>
)}
<Link to={`/wizard/${idShosen}`}>
<div
onClick={() => {
setUUID(idShosen);
setStartScreen();

setViewMode(true);
navigate(`wizard/${idShosen}`);

window.localStorage.setItem(storageItemKey, "");
}}
>
<Button disabled={!idShosen} label="Customize Excel template" />
</Link>
{/* <div onClick={downloadNexus}>
<Button disabled={!idShosen} label="Download NeXus File" />
</div> */}
{/* <div onClick={generateAndPreview}>
<Button
disabled={!idShosen || isGenerating}
label={
isGenerating ? "Generating preview..." : "Preview NeXus File"
}
/>
</div> */}

{/* <Button disabled={!idShosen || error} label={"Edit data"} /> */}
</div>
</div>
</div>
</div>
Expand Down
47 changes: 35 additions & 12 deletions src/SurveyComp/SurveyComp.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import config from "../utils/config";

import "survey-core/defaultV2.min.css";
import "../App.css";
// import json from "../SurveyComp/dataComp";

const orcidPattern = /^\d{4}-\d{4}-\d{4}-(\d{4}|[Xx])$/;

Expand All @@ -31,7 +32,7 @@ function isValidOrcid([ORCID]) {
FunctionFactory.Instance.register("isValidOrcid", isValidOrcid);

// eslint-disable-next-line react/prop-types
function SurveyComponent({ setResult }) {
function SurveyComponent({ setResult, definition, uuid: uuidProp, mode: modeProp, isDataEntry = false }) {
const [surveyJson, setSurveyJson] = useState(null);
const [survey, setSurvey] = useState(null);

Expand All @@ -44,20 +45,17 @@ function SurveyComponent({ setResult }) {
const uuidParams = queryParams.get("uuid");
const viewParams = queryParams.get("mode");

const id = idShosen ? idShosen : UUID || uuidParams;
const id = uuidProp || idShosen || UUID || uuidParams;

// Load schema once (from localStorage or API)
useEffect(() => {
async function loadSchema() {
try {
const response = await fetch(
`${config.apiUrl}/../definition/template_designer`,
{
headers: {
Authorization: `Bearer ${localStorage.getItem("access_token")}`,
},
const response = await fetch(`${definition}`, {
headers: {
Authorization: `Bearer ${localStorage.getItem("access_token")}`,
},
);
});
const json = await response.json();
localStorage.setItem("surveyJson", JSON.stringify(json));
setSurveyJson(json);
Expand Down Expand Up @@ -98,10 +96,18 @@ function SurveyComponent({ setResult }) {
data: model,
});

const storageItemKey = "my-survey";
// Use a uuid-specific key for data-entry mode so answers are scoped
// per template and never collide with the blueprint designer storage.
const storageItemKey = isDataEntry
? `data-entry-${id}`
: "my-survey";

function saveSurveyData(survey) {
postRequestUUID(survey.data, id);
// In data-entry mode never POST to the backend — customization is
// local-only. In blueprint-designer mode POST as before.
if (!isDataEntry) {
postRequestUUID(survey.data, id);
}
setIntermediateData(survey.data);
}

Expand Down Expand Up @@ -147,7 +153,24 @@ function SurveyComponent({ setResult }) {

setIntermediateData(data);
survey.data = data;
if (viewMode || !viewParams) {
// In data-entry mode, layer localStorage answers on top of any
// backend-loaded data (localStorage is more recent).
const storageKey = isDataEntry ? `data-entry-${id}` : "my-survey";
const saved = window.localStorage.getItem(storageKey);
if (saved) {
try {
const parsed = JSON.parse(saved);
// pageNo is a nav helper, not a survey answer
const { pageNo, ...answers } = parsed;
survey.data = { ...survey.data, ...answers };
} catch (e) {
console.warn("Could not restore saved survey data", e);
}
}
// modeProp takes priority; fall back to URL ?mode= param; default is display
if (modeProp) {
survey.mode = modeProp;
} else if (viewMode || !viewParams) {
survey.mode = "display";
}
} catch (error) {
Expand Down
5 changes: 4 additions & 1 deletion src/lib/request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,17 @@ export const postRequest = (data) => {
});
};

export const downloadFile = (uuid, templateURL) => {
export const downloadFile = (uuid, templateURL, customization = null) => {
console.log(sessionStorage.getItem("access_token"));

fetch(templateURL, {
cache: "no-cache",
method: customization ? "POST" : "GET",
headers: {
Authorization: `Bearer ${sessionStorage.getItem("access_token")}`,
...(customization ? { "Content-Type": "application/json" } : {}),
},
body: customization ? JSON.stringify(customization) : undefined,
})
.then((resp) => {
if (!resp.ok) {
Expand Down
3 changes: 2 additions & 1 deletion src/main.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import HomePage from "./pages/HomePage.tsx";
import TemplatePage from "./pages/TemplatePage.tsx";
import WizardPage from "./pages/WizardPage.tsx";
import PreferencesPage from "./pages/PreferencesPage.tsx";
import DataPage from "./pages/DataPage.tsx";
import UploadPage from "./pages/UploadPage.tsx";
import NotFoundPage from "./pages/NotFoundPage.tsx";

Expand Down Expand Up @@ -36,7 +37,7 @@ const router = createBrowserRouter(
},
{
path: "/wizard/:templateId",
Component: WizardPage,
Component: DataPage,
},
{
path: "/preferences",
Expand Down
67 changes: 67 additions & 0 deletions src/pages/DataPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import React, { useState } from "react";

import Button from "@/ui/Button";
import { Link, useParams } from "react-router-dom";
import LogoBarWizard from "../MenuBar/LogoBarWizard";
import SurveyComponent from "../SurveyComp/SurveyComp";
import { useProjectID } from "../store/store";
import config from "@/utils/config";
import { downloadFile } from "@/lib/request";

export default function DataPage() {
const [result, setResult] = useState(null);
const projectID = useProjectID();

let params = useParams();
const uuid = params.templateId;
const templateURL = `${config.apiUrl}/${uuid}?format=xlsx&project=${projectID}`;
const customXlsxURL = `${config.apiUrl}/${uuid}/xlsx?project=${projectID}`;
const definition = `${config.apiUrl}/${uuid}?format=json&data_entry=true`;

const downloadXLS = () => {
// Read customization from localStorage — never stored on the backend.
const storageKey = `data-entry-${uuid}`;
let payload = null;
try {
const saved = window.localStorage.getItem(storageKey);
if (saved) {
const { pageNo, ...answers } = JSON.parse(saved);
payload = answers;
}
} catch (e) {
console.warn("Could not read customization from localStorage", e);
}
console.log("customization payload:", payload);
uuid && downloadFile(uuid, customXlsxURL, payload);
};
return (
<div>
<p className="underDev">
The Template Wizard App is under development right now
</p>
<LogoBarWizard />
<div style={{ padding: "1rem" }}>
<div style={{ display: "flex", gap: "1rem" }}>
<Link to="/">
<Button label="Back to Templates" disabled={false} />
</Link>
<div onClick={downloadXLS}>
<Button
disabled={!params.templateId}
label="Generate Excel Template"
/>
</div>
</div>
<div style={{ marginTop: "1rem" }}>
<SurveyComponent
setResult={setResult}
uuid={params.templateId}
definition={definition}
mode="edit"
isDataEntry={true}
/>
</div>
</div>
</div>
);
}
9 changes: 8 additions & 1 deletion src/pages/TemplatePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import SurveyComponent from "../SurveyComp/SurveyComp";
import { useSetUuid } from "../store/store";

import "../App.css";
import config from "@/utils/config";

export default function TemplatePage({ uuid }) {
const params = useParams<{ templateId: string }>();
Expand All @@ -23,14 +24,20 @@ export default function TemplatePage({ uuid }) {

const [result, setResult] = useState(null);

const definition = `${config.apiUrl}/../definition/template_designer`;

return (
<div data-cy="template-page">
<div className="headerWrap">
<LogoBar startScreen={false} />
<TopMenuBar />
</div>
<div className="mainWrap">
<SurveyComponent setResult={setResult} uuid={uuid} />
<SurveyComponent
setResult={setResult}
uuid={uuid}
definition={definition}
/>
</div>
</div>
);
Expand Down
4 changes: 3 additions & 1 deletion src/pages/WizardPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ import React from "react";
import LogoBarWizard from "../MenuBar/LogoBarWizard";
import Button from "@/ui/Button";
import Select from "@/ui/Select";
import { Link } from "react-router-dom";
import { Link, useParams } from "react-router-dom";

const selectUrl =
"https://enanomapper.adma.ai/api/projects/nanoreg2/materials.json";

export default function WizardPage() {
let params = useParams();

return (
<div>
<p className="underDev">
Expand Down
2 changes: 2 additions & 0 deletions src/ui/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import EditIcon from "@/IconsComponents/EditIcon";
import ShareLinkIcon from "@/IconsComponents/ShareLinkIcon";
import CustomizeIcon from "@/IconsComponents/CustomizeIcon";
import BackArrow from "@/IconsComponents/BackArrow";
import { TbDatabaseEdit } from "react-icons/tb";
import "./Button.css";

export default function Button({ label, disabled }) {
Expand Down Expand Up @@ -38,6 +39,7 @@ export default function Button({ label, disabled }) {
{label == "Share" && <ShareIcon />}
{label == "Generate Excel Template" && <ExcelIcon disabled={disabled} />}
{label == "Back to Templates" && <BackArrow disabled={disabled} />}
{label == "Edit data" && <TbDatabaseEdit size={20} />}
<span>{label}</span>
</button>
);
Expand Down
Loading