fix(approvals): adjust scripts to handle timesheet modifications made through approvals page
This commit is contained in:
parent
388e002dda
commit
b9613889f5
|
|
@ -199,7 +199,7 @@
|
|||
/>
|
||||
|
||||
<q-btn
|
||||
v-else
|
||||
v-else-if="!expense.is_approved && mode === 'normal'"
|
||||
flat
|
||||
dense
|
||||
size="lg"
|
||||
|
|
|
|||
|
|
@ -2,12 +2,15 @@
|
|||
setup
|
||||
lang="ts"
|
||||
>
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { onMounted, ref } from 'vue';
|
||||
import { QSelect, QInput } from 'quasar';
|
||||
import { QSelect, QInput, useQuasar } from 'quasar';
|
||||
import { useUiStore } from 'src/stores/ui-store';
|
||||
import { SHIFT_OPTIONS } from 'src/modules/timesheets/utils/shift.util';
|
||||
import type { Shift } from 'src/modules/timesheets/models/shift.models';
|
||||
|
||||
const q = useQuasar();
|
||||
const { t } = useI18n();
|
||||
const ui_store = useUiStore();
|
||||
|
||||
const COMMENT_LENGTH_MAX = 280;
|
||||
|
|
@ -24,6 +27,24 @@
|
|||
holiday?: boolean | undefined;
|
||||
}>();
|
||||
|
||||
const time_input_props = {
|
||||
dense: true,
|
||||
borderless: shift.value.is_approved && isTimesheetApproved,
|
||||
readonly: shift.value.is_approved && isTimesheetApproved,
|
||||
standout: q.dark.isActive ? 'bg-blue-grey-3' : 'bg-blue-grey-9',
|
||||
labelSlot: true,
|
||||
lazyRules: true,
|
||||
noErrorIcon: true,
|
||||
hideBottomSpace: true,
|
||||
error: shift.value.has_error,
|
||||
errorMessage: errorMessage ? t(errorMessage) : (error_message.value ? t(error_message.value) : undefined),
|
||||
labelColor: shift.value.is_approved ? 'white' : (holiday ? 'purple-5' : 'accent'),
|
||||
class: `col rounded-5 bg-dark q-mx-xs ${shift.value.id === -2 ? 'bg-negative' : ''} ${shift.value.is_approved || isTimesheetApproved ? 'cursor-not-allowed inset-shadow' : ''}`,
|
||||
inputClass: `text-weight-medium ${shift.value.id === -2 ? 'text-white ' : ' '} ${shift.value.is_approved ? 'text-white cursor-not-allowed q-px-sm' : ''}`,
|
||||
style: shift.value.is_approved ? (holiday ? 'background-color: #7b1fa2 !important' : 'background-color: #0a7d32 !important;') : '',
|
||||
inputStyle: "font-size: 1.2em;"
|
||||
}
|
||||
|
||||
const emit = defineEmits<{
|
||||
'requestDelete': [void];
|
||||
'onTimeFieldBlur': [void];
|
||||
|
|
@ -37,7 +58,7 @@
|
|||
shift.value.has_error = false;
|
||||
error_message.value = undefined;
|
||||
emit('onTimeFieldBlur');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const onBlurShiftTypeSelect = () => {
|
||||
|
|
@ -141,7 +162,7 @@
|
|||
dense
|
||||
keep-color
|
||||
size="3em"
|
||||
:color="holiday? 'purple-5' : 'accent'"
|
||||
:color="holiday ? 'purple-5' : 'accent'"
|
||||
icon="las la-building"
|
||||
checked-icon="las la-laptop"
|
||||
>
|
||||
|
|
@ -158,13 +179,14 @@
|
|||
</template>
|
||||
|
||||
<template #option="scope">
|
||||
<q-item clickable v-bind="scope.itemProps">
|
||||
<q-item
|
||||
clickable
|
||||
v-bind="scope.itemProps"
|
||||
>
|
||||
<q-item-section avatar>
|
||||
<q-icon
|
||||
:name="scope.opt.icon"
|
||||
/>
|
||||
<q-icon :name="scope.opt.icon" />
|
||||
</q-item-section>
|
||||
|
||||
|
||||
<q-item-section class="text-left">
|
||||
{{ $t(scope.label) }}
|
||||
</q-item-section>
|
||||
|
|
@ -178,23 +200,8 @@
|
|||
<q-input
|
||||
ref="start_time"
|
||||
v-model="shift.start_time"
|
||||
dense
|
||||
:borderless="(shift.is_approved && isTimesheetApproved)"
|
||||
:readonly="(shift.is_approved && isTimesheetApproved)"
|
||||
v-bind="time_input_props"
|
||||
type="time"
|
||||
:standout="$q.dark.isActive ? 'bg-blue-grey-3' : 'bg-blue-grey-9'"
|
||||
label-slot
|
||||
lazy-rules
|
||||
no-error-icon
|
||||
hide-bottom-space
|
||||
:error="shift.has_error"
|
||||
:error-message="errorMessage ? $t(errorMessage) : (error_message ? $t(error_message) : undefined)"
|
||||
:label-color="!shift.is_approved ? (holiday? 'purple-5' : 'accent') : 'white'"
|
||||
class="col rounded-5 bg-dark q-mx-xs"
|
||||
:class="(shift.id === -2 ? 'bg-negative ' : ' ') + (!shift.is_approved && !isTimesheetApproved ? '' : 'cursor-not-allowed inset-shadow')"
|
||||
:input-class="'text-weight-medium ' + (shift.id === -2 ? 'text-white ' : ' ') + (shift.is_approved ? 'text-white cursor-not-allowed q-px-sm' : '')"
|
||||
input-style="font-size: 1.2em;"
|
||||
:style="shift.is_approved ? (holiday ? 'background-color: #7b1fa2 !important' : 'background-color: #0a7d32 !important;') : ''"
|
||||
@blur="onTimeFieldBlur(shift.start_time)"
|
||||
>
|
||||
<template #label>
|
||||
|
|
@ -210,22 +217,8 @@
|
|||
<q-input
|
||||
ref="end_time"
|
||||
v-model="shift.end_time"
|
||||
:standout="$q.dark.isActive ? 'bg-blue-grey-3' : 'bg-blue-grey-9'"
|
||||
dense
|
||||
:borderless="(shift.is_approved && isTimesheetApproved)"
|
||||
:readonly="(shift.is_approved && isTimesheetApproved)"
|
||||
v-bind="time_input_props"
|
||||
type="time"
|
||||
label-slot
|
||||
no-error-icon
|
||||
hide-bottom-space
|
||||
:error="shift.has_error"
|
||||
:error-message="errorMessage ? $t(errorMessage) : (error_message ? $t(error_message) : undefined)"
|
||||
:label-color="!shift.is_approved ? (holiday? 'purple-5' : 'accent') : 'white'"
|
||||
:input-class="'text-weight-medium ' + (shift.id === -2 ? 'text-white ' : ' ') + (shift.is_approved ? 'text-white cursor-not-allowed q-px-sm' : '')"
|
||||
input-style="font-size: 1.2em;"
|
||||
class="col rounded-5 bg-dark q-mx-xs"
|
||||
:class="(shift.id === -2 ? 'bg-negative ' : ' ') + (shift.is_approved ? 'cursor-not-allowed q-px-xs transparent inset-shadow' : (isTimesheetApproved ? 'inset-shadow' : ''))"
|
||||
:style="shift.is_approved ? (holiday ? 'background-color: #7b1fa2 !important' : 'background-color: #0a7d32 !important;') : ''"
|
||||
@blur="onTimeFieldBlur(shift.end_time)"
|
||||
>
|
||||
<template #label>
|
||||
|
|
@ -247,9 +240,9 @@
|
|||
v-if="!ui_store.is_mobile_mode"
|
||||
push
|
||||
dense
|
||||
:color="shift.is_approved ? 'white' : (holiday? 'purple-5' : 'accent')"
|
||||
:color="shift.is_approved ? 'white' : (holiday ? 'purple-5' : 'accent')"
|
||||
:icon="shift.comment ? 'chat' : 'chat_bubble_outline'"
|
||||
:text-color="shift.is_approved ? (holiday? 'purple-5' : 'accent') : 'white'"
|
||||
:text-color="shift.is_approved ? (holiday ? 'purple-5' : 'accent') : 'white'"
|
||||
class="col"
|
||||
:class="ui_store.is_mobile_mode ? 'q-mt-xs bg-dark' : ''"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -18,13 +18,14 @@
|
|||
const timesheet_store = useTimesheetStore();
|
||||
const shift_error_message = ref<string | undefined>();
|
||||
|
||||
const { day, dense = false, approved = false, holiday = false } = defineProps<{
|
||||
const { day, dense = false, approved = false, holiday = false, employeeEmail } = defineProps<{
|
||||
timesheetId: number;
|
||||
weekDayIndex: number;
|
||||
day: TimesheetDay;
|
||||
dense?: boolean;
|
||||
approved?: boolean;
|
||||
holiday?: boolean;
|
||||
employeeEmail?: string;
|
||||
}>();
|
||||
|
||||
const preset_mouseover = ref(false);
|
||||
|
|
@ -38,7 +39,7 @@
|
|||
shift.id = 0;
|
||||
emit('deleteUnsavedShift');
|
||||
} else {
|
||||
await shift_api.deleteShiftById(shift.id);
|
||||
await shift_api.deleteShiftById(shift.id, employeeEmail);
|
||||
}
|
||||
|
||||
if (day.shifts.length < 2 && shift_error_message.value !== undefined) {
|
||||
|
|
|
|||
|
|
@ -7,9 +7,9 @@ export const useShiftApi = () => {
|
|||
const shift_store = useShiftStore();
|
||||
const auth_store = useAuthStore();
|
||||
|
||||
const deleteShiftById = async (shift_id: number) => {
|
||||
const deleteShiftById = async (shift_id: number, employee_email?: string | undefined) => {
|
||||
timesheet_store.is_loading = true;
|
||||
const success = await shift_store.deleteShiftById(shift_id);
|
||||
const success = await shift_store.deleteShiftById(shift_id, employee_email);
|
||||
|
||||
if (success) {
|
||||
await timesheet_store.getTimesheetsByOptionalEmployeeEmail(auth_store.user?.email ?? '');
|
||||
|
|
|
|||
|
|
@ -3,17 +3,32 @@ import type { BackendResponse } from "src/modules/shared/models/backend-response
|
|||
import type { Shift } from "src/modules/timesheets/models/shift.models";
|
||||
|
||||
export const ShiftService = {
|
||||
deleteShiftById: async (shift_id: number) => {
|
||||
deleteShiftById: async (shift_id: number, employee_email?: string | undefined) => {
|
||||
if (employee_email) {
|
||||
const response = await api.delete(`/shift/${shift_id}/${employee_email}`);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
const response = await api.delete(`/shift/${shift_id}`);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
createNewShifts: async (new_shifts: Shift[]):Promise<BackendResponse<Shift>> => {
|
||||
createNewShifts: async (new_shifts: Shift[], employee_email?: string | undefined):Promise<BackendResponse<Shift>> => {
|
||||
if (employee_email) {
|
||||
const response = await api.post(`/shift/create/${employee_email}`);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
const response = await api.post(`/shift/create`, new_shifts);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
updateShifts: async (existing_shifts: Shift[]):Promise<BackendResponse<Shift>> => {
|
||||
updateShifts: async (existing_shifts: Shift[], employee_email?: string | undefined):Promise<BackendResponse<Shift>> => {
|
||||
if (employee_email) {
|
||||
const response = await api.patch(`/shift/update/${employee_email}`);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
const response = await api.patch(`/shift/update`, existing_shifts);
|
||||
return response.data;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,6 +34,12 @@
|
|||
onUnmounted(() => {
|
||||
timesheet_store.unsubscribeToPayPeriodObservable();
|
||||
})
|
||||
|
||||
const details_dialog_props = {
|
||||
'is-loading': timesheet_store.is_loading,
|
||||
'employee-overview': timesheet_store.current_pay_period_overview,
|
||||
timesheets: timesheet_store.timesheets,
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
|
@ -41,11 +47,7 @@
|
|||
class="bg-secondary"
|
||||
:style-fn="tableStyleFunction"
|
||||
>
|
||||
<DetailsDialog
|
||||
:is-loading="timesheet_store.is_loading"
|
||||
:employee-overview="timesheet_store.current_pay_period_overview"
|
||||
:timesheets="timesheet_store.timesheets"
|
||||
/>
|
||||
<DetailsDialog v-bind="details_dialog_props" />
|
||||
|
||||
<OverviewReport />
|
||||
|
||||
|
|
|
|||
|
|
@ -9,9 +9,9 @@ export const useShiftStore = defineStore('shift_store', () => {
|
|||
const timesheet_store = useTimesheetStore();
|
||||
const shift_errors = ref<string[]>([]);
|
||||
|
||||
const deleteShiftById = async (shift_id: number): Promise<boolean> => {
|
||||
const deleteShiftById = async (shift_id: number, employee_email?: string | undefined): Promise<boolean> => {
|
||||
try {
|
||||
await ShiftService.deleteShiftById(shift_id);
|
||||
await ShiftService.deleteShiftById(shift_id, employee_email);
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.error('DEV ERROR || error while deleting shift: ', error);
|
||||
|
|
@ -19,7 +19,7 @@ export const useShiftStore = defineStore('shift_store', () => {
|
|||
}
|
||||
};
|
||||
|
||||
const createNewShifts = async (): Promise<boolean> => {
|
||||
const createNewShifts = async (employee_email?: string | undefined): Promise<boolean> => {
|
||||
if (timesheet_store.timesheets === undefined) return false;
|
||||
|
||||
try {
|
||||
|
|
@ -27,7 +27,7 @@ export const useShiftStore = defineStore('shift_store', () => {
|
|||
const new_shifts = days.flatMap(day => day.shifts).filter(shift => shift.id < 0);
|
||||
|
||||
if (new_shifts?.length > 0) {
|
||||
const response = await ShiftService.createNewShifts(new_shifts);
|
||||
const response = await ShiftService.createNewShifts(new_shifts, employee_email);
|
||||
if (response.success) {
|
||||
return true;
|
||||
}
|
||||
|
|
@ -40,14 +40,14 @@ export const useShiftStore = defineStore('shift_store', () => {
|
|||
}
|
||||
};
|
||||
|
||||
const updateShifts = async (): Promise<boolean> => {
|
||||
const updateShifts = async (employee_email?: string | undefined): Promise<boolean> => {
|
||||
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.id > 0);
|
||||
|
||||
if (existing_shifts?.length > 0) {
|
||||
const response = await ShiftService.updateShifts(existing_shifts);
|
||||
const response = await ShiftService.updateShifts(existing_shifts, employee_email);
|
||||
|
||||
if (response.success) {
|
||||
return true;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user