refactor(timesheet): fix delete shift functionality which had stopped working due to complete frontend refactor

This commit is contained in:
Nicolas Drolet 2025-10-14 14:18:32 -04:00
parent 7f43341629
commit 702a977fce
9 changed files with 102 additions and 82 deletions

View File

@ -22,6 +22,8 @@
const employeeEmail = defineModel(); const employeeEmail = defineModel();
const visible_columns = ref<string[]>(['REGULAR', 'email']);
const emit = defineEmits<{ const emit = defineEmits<{
'clickedDetailsButton': [email: string]; 'clickedDetailsButton': [email: string];
}>(); }>();
@ -56,6 +58,7 @@
<template> <template>
<div class="q-pa-md"> <div class="q-pa-md">
<q-table <q-table
:visible-columns="visible_columns"
:rows="overview_rows" :rows="overview_rows"
:columns="pay_period_overview_columns" :columns="pay_period_overview_columns"
row-key="email" row-key="email"

View File

@ -1,4 +1,7 @@
<script setup lang="ts"> <script
setup
lang="ts"
>
import { useShiftStore } from 'src/stores/shift-store'; import { useShiftStore } from 'src/stores/shift-store';
import { SHIFT_TYPES } from 'src/modules/timesheets/models/shift.models'; import { SHIFT_TYPES } from 'src/modules/timesheets/models/shift.models';

View File

@ -5,6 +5,7 @@
import { computed, ref } from 'vue'; import { computed, ref } from 'vue';
import { useShiftStore } from 'src/stores/shift-store'; import { useShiftStore } from 'src/stores/shift-store';
import { useShiftApi } from 'src/modules/timesheets/composables/api/use-shift-api'; import { useShiftApi } from 'src/modules/timesheets/composables/api/use-shift-api';
import ShiftCrudDialogAddUpdateShift from 'src/modules/timesheets/components/shift-crud-dialog-add-update-shift.vue';
const shift_store = useShiftStore(); const shift_store = useShiftStore();
const shift_api = useShiftApi(); const shift_api = useShiftApi();
@ -69,7 +70,7 @@
v-if="shift_store.mode !== 'delete'" v-if="shift_store.mode !== 'delete'"
class="row no-wrap items-start justify-center" class="row no-wrap items-start justify-center"
> >
<ShiftCrudDialogAddUpdateShift />
</div> </div>
<div <div

View File

@ -16,7 +16,7 @@ export const useShiftApi = () => {
start_time: shift.start_time, start_time: shift.start_time,
end_time: shift.end_time, end_time: shift.end_time,
type: shift.type, type: shift.type,
is_approved: false, is_approved: shift.is_approved,
is_remote: shift.is_remote, is_remote: shift.is_remote,
comment: comment, comment: comment,
}; };

View File

@ -10,7 +10,7 @@ export const SHIFT_TYPES = [
export type ShiftType = 'REGULAR' | 'EVENING' | 'EMERGENCY' | 'OVERTIME' | 'HOLIDAY' | 'VACATION' | 'SICK' ; export type ShiftType = 'REGULAR' | 'EVENING' | 'EMERGENCY' | 'OVERTIME' | 'HOLIDAY' | 'VACATION' | 'SICK' ;
export type UpsertAction = 'create' | 'update' | 'delete'; export type CrudAction = 'create' | 'update' | 'delete';
export type ShiftLegendItem = { export type ShiftLegendItem = {
type: ShiftType; type: ShiftType;
@ -30,7 +30,7 @@ export interface Shift {
} }
export interface UpsertShiftsResponse { export interface UpsertShiftsResponse {
action: UpsertAction; action: CrudAction;
day: Shift[]; day: Shift[];
} }

View File

@ -1,5 +1,5 @@
import { api } from "src/boot/axios"; import { api } from "src/boot/axios";
import type { UpsertShift } from "src/modules/timesheets/models/shift.models"; import type { CrudAction, UpsertShift } from "src/modules/timesheets/models/shift.models";
import type { PayPeriod } from "src/modules/shared/models/pay-period.models"; import type { PayPeriod } from "src/modules/shared/models/pay-period.models";
import type { PayPeriodDetails } from "src/modules/timesheets/models/pay-period-details.models"; import type { PayPeriodDetails } from "src/modules/timesheets/models/pay-period-details.models";
import type { PayPeriodOverview } from "src/modules/timesheet-approval/models/pay-period-overview.models"; import type { PayPeriodOverview } from "src/modules/timesheet-approval/models/pay-period-overview.models";
@ -36,15 +36,21 @@ export const timesheetService = {
return response.data; return response.data;
}, },
upsertOrDeleteShiftsByDateAndEmployeeEmail: async (email: string, payload: UpsertShift): Promise<PayPeriodDetails> => { upsertShiftsByEmployeeEmailAndAction: async (email: string, payload: UpsertShift, action: CrudAction): Promise<PayPeriodDetails> => {
const response = await api.put(`/shifts/upsert/${email}`, payload); const response = await api.put(`/shifts/upsert/${email}?action=${action}`, payload);
return response.data; return response.data;
}, },
deleteShiftsByEmployeeEmailAndDate: async (email: string, date: string, payload: UpsertShift) => {
console.log('sent old shift: ', payload);
const response = await api.delete(`/shifts/delete/${email}/${date}`, { data: payload });
return response;
},
upsertOrDeleteExpensesByPayPeriodAndEmployeeEmail: async (email: string, date: string, payload: UpsertExpense): Promise<Expense[]> => { upsertOrDeleteExpensesByPayPeriodAndEmployeeEmail: async (email: string, date: string, payload: UpsertExpense): Promise<Expense[]> => {
const headers = { 'Content-Type': 'application/json' } const headers = { 'Content-Type': 'application/json' }
const response = await api.put(`/expenses/upsert/${email}/${date}`, payload, { headers }); const response = await api.put(`/expenses/upsert/${email}/${date}`, payload, { headers });
return response.data; return response.data;
} },
}; };

View File

@ -6,7 +6,7 @@
const auth_store = useAuthStore(); const auth_store = useAuthStore();
const employee_roles = [ 'SUPERVISOR', 'EMPLOYEE', 'ADMIN', 'HR', 'ACCOUNTING' ]; const employee_roles = [ 'SUPERVISOR', 'EMPLOYEE', 'ADMIN', 'HR', 'ACCOUNTING' ];
const { employeeProfile } = defineProps<{ defineProps<{
employeeProfile?: EmployeeProfile | undefined; employeeProfile?: EmployeeProfile | undefined;
}>(); }>();
</script> </script>

View File

@ -4,7 +4,7 @@ import { useTimesheetStore } from "src/stores/timesheet-store";
import { default_expense, default_pay_period_expenses, type UpsertExpense, type Expense, type PayPeriodExpenses } from "src/modules/timesheets/models/expense.models"; import { default_expense, default_pay_period_expenses, type UpsertExpense, type Expense, type PayPeriodExpenses } from "src/modules/timesheets/models/expense.models";
import { timesheetService } from "src/modules/timesheets/services/timesheet-service"; import { timesheetService } from "src/modules/timesheets/services/timesheet-service";
import { ExpensesApiError, type GenericApiError } from "src/modules/timesheets/models/expense.validation"; import { ExpensesApiError, type GenericApiError } from "src/modules/timesheets/models/expense.validation";
import type { UpsertAction } from "src/modules/timesheets/models/shift.models"; import type { CrudAction } from "src/modules/timesheets/models/shift.models";
@ -12,7 +12,7 @@ export const useExpensesStore = defineStore('expenses', () => {
const timesheet_store = useTimesheetStore(); const timesheet_store = useTimesheetStore();
const is_open = ref(false); const is_open = ref(false);
const is_loading = ref(false); const is_loading = ref(false);
const mode = ref<UpsertAction>('create'); const mode = ref<CrudAction>('create');
const pay_period_expenses = ref<PayPeriodExpenses>(default_pay_period_expenses); const pay_period_expenses = ref<PayPeriodExpenses>(default_pay_period_expenses);
const current_expense = ref<Expense>(default_expense); const current_expense = ref<Expense>(default_expense);
const initial_expense = ref<Expense>(default_expense); const initial_expense = ref<Expense>(default_expense);

View File

@ -3,18 +3,18 @@ import { defineStore } from "pinia";
import { unwrapAndClone } from "src/utils/unwrap-and-clone"; import { unwrapAndClone } from "src/utils/unwrap-and-clone";
import { timesheetService } from "src/modules/timesheets/services/timesheet-service"; import { timesheetService } from "src/modules/timesheets/services/timesheet-service";
import { useTimesheetStore } from "src/stores/timesheet-store"; import { useTimesheetStore } from "src/stores/timesheet-store";
import { default_shift, type UpsertAction, type Shift, type UpsertShift } from "src/modules/timesheets/models/shift.models"; import { default_shift, type CrudAction, type Shift, type UpsertShift } from "src/modules/timesheets/models/shift.models";
export const useShiftStore = defineStore('shift', () => { export const useShiftStore = defineStore('shift', () => {
const is_open = ref(false); const is_open = ref(false);
const mode = ref<UpsertAction>('create'); const mode = ref<CrudAction>('create');
const date_iso = ref<string>(''); const date_iso = ref<string>('');
const current_shift = ref<Shift>(default_shift); const current_shift = ref<Shift>(default_shift);
const initial_shift = ref<Shift>(default_shift); const initial_shift = ref<Shift>(default_shift);
const timesheet_store = useTimesheetStore(); const timesheet_store = useTimesheetStore();
const open = (next_mode: UpsertAction, date: string, current: Shift, initial: Shift) => { const open = (next_mode: CrudAction, date: string, current: Shift, initial: Shift) => {
mode.value = next_mode; mode.value = next_mode;
date_iso.value = date; date_iso.value = date;
current_shift.value = current; // new shift current_shift.value = current; // new shift
@ -38,19 +38,26 @@ export const useShiftStore = defineStore('shift', () => {
is_open.value = false; is_open.value = false;
mode.value = 'create'; mode.value = 'create';
date_iso.value = ''; date_iso.value = '';
current_shift.value = default_shift;
initial_shift.value = default_shift;
}; };
const upsertOrDeleteShiftByEmployeeEmail = async (employee_email: string, upsert_shift: UpsertShift) => { const upsertOrDeleteShiftByEmployeeEmail = async (employee_email: string, upsert_shift: UpsertShift) => {
const encoded_email = encodeURIComponent(employee_email); const encoded_email = encodeURIComponent(employee_email);
try { try {
const result = await timesheetService.upsertOrDeleteShiftsByDateAndEmployeeEmail(encoded_email, upsert_shift); if (mode.value === 'delete') {
const result = await timesheetService.deleteShiftsByEmployeeEmailAndDate(encoded_email, upsert_shift.old_shift?.date ?? '', upsert_shift);
console.log('result: ', result);
if (result.status === 200) {
await timesheet_store.getPayPeriodDetailsByEmployeeEmail(employee_email);
}
} else {
const result = await timesheetService.upsertShiftsByEmployeeEmailAndAction(encoded_email, upsert_shift, mode.value);
timesheet_store.pay_period_details = result; timesheet_store.pay_period_details = result;
}
close(); close();
} catch (err) { } catch (err) {
console.log('error doing thing: ', err) console.log('error doing thing: ', err);
// const status_code: number = err?.response?.status ?? 500; // const status_code: number = err?.response?.status ?? 500;
// const data = err?.response?.data ?? {}; // const data = err?.response?.data ?? {};
// throw new GenericApiError({ // throw new GenericApiError({