mirror of
https://github.com/FH-Complete/FHC-Core.git
synced 2026-10-12 15:04:04 +00:00
course picker
- kurse vom lektor koennen angezeigt werden - searchbar button hinzuefuegt um kurse vom lektor im course picker zu laden
This commit is contained in:
@@ -5,11 +5,13 @@ if (! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
class Coursepicker extends FHCAPI_Controller
|
||||
{
|
||||
private $_ci;
|
||||
|
||||
const ALLOWED_COURSE_FILTER = ['uid', 'stg'];
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct([
|
||||
'search' => self::PERM_LOGGED,
|
||||
'getByStg' => self::PERM_LOGGED
|
||||
'getCourses' => self::PERM_LOGGED,
|
||||
]);
|
||||
|
||||
$this->_ci = &get_instance();
|
||||
@@ -22,88 +24,40 @@ class Coursepicker extends FHCAPI_Controller
|
||||
$this->loadPhrases(['ui']);
|
||||
}
|
||||
|
||||
public function search()
|
||||
{
|
||||
$query = $this->input->get('query');
|
||||
if (is_null($query))
|
||||
$this->terminateWithError($this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
|
||||
|
||||
$query_words = explode(' ', $query);
|
||||
|
||||
//TODO Where weiter anpassen z.B. Fachbereich
|
||||
$this->_ci->LehreinheitModel->addSelect('tbl_lehreinheit.lehreinheit_id,
|
||||
tbl_lehreinheit.lvnr,
|
||||
tbl_lehreinheit.lehrfach_id,
|
||||
lehrfach.kurzbz AS lehrfach,
|
||||
lehrfach.bezeichnung AS lehrfach_bez,
|
||||
lehrfach.farbe AS lehrfach_farbe,
|
||||
tbl_lehreinheit.lehrform_kurzbz AS lehrform,
|
||||
lema.mitarbeiter_uid AS lektor_uid,
|
||||
tbl_mitarbeiter.kurzbz AS lektor,
|
||||
tbl_studiengang.studiengang_kz,
|
||||
upper(tbl_studiengang.typ::character varying::text || tbl_studiengang.kurzbz::text) AS studiengang,
|
||||
lvb.semester,
|
||||
lvb.verband,
|
||||
lvb.gruppe,
|
||||
lvb.gruppe_kurzbz,
|
||||
tbl_lehreinheit.raumtyp,
|
||||
tbl_lehreinheit.raumtypalternativ,
|
||||
tbl_lehreinheit.stundenblockung,
|
||||
tbl_lehreinheit.wochenrythmus,
|
||||
lema.semesterstunden,
|
||||
lema.planstunden,
|
||||
tbl_lehreinheit.start_kw,
|
||||
tbl_lehreinheit.anmerkung,
|
||||
tbl_lehreinheit.studiensemester_kurzbz');
|
||||
|
||||
$this->_ci->LehreinheitModel->addJoin('lehre.tbl_lehreinheitmitarbeiter lema', 'tbl_lehreinheit.lehreinheit_id = lema.lehreinheit_id');
|
||||
$this->_ci->LehreinheitModel->addJoin('lehre.tbl_lehreinheitgruppe lvb', 'tbl_lehreinheit.lehreinheit_id = lvb.lehreinheit_id');
|
||||
$this->_ci->LehreinheitModel->addJoin('public.tbl_studiengang', 'lvb.studiengang_kz = tbl_studiengang.studiengang_kz');
|
||||
$this->_ci->LehreinheitModel->addJoin('lehre.tbl_lehrveranstaltung lehrfach', 'tbl_lehreinheit.lehrfach_id = lehrfach.lehrveranstaltung_id');
|
||||
$this->_ci->LehreinheitModel->addJoin('public.tbl_mitarbeiter', 'lema.mitarbeiter_uid = tbl_mitarbeiter.mitarbeiter_uid');
|
||||
$this->_ci->LehreinheitModel->addJoin('lehre.tbl_lehrform', 'tbl_lehrform.lehrform_kurzbz = tbl_lehreinheit.lehrform_kurzbz');
|
||||
|
||||
$this->_ci->MitarbeiterModel->db->group_start();
|
||||
|
||||
foreach ($query_words as $word)
|
||||
{
|
||||
$this->_ci->LehreinheitModel->db->group_start();
|
||||
$this->_ci->LehreinheitModel->db->where('lema.mitarbeiter_uid ILIKE', "%" . $word . "%");
|
||||
$this->_ci->LehreinheitModel->db->or_where('lvb.gruppe_kurzbz ILIKE', "%" . $word . "%");
|
||||
$this->_ci->LehreinheitModel->db->or_where('tbl_studiengang.kurzbzlang ILIKE', "%" . $word . "%");
|
||||
$this->_ci->LehreinheitModel->db->or_where('lvb.verband ILIKE', "%" . $word . "%");
|
||||
$this->_ci->LehreinheitModel->db->or_where('lvb.gruppe ILIKE', "%" . $word . "%");
|
||||
$this->_ci->LehreinheitModel->db->or_where('lehrfach.bezeichnung ILIKE', "%" . $word . "%");
|
||||
|
||||
if (is_numeric($word))
|
||||
{
|
||||
$this->_ci->LehreinheitModel->db->or_where('tbl_studiengang.studiengang_kz', $word);
|
||||
$this->_ci->LehreinheitModel->db->or_where('lvb.semester', $word);
|
||||
}
|
||||
$this->_ci->LehreinheitModel->db->group_end();
|
||||
|
||||
}
|
||||
$this->_ci->LehreinheitModel->db->group_end();
|
||||
$this->_ci->LehreinheitModel->db->where('tbl_lehreinheit.studiensemester_kurzbz = \'SS2025\'');
|
||||
$this->_ci->LehreinheitModel->db->where(array('tbl_lehrform.verplanen' => true));
|
||||
|
||||
$result = $this->_ci->LehreinheitModel->load();
|
||||
|
||||
$this->terminateWithSuccess(hasData($result) ? getData($result) : array());
|
||||
}
|
||||
|
||||
public function getByStg()
|
||||
public function getCourses()
|
||||
{
|
||||
$this->_ci->form_validation->set_data($_POST);
|
||||
$this->_ci->form_validation->set_rules('studiengaenge[]',"studiengaenge","required");
|
||||
$this->_ci->form_validation->set_rules('studiensemester_kurzbz',"studiensemester_kurzbz","required");
|
||||
|
||||
if($this->_ci->form_validation->run() === FALSE)
|
||||
$this->terminateWithValidationErrors($this->_ci->form_validation->error_array());
|
||||
|
||||
$studiengaenge = $this->input->post('studiengaenge');
|
||||
$studiensemester_kurzbz = $this->input->post('studiensemester_kurzbz');
|
||||
$studiensemester_kurzbz = $this->_ci->input->post('studiensemester_kurzbz', TRUE);
|
||||
|
||||
$filter = $this->_checkFilter(self::ALLOWED_COURSE_FILTER);
|
||||
|
||||
$this->_getBasePlan($studiensemester_kurzbz);
|
||||
|
||||
$this->_ci->LehreinheitModel->db->group_start();
|
||||
if (isset($filter->stg))
|
||||
$this->_addStgWhere($filter->stg);
|
||||
|
||||
if (isset($filter->uid))
|
||||
{
|
||||
$uid_array = (array) $filter->uid;
|
||||
$this->_ci->LehreinheitModel->db->or_where_in('tbl_benutzer.uid', $uid_array);
|
||||
}
|
||||
|
||||
$this->_ci->LehreinheitModel->db->group_end();
|
||||
|
||||
$this->_ci->LehreinheitModel->addOrder('lehreinheit_id');
|
||||
$result = $this->_ci->LehreinheitModel->load();
|
||||
$result = hasData($result) ? getData($result) : array();
|
||||
$this->terminateWithSuccess($this->_mapEvents($result));
|
||||
}
|
||||
|
||||
private function _getBasePlan($studiensemester_kurzbz)
|
||||
{
|
||||
$this->_ci->LehreinheitModel->addSelect('
|
||||
tbl_lehreinheit.lehreinheit_id,
|
||||
tbl_lehreinheit.lvnr,
|
||||
@@ -142,6 +96,15 @@ class Coursepicker extends FHCAPI_Controller
|
||||
$this->_ci->LehreinheitModel->addJoin('public.tbl_benutzer', 'ma.mitarbeiter_uid = tbl_benutzer.uid');
|
||||
$this->_ci->LehreinheitModel->addJoin('public.tbl_person', 'tbl_benutzer.person_id = tbl_person.person_id');
|
||||
|
||||
$this->_ci->LehreinheitModel->db->group_start();
|
||||
$this->_ci->LehreinheitModel->db->where('tbl_lehrform.verplanen', true);
|
||||
$this->_ci->LehreinheitModel->db->where('tbl_lehreinheit.studiensemester_kurzbz', $studiensemester_kurzbz);
|
||||
$this->_ci->LehreinheitModel->db->group_end();
|
||||
|
||||
}
|
||||
|
||||
private function _addStgWhere($studiengaenge)
|
||||
{
|
||||
$this->_ci->LehreinheitModel->db->group_start();
|
||||
$first = true;
|
||||
foreach ($studiengaenge as $studiengang)
|
||||
@@ -165,14 +128,10 @@ class Coursepicker extends FHCAPI_Controller
|
||||
$this->_ci->LehreinheitModel->db->group_end();
|
||||
}
|
||||
$this->_ci->LehreinheitModel->db->group_end();
|
||||
}
|
||||
|
||||
$result = $this->_ci->LehreinheitModel->loadWhere(array(
|
||||
'tbl_lehrform.verplanen' => true,
|
||||
'tbl_lehreinheit.studiensemester_kurzbz' => $studiensemester_kurzbz
|
||||
));
|
||||
|
||||
$result = hasData($result) ? getData($result) : array();
|
||||
|
||||
private function _mapEvents($result)
|
||||
{
|
||||
$lehreinheit_ids = array_values(array_unique(array_column($result, 'lehreinheit_id')));
|
||||
|
||||
$offen_map = array();
|
||||
@@ -281,10 +240,8 @@ class Coursepicker extends FHCAPI_Controller
|
||||
$group->verplant = $this->_formatArr($group->verplant);
|
||||
$group->offenestunden = $this->_formatArr($group->offenestunden);
|
||||
}
|
||||
|
||||
$this->terminateWithSuccess(array_values($grouped));
|
||||
return array_values($grouped);
|
||||
}
|
||||
|
||||
private function _formatArr($arr)
|
||||
{
|
||||
$values = array_values(array_unique($arr));
|
||||
@@ -296,5 +253,24 @@ class Coursepicker extends FHCAPI_Controller
|
||||
return $formatted;
|
||||
}
|
||||
|
||||
private function _checkFilter($filters)
|
||||
{
|
||||
$filter_valid = false;
|
||||
$filter_object = new stdClass();
|
||||
foreach ($filters as $filter)
|
||||
{
|
||||
if ($this->_ci->input->post($filter))
|
||||
{
|
||||
$filter_valid = true;
|
||||
$filter_object->$filter = $this->_ci->input->post($filter);
|
||||
}
|
||||
}
|
||||
|
||||
if (!$filter_valid)
|
||||
$this->terminateWithError($this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
|
||||
|
||||
return $filter_object;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,16 +1,9 @@
|
||||
export default {
|
||||
search(query) {
|
||||
return {
|
||||
method: 'get',
|
||||
url: 'api/frontend/v1/tempus/coursepicker/search',
|
||||
params: { query }
|
||||
};
|
||||
},
|
||||
getByStg(studiengaenge, studiensemester_kurzbz) {
|
||||
getCourses(filter, studiensemester_kurzbz) {
|
||||
return {
|
||||
method: 'post',
|
||||
url: 'api/frontend/v1/tempus/coursepicker/getByStg',
|
||||
params: { studiengaenge, studiensemester_kurzbz }
|
||||
url: 'api/frontend/v1/tempus/coursepicker/getCourses',
|
||||
params: { ...filter, studiensemester_kurzbz }
|
||||
};
|
||||
},
|
||||
|
||||
|
||||
@@ -14,6 +14,10 @@ export default {
|
||||
type: Array,
|
||||
default: [],
|
||||
},
|
||||
lecturers: {
|
||||
type: Array,
|
||||
default: [],
|
||||
},
|
||||
studiensemester: {
|
||||
type: String,
|
||||
default: null
|
||||
@@ -26,7 +30,8 @@ export default {
|
||||
allCourses: [],
|
||||
sortBy: null,
|
||||
multiWeekIds: new Set(),
|
||||
favorites: new Set()
|
||||
favorites: new Set(),
|
||||
filter: {}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@@ -86,32 +91,45 @@ export default {
|
||||
studiengaenge: {
|
||||
deep: true,
|
||||
handler(val) {
|
||||
this.searchparam = '';
|
||||
this.loadCoursesByStg(val);
|
||||
this.loadCourses();
|
||||
}
|
||||
},
|
||||
lecturers: {
|
||||
deep: true,
|
||||
handler() {
|
||||
this.loadCourses();
|
||||
}
|
||||
},
|
||||
studiensemester() {
|
||||
if (this.studiengaenge)
|
||||
this.loadCoursesByStg(this.studiengaenge);
|
||||
this.loadCourses();
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
async loadCoursesByStg(stg) {
|
||||
if (stg.length <= 0)
|
||||
{
|
||||
this.allCourses = [];
|
||||
return;
|
||||
async loadCourses()
|
||||
{
|
||||
const hasLektoren = this.lecturers.length > 0;
|
||||
const hasStg = this.studiengaenge.length > 0;
|
||||
|
||||
this.filter = {};
|
||||
if (hasLektoren)
|
||||
this.filter.uid = this.lecturers;
|
||||
|
||||
if (hasStg) {
|
||||
this.filter.stg = this.studiengaenge.map(
|
||||
({ studiengang_kz, semester, orgform_kurzbz }) => ({
|
||||
studiengang_kz,
|
||||
semester,
|
||||
orgform_kurzbz,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
let payload = stg.map(({ studiengang_kz, semester, orgform_kurzbz }) => ({
|
||||
studiengang_kz,
|
||||
semester,
|
||||
orgform_kurzbz
|
||||
}));
|
||||
|
||||
this.$api.call(ApiCoursePicker.getByStg(payload, this.studiensemester))
|
||||
if (Object.keys(this.filter).length === 0)
|
||||
return this.allCourses = [];
|
||||
this.$api.call(ApiCoursePicker.getCourses(this.filter, this.studiensemester))
|
||||
.then(result => {
|
||||
this.allCourses = result.data.map(e => ({
|
||||
this.allCourses = result?.data?.map(e => ({
|
||||
lehreinheit_id: e.lehreinheit_id,
|
||||
lektoren: e.lektoren,
|
||||
raumtyp: e.raumtyp,
|
||||
@@ -177,7 +195,7 @@ export default {
|
||||
},
|
||||
reload()
|
||||
{
|
||||
this.loadCoursesByStg(this.studiengaenge);
|
||||
this.loadCourses();
|
||||
},
|
||||
toggleMultiWeek(course)
|
||||
{
|
||||
@@ -253,7 +271,7 @@ export default {
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="studiengaenge.length <= 0" class="d-flex flex-column align-items-center justify-content-center text-center text-muted py-5 px-3 h-100">
|
||||
<div v-if="Object.keys(filter).length <= 0" class="d-flex flex-column align-items-center justify-content-center text-center text-muted py-5 px-3 h-100">
|
||||
<span class="small fw-semibold mb-1">{{$p.t('lehre', 'cptitleempty')}}</span>
|
||||
<span class="small">{{$p.t('lehre', 'cpempty')}}</span>
|
||||
</div>
|
||||
|
||||
@@ -47,6 +47,10 @@ export default {
|
||||
<i :class="l.overlays.wishes ? 'fa-solid fa-toggle-on text-primary' : 'fa-solid fa-toggle-off text-muted'"></i>
|
||||
<span class="form-check-label">Zeitwünsche</span>
|
||||
</div>
|
||||
<div class="d-flex align-items-center gap-2" @click="l.showCoursePicker = !l.showCoursePicker" style="cursor:pointer">
|
||||
<i :class="l.showCoursePicker ? 'fa-solid fa-toggle-on text-primary' : 'fa-solid fa-toggle-off text-muted'"></i>
|
||||
<span class="form-check-label">Course Picker</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -43,6 +43,14 @@ export function getTempusSearchbarOptions(self)
|
||||
self.addToFilter(data, 'mitarbeiter');
|
||||
}
|
||||
},
|
||||
{
|
||||
label: "zum Course Picker hinzufügen",
|
||||
icon: "fas fa-plus",
|
||||
type: "function",
|
||||
action: (data) => {
|
||||
self.addToCoursePicker(data);
|
||||
}
|
||||
},
|
||||
]
|
||||
},
|
||||
}
|
||||
|
||||
@@ -181,21 +181,11 @@ export default {
|
||||
.filter((lecture) => lecture.showEvents)
|
||||
.map((lecture) => lecture.uid);
|
||||
},
|
||||
visibleStatusOptions() {
|
||||
return Object.entries(this.visibleStatusArray).map(([key, label]) => ({
|
||||
key,
|
||||
label,
|
||||
}));
|
||||
},
|
||||
visibleStatusValue() {
|
||||
if (this.visibleStatus.includes("all"))
|
||||
return this.visibleStatusOptions.filter(
|
||||
(visibleStatus) => visibleStatus.key === "all",
|
||||
);
|
||||
return this.visibleStatus.map((status) => ({
|
||||
key: status,
|
||||
label: this.visibleStatusArray[status],
|
||||
}));
|
||||
courseLecturers() {
|
||||
if (!this.lecturers.length) return [];
|
||||
return this.lecturers
|
||||
.filter((lecture) => lecture.showCoursePicker)
|
||||
.map((lecture) => lecture.uid);
|
||||
},
|
||||
keyboardShortcuts() {
|
||||
return getTempusShortcuts(this);
|
||||
@@ -276,12 +266,11 @@ export default {
|
||||
.call(ApiKalender.syncToStudent(orig.kalender_id))
|
||||
.then(() => this.$refs.calendar.resetEventLoader());
|
||||
},
|
||||
setOrt: function (data) {
|
||||
setOrt (data) {
|
||||
this.ort_kurzbz = data.ort_kurzbz;
|
||||
this.rooms = [{ ort_kurzbz: data.ort_kurzbz }];
|
||||
},
|
||||
onSelectVerbandAndClose(payload) {
|
||||
console.log(payload);
|
||||
this.onSelectVerband(payload);
|
||||
bootstrap.Offcanvas.getOrCreateInstance(this.$refs.verbandMenu).hide();
|
||||
},
|
||||
@@ -307,41 +296,62 @@ export default {
|
||||
];
|
||||
}
|
||||
},
|
||||
setEmp: function (data) {
|
||||
addToCoursePicker(data)
|
||||
{
|
||||
const uid = data.uid;
|
||||
const label = data.name;
|
||||
let lecturer = this.lecturers.find((lecture) => lecture.uid === uid);
|
||||
|
||||
for (const lect of this.lecturers) delete this.overlayCache[lect.uid];
|
||||
if (!lecturer)
|
||||
{
|
||||
this.addToFilter(data, 'mitarbeiter');
|
||||
lecturer = this.lecturers.find((lecture) => lecture.uid === uid);
|
||||
|
||||
this.lecturers = [
|
||||
if (lecturer)
|
||||
{
|
||||
uid,
|
||||
label,
|
||||
showEvents: true,
|
||||
overlays: { blocks: true, wishes: true },
|
||||
},
|
||||
];
|
||||
lecturer.overlays = {
|
||||
blocks: false,
|
||||
wishes: false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.$refs.calendar.resetEventLoader();
|
||||
if (this.lastRange) this.handleRange(this.lastRange);
|
||||
if (lecturer)
|
||||
{
|
||||
lecturer.showCoursePicker = true
|
||||
}
|
||||
},
|
||||
addToFilter: function (filter, type) {
|
||||
if (type === "ort") {
|
||||
|
||||
addToFilter (filter, type) {
|
||||
if (type === "ort")
|
||||
{
|
||||
const ort_kurzbz = filter.ort_kurzbz;
|
||||
if (!this.rooms.some((room) => room.ort_kurzbz === ort_kurzbz)) {
|
||||
if (!this.rooms.some((room) => room.ort_kurzbz === ort_kurzbz))
|
||||
{
|
||||
this.rooms.push({ ort_kurzbz });
|
||||
}
|
||||
} else if (type === "mitarbeiter") {
|
||||
}
|
||||
else if (type === "mitarbeiter")
|
||||
{
|
||||
const uid = filter.uid;
|
||||
const label = filter.name;
|
||||
if (!this.lecturers.some((l) => l.uid === uid)) {
|
||||
|
||||
let lecturer = this.lecturers.find((lecture) => lecture.uid === uid);
|
||||
|
||||
if (!lecturer)
|
||||
{
|
||||
this.lecturers.push({
|
||||
uid,
|
||||
label,
|
||||
showEvents: true,
|
||||
overlays: { blocks: true, wishes: true },
|
||||
showCoursePicker: false
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
lecturer.showEvents = true;
|
||||
lecturer.overlays = { blocks: true, wishes: true };
|
||||
}
|
||||
}
|
||||
|
||||
this.$refs.calendar.resetEventLoader();
|
||||
@@ -1175,21 +1185,10 @@ export default {
|
||||
</button>
|
||||
</div>
|
||||
<div class="px-2 py-1 w-100">
|
||||
<!--<Multiselect
|
||||
:model-value="visibleStatusValue"
|
||||
@update:model-value="val => toggleStatus(val.map(o => o.key))"
|
||||
option-label="label"
|
||||
:options="visibleStatusOptions"
|
||||
placeholder="Status filtern"
|
||||
:hide-selected="false"
|
||||
:show-toggle-all="false"
|
||||
class="w-100"
|
||||
/>-->
|
||||
|
||||
<div
|
||||
class="d-flex gap-1 py-1"
|
||||
data-cy="previewRoleOptionsHolder"
|
||||
>
|
||||
class="d-flex gap-1 py-1"
|
||||
data-cy="previewRoleOptionsHolder"
|
||||
>
|
||||
<button
|
||||
class="btn btn-sm"
|
||||
:class="previewRole === 'planer' ? 'btn-dark' : 'btn-outline-dark'"
|
||||
@@ -1239,7 +1238,13 @@ export default {
|
||||
v-model:parked-keys="parkedKeys"
|
||||
></parking-slot>
|
||||
|
||||
<fhc-coursepicker ref="coursepicker" :studiengaenge="studiengaenge" @select-lecturer="setEmp" @select-kw="jumpToKw" :studiensemester="selectedStudiensemester"></fhc-coursepicker>
|
||||
<fhc-coursepicker
|
||||
ref="coursepicker"
|
||||
:studiengaenge="studiengaenge"
|
||||
:lecturers="courseLecturers"
|
||||
@select-lecturer="addToFilter($event, 'mitarbeiter')"
|
||||
@select-kw="jumpToKw"
|
||||
:studiensemester="selectedStudiensemester"/>
|
||||
|
||||
</div>
|
||||
<stv-studiensemester v-model:studiensemester-kurzbz="selectedStudiensemester"></stv-studiensemester>
|
||||
|
||||
Reference in New Issue
Block a user