From 9f15f80be46cd109260aab7d7d2cd47e316fbe8d Mon Sep 17 00:00:00 2001 From: Nic D Date: Mon, 9 Mar 2026 14:01:36 -0400 Subject: [PATCH 1/4] fix(timesheet-approval): prevent display of SSE events unrelated to current pay period viewed --- .../models/pay-period-event.models.ts | 1 + src/stores/timesheet-store.ts | 24 +++++++++---------- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/src/modules/timesheet-approval/models/pay-period-event.models.ts b/src/modules/timesheet-approval/models/pay-period-event.models.ts index 80e03cd..17f61ab 100644 --- a/src/modules/timesheet-approval/models/pay-period-event.models.ts +++ b/src/modules/timesheet-approval/models/pay-period-event.models.ts @@ -2,4 +2,5 @@ export interface PayPeriodEvent { employee_email: string; event_type: 'shift' | 'expense' | 'preset'; action: 'create' | 'update' | 'delete'; + date: string; } \ No newline at end of file diff --git a/src/stores/timesheet-store.ts b/src/stores/timesheet-store.ts index f6f1841..d9914d9 100644 --- a/src/stores/timesheet-store.ts +++ b/src/stores/timesheet-store.ts @@ -1,3 +1,5 @@ +import { Notify, date } from 'quasar'; +import { useI18n } from 'vue-i18n'; import { computed, ref } from 'vue'; import { defineStore } from 'pinia'; import { unwrapAndClone } from 'src/utils/unwrap-and-clone'; @@ -9,8 +11,6 @@ import type { Timesheet } from 'src/modules/timesheets/models/timesheet.models'; import type { PayPeriodEvent } from 'src/modules/timesheet-approval/models/pay-period-event.models'; import type { TimesheetApprovalCSVReportFilters } from 'src/modules/timesheet-approval/models/timesheet-approval-csv-report.models'; import { type FederalHoliday, TARGO_HOLIDAY_NAMES_FR } from 'src/modules/timesheets/models/federal-holidays.models'; -import { Notify } from 'quasar'; -import { useI18n } from 'vue-i18n'; export const useTimesheetStore = defineStore('timesheet', () => { @@ -139,13 +139,6 @@ export const useTimesheetStore = defineStore('timesheet', () => { try { const timesheet_ids = timesheets.value.map(timesheet => timesheet.timesheet_id); - // Backend returns the amount of shifts and expenses successfully updated, could be useful for error handling??? - // const shift_expense_count = timesheets.value.reduce((timesheets_sum, timesheet) => { - // return timesheets_sum + timesheet.days.reduce((day_sum, day) => { - // return day_sum + day.shifts.length + day.expenses.length - // }, 0); - // }, 0); - const response = await timesheetApprovalService.updateTimesheetsApprovalStatus(email, timesheet_ids, approval_status); return response.success; } catch (error) { @@ -185,19 +178,24 @@ export const useTimesheetStore = defineStore('timesheet', () => { if (pay_period_observer.value === undefined) { pay_period_observer.value = timesheetApprovalService.subscribeToPayPeriodObservable(); pay_period_observer.value.onmessage = async (event: MessageEvent) => { - // find employee that modified their timesheets const pay_period_event: PayPeriodEvent = JSON.parse(event.data); + + // abort notification if event date is not within pay period being currently viewed + const eventDate = date.extractDate(pay_period_event.date, 'YYYY-MM-DD'); + const startDate = date.extractDate(pay_period.value!.period_start, 'YYYY-MM-DD'); + const endDate = date.extractDate(pay_period.value!.period_end, 'YYYY-MM-DD'); + + if (!date.isBetweenDates(eventDate, startDate, endDate, { inclusiveFrom: true, inclusiveTo: true, onlyDate: true })) + return; + const overview = pay_period_overviews.value.find(overview => overview.email === pay_period_event.employee_email); const employee_name = overview?.employee_first_name + ' ' + overview?.employee_last_name; - // update overviews await getTimesheetOverviews(); - // if user is looking at details of employee that generated event, update if (selected_employee_name.value === employee_name) await getTimesheetsByOptionalEmployeeEmail(pay_period_event.employee_email); - // create visual feedback of notification and update Notify.create({ message: `${employee_name} ${t('timesheet_approvals.event.' + pay_period_event.action)} ${t('timesheet_approvals.event.' + pay_period_event.event_type)}`, color: 'warning', From 1271d1eb6195c86e5ad808ad87a833ba3c1a2643 Mon Sep 17 00:00:00 2001 From: Nic D Date: Tue, 10 Mar 2026 15:52:40 -0400 Subject: [PATCH 2/4] fix(timesheet): fix issue with expense not updating properly in approval module Also rework expense item appearance in list to better divide space between components for visual clarity. --- quasar.config.ts | 7 +- .../components/details-dialog.vue | 40 +- .../components/overview-report.vue | 2 +- .../components/expense-dialog-form.vue | 479 +++++++++--------- .../components/expense-dialog-list-item.vue | 175 +++---- .../components/expense-dialog-list.vue | 8 +- .../timesheets/components/expense-dialog.vue | 15 +- .../timesheets/composables/use-expense-api.ts | 29 +- src/stores/expense-store.ts | 4 +- src/stores/timesheet-store.ts | 9 +- src/utils/date-and-time-utils.ts | 20 +- 11 files changed, 411 insertions(+), 377 deletions(-) diff --git a/quasar.config.ts b/quasar.config.ts index 205b2f3..7a69943 100644 --- a/quasar.config.ts +++ b/quasar.config.ts @@ -66,10 +66,13 @@ export default defineConfig((ctx) => { // polyfillModulePreload: true, // distDir - extendViteConf: (_config) => ({ + extendViteConf: (config) => ({ optimizeDeps: { exclude: ['tesseract.js'] - } + }, + define: { + __VUE_PROD_DEVTOOLS__: config.mode !== 'production' + }, }), // viteVuePluginOptions: {}, diff --git a/src/modules/timesheet-approval/components/details-dialog.vue b/src/modules/timesheet-approval/components/details-dialog.vue index 0c3f08a..93136b7 100644 --- a/src/modules/timesheet-approval/components/details-dialog.vue +++ b/src/modules/timesheet-approval/components/details-dialog.vue @@ -2,20 +2,21 @@ setup lang="ts" > - import { useI18n } from 'vue-i18n'; - import { computed, ref } from 'vue'; - import { useTimesheetStore } from 'src/stores/timesheet-store'; import DetailsDialogChartHoursWorked from 'src/modules/timesheet-approval/components/details-dialog-chart-hours-worked.vue'; import DetailsDialogChartShiftTypes from 'src/modules/timesheet-approval/components/details-dialog-chart-shift-types.vue'; import DetailsDialogChartExpenses from 'src/modules/timesheet-approval/components/details-dialog-chart-expenses.vue'; import TimesheetWrapper from 'src/modules/timesheets/components/timesheet-wrapper.vue'; import ExpenseDialogList from 'src/modules/timesheets/components/expense-dialog-list.vue'; import ExpenseDialogForm from 'src/modules/timesheets/components/expense-dialog-form.vue'; + + import { date } from 'quasar'; + import { useI18n } from 'vue-i18n'; + import { computed, ref } from 'vue'; + import { useTimesheetStore } from 'src/stores/timesheet-store'; import { useTimesheetApprovalApi } from '../composables/use-timesheet-approval-api'; import { useShiftApi } from 'src/modules/timesheets/composables/use-shift-api'; import { useExpensesStore } from 'src/stores/expense-store'; import { Expense } from 'src/modules/timesheets/models/expense.models'; - import { date } from 'quasar'; // ========== state ======================================== @@ -25,6 +26,7 @@ const timesheetApprovalApi = useTimesheetApprovalApi(); const shiftApi = useShiftApi(); const isDialogOpen = ref(false); + const refreshKey = ref(0); // ========== computed ======================================== @@ -34,9 +36,9 @@ t('shared.label.unlock') : t('shared.label.lock') ); - + const approveButtonIcon = computed(() => isApproved.value ? 'las la-lock' : 'las la-unlock'); - + const hasExpenses = computed(() => timesheetStore.timesheets.some(timesheet => Object.values(timesheet.weekly_expenses).some(hours => hours > 0)) ); @@ -60,13 +62,22 @@ expenseStore.is_showing_create_form = false; } - const onClickExpenseCreate = () => { + const onClickNewExpense = () => { expenseStore.mode = 'create'; if (timesheetStore.pay_period) expenseStore.current_expense = new Expense(timesheetStore.pay_period.period_start); else expenseStore.current_expense = new Expense(date.formatDate(new Date(), 'YYYY-MM-DD')); } + + const onClickSaveNewExpense = () => { + expenseStore.is_showing_create_form = false; + } + + const onShowDetailsDialog = () => { + isDialogOpen.value = true; + expenseStore.is_showing_create_form = false; + } - \ No newline at end of file From 9213a42d6b4ff53dcde9382b73ea38aa9a768c3b Mon Sep 17 00:00:00 2001 From: "Nic D." <91558719+Venti-Bear@users.noreply.github.com> Date: Wed, 11 Mar 2026 12:24:06 -0400 Subject: [PATCH 4/4] refactor(timesheet): complete overhaul of expense UI, fix functionality in approval module. --- src/modules/shared/components/targo-input.vue | 65 ++-- .../components/details-dialog.vue | 1 + .../components/overview-list.vue | 1 + .../components/expense-dialog-form.vue | 329 ++++++++++-------- .../components/expense-dialog-list-item.vue | 1 + 5 files changed, 224 insertions(+), 173 deletions(-) diff --git a/src/modules/shared/components/targo-input.vue b/src/modules/shared/components/targo-input.vue index 56fae33..8cba47b 100644 --- a/src/modules/shared/components/targo-input.vue +++ b/src/modules/shared/components/targo-input.vue @@ -3,7 +3,7 @@ lang="ts" > const model = defineModel({ required: true }); - const is_date_picker_open = defineModel('isDatePickerOpen', {default: false}); + const is_date_picker_open = defineModel('isDatePickerOpen', { default: false }); defineProps<{ label?: string | undefined; @@ -11,16 +11,22 @@ maxLength?: number; noTopPadding?: boolean; backgroundColor?: 'bg-secondary' | 'bg-dark'; + appendContent?: string | number; }>(); + + defineOptions({ + inheritAttrs: false + }) - - diff --git a/src/modules/timesheet-approval/components/details-dialog.vue b/src/modules/timesheet-approval/components/details-dialog.vue index 93136b7..544eeca 100644 --- a/src/modules/timesheet-approval/components/details-dialog.vue +++ b/src/modules/timesheet-approval/components/details-dialog.vue @@ -197,6 +197,7 @@ diff --git a/src/modules/timesheet-approval/components/overview-list.vue b/src/modules/timesheet-approval/components/overview-list.vue index 108958d..22403c0 100644 --- a/src/modules/timesheet-approval/components/overview-list.vue +++ b/src/modules/timesheet-approval/components/overview-list.vue @@ -117,6 +117,7 @@