news widget template carousel with menu update;

This commit is contained in:
Johann Hoffmann
2024-11-29 15:24:33 +01:00
parent 1346466f79
commit 1ca0f35d29
3 changed files with 170 additions and 39 deletions
@@ -125,7 +125,7 @@ class Cms extends FHCAPI_Controller
//get the data or terminate with error
$news = $this->getDataOrTerminateWithError($news);
// collect the content of the news
foreach($news as $news_element){
$this->addMeta("content_id",$news_element->content_id);
@@ -134,12 +134,17 @@ class Cms extends FHCAPI_Controller
$this->NewsModel->resetQuery();
$content = $this->cmslib->getContent($news_element->content_id);
$content = $this->getDataOrTerminateWithError($content);
$content = getData($content);
$news_element->content_obj = $content;
}
$withContent = function($news) {
return $news->content_obj != null;
};
$newsWithContent = array_filter($news, $withContent);
$this->terminateWithSuccess($news);
$this->terminateWithSuccess($newsWithContent);
}
+65 -16
View File
@@ -1,23 +1,72 @@
.widgets-news .card-header {
flex-direction: column;
align-items: flex-start !important;
}
:root{
--news-widget-height: 1;
}
.widgets-news .news-content > div,
.widgets-news .news-content .row:nth-child(1),
.widgets-news .news-content .news-list,
.widgets-news .news-content .news-list-item,
.widgets-news .news-content .card-body
{
height: 100%;
}
.widgets-news img
{
max-width: 100%;
}
}
.fhc-news-menu-item {
padding: 0.375rem;
color: var(--fhc-cis-menu-lvl-1-color);
min-height: 5%;
max-height: 30%;
width: 100%;
justify-content: space-between;
align-items: center;
/*background-color: #769b12;*/
background-color: #00649c;
/*background-color: var(--fhc-cis-menu-lvl-1-bg);*/
border: 1px solid #f1f1f1; /* Button border */
/*border-radius: 5px; !* Rounded corners *!*/
font-size: 16px; /* Adjust text size */
cursor: pointer; /* Make it look clickable */
transition: background-color 0.2s ease, border-color 0.2s ease; /* Smooth transition */
}
.fhc-news-menu-item:hover {
/*background-color: #8bb717; !* Darker shade for hover effect *!*/
background-color: var(--fhc-cis-menu-lvl-1-bg-hover);
border-color: #f1f1f1; /* Darker border for hover effect */
}
.fhc-news-menu-item:active {
/*background-color: #b1e81a; !* Even darker shade when clicked *!*/
background-color: var(--fhc-cis-menu-lvl-1-color-hover);
border-color: #f1f1f1; /* Darker border when clicked */
}
.fhc-news-menu-item:focus {
outline: none; /* Remove the outline on focus */
/*box-shadow: 0 0 0 0.2rem rgba(183, 255, 0, 0.96); !* Focus ring for accessibility *!*/
}
.fhc-news-menu-item-betreff
{
width: 100%;
text-align: center;
max-height: 100%;
height: 100%;
}
.fhc-news-menu-item-date {
text-align: end;
width: 100%;
max-height: 100%;
height: 100%;
}
.fhc-carousel .carousel-item {
transition: transform 0.375s ease-in-out, opacity 0.75s ease-in-out; /* Customize duration and easing */
}
.fhc-carousel .carousel-item-next,
.fhc-carousel .carousel-item-prev {
transition: transform 0.44s ease-in-out, opacity 0.8s ease-in-out; /* Apply the same timing */
}
.fhc-carousel .carousel-item-start,
.fhc-carousel .carousel-item-end {
transition: transform 0.44s ease-in-out, opacity 0.8s ease-in-out; /* Ensure smooth entry and exit */
}
+97 -20
View File
@@ -1,14 +1,17 @@
import AbstractWidget from './Abstract';
import BsModal from '../Bootstrap/Modal';
const MAX_LOADED_NEWS = 10;
const MAX_LOADED_NEWS = 30;
export default {
name: "WidgetsNews",
components: {BsModal},
components: {
BsModal
},
data: () => ({
allNewsList: [],
singleNews: {},
selected: null
}),
mixins: [AbstractWidget],
computed: {
@@ -17,10 +20,12 @@ export default {
},
newsList() {
//Return news amount depending on widget width and size
let quantity = this.width;
// let quantity = this.width;
let quantity = MAX_LOADED_NEWS;
if (this.width === 1) {
quantity = this.height === 1 ? 4 : 10;
quantity = this.height === 1 ? 4 : MAX_LOADED_NEWS;
}
return this.allNewsList.slice(0, quantity);
@@ -31,12 +36,18 @@ export default {
"skin/images/fh_technikum_wien_illustration_klein.png"
);
},
activeNews() {
return this.allNewsList.find(news => news.minimized === false) ?? this.allNewsList[0] ?? null
}
},
created() {
this.$fhcApi.factory.cms
.news(MAX_LOADED_NEWS)
.then((res) => {
this.allNewsList = res.data;
this.allNewsList = Array.from(Object.values(res.data));
this.selected = this.allNewsList.length ? this.allNewsList[0] : null
})
.catch((err) => {
console.error("ERROR: ", err.response.data);
@@ -45,6 +56,39 @@ export default {
this.$emit("setConfig", false);
},
methods: {
setNext(){
const thisIndex = this.allNewsList.findIndex(n=>n.news_id == this.selected.news_id)
const nextIndex = thisIndex == (this.allNewsList.length - 1) ? 0 : thisIndex + 1
this.setSelected(this.allNewsList[nextIndex])
},
setPrev() {
const thisIndex = this.allNewsList.findIndex(n=>n.news_id == this.selected.news_id)
const prevIndex = thisIndex ? thisIndex - 1 : this.allNewsList.length - 1
this.setSelected(this.allNewsList[prevIndex], 'prev')
},
setSelected(news, direction = "next") {
if (this.selected && news && this.selected === news) return
if(this.selected){
const otherDirection = direction === "next" ? "prev" : "next"
const oldCard = document.getElementById('card-'+this.selected.news_id)
oldCard.classList.remove('active')
oldCard.classList.add('carousel-item-'+otherDirection)
}
const newCard = document.getElementById('card-'+news.news_id)
newCard.classList.add('carousel-item-'+direction)
void newCard.offsetWidth;
newCard.classList.add('active')
newCard.addEventListener('transitionend', () => {
newCard.classList.remove('carousel-item-'+direction);
}, { once: true });
this.selected = news
},
contentURI: function (content_id) {
return (
FHC_JS_DATA_STORAGE_OBJECT.app_root +
@@ -67,23 +111,56 @@ export default {
},
template: /*html*/ `
<div class="widgets-news h-100" :style="getNewsWidgetStyle">
<div class="d-flex flex-column h-100 ">
<div class="d-flex flex-column h-100">
<div class="h-100" style="overflow-y: auto" v-if="width == 1">
<div v-for="(news, index) in newsList" :key="news.id" class="mt-2">
<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>
</div>
<div v-else-if="width > 1 && height === 1" class="h-100" :class="'row row-cols-' + width">
<div class="h-100" v-for="news in newsList" :key="news.id">
<div class="news-content h-100" :style="'--news-widget-height: '+height" ref="htmlContent" v-html="news.content_obj.content"></div>
</div>
</div>
<div v-else class="h-100" :class="'row row-cols-' + width + ' gx-2'">
<div class="h-100" v-for="news in newsList" :key="news.id">
<div class="news-content h-100" :style="'--news-widget-height: '+height" ref="htmlContent" v-html="news.content_obj.content"></div>
</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>
</div>
<div v-else-if="width > 1 && height === 1" class="h-100" :class="'row row-cols-' + width">
<div class="h-100" v-for="news in newsList" :key="news.id">
<div class="news-content h-100" :style="'--news-widget-height: '+height" ref="htmlContent" v-html="news.content_obj.content"></div>
</div>
</div>
<div v-else class="row h-100">
<div :class="'col-'+(width == 2? 6 : 4) + ' h-100'" style="overflow: auto; padding-right: 0px; margin: 0px;">
<template v-for="news in newsList" :key="'menu-'+news.news_id">
<div class="row fhc-news-menu-item" @click="setSelected(news)">
<div class="col-8 fhc-news-menu-item-betreff" style="overflow-y: hidden;"><p>{{news.content_obj.betreff ?? ''}}</p></div>
<span class="fhc-news-menu-item-date"
>{{ news.datum ?? ''}}</span>
</div>
</template>
</div>
<div :class="'col-'+(width == 2? 6 : 8) + ' h-100'" ref="htmlContent" style="padding: 0px; margin: 0px;">
<div class="container" style="padding: 0px; height: 100%;" ref="carocontainer">
<div id="carouselExampleControls" style="height: 100%;" class="carousel slide fhc-carousel" data-bs-ride="carousel"
data-bs-interval="false"
ref="carocontrols">
<div class="carousel-indicators">
<button v-for="(news, index) in newsList" :id="'indicator-'+news_news_id" type="button" data-bs-target="#carouselExampleIndicators" data-bs-slide-to="index"></button>
</div>
<div class="carousel-inner" style="height: 100%;">
<div v-for="news in newsList" class="carousel-item" :class="(this.selected.news_id === news.news_id ? 'active' : '')" :id="'card-'+news.news_id" style="height: 100%; overflow-y: auto; margin: 0px;" v-html="news.content_obj.content">
</div>
</div>
<button @click="setPrev" style="z-index: 9999; color: black; opacity: 1;" class="carousel-control-prev" type="button">
<i class="fa fa-chevron-left"></i>
</button>
<button @click="setNext" style="z-index: 9999; color: black; opacity: 1;" class="carousel-control-next" type="button">
<i class="fa fa-chevron-right"></i>
</button>
</div>
</div>
</div>
</div>
</div>
</div>`,