Merge branch 'feature-39571/Studierendenverwaltung_CoreNotizcontroller' into studvw_2026-02_rc4

This commit is contained in:
Harald Bamberger
2026-02-03 10:43:39 +01:00
42 changed files with 1656 additions and 335 deletions
+13
View File
@@ -130,3 +130,16 @@ $config['students_tab_order'] = [
'combinePeople',
'archive',
];
$config['stv_prestudent_tags'] = [
'prioone' => ['readonly' => false],
'priotwo' => ['readonly' => true],
'hinweis' => ['readonly' => false],
'hinweis_assistenz' => ['readonly' => true],
'hinweis_kf' => ['readonly' => true],
'hinweis_lehrende' => ['readonly' => false],
'hinweis_stg_kf' => ['readonly' => true],
'finished_stg' => ['readonly' => true],
'finished_kf' => ['readonly' => true],
'inwork_kf' => ['readonly' => true],
];
@@ -0,0 +1,44 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
use \DateTime as DateTime;
class NotizAnrechnung extends Notiz_Controller
{
public function __construct()
{
parent::__construct([
'isBerechtigt' => ['admin:r', 'assistenz:r'],
]);
//Load Models
$this->load->model('person/Notiz_model', 'NotizModel');
$this->load->model('person/Notizzuordnung_model', 'NotizzuordnungModel');
// Load Libraries
$this->load->library('VariableLib', ['uid' => getAuthUID()]);
// Load language phrases
$this->loadPhrases([
'ui'
]);
}
public function isBerechtigt($id, $typeId)
{
if($typeId != "anrechnung_id")
{
$this->terminateWithError($this->p->t('ui','error_typeNotizIdIncorrect'), self::ERROR_TYPE_GENERAL);
}
//TODO define permission
if(!$this->permissionlib->isBerechtigt('admin', 'suid') && !$this->permissionlib->isBerechtigt('assistenz', 'suid'))
{
$result = $this->p->t('lehre','error_keineSchreibrechte');
$this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
}
$this->terminateWithSuccess("berechtigt in überschreibender Funktion");
}
}
@@ -0,0 +1,43 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
use \DateTime as DateTime;
class NotizBestellung extends Notiz_Controller
{
public function __construct()
{
parent::__construct([
'isBerechtigt' => ['admin:r', 'assistenz:r'],
]);
//Load Models
$this->load->model('person/Notiz_model', 'NotizModel');
$this->load->model('person/Notizzuordnung_model', 'NotizzuordnungModel');
// Load Libraries
$this->load->library('VariableLib', ['uid' => getAuthUID()]);
// Load language phrases
$this->loadPhrases([
'ui'
]);
}
public function isBerechtigt($id, $typeId)
{
if($typeId != "bestellung_id")
{
$this->terminateWithError($this->p->t('ui','error_typeNotizIdIncorrect'), self::ERROR_TYPE_GENERAL);
}
//TODO define permission
if(!$this->permissionlib->isBerechtigt('admin', 'suid') && !$this->permissionlib->isBerechtigt('assistenz', 'suid'))
{
$result = $this->p->t('lehre','error_keineSchreibrechte');
$this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
}
$this->terminateWithSuccess("berechtigt in überschreibender Funktion");
}
}
@@ -17,5 +17,106 @@ class NotizLehreinheit extends Notiz_Controller
'getMitarbeiter' => ['admin:r', 'assistenz:r'],
'isBerechtigt' => ['admin:r', 'assistenz:r'],
]);
//Load Models
$this->load->model('person/Notiz_model', 'NotizModel');
$this->load->model('person/Notizzuordnung_model', 'NotizzuordnungModel');
$this->load->model('education/Lehreinheit_model', 'LehreinheitModel');
// Load Libraries
$this->load->library('VariableLib', ['uid' => getAuthUID()]);
//Permission checks for allowed Oes
$allowedOes = $this->permissionlib->getOE_isEntitledFor('assistenz') ?: [];
if ($this->router->method == 'addNewNotiz')
{
$json = $this->input->post('data');
$post_data = json_decode($json, true);
$lehreinheit_id = $post_data['id'];
if(!$lehreinheit_id)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Lehreinheit ID']), self::ERROR_TYPE_GENERAL);
}
$this->_checkAllowedOesFromLehreinheit($lehreinheit_id, $allowedOes);
}
if ($this->router->method == 'updateNotiz')
{
$json = $this->input->post('data');
$post_data = json_decode($json, true);
$notiz_id = $post_data['notiz_id'];
if(!$notiz_id)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Notiz ID']), self::ERROR_TYPE_GENERAL);
}
//get lehreinheit_id
$result = $this->NotizzuordnungModel->loadWhere(['notiz_id' => $notiz_id]);
$data = $this->getDataOrTerminateWithError($result);
$lehreinheit_id = current($data)->lehreinheit_id;
if(!$lehreinheit_id)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Lehreinheit ID']), self::ERROR_TYPE_GENERAL);
}
$this->_checkAllowedOesFromLehreinheit($lehreinheit_id, $allowedOes);
}
if ($this->router->method == 'deleteNotiz')
{
$notiz_id = $this->input->post('notiz_id');
$lehreinheit_id = $this->input->post('id');
if(!$notiz_id)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Notiz ID']), self::ERROR_TYPE_GENERAL);
}
if(!$lehreinheit_id)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Lehreinheit ID']), self::ERROR_TYPE_GENERAL);
}
$this->_checkAllowedOesFromLehreinheit($lehreinheit_id, $allowedOes);
}
// Load language phrases
$this->loadPhrases([
'ui'
]);
}
}
private function _checkAllowedOesFromLehreinheit($lehreinheit_id, $allowedOes)
{
//get oe from lehreinheit
$result = $this->LehreinheitModel->getOes($lehreinheit_id);
$data = $this->getDataOrTerminateWithError($result);
$oes = current($data);
if (!in_array($oes, $allowedOes))
{
return $this->terminateWithError($this->p->t('ui', 'error_keineBerechtigungStg') . " " . $oes, self::ERROR_TYPE_GENERAL);
}
}
public function isBerechtigt($id, $typeId)
{
if($typeId != "lehreinheit_id")
{
$this->terminateWithError($this->p->t('ui','error_typeNotizIdIncorrect'), self::ERROR_TYPE_GENERAL);
}
if(!$this->permissionlib->isBerechtigt('admin', 'suid') && !$this->permissionlib->isBerechtigt('assistenz', 'suid'))
{
$result = $this->p->t('lehre','error_keineSchreibrechte');
$this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
}
$this->terminateWithSuccess("berechtigt in überschreibender Funktion");
}
}
@@ -0,0 +1,44 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
use \DateTime as DateTime;
class NotizMitarbeiter extends Notiz_Controller
{
public function __construct()
{
parent::__construct([
'isBerechtigt' => ['admin:r', 'assistenz:r'],
]);
//Load Models
$this->load->model('person/Notiz_model', 'NotizModel');
$this->load->model('person/Notizzuordnung_model', 'NotizzuordnungModel');
// Load Libraries
$this->load->library('VariableLib', ['uid' => getAuthUID()]);
// Load language phrases
$this->loadPhrases([
'ui'
]);
}
public function isBerechtigt($id, $typeId)
{
if($typeId != "mitarbeiter_uid")
{
$this->terminateWithError($this->p->t('ui','error_typeNotizIdIncorrect'), self::ERROR_TYPE_GENERAL);
}
//TODO define permission
if(!$this->permissionlib->isBerechtigt('admin', 'suid') && !$this->permissionlib->isBerechtigt('assistenz', 'suid'))
{
$result = $this->p->t('lehre','error_keineSchreibrechte');
$this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
}
$this->terminateWithSuccess("berechtigt in überschreibender Funktion");
}
}
@@ -20,33 +20,123 @@ class NotizPerson extends Notiz_Controller
'isBerechtigt' => ['admin:r', 'assistenz:r'],
'getCountNotes' => ['admin:r', 'assistenz:r'],
]);
//Load Models
$this->load->model('person/Benutzer_model', 'BenutzerModel');
$this->load->model('crm/Student_model', 'StudentModel');
//Permission checks for allowed Oes
if ($this->router->method == 'addNewNotiz')
{
$json = $this->input->post('data');
$post_data = json_decode($json, true);
$person_id = $post_data['id'];
$allowedStgs = $this->permissionlib->getSTG_isEntitledFor('assistenz') ?: [];
if(!$person_id)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Person ID']), self::ERROR_TYPE_GENERAL);
}
$this->_checkIfBerechtigungForOneUidExists($person_id, $allowedStgs);
}
if ( $this->router->method == 'updateNotiz')
{
$json = $this->input->post('data');
$post_data = json_decode($json, true);
$notiz_id = $post_data['notiz_id'];
if(!$notiz_id)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Notiz ID']), self::ERROR_TYPE_GENERAL);
}
//get person_id
$result = $this->NotizzuordnungModel->loadWhere(['notiz_id' => $notiz_id]);
$data = $this->getDataOrTerminateWithError($result);
$person_id = current($data)->person_id;
$allowedStgs = $this->permissionlib->getSTG_isEntitledFor('assistenz') ?: [];
$this->_checkIfBerechtigungForOneUidExists($person_id, $allowedStgs);
}
if ($this->router->method == 'deleteNotiz' )
{
$notiz_id = $this->input->post('notiz_id');
$person_id = $this->input->post('id');
if(!$notiz_id)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Notiz ID']), self::ERROR_TYPE_GENERAL);
}
if(!$person_id)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'person ID']), self::ERROR_TYPE_GENERAL);
}
$allowedStgs = $this->permissionlib->getSTG_isEntitledFor('assistenz') ?: [];
$this->_checkIfBerechtigungForOneUidExists($person_id, $allowedStgs);
}
}
public function isBerechtigt($id, $typeId)
{
if($typeId != "person_id")
{
return $this->terminateWithError($this->p->t('ui', 'error_typeNotizIdIncorrect'), self::ERROR_TYPE_GENERAL);
$this->terminateWithError($this->p->t('ui', 'error_typeNotizIdIncorrect'), self::ERROR_TYPE_GENERAL);
}
//TODO define permission
if (!$this->permissionlib->isBerechtigt('admin', 'suid') && !$this->permissionlib->isBerechtigt('assistenz', 'suid'))
{
$result = $this->p->t('lehre', 'error_keineSchreibrechte');
return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
$this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
}
return $this->outputJsonSuccess(true);
$this->terminateWithSuccess("berechtigt in überschreibender Funktion");
}
public function loadDokumente()
//stv: if person has permission of one studiengang of person -> permission to add/update/delete Note
private function _checkIfBerechtigungForOneUidExists($person_id, $allowedStgs)
{
$notiz_id = $this->input->post('notiz_id');
//get all studentUids of person_id
$result = $this->BenutzerModel->loadWhere(['person_id' => $person_id]);
$data = $this->getDataOrTerminateWithError($result);
// TODO(chris): make CI variant of endpoint
$this->NotizModel->addSelect($this->NotizModel->escape(base_url('content/notizdokdownload.php?id=')) . ' || campus.tbl_dms_version.dms_id AS preview');
return parent::loadDokumente();
$checkarray = [];
foreach ($data as $item)
{
//check if isStudent
$result = $this->StudentModel->isStudent($item->uid);
$isStudent = $this->getDataOrTerminateWithError($result);
if($isStudent)
{
$checkarray[] = $this->_checkAllowedStgsFromUid($item->uid, $allowedStgs);
}
}
if (!in_array(1, $checkarray))
return $this->terminateWithError($this->p->t('ui', 'error_keineBerechtigungStg'), self::ERROR_TYPE_GENERAL);
}
}
private function _checkAllowedStgsFromUid($student_uid, $allowedStgs)
{
$this->load->model('crm/Student_model', 'StudentModel');
$result = $this->StudentModel->loadWhere(['student_uid' => $student_uid]);
$data = $this->getDataOrTerminateWithError($result);
$studiengang_kz = current($data)->studiengang_kz;
if (!in_array($studiengang_kz, $allowedStgs))
{
return 0;
}
else
{
return 1;
}
}
}
@@ -0,0 +1,117 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
use \DateTime as DateTime;
class NotizPrestudent extends Notiz_Controller
{
public function __construct()
{
parent::__construct([
'isBerechtigt' => ['admin:r', 'assistenz:r'],
]);
//Load Models
$this->load->model('person/Notiz_model', 'NotizModel');
$this->load->model('person/Notizzuordnung_model', 'NotizzuordnungModel');
$this->load->model('crm/Student_model', 'StudentModel');
// Load Libraries
$this->load->library('VariableLib', ['uid' => getAuthUID()]);
// Load language phrases
$this->loadPhrases([
'ui'
]);
//Permission checks for Studiengangsarray
$allowedStgs = $this->permissionlib->getSTG_isEntitledFor('assistenz') ?: [];
if ($this->router->method == 'addNewNotiz')
{
$json = $this->input->post('data');
$post_data = json_decode($json, true);
$prestudent_id = $post_data['id'];
if(!$prestudent_id)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Lehreinheit ID']), self::ERROR_TYPE_GENERAL);
}
$this->_checkAllowedOesFromPrestudent($prestudent_id, $allowedStgs);
}
if ($this->router->method == 'updateNotiz')
{
$json = $this->input->post('data');
$post_data = json_decode($json, true);
$notiz_id = $post_data['notiz_id'];
if(!$notiz_id)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Notiz ID']), self::ERROR_TYPE_GENERAL);
}
//get prestudent_id
$result = $this->NotizzuordnungModel->loadWhere(['notiz_id' => $notiz_id]);
$data = $this->getDataOrTerminateWithError($result);
$prestudent_id = current($data)->prestudent_id;
if(!$prestudent_id)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Prestudent ID']), self::ERROR_TYPE_GENERAL);
}
$this->_checkAllowedOesFromPrestudent($prestudent_id, $allowedStgs);
}
if ($this->router->method == 'deleteNotiz')
{
$notiz_id = $this->input->post('notiz_id');
$prestudent_id = $this->input->post('id');
if(!$notiz_id)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Notiz ID']), self::ERROR_TYPE_GENERAL);
}
if(!$prestudent_id)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Prestudent ID']), self::ERROR_TYPE_GENERAL);
}
$this->_checkAllowedOesFromPrestudent($prestudent_id, $allowedStgs);
}
}
public function isBerechtigt($id, $typeId)
{
if($typeId != "prestudent_id")
{
$this->terminateWithError($this->p->t('ui','error_typeNotizIdIncorrect'), self::ERROR_TYPE_GENERAL);
}
if(!$this->permissionlib->isBerechtigt('admin', 'suid') && !$this->permissionlib->isBerechtigt('assistenz', 'suid'))
{
$result = $this->p->t('lehre','error_keineSchreibrechte');
$this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
}
$this->terminateWithSuccess("berechtigt in überschreibender Funktion");
}
private function _checkAllowedOesFromPrestudent($prestudent_id, $allowedStgs)
{
$student_uid = $this->StudentModel->getUID($prestudent_id);
$result = $this->StudentModel->loadWhere(['student_uid' => $student_uid]);
$data = $this->getDataOrTerminateWithError($result);
$studiengang_kz = current($data)->studiengang_kz;
if (!in_array($studiengang_kz, $allowedStgs))
{
return $this->terminateWithError($this->p->t('ui', 'error_keineBerechtigungStg'), self::ERROR_TYPE_GENERAL);
}
}
}
@@ -0,0 +1,32 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
use \DateTime as DateTime;
class NotizProjekt extends Notiz_Controller
{
public function __construct()
{
parent::__construct([
'isBerechtigt' => ['admin:r', 'assistenz:r'],
]);
}
public function isBerechtigt($id, $typeId)
{
if($typeId != "projekt_kurzbz")
{
$this->terminateWithError($this->p->t('ui','error_typeNotizIdIncorrect'), self::ERROR_TYPE_GENERAL);
}
//TODO define permission
if(!$this->permissionlib->isBerechtigt('admin', 'suid') && !$this->permissionlib->isBerechtigt('assistenz', 'suid'))
{
$result = $this->p->t('lehre','error_keineSchreibrechte');
$this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
}
$this->terminateWithSuccess("berechtigt in überschreibender Funktion");
}
}
@@ -0,0 +1,32 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
use \DateTime as DateTime;
class NotizProjektphase extends Notiz_Controller
{
public function __construct()
{
parent::__construct([
'isBerechtigt' => ['admin:r', 'assistenz:r'],
]);
}
public function isBerechtigt($id, $typeId)
{
if($typeId != "projektphase_id")
{
$this->terminateWithError($this->p->t('ui','error_typeNotizIdIncorrect'), self::ERROR_TYPE_GENERAL);
}
//TODO define permission
if(!$this->permissionlib->isBerechtigt('admin', 'suid') && !$this->permissionlib->isBerechtigt('assistenz', 'suid'))
{
$result = $this->p->t('lehre','error_keineSchreibrechte');
$this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
}
$this->terminateWithSuccess("berechtigt in überschreibender Funktion");
}
}
@@ -0,0 +1,32 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
use \DateTime as DateTime;
class NotizProjekttask extends Notiz_Controller
{
public function __construct()
{
parent::__construct([
'isBerechtigt' => ['admin:r', 'assistenz:r'],
]);
}
public function isBerechtigt($id, $typeId)
{
if($typeId != "projekttask_id")
{
$this->terminateWithError($this->p->t('ui','error_typeNotizIdIncorrect'), self::ERROR_TYPE_GENERAL);
}
//TODO define permission
if(!$this->permissionlib->isBerechtigt('admin', 'suid') && !$this->permissionlib->isBerechtigt('assistenz', 'suid'))
{
$result = $this->p->t('lehre','error_keineSchreibrechte');
$this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
}
$this->terminateWithSuccess("berechtigt in überschreibender Funktion");
}
}
@@ -611,7 +611,7 @@ class Students extends FHCAPI_Controller
if (!$verband && !$gruppe && $orgform_kurzbz !== null) {
$this->PrestudentModel->db->where(
"(
SELECT orgform_kurzbz
SELECT orgform_kurzbz
FROM public.tbl_prestudentstatus
WHERE prestudent_id=tbl_prestudent.prestudent_id
AND studiensemester_kurzbz=" . $this->PrestudentModel->escape($studiensemester_kurzbz) . "
@@ -855,6 +855,41 @@ class Students extends FHCAPI_Controller
{
$stdsemEsc = $studiensemester_kurzbz ? $this->PrestudentModel->escape($studiensemester_kurzbz) : 'NULL';
$this->load->config('stv');
$tags = $this->config->item('stv_prestudent_tags');
$whereTags = '';
if (is_array($tags) && !isEmptyArray($tags)) {
$tags = array_keys($tags);
foreach ($tags as $key => $tag) {
$tags[$key] = $this->db->escape($tag);
}
$whereTags = " AND nt.typ_kurzbz IN (" . implode(",", $tags) . ")";
}
$subQueryTag = "
(
SELECT
tag.prestudent_id,
COALESCE(json_agg(tag ORDER BY tag.done), '[]'::json) AS tags
FROM (
SELECT DISTINCT ON (n.notiz_id)
n.notiz_id AS id,
nt.typ_kurzbz,
array_to_json(nt.bezeichnung_mehrsprachig)->>0 AS beschreibung,
n.text AS notiz,
nt.style,
n.erledigt AS done,
nz.prestudent_id
FROM public.tbl_notizzuordnung AS nz
JOIN public.tbl_notiz AS n ON nz.notiz_id = n.notiz_id
JOIN public.tbl_notiz_typ AS nt ON n.typ = nt.typ_kurzbz "
. $whereTags .
"
) AS tag
GROUP BY tag.prestudent_id
) AS tag_data_agg
";
$this->PrestudentModel->addJoin('public.tbl_studiengang stg', 'studiengang_kz', 'LEFT');
$this->PrestudentModel->addJoin('public.tbl_person p', 'person_id');
@@ -877,8 +912,11 @@ class Students extends FHCAPI_Controller
AND ps.studiensemester_kurzbz=public.get_stdsem_prestudent(tbl_prestudent.prestudent_id, ' . $stdsemEsc . ')
AND ps.ausbildungssemester=public.get_absem_prestudent(tbl_prestudent.prestudent_id, ' . $stdsemEsc . ')', 'LEFT');
$this->PrestudentModel->addJoin($subQueryTag, 'tag_data_agg.prestudent_id = tbl_prestudent.prestudent_id', 'LEFT');
$this->PrestudentModel->addSelect("b.uid");
$this->PrestudentModel->addSelect('tag_data_agg.tags');
$this->PrestudentModel->addSelect('titelpre');
$this->PrestudentModel->addSelect('nachname');
$this->PrestudentModel->addSelect('vorname');
@@ -0,0 +1,48 @@
<?php
if (!defined('BASEPATH'))
exit('No direct script access allowed');
class Tags extends Tag_Controller
{
const BERECHTIGUNG_KURZBZ = ['admin:rw', 'assistenz:rw'];
public function __construct()
{
parent::__construct([
'getTag' => self::BERECHTIGUNG_KURZBZ,
'getTags' => self::BERECHTIGUNG_KURZBZ,
'addTag' => self::BERECHTIGUNG_KURZBZ,
'updateTag' => self::BERECHTIGUNG_KURZBZ,
'doneTag' => self::BERECHTIGUNG_KURZBZ,
'deleteTag' => self::BERECHTIGUNG_KURZBZ
]);
$this->config->load('stv');
}
public function getTag($readonly_tags = null)
{
parent::getTag($this->config->item('stv_prestudent_tags'));
}
public function getTags($tags = null)
{
parent::getTags($this->config->item('stv_prestudent_tags'));
}
public function addTag($withZuordnung = true, $updatable_tags = null)
{
parent::addTag(true, $this->config->item('stv_prestudent_tags'));
}
public function updateTag($updatable_tags = null)
{
parent::updateTag($this->config->item('stv_prestudent_tags'));
}
public function deleteTag($withZuordnung = true, $updatable_tags = null)
{
parent::deleteTag(true, $this->config->item('stv_prestudent_tags'));
}
public function doneTag($updatable_tags = null)
{
parent::doneTag($this->config->item('stv_prestudent_tags'));
}
}
+46 -61
View File
@@ -8,7 +8,7 @@ abstract class Notiz_Controller extends FHCAPI_Controller
{
const DEFAULT_PERMISSION_R = 'admin:r';
const DEFAULT_PERMISSION_RW = 'admin:rw';
//public function __construct($zuordnung = 'person/Notizzuordnung_model')
public function __construct($permissions)
{
$default_permissions = [
@@ -97,13 +97,13 @@ abstract class Notiz_Controller extends FHCAPI_Controller
if (isError($result)) {
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
return $this->terminateWithSuccess(getData($result) ?: []);
$this->terminateWithSuccess(getData($result) ?: []);
}
//Override function
protected function isBerechtigt($id, $typeId){
return $this->terminateWithError("in abstract function: define right in extension", self::ERROR_TYPE_GENERAL);
$this->terminateWithError("in abstract function: define right in extension", self::ERROR_TYPE_GENERAL);
}
public function loadNotiz()
@@ -112,7 +112,6 @@ abstract class Notiz_Controller extends FHCAPI_Controller
$notiz_id = $this->input->post('notiz_id');
//$this->load->model('person/Notiz_model', 'NotizModel');
$this->NotizModel->addJoin('public.tbl_notiz_dokument', 'notiz_id', 'LEFT');
$this->NotizModel->addSelect('*');
$this->NotizModel->addSelect("TO_CHAR(CASE WHEN public.tbl_notiz.updateamum >= public.tbl_notiz.insertamum
@@ -143,14 +142,9 @@ abstract class Notiz_Controller extends FHCAPI_Controller
$uid = getAuthUID();
if (isset($_POST['data']))
{
$data = json_decode($_POST['data']);
unset($_POST['data']);
foreach ($data as $k => $v) {
$_POST[$k] = $v;
}
}
$json = $this->input->post('data');
$post_data = json_decode($json, true);
$this->form_validation->set_data($post_data);
//Form Validation
$this->form_validation->set_rules('titel', 'Titel', 'required', [
@@ -166,26 +160,25 @@ abstract class Notiz_Controller extends FHCAPI_Controller
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
$titel = $this->input->post('titel');
$text = $this->input->post('text');
$erledigt = $this->input->post('erledigt');
$verfasser_uid = isset($_POST['verfasser']) ? $_POST['verfasser'] : $uid;
$bearbeiter_uid = isset($_POST['bearbeiter']) ? $_POST['bearbeiter'] : null;
$type = $this->input->post('typeId');
$start = $this->input->post('start');
$ende = $this->input->post('ende');
$titel = $post_data['titel'];
$text = $post_data['text'];
$erledigt = $post_data['erledigt'];
$bearbeiter_uid = isset($post_data['bearbeiter']) ? $post_data['bearbeiter'] : null;
$type = $post_data['typeId'];
$start = isset($post_data['start']) ? $post_data['start'] : null;
$ende = isset($post_data['ende']) ? $post_data['ende'] : null;
// Start DB transaction
$this->db->trans_start();
//Save note
$result = $this->NotizModel->insert(array('titel' => $titel, 'text' => $text, 'erledigt' => $erledigt, 'verfasser_uid' => $verfasser_uid,
"insertvon" => $verfasser_uid, 'start' => $start, 'ende' => $ende, 'bearbeiter_uid' => $bearbeiter_uid));
$result = $this->NotizModel->insert(array('titel' => $titel, 'text' => $text, 'erledigt' => $erledigt, 'verfasser_uid' => $uid,
"insertvon" => $uid, 'start' => $start, 'ende' => $ende, 'bearbeiter_uid' => $bearbeiter_uid));
if (isError($result))
{
$this->db->trans_rollback();
return $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
$notiz_id = $result->retval;
@@ -220,7 +213,7 @@ abstract class Notiz_Controller extends FHCAPI_Controller
if (isError($result))
{
$this->db->trans_rollback();
return $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
$dms_id_arr[] = $result->retval['dms_id'];
}
@@ -235,34 +228,28 @@ abstract class Notiz_Controller extends FHCAPI_Controller
if (isError($result))
{
$this->db->trans_rollback();
return $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
}
}
$this->db->trans_commit();
return $this->terminateWithSuccess($result);
$this->terminateWithSuccess($result);
}
public function updateNotiz()
{
$this->load->library('form_validation');
$this->load->library('DmsLib');
if (isset($_POST['data']))
{
$data = json_decode($_POST['data']);
unset($_POST['data']);
foreach ($data as $k => $v) {
$_POST[$k] = $v;
}
}
$json = $this->input->post('data');
$post_data = json_decode($json, true);
$notiz_id = $this->input->post('notiz_id');
$this->form_validation->set_data($post_data);
if(!$notiz_id)
{
$this->terminateWithError($this->p->t('ui','error_missingId',['id'=>'Notiz_id']), self::ERROR_TYPE_GENERAL);
}
$this->form_validation->set_rules('notiz_id', 'Notiz ID', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'notiz_id'])
]);
//Form Validation
$this->form_validation->set_rules('titel', 'Titel', 'required', [
@@ -280,25 +267,23 @@ abstract class Notiz_Controller extends FHCAPI_Controller
//update Notiz
$uid = getAuthUID();
$titel = $this->input->post('titel');
$text = $this->input->post('text');
$verfasser_uid = isset($_POST['verfasser']) ? $_POST['verfasser'] : $uid;
$bearbeiter_uid = isset($_POST['bearbeiter']) ? $_POST['bearbeiter'] : $uid;
$erledigt = $this->input->post('erledigt');
$start = $this->input->post('start');
$ende = $this->input->post('ende');
$titel = $post_data['titel'];
$text = $post_data['text'];
$bearbeiter_uid = isset($post_data['bearbeiter']) ? $post_data['bearbeiter'] : $post_data['bearbeiter_uid'];
$erledigt = $post_data['erledigt'];
$start = $post_data['start'];
$ende = $post_data['ende'];
$result = $this->NotizModel->update(
[
'notiz_id' => $notiz_id
'notiz_id' => $post_data['notiz_id'],
],
[
'titel' => $titel,
'updatevon' => $uid,
'updateamum' => date('c'),
'text' => $text,
'verfasser_uid' => $verfasser_uid,
'bearbeiter_uid' => $bearbeiter_uid,
'bearbeiter_uid' => isEmptyString($bearbeiter_uid) ? null : $bearbeiter_uid,
'start' => $start,
'ende' => $ende,
'erledigt' => $erledigt
@@ -306,7 +291,7 @@ abstract class Notiz_Controller extends FHCAPI_Controller
);
if (isError($result))
{
return $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
//update(1) loading all dms-entries with this notiz_id
@@ -314,7 +299,7 @@ abstract class Notiz_Controller extends FHCAPI_Controller
$this->load->model('person/Notizdokument_model', 'NotizdokumentModel');
$this->NotizdokumentModel->addJoin('campus.tbl_dms_version', 'dms_id');
$result = $this->NotizdokumentModel->loadWhere(array('notiz_id' => $notiz_id));
$result = $this->NotizdokumentModel->loadWhere(array('notiz_id' => $post_data['notiz_id']));
$result = $this->getDataOrTerminateWithError($result);
foreach ($result as $doc) {
$dms_id_arr[$doc->dms_id] = array(
@@ -351,7 +336,7 @@ abstract class Notiz_Controller extends FHCAPI_Controller
$result = $this->getDataOrTerminateWithError($result);
$dms_id = $result['dms_id'];
$result = $this->NotizdokumentModel->insert(array('notiz_id' => $notiz_id, 'dms_id' => $dms_id));
$result = $this->NotizdokumentModel->insert(array('notiz_id' => $post_data['notiz_id'], 'dms_id' => $dms_id));
$this->getDataOrTerminateWithError($result);
}
@@ -365,7 +350,7 @@ abstract class Notiz_Controller extends FHCAPI_Controller
$this->getDataOrTerminateWithError($result);
}
return $this->terminateWithSuccess($result);
$this->terminateWithSuccess($result);
}
public function deleteNotiz()
@@ -416,15 +401,15 @@ abstract class Notiz_Controller extends FHCAPI_Controller
if (isError($result))
{
$this->db->trans_rollback();
return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
$this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
}
if(!hasData($result))
{
return $this->terminateWithError($this->p->t('ui','error_missingId', ['id'=> 'Notiz_id']), self::ERROR_TYPE_GENERAL);
$this->terminateWithError($this->p->t('ui','error_missingId', ['id'=> 'Notiz_id']), self::ERROR_TYPE_GENERAL);
}
$this->db->trans_complete();
return $this->terminateWithSuccess(getData($result));
$this->terminateWithSuccess(getData($result));
}
public function loadDokumente()
@@ -440,14 +425,14 @@ abstract class Notiz_Controller extends FHCAPI_Controller
array('public.tbl_notiz.notiz_id' => $notiz_id)
);
if (isError($result)) {
return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
$this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
}
if(!hasData($result))
{
return $this->terminateWithError($this->p->t('ui','error_missingId', ['id'=> 'Notiz_id']), self::ERROR_TYPE_GENERAL);
$this->terminateWithError($this->p->t('ui','error_missingId', ['id'=> 'Notiz_id']), self::ERROR_TYPE_GENERAL);
}
return $this->terminateWithSuccess(getData($result));
$this->terminateWithSuccess(getData($result));
}
public function getMitarbeiter($searchString)
@@ -457,7 +442,7 @@ abstract class Notiz_Controller extends FHCAPI_Controller
if (isError($result)) {
$this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
}
return $this->terminateWithSuccess($result);
$this->terminateWithSuccess($result);
}
public function getCountNotes($person_id)
@@ -476,4 +461,4 @@ abstract class Notiz_Controller extends FHCAPI_Controller
return $this->terminateWithSuccess($anzahl->anzahl ?: 0);
}
}
}
+3 -1
View File
@@ -14,12 +14,14 @@
'ui',
'notiz',
),
'tags' => true,
'customCSSs' => [
#datepicker fuer component functions
'public/css/components/vue-datepicker.css',
'public/css/components/primevue.css',
'public/css/Studentenverwaltung.css',
'public/css/components/function.css'
'public/css/components/function.css',
//'public/css/Lvverwaltung.css' //css tags?
],
'customJSs' => [
'vendor/vuejs/vuedatepicker_js/vue-datepicker.iife.js',
+29
View File
@@ -0,0 +1,29 @@
/**
* Copyright (C) 2025 fhcomplete.org
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import Person from './person.js';
export default {
...Person,
getNotizen(id, type) {
return {
method: 'get',
url: 'api/frontend/v1/notiz/notizAnrechnung/getNotizen/' + encodeURIComponent(id) + '/' + encodeURIComponent(type)
};
},
};
+29
View File
@@ -0,0 +1,29 @@
/**
* Copyright (C) 2025 fhcomplete.org
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import Person from './person.js';
export default {
...Person,
getNotizen(id, type) {
return {
method: 'get',
url: 'api/frontend/v1/notiz/notizBestellung/getNotizen/' + encodeURIComponent(id) + '/' + encodeURIComponent(type)
};
},
};
@@ -26,4 +26,29 @@ export default {
url: 'api/frontend/v1/notiz/notizLehreinheit/getNotizen/' + encodeURIComponent(id) + '/' + encodeURIComponent(type)
};
},
addNewNotiz(lehreinheit_id, params) {
return {
method: 'post',
url: 'api/frontend/v1/notiz/notizLehreinheit/addNewNotiz/' + lehreinheit_id,
params
};
},
updateNotiz(notiz_id, params) {
return {
method: 'post',
url: 'api/frontend/v1/notiz/notizLehreinheit/updateNotiz/' + notiz_id,
params
};
},
deleteNotiz(notiz_id, type_id, id) {
return {
method: 'post',
url: 'api/frontend/v1/notiz/notizLehreinheit/deleteNotiz/',
params: {
notiz_id,
type_id,
id
}
};
},
};
@@ -0,0 +1,29 @@
/**
* Copyright (C) 2025 fhcomplete.org
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import Person from './person.js';
export default {
...Person,
getNotizen(id, type) {
return {
method: 'get',
url: 'api/frontend/v1/notiz/notizMitarbeiter/getNotizen/' + encodeURIComponent(id) + '/' + encodeURIComponent(type)
};
},
};
+29
View File
@@ -0,0 +1,29 @@
/**
* Copyright (C) 2025 fhcomplete.org
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import Person from './person.js';
export default {
...Person,
getNotizen(id, type) {
return {
method: 'get',
url: 'api/frontend/v1/notiz/notizPrestudent/getNotizen/' + encodeURIComponent(id) + '/' + encodeURIComponent(type)
};
},
};
+29
View File
@@ -0,0 +1,29 @@
/**
* Copyright (C) 2025 fhcomplete.org
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import Person from './person.js';
export default {
...Person,
getNotizen(id, type) {
return {
method: 'get',
url: 'api/frontend/v1/notiz/notizProjekt/getNotizen/' + encodeURIComponent(id) + '/' + encodeURIComponent(type)
};
},
};
@@ -0,0 +1,29 @@
/**
* Copyright (C) 2025 fhcomplete.org
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import Person from './person.js';
export default {
...Person,
getNotizen(id, type) {
return {
method: 'get',
url: 'api/frontend/v1/notiz/notizProjektphase/getNotizen/' + encodeURIComponent(id) + '/' + encodeURIComponent(type)
};
},
};
@@ -0,0 +1,29 @@
/**
* Copyright (C) 2025 fhcomplete.org
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import Person from './person.js';
export default {
...Person,
getNotizen(id, type) {
return {
method: 'get',
url: 'api/frontend/v1/notiz/notizProjekttask/getNotizen/' + encodeURIComponent(id) + '/' + encodeURIComponent(type)
};
},
};
+54
View File
@@ -0,0 +1,54 @@
export default {
getTag(data)
{
return {
method: 'get',
url: 'api/frontend/v1/stv/Tags/getTag',
params: data
};
},
getTags(data)
{
return {
method: 'get',
url: 'api/frontend/v1/stv/Tags/getTags'
};
},
addTag(data)
{
return {
method: 'post',
url: 'api/frontend/v1/stv/Tags/addTag',
params: data
};
},
updateTag(data)
{
return {
method: 'post',
url: 'api/frontend/v1/stv/Tags/updateTag',
params: data
};
},
doneTag(data)
{
return {
method: 'post',
url: 'api/frontend/v1/stv/Tags/doneTag',
params: data
};
},
deleteTag(data)
{
return {
method: 'post',
url: 'api/frontend/v1/stv/Tags/deleteTag',
params: data
};
},
};
+19 -2
View File
@@ -1,5 +1,22 @@
import person from "./notiz/person.js";
import prestudent from "./notiz/prestudent.js";
import mitarbeiter from "./notiz/mitarbeiter.js";
import projekt from "./notiz/projekt.js";
import anrechnung from "./notiz/anrechnung.js";
import bestellung from "./notiz/bestellung.js";
import lehreinheit from "./notiz/lehreinheit.js";
import projektphase from "./notiz/projektphase.js";
import projekttask from "./notiz/projekttask.js";
export default {
person
}
person,
prestudent,
mitarbeiter,
anrechnung,
bestellung,
lehreinheit,
projekt,
projektphase,
projekttask,
}
+38
View File
@@ -0,0 +1,38 @@
export default {
getNotizen(url, config, params){
return this.$fhcApi.get('api/frontend/v1/notiz/notizAnrechnung/getNotizen/' + params.id + '/' + params.type);
},
getUid(){
return this.$fhcApi.get('api/frontend/v1/notiz/notizAnrechnung/getUid/');
},
addNewNotiz(id, formData) {
return this.$fhcApi.post('api/frontend/v1/notiz/notizAnrechnung/addNewNotiz/' + id,
formData
);
},
loadNotiz(notiz_id){
return this.$fhcApi.post('api/frontend/v1/notiz/notizAnrechnung/loadNotiz/', {
notiz_id
});
},
loadDokumente(notiz_id){
return this.$fhcApi.post('api/frontend/v1/notiz/notizAnrechnung/loadDokumente/', {
notiz_id
});
},
deleteNotiz(notiz_id, type_id, id){
return this.$fhcApi.post('api/frontend/v1/notiz/notizAnrechnung/deleteNotiz/', {
notiz_id,
type_id,
id
});
},
updateNotiz(notiz_id, formData){
return this.$fhcApi.post('api/frontend/v1/notiz/notizAnrechnung/updateNotiz/' + notiz_id,
formData
);
},
getMitarbeiter(event){
return this.$fhcApi.get('api/frontend/v1/notiz/notizAnrechnung/getMitarbeiter/' + event);
}
}
+38
View File
@@ -0,0 +1,38 @@
export default {
getNotizen(url, config, params){
return this.$fhcApi.get('api/frontend/v1/notiz/notizBestellung/getNotizen/' + params.id + '/' + params.type);
},
getUid(){
return this.$fhcApi.get('api/frontend/v1/notiz/notizBestellung/getUid/');
},
addNewNotiz(id, formData) {
return this.$fhcApi.post('api/frontend/v1/notiz/notizBestellung/addNewNotiz/' + id,
formData
);
},
loadNotiz(notiz_id){
return this.$fhcApi.post('api/frontend/v1/notiz/notizBestellung/loadNotiz/', {
notiz_id
});
},
loadDokumente(notiz_id){
return this.$fhcApi.post('api/frontend/v1/notiz/notizBestellung/loadDokumente/', {
notiz_id
});
},
deleteNotiz(notiz_id, type_id, id){
return this.$fhcApi.post('api/frontend/v1/notiz/notizBestellung/deleteNotiz/', {
notiz_id,
type_id,
id
});
},
updateNotiz(notiz_id, formData){
return this.$fhcApi.post('api/frontend/v1/notiz/notizBestellung/updateNotiz/' + notiz_id,
formData
);
},
getMitarbeiter(event){
return this.$fhcApi.get('api/frontend/v1/notiz/notizBestellung/getMitarbeiter/' + event);
}
}
+38
View File
@@ -0,0 +1,38 @@
export default {
getNotizen(url, config, params){
return this.$fhcApi.get('api/frontend/v1/notiz/notizLehreinheit/getNotizen/' + params.id + '/' + params.type);
},
getUid(){
return this.$fhcApi.get('api/frontend/v1/notiz/notizLehreinheit/getUid/');
},
addNewNotiz(id, formData) {
return this.$fhcApi.post('api/frontend/v1/notiz/notizLehreinheit/addNewNotiz/' + id,
formData
);
},
loadNotiz(notiz_id){
return this.$fhcApi.post('api/frontend/v1/notiz/notizLehreinheit/loadNotiz/', {
notiz_id
});
},
loadDokumente(notiz_id){
return this.$fhcApi.post('api/frontend/v1/notiz/notizLehreinheit/loadDokumente/', {
notiz_id
});
},
deleteNotiz(notiz_id, type_id, id){
return this.$fhcApi.post('api/frontend/v1/notiz/notizLehreinheit/deleteNotiz/', {
notiz_id,
type_id,
id
});
},
updateNotiz(notiz_id, formData){
return this.$fhcApi.post('api/frontend/v1/notiz/notizLehreinheit/updateNotiz/' + notiz_id,
formData
);
},
getMitarbeiter(event){
return this.$fhcApi.get('api/frontend/v1/notiz/notizLehreinheit/getMitarbeiter/' + event);
}
}
+38
View File
@@ -0,0 +1,38 @@
export default {
getNotizen(url, config, params){
return this.$fhcApi.get('api/frontend/v1/notiz/notizMitarbeiter/getNotizen/' + params.id + '/' + params.type);
},
getUid(){
return this.$fhcApi.get('api/frontend/v1/notiz/notizMitarbeiter/getUid/');
},
addNewNotiz(id, formData) {
return this.$fhcApi.post('api/frontend/v1/notiz/notizMitarbeiter/addNewNotiz/' + id,
formData
);
},
loadNotiz(notiz_id){
return this.$fhcApi.post('api/frontend/v1/notiz/notizMitarbeiter/loadNotiz/', {
notiz_id
});
},
loadDokumente(notiz_id){
return this.$fhcApi.post('api/frontend/v1/notiz/notizMitarbeiter/loadDokumente/', {
notiz_id
});
},
deleteNotiz(notiz_id, type_id, id){
return this.$fhcApi.post('api/frontend/v1/notiz/notizMitarbeiter/deleteNotiz/', {
notiz_id,
type_id,
id
});
},
updateNotiz(notiz_id, formData){
return this.$fhcApi.post('api/frontend/v1/notiz/notizMitarbeiter/updateNotiz/' + notiz_id,
formData
);
},
getMitarbeiter(event){
return this.$fhcApi.get('api/frontend/v1/notiz/notizMitarbeiter/getMitarbeiter/' + event);
}
}
+1 -1
View File
@@ -38,4 +38,4 @@ export default {
isBerechtigt(id, type_id){
return this.$fhcApi.get('api/frontend/v1/notiz/notizPerson/isBerechtigt/');
}
}
}
+38
View File
@@ -0,0 +1,38 @@
export default {
getNotizen(url, config, params){
return this.$fhcApi.get('api/frontend/v1/notiz/notizPrestudent/getNotizen/' + params.id + '/' + params.type);
},
getUid(){
return this.$fhcApi.get('api/frontend/v1/notiz/notizPrestudent/getUid/');
},
addNewNotiz(id, formData) {
return this.$fhcApi.post('api/frontend/v1/notiz/notizPrestudent/addNewNotiz/' + id,
formData
);
},
loadNotiz(notiz_id){
return this.$fhcApi.post('api/frontend/v1/notiz/notizPrestudent/loadNotiz/', {
notiz_id
});
},
loadDokumente(notiz_id){
return this.$fhcApi.post('api/frontend/v1/notiz/notizPrestudent/loadDokumente/', {
notiz_id
});
},
deleteNotiz(notiz_id, type_id, id){
return this.$fhcApi.post('api/frontend/v1/notiz/notizPrestudent/deleteNotiz/', {
notiz_id,
type_id,
id
});
},
updateNotiz(notiz_id, formData){
return this.$fhcApi.post('api/frontend/v1/notiz/notizPrestudent/updateNotiz/' + notiz_id,
formData
);
},
getMitarbeiter(event){
return this.$fhcApi.get('api/frontend/v1/notiz/notizPrestudent/getMitarbeiter/' + event);
}
}
+38
View File
@@ -0,0 +1,38 @@
export default {
getNotizen(url, config, params){
return this.$fhcApi.get('api/frontend/v1/notiz/NotizProjekt/getNotizen/' + params.id + '/' + params.type);
},
getUid(){
return this.$fhcApi.get('api/frontend/v1/notiz/NotizProjekt/getUid/');
},
addNewNotiz(id, formData) {
return this.$fhcApi.post('api/frontend/v1/notiz/NotizProjekt/addNewNotiz/' + id,
formData
);
},
loadNotiz(notiz_id){
return this.$fhcApi.post('api/frontend/v1/notiz/NotizProjekt/loadNotiz/', {
notiz_id
});
},
loadDokumente(notiz_id){
return this.$fhcApi.post('api/frontend/v1/notiz/NotizProjekt/loadDokumente/', {
notiz_id
});
},
deleteNotiz(notiz_id, type_id, id){
return this.$fhcApi.post('api/frontend/v1/notiz/NotizProjekt/deleteNotiz/', {
notiz_id,
type_id,
id
});
},
updateNotiz(notiz_id, formData){
return this.$fhcApi.post('api/frontend/v1/notiz/NotizProjekt/updateNotiz/' + notiz_id,
formData
);
},
getMitarbeiter(event){
return this.$fhcApi.get('api/frontend/v1/notiz/NotizProjekt/getMitarbeiter/' + event);
}
}
+38
View File
@@ -0,0 +1,38 @@
export default {
getNotizen(url, config, params){
return this.$fhcApi.get('api/frontend/v1/notiz/notizProjektphase/getNotizen/' + params.id + '/' + params.type);
},
getUid(){
return this.$fhcApi.get('api/frontend/v1/notiz/notizProjektphase/getUid/');
},
addNewNotiz(id, formData) {
return this.$fhcApi.post('api/frontend/v1/notiz/notizProjektphase/addNewNotiz/' + id,
formData
);
},
loadNotiz(notiz_id){
return this.$fhcApi.post('api/frontend/v1/notiz/notizProjektphase/loadNotiz/', {
notiz_id
});
},
loadDokumente(notiz_id){
return this.$fhcApi.post('api/frontend/v1/notiz/notizProjektphase/loadDokumente/', {
notiz_id
});
},
deleteNotiz(notiz_id, type_id, id){
return this.$fhcApi.post('api/frontend/v1/notiz/notizProjektphase/deleteNotiz/', {
notiz_id,
type_id,
id
});
},
updateNotiz(notiz_id, formData){
return this.$fhcApi.post('api/frontend/v1/notiz/notizProjektphase/updateNotiz/' + notiz_id,
formData
);
},
getMitarbeiter(event){
return this.$fhcApi.get('api/frontend/v1/notiz/notizProjektphase/getMitarbeiter/' + event);
}
}
+38
View File
@@ -0,0 +1,38 @@
export default {
getNotizen(url, config, params){
return this.$fhcApi.get('api/frontend/v1/notiz/notizProjekttask/getNotizen/' + params.id + '/' + params.type);
},
getUid(){
return this.$fhcApi.get('api/frontend/v1/notiz/notizProjekttask/getUid/');
},
addNewNotiz(id, formData) {
return this.$fhcApi.post('api/frontend/v1/notiz/notizProjekttask/addNewNotiz/' + id,
formData
);
},
loadNotiz(notiz_id){
return this.$fhcApi.post('api/frontend/v1/notiz/notizProjekttask/loadNotiz/', {
notiz_id
});
},
loadDokumente(notiz_id){
return this.$fhcApi.post('api/frontend/v1/notiz/notizProjekttask/loadDokumente/', {
notiz_id
});
},
deleteNotiz(notiz_id, type_id, id){
return this.$fhcApi.post('api/frontend/v1/notiz/notizProjekttask/deleteNotiz/', {
notiz_id,
type_id,
id
});
},
updateNotiz(notiz_id, formData){
return this.$fhcApi.post('api/frontend/v1/notiz/notizProjekttask/updateNotiz/' + notiz_id,
formData
);
},
getMitarbeiter(event){
return this.$fhcApi.get('api/frontend/v1/notiz/notizProjekttask/getMitarbeiter/' + event);
}
}
+10 -161
View File
@@ -4,6 +4,8 @@ import DetailsForm from "../Details/Form.js";
import CoreTag from '../../Tag/Tag.js';
import { tagHeaderFilter } from '../../../../js/tabulator/filters/extendedHeaderFilter.js';
import { extendedHeaderFilter } from "../../../../js/tabulator/filters/extendedHeaderFilter.js";
import { tagFormatter } from "../../../../js/tabulator/formatter/tags.js";
import { addTagInTable, deleteTagInTable, updateTagInTable } from "../../../../js/helpers/TagHelper.js";
import ApiLv from "../../../api/lehrveranstaltung.js";
import ApiTag from "../../../api/lehrveranstaltung/tag.js";
@@ -223,72 +225,7 @@ export default {
headerFilter: "input",
headerFilterFunc: tagHeaderFilter,
headerFilterFuncParams: {field: 'tags'},
formatter: (cell) => {
let tags = cell.getValue();
if (!tags) return;
let container = document.createElement('div');
container.className = "d-flex gap-1";
let parsedTags = JSON.parse(tags);
let maxVisibleTags = 2;
const rowData = cell.getRow().getData();
if (rowData._tagExpanded === undefined) {
rowData._tagExpanded = false;
}
const renderTags = () => {
container.innerHTML = '';
parsedTags = parsedTags.filter(item => item !== null);
parsedTags.sort((a, b) => {
let adone = a.done ? 1 : 0;
let bbone = b.done ? 1 : 0;
if (adone !== bbone)
{
return adone - bbone;
}
return b.id - a.id;
});
const tagsToShow = rowData._tagExpanded ? parsedTags : parsedTags.slice(0, maxVisibleTags);
tagsToShow.forEach(tag => {
if (!tag) return;
let tagElement = document.createElement('span');
tagElement.innerText = tag.beschreibung;
tagElement.title = tag.notiz;
tagElement.className = "tag " + tag.style;
if (tag.done) tagElement.className += " tag_done";
tagElement.addEventListener('click', (event) => {
event.stopPropagation();
event.preventDefault();
this.$refs.tagComponent.editTag(tag.id);
});
container.appendChild(tagElement);
});
if (parsedTags.length > maxVisibleTags) {
let toggle = document.createElement('button');
toggle.innerText = (rowData._tagExpanded ? '- ' : '+ ') + (parsedTags.length - maxVisibleTags);
toggle.className = "display_all";
toggle.title = rowData._tagExpanded ? "Tags ausblenden" : "Tags einblenden";
toggle.addEventListener('click', () => {
rowData._tagExpanded = !rowData._tagExpanded;
renderTags();
});
container.appendChild(toggle);
}
};
renderTags();
return container;
},
formatter: (cell) => tagFormatter(cell, this.$refs.tagComponent),
width: 150,
},
{
@@ -444,104 +381,16 @@ export default {
},
addedTag(addedTag)
{
const table = this.$refs.table.tabulator;
this.selectedRows.forEach(row =>
{
if (Array.isArray(addedTag.response))
{
addedTag.response.forEach(tag => {
const targetRow = this.allRows.find(row => row.getData().lehreinheit_id === tag.lehreinheit_id);
if (targetRow)
{
const rowData = targetRow.getData();
let tags = [];
try {
tags = JSON.parse(rowData.tags || '[]');
} catch (e) {}
const tagExists = tags.some((t) => t.id === tag.id);
if (!tagExists)
{
addedTag.id = tag.id;
tags.unshift({ ...addedTag });
targetRow.update({ tags: JSON.stringify(tags) });
targetRow.reformat();
}
}
});
}
});
addTagInTable(addedTag, this.allRows, 'lehreinheit_id')
},
deletedTag(deletedTag) {
const targetRow = this.allRows.find(row => {
const rowData = row.getData();
let tags = [];
try {
tags = JSON.parse(rowData.tags || '[]');
} catch (e) {}
return tags.some(tag => tag.id === deletedTag);
});
if (targetRow) {
const rowData = targetRow.getData();
let tags = [];
try {
tags = JSON.parse(rowData.tags || '[]');
} catch (e) {}
const filteredTags = tags.filter(t => t.id !== deletedTag);
const updatedTags = JSON.stringify(filteredTags);
if (updatedTags !== rowData.tags) {
targetRow.update({
tags: updatedTags
});
targetRow.reformat();
}
}
deletedTag(deletedTag)
{
deleteTagInTable(deletedTag, this.allRows);
},
updatedTag(updatedTag) {
const targetRow = this.allRows.find(row => {
const rowData = row.getData();
let tags = [];
try {
tags = JSON.parse(rowData.tags || '[]');
} catch (e) {}
return tags.some(t => t?.id === updatedTag.id);
});
if (targetRow)
{
const rowData = targetRow.getData();
let tags = [];
try {
tags = JSON.parse(rowData.tags || '[]');
} catch (e) {}
let changed = false;
const tagIndex = tags.findIndex(tag => tag?.id === updatedTag.id);
if (tagIndex !== -1) {
tags[tagIndex] = { ...updatedTag };
changed = true;
}
if (changed)
{
targetRow.update({
tags: JSON.stringify(tags),
});
targetRow.reformat();
}
}
updatedTag(updatedTag)
{
updateTagInTable(updatedTag, this.allRows);
},
async copyLehreinheit(row, art)
{
+49 -84
View File
@@ -1,5 +1,4 @@
import VueDatePicker from '../vueDatepicker.js.php';
import PvAutoComplete from "../../../../index.ci.php/public/js/components/primevue/autocomplete/autocomplete.esm.min.js";
import FormUploadDms from '../Form/Upload/Dms.js';
import {CoreFilterCmpt} from "../filter/Filter.js";
import BsModal from "../Bootstrap/Modal.js";
@@ -11,7 +10,6 @@ export default {
components: {
CoreFilterCmpt,
VueDatePicker,
PvAutoComplete,
FormUploadDms,
FormForm,
FormInput,
@@ -281,6 +279,7 @@ export default {
editor: null,
notizData: {
typeId: this.typeId,
id: this.id,
titel: null,
statusNew: true,
text: '',
@@ -307,7 +306,8 @@ export default {
showType_id: false,
showId: false,
showLastupdate: false
}
},
currentVerfasserUid: null
}
},
methods: {
@@ -335,8 +335,6 @@ export default {
this.notizData.bis = this.notizen.ende;
this.notizData.document = this.notizen.dms_id;
this.notizData.erledigt = this.notizen.erledigt;
this.notizData.verfasser = this.notizen.verfasser_uid;
this.notizData.intVerfasser = this.notizen.verfasser_uid;
this.notizData.intBearbeiter = this.notizen.bearbeiter_uid;
this.notizData.bearbeiter = this.notizen.bearbeiter_uid;
}
@@ -359,6 +357,7 @@ export default {
},
addNewNotiz() {
const formData = new FormData();
this.notizData.id = this.id;
formData.append('data', JSON.stringify(this.notizData));
Object.entries(this.notizData.anhang).forEach(([k, v]) => formData.append(k, v));
@@ -402,6 +401,7 @@ export default {
this.notizData = result.data;
this.notizData.typeId = this.typeId;
this.notizData.anhang = [];
this.currentVerfasserUid = result.data.verfasser_uid;
return result;
})
.catch(this.$fhcAlert.handleSystemError);
@@ -455,16 +455,17 @@ export default {
bis: null,
document: null,
erledigt: false,
verfasser: this.uid,
bearbeiter: null,
anhang: []
anhang: [],
};
this.currentVerfasserUid = this.uid
},
getUid() {
return this.$api
.call(this.endpoint.getUid())
.then(result => {
this.notizData.intVerfasser = result.data;
this.currentVerfasserUid = result.data;
this.uid = result.data;
})
.catch(this.$fhcAlert.handleSystemError);
},
@@ -547,14 +548,7 @@ export default {
},
deep: true
},
'notizData.intVerfasser': {
handler(newVal) {
if (typeof newVal === 'object') {
this.notizData.verfasser = newVal.mitarbeiter_uid;
}
},
deep: true
},
id() {
this.reload();
}
@@ -654,24 +648,23 @@ export default {
<div class="row mb-3">
<label for="bis" class="form-label col-sm-2">{{$p.t('notiz','verfasser')}}</label>
<div v-if="notizData.verfasser_uid" class="col-sm-3">
<input type="text" :readonly="readonly" class="form-control" id="name" v-model="notizData.verfasser_uid">
</div>
<div v-else class="col-sm-3">
<PvAutoComplete v-model="notizData.intVerfasser" optionLabel="mitarbeiter" :suggestions="filteredMitarbeiter" @complete="search" minLength="3"/>
<div class="col-sm-3">
<input type="text" readonly="readonly" class="form-control" id="name" v-model="currentVerfasserUid">
</div>
<label for="von" class="form-label col-sm-1">{{$p.t('global','gueltigVon')}}</label>
<div class="col-sm-3">
<vue-date-picker
id="von"
v-model="notizData.start"
clearable="false"
<form-input
type="DatePicker"
v-model="notizData['start']"
name="von"
auto-apply
:enable-time-picker="false"
format="dd.MM.yyyy"
preview-format="dd.MM.yyyy"
:teleport="true"
preview-format="dd.MM.yyyy"></vue-date-picker>
>
</form-input>
</div>
</div>
@@ -679,26 +672,35 @@ export default {
<label for="bis" class="form-label col-sm-2">{{$p.t('notiz','bearbeiter')}}</label>
<div v-if="notizData.bearbeiter_uid" class="col-sm-3">
<input type="text" :readonly="readonly" class="form-control" id="name" v-model="notizData.bearbeiter_uid">
<input type="text" class="form-control" id="name" v-model="notizData.bearbeiter_uid">
</div>
<div v-else class="col-sm-3">
<PvAutoComplete v-model="notizData.intBearbeiter" optionLabel="mitarbeiter" :suggestions="filteredMitarbeiter" @complete="search" minlength="3"/>
<form-input
type="autocomplete"
v-model="notizData.intBearbeiter"
:suggestions="filteredMitarbeiter"
@complete="search"
optionLabel="mitarbeiter"
minlength="3"
>
</form-input>
</div>
<label for="bis" class="form-label col-sm-1">{{$p.t('global','gueltigBis')}}</label>
<div class="col-sm-3">
<vue-date-picker
id="bis"
<form-input
type="DatePicker"
v-model="notizData.ende"
clearable="false"
name="bis"
auto-apply
:enable-time-picker="false"
format="dd.MM.yyyy"
preview-format="dd.MM.yyyy"
:teleport="true"
preview-format="dd.MM.yyyy">
</vue-date-picker>
>
</form-input>
</div>
</div>
@@ -842,28 +844,15 @@ export default {
<div class="row mb-3">
<form-input
v-if="notizData.verfasser_uid"
container-class="col-6"
:label="$p.t('notiz', 'verfasser')"
type="text"
v-model="notizData.verfasser_uid"
name="titel"
readonly="readonly"
v-model="currentVerfasserUid"
name="verfasser"
>
</form-input>
<form-input
v-else
container-class="col-6"
:label="$p.t('notiz', 'verfasser')"
type="autocomplete"
v-model="notizData.intVerfasser"
:suggestions="filteredMitarbeiter"
@complete="search"
optionLabel="mitarbeiter"
minLength="3"
>
</form-input>
<form-input
v-if="notizData.bearbeiter_uid"
container-class="col-6"
@@ -1008,25 +997,12 @@ export default {
<div class="row mb-3">
<form-input
v-if="notizData.verfasser_uid"
container-class="col-6"
:label="$p.t('notiz', 'verfasser')"
type="text"
v-model="notizData.verfasser_uid"
name="titel"
>
</form-input>
<form-input
v-else
container-class="col-6"
:label="$p.t('notiz', 'verfasser')"
type="autocomplete"
v-model="notizData.intVerfasser"
:suggestions="filteredMitarbeiter"
@complete="search"
optionLabel="mitarbeiter"
minLength="3"
readonly="readonly"
v-model="currentVerfasserUid"
name="verfasser"
>
</form-input>
@@ -1195,33 +1171,21 @@ export default {
<div class="row mb-3">
<form-input
v-if="notizData.verfasser_uid"
container-class="col-6"
:label="$p.t('notiz', 'verfasser')"
type="text"
v-model="notizData.verfasser_uid"
name="titel"
readonly="readonly"
v-model="currentVerfasserUid"
name="verfasser"
>
</form-input>
<form-input
v-else
container-class="col-6"
:label="$p.t('notiz', 'verfasser')"
type="autocomplete"
v-model="notizData.intVerfasser"
:suggestions="filteredMitarbeiter"
@complete="search"
optionLabel="mitarbeiter"
minLength="3"
>
</form-input>
<form-input
v-if="notizData.bearbeiter_uid"
container-class="col-6"
:label="$p.t('notiz', 'bearbeiter')"
v-model="notizData.bearbeiter_uid"
name="bearbeiter"
minlength="3"
>
</form-input>
@@ -1235,6 +1199,7 @@ export default {
:suggestions="filteredMitarbeiter"
@complete="search"
optionLabel="mitarbeiter"
name="bearbeiter"
minlength="3"
>
</form-input>
@@ -1292,4 +1257,4 @@ export default {
<p v-else>Kein Layout übergeben</p>
</div>
</div>`,
}
}
@@ -17,7 +17,6 @@ export default {
},
template: `
<div class="stv-details-notizen h-100 pb-3">
<!-- Test Version classicFas for enter with one click vs popupModal-->
<core-notiz
@@ -76,7 +75,6 @@ visibleColumns: list, which fields shoult be showed as default in filter compone
------------------------ SOME TESTDATA -----------------------------------------------------
---------------------------------------------------------------------------------------------
<core-notiz
:endpoint="$fhcApi.factory.notiz.mitarbeiter"
ref="formc"
@@ -114,8 +112,9 @@ visibleColumns: list, which fields shoult be showed as default in filter compone
:showTinyMCE="true"
:visible-columns="['titel','text','verfasser','bearbeiter','dokumente']"
>
</core-notiz>-->
</core-notiz>
-->
</div>
`
};
};
@@ -1,5 +1,11 @@
import {CoreFilterCmpt} from "../../filter/Filter.js";
import ListNew from './List/New.js';
import CoreTag from '../../Tag/Tag.js';
import { tagHeaderFilter } from "../../../tabulator/filters/extendedHeaderFilter.js";
import { addTagInTable, deleteTagInTable, updateTagInTable } from "../../../../js/helpers/TagHelper.js";
import { tagFormatter } from "../../../../js/tabulator/formatter/tags.js";
//import { extendedHeaderFilter } from "../../../tabulator/filters/extendedHeaderFilter.js";
import ApiTag from "../../../api/factory/stv/tag.js";
import ListFilter from './List/Filter.js';
import { capitalize } from '../../../helpers/StringHelpers.js';
@@ -11,6 +17,7 @@ export default {
components: {
CoreFilterCmpt,
ListNew,
CoreTag,
ListFilter
},
directives: {
@@ -57,6 +64,16 @@ export default {
columns:[
{title:"UID", field:"uid", headerFilter: true},
{title:"TitelPre", field:"titelpre", headerFilter: "list", headerFilterParams: {valuesLookup:true, listOnEmpty:true, autocomplete:true, sort:"asc"}},
{
title: 'Tags',
field: 'tags',
tooltip: false,
headerFilter: "input",
headerFilterFunc: tagHeaderFilter,
headerFilterFuncParams: {field: 'tags'},
formatter: (cell) => tagFormatter(cell, this.$refs.tagComponent),
width: 150,
},
{title:"Nachname", field:"nachname", headerFilter: true},
{title:"Vorname", field:"vorname", headerFilter: true},
{title:"Wahlname", field:"wahlname", visible:false, headerFilter: true},
@@ -157,7 +174,7 @@ export default {
selectable: true,
selectableRangeMode: 'click',
index: 'prestudent_id',
persistenceID: 'stv-list'
persistenceID: 'stv-list',
},
tabulatorEvents: [
{
@@ -166,7 +183,10 @@ export default {
},
{
event: 'dataProcessed',
handler: this.autoSelectRows
handler: (data) => {
this.getAllRows()
this.autoSelectRows(data)
}
},
{
event: 'dataLoaded',
@@ -179,6 +199,18 @@ export default {
{
event: 'rowClick',
handler: this.handleRowClick // TODO(chris): this should be in the filter component
},
{
event: 'dataTreeRowExpanded',
handler: (data) => {
this.getExpandedRows()
}
},
{
event: 'dataTreeRowCollapsed',
handler: (data) => {
this.getExpandedRows()
}
}
],
focusObj: null, // TODO(chris): this should be in the filter component
@@ -187,6 +219,10 @@ export default {
count: 0,
filteredcount: 0,
selectedcount: 0,
//tags
expanded: [],
selectedColumnValues: [],
tagEndpoint: ApiTag,
currentEndpoint: null
}
},
@@ -327,6 +363,11 @@ export default {
rowSelectionChanged(data, rows) {
this.selectedcount = data.length;
this.lastSelected = this.selected;
//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);
// set selected elements draggable
@@ -339,7 +380,7 @@ export default {
rows.forEach(row => row.getElement().draggable = true);
},
autoSelectRows(data) {
if (this.lastSelected) {
if (Array.isArray(this.lastSelected) && this.lastSelected.length){
// NOTE(chris): reselect rows on refresh
let selected = this.lastSelected.map(el => this.$refs.table.tabulator.getRow(el.prestudent_id))
// TODO(chris): unselect current item if it's no longer in the table?
@@ -348,7 +389,7 @@ export default {
if (selected.length)
this.$refs.table.tabulator.selectRow(selected);
} else if(this.lastSelected === undefined) {
} else if(data && this.lastSelected === undefined) {
// NOTE(chris): select row if it's the only one (preferably only on startup)
if (data.length == 1) {
this.$refs.table.tabulator.selectRow(this.$refs.table.tabulator.getRows());
@@ -471,7 +512,24 @@ export default {
if (el != this.focusObj)
this.changeFocus(this.focusObj, el);
}
}
},
//methods tags
addedTag(addedTag)
{
addTagInTable(addedTag, this.allRows, 'prestudent_id')
},
deletedTag(deletedTag)
{
deleteTagInTable(deletedTag, this.allRows);
},
updatedTag(updatedTag)
{
updateTagInTable(updatedTag, this.allRows)
},
getAllRows() {
this.allRows = this.$refs.table.tabulator.getRows();
},
},
// TODO(chris): focusin, focusout, keydown and tabindex should be in the filter component
// TODO(chris): filter component column chooser has no accessibilty features
@@ -500,6 +558,18 @@ export default {
@click:new="actionNewPrestudent"
@table-built="translateTabulator"
>
<template #actions>
<core-tag ref="tagComponent"
:endpoint="tagEndpoint"
:values="selectedColumnValues"
@added="addedTag"
@deleted="deletedTag"
@updated="updatedTag"
zuordnung_typ="prestudent_id"
></core-tag>
</template>
<template #filter>
<div class="card">
<div class="card-body">
+3 -1
View File
@@ -238,6 +238,8 @@ export default {
field="notiz"
:readonly="tagData.readonly"
placeholder="Notiz..."
@keyup.stop=""
@keydown.stop=""
></form-input>
<button
type="button"
@@ -277,4 +279,4 @@ export default {
</div>
</template>
</bs-modal>`,
}
}
+124
View File
@@ -0,0 +1,124 @@
export function addTagInTable(addedTag, rows, matchKey, tagsKey = "tags")
{
if (!addedTag || !Array.isArray(addedTag.response))
return;
rows.forEach(row =>
{
const rowData = row.getData();
let updated = false;
addedTag.response.forEach(tag =>
{
if (rowData[matchKey] !== tag[matchKey])
return;
let tags;
try {
tags = JSON.parse(rowData[tagsKey] || "[]");
} catch (e) {
tags = [];
}
if (!Array.isArray(tags))
tags = [];
if (tags.some(t => t?.id === tag.id))
return;
let newTag = { ...addedTag, id: tag.id };
tags.unshift(newTag);
rowData[tagsKey] = JSON.stringify(tags);
updated = true;
});
if (updated)
row.update(rowData);
});
}
export function deleteTagInTable(deletedTag, rows, tagsKeys = ['tags'])
{
if (!Array.isArray(tagsKeys))
tagsKeys = [tagsKeys];
rows.forEach(row => {
let rowData = row.getData();
let updates = {};
let changed = false;
tagsKeys.forEach(key => {
let tags;
try {
tags = JSON.parse(rowData[key] || "[]");
} catch (e) {
tags = [];
}
if (!Array.isArray(tags))
return;
let filtered = tags.filter(tag => tag?.id !== deletedTag);
if (filtered.length !== tags.length)
{
updates[key] = JSON.stringify(filtered);
changed = true;
}
});
if (changed) {
row.update(updates);
row.reformat();
}
});
}
export function updateTagInTable(updatedTag, rows, fields = ['tags'])
{
if (!Array.isArray(fields))
fields = [fields];
rows.forEach(row =>
{
const rowData = row.getData();
let updated = false;
fields.forEach(field =>
{
if (!rowData[field])
return;
let fieldData;
try {
fieldData = JSON.parse(rowData[field] || "[]");
} catch (e) {
return;
}
if (!Array.isArray(fieldData))
return;
let index = fieldData.findIndex(tag => tag?.id === updatedTag.id);
if (index !== -1)
{
fieldData[index] = { ...updatedTag };
let updatedFieldData = JSON.stringify(fieldData);
if (updatedFieldData !== rowData[field])
{
rowData[field] = updatedFieldData;
updated = true;
}
}
});
if (updated)
row.update(rowData);
});
}
@@ -146,7 +146,7 @@ export function tagHeaderFilter(headerValue, rowValue, rowData, filterParams)
if (Array.isArray(data))
{
combinedText = data
.filter(item => item?.done === false)
.filter(item => item?.done !== true)
.map(item => `${item?.beschreibung} ${item?.notiz}`)
.join(' ');
}
+67
View File
@@ -0,0 +1,67 @@
export function tagFormatter(cell, tagComponent)
{
let tags = cell.getValue();
if (!tags) return;
let container = document.createElement('div');
container.className = "d-flex gap-1";
let parsedTags = JSON.parse(tags);
let maxVisibleTags = 2;
const rowData = cell.getRow().getData();
if (rowData._tagExpanded === undefined) {
rowData._tagExpanded = false;
}
const renderTags = () => {
container.innerHTML = '';
parsedTags = parsedTags.filter(item => item !== null);
parsedTags.sort((a, b) => {
let adone = a.done ? 1 : 0;
let bbone = b.done ? 1 : 0;
if (adone !== bbone)
{
return adone - bbone;
}
return b.id - a.id;
});
const tagsToShow = rowData._tagExpanded ? parsedTags : parsedTags.slice(0, maxVisibleTags);
tagsToShow.forEach(tag => {
if (!tag) return;
let tagElement = document.createElement('span');
tagElement.innerText = tag.beschreibung;
tagElement.title = tag.notiz;
tagElement.className = "tag " + tag.style;
if (tag.done) tagElement.className += " tag_done";
tagElement.addEventListener('click', (event) => {
event.stopPropagation();
event.preventDefault();
tagComponent.editTag(tag.id);
});
container.appendChild(tagElement);
});
if (parsedTags.length > maxVisibleTags) {
let toggle = document.createElement('button');
toggle.innerText = (rowData._tagExpanded ? '- ' : '+ ') + (parsedTags.length - maxVisibleTags);
toggle.className = "display_all";
toggle.title = rowData._tagExpanded ? "Tags ausblenden" : "Tags einblenden";
toggle.addEventListener('click', () => {
rowData._tagExpanded = !rowData._tagExpanded;
renderTags();
});
container.appendChild(toggle);
}
};
renderTags();
return container;
}
+21
View File
@@ -26071,6 +26071,27 @@ array(
)
)
),
//**************************** FHC-Core-Notizcomponent
array(
'app' => 'core',
'category' => 'ui',
'phrase' => 'error_typeNotizIdIncorrect',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Id-Typ der Notiz ist nicht korrekt',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Id type of note is incorrect',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'ui',