mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-09-27 00:55:01 +00:00
Merge branch '71-task-feature-and-bug-by-status-for-boris' into 'ticket-app-master'
Misc: homepage widget with tickets, and improvements in ticket list See merge request Chill-Projet/chill-bundles!879
This commit is contained in:
@@ -1,15 +0,0 @@
|
|||||||
import { createApp } from "vue";
|
|
||||||
import { _createI18n } from "ChillMainAssets/vuejs/_js/i18n";
|
|
||||||
import { appMessages } from "ChillMainAssets/vuejs/HomepageWidget/js/i18n";
|
|
||||||
import { store } from "ChillMainAssets/vuejs/HomepageWidget/js/store";
|
|
||||||
import App from "ChillMainAssets/vuejs/HomepageWidget/App";
|
|
||||||
|
|
||||||
const i18n = _createI18n(appMessages);
|
|
||||||
|
|
||||||
const app = createApp({
|
|
||||||
template: `<app></app>`,
|
|
||||||
})
|
|
||||||
.use(store)
|
|
||||||
.use(i18n)
|
|
||||||
.component("app", App)
|
|
||||||
.mount("#homepage_widget");
|
|
@@ -0,0 +1,6 @@
|
|||||||
|
import App from "ChillMainAssets/vuejs/HomepageWidget/App.vue";
|
||||||
|
import { createApp } from "vue";
|
||||||
|
import { store } from "ChillMainAssets/vuejs/HomepageWidget/store";
|
||||||
|
|
||||||
|
const _app = createApp(App);
|
||||||
|
_app.use(store).mount("#homepage_widget");
|
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<h2>{{ $t("main_title") }}</h2>
|
<h2>{{ trans(MAIN_TITLE) }}</h2>
|
||||||
|
|
||||||
<ul class="nav nav-tabs">
|
<ul class="nav nav-tabs">
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
@@ -11,14 +11,24 @@
|
|||||||
<i class="fa fa-dashboard" />
|
<i class="fa fa-dashboard" />
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a
|
||||||
|
class="nav-link"
|
||||||
|
:class="{ active: activeTab === 'MyTickets' }"
|
||||||
|
@click="selectTab('MyTickets')"
|
||||||
|
>
|
||||||
|
{{ trans(MY_TICKETS_TAB) }}
|
||||||
|
<tab-counter :count="ticketListState.value?.count || 0" />
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a
|
<a
|
||||||
class="nav-link"
|
class="nav-link"
|
||||||
:class="{ active: activeTab === 'MyNotifications' }"
|
:class="{ active: activeTab === 'MyNotifications' }"
|
||||||
@click="selectTab('MyNotifications')"
|
@click="selectTab('MyNotifications')"
|
||||||
>
|
>
|
||||||
{{ $t("my_notifications.tab") }}
|
{{ trans(MY_NOTIFICATIONS_TAB) }}
|
||||||
<tab-counter :count="state.notifications.count" />
|
<tab-counter :count="state.value?.notifications?.count || 0" />
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
@@ -27,25 +37,17 @@
|
|||||||
:class="{ active: activeTab === 'MyAccompanyingCourses' }"
|
:class="{ active: activeTab === 'MyAccompanyingCourses' }"
|
||||||
@click="selectTab('MyAccompanyingCourses')"
|
@click="selectTab('MyAccompanyingCourses')"
|
||||||
>
|
>
|
||||||
{{ $t("my_accompanying_courses.tab") }}
|
{{ trans(MY_ACCOMPANYING_COURSES_TAB) }}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<!-- <li class="nav-item">
|
|
||||||
<a class="nav-link"
|
|
||||||
:class="{'active': activeTab === 'MyWorks'}"
|
|
||||||
@click="selectTab('MyWorks')">
|
|
||||||
{{ $t('my_works.tab') }}
|
|
||||||
<tab-counter :count="state.works.count"></tab-counter>
|
|
||||||
</a>
|
|
||||||
</li> -->
|
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a
|
<a
|
||||||
class="nav-link"
|
class="nav-link"
|
||||||
:class="{ active: activeTab === 'MyEvaluations' }"
|
:class="{ active: activeTab === 'MyEvaluations' }"
|
||||||
@click="selectTab('MyEvaluations')"
|
@click="selectTab('MyEvaluations')"
|
||||||
>
|
>
|
||||||
{{ $t("my_evaluations.tab") }}
|
{{ trans(MY_EVALUATIONS_TAB) }}
|
||||||
<tab-counter :count="state.evaluations.count" />
|
<tab-counter :count="state.value?.evaluations?.count || 0" />
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
@@ -54,9 +56,12 @@
|
|||||||
:class="{ active: activeTab === 'MyTasks' }"
|
:class="{ active: activeTab === 'MyTasks' }"
|
||||||
@click="selectTab('MyTasks')"
|
@click="selectTab('MyTasks')"
|
||||||
>
|
>
|
||||||
{{ $t("my_tasks.tab") }}
|
{{ trans(MY_TASKS_TAB) }}
|
||||||
<tab-counter
|
<tab-counter
|
||||||
:count="state.tasks.warning.count + state.tasks.alert.count"
|
:count="
|
||||||
|
(state.value?.tasks?.warning?.count || 0) +
|
||||||
|
(state.value?.tasks?.alert?.count || 0)
|
||||||
|
"
|
||||||
/>
|
/>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
@@ -66,19 +71,25 @@
|
|||||||
:class="{ active: activeTab === 'MyWorkflows' }"
|
:class="{ active: activeTab === 'MyWorkflows' }"
|
||||||
@click="selectTab('MyWorkflows')"
|
@click="selectTab('MyWorkflows')"
|
||||||
>
|
>
|
||||||
{{ $t("my_workflows.tab") }}
|
{{ trans(MY_WORKFLOWS_TAB) }}
|
||||||
<tab-counter :count="state.workflows.count + state.workflowsCc.count" />
|
<tab-counter
|
||||||
|
:count="
|
||||||
|
(state.value?.workflows?.count || 0) +
|
||||||
|
(state.value?.workflowsCc?.count || 0)
|
||||||
|
"
|
||||||
|
/>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item loading ms-auto py-2" v-if="loading">
|
<li class="nav-item loading ms-auto py-2" v-if="loading">
|
||||||
<i
|
<i
|
||||||
class="fa fa-circle-o-notch fa-spin fa-lg text-chill-gray"
|
class="fa fa-circle-o-notch fa-spin fa-lg text-chill-gray"
|
||||||
:title="$t('loading')"
|
:title="trans(LOADING)"
|
||||||
/>
|
/>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<div class="my-4">
|
<div class="my-4">
|
||||||
|
<my-tickets v-if="activeTab == 'MyTickets'" />
|
||||||
<my-customs v-if="activeTab === 'MyCustoms'" />
|
<my-customs v-if="activeTab === 'MyCustoms'" />
|
||||||
<my-works v-else-if="activeTab === 'MyWorks'" />
|
<my-works v-else-if="activeTab === 'MyWorks'" />
|
||||||
<my-evaluations v-else-if="activeTab === 'MyEvaluations'" />
|
<my-evaluations v-else-if="activeTab === 'MyEvaluations'" />
|
||||||
@@ -91,63 +102,58 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script lang="ts" setup>
|
||||||
import MyCustoms from "./MyCustoms";
|
import { ref, computed, onMounted } from "vue";
|
||||||
import MyWorks from "./MyWorks";
|
import { useStore } from "vuex";
|
||||||
import MyEvaluations from "./MyEvaluations";
|
import MyCustoms from "./MyCustoms.vue";
|
||||||
import MyTasks from "./MyTasks";
|
import MyWorks from "./MyWorks.vue";
|
||||||
import MyAccompanyingCourses from "./MyAccompanyingCourses";
|
import MyEvaluations from "./MyEvaluations.vue";
|
||||||
import MyNotifications from "./MyNotifications";
|
import MyTasks from "./MyTasks.vue";
|
||||||
|
import MyAccompanyingCourses from "./MyAccompanyingCourses.vue";
|
||||||
|
import MyNotifications from "./MyNotifications.vue";
|
||||||
import MyWorkflows from "./MyWorkflows.vue";
|
import MyWorkflows from "./MyWorkflows.vue";
|
||||||
import TabCounter from "./TabCounter";
|
import MyTickets from "./MyTickets.vue";
|
||||||
import { mapState } from "vuex";
|
import TabCounter from "./TabCounter.vue";
|
||||||
|
import {
|
||||||
|
MAIN_TITLE,
|
||||||
|
MY_TICKETS_TAB,
|
||||||
|
MY_EVALUATIONS_TAB,
|
||||||
|
MY_TASKS_TAB,
|
||||||
|
MY_ACCOMPANYING_COURSES_TAB,
|
||||||
|
MY_NOTIFICATIONS_TAB,
|
||||||
|
MY_WORKFLOWS_TAB,
|
||||||
|
LOADING,
|
||||||
|
trans,
|
||||||
|
} from "translator";
|
||||||
|
const store = useStore();
|
||||||
|
|
||||||
export default {
|
const activeTab = ref("MyCustoms");
|
||||||
name: "App",
|
|
||||||
components: {
|
const loading = computed(() => store.state.loading);
|
||||||
MyCustoms,
|
|
||||||
MyWorks,
|
const state = computed(() => store.state.homepage);
|
||||||
MyEvaluations,
|
const ticketListState = computed(() => store.state.ticketList);
|
||||||
MyTasks,
|
|
||||||
MyWorkflows,
|
function selectTab(tab: string) {
|
||||||
MyAccompanyingCourses,
|
if (tab !== "MyCustoms") {
|
||||||
MyNotifications,
|
store.dispatch("getByTab", { tab: tab });
|
||||||
TabCounter,
|
}
|
||||||
},
|
activeTab.value = tab;
|
||||||
data() {
|
}
|
||||||
return {
|
|
||||||
activeTab: "MyCustoms",
|
onMounted(() => {
|
||||||
};
|
for (const m of [
|
||||||
},
|
"MyTickets",
|
||||||
computed: {
|
"MyNotifications",
|
||||||
...mapState(["loading"]),
|
"MyAccompanyingCourses",
|
||||||
// just to see all in devtool :
|
// 'MyWorks',
|
||||||
...mapState({
|
"MyEvaluations",
|
||||||
state: (state) => state,
|
"MyTasks",
|
||||||
}),
|
"MyWorkflows",
|
||||||
},
|
]) {
|
||||||
methods: {
|
store.dispatch("getByTab", { tab: m, param: "countOnly=1" });
|
||||||
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>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
@@ -1,35 +1,35 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="alert alert-light">
|
<div class="alert alert-light">
|
||||||
{{ $t("my_accompanying_courses.description") }}
|
{{ trans(MY_ACCOMPANYING_COURSES_DESCRIPTION) }}
|
||||||
</div>
|
</div>
|
||||||
<span v-if="noResults" class="chill-no-data-statement">{{
|
<span v-if="noResults" class="chill-no-data-statement">
|
||||||
$t("no_data")
|
{{ trans(NO_DATA) }}
|
||||||
}}</span>
|
</span>
|
||||||
<tab-table v-else>
|
<tab-table v-else>
|
||||||
<template #thead>
|
<template #thead>
|
||||||
<th scope="col">
|
<th scope="col">
|
||||||
{{ $t("opening_date") }}
|
{{ trans(OPENING_DATE) }}
|
||||||
</th>
|
</th>
|
||||||
<th scope="col">
|
<th scope="col">
|
||||||
{{ $t("social_issues") }}
|
{{ trans(SOCIAL_ISSUES) }}
|
||||||
</th>
|
</th>
|
||||||
<th scope="col">
|
<th scope="col">
|
||||||
{{ $t("concerned_persons") }}
|
{{ trans(CONCERNED_PERSONS) }}
|
||||||
</th>
|
</th>
|
||||||
<th scope="col" />
|
<th scope="col" />
|
||||||
<th scope="col" />
|
<th scope="col" />
|
||||||
</template>
|
</template>
|
||||||
<template #tbody>
|
<template #tbody>
|
||||||
<tr v-for="(c, i) in accompanyingCourses.results" :key="`course-${i}`">
|
<tr v-for="(c, i) in accompanyingCourses.results" :key="`course-${i}`">
|
||||||
<td>{{ $d(c.openingDate.datetime, "short") }}</td>
|
<td>{{ $d(new Date(c.openingDate.datetime), "short") }}</td>
|
||||||
<td>
|
<td>
|
||||||
<span
|
<span
|
||||||
v-for="(i, index) in c.socialIssues"
|
v-for="(issue, index) in c.socialIssues"
|
||||||
:key="index"
|
:key="index"
|
||||||
class="chill-entity entity-social-issue"
|
class="chill-entity entity-social-issue"
|
||||||
>
|
>
|
||||||
<span class="badge bg-chill-l-gray text-dark">
|
<span class="badge bg-chill-l-gray text-dark">
|
||||||
{{ localizeString(i.title) }}
|
{{ localizeString(issue.title) }}
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
@@ -46,15 +46,15 @@
|
|||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<span v-if="c.emergency" class="badge rounded-pill bg-danger me-1">{{
|
<span v-if="c.emergency" class="badge rounded-pill bg-danger me-1">{{
|
||||||
$t("emergency")
|
trans(EMERGENCY)
|
||||||
}}</span>
|
}}</span>
|
||||||
<span v-if="c.confidential" class="badge rounded-pill bg-danger">{{
|
<span v-if="c.confidential" class="badge rounded-pill bg-danger">{{
|
||||||
$t("confidential")
|
trans(CONFIDENTIAL)
|
||||||
}}</span>
|
}}</span>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<a class="btn btn-sm btn-show" :href="getUrl(c)">
|
<a class="btn btn-sm btn-show" :href="getUrl(c)">
|
||||||
{{ $t("show_entity", { entity: $t("the_course") }) }}
|
{{ trans(SHOW_ENTITY, { entity: trans(THE_COURSE) }) }}
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -62,36 +62,45 @@
|
|||||||
</tab-table>
|
</tab-table>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script lang="ts" setup>
|
||||||
import { mapState, mapGetters } from "vuex";
|
import { computed, ComputedRef } from "vue";
|
||||||
import TabTable from "./TabTable";
|
import { useStore } from "vuex";
|
||||||
import OnTheFly from "ChillMainAssets/vuejs/OnTheFly/components/OnTheFly";
|
import TabTable from "./TabTable.vue";
|
||||||
|
import OnTheFly from "ChillMainAssets/vuejs/OnTheFly/components/OnTheFly.vue";
|
||||||
import { localizeString } from "ChillMainAssets/lib/localizationHelper/localizationHelper";
|
import { localizeString } from "ChillMainAssets/lib/localizationHelper/localizationHelper";
|
||||||
|
import { AccompanyingCourse } from "ChillPersonAssets/types";
|
||||||
|
import { PaginationResponse } from "ChillMainAssets/lib/api/apiMethods";
|
||||||
|
import {
|
||||||
|
MY_ACCOMPANYING_COURSES_DESCRIPTION,
|
||||||
|
OPENING_DATE,
|
||||||
|
SOCIAL_ISSUES,
|
||||||
|
CONCERNED_PERSONS,
|
||||||
|
SHOW_ENTITY,
|
||||||
|
THE_COURSE,
|
||||||
|
NO_DATA,
|
||||||
|
EMERGENCY,
|
||||||
|
CONFIDENTIAL,
|
||||||
|
trans,
|
||||||
|
} from "translator";
|
||||||
|
const store = useStore();
|
||||||
|
|
||||||
export default {
|
const accompanyingCourses: ComputedRef<PaginationResponse<AccompanyingCourse>> =
|
||||||
name: "MyAccompanyingCourses",
|
computed(() => store.state.homepage.accompanyingCourses);
|
||||||
components: {
|
const isAccompanyingCoursesLoaded = computed(
|
||||||
TabTable,
|
() => store.getters.isAccompanyingCoursesLoaded,
|
||||||
OnTheFly,
|
);
|
||||||
},
|
|
||||||
computed: {
|
const noResults = computed(() => {
|
||||||
...mapState(["accompanyingCourses"]),
|
if (!isAccompanyingCoursesLoaded.value) {
|
||||||
...mapGetters(["isAccompanyingCoursesLoaded"]),
|
return false;
|
||||||
noResults() {
|
} else {
|
||||||
if (!this.isAccompanyingCoursesLoaded) {
|
return accompanyingCourses.value.count === 0;
|
||||||
return false;
|
}
|
||||||
} else {
|
});
|
||||||
return this.accompanyingCourses.count === 0;
|
|
||||||
}
|
function getUrl(c: { id: number }): string {
|
||||||
},
|
return `/fr/parcours/${c.id}`;
|
||||||
},
|
}
|
||||||
methods: {
|
|
||||||
localizeString,
|
|
||||||
getUrl(c) {
|
|
||||||
return `/fr/parcours/${c.id}`;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
@@ -1,93 +1,72 @@
|
|||||||
<template>
|
<template>
|
||||||
<span v-if="noResults" class="chill-no-data-statement">{{
|
<span v-if="noResults" class="chill-no-data-statement">
|
||||||
$t("no_dashboard")
|
{{ trans(NO_DASHBOARD) }}
|
||||||
}}</span>
|
</span>
|
||||||
<div v-else id="dashboards" class="container g-3">
|
<div v-else id="dashboards" class="container g-3">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="mbloc col-xs-12 col-sm-4">
|
<div class="mbloc col-xs-12 col-sm-4">
|
||||||
<div class="custom1">
|
<div class="custom1">
|
||||||
<ul class="list-unstyled">
|
<ul class="list-unstyled">
|
||||||
<li v-if="counter.notifications > 0">
|
<li v-if="(counter.value?.notifications || 0) > 0">
|
||||||
<i18n-t
|
<span :class="counterClass">
|
||||||
keypath="counter.unread_notifications"
|
{{
|
||||||
tag="span"
|
trans(COUNTER_UNREAD_NOTIFICATIONS, {
|
||||||
:class="counterClass"
|
n: counter.value?.notifications || 0,
|
||||||
:plural="counter.notifications"
|
})
|
||||||
>
|
}}
|
||||||
<template #n>
|
</span>
|
||||||
<span>{{ counter.notifications }}</span>
|
|
||||||
</template>
|
|
||||||
</i18n-t>
|
|
||||||
</li>
|
</li>
|
||||||
<li v-if="counter.accompanyingCourses > 0">
|
<li v-if="(counter.value?.accompanyingCourses || 0) > 0">
|
||||||
<i18n-t
|
<span :class="counterClass">
|
||||||
keypath="counter.assignated_courses"
|
{{
|
||||||
tag="span"
|
trans(COUNTER_ASSIGNATED_COURSES, {
|
||||||
:class="counterClass"
|
n: counter.value?.accompanyingCourses || 0,
|
||||||
:plural="counter.accompanyingCourses"
|
})
|
||||||
>
|
}}
|
||||||
<template #n>
|
</span>
|
||||||
<span>{{ counter.accompanyingCourses }}</span>
|
|
||||||
</template>
|
|
||||||
</i18n-t>
|
|
||||||
</li>
|
</li>
|
||||||
<li v-if="counter.works > 0">
|
<li v-if="(counter.value?.works || 0) > 0">
|
||||||
<i18n-t
|
<span :class="counterClass">
|
||||||
keypath="counter.assignated_actions"
|
{{
|
||||||
tag="span"
|
trans(COUNTER_ASSIGNATED_ACTIONS, {
|
||||||
:class="counterClass"
|
n: counter.value?.works || 0,
|
||||||
:plural="counter.works"
|
})
|
||||||
>
|
}}
|
||||||
<template #n>
|
</span>
|
||||||
<span>{{ counter.works }}</span>
|
|
||||||
</template>
|
|
||||||
</i18n-t>
|
|
||||||
</li>
|
</li>
|
||||||
<li v-if="counter.evaluations > 0">
|
<li v-if="(counter.value?.evaluations || 0) > 0">
|
||||||
<i18n-t
|
<span :class="counterClass">
|
||||||
keypath="counter.assignated_evaluations"
|
{{
|
||||||
tag="span"
|
trans(COUNTER_ASSIGNATED_EVALUATIONS, {
|
||||||
:class="counterClass"
|
n: counter.value?.evaluations || 0,
|
||||||
:plural="counter.evaluations"
|
})
|
||||||
>
|
}}
|
||||||
<template #n>
|
</span>
|
||||||
<span>{{ counter.evaluations }}</span>
|
|
||||||
</template>
|
|
||||||
</i18n-t>
|
|
||||||
</li>
|
</li>
|
||||||
<li v-if="counter.tasksAlert > 0">
|
<li v-if="(counter.value?.tasksAlert || 0) > 0">
|
||||||
<i18n-t
|
<span :class="counterClass">
|
||||||
keypath="counter.alert_tasks"
|
{{
|
||||||
tag="span"
|
trans(COUNTER_ALERT_TASKS, {
|
||||||
:class="counterClass"
|
n: counter.value?.tasksAlert || 0,
|
||||||
:plural="counter.tasksAlert"
|
})
|
||||||
>
|
}}
|
||||||
<template #n>
|
</span>
|
||||||
<span>{{ counter.tasksAlert }}</span>
|
|
||||||
</template>
|
|
||||||
</i18n-t>
|
|
||||||
</li>
|
</li>
|
||||||
<li v-if="counter.tasksWarning > 0">
|
<li v-if="(counter.value?.tasksWarning || 0) > 0">
|
||||||
<i18n-t
|
<span :class="counterClass">
|
||||||
keypath="counter.warning_tasks"
|
{{
|
||||||
tag="span"
|
trans(COUNTER_WARNING_TASKS, {
|
||||||
:class="counterClass"
|
n: counter.value?.tasksWarning || 0,
|
||||||
:plural="counter.tasksWarning"
|
})
|
||||||
>
|
}}
|
||||||
<template #n>
|
</span>
|
||||||
<span>{{ counter.tasksWarning }}</span>
|
|
||||||
</template>
|
|
||||||
</i18n-t>
|
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<template v-if="this.hasDashboardItems">
|
<template v-if="hasDashboardItems">
|
||||||
<template
|
<template v-for="(dashboardItem, index) in dashboardItems" :key="index">
|
||||||
v-for="(dashboardItem, index) in this.dashboardItems"
|
|
||||||
:key="index"
|
|
||||||
>
|
|
||||||
<div
|
<div
|
||||||
class="mbloc col-xs-12 col-sm-8 news"
|
class="mbloc col-xs-12 col-sm-8 news"
|
||||||
v-if="dashboardItem.type === 'news'"
|
v-if="dashboardItem.type === 'news'"
|
||||||
@@ -100,44 +79,53 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script lang="ts" setup>
|
||||||
import { mapGetters } from "vuex";
|
import { ref, computed, onMounted } from "vue";
|
||||||
|
import { useStore } from "vuex";
|
||||||
import { makeFetch } from "ChillMainAssets/lib/api/apiMethods";
|
import { makeFetch } from "ChillMainAssets/lib/api/apiMethods";
|
||||||
import News from "./DashboardWidgets/News.vue";
|
import News from "./DashboardWidgets/News.vue";
|
||||||
|
import {
|
||||||
|
NO_DASHBOARD,
|
||||||
|
COUNTER_UNREAD_NOTIFICATIONS,
|
||||||
|
COUNTER_ASSIGNATED_COURSES,
|
||||||
|
COUNTER_ASSIGNATED_ACTIONS,
|
||||||
|
COUNTER_ASSIGNATED_EVALUATIONS,
|
||||||
|
COUNTER_ALERT_TASKS,
|
||||||
|
COUNTER_WARNING_TASKS,
|
||||||
|
trans,
|
||||||
|
} from "translator";
|
||||||
|
|
||||||
export default {
|
interface MyCustom {
|
||||||
name: "MyCustoms",
|
id: number;
|
||||||
components: {
|
type: string;
|
||||||
News,
|
metadata: Record<string, unknown>;
|
||||||
},
|
userId: number;
|
||||||
data() {
|
position: string;
|
||||||
return {
|
}
|
||||||
counterClass: {
|
|
||||||
counter: true, //hack to pass class 'counter' in i18n-t
|
const store = useStore();
|
||||||
},
|
|
||||||
dashboardItems: [],
|
const counter = computed(() => store.getters.counter);
|
||||||
masonry: null,
|
|
||||||
};
|
const counterClass = { counter: true };
|
||||||
},
|
|
||||||
computed: {
|
const dashboardItems = ref<MyCustom[]>([]);
|
||||||
...mapGetters(["counter"]),
|
|
||||||
noResults() {
|
const noResults = computed(() => false);
|
||||||
return false;
|
|
||||||
},
|
const hasDashboardItems = computed(() => dashboardItems.value.length > 0);
|
||||||
hasDashboardItems() {
|
|
||||||
return this.dashboardItems.length > 0;
|
onMounted(async () => {
|
||||||
},
|
try {
|
||||||
},
|
const response: MyCustom[] = await makeFetch(
|
||||||
mounted() {
|
"GET",
|
||||||
makeFetch("GET", "/api/1.0/main/dashboard-config-item.json")
|
"/api/1.0/main/dashboard-config-item.json",
|
||||||
.then((response) => {
|
);
|
||||||
this.dashboardItems = response;
|
dashboardItems.value = response;
|
||||||
})
|
} catch (error) {
|
||||||
.catch((error) => {
|
throw error;
|
||||||
throw error;
|
}
|
||||||
});
|
});
|
||||||
},
|
|
||||||
};
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
@@ -1,44 +1,50 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="accompanying-course-work">
|
<div class="accompanying-course-work">
|
||||||
<div class="alert alert-light">
|
<div class="alert alert-light">
|
||||||
{{ $t("my_evaluations.description") }}
|
{{ trans(MY_EVALUATIONS_DESCRIPTION) }}
|
||||||
</div>
|
</div>
|
||||||
<span v-if="noResults" class="chill-no-data-statement">{{
|
<span v-if="noResults" class="chill-no-data-statement">
|
||||||
$t("no_data")
|
{{ trans(NO_DATA) }}
|
||||||
}}</span>
|
</span>
|
||||||
<tab-table v-else>
|
<tab-table v-else>
|
||||||
<template #thead>
|
<template #thead>
|
||||||
<th scope="col">
|
<th scope="col">
|
||||||
{{ $t("max_date") }}
|
{{ trans(MAX_DATE) }}
|
||||||
</th>
|
</th>
|
||||||
<th scope="col">
|
<th scope="col">
|
||||||
{{ $t("evaluation") }}
|
{{ trans(EVALUATION) }}
|
||||||
</th>
|
</th>
|
||||||
<th scope="col">
|
<th scope="col">
|
||||||
{{ $t("SocialAction") }}
|
{{ trans(SOCIAL_ACTION) }}
|
||||||
</th>
|
</th>
|
||||||
<th scope="col" />
|
<th scope="col" />
|
||||||
</template>
|
</template>
|
||||||
<template #tbody>
|
<template #tbody>
|
||||||
<tr v-for="(e, i) in evaluations.results" :key="`evaluation-${i}`">
|
<tr v-for="(e, i) in evaluations.results" :key="`evaluation-${i}`">
|
||||||
<td>{{ $d(e.maxDate.datetime, "short") }}</td>
|
|
||||||
<td>
|
<td>
|
||||||
{{ localizeString(e.evaluation.title) }}
|
{{
|
||||||
|
e.maxDate?.datetime
|
||||||
|
? $d(new Date(e.maxDate.datetime), "short")
|
||||||
|
: ""
|
||||||
|
}}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{ localizeString(e.evaluation?.title ?? null) }}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<span class="chill-entity entity-social-issue">
|
<span class="chill-entity entity-social-issue">
|
||||||
<span class="badge bg-chill-l-gray text-dark">
|
<span class="badge bg-chill-l-gray text-dark">
|
||||||
{{ e.accompanyingPeriodWork.socialAction.issue.text }}
|
{{ e.accompanyingPeriodWork?.socialAction?.issue?.text ?? "" }}
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
<h4 class="badge-title">
|
<h4 class="badge-title">
|
||||||
<span class="title_label" />
|
<span class="title_label" />
|
||||||
<span class="title_action">
|
<span class="title_action">
|
||||||
{{ e.accompanyingPeriodWork.socialAction.text }}
|
{{ e.accompanyingPeriodWork?.socialAction?.text ?? "" }}
|
||||||
</span>
|
</span>
|
||||||
</h4>
|
</h4>
|
||||||
<span
|
<span
|
||||||
v-for="person in e.accompanyingPeriodWork.persons"
|
v-for="person in e.accompanyingPeriodWork?.persons ?? []"
|
||||||
class="me-1"
|
class="me-1"
|
||||||
:key="person.id"
|
:key="person.id"
|
||||||
>
|
>
|
||||||
@@ -55,18 +61,22 @@
|
|||||||
<div class="btn-group-vertical" role="group" aria-label="Actions">
|
<div class="btn-group-vertical" role="group" aria-label="Actions">
|
||||||
<a class="btn btn-sm btn-show" :href="getUrl(e)">
|
<a class="btn btn-sm btn-show" :href="getUrl(e)">
|
||||||
{{
|
{{
|
||||||
$t("show_entity", {
|
trans(SHOW_ENTITY, {
|
||||||
entity: $t("the_evaluation"),
|
entity: trans(THE_EVALUATION),
|
||||||
})
|
})
|
||||||
}}
|
}}
|
||||||
</a>
|
</a>
|
||||||
<a
|
<a
|
||||||
class="btn btn-sm btn-show"
|
class="btn btn-sm btn-show"
|
||||||
:href="getUrl(e.accompanyingPeriodWork.accompanyingPeriod)"
|
:href="getUrl(e.accompanyingPeriodWork.accompanyingPeriod!)"
|
||||||
|
v-if="
|
||||||
|
e.accompanyingPeriodWork &&
|
||||||
|
e.accompanyingPeriodWork.accompanyingPeriod
|
||||||
|
"
|
||||||
>
|
>
|
||||||
{{
|
{{
|
||||||
$t("show_entity", {
|
trans(SHOW_ENTITY, {
|
||||||
entity: $t("the_course"),
|
entity: trans(THE_COURSE),
|
||||||
})
|
})
|
||||||
}}
|
}}
|
||||||
</a>
|
</a>
|
||||||
@@ -78,46 +88,70 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script lang="ts" setup>
|
||||||
import { mapState, mapGetters } from "vuex";
|
import { computed } from "vue";
|
||||||
import TabTable from "./TabTable";
|
import { useStore } from "vuex";
|
||||||
import OnTheFly from "ChillMainAssets/vuejs/OnTheFly/components/OnTheFly";
|
import TabTable from "./TabTable.vue";
|
||||||
|
import OnTheFly from "ChillMainAssets/vuejs/OnTheFly/components/OnTheFly.vue";
|
||||||
import { localizeString } from "../../lib/localizationHelper/localizationHelper";
|
import { localizeString } from "../../lib/localizationHelper/localizationHelper";
|
||||||
|
|
||||||
export default {
|
const store = useStore();
|
||||||
name: "MyEvaluations",
|
|
||||||
components: {
|
import type { ComputedRef } from "vue";
|
||||||
TabTable,
|
import {
|
||||||
OnTheFly,
|
AccompanyingPeriod,
|
||||||
},
|
AccompanyingPeriodWorkEvaluation,
|
||||||
computed: {
|
AccompanyingPeriodWork,
|
||||||
...mapState(["evaluations"]),
|
} from "ChillPersonAssets/types";
|
||||||
...mapGetters(["isEvaluationsLoaded"]),
|
import { PaginationResponse } from "ChillMainAssets/lib/api/apiMethods";
|
||||||
noResults() {
|
import {
|
||||||
if (!this.isEvaluationsLoaded) {
|
MY_EVALUATIONS_DESCRIPTION,
|
||||||
return false;
|
MAX_DATE,
|
||||||
} else {
|
EVALUATION,
|
||||||
return this.evaluations.count === 0;
|
SHOW_ENTITY,
|
||||||
}
|
THE_COURSE,
|
||||||
},
|
THE_EVALUATION,
|
||||||
},
|
SOCIAL_ACTION,
|
||||||
methods: {
|
NO_DATA,
|
||||||
localizeString,
|
trans,
|
||||||
getUrl(e) {
|
} from "translator";
|
||||||
switch (e.type) {
|
const evaluations: ComputedRef<
|
||||||
case "accompanying_period_work_evaluation":
|
PaginationResponse<AccompanyingPeriodWorkEvaluation>
|
||||||
let anchor = "#evaluations";
|
> = computed(() => store.state.homepage.evaluations);
|
||||||
return `/fr/person/accompanying-period/work/${e.accompanyingPeriodWork.id}/edit${anchor}`;
|
const isEvaluationsLoaded = computed(() => store.getters.isEvaluationsLoaded);
|
||||||
case "accompanying_period_work":
|
|
||||||
return `/fr/person/accompanying-period/work/${e.id}/edit`;
|
const noResults = computed(() => {
|
||||||
case "accompanying_period":
|
if (!isEvaluationsLoaded.value) {
|
||||||
return `/fr/parcours/${e.id}`;
|
return false;
|
||||||
default:
|
} else {
|
||||||
throw "entity type unknown";
|
return evaluations.value.count === 0;
|
||||||
}
|
}
|
||||||
},
|
});
|
||||||
},
|
|
||||||
};
|
function getUrl(
|
||||||
|
e:
|
||||||
|
| AccompanyingPeriodWorkEvaluation
|
||||||
|
| AccompanyingPeriod
|
||||||
|
| AccompanyingPeriodWork,
|
||||||
|
): string {
|
||||||
|
if (!e) {
|
||||||
|
throw "entity is undefined";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ("type" in e && typeof e.type === "string") {
|
||||||
|
switch (e.type) {
|
||||||
|
case "accompanying_period_work_evaluation":
|
||||||
|
return `/fr/person/accompanying-period/work/${e.accompanyingPeriodWork?.id}/edit#evaluations`;
|
||||||
|
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";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped></style>
|
<style scoped></style>
|
||||||
|
@@ -1,26 +1,26 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="alert alert-light">
|
<div class="alert alert-light">
|
||||||
{{ $t("my_notifications.description") }}
|
{{ trans(MY_NOTIFICATIONS_DESCRIPTION) }}
|
||||||
</div>
|
</div>
|
||||||
<span v-if="noResults" class="chill-no-data-statement">{{
|
<span v-if="noResults" class="chill-no-data-statement">
|
||||||
$t("no_data")
|
{{ trans(NO_DATA) }}
|
||||||
}}</span>
|
</span>
|
||||||
<tab-table v-else>
|
<tab-table v-else>
|
||||||
<template #thead>
|
<template #thead>
|
||||||
<th scope="col">
|
<th scope="col">
|
||||||
{{ $t("Date") }}
|
{{ trans(DATE) }}
|
||||||
</th>
|
</th>
|
||||||
<th scope="col">
|
<th scope="col">
|
||||||
{{ $t("Subject") }}
|
{{ trans(SUBJECT) }}
|
||||||
</th>
|
</th>
|
||||||
<th scope="col">
|
<th scope="col">
|
||||||
{{ $t("From") }}
|
{{ trans(FROM) }}
|
||||||
</th>
|
</th>
|
||||||
<th scope="col" />
|
<th scope="col" />
|
||||||
</template>
|
</template>
|
||||||
<template #tbody>
|
<template #tbody>
|
||||||
<tr v-for="(n, i) in notifications.results" :key="`notify-${i}`">
|
<tr v-for="(n, i) in notifications.results" :key="`notify-${i}`">
|
||||||
<td>{{ $d(n.date.datetime, "long") }}</td>
|
<td>{{ $d(new Date(n.date.datetime), "long") }}</td>
|
||||||
<td>
|
<td>
|
||||||
<span class="unread">
|
<span class="unread">
|
||||||
<i class="fa fa-envelope-o" />
|
<i class="fa fa-envelope-o" />
|
||||||
@@ -31,11 +31,11 @@
|
|||||||
{{ n.sender.text }}
|
{{ n.sender.text }}
|
||||||
</td>
|
</td>
|
||||||
<td v-else>
|
<td v-else>
|
||||||
{{ $t("automatic_notification") }}
|
{{ trans(AUTOMATIC_NOTIFICATION) }}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<a class="btn btn-sm btn-show" :href="getEntityUrl(n)">
|
<a class="btn btn-sm btn-show" :href="getEntityUrl(n)">
|
||||||
{{ $t("show_entity", { entity: getEntityName(n) }) }}
|
{{ trans(SHOW_ENTITY, { entity: getEntityName(n) }) }}
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -43,65 +43,82 @@
|
|||||||
</tab-table>
|
</tab-table>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script lang="ts" setup>
|
||||||
import { mapState, mapGetters } from "vuex";
|
import { computed, ComputedRef } from "vue";
|
||||||
import TabTable from "./TabTable";
|
import { useStore } from "vuex";
|
||||||
import { appMessages } from "ChillMainAssets/vuejs/HomepageWidget/js/i18n";
|
import TabTable from "./TabTable.vue";
|
||||||
|
import { Notification } from "ChillPersonAssets/types";
|
||||||
|
|
||||||
export default {
|
import {
|
||||||
name: "MyNotifications",
|
MY_NOTIFICATIONS_DESCRIPTION,
|
||||||
components: {
|
DATE,
|
||||||
TabTable,
|
FROM,
|
||||||
},
|
SUBJECT,
|
||||||
computed: {
|
SHOW_ENTITY,
|
||||||
...mapState(["notifications"]),
|
THE_ACTIVITY,
|
||||||
...mapGetters(["isNotificationsLoaded"]),
|
THE_COURSE,
|
||||||
noResults() {
|
THE_ACTION,
|
||||||
if (!this.isNotificationsLoaded) {
|
THE_EVALUATION_DOCUMENT,
|
||||||
return false;
|
THE_WORKFLOW,
|
||||||
} else {
|
NO_DATA,
|
||||||
return this.notifications.count === 0;
|
AUTOMATIC_NOTIFICATION,
|
||||||
}
|
trans,
|
||||||
},
|
} from "translator";
|
||||||
},
|
import { PaginationResponse } from "ChillMainAssets/lib/api/apiMethods";
|
||||||
methods: {
|
const store = useStore();
|
||||||
getNotificationUrl(n) {
|
|
||||||
return `/fr/notification/${n.id}/show`;
|
const notifications: ComputedRef<PaginationResponse<Notification>> = computed(
|
||||||
},
|
() => store.state.homepage.notifications,
|
||||||
getEntityName(n) {
|
);
|
||||||
switch (n.relatedEntityClass) {
|
const isNotificationsLoaded = computed(
|
||||||
case "Chill\\ActivityBundle\\Entity\\Activity":
|
() => store.getters.isNotificationsLoaded,
|
||||||
return appMessages.fr.the_activity;
|
);
|
||||||
case "Chill\\PersonBundle\\Entity\\AccompanyingPeriod":
|
|
||||||
return appMessages.fr.the_course;
|
const noResults = computed(() => {
|
||||||
case "Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWork":
|
if (!isNotificationsLoaded.value) {
|
||||||
return appMessages.fr.the_action;
|
return false;
|
||||||
case "Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWorkEvaluationDocument":
|
} else {
|
||||||
return appMessages.fr.the_evaluation_document;
|
return notifications.value.count === 0;
|
||||||
case "Chill\\MainBundle\\Entity\\Workflow\\EntityWorkflow":
|
}
|
||||||
return appMessages.fr.the_workflow;
|
});
|
||||||
default:
|
|
||||||
throw "notification type unknown";
|
function getNotificationUrl(n: Notification): string {
|
||||||
}
|
return `/fr/notification/${n.id}/show`;
|
||||||
},
|
}
|
||||||
getEntityUrl(n) {
|
|
||||||
switch (n.relatedEntityClass) {
|
function getEntityName(n: Notification): string {
|
||||||
case "Chill\\ActivityBundle\\Entity\\Activity":
|
switch (n.relatedEntityClass) {
|
||||||
return `/fr/activity/${n.relatedEntityId}/show`;
|
case "Chill\\ActivityBundle\\Entity\\Activity":
|
||||||
case "Chill\\PersonBundle\\Entity\\AccompanyingPeriod":
|
return trans(THE_ACTIVITY);
|
||||||
return `/fr/parcours/${n.relatedEntityId}`;
|
case "Chill\\PersonBundle\\Entity\\AccompanyingPeriod":
|
||||||
case "Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWork":
|
return trans(THE_COURSE);
|
||||||
return `/fr/person/accompanying-period/work/${n.relatedEntityId}/show`;
|
case "Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWork":
|
||||||
case "Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWorkEvaluationDocument":
|
return trans(THE_ACTION);
|
||||||
return `/fr/person/accompanying-period/work/evaluation/document/${n.relatedEntityId}/show`;
|
case "Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWorkEvaluationDocument":
|
||||||
case "Chill\\MainBundle\\Entity\\Workflow\\EntityWorkflow":
|
return trans(THE_EVALUATION_DOCUMENT);
|
||||||
return `/fr/main/workflow/${n.relatedEntityId}/show`;
|
case "Chill\\MainBundle\\Entity\\Workflow\\EntityWorkflow":
|
||||||
default:
|
return trans(THE_WORKFLOW);
|
||||||
throw "notification type unknown";
|
default:
|
||||||
}
|
throw "notification type unknown";
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
};
|
|
||||||
|
function getEntityUrl(n: Notification): string {
|
||||||
|
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>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
@@ -1,36 +1,38 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="alert alert-light">
|
<div class="alert alert-light">
|
||||||
{{ $t("my_tasks.description_warning") }}
|
{{ trans(MY_TASKS_DESCRIPTION_WARNING) }}
|
||||||
</div>
|
</div>
|
||||||
<span v-if="noResultsAlert" class="chill-no-data-statement">{{
|
<span v-if="noResultsAlert" class="chill-no-data-statement">
|
||||||
$t("no_data")
|
{{ trans(NO_DATA) }}
|
||||||
}}</span>
|
</span>
|
||||||
<tab-table v-else>
|
<tab-table v-else>
|
||||||
<template #thead>
|
<template #thead>
|
||||||
<th scope="col">
|
<th scope="col">
|
||||||
{{ $t("warning_date") }}
|
{{ trans(WARNING_DATE) }}
|
||||||
</th>
|
</th>
|
||||||
<th scope="col">
|
<th scope="col">
|
||||||
{{ $t("max_date") }}
|
{{ trans(MAX_DATE) }}
|
||||||
</th>
|
</th>
|
||||||
<th scope="col">
|
<th scope="col">
|
||||||
{{ $t("task") }}
|
{{ trans(TASK) }}
|
||||||
</th>
|
</th>
|
||||||
<th scope="col" />
|
<th scope="col" />
|
||||||
</template>
|
</template>
|
||||||
<template #tbody>
|
<template #tbody>
|
||||||
<tr v-for="(t, i) in tasks.alert.results" :key="`task-alert-${i}`">
|
<tr v-for="(t, i) in tasks.alert.results" :key="`task-alert-${i}`">
|
||||||
<td v-if="null !== t.warningDate">
|
<td v-if="t.warningDate !== null">
|
||||||
{{ $d(t.warningDate.datetime, "short") }}
|
{{ $d(new Date(t.warningDate.datetime), "short") }}
|
||||||
</td>
|
</td>
|
||||||
<td v-else />
|
<td v-else />
|
||||||
<td>
|
<td>
|
||||||
<span class="outdated">{{ $d(t.endDate.datetime, "short") }}</span>
|
<span class="outdated">{{
|
||||||
|
$d(new Date(t.endDate.datetime), "short")
|
||||||
|
}}</span>
|
||||||
</td>
|
</td>
|
||||||
<td>{{ t.title }}</td>
|
<td>{{ t.title }}</td>
|
||||||
<td>
|
<td>
|
||||||
<a class="btn btn-sm btn-show" :href="getUrl(t)">
|
<a class="btn btn-sm btn-show" :href="getUrl(t)">
|
||||||
{{ $t("show_entity", { entity: $t("the_task") }) }}
|
{{ trans(SHOW_ENTITY, { entity: trans(THE_TASK) }) }}
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -38,21 +40,21 @@
|
|||||||
</tab-table>
|
</tab-table>
|
||||||
|
|
||||||
<div class="alert alert-light">
|
<div class="alert alert-light">
|
||||||
{{ $t("my_tasks.description_alert") }}
|
{{ trans(MY_TASKS_DESCRIPTION_ALERT) }}
|
||||||
</div>
|
</div>
|
||||||
<span v-if="noResultsWarning" class="chill-no-data-statement">{{
|
<span v-if="noResultsWarning" class="chill-no-data-statement">
|
||||||
$t("no_data")
|
{{ trans(NO_DATA) }}
|
||||||
}}</span>
|
</span>
|
||||||
<tab-table v-else>
|
<tab-table v-else>
|
||||||
<template #thead>
|
<template #thead>
|
||||||
<th scope="col">
|
<th scope="col">
|
||||||
{{ $t("warning_date") }}
|
{{ trans(WARNING_DATE) }}
|
||||||
</th>
|
</th>
|
||||||
<th scope="col">
|
<th scope="col">
|
||||||
{{ $t("max_date") }}
|
{{ trans(MAX_DATE) }}
|
||||||
</th>
|
</th>
|
||||||
<th scope="col">
|
<th scope="col">
|
||||||
{{ $t("task") }}
|
{{ trans(TASK) }}
|
||||||
</th>
|
</th>
|
||||||
<th scope="col" />
|
<th scope="col" />
|
||||||
</template>
|
</template>
|
||||||
@@ -60,14 +62,14 @@
|
|||||||
<tr v-for="(t, i) in tasks.warning.results" :key="`task-warning-${i}`">
|
<tr v-for="(t, i) in tasks.warning.results" :key="`task-warning-${i}`">
|
||||||
<td>
|
<td>
|
||||||
<span class="outdated">{{
|
<span class="outdated">{{
|
||||||
$d(t.warningDate.datetime, "short")
|
$d(new Date(t.warningDate.datetime), "short")
|
||||||
}}</span>
|
}}</span>
|
||||||
</td>
|
</td>
|
||||||
<td>{{ $d(t.endDate.datetime, "short") }}</td>
|
<td>{{ $d(new Date(t.endDate.datetime), "short") }}</td>
|
||||||
<td>{{ t.title }}</td>
|
<td>{{ t.title }}</td>
|
||||||
<td>
|
<td>
|
||||||
<a class="btn btn-sm btn-show" :href="getUrl(t)">
|
<a class="btn btn-sm btn-show" :href="getUrl(t)">
|
||||||
{{ $t("show_entity", { entity: $t("the_task") }) }}
|
{{ trans(SHOW_ENTITY, { entity: trans(THE_TASK) }) }}
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -75,39 +77,51 @@
|
|||||||
</tab-table>
|
</tab-table>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script lang="ts" setup>
|
||||||
import { mapState, mapGetters } from "vuex";
|
import { computed, ComputedRef } from "vue";
|
||||||
import TabTable from "./TabTable";
|
import { useStore } from "vuex";
|
||||||
|
import TabTable from "./TabTable.vue";
|
||||||
|
import {
|
||||||
|
MY_TASKS_DESCRIPTION_ALERT,
|
||||||
|
MY_TASKS_DESCRIPTION_WARNING,
|
||||||
|
MAX_DATE,
|
||||||
|
WARNING_DATE,
|
||||||
|
TASK,
|
||||||
|
SHOW_ENTITY,
|
||||||
|
THE_TASK,
|
||||||
|
NO_DATA,
|
||||||
|
trans,
|
||||||
|
} from "translator";
|
||||||
|
import { TasksState } from "./store/modules/homepage";
|
||||||
|
import { Alert, Warning } from "ChillPersonAssets/types";
|
||||||
|
|
||||||
export default {
|
const store = useStore();
|
||||||
name: "MyTasks",
|
|
||||||
components: {
|
const tasks: ComputedRef<TasksState> = computed(
|
||||||
TabTable,
|
() => store.state.homepage.tasks,
|
||||||
},
|
);
|
||||||
computed: {
|
const isTasksWarningLoaded = computed(() => store.getters.isTasksWarningLoaded);
|
||||||
...mapState(["tasks"]),
|
const isTasksAlertLoaded = computed(() => store.getters.isTasksAlertLoaded);
|
||||||
...mapGetters(["isTasksWarningLoaded", "isTasksAlertLoaded"]),
|
|
||||||
noResultsAlert() {
|
const noResultsAlert = computed(() => {
|
||||||
if (!this.isTasksAlertLoaded) {
|
if (!isTasksAlertLoaded.value) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
return this.tasks.alert.count === 0;
|
return tasks.value.alert.count === 0;
|
||||||
}
|
}
|
||||||
},
|
});
|
||||||
noResultsWarning() {
|
|
||||||
if (!this.isTasksWarningLoaded) {
|
const noResultsWarning = computed(() => {
|
||||||
return false;
|
if (!isTasksWarningLoaded.value) {
|
||||||
} else {
|
return false;
|
||||||
return this.tasks.warning.count === 0;
|
} else {
|
||||||
}
|
return tasks.value.warning.count === 0;
|
||||||
},
|
}
|
||||||
},
|
});
|
||||||
methods: {
|
|
||||||
getUrl(t) {
|
function getUrl(t: Warning | Alert): string {
|
||||||
return `/fr/task/single-task/${t.id}/show`;
|
return `/fr/task/single-task/${t.id}/show`;
|
||||||
},
|
}
|
||||||
},
|
|
||||||
};
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
@@ -0,0 +1,58 @@
|
|||||||
|
<template>
|
||||||
|
<div class="col-12">
|
||||||
|
<!-- Loading state -->
|
||||||
|
<div
|
||||||
|
v-if="isTicketLoading"
|
||||||
|
class="d-flex justify-content-center align-items-center"
|
||||||
|
style="height: 200px"
|
||||||
|
>
|
||||||
|
<div class="text-center">
|
||||||
|
<div class="spinner-border mb-3" role="status">
|
||||||
|
<span class="visually-hidden">{{
|
||||||
|
trans(CHILL_TICKET_LIST_LOADING_TICKET)
|
||||||
|
}}</span>
|
||||||
|
</div>
|
||||||
|
<div class="text-muted">
|
||||||
|
{{ trans(CHILL_TICKET_LIST_LOADING_TICKET) }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Ticket list -->
|
||||||
|
<ticket-list-component
|
||||||
|
v-else
|
||||||
|
:tickets="ticketList"
|
||||||
|
title=""
|
||||||
|
:hasMoreTickets="pagination.next !== null"
|
||||||
|
@fetchNextPage="fetchNextPage"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { computed } from "vue";
|
||||||
|
import { useStore } from "vuex";
|
||||||
|
// Components
|
||||||
|
import TicketListComponent from "../../../../../ChillTicketBundle/src/Resources/public/vuejs/TicketList/components/TicketListComponent.vue";
|
||||||
|
|
||||||
|
// Types
|
||||||
|
import { Pagination } from "ChillMainAssets/lib/api/apiMethods";
|
||||||
|
import { TicketSimple } from "src/Bundle/ChillTicketBundle/src/Resources/public/types";
|
||||||
|
|
||||||
|
// Translation
|
||||||
|
import { CHILL_TICKET_LIST_LOADING_TICKET, trans } from "translator";
|
||||||
|
|
||||||
|
const store = useStore();
|
||||||
|
const pagination = computed(() => store.getters.getPagination as Pagination);
|
||||||
|
|
||||||
|
const ticketList = computed(
|
||||||
|
() => store.getters.getTicketList as TicketSimple[],
|
||||||
|
);
|
||||||
|
const isTicketLoading = computed(() => store.getters.isTicketLoading);
|
||||||
|
|
||||||
|
const fetchNextPage = async () => {
|
||||||
|
if (pagination.value.next) {
|
||||||
|
await store.dispatch("fetchTicketListByUrl", pagination.value.next);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
@@ -1,26 +1,27 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="alert alert-light">
|
<div class="alert alert-light">
|
||||||
{{ $t("my_workflows.description") }}
|
{{ trans(MY_WORKFLOWS_DESCRIPTION) }}
|
||||||
</div>
|
</div>
|
||||||
<my-workflows-table :workflows="workflows" />
|
<my-workflows-table :workflows="workflows" />
|
||||||
|
|
||||||
<div class="alert alert-light">
|
<div class="alert alert-light">
|
||||||
{{ $t("my_workflows.description_cc") }}
|
{{ trans(MY_WORKFLOWS_DESCRIPTION_CC) }}
|
||||||
</div>
|
</div>
|
||||||
<my-workflows-table :workflows="workflowsCc" />
|
<my-workflows-table :workflows="workflowsCc" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script lang="ts" setup>
|
||||||
import { mapState } from "vuex";
|
import { computed } from "vue";
|
||||||
|
import { useStore } from "vuex";
|
||||||
import MyWorkflowsTable from "./MyWorkflowsTable.vue";
|
import MyWorkflowsTable from "./MyWorkflowsTable.vue";
|
||||||
|
import {
|
||||||
|
MY_WORKFLOWS_DESCRIPTION,
|
||||||
|
MY_WORKFLOWS_DESCRIPTION_CC,
|
||||||
|
trans,
|
||||||
|
} from "translator";
|
||||||
|
|
||||||
export default {
|
const store = useStore();
|
||||||
name: "MyWorkflows",
|
|
||||||
components: {
|
const workflows = computed(() => store.state.homepage.workflows);
|
||||||
MyWorkflowsTable,
|
const workflowsCc = computed(() => store.state.homepage.workflowsCc);
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapState(["workflows", "workflowsCc"]),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
</script>
|
</script>
|
||||||
|
@@ -1,17 +1,17 @@
|
|||||||
<template>
|
<template>
|
||||||
<span v-if="hasNoResults(workflows)" class="chill-no-data-statement">{{
|
<span v-if="hasNoResults" class="chill-no-data-statement">
|
||||||
$t("no_data")
|
{{ trans(NO_DATA) }}
|
||||||
}}</span>
|
</span>
|
||||||
<tab-table v-else>
|
<tab-table v-else>
|
||||||
<template #thead>
|
<template #thead>
|
||||||
<th scope="col">
|
<th scope="col">
|
||||||
{{ $t("Object_workflow") }}
|
{{ trans(OBJECT_WORKFLOW) }}
|
||||||
</th>
|
</th>
|
||||||
<th scope="col">
|
<th scope="col">
|
||||||
{{ $t("Step") }}
|
{{ trans(STEP) }}
|
||||||
</th>
|
</th>
|
||||||
<th scope="col">
|
<th scope="col">
|
||||||
{{ $t("concerned_users") }}
|
{{ trans(CONCERNED_USERS) }}
|
||||||
</th>
|
</th>
|
||||||
<th scope="col" />
|
<th scope="col" />
|
||||||
</template>
|
</template>
|
||||||
@@ -29,7 +29,7 @@
|
|||||||
<span
|
<span
|
||||||
v-if="w.isOnHoldAtCurrentStep"
|
v-if="w.isOnHoldAtCurrentStep"
|
||||||
class="badge bg-success rounded-pill"
|
class="badge bg-success rounded-pill"
|
||||||
>{{ $t("on_hold") }}</span
|
>{{ trans(ON_HOLD) }}</span
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
@@ -46,7 +46,7 @@
|
|||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<a class="btn btn-sm btn-show" :href="getUrl(w)">
|
<a class="btn btn-sm btn-show" :href="getUrl(w)">
|
||||||
{{ $t("show_entity", { entity: $t("the_workflow") }) }}
|
{{ trans(SHOW_ENTITY, { entity: trans(THE_WORKFLOW) }) }}
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -54,38 +54,48 @@
|
|||||||
</tab-table>
|
</tab-table>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script lang="ts" setup>
|
||||||
import { mapGetters } from "vuex";
|
import { computed } from "vue";
|
||||||
import TabTable from "./TabTable";
|
import { useStore } from "vuex";
|
||||||
import OnTheFly from "ChillMainAssets/vuejs/OnTheFly/components/OnTheFly";
|
import TabTable from "./TabTable.vue";
|
||||||
|
import OnTheFly from "ChillMainAssets/vuejs/OnTheFly/components/OnTheFly.vue";
|
||||||
|
import { Workflow } from "ChillPersonAssets/types";
|
||||||
|
import {
|
||||||
|
CONCERNED_USERS,
|
||||||
|
OBJECT_WORKFLOW,
|
||||||
|
ON_HOLD,
|
||||||
|
SHOW_ENTITY,
|
||||||
|
THE_WORKFLOW,
|
||||||
|
NO_DATA,
|
||||||
|
STEP,
|
||||||
|
trans,
|
||||||
|
} from "translator";
|
||||||
|
import { PaginationResponse } from "ChillMainAssets/lib/api/apiMethods";
|
||||||
|
|
||||||
export default {
|
const props = defineProps<{
|
||||||
name: "MyWorkflows",
|
workflows: PaginationResponse<Workflow>;
|
||||||
components: {
|
}>();
|
||||||
TabTable,
|
|
||||||
OnTheFly,
|
const store = useStore();
|
||||||
},
|
|
||||||
props: ["workflows"],
|
const isWorkflowsLoaded = computed(() => store.getters.isWorkflowsLoaded);
|
||||||
computed: {
|
|
||||||
...mapGetters(["isWorkflowsLoaded"]),
|
const hasNoResults = computed(() => {
|
||||||
},
|
if (!isWorkflowsLoaded.value) {
|
||||||
methods: {
|
return false;
|
||||||
hasNoResults(workflows) {
|
} else {
|
||||||
if (!this.isWorkflowsLoaded) {
|
return props.workflows.count === 0;
|
||||||
return false;
|
}
|
||||||
} else {
|
});
|
||||||
return workflows.count === 0;
|
|
||||||
}
|
function getUrl(w: Workflow): string {
|
||||||
},
|
return `/fr/main/workflow/${w.id}/show`;
|
||||||
getUrl(w) {
|
}
|
||||||
return `/fr/main/workflow/${w.id}/show`;
|
|
||||||
},
|
function getStep(w: Workflow): string {
|
||||||
getStep(w) {
|
const lastStep = w.steps.length - 1;
|
||||||
const lastStep = w.steps.length - 1;
|
return w.steps[lastStep].currentStep.text;
|
||||||
return w.steps[lastStep].currentStep.text;
|
}
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
@@ -1,27 +1,26 @@
|
|||||||
// CURRENTLY NOT IN USE
|
|
||||||
<template>
|
<template>
|
||||||
<div class="accompanying-course-work">
|
<div class="accompanying-course-work">
|
||||||
<div class="alert alert-light">
|
<div class="alert alert-light">
|
||||||
{{ $t("my_works.description") }}
|
{{ trans(MY_WORKS_DESCRIPTION) }}
|
||||||
</div>
|
</div>
|
||||||
<span v-if="noResults" class="chill-no-data-statement">{{
|
<span v-if="noResults" class="chill-no-data-statement">
|
||||||
$t("no_data")
|
{{ trans(NO_DATA) }}
|
||||||
}}</span>
|
</span>
|
||||||
<tab-table v-else>
|
<tab-table v-else>
|
||||||
<template #thead>
|
<template #thead>
|
||||||
<th scope="col">
|
<th scope="col">
|
||||||
{{ $t("StartDate") }}
|
{{ trans(START_DATE) }}
|
||||||
</th>
|
</th>
|
||||||
<th scope="col">
|
<th scope="col">
|
||||||
{{ $t("SocialAction") }}
|
{{ trans(SOCIAL_ACTION) }}
|
||||||
</th>
|
</th>
|
||||||
<th scope="col">
|
<th scope="col">
|
||||||
{{ $t("concerned_persons") }}
|
{{ trans(CONCERNED_PERSONS) }}
|
||||||
</th>
|
</th>
|
||||||
<th scope="col" />
|
<th scope="col" />
|
||||||
</template>
|
</template>
|
||||||
<template #tbody>
|
<template #tbody>
|
||||||
<tr v-for="(w, i) in works.results" :key="`works-${i}`">
|
<tr v-for="(w, i) in works.value.results" :key="`works-${i}`">
|
||||||
<td>{{ $d(w.startDate.datetime, "short") }}</td>
|
<td>{{ $d(w.startDate.datetime, "short") }}</td>
|
||||||
<td>
|
<td>
|
||||||
<span class="chill-entity entity-social-issue">
|
<span class="chill-entity entity-social-issue">
|
||||||
@@ -51,8 +50,8 @@
|
|||||||
<div class="btn-group-vertical" role="group" aria-label="Actions">
|
<div class="btn-group-vertical" role="group" aria-label="Actions">
|
||||||
<a class="btn btn-sm btn-update" :href="getUrl(w)">
|
<a class="btn btn-sm btn-update" :href="getUrl(w)">
|
||||||
{{
|
{{
|
||||||
$t("show_entity", {
|
trans(SHOW_ENTITY, {
|
||||||
entity: $t("the_action"),
|
entity: trans(THE_ACTION),
|
||||||
})
|
})
|
||||||
}}
|
}}
|
||||||
</a>
|
</a>
|
||||||
@@ -61,8 +60,8 @@
|
|||||||
:href="getUrl(w.accompanyingPeriod)"
|
:href="getUrl(w.accompanyingPeriod)"
|
||||||
>
|
>
|
||||||
{{
|
{{
|
||||||
$t("show_entity", {
|
trans(SHOW_ENTITY, {
|
||||||
entity: $t("the_course"),
|
entity: trans(THE_COURSE),
|
||||||
})
|
})
|
||||||
}}
|
}}
|
||||||
</a>
|
</a>
|
||||||
@@ -74,41 +73,47 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script lang="ts" setup>
|
||||||
import { mapState, mapGetters } from "vuex";
|
import { computed } from "vue";
|
||||||
import TabTable from "./TabTable";
|
import { useStore } from "vuex";
|
||||||
import OnTheFly from "ChillMainAssets/vuejs/OnTheFly/components/OnTheFly";
|
import TabTable from "./TabTable.vue";
|
||||||
|
import OnTheFly from "ChillMainAssets/vuejs/OnTheFly/components/OnTheFly.vue";
|
||||||
|
import {
|
||||||
|
MY_WORKS_DESCRIPTION,
|
||||||
|
CONCERNED_PERSONS,
|
||||||
|
SHOW_ENTITY,
|
||||||
|
THE_COURSE,
|
||||||
|
THE_ACTION,
|
||||||
|
SOCIAL_ACTION,
|
||||||
|
START_DATE,
|
||||||
|
NO_DATA,
|
||||||
|
trans,
|
||||||
|
} from "translator";
|
||||||
|
import { Workflow } from "ChillPersonAssets/types";
|
||||||
|
|
||||||
export default {
|
const store = useStore();
|
||||||
name: "MyWorks",
|
|
||||||
components: {
|
const works = computed(() => store.state.homepage.works);
|
||||||
TabTable,
|
const isWorksLoaded = computed(() => store.getters.isWorksLoaded);
|
||||||
OnTheFly,
|
|
||||||
},
|
const noResults = computed(() => {
|
||||||
computed: {
|
if (!isWorksLoaded.value) {
|
||||||
...mapState(["works"]),
|
return false;
|
||||||
...mapGetters(["isWorksLoaded"]),
|
} else {
|
||||||
noResults() {
|
return works.value.count === 0;
|
||||||
if (!this.isWorksLoaded) {
|
}
|
||||||
return false;
|
});
|
||||||
} else {
|
|
||||||
return this.works.count === 0;
|
function getUrl(e: Workflow): string {
|
||||||
}
|
switch (e.type) {
|
||||||
},
|
case "accompanying_period_work":
|
||||||
},
|
return `/fr/person/accompanying-period/work/${e.id}/edit`;
|
||||||
methods: {
|
case "accompanying_period":
|
||||||
getUrl(e) {
|
return `/fr/parcours/${e.id}`;
|
||||||
switch (e.type) {
|
default:
|
||||||
case "accompanying_period_work":
|
throw "entity type unknown";
|
||||||
return `/fr/person/accompanying-period/work/${e.id}/edit`;
|
}
|
||||||
case "accompanying_period":
|
}
|
||||||
return `/fr/parcours/${e.id}`;
|
|
||||||
default:
|
|
||||||
throw "entity type unknown";
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped></style>
|
<style scoped></style>
|
||||||
|
@@ -4,14 +4,14 @@
|
|||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script lang="ts" setup>
|
||||||
export default {
|
import { computed } from "vue";
|
||||||
name: "TabCounter",
|
|
||||||
props: ["count"],
|
const props = defineProps<{
|
||||||
computed: {
|
count: number;
|
||||||
isCounterAvailable() {
|
}>();
|
||||||
return typeof this.count !== "undefined" && this.count > 0;
|
|
||||||
},
|
const isCounterAvailable = computed(
|
||||||
},
|
() => typeof props.count !== "undefined" && props.count > 0,
|
||||||
};
|
);
|
||||||
</script>
|
</script>
|
||||||
|
@@ -11,11 +11,8 @@
|
|||||||
</table>
|
</table>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script lang="ts" setup>
|
||||||
export default {
|
// Pas de props à définir, composant slot simple
|
||||||
name: "TabTable",
|
|
||||||
props: [],
|
|
||||||
};
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped></style>
|
<style scoped></style>
|
||||||
|
@@ -1,89 +0,0 @@
|
|||||||
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",
|
|
||||||
on_hold: "En attente",
|
|
||||||
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 };
|
|
@@ -0,0 +1,55 @@
|
|||||||
|
import { createStore } from "vuex";
|
||||||
|
import { State as HomepageStates, moduleHomepage } from "./modules/homepage";
|
||||||
|
|
||||||
|
import {
|
||||||
|
State as TicketListStates,
|
||||||
|
moduleTicketList,
|
||||||
|
} from "../../../../../../ChillTicketBundle/src/Resources/public/vuejs/TicketApp/store/modules/ticket_list";
|
||||||
|
import {
|
||||||
|
State as TicketStates,
|
||||||
|
moduleTicket,
|
||||||
|
} from "../../../../../../ChillTicketBundle/src/Resources/public/vuejs/TicketApp/store/modules/ticket";
|
||||||
|
import {
|
||||||
|
State as CommentStates,
|
||||||
|
moduleComment,
|
||||||
|
} from "../../../../../../ChillTicketBundle/src/Resources/public/vuejs/TicketApp/store/modules/comment";
|
||||||
|
import {
|
||||||
|
moduleMotive,
|
||||||
|
State as MotiveStates,
|
||||||
|
} from "../../../../../../ChillTicketBundle/src/Resources/public/vuejs/TicketApp/store/modules/motive";
|
||||||
|
import {
|
||||||
|
State as AddresseeStates,
|
||||||
|
moduleAddressee,
|
||||||
|
} from "../../../../../../ChillTicketBundle/src/Resources/public/vuejs/TicketApp/store/modules/addressee";
|
||||||
|
import {
|
||||||
|
modulePersons,
|
||||||
|
State as PersonsState,
|
||||||
|
} from "../../../../../../ChillTicketBundle/src/Resources/public/vuejs/TicketApp/store/modules/persons";
|
||||||
|
|
||||||
|
import {
|
||||||
|
moduleUser,
|
||||||
|
State as UserState,
|
||||||
|
} from "../../../../../../ChillTicketBundle/src/Resources/public/vuejs/TicketApp/store/modules/user";
|
||||||
|
|
||||||
|
export interface RootState {
|
||||||
|
homepage: HomepageStates;
|
||||||
|
motive: MotiveStates;
|
||||||
|
ticket: TicketStates;
|
||||||
|
comment: CommentStates;
|
||||||
|
addressee: AddresseeStates;
|
||||||
|
persons: PersonsState;
|
||||||
|
ticketList: TicketListStates;
|
||||||
|
user: UserState;
|
||||||
|
}
|
||||||
|
export const store = createStore<RootState>({
|
||||||
|
modules: {
|
||||||
|
homepage: moduleHomepage,
|
||||||
|
motive: moduleMotive,
|
||||||
|
ticket: moduleTicket,
|
||||||
|
comment: moduleComment,
|
||||||
|
addressee: moduleAddressee,
|
||||||
|
person: modulePersons,
|
||||||
|
ticketList: moduleTicketList,
|
||||||
|
user: moduleUser,
|
||||||
|
},
|
||||||
|
});
|
@@ -1,90 +1,113 @@
|
|||||||
import "es6-promise/auto";
|
import "es6-promise/auto";
|
||||||
import { createStore } from "vuex";
|
import { Module } from "vuex";
|
||||||
import { makeFetch } from "ChillMainAssets/lib/api/apiMethods";
|
import {
|
||||||
|
makeFetch,
|
||||||
|
PaginationResponse,
|
||||||
|
} from "ChillMainAssets/lib/api/apiMethods";
|
||||||
|
import {
|
||||||
|
AccompanyingCourse,
|
||||||
|
Alert,
|
||||||
|
Evaluation,
|
||||||
|
Warning,
|
||||||
|
Workflow,
|
||||||
|
WorflowCc,
|
||||||
|
} from "ChillPersonAssets/types";
|
||||||
|
import { RootState } from "..";
|
||||||
|
|
||||||
const debug = process.env.NODE_ENV !== "production";
|
export interface TasksState {
|
||||||
|
warning: PaginationResponse<Warning>;
|
||||||
|
alert: PaginationResponse<Alert>;
|
||||||
|
}
|
||||||
|
|
||||||
const isEmpty = (obj) => {
|
export interface State {
|
||||||
return (
|
evaluations: PaginationResponse<Evaluation>;
|
||||||
obj &&
|
tasks: TasksState;
|
||||||
Object.keys(obj).length <= 1 &&
|
accompanyingCourses: PaginationResponse<AccompanyingCourse>;
|
||||||
Object.getPrototypeOf(obj) === Object.prototype
|
notifications: PaginationResponse<Notification>;
|
||||||
);
|
workflows: PaginationResponse<Workflow>;
|
||||||
};
|
workflowsCc: PaginationResponse<WorflowCc>;
|
||||||
|
errorMsg: unknown[];
|
||||||
|
loading: boolean;
|
||||||
|
ticketsLoading: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
const store = createStore({
|
export const moduleHomepage: Module<State, RootState> = {
|
||||||
strict: debug,
|
|
||||||
state: {
|
state: {
|
||||||
// works: {},
|
evaluations: {
|
||||||
evaluations: {},
|
count: 0,
|
||||||
|
} as PaginationResponse<Evaluation>,
|
||||||
tasks: {
|
tasks: {
|
||||||
warning: {},
|
warning: {
|
||||||
alert: {},
|
count: 0,
|
||||||
|
} as PaginationResponse<Warning>,
|
||||||
|
alert: {
|
||||||
|
count: 0,
|
||||||
|
} as PaginationResponse<Alert>,
|
||||||
},
|
},
|
||||||
accompanyingCourses: {},
|
accompanyingCourses: {
|
||||||
notifications: {},
|
count: 0,
|
||||||
workflows: {},
|
} as PaginationResponse<AccompanyingCourse>,
|
||||||
workflowsCc: {},
|
notifications: {
|
||||||
|
count: 0,
|
||||||
|
} as PaginationResponse<Notification>,
|
||||||
|
workflows: {
|
||||||
|
count: 0,
|
||||||
|
} as PaginationResponse<Workflow>,
|
||||||
|
workflowsCc: {
|
||||||
|
count: 0,
|
||||||
|
} as PaginationResponse<WorflowCc>,
|
||||||
|
ticketsLoading: false,
|
||||||
errorMsg: [],
|
errorMsg: [],
|
||||||
loading: false,
|
loading: false,
|
||||||
},
|
},
|
||||||
getters: {
|
getters: {
|
||||||
// isWorksLoaded(state) {
|
isTicketLoading: (state) => {
|
||||||
// return !isEmpty(state.works);
|
return state.ticketsLoading;
|
||||||
// },
|
},
|
||||||
isEvaluationsLoaded(state) {
|
isEvaluationsLoaded(state) {
|
||||||
return !isEmpty(state.evaluations);
|
return Array.isArray(state.evaluations.results);
|
||||||
},
|
},
|
||||||
isTasksWarningLoaded(state) {
|
isTasksWarningLoaded(state) {
|
||||||
return !isEmpty(state.tasks.warning);
|
return Array.isArray(state.tasks.warning.results);
|
||||||
},
|
},
|
||||||
isTasksAlertLoaded(state) {
|
isTasksAlertLoaded(state) {
|
||||||
return !isEmpty(state.tasks.alert);
|
return Array.isArray(state.tasks.alert.results);
|
||||||
},
|
},
|
||||||
isAccompanyingCoursesLoaded(state) {
|
isAccompanyingCoursesLoaded(state) {
|
||||||
return !isEmpty(state.accompanyingCourses);
|
return Array.isArray(state.accompanyingCourses.results);
|
||||||
},
|
},
|
||||||
isNotificationsLoaded(state) {
|
isNotificationsLoaded(state) {
|
||||||
return !isEmpty(state.notifications);
|
return Array.isArray(state.notifications.results);
|
||||||
},
|
},
|
||||||
isWorkflowsLoaded(state) {
|
isWorkflowsLoaded(state) {
|
||||||
return !isEmpty(state.workflows);
|
return Array.isArray(state.workflows.results);
|
||||||
},
|
},
|
||||||
counter(state) {
|
counter(state, getters, rootState, rootGetters) {
|
||||||
return {
|
return {
|
||||||
// works: state.works.count,
|
tickets: rootGetters["ticketList/getCount"] || 0,
|
||||||
evaluations: state.evaluations.count,
|
evaluations: state.evaluations.count || 0,
|
||||||
tasksWarning: state.tasks.warning.count,
|
tasksWarning: state.tasks.warning.count || 0,
|
||||||
tasksAlert: state.tasks.alert.count,
|
tasksAlert: state.tasks.alert.count || 0,
|
||||||
accompanyingCourses: state.accompanyingCourses.count,
|
accompanyingCourses: state.accompanyingCourses.count || 0,
|
||||||
notifications: state.notifications.count,
|
notifications: state.notifications.count || 0,
|
||||||
workflows: state.workflows.count,
|
workflows: state.workflows.count || 0,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
mutations: {
|
mutations: {
|
||||||
// addWorks(state, works) {
|
|
||||||
// //console.log('addWorks', works);
|
|
||||||
// state.works = works;
|
|
||||||
// },
|
|
||||||
addEvaluations(state, evaluations) {
|
addEvaluations(state, evaluations) {
|
||||||
//console.log('addEvaluations', evaluations);
|
|
||||||
state.evaluations = evaluations;
|
state.evaluations = evaluations;
|
||||||
},
|
},
|
||||||
addTasksWarning(state, tasks) {
|
addTasksWarning(state, tasks) {
|
||||||
//console.log('addTasksWarning', tasks);
|
|
||||||
state.tasks.warning = tasks;
|
state.tasks.warning = tasks;
|
||||||
},
|
},
|
||||||
addTasksAlert(state, tasks) {
|
addTasksAlert(state, tasks) {
|
||||||
//console.log('addTasksAlert', tasks);
|
|
||||||
state.tasks.alert = tasks;
|
state.tasks.alert = tasks;
|
||||||
},
|
},
|
||||||
addCourses(state, courses) {
|
addCourses(state, courses) {
|
||||||
//console.log('addCourses', courses);
|
|
||||||
state.accompanyingCourses = courses;
|
state.accompanyingCourses = courses;
|
||||||
},
|
},
|
||||||
addNotifications(state, notifications) {
|
addNotifications(state, notifications) {
|
||||||
//console.log('addNotifications', notifications);
|
|
||||||
state.notifications = notifications;
|
state.notifications = notifications;
|
||||||
},
|
},
|
||||||
addWorkflows(state, workflows) {
|
addWorkflows(state, workflows) {
|
||||||
@@ -96,29 +119,29 @@ const store = createStore({
|
|||||||
setLoading(state, bool) {
|
setLoading(state, bool) {
|
||||||
state.loading = bool;
|
state.loading = bool;
|
||||||
},
|
},
|
||||||
|
setTicketsLoading(state, bool) {
|
||||||
|
state.ticketsLoading = bool;
|
||||||
|
},
|
||||||
catchError(state, error) {
|
catchError(state, error) {
|
||||||
state.errorMsg.push(error);
|
state.errorMsg.push(error);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
getByTab({ commit, getters }, { tab, param }) {
|
async getByTab({ commit, getters, dispatch }, { tab, param }) {
|
||||||
switch (tab) {
|
switch (tab) {
|
||||||
// case 'MyWorks':
|
case "MyTickets":
|
||||||
// if (!getters.isWorksLoaded) {
|
if (!getters.isTicketsLoaded) {
|
||||||
// commit('setLoading', true);
|
commit("setTicketsLoading", true);
|
||||||
// const url = `/api/1.0/person/accompanying-period/work/my-near-end${'?'+ param}`;
|
// Utilise l'action du module ticket_list
|
||||||
// makeFetch('GET', url)
|
await dispatch(
|
||||||
// .then((response) => {
|
"fetchTicketList",
|
||||||
// commit('addWorks', response);
|
{ byAddresseeToMe: true },
|
||||||
// commit('setLoading', false);
|
{ root: true },
|
||||||
// })
|
);
|
||||||
// .catch((error) => {
|
|
||||||
// commit('catchError', error);
|
commit("setTicketsLoading", false);
|
||||||
// throw error;
|
}
|
||||||
// })
|
break;
|
||||||
// ;
|
|
||||||
// }
|
|
||||||
// break;
|
|
||||||
case "MyEvaluations":
|
case "MyEvaluations":
|
||||||
if (!getters.isEvaluationsLoaded) {
|
if (!getters.isEvaluationsLoaded) {
|
||||||
commit("setLoading", true);
|
commit("setLoading", true);
|
||||||
@@ -180,7 +203,6 @@ const store = createStore({
|
|||||||
const url = `/api/1.0/main/notification/my/unread${"?" + param}`;
|
const url = `/api/1.0/main/notification/my/unread${"?" + param}`;
|
||||||
makeFetch("GET", url)
|
makeFetch("GET", url)
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
console.log("notifications", response);
|
|
||||||
commit("addNotifications", response);
|
commit("addNotifications", response);
|
||||||
commit("setLoading", false);
|
commit("setLoading", false);
|
||||||
})
|
})
|
||||||
@@ -217,6 +239,4 @@ const store = createStore({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
};
|
||||||
|
|
||||||
export { store };
|
|
@@ -46,10 +46,7 @@
|
|||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<ul
|
<ul class="badge-suggest add-items inline text-end">
|
||||||
class="badge-suggest add-items inline"
|
|
||||||
style="justify-content: flex-end; display: flex"
|
|
||||||
>
|
|
||||||
<li
|
<li
|
||||||
v-for="s in suggested"
|
v-for="s in suggested"
|
||||||
:key="s.type + s.id"
|
:key="s.type + s.id"
|
||||||
|
@@ -44,16 +44,16 @@ class SearchUserGroupApiProvider implements SearchApiInterface, LocaleAwareInter
|
|||||||
|
|
||||||
public function provideQuery(string $pattern, array $parameters): SearchApiQuery
|
public function provideQuery(string $pattern, array $parameters): SearchApiQuery
|
||||||
{
|
{
|
||||||
return $this->userGroupRepository->provideSearchApiQuery($pattern, $this->getLocale(), 'user-group');
|
return $this->userGroupRepository->provideSearchApiQuery($pattern, $this->getLocale(), 'user_group');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function supportsResult(string $key, array $metadatas): bool
|
public function supportsResult(string $key, array $metadatas): bool
|
||||||
{
|
{
|
||||||
return 'user-group' === $key;
|
return 'user_group' === $key;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function supportsTypes(string $pattern, array $types, array $parameters): bool
|
public function supportsTypes(string $pattern, array $types, array $parameters): bool
|
||||||
{
|
{
|
||||||
return in_array('user-group', $types, true);
|
return in_array('user_group', $types, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -305,7 +305,7 @@ paths:
|
|||||||
- thirdparty
|
- thirdparty
|
||||||
- user
|
- user
|
||||||
- household
|
- household
|
||||||
- user-group
|
- user_group
|
||||||
responses:
|
responses:
|
||||||
200:
|
200:
|
||||||
description: "OK"
|
description: "OK"
|
||||||
|
@@ -26,7 +26,7 @@ module.exports = function (encore, entries) {
|
|||||||
);
|
);
|
||||||
encore.addEntry(
|
encore.addEntry(
|
||||||
"page_homepage_widget",
|
"page_homepage_widget",
|
||||||
__dirname + "/Resources/public/page/homepage_widget/index.js",
|
__dirname + "/Resources/public/page/homepage_widget/index.ts",
|
||||||
);
|
);
|
||||||
encore.addEntry(
|
encore.addEntry(
|
||||||
"page_export",
|
"page_export",
|
||||||
|
@@ -191,3 +191,61 @@ pick_entity:
|
|||||||
one {Tiers}
|
one {Tiers}
|
||||||
other {Tiers}
|
other {Tiers}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
loading: "Chargement..."
|
||||||
|
main_title: "Vue d'ensemble"
|
||||||
|
my_tickets.tab: "Mes Tickets"
|
||||||
|
my_works.tab: "Mes actions"
|
||||||
|
my_works.description: "Liste des actions d'accompagnement dont je suis référent et qui arrivent à échéance."
|
||||||
|
my_evaluations.tab: "Mes évaluations"
|
||||||
|
my_evaluations.description: "Liste des évaluations dont je suis référent et qui arrivent à échéance."
|
||||||
|
my_tasks.tab: "Mes tâches"
|
||||||
|
my_tasks.description_alert: "Liste des tâches auxquelles je suis assigné et dont la date de rappel est dépassée."
|
||||||
|
my_tasks.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"
|
||||||
|
my_accompanying_courses.description: "Liste des parcours d'accompagnement que l'on vient de m'attribuer depuis moins de 15 jours."
|
||||||
|
my_notifications.tab: "Mes nouvelles notifications"
|
||||||
|
my_notifications.description: "Liste des notifications reçues et non lues."
|
||||||
|
my_workflows.tab: "Mes workflows"
|
||||||
|
my_workflows.description: "Liste des workflows en attente d'une action."
|
||||||
|
my_workflows.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"
|
||||||
|
on_hold: "En attente"
|
||||||
|
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, plural, one {# notification non lue} other {# notifications non lues}}"
|
||||||
|
counter.assignated_courses: "{n, plural, one {# parcours récent assigné} other {# parcours récents assignés}}"
|
||||||
|
counter.assignated_actions: "{n, plural, one {# action assignée} other {# actions assignées}}"
|
||||||
|
counter.assignated_evaluations: "{n, plural, one {# évaluation assignée} other {# évaluations assignées}}"
|
||||||
|
counter.alert_tasks: "{n, plural, one {# tâche en rappel} other {# tâches en rappel}}"
|
||||||
|
counter.warning_tasks: "{n, plural, one {# tâche à échéance} other {# tâches à échéance}}"
|
||||||
|
emergency: "Urgent"
|
||||||
|
confidential: "Confidentiel"
|
||||||
|
automatic_notification: "Notification automatique"
|
||||||
|
widget.news.title: "Actualités"
|
||||||
|
widget.news.readMore: "Lire la suite"
|
||||||
|
widget.news.date: "Date"
|
||||||
|
widget.news.none: "Aucune actualité"
|
||||||
|
@@ -14,12 +14,12 @@ import {
|
|||||||
import { StoredObject } from "ChillDocStoreAssets/types";
|
import { StoredObject } from "ChillDocStoreAssets/types";
|
||||||
import { Thirdparty } from "../../../ChillThirdPartyBundle/Resources/public/types";
|
import { Thirdparty } from "../../../ChillThirdPartyBundle/Resources/public/types";
|
||||||
import { Calendar } from "../../../ChillCalendarBundle/Resources/public/types";
|
import { Calendar } from "../../../ChillCalendarBundle/Resources/public/types";
|
||||||
|
import Person from "./vuejs/_components/OnTheFly/Person.vue";
|
||||||
|
|
||||||
export interface AltName {
|
export interface AltName {
|
||||||
label: string;
|
label: string;
|
||||||
key: string;
|
key: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Person {
|
export interface Person {
|
||||||
id: number;
|
id: number;
|
||||||
type: "person";
|
type: "person";
|
||||||
@@ -45,6 +45,7 @@ export interface Person {
|
|||||||
|
|
||||||
export interface AccompanyingPeriod {
|
export interface AccompanyingPeriod {
|
||||||
id: number;
|
id: number;
|
||||||
|
type: "accompanying_period";
|
||||||
addressLocation?: Address | null;
|
addressLocation?: Address | null;
|
||||||
administrativeLocation?: Location | null;
|
administrativeLocation?: Location | null;
|
||||||
calendars: Calendar[];
|
calendars: Calendar[];
|
||||||
@@ -81,6 +82,7 @@ export interface AccompanyingPeriod {
|
|||||||
|
|
||||||
export interface AccompanyingPeriodWork {
|
export interface AccompanyingPeriodWork {
|
||||||
id: number;
|
id: number;
|
||||||
|
type: "accompanying_period_work";
|
||||||
accompanyingPeriod?: AccompanyingPeriod;
|
accompanyingPeriod?: AccompanyingPeriod;
|
||||||
accompanyingPeriodWorkEvaluations: AccompanyingPeriodWorkEvaluation[];
|
accompanyingPeriodWorkEvaluations: AccompanyingPeriodWorkEvaluation[];
|
||||||
createdAt?: string;
|
createdAt?: string;
|
||||||
@@ -105,6 +107,7 @@ export interface AccompanyingPeriodWork {
|
|||||||
|
|
||||||
export interface SocialAction {
|
export interface SocialAction {
|
||||||
id: number;
|
id: number;
|
||||||
|
text: string;
|
||||||
parent?: SocialAction | null;
|
parent?: SocialAction | null;
|
||||||
children: SocialAction[];
|
children: SocialAction[];
|
||||||
issue?: SocialIssue | null;
|
issue?: SocialIssue | null;
|
||||||
@@ -166,6 +169,7 @@ export interface AccompanyingPeriodLocationHistory {
|
|||||||
|
|
||||||
export interface SocialIssue {
|
export interface SocialIssue {
|
||||||
id: number;
|
id: number;
|
||||||
|
text: string;
|
||||||
parent?: SocialIssue | null;
|
parent?: SocialIssue | null;
|
||||||
children: SocialIssue[];
|
children: SocialIssue[];
|
||||||
socialActions?: SocialAction[] | null;
|
socialActions?: SocialAction[] | null;
|
||||||
@@ -206,6 +210,7 @@ export interface AccompanyingPeriodWorkGoal {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface AccompanyingPeriodWorkEvaluation {
|
export interface AccompanyingPeriodWorkEvaluation {
|
||||||
|
type: "accompanying_period_work_evaluation";
|
||||||
accompanyingPeriodWork: AccompanyingPeriodWork | null;
|
accompanyingPeriodWork: AccompanyingPeriodWork | null;
|
||||||
comment: string;
|
comment: string;
|
||||||
createdAt: DateTime | null;
|
createdAt: DateTime | null;
|
||||||
@@ -236,6 +241,68 @@ export interface Evaluation {
|
|||||||
notificationDelay: string;
|
notificationDelay: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface Step {
|
||||||
|
currentStep: {
|
||||||
|
text: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Workflow {
|
||||||
|
id: number;
|
||||||
|
title: string;
|
||||||
|
type: "accompanying_period_work" | "accompanying_period";
|
||||||
|
isOnHoldAtCurrentStep: boolean;
|
||||||
|
datas: {
|
||||||
|
persons: Person[];
|
||||||
|
};
|
||||||
|
steps: Step[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface WorflowCc {
|
||||||
|
id: number;
|
||||||
|
title: string;
|
||||||
|
isOnHoldAtCurrentStep: boolean;
|
||||||
|
datas: {
|
||||||
|
persons: Person[];
|
||||||
|
};
|
||||||
|
steps: Step[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Warning {
|
||||||
|
id: number;
|
||||||
|
warningDate: DateTime;
|
||||||
|
endDate: DateTime;
|
||||||
|
title: string;
|
||||||
|
}
|
||||||
|
export interface Alert {
|
||||||
|
id: number;
|
||||||
|
warningDate: DateTime;
|
||||||
|
endDate: DateTime;
|
||||||
|
title: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Notification {
|
||||||
|
id: number;
|
||||||
|
date: DateTime;
|
||||||
|
title: string;
|
||||||
|
sender: {
|
||||||
|
text: string;
|
||||||
|
};
|
||||||
|
relatedEntityClass: string;
|
||||||
|
relatedEntityId: number;
|
||||||
|
}
|
||||||
|
export interface Participation {
|
||||||
|
person: Person;
|
||||||
|
}
|
||||||
|
export interface AccompanyingCourse {
|
||||||
|
id: number;
|
||||||
|
openingDate: DateTime;
|
||||||
|
socialIssues: SocialIssue[];
|
||||||
|
participations: Participation[];
|
||||||
|
emergency: boolean;
|
||||||
|
confidential: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
export interface AccompanyingPeriodWorkReferrerHistory {
|
export interface AccompanyingPeriodWorkReferrerHistory {
|
||||||
id: number;
|
id: number;
|
||||||
accompanyingPeriodWork: AccompanyingPeriodWork;
|
accompanyingPeriodWork: AccompanyingPeriodWork;
|
||||||
|
@@ -165,6 +165,7 @@ export interface TicketFilters {
|
|||||||
byCreatedBefore: string;
|
byCreatedBefore: string;
|
||||||
byResponseTimeExceeded: boolean;
|
byResponseTimeExceeded: boolean;
|
||||||
byAddresseeToMe: boolean;
|
byAddresseeToMe: boolean;
|
||||||
|
byTicketId: number | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TicketFilterParams {
|
export interface TicketFilterParams {
|
||||||
@@ -179,6 +180,7 @@ export interface TicketFilterParams {
|
|||||||
byCreatedBefore?: string;
|
byCreatedBefore?: string;
|
||||||
byResponseTimeExceeded?: string;
|
byResponseTimeExceeded?: string;
|
||||||
byAddresseeToMe?: boolean;
|
byAddresseeToMe?: boolean;
|
||||||
|
byTicketId?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TicketInitForm {
|
export interface TicketInitForm {
|
||||||
|
@@ -1,20 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="col-12">
|
<div class="col-12" v-if="!commentHistory.deleted">
|
||||||
<blockquote class="chill-user-quote">
|
<blockquote class="chill-user-quote">
|
||||||
<button
|
|
||||||
class="btn btn-sm btn-primary float-end"
|
|
||||||
title="Visible"
|
|
||||||
@click="visibleComment"
|
|
||||||
v-if="commentHistory.deleted"
|
|
||||||
>
|
|
||||||
<i class="bi bi-eye"></i>
|
|
||||||
</button>
|
|
||||||
<button
|
<button
|
||||||
class="btn btn-sm bg-chill-red float-end text-white"
|
class="btn btn-sm bg-chill-red float-end text-white"
|
||||||
@click="maskComment"
|
@click="deleteComment"
|
||||||
v-else
|
|
||||||
>
|
>
|
||||||
<i class="bi bi-eye-slash"></i>
|
<i class="bi bi-trash"></i>
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
class="btn btn-sm btn-edit mx-2 float-end text-white"
|
class="btn btn-sm btn-edit mx-2 float-end text-white"
|
||||||
@@ -24,14 +15,16 @@
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<p v-html="convertMarkdownToHtml(commentHistory.content)"></p>
|
<p v-html="convertMarkdownToHtml(commentHistory.content)"></p>
|
||||||
<span
|
|
||||||
v-if="commentHistory.deleted"
|
|
||||||
class="ms-2 d-block text-center fst-italic text-muted"
|
|
||||||
>
|
|
||||||
{{ trans(CHILL_TICKET_TICKET_MASK_COMMENT_HINT) }}
|
|
||||||
</span>
|
|
||||||
</blockquote>
|
</blockquote>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="col-12" v-else>
|
||||||
|
<span class="ms-2 d-block text-center">
|
||||||
|
{{ trans(CHILL_TICKET_TICKET_MASK_COMMENT_HINT) }}
|
||||||
|
<button class="btn btn-primary btn-sm ms-2" @click="restoreComment">
|
||||||
|
{{ trans(CANCEL) }}
|
||||||
|
</button>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
<Modal
|
<Modal
|
||||||
v-if="editCommentModal"
|
v-if="editCommentModal"
|
||||||
:show="editCommentModal"
|
:show="editCommentModal"
|
||||||
@@ -75,6 +68,7 @@ import {
|
|||||||
CHILL_TICKET_TICKET_MASK_COMMENT_SUCCESS,
|
CHILL_TICKET_TICKET_MASK_COMMENT_SUCCESS,
|
||||||
CHILL_TICKET_TICKET_MASK_COMMENT_HINT,
|
CHILL_TICKET_TICKET_MASK_COMMENT_HINT,
|
||||||
CHILL_TICKET_TICKET_VISIBLE_COMMENT_SUCCESS,
|
CHILL_TICKET_TICKET_VISIBLE_COMMENT_SUCCESS,
|
||||||
|
CANCEL,
|
||||||
} from "translator";
|
} from "translator";
|
||||||
import { useToast } from "vue-toast-notification";
|
import { useToast } from "vue-toast-notification";
|
||||||
|
|
||||||
@@ -97,18 +91,17 @@ const saveComment = () => {
|
|||||||
toast.success(trans(CHILL_TICKET_TICKET_EDIT_COMMENT_SUCCESS));
|
toast.success(trans(CHILL_TICKET_TICKET_EDIT_COMMENT_SUCCESS));
|
||||||
};
|
};
|
||||||
|
|
||||||
const maskComment = () => {
|
const deleteComment = () => {
|
||||||
store.dispatch("maskComment", props.commentHistory.id);
|
store.dispatch("deleteComment", props.commentHistory.id);
|
||||||
|
store.commit("addRemovedCommentIds", props.commentHistory.id);
|
||||||
editCommentModal.value = false;
|
editCommentModal.value = false;
|
||||||
toast.success(trans(CHILL_TICKET_TICKET_MASK_COMMENT_SUCCESS));
|
toast.success(trans(CHILL_TICKET_TICKET_MASK_COMMENT_SUCCESS));
|
||||||
};
|
};
|
||||||
|
const restoreComment = () => {
|
||||||
const visibleComment = () => {
|
store.dispatch("restoreComment", props.commentHistory.id);
|
||||||
store.dispatch("visibleComment", props.commentHistory.id);
|
|
||||||
editCommentModal.value = false;
|
editCommentModal.value = false;
|
||||||
toast.success(trans(CHILL_TICKET_TICKET_VISIBLE_COMMENT_SUCCESS));
|
toast.success(trans(CHILL_TICKET_TICKET_VISIBLE_COMMENT_SUCCESS));
|
||||||
};
|
};
|
||||||
|
|
||||||
const preprocess = (markdown: string): string => {
|
const preprocess = (markdown: string): string => {
|
||||||
return markdown;
|
return markdown;
|
||||||
};
|
};
|
||||||
|
@@ -0,0 +1,49 @@
|
|||||||
|
<template>
|
||||||
|
<div class="input-group mb-3">
|
||||||
|
<input
|
||||||
|
v-model="ticketId"
|
||||||
|
type="number"
|
||||||
|
class="form-control"
|
||||||
|
:placeholder="trans(CHILL_TICKET_LIST_FILTER_TICKET_ID)"
|
||||||
|
@input="
|
||||||
|
ticketId = isNaN(Number(($event.target as HTMLInputElement).value))
|
||||||
|
? null
|
||||||
|
: Number(($event.target as HTMLInputElement).value)
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
<span class="input-group-text" v-if="ticketId !== null">
|
||||||
|
<i
|
||||||
|
class="fa fa-times chill-red"
|
||||||
|
style="cursor: pointer"
|
||||||
|
@click="ticketId = null"
|
||||||
|
title="clear"
|
||||||
|
></i>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, watch } from "vue";
|
||||||
|
// Translation
|
||||||
|
import { trans, CHILL_TICKET_LIST_FILTER_TICKET_ID } from "translator";
|
||||||
|
const props = defineProps<{
|
||||||
|
modelValue: number | null;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const ticketId = ref<number | null>(props.modelValue);
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.modelValue,
|
||||||
|
(newVal) => {
|
||||||
|
if (newVal === null) {
|
||||||
|
ticketId.value = null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
const emit = defineEmits(["update:modelValue"]);
|
||||||
|
|
||||||
|
watch(ticketId, (ticketId) => {
|
||||||
|
emit("update:modelValue", ticketId ? ticketId : null);
|
||||||
|
});
|
||||||
|
</script>
|
@@ -8,23 +8,15 @@ import { ApiException } from "../../../../../../../../ChillMainBundle/Resources/
|
|||||||
|
|
||||||
export interface State {
|
export interface State {
|
||||||
comments: Comment[];
|
comments: Comment[];
|
||||||
|
removedCommentIds: Comment["id"][];
|
||||||
}
|
}
|
||||||
|
|
||||||
export const moduleComment: Module<State, RootState> = {
|
export const moduleComment: Module<State, RootState> = {
|
||||||
state: () => ({
|
state: () => ({
|
||||||
comments: [] as Comment[],
|
comments: [] as Comment[],
|
||||||
|
removedCommentIds: [] as Comment["id"][],
|
||||||
}),
|
}),
|
||||||
getters: {
|
getters: {
|
||||||
canBeDisplayed:
|
|
||||||
(state: State, getters: unknown, rootState: RootState) =>
|
|
||||||
(comment: Comment) => {
|
|
||||||
return (
|
|
||||||
(comment.deleted &&
|
|
||||||
comment.createdBy?.username ===
|
|
||||||
rootState.user.currentUser?.username) ||
|
|
||||||
!comment.deleted
|
|
||||||
);
|
|
||||||
},
|
|
||||||
canBeEdited:
|
canBeEdited:
|
||||||
(state: State, getters: unknown, rootState: RootState) =>
|
(state: State, getters: unknown, rootState: RootState) =>
|
||||||
(comment: Comment) => {
|
(comment: Comment) => {
|
||||||
@@ -32,8 +24,15 @@ export const moduleComment: Module<State, RootState> = {
|
|||||||
comment.createdBy?.username === rootState.user.currentUser?.username
|
comment.createdBy?.username === rootState.user.currentUser?.username
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
getRemovedCommentIds(state) {
|
||||||
|
return state.removedCommentIds;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mutations: {
|
||||||
|
addRemovedCommentIds(state, commentId: number) {
|
||||||
|
state.removedCommentIds.push(commentId);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
mutations: {},
|
|
||||||
actions: {
|
actions: {
|
||||||
async createComment({ commit, rootState }, content: Comment["content"]) {
|
async createComment({ commit, rootState }, content: Comment["content"]) {
|
||||||
try {
|
try {
|
||||||
@@ -64,7 +63,7 @@ export const moduleComment: Module<State, RootState> = {
|
|||||||
throw error.name;
|
throw error.name;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async maskComment({ commit }, id: Comment["id"]) {
|
async deleteComment({ commit }, id: Comment["id"]) {
|
||||||
try {
|
try {
|
||||||
const result: Comment = await makeFetch(
|
const result: Comment = await makeFetch(
|
||||||
"POST",
|
"POST",
|
||||||
@@ -77,7 +76,7 @@ export const moduleComment: Module<State, RootState> = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
async visibleComment({ commit }, id: Comment["id"]) {
|
async restoreComment({ commit }, id: Comment["id"]) {
|
||||||
try {
|
try {
|
||||||
const result: Comment = await makeFetch(
|
const result: Comment = await makeFetch(
|
||||||
"POST",
|
"POST",
|
||||||
|
@@ -73,7 +73,10 @@ export const moduleTicketList: Module<State, RootState> = {
|
|||||||
([, value]) =>
|
([, value]) =>
|
||||||
value !== undefined &&
|
value !== undefined &&
|
||||||
value !== null &&
|
value !== null &&
|
||||||
(value === true || (value !== "" && value.length > 0)),
|
(value === true ||
|
||||||
|
(typeof value === "number" && !isNaN(value)) ||
|
||||||
|
(typeof value === "string" && value !== "") ||
|
||||||
|
(Array.isArray(value) && value.length > 0)),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
params = new URLSearchParams(
|
params = new URLSearchParams(
|
||||||
|
@@ -101,7 +101,6 @@ onMounted(async () => {
|
|||||||
await store.dispatch("getCurrentUser");
|
await store.dispatch("getCurrentUser");
|
||||||
await store.dispatch("fetchTicketList", filters);
|
await store.dispatch("fetchTicketList", filters);
|
||||||
await store.dispatch("fetchMotives");
|
await store.dispatch("fetchMotives");
|
||||||
await store.dispatch("fetchUserGroups");
|
|
||||||
} finally {
|
} finally {
|
||||||
isLoading.value = false;
|
isLoading.value = false;
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,65 @@
|
|||||||
|
<template>
|
||||||
|
<label :for="dateId" class="form-label col-12">
|
||||||
|
{{ label }}
|
||||||
|
</label>
|
||||||
|
<div class="d-flex gap-2">
|
||||||
|
<div class="input-group">
|
||||||
|
<input
|
||||||
|
type="date"
|
||||||
|
:id="dateId"
|
||||||
|
v-model="modelDate"
|
||||||
|
class="form-control"
|
||||||
|
:disabled="disabled"
|
||||||
|
/>
|
||||||
|
<input
|
||||||
|
type="time"
|
||||||
|
v-model="modelTime"
|
||||||
|
class="form-control"
|
||||||
|
:disabled="disabled"
|
||||||
|
style="max-width: 120px"
|
||||||
|
placeholder="hh:mm"
|
||||||
|
/>
|
||||||
|
<span class="input-group-text" v-if="modelDate">
|
||||||
|
<i
|
||||||
|
class="fa fa-times chill-red"
|
||||||
|
style="cursor: pointer"
|
||||||
|
@click="clear"
|
||||||
|
title="clear"
|
||||||
|
></i>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { computed } from "vue";
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
label: string;
|
||||||
|
dateId: string;
|
||||||
|
modelValueDate: string;
|
||||||
|
modelValueTime: string;
|
||||||
|
defaultValueTime: string;
|
||||||
|
disabled?: boolean;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
(e: "update:modelValueDate", value: string): void;
|
||||||
|
(e: "update:modelValueTime", value: string): void;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const modelDate = computed({
|
||||||
|
get: () => props.modelValueDate,
|
||||||
|
set: (val: string) => emit("update:modelValueDate", val),
|
||||||
|
});
|
||||||
|
|
||||||
|
const modelTime = computed({
|
||||||
|
get: () => props.modelValueTime,
|
||||||
|
set: (val: string) => emit("update:modelValueTime", val),
|
||||||
|
});
|
||||||
|
|
||||||
|
function clear() {
|
||||||
|
emit("update:modelValueDate", "");
|
||||||
|
emit("update:modelValueTime", props.defaultValueTime);
|
||||||
|
}
|
||||||
|
</script>
|
@@ -43,12 +43,12 @@
|
|||||||
}}</label>
|
}}</label>
|
||||||
<addressee-selector-component
|
<addressee-selector-component
|
||||||
v-model="selectedAddressees"
|
v-model="selectedAddressees"
|
||||||
:suggested="userGroups"
|
:suggested="[]"
|
||||||
:label="trans(CHILL_TICKET_LIST_FILTER_BY_ADDRESSEES)"
|
:label="trans(CHILL_TICKET_LIST_FILTER_BY_ADDRESSEES)"
|
||||||
id="addresseeSelector"
|
id="addresseeSelector"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-6">
|
<div class="col-md-6 mb-3">
|
||||||
<!-- Filtre par motifs -->
|
<!-- Filtre par motifs -->
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<label class="form-label" for="motiveSelector">{{
|
<label class="form-label" for="motiveSelector">{{
|
||||||
@@ -60,7 +60,7 @@
|
|||||||
id="motiveSelector"
|
id="motiveSelector"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div class="mt-1" style="min-height: 2.2em">
|
<div class="mb-2" style="min-height: 2em">
|
||||||
<div class="d-flex flex-wrap gap-2">
|
<div class="d-flex flex-wrap gap-2">
|
||||||
<span
|
<span
|
||||||
v-for="motive in selectedMotives"
|
v-for="motive in selectedMotives"
|
||||||
@@ -79,43 +79,40 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- Filtre par état actuel -->
|
<!-- Filtre par état actuel -->
|
||||||
<div class="row">
|
<div class="d-flex gap-3">
|
||||||
<div class="col-6">
|
<div>
|
||||||
<div class="mb-2">
|
<label class="form-label pe-2" for="currentState">
|
||||||
<label class="form-label pe-2" for="currentState">
|
{{ trans(CHILL_TICKET_LIST_FILTER_CURRENT_STATE) }}
|
||||||
{{ trans(CHILL_TICKET_LIST_FILTER_CURRENT_STATE) }}
|
</label>
|
||||||
</label>
|
<toggle-component
|
||||||
<toggle-component
|
v-model="isClosedToggled"
|
||||||
v-model="isClosedToggled"
|
:on-label="trans(CHILL_TICKET_LIST_FILTER_CLOSED)"
|
||||||
:on-label="trans(CHILL_TICKET_LIST_FILTER_CLOSED)"
|
:off-label="trans(CHILL_TICKET_LIST_FILTER_OPEN)"
|
||||||
:off-label="trans(CHILL_TICKET_LIST_FILTER_OPEN)"
|
:classColor="{
|
||||||
:classColor="{
|
on: 'bg-chill-red',
|
||||||
on: 'bg-chill-red',
|
off: 'bg-chill-green',
|
||||||
off: 'bg-chill-green',
|
}"
|
||||||
}"
|
@update:model-value="handleStateToggle"
|
||||||
@update:model-value="handleStateToggle"
|
id="currentState"
|
||||||
id="currentState"
|
/>
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Filtre par état d'urgence -->
|
<!-- Filtre par état d'urgence -->
|
||||||
<div class="col-6">
|
<div>
|
||||||
<div class="mb-2">
|
<label class="form-label pe-2" for="emergency">
|
||||||
<label class="form-label pe-2" for="emergency">
|
{{ trans(CHILL_TICKET_LIST_FILTER_EMERGENCY) }}
|
||||||
{{ trans(CHILL_TICKET_LIST_FILTER_EMERGENCY) }}
|
</label>
|
||||||
</label>
|
<toggle-component
|
||||||
<toggle-component
|
v-model="isEmergencyToggled"
|
||||||
v-model="isEmergencyToggled"
|
:on-label="trans(CHILL_TICKET_LIST_FILTER_EMERGENCY)"
|
||||||
:on-label="trans(CHILL_TICKET_LIST_FILTER_EMERGENCY)"
|
:off-label="trans(CHILL_TICKET_LIST_FILTER_EMERGENCY)"
|
||||||
:off-label="trans(CHILL_TICKET_LIST_FILTER_EMERGENCY)"
|
:classColor="{
|
||||||
:classColor="{
|
on: 'bg-warning',
|
||||||
on: 'bg-warning',
|
off: 'bg-secondary',
|
||||||
off: 'bg-secondary',
|
}"
|
||||||
}"
|
@update:model-value="handleEmergencyToggle"
|
||||||
@update:model-value="handleEmergencyToggle"
|
id="emergency"
|
||||||
id="emergency"
|
/>
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -124,6 +121,18 @@
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
<!-- Filtre pour temps de réponse dépassé -->
|
<!-- Filtre pour temps de réponse dépassé -->
|
||||||
<div class="col-md-6 mb-3">
|
<div class="col-md-6 mb-3">
|
||||||
|
<div class="form-check">
|
||||||
|
<input
|
||||||
|
v-model="filters.byAddresseeToMe"
|
||||||
|
class="form-check-input"
|
||||||
|
type="checkbox"
|
||||||
|
id="stateMe"
|
||||||
|
/>
|
||||||
|
<label class="form-check-label" for="stateMe">
|
||||||
|
{{ trans(CHILL_TICKET_LIST_FILTER_TO_ME) }}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="form-check">
|
<div class="form-check">
|
||||||
<input
|
<input
|
||||||
class="form-check-input"
|
class="form-check-input"
|
||||||
@@ -141,48 +150,40 @@
|
|||||||
{{ trans(CHILL_TICKET_LIST_FILTER_RESPONSE_TIME_WARNING) }}
|
{{ trans(CHILL_TICKET_LIST_FILTER_RESPONSE_TIME_WARNING) }}
|
||||||
</small>
|
</small>
|
||||||
</div>
|
</div>
|
||||||
<!-- Filtre par mes tickets -->
|
<!-- Filtre par numéro de ticket -->
|
||||||
<div class="col-md-6 mb-3">
|
<div class="col-md-6 mb-3">
|
||||||
<div class="d-flex gap-3">
|
<label class="form-label pe-2" for="ticketSelector">
|
||||||
<div class="form-check">
|
{{ trans(CHILL_TICKET_LIST_FILTER_BY_TICKET_ID) }}
|
||||||
<input
|
</label>
|
||||||
v-model="filters.byAddresseeToMe"
|
<ticket-selector v-model="filters.byTicketId" id="ticketSelector" />
|
||||||
class="form-check-input"
|
|
||||||
type="checkbox"
|
|
||||||
id="stateMe"
|
|
||||||
/>
|
|
||||||
<label class="form-check-label" for="stateMe">
|
|
||||||
{{ trans(CHILL_TICKET_LIST_FILTER_TO_ME) }}
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Filtre par date de création -->
|
<!-- Filtre par date de création -->
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-6 mb-3">
|
<div class="col-md-6 mb-3">
|
||||||
<label for="byCreatedAfter" class="form-label">{{
|
<date-and-time-selector-component
|
||||||
trans(CHILL_TICKET_LIST_FILTER_CREATED_AFTER)
|
:label="trans(CHILL_TICKET_LIST_FILTER_CREATED_AFTER)"
|
||||||
}}</label>
|
date-id="byCreatedAfter"
|
||||||
<input
|
default-value-time="00:00"
|
||||||
type="datetime-local"
|
:model-value-date="filters.byCreatedAfter"
|
||||||
id="byCreatedAfter"
|
:model-value-time="byCreatedAfterTime"
|
||||||
v-model="filters.byCreatedAfter"
|
|
||||||
class="form-control"
|
|
||||||
:disabled="filters.byResponseTimeExceeded"
|
:disabled="filters.byResponseTimeExceeded"
|
||||||
|
@update:modelValueDate="filters.byCreatedAfter = $event"
|
||||||
|
@update:modelValueTime="byCreatedAfterTime = $event"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-md-6 mb-3">
|
<div class="col-md-6 mb-3">
|
||||||
<label for="byCreatedBefore" class="form-label">{{
|
<date-and-time-selector-component
|
||||||
trans(CHILL_TICKET_LIST_FILTER_CREATED_BEFORE)
|
:label="trans(CHILL_TICKET_LIST_FILTER_CREATED_BEFORE)"
|
||||||
}}</label>
|
date-id="byCreatedBefore"
|
||||||
<input
|
default-value-time="23:59"
|
||||||
type="datetime-local"
|
:model-value-date="filters.byCreatedBefore"
|
||||||
id="byCreatedBefore"
|
:model-value-time="byCreatedBeforeTime"
|
||||||
v-model="filters.byCreatedBefore"
|
|
||||||
class="form-control"
|
|
||||||
:disabled="filters.byResponseTimeExceeded"
|
:disabled="filters.byResponseTimeExceeded"
|
||||||
|
@update:modelValueDate="filters.byCreatedBefore = $event"
|
||||||
|
@update:modelValueTime="byCreatedBeforeTime = $event"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -218,10 +219,13 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, computed, watch } from "vue";
|
import { ref, computed, watch } from "vue";
|
||||||
import { useStore } from "vuex";
|
|
||||||
import type { Person } from "ChillPersonAssets/types";
|
import type { Person } from "ChillPersonAssets/types";
|
||||||
import type { Motive, TicketFilterParams, TicketFilters } from "../../../types";
|
import {
|
||||||
import { User, UserGroup, UserGroupOrUser } from "ChillMainAssets/types";
|
type Motive,
|
||||||
|
type TicketFilterParams,
|
||||||
|
type TicketFilters,
|
||||||
|
} from "../../../types";
|
||||||
|
import { User, UserGroupOrUser } from "ChillMainAssets/types";
|
||||||
|
|
||||||
// Translation
|
// Translation
|
||||||
import {
|
import {
|
||||||
@@ -234,6 +238,7 @@ import {
|
|||||||
CHILL_TICKET_LIST_FILTER_ADDRESSEES,
|
CHILL_TICKET_LIST_FILTER_ADDRESSEES,
|
||||||
CHILL_TICKET_LIST_FILTER_BY_ADDRESSEES,
|
CHILL_TICKET_LIST_FILTER_BY_ADDRESSEES,
|
||||||
CHILL_TICKET_LIST_FILTER_BY_MOTIVES,
|
CHILL_TICKET_LIST_FILTER_BY_MOTIVES,
|
||||||
|
CHILL_TICKET_LIST_FILTER_BY_TICKET_ID,
|
||||||
CHILL_TICKET_LIST_FILTER_REMOVE,
|
CHILL_TICKET_LIST_FILTER_REMOVE,
|
||||||
CHILL_TICKET_LIST_FILTER_OPEN,
|
CHILL_TICKET_LIST_FILTER_OPEN,
|
||||||
CHILL_TICKET_LIST_FILTER_CLOSED,
|
CHILL_TICKET_LIST_FILTER_CLOSED,
|
||||||
@@ -254,6 +259,8 @@ import PersonsSelector from "../../TicketApp/components/Person/PersonsSelectorCo
|
|||||||
import MotiveSelector from "../../TicketApp/components/Motive/MotiveSelectorComponent.vue";
|
import MotiveSelector from "../../TicketApp/components/Motive/MotiveSelectorComponent.vue";
|
||||||
import AddresseeSelectorComponent from "../../TicketApp/components/Addressee/AddresseeSelectorComponent.vue";
|
import AddresseeSelectorComponent from "../../TicketApp/components/Addressee/AddresseeSelectorComponent.vue";
|
||||||
import ToggleComponent from "./ToggleComponent.vue";
|
import ToggleComponent from "./ToggleComponent.vue";
|
||||||
|
import TicketSelector from "../../TicketApp/components/Ticket/TicketSelector.vue";
|
||||||
|
import DateAndTimeSelectorComponent from "./DateAndTimeSelectorComponent.vue";
|
||||||
|
|
||||||
// Props
|
// Props
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
@@ -267,8 +274,6 @@ const emit = defineEmits<{
|
|||||||
"filters-changed": [filters: TicketFilterParams];
|
"filters-changed": [filters: TicketFilterParams];
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const store = useStore();
|
|
||||||
|
|
||||||
// État réactif
|
// État réactif
|
||||||
const filters = ref<TicketFilters>({
|
const filters = ref<TicketFilters>({
|
||||||
byCurrentState: ["open"],
|
byCurrentState: ["open"],
|
||||||
@@ -277,15 +282,18 @@ const filters = ref<TicketFilters>({
|
|||||||
byCreatedBefore: "",
|
byCreatedBefore: "",
|
||||||
byResponseTimeExceeded: false,
|
byResponseTimeExceeded: false,
|
||||||
byAddresseeToMe: false,
|
byAddresseeToMe: false,
|
||||||
|
byTicketId: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const byCreatedAfterTime = ref("00:00");
|
||||||
|
const byCreatedBeforeTime = ref("23:59");
|
||||||
|
|
||||||
// Sélection des personnes
|
// Sélection des personnes
|
||||||
const selectedPersons = ref<Person[]>([]);
|
const selectedPersons = ref<Person[]>([]);
|
||||||
const availablePersons = ref<Person[]>(props.availablePersons || []);
|
const availablePersons = ref<Person[]>(props.availablePersons || []);
|
||||||
|
|
||||||
// Sélection des utilisateur assigné
|
// Sélection des utilisateur assigné
|
||||||
const selectedAddressees = ref<UserGroupOrUser[]>([]);
|
const selectedAddressees = ref<UserGroupOrUser[]>([]);
|
||||||
const userGroups = computed(() => store.getters.getUserGroups as UserGroup[]);
|
|
||||||
|
|
||||||
// Séléction des créateurs
|
// Séléction des créateurs
|
||||||
const selectedCreator = ref<User[]>([]);
|
const selectedCreator = ref<User[]>([]);
|
||||||
@@ -351,10 +359,10 @@ const handleEmergencyToggle = (value: boolean) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Méthodes
|
const formatDateToISO = (dateString: string, timeString: string): string => {
|
||||||
const formatDateToISO = (dateString: string): string => {
|
const [hours, minutes] = timeString.split(":").map(Number);
|
||||||
if (!dateString) return dateString;
|
|
||||||
const date = new Date(dateString);
|
const date = new Date(dateString);
|
||||||
|
date.setHours(hours, minutes, 0, 0);
|
||||||
return date.toISOString();
|
return date.toISOString();
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -406,11 +414,17 @@ const applyFilters = (): void => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (filters.value.byCreatedAfter) {
|
if (filters.value.byCreatedAfter) {
|
||||||
apiFilters.byCreatedAfter = formatDateToISO(filters.value.byCreatedAfter);
|
apiFilters.byCreatedAfter = formatDateToISO(
|
||||||
|
filters.value.byCreatedAfter,
|
||||||
|
byCreatedAfterTime.value,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (filters.value.byCreatedBefore) {
|
if (filters.value.byCreatedBefore) {
|
||||||
apiFilters.byCreatedBefore = formatDateToISO(filters.value.byCreatedBefore);
|
apiFilters.byCreatedBefore = formatDateToISO(
|
||||||
|
filters.value.byCreatedBefore,
|
||||||
|
byCreatedBeforeTime.value,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (filters.value.byResponseTimeExceeded) {
|
if (filters.value.byResponseTimeExceeded) {
|
||||||
@@ -419,7 +433,12 @@ const applyFilters = (): void => {
|
|||||||
if (filters.value.byAddresseeToMe) {
|
if (filters.value.byAddresseeToMe) {
|
||||||
apiFilters.byAddresseeToMe = true;
|
apiFilters.byAddresseeToMe = true;
|
||||||
}
|
}
|
||||||
|
if (filters.value.byAddresseeToMe) {
|
||||||
|
apiFilters.byAddresseeToMe = true;
|
||||||
|
}
|
||||||
|
if (filters.value.byTicketId) {
|
||||||
|
apiFilters.byTicketId = filters.value.byTicketId;
|
||||||
|
}
|
||||||
emit("filters-changed", apiFilters);
|
emit("filters-changed", apiFilters);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -431,13 +450,14 @@ const resetFilters = (): void => {
|
|||||||
byCreatedBefore: "",
|
byCreatedBefore: "",
|
||||||
byResponseTimeExceeded: false,
|
byResponseTimeExceeded: false,
|
||||||
byAddresseeToMe: false,
|
byAddresseeToMe: false,
|
||||||
|
byTicketId: null,
|
||||||
};
|
};
|
||||||
selectedPersons.value = [];
|
selectedPersons.value = [];
|
||||||
selectedCreator.value = [];
|
selectedCreator.value = [];
|
||||||
selectedAddressees.value = [];
|
selectedAddressees.value = [];
|
||||||
selectedMotives.value = [];
|
selectedMotives.value = [];
|
||||||
selectedMotive.value = undefined;
|
selectedMotive.value = undefined;
|
||||||
isClosedToggled.value = true;
|
isClosedToggled.value = false;
|
||||||
isEmergencyToggled.value = false;
|
isEmergencyToggled.value = false;
|
||||||
applyFilters();
|
applyFilters();
|
||||||
};
|
};
|
||||||
@@ -446,7 +466,7 @@ const handleResponseTimeExceededChange = (): void => {
|
|||||||
if (filters.value.byResponseTimeExceeded) {
|
if (filters.value.byResponseTimeExceeded) {
|
||||||
filters.value.byCreatedBefore = "";
|
filters.value.byCreatedBefore = "";
|
||||||
filters.value.byCreatedAfter = "";
|
filters.value.byCreatedAfter = "";
|
||||||
isClosedToggled.value = true;
|
isClosedToggled.value = false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
@@ -11,16 +11,6 @@
|
|||||||
<div class="d-flex align-items-center fw-bold">
|
<div class="d-flex align-items-center fw-bold">
|
||||||
<i :class="`${actionIcons[history_line.event_type]} me-1`"></i>
|
<i :class="`${actionIcons[history_line.event_type]} me-1`"></i>
|
||||||
<span>{{ explainSentence(history_line) }}</span>
|
<span>{{ explainSentence(history_line) }}</span>
|
||||||
<span
|
|
||||||
v-if="
|
|
||||||
history_line.event_type === 'add_comment' &&
|
|
||||||
history_line.data.deleted
|
|
||||||
"
|
|
||||||
class="badge bg-danger ms-2"
|
|
||||||
>
|
|
||||||
{{ trans(CHILL_TICKET_TICKET_HISTORY_MASK_COMMENT) }}
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<state-component
|
<state-component
|
||||||
:new_state="history_line.data.new_state"
|
:new_state="history_line.data.new_state"
|
||||||
v-if="history_line.event_type == 'state_change'"
|
v-if="history_line.event_type == 'state_change'"
|
||||||
@@ -59,10 +49,7 @@
|
|||||||
/>
|
/>
|
||||||
<comment-component
|
<comment-component
|
||||||
:commentHistory="history_line.data"
|
:commentHistory="history_line.data"
|
||||||
v-else-if="
|
v-else-if="history_line.event_type == 'add_comment'"
|
||||||
history_line.event_type == 'add_comment' &&
|
|
||||||
canBeDisplayed(history_line.data)
|
|
||||||
"
|
|
||||||
/>
|
/>
|
||||||
<addressee-component
|
<addressee-component
|
||||||
:addressees="history_line.data.addressees"
|
:addressees="history_line.data.addressees"
|
||||||
@@ -105,19 +92,24 @@ import {
|
|||||||
CHILL_TICKET_TICKET_HISTORY_STATE_CHANGE,
|
CHILL_TICKET_TICKET_HISTORY_STATE_CHANGE,
|
||||||
CHILL_TICKET_TICKET_HISTORY_EMERGENCY_CHANGE,
|
CHILL_TICKET_TICKET_HISTORY_EMERGENCY_CHANGE,
|
||||||
CHILL_TICKET_TICKET_HISTORY_SET_CALLER,
|
CHILL_TICKET_TICKET_HISTORY_SET_CALLER,
|
||||||
CHILL_TICKET_TICKET_HISTORY_MASK_COMMENT,
|
|
||||||
} from "translator";
|
} from "translator";
|
||||||
|
|
||||||
const props = defineProps<{ history?: TicketHistoryLine[] }>();
|
const props = defineProps<{ history?: TicketHistoryLine[] }>();
|
||||||
const history = props.history ?? [];
|
const history = props.history ?? [];
|
||||||
const store = useStore();
|
const store = useStore();
|
||||||
|
|
||||||
const actionIcons = ref(store.getters.getActionIcons);
|
const actionIcons = ref<Record<string, string>>(store.getters.getActionIcons);
|
||||||
const canBeDisplayed = ref(store.getters.canBeDisplayed);
|
const removedCommentIds = ref<number[]>(store.getters.getRemovedCommentIds);
|
||||||
|
|
||||||
const filteredHistoryLines = computed(() =>
|
const filteredHistoryLines = computed(() =>
|
||||||
history.filter(
|
history.filter(
|
||||||
(line: TicketHistoryLine) => !(line.event_type === "add_person"),
|
(line: TicketHistoryLine) =>
|
||||||
|
line.event_type !== "add_person" &&
|
||||||
|
!(
|
||||||
|
line.event_type == "add_comment" &&
|
||||||
|
line.data.deleted &&
|
||||||
|
!removedCommentIds.value.includes(line.data.id)
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@@ -24,6 +24,8 @@ chill_ticket:
|
|||||||
addressees: "Par destinataire"
|
addressees: "Par destinataire"
|
||||||
by_addressees: "Par destinataire"
|
by_addressees: "Par destinataire"
|
||||||
by_motives: "Par motifs"
|
by_motives: "Par motifs"
|
||||||
|
by_ticket_id: "Par numéro de ticket"
|
||||||
|
ticket_id: "Numéro de ticket"
|
||||||
current_state: "État actuel"
|
current_state: "État actuel"
|
||||||
open: "Ouvert"
|
open: "Ouvert"
|
||||||
closed: "Clôturé"
|
closed: "Clôturé"
|
||||||
@@ -55,7 +57,7 @@ chill_ticket:
|
|||||||
create_ticket: "Ticket créé"
|
create_ticket: "Ticket créé"
|
||||||
state_change: ""
|
state_change: ""
|
||||||
emergency_change: ""
|
emergency_change: ""
|
||||||
mask_comment: "Masqué"
|
mask_comment: "Supprimer"
|
||||||
previous_tickets: "Précédents tickets"
|
previous_tickets: "Précédents tickets"
|
||||||
actions_toolbar:
|
actions_toolbar:
|
||||||
cancel: "Annuler"
|
cancel: "Annuler"
|
||||||
@@ -67,10 +69,10 @@ chill_ticket:
|
|||||||
reopen_success: "Rouverture du ticket réussie"
|
reopen_success: "Rouverture du ticket réussie"
|
||||||
reopen_error: "Erreur lors de la rouverture du ticket"
|
reopen_error: "Erreur lors de la rouverture du ticket"
|
||||||
visible_comment:
|
visible_comment:
|
||||||
success: "Commentaire visible"
|
success: "Commentaire restauré"
|
||||||
mask_comment:
|
mask_comment:
|
||||||
success: "Commentaire masqué"
|
success: "Commentaire supprimé"
|
||||||
hint: "Ce commentaire est masqué; il n'est visible que par vous."
|
hint: "Ce commentaire a été supprimé."
|
||||||
edit_comment:
|
edit_comment:
|
||||||
title: "Éditer le commentaire"
|
title: "Éditer le commentaire"
|
||||||
success: "Commentaire modifié"
|
success: "Commentaire modifié"
|
||||||
|
Reference in New Issue
Block a user