+
{{ $d(date.extractDate(startDate, 'YYYY-MM-DD'), date_format_options) }}
{{ $t('shared.misc.to') }}
-
+
{{ $d(date.extractDate(endDate, 'YYYY-MM-DD'), date_format_options) }}
diff --git a/src/modules/shared/components/pay-period-navigator.vue b/src/modules/shared/components/pay-period-navigator.vue
index cd24802..f9ff694 100644
--- a/src/modules/shared/components/pay-period-navigator.vue
+++ b/src/modules/shared/components/pay-period-navigator.vue
@@ -63,7 +63,7 @@
expenses_store.mode === 'update' ? 'accent' : '');
+ const openDatePicker = () => {
+ is_navigator_open.value = true;
+ if (expenses_store.current_expense.date === '') {
+ expenses_store.current_expense.date = date.formatDate(new Date(), 'YYYY-MM-DD');
+ }
+ };
+
const cancelUpdateMode = () => {
expenses_store.current_expense = new Expense;
expenses_store.initial_expense = new Expense;
- }
+ expenses_store.mode = 'create';
+ };
const requestExpenseCreationOrUpdate = async () => {
if (expenses_store.mode === 'create') await expenses_api.createExpenseByEmployeeEmail(employee_email ?? '', expenses_store.current_expense?.date ?? '');
else await expenses_api.updateExpenseByEmployeeEmail(employee_email ?? '', expenses_store.current_expense?.date ?? '');
- }
+ };
-
+
{{ $t('timesheet.expense.add_expense') }}
-
-
+
-
+
-
+
+
@@ -81,20 +95,25 @@
-
+
-
+ >
+
+
+ {{ $t('timesheet.expense.amount') }}
+
+
+
+
-
+
-
+ >
+
+
+ {{ $t('timesheet.expense.mileage') }}
+
+
+
+
-
- {{ $t('timesheet.expense.comment') }}
+
+ {{ $t('timesheet.expense.employee_comment') }}
@@ -166,7 +193,6 @@
stack-label
:label="$t('timesheet.expense.hints.attach_file')"
class="col"
- :bg-color="background_color"
style="max-width: 300px;"
>
@@ -177,30 +203,29 @@
/>
+
+
\ No newline at end of file
diff --git a/src/modules/timesheets/components/expense-dialog-header.vue b/src/modules/timesheets/components/expense-dialog-header.vue
index 02e3753..a34a182 100644
--- a/src/modules/timesheets/components/expense-dialog-header.vue
+++ b/src/modules/timesheets/components/expense-dialog-header.vue
@@ -2,43 +2,91 @@
setup
lang="ts"
>
- /* eslint-disable */
+ import { computed } from 'vue';
import { useExpensesStore } from 'src/stores/expense-store';
+ import { useTimesheetStore } from 'src/stores/timesheet-store';
+ const timesheet_store = useTimesheetStore();
const expense_store = useExpensesStore();
+ const weekly_totals = computed(() => {
+ let expenses = 0;
+ let mileage = 0;
+ timesheet_store.timesheets.forEach(timesheet => {
+ expenses += timesheet.weekly_expenses.expenses ?? 0;
+ mileage += timesheet.weekly_expenses.mileage ?? 0;
+ });
+
+ return { expenses, mileage };
+ });
-
-
- {{ $t('timesheet.expense.title') }}
-
+
+
+
+ {{ $t('timesheet.expense.title') }}
+
-
-
+
+
+
+
+
+ {{ $t('timesheet.expense.total_amount') }} :
+
+
+
+
+
+ {{ weekly_totals.expenses.toFixed(2) }}
+
+
+
+
+
+ {{ $t('timesheet.expense.total_mileage') }} :
+
+
+
+
+
+ {{ weekly_totals.mileage.toFixed(1) }}
+
+
+
+
\ 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 41a5d63..996c1f4 100644
--- a/src/modules/timesheets/components/expense-dialog-list-item.vue
+++ b/src/modules/timesheets/components/expense-dialog-list-item.vue
@@ -4,13 +4,13 @@
>
import { computed, inject, ref } from 'vue';
import { unwrapAndClone } from 'src/utils/unwrap-and-clone';
+ import { deepEqual } from 'src/utils/deep-equal';
import { useExpensesApi } from 'src/modules/timesheets/composables/use-expense-api';
import { useExpensesStore } from 'src/stores/expense-store';
import { getExpenseIcon } from 'src/modules/timesheets/utils/expense.util';
import { useAuthStore } from 'src/stores/auth-store';
import { CAN_APPROVE_PAY_PERIODS } from 'src/modules/shared/models/user.models';
import { Expense } from 'src/modules/timesheets/models/expense.models';
- import { deepEqual } from 'src/utils/deep-equal';
const { expense, horizontal = false } = defineProps<{
expense: Expense;
@@ -25,18 +25,11 @@
const employee_email = inject
('employeeEmail') ?? '';
const refresh_key = ref(1);
- const background_class = computed(() => deepEqual(expense, expenses_store.current_expense) ? 'bg-accent' : '');
- const approved_class = computed(() => horizontal ? ' q-mx-xs q-pa-xs cursor-pointer' : '')
- const expense_item_style = computed(() => is_approved.value ? 'border: solid 2px var(--q-primary);' : 'border: solid 2px grey;');
+ const background_class = computed(() => deepEqual(expense, expenses_store.current_expense) ? '' : '');
+ const background_style = computed(() => deepEqual(expense, expenses_store.current_expense) ? 'border: 3px solid var(--q-accent);' : '');
+ const approved_class = computed(() => expense.is_approved ? ' bg-accent text-white' : '')
const is_authorized_to_approve = computed(() => CAN_APPROVE_PAY_PERIODS.includes(auth_store.user?.role ?? 'GUEST'))
- const setExpenseToUpdate = () => {
- expenses_store.mode = 'update';
- // if (expense.is_approved) return;
- expenses_store.current_expense = expense;
- expenses_store.initial_expense = unwrapAndClone(expense);
- };
-
const requestExpenseDeletion = async () => {
// expenses_store.mode = 'delete';
expenses_store.initial_expense = expense;
@@ -52,13 +45,15 @@
}
const onUpdateClicked = () => {
- if (expenses_store.mode === 'update') {
+ if (deepEqual(expense, expenses_store.current_expense)){
expenses_store.mode = 'create';
expenses_store.current_expense = new Expense;
- expenses_store.initial_expense = new Expense;
- return;
+ return;
}
- setExpenseToUpdate();
+
+ expenses_store.mode = 'update';
+ expenses_store.current_expense = expense;
+ expenses_store.initial_expense = unwrapAndClone(expense);
}
@@ -70,28 +65,16 @@
-
-
-
-
-
+
{{ expense.mileage?.toFixed(1) }} km
@@ -126,7 +109,8 @@
{{ $d(new Date(expense.date), { month: 'short', day: 'numeric', weekday: 'long' }) }}
@@ -135,28 +119,32 @@
-
+
+
+ attachment_goes_here.jpg
+
+
-
+
{{ $t('timesheet.expense.employee_comment') }}
{{ expense.comment }}
@@ -164,10 +152,10 @@
-
+
{{ $t('timesheet.expense.supervisor_comment') }}
diff --git a/src/modules/timesheets/components/expense-dialog-list.vue b/src/modules/timesheets/components/expense-dialog-list.vue
index e0f31b7..baf542e 100644
--- a/src/modules/timesheets/components/expense-dialog-list.vue
+++ b/src/modules/timesheets/components/expense-dialog-list.vue
@@ -16,7 +16,7 @@
-
+
-
-
-
\ No newline at end of file
diff --git a/src/modules/timesheets/components/shift-list-date-widget.vue b/src/modules/timesheets/components/shift-list-date-widget.vue
new file mode 100644
index 0000000..5555892
--- /dev/null
+++ b/src/modules/timesheets/components/shift-list-date-widget.vue
@@ -0,0 +1,53 @@
+
+
+
+
+
+ {{ $d(display_date, { weekday: $q.screen.lt.md ? 'short' : 'long'}) }}
+
+
+ {{ display_date.getDate() }}
+
+
+ {{ $d(display_date, { month: $q.screen.lt.md ? 'short' : 'long' }) }}
+
+
+
\ No newline at end of file
diff --git a/src/modules/timesheets/components/shift-list-day-row.vue b/src/modules/timesheets/components/shift-list-day-row.vue
new file mode 100644
index 0000000..f15fe3e
--- /dev/null
+++ b/src/modules/timesheets/components/shift-list-day-row.vue
@@ -0,0 +1,266 @@
+
+
+
+ slideDeleteShift(details.reset)"
+ >
+
+
+
+
+
+
+
shift.type = option.value"
+ >
+
+
+
+ {{ scope.opt.label }}
+
+
+
+
+
+
+
+ {{ $t('shared.misc.in') }}
+
+
+
+
+
+
+ {{ $t('shared.misc.out') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ 280 - (scope.value?.length ?? 0) }}
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/modules/timesheets/components/shift-list-day.vue b/src/modules/timesheets/components/shift-list-day.vue
new file mode 100644
index 0000000..2d926eb
--- /dev/null
+++ b/src/modules/timesheets/components/shift-list-day.vue
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/modules/timesheets/components/shift-list-row.vue b/src/modules/timesheets/components/shift-list-row.vue
deleted file mode 100644
index e7c98b1..0000000
--- a/src/modules/timesheets/components/shift-list-row.vue
+++ /dev/null
@@ -1,208 +0,0 @@
-
-
-
-
-
-
-
-
-
- {{ scope.opt.label }}
-
-
-
-
-
-
-
- {{ $t('shared.misc.in') }}
-
-
-
-
-
-
-
-
-
-
- {{ $t('shared.misc.out') }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/modules/timesheets/components/shift-list.vue b/src/modules/timesheets/components/shift-list.vue
index 69a0025..60c520d 100644
--- a/src/modules/timesheets/components/shift-list.vue
+++ b/src/modules/timesheets/components/shift-list.vue
@@ -3,27 +3,17 @@
lang="ts"
>
import { date } from 'quasar';
- import { computed } from 'vue';
- import { useQuasar } from 'quasar';
- import ShiftListRow from 'src/modules/timesheets/components/shift-list-row.vue';
- import { useTimesheetStore } from 'src/stores/timesheet-store';
- import { useShiftApi } from 'src/modules/timesheets/composables/use-shift-api';
- import { Shift } from 'src/modules/timesheets/models/shift.models';
import { useUiStore } from 'src/stores/ui-store';
+ import { useTimesheetStore } from 'src/stores/timesheet-store';
+ import { Shift } from 'src/modules/timesheets/models/shift.models';
+ import ShiftListDay from 'src/modules/timesheets/components/shift-list-day.vue';
+ import ShiftListDateWidget from 'src/modules/timesheets/components/shift-list-date-widget.vue';
+ import type { TimesheetDay } from 'src/modules/timesheets/models/timesheet.models';
+
+ const { extractDate } = date;
- const q = useQuasar();
const ui_store = useUiStore();
const timesheet_store = useTimesheetStore();
- const shift_api = useShiftApi();
-
- const { dense = false } = defineProps<{
- dense?: boolean;
- }>();
-
- const is_mobile = computed(() => q.screen.lt.md);
- const date_font_size = computed(() => dense ? '1.5em' : '2.5em');
- const weekday_font_size = computed(() => dense ? '0.55em;' : '0.7em;');
- const date_box_size = computed(() => dense || is_mobile.value ? 'width: 40px; height: 75px;' : 'width: 75px; height: 75px;');
const addNewShift = (day_shifts: Shift[], date: string, timesheet_id: number) => {
ui_store.focus_next_component = true;
@@ -33,13 +23,18 @@
day_shifts.push(new_shift);
};
- const deleteCurrentShift = async (shift: Shift) => {
- console.log('shift to delete: ', shift);
- if (shift.shift_id < 0) {
- shift.shift_id = 0;
- return;
+ const deleteUnsavedShift = (timesheet_index: number, day_index: number) => {
+ if (timesheet_store.timesheets !== undefined) {
+ const day = timesheet_store.timesheets[timesheet_index]!.days[day_index]!;
+ const shifts_without_deleted_shift = day.shifts.filter(shift => shift.id !== 0);
+ day.shifts = shifts_without_deleted_shift;
+ console.log("day's shifts after cleanup: ", day.shifts);
}
- await shift_api.deleteShiftById(shift.shift_id);
+ }
+
+ const getDayApproval = (day: TimesheetDay) => {
+ if (day.shifts.length < 1) return false;
+ return day.shifts.every(shift => shift.is_approved === true);
}
@@ -49,77 +44,118 @@
:style="$q.screen.lt.md ? 'width: 90vw !important;' : ''"
>
-
-
-
+
+
- {{ $d(date.extractDate(day.date, 'YYYY-MM-DD'), {
- weekday: $q.screen.lt.md ? 'short' :
- 'long'
- })
- }}
-
-
- {{ date.extractDate(day.date, 'YYYY-MM-DD').getDate() }}
-
-
- {{ $d(date.extractDate(day.date, 'YYYY-MM-DD'), {
- month: $q.screen.lt.md ? 'short' : 'long'
- })
- }}
-
-
+
{{ $d(extractDate(day.date, 'YYYY-MM-DD'), {
+ weekday: 'long', day: 'numeric', month:
+ 'long'
+ }) }}
+
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
diff --git a/src/modules/timesheets/components/timesheet-error-widget.vue b/src/modules/timesheets/components/timesheet-error-widget.vue
new file mode 100644
index 0000000..a667a26
--- /dev/null
+++ b/src/modules/timesheets/components/timesheet-error-widget.vue
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+
+
+ {{ error.conflicts.date }}
+
+
+
+
+ {{ error.conflicts.start_time }} - {{ error.conflicts.end_time }}
+
+
+
+
+ {{ $t('timesheet.shift.errors.' + error.error_code) }}
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/modules/timesheets/components/timesheet-wrapper.vue b/src/modules/timesheets/components/timesheet-wrapper.vue
index 6ac0c04..3c0a970 100644
--- a/src/modules/timesheets/components/timesheet-wrapper.vue
+++ b/src/modules/timesheets/components/timesheet-wrapper.vue
@@ -5,11 +5,12 @@
import ShiftList from 'src/modules/timesheets/components/shift-list.vue';
import ExpenseDialog from 'src/modules/timesheets/components/expense-dialog.vue';
import PayPeriodNavigator from 'src/modules/shared/components/pay-period-navigator.vue';
+ import TimesheetErrorWidget from 'src/modules/timesheets/components/timesheet-error-widget.vue';
import { useTimesheetStore } from 'src/stores/timesheet-store';
import { useTimesheetApi } from 'src/modules/timesheets/composables/use-timesheet-api';
import { useExpensesStore } from 'src/stores/expense-store';
import { provide } from 'vue';
-import { useShiftApi } from 'src/modules/timesheets/composables/use-shift-api';
+ import { useShiftApi } from 'src/modules/timesheets/composables/use-shift-api';
const { open } = useExpensesStore();
const shift_api = useShiftApi();
@@ -76,12 +77,12 @@ import { useShiftApi } from 'src/modules/timesheets/composables/use-shift-api';
-
+
+
+
+
diff --git a/src/modules/timesheets/composables/use-shift-api.ts b/src/modules/timesheets/composables/use-shift-api.ts
index ccbbcc4..bb41d22 100644
--- a/src/modules/timesheets/composables/use-shift-api.ts
+++ b/src/modules/timesheets/composables/use-shift-api.ts
@@ -20,15 +20,14 @@ export const useShiftApi = () => {
const saveShiftChanges = async () => {
timesheet_store.is_loading = true;
+
const create_success = await shift_store.createNewShifts();
+ const update_success = await shift_store.updateShifts();
- if (create_success) {
- const update_success = await shift_store.updateShifts();
-
- if (update_success) {
- await timesheet_store.getTimesheetsByEmployeeEmail(auth_store.user?.email ?? '')
- }
+ if (create_success || update_success){
+ await timesheet_store.getTimesheetsByEmployeeEmail(auth_store.user?.email ?? '');
}
+
timesheet_store.is_loading = false;
}
diff --git a/src/modules/timesheets/models/shift.models.ts b/src/modules/timesheets/models/shift.models.ts
index f312091..2881a61 100644
--- a/src/modules/timesheets/models/shift.models.ts
+++ b/src/modules/timesheets/models/shift.models.ts
@@ -9,6 +9,8 @@ export const SHIFT_TYPES: ShiftType[] = [
export type ShiftType = 'REGULAR' | 'EVENING' | 'EMERGENCY' | 'HOLIDAY' | 'VACATION' | 'SICK';
+export type ShiftErrorCode = 'SHIFT_OVERLAP' | 'MISSING_START_TIME' | 'MISSING_END_TIME' | 'COMMENT_LENGTH_EXCEEDED' | 'APPROVAL_LOCK' | 'INVALID_DATE' | 'INVALID TYPE' | 'INVALID_TIMESHEET';
+
export type ShiftLegendItem = {
type: ShiftType;
color: string;
@@ -17,7 +19,7 @@ export type ShiftLegendItem = {
};
export class Shift {
- shift_id: number;
+ id: number;
timesheet_id: number;
date: string; //YYYY-MM-DD
type: ShiftType;
@@ -28,7 +30,7 @@ export class Shift {
is_remote: boolean;
constructor() {
- this.shift_id = -1;
+ this.id = -1;
this.timesheet_id = -1;
this.date = '';
this.type = 'REGULAR';
@@ -40,7 +42,21 @@ export class Shift {
}
}
-export interface NewShift {
- timesheet_id: number;
- shifts: Shift[];
+export interface ShiftAPIResponse {
+ ok: boolean;
+ data?: {
+ shift: Shift;
+ overtime: unknown;
+ }
+ error?: ShiftAPIError;
+}
+
+export interface ShiftAPIError {
+ error_code: ShiftErrorCode;
+ conflicts:
+ {
+ date: string;
+ start_time: string;
+ end_time: string;
+ }
}
\ No newline at end of file
diff --git a/src/modules/timesheets/services/shift-service.ts b/src/modules/timesheets/services/shift-service.ts
index 0880c56..f7eac5b 100644
--- a/src/modules/timesheets/services/shift-service.ts
+++ b/src/modules/timesheets/services/shift-service.ts
@@ -1,6 +1,5 @@
-/* eslint-disable */
import { api } from "src/boot/axios";
-import type { Shift } from "src/modules/timesheets/models/shift.models";
+import type { Shift, ShiftAPIResponse } from "src/modules/timesheets/models/shift.models";
export const ShiftService = {
deleteShiftById: async (shift_id: number) => {
@@ -8,17 +7,15 @@ export const ShiftService = {
return response.data;
},
- createNewShifts: async (new_shifts: Shift[]) => {
- // const response = await api.post(`/shift/`, { dtos: new_shifts });
- // return response;
- console.log('create shift payload: ', new_shifts);
- return {status: 200};
+ createNewShifts: async (new_shifts: Shift[]):Promise => {
+ const response = await api.post(`/shift/create`, new_shifts);
+ return response.data;
},
updateShifts: async (existing_shifts: Shift[]) => {
- // const response = await api.patch(`/shift/`, { dtos: existing_shifts });
- // return response;
- console.log('update shift payload: ', existing_shifts);
- return {status: 200};
+ console.log('sent shifts: ', existing_shifts)
+ const response = await api.patch(`/shift/update`, existing_shifts);
+ console.log('API response to existing shifts: ', response.data);
+ return response;
}
};
\ No newline at end of file
diff --git a/src/modules/timesheets/services/timesheet-service.ts b/src/modules/timesheets/services/timesheet-service.ts
index c12caf0..422c726 100644
--- a/src/modules/timesheets/services/timesheet-service.ts
+++ b/src/modules/timesheets/services/timesheet-service.ts
@@ -19,8 +19,8 @@ export const timesheetService = {
return response.data;
},
- getTimesheetsByPayPeriodAndEmployeeEmail: async (employee_email: string, year: number, period_number: number): Promise => {
- const response = await api.get('timesheets', { params: { employee_email, year, period_number } });
+ getTimesheetsByPayPeriod: async (year: number, period_number: number): Promise => {
+ const response = await api.get('timesheets', { params: { year, period_number } });
return response.data;
},
};
\ No newline at end of file
diff --git a/src/pages/dashboard-page.vue b/src/pages/dashboard-page.vue
index b707787..0c502fe 100644
--- a/src/pages/dashboard-page.vue
+++ b/src/pages/dashboard-page.vue
@@ -2,7 +2,16 @@
setup
lang="ts"
>
-import { Notify } from 'quasar';
+ import { ref } from 'vue';
+ import { Notify } from 'quasar';
+
+ const LOREM_IPSUM = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et \
+ dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip \
+ ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu \
+ fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia \
+ deserunt mollit anim id est laborum."
+
+ const slide = ref('welcome');
const clickNotify = () => {
Notify.create({
@@ -10,38 +19,84 @@ import { Notify } from 'quasar';
color: 'info'
})
}
-
-
-
-
- Welcome to App Targo, !
-
-
-
-
- Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et
- dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip
- ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu
- fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia
- deserunt mollit anim id est laborum.
-
-
-
-
-
+
+
+
+
+
+
+ Welcome to App Targo!
+
+
+
+ {{ LOREM_IPSUM }}
+
+
+
+
+
+ {{ LOREM_IPSUM }}
+
+
+
+
+
+ {{ LOREM_IPSUM }}
+
+
+
+
+
+ {{ LOREM_IPSUM }}
+
+
+
+
-
+
\ No newline at end of file
diff --git a/src/stores/shift-store.ts b/src/stores/shift-store.ts
index 8f2950c..1b2e699 100644
--- a/src/stores/shift-store.ts
+++ b/src/stores/shift-store.ts
@@ -1,12 +1,13 @@
import { ref } from "vue";
+import { Notify } from "quasar";
import { defineStore } from "pinia";
import { ShiftService } from "src/modules/timesheets/services/shift-service";
import { useTimesheetStore } from "src/stores/timesheet-store";
-import { Notify } from "quasar";
+import type { ShiftAPIError } from "src/modules/timesheets/models/shift.models";
export const useShiftStore = defineStore('shift_store', () => {
const timesheet_store = useTimesheetStore();
- const shift_error = ref();
+ const shift_errors = ref([]);
const deleteShiftById = async (shift_id: number): Promise => {
try {
@@ -19,20 +20,25 @@ export const useShiftStore = defineStore('shift_store', () => {
};
const createNewShifts = async (): Promise => {
- if (timesheet_store.timesheets === undefined) return false;
+ if (timesheet_store.timesheets === undefined) {
+ console.log('no changes in existing shifts detected');
+ return false;
+ }
try {
- const new_shifts = timesheet_store.timesheets.flatMap(week => week.days).flatMap(day => day.shifts).filter(shift => shift.shift_id < 0);
+ const new_shifts = timesheet_store.timesheets.flatMap(week => week.days).flatMap(day => day.shifts).filter(shift => shift.id < 0);
if (new_shifts?.length > 0) {
const response = await ShiftService.createNewShifts(new_shifts);
- if (response.status <= 200) {
+ if (response.every(res => res.ok)) {
return true;
}
+ else {
+ response.forEach(res => {
+ shift_errors.value.push(res.error!);
+ });
+ }
}
-
- console.log('No new shifts to save');
- Notify.create('no new shifts to save')
return false;
} catch (error) {
console.error('Error creating new shifts: ', error);
@@ -44,11 +50,12 @@ export const useShiftStore = defineStore('shift_store', () => {
if (timesheet_store.timesheets === undefined) return false;
try {
- const existing_shifts = timesheet_store.timesheets.flatMap(week => week.days).flatMap(day => day.shifts).filter(shift => shift.shift_id > 0);
+ const existing_shifts = timesheet_store.timesheets.flatMap(week => week.days).flatMap(day => day.shifts).filter(shift => shift.id > 0);
if (existing_shifts?.length > 0) {
const response = await ShiftService.updateShifts(existing_shifts);
- if (response.status <= 200) {
+
+ if (response.status < 400) {
return true;
}
}
@@ -63,7 +70,7 @@ export const useShiftStore = defineStore('shift_store', () => {
}
return {
- shift_error,
+ shift_errors,
deleteShiftById,
createNewShifts,
updateShifts,
diff --git a/src/stores/timesheet-store.ts b/src/stores/timesheet-store.ts
index 73c5b82..801bb7b 100644
--- a/src/stores/timesheet-store.ts
+++ b/src/stores/timesheet-store.ts
@@ -7,6 +7,7 @@ import type { TimesheetOverview } from "src/modules/timesheet-approval/models/ti
import type { PayPeriod } from 'src/modules/shared/models/pay-period.models';
import type { Timesheet } from 'src/modules/timesheets/models/timesheet.models';
import type { TimesheetApprovalCSVReportFilters } from 'src/modules/timesheet-approval/models/timesheet-approval-csv-report.models';
+import { unwrapAndClone } from 'src/utils/unwrap-and-clone';
export const useTimesheetStore = defineStore('timesheet', () => {
@@ -15,7 +16,8 @@ export const useTimesheetStore = defineStore('timesheet', () => {
const pay_period = ref();
const pay_period_overviews = ref([]);
const current_pay_period_overview = ref();
- const timesheets = ref();
+ const timesheets = ref([]);
+ const initial_timesheets = ref([]);
const pay_period_report = ref();
const getPayPeriodByDateOrYearAndNumber = async (date_or_year: string | number, period_number?: number): Promise => {
@@ -58,13 +60,17 @@ export const useTimesheetStore = defineStore('timesheet', () => {
}
};
- const getTimesheetsByEmployeeEmail = async (employee_email: string) => {
+ const getTimesheetsByEmployeeEmail = async (employee_email?: string) => {
is_loading.value = true;
if (pay_period.value === undefined) return;
try {
- const response = await timesheetService.getTimesheetsByPayPeriodAndEmployeeEmail(employee_email, pay_period.value.pay_year, pay_period.value.pay_period_no);
+ if (employee_email) {
+ console.log('email: ', employee_email);
+ }
+ const response = await timesheetService.getTimesheetsByPayPeriod(pay_period.value.pay_year, pay_period.value.pay_period_no);
timesheets.value = response.timesheets;
+ initial_timesheets.value = unwrapAndClone(timesheets.value);
is_loading.value = false;
} catch (error) {
console.error('There was an error retrieving timesheet details for this employee: ', error);
@@ -97,6 +103,7 @@ export const useTimesheetStore = defineStore('timesheet', () => {
pay_period_overviews,
current_pay_period_overview,
timesheets,
+ initial_timesheets,
getPayPeriodByDateOrYearAndNumber,
getTimesheetOverviewsByPayPeriod,
getTimesheetsByEmployeeEmail,