mirror of
https://github.com/FH-Complete/FHC-Core.git
synced 2026-07-26 09:04:28 +00:00
Calendar: ResizeObserver for compact day mode
This commit is contained in:
@@ -3,6 +3,8 @@ import LabelDay from '../../Base/Label/Day.js';
|
|||||||
import LabelDow from '../../Base/Label/Dow.js';
|
import LabelDow from '../../Base/Label/Dow.js';
|
||||||
import LabelTime from '../../Base/Label/Time.js';
|
import LabelTime from '../../Base/Label/Time.js';
|
||||||
|
|
||||||
|
import { useResizeObserver } from '../../../../composables/Responsive.js';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "DayView",
|
name: "DayView",
|
||||||
components: {
|
components: {
|
||||||
@@ -22,8 +24,7 @@ export default {
|
|||||||
required: true
|
required: true
|
||||||
},
|
},
|
||||||
emptyMessage: String,
|
emptyMessage: String,
|
||||||
emptyMessageDetails: String,
|
emptyMessageDetails: String
|
||||||
compact: Boolean
|
|
||||||
},
|
},
|
||||||
emits: [
|
emits: [
|
||||||
"requestModalOpen",
|
"requestModalOpen",
|
||||||
@@ -104,11 +105,21 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
setup() {
|
||||||
|
const container = Vue.ref(null); // use useTemplateRef when updating to Vue 3.5
|
||||||
|
const { compact } = useResizeObserver(container, 750);
|
||||||
|
|
||||||
|
return {
|
||||||
|
container, // must be exposed or it won't be set in Vue < 3.5
|
||||||
|
compact
|
||||||
|
};
|
||||||
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.gridMainRef = this.$refs.grid.$refs.main;
|
this.gridMainRef = this.$refs.grid.$refs.main;
|
||||||
},
|
},
|
||||||
template: /* html */`
|
template: /* html */`
|
||||||
<div
|
<div
|
||||||
|
ref="container"
|
||||||
class="fhc-calendar-mode-day-view d-flex h-100"
|
class="fhc-calendar-mode-day-view d-flex h-100"
|
||||||
@cal-click-default.capture="handleClickDefaults"
|
@cal-click-default.capture="handleClickDefaults"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -34,8 +34,7 @@ export default {
|
|||||||
modeOptions: {
|
modeOptions: {
|
||||||
day: {
|
day: {
|
||||||
emptyMessage: Vue.computed(() => this.$p.t('lehre/noLvFound')),
|
emptyMessage: Vue.computed(() => this.$p.t('lehre/noLvFound')),
|
||||||
emptyMessageDetails: Vue.computed(() => this.$p.t('lehre/noLvFound')),
|
emptyMessageDetails: Vue.computed(() => this.$p.t('lehre/noLvFound'))
|
||||||
compact: false
|
|
||||||
},
|
},
|
||||||
week: {
|
week: {
|
||||||
collapseEmptyDays: false
|
collapseEmptyDays: false
|
||||||
|
|||||||
@@ -32,8 +32,7 @@ export default {
|
|||||||
modeOptions: {
|
modeOptions: {
|
||||||
day: {
|
day: {
|
||||||
emptyMessage: Vue.computed(() => this.$p.t('rauminfo/keineRaumReservierung')),
|
emptyMessage: Vue.computed(() => this.$p.t('rauminfo/keineRaumReservierung')),
|
||||||
emptyMessageDetails: Vue.computed(() => this.$p.t('rauminfo/keineRaumReservierung')),
|
emptyMessageDetails: Vue.computed(() => this.$p.t('rauminfo/keineRaumReservierung'))
|
||||||
compact: false
|
|
||||||
},
|
},
|
||||||
week: {
|
week: {
|
||||||
collapseEmptyDays: false
|
collapseEmptyDays: false
|
||||||
|
|||||||
@@ -0,0 +1,85 @@
|
|||||||
|
/**
|
||||||
|
* size returns the key of smallest threshold array (integer converts to
|
||||||
|
* { compact: threshold }) entry that is bigger than the current width of
|
||||||
|
* the element or 'full' if none is found.
|
||||||
|
* compact is true if the smallest threshold array entry is bigger than the
|
||||||
|
* current width or false otherwise.
|
||||||
|
*
|
||||||
|
* @param DOMElement|VueTemplateRef element
|
||||||
|
* @param object|array|integer threshold
|
||||||
|
* @return object { compact:Boolean, size:String }
|
||||||
|
*/
|
||||||
|
export function useResizeObserver(element, threshold) {
|
||||||
|
/* Result Vars */
|
||||||
|
const compact = Vue.ref(false);
|
||||||
|
const size = Vue.ref(false);
|
||||||
|
|
||||||
|
/* Helper Vars */
|
||||||
|
const mounted = Vue.ref(false);
|
||||||
|
const elementRef = Vue.computed(() => {
|
||||||
|
if (!Vue.isRef(element))
|
||||||
|
return element;
|
||||||
|
|
||||||
|
if (!element.value)
|
||||||
|
return element.value;
|
||||||
|
|
||||||
|
if (element.value.$el) // Maybe there is a better test
|
||||||
|
return element.value.$el;
|
||||||
|
|
||||||
|
return element.value;
|
||||||
|
});
|
||||||
|
const compareArray = Vue.computed(() => {
|
||||||
|
const input = Vue.isRef(threshold) ? threshold.value : threshold;
|
||||||
|
if (Number.isInteger(input))
|
||||||
|
return [['compact', input]];
|
||||||
|
if (Array.isArray(input))
|
||||||
|
return input.map((value, key) => [key, value]).sort((a, b) => a[1]-b[1]);
|
||||||
|
return Object.entries(input).sort((a, b) => a[1]-b[1]);
|
||||||
|
});
|
||||||
|
|
||||||
|
/* Helper Functions */
|
||||||
|
function updateResultVars() {
|
||||||
|
const compare = threshold.value || threshold;
|
||||||
|
if (elementRef.value.offsetWidth === undefined)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const found = compareArray.value.find(compare => compare[1] > elementRef.value.offsetWidth);
|
||||||
|
|
||||||
|
size.value = found ? found[0] : 'full';
|
||||||
|
compact.value = (size.value == compareArray.value[0][0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Observer */
|
||||||
|
const observer = new ResizeObserver(() => {
|
||||||
|
if (elementRef.value) {
|
||||||
|
updateResultVars();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
/* Observer Helper Functions */
|
||||||
|
function addObserver() {
|
||||||
|
if (!elementRef.value)
|
||||||
|
return;
|
||||||
|
|
||||||
|
updateResultVars();
|
||||||
|
observer.observe(elementRef.value);
|
||||||
|
mounted.value = true;
|
||||||
|
}
|
||||||
|
function removeObserver() {
|
||||||
|
if (mounted.value) {
|
||||||
|
observer.disconnect()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Main Logic */
|
||||||
|
Vue.onMounted(addObserver);
|
||||||
|
Vue.onUnmounted(removeObserver);
|
||||||
|
|
||||||
|
Vue.watchEffect(() => {
|
||||||
|
if (elementRef.value) {
|
||||||
|
removeObserver();
|
||||||
|
addObserver();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return { compact, size };
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user