From e44d790a21000fc9cba826edc38a484625dd40cf Mon Sep 17 00:00:00 2001
From: "Nic D." <91558719+Venti-Bear@users.noreply.github.com>
Date: Mon, 26 Jan 2026 09:52:45 -0500
Subject: [PATCH 1/7] fix(timesheet-approval): fix oversight to modify employee
timesheet from approval module
Fixed an oversight in the logic in one of the steps to update and create shifts from the timesheet approval page, which led to update or create requests being sent with the users credentials instead of the employees
---
src/i18n/en-ca/index.ts | 3 ++
src/i18n/fr-ca/index.ts | 3 ++
.../components/timesheet-wrapper.vue | 36 ++++++++++++++-----
.../timesheets/composables/use-shift-api.ts | 6 ++--
src/stores/shift-store.ts | 3 +-
5 files changed, 37 insertions(+), 14 deletions(-)
diff --git a/src/i18n/en-ca/index.ts b/src/i18n/en-ca/index.ts
index e7514ce..f256e88 100644
--- a/src/i18n/en-ca/index.ts
+++ b/src/i18n/en-ca/index.ts
@@ -224,6 +224,7 @@ export default {
error: {
no_data_found: "no data found",
no_search_results: "no results matching search",
+ generic_error: "An error occured",
},
label: {
search: "search",
@@ -284,6 +285,7 @@ export default {
apply_preset: "auto-fill",
apply_preset_day: "Apply schedule to day",
apply_preset_week: "Apply schedule to week",
+ save_successful: "timesheets saved",
nav_button: {
calendar_date_picker: "Calendar",
current_week: "This week",
@@ -359,6 +361,7 @@ export default {
SHIFT_TYPE_REQUIRED: "Shift type required",
TIMESHEET_NOT_FOUND: "No timesheet found with provided data",
UPDATE_ERROR: "Error while updating data",
+ ERROR_SAVING_SHIFTS: "Timesheet changes were not saved",
},
},
diff --git a/src/i18n/fr-ca/index.ts b/src/i18n/fr-ca/index.ts
index 13c402c..8ab3e7c 100644
--- a/src/i18n/fr-ca/index.ts
+++ b/src/i18n/fr-ca/index.ts
@@ -224,6 +224,7 @@ export default {
error: {
no_data_found: 'aucune donnée à afficher',
no_search_results: 'aucun résultat ne correspond à la recherche',
+ generic_error: "Une erreur est survenue",
},
label: {
search: 'recherche',
@@ -284,6 +285,7 @@ export default {
apply_preset: "auto-remplir",
apply_preset_day: "Appliquer horaire pour la journée",
apply_preset_week: "Appliquer horaire pour la semaine",
+ save_successful: "feuilles de temps enregistrées",
nav_button: {
calendar_date_picker: "Calendrier",
current_week: "Semaine actuelle",
@@ -359,6 +361,7 @@ export default {
SHIFT_TYPE_REQUIRED: "Type requis",
TIMESHEET_NOT_FOUND: "Aucune feuille de temps ne correspond au détails fournis",
UPDATE_ERROR: "Une erreur est survenu lors de la mise à jour",
+ ERROR_SAVING_SHIFTS: "les changements aux feuilles de temps n'ont pas été enregistrés",
},
},
diff --git a/src/modules/timesheets/components/timesheet-wrapper.vue b/src/modules/timesheets/components/timesheet-wrapper.vue
index 00318ba..1acb3ba 100644
--- a/src/modules/timesheets/components/timesheet-wrapper.vue
+++ b/src/modules/timesheets/components/timesheet-wrapper.vue
@@ -2,7 +2,6 @@
setup
lang="ts"
>
- /* eslint-disable */
import ShiftList from 'src/modules/timesheets/components/shift-list.vue';
import ShiftListScrollable from 'src/modules/timesheets/components/shift-list-scrollable.vue';
import LoadingOverlay from 'src/modules/shared/components/loading-overlay.vue';
@@ -13,14 +12,15 @@
import ShiftListWeeklyOverview from 'src/modules/timesheets/components/shift-list-weekly-overview.vue';
import ShiftListWeeklyOverviewMobile from 'src/modules/timesheets/components/mobile/shift-list-weekly-overview-mobile.vue';
+ import { useI18n } from 'vue-i18n';
import { computed, onMounted } from 'vue';
import { useShiftApi } from 'src/modules/timesheets/composables/use-shift-api';
import { useTimesheetApi } from 'src/modules/timesheets/composables/use-timesheet-api';
import { useExpensesStore } from 'src/stores/expense-store';
import { useTimesheetStore } from 'src/stores/timesheet-store';
- import { date } from 'quasar';
-
+ import { date, Notify } from 'quasar';
+ const { t } = useI18n();
const expenses_store = useExpensesStore();
const timesheet_store = useTimesheetStore();
const timesheet_api = useTimesheetApi();
@@ -41,13 +41,25 @@
sum + timesheet.weekly_expenses.expenses
+ timesheet.weekly_expenses.on_call
+ timesheet.weekly_expenses.per_diem,
- 0) //initial value
- );
+ 0 //initial value
+ ));
const { mode = 'normal' } = defineProps<{
mode?: 'approval' | 'normal';
}>();
+ const onClickSaveTimesheets = async () => {
+ if (mode === 'normal') {
+ await shift_api.saveShiftChanges();
+ Notify.create({
+ message: t('timesheet.save_successful'),
+ color: 'accent',
+ });
+ } else {
+ await shift_api.saveShiftChanges(timesheet_store.current_pay_period_overview?.email);
+ }
+ }
+
onMounted(async () => {
if (mode === 'normal')
await timesheet_api.getTimesheetsByDate(date.formatDate(new Date(), 'YYYY-MM-DD'));
@@ -97,7 +109,10 @@
v-if="!$q.platform.is.mobile"
class="col-xs-6 col-md-4 col-xl-3 q-pa-md"
>
-
+
@@ -116,7 +131,10 @@
/>
-
+
@@ -204,7 +222,7 @@
:label="$t('shared.label.save')"
class="col-auto absolute-bottom shadow-up-10"
style="height: 50px;"
- @click="shift_api.saveShiftChanges"
+ @click="onClickSaveTimesheets"
/>
{
timesheet_store.is_loading = false;
};
- const saveShiftChanges = async () => {
+ const saveShiftChanges = async (employee_email?: string) => {
timesheet_store.is_loading = true;
- const update_success = await shift_store.updateShifts();
- const create_success = await shift_store.createNewShifts();
+ const update_success = await shift_store.updateShifts(employee_email);
+ const create_success = await shift_store.createNewShifts(employee_email);
if (create_success || update_success){
await timesheet_store.getTimesheetsByOptionalEmployeeEmail(auth_store.user?.email ?? '');
diff --git a/src/stores/shift-store.ts b/src/stores/shift-store.ts
index f2f62f9..db4ede5 100644
--- a/src/stores/shift-store.ts
+++ b/src/stores/shift-store.ts
@@ -53,8 +53,7 @@ export const useShiftStore = defineStore('shift_store', () => {
return true;
}
}
-
- Notify.create('No shifts to update')
+
return false;
} catch (error) {
Notify.create('Error updating shifts');
From 42de823b870dcde58820edbf11362ab867b5b193 Mon Sep 17 00:00:00 2001
From: "Nic D." <91558719+Venti-Bear@users.noreply.github.com>
Date: Mon, 26 Jan 2026 10:05:47 -0500
Subject: [PATCH 2/7] fix(date-time-utils): fix rounding error in util method
that converts hours float to HHmm string
---
src/utils/date-and-time-utils.ts | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/src/utils/date-and-time-utils.ts b/src/utils/date-and-time-utils.ts
index 3360f77..52a4758 100644
--- a/src/utils/date-and-time-utils.ts
+++ b/src/utils/date-and-time-utils.ts
@@ -21,7 +21,13 @@ export const getMinutes = (hours: number) => {
}
export const getHoursMinutesStringFromHoursFloat = (hours: number): string => {
- const flat_hours = Math.floor(hours);
- const minutes = Math.round((hours - flat_hours) * 60);
+ let flat_hours = Math.floor(hours);
+ let minutes = Math.round((hours - flat_hours) * 60);
+
+ if (minutes === 60) {
+ flat_hours += 1;
+ minutes = 0;
+ }
+
return `${flat_hours}h${minutes > 1 ? ' ' + minutes : ''}`
}
\ No newline at end of file
From 8231b3084da9ca4d4778d8134c6b82466bce4b7f Mon Sep 17 00:00:00 2001
From: "Nic D." <91558719+Venti-Bear@users.noreply.github.com>
Date: Mon, 26 Jan 2026 10:08:53 -0500
Subject: [PATCH 3/7] fix(timesheets): fix error where shift payload is not
sent when modify employee timesheets from approval page
---
src/modules/timesheets/services/shift-service.ts | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/modules/timesheets/services/shift-service.ts b/src/modules/timesheets/services/shift-service.ts
index aef90ec..5abf09a 100644
--- a/src/modules/timesheets/services/shift-service.ts
+++ b/src/modules/timesheets/services/shift-service.ts
@@ -15,7 +15,7 @@ export const ShiftService = {
createNewShifts: async (new_shifts: Shift[], employee_email?: string):Promise> => {
if (employee_email) {
- const response = await api.post(`/shift/create/${employee_email}`);
+ const response = await api.post(`/shift/create/${employee_email}`, new_shifts);
return response.data;
}
@@ -25,7 +25,7 @@ export const ShiftService = {
updateShifts: async (existing_shifts: Shift[], employee_email?: string):Promise> => {
if (employee_email) {
- const response = await api.patch(`/shift/update/${employee_email}`);
+ const response = await api.patch(`/shift/update/${employee_email}`, existing_shifts);
return response.data;
}
From 75060a22282f4df26439083ddae7394b473fc27f Mon Sep 17 00:00:00 2001
From: "Nic D." <91558719+Venti-Bear@users.noreply.github.com>
Date: Mon, 26 Jan 2026 10:41:24 -0500
Subject: [PATCH 4/7] fix(timesheet-approval): minor fix to timesheet reload
after changes to employee timesheet
was reloading users timesheets instead of employees after update or create
---
src/modules/timesheets/composables/use-shift-api.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/modules/timesheets/composables/use-shift-api.ts b/src/modules/timesheets/composables/use-shift-api.ts
index ef1df28..6b6176e 100644
--- a/src/modules/timesheets/composables/use-shift-api.ts
+++ b/src/modules/timesheets/composables/use-shift-api.ts
@@ -25,7 +25,7 @@ export const useShiftApi = () => {
const create_success = await shift_store.createNewShifts(employee_email);
if (create_success || update_success){
- await timesheet_store.getTimesheetsByOptionalEmployeeEmail(auth_store.user?.email ?? '');
+ await timesheet_store.getTimesheetsByOptionalEmployeeEmail(employee_email);
}
timesheet_store.is_loading = false;
From 1cac8966be081be6f6b4cf2d15ae5dcc825fe202 Mon Sep 17 00:00:00 2001
From: "Nic D." <91558719+Venti-Bear@users.noreply.github.com>
Date: Mon, 26 Jan 2026 11:09:50 -0500
Subject: [PATCH 5/7] fix(timesheet-approval): fix issue where expense wouldn't
show correct expense type an refuse to update
---
.../components/expense-dialog-form.vue | 22 ++++++++++++++-----
.../components/expense-dialog-list-item.vue | 2 +-
.../timesheets/composables/use-expense-api.ts | 11 +++++-----
.../timesheets/composables/use-shift-api.ts | 4 +---
4 files changed, 24 insertions(+), 15 deletions(-)
diff --git a/src/modules/timesheets/components/expense-dialog-form.vue b/src/modules/timesheets/components/expense-dialog-form.vue
index 6ae8811..1dc7f97 100644
--- a/src/modules/timesheets/components/expense-dialog-form.vue
+++ b/src/modules/timesheets/components/expense-dialog-form.vue
@@ -33,6 +33,8 @@
const period_start_date = computed(() => timesheet_store.pay_period?.period_start.replaceAll('-', '/') ?? '');
const period_end_date = computed(() => timesheet_store.pay_period?.period_end.replaceAll('-', '/') ?? '');
+ const expense = defineModel({ default: new Expense(new Date().toISOString().slice(0, 10)) })
+
const expense_options: ExpenseOption[] = [
{ label: t('timesheet.expense.types.PER_DIEM'), value: 'PER_DIEM', icon: getExpenseIcon('PER_DIEM') },
{ label: t('timesheet.expense.types.EXPENSES'), value: 'EXPENSES', icon: getExpenseIcon('EXPENSES') },
@@ -55,7 +57,10 @@
}
const requestExpenseCreationOrUpdate = async () => {
- await expenses_api.upsertExpense(expenses_store.current_expense);
+ if (expenses_store.mode === 'update')
+ await expenses_api.upsertExpense(expenses_store.current_expense, timesheet_store.current_pay_period_overview?.email);
+ else
+ await expenses_api.upsertExpense(expenses_store.current_expense);
expenses_store.is_showing_create_form = true;
expenses_store.mode = 'create';
@@ -63,13 +68,18 @@
};
onMounted(() => {
- expense_selected.value = expense_options.find(expense => expense.value === expenses_store.current_expense.type);
+ if (expense.value)
+ expense_selected.value = expense_options.find(expense_option => expense_option.value === expense.value.type);
+ else
+ expense_selected.value = expense_options[1];
+
+ console.log('expense mount triggered: current expense type is ', expenses_store.current_expense.type, ', matching option is: ', expense_selected.value);
})
\ No newline at end of file
diff --git a/src/modules/timesheets/components/expense-dialog-list-item.vue b/src/modules/timesheets/components/expense-dialog-list-item.vue
index 5b29602..3bdd0a6 100644
--- a/src/modules/timesheets/components/expense-dialog-list-item.vue
+++ b/src/modules/timesheets/components/expense-dialog-list-item.vue
@@ -212,6 +212,6 @@
-
+
\ No newline at end of file
diff --git a/src/modules/timesheets/composables/use-expense-api.ts b/src/modules/timesheets/composables/use-expense-api.ts
index d5ea046..e4b3485 100644
--- a/src/modules/timesheets/composables/use-expense-api.ts
+++ b/src/modules/timesheets/composables/use-expense-api.ts
@@ -8,18 +8,19 @@ export const useExpensesApi = () => {
const expenses_store = useExpensesStore();
const timesheet_store = useTimesheetStore();
- const upsertExpense = async (expense: Expense): Promise => {
- const success = await expenses_store.upsertExpense(expense);
+ const upsertExpense = async (expense: Expense, employee_email?: string): Promise => {
+ const success = await expenses_store.upsertExpense(expense, employee_email);
+
if (success) {
expenses_store.current_expense = new Expense(date.formatDate( new Date(), 'YYYY-MM-DD'));
- timesheet_store.getTimesheetsByOptionalEmployeeEmail();
+ timesheet_store.getTimesheetsByOptionalEmployeeEmail(employee_email);
}
};
- const deleteExpenseById = async (expense_id: number): Promise => {
+ const deleteExpenseById = async (expense_id: number, employee_email?: string): Promise => {
const success = await expenses_store.deleteExpenseById(expense_id);
if (success) {
- timesheet_store.getTimesheetsByOptionalEmployeeEmail();
+ timesheet_store.getTimesheetsByOptionalEmployeeEmail(employee_email);
}
};
diff --git a/src/modules/timesheets/composables/use-shift-api.ts b/src/modules/timesheets/composables/use-shift-api.ts
index 6b6176e..2696836 100644
--- a/src/modules/timesheets/composables/use-shift-api.ts
+++ b/src/modules/timesheets/composables/use-shift-api.ts
@@ -1,18 +1,16 @@
-import { useAuthStore } from "src/stores/auth-store";
import { useShiftStore } from "src/stores/shift-store";
import { useTimesheetStore } from "src/stores/timesheet-store";
export const useShiftApi = () => {
const timesheet_store = useTimesheetStore();
const shift_store = useShiftStore();
- const auth_store = useAuthStore();
const deleteShiftById = async (shift_id: number, employee_email?: string) => {
timesheet_store.is_loading = true;
const success = await shift_store.deleteShiftById(shift_id, employee_email);
if (success) {
- await timesheet_store.getTimesheetsByOptionalEmployeeEmail(auth_store.user?.email ?? '');
+ await timesheet_store.getTimesheetsByOptionalEmployeeEmail(employee_email);
}
timesheet_store.is_loading = false;
From b0de761645064869df9df1001bc04eb250fd7ce5 Mon Sep 17 00:00:00 2001
From: "Nic D." <91558719+Venti-Bear@users.noreply.github.com>
Date: Mon, 26 Jan 2026 12:16:52 -0500
Subject: [PATCH 6/7] fix(timesheet-approval): overview list now updates when
closing details dialog.
Graphs at top of details dialog now update dynamically if user makes changes to employee timesheet.
---
.../details-dialog-chart-expenses.vue | 36 ++++++-------
.../details-dialog-chart-hours-worked.vue | 32 +++++-------
.../details-dialog-chart-shift-types.vue | 52 ++++++++++---------
.../components/details-dialog.vue | 1 +
.../components/expense-dialog-form.vue | 2 -
5 files changed, 56 insertions(+), 67 deletions(-)
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 2147d13..aac41f0 100644
--- a/src/modules/timesheet-approval/components/details-dialog-chart-expenses.vue
+++ b/src/modules/timesheet-approval/components/details-dialog-chart-expenses.vue
@@ -2,12 +2,12 @@
setup
lang="ts"
>
- import { onMounted, ref } from 'vue';
+ import { computed, ref } from 'vue';
import { Bar } from 'vue-chartjs';
import { useI18n } from 'vue-i18n';
import { useQuasar, colors } from 'quasar';
import { useTimesheetStore } from 'src/stores/timesheet-store';
- import { Chart as ChartJS, Title, Tooltip, Legend, BarElement, CategoryScale, LinearScale, TimeScale, type ChartDataset } from 'chart.js';
+ import { Chart as ChartJS, Title, Tooltip, Legend, BarElement, CategoryScale, LinearScale, TimeScale } from 'chart.js';
const { t } = useI18n();
const $q = useQuasar();
@@ -19,27 +19,21 @@
const timesheet_store = useTimesheetStore();
- const all_days = timesheet_store.timesheets.flatMap(week => week.days.flatMap(day => day.daily_expenses));
+ const all_days = computed(() => timesheet_store.timesheets.flatMap(week => week.days.flatMap(day => day.daily_expenses)));
const expenses_labels = ref(timesheet_store.timesheets.flatMap(week => week.days.map(day => day.date.slice(-5,))));
- const expenses_dataset = ref[]>([]);
-
- onMounted(() => {
- setTimeout(() => {
- expenses_dataset.value = [
- {
- label: t('timesheet_approvals.table.expenses'),
- data: all_days.map(day => (day.expenses + day.on_call + day.per_diem)),
- backgroundColor: colors.getPaletteColor('accent'),
- },
- {
- label: t('timesheet_approvals.table.mileage'),
- data: all_days.map(day => day.mileage),
- backgroundColor: colors.getPaletteColor('info'),
- }
- ]
- }, 100)
- });
+ const expenses_dataset = computed(() => [
+ {
+ label: t('timesheet_approvals.table.expenses'),
+ data: all_days.value.map(day => (day.expenses + day.on_call + day.per_diem)),
+ backgroundColor: colors.getPaletteColor('accent'),
+ },
+ {
+ label: t('timesheet_approvals.table.mileage'),
+ data: all_days.value.map(day => day.mileage),
+ backgroundColor: colors.getPaletteColor('info'),
+ }
+ ]);
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 b3f8867..d7e78d7 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
@@ -2,17 +2,17 @@
setup
lang="ts"
>
- import { ref, onMounted } from 'vue';
+ import { ref, computed } from 'vue';
import { useI18n } from 'vue-i18n';
import { colors, date, useQuasar } from 'quasar';
import { Bar } from 'vue-chartjs';
- import { Chart as ChartJS, Title, Tooltip, Legend, BarElement, CategoryScale, LinearScale, TimeScale, type ChartDataset } from 'chart.js';
+ import { Chart as ChartJS, Title, Tooltip, Legend, BarElement, CategoryScale, LinearScale, TimeScale } from 'chart.js';
import { useTimesheetStore } from 'src/stores/timesheet-store';
import type { TotalHours } from 'src/modules/timesheets/models/timesheet.models';
-import { getHoursMinutesStringFromHoursFloat } from 'src/utils/date-and-time-utils';
+ import { getHoursMinutesStringFromHoursFloat } from 'src/utils/date-and-time-utils';
interface ChartConfigHoursWorked {
- key: keyof Pick;
+ key: keyof Pick;
label: string;
color: string;
}
@@ -27,7 +27,7 @@ import { getHoursMinutesStringFromHoursFloat } from 'src/utils/date-and-time-uti
const timesheet_store = useTimesheetStore();
- const all_days = timesheet_store.timesheets.flatMap(week => week.days);
+ const all_days = computed(() => timesheet_store.timesheets.flatMap(week => week.days));
const datasetConfig: ChartConfigHoursWorked[] = [
{
@@ -62,18 +62,12 @@ import { getHoursMinutesStringFromHoursFloat } from 'src/utils/date-and-time-uti
},
];
- const hours_worked_labels = ref(all_days.map(day => day.date.slice(-5,)));
- const hours_worked_dataset = ref[]>([]);
-
- onMounted(() => {
- setTimeout(() => {
- hours_worked_dataset.value = datasetConfig.map(cfg => ({
- label: cfg.label,
- data: all_days.map(day => day.daily_hours[cfg.key]),
- backgroundColor: cfg.color,
- }));
- }, 100);
- });
+ const hours_worked_labels = ref(all_days.value.map(day => day.date.slice(-5,)));
+ const hours_worked_datasets = computed(() => datasetConfig.map(cfg => ({
+ label: cfg.label,
+ data: all_days.value.map(day => day.daily_hours[cfg.key]),
+ backgroundColor: cfg.color,
+ })))
@@ -83,7 +77,7 @@ import { getHoursMinutesStringFromHoursFloat } from 'src/utils/date-and-time-uti
>
- /* eslint-disable */
- import { onMounted, ref } from 'vue';
+ import { computed } from 'vue';
import { useI18n } from 'vue-i18n';
import { colors } from 'quasar';
import { useQuasar } from 'quasar';
import { Doughnut } from 'vue-chartjs';
- import { Chart as ChartJS, Title, Tooltip, Legend, ArcElement, CategoryScale, LinearScale, type ChartDataset } from 'chart.js';
+ import { Chart as ChartJS, Title, Tooltip, Legend, ArcElement, CategoryScale, LinearScale } from 'chart.js';
import { useTimesheetStore } from 'src/stores/timesheet-store';
import { getHoursMinutesStringFromHoursFloat } from 'src/utils/date-and-time-utils';
+ import type { Timesheet, TotalHours } from 'src/modules/timesheets/models/timesheet.models';
const $q = useQuasar();
const { t } = useI18n();
@@ -22,33 +22,27 @@
const timesheet_store = useTimesheetStore();
- const shift_type_labels = ref([
+ const TRACKABLE_SHIFT_TYPES: (keyof TotalHours)[] = ['regular', 'evening', 'emergency', 'overtime', 'holiday', 'vacation']
+
+ const SHIFT_TYPE_LABELS = [
t('shared.shift_type.regular'),
t('shared.shift_type.evening'),
t('shared.shift_type.emergency'),
t('shared.shift_type.overtime'),
- ]);
+ t('shared.shift_type.holiday'),
+ t('shared.shift_type.vacation'),
+ ];
- const shift_type_totals = ref[]>([]);
+ const shift_type_data = computed(() => {
+ const initial_totals = new Array(TRACKABLE_SHIFT_TYPES.length).fill(0);
- onMounted(() => {
- setTimeout(() => {
- 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('accent'), // Regular
- colors.getPaletteColor('green-10'), // Evening
- colors.getPaletteColor('warning'), // Emergency
- colors.getPaletteColor('negative'), // Overtime
- ]
- }]
+ return timesheet_store.timesheets.reduce((accumulator: number[], timesheet: Timesheet) => {
+ TRACKABLE_SHIFT_TYPES.forEach( (trackable_shift_type, index) => {
+ accumulator[index]! += timesheet.weekly_hours[trackable_shift_type] ?? 0;
+ });
- }, 100);
+ return accumulator;
+ }, initial_totals);
});
@@ -59,8 +53,16 @@
>
expense_option.value === expense.value.type);
else
expense_selected.value = expense_options[1];
-
- console.log('expense mount triggered: current expense type is ', expenses_store.current_expense.type, ', matching option is: ', expense_selected.value);
})
From e8f72178b2fe6a85edcf5bc879201c2398f22b24 Mon Sep 17 00:00:00 2001
From: "Nic D." <91558719+Venti-Bear@users.noreply.github.com>
Date: Mon, 26 Jan 2026 16:27:54 -0500
Subject: [PATCH 7/7] refactor(auth): change behavior of disconnect button, now
ends authentik session for app only
---
src/stores/auth-store.ts | 18 +++++++++++-------
1 file changed, 11 insertions(+), 7 deletions(-)
diff --git a/src/stores/auth-store.ts b/src/stores/auth-store.ts
index 3eecc6f..cee85c7 100644
--- a/src/stores/auth-store.ts
+++ b/src/stores/auth-store.ts
@@ -31,6 +31,10 @@ export const useAuthStore = defineStore('auth', () => {
const logout = () => {
user.value = undefined;
+ AuthService.logout();
+ const logout_popup = window.open('https://auth.targo.ca/application/o/montargo/end-session/', 'logoutPopup', 'width=200,height=200');
+
+ setInterval(() => logout_popup?.close(), 2000);
};
const handleAuthMessage = async (event: MessageEvent) => {
@@ -61,13 +65,13 @@ export const useAuthStore = defineStore('auth', () => {
return { status: 400, message: 'unknown error occured' };
}
- return {
- user,
- authError,
- login,
- oidcLogin,
- logout,
- getProfile
+ return {
+ user,
+ authError,
+ login,
+ oidcLogin,
+ logout,
+ getProfile
};
});