diff --git a/backend/workflow_manager/endpoint/destination.py b/backend/workflow_manager/endpoint/destination.py
index bdb37385d..53cf3637b 100644
--- a/backend/workflow_manager/endpoint/destination.py
+++ b/backend/workflow_manager/endpoint/destination.py
@@ -511,7 +511,7 @@ def _push_to_queue(
file_content = remote_file.read()
# Convert file content to a base64 encoded string
file_content_base64 = base64.b64encode(file_content).decode("utf-8")
- q_name = f"review_queue_{self.organization_id}_{workflow.workflow_name}"
+ q_name = f"review_queue_{self.organization_id}_{workflow.id}"
queue_result = QueueResult(
file=file_name,
whisper_hash=meta_data["whisper-hash"],
@@ -519,7 +519,7 @@ def _push_to_queue(
result=result,
workflow_id=str(self.workflow_id),
file_content=file_content_base64,
- )
+ ).to_dict()
# Convert the result dictionary to a JSON string
queue_result_json = json.dumps(queue_result)
conn = QueueUtils.get_queue_inst()
diff --git a/backend/workflow_manager/endpoint/queue_utils.py b/backend/workflow_manager/endpoint/queue_utils.py
index bbb4dddb3..17ca4e3c1 100644
--- a/backend/workflow_manager/endpoint/queue_utils.py
+++ b/backend/workflow_manager/endpoint/queue_utils.py
@@ -39,3 +39,13 @@ class QueueResult:
result: Any
workflow_id: str
file_content: str
+
+ def to_dict(self) -> Any:
+ return {
+ "file": self.file,
+ "whisper_hash": self.whisper_hash,
+ "status": self.status,
+ "result": self.result,
+ "workflow_id": self.workflow_id,
+ "file_content": self.file_content,
+ }
diff --git a/frontend/package-lock.json b/frontend/package-lock.json
index 2c7eec1d6..d7661da1f 100644
--- a/frontend/package-lock.json
+++ b/frontend/package-lock.json
@@ -11,6 +11,7 @@
"@ant-design/icons": "^5.1.4",
"@react-pdf-viewer/core": "^3.12.0",
"@react-pdf-viewer/default-layout": "^3.12.0",
+ "@react-pdf-viewer/highlight": "^3.12.0",
"@react-pdf-viewer/page-navigation": "^3.12.0",
"@rjsf/antd": "^5.16.1",
"@rjsf/core": "^5.8.1",
@@ -31,7 +32,7 @@
"http-proxy-middleware": "^2.0.6",
"js-cookie": "^3.0.5",
"js-yaml": "^4.1.0",
- "json-2-csv": "^5.5.4",
+ "json-2-csv": "^5.5.1",
"markdown-to-jsx": "^7.2.1",
"moment": "^2.29.4",
"moment-timezone": "^0.5.45",
@@ -3801,6 +3802,18 @@
"react-dom": ">=16.8.0"
}
},
+ "node_modules/@react-pdf-viewer/highlight": {
+ "version": "3.12.0",
+ "resolved": "https://registry.npmjs.org/@react-pdf-viewer/highlight/-/highlight-3.12.0.tgz",
+ "integrity": "sha512-UxdnvnvTjikugOUEj/RIeJm3Lm93aVu+Xr0jMa7d+wrZlHh5b7wTd+FeI6gNk9wdJDrB70oHiCzn6MTbepkc5g==",
+ "dependencies": {
+ "@react-pdf-viewer/core": "3.12.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.8.0",
+ "react-dom": ">=16.8.0"
+ }
+ },
"node_modules/@react-pdf-viewer/open": {
"version": "3.12.0",
"resolved": "https://registry.npmjs.org/@react-pdf-viewer/open/-/open-3.12.0.tgz",
@@ -23167,6 +23180,14 @@
"@react-pdf-viewer/core": "3.12.0"
}
},
+ "@react-pdf-viewer/highlight": {
+ "version": "3.12.0",
+ "resolved": "https://registry.npmjs.org/@react-pdf-viewer/highlight/-/highlight-3.12.0.tgz",
+ "integrity": "sha512-UxdnvnvTjikugOUEj/RIeJm3Lm93aVu+Xr0jMa7d+wrZlHh5b7wTd+FeI6gNk9wdJDrB70oHiCzn6MTbepkc5g==",
+ "requires": {
+ "@react-pdf-viewer/core": "3.12.0"
+ }
+ },
"@react-pdf-viewer/open": {
"version": "3.12.0",
"resolved": "https://registry.npmjs.org/@react-pdf-viewer/open/-/open-3.12.0.tgz",
diff --git a/frontend/package.json b/frontend/package.json
index 9a9bd21ae..80516d443 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -6,6 +6,7 @@
"@ant-design/icons": "^5.1.4",
"@react-pdf-viewer/core": "^3.12.0",
"@react-pdf-viewer/default-layout": "^3.12.0",
+ "@react-pdf-viewer/highlight": "^3.12.0",
"@react-pdf-viewer/page-navigation": "^3.12.0",
"@rjsf/antd": "^5.16.1",
"@rjsf/core": "^5.8.1",
@@ -26,7 +27,7 @@
"http-proxy-middleware": "^2.0.6",
"js-cookie": "^3.0.5",
"js-yaml": "^4.1.0",
- "json-2-csv": "^5.5.4",
+ "json-2-csv": "^5.5.1",
"markdown-to-jsx": "^7.2.1",
"moment": "^2.29.4",
"moment-timezone": "^0.5.45",
diff --git a/frontend/src/components/custom-tools/pdf-viewer/Highlight.css b/frontend/src/components/custom-tools/pdf-viewer/Highlight.css
new file mode 100644
index 000000000..48649cd0c
--- /dev/null
+++ b/frontend/src/components/custom-tools/pdf-viewer/Highlight.css
@@ -0,0 +1,9 @@
+.pdf-container {
+ position: relative;
+}
+
+.highlight {
+ position: absolute;
+ background-color: yellow;
+ opacity: 0.5;
+}
diff --git a/frontend/src/components/custom-tools/pdf-viewer/PdfViewer.jsx b/frontend/src/components/custom-tools/pdf-viewer/PdfViewer.jsx
index 4ee872189..2526fcfde 100644
--- a/frontend/src/components/custom-tools/pdf-viewer/PdfViewer.jsx
+++ b/frontend/src/components/custom-tools/pdf-viewer/PdfViewer.jsx
@@ -1,18 +1,43 @@
+import { useRef } from "react";
import { Viewer, Worker } from "@react-pdf-viewer/core";
import { defaultLayoutPlugin } from "@react-pdf-viewer/default-layout";
import { pageNavigationPlugin } from "@react-pdf-viewer/page-navigation";
import PropTypes from "prop-types";
+import { highlightPlugin } from "@react-pdf-viewer/highlight";
+import "@react-pdf-viewer/highlight/lib/styles/index.css";
+import "./Highlight.css";
-function PdfViewer({ fileUrl }) {
+let RenderHighlights;
+try {
+ RenderHighlights =
+ require("../../../plugins/pdf-highlight/RenderHighlights").RenderHighlights;
+} catch (err) {
+ // Do nothing, No plugin will be loaded.
+}
+
+function PdfViewer({ fileUrl, highlightData }) {
const newPlugin = defaultLayoutPlugin();
const pageNavigationPluginInstance = pageNavigationPlugin();
+ const parentRef = useRef(null);
+ let highlightPluginInstance = "";
+ if (RenderHighlights && highlightData) {
+ highlightPluginInstance = highlightPlugin({
+ renderHighlights: (props) => (
+