mirror of
https://github.com/FH-Complete/FHC-Core.git
synced 2026-07-26 09:04:28 +00:00
Merge branch 'feature-61164/AbgabetoolQualityGates'
This commit is contained in:
@@ -41,3 +41,5 @@ $config['STG_MOODLE_LINK'] = 'https://moodle.technikum-wien.at/course/view.php?i
|
|||||||
|
|
||||||
$config['ASSISTENZ_SAMMELMAIL_BUTTON_STUDENT'] = true;
|
$config['ASSISTENZ_SAMMELMAIL_BUTTON_STUDENT'] = true;
|
||||||
$config['ASSISTENZ_SAMMELMAIL_BUTTON_BETREUER'] = true;
|
$config['ASSISTENZ_SAMMELMAIL_BUTTON_BETREUER'] = true;
|
||||||
|
|
||||||
|
$config['BETREUER_SAMMELMAIL_BUTTON_STUDENT'] = true;
|
||||||
|
|||||||
@@ -89,13 +89,15 @@ class Abgabe extends FHCAPI_Controller
|
|||||||
$abgabetypenBetreuer = $this->config->item('ALLOWED_ABGABETYPEN_BETREUER');
|
$abgabetypenBetreuer = $this->config->item('ALLOWED_ABGABETYPEN_BETREUER');
|
||||||
$ASSISTENZ_SAMMELMAIL_BUTTON_STUDENT = $this->config->item('ASSISTENZ_SAMMELMAIL_BUTTON_STUDENT');
|
$ASSISTENZ_SAMMELMAIL_BUTTON_STUDENT = $this->config->item('ASSISTENZ_SAMMELMAIL_BUTTON_STUDENT');
|
||||||
$ASSISTENZ_SAMMELMAIL_BUTTON_BETREUER = $this->config->item('ASSISTENZ_SAMMELMAIL_BUTTON_BETREUER');
|
$ASSISTENZ_SAMMELMAIL_BUTTON_BETREUER = $this->config->item('ASSISTENZ_SAMMELMAIL_BUTTON_BETREUER');
|
||||||
|
$BETREUER_SAMMELMAIL_BUTTON_STUDENT = $this->config->item('BETREUER_SAMMELMAIL_BUTTON_STUDENT');
|
||||||
|
|
||||||
$ret = array(
|
$ret = array(
|
||||||
'old_abgabe_beurteilung_link' => $old_abgabe_beurteilung_link,
|
'old_abgabe_beurteilung_link' => $old_abgabe_beurteilung_link,
|
||||||
'turnitin_link' => $turnitin_link,
|
'turnitin_link' => $turnitin_link,
|
||||||
'abgabetypenBetreuer' => $abgabetypenBetreuer,
|
'abgabetypenBetreuer' => $abgabetypenBetreuer,
|
||||||
'ASSISTENZ_SAMMELMAIL_BUTTON_STUDENT' => $ASSISTENZ_SAMMELMAIL_BUTTON_STUDENT,
|
'ASSISTENZ_SAMMELMAIL_BUTTON_STUDENT' => $ASSISTENZ_SAMMELMAIL_BUTTON_STUDENT,
|
||||||
'ASSISTENZ_SAMMELMAIL_BUTTON_BETREUER' => $ASSISTENZ_SAMMELMAIL_BUTTON_BETREUER
|
'ASSISTENZ_SAMMELMAIL_BUTTON_BETREUER' => $ASSISTENZ_SAMMELMAIL_BUTTON_BETREUER,
|
||||||
|
'BETREUER_SAMMELMAIL_BUTTON_STUDENT' => $BETREUER_SAMMELMAIL_BUTTON_STUDENT,
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->terminateWithSuccess($ret);
|
$this->terminateWithSuccess($ret);
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ export const AbgabeMitarbeiterDetail = {
|
|||||||
Message: primevue.message,
|
Message: primevue.message,
|
||||||
VueDatePicker
|
VueDatePicker
|
||||||
},
|
},
|
||||||
|
emits: ['paUpdated'],
|
||||||
inject: [
|
inject: [
|
||||||
'abgabeTypeOptions',
|
'abgabeTypeOptions',
|
||||||
'abgabetypenBetreuer',
|
'abgabetypenBetreuer',
|
||||||
@@ -132,8 +133,8 @@ export const AbgabeMitarbeiterDetail = {
|
|||||||
const noteOptExisting = this.allowedNotenOptions.find(opt => opt.note == existingTerminRes.note)
|
const noteOptExisting = this.allowedNotenOptions.find(opt => opt.note == existingTerminRes.note)
|
||||||
existingTerminRes.note = noteOptExisting
|
existingTerminRes.note = noteOptExisting
|
||||||
|
|
||||||
const existingTerminResCurrObj = this.projektarbeit.abgabetermine.find(paa => paa.paabgabe_id == existingTerminRes.paabgabe_id)
|
termin.paabgabetyp_kurzbz = newTerminRes.paabgabetyp_kurzbz
|
||||||
existingTerminResCurrObj.noteBackend = noteOpt // do NOT take noteOptExisting -> should reflect the "yes the qgate grade is confirmed in backend ux behaviour"
|
termin.noteBackend = noteOpt // do NOT take noteOptExisting -> should reflect the "yes the qgate grade is confirmed in backend ux behaviour"
|
||||||
termin.dateStyle = getDateStyleClass(termin, this.notenOptions)
|
termin.dateStyle = getDateStyleClass(termin, this.notenOptions)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,6 +175,8 @@ export const AbgabeMitarbeiterDetail = {
|
|||||||
} else {
|
} else {
|
||||||
this.showAutomagicModalPhrase = false
|
this.showAutomagicModalPhrase = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.$emit("paUpdated", this.projektarbeit)
|
||||||
} else if(res?.meta?.status == 'error'){
|
} else if(res?.meta?.status == 'error'){
|
||||||
this.$fhcAlert.alertError()
|
this.$fhcAlert.alertError()
|
||||||
}
|
}
|
||||||
@@ -257,6 +260,7 @@ export const AbgabeMitarbeiterDetail = {
|
|||||||
// this.$p.t('global/tooltipLektorDeleteKontrolle', [this.$entryParams.permissions.kontrolleDeleteMaxReach ])
|
// this.$p.t('global/tooltipLektorDeleteKontrolle', [this.$entryParams.permissions.kontrolleDeleteMaxReach ])
|
||||||
const deletedTerminIndex = this.projektarbeit.abgabetermine.findIndex(t => t.paabgabe_id === termin.paabgabe_id)
|
const deletedTerminIndex = this.projektarbeit.abgabetermine.findIndex(t => t.paabgabe_id === termin.paabgabe_id)
|
||||||
this.projektarbeit.abgabetermine.splice(deletedTerminIndex, 1)
|
this.projektarbeit.abgabetermine.splice(deletedTerminIndex, 1)
|
||||||
|
this.$emit("paUpdated", this.projektarbeit)
|
||||||
} else if(res?.meta?.status == 'error'){
|
} else if(res?.meta?.status == 'error'){
|
||||||
this.$fhcAlert.alertError()
|
this.$fhcAlert.alertError()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -210,12 +210,12 @@ export const AbgabetoolAssistenz = {
|
|||||||
headerFilter: dateFilter,
|
headerFilter: dateFilter,
|
||||||
headerFilterFunc: this.headerFilterTerminCol,
|
headerFilterFunc: this.headerFilterTerminCol,
|
||||||
sorter: this.sortFuncTerminCol,
|
sorter: this.sortFuncTerminCol,
|
||||||
field: 'prevTermin', formatter: this.abgabterminFormatter, widthGrow: 1, width: 220, tooltip: false},
|
field: 'prevTermin', formatter: this.abgabterminFormatter, widthGrow: 1, width: 250, tooltip: false},
|
||||||
{title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4nextAbgabetermin'))), field: 'nextTermin',
|
{title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4nextAbgabetermin'))), field: 'nextTermin',
|
||||||
headerFilter: dateFilter,
|
headerFilter: dateFilter,
|
||||||
headerFilterFunc: this.headerFilterTerminCol,
|
headerFilterFunc: this.headerFilterTerminCol,
|
||||||
sorter: this.sortFuncTerminCol,
|
sorter: this.sortFuncTerminCol,
|
||||||
formatter: this.abgabterminFormatter, widthGrow: 1, width: 220, tooltip: false},
|
formatter: this.abgabterminFormatter, widthGrow: 1, width: 250, tooltip: false},
|
||||||
{title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4qgate1Status'))),
|
{title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4qgate1Status'))),
|
||||||
headerFilter: 'list',
|
headerFilter: 'list',
|
||||||
headerFilterParams: { valuesLookup: this.getQGateStatusList },
|
headerFilterParams: { valuesLookup: this.getQGateStatusList },
|
||||||
@@ -226,7 +226,7 @@ export const AbgabetoolAssistenz = {
|
|||||||
field: 'qgate2Status', formatter: this.centeredTextFormatter, widthGrow: 1, width: 220, tooltip: false},
|
field: 'qgate2Status', formatter: this.centeredTextFormatter, widthGrow: 1, width: 220, tooltip: false},
|
||||||
],
|
],
|
||||||
persistence: false,
|
persistence: false,
|
||||||
persistenceID: "abgabetool_2026_02"
|
persistenceID: "abgabetool_2026_02_26"
|
||||||
},
|
},
|
||||||
abgabeTableEventHandlers: [
|
abgabeTableEventHandlers: [
|
||||||
{
|
{
|
||||||
@@ -247,6 +247,10 @@ export const AbgabetoolAssistenz = {
|
|||||||
]};
|
]};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
handlePaUpdated(projektarbeit) {
|
||||||
|
this.checkAbgabetermineProjektarbeit(projektarbeit)
|
||||||
|
this.$refs.abgabeTable.tabulator.redraw(true)
|
||||||
|
},
|
||||||
getQGateStatusList() {
|
getQGateStatusList() {
|
||||||
return [
|
return [
|
||||||
this.$p.t('abgabetool/c4keinTerminVorhanden'),
|
this.$p.t('abgabetool/c4keinTerminVorhanden'),
|
||||||
@@ -309,11 +313,13 @@ export const AbgabetoolAssistenz = {
|
|||||||
return false
|
return false
|
||||||
},
|
},
|
||||||
sammelMailStudent(param) {
|
sammelMailStudent(param) {
|
||||||
|
|
||||||
const emails = this.selectedData
|
const recipientList = [];
|
||||||
.map(row => `${row.student_uid}@${this.domain}`)
|
this.selectedData.forEach(d => {
|
||||||
.join(',');
|
recipientList.push(`${d.student_uid}@${this.domain}`)
|
||||||
const uniqueRecipients = [...new Set(emails)];
|
})
|
||||||
|
|
||||||
|
const uniqueRecipients = [...new Set(recipientList)];
|
||||||
const subject = this.$p.t('abgabetool/c4sammelmailStudentBetreff', [this.selectedStudiengangOption?.bezeichnung]);
|
const subject = this.$p.t('abgabetool/c4sammelmailStudentBetreff', [this.selectedStudiengangOption?.bezeichnung]);
|
||||||
splitMailsHelper(uniqueRecipients, param.originalEvent, subject, this.$fhcAlert, this.$p)
|
splitMailsHelper(uniqueRecipients, param.originalEvent, subject, this.$fhcAlert, this.$p)
|
||||||
},
|
},
|
||||||
@@ -362,7 +368,6 @@ export const AbgabetoolAssistenz = {
|
|||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
checkQualityGateStatus(projekt) {
|
checkQualityGateStatus(projekt) {
|
||||||
// TODO: might refine the representation of these states and maybe refactor code a little
|
|
||||||
const qgate1Termine = []
|
const qgate1Termine = []
|
||||||
const qgate2Termine = []
|
const qgate2Termine = []
|
||||||
|
|
||||||
@@ -382,7 +387,7 @@ export const AbgabetoolAssistenz = {
|
|||||||
// reuse luxon calculated diffMs (termin.datum in relation to today) from previous datestyle check
|
// reuse luxon calculated diffMs (termin.datum in relation to today) from previous datestyle check
|
||||||
qgate1Termine.forEach(qgate => {
|
qgate1Termine.forEach(qgate => {
|
||||||
if(qgate.note != null && projekt.qgate1StatusRank <= 5) {
|
if(qgate.note != null && projekt.qgate1StatusRank <= 5) {
|
||||||
const noteOpt = this.notenOptions.find(opt => opt.note == qgate.note)
|
const noteOpt = typeof qgate.note !== 'object' ? this.notenOptions.find(opt => opt.note == qgate.note) : qgate.note
|
||||||
if(noteOpt.positiv) {
|
if(noteOpt.positiv) {
|
||||||
projekt.qgate1Status = this.$p.t('abgabetool/c4positivBenotet')
|
projekt.qgate1Status = this.$p.t('abgabetool/c4positivBenotet')
|
||||||
projekt.qgate1StatusRank = 5
|
projekt.qgate1StatusRank = 5
|
||||||
@@ -404,7 +409,7 @@ export const AbgabetoolAssistenz = {
|
|||||||
|
|
||||||
qgate2Termine.forEach(qgate => {
|
qgate2Termine.forEach(qgate => {
|
||||||
if(qgate.note != null && projekt.qgate1StatusRank <= 5) {
|
if(qgate.note != null && projekt.qgate1StatusRank <= 5) {
|
||||||
const noteOpt = this.notenOptions.find(opt => opt.note == qgate.note)
|
const noteOpt = typeof qgate.note !== 'object' ? this.notenOptions.find(opt => opt.note == qgate.note) : qgate.note
|
||||||
if(noteOpt.positiv) {
|
if(noteOpt.positiv) {
|
||||||
projekt.qgate2Status = this.$p.t('abgabetool/c4positivBenotet')
|
projekt.qgate2Status = this.$p.t('abgabetool/c4positivBenotet')
|
||||||
projekt.qgate2StatusRank = 5
|
projekt.qgate2StatusRank = 5
|
||||||
@@ -1287,7 +1292,13 @@ export const AbgabetoolAssistenz = {
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template v-slot:default>
|
<template v-slot:default>
|
||||||
<AbgabeDetail :projektarbeit="selectedProjektarbeit" :isFullscreen="detailIsFullscreen" :assistenzMode="true"></AbgabeDetail>
|
<AbgabeDetail
|
||||||
|
:projektarbeit="selectedProjektarbeit"
|
||||||
|
:isFullscreen="detailIsFullscreen"
|
||||||
|
:assistenzMode="true"
|
||||||
|
@paUpdated="handlePaUpdated">
|
||||||
|
|
||||||
|
</AbgabeDetail>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
</bs-modal>
|
</bs-modal>
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import ApiAbgabe from '../../../api/factory/abgabe.js'
|
|||||||
import FhcOverlay from "../../Overlay/FhcOverlay.js";
|
import FhcOverlay from "../../Overlay/FhcOverlay.js";
|
||||||
import { getDateStyleClass } from "./getDateStyleClass.js";
|
import { getDateStyleClass } from "./getDateStyleClass.js";
|
||||||
import { dateFilter } from '../../../tabulator/filters/Dates.js';
|
import { dateFilter } from '../../../tabulator/filters/Dates.js';
|
||||||
|
import {splitMailsHelper} from "../../../helpers/EmailHelpers.js";
|
||||||
|
|
||||||
export const AbgabetoolMitarbeiter = {
|
export const AbgabetoolMitarbeiter = {
|
||||||
name: "AbgabetoolMitarbeiter",
|
name: "AbgabetoolMitarbeiter",
|
||||||
@@ -16,6 +17,7 @@ export const AbgabetoolMitarbeiter = {
|
|||||||
Checkbox: primevue.checkbox,
|
Checkbox: primevue.checkbox,
|
||||||
Dropdown: primevue.dropdown,
|
Dropdown: primevue.dropdown,
|
||||||
Textarea: primevue.textarea,
|
Textarea: primevue.textarea,
|
||||||
|
TieredMenu: primevue.tieredmenu,
|
||||||
VueDatePicker,
|
VueDatePicker,
|
||||||
FhcOverlay
|
FhcOverlay
|
||||||
},
|
},
|
||||||
@@ -48,6 +50,7 @@ export const AbgabetoolMitarbeiter = {
|
|||||||
phrasenResolved: false,
|
phrasenResolved: false,
|
||||||
turnitin_link: null,
|
turnitin_link: null,
|
||||||
old_abgabe_beurteilung_link: null,
|
old_abgabe_beurteilung_link: null,
|
||||||
|
BETREUER_SAMMELMAIL_BUTTON_STUDENT: null,
|
||||||
saving: false,
|
saving: false,
|
||||||
loading: false,
|
loading: false,
|
||||||
abgabeTypeOptions: null,
|
abgabeTypeOptions: null,
|
||||||
@@ -139,7 +142,6 @@ export const AbgabetoolMitarbeiter = {
|
|||||||
},
|
},
|
||||||
{title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4details'))), field: 'details', formatter: this.detailFormatter, headerFilter: false, headerSort: false, widthGrow: 1, tooltip: false, cssClass: 'sticky-col'},
|
{title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4details'))), field: 'details', formatter: this.detailFormatter, headerFilter: false, headerSort: false, widthGrow: 1, tooltip: false, cssClass: 'sticky-col'},
|
||||||
{title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4personenkennzeichen'))), headerFilter: true, field: 'pkz', formatter: this.pkzTextFormatter, widthGrow: 1, tooltip: false},
|
{title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4personenkennzeichen'))), headerFilter: true, field: 'pkz', formatter: this.pkzTextFormatter, widthGrow: 1, tooltip: false},
|
||||||
{title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4kontakt'))), field: 'mail', formatter: this.mailFormatter, widthGrow: 1, tooltip: false, visible: false},
|
|
||||||
{title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4vorname'))), field: 'vorname', headerFilter: true, formatter: this.centeredTextFormatter,widthGrow: 1},
|
{title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4vorname'))), field: 'vorname', headerFilter: true, formatter: this.centeredTextFormatter,widthGrow: 1},
|
||||||
{title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4nachname'))), field: 'nachname', headerFilter: true, formatter: this.centeredTextFormatter, widthGrow: 1},
|
{title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4nachname'))), field: 'nachname', headerFilter: true, formatter: this.centeredTextFormatter, widthGrow: 1},
|
||||||
{title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4projekttyp'))), field: 'projekttyp_kurzbz', formatter: this.centeredTextFormatter, widthGrow: 1},
|
{title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4projekttyp'))), field: 'projekttyp_kurzbz', formatter: this.centeredTextFormatter, widthGrow: 1},
|
||||||
@@ -151,12 +153,12 @@ export const AbgabetoolMitarbeiter = {
|
|||||||
headerFilter: dateFilter,
|
headerFilter: dateFilter,
|
||||||
headerFilterFunc: this.headerFilterTerminCol,
|
headerFilterFunc: this.headerFilterTerminCol,
|
||||||
sorter: this.sortFuncTerminCol,
|
sorter: this.sortFuncTerminCol,
|
||||||
formatter: this.abgabterminFormatter, widthGrow: 1, width: 220, tooltip: false},
|
formatter: this.abgabterminFormatter, widthGrow: 1, width: 250, tooltip: false},
|
||||||
{title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4nextAbgabetermin'))), field: 'nextTermin',
|
{title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4nextAbgabetermin'))), field: 'nextTermin',
|
||||||
headerFilter: dateFilter,
|
headerFilter: dateFilter,
|
||||||
headerFilterFunc: this.headerFilterTerminCol,
|
headerFilterFunc: this.headerFilterTerminCol,
|
||||||
sorter: this.sortFuncTerminCol,
|
sorter: this.sortFuncTerminCol,
|
||||||
formatter: this.abgabterminFormatter, widthGrow: 1, width: 220, tooltip: false},
|
formatter: this.abgabterminFormatter, widthGrow: 1, width: 250, tooltip: false},
|
||||||
{title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4qgate1Status'))),
|
{title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4qgate1Status'))),
|
||||||
headerFilter: 'list',
|
headerFilter: 'list',
|
||||||
headerFilterParams: { valuesLookup: this.getQGateStatusList },
|
headerFilterParams: { valuesLookup: this.getQGateStatusList },
|
||||||
@@ -167,7 +169,7 @@ export const AbgabetoolMitarbeiter = {
|
|||||||
field: 'qgate2Status', formatter: this.centeredTextFormatter, widthGrow: 1, width: 220, tooltip: false}
|
field: 'qgate2Status', formatter: this.centeredTextFormatter, widthGrow: 1, width: 220, tooltip: false}
|
||||||
],
|
],
|
||||||
persistence: false,
|
persistence: false,
|
||||||
persistenceID: 'abgabeTableBetreuer2026-02-24'
|
persistenceID: 'abgabeTableBetreuer2026-02-26'
|
||||||
},
|
},
|
||||||
abgabeTableEventHandlers: [{
|
abgabeTableEventHandlers: [{
|
||||||
event: "tableBuilt",
|
event: "tableBuilt",
|
||||||
@@ -203,6 +205,20 @@ export const AbgabetoolMitarbeiter = {
|
|||||||
]};
|
]};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
handlePaUpdated(projektarbeit) {
|
||||||
|
this.checkAbgabetermineProjektarbeit(projektarbeit)
|
||||||
|
this.$refs.abgabeTable.tabulator.redraw(true)
|
||||||
|
},
|
||||||
|
sammelMailStudent(param) {
|
||||||
|
|
||||||
|
const recipientList = [];
|
||||||
|
this.selectedData.forEach(d => {
|
||||||
|
recipientList.push(`${d.student_uid}@${this.domain}`)
|
||||||
|
})
|
||||||
|
const uniqueRecipients = [...new Set(recipientList)];
|
||||||
|
const subject = ""; // empty subject line
|
||||||
|
splitMailsHelper(uniqueRecipients, param.originalEvent, subject, this.$fhcAlert, this.$p)
|
||||||
|
},
|
||||||
getQGateStatusList() {
|
getQGateStatusList() {
|
||||||
return [
|
return [
|
||||||
this.$p.t('abgabetool/c4keinTerminVorhanden'),
|
this.$p.t('abgabetool/c4keinTerminVorhanden'),
|
||||||
@@ -375,7 +391,6 @@ export const AbgabetoolMitarbeiter = {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
checkQualityGateStatus(projekt) {
|
checkQualityGateStatus(projekt) {
|
||||||
// TODO: might refine the representation of these states and maybe refactor code a little
|
|
||||||
const qgate1Termine = []
|
const qgate1Termine = []
|
||||||
const qgate2Termine = []
|
const qgate2Termine = []
|
||||||
|
|
||||||
@@ -395,7 +410,7 @@ export const AbgabetoolMitarbeiter = {
|
|||||||
// reuse luxon calculated diffMs (termin.datum in relation to today) from previous datestyle check
|
// reuse luxon calculated diffMs (termin.datum in relation to today) from previous datestyle check
|
||||||
qgate1Termine.forEach(qgate => {
|
qgate1Termine.forEach(qgate => {
|
||||||
if(qgate.note != null && projekt.qgate1StatusRank <= 5) {
|
if(qgate.note != null && projekt.qgate1StatusRank <= 5) {
|
||||||
const noteOpt = this.notenOptions.find(opt => opt.note == qgate.note)
|
const noteOpt = typeof qgate.note !== 'object' ? this.notenOptions.find(opt => opt.note == qgate.note) : qgate.note
|
||||||
if(noteOpt.positiv) {
|
if(noteOpt.positiv) {
|
||||||
projekt.qgate1Status = this.$p.t('abgabetool/c4positivBenotet')
|
projekt.qgate1Status = this.$p.t('abgabetool/c4positivBenotet')
|
||||||
projekt.qgate1StatusRank = 5
|
projekt.qgate1StatusRank = 5
|
||||||
@@ -417,7 +432,7 @@ export const AbgabetoolMitarbeiter = {
|
|||||||
|
|
||||||
qgate2Termine.forEach(qgate => {
|
qgate2Termine.forEach(qgate => {
|
||||||
if(qgate.note != null && projekt.qgate1StatusRank <= 5) {
|
if(qgate.note != null && projekt.qgate1StatusRank <= 5) {
|
||||||
const noteOpt = this.notenOptions.find(opt => opt.note == qgate.note)
|
const noteOpt = typeof qgate.note !== 'object' ? this.notenOptions.find(opt => opt.note == qgate.note) : qgate.note
|
||||||
if(noteOpt.positiv) {
|
if(noteOpt.positiv) {
|
||||||
projekt.qgate2Status = this.$p.t('abgabetool/c4positivBenotet')
|
projekt.qgate2Status = this.$p.t('abgabetool/c4positivBenotet')
|
||||||
projekt.qgate2StatusRank = 5
|
projekt.qgate2StatusRank = 5
|
||||||
@@ -677,12 +692,13 @@ export const AbgabetoolMitarbeiter = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pa.abgabetermine.forEach(termin => {
|
pa.abgabetermine.forEach(termin => {
|
||||||
termin.note = this.allowedNotenOptions.find(opt => opt.note == termin.note)
|
const noteOpt = this.allowedNotenOptions.find(opt => opt.note == termin.note)
|
||||||
|
if(noteOpt) termin.note = noteOpt
|
||||||
termin.file = []
|
termin.file = []
|
||||||
|
|
||||||
// only set this if it has not been set yet and abgabetermin has a note (qgate)
|
// only set this if it has not been set yet and abgabetermin has a note (qgate)
|
||||||
if(!termin.noteBackend && termin.note) {
|
if(!termin.noteBackend && noteOpt) {
|
||||||
termin.noteBackend = termin.note
|
termin.noteBackend = noteOpt
|
||||||
}
|
}
|
||||||
|
|
||||||
// update 08-01-2026: everybody is allowed to do everything in client, critical checks happen at backend level
|
// update 08-01-2026: everybody is allowed to do everything in client, critical checks happen at backend level
|
||||||
@@ -719,11 +735,6 @@ export const AbgabetoolMitarbeiter = {
|
|||||||
return '<div style="display: flex; justify-content: center; align-items: center; height: 100%">' +
|
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>'
|
'<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) {
|
beurteilungFormatter(cell) {
|
||||||
const val = cell.getValue()
|
const val = cell.getValue()
|
||||||
if(val) {
|
if(val) {
|
||||||
@@ -828,6 +839,29 @@ export const AbgabetoolMitarbeiter = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
emailItems() {
|
||||||
|
const menu = []
|
||||||
|
|
||||||
|
if(this.BETREUER_SAMMELMAIL_BUTTON_STUDENT){
|
||||||
|
menu.push({
|
||||||
|
label: this.$p.t('abgabetool/c4sendEmailStudierendev2', [this.uniqueStudentEmailCount]),
|
||||||
|
command: this.sammelMailStudent
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return menu
|
||||||
|
},
|
||||||
|
uniqueStudentEmailCount() {
|
||||||
|
const emails = new Set();
|
||||||
|
|
||||||
|
this.selectedData.forEach(row => {
|
||||||
|
if (row.student_uid) {
|
||||||
|
emails.add(row.student_uid); // actually dont need domain for this
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return emails.size;
|
||||||
|
},
|
||||||
getAllowedAbgabeTypeOptions() {
|
getAllowedAbgabeTypeOptions() {
|
||||||
return this.abgabeTypeOptions.filter(opt => this.abgabetypenBetreuer.includes(opt.paabgabetyp_kurzbz))
|
return this.abgabeTypeOptions.filter(opt => this.abgabetypenBetreuer.includes(opt.paabgabetyp_kurzbz))
|
||||||
}
|
}
|
||||||
@@ -840,6 +874,7 @@ export const AbgabetoolMitarbeiter = {
|
|||||||
this.turnitin_link = res.data?.turnitin_link
|
this.turnitin_link = res.data?.turnitin_link
|
||||||
this.old_abgabe_beurteilung_link = res.data?.old_abgabe_beurteilung_link
|
this.old_abgabe_beurteilung_link = res.data?.old_abgabe_beurteilung_link
|
||||||
this.abgabetypenBetreuer = res.data?.abgabetypenBetreuer
|
this.abgabetypenBetreuer = res.data?.abgabetypenBetreuer
|
||||||
|
this.BETREUER_SAMMELMAIL_BUTTON_STUDENT = res.data?.BETREUER_SAMMELMAIL_BUTTON_STUDENT
|
||||||
}).catch(e => {
|
}).catch(e => {
|
||||||
this.loading = false
|
this.loading = false
|
||||||
})
|
})
|
||||||
@@ -952,7 +987,11 @@ export const AbgabetoolMitarbeiter = {
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template v-slot:default>
|
<template v-slot:default>
|
||||||
<AbgabeDetail :projektarbeit="selectedProjektarbeit" :isFullscreen="detailIsFullscreen"></AbgabeDetail>
|
<AbgabeDetail
|
||||||
|
:projektarbeit="selectedProjektarbeit"
|
||||||
|
:isFullscreen="detailIsFullscreen"
|
||||||
|
@paUpdated="handlePaUpdated">
|
||||||
|
</AbgabeDetail>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
</bs-modal>
|
</bs-modal>
|
||||||
@@ -988,7 +1027,17 @@ export const AbgabetoolMitarbeiter = {
|
|||||||
<i class="fa fa-hourglass-end"></i>
|
<i class="fa fa-hourglass-end"></i>
|
||||||
{{ $p.t('abgabetool/showDeadlines') }}
|
{{ $p.t('abgabetool/showDeadlines') }}
|
||||||
</button>
|
</button>
|
||||||
|
<button
|
||||||
|
v-if="emailItems.length"
|
||||||
|
role="button"
|
||||||
|
@click="evt => $refs.menu.toggle(evt)"
|
||||||
|
class="btn btn-outline-secondary dropdown-toggle"
|
||||||
|
aria-haspopup="true"
|
||||||
|
>
|
||||||
|
<i class="fa fa-envelope"></i>
|
||||||
|
</button>
|
||||||
|
<tiered-menu ref="menu" :model="emailItems" popup :autoZIndex="false" />
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
</core-filter-cmpt>
|
</core-filter-cmpt>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user