mirror of
https://github.com/FH-Complete/FHC-Core.git
synced 2026-10-24 12:46:16 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
99445d2372 | ||
|
|
0ab6e3d00d | ||
|
|
385b262be8 | ||
|
|
b4206e1e48 | ||
|
|
e09555908a | ||
|
|
38060c60fb | ||
|
|
40516b34a2 | ||
|
|
ea97e3a192 | ||
|
|
f34481ae60 | ||
|
|
fcf3cbac6c | ||
|
|
40b28b88b9 | ||
|
|
11f2f0ad75 | ||
|
|
4abe6f0d24 | ||
|
|
9fbbd6b855 | ||
|
|
60b2c89c66 |
@@ -198,7 +198,7 @@ class Grades extends FHCAPI_Controller
|
||||
$now = date('c');
|
||||
|
||||
// NOTE(chris): Stg Permissions
|
||||
if (!$this->hasPermissionGradeUID($lehrveranstaltung_id, $student_uid))
|
||||
if (!$this->hasPermissionUpdate($lehrveranstaltung_id, $student_uid))
|
||||
return $this->_outputAuthError([$this->router->method => ['admin', 'assistenz']]);
|
||||
|
||||
$this->load->model('education/Zeugnisnote_model', 'ZeugnisnoteModel');
|
||||
@@ -260,7 +260,7 @@ class Grades extends FHCAPI_Controller
|
||||
$lehrveranstaltung_id = $this->input->post('lehrveranstaltung_id');
|
||||
|
||||
// NOTE(chris): Stg Permissions
|
||||
if (!$this->hasPermissionGradeUID($lehrveranstaltung_id, $student_uid))
|
||||
if (!$this->hasPermissionDelete($lehrveranstaltung_id, $student_uid))
|
||||
return $this->_outputAuthError([$this->router->method => ['admin', 'assistenz']]);
|
||||
|
||||
$this->load->model('education/Zeugnisnote_model', 'ZeugnisnoteModel');
|
||||
@@ -298,7 +298,7 @@ class Grades extends FHCAPI_Controller
|
||||
$authUID = getAuthUID();
|
||||
|
||||
// NOTE(chris): Stg Permissions
|
||||
if (!$this->hasPermissionGradeUID($lehrveranstaltung_id, $student_uid))
|
||||
if (!$this->hasPermissionCopy($lehrveranstaltung_id, $student_uid))
|
||||
return $this->_outputAuthError([$this->router->method => 'student/noten']);
|
||||
|
||||
$this->load->model('education/Lvgesamtnote_model', 'LvgesamtnoteModel');
|
||||
@@ -410,7 +410,7 @@ class Grades extends FHCAPI_Controller
|
||||
$repeaterGrade = current($repeaterGrade);
|
||||
|
||||
// NOTE(chris): Stg Permissions
|
||||
if (!$this->hasPermissionGradeUID($repeaterGrade->lehrveranstaltung_id, $repeaterGrade->student_uid))
|
||||
if (!$this->hasPermissionCopy($repeaterGrade->lehrveranstaltung_id, $repeaterGrade->student_uid))
|
||||
return $this->_outputAuthError([$this->router->method => 'student/noten']);
|
||||
|
||||
$data = [
|
||||
@@ -565,57 +565,136 @@ class Grades extends FHCAPI_Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* Combined helper function to check permissions for
|
||||
* certificate-modifying functions
|
||||
* Helper function to check permissions for updateCertificate()
|
||||
*
|
||||
* @param integer $lehrveranstaltung_id
|
||||
* @param string $student_uid
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
protected function hasPermissionGradeUID($lehrveranstaltung_id, $student_uid)
|
||||
protected function hasPermissionUpdate($lehrveranstaltung_id, $student_uid)
|
||||
{
|
||||
if ($lehrveranstaltung_id === null || $student_uid === null)
|
||||
return true;
|
||||
|
||||
|
||||
$this->load->model('crm/Student_model', 'StudentModel');
|
||||
|
||||
$studentResult = $this->StudentModel->load([$student_uid]);
|
||||
if (isError($studentResult) || !hasData($studentResult))
|
||||
$result = $this->StudentModel->load([$student_uid]);
|
||||
if (isError($result) || !hasData($result))
|
||||
return false;
|
||||
|
||||
$student = current(getData($studentResult));
|
||||
$student = current(getData($result));
|
||||
|
||||
if ($this->permissionlib->isBerechtigt('admin', 'suid', $student->studiengang_kz))
|
||||
return true;
|
||||
if ($this->permissionlib->isBerechtigt('assistenz', 'suid', $student->studiengang_kz))
|
||||
return true;
|
||||
|
||||
$this->load->model('organisation/Studienplan_model', 'StudienplanModel');
|
||||
|
||||
$oesResult = $this->StudienplanModel->getAllOesForLv($lehrveranstaltung_id);
|
||||
if (isError($oesResult))
|
||||
$result = $this->StudienplanModel->getAllOesForLv($lehrveranstaltung_id);
|
||||
if (isError($result))
|
||||
return false;
|
||||
|
||||
$oes = hasData($oesResult) ? getData($oesResult) : [];
|
||||
$oes = getData($result) ?: [];
|
||||
|
||||
$this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel');
|
||||
|
||||
$lvResult = $this->LehrveranstaltungModel->load($lehrveranstaltung_id);
|
||||
if (isError($lvResult))
|
||||
$result = $this->LehrveranstaltungModel->getStg($lehrveranstaltung_id);
|
||||
if (isError($result))
|
||||
return false;
|
||||
|
||||
if (hasData($lvResult))
|
||||
$oes[] = current(getData($lvResult));
|
||||
|
||||
|
||||
if ($this->permissionlib->isBerechtigt('student/noten', 'suid', $student->studiengang_kz))
|
||||
return true;
|
||||
if (hasData($result))
|
||||
$oes[] = current(getData($result));
|
||||
|
||||
foreach ($oes as $oe) {
|
||||
if ($this->permissionlib->isBerechtigt('student/noten', 'suid', $oe->oe_kurzbz))
|
||||
if ($this->permissionlib->isBerechtigt('admin', 'suid', $oe->oe_kurzbz))
|
||||
return true;
|
||||
if ($this->permissionlib->isBerechtigt('student/noten', 'suid', $oe->studiengang_kz))
|
||||
if ($this->permissionlib->isBerechtigt('assistenz', 'suid', $oe->oe_kurzbz))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to check permissions for deleteCertificate()
|
||||
*
|
||||
* @param integer $lehrveranstaltung_id
|
||||
* @param string $student_uid
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
protected function hasPermissionDelete($lehrveranstaltung_id, $student_uid)
|
||||
{
|
||||
if ($lehrveranstaltung_id === null || $student_uid === null)
|
||||
return true;
|
||||
|
||||
$this->load->model('crm/Student_model', 'StudentModel');
|
||||
|
||||
$result = $this->StudentModel->load([$student_uid]);
|
||||
if (isError($result) || !hasData($result))
|
||||
return false;
|
||||
|
||||
$student = current(getData($result));
|
||||
|
||||
if ($this->permissionlib->isBerechtigt('admin', 'suid', $student->studiengang_kz))
|
||||
return true;
|
||||
if ($this->permissionlib->isBerechtigt('assistenz', 'suid', $student->studiengang_kz))
|
||||
return true;
|
||||
|
||||
$this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel');
|
||||
|
||||
$result = $this->LehrveranstaltungModel->load($lehrveranstaltung_id);
|
||||
if (isError($result) || !hasData($result))
|
||||
return false;
|
||||
|
||||
$oe = current(getData($result));
|
||||
|
||||
if ($this->permissionlib->isBerechtigt('admin', 'suid', $oe->oe_kurzbz))
|
||||
return true;
|
||||
if ($this->permissionlib->isBerechtigt('assistenz', 'suid', $oe->oe_kurzbz))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to check permissions for
|
||||
* copyTeacherProposalToCertificate() and copyRepeaterGradeToCertificate()
|
||||
*
|
||||
* @param integer $lehrveranstaltung_id
|
||||
* @param string $student_uid
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
protected function hasPermissionCopy($lehrveranstaltung_id, $student_uid)
|
||||
{
|
||||
if ($lehrveranstaltung_id === null || $student_uid === null)
|
||||
return true;
|
||||
|
||||
$this->load->model('crm/Student_model', 'StudentModel');
|
||||
|
||||
$result = $this->StudentModel->load([$student_uid]);
|
||||
if (isError($result) || !hasData($result))
|
||||
return false;
|
||||
|
||||
$student = current(getData($result));
|
||||
|
||||
if ($this->permissionlib->isBerechtigt('student/noten', 'suid', $student->studiengang_kz))
|
||||
return true;
|
||||
|
||||
$this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel');
|
||||
|
||||
$result = $this->LehrveranstaltungModel->load($lehrveranstaltung_id);
|
||||
if (isError($result) || !hasData($result))
|
||||
return false;
|
||||
|
||||
$oe = current(getData($result));
|
||||
|
||||
if ($this->permissionlib->isBerechtigt('student/noten', 'suid', $oe->oe_kurzbz))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ export default {
|
||||
urlMatchRankings:[],
|
||||
navUserDropdown:null,
|
||||
menuOpen:true,
|
||||
openMenuHierarchy: [],
|
||||
};
|
||||
},
|
||||
inject: ["isNarrow", "isMobile"],
|
||||
@@ -35,7 +36,7 @@ export default {
|
||||
return{
|
||||
setActiveEntry: this.setActiveEntry,
|
||||
addUrlCount: this.addUrlCount,
|
||||
makeParentContentActive: this.makeParentContentActive,
|
||||
setOpenMenuHierarchy: this.setOpenMenuHierarchy,
|
||||
}
|
||||
},
|
||||
computed:{
|
||||
@@ -82,19 +83,6 @@ export default {
|
||||
handleHideNavUser(){
|
||||
document.removeEventListener("click", this.checkSettingsVisibility);
|
||||
},
|
||||
makeParentContentActive(content_id, collection=this.entries, parent=null){
|
||||
if(!collection) return;
|
||||
if (typeof collection == 'object' && !Array.isArray(collection) && Object.entries(collection).length > 0) {
|
||||
collection = Object.values(collection);
|
||||
}
|
||||
for(let entry of collection){
|
||||
if(entry.content_id == content_id){
|
||||
this.activeEntry = parent;
|
||||
}
|
||||
this.makeParentContentActive(content_id, entry.childs, entry.content_id);
|
||||
}
|
||||
|
||||
},
|
||||
addUrlCount(count){
|
||||
this.urlMatchRankings.push(count);
|
||||
},
|
||||
@@ -102,6 +90,9 @@ export default {
|
||||
setActiveEntry(content_id){
|
||||
this.activeEntry = content_id;
|
||||
},
|
||||
setOpenMenuHierarchy(openMenuHierarchy) {
|
||||
this.openMenuHierarchy = openMenuHierarchy;
|
||||
},
|
||||
},
|
||||
created(){
|
||||
this.fetchMenu();
|
||||
@@ -192,7 +183,14 @@ export default {
|
||||
<div class="offcanvas-body p-0">
|
||||
<div id="nav-main-menu" class="nav-menu-collapse collapse collapse-horizontal show">
|
||||
<div class="flex-grow-1">
|
||||
<cis-menu-entry :highestMatchingUrlCount="highestMatchingUrlCount" :activeContent="activeEntry" v-for="entry in entries" :key="entry.content_id" :entry="entry" />
|
||||
<cis-menu-entry
|
||||
v-for="entry in entries"
|
||||
:key="entry.content_id"
|
||||
:highestMatchingUrlCount="highestMatchingUrlCount"
|
||||
:activeContent="activeEntry"
|
||||
:entry="entry"
|
||||
:openMenuHierarchy="openMenuHierarchy"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -8,6 +8,11 @@ export default {
|
||||
},
|
||||
activeContent: [String, Number],
|
||||
highestMatchingUrlCount: Number,
|
||||
openMenuHierarchy: Array,
|
||||
precedingMenuHierarchy: {
|
||||
type: Array,
|
||||
default: [],
|
||||
},
|
||||
},
|
||||
data: () => {
|
||||
return {
|
||||
@@ -15,7 +20,7 @@ export default {
|
||||
urlCount:0,
|
||||
}
|
||||
},
|
||||
inject: ['makeParentContentActive', 'setActiveEntry','addUrlCount'],
|
||||
inject: ['setActiveEntry', 'setOpenMenuHierarchy', 'addUrlCount'],
|
||||
watch:{
|
||||
highestMatchingUrlCount: function(newValue)
|
||||
{
|
||||
@@ -25,49 +30,27 @@ export default {
|
||||
this.setActiveEntry(this.entry.content_id);
|
||||
}
|
||||
},
|
||||
activeContent: function(newValue){
|
||||
if(newValue == this.entry.content_id){
|
||||
// wenn der Menupunkt nicht bereits offen ist
|
||||
if (!this.entry.menu_open){
|
||||
this.entry.menu_open = true;
|
||||
}
|
||||
|
||||
}else{
|
||||
if (this.searchRecursiveChild(this.entry, 'content_id',newValue)) {
|
||||
this.entry.menu_open = true;
|
||||
} else {
|
||||
this.entry.menu_open = false;
|
||||
}
|
||||
openMenuHierarchy() {
|
||||
if (!this.hasChilds) return;
|
||||
|
||||
if (this.$props.openMenuHierarchy.length && this.$props.openMenuHierarchy[0] === this.$props.entry.content_id) {
|
||||
this.$props.entry.menu_open = true;
|
||||
} else {
|
||||
this.$props.entry.menu_open = false;
|
||||
}
|
||||
},
|
||||
'entry.menu_open': function (newValue,oldValue) {
|
||||
if (newValue)
|
||||
{
|
||||
// only invokes .show if this.collapse is not null
|
||||
this.collapse && this.collapse.show();
|
||||
}
|
||||
else
|
||||
{
|
||||
// only invokes .hide if this.collapse is not null
|
||||
this.collapse && this.collapse.hide();
|
||||
if (this.activeContent == this.entry.content_id)
|
||||
{
|
||||
this.makeParentContentActive(this.entry.content_id);
|
||||
}
|
||||
'entry.menu_open': function (isMenuOpen) {
|
||||
if (!this.collapse)
|
||||
return;
|
||||
|
||||
if (isMenuOpen) {
|
||||
this.collapse.show();
|
||||
} else {
|
||||
this.collapse.hide();
|
||||
}
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
active: function () {
|
||||
if (this.entry.menu_open){
|
||||
return true;
|
||||
}
|
||||
else if (this.activeContent) {
|
||||
return this.activeContent == this.entry.content_id;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
hasFullLink() {
|
||||
return this.entry.url.startsWith(FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router)
|
||||
},
|
||||
@@ -89,25 +72,34 @@ export default {
|
||||
},
|
||||
hasChilds() {
|
||||
return this.entry.childs && this.entry.childs.length !== 0;
|
||||
}
|
||||
},
|
||||
menuHierarchy() {
|
||||
return [...this.$props.precedingMenuHierarchy, this.$props.entry.content_id];
|
||||
},
|
||||
menuNodeHref() {
|
||||
if (this.hasChilds) {
|
||||
return this.$props.entry.menu_open && this.hasFullLink
|
||||
? this.$props.entry.url
|
||||
: null;
|
||||
} else {
|
||||
return this.$props.entry.url;
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
getUrlMatchPoints(url,link){
|
||||
let splitted_link = link.split('/');
|
||||
let splitted_url = url.href.split('/');
|
||||
|
||||
let count = 0;
|
||||
|
||||
for(let part_url of splitted_url)
|
||||
{
|
||||
for (let part_link of splitted_link)
|
||||
{
|
||||
if(part_url == part_link)
|
||||
{
|
||||
for (let part_url of splitted_url) {
|
||||
for (let part_link of splitted_link) {
|
||||
if (part_url === part_link) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.urlCount = count;
|
||||
this.addUrlCount(count);
|
||||
},
|
||||
@@ -119,14 +111,11 @@ export default {
|
||||
let url_hash = url.hash;
|
||||
url_hash = url_hash.replace(url_hash_spaceSymbol_regex, " ").replace(url_hash_sharpSymbol_regex,"");
|
||||
|
||||
// if the url hash contains the titel of the menu
|
||||
// or if the url equals the link of a menu
|
||||
// then set the menu active
|
||||
if (url_hash == this.entry.titel || url.href == this.entry.url) {
|
||||
this.setActiveEntry(this.entry.content_id);
|
||||
this.setOpenMenuHierarchy(this.menuHierarchy);
|
||||
}
|
||||
},
|
||||
// searches the childs of an entry recursively based on the value of a property
|
||||
searchRecursiveChild(entry,property,value){
|
||||
if (typeof entry.childs == 'object' && !Array.isArray(entry.childs) && Object.entries(entry.childs).length > 0){
|
||||
entry.childs = Object.values(entry.childs);
|
||||
@@ -143,16 +132,23 @@ export default {
|
||||
}
|
||||
return false;
|
||||
},
|
||||
toggleCollapse(evt) {
|
||||
if (this.active)
|
||||
{
|
||||
this.makeParentContentActive(this.entry.content_id);
|
||||
toggleCollapse() {
|
||||
if (!this.$props.entry.menu_open) {
|
||||
this.setOpenMenuHierarchy(this.menuHierarchy);
|
||||
} else {
|
||||
this.setOpenMenuHierarchy(this.precedingMenuHierarchy);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.setActiveEntry(this.entry.content_id);
|
||||
},
|
||||
handleClickOnMenuNode() {
|
||||
if (this.hasFullLink) {
|
||||
this.setActiveEntry(this.$props.entry.content_id);
|
||||
if (this.hasChilds) {
|
||||
this.setOpenMenuHierarchy(this.menuHierarchy);
|
||||
}
|
||||
} else if (this.hasChilds) {
|
||||
this.toggleCollapse();
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
if (this.$refs.children) {
|
||||
@@ -168,41 +164,41 @@ export default {
|
||||
INCLUDE
|
||||
</div>
|
||||
<template v-else>
|
||||
<template v-if="hasChilds">
|
||||
<div class="btn-group w-100">
|
||||
<a :target="target"
|
||||
:href="(entry.menu_open && hasFullLink) ? entry.url : null"
|
||||
@click="toggleCollapse"
|
||||
:class="{
|
||||
'btn btn-default rounded-0 text-start': true,
|
||||
['btn-level-' + level]: true,
|
||||
'fw-bold':active
|
||||
}">
|
||||
{{ entry.titel }}
|
||||
</a>
|
||||
<button @click.prevent="toggleCollapse" :aria-expanded="entry.menu_open"
|
||||
:class="{
|
||||
'btn btn-default rounded-0 dropdown-toggle dropdown-toggle-split flex-grow-0': true,
|
||||
collapsed: !entry.menu_open
|
||||
}">
|
||||
<span class="visually-hidden">Toggle Dropdown</span>
|
||||
</button>
|
||||
</div>
|
||||
<ul ref="children"
|
||||
class="nav w-100 collapse">
|
||||
<cis-menu-entry :highestMatchingUrlCount="highestMatchingUrlCount" :activeContent="activeContent" v-for="child in entry.childs" :key="child" :entry="child" :level="level + 1"/>
|
||||
</ul>
|
||||
</template>
|
||||
<a v-else
|
||||
:href="entry.url"
|
||||
:target="target"
|
||||
:class="{
|
||||
'btn btn-default rounded-0 w-100 text-start': true,
|
||||
['btn-level-' + level]: true,
|
||||
'fw-bold':active
|
||||
}"
|
||||
@mouseup="setActiveEntry(entry.content_id)">
|
||||
{{ entry.titel }}
|
||||
</a>
|
||||
<div class="btn-group w-100">
|
||||
<a
|
||||
@click="handleClickOnMenuNode($event)"
|
||||
:href="menuNodeHref"
|
||||
:target="target"
|
||||
class="btn btn-default rounded-0 text-start"
|
||||
:class="{
|
||||
['btn-level-' + level]: true,
|
||||
'fw-bold': $props.activeContent === $props.entry.content_id
|
||||
}"
|
||||
:style="'padding-left: calc(var(--bs-btn-padding-x) * ' + $props.level + ');'"
|
||||
>
|
||||
{{ entry.titel }}
|
||||
</a>
|
||||
<button
|
||||
v-if="hasChilds"
|
||||
@click.prevent="toggleCollapse()"
|
||||
:aria-expanded="entry.menu_open"
|
||||
class="btn btn-default rounded-0 dropdown-toggle dropdown-toggle-split flex-grow-0"
|
||||
:class="{ collapsed: !entry.menu_open }"
|
||||
>
|
||||
<span class="visually-hidden">Toggle Dropdown</span>
|
||||
</button>
|
||||
</div>
|
||||
<ul v-if="hasChilds" ref="children" class="nav w-100 collapse" >
|
||||
<cis-menu-entry
|
||||
v-for="child in entry.childs"
|
||||
:key="child"
|
||||
:highestMatchingUrlCount="highestMatchingUrlCount"
|
||||
:activeContent="activeContent"
|
||||
:entry="child"
|
||||
:level="level + 1"
|
||||
:openMenuHierarchy="$props.openMenuHierarchy.slice(1)"
|
||||
:precedingMenuHierarchy="menuHierarchy"
|
||||
/>
|
||||
</ul>
|
||||
</template>`
|
||||
};
|
||||
@@ -822,18 +822,33 @@ 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 #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 v-if="filter.length || headerFilterActive">
|
||||
<div class="d-flex justify-content-center align-items-center gap-2 ps-4 position-absolute start-50 translate-middle-x">
|
||||
<p class="text-danger mb-0">
|
||||
<strong>{{$p.t('filter','filterActive')}}</strong>
|
||||
</p>
|
||||
|
||||
<button
|
||||
class="btn btn-outline-danger sm"
|
||||
:title="$p.t('filter/filterDelete')"
|
||||
@click="resetFilter"
|
||||
>
|
||||
<span class="fa-solid fa-filter-circle-xmark"></span>
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
|
||||
<template #additional>
|
||||
<div class="pe-1">
|
||||
@@ -873,22 +888,7 @@ export default {
|
||||
<i class="fa-solid fa-refresh pe-1"></i> {{selected.length}}
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template v-if="filter.length || headerFilterActive">
|
||||
<div class="d-flex justify-content-center align-items-center gap-2 ps-4 position-absolute start-50 translate-middle-x">
|
||||
<p class="text-danger mb-0">
|
||||
<strong>{{$p.t('filter','filterActive')}}</strong>
|
||||
</p>
|
||||
|
||||
<button
|
||||
class="btn btn-outline-danger sm"
|
||||
:title="$p.t('filter/filterDelete')"
|
||||
@click="resetFilter"
|
||||
>
|
||||
<span class="fa-solid fa-filter-circle-xmark"></span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<template #filter>
|
||||
|
||||
Reference in New Issue
Block a user