mirror of
https://github.com/FH-Complete/FHC-Core.git
synced 2026-10-12 15:04:04 +00:00
Merge remote-tracking branch 'origin/feature-78288/tempus_usability' into feature-68298/Tempus_Grundstruktur
# Conflicts: # public/css/components/horizontalsplit.css # public/js/components/Tempus/Filters/searchbarOptions.js
This commit is contained in:
@@ -86,9 +86,18 @@ class KalenderLib
|
||||
tbl_lehreinheitgruppe.verband as le_verband,
|
||||
tbl_lehreinheitgruppe.gruppe as le_gruppe,
|
||||
le_gruppe.direktinskription as le_direktinskription,
|
||||
|
||||
|
||||
');
|
||||
CASE
|
||||
WHEN vonstunde.stunde IS NOT NULL AND bisstunde.stunde IS NOT NULL
|
||||
THEN bisstunde.stunde - vonstunde.stunde + 1
|
||||
ELSE ROUND(
|
||||
COALESCE(
|
||||
(
|
||||
SELECT SUM(EXTRACT(EPOCH FROM (LEAST(stunde.ende, tbl_kalender.bis::time) - GREATEST(stunde.beginn, tbl_kalender.von::time))) / 60) / 45
|
||||
FROM lehre.tbl_stunde stunde
|
||||
WHERE stunde.beginn < tbl_kalender.bis::time AND stunde.ende > tbl_kalender.von::time)
|
||||
,0)
|
||||
,2
|
||||
) END AS verplante_stunden');
|
||||
|
||||
$this->_ci->KalenderModel->addJoin('lehre.tbl_kalender_lehreinheit', 'tbl_kalender.kalender_id = tbl_kalender_lehreinheit.kalender_id', 'LEFT');
|
||||
$this->_ci->KalenderModel->addJoin('lehre.tbl_kalender_event', 'tbl_kalender.kalender_id = tbl_kalender_event.kalender_id', 'LEFT');
|
||||
@@ -134,6 +143,9 @@ class KalenderLib
|
||||
);
|
||||
$this->_ci->KalenderModel->addJoin('public.tbl_studiengang le_studiengang', 'le_lehrverband.studiengang_kz = le_studiengang.studiengang_kz', 'LEFT');
|
||||
|
||||
$this->_ci->KalenderModel->db->join('lehre.tbl_stunde vonstunde', 'tbl_kalender.von::time = vonstunde.beginn', 'LEFT', FALSE);
|
||||
$this->_ci->KalenderModel->db->join('lehre.tbl_stunde bisstunde', 'tbl_kalender.bis::time = bisstunde.ende', 'LEFT', FALSE);
|
||||
|
||||
$this->_ci->KalenderModel->db->where('tbl_kalender.von >=', $start_date);
|
||||
$this->_ci->KalenderModel->db->where('tbl_kalender.bis <', $end_date);
|
||||
|
||||
@@ -174,6 +186,7 @@ class KalenderLib
|
||||
'lehrfach_bez' => isset($row->lehrfach_bezeichnung) ? $row->lehrfach_bezeichnung : '',
|
||||
'farbe' => isset($row->farbe) ? $row->farbe : '',
|
||||
'lehrveranstaltung_id' => $row->lehrveranstaltung_id,
|
||||
'verplante_stunden' => $row->verplante_stunden,
|
||||
'organisationseinheit' => isset($row->oe_kurzbz) ? $row->oe_kurzbz : '',
|
||||
'kalender_id' => $id,
|
||||
'lehreinheit_id' => [],
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
@import './components/Notiz.css';
|
||||
@import './components/Messages.css';
|
||||
@import './components/AppMenu.css';
|
||||
@import './components/horizontalsplit.css';
|
||||
|
||||
|
||||
html {
|
||||
font-size: .875em;
|
||||
|
||||
@@ -68,9 +68,16 @@
|
||||
/* Grid */
|
||||
.fhc-calendar-base-grid {
|
||||
--fhc-calendar-axis-collapsible: .2fr;
|
||||
--fhc-calendar-axis-collapsible-manual: .1fr;
|
||||
|
||||
background-color: var(--fhc-calendar-bg-gap);
|
||||
grid-gap: var(--fhc-calendar-gap-header, calc(var(--fhc-calendar-gap, 1px) * 2));
|
||||
}
|
||||
|
||||
.fhc-calendar-base-grid-line-collapsed {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.fhc-calendar-base-grid .grid-header {
|
||||
background-color: var(--fhc-calendar-bg-header-gap, var(--fhc-calendar-bg-gap));
|
||||
}
|
||||
|
||||
@@ -61,7 +61,11 @@ export default {
|
||||
flipAxis: Boolean,
|
||||
allDayEvents: Boolean,
|
||||
axisMainCollapsible: Boolean,
|
||||
snapToGrid: Boolean
|
||||
snapToGrid: Boolean,
|
||||
dayVisibility: {
|
||||
type: Array,
|
||||
default: null
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@@ -160,7 +164,17 @@ export default {
|
||||
hasValidEvents() {
|
||||
return this.events.find(e => e.length);
|
||||
},
|
||||
styleGridCols() {
|
||||
styleGridCols()
|
||||
{
|
||||
if (this.dayVisibility)
|
||||
{
|
||||
let anyVisible = this.dayVisibility.some(day => day);
|
||||
if (anyVisible)
|
||||
{
|
||||
return this.axisMain.map((day, i) => this.isDayCollapsed(i) ? 'var(--fhc-calendar-axis-collapsible-manual, 0.1fr)' : '1fr').join(' ');
|
||||
}
|
||||
}
|
||||
|
||||
let cols = 'repeat(' + this.axisMain.length + ', 1fr)';
|
||||
if (this.axisMainCollapsible) {
|
||||
if (this.hasValidEvents)
|
||||
@@ -479,6 +493,16 @@ export default {
|
||||
}
|
||||
});
|
||||
},
|
||||
isDayCollapsed(index)
|
||||
{
|
||||
if (this.dayVisibility)
|
||||
{
|
||||
let anyVisible = this.dayVisibility.some(day => day);
|
||||
if (anyVisible)
|
||||
return !this.dayVisibility[index];
|
||||
}
|
||||
return this.axisMainCollapsible && this.hasValidEvents && !this.events[index].length;
|
||||
}
|
||||
},
|
||||
setup()
|
||||
{
|
||||
@@ -504,7 +528,7 @@ export default {
|
||||
v-for="(date, index) in axisMain"
|
||||
:key="index"
|
||||
class="main-header"
|
||||
:class="{'collapsed-header': axisMainCollapsible && hasValidEvents && !events[index].length}"
|
||||
:class="{'collapsed-header': isDayCollapsed(index)}"
|
||||
:style="'grid-' + axisCol + ':' + (2+index)"
|
||||
>
|
||||
<slot name="main-header" v-bind="{ index, date }" />
|
||||
@@ -592,6 +616,7 @@ export default {
|
||||
:date="date"
|
||||
:events="eventsNormal[index]"
|
||||
:backgrounds="backgrounds[index]"
|
||||
:class="{ 'fhc-calendar-base-grid-line-collapsed': isDayCollapsed(index) }"
|
||||
style="position:relative"
|
||||
@resize-start="handleResizeStart"
|
||||
:style="'grid-' + axisRow + ':1/-1;grid-' + axisCol + ':' + (1+index)"
|
||||
|
||||
@@ -2,6 +2,8 @@ import CalendarGrid from '../../Base/Grid.js';
|
||||
import LabelDay from '../../Base/Label/Day.js';
|
||||
import LabelDow from '../../Base/Label/Dow.js';
|
||||
import LabelTime from '../../Base/Label/Time.js';
|
||||
import FormInput from "../../../Form/Input.js";
|
||||
|
||||
|
||||
export default {
|
||||
name: "WeekView",
|
||||
@@ -9,7 +11,8 @@ export default {
|
||||
CalendarGrid,
|
||||
LabelDay,
|
||||
LabelDow,
|
||||
LabelTime
|
||||
LabelTime,
|
||||
FormInput
|
||||
},
|
||||
inject: {
|
||||
timeGrid: "timeGrid",
|
||||
@@ -23,6 +26,11 @@ export default {
|
||||
},
|
||||
collapseEmptyDays: Boolean
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
visibleDays: JSON.parse(localStorage.getItem('fhc-calender-visible-days')) ?? [true, true, true, true, true, true, true]
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
start() {
|
||||
return this.day.startOf('week', { useLocaleWeeks: true });
|
||||
@@ -44,11 +52,19 @@ export default {
|
||||
const end = this.hoursPlan?.end ?? 23;
|
||||
return Array.from({ length: end - start + 1 }, (e, i) => luxon.Duration.fromObject({ hours: i + start }));
|
||||
}
|
||||
},
|
||||
dayVisibility() {
|
||||
return this.axisMain.map(date => this.visibleDays[date.weekday -1])
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
isToday(date) {
|
||||
return date.hasSame(luxon.DateTime.now().setZone(this.timezone), 'day');
|
||||
},
|
||||
toggleDay(day)
|
||||
{
|
||||
this.visibleDays.splice(day, 1, !this.visibleDays[day])
|
||||
localStorage.setItem('fhc-calender-visible-days', JSON.stringify(this.visibleDays))
|
||||
}
|
||||
},
|
||||
template: /* html */`
|
||||
@@ -60,9 +76,10 @@ export default {
|
||||
:axis-main-collapsible="collapseEmptyDays"
|
||||
:snap-to-grid="!!timeGrid"
|
||||
all-day-events
|
||||
:day-visibility="dayVisibility"
|
||||
>
|
||||
<template #main-header="{ date }">
|
||||
<div :class="{ today: isToday(date) }">
|
||||
<template #main-header="{ date, index }">
|
||||
<div :class="{ today: isToday(date) }" class="d-flex flex-column align-items-center">
|
||||
<label-dow
|
||||
v-bind="{ date }"
|
||||
@cal-click="evt => evt.detail.source = 'day'"
|
||||
@@ -70,6 +87,13 @@ export default {
|
||||
<label-day
|
||||
v-bind="{ date }"
|
||||
/>
|
||||
<form-input
|
||||
type="checkbox"
|
||||
:checked="visibleDays[date.weekday - 1]"
|
||||
@change="toggleDay(date.weekday - 1)"
|
||||
@click.stop
|
||||
>
|
||||
</form-input>
|
||||
</div>
|
||||
</template>
|
||||
<template #part-header="{ part }">
|
||||
|
||||
@@ -51,6 +51,17 @@ export function getTempusSearchbarOptions(self)
|
||||
self.addToCoursePicker(data);
|
||||
}
|
||||
},
|
||||
{
|
||||
label: "LVVerwaltung",
|
||||
icon: "fas fa-up-right-from-square",
|
||||
type: "function",
|
||||
action: (data) => {
|
||||
const link = FHC_JS_DATA_STORAGE_OBJECT.app_root +
|
||||
FHC_JS_DATA_STORAGE_OBJECT.ci_router +
|
||||
"/LVVerwaltung/emp/" + self.selectedStudiensemester + "/" + data.uid;
|
||||
window.open(link, "_blank");
|
||||
}
|
||||
},
|
||||
]
|
||||
},
|
||||
}
|
||||
|
||||
@@ -15,6 +15,15 @@ export default {
|
||||
|
||||
return classes;
|
||||
},
|
||||
statusIcon()
|
||||
{
|
||||
if (['planning', 'sync_preview'].includes(this.event.status_kurzbz))
|
||||
return 'fa-solid fa-pen-ruler text-muted';
|
||||
else if (['preview', 'sync_live', 'to_delete_preview'].includes(this.event.status_kurzbz))
|
||||
return 'fa-solid fa-chalkboard-user text-muted';
|
||||
else if (['live', 'to_delete_live'].includes(this.event.status_kurzbz))
|
||||
return 'fa-solid fa-user-graduate text-muted'
|
||||
},
|
||||
topicString() {
|
||||
return Array.isArray(this.event.topic) ? this.event.topic.join(', ') : this.event.topic;
|
||||
},
|
||||
@@ -85,10 +94,12 @@ export default {
|
||||
class="position-relative"
|
||||
@wheel.stop
|
||||
>
|
||||
<div v-if="event.has_assigned_resources" class="position-absolute top-0 start-0 m-1" >
|
||||
<i
|
||||
class="fa-solid fa-table-list text-muted"
|
||||
></i>
|
||||
<div class="position-absolute top-0 start-0 m-1">
|
||||
<i :class="statusIcon"></i>
|
||||
<i class="fa-solid fa-table-list text-muted" v-if="event.has_assigned_resources"></i>
|
||||
</div>
|
||||
<div class="position-absolute bottom-0 start-0 m-1">
|
||||
{{event.verplante_stunden}}
|
||||
</div>
|
||||
<div
|
||||
v-if="!event.allDayEvent && event?.beginn && event?.ende"
|
||||
|
||||
@@ -48,6 +48,7 @@ import MultiWeekPlanModal from "./MultiWeekPlanModal.js";
|
||||
import { getTempusSearchbarOptions } from "./Filters/searchbarOptions.js";
|
||||
import RaumauswahlModal from "./RaumauswahlModal.js";
|
||||
import LehreinheitModal from "./LehreinheitModal.js";
|
||||
import HorizontalSplit from "../horizontalsplit/horizontalsplit.js";
|
||||
|
||||
export default {
|
||||
name: "Tempus",
|
||||
@@ -72,7 +73,8 @@ export default {
|
||||
KeyboardShortcuts,
|
||||
MultiWeekPlanModal,
|
||||
RaumauswahlModal,
|
||||
LehreinheitModal
|
||||
LehreinheitModal,
|
||||
HorizontalSplit
|
||||
},
|
||||
props: {
|
||||
defaultSemester: String,
|
||||
@@ -996,6 +998,13 @@ export default {
|
||||
|
||||
this.resourcesAssignmentModal.areFormButtonsDisplayed = true;
|
||||
},
|
||||
sidebarCollapsed(newVal)
|
||||
{
|
||||
if(newVal)
|
||||
this.$refs.hSplit.collapseLeft()
|
||||
else
|
||||
this.$refs.hSplit.showBoth()
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.reservierungPending = false;
|
||||
@@ -1167,7 +1176,10 @@ export default {
|
||||
<app-menu app-identifier="tempus" />
|
||||
</div>
|
||||
</aside>
|
||||
<nav id="sidebarMenu" class="bg-light offcanvas offcanvas-start col-md p-md-0 h-100 d-flex flex-column">
|
||||
|
||||
<horizontal-split ref="hSplit" :defaultRatio="[15, 85]">
|
||||
<template #left>
|
||||
<nav id="sidebarMenu" class="bg-light offcanvas offcanvas-start col-md p-md-0 h-100 w-100">
|
||||
<div class="sidebar-icons d-flex flex-row align-items-start py-2 gap-1 ps-2">
|
||||
<button
|
||||
class="btn btn-outline-secondary"
|
||||
@@ -1257,9 +1269,9 @@ export default {
|
||||
|
||||
</div>
|
||||
<stv-studiensemester v-model:studiensemester-kurzbz="selectedStudiensemester"></stv-studiensemester>
|
||||
|
||||
</nav>
|
||||
<main class="col-md-8 ms-sm-auto col-lg-9 col-xl-10">
|
||||
</template>
|
||||
<template #right>
|
||||
<fhc-calendar
|
||||
ref="calendar"
|
||||
:timezone="config.timezone"
|
||||
@@ -1279,7 +1291,8 @@ export default {
|
||||
@update:range="handleRange"
|
||||
class="responsive-calendar"
|
||||
/>
|
||||
</main>
|
||||
</template>
|
||||
</horizontal-split>
|
||||
</div>
|
||||
</div>
|
||||
<app-config ref="config" v-model="appconfig" :endpoints="configEndpoints"></app-config>
|
||||
|
||||
Reference in New Issue
Block a user