Correction de bugs, ajout champs urgents dans la modal d'initialisation du ticket et ajout d'un configuration pour l'affichage des tabs dans la homepage

This commit is contained in:
Boris Waaub
2025-09-22 09:23:30 +00:00
committed by Julien Fastré
parent ec9d0be70b
commit e1ef65d4ca
19 changed files with 242 additions and 141 deletions

View File

@@ -1,83 +1,15 @@
<template>
<h2>{{ trans(MAIN_TITLE) }}</h2>
<ul class="nav nav-tabs">
<li class="nav-item">
<li v-for="tab in displayedTabs" :key="tab.key" class="nav-item">
<a
class="nav-link"
:class="{ active: activeTab === 'MyCustoms' }"
@click="selectTab('MyCustoms')"
:class="{ active: activeTab === tab.key }"
@click="selectTab(tab.key)"
>
<i class="fa fa-dashboard" />
</a>
</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">
<a
class="nav-link"
:class="{ active: activeTab === 'MyNotifications' }"
@click="selectTab('MyNotifications')"
>
{{ trans(MY_NOTIFICATIONS_TAB) }}
<tab-counter :count="state.value?.notifications?.count || 0" />
</a>
</li>
<li class="nav-item">
<a
class="nav-link"
:class="{ active: activeTab === 'MyAccompanyingCourses' }"
@click="selectTab('MyAccompanyingCourses')"
>
{{ trans(MY_ACCOMPANYING_COURSES_TAB) }}
</a>
</li>
<li class="nav-item">
<a
class="nav-link"
:class="{ active: activeTab === 'MyEvaluations' }"
@click="selectTab('MyEvaluations')"
>
{{ trans(MY_EVALUATIONS_TAB) }}
<tab-counter :count="state.value?.evaluations?.count || 0" />
</a>
</li>
<li class="nav-item">
<a
class="nav-link"
:class="{ active: activeTab === 'MyTasks' }"
@click="selectTab('MyTasks')"
>
{{ trans(MY_TASKS_TAB) }}
<tab-counter
:count="
(state.value?.tasks?.warning?.count || 0) +
(state.value?.tasks?.alert?.count || 0)
"
/>
</a>
</li>
<li class="nav-item">
<a
class="nav-link"
:class="{ active: activeTab === 'MyWorkflows' }"
@click="selectTab('MyWorkflows')"
>
{{ trans(MY_WORKFLOWS_TAB) }}
<tab-counter
:count="
(state.value?.workflows?.count || 0) +
(state.value?.workflowsCc?.count || 0)
"
/>
<i v-if="tab.icon" :class="tab.icon" />
<span v-else>{{ tab.label }}</span>
<tab-counter v-if="tab.counter" :count="tab.counter()" />
</a>
</li>
<li class="nav-item loading ms-auto py-2" v-if="loading">
@@ -87,26 +19,25 @@
/>
</li>
</ul>
<div class="my-4">
<my-tickets v-if="activeTab == 'MyTickets'" />
<my-customs v-if="activeTab === 'MyCustoms'" />
<my-works v-else-if="activeTab === 'MyWorks'" />
<my-evaluations v-else-if="activeTab === 'MyEvaluations'" />
<my-tasks v-else-if="activeTab === 'MyTasks'" />
<my-accompanying-courses
v-else-if="activeTab === 'MyAccompanyingCourses'"
<MyCustoms v-if="activeTab === HomepageTabs.MyCustoms" />
<MyTickets v-else-if="activeTab === HomepageTabs.MyTickets" />
<MyNotifications v-else-if="activeTab === HomepageTabs.MyNotifications" />
<MyAccompanyingCourses
v-else-if="activeTab === HomepageTabs.MyAccompanyingCourses"
/>
<my-notifications v-else-if="activeTab === 'MyNotifications'" />
<my-workflows v-else-if="activeTab === 'MyWorkflows'" />
<MyEvaluations v-else-if="activeTab === HomepageTabs.MyEvaluations" />
<MyTasks v-else-if="activeTab === HomepageTabs.MyTasks" />
<MyWorkflows v-else-if="activeTab === HomepageTabs.MyWorkflows" />
</div>
</template>
<script lang="ts" setup>
import { ref, computed, onMounted } from "vue";
import { useStore } from "vuex";
// Components
import MyCustoms from "./MyCustoms.vue";
import MyWorks from "./MyWorks.vue";
import MyEvaluations from "./MyEvaluations.vue";
import MyTasks from "./MyTasks.vue";
import MyAccompanyingCourses from "./MyAccompanyingCourses.vue";
@@ -114,6 +45,8 @@ import MyNotifications from "./MyNotifications.vue";
import MyWorkflows from "./MyWorkflows.vue";
import MyTickets from "./MyTickets.vue";
import TabCounter from "./TabCounter.vue";
// Translations
import {
MAIN_TITLE,
MY_TICKETS_TAB,
@@ -125,33 +58,97 @@ import {
LOADING,
trans,
} from "translator";
// Types
import {
HomepageConfig,
HomepageTabs,
TabDefinition,
} from "ChillMainAssets/types";
const store = useStore();
const activeTab = ref("MyCustoms");
const loading = computed(() => store.state.loading);
defineExpose({ HomepageTabs });
const homepageConfig = ref<HomepageConfig>(JSON.parse(window.homepage_config));
const state = computed(() => store.state.homepage);
const ticketListState = computed(() => store.state.ticketList);
function selectTab(tab: string) {
if (tab !== "MyCustoms") {
const tabDefinitions: TabDefinition[] = [
{
key: HomepageTabs.MyCustoms,
label: "",
icon: "fa fa-dashboard",
counter: () => 0,
},
{
key: HomepageTabs.MyTickets,
label: trans(MY_TICKETS_TAB),
icon: null,
counter: () => ticketListState.value?.count,
},
{
key: HomepageTabs.MyNotifications,
label: trans(MY_NOTIFICATIONS_TAB),
icon: null,
counter: () => state.value?.notifications?.count,
},
{
key: HomepageTabs.MyAccompanyingCourses,
label: trans(MY_ACCOMPANYING_COURSES_TAB),
icon: null,
counter: () => state.value?.accompanyingCourses?.count,
},
{
key: HomepageTabs.MyEvaluations,
label: trans(MY_EVALUATIONS_TAB),
icon: null,
counter: () => state.value?.evaluations?.count,
},
{
key: HomepageTabs.MyTasks,
label: trans(MY_TASKS_TAB),
icon: null,
counter: () =>
state.value?.tasks?.warning?.count + state.value?.tasks?.alert?.count,
},
{
key: HomepageTabs.MyWorkflows,
label: trans(MY_WORKFLOWS_TAB),
icon: null,
counter: () =>
state.value?.workflows?.count + state.value?.workflowsCc?.count,
},
];
const displayedTabs = computed(() => {
// Always show MyCustoms first if present
const tabs = [] as TabDefinition[];
for (const tabEnum of homepageConfig.value.displayTabs) {
const def = tabDefinitions.find(
(t) => t.key === Number(HomepageTabs[tabEnum]),
);
if (def) tabs.push(def);
}
return tabs.filter(Boolean);
});
const activeTab = ref(Number(HomepageTabs[homepageConfig.value.defaultTab]));
const loading = computed(() => store.state.loading);
function selectTab(tab: HomepageTabs) {
if (tab !== HomepageTabs.MyCustoms) {
store.dispatch("getByTab", { tab: tab });
}
activeTab.value = tab;
}
onMounted(() => {
for (const m of [
"MyTickets",
"MyNotifications",
"MyAccompanyingCourses",
// 'MyWorks',
"MyEvaluations",
"MyTasks",
"MyWorkflows",
]) {
store.dispatch("getByTab", { tab: m, param: "countOnly=1" });
for (const tab of displayedTabs.value) {
if (tab.key !== HomepageTabs.MyCustoms) {
store.dispatch("getByTab", { tab: tab.key, param: "countOnly=1" });
}
}
});
</script>

View File

@@ -1,5 +1,5 @@
<template>
<span v-if="isCounterAvailable" class="badge rounded-pill bg-danger">
<span v-if="isCounterAvailable" class="badge rounded-pill bg-danger mx-2">
{{ count }}
</span>
</template>

View File

@@ -13,6 +13,7 @@ import {
WorflowCc,
} from "ChillPersonAssets/types";
import { RootState } from "..";
import { HomepageTabs } from "ChillMainAssets/types";
export interface TasksState {
warning: PaginationResponse<Warning>;
@@ -82,17 +83,6 @@ export const moduleHomepage: Module<State, RootState> = {
isWorkflowsLoaded(state) {
return Array.isArray(state.workflows.results);
},
counter(state, getters, rootState, rootGetters) {
return {
tickets: rootGetters["ticketList/getCount"] || 0,
evaluations: state.evaluations.count || 0,
tasksWarning: state.tasks.warning.count || 0,
tasksAlert: state.tasks.alert.count || 0,
accompanyingCourses: state.accompanyingCourses.count || 0,
notifications: state.notifications.count || 0,
workflows: state.workflows.count || 0,
};
},
},
mutations: {
addEvaluations(state, evaluations) {
@@ -129,20 +119,20 @@ export const moduleHomepage: Module<State, RootState> = {
actions: {
async getByTab({ commit, getters, dispatch }, { tab, param }) {
switch (tab) {
case "MyTickets":
case HomepageTabs.MyTickets:
if (!getters.isTicketsLoaded) {
commit("setTicketsLoading", true);
// Utilise l'action du module ticket_list
await dispatch(
"fetchTicketList",
{ byAddresseeToMe: true },
{ byAddresseeToMe: true, byCurrentState: "open" },
{ root: true },
);
commit("setTicketsLoading", false);
}
break;
case "MyEvaluations":
case HomepageTabs.MyEvaluations:
if (!getters.isEvaluationsLoaded) {
commit("setLoading", true);
const url = `/api/1.0/person/accompanying-period/work/evaluation/my-near-end${"?" + param}`;
@@ -157,7 +147,7 @@ export const moduleHomepage: Module<State, RootState> = {
});
}
break;
case "MyTasks":
case HomepageTabs.MyTasks:
if (!(getters.isTasksWarningLoaded && getters.isTasksAlertLoaded)) {
commit("setLoading", true);
const urlWarning = `/api/1.0/task/single-task/list/my?f[q]=&f[checkboxes][status][]=warning&f[checkboxes][states][]=new&f[checkboxes][states][]=in_progress${"&" + param}`,
@@ -182,7 +172,7 @@ export const moduleHomepage: Module<State, RootState> = {
});
}
break;
case "MyAccompanyingCourses":
case HomepageTabs.MyAccompanyingCourses:
if (!getters.isAccompanyingCoursesLoaded) {
commit("setLoading", true);
const url = `/api/1.0/person/accompanying-course/list/by-recent-attributions${"?" + param}`;
@@ -197,7 +187,7 @@ export const moduleHomepage: Module<State, RootState> = {
});
}
break;
case "MyNotifications":
case HomepageTabs.MyNotifications:
if (!getters.isNotificationsLoaded) {
commit("setLoading", true);
const url = `/api/1.0/main/notification/my/unread${"?" + param}`;
@@ -212,7 +202,7 @@ export const moduleHomepage: Module<State, RootState> = {
});
}
break;
case "MyWorkflows":
case HomepageTabs.MyWorkflows:
if (!getters.isWorflowsLoaded) {
commit("setLoading", true);
makeFetch("GET", "/api/1.0/main/workflow/my")