diff --git a/web/src/components/FOI/Home/Edit.tsx b/web/src/components/FOI/Home/Edit.tsx
new file mode 100644
index 000000000..1a7cb8f03
--- /dev/null
+++ b/web/src/components/FOI/Home/Edit.tsx
@@ -0,0 +1,88 @@
+import { ReactComponent as EditLogo } from "../../../assets/images/icon-pencil-line.svg";
+
+ const disableMultiSelectEdit = (_selectedAnnotations: any) => {
+ if (_selectedAnnotations && _selectedAnnotations.length > 0) {
+ return _selectedAnnotations.some(
+ (obj: any) =>
+ obj.Subject !== "Redact" && obj.getCustomData("sections") === ""
+ );
+ }
+ return true;
+ };
+
+ //START: Bulk Edit using Multi Select Option
+ const MultiSelectEdit = ({docInstance, editRedactions}: any) => {
+ let _selectedAnnotations =
+ docInstance?.Core?.annotationManager.getSelectedAnnotations();
+ const disableEdit = disableMultiSelectEdit(_selectedAnnotations);
+ const _selectedRedactions = _selectedAnnotations?.filter(
+ (obj: any) =>
+ obj.Subject !== "Redact" && obj.getCustomData("sections") !== ""
+ );
+ return (
+
+ );
+ };
+ //END: Bulk Edit using Multi Select Option
+
+
+ const Edit = ({instance, editAnnotation}: any) => {
+ let _selectedAnnotations = instance?.Core?.annotationManager.getSelectedAnnotations();
+ const disableEdit = _selectedAnnotations.some(
+ (obj: any) =>
+ obj.Subject !== "Redact" && obj.getCustomData("sections") === ""
+ );
+ const _selectedRedaction = _selectedAnnotations.filter(
+ (obj: any) => obj.Subject === "Redact"
+ );
+ return (
+
+ );
+ };
+
+ export {
+ MultiSelectEdit,
+ Edit
+ };
\ No newline at end of file
diff --git a/web/src/components/FOI/Home/Redlining.js b/web/src/components/FOI/Home/Redlining.js
index 9fe6b8a2c..8c29df5e0 100644
--- a/web/src/components/FOI/Home/Redlining.js
+++ b/web/src/components/FOI/Home/Redlining.js
@@ -52,7 +52,11 @@ import {
getStitchedPageNoFromOriginal,
createPageFlagPayload,
sortByLastModified,
+ createRedactionSectionsString,
+ getSections,
+ getValidSections,
} from "./utils";
+import { Edit, MultiSelectEdit } from "./Edit";
import _ from "lodash";
const Redlining = React.forwardRef(
@@ -121,10 +125,8 @@ const Redlining = React.forwardRef(
// State variables for Bulk Edit using Multi Selection option
const [editRedacts, setEditRedacts] = useState(null);
- const [multiSelectedAnnotations, setMultiSelectedAnnotations] = useState(
- []
- );
const [multiSelectFooter, setMultiSelectFooter] = useState(null);
+ const [enableMultiSelect, setEnableMultiSelect] = useState(false);
//xml parser
const parser = new XMLParser();
@@ -190,56 +192,15 @@ const Redlining = React.forwardRef(
isReadyForSignOff() && requestStatus == RequestStates["Response"]
);
- //START: Bulk Edit using Multi Select Option
- const MultiSelectEdit = () => {
- let _selectedAnnotations = multiSelectedAnnotations;
- const disableEdit =
- _selectedAnnotations.length === 0 ||
- _selectedAnnotations?.some(
- (obj) =>
- obj.Subject !== "Redact" && obj.getCustomData("sections") === ""
- );
- const _selectedRedactions = _selectedAnnotations?.filter(
- (obj) =>
- obj.Subject !== "Redact" && obj.getCustomData("sections") !== ""
- );
- return (
-
- );
- };
- //END: Bulk Edit using Multi Select Option
-
// const [storedannotations, setstoreannotations] = useState(localStorage.getItem("storedannotations") || [])
// if using a class, equivalent of componentDidMount
useEffect(() => {
let initializeWebViewer = async () => {
let currentDocumentS3Url = currentDocument?.currentDocumentS3Url;
fetchSections(requestid, (error) => console.log(error));
- let response = await fetchPDFTronLicense(
- null,
- (error) => console.log(error)
- )
+ let response = await fetchPDFTronLicense(null, (error) =>
+ console.log(error)
+ );
WebViewer(
{
licenseKey: response.data.license,
@@ -390,45 +351,12 @@ const Redlining = React.forwardRef(
);
});
- const Edit = () => {
- let _selectedAnnotations = annotationManager.getSelectedAnnotations();
- const disableEdit = _selectedAnnotations.some(
- (obj) =>
- obj.Subject !== "Redact" && obj.getCustomData("sections") === ""
- );
- const _selectedRedaction = _selectedAnnotations.filter(
- (obj) => obj.Subject === "Redact"
- );
- return (
-
- );
- };
-
instance.UI.annotationPopup.add({
type: "customElement",
title: "Edit",
- render: () => ,
+ render: () => (
+
+ ),
});
setDocInstance(instance);
@@ -506,7 +434,7 @@ const Redlining = React.forwardRef(
multiDeleteButton?.addEventListener("click", function () {
root = null;
setMultiSelectFooter(root);
- setMultiSelectedAnnotations([]);
+ setEnableMultiSelect(false);
});
}
@@ -516,7 +444,7 @@ const Redlining = React.forwardRef(
closeButton?.addEventListener("click", function () {
root = null;
setMultiSelectFooter(root);
- setMultiSelectedAnnotations([]);
+ setEnableMultiSelect(false);
});
}
@@ -530,7 +458,7 @@ const Redlining = React.forwardRef(
if (isActive) {
root = null;
setMultiSelectFooter(root);
- setMultiSelectedAnnotations([]);
+ setEnableMultiSelect(false);
}
});
@@ -548,40 +476,19 @@ const Redlining = React.forwardRef(
_multiSelectFooter.firstChild
);
}
- const listItems = document.querySelectorAll('[role="listitem"]');
+ const listItems =
+ document.querySelectorAll('[role="listitem"]');
listItems.forEach((listItem) => {
- let checkbox = listItem.querySelector('input[type="checkbox"]');
+ let checkbox = listItem.querySelector(
+ 'input[type="checkbox"]'
+ );
if (checkbox) {
if (root === null) {
root = createRoot(editButton);
setMultiSelectFooter(root);
}
checkbox.addEventListener("click", function () {
- checkbox = listItem.querySelector('input[type="checkbox"]');
- const spanWrapper = checkbox.parentElement.parentElement; // Get the parent span element
- // Check if the span element has the "ui__choice--checked" class
- const isChecked = spanWrapper.classList.contains(
- "ui__choice--checked"
- ); //actual scenario isChecked = true when you uncheck the checkbox
- const selectedIdString = checkbox.id?.split("_");
- if (selectedIdString.length > 0) {
- const annotationName = selectedIdString[1];
- const _annot =
- annotationManager.getAnnotationById(annotationName);
- setMultiSelectedAnnotations((prevSelectedAnnotations) => {
- const isExists = prevSelectedAnnotations.find(
- (_annotation) => _annotation.Id === annotationName
- );
- if (isExists === undefined && !isChecked) {
- return [...prevSelectedAnnotations, _annot];
- } else if (isExists && isChecked) {
- return prevSelectedAnnotations.filter(
- (_annotation) => _annotation.Id !== annotationName
- );
- }
- return prevSelectedAnnotations;
- });
- }
+ setEnableMultiSelect(true);
});
}
});
@@ -591,19 +498,10 @@ const Redlining = React.forwardRef(
true
);
});
- }
+ };
initializeWebViewer();
}, []);
- //START: UE to render MultiSelectEdit part of Bulk Edit using Multi Select Option
- useEffect(() => {
- if (multiSelectFooter) {
- multiSelectFooter.render();
- }
- }, [multiSelectedAnnotations]);
-
- //END: UE to render MultiSelectEdit part of Bulk Edit using Multi Select Option
-
useEffect(() => {
const changeLayer = async () => {
if (currentLayer) {
@@ -967,7 +865,7 @@ const Redlining = React.forwardRef(
}
}
});
- docInstance.Core.Annotations.NoMove=true;
+ docInstance.Core.Annotations.NoMove = true;
setAnnots(docInstance.Core.Annotations);
}
},
@@ -982,25 +880,14 @@ const Redlining = React.forwardRef(
useEffect(() => {
annotManager?.addEventListener("annotationSelected", (annotations) => {
- //START - handled grouped annotation selection due to auto multi select issue part of Bulk Edit using Multi Select Option.
- // get freetext annotations with redaction sections alone
- const _selectedRedactions = annotations.filter(
- (obj) =>
- obj.Subject !== "Redact" && obj.getCustomData("sections") !== ""
- );
- let annotationName = _selectedRedactions[0]?.Id;
- if (annotationName) {
- setMultiSelectedAnnotations((prevSelectedAnnotations) => {
- const isExists = prevSelectedAnnotations.find(
- (_annotation) => _annotation.Id === annotationName
- );
- if (isExists === undefined) {
- return [...prevSelectedAnnotations, _selectedRedactions[0]];
- }
- return prevSelectedAnnotations;
- });
+ if (multiSelectFooter && enableMultiSelect) {
+ multiSelectFooter.render(
+
+ );
}
- //END - handled grouped annotation selection due to auto multi select issue part of Bulk Edit using Multi Select Option.
});
annotManager?.removeEventListener(
@@ -1023,6 +910,8 @@ const Redlining = React.forwardRef(
newRedaction,
pageSelections,
redlineSaving,
+ multiSelectFooter,
+ enableMultiSelect,
]);
useImperativeHandle(ref, () => ({
@@ -1195,7 +1084,7 @@ const Redlining = React.forwardRef(
_annotation.NoMove = true;
if (_annotation.Subject === "Redact") {
_annotation.IsHoverable = false;
-
+
if (_annotation.type === "fullPage") {
_annotation.NoResize = true;
annotManager.bringToBack(_annotation);
@@ -1259,26 +1148,16 @@ const Redlining = React.forwardRef(
childAnnotation.Y = _redact.Y;
childAnnotation.FontSize = _redact.FontSize;
if (redactionSectionsIds.length > 0) {
- let redactionSections = sections
- .filter((s) => redactionSectionsIds.indexOf(s.id) > -1)
- .map((s) => s.section)
- .join(", ");
- if (
- redactionSectionsIds?.length == 1 &&
- redactionSectionsIds[0] === 25
- ) {
- redactionSections = " ";
- }
+ let redactionSections = createRedactionSectionsString(
+ sections,
+ redactionSectionsIds
+ );
childAnnotation.setContents(redactionSections);
const displayedDoc =
pageMappedDocs.stitchedPageLookup[Number(node.attributes.page) + 1];
childAnnotation.setCustomData(
"sections",
- JSON.stringify(
- sections
- .filter((s) => redactionSectionsIds.indexOf(s.id) > -1)
- .map((s) => ({ id: s.id, section: s.section }))
- )
+ JSON.stringify(getSections(sections, redactionSectionsIds))
);
childAnnotation.setCustomData("docid", displayedDoc.docid);
childAnnotation.setCustomData("docversion", displayedDoc.docversion);
@@ -1323,7 +1202,7 @@ const Redlining = React.forwardRef(
});
}
setSelectedSections([]);
- setMultiSelectedAnnotations([]);
+ setEnableMultiSelect(false);
setEditRedacts(null);
});
@@ -1361,16 +1240,10 @@ const Redlining = React.forwardRef(
childAnnotation = getCoordinates(childAnnotation, redaction, X);
let redactionSectionsIds = selectedSections;
if (redactionSectionsIds.length > 0) {
- let redactionSections = sections
- .filter((s) => redactionSectionsIds.indexOf(s.id) > -1)
- .map((s) => s.section)
- .join(", ");
- if (
- redactionSectionsIds?.length == 1 &&
- redactionSectionsIds[0] === 25
- ) {
- redactionSections = " ";
- }
+ let redactionSections = createRedactionSectionsString(
+ sections,
+ redactionSectionsIds
+ );
childAnnotation.setContents(redactionSections);
const displayedDoc =
pageMappedDocs.stitchedPageLookup[
@@ -1378,11 +1251,7 @@ const Redlining = React.forwardRef(
];
childAnnotation.setCustomData(
"sections",
- JSON.stringify(
- sections
- .filter((s) => redactionSectionsIds.indexOf(s.id) > -1)
- .map((s) => ({ id: s.id, section: s.section }))
- )
+ JSON.stringify(getSections(sections, redactionSectionsIds))
);
childAnnotation.setCustomData("docid", displayedDoc.docid);
childAnnotation.setCustomData(
@@ -1470,22 +1339,16 @@ const Redlining = React.forwardRef(
annot.Author = user?.name || user?.preferred_username || "";
let redactionSectionsIds =
defaultSections.length > 0 ? defaultSections : selectedSections;
- let redactionSections = sections.filter(
- (s) => redactionSectionsIds.indexOf(s.id) > -1
+ let redactionSections = createRedactionSectionsString(
+ sections,
+ redactionSectionsIds
);
- let redactionSectionsString = redactionSections
- .map((s) => s.section)
- .join(", ");
- if (selectedSections?.length == 1 && selectedSections[0] === 25) {
- redactionSectionsString = " ";
- }
- annot.setContents(redactionSectionsString);
+ annot.setAutoSizeType("auto");
+ annot.setContents(redactionSections);
annot.setCustomData("parentRedaction", redaction.Id);
annot.setCustomData(
"sections",
- JSON.stringify(
- redactionSections.map((s) => ({ id: s.id, section: s.section }))
- )
+ JSON.stringify(getSections(sections, redactionSectionsIds))
);
const doc = docViewer.getDocument();
const pageInfo = doc.getPageInfo(annot.PageNumber);
@@ -1539,7 +1402,10 @@ const Redlining = React.forwardRef(
}
}
- for (let section of redactionSections) {
+ for (let section of getValidSections(
+ sections,
+ redactionSectionsIds
+ )) {
section.count++;
}
//delete if there are existing fullpage redactions
@@ -2049,7 +1915,7 @@ const Redlining = React.forwardRef(
// saves the document with annotations in it
xfdfString: xfdfString,
downloadType: downloadType,
- flatten: true
+ flatten: true,
})
.then(async (_data) => {
const _arr = new Uint8Array(_data);
diff --git a/web/src/components/FOI/Home/utils.js b/web/src/components/FOI/Home/utils.js
index e5af50971..7aedd0a3a 100644
--- a/web/src/components/FOI/Home/utils.js
+++ b/web/src/components/FOI/Home/utils.js
@@ -71,3 +71,27 @@ export const getProgramAreas = (pageFlagList) => {
// Helper function to sort files by lastmodified date
export const sortByLastModified = (files) => files.sort(docSorting);
+
+export const getValidSections = (sections, redactionSectionsIds) => {
+ return sections.filter((s) => redactionSectionsIds.indexOf(s.id) > -1);
+};
+
+export const getSections = (sections, redactionSectionsIds) => {
+ return getValidSections(sections, redactionSectionsIds).map((s) => ({
+ id: s.id,
+ section: s.section,
+ }));
+};
+
+export const createRedactionSectionsString = (
+ sections,
+ redactionSectionsIds
+) => {
+ let redactionSections = getValidSections(sections, redactionSectionsIds)
+ .map((s) => s.section)
+ .join(", ");
+ if (redactionSectionsIds?.length == 1 && redactionSectionsIds[0] === 25) {
+ redactionSections = " ";
+ }
+ return redactionSections;
+};