mirror of
https://github.com/FH-Complete/FHC-Core.git
synced 2026-07-19 16:02:15 +00:00
update(News Widget/Content stylings): updates the style of the news widget and single news view
This commit is contained in:
@@ -158,32 +158,17 @@
|
||||
|
||||
.carousel-control-prev,
|
||||
.carousel-control-next {
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s ease;
|
||||
top: 0.5rem !important;
|
||||
bottom: auto !important;
|
||||
opacity: 1 !important;
|
||||
}
|
||||
|
||||
/* Show the buttons when the carousel is hovered */
|
||||
.carousel:hover .carousel-control-prev,
|
||||
.carousel:hover .carousel-control-next {
|
||||
opacity: 1;
|
||||
.fhc-news-items-lg .row:hover{
|
||||
background-color: var(--fhc-primary);
|
||||
color: var(--fhc-light);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.fhc-news-text{
|
||||
font-size: 0.75em;
|
||||
}
|
||||
.fhc-news-items-sm{
|
||||
|
||||
.fhc-news-xs {
|
||||
font-size: 0.6em;
|
||||
}
|
||||
|
||||
.fhc-news-sm {
|
||||
font-size: 0.7em;
|
||||
}
|
||||
|
||||
.fhc-news-md {
|
||||
font-size: 1.1em;
|
||||
}
|
||||
|
||||
.fhc-news-lg {
|
||||
font-size: 1.4em;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import raum_contentmittitel from './Content_types/Raum_contentmittitel.js'
|
||||
import general from './Content_types/General.js'
|
||||
import BsConfirm from "../../Bootstrap/Confirm.js";
|
||||
|
||||
import news_content from './Content_types/News_content.js';
|
||||
import ApiCms from '../../../api/factory/cms.js';
|
||||
|
||||
export default {
|
||||
@@ -22,6 +22,7 @@ export default {
|
||||
},
|
||||
components: {
|
||||
raum_contentmittitel,
|
||||
news_content,
|
||||
general,
|
||||
},
|
||||
data() {
|
||||
@@ -80,6 +81,8 @@ export default {
|
||||
switch (this.content_type) {
|
||||
case "raum_contentmittitel":
|
||||
return "raum_contentmittitel";
|
||||
case "news":
|
||||
return "news_content";
|
||||
default:
|
||||
return "general";
|
||||
};
|
||||
|
||||
@@ -0,0 +1,142 @@
|
||||
import { replaceRelativeLegacyLink } from "../../../../helpers/LegacyLinkReplaceHelper.js"
|
||||
export default {
|
||||
name: "GeneralComponent",
|
||||
props:{
|
||||
content:{
|
||||
type:String,
|
||||
required:true,
|
||||
},
|
||||
},
|
||||
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 = Array.from(document.getElementsByClassName("tablesorter"));
|
||||
|
||||
tables.forEach((table, index) => {
|
||||
this.sanitizeLegacyTables(table)
|
||||
|
||||
new Tabulator(table, {
|
||||
index: index,
|
||||
layout: "fitDataFill",
|
||||
|
||||
columnDefaults: {
|
||||
formatter: "html",
|
||||
resizable: true,
|
||||
minWidth: "100px"
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
document.querySelectorAll("#cms [data-confirm]").forEach((el) => {
|
||||
el.addEventListener("click", (evt) => {
|
||||
evt.preventDefault();
|
||||
BsConfirm.popup(el.dataset.confirm)
|
||||
.then(() => {
|
||||
Axios.get(el.href)
|
||||
.then((res) => {
|
||||
// TODO(chris): check for success then show message and/or reload
|
||||
location = location;
|
||||
})
|
||||
.catch((err) => console.error("ERROR:", err));
|
||||
})
|
||||
.catch(() => {});
|
||||
});
|
||||
});
|
||||
document.querySelectorAll("#cms [data-href]").forEach((el) => {
|
||||
el.href = el.dataset.href.replace(
|
||||
/^ROOT\//,
|
||||
FHC_JS_DATA_STORAGE_OBJECT.app_root
|
||||
);
|
||||
});
|
||||
|
||||
document.querySelectorAll("[href]").forEach((element) => {
|
||||
let orignal_href = element.getAttribute("href");
|
||||
let new_href = replaceRelativeLegacyLink(orignal_href);
|
||||
element.href = new_href;
|
||||
});
|
||||
|
||||
document.querySelectorAll("[style*=background-color]").forEach((element) => {
|
||||
if (element.style.backgroundColor == "rgb(255, 255, 255)"){
|
||||
element.style.backgroundColor = "var(--fhc-background)";
|
||||
}
|
||||
if(element.querySelector("*[style*=background-color]")){
|
||||
element.style.backgroundColor = "var(--fhc-tertiary)";
|
||||
}
|
||||
});
|
||||
|
||||
Vue.nextTick(() => {
|
||||
document.querySelectorAll(".card-header").forEach((el) => {
|
||||
el.classList.add("fhc-primary");
|
||||
});
|
||||
document.querySelectorAll(".row").forEach((el) => {
|
||||
el.classList.add("w-100");
|
||||
el.classList.add("align-items-center");
|
||||
|
||||
});
|
||||
document.querySelectorAll(".row h2").forEach((el) => {
|
||||
el.classList.add("mb-0");
|
||||
});
|
||||
|
||||
})
|
||||
|
||||
},
|
||||
template: /*html*/ `
|
||||
<!-- div that contains the content -->
|
||||
<div v-if="content" class="container" style="max-width: 100%;"><div class="row"><div class="col">
|
||||
<div v-html="content" ></div>
|
||||
</div></div></div>
|
||||
<p v-else>Content was not found</p>
|
||||
`,
|
||||
};
|
||||
|
||||
@@ -164,7 +164,7 @@ export default {
|
||||
</Transition>
|
||||
<span class="col mx-2 px-2">{{ widget.setup.name }}</span>
|
||||
<template v-if="isPinned">
|
||||
<div type="button" v-if="editMode" pinned="true" @click="unpin" v-tooltip="{showDelay:1000, value: 'unpin item'}" aria-label="unpin item" class="pin cursor-pointer col-auto me-2">
|
||||
<div type="button" role="button" v-if="editMode" pinned="true" @click="unpin" title="unpin item" aria-label="unpin item" class="pin cursor-pointer col-auto me-2">
|
||||
<i class="fa-solid fa-thumbtack " aria-hidden="true"></i>
|
||||
</div>
|
||||
<div v-else class="col-auto me-2">
|
||||
@@ -172,7 +172,7 @@ export default {
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<div type="button" v-if="editMode" class="col-auto me-2 pin" @click="pinItem" aria-label="pin item" v-tooltip="{showDelay:1000, value: 'pin item'}">
|
||||
<div type="button" role="button" v-if="editMode" class="col-auto me-2 pin" @click="pinItem" aria-label="pin item" title="pin item">
|
||||
<i class="fa-solid fa-thumbtack" aria-hidden="true" style="color:lightgray;"></i>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -36,7 +36,12 @@ export default {
|
||||
quantity = this.height === 1 ? 4 : MAX_LOADED_NEWS;
|
||||
}
|
||||
|
||||
return this.allNewsList.slice(0, quantity);
|
||||
let slicedNews= this.allNewsList.slice(0, quantity);
|
||||
slicedNews.sort((a,b)=>{
|
||||
return new Date(b.insertamum) - new Date(a.insertamum);
|
||||
});
|
||||
|
||||
return slicedNews;
|
||||
},
|
||||
carouselItems() {
|
||||
return this.allNewsList.reduce((acc, cur) => {
|
||||
@@ -47,6 +52,14 @@ export default {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
formatDate: function (dateTime) {
|
||||
const dt = new Date(dateTime);
|
||||
return dt.getDate() + '.' + (dt.getMonth() + 1) + '.' + dt.getFullYear();
|
||||
},
|
||||
formatTime: function (dateTime) {
|
||||
const dt = new Date(dateTime);
|
||||
return dt.getHours() + ':' + dt.getMinutes();
|
||||
},
|
||||
isString(value){
|
||||
return Object.prototype.toString.call(value) === '[object String]';
|
||||
},
|
||||
@@ -141,6 +154,25 @@ export default {
|
||||
this.allNewsList = Array.from(Object.values(news));
|
||||
this.selected = this.allNewsList.length ? this.allNewsList[0] : null
|
||||
this.initActiveItem()
|
||||
|
||||
Vue.nextTick(() => {
|
||||
document.querySelectorAll(".fhc-news-card-item .card-body, .fhc-news-card-item .card, .fhc-news-card-item .card-header").forEach((el) => {
|
||||
el.classList.add("border-0");
|
||||
});
|
||||
|
||||
document.querySelectorAll(".fhc-news-card-item .card-header").forEach((el) => {
|
||||
el.classList.add("px-5");
|
||||
el.classList.add("fhc-primary");
|
||||
});
|
||||
document.querySelectorAll(".fhc-news-card-item .card-header .row").forEach((el) => {
|
||||
el.classList.add("w-100");
|
||||
el.classList.add("align-items-center");
|
||||
|
||||
});
|
||||
document.querySelectorAll(".fhc-news-card-item .card-header .row h2").forEach((el) => {
|
||||
el.classList.add("mb-0");
|
||||
});
|
||||
})
|
||||
|
||||
})
|
||||
.catch((err) => {
|
||||
@@ -167,32 +199,37 @@ export default {
|
||||
}
|
||||
|
||||
this.initCarouselInstance()
|
||||
|
||||
|
||||
},
|
||||
template: /*html*/ `
|
||||
<div ref="container" class="widgets-news h-100" :class="sizeClass" :style="getNewsWidgetStyle">
|
||||
<div class="d-flex flex-column h-100">
|
||||
<div class="h-100" style="overflow-y: auto" v-show="width == 1">
|
||||
<div v-for="(news, index) in newsList" :key="news.news_id" class="mt-2">
|
||||
<div v-if="index > 0 " class="fhc-seperator"></div>
|
||||
<a :href="contentURI(news.content_id)" >{{ news.content_obj.betreff?news.content_obj.betreff:getDate(news.insertamum) }}</a><br>
|
||||
<span class="small text-muted">{{ formatDateTime(news.insertamum) }}</span>
|
||||
<div class="h-100 fhc-news-items-sm" style="overflow-y: auto" v-show="width == 1" >
|
||||
<div v-for="(news, index) in newsList" :key="news.news_id" class="py-2">
|
||||
<div class="row m-0">
|
||||
<div class="col-3 d-flex">
|
||||
<span class="small">{{ formatDate(news.insertamum) }} </span>
|
||||
<span class="ms-auto small">{{ formatTime(news.insertamum) }} </span>
|
||||
</div>
|
||||
<div class="col">
|
||||
<a :href="contentURI(news.content_id)" >{{ news.content_obj.betreff?news.content_obj.betreff:getDate(news.insertamum) }}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-show="width >1" class="row h-100 g-0">
|
||||
<div :class="'col-'+(width == 2? 6 : 4) + ' h-100 g-0'" style="overflow: auto;">
|
||||
<template v-for="news in newsList" :key="'menu-'+news.news_id">
|
||||
<div class="position-relative">
|
||||
<div class="row fhc-news-menu-item " @click="setSelected(news)" :class="getMenuItemClass(news)" style="margin-right: 0px; margin-left: 0px; overflow-y: hidden;">
|
||||
<div class="col-8 fhc-news-menu-item-betreff">
|
||||
<p class="fhc-news-text mb-0">
|
||||
{{news.content_obj.betreff ?? ''}}
|
||||
</p>
|
||||
</div>
|
||||
<span style="top:2px; right:0" class=" position-absolute d-none d-xl-block fhc-news-text fhc-news-menu-item-date fw-bold">
|
||||
{{ news.datumformatted ?? ''}}
|
||||
</span>
|
||||
</div>
|
||||
<div :class="'col-'+(width == 2? 6 : 4) + ' h-100 g-0'" style="overflow: auto;" class="fhc-news-items-lg border-end" >
|
||||
<template v-for="news in newsList" :key="'menu-'+news.news_id" >
|
||||
<div class="row m-0 py-2" @click="setSelected(news)">
|
||||
<div class="col-3 d-flex">
|
||||
<span class="small">{{ formatDate(news.insertamum) }} </span>
|
||||
<span class="ms-auto small">{{ formatTime(news.insertamum) }} </span>
|
||||
</div>
|
||||
<div class="col">
|
||||
<span >{{ news.content_obj.betreff?news.content_obj.betreff:getDate(news.insertamum) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
<div :class="'col-'+(width == 2? 6 : 8) + ' h-100'" style="padding-left: 0px; padding-right: 0px;" ref="htmlContent">
|
||||
@@ -200,16 +237,16 @@ export default {
|
||||
<div id="FhcCarouselContainer" style="height: 100%;" ref="carousel" class="carousel slide fhc-carousel" data-bs-interval="false">
|
||||
|
||||
<div class="carousel-inner" ref="carouselInner" style="height: 100%; max-width: 100%;">
|
||||
<div ref="carouselItems" v-for="(news, index) in newsList" class="carousel-item " style="overflow-y: auto; overflow-x: hidden; height: 100%;" :id="'card-'+news.news_id" v-html="news.content_obj.content"/>
|
||||
<div ref="carouselItems" v-for="(news, index) in newsList" class="carousel-item fhc-news-card-item" style="overflow-y: auto; overflow-x: hidden; height: 100%;" :id="'card-'+news.news_id" v-html="news.content_obj.content"/>
|
||||
</div>
|
||||
<button @click="setPrev" @focus="$event.target.blur()" style="z-index: 100; color: black; overflow: hidden; margin-left: 10px; width:35px;" data-bs-target="#FhcCarouselContainer" class="carousel-control-prev" type="button">
|
||||
<div class="border rounded-circle" style="padding-left: 0.4rem; padding-right: 0.4rem; background-color:rgba(138,138,138,0.4)">
|
||||
<i class="fa fa-chevron-left"></i>
|
||||
<button @click="setPrev" style="z-index: 100; overflow: hidden; margin-left: 4px; width:35px;" data-bs-target="#FhcCarouselContainer" class="carousel-control-prev" type="button">
|
||||
<div style="padding-left: 0.4rem; padding-right: 0.4rem;">
|
||||
<i class="fa fa-chevron-left fhc-text-light"></i>
|
||||
</div>
|
||||
</button>
|
||||
<button @click="setNext" @focus="$event.target.blur()" style="z-index: 100; color: black; overflow: hidden; margin-right: 10px; width:35px;" data-bs-target="#FhcCarouselContainer" class="carousel-control-next" type="button">
|
||||
<div class="border rounded-circle" style="padding-left: 0.4rem; padding-right: 0.4rem; background-color:rgba(138,138,138,0.4)">
|
||||
<i class="fa fa-chevron-right"></i>
|
||||
<button @click="setNext" style="z-index: 100; overflow: hidden; margin-right: 4px; width:35px;" data-bs-target="#FhcCarouselContainer" class="carousel-control-next" type="button">
|
||||
<div style="padding-left: 0.4rem; padding-right: 0.4rem;">
|
||||
<i class="fa fa-chevron-right fhc-text-light"></i>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user