f4ffc02028
LST-59 (3.1) front. Completes the Reporting module. - New frontend/modules/reporting/ layer (auto-detected): /reporting page (admin middleware) consuming the 4 read-only report endpoints. - Filters (period presets + custom dates, project, user). 4 sections (time per project, time per user, tasks by status, absences by type) each with a DataTable + a Chart.js chart (reused global registration). - Front-side CSV export per section (useCsvExport: BOM UTF-8, ; separator). - i18n keys (reporting.*, sidebar.admin.reporting). nuxt build passes; /reporting routed; no route regression.
53 lines
1.1 KiB
Vue
53 lines
1.1 KiB
Vue
<template>
|
|
<div class="h-64">
|
|
<Bar
|
|
v-if="hasData"
|
|
:data="chartData"
|
|
:options="options"
|
|
/>
|
|
<p v-else class="flex h-full items-center justify-center text-sm text-neutral-400">
|
|
{{ emptyMessage ?? $t('reporting.empty') }}
|
|
</p>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { Bar } from 'vue-chartjs'
|
|
|
|
const props = defineProps<{
|
|
labels: string[]
|
|
values: number[]
|
|
color?: string
|
|
emptyMessage?: string
|
|
}>()
|
|
|
|
const hasData = computed(() => props.values.some(v => v > 0))
|
|
|
|
const chartData = computed(() => ({
|
|
labels: props.labels,
|
|
datasets: [{
|
|
data: props.values,
|
|
backgroundColor: props.color ?? '#6366f1',
|
|
borderWidth: 0,
|
|
borderRadius: 6,
|
|
}],
|
|
}))
|
|
|
|
const options = {
|
|
responsive: true,
|
|
maintainAspectRatio: false,
|
|
plugins: {
|
|
legend: { display: false },
|
|
},
|
|
scales: {
|
|
y: {
|
|
beginAtZero: true,
|
|
grid: { color: '#f3f4f6' },
|
|
},
|
|
x: {
|
|
grid: { display: false },
|
|
},
|
|
},
|
|
}
|
|
</script>
|