Files
chill-bundles/src/Bundle/ChillMainBundle/Resources/public/vuejs/HomepageWidget/App.vue
2025-09-30 13:49:04 +00:00

157 lines
4.1 KiB
Vue

<template>
<h2>{{ trans(MAIN_TITLE) }}</h2>
<ul class="nav nav-tabs">
<li v-for="tab in displayedTabs" :key="tab.key" class="nav-item">
<a
class="nav-link"
:class="{ active: activeTab === tab.key }"
@click="selectTab(tab.key)"
>
<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">
<i
class="fa fa-circle-o-notch fa-spin fa-lg text-chill-gray"
:title="trans(LOADING)"
/>
</li>
</ul>
<div class="my-4">
<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"
/>
<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 MyEvaluations from "./MyEvaluations.vue";
import MyTasks from "./MyTasks.vue";
import MyAccompanyingCourses from "./MyAccompanyingCourses.vue";
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,
MY_EVALUATIONS_TAB,
MY_TASKS_TAB,
MY_ACCOMPANYING_COURSES_TAB,
MY_NOTIFICATIONS_TAB,
MY_WORKFLOWS_TAB,
LOADING,
trans,
} from "translator";
// Types
import {
HomepageConfig,
HomepageTabs,
TabDefinition,
} from "ChillMainAssets/types";
const store = useStore();
defineExpose({ HomepageTabs });
const homepageConfig = ref<HomepageConfig>(JSON.parse(window.homepage_config));
const state = computed(() => store.state.homepage);
const ticketListState = computed(() => store.state.ticketList);
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(() => {
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);
async function selectTab(tab: HomepageTabs) {
activeTab.value = tab;
}
onMounted(() => {
for (const tab of displayedTabs.value) {
if (tab.key !== HomepageTabs.MyCustoms) {
store.dispatch("getByTab", { tab: tab.key, param: "countOnly=1" });
}
}
});
</script>
<style scoped>
a.nav-link {
cursor: pointer;
}
</style>