diff --git a/frontend/src/components/CaseImporterFlow.jsx b/frontend/src/components/CaseImporterFlow.jsx
index a685824e..061ef7d1 100644
--- a/frontend/src/components/CaseImporterFlow.jsx
+++ b/frontend/src/components/CaseImporterFlow.jsx
@@ -41,7 +41,7 @@ function CaseImporterFlow({ titleId, onClose }) {
if (svgElement && svgElement.hasAttribute("data-metadata")) {
const metadataStr = svgElement.getAttribute("data-metadata");
try {
- return JSON.parse(decodeFromHtml(metadataStr));
+ return JSON.parse(JSON.parse(decodeFromHtml(metadataStr)));
} catch (err) {
console.error("Error parsing metadata:", err);
}
@@ -76,14 +76,14 @@ function CaseImporterFlow({ titleId, onClose }) {
);
const postCaseJSON = useCallback(
- (json_str) => {
+ (json) => {
const requestOptions = {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Token ${token}`,
},
- body: json_str,
+ body: JSON.stringify(json),
};
setLoading(true);
@@ -123,7 +123,7 @@ function CaseImporterFlow({ titleId, onClose }) {
if (uploadType === "url") {
getUrlContent(url).then((json) => {
if (json) {
- postCaseJSON(JSON.stringify(json));
+ postCaseJSON(json);
}
});
} else {
@@ -160,7 +160,7 @@ function CaseImporterFlow({ titleId, onClose }) {
const metadataStr = svgElement.getAttribute("data-metadata");
try {
const metadataJSON = JSON.parse(metadataStr);
- setFileJson(metadataJSON);
+ setFileJson(JSON.parse(metadataJSON));
} catch (err) {
// TODO error could be better
setFileError("File is not a valid SVG");
diff --git a/frontend/src/components/CaseMediaPreview.jsx b/frontend/src/components/CaseMediaPreview.jsx
new file mode 100644
index 00000000..46aa2b1e
--- /dev/null
+++ b/frontend/src/components/CaseMediaPreview.jsx
@@ -0,0 +1,77 @@
+import configData from "../config.json";
+import { CardMedia } from "@mui/material";
+import mockup_diagram from "../images/mockup-diagram.png";
+import { useTheme } from "@emotion/react";
+import { useEffect, useState } from "react";
+import MermaidChart from "./Mermaid";
+import { useLoginToken } from "../hooks/useAuth";
+import { getCase } from "./caseApi";
+import { Box } from "@mui/material";
+import { LoadingCard } from "./ManageCases";
+
+export const CaseMediaPreview = ({ caseObj }) => {
+ const theme = useTheme();
+ const [token] = useLoginToken();
+ const [assuranceCase, setAssuranceCase] = useState();
+ const [isLoading, setIsLoading] = useState(true);
+
+ useEffect(() => {
+ if (token) {
+ let isMounted = true;
+ getCase(token, caseObj.id)
+ .then((json) => {
+ if (!isMounted) {
+ return;
+ }
+ setAssuranceCase(json);
+ setIsLoading(false);
+ })
+ .catch((err) => {
+ console.error(err);
+ // TODO show error to user
+ });
+
+ return () => {
+ isMounted = false;
+ };
+ }
+ }, [token, caseObj]);
+
+ if (configData.use_case_preview_svg) {
+ return (
+ <>
+ {isLoading ? (
+
+ ) : (
+
+ {}}
+ setMermaidFocus={() => {}}
+ />
+
+ )}
+ >
+ );
+ } else {
+ return (
+
+ );
+ }
+};
diff --git a/frontend/src/components/ManageCases.jsx b/frontend/src/components/ManageCases.jsx
index 90afe2dc..b37576ba 100644
--- a/frontend/src/components/ManageCases.jsx
+++ b/frontend/src/components/ManageCases.jsx
@@ -24,6 +24,7 @@ import CommentSection from "./CommentSection";
import CasePermissionsManager from "./CasePermissionsManager";
import DeleteCaseModal from "./DeleteCaseModal";
import ErrorMessage from "./common/ErrorMessage";
+import { CaseMediaPreview } from "./CaseMediaPreview";
const ThemedCard = ({ sx, ...props }) => {
return (
@@ -77,7 +78,7 @@ const formatter = new Intl.DateTimeFormat(undefined, {
year: "numeric",
});
-const CaseCard = ({ id, name, description, createdDate, reload }) => {
+const CaseCard = ({ caseObj, reload }) => {
const theme = useTheme();
const [menuOpen, setMenuOpen] = useState(false);
@@ -135,16 +136,11 @@ const CaseCard = ({ id, name, description, createdDate, reload }) => {
-
+
+
{
textDecoration: "none",
color: "unset",
overflow: "hidden",
+ zIndex: 99,
}}
>
- {name}
+ {caseObj.name}
{
minHeight: 0,
}}
>
- {description?.split("\n").map((str) => (
+ {caseObj.description?.split("\n").map((str) => (
<>
{str}
@@ -183,7 +180,7 @@ const CaseCard = ({ id, name, description, createdDate, reload }) => {
{/* TODO, designs would prefer the updated date */}
- Created: {formatter.format(createdDate)}
+ Created: {formatter.format(caseObj.createdDate)}
@@ -221,26 +218,30 @@ const CaseCard = ({ id, name, description, createdDate, reload }) => {
+
-
);
};
-const LoadingCard = () => {
+export const LoadingCard = () => {
return (
@@ -353,8 +354,8 @@ const ManageCases = () => {
) : (
<>
- {cases.map(({ id, ...props }) => (
-
+ {cases.map((caseObj) => (
+
))}
>
)}
diff --git a/frontend/src/components/Mermaid.js b/frontend/src/components/Mermaid.js
index e2271825..7455dede 100644
--- a/frontend/src/components/Mermaid.js
+++ b/frontend/src/components/Mermaid.js
@@ -13,11 +13,14 @@ function MermaidChart({
}) {
const [collapsedNodes, setCollapsedNodes] = useState([]);
- const chartmd = useMemo(
- () =>
- jsonToMermaid(assuranceCase, selectedType, selectedId, collapsedNodes),
- [assuranceCase, selectedType, selectedId, collapsedNodes],
- );
+ const chartmd = useMemo(() => {
+ return jsonToMermaid(
+ assuranceCase,
+ selectedType,
+ selectedId,
+ collapsedNodes,
+ );
+ }, [assuranceCase, selectedType, selectedId, collapsedNodes]);
// refresh state
useEffect(() => {
@@ -81,7 +84,7 @@ function MermaidChart({
// trigger mermaid reload
useEffect(() => {
try {
- const mermaidDiv = document.querySelector(".mermaid");
+ const mermaidDiv = document.querySelector(`.mermaid-${caseId}`);
if (mermaidDiv) {
// inject the markdown here, rather than via react
// so in between render and the effect you don't see the text
@@ -108,12 +111,14 @@ function MermaidChart({
key={chartmd}
style={{
display: "flex",
+ flexDirection: "column",
height: "100%",
width: "100%",
- justifyContent: "center",
+ justifyContent: "start",
+ alignItems: "start",
overflow: "visible",
}}
- className="mermaid"
+ className={`mermaid-${caseId} mermaid`}
/>
);
}
diff --git a/frontend/src/config.json b/frontend/src/config.json
index 37ff7616..d257be46 100644
--- a/frontend/src/config.json
+++ b/frontend/src/config.json
@@ -149,5 +149,6 @@
"desc_char_max_len": 40,
"evidence_url_char_max_len": 250
}
- }
+ },
+ "use_case_preview_svg": true
}