From 601c6c53e762d59869990514cad05facafa5bb28 Mon Sep 17 00:00:00 2001 From: Alexei Karpenko Date: Mon, 3 Nov 2025 15:49:31 +0100 Subject: [PATCH 1/6] CIS4: added Projektabgabe Uebersicht, enabled filtering by Abgabe data and person data --- .../Cis/ProjektabgabeUebersicht.php | 36 ++ .../v1/education/PaabgabeUebersicht.php | 176 ++++++++++ .../models/education/Paabgabe_model.php | 195 ++++++++++- public/js/api/factory/paabgabeUebersicht.js | 37 +++ public/js/apps/Dashboard/Fhc.js | 29 +- .../ProjektabgabeUebersicht.js | 309 ++++++++++++++++++ 6 files changed, 770 insertions(+), 12 deletions(-) create mode 100644 application/controllers/Cis/ProjektabgabeUebersicht.php create mode 100644 application/controllers/api/frontend/v1/education/PaabgabeUebersicht.php create mode 100644 public/js/api/factory/paabgabeUebersicht.js create mode 100644 public/js/components/Cis/ProjektabgabeUebersicht/ProjektabgabeUebersicht.js diff --git a/application/controllers/Cis/ProjektabgabeUebersicht.php b/application/controllers/Cis/ProjektabgabeUebersicht.php new file mode 100644 index 000000000..62c46dd5f --- /dev/null +++ b/application/controllers/Cis/ProjektabgabeUebersicht.php @@ -0,0 +1,36 @@ + ['basis/cis:r'] + ]); + } + + // ----------------------------------------------------------------------------------------------------------------- + // Public methods + + /** + * @return void + */ + public function index() + { + // TODO create permission + $viewData = array( + 'uid' => getAuthUID(), + 'showEdit' => true + ); + + $this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'ProjektabgabeUebersicht']); + } +} diff --git a/application/controllers/api/frontend/v1/education/PaabgabeUebersicht.php b/application/controllers/api/frontend/v1/education/PaabgabeUebersicht.php new file mode 100644 index 000000000..c00f5a411 --- /dev/null +++ b/application/controllers/api/frontend/v1/education/PaabgabeUebersicht.php @@ -0,0 +1,176 @@ + array('lehre/abgabetool:r'), + 'getPaAbgaben' => array('lehre/abgabetool:r'), + 'getTermine' => array('lehre/abgabetool:r'), + 'getPaAbgabetypen' => array('lehre/abgabetool:r') + //'downloadProjektarbeit' => array('lehre/abgabetool:r') + ]); + + $this->load->model('education/Paabgabe_model', 'PaabgabeModel'); + + $this->load->library('PermissionLib'); + } + + /** + * + * + * @return array|stdClass|null + */ + public function getPaAbgaben() + { + $studiengang_kz = $this->input->get('studiengang_kz'); + $abgabetyp_kurzbz = $this->input->get('abgabetyp_kurzbz'); + $abgabedatum = $this->input->get('abgabedatum'); + $personSearchString = $this->input->get('personSearchString'); + + + $result = $this->PaabgabeModel->getPaAbgaben(self::ABGABE_TYPES, $studiengang_kz, $abgabetyp_kurzbz, $abgabedatum, $personSearchString); + $this->addMeta('res', $result); + + if (isError($result)) $this->terminateWithError(getError($result), self::ERROR_TYPE_DB); + + $this->terminateWithSuccess(getData($result) ?: []); + } + + /** + * + * + * @return array|stdClass|null + */ + //~ public function searchPaAbgabenByPerson() + //~ { + //~ $searchString = $this->input->get('searchString'); + + //~ $result = $this->PaabgabeModel->searchPaAbgabenByPerson(self::ABGABE_TYPES, $searchString); + //~ $this->addMeta('res', $result); + + //~ if (isError($result)) $this->terminateWithError(getError($result), self::ERROR_TYPE_DB); + + //~ $this->terminateWithSuccess(getData($result) ?: []); + //~ } + + /** + * + * + * @return array|stdClass|null + */ + public function getStudiengaenge() + { + $studiengang_kz_arr = $this->permissionlib->getSTG_isEntitledFor(self::DOWNLOAD_PERMISSION); + + if (!$studiengang_kz_arr) $this->terminateWithSuccess([]); + + $this->load->model('organisation/Studiengang_model', 'StudiengangModel'); + + $this->StudiengangModel->addSelect('tbl_studiengang.*, UPPER(tbl_studiengang.typ || tbl_studiengang.kurzbz) AS kuerzel', $studiengang_kz_arr); + $this->StudiengangModel->db->where_in('studiengang_kz', $studiengang_kz_arr); + $this->StudiengangModel->addOrder('typ, kurzbz'); + $result = $this->StudiengangModel->load(); + + if (isError($result)) $this->terminateWithError(getError($result), self::ERROR_TYPE_DB); + + $this->terminateWithSuccess((getData($result) ?: [])); + } + + + /** + * + * + * @return array|stdClass|null + */ + public function getTermine() + { + $studiengang_kz = $this->input->get('studiengang_kz'); + $abgabetyp_kurzbz = $this->input->get('abgabetyp_kurzbz'); + + $result = $this->PaabgabeModel->getTermine(self::ABGABE_TYPES, $studiengang_kz, $abgabetyp_kurzbz); + + if (isError($result)) $this->terminateWithError(getError($result), self::ERROR_TYPE_DB); + + $this->terminateWithSuccess((getData($result) ?: [])); + } + + /** + * + * + * @return array|stdClass|null + */ + public function getPaAbgabetypen() + { + // Load model PaabgabetypModel + $this->load->model('education/Paabgabetyp_model', 'PaabgabetypModel'); + + $result = $this->PaabgabetypModel->load(); + + if (isError($result)) $this->terminateWithError(getError($result), self::ERROR_TYPE_DB); + + $this->terminateWithSuccess((getData($result) ?: [])); + } + + /** + * Download Projektarbeit document. + */ + //~ public function downloadProjektarbeit() + //~ { + //~ $paabgabe_id = $this->input->get('paabgabe_id'); + + //~ if (!is_numeric($paabgabe_id)) + //~ $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id' => 'Abgabe ID']), self::ERROR_TYPE_GENERAL); + + //~ //$abgabeRes = $this->PaabgabeModel->getEndabgabe($projektarbeit_id); + //~ $this->PaabgabeModel->addSelect("paabgabe_id, student_uid, tbl_paabgabe.datum, tbl_paabgabe.abgabedatum, projekttyp_kurzbz, titel, titel_english, + //~ paabgabe_id || '_' || student_uid || '.pdf' AS filename"); + //~ $this->PaabgabeModel->addJoin('lehre.tbl_projektarbeit', 'projektarbeit_id'); + //~ $abgabeRes = $this->PaabgabeModel->load($paabgabe_id); + + //~ if (isError($abgabeRes)) + //~ show_error(getError($abgabeRes)); + + //~ if (hasData($abgabeRes)) + //~ { + //~ $endabgabe = getData($abgabeRes)[0]; + //~ $filepath = PAABGABE_PATH.$endabgabe->filename; + + //~ if (file_exists($filepath)) + //~ { + //~ $this->output + //~ ->set_status_header(200) + //~ ->set_content_type('application/pdf', 'utf-8') + //~ ->set_header('Content-Disposition: attachment; filename="'.$endabgabe->filename.'"') + //~ ->set_output(file_get_contents($filepath)) + //~ ->_display(); + //~ } + //~ else + //~ { + //~ show_error("File does not exist."); + //~ } + //~ } + //~ } +} diff --git a/application/models/education/Paabgabe_model.php b/application/models/education/Paabgabe_model.php index 343a86706..e5d5b6571 100644 --- a/application/models/education/Paabgabe_model.php +++ b/application/models/education/Paabgabe_model.php @@ -60,5 +60,198 @@ class Paabgabe_model extends DB_Model return $this->execReadOnlyQuery($qry, array($person_id)); } - + + public function getPaAbgaben( + $projekttyp_kurzbz_arr, + $studiengang_kz = null, + $abgabetyp_kurzbz = null, + $abgabedatum = null, + $personSearchString = null, + $limit = 100 + ) { + // convert search string + if (is_numeric($personSearchString)) + { + $personSearchString = (int) $personSearchString; + } + else + { + // remove empty spaces and lowercase + $personSearchString = strtolower(str_replace(' ', '', $personSearchString)); + } + + $params = []; + + $qry = " + SELECT + tbl_studiengang.bezeichnung AS stgbez, tbl_paabgabe.datum AS termin, + tbl_paabgabe.*, abgabetyp.bezeichnung AS paabgabetyp_bezeichnung, ben.uid, pers.vorname, pers.nachname, pa.projekttyp_kurzbz, pa.titel + FROM + lehre.tbl_projektarbeit pa + JOIN campus.tbl_paabgabe USING(projektarbeit_id) + JOIN campus.tbl_paabgabetyp abgabetyp USING(paabgabetyp_kurzbz) + LEFT JOIN public.tbl_benutzer ben ON(uid=student_uid) + LEFT JOIN public.tbl_person pers ON(ben.person_id=pers.person_id) + LEFT JOIN lehre.tbl_lehreinheit USING(lehreinheit_id) + LEFT JOIN lehre.tbl_lehrveranstaltung USING(lehrveranstaltung_id) + LEFT JOIN public.tbl_studiengang USING(studiengang_kz) + WHERE + TRUE"; + + if (isset($projekttyp_kurzbz_arr) && !isEmptyArray($projekttyp_kurzbz_arr)) + { + $qry .= " AND projekttyp_kurzbz IN ?"; + $params[] = $projekttyp_kurzbz_arr; + } + + if (isset($studiengang_kz) && is_numeric($studiengang_kz)) + { + $qry .= " AND public.tbl_studiengang.studiengang_kz=?"; + $params[] = $studiengang_kz; + } + + if (isset($abgabetyp_kurzbz)) + { + $qry .= " AND campus.tbl_paabgabe.paabgabetyp_kurzbz=?"; + $params[] = $abgabetyp_kurzbz; + } + + if (isset($abgabedatum)) + { + $qry .= " AND campus.tbl_paabgabe.datum=?"; + $params[] = $abgabedatum; + } + + if (is_integer($personSearchString)) + { + $params = array_merge($params, [$personSearchString, $personSearchString]); + $qry .= " AND ( + pers.person_id = ? + OR EXISTS (SELECT 1 FROM public.tbl_prestudent WHERE person_id = pers.person_id AND prestudent_id = ?) + )"; + } + elseif (is_string($personSearchString)) + { + $qry .= " AND ( + LOWER(REPLACE(pers.nachname || pers.vorname || pers.nachname, ' ', '')) LIKE ".$this->db->escape('%'.$personSearchString.'%')." + OR ben.uid LIKE ".$this->db->escape('%'.$personSearchString.'%')." + )"; + } + + $qry .= " ORDER BY nachname"; + + if (isset($limit) && is_numeric($limit) + && (!isset($studiengang_kz) || !is_numeric($studiengang_kz)) + && !isset($abgabetyp_kurzbz) && !isset($abgabedatum)) + { + $qry .= " LIMIT ?"; + $params[] = $limit; + } + + return $this->execReadOnlyQuery($qry, $params); + } + + public function getTermine($projekttyp_kurzbz_arr, $studiengang_kz, $abgabetyp_kurzbz) + { + $params = []; + + $qry = " + SELECT + DISTINCT campus.tbl_paabgabe.datum as termin, to_char(campus.tbl_paabgabe.datum, 'DD.MM.YYYY') as termin_anzeige + FROM + lehre.tbl_projektarbeit + JOIN campus.tbl_paabgabe USING(projektarbeit_id) + LEFT JOIN public.tbl_benutzer ON(uid=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 USING(studiengang_kz) + WHERE + TRUE"; + + if (isset($projekttyp_kurzbz_arr) && !isEmptyArray($projekttyp_kurzbz_arr)) + { + $qry .= " AND projekttyp_kurzbz IN ?"; + $params[] = $projekttyp_kurzbz_arr; + } + + if (isset($studiengang_kz) && is_numeric($studiengang_kz)) + { + $qry .= " AND public.tbl_studiengang.studiengang_kz=?"; + $params[] = $studiengang_kz; + } + + if (isset($abgabetyp_kurzbz)) + { + $qry .= " AND campus.tbl_paabgabe.paabgabetyp_kurzbz=?"; + $params[] = $abgabetyp_kurzbz; + } + + $qry .= " ORDER BY termin DESC"; + + return $this->execReadOnlyQuery($qry, $params); + } + + //~ public function searchPaAbgabenByPerson($projekttyp_kurzbz_arr, $searchString, $limit = 100) + //~ { + //~ if (is_numeric($searchString)) + //~ { + //~ $searchString = (int) $searchString; + //~ } + //~ else + //~ { + //~ $searchString = strtolower(str_replace(' ', '', $searchString)); + //~ } + + //~ $params = []; + + //~ $qry = " + //~ SELECT + //~ tbl_studiengang.bezeichnung AS stgbez, tbl_paabgabe.datum AS termin, + //~ tbl_paabgabe.*, abgabetyp.bezeichnung AS paabgabetyp_bezeichnung, ben.uid, pers.vorname, pers.nachname, pa.projekttyp_kurzbz, pa.titel + //~ FROM + //~ lehre.tbl_projektarbeit pa + //~ JOIN campus.tbl_paabgabe USING(projektarbeit_id) + //~ JOIN campus.tbl_paabgabetyp abgabetyp USING(paabgabetyp_kurzbz) + //~ LEFT JOIN public.tbl_benutzer ben ON(uid=student_uid) + //~ LEFT JOIN public.tbl_person pers ON(ben.person_id=pers.person_id) + //~ LEFT JOIN lehre.tbl_lehreinheit USING(lehreinheit_id) + //~ LEFT JOIN lehre.tbl_lehrveranstaltung USING(lehrveranstaltung_id) + //~ LEFT JOIN public.tbl_studiengang USING(studiengang_kz) + //~ WHERE + //~ TRUE"; + + //~ if (isset($projekttyp_kurzbz_arr) && !isEmptyArray($projekttyp_kurzbz_arr)) + //~ { + //~ $qry .= " AND projekttyp_kurzbz IN ?"; + //~ $params[] = $projekttyp_kurzbz_arr; + //~ } + + + //~ if (is_integer($searchString)) + //~ { + //~ $params = array_merge($params, [$searchString, $searchString]); + //~ $qry .= " AND ( + //~ pers.person_id = ? + //~ OR EXISTS (SELECT 1 FROM public.tbl_prestudent WHERE person_id = pers.person_id AND prestudent_id = ?) + //~ )"; + //~ } + //~ else + //~ { + //~ $qry .= " AND ( + //~ LOWER(REPLACE(pers.nachname || pers.vorname || pers.nachname, ' ', '')) LIKE ".$this->db->escape('%'.$searchString.'%')." + //~ OR ben.uid LIKE ".$this->db->escape('%'.$searchString.'%')." + //~ )"; + //~ } + + //~ $qry .= " ORDER BY nachname"; + + //~ if (isset($limit) && is_numeric($limit)) + //~ { + //~ $qry .= " LIMIT ?"; + //~ $params[] = $limit; + //~ } + + //~ return $this->execReadOnlyQuery($qry, $params); + //~ } } diff --git a/public/js/api/factory/paabgabeUebersicht.js b/public/js/api/factory/paabgabeUebersicht.js new file mode 100644 index 000000000..d11aad6bd --- /dev/null +++ b/public/js/api/factory/paabgabeUebersicht.js @@ -0,0 +1,37 @@ +export default { + getPaAbgaben(studiengang_kz, abgabetyp_kurzbz, abgabedatum, personSearchString) { + return { + method: 'get', + url: '/api/frontend/v1/education/PaabgabeUebersicht/getPaAbgaben', + params: { + studiengang_kz: studiengang_kz, abgabetyp_kurzbz: abgabetyp_kurzbz, abgabedatum: abgabedatum, personSearchString: personSearchString + } + }; + }, + //~ searchPaAbgabenByPerson(searchString) { + //~ return { + //~ method: 'get', + //~ url: '/api/frontend/v1/education/PaabgabeUebersicht/searchPaAbgabenByPerson', + //~ params: { searchString: searchString } + //~ }; + //~ }, + getStudiengaenge() { + return { + method: 'get', + url: '/api/frontend/v1/education/PaabgabeUebersicht/getStudiengaenge' + }; + }, + getTermine(studiengang_kz, abgabetyp_kurzbz) { + return { + method: 'get', + url: '/api/frontend/v1/education/PaabgabeUebersicht/getTermine', + params: { studiengang_kz: studiengang_kz, abgabetyp_kurzbz: abgabetyp_kurzbz } + }; + }, + getPaAbgabetypen() { + return { + method: 'get', + url: '/api/frontend/v1/education/PaabgabeUebersicht/getPaAbgabetypen' + }; + } +}; \ No newline at end of file diff --git a/public/js/apps/Dashboard/Fhc.js b/public/js/apps/Dashboard/Fhc.js index 093ad815b..9cd7573c1 100644 --- a/public/js/apps/Dashboard/Fhc.js +++ b/public/js/apps/Dashboard/Fhc.js @@ -16,6 +16,7 @@ import AbgabetoolStudent from "../../components/Cis/Abgabetool/AbgabetoolStudent import AbgabetoolMitarbeiter from "../../components/Cis/Abgabetool/AbgabetoolMitarbeiter.js"; import DeadlineOverview from "../../components/Cis/Abgabetool/DeadlineOverview.js"; import Studium from "../../components/Cis/Studium/Studium.js"; +import PaabgabeUebersicht from "../../components/Cis/ProjektabgabeUebersicht/ProjektabgabeUebersicht.js"; import ApiRenderers from '../../api/factory/renderers.js'; import ApiRouteInfo from '../../api/factory/routeinfo.js'; @@ -67,6 +68,12 @@ const router = VueRouter.createRouter({ component: Raumsuche, props: true }, + { + path: `/Cis/ProjektabgabeUebersicht`, + name: 'PaabgabeUebersicht', + component: PaabgabeUebersicht, + props: true + }, // Redirect old links to new format { path: "/CisVue/Cms/getRoomInformation/:ort_kurzbz", @@ -153,7 +160,7 @@ const router = VueRouter.createRouter({ // Redirect old links to new format { // only trigger on first param being numeric to avoid paths like "LvPlan/Month" entering here - path: "/Cis/LvPlan/:lv_id(\\d+)", + path: "/Cis/LvPlan/:lv_id(\\d+)", name: "LvPlanOld", component: LvPlan, redirect(to) { @@ -228,13 +235,13 @@ const app = Vue.createApp({ computed: { isMobile() { return /Mobi|Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent); - } + } }, provide() { return { // provide injectable & watchable language property language: Vue.computed(() => this.$p.user_language), renderers: Vue.computed(() => this.renderers), - } + } }, methods: { isInternalRoute(href) { @@ -247,7 +254,7 @@ const app = Vue.createApp({ if(target?.id == 'skiplink') return if (target && this.isInternalRoute(target.href)) { const url = new URL(target.href) - + const path = url.pathname const base = this.$router.options.history.base const route = path.replace(base, '') || '/' @@ -255,19 +262,19 @@ const app = Vue.createApp({ // let click event propagate normally if we dont route internally const res = this.$router.resolve(route) if(!res?.matched?.length || res.name === 'Fallback') return - + event.preventDefault(); // Prevent browser navigation - + if(this.isMobile) { // toggle the menu const navMain = document.getElementById('nav-main'); // fix unwanted toggle from off to on for some links on mobile if(navMain.classList.contains('show')){ document.getElementById('nav-main-btn').click(); - } + } } - + this.$router.push(route); - + } } }, @@ -282,9 +289,9 @@ const app = Vue.createApp({ let calendarEvent = null; if (data[rendertype].modalTitle) modalTitle = Vue.markRaw(Vue.defineAsyncComponent(() => import(data[rendertype].modalTitle))); - if (data[rendertype].modalContent) + if (data[rendertype].modalContent) modalContent = Vue.markRaw(Vue.defineAsyncComponent(() => import(data[rendertype].modalContent))); - if (data[rendertype].calendarEvent) + if (data[rendertype].calendarEvent) calendarEvent = Vue.markRaw(Vue.defineAsyncComponent(() => import(data[rendertype].calendarEvent))); if (data[rendertype].calendarEventStyles){ diff --git a/public/js/components/Cis/ProjektabgabeUebersicht/ProjektabgabeUebersicht.js b/public/js/components/Cis/ProjektabgabeUebersicht/ProjektabgabeUebersicht.js new file mode 100644 index 000000000..dcdc9bdc0 --- /dev/null +++ b/public/js/components/Cis/ProjektabgabeUebersicht/ProjektabgabeUebersicht.js @@ -0,0 +1,309 @@ +import {CoreFilterCmpt} from "../../../components/filter/Filter.js"; +import VueDatePicker from '../../vueDatepicker.js.php'; +import ApiPaabgabe from '../../../api/factory/paabgabeUebersicht.js' +import Loader from "../../Loader.js"; + +export const ProjektabgabeUebersicht = { + name: "ProjektabgabeUebersicht", + props: { + viewData: Object // NOTE: this is inherited from router-view + }, + components: { + VueDatePicker, + CoreFilterCmpt, + Loader + }, + data() { + return { + phrasenPromise: null, + phrasenResolved: false, + tabulatorUuid: Vue.ref(0), + tableBuiltResolve: null, + tableBuiltPromise: null, + studiengaenge: null, + abgabetypen: null, + termine: null, + abgaben: null, + defaultStudiengang: { + studiengang_kz: null, + kuerzel: Vue.computed(() => this.$p.t('abgabetool/studiengangWaehlen')) + }, + defaultTyp: { + paabgabetyp_kurzbz: null, + bezeichnung: Vue.computed(() => this.$p.t('abgabetool/abgabetypWaehlen')) + }, + defaultTermin: { + termin: null, + termin_anzeige: Vue.computed(() => this.$p.t('abgabetool/terminWaehlen')) + }, + selectedStudiengang: null, + selectedAbgabetyp: null, + selectedTermin: null, + personSearchString: null, + paabgabeTableOptions: { + height: Vue.ref(400), + index: 'paabgabe_id', + layout: 'fitColumns', + //~ placeholder: this.$p.t('global/noDataAvailable'), + columns: [ + { + title: Vue.computed(() => this.$p.t('global/aktionen')), field: 'actions', + formatter: (cell, formatterParams, onRendered) => { + let container = document.createElement('div'); + container.className = "d-flex gap-2"; + + let downloadButton = document.createElement('button'); + downloadButton.className = 'btn btn-outline-secondary'; + downloadButton.innerHTML = ''; + downloadButton.title = this.$p.t('ui', 'downloadDok'); + downloadButton.addEventListener('click', evt => { + evt.stopPropagation(); + this.actionDownload(cell.getData().paabgabe_id); + }); + container.append(downloadButton); + + if (this.viewData.showEdit) + { + let editButton = document.createElement('button'); + editButton.className = 'btn btn-outline-secondary'; + editButton.innerHTML = ''; + editButton.addEventListener('click', () => + this.$refs.edit.open(cell.getData()) + ); + container.append(editButton); + } + + return container; + } + }, + {title: Vue.computed(() => this.$p.t('abgabetool/paabgabeid')), field: 'paabgabe_id', widthGrow: 1, visible: false}, + { + title: Vue.computed(() => this.$p.t('abgabetool/termin')), + field: "termin", + widthGrow: 1, + formatter: function (cell) { + const dateStr = cell.getValue(); + if (!dateStr) return ""; + + const date = new Date(dateStr); + return date.toLocaleString("de-DE", { + day: "2-digit", + month: "2-digit", + year: "numeric", + hour12: false + }); + } + }, + {title: Vue.computed(() => this.$p.t('abgabetool/c4abgabetyp')), field: 'paabgabetyp_bezeichnung', widthGrow: 1}, + {title: Vue.computed(() => this.$p.t('person/uid')), field: 'uid', widthGrow: 1}, + {title: Vue.computed(() => this.$p.t('person/vorname')), field: 'vorname', widthGrow: 1}, + {title: Vue.computed(() => this.$p.t('person/nachname')), field: 'nachname', widthGrow: 1}, + {title: Vue.computed(() => this.$p.t('abgabetool/typ')), field: 'projekttyp_kurzbz', widthGrow: 1}, + {title: Vue.computed(() => this.$p.t('abgabetool/titel')), field: 'titel', widthGrow: 1} + ], + persistence: false, + }, + paabgabeTableEventHandlers: [{ + event: "tableBuilt", + handler: async () => { + this.tableBuiltResolve() + } + } + ]}; + }, + methods: { + tableResolve(resolve) { + this.tableBuiltResolve = resolve + }, + setupData(data){ + //~ const d = data.map(paabgabe => { + //~ return { + //~ ort_kurzbz: paabgabe.ort_kurzbz, + //~ bezeichnung: paabgabe.bezeichnung.replace('&', '&'), + //~ nummer: paabgabe.planbezeichnung, + //~ personen: paabgabe.max_person + //~ } + //~ }) + + this.$refs.paabgabeTable.tabulator.setData(data); + }, + setNoDataPlaceholder() { + this.$refs.paabgabeTable.tabulatorOptions.placeholder = this.$p.t('global/noDataAvailable'); + }, + loadStudiengaenge() { + this.$api.call(ApiPaabgabe.getStudiengaenge()) + .then(res => { + this.studiengaenge = res?.data ?? [] + }) + }, + loadPaabgabeTypes() { + this.$api.call(ApiPaabgabe.getPaAbgabetypen()) + .then(res => { + this.abgabetypen = res?.data ?? [] + }) + }, + loadTermine() { + this.$api.call(ApiPaabgabe.getTermine(this.selectedStudiengang, this.selectedAbgabetyp)) + .then(res => { + this.termine = res?.data ?? [] + }) + }, + loadPaAbgaben() { + this.$refs.loader.show(); + //~ const func = + //~ this.personSearchString && this.personSearchString != '' + //~ ? ApiPaabgabe.searchPaAbgabenByPerson(this.personSearchString) + //~ : ApiPaabgabe.getPaAbgaben(this.selectedStudiengang, this.selectedAbgabetyp, this.selectedTermin); + + this.$api.call( + ApiPaabgabe.getPaAbgaben(this.selectedStudiengang, this.selectedAbgabetyp, this.selectedTermin, this.personSearchString) + ) + .then(res => { + this.$refs.loader.hide(); + this.setupData(res?.data ?? []); + }); + }, + handleUuidDefined(uuid) { + this.tabulatorUuid = uuid + }, + searchPaAbgabenByPerson(){ + this.$api.call(ApiPaabgabe.getPaAbgaben(this.selectedStudiengang, this.selectedAbgabetyp, this.selectedTermin)) + .then(res => { + this.setupData(res?.data ?? []); + //this.abgaben = res?.data ?? [] + }); + }, + //~ setRoute(val) { + //~ // TODO: router push + //~ }, + async setupMounted() { + this.tableBuiltPromise = new Promise(this.tableResolve); + await this.tableBuiltPromise; + + this.setNoDataPlaceholder(); + this.loadStudiengaenge(); + this.loadPaabgabeTypes(); + this.loadTermine(); + //this.loadPaAbgaben(); + + + //~ const tableID = this.tabulatorUuid ? ('-' + this.tabulatorUuid) : '' + //~ const tableDataSet = document.getElementById('filterTableDataset' + tableID); + //~ if(!tableDataSet) return + //~ const rect = tableDataSet.getBoundingClientRect(); + + //~ const h = window.visualViewport.height - rect.top - 100 + //~ if(this.$refs.raumsucheTable) { + //~ this.$refs.raumsucheTable.$refs.table.style.setProperty('height', h+'px') + //~ } + + }, + actionDownload(paabgabe_id) { + //~ window.open( + //~ FHC_JS_DATA_STORAGE_OBJECT.app_root + //~ + FHC_JS_DATA_STORAGE_OBJECT.ci_router + //~ +'/api/frontend/v1/education/paabgabe/downloadProjektarbeit?paabgabe_id=' + encodeURIComponent(paabgabe_id), + //~ '_blank' + //~ ); + } + }, + computed: { + isDarkMode(){ + return this.$theme.theme_name.value == 'dark'; + }, + personSearchEnabled() { + this.loadTermine(); + return this.selectedStudiengang == null && this.selectedTermin == null && this.selectedAbgabetyp == null; + }, + abgabeSearchEnabled() { + return this.personSearchString == '' || this.personSearchString == null; + } + }, + created() { + this.phrasenPromise = this.$p.loadCategory(['abgabetool', 'global', 'person', 'ui']); + this.phrasenPromise.then(()=> {this.phrasenResolved = true}); + }, + mounted() { + this.setupMounted(); + }, + template: ` +

{{$p.t('abgabetool/projektabgabeUebersicht')}}

+
+
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+
+ + + + + ` +}; + +export default ProjektabgabeUebersicht; From bd67e41aa6130158ede69c5572ab712eb9b5b688 Mon Sep 17 00:00:00 2001 From: Alexei Karpenko Date: Wed, 5 Nov 2025 11:44:36 +0100 Subject: [PATCH 2/6] Projektabgabe Uebersicht: added zip download, bugfixes Projektabgabe search --- .../v1/education/PaabgabeUebersicht.php | 78 ++++++++++---- .../models/education/Paabgabe_model.php | 101 +++--------------- public/js/api/factory/paabgabeUebersicht.js | 7 -- .../ProjektabgabeUebersicht.js | 50 +++++---- 4 files changed, 99 insertions(+), 137 deletions(-) diff --git a/application/controllers/api/frontend/v1/education/PaabgabeUebersicht.php b/application/controllers/api/frontend/v1/education/PaabgabeUebersicht.php index c00f5a411..411851e98 100644 --- a/application/controllers/api/frontend/v1/education/PaabgabeUebersicht.php +++ b/application/controllers/api/frontend/v1/education/PaabgabeUebersicht.php @@ -14,7 +14,6 @@ if (!defined('BASEPATH')) exit('No direct script access allowed'); - class PaabgabeUebersicht extends FHCAPI_Controller { const DOWNLOAD_PERMISSION = 'lehre/abgabetool:download'; @@ -26,16 +25,22 @@ class PaabgabeUebersicht extends FHCAPI_Controller public function __construct() { parent::__construct([ - 'getStudiengaenge' => array('lehre/abgabetool:r'), 'getPaAbgaben' => array('lehre/abgabetool:r'), + 'getStudiengaenge' => array('lehre/abgabetool:r'), 'getTermine' => array('lehre/abgabetool:r'), - 'getPaAbgabetypen' => array('lehre/abgabetool:r') + 'getPaAbgabetypen' => array('lehre/abgabetool:r'), + 'downloadZip' => array('lehre/abgabetool:r') //'downloadProjektarbeit' => array('lehre/abgabetool:r') ]); $this->load->model('education/Paabgabe_model', 'PaabgabeModel'); $this->load->library('PermissionLib'); + + // Load Phrases + $this->loadPhrases([ + 'abgabetool' + ]); } /** @@ -50,32 +55,13 @@ class PaabgabeUebersicht extends FHCAPI_Controller $abgabedatum = $this->input->get('abgabedatum'); $personSearchString = $this->input->get('personSearchString'); - $result = $this->PaabgabeModel->getPaAbgaben(self::ABGABE_TYPES, $studiengang_kz, $abgabetyp_kurzbz, $abgabedatum, $personSearchString); - $this->addMeta('res', $result); if (isError($result)) $this->terminateWithError(getError($result), self::ERROR_TYPE_DB); $this->terminateWithSuccess(getData($result) ?: []); } - /** - * - * - * @return array|stdClass|null - */ - //~ public function searchPaAbgabenByPerson() - //~ { - //~ $searchString = $this->input->get('searchString'); - - //~ $result = $this->PaabgabeModel->searchPaAbgabenByPerson(self::ABGABE_TYPES, $searchString); - //~ $this->addMeta('res', $result); - - //~ if (isError($result)) $this->terminateWithError(getError($result), self::ERROR_TYPE_DB); - - //~ $this->terminateWithSuccess(getData($result) ?: []); - //~ } - /** * * @@ -99,7 +85,6 @@ class PaabgabeUebersicht extends FHCAPI_Controller $this->terminateWithSuccess((getData($result) ?: [])); } - /** * * @@ -127,6 +112,7 @@ class PaabgabeUebersicht extends FHCAPI_Controller // Load model PaabgabetypModel $this->load->model('education/Paabgabetyp_model', 'PaabgabetypModel'); + $this->PaabgabetypModel->addOrder('bezeichnung'); $result = $this->PaabgabetypModel->load(); if (isError($result)) $this->terminateWithError(getError($result), self::ERROR_TYPE_DB); @@ -134,6 +120,52 @@ class PaabgabeUebersicht extends FHCAPI_Controller $this->terminateWithSuccess((getData($result) ?: [])); } + /** + * + * @param + * @return object success or error + */ + public function downloadZip() + { + $studiengang_kz = $this->input->get('studiengang_kz'); + $abgabetyp_kurzbz = $this->input->get('abgabetyp_kurzbz'); + $abgabedatum = $this->input->get('abgabedatum'); + $personSearchString = $this->input->get('personSearchString'); + + if (!isset($studiengang_kz) && !isset($abgabetyp_kurzbz) && !isset($abgabedatum) && !isset($personSearchString)) + $this->terminateWithFileOutput('text/plain', $this->p->t('abgabetool', 'keineAuswahl')); + + $this->load->library('zip'); + + $result = $this->PaabgabeModel->getPaAbgaben(self::ABGABE_TYPES, $studiengang_kz, $abgabetyp_kurzbz, $abgabedatum, $personSearchString); + + if (isError($result)) $this->terminateWithFileOutput('text/plain', getError($result)); + + $fileExists = false; + $studiengang_kuerzel = null; + + if (!hasData($result)) $this->terminateWithFileOutput('text/plain', $this->p->t('abgabetool', 'keineDateienVorhanden')); + + $abgaben = getData($result); + + foreach ($abgaben as $abgabe) + { + $path = PAABGABE_PATH.$abgabe->paabgabe_id.'_'.$abgabe->uid.'.pdf'; + if (file_exists($path)) + { + $fileExists = true; + $studiengang_kuerzel = $abgabe->studiengang_kuerzel; + $this->zip->read_file($path); + } + } + + if (!$fileExists) $this->terminateWithFileOutput('text/plain', $this->p->t('abgabetool', 'keineDateienVorhanden')); + + $studiengang_kz = $this->input->get('studiengang_kz'); + $zipFileName = 'Abgabe'.(isset($studiengang_kz) && isset($studiengang_kuerzel) ? '_'.$studiengang_kuerzel : '').'.zip'; + $this->zip->download($zipFileName); + } + /** * Download Projektarbeit document. */ diff --git a/application/models/education/Paabgabe_model.php b/application/models/education/Paabgabe_model.php index e5d5b6571..d48ddf9a2 100644 --- a/application/models/education/Paabgabe_model.php +++ b/application/models/education/Paabgabe_model.php @@ -67,34 +67,25 @@ class Paabgabe_model extends DB_Model $abgabetyp_kurzbz = null, $abgabedatum = null, $personSearchString = null, - $limit = 100 + $limit = 1000 ) { - // convert search string - if (is_numeric($personSearchString)) - { - $personSearchString = (int) $personSearchString; - } - else - { - // remove empty spaces and lowercase - $personSearchString = strtolower(str_replace(' ', '', $personSearchString)); - } - $params = []; $qry = " SELECT - tbl_studiengang.bezeichnung AS stgbez, tbl_paabgabe.datum AS termin, - tbl_paabgabe.*, abgabetyp.bezeichnung AS paabgabetyp_bezeichnung, ben.uid, pers.vorname, pers.nachname, pa.projekttyp_kurzbz, pa.titel + stg.bezeichnung AS stgbez, paabg.datum AS termin, + paabg.paabgabe_id, paabg.projektarbeit_id, paabg.paabgabetyp_kurzbz, paabg.abgabedatum, + abgabetyp.bezeichnung AS paabgabetyp_bezeichnung, ben.uid, pers.vorname, pers.nachname, pa.projekttyp_kurzbz, pa.titel, + UPPER(stg.typ || stg.kurzbz) AS studiengang_kuerzel FROM lehre.tbl_projektarbeit pa - JOIN campus.tbl_paabgabe USING(projektarbeit_id) + JOIN campus.tbl_paabgabe paabg USING(projektarbeit_id) JOIN campus.tbl_paabgabetyp abgabetyp USING(paabgabetyp_kurzbz) LEFT JOIN public.tbl_benutzer ben ON(uid=student_uid) LEFT JOIN public.tbl_person pers ON(ben.person_id=pers.person_id) LEFT JOIN lehre.tbl_lehreinheit USING(lehreinheit_id) LEFT JOIN lehre.tbl_lehrveranstaltung USING(lehrveranstaltung_id) - LEFT JOIN public.tbl_studiengang USING(studiengang_kz) + LEFT JOIN public.tbl_studiengang stg USING(studiengang_kz) WHERE TRUE"; @@ -106,24 +97,25 @@ class Paabgabe_model extends DB_Model if (isset($studiengang_kz) && is_numeric($studiengang_kz)) { - $qry .= " AND public.tbl_studiengang.studiengang_kz=?"; + $qry .= " AND stg.studiengang_kz=?"; $params[] = $studiengang_kz; } if (isset($abgabetyp_kurzbz)) { - $qry .= " AND campus.tbl_paabgabe.paabgabetyp_kurzbz=?"; + $qry .= " AND paabg.paabgabetyp_kurzbz=?"; $params[] = $abgabetyp_kurzbz; } if (isset($abgabedatum)) { - $qry .= " AND campus.tbl_paabgabe.datum=?"; + $qry .= " AND paabg.datum=?"; $params[] = $abgabedatum; } - if (is_integer($personSearchString)) + if (is_numeric($personSearchString)) { + $personSearchString = (int) $personSearchString; $params = array_merge($params, [$personSearchString, $personSearchString]); $qry .= " AND ( pers.person_id = ? @@ -132,6 +124,8 @@ class Paabgabe_model extends DB_Model } elseif (is_string($personSearchString)) { + // remove empty spaces and lowercase + $personSearchString = strtolower(str_replace(' ', '', $personSearchString)); $qry .= " AND ( LOWER(REPLACE(pers.nachname || pers.vorname || pers.nachname, ' ', '')) LIKE ".$this->db->escape('%'.$personSearchString.'%')." OR ben.uid LIKE ".$this->db->escape('%'.$personSearchString.'%')." @@ -140,9 +134,7 @@ class Paabgabe_model extends DB_Model $qry .= " ORDER BY nachname"; - if (isset($limit) && is_numeric($limit) - && (!isset($studiengang_kz) || !is_numeric($studiengang_kz)) - && !isset($abgabetyp_kurzbz) && !isset($abgabedatum)) + if (isset($limit) && is_numeric($limit) && (!isset($studiengang_kz) || !is_numeric($studiengang_kz)) && !isset($abgabedatum)) { $qry .= " LIMIT ?"; $params[] = $limit; @@ -191,67 +183,4 @@ class Paabgabe_model extends DB_Model return $this->execReadOnlyQuery($qry, $params); } - - //~ public function searchPaAbgabenByPerson($projekttyp_kurzbz_arr, $searchString, $limit = 100) - //~ { - //~ if (is_numeric($searchString)) - //~ { - //~ $searchString = (int) $searchString; - //~ } - //~ else - //~ { - //~ $searchString = strtolower(str_replace(' ', '', $searchString)); - //~ } - - //~ $params = []; - - //~ $qry = " - //~ SELECT - //~ tbl_studiengang.bezeichnung AS stgbez, tbl_paabgabe.datum AS termin, - //~ tbl_paabgabe.*, abgabetyp.bezeichnung AS paabgabetyp_bezeichnung, ben.uid, pers.vorname, pers.nachname, pa.projekttyp_kurzbz, pa.titel - //~ FROM - //~ lehre.tbl_projektarbeit pa - //~ JOIN campus.tbl_paabgabe USING(projektarbeit_id) - //~ JOIN campus.tbl_paabgabetyp abgabetyp USING(paabgabetyp_kurzbz) - //~ LEFT JOIN public.tbl_benutzer ben ON(uid=student_uid) - //~ LEFT JOIN public.tbl_person pers ON(ben.person_id=pers.person_id) - //~ LEFT JOIN lehre.tbl_lehreinheit USING(lehreinheit_id) - //~ LEFT JOIN lehre.tbl_lehrveranstaltung USING(lehrveranstaltung_id) - //~ LEFT JOIN public.tbl_studiengang USING(studiengang_kz) - //~ WHERE - //~ TRUE"; - - //~ if (isset($projekttyp_kurzbz_arr) && !isEmptyArray($projekttyp_kurzbz_arr)) - //~ { - //~ $qry .= " AND projekttyp_kurzbz IN ?"; - //~ $params[] = $projekttyp_kurzbz_arr; - //~ } - - - //~ if (is_integer($searchString)) - //~ { - //~ $params = array_merge($params, [$searchString, $searchString]); - //~ $qry .= " AND ( - //~ pers.person_id = ? - //~ OR EXISTS (SELECT 1 FROM public.tbl_prestudent WHERE person_id = pers.person_id AND prestudent_id = ?) - //~ )"; - //~ } - //~ else - //~ { - //~ $qry .= " AND ( - //~ LOWER(REPLACE(pers.nachname || pers.vorname || pers.nachname, ' ', '')) LIKE ".$this->db->escape('%'.$searchString.'%')." - //~ OR ben.uid LIKE ".$this->db->escape('%'.$searchString.'%')." - //~ )"; - //~ } - - //~ $qry .= " ORDER BY nachname"; - - //~ if (isset($limit) && is_numeric($limit)) - //~ { - //~ $qry .= " LIMIT ?"; - //~ $params[] = $limit; - //~ } - - //~ return $this->execReadOnlyQuery($qry, $params); - //~ } } diff --git a/public/js/api/factory/paabgabeUebersicht.js b/public/js/api/factory/paabgabeUebersicht.js index d11aad6bd..35120d2ab 100644 --- a/public/js/api/factory/paabgabeUebersicht.js +++ b/public/js/api/factory/paabgabeUebersicht.js @@ -8,13 +8,6 @@ export default { } }; }, - //~ searchPaAbgabenByPerson(searchString) { - //~ return { - //~ method: 'get', - //~ url: '/api/frontend/v1/education/PaabgabeUebersicht/searchPaAbgabenByPerson', - //~ params: { searchString: searchString } - //~ }; - //~ }, getStudiengaenge() { return { method: 'get', diff --git a/public/js/components/Cis/ProjektabgabeUebersicht/ProjektabgabeUebersicht.js b/public/js/components/Cis/ProjektabgabeUebersicht/ProjektabgabeUebersicht.js index dcdc9bdc0..f01c0a40c 100644 --- a/public/js/components/Cis/ProjektabgabeUebersicht/ProjektabgabeUebersicht.js +++ b/public/js/components/Cis/ProjektabgabeUebersicht/ProjektabgabeUebersicht.js @@ -1,5 +1,4 @@ import {CoreFilterCmpt} from "../../../components/filter/Filter.js"; -import VueDatePicker from '../../vueDatepicker.js.php'; import ApiPaabgabe from '../../../api/factory/paabgabeUebersicht.js' import Loader from "../../Loader.js"; @@ -9,7 +8,6 @@ export const ProjektabgabeUebersicht = { viewData: Object // NOTE: this is inherited from router-view }, components: { - VueDatePicker, CoreFilterCmpt, Loader }, @@ -115,7 +113,7 @@ export const ProjektabgabeUebersicht = { tableResolve(resolve) { this.tableBuiltResolve = resolve }, - setupData(data){ + setupData(){ //~ const d = data.map(paabgabe => { //~ return { //~ ort_kurzbz: paabgabe.ort_kurzbz, @@ -125,7 +123,7 @@ export const ProjektabgabeUebersicht = { //~ } //~ }) - this.$refs.paabgabeTable.tabulator.setData(data); + this.$refs.paabgabeTable.tabulator.setData(this.abgaben); }, setNoDataPlaceholder() { this.$refs.paabgabeTable.tabulatorOptions.placeholder = this.$p.t('global/noDataAvailable'); @@ -145,45 +143,37 @@ export const ProjektabgabeUebersicht = { loadTermine() { this.$api.call(ApiPaabgabe.getTermine(this.selectedStudiengang, this.selectedAbgabetyp)) .then(res => { + this.selectedTermin = null; this.termine = res?.data ?? [] }) }, loadPaAbgaben() { this.$refs.loader.show(); - //~ const func = - //~ this.personSearchString && this.personSearchString != '' - //~ ? ApiPaabgabe.searchPaAbgabenByPerson(this.personSearchString) - //~ : ApiPaabgabe.getPaAbgaben(this.selectedStudiengang, this.selectedAbgabetyp, this.selectedTermin); this.$api.call( ApiPaabgabe.getPaAbgaben(this.selectedStudiengang, this.selectedAbgabetyp, this.selectedTermin, this.personSearchString) ) .then(res => { this.$refs.loader.hide(); + this.abgaben = res?.data ?? []; this.setupData(res?.data ?? []); }); }, handleUuidDefined(uuid) { this.tabulatorUuid = uuid }, - searchPaAbgabenByPerson(){ - this.$api.call(ApiPaabgabe.getPaAbgaben(this.selectedStudiengang, this.selectedAbgabetyp, this.selectedTermin)) - .then(res => { - this.setupData(res?.data ?? []); - //this.abgaben = res?.data ?? [] - }); - }, //~ setRoute(val) { //~ // TODO: router push //~ }, async setupMounted() { + this.loadStudiengaenge(); + this.loadPaabgabeTypes(); + this.loadTermine(); + this.tableBuiltPromise = new Promise(this.tableResolve); await this.tableBuiltPromise; this.setNoDataPlaceholder(); - this.loadStudiengaenge(); - this.loadPaabgabeTypes(); - this.loadTermine(); //this.loadPaAbgaben(); @@ -202,21 +192,35 @@ export const ProjektabgabeUebersicht = { //~ window.open( //~ FHC_JS_DATA_STORAGE_OBJECT.app_root //~ + FHC_JS_DATA_STORAGE_OBJECT.ci_router - //~ +'/api/frontend/v1/education/paabgabe/downloadProjektarbeit?paabgabe_id=' + encodeURIComponent(paabgabe_id), + //~ +'/api/frontend/v1/education/paabgabeuebersicht/downloadProjektarbeit?paabgabe_id=' + encodeURIComponent(paabgabe_id), //~ '_blank' //~ ); + }, + actionDownloadZip(ev) { + console.log(ev); + const url = new URL(FHC_JS_DATA_STORAGE_OBJECT.app_root + + FHC_JS_DATA_STORAGE_OBJECT.ci_router + +'/api/frontend/v1/education/PaabgabeUebersicht/downloadZip'); + if (this.selectedStudiengang) url.searchParams.append('studiengang_kz', this.selectedStudiengang); + if (this.selectedAbgabetyp) url.searchParams.append('abgabetyp_kurzbz', this.selectedAbgabetyp); + if (this.selectedTermin) url.searchParams.append('abgabedatum', this.selectedTermin); + if (this.personSearchString) url.searchParams.append('personSearchString', this.personSearchString); + console.log(url.toString()); + window.open(url.toString(), '_blank'); } }, computed: { - isDarkMode(){ + isDarkMode() { return this.$theme.theme_name.value == 'dark'; }, personSearchEnabled() { - this.loadTermine(); return this.selectedStudiengang == null && this.selectedTermin == null && this.selectedAbgabetyp == null; }, abgabeSearchEnabled() { return this.personSearchString == '' || this.personSearchString == null; + }, + zipDownloadUrl() { + return FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router + '/api/frontend/v1/education/PaabgabeUebersicht/downloadZip'; } }, created() { @@ -290,6 +294,10 @@ export const ProjektabgabeUebersicht = {
+
+ +
+ Date: Fri, 7 Nov 2025 02:22:21 +0100 Subject: [PATCH 3/6] Projektabgabe Uebersicht: added person status --- .../models/education/Paabgabe_model.php | 30 ++++++++++++++++++- .../ProjektabgabeUebersicht.js | 3 +- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/application/models/education/Paabgabe_model.php b/application/models/education/Paabgabe_model.php index d48ddf9a2..9bec3fcca 100644 --- a/application/models/education/Paabgabe_model.php +++ b/application/models/education/Paabgabe_model.php @@ -76,7 +76,35 @@ class Paabgabe_model extends DB_Model stg.bezeichnung AS stgbez, paabg.datum AS termin, paabg.paabgabe_id, paabg.projektarbeit_id, paabg.paabgabetyp_kurzbz, paabg.abgabedatum, abgabetyp.bezeichnung AS paabgabetyp_bezeichnung, ben.uid, pers.vorname, pers.nachname, pa.projekttyp_kurzbz, pa.titel, - UPPER(stg.typ || stg.kurzbz) AS studiengang_kuerzel + UPPER(stg.typ || stg.kurzbz) AS studiengang_kuerzel, + ( + /* show all relevant Studiengänge of person and wether it is an employee*/ + SELECT + STRING_AGG(studiengang || ' ' || last_status, ' | ') + || (CASE WHEN EXISTS ( + SELECT 1 FROM public.tbl_mitarbeiter ma + JOIN public.tbl_benutzer ben ON ma.mitarbeiter_uid = ben.uid + WHERE person_id = prestudents.person_id + AND ben.aktiv + ) THEN ' | Mitarbeiter' ELSE '' END) + FROM ( + SELECT + DISTINCT person_id, prestudent_id, UPPER(stg.typ || stg.kurzbz) AS studiengang, + get_rolle_prestudent(ps.prestudent_id, null) AS last_status + FROM + public.tbl_prestudent ps + JOIN public.tbl_studiengang stg USING (studiengang_kz) + WHERE + person_id = pers.person_id + ORDER BY + prestudent_id DESC + ) prestudents + WHERE + last_status IN ('Abgewiesener','Aufgenommener', 'Student', 'Incoming', 'Diplomand', 'Abbrecher', 'Unterbrecher', 'Absolvent') + GROUP BY + person_id + LIMIT 1; + ) AS status FROM lehre.tbl_projektarbeit pa JOIN campus.tbl_paabgabe paabg USING(projektarbeit_id) diff --git a/public/js/components/Cis/ProjektabgabeUebersicht/ProjektabgabeUebersicht.js b/public/js/components/Cis/ProjektabgabeUebersicht/ProjektabgabeUebersicht.js index f01c0a40c..6e73e97da 100644 --- a/public/js/components/Cis/ProjektabgabeUebersicht/ProjektabgabeUebersicht.js +++ b/public/js/components/Cis/ProjektabgabeUebersicht/ProjektabgabeUebersicht.js @@ -97,7 +97,8 @@ export const ProjektabgabeUebersicht = { {title: Vue.computed(() => this.$p.t('person/vorname')), field: 'vorname', widthGrow: 1}, {title: Vue.computed(() => this.$p.t('person/nachname')), field: 'nachname', widthGrow: 1}, {title: Vue.computed(() => this.$p.t('abgabetool/typ')), field: 'projekttyp_kurzbz', widthGrow: 1}, - {title: Vue.computed(() => this.$p.t('abgabetool/titel')), field: 'titel', widthGrow: 1} + {title: Vue.computed(() => this.$p.t('abgabetool/titel')), field: 'titel', widthGrow: 1}, + {title: Vue.computed(() => this.$p.t('abgabetool/status')), field: 'status', widthGrow: 1} ], persistence: false, }, From 6861e26ed64cc35134d813ef4146b76b4051c531 Mon Sep 17 00:00:00 2001 From: Alexei Karpenko Date: Mon, 10 Nov 2025 14:43:28 +0100 Subject: [PATCH 4/6] =?UTF-8?q?Projektabgabe=20=C3=9Cbersicht:=20added=20f?= =?UTF-8?q?lag=20"inVisualLibrary=20with=20event"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../v1/education/PaabgabeUebersicht.php | 8 ++++++++ .../ProjektabgabeUebersicht.js | 18 +++++++++++++----- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/application/controllers/api/frontend/v1/education/PaabgabeUebersicht.php b/application/controllers/api/frontend/v1/education/PaabgabeUebersicht.php index 411851e98..ad62702d8 100644 --- a/application/controllers/api/frontend/v1/education/PaabgabeUebersicht.php +++ b/application/controllers/api/frontend/v1/education/PaabgabeUebersicht.php @@ -14,6 +14,8 @@ if (!defined('BASEPATH')) exit('No direct script access allowed'); +use CI3_Events as Events; + class PaabgabeUebersicht extends FHCAPI_Controller { const DOWNLOAD_PERMISSION = 'lehre/abgabetool:download'; @@ -59,6 +61,12 @@ class PaabgabeUebersicht extends FHCAPI_Controller if (isError($result)) $this->terminateWithError(getError($result), self::ERROR_TYPE_DB); + // check wether Abgabe is in visual library + if (hasData($result)) + { + Events::trigger('in_visual_library', getData($result)); + } + $this->terminateWithSuccess(getData($result) ?: []); } diff --git a/public/js/components/Cis/ProjektabgabeUebersicht/ProjektabgabeUebersicht.js b/public/js/components/Cis/ProjektabgabeUebersicht/ProjektabgabeUebersicht.js index 6e73e97da..68821a231 100644 --- a/public/js/components/Cis/ProjektabgabeUebersicht/ProjektabgabeUebersicht.js +++ b/public/js/components/Cis/ProjektabgabeUebersicht/ProjektabgabeUebersicht.js @@ -65,9 +65,9 @@ export const ProjektabgabeUebersicht = { let editButton = document.createElement('button'); editButton.className = 'btn btn-outline-secondary'; editButton.innerHTML = ''; - editButton.addEventListener('click', () => - this.$refs.edit.open(cell.getData()) - ); + //editButton.addEventListener('click', () => + //this.$refs.edit.open(cell.getData()) + //); container.append(editButton); } @@ -75,6 +75,7 @@ export const ProjektabgabeUebersicht = { } }, {title: Vue.computed(() => this.$p.t('abgabetool/paabgabeid')), field: 'paabgabe_id', widthGrow: 1, visible: false}, + {title: Vue.computed(() => this.$p.t('abgabetool/projektarbeitid')), field: 'projektarbeit_id', widthGrow: 1, visible: false}, { title: Vue.computed(() => this.$p.t('abgabetool/termin')), field: "termin", @@ -98,7 +99,15 @@ export const ProjektabgabeUebersicht = { {title: Vue.computed(() => this.$p.t('person/nachname')), field: 'nachname', widthGrow: 1}, {title: Vue.computed(() => this.$p.t('abgabetool/typ')), field: 'projekttyp_kurzbz', widthGrow: 1}, {title: Vue.computed(() => this.$p.t('abgabetool/titel')), field: 'titel', widthGrow: 1}, - {title: Vue.computed(() => this.$p.t('abgabetool/status')), field: 'status', widthGrow: 1} + {title: Vue.computed(() => this.$p.t('abgabetool/status')), field: 'status', widthGrow: 2}, + { + title: Vue.computed(() => this.$p.t('abgabetool/inVisualLibrary')), + field: 'in_visual_library', + widthGrow: 1, + formatter: (cell) => { + return cell.getValue() ? this.$p.t('ui/ja') : this.$p.t('ui/nein'); + } + } ], persistence: false, }, @@ -206,7 +215,6 @@ export const ProjektabgabeUebersicht = { if (this.selectedAbgabetyp) url.searchParams.append('abgabetyp_kurzbz', this.selectedAbgabetyp); if (this.selectedTermin) url.searchParams.append('abgabedatum', this.selectedTermin); if (this.personSearchString) url.searchParams.append('personSearchString', this.personSearchString); - console.log(url.toString()); window.open(url.toString(), '_blank'); } }, From 91d24ebae832792b838c634faa3a6bb170fead08 Mon Sep 17 00:00:00 2001 From: Alexei Karpenko Date: Mon, 10 Nov 2025 17:37:24 +0100 Subject: [PATCH 5/6] =?UTF-8?q?Projektabgabe=20=C3=9Cbersicht:=20added=20p?= =?UTF-8?q?hrases?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../v1/education/PaabgabeUebersicht.php | 2 +- .../models/education/Paabgabe_model.php | 2 +- .../ProjektabgabeUebersicht.js | 40 +-- system/phrasesupdate.php | 262 ++++++++++++++++++ 4 files changed, 286 insertions(+), 20 deletions(-) diff --git a/application/controllers/api/frontend/v1/education/PaabgabeUebersicht.php b/application/controllers/api/frontend/v1/education/PaabgabeUebersicht.php index ad62702d8..31b7a27fb 100644 --- a/application/controllers/api/frontend/v1/education/PaabgabeUebersicht.php +++ b/application/controllers/api/frontend/v1/education/PaabgabeUebersicht.php @@ -141,7 +141,7 @@ class PaabgabeUebersicht extends FHCAPI_Controller $personSearchString = $this->input->get('personSearchString'); if (!isset($studiengang_kz) && !isset($abgabetyp_kurzbz) && !isset($abgabedatum) && !isset($personSearchString)) - $this->terminateWithFileOutput('text/plain', $this->p->t('abgabetool', 'keineAuswahl')); + $this->terminateWithFileOutput('text/plain', $this->p->t('abgabetool', 'nichtsAusgewaehlt')); $this->load->library('zip'); diff --git a/application/models/education/Paabgabe_model.php b/application/models/education/Paabgabe_model.php index 9bec3fcca..2598e79f1 100644 --- a/application/models/education/Paabgabe_model.php +++ b/application/models/education/Paabgabe_model.php @@ -177,7 +177,7 @@ class Paabgabe_model extends DB_Model $qry = " SELECT - DISTINCT campus.tbl_paabgabe.datum as termin, to_char(campus.tbl_paabgabe.datum, 'DD.MM.YYYY') as termin_anzeige + DISTINCT tbl_paabgabe.datum as termin, to_char(tbl_paabgabe.datum, 'DD.MM.YYYY') as termin_anzeige FROM lehre.tbl_projektarbeit JOIN campus.tbl_paabgabe USING(projektarbeit_id) diff --git a/public/js/components/Cis/ProjektabgabeUebersicht/ProjektabgabeUebersicht.js b/public/js/components/Cis/ProjektabgabeUebersicht/ProjektabgabeUebersicht.js index 68821a231..b14f6ff16 100644 --- a/public/js/components/Cis/ProjektabgabeUebersicht/ProjektabgabeUebersicht.js +++ b/public/js/components/Cis/ProjektabgabeUebersicht/ProjektabgabeUebersicht.js @@ -24,15 +24,15 @@ export const ProjektabgabeUebersicht = { abgaben: null, defaultStudiengang: { studiengang_kz: null, - kuerzel: Vue.computed(() => this.$p.t('abgabetool/studiengangWaehlen')) + kuerzel: '-' }, defaultTyp: { paabgabetyp_kurzbz: null, - bezeichnung: Vue.computed(() => this.$p.t('abgabetool/abgabetypWaehlen')) + bezeichnung: '-' }, defaultTermin: { termin: null, - termin_anzeige: Vue.computed(() => this.$p.t('abgabetool/terminWaehlen')) + termin_anzeige: Vue.computed(() => this.$p.t('ui/alle')) }, selectedStudiengang: null, selectedAbgabetyp: null, @@ -74,8 +74,8 @@ export const ProjektabgabeUebersicht = { return container; } }, - {title: Vue.computed(() => this.$p.t('abgabetool/paabgabeid')), field: 'paabgabe_id', widthGrow: 1, visible: false}, - {title: Vue.computed(() => this.$p.t('abgabetool/projektarbeitid')), field: 'projektarbeit_id', widthGrow: 1, visible: false}, + {title: Vue.computed(() => this.$p.t('abgabetool/paabgabeid')), field: 'paabgabe_id', visible: false}, + {title: Vue.computed(() => this.$p.t('abgabetool/projektarbeitid')), field: 'projektarbeit_id', visible: false}, { title: Vue.computed(() => this.$p.t('abgabetool/termin')), field: "termin", @@ -93,15 +93,15 @@ export const ProjektabgabeUebersicht = { }); } }, - {title: Vue.computed(() => this.$p.t('abgabetool/c4abgabetyp')), field: 'paabgabetyp_bezeichnung', widthGrow: 1}, - {title: Vue.computed(() => this.$p.t('person/uid')), field: 'uid', widthGrow: 1}, - {title: Vue.computed(() => this.$p.t('person/vorname')), field: 'vorname', widthGrow: 1}, - {title: Vue.computed(() => this.$p.t('person/nachname')), field: 'nachname', widthGrow: 1}, - {title: Vue.computed(() => this.$p.t('abgabetool/typ')), field: 'projekttyp_kurzbz', widthGrow: 1}, - {title: Vue.computed(() => this.$p.t('abgabetool/titel')), field: 'titel', widthGrow: 1}, - {title: Vue.computed(() => this.$p.t('abgabetool/status')), field: 'status', widthGrow: 2}, + {title: Vue.computed(() => this.$p.t('abgabetool/c4abgabetyp')), field: 'paabgabetyp_bezeichnung'}, + {title: Vue.computed(() => this.$p.t('person/uid')), field: 'uid'}, + {title: Vue.computed(() => this.$p.t('person/vorname')), field: 'vorname'}, + {title: Vue.computed(() => this.$p.t('person/nachname')), field: 'nachname'}, + {title: Vue.computed(() => this.$p.t('abgabetool/c4projekttyp')), field: 'projekttyp_kurzbz'}, + {title: Vue.computed(() => this.$p.t('abgabetool/c4titel')), field: 'titel'}, + {title: Vue.computed(() => this.$p.t('abgabetool/personStatus')), field: 'personStatus'}, { - title: Vue.computed(() => this.$p.t('abgabetool/inVisualLibrary')), + title: "in Visual Library", field: 'in_visual_library', widthGrow: 1, formatter: (cell) => { @@ -245,6 +245,7 @@ export const ProjektabgabeUebersicht = {
+
{{ $p.t('abgabetool/studiengang') }}:
@@ -275,12 +277,13 @@ export const ProjektabgabeUebersicht = {
+
{{ $p.t('abgabetool/termin') }}:
-
+
-
+
diff --git a/system/phrasesupdate.php b/system/phrasesupdate.php index 5d3833dc9..4cbef80c7 100644 --- a/system/phrasesupdate.php +++ b/system/phrasesupdate.php @@ -49981,8 +49981,270 @@ I have been informed that I am under no obligation to consent to the transmissio 'description' => '', 'insertvon' => 'system' ) + ) + ), + //**************************** CIS Projektabgabeuebersicht start + array( + 'app' => 'core', + 'category' => 'abgabetool', + 'phrase' => 'studiengang', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Studiengang', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'study program', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'abgabetool', + 'phrase' => 'studiengangWaehlen', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Studiengang auswählen', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Select study program', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'abgabetool', + 'phrase' => 'abgabetypWaehlen', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Abgabetyp auswählen', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Select type of submission', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'abgabetool', + 'phrase' => 'terminWaehlen', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Termin auswählen', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Select due date', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'abgabetool', + 'phrase' => 'personsuche', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Personsuche', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'person search', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'abgabetool', + 'phrase' => 'anzeigen', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Abgaben anzeigen', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Show submissions', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'abgabetool', + 'phrase' => 'zipDownload', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'ZIP herunterladen', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Download ZIP', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'abgabetool', + 'phrase' => 'paabgabeid', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Projektabgabe ID', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'thesis submission ID', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'abgabetool', + 'phrase' => 'projektarbeitid', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Projektarbeit ID', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'projekt work ID', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'abgabetool', + 'phrase' => 'termin', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Termin', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'due date', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'abgabetool', + 'phrase' => 'personStatus', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Personstatus', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'person status', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'abgabetool', + 'phrase' => 'nichtsAusgewaehlt', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Nichts ausgewählt', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'No selection', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'abgabetool', + 'phrase' => 'keineDateienVorhanden', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Keine Dateien vorhanden', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'No files available', + 'description' => '', + 'insertvon' => 'system' + ) ) ) + //**************************** CIS Projektabgabeuebersicht ende ); From 73244df019f925315c33ab298fdb497a176b3ca9 Mon Sep 17 00:00:00 2001 From: Alexei Karpenko Date: Tue, 11 Nov 2025 12:41:20 +0100 Subject: [PATCH 6/6] Projektabgaben Uebersicht: added comments, changed placehoder search text, added phrase --- .../v1/education/PaabgabeUebersicht.php | 20 +++++-------------- .../models/education/Paabgabe_model.php | 17 ++++++++++++++++ .../ProjektabgabeUebersicht.js | 12 +++++++---- system/phrasesupdate.php | 20 +++++++++++++++++++ 4 files changed, 50 insertions(+), 19 deletions(-) diff --git a/application/controllers/api/frontend/v1/education/PaabgabeUebersicht.php b/application/controllers/api/frontend/v1/education/PaabgabeUebersicht.php index 31b7a27fb..13824d6df 100644 --- a/application/controllers/api/frontend/v1/education/PaabgabeUebersicht.php +++ b/application/controllers/api/frontend/v1/education/PaabgabeUebersicht.php @@ -46,9 +46,7 @@ class PaabgabeUebersicht extends FHCAPI_Controller } /** - * - * - * @return array|stdClass|null + * Get Projektabgaben for search criteria. */ public function getPaAbgaben() { @@ -71,9 +69,7 @@ class PaabgabeUebersicht extends FHCAPI_Controller } /** - * - * - * @return array|stdClass|null + * Get all Studiengänge for which user is entitled for */ public function getStudiengaenge() { @@ -94,9 +90,7 @@ class PaabgabeUebersicht extends FHCAPI_Controller } /** - * - * - * @return array|stdClass|null + * Get projekt work due dates, depending on search criteria. */ public function getTermine() { @@ -111,9 +105,7 @@ class PaabgabeUebersicht extends FHCAPI_Controller } /** - * - * - * @return array|stdClass|null + * Get all submission types. */ public function getPaAbgabetypen() { @@ -129,9 +121,7 @@ class PaabgabeUebersicht extends FHCAPI_Controller } /** - * - * @param - * @return object success or error + * Download zip files with project works matching submission search criteria. */ public function downloadZip() { diff --git a/application/models/education/Paabgabe_model.php b/application/models/education/Paabgabe_model.php index 2598e79f1..d0feb7f3a 100644 --- a/application/models/education/Paabgabe_model.php +++ b/application/models/education/Paabgabe_model.php @@ -61,6 +61,16 @@ class Paabgabe_model extends DB_Model return $this->execReadOnlyQuery($qry, array($person_id)); } + /** + * Gets project submissions for search criteria. + * @param array $projekttyp_kurzbz_arr contains all relevant project types (e.g. Bachelor) + * @param int $studiengang_kz study program + * @param string $abgabetyp_kurzbz project submission type (e.g. end upload, intermediate submission) + * @param string $abgabedatum due date for hand-in + * @param string $personSearchString for searching by person, i.e. name, uid, person/prestudent id + * @param int $limit limiting max number of results if search criteria is not precise enough + * @return object + */ public function getPaAbgaben( $projekttyp_kurzbz_arr, $studiengang_kz = null, @@ -171,6 +181,13 @@ class Paabgabe_model extends DB_Model return $this->execReadOnlyQuery($qry, $params); } + /** + * Gets due dates for projekt submission search criteria. + * @param array $projekttyp_kurzbz_arr contains all relevant project types (e.g. Bachelor) + * @param int $studiengang_kz study program + * @param string $abgabetyp_kurzbz project submission type (e.g. end upload, intermediate submission) + * @return object + */ public function getTermine($projekttyp_kurzbz_arr, $studiengang_kz, $abgabetyp_kurzbz) { $params = []; diff --git a/public/js/components/Cis/ProjektabgabeUebersicht/ProjektabgabeUebersicht.js b/public/js/components/Cis/ProjektabgabeUebersicht/ProjektabgabeUebersicht.js index b14f6ff16..4a36339a8 100644 --- a/public/js/components/Cis/ProjektabgabeUebersicht/ProjektabgabeUebersicht.js +++ b/public/js/components/Cis/ProjektabgabeUebersicht/ProjektabgabeUebersicht.js @@ -103,7 +103,6 @@ export const ProjektabgabeUebersicht = { { title: "in Visual Library", field: 'in_visual_library', - widthGrow: 1, formatter: (cell) => { return cell.getValue() ? this.$p.t('ui/ja') : this.$p.t('ui/nein'); } @@ -135,6 +134,7 @@ export const ProjektabgabeUebersicht = { this.$refs.paabgabeTable.tabulator.setData(this.abgaben); }, + // set placeholder text for no data table setNoDataPlaceholder() { this.$refs.paabgabeTable.tabulatorOptions.placeholder = this.$p.t('global/noDataAvailable'); }, @@ -176,13 +176,17 @@ export const ProjektabgabeUebersicht = { //~ // TODO: router push //~ }, async setupMounted() { + + // load data for dropdowns this.loadStudiengaenge(); this.loadPaabgabeTypes(); this.loadTermine(); + // wait for table to build this.tableBuiltPromise = new Promise(this.tableResolve); await this.tableBuiltPromise; + // data placeholder after table built so phrases are available this.setNoDataPlaceholder(); //this.loadPaAbgaben(); @@ -206,8 +210,8 @@ export const ProjektabgabeUebersicht = { //~ '_blank' //~ ); }, - actionDownloadZip(ev) { - console.log(ev); + // download zip file with all searched submission files + actionDownloadZip() { const url = new URL(FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router +'/api/frontend/v1/education/PaabgabeUebersicht/downloadZip'); @@ -297,7 +301,7 @@ export const ProjektabgabeUebersicht = { type="text" name="person-search" class="form-control" - :placeholder="'name, uid, person ID, prestudent ID'" + :placeholder="'name/uid/person ID/prestudent ID'" :disabled="!personSearchEnabled" v-on:keyup.enter="loadPaAbgaben" v-model="personSearchString" diff --git a/system/phrasesupdate.php b/system/phrasesupdate.php index 4cbef80c7..e9831cce2 100644 --- a/system/phrasesupdate.php +++ b/system/phrasesupdate.php @@ -49984,6 +49984,26 @@ I have been informed that I am under no obligation to consent to the transmissio ) ), //**************************** CIS Projektabgabeuebersicht start + array( + 'app' => 'core', + 'category' => 'abgabetool', + 'phrase' => 'projektabgabeUebersicht', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Projektabgabe Übersicht', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Project work submission overview', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), array( 'app' => 'core', 'category' => 'abgabetool',