Merge branch 'feature-25999/C4_cleanup' into merge_FHC4_C4

This commit is contained in:
Harald Bamberger
2025-02-12 13:47:24 +01:00
10 changed files with 127 additions and 24 deletions
@@ -499,7 +499,7 @@ class Profil extends FHCAPI_Controller
/** @param integer $geburtsInfo */
if ($geburtsInfo) {
array_push($selectClause, "gebort");
array_push($selectClause, "gebdatum");
array_push($selectClause, "TO_CHAR(gebdatum, 'DD.MM.YYYY') as gebdatum");
}
$this->BenutzerModel->addSelect($selectClause);
$this->BenutzerModel->addJoin("tbl_person", "person_id");
@@ -278,6 +278,23 @@ class Stundenplan extends FHCAPI_Controller
$gruppe_obj_array[] = $lv_gruppe_object;
}
if($item->ort_kurzbz) {
$ort_content_object = $this->StundenplanModel->execReadOnlyQuery("
SELECT content_id
FROM public.tbl_ort
WHERE ort_kurzbz = ?", [$item->ort_kurzbz]);
if (isError($ort_content_object)) {
$this->show_error(getError($ort_content_object));
}
$ort_content_object = getData($ort_content_object)[0];
if($ort_content_object) {
$item->ort_content_id = $ort_content_object->content_id;
}
}
$item->gruppe = $gruppe_obj_array;
$item->lektor = $lektor_obj_array;
+1 -2
View File
@@ -203,8 +203,7 @@
}
.fhc-highlight-day {
border-width: 2px !important;
border-color: black !important;
box-shadow: inset 0 0 0 2px black !important;
}
.fhc-calendar-sm .fhc-calendar-month-page-day.active .no,
+12 -3
View File
@@ -98,11 +98,12 @@ const app = Vue.createApp({
const target = event.target.closest('a');
if (target && this.isInternalRoute(target.href)) {
const url = new URL(target.href)
const path = new URL(target.href).pathname
const path = url.pathname
const base = this.$router.options.history.base
const route = path.replace(base, '') || '/'
// let click event propagate normally if we dont route internally
const res = this.$router.resolve(route)
if(!res?.matched?.length) return
@@ -112,10 +113,13 @@ const app = Vue.createApp({
if(this.isMobile) { // toggle the menu
const navMain = document.getElementById('nav-main');
// fix unwanted toggle from off to on for some links on mobile
if(navMain.classList.contains('show')) document.getElementById('nav-main-btn').click();
if(navMain.classList.contains('show')){
document.getElementById('nav-main-btn').click();
}
}
this.$router.push(route);
}
}
},
@@ -127,6 +131,11 @@ const app = Vue.createApp({
},
});
router.beforeEach((to,from) => {
console.log('to', to)
console.log('from', from)
})
// kind of a bandaid for bad css on some pages to avoid horizontal scroll
setScrollbarWidth();
app.use(router);
@@ -1,6 +1,11 @@
export default {
name: "RaumComponent",
data() {
return {
imgContent: null
}
},
props:{
content:{
type:String,
@@ -10,11 +15,64 @@ export default {
type:Number,
}
},
methods: {
sanitizeLegacyTables(table) {
// find nested tables and replace with p element
const tt = table.querySelectorAll('table')
tt.forEach(t => {
const textContent = t.textContent.trim();
const pElement = document.createElement('p');
pElement.textContent = textContent;
t.parentNode.replaceChild(pElement, t);
})
// find unordered lists, traverse li childs and replace with p element -> more readable than 1 p tag for ul
const ul = table.querySelectorAll('ul')
ul.forEach(u => {
Array.from(u.children).forEach(li => {
const p = document.createElement('p');
p.textContent = li.textContent
u.parentNode.appendChild(p)
})
u.parentNode.removeChild(u)
})
// find bare text nodes and put into p element
const td = Array.from(table.querySelectorAll('td')).filter(el => el.scrollWidth > 100)
td.forEach(element => {
if (element.firstChild?.nodeType === Node.TEXT_NODE && element.firstChild.length > 10) {
const p = document.createElement('p');
p.appendChild(element.firstChild)
element.appendChild(p);
}
});
// flatten nested th elements
const ths = Array.from(table.querySelectorAll('th'))
ths.forEach(th => {
if(th.children.length > 1) {
th.innerHTML = Array.from(th.childNodes).find(cn => cn.textContent).textContent
}
})
// let p elements wrap on overflow
const p = table.querySelectorAll('p')
p.forEach(p => {
p.style.setProperty('word-wrap', 'break-word');
p.style.setProperty('white-space', 'normal');
p.style.setProperty('max-width', '400px');
})
}
},
mounted(){
// replaces the tablesorter with the tabulator
let tables = document.getElementsByClassName("tablesorter");
for (let table of tables) {
this.sanitizeLegacyTables(table)
new Tabulator(table, {
layout: "fitDataStretch",
@@ -25,11 +83,11 @@ export default {
}
})
}
// tries to wrap the Raum titel with a link tag that redirects to the Reservierungen of that Raum
let title = document.getElementsByTagName("h1");
title = title.length ? title[0] : null;
if (title)
// tries to wrap the Raum titel with a link tag that redirects to the Reservierungen of that Raum
if (title && title.innerText)
{
let room_name = title.innerText;
let room_name_reg_exp = new RegExp("\\w*\\s([a-zA-Z][0-9\\.]+)$");
@@ -48,15 +106,31 @@ export default {
console.error(`the regular expression did not match the room name: ${room_name}`);
}
return
}
else
const parser = new DOMParser()
const doc = parser.parseFromString(`<div>${this.content}</div>`, "text/html");
const img = doc.querySelector("img")
if(img && img.title)
{
console.error(`was not able to get the title of the raum_contentmittitel by searching for the first h1 element`);
const imgAttributes = {}
for (let attr of img.attributes) {
imgAttributes[attr.name] = attr.value
}
this.imgContent = imgAttributes
}
console.error(`was not able to get the title of the raum_contentmittitel`);
},
template: /*html*/ `
<!-- div that contains the content -->
<div v-html="content" v-if="content" ></div>
<!-- TODO: test with more img content from cms-->
<div v-if="imgContent"><img v-bind="imgContent"></img></div>
<div v-html="content" v-else-if="content" ></div>
<p v-else>Content was not found</p>
`,
};
+5 -2
View File
@@ -74,7 +74,7 @@ export default {
return '';
let xmlDoc = (new DOMParser()).parseFromString(this.entry.content,"text/xml");
let url = xmlDoc.getElementsByTagName('url')[0];
if (!url)
return '';
// TODO(chris): replace get params
@@ -101,6 +101,9 @@ export default {
}
return FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router + '/CisVue/Cms/content/' + this.entry.content_id;
},
hasFullLink() {
return this.link.startsWith(FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router)
},
target() {
if (this.entry.template_kurzbz == 'redirect') {
if (!this.entry.content)
@@ -201,7 +204,7 @@ export default {
<template v-if="hasChilds">
<div class="btn-group w-100">
<a :target="target"
:href="(entry.menu_open)?link:null"
:href="(entry.menu_open && hasFullLink)?link:null"
@click="toggleCollapse"
:class="{
'btn btn-default rounded-0 text-start': true,
+1 -2
View File
@@ -24,8 +24,7 @@ export default {
{
if (!this.event || !this.event.ort_content_id) return "a";
// TODO: define/build link with content_id and/or roomname
// return FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router + `/CisVue/cms/content/${this.event.ort_content_id}`
return FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router + `/CisVue/Cms/content/${this.event.ort_content_id}`
},
start_time: function () {
if (!this.event.start) return 'N/A';
@@ -230,7 +230,7 @@ export default {
[`${this.$p.t('profil', 'Geburtsort')}`]: this.data.gebort,
[`${this.$p.t('profil', 'Kurzzeichen')}`]: this.data.kurzbz,
[`${this.$p.t('profil', 'Telefon')}`]:
(this.data.standort_telefon ? this.data.standort_telefon + " " + this.data.telefonklappe : this.data.telefonklappe),
(this.data.standort_telefon ? this.data.standort_telefon.kontakt + " " + this.data.telefonklappe : this.data.telefonklappe),
[`${this.$p.t('profil', 'Büro')}`]: this.data.ort_kurzbz,
};
},
+7 -5
View File
@@ -139,11 +139,13 @@ export default {
}
}).observe(this.$refs.container);
}
Vue.nextTick(()=>{
this.carouselInstance = new bootstrap.Carousel(this.$refs.carousel, {
wrap: false, // keep this off even though it actually wraps
interval: false
});
Vue.nextTick(()=> {
if(this.$refs.carousel) { // carousel ref might not exist in every widget width/height
this.carouselInstance = new bootstrap.Carousel(this.$refs.carousel, {
wrap: false, // keep this off even though it actually wraps
interval: false
});
}
})
},
+1 -1
View File
@@ -3,7 +3,7 @@ import CalendarDates from "./CalendarDates.js";
const monthDayRanges = []
for(let i = 1; i < 13; i++) {
monthDayRanges.push(new Date(1995, i, 0).getDate())
monthDayRanges.push(new Date(new Date(Date.now()).getFullYear(), i, 0).getDate())
}
class CalendarDate {