Make external grpc address configurable

master
Bas Kloosterman 12 months ago
parent 674b3505ef
commit 3461e04283
  1. 4
      docker-compose.yaml
  2. 8
      dvzaservice/main.go
  3. 3
      dvzaservice/srv.go
  4. 1
      dvzaservice/templates/index.html
  5. 2
      whiteboxservice/app/src/Home.js
  6. 442
      whiteboxservice/bin/template.html
  7. 8
      whiteboxservice/main.go
  8. 2
      whiteboxservice/srv.go
  9. 1
      whiteboxservice/templates/index.html

@ -16,7 +16,7 @@ services:
container_name: okapi_wbx
restart: always
environment:
EXT_ADDR: "okapi_wbx:8888"
EXT_ADDR: "okapi_wbx"
BIN_FOLDER: "/wbxbin"
volumes:
- "./wbx/data:/data"
@ -28,7 +28,7 @@ services:
container_name: okapi_dvza
restart: always
environment:
EXT_ADDR: "okapi_dvza:9999"
EXT_ADDR: "okapi_dvza"
volumes:
- "./dvza/data:/data"
- "./dvza/certs:/certs"

@ -16,7 +16,9 @@ import (
"src.whiteboxsystems.nl/DECOZO/okapidemo/certgen"
)
var rpcAddr = "0.0.0.0:9999"
var rpcPort = "9999"
var rpcAddr = "0.0.0.0:" + rpcPort
var extRpcAddr = "localhost:" + rpcPort
var uiAddr = "0.0.0.0:9095"
func loadCert() *tls.Certificate {
@ -84,6 +86,10 @@ func main() {
grpcServer := grpc.NewServer(opts...)
if ext := os.Getenv("EXT_ADDR"); ext != "" {
extRpcAddr = ext + ":" + rpcPort
}
go func() {
lis, err := net.Listen("tcp", rpcAddr)
if err != nil {

@ -69,7 +69,8 @@ func (srv *UIService) init() {
}
func (srv *UIService) GetIndex(c *gin.Context) {
c.HTML(http.StatusOK, "index.html", gin.H{})
c.HTML(http.StatusOK, "index.html", gin.H{"externalURL": extRpcAddr})
}
func (srv *UIService) GetConnection(c *gin.Context) {

@ -8,6 +8,7 @@
</head>
<body>
<div id="root"></div>
<script>window.externalUrl = '{{.externalURL}}'</script>
<script src="/assets/js/index.js"></script>
</body>
</html>

@ -5,7 +5,7 @@ const App = () => {
return (
<div>
<h1 className="t-page-header">Welkom bij Whitebox</h1>
<p>Dit systeem is beschikbaar op: <code>wbx.openkv.mcsr.nl:8888</code></p>
<p>Dit systeem is beschikbaar op: <code>{window.externalUrl}</code></p>
</div>
);
};

@ -1,442 +0,0 @@
<style>
.container { margin: 1em auto; font-size: 12pt; font-family: "Helvetica Neue",Helvetica,Arial,sans-serif; }
@media screen and (max-width: 700px) {
.container { width: 700px; }
}
@media screen and (min-width: 1200px) {
.container { width: 1200px; }
}
.container h3 { margin-bottom: 8px; }
.container ul { list-style-type: none; }
.container li + li { margin-top: 10px; }
.container td { vertical-align: top; }
.container .seg { margin-top: 8px; padding: 8px 10px; border: 0 solid #e7e7e7; border-width: 0 1px 1px 1px; }
.container .seg-hdr { margin-top: 8px; border-top-width: 1px; background: #F8F8F8; }
.container .seg-hdr-white { margin-top: 8px; background: #FFFFFF; border-color: transparent; }
.container a { color: royalblue }
.container table.patient th { text-align: left; padding-right: 1em }
.container table.SOEPkind { margin: -6px 0 }
.container table.SOEPkind tr { height: 1em }
.container table.SOEPkind th { text-align: left; width: 32px; height: 1em; font-weight: normal }
.container table.results th { text-align: left }
.container .error { position: fixed; top: 10px; margin-left: 32px; border: 2px solid #000000; background-color: #FF2222; }
.row + .row { margin-top: 4px; }
.table { font-size: 100%; width: 100%; border-spacing: 0; border-collapse: collapse; }
.table tr { font-size: 100% }
.table td { font-size: 100% }
.table th { font-size: 100%; text-align: left; }
.table tbody td { font-size: 100%; text-align: left; padding: 2px 8px 2px 0; }
.table thead th { font-size: 100%; padding: 0 0 2px 0; }
.table tr.highlight { background: #E3E9E3 }
.column-attn { width: 1em; }
.column-code { width: 4em; }
.column-date { width: 6.5em; }
.column-small-name { width: 10em; }
.column-medium-name { width: 14em; }
.column-large-name { width: 28em; }
.column-name { width: 20em; }
.column-instr{ width: 15em; }
.column-quantity { width: 12em; }
.no-margin { margin-bottom: 0px; }
.seg-date { float: left; width: 6.5em; }
.seg-content-offset { margin-left: 6.5em }
.column-result-id { width: 16em }
.column-result-name { width: 10em }
.container h3.fold-toggle { margin-bottom: 8px }
.container h4.fold-toggle { margin-bottom: 0; margin-top: 4px }
.container h3.fold-toggle.fold-toggle-hidden { margin-bottom: 0 }
.container h4.fold-toggle.fold-toggle-hidden { margin-bottom: 4px }
.fold-toggle .fold-marker:before,
.container h3.fold-toggle:before,
.container h4.fold-toggle:before { content: "▾ " }
.fold-toggle.fold-toggle-hidden .fold-marker:before,
.container h3.fold-toggle.fold-toggle-hidden:before,
.container h4.fold-toggle.fold-toggle-hidden:before { content: "▸ " }
.fold-toggle { cursor: pointer; }
.fold-hidden {display: none}
.hidden
{
display: none !important
}
.container textarea
{
border: 1px solid #333;
padding: .5em;
font-size: 100%
}
.container input[type=submit]
{
font-size: 90%;
padding: .25em
}
.container button
{
font-size: 75%;
padding: .25em
}
</style>
<div class="container">
{{define "person-row"}}
<tr id="person-{{.Anchor}}">
<td class="column-small-name">{{if .Name}}{{.Name}}{{else}}<em>Geen naam</em>{{end}}</td>
<td class="column-small-name">{{.Function}}</td>
<td class="column-medium-name">{{.Address}}</td>
<td class="column-small-name">{{if .AGB}}AGB: {{.AGB}}{{end}}</td>
</tr>{{end}}
{{define "medi-group-epi"}}
{{$root := .}}
<table class="table">
<thead>
<tr>
<th class="column-date">Datum</th>
<th class="column-code">Type</th>
<th class="column-date">ICPC</th>
<th class="column-name">Beschrijving</th>
{{if eq .Extra.verbose_icpc_description "true"}}
<th class="column-desc">Beschrijving arts</th>
{{else}}
{{end}}
<th class="column-desc"></th>
</tr>
</thead>
<tbody>
{{range .Episodes}}
<tr{{if .Anchor}} id="medigroup-{{.Anchor}}"{{end}}>
<td>{{.Date}}</td>
<td>{{.Type}}</td>
<td>{{.ICPC}}</td>
{{if eq $root.Extra.verbose_icpc_description "true"}}
<td>{{.Title}}</td>
<td>{{.Description}}</td>
{{else}}
{{if eq .Description ""}}
<td colspan="2">{{.Title}}</td>
{{else}}
<td colspan="2">{{.Description}}</td>
{{end}}
{{end}}
</tr>{{end}}
</tbody>
</table>
{{end}}
{{define "medi-group-ica"}}
{{$root := .}}
<table class="table">
<thead>
<tr>
<th class="column-date">Datum</th>
<th class="column-code">Type</th>
<th class="column-date">ICPC</th>
<th class="column-name" colspan="2">Beschrijving</th>
{{if eq $root.Extra.verbose_icpc_description "true"}}
<th class="column-desc"></th>
{{else}}
{{end}}
</tr>
</thead>
<tbody>
{{range .Indicators}}
<tr{{if .Anchor}} id="medigroup-{{.Anchor}}"{{end}}>
<td>{{.Date}}</td>
<td>{{.Type}}</td>
<td>{{.ICPC}}</td>
<td>{{.Title}}</td>
{{if eq $root.Extra.verbose_icpc_description "true"}}
<td>{{.Description}}</td>
{{else}}
<td></td>
{{end}}
</tr>{{end}}
</tbody>
</table>
{{end}}
<div class="seg seg-hdr" data-his="{{.HIS}}">
<h3>Huisarts</h3>
<table class="table">
{{template "person-row" .GP}}
{{if .Pharmacy.Anchor}}{{template "person-row" .Pharmacy}}{{end}}
</table>
{{if .Practitioners}}
<h4 data-fold-toggle="practicioners" data-fold-hide="1">Medebehandelaren</h4>
<div data-fold="practicioners">
<table class="table">{{range .Practitioners}}
{{template "person-row" .}}{{end}}
</table>
</div>
{{end}}
</div>
<div class="seg seg-hdr">
<h3>Patiënt</h3>
<table class="patient">
<tr>
<th>Naam:
<td>{{.Patient.Name}}
{{if .Patient.BSN}}
<tr>
<th>BSN:
<td>{{.Patient.BSN}}
{{end}}
<tr>
<th>Geboortedatum:
<td>{{.Patient.Birthdate}}
<tr>
<th>Adres:
<td>{{.Patient.Address}}
<tr>
<th>Geslacht:
<td>{{.Patient.Gender}}
{{range .Patient.OtherFields}}
<tr>
<th>{{.Key}}:
<td{{if eq .Key "Toegepast filter"}} title="Een filter is een (standaard) filter dat door een huisarts over alle of een deel van de patiëntendossiers wordt toegepast. De minimale professionele samenvatting (PS) bevat een samenvatting van alleen zeer recente informatie uit het huisartsdossier, met alleen actuele / chronische medicatie. Dit is minder informatie dan de standaard NHG PS, die journaalregels tot 4 maanden terug, of de laatste 5 consultverslagen kan bevatten. Houd er svp rekening mee dat geen enkel type PS alle, of gegarandeerd volledige of correcte informatie bevat."{{end}}>{{.Value}}
{{end}}
</table>
</div>
{{if .Memo}}
<div class="seg seg-hdr">
<h3>Memo</h3>
{{.Memo}}
</div>
{{end}}
{{if .Episodes}}
<div class="seg seg-hdr">
<h3>Episodelijst</h3>
{{template "medi-group-epi" .}}
</div>
{{end}}
{{if .Indicators}}
<div class="seg seg-hdr">
<h3>Contra-indicaties, interacties en allergie&#235;n</h3>
{{template "medi-group-ica" .}}
</div>
{{end}}
{{if .Medication}}
<div class="seg seg-hdr">
<h3 data-fold-toggle="med-table">Medicatieoverzicht</h3>
<table data-fold="med-table" class="table">
<thead>
<tr>
<th class="column-large-name">Recept</th>
<th class="column-instr">Gebruiksvoorschrift</th>
<th class="column-quantity">Hoeveelheid</th>
<th class="column-date">Ingang</th>
<th class="column-date">Vervalt</th>
</tr>
</thead>
<tbody>
{{range $index, $med := .Medication}}
{{if gt (len $med.Fold) 1}}
<tr data-fold-toggle="medfold-{{$index}}" data-fold-hide="1">
<td>{{$med.Recipe}}</td>
<td>{{$med.Instructions}}</td>
<td>{{ YieldDosage $med }}</td>
<td>{{$med.StartDate}}</td>
<td>{{$med.EndDate}}</td>
</tr>
{{range $fold := $med.Fold}}
<tr data-fold="medfold-{{$index}}">
<td></td>
<td>{{ if ne $med.Instructions $fold.Instructions}}{{$fold.Instructions}}{{else}}{{end}}</td>
<td>{{ YieldDosage $fold }}</td>
<td>{{$fold.StartDate}}</td>
<td>{{$fold.EndDate}}</td>
</tr>
{{end}}
{{else}}
<tr>
<td>{{$med.Recipe}}</td>
<td>{{$med.Instructions}}</td>
<td>{{ YieldDosage $med }}</td>
<td>{{$med.StartDate}}</td>
<td>{{$med.EndDate}}</td>
</tr>
{{end}}
{{end }}
</tbody>
</table>
</div>
{{end}}
{{if .Journal}}
<div class="seg seg-hdr-white">
<h3>Journaal</h3>
</div>
{{range .Journal}}
<div class="seg seg-hdr">
<div class="seg-date">{{.Date}}</div>
<div class="seg-content-offset" title="{{.AuthorName}}{{if .Kind}} ({{.Kind}}){{end}}">
{{if .Results}}
<div class="row">
<table class="results">
<thead>
<tr>
<th class="column-result-id">Identificatie</th>
<th class="column-result-name">Resultaat</th>
<th class="column-result-desc">Beschrijving</th>
</tr>
</thead>
<tbody>
{{range .Results}}
<tr {{if .Episode}}data-episode="{{.Episode}}"{{end}}><td>{{.Kind}}</td>
<td>{{.Result}}</td>
<td>{{if eq .Identification "Buiten normaalwaarde"}}<strong>{{.Identification}}</strong>{{else}}{{.Identification}}{{end}}
{{if and .Identification .Description}}<br>{{end}}
{{.Description}}
</td>
</tr>
{{end}}
</tbody>
</table>
</div>
{{end}}
{{range .Lines}}
<div class="row"{{if .Episode}} data-episode="{{.Episode}}"{{end}}>
<table class="SOEPkind">
<tr>
{{if .SOEP}}
<th style="padding-top: 10px; vertical-align: top;">{{.SOEP}}:
<td style="padding-top: 10px; vertical-align: top;">{{ConvertLinebreaks .Text}}
{{end}}
{{if .Kind}}
<th style="padding-top: 10px; vertical-align: top;">{{.Kind}}{{if .Text}}:{{end}}
<td style="padding-top: 10px; vertical-align: top;">{{ConvertLinebreaks .Text}}
{{end}}
</tr>
</table>
</div>
{{end}}
</div>
</div>
{{end}}
{{end}}
{{if .Extra.csrf_token }}
<div class="seg seg-hdr-white">
<br>
<h3 id="feedback-header"><button onClick="feedbackHeaderClicked()">Notitie schrijven</button></h3>
<form id="feedback-form" class="hidden" method="POST" onSubmit="sendFeedback(); return false"> <!-- TODO: contruct proper URL in golang -->
<input type="hidden" name="csrf_token" value="{{.Extra.csrf_token}}" id="csrf">
<p><br><textarea id="feedback-textarea" rows="7" cols="50"></textarea>
<p><br><input type="submit" value="Opsturen">
</form>
</div>
{{end}}
</div>
<script>
(function() {
var folds = document.querySelectorAll('[data-fold-toggle]');
for (var i = 0; i < folds.length; i++) {
(function(btn) {
var t = btn.getAttribute('data-fold-toggle');
var fds = document.querySelectorAll('[data-fold="' + t + '"]');
btn.classList.add('fold-toggle');
var hidden = false;
var sync = function() {
if (hidden) {
btn.classList.add('fold-toggle-hidden');
} else {
btn.classList.remove('fold-toggle-hidden');
}
for (var j = 0; j < fds.length; j++) {
var e = fds[j].classList;
if (hidden) {
e.add('fold-hidden');
} else {
e.remove('fold-hidden');
}
}
setTimeout(send_height_to_parent, 0);
};
if (btn.getAttribute('data-fold-hide') == '1') {
hidden = true;
}
btn.addEventListener('click', function() {
hidden = !hidden;
sync();
});
sync();
})(folds[i]);
}
})();
function feedbackHeaderClicked()
{
toggle('feedback-form')
var textarea = document.getElementById('feedback-textarea')
textarea.focus()
}
function toggle(id)
{
var elem = document.getElementById(id)
if (elem)
{
var className = elem.getAttribute('class')
if (className == 'hidden')
{
elem.setAttribute('class', '')
}
else
{
elem.setAttribute('class', 'hidden')
}
}
}
function getXMLHttpRequest()
{
if (window.XMLHttpRequest)
{
return new XMLHttpRequest()
}
else if (window.ActiveXObject)
{
return new ActiveXObject('Microsoft.XMLHTTP')
}
}
</script></body></html>

@ -16,9 +16,10 @@ import (
"src.whiteboxsystems.nl/DECOZO/okapidemo/certgen"
)
var srvaddr = "0.0.0.0:8888"
var rpcPort = "8888"
var srvaddr = "0.0.0.0:" + rpcPort
var extRpcAddr = "localhost:" + rpcPort
var patientIf = "0.0.0.0:8085"
var binFolder = "./bin"
func loadCert() *tls.Certificate {
_, err := os.Stat("certs/client.crt")
@ -71,6 +72,9 @@ func main() {
binFolder = os.Getenv("BIN_FOLDER")
}
if ext := os.Getenv("EXT_ADDR"); ext != "" {
extRpcAddr = ext + ":" + rpcPort
}
openapisrv := NewServer()
openapisrv.LoadData("./data/data.db")
opts := []grpc.ServerOption{

@ -70,7 +70,7 @@ func (srv *UIService) init() {
}
func (srv *UIService) GetIndex(c *gin.Context) {
c.HTML(http.StatusOK, "index.html", gin.H{})
c.HTML(http.StatusOK, "index.html", gin.H{"externalURL": extRpcAddr})
}
func (srv *UIService) GetConnection(c *gin.Context) {

@ -8,6 +8,7 @@
</head>
<body>
<div id="root"></div>
<script>window.externalUrl = '{{.externalURL}}'</script>
<script src="/assets/js/index.js"></script>
</body>
</html>
Loading…
Cancel
Save