diff --git a/application/controllers/Cis/Abgabetool.php b/application/controllers/Cis/Abgabetool.php
index e7d183f04..1895f7472 100644
--- a/application/controllers/Cis/Abgabetool.php
+++ b/application/controllers/Cis/Abgabetool.php
@@ -16,7 +16,8 @@ class Abgabetool extends Auth_Controller
'index' => self::PERM_LOGGED,
'getStudentProjektarbeitAbgabeFile' => self::PERM_LOGGED,
'Mitarbeiter' => self::PERM_LOGGED,
- 'Student' => self::PERM_LOGGED
+ 'Student' => self::PERM_LOGGED,
+ 'Deadlines' => self::PERM_LOGGED
]);
}
@@ -43,7 +44,7 @@ class Abgabetool extends Auth_Controller
'uid'=>getAuthUID(),
);
- $this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'Abgabetool']);
+ $this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'AbgabetoolStudent']);
}
public function Mitarbeiter()
@@ -53,7 +54,17 @@ class Abgabetool extends Auth_Controller
'uid'=>getAuthUID(),
);
- $this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'Abgabetool']);
+ $this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'AbgabetoolMitarbeiter']);
+ }
+
+ public function Deadlines()
+ {
+
+ $viewData = array(
+ 'uid'=>getAuthUID(),
+ );
+
+ $this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'DeadlinesOverview']);
}
@@ -66,7 +77,7 @@ class Abgabetool extends Auth_Controller
$student_uid = $this->_ci->input->get('student_uid');
if (!isset($paabgabe_id) || isEmptyString($paabgabe_id) || !isset($student_uid) || isEmptyString($student_uid))
- $this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general');
+ $this->terminateWithJsonError($this->p->t('global', 'wrongParameters'), 'general');
$this->_ci->load->model('education/Projektarbeit_model', 'ProjektarbeitModel');
@@ -88,10 +99,10 @@ class Abgabetool extends Auth_Controller
readfile($file_path); // read file content to output buffer
} else {
- $this->terminateWithError('File not found');
+ $this->terminateWithJsonError('File not found');
}
} else {
- $this->terminateWithError('Keine Zuordnung!');
+ $this->terminateWithJsonError('Keine Zuordnung!');
}
}
}
diff --git a/application/controllers/api/frontend/v1/Lehre.php b/application/controllers/api/frontend/v1/Lehre.php
index 375551e7a..0ec2456f5 100644
--- a/application/controllers/api/frontend/v1/Lehre.php
+++ b/application/controllers/api/frontend/v1/Lehre.php
@@ -45,7 +45,9 @@ class Lehre extends FHCAPI_Controller
'postStudentProjektarbeitEndupload' => self::PERM_LOGGED,
'getMitarbeiterProjektarbeiten' => self::PERM_LOGGED,
'postProjektarbeitAbgabe' => self::PERM_LOGGED,
- 'deleteProjektarbeitAbgabe' => self::PERM_LOGGED
+ 'deleteProjektarbeitAbgabe' => self::PERM_LOGGED,
+ 'postSerientermin' => self::PERM_LOGGED,
+ 'fetchDeadlines' => self::PERM_LOGGED // TODO: mitarbeiter recht prüfen
]);
$this->load->library('PhrasesLib');
@@ -556,5 +558,116 @@ class Lehre extends FHCAPI_Controller
$this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general');
}
+
+ /**
+ * endpoint for adding the same paabgabe for multiple projektarbeiten
+ * can be slow for large n since it queries twice per projektarbeit_id
+ */
+ public function postSerientermin() {
+ $projektarbeit_ids = $_POST['projektarbeit_ids'];
+ $datum = $_POST['datum'];
+ $paabgabetyp_kurzbz = $_POST['paabgabetyp_kurzbz'];
+ $bezeichnung = $_POST['bezeichnung'];
+ $kurzbz = $_POST['kurzbz'];
+
+ if (!isset($projektarbeit_ids) || !is_array($projektarbeit_ids) || empty($projektarbeit_ids)
+ || !isset($datum) || isEmptyString($datum)
+ || !isset($kurzbz) || isEmptyString($kurzbz)
+ || !isset($bezeichnung) || isEmptyString($bezeichnung)
+ || !isset($paabgabetyp_kurzbz) || isEmptyString($paabgabetyp_kurzbz))
+ $this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general');
+
+ // old script checks if there already are tbl_paabgabe entries with exact date, type & kurzbz
+ // for each termin - good to check that in principle but should not matter in this place. if necessary
+ // duplicate abgabetermine can be easily deleted manually, also via cronjob@night.
+
+ // since this entry includes the kurzbz string match, it should have only ever mattered when there were
+ // multiple users entering the exact same set of (date, type, kurzbz) - which is a much more narrow case than the
+ // general "saveMultiple" function should handle
+
+ // old script afterwards again queries if user is not the zweitbetreuer of any id - this is blocked in the ui
+ // and should never unintentionally happen
+
+ // TODO: check berechtigung &/|| zuordnung?
+
+ $this->load->model('education/Paabgabe_model', 'PaabgabeModel');
+ $this->load->model('education/Projektarbeit_model', 'ProjektarbeitModel');
+
+ $res = [];
+ foreach ($projektarbeit_ids as $projektarbeit_id) {
+
+ $result = $this->PaabgabeModel->insert(
+ array(
+ 'projektarbeit_id' => $projektarbeit_id,
+ 'paabgabetyp_kurzbz' => $paabgabetyp_kurzbz,
+ 'fixtermin' => false,
+ 'datum' => $datum,
+ 'kurzbz' => $kurzbz,
+ 'insertvon' => getAuthUID(),
+ 'insertamum' => date('Y-m-d H:i:s')
+ )
+ );
+
+ $data = $this->getDataOrTerminateWithError($result);
+
+// $res[] = $data;
+
+ // send mail to student
+ $result = $this->ProjektarbeitModel->getStudentInfoForProjektarbeitId($projektarbeit_id);
+ $data = $this->getDataOrTerminateWithError($result);
+
+// $this->addMeta('emaildata'.$projektarbeit_id, $data);
+
+ $datetime = new DateTime($datum);
+ $dateEmailFormatted = $datetime->format('d.m.Y');
+
+ $anredeFillString = $data[0]->anrede=="Herr"?"r":"";
+
+ $fullFormattedNameString = trim($data[0]->titelpre." ".$data[0]->vorname." ".$data[0]->nachname." ".$data[0]->titelpost);
+ $res[] = $fullFormattedNameString;
+
+ // Prepare mail content
+ $body_fields = array(
+ 'anrede' => $data[0]->anrede,
+ 'anredeFillString' => $anredeFillString,
+ 'datum' => $dateEmailFormatted,
+ 'bezeichnung' => $bezeichnung,
+ 'fullFormattedNameString' => $fullFormattedNameString,
+ 'kurzbz' => $kurzbz
+ );
+
+ $email = $data[0]->uid."@".DOMAIN;
+
+ sendSanchoMail(
+ 'neuerTerminBachelorMasterbetreuung',
+ $body_fields,
+ $email,
+ $this->p->t('abgabetool', 'neuerTerminBachelorMasterbetreuung')
+ );
+ }
+
+ $this->terminateWithSuccess($res);
+
+ }
+
+ public function fetchDeadlines() {
+ $person_id = $_POST['person_id'];
+
+ if (!isset($person_id) || isEmptyString($person_id))
+ $person_id = getAuthPersonId();
+
+
+ if($person_id !== getAuthPersonId()) {
+ $this->load->library('PermissionLib');
+ $isAdmin = $this->permissionlib->isBerechtigt('admin');
+ if(!$isAdmin) $this->terminateWithError($this->p->t('ui', 'keineBerechtigung'), 'general');
+ }
+
+ $this->load->model('education/Paabgabe_model', 'PaabgabeModel');
+ $result = $this->PaabgabeModel->getDeadlines($person_id);
+ $data = $this->getDataOrTerminateWithError($result);
+
+ $this->terminateWithSuccess($data);
+ }
}
diff --git a/application/models/education/Paabgabe_model.php b/application/models/education/Paabgabe_model.php
index 558059f72..343a86706 100644
--- a/application/models/education/Paabgabe_model.php
+++ b/application/models/education/Paabgabe_model.php
@@ -30,5 +30,35 @@ class Paabgabe_model extends DB_Model
return $this->execQuery($qry, array($projektarbeit_id));
}
+
+ /**
+ * Gets all Paabgabe Termin Deadlines of zugewiesene Projektarbeiten as a Mitarbeiter for Terminübersicht Abgabetool.
+ * @param int $person_id
+ * @return object
+ */
+ public function getDeadlines($person_id)
+ {
+ $qry = "SELECT
+ DISTINCT TO_CHAR(tbl_paabgabe.datum, 'DD.MM.YYYY') as datum, tbl_paabgabe.fixtermin, tbl_paabgabe.kurzbz,
+ person_student.vorname as stud_vorname, person_student.nachname as stud_nachname,
+ person_student.titelpre as stud_titelpre, person_student.titelpost as stud_titelpost,
+ tbl_lehrveranstaltung.semester, UPPER(tbl_studiengang.typ || tbl_studiengang.kurzbz) as stg,
+ tbl_paabgabetyp.bezeichnung as typ_bezeichnung
+ FROM
+ campus.tbl_paabgabe
+ JOIN lehre.tbl_projektarbeit USING(projektarbeit_id)
+ JOIN lehre.tbl_projektbetreuer USING(projektarbeit_id)
+ JOIN public.tbl_benutzer bn_student ON(tbl_projektarbeit.student_uid=bn_student.uid)
+ JOIN public.tbl_person person_student ON(bn_student.person_id=person_student.person_id)
+ JOIN lehre.tbl_lehreinheit ON(tbl_projektarbeit.lehreinheit_id=tbl_lehreinheit.lehreinheit_id)
+ JOIN lehre.tbl_lehrveranstaltung ON(tbl_lehreinheit.lehrveranstaltung_id=tbl_lehrveranstaltung.lehrveranstaltung_id)
+ JOIN public.tbl_studiengang ON(tbl_lehrveranstaltung.studiengang_kz=tbl_studiengang.studiengang_kz)
+ JOIN campus.tbl_paabgabetyp USING(paabgabetyp_kurzbz)
+ WHERE
+ tbl_projektbetreuer.person_id= ? AND tbl_paabgabe.datum>=now() AND bn_student.aktiv
+ ORDER BY datum";
+
+ return $this->execReadOnlyQuery($qry, array($person_id));
+ }
}
diff --git a/application/models/education/Projektarbeit_model.php b/application/models/education/Projektarbeit_model.php
index 1041b3aec..4083dbf6e 100644
--- a/application/models/education/Projektarbeit_model.php
+++ b/application/models/education/Projektarbeit_model.php
@@ -212,7 +212,11 @@ class Projektarbeit_model extends DB_Model
return $this->execReadOnlyQuery($qry, array($studentUID, $maUID));
}
-
+
+ /**
+ * Get a List of Projektarbeiten of a mitarbeiter with zuordnung
+ * used by the mitarbeiter cis4 abgabetool.
+ */
public function getMitarbeiterProjektarbeiten($uid, $showAll){
$qry = "SELECT
*
@@ -242,4 +246,19 @@ class Projektarbeit_model extends DB_Model
return $this->execReadOnlyQuery($qry, array($uid));
}
+
+ /**
+ * Fetch Student info relevant to a projektarbeit_id
+ */
+ public function getStudentInfoForProjektarbeitId($projektarbeit_id) {
+
+ $qry = "SELECT *
+ FROM campus.vw_student
+ WHERE uid IN(
+ SELECT student_uid
+ FROM lehre.tbl_projektarbeit
+ WHERE projektarbeit_id = ? )";
+
+ return $this->execReadOnlyQuery($qry, array($projektarbeit_id));
+ }
}
diff --git a/public/js/api/lehre.js b/public/js/api/lehre.js
index 2bf6dd277..5797a2c75 100644
--- a/public/js/api/lehre.js
+++ b/public/js/api/lehre.js
@@ -76,6 +76,22 @@ export default {
}
const url = '/api/frontend/v1/Lehre/deleteProjektarbeitAbgabe';
+ return this.$fhcApi.post(url, payload, null)
+ },
+ postSerientermin(datum, paabgabetyp_kurzbz, bezeichnung, kurzbz, projektarbeit_ids) {
+ const payload = {
+ datum, paabgabetyp_kurzbz, bezeichnung, kurzbz, projektarbeit_ids
+ }
+ const url = '/api/frontend/v1/Lehre/postSerientermin';
+
+ return this.$fhcApi.post(url, payload, null)
+ },
+ fetchDeadlines(person_id) {
+ const payload = {
+ person_id
+ }
+ const url = '/api/frontend/v1/Lehre/fetchDeadlines';
+
return this.$fhcApi.post(url, payload, null)
}
}
\ No newline at end of file
diff --git a/public/js/apps/Dashboard/Fhc.js b/public/js/apps/Dashboard/Fhc.js
index b04db0a83..5e6b006b9 100644
--- a/public/js/apps/Dashboard/Fhc.js
+++ b/public/js/apps/Dashboard/Fhc.js
@@ -12,6 +12,7 @@ import Info from "../../components/Cis/Mylv/Semester/Studiengang/Lv/Info.js";
import RoomInformation, {DEFAULT_MODE_RAUMINFO} from "../../components/Cis/Mylv/RoomInformation.js";
import AbgabetoolStudent from "../../components/Cis/Abgabetool/AbgabetoolStudent.js";
import AbgabetoolMitarbeiter from "../../components/Cis/Abgabetool/AbgabetoolMitarbeiter.js";
+import DeadlineOverview from "../../components/Cis/Abgabetool/DeadlineOverview.js";
@@ -44,6 +45,12 @@ const router = VueRouter.createRouter({
component: AbgabetoolMitarbeiter,
props: true
},
+ {
+ path: `/Cis/Abgabetool/Deadlines/:person_uid_prop?`,
+ name: 'DeadlineOverview',
+ component: DeadlineOverview,
+ props: true
+ },
{
path: `/Cis/Raumsuche`,
name: 'Raumsuche',
diff --git a/public/js/components/Cis/Abgabetool/AbgabeMitarbeiterDetail.js b/public/js/components/Cis/Abgabetool/AbgabeMitarbeiterDetail.js
index 7e0da66f6..c49dcfd0a 100644
--- a/public/js/components/Cis/Abgabetool/AbgabeMitarbeiterDetail.js
+++ b/public/js/components/Cis/Abgabetool/AbgabeMitarbeiterDetail.js
@@ -19,6 +19,7 @@ export const AbgabeMitarbeiterDetail = {
},
data() {
return {
+ oldPaBeurteilungLink: 'https://moodle.technikum-wien.at/mod/page/view.php?id=1005052', // TODO: inject from app & app provide link from config
eidAkzeptiert: false,
enduploadTermin: null,
allActiveLanguages: FHC_JS_DATA_STORAGE_OBJECT.server_languages,
@@ -44,16 +45,7 @@ export const AbgabeMitarbeiterDetail = {
paabgabetyp_kurzbz: 'enda',
bezeichnung: 'Endabgabe im Sekretariat'
}
- ],
- form: Vue.reactive({
- sprache: '',
- abstract: '',
- abstract_en: '',
- schlagwoerter: '',
- schlagwoerter_en: '',
- kontrollschlagwoerter: '',
- seitenanzahl: 1,
- })
+ ]
}
},
methods: {
@@ -171,21 +163,14 @@ export const AbgabeMitarbeiterDetail = {
window.open(link, '_blank')
},
openPlagiatcheck() {
- // todo: hardcoded turnitin link pfui?
+ // todo: hardcoded turnitin link?
const link = "https://technikum-wien.turnitin.com/sso/sp/redwood/saml/5IyfmBr2OcSIaWQTKlFCGj/start"
window.open(link, '_blank')
- }
- },
- watch: {
- projektarbeit(newVal) {
- // default select german if projektarbeit sprache was null
- this.form.sprache = newVal.sprache ? this.allActiveLanguages.find(lang => lang.sprache == newVal.sprache) : this.allActiveLanguages.find(lang => lang.sprache == 'German')
- this.form.abstract = newVal.abstract
- this.form.abstract_en = newVal.abstract_en
- this.form.schlagwoerter = newVal.schlagwoerter
- this.form.schlagwoerter_en = newVal.schlagwoerter_en
- this.form.kontrollschlagwoerter = newVal.kontrollschlagwoerter
- this.form.seitenanzahl = newVal.seitenanzahl
+ },
+ openBenotung() {
+ const path = this.projektarbeit?.betreuerart_kurzbz == 'Zweitbegutachter' ? 'ProjektarbeitsbeurteilungZweitbegutachter' : 'ProjektarbeitsbeurteilungErstbegutachter'
+ const link = FHC_JS_DATA_STORAGE_OBJECT.app_root + 'index.ci.php/extensions/FHC-Core-Projektarbeitsbeurteilung/' + path
+ window.open(link, '_blank')
}
},
computed: {
@@ -212,28 +197,47 @@ export const AbgabeMitarbeiterDetail = {
template: `
+
{{$p.t('abgabetool/c4abgabeMitarbeiterbereich')}}
+
+
{{projektarbeit?.student}}
{{projektarbeit?.titel}}
{{projektarbeit?.zweitbegutachter}}
-
-
-
+
+
+
+
+
+
+
+ Kein Endupload vorhanden!
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
@@ -303,101 +307,6 @@ export const AbgabeMitarbeiterDetail = {
-
-
-
- {{$p.t('abgabetool/c4enduploadZusatzdaten')}}
-
-
-
-
Student UID: {{ projektarbeit?.student_uid}}
-
-
-
-
-
Titel: {{ projektarbeit?.titel }}
-
-
-
-
-
-
{{$p.t('abgabetool/c4Sprache')}}
-
-
-
-
-
-
-
-
Kontrollierte Schlagwörter
-
-
-
-
-
-
{{$p.t('abgabetool/c4schlagwoerterGer')}}
-
-
-
-
-
-
-
{{$p.t('abgabetool/c4schlagwoerterEng')}}
-
-
-
-
-
-
-
{{$p.t('abgabetool/c4abstractGer')}}
-
-
-
-
-
-
-
{{$p.t('abgabetool/c4abstractEng')}}
-
-
-
-
-
-
-
{{$p.t('abgabetool/c4seitenanzahl')}}
-
-
-
-
-
-
-
-
-
-
-
{{ $p.t('abgabetool/c4gelesenUndAkzeptiert') }}
-
-
-
-
-
-
-
-
-
-
-
-
-
`,
};
diff --git a/public/js/components/Cis/Abgabetool/AbgabetoolMitarbeiter.js b/public/js/components/Cis/Abgabetool/AbgabetoolMitarbeiter.js
index 06a1f2d00..2d2316036 100644
--- a/public/js/components/Cis/Abgabetool/AbgabetoolMitarbeiter.js
+++ b/public/js/components/Cis/Abgabetool/AbgabetoolMitarbeiter.js
@@ -1,13 +1,18 @@
import {CoreFilterCmpt} from "../../../components/filter/Filter.js";
import AbgabeDetail from "./AbgabeMitarbeiterDetail.js";
import VerticalSplit from "../../verticalsplit/verticalsplit.js"
+import BsModal from '../../Bootstrap/Modal.js';
export const AbgabetoolMitarbeiter = {
name: "AbgabetoolMitarbeiter",
components: {
+ BsModal,
CoreFilterCmpt,
AbgabeDetail,
VerticalSplit,
+ Dropdown: primevue.dropdown,
+ Textarea: primevue.textarea,
+ VueDatePicker
},
props: {
viewData: {
@@ -21,6 +26,39 @@ export const AbgabetoolMitarbeiter = {
},
data() {
return {
+ saving: false,
+ loading: false,
+ // TODO: fetch types
+ allAbgabeTypes: [
+ {
+ paabgabetyp_kurzbz: 'abstract',
+ bezeichnung: 'Entwurf'
+ },
+ {
+ paabgabetyp_kurzbz: 'zwischen',
+ bezeichnung: 'Zwischenabgabe'
+ },
+ {
+ paabgabetyp_kurzbz: 'note',
+ bezeichnung: 'Benotung'
+ },
+ {
+ paabgabetyp_kurzbz: 'end',
+ bezeichnung: 'Endupload'
+ },
+ {
+ paabgabetyp_kurzbz: 'enda',
+ bezeichnung: 'Endabgabe im Sekretariat'
+ }
+ ],
+ serienTermin: Vue.reactive({
+ datum: new Date(),
+ bezeichnung: {
+ paabgabetyp_kurzbz: 'zwischen',
+ bezeichnung: 'Zwischenabgabe'
+ },
+ kurzbz: ''
+ }),
showAll: false,
tabulatorUuid: Vue.ref(0),
selectedData: [],
@@ -38,6 +76,7 @@ export const AbgabetoolMitarbeiter = {
layout: 'fitDataStretch',
placeholder: this.$p.t('global/noDataAvailable'),
selectable: true,
+ selectableCheck: this.selectionCheck,
columns: [
{
formatter: 'rowSelection',
@@ -59,7 +98,7 @@ export const AbgabetoolMitarbeiter = {
{title: Vue.computed(() => this.$p.t('abgabetool/c4stg')), field: 'stg', formatter: this.centeredTextFormatter, widthGrow: 2},
{title: Vue.computed(() => this.$p.t('abgabetool/c4sem')), field: 'studiensemester_kurzbz', formatter: this.centeredTextFormatter, widthGrow: 1},
{title: Vue.computed(() => this.$p.t('abgabetool/c4titel')), field: 'titel', formatter: this.centeredTextFormatter, maxWidth: 500, widthGrow: 8},
- {title: Vue.computed(() => this.$p.t('abgabetool/c4beteuerart')), field: 'betreuerart_beschreibung',formatter: this.centeredTextFormatter, widthGrow: 8}
+ {title: Vue.computed(() => this.$p.t('abgabetool/c4betreuerart')), field: 'betreuerart_beschreibung',formatter: this.centeredTextFormatter, widthGrow: 8}
],
persistence: false,
},
@@ -74,24 +113,10 @@ export const AbgabetoolMitarbeiter = {
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)
}
- e.stopPropagation()
-
- }
- },
- {
- event: "rowClick",
- handler: async (e, row) => {
-
- e.stopPropagation()
-
- }
- },
- {
- event: "rowSelected",
- handler: async (row) => {
-
-
}
},
{
@@ -103,16 +128,82 @@ export const AbgabetoolMitarbeiter = {
]};
},
methods: {
+ getOptionLabelAbgabetyp(option){
+ return option.bezeichnung
+ },
+ formatDate(dateParam) {
+ const date = new Date(dateParam)
+ // handle missing leading 0
+ const padZero = (num) => String(num).padStart(2, '0');
+
+ const month = padZero(date.getMonth() + 1); // Months are zero-based
+ const day = padZero(date.getDate());
+ const year = date.getFullYear();
+
+ return `${day}.${month}.${year}`;
+ },
+ undoSelection(cell) {
+ // checks if cells row is selected and unselects -> imitates columns which dont trigger row selection
+ // but actually just revert it after the fact
+
+ const row = cell.getRow()
+ if(row.isSelected()) {
+ row.deselect();
+ }
+ },
+ selectionCheck(row) {
+ const data = row.getData()
+ if(data?.betreuerart_kurzbz == 'Zweitbegutachter') return false
+ return true
+ },
showDeadlines(){
- // TODO: open seperate view in new window containing all future deadlines for the employee
+ const link = FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router
+ + '/Cis/Abgabetool/Deadlines'
+ window.open(link, '_blank')
},
toggleShowAll(showall) {
this.showAll = showall
- // TODO: debug tabulator row render
- this.loadProjektarbeiten(showall, () => { this.$refs.abgabeTable?.tabulator.redraw(true) })
+ 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()
},
addSeries() {
+ this.saving = true
+ this.$fhcApi.factory.lehre.postSerientermin(
+ this.serienTermin.datum.toISOString(),
+ this.serienTermin.bezeichnung.paabgabetyp_kurzbz,
+ this.serienTermin.bezeichnung.bezeichnung,
+ this.serienTermin.kurzbz,
+ this.selectedData?.map(projekt => projekt.projektarbeit_id)
+ ).then(res => {
+ if (res.meta.status === "success" && res.data) {
+ this.$fhcAlert.alertSuccess(this.$p.t('abgabetool/serienTerminGespeichert'))
+ // TODO: sticky lifetime erhöhen um sinnvoll lesen zu können?
+ this.$fhcAlert.alertInfo(this.$p.t('abgabetool/serienTerminEmailSentInfo', [this.createInfoString(res.data)]));
+ } else {
+ this.$fhcAlert.alertError(this.$p.t('abgabetool/errorSerienterminSpeichern'))
+ }
+ }).finally(()=>{
+ this.saving = false
+ })
+
+ this.$refs.modalContainerAddSeries.hide()
+ },
+ createInfoString(data) {
+ let str = '';
+ data.forEach(name => {
+ str += name
+ str += '; '
+ })
+
+ return str
},
isPastDate(date) {
return new Date(date) < new Date(Date.now())
@@ -283,8 +374,57 @@ export const AbgabetoolMitarbeiter = {
this.setupMounted()
},
template: `
-
-
+
+
+
+ {{ $p.t('abgabetool/addSeries') }}
+
+
+
+
+
+ {{$p.t('abgabetool/c4zieldatum')}}
+
+
+ {{$p.t('abgabetool/c4abgabetyp')}}
+
+
+ {{$p.t('abgabetool/c4abgabekurzbz')}}
+
+
+
+
+
+
+
+
+
@@ -296,9 +436,9 @@ export const AbgabetoolMitarbeiter = {
@uuidDefined="handleUuidDefined"
ref="abgabeTable"
:newBtnShow="true"
- :newBtnLabel="$p.t('global/neueTerminserie')"
+ :newBtnLabel="$p.t('abgabetool/neueTerminserie')"
:newBtnDisabled="!selectedData.length"
- @click:new=addSeries
+ @click:new=openAddSeriesModal
:tabulator-options="abgabeTableOptions"
:tabulator-events="abgabeTableEventHandlers"
tableOnly
@@ -316,6 +456,14 @@ export const AbgabetoolMitarbeiter = {
{{ $p.t('abgabetool/showDeadlines') }}
+
+
+ {{ $p.t('abgabetool/currentlySaving') }}
+
+
+ {{ $p.t('abgabetool/currentlyLoading') }}
+
+
diff --git a/public/js/components/Cis/Abgabetool/DeadlineOverview.js b/public/js/components/Cis/Abgabetool/DeadlineOverview.js
new file mode 100644
index 000000000..d2b133979
--- /dev/null
+++ b/public/js/components/Cis/Abgabetool/DeadlineOverview.js
@@ -0,0 +1,151 @@
+import {CoreFilterCmpt} from "../../../components/filter/Filter.js";
+
+export const DeadlineOverview = {
+ name: "DeadlineOverview",
+ components: {
+ CoreFilterCmpt,
+ },
+ props: {
+ person_uid_prop: {
+ default: null
+ },
+ viewData: {
+ type: Object,
+ required: true,
+ default: () => ({name: '', uid: ''}),
+ validator(value) {
+ return value && value.name && value.uid
+ }
+ }
+ },
+ data() {
+ return {
+ fullName: null, // TODO: fetch this somewhere
+ deadlines: null,
+ tabulatorUuid: Vue.ref(0),
+ tableBuiltResolve: null,
+ tableBuiltPromise: null,
+ deadlineTableOptions: {
+ height: 700,
+ index: 'projektarbeit_id',
+ layout: 'fitColumns',
+ placeholder: this.$p.t('global/noDataAvailable'),
+ columns: [
+ {title: Vue.computed(() => this.$p.t('abgabetool/c4zieldatum')), field: 'datum', formatter: this.centeredTextFormatter, widthGrow: 1, tooltip: false},
+ {title: Vue.computed(() => this.$p.t('abgabetool/c4fixtermin')), field: 'fixterminstring', formatter: this.centeredTextFormatter, widthGrow: 1, tooltip: false},
+ {title: Vue.computed(() => this.$p.t('abgabetool/c4abgabetyp')), field: 'typ_bezeichnung', formatter: this.centeredTextFormatter, widthGrow: 1},
+ {title: Vue.computed(() => this.$p.t('abgabetool/c4abgabekurzbz')), field: 'kurzbz', formatter: this.centeredTextFormatter, widthGrow: 3},
+ {title: Vue.computed(() => this.$p.t('person/studentIn')), field: 'student', formatter: this.centeredTextFormatter, widthGrow: 2},
+ {title: Vue.computed(() => this.$p.t('abgabetool/c4stg')), field: 'stg', formatter: this.centeredTextFormatter,widthGrow: 1},
+ {title: Vue.computed(() => this.$p.t('abgabetool/c4sem')), field: 'semester', formatter: this.centeredTextFormatter, widthGrow: 1}
+ ],
+ persistence: false,
+ },
+ deadlineTableEventHandlers: [{
+ event: "tableBuilt",
+ handler: async () => {
+ this.tableBuiltResolve()
+ }
+ },
+ {
+ event: "cellClick",
+ handler: async (e, cell) => {
+
+ if(cell.getColumn().getField() === "details") {
+ const val = cell.getValue()
+
+ if(val.mode === 'detailTermine') {
+ this.setDetailComponent(cell.getValue())
+ } else if (val.mode === 'beurteilungDownload') {
+ const pdfExportLink = FHC_JS_DATA_STORAGE_OBJECT.app_root + 'cis/private/pdfExport.php?xml=projektarbeitsbeurteilung.xml.php&xsl=Projektbeurteilung&betreuerart_kurzbz='+val.betreuerart_kurzbz+'&projektarbeit_id='+val.projektarbeit_id+'&person_id=' + val.betreuer_person_id
+ // const pdfExportLink2 = FHC_JS_DATA_STORAGE_OBJECT.app_root + 'cis/private/lehre/projektbeurteilungDocumentExport.php?betreuerart_kurzbz='+val.betreuerart_kurzbz+'&projektarbeit_id='+val.projektarbeit_id+'&person_id=' + val.betreuer_person_id
+ window.open(pdfExportLink, '_blank')
+ }
+
+ } else if (cell.getColumn().getField() === "beurteilung") {
+ const val = cell.getValue()
+
+ if(val != '-') window.open(val, '_blank')
+ }
+ e.stopPropagation()
+
+ }
+ }
+ ]};
+ },
+ methods: {
+ centeredTextFormatter(cell) {
+ const val = cell.getValue()
+
+ return ''
+ },
+ tableResolve(resolve) {
+ this.tableBuiltResolve = resolve
+ },
+ loadDeadlines() {
+ this.$fhcApi.factory.lehre.fetchDeadlines(this.person_uid_prop ?? null)
+ .then(res => {
+ if(res?.data) this.setupData(res.data)
+ })
+ },
+ setupData(data) {
+ this.deadlines = data
+
+ this.deadlines.forEach(dl => {
+ dl.student = (dl.stud_titelpre ? (dl.stud_titelpre + ' ') :'') + dl.stud_vorname + ' ' + dl.stud_nachname + (dl.stud_titelpost ? (' ' + dl.stud_titelpost) :'')
+ dl.fixterminstring = dl.fixtermin ? this.$p.t('abgabetool/c4yes') : this.$p.t('abgabetool/c4no')
+ })
+
+ this.$refs.deadlineTable.tabulator.setColumns(this.deadlineTableOptions.columns)
+ this.$refs.deadlineTable.tabulator.setData(this.deadlines);
+ },
+ handleUuidDefined(uuid) {
+ this.tabulatorUuid = uuid
+ },
+ calcMaxTableHeight() {
+ const tableID = this.tabulatorUuid ? ('-' + this.tabulatorUuid) : ''
+ const tableDataSet = document.getElementById('filterTableDataset' + tableID);
+ if(!tableDataSet) return
+ const rect = tableDataSet.getBoundingClientRect();
+
+ this.deadlineTableOptions.height = window.visualViewport.height - rect.top
+ this.$refs.deadlineTable.tabulator.setHeight(this.deadlineTableOptions.height)
+ },
+ async setupMounted() {
+ this.tableBuiltPromise = new Promise(this.tableResolve)
+ await this.tableBuiltPromise
+
+ this.loadDeadlines()
+ this.calcMaxTableHeight()
+ }
+ },
+ watch: {
+
+ },
+ computed: {
+
+ },
+ created() {
+
+ },
+ mounted() {
+ this.setupMounted()
+ },
+ template: `
+ {{$p.t('abgabetool/deadlinesTitle')}} {{ fullName ? ('-' + fullName) : ''}}
+
+
+
+ `,
+};
+
+export default DeadlineOverview;
diff --git a/system/phrasesupdate.php b/system/phrasesupdate.php
index ae1c9daaa..9e9385c5c 100644
--- a/system/phrasesupdate.php
+++ b/system/phrasesupdate.php
@@ -30938,7 +30938,7 @@ array(
),
array(
'sprache' => 'English',
- 'text' => 'Wrong parameters tranferred',
+ 'text' => 'Wrong parameters transferred',
'description' => '',
'insertvon' => 'system'
)
@@ -37879,6 +37879,66 @@ array(
)
)
),
+ array(
+ 'app' => 'core',
+ 'category' => 'abgabetool',
+ 'phrase' => 'neuerTerminBachelorMasterbetreuung',
+ 'insertvon' => 'system',
+ 'phrases' => array(
+ array(
+ 'sprache' => 'German',
+ 'text' => "Neuer Termin Bachelor-/Masterarbeitsbetreuung",
+ 'description' => '',
+ 'insertvon' => 'system'
+ ),
+ array(
+ 'sprache' => 'English',
+ 'text' => "New date for Bachelor/Master thesis supervision",
+ 'description' => '',
+ 'insertvon' => 'system'
+ )
+ )
+ ),
+ array(
+ 'app' => 'core',
+ 'category' => 'abgabetool',
+ 'phrase' => 'neueTerminserie',
+ 'insertvon' => 'system',
+ 'phrases' => array(
+ array(
+ 'sprache' => 'German',
+ 'text' => "Terminserie anlegen",
+ 'description' => '',
+ 'insertvon' => 'system'
+ ),
+ array(
+ 'sprache' => 'English',
+ 'text' => "Create recurring deadline",
+ 'description' => '',
+ 'insertvon' => 'system'
+ )
+ )
+ ),
+ array(
+ 'app' => 'core',
+ 'category' => 'abgabetool',
+ 'phrase' => 'serienTerminEmailSentInfo',
+ 'insertvon' => 'system',
+ 'phrases' => array(
+ array(
+ 'sprache' => 'German',
+ 'text' => "Email über neuen Abgabetermin versendet an: {0}",
+ 'description' => '',
+ 'insertvon' => 'system'
+ ),
+ array(
+ 'sprache' => 'English',
+ 'text' => "Email about new deadline sent to: {0}",
+ 'description' => '',
+ 'insertvon' => 'system'
+ )
+ )
+ ),
array(
'app' => 'core',
'category' => 'abgabetool',
@@ -39784,6 +39844,26 @@ array(
)
)
),
+ array(
+ 'app' => 'core',
+ 'category' => 'abgabetool',
+ 'phrase' => 'c4aeltereParbeitBenoten',
+ 'insertvon' => 'system',
+ 'phrases' => array(
+ array(
+ 'sprache' => 'German',
+ 'text' => 'Projektarbeit für älteres Semester, bitte Word-Formular zur Benotung verwenden!',
+ 'description' => '',
+ 'insertvon' => 'system'
+ ),
+ array(
+ 'sprache' => 'English',
+ 'text' => 'Thesis handed in for older semester, please use word form for assessment!',
+ 'description' => '',
+ 'insertvon' => 'system'
+ )
+ )
+ ),
array(
'app' => 'core',
'category' => 'abgabetool',
@@ -39964,6 +40044,66 @@ array(
)
)
),
+ array(
+ 'app' => 'core',
+ 'category' => 'abgabetool',
+ 'phrase' => 'deadlinesTitle',
+ 'insertvon' => 'system',
+ 'phrases' => array(
+ array(
+ 'sprache' => 'German',
+ 'text' => "Terminübersicht",
+ 'description' => '',
+ 'insertvon' => 'system'
+ ),
+ array(
+ 'sprache' => 'English',
+ 'text' => "Deadline Overview",
+ 'description' => '',
+ 'insertvon' => 'system'
+ )
+ )
+ ),
+ array(
+ 'app' => 'core',
+ 'category' => 'abgabetool',
+ 'phrase' => 'c4yes',
+ 'insertvon' => 'system',
+ 'phrases' => array(
+ array(
+ 'sprache' => 'German',
+ 'text' => "Ja",
+ 'description' => '',
+ 'insertvon' => 'system'
+ ),
+ array(
+ 'sprache' => 'English',
+ 'text' => "Yes",
+ 'description' => '',
+ 'insertvon' => 'system'
+ )
+ )
+ ),
+ array(
+ 'app' => 'core',
+ 'category' => 'abgabetool',
+ 'phrase' => 'c4no',
+ 'insertvon' => 'system',
+ 'phrases' => array(
+ array(
+ 'sprache' => 'German',
+ 'text' => "Nein",
+ 'description' => '',
+ 'insertvon' => 'system'
+ ),
+ array(
+ 'sprache' => 'English',
+ 'text' => "No",
+ 'description' => '',
+ 'insertvon' => 'system'
+ )
+ )
+ ),
array(
'app' => 'core',
'category' => 'abgabetool',
@@ -40044,6 +40184,46 @@ array(
)
)
),
+ array(
+ 'app' => 'core',
+ 'category' => 'abgabetool',
+ 'phrase' => 'currentlySaving',
+ 'insertvon' => 'system',
+ 'phrases' => array(
+ array(
+ 'sprache' => 'German',
+ 'text' => "Speichern... ",
+ 'description' => '',
+ 'insertvon' => 'system'
+ ),
+ array(
+ 'sprache' => 'English',
+ 'text' => 'Saving... ',
+ 'description' => '',
+ 'insertvon' => 'system'
+ )
+ )
+ ),
+ array(
+ 'app' => 'core',
+ 'category' => 'abgabetool',
+ 'phrase' => 'currentlyLoading',
+ 'insertvon' => 'system',
+ 'phrases' => array(
+ array(
+ 'sprache' => 'German',
+ 'text' => "Laden... ",
+ 'description' => '',
+ 'insertvon' => 'system'
+ ),
+ array(
+ 'sprache' => 'English',
+ 'text' => 'Loading... ',
+ 'description' => '',
+ 'insertvon' => 'system'
+ )
+ )
+ ),
array(
'app' => 'core',
'category' => 'abgabetool',