diff --git a/public/css/Studentenverwaltung.css b/public/css/Studentenverwaltung.css
index cb4b8f2e9..b0285a628 100644
--- a/public/css/Studentenverwaltung.css
+++ b/public/css/Studentenverwaltung.css
@@ -2,6 +2,7 @@
@import './SvgIcons.css';
@import './components/searchbar/searchbar.css';
@import './components/verticalsplit.css';
+@import './components/horizontalsplit.css';
@import './components/FilterComponent.css';
@import './components/Tabs.css';
@import './components/Notiz.css';
diff --git a/public/css/components/horizontalsplit.css b/public/css/components/horizontalsplit.css
new file mode 100644
index 000000000..0db03b2b4
--- /dev/null
+++ b/public/css/components/horizontalsplit.css
@@ -0,0 +1,73 @@
+:root {
+ --fhc-horizontalsplit-hsplitter-bg-color: var(--fhc-background, #eee);
+ --fhc-horizontalsplit-hsplitter-border-color: var(--fhc-border, #eee);
+ --fhc-horizontalsplit-hsplitter-splitactions-color: var(--fhc-dark, #000);
+}
+
+.horizontalsplit-container {
+ display: flex;
+ flex-direction: row;
+ overflow: hidden;
+ max-height: 100%;
+ padding: 0px;
+}
+
+.horizontalsplitted {
+ overflow: auto;
+ flex-shrink: 0;
+}
+
+.horizontalsplitter {
+ flex-shrink: 0;
+ width: 8px;
+ cursor: col-resize;
+ user-select: none;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.horizontalsplitter.left {
+ border-left: solid 3px var(--fhc-horizontalsplit-hsplitter-border-color);
+}
+
+.horizontalsplitter.right {
+ border-right: solid 3px var(--fhc-horizontalsplit-hsplitter-border-color);
+}
+
+.splitactions.horizontal {
+ background-color: var(--fhc-horizontalsplit-hsplitter-bg-color);
+ color: var(--fhc-horizontalsplit-hsplitter-splitactions-color);
+ display: flex;
+ flex-direction: column;
+ padding: 5px 0 5px 0;
+}
+
+.splitactions.horizontal.left {
+ border-radius: 0 40% 40% 0;
+}
+
+.splitactions.horizontal.right {
+ border-radius: 40% 0 0 40%;
+}
+
+.splitactions.horizontal .splitaction {
+ width: auto;
+ height: 28px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.splitactions.horizontal .splitaction.resize {
+ cursor: col-resize;
+}
+
+#content {
+ padding-top: 0 !important;
+ padding-bottom: 0 !important;
+}
+
+#content > div:first-child {
+ margin-top: 30px;
+}
\ No newline at end of file
diff --git a/public/js/components/Stv/Studentenverwaltung.js b/public/js/components/Stv/Studentenverwaltung.js
index 66ff7f891..4c57c56f9 100644
--- a/public/js/components/Stv/Studentenverwaltung.js
+++ b/public/js/components/Stv/Studentenverwaltung.js
@@ -18,6 +18,7 @@
import CoreSearchbar from "../searchbar/searchbar.js";
import NavLanguage from "../navigation/Language.js";
import VerticalSplit from "../verticalsplit/verticalsplit.js";
+import HorizontalSplit from "../horizontalsplit/horizontalsplit.js";
import AppMenu from "../AppMenu.js";
import AppConfig from "../AppConfig.js";
import StvVerband from "./Studentenverwaltung/Verband.js";
@@ -37,6 +38,7 @@ export default {
CoreSearchbar,
NavLanguage,
VerticalSplit,
+ HorizontalSplit,
AppMenu,
AppConfig,
StvVerband,
@@ -235,6 +237,10 @@ export default {
}
}
}
+ },
+ sidebarCollapsed(newVal) {
+ if(newVal) this.$refs.hSplit.collapseLeft()
+ else this.$refs.hSplit.showBoth()
}
},
methods: {
@@ -632,23 +638,30 @@ export default {
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/public/js/components/horizontalsplit/horizontalsplit.js b/public/js/components/horizontalsplit/horizontalsplit.js
new file mode 100644
index 000000000..2d91cc6a9
--- /dev/null
+++ b/public/js/components/horizontalsplit/horizontalsplit.js
@@ -0,0 +1,147 @@
+export default {
+ name: 'HorizontalSplit',
+ props: {
+ defaultRatio: {
+ type: Array,
+ default: () => [50, 50]
+ }
+ },
+ data: function () {
+ return {
+ availWidth: 0,
+ leftwidth: 0,
+ rightwidth: 0,
+ mousePosX: 0,
+ resize: false,
+ hsplitterOffset: 0,
+ selfOffsetLeft: 0
+ };
+ },
+ template: `
+
+ `,
+ mounted: function () {
+ this.calcWidths();
+ this.trackHorizontalSplitterOffsetLeft();
+ window.addEventListener('resize', this.calcWidths);
+ },
+ updated: function () {
+ this.trackHorizontalSplitterOffsetLeft();
+ },
+ beforeDestroy: function () {
+ window.removeEventListener('resize', this.calcWidths);
+ },
+ methods: {
+ calcWidths: function () {
+ var oldavailWidth = this.availWidth;
+ this.selfOffsetLeft = this.$refs.horizontalsplit.offsetLeft;
+ this.availWidth = this.$refs.horizontalsplit.offsetWidth - this.$refs.hsplitter.offsetWidth;
+
+ if ((this.leftwidth === 0 && this.rightwidth === 0) || oldavailWidth === 0) {
+ this.leftwidth = Math.floor(this.availWidth * (this.defaultRatio[0] / 100));
+ } else {
+ this.leftwidth = Math.floor(((this.leftwidth * 100) / oldavailWidth) / 100 * this.availWidth);
+ }
+ this.rightwidth = this.availWidth - this.leftwidth;
+ },
+ collapseLeft: function () {
+ this.calcWidths();
+ this.leftwidth = 0;
+ this.rightwidth = this.availWidth;
+ },
+ collapseRight: function () {
+ this.calcWidths();
+ this.leftwidth = this.availWidth;
+ this.rightwidth = 0;
+ },
+ showBoth: function () {
+ this.leftwidth = Math.floor(this.availWidth * (this.defaultRatio[0] / 100));
+ this.rightwidth = this.availWidth - this.leftwidth;
+ },
+ isCollapsed: function () {
+ if (this.leftwidth === 0) {
+ return 'left';
+ } else if (this.rightwidth === 0) {
+ return 'right';
+ } else {
+ return false;
+ }
+ },
+ dragStart: function (e) {
+ e.preventDefault();
+ e.stopPropagation();
+ window.addEventListener('mouseup', this.dragEnd);
+ window.addEventListener('mousemove', this.drag);
+ this.resize = true;
+ this.mousePosX = e.clientX;
+ },
+ drag: function (e) {
+ if (!this.resize) {
+ return;
+ }
+ e.preventDefault();
+ e.stopPropagation();
+ var offsetX = e.clientX - this.mousePosX;
+ this.leftwidth = this.leftwidth + offsetX;
+ if (this.leftwidth < 0) {
+ this.leftwidth = 0;
+ }
+ if (this.leftwidth > this.availWidth) {
+ this.leftwidth = this.availWidth;
+ }
+ this.rightwidth = this.availWidth - this.leftwidth;
+ this.mousePosX = e.clientX;
+ },
+ dragEnd: function (e) {
+ e.preventDefault();
+ e.stopPropagation();
+ window.removeEventListener('mousemove', this.drag);
+ window.removeEventListener('mouseup', this.dragEnd);
+ this.resize = false;
+ this.mousePosX = e.clientX;
+ },
+ trackHorizontalSplitterOffsetLeft: function () {
+ this.hsplitterOffset = this.$refs.hsplitter.offsetLeft;
+ }
+ },
+ computed: {
+ leftOrRightClass: function () {
+ return ((this.hsplitterOffset - this.selfOffsetLeft) <= Math.floor(this.availWidth / 2))
+ ? 'left'
+ : 'right';
+ },
+ leftwidthcss: function () {
+ return this.leftwidth + 'px';
+ },
+ rightwidthcss: function () {
+ return this.rightwidth + 'px';
+ }
+ }
+};
\ No newline at end of file
diff --git a/public/js/components/verticalsplit/verticalsplit.js b/public/js/components/verticalsplit/verticalsplit.js
index e712d1ecb..91561a1d3 100644
--- a/public/js/components/verticalsplit/verticalsplit.js
+++ b/public/js/components/verticalsplit/verticalsplit.js
@@ -1,5 +1,11 @@
export default {
name: 'VerticalSplit',
+ props: {
+ defaultRatio: {
+ type: Array,
+ default: () => [50, 50]
+ }
+ },
data: function() {
return {
availHeight: 0,
@@ -50,17 +56,22 @@ export default {
updated: function() {
this.trackVerticalSplitterOffsetTop();
},
+ beforeDestroy: function () {
+ window.removeEventListener('resize', this.calcHeights);
+ },
methods: {
calcHeights: function() {
var windowheight = window.innerHeight;
var oldavailHeight = this.availHeight;
this.selfOffsetTop = this.$refs.verticalsplit.offsetTop;
this.availHeight = windowheight - this.selfOffsetTop - this.$refs.vsplitter.offsetHeight;
+
if( (this.topheight === 0 && this.bottomheight === 0) || oldavailHeight === 0 ) {
- this.topheight = Math.floor(this.availHeight/2);
+ this.topheight = Math.floor(this.availHeight * (this.defaultRatio[0] / 100));
} else {
this.topheight = Math.floor( ((((this.topheight * 100) / oldavailHeight) / 100) * this.availHeight) );
}
+
this.bottomheight = this.availHeight - this.topheight;
},
collapseTop: function() {
@@ -74,8 +85,8 @@ export default {
this.bottomheight = 0;
},
showBoth: function() {
- this.topheight = Math.floor(this.availHeight/2);
- this.bottomheight = Math.floor(this.availHeight/2);
+ this.topheight = Math.floor(this.availHeight * (this.defaultRatio[0] / 100));
+ this.bottomheight = this.availHeight - this.topheight
},
isCollapsed: function() {
if( this.topheight === 0 ) {