Skip to content

Commit

Permalink
feat(google-cloud): Add support for Google Cloud Healthcare API DICOM…
Browse files Browse the repository at this point in the history
… Store Switch (#325)

* NOTASK: PoC for loading data from Healthcare API

* NOTASK: PoC for loading data from Healthcare API fix

* Add sample dialog for loading test dicom-picker

* Fix incorrect promise resolving

* NOTASK: PoC for loading dicom store

* Add web-components as git submodules. (Probably will be changed later)

* Add rough dicomStore picker

* Add dataset selector

* NOTASK: QIDO metadata first draft

* NOTASK: Not Implemented error for color images

* NOTASK: clean-up

* Dicom files uploader intermediate version

* NOTASK: Accept header

* NOTASK: docker configs

* NOTASK: fix

* NOTASK: howTo

* Add draft of DICOM uploader

* Add missing files

* Fix error with missing clientId

* Update submodule

* NOTASK: HowTo

* NOTASK: config for dev

* NOTASK: new docker file

* clean-up

* Update GCP web-components

* Add integration with async web components

* Fix errors in nginx.conf

* Structured reports views basic implementation

* NOTASK: qido -> wado

* NOTASK: config fix

* NOTASK: dirty copy-paste implementation

* Add "Change dicom store" button.
Add an ability to clear date.
Fix bug, when OAuth dosn't work if URL is not /

* Fix studylist filtering

* Fix dockerfile

* NOTASK: meteor update

* NOTASK: fix of package structure

* NOTASK: merge fix

* improvements

Move check for now SR into SR modal
Use simple button to open SR modal
Remove button styling
cleanup

* copy SR data retrieval to wado

* make search of SR simpler

* Codestyle fix

* NOTASK: palette color error message

* Fix date filter.
Fix server settings on first loading.
Add SR and PS buttons

* NOTASK: PS is now hidden by default

* NOTASK: dirty solution

* NOTASK:  new wadoimage lib version

* Fix PS and SR buttons

* Make modal dialogs vertically centered

* Update web components. Quick UI fixes

* Add missing files to the previous commit

* NOTASK:  show-hide for PS

* NOTASK:  show-hide for PS

* NOTASK:  fix of min-max PixelValue bug

* Add "sign out" functionality for Google OAuth. Update web-components.

* intermediate commit

* Add demo signin page

* Beautifying demo sign in page

* NOTASK:  merge

* NOTASK:  clean-up

* Use npm for getting healthcare-api-adapter instead of git submodule.

* NOTASK:  clean-up

* meteor update

* clean-up

* clean-up

* Clean up code

* Update healthcare-api-adapter version. Add location to dicom store path. Fix buttons style.

* Downgrade meteor and packages to master version. Use meteor-build-client-fixed2
  • Loading branch information
pavertomato authored and swederik committed Mar 22, 2019
1 parent 1783351 commit 9486522
Show file tree
Hide file tree
Showing 68 changed files with 1,422 additions and 514 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.idea/
.vscode/
.meteor/local
.meteor/meteorite
.meteor/dev_bundle
Expand Down
4 changes: 3 additions & 1 deletion OHIFViewer/.meteor/packages
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ ohif:viewerbase
ohif:study-list
ohif:hanging-protocols
ohif:metadata
ohif:google-cloud
ohif:demo-mode
ohif:user-oidc
ohif:measurement-table

Expand All @@ -50,4 +52,4 @@ johdirr:meteor-git-rev
cultofcoders:persistent-session
shell-server@0.3.1
underscore
meteortesting:mocha
meteortesting:mocha
4 changes: 3 additions & 1 deletion OHIFViewer/.meteor/versions
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,9 @@ ohif:commands@0.0.1
ohif:core@0.0.1
ohif:cornerstone@0.0.1
ohif:cornerstone-settings@0.0.1
ohif:demo-mode@0.0.1
ohif:design@0.0.1
ohif:google-cloud@0.0.1
ohif:hanging-protocols@0.0.1
ohif:header@0.0.1
ohif:hotkeys@0.0.1
Expand Down Expand Up @@ -128,4 +130,4 @@ ui@1.0.13
underscore@1.0.10
url@1.2.0
webapp@1.6.2
webapp-hashing@1.0.9
webapp-hashing@1.0.9
6 changes: 4 additions & 2 deletions OHIFViewer/client/components/ohifViewer/ohifViewer.html
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
</div>
{{/section}}
{{/header}}

{{>Template.dynamic template=(choose this.template 'studylist') data=this}}

{{#if isStudyListReady}}
{{>Template.dynamic template=(choose this.template 'studylist') data=this}}
{{/if}}
</template>
31 changes: 28 additions & 3 deletions OHIFViewer/client/components/ohifViewer/ohifViewer.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { OHIF } from 'meteor/ohif:core';
Template.ohifViewer.onCreated(() => {
const instance = Template.instance();
instance.headerClasses = new ReactiveVar('');
Session.set("IsStudyListReady", true);;

const headerItems = [{
action: () => OHIF.ui.showDialog('serverInformationModal'),
Expand All @@ -31,9 +32,11 @@ Template.ohifViewer.onCreated(() => {
icon: 'fa fa-info'
}];

if (OHIF.user.userLoggedIn() === true) {
const isUserLoggedIn = OHIF.user.userLoggedIn();
const isDemoUserLoggedIn = OHIF.demoMode && OHIF.demoMode.userLoggedIn();
if (isUserLoggedIn || isDemoUserLoggedIn) {
headerItems.push({
action: OHIF.user.logout,
action: isDemoUserLoggedIn ? OHIF.demoMode.logout : OHIF.user.logout,
text: 'Logout',
iconClasses: 'logout',
iconSvgUse: 'packages/ohif_viewerbase/assets/user-menu-icons.svg#logout'
Expand All @@ -57,6 +60,24 @@ Template.ohifViewer.onCreated(() => {
// Set the viewer open state on session
Session.set('ViewerOpened', isViewer);
});

if (OHIF.demoMode && OHIF.demoMode.userLoggedIn())
OHIF.demoMode.setDemoServerConfig();
else if (OHIF.gcloud && OHIF.gcloud.isEnabled()) {
const server = OHIF.servers.getCurrentServer();
if (!server || !server.isCloud) {
Session.set("IsStudyListReady", false);
OHIF.gcloud.showDicomStorePicker({canClose: OHIF.demoMode}).then(config => {
if (!config) {
if (OHIF.demoMode)
Router.go('/demo-signin');
return;
}
OHIF.servers.applyCloudServerConfig(config);
Session.set("IsStudyListReady", true);
});
}
}
});

Template.ohifViewer.events({
Expand All @@ -72,7 +93,8 @@ Template.ohifViewer.events({
Router.go('viewerStudies', { studyInstanceUids });
}
}
}
},

});

Template.ohifViewer.helpers({
Expand All @@ -86,5 +108,8 @@ Template.ohifViewer.helpers({
}

return instance.hasViewerData ? 'Back to viewer' : '';
},
isStudyListReady() {
return !!Session.get('IsStudyListReady');
}
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<template name="structuredReportModal">
{{#dialogForm (extend this
id='structuredReportModal'
dialogClass='themed modal-lg'
title='Structured report'
hideCancel=true
hideConfirm=true
)}}
<div id="root"></div>
{{/dialogForm}}
</template>
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import { $ } from 'meteor/jquery';
import { OHIF } from 'meteor/ohif:core';

Template.structuredReportModal.onRendered(() => {
const structuredReport = getStructureReport();

render(structuredReport);
});

// FIXME: we use just 1st SR for current study for now
function getStructureReport() {
let structuredReport;

OHIF.viewer.StudyMetadataList.find(studyMetadata => {

structuredReport = studyMetadata.findInstance(instance => instance.getData().modality === 'SR');

// If SR is found stop the search
return !!structuredReport;
});

return structuredReport;
}

function render(structureReport) {
const root = $('#root');

if (structureReport) {
renderStructuredReport(root, structureReport.getData());
} else {
renderNoData(root);
}

}

function renderStructuredReport(root, data) {
root.append(getMainDataHtml(data));
root.append(getContentSequenceHtml(data.contentSequence));
}

function renderNoData(root) {
root.append('<div>No structured report found</div>');
}

function getMainDataHtml(data) {
const root = $('<div></div>');

const { completionFlag, verificationFlag, manufacturer, contentDateTime } = data;

if (completionFlag) {
root.append(getMainDataItemHtml('Completion flag', completionFlag));
}

if (verificationFlag) {
root.append(getMainDataItemHtml('Verification flag', verificationFlag));
}

if (manufacturer) {
root.append(getMainDataItemHtml('Manufacturer', manufacturer));
}

if (contentDateTime) {
root.append(getMainDataItemHtml('Content Date/Time', contentDateTime));
}

return root;
}

const getContentSequenceHtml = (data, level = 1) => {
const root = $('<div></div>');
const header = data.header;
const items = data.items || [];

if (header) {
root.append(`<h${level}>${header}</h${level}>`);
}

items.forEach(item => {
root.append(
item instanceof Object
? getContentSequenceHtml(item, level + 1)
: `<div>${item}</div>`
);
});

return root;
}

function getMainDataItemHtml(key, value) {
return $(`<div><b>${key}</b>: ${value}</div>`);
}
18 changes: 17 additions & 1 deletion OHIFViewer/client/components/toolbarSection/toolbarSection.js
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,22 @@ Template.toolbarSection.helpers({
buttonTemplateName: 'layoutButton'
});

buttonData.push({
id: 'sr',
title: 'SR',
classes: 'imageViewerTool',
svgLink: '/packages/ohif_viewerbase/assets/icons.svg#icon-sr'
});

buttonData.push({
id: 'ps',
title: 'PS',
iconClasses: 'fa fa-th-large',
classes: 'imageViewerTool',
svgLink: '/packages/ohif_viewerbase/assets/icons.svg#icon-ps'
});


buttonData.push({
id: 'toggleMore',
title: 'More',
Expand Down Expand Up @@ -318,4 +334,4 @@ Template.toolbarSection.onRendered(function() {
}
}
}
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<template name="demoSignin">
<div class="demoSignin">
<div class="demo-content">
<div class="demo-brand">
<svg class="logo-image">
<use xlink:href={{absoluteUrl "packages/ohif_viewerbase/assets/icons.svg#icon-ohif-logo"}}></use>
</svg>
<div class="logo-text">Open Health Imaging Foundation</div>
</div>
<div class="demoSigninButtons">
<button type="submit" id="google-login-button" class="button button--nostyle">
<span class="sign-in-with-google-icon-tile">
<svg class="google-icon">
<use xlink:href={{absoluteUrl "packages/ohif_viewerbase/assets/icons.svg#google-icon"}}></use>
</svg></span>
<span>Sign in with Google</span>
</button>
<hr class="tint">
<button id="anonymous-login-button">
<span>Anonymous Sign in</span>
</button>
</div>
</div>
</div>
</template>
15 changes: 15 additions & 0 deletions Packages/ohif-demo-mode/client/components/demoSignin/demoSignin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { OHIF } from 'meteor/ohif:core';
import { Router } from 'meteor/clinical:router';

Template.demoSignin.events({
'click #google-login-button'() {
OHIF.gcloud.setEnabled(true);
OHIF.user.login();
},
'click #anonymous-login-button'() {
OHIF.gcloud.setEnabled(false);
OHIF.demoMode.login();
Router.go('/studylist', {}, { replaceState: true });
}
});

Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
@require '{ohif:design}/app'

.demoSignin
display flex
flex 1
flex-flow row nowrap
align-items stretch
height 100vh
min-height 600px
width 100%
background-color rgba(21, 25, 30, 0.7)

.demo-content
margin auto
width 500px
position relative
top -150px

.demoSigninButtons
margin auto
width 270px
font-weight 500

#google-login-button
display flex
justify-content center
height 40px
width 100%
color #fff
border-color #4285F4
background #4285F4
border-radius 3px
box-shadow 0 0 1px 0 rgba(0, 0, 0, 0.12), 0 1px 1px 0 rgba(0, 0, 0, 0.24)
cursor pointer
position relative
align-items center

#anonymous-login-button
display flex
justify-content center
height 40px
width 100%
color #757575
border-color white
background white
border-radius 3px
box-shadow 0 0 1px 0 rgba(0, 0, 0, 0.12), 0 1px 1px 0 rgba(0, 0, 0, 0.24)
cursor pointer
position relative
align-items center

#google-login-button .sign-in-with-google-icon-tile
position absolute
top 1px
left 1px
background #fff
border-radius 2px
height 32px
width 32px
display flex
align-items center
justify-content center
font-weight 500

svg.google-icon
width 24px
height 24px

hr.tint
border-color hsla(0, 0%, 100%, 0.3)

.demo-brand
height 60px
display inline-block
text-decoration none
margin-bottom 30px

.logo-image
display inline-block
fill transparent
float left
height 100%
margin 0 8px 0 0
width 60px
margin-right 20px

.logo-text
display inline-block
font-family Roboto, Arial, Helvetica, sans-serif
font-size 26px
font-weight 400
theme('color', '$textPrimaryColor')
line-height 60px
3 changes: 3 additions & 0 deletions Packages/ohif-demo-mode/client/components/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import './demoSignin/demoSignin.html';
import './demoSignin/demoSignin.js';
import './demoSignin/demoSignin.styl';

0 comments on commit 9486522

Please sign in to comment.