targo-frontend/src/modules/timesheet-approval/components/details-crud-dialog-chart-hours-worked.vue

97 lines
3.4 KiB
Vue

<script setup lang="ts">
import { ref } from 'vue';
import { colors } from 'quasar';
import { Bar } from 'vue-chartjs';
import { useI18n } from 'vue-i18n';
import { useQuasar } from 'quasar';
import { Chart as ChartJS, Title, Tooltip, Legend, BarElement, CategoryScale, LinearScale, type ChartData, type ChartDataset } from 'chart.js';
import { useTimesheetStore } from 'src/stores/timesheet-store';
const { t } = useI18n();
const $q = useQuasar();
ChartJS.register(Title, Tooltip, Legend, BarElement, CategoryScale, LinearScale);
ChartJS.defaults.font.family = '"Roboto", sans-serif';
ChartJS.defaults.maintainAspectRatio = false;
ChartJS.defaults.color = $q.dark.isActive ? '#F5F5F5' : '#616161';
const timesheet_store = useTimesheetStore();
const hours_worked_labels = ref<string[]>([]);
const hours_worked_dataset = ref<ChartDataset<'bar'>[]>([]);
const getHoursWorkedData = (): ChartData<'bar'> => {
const all_days = timesheet_store.pay_period_details.weeks.flatMap( week => Object.values(week.shifts));
const datasetConfig = [
{
key: 'regular_hours',
label: t('shared.shift_type.regular'),
color: colors.getPaletteColor('green-5'),
},
{
key: 'evening_hours',
label: t('shared.shift_type.evening'),
color: colors.getPaletteColor('green-9'),
},
{
key: 'emergency_hours',
label: t('shared.shift_type.emergency'),
color: getComputedStyle(document.body).getPropertyValue('--q-warning').trim(),
},
{
key: 'overtime_hours',
label: t('shared.shift_type.overtime'),
color: getComputedStyle(document.body).getPropertyValue('--q-negative').trim(),
},
] as const;
hours_worked_dataset.value = datasetConfig.map(cfg => ({
label: cfg.label,
data: all_days.map(day => day[ cfg.key ]),
backgroundColor: cfg.color,
}));
hours_worked_labels.value = all_days.map(day => day.short_date);
return {
labels: hours_worked_labels.value,
datasets: hours_worked_dataset.value,
};
};
</script>
<template>
<div>
<Bar
:data="getHoursWorkedData()"
:options="({
indexAxis: $q.screen.lt.md? 'y' : 'x',
plugins: {
legend: {
labels: {
boxWidth: 15,
},
},
title: {
display: true,
text: t('timesheet_approvals.chart.hours_worked_title'),
}
},
scales: {
x: {
stacked: true,
},
y: {
stacked: true,
suggestedMin: 0,
suggestedMax: 10,
}
}
})"
/>
</div>
</template>