Merge branch 'feat/v2-main' of github.com:OHIF/Viewers into feat/v2-main

This commit is contained in:
dannyrb 2020-08-20 12:29:58 -04:00
commit ec9b2e1dd0
4 changed files with 69 additions and 24 deletions

View File

@ -66,7 +66,7 @@ function createDicomWebApi(dicomWebConfig) {
query: {
studies: {
mapParams: mapParams.bind(),
search: async function(origParams) {
search: async function (origParams) {
const { studyInstanceUid, seriesInstanceUid, ...mappedParams } =
mapParams(origParams, {
supportsFuzzyMatching,
@ -86,7 +86,7 @@ function createDicomWebApi(dicomWebConfig) {
},
series: {
// mapParams: mapParams.bind(),
search: async function(studyInstanceUid) {
search: async function (studyInstanceUid) {
const results = await seriesInStudy(
qidoDicomWebClient,
studyInstanceUid

View File

@ -2,14 +2,16 @@ import React from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';
const stickyClasses = 'sticky top-0 z-10';
const stickyClasses = 'sticky top-0';
const notStickyClasses = 'relative';
const NavBar = ({ className, children, isSticky }) => {
return (
<div
className={classnames(
'flex flex-row items-center bg-secondary-dark px-3 py-1 min-h-16 border-b-4 border-black',
'flex flex-row items-center bg-secondary-dark px-3 py-1 min-h-16 border-b-4 border-black z-20',
isSticky && stickyClasses,
!isSticky && notStickyClasses,
className
)}
>

View File

@ -6,6 +6,9 @@ import { MODULE_TYPES } from '@ohif/core';
import { useAppConfig } from '@state';
import { extensionManager } from '../App.jsx';
let cacheMap = {};
let total = {};
/**
* Uses route properties to determine the data source that should be passed
* to the child layout template. In some instances, initiates requests and
@ -17,8 +20,6 @@ import { extensionManager } from '../App.jsx';
function DataSourceWrapper(props) {
const [appConfig] = useAppConfig();
const { children: LayoutTemplate, history, ...rest } = props;
const queryFilterValues = _getQueryFilterValues(history.location.search);
// TODO: Fetch by type, name, etc?
const dataSourceModules = extensionManager.modules[MODULE_TYPES.DATA_SOURCE];
// TODO: Good usecase for flatmap?
@ -46,17 +47,61 @@ function DataSourceWrapper(props) {
// studies.processResults --> <LayoutTemplate studies={} />
// But only for LayoutTemplate type of 'list'?
// Or no data fetching here, and just hand down my source
const [data, setData] = useState([]);
const STUDIES_LIMIT = 101;
const [data, setData] = useState({ studies: [], total: 0 });
const [isLoading, setIsLoading] = useState(false);
useEffect(() => {
// 204: no content
async function getData() {
setIsLoading(true);
const searchResults = await dataSource.query.studies.search(
queryFilterValues
);
setData(searchResults);
const limit = STUDIES_LIMIT - 1;
const queryFilterValues = _getQueryFilterValues(history.location.search);
const { resultsPerPage = 25, pageNumber = 1 } = queryFilterValues;
const reachedLimits = parseInt((resultsPerPage * pageNumber) / STUDIES_LIMIT);
const cacheKey = `${pageNumber}-${resultsPerPage}`;
const getFromCache = async ({ cacheKey, pageNumber, resultsPerPage, limit, options }) => {
const pagesAmount = limit / resultsPerPage;
const pageToRequest = parseInt((resultsPerPage * pageNumber) / STUDIES_LIMIT);
let length = 0;
if (!cacheMap[cacheKey]) {
length = pageToRequest > 0 ? (pageToRequest * STUDIES_LIMIT) : 1;
const studiesPromise = dataSource.query.studies.search(options);
for (let pageNum = 0; pageNum < pagesAmount; pageNum++) {
const currentPageNumber = (pageNum + 1) + (pageToRequest * pagesAmount);
cacheMap[`${currentPageNumber}-${resultsPerPage}`] = studiesPromise.then(function (results) {
const slicedResult = results.slice((pageNum * resultsPerPage), ((pageNum + 1) * resultsPerPage));
length += slicedResult.length;
return slicedResult;
});
}
}
const cache = await cacheMap[cacheKey];
return { cache, length, index: pageToRequest };
};
const { cache: studies, index, length } = await getFromCache({
cacheKey,
pageNumber,
resultsPerPage,
limit,
options: { ...queryFilterValues, ...{ offset: reachedLimits * limit } }
});
const totalKey = `${resultsPerPage}-${index}`;
total[totalKey] = total[totalKey] ? total[totalKey] + length : length;
const totals = Object.keys(total).map(key => total[key]);
const biggestIndex = totals.indexOf(Math.max(...totals));
const biggestKey = Object.keys(total)[biggestIndex];
const biggestTotal = total[biggestKey];
setIsLoading(false);
setData({ studies, total: biggestTotal });
}
try {
@ -73,7 +118,8 @@ function DataSourceWrapper(props) {
<LayoutTemplate
{...rest}
history={history}
data={data}
data={data.studies}
dataTotal={data.total}
dataSource={dataSource}
isLoadingData={isLoading}
/>
@ -106,6 +152,7 @@ function _getQueryFilterValues(query) {
startDate: query.get('startDate'),
endDate: query.get('endDate'),
page: _tryParseInt(query.get('page'), undefined),
pageNumber: _tryParseInt(query.get('pageNumber'), undefined),
resultsPerPage: _tryParseInt(query.get('resultsPerPage'), undefined),
// Rarely supported server-side
sortBy: query.get('sortBy'),

View File

@ -33,15 +33,15 @@ const seriesInStudiesMap = new Map();
* TODO:
* - debounce `setFilterValues` (150ms?)
*/
function WorkList({ history, data: studies, isLoadingData, dataSource, hotkeysManager }) {
function WorkList({ history, data: studies, dataTotal: studiesTotal, isLoadingData, dataSource, hotkeysManager }) {
const { hotkeyDefinitions, hotkeyDefaults } = hotkeysManager;
const { show, hide } = useModal();
const { t } = useTranslation();
// ~ Modes
const [appConfig] = useAppConfig();
// ~ Filters
const query = useQuery();
const STUDIES_LIMIT = 101;
const queryFilterValues = _getQueryFilterValues(query);
const [filterValues, _setFilterValues] = useState({
...defaultFilterValues,
@ -64,12 +64,9 @@ function WorkList({ history, data: studies, isLoadingData, dataSource, hotkeysMa
const noSortApplied = sortBy === '' || !sortBy;
const sortModifier = sortDirection === 'descending' ? 1 : -1;
if (noSortApplied && studies.length < 101) {
if (noSortApplied && studiesTotal < STUDIES_LIMIT) {
const ascendingSortModifier = -1;
defaultSortValues = {
sortBy: 'studyDate',
sortDirection: 'ascending',
};
defaultSortValues = { sortBy: 'studyDate', sortDirection: 'ascending' };
return _sortStringDates(s1, s2, ascendingSortModifier);
} else if (noSortApplied) {
return 0;
@ -96,7 +93,7 @@ function WorkList({ history, data: studies, isLoadingData, dataSource, hotkeysMa
// ~ Rows & Studies
const [expandedRows, setExpandedRows] = useState([]);
const [studiesWithSeriesData, setStudiesWithSeriesData] = useState([]);
const numOfStudies = studies.length;
const numOfStudies = studiesTotal;
const totalPages = Math.floor(numOfStudies / resultsPerPage) + 1;
const setFilterValues = val => {
@ -111,6 +108,7 @@ function WorkList({ history, data: studies, isLoadingData, dataSource, hotkeysMa
if (newPageNumber > totalPages) {
return;
}
setFilterValues({ ...filterValues, pageNumber: newPageNumber });
};
@ -135,6 +133,7 @@ function WorkList({ history, data: studies, isLoadingData, dataSource, hotkeysMa
if (!debouncedFilterValues) {
return;
}
const queryString = {};
Object.keys(defaultFilterValues).forEach(key => {
const defaultValue = defaultFilterValues[key];
@ -389,10 +388,7 @@ function WorkList({ history, data: studies, isLoadingData, dataSource, hotkeysMa
{hasStudies ? (
<>
<StudyListTable
tableDataSource={tableDataSource.slice(
(pageNumber - 1) * resultsPerPage,
(pageNumber - 1) * resultsPerPage + resultsPerPage
)}
tableDataSource={tableDataSource}
numOfStudies={numOfStudies}
filtersMeta={filtersMeta}
/>