Apply prettier rules

This commit is contained in:
2024-11-14 18:47:38 +01:00
parent 610227815a
commit aa0785fc71
291 changed files with 23646 additions and 22071 deletions

View File

@@ -1,36 +1,36 @@
<template>
<h2>{{ $t('main_title') }}</h2>
<h2>{{ $t("main_title") }}</h2>
<ul class="nav nav-tabs">
<li class="nav-item">
<a
class="nav-link"
:class="{'active': activeTab === 'MyCustoms'}"
@click="selectTab('MyCustoms')"
>
<i class="fa fa-dashboard" />
</a>
</li>
<li class="nav-item">
<a
class="nav-link"
:class="{'active': activeTab === 'MyNotifications'}"
@click="selectTab('MyNotifications')"
>
{{ $t('my_notifications.tab') }}
<tab-counter :count="state.notifications.count" />
</a>
</li>
<li class="nav-item">
<a
class="nav-link"
:class="{'active': activeTab === 'MyAccompanyingCourses'}"
@click="selectTab('MyAccompanyingCourses')"
>
{{ $t('my_accompanying_courses.tab') }}
</a>
</li>
<!-- <li class="nav-item">
<ul class="nav nav-tabs">
<li class="nav-item">
<a
class="nav-link"
:class="{ active: activeTab === 'MyCustoms' }"
@click="selectTab('MyCustoms')"
>
<i class="fa fa-dashboard" />
</a>
</li>
<li class="nav-item">
<a
class="nav-link"
:class="{ active: activeTab === 'MyNotifications' }"
@click="selectTab('MyNotifications')"
>
{{ $t("my_notifications.tab") }}
<tab-counter :count="state.notifications.count" />
</a>
</li>
<li class="nav-item">
<a
class="nav-link"
:class="{ active: activeTab === 'MyAccompanyingCourses' }"
@click="selectTab('MyAccompanyingCourses')"
>
{{ $t("my_accompanying_courses.tab") }}
</a>
</li>
<!-- <li class="nav-item">
<a class="nav-link"
:class="{'active': activeTab === 'MyWorks'}"
@click="selectTab('MyWorks')">
@@ -38,135 +38,122 @@
<tab-counter :count="state.works.count"></tab-counter>
</a>
</li> -->
<li class="nav-item">
<a
class="nav-link"
:class="{'active': activeTab === 'MyEvaluations'}"
@click="selectTab('MyEvaluations')"
>
{{ $t('my_evaluations.tab') }}
<tab-counter :count="state.evaluations.count" />
</a>
</li>
<li class="nav-item">
<a
class="nav-link"
:class="{'active': activeTab === 'MyTasks'}"
@click="selectTab('MyTasks')"
>
{{ $t('my_tasks.tab') }}
<tab-counter :count="state.tasks.warning.count + state.tasks.alert.count" />
</a>
</li>
<li class="nav-item">
<a
class="nav-link"
:class="{'active': activeTab === 'MyWorkflows'}"
@click="selectTab('MyWorkflows')"
>
{{ $t('my_workflows.tab') }}
<tab-counter :count="state.workflows.count + state.workflowsCc.count" />
</a>
</li>
<li
class="nav-item loading ms-auto py-2"
v-if="loading"
>
<i
class="fa fa-circle-o-notch fa-spin fa-lg text-chill-gray"
:title="$t('loading')"
/>
</li>
</ul>
<li class="nav-item">
<a
class="nav-link"
:class="{ active: activeTab === 'MyEvaluations' }"
@click="selectTab('MyEvaluations')"
>
{{ $t("my_evaluations.tab") }}
<tab-counter :count="state.evaluations.count" />
</a>
</li>
<li class="nav-item">
<a
class="nav-link"
:class="{ active: activeTab === 'MyTasks' }"
@click="selectTab('MyTasks')"
>
{{ $t("my_tasks.tab") }}
<tab-counter
:count="state.tasks.warning.count + state.tasks.alert.count"
/>
</a>
</li>
<li class="nav-item">
<a
class="nav-link"
:class="{ active: activeTab === 'MyWorkflows' }"
@click="selectTab('MyWorkflows')"
>
{{ $t("my_workflows.tab") }}
<tab-counter
:count="state.workflows.count + state.workflowsCc.count"
/>
</a>
</li>
<li class="nav-item loading ms-auto py-2" v-if="loading">
<i
class="fa fa-circle-o-notch fa-spin fa-lg text-chill-gray"
:title="$t('loading')"
/>
</li>
</ul>
<div class="my-4">
<my-customs
v-if="activeTab === 'MyCustoms'"
/>
<my-works
v-else-if="activeTab === 'MyWorks'"
/>
<my-evaluations
v-else-if="activeTab === 'MyEvaluations'"
/>
<my-tasks
v-else-if="activeTab === 'MyTasks'"
/>
<my-accompanying-courses
v-else-if="activeTab === 'MyAccompanyingCourses'"
/>
<my-notifications
v-else-if="activeTab === 'MyNotifications'"
/>
<my-workflows
v-else-if="activeTab === 'MyWorkflows'"
/>
</div>
<div class="my-4">
<my-customs v-if="activeTab === 'MyCustoms'" />
<my-works v-else-if="activeTab === 'MyWorks'" />
<my-evaluations v-else-if="activeTab === 'MyEvaluations'" />
<my-tasks v-else-if="activeTab === 'MyTasks'" />
<my-accompanying-courses
v-else-if="activeTab === 'MyAccompanyingCourses'"
/>
<my-notifications v-else-if="activeTab === 'MyNotifications'" />
<my-workflows v-else-if="activeTab === 'MyWorkflows'" />
</div>
</template>
<script>
import MyCustoms from './MyCustoms';
import MyWorks from './MyWorks';
import MyEvaluations from './MyEvaluations';
import MyTasks from './MyTasks';
import MyAccompanyingCourses from './MyAccompanyingCourses';
import MyNotifications from './MyNotifications';
import MyWorkflows from './MyWorkflows.vue';
import TabCounter from './TabCounter';
import MyCustoms from "./MyCustoms";
import MyWorks from "./MyWorks";
import MyEvaluations from "./MyEvaluations";
import MyTasks from "./MyTasks";
import MyAccompanyingCourses from "./MyAccompanyingCourses";
import MyNotifications from "./MyNotifications";
import MyWorkflows from "./MyWorkflows.vue";
import TabCounter from "./TabCounter";
import { mapState } from "vuex";
export default {
name: "App",
components: {
MyCustoms,
MyWorks,
MyEvaluations,
MyTasks,
MyWorkflows,
MyAccompanyingCourses,
MyNotifications,
TabCounter,
},
data() {
return {
activeTab: 'MyCustoms',
}
},
computed: {
...mapState([
'loading',
]),
// just to see all in devtool :
...mapState({
state: (state) => state,
}),
},
methods: {
selectTab(tab) {
if (tab !== 'MyCustoms') {
this.$store.dispatch('getByTab', { tab: tab });
}
this.activeTab = tab;
console.log(this.activeTab)
}
},
mounted() {
for (const m of [
'MyNotifications',
'MyAccompanyingCourses',
// 'MyWorks',
'MyEvaluations',
'MyTasks',
'MyWorkflows',
]) {
this.$store.dispatch('getByTab', { tab: m, param: "countOnly=1" });
}
}
}
name: "App",
components: {
MyCustoms,
MyWorks,
MyEvaluations,
MyTasks,
MyWorkflows,
MyAccompanyingCourses,
MyNotifications,
TabCounter,
},
data() {
return {
activeTab: "MyCustoms",
};
},
computed: {
...mapState(["loading"]),
// just to see all in devtool :
...mapState({
state: (state) => state,
}),
},
methods: {
selectTab(tab) {
if (tab !== "MyCustoms") {
this.$store.dispatch("getByTab", { tab: tab });
}
this.activeTab = tab;
console.log(this.activeTab);
},
},
mounted() {
for (const m of [
"MyNotifications",
"MyAccompanyingCourses",
// 'MyWorks',
"MyEvaluations",
"MyTasks",
"MyWorkflows",
]) {
this.$store.dispatch("getByTab", { tab: m, param: "countOnly=1" });
}
},
};
</script>
<style scoped>
a.nav-link {
cursor: pointer;
cursor: pointer;
}
</style>

View File

@@ -1,24 +1,25 @@
<template>
<div>
<h1>{{ $t('widget.news.title') }}</h1>
<h1>{{ $t("widget.news.title") }}</h1>
<ul v-if="newsItems.length > 0" class="scrollable">
<NewsItem v-for="item in newsItems" :item="item" :key="item.id" />
</ul>
<p v-if="newsItems.length === 0 " class="chill-no-data-statement">{{ $t('widget.news.none') }}</p>
<p v-if="newsItems.length === 0" class="chill-no-data-statement">
{{ $t("widget.news.none") }}
</p>
</div>
</template>
<script setup lang="ts">
import { onMounted, ref } from 'vue'
import { fetchResults } from '../../../lib/api/apiMethods';
import { NewsItemType } from '../../../types';
import NewsItem from './NewsItem.vue';
import { onMounted, ref } from "vue";
import { fetchResults } from "../../../lib/api/apiMethods";
import { NewsItemType } from "../../../types";
import NewsItem from "./NewsItem.vue";
const newsItems = ref<NewsItemType[]>([])
const newsItems = ref<NewsItemType[]>([]);
onMounted(() => {
fetchResults<NewsItemType>('/api/1.0/main/news/current.json')
fetchResults<NewsItemType>("/api/1.0/main/news/current.json")
.then((news): Promise<void> => {
// console.log('news articles', response.results)
newsItems.value = news;
@@ -26,10 +27,9 @@ onMounted(() => {
return Promise.resolve();
})
.catch((error: string) => {
console.error('Error fetching news items', error);
})
})
console.error("Error fetching news items", error);
});
});
</script>
<style scoped>
@@ -41,6 +41,4 @@ ul {
h1 {
text-align: center;
}
</style>

View File

@@ -1,11 +1,18 @@
<template>
<li>
<h2>{{ props.item.title }}</h2>
<time class="createdBy" datetime="{{item.startDate.datetime}}">{{ $d(newsItemStartDate(), 'text') }}</time>
<time class="createdBy" datetime="{{item.startDate.datetime}}">{{
$d(newsItemStartDate(), "text")
}}</time>
<div class="content" v-if="shouldTruncate(item.content)">
<div v-html="prepareContent(item.content)"></div>
<div class="float-end">
<button class="btn btn-sm btn-show read-more" @click="() => openModal(item)">{{ $t('widget.news.readMore') }}</button>
<button
class="btn btn-sm btn-show read-more"
@click="() => openModal(item)"
>
{{ $t("widget.news.readMore") }}
</button>
</div>
</div>
<div class="content" v-else>
@@ -18,7 +25,11 @@
</template>
<template #body>
<p class="news-date">
<time class="createdBy" datetime="{{item.startDate.datetime}}">{{ $d(newsItemStartDate(), 'text') }}</time>
<time
class="createdBy"
datetime="{{item.startDate.datetime}}"
>{{ $d(newsItemStartDate(), "text") }}</time
>
</p>
<div v-html="convertMarkdownToHtml(item.content)"></div>
</template>
@@ -28,18 +39,17 @@
<script setup lang="ts">
import Modal from "ChillMainAssets/vuejs/_components/Modal.vue";
import { marked } from 'marked';
import DOMPurify from 'dompurify';
import { marked } from "marked";
import DOMPurify from "dompurify";
import { NewsItemType } from "../../../types";
import type { PropType } from 'vue'
import type { PropType } from "vue";
import { ref } from "vue";
import {ISOToDatetime} from '../../../chill/js/date';
import { ISOToDatetime } from "../../../chill/js/date";
const props = defineProps({
item: {
type: Object as PropType<NewsItemType>,
required: true
required: true,
},
maxLength: {
type: Number,
@@ -49,9 +59,9 @@ const props = defineProps({
maxLines: {
type: Number,
required: false,
default: 3
}
})
default: 3,
},
});
const selectedArticle = ref<NewsItemType | null>(null);
const showModal = ref(false);
@@ -67,7 +77,7 @@ const closeModal = () => {
};
const shouldTruncate = (content: string): boolean => {
const lines = content.split('\n');
const lines = content.split("\n");
// Check if any line exceeds the maximum length
const tooManyLines = lines.length > props.maxLines;
@@ -79,67 +89,74 @@ const truncateContent = (content: string): string => {
let truncatedContent = content.slice(0, props.maxLength);
let linkDepth = 0;
let linkStartIndex = -1;
const lines = content.split('\n');
const lines = content.split("\n");
// Truncate if amount of lines are too many
if (lines.length > props.maxLines && content.length < props.maxLength) {
const truncatedContent = lines.slice(0, props.maxLines).join('\n').trim();
return truncatedContent + '...';
const truncatedContent = lines
.slice(0, props.maxLines)
.join("\n")
.trim();
return truncatedContent + "...";
}
for (let i = 0; i < truncatedContent.length; i++) {
const char = truncatedContent[i];
if (char === '[') {
if (char === "[") {
linkDepth++;
if (linkDepth === 1) {
linkStartIndex = i;
}
} else if (char === ']') {
} else if (char === "]") {
linkDepth = Math.max(0, linkDepth - 1);
} else if (char === '(' && linkDepth === 0) {
} else if (char === "(" && linkDepth === 0) {
truncatedContent = truncatedContent.slice(0, i);
break;
}
}
while (linkDepth > 0) {
truncatedContent += ']';
truncatedContent += "]";
linkDepth--;
}
// If a link was found, append the URL inside the parentheses
if (linkStartIndex !== -1) {
const linkEndIndex = content.indexOf(')', linkStartIndex);
const linkEndIndex = content.indexOf(")", linkStartIndex);
const url = content.slice(linkStartIndex + 1, linkEndIndex);
truncatedContent = truncatedContent.slice(0, linkStartIndex) + `(${url})`;
truncatedContent =
truncatedContent.slice(0, linkStartIndex) + `(${url})`;
}
truncatedContent += '...';
truncatedContent += "...";
return truncatedContent;
};
const preprocess = (markdown: string): string => {
return markdown;
}
};
const postprocess = (html: string): string => {
DOMPurify.addHook('afterSanitizeAttributes', (node: any) => {
if ('target' in node) {
node.setAttribute('target', '_blank');
node.setAttribute('rel', 'noopener noreferrer');
DOMPurify.addHook("afterSanitizeAttributes", (node: any) => {
if ("target" in node) {
node.setAttribute("target", "_blank");
node.setAttribute("rel", "noopener noreferrer");
}
if (!node.hasAttribute('target') && (node.hasAttribute('xlink:href') || node.hasAttribute('href'))) {
node.setAttribute('xlink:show', 'new');
if (
!node.hasAttribute("target") &&
(node.hasAttribute("xlink:href") || node.hasAttribute("href"))
) {
node.setAttribute("xlink:show", "new");
}
})
});
return DOMPurify.sanitize(html);
}
};
const convertMarkdownToHtml = (markdown: string): string => {
marked.use({'hooks': {postprocess, preprocess}, 'async': false});
marked.use({ hooks: { postprocess, preprocess }, async: false });
const rawHtml = marked(markdown) as string;
return rawHtml;
};
@@ -149,18 +166,16 @@ const prepareContent = (content: string): string => {
return truncateContent(htmlContent);
};
const newsItemStartDate = (): null|Date => {
const newsItemStartDate = (): null | Date => {
return ISOToDatetime(props.item?.startDate.datetime);
}
};
</script>
<style scoped>
li {
margin-bottom: 20px;
overflow: hidden;
padding: .8rem;
padding: 0.8rem;
background-color: #fbfbfb;
border-radius: 4px;
}
@@ -172,12 +187,11 @@ h2 {
.content {
overflow: hidden;
font-size: .9rem;
font-size: 0.9rem;
position: relative;
}
.news-title {
font-weight: bold;
}
</style>

View File

@@ -1,116 +1,110 @@
<template>
<div class="alert alert-light">
{{ $t('my_accompanying_courses.description') }}
</div>
<span
v-if="noResults"
class="chill-no-data-statement"
>{{ $t('no_data') }}</span>
<tab-table v-else>
<template #thead>
<th scope="col">
{{ $t('opening_date') }}
</th>
<th scope="col">
{{ $t('social_issues') }}
</th>
<th scope="col">
{{ $t('concerned_persons') }}
</th>
<th scope="col" />
<th scope="col" />
</template>
<template #tbody>
<tr
v-for="(c, i) in accompanyingCourses.results"
:key="`course-${i}`"
>
<td>{{ $d(c.openingDate.datetime, 'short') }}</td>
<td>
<span
v-for="(i, index) in c.socialIssues"
:key="index"
class="chill-entity entity-social-issue"
>
<span class="badge bg-chill-l-gray text-dark">
{{ i.title.fr }}
</span>
</span>
</td>
<td>
<span
v-for="p in c.participations"
class="me-1"
:key="p.person.id"
>
<on-the-fly
:type="p.person.type"
:id="p.person.id"
:button-text="p.person.textAge"
:display-badge="'true' === 'true'"
action="show"
/>
</span>
</td>
<td>
<span
v-if="c.emergency"
class="badge rounded-pill bg-danger me-1"
>{{ $t('emergency') }}</span>
<span
v-if="c.confidential"
class="badge rounded-pill bg-danger"
>{{ $t('confidential') }}</span>
</td>
<td>
<a
class="btn btn-sm btn-show"
:href="getUrl(c)"
>
{{ $t('show_entity', { entity: $t('the_course') }) }}
</a>
</td>
</tr>
</template>
</tab-table>
<div class="alert alert-light">
{{ $t("my_accompanying_courses.description") }}
</div>
<span v-if="noResults" class="chill-no-data-statement">{{
$t("no_data")
}}</span>
<tab-table v-else>
<template #thead>
<th scope="col">
{{ $t("opening_date") }}
</th>
<th scope="col">
{{ $t("social_issues") }}
</th>
<th scope="col">
{{ $t("concerned_persons") }}
</th>
<th scope="col" />
<th scope="col" />
</template>
<template #tbody>
<tr
v-for="(c, i) in accompanyingCourses.results"
:key="`course-${i}`"
>
<td>{{ $d(c.openingDate.datetime, "short") }}</td>
<td>
<span
v-for="(i, index) in c.socialIssues"
:key="index"
class="chill-entity entity-social-issue"
>
<span class="badge bg-chill-l-gray text-dark">
{{ i.title.fr }}
</span>
</span>
</td>
<td>
<span
v-for="p in c.participations"
class="me-1"
:key="p.person.id"
>
<on-the-fly
:type="p.person.type"
:id="p.person.id"
:button-text="p.person.textAge"
:display-badge="'true' === 'true'"
action="show"
/>
</span>
</td>
<td>
<span
v-if="c.emergency"
class="badge rounded-pill bg-danger me-1"
>{{ $t("emergency") }}</span
>
<span
v-if="c.confidential"
class="badge rounded-pill bg-danger"
>{{ $t("confidential") }}</span
>
</td>
<td>
<a class="btn btn-sm btn-show" :href="getUrl(c)">
{{ $t("show_entity", { entity: $t("the_course") }) }}
</a>
</td>
</tr>
</template>
</tab-table>
</template>
<script>
import { mapState, mapGetters } from "vuex";
import TabTable from "./TabTable";
import OnTheFly from 'ChillMainAssets/vuejs/OnTheFly/components/OnTheFly';
import OnTheFly from "ChillMainAssets/vuejs/OnTheFly/components/OnTheFly";
export default {
name: "MyAccompanyingCourses",
components: {
TabTable,
OnTheFly,
},
computed: {
...mapState([
'accompanyingCourses',
]),
...mapGetters([
'isAccompanyingCoursesLoaded',
]),
noResults() {
if (!this.isAccompanyingCoursesLoaded) {
return false;
} else {
return this.accompanyingCourses.count === 0;
}
},
},
methods: {
getUrl(c) {
return `/fr/parcours/${c.id}`
}
}
}
name: "MyAccompanyingCourses",
components: {
TabTable,
OnTheFly,
},
computed: {
...mapState(["accompanyingCourses"]),
...mapGetters(["isAccompanyingCoursesLoaded"]),
noResults() {
if (!this.isAccompanyingCoursesLoaded) {
return false;
} else {
return this.accompanyingCourses.count === 0;
}
},
},
methods: {
getUrl(c) {
return `/fr/parcours/${c.id}`;
},
},
};
</script>
<style scoped>
span.badge.rounded-pill.bg-danger {
text-transform: uppercase;
text-transform: uppercase;
}
</style>

View File

@@ -1,158 +1,158 @@
<template>
<span
v-if="noResults"
class="chill-no-data-statement"
>{{ $t('no_dashboard') }}</span>
<div
v-else
id="dashboards"
class="container g-3"
>
<div class="row">
<div class="mbloc col-xs-12 col-sm-4">
<div class="custom1">
<ul class="list-unstyled">
<li v-if="counter.notifications > 0">
<i18n-t
keypath="counter.unread_notifications"
tag="span"
:class="counterClass"
:plural="counter.notifications"
>
<template #n>
<span>{{ counter.notifications }}</span>
</template>
</i18n-t>
</li>
<li v-if="counter.accompanyingCourses > 0">
<i18n-t
keypath="counter.assignated_courses"
tag="span"
:class="counterClass"
:plural="counter.accompanyingCourses"
>
<template #n>
<span>{{ counter.accompanyingCourses }}</span>
</template>
</i18n-t>
</li>
<li v-if="counter.works > 0">
<i18n-t
keypath="counter.assignated_actions"
tag="span"
:class="counterClass"
:plural="counter.works"
>
<template #n>
<span>{{ counter.works }}</span>
</template>
</i18n-t>
</li>
<li v-if="counter.evaluations > 0">
<i18n-t
keypath="counter.assignated_evaluations"
tag="span"
:class="counterClass"
:plural="counter.evaluations"
>
<template #n>
<span>{{ counter.evaluations }}</span>
</template>
</i18n-t>
</li>
<li v-if="counter.tasksAlert > 0">
<i18n-t
keypath="counter.alert_tasks"
tag="span"
:class="counterClass"
:plural="counter.tasksAlert"
>
<template #n>
<span>{{ counter.tasksAlert }}</span>
</template>
</i18n-t>
</li>
<li v-if="counter.tasksWarning > 0">
<i18n-t
keypath="counter.warning_tasks"
tag="span"
:class="counterClass"
:plural="counter.tasksWarning"
>
<template #n>
<span>{{ counter.tasksWarning }}</span>
</template>
</i18n-t>
</li>
</ul>
</div>
</div>
<span v-if="noResults" class="chill-no-data-statement">{{
$t("no_dashboard")
}}</span>
<div v-else id="dashboards" class="container g-3">
<div class="row">
<div class="mbloc col-xs-12 col-sm-4">
<div class="custom1">
<ul class="list-unstyled">
<li v-if="counter.notifications > 0">
<i18n-t
keypath="counter.unread_notifications"
tag="span"
:class="counterClass"
:plural="counter.notifications"
>
<template #n>
<span>{{ counter.notifications }}</span>
</template>
</i18n-t>
</li>
<li v-if="counter.accompanyingCourses > 0">
<i18n-t
keypath="counter.assignated_courses"
tag="span"
:class="counterClass"
:plural="counter.accompanyingCourses"
>
<template #n>
<span>{{
counter.accompanyingCourses
}}</span>
</template>
</i18n-t>
</li>
<li v-if="counter.works > 0">
<i18n-t
keypath="counter.assignated_actions"
tag="span"
:class="counterClass"
:plural="counter.works"
>
<template #n>
<span>{{ counter.works }}</span>
</template>
</i18n-t>
</li>
<li v-if="counter.evaluations > 0">
<i18n-t
keypath="counter.assignated_evaluations"
tag="span"
:class="counterClass"
:plural="counter.evaluations"
>
<template #n>
<span>{{ counter.evaluations }}</span>
</template>
</i18n-t>
</li>
<li v-if="counter.tasksAlert > 0">
<i18n-t
keypath="counter.alert_tasks"
tag="span"
:class="counterClass"
:plural="counter.tasksAlert"
>
<template #n>
<span>{{ counter.tasksAlert }}</span>
</template>
</i18n-t>
</li>
<li v-if="counter.tasksWarning > 0">
<i18n-t
keypath="counter.warning_tasks"
tag="span"
:class="counterClass"
:plural="counter.tasksWarning"
>
<template #n>
<span>{{ counter.tasksWarning }}</span>
</template>
</i18n-t>
</li>
</ul>
</div>
</div>
<template v-if="this.hasDashboardItems">
<template v-for="(dashboardItem, index) in this.dashboardItems" :key="index">
<div
class="mbloc col-xs-12 col-sm-8 news"
v-if="dashboardItem.type === 'news'"
>
<News />
</div>
</template>
</template>
<template v-if="this.hasDashboardItems">
<template
v-for="(dashboardItem, index) in this.dashboardItems"
:key="index"
>
<div
class="mbloc col-xs-12 col-sm-8 news"
v-if="dashboardItem.type === 'news'"
>
<News />
</div>
</template>
</template>
</div>
</div>
</div>
</template>
<script>
import { mapGetters } from "vuex";
import {makeFetch} from "ChillMainAssets/lib/api/apiMethods";
import News from './DashboardWidgets/News.vue';
import { makeFetch } from "ChillMainAssets/lib/api/apiMethods";
import News from "./DashboardWidgets/News.vue";
export default {
name: "MyCustoms",
name: "MyCustoms",
components: {
News
News,
},
data() {
return {
counterClass: {
counter: true //hack to pass class 'counter' in i18n-t
},
dashboardItems: [],
masonry: null,
}
},
computed: {
...mapGetters(['counter']),
noResults() {
return false
},
hasDashboardItems() {
return this.dashboardItems.length > 0;
}
},
mounted() {
makeFetch('GET', '/api/1.0/main/dashboard-config-item.json')
.then((response) => {
this.dashboardItems = response;
})
.catch((error) => {
throw error
});
},
}
data() {
return {
counterClass: {
counter: true, //hack to pass class 'counter' in i18n-t
},
dashboardItems: [],
masonry: null,
};
},
computed: {
...mapGetters(["counter"]),
noResults() {
return false;
},
hasDashboardItems() {
return this.dashboardItems.length > 0;
},
},
mounted() {
makeFetch("GET", "/api/1.0/main/dashboard-config-item.json")
.then((response) => {
this.dashboardItems = response;
})
.catch((error) => {
throw error;
});
},
};
</script>
<style lang="scss" scoped>
div.custom4,
div.custom3,
div.custom2 {
font-style: italic;
color: var(--bs-chill-gray);
font-style: italic;
color: var(--bs-chill-gray);
}
span.counter {
& > span {
background-color: unset;
}
& > span {
background-color: unset;
}
}
div.news {

View File

@@ -1,130 +1,136 @@
<template>
<div class="accompanying-course-work">
<div class="alert alert-light">
{{ $t('my_evaluations.description') }}
<div class="accompanying-course-work">
<div class="alert alert-light">
{{ $t("my_evaluations.description") }}
</div>
<span v-if="noResults" class="chill-no-data-statement">{{
$t("no_data")
}}</span>
<tab-table v-else>
<template #thead>
<th scope="col">
{{ $t("max_date") }}
</th>
<th scope="col">
{{ $t("evaluation") }}
</th>
<th scope="col">
{{ $t("SocialAction") }}
</th>
<th scope="col" />
</template>
<template #tbody>
<tr
v-for="(e, i) in evaluations.results"
:key="`evaluation-${i}`"
>
<td>{{ $d(e.maxDate.datetime, "short") }}</td>
<td>
{{ e.evaluation.title.fr }}
</td>
<td>
<span class="chill-entity entity-social-issue">
<span class="badge bg-chill-l-gray text-dark">
{{
e.accompanyingPeriodWork.socialAction.issue
.text
}}
</span>
</span>
<h4 class="badge-title">
<span class="title_label" />
<span class="title_action">
{{ e.accompanyingPeriodWork.socialAction.text }}
</span>
</h4>
<span
v-for="person in e.accompanyingPeriodWork.persons"
class="me-1"
:key="person.id"
>
<on-the-fly
:type="person.type"
:id="person.id"
:button-text="person.textAge"
:display-badge="'true' === 'true'"
action="show"
/>
</span>
</td>
<td>
<div
class="btn-group-vertical"
role="group"
aria-label="Actions"
>
<a class="btn btn-sm btn-show" :href="getUrl(e)">
{{
$t("show_entity", {
entity: $t("the_evaluation"),
})
}}
</a>
<a
class="btn btn-sm btn-show"
:href="
getUrl(
e.accompanyingPeriodWork
.accompanyingPeriod,
)
"
>
{{
$t("show_entity", {
entity: $t("the_course"),
})
}}
</a>
</div>
</td>
</tr>
</template>
</tab-table>
</div>
<span
v-if="noResults"
class="chill-no-data-statement"
>{{ $t('no_data') }}</span>
<tab-table v-else>
<template #thead>
<th scope="col">
{{ $t('max_date') }}
</th>
<th scope="col">
{{ $t('evaluation') }}
</th>
<th scope="col">
{{ $t('SocialAction') }}
</th>
<th scope="col" />
</template>
<template #tbody>
<tr
v-for="(e, i) in evaluations.results"
:key="`evaluation-${i}`"
>
<td>{{ $d(e.maxDate.datetime, 'short') }}</td>
<td>
{{ e.evaluation.title.fr }}
</td>
<td>
<span class="chill-entity entity-social-issue">
<span class="badge bg-chill-l-gray text-dark">
{{ e.accompanyingPeriodWork.socialAction.issue.text }}
</span>
</span>
<h4 class="badge-title">
<span class="title_label" />
<span class="title_action">
{{ e.accompanyingPeriodWork.socialAction.text }}
</span>
</h4>
<span
v-for="person in e.accompanyingPeriodWork.persons"
class="me-1"
:key="person.id"
>
<on-the-fly
:type="person.type"
:id="person.id"
:button-text="person.textAge"
:display-badge="'true' === 'true'"
action="show"
/>
</span>
</td>
<td>
<div
class="btn-group-vertical"
role="group"
aria-label="Actions"
>
<a
class="btn btn-sm btn-show"
:href="getUrl(e)"
>
{{ $t('show_entity', { entity: $t('the_evaluation') }) }}
</a>
<a
class="btn btn-sm btn-show"
:href="getUrl(e.accompanyingPeriodWork.accompanyingPeriod)"
>
{{ $t('show_entity', { entity: $t('the_course') }) }}
</a>
</div>
</td>
</tr>
</template>
</tab-table>
</div>
</template>
<script>
import { mapState, mapGetters } from "vuex";
import TabTable from "./TabTable";
import OnTheFly from 'ChillMainAssets/vuejs/OnTheFly/components/OnTheFly';
import OnTheFly from "ChillMainAssets/vuejs/OnTheFly/components/OnTheFly";
export default {
name: "MyEvaluations",
components: {
TabTable,
OnTheFly,
},
computed: {
...mapState([
'evaluations',
]),
...mapGetters([
'isEvaluationsLoaded',
]),
noResults() {
if (!this.isEvaluationsLoaded) {
return false;
} else {
return this.evaluations.count === 0;
}
}
},
methods: {
getUrl(e) {
switch (e.type) {
case 'accompanying_period_work_evaluation':
let anchor = '#evaluations';
return `/fr/person/accompanying-period/work/${e.accompanyingPeriodWork.id}/edit${anchor}`;
case 'accompanying_period_work':
return `/fr/person/accompanying-period/work/${e.id}/edit`
case 'accompanying_period':
return `/fr/parcours/${e.id}`
default:
throw 'entity type unknown';
}
}
},
}
name: "MyEvaluations",
components: {
TabTable,
OnTheFly,
},
computed: {
...mapState(["evaluations"]),
...mapGetters(["isEvaluationsLoaded"]),
noResults() {
if (!this.isEvaluationsLoaded) {
return false;
} else {
return this.evaluations.count === 0;
}
},
},
methods: {
getUrl(e) {
switch (e.type) {
case "accompanying_period_work_evaluation":
let anchor = "#evaluations";
return `/fr/person/accompanying-period/work/${e.accompanyingPeriodWork.id}/edit${anchor}`;
case "accompanying_period_work":
return `/fr/person/accompanying-period/work/${e.id}/edit`;
case "accompanying_period":
return `/fr/parcours/${e.id}`;
default:
throw "entity type unknown";
}
},
},
};
</script>
<style scoped>
</style>
<style scoped></style>

View File

@@ -1,129 +1,117 @@
<template>
<div class="alert alert-light">
{{ $t('my_notifications.description') }}
</div>
<span
v-if="noResults"
class="chill-no-data-statement"
>{{ $t('no_data') }}</span>
<tab-table v-else>
<template #thead>
<th scope="col">
{{ $t('Date') }}
</th>
<th scope="col">
{{ $t('Subject') }}
</th>
<th scope="col">
{{ $t('From') }}
</th>
<th scope="col" />
</template>
<template #tbody>
<tr
v-for="(n, i) in notifications.results"
:key="`notify-${i}`"
>
<td>{{ $d(n.date.datetime, 'long') }}</td>
<td>
<span class="unread">
<i class="fa fa-envelope-o" />
<a :href="getNotificationUrl(n)">{{ n.title }}</a>
</span>
</td>
<td v-if="n.sender != null">
{{ n.sender.text }}
</td>
<td v-else>
{{ $t('automatic_notification') }}
</td>
<td>
<a
class="btn btn-sm btn-show"
:href="getEntityUrl(n)"
>
{{ $t('show_entity', { entity: getEntityName(n) }) }}
</a>
</td>
</tr>
</template>
</tab-table>
<div class="alert alert-light">
{{ $t("my_notifications.description") }}
</div>
<span v-if="noResults" class="chill-no-data-statement">{{
$t("no_data")
}}</span>
<tab-table v-else>
<template #thead>
<th scope="col">
{{ $t("Date") }}
</th>
<th scope="col">
{{ $t("Subject") }}
</th>
<th scope="col">
{{ $t("From") }}
</th>
<th scope="col" />
</template>
<template #tbody>
<tr v-for="(n, i) in notifications.results" :key="`notify-${i}`">
<td>{{ $d(n.date.datetime, "long") }}</td>
<td>
<span class="unread">
<i class="fa fa-envelope-o" />
<a :href="getNotificationUrl(n)">{{ n.title }}</a>
</span>
</td>
<td v-if="n.sender != null">
{{ n.sender.text }}
</td>
<td v-else>
{{ $t("automatic_notification") }}
</td>
<td>
<a class="btn btn-sm btn-show" :href="getEntityUrl(n)">
{{ $t("show_entity", { entity: getEntityName(n) }) }}
</a>
</td>
</tr>
</template>
</tab-table>
</template>
<script>
import { mapState, mapGetters } from "vuex";
import TabTable from "./TabTable";
import { appMessages } from 'ChillMainAssets/vuejs/HomepageWidget/js/i18n';
import { appMessages } from "ChillMainAssets/vuejs/HomepageWidget/js/i18n";
export default {
name: "MyNotifications",
components: {
TabTable
},
computed: {
...mapState([
'notifications',
]),
...mapGetters([
'isNotificationsLoaded',
]),
noResults() {
if (!this.isNotificationsLoaded) {
return false;
} else {
return this.notifications.count === 0;
}
}
},
methods: {
getNotificationUrl(n) {
return `/fr/notification/${n.id}/show`
},
getEntityName(n) {
switch (n.relatedEntityClass) {
case 'Chill\\ActivityBundle\\Entity\\Activity':
return appMessages.fr.the_activity;
case 'Chill\\PersonBundle\\Entity\\AccompanyingPeriod':
return appMessages.fr.the_course;
case 'Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWork':
return appMessages.fr.the_action;
case 'Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWorkEvaluationDocument':
return appMessages.fr.the_evaluation_document;
case 'Chill\\MainBundle\\Entity\\Workflow\\EntityWorkflow':
return appMessages.fr.the_workflow;
default:
throw 'notification type unknown';
}
},
getEntityUrl(n) {
switch (n.relatedEntityClass) {
case 'Chill\\ActivityBundle\\Entity\\Activity':
return `/fr/activity/${n.relatedEntityId}/show`
case 'Chill\\PersonBundle\\Entity\\AccompanyingPeriod':
return `/fr/parcours/${n.relatedEntityId}`
case 'Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWork':
return `/fr/person/accompanying-period/work/${n.relatedEntityId}/show`
case 'Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWorkEvaluationDocument':
return `/fr/person/accompanying-period/work/evaluation/document/${n.relatedEntityId}/show`
case 'Chill\\MainBundle\\Entity\\Workflow\\EntityWorkflow':
return `/fr/main/workflow/${n.relatedEntityId}/show`
default:
throw 'notification type unknown';
}
}
}
}
name: "MyNotifications",
components: {
TabTable,
},
computed: {
...mapState(["notifications"]),
...mapGetters(["isNotificationsLoaded"]),
noResults() {
if (!this.isNotificationsLoaded) {
return false;
} else {
return this.notifications.count === 0;
}
},
},
methods: {
getNotificationUrl(n) {
return `/fr/notification/${n.id}/show`;
},
getEntityName(n) {
switch (n.relatedEntityClass) {
case "Chill\\ActivityBundle\\Entity\\Activity":
return appMessages.fr.the_activity;
case "Chill\\PersonBundle\\Entity\\AccompanyingPeriod":
return appMessages.fr.the_course;
case "Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWork":
return appMessages.fr.the_action;
case "Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWorkEvaluationDocument":
return appMessages.fr.the_evaluation_document;
case "Chill\\MainBundle\\Entity\\Workflow\\EntityWorkflow":
return appMessages.fr.the_workflow;
default:
throw "notification type unknown";
}
},
getEntityUrl(n) {
switch (n.relatedEntityClass) {
case "Chill\\ActivityBundle\\Entity\\Activity":
return `/fr/activity/${n.relatedEntityId}/show`;
case "Chill\\PersonBundle\\Entity\\AccompanyingPeriod":
return `/fr/parcours/${n.relatedEntityId}`;
case "Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWork":
return `/fr/person/accompanying-period/work/${n.relatedEntityId}/show`;
case "Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWorkEvaluationDocument":
return `/fr/person/accompanying-period/work/evaluation/document/${n.relatedEntityId}/show`;
case "Chill\\MainBundle\\Entity\\Workflow\\EntityWorkflow":
return `/fr/main/workflow/${n.relatedEntityId}/show`;
default:
throw "notification type unknown";
}
},
},
};
</script>
<style lang="scss" scoped>
span.unread {
font-weight: bold;
i {
margin-right: 0.5em;
}
a {
text-decoration: unset;
}
font-weight: bold;
i {
margin-right: 0.5em;
}
a {
text-decoration: unset;
}
}
</style>
</style>

View File

@@ -1,90 +1,83 @@
<template>
<div class="alert alert-light">
{{ $t('my_tasks.description_warning') }}
</div>
<span
v-if="noResultsAlert"
class="chill-no-data-statement"
>{{ $t('no_data') }}</span>
<tab-table v-else>
<template #thead>
<th scope="col">
{{ $t('warning_date') }}
</th>
<th scope="col">
{{ $t('max_date') }}
</th>
<th scope="col">
{{ $t('task') }}
</th>
<th scope="col" />
</template>
<template #tbody>
<tr
v-for="(t, i) in tasks.alert.results"
:key="`task-alert-${i}`"
>
<td v-if="null !== t.warningDate">
{{ $d(t.warningDate.datetime, 'short') }}
</td>
<td v-else />
<td>
<span class="outdated">{{ $d(t.endDate.datetime, 'short') }}</span>
</td>
<td>{{ t.title }}</td>
<td>
<a
class="btn btn-sm btn-show"
:href="getUrl(t)"
>
{{ $t('show_entity', { entity: $t('the_task') }) }}
</a>
</td>
</tr>
</template>
</tab-table>
<div class="alert alert-light">
{{ $t("my_tasks.description_warning") }}
</div>
<span v-if="noResultsAlert" class="chill-no-data-statement">{{
$t("no_data")
}}</span>
<tab-table v-else>
<template #thead>
<th scope="col">
{{ $t("warning_date") }}
</th>
<th scope="col">
{{ $t("max_date") }}
</th>
<th scope="col">
{{ $t("task") }}
</th>
<th scope="col" />
</template>
<template #tbody>
<tr v-for="(t, i) in tasks.alert.results" :key="`task-alert-${i}`">
<td v-if="null !== t.warningDate">
{{ $d(t.warningDate.datetime, "short") }}
</td>
<td v-else />
<td>
<span class="outdated">{{
$d(t.endDate.datetime, "short")
}}</span>
</td>
<td>{{ t.title }}</td>
<td>
<a class="btn btn-sm btn-show" :href="getUrl(t)">
{{ $t("show_entity", { entity: $t("the_task") }) }}
</a>
</td>
</tr>
</template>
</tab-table>
<div class="alert alert-light">
{{ $t('my_tasks.description_alert') }}
</div>
<span
v-if="noResultsWarning"
class="chill-no-data-statement"
>{{ $t('no_data') }}</span>
<tab-table v-else>
<template #thead>
<th scope="col">
{{ $t('warning_date') }}
</th>
<th scope="col">
{{ $t('max_date') }}
</th>
<th scope="col">
{{ $t('task') }}
</th>
<th scope="col" />
</template>
<template #tbody>
<tr
v-for="(t, i) in tasks.warning.results"
:key="`task-warning-${i}`"
>
<td>
<span class="outdated">{{ $d(t.warningDate.datetime, 'short') }}</span>
</td>
<td>{{ $d(t.endDate.datetime, 'short') }}</td>
<td>{{ t.title }}</td>
<td>
<a
class="btn btn-sm btn-show"
:href="getUrl(t)"
>
{{ $t('show_entity', { entity: $t('the_task') }) }}
</a>
</td>
</tr>
</template>
</tab-table>
<div class="alert alert-light">
{{ $t("my_tasks.description_alert") }}
</div>
<span v-if="noResultsWarning" class="chill-no-data-statement">{{
$t("no_data")
}}</span>
<tab-table v-else>
<template #thead>
<th scope="col">
{{ $t("warning_date") }}
</th>
<th scope="col">
{{ $t("max_date") }}
</th>
<th scope="col">
{{ $t("task") }}
</th>
<th scope="col" />
</template>
<template #tbody>
<tr
v-for="(t, i) in tasks.warning.results"
:key="`task-warning-${i}`"
>
<td>
<span class="outdated">{{
$d(t.warningDate.datetime, "short")
}}</span>
</td>
<td>{{ $d(t.endDate.datetime, "short") }}</td>
<td>{{ t.title }}</td>
<td>
<a class="btn btn-sm btn-show" :href="getUrl(t)">
{{ $t("show_entity", { entity: $t("the_task") }) }}
</a>
</td>
</tr>
</template>
</tab-table>
</template>
<script>
@@ -92,44 +85,39 @@ import { mapState, mapGetters } from "vuex";
import TabTable from "./TabTable";
export default {
name: "MyTasks",
components: {
TabTable
},
computed: {
...mapState([
'tasks',
]),
...mapGetters([
'isTasksWarningLoaded',
'isTasksAlertLoaded',
]),
noResultsAlert() {
if (!this.isTasksAlertLoaded) {
return false;
} else {
return this.tasks.alert.count === 0;
}
},
noResultsWarning() {
if (!this.isTasksWarningLoaded) {
return false;
} else {
return this.tasks.warning.count === 0;
}
}
},
methods: {
getUrl(t) {
return `/fr/task/single-task/${t.id}/show`
}
},
}
name: "MyTasks",
components: {
TabTable,
},
computed: {
...mapState(["tasks"]),
...mapGetters(["isTasksWarningLoaded", "isTasksAlertLoaded"]),
noResultsAlert() {
if (!this.isTasksAlertLoaded) {
return false;
} else {
return this.tasks.alert.count === 0;
}
},
noResultsWarning() {
if (!this.isTasksWarningLoaded) {
return false;
} else {
return this.tasks.warning.count === 0;
}
},
},
methods: {
getUrl(t) {
return `/fr/task/single-task/${t.id}/show`;
},
},
};
</script>
<style scoped>
span.outdated {
font-weight: bold;
color: var(--bs-warning);
font-weight: bold;
color: var(--bs-warning);
}
</style>
</style>

View File

@@ -1,29 +1,26 @@
<template>
<div class="alert alert-light">
{{ $t('my_workflows.description') }}
</div>
<my-workflows-table :workflows="workflows" />
<div class="alert alert-light">
{{ $t("my_workflows.description") }}
</div>
<my-workflows-table :workflows="workflows" />
<div class="alert alert-light">
{{ $t('my_workflows.description_cc') }}
</div>
<my-workflows-table :workflows="workflowsCc" />
<div class="alert alert-light">
{{ $t("my_workflows.description_cc") }}
</div>
<my-workflows-table :workflows="workflowsCc" />
</template>
<script>
import { mapState } from "vuex";
import MyWorkflowsTable from './MyWorkflowsTable.vue';
import MyWorkflowsTable from "./MyWorkflowsTable.vue";
export default {
name: "MyWorkflows",
components: {
MyWorkflowsTable
MyWorkflowsTable,
},
computed: {
...mapState([
'workflows',
'workflowsCc',
]),
...mapState(["workflows", "workflowsCc"]),
},
}
</script>
};
</script>

View File

@@ -1,79 +1,68 @@
<template>
<span
v-if="hasNoResults(workflows)"
class="chill-no-data-statement"
>{{ $t('no_data') }}</span>
<tab-table v-else>
<template #thead>
<th scope="col">
{{ $t('Object_workflow') }}
</th>
<th scope="col">
{{ $t('Step') }}
</th>
<th scope="col">
{{ $t('concerned_users') }}
</th>
<th scope="col" />
</template>
<template #tbody>
<tr
v-for="(w, i) in workflows.results"
:key="`workflow-${i}`"
>
<td>{{ w.title }}</td>
<td>
<div class="workflow">
<div class="breadcrumb">
<i class="fa fa-circle me-1 text-chill-yellow mx-2" />
<span class="mx-2">{{ getStep(w) }}</span>
</div>
</div>
</td>
<td v-if="w.datas.persons !== null">
<span
v-for="p in w.datas.persons"
class="me-1"
:key="p.id"
>
<on-the-fly
:type="p.type"
:id="p.id"
:button-text="p.textAge"
:display-badge="'true' === 'true'"
action="show"
/>
</span>
</td>
<td>
<a
class="btn btn-sm btn-show"
:href="getUrl(w)"
>
{{ $t('show_entity', { entity: $t('the_workflow') }) }}
</a>
</td>
</tr>
</template>
</tab-table>
<span v-if="hasNoResults(workflows)" class="chill-no-data-statement">{{
$t("no_data")
}}</span>
<tab-table v-else>
<template #thead>
<th scope="col">
{{ $t("Object_workflow") }}
</th>
<th scope="col">
{{ $t("Step") }}
</th>
<th scope="col">
{{ $t("concerned_users") }}
</th>
<th scope="col" />
</template>
<template #tbody>
<tr v-for="(w, i) in workflows.results" :key="`workflow-${i}`">
<td>{{ w.title }}</td>
<td>
<div class="workflow">
<div class="breadcrumb">
<i
class="fa fa-circle me-1 text-chill-yellow mx-2"
/>
<span class="mx-2">{{ getStep(w) }}</span>
</div>
</div>
</td>
<td v-if="w.datas.persons !== null">
<span v-for="p in w.datas.persons" class="me-1" :key="p.id">
<on-the-fly
:type="p.type"
:id="p.id"
:button-text="p.textAge"
:display-badge="'true' === 'true'"
action="show"
/>
</span>
</td>
<td>
<a class="btn btn-sm btn-show" :href="getUrl(w)">
{{ $t("show_entity", { entity: $t("the_workflow") }) }}
</a>
</td>
</tr>
</template>
</tab-table>
</template>
<script>
import { mapGetters } from "vuex";
import TabTable from "./TabTable";
import OnTheFly from 'ChillMainAssets/vuejs/OnTheFly/components/OnTheFly';
import OnTheFly from "ChillMainAssets/vuejs/OnTheFly/components/OnTheFly";
export default {
name: "MyWorkflows",
components: {
TabTable,
OnTheFly
OnTheFly,
},
props: ['workflows'],
props: ["workflows"],
computed: {
...mapGetters([
'isWorkflowsLoaded',
]),
...mapGetters(["isWorkflowsLoaded"]),
},
methods: {
hasNoResults(workflows) {
@@ -87,11 +76,11 @@ export default {
return `/fr/main/workflow/${w.id}/show`;
},
getStep(w) {
const lastStep = w.steps.length - 1
const lastStep = w.steps.length - 1;
return w.steps[lastStep].currentStep.text;
}
},
},
}
};
</script>
<style scoped>

View File

@@ -1,127 +1,122 @@
// CURRENTLY NOT IN USE
<template>
<div class="accompanying-course-work">
<div class="alert alert-light">
{{ $t('my_works.description') }}
<div class="accompanying-course-work">
<div class="alert alert-light">
{{ $t("my_works.description") }}
</div>
<span v-if="noResults" class="chill-no-data-statement">{{
$t("no_data")
}}</span>
<tab-table v-else>
<template #thead>
<th scope="col">
{{ $t("StartDate") }}
</th>
<th scope="col">
{{ $t("SocialAction") }}
</th>
<th scope="col">
{{ $t("concerned_persons") }}
</th>
<th scope="col" />
</template>
<template #tbody>
<tr v-for="(w, i) in works.results" :key="`works-${i}`">
<td>{{ $d(w.startDate.datetime, "short") }}</td>
<td>
<span class="chill-entity entity-social-issue">
<span class="badge bg-chill-l-gray text-dark">
{{ w.socialAction.issue.text }}
</span>
</span>
<h4 class="badge-title">
<span class="title_label" />
<span class="title_action">
{{ w.socialAction.text }}
</span>
</h4>
</td>
<td>
<span
v-for="person in w.persons"
class="me-1"
:key="person.id"
>
<on-the-fly
:type="person.type"
:id="person.id"
:button-text="person.textAge"
:display-badge="'true' === 'true'"
action="show"
/>
</span>
</td>
<td>
<div
class="btn-group-vertical"
role="group"
aria-label="Actions"
>
<a class="btn btn-sm btn-update" :href="getUrl(w)">
{{
$t("show_entity", {
entity: $t("the_action"),
})
}}
</a>
<a
class="btn btn-sm btn-show"
:href="getUrl(w.accompanyingPeriod)"
>
{{
$t("show_entity", {
entity: $t("the_course"),
})
}}
</a>
</div>
</td>
</tr>
</template>
</tab-table>
</div>
<span
v-if="noResults"
class="chill-no-data-statement"
>{{ $t('no_data') }}</span>
<tab-table v-else>
<template #thead>
<th scope="col">
{{ $t('StartDate') }}
</th>
<th scope="col">
{{ $t('SocialAction') }}
</th>
<th scope="col">
{{ $t('concerned_persons') }}
</th>
<th scope="col" />
</template>
<template #tbody>
<tr
v-for="(w, i) in works.results"
:key="`works-${i}`"
>
<td>{{ $d(w.startDate.datetime, 'short') }}</td>
<td>
<span class="chill-entity entity-social-issue">
<span class="badge bg-chill-l-gray text-dark">
{{ w.socialAction.issue.text }}
</span>
</span>
<h4 class="badge-title">
<span class="title_label" />
<span class="title_action">
{{ w.socialAction.text }}
</span>
</h4>
</td>
<td>
<span
v-for="person in w.persons"
class="me-1"
:key="person.id"
>
<on-the-fly
:type="person.type"
:id="person.id"
:button-text="person.textAge"
:display-badge="'true' === 'true'"
action="show"
/>
</span>
</td>
<td>
<div
class="btn-group-vertical"
role="group"
aria-label="Actions"
>
<a
class="btn btn-sm btn-update"
:href="getUrl(w)"
>
{{ $t('show_entity', { entity: $t('the_action') }) }}
</a>
<a
class="btn btn-sm btn-show"
:href="getUrl(w.accompanyingPeriod)"
>
{{ $t('show_entity', { entity: $t('the_course') }) }}
</a>
</div>
</td>
</tr>
</template>
</tab-table>
</div>
</template>
<script>
import { mapState, mapGetters } from "vuex";
import TabTable from "./TabTable";
import OnTheFly from 'ChillMainAssets/vuejs/OnTheFly/components/OnTheFly';
import OnTheFly from "ChillMainAssets/vuejs/OnTheFly/components/OnTheFly";
export default {
name: "MyWorks",
components: {
TabTable,
OnTheFly,
},
computed: {
...mapState([
'works',
]),
...mapGetters([
'isWorksLoaded',
]),
noResults() {
if (!this.isWorksLoaded) {
return false;
} else {
return this.works.count === 0;
}
}
},
methods: {
getUrl(e) {
switch (e.type) {
case 'accompanying_period_work':
return `/fr/person/accompanying-period/work/${e.id}/edit`
case 'accompanying_period':
return `/fr/parcours/${e.id}`
default:
throw 'entity type unknown';
}
}
},
}
name: "MyWorks",
components: {
TabTable,
OnTheFly,
},
computed: {
...mapState(["works"]),
...mapGetters(["isWorksLoaded"]),
noResults() {
if (!this.isWorksLoaded) {
return false;
} else {
return this.works.count === 0;
}
},
},
methods: {
getUrl(e) {
switch (e.type) {
case "accompanying_period_work":
return `/fr/person/accompanying-period/work/${e.id}/edit`;
case "accompanying_period":
return `/fr/parcours/${e.id}`;
default:
throw "entity type unknown";
}
},
},
};
</script>
<style scoped>
</style>
<style scoped></style>

View File

@@ -1,20 +1,17 @@
<template>
<span
v-if="isCounterAvailable"
class="badge rounded-pill bg-danger"
>
{{ count }}
</span>
<span v-if="isCounterAvailable" class="badge rounded-pill bg-danger">
{{ count }}
</span>
</template>
<script>
export default {
name: "TabCounter",
props: ['count'],
computed: {
isCounterAvailable() {
return (typeof this.count !== 'undefined' && this.count > 0 )
}
}
}
</script>
name: "TabCounter",
props: ["count"],
computed: {
isCounterAvailable() {
return typeof this.count !== "undefined" && this.count > 0;
},
},
};
</script>

View File

@@ -1,21 +1,21 @@
<template>
<table class="table table-striped table-hover">
<thead>
<tr>
<slot name="thead" />
</tr>
</thead>
<tbody>
<slot name="tbody" />
</tbody>
</table>
<table class="table table-striped table-hover">
<thead>
<tr>
<slot name="thead" />
</tr>
</thead>
<tbody>
<slot name="tbody" />
</tbody>
</table>
</template>
<script>
export default {
name: "TabTable",
props: []
}
name: "TabTable",
props: [],
};
</script>
<style scoped></style>
<style scoped></style>

View File

@@ -1,82 +1,88 @@
const appMessages = {
fr: {
main_title: "Vue d'ensemble",
my_works: {
tab: "Mes actions",
description: "Liste des actions d'accompagnement dont je suis référent et qui arrivent à échéance.",
},
my_evaluations: {
tab: "Mes évaluations",
description: "Liste des évaluations dont je suis référent et qui arrivent à échéance.",
},
my_tasks: {
tab: "Mes tâches",
description_alert: "Liste des tâches auxquelles je suis assigné et dont la date de rappel est dépassée.",
description_warning: "Liste des tâches auxquelles je suis assigné et dont la date d'échéance est dépassée.",
},
my_accompanying_courses: {
tab: "Mes nouveaux parcours",
description: "Liste des parcours d'accompagnement que l'on vient de m'attribuer depuis moins de 15 jours.",
},
my_notifications: {
tab: "Mes nouvelles notifications",
description: "Liste des notifications reçues et non lues.",
},
my_workflows: {
tab: "Mes workflows",
description: "Liste des workflows en attente d'une action.",
description_cc: "Liste des workflows dont je suis en copie."
},
opening_date: "Date d'ouverture",
social_issues: "Problématiques sociales",
concerned_persons: "Usagers concernés",
max_date: "Date d'échéance",
warning_date: "Date de rappel",
evaluation: "Évaluation",
task: "Tâche",
Date: "Date",
From: "Expéditeur",
Subject: "Objet",
Entity: "Associé à",
Step: "Étape",
concerned_users: "Usagers concernés",
Object_workflow: "Objet du workflow",
show_entity: "Voir {entity}",
the_activity: "l'échange",
the_course: "le parcours",
the_action: "l'action",
the_evaluation: "l'évaluation",
the_evaluation_document: "le document",
the_task: "la tâche",
the_workflow: "le workflow",
StartDate: "Date d'ouverture",
SocialAction: "Action d'accompagnement",
no_data: "Aucun résultats",
no_dashboard: "Pas de tableaux de bord",
counter: {
unread_notifications: "{n} notification non lue | {n} notifications non lues",
assignated_courses: "{n} parcours récent assigné | {n} parcours récents assignés",
assignated_actions: "{n} action assignée | {n} actions assignées",
assignated_evaluations: "{n} évaluation assignée | {n} évaluations assignées",
alert_tasks: "{n} tâche en rappel | {n} tâches en rappel",
warning_tasks: "{n} tâche à échéance | {n} tâches à échéance",
},
emergency: "Urgent",
confidential: "Confidentiel",
automatic_notification: "Notification automatique",
widget: {
news: {
title: "Actualités",
readMore: "Lire la suite",
date: "Date",
none: "Aucune actualité"
}
}
}
fr: {
main_title: "Vue d'ensemble",
my_works: {
tab: "Mes actions",
description:
"Liste des actions d'accompagnement dont je suis référent et qui arrivent à échéance.",
},
my_evaluations: {
tab: "Mes évaluations",
description:
"Liste des évaluations dont je suis référent et qui arrivent à échéance.",
},
my_tasks: {
tab: "Mes tâches",
description_alert:
"Liste des tâches auxquelles je suis assigné et dont la date de rappel est dépassée.",
description_warning:
"Liste des tâches auxquelles je suis assigné et dont la date d'échéance est dépassée.",
},
my_accompanying_courses: {
tab: "Mes nouveaux parcours",
description:
"Liste des parcours d'accompagnement que l'on vient de m'attribuer depuis moins de 15 jours.",
},
my_notifications: {
tab: "Mes nouvelles notifications",
description: "Liste des notifications reçues et non lues.",
},
my_workflows: {
tab: "Mes workflows",
description: "Liste des workflows en attente d'une action.",
description_cc: "Liste des workflows dont je suis en copie.",
},
opening_date: "Date d'ouverture",
social_issues: "Problématiques sociales",
concerned_persons: "Usagers concernés",
max_date: "Date d'échéance",
warning_date: "Date de rappel",
evaluation: "Évaluation",
task: "Tâche",
Date: "Date",
From: "Expéditeur",
Subject: "Objet",
Entity: "Associé à",
Step: "Étape",
concerned_users: "Usagers concernés",
Object_workflow: "Objet du workflow",
show_entity: "Voir {entity}",
the_activity: "l'échange",
the_course: "le parcours",
the_action: "l'action",
the_evaluation: "l'évaluation",
the_evaluation_document: "le document",
the_task: "la tâche",
the_workflow: "le workflow",
StartDate: "Date d'ouverture",
SocialAction: "Action d'accompagnement",
no_data: "Aucun résultats",
no_dashboard: "Pas de tableaux de bord",
counter: {
unread_notifications:
"{n} notification non lue | {n} notifications non lues",
assignated_courses:
"{n} parcours récent assigné | {n} parcours récents assignés",
assignated_actions: "{n} action assignée | {n} actions assignées",
assignated_evaluations:
"{n} évaluation assignée | {n} évaluations assignées",
alert_tasks: "{n} tâche en rappel | {n} tâches en rappel",
warning_tasks: "{n} tâche à échéance | {n} tâches à échéance",
},
emergency: "Urgent",
confidential: "Confidentiel",
automatic_notification: "Notification automatique",
widget: {
news: {
title: "Actualités",
readMore: "Lire la suite",
date: "Date",
none: "Aucune actualité",
},
},
},
};
Object.assign(appMessages.fr);
export {
appMessages
};
export { appMessages };

View File

@@ -1,226 +1,222 @@
import 'es6-promise/auto';
import { createStore } from 'vuex';
import "es6-promise/auto";
import { createStore } from "vuex";
import { makeFetch } from "ChillMainAssets/lib/api/apiMethods";
const debug = process.env.NODE_ENV !== 'production';
const debug = process.env.NODE_ENV !== "production";
const isEmpty = (obj) => {
return obj
&& Object.keys(obj).length <= 1
&& Object.getPrototypeOf(obj) === Object.prototype;
return (
obj &&
Object.keys(obj).length <= 1 &&
Object.getPrototypeOf(obj) === Object.prototype
);
};
const store = createStore({
strict: debug,
state: {
// works: {},
evaluations: {},
tasks: {
warning: {},
alert: {}
},
accompanyingCourses: {},
notifications: {},
workflows: {},
workflowsCc: {},
errorMsg: [],
loading: false
strict: debug,
state: {
// works: {},
evaluations: {},
tasks: {
warning: {},
alert: {},
},
getters: {
// isWorksLoaded(state) {
// return !isEmpty(state.works);
// },
isEvaluationsLoaded(state) {
return !isEmpty(state.evaluations);
},
isTasksWarningLoaded(state) {
return !isEmpty(state.tasks.warning);
},
isTasksAlertLoaded(state) {
return !isEmpty(state.tasks.alert);
},
isAccompanyingCoursesLoaded(state) {
return !isEmpty(state.accompanyingCourses);
},
isNotificationsLoaded(state) {
return !isEmpty(state.notifications);
},
isWorkflowsLoaded(state) {
return !isEmpty(state.workflows);
},
counter(state) {
return {
// works: state.works.count,
evaluations: state.evaluations.count,
tasksWarning: state.tasks.warning.count,
tasksAlert: state.tasks.alert.count,
accompanyingCourses: state.accompanyingCourses.count,
notifications: state.notifications.count,
workflows: state.workflows.count
}
}
accompanyingCourses: {},
notifications: {},
workflows: {},
workflowsCc: {},
errorMsg: [],
loading: false,
},
getters: {
// isWorksLoaded(state) {
// return !isEmpty(state.works);
// },
isEvaluationsLoaded(state) {
return !isEmpty(state.evaluations);
},
mutations: {
// addWorks(state, works) {
// //console.log('addWorks', works);
// state.works = works;
// },
addEvaluations(state, evaluations) {
//console.log('addEvaluations', evaluations);
state.evaluations = evaluations;
},
addTasksWarning(state, tasks) {
//console.log('addTasksWarning', tasks);
state.tasks.warning = tasks;
},
addTasksAlert(state, tasks) {
//console.log('addTasksAlert', tasks);
state.tasks.alert = tasks;
},
addCourses(state, courses) {
//console.log('addCourses', courses);
state.accompanyingCourses = courses;
},
addNotifications(state, notifications) {
//console.log('addNotifications', notifications);
state.notifications = notifications;
},
addWorkflows(state, workflows) {
state.workflows = workflows;
},
addWorkflowsCc(state, workflows) {
state.workflowsCc = workflows;
},
setLoading(state, bool) {
state.loading = bool;
},
catchError(state, error) {
state.errorMsg.push(error);
},
isTasksWarningLoaded(state) {
return !isEmpty(state.tasks.warning);
},
actions: {
getByTab({ commit, getters }, { tab, param }) {
switch (tab) {
// case 'MyWorks':
// if (!getters.isWorksLoaded) {
// commit('setLoading', true);
// const url = `/api/1.0/person/accompanying-period/work/my-near-end${'?'+ param}`;
// makeFetch('GET', url)
// .then((response) => {
// commit('addWorks', response);
// commit('setLoading', false);
// })
// .catch((error) => {
// commit('catchError', error);
// throw error;
// })
// ;
// }
// break;
case 'MyEvaluations':
if (!getters.isEvaluationsLoaded) {
commit('setLoading', true);
const url = `/api/1.0/person/accompanying-period/work/evaluation/my-near-end${'?'+ param}`;
makeFetch('GET', url)
.then((response) => {
commit('addEvaluations', response);
commit('setLoading', false);
})
.catch((error) => {
commit('catchError', error);
throw error;
})
;
}
break;
case 'MyTasks':
if (!(getters.isTasksWarningLoaded && getters.isTasksAlertLoaded)) {
commit('setLoading', true);
const
urlWarning = `/api/1.0/task/single-task/list/my?f[q]=&f[checkboxes][status][]=warning&f[checkboxes][states][]=new&f[checkboxes][states][]=in_progress${'&'+ param}`,
urlAlert = `/api/1.0/task/single-task/list/my?f[q]=&f[checkboxes][status][]=alert&f[checkboxes][states][]=new&f[checkboxes][states][]=in_progress${'&'+ param}`
;
makeFetch('GET', urlWarning)
.then((response) => {
commit('addTasksWarning', response);
commit('setLoading', false);
})
.catch((error) => {
commit('catchError', error);
throw error;
})
;
makeFetch('GET', urlAlert)
.then((response) => {
commit('addTasksAlert', response);
commit('setLoading', false);
})
.catch((error) => {
commit('catchError', error);
throw error;
})
;
}
break;
case 'MyAccompanyingCourses':
if (!getters.isAccompanyingCoursesLoaded) {
commit('setLoading', true);
const url = `/api/1.0/person/accompanying-course/list/by-recent-attributions${'?'+ param}`;
makeFetch('GET', url)
.then((response) => {
commit('addCourses', response);
commit('setLoading', false);
})
.catch((error) => {
commit('catchError', error);
throw error;
})
;
}
break;
case 'MyNotifications':
if (!getters.isNotificationsLoaded) {
commit('setLoading', true);
const url = `/api/1.0/main/notification/my/unread${'?'+ param}`;
makeFetch('GET', url)
.then((response) => {
console.log('notifications', response)
commit('addNotifications', response);
commit('setLoading', false);
})
.catch((error) => {
commit('catchError', error);
throw error;
});
}
break;
case 'MyWorkflows':
if (!getters.isWorflowsLoaded) {
commit('setLoading', true);
makeFetch('GET', '/api/1.0/main/workflow/my')
.then((response) => {
commit('addWorkflows', response);
makeFetch('GET', '/api/1.0/main/workflow/my-cc')
.then((response) => {
commit('addWorkflowsCc', response);
commit('setLoading', false);
})
.catch((error) => {
commit('catchError', error);
throw error;
});
})
.catch((error) => {
commit('catchError', error);
throw error;
});
}
break;
default:
throw 'tab '+ tab;
}
},
isTasksAlertLoaded(state) {
return !isEmpty(state.tasks.alert);
},
isAccompanyingCoursesLoaded(state) {
return !isEmpty(state.accompanyingCourses);
},
isNotificationsLoaded(state) {
return !isEmpty(state.notifications);
},
isWorkflowsLoaded(state) {
return !isEmpty(state.workflows);
},
counter(state) {
return {
// works: state.works.count,
evaluations: state.evaluations.count,
tasksWarning: state.tasks.warning.count,
tasksAlert: state.tasks.alert.count,
accompanyingCourses: state.accompanyingCourses.count,
notifications: state.notifications.count,
workflows: state.workflows.count,
};
},
},
mutations: {
// addWorks(state, works) {
// //console.log('addWorks', works);
// state.works = works;
// },
addEvaluations(state, evaluations) {
//console.log('addEvaluations', evaluations);
state.evaluations = evaluations;
},
addTasksWarning(state, tasks) {
//console.log('addTasksWarning', tasks);
state.tasks.warning = tasks;
},
addTasksAlert(state, tasks) {
//console.log('addTasksAlert', tasks);
state.tasks.alert = tasks;
},
addCourses(state, courses) {
//console.log('addCourses', courses);
state.accompanyingCourses = courses;
},
addNotifications(state, notifications) {
//console.log('addNotifications', notifications);
state.notifications = notifications;
},
addWorkflows(state, workflows) {
state.workflows = workflows;
},
addWorkflowsCc(state, workflows) {
state.workflowsCc = workflows;
},
setLoading(state, bool) {
state.loading = bool;
},
catchError(state, error) {
state.errorMsg.push(error);
},
},
actions: {
getByTab({ commit, getters }, { tab, param }) {
switch (tab) {
// case 'MyWorks':
// if (!getters.isWorksLoaded) {
// commit('setLoading', true);
// const url = `/api/1.0/person/accompanying-period/work/my-near-end${'?'+ param}`;
// makeFetch('GET', url)
// .then((response) => {
// commit('addWorks', response);
// commit('setLoading', false);
// })
// .catch((error) => {
// commit('catchError', error);
// throw error;
// })
// ;
// }
// break;
case "MyEvaluations":
if (!getters.isEvaluationsLoaded) {
commit("setLoading", true);
const url = `/api/1.0/person/accompanying-period/work/evaluation/my-near-end${"?" + param}`;
makeFetch("GET", url)
.then((response) => {
commit("addEvaluations", response);
commit("setLoading", false);
})
.catch((error) => {
commit("catchError", error);
throw error;
});
}
break;
case "MyTasks":
if (!(getters.isTasksWarningLoaded && getters.isTasksAlertLoaded)) {
commit("setLoading", true);
const urlWarning = `/api/1.0/task/single-task/list/my?f[q]=&f[checkboxes][status][]=warning&f[checkboxes][states][]=new&f[checkboxes][states][]=in_progress${"&" + param}`,
urlAlert = `/api/1.0/task/single-task/list/my?f[q]=&f[checkboxes][status][]=alert&f[checkboxes][states][]=new&f[checkboxes][states][]=in_progress${"&" + param}`;
makeFetch("GET", urlWarning)
.then((response) => {
commit("addTasksWarning", response);
commit("setLoading", false);
})
.catch((error) => {
commit("catchError", error);
throw error;
});
makeFetch("GET", urlAlert)
.then((response) => {
commit("addTasksAlert", response);
commit("setLoading", false);
})
.catch((error) => {
commit("catchError", error);
throw error;
});
}
break;
case "MyAccompanyingCourses":
if (!getters.isAccompanyingCoursesLoaded) {
commit("setLoading", true);
const url = `/api/1.0/person/accompanying-course/list/by-recent-attributions${"?" + param}`;
makeFetch("GET", url)
.then((response) => {
commit("addCourses", response);
commit("setLoading", false);
})
.catch((error) => {
commit("catchError", error);
throw error;
});
}
break;
case "MyNotifications":
if (!getters.isNotificationsLoaded) {
commit("setLoading", true);
const url = `/api/1.0/main/notification/my/unread${"?" + param}`;
makeFetch("GET", url)
.then((response) => {
console.log("notifications", response);
commit("addNotifications", response);
commit("setLoading", false);
})
.catch((error) => {
commit("catchError", error);
throw error;
});
}
break;
case "MyWorkflows":
if (!getters.isWorflowsLoaded) {
commit("setLoading", true);
makeFetch("GET", "/api/1.0/main/workflow/my")
.then((response) => {
commit("addWorkflows", response);
makeFetch("GET", "/api/1.0/main/workflow/my-cc")
.then((response) => {
commit("addWorkflowsCc", response);
commit("setLoading", false);
})
.catch((error) => {
commit("catchError", error);
throw error;
});
})
.catch((error) => {
commit("catchError", error);
throw error;
});
}
break;
default:
throw "tab " + tab;
}
},
},
});
export { store };