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) => ( + + ), + }); + } return ( -
+
@@ -21,6 +46,7 @@ function PdfViewer({ fileUrl }) { PdfViewer.propTypes = { fileUrl: PropTypes.any, + highlightData: PropTypes.array, }; export { PdfViewer };