mirror of
https://github.com/FH-Complete/FHC-Core.git
synced 2026-06-01 12:19:28 +00:00
Compare commits
56 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f6f58642f5 | |||
| 1561aa55b7 | |||
| bb366e4117 | |||
| 0962e62e69 | |||
| dcd6cfd74b | |||
| baaf941f25 | |||
| 2e5e7afb4d | |||
| 178638c006 | |||
| 981c97173e | |||
| d4e170037b | |||
| 7aba7aefb9 | |||
| e5ae400686 | |||
| 8ce67a4726 | |||
| bcfdf1e05c | |||
| cb744799bd | |||
| 90ebee25fe | |||
| 3e8ed231a6 | |||
| 4c67b9d267 | |||
| c16cf342cb | |||
| d843f05922 | |||
| 44e9b4dff1 | |||
| bda42ab347 | |||
| b5b69878b8 | |||
| 6f17ddbbdf | |||
| 21ea277aaf | |||
| 2c0badf67c | |||
| 903f3b99b3 | |||
| df9edc36e0 | |||
| 3aebccbb9d | |||
| 0621564be7 | |||
| f1714db09e | |||
| aba4bc2909 | |||
| 70b025da30 | |||
| 87dd858358 | |||
| 51f3edcd72 | |||
| e7f626bd72 | |||
| 17f94aabdf | |||
| c49e32c4ac | |||
| df124db84a | |||
| 29a4b4aadc | |||
| 2682ea75ab | |||
| b3a63a60e9 | |||
| a54dfaf0c7 | |||
| 595538d6bb | |||
| a5329e5bba | |||
| 37a79c4589 | |||
| dd760f8210 | |||
| dd87e893ba | |||
| 127ce312ea | |||
| 2237e9f1b7 | |||
| 9b4fa132dc | |||
| daf332a102 | |||
| c127c0900e | |||
| fc01fa045e | |||
| f57dc6785b | |||
| cf59bcff12 |
@@ -170,6 +170,13 @@ $config['navigation_header'] = array(
|
||||
'expand' => true,
|
||||
'sort' => 51,
|
||||
'requiredPermissions' => 'vertrag/mitarbeiter:r'
|
||||
),
|
||||
'studierendenverwaltung' => array(
|
||||
'link' => site_url('studentenverwaltung'),
|
||||
'description' => 'Studierendenverwaltung',
|
||||
'expand' => true,
|
||||
'sort' => 52,
|
||||
'requiredPermissions' => ['admin:r', 'assistenz:r']
|
||||
)
|
||||
)
|
||||
),
|
||||
|
||||
@@ -9,9 +9,10 @@ class Detailheader extends FHCAPI_Controller
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct([
|
||||
'getHeader' => ['vertrag/mitarbeiter:r'],
|
||||
'getPersonAbteilung' => ['vertrag/mitarbeiter:r'],
|
||||
'getLeitungOrg' => ['vertrag/mitarbeiter:r'],
|
||||
'getHeader' => self::PERM_LOGGED,
|
||||
'getPersonAbteilung' => self::PERM_LOGGED,
|
||||
'getLeitungOrg' => self::PERM_LOGGED,
|
||||
'getSemesterStati' => self::PERM_LOGGED,
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -48,6 +49,17 @@ class Detailheader extends FHCAPI_Controller
|
||||
$this->terminateWithSuccess(current($data));
|
||||
}
|
||||
|
||||
public function getSemesterStati($prestudent_id)
|
||||
{
|
||||
$this->load->model('crm/Prestudentstatus_model', 'PrestudentstatusModel');
|
||||
|
||||
$result = $this->PrestudentstatusModel->getAllPrestudentstatiWithStudiensemester($prestudent_id);
|
||||
|
||||
$data = $this->getDataOrTerminateWithError($result);
|
||||
|
||||
$this->terminateWithSuccess($data);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -246,12 +246,12 @@ class Abschlusspruefung extends FHCAPI_Controller
|
||||
{
|
||||
$searchString = $this->input->get('searchString') ?? '';
|
||||
|
||||
$this->load->model('ressource/Mitarbeiter_model', 'MitarbeiterModel');
|
||||
$this->load->model('person/Person_model', 'PersonModel');
|
||||
|
||||
$result = $this->MitarbeiterModel->searchMitarbeiter($searchString, 'ohneMaUid');
|
||||
$result = $this->PersonModel->searchPerson($searchString, 'mitMaUid');
|
||||
|
||||
if (isError($result)) {
|
||||
$this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
|
||||
$this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
|
||||
}
|
||||
|
||||
$this->terminateWithSuccess($result ?: []);
|
||||
|
||||
@@ -90,6 +90,15 @@ class Projektarbeit extends FHCAPI_Controller
|
||||
|
||||
if (!isset($projektarbeit_id) || !is_numeric($projektarbeit_id)) return $this->terminateWithError('Projektarbeit Id missing', self::ERROR_TYPE_GENERAL);
|
||||
|
||||
$result = $this->fetchProjektarbeitByID($projektarbeit_id);
|
||||
|
||||
$data = $this->getDataOrTerminateWithError($result);
|
||||
|
||||
$this->terminateWithSuccess(current($data));
|
||||
}
|
||||
|
||||
private function fetchProjektarbeitById($projektarbeit_id) {
|
||||
$this->ProjektarbeitModel->resetQuery();
|
||||
$this->ProjektarbeitModel->addSelect(
|
||||
'lehre.tbl_projektarbeit.projektarbeit_id, titel, titel_english, themenbereich, projekttyp_kurzbz, lehrveranstaltung_id, lehreinheit_id,
|
||||
firma_id, beginn, ende, gesperrtbis, note, final, freigegeben, tbl_projektarbeit.anmerkung, fa.name AS firma_name'
|
||||
@@ -97,13 +106,10 @@ class Projektarbeit extends FHCAPI_Controller
|
||||
$this->ProjektarbeitModel->addJoin('lehre.tbl_lehreinheit le', 'lehreinheit_id');
|
||||
$this->ProjektarbeitModel->addJoin('lehre.tbl_lehrveranstaltung lv', 'lehrveranstaltung_id');
|
||||
$this->ProjektarbeitModel->addJoin('public.tbl_firma fa', 'firma_id', 'LEFT');
|
||||
$result = $this->ProjektarbeitModel->loadWhere(
|
||||
return $this->ProjektarbeitModel->loadWhere(
|
||||
array('projektarbeit_id' => $projektarbeit_id)
|
||||
);
|
||||
|
||||
$data = $this->getDataOrTerminateWithError($result);
|
||||
|
||||
$this->terminateWithSuccess(current($data));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -132,7 +138,8 @@ class Projektarbeit extends FHCAPI_Controller
|
||||
);
|
||||
|
||||
$data = $this->getDataOrTerminateWithError($result);
|
||||
|
||||
$data = $this->getDataOrTerminateWithError($this->fetchProjektarbeitById($data));
|
||||
|
||||
$this->terminateWithSuccess($data);
|
||||
}
|
||||
|
||||
|
||||
@@ -144,6 +144,7 @@ class Student extends FHCAPI_Controller
|
||||
. $this->PrestudentModel->escape($studiensemester_kurzbz)
|
||||
. ") AS statusofsemester"
|
||||
);
|
||||
$this->PrestudentModel->addSelect($this->PrestudentModel->escape($studiensemester_kurzbz) . ' as query_studiensemester_kurzbz');
|
||||
|
||||
$this->PrestudentModel->addJoin('public.tbl_student s', 'prestudent_id', 'LEFT');
|
||||
$this->PrestudentModel->addJoin('public.tbl_benutzer b', 'student_uid = uid', 'LEFT');
|
||||
|
||||
@@ -468,6 +468,8 @@ class Students extends FHCAPI_Controller
|
||||
$this->PrestudentModel->addSelect("'' AS verband");
|
||||
$this->PrestudentModel->addSelect("'' AS gruppe");
|
||||
$this->addSelectPrioRel();
|
||||
$query_studiensemester_kurzbz = $studiensemester_kurzbz ? $this->PrestudentModel->escape($studiensemester_kurzbz) : '\'NULL\'';
|
||||
$this->PrestudentModel->addSelect($query_studiensemester_kurzbz . ' as query_studiensemester_kurzbz');
|
||||
|
||||
$this->addFilter($studiensemester_kurzbz);
|
||||
|
||||
@@ -588,6 +590,7 @@ class Students extends FHCAPI_Controller
|
||||
$this->PrestudentModel->addSelect('v.verband');
|
||||
$this->PrestudentModel->addSelect('v.gruppe');
|
||||
$this->PrestudentModel->addSelect("'' AS priorisierung_relativ");
|
||||
$this->PrestudentModel->addSelect($this->PrestudentModel->escape($studiensemester_kurzbz) . ' as query_studiensemester_kurzbz');
|
||||
|
||||
|
||||
$where = [];
|
||||
@@ -798,6 +801,7 @@ class Students extends FHCAPI_Controller
|
||||
$this->PrestudentModel->addSelect("COALESCE(v.semester::text, CASE WHEN public.get_rolle_prestudent(tbl_prestudent.prestudent_id, NULL) IN ('Aufgenommener', 'Bewerber', 'Wartender', 'interessent') THEN public.get_absem_prestudent(tbl_prestudent.prestudent_id, NULL)::text ELSE ''::text END) AS semester", false);
|
||||
$this->PrestudentModel->addSelect('v.verband');
|
||||
$this->PrestudentModel->addSelect('v.gruppe');
|
||||
$this->PrestudentModel->addSelect($this->PrestudentModel->escape($studiensemester_kurzbz) . ' as query_studiensemester_kurzbz');
|
||||
|
||||
//add status per semester
|
||||
$this->PrestudentModel->addSelect(
|
||||
@@ -953,6 +957,13 @@ class Students extends FHCAPI_Controller
|
||||
$this->PrestudentModel->addSelect('pls.status_kurzbz AS status');
|
||||
$this->PrestudentModel->addSelect('pls.datum AS status_datum');
|
||||
$this->PrestudentModel->addSelect('pls.bestaetigtam AS status_bestaetigung');
|
||||
$this->PrestudentModel->addSelect("
|
||||
CASE
|
||||
WHEN pls.status_kurzbz = 'Interessent'
|
||||
THEN pls.ausbildungssemester
|
||||
ELSE s.semester
|
||||
END AS semester_berechnet
|
||||
");
|
||||
$this->PrestudentModel->addSelect(
|
||||
"(SELECT kontakt FROM public.tbl_kontakt WHERE kontakttyp='email' AND person_id=p.person_id AND zustellung LIMIT 1) AS mail_privat",
|
||||
false
|
||||
|
||||
@@ -198,7 +198,19 @@ class Gradelist extends Auth_Controller
|
||||
if (!isset($row_noten->found))
|
||||
{
|
||||
$result_lv = $this->LehrveranstaltungModel->load($row_noten->lehrveranstaltung_id);
|
||||
$result_stg = $this->StudiengangModel->load($result_lv->retval[0]->studiengang_kz);
|
||||
|
||||
$studiengang_kz = null;
|
||||
|
||||
if (!empty($result_lv->retval) && isset($result_lv->retval[0]) && isset($result_lv->retval[0]->studiengang_kz))
|
||||
{
|
||||
$result_stg = $this->StudiengangModel->load($result_lv->retval[0]->studiengang_kz);
|
||||
|
||||
if (!empty($result_stg->retval) && isset($result_stg->retval[0]) && is_object($result_stg->retval[0]) && isset($result_stg->retval[0]->kurzbzlang))
|
||||
{
|
||||
$studiengang_kz = $result_stg->retval[0]->kurzbzlang;
|
||||
}
|
||||
}
|
||||
|
||||
$courses['semester'][$row_noten->studiensemester_kurzbz]['lvs_nonstpl'][] = array(
|
||||
'lehrveranstaltung_id' => $row_noten->lehrveranstaltung_id,
|
||||
'lehrtyp_kurzbz' => $result_lv->retval[0]->lehrtyp_kurzbz,
|
||||
@@ -212,8 +224,8 @@ class Gradelist extends Auth_Controller
|
||||
'semester' => $result_lv->retval[0]->semester,
|
||||
'note' => $row_noten->note,
|
||||
'datum' => $row_noten->benotungsdatum,
|
||||
'zugeordnet' => true,
|
||||
'studiengang_kurzbz' => $result_stg->retval[0]->kurzbzlang
|
||||
'studiengang_kurzbz' => $studiengang_kz,
|
||||
'zugeordnet' => true
|
||||
);
|
||||
if(!isset($courses['semester'][$row_noten->studiensemester_kurzbz]['data']['ectssumme_nonstpl']))
|
||||
$courses['semester'][$row_noten->studiensemester_kurzbz]['data']['ectssumme_nonstpl'] = 0;
|
||||
|
||||
@@ -149,7 +149,7 @@ class Person_model extends DB_Model
|
||||
* @param $filter Term to search for.
|
||||
* @return DB-result
|
||||
*/
|
||||
public function searchPerson($filter)
|
||||
public function searchPerson($filter, $mode=null)
|
||||
{
|
||||
$this->addSelect('vorname, nachname, gebdatum, person_id, titelpre, titelpost');
|
||||
$this->addSelect("CASE
|
||||
@@ -161,6 +161,26 @@ class Person_model extends DB_Model
|
||||
THEN 'Student'
|
||||
ELSE 'Person'
|
||||
END AS status");
|
||||
|
||||
if($mode == 'mitMaUid')
|
||||
{
|
||||
$this->addSelect("(
|
||||
SELECT m.mitarbeiter_uid
|
||||
FROM public.tbl_benutzer b
|
||||
JOIN public.tbl_mitarbeiter m
|
||||
ON b.uid = m.mitarbeiter_uid
|
||||
WHERE b.person_id = tbl_person.person_id
|
||||
LIMIT 1
|
||||
)
|
||||
AS uid");
|
||||
$this->addOrder('uid, lower(nachname), lower(vorname)');
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->addOrder('lower(nachname), lower(vorname)');
|
||||
}
|
||||
|
||||
|
||||
$result = $this->loadWhere(
|
||||
'lower(nachname) like '.$this->db->escape('%'.mb_strtolower($filter).'%')."
|
||||
OR lower(vorname) like ".$this->db->escape('%'.$filter.'%')."
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
@import './SvgIcons.css';
|
||||
@import './components/searchbar/searchbar.css';
|
||||
@import './components/verticalsplit.css';
|
||||
@import './components/horizontalsplit.css';
|
||||
@import './components/FilterComponent.css';
|
||||
@import './components/Tabs.css';
|
||||
@import './components/Notiz.css';
|
||||
@@ -277,3 +278,7 @@ html.fs_huge {
|
||||
}
|
||||
*/
|
||||
/* slim ende */
|
||||
|
||||
.fhc-xxl-modal {
|
||||
min-width: 80vw;
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
:root {
|
||||
--fhc-horizontalsplit-hsplitter-bg-color: var(--fhc-background, #eee);
|
||||
--fhc-horizontalsplit-hsplitter-border-color: var(--fhc-border, #eee);
|
||||
--fhc-horizontalsplit-hsplitter-splitactions-color: var(--fhc-dark, #000);
|
||||
}
|
||||
|
||||
.horizontalsplit-container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
overflow: hidden;
|
||||
max-height: 100%;
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
.horizontalsplitted {
|
||||
overflow: auto;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.horizontalsplitter {
|
||||
flex-shrink: 0;
|
||||
width: 16px;
|
||||
cursor: col-resize;
|
||||
user-select: none;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.horizontalsplitter.left {
|
||||
border-left: solid 3px var(--fhc-horizontalsplit-hsplitter-border-color);
|
||||
margin-right: 3px;
|
||||
}
|
||||
|
||||
.horizontalsplitter.right {
|
||||
border-right: solid 3px var(--fhc-horizontalsplit-hsplitter-border-color);
|
||||
margin-left: 3px;
|
||||
}
|
||||
|
||||
.splitactions.horizontal {
|
||||
background-color: var(--fhc-horizontalsplit-hsplitter-bg-color);
|
||||
color: var(--fhc-horizontalsplit-hsplitter-splitactions-color);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 5px 0 5px 0;
|
||||
}
|
||||
|
||||
.splitactions.horizontal.left {
|
||||
border-radius: 0 40% 40% 0;
|
||||
}
|
||||
|
||||
.splitactions.horizontal.right {
|
||||
border-radius: 40% 0 0 40%;
|
||||
}
|
||||
|
||||
.splitactions.horizontal .splitaction {
|
||||
width: 14px;
|
||||
height: 28px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.splitactions.horizontal .splitaction.resize {
|
||||
cursor: col-resize;
|
||||
}
|
||||
|
||||
#content {
|
||||
padding-top: 0 !important;
|
||||
padding-bottom: 0 !important;
|
||||
}
|
||||
|
||||
#content > div:first-child {
|
||||
margin-top: 30px;
|
||||
}
|
||||
+2
-1
@@ -69,6 +69,7 @@
|
||||
|
||||
.tag_limette {
|
||||
background-color: #D3FFCE;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.tag_done {
|
||||
@@ -111,4 +112,4 @@
|
||||
.copy-btn {
|
||||
float: right;
|
||||
margin-top: 3px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,4 +34,10 @@ export default {
|
||||
url: 'api/frontend/v1/detailheader/detailheader/getLeitungOrg/' + oekurzbz,
|
||||
};
|
||||
},
|
||||
getSemesterStati(prestudent_id){
|
||||
return {
|
||||
method: 'get',
|
||||
url: 'api/frontend/v1/detailheader/detailheader/getSemesterStati/' + prestudent_id,
|
||||
};
|
||||
},
|
||||
}
|
||||
@@ -35,9 +35,6 @@ export default {
|
||||
getMitarbeiter(searchString){
|
||||
return this.$fhcApi.get('api/frontend/v1/stv/abschlusspruefung/getMitarbeiter/' + searchString);
|
||||
},
|
||||
getPruefer(searchString){
|
||||
return this.$fhcApi.get('api/frontend/v1/stv/abschlusspruefung/getPruefer/' + searchString);
|
||||
},
|
||||
getNoten(){
|
||||
return this.$fhcApi.get('api/frontend/v1/stv/abschlusspruefung/getNoten/');
|
||||
},
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
import ApiDetailHeader from "../../api/factory/detailHeader.js";
|
||||
import ApiHandleFoto from "../../api/factory/fotoHandling.js";
|
||||
import ModalUploadFoto from "./Modal/UploadFoto.js";
|
||||
import PvSkeleton from "../../../../index.ci.php/public/js/components/primevue/skeleton/skeleton.esm.min.js";
|
||||
|
||||
export default {
|
||||
name: 'DetailHeader',
|
||||
components: {
|
||||
ModalUploadFoto
|
||||
ModalUploadFoto,
|
||||
PvSkeleton
|
||||
},
|
||||
props: {
|
||||
headerData: {
|
||||
@@ -38,6 +40,14 @@ export default {
|
||||
'mitarbeiter',
|
||||
].includes(value)
|
||||
}
|
||||
},
|
||||
currentSemester: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
isLoading: { //if true, then parent isLoading
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@@ -60,8 +70,7 @@ export default {
|
||||
},
|
||||
hasTileUIDSlot() {
|
||||
return !!this.$slots.uid
|
||||
},
|
||||
|
||||
}
|
||||
},
|
||||
created(){
|
||||
if (this.typeHeader === 'student') {
|
||||
@@ -71,7 +80,7 @@ export default {
|
||||
} else if (this.typeHeader === 'mitarbeiter') {
|
||||
if (!this.person_id || !this.mitarbeiter_uid || !this.domain) {
|
||||
throw new Error(
|
||||
'[DetailHeader] "person_id", "mitarbeiter_uid", and "domain" are requried.'
|
||||
'[DetailHeader] "person_id", "mitarbeiter_uid", and "domain" are required.'
|
||||
)
|
||||
}
|
||||
this.loadHeaderData(this.person_id, this.mitarbeiter_uid);
|
||||
@@ -86,13 +95,26 @@ export default {
|
||||
},
|
||||
deep: true,
|
||||
},
|
||||
headerData: {
|
||||
handler(newVal) {
|
||||
if (this.typeHeader === 'student' && newVal?.length) {
|
||||
this.getSemesterStati(newVal[0].prestudent_id);
|
||||
}
|
||||
},
|
||||
immediate: true
|
||||
},
|
||||
},
|
||||
data(){
|
||||
return{
|
||||
headerDataMa: {},
|
||||
departmentData: {},
|
||||
leitungData: {},
|
||||
isFetchingIssues: false
|
||||
isFetchingIssues: false,
|
||||
noCurrentStatus: false,
|
||||
semesterStatiLoading: false,
|
||||
leitungOrgLoading: false,
|
||||
departmentDataLoading: false,
|
||||
headerDataMaLoading: false
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
@@ -108,29 +130,40 @@ export default {
|
||||
});
|
||||
},
|
||||
getHeader(person_id) {
|
||||
this.headerDataMaLoading = true;
|
||||
return this.$api
|
||||
.call(ApiDetailHeader.getHeader(person_id))
|
||||
.then(result => {
|
||||
this.headerDataMa = result.data;
|
||||
|
||||
})
|
||||
.catch(this.$fhcAlert.handleSystemError);
|
||||
.catch(this.$fhcAlert.handleSystemError)
|
||||
.finally(() => {
|
||||
this.headerDataMaLoading = false;
|
||||
});
|
||||
},
|
||||
loadDepartmentData(mitarbeiter_uid) {
|
||||
this.departmentDataLoading = true;
|
||||
return this.$api
|
||||
.call(ApiDetailHeader.getPersonAbteilung(mitarbeiter_uid))
|
||||
.then(result => {
|
||||
this.departmentData = result.data;
|
||||
})
|
||||
.catch(this.$fhcAlert.handleSystemError);
|
||||
.catch(this.$fhcAlert.handleSystemError)
|
||||
.finally(() => {
|
||||
this.departmentDataLoading = false;
|
||||
});
|
||||
},
|
||||
getLeitungOrg(oekurzbz){
|
||||
this.leitungOrgLoading = true;
|
||||
return this.$api
|
||||
.call(ApiDetailHeader.getLeitungOrg(oekurzbz))
|
||||
.then(result => {
|
||||
this.leitungData = result.data;
|
||||
})
|
||||
.catch(this.$fhcAlert.handleSystemError);
|
||||
.catch(this.$fhcAlert.handleSystemError)
|
||||
.finally(() => {
|
||||
this.leitungOrgLoading = false;
|
||||
});
|
||||
},
|
||||
async goToLeitung() {
|
||||
this.loadHeaderData(this.leitungData.person_id, this.leitungData.uid);
|
||||
@@ -179,6 +212,33 @@ export default {
|
||||
} else {
|
||||
return 'data:image/jpeg;base64,' + foto;
|
||||
}
|
||||
},
|
||||
getSemesterStati(prestudent_id){
|
||||
this.semesterStatiLoading = true;
|
||||
this.$api
|
||||
.call(ApiDetailHeader.getSemesterStati(prestudent_id))
|
||||
.then(result => {
|
||||
this.semesterStati = result.data;
|
||||
this.setNoCurrentStatus();
|
||||
})
|
||||
.catch(this.$fhcAlert.handleSystemError)
|
||||
.finally(() => {
|
||||
this.semesterStatiLoading = false;
|
||||
});
|
||||
},
|
||||
setNoCurrentStatus() {
|
||||
if(!Array.isArray(this.semesterStati))
|
||||
{
|
||||
this.noCurrentStatus = false;
|
||||
}
|
||||
|
||||
if(!this.semesterStati.some(item => item.studiensemester_kurzbz === this.currentSemester)) {
|
||||
this.noCurrentStatus = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.noCurrentStatus = false;
|
||||
}
|
||||
}
|
||||
},
|
||||
template: `
|
||||
@@ -200,7 +260,6 @@ export default {
|
||||
</modal-upload-foto>
|
||||
|
||||
<template v-if="typeHeader==='student'">
|
||||
|
||||
<div
|
||||
v-for="person in headerData"
|
||||
:key="person.person_id"
|
||||
@@ -236,62 +295,100 @@ export default {
|
||||
<small class="text-muted">{{person.uid}}</small>
|
||||
</div>
|
||||
|
||||
<div v-if="headerData.length == 1">
|
||||
<div class="d-flex align-items-center gap-3">
|
||||
<h2 class="h4">
|
||||
{{headerData[0].titelpre}}
|
||||
{{headerData[0].vorname}}
|
||||
{{headerData[0].nachname}}
|
||||
<span v-if="headerData[0].titelpost">, </span>
|
||||
{{headerData[0].titelpost}}
|
||||
</h2>
|
||||
<h6 v-if="headerData[0].unruly" class="badge" :class="'bg-unruly rounded-0'"><strong>unruly</strong></h6>
|
||||
</div>
|
||||
<div v-if="headerData.length == 1">
|
||||
<div v-if="!isLoading" class="d-flex align-items-center gap-3">
|
||||
<h2 class="h4">
|
||||
{{headerData[0].titelpre}}
|
||||
{{headerData[0].vorname}}
|
||||
{{headerData[0].nachname}}
|
||||
<span v-if="headerData[0].titelpost">, </span>
|
||||
{{headerData[0].titelpost}}
|
||||
</h2>
|
||||
<h6 v-if="headerData[0].unruly" class="badge" :class="'bg-unruly rounded-0'"><strong>unruly</strong></h6>
|
||||
</div>
|
||||
<div v-else class="d-flex align-items-center gap-3">
|
||||
<pv-skeleton width="15rem" height="2rem" borderRadius="16px"></pv-skeleton>
|
||||
<h6 v-if="headerData[0].unruly" class="badge" :class="'bg-unruly rounded-0'"><strong>unruly</strong></h6>
|
||||
</div>
|
||||
|
||||
<h5 class="h6">
|
||||
<strong class="text-muted">{{$p.t('lehre', 'studiengang')}} </strong>
|
||||
{{headerData[0].stg_bezeichnung}} ({{headerData[0].studiengang}})
|
||||
<strong v-if="headerData[0].semester" class="text-muted"> | {{$p.t('lehre', 'semester')}} </strong>
|
||||
{{headerData[0].semester}}
|
||||
<strong v-if="headerData[0].verband" class="text-muted"> | {{$p.t('lehre', 'verband')}}</strong>
|
||||
{{headerData[0].verband}}
|
||||
<strong v-if="headerData[0].gruppe" class="text-muted"> | {{$p.t('lehre', 'gruppe')}} </strong>
|
||||
{{headerData[0].gruppe}}
|
||||
</h5>
|
||||
<h5 class="h6 d-flex align-items-center flex-wrap gap-1">
|
||||
<strong class="text-muted">{{$p.t('lehre', 'studiengang')}} </strong>
|
||||
<span v-if="!isLoading">
|
||||
{{headerData[0].stg_bezeichnung}} ({{headerData[0].studiengang}})
|
||||
</span>
|
||||
<span v-else>
|
||||
<pv-skeleton width="10rem"></pv-skeleton>
|
||||
</span>
|
||||
<template v-if="!semesterStatiLoading">
|
||||
<strong v-if="headerData[0].semester != null" class="text-muted"> | {{$p.t('lehre', 'semester')}} </strong>
|
||||
{{headerData[0].semester}}
|
||||
<strong v-if="headerData[0].gruppe !== null && headerData[0].verband != ' '" class="text-muted"> | {{$p.t('lehre', 'verband')}}</strong>
|
||||
{{headerData[0].verband}}
|
||||
<strong v-if="headerData[0].gruppe !== null && headerData[0].gruppe != ' '" class="text-muted"> | {{$p.t('lehre', 'gruppe')}} </strong>
|
||||
{{headerData[0].gruppe}}
|
||||
</template>
|
||||
<template v-else>
|
||||
<strong class="text-muted"> | {{$p.t('lehre', 'semester')}} </strong>
|
||||
<pv-skeleton size="1rem" class="mr-2"></pv-skeleton>
|
||||
<strong class="text-muted"> | {{$p.t('lehre', 'verband')}}</strong>
|
||||
<pv-skeleton size="1rem" class="mr-2"></pv-skeleton>
|
||||
<strong class="text-muted"> | {{$p.t('lehre', 'gruppe')}} </strong>
|
||||
<pv-skeleton size="1rem" class="mr-2"></pv-skeleton>
|
||||
</template>
|
||||
</h5>
|
||||
|
||||
<h5 class="h6">
|
||||
<strong class="text-muted">Email </strong>
|
||||
<span>
|
||||
<a :href="'mailto:'+headerData[0]?.mail_intern">{{headerData[0].mail_intern}}</a>
|
||||
</span>
|
||||
<strong v-if="headerData[0].statusofsemester" class="text-muted"> | Status </strong>
|
||||
{{headerData[0].statusofsemester}}
|
||||
</h5>
|
||||
|
||||
</div>
|
||||
<div v-if="headerData.length == 1" class="col-md-1 d-flex flex-column align-items-end justify-content-start ms-auto">
|
||||
<div class="d-flex py-1">
|
||||
<div class="px-2" style="min-width: 100px;">
|
||||
<slot name="issues"></slot>
|
||||
</div>
|
||||
<div v-if="hasTileGammaSlot" class="px-2" style="border-left: 1px solid #EEE">
|
||||
<h4 class="mb-1 text-center"><slot name="titleGammaTile"></slot></h4>
|
||||
<h6 class="text-muted text-center"><slot name="valueGammaTile"></slot></h6>
|
||||
</div>
|
||||
<div v-if="hasTileBetaSlot" class="px-2" style="border-left: 1px solid #EEE">
|
||||
<h4 class="mb-1 text-center"><slot name="titleBetaTile"></slot></h4>
|
||||
<h6 class="text-muted text-center"><slot name="valueBetaTile"></slot></h6>
|
||||
</div>
|
||||
<div v-if="hasTileAlphaSlot" class="px-2" style="border-left: 1px solid #EEE">
|
||||
<h4 class="mb-1 text-center"><slot name="titleAlphaTile"></slot></h4>
|
||||
<h6 class="text-muted text-center"><slot name="valueAlphaTile"></slot></h6>
|
||||
</div>
|
||||
<div v-if="hasTileUIDSlot" class="px-2" style="border-left: 1px solid #EEE">
|
||||
<h4 class="mb-1 text-center">UID</h4>
|
||||
<h6 class="text-muted text-center"><slot name="uid"></slot></h6>
|
||||
</div>
|
||||
<h5 class="h6 d-flex align-items-center flex-wrap gap-1">
|
||||
<strong class="text-muted">Email </strong>
|
||||
<span v-if="!isLoading">
|
||||
<a :href="'mailto:'+headerData[0]?.mail_intern">{{headerData[0].mail_intern}}</a>
|
||||
</span>
|
||||
<span v-else>
|
||||
<pv-skeleton width="10rem"></pv-skeleton>
|
||||
</span>
|
||||
<strong class="text-muted"> | Status </strong>
|
||||
<span v-if="noCurrentStatus">
|
||||
<strong class="text-danger">{{$p.t('lehre', 'textNoStatusInSem', { sem: currentSemester}) }}</strong>
|
||||
</span>
|
||||
<span v-else>
|
||||
{{headerData[0].statusofsemester}}
|
||||
</span>
|
||||
</h5>
|
||||
</div>
|
||||
<div v-if="headerData.length == 1" class="col-md-1 d-flex flex-column align-items-end justify-content-start ms-auto">
|
||||
<div class="d-flex py-1">
|
||||
<div class="px-2" style="min-width: 100px;">
|
||||
<slot name="issues"></slot>
|
||||
</div>
|
||||
<div v-if="hasTileGammaSlot" class="px-2" style="border-left: 1px solid #EEE">
|
||||
<h4 class="mb-1 text-center"><slot name="titleGammaTile"></slot></h4>
|
||||
<h6 class="text-muted d-flex align-items-center justify-content-center flex-wrap gap-1">
|
||||
<pv-skeleton v-if="isLoading" width="4rem"></pv-skeleton>
|
||||
<slot v-else name="valueGammaTile"></slot>
|
||||
</h6>
|
||||
</div>
|
||||
<div v-if="hasTileBetaSlot" class="px-2" style="border-left: 1px solid #EEE">
|
||||
<h4 class="mb-1 text-center"><slot name="titleBetaTile"></slot></h4>
|
||||
<h6 class="text-muted d-flex align-items-center justify-content-center flex-wrap gap-1">
|
||||
<pv-skeleton v-if="isLoading" width="4rem"></pv-skeleton>
|
||||
<slot v-else name="valueBetaTile"></slot>
|
||||
</h6>
|
||||
</div>
|
||||
<div v-if="hasTileAlphaSlot" class="px-2" style="border-left: 1px solid #EEE">
|
||||
<h4 class="mb-1 text-center"><slot name="titleAlphaTile"></slot></h4>
|
||||
<h6 class="text-muted d-flex align-items-center justify-content-center flex-wrap gap-1">
|
||||
<pv-skeleton v-if="isLoading" width="4rem"></pv-skeleton>
|
||||
<slot v-else name="valueAlphaTile"></slot>
|
||||
</h6>
|
||||
</div>
|
||||
<div v-if="hasTileUIDSlot" class="px-2" style="border-left: 1px solid #EEE">
|
||||
<h4 class="mb-1 text-center">UID</h4>
|
||||
<h6 class="text-muted d-flex align-items-center justify-content-center flex-wrap gap-1">
|
||||
<pv-skeleton v-if="isLoading" width="4rem"></pv-skeleton>
|
||||
<slot v-else name="uid"></slot>
|
||||
</h6>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
@@ -330,27 +427,51 @@ export default {
|
||||
|
||||
<!--show Ma-Details-->
|
||||
<div class="col-md-9 text-nowrap mt-2">
|
||||
<h4>{{headerDataMa.titelpre}} {{headerDataMa.vorname}} {{headerDataMa.nachname}}<span v-if="headerDataMa?.titelpost">, </span> {{headerDataMa.titelpost}}</h4>
|
||||
<strong class="text-muted">{{departmentData.organisationseinheittyp_kurzbz}}</strong>
|
||||
{{departmentData.bezeichnung}}
|
||||
<span v-if="leitungData.uid"> | </span>
|
||||
<strong v-if="leitungData.uid" class="text-muted">Vorgesetzte*r </strong>
|
||||
<a href="#" @click.prevent="goToLeitung">
|
||||
{{leitungData.titelpre}} {{leitungData.vorname}} {{leitungData.nachname}}
|
||||
</a>
|
||||
<p>
|
||||
<strong class="text-muted">Email </strong>
|
||||
<span v-if="headerDataMa && (headerDataMa.alias === undefined || headerDataMa.alias === null || headerDataMa.alias === '')">
|
||||
<a :href="'mailto:' + mitarbeiter_uid + '@' + domain">
|
||||
{{ mitarbeiter_uid }}@{{ domain }}
|
||||
<h4 v-if="!headerDataMaLoading">{{headerDataMa.titelpre}} {{headerDataMa.vorname}} {{headerDataMa.nachname}}<span v-if="headerDataMa?.titelpost">, </span> {{headerDataMa.titelpost}}</h4>
|
||||
<h4 v-else><pv-skeleton width="15rem" height="2rem" borderRadius="16px"></pv-skeleton></h4>
|
||||
<div class="d-flex align-items-center flex-wrap gap-1">
|
||||
<strong class="text-muted">{{departmentData.organisationseinheittyp_kurzbz}}</strong>
|
||||
<span v-if="!departmentDataLoading">
|
||||
{{departmentData.bezeichnung}}
|
||||
</span>
|
||||
<span v-else>
|
||||
<pv-skeleton width="12rem"></pv-skeleton>
|
||||
</span>
|
||||
<span v-if="leitungData.uid"> | </span>
|
||||
<strong v-if="leitungData.uid" class="text-muted">Vorgesetzte*r </strong>
|
||||
<span v-if="!leitungOrgLoading">
|
||||
<a href="#" @click.prevent="goToLeitung">
|
||||
{{leitungData.titelpre}} {{leitungData.vorname}} {{leitungData.nachname}}
|
||||
</a>
|
||||
</span>
|
||||
<span v-else>
|
||||
<a :href="'mailto:'+headerDataMa?.alias+'@'+domain">{{headerDataMa.alias}}@{{domain}}</a>
|
||||
<pv-skeleton width="5rem"></pv-skeleton>
|
||||
</span>
|
||||
<span v-if="headerDataMa?.telefonklappe" class="mb-2"> | <strong class="text-muted">DW </strong>{{headerDataMa?.telefonklappe}}</span>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="d-flex align-items-center gap-2 flex-nowrap">
|
||||
<div class="d-flex align-items-center gap-1">
|
||||
<strong class="text-muted">Email</strong>
|
||||
<template v-if="!headerDataMaLoading">
|
||||
<a :href="'mailto:' + (headerDataMa?.alias || mitarbeiter_uid) + '@' + domain">
|
||||
{{ (headerDataMa?.alias || mitarbeiter_uid) + '@' + domain }}
|
||||
</a>
|
||||
</template>
|
||||
<pv-skeleton v-else width="10rem"></pv-skeleton>
|
||||
</div>
|
||||
|
||||
<div v-if="headerDataMa?.telefonklappe" class="d-flex align-items-center gap-1">
|
||||
<span>|</span>
|
||||
<strong class="text-muted">DW</strong>
|
||||
<template v-if="!headerDataMaLoading">
|
||||
{{ headerDataMa.telefonklappe }}
|
||||
</template>
|
||||
<pv-skeleton v-else width="4rem"></pv-skeleton>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<slot name="tag"></slot>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="col-md-1 d-flex flex-column align-items-end justify-content-start ms-auto">
|
||||
@@ -360,20 +481,33 @@ export default {
|
||||
</div>
|
||||
<div v-if="hasTileGammaSlot" class="px-2" style="border-left: 1px solid #EEE">
|
||||
<h4 class="mb-1 text-center"><slot name="titleGammaTile"></slot></h4>
|
||||
<h6 class="text-muted text-center"><slot name="valueGammaTile"></slot></h6>
|
||||
<h6 class="text-muted d-flex align-items-center justify-content-center flex-wrap gap-1">
|
||||
<pv-skeleton v-if="isLoading" width="4rem"></pv-skeleton>
|
||||
<slot v-else name="valueGammaTile"></slot>
|
||||
</h6>
|
||||
</div>
|
||||
<div v-if="hasTileBetaSlot" class="px-2" style="border-left: 1px solid #EEE">
|
||||
<h4 class="mb-1 text-center"><slot name="titleBetaTile"></slot></h4>
|
||||
<h6 class="text-muted text-center"><slot name="valueBetaTile" :valueBetaTile="valueBetaTile"></slot></h6>
|
||||
<h6 class="text-muted d-flex align-items-center justify-content-center flex-wrap gap-1">
|
||||
<pv-skeleton v-if="isLoading" width="4rem"></pv-skeleton>
|
||||
<slot v-else name="valueBetaTile"></slot>
|
||||
</h6>
|
||||
</div>
|
||||
<div v-if="hasTileAlphaSlot" class="px-2" style="border-left: 1px solid #EEE">
|
||||
<h4 class="mb-1 text-center"><slot name="titleAlphaTile"></slot></h4>
|
||||
<h6 class="text-muted text-center"><slot name="valueAlphaTile"></slot></h6>
|
||||
<h6 class="text-muted d-flex align-items-center justify-content-center flex-wrap gap-1">
|
||||
<pv-skeleton v-if="isLoading" width="4rem"></pv-skeleton>
|
||||
<slot v-else name="valueAlphaTile"></slot>
|
||||
</h6>
|
||||
</div>
|
||||
<div v-if="hasTileUIDSlot" class="px-2" style="border-left: 1px solid #EEE">
|
||||
<h4 class="mb-1 text-center">UID</h4>
|
||||
<h6 class="text-muted text-center"><slot name="uid"></slot></h6>
|
||||
<h6 class="text-muted d-flex align-items-center justify-content-center flex-wrap gap-1">
|
||||
<pv-skeleton v-if="isLoading" width="4rem"></pv-skeleton>
|
||||
<slot v-else name="uid"></slot>
|
||||
</h6>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -29,7 +29,8 @@ export default {
|
||||
label: String,
|
||||
// NOTE(chris): remove these from $attrs array to prevent doubled event listeners
|
||||
onInput: [Array, Function],
|
||||
'onUpdate:modelValue': [Array, Function]
|
||||
'onUpdate:modelValue': [Array, Function],
|
||||
titleActionButton: String
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@@ -317,6 +318,7 @@ export default {
|
||||
:id="idCmp"
|
||||
:name="name"
|
||||
:class="validationClass"
|
||||
:titleActionButton="titleActionButton"
|
||||
@update:model-value="clearValidationForThisName"
|
||||
>
|
||||
<slot></slot>
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
export default {
|
||||
emits: [
|
||||
'update:modelValue'
|
||||
'update:modelValue',
|
||||
'actionbutton-clicked'
|
||||
],
|
||||
props: {
|
||||
modelValue: String
|
||||
modelValue: String,
|
||||
titleActionButton: {
|
||||
type: String,
|
||||
default: ""
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
valueAsBase64DataString() {
|
||||
@@ -28,6 +33,9 @@ export default {
|
||||
},
|
||||
deleteImage() {
|
||||
this.$emit('update:modelValue', '');
|
||||
},
|
||||
emitAction(){
|
||||
this.$emit('actionbutton-clicked', this.modelValue);
|
||||
}
|
||||
},
|
||||
template: `
|
||||
@@ -42,6 +50,7 @@ export default {
|
||||
<button type="button" class="btn btn-outline-dark btn-sm" @click="openUploadDialog">
|
||||
<i class="fa fa-pen"></i>
|
||||
</button>
|
||||
<button v-if="titleActionButton" class="btn btn-outline-dark btn-sm" @click="emitAction">{{titleActionButton}}</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
import CoreSearchbar from "../searchbar/searchbar.js";
|
||||
import NavLanguage from "../navigation/Language.js";
|
||||
import VerticalSplit from "../verticalsplit/verticalsplit.js";
|
||||
import HorizontalSplit from "../horizontalsplit/horizontalsplit.js";
|
||||
import AppMenu from "../AppMenu.js";
|
||||
import AppConfig from "../AppConfig.js";
|
||||
import StvVerband from "./Studentenverwaltung/Verband.js";
|
||||
@@ -37,6 +38,7 @@ export default {
|
||||
CoreSearchbar,
|
||||
NavLanguage,
|
||||
VerticalSplit,
|
||||
HorizontalSplit,
|
||||
AppMenu,
|
||||
AppConfig,
|
||||
StvVerband,
|
||||
@@ -192,7 +194,44 @@ export default {
|
||||
}
|
||||
|
||||
return extraItems;
|
||||
}
|
||||
},
|
||||
appMenuLvPlanungItems() {
|
||||
const extraItems = [];
|
||||
|
||||
if (this.studiengangKz !== undefined && this.selected_semester !== undefined) {
|
||||
const studiengang_kz = String(this.studiengangKz);
|
||||
const semester = String(this.selected_semester);
|
||||
const orgform = this.selected_orgform || '';
|
||||
|
||||
extraItems.push({
|
||||
link: FHC_JS_DATA_STORAGE_OBJECT.app_root
|
||||
+ 'content/statistik/lvplanung.xls.php?'
|
||||
+ '&studiengang_kz=' + studiengang_kz
|
||||
+ '&semester=' + semester
|
||||
+ '&studiensemester_kurzbz=' + this.studiensemesterKurzbz
|
||||
+ '&orgform_kurzbz=' + orgform,
|
||||
description: 'stv/lvplanung_xls'
|
||||
});
|
||||
extraItems.push({
|
||||
link: FHC_JS_DATA_STORAGE_OBJECT.app_root
|
||||
+ 'content/statistik/lvplanung.php?'
|
||||
+ '&studiengang_kz=' + studiengang_kz
|
||||
+ '&semester=' + semester,
|
||||
description: 'stv/lvplanung_html'
|
||||
});
|
||||
}
|
||||
|
||||
return extraItems;
|
||||
},
|
||||
linkRt(){
|
||||
return FHC_JS_DATA_STORAGE_OBJECT.app_root + '/vilesci/stammdaten/reihungstestverwaltung.php'
|
||||
},
|
||||
selected_uid(){
|
||||
return this.selected?.[this.selected.length - 1]?.uid ?? null;
|
||||
},
|
||||
linkGradeList(){
|
||||
return FHC_JS_DATA_STORAGE_OBJECT.app_root + 'index.ci.php/person/gradelist/index/' + this.selected_uid
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
'url_studiensemester_kurzbz': function (newVal, oldVal) {
|
||||
@@ -212,6 +251,7 @@ export default {
|
||||
'url_studiengang': function (newVal, oldVal) {
|
||||
if (newVal !== oldVal) {
|
||||
this.checkUrlStudiengang();
|
||||
this.$refs.stvList.clearSelection();
|
||||
}
|
||||
},
|
||||
'url_mode': function () {
|
||||
@@ -235,6 +275,10 @@ export default {
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
sidebarCollapsed(newVal) {
|
||||
if(newVal) this.$refs.hSplit.collapseLeft()
|
||||
else this.$refs.hSplit.showBoth()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@@ -431,6 +475,9 @@ export default {
|
||||
},
|
||||
deleteCustomFilter(){
|
||||
this.$refs.stvList.resetFilter();
|
||||
},
|
||||
showAlertNoSelectedStudent(){
|
||||
this.$fhcAlert.alertError(this.$p.t('ui', 'alert_chooseStudent'));
|
||||
}
|
||||
},
|
||||
created() {
|
||||
@@ -629,26 +676,69 @@ export default {
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropend">
|
||||
<a
|
||||
class="dropdown-toggle"
|
||||
href="#"
|
||||
role="button"
|
||||
data-bs-toggle="dropdown"
|
||||
aria-expanded="false"
|
||||
:class="{ disabled: !appMenuExtraItems.length }"
|
||||
data-bs-popper-config='{"strategy":"fixed"}'
|
||||
>
|
||||
{{ $p.t('stv/lvplanung') }}
|
||||
</a>
|
||||
<ul class="dropdown-menu p-0">
|
||||
<li
|
||||
v-for="(item, key) in appMenuLvPlanungItems"
|
||||
:key="key"
|
||||
>
|
||||
<a class="dropdown-item" :href="item.link" target="_blank">
|
||||
{{ $p.t(item.description) }}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<a :href="linkRt" target="_blank">
|
||||
{{ $p.t('stv/RTVerwaltung') }}
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a v-if="selected_uid" :href="linkGradeList" target="_blank">
|
||||
{{ $p.t('stv/studienverlauf') }}
|
||||
</a>
|
||||
<a v-else href="#" @click.prevent="showAlertNoSelectedStudent">
|
||||
{{ $p.t('stv/studienverlauf') }}
|
||||
</a>
|
||||
</li>
|
||||
</app-menu>
|
||||
</div>
|
||||
</aside>
|
||||
<nav id="sidebarMenu" class="bg-light offcanvas offcanvas-start col-md p-md-0 h-100">
|
||||
<div class="offcanvas-header justify-content-end px-1 d-md-none">
|
||||
<button type="button" class="btn-close text-reset" data-bs-dismiss="offcanvas" :aria-label="$p.t('ui/schliessen')"></button>
|
||||
</div>
|
||||
<stv-verband :preselectedKey="studiengangKz ? '' + studiengangKz : null" :endpoint="verbandEndpoint" @select-verband="onSelectVerband" class="col" style="height:0%"></stv-verband>
|
||||
<stv-studiensemester v-model:studiensemester-kurzbz="studiensemesterKurzbz" @update:studiensemester-kurzbz="studiensemesterChanged"></stv-studiensemester>
|
||||
</nav>
|
||||
<main class="col-md-8 ms-sm-auto col-lg-9 col-xl-10">
|
||||
<vertical-split>
|
||||
<template #top>
|
||||
<stv-list ref="stvList" v-model:selected="selected" :studiengang-kz="studiengangKz" :studiensemester-kurzbz="studiensemesterKurzbz" @filterActive="handleCustomFilter"></stv-list>
|
||||
</template>
|
||||
<template #bottom>
|
||||
<stv-details ref="details" :students="selected" @reload="reloadList"></stv-details>
|
||||
</template>
|
||||
</vertical-split>
|
||||
</main>
|
||||
<horizontal-split ref="hSplit" :defaultRatio="[15, 85]">
|
||||
<template #left>
|
||||
<nav id="sidebarMenu" class="bg-light offcanvas offcanvas-start col-md p-md-0 h-100 w-100">
|
||||
<div class="offcanvas-header justify-content-end px-1 d-md-none">
|
||||
<button type="button" class="btn-close text-reset" data-bs-dismiss="offcanvas" :aria-label="$p.t('ui/schliessen')"></button>
|
||||
</div>
|
||||
<stv-verband :preselectedKey="studiengangKz ? '' + studiengangKz : null" :endpoint="verbandEndpoint" @select-verband="onSelectVerband" class="col" style="height:0%"></stv-verband>
|
||||
<stv-studiensemester v-model:studiensemester-kurzbz="studiensemesterKurzbz" @update:studiensemester-kurzbz="studiensemesterChanged"></stv-studiensemester>
|
||||
</nav>
|
||||
</template>
|
||||
<template #right>
|
||||
<main>
|
||||
<vertical-split :defaultRatio="[50, 50]">
|
||||
<template #top>
|
||||
<stv-list ref="stvList" v-model:selected="selected" :studiengang-kz="studiengangKz" :studiensemester-kurzbz="studiensemesterKurzbz" @filterActive="handleCustomFilter"></stv-list>
|
||||
</template>
|
||||
<template #bottom>
|
||||
<stv-details ref="details" :students="selected" @reload="reloadList"></stv-details>
|
||||
</template>
|
||||
</vertical-split>
|
||||
</main>
|
||||
</template>
|
||||
</horizontal-split>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<app-config ref="config" v-model="appconfig" :endpoints="configEndpoints"></app-config>
|
||||
|
||||
@@ -2,12 +2,18 @@ import FhcTabs from "../../Tabs.js";
|
||||
import FhcHeader from "../../DetailHeader/DetailHeader.js";
|
||||
|
||||
import ApiStvApp from '../../../api/factory/stv/app.js';
|
||||
import ApiStudent from '../../../api/factory/stv/students.js';
|
||||
|
||||
// TODO(chris): alt & title
|
||||
// TODO(chris): phrasen
|
||||
|
||||
export default {
|
||||
name: "DetailsPrestudent",
|
||||
inject: {
|
||||
currentSemester: {
|
||||
from: 'currentSemester',
|
||||
},
|
||||
},
|
||||
components: {
|
||||
FhcTabs,
|
||||
FhcHeader
|
||||
@@ -15,7 +21,9 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
configStudent: {},
|
||||
configStudents: {}
|
||||
configStudents: {},
|
||||
activeTab: null,
|
||||
localStudent: null
|
||||
};
|
||||
},
|
||||
props: {
|
||||
@@ -40,6 +48,9 @@ export default {
|
||||
}
|
||||
return Object.fromEntries(Object.entries(this.configStudents).filter(([ , value ]) => !value.showOnlyWithUid && !value.showOnlyWithUid));
|
||||
},
|
||||
isLoading() {
|
||||
return this.students === null; //null-> loading, [] -> empty, [...] -> data, necessary for skeleton in child
|
||||
},
|
||||
tile_PersId(){
|
||||
let tile = this.students[0].person_id != null ? this.students[0].person_id : '-';
|
||||
return tile;
|
||||
@@ -57,6 +68,21 @@ export default {
|
||||
'$p.user_language.value'(n, o) {
|
||||
if (n !== o && o !== undefined)
|
||||
this.loadConfig();
|
||||
},
|
||||
currentSemester(newVal) {
|
||||
if (
|
||||
Array.isArray(this.students) &&
|
||||
this.students.length === 1 &&
|
||||
newVal !== this.students[0].query_studiensemester_kurzbz
|
||||
) {
|
||||
this.reloadDataStudent();
|
||||
}
|
||||
else {
|
||||
this.localStudent = null;
|
||||
}
|
||||
},
|
||||
students() {
|
||||
this.localStudent = null;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@@ -74,10 +100,28 @@ export default {
|
||||
})
|
||||
.catch(this.$fhcAlert.handleSystemError);
|
||||
},
|
||||
handleTabChanged(key) {
|
||||
this.activeTab = key
|
||||
this.reload()
|
||||
},
|
||||
reload() {
|
||||
if (this.$refs.tabs?.$refs?.current?.reload)
|
||||
this.$refs.tabs.$refs.current.reload();
|
||||
},
|
||||
reloadDataStudent(){
|
||||
this.localStudent = null;
|
||||
const studentArr = this.students;
|
||||
|
||||
if (!studentArr || !studentArr.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.$api
|
||||
.call(ApiStudent.uid(studentArr[0].uid, this.currentSemester))
|
||||
.then(result => {
|
||||
this.localStudent = result.data;
|
||||
});
|
||||
},
|
||||
reloadList() {
|
||||
this.$emit('reload');
|
||||
},
|
||||
@@ -92,10 +136,12 @@ export default {
|
||||
</div>
|
||||
<div v-else-if="configStudent && configStudents" class="d-flex flex-column h-100">
|
||||
<fhc-header
|
||||
:headerData="students"
|
||||
:headerData="localStudent || students"
|
||||
:currentSemester="currentSemester"
|
||||
typeHeader="student"
|
||||
@reload="reloadList"
|
||||
fotoEditable
|
||||
:isLoading="isLoading"
|
||||
>
|
||||
<template #uid>{{students[0].uid}}</template>
|
||||
<template #titleAlphaTile>PersID</template>
|
||||
@@ -107,16 +153,16 @@ export default {
|
||||
</fhc-header>
|
||||
<fhc-tabs
|
||||
v-if="students.length == 1"
|
||||
ref="tabs"
|
||||
ref="tabs"
|
||||
:useprimevue="true"
|
||||
:modelValue="students[0]"
|
||||
:modelValue="(Array.isArray(localStudent) && localStudent[0]) || students[0]"
|
||||
:config="config"
|
||||
:default="$route.params.tab"
|
||||
:default="activeTab ?? $route.params.tab"
|
||||
style="flex: 1 1 0%; height: 0%"
|
||||
@changed="reload"
|
||||
@changed="handleTabChanged"
|
||||
>
|
||||
</fhc-tabs>
|
||||
<fhc-tabs v-else ref="tabs" :useprimevue="true" :modelValue="students" :config="config" :default="$route.params.tab" style="flex: 1 1 0%; height: 0%" @changed="reload"></fhc-tabs>
|
||||
<fhc-tabs v-else ref="tabs" :useprimevue="true" :modelValue="students" :config="config" :default="activeTab ?? $route.params.tab" style="flex: 1 1 0%; height: 0%" @changed="handleTabChanged"></fhc-tabs>
|
||||
</div>
|
||||
<div v-else>
|
||||
Loading...
|
||||
|
||||
+161
-37
@@ -238,6 +238,16 @@ export default {
|
||||
}
|
||||
return this.student.map(e => e.uid);
|
||||
},
|
||||
studentNames() {
|
||||
if (this.student.uid)
|
||||
{
|
||||
return [this.student.vorname + ' ' + this.student.nachname];
|
||||
}
|
||||
|
||||
const array = this.student.map(e => ' ' + e.vorname + ' ' + e.nachname + '(' + e.uid +')');
|
||||
|
||||
return array.toString();
|
||||
},
|
||||
studentKzs(){
|
||||
if (this.student.uid)
|
||||
{
|
||||
@@ -287,10 +297,50 @@ export default {
|
||||
.catch(this.$fhcAlert.handleSystemError);
|
||||
},
|
||||
actionNewAbschlusspruefung() {
|
||||
this.resetForm();
|
||||
this.statusNew = true;
|
||||
this.$refs.finalexamModal.show();
|
||||
this.setDefaultFormData();
|
||||
this.statusNew = true;
|
||||
|
||||
//prepare local Storage
|
||||
let STORAGE_KEY = 'finalExamDefaultData';
|
||||
const id = '20260224_02';
|
||||
const stored = JSON.parse(localStorage.getItem(STORAGE_KEY)) || {};
|
||||
|
||||
if (stored[id]) {
|
||||
const data = stored[id];
|
||||
|
||||
this.formData.pruefungstyp_kurzbz = data.pruefungstyp_kurzbz;
|
||||
this.formData.datum = data.datum;
|
||||
this.formData.sponsion = data.sponsion;
|
||||
this.formData.akadgrad_id = data.akadgrad_id;
|
||||
|
||||
if (data.vorsitz_uid) {
|
||||
this.selectedVorsitz = {
|
||||
mitarbeiter_uid: data.vorsitz_uid,
|
||||
person_id: data.vorsitz_person_id,
|
||||
label: data.vorsitz_label
|
||||
};
|
||||
}
|
||||
|
||||
if (data.pruefer1_person_id) {
|
||||
this.selectedPruefer1 = {
|
||||
person_id: data.pruefer1_person_id,
|
||||
label: data.pruefer1_label
|
||||
};
|
||||
}
|
||||
if (data.pruefer2_person_id) {
|
||||
this.selectedPruefer2 = {
|
||||
person_id: data.pruefer2_person_id,
|
||||
label: data.pruefer2_label
|
||||
};
|
||||
}
|
||||
if (data.pruefer3_person_id) {
|
||||
this.selectedPruefer3 = {
|
||||
person_id: data.pruefer3_person_id,
|
||||
label: data.pruefer3_label
|
||||
};
|
||||
}
|
||||
}
|
||||
this.$refs.finalexamModal.show();
|
||||
},
|
||||
actionEditAbschlusspruefung(abschlusspruefung_id) {
|
||||
this.resetForm();
|
||||
@@ -305,20 +355,23 @@ export default {
|
||||
};
|
||||
if (data.p1_person_id) {
|
||||
this.selectedPruefer1 = {
|
||||
label: this.getPersonLabel(data.p1_titelpre, data.p1_nachname, data.p1_vorname, data.p1_titelpost),
|
||||
person_id: data.p1_person_id
|
||||
label: this.getPersonLabel(data.p1_titelpre, data.p1_nachname, data.p1_vorname, data.p1_titelpost, data.p1_uid),
|
||||
person_id: data.p1_person_id,
|
||||
mitarbeiter_uid: data.p1_uid
|
||||
};
|
||||
}
|
||||
if (data.p2_person_id) {
|
||||
this.selectedPruefer2 = {
|
||||
label: this.getPersonLabel(data.p2_titelpre, data.p2_nachname, data.p2_vorname, data.p2_titelpost),
|
||||
person_id: data.p2_person_id
|
||||
label: this.getPersonLabel(data.p2_titelpre, data.p2_nachname, data.p2_vorname, data.p2_titelpost, data.p2_uid),
|
||||
person_id: data.p2_person_id,
|
||||
mitarbeiter_uid: data.p2_uid
|
||||
}
|
||||
};
|
||||
if (data.p3_person_id) {
|
||||
this.selectedPruefer3= {
|
||||
label: this.getPersonLabel(data.p3_titelpre, data.p3_nachname, data.p3_vorname, data.p3_titelpost),
|
||||
person_id: data.p3_person_id
|
||||
label: this.getPersonLabel(data.p3_titelpre, data.p3_nachname, data.p3_vorname, data.p3_titelpost, data.p3_uid),
|
||||
person_id: data.p3_person_id,
|
||||
mitarbeiter_uid: data.p3_uid
|
||||
};
|
||||
}
|
||||
});
|
||||
@@ -337,6 +390,29 @@ export default {
|
||||
.then(this.deleteAbschlusspruefung)
|
||||
.catch(this.$fhcAlert.handleSystemError);
|
||||
},
|
||||
saveOrUpdateLocalStorage(){
|
||||
let STORAGE_KEY = 'finalExamDefaultData';
|
||||
|
||||
const id = '20260224_02';
|
||||
const stored = JSON.parse(localStorage.getItem(STORAGE_KEY)) || {};
|
||||
|
||||
stored[id] = {
|
||||
pruefungstyp_kurzbz: this.formData.pruefungstyp_kurzbz,
|
||||
vorsitz_uid: this.selectedVorsitz?.mitarbeiter_uid || null,
|
||||
vorsitz_person_id: this.selectedVorsitz?.person_id || null,
|
||||
vorsitz_label: this.selectedVorsitz?.label || null,
|
||||
pruefer1_person_id: this.selectedPruefer1?.person_id || null,
|
||||
pruefer1_label: this.selectedPruefer1?.label || null,
|
||||
pruefer2_person_id: this.selectedPruefer2?.person_id || null,
|
||||
pruefer2_label: this.selectedPruefer2?.label || null,
|
||||
pruefer3_person_id: this.selectedPruefer3?.person_id || null,
|
||||
pruefer3_label: this.selectedPruefer3?.label || null,
|
||||
akadgrad_id: this.formData.akadgrad_id,
|
||||
datum: this.formData.datum,
|
||||
sponsion: this.formData.sponsion
|
||||
};
|
||||
localStorage.setItem(STORAGE_KEY, JSON.stringify(stored));
|
||||
},
|
||||
addNewAbschlusspruefung() {
|
||||
const dataToSend = {
|
||||
uid: this.student.uid,
|
||||
@@ -347,6 +423,8 @@ export default {
|
||||
.call(ApiStvAbschlusspruefung.addNewAbschlusspruefung(dataToSend))
|
||||
.then(response => {
|
||||
this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successSave'));
|
||||
//save formData fields in LocalStorage
|
||||
this.saveOrUpdateLocalStorage();
|
||||
this.hideModal('finalexamModal');
|
||||
this.resetForm();
|
||||
})
|
||||
@@ -355,6 +433,26 @@ export default {
|
||||
this.reload();
|
||||
});
|
||||
},
|
||||
async addNewAbschlusspruefungMulti(){
|
||||
try {
|
||||
for (const student of this.studentUids) {
|
||||
|
||||
await this.$refs.formFinalExam.call(
|
||||
ApiStvAbschlusspruefung.addNewAbschlusspruefung({
|
||||
uid: student,
|
||||
formData: this.formData
|
||||
})
|
||||
);
|
||||
}
|
||||
this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successSave'));
|
||||
//save formData fields in LocalStorage
|
||||
this.saveOrUpdateLocalStorage();
|
||||
this.hideModal('finalexamModal');
|
||||
this.resetForm();
|
||||
} catch (error) {
|
||||
this.$fhcAlert.handleSystemError(error);
|
||||
}
|
||||
},
|
||||
hideModal(modalRef){
|
||||
this.$refs[modalRef].hide();
|
||||
},
|
||||
@@ -376,6 +474,9 @@ export default {
|
||||
id: abschlusspruefung_id,
|
||||
formData: this.formData
|
||||
};
|
||||
//uncomment if also save data in local storage for update
|
||||
//this.saveOrUpdateLocalStorage();
|
||||
|
||||
return this.$refs.formFinalExam
|
||||
.call(ApiStvAbschlusspruefung.updateAbschlusspruefung(dataToSend))
|
||||
.then(response => {
|
||||
@@ -417,7 +518,6 @@ export default {
|
||||
this.selectedPruefer1 = null;
|
||||
this.selectedPruefer2 = null;
|
||||
this.selectedPruefer3 = null;
|
||||
|
||||
},
|
||||
setDefaultFormData() {
|
||||
|
||||
@@ -471,29 +571,29 @@ export default {
|
||||
searchPerson(event) {
|
||||
if (this.abortController.persons) {
|
||||
this.abortController.persons.abort();
|
||||
}
|
||||
|
||||
}
|
||||
this.abortController.persons = new AbortController();
|
||||
|
||||
return this.$api
|
||||
.call(ApiStvAbschlusspruefung.getPruefer(event.query))
|
||||
.then(result => {
|
||||
this.filteredPersons = [];
|
||||
for (let person of result.data.retval) {
|
||||
this.filteredPersons.push(
|
||||
{
|
||||
label: this.getPersonLabel(
|
||||
person.titelpre,
|
||||
person.nachname,
|
||||
person.vorname,
|
||||
person.titelpost,
|
||||
person.person_uid
|
||||
),
|
||||
person_id: person.person_id
|
||||
}
|
||||
);
|
||||
}
|
||||
});
|
||||
this.filteredPersons = [];
|
||||
for (let person of result.data.retval) {
|
||||
this.filteredPersons.push(
|
||||
{
|
||||
label: this.getPersonLabel(
|
||||
person.titelpre,
|
||||
person.nachname,
|
||||
person.vorname,
|
||||
person.titelpost,
|
||||
person.uid
|
||||
),
|
||||
person_id: person.person_id,
|
||||
mitarbeiter_uid: person.uid
|
||||
}
|
||||
);
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
created() {
|
||||
@@ -526,7 +626,7 @@ export default {
|
||||
.catch(this.$fhcAlert.handleSystemError);
|
||||
|
||||
this.$api
|
||||
.call(ApiStvAbschlusspruefung.getAkadGrade(this.student.studiengang_kz))
|
||||
.call(ApiStvAbschlusspruefung.getAkadGrade(this.stg_kz))
|
||||
.then(result => {
|
||||
this.arrAkadGrad = result.data;
|
||||
})
|
||||
@@ -547,7 +647,8 @@ export default {
|
||||
<div class="stv-details-abschlusspruefung h-100 pb-3">
|
||||
<h4>{{this.$p.t('stv','tab_finalexam')}}</h4>
|
||||
|
||||
<div v-if="this.student.length">
|
||||
<div v-if="this.student.length" class="d-flex gap-2">
|
||||
<button class="btn btn-primary" @click="actionNewAbschlusspruefung()"> + {{$p.t('stv', 'tab_finalexam')}}</button>
|
||||
<abschlusspruefung-dropdown
|
||||
:showAllFormats="showAllFormats"
|
||||
:studentUids="studentUids"
|
||||
@@ -579,12 +680,14 @@ export default {
|
||||
<template #title>
|
||||
<p v-if="statusNew" class="fw-bold mt-3">{{$p.t('abschlusspruefung', 'abschluessPruefungAnlegen')}}</p>
|
||||
<p v-else class="fw-bold mt-3">{{$p.t('abschlusspruefung', 'abschluessPruefungBearbeiten')}}</p>
|
||||
<small v-if="this.student.length" class="text-muted">{{studentNames}}</small>
|
||||
</template>
|
||||
|
||||
<form-form v-if="!this.student.length" ref="formFinalExam" @submit.prevent>
|
||||
<form-form ref="formFinalExam" @submit.prevent>
|
||||
|
||||
<legend>{{this.$p.t('global','details')}}</legend>
|
||||
<p v-if="statusNew">[{{$p.t('ui', 'neu')}}]</p>
|
||||
|
||||
<div class="row mb-3">
|
||||
<form-input
|
||||
container-class="col-6 stv-details-abschlusspruefung-typ"
|
||||
@@ -602,6 +705,7 @@ export default {
|
||||
</option>
|
||||
</form-input>
|
||||
<form-input
|
||||
v-if="!this.student.length"
|
||||
container-class="col-6 stv-details-abschlusspruefung-note"
|
||||
:label="$p.t('abschlusspruefung', 'notekommpruefung')"
|
||||
type="select"
|
||||
@@ -670,9 +774,10 @@ export default {
|
||||
>
|
||||
</form-input>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="row mb-3">
|
||||
<form-input
|
||||
v-if="!this.student.length"
|
||||
container-class="col-6 stv-details-abschlusspruefung-abschlussbeurteilung_kurzbz"
|
||||
:label="$p.t('abschlusspruefung', 'abschlussbeurteilung')"
|
||||
type="select"
|
||||
@@ -698,7 +803,23 @@ export default {
|
||||
optionValue="person_id"
|
||||
dropdown
|
||||
forceSelection
|
||||
:suggestions="filteredPersons"
|
||||
:suggestions="filteredPersons"
|
||||
@complete="searchPerson"
|
||||
:min-length="3"
|
||||
>
|
||||
</form-input>
|
||||
<form-input
|
||||
v-if="this.student.length"
|
||||
type="autocomplete"
|
||||
container-class="col-6 stv-details-abschlusspruefung-pruefer3"
|
||||
:label="$p.t('abschlusspruefung', 'pruefer3')"
|
||||
name="pruefer3"
|
||||
v-model="selectedPruefer3"
|
||||
optionLabel="label"
|
||||
optionValue="person_id"
|
||||
dropdown
|
||||
forceSelection
|
||||
:suggestions="filteredPersons"
|
||||
@complete="searchPerson"
|
||||
:min-length="3"
|
||||
>
|
||||
@@ -722,6 +843,7 @@ export default {
|
||||
</option>
|
||||
</form-input>
|
||||
<form-input
|
||||
v-if="!this.student.length"
|
||||
type="autocomplete"
|
||||
container-class="col-6 stv-details-abschlusspruefung-pruefer3"
|
||||
:label="$p.t('abschlusspruefung', 'pruefer3')"
|
||||
@@ -731,7 +853,7 @@ export default {
|
||||
optionValue="person_id"
|
||||
dropdown
|
||||
forceSelection
|
||||
:suggestions="filteredPersons"
|
||||
:suggestions="filteredPersons"
|
||||
@complete="searchPerson"
|
||||
:min-length="3"
|
||||
>
|
||||
@@ -779,6 +901,7 @@ export default {
|
||||
>
|
||||
</form-input>
|
||||
<form-input
|
||||
v-if="!this.student.length"
|
||||
container-class="col-6 stv-details-abschlusspruefung-protokoll"
|
||||
:label="$p.t('abschlusspruefung', 'protokoll')"
|
||||
type="textarea"
|
||||
@@ -790,7 +913,7 @@ export default {
|
||||
</form-input>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3 col-6">
|
||||
<div v-if="!this.student.length" class="row mb-3 col-6">
|
||||
<div class="col">
|
||||
<p >{{$p.t('abschlusspruefung', 'zurBeurteilung')}}</p>
|
||||
</div>
|
||||
@@ -807,8 +930,9 @@ export default {
|
||||
|
||||
<template #footer>
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">{{$p.t('ui', 'abbrechen')}}</button>
|
||||
<button v-if="statusNew" class="btn btn-primary" @click="addNewAbschlusspruefung()"> {{$p.t('ui', 'speichern')}}</button>
|
||||
<button v-else class="btn btn-primary" @click="updateAbschlusspruefung(formData.abschlusspruefung_id)"> {{$p.t('ui', 'speichern')}}</button>
|
||||
<button v-if="statusNew && !this.student.length" class="btn btn-primary" @click="addNewAbschlusspruefung()"> {{$p.t('ui', 'speichern')}}</button>
|
||||
<button v-else-if="statusNew && this.student.length" class="btn btn-primary" @click="addNewAbschlusspruefungMulti(studentUids)"> {{$p.t('ui', 'speichern')}}</button>
|
||||
<button v-else class="btn btn-primary" @click="updateAbschlusspruefung(formData.abschlusspruefung_id)"> {{$p.t('ui', 'speichern')}}</button>
|
||||
</template>
|
||||
|
||||
</bs-modal>
|
||||
|
||||
@@ -158,6 +158,16 @@ export default {
|
||||
},
|
||||
reload(){
|
||||
this.updateStudent(this.modelValue);
|
||||
},
|
||||
sendInfomail(){
|
||||
const subject = this.$p.t('person', 'betreffProfilfoto');
|
||||
const subjectEncoded = encodeURIComponent(subject);
|
||||
|
||||
const body = this.$p.t('person', 'mailText_profilfoto');
|
||||
const bodyWithNewLines = body.replace(/\\n/g, '\n');
|
||||
const bodyEncoded = encodeURIComponent(bodyWithNewLines);
|
||||
|
||||
window.location.href = "mailto:" + this.modelValue.mail_intern + "?subject=" + subjectEncoded + "&body=" + bodyEncoded;
|
||||
}
|
||||
},
|
||||
created() {
|
||||
@@ -386,8 +396,10 @@ export default {
|
||||
container-class="col stv-details-details-foto"
|
||||
:label="$p.t('person', 'foto')"
|
||||
type="UploadImage"
|
||||
titleActionButton="Infomail"
|
||||
v-model="data.foto"
|
||||
name="foto"
|
||||
@actionbutton-clicked="sendInfomail"
|
||||
>
|
||||
<img alt="No Image" :src="noImageSrc" class="w-100">
|
||||
</form-input>
|
||||
|
||||
@@ -5,6 +5,7 @@ import PvAutoComplete from "../../../../../../../index.ci.php/public/js/componen
|
||||
import ApiStvProjektarbeit from '../../../../../api/factory/stv/projektarbeit.js';
|
||||
|
||||
export default {
|
||||
name: 'ProjektarbeitDetails',
|
||||
components: {
|
||||
FormForm,
|
||||
FormInput,
|
||||
@@ -110,6 +111,10 @@ export default {
|
||||
this.formData.anmerkung = null;
|
||||
this.$refs.formDetails.clearValidation();
|
||||
},
|
||||
setFormData(projektarbeit) {
|
||||
this.formData = projektarbeit;
|
||||
if (this.formData.firma_id) this.formData.firma = {firma_id: this.formData.firma_id, name: this.formData.firma_name};
|
||||
},
|
||||
getFormData(newProjektarbeit, studiensemester_kurzbz, additional_lehrveranstaltung_id) {
|
||||
|
||||
this.additional_lehrveranstaltung_id = additional_lehrveranstaltung_id;
|
||||
@@ -148,8 +153,7 @@ export default {
|
||||
return this.$api
|
||||
.call(ApiStvProjektarbeit.loadProjektarbeit(projektarbeit_id))
|
||||
.then(result => {
|
||||
this.formData = result.data;
|
||||
if (this.formData.firma_id) this.formData.firma = {firma_id: this.formData.firma_id, name: this.formData.firma_name};
|
||||
this.setFormData(result.data)
|
||||
return result;
|
||||
})
|
||||
.catch(this.$fhcAlert.handleSystemError)
|
||||
|
||||
+40
-56
@@ -9,6 +9,7 @@ import ProjektarbeitDetails from "./Details.js";
|
||||
import Projektbetreuer from "./Projektbetreuer.js";
|
||||
|
||||
export default {
|
||||
name: 'Projektarbeit',
|
||||
components: {
|
||||
CoreFilterCmpt,
|
||||
BsModal,
|
||||
@@ -213,17 +214,6 @@ export default {
|
||||
});
|
||||
container.append(button);
|
||||
|
||||
button = document.createElement('button');
|
||||
button.className = 'btn btn-outline-secondary btn-action';
|
||||
button.innerHTML = '<i class="fa fa-users"></i>';
|
||||
button.title = this.$p.t('projektarbeit', 'betreuerBearbeiten');
|
||||
button.addEventListener('click', (event) => {
|
||||
let data = cell.getData();
|
||||
this.editedProjektarbeit = data;
|
||||
this.actionEditBetreuer();
|
||||
});
|
||||
container.append(button);
|
||||
|
||||
button = document.createElement('button');
|
||||
button.className = 'btn btn-outline-secondary btn-action';
|
||||
button.innerHTML = '<i class="fa fa-xmark"></i>';
|
||||
@@ -264,6 +254,7 @@ export default {
|
||||
actionEditProjektarbeit() {
|
||||
this.statusNew = false;
|
||||
this.toggleMenu('details');
|
||||
this.$refs.projektbetreuer.getProjektbetreuer(this.editedProjektarbeit?.projektarbeit_id, this.editedProjektarbeit?.studiensemester_kurzbz);
|
||||
this.$refs.projektarbeitModal.show();
|
||||
},
|
||||
actionEditBetreuer() {
|
||||
@@ -280,9 +271,18 @@ export default {
|
||||
.then(this.deleteProjektarbeit)
|
||||
.catch(this.$fhcAlert.handleSystemError);
|
||||
},
|
||||
saveProjektarbeit() {
|
||||
if(this.statusNew) this.addNewProjektarbeit()
|
||||
else this.updateProjektarbeit()
|
||||
},
|
||||
addNewProjektarbeit() {
|
||||
this.$refs.projektarbeitDetails.addNewProjektarbeit()
|
||||
.then((result) => {
|
||||
if(result?.data?.length) {
|
||||
this.editedProjektarbeit = result.data[0]
|
||||
this.$refs.projektarbeitDetails.setFormData(this.editedProjektarbeit)
|
||||
this.toggleMenu('betreuer');
|
||||
}
|
||||
this.projektarbeitSaved();
|
||||
})
|
||||
.catch(this.$fhcAlert.handleSystemError);
|
||||
@@ -308,7 +308,8 @@ export default {
|
||||
projektarbeitSaved() {
|
||||
this.reload();
|
||||
this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successSave'));
|
||||
this.hideModal('projektarbeitModal');
|
||||
if(!this.statusNew) this.hideModal('projektarbeitModal');
|
||||
else this.statusNew = false
|
||||
},
|
||||
setDefaultStunden(projekttyp_kurzbz) {
|
||||
this.$refs.projektbetreuer.setDefaultStunden(projekttyp_kurzbz);
|
||||
@@ -321,22 +322,22 @@ export default {
|
||||
},
|
||||
toggleMenu(tabId) {
|
||||
this.activeTab = tabId;
|
||||
if (this.statusNew == false) {
|
||||
switch(tabId) {
|
||||
case 'details':
|
||||
this.$refs.projektarbeitDetails.getFormData(
|
||||
this.statusNew, this.editedProjektarbeit?.studiensemester_kurzbz, this.editedProjektarbeit?.lehrveranstaltung_id
|
||||
);
|
||||
this.$refs.projektarbeitDetails.loadProjektarbeit(this.editedProjektarbeit?.projektarbeit_id);
|
||||
break;
|
||||
case 'betreuer':
|
||||
this.$refs.projektbetreuer.getFormData(
|
||||
this.editedProjektarbeit ? this.editedProjektarbeit.projekttyp_kurzbz : null
|
||||
);
|
||||
this.$refs.projektbetreuer.getProjektbetreuer(this.editedProjektarbeit?.projektarbeit_id, this.editedProjektarbeit?.studiensemester_kurzbz);
|
||||
break;
|
||||
}
|
||||
if (this.statusNew == false && tabId == 'details') {
|
||||
|
||||
this.$refs.projektarbeitDetails.getFormData(
|
||||
this.statusNew, this.editedProjektarbeit?.studiensemester_kurzbz, this.editedProjektarbeit?.lehrveranstaltung_id
|
||||
);
|
||||
this.$refs.projektarbeitDetails.loadProjektarbeit(this.editedProjektarbeit?.projektarbeit_id);
|
||||
} else if(tabId == 'betreuer') {
|
||||
this.$refs.projektbetreuer.getFormData(
|
||||
this.editedProjektarbeit ? this.editedProjektarbeit.projekttyp_kurzbz : null
|
||||
);
|
||||
this.$refs.projektbetreuer.getProjektbetreuer(this.editedProjektarbeit?.projektarbeit_id, this.editedProjektarbeit?.studiensemester_kurzbz);
|
||||
}
|
||||
},
|
||||
resetFormData() {
|
||||
this.$refs.projektarbeitDetails.resetForm()
|
||||
this.$refs.projektbetreuer.resetForm()
|
||||
}
|
||||
},
|
||||
template: `
|
||||
@@ -358,46 +359,29 @@ export default {
|
||||
</core-filter-cmpt>
|
||||
|
||||
<!--Modal: projektarbeitModal-->
|
||||
<bs-modal ref="projektarbeitModal" dialog-class="modal-xl modal-dialog-scrollable" header-class="flex-wrap pb-0">
|
||||
<bs-modal ref="projektarbeitModal" :dialog-class="(statusNew ? 'modal-xl ' : 'fhc-xxl-modal ' ) + 'modal-dialog-scrollable'"
|
||||
header-class="flex-wrap pb-0"
|
||||
@hideBsModal="resetFormData"
|
||||
>
|
||||
<template #title>
|
||||
<p v-if="statusNew" class="fw-bold mt-3">{{$p.t('projektarbeit', 'projektarbeitAnlegen')}}</p>
|
||||
<p v-else class="fw-bold mt-3">{{$p.t('projektarbeit', 'projektarbeitBearbeiten')}}</p>
|
||||
</template>
|
||||
|
||||
<template #modal-header-content v-if="!statusNew">
|
||||
<ul class="nav nav-tabs w-100 mt-3 msg_preview" id="pa_tabs" role="tablist">
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link" :class="activeTab == 'details' ? 'active' : ''" id="details-tab" data-bs-toggle="tab" data-bs-target="#details" type="button" role="tab" aria-controls="details" aria-selected="true" @click="toggleMenu('details')">Details</button>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link" :class="activeTab == 'betreuer' ? 'active' : ''" id="betreuer-tab" data-bs-toggle="tab" data-bs-target="#betreuer" type="button" role="tab" aria-controls="betreuer" aria-selected="false" @click="toggleMenu('betreuer')">{{$p.t('projektarbeit', 'betreuerGross')}}</button>
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
|
||||
<div class="tab-content" id="pa_content">
|
||||
<div class="tab-pane fade show" :class="activeTab == 'details' ? 'active' : ''" id="details" role="tabpanel" aria-labelledby="details-tab">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<projektarbeit-details ref="projektarbeitDetails" :student="student" @projekttyp-changed="setDefaultStunden">
|
||||
</projektarbeit-details>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" >
|
||||
<div :class="statusNew ? 'col-12' : 'col-6'">
|
||||
<projektarbeit-details ref="projektarbeitDetails" :student="student" @projekttyp-changed="setDefaultStunden">
|
||||
</projektarbeit-details>
|
||||
</div>
|
||||
|
||||
<div class="tab-pane fade show" :class="activeTab == 'betreuer' ? 'active' : ''" id="betreuer" role="tabpanel" aria-labelledby="betreuer-tab">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<projektbetreuer ref="projektbetreuer" :config="config" @betreuer-saved="reload"></projektbetreuer>
|
||||
</div>
|
||||
</div>
|
||||
<div :class="statusNew ? '' : 'col-6'" :style="statusNew ? 'display: none' : ''">
|
||||
<projektbetreuer ref="projektbetreuer" :config="config" @betreuer-saved="reload"></projektbetreuer>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<template #footer>
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">{{$p.t('ui', 'abbrechen')}}</button>
|
||||
<button v-if="statusNew" class="btn btn-primary" @click="addNewProjektarbeit()"> {{$p.t('ui', 'speichern')}}</button>
|
||||
<button v-if="!statusNew && activeTab == 'details'" class="btn btn-primary" @click="updateProjektarbeit()"> {{$p.t('ui', 'speichern')}}</button>
|
||||
<button type="button" class="btn btn-secondary" @click="resetFormData" data-bs-dismiss="modal">{{$p.t('ui', 'abbrechen')}}</button>
|
||||
<button class="btn btn-primary" @click="saveProjektarbeit()"> {{$p.t('ui', 'speichern')}}</button>
|
||||
</template>
|
||||
|
||||
</bs-modal>
|
||||
|
||||
@@ -10,6 +10,7 @@ import Vertrag from "./Vertrag.js";
|
||||
import ApiStvProjektbetreuer from '../../../../../api/factory/stv/projektbetreuer.js';
|
||||
|
||||
export default {
|
||||
name: 'Projektbetreuer',
|
||||
components: {
|
||||
CoreFilterCmpt,
|
||||
BsModal,
|
||||
|
||||
@@ -93,7 +93,7 @@ export default {
|
||||
}
|
||||
},
|
||||
{title:"Geschlecht", field:"geschlecht", headerFilter: "list", headerFilterParams: {values:{'m':'männlich','w':'weiblich','x':'divers','u':'unbekannt'}, listOnEmpty:true, autocomplete:true}},
|
||||
{title:"Sem.", field:"semester", headerFilter: "list", headerFilterParams: {valuesLookup:true, listOnEmpty:true, autocomplete:true, sort:"asc"}},
|
||||
{title:"Sem.", field:"semester_berechnet", headerFilter: "list", headerFilterParams: {valuesLookup:true, listOnEmpty:true, autocomplete:true, sort:"asc"}},
|
||||
{title:"Verb.", field:"verband", headerFilter: "list", headerFilterParams: {valuesLookup:true, listOnEmpty:true, autocomplete:true, sort:"asc"}},
|
||||
{title:"Grp.", field:"gruppe", headerFilter: "list", headerFilterParams: {valuesLookup:true, listOnEmpty:true, autocomplete:true, sort:"asc"}},
|
||||
{title:"Studiengang", field:"studiengang", headerFilter: "list", headerFilterParams: {valuesLookup:true, listOnEmpty:true, autocomplete:true, sort:"asc"}},
|
||||
@@ -171,7 +171,7 @@ export default {
|
||||
selectableRows: true,
|
||||
selectableRowsRangeMode: 'click',
|
||||
index: 'prestudent_id',
|
||||
persistenceID: 'stv-list',
|
||||
persistenceID: 'stv-list-20260223_01'
|
||||
},
|
||||
tabulatorEvents: [
|
||||
{
|
||||
@@ -195,7 +195,15 @@ export default {
|
||||
},
|
||||
{
|
||||
event: 'dataLoaded',
|
||||
handler: data => this.count = data.length
|
||||
handler: data => {
|
||||
if (Array.isArray(data)) {
|
||||
this.count = data.length;
|
||||
this.allPrestudents = data.map(item => item.prestudent_id);
|
||||
} else {
|
||||
this.count = 0;
|
||||
this.allPrestudents = [];
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
event: 'dataFiltered',
|
||||
@@ -237,7 +245,8 @@ export default {
|
||||
dragSource: [],
|
||||
oldScrollUrl: '',
|
||||
oldScrollLeft: 0,
|
||||
oldScrollTop: 0
|
||||
oldScrollTop: 0,
|
||||
allPrestudents: []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@@ -274,6 +283,7 @@ export default {
|
||||
};
|
||||
});
|
||||
},
|
||||
//TODO(Manu) check: replace download or additional entry?
|
||||
downloadConfig() {
|
||||
return {
|
||||
csv: {
|
||||
@@ -291,6 +301,21 @@ export default {
|
||||
.replace(/\//g, '_');
|
||||
return "StudentList_" + today + ".csv";
|
||||
},
|
||||
selectedPrestudents() {
|
||||
if (this.selected && this.selected.length > 0) {
|
||||
return this.selected.map(item => item.prestudent_id);
|
||||
} else {
|
||||
// fallback whole list of prestudents
|
||||
return this.allPrestudents || [];
|
||||
}
|
||||
},
|
||||
|
||||
linkXLS(){
|
||||
return FHC_JS_DATA_STORAGE_OBJECT.app_root
|
||||
+ 'content/statistik/studentenexportextended.xls.php?'
|
||||
+ '&studiensemester_kurzbz=' + this.currentSemester
|
||||
+ '&data=' + this.selectedPrestudents.join(";");
|
||||
},
|
||||
},
|
||||
created: function() {
|
||||
if(this.tagsEnabled) {
|
||||
@@ -330,7 +355,7 @@ export default {
|
||||
ersatzkennzeichen: capitalize(this.$p.t('person/ersatzkennzeichen')),
|
||||
gebdatum: capitalize(this.$p.t('person/geburtsdatum')),
|
||||
geschlecht: capitalize(this.$p.t('person/geschlecht')),
|
||||
semester: capitalize(this.$p.t('lehre/sem')),
|
||||
semester_berechnet: capitalize(this.$p.t('lehre/sem')),
|
||||
verband: capitalize(this.$p.t('lehre/verb')),
|
||||
gruppe: capitalize(this.$p.t('lehre/grp')),
|
||||
studiengang: capitalize(this.$p.t('lehre/studiengang')),
|
||||
@@ -391,15 +416,17 @@ export default {
|
||||
actionNewPrestudent() {
|
||||
this.$refs.new.open();
|
||||
},
|
||||
rowSelectionChanged(data, rows) {
|
||||
rowSelectionChanged(data, rows, selected, deselected) {
|
||||
this.selectedcount = data.length;
|
||||
this.lastSelected = this.selected;
|
||||
|
||||
if(selected.length > 0 || deselected.length > 0){
|
||||
this.lastSelected = this.selected;
|
||||
this.$emit('update:selected', data);
|
||||
}
|
||||
|
||||
//for tags
|
||||
this.selectedRows = this.$refs.table.tabulator.getSelectedRows();
|
||||
this.selectedColumnValues = this.selectedRows.filter(row => row.getData().prestudent_id !== undefined && row.getData().prestudent_id).map(row => row.getData().prestudent_id);
|
||||
|
||||
this.$emit('update:selected', data);
|
||||
},
|
||||
autoSelectRows(data) {
|
||||
if (Array.isArray(this.lastSelected) && this.lastSelected.length){
|
||||
@@ -546,6 +573,10 @@ export default {
|
||||
this.changeFocus(this.focusObj, el);
|
||||
}
|
||||
},
|
||||
clearSelection(){
|
||||
this.lastSelected = [];
|
||||
this.$emit('update:selected',[]);
|
||||
},
|
||||
//methods tags
|
||||
addedTag(addedTag)
|
||||
{
|
||||
@@ -600,7 +631,7 @@ export default {
|
||||
// TODO(chris): focusin, focusout, keydown and tabindex should be in the filter component
|
||||
// TODO(chris): filter component column chooser has no accessibilty features
|
||||
template: `
|
||||
<div class="stv-list h-100 pt-3">
|
||||
<div class="stv-list h-100 pt-3">
|
||||
<div
|
||||
class="tabulator-container d-flex flex-column h-100"
|
||||
:class="{'has-filter': filter.length}"
|
||||
@@ -627,6 +658,27 @@ export default {
|
||||
@headerFilterOn="handleHeaderFilter"
|
||||
>
|
||||
|
||||
<!--
|
||||
<template #actions>
|
||||
<div>
|
||||
<button
|
||||
class="btn btn-outline-success sm mb-1"
|
||||
:title="'Export ' + selectedPrestudents.length + ' prestudent(s) to Excel'"
|
||||
>
|
||||
<i class="fas fa-file-excel fa-xl"></i>
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
-->
|
||||
|
||||
<template #additional>
|
||||
<div class="pe-2">
|
||||
<a :href="linkXLS" target="_blank">
|
||||
<i class="fas fa-file-excel fa-xl text-success" :title="$p.t('stv', 'text_exportXLS', { count: selectedPrestudents.length })"></i>
|
||||
</a>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #actions>
|
||||
<core-tag ref="tagComponent"
|
||||
v-if="tagsEnabled"
|
||||
|
||||
@@ -723,6 +723,7 @@ export const CoreFilterCmpt = {
|
||||
<span class="fa-solid fa-xl fa-table-columns"></span>
|
||||
</a>
|
||||
<table-download class="btn btn-link px-0 fhc-text" :tabulator="tabulator" :config="download"></table-download>
|
||||
<slot name="additional"></slot>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -0,0 +1,147 @@
|
||||
export default {
|
||||
name: 'HorizontalSplit',
|
||||
props: {
|
||||
defaultRatio: {
|
||||
type: Array,
|
||||
default: () => [50, 50]
|
||||
}
|
||||
},
|
||||
data: function () {
|
||||
return {
|
||||
availWidth: 0,
|
||||
leftwidth: 0,
|
||||
rightwidth: 0,
|
||||
mousePosX: 0,
|
||||
resize: false,
|
||||
hsplitterOffset: 0,
|
||||
selfOffsetLeft: 0
|
||||
};
|
||||
},
|
||||
template: `
|
||||
<div ref="horizontalsplit" class="horizontalsplit-container">
|
||||
<div ref="leftpanel" class="horizontalsplitted"
|
||||
:style="{ width: this.leftwidthcss }">
|
||||
<slot name="left">
|
||||
<p>Left Panel</p>
|
||||
</slot>
|
||||
</div>
|
||||
<div ref="hsplitter" class="horizontalsplitter"
|
||||
:class="this.leftOrRightClass" @mousedown="this.dragStart">
|
||||
<div class="splitactions horizontal" :class="this.leftOrRightClass">
|
||||
<span @click="this.collapseRight" class="splitaction">
|
||||
<i class="fas fa-angle-right text-muted"></i>
|
||||
</span>
|
||||
<span @dblclick="this.showBoth" class="splitaction resize">
|
||||
<i class="fas fa-grip-lines-vertical text-muted"></i>
|
||||
</span>
|
||||
<span @click="this.collapseLeft" class="splitaction">
|
||||
<i class="fas fa-angle-left text-muted"></i>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div ref="rightpanel" class="horizontalsplitted"
|
||||
:style="{ width: this.rightwidthcss }">
|
||||
<slot name="right">
|
||||
<p/>
|
||||
</slot>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
mounted: function () {
|
||||
this.calcWidths();
|
||||
this.trackHorizontalSplitterOffsetLeft();
|
||||
window.addEventListener('resize', this.calcWidths);
|
||||
},
|
||||
updated: function () {
|
||||
this.trackHorizontalSplitterOffsetLeft();
|
||||
},
|
||||
beforeDestroy: function () {
|
||||
window.removeEventListener('resize', this.calcWidths);
|
||||
},
|
||||
methods: {
|
||||
calcWidths: function () {
|
||||
var oldavailWidth = this.availWidth;
|
||||
this.selfOffsetLeft = this.$refs.horizontalsplit.offsetLeft;
|
||||
this.availWidth = this.$refs.horizontalsplit.offsetWidth - this.$refs.hsplitter.offsetWidth;
|
||||
|
||||
if ((this.leftwidth === 0 && this.rightwidth === 0) || oldavailWidth === 0) {
|
||||
this.leftwidth = Math.floor(this.availWidth * (this.defaultRatio[0] / 100));
|
||||
} else {
|
||||
this.leftwidth = Math.floor(((this.leftwidth * 100) / oldavailWidth) / 100 * this.availWidth);
|
||||
}
|
||||
this.rightwidth = this.availWidth - this.leftwidth;
|
||||
},
|
||||
collapseLeft: function () {
|
||||
this.calcWidths();
|
||||
this.leftwidth = 0;
|
||||
this.rightwidth = this.availWidth;
|
||||
},
|
||||
collapseRight: function () {
|
||||
this.calcWidths();
|
||||
this.leftwidth = this.availWidth;
|
||||
this.rightwidth = 0;
|
||||
},
|
||||
showBoth: function () {
|
||||
this.leftwidth = Math.floor(this.availWidth * (this.defaultRatio[0] / 100));
|
||||
this.rightwidth = this.availWidth - this.leftwidth;
|
||||
},
|
||||
isCollapsed: function () {
|
||||
if (this.leftwidth === 0) {
|
||||
return 'left';
|
||||
} else if (this.rightwidth === 0) {
|
||||
return 'right';
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
dragStart: function (e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
window.addEventListener('mouseup', this.dragEnd);
|
||||
window.addEventListener('mousemove', this.drag);
|
||||
this.resize = true;
|
||||
this.mousePosX = e.clientX;
|
||||
},
|
||||
drag: function (e) {
|
||||
if (!this.resize) {
|
||||
return;
|
||||
}
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
var offsetX = e.clientX - this.mousePosX;
|
||||
this.leftwidth = this.leftwidth + offsetX;
|
||||
if (this.leftwidth < 0) {
|
||||
this.leftwidth = 0;
|
||||
}
|
||||
if (this.leftwidth > this.availWidth) {
|
||||
this.leftwidth = this.availWidth;
|
||||
}
|
||||
this.rightwidth = this.availWidth - this.leftwidth;
|
||||
this.mousePosX = e.clientX;
|
||||
},
|
||||
dragEnd: function (e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
window.removeEventListener('mousemove', this.drag);
|
||||
window.removeEventListener('mouseup', this.dragEnd);
|
||||
this.resize = false;
|
||||
this.mousePosX = e.clientX;
|
||||
},
|
||||
trackHorizontalSplitterOffsetLeft: function () {
|
||||
this.hsplitterOffset = this.$refs.hsplitter.offsetLeft;
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
leftOrRightClass: function () {
|
||||
return ((this.hsplitterOffset - this.selfOffsetLeft) <= Math.floor(this.availWidth / 2))
|
||||
? 'left'
|
||||
: 'right';
|
||||
},
|
||||
leftwidthcss: function () {
|
||||
return this.leftwidth + 'px';
|
||||
},
|
||||
rightwidthcss: function () {
|
||||
return this.rightwidth + 'px';
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -1,5 +1,11 @@
|
||||
export default {
|
||||
name: 'VerticalSplit',
|
||||
props: {
|
||||
defaultRatio: {
|
||||
type: Array,
|
||||
default: () => [50, 50]
|
||||
}
|
||||
},
|
||||
data: function() {
|
||||
return {
|
||||
availHeight: 0,
|
||||
@@ -50,17 +56,22 @@ export default {
|
||||
updated: function() {
|
||||
this.trackVerticalSplitterOffsetTop();
|
||||
},
|
||||
beforeDestroy: function () {
|
||||
window.removeEventListener('resize', this.calcHeights);
|
||||
},
|
||||
methods: {
|
||||
calcHeights: function() {
|
||||
var windowheight = window.innerHeight;
|
||||
var oldavailHeight = this.availHeight;
|
||||
this.selfOffsetTop = this.$refs.verticalsplit.offsetTop;
|
||||
this.availHeight = windowheight - this.selfOffsetTop - this.$refs.vsplitter.offsetHeight;
|
||||
|
||||
if( (this.topheight === 0 && this.bottomheight === 0) || oldavailHeight === 0 ) {
|
||||
this.topheight = Math.floor(this.availHeight/2);
|
||||
this.topheight = Math.floor(this.availHeight * (this.defaultRatio[0] / 100));
|
||||
} else {
|
||||
this.topheight = Math.floor( ((((this.topheight * 100) / oldavailHeight) / 100) * this.availHeight) );
|
||||
}
|
||||
|
||||
this.bottomheight = this.availHeight - this.topheight;
|
||||
},
|
||||
collapseTop: function() {
|
||||
@@ -74,8 +85,8 @@ export default {
|
||||
this.bottomheight = 0;
|
||||
},
|
||||
showBoth: function() {
|
||||
this.topheight = Math.floor(this.availHeight/2);
|
||||
this.bottomheight = Math.floor(this.availHeight/2);
|
||||
this.topheight = Math.floor(this.availHeight * (this.defaultRatio[0] / 100));
|
||||
this.bottomheight = this.availHeight - this.topheight
|
||||
},
|
||||
isCollapsed: function() {
|
||||
if( this.topheight === 0 ) {
|
||||
|
||||
@@ -53699,6 +53699,46 @@ and represent the current state of research on the topic. The prescribed citatio
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'person',
|
||||
'phrase' => 'mailText_profilfoto',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => "Hallo,\n\nIhr Profilbild wurde entfernt, da es nicht den aktuellen Bildrichtlinen entspricht. Bitte laden Sie unter CIS->Profil ein neues Profilbild hoch!\n\nDanke!",
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => "Hello,\n\nYour profile picture has been removed because it does not comply with the current image guidelines. Please upload a new profile picture under CIS->Profile!\n\nThank you!",
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'person',
|
||||
'phrase' => 'betreffProfilfoto',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Profilbild',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'Profile picture',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
// FHC-4 Finetuning END
|
||||
|
||||
//**************************** CORE/search
|
||||
@@ -58095,6 +58135,86 @@ I have been informed that I am under no obligation to consent to the transmissio
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'stv',
|
||||
'phrase' => 'lvplanung',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'LV-Planung',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'Course-Planning',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'stv',
|
||||
'phrase' => 'lvplanung_xls',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'LV-Planung EXCEL',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'Course-Planning EXCEL',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'stv',
|
||||
'phrase' => 'lvplanung_html',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'LV-Planung HTML',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'Course-Planning HTML',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'stv',
|
||||
'phrase' => 'RTVerwaltung',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Reihungstestverwaltung',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'Administration Placement Test',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
|
||||
// ### Phrases Dashboard Admin START
|
||||
array(
|
||||
@@ -58177,6 +58297,86 @@ I have been informed that I am under no obligation to consent to the transmissio
|
||||
)
|
||||
),
|
||||
// ### Phrases Dashboard Admin END
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'stv',
|
||||
'phrase' => 'text_exportXLS',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => '{count} Prestudent(Innen) als Excel exportieren',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'Export {count} prestudent(s) to Excel',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'ui',
|
||||
'phrase' => 'alert_chooseStudent',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Bitte eine/n Studierende/n markieren!',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'Please select a student!',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'stv',
|
||||
'phrase' => 'studienverlauf',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Studienverlauf',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'Gradelist',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'lehre',
|
||||
'phrase' => 'textNoStatusInSem',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Kein Status im {sem}',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'No status in {sem}',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
);
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user