Files
pedwfrontend/components/pdftemplates/appealRow_pdf.js
T
Robert Bond 1e14fbc709 Merged PR 2387: update welsh translations for new appeal pdf
update welsh translations for new appeal pdf

Related work items: #23562
2026-06-15 12:03:28 +00:00

756 lines
38 KiB
JavaScript

import { JSONPath as jsonpath } from "jsonpath-plus";
import useTranslation from "next-translate/useTranslation";
import xpath from "xpath";
import {
bytesToSize,
getPickListLabel,
getDocumentTypeFromFilename,
getFormCollectionByID
} from "../../components/utils";
import fieldLookup from "../../data/crmfieldlookuptranslations.json";
import { StyleSheet, Text, View, Font } from "@react-pdf/renderer";
import Html from "react-pdf-html";
import { DOMParser, XMLSerializer } from "@xmldom/xmldom";
import transLookup from "../../data/lookuptranslations.json";
export const AppealRow_pdf = (props) => {
let { t } = useTranslation();
let locale = props.props.locale;
const {
formXML,
whichSection,
sectionCount,
onSubmit,
updateCurrentSection,
mandatoryFieldsData
} = props;
const styles = StyleSheet.create({
page: {
backgroundColor: "white",
padding: 20,
fontSize: 16,
paddingBottom: 50
},
header: {
fontSize: 25,
fontFamily: "Helvetica",
flexDirection: "row",
justifyContent: "space-between"
},
subHeader: {
fontSize: 20
},
logoImage: { width: "200pt" },
questionBullet: { width: "5%", fontSize: 12 },
questionText: {
width: "35%",
fontSize: 12,
marginRight: 5
},
questionTextMid: { width: "80%", fontSize: 12 },
questionTextWide: { width: "95%", fontSize: 12, marginBottom: 5 },
questionAnswer: {
color: "#757575",
width: "65%",
fontSize: 12,
padding: 5,
border: 1,
borderColor: "#eee",
paddingLeft: 10,
backgroundColor: "white",
display: "flex",
flexWrap: "wrap"
},
questionAnswerMid: {
color: "#757575",
width: "20%",
fontSize: 12,
padding: 5,
border: 1,
borderColor: "#eee",
paddingLeft: 10,
backgroundColor: "white",
display: "flex",
flexWrap: "wrap"
},
questionAnswerWide: {
color: "#757575",
width: "100%",
fontSize: 12,
border: 1,
borderColor: "#eee",
backgroundColor: "white",
padding: 5
},
questionAnswerRow: {
width: "100%",
flex: 1,
flexDirection: "row",
flexGrow: 1
},
questionAnswerColLeft: {
width: "40%"
},
questionAnswerColRight: {
padding: 5,
width: "40%"
},
sectionContainer: {
backgroundColor: "#F8F8F8",
padding: 10,
marginTop: 20,
fontSize: 15
},
pageNumber: {
position: "absolute",
fontSize: 12,
bottom: 20,
left: 0,
right: 0,
textAlign: "center",
color: "grey"
},
documentList: {
fontSize: 10,
lineHeight: 1.4
},
richArea: {
fontSize: 12,
flexDirection: "column"
}
});
const parser = new DOMParser();
var doc = parser.parseFromString(formXML, "text/xml");
var rowXML = xpath.select(
"/form/tabs/tab[" +
whichSection +
"]/columns//sections/section/rows/row",
doc
);
function formatDate(dateObj) {
var m = new Date(dateObj);
var dateString;
dateObj != null
? (dateString =
("0" + m.getDate()).slice(-2) +
"/" +
("0" + (m.getMonth() + 1)).slice(-2) +
"/" +
m.getFullYear())
: (dateString = "");
return dateString;
}
const FieldsTranslations = (label, locale) => {
const appealtypes = getFormCollectionByID(
props.props.caseObj.pinswg_appealcasetype
).UrlName;
const formObj = jsonpath({
path: `$['${appealtypes}'].[?(@.value=="${label}")]`,
json: fieldLookup,
eval: true
});
const item = formObj?.[0];
if (locale === "cy" && !item?.value_cy) {
console.warn(`[Missing Welsh translation]`, {
label: item?.value,
orig: label,
appealType: appealtypes
});
}
return locale === "cy"
? (item?.value_cy ?? item?.value ?? label)
: (item?.value ?? label);
};
Font.registerHyphenationCallback((word) => [word]);
function CleanHTML(htmlStr) {
let cleanStr =
typeof htmlStr === "string"
? htmlStr.replace(
/<p><br><\/p>|<p class=\"ql-align-justify\"><br><\/p>/g,
""
)
: "";
return cleanStr;
}
return (
<>
{Object.keys(rowXML).map((key, index) => {
var newRowXML = new XMLSerializer().serializeToString(
rowXML[key]
);
var doc = parser.parseFromString(newRowXML, "text/xml");
var rows = xpath.select("//label/@description", doc);
var fieldtype = xpath.select("//@classid", doc);
var datafieldname = xpath.select("//@datafieldname", doc);
var datafieldcontent = xpath.select("//@datafieldcontent", doc);
var parentField = xpath.select("//@parentField", doc);
var parentFieldShowOnValue = xpath.select(
"//@parentFieldShowOnValue",
doc
);
var documentTypeCode = xpath.select(
"//@ishareDocumentCode",
doc
);
// console.log(
// fieldtype[0].value,
// " - ",
// datafieldname[0].value,
// " - ",
// props.props[datafieldname[0].value],
// " - ",
// rows[0].value
// );
return (
<>
{(() => {
switch (fieldtype[0].value) {
case "{5B773807-9FB2-42db-97C3-7A91EFF8ADFF}":
return (
<View
style={{
flexDirection: "row",
marginBottom: 10
}}
wrap={false}
>
<Text
style={styles.questionTextWide}
>
{FieldsTranslations(
rows[0].value,
locale
)}{" "}
</Text>
<Text
style={styles.questionAnswerMid}
>
{formatDate(
props.props[
datafieldname[0].value
]
)}{" "}
</Text>
</View>
);
break;
case "{E0DECE4B-6FC8-4a8f-A065-082708572369}":
const fieldName = datafieldname[0].value;
// console.log(
// JSON.stringify(props.props, null, 2)
// );
return (
<View
style={{
flexDirection: "column",
marginBottom: 10
}}
wrap={false}
>
<View
wrap={false}
style={{
flexDirection: "row",
marginBottom: 10
}}
>
<Text
style={
styles.questionTextMid
}
>
{FieldsTranslations(
rows[0].value,
locale
)}
</Text>
</View>
<View
style={
styles.questionAnswerWide
}
>
<Text>
{
props.props[
datafieldname[0]
.value
]
}
{props.props[fieldName] ??
props.props.caseObj?.[
fieldName
]}
</Text>
</View>
</View>
);
break;
case "{07FAC785-CD58-4f9f-ABB3-4B7DDC6ED5ED}":
var fieldCopy = datafieldcontent[0].value
.replace("]", "")
.replace("[", "")
.split(",")
.find((a) =>
a.includes(
props.props[
datafieldname[0].value
]
)
);
fieldCopy =
typeof fieldCopy != "undefined"
? fieldCopy.split("|")[1]
: fieldCopy;
const transData = require(
"../../locales/" +
locale +
"/" +
(typeof fieldCopy != "undefined"
? fieldCopy.split(":")[0]
: "common") +
".json"
);
let transCopy =
typeof fieldCopy != "undefined"
? transData[fieldCopy.split(":")[1]]
: fieldCopy;
return (
<View
style={{
flexDirection: "column",
marginBottom: 10
}}
wrap={false}
>
<View
wrap={false}
style={{
flexDirection: "row",
marginBottom: 10
}}
>
<Text
style={
styles.questionTextWide
}
>
{FieldsTranslations(
rows[0].value,
locale
)}{" "}
</Text>
</View>
<View
style={
styles.questionAnswerWide
}
>
<Text>{transCopy}</Text>
</View>
</View>
);
break;
case "{E0DECE4B-6666-4a8f-A065-082708572369}":
return (
<View
style={{
flexDirection: "column",
marginBottom: 10
}}
>
<View
wrap={false}
style={{
flexDirection: "row",
marginBottom: 10
}}
>
<Text
style={
styles.questionTextWide
}
>
{FieldsTranslations(
rows[0].value,
locale
)}
</Text>
</View>
<View
style={
styles.questionAnswerWide
}
>
<Html style={styles.richArea}>
{CleanHTML(
props.props[
datafieldname[0]
.value
]
)}
</Html>
</View>
</View>
);
break;
case "{3EF39988-22BB-4f0b-BBBE-64B5A3748AEE}":
return (
<View
wrap={false}
style={{
flexDirection: "row",
marginBottom: 10
}}
>
<Text style={styles.questionText}>
{/* {FieldsTranslations(rows[0].value)} */}
{FieldsTranslations(
rows[0].value,
locale
)}
</Text>
<Text style={styles.questionAnswer}>
{locale == "cy"
? jsonpath({
path:
'$..[?(@ && @.value=="' +
getPickListLabel(
props.pickListData,
datafieldname[0]
.value,
props.props[
datafieldname[0]
.value
]
) +
'")].value_cy',
json: transLookup,
eval: true
})
: getPickListLabel(
props.pickListData,
datafieldname[0]
.value,
props.props[
datafieldname[0]
.value
]
)}
</Text>
</View>
);
break;
case "{16D63FD6-119B-4353-BDCA-18358721C3FE}":
// const blobList = jsonpath({path:
// "$..[?(@ && @.documentType=='" +
// documentTypeCode[0].value +
// "')]",
// props.filesList
// );
//const blobList = props.filesList || [];
const blobList =
props.filesList.hasOwnProperty("value")
? props.filesList.value
: props.filesList || [];
return (
<View
style={{
flexDirection: "column",
marginBottom: 10
}}
>
<View
style={{
flexDirection: "column",
marginBottom: 10
}}
>
{/* Removed wrap={false} here so the list can flow to page 2 */}
<View
style={{
flexDirection: "row",
marginBottom: 10
}}
>
<Text
style={
styles.questionTextWide
}
>
{FieldsTranslations(
rows[0].value,
locale
)}
</Text>
</View>
<View
style={
styles.questionAnswerWide
}
>
{blobList.map((blob, i) => {
const isTargetType =
getDocumentTypeFromFilename(
blob.name
) ===
documentTypeCode[0]
.value;
if (!isTargetType)
return null;
return (
/* wrap={false} here ensures a single filename stays together */
<View
key={i}
wrap={false}
style={{
marginBottom: 4
}}
>
<Text
style={
styles.documentList
}
>
{blob.name}
{blob?.size &&
` - ${bytesToSize(blob.size)}`}
</Text>
</View>
);
})}
</View>
</View>
</View>
);
break;
case "{0273EDBD-AC1D-40d3-9FB2-095C621B552D}":
// console.log(
// datafieldname[0].value,
// props.props[datafieldname[0].value]
// );
return (
<View
style={{
flexDirection: "column",
marginBottom: 10
}}
wrap={false}
>
<View
wrap={false}
style={{
flexDirection: "row",
marginBottom: 10
}}
>
<Text
style={
styles.questionTextMid
}
>
{FieldsTranslations(
rows[0].value,
locale
)}
</Text>
</View>
<View
style={
styles.questionAnswerWide
}
>
<View
style={{
flexDirection: "column",
marginBottom: 10
}}
>
{(props.props.hasOwnProperty(
datafieldname[0].value
) &&
props.props[
datafieldname[0]
.value
] == null) ||
props.props[
datafieldname[0].value
] == undefined ? (
<View>
<Text>N/A</Text>
</View>
) : (
props.props[
datafieldname[0]
.value
].map(
(tenant, index) => {
return typeof tenant.pinswg_owners_firstname !=
"undefined" ||
typeof tenant.pinswg_agriculturaltenantname_firstname !=
"undefined" ? (
<View
key={
index
}
style={{
flexDirection:
"row",
marginBottom: 10
}}
>
<Text
style={{
width: "50%",
paddingRight:
"20"
}}
>
{tenant?.pinswg_agriculturaltenantname_firstname &&
tenant.pinswg_agriculturaltenantname_firstname +
" " +
tenant.pinswg_agriculturaltenantname_lastname}
{tenant?.pinswg_owners_firstname &&
tenant.pinswg_owners_firstname +
" " +
tenant.pinswg_owners_lastname}
{
" "
}
{tenant?.pinswg_owners_email &&
tenant.pinswg_owners_email}
{tenant?.pinswg_agriculturaltenantname_email &&
tenant.pinswg_agriculturaltenantname_email}
</Text>
<Text
style={{
width: "40%"
}}
>
Notice
served:{" "}
{formatDate(
tenant.dateserved
)}
</Text>
</View>
) : (
""
);
}
)
)}
</View>
</View>
</View>
);
case "{67FAC785-CD58-4f9f-ABB3-4B7DDC6ED5ED}":
return (
<View
style={{
flexDirection: "column",
marginBottom: 10
}}
wrap={false}
>
<View
wrap={false}
style={{
flexDirection: "row",
marginBottom: 10
}}
>
<Text
style={styles.questionText}
wrap={false}
>
{FieldsTranslations(
rows[0].value,
locale
)}
</Text>
<Text
style={
styles.questionAnswer
}
>
{props.props[
datafieldname[0].value
] == "true"
? locale == "cy"
? "Ydw"
: "Yes"
: locale == "cy"
? "Na"
: "No"}
</Text>
</View>
</View>
);
break;
default:
return (
<View
wrap={false}
style={{
flexDirection: "row",
marginBottom: 10
}}
>
<Text style={styles.questionText}>
{FieldsTranslations(
rows[0].value,
locale
)}
</Text>
<Text style={styles.questionAnswer}>
{
props.props[
datafieldname[0].value
]
}
</Text>
</View>
);
break;
}
})()}
</>
);
})}
</>
);
};