make frontend news widget

This commit is contained in:
Julie Lenaerts 2023-11-09 13:49:32 +01:00
parent efdc84930b
commit 6c93c8b8fa
7 changed files with 141 additions and 38 deletions

View File

@ -19,17 +19,17 @@ class DashboardApiController
{
}
public function indexApi()
{
return $this->getDashboardConfiguration();
}
// I dont understand why this method is needed, but if I do a cache clear without this method present, he gives an error saying it needs to be present.
public function setCrudConfig()
{
return null;
}
/**
* Give the user dashboard configuration
*
* @Route("/api/1.0/main/dashboard-config-item.json", methods={"post"})
*/
public function getDashboardConfiguration(): JsonResponse
{
$data = [

View File

@ -97,6 +97,8 @@ import MyNotifications from './MyNotifications';
import MyWorkflows from './MyWorkflows.vue';
import TabCounter from './TabCounter';
import { mapState } from "vuex";
import { makeFetch } from "ChillMainAssets/lib/api/apiMethods";
export default {
name: "App",
@ -112,7 +114,7 @@ export default {
},
data() {
return {
activeTab: 'MyCustoms'
activeTab: 'MyCustoms',
}
},
computed: {
@ -131,7 +133,6 @@ export default {
}
},
mounted() {
this.$store.dispatch('getDashboardItems', {userId: 1})
for (const m of [
'MyNotifications',
'MyAccompanyingCourses',

View File

@ -0,0 +1,106 @@
<template>
<div>
<h1>{{ $t('widget.news.title') }}</h1>
<ul class="scrollable">
<li v-for="item in newsItems" :key="item.id">
<h2>{{ item.title }}</h2>
<div class="content" v-if="shouldTruncate(item.content)">
{{ truncateContent(item.content) }}
<span class="read-more" @click="() => openModal(item)">Read more</span>
</div>
<div class="content" v-else>
{{ item.content }}
</div>
<modal v-if="showModal" @close="closeModal">
<template #header>{{ item.title }}</template>
<template #body>{{ item.content }}</template>
</modal>
</li>
</ul>
</div>
</template>
<script setup lang="ts">
import { onMounted, ref } from 'vue'
import {makeFetch} from "ChillMainAssets/lib/api/apiMethods";
import Modal from '../../_components/Modal.vue'; // Adjust the import path
const newsItems = ref([])
const selectedArticle = ref(null);
const showModal = ref(false);
const openModal = (item) => {
selectedArticle.value = item;
showModal.value = true;
};
const closeModal = () => {
selectedArticle.value = null;
showModal.value = false;
};;
const shouldTruncate = (content, maxLength = 100) => {
return content.length > maxLength;
};
const truncateContent = (content, maxLength = 100) => {
if (shouldTruncate(content, maxLength)) {
return content.slice(0, maxLength) + '...';
} else {
return content;
}
};
onMounted(() => {
makeFetch('GET', '/api/1.0/main/news.json')
.then((response) => {
newsItems.value = response.results
})
.catch((error) => {
console.error('Error fetching news items', error);
})
})
</script>
<style scoped>
ul {
list-style: none;
padding: 0;
}
li {
margin-bottom: 20px;
overflow: hidden;
}
h2 {
margin-bottom: 10px;
}
.content {
max-height: 100px; /* Adjust the max height as needed */
overflow: hidden;
}
.scrollable {
overflow-y: auto;
max-height: 150px; /* Same as .content max-height */
margin-bottom: 10px; /* To give space for the scrollbar */
}
button {
cursor: pointer;
background-color: #3498db;
color: #fff;
border: none;
padding: 5px 10px;
border-radius: 3px;
}
.read-more {
color: #3498db; /* Adjust the color as needed */
cursor: pointer;
}
</style>

View File

@ -39,18 +39,11 @@
</div>
</div>
<div class="mbloc col col-sm-6 col-lg-4">
<div class="custom2">
News
<MyWidget :chart-data="chartData" />
</div>
</div>
<div class="mbloc col col-sm-6 col-lg-4">
<div class="custom3">
Mon dashboard personnalisé
</div>
</div>
<div class="mbloc col col-lg-6 col-lg-4" v-if="this.dashboardItems">
<div v-for="dashboardItem in this.dashboardItems">
<News v-if="dashboardItem.type ==='news'"/>
</div>
</div>
</div>
</template>
@ -58,14 +51,20 @@
<script>
import { mapGetters } from "vuex";
import Masonry from 'masonry-layout/masonry';
import {makeFetch} from "ChillMainAssets/lib/api/apiMethods";
import News from './DashboardWidgets/News.vue';
export default {
name: "MyCustoms",
components: {
News
},
data() {
return {
counterClass: {
counter: true //hack to pass class 'counter' in i18n-t
},
dashboardItems: []
}
},
computed: {
@ -77,6 +76,15 @@ export default {
mounted() {
const elem = document.querySelector('#dashboards');
const masonry = new Masonry(elem, {});
//Fetch the dashboard items configured for user. Currently response is still hardcoded and no user id passed.
makeFetch('GET', '/api/1.0/main/dashboard-config-item.json')
.then((response) => {
this.dashboardItems = response;
console.log('dashboarditems', this.dashboardItems)
})
.catch((error) => {
throw error
})
}
}
</script>

View File

@ -24,7 +24,6 @@ const store = createStore({
workflows: {},
workflowsCc: {},
errorMsg: [],
dashboardItems: {},
loading: false
},
getters: {
@ -98,24 +97,8 @@ const store = createStore({
catchError(state, error) {
state.errorMsg.push(error);
},
addDashboardItems(state, dashboardItems) {
state.dashboardItems = dashboardItems;
}
},
actions: {
getDashboardItems({commit, getters}, { userId }) {
const url = `/api/1.0/main/dashboard-item/${userId}.json`;
makeFetch('GET', url)
.then((response) => {
console.log('dashboardItems', response.results)
commit('addDashboardItems', response);
})
.catch((error) => {
commit('catchError', error);
throw error;
})
;
},
getByTab({ commit, getters }, { tab, param }) {
switch (tab) {
// case 'MyWorks':

View File

@ -51,7 +51,12 @@ const messages = {
years_old: "1 an | {n} an | {n} ans",
residential_address: "Adresse de résidence",
located_at: "réside chez"
}
},
widget: {
news: {
title: "Actualités"
}
}
}
};