diff --git a/htdocs/RoutePatientDocuments.vue b/htdocs/RoutePatientDocuments.vue index 0e2251c..e0e9369 100644 --- a/htdocs/RoutePatientDocuments.vue +++ b/htdocs/RoutePatientDocuments.vue @@ -26,7 +26,7 @@ {{doctitle(selection_text) || 'Document'}} -
{{selection_text}}
+
{{selection_text}}
@@ -46,10 +46,14 @@ cursor: default; border-top: 1px solid #dee2e6; padding: 0.25rem 0.75rem; + scroll-margin-top: 3.6875rem; } li.record:nth-child(even) { background-color: rgba(0, 0, 0, 0.05); } + ul.scroller.list-skinny li.record { + scroll-margin-top: 0; + } li.record a { color: inherit; } @@ -70,6 +74,7 @@ text-decoration: none; } div.detail { + scroll-margin-top: calc(3.6875rem + 2.5625rem + 25vh); font-family: monospace; white-space: pre-wrap; } @@ -85,6 +90,7 @@ } div.detail { max-height: 75vh; + scroll-margin-top: 0; overflow-y: auto; } } @@ -192,6 +198,27 @@ this.selection_text = null; console.warn(ex); } + if(this.$refs.scroller) { + if(this.selection_text) { // scroll to selected item + await this.$nextTick(); + var active = this.$refs.scroller.querySelectorAll(':scope > .active'); + if(active.length > 0) (Element.prototype.scrollIntoViewIfNeeded || Element.prototype.scrollIntoView).call(active[0]); + if(this.$refs.detail) { // scroll to top of detail panel + this.$refs.detail.scrollIntoView(); + this.$refs.detail.scrollTop = 0; + } + } else { // scroll to topmost item + var offset = this.$refs.scroller.getBoundingClientRect().top; + for(var children = this.$refs.scroller.children, count = children.length, i = 0; i < count; ++i) if(children[i].getBoundingClientRect().top >= offset) { + await this.$nextTick(); + var behavior = document.documentElement.style.scrollBehavior; + document.documentElement.style.scrollBehavior = 'auto'; // inhibit Bootstrap smooth scrolling + children[i].scrollIntoView(); + document.documentElement.style.scrollBehavior = behavior; + break; + } + } + } }, { immediate: true } ); diff --git a/htdocs/RoutePatientReports.vue b/htdocs/RoutePatientReports.vue index c6ed087..9b8bbbb 100644 --- a/htdocs/RoutePatientReports.vue +++ b/htdocs/RoutePatientReports.vue @@ -34,7 +34,7 @@ {{selection.title.join(' - ')}} -
+
@@ -74,10 +74,14 @@ cursor: default; border-top: 1px solid #dee2e6; padding: 0.25rem 0.75rem; + scroll-margin-top: 10.5rem; } li.record:nth-child(even) { background-color: rgba(0, 0, 0, 0.05); } + ul.scroller.list-skinny li.record { + scroll-margin-top: 0; + } li.record.active { color: #fff; background-color: #0d6efd; @@ -149,6 +153,7 @@ cursor: default; } div.detail { + scroll-margin-top: calc(3.6875rem + 2.5625rem + 25vh); font-family: monospace; white-space: pre-wrap; } @@ -161,6 +166,7 @@ } div.detail { max-height: 75vh; + scroll-margin-top: 0; overflow-y: auto; } } @@ -481,6 +487,29 @@ for(var i = 0; i < value.length; ++i) if(value[i].id == id) return this.selection = value[i]; this.selection = null; } + }, + async selection(value) { + if(this.$refs.scroller) { + if(value) { // scroll to selected item + await this.$nextTick(); + var active = this.$refs.scroller.querySelectorAll(':scope > .active'); + if(active.length > 0) (Element.prototype.scrollIntoViewIfNeeded || Element.prototype.scrollIntoView).call(active[0]); + if(this.$refs.detail) { // scroll to top of detail panel + this.$refs.detail.scrollIntoView(); + this.$refs.detail.scrollTop = 0; + } + } else { // scroll to topmost item + var offset = this.$refs.scroller.getBoundingClientRect().top; + for(var children = this.$refs.scroller.children, count = children.length, i = 0; i < count; ++i) if(children[i].getBoundingClientRect().top >= offset) { + await this.$nextTick(); + var behavior = document.documentElement.style.scrollBehavior; + document.documentElement.style.scrollBehavior = 'auto'; // inhibit Bootstrap smooth scrolling + children[i].scrollIntoView(); + document.documentElement.style.scrollBehavior = behavior; + break; + } + } + } } }, methods: {