mirror of
https://github.com/FH-Complete/FHC-Core.git
synced 2026-06-01 20:29:29 +00:00
WIP Abgabetool Mitarbeiter DetailComponent
This commit is contained in:
@@ -13,8 +13,10 @@ class Abgabetool extends Auth_Controller
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct([
|
||||
'index' => ['basis/cis:r'],
|
||||
'getStudentProjektarbeitAbgabeFile' => ['basis/cis:r']
|
||||
'index' => self::PERM_LOGGED,
|
||||
'getStudentProjektarbeitAbgabeFile' => self::PERM_LOGGED,
|
||||
'Mitarbeiter' => self::PERM_LOGGED,
|
||||
'Student' => self::PERM_LOGGED
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -33,7 +35,28 @@ class Abgabetool extends Auth_Controller
|
||||
|
||||
$this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'Abgabetool']);
|
||||
}
|
||||
|
||||
|
||||
public function Student()
|
||||
{
|
||||
|
||||
$viewData = array(
|
||||
'uid'=>getAuthUID(),
|
||||
);
|
||||
|
||||
$this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'Abgabetool']);
|
||||
}
|
||||
|
||||
public function Mitarbeiter()
|
||||
{
|
||||
|
||||
$viewData = array(
|
||||
'uid'=>getAuthUID(),
|
||||
);
|
||||
|
||||
$this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'Abgabetool']);
|
||||
}
|
||||
|
||||
|
||||
public function getStudentProjektarbeitAbgabeFile()
|
||||
{
|
||||
$this->_ci =& get_instance();
|
||||
|
||||
@@ -42,7 +42,8 @@ class Lehre extends FHCAPI_Controller
|
||||
'getStudentProjektarbeiten' => self::PERM_LOGGED, // TODO: abgabetool berechtigung?
|
||||
'getStudentProjektabgaben' => self::PERM_LOGGED,
|
||||
'postStudentProjektarbeitZwischenabgabe' => self::PERM_LOGGED,
|
||||
'postStudentProjektarbeitEndupload' => self::PERM_LOGGED
|
||||
'postStudentProjektarbeitEndupload' => self::PERM_LOGGED,
|
||||
'getMitarbeiterProjektarbeiten' => self::PERM_LOGGED
|
||||
]);
|
||||
|
||||
$this->load->library('PhrasesLib');
|
||||
@@ -443,5 +444,34 @@ class Lehre extends FHCAPI_Controller
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function getMitarbeiterProjektarbeiten() {
|
||||
$this->load->model('education/Projektarbeit_model', 'ProjektarbeitModel');
|
||||
|
||||
// if (!isset($uid) || isEmptyString($uid))
|
||||
// $this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general');
|
||||
|
||||
$boolParamStr = $this->input->get('showall');
|
||||
$trueStrings = ['true', '1'];
|
||||
$falseStrings = ['false', '0'];
|
||||
|
||||
// Handle missing or invalid parameter
|
||||
if ($boolParamStr === null) {
|
||||
$this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general');
|
||||
}
|
||||
$boolParamStrLower = strtolower($boolParamStr);
|
||||
|
||||
if (in_array($boolParamStrLower, $trueStrings, true)) {
|
||||
$showAllBool = true;
|
||||
} elseif (in_array($boolParamStrLower, $falseStrings, true)) {
|
||||
$showAllBool = false;
|
||||
} else {
|
||||
// $this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general');
|
||||
}
|
||||
|
||||
$projektarbeiten = $this->ProjektarbeitModel->getMitarbeiterProjektarbeiten(getAuthUID(), $showAllBool);
|
||||
|
||||
$this->terminateWithSuccess(array($projektarbeiten, DOMAIN));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -211,4 +211,34 @@ class Projektarbeit_model extends DB_Model
|
||||
|
||||
return $this->execReadOnlyQuery($qry, array($studentUID, $maUID));
|
||||
}
|
||||
|
||||
public function getMitarbeiterProjektarbeiten($uid, $showAll){
|
||||
$qry = "SELECT
|
||||
*
|
||||
FROM
|
||||
(SELECT tbl_person.vorname, tbl_person.nachname, tbl_studiengang.typ, tbl_studiengang.kurzbz,
|
||||
tbl_projektarbeit.projekttyp_kurzbz, tbl_projekttyp.bezeichnung, tbl_projektarbeit.titel, tbl_projektarbeit.projektarbeit_id,
|
||||
tbl_projektbetreuer.betreuerart_kurzbz, tbl_betreuerart.beschreibung AS betreuerart_beschreibung,
|
||||
tbl_benutzer.uid, tbl_student.matrikelnr, tbl_lehreinheit.studiensemester_kurzbz
|
||||
FROM lehre.tbl_projektarbeit
|
||||
LEFT JOIN lehre.tbl_projektbetreuer using(projektarbeit_id)
|
||||
LEFT JOIN lehre.tbl_betreuerart using(betreuerart_kurzbz)
|
||||
LEFT JOIN public.tbl_benutzer on(uid=student_uid)
|
||||
LEFT JOIN public.tbl_student on(public.tbl_benutzer.uid=public.tbl_student.student_uid)
|
||||
LEFT JOIN public.tbl_person on(tbl_benutzer.person_id=tbl_person.person_id)
|
||||
LEFT JOIN lehre.tbl_lehreinheit using(lehreinheit_id)
|
||||
LEFT JOIN lehre.tbl_lehrveranstaltung using(lehrveranstaltung_id)
|
||||
LEFT JOIN public.tbl_studiengang on(lehre.tbl_lehrveranstaltung.studiengang_kz=public.tbl_studiengang.studiengang_kz)
|
||||
LEFT JOIN lehre.tbl_projekttyp USING (projekttyp_kurzbz)
|
||||
WHERE (projekttyp_kurzbz='Bachelor' OR projekttyp_kurzbz='Diplom')
|
||||
AND tbl_projektbetreuer.person_id IN (SELECT person_id FROM public.tbl_benutzer
|
||||
WHERE public.tbl_benutzer.person_id=lehre.tbl_projektbetreuer.person_id
|
||||
AND public.tbl_benutzer.uid= ? )
|
||||
".($showAll?'':' AND public.tbl_benutzer.aktiv AND lehre.tbl_projektarbeit.note IS NULL ')."
|
||||
AND betreuerart_kurzbz IN ('Betreuer', 'Begutachter', 'Erstbegutachter', 'Zweitbegutachter', 'Erstbetreuer', 'Senatsvorsitz', 'Senatsmitglied')
|
||||
ORDER BY tbl_projektarbeit.projektarbeit_id, betreuerart_kurzbz desc) as xy
|
||||
ORDER BY nachname;";
|
||||
|
||||
return $this->execReadOnlyQuery($qry, array($uid));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,5 +48,11 @@ export default {
|
||||
const url = `/Cis/Abgabetool/getStudentProjektarbeitAbgabeFile?paabgabe_id=${paabgabe_id}&student_uid=${student_uid}`;
|
||||
|
||||
window.location = FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router + url
|
||||
},
|
||||
getMitarbeiterProjektarbeiten(uid, all) {
|
||||
return this.$fhcApi.get(
|
||||
`/api/frontend/v1/Lehre/getMitarbeiterProjektarbeiten?showall=${all}`
|
||||
, {}
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,8 @@ import CmsNews from "../../components/Cis/Cms/News.js";
|
||||
import CmsContent from "../../components/Cis/Cms/Content.js";
|
||||
import Info from "../../components/Cis/Mylv/Semester/Studiengang/Lv/Info.js";
|
||||
import RoomInformation, { DEFAULT_MODE_RAUMINFO } from "../../components/Cis/Mylv/RoomInformation.js";
|
||||
import Abgabetool from "../../components/Cis/Abgabetool/Abgabetool";
|
||||
import AbgabetoolStudent from "../../components/Cis/Abgabetool/AbgabetoolStudent.js";
|
||||
import AbgabetoolMitarbeiter from "../../components/Cis/Abgabetool/AbgabetoolMitarbeiter.js";
|
||||
|
||||
const ciPath = FHC_JS_DATA_STORAGE_OBJECT.app_root.replace(/(https:|)(^|\/\/)(.*?\/)/g, '') + FHC_JS_DATA_STORAGE_OBJECT.ci_router;
|
||||
|
||||
@@ -31,9 +32,15 @@ const router = VueRouter.createRouter({
|
||||
props: true
|
||||
},
|
||||
{
|
||||
path: `/Cis/Abgabetool`,
|
||||
name: 'Abgabetool',
|
||||
component: Abgabetool,
|
||||
path: `/Cis/Abgabetool/Student`,
|
||||
name: 'AbgabetoolStudent',
|
||||
component: AbgabetoolStudent,
|
||||
props: true
|
||||
},
|
||||
{
|
||||
path: `/Cis/Abgabetool/Mitarbeiter`,
|
||||
name: 'AbgabetoolMitarbeiter',
|
||||
component: AbgabetoolMitarbeiter,
|
||||
props: true
|
||||
},
|
||||
{
|
||||
@@ -211,8 +218,6 @@ const router = VueRouter.createRouter({
|
||||
]
|
||||
})
|
||||
|
||||
|
||||
|
||||
const app = Vue.createApp({
|
||||
name: 'FhcApp',
|
||||
data: () => ({
|
||||
|
||||
@@ -0,0 +1,286 @@
|
||||
import BsModal from '../../Bootstrap/Modal.js';
|
||||
|
||||
const today = new Date()
|
||||
export const AbgabeMitarbeiterDetail = {
|
||||
name: "AbgabeMitarbeiterDetail",
|
||||
components: {
|
||||
BsModal,
|
||||
InputNumber: primevue.inputnumber,
|
||||
Checkbox: primevue.checkbox,
|
||||
Dropdown: primevue.dropdown,
|
||||
Textarea: primevue.textarea
|
||||
},
|
||||
props: {
|
||||
projektarbeit: {
|
||||
type: Object,
|
||||
default: null
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
eidAkzeptiert: false,
|
||||
enduploadTermin: null,
|
||||
allActiveLanguages: FHC_JS_DATA_STORAGE_OBJECT.server_languages,
|
||||
form: Vue.reactive({
|
||||
sprache: '',
|
||||
abstract: '',
|
||||
abstract_en: '',
|
||||
schlagwoerter: '',
|
||||
schlagwoerter_en: '',
|
||||
kontrollschlagwoerter: '',
|
||||
seitenanzahl: 1,
|
||||
})
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
openZusatzdatenModal(termin) {
|
||||
|
||||
},
|
||||
save(termin) {
|
||||
// TODO: api speichern termin
|
||||
},
|
||||
delete(termin) {
|
||||
// TODO: api delete termin
|
||||
},
|
||||
validate: function(termin) {
|
||||
if(!termin.file.length) {
|
||||
this.$fhcAlert.alertWarning(this.$p.t('global/warningChooseFile'));
|
||||
return false
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
downloadAbgabe(termin) {
|
||||
this.$fhcApi.factory.lehre.getStudentProjektarbeitAbgabeFile(termin.paabgabe_id, this.projektarbeit.student_uid)
|
||||
},
|
||||
dateDiffInDays(datum, today){
|
||||
const oneDayMs = 1000 * 60 * 60 * 24
|
||||
return Math.round((new Date(datum) - new Date(today)) / oneDayMs)
|
||||
},
|
||||
getDateStyle(termin) {
|
||||
const datum = new Date(termin.datum)
|
||||
const abgabedatum = new Date(termin.abgabedatum)
|
||||
|
||||
// todo: rework styling but keep the color pattern logic
|
||||
// https://wiki.fhcomplete.info/doku.php?id=cis:abgabetool_fuer_studierende
|
||||
let color = 'white'
|
||||
let fontColor = 'black'
|
||||
if (termin.abgabedatum === null) {
|
||||
if(datum < today) {
|
||||
color = 'red'
|
||||
fontColor = 'white'
|
||||
} else if (datum > today && this.dateDiffInDays(datum, today) <= 12) {
|
||||
color = 'yellow'
|
||||
}
|
||||
} else if(abgabedatum > datum) {
|
||||
color = 'pink' // aka "hellrot"
|
||||
fontColor = 'white'
|
||||
} else {
|
||||
color = 'green'
|
||||
}
|
||||
|
||||
return 'font-color: ' + fontColor + '; background-color: ' + color
|
||||
},
|
||||
openBeurteilungLink(link) {
|
||||
window.open(link, '_blank')
|
||||
},
|
||||
getOptionLabel(option) {
|
||||
return option.sprache
|
||||
}
|
||||
},
|
||||
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
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
getEid() {
|
||||
return this.$p.t('abgabetool/c4eidesstattlicheErklaerung')
|
||||
},
|
||||
getEnduploadErlaubt() {
|
||||
return !this.eidAkzeptiert
|
||||
}
|
||||
},
|
||||
created() {
|
||||
|
||||
},
|
||||
mounted() {
|
||||
|
||||
},
|
||||
template: `
|
||||
<div v-if="projektarbeit">
|
||||
|
||||
<h5>{{$p.t('abgabetool/c4abgabeMitarbeiterbereich')}}</h5>
|
||||
<div class="row">
|
||||
<p> {{projektarbeit?.student}}</p>
|
||||
<p> {{projektarbeit?.titel}}</p>
|
||||
<p v-if="projektarbeit?.zweitbegutachter"> {{projektarbeit?.zweitbegutachter}}</p>
|
||||
</div>
|
||||
<div id="uploadWrapper">
|
||||
<div class="row" style="margin-bottom: 12px;">
|
||||
<div style="width: 100px">{{$p.t('abgabetool/c4fixtermin')}}</div>
|
||||
<div class="col-1">{{$p.t('abgabetool/c4zieldatum')}}</div>
|
||||
<div class="col-1">{{$p.t('abgabetool/c4abgabetyp')}}</div>
|
||||
<div class="col-2">{{$p.t('abgabetool/c4abgabekurzbz')}}</div>
|
||||
<div class="col-1">{{$p.t('abgabetool/c4abgabedatum')}}</div>
|
||||
<div class="col">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<!-- TODO: show some nothing found placeholder when abgabetermine are empty -->
|
||||
<div class="row" v-for="termin in projektarbeit.abgabetermine">
|
||||
<div style="width: 100px" class="d-flex justify-content-center align-items-center">
|
||||
<p class="fhc-bullet" :class="{ 'fhc-bullet-red': termin.fixtermin, 'fhc-bullet-green': !termin.fixtermin }"></p>
|
||||
</div>
|
||||
<div class="col-1 d-flex justify-content-center align-items-center">
|
||||
<div :style="getDateStyle(termin)">
|
||||
<!-- TODO: date input-->
|
||||
{{ termin.datum?.split("-").reverse().join(".") }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-1 d-flex justify-content-center align-items-center">
|
||||
<!-- TODO: type dropdown select -->
|
||||
{{ termin.bezeichnung }}
|
||||
</div>
|
||||
<div class="col-2 d-flex justify-content-center align-items-center">
|
||||
<!-- TODO: abgabe kurzbz input -->
|
||||
{{ termin.kurzbz }}
|
||||
</div>
|
||||
<div class="col-1 d-flex justify-content-center align-items-center">
|
||||
{{ termin.abgabedatum?.split("-").reverse().join(".") }}
|
||||
<a v-if="termin?.abgabedatum" @click="downloadAbgabe(termin)" style="margin-left:4px; cursor: pointer;">
|
||||
<i class="fa-solid fa-file-pdf"></i>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<div class="row">
|
||||
<div class="col-3">
|
||||
<button class="btn btn-primary border-0" @click="save(termin)" :disabled="!termin.allowedToUpload">
|
||||
Speichern
|
||||
<i style="margin-left: 8px" class="fa-solid fa-floppy-disk"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<button class="btn btn-primary border-0" @click="delete(termin)" :disabled="!termin.allowedToUpload">
|
||||
Löschen
|
||||
<i style="margin-left: 8px" class="fa-solid fa-trash"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div v-if="termin.endupload && hasFile" class="col-3">
|
||||
<button class="btn btn-primary border-0" @click="openZusatzdatenModal(termin)" :disabled="!termin.allowedToUpload">
|
||||
Löschen
|
||||
<i style="margin-left: 8px" class="fa-solid fa-trash"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<bs-modal ref="modalContainerEnduploadZusatzdaten" class="bootstrap-prompt" dialogClass="modal-lg">
|
||||
<template v-slot:title>
|
||||
<div>
|
||||
{{$p.t('abgabetool/c4enduploadZusatzdaten')}}
|
||||
</div>
|
||||
<div class="row mb-3 align-items-center">
|
||||
|
||||
<p class="ml-4 mr-4">Student UID: {{ projektarbeit?.student_uid}}</p>
|
||||
|
||||
</div>
|
||||
<div class="row mb-3 align-items-center">
|
||||
|
||||
<p class="ml-4 mr-4">Titel: {{ projektarbeit?.titel }}</p>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
<template v-slot:default>
|
||||
<div class="row mb-3 align-items-center">
|
||||
<div class="row">{{$p.t('abgabetool/c4Sprache')}}</div>
|
||||
<div class="row">
|
||||
<Dropdown
|
||||
:style="{'width': '100%'}"
|
||||
v-model="form.sprache"
|
||||
:options="allActiveLanguages"
|
||||
:optionLabel="getOptionLabel">
|
||||
</Dropdown>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3 align-items-center">
|
||||
<div class="row">Kontrollierte Schlagwörter</div>
|
||||
<div class="row">
|
||||
<Textarea v-model="form.kontrollschlagwoerter"></Textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-3 align-items-center">
|
||||
<div class="row">{{$p.t('abgabetool/c4schlagwoerterGer')}}</div>
|
||||
<div class="row">
|
||||
<Textarea v-model="form.schlagwoerter"></Textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3 align-items-center">
|
||||
<div class="row">{{$p.t('abgabetool/c4schlagwoerterEng')}}</div>
|
||||
<div class="row">
|
||||
<Textarea v-model="form.schlagwoerter_en"></Textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3 align-items-center">
|
||||
<div class="row">{{$p.t('abgabetool/c4abstractGer')}}</div>
|
||||
<div class="row">
|
||||
<Textarea v-model="form.abstract" rows="10"></Textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3 align-items-center">
|
||||
<div class="row">{{$p.t('abgabetool/c4abstractEng')}}</div>
|
||||
<div class="row">
|
||||
<Textarea v-model="form.abstract_en" rows="10"></Textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3 align-items-center">
|
||||
<div class="row">{{$p.t('abgabetool/c4seitenanzahl')}}</div>
|
||||
<div class="row">
|
||||
<InputNumber
|
||||
v-model="form.seitenanzahl"
|
||||
inputId="seitenanzahlInput" :min="1" :max="100000">
|
||||
</InputNumber>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="projektarbeit">
|
||||
<div v-html="getEid"></div>
|
||||
<div class="row">
|
||||
<div class="col-9"></div>
|
||||
<div class="col-2"><p>{{ $p.t('abgabetool/c4gelesenUndAkzeptiert') }}</p></div>
|
||||
<div class="col-1">
|
||||
|
||||
<Checkbox
|
||||
v-model="eidAkzeptiert"
|
||||
:binary="true"
|
||||
:pt="{ root: { class: 'ml-auto' }}"
|
||||
>
|
||||
</Checkbox>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
<template v-slot:footer>
|
||||
<button class="btn btn-primary" :disabled="getEnduploadErlaubt" @click="triggerEndupload">{{$p.t('ui/hochladen')}}</button>
|
||||
</template>
|
||||
</bs-modal>
|
||||
|
||||
`,
|
||||
};
|
||||
|
||||
export default AbgabeMitarbeiterDetail;
|
||||
+4
-4
@@ -2,8 +2,8 @@ import Upload from '../../../components/Form/Upload/Dms.js';
|
||||
import BsModal from '../../Bootstrap/Modal.js';
|
||||
|
||||
const today = new Date()
|
||||
export const AbgabeDetail = {
|
||||
name: "AbgabeDetail",
|
||||
export const AbgabeStudentDetail = {
|
||||
name: "AbgabeStudentDetail",
|
||||
components: {
|
||||
Upload,
|
||||
BsModal,
|
||||
@@ -210,7 +210,7 @@ export const AbgabeDetail = {
|
||||
<div class="col-2 d-flex justify-content-center align-items-center">{{ termin.kurzbz }}</div>
|
||||
<div class="col-1 d-flex justify-content-center align-items-center">
|
||||
{{ termin.abgabedatum?.split("-").reverse().join(".") }}
|
||||
<a v-if="termin?.abgabedatum" @click="downloadAbgabe(termin)" style="cursor: pointer;">
|
||||
<a v-if="termin?.abgabedatum" @click="downloadAbgabe(termin)" style="margin-left:4px; cursor: pointer;">
|
||||
<i class="fa-solid fa-file-pdf"></i>
|
||||
</a>
|
||||
</div>
|
||||
@@ -335,4 +335,4 @@ export const AbgabeDetail = {
|
||||
`,
|
||||
};
|
||||
|
||||
export default AbgabeDetail;
|
||||
export default AbgabeStudentDetail;
|
||||
@@ -0,0 +1,326 @@
|
||||
import {CoreFilterCmpt} from "../../../components/filter/Filter.js";
|
||||
import AbgabeDetail from "./AbgabeMitarbeiterDetail.js";
|
||||
import VerticalSplit from "../../verticalsplit/verticalsplit.js"
|
||||
|
||||
export const AbgabetoolMitarbeiter = {
|
||||
name: "AbgabetoolMitarbeiter",
|
||||
components: {
|
||||
CoreFilterCmpt,
|
||||
AbgabeDetail,
|
||||
VerticalSplit
|
||||
},
|
||||
props: {
|
||||
viewData: {
|
||||
type: Object,
|
||||
required: true,
|
||||
default: () => ({name: '', uid: ''}),
|
||||
validator(value) {
|
||||
return value && value.name && value.uid
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
showAll: false,
|
||||
tabulatorUuid: Vue.ref(0),
|
||||
selectedData: [],
|
||||
domain: '',
|
||||
student_uid: null,
|
||||
detail: null,
|
||||
detailOffset: 0,
|
||||
projektarbeiten: null,
|
||||
selectedProjektarbeit: null,
|
||||
tableBuiltResolve: null,
|
||||
tableBuiltPromise: null,
|
||||
abgabeTableOptions: {
|
||||
height: 300,
|
||||
index: 'projektarbeit_id',
|
||||
layout: 'fitDataStretch',
|
||||
placeholder: this.$p.t('global/noDataAvailable'),
|
||||
selectable: true,
|
||||
columns: [
|
||||
{
|
||||
formatter: 'rowSelection',
|
||||
titleFormatter: 'rowSelection',
|
||||
titleFormatterParams: {
|
||||
rowRange: "active" // Only toggle the values of the active filtered rows
|
||||
},
|
||||
hozAlign:"center",
|
||||
headerSort: false,
|
||||
frozen: true,
|
||||
width: 70
|
||||
},
|
||||
{title: Vue.computed(() => this.$p.t('abgabetool/c4details')), field: 'details', formatter: this.detailFormatter, widthGrow: 1, tooltip: false},
|
||||
{title: Vue.computed(() => this.$p.t('abgabetool/c4personenkennzeichen')), field: 'pkz', formatter: this.pkzTextFormatter, widthGrow: 1, tooltip: false},
|
||||
{title: Vue.computed(() => this.$p.t('abgabetool/c4kontakt')), field: 'mail', formatter: this.mailFormatter, widthGrow: 1, tooltip: false},
|
||||
{title: Vue.computed(() => this.$p.t('abgabetool/c4vorname')), field: 'vorname', formatter: this.centeredTextFormatter, widthGrow: 1},
|
||||
{title: Vue.computed(() => this.$p.t('abgabetool/c4nachname')), field: 'nachname', formatter: this.centeredTextFormatter, widthGrow: 1},
|
||||
{title: Vue.computed(() => this.$p.t('abgabetool/c4projekttyp')), field: 'projekttyp_kurzbz', formatter: this.centeredTextFormatter, widthGrow: 1},
|
||||
{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}
|
||||
],
|
||||
persistence: false,
|
||||
},
|
||||
abgabeTableEventHandlers: [{
|
||||
event: "tableBuilt",
|
||||
handler: async () => {
|
||||
this.tableBuiltResolve()
|
||||
}
|
||||
},
|
||||
{
|
||||
event: "cellClick",
|
||||
handler: async (e, cell) => {
|
||||
debugger
|
||||
if(cell.getColumn().getField() === "details") {
|
||||
this.setDetailComponent(cell.getValue())
|
||||
}
|
||||
e.stopPropagation()
|
||||
|
||||
}
|
||||
},
|
||||
{
|
||||
event: "rowClick",
|
||||
handler: async (e, row) => {
|
||||
|
||||
debugger
|
||||
e.stopPropagation()
|
||||
|
||||
}
|
||||
},
|
||||
{
|
||||
event: "rowSelected",
|
||||
handler: async (row) => {
|
||||
|
||||
debugger
|
||||
|
||||
}
|
||||
},
|
||||
{
|
||||
event: "rowSelectionChanged",
|
||||
handler: async(data) => {
|
||||
this.selectedData = data
|
||||
}
|
||||
}
|
||||
]};
|
||||
},
|
||||
methods: {
|
||||
showDeadlines(){
|
||||
// TODO: open seperate view in new window containing all future deadlines for the employee
|
||||
},
|
||||
toggleShowAll(showall) {
|
||||
this.showAll = showall
|
||||
this.loadProjektarbeiten(showall, () => { this.$refs.abgabeTable?.tabulator.redraw(true) })
|
||||
},
|
||||
addSeries() {
|
||||
|
||||
},
|
||||
isPastDate(date) {
|
||||
return new Date(date) < new Date(Date.now())
|
||||
},
|
||||
setDetailComponent(details){
|
||||
debugger
|
||||
this.loadAbgaben(details).then((res)=> {
|
||||
debugger
|
||||
const pa = this.projektarbeiten?.retval?.find(projekarbeit => projekarbeit.projektarbeit_id == details.projektarbeit_id)
|
||||
pa.abgabetermine = res.data.retval
|
||||
pa.abgabetermine.forEach(termin => {
|
||||
termin.file = []
|
||||
termin.allowedToUpload = true
|
||||
|
||||
// TODO: fixtermin logic?
|
||||
if(termin.bezeichnung == 'Endupload' && this.isPastDate(termin.datum)) {
|
||||
|
||||
// termin.allowedToUpload = false
|
||||
} else {
|
||||
// termin.allowedToUpload = true
|
||||
}
|
||||
|
||||
})
|
||||
pa.betreuer = this.buildBetreuer(pa)
|
||||
pa.student_uid = details.student_uid
|
||||
pa.student = `${pa.vorname} ${pa.nachname}`
|
||||
|
||||
this.selectedProjektarbeit = pa
|
||||
|
||||
Vue.nextTick(()=>{
|
||||
this.$refs.verticalsplit.showBoth()
|
||||
})
|
||||
|
||||
})
|
||||
},
|
||||
centeredTextFormatter(cell) {
|
||||
const val = cell.getValue()
|
||||
if(!val) return
|
||||
|
||||
return '<div style="display: flex; justify-content: center; align-items: center; height: 100%">' +
|
||||
'<p style="max-width: 100%; width: 100%; overflow-wrap: break-word; word-break: break-word; white-space: normal; margin: 0px; text-align: center">'+val+'</p></div>'
|
||||
},
|
||||
detailFormatter(cell) {
|
||||
return '<div style="display: flex; justify-content: center; align-items: center; height: 100%">' +
|
||||
'<a><i class="fa fa-folder-open" style="color:#00649C"></i></a></div>'
|
||||
},
|
||||
mailFormatter(cell) {
|
||||
const val = cell.getValue()
|
||||
return '<div style="display: flex; justify-content: center; align-items: center; height: 100%">' +
|
||||
'<a href='+val+'><i class="fa fa-envelope" style="color:#00649C"></i></a></div>'
|
||||
},
|
||||
beurteilungFormatter(cell) {
|
||||
const val = cell.getValue()
|
||||
if(val) {
|
||||
return '<div style="display: flex; justify-content: center; align-items: center; height: 100%">' +
|
||||
'<a><i class="fa fa-file-pdf" style="color:#00649C"></i></a></div>'
|
||||
} else return '-'
|
||||
},
|
||||
pkzTextFormatter(cell) {
|
||||
const val = cell.getValue()
|
||||
|
||||
return '<div style="display: flex; justify-content: center; align-items: center; height: 100%">' +
|
||||
'<p style="max-width: 100%; word-wrap: break-word; white-space: normal;">'+val+'</p></div>'
|
||||
},
|
||||
tableResolve(resolve) {
|
||||
this.tableBuiltResolve = resolve
|
||||
},
|
||||
buildMailToLink(abgabe) {
|
||||
return 'mailto:' + abgabe.uid +'@'+ this.domain
|
||||
},
|
||||
buildPKZ(projekt) {
|
||||
return `${projekt.uid} / ${projekt.matrikelnr}`
|
||||
},
|
||||
buildStg(projekt) {
|
||||
return (projekt.typ + projekt.kurzbz)?.toUpperCase()
|
||||
},
|
||||
buildBetreuer(abgabe) {
|
||||
return abgabe.betreuerart_beschreibung + ': ' + (abgabe.btitelpre ? abgabe.btitelpre + ' ' : '') + abgabe.bvorname + ' ' + abgabe.bnachname + (abgabe.btitelpost ? ' ' + abgabe.btitelpost : '')
|
||||
},
|
||||
setupData(data){
|
||||
this.projektarbeiten = data[0]
|
||||
this.domain = data[1]
|
||||
|
||||
const d = data[0]?.retval?.map(projekt => {
|
||||
let mode = 'detailTermine'
|
||||
|
||||
return {
|
||||
...projekt,
|
||||
details: {
|
||||
student_uid: projekt.uid,
|
||||
projektarbeit_id: projekt.projektarbeit_id,
|
||||
},
|
||||
pkz: this.buildPKZ(projekt),
|
||||
beurteilung: projekt.beurteilungLink ?? null,
|
||||
sem: projekt.studiensemester_kurzbz,
|
||||
stg: this.buildStg(projekt),
|
||||
mail: this.buildMailToLink(projekt),
|
||||
typ: projekt.projekttyp_kurzbz,
|
||||
titel: projekt.titel
|
||||
}
|
||||
})
|
||||
|
||||
this.$refs.abgabeTable.tabulator.setColumns(this.abgabeTableOptions.columns)
|
||||
this.$refs.abgabeTable.tabulator.setData(d);
|
||||
},
|
||||
loadProjektarbeiten(all = false, callback) {
|
||||
this.$fhcApi.factory.lehre.getMitarbeiterProjektarbeiten(this.viewData?.uid ?? null, all)
|
||||
.then(res => {
|
||||
if(res?.data) this.setupData(res.data)
|
||||
}).finally(() => {
|
||||
if(callback) {
|
||||
callback()
|
||||
}
|
||||
})
|
||||
},
|
||||
loadAbgaben(details) {
|
||||
return new Promise((resolve) => {
|
||||
this.$fhcApi.factory.lehre.getStudentProjektabgaben(details)
|
||||
.then(res => {
|
||||
resolve(res)
|
||||
})
|
||||
})
|
||||
},
|
||||
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.abgabeTableOptions.height = window.visualViewport.height - rect.top
|
||||
this.$refs.abgabeTable.tabulator.setHeight(this.abgabeTableOptions.height)
|
||||
},
|
||||
async setupMounted() {
|
||||
this.tableBuiltPromise = new Promise(this.tableResolve)
|
||||
await this.tableBuiltPromise
|
||||
|
||||
this.loadProjektarbeiten()
|
||||
|
||||
|
||||
this.$refs.verticalsplit.collapseBottom()
|
||||
this.calcMaxTableHeight()
|
||||
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
|
||||
},
|
||||
computed: {
|
||||
|
||||
},
|
||||
created() {
|
||||
|
||||
},
|
||||
mounted() {
|
||||
this.setupMounted()
|
||||
},
|
||||
template: `
|
||||
<div class="h-100">
|
||||
|
||||
|
||||
<h2>{{$p.t('abgabetool/abgabetoolTitle')}}</h2>
|
||||
<hr>
|
||||
|
||||
<vertical-split ref="verticalsplit">
|
||||
<template #top>
|
||||
<core-filter-cmpt
|
||||
:title="''"
|
||||
@uuidDefined="handleUuidDefined"
|
||||
ref="abgabeTable"
|
||||
:newBtnShow="true"
|
||||
:newBtnLabel="$p.t('global/neueTerminserie')"
|
||||
:newBtnDisabled="!selectedData.length"
|
||||
@click:new=addSeries
|
||||
:tabulator-options="abgabeTableOptions"
|
||||
:tabulator-events="abgabeTableEventHandlers"
|
||||
tableOnly
|
||||
:sideMenu="false"
|
||||
:useSelectionSpan="false"
|
||||
>
|
||||
<template #actions>
|
||||
<button @click="toggleShowAll(!showAll)" role="button" class="btn btn-secondary ml-2">
|
||||
<i v-show="!showAll" class="fa fa-eye"></i>
|
||||
<i v-show="showAll" class="fa fa-eye-slash"></i>
|
||||
{{ $p.t('abgabetool/showAll') }}
|
||||
</button>
|
||||
|
||||
<button @click="showDeadlines" role="button" class="btn btn-secondary ml-2">
|
||||
<i class="fa fa-hourglass-end"></i>
|
||||
{{ $p.t('abgabetool/showDeadlines') }}
|
||||
</button>
|
||||
</template>
|
||||
</core-filter-cmpt>
|
||||
</template>
|
||||
<template #bottom>
|
||||
<div v-show="selectedProjektarbeit" ref="selProj">
|
||||
<AbgabeDetail :projektarbeit="selectedProjektarbeit"></AbgabeDetail>
|
||||
</div>
|
||||
</template>
|
||||
</vertical-split>
|
||||
|
||||
</div>
|
||||
|
||||
`,
|
||||
};
|
||||
|
||||
export default AbgabetoolMitarbeiter;
|
||||
+6
-6
@@ -1,8 +1,8 @@
|
||||
import {CoreFilterCmpt} from "../../../components/filter/Filter.js";
|
||||
import AbgabeDetail from "./AbgabeDetail";
|
||||
import AbgabeDetail from "./AbgabeStudentDetail.js";
|
||||
|
||||
export const Abgabetool = {
|
||||
name: "Abgabetool",
|
||||
export const AbgabetoolStudent = {
|
||||
name: "AbgabetoolStudent",
|
||||
components: {
|
||||
VueDatePicker,
|
||||
CoreFilterCmpt,
|
||||
@@ -33,8 +33,8 @@ export const Abgabetool = {
|
||||
layout: 'fitColumns',
|
||||
placeholder: this.$p.t('global/noDataAvailable'),
|
||||
columns: [
|
||||
{title: Vue.computed(() => this.$p.t('abgabetool/c4details')), formatter: this.detailFormatter, field: 'details', widthGrow: 1, tooltip: false},
|
||||
{title: Vue.computed(() => this.$p.t('abgabetool/c4beurteilung')), formatter: this.beurteilungFormatter, field: 'beurteilung', widthGrow: 1, tooltip: false},
|
||||
{title: Vue.computed(() => this.$p.t('abgabetool/c4details')), field: 'details', formatter: this.detailFormatter, widthGrow: 1, tooltip: false},
|
||||
{title: Vue.computed(() => this.$p.t('abgabetool/c4beurteilung')), field: 'beurteilung', formatter: this.beurteilungFormatter, widthGrow: 1, tooltip: false},
|
||||
{title: Vue.computed(() => this.$p.t('abgabetool/c4sem')), field: 'sem', formatter: this.centeredTextFormatter, widthGrow: 1},
|
||||
{title: Vue.computed(() => this.$p.t('abgabetool/c4stg')), field: 'stg', formatter: this.centeredTextFormatter, widthGrow: 1},
|
||||
{title: Vue.computed(() => this.$p.t('abgabetool/c4kontakt')), field: 'mail', formatter: this.mailFormatter, widthGrow: 1},
|
||||
@@ -233,4 +233,4 @@ export const Abgabetool = {
|
||||
`,
|
||||
};
|
||||
|
||||
export default Abgabetool;
|
||||
export default AbgabetoolStudent;
|
||||
@@ -74,7 +74,11 @@ export const CoreFilterCmpt = {
|
||||
// TODO soll im master kommen?
|
||||
idField: String,
|
||||
parentIdField: String,
|
||||
countOnly: Boolean
|
||||
countOnly: Boolean,
|
||||
useSelectionSpan: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
},
|
||||
data: function() {
|
||||
return {
|
||||
@@ -613,7 +617,7 @@ export const CoreFilterCmpt = {
|
||||
<button v-if="reload" class="btn btn-outline-secondary" aria-label="Reload" @click="reloadTable">
|
||||
<span class="fa-solid fa-rotate-right" aria-hidden="true"></span>
|
||||
</button>
|
||||
<span v-if="$slots.actions && tabulatorHasSelector">
|
||||
<span v-if="$slots.actions && tabulatorHasSelector && useSelectionSpan">
|
||||
<span v-if="countOnly">{{ selectedData.length }} ausgewählt</span>
|
||||
<span v-else> Mit {{ selectedData.length }} ausgewählten:</span>
|
||||
</span>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
export default {
|
||||
name: 'VerticalSplit',
|
||||
data: function() {
|
||||
return {
|
||||
availHeight: 0,
|
||||
|
||||
@@ -38177,6 +38177,126 @@ array(
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'abgabetool',
|
||||
'phrase' => 'c4personenkennzeichen',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => "Personenkennzeichen",
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => "Personal identity number",
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'abgabetool',
|
||||
'phrase' => 'c4vorname',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => "Vorname",
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => "First Name",
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'abgabetool',
|
||||
'phrase' => 'c4nachname',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => "Nachname",
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'Last Name',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'abgabetool',
|
||||
'phrase' => 'c4betreuerart',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => "Betreuerart",
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'Supervisor type',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'abgabetool',
|
||||
'phrase' => 'showAll',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => "Alle anzeigen",
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'Show All',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'abgabetool',
|
||||
'phrase' => 'showDeadlines',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => "Deadlines anzeigen",
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'Show Deadlines',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'abgabetool',
|
||||
|
||||
Reference in New Issue
Block a user