@@ -348,19 +341,19 @@ function TableRow(props) {
style={{
display: 'flex',
flexDirection: 'column',
- minWidth: '80px',
+ maxWidth: '80px',
+ width: '80px',
}}
>
- {modalities}
+ {modalities || `(${t('Empty')})`}
{studyDate}
@@ -381,7 +374,7 @@ function TableRow(props) {
TableRow.propTypes = {
accessionNumber: PropTypes.string.isRequired,
isHighlighted: PropTypes.bool,
- modalities: PropTypes.string.isRequired,
+ modalities: PropTypes.string,
patientId: PropTypes.string.isRequired,
patientName: PropTypes.string.isRequired,
studyDate: PropTypes.string.isRequired,
diff --git a/platform/ui/src/components/studyList/StudyList.styl b/platform/ui/src/components/studyList/StudyList.styl
index 0f72e91a0..807304bdf 100644
--- a/platform/ui/src/components/studyList/StudyList.styl
+++ b/platform/ui/src/components/studyList/StudyList.styl
@@ -113,11 +113,18 @@ table.table
border-spacing: 0;
border-collapse: collapse;
table-layout: fixed;
+ color: var(--table-text-primary-color)
+ font-weight: 300
> tbody tr
padding: 5px
background-color: black
+ > tbody td
+ padding: $body-cell-top-bottom-padding 8px;
+ height: $body-cell-height
+ word-wrap: break-word;
+
/* Striped Variant */
&.table--striped > tbody tr:nth-child(even)
background-color: var(--ui-gray-darker)
@@ -130,6 +137,9 @@ table.table
&:hover, &:active, &.active
background-color: var(--ui-gray-darker)
+ .empty-value
+ color: var(--ui-gray-light)
+
.study-list-container > table.table > tr
height: 20px
@@ -146,18 +156,14 @@ table.table
text-align: left;
border-top: 0;
-.study-list-container > table.table > tbody > tr > td
- padding: $body-cell-top-bottom-padding 8px;
- height: $body-cell-height
- color: var(--table-text-primary-color)
- font-weight: 300
- word-wrap: break-word;
-
- &.emptyCell
- color: var(--ui-gray-light)
-
.study-list-container > table.table > thead > tr > th.studyDate
min-width: 230px
+.study-list-container > table.table .modalities
+ font-weight: 500;
+ min-height: 20px;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ overflow: hidden;
.study-list-container
.filters
diff --git a/platform/ui/src/components/studyList/internal/bkdr-hash.js b/platform/ui/src/components/studyList/internal/bkdr-hash.js
deleted file mode 100644
index 888f7aeab..000000000
--- a/platform/ui/src/components/studyList/internal/bkdr-hash.js
+++ /dev/null
@@ -1,24 +0,0 @@
-/**
- * BKDR Hash (modified version)
- *
- * @param {String} str string to hash
- * @returns {Number}
- */
-function BKDRHash(str) {
- const seed = 131;
- const seed2 = 137;
- let hash = 0;
- // make hash more sensitive for short string like 'a', 'b', 'c'
- str += 'x';
- // Note: Number.MAX_SAFE_INTEGER equals 9007199254740991
- var MAX_SAFE_INTEGER = parseInt(9007199254740991 / seed2);
- for (var i = 0; i < str.length; i++) {
- if (hash > MAX_SAFE_INTEGER) {
- hash = parseInt(hash / seed2);
- }
- hash = hash * seed + str.charCodeAt(i);
- }
- return hash;
-}
-
-export default BKDRHash;
diff --git a/platform/ui/src/components/studyList/internal/color-hash.js b/platform/ui/src/components/studyList/internal/color-hash.js
deleted file mode 100644
index fc2eea7dd..000000000
--- a/platform/ui/src/components/studyList/internal/color-hash.js
+++ /dev/null
@@ -1,145 +0,0 @@
-import BKDRHash from './bkdr-hash';
-
-/**
- * Convert RGB Array to HEX
- *
- * @param {Array} RGBArray - [R, G, B]
- * @returns {String} 6 digits hex starting with #
- */
-function RGB2HEX(RGBArray) {
- let hex = '#';
- RGBArray.forEach(function(value) {
- if (value < 16) {
- hex += 0;
- }
- hex += value.toString(16);
- });
- return hex;
-}
-
-/**
- * Convert HSL to RGB
- *
- * @see {@link http://zh.wikipedia.org/wiki/HSL和HSV色彩空间} for further information.
- * @param {Number} H Hue ∈ [0, 360)
- * @param {Number} S Saturation ∈ [0, 1]
- * @param {Number} L Lightness ∈ [0, 1]
- * @returns {Array} R, G, B ∈ [0, 255]
- */
-function HSL2RGB(H, S, L) {
- H /= 360;
-
- const q = L < 0.5 ? L * (1 + S) : L + S - L * S;
- const p = 2 * L - q;
-
- return [H + 1 / 3, H, H - 1 / 3].map(function(color) {
- if (color < 0) {
- color++;
- }
- if (color > 1) {
- color--;
- }
- if (color < 1 / 6) {
- color = p + (q - p) * 6 * color;
- } else if (color < 0.5) {
- color = q;
- } else if (color < 2 / 3) {
- color = p + (q - p) * 6 * (2 / 3 - color);
- } else {
- color = p;
- }
- return Math.round(color * 255);
- });
-}
-
-function isArray(o) {
- return Object.prototype.toString.call(o) === '[object Array]';
-}
-
-/**
- * Color Hash Class
- *
- * @class
- */
-const ColorHash = function(options = {}) {
- const LS = [options.lightness, options.saturation].map(function(param) {
- param = param || [0.35, 0.5, 0.65]; // note that 3 is a prime
- return isArray(param) ? param.concat() : [param];
- });
-
- this.L = LS[0];
- this.S = LS[1];
-
- if (typeof options.hue === 'number') {
- options.hue = { min: options.hue, max: options.hue };
- }
- if (typeof options.hue === 'object' && !isArray(options.hue)) {
- options.hue = [options.hue];
- }
- if (typeof options.hue === 'undefined') {
- options.hue = [];
- }
- this.hueRanges = options.hue.map(function(range) {
- return {
- min: typeof range.min === 'undefined' ? 0 : range.min,
- max: typeof range.max === 'undefined' ? 360 : range.max,
- };
- });
-
- this.hash = options.hash || BKDRHash;
-};
-
-/**
- * Returns the hash in [h, s, l].
- * Note that H ∈ [0, 360); S ∈ [0, 1]; L ∈ [0, 1];
- *
- * @param {String} str string to hash
- * @returns {Array} [h, s, l]
- */
-ColorHash.prototype.hsl = function(str) {
- var H, S, L;
- var hash = this.hash(str);
-
- if (this.hueRanges.length) {
- var range = this.hueRanges[hash % this.hueRanges.length];
- var hueResolution = 727; // note that 727 is a prime
- H =
- (((hash / this.hueRanges.length) % hueResolution) *
- (range.max - range.min)) /
- hueResolution +
- range.min;
- } else {
- H = hash % 359; // note that 359 is a prime
- }
- hash = parseInt(hash / 360);
- S = this.S[hash % this.S.length];
- hash = parseInt(hash / this.S.length);
- L = this.L[hash % this.L.length];
-
- return [H, S, L];
-};
-
-/**
- * Returns the hash in [r, g, b].
- * Note that R, G, B ∈ [0, 255]
- *
- * @param {String} str string to hash
- * @returns {Array} [r, g, b]
- */
-ColorHash.prototype.rgb = function(str) {
- var hsl = this.hsl(str);
- return HSL2RGB.apply(this, hsl);
-};
-
-/**
- * Returns the hash in hex
- *
- * @param {String} str string to hash
- * @returns {String} hex with #
- */
-ColorHash.prototype.hex = function(str) {
- var rgb = this.rgb(str);
- return RGB2HEX(rgb);
-};
-
-export default ColorHash;
diff --git a/platform/viewer/src/studylist/StudyListRoute.js b/platform/viewer/src/studylist/StudyListRoute.js
index 8e2c4eb2d..3218e7a26 100644
--- a/platform/viewer/src/studylist/StudyListRoute.js
+++ b/platform/viewer/src/studylist/StudyListRoute.js
@@ -77,39 +77,43 @@ function StudyListRoute(props) {
// Called when relevant state/props are updated
// Watches filters and sort, debounced
- useEffect(() => {
- const fetchStudies = async () => {
- try {
- setSearchStatus({ error: null, isSearchingForStudies: true });
+ useEffect(
+ () => {
+ const fetchStudies = async () => {
+ try {
+ setSearchStatus({ error: null, isSearchingForStudies: true });
- const response = await getStudyList(
- server,
- debouncedFilters,
- debouncedSort,
- rowsPerPage,
- pageNumber,
- displaySize
- );
+ const response = await getStudyList(
+ server,
+ debouncedFilters,
+ debouncedSort,
+ rowsPerPage,
+ pageNumber,
+ displaySize
+ );
- setStudies(response);
- setSearchStatus({ error: null, isSearchingForStudies: false });
- } catch (error) {
- console.warn(error);
- setSearchStatus({ error: true, isFetching: false });
+ setStudies(response);
+ setSearchStatus({ error: null, isSearchingForStudies: false });
+ } catch (error) {
+ console.warn(error);
+ setSearchStatus({ error: true, isFetching: false });
+ }
+ };
+
+ if (server) {
+ fetchStudies();
}
- };
-
- if (server) {
- fetchStudies();
- }
- }, [
- debouncedFilters,
- debouncedSort,
- rowsPerPage,
- pageNumber,
- displaySize,
- server,
- ]);
+ },
+ // TODO: Can we update studies directly?
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ [
+ debouncedFilters,
+ debouncedSort,
+ rowsPerPage,
+ pageNumber,
+ displaySize,
+ server,
+ ]);
// TODO: Update Server
// if (this.props.server !== prevProps.server) {
@@ -352,6 +356,9 @@ async function getStudyList(
// Only the fields we use
const mappedStudies = studies.map(study => {
+ const patientName =
+ typeof study.patientName === 'string' ? study.patientName : undefined;
+
return {
accessionNumber: study.accessionNumber, // "1"
modalities: study.modalities, // "SEG\\MR"
@@ -359,7 +366,7 @@ async function getStudyList(
// numberOfStudyRelatedSeries: "3"
// patientBirthdate: undefined
patientId: study.patientId, // "NOID"
- patientName: study.patientName, // "NAME^NONE"
+ patientName, // "NAME^NONE"
// patientSex: "M"
// referringPhysicianName: undefined
studyDate: study.studyDate, // "Jun 28, 2002"