diff --git a/src/App.js b/src/App.js index dd82da318..1a6bb55e6 100644 --- a/src/App.js +++ b/src/App.js @@ -1,71 +1,74 @@ -import React, { Component } from 'react'; -import { Route, Switch, Redirect, withRouter } from 'react-router-dom'; -import { connect } from 'react-redux'; -import { ToastContainer } from 'react-toastify'; -import { EventSourcePolyfill } from 'event-source-polyfill'; -import Keycloak from 'keycloak-js'; -import _ from 'lodash'; -import { getUser, getUserInfo } from './services/userServices'; -import NavBar from './components/navbar'; -import Sidebar from './components/sideBar/sidebar'; -import SearchView from './components/searchView/searchView'; -import DisplayView from './components/display/displayView'; -import AnnotationSearch from './components/annotationSearch'; -import AnotateView from './components/anotateView'; -import ProgressView from './components/progressView'; -import FlexView from './components/flexView'; -import NotFound from './components/notFound'; -import LoginForm from './components/loginForm'; -import Logout from './components/logout'; -import ProtectedRoute from './components/common/protectedRoute'; -import Cornerstone from './components/cornerstone/cornerstone'; -import Management from './components/management/mainMenu'; -import InfoMenu from './components/infoMenu'; -import UserMenu from './components/userProfileMenu.jsx'; -import WarningModal from './components/common/warningModal'; -import ConfirmationModal from './components/common/confirmationModal'; -import SelectModalMenu from './components/common/SelectModalMenu'; +import React, { Component } from "react"; +import { Route, Switch, Redirect, withRouter } from "react-router-dom"; +import { connect } from "react-redux"; +import { ToastContainer } from "react-toastify"; +import { EventSourcePolyfill } from "event-source-polyfill"; +import Keycloak from "keycloak-js"; +import _ from "lodash"; +import { getUser, getUserInfo } from "./services/userServices"; +import NavBar from "./components/navbar"; +import Sidebar from "./components/sideBar/sidebar"; +import SearchView from "./components/searchView/searchView"; +import DisplayView from "./components/display/displayView"; +import AnnotationSearch from "./components/annotationSearch"; +import AnotateView from "./components/anotateView"; +import ProgressView from "./components/progressView"; +import FlexView from "./components/flexView"; +import NotFound from "./components/notFound"; +import LoginForm from "./components/loginForm"; +import Logout from "./components/logout"; +import ProtectedRoute from "./components/common/protectedRoute"; +import Cornerstone from "./components/cornerstone/cornerstone"; +import Management from "./components/management/mainMenu"; +import InfoMenu from "./components/infoMenu"; +import UserMenu from "./components/userProfileMenu.jsx"; +import WarningModal from "./components/common/warningModal"; +import ConfirmationModal from "./components/common/confirmationModal"; +import SelectModalMenu from "./components/common/SelectModalMenu"; // import AnnotationsDock from "./components/annotationsList/annotationDock/annotationsDock"; -import auth from './services/authService'; -import MaxViewAlert from './components/annotationsList/maxViewPortAlert'; +import auth from "./services/authService"; +import MaxViewAlert from "./components/annotationsList/maxViewPortAlert"; import { clearAimId, getNotificationsData, clearSelection, selectProject, getTemplates, - segUploadCompleted -} from './components/annotationsList/action'; -import Worklist from './components/sideBar/sideBarWorklist'; -import ErrorBoundary from './ErrorBoundary'; -import Report from './components/searchView/Report.jsx'; -import { getSubjects, getSubject } from './services/subjectServices'; -import 'bootstrap/dist/css/bootstrap.min.css'; -import 'react-toastify/dist/ReactToastify.css'; -import './App.css'; -import RightsideBar from './components/RightsideBar/RightsideBar'; -import MinimizedReport from './components/searchView/MinimizedReport'; + segUploadCompleted, + getSingleSerie, + addToGrid2, +} from "./components/annotationsList/action"; +import Worklist from "./components/sideBar/sideBarWorklist"; +import ErrorBoundary from "./ErrorBoundary"; +import Report from "./components/searchView/Report.jsx"; +import { getSubjects, getSubject } from "./services/subjectServices"; +import { decrypt, decryptAndAdd } from "./services/decryptUrlService"; +import "bootstrap/dist/css/bootstrap.min.css"; +import "react-toastify/dist/ReactToastify.css"; +import "./App.css"; +import RightsideBar from "./components/RightsideBar/RightsideBar"; +import MinimizedReport from "./components/searchView/MinimizedReport"; const messages = { noPatient: { - title: 'No Patient Selected', - message: 'Select a patient to get a report!' + title: "No Patient Selected", + message: "Select a patient to get a report!", }, multiplePatient: { - title: 'Multiple Patients Selected', - message: 'Select only one patient to get the report!' + title: "Multiple Patients Selected", + message: "Select only one patient to get the report!", }, projectWaterfall: { - title: 'Project Selected', - message: 'Waterfall report will be created for project ' - } + title: "Project Selected", + message: "Waterfall report will be created for project ", + }, }; const reportsList = [ - { name: 'ADLA' }, - { name: 'Longitudinal' }, - { name: 'RECIST' }, - { name: 'Waterfall' } + { name: "ADLA" }, + { name: "Longitudinal" }, + { name: "RECIST" }, + { name: "Waterfall" }, ]; class App extends Component { constructor(props) { @@ -77,7 +80,7 @@ class App extends Component { authenticated: false, openInfo: false, openUser: false, - viewType: 'search', + viewType: "search", lastEventId: null, showLog: false, admin: false, @@ -93,56 +96,56 @@ class App extends Component { showWarning: false, showConfirmation: false, showReportsMenu: false, - title: '', - message: '', - reportType: '', + title: "", + message: "", + reportType: "", reportsCompArr: [], minReportsArr: [], hiddenReports: {}, metric: null, - searchQuery: '' + searchQuery: "", }; } getProjectAdded = () => { - this.setState(state => ({ + this.setState((state) => ({ projectAdded: state.projectAdded + 1, refTree: {}, // treeData: {}, expandLevel: 0, - treeExpand: {} + treeExpand: {}, })); - localStorage.setItem('treeData', JSON.stringify({})); + localStorage.setItem("treeData", JSON.stringify({})); }; closeWarning = () => { this.setState({ showConfirmation: false, showWarning: false, - title: '', - message: '' + title: "", + message: "", }); }; handleReportsClick = () => { - this.setState(state => ({ showReportsMenu: !state.showReportsMenu })); + this.setState((state) => ({ showReportsMenu: !state.showReportsMenu })); }; - countCurrentReports = arr => { + countCurrentReports = (arr) => { let nullCount = 0; - arr.forEach(el => { + arr.forEach((el) => { if (el === null) nullCount++; }); return nullCount; }; - closeReportModal = index => { + closeReportModal = (index) => { const arr = [...this.state.reportsCompArr]; arr[index] = null; this.setState({ template: null, report: null, - reportsCompArr: arr + reportsCompArr: arr, }); // if there isn't any report open clear selection @@ -162,13 +165,13 @@ class App extends Component { this.setState({ hiddenReports, - minReportsArr + minReportsArr, }); this.closeReportModal(reportIndex); }; - handleMaximizeReport = e => { + handleMaximizeReport = (e) => { let { index, reportindex } = e.target.dataset; index = parseInt(index); reportindex = parseInt(reportindex); @@ -182,7 +185,7 @@ class App extends Component { this.setState({ hiddenReports, minReportsArr, - reportsCompArr + reportsCompArr, }); }; @@ -199,7 +202,7 @@ class App extends Component { header={title} onClose={this.handleCloseMinimize} onExpand={this.handleMaximizeReport} - key={minIndex + 'min'} + key={minIndex + "min"} count={Object.values(hiddenReports).length} /> ); @@ -208,32 +211,32 @@ class App extends Component { this.setState({ minReportsArr, reportsCompArr, hiddenReports }); }; - handleReportSelect = e => { + handleReportSelect = (e) => { const { projectMap, selectedPatients } = this.props; const patients = Object.values(selectedPatients); const reportType = e.target.dataset.opt; this.handleReportsClick(); if (patients.length === 0) { - if (reportType === 'Waterfall') { + if (reportType === "Waterfall") { this.setState({ showConfirmation: true, title: messages.projectWaterfall.title, message: messages.projectWaterfall.message + - projectMap[this.state.pid].projectName + projectMap[this.state.pid].projectName, }); } else { this.setState({ showWarning: true, title: messages.noPatient.title, - message: messages.noPatient.message + message: messages.noPatient.message, }); } - } else if (patients.length > 1 && reportType !== 'Waterfall') { + } else if (patients.length > 1 && reportType !== "Waterfall") { this.setState({ showWarning: true, title: messages.multiplePatient.title, - message: messages.multiplePatient.message + message: messages.multiplePatient.message, }); } else { const reportsCompArr = [...this.state.reportsCompArr]; @@ -253,15 +256,15 @@ class App extends Component { this.setState({ template: null, reportType, - reportsCompArr + reportsCompArr, }); } }; - getMetric = metric => { + getMetric = (metric) => { this.setState({ metric }); }; - handleWaterFallClickOnBar = async name => { + handleWaterFallClickOnBar = async (name) => { // find the patient selected // if project selected get patient details with call const { selectedProject, selectedPatients } = this.props; @@ -287,7 +290,7 @@ class App extends Component { /> ); this.setState({ - reportsCompArr + reportsCompArr, }); }; @@ -298,7 +301,7 @@ class App extends Component { reportsCompArr.push( { try { const treeExpand = { ...this.state.treeExpand }; - if (level === 'patientID') { + if (level === "patientID") { treeExpand[ids.index] = false; } this.setState({ treeExpand }); @@ -402,7 +405,7 @@ class App extends Component { }); }; - getTreeExpandSingle = async expandObj => { + getTreeExpandSingle = async (expandObj) => { try { const { patient, study, series } = expandObj; let treeExpand = { ...this.state.treeExpand }; @@ -440,18 +443,18 @@ class App extends Component { } }; - getExpandLevel = expandLevel => { + getExpandLevel = (expandLevel) => { this.setState({ expandLevel }); }; handleShrink = async () => { const { expandLevel } = this.state; if (expandLevel > 0) { - await this.setState(state => ({ expandLevel: state.expandLevel - 1 })); + await this.setState((state) => ({ expandLevel: state.expandLevel - 1 })); } }; - closeMenu = notification => { + closeMenu = (notification) => { // if (event && event.type === "keydown") { // if (event.key === "Escape" || event.keyCode === 27) { // this.setState({ openMng: false }); @@ -461,96 +464,98 @@ class App extends Component { openMng: false, openInfo: false, openUser: false, - openMenu: false + openMenu: false, }); if (notification) this.updateNotificationSeen(); }; - switchView = viewType => { + switchView = (viewType) => { const { pid } = this.state; this.setState({ viewType }); - if (viewType === 'search') { + if (viewType === "search") { this.props.dispatch(clearSelection()); pid ? this.props.history.push(`/list/${pid}`) : this.props.history.push(`/list`); - } else if (viewType === 'display') { + } else if (viewType === "display") { this.props.history.push(`/display`); - } else if (viewType === 'annotations') { + } else if (viewType === "annotations") { this.props.history.push(`/search`); } }; handleMngMenu = () => { - this.setState(state => ({ + this.setState((state) => ({ openInfo: false, openMng: !state.openMng, - openUser: false + openUser: false, })); }; handleInfoMenu = () => { - this.setState(state => ({ + this.setState((state) => ({ openInfo: !state.openInfo, openMng: false, - openUser: false + openUser: false, })); }; handleUserProfileMenu = () => { - this.setState(state => ({ + this.setState((state) => ({ openInfo: false, openMng: false, - openUser: !state.openUser + openUser: !state.openUser, })); }; updateProgress = () => { - this.setState(state => ({ progressUpdated: state.progressUpdated + 1 })); + this.setState((state) => ({ progressUpdated: state.progressUpdated + 1 })); }; async componentDidMount() { - localStorage.setItem('treeData', JSON.stringify({})); + localStorage.setItem("treeData", JSON.stringify({})); Promise.all([ fetch(`${process.env.PUBLIC_URL}/config.json`), - fetch(`${process.env.PUBLIC_URL}/keycloak.json`) + fetch(`${process.env.PUBLIC_URL}/keycloak.json`), ]) - .then(async results => { + .then(async (results) => { const configData = await results[0].json(); - let { mode, apiUrl, wadoUrl, authMode } = configData; + let { mode, apiUrl, wadoUrl, authMode, MAX_PORT } = configData; // check and use environment variables if any mode = process.env.REACT_APP_MODE || mode; apiUrl = process.env.REACT_APP_API_URL || apiUrl; wadoUrl = process.env.REACT_APP_WADO_URL || wadoUrl; authMode = process.env.REACT_APP_AUTH_MODE || authMode; - sessionStorage.setItem('mode', mode); - sessionStorage.setItem('apiUrl', apiUrl); - sessionStorage.setItem('wadoUrl', wadoUrl); - sessionStorage.setItem('authMode', authMode); + MAX_PORT = process.env.REACT_APP_MAX_PORT || MAX_PORT; + sessionStorage.setItem("mode", mode); + sessionStorage.setItem("apiUrl", apiUrl); + sessionStorage.setItem("wadoUrl", wadoUrl); + sessionStorage.setItem("authMode", authMode); + sessionStorage.setItem("MAX_PORT", MAX_PORT); this.setState({ mode, apiUrl, wadoUrl, authMode }); const keycloakData = await results[1].json(); const auth = - process.env.REACT_APP_AUTH_URL || keycloakData['auth-server-url']; + process.env.REACT_APP_AUTH_URL || keycloakData["auth-server-url"]; const keycloakJson = {}; // check and use environment variables if any keycloakJson.realm = process.env.REACT_APP_AUTH_REALM || keycloakData.realm; keycloakJson.url = - process.env.REACT_APP_AUTH_URL || keycloakData['auth-server-url']; + process.env.REACT_APP_AUTH_URL || keycloakData["auth-server-url"]; keycloakJson.clientId = process.env.REACT_APP_AUTH_RESOURCE || keycloakData.resource; - sessionStorage.setItem('auth', auth); - sessionStorage.setItem('keycloakJson', JSON.stringify(keycloakJson)); - this.completeAutorization(apiUrl); - if (mode === 'lite') this.setState({ pid: 'lite' }); + sessionStorage.setItem("auth", auth); + sessionStorage.setItem("keycloakJson", JSON.stringify(keycloakJson)); + if (mode === "lite") this.setState({ pid: "lite" }); + this.checkArguments(); }) - .catch(err => { + .catch((err) => { console.error(err); }); //get notifications from sessionStorage and setState - let notifications = sessionStorage.getItem('notifications'); + let notifications = sessionStorage.getItem("notifications"); if (!notifications) { - sessionStorage.setItem('notifications', JSON.stringify([])); + sessionStorage.setItem("notifications", JSON.stringify([])); this.setState({ notifications: [] }); } else { notifications = JSON.parse(notifications); @@ -558,128 +563,181 @@ class App extends Component { } } - componentDidUpdate = prevProps => { - const uploaded = this.props.notificationAction.startsWith('Upload'); - const deleted = this.props.notificationAction.startsWith('Delete'); + componentDidUpdate = (prevProps) => { + const uploaded = this.props.notificationAction.startsWith("Upload"); + const deleted = this.props.notificationAction.startsWith("Delete"); if ( prevProps.lastEventId !== this.props.lastEventId && (uploaded || deleted) ) { this.props.dispatch(getTemplates()); - localStorage.setItem('treeData', JSON.stringify({})); + localStorage.setItem("treeData", JSON.stringify({})); this.clearTreeExpand(); } - const oldPid = prevProps.location.pathname.split('/').pop(); - const newPid = this.props.location.pathname.split('/').pop(); - const route = this.props.location.pathname.split('/')[1]; + const oldPid = prevProps.location.pathname.split("/").pop(); + const newPid = this.props.location.pathname.split("/").pop(); + const route = this.props.location.pathname.split("/")[1]; - if (oldPid !== newPid && route === 'list') { + if (oldPid !== newPid && route === "list") { this.setState({ pid: newPid }); } }; - completeAutorization = apiUrl => { + componentWillUnmount = () => { + this.eventSource.removeEventListener( + "message", + this.getMessageFromEventSrc + ); + localStorage.setItem("treeData", JSON.stringify({})); + }; + + checkArguments = async () => { + const { search } = this.props.location; + let args; + if (search && (args = search.split("?arg=")[1])) { + const { data } = await decrypt(args); + const { API_KEY, seriesArray, user } = data; + console.log("seriesArray", seriesArray); + const parsedSeriesArray = JSON.parse(seriesArray); + console.log("parsed array", parsedSeriesArray); + if (API_KEY) { + sessionStorage.setItem("authMode", "apiKey"); + sessionStorage.setItem("API_KEY", API_KEY); + sessionStorage.setItem("user", user); + sessionStorage.setItem("username", user); + } + this.completeAutorization(); + const promiseArr = []; + for (let serie of parsedSeriesArray) { + serie = { ...serie, projectID: "lite" }; + this.props.dispatch(addToGrid2(serie)); + promiseArr.push(this.props.dispatch(getSingleSerie(serie))); + } + Promise.all(promiseArr) + .then(() => { + this.props.history.push("/display"); + }) + .catch((err) => console.error(err)); + } else this.completeAutorization(); + }; + + completeAutorization = () => { let getAuthUser = null; + const authMode = sessionStorage.getItem("authMode"); + const apiUrl = sessionStorage.getItem("apiUrl"); - if (sessionStorage.getItem('authMode') !== 'external') { + if (authMode === "apiKey") { + const username = sessionStorage.getItem("username"); + getAuthUser = new Promise((resolve) => { + resolve({ + userInfo: { preferred_username: username }, + keycloak: {}, + authenticated: true, + }); + }).catch((err) => reject(err)); + } else if (authMode !== "external") { const keycloak = Keycloak( - JSON.parse(sessionStorage.getItem('keycloakJson')) + JSON.parse(sessionStorage.getItem("keycloakJson")) ); getAuthUser = new Promise((resolve, reject) => { keycloak - .init({ onLoad: 'login-required' }) - .then(authenticated => { + .init({ onLoad: "login-required" }) + .then((authenticated) => { keycloak .loadUserInfo() - .then(userInfo => { + .then((userInfo) => { resolve({ userInfo, keycloak, authenticated }); }) - .catch(err => reject(err)); + .catch((err) => reject(err)); }) - .catch(err => reject(err)); + .catch((err) => reject(err)); }); } else { // authMode is external ask backend for user getAuthUser = new Promise((resolve, reject) => { getUserInfo() - .then(userInfoResponse => { + .then((userInfoResponse) => { resolve({ userInfo: userInfoResponse.data, keycloak: {}, - authenticated: true + authenticated: true, }); }) - .catch(err => reject(err)); + .catch((err) => reject(err)); }); } getAuthUser - .then(async result => { + .then(async (result) => { try { + const username = + result.userInfo.preferred_username || result.userInfo.email; + let userData; + try { + userData = await getUser(username); + userData = userData.data; + this.setState({ admin: userData.admin }); + } catch (err) { + console.error(err); + } let user = { - user: result.userInfo.preferred_username || result.userInfo.email, - displayname: result.userInfo.given_name || result.userInfo.givenName + user: userData.username, + displayname: `${userData.firstname} ${userData.lastname}`, }; await auth.login(user, null, result.keycloak); this.setState({ keycloak: result.keycloak, authenticated: result.authenticated, id: result.userInfo.sub, - user + user, }); - const { - email, - family_name, - given_name, - preferred_username - } = result.userInfo; - const username = preferred_username || email; - let userData; - try { - userData = await getUser(username); - userData = userData.data; - this.setState({ admin: userData.admin }); - } catch (err) { - console.error(err); - } - this.eventSource = new EventSourcePolyfill( - `${apiUrl}/notifications`, - result.keycloak.token - ? { - headers: { - authorization: `Bearer ${result.keycloak.token}` + if (authMode === "apiKey") { + const API_KEY = sessionStorage.getItem("API_KEY"); + const user = sessionStorage.getItem("user"); + this.eventSource = new EventSourcePolyfill( + `${apiUrl}/notifications?user=${user}`, + { + headers: { + authorization: `apikey ${API_KEY}`, + }, + } + ); + } else { + this.eventSource = new EventSourcePolyfill( + `${apiUrl}/notifications`, + result.keycloak.token + ? { + headers: { + authorization: `Bearer ${result.keycloak.token}`, + }, } - } - : {} - ); + : {} + ); + } + this.eventSource.addEventListener( - 'message', + "message", this.getMessageFromEventSrc ); } catch (err) { - console.log('Error in user retrieval!', err); + console.error("Error in user retrieval!", err); } }) - .catch(err2 => { - console.log('Authentication failed!', err2); + .catch((err2) => { + console.error("Authentication failed!", err2); }); }; - getMessageFromEventSrc = res => { + getMessageFromEventSrc = (res) => { try { - if (res.data === 'heartbeat') { + if (res.data === "heartbeat") { return; } const parsedRes = JSON.parse(res.data); const { lastEventId } = res; - const { - params, - createdtime, - projectID, - error, - refresh - } = parsedRes.notification; + const { params, createdtime, projectID, error, refresh } = + parsedRes.notification; const action = parsedRes.notification.function; const message = params; // check if the notification is for successfull upload segmentation @@ -689,7 +747,7 @@ class App extends Component { getNotificationsData(projectID, lastEventId, refresh, action) ); let time = new Date(createdtime).toString(); - const GMTIndex = time.indexOf(' G'); + const GMTIndex = time.indexOf(" G"); time = time.substring(0, GMTIndex - 3); let notifications = [...this.state.notifications]; notifications.unshift({ @@ -697,14 +755,14 @@ class App extends Component { time, seen: false, action, - error + error, }); - const tagEdited = action.startsWith('Tag'); - const uploaded = action.startsWith('Upload'); + const tagEdited = action.startsWith("Tag"); + const uploaded = action.startsWith("Upload"); if (tagEdited || uploaded) { const { pid } = this.state; // this.setState({ treeData: {} }); - localStorage.setItem('treeData', JSON.stringify({})); + localStorage.setItem("treeData", JSON.stringify({})); this.setState({ pid }); if (this.props.openSeries.length === 0) { this.props.history.push(`/list/${pid}`); @@ -712,48 +770,40 @@ class App extends Component { } this.setState({ notifications }); const stringified = JSON.stringify(notifications); - sessionStorage.setItem('notifications', stringified); + sessionStorage.setItem("notifications", stringified); } catch (err) { console.error(err); } }; - componentWillUnmount = () => { - this.eventSource.removeEventListener( - 'message', - this.getMessageFromEventSrc - ); - localStorage.setItem('treeData', JSON.stringify({})); - }; - - onLogout = e => { + onLogout = (e) => { auth.logout(); // sessionStorage.removeItem("annotations"); - sessionStorage.setItem('notifications', JSON.stringify([])); + sessionStorage.setItem("notifications", JSON.stringify([])); this.setState({ authenticated: false, id: null, name: null, - user: null + user: null, }); - if (sessionStorage.getItem('authMode') !== 'external') + if (sessionStorage.getItem("authMode") !== "external") this.state.keycloak.logout().then(() => { this.setState({ - keycloak: null + keycloak: null, }); auth.logout(); }); - else console.log('No logout in external authentication mode'); + else console.error("No logout in external authentication mode"); }; updateNotificationSeen = () => { const notifications = [...this.state.notifications]; - notifications.forEach(notification => { + notifications.forEach((notification) => { notification.seen = true; }); this.setState({ notifications }); const stringified = JSON.stringify(notifications); - sessionStorage.setItem('notifications', stringified); + sessionStorage.setItem("notifications", stringified); }; switchSearhView = () => { @@ -763,20 +813,20 @@ class App extends Component { handleCloseAll = () => { // let { closeAll } = this.state; // closeAll += 1; - this.setState(state => ({ + this.setState((state) => ({ expandLevel: 0, - closeAll: state.closeAll + 1 + closeAll: state.closeAll + 1, })); }; getTreeData = (projectID, level, data) => { try { - let treeData = JSON.parse(localStorage.getItem('treeData')); + let treeData = JSON.parse(localStorage.getItem("treeData")); // const treeData = { ...this.state.treeData }; const patientIDs = []; - if (level === 'subject') { + if (level === "subject") { if (!treeData[projectID]) treeData[projectID] = {}; - data.forEach(el => { + data.forEach((el) => { if (!treeData[projectID][el.subjectID]) { treeData[projectID][el.subjectID] = { data: el, studies: {} }; } @@ -791,14 +841,14 @@ class App extends Component { } } } - } else if (level === 'studies') { + } else if (level === "studies") { const studyUIDs = []; const patientID = data[0].patientID; - data.forEach(el => { + data.forEach((el) => { if (!treeData[projectID][el.patientID].studies[el.studyUID]) { treeData[projectID][el.patientID].studies[el.studyUID] = { data: el, - series: {} + series: {}, }; } studyUIDs.push(el.studyUID); @@ -812,11 +862,11 @@ class App extends Component { } } } - } else if (level === 'series') { + } else if (level === "series") { const patientID = data[0].patientID; const studyUID = data[0].studyUID; const seriesUIDs = []; - data.forEach(el => { + data.forEach((el) => { if ( !treeData[projectID][el.patientID].studies[el.studyUID].series[ el.seriesUID @@ -825,7 +875,7 @@ class App extends Component { treeData[projectID][el.patientID].studies[el.studyUID].series[ el.seriesUID ] = { - data: el + data: el, }; } seriesUIDs.push(el.seriesUID); @@ -842,14 +892,14 @@ class App extends Component { } } // this.setState({ treeData }); - localStorage.setItem('treeData', JSON.stringify(treeData)); + localStorage.setItem("treeData", JSON.stringify(treeData)); } catch (err) { console.error(err); } }; - getPidUpdate = pid => { - this.setState({ searchQuery: '' }); + getPidUpdate = (pid) => { + this.setState({ searchQuery: "" }); this.setState({ pid }); }; @@ -858,7 +908,7 @@ class App extends Component { }; sortLevelArr = (arr, attribute) => { - return arr.sort(function(a, b) { + return arr.sort(function (a, b) { if (a.data[attribute] < b.data[attribute]) { return -1; } @@ -886,13 +936,13 @@ class App extends Component { clearAllTreeData = () => { // this.setState({ treeData: {} }); - localStorage.setItem('treeData', JSON.stringify({})); + localStorage.setItem("treeData", JSON.stringify({})); }; clearTreeData = () => { try { const { pid, treeExpand } = this.state; - let treeData = JSON.parse(localStorage.getItem('treeData'))[pid]; + let treeData = JSON.parse(localStorage.getItem("treeData"))[pid]; const patients = treeData[pid]; const patientsArr = Object.values(patients); for (let patientIndex in treeExpand) { @@ -901,8 +951,8 @@ class App extends Component { const patientID = this.getPatientIDfromSortedArray( patientIndex, patientsArr, - 'subjectName', - 'subjectID' + "subjectName", + "subjectID" ); if (!treeExpand[patientIndex]) { // find subject id and empty studies @@ -919,18 +969,18 @@ class App extends Component { } treeData[pid] = patients; // this.setState({ treeData }); - localStorage.setItem('treeData', JSON.stringify(treeData)); + localStorage.setItem("treeData", JSON.stringify(treeData)); } catch (err) { console.error(err); } }; findNonExisting = (arr, uid, level) => { - const result = arr.filter(el => el[level] === uid); + const result = arr.filter((el) => el[level] === uid); return result[0]; }; - checkIfSegUpload = params => { + checkIfSegUpload = (params) => { const { isSegUploaded } = this.props; const segsUploaded = Object.keys(isSegUploaded); for (let i = 0; i < segsUploaded.length; i++) { @@ -943,7 +993,7 @@ class App extends Component { updateTreeDataOnSave = async (refs, newLevel) => { try { // this.setState({ treeData: {} }); - localStorage.setItem('treeData', JSON.stringify({})); + localStorage.setItem("treeData", JSON.stringify({})); this.clearTreeExpand(); } catch (err) { console.error(err); @@ -960,7 +1010,7 @@ class App extends Component { showWarning, showConfirmation, title, - message + message, } = this.state; let noOfUnseen; if (notifications) { @@ -1029,7 +1079,7 @@ class App extends Component { {showConfirmation && ( )} - {this.state.authenticated && mode !== 'lite' && ( -
+ {this.state.authenticated && mode !== "lite" && ( +
( + render={(props) => ( ( + render={(props) => ( ( + render={(props) => ( } + render={(props) => ( + + )} /> ( + render={(props) => ( this.setState({ searchQuery: query })} + setQuery={(query) => + this.setState({ searchQuery: query }) + } /> )} /> @@ -1150,7 +1204,7 @@ class App extends Component { from="/" exact to="/list" - render={props => ( + render={(props) => (
)} - {this.state.authenticated && mode === 'lite' && ( + {this.state.authenticated && mode === "lite" && ( ( + render={(props) => ( ( + render={(props) => ( this.setState({ searchQuery: query })} + setQuery={(query) => this.setState({ searchQuery: query })} /> )} /> ( + render={(props) => ( { +const mapStateToProps = (state) => { // console.log(state.managementReducer); // console.log(state.annotationsListReducer); const { @@ -1275,7 +1329,7 @@ const mapStateToProps = state => { projectMap, lastEventId, notificationAction, - isSegUploaded + isSegUploaded, } = state.annotationsListReducer; return { showGridFullAlert, @@ -1290,7 +1344,7 @@ const mapStateToProps = state => { lastEventId, notificationAction, isSegUploaded, - selection: state.managementReducer.selection + selection: state.managementReducer.selection, }; }; export default withRouter(connect(mapStateToProps)(App)); diff --git a/src/components/annotationSearch/AnnotationTable.jsx b/src/components/annotationSearch/AnnotationTable.jsx index 83fb4d1a9..189500d3f 100644 --- a/src/components/annotationSearch/AnnotationTable.jsx +++ b/src/components/annotationSearch/AnnotationTable.jsx @@ -4,7 +4,6 @@ import { useTable, usePagination, useRowSelect } from 'react-table'; import { Link } from 'react-router-dom'; import { FaRegEye } from 'react-icons/fa'; import { clearCarets, convertDateFormat } from '../../Utils/aid.js'; -import { MAX_PORT } from '../../constants'; import { changeActivePort, jumpToAim, @@ -20,6 +19,7 @@ import { import { getSeries } from '../../services/seriesServices'; const defaultPageSize = 200; +const MAX_PORT = sessionStorage.getItem("MAX_PORT"); function Table({ columns, @@ -312,7 +312,7 @@ function AnnotationTable(props) { } //getsingleSerie Promise.all(promiseArr) - .then(() => {}) + .then(() => { }) .catch(err => console.error(err)); //if patient doesnot exist get patient diff --git a/src/components/annotationsList/action.js b/src/components/annotationsList/action.js index e5dff7276..b8449958c 100644 --- a/src/components/annotationsList/action.js +++ b/src/components/annotationsList/action.js @@ -24,6 +24,7 @@ import { SELECT_PROJECT, CLEAR_SELECTION, ADD_TO_GRID, + ADD_TO_GRID2, LOAD_COMPLETED, START_LOADING, UPDATE_PATIENT, @@ -43,20 +44,20 @@ import { SEG_UPLOAD_REMOVE, AIM_DELETE, colors, - commonLabels -} from './types'; + commonLabels, +} from "./types"; -import { getSeries } from '../../services/seriesServices'; -import { getStudies, getStudyAims } from '../../services/studyServices'; +import { getSeries } from "../../services/seriesServices"; +import { getStudies, getStudyAims } from "../../services/studyServices"; import { getAnnotations, getAnnotationsJSON, - getSubjectsAnnotations -} from '../../services/annotationServices'; -import { getAllTemplates } from '../../services/templateServices'; -import { getImageIdAnnotations } from 'aimapi'; + getSubjectsAnnotations, +} from "../../services/annotationServices"; +import { getAllTemplates } from "../../services/templateServices"; +import { getImageIdAnnotations } from "aimapi"; -export const getProjectMap = projectMap => { +export const getProjectMap = (projectMap) => { return { type: GET_PROJECT_MAP, projectMap }; }; @@ -71,12 +72,12 @@ export const getTemplates = () => { } dispatch({ type: GET_TEMPLATES, templates }); } catch (err) { - console.error('getting template JSONs', err); + console.error("getting template JSONs", err); } }; }; -export const clearGrid = item => { +export const clearGrid = (item) => { return { type: CLEAR_GRID }; }; @@ -86,23 +87,23 @@ export const clearActivePortAimID = () => { export const clearAimId = () => { return { - type: CLEAR_AIMID + type: CLEAR_AIMID, }; }; -export const updateImageIndex = imageIndex => { +export const updateImageIndex = (imageIndex) => { return { type: UPDATE_IMAGE_INDEX, imageIndex }; }; -export const updateImageId = imageID => { +export const updateImageId = (imageID) => { return { type: UPDATE_IMAGEID, - imageID + imageID, }; }; export const closeSerie = () => { return { - type: CLOSE_SERIE + type: CLOSE_SERIE, }; }; @@ -114,7 +115,7 @@ export const getNotificationsData = ( ) => { return { type: GET_NOTIFICATIONS, - payload: { uploadedPid, lastEventId, refresh, notificationAction } + payload: { uploadedPid, lastEventId, refresh, notificationAction }, }; }; @@ -128,19 +129,19 @@ export const updatePatient = ( ) => { return { type: UPDATE_PATIENT, - payload: { type, status, patient, study, serie, annotation } + payload: { type, status, patient, study, serie, annotation }, }; }; -export const updatePatientOnAimSave = aimRefs => { +export const updatePatientOnAimSave = (aimRefs) => { return { type: UPDATE_PATIENT_AIM_SAVE, aimRefs }; }; -export const updatePatientOnAimDelete = aimRefs => { +export const updatePatientOnAimDelete = (aimRefs) => { return { type: UPDATE_PATIENT_AIM_DELETE, aimRefs }; }; -export const clearSelection = selectionType => { +export const clearSelection = (selectionType) => { return { type: CLEAR_SELECTION, selectionType }; }; @@ -153,17 +154,17 @@ export const startLoading = () => { export const loadPatient = () => { return { type: LOAD_PATIENT }; }; -export const loadPatientError = err => { +export const loadPatientError = (err) => { return { type: LOAD_PATIENT_ERROR, err }; }; -export const loadPatientSuccess = patient => { +export const loadPatientSuccess = (patient) => { return { type: LOAD_PATIENT_SUCCESS, patient }; }; export const jumpToAim = (seriesUID, aimID, index) => { return { type: JUMP_TO_AIM, - payload: { seriesUID, aimID, index } + payload: { seriesUID, aimID, index }, }; }; export const displaySingleAim = ( @@ -176,33 +177,29 @@ export const displaySingleAim = ( return { type: DISPLAY_SINGLE_AIM, - payload: { patientID, studyUID, seriesUID, aimID } + payload: { patientID, studyUID, seriesUID, aimID }, }; }; -export const selectPatient = selectedPatientObj => { - let { - projectID, - subjectName, - numberOfAnnotations, - index - } = selectedPatientObj; - projectID = projectID ? projectID : 'lite'; +export const selectPatient = (selectedPatientObj) => { + let { projectID, subjectName, numberOfAnnotations, index } = + selectedPatientObj; + projectID = projectID ? projectID : "lite"; const patientID = selectedPatientObj.subjectID; return { type: SELECT_PATIENT, - patient: { projectID, patientID, numberOfAnnotations, subjectName, index } + patient: { projectID, patientID, numberOfAnnotations, subjectName, index }, }; }; -export const selectProject = projectID => { +export const selectProject = (projectID) => { return { type: SELECT_PROJECT, - projectID + projectID, }; }; -export const selectStudy = selectedStudyObj => { +export const selectStudy = (selectedStudyObj) => { let { studyUID, patientID, @@ -210,9 +207,9 @@ export const selectStudy = selectedStudyObj => { studyDescription, patientName, numberOfSeries, - numberOfAnnotations + numberOfAnnotations, } = selectedStudyObj; - projectID = projectID ? projectID : 'lite'; + projectID = projectID ? projectID : "lite"; return { type: SELECT_STUDY, @@ -223,8 +220,8 @@ export const selectStudy = selectedStudyObj => { studyDescription, patientName, numberOfSeries, - numberOfAnnotations - } + numberOfAnnotations, + }, }; }; @@ -236,7 +233,7 @@ export const selectSerie = (selectedSerieObj, studyDescription) => { projectID, patientName, seriesDescription, - numberOfAnnotations + numberOfAnnotations, } = selectedSerieObj; return { @@ -250,8 +247,8 @@ export const selectSerie = (selectedSerieObj, studyDescription) => { patientName, seriesDescription, studyDescription, - numberOfAnnotations - } + numberOfAnnotations, + }, }; }; @@ -273,7 +270,7 @@ export const selectAnnotation = ( patientName, - name + name, } = selectedAnnotationObj; return { @@ -293,14 +290,14 @@ export const selectAnnotation = ( patientName, name, studyDescription, - seriesDescription - } + seriesDescription, + }, }; }; export const addToGrid = (serie, annotation) => { let { patientID, studyUID, seriesUID, projectID, patientName } = serie; - projectID = projectID ? projectID : 'lite'; + projectID = projectID ? projectID : "lite"; if (annotation) patientID = serie.originalSubjectID || serie.subjectID || serie.patientID; let reference = { @@ -309,19 +306,36 @@ export const addToGrid = (serie, annotation) => { studyUID, seriesUID, patientName, - aimID: annotation + aimID: annotation, // imageIndex: 0 }; return { type: ADD_TO_GRID, reference }; }; +export const addToGrid2 = (serie, annotation) => { + let { patientID, studyUID, seriesUID, projectID, patientName } = serie; + projectID = projectID ? projectID : "lite"; + if (annotation) + patientID = serie.originalSubjectID || serie.subjectID || serie.patientID; + let reference = { + projectID, + patientID, + studyUID, + seriesUID, + patientName, + aimID: annotation, + // imageIndex: 0 + }; + return { type: ADD_TO_GRID2, reference }; +}; + export const showAnnotationWindow = () => { return { type: SHOW_ANNOTATION_WINDOW }; }; const loadAnnotations = () => { return { - type: LOAD_ANNOTATIONS + type: LOAD_ANNOTATIONS, }; }; @@ -333,24 +347,24 @@ const loadAnnotations = () => { // }; export const openProjectSelectionModal = () => { return { - type: OPEN_PROJECT_MODAL + type: OPEN_PROJECT_MODAL, }; }; const annotationsLoaded = () => { return { - type: LOAD_ANNOTATIONS_SUCCESS + type: LOAD_ANNOTATIONS_SUCCESS, }; }; -export const annotationsLoadingError = error => { +export const annotationsLoadingError = (error) => { return { - type: LOAD_ANNOTATIONS_ERROR + type: LOAD_ANNOTATIONS_ERROR, }; }; export const alertViewPortFull = () => { return { - type: VIEWPORT_FULL + type: VIEWPORT_FULL, }; }; @@ -363,42 +377,42 @@ export const updateAnnotationDisplay = ( ) => { return { type: UPDATE_ANNOTATION_DISPLAY, - payload: { patient, study, serie, annotation, isDisplayed } + payload: { patient, study, serie, annotation, isDisplayed }, }; }; export const toggleAllAnnotations = (seriesUID, displayStatus) => { return { type: TOGGLE_ALL_ANNOTATIONS, - payload: { seriesUID, displayStatus } + payload: { seriesUID, displayStatus }, }; }; export const toggleAllLabels = (serieID, checked) => { return { type: TOGGLE_ALL_LABELS, - payload: { serieID, checked } + payload: { serieID, checked }, }; }; export const toggleSingleLabel = (serieID, aimID) => { return { type: TOGGLE_LABEL, - payload: { serieID, aimID } + payload: { serieID, aimID }, }; }; -export const changeActivePort = portIndex => { +export const changeActivePort = (portIndex) => { return { type: CHANGE_ACTIVE_PORT, - portIndex + portIndex, }; }; export const singleSerieLoaded = (ref, aimsData, serID, imageData, ann) => { return { type: LOAD_SERIE_SUCCESS, - payload: { ref, aimsData, serID, imageData, ann } + payload: { ref, aimsData, serID, imageData, ann }, }; }; @@ -427,22 +441,22 @@ const getAimListFields = (aims, ann) => { if (imgAimUID) { if (markupColor) { color = { - button: { background: '#aaaaaa', color: 'black' }, - label: { background: markupColor, color: 'white' } + button: { background: "#aaaaaa", color: "black" }, + label: { background: markupColor, color: "white" }, }; } else color = colors[index]; } else color = commonLabels; let type = imgAimUID - ? 'image' + ? "image" : serieAimUID && !imgAimUID - ? 'serie' - : 'study'; + ? "serie" + : "study"; let aimName = aim.ImageAnnotationCollection.imageAnnotations.ImageAnnotation[0]?.name .value; - let ind = aimName.indexOf('~'); + let ind = aimName.indexOf("~"); if (ind >= 0) { aimName = aimName.substring(0, ind); } @@ -459,7 +473,7 @@ const getAimListFields = (aims, ann) => { inferenceEntityCollection, segmentationEntityCollection, typeCode, - trackingUniqueIdentifier + trackingUniqueIdentifier, } = aim.ImageAnnotationCollection.imageAnnotations.ImageAnnotation[0]; const aimFields = { name, @@ -469,7 +483,7 @@ const getAimListFields = (aims, ann) => { inferenceEntityCollection, segmentationEntityCollection, typeCode, - trackingUniqueIdentifier: trackingUniqueIdentifier?.root + trackingUniqueIdentifier: trackingUniqueIdentifier?.root, }; const user = aim.ImageAnnotationCollection.user.name.value; const id = aim.ImageAnnotationCollection.uniqueIdentifier.root; @@ -485,33 +499,28 @@ const getAimListFields = (aims, ann) => { // color, type, imgAimUID, - markupColor + markupColor, }; }); return result; } catch (err) { - console.error('Error in parsing aim attributes', err); + console.error("Error in parsing aim attributes", err); } }; const getRequiredFields = (arr, type, selectedID) => { let result = {}; if (arr) { - arr.forEach(element => { + arr.forEach((element) => { let obj; - if (type === 'study') { + if (type === "study") { const { studyUID, studyDescription } = element; obj = { studyUID, studyDescription }; result[studyUID] = obj; - } else if (type === 'serie') { - let { - seriesUID, - seriesDescription, - studyUID, - patientID, - projectID - } = element; - projectID = projectID ? projectID : 'lite'; + } else if (type === "serie") { + let { seriesUID, seriesDescription, studyUID, patientID, projectID } = + element; + projectID = projectID ? projectID : "lite"; const isDisplayed = seriesUID === selectedID || selectedID === studyUID; obj = { @@ -520,7 +529,7 @@ const getRequiredFields = (arr, type, selectedID) => { studyUID, patientID, projectID, - isDisplayed + isDisplayed, }; result[seriesUID] = obj; } else { @@ -532,7 +541,7 @@ const getRequiredFields = (arr, type, selectedID) => { name, aimID, comment, - isDisplayed + isDisplayed, }; result[aimID] = obj; } @@ -546,7 +555,7 @@ const getStudiesData = async (dataObj, projectID, patientID, selectedID) => { const { data: studies } = await getStudies(projectID, patientID); //create an empty object to be "studies" property in the data //iterate over the studies array create key/value pairs - dataObj['studies'] = getRequiredFields(studies, 'study', selectedID); + dataObj["studies"] = getRequiredFields(studies, "study", selectedID); return new Promise((resolve, reject) => { resolve(dataObj); }); @@ -555,7 +564,7 @@ const getStudiesData = async (dataObj, projectID, patientID, selectedID) => { reject( new Error( `Error while getting study data ${err}`, - 'src/components/annotationList/action.js' + "src/components/annotationList/action.js" ) ); }); @@ -565,7 +574,7 @@ const getStudiesData = async (dataObj, projectID, patientID, selectedID) => { const getSeriesData = async (projectID, patientID, studyID, selectedID) => { try { const { data: series } = await getSeries(projectID, patientID, studyID); - const formattedSeries = getRequiredFields(series, 'serie', selectedID); + const formattedSeries = getRequiredFields(series, "serie", selectedID); return new Promise((resolve, reject) => { resolve(formattedSeries); }); @@ -574,7 +583,7 @@ const getSeriesData = async (projectID, patientID, studyID, selectedID) => { reject( new Error( `Error while getting series data ${err}`, - 'src/components/annotationList/action.js' + "src/components/annotationList/action.js" ) ); }); @@ -593,13 +602,13 @@ const getAnnotationData = async ( projectId, subjectId, studyId, - seriesId + seriesId, }); let formattedAnnotation = []; if (annotations) { formattedAnnotation = getRequiredFields( annotations, - 'annotation', + "annotation", selectedID ); } @@ -611,7 +620,7 @@ const getAnnotationData = async ( reject( new Error( `Error while getting annotations data ${err}`, - 'src/components/annotationList/action.js' + "src/components/annotationList/action.js" ) ); }); @@ -628,20 +637,14 @@ export const getSingleSerie = (serie, annotation) => { studyUID, seriesUID, numberOfAnnotations, - aimID: annotation + aimID: annotation, }; const { aimsData, imageData } = await getSingleSerieData( serie, annotation ); await dispatch( - singleSerieLoaded( - reference, - aimsData, - seriesUID, - imageData, - annotation - ) + singleSerieLoaded(reference, aimsData, seriesUID, imageData, annotation) ); } catch (err) { console.error(err); @@ -657,7 +660,7 @@ export const updateSingleSerie = (serie, annotation) => { studyUID, seriesUID, numberOfAnnotations, - aimID: annotation + aimID: annotation, }; const { aimsData, imageData } = await getSingleSerieData(serie, annotation); await dispatch( @@ -668,7 +671,7 @@ export const updateSingleSerie = (serie, annotation) => { const extractSerieAims = (arr, seriesID) => { let serieAims = []; - arr.forEach(aim => { + arr.forEach((aim) => { const serieUID = aim.ImageAnnotationCollection.imageAnnotations.ImageAnnotation[0] .imageReferenceEntityCollection.ImageReferenceEntity[0].imageStudy @@ -680,9 +683,9 @@ const extractSerieAims = (arr, seriesID) => { return serieAims; }; -const extractStudyAims = arr => { +const extractStudyAims = (arr) => { let studyAims = []; - arr.forEach(aim => { + arr.forEach((aim) => { const serieUID = aim.ImageAnnotationCollection.imageAnnotations.ImageAnnotation[0] .imageReferenceEntityCollection.ImageReferenceEntity[0].imageStudy @@ -698,7 +701,7 @@ const extractNonMarkupAims = (arr, seriesID) => { let studyAims = []; let serieAims = []; // let imageAims = {}; - arr.forEach(aim => { + arr.forEach((aim) => { const series = aim.ImageAnnotationCollection.imageAnnotations.ImageAnnotation[0] .imageReferenceEntityCollection.ImageReferenceEntity[0].imageStudy @@ -727,12 +730,12 @@ const extractNonMarkupAims = (arr, seriesID) => { return { studyAims, serieAims }; }; -const alterImageID = imageAimsObj => { +const alterImageID = (imageAimsObj) => { const imageIDs = Object.keys(imageAimsObj); const aims = Object.values(imageAimsObj); const result = {}; for (let i = 0; i < aims.length; i++) { - const newId = imageIDs[i] ? imageIDs[i] + '-img' : [i] + '-img'; + const newId = imageIDs[i] ? imageIDs[i] + "-img" : [i] + "-img"; result[newId] = aims[i]; } return result; @@ -743,22 +746,22 @@ const getSingleSerieData = (serie, annotation) => { let aimsData; let imageData; let { studyUID, seriesUID, projectID, patientID } = serie; - projectID = projectID ? projectID : 'lite'; + projectID = projectID ? projectID : "lite"; patientID = patientID ? patientID : serie.subjectID; getStudyAims(patientID, studyUID, projectID) - .then(async result => { + .then(async (result) => { const { studyAims, serieAims } = extractNonMarkupAims( result.data.rows, seriesUID ); aimsData = serieAims.concat(studyAims); imageData = { - ...getImageIdAnnotations(serieAims) + ...getImageIdAnnotations(serieAims), }; aimsData = getAimListFields(aimsData, annotation); resolve({ aimsData, imageData }); }) - .catch(err => reject('Error while getting annotation data', err)); + .catch((err) => reject("Error while getting annotation data", err)); }); }; @@ -769,7 +772,7 @@ export function getWholeData(serie, study, annotation) { dispatch(loadPatient()); let { projectID, patientID, patientName, studyUID } = serie || study || annotation; - projectID = projectID ? projectID : 'lite'; + projectID = projectID ? projectID : "lite"; if (annotation) patientID = annotation.subjectID; let selectedID; @@ -785,7 +788,7 @@ export function getWholeData(serie, study, annotation) { let summaryData = { projectID, patientID, - patientName + patientName, }; // make call to get study and populate the studies data try { @@ -796,7 +799,7 @@ export function getWholeData(serie, study, annotation) { dispatch(loadPatientError(error)); } // make call to get series and populate studies with series data - const studies = Object.values(summaryData['studies']); + const studies = Object.values(summaryData["studies"]); for (let st of studies) { let series; try { @@ -839,23 +842,23 @@ export function getWholeData(serie, study, annotation) { export const setSegLabelMapIndex = (aimID, labelMapIndex) => { return { type: SET_SEG_LABEL_MAP_INDEX, - payload: { aimID, labelMapIndex } + payload: { aimID, labelMapIndex }, }; }; -export const segUploadStarted = segUid => { +export const segUploadStarted = (segUid) => { return { type: SEG_UPLOAD_STARTED, payload: segUid }; }; -export const segUploadCompleted = segUid => { +export const segUploadCompleted = (segUid) => { return { type: SEG_UPLOAD_COMPLETED, payload: segUid }; }; -export const segUploadRemove = segUid => { +export const segUploadRemove = (segUid) => { return { type: SEG_UPLOAD_REMOVE, payload: segUid }; }; -export const aimDelete = aimRefs => { +export const aimDelete = (aimRefs) => { return { type: AIM_DELETE, payload: aimRefs }; }; diff --git a/src/components/annotationsList/containers/listItem.jsx b/src/components/annotationsList/containers/listItem.jsx index 91d175f04..21b4cec02 100644 --- a/src/components/annotationsList/containers/listItem.jsx +++ b/src/components/annotationsList/containers/listItem.jsx @@ -1,7 +1,6 @@ import React from "react"; import { connect } from "react-redux"; import { FaMinus, FaPlus, FaEye, FaCheck } from "react-icons/fa"; -import { MAX_PORT } from "../../../constants"; import Annotations from "./annotations"; import { updateAnnotationDisplay, @@ -16,6 +15,8 @@ import { showAnnotationDock } from "../action"; +const MAX_PORT = sessionStorage.getItem("MAX_PORT"); + //single serie will be passed class ListItem extends React.Component { state = { @@ -80,7 +81,7 @@ class ListItem extends React.Component { this.props.dispatch(addToGrid(this.props.serie)); this.props .dispatch(getSingleSerie(this.props.serie)) - .then(() => {}) + .then(() => { }) .catch(err => console.log(err)); this.props.dispatch( updatePatient("serie", true, patientID, studyUID, seriesUID) @@ -170,7 +171,7 @@ class ListItem extends React.Component { //getsingleserie this.props .dispatch(getSingleSerie(this.props.serie)) - .then(() => {}) + .then(() => { }) .catch(err => console.log(err)); //update patient?? with serie this.props.dispatch( diff --git a/src/components/annotationsList/reducer.js b/src/components/annotationsList/reducer.js index 499f22411..0b58c7927 100644 --- a/src/components/annotationsList/reducer.js +++ b/src/components/annotationsList/reducer.js @@ -24,6 +24,7 @@ import { LOAD_COMPLETED, START_LOADING, ADD_TO_GRID, + ADD_TO_GRID2, DISPLAY_SINGLE_AIM, JUMP_TO_AIM, UPDATE_PATIENT, @@ -43,13 +44,13 @@ import { SEG_UPLOAD_REMOVE, AIM_DELETE, colors, - commonLabels -} from './types'; + commonLabels, +} from "./types"; import { persistColorInSaveAim, - persistColorInDeleteAim -} from '../../Utils/aid'; -import { MdSatellite } from 'react-icons/md'; + persistColorInDeleteAim, +} from "../../Utils/aid"; +import { MdSatellite } from "react-icons/md"; const initialState = { openSeries: [], aimsList: {}, @@ -71,9 +72,9 @@ const initialState = { projectMap: {}, templates: {}, aimSegLabelMaps: {}, - notificationAction: '', + notificationAction: "", reports: [], - isSegUploaded: {} + isSegUploaded: {}, }; const asyncReducer = (state = initialState, action) => { @@ -82,7 +83,7 @@ const asyncReducer = (state = initialState, action) => { let aimRefs = {}; switch (action.type) { case UPDATE_IMAGE_INDEX: - const updatedOpenSeries = state.openSeries.map(serie => { + const updatedOpenSeries = state.openSeries.map((serie) => { const newSerie = { ...serie }; if (serie.imageAnnotations) { newSerie.imageAnnotations = { ...serie.imageAnnotations }; @@ -93,18 +94,14 @@ const asyncReducer = (state = initialState, action) => { updatedOpenSeries[state.activePort].imageIndex = action.imageIndex; return { ...state, openSeries: updatedOpenSeries }; case GET_NOTIFICATIONS: - const { - uploadedPid, - lastEventId, - refresh, - notificationAction - } = action.payload; + const { uploadedPid, lastEventId, refresh, notificationAction } = + action.payload; return { ...state, uploadedPid, lastEventId, refresh, - notificationAction + notificationAction, }; case UPDATE_PATIENT_AIM_DELETE: let patientAimDelete = { ...state.patients }; @@ -121,7 +118,7 @@ const asyncReducer = (state = initialState, action) => { ].annotations[aimRefs.aimID] = { ...aimRefs }; return { ...state, patient: patientAimSave }; case CLEAR_AIMID: - aimIDClearedOPenSeries = state.openSeries.map(serie => { + aimIDClearedOPenSeries = state.openSeries.map((serie) => { const newSerie = { ...serie }; if (serie.imageAnnotations) { newSerie.imageAnnotations = { ...serie.imageAnnotations }; @@ -134,7 +131,7 @@ const asyncReducer = (state = initialState, action) => { return { ...state, openSeries: aimIDClearedOPenSeries }; case CLEAR_ACTIVE_AIMID: - aimIDClearedOPenSeries = state.openSeries.map(serie => { + aimIDClearedOPenSeries = state.openSeries.map((serie) => { const newSerie = { ...serie }; if (serie.imageAnnotations) { newSerie.imageAnnotations = { ...serie.imageAnnotations }; @@ -145,7 +142,7 @@ const asyncReducer = (state = initialState, action) => { return { ...state, openSeries: aimIDClearedOPenSeries }; case UPDATE_IMAGEID: - const openSeriesToUpdate = state.openSeries.map(serie => { + const openSeriesToUpdate = state.openSeries.map((serie) => { const newSerie = { ...serie }; if (serie.imageAnnotations) { newSerie.imageAnnotations = { ...serie.imageAnnotations }; @@ -190,13 +187,13 @@ const asyncReducer = (state = initialState, action) => { openSeries: delGrid, aimsList: delAims, // patients: delPatients, - activePort: delActivePort + activePort: delActivePort, }; case LOAD_ANNOTATIONS: return Object.assign({}, state, { loading: true, - error: false + error: false, }); case LOAD_ANNOTATIONS_SUCCESS: return { ...state, loading: false }; @@ -207,7 +204,7 @@ const asyncReducer = (state = initialState, action) => { const projectModalStatus = !state.showProjectModal; return { ...state, showProjectModal: projectModalStatus }; case LOAD_SERIE_SUCCESS: - let imageAddedSeries = state.openSeries.map(serie => { + let imageAddedSeries = state.openSeries.map((serie) => { const newSerie = { ...serie }; if (serie.imageAnnotations) { newSerie.imageAnnotations = { ...serie.imageAnnotations }; @@ -251,16 +248,16 @@ const asyncReducer = (state = initialState, action) => { error: false, aimsList: { ...state.aimsList, - [action.payload.ref.seriesUID]: colorAimsList + [action.payload.ref.seriesUID]: colorAimsList, }, - openSeries: imageAddedSeries + openSeries: imageAddedSeries, }); return result; case LOAD_ANNOTATIONS_ERROR: return Object.assign({}, state, { loading: false, - error: action.error + error: action.error, }); case UPDATE_ANNOTATION_DISPLAY: let { patient, study, serie, annotation, isDisplayed } = action.payload; @@ -271,15 +268,15 @@ const asyncReducer = (state = initialState, action) => { ...state.aimsList[serie], [annotation]: { ...state.aimsList[serie][annotation], - isDisplayed - } - } - } + isDisplayed, + }, + }, + }, }); case CHANGE_ACTIVE_PORT: //get openseries iterate over the - const changedPortSeries = state.openSeries.map(serie => { + const changedPortSeries = state.openSeries.map((serie) => { const newSerie = { ...serie }; if (serie.imageAnnotations) { newSerie.imageAnnotations = { ...serie.imageAnnotations }; @@ -294,7 +291,7 @@ const asyncReducer = (state = initialState, action) => { return Object.assign({}, state, { activePort: action.portIndex, - openSeries: changedPortSeries + openSeries: changedPortSeries, }); case TOGGLE_ALL_ANNOTATIONS: @@ -305,7 +302,7 @@ const asyncReducer = (state = initialState, action) => { toggleAnns[seriesUID][ann].isDisplayed = displayStatus; } return Object.assign({}, state, { - aimsList: toggleAnns + aimsList: toggleAnns, }); case TOGGLE_ALL_LABELS: const toggledLabelSerie = { ...state.aimsList }; @@ -339,7 +336,7 @@ const asyncReducer = (state = initialState, action) => { for (let item in selectionObj) { if (state.patients[item.patientID]) { clearedPatients[item.patientID] = { - ...state.patients[item.patientID] + ...state.patients[item.patientID], }; } } @@ -362,26 +359,26 @@ const asyncReducer = (state = initialState, action) => { patients: clearedPatients, openSeries: [], aimsList: {}, - activePort: 0 + activePort: 0, }; case CLEAR_SELECTION: let selectionState = { ...state }; - if (action.selectionType === 'annotation') { + if (action.selectionType === "annotation") { selectionState.selectedSeries = {}; selectionState.selectedStudies = {}; selectionState.selectedPatients = {}; selectionState.selectedProject = null; - } else if (action.selectionType === 'serie') { + } else if (action.selectionType === "serie") { selectionState.selectedAnnotations = {}; selectionState.selectedStudies = {}; selectionState.selectedPatients = {}; selectionState.selectedProject = null; - } else if (action.selectionType === 'study') { + } else if (action.selectionType === "study") { selectionState.selectedAnnotations = {}; selectionState.selectedSeries = {}; selectionState.selectedPatients = {}; selectionState.selectedProject = null; - } else if (action.selectionType === 'patient') { + } else if (action.selectionType === "patient") { selectionState.selectedAnnotations = {}; selectionState.selectedSeries = {}; selectionState.selectedStudies = {}; @@ -396,7 +393,7 @@ const asyncReducer = (state = initialState, action) => { return selectionState; case SELECT_PATIENT: let patientsNew = { - ...state.selectedPatients + ...state.selectedPatients, }; patientsNew[action.patient.patientID] ? delete patientsNew[action.patient.patientID] @@ -404,7 +401,7 @@ const asyncReducer = (state = initialState, action) => { return { ...state, selectedPatients: patientsNew }; case SELECT_STUDY: let newStudies = { - ...state.selectedStudies + ...state.selectedStudies, }; newStudies[action.study.studyUID] ? delete newStudies[action.study.studyUID] @@ -416,7 +413,7 @@ const asyncReducer = (state = initialState, action) => { return { ...state, loading: false }; case SELECT_SERIE: let newSeries = { - ...state.selectedSeries + ...state.selectedSeries, }; newSeries[action.serie.seriesUID] ? delete newSeries[action.serie.seriesUID] @@ -425,7 +422,7 @@ const asyncReducer = (state = initialState, action) => { return { ...state, selectedSeries: newSeries }; case SELECT_ANNOTATION: let newAnnotations = { - ...state.selectedAnnotations + ...state.selectedAnnotations, }; newAnnotations[action.annotation.aimID] ? delete newAnnotations[action.annotation.aimID] @@ -438,7 +435,7 @@ const asyncReducer = (state = initialState, action) => { return { ...state, patientLoadingError: action.err, - patientLoading: false + patientLoading: false, }; case LOAD_PATIENT_SUCCESS: let addedNewPatient = { ...state.patients }; @@ -448,11 +445,11 @@ const asyncReducer = (state = initialState, action) => { ...state, patients: addedNewPatient, patientLoading: false, - patientLoadingError: false + patientLoadingError: false, }; case DISPLAY_SINGLE_AIM: let aimPatient = { ...state.patients[action.payload.patientID] }; - let aimOpenSeries = state.openSeries.map(serie => { + let aimOpenSeries = state.openSeries.map((serie) => { const newSerie = { ...serie }; if (serie.imageAnnotations) { newSerie.imageAnnotations = { ...serie.imageAnnotations }; @@ -488,7 +485,7 @@ const asyncReducer = (state = initialState, action) => { ].annotations ); - allAims.forEach(ann => { + allAims.forEach((ann) => { if (ann === action.payload.aimID) { aimAimsList[ann].isDisplayed = true; aimAimsList[ann].showLabel = true; @@ -504,13 +501,13 @@ const asyncReducer = (state = initialState, action) => { ...state, aimsList: { ...state.aimsList, - [action.payload.seriesUID]: aimAimsList + [action.payload.seriesUID]: aimAimsList, }, patients: { ...state.patients, - [action.payload.patientID]: aimPatient + [action.payload.patientID]: aimPatient, }, - openSeries: aimOpenSeries + openSeries: aimOpenSeries, }; case ADD_TO_GRID: const seriesInfo = { ...action.reference }; @@ -523,18 +520,29 @@ const asyncReducer = (state = initialState, action) => { return { ...state, openSeries: newOpenSeries, - activePort: newOpenSeries.length - 1 + activePort: newOpenSeries.length - 1, + }; + case ADD_TO_GRID2: + const seriesInfo2 = { ...action.reference }; + seriesInfo2.projectName = "lite"; + seriesInfo2.defaultTemplate = null; + let newOpenSeries2 = state.openSeries.concat(seriesInfo2); + + return { + ...state, + openSeries: newOpenSeries2, + activePort: newOpenSeries2.length - 1, }; case UPDATE_PATIENT: let updatedPt = { ...state.patients[action.payload.patient] }; - if (action.payload.type === 'study') { + if (action.payload.type === "study") { let selectedSt = updatedPt.studies[action.payload.study]; for (let serie in selectedSt.series) { selectedSt.series[serie].isDisplayed = action.payload.status; } } else if ( - action.payload.type === 'serie' || - action.payload.type === 'annotation' + action.payload.type === "serie" || + action.payload.type === "annotation" ) { let selectedSr = updatedPt.studies[action.payload.study].series[ @@ -551,7 +559,7 @@ const asyncReducer = (state = initialState, action) => { case JUMP_TO_AIM: let { aimID, index } = action.payload; let serUID = action.payload.seriesUID; - let updatedGrid = state.openSeries.map(serie => { + let updatedGrid = state.openSeries.map((serie) => { const newSerie = { ...serie }; if (serie.imageAnnotations) { newSerie.imageAnnotations = { ...serie.imageAnnotations }; @@ -569,21 +577,21 @@ const asyncReducer = (state = initialState, action) => { ...state.aimsList[serUID], [aimID]: { ...state.aimsList[serUID][aimID], - isDisplayed: true - } - } - } + isDisplayed: true, + }, + }, + }, }); case GET_PROJECT_MAP: return { ...state, - projectMap: action.projectMap + projectMap: action.projectMap, }; case SET_SEG_LABEL_MAP_INDEX: { const { aimID, labelMapIndex } = action.payload; return { ...state, - aimSegLabelMaps: { ...state.aimSegLabelMaps, [aimID]: labelMapIndex } + aimSegLabelMaps: { ...state.aimSegLabelMaps, [aimID]: labelMapIndex }, }; } case GET_TEMPLATES: @@ -591,20 +599,20 @@ const asyncReducer = (state = initialState, action) => { case SEG_UPLOAD_STARTED: { let segUid = action.payload; return Object.assign({}, state, { - isSegUploaded: { ...state.isSegUploaded, [segUid]: false } + isSegUploaded: { ...state.isSegUploaded, [segUid]: false }, }); } case SEG_UPLOAD_COMPLETED: { let segUid = action.payload; return Object.assign({}, state, { - isSegUploaded: { ...state.isSegUploaded, [segUid]: true } + isSegUploaded: { ...state.isSegUploaded, [segUid]: true }, }); } case SEG_UPLOAD_REMOVE: { let segUid = action.payload; const { [segUid]: value, ...theRest } = state.isSegUploaded; return Object.assign({}, state, { - isSegUploaded: { ...theRest } + isSegUploaded: { ...theRest }, }); } case AIM_DELETE: { diff --git a/src/components/annotationsList/selectSerieModal.jsx b/src/components/annotationsList/selectSerieModal.jsx index f5eec025d..1d9f3b7b8 100644 --- a/src/components/annotationsList/selectSerieModal.jsx +++ b/src/components/annotationsList/selectSerieModal.jsx @@ -13,10 +13,9 @@ import { import SelectionItem from "./containers/selectionItem"; import { FaRegCheckSquare } from "react-icons/fa"; import { getSeries } from "../../services/seriesServices"; -import { MAX_PORT } from "../../constants"; import "./annotationsList.css" - +const MAX_PORT = sessionStorage.getItem("MAX_PORT"); const message = { title: "Not enough ports to open series" }; diff --git a/src/components/annotationsList/types.js b/src/components/annotationsList/types.js index 6e9bff589..16ffa90fd 100644 --- a/src/components/annotationsList/types.js +++ b/src/components/annotationsList/types.js @@ -1,108 +1,109 @@ -export const LOAD_ANNOTATIONS = 'epadjs/annotationList/LOAD_ANNOTATIONS'; +export const LOAD_ANNOTATIONS = "epadjs/annotationList/LOAD_ANNOTATIONS"; export const LOAD_ANNOTATIONS_SUCCESS = - 'epadjs/annotationList/LOAD_ANNOTATIONS_SUCCESS'; + "epadjs/annotationList/LOAD_ANNOTATIONS_SUCCESS"; export const LOAD_ANNOTATIONS_ERROR = - 'epadjs/annotationList/LOAD_ANNOTATIONS_ERROR'; -export const LOAD_PATIENT = 'epadjs/annotationList/LOAD_PATIENT'; -export const LOAD_PATIENT_ERROR = 'epadjs/annotationList/LOAD_PATIENT_ERROR'; + "epadjs/annotationList/LOAD_ANNOTATIONS_ERROR"; +export const LOAD_PATIENT = "epadjs/annotationList/LOAD_PATIENT"; +export const LOAD_PATIENT_ERROR = "epadjs/annotationList/LOAD_PATIENT_ERROR"; export const LOAD_PATIENT_SUCCESS = - 'epadjs/annotationList/LOAD_PATIENT_SUCCESS'; -export const VIEWPORT_FULL = 'epadjs/annotationList/VIEWPORT_FULL'; -export const OPEN_PROJECT_MODAL = 'epadjs/annotationList/OPEN_PROJECT_MODAL'; + "epadjs/annotationList/LOAD_PATIENT_SUCCESS"; +export const VIEWPORT_FULL = "epadjs/annotationList/VIEWPORT_FULL"; +export const OPEN_PROJECT_MODAL = "epadjs/annotationList/OPEN_PROJECT_MODAL"; export const UPDATE_ANNOTATION_DISPLAY = - 'epadjs/annotationList/UPDATE_ANNOTATION_DISPLAY'; + "epadjs/annotationList/UPDATE_ANNOTATION_DISPLAY"; export const TOGGLE_ALL_ANNOTATIONS = - 'epadjs/annotationList/TOGGLE_ALL_ANNOTATIONS'; -export const TOGGLE_ALL_LABELS = 'epadjs/annotationList/TOGGLE_ALL_LABELS'; -export const TOGGLE_LABEL = 'epadjs/annotationList/TOGGLE_LABEL'; -export const CHANGE_ACTIVE_PORT = 'epadjs/annotationList/CHANGE_ACTIVE_PORT'; -export const LOAD_SERIE_SUCCESS = 'epadjs/annotationList/LOAD_SERIE_SUCCESS'; + "epadjs/annotationList/TOGGLE_ALL_ANNOTATIONS"; +export const TOGGLE_ALL_LABELS = "epadjs/annotationList/TOGGLE_ALL_LABELS"; +export const TOGGLE_LABEL = "epadjs/annotationList/TOGGLE_LABEL"; +export const CHANGE_ACTIVE_PORT = "epadjs/annotationList/CHANGE_ACTIVE_PORT"; +export const LOAD_SERIE_SUCCESS = "epadjs/annotationList/LOAD_SERIE_SUCCESS"; export const SHOW_ANNOTATION_WINDOW = - 'epadjs/annotationList/SHOW_ANNOTATION_WINDOW'; -export const SELECT_PROJECT = 'epadjs/annotationList/SELECT_PROJECT'; -export const SELECT_PATIENT = 'epadjs/annotationList/SELECT_PATIENT'; -export const SELECT_SERIE = 'epadjs/annotationList/SELECT_SERIE'; -export const SELECT_STUDY = 'epadjs/annotationList/SELECT_STUDY'; -export const SELECT_ANNOTATION = 'epadjs/annotationList/SELECT_ANNOTATION'; -export const CLEAR_GRID = 'epadjs/annotationList/CLEAR_GRID '; -export const CLEAR_SELECTION = 'epadjs/annotationList/CLEAR_SELECTION '; -export const GET_PATIENT = 'epadjs/annotationList/GET_PATIENT'; -export const DISPLAY_SINGLE_AIM = 'epadjs/annotationList/DISPLAY_SINGLE_AIM'; -export const JUMP_TO_AIM = 'epadjs/annotationList/JUMP_TO_AIM'; -export const ADD_TO_GRID = 'epadjs/annotationList/ADD_TO_GRID'; -export const LOAD_COMPLETED = 'epadjs/annotationList/LOAD_COMPLETED'; -export const START_LOADING = 'epadjs/annotationList/START_LOADING'; -export const UPDATE_PATIENT = 'epadjs/annotationList/UPDATE_PATIENT'; -export const CLOSE_SERIE = 'epadjs/annotationList/CLOSE_SERIE'; -export const UPDATE_IMAGEID = 'epadjs/annotationList/UPDATE_IMAGEID'; -export const CLEAR_AIMID = 'epadjs/annotationList/CLEAR_AIMID'; + "epadjs/annotationList/SHOW_ANNOTATION_WINDOW"; +export const SELECT_PROJECT = "epadjs/annotationList/SELECT_PROJECT"; +export const SELECT_PATIENT = "epadjs/annotationList/SELECT_PATIENT"; +export const SELECT_SERIE = "epadjs/annotationList/SELECT_SERIE"; +export const SELECT_STUDY = "epadjs/annotationList/SELECT_STUDY"; +export const SELECT_ANNOTATION = "epadjs/annotationList/SELECT_ANNOTATION"; +export const CLEAR_GRID = "epadjs/annotationList/CLEAR_GRID "; +export const CLEAR_SELECTION = "epadjs/annotationList/CLEAR_SELECTION "; +export const GET_PATIENT = "epadjs/annotationList/GET_PATIENT"; +export const DISPLAY_SINGLE_AIM = "epadjs/annotationList/DISPLAY_SINGLE_AIM"; +export const JUMP_TO_AIM = "epadjs/annotationList/JUMP_TO_AIM"; +export const ADD_TO_GRID = "epadjs/annotationList/ADD_TO_GRID"; +export const ADD_TO_GRID2 = "epadjs/annotationList/ADD_TO_GRID2"; +export const LOAD_COMPLETED = "epadjs/annotationList/LOAD_COMPLETED"; +export const START_LOADING = "epadjs/annotationList/START_LOADING"; +export const UPDATE_PATIENT = "epadjs/annotationList/UPDATE_PATIENT"; +export const CLOSE_SERIE = "epadjs/annotationList/CLOSE_SERIE"; +export const UPDATE_IMAGEID = "epadjs/annotationList/UPDATE_IMAGEID"; +export const CLEAR_AIMID = "epadjs/annotationList/CLEAR_AIMID"; export const UPDATE_PATIENT_AIM_SAVE = - 'epadjs/annotationList/UPDATE_PATIENT_AIM_SAVE'; + "epadjs/annotationList/UPDATE_PATIENT_AIM_SAVE"; export const UPDATE_PATIENT_AIM_DELETE = - 'epadjs/annotationList/UPDATE_PATIENT_AIM_DELETE'; -export const GET_NOTIFICATIONS = 'epadjs/annotationList/GET_NOTIFICATIONS'; -export const CLEAR_ACTIVE_AIMID = 'epadjs/annotationList/CLEAR_ACTIVE_AIMID'; -export const UPDATE_IMAGE_INDEX = 'epadjs/annotationList/UPDATE_IMAGE_INDEX '; -export const GET_PROJECT_MAP = 'epadjs/annotationList/GET_PROJECT_MAP'; + "epadjs/annotationList/UPDATE_PATIENT_AIM_DELETE"; +export const GET_NOTIFICATIONS = "epadjs/annotationList/GET_NOTIFICATIONS"; +export const CLEAR_ACTIVE_AIMID = "epadjs/annotationList/CLEAR_ACTIVE_AIMID"; +export const UPDATE_IMAGE_INDEX = "epadjs/annotationList/UPDATE_IMAGE_INDEX "; +export const GET_PROJECT_MAP = "epadjs/annotationList/GET_PROJECT_MAP"; export const SET_SEG_LABEL_MAP_INDEX = - 'epadjs/annotationList/SET_SEG_LABEL_MAP_INDEX'; -export const GET_TEMPLATES = 'epadjs/annotationList/GET_TEMPLATES'; -export const SEG_UPLOAD_STARTED = 'epadjs/annotationList/SEG_UPLOAD_STARTED'; + "epadjs/annotationList/SET_SEG_LABEL_MAP_INDEX"; +export const GET_TEMPLATES = "epadjs/annotationList/GET_TEMPLATES"; +export const SEG_UPLOAD_STARTED = "epadjs/annotationList/SEG_UPLOAD_STARTED"; export const SEG_UPLOAD_COMPLETED = - 'epadjs/annotationList/SEG_UPLOAD_COMPLETED'; -export const SEG_UPLOAD_REMOVE = 'epadjs/annotationList/SEG_UPLOAD_REMOVE'; -export const AIM_DELETE = 'epadjs/annotationList/AIM_DELETE'; + "epadjs/annotationList/SEG_UPLOAD_COMPLETED"; +export const SEG_UPLOAD_REMOVE = "epadjs/annotationList/SEG_UPLOAD_REMOVE"; +export const AIM_DELETE = "epadjs/annotationList/AIM_DELETE"; export const commonLabels = { - button: { background: '#c0c0c0', color: 'black' }, - label: { background: '#858585', color: 'white' } + button: { background: "#c0c0c0", color: "black" }, + label: { background: "#858585", color: "white" }, }; export const colors = [ { - button: { background: '#e6194B', color: 'black' }, - label: { background: '#8a0d2a', color: 'white' } + button: { background: "#e6194B", color: "black" }, + label: { background: "#8a0d2a", color: "white" }, }, // { button: { background: "#ffe119", color: "black" }, // label: { background: "#786d22", color: "white" } // }, { - button: { background: '#3cb44b', color: 'black' }, - label: { background: '#3d7540', color: 'white' } + button: { background: "#3cb44b", color: "black" }, + label: { background: "#3d7540", color: "white" }, }, { - button: { background: '#42d4f4', color: 'black' }, - label: { background: '#4a8c99', color: 'white' } + button: { background: "#42d4f4", color: "black" }, + label: { background: "#4a8c99", color: "white" }, }, { - button: { background: '#ff9000', color: 'black' }, - label: { background: '#915d38', color: 'white' } + button: { background: "#ff9000", color: "black" }, + label: { background: "#915d38", color: "white" }, }, { - button: { background: '#4363d8', color: 'white' }, - label: { background: '#49598f', color: 'white' } + button: { background: "#4363d8", color: "white" }, + label: { background: "#49598f", color: "white" }, }, { - button: { background: '#911eb4', color: 'white' }, - label: { background: '#632a73', color: 'white' } + button: { background: "#911eb4", color: "white" }, + label: { background: "#632a73", color: "white" }, }, { - button: { background: '#7ebfb1', color: 'black' }, - label: { background: '#397d74', color: 'white' } + button: { background: "#7ebfb1", color: "black" }, + label: { background: "#397d74", color: "white" }, }, { - button: { background: '#ffc0cb', color: 'black' }, - label: { background: '#9e5857', color: 'white' } + button: { background: "#ffc0cb", color: "black" }, + label: { background: "#9e5857", color: "white" }, }, { - button: { background: '#fffac8', color: 'black' }, - label: { background: '#9e9859', color: 'white' } + button: { background: "#fffac8", color: "black" }, + label: { background: "#9e9859", color: "white" }, }, { - button: { background: '#aaffc3', color: 'black' }, - label: { background: '#489c5f', color: 'white' } + button: { background: "#aaffc3", color: "black" }, + label: { background: "#489c5f", color: "white" }, }, { - button: { background: '#e6beff', color: 'black' }, - label: { background: '#7e5296', color: 'white' } - } + button: { background: "#e6beff", color: "black" }, + label: { background: "#7e5296", color: "white" }, + }, ]; diff --git a/src/components/display/ViewportCalculations.js b/src/components/display/ViewportCalculations.js new file mode 100644 index 000000000..94281d64e --- /dev/null +++ b/src/components/display/ViewportCalculations.js @@ -0,0 +1,37 @@ +const getVPDimensions = (numSeries) => { + const navbar = document.getElementsByClassName("navbar")[0].clientHeight; + let toolbarHeight = + document.getElementsByClassName("toolbar")[0].clientHeight; + const windowInner = window.innerHeight; + const containerHeight = windowInner - toolbarHeight - navbar - 10; + + let width, height; + switch (numSeries) { + case 1: + width = "100%"; + height = containerHeight; + break; + case 2: + width = "50%"; + height = containerHeight; + break; + case (3, 4): + width = "50%"; + height = containerHeight / 2; + break; + case (5, 6): + width = "33%"; + height = containerHeight / 2; + break; + case (7, 8): + width = "25%"; + height = containerHeight / 2; + break; + default: + width = "100%"; + height = containerHeight; + } + return { width, height }; +}; + +export default getVPDimensions; diff --git a/src/components/display/displayView.jsx b/src/components/display/displayView.jsx index 5542e5ba0..12ba99de7 100644 --- a/src/components/display/displayView.jsx +++ b/src/components/display/displayView.jsx @@ -43,6 +43,7 @@ import { isThisSecond } from "date-fns/esm"; import { FiMessageSquare } from "react-icons/fi"; import { errorMonitor } from "events"; import FreehandRoiSculptorTool from '../../cornerstone-tools/tools/FreehandRoiSculptorTool'; +import getVPDimensions from "./ViewportCalculations"; const mode = sessionStorage.getItem("mode"); const wadoUrl = sessionStorage.getItem("wadoUrl"); @@ -180,7 +181,8 @@ class DisplayView extends Component { window.addEventListener("editAim", this.editAimHandler); window.addEventListener("deleteAim", this.deleteAimHandler); window.addEventListener('keydown', this.handleKeyPressed); - if (series && series.length > 0) { + const API_KEY = sessionStorage.getItem("API_KEY"); + if (series && series.length > 0 && !API_KEY) { const tokenRefresh = setInterval(this.checkTokenExpire, 500); this.setState({ tokenRefresh }) }; @@ -538,8 +540,15 @@ class DisplayView extends Component { let newImageIds = {}; let cornerstoneImageIds = []; const imageUrls = await this.getImages(serie); + const API_KEY = sessionStorage.getItem("API_KEY"); + let baseUrl; imageUrls.map((url) => { - const baseUrl = wadoUrl + url.lossyImage; + if (API_KEY) { + const user = sessionStorage.getItem("user"); + baseUrl = wadoUrl + url.lossyImage + `&user=${user}`; + } + else baseUrl = wadoUrl + url.lossyImage; + if (url.multiFrameImage === true) { for (var i = 0; i < url.numberOfFrames; i++) { let multiFrameUrl = baseUrl + "&frame=" + i; @@ -693,21 +702,24 @@ class DisplayView extends Component { }; getViewports = (containerHeight) => { - let numSeries = this.props.series.length; - let numCols = numSeries % 3; - containerHeight = containerHeight - ? containerHeight - : this.state.containerHeight; - if (numSeries > 3) { - this.setState({ height: containerHeight / 2 }); - this.setState({ width: "33%" }); - return; - } - if (numCols === 1) { - this.setState({ width: "100%", height: containerHeight }); - } else if (numCols === 2) - this.setState({ width: "50%", height: containerHeight }); - else this.setState({ width: "33%", height: containerHeight }); + + const numSeries = this.props.series.length; + const { width, height } = getVPDimensions(numSeries); + this.setState({ width, height }); + // let numCols = numSeries % 3; + // containerHeight = containerHeight + // ? containerHeight + // : this.state.containerHeight; + // if (numSeries > 3) { + // this.setState({ height: containerHeight / 2 }); + // this.setState({ width: "33%" }); + // return; + // } + // if (numCols === 1) { + // this.setState({ width: "100%", height: containerHeight }); + // } else if (numCols === 2) + // this.setState({ width: "50%", height: containerHeight }); + // else this.setState({ width: "33%", height: containerHeight }); }; createRefs() { diff --git a/src/components/flexView/SeriesTable.jsx b/src/components/flexView/SeriesTable.jsx index 58e0f912b..df89344c5 100644 --- a/src/components/flexView/SeriesTable.jsx +++ b/src/components/flexView/SeriesTable.jsx @@ -3,7 +3,6 @@ import { connect } from "react-redux"; import { withRouter } from "react-router-dom"; import Draggable from "react-draggable"; import { FaRegCheckSquare } from "react-icons/fa"; -import { MAX_PORT } from "../../constants"; import { addToGrid, getSingleSerie, @@ -11,6 +10,8 @@ import { updatePatient, clearSelection, } from "../annotationsList/action"; + +const MAX_PORT = sessionStorage.getItem("MAX_PORT"); // connect to store // is seriesUID in the openSeries checkbox clicked const SeriesTable = (props) => { @@ -43,7 +44,7 @@ const SeriesTable = (props) => { props.dispatch(addToGrid(selected)); props .dispatch(getSingleSerie(selected)) - .then(() => {}) + .then(() => { }) .catch((err) => console.log(err)); if (!props.patients[selected.patientID]) { // props.dispatch(getWholeData(selected)); diff --git a/src/components/management/annotations/annotations.jsx b/src/components/management/annotations/annotations.jsx index 9e5b7ea1d..2550ffab0 100644 --- a/src/components/management/annotations/annotations.jsx +++ b/src/components/management/annotations/annotations.jsx @@ -16,7 +16,6 @@ import matchSorter from "match-sorter"; import DeleteAlert from "../common/alertDeletionModal"; import UploadModal from "../../searchView/uploadModal"; import DownloadModal from "../../searchView/annotationDownloadModal"; -import { MAX_PORT } from "../../../constants"; import { changeActivePort, jumpToAim, @@ -35,6 +34,7 @@ import { getSeries } from "../../../services/seriesServices"; import SelectSeriesModal from "../../annotationsList/selectSerieModal"; const mode = sessionStorage.getItem("mode"); +const MAX_PORT = sessionStorage.getItem("MAX_PORT"); const messages = { deleteSelected: "Delete selected annotations? This cannot be undone.", @@ -190,8 +190,8 @@ class Annotations extends React.Component { const { data: { rows, total_rows, bookmark } } = projectID && projectID !== 'all_aims' - ? await getSummaryAnnotations(projectID, bookmarkPassed) - : await getAllAnnotations(bookmarkPassed); + ? await getSummaryAnnotations(projectID, bookmarkPassed) + : await getAllAnnotations(bookmarkPassed); if (bookmarkPassed) { const pages = Math.ceil(total_rows / pageSize); @@ -327,10 +327,10 @@ class Annotations extends React.Component { keys.length === 0 ? this.setState({ selectAll: 0, selected: {}, filteredData: [] }) : this.setState({ - seriesAlreadyOpen: keys.length, - selected: notDeleted, - selectAll: 2 - }); + seriesAlreadyOpen: keys.length, + selected: notDeleted, + selectAll: 2 + }); }) .catch(error => { if ( @@ -869,7 +869,7 @@ class Annotations extends React.Component { } //getsingleSerie Promise.all(promiseArr) - .then(() => {}) + .then(() => { }) .catch(err => console.error(err)); //if patient doesnot exist get patient diff --git a/src/components/navbar.jsx b/src/components/navbar.jsx index 225e24feb..d278468e9 100644 --- a/src/components/navbar.jsx +++ b/src/components/navbar.jsx @@ -87,16 +87,7 @@ const NavBar = ({ Progress - */} - + */} {/*
  • Edit @@ -117,6 +108,15 @@ const NavBar = ({
  • {' '} )} +
    @@ -515,7 +524,7 @@ const Report = props => { /> )} - {data.waterfallExport && Export to CSV} + {data.waterfallExport && Export to CSV} )} diff --git a/src/components/searchView/Series.jsx b/src/components/searchView/Series.jsx index 32a0f6be3..4f73270bb 100644 --- a/src/components/searchView/Series.jsx +++ b/src/components/searchView/Series.jsx @@ -5,7 +5,6 @@ import { toast } from "react-toastify"; import { withRouter } from 'react-router-dom'; import ReactTooltip from 'react-tooltip'; import PropagateLoader from 'react-spinners/PropagateLoader'; -import { MAX_PORT } from '../../constants'; import { formatDate } from '../flexView/helperMethods'; import Annotations from './Annotations'; import { getSeries } from '../../services/seriesServices'; @@ -21,6 +20,8 @@ import { selectAnnotation } from '../annotationsList/action'; +const MAX_PORT = sessionStorage.getItem("MAX_PORT"); + function Table({ columns, data, diff --git a/src/components/searchView/Studies.jsx b/src/components/searchView/Studies.jsx index 311176a6f..5f48c4fab 100644 --- a/src/components/searchView/Studies.jsx +++ b/src/components/searchView/Studies.jsx @@ -11,7 +11,8 @@ import Series from './Series'; import { formatDate } from '../flexView/helperMethods'; import { getSeries } from '../../services/seriesServices'; import { clearCarets } from '../../Utils/aid.js'; -import { MAX_PORT } from '../../constants'; + +const MAX_PORT = sessionStorage.getItem("MAX_PORT"); import { getSingleSerie, @@ -254,7 +255,7 @@ function Studies(props) { } //getsingleSerie Promise.all(promiseArr) - .then(() => {}) + .then(() => { }) .catch(err => console.error(err)); //if patient doesnot exist get patient @@ -482,8 +483,8 @@ function Studies(props) { const studiesArray = treeData[projectID] && treeData[projectID][subjectID] ? Object.values(treeData[projectID][subjectID].studies).map( - el => el.data - ) + el => el.data + ) : []; return studiesArray; diff --git a/src/components/searchView/searchView.jsx b/src/components/searchView/searchView.jsx index ac3da716a..d858bea67 100644 --- a/src/components/searchView/searchView.jsx +++ b/src/components/searchView/searchView.jsx @@ -35,7 +35,6 @@ import { updateSingleSerie, updatePatientOnAimDelete } from '../annotationsList/action'; -import { MAX_PORT } from '../../constants'; import DownloadSelection from './annotationDownloadModal'; import './searchView.css'; import UploadModal from './uploadModal'; @@ -56,7 +55,9 @@ import WarningModal from '../common/warningModal'; import AnnotationCreationModal from './annotationCreationModal.jsx'; import UpLoadWizard from '../tagEditor/uploadWizard'; import { FaLessThan } from 'react-icons/fa'; + const mode = sessionStorage.getItem('mode'); +const MAX_PORT = sessionStorage.getItem("MAX_PORT"); const messages = { newUser: { @@ -128,7 +129,7 @@ class SearchView extends Component { subjects, expandLevel }); - } catch (err) {} + } catch (err) { } }; componentDidUpdate = async prevProps => { @@ -171,10 +172,10 @@ class SearchView extends Component { patients.length > 0 ? patients : studies.length > 0 - ? studies - : series.length > 0 - ? series - : annotations; + ? studies + : series.length > 0 + ? series + : annotations; selection.forEach((el, i) => { if (el.projectID === 'all' || el.projectID === 'nonassigned') { checkFromProjectID = true; @@ -996,7 +997,7 @@ class SearchView extends Component { onAddProject={this.handleProjectClick} admin={this.props.admin} hideEyeIcon={hideEyeIcon} - // expanding={expanding} + // expanding={expanding} /> {isSerieSelectionOpen && !this.props.loading && ( 0) { const projectList = notAuthorized.reduce((all, item, i) => { - return `${all} ${item}${ - notAuthorized.length - 1 === i ? "" : ", " - }`; + return `${all} ${item}${notAuthorized.length - 1 === i ? "" : ", " + }`; }, ""); const message = `${messages.notAuthorizedProjects} ${projectList}` toast.error(message, { diff --git a/src/constants.js b/src/constants.js index 639f4c191..495d87798 100644 --- a/src/constants.js +++ b/src/constants.js @@ -1,7 +1,6 @@ -export const MAX_PORT = 6; export const widthUnit = 20; -export const formatDates = timeStamp => { +export const formatDates = (timeStamp) => { //split it by space timeStamp = timeStamp + ""; if (!timeStamp.includes(" ")) { diff --git a/src/services/authService.js b/src/services/authService.js index bee181529..da6682919 100644 --- a/src/services/authService.js +++ b/src/services/authService.js @@ -46,7 +46,18 @@ export function getCurrentUser() { } export async function getAuthHeader() { - if (this.keycloak) { + const API_KEY = sessionStorage.getItem("API_KEY"); + if (API_KEY) { + const header = `apikey ${API_KEY}`; + if (header) { + cornerstoneWADOImageLoader.configure({ + beforeSend: function (xhr) { + xhr.setRequestHeader("Authorization", header); + }, + }); + return header; + } + } else if (this.keycloak) { try { await refreshToken(this.keycloak, 5); const header = `Bearer ${this.keycloak.token}`; diff --git a/src/services/decryptUrlService.js b/src/services/decryptUrlService.js new file mode 100644 index 000000000..dd8435b64 --- /dev/null +++ b/src/services/decryptUrlService.js @@ -0,0 +1,10 @@ +import http from "./httpService"; +const apiUrl = sessionStorage.getItem("apiUrl"); + +export function decrypt(args) { + return http.get(apiUrl + "/decrypt?arg=" + args); +} + +export function decryptAndAdd(args) { + return http.put(apiUrl + "/decryptandadd?arg=" + args); +} diff --git a/src/services/httpService.js b/src/services/httpService.js index 06e11657c..31252b397 100644 --- a/src/services/httpService.js +++ b/src/services/httpService.js @@ -7,16 +7,22 @@ axios.defaults.headers.common["Content-Type"] = "application/json, multipart/form-data"; axios.interceptors.request.use( - async config => { + async (config) => { // initializeKeyCloak(); + const apikey = sessionStorage.getItem("API_KEY"); + const user = sessionStorage.getItem("user"); + if (apikey && user) { + config.params = {}; + config.params["user"] = user; + } const header = await auth.getAuthHeader(); if (header) config.headers.authorization = header; return config; }, - error => Promise.reject(error) + (error) => Promise.reject(error) ); -axios.interceptors.response.use(null, error => { +axios.interceptors.response.use(null, (error) => { console.log("ERROR::"); console.log(error); // console.log("ERROR::", error.response.data);