mirror of
https://github.com/FH-Complete/FHC-Core.git
synced 2026-07-19 16:02:15 +00:00
match abgabetool_detail student/mitarbeiter look&feel; WIP terminserie, zweitbetreuer logic etc
This commit is contained in:
@@ -130,13 +130,26 @@ class Lehre extends FHCAPI_Controller
|
||||
public function getStudentProjektabgaben() {
|
||||
$projektarbeit_id = $this->input->get("projektarbeit_id",TRUE);
|
||||
|
||||
// TODO: error messages
|
||||
|
||||
if (!isset($projektarbeit_id) || isEmptyString($projektarbeit_id))
|
||||
$this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general');
|
||||
|
||||
$projektarbeit_obj = new projektarbeit();
|
||||
if($projektarbeit_id==-1)
|
||||
$this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general');
|
||||
|
||||
if(!$projektarbeit_obj->load($projektarbeit_id))
|
||||
$this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general');
|
||||
|
||||
$paIsCurrent = $projektarbeit_obj->projektarbeitIsCurrent($projektarbeit_id);
|
||||
|
||||
$this->load->model('education/Projektarbeit_model', 'ProjektarbeitModel');
|
||||
$ret = $this->ProjektarbeitModel->getProjektarbeitAbgabetermine($projektarbeit_id);
|
||||
|
||||
$this->terminateWithSuccess($ret);
|
||||
// TODO: fetch zweitbetreuer
|
||||
|
||||
$this->terminateWithSuccess(array($ret, $paIsCurrent));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -100,8 +100,8 @@ class Ort extends FHCAPI_Controller
|
||||
)
|
||||
";
|
||||
$params = array_merge($params, [$datum, $vonStunde, $bisStunde, $datum, $vonStunde, $bisStunde]);
|
||||
$this->addMeta('qry', $qry);
|
||||
$this->addMeta('params', $params);
|
||||
// $this->addMeta('qry', $qry);
|
||||
// $this->addMeta('params', $params);
|
||||
$result = $this->OrtModel->execReadOnlyQuery($qry, $params);
|
||||
|
||||
$this->terminateWithSuccess($result);
|
||||
|
||||
@@ -93,7 +93,6 @@ export const AbgabeMitarbeiterDetail = {
|
||||
})
|
||||
},
|
||||
deleteTermin(termin) {
|
||||
debugger
|
||||
this.$fhcApi.factory.lehre.deleteProjektarbeitAbgabe(termin.paabgabe_id).then( (res) => {
|
||||
if(res?.meta?.status == 'success') {
|
||||
this.$fhcAlert.alertSuccess(this.$p.t('ui/genericDeleted', [this.$p.t('abgabetool/abgabe')]))
|
||||
@@ -144,7 +143,7 @@ export const AbgabeMitarbeiterDetail = {
|
||||
color = 'green'
|
||||
}
|
||||
|
||||
return 'font-color: ' + fontColor + '; background-color: ' + color
|
||||
return `font-color: ${fontColor} ; background-color: ${color}; border-radius: 50%;`
|
||||
},
|
||||
openBeurteilungLink(link) {
|
||||
window.open(link, '_blank')
|
||||
@@ -167,7 +166,14 @@ export const AbgabeMitarbeiterDetail = {
|
||||
return `${day}.${month}.${year}`;
|
||||
},
|
||||
openStudentPage() {
|
||||
// TODO: do it
|
||||
const link = FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router
|
||||
+ '/Cis/Abgabetool/Student/' + this.projektarbeit?.student_uid
|
||||
window.open(link, '_blank')
|
||||
},
|
||||
openPlagiatcheck() {
|
||||
// todo: hardcoded turnitin link pfui?
|
||||
const link = "https://technikum-wien.turnitin.com/sso/sp/redwood/saml/5IyfmBr2OcSIaWQTKlFCGj/start"
|
||||
window.open(link, '_blank')
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
@@ -188,7 +194,14 @@ export const AbgabeMitarbeiterDetail = {
|
||||
},
|
||||
getEnduploadErlaubt() {
|
||||
return !this.eidAkzeptiert
|
||||
},
|
||||
getSemesterBenotbar(){
|
||||
return this.projektarbeit?.isCurrent ?? false
|
||||
},
|
||||
endUploadVorhanden(){
|
||||
return this.projektarbeit?.abgabetermine.find(abgabe => abgabe.paabgabetyp_kurzbz === 'end' && abgabe.abgabedatum !== null)
|
||||
}
|
||||
|
||||
},
|
||||
created() {
|
||||
|
||||
@@ -206,10 +219,20 @@ export const AbgabeMitarbeiterDetail = {
|
||||
<p> {{projektarbeit?.titel}}</p>
|
||||
<p v-if="projektarbeit?.zweitbegutachter"> {{projektarbeit?.zweitbegutachter}}</p>
|
||||
</div>
|
||||
<div>
|
||||
<button class="btn btn-primary border-0" @click="openStudentPage">
|
||||
Speichern
|
||||
<i style="margin-left: 8px" class="fa-solid fa-floppy-disk"></i>
|
||||
<div class="col-4 d-flex justify-content-end">
|
||||
<div>
|
||||
<button :disabled="!getSemesterBenotbar && endUploadVorhanden" class="btn btn-secondary border-0" @click="openPlagiatcheck" style="margin-right: 4px;">
|
||||
benoten
|
||||
<i style="margin-left: 8px" class="fa-solid fa-user-check"></i>
|
||||
</button>
|
||||
</div>
|
||||
<button v-if="projektarbeit?.betreuerart_kurzbz !== 'Zweitbegutachter'" class="btn btn-secondary border-0" @click="openPlagiatcheck" style="margin-right: 4px;">
|
||||
zur Plagiatsprüfung
|
||||
<i style="margin-left: 8px" class="fa-solid fa-user-check"></i>
|
||||
</button>
|
||||
<button class="btn btn-secondary border-0" @click="openStudentPage">
|
||||
Studentenansicht
|
||||
<i style="margin-left: 8px" class="fa-solid fa-eye"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -232,6 +255,7 @@ export const AbgabeMitarbeiterDetail = {
|
||||
<div class="col-2 d-flex justify-content-center align-items-center">
|
||||
<div :style="getDateStyle(termin)">
|
||||
<VueDatePicker
|
||||
style="width: 95%;"
|
||||
v-model="termin.datum"
|
||||
:clearable="false"
|
||||
:disabled="!termin.allowedToSave"
|
||||
|
||||
@@ -10,7 +10,8 @@ export const AbgabeStudentDetail = {
|
||||
InputNumber: primevue.inputnumber,
|
||||
Checkbox: primevue.checkbox,
|
||||
Dropdown: primevue.dropdown,
|
||||
Textarea: primevue.textarea
|
||||
Textarea: primevue.textarea,
|
||||
VueDatePicker
|
||||
},
|
||||
props: {
|
||||
projektarbeit: {
|
||||
@@ -82,6 +83,17 @@ export const AbgabeStudentDetail = {
|
||||
downloadAbgabe(termin) {
|
||||
this.$fhcApi.factory.lehre.getStudentProjektarbeitAbgabeFile(termin.paabgabe_id, this.projektarbeit.student_uid)
|
||||
},
|
||||
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}`;
|
||||
},
|
||||
upload(termin) {
|
||||
|
||||
if (!this.validate(termin))
|
||||
@@ -147,7 +159,7 @@ export const AbgabeStudentDetail = {
|
||||
color = 'green'
|
||||
}
|
||||
|
||||
return 'font-color: ' + fontColor + '; background-color: ' + color
|
||||
return `font-color: ${fontColor} ; background-color: ${color}; border-radius: 50%;`
|
||||
},
|
||||
openBeurteilungLink(link) {
|
||||
window.open(link, '_blank')
|
||||
@@ -193,9 +205,9 @@ export const AbgabeStudentDetail = {
|
||||
<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-2">{{$p.t('abgabetool/c4zieldatum')}}</div>
|
||||
<div class="col-2">{{$p.t('abgabetool/c4abgabetyp')}}</div>
|
||||
<div class="col-4">{{$p.t('abgabetool/c4abgabekurzbz')}}</div>
|
||||
<div class="col-1">{{$p.t('abgabetool/c4abgabedatum')}}</div>
|
||||
<div class="col">
|
||||
{{$p.t('abgabetool/c4fileupload')}}
|
||||
@@ -205,33 +217,42 @@ export const AbgabeStudentDetail = {
|
||||
<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 class="col-2 d-flex justify-content-center align-items-center">
|
||||
<div :style="getDateStyle(termin)">
|
||||
{{ termin.datum?.split("-").reverse().join(".") }}
|
||||
<VueDatePicker
|
||||
style="width: 95%;"
|
||||
v-model="termin.datum"
|
||||
:clearable="false"
|
||||
:disabled="true"
|
||||
:enable-time-picker="false"
|
||||
:format="formatDate"
|
||||
:text-input="true"
|
||||
auto-apply>
|
||||
</VueDatePicker>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-1 d-flex justify-content-center align-items-center">{{ termin.bezeichnung }}</div>
|
||||
<div class="col-2 d-flex justify-content-center align-items-center">{{ termin.kurzbz }}</div>
|
||||
<div class="col-2 d-flex justify-content-center align-items-center">{{ termin.bezeichnung }}</div>
|
||||
<div class="col-4 d-flex justify-content-center align-items-center">
|
||||
<Textarea style="margin-bottom: 4px;" v-model="termin.kurzbz" rows="3" cols="60" :disabled="true"></Textarea>
|
||||
</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="col-2" v-if="!viewMode">
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
<Upload v-if="termin && termin.allowedToUpload" :disabled="viewMode" accept=".pdf" v-model="termin.file"></Upload>
|
||||
<Upload v-if="termin && termin.allowedToUpload" accept=".pdf" v-model="termin.file"></Upload>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<button class="btn btn-primary border-0" @click="upload(termin)" :disabled="!termin.allowedToUpload || viewMode">
|
||||
<button class="btn btn-primary border-0" @click="upload(termin)" :disabled="!termin.allowedToUpload">
|
||||
Upload
|
||||
<i style="margin-left: 8px" class="fa-solid fa-upload"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -72,7 +72,6 @@ export const AbgabetoolMitarbeiter = {
|
||||
{
|
||||
event: "cellClick",
|
||||
handler: async (e, cell) => {
|
||||
debugger
|
||||
if(cell.getColumn().getField() === "details") {
|
||||
this.setDetailComponent(cell.getValue())
|
||||
}
|
||||
@@ -84,7 +83,6 @@ export const AbgabetoolMitarbeiter = {
|
||||
event: "rowClick",
|
||||
handler: async (e, row) => {
|
||||
|
||||
debugger
|
||||
e.stopPropagation()
|
||||
|
||||
}
|
||||
@@ -93,7 +91,6 @@ export const AbgabetoolMitarbeiter = {
|
||||
event: "rowSelected",
|
||||
handler: async (row) => {
|
||||
|
||||
debugger
|
||||
|
||||
}
|
||||
},
|
||||
@@ -123,7 +120,8 @@ export const AbgabetoolMitarbeiter = {
|
||||
setDetailComponent(details){
|
||||
this.loadAbgaben(details).then((res)=> {
|
||||
const pa = this.projektarbeiten?.retval?.find(projekarbeit => projekarbeit.projektarbeit_id == details.projektarbeit_id)
|
||||
pa.abgabetermine = res.data.retval
|
||||
pa.abgabetermine = res.data[0].retval
|
||||
pa.isCurrent = res.data[1]
|
||||
pa.abgabetermine.push({ // new abgatermin row
|
||||
|
||||
'paabgabe_id': -1,
|
||||
@@ -153,9 +151,9 @@ export const AbgabetoolMitarbeiter = {
|
||||
|
||||
this.selectedProjektarbeit = pa
|
||||
|
||||
Vue.nextTick(()=>{
|
||||
this.$refs.verticalsplit.showBoth()
|
||||
})
|
||||
|
||||
this.$refs.verticalsplit.showBoth()
|
||||
|
||||
|
||||
})
|
||||
},
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
import {CoreFilterCmpt} from "../../../components/filter/Filter.js";
|
||||
import AbgabeDetail from "./AbgabeStudentDetail.js";
|
||||
import VerticalSplit from "../../verticalsplit/verticalsplit.js";
|
||||
|
||||
export const AbgabetoolStudent = {
|
||||
name: "AbgabetoolStudent",
|
||||
components: {
|
||||
CoreFilterCmpt,
|
||||
AbgabeDetail
|
||||
AbgabeDetail,
|
||||
VerticalSplit
|
||||
},
|
||||
props: {
|
||||
student_uid_prop: {
|
||||
@@ -22,6 +24,7 @@ export const AbgabetoolStudent = {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
tabulatorUuid: Vue.ref(0),
|
||||
domain: '',
|
||||
student_uid: null,
|
||||
detail: null,
|
||||
@@ -30,7 +33,7 @@ export const AbgabetoolStudent = {
|
||||
tableBuiltResolve: null,
|
||||
tableBuiltPromise: null,
|
||||
abgabeTableOptions: {
|
||||
height: 300,
|
||||
height: 700,
|
||||
index: 'projektarbeit_id',
|
||||
layout: 'fitColumns',
|
||||
placeholder: this.$p.t('global/noDataAvailable'),
|
||||
@@ -85,7 +88,7 @@ export const AbgabetoolStudent = {
|
||||
setDetailComponent(details){
|
||||
this.loadAbgaben(details).then((res)=> {
|
||||
const pa = this.projektarbeiten?.retval?.find(projekarbeit => projekarbeit.projektarbeit_id == details.projektarbeit_id)
|
||||
pa.abgabetermine = res.data.retval
|
||||
pa.abgabetermine = res.data[0].retval
|
||||
pa.abgabetermine.forEach(termin => {
|
||||
termin.file = []
|
||||
termin.allowedToUpload = true
|
||||
@@ -103,6 +106,10 @@ export const AbgabetoolStudent = {
|
||||
pa.student_uid = this.student_uid
|
||||
|
||||
this.selectedProjektarbeit = pa
|
||||
|
||||
|
||||
this.$refs.verticalsplit.showBoth()
|
||||
|
||||
})
|
||||
|
||||
},
|
||||
@@ -195,12 +202,23 @@ export const AbgabetoolStudent = {
|
||||
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: {
|
||||
@@ -218,22 +236,28 @@ export const AbgabetoolStudent = {
|
||||
this.setupMounted()
|
||||
},
|
||||
template: `
|
||||
<h2>{{$p.t('abgabetool/abgabetoolTitle')}}</h2>
|
||||
<hr>
|
||||
|
||||
<core-filter-cmpt
|
||||
:title="''"
|
||||
ref="abgabeTable"
|
||||
:tabulator-options="abgabeTableOptions"
|
||||
:tabulator-events="abgabeTableEventHandlers"
|
||||
tableOnly
|
||||
:sideMenu="false"
|
||||
/>
|
||||
|
||||
<hr>
|
||||
<div v-show="selectedProjektarbeit">
|
||||
<AbgabeDetail :viewMode="isViewMode" :projektarbeit="selectedProjektarbeit"></AbgabeDetail>
|
||||
</div>
|
||||
<vertical-split ref="verticalsplit">
|
||||
<template #top>
|
||||
<h2>{{$p.t('abgabetool/abgabetoolTitle')}}</h2>
|
||||
<hr>
|
||||
|
||||
<core-filter-cmpt
|
||||
@uuidDefined="handleUuidDefined"
|
||||
:title="''"
|
||||
ref="abgabeTable"
|
||||
:tabulator-options="abgabeTableOptions"
|
||||
:tabulator-events="abgabeTableEventHandlers"
|
||||
tableOnly
|
||||
:sideMenu="false"
|
||||
/>
|
||||
|
||||
</template>
|
||||
<template #bottom>
|
||||
<div v-show="selectedProjektarbeit">
|
||||
<AbgabeDetail :viewMode="isViewMode" :projektarbeit="selectedProjektarbeit"></AbgabeDetail>
|
||||
</div>
|
||||
</template>
|
||||
</vertical-split>
|
||||
`,
|
||||
};
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
import {CoreFilterCmpt} from "../../../components/filter/Filter.js";
|
||||
|
||||
export const Raumsuche = {
|
||||
|
||||
@@ -20,6 +20,10 @@ export default {
|
||||
accept: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@@ -88,7 +92,7 @@ export default {
|
||||
},
|
||||
template: `
|
||||
<div class="form-upload-dms">
|
||||
<input ref="upload" class="form-control" :accept="accept" :class="inputClass" :id="id" :name="name" :multiple="multiple" type="file" @change="addFiles">
|
||||
<input ref="upload" class="form-control" :disabled="disabled" :accept="accept" :class="inputClass" :id="id" :name="name" :multiple="multiple" type="file" @change="addFiles">
|
||||
<ul v-if="modelValue.length && multiple && !noList" :accept="accept" class="list-unstyled m-0">
|
||||
<dms-item
|
||||
v-for="(file, index) in modelValue"
|
||||
|
||||
@@ -37879,6 +37879,66 @@ array(
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'abgabetool',
|
||||
'phrase' => 'c4abgabeMitarbeiterbereich',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => "Dokumentabgabe - Mitarbeiterbereich",
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => "File submission - Employee area",
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'abgabetool',
|
||||
'phrase' => 'abgabe',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => "Abgabe",
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'Submission',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'ui',
|
||||
'phrase' => 'genericDeleted',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => '{0} gelöscht',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => '{0} deleted',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'lehre',
|
||||
|
||||
Reference in New Issue
Block a user