mirror of
https://github.com/FH-Complete/FHC-Core.git
synced 2026-07-15 22:12:16 +00:00
Merge branch 'feature-25999/C4_cleanup' of github.com:FH-Complete/FHC-Core into feature-25999/C4_cleanup
This commit is contained in:
@@ -62,6 +62,7 @@ $route['api/v1/ressource/[B|b]etriebsmittelperson/(:any)'] = 'api/v1/ressource/b
|
||||
$route['api/v1/system/[S|s]prache/(:any)'] = 'api/v1/system/sprache2/$1';
|
||||
|
||||
$route['CisVue'] = 'CisVue/dashboard';
|
||||
$route['Cis/Stundenplan/(:any)'] = 'Cis/Stundenplan';
|
||||
|
||||
// load routes from extensions
|
||||
$subdir = 'application/config/extensions';
|
||||
@@ -83,5 +84,4 @@ if ($dirlist)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
$includesArray = array(
|
||||
'title' => 'Dashboard',
|
||||
'tabulator5'=>true,
|
||||
'primevue3' => true,
|
||||
'customJSModules' => ['public/js/apps/Dashboard/Fhc.js'],
|
||||
'customCSSs' => [
|
||||
'public/css/components/dashboard.css'
|
||||
|
||||
@@ -238,7 +238,7 @@ html {
|
||||
body {
|
||||
display: flex;
|
||||
padding-top: var(--fhc-cis-header-height);
|
||||
width: calc(100vw - var(--scrollbar-width, 0px));
|
||||
width: calc(100svw - var(--scrollbar-width, 0px));
|
||||
/* overflow: visible !important; */
|
||||
}
|
||||
#cis-header {
|
||||
|
||||
@@ -8,6 +8,7 @@ const app = Vue.createApp({
|
||||
data() {
|
||||
return {
|
||||
stunden: [],
|
||||
lv_id: null,
|
||||
events: null,
|
||||
calendarDate: new CalendarDate(new Date()),
|
||||
currentlySelectedEvent: null,
|
||||
@@ -35,6 +36,9 @@ const app = Vue.createApp({
|
||||
|
||||
},
|
||||
methods:{
|
||||
getLvID: function () {
|
||||
this.lv_id = window.location.pathname
|
||||
},
|
||||
selectDay: function(day){
|
||||
this.currentDay = day;
|
||||
},
|
||||
@@ -101,11 +105,7 @@ const app = Vue.createApp({
|
||||
},
|
||||
created()
|
||||
{
|
||||
this.loadEvents();
|
||||
},
|
||||
mounted()
|
||||
{
|
||||
|
||||
this.getLvID()
|
||||
},
|
||||
//TODO: Stundenplan phrase
|
||||
template:/*html*/`
|
||||
@@ -136,6 +136,7 @@ const app = Vue.createApp({
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template
|
||||
</fhc-calendar>
|
||||
`
|
||||
});
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import FhcDashboard from '../../components/Dashboard/Dashboard.js';
|
||||
import FhcApi from '../../plugin/FhcApi.js';
|
||||
import Phrasen from '../../plugin/Phrasen.js';
|
||||
import { setScrollbarWidth } from "../../helpers/CssVarCalcHelpers";
|
||||
|
||||
const app = Vue.createApp({
|
||||
name: 'FhcApp',
|
||||
@@ -11,6 +12,9 @@ const app = Vue.createApp({
|
||||
FhcDashboard
|
||||
}
|
||||
});
|
||||
|
||||
setScrollbarWidth();
|
||||
|
||||
app.config.unwrapInjectedRef = true;
|
||||
app.use(FhcApi);
|
||||
app.use(Phrasen);
|
||||
|
||||
@@ -23,9 +23,6 @@ export default {
|
||||
},
|
||||
template: `
|
||||
<div class="fhc-calendar-minimized h-100 d-flex flex-column">
|
||||
<div class="card-header d-grid" :class="classHeader">
|
||||
<button class="btn btn-link link-secondary text-decoration-none" @click="maximize">{{ date.format({dateStyle: ['long','full','full','full'][this.size]}) }}</button>
|
||||
</div>
|
||||
<slot name="minimizedPage"></slot>
|
||||
</div>`
|
||||
}
|
||||
|
||||
@@ -31,6 +31,13 @@ export default {
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
getSectionStyle() {
|
||||
|
||||
const bgString = `background:
|
||||
linear-gradient(0deg, rgba(128, 128, 128, 0.05) 0%, rgba(128, 128, 128, 0.1) 50%, rgba(128, 128, 128, 0.05) 100%)`
|
||||
|
||||
return 'margin-bottom: 8px;' + bgString;
|
||||
},
|
||||
items() {
|
||||
return this.widgets.map(item => {
|
||||
return { ...item, ...(item.place[this.gridWidth] || {h: 1, w:1, x:0, y:0})};
|
||||
@@ -170,10 +177,10 @@ export default {
|
||||
});
|
||||
},
|
||||
template: `
|
||||
<div class="dashboard-section" ref="container">
|
||||
<h3 class="d-flex">
|
||||
<span class="col">{{name}}</span>
|
||||
<button class="col-auto btn" @click.prevent="editMode = !editMode"><i class="fa-solid fa-gear"></i></button>
|
||||
<div class="dashboard-section" ref="container" :style="getSectionStyle">
|
||||
<h3>
|
||||
<span >{{$p.t('ui/section' + name)}}</span>
|
||||
<button style="margin-left: 8px;" class="btn" @click="editMode = !editMode"><i class="fa-solid fa-gear"></i></button>
|
||||
</h3>
|
||||
<drop-grid v-model:cols="gridWidth" :items="items" :placeholders="items_placeholders" :active="editMode" :resize-limit="checkResizeLimit" :margin-for-extra-row=".01" @rearrange-items="updatePositions" @gridHeight="gridHeight=$event" >
|
||||
<template #default="item" #default>
|
||||
@@ -203,4 +210,4 @@ OLD VERSION - ON HOVER
|
||||
<template #empty-tile-hover="{x,y}">
|
||||
<div class="empty-tile-hover" @click="$emit('widgetAdd', name, { widget: 1, config: {}, place: {[gridWidth]: {x,y,w:1,h:1}}, custom: 1 })"></div>
|
||||
</template>
|
||||
*/
|
||||
*/
|
||||
@@ -21,7 +21,7 @@ export default {
|
||||
stunden: [],
|
||||
minimized: true,
|
||||
events: null,
|
||||
currentDay: new Date(),
|
||||
currentDay: this.getCurrentDate(),
|
||||
calendarDate: new CalendarDate(new Date()),
|
||||
roomInfoContentID: null,
|
||||
ort_kurzbz: null,
|
||||
@@ -29,7 +29,19 @@ export default {
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
||||
allEventsGrouped() {
|
||||
// groups all events of all days until end of week together
|
||||
const currentCalendarDate = new CalendarDate(this.currentDay)
|
||||
const mapArr = currentCalendarDate.wholeWorkWeek.map((d) => [new CalendarDate(d), []])
|
||||
|
||||
return new Map((this.events || []).filter(evt => evt.end < currentCalendarDate.lastDayOfWeek && evt.start >= currentCalendarDate.firstDayOfWeek).reduce((acc, cur) => {
|
||||
const date = new CalendarDate(new Date(cur.datum))
|
||||
const arr = acc.find(el => el[0].compare(date))
|
||||
arr[1].push(cur)
|
||||
|
||||
return acc
|
||||
}, mapArr))
|
||||
},
|
||||
currentEvents() {
|
||||
return (this.events || []).filter(evt => evt.end < this.dayAfterCurrentDay && evt.start >= this.currentDay);
|
||||
},
|
||||
@@ -46,6 +58,17 @@ export default {
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
getEventStyle: function(evt) {
|
||||
const styles = {'background-color': evt.color};
|
||||
if(evt.start.getTime() < Date.now()) styles.opacity = 0.5;
|
||||
|
||||
return styles;
|
||||
},
|
||||
getCurrentDate: function() {
|
||||
const today = new Date()
|
||||
today.setHours(0,0,0)
|
||||
return today
|
||||
},
|
||||
calendarDateToString: function (calendarDate) {
|
||||
|
||||
return calendarDate instanceof CalendarDate ?
|
||||
@@ -127,6 +150,10 @@ export default {
|
||||
this.events = promise_events;
|
||||
});
|
||||
},
|
||||
|
||||
setCalendarMaximized() {
|
||||
this.minimized = false
|
||||
}
|
||||
|
||||
|
||||
},
|
||||
@@ -162,12 +189,15 @@ export default {
|
||||
<content-modal :contentID="roomInfoContentID" :ort_kurzbz="" dialogClass="modal-lg" ref="contentModal"/>
|
||||
<fhc-calendar @change:range="updateRange" :initial-date="currentDay" class="border-0" class-header="p-0" @select:day="selectDay" v-model:minimized="minimized" :events="events" no-week-view :show-weeks="false" >
|
||||
<template #minimizedPage >
|
||||
<div class="flex-grow-1 overflow-scroll">
|
||||
<div class="flex-grow-1" style="overflow-y: scroll; overflow-x: hidden">
|
||||
<div v-if="events === null" class="d-flex h-100 justify-content-center align-items-center">
|
||||
<i class="fa-solid fa-spinner fa-pulse fa-3x"></i>
|
||||
</div>
|
||||
<div v-else-if="currentEvents.length" class="list-group list-group-flush">
|
||||
<div role="button" @click="showLvUebersicht(evt)" class="" v-for="evt in currentEvents" :key="evt.id" class="list-group-item small" :style="{'background-color':evt.color}">
|
||||
<template ref="allWeek" v-else-if="allEventsGrouped.size" v-for="([key, value], index) in allEventsGrouped" :key="index" style="margin-top: 8px;">
|
||||
<div class="card-header d-grid p-0">
|
||||
<button class="btn btn-link link-secondary text-decoration-none" @click="setCalendarMaximized">{{ key.format({dateStyle: "full"})}}</button>
|
||||
</div>
|
||||
<div role="button" @click="showLvUebersicht(evt)" v-for="evt in value" :key="evt.id" class="list-group-item small" :style="getEventStyle(evt)">
|
||||
<b>{{evt.topic}}</b>
|
||||
<br>
|
||||
<small class="d-flex w-100 justify-content-between">
|
||||
@@ -176,13 +206,13 @@ export default {
|
||||
<span>{{evt.start.toLocaleTimeString(undefined, {hour:'numeric',minute:'numeric'})}}-{{evt.end.toLocaleTimeString(undefined, {hour:'numeric',minute:'numeric'})}}</span>
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<div v-else class="d-flex h-100 justify-content-center align-items-center fst-italic text-center">
|
||||
{{ p.t('lehre/noLvFound') }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</fhc-calendar>
|
||||
|
||||
</div>
|
||||
</div>`
|
||||
}
|
||||
@@ -61,6 +61,8 @@ export default {
|
||||
return {
|
||||
'--fhc-dg-row-height': 100/(this.rows + addH) + '%',
|
||||
'--fhc-dg-col-width': 100/this.cols + '%',
|
||||
'--fhc-dg-item-padding-horizontal': '0.5%',
|
||||
'--fhc-dg-item-padding-top': '0.5%',
|
||||
'padding-bottom': 100 * (this.rows + addH)/this.cols + '%'
|
||||
}
|
||||
},
|
||||
@@ -130,9 +132,12 @@ export default {
|
||||
cols() {
|
||||
this.dragCancel();
|
||||
},
|
||||
rows(value){
|
||||
this.$emit('gridHeight',value);
|
||||
},
|
||||
rows: {
|
||||
handler(value) {
|
||||
this.$emit('gridHeight', value);
|
||||
},
|
||||
immediate: true
|
||||
},
|
||||
indexedItems: {
|
||||
handler(value) {
|
||||
this.dragCancel();
|
||||
@@ -366,7 +371,10 @@ export default {
|
||||
top: 'calc(' + item.y + ' * var(--fhc-dg-row-height))',
|
||||
left: 'calc(' + item.x + ' * var(--fhc-dg-col-width))',
|
||||
width: 'calc(' + item.w + ' * var(--fhc-dg-col-width))',
|
||||
height: 'calc(' + item.h + ' * var(--fhc-dg-row-height))'
|
||||
height: 'calc(' + item.h + ' * var(--fhc-dg-row-height))',
|
||||
paddingTop: 'var(--fhc-dg-item-padding-top)',
|
||||
paddingLeft: 'var(--fhc-dg-item-padding-horizontal)',
|
||||
paddingRight: 'var(--fhc-dg-item-padding-horizontal)'
|
||||
}">
|
||||
<template v-slot="item">
|
||||
<slot v-bind="item.data" v-bind="item" :x="item.x" :y="item.y" ></slot>
|
||||
|
||||
@@ -68,6 +68,15 @@ class CalendarDate {
|
||||
lastDayOfWeek.setDate(this.d -(lastDayOfWeek.getDay()+7-this.weekStart)%7 +6);
|
||||
return lastDayOfWeek;
|
||||
}
|
||||
get wholeWorkWeek() {
|
||||
const days = []
|
||||
const date = new Date(this.y, this.m, this.d);
|
||||
for(let i = 0; i < 5; i++) {
|
||||
days[i] = new Date(this.y, this.m, this.d)
|
||||
days[i].setDate(this.d -(date.getDay()+7-this.weekStart)%7 + i)
|
||||
}
|
||||
return days
|
||||
}
|
||||
get cdLastDayOfWeek() {
|
||||
return new CalendarDate(this.lastDayOfWeek);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
// Create a temporary div element, set styles to ensure it's scrollable and off-screen, get scrollbar width from that
|
||||
function getScrollbarWidth() {
|
||||
const div = document.createElement('div');
|
||||
|
||||
div.style.position = 'absolute';
|
||||
div.style.top = '-9999px';
|
||||
div.style.width = '100px';
|
||||
div.style.height = '100px';
|
||||
div.style.overflow = 'scroll';
|
||||
|
||||
document.body.appendChild(div);
|
||||
const scrollbarWidth = div.offsetWidth - div.clientWidth;
|
||||
document.body.removeChild(div);
|
||||
|
||||
return scrollbarWidth;
|
||||
}
|
||||
|
||||
// Detect the browser and set a CSS variable for the scrollbar width since chrome scrollbars mess with 100vw/vh css
|
||||
export function setScrollbarWidth() {
|
||||
const isChromium = /Chrome/.test(navigator.userAgent);
|
||||
const isFirefox = /Firefox/.test(navigator.userAgent);
|
||||
|
||||
if (isChromium) {
|
||||
const width = getScrollbarWidth() + 'px';
|
||||
document.body.style.setProperty('--scrollbar-width', width); // Set the value for Chrome
|
||||
} else if (isFirefox) {
|
||||
document.body.style.setProperty('--scrollbar-width', '0px'); // Set the value for Firefox or adjust as needed
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user