Skip to content
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

Hiding DICOM Viewer button for the imaging studies that doesn't have one #1174

Merged
merged 12 commits into from
Dec 16, 2022
52 changes: 46 additions & 6 deletions src/GuppyDataExplorer/ExplorerTable/index.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import React, { useEffect, ReactNode } from 'react';
import PropTypes from 'prop-types';
import _ from 'lodash';
import _, { isEqual } from 'lodash';
import pluralize from 'pluralize';
import ReactTable from 'react-table';
import { Switch } from 'antd';
Expand All @@ -21,6 +21,7 @@ class ExplorerTable extends React.Component {
pageSize: props.defaultPageSize,
currentPage: 0,
showEmptyColumns: false,
tableData: this.props.rawData,
};
}

Expand Down Expand Up @@ -56,7 +57,7 @@ class ExplorerTable extends React.Component {

/**
* Build column configs for each table according to their locations and fields
* @param field: the full field name, if it is a nested field, it would contains at least 1 '.'
* @param field: the full field name, if it is a nested field, it would contain at least 1 '.'
* @param isNestedTableColumn: control flag to determine if it is building column config for
* the root table or inner nested tables
* @param isDetailedColumn: control flag to determine if it is building column config for inner
Expand All @@ -65,7 +66,7 @@ class ExplorerTable extends React.Component {
*/
buildColumnConfig = (field, isNestedTableColumn, isDetailedColumn) => {
const fieldMappingEntry = this.props.guppyConfig.fieldMapping
&& this.props.guppyConfig.fieldMapping.find((i) => i.field === field);
&& this.props.guppyConfig.fieldMapping.find((i) => i.field === field);
const overrideName = fieldMappingEntry ? fieldMappingEntry.name : undefined;
const fieldStringsArray = field.split('.');
// for nested table, we only display the children names in column header
Expand Down Expand Up @@ -130,7 +131,10 @@ class ExplorerTable extends React.Component {

// if this field is the `dicomViewerId`, convert the value to a link to the DICOM viewer
if (this.props.tableConfig.dicomViewerId && this.props.tableConfig.dicomViewerId === field && valueStr) {
const dicomViewerLink = `${hostname}dicom-viewer/viewer/${valueStr}`;
let dicomViewerLink = `${hostname}dicom-viewer/viewer/${valueStr}`;
if (row.original.has_dicom_images !== undefined && !row.original.has_dicom_images) {
dicomViewerLink = undefined;
}
if (this.props.tableConfig.linkFields.includes(field)) { // link button
valueStr = dicomViewerLink;
} else { // direct link
Expand Down Expand Up @@ -248,10 +252,46 @@ class ExplorerTable extends React.Component {
this.setState({ showEmptyColumns: checked });
};

/**
* processes the table data if this is a dicom table. This will determine if the table row
* has image data and will then esure that the lick icon is shown
*/
augmentData = () => {
const haveField = this.props.rawData.filter((x) => Object.keys(x).includes(this.props.tableConfig.dicomViewerId));
if (haveField.length === this.props.rawData.length) {
this.setState({ loading: true });
// eslint-disable-next-line array-callback-return
Promise.all(this.props.rawData.map((x) => {
const dicomServerLink = `${hostname}dicom-server/dicom-web/studies/${x[this.props.tableConfig.dicomViewerId]}/series`;
return fetch(dicomServerLink, {
method: 'GET',
})
.then((resp) => ({ ...x, has_dicom_images: resp.headers.get('content-length') !== '22' }),
);
})).then((data) => {
this.setState({ tableData: data });
this.setState({ loading: false });
});
}
}

/**
* Used to process the table data when needed.
* THis is used primarily to check for the existence
* of a Dicom images to show the link icon to the dicom viewer
* @param prevProps
*/
componentDidUpdate(prevProps) {
if (this.props.tableConfig.dicomViewerId && !isEqual(this.props.rawData, prevProps.rawData)) {
this.augmentData();
} else if (this.props.rawData !== prevProps.rawData) this.setState({ tableData: this.props.rawData });
}

render() {
if (!this.props.tableConfig.fields || this.props.tableConfig.fields.length === 0) {
return null;
}

// build column configs for root table first
const rootColumnsConfig = this.props.tableConfig.fields.map((field) => {
const tempColumnConfig = this.buildColumnConfig(field, false, false);
Expand Down Expand Up @@ -368,7 +408,7 @@ class ExplorerTable extends React.Component {
<ReactTable
columns={rootColumnsConfig}
manual
data={(this.props.isLocked || !this.props.rawData) ? [] : this.props.rawData}
data={(this.props.isLocked || !this.props.rawData) ? [] : this.state.tableData}
showPageSizeOptions={!this.props.isLocked}
pages={(this.props.isLocked) ? 0 : visiblePages} // Total number of pages, don't show 10000+ records in table
loading={this.state.loading}
Expand Down
5 changes: 3 additions & 2 deletions src/GuppyDataExplorer/ExplorerVisualization/index.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react';
import React, { useEffect } from 'react';
import PropTypes from 'prop-types';
import GuppyWrapper from '@gen3/guppy/dist/components/GuppyWrapper';
import ConnectedFilter from '@gen3/guppy/dist/components/ConnectedFilter';
Expand All @@ -8,7 +8,7 @@ import { components } from '../../params';
import { guppyUrl, tierAccessLevel, tierAccessLimit } from '../../localconf';
import DataSummaryCardGroup from '../../components/cards/DataSummaryCardGroup';
import ExplorerHeatMap from '../ExplorerHeatMap';
import ExplorerTable from '../ExplorerTable';
import ExplorerTable, {DicomHasImageLinkObserver} from '../ExplorerTable';
import ReduxExplorerButtonGroup from '../ExplorerButtonGroup/ReduxExplorerButtonGroup';
import {
TableConfigType,
Expand All @@ -20,6 +20,7 @@ import { checkForAnySelectedUnaccessibleField } from '../GuppyDataExplorerHelper
import './ExplorerVisualization.css';
import { labelToPlural } from '../utils';


class ExplorerVisualization extends React.Component {
constructor(props) {
super(props);
Expand Down