fix for pdf formatting and hyperlinks
This commit is contained in:
+115
-114
@@ -5,7 +5,7 @@ import {
|
||||
getBasicSearchDetails,
|
||||
getBasicSearchDetailsPaged,
|
||||
getPortalModuleDetailsProxy,
|
||||
getPortalModuleDetails,
|
||||
getPortalModuleDetails
|
||||
} from "../../actions";
|
||||
import data from "../../data/collections.json";
|
||||
import { useRouter } from "next/router";
|
||||
@@ -20,7 +20,7 @@ export const getFormCollection = (formtype) => {
|
||||
const collectionName = jsonpath({
|
||||
path: "$..[?(@ && @.LogicalName=='" + formtype + "')]",
|
||||
json: data,
|
||||
eval: true,
|
||||
eval: true
|
||||
});
|
||||
return collectionName[0];
|
||||
};
|
||||
@@ -29,7 +29,7 @@ export const getFormCollectionByID = (appealTypeID) => {
|
||||
const collectionName = jsonpath({
|
||||
path: "$..[?(@ && @.appealTypeID =='" + appealTypeID + "')]",
|
||||
json: data,
|
||||
eval: true,
|
||||
eval: true
|
||||
});
|
||||
return collectionName[0];
|
||||
};
|
||||
@@ -38,7 +38,7 @@ export const getNavigationPropertyByPrimaryAttribute = (primaryAttribute) => {
|
||||
const collectionName = jsonpath({
|
||||
path: "$..[?(@ && @.PrimaryIdAttribute =='" + primaryAttribute + "')]",
|
||||
json: data,
|
||||
eval: true,
|
||||
eval: true
|
||||
});
|
||||
return collectionName[0];
|
||||
};
|
||||
@@ -47,7 +47,7 @@ export const getFormIDByLogicalName = (appealTypeLogicalName) => {
|
||||
const collectionName = jsonpath({
|
||||
path: "$..[?(@ && @.LogicalName =='" + appealTypeLogicalName + "')]",
|
||||
json: data,
|
||||
eval: true,
|
||||
eval: true
|
||||
});
|
||||
return collectionName[0];
|
||||
};
|
||||
@@ -56,7 +56,7 @@ export const getPickListLabel = (data, picklistType, picklistID) => {
|
||||
const pickListData = jsonpath({
|
||||
path: "$..[?(@ && @.LogicalName=='" + picklistType + "')]",
|
||||
json: data,
|
||||
eval: true,
|
||||
eval: true
|
||||
});
|
||||
|
||||
const pickListLabel = jsonpath({
|
||||
@@ -66,7 +66,7 @@ export const getPickListLabel = (data, picklistType, picklistID) => {
|
||||
"')].Label.LocalizedLabels..Label",
|
||||
|
||||
json: pickListData,
|
||||
eval: true,
|
||||
eval: true
|
||||
});
|
||||
return pickListLabel[0];
|
||||
};
|
||||
@@ -75,7 +75,7 @@ export const getRadioLabel = (data, radiotListName, radioListID) => {
|
||||
const radioListData = jsonpath({
|
||||
path: "$..[?(@ && @.LogicalName=='" + radiotListName + "')]",
|
||||
json: data,
|
||||
eval: true,
|
||||
eval: true
|
||||
});
|
||||
|
||||
const pickListLabel = jsonpath({
|
||||
@@ -85,7 +85,7 @@ export const getRadioLabel = (data, radiotListName, radioListID) => {
|
||||
"')].Label.LocalizedLabels..Label",
|
||||
|
||||
json: radioListData,
|
||||
eval: true,
|
||||
eval: true
|
||||
});
|
||||
return pickListLabel[0];
|
||||
};
|
||||
@@ -100,7 +100,7 @@ export const getSearchDetails = async (searchResultsObj) => {
|
||||
searchResultsObj = searchResultsObj.value;
|
||||
const detailsObj = searchResultsObj.map((searchDetail, index) => {
|
||||
let formMeta = getFormCollectionByID(
|
||||
searchDetail.pinswg_appealcasetype,
|
||||
searchDetail.pinswg_appealcasetype
|
||||
);
|
||||
// console.log(
|
||||
// "------------------- Details: ",
|
||||
@@ -117,11 +117,11 @@ export const getSearchDetails = async (searchResultsObj) => {
|
||||
"pinswg_dnses",
|
||||
searchDetail.title,
|
||||
"pinswg_dnsid",
|
||||
searchDetail.incidentid,
|
||||
searchDetail.incidentid
|
||||
) || {
|
||||
"@odata.count": 1,
|
||||
"value": [{ "title": searchDetail.title }],
|
||||
},
|
||||
"value": [{ "title": searchDetail.title }]
|
||||
}
|
||||
);
|
||||
} else {
|
||||
// formMeta?.LogicalCollectionName &&
|
||||
@@ -131,11 +131,11 @@ export const getSearchDetails = async (searchResultsObj) => {
|
||||
formMeta.LogicalCollectionName,
|
||||
searchDetail.title,
|
||||
formMeta.PrimaryIdAttribute,
|
||||
searchDetail.incidentid,
|
||||
searchDetail.incidentid
|
||||
) || {
|
||||
"@odata.count": 1,
|
||||
"value": [{ "title": searchDetail.title }],
|
||||
},
|
||||
"value": [{ "title": searchDetail.title }]
|
||||
}
|
||||
);
|
||||
}
|
||||
});
|
||||
@@ -159,7 +159,7 @@ export const getPartSavedDetails = (searchResultsObj) => {
|
||||
console.log(searchDetail.title);
|
||||
} else {
|
||||
let formMeta = getFormCollectionByID(
|
||||
searchDetail.pinswg_appealcasetype,
|
||||
searchDetail.pinswg_appealcasetype
|
||||
);
|
||||
// console.log(formMeta);
|
||||
detailsArr.push(
|
||||
@@ -167,8 +167,8 @@ export const getPartSavedDetails = (searchResultsObj) => {
|
||||
formMeta.LogicalCollectionName,
|
||||
searchDetail.title,
|
||||
formMeta.PrimaryIdAttribute,
|
||||
searchDetail.incidentid,
|
||||
),
|
||||
searchDetail.incidentid
|
||||
)
|
||||
);
|
||||
}
|
||||
});
|
||||
@@ -279,7 +279,7 @@ export const getSearchDetailsPaged = async (searchResultsObj) => {
|
||||
if (!acc[appealType]) acc[appealType] = [];
|
||||
acc[appealType].push({
|
||||
incidentID: detail.incidentid,
|
||||
title: detail.title,
|
||||
title: detail.title
|
||||
});
|
||||
return acc;
|
||||
}, {});
|
||||
@@ -307,7 +307,7 @@ export const getSearchDetailsPaged = async (searchResultsObj) => {
|
||||
formMeta.LogicalCollectionName, // appealTypeName
|
||||
null, // caseReference is no longer used in batch
|
||||
formMeta.PrimaryIdAttribute, // primaryIdAttribute
|
||||
incidentIDs, // pass array of incidentIDs
|
||||
incidentIDs // pass array of incidentIDs
|
||||
);
|
||||
|
||||
allDetails.push(...details);
|
||||
@@ -323,7 +323,7 @@ export const getProgressObj = (
|
||||
formObjXML,
|
||||
titleList,
|
||||
mandatoryFieldsData,
|
||||
props,
|
||||
props
|
||||
) => {
|
||||
const parser = new DOMParser();
|
||||
const BuildFormObj = (formObjXML) => {
|
||||
@@ -336,7 +336,7 @@ export const getProgressObj = (
|
||||
"//tabs/tab[" +
|
||||
(index + 1) +
|
||||
"]//rows/row/control[not(@parentField)]/..",
|
||||
doc,
|
||||
doc
|
||||
);
|
||||
|
||||
return BuildRowObj(sectionXML, titleList[key].value);
|
||||
@@ -376,10 +376,10 @@ export const getProgressObj = (
|
||||
0) ||
|
||||
(_.has(props.props.form.appealForm, "values") &&
|
||||
Object.keys(
|
||||
props.props.form.appealForm.values,
|
||||
props.props.form.appealForm.values
|
||||
).filter((k) => k.startsWith("pinswg_fileUpload"))
|
||||
.length > 0)
|
||||
: rowCount == formObj[key].fieldsTotal,
|
||||
: rowCount == formObj[key].fieldsTotal
|
||||
};
|
||||
});
|
||||
|
||||
@@ -401,17 +401,17 @@ export const getProgressObj = (
|
||||
|
||||
var parentFieldShowOnValue = xpath.select(
|
||||
"//@parentFieldShowOnValue",
|
||||
doc,
|
||||
doc
|
||||
);
|
||||
|
||||
var requiredDocumentValue = xpath.select(
|
||||
"//@requiredDocumentValue",
|
||||
doc,
|
||||
doc
|
||||
);
|
||||
|
||||
var requiredDocumentLabel = xpath.select(
|
||||
"//@requiredDocumentLabel",
|
||||
doc,
|
||||
doc
|
||||
);
|
||||
|
||||
var hint = xpath.select("//label/@hint", doc);
|
||||
@@ -449,7 +449,7 @@ export const getProgressObj = (
|
||||
datafieldname[0].value +
|
||||
"')]",
|
||||
json: mandatoryFieldsData,
|
||||
eval: true,
|
||||
eval: true
|
||||
});
|
||||
|
||||
if (datafieldname[0].value.includes("pinswg_fileUpload")) {
|
||||
@@ -461,7 +461,7 @@ export const getProgressObj = (
|
||||
"label": rows[0].value,
|
||||
"datafieldname": datafieldname[0].value,
|
||||
"datafieldcontent": datafieldcontent,
|
||||
"validation": validation,
|
||||
"validation": validation
|
||||
};
|
||||
}
|
||||
} else {
|
||||
@@ -471,7 +471,7 @@ export const getProgressObj = (
|
||||
"datafieldname": datafieldname[0].value,
|
||||
"key": key,
|
||||
"picklistData": props.props.formData.pickListData,
|
||||
"mandatoryFieldsData": mandatoryFieldsData,
|
||||
"mandatoryFieldsData": mandatoryFieldsData
|
||||
};
|
||||
}
|
||||
} else {
|
||||
@@ -483,7 +483,7 @@ export const getProgressObj = (
|
||||
"label": rows[0].value,
|
||||
"datafieldname": datafieldname[0].value,
|
||||
"datafieldcontent": datafieldcontent,
|
||||
"validation": validation,
|
||||
"validation": validation
|
||||
};
|
||||
} else {
|
||||
return null;
|
||||
@@ -518,7 +518,7 @@ export const getProgressObj = (
|
||||
"title": titleList,
|
||||
"validationFieldsTotal": filterUnwanted(rowObj).length,
|
||||
"fieldsTotal": rowObj.length,
|
||||
"fieldsrowObj": rowObj,
|
||||
"fieldsrowObj": rowObj
|
||||
};
|
||||
};
|
||||
|
||||
@@ -616,7 +616,7 @@ export const getDetailsProxy = (resultsObj, detailsType) => {
|
||||
? searchDetail.ticketnumber
|
||||
: searchDetail[
|
||||
"_pinswg_watchedcase_value@OData.Community.Display.V1.FormattedValue"
|
||||
],
|
||||
]
|
||||
);
|
||||
} else {
|
||||
detailsArr.push(
|
||||
@@ -627,8 +627,8 @@ export const getDetailsProxy = (resultsObj, detailsType) => {
|
||||
? searchDetail.ticketnumber
|
||||
: searchDetail[
|
||||
"_pinswg_watchedcase_value@OData.Community.Display.V1.FormattedValue"
|
||||
],
|
||||
),
|
||||
]
|
||||
)
|
||||
);
|
||||
}
|
||||
});
|
||||
@@ -678,98 +678,99 @@ export const getDocumentTypeFromFilename = (filename) => {
|
||||
return doctypeCode;
|
||||
};
|
||||
|
||||
export const updateLinks = (jsonObj) => {
|
||||
const parser = new DOMParser();
|
||||
export const updateLinks = (input) => {
|
||||
const EMPTY_QUILL_PARAGRAPHS_REGEX =
|
||||
/<p[^>]*>\s*(?:<br\s*\/?>| |\s)*\s*<\/p>/gi;
|
||||
|
||||
// Function to process the HTML string and replace URLs with <a> tags
|
||||
const processHtmlString = (htmlString) => {
|
||||
const doc = parser.parseFromString(htmlString, "text/html");
|
||||
const URL_REGEX = /\b(https?:\/\/[^\s<]+)/gi;
|
||||
|
||||
// Find all text nodes in the document
|
||||
const walk = (node) => {
|
||||
if (node.nodeType === Node.TEXT_NODE) {
|
||||
const urlRegex =
|
||||
/(?:https?:\/\/)?(?:www\.)?([a-zA-Z0-9.-]+\.[a-zA-Z]{2,})(\/[^\s]*)?/g;
|
||||
let match;
|
||||
let currentText = node.textContent;
|
||||
let lastIndex = 0;
|
||||
let newNodeContent = [];
|
||||
const stripTrailingUrlPunctuation = (url) => {
|
||||
let cleanUrl = url;
|
||||
let trailing = "";
|
||||
|
||||
// Process all URLs found in the current text node
|
||||
while ((match = urlRegex.exec(currentText)) !== null) {
|
||||
// Before the URL
|
||||
if (match.index > lastIndex) {
|
||||
newNodeContent.push(
|
||||
currentText.slice(lastIndex, match.index),
|
||||
);
|
||||
while (/[.,!?;:'"]$/.test(cleanUrl)) {
|
||||
trailing = cleanUrl.slice(-1) + trailing;
|
||||
cleanUrl = cleanUrl.slice(0, -1);
|
||||
}
|
||||
|
||||
const pairs = [
|
||||
[")", "("],
|
||||
["]", "["],
|
||||
["}", "{"]
|
||||
];
|
||||
|
||||
let changed = true;
|
||||
while (changed && cleanUrl) {
|
||||
changed = false;
|
||||
|
||||
for (const [close, open] of pairs) {
|
||||
if (cleanUrl.endsWith(close)) {
|
||||
const openCount = (
|
||||
cleanUrl.match(new RegExp(`\\${open}`, "g")) || []
|
||||
).length;
|
||||
const closeCount = (
|
||||
cleanUrl.match(new RegExp(`\\${close}`, "g")) || []
|
||||
).length;
|
||||
|
||||
if (closeCount > openCount) {
|
||||
trailing = close + trailing;
|
||||
cleanUrl = cleanUrl.slice(0, -1);
|
||||
changed = true;
|
||||
}
|
||||
|
||||
// Construct the full URL (default to https://)
|
||||
let fullUrl = match[0];
|
||||
if (
|
||||
!fullUrl.startsWith("http://") &&
|
||||
!fullUrl.startsWith("https://")
|
||||
) {
|
||||
fullUrl = `https://${match[1]}${match[2] || ""}`; // Default to https
|
||||
}
|
||||
|
||||
// Create the anchor element
|
||||
const anchor = document.createElement("a");
|
||||
anchor.href = fullUrl;
|
||||
anchor.textContent = match[0];
|
||||
anchor.target = "_blank";
|
||||
anchor.setAttribute("rel", "noopener noreferrer");
|
||||
|
||||
// Add the anchor tag to the node content
|
||||
newNodeContent.push(anchor);
|
||||
|
||||
// Update the last index processed
|
||||
lastIndex = urlRegex.lastIndex;
|
||||
}
|
||||
|
||||
// Add the remaining text after the last URL
|
||||
if (lastIndex < currentText.length) {
|
||||
newNodeContent.push(currentText.slice(lastIndex));
|
||||
}
|
||||
|
||||
// If there were any replacements, update the text node
|
||||
if (newNodeContent.length > 0) {
|
||||
const fragment = document.createDocumentFragment();
|
||||
newNodeContent.forEach((item) => {
|
||||
if (typeof item === "string") {
|
||||
fragment.appendChild(document.createTextNode(item));
|
||||
} else {
|
||||
fragment.appendChild(item);
|
||||
}
|
||||
});
|
||||
node.parentNode.replaceChild(fragment, node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Traverse child nodes
|
||||
for (let i = 0; i < node.childNodes.length; i++) {
|
||||
walk(node.childNodes[i]);
|
||||
}
|
||||
};
|
||||
|
||||
walk(doc.body);
|
||||
|
||||
return doc.body.innerHTML;
|
||||
return { cleanUrl, trailing };
|
||||
};
|
||||
|
||||
// Iterate over the JSON object and process values that are strings (HTML content)
|
||||
for (const key in jsonObj) {
|
||||
if (jsonObj.hasOwnProperty(key)) {
|
||||
const value = jsonObj[key];
|
||||
const processHtmlString = (htmlString) => {
|
||||
if (typeof htmlString !== "string" || !htmlString) return htmlString;
|
||||
|
||||
// If the value is a string and contains HTML, process it
|
||||
if (typeof value === "string" && /<[^>]*>/g.test(value)) {
|
||||
jsonObj[key] = processHtmlString(value);
|
||||
let html = htmlString.replace(EMPTY_QUILL_PARAGRAPHS_REGEX, "");
|
||||
|
||||
const anchorPlaceholders = [];
|
||||
html = html.replace(/<a\b[^>]*>[\s\S]*?<\/a>/gi, (match) => {
|
||||
const token = `__ANCHOR_PLACEHOLDER_${anchorPlaceholders.length}__`;
|
||||
anchorPlaceholders.push(match);
|
||||
return token;
|
||||
});
|
||||
|
||||
html = html.replace(URL_REGEX, (match) => {
|
||||
const { cleanUrl, trailing } = stripTrailingUrlPunctuation(match);
|
||||
|
||||
if (!cleanUrl) return match;
|
||||
|
||||
return `<a href="${cleanUrl}" target="_blank" rel="noopener noreferrer">${cleanUrl}</a>${trailing}`;
|
||||
});
|
||||
|
||||
html = html.replace(/__ANCHOR_PLACEHOLDER_(\d+)__/g, (_, index) => {
|
||||
return anchorPlaceholders[Number(index)];
|
||||
});
|
||||
|
||||
return html;
|
||||
};
|
||||
|
||||
if (typeof input === "string") {
|
||||
return processHtmlString(input);
|
||||
}
|
||||
|
||||
if (!input || typeof input !== "object" || Array.isArray(input)) {
|
||||
return input;
|
||||
}
|
||||
|
||||
const updated = { ...input };
|
||||
|
||||
for (const key in updated) {
|
||||
if (Object.prototype.hasOwnProperty.call(updated, key)) {
|
||||
const value = updated[key];
|
||||
if (typeof value === "string") {
|
||||
updated[key] = processHtmlString(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return jsonObj;
|
||||
return updated;
|
||||
};
|
||||
|
||||
export const whichRepType = (props) => {
|
||||
|
||||
Reference in New Issue
Block a user