mirror of
https://github.com/FH-Complete/FHC-Core.git
synced 2026-10-12 06:54:04 +00:00
Merge branch 'feature-77372/lv_verwaltung_release_fine_tuning' into studvw_lvvw_2026_08_rc
This commit is contained in:
@@ -38,3 +38,9 @@ textarea[name="anmerkung"] {
|
||||
{
|
||||
border-color: black;
|
||||
}
|
||||
|
||||
.node-verband {
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
}
|
||||
|
||||
@@ -16,16 +16,20 @@
|
||||
*/
|
||||
|
||||
export default {
|
||||
getCourselist(params) {
|
||||
getCourselist(student_uid, start_date, end_date, stundenplan) {
|
||||
return {
|
||||
method: 'get',
|
||||
url: 'api/frontend/v1/stv/LvTermine/getStundenplan/' + params.student_uid + '/'
|
||||
+ params.start_date + '/'
|
||||
+ params.end_date + '/'
|
||||
+ params.group_consecutiveHours + '/'
|
||||
+ params.dbStundenplanTable
|
||||
url: 'api/frontend/v1/stv/LvTermine/getStundenplan/' + encodeURIComponent(student_uid) + '/'
|
||||
+ encodeURIComponent(start_date) + '/'
|
||||
+ encodeURIComponent(end_date) + '/'
|
||||
+ encodeURIComponent(stundenplan) + '/'
|
||||
+ encodeURIComponent(true)
|
||||
};
|
||||
},
|
||||
exportCalendar(student_uid, stundenplan)
|
||||
{
|
||||
return FHC_JS_DATA_STORAGE_OBJECT.app_root + 'content/statistik/termine.xls.php?student_uid=' + encodeURIComponent(student_uid) + '&db_stpl_table='+encodeURIComponent(stundenplan);
|
||||
},
|
||||
getStudiensemester(){
|
||||
return {
|
||||
method: 'get',
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
export default {
|
||||
get() {
|
||||
return {
|
||||
method: 'get',
|
||||
url: '/api/frontend/v1/lv/config/get'
|
||||
};
|
||||
},
|
||||
set(params) {
|
||||
return {
|
||||
method: 'post',
|
||||
url: 'api/frontend/v1/lv/config/set',
|
||||
params
|
||||
};
|
||||
}
|
||||
};
|
||||
@@ -18,6 +18,14 @@ export default {
|
||||
params: newData
|
||||
};
|
||||
},
|
||||
getGruppe(gruppe)
|
||||
{
|
||||
return {
|
||||
method: 'post',
|
||||
url: '/api/frontend/v1/lv/gruppe/getGruppe/',
|
||||
params: gruppe
|
||||
};
|
||||
},
|
||||
getByLehreinheit(lehreinheit_id)
|
||||
{
|
||||
return {
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
export default {
|
||||
getCourselist(le_id, start_date, end_date, stundenplan)
|
||||
{
|
||||
return {
|
||||
method: 'get',
|
||||
url: '/api/frontend/v1/lvPlan/getLeEvents/' + encodeURIComponent(le_id) + "/" + encodeURIComponent(start_date) + "/" + encodeURIComponent(end_date) + "/" + encodeURIComponent(stundenplan),
|
||||
};
|
||||
},
|
||||
exportCalendar(le_id, stundenplan)
|
||||
{
|
||||
return FHC_JS_DATA_STORAGE_OBJECT.app_root + 'content/statistik/termine.xls.php?lehreinheit_id=' + encodeURIComponent(le_id) + '&db_stpl_table='+encodeURIComponent(stundenplan);
|
||||
},
|
||||
getStudiensemester(){
|
||||
return {
|
||||
method: 'get',
|
||||
url: '/api/frontend/v1/lv/setup/getStudiensemester/'
|
||||
};
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,19 @@
|
||||
export default {
|
||||
getCourselist(lv_id, start_date, end_date, stundenplan)
|
||||
{
|
||||
return {
|
||||
method: 'get',
|
||||
url: '/api/frontend/v1/lvPlan/getLvEvents/' + encodeURIComponent(lv_id) + "/" + encodeURIComponent(start_date) + "/" + encodeURIComponent(end_date) + "/" + encodeURIComponent(stundenplan),
|
||||
};
|
||||
},
|
||||
exportCalendar(lv_id, stundenplan)
|
||||
{
|
||||
return FHC_JS_DATA_STORAGE_OBJECT.app_root + 'content/statistik/termine.xls.php?lehrveranstaltung_id=' + encodeURIComponent(lv_id) + '&db_stpl_table='+encodeURIComponent(stundenplan);
|
||||
},
|
||||
getStudiensemester(){
|
||||
return {
|
||||
method: 'get',
|
||||
url: '/api/frontend/v1/lv/setup/getStudiensemester/'
|
||||
};
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,25 @@
|
||||
import Grades from '../factory/stv/grades.js';
|
||||
|
||||
export default {
|
||||
...Grades,
|
||||
getCertificate(lv_id, studiensemester_kurzbz) {
|
||||
let url = 'api/frontend/v1/lv/noten/getCertificate/' + encodeURIComponent(lv_id);
|
||||
if (!!studiensemester_kurzbz) {
|
||||
url = url + '/' + encodeURIComponent(studiensemester_kurzbz);
|
||||
}
|
||||
return {
|
||||
method: 'get',
|
||||
url: url
|
||||
};
|
||||
},
|
||||
getTeacherProposal(lv_id, studiensemester_kurzbz) {
|
||||
let url = 'api/frontend/v1/lv/noten/getTeacherProposal/' + encodeURIComponent(lv_id);
|
||||
if (!!studiensemester_kurzbz) {
|
||||
url = url + '/' + encodeURIComponent(studiensemester_kurzbz);
|
||||
}
|
||||
return {
|
||||
method: 'get',
|
||||
url: url
|
||||
};
|
||||
},
|
||||
};
|
||||
@@ -1,9 +1,16 @@
|
||||
export default {
|
||||
getTabs()
|
||||
getLETabs()
|
||||
{
|
||||
return {
|
||||
method: 'get',
|
||||
url: '/api/frontend/v1/lv/setup/getTabs/'
|
||||
url: '/api/frontend/v1/lv/setup/getLETabs/'
|
||||
};
|
||||
},
|
||||
getLVTabs()
|
||||
{
|
||||
return {
|
||||
method: 'get',
|
||||
url: '/api/frontend/v1/lv/setup/getLVTabs/'
|
||||
};
|
||||
},
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ import {CoreFilterCmpt} from "../../filter/Filter.js";
|
||||
import FormForm from '../../Form/Form.js';
|
||||
import FormInput from '../../Form/Input.js';
|
||||
import ApiGruppe from "../../../api/lehrveranstaltung/gruppe.js";
|
||||
import drop from '../../../directives/drop.js';
|
||||
export default{
|
||||
name: "LVGruppen",
|
||||
components: {
|
||||
@@ -9,6 +10,9 @@ export default{
|
||||
FormForm,
|
||||
FormInput
|
||||
},
|
||||
directives: {
|
||||
drop
|
||||
},
|
||||
props: {
|
||||
lehreinheit_id: Number
|
||||
},
|
||||
@@ -187,28 +191,48 @@ export default{
|
||||
this.reload();
|
||||
})
|
||||
},
|
||||
onDropVerband(node, gruppe) {
|
||||
this.$api.call(ApiGruppe.getGruppe(gruppe))
|
||||
.then(result => result.data)
|
||||
.then(result => {
|
||||
|
||||
let newData = {
|
||||
'gid': result,
|
||||
'lehreinheit_id': this.lehreinheit_id,
|
||||
'lehrverband': gruppe.lehrverband,
|
||||
}
|
||||
this.$api.call(ApiGruppe.add(newData))
|
||||
.then(result => {
|
||||
this.reload()
|
||||
})
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
},
|
||||
template: `
|
||||
<core-filter-cmpt
|
||||
ref="table"
|
||||
:tabulator-options="tabulatorOptions"
|
||||
:tabulator-events="tabulatorEvents"
|
||||
table-only
|
||||
:side-menu="false"
|
||||
:reload=true
|
||||
>
|
||||
<template #search> <!--TODO (david) Slot prüfen -->
|
||||
<form-input
|
||||
type="autocomplete"
|
||||
:suggestions="filteredGroups"
|
||||
:placeholder="$p.t('lehre', 'addGroup')"
|
||||
v-model="selectedGroup"
|
||||
field="label"
|
||||
@item-select="addGroup"
|
||||
@complete="searchGroup"
|
||||
></form-input>
|
||||
</template>
|
||||
|
||||
</core-filter-cmpt>
|
||||
<div v-drop:link-strict.verband="(evt, gruppe) => onDropVerband(node, gruppe)">
|
||||
<core-filter-cmpt
|
||||
ref="table"
|
||||
:tabulator-options="tabulatorOptions"
|
||||
:tabulator-events="tabulatorEvents"
|
||||
table-only
|
||||
:side-menu="false"
|
||||
:reload=true
|
||||
>
|
||||
<template #search> <!--TODO (david) Slot prüfen -->
|
||||
<form-input
|
||||
type="autocomplete"
|
||||
:suggestions="filteredGroups"
|
||||
:placeholder="$p.t('lehre', 'addGroup')"
|
||||
v-model="selectedGroup"
|
||||
field="label"
|
||||
@item-select="addGroup"
|
||||
@complete="searchGroup"
|
||||
></form-input>
|
||||
</template>
|
||||
|
||||
</core-filter-cmpt>
|
||||
</div>
|
||||
`
|
||||
};
|
||||
@@ -9,6 +9,8 @@ import LvTabs from "./Setup/Tabs.js";
|
||||
import ApiDetails from "../../api/lehrveranstaltung/details.js";
|
||||
import ApiLektor from "../../api/lehrveranstaltung/lektor.js";
|
||||
import ApiSearchbar from "../../api/factory/searchbar.js";
|
||||
import AppConfig from "../AppConfig.js";
|
||||
import ApiLvConfig from "../../api/lehrveranstaltung/config.js";
|
||||
|
||||
|
||||
export default {
|
||||
@@ -21,8 +23,11 @@ export default {
|
||||
StvStudiensemester,
|
||||
LvTable,
|
||||
LvTabs,
|
||||
AppConfig
|
||||
},
|
||||
props: {
|
||||
avatarUrl: String,
|
||||
logoutUrl: String,
|
||||
defaultSemester: String,
|
||||
lvRoot: String,
|
||||
permissions: Object,
|
||||
@@ -37,7 +42,6 @@ export default {
|
||||
lehreinheitAnmerkungDefault: (this.config.lehreinheitAnmerkungDefault || '').replace(/\\n/g, '\n'),
|
||||
lehreinheitRaumtypDefault: this.config.lehreinheitRaumtypDefault,
|
||||
lehreinheitRaumtypAlternativeDefault: this.config.lehreinheitRaumtypAlternativeDefault,
|
||||
|
||||
permissionLehrveranstaltung: this.permissions['lehre/lehrveranstaltung'],
|
||||
permissionGruppenEntfernen: this.permissions['lv-plan/gruppenentfernen'],
|
||||
permissionLektorEntfernen: this.permissions['lv-plan/lektorentfernen'],
|
||||
@@ -45,6 +49,8 @@ export default {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
appconfig:{},
|
||||
configEndpoints: ApiLvConfig,
|
||||
selected: [],
|
||||
studiengang: "",
|
||||
selectedStudiensemester: this.defaultSemester,
|
||||
@@ -104,6 +110,71 @@ export default {
|
||||
semester() {
|
||||
return this.filter.semester;
|
||||
},
|
||||
appMenuExtraItems()
|
||||
{
|
||||
let extraItems = [];
|
||||
|
||||
const studiengang_kz = this.stg || '';
|
||||
const studiensemester = this.selectedStudiensemester;
|
||||
const semester = this.semester || '';
|
||||
const uid = this.emp || '';
|
||||
|
||||
|
||||
extraItems.push(
|
||||
{
|
||||
description: 'lehre/berichte',
|
||||
requires: ['stg'],
|
||||
children: [
|
||||
{
|
||||
link: FHC_JS_DATA_STORAGE_OBJECT.app_root
|
||||
+ 'content/statistik/lvplanung.xls.php'
|
||||
+ '?studiengang_kz=' + studiengang_kz
|
||||
+ '&studiensemester_kurzbz=' + studiensemester
|
||||
+ '&semester=' + semester,
|
||||
description: 'lehre/lvplanung',
|
||||
requires: ['stg']
|
||||
},
|
||||
{
|
||||
link: FHC_JS_DATA_STORAGE_OBJECT.app_root
|
||||
+ 'content/statistik/lehrauftragsliste_gst.xls.php'
|
||||
+ '?studiengang_kz=' + studiengang_kz
|
||||
+ '&studiensemester_kurzbz=' + studiensemester
|
||||
+ '&semester=' + semester,
|
||||
description: 'lehre/lehrauftragsliste',
|
||||
requires: ['stg']
|
||||
},
|
||||
{
|
||||
link: FHC_JS_DATA_STORAGE_OBJECT.app_root
|
||||
+ 'content/pdfExport.php?xml=lehrauftrag.xml.php'
|
||||
+ '&xsl=Lehrauftrag'
|
||||
+ '&stg_kz=' + studiengang_kz
|
||||
+ '&ss=' + studiensemester,
|
||||
description: 'lehre/lehrauftraege',
|
||||
requires: ['stg']
|
||||
},
|
||||
{
|
||||
link: FHC_JS_DATA_STORAGE_OBJECT.app_root
|
||||
+ 'content/pdfExport.php?xml=lehrauftrag.xml.php'
|
||||
+ '&xsl=Lehrauftrag'
|
||||
+ '&stg_kz=' + studiengang_kz
|
||||
+ '&ss=' + studiensemester
|
||||
+ '&uid=' + uid,
|
||||
description: 'lehre/lehrauftragslisteemp',
|
||||
requires: ['emp']
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
link: FHC_JS_DATA_STORAGE_OBJECT.app_root
|
||||
+ 'vilesci/lehre/lehrveranstaltung.php'
|
||||
+ '?stg_kz=' + studiengang_kz,
|
||||
description: 'lehre/extrakvverwaltung',
|
||||
requires: ['stg']
|
||||
}
|
||||
);
|
||||
|
||||
return extraItems;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
updateFilter()
|
||||
@@ -188,6 +259,21 @@ export default {
|
||||
}
|
||||
this.selectedStudiensemester = stdsem;
|
||||
this.selected = [];
|
||||
},
|
||||
isDisabled(item)
|
||||
{
|
||||
if (!item?.requires?.length)
|
||||
return false;
|
||||
|
||||
const values = {
|
||||
stg: this.stg,
|
||||
emp: this.emp,
|
||||
studiensemester: this.selectedStudiensemester,
|
||||
semester: this.semester
|
||||
};
|
||||
|
||||
return item.requires.some(req => !values[req]);
|
||||
|
||||
}
|
||||
},
|
||||
created() {
|
||||
@@ -261,6 +347,51 @@ export default {
|
||||
<span class="fa-solid fa-table-list"></span>
|
||||
</button>
|
||||
<core-searchbar :searchoptions="searchbaroptions" :searchfunction=searchfunction class="searchbar w-100"></core-searchbar>
|
||||
<div id="nav-user" class="dropdown">
|
||||
<button
|
||||
id="nav-user-btn"
|
||||
class="btn btn-link rounded-0 py-0"
|
||||
type="button"
|
||||
data-bs-toggle="dropdown"
|
||||
data-bs-target="#nav-user-menu"
|
||||
aria-expanded="false"
|
||||
aria-controls="nav-user-menu"
|
||||
>
|
||||
<img
|
||||
:src="avatarUrl"
|
||||
:alt="$p.t('profilUpdate/profilBild')"
|
||||
class="bg-light avatar rounded-circle border border-light"
|
||||
/>
|
||||
</button>
|
||||
<ul
|
||||
ref="navUserDropdown"
|
||||
class="dropdown-menu dropdown-menu-dark dropdown-menu-end rounded-0 text-center m-0"
|
||||
aria-labelledby="nav-user-btn"
|
||||
>
|
||||
<li>
|
||||
<button
|
||||
type="button"
|
||||
class="dropdown-item"
|
||||
data-bs-toggle="modal"
|
||||
data-bs-target="#configModal"
|
||||
>
|
||||
{{ $p.t('ui/settings') }}
|
||||
</button>
|
||||
</li>
|
||||
<li><hr class="dropdown-divider m-0"/></li>
|
||||
<li>
|
||||
<nav-language
|
||||
item-class="dropdown-item border-left-dark"
|
||||
/>
|
||||
</li>
|
||||
<li><hr class="dropdown-divider m-0"/></li>
|
||||
<li>
|
||||
<a class="dropdown-item" :href="logoutUrl">
|
||||
{{ $p.t('ui/logout') }}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</header>
|
||||
<div class="container-fluid overflow-hidden">
|
||||
<div class="row h-100">
|
||||
@@ -270,7 +401,40 @@ export default {
|
||||
<button type="button" class="btn-close text-reset" data-bs-dismiss="offcanvas" :aria-label="$p.t('ui/schliessen')"></button>
|
||||
</div>
|
||||
<div class="offcanvas-body">
|
||||
<app-menu app-identifier="lvv" />
|
||||
<app-menu app-identifier="lvv">
|
||||
<template v-for="(item, key) in appMenuExtraItems" :key="key">
|
||||
<li v-if="item.children" class="dropend">
|
||||
<a
|
||||
class="dropdown-toggle"
|
||||
href="#"
|
||||
role="button"
|
||||
data-bs-toggle="dropdown"
|
||||
aria-expanded="false"
|
||||
data-bs-popper-config='{"strategy":"fixed"}'
|
||||
>
|
||||
{{ $p.t(item.description) }}
|
||||
</a>
|
||||
<ul class="dropdown-menu p-0">
|
||||
<li
|
||||
v-for="(child, childKey) in item.children"
|
||||
:key="childKey"
|
||||
>
|
||||
<a class="dropdown-item" :href="child.link" target="_blank" :class="{ disabled: isDisabled(child) }">
|
||||
{{ $p.t(child.description) }}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li v-else>
|
||||
<a
|
||||
:href="item.link"
|
||||
target="_blank"
|
||||
:class="{ disabled: isDisabled(item) }">
|
||||
{{ $p.t(item.description) }}
|
||||
</a>
|
||||
</li>
|
||||
</template>
|
||||
</app-menu>
|
||||
</div>
|
||||
</aside>
|
||||
<nav id="sidebarMenu" class="bg-light offcanvas offcanvas-start col-md p-md-0 h-100">
|
||||
@@ -325,5 +489,6 @@ export default {
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
<app-config ref="config" v-model="appconfig" :endpoints="configEndpoints"></app-config>
|
||||
</div>`
|
||||
};
|
||||
|
||||
@@ -140,7 +140,7 @@ export default{
|
||||
{
|
||||
this.$emit('changedLektor', this.changed.mitarbeiter_uid);
|
||||
}
|
||||
if (this.changed.semesterstunden || this.changed.stundensatz)
|
||||
else if (this.changed.semesterstunden || this.changed.stundensatz)
|
||||
{
|
||||
this.$emit('changedCosts');
|
||||
}
|
||||
@@ -183,9 +183,6 @@ export default{
|
||||
},
|
||||
|
||||
},
|
||||
created() {
|
||||
this.getLektorData()
|
||||
},
|
||||
template: `
|
||||
<core-form ref="form" @submit.prevent="updateDaten">
|
||||
<div class="position-sticky top-0 z-1">
|
||||
|
||||
@@ -57,6 +57,7 @@ export default {
|
||||
if (this.$refs.table && this.$refs.table.tabulator)
|
||||
{
|
||||
this.expanded = [];
|
||||
this.currentTreeLevel = 0;
|
||||
this.reload();
|
||||
}
|
||||
},
|
||||
@@ -143,7 +144,8 @@ export default {
|
||||
headerFilterFunc: extendedHeaderFilter,
|
||||
},
|
||||
layout: 'fitDataStretch',
|
||||
persistenceID: 'lehrveranstaltungen_2025_07_31_v1',
|
||||
height: '100%',
|
||||
persistenceID: 'lehrveranstaltungen_2026_07_15_v1',
|
||||
selectableRowsRangeMode: 'click',
|
||||
selectableRows: true,
|
||||
rowContextMenu: (component, e) => {
|
||||
@@ -238,14 +240,13 @@ export default {
|
||||
|
||||
if (data[0]?.lehreinheit_id !== undefined && this.selectedColumnValues.length === 1)
|
||||
{
|
||||
this.$emit('update:selected', [data[0]]);
|
||||
this.lv_info = false
|
||||
}
|
||||
else if (data[0]?.lehrveranstaltung_id)
|
||||
{
|
||||
this.$emit('update:selected', {});
|
||||
this.getLVInfos(data[0]);
|
||||
}
|
||||
this.$emit('update:selected', data);
|
||||
},
|
||||
getLVInfos(data)
|
||||
{
|
||||
@@ -455,47 +456,50 @@ export default {
|
||||
},
|
||||
},
|
||||
template: `
|
||||
<core-filter-cmpt
|
||||
ref="table"
|
||||
:tabulator-options="tabulatorOptions"
|
||||
:tabulator-events="tabulatorEvents"
|
||||
table-only
|
||||
:side-menu="false"
|
||||
:reload=true
|
||||
new-btn-label="LV-Teil hinzufügen"
|
||||
new-btn-show
|
||||
:new-btn-disabled="!lv_info"
|
||||
@click:new="showLehreinheitModal">
|
||||
|
||||
<template #actions>
|
||||
<button @click="expandTree" class="btn btn-outline-secondary" type="button" :title="$p.t('lehre', 'aufklappen')"><i class="fa-solid fa-maximize"></i></button>
|
||||
<button @click="resetTree" class="btn btn-outline-secondary" type="button" :title="$p.t('lehre', 'zuklappen')"><i id="togglegroup" class="fa-solid fa-minimize"></i></button>
|
||||
<core-tag ref="tagComponent"
|
||||
:endpoint="tagEndpoint"
|
||||
:values="selectedColumnValues"
|
||||
@added="addedTag"
|
||||
@deleted="deletedTag"
|
||||
@updated="updatedTag"
|
||||
zuordnung_typ="lehreinheit_id"
|
||||
></core-tag>
|
||||
</template>
|
||||
<template #search>
|
||||
<slot name="filterzuruecksetzen"></slot>
|
||||
</template>
|
||||
</core-filter-cmpt>
|
||||
<bs-modal ref="lehreinheitModal" dialogClass="modal-xxl">
|
||||
<template #title>
|
||||
<p class="fw-bold mt-3">{{$p.t('lehre', 'newlehreinheit')}}</p>
|
||||
</template>
|
||||
|
||||
<template v-if="lv_info">
|
||||
<details-form :data="lv_info"/>
|
||||
</template>
|
||||
|
||||
<template #footer>
|
||||
<button type="button" class="btn btn-primary" @click="addNewLehreinheit">{{$p.t('ui', 'speichern')}}</button>
|
||||
</template>
|
||||
</bs-modal>
|
||||
|
||||
<div class="lv-list h-100 pt-3">
|
||||
<div class="tabulator-container d-flex flex-column h-100">
|
||||
<core-filter-cmpt
|
||||
ref="table"
|
||||
:tabulator-options="tabulatorOptions"
|
||||
:tabulator-events="tabulatorEvents"
|
||||
table-only
|
||||
:side-menu="false"
|
||||
:reload=true
|
||||
new-btn-label="LV-Teil hinzufügen"
|
||||
new-btn-show
|
||||
:new-btn-disabled="!lv_info"
|
||||
@click:new="showLehreinheitModal">
|
||||
|
||||
<template #actions>
|
||||
<button @click="expandTree" class="btn btn-outline-secondary" type="button" :title="$p.t('lehre', 'aufklappen')"><i class="fa-solid fa-maximize"></i></button>
|
||||
<button @click="resetTree" class="btn btn-outline-secondary" type="button" :title="$p.t('lehre', 'zuklappen')"><i id="togglegroup" class="fa-solid fa-minimize"></i></button>
|
||||
<core-tag ref="tagComponent"
|
||||
:endpoint="tagEndpoint"
|
||||
:values="selectedColumnValues"
|
||||
@added="addedTag"
|
||||
@deleted="deletedTag"
|
||||
@updated="updatedTag"
|
||||
zuordnung_typ="lehreinheit_id"
|
||||
></core-tag>
|
||||
</template>
|
||||
<template #search>
|
||||
<slot name="filterzuruecksetzen"></slot>
|
||||
</template>
|
||||
</core-filter-cmpt>
|
||||
</div>
|
||||
<bs-modal ref="lehreinheitModal" dialogClass="modal-xxl">
|
||||
<template #title>
|
||||
<p class="fw-bold mt-3">{{$p.t('lehre', 'newlehreinheit')}}</p>
|
||||
</template>
|
||||
|
||||
<template v-if="lv_info">
|
||||
<details-form :data="lv_info"/>
|
||||
</template>
|
||||
|
||||
<template #footer>
|
||||
<button type="button" class="btn btn-primary" @click="addNewLehreinheit">{{$p.t('ui', 'speichern')}}</button>
|
||||
</template>
|
||||
</bs-modal>
|
||||
</div>
|
||||
`
|
||||
};
|
||||
@@ -8,6 +8,7 @@ export default {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
configLETabs: {},
|
||||
configLVTabs: {},
|
||||
};
|
||||
},
|
||||
@@ -19,7 +20,7 @@ export default {
|
||||
if (!this.lv || !this.lv.length)
|
||||
return {};
|
||||
|
||||
return this.configLVTabs;
|
||||
return this.configLETabs;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@@ -31,26 +32,42 @@ export default {
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.$api.call(Setup.getTabs())
|
||||
this.$api.call(Setup.getLETabs())
|
||||
.then(result => {
|
||||
this.configLETabs = result.data;
|
||||
})
|
||||
.catch(this.$fhcAlert.handleSystemError);
|
||||
|
||||
this.$api.call(Setup.getLVTabs())
|
||||
.then(result => {
|
||||
this.configLVTabs = result.data;
|
||||
})
|
||||
.catch(this.$fhcAlert.handleSystemError);
|
||||
|
||||
},
|
||||
template: `
|
||||
<div class="stv-details h-100 pb-3 d-flex flex-column">
|
||||
<div v-if="!lv?.length" class="justify-content-center d-flex h-100 align-items-center">
|
||||
Bitte eine Lehreinheit auswählen!
|
||||
</div>
|
||||
<div v-else-if="configLVTabs" class="d-flex flex-column h-100 pb-3">
|
||||
<div v-else-if="configLETabs && configLVTabs" class="d-flex flex-column h-100 pb-3">
|
||||
<fhc-tabs
|
||||
v-if="lv.length === 1"
|
||||
v-if="lv.length === 1 && lv[0]?.lehreinheit_id"
|
||||
ref="tabs"
|
||||
:useprimevue="true"
|
||||
:modelValue="lv[0]"
|
||||
:config="configLETabs"
|
||||
:default="$route.params.tab"
|
||||
style="flex: 1 1 0%; height: 0%"
|
||||
@changed="reload"
|
||||
/>
|
||||
<fhc-tabs
|
||||
v-else-if="lv.length === 1"
|
||||
ref="tabs"
|
||||
:useprimevue="true"
|
||||
:modelValue="lv[0]"
|
||||
:config="configLVTabs"
|
||||
:default="$route.params.tab"
|
||||
style="flex: 1 1 0%; height: 0%"
|
||||
@changed="reload"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
import TableLvList from "../../Stv/Studentenverwaltung/Details/Lehrveranstaltungstermine/ListLehrveranstaltungstermine.js";
|
||||
import ApiLVTermine from "../../../api/lehrveranstaltung/lvtermine.js";
|
||||
|
||||
export default {
|
||||
name: "LVTabTermine",
|
||||
components: {
|
||||
TableLvList
|
||||
},
|
||||
props: {
|
||||
modelValue: Object,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
endpoint: ApiLVTermine
|
||||
};
|
||||
},
|
||||
template: `
|
||||
<div class="lv-details-course-list h-100 d-flex flex-column">
|
||||
<table-lv-list ref="tbl_course_list" :id="modelValue.lehrveranstaltung_id" :endpoint="endpoint"></table-lv-list>
|
||||
</div>`
|
||||
};
|
||||
@@ -0,0 +1,116 @@
|
||||
import NotenZeugnis from "../../Stv/Studentenverwaltung/Details/Noten/Zeugnis.js";
|
||||
import NotenTeacher from "../../Stv/Studentenverwaltung/Details/Noten/Teacher.js";
|
||||
import NotenRepeater from "../../Stv/Studentenverwaltung/Details/Noten/Repeater.js";
|
||||
import ApiLVNoten from "../../../api/lehrveranstaltung/noten.js";
|
||||
import { highlightGesamtnote } from "../../../helpers/DocumentHelper.js";
|
||||
const LOCAL_STORAGE_ID = 'lv_details_noten_2025_12_02_stdsem_all';
|
||||
|
||||
export default {
|
||||
name: "LVTabNoten",
|
||||
components: {
|
||||
NotenZeugnis,
|
||||
NotenTeacher,
|
||||
NotenRepeater
|
||||
},
|
||||
provide() {
|
||||
return {
|
||||
config: this.config
|
||||
}
|
||||
},
|
||||
props: {
|
||||
modelValue: Object,
|
||||
config: Object
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
stdsem: '',
|
||||
endpoint: ApiLVNoten,
|
||||
tabulatorOptions: {
|
||||
visibleColumns: {
|
||||
vorname: true,
|
||||
nachname: true,
|
||||
lehrveranstaltung_bezeichnung: false
|
||||
},
|
||||
headerFilter: {
|
||||
vorname: true,
|
||||
nachname: true,
|
||||
lehrveranstaltung_bezeichnung: false
|
||||
},
|
||||
persistenceZeugnisID: 'lv-details-noten-zeugnis-2025120401',
|
||||
persistenceTeacherID: 'lv-details-noten-teacher-2025120401',
|
||||
},
|
||||
zeugnisLoaded: false,
|
||||
teacherLoaded: false,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
reload() {
|
||||
this.zeugnisLoaded = false;
|
||||
this.teacherLoaded = false;
|
||||
|
||||
this.$refs.zeugnis.$refs.table.reloadTable();
|
||||
this.$refs.teacher.$refs.table.reloadTable();
|
||||
},
|
||||
saveStdsem(event) {
|
||||
window.localStorage.setItem(LOCAL_STORAGE_ID, event.target.value);
|
||||
},
|
||||
onZeugnisLoaded() {
|
||||
this.zeugnisLoaded = true;
|
||||
this.checkHighlight();
|
||||
},
|
||||
onTeacherLoaded() {
|
||||
this.teacherLoaded = true;
|
||||
this.checkHighlight();
|
||||
},
|
||||
checkHighlight()
|
||||
{
|
||||
if (!this.zeugnisLoaded || !this.teacherLoaded)
|
||||
return;
|
||||
|
||||
if (!this.$refs.zeugnis || !this.$refs.teacher)
|
||||
return;
|
||||
|
||||
let zeugnisTable = this.$refs.zeugnis.$refs.table.tabulator;
|
||||
let teacherTable = this.$refs.teacher.$refs.table.tabulator;
|
||||
|
||||
if (!zeugnisTable || !teacherTable)
|
||||
return;
|
||||
|
||||
highlightGesamtnote(zeugnisTable, teacherTable);
|
||||
}
|
||||
},
|
||||
created() {
|
||||
const savedPath = window.localStorage.getItem(LOCAL_STORAGE_ID);
|
||||
this.stdsem = savedPath || '';
|
||||
},
|
||||
template: `
|
||||
<div class="stv-details-noten d-flex flex-column overflow-hidden">
|
||||
<div class="mb-3">
|
||||
<select class="form-select" v-model="stdsem" @input="saveStdsem" v-if="config?.semesterSelect ?? true">
|
||||
<option value="">{{ $p.t('ui/current_semester') }}</option>
|
||||
<option value="true">{{ $p.t('ui/all_semester') }}</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-8">
|
||||
<noten-zeugnis
|
||||
ref="zeugnis"
|
||||
:id="modelValue.lehrveranstaltung_id"
|
||||
:all-semester="!!stdsem"
|
||||
:endpoint="endpoint"
|
||||
:optionalTabulatorOptions="tabulatorOptions"
|
||||
@loaded="onZeugnisLoaded"/>
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<noten-teacher
|
||||
ref="teacher"
|
||||
:id="modelValue.lehrveranstaltung_id"
|
||||
:all-semester="!!stdsem"
|
||||
:endpoint="endpoint"
|
||||
@copied="reload"
|
||||
:optionalTabulatorOptions="tabulatorOptions"
|
||||
@loaded="onTeacherLoaded"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>`
|
||||
};
|
||||
@@ -0,0 +1,21 @@
|
||||
import TableLvList from "../../Stv/Studentenverwaltung/Details/Lehrveranstaltungstermine/ListLehrveranstaltungstermine.js";
|
||||
import ApiLETermine from "../../../api/lehrveranstaltung/letermine.js";
|
||||
|
||||
export default {
|
||||
name: "LETabTermine",
|
||||
components: {
|
||||
TableLvList
|
||||
},
|
||||
props: {
|
||||
modelValue: Object,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
endpoint: ApiLETermine
|
||||
};
|
||||
},
|
||||
template: `
|
||||
<div class="le-details-course-list h-100 d-flex flex-column">
|
||||
<table-lv-list ref="tbl_course_list" :id="modelValue.lehreinheit_id" :endpoint="endpoint"></table-lv-list>
|
||||
</div>`
|
||||
};
|
||||
@@ -1,4 +1,5 @@
|
||||
import TableLvList from "./Lehrveranstaltungstermine/ListLehrveranstaltungstermine.js";
|
||||
import ApiStvCoursedates from "../../../../api/factory/stv/coursedates.js";
|
||||
|
||||
export default {
|
||||
name: "TabCourseList",
|
||||
@@ -8,11 +9,13 @@ export default {
|
||||
props: {
|
||||
modelValue: Object,
|
||||
},
|
||||
data(){
|
||||
return {}
|
||||
data() {
|
||||
return {
|
||||
endpoint: ApiStvCoursedates
|
||||
};
|
||||
},
|
||||
template: `
|
||||
<div class="stv-details-course-list h-100 d-flex flex-column">
|
||||
<table-lv-list ref="tbl_course_list" :student="modelValue"></table-lv-list>
|
||||
<table-lv-list ref="tbl_course_list" :id="modelValue.uid" :endpoint="endpoint"></table-lv-list>
|
||||
</div>`
|
||||
};
|
||||
+14
-13
@@ -2,8 +2,6 @@ import {CoreFilterCmpt} from "../../../../filter/Filter.js";
|
||||
import FormInput from "../../../../Form/Input.js";
|
||||
import FormForm from '../../../../Form/Form.js';
|
||||
|
||||
import ApiStvCoursedates from "../../../../../api/factory/stv/coursedates.js";
|
||||
|
||||
export default {
|
||||
name: "TblCourseList",
|
||||
components: {
|
||||
@@ -17,7 +15,14 @@ export default {
|
||||
},
|
||||
},
|
||||
props: {
|
||||
student: Object
|
||||
id: {
|
||||
type: [Number, String],
|
||||
required: true
|
||||
},
|
||||
endpoint: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
},
|
||||
data(){
|
||||
return {
|
||||
@@ -48,14 +53,7 @@ export default {
|
||||
initTabulatorOptions(){
|
||||
this.tabulatorOptions = {
|
||||
ajaxURL: 'dummy',
|
||||
ajaxRequestFunc: () => this.$api.call(
|
||||
ApiStvCoursedates.getCourselist({
|
||||
student_uid: this.student.uid,
|
||||
start_date: this.dataSem.start,
|
||||
end_date: this.dataSem.ende,
|
||||
group_consecutiveHours: true,
|
||||
dbStundenplanTable: this.dbStundenplanTable})
|
||||
),
|
||||
ajaxRequestFunc: () => this.$api.call(this.endpoint.getCourselist(this.id, this.dataSem.start, this.dataSem.ende, this.dbStundenplanTable)),
|
||||
ajaxResponse: (url, params, response) => {
|
||||
return response.data;
|
||||
},
|
||||
@@ -131,7 +129,7 @@ export default {
|
||||
this.dataSem = this.listStudiensemester.find(item => item.studiensemester_kurzbz === studiensemester_kurzbz);
|
||||
},
|
||||
exportToExcel(){
|
||||
window.open(this.downloadLink, '_blank');
|
||||
window.open(this.endpoint.exportCalendar(this.id, this.dbStundenplanTable), '_blank');
|
||||
},
|
||||
reload() {
|
||||
this.$refs.table.reloadTable();
|
||||
@@ -145,10 +143,13 @@ export default {
|
||||
currentSemester(newVal, oldVal) {
|
||||
this.getDatesOfSemester(newVal);
|
||||
},
|
||||
id() {
|
||||
this.reload();
|
||||
}
|
||||
},
|
||||
created(){
|
||||
this.$api
|
||||
.call(ApiStvCoursedates.getStudiensemester())
|
||||
.call(this.endpoint.getStudiensemester())
|
||||
.then(result => {
|
||||
this.listStudiensemester = result.data;
|
||||
this.getDatesOfSemester(this.currentSemester);
|
||||
|
||||
@@ -2,6 +2,9 @@ import NotenZeugnis from './Noten/Zeugnis.js';
|
||||
import NotenTeacher from './Noten/Teacher.js';
|
||||
import NotenRepeater from './Noten/Repeater.js';
|
||||
|
||||
import ApiStvGrades from '../../../../api/factory/stv/grades.js';
|
||||
import { highlightGesamtnote } from "../../../../helpers/DocumentHelper.js";
|
||||
|
||||
const LOCAL_STORAGE_ID = 'stv_details_noten_2024-11-25_stdsem_all';
|
||||
|
||||
export default {
|
||||
@@ -22,7 +25,10 @@ export default {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
stdsem: ''
|
||||
stdsem: '',
|
||||
endpoint: ApiStvGrades,
|
||||
zeugnisLoaded: false,
|
||||
teacherLoaded: false,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
@@ -33,6 +39,30 @@ export default {
|
||||
},
|
||||
saveStdsem(event) {
|
||||
window.localStorage.setItem(LOCAL_STORAGE_ID, event.target.value);
|
||||
},
|
||||
onZeugnisLoaded() {
|
||||
this.zeugnisLoaded = true;
|
||||
this.checkHighlight();
|
||||
},
|
||||
onTeacherLoaded() {
|
||||
this.teacherLoaded = true;
|
||||
this.checkHighlight();
|
||||
},
|
||||
checkHighlight()
|
||||
{
|
||||
if (!this.zeugnisLoaded || !this.teacherLoaded)
|
||||
return;
|
||||
|
||||
if (!this.$refs.zeugnis || !this.$refs.teacher)
|
||||
return;
|
||||
|
||||
let zeugnisTable = this.$refs.zeugnis.$refs.table.tabulator;
|
||||
let teacherTable = this.$refs.teacher.$refs.table.tabulator;
|
||||
|
||||
if (!zeugnisTable || !teacherTable)
|
||||
return;
|
||||
|
||||
highlightGesamtnote(zeugnisTable, teacherTable);
|
||||
}
|
||||
},
|
||||
created() {
|
||||
@@ -49,10 +79,10 @@ export default {
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-8">
|
||||
<noten-zeugnis ref="zeugnis" :student="modelValue" :all-semester="!!stdsem"></noten-zeugnis>
|
||||
<noten-zeugnis ref="zeugnis" :id="modelValue.prestudent_id" :all-semester="!!stdsem" :endpoint="endpoint" @loaded="onZeugnisLoaded"></noten-zeugnis>
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<noten-teacher ref="teacher" :student="modelValue" :all-semester="!!stdsem" @copied="reload"></noten-teacher>
|
||||
<noten-teacher ref="teacher" :id="modelValue.prestudent_id" :endpoint="endpoint" :all-semester="!!stdsem" @copied="reload" @loaded="onTeacherLoaded"></noten-teacher>
|
||||
<noten-repeater class="mt-4" ref="repeater" :student="modelValue" :all-semester="!!stdsem" @copied="reload"></noten-repeater>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
import {CoreFilterCmpt} from "../../../../filter/Filter.js";
|
||||
|
||||
import ApiStvGrades from '../../../../../api/factory/stv/grades.js';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
CoreFilterCmpt
|
||||
},
|
||||
emits: [
|
||||
"copied"
|
||||
"copied",
|
||||
"loaded"
|
||||
],
|
||||
inject: {
|
||||
currentSemester: {
|
||||
@@ -16,20 +15,33 @@ export default {
|
||||
}
|
||||
},
|
||||
props: {
|
||||
student: Object,
|
||||
allSemester: Boolean
|
||||
endpoint: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
id: {
|
||||
type: [Number, String],
|
||||
required: true
|
||||
},
|
||||
allSemester: Boolean,
|
||||
optionalTabulatorOptions: Object,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
tabulatorEvents: []
|
||||
tabulatorEvents: [
|
||||
{
|
||||
event: "dataProcessed",
|
||||
handler: () => this.$emit("loaded"),
|
||||
},
|
||||
]
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
tabulatorOptions() {
|
||||
return {
|
||||
ajaxURL: 'dummy',
|
||||
ajaxRequestFunc: () => this.$api.call(ApiStvGrades.getTeacherProposal(
|
||||
this.student.prestudent_id,
|
||||
ajaxRequestFunc: () => this.$api.call(this.endpoint.getTeacherProposal(
|
||||
this.id,
|
||||
(!this.allSemester ? this.currentSemester : null)
|
||||
)),
|
||||
ajaxResponse: (url, params, response) => {
|
||||
@@ -77,16 +89,19 @@ export default {
|
||||
{ field: 'lehrveranstaltung_id', title: this.$p.t('lehre/lehrveranstaltung_id'), visible: false },
|
||||
{ field: 'punkte', title: this.$p.t('stv/grades_points'), visible: false }
|
||||
],
|
||||
columnDefaults: {
|
||||
headerFilter: this.optionalTabulatorOptions?.headerFilter ?? false,
|
||||
},
|
||||
layout: 'fitDataStretch',
|
||||
height: '100%',
|
||||
selectableRows: true,
|
||||
selectableRowsRangeMode: 'click',
|
||||
persistenceID: 'stv-details-noten-teacher-20260217'
|
||||
persistenceID: this.optionalTabulatorOptions?.persistenceTeacherID ?? 'stv-details-noten-teacher-2025120401',
|
||||
};
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
student(n) {
|
||||
id() {
|
||||
this.$refs.table.reloadTable();
|
||||
},
|
||||
allSemester(n) {
|
||||
@@ -97,7 +112,7 @@ export default {
|
||||
copyGrades(selected) {
|
||||
const promises = selected.map(
|
||||
grade => this.$api
|
||||
.call(ApiStvGrades.copyTeacherProposalToCertificate(grade), {
|
||||
.call(this.endpoint.copyTeacherProposalToCertificate(grade), {
|
||||
errorHeader: grade.lehrveranstaltung_bezeichnung
|
||||
})
|
||||
.then(() => {
|
||||
|
||||
@@ -2,8 +2,6 @@ import {CoreFilterCmpt} from "../../../../filter/Filter.js";
|
||||
import ZeugnisActions from './Zeugnis/Actions.js';
|
||||
import ZeugnisDocuments from './Zeugnis/Documents.js';
|
||||
|
||||
import ApiStvGrades from '../../../../../api/factory/stv/grades.js';
|
||||
|
||||
export default {
|
||||
name: 'Zeugnis',
|
||||
components: {
|
||||
@@ -11,6 +9,7 @@ export default {
|
||||
ZeugnisActions,
|
||||
ZeugnisDocuments
|
||||
},
|
||||
emits: ['loaded'],
|
||||
inject: {
|
||||
config: {
|
||||
from: 'config',
|
||||
@@ -22,7 +21,15 @@ export default {
|
||||
}
|
||||
},
|
||||
props: {
|
||||
student: Object,
|
||||
endpoint: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
id: {
|
||||
type: [Number, String],
|
||||
required: true
|
||||
},
|
||||
optionalTabulatorOptions: Object,
|
||||
allSemester: Boolean
|
||||
},
|
||||
data() {
|
||||
@@ -35,6 +42,10 @@ export default {
|
||||
return item;
|
||||
})
|
||||
},
|
||||
{
|
||||
event: "dataProcessed",
|
||||
handler: () => this.$emit("loaded")
|
||||
},
|
||||
{
|
||||
event: "rowSelected",
|
||||
handler: row => row.getElement().style.zIndex = 12
|
||||
@@ -53,7 +64,7 @@ export default {
|
||||
computed: {
|
||||
tabulatorOptions() {
|
||||
const listPromise = this.$api
|
||||
.call(ApiStvGrades.list())
|
||||
.call(this.endpoint.list())
|
||||
.then(res => res.data.map(({bezeichnung: label, note: value}) => ({label, value})));
|
||||
|
||||
let gradeField = {
|
||||
@@ -86,7 +97,7 @@ export default {
|
||||
note_bezeichnung
|
||||
}))
|
||||
// send to backend
|
||||
.then(data => this.$api.call(ApiStvGrades.updateCertificate(data)))
|
||||
.then(data => this.$api.call(this.endpoint.updateCertificate(data)))
|
||||
// get bezeichnung again
|
||||
.then(() => listPromise)
|
||||
.then(list => list.find(el => el.value == note))
|
||||
@@ -109,7 +120,7 @@ export default {
|
||||
if (filterTerm) {
|
||||
return this.$api
|
||||
.call(
|
||||
ApiStvGrades.getGradeFromPoints(
|
||||
this.endpoint.getGradeFromPoints(
|
||||
filterTerm,
|
||||
cell.getData().lehrveranstaltung_id,
|
||||
this.currentSemester
|
||||
@@ -142,6 +153,8 @@ export default {
|
||||
.then(() => node.innerText = this.$p.t('ui/loading'))
|
||||
.catch(this.$fhcAlert.handleSystemError);
|
||||
gradeField.editorParams.placeholderLoading = node;
|
||||
gradeField.visible = this.optionalTabulatorOptions?.visibleColumns?.note ?? true
|
||||
gradeField.headerFiler = this.optionalTabulatorOptions?.headerFilter?.note || this.optionalTabulatorOptions?.note || false
|
||||
}
|
||||
|
||||
const columns = [
|
||||
@@ -238,8 +251,8 @@ export default {
|
||||
|
||||
return {
|
||||
ajaxURL: 'dummy',
|
||||
ajaxRequestFunc: () => this.$api.call(ApiStvGrades.getCertificate(
|
||||
this.student.prestudent_id,
|
||||
ajaxRequestFunc: () => this.$api.call(this.endpoint.getCertificate(
|
||||
this.id,
|
||||
(!this.allSemester ? this.currentSemester : null)
|
||||
)),
|
||||
ajaxResponse: (url, params, response) => {
|
||||
@@ -248,9 +261,10 @@ export default {
|
||||
columns,
|
||||
height: '100%',
|
||||
layout: 'fitDataStretchFrozen',
|
||||
selectableRows: 1,
|
||||
selectable: true,
|
||||
selectableRowsRangeMode: 'click',
|
||||
persistenceID: 'stv-details-noten-zeugnis-20260217',
|
||||
selectableRows: true,
|
||||
persistenceID: this.optionalTabulatorOptions?.persistenceZeugnisID ?? 'stv-details-noten-zeugnis-20260217',
|
||||
persistence:{
|
||||
columns: ["width", "visible", "frozen"]
|
||||
}
|
||||
@@ -258,7 +272,8 @@ export default {
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
student(n) {
|
||||
id()
|
||||
{
|
||||
this.$refs.table.reloadTable();
|
||||
},
|
||||
allSemester(n) {
|
||||
@@ -269,7 +284,7 @@ export default {
|
||||
setGrade(data) {
|
||||
this.$api
|
||||
.call(
|
||||
ApiStvGrades.updateCertificate(data),
|
||||
this.endpoint.updateCertificate(data),
|
||||
{ errorHeader: data.lehrveranstaltung_bezeichnung }
|
||||
)
|
||||
.then(this.$refs.table.reloadTable)
|
||||
@@ -282,7 +297,7 @@ export default {
|
||||
.confirmDelete()
|
||||
.then(result => result ? data : Promise.reject({handled:true}))
|
||||
.then(data => this.$api.call(
|
||||
ApiStvGrades.deleteCertificate(data),
|
||||
this.endpoint.deleteCertificate(data),
|
||||
{ errorHeader: data.lehrveranstaltung_bezeichnung }
|
||||
))
|
||||
.then(this.$refs.table.reloadTable)
|
||||
@@ -291,7 +306,7 @@ export default {
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.$p.loadCategory(['global', 'stv', 'lehre'])
|
||||
this.$p.loadCategory(['global', 'stv', 'lehre', 'person'])
|
||||
.then(() => {
|
||||
if (this.$refs.table.tableBuilt)
|
||||
this.$refs.table.tabulator.columnManager.setColumns(this.tabulatorOptions.columns);
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
export function highlightGesamtnote(zeugnisTable, teacherTable)
|
||||
{
|
||||
let zeugnisData = zeugnisTable.getData();
|
||||
|
||||
let studentsWithNote = new Set();
|
||||
|
||||
zeugnisData.forEach(row => {
|
||||
let student = row.uid;
|
||||
let lv = row.lehrveranstaltung_id;
|
||||
let note = row.note;
|
||||
|
||||
if (!student || !lv)
|
||||
return;
|
||||
|
||||
if (note == null || note === "")
|
||||
return;
|
||||
|
||||
let key = `${student}_${lv}`;
|
||||
studentsWithNote.add(key);
|
||||
});
|
||||
|
||||
teacherTable.deselectRow();
|
||||
|
||||
teacherTable.getRows().forEach(row => {
|
||||
let data = row.getData();
|
||||
|
||||
let student = data.student_uid;
|
||||
let lv = data.lehrveranstaltung_id;
|
||||
let note = data.note;
|
||||
|
||||
if (!student || !lv)
|
||||
return;
|
||||
|
||||
if (note == null || note === "")
|
||||
return;
|
||||
|
||||
let key = `${student}_${lv}`;
|
||||
|
||||
if (!studentsWithNote.has(key))
|
||||
{
|
||||
row.select();
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -30,6 +30,10 @@ const TYPE_DEFINITION = {
|
||||
prestudent: {
|
||||
id: "prestudent_id",
|
||||
dragIcon: "fa-solid fa-user-graduate text-muted"
|
||||
},
|
||||
verband: {
|
||||
id: "gruppe_id",
|
||||
dragIcon: "fa-solid fa-user-group text-muted"
|
||||
}
|
||||
// TODO: IMPLEMENT OTHER TYPES
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user