Skip to content

Commit

Permalink
Merge pull request #372 from alan-turing-institute/develop
Browse files Browse the repository at this point in the history
case import fix and SVG case previews
  • Loading branch information
kallewesterling authored Jan 30, 2024
2 parents 3d4526b + 00d8eb6 commit 69708c0
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 33 deletions.
10 changes: 5 additions & 5 deletions frontend/src/components/CaseImporterFlow.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -123,7 +123,7 @@ function CaseImporterFlow({ titleId, onClose }) {
if (uploadType === "url") {
getUrlContent(url).then((json) => {
if (json) {
postCaseJSON(JSON.stringify(json));
postCaseJSON(json);
}
});
} else {
Expand Down Expand Up @@ -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");
Expand Down
77 changes: 77 additions & 0 deletions frontend/src/components/CaseMediaPreview.jsx
Original file line number Diff line number Diff line change
@@ -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 ? (
<LoadingCard />
) : (
<Box
sx={{
height: "50%",
position: "relative",
pointerEvents: "none",
overflow: "hidden",
}}
>
<MermaidChart
assuranceCase={assuranceCase}
caseId={caseObj.id}
selectedId={[]}
selectedType={[]}
setSelected={() => {}}
setMermaidFocus={() => {}}
/>
</Box>
)}
</>
);
} else {
return (
<CardMedia
height={227}
component="img"
image={mockup_diagram}
alt=""
sx={{ background: theme.palette.grey[200] }}
/>
);
}
};
39 changes: 20 additions & 19 deletions frontend/src/components/ManageCases.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -135,16 +136,11 @@ const CaseCard = ({ id, name, description, createdDate, reload }) => {
<ThemedCard sx={{ position: "relative" }}>
<CardActionArea
component={Link}
to={"case/" + id}
to={"case/" + caseObj.id}
sx={{ height: "100%" }}
>
<CardMedia
height={227}
component="img"
image={mockup_diagram}
alt=""
sx={{ background: theme.palette.grey[200] }}
/>
<CaseMediaPreview caseObj={caseObj} />

<CardContent
sx={{
padding: "1.5rem",
Expand All @@ -156,10 +152,11 @@ const CaseCard = ({ id, name, description, createdDate, reload }) => {
textDecoration: "none",
color: "unset",
overflow: "hidden",
zIndex: 99,
}}
>
<Typography variant="h3" component="h2">
{name}
{caseObj.name}
</Typography>
<Typography
variant="body2"
Expand All @@ -174,7 +171,7 @@ const CaseCard = ({ id, name, description, createdDate, reload }) => {
minHeight: 0,
}}
>
{description?.split("\n").map((str) => (
{caseObj.description?.split("\n").map((str) => (
<>
{str}
<br />
Expand All @@ -183,7 +180,7 @@ const CaseCard = ({ id, name, description, createdDate, reload }) => {
</Typography>
{/* TODO, designs would prefer the updated date */}
<Typography variant="body2">
Created: {formatter.format(createdDate)}
Created: {formatter.format(caseObj.createdDate)}
</Typography>
</CardContent>
</CardActionArea>
Expand Down Expand Up @@ -221,26 +218,30 @@ const CaseCard = ({ id, name, description, createdDate, reload }) => {
<ExportCaseModal
isOpen={exportOpen}
onClose={onExportClose}
caseId={id}
caseId={caseObj.id}
/>
<CommentSection
isOpen={notesOpen}
onClose={onNotesClose}
caseId={caseObj.id}
/>
<CommentSection isOpen={notesOpen} onClose={onNotesClose} caseId={id} />
<CasePermissionsManager
isOpen={permissionsOpen}
onClose={onPermissionsClose}
caseId={id}
caseId={caseObj.id}
onSuccess={onPermissionsSuccess}
/>
<DeleteCaseModal
isOpen={deleteOpen}
onClose={onDeleteClose}
caseId={id}
caseId={caseObj.id}
onDelete={onDeleteSuccess}
/>
</ThemedCard>
);
};

const LoadingCard = () => {
export const LoadingCard = () => {
return (
<ThemedCard sx={{ display: "flex" }}>
<LoadingSpinner sx={{ margin: "auto" }} />
Expand Down Expand Up @@ -353,8 +354,8 @@ const ManageCases = () => {
<LoadingCard />
) : (
<>
{cases.map(({ id, ...props }) => (
<CaseCard id={id} key={id} {...props} reload={doLoad} />
{cases.map((caseObj) => (
<CaseCard caseObj={caseObj} reload={doLoad} />
))}
</>
)}
Expand Down
21 changes: 13 additions & 8 deletions frontend/src/components/Mermaid.js
Original file line number Diff line number Diff line change
Expand Up @@ -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(() => {
Expand Down Expand Up @@ -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
Expand All @@ -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`}
/>
);
}
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -149,5 +149,6 @@
"desc_char_max_len": 40,
"evidence_url_char_max_len": 250
}
}
},
"use_case_preview_svg": true
}

0 comments on commit 69708c0

Please sign in to comment.