fix via view page
This commit is contained in:
@@ -34,9 +34,9 @@
|
||||
<article class="card border-secondary-subtle shadow-sm case-item"
|
||||
data-title="{{ case.title }}"
|
||||
data-case="{{ case.pk }}"
|
||||
data-casejson="{{ case.viva_details_json|escapejs }}"
|
||||
data-images="{{ case.series_images_nested_json|escapejs }}"
|
||||
data-viewerstate="{{ casedetail.default_viewerstate_string|escapejs }}">
|
||||
data-casejson="{{ case.viva_details_json|urlencode }}"
|
||||
data-images="{{ case.series_images_nested_json|urlencode }}"
|
||||
data-viewerstate="{{ casedetail.default_viewerstate_string|urlencode }}">
|
||||
<header class="card-header d-flex flex-wrap justify-content-between align-items-center gap-2">
|
||||
<div>
|
||||
<span class="badge bg-primary me-2">Case {{ forloop.counter }}</span>
|
||||
@@ -119,10 +119,10 @@
|
||||
data-displayset="{{ ds.pk }}"
|
||||
data-case="{{ case.pk }}"
|
||||
data-title="{{ ds.name }}"
|
||||
data-casejson="{{ case.viva_details_json|escapejs }}"
|
||||
data-images="{{ case.series_images_nested_json|escapejs }}"
|
||||
data-viewerstate="{{ ds.viewerstate_string|escapejs }}"
|
||||
data-annotations="{{ ds.annotations_string|escapejs }}">
|
||||
data-casejson="{{ case.viva_details_json|urlencode }}"
|
||||
data-images="{{ case.series_images_nested_json|urlencode }}"
|
||||
data-viewerstate="{{ ds.viewerstate_string|urlencode }}"
|
||||
data-annotations="{{ ds.annotations_string|urlencode }}">
|
||||
Load Display Set
|
||||
</button>
|
||||
<button class="edit-link-displayset btn btn-outline-warning btn-sm" style="display:none;">
|
||||
@@ -151,6 +151,7 @@
|
||||
<div class="card border-secondary-subtle shadow-sm">
|
||||
<div class="card-header"><h2 class="h5 mb-0">Current Case</h2></div>
|
||||
<div class="card-body" id="case-details">
|
||||
<div id="user-message" class="alert py-2" style="display:none;"></div>
|
||||
<div id="loading-case" class="alert alert-warning py-2" style="display:none;">Waiting for case to load in linked window.</div>
|
||||
<div id="current-case-title" class="mb-2">None</div>
|
||||
<div id="current-case-series" class="mb-2"></div>
|
||||
@@ -171,8 +172,42 @@
|
||||
<script type="text/javascript">
|
||||
var win2 = false;
|
||||
let editMode = false;
|
||||
let viewerConnected = false;
|
||||
|
||||
$(document).ready(function() {
|
||||
const showUserMessage = function(message, level = 'warning') {
|
||||
const $msg = $('#user-message');
|
||||
$msg
|
||||
.removeClass('alert-warning alert-danger alert-success alert-info')
|
||||
.addClass('alert-' + level)
|
||||
.text(message)
|
||||
.show();
|
||||
};
|
||||
|
||||
const clearUserMessage = function() {
|
||||
$('#user-message').hide().text('');
|
||||
};
|
||||
|
||||
const parseEncodedJson = function(raw, label) {
|
||||
if (!raw) {
|
||||
return {};
|
||||
}
|
||||
try {
|
||||
return JSON.parse(decodeURIComponent(raw));
|
||||
} catch (err) {
|
||||
throw new Error('Unable to parse ' + label + ' payload.');
|
||||
}
|
||||
};
|
||||
|
||||
const ensureViewerWindowReady = function() {
|
||||
if (!win2 || win2.closed) {
|
||||
showUserMessage('Viewer is not open. Click "Open Viewer Local" before loading a case or series.', 'warning');
|
||||
return false;
|
||||
}
|
||||
clearUserMessage();
|
||||
return true;
|
||||
};
|
||||
|
||||
// Edit mode toggle
|
||||
$('#toggle-edit-mode').click(function() {
|
||||
editMode = !editMode;
|
||||
@@ -196,8 +231,10 @@
|
||||
console.log("message received");
|
||||
console.log(event);
|
||||
if (event.data.type == "open-complete-local") {
|
||||
viewerConnected = true;
|
||||
$("#loading-case").hide();
|
||||
$("#open-viewer-local").removeClass("flash-button");
|
||||
clearUserMessage();
|
||||
//bc.postMessage({"type": "open-complete-local"});
|
||||
}
|
||||
};
|
||||
@@ -209,104 +246,127 @@
|
||||
$('#viewer').attr('src', url)
|
||||
});
|
||||
$('.open-case-local').click(function() {
|
||||
let c = this.closest(".case-item");
|
||||
console.log('clicked local', c)
|
||||
console.log('open local', c.dataset.case)
|
||||
casedetails = JSON.parse(c.dataset.casejson);
|
||||
let viewerstate = JSON.parse(c.dataset.viewerstate) || {};
|
||||
$('#loading-case').show()
|
||||
$("#open-viewer-local").addClass("flash-button");
|
||||
$('#current-case-title').html("<span class='title'>Case:</span> "+c.dataset.title);
|
||||
$("#current-case-history").html("<span class='title'>History:</span> "+casedetails['history']);
|
||||
$("#current-case-discussion").html("<span class='title'>Discussion:</span> "+casedetails['discussion']);
|
||||
$("#current-case-report").html("<span class='title'>Report:</span> "+casedetails['report']);
|
||||
|
||||
bc.postMessage({"type": "open",
|
||||
"case" : c.dataset.case, "images": c.dataset.images,
|
||||
"viewerstate": viewerstate
|
||||
});
|
||||
|
||||
// Inject the per-case question snippet into the current case panel
|
||||
try {
|
||||
if (!ensureViewerWindowReady()) {
|
||||
return;
|
||||
}
|
||||
let c = this.closest(".case-item");
|
||||
console.log('clicked local', c)
|
||||
console.log('open local', c.dataset.case)
|
||||
casedetails = parseEncodedJson(c.dataset.casejson, 'case details');
|
||||
let viewerstate = parseEncodedJson(c.dataset.viewerstate, 'viewer state') || {};
|
||||
let images = decodeURIComponent(c.dataset.images || '[]');
|
||||
$('#loading-case').show()
|
||||
$("#open-viewer-local").addClass("flash-button");
|
||||
$('#current-case-title').html("<span class='title'>Case:</span> "+c.dataset.title);
|
||||
$("#current-case-history").html("<span class='title'>History:</span> "+(casedetails['history'] || ''));
|
||||
$("#current-case-discussion").html("<span class='title'>Discussion:</span> "+(casedetails['discussion'] || ''));
|
||||
$("#current-case-report").html("<span class='title'>Report:</span> "+(casedetails['report'] || ''));
|
||||
|
||||
bc.postMessage({"type": "open",
|
||||
"case" : c.dataset.case, "images": images,
|
||||
"viewerstate": viewerstate
|
||||
});
|
||||
|
||||
// Inject the per-case question snippet into the current case panel
|
||||
var snippet = $(c).find('.question-block-snippet').html();
|
||||
$('#current-case-questions').html(snippet || '');
|
||||
} catch (e) {
|
||||
console.warn('Unable to inject question snippet', e);
|
||||
console.error('Case load failed', e);
|
||||
showUserMessage('Case load failed: ' + (e.message || 'Unexpected error while parsing case data.'), 'danger');
|
||||
}
|
||||
|
||||
});
|
||||
$('.open-displayset').click(function() {
|
||||
let c = this;
|
||||
console.log('clicked local', c)
|
||||
console.log('open local', c.dataset.case)
|
||||
casedetails = JSON.parse(c.dataset.casejson);
|
||||
let viewerstate = JSON.parse(c.dataset.viewerstate) || {};
|
||||
let annotations = JSON.parse(c.dataset.annotations) || {};
|
||||
$('#loading-case').show()
|
||||
$("#open-viewer-local").addClass("flash-button");
|
||||
$('#current-case-title').html("<span class='title'>Case:</span> "+c.dataset.title);
|
||||
$("#current-case-history").html("<span class='title'>History:</span> "+casedetails['history']);
|
||||
$("#current-case-discussion").html("<span class='title'>Discussion:</span> "+casedetails['discussion']);
|
||||
$("#current-case-report").html("<span class='title'>Report:</span> "+casedetails['report']);
|
||||
|
||||
bc.postMessage({"type": "open",
|
||||
"case" : c.dataset.case, "images": c.dataset.images,
|
||||
"viewerstate": viewerstate,
|
||||
"annotations": annotations
|
||||
});
|
||||
|
||||
// Inject the per-case question snippet
|
||||
try {
|
||||
if (!ensureViewerWindowReady()) {
|
||||
return;
|
||||
}
|
||||
let c = this;
|
||||
console.log('clicked local', c)
|
||||
console.log('open local', c.dataset.case)
|
||||
casedetails = parseEncodedJson(c.dataset.casejson, 'display set case details');
|
||||
let viewerstate = parseEncodedJson(c.dataset.viewerstate, 'display set viewer state') || {};
|
||||
let annotations = parseEncodedJson(c.dataset.annotations, 'display set annotations') || {};
|
||||
let images = decodeURIComponent(c.dataset.images || '[]');
|
||||
$('#loading-case').show()
|
||||
$("#open-viewer-local").addClass("flash-button");
|
||||
$('#current-case-title').html("<span class='title'>Case:</span> "+c.dataset.title);
|
||||
$("#current-case-history").html("<span class='title'>History:</span> "+(casedetails['history'] || ''));
|
||||
$("#current-case-discussion").html("<span class='title'>Discussion:</span> "+(casedetails['discussion'] || ''));
|
||||
$("#current-case-report").html("<span class='title'>Report:</span> "+(casedetails['report'] || ''));
|
||||
|
||||
bc.postMessage({"type": "open",
|
||||
"case" : c.dataset.case, "images": images,
|
||||
"viewerstate": viewerstate,
|
||||
"annotations": annotations
|
||||
});
|
||||
|
||||
// Inject the per-case question snippet
|
||||
var caseItem = $(this).closest('.case-item');
|
||||
var snippet = caseItem.find('.question-block-snippet').html();
|
||||
$('#current-case-questions').html(snippet || '');
|
||||
} catch (e) {
|
||||
console.warn('Unable to inject question snippet for displayset', e);
|
||||
console.error('Display set load failed', e);
|
||||
showUserMessage('Display set load failed: ' + (e.message || 'Unexpected error while parsing display set data.'), 'danger');
|
||||
}
|
||||
|
||||
});
|
||||
$('.open-series-local').click(function() {
|
||||
let c = $(this).closest(".case-item")[0];
|
||||
let seriesNumber = $(this).data('series');
|
||||
let seriesPk = $(this).data('target');
|
||||
let caseDetails = JSON.parse(c.dataset.casejson);
|
||||
let images = JSON.parse(c.dataset.images)[seriesNumber - 1] || [];
|
||||
$('#loading-case').show();
|
||||
$("#open-viewer-local").addClass("flash-button");
|
||||
$('#current-case-title').html("<span class='title'>Case:</span> " + c.dataset.title);
|
||||
$('#current-case-series').html("<span class='title'>Series:</span> " + seriesNumber);
|
||||
$("#current-case-history").html("<span class='title'>History:</span> " + caseDetails['history']);
|
||||
$("#current-case-discussion").html("<span class='title'>Discussion:</span> " + caseDetails['discussion']);
|
||||
$("#current-case-report").html("<span class='title'>Report:</span> " + caseDetails['report']);
|
||||
|
||||
// Send only the images for this series
|
||||
bc.postMessage({
|
||||
"type": "open",
|
||||
"case": c.dataset.case,
|
||||
"series": seriesPk,
|
||||
"images": JSON.stringify(images),
|
||||
});
|
||||
|
||||
// Inject the per-case question snippet
|
||||
try {
|
||||
if (!ensureViewerWindowReady()) {
|
||||
return;
|
||||
}
|
||||
let c = $(this).closest(".case-item")[0];
|
||||
let seriesNumber = $(this).data('series');
|
||||
let seriesPk = $(this).data('target');
|
||||
let caseDetails = parseEncodedJson(c.dataset.casejson, 'series case details');
|
||||
let allSeriesImages = parseEncodedJson(c.dataset.images, 'series images');
|
||||
let images = allSeriesImages[seriesNumber - 1] || [];
|
||||
$('#loading-case').show();
|
||||
$("#open-viewer-local").addClass("flash-button");
|
||||
$('#current-case-title').html("<span class='title'>Case:</span> " + c.dataset.title);
|
||||
$('#current-case-series').html("<span class='title'>Series:</span> " + seriesNumber);
|
||||
$("#current-case-history").html("<span class='title'>History:</span> " + (caseDetails['history'] || ''));
|
||||
$("#current-case-discussion").html("<span class='title'>Discussion:</span> " + (caseDetails['discussion'] || ''));
|
||||
$("#current-case-report").html("<span class='title'>Report:</span> " + (caseDetails['report'] || ''));
|
||||
|
||||
// Send only the images for this series
|
||||
bc.postMessage({
|
||||
"type": "open",
|
||||
"case": c.dataset.case,
|
||||
"series": seriesPk,
|
||||
"images": JSON.stringify(images),
|
||||
});
|
||||
|
||||
// Inject the per-case question snippet
|
||||
var snippet = $(c).find('.question-block-snippet').html();
|
||||
$('#current-case-questions').html(snippet || '');
|
||||
} catch (e) {
|
||||
console.warn('Unable to inject question snippet for series', e);
|
||||
console.error('Series load failed', e);
|
||||
showUserMessage('Series load failed: ' + (e.message || 'Unexpected error while parsing series data.'), 'danger');
|
||||
}
|
||||
});
|
||||
// Load resource into linked viewer
|
||||
$('.open-resource').click(function() {
|
||||
var src = $(this).data('src');
|
||||
var title = $(this).data('title') || 'Resource';
|
||||
$('#loading-case').show();
|
||||
$("#open-viewer-local").addClass("flash-button");
|
||||
$('#current-case-title').html("<span class='title'>Resource:</span> "+title);
|
||||
$('#current-case-history').html('');
|
||||
$('#current-case-discussion').html('');
|
||||
$('#current-case-report').html('');
|
||||
try {
|
||||
if (!ensureViewerWindowReady()) {
|
||||
return;
|
||||
}
|
||||
var src = $(this).data('src');
|
||||
var title = $(this).data('title') || 'Resource';
|
||||
$('#loading-case').show();
|
||||
$("#open-viewer-local").addClass("flash-button");
|
||||
$('#current-case-title').html("<span class='title'>Resource:</span> "+title);
|
||||
$('#current-case-history').html('');
|
||||
$('#current-case-discussion').html('');
|
||||
$('#current-case-report').html('');
|
||||
|
||||
bc.postMessage({"type": "open", "url": src});
|
||||
bc.postMessage({"type": "open", "url": src});
|
||||
} catch (e) {
|
||||
console.error('Resource load failed', e);
|
||||
showUserMessage('Resource load failed: ' + (e.message || 'Unexpected error.'), 'danger');
|
||||
}
|
||||
});
|
||||
$('.send-message').click(function() {
|
||||
var url = $(this).data('target');
|
||||
@@ -314,7 +374,13 @@
|
||||
})
|
||||
$('#open-viewer-local').click(function() {
|
||||
$("#open-viewer-local").removeClass("flash-button");
|
||||
openSecondaryWindow("{% url 'atlas:collection_viewer_local_progressive' %}");
|
||||
viewerConnected = false;
|
||||
const opened = openSecondaryWindow("{% url 'atlas:collection_viewer_local_progressive' %}");
|
||||
if (!opened) {
|
||||
showUserMessage('Unable to open viewer window. Please allow pop-ups for this site and try again.', 'danger');
|
||||
return;
|
||||
}
|
||||
showUserMessage('Viewer window opened. Load a case to begin. If nothing appears, check pop-up blockers and re-open the viewer.', 'info');
|
||||
//bc.postMessage(url);
|
||||
})
|
||||
$('#view-series').click(function() {
|
||||
@@ -326,11 +392,12 @@
|
||||
});
|
||||
function openSecondaryWindow(url) {
|
||||
//return win2 = window.open(url,'secondary','width=300,height=100');
|
||||
return win2 = window.open(
|
||||
win2 = window.open(
|
||||
url,
|
||||
'secondary',
|
||||
'toolbar=no,location=no,status=no,menubar=no,scrollbars=yes,resizable=yes,width=1200,height=800'
|
||||
);
|
||||
return win2;
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
@@ -61,16 +61,16 @@
|
||||
<p>To do so you will have to first export the files from the PACs system.</p>
|
||||
<p>Once uploaded the series will be available to be imported into cases
|
||||
|
||||
<h2>Cases</h2>
|
||||
<h3>Ordering dicoms within a series</h3>
|
||||
<p>Depending on how dicoms are exported images within a stack may appear in the wrong order. This is apparent when viewing the stacks/series as jumping of images.</p>
|
||||
<p>In most cases this can be fixed by re-ordering based on series metadata (usually slice location).</p>
|
||||
<p>It is possible to reorder all the stacks in a case at once, or to reorder individual stacks.</p>
|
||||
<h4>Reorder all stacks in a case</h4>
|
||||
<p>Go to the case page, click "Manage Series" then "Order dicoms by slice location". This will reorder all the stacks in the case based on slice location.</p>
|
||||
<h4>Reorder individual stacks</h4>
|
||||
<p>More ordering options (if the above does not work) are available on the series page.</p>
|
||||
<p>These can be accessed by opening the "Series info" section and selecting the appropriate button.</p>
|
||||
<h2>Cases</h2>
|
||||
<h3>Ordering dicoms within a series</h3>
|
||||
<p>Depending on how dicoms are exported images within a stack may appear in the wrong order. This is apparent when viewing the stacks/series as jumping of images.</p>
|
||||
<p>In most cases this can be fixed by re-ordering based on series metadata (usually slice location).</p>
|
||||
<p>It is possible to reorder all the stacks in a case at once, or to reorder individual stacks.</p>
|
||||
<h4>Reorder all stacks in a case</h4>
|
||||
<p>Go to the case page, click "Manage Series" then "Order dicoms by slice location". This will reorder all the stacks in the case based on slice location.</p>
|
||||
<h4>Reorder individual stacks</h4>
|
||||
<p>More ordering options (if the above does not work) are available on the series page.</p>
|
||||
<p>These can be accessed by opening the "Series info" section and selecting the appropriate button.</p>
|
||||
|
||||
|
||||
|
||||
|
||||
+65
-65
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user