Mercurial > hg > orthanc
comparison OrthancServer/OrthancExplorer/explorer.js @ 4044:d25f4c0fa160 framework
splitting code into OrthancFramework and OrthancServer
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Wed, 10 Jun 2020 20:30:34 +0200 |
parents | OrthancExplorer/explorer.js@6dba4fa8a6cb |
children | 4bb7522a63e0 |
comparison
equal
deleted
inserted
replaced
4043:6c6239aec462 | 4044:d25f4c0fa160 |
---|---|
1 // http://stackoverflow.com/questions/1663741/is-there-a-good-jquery-drag-and-drop-file-upload-plugin | |
2 | |
3 | |
4 // Forbid the access to IE | |
5 if ($.browser.msie) | |
6 { | |
7 alert("Please use Mozilla Firefox or Google Chrome. Microsoft Internet Explorer is not supported."); | |
8 } | |
9 | |
10 // http://jquerymobile.com/demos/1.1.0/docs/api/globalconfig.html | |
11 //$.mobile.ajaxEnabled = false; | |
12 //$.mobile.page.prototype.options.addBackBtn = true; | |
13 //$.mobile.defaultPageTransition = 'slide'; | |
14 | |
15 | |
16 var LIMIT_RESOURCES = 100; | |
17 | |
18 var currentPage = ''; | |
19 var currentUuid = ''; | |
20 | |
21 | |
22 function DeepCopy(obj) | |
23 { | |
24 return jQuery.extend(true, {}, obj); | |
25 } | |
26 | |
27 | |
28 function ChangePage(page, options) | |
29 { | |
30 var first = true; | |
31 var value; | |
32 | |
33 if (options) { | |
34 for (var key in options) { | |
35 value = options[key]; | |
36 if (first) { | |
37 page += '?'; | |
38 first = false; | |
39 } else { | |
40 page += '&'; | |
41 } | |
42 | |
43 page += key + '=' + value; | |
44 } | |
45 } | |
46 | |
47 window.location.replace('explorer.html#' + page); | |
48 /*$.mobile.changePage('#' + page, { | |
49 changeHash: true | |
50 });*/ | |
51 } | |
52 | |
53 | |
54 function Refresh() | |
55 { | |
56 if (currentPage == 'patient') | |
57 RefreshPatient(); | |
58 else if (currentPage == 'study') | |
59 RefreshStudy(); | |
60 else if (currentPage == 'series') | |
61 RefreshSeries(); | |
62 else if (currentPage == 'instance') | |
63 RefreshInstance(); | |
64 } | |
65 | |
66 | |
67 $(document).ready(function() { | |
68 var $tree = $('#dicom-tree'); | |
69 $tree.tree({ | |
70 autoEscape: false | |
71 }); | |
72 | |
73 $('#dicom-tree').bind( | |
74 'tree.click', | |
75 function(event) { | |
76 if (event.node.is_open) | |
77 $tree.tree('closeNode', event.node, true); | |
78 else | |
79 $tree.tree('openNode', event.node, true); | |
80 } | |
81 ); | |
82 | |
83 // Inject the template of the warning about insecure setup as the | |
84 // first child of each page | |
85 var insecure = $('#template-insecure').html(); | |
86 $('[data-role="page"]>[data-role="content"]').prepend(insecure); | |
87 | |
88 currentPage = $.mobile.pageData.active; | |
89 currentUuid = $.mobile.pageData.uuid; | |
90 if (!(typeof currentPage === 'undefined') && | |
91 !(typeof currentUuid === 'undefined') && | |
92 currentPage.length > 0 && | |
93 currentUuid.length > 0) | |
94 { | |
95 Refresh(); | |
96 } | |
97 }); | |
98 | |
99 function GetAuthorizationTokensFromUrl() { | |
100 var urlVariables = window.location.search.substring(1).split('&'); | |
101 var dict = {}; | |
102 | |
103 for (var i = 0; i < urlVariables.length; i++) { | |
104 var split = urlVariables[i].split('='); | |
105 | |
106 if (split.length == 2 && (split[0] == "token" || split[0] == "auth-token" || split[0] == "authorization")) { | |
107 dict[split[0]] = split[1]; | |
108 } | |
109 } | |
110 return dict; | |
111 }; | |
112 | |
113 var authorizationTokens = GetAuthorizationTokensFromUrl(); | |
114 | |
115 /* Copy the authoziation toekn from the url search parameters into HTTP headers in every request to the Rest API. | |
116 Thanks to this behaviour, you may specify a ?token=xxx in your url and this will be passed | |
117 as the "token" header in every request to the API allowing you to use the authorization plugin */ | |
118 $.ajaxSetup( | |
119 { | |
120 headers : authorizationTokens | |
121 } | |
122 ); | |
123 | |
124 | |
125 function SplitLongUid(s) | |
126 { | |
127 return '<span>' + s.substr(0, s.length / 2) + '</span> <span>' + s.substr(s.length / 2, s.length - s.length / 2) + '</span>'; | |
128 } | |
129 | |
130 | |
131 function ParseDicomDate(s) | |
132 { | |
133 y = parseInt(s.substr(0, 4), 10); | |
134 m = parseInt(s.substr(4, 2), 10) - 1; | |
135 d = parseInt(s.substr(6, 2), 10); | |
136 | |
137 if (y == null || m == null || d == null || | |
138 !isFinite(y) || !isFinite(m) || !isFinite(d)) | |
139 { | |
140 return null; | |
141 } | |
142 | |
143 if (y < 1900 || y > 2100 || | |
144 m < 0 || m >= 12 || | |
145 d <= 0 || d >= 32) | |
146 { | |
147 return null; | |
148 } | |
149 | |
150 return new Date(y, m, d); | |
151 } | |
152 | |
153 | |
154 function FormatDicomDate(s) | |
155 { | |
156 if (s == undefined) | |
157 return "No date"; | |
158 | |
159 var d = ParseDicomDate(s); | |
160 if (d == null) | |
161 return '?'; | |
162 else | |
163 return d.toString('dddd, MMMM d, yyyy'); | |
164 } | |
165 | |
166 function FormatFloatSequence(s) | |
167 { | |
168 if (s == undefined || s.length == 0) | |
169 return "-"; | |
170 | |
171 if (s.indexOf("\\") == -1) | |
172 return s; | |
173 | |
174 var oldValues = s.split("\\"); | |
175 var newValues = []; | |
176 for (var i = 0; i < oldValues.length; i++) | |
177 { | |
178 newValues.push(parseFloat(oldValues[i]).toFixed(3)); | |
179 } | |
180 return newValues.join("\\"); | |
181 } | |
182 | |
183 function Sort(arr, fieldExtractor, isInteger, reverse) | |
184 { | |
185 var defaultValue; | |
186 if (isInteger) | |
187 defaultValue = 0; | |
188 else | |
189 defaultValue = ''; | |
190 | |
191 arr.sort(function(a, b) { | |
192 var ta = fieldExtractor(a); | |
193 var tb = fieldExtractor(b); | |
194 var order; | |
195 | |
196 if (ta == undefined) | |
197 ta = defaultValue; | |
198 | |
199 if (tb == undefined) | |
200 tb = defaultValue; | |
201 | |
202 if (isInteger) | |
203 { | |
204 ta = parseInt(ta, 10); | |
205 tb = parseInt(tb, 10); | |
206 order = ta - tb; | |
207 } | |
208 else | |
209 { | |
210 if (ta < tb) | |
211 order = -1; | |
212 else if (ta > tb) | |
213 order = 1; | |
214 else | |
215 order = 0; | |
216 } | |
217 | |
218 if (reverse) | |
219 return -order; | |
220 else | |
221 return order; | |
222 }); | |
223 } | |
224 | |
225 | |
226 function SortOnDicomTag(arr, tag, isInteger, reverse) | |
227 { | |
228 return Sort(arr, function(a) { | |
229 return a.MainDicomTags[tag]; | |
230 }, isInteger, reverse); | |
231 } | |
232 | |
233 | |
234 | |
235 function GetResource(uri, callback) | |
236 { | |
237 $.ajax({ | |
238 url: '..' + uri, | |
239 dataType: 'json', | |
240 async: false, | |
241 cache: false, | |
242 success: function(s) { | |
243 callback(s); | |
244 } | |
245 }); | |
246 } | |
247 | |
248 | |
249 function CompleteFormatting(node, link, isReverse, count) | |
250 { | |
251 if (count != null) | |
252 { | |
253 node = node.add($('<span>') | |
254 .addClass('ui-li-count') | |
255 .text(count)); | |
256 } | |
257 | |
258 if (link != null) | |
259 { | |
260 node = $('<a>').attr('href', link).append(node); | |
261 | |
262 if (isReverse) | |
263 node.attr('data-direction', 'reverse') | |
264 } | |
265 | |
266 node = $('<li>').append(node); | |
267 | |
268 if (isReverse) | |
269 node.attr('data-icon', 'back'); | |
270 | |
271 return node; | |
272 } | |
273 | |
274 | |
275 function FormatMainDicomTags(target, tags, tagsToIgnore) | |
276 { | |
277 var v; | |
278 | |
279 for (var i in tags) | |
280 { | |
281 if (tagsToIgnore.indexOf(i) == -1) | |
282 { | |
283 v = tags[i]; | |
284 | |
285 if (i == "PatientBirthDate" || | |
286 i == "StudyDate" || | |
287 i == "SeriesDate") | |
288 { | |
289 v = FormatDicomDate(v); | |
290 } | |
291 else if (i == "DicomStudyInstanceUID" || | |
292 i == "DicomSeriesInstanceUID") | |
293 { | |
294 v = SplitLongUid(v); | |
295 } | |
296 else if (i == "ImagePositionPatient" || | |
297 i == "ImageOrientationPatient") | |
298 { | |
299 v = FormatFloatSequence(v); | |
300 } | |
301 | |
302 target.append($('<p>') | |
303 .text(i + ': ') | |
304 .append($('<strong>').text(v))); | |
305 } | |
306 } | |
307 } | |
308 | |
309 | |
310 function FormatPatient(patient, link, isReverse) | |
311 { | |
312 var node = $('<div>').append($('<h3>').text(patient.MainDicomTags.PatientName)); | |
313 | |
314 FormatMainDicomTags(node, patient.MainDicomTags, [ | |
315 "PatientName" | |
316 // "OtherPatientIDs" | |
317 ]); | |
318 | |
319 return CompleteFormatting(node, link, isReverse, patient.Studies.length); | |
320 } | |
321 | |
322 | |
323 | |
324 function FormatStudy(study, link, isReverse, includePatient) | |
325 { | |
326 var label; | |
327 var node; | |
328 | |
329 if (includePatient) { | |
330 label = study.Label; | |
331 } else { | |
332 label = study.MainDicomTags.StudyDescription; | |
333 } | |
334 | |
335 node = $('<div>').append($('<h3>').text(label)); | |
336 | |
337 if (includePatient) { | |
338 FormatMainDicomTags(node, study.PatientMainDicomTags, [ | |
339 'PatientName' | |
340 ]); | |
341 } | |
342 | |
343 FormatMainDicomTags(node, study.MainDicomTags, [ | |
344 'StudyDescription', | |
345 'StudyTime' | |
346 ]); | |
347 | |
348 return CompleteFormatting(node, link, isReverse, study.Series.length); | |
349 } | |
350 | |
351 | |
352 | |
353 function FormatSeries(series, link, isReverse) | |
354 { | |
355 var c; | |
356 var node; | |
357 | |
358 if (series.ExpectedNumberOfInstances == null || | |
359 series.Instances.length == series.ExpectedNumberOfInstances) | |
360 { | |
361 c = series.Instances.length; | |
362 } | |
363 else | |
364 { | |
365 c = series.Instances.length + '/' + series.ExpectedNumberOfInstances; | |
366 } | |
367 | |
368 node = $('<div>') | |
369 .append($('<h3>').text(series.MainDicomTags.SeriesDescription)) | |
370 .append($('<p>').append($('<em>') | |
371 .text('Status: ') | |
372 .append($('<strong>').text(series.Status)))); | |
373 | |
374 FormatMainDicomTags(node, series.MainDicomTags, [ | |
375 "SeriesDescription", | |
376 "SeriesTime", | |
377 "Manufacturer", | |
378 "ImagesInAcquisition", | |
379 "SeriesDate", | |
380 "ImageOrientationPatient" | |
381 ]); | |
382 | |
383 return CompleteFormatting(node, link, isReverse, c); | |
384 } | |
385 | |
386 | |
387 function FormatInstance(instance, link, isReverse) | |
388 { | |
389 var node = $('<div>').append($('<h3>').text('Instance: ' + instance.IndexInSeries)); | |
390 | |
391 FormatMainDicomTags(node, instance.MainDicomTags, [ | |
392 "AcquisitionNumber", | |
393 "InstanceNumber", | |
394 "InstanceCreationDate", | |
395 "InstanceCreationTime" | |
396 ]); | |
397 | |
398 return CompleteFormatting(node, link, isReverse); | |
399 } | |
400 | |
401 | |
402 $('[data-role="page"]').live('pagebeforeshow', function() { | |
403 $.ajax({ | |
404 url: '../system', | |
405 dataType: 'json', | |
406 async: false, | |
407 cache: false, | |
408 success: function(s) { | |
409 if (s.Name != "") { | |
410 $('.orthanc-name').html($('<a>') | |
411 .addClass('ui-link') | |
412 .attr('href', 'explorer.html') | |
413 .text(s.Name) | |
414 .append(' » ')); | |
415 } | |
416 | |
417 // New in Orthanc 1.5.8 | |
418 if ('IsHttpServerSecure' in s && | |
419 !s.IsHttpServerSecure) { | |
420 $('.warning-insecure').show(); | |
421 } else { | |
422 $('.warning-insecure').hide(); | |
423 } | |
424 } | |
425 }); | |
426 }); | |
427 | |
428 | |
429 | |
430 $('#lookup').live('pagebeforeshow', function() { | |
431 // NB: "GenerateDicomDate()" is defined in "query-retrieve.js" | |
432 var target = $('#lookup-study-date'); | |
433 $('option', target).remove(); | |
434 target.append($('<option>').attr('value', '').text('Any date')); | |
435 target.append($('<option>').attr('value', GenerateDicomDate(0)).text('Today')); | |
436 target.append($('<option>').attr('value', GenerateDicomDate(-1)).text('Yesterday')); | |
437 target.append($('<option>').attr('value', GenerateDicomDate(-7) + '-').text('Last 7 days')); | |
438 target.append($('<option>').attr('value', GenerateDicomDate(-31) + '-').text('Last 31 days')); | |
439 target.append($('<option>').attr('value', GenerateDicomDate(-31 * 3) + '-').text('Last 3 months')); | |
440 target.append($('<option>').attr('value', GenerateDicomDate(-365) + '-').text('Last year')); | |
441 target.selectmenu('refresh'); | |
442 | |
443 $('#lookup-result').hide(); | |
444 }); | |
445 | |
446 | |
447 $('#lookup-submit').live('click', function() { | |
448 var lookup; | |
449 | |
450 $('#lookup-result').hide(); | |
451 | |
452 lookup = { | |
453 'Level' : 'Study', | |
454 'Expand' : true, | |
455 'Limit' : LIMIT_RESOURCES + 1, | |
456 'Query' : { | |
457 'StudyDate' : $('#lookup-study-date').val() | |
458 } | |
459 }; | |
460 | |
461 $('#lookup-form input').each(function(index, input) { | |
462 if (input.value.length != 0) { | |
463 if (input.id == 'lookup-patient-id') { | |
464 lookup['Query']['PatientID'] = input.value; | |
465 } | |
466 else if (input.id == 'lookup-patient-name') { | |
467 lookup['Query']['PatientName'] = input.value; | |
468 } | |
469 else if (input.id == 'lookup-accession-number') { | |
470 lookup['Query']['AccessionNumber'] = input.value; | |
471 } | |
472 else if (input.id == 'lookup-study-description') { | |
473 lookup['Query']['StudyDescription'] = input.value; | |
474 } | |
475 else { | |
476 console.error('Unknown lookup field: ' + input.id); | |
477 } | |
478 } | |
479 }); | |
480 | |
481 $.ajax({ | |
482 url: '../tools/find', | |
483 type: 'POST', | |
484 data: JSON.stringify(lookup), | |
485 dataType: 'json', | |
486 async: false, | |
487 error: function() { | |
488 alert('Error during lookup'); | |
489 }, | |
490 success: function(studies) { | |
491 FormatListOfStudies('#lookup-result ul', '#lookup-alert', '#lookup-count', studies); | |
492 $('#lookup-result').show(); | |
493 } | |
494 }); | |
495 | |
496 return false; | |
497 }); | |
498 | |
499 | |
500 $('#find-patients').live('pagebeforeshow', function() { | |
501 GetResource('/patients?expand&since=0&limit=' + (LIMIT_RESOURCES + 1), function(patients) { | |
502 var target = $('#all-patients'); | |
503 var count, showAlert, p; | |
504 | |
505 | |
506 $('li', target).remove(); | |
507 | |
508 SortOnDicomTag(patients, 'PatientName', false, false); | |
509 | |
510 if (patients.length <= LIMIT_RESOURCES) { | |
511 count = patients.length; | |
512 showAlert = false; | |
513 } | |
514 else { | |
515 count = LIMIT_RESOURCES; | |
516 showAlert = true; | |
517 } | |
518 | |
519 for (var i = 0; i < count; i++) { | |
520 p = FormatPatient(patients[i], '#patient?uuid=' + patients[i].ID); | |
521 target.append(p); | |
522 } | |
523 | |
524 target.listview('refresh'); | |
525 | |
526 if (showAlert) { | |
527 $('#count-patients').text(LIMIT_RESOURCES); | |
528 $('#alert-patients').show(); | |
529 } else { | |
530 $('#alert-patients').hide(); | |
531 } | |
532 }); | |
533 }); | |
534 | |
535 | |
536 | |
537 function FormatListOfStudies(targetId, alertId, countId, studies) | |
538 { | |
539 var target = $(targetId); | |
540 var patient, study, s; | |
541 var count, showAlert; | |
542 | |
543 $('li', target).remove(); | |
544 | |
545 for (var i = 0; i < studies.length; i++) { | |
546 patient = studies[i].PatientMainDicomTags.PatientName; | |
547 study = studies[i].MainDicomTags.StudyDescription; | |
548 | |
549 s = ""; | |
550 if (typeof patient === 'string') { | |
551 s = patient; | |
552 } | |
553 | |
554 if (typeof study === 'string') { | |
555 if (s.length > 0) { | |
556 s += ' - '; | |
557 } | |
558 | |
559 s += study; | |
560 } | |
561 | |
562 studies[i]['Label'] = s; | |
563 } | |
564 | |
565 Sort(studies, function(a) { return a.Label }, false, false); | |
566 | |
567 if (studies.length <= LIMIT_RESOURCES) { | |
568 count = studies.length; | |
569 showAlert = false; | |
570 } | |
571 else { | |
572 count = LIMIT_RESOURCES; | |
573 showAlert = true; | |
574 } | |
575 | |
576 for (var i = 0; i < count; i++) { | |
577 s = FormatStudy(studies[i], '#study?uuid=' + studies[i].ID, false, true); | |
578 target.append(s); | |
579 } | |
580 | |
581 target.listview('refresh'); | |
582 | |
583 if (showAlert) { | |
584 $(countId).text(LIMIT_RESOURCES); | |
585 $(alertId).show(); | |
586 } else { | |
587 $(alertId).hide(); | |
588 } | |
589 } | |
590 | |
591 | |
592 $('#find-studies').live('pagebeforeshow', function() { | |
593 GetResource('/studies?expand&since=0&limit=' + (LIMIT_RESOURCES + 1), function(studies) { | |
594 FormatListOfStudies('#all-studies', '#alert-studies', '#count-studies', studies); | |
595 }); | |
596 }); | |
597 | |
598 | |
599 | |
600 function SetupAnonymizedOrModifiedFrom(buttonSelector, resource, resourceType, field) | |
601 { | |
602 if (field in resource) | |
603 { | |
604 $(buttonSelector).closest('li').show(); | |
605 $(buttonSelector).click(function(e) { | |
606 window.location.assign('explorer.html#' + resourceType + '?uuid=' + resource[field]); | |
607 }); | |
608 } | |
609 else | |
610 { | |
611 $(buttonSelector).closest('li').hide(); | |
612 } | |
613 } | |
614 | |
615 | |
616 | |
617 function RefreshPatient() | |
618 { | |
619 var pageData, target, v; | |
620 | |
621 if ($.mobile.pageData) { | |
622 pageData = DeepCopy($.mobile.pageData); | |
623 | |
624 GetResource('/patients/' + pageData.uuid, function(patient) { | |
625 GetResource('/patients/' + pageData.uuid + '/studies', function(studies) { | |
626 SortOnDicomTag(studies, 'StudyDate', false, true); | |
627 | |
628 $('#patient-info li').remove(); | |
629 $('#patient-info') | |
630 .append('<li data-role="list-divider">Patient</li>') | |
631 .append(FormatPatient(patient)) | |
632 .listview('refresh'); | |
633 | |
634 target = $('#list-studies'); | |
635 $('li', target).remove(); | |
636 | |
637 for (var i = 0; i < studies.length; i++) { | |
638 if (i == 0 || studies[i].MainDicomTags.StudyDate != studies[i - 1].MainDicomTags.StudyDate) | |
639 { | |
640 target.append($('<li>') | |
641 .attr('data-role', 'list-divider') | |
642 .text(FormatDicomDate(studies[i].MainDicomTags.StudyDate))); | |
643 } | |
644 | |
645 target.append(FormatStudy(studies[i], '#study?uuid=' + studies[i].ID)); | |
646 } | |
647 | |
648 SetupAnonymizedOrModifiedFrom('#patient-anonymized-from', patient, 'patient', 'AnonymizedFrom'); | |
649 SetupAnonymizedOrModifiedFrom('#patient-modified-from', patient, 'patient', 'ModifiedFrom'); | |
650 | |
651 target.listview('refresh'); | |
652 | |
653 // Check whether this patient is protected | |
654 $.ajax({ | |
655 url: '../patients/' + pageData.uuid + '/protected', | |
656 type: 'GET', | |
657 dataType: 'text', | |
658 async: false, | |
659 cache: false, | |
660 success: function (s) { | |
661 v = (s == '1') ? 'on' : 'off'; | |
662 $('#protection').val(v).slider('refresh'); | |
663 } | |
664 }); | |
665 | |
666 currentPage = 'patient'; | |
667 currentUuid = pageData.uuid; | |
668 }); | |
669 }); | |
670 } | |
671 } | |
672 | |
673 | |
674 function RefreshStudy() | |
675 { | |
676 var pageData, target; | |
677 | |
678 if ($.mobile.pageData) { | |
679 pageData = DeepCopy($.mobile.pageData); | |
680 | |
681 GetResource('/studies/' + pageData.uuid, function(study) { | |
682 GetResource('/patients/' + study.ParentPatient, function(patient) { | |
683 GetResource('/studies/' + pageData.uuid + '/series', function(series) { | |
684 SortOnDicomTag(series, 'SeriesDate', false, true); | |
685 | |
686 $('#study .patient-link').attr('href', '#patient?uuid=' + patient.ID); | |
687 $('#study-info li').remove(); | |
688 $('#study-info') | |
689 .append('<li data-role="list-divider">Patient</li>') | |
690 .append(FormatPatient(patient, '#patient?uuid=' + patient.ID, true)) | |
691 .append('<li data-role="list-divider">Study</li>') | |
692 .append(FormatStudy(study)) | |
693 .listview('refresh'); | |
694 | |
695 SetupAnonymizedOrModifiedFrom('#study-anonymized-from', study, 'study', 'AnonymizedFrom'); | |
696 SetupAnonymizedOrModifiedFrom('#study-modified-from', study, 'study', 'ModifiedFrom'); | |
697 | |
698 target = $('#list-series'); | |
699 $('li', target).remove(); | |
700 for (var i = 0; i < series.length; i++) { | |
701 if (i == 0 || series[i].MainDicomTags.SeriesDate != series[i - 1].MainDicomTags.SeriesDate) | |
702 { | |
703 target.append($('<li>') | |
704 .attr('data-role', 'list-divider') | |
705 .text(FormatDicomDate(series[i].MainDicomTags.SeriesDate))); | |
706 } | |
707 | |
708 target.append(FormatSeries(series[i], '#series?uuid=' + series[i].ID)); | |
709 } | |
710 target.listview('refresh'); | |
711 | |
712 currentPage = 'study'; | |
713 currentUuid = pageData.uuid; | |
714 }); | |
715 }); | |
716 }); | |
717 } | |
718 } | |
719 | |
720 | |
721 function RefreshSeries() | |
722 { | |
723 var pageData, target; | |
724 | |
725 if ($.mobile.pageData) { | |
726 pageData = DeepCopy($.mobile.pageData); | |
727 | |
728 GetResource('/series/' + pageData.uuid, function(series) { | |
729 GetResource('/studies/' + series.ParentStudy, function(study) { | |
730 GetResource('/patients/' + study.ParentPatient, function(patient) { | |
731 GetResource('/series/' + pageData.uuid + '/instances', function(instances) { | |
732 Sort(instances, function(x) { return x.IndexInSeries; }, true, false); | |
733 | |
734 $('#series .patient-link').attr('href', '#patient?uuid=' + patient.ID); | |
735 $('#series .study-link').attr('href', '#study?uuid=' + study.ID); | |
736 | |
737 $('#series-info li').remove(); | |
738 $('#series-info') | |
739 .append('<li data-role="list-divider">Patient</li>') | |
740 .append(FormatPatient(patient, '#patient?uuid=' + patient.ID, true)) | |
741 .append('<li data-role="list-divider">Study</li>') | |
742 .append(FormatStudy(study, '#study?uuid=' + study.ID, true)) | |
743 .append('<li data-role="list-divider">Series</li>') | |
744 .append(FormatSeries(series)) | |
745 .listview('refresh'); | |
746 | |
747 SetupAnonymizedOrModifiedFrom('#series-anonymized-from', series, 'series', 'AnonymizedFrom'); | |
748 SetupAnonymizedOrModifiedFrom('#series-modified-from', series, 'series', 'ModifiedFrom'); | |
749 | |
750 target = $('#list-instances'); | |
751 $('li', target).remove(); | |
752 for (var i = 0; i < instances.length; i++) { | |
753 target.append(FormatInstance(instances[i], '#instance?uuid=' + instances[i].ID)); | |
754 } | |
755 target.listview('refresh'); | |
756 | |
757 currentPage = 'series'; | |
758 currentUuid = pageData.uuid; | |
759 }); | |
760 }); | |
761 }); | |
762 }); | |
763 } | |
764 } | |
765 | |
766 | |
767 function EscapeHtml(value) | |
768 { | |
769 var ENTITY_MAP = { | |
770 '&': '&', | |
771 '<': '<', | |
772 '>': '>', | |
773 '"': '"', | |
774 "'": ''', | |
775 '/': '/', | |
776 '`': '`', | |
777 '=': '=' | |
778 }; | |
779 | |
780 return String(value).replace(/[&<>"'`=\/]/g, function (s) { | |
781 return ENTITY_MAP[s]; | |
782 }); | |
783 } | |
784 | |
785 | |
786 function ConvertForTree(dicom) | |
787 { | |
788 var result = []; | |
789 var label, c; | |
790 | |
791 for (var i in dicom) { | |
792 if (dicom[i] != null) { | |
793 label = (i + '<span class="tag-name"> (<i>' + | |
794 EscapeHtml(dicom[i]["Name"]) + | |
795 '</i>)</span>: '); | |
796 | |
797 if (dicom[i]["Type"] == 'String') | |
798 { | |
799 result.push({ | |
800 label: label + '<strong>' + EscapeHtml(dicom[i]["Value"]) + '</strong>', | |
801 children: [] | |
802 }); | |
803 } | |
804 else if (dicom[i]["Type"] == 'TooLong') | |
805 { | |
806 result.push({ | |
807 label: label + '<i>Too long</i>', | |
808 children: [] | |
809 }); | |
810 } | |
811 else if (dicom[i]["Type"] == 'Null') | |
812 { | |
813 result.push({ | |
814 label: label + '<i>Null</i>', | |
815 children: [] | |
816 }); | |
817 } | |
818 else if (dicom[i]["Type"] == 'Sequence') | |
819 { | |
820 c = []; | |
821 for (var j = 0; j < dicom[i]["Value"].length; j++) { | |
822 c.push({ | |
823 label: 'Item ' + j, | |
824 children: ConvertForTree(dicom[i]["Value"][j]) | |
825 }); | |
826 } | |
827 | |
828 result.push({ | |
829 label: label + '[]', | |
830 children: c | |
831 }); | |
832 } | |
833 } | |
834 } | |
835 | |
836 return result; | |
837 } | |
838 | |
839 | |
840 function RefreshInstance() | |
841 { | |
842 var pageData; | |
843 | |
844 if ($.mobile.pageData) { | |
845 pageData = DeepCopy($.mobile.pageData); | |
846 | |
847 GetResource('/instances/' + pageData.uuid, function(instance) { | |
848 GetResource('/series/' + instance.ParentSeries, function(series) { | |
849 GetResource('/studies/' + series.ParentStudy, function(study) { | |
850 GetResource('/patients/' + study.ParentPatient, function(patient) { | |
851 | |
852 $('#instance .patient-link').attr('href', '#patient?uuid=' + patient.ID); | |
853 $('#instance .study-link').attr('href', '#study?uuid=' + study.ID); | |
854 $('#instance .series-link').attr('href', '#series?uuid=' + series.ID); | |
855 | |
856 $('#instance-info li').remove(); | |
857 $('#instance-info') | |
858 .append('<li data-role="list-divider">Patient</li>') | |
859 .append(FormatPatient(patient, '#patient?uuid=' + patient.ID, true)) | |
860 .append('<li data-role="list-divider">Study</li>') | |
861 .append(FormatStudy(study, '#study?uuid=' + study.ID, true)) | |
862 .append('<li data-role="list-divider">Series</li>') | |
863 .append(FormatSeries(series, '#series?uuid=' + series.ID, true)) | |
864 .append('<li data-role="list-divider">Instance</li>') | |
865 .append(FormatInstance(instance)) | |
866 .listview('refresh'); | |
867 | |
868 GetResource('/instances/' + instance.ID + '/tags', function(s) { | |
869 $('#dicom-tree').tree('loadData', ConvertForTree(s)); | |
870 }); | |
871 | |
872 SetupAnonymizedOrModifiedFrom('#instance-anonymized-from', instance, 'instance', 'AnonymizedFrom'); | |
873 SetupAnonymizedOrModifiedFrom('#instance-modified-from', instance, 'instance', 'ModifiedFrom'); | |
874 | |
875 currentPage = 'instance'; | |
876 currentUuid = pageData.uuid; | |
877 }); | |
878 }); | |
879 }); | |
880 }); | |
881 } | |
882 } | |
883 | |
884 $(document).live('pagebeforehide', function() { | |
885 currentPage = ''; | |
886 currentUuid = ''; | |
887 }); | |
888 | |
889 | |
890 | |
891 $('#patient').live('pagebeforeshow', RefreshPatient); | |
892 $('#study').live('pagebeforeshow', RefreshStudy); | |
893 $('#series').live('pagebeforeshow', RefreshSeries); | |
894 $('#instance').live('pagebeforeshow', RefreshInstance); | |
895 | |
896 $(function() { | |
897 $(window).hashchange(function(e, data) { | |
898 // This fixes the navigation with the back button and with the anonymization | |
899 if ('uuid' in $.mobile.pageData && | |
900 currentPage == $.mobile.pageData.active && | |
901 currentUuid != $.mobile.pageData.uuid) { | |
902 Refresh(); | |
903 } | |
904 }); | |
905 }); | |
906 | |
907 | |
908 | |
909 | |
910 | |
911 function DeleteResource(path) | |
912 { | |
913 $.ajax({ | |
914 url: path, | |
915 type: 'DELETE', | |
916 dataType: 'json', | |
917 async: false, | |
918 success: function(s) { | |
919 var ancestor = s.RemainingAncestor; | |
920 if (ancestor == null) | |
921 $.mobile.changePage('#lookup'); | |
922 else | |
923 $.mobile.changePage('#' + ancestor.Type.toLowerCase() + '?uuid=' + ancestor.ID); | |
924 } | |
925 }); | |
926 } | |
927 | |
928 | |
929 | |
930 function OpenDeleteResourceDialog(path, title) | |
931 { | |
932 $(document).simpledialog2({ | |
933 // http://dev.jtsage.com/jQM-SimpleDialog/demos2/ | |
934 // http://dev.jtsage.com/jQM-SimpleDialog/demos2/options.html | |
935 mode: 'button', | |
936 animate: false, | |
937 headerText: title, | |
938 headerClose: true, | |
939 width: '500px', | |
940 buttons : { | |
941 'OK': { | |
942 click: function () { | |
943 DeleteResource(path); | |
944 }, | |
945 icon: "delete", | |
946 theme: "c" | |
947 }, | |
948 'Cancel': { | |
949 click: function () { | |
950 } | |
951 } | |
952 } | |
953 }); | |
954 } | |
955 | |
956 | |
957 | |
958 $('#instance-delete').live('click', function() { | |
959 OpenDeleteResourceDialog('../instances/' + $.mobile.pageData.uuid, | |
960 'Delete this instance?'); | |
961 }); | |
962 | |
963 $('#study-delete').live('click', function() { | |
964 OpenDeleteResourceDialog('../studies/' + $.mobile.pageData.uuid, | |
965 'Delete this study?'); | |
966 }); | |
967 | |
968 $('#series-delete').live('click', function() { | |
969 OpenDeleteResourceDialog('../series/' + $.mobile.pageData.uuid, | |
970 'Delete this series?'); | |
971 }); | |
972 | |
973 $('#patient-delete').live('click', function() { | |
974 OpenDeleteResourceDialog('../patients/' + $.mobile.pageData.uuid, | |
975 'Delete this patient?'); | |
976 }); | |
977 | |
978 | |
979 $('#instance-download-dicom').live('click', function(e) { | |
980 // http://stackoverflow.com/a/1296101 | |
981 e.preventDefault(); //stop the browser from following | |
982 window.location.href = '../instances/' + $.mobile.pageData.uuid + '/file'; | |
983 }); | |
984 | |
985 $('#instance-download-json').live('click', function(e) { | |
986 // http://stackoverflow.com/a/1296101 | |
987 e.preventDefault(); //stop the browser from following | |
988 window.location.href = '../instances/' + $.mobile.pageData.uuid + '/tags'; | |
989 }); | |
990 | |
991 | |
992 | |
993 $('#instance-preview').live('click', function(e) { | |
994 var pageData, pdf, images; | |
995 | |
996 if ($.mobile.pageData) { | |
997 pageData = DeepCopy($.mobile.pageData); | |
998 | |
999 pdf = '../instances/' + pageData.uuid + '/pdf'; | |
1000 $.ajax({ | |
1001 url: pdf, | |
1002 cache: false, | |
1003 success: function(s) { | |
1004 window.location.assign(pdf); | |
1005 }, | |
1006 error: function() { | |
1007 GetResource('/instances/' + pageData.uuid + '/frames', function(frames) { | |
1008 if (frames.length == 1) | |
1009 { | |
1010 // Viewing a single-frame image | |
1011 jQuery.slimbox('../instances/' + pageData.uuid + '/preview', '', { | |
1012 overlayFadeDuration : 1, | |
1013 resizeDuration : 1, | |
1014 imageFadeDuration : 1 | |
1015 }); | |
1016 } | |
1017 else | |
1018 { | |
1019 // Viewing a multi-frame image | |
1020 | |
1021 images = []; | |
1022 for (var i = 0; i < frames.length; i++) { | |
1023 images.push([ '../instances/' + pageData.uuid + '/frames/' + i + '/preview' ]); | |
1024 } | |
1025 | |
1026 jQuery.slimbox(images, 0, { | |
1027 overlayFadeDuration : 1, | |
1028 resizeDuration : 1, | |
1029 imageFadeDuration : 1, | |
1030 loop : true | |
1031 }); | |
1032 } | |
1033 }); | |
1034 } | |
1035 }); | |
1036 } | |
1037 }); | |
1038 | |
1039 | |
1040 | |
1041 $('#series-preview').live('click', function(e) { | |
1042 var pageData, images; | |
1043 | |
1044 if ($.mobile.pageData) { | |
1045 pageData = DeepCopy($.mobile.pageData); | |
1046 | |
1047 GetResource('/series/' + pageData.uuid, function(series) { | |
1048 GetResource('/series/' + pageData.uuid + '/instances', function(instances) { | |
1049 Sort(instances, function(x) { return x.IndexInSeries; }, true, false); | |
1050 | |
1051 images = []; | |
1052 for (var i = 0; i < instances.length; i++) { | |
1053 images.push([ '../instances/' + instances[i].ID + '/preview', | |
1054 (i + 1).toString() + '/' + instances.length.toString() ]) | |
1055 } | |
1056 | |
1057 jQuery.slimbox(images, 0, { | |
1058 overlayFadeDuration : 1, | |
1059 resizeDuration : 1, | |
1060 imageFadeDuration : 1, | |
1061 loop : true | |
1062 }); | |
1063 }); | |
1064 }); | |
1065 } | |
1066 }); | |
1067 | |
1068 | |
1069 | |
1070 | |
1071 | |
1072 function ChooseDicomModality(callback) | |
1073 { | |
1074 var clickedModality = ''; | |
1075 var clickedPeer = ''; | |
1076 var items = $('<ul>') | |
1077 .attr('data-divider-theme', 'd') | |
1078 .attr('data-role', 'listview'); | |
1079 | |
1080 // Retrieve the list of the known DICOM modalities | |
1081 $.ajax({ | |
1082 url: '../modalities', | |
1083 type: 'GET', | |
1084 dataType: 'json', | |
1085 async: false, | |
1086 cache: false, | |
1087 success: function(modalities) { | |
1088 var name, item; | |
1089 | |
1090 if (modalities.length > 0) | |
1091 { | |
1092 items.append('<li data-role="list-divider">DICOM modalities</li>'); | |
1093 | |
1094 for (var i = 0; i < modalities.length; i++) { | |
1095 name = modalities[i]; | |
1096 item = $('<li>') | |
1097 .html('<a href="#" rel="close">' + name + '</a>') | |
1098 .attr('name', name) | |
1099 .click(function() { | |
1100 clickedModality = $(this).attr('name'); | |
1101 }); | |
1102 items.append(item); | |
1103 } | |
1104 } | |
1105 | |
1106 // Retrieve the list of the known Orthanc peers | |
1107 $.ajax({ | |
1108 url: '../peers', | |
1109 type: 'GET', | |
1110 dataType: 'json', | |
1111 async: false, | |
1112 cache: false, | |
1113 success: function(peers) { | |
1114 var name, item; | |
1115 | |
1116 if (peers.length > 0) | |
1117 { | |
1118 items.append('<li data-role="list-divider">Orthanc peers</li>'); | |
1119 | |
1120 for (var i = 0; i < peers.length; i++) { | |
1121 name = peers[i]; | |
1122 item = $('<li>') | |
1123 .html('<a href="#" rel="close">' + name + '</a>') | |
1124 .attr('name', name) | |
1125 .click(function() { | |
1126 clickedPeer = $(this).attr('name'); | |
1127 }); | |
1128 items.append(item); | |
1129 } | |
1130 } | |
1131 | |
1132 // Launch the dialog | |
1133 $('#dialog').simpledialog2({ | |
1134 mode: 'blank', | |
1135 animate: false, | |
1136 headerText: 'Choose target', | |
1137 headerClose: true, | |
1138 forceInput: false, | |
1139 width: '100%', | |
1140 blankContent: items, | |
1141 callbackClose: function() { | |
1142 var timer; | |
1143 function WaitForDialogToClose() { | |
1144 if (!$('#dialog').is(':visible')) { | |
1145 clearInterval(timer); | |
1146 callback(clickedModality, clickedPeer); | |
1147 } | |
1148 } | |
1149 timer = setInterval(WaitForDialogToClose, 100); | |
1150 } | |
1151 }); | |
1152 } | |
1153 }); | |
1154 } | |
1155 }); | |
1156 } | |
1157 | |
1158 | |
1159 $('#instance-store,#series-store,#study-store,#patient-store').live('click', function(e) { | |
1160 ChooseDicomModality(function(modality, peer) { | |
1161 var pageData = DeepCopy($.mobile.pageData); | |
1162 var url, loading; | |
1163 | |
1164 if (modality != '') | |
1165 { | |
1166 url = '../modalities/' + modality + '/store'; | |
1167 loading = '#dicom-store'; | |
1168 } | |
1169 | |
1170 if (peer != '') | |
1171 { | |
1172 url = '../peers/' + peer + '/store'; | |
1173 loading = '#peer-store'; | |
1174 } | |
1175 | |
1176 if (url != '') { | |
1177 $.ajax({ | |
1178 url: url, | |
1179 type: 'POST', | |
1180 dataType: 'text', | |
1181 data: pageData.uuid, | |
1182 async: true, // Necessary to block UI | |
1183 beforeSend: function() { | |
1184 $.blockUI({ message: $(loading) }); | |
1185 }, | |
1186 complete: function(s) { | |
1187 $.unblockUI(); | |
1188 }, | |
1189 success: function(s) { | |
1190 }, | |
1191 error: function() { | |
1192 alert('Error during store'); | |
1193 } | |
1194 }); | |
1195 } | |
1196 }); | |
1197 }); | |
1198 | |
1199 | |
1200 $('#show-tag-name').live('change', function(e) { | |
1201 var checked = e.currentTarget.checked; | |
1202 if (checked) | |
1203 $('.tag-name').show(); | |
1204 else | |
1205 $('.tag-name').hide(); | |
1206 }); | |
1207 | |
1208 | |
1209 $('#patient-archive').live('click', function(e) { | |
1210 e.preventDefault(); //stop the browser from following | |
1211 window.location.href = '../patients/' + $.mobile.pageData.uuid + '/archive'; | |
1212 }); | |
1213 | |
1214 $('#study-archive').live('click', function(e) { | |
1215 e.preventDefault(); //stop the browser from following | |
1216 window.location.href = '../studies/' + $.mobile.pageData.uuid + '/archive'; | |
1217 }); | |
1218 | |
1219 $('#series-archive').live('click', function(e) { | |
1220 e.preventDefault(); //stop the browser from following | |
1221 window.location.href = '../series/' + $.mobile.pageData.uuid + '/archive'; | |
1222 }); | |
1223 | |
1224 | |
1225 $('#patient-media').live('click', function(e) { | |
1226 e.preventDefault(); //stop the browser from following | |
1227 window.location.href = '../patients/' + $.mobile.pageData.uuid + '/media'; | |
1228 }); | |
1229 | |
1230 $('#study-media').live('click', function(e) { | |
1231 e.preventDefault(); //stop the browser from following | |
1232 window.location.href = '../studies/' + $.mobile.pageData.uuid + '/media'; | |
1233 }); | |
1234 | |
1235 $('#series-media').live('click', function(e) { | |
1236 e.preventDefault(); //stop the browser from following | |
1237 window.location.href = '../series/' + $.mobile.pageData.uuid + '/media'; | |
1238 }); | |
1239 | |
1240 | |
1241 | |
1242 $('#protection').live('change', function(e) { | |
1243 var isProtected = e.target.value == "on"; | |
1244 $.ajax({ | |
1245 url: '../patients/' + $.mobile.pageData.uuid + '/protected', | |
1246 type: 'PUT', | |
1247 dataType: 'text', | |
1248 data: isProtected ? '1' : '0', | |
1249 async: false | |
1250 }); | |
1251 }); | |
1252 | |
1253 | |
1254 | |
1255 function OpenAnonymizeResourceDialog(path, title) | |
1256 { | |
1257 $(document).simpledialog2({ | |
1258 mode: 'button', | |
1259 animate: false, | |
1260 headerText: title, | |
1261 headerClose: true, | |
1262 width: '500px', | |
1263 buttons : { | |
1264 'OK': { | |
1265 click: function () { | |
1266 $.ajax({ | |
1267 url: path + '/anonymize', | |
1268 type: 'POST', | |
1269 data: '{ "Keep" : [ "SeriesDescription", "StudyDescription" ] }', | |
1270 dataType: 'json', | |
1271 async: false, | |
1272 cache: false, | |
1273 success: function(s) { | |
1274 // The following line does not work... | |
1275 //$.mobile.changePage('explorer.html#patient?uuid=' + s.PatientID); | |
1276 | |
1277 window.location.assign('explorer.html#patient?uuid=' + s.PatientID); | |
1278 //window.location.reload(); | |
1279 } | |
1280 }); | |
1281 }, | |
1282 icon: "delete", | |
1283 theme: "c" | |
1284 }, | |
1285 'Cancel': { | |
1286 click: function () { | |
1287 } | |
1288 } | |
1289 } | |
1290 }); | |
1291 } | |
1292 | |
1293 $('#instance-anonymize').live('click', function() { | |
1294 OpenAnonymizeResourceDialog('../instances/' + $.mobile.pageData.uuid, | |
1295 'Anonymize this instance?'); | |
1296 }); | |
1297 | |
1298 $('#study-anonymize').live('click', function() { | |
1299 OpenAnonymizeResourceDialog('../studies/' + $.mobile.pageData.uuid, | |
1300 'Anonymize this study?'); | |
1301 }); | |
1302 | |
1303 $('#series-anonymize').live('click', function() { | |
1304 OpenAnonymizeResourceDialog('../series/' + $.mobile.pageData.uuid, | |
1305 'Anonymize this series?'); | |
1306 }); | |
1307 | |
1308 $('#patient-anonymize').live('click', function() { | |
1309 OpenAnonymizeResourceDialog('../patients/' + $.mobile.pageData.uuid, | |
1310 'Anonymize this patient?'); | |
1311 }); | |
1312 | |
1313 | |
1314 $('#plugins').live('pagebeforeshow', function() { | |
1315 $.ajax({ | |
1316 url: '../plugins', | |
1317 dataType: 'json', | |
1318 async: false, | |
1319 cache: false, | |
1320 success: function(plugins) { | |
1321 var target = $('#all-plugins'); | |
1322 $('li', target).remove(); | |
1323 | |
1324 plugins.map(function(id) { | |
1325 return $.ajax({ | |
1326 url: '../plugins/' + id, | |
1327 dataType: 'json', | |
1328 async: false, | |
1329 cache: false, | |
1330 success: function(plugin) { | |
1331 var li = $('<li>'); | |
1332 var item = li; | |
1333 | |
1334 if ('RootUri' in plugin) | |
1335 { | |
1336 item = $('<a>'); | |
1337 li.append(item); | |
1338 item.click(function() { | |
1339 window.open(plugin.RootUri); | |
1340 }); | |
1341 } | |
1342 | |
1343 item.append($('<h1>').text(plugin.ID)); | |
1344 item.append($('<p>').text(plugin.Description)); | |
1345 item.append($('<span>').addClass('ui-li-count').text(plugin.Version)); | |
1346 target.append(li); | |
1347 } | |
1348 }); | |
1349 }); | |
1350 | |
1351 target.listview('refresh'); | |
1352 } | |
1353 }); | |
1354 }); | |
1355 | |
1356 | |
1357 | |
1358 function ParseJobTime(s) | |
1359 { | |
1360 var t = (s.substr(0, 4) + '-' + | |
1361 s.substr(4, 2) + '-' + | |
1362 s.substr(6, 5) + ':' + | |
1363 s.substr(11, 2) + ':' + | |
1364 s.substr(13)); | |
1365 var utc = new Date(t); | |
1366 | |
1367 // Convert from UTC to local time | |
1368 return new Date(utc.getTime() - utc.getTimezoneOffset() * 60000); | |
1369 } | |
1370 | |
1371 | |
1372 function AddJobField(target, description, field) | |
1373 { | |
1374 if (!(typeof field === 'undefined')) { | |
1375 target.append($('<p>') | |
1376 .text(description) | |
1377 .append($('<strong>').text(field))); | |
1378 } | |
1379 } | |
1380 | |
1381 | |
1382 function AddJobDateField(target, description, field) | |
1383 { | |
1384 if (!(typeof field === 'undefined')) { | |
1385 target.append($('<p>') | |
1386 .text(description) | |
1387 .append($('<strong>').text(ParseJobTime(field)))); | |
1388 } | |
1389 } | |
1390 | |
1391 | |
1392 $('#jobs').live('pagebeforeshow', function() { | |
1393 $.ajax({ | |
1394 url: '../jobs?expand', | |
1395 dataType: 'json', | |
1396 async: false, | |
1397 cache: false, | |
1398 success: function(jobs) { | |
1399 var target = $('#all-jobs'); | |
1400 var running, pending, inactive; | |
1401 | |
1402 $('li', target).remove(); | |
1403 | |
1404 running = $('<li>') | |
1405 .attr('data-role', 'list-divider') | |
1406 .text('Currently running'); | |
1407 | |
1408 pending = $('<li>') | |
1409 .attr('data-role', 'list-divider') | |
1410 .text('Pending jobs'); | |
1411 | |
1412 inactive = $('<li>') | |
1413 .attr('data-role', 'list-divider') | |
1414 .text('Inactive jobs'); | |
1415 | |
1416 target.append(running); | |
1417 target.append(pending); | |
1418 target.append(inactive); | |
1419 | |
1420 jobs.map(function(job) { | |
1421 var li = $('<li>'); | |
1422 var item = $('<a>'); | |
1423 | |
1424 li.append(item); | |
1425 item.attr('href', '#job?uuid=' + job.ID); | |
1426 item.append($('<h1>').text(job.Type)); | |
1427 item.append($('<span>').addClass('ui-li-count').text(job.State)); | |
1428 AddJobField(item, 'ID: ', job.ID); | |
1429 AddJobField(item, 'Local AET: ', job.Content.LocalAet); | |
1430 AddJobField(item, 'Remote AET: ', job.Content.RemoteAet); | |
1431 AddJobDateField(item, 'Creation time: ', job.CreationTime); | |
1432 AddJobDateField(item, 'Completion time: ', job.CompletionTime); | |
1433 AddJobDateField(item, 'ETA: ', job.EstimatedTimeOfArrival); | |
1434 | |
1435 if (job.State == 'Running' || | |
1436 job.State == 'Pending' || | |
1437 job.State == 'Paused') { | |
1438 AddJobField(item, 'Priority: ', job.Priority); | |
1439 AddJobField(item, 'Progress: ', job.Progress); | |
1440 } | |
1441 | |
1442 if (job.State == 'Running') { | |
1443 li.insertAfter(running); | |
1444 } else if (job.State == 'Pending' || | |
1445 job.State == 'Paused') { | |
1446 li.insertAfter(pending); | |
1447 } else { | |
1448 li.insertAfter(inactive); | |
1449 } | |
1450 }); | |
1451 | |
1452 target.listview('refresh'); | |
1453 } | |
1454 }); | |
1455 }); | |
1456 | |
1457 | |
1458 $('#job').live('pagebeforeshow', function() { | |
1459 var pageData, target; | |
1460 | |
1461 if ($.mobile.pageData) { | |
1462 pageData = DeepCopy($.mobile.pageData); | |
1463 | |
1464 $.ajax({ | |
1465 url: '../jobs/' + pageData.uuid, | |
1466 dataType: 'json', | |
1467 async: false, | |
1468 cache: false, | |
1469 success: function(job) { | |
1470 var block, value; | |
1471 | |
1472 target = $('#job-info'); | |
1473 $('li', target).remove(); | |
1474 | |
1475 target.append($('<li>') | |
1476 .attr('data-role', 'list-divider') | |
1477 .text('General information about the job')); | |
1478 | |
1479 { | |
1480 block = $('<li>'); | |
1481 for (var i in job) { | |
1482 if (i == 'CreationTime' || | |
1483 i == 'CompletionTime' || | |
1484 i == 'EstimatedTimeOfArrival') { | |
1485 AddJobDateField(block, i + ': ', job[i]); | |
1486 } else if (i != 'InternalContent' && | |
1487 i != 'Content' && | |
1488 i != 'Timestamp') { | |
1489 AddJobField(block, i + ': ', job[i]); | |
1490 } | |
1491 } | |
1492 } | |
1493 | |
1494 target.append(block); | |
1495 | |
1496 target.append($('<li>') | |
1497 .attr('data-role', 'list-divider') | |
1498 .text('Detailed information')); | |
1499 | |
1500 { | |
1501 block = $('<li>'); | |
1502 | |
1503 for (var item in job.Content) { | |
1504 var value = job.Content[item]; | |
1505 if (typeof value !== 'string') { | |
1506 value = JSON.stringify(value); | |
1507 } | |
1508 | |
1509 AddJobField(block, item + ': ', value); | |
1510 } | |
1511 } | |
1512 | |
1513 target.append(block); | |
1514 | |
1515 target.listview('refresh'); | |
1516 | |
1517 $('#job-cancel').closest('.ui-btn').hide(); | |
1518 $('#job-resubmit').closest('.ui-btn').hide(); | |
1519 $('#job-pause').closest('.ui-btn').hide(); | |
1520 $('#job-resume').closest('.ui-btn').hide(); | |
1521 | |
1522 if (job.State == 'Running' || | |
1523 job.State == 'Pending' || | |
1524 job.State == 'Retry') { | |
1525 $('#job-cancel').closest('.ui-btn').show(); | |
1526 $('#job-pause').closest('.ui-btn').show(); | |
1527 } | |
1528 else if (job.State == 'Success') { | |
1529 } | |
1530 else if (job.State == 'Failure') { | |
1531 $('#job-resubmit').closest('.ui-btn').show(); | |
1532 } | |
1533 else if (job.State == 'Paused') { | |
1534 $('#job-resume').closest('.ui-btn').show(); | |
1535 } | |
1536 } | |
1537 }); | |
1538 } | |
1539 }); | |
1540 | |
1541 | |
1542 | |
1543 function TriggerJobAction(action) | |
1544 { | |
1545 $.ajax({ | |
1546 url: '../jobs/' + $.mobile.pageData.uuid + '/' + action, | |
1547 type: 'POST', | |
1548 async: false, | |
1549 cache: false, | |
1550 complete: function(s) { | |
1551 window.location.reload(); | |
1552 } | |
1553 }); | |
1554 } | |
1555 | |
1556 $('#job-cancel').live('click', function() { | |
1557 TriggerJobAction('cancel'); | |
1558 }); | |
1559 | |
1560 $('#job-resubmit').live('click', function() { | |
1561 TriggerJobAction('resubmit'); | |
1562 }); | |
1563 | |
1564 $('#job-pause').live('click', function() { | |
1565 TriggerJobAction('pause'); | |
1566 }); | |
1567 | |
1568 $('#job-resume').live('click', function() { | |
1569 TriggerJobAction('resume'); | |
1570 }); |