mirror of
https://github.com/FH-Complete/FHC-Core.git
synced 2026-07-20 00:12:15 +00:00
NotenTab: Use Points
This commit is contained in:
@@ -97,6 +97,7 @@ class Config extends FHCAPI_Controller
|
||||
'showOnlyWithUid' => true,
|
||||
'config' => [
|
||||
'edit' => 'both', // Possible values: both|header|inline
|
||||
'usePoints' => defined('CIS_GESAMTNOTE_PUNKTE') && CIS_GESAMTNOTE_PUNKTE
|
||||
]
|
||||
];
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ class Notenschluesselaufteilung_model extends DB_Model
|
||||
* @param integer $lehrveranstaltung_id
|
||||
* @param string $studiensemester_kurzbz
|
||||
*
|
||||
* @return stdClass
|
||||
* @return stdClass returns success(null) if no entry is found
|
||||
*/
|
||||
public function getNote($points, $lehrveranstaltung_id, $studiensemester_kurzbz)
|
||||
{
|
||||
@@ -38,7 +38,7 @@ class Notenschluesselaufteilung_model extends DB_Model
|
||||
if (isError($result))
|
||||
return $result;
|
||||
if (!hasData($result))
|
||||
return error("Es wurde kein passender eintrag gefunden"); // TODO(chris): phrase
|
||||
return success(null);
|
||||
return success(current(getData($result))->note);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,8 @@ class Notenschluesselzuordnung_model extends DB_Model
|
||||
|
||||
$this->db->where("lehrveranstaltung_id", $lehrveranstaltung_id);
|
||||
if ($studiensemester_kurzbz) {
|
||||
$this->db->where_in("studiensemester_kurzbz", [$studiensemester_kurzbz, null]);
|
||||
$this->db->where("studiensemester_kurzbz", $studiensemester_kurzbz);
|
||||
$this->db->or_where("studiensemester_kurzbz", null);
|
||||
} else {
|
||||
$this->db->where("studiensemester_kurzbz", null);
|
||||
}
|
||||
|
||||
@@ -54,3 +54,12 @@
|
||||
z-index: 1;
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Make keyboard-focused list items look like the mouse-hovered list items
|
||||
*/
|
||||
.tabulator-edit-list .tabulator-edit-list-item.focused {
|
||||
color: #fff;
|
||||
background: #1d68cd;
|
||||
}
|
||||
@@ -52,7 +52,8 @@ export default {
|
||||
}
|
||||
);
|
||||
},
|
||||
getGradeFromPoints(points) {
|
||||
return this.$fhcApi.post('api/frontend/v1/stv/grades/getGradeFromPoints', data);
|
||||
getGradeFromPoints(points, lehrveranstaltung_id, manualErrorHandling) {
|
||||
const config = manualErrorHandling ? {errorHandling: false} : {};
|
||||
return this.$fhcApi.post('api/frontend/v1/stv/grades/getGradeFromPoints', {points, lehrveranstaltung_id}, config);
|
||||
}
|
||||
}
|
||||
@@ -33,48 +33,73 @@ export default {
|
||||
tooltip: (evt, cell) => cell.getData().note_bezeichnung
|
||||
};
|
||||
if (['both', 'inline'].includes(this.config.edit)) {
|
||||
gradeField = {...gradeField, ...{
|
||||
editor: 'list',
|
||||
editorParams: {
|
||||
valuesLookup: (cell, filterTerm) => listPromise,
|
||||
placeholderLoading: "Loading Remote Data...", // TODO(chris): phrase
|
||||
},
|
||||
cellEdited: cell => {
|
||||
// get row data
|
||||
const {lehrveranstaltung_id, uid: student_uid, studiensemester_kurzbz} = cell.getData();
|
||||
// get changed value
|
||||
const note = cell.getValue();
|
||||
|
||||
listPromise
|
||||
// get bezeichnung
|
||||
.then(list => list.find(el => el.value == note))
|
||||
.then(found => found ? found.label : Promise.reject({message: 'not found'}))
|
||||
// prepare data object
|
||||
.then(note_bezeichnung => ({
|
||||
lehrveranstaltung_id,
|
||||
student_uid,
|
||||
studiensemester_kurzbz,
|
||||
note,
|
||||
note_bezeichnung
|
||||
}))
|
||||
// send to backend
|
||||
.then(this.$fhcApi.factory.stv.grades.updateCertificate)
|
||||
// get bezeichnung again
|
||||
.then(() => listPromise)
|
||||
.then(list => list.find(el => el.value == note))
|
||||
.then(found => found ? found.label : Promise.reject({message: 'not found'}))
|
||||
// update other fields in row
|
||||
.then(note_bezeichnung => cell.getRow().update({note_bezeichnung}))
|
||||
.then(() => cell.getRow().reformat())
|
||||
// cleanup
|
||||
.then(cell.clearEdited)
|
||||
.catch(err => {
|
||||
cell.restoreOldValue();
|
||||
cell.clearEdited();
|
||||
this.$fhcAlert.handleFormValidation(err);
|
||||
});
|
||||
}
|
||||
}};
|
||||
gradeField.editor = 'list';
|
||||
gradeField.cellEdited = cell => {
|
||||
// get changed value
|
||||
const note = cell.getValue();
|
||||
if (note === '')
|
||||
return;
|
||||
|
||||
// get row data
|
||||
const {lehrveranstaltung_id, uid: student_uid, studiensemester_kurzbz} = cell.getData();
|
||||
|
||||
listPromise
|
||||
// get bezeichnung
|
||||
.then(list => list.find(el => el.value == note))
|
||||
.then(found => found ? found.label : Promise.reject({message: 'not found'}))
|
||||
// prepare data object
|
||||
.then(note_bezeichnung => ({
|
||||
lehrveranstaltung_id,
|
||||
student_uid,
|
||||
studiensemester_kurzbz,
|
||||
note,
|
||||
note_bezeichnung
|
||||
}))
|
||||
// send to backend
|
||||
.then(this.$fhcApi.factory.stv.grades.updateCertificate)
|
||||
// get bezeichnung again
|
||||
.then(() => listPromise)
|
||||
.then(list => list.find(el => el.value == note))
|
||||
.then(found => found ? found.label : Promise.reject({message: 'not found'}))
|
||||
// update other fields in row
|
||||
.then(note_bezeichnung => cell.getRow().update({note_bezeichnung}))
|
||||
.then(() => cell.getRow().reformat())
|
||||
// cleanup
|
||||
.then(cell.clearEdited)
|
||||
.catch(err => {
|
||||
cell.restoreOldValue();
|
||||
cell.clearEdited();
|
||||
this.$fhcAlert.handleFormValidation(err);
|
||||
});
|
||||
};
|
||||
if (this.config.usePoints) {
|
||||
gradeField.editorParams = {
|
||||
valuesLookup: (cell, filterTerm) => {
|
||||
if (filterTerm) {
|
||||
return this.$fhcApi.factory
|
||||
.stv.grades.getGradeFromPoints(filterTerm, cell.getData().lehrveranstaltung_id, true)
|
||||
.then(result =>
|
||||
result.data === null
|
||||
? []
|
||||
: listPromise.then(res => res.filter(grade => grade.value === result.data))
|
||||
)
|
||||
.catch(err => []);
|
||||
}
|
||||
return listPromise;
|
||||
},
|
||||
autocomplete: true,
|
||||
filterRemote: true,
|
||||
allowEmpty: true,
|
||||
listOnEmpty: true
|
||||
};
|
||||
gradeField.cellEditing = cell => cell.setValue('');
|
||||
gradeField.cellEditCancelled = cell => cell;
|
||||
} else {
|
||||
gradeField.editorParams = {
|
||||
valuesLookup: (cell, filterTerm) => listPromise
|
||||
};
|
||||
}
|
||||
gradeField.editorParams.placeholderLoading = "Loading Remote Data..." // TODO(chris): phrase
|
||||
}
|
||||
|
||||
const columns = [
|
||||
|
||||
@@ -1,4 +1,12 @@
|
||||
import CoreForm from '../../../../../Form/Form.js';
|
||||
import FormInput from '../../../../../Form/Input.js';
|
||||
|
||||
|
||||
export default {
|
||||
components: {
|
||||
CoreForm,
|
||||
FormInput
|
||||
},
|
||||
emits: [
|
||||
'setGrades'
|
||||
],
|
||||
@@ -10,7 +18,9 @@ export default {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
grades: []
|
||||
grades: [],
|
||||
suggestions: null,
|
||||
currentPoints: ''
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
@@ -34,6 +44,34 @@ export default {
|
||||
return { lehrveranstaltung_id, student_uid, studiensemester_kurzbz, note };
|
||||
}));
|
||||
}
|
||||
},
|
||||
currentLabel() {
|
||||
if (this.current == '')
|
||||
return 'Note setzen'; // TODO(chris): phrase
|
||||
return this.grades.find(grade => grade.note === this.current)?.bezeichnung || '';
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
convertPoints({evt, query}) {
|
||||
if (!query) {
|
||||
return this.suggestions = this.grades;
|
||||
}
|
||||
this.$refs.points.factory
|
||||
.stv.grades.getGradeFromPoints(query, this.selected.find(Boolean)?.lehrveranstaltung_id)
|
||||
.then(result => {
|
||||
if (result.data === null) {
|
||||
this.suggestions = [];
|
||||
return result;
|
||||
}
|
||||
this.suggestions = this.grades.filter(grade => grade.note == result.data);
|
||||
})
|
||||
.catch(this.$fhcAlert.handleSystemError);
|
||||
},
|
||||
setPoints({evt, value: {note}}) {
|
||||
if (this.selected)
|
||||
this.selected.forEach(grade => grade.note = note);
|
||||
this.currentPoints = '';
|
||||
this.current = note;
|
||||
}
|
||||
},
|
||||
created() {
|
||||
@@ -47,9 +85,30 @@ export default {
|
||||
// TODO(chris): phrases
|
||||
template: `
|
||||
<div class="stv-details-noten-zeugnis-actions">
|
||||
<select v-if="['both', 'header'].includes(config.edit)" class="form-select" v-model="current" :disabled="!selected.length">
|
||||
<option value="" disabled>Note setzen</option>
|
||||
<option v-for="grade in grades" :key="grade.note" :value="grade.note">{{ grade.bezeichnung }}</option>
|
||||
</select>
|
||||
<template v-if="['both', 'header'].includes(config.edit)">
|
||||
<core-form
|
||||
v-if="config.usePoints"
|
||||
ref="points"
|
||||
>
|
||||
<form-input
|
||||
type="autocomplete"
|
||||
name="points"
|
||||
v-model="currentPoints"
|
||||
:placeholder="currentLabel"
|
||||
:suggestions="suggestions"
|
||||
@complete="convertPoints"
|
||||
@item-select="setPoints"
|
||||
optionLabel="bezeichnung"
|
||||
dropdown
|
||||
forceSelection
|
||||
:disabled="!selected.length"
|
||||
>
|
||||
</form-input>
|
||||
</core-form>
|
||||
<select v-else class="form-select" v-model="current" :disabled="!selected.length">
|
||||
<option value="" disabled>Note setzen</option>
|
||||
<option v-for="grade in grades" :key="grade.note" :value="grade.note">{{ grade.bezeichnung }}</option>
|
||||
</select>
|
||||
</template>
|
||||
</div>`
|
||||
};
|
||||
Reference in New Issue
Block a user