email tbl_vorlage inserts dbupdate script; index.ci.php/Abgabetool/Assistenz/stg_kz? optional param route in old cis & cis4; no data placeholder phrase fix;

This commit is contained in:
Johann Hoffmann
2025-11-17 15:57:53 +01:00
parent 1120b823d2
commit 6cd0e3a574
11 changed files with 104 additions and 75 deletions
+2 -1
View File
@@ -66,9 +66,10 @@ $route['Cis/MyLvPlan/.*'] = 'Cis/MyLvPlan/index/$1';
$route['Cis/MyLv/.*'] = 'Cis/MyLv/index/$1';
$route['Abgabetool/Assistenz'] = 'Cis/Abgabetool/Assistenz';
$route['Abgabetool/Assistenz/(:any)'] = 'Cis/Abgabetool/Assistenz/$1';
$route['Abgabetool/Mitarbeiter'] = 'Cis/Abgabetool/Mitarbeiter';
$route['Abgabetool/Student'] = 'Cis/Abgabetool/Student';
$route['Abgabetool/Student/.*'] = 'Cis/Abgabetool/Student/$1';
$route['Abgabetool/Student/(:any)'] = 'Cis/Abgabetool/Student/$1';
$route['Abgabetool/Deadlines'] = 'Cis/Abgabetool/Deadlines';
// Studierendenverwaltung List Routes
+4 -9
View File
@@ -29,7 +29,7 @@ class Abgabetool extends Auth_Controller
*/
public function index()
{
// TODO: do we even need this?
// TODO: routing from index based on berechtigung?
$viewData = array(
'uid'=>getAuthUID(),
@@ -44,12 +44,9 @@ class Abgabetool extends Auth_Controller
public function Student($student_uid_prop = '')
{
$viewData = array(
'uid'=>getAuthUID(),
);
if(defined('CIS4') && CIS4) {
$this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'AbgabetoolStudent']);
@@ -60,7 +57,6 @@ class Abgabetool extends Auth_Controller
public function Mitarbeiter()
{
$viewData = array(
'uid'=>getAuthUID(),
);
@@ -72,9 +68,9 @@ class Abgabetool extends Auth_Controller
}
}
public function Assistenz()
public function Assistenz($stg_kz_prop = '')
{
$viewData = array(
'uid'=>getAuthUID(),
);
@@ -82,13 +78,12 @@ class Abgabetool extends Auth_Controller
if(defined('CIS4') && CIS4) {
$this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'AbgabetoolAssistenz']);
} else {
$this->load->view('Cis/Abgabetool.php', ['uid' => getAuthUID(), 'route' => 'AbgabetoolAssistenz']);
$this->load->view('Cis/Abgabetool.php', ['uid' => getAuthUID(), 'route' => 'AbgabetoolAssistenz', 'stg_kz_prop' => $stg_kz_prop]);
}
}
public function Deadlines()
{
$viewData = array(
'uid'=>getAuthUID(),
);
+4 -1
View File
@@ -37,7 +37,10 @@ $includesArray = array(
$this->load->view('templates/FHC-Header', $includesArray);
?>
<div id="abgabetoolroot" class="h-100" route=<?php echo json_encode($route) ?> uid=<?php echo $uid ?> student_uid_prop=<?php echo $student_uid_prop ?? '' ?>>
<div id="abgabetoolroot" class="h-100" route=<?php echo json_encode($route) ?>
uid=<?php echo $uid ?> student_uid_prop=<?php echo $student_uid_prop ?? '""' ?>
stg_kz_prop=<?php echo $stg_kz_prop ?? '""' ?>
>
</div>
<?php $this->load->view('templates/FHC-Footer', $includesArray); ?>
+11 -1
View File
@@ -1,6 +1,7 @@
import PluginsPhrasen from '../../plugins/Phrasen.js';
import AbgabetoolStudent from "../../components/Cis/Abgabetool/AbgabetoolStudent.js";
import AbgabetoolMitarbeiter from "../../components/Cis/Abgabetool/AbgabetoolMitarbeiter.js";
import AbgabetoolAssistenz from "../../components/Cis/Abgabetool/AbgabetoolAssistenz.js";
import DeadlineOverview from "../../components/Cis/Abgabetool/DeadlineOverview.js";
import {capitalize} from "../../helpers/StringHelpers.js";
@@ -9,13 +10,15 @@ const app = Vue.createApp({
components: {
AbgabetoolStudent,
AbgabetoolMitarbeiter,
AbgabetoolAssistenz,
DeadlineOverview
},
data: function() {
return {
comp: null,
uid: null,
student_uid: null
student_uid: null,
stg_kz: null
};
},
methods: {
@@ -27,6 +30,9 @@ const app = Vue.createApp({
},
student_uid_computed() {
return this.student_uid ?? null
},
stg_kz_computed() {
return this.stg_kz ?? null
}
},
created() {
@@ -40,6 +46,9 @@ const app = Vue.createApp({
const uid = root.getAttribute("uid");
this.uid = uid
const stg_kz = root.getAttribute("stg_kz_prop");
this.stg_kz = stg_kz
const student_uid = root.getAttribute("student_uid_prop");
this.student_uid = student_uid
@@ -48,6 +57,7 @@ const app = Vue.createApp({
<template v-if="comp && uid">
<AbgabetoolStudent v-if="comp == 'AbgabetoolStudent'" :viewData="viewData" :student_uid_prop="student_uid_computed"></AbgabetoolStudent>
<AbgabetoolMitarbeiter v-if="comp == 'AbgabetoolMitarbeiter'" :viewData="viewData"></AbgabetoolMitarbeiter>
<AbgabetoolAssistenz v-if="comp == 'AbgabetoolAssistenz'" :viewData="viewData" :stg_kz_prop="stg_kz_computed"></AbgabetoolAssistenz>
<DeadlineOverview v-if="comp == 'DeadlinesOverview'" :viewData="viewData"></DeadlineOverview>
</template>
`
+1 -1
View File
@@ -58,7 +58,7 @@ const router = VueRouter.createRouter({
props: true
},
{
path: `/Cis/Abgabetool/Assistenz`,
path: `/Cis/Abgabetool/Assistenz/:stg_kz_prop?`,
name: 'AbgabetoolAssistenz',
component: AbgabetoolAssistenz,
props: true
@@ -125,7 +125,7 @@ export const AbgabeMitarbeiterDetail = {
'paabgabe_id': -1,
'projektarbeit_id': this.projektarbeit.projektarbeit_id,
'fixtermin': false,
'inertedFixtermin': true,
'invertedFixtermin': true,
'kurzbz': '', // todo kurzbz textfield value vorschlag für qualgates
'datum': new Date().toISOString().split('T')[0],
'note': this.allowedNotenOptions.find(opt => opt.note == 9),
@@ -492,7 +492,7 @@ export const AbgabeMitarbeiterDetail = {
<div v-if="showAutomagicModalPhrase" class="text-center"><p>{{$p.t('abgabetool/c4abgabeQualGateNegativAddNewAutomagisch')}}</p></div>
<div v-if="newTermin">
<div v-if="assistenzMode" class="row">
<div class="col-4 col-md-3 fw-bold">{{$p.t('abgabetool/c4fixtermin')}}</div>
<div class="col-4 col-md-3 fw-bold">{{$p.t('abgabetool/c4fixterminv4')}}</div>
<div class="col-8 col-md-9">
<Checkbox
v-model="newTermin.invertedFixtermin"
@@ -42,6 +42,9 @@ export const AbgabetoolAssistenz = {
}
},
props: {
stg_kz_prop: {
default: null
},
viewData: {
type: Object,
required: true,
@@ -121,7 +124,7 @@ export const AbgabetoolAssistenz = {
width: 40
},
{title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4details'))), field: 'details', formatter: this.formAction, tooltip:false, minWidth: 150,},
{title: 'pa_id', field: 'projektarbeit_id', visible: true},
// {title: 'pa_id', field: 'projektarbeit_id', visible: true},
// {title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4details'))), field: 'details', formatter: this.detailFormatter, widthGrow: 1,responsive:0, tooltip: false},
{title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4personenkennzeichen'))), headerFilter: true, field: 'pkz', formatter: this.pkzTextFormatter,responsive:0, widthGrow: 1, tooltip: false},
// {title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4termineTimeLine'))), headerFilter: true, field: 'abgabetermine',responsive:2, formatter: this.timelineFormatter, widthGrow: 1, tooltip: false},
@@ -134,7 +137,7 @@ export const AbgabetoolAssistenz = {
{title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4stg'))), field: 'stg', headerFilter: true, responsive:3, visible: false, formatter: this.centeredTextFormatter, widthGrow: 1},
{title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4note'))), field: 'note_bez', headerFilter: true,
responsive:3, visible: false, formatter: this.centeredTextFormatter, widthGrow: 1},
{title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4sem'))), field: 'studiensemester_kurzbz', headerFilter: true, visible: false, responsive:3,formatter: this.centeredTextFormatter, widthGrow: 1},
{title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4sem'))), field: 'studiensemester_kurzbz', headerFilter: true, visible: true, responsive:2,formatter: this.centeredTextFormatter, widthGrow: 1},
{title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4titel'))), field: 'titel', headerFilter: true, responsive:3, visible: false, formatter: this.centeredTextFormatter, widthGrow: 1},
{title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4erstbetreuer'))), field: 'erstbetreuer', headerFilter: true, responsive:3,formatter: this.centeredTextFormatter, widthGrow: 1},
{title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4zweitbetreuer'))), field: 'zweitbetreuer', headerFilter: true, responsive:3,formatter: this.centeredTextFormatter, widthGrow: 1, visible: false},
@@ -150,26 +153,12 @@ export const AbgabetoolAssistenz = {
this.tableBuiltResolve()
}
},
// {
// event: "cellClick",
// handler: async (e, cell) => {
// if(cell.getColumn().getField() === "details") {
// this.setDetailComponent(cell.getValue())
// this.undoSelection(cell)
// } else if (cell.getColumn().getField() === "mail") {
// this.undoSelection(cell)
// } else if (cell.getColumn().getField() === "abgabetermine") {
// this.openTimeline(cell.getValue())
// this.undoSelection(cell)
// }
// }
// },
{
event: "rowSelectionChanged",
handler: async(data) => {
this.selectedData = data
}
{
event: "rowSelectionChanged",
handler: async(data) => {
this.selectedData = data
}
}
]};
},
methods: {
@@ -409,15 +398,6 @@ export const AbgabetoolAssistenz = {
+ '/Cis/Abgabetool/Deadlines'
window.open(link, '_blank')
},
toggleShowAll(showall) {
this.showAll = showall
this.loading = true
this.loadProjektarbeiten(showall, () => {
this.$refs.abgabeTable?.tabulator.redraw(true)
this.$refs.abgabeTable?.tabulator.setSort([]);
this.loading = false
})
},
openAddSeriesModal() {
this.$refs.modalContainerAddSeries.show()
},
@@ -460,6 +440,9 @@ export const AbgabetoolAssistenz = {
this.$refs.abgabeTable.tabulator.deselectRow()
const mappedData = this.mapProjekteToTableData(this.projektarbeiten)
if(!this.$refs.abgabeTable.tabulator) return
this.$refs.abgabeTable.tabulator.clearData()
this.$refs.abgabeTable.tabulator.setColumns(this.abgabeTableOptions.columns)
@@ -541,8 +524,6 @@ export const AbgabetoolAssistenz = {
})
// TODO: do same thing for sidebar
const vorname = pa.vorname ?? pa.student_vorname
const nachname = pa.nachname ?? pa.student_nachname
pa.student = `${vorname} ${nachname}`
@@ -694,7 +675,7 @@ export const AbgabetoolAssistenz = {
loadProjektarbeiten(all = false, callback) {
this.loading = true
this.$api.call(ApiAbgabe.getProjektarbeitenForStudiengang(
this.getCurrentStudiengang,
this.selectedStudiengangOption.studiengang_kz,
this.notenOptionFilter?.benotet ?? 0
))
.then(res => {
@@ -730,37 +711,27 @@ export const AbgabetoolAssistenz = {
async setupMounted() {
this.tableBuiltPromise = new Promise(this.tableResolve)
await this.tableBuiltPromise
// called through notenOptionFilter watcher on startup
// called through notenOptionFilter/selectedStudiengangOption watcher on startup
// this.loadProjektarbeiten()
// this.$refs.verticalsplit.collapseBottom()
this.calcMaxTableHeight()
},
sendEmailBegutachter() {
// TODO: implement
},
sendEmailStudierende() {
// TODO: implement
}
},
watch: {
selectedStudiengangOption(newVal, oldVal) {
this.loadProjektarbeiten()
// implicitely avoids juggling around promises for created api calls,
// since we need note & stg flags for loadProjektarbeiten
if(this.notenOptionFilter !== null && this.selectedStudiengangOption !== null) {
this.loadProjektarbeiten()
}
},
notenOptionFilter(newVal) {
// that single where clause is worth a decent load time so rather not filter tabulator but just
// adapt the qry
this.loadProjektarbeiten()
}
},
computed: {
getCurrentStudiengang() {
// TODO: sophisticated logic pulling from default value by viewData or dropdown select
return this.selectedStudiengangOption?.studiengang_kz ?? 257
if(this.notenOptionFilter !== null && this.selectedStudiengangOption !== null) {
this.loadProjektarbeiten()
}
}
},
created() {
@@ -778,6 +749,13 @@ export const AbgabetoolAssistenz = {
// fetch studiengänge options
this.$api.call(ApiAbgabe.getStudiengaenge()).then(res => {
this.studiengaengeOptions = res.data
if(this.studiengaengeOptions?.length) {
// use this.stg_kz_prop as default selected in case of url param usage
this.selectedStudiengangOption = this.stg_kz_prop ? res.data.find(stgOpt => stgOpt.studiengang_kz == this.stg_kz_prop) : res.data[0]
}
}).catch(e => {
this.loading = false
})
@@ -1035,8 +1013,7 @@ export const AbgabetoolAssistenz = {
:style="{'width': '100%', 'scroll-behavior': 'auto !important'}"
:optionLabel="getOptionLabelStg"
v-model="selectedStudiengangOption"
:options="studiengaengeOptions"
showClear
:options="studiengaengeOptions"
:tabindex="2"
>
<template #optionsgroup="slotProps">
@@ -69,7 +69,7 @@ export const AbgabetoolMitarbeiter = {
minHeight: 250,
index: 'projektarbeit_id',
layout: 'fitDataStretch',
placeholder: this.$p.t('global/noDataAvailable'),
placeholder: Vue.computed(() => this.$p.t('global/noDataAvailable')),
selectable: true,
selectableCheck: this.selectionCheck,
rowHeight: 80,
@@ -299,7 +299,6 @@ export const AbgabetoolMitarbeiter = {
this.domain = data[1]
const d = data[0]?.retval?.map(projekt => {
let mode = 'detailTermine'
return {
...projekt,
@@ -316,7 +315,7 @@ export const AbgabetoolMitarbeiter = {
titel: projekt.titel
}
})
this.$refs.abgabeTable.tabulator.setColumns(this.abgabeTableOptions.columns)
this.$refs.abgabeTable.tabulator.setData(d);
},
@@ -2,7 +2,7 @@ export const AbgabeterminStatusLegende = {
name: 'AbgabeterminStatusLegende',
template: `
<div class="text-center">
<div class="col" style="width: 50%; margin-left: 12px;">
<div class="col" style="width: 80%; margin-left: 12px;">
<div class="row" style="margin-bottom: 2px">
<div class="col-auto verspaetet-header" style="height: 36px; width:36px; padding: 0px; display: flex; align-items: center; justify-content: center;">
@@ -287,4 +287,48 @@ if($result = $db->db_query("SELECT 1 FROM information_schema.routines WHERE rout
else
echo "<br>campus.get_betreuer_details function hinzugefuegt";
}
}
}
if($result = $db->db_query("SELECT 1 FROM system.tbl_berechtigung WHERE berechtigung_kurzbz = 'basis/abgabe_assistenz'"))
{
if($db->db_num_rows($result) === 0)
{
$qry = "INSERT INTO system.tbl_berechtigung(berechtigung_kurzbz, beschreibung)
SELECT 'basis/abgabe_assistenz', 'Recht um Abgabetool für Assistenzen zu bedienen'";
if(!$db->db_query($qry))
echo '<strong>system.tbl_berechtigung: '.$db->db_last_error().'</strong><br>';
else
echo "<br>system.tbl_berechtigung insert basis/abgabe_assistenz hinzugefuegt";
}
}
if($result = $db->db_query("SELECT 1 FROM public.tbl_vorlage WHERE vorlage_kurzbz = 'paabgabeUpdatesBetSM'"))
{
if($db->db_num_rows($result) === 0)
{
$qry = "INSERT INTO public.tbl_vorlage (vorlage_kurzbz, bezeichnung, anmerkung, mimetype)
VALUES ('paabgabeUpdatesBetSM', 'paabgabeUpdatesBetSM', null, 'text/html')
ON CONFLICT (vorlage_kurzbz) DO NOTHING;";
if(!$db->db_query($qry))
echo '<strong>system.tbl_vorlage: '.$db->db_last_error().'</strong><br>';
else
echo "<br>system.tbl_vorlage paabgabeUpdatesBetSM hinzugefuegt";
}
}
if($result = $db->db_query("SELECT 1 FROM public.tbl_vorlage WHERE vorlage_kurzbz = 'paabgabeUpdatesSammelmail'"))
{
if($db->db_num_rows($result) === 0)
{
$qry = "INSERT INTO public.tbl_vorlage (vorlage_kurzbz, bezeichnung, anmerkung, mimetype)
VALUES ('paabgabeUpdatesSammelmail', 'paabgabeUpdatesSammelmail', null, 'text/html')
ON CONFLICT (vorlage_kurzbz) DO NOTHING;";
if(!$db->db_query($qry))
echo '<strong>system.tbl_vorlage: '.$db->db_last_error().'</strong><br>';
else
echo "<br>system.tbl_vorlage paabgabeUpdatesSammelmail hinzugefuegt";
}
}
+1 -1
View File
@@ -43647,7 +43647,7 @@ array(
),
array(
'sprache' => 'English',
'text' => 'Download Abgabe',
'text' => 'Download File',
'description' => '',
'insertvon' => 'system'
)