From 3b84c6e1d2d76fb3a5b060c939e7e1a643879582 Mon Sep 17 00:00:00 2001 From: 3keyroman Date: Wed, 3 Jul 2024 16:38:19 +0200 Subject: [PATCH 1/2] Improve PDF data and layout - include first page with PKIC logo - add model version to summary - add report date to summary - add link to the assessment - remove header and footer from first page --- package-lock.json | 10 ++ package.json | 1 + src/components/Assessment/Assessment.tsx | 7 ++ src/utils/pdfGenerator.tsx | 148 +++++++++++++++++++---- 4 files changed, 144 insertions(+), 22 deletions(-) diff --git a/package-lock.json b/package-lock.json index dba53ac..8f78191 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,7 @@ "@fortawesome/free-solid-svg-icons": "^6.5.2", "@fortawesome/react-fontawesome": "^0.2.2", "@react-pdf/renderer": "^3.4.4", + "date-fns": "^3.6.0", "js-yaml": "^4.1.0", "react": "^18.3.1", "react-chartjs-2": "^5.2.0", @@ -3804,6 +3805,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/date-fns": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-3.6.0.tgz", + "integrity": "sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/kossnocorp" + } + }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", diff --git a/package.json b/package.json index 9893c41..52e8e6a 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "@fortawesome/free-solid-svg-icons": "^6.5.2", "@fortawesome/react-fontawesome": "^0.2.2", "@react-pdf/renderer": "^3.4.4", + "date-fns": "^3.6.0", "js-yaml": "^4.1.0", "react": "^18.3.1", "react-chartjs-2": "^5.2.0", diff --git a/src/components/Assessment/Assessment.tsx b/src/components/Assessment/Assessment.tsx index 353129a..6940359 100644 --- a/src/components/Assessment/Assessment.tsx +++ b/src/components/Assessment/Assessment.tsx @@ -173,6 +173,12 @@ export const Assessment: React.FC = ({ src }) => { data.modules, progress, ); + const url = generateURL( + progress, + assessmentName, + assessorName, + useCaseDescription, + ); exportToPDF( progress, chartRef.current, @@ -182,6 +188,7 @@ export const Assessment: React.FC = ({ src }) => { assessmentName, assessorName, useCaseDescription, + url, ); } }; diff --git a/src/utils/pdfGenerator.tsx b/src/utils/pdfGenerator.tsx index 656291c..0e1ccf2 100644 --- a/src/utils/pdfGenerator.tsx +++ b/src/utils/pdfGenerator.tsx @@ -22,32 +22,60 @@ import { faLinkedin, faXTwitter, } from "@fortawesome/free-brands-svg-icons"; +import { format } from "date-fns"; -const PkicLogoSvg = () => ( +const PkicLogoSvg = ({ fillColor = "grey" }) => ( + + +); + +const PkicBadgeSvg = ({ fillColor = "grey" }) => ( + + + + + + + @@ -63,6 +91,18 @@ const styles = StyleSheet.create({ paddingLeft: 40, paddingRight: 40, }, + logo_first: { + width: 700, + height: "auto", + marginTop: -150, + marginLeft: -300, + }, + title_first: { + fontSize: 50, + fontStyle: "bold", + textAlign: "right", + paddingTop: 10, + }, header: { flexDirection: "row", justifyContent: "center", @@ -174,13 +214,16 @@ const styles = StyleSheet.create({ position: "absolute", }, fixed_footer: { + position: "absolute", bottom: 20, left: 0, right: 0, - textAlign: "center", + flexDirection: "row", + justifyContent: "space-between", fontSize: 12, + paddingLeft: 40, + paddingRight: 40, color: "grey", - position: "absolute", }, about_heading: { fontSize: 12, @@ -214,11 +257,17 @@ const Header: React.FC = () => ( ); -const Footer: React.FC = () => ( +const Footer: React.FC<{ assessmentUrl: string }> = ({ assessmentUrl }) => ( `${pageNumber} / ${totalPages}`} /> + + Go To Assessment + ); @@ -235,6 +284,7 @@ interface PdfDocumentProps { assessmentName: string; assessorName: string; useCaseDescription: string; + assessmentUrl: string; } // Function to determine color based on the level @@ -312,14 +362,43 @@ const PdfDocument: React.FC = ({ assessmentName, assessorName, useCaseDescription, + assessmentUrl, }) => ( + {/*first page contains only PKIC logo centered in the middle of the page*/} -
-
+ + + + PKI Maturity + Self-Assessment + Report +
- PKI Maturity Self-Assessment Report + {/*second page contains summary*/} + +
+
+ Summary + + + Report Date: + + + + {format(new Date(), "MMMM do, yyyy h:mm a")} + + + + + + Model Version: + + + 1.0 + + = ({ {assessorName} - + Use Case Description: @@ -370,13 +449,30 @@ const PdfDocument: React.FC = ({ + + + Assessment Link: + + + + + Go To Assessment + + + + +
- {/*break*/} - - Overall PKI Maturity Level - + {/*third page contains details*/} + +
+
+ Overall PKI Maturity Level = ({ }), )} +
- {/*break*/} - - About PKI Maturity Model - + {/*fourth page contains about, consortium and resources*/} + +
+
+ About PKI Maturity Model The maturity model is based on the Capability Maturity Model Integration (CMMI) developed by Carnegie Mellon University. It should provide the @@ -853,6 +955,7 @@ export const exportToPDF = async ( assessmentName: string, assessorName: string, useCaseDescription: string, + assessmentUrl: string, ) => { const chartCanvas = chartElement.querySelector("canvas") as HTMLCanvasElement; const chartImgData = chartCanvas.toDataURL("image/png"); @@ -867,6 +970,7 @@ export const exportToPDF = async ( assessmentName={assessmentName} assessorName={assessorName} useCaseDescription={useCaseDescription} + assessmentUrl={assessmentUrl} /> ); From 1443066565cdf7799c97ca7ae2ac7e2cce84d7d5 Mon Sep 17 00:00:00 2001 From: 3keyroman Date: Sat, 6 Jul 2024 18:11:49 +0200 Subject: [PATCH 2/2] Update PDF template --- src/components/Assessment/Assessment.tsx | 2 + src/utils/pdfGenerator.tsx | 172 ++++++++++++++--------- 2 files changed, 108 insertions(+), 66 deletions(-) diff --git a/src/components/Assessment/Assessment.tsx b/src/components/Assessment/Assessment.tsx index 6940359..eb2bc99 100644 --- a/src/components/Assessment/Assessment.tsx +++ b/src/components/Assessment/Assessment.tsx @@ -27,6 +27,7 @@ export const Assessment: React.FC = ({ src }) => { applicability: true, }; + const version = "0.0.1"; const [data, setData] = useState(null); const [progress, setProgress] = useState>({}); const [currentTab, setCurrentTab] = useState(null); @@ -189,6 +190,7 @@ export const Assessment: React.FC = ({ src }) => { assessorName, useCaseDescription, url, + version, ); } }; diff --git a/src/utils/pdfGenerator.tsx b/src/utils/pdfGenerator.tsx index 0e1ccf2..0542a22 100644 --- a/src/utils/pdfGenerator.tsx +++ b/src/utils/pdfGenerator.tsx @@ -1,5 +1,6 @@ import { Document, + Font, G, Image, Link, @@ -24,7 +25,34 @@ import { } from "@fortawesome/free-brands-svg-icons"; import { format } from "date-fns"; -const PkicLogoSvg = ({ fillColor = "grey" }) => ( +// Register Roboto font +Font.register({ + family: "Roboto", + fonts: [ + { src: "https://fonts.gstatic.com/s/roboto/v20/KFOmCnqEu92Fr1Me5Q.ttf" }, // Roboto Regular + { + src: "https://fonts.gstatic.com/s/roboto/v20/KFOmCnqEu92Fr1Me5Q.ttf", + fontWeight: 700, + }, // Roboto Bold + ], +}); + +const primaryColor = getComputedStyle( + document.documentElement, +).getPropertyValue("--pkimm-primary-color"); +const secondaryColor = getComputedStyle( + document.documentElement, +).getPropertyValue("--pkimm-secondary-color"); +const tertiaryColor = getComputedStyle( + document.documentElement, +).getPropertyValue("--pkimm-tertiary-color"); + +const PkicLogoSvg = ({ + fillColor = "black", + fillOne = primaryColor, + fillTwo = secondaryColor, + fillThree = tertiaryColor, +}) => ( ( /> - - - - -); - -const PkicBadgeSvg = ({ fillColor = "grey" }) => ( - - - - - ( // Define styles for the PDF const styles = StyleSheet.create({ + body: { + fontFamily: "Roboto", + }, page: { + fontFamily: "Roboto", flexDirection: "column", paddingTop: 80, paddingBottom: 50, @@ -92,15 +97,21 @@ const styles = StyleSheet.create({ paddingRight: 40, }, logo_first: { - width: 700, + width: 300, height: "auto", - marginTop: -150, - marginLeft: -300, + marginTop: 150, + alignSelf: "center", }, title_first: { fontSize: 50, - fontStyle: "bold", - textAlign: "right", + fontWeight: "bold", + textAlign: "center", + paddingTop: 10, + }, + subtitle_first: { + fontSize: 30, + fontWeight: "bold", + textAlign: "center", paddingTop: 10, }, header: { @@ -123,13 +134,13 @@ const styles = StyleSheet.create({ }, title: { fontSize: 25, - fontStyle: "bold", + fontWeight: "bold", textAlign: "center", marginBottom: 20, }, heading: { fontSize: 20, - fontStyle: "bold", + fontWeight: "bold", textAlign: "center", marginBottom: 10, }, @@ -220,7 +231,7 @@ const styles = StyleSheet.create({ right: 0, flexDirection: "row", justifyContent: "space-between", - fontSize: 12, + fontSize: 8, paddingLeft: 40, paddingRight: 40, color: "grey", @@ -253,18 +264,28 @@ const styles = StyleSheet.create({ const Header: React.FC = () => ( - + ); -const Footer: React.FC<{ assessmentUrl: string }> = ({ assessmentUrl }) => ( +const Footer: React.FC<{ assessmentUrl: string; version: string }> = ({ + assessmentUrl, + version, +}) => ( `${pageNumber} / ${totalPages}`} /> + {version} + {format(new Date(), "MMMM do, yyyy h:mm a")} Go To Assessment @@ -285,6 +306,7 @@ interface PdfDocumentProps { assessorName: string; useCaseDescription: string; assessmentUrl: string; + version: string; } // Function to determine color based on the level @@ -363,34 +385,30 @@ const PdfDocument: React.FC = ({ assessorName, useCaseDescription, assessmentUrl, + version, }) => ( {/*first page contains only PKIC logo centered in the middle of the page*/} - + - PKI Maturity - Self-Assessment - Report + + PKI Maturity Model + + Self-Assessment Report + {version} + + {format(new Date(), "MMMM do, yyyy h:mm a")} + {/*second page contains summary*/}
-
+
Summary - - - Report Date: - - - - {format(new Date(), "MMMM do, yyyy h:mm a")} - - - Model Version: @@ -471,7 +489,7 @@ const PdfDocument: React.FC = ({ {/*third page contains details*/}
-
+
Overall PKI Maturity Level = ({ bookmark={{ title: "About PKI Maturity Model" }} >
-
+
About PKI Maturity Model The maturity model is based on the Capability Maturity Model Integration @@ -753,7 +771,9 @@ const PdfDocument: React.FC = ({ - PKI Consortium + + PKI Consortium + @@ -765,7 +785,10 @@ const PdfDocument: React.FC = ({ - + PKI maturity model @@ -781,7 +804,10 @@ const PdfDocument: React.FC = ({ - + Categories description @@ -796,7 +822,10 @@ const PdfDocument: React.FC = ({ - + PKI maturity assessment process @@ -810,7 +839,10 @@ const PdfDocument: React.FC = ({ - + PKI maturity assessment tools @@ -825,7 +857,10 @@ const PdfDocument: React.FC = ({ - + Feedback form @@ -839,7 +874,10 @@ const PdfDocument: React.FC = ({ - + PKI maturity model community discussion @@ -956,6 +994,7 @@ export const exportToPDF = async ( assessorName: string, useCaseDescription: string, assessmentUrl: string, + version: string, ) => { const chartCanvas = chartElement.querySelector("canvas") as HTMLCanvasElement; const chartImgData = chartCanvas.toDataURL("image/png"); @@ -971,6 +1010,7 @@ export const exportToPDF = async ( assessorName={assessorName} useCaseDescription={useCaseDescription} assessmentUrl={assessmentUrl} + version={version} /> );