Skip to content

Use setExtractionStatus action/reducer to propagate the message in th… #97

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Dec 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "consort-frontend",
"version": "0.8.0",
"version": "0.9.0",
"description": "",
"engines": {
"npm": ">=8.11",
Expand Down
30 changes: 11 additions & 19 deletions src/actions/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,6 @@ import {ADD_FILE_TO_DATASET, addFileToDataset, CREATE_DATASETS, createDataset} f

const clientInfo = await getClientInfo();

export function setStatement(statementType) {
return (dispatch) => {
dispatch({
type: 'SET_STATEMENT_TYPE',
statementType: statementType,
receivedAt: Date.now(),
});
};
}

// createUploadExtract thunk function
export function createUploadExtract(file, config) {
Expand All @@ -43,29 +34,30 @@ export function createUploadExtract(file, config) {
if (file_json !== undefined){
file_json["filename"] = file.name;
// submit uploaded file for extraction
dispatch(setExtractionStatus("Analyzing file"));
if (file.type == "application/vnd.openxmlformats-officedocument.wordprocessingml.document" || file.type =="application/msword"){
const word_pipeline_status = await wordPipeline(file_json, dataset_json, config, clientInfo);
if (word_pipeline_status) {
console.log("File extraction complete.");
dispatch(setExtractionStatus(SET_EXTRACTION_STATUS, true));
console.log("File extraction complete");
dispatch(setExtractionStatus("File extraction complete"));

}
else {
console.error("File extraction failed");
dispatch(setExtractionStatus(SET_EXTRACTION_STATUS, false));
dispatch(setExtractionStatus("File extraction failed"));
}

}
else if (file.type == "application/pdf") {
const pdf_pipeline_status = await pdfPipeline(file_json, dataset_json, config, clientInfo);
if (pdf_pipeline_status) {
console.log("File extraction complete.");
dispatch(setExtractionStatus(SET_EXTRACTION_STATUS, true));
dispatch(setExtractionStatus("File extraction complete"));

}
else {
console.error("File extraction failed");
dispatch(setExtractionStatus(SET_EXTRACTION_STATUS, false));
dispatch(setExtractionStatus("File extraction failed"));
}

// TODO add extracted output files to dataset state
Expand All @@ -75,20 +67,20 @@ export function createUploadExtract(file, config) {
else {
// TODO add error action
console.error("Error in file type");
dispatch(setExtractionStatus(SET_EXTRACTION_STATUS, false));
dispatch(setExtractionStatus("Error in file type"));
}
// after submitting uploaded file for extraction, add the file to dataset state
dispatch(addFileToDataset(ADD_FILE_TO_DATASET, file_json));
}
else {
console.error("Error in clowder upload of file ", file.name)
dispatch(setExtractionStatus(SET_EXTRACTION_STATUS, false));
dispatch(setExtractionStatus("Error in clowder upload of file " + file.name));
}
}
else {
console.error("Error in dataset creation");
dispatch(setExtractionStatus(SET_EXTRACTION_STATUS, false));
}
dispatch(setExtractionStatus("Error in dataset creation"));
}
};
}

4 changes: 2 additions & 2 deletions src/actions/file.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,10 @@ export function fetchFileMetadataJsonld(id) {
}

export const SET_EXTRACTION_STATUS = "SET_EXTRACTION_STATUS";
export function setExtractionStatus(type, status) {
export function setExtractionStatus(status) {
return (dispatch) => {
dispatch({
type: type,
type: SET_EXTRACTION_STATUS,
extractionStatus: status
});
};
Expand Down
44 changes: 18 additions & 26 deletions src/components/childComponents/CreateAndUpload.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {getClientInfo} from "../../utils/common";
import Dropfile from "./Dropfile";
import {createUploadExtract} from "../../actions/client";
import {getDatasetMetadata, getFileInDataset} from "../../utils/dataset";
import {fetchFilePreviews} from "../../actions/file";
import { fetchFilePreviews, SET_EXTRACTION_STATUS, setExtractionStatus } from "../../actions/file";
import {SET_DATASET_METADATA, setDatasetMetadata} from "../../actions/dataset";
import {SET_STATEMENT_TYPE, setStatement} from '../../actions/statement';
import config from "../../app.config";
Expand All @@ -27,7 +27,6 @@ export default function CreateAndUpload() {
const rctExtractor = config.rct_extractor;

const [mouseHover, setMouseHover] = useState(false); // mouse hover state for dropzone
const [statementTypeSelected, setStatementTypeSelected] = useState(false); // user choice of statement type consort or spirit
const [loading, setLoading] = useState(false); // loading overlay state and button disabled state. set to active when dropfile is active
const [loading_text, setLoadingText] = useState("Processing"); // loading overlay text.
const [filename, setFilename] = useState(''); // uploaded filename
Expand All @@ -39,11 +38,11 @@ export default function CreateAndUpload() {
const extractionStatus = useSelector(state => state.file.extractionStatus);
const listFilePreviews = (fileId, clientInfo) => dispatch(fetchFilePreviews(fileId, clientInfo));
const datasetMetadata = (json) => dispatch(setDatasetMetadata(SET_DATASET_METADATA, json));
const statementType = useSelector(state => state.statement.statementType);

const handleStatementChange = (event) => {
dispatch(setStatement(SET_STATEMENT_TYPE, event.target.value));
config.statementType = event.target.value;
setStatementTypeSelected(true);
};

const onDropFile = (file) => {
Expand All @@ -55,13 +54,13 @@ export default function CreateAndUpload() {

// useEffect on extractionStatus for preview generation
useEffect(async () => {
if (extractionStatus !== null && extractionStatus === true) {
if (extractionStatus !== null) {
setLoadingText(extractionStatus);
const clientInfo = await getClientInfo();
const file_name = filename.replace(/\.[^/.]+$/, ""); // get filename without extension;
const dataset_id = datasets[0].id;
// check extraction status and html file generation in loop
const html_file_loop = async () => {
setLoadingText("Checking extraction status");
const highlights_filename = file_name + '_highlights' + '.json'
const highlightsFile = await getFileInDataset(dataset_id, "application/json", highlights_filename, clientInfo);
if (highlightsFile !== null && typeof highlightsFile.id === "string") {
Expand All @@ -86,7 +85,6 @@ export default function CreateAndUpload() {
}
datasetMetadata(metadata);

setLoadingText("Extraction completed");
setPreview(false) // Continue button activated
setSpinner(false); // stop display of spinner
} else {
Expand All @@ -102,35 +100,30 @@ export default function CreateAndUpload() {
}
}
else if (extractionStatus === false){
setLoadingText("Error in extraction");
dispatch(setExtractionStatus("Error in extraction"));
setSpinner(false); // stop display of spinner
}
}, [extractionStatus]);
}, [extractionStatus]); // TODO: This useEffect will trigger again when the extractionStatus is completed


// onDrop function to trigger createUploadExtract action dispatch
const onDrop = useCallback((acceptedFiles, rejectedFiles) => {
if (!statementTypeSelected) {
setLoadingText("Please select a statement type (Trial results or Trial protocol) first");
setSpinner(false);
return;
}

// this callback function is triggered when a file is dropped into the dropzone
setLoading(true);
try {
acceptedFiles.map(file => {
onDropFile(file)
})
rejectedFiles.map(file => {
setLoadingText("File rejected");
dispatch(setExtractionStatus("File rejected"));
setSpinner(false);
})
}
catch(error) {
setLoadingText("Upload failed", error)
dispatch(setExtractionStatus("Upload failed"));
setSpinner(false);
}
}, [mouseHover, statementTypeSelected]);
}, [mouseHover]);


const goToPreviewRoute = () => {
Expand All @@ -144,23 +137,22 @@ export default function CreateAndUpload() {
<Box className="createupload">
<LoadingOverlay active={loading} text={loading_text} spinner={spinner}>
<div className="mousehoverdrop" onMouseEnter={() => setMouseHover(true)}>
<Dropfile
onDrop={onDrop}
<Dropfile
onDrop={onDrop}
accept={{
"application/vnd.openxmlformats-officedocument.wordprocessingml.document": [".docx"],
"application/msword": [".doc"],
"application/vnd.openxmlformats-officedocument.wordprocessingml.document": [".docx"],
"application/msword": [".doc"],
"application/pdf": [".pdf"]
}}
message={!statementTypeSelected ?
"Please select a statement type above before uploading files" :
"Drag and drop files here"}
message={"Drag and drop files here"}
/>
</div>
</LoadingOverlay>

<div className="radio-buttons-group-div">
<RadioGroup
name="radio-buttons-group"
<RadioGroup
defaultValue={statementType}
name="radio-buttons-group"
row
onChange={handleStatementChange}
>
Expand Down
2 changes: 1 addition & 1 deletion src/components/childComponents/FilePreview.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export default function FilePreview() {
if (filePreviews !== undefined && filePreviews.length > 0) {
const previewsTemp = [];
// get either pdf preview / html preview
if (filePreviews.length === 1){
if (filePreviews.length > 0){
console.log("filePreviews:", filePreviews);
const fileId = filePreviews[0][0].file_id;
const previewsList = filePreviews[0][0].previews;
Expand Down
95 changes: 11 additions & 84 deletions src/components/previewers/Pdf.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,91 +4,16 @@ import {useDispatch, useSelector} from "react-redux";
import { pdfjs , Document, Page } from 'react-pdf';
import "react-pdf/dist/esm/Page/TextLayer.css";
import {SET_PAGE_NUMBER, setPageNumber} from "../../actions/pdfpreview";
import {
consort_highlight_color,
consort_label_color,
spirit_highlight_color,
spirit_label_color
} from '../styledComponents/HighlightColors';


pdfjs.GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjs.version}/pdf.worker.js`;

const highlight_color = {
"1a":"#88FF88",
"1b":"#88FF88",
"2a": "#CCAAFF",
"2b": "#CCAAFF",
"3a": "#88FFFF",
"3b": "#88FFFF",
"4a": "#88FFFF",
"4b": "#88FFFF",
"5": "#88FFFF",
"6a": "#88FFFF",
"6b": "#88FFFF",
"7a": "#88FFFF",
"7b": "#88FFFF",
"8a": "#88FFFF",
"8b": "#88FFFF",
"9" : "#88FFFF",
"10" :"#88FFFF",
"11a" :"#88FFFF",
"11b" :"#88FFFF",
"12a ":"#88FFFF",
"12b" :"#88FFFF",
"13a":"#bbff44",
"13b" :"#bbff44",
"14a" :"#bbff44",
"14b" :"#bbff44",
"15" :"#bbff44",
"16" :"#bbff44",
"17a" :"#bbff44",
"17b" :"#bbff44",
"18" :"#bbff44",
"19" :"#bbff44",
"20" :"#AACCFF",
"21" :"#AACCFF",
"22" :"#AACCFF",
"23" :"#FFAACC",
"24" :"#FFAACC",
"25" :"#FFAACC",
}

const label_color = {
"1a":"#009c00",
"1b":"#009c00",
"2a": "#4400aa",
"2b": "#4400aa",
"3a": "#009c9c",
"3b": "#009c9c",
"4a": "#009c9c",
"4b": "#009c9c",
"5": "#009c9c",
"6a": "#009c9c",
"6b": "#009c9c",
"7a": "#009c9c",
"7b": "#009c9c",
"8a": "#009c9c",
"8b": "#009c9c",
"9" : "#009c9c",
"10" :"#009c9c",
"11a" :"#009c9c",
"11b" :"#009c9c",
"12a ":"#009c9c",
"12b" :"#009c9c",
"13a":"#528100",
"13b" :"#528100",
"14a" :"#528100",
"14b" :"#528100",
"15" :"#528100",
"16" :"#528100",
"17a" :"#528100",
"17b" :"#528100",
"18" :"#528100",
"19" :"#528100",
"20" :"#0044aa",
"21" :"#0044aa",
"22" :"#0044aa",
"23" :"#0044aa",
"24" :"#0044aa",
"25" :"#0044aa",
}


export default function Pdf(props) {
const dispatch = useDispatch();

Expand All @@ -105,6 +30,8 @@ export default function Pdf(props) {
let pageNumber = useSelector((state) => state.pdfpreview.pageNumber);
const dispatchPageNumber = (number) => dispatch(setPageNumber(SET_PAGE_NUMBER, number));

const statementType = useSelector(state => state.statement.statementType);

const [pageWidth, setPageWidth] = useState(500);
const [pageHeight, setPageHeight]= useState(799);
let [canvas_width, setCanvasWidth] = useState(500);
Expand Down Expand Up @@ -197,16 +124,16 @@ export default function Pdf(props) {
function highlightText(context, label, x, y, width, height){
// rectangle highlights styling
context.globalAlpha = 0.2
context.fillStyle = highlight_color[label]; // 'rgb(255, 190, 60)';
context.fillStyle = statementType === "consort" ? consort_highlight_color[label] : spirit_highlight_color[label];
context.fillRect(x , y , width , height );
}

function highlightLabel(context, label, x, y){
context.globalAlpha = 1.0
context.fillStyle = highlight_color[label];
context.fillStyle = statementType === "consort" ? consort_highlight_color[label] : spirit_highlight_color[label];
context.fillRect(x, y, 25, 12);
context.font = "bold 12px Verdana";
context.fillStyle = label_color[label];
context.fillStyle = statementType === "consort" ? consort_label_color[label] : spirit_label_color[label];
context.textAlign = "start";
context.textBaseline = "top";
context.fillText(label, x, y);
Expand Down
Loading