From a47222a7b8ebcf44598efa09ad8e01dc9e8fea7f Mon Sep 17 00:00:00 2001 From: Nicolas Drolet Date: Thu, 20 Nov 2025 14:41:50 -0500 Subject: [PATCH] fix(approvals): reimplement charts with new structures, clean UI/UX, refine list view --- src/css/app.scss | 1 - src/css/quasar.variables.scss | 4 +- src/i18n/en-ca/index.ts | 4 +- src/i18n/fr-ca/index.ts | 4 +- .../details-dialog-chart-expenses.vue | 36 +++---- .../details-dialog-chart-hours-worked.vue | 102 ++++++++++-------- .../details-dialog-chart-shift-types.vue | 42 ++++---- .../components/details-dialog.vue | 32 +++--- .../components/overview-list-item.vue | 4 +- .../components/overview-list.vue | 84 ++++++++++----- .../composables/use-timesheet-approval-api.ts | 34 +++--- .../models/timesheet-overview.models.ts | 58 +++++++--- .../timesheets/components/shift-list.vue | 1 - .../timesheets/models/timesheet.models.ts | 4 +- .../timesheets/services/timesheet-service.ts | 4 +- src/pages/timesheet-approval-page.vue | 9 +- src/stores/timesheet-store.ts | 14 ++- 17 files changed, 251 insertions(+), 186 deletions(-) diff --git a/src/css/app.scss b/src/css/app.scss index 29d530e..1ade66d 100644 --- a/src/css/app.scss +++ b/src/css/app.scss @@ -5,7 +5,6 @@ } } - .text-fb-blue { color: #4267B2 !important; } diff --git a/src/css/quasar.variables.scss b/src/css/quasar.variables.scss index f803073..1b60238 100644 --- a/src/css/quasar.variables.scss +++ b/src/css/quasar.variables.scss @@ -15,9 +15,9 @@ $primary : #30303A; $secondary : #DAE0E7; $accent : #0c9a3b; -$accent2 : #0a7d32; +$accent2 : #0a7d32; -$dark-shadow-color : #173625; +$dark-shadow-color : #000000; $elevation-dark-umbra : rgba($dark-shadow-color, 1); $elevation-dark-penumbra : rgba($dark-shadow-color, 0.75); diff --git a/src/i18n/en-ca/index.ts b/src/i18n/en-ca/index.ts index 17831c0..1f96213 100644 --- a/src/i18n/en-ca/index.ts +++ b/src/i18n/en-ca/index.ts @@ -130,8 +130,8 @@ export default { nav_button: { calendar_date_picker: "Calendar", current_week: "This week", - next_week: "Next week", - previous_week: "Previous week", + next_week: "Next period", + previous_week: "Previous period", }, save_button: "Save", cancel_button: "Cancel", diff --git a/src/i18n/fr-ca/index.ts b/src/i18n/fr-ca/index.ts index 1fcc2bb..43b22b5 100644 --- a/src/i18n/fr-ca/index.ts +++ b/src/i18n/fr-ca/index.ts @@ -131,8 +131,8 @@ export default { nav_button: { calendar_date_picker: "Calendrier", current_week: "Semaine actuelle", - next_week: "Prochaine semaine", - previous_week: "Semaine précédente", + next_week: "Prochaine période", + previous_week: "Période précédente", }, save_button: "Enregistrer", cancel_button: "Annuler", diff --git a/src/modules/timesheet-approval/components/details-dialog-chart-expenses.vue b/src/modules/timesheet-approval/components/details-dialog-chart-expenses.vue index eb74d61..3ed73c3 100644 --- a/src/modules/timesheet-approval/components/details-dialog-chart-expenses.vue +++ b/src/modules/timesheet-approval/components/details-dialog-chart-expenses.vue @@ -7,7 +7,7 @@ import { ref } from 'vue'; import { Bar } from 'vue-chartjs'; import { useI18n } from 'vue-i18n'; - import { useQuasar } from 'quasar'; + import { useQuasar, colors } from 'quasar'; import { useTimesheetStore } from 'src/stores/timesheet-store'; import { Chart as ChartJS, Title, Tooltip, Legend, BarElement, CategoryScale, LinearScale, TimeScale, type ChartData, type ChartDataset } from 'chart.js'; @@ -25,28 +25,26 @@ const expenses_labels = ref([]); const getExpensesData = (): ChartData<'bar'> => { - // const all_days = timesheet_store.pay_period_details.weeks.flatMap(week => Object.values(week.expenses)); - // const all_days_dates = timesheet_store.pay_period_details.weeks.flatMap(week => Object.values(week.shifts)) + const all_days = timesheet_store.timesheets.flatMap(week => week.days.flatMap(day => day.daily_expenses)); - // const all_costs = all_days.map(day => day.total_expenses); - // console.log('costs, ', all_costs); - // const all_mileage = all_days.map(day => day.total_mileage); + const all_costs = all_days.map(day => (day.expenses + day.on_call + day.per_diem)); + const all_mileage = all_days.map(day => day.mileage); - // expenses_dataset.value = [ - // { - // label: t('timesheet_approvals.table.expenses'), - // data: all_costs, - // backgroundColor: getComputedStyle(document.body).getPropertyValue('--q-primary').trim(), - // }, - // { - // label: t('timesheet_approvals.table.mileage'), - // data: all_mileage, - // backgroundColor: getComputedStyle(document.body).getPropertyValue('--q-info').trim(), - // } - // ] + expenses_dataset.value = [ + { + label: t('timesheet_approvals.table.expenses'), + data: all_costs, + backgroundColor: colors.getPaletteColor('primary'), + }, + { + label: t('timesheet_approvals.table.mileage'), + data: all_mileage, + backgroundColor: colors.getPaletteColor('info'), + } + ] - // expenses_labels.value = all_days_dates.map(day => day.short_date); + expenses_labels.value = timesheet_store.timesheets.flatMap(week => week.days.map(day => day.date.slice(-5, ))); return { datasets: expenses_dataset.value, diff --git a/src/modules/timesheet-approval/components/details-dialog-chart-hours-worked.vue b/src/modules/timesheet-approval/components/details-dialog-chart-hours-worked.vue index 743f4fe..6a13aa8 100644 --- a/src/modules/timesheet-approval/components/details-dialog-chart-hours-worked.vue +++ b/src/modules/timesheet-approval/components/details-dialog-chart-hours-worked.vue @@ -1,67 +1,79 @@ - \ No newline at end of file diff --git a/src/modules/timesheet-approval/components/details-dialog-chart-shift-types.vue b/src/modules/timesheet-approval/components/details-dialog-chart-shift-types.vue index f8016d0..c1edb19 100644 --- a/src/modules/timesheet-approval/components/details-dialog-chart-shift-types.vue +++ b/src/modules/timesheet-approval/components/details-dialog-chart-shift-types.vue @@ -17,33 +17,33 @@ ChartJS.defaults.maintainAspectRatio = false; ChartJS.defaults.color = $q.dark.isActive ? '#F5F5F5' : '#616161'; - const { current_pay_period_overview } = useTimesheetStore(); + const timesheet_store = useTimesheetStore(); const shift_type_labels = ref([]); const shift_type_totals = ref[]>([{ data: [40, 0, 2, 5], }]); - // shift_type_totals.value = [{ - // data: [ - // current_pay_period_overview.regular_hours, - // current_pay_period_overview.other_hours.evening_hours, - // current_pay_period_overview.other_hours.emergency_hours, - // current_pay_period_overview.other_hours.overtime_hours, - // ], - // backgroundColor: [ - // colors.getPaletteColor('green-5'), // Regular - // colors.getPaletteColor('green-9'), // Evening - // getComputedStyle(document.body).getPropertyValue('--q-warning').trim(), // Emergency - // getComputedStyle(document.body).getPropertyValue('--q-negative').trim(), // Overtime - // ] - // }]; + shift_type_totals.value = [{ + data: [ + timesheet_store.current_pay_period_overview!.regular_hours, + timesheet_store.current_pay_period_overview!.other_hours.evening_hours, + timesheet_store.current_pay_period_overview!.other_hours.emergency_hours, + timesheet_store.current_pay_period_overview!.other_hours.overtime_hours, + ], + backgroundColor: [ + colors.getPaletteColor('primary'), // Regular + colors.getPaletteColor('accent'), // Evening + colors.getPaletteColor('warning'), // Emergency + colors.getPaletteColor('negative'), // Overtime + ] + }]; - // shift_type_labels.value = [ - // current_pay_period_overview.regular_hours.toString() + 'h', - // current_pay_period_overview.other_hours.evening_hours.toString() + 'h', - // current_pay_period_overview.other_hours.emergency_hours.toString() + 'h', - // current_pay_period_overview.other_hours.overtime_hours.toString() + 'h', - // ] + shift_type_labels.value = [ + timesheet_store.current_pay_period_overview!.regular_hours.toString() + 'h', + timesheet_store.current_pay_period_overview!.other_hours.evening_hours.toString() + 'h', + timesheet_store.current_pay_period_overview!.other_hours.emergency_hours.toString() + 'h', + timesheet_store.current_pay_period_overview!.other_hours.overtime_hours.toString() + 'h', + ] const data = { diff --git a/src/modules/timesheet-approval/components/details-dialog.vue b/src/modules/timesheet-approval/components/details-dialog.vue index b68be4a..4975e1d 100644 --- a/src/modules/timesheet-approval/components/details-dialog.vue +++ b/src/modules/timesheet-approval/components/details-dialog.vue @@ -17,7 +17,7 @@ const dialog_model = defineModel('dialog', { default: false }); const timesheet_store = useTimesheetStore(); - const render_key = ref(1); + const is_dialog_open = ref(false); provide('employeeEmail', employeeEmail); @@ -29,45 +29,37 @@ full-height transition-show="jump-down" transition-hide="jump-down" - @show="render_key += 1" + @show="is_dialog_open = true" + @hide="is_dialog_open = false" > - TODO: Name goes here + {{ timesheet_store.selected_employee_name }} - + - + - + diff --git a/src/modules/timesheet-approval/components/overview-list-item.vue b/src/modules/timesheet-approval/components/overview-list-item.vue index 6acbe35..30720e6 100644 --- a/src/modules/timesheet-approval/components/overview-list-item.vue +++ b/src/modules/timesheet-approval/components/overview-list-item.vue @@ -17,13 +17,13 @@