Merge branch 'feature-25999/C4_cleanup' into merge_FHC4_C4

This commit is contained in:
Harald Bamberger
2025-02-14 14:58:46 +01:00
16 changed files with 210 additions and 58 deletions
+5
View File
@@ -89,6 +89,11 @@ const app = Vue.createApp({
return /Mobi|Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
}
},
provide() {
return { // provide injectable & watchable language property
language: Vue.computed(() => this.$p.user_language)
}
},
methods: {
isInternalRoute(href) {
const internalBase = window.location.origin
+1 -1
View File
@@ -368,7 +368,7 @@ export default {
</div>
</Transition>
<div>
<h1 v-if="noEventsCondition" class="m-0 text-secondary" ref="noEventsText" :style="noLvStyle">Keine Lehrveranstaltungen</h1>
<h1 v-if="noEventsCondition" class="m-0 text-secondary" ref="noEventsText" :style="noLvStyle">{{ $p.t('lehre/noLvFound') }}</h1>
<div :class="{'fhc-calendar-no-events-overlay':noEventsCondition, 'events':true}">
<div class="hours">
-2
View File
@@ -8,8 +8,6 @@ export default {
'size',
'focusDate'
],
data() {
},
computed: {
weeks(){
return [...Array(this.focusDate.numWeeks).keys()].map(i => i + 1);
+2 -2
View File
@@ -56,11 +56,11 @@ export default {
},
},
template:/*html*/`
<div v-if="!menu">No Menu available</div>
<div v-if="!menu">{{$p.t('lehre','lehrveranstaltungsUnavailable')}}</div>
<div v-else>
<div class="container" :class="containerStyles">
<div class="row g-2 justify-content-center" :class="rowStyles">
<div style="min-height:150px; min-width:150px;" class="col-12 col-lg-6 col-xl-4" v-for="(menuItem, index) in menu" :key="index">
<div style="min-height:150px; min-width:150px;" class="col-12 col-lg-6 col-xl-4" v-for="(menuItem, index) in menu" :key="index">
<a :id="menuItem.name" :class="{'dropdown-toggle':menuItem.c4_moodle_links?.length }" role="button" :href="c4_link(menuItem)"
:disabled="c4_disabled(menuItem)" :data-bs-toggle="menuItem.c4_moodle_links?.length?'dropdown':null"
class="fhc-entry p-2 w-100 text-wrap border border-1 rounded-3 d-flex flex-column align-items-center justify-content-center text-center text-decoration-none link-dark h-100">
+3 -3
View File
@@ -68,7 +68,7 @@ export default {
return BsModal.popup.bind(this)(null, options);
},
template: /*html*/ `
<bs-modal ref="modalContainer" @showBsModal="onModalShow" @hideBsModal="onModalHide" v-bind="$props" :bodyClass="''" dialogClass='modal-lg' class="bootstrap-alert" backdrop="false" >
<bs-modal ref="modalContainer" @showBsModal="onModalShow" @hideBsModal="onModalHide" v-bind="$props" :bodyClass="''" dialogClass='modal-lg' class="bootstrap-alert" :backdrop="false" >
<template v-slot:title>
<template v-if="event.titel">{{ event.titel + ' - ' + event.lehrfach_bez + ' [' + event.ort_kurzbz+']'}}</template>
<template v-else>{{ event.lehrfach_bez + ' [' + event.ort_kurzbz+']'}}</template>
@@ -77,7 +77,7 @@ export default {
<h3 >{{$p.t('lvinfo','lehrveranstaltungsinformationen')}}</h3>
<lv-info :event="event"></lv-info>
<template v-if="showMenu">
<h3 >Lehrveranstaltungs Menu</h3>
<h3>{{$p.t('lehre','lehrveranstaltungsmenue')}}</h3>
<lv-menu :menu="menu"></lv-menu>
</template>
</template>
@@ -87,4 +87,4 @@ export default {
</template>
<!-- end of optional footer -->
</bs-modal>`,
};
};
@@ -66,6 +66,7 @@ export default {
return bodyStyle;
},
grade() {
// TODO: noten phrasen
return this.benotung ? this.znote || this.lvnote || null : null;
},
LvHasPruefungenInformation(){
@@ -159,7 +160,7 @@ export default {
<div class="p-2" :class="is_organisatorische_einheit?'':'card-header'">
<!-- {{module}} if the module of the lv is important then query the module from the api endpoint for LV-->
<h6 class="fw-bold" v-if="is_organisatorische_einheit" >Organisatorische Einheit:</h6>
<h6 class="fw-bold" v-if="is_organisatorische_einheit" >{{ $p.t('lehre/organisationseinheit') }}:</h6>
<h6 class="mb-0">{{bezeichnung}}</h6>
</div>
<div v-if="!emptyMenu" class="card-body " :style="bodyStyle">
@@ -197,14 +198,14 @@ export default {
<template v-if="LvHasPruefungenInformation">
<a href="#" class="col-auto text-start text-decoration-none" @click.prevent="openPruefungen">
<i class="fa fa-check text-success" v-if="positiv"></i>
<span class="ps-1" :style="'color:'+gradeColor">{{ grade || p.t('lehre/noGrades') }}</span>
<span class="ps-1" :style="'color:'+gradeColor">{{ grade || $p.t('lehre/noGrades') }}</span>
</a>
</template>
<!-- template for the LV with no pruefungen -->
<template v-else>
<span class="col-auto text-start text-decoration-none" >
<i class="fa fa-check text-success" v-if="positiv"></i>
<span class="ps-1" :style="'color:'+gradeColor">{{ grade || p.t('lehre/noGrades') }}</span>
<span class="ps-1" :style="'color:'+gradeColor">{{ grade || $p.t('lehre/noGrades') }}</span>
</span>
</template>
</div>
+2 -2
View File
@@ -103,7 +103,7 @@ export default {
<button class="btn btn-outline-secondary" type="button" :disabled="currentIsFirst" @click="prevSem">
<i class="fa fa-caret-left" aria-hidden="true"></i>
</button>
<select ref="studiensemester" v-model="currentSemester" class="form-select" :aria-label="p.t('global/studiensemester_auswaehlen')" @change="setHash($event.target.value)">
<select ref="studiensemester" v-model="currentSemester" class="form-select" :aria-label="$p.t('global/studiensemester_auswaehlen')" @change="setHash($event.target.value)">
<option v-for="semester in studiensemester" :key="semester.studiensemester_kurzbz">{{semester.studiensemester_kurzbz}}</option>
</select>
<button class="btn btn-outline-secondary" type="button" :disabled="currentIsLast" @click="nextSem">
@@ -113,7 +113,7 @@ export default {
</div>
</div>
<div class="alert alert-danger" role="alert" v-else>
{{p.t('lehre/noLvFound')}}
{{$p.t('lehre/noLvFound')}}
</div>
<mylv-semester v-bind="current"/>
</div>
@@ -25,7 +25,7 @@ export default {
ProfilInformation,
},
inject: ["sortProfilUpdates", "collapseFunction"],
inject: ["sortProfilUpdates", "collapseFunction", "language"],
data() {
return {
@@ -56,21 +56,21 @@ export default {
visible: true
},
{
title: "Bezeichnung",
title: Vue.computed(() => this.$p.t('ui/bezeichnung')),
field: "Bezeichnung",
headerFilter: true,
minWidth: 200,
visible: true
},
{
title: "Organisationseinheit",
title: Vue.computed(() => this.$p.t('lehre/organisationseinheit')),
field: "Organisationseinheit",
headerFilter: true,
minWidth: 200,
visible: true
},
{
title: "Gültig_von",
title: Vue.computed(() => this.$p.t('global/gueltigVon')),
field: "Gültig_von",
headerFilter: true,
resizable: true,
@@ -78,7 +78,7 @@ export default {
visible: true
},
{
title: "Gültig_bis",
title: Vue.computed(() => this.$p.t('global/gueltigBis')),
field: "Gültig_bis",
headerFilter: true,
resizable: true,
@@ -86,7 +86,7 @@ export default {
visible: true
},
{
title: "Wochenstunden",
title: Vue.computed(() => this.$p.t('profil/wochenstunden')),
field: "Wochenstunden",
headerFilter: true,
minWidth: 200,
@@ -96,6 +96,10 @@ export default {
},
betriebsmittel_table_options: {
persistenceID: "filterTableMaProfilBetriebsmittel",
persistence: {
columns: false
},
height: 300,
layout: "fitColumns",
responsiveLayout: "collapse",
@@ -115,14 +119,14 @@ export default {
visible: true
},
{
title: "Betriebsmittel",
title: Vue.computed(() => this.$p.t('profil/entlehnteBetriebsmittel')),
field: "betriebsmittel",
headerFilter: true,
minWidth: 200,
visible: true
},
{
title: "Nummer",
title: Vue.computed(() => this.$p.t('profil/inventarnummer')),
field: "Nummer",
headerFilter: true,
resizable: true,
@@ -130,7 +134,7 @@ export default {
visible: true
},
{
title: "Ausgegeben_am",
title: Vue.computed(() => this.$p.t('profil/ausgabedatum')),
field: "Ausgegeben_am",
headerFilter: true,
minWidth: 200,
@@ -145,17 +149,14 @@ export default {
data: Object,
editData: Object,
},
'data.funktionen'(newVal) {
if(this.$refs.funktionenTable) this.$refs.funktionenTable.tabulator.setData(newVal);
},
'data.mittel'(newVal) {
if(this.$refs.betriebsmittelTable) this.$refs.betriebsmittelTable.tabulator.setData(newVal);
},
methods: {
betriebsmittelTableBuilt: function () {
this.$refs.betriebsmittelTable.tabulator.setColumns(this.betriebsmittel_table_options.columns)
this.$refs.betriebsmittelTable.tabulator.setData(this.data.mittel);
},
funktionenTableBuilt: function () {
this.$refs.funktionenTable.tabulator.setColumns(this.funktionen_table_options.columns)
this.$refs.funktionenTable.tabulator.setData(this.data.funktionen);
},
hideEditProfilModal: function () {
@@ -202,6 +203,10 @@ export default {
}
});
},
setTableColumnTitles() { // reevaluates computed phrasen
if(this.$refs.betriebsmittelTable) this.$refs.betriebsmittelTable.tabulator.setColumns(this.betriebsmittel_table_options.columns)
if(this.$refs.funktionenTable) this.$refs.funktionenTable.tabulator.setColumns(this.funktionen_table_options.columns)
}
},
computed: {
@@ -274,10 +279,17 @@ export default {
this.data.profilUpdates?.sort(this.sortProfilUpdates);
},
mounted() {
watch: {
'data.funktionen'(newVal) {
if(this.$refs.funktionenTable) this.$refs.funktionenTable.tabulator.setData(newVal);
},
'data.mittel'(newVal) {
if(this.$refs.betriebsmittelTable) this.$refs.betriebsmittelTable.tabulator.setData(newVal);
},
'language.value'(newVal) {
this.setTableColumnTitles()
}
},
template: /*html*/ `
<div class="container-fluid text-break fhc-form" >
<edit-profil v-if="showModal" ref="editModal" @hideBsModal="hideEditProfilModal" :value="JSON.parse(JSON.stringify(filteredEditData))" :title="$p.t('profil','profilBearbeiten')"></edit-profil>
@@ -14,7 +14,7 @@ export default {
ProfilEmails,
ProfilInformation,
},
inject: ["collapseFunction"],
inject: ["collapseFunction", "language"],
data() {
return {
collapseIconFunktionen: true,
@@ -44,21 +44,21 @@ export default {
visible: true
},
{
title: "Bezeichnung",
title: Vue.computed(() => this.$p.t('ui/bezeichnung')),
field: "Bezeichnung",
headerFilter: true,
minWidth: 200,
visible: true
},
{
title: "Organisationseinheit",
title: Vue.computed(() => this.$p.t('lehre/organisationseinheit')),
field: "Organisationseinheit",
headerFilter: true,
minWidth: 200,
visible: true
},
{
title: "Gültig_von",
title: Vue.computed(() => this.$p.t('global/gueltigVon')),
field: "Gültig_von",
headerFilter: true,
resizable: true,
@@ -66,7 +66,7 @@ export default {
visible: true
},
{
title: "Gültig_bis",
title: Vue.computed(() => this.$p.t('global/gueltigBis')),
field: "Gültig_bis",
headerFilter: true,
resizable: true,
@@ -74,7 +74,7 @@ export default {
visible: true
},
{
title: "Wochenstunden",
title: Vue.computed(() => this.$p.t('profil/wochenstunden')),
field: "Wochenstunden",
headerFilter: true,
minWidth: 200,
@@ -96,6 +96,9 @@ export default {
'data.funktionen'(newVal) {
if(this.$refs.funktionenTable) this.$refs.funktionenTable.tabulator.setData(newVal);
},
'language.value'(newVal) { // reevaluates computed phrasen
if(this.$refs.funktionenTable) this.$refs.funktionenTable.tabulator.setColumns(this.funktionen_table_options.columns)
}
},
computed: {
getTelefonValue() {
@@ -181,7 +181,7 @@ export default {
return BsModal.popup(null, options);
},
template: /*html*/ `
<bs-modal v-show="!loading" ref="modalContainer" v-bind="$props" body-class="" dialog-class="modal-lg" class="bootstrap-alert" backdrop="false">
<bs-modal v-show="!loading" ref="modalContainer" v-bind="$props" body-class="" dialog-class="modal-lg" class="bootstrap-alert" :backdrop="false">
<template v-if="title" v-slot:title>{{title}}</template>
<template v-slot:default>
<div>
@@ -24,7 +24,7 @@ export default {
FetchProfilUpdates,
EditProfil,
},
inject: ["sortProfilUpdates", "collapseFunction"],
inject: ["sortProfilUpdates", "collapseFunction", "language"],
data() {
return {
showModal: false,
@@ -33,18 +33,27 @@ export default {
// tabulator options
zutrittsgruppen_table_options: {
persistenceID: "filterTableStudentProfilZutrittsgruppen",
persistence: {
columns: false
},
height: 200,
layout: "fitColumns",
data: [{bezeichnung: ""}],
columns: [{title: "Zutritt", field: "bezeichnung"}],
columns: [{
title: Vue.computed(() => this.$p.t('profil/zutrittsGruppen')),
field: "bezeichnung"
}],
},
betriebsmittel_table_options: {
persistenceID: "filterTableStudentProfilBetriebsmittel",
persistence: {
columns: false
},
height: 300,
layout: "fitColumns",
responsiveLayout: "collapse",
responsiveLayoutCollapseUseFormatters: false,
responsiveLayoutCollapseFormatter: Vue.$collapseFormatter,
data: [{betriebsmittel: "", Nummer: "", Ausgegeben_am: ""}],
columns: [
{
title:
@@ -57,23 +66,26 @@ export default {
headerClick: this.collapseFunction,
},
{
title: "Betriebsmittel",
title: Vue.computed(() => this.$p.t('profil/entlehnteBetriebsmittel')),
field: "betriebsmittel",
headerFilter: true,
minWidth: 200,
visible: true
},
{
title: "Nummer",
title: Vue.computed(() => this.$p.t('profil/inventarnummer')),
field: "Nummer",
headerFilter: true,
resizable: true,
minWidth: 200,
visible: true
},
{
title: "Ausgegeben_am",
title: Vue.computed(() => this.$p.t('profil/ausgabedatum')),
field: "Ausgegeben_am",
headerFilter: true,
minWidth: 200,
visible: true
},
],
},
@@ -92,9 +104,11 @@ export default {
methods: {
betriebsmittelTableBuilt: function () {
this.$refs.betriebsmittelTable.tabulator.setColumns(this.betriebsmittel_table_options.columns)
this.$refs.betriebsmittelTable.tabulator.setData(this.data.mittel);
},
zutrittsgruppenTableBuilt: function () {
this.$refs.zutrittsgruppenTable.tabulator.setColumns(this.zutrittsgruppen_table_options.columns)
this.$refs.zutrittsgruppenTable.tabulator.setData(
this.data.zuttritsgruppen
);
@@ -212,6 +226,12 @@ export default {
//? sorts the profil Updates: pending -> accepted -> rejected
this.data.profilUpdates?.sort(this.sortProfilUpdates);
},
watch: {
'language.value'(newVal) {
if(this.$refs.betriebsmittelTable) this.$refs.betriebsmittelTable.tabulator.setColumns(this.betriebsmittel_table_options.columns)
if(this.$refs.zutrittsgruppenTable) this.$refs.zutrittsgruppenTable.tabulator.setColumns(this.zutrittsgruppen_table_options.columns)
}
},
template: /*html*/ `
<div class="container-fluid text-break fhc-form">
<edit-profil v-if="showModal" ref="editModal" @hideBsModal="hideEditProfilModal"
@@ -331,10 +351,23 @@ export default {
<!-- SECOND ROW UNDER THE PROFIL IMAGE AND INFORMATION WITH THE TABLES -->
<div class="row">
<div class="col-12 mb-4" >
<core-filter-cmpt @tableBuilt="betriebsmittelTableBuilt" :title="$p.t('profil','entlehnteBetriebsmittel')" ref="betriebsmittelTable" :tabulator-options="betriebsmittel_table_options" tableOnly :sideMenu="false" />
<core-filter-cmpt
@tableBuilt="betriebsmittelTableBuilt"
:title="$p.t('profil','entlehnteBetriebsmittel')"
ref="betriebsmittelTable"
:tabulator-options="betriebsmittel_table_options"
tableOnly
:sideMenu="false" />
</div>
<div class="col-12 mb-4" >
<core-filter-cmpt @tableBuilt="zutrittsgruppenTableBuilt" :title="$p.t('profil','zutrittsGruppen')" ref="zutrittsgruppenTable" :tabulator-options="zutrittsgruppen_table_options" tableOnly :sideMenu="false" noColumnFilter />
<core-filter-cmpt
@tableBuilt="zutrittsgruppenTableBuilt"
:title="$p.t('profil','zutrittsGruppen')"
ref="zutrittsgruppenTable"
:tabulator-options="zutrittsgruppen_table_options"
tableOnly
:sideMenu="false"
noColumnFilter />
</div>
</div>
<!-- END OF MAIN CONTENT COL -->
@@ -108,7 +108,7 @@ export default {
},
template: /*html*/ `
<bs-modal v-show="!loading" ref="modalContainer" v-bind="$props" body-class="" dialog-class="modal-lg" class="bootstrap-alert" backdrop="false" >
<bs-modal v-show="!loading" ref="modalContainer" v-bind="$props" body-class="" dialog-class="modal-lg" class="bootstrap-alert" :backdrop="false" >
<template v-slot:title>
{{title}}
@@ -206,15 +206,15 @@ export const Stundenplan = {
</div>
</div>
<div class="col ">
<p>Lehrveranstaltung:</p>
<p>{{ $p.t('lehre/lehrveranstaltung') }}:</p>
<p class="m-0">{{event?.orig.topic}}</p>
</div>
<div class="col ">
<p>Lektor:</p>
<p>{{ $p.t('lehre/lektor') }}:</p>
<p class="m-0" v-for="lektor in event?.orig.lektor">{{lektor.kurzbz}}</p>
</div>
<div class="col ">
<p>Ort: </p>
<p>{{ $p.t('profil/Ort') }}: </p>
<p class="m-0">{{event?.orig.ort_kurzbz}}</p>
</div>
</div>
@@ -224,11 +224,11 @@ export const Stundenplan = {
<div class="w-100">
<lv-info :event="currentlySelectedEvent" />
</div>
<h3 >Lehrveranstaltungs Menu</h3>
<h3 >{{$p.t('lehre','lehrveranstaltungsmenue')}}</h3>
<lv-menu :containerStyles="['p-0']" :rowStyles="['m-0']" v-show="lvMenu" :menu="lvMenu" />
</template>
<template #pageMobilContentEmpty >
<h3>Keine Lehrveranstaltungen</h3>
<h3>{{ $p.t('lehre/noLvFound') }}</h3>
</template>
</fhc-calendar>
`
@@ -192,11 +192,11 @@ export default {
</small>
</div>
<div v-if="!value.length" class="list-group-item small text-center">
{{ p.t('lehre/noLvFound') }}
{{ $p.t('lehre/noLvFound') }}
</div>
</template>
<div v-else class="d-flex h-100 justify-content-center align-items-center fst-italic text-center">
{{ p.t('lehre/noLvFound') }}
{{ $p.t('lehre/noLvFound') }}
</div>
</div>
</template>
+3 -3
View File
@@ -71,9 +71,9 @@ class CalendarDate {
}
get wYear() {
if( this.w === 1 ) {
return this.cdLastDayOfWeek.format({ year: 'numeric' });
return this.cdLastDayOfWeek.y;
}
return this.cdFirstDayOfWeek.format({ year: 'numeric' });
return this.cdFirstDayOfWeek.y;
}
get wd() {
if (this._wd === null) {
@@ -271,4 +271,4 @@ CalendarDate.getWeekStart = function(locale) {
}
}
export default CalendarDate
export default CalendarDate
+100
View File
@@ -27676,6 +27676,66 @@ array(
)
)
),
array(
'app' => 'core',
'category' => 'profil',
'phrase' => 'inventarnummer',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Inventarnummer',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'inventory number',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'profil',
'phrase' => 'ausgabedatum',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Ausgabedatum',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'issue date',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'profil',
'phrase' => 'wochenstunden',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Wochenstunden',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'working hours',
'description' => '',
'insertvon' => 'system'
)
)
),
//Profil Phrasen ende
//ProfilUpdate Phrasen start
array(
@@ -38503,6 +38563,46 @@ array(
)
)
),
array(
'app' => 'core',
'category' => 'lehre',
'phrase' => 'lehrveranstaltungsmenue',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Lehrveranstaltungsmenü',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Course Menu',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'lehre',
'phrase' => 'lehrveranstaltungsmenueUnavailable',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Kein Lehrveranstaltungsmenü verfügbar',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'No Course Menu available',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'lehre',