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..13824d6df --- /dev/null +++ b/application/controllers/api/frontend/v1/education/PaabgabeUebersicht.php @@ -0,0 +1,206 @@ + array('lehre/abgabetool:r'), + 'getStudiengaenge' => array('lehre/abgabetool:r'), + 'getTermine' => 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' + ]); + } + + /** + * Get Projektabgaben for search criteria. + */ + 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); + + 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) ?: []); + } + + /** + * Get all Studiengänge for which user is entitled for + */ + 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) ?: [])); + } + + /** + * Get projekt work due dates, depending on search criteria. + */ + 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) ?: [])); + } + + /** + * Get all submission types. + */ + public function getPaAbgabetypen() + { + // 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); + + $this->terminateWithSuccess((getData($result) ?: [])); + } + + /** + * Download zip files with project works matching submission search criteria. + */ + 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', 'nichtsAusgewaehlt')); + + $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. + */ + //~ 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 99b9b75f1..f073e5f73 100644 --- a/application/models/education/Paabgabe_model.php +++ b/application/models/education/Paabgabe_model.php @@ -61,6 +61,174 @@ 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, + $abgabetyp_kurzbz = null, + $abgabedatum = null, + $personSearchString = null, + $limit = 1000 + ) { + $params = []; + + $qry = " + SELECT + 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, + ( + /* 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) + 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 stg 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 stg.studiengang_kz=?"; + $params[] = $studiengang_kz; + } + + if (isset($abgabetyp_kurzbz)) + { + $qry .= " AND paabg.paabgabetyp_kurzbz=?"; + $params[] = $abgabetyp_kurzbz; + } + + if (isset($abgabedatum)) + { + $qry .= " AND paabg.datum=?"; + $params[] = $abgabedatum; + } + + if (is_numeric($personSearchString)) + { + $personSearchString = (int) $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)) + { + // 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.'%')." + )"; + } + + $qry .= " ORDER BY nachname"; + + if (isset($limit) && is_numeric($limit) && (!isset($studiengang_kz) || !is_numeric($studiengang_kz)) && !isset($abgabedatum)) + { + $qry .= " LIMIT ?"; + $params[] = $limit; + } + + 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 = []; + + $qry = " + SELECT + 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) + 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 findAbgabenNewOrUpdatedSince($interval, $relevantTypes) { diff --git a/public/js/api/factory/paabgabeUebersicht.js b/public/js/api/factory/paabgabeUebersicht.js new file mode 100644 index 000000000..35120d2ab --- /dev/null +++ b/public/js/api/factory/paabgabeUebersicht.js @@ -0,0 +1,30 @@ +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 + } + }; + }, + 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/Cis/Cis.js b/public/js/apps/Cis/Cis.js index 8a56c16e2..ee373886f 100644 --- a/public/js/apps/Cis/Cis.js +++ b/public/js/apps/Cis/Cis.js @@ -19,6 +19,7 @@ import DeadlineOverview from "../../components/Cis/Abgabetool/DeadlineOverview.j import Studium from "../../components/Cis/Studium/Studium.js"; import StgOrgLvPlan from "../../components/Cis/LvPlan/StgOrg.js"; import OtherLvPlan from "../../components/Cis/LvPlan/OtherLvPlan.js"; +import PaabgabeUebersicht from "../../components/Cis/ProjektabgabeUebersicht/ProjektabgabeUebersicht.js"; import ApiRouteInfo from '../../api/factory/routeinfo.js'; import {capitalize} from "../../helpers/StringHelpers.js"; @@ -77,6 +78,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", @@ -163,7 +170,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) { @@ -278,7 +285,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, '') || '/' @@ -286,19 +293,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); - + } } }, diff --git a/public/js/components/Cis/ProjektabgabeUebersicht/ProjektabgabeUebersicht.js b/public/js/components/Cis/ProjektabgabeUebersicht/ProjektabgabeUebersicht.js new file mode 100644 index 000000000..4a36339a8 --- /dev/null +++ b/public/js/components/Cis/ProjektabgabeUebersicht/ProjektabgabeUebersicht.js @@ -0,0 +1,334 @@ +import {CoreFilterCmpt} from "../../../components/filter/Filter.js"; +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: { + 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: '-' + }, + defaultTyp: { + paabgabetyp_kurzbz: null, + bezeichnung: '-' + }, + defaultTermin: { + termin: null, + termin_anzeige: Vue.computed(() => this.$p.t('ui/alle')) + }, + 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', 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", + 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'}, + {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: "in Visual Library", + field: 'in_visual_library', + formatter: (cell) => { + return cell.getValue() ? this.$p.t('ui/ja') : this.$p.t('ui/nein'); + } + } + ], + persistence: false, + }, + paabgabeTableEventHandlers: [{ + event: "tableBuilt", + handler: async () => { + this.tableBuiltResolve() + } + } + ]}; + }, + methods: { + tableResolve(resolve) { + this.tableBuiltResolve = resolve + }, + setupData(){ + //~ 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(this.abgaben); + }, + // set placeholder text for no data table + 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.selectedTermin = null; + this.termine = res?.data ?? [] + }) + }, + loadPaAbgaben() { + this.$refs.loader.show(); + + 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 + }, + //~ setRoute(val) { + //~ // 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(); + + + //~ 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/paabgabeuebersicht/downloadProjektarbeit?paabgabe_id=' + encodeURIComponent(paabgabe_id), + //~ '_blank' + //~ ); + }, + // 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'); + 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); + window.open(url.toString(), '_blank'); + } + }, + computed: { + isDarkMode() { + return this.$theme.theme_name.value == 'dark'; + }, + personSearchEnabled() { + 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() { + this.phrasenPromise = this.$p.loadCategory(['abgabetool', 'global', 'person', 'ui']); + this.phrasenPromise.then(()=> {this.phrasenResolved = true}); + }, + mounted() { + this.setupMounted(); + }, + template: ` +

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

+
+
+ +
+
{{ $p.t('abgabetool/studiengang') }}:
+ +
+ +
+
{{ $p.t('abgabetool/c4abgabetyp') }}:
+ +
+ +
+
{{ $p.t('abgabetool/termin') }}:
+ +
+ +
+
{{ $p.t('abgabetool/personsuche') }}:
+ +
+ +
+ +
+
+ +
+ +
+ + + + + ` +}; + +export default ProjektabgabeUebersicht; diff --git a/system/phrasesupdate.php b/system/phrasesupdate.php index 55882b909..6c88d692f 100644 --- a/system/phrasesupdate.php +++ b/system/phrasesupdate.php @@ -59246,6 +59246,288 @@ I have been informed that I am under no obligation to consent to the transmissio ) ), // ### End Notenstatistik + //**************************** 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', + '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 );