From 2e2f2cd802b5d761b6f4870f0741db74987e69fc Mon Sep 17 00:00:00 2001 From: Nicolas Drolet Date: Tue, 20 Jan 2026 16:27:23 -0500 Subject: [PATCH 1/2] feat(timesheet_approval): begin integration of connection to approval SSE stream --- src/i18n/en-ca/index.ts | 7 +++++++ src/i18n/fr-ca/index.ts | 7 +++++++ .../services/timesheet-approval-service.ts | 4 ++++ src/stores/timesheet-store.ts | 11 +++++++++++ 4 files changed, 29 insertions(+) diff --git a/src/i18n/en-ca/index.ts b/src/i18n/en-ca/index.ts index ade6d75..ab923ec 100644 --- a/src/i18n/en-ca/index.ts +++ b/src/i18n/en-ca/index.ts @@ -367,6 +367,13 @@ export default { hours_worked_title: "hours worked", expenses_title: "expenses accrued", }, + event: { + update: "has updated", + create: "has created", + delete: "has deleted", + expense: "an expense", + shift: "a shift", + }, print_report: { title: "Download options", description: "Choose what to include in the report", diff --git a/src/i18n/fr-ca/index.ts b/src/i18n/fr-ca/index.ts index d18f8fc..2403e5e 100644 --- a/src/i18n/fr-ca/index.ts +++ b/src/i18n/fr-ca/index.ts @@ -367,6 +367,13 @@ export default { hours_worked_title: "heures travaillées", expenses_title: "dépenses encourues" }, + event: { + update: "a mis à jour", + create: "a créé", + delete: "a supprimé", + expense: "une dépense", + shift: " un quart de travail", + }, print_report: { title: "options de téléchargement", description: "Choisissez ce qui sera inclu dans le rapport", diff --git a/src/modules/timesheet-approval/services/timesheet-approval-service.ts b/src/modules/timesheet-approval/services/timesheet-approval-service.ts index 383dde2..1e9607e 100644 --- a/src/modules/timesheet-approval/services/timesheet-approval-service.ts +++ b/src/modules/timesheet-approval/services/timesheet-approval-service.ts @@ -18,4 +18,8 @@ export const timesheetApprovalService = { const response = await api.patch>('pay-periods/pay-period-approval', { email, timesheet_ids, is_approved}); return response.data; }, + + subscribeToPayPeriodObservable: (): EventSource => { + return new EventSource('pay-periods/subscribe') + }, }; \ No newline at end of file diff --git a/src/stores/timesheet-store.ts b/src/stores/timesheet-store.ts index 1163d25..c73e1b6 100644 --- a/src/stores/timesheet-store.ts +++ b/src/stores/timesheet-store.ts @@ -26,6 +26,7 @@ export const useTimesheetStore = defineStore('timesheet', () => { const has_timesheet_preset = ref(false); const current_pay_period_overview = ref(); const pay_period_report = ref(); + const pay_period_observer = ref(); const federal_holidays = ref([]); @@ -180,6 +181,15 @@ export const useTimesheetStore = defineStore('timesheet', () => { is_report_dialog_open.value = false; }; + const subscribeToPayPeriodObservable = () => { + if (pay_period_observer.value === undefined) { + pay_period_observer.value = timesheetApprovalService.subscribeToPayPeriodObservable(); + pay_period_observer.value.onmessage = () => { + + } + } + } + return { is_loading, is_report_dialog_open, @@ -203,5 +213,6 @@ export const useTimesheetStore = defineStore('timesheet', () => { getPayPeriodReport, openReportDialog, closeReportDialog, + subscribeToPayPeriodObservable, }; }); \ No newline at end of file From dccc2f4a1087088e0b96cbeb9b8962244b587008 Mon Sep 17 00:00:00 2001 From: Nic D Date: Wed, 21 Jan 2026 10:21:01 -0500 Subject: [PATCH 2/2] feat(approvals): add SSE to timesheet-approval to notify of timesheet changes --- src/i18n/en-ca/index.ts | 1 + src/i18n/fr-ca/index.ts | 1 + .../models/pay-period-event.models.ts | 5 +++ .../services/timesheet-approval-service.ts | 2 +- src/pages/timesheet-approval-page.vue | 7 ++++- src/pages/timesheet-page.vue | 13 ++++---- src/stores/timesheet-store.ts | 31 ++++++++++++++++--- 7 files changed, 47 insertions(+), 13 deletions(-) create mode 100644 src/modules/timesheet-approval/models/pay-period-event.models.ts diff --git a/src/i18n/en-ca/index.ts b/src/i18n/en-ca/index.ts index ab923ec..58909a6 100644 --- a/src/i18n/en-ca/index.ts +++ b/src/i18n/en-ca/index.ts @@ -373,6 +373,7 @@ export default { delete: "has deleted", expense: "an expense", shift: "a shift", + preset: "many shifts", }, print_report: { title: "Download options", diff --git a/src/i18n/fr-ca/index.ts b/src/i18n/fr-ca/index.ts index 2403e5e..27d8ff3 100644 --- a/src/i18n/fr-ca/index.ts +++ b/src/i18n/fr-ca/index.ts @@ -373,6 +373,7 @@ export default { delete: "a supprimé", expense: "une dépense", shift: " un quart de travail", + preset: "plusieurs quarts de travail", }, print_report: { title: "options de téléchargement", diff --git a/src/modules/timesheet-approval/models/pay-period-event.models.ts b/src/modules/timesheet-approval/models/pay-period-event.models.ts new file mode 100644 index 0000000..80e03cd --- /dev/null +++ b/src/modules/timesheet-approval/models/pay-period-event.models.ts @@ -0,0 +1,5 @@ +export interface PayPeriodEvent { + employee_email: string; + event_type: 'shift' | 'expense' | 'preset'; + action: 'create' | 'update' | 'delete'; +} \ No newline at end of file diff --git a/src/modules/timesheet-approval/services/timesheet-approval-service.ts b/src/modules/timesheet-approval/services/timesheet-approval-service.ts index 1e9607e..34416f0 100644 --- a/src/modules/timesheet-approval/services/timesheet-approval-service.ts +++ b/src/modules/timesheet-approval/services/timesheet-approval-service.ts @@ -20,6 +20,6 @@ export const timesheetApprovalService = { }, subscribeToPayPeriodObservable: (): EventSource => { - return new EventSource('pay-periods/subscribe') + return new EventSource('http://localhost:3000/pay-periods/subscribe'); }, }; \ No newline at end of file diff --git a/src/pages/timesheet-approval-page.vue b/src/pages/timesheet-approval-page.vue index 5677750..947c41c 100644 --- a/src/pages/timesheet-approval-page.vue +++ b/src/pages/timesheet-approval-page.vue @@ -9,7 +9,7 @@ import OverviewReport from 'src/modules/timesheet-approval/components/overview-report.vue'; import { date } from 'quasar'; - import { computed, onMounted, ref } from 'vue'; + import { computed, onMounted, onUnmounted, ref } from 'vue'; import { useTimesheetApprovalApi } from 'src/modules/timesheet-approval/composables/use-timesheet-approval-api'; import { useTimesheetStore } from 'src/stores/timesheet-store'; @@ -28,7 +28,12 @@ onMounted(async () => { await timesheet_approval_api.getTimesheetOverviewsByDate(date.formatDate(new Date(), 'YYYY-MM-DD')); + timesheet_store.subscribeToPayPeriodObservable(); }); + + onUnmounted(() => { + timesheet_store.unsubscribeToPayPeriodObservable(); + })