Skip to content

Commit

Permalink
added clickable icon to open the primary viewer directly from the stu…
Browse files Browse the repository at this point in the history
…dy list
  • Loading branch information
amazy committed Sep 11, 2024
1 parent a595386 commit 9b1d381
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 6 deletions.
24 changes: 21 additions & 3 deletions WebApplication/src/components/StudyItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import api from "../orthancApi";
import dateHelpers from "../helpers/date-helpers"
import SourceType from '../helpers/source-type';
import resourceHelpers from "../helpers/resource-helpers";
import TokenLinkButton from "./TokenLinkButton.vue";
export default {
props: ["studyId"],
Expand Down Expand Up @@ -135,22 +136,35 @@ export default {
} else {
return seriesCount;
}
},
hasPrimaryViewerIcon() {
return this.studiesSourceType == SourceType.LOCAL_ORTHANC;
},
primaryViewerUrl() {
return resourceHelpers.getPrimaryViewerUrl("study", this.study.ID, this.study.MainDicomTags.StudyInstanceUID);
}
},
components: { SeriesList, StudyDetails }
components: { SeriesList, StudyDetails, TokenLinkButton }
}
</script>


<template>
<tbody>
<tr v-if="loaded" :class="{ 'study-row-collapsed': !expanded, 'study-row-expanded': expanded, 'study-row-show-labels': showLabels }">
<tr v-if="loaded" :class="{ 'study-row-collapsed': !expanded, 'study-row-expanded': expanded, 'study-row-show-labels': showLabels }" @dblclick="doubleClicked">
<td>
<div class="form-check">
<input class="form-check-input" type="checkbox" v-model="selected" @click="clickedSelect">
</div>
</td>
<td v-if="hasPrimaryViewerIcon" class="td-viewer-icon">
<TokenLinkButton v-if="primaryViewerUrl"
level="study" :linkUrl="primaryViewerUrl"
:resourcesOrthancId="study.ID" linkType="icon"
iconClass="bi bi-eye-fill"
:tokenType="'viewer-instant-link'" :opensInNewTab="true">
</TokenLinkButton>
</td>
<td v-for="columnTag in uiOptions.StudyListColumns" :key="columnTag" class="cut-text"
:class="{ 'text-center': columnTag in ['modalities', 'seriesCount', 'instancesCount', 'seriesAndInstancesCount'] }" data-bs-toggle="collapse"
v-bind:data-bs-target="'#study-details-' + this.studyId">
Expand Down Expand Up @@ -259,4 +273,8 @@ export default {
border-top: 0px !important;
border-bottom: 0px !important;
}
.td-viewer-icon {
padding: 0; /* to maximize click space for the icon */
}
</style>
5 changes: 5 additions & 0 deletions WebApplication/src/components/StudyList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,9 @@ export default {
},
datePickerFormat() {
return this.uiOptions.DateFormat;
},
hasPrimaryViewerIcon() {
return this.sourceType == SourceType.LOCAL_ORTHANC;
}
},
watch: {
Expand Down Expand Up @@ -726,6 +729,7 @@ export default {
<table class="table table-responsive table-sm study-table table-borderless">
<thead class="study-table-header">
<th width="2%" scope="col" ></th>
<th v-if="hasPrimaryViewerIcon" width="3%" scope="col" ></th>
<th v-for="columnTag in uiOptions.StudyListColumns" :key="columnTag" data-bs-toggle="tooltip"
v-bind:title="columnTooltip(columnTag)" v-bind:width="columnWidth(columnTag)"
class="study-table-title">{{
Expand All @@ -739,6 +743,7 @@ export default {
<i class="fa-regular fa-circle-xmark"></i>
</button>
</th>
<th v-if="hasPrimaryViewerIcon" scope="col" ></th>
<th v-for="columnTag in uiOptions.StudyListColumns" :key="columnTag">
<div v-if="columnTag == 'StudyDate'">
<Datepicker v-if="columnTag == 'StudyDate'" v-model="filterStudyDateForDatePicker"
Expand Down
36 changes: 34 additions & 2 deletions WebApplication/src/components/TokenLinkButton.vue
Original file line number Diff line number Diff line change
Expand Up @@ -77,26 +77,41 @@ export default {
isDropDownItem() {
return this.linkType == "dropdown-item";
},
isIcon() {
return this.linkType == "icon";
},
classes() {
if (this.disabled) {
return "btn-secondary disabled-link";
} else {
return "btn-secondary";
}
},
divClasses() {
if (this.linkType == "icon") {
return "div-icon"
} else {
return "";
}
}
},
components: {}
}
</script>

<template>
<div>
<div :class="divClasses">
<a v-if="isButton" class="btn btn-sm m-1" type="button"
data-bs-toggle="tooltip" :title="title" @click="clicked" :target="target" :href="linkUrl" :class="classes">
<i :class="iconClass"></i>
</a>
<a v-if="isDropDownItem" class="dropdown-item" :target="target" @click="clicked"
:href="linkUrl">{{ title }}</a>
:href="linkUrl">{{ title }}
</a>
<a v-if="isIcon" class="icon" :target="target" @click="clicked"
:href="linkUrl">
<i :class="iconClass" style="padding-top: 4px;"></i>
</a>
</div>
</template>

Expand All @@ -107,4 +122,21 @@ export default {
background-color: #6c757d;
opacity: 0.65;
}
.icon {
color: var(--bs-table-color);
width: 100%; /* increase the size of the clickable area */
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.div-icon {
width: 100%; /* increase the size of the clickable area */
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
</style>
40 changes: 39 additions & 1 deletion WebApplication/src/helpers/resource-helpers.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import store from "../store"
import api from "../orthancApi"

export default {
getResourceTitle(resourceType, patientMainDicomTags, studyMainDicomTags, seriesMainDicomTags, instanceTags) {
let title = [];
Expand Down Expand Up @@ -34,10 +37,45 @@ export default {
patientNameCapture : "([^\\^]+)\\^?([^\\^]+)?\\^?([^\\^]+)?\\^?([^\\^]+)?\\^?([^\\^]+)?",
patientNameFormatting : null,
formatPatientName(originalPatientName) {
if (this.patientNameFormatting) {
if (originalPatientName && this.patientNameFormatting && this.patientNameCapture) {
return originalPatientName.replace(new RegExp(this.patientNameCapture), this.patientNameFormatting);
} else {
return originalPatientName;
}
},

getPrimaryViewerUrl(level, orthancId, dicomId) {
if (store.state.configuration.uiOptions.ViewersOrdering.length > 0) {
return this.getViewerUrl(level, orthancId, dicomId, store.state.configuration.uiOptions.ViewersOrdering[0]);
}
return null;
},

getViewerUrl(level, orthancId, dicomId, viewer) {
if (viewer == 'osimis-web-viewer') {
return api.getOsimisViewerUrl(level, orthancId);
} else if (viewer == 'stone-webviewer') {
return api.getStoneViewerUrl(level, dicomId)
} else if (viewer == 'volview') {
return api.getVolViewUrl(level, orthancId);
} else if (viewer == 'ohif') {
if (store.state.configuration.ohifDataSource == 'dicom-web') {
return api.getOhifViewerUrlForDicomWeb('basic', dicomId);
} else {
return api.getOhifViewerUrlForDicomJson('basic', dicomId);
}
} else if (viewer == 'ohif-vr') {
return api.getOhifViewerUrl('vr');
} else if (viewer == 'ohif-tmtv') {
return api.getOhifViewerUrl('tmtv');
} else if (viewer == 'ohif-seg') {
return api.getOhifViewerUrl('seg');
} else if (viewer == 'ohif-micro') {
return api.getOhifViewerUrl('microscopy');
} else if (viewer == 'wsi') {
return api.getWsiViewerUrl(orthancId); // note: this must be a series ID !
} else if (viewer == 'meddream') {
return store.state.configuration.uiOptions.MedDreamViewerPublicRoot + "?study=" + dicomId;
}
}
}
1 change: 1 addition & 0 deletions release-notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ Pending changes in the mainline
===============================

Changes:
- Added a clickable icon to open the primary viewer without expanding the study.
- new configuration "CustomFavIconPath" to customize the FavIcon
- new configuration "CustomTitle" to customize the tab/window title
- new configurations to modify the PatientName display:
Expand Down

0 comments on commit 9b1d381

Please sign in to comment.