feat(schedule-preset): can now add new presets and assign them to employees.

Also fixed issue with with backend not treating first_work_day properly when creating new employee. Also did some optimizing for the employee list table with consistent sorting and better list mode.
This commit is contained in:
Nic D. 2025-12-11 16:59:35 -05:00
parent 3579931899
commit a2103a306b
6 changed files with 22 additions and 21 deletions

View File

@ -28,6 +28,7 @@ import { useEmployeeListApi } from '../composables/use-employee-api';
preset_options.value = getPresetOptions();
const current_option = preset_options.value.find(option => option.value === employee_store.employee.preset_id);
current_preset.value = current_option ?? { label: undefined, value: -1 };
schedule_preset_store.setCurrentSchedulePreset(current_preset.value.value);
});
</script>

View File

@ -15,7 +15,7 @@
const employee_store = useEmployeeStore();
const timesheet_store = useTimesheetStore();
const ui_store = useUiStore();
const visible_columns = ref<(keyof EmployeeProfile)[]>(['first_name', 'email', 'company_name', 'supervisor_full_name', 'company_name', 'job_title', 'last_work_day']);
const visible_columns = ref<(keyof EmployeeProfile)[]>(['first_name', 'email', 'job_title', 'last_work_day']);
const table_grid_container = ref<HTMLElement | null>(null);
@ -72,12 +72,12 @@
:columns="employee_list_columns"
row-key="email"
:rows-per-page-options="[0]"
:pagination="{ sortBy: 'last_work_day', descending: true, }"
:pagination="{ sortBy: 'first_name' }"
:filter="filters"
:filter-method="filterEmployeeRows"
class="bg-transparent no-shadow sticky-header-table"
:style="$q.screen.lt.md ? '' : 'width: 80vw;'"
:table-class="$q.dark.isActive ? 'q-py-none q-mx-md rounded-10 bg-dark shadow-10' : 'q-py-none q-mx-md rounded-10 bg-white shadow-10'"
:table-class="$q.dark.isActive ? 'q-py-none q-mx-md rounded-10 bg-dark shadow-10 hide-scrollbar' : 'q-py-none q-mx-md rounded-10 bg-white shadow-10 hide-scrollbar'"
color="accent"
table-header-class="text-accent text-uppercase"
card-container-class="justify-center"
@ -183,15 +183,15 @@
>
<transition
appear
enter-active-class="animated fadeInUp fast"
leave-active-class="animated fadeOutDown fast"
enter-active-class="animated fadeInUp slow"
leave-active-class="animated fadeOutDown faster"
mode="out-in"
>
<div
:key="scope.rowIndex + (timesheet_store.pay_period?.pay_period_no ?? 0)"
class="rounded-5 cursor-pointer"
style="font-size: 1.2em;"
:style="`animation-delay: ${scope.rowIndex / 30}s; ` + (scope.row.last_work_day === null ? '' : 'opacity: 0.5;')"
:style="`animation-delay: ${scope.pageIndex + scope.rowIndex * 5}ms; ` + (scope.row.last_work_day === null ? '' : 'opacity: 0.5;')"
>
<div v-if="scope.col.name === 'first_name'">
<span

View File

@ -34,7 +34,7 @@ export class EmployeeProfile {
this.residence = '';
this.birth_date = '';
this.is_supervisor = false;
this.external_payroll_id = -1;
this.external_payroll_id = 999;
this.user_module_access = ['dashboard',];
}
}
@ -85,7 +85,6 @@ export const employee_list_columns: QTableColumn<EmployeeProfile>[] = [
label: 'employee_list.table.role',
field: 'job_title',
align: 'left',
sortable: true,
},
{
name: 'last_work_day',

View File

@ -19,7 +19,7 @@ export const EmployeeListService = {
return response.data;
},
createNewEmployee: async (profile: Omit<EmployeeProfile, 'last_work_day' | 'birth_date' | 'external_payroll_id'>): Promise<BackendResponse<EmployeeProfile>> => {
createNewEmployee: async (profile: Omit<EmployeeProfile, 'last_work_day' | 'birth_date'>): Promise<BackendResponse<EmployeeProfile>> => {
const response = await api.post('employees/create', profile);
return response.data;
},

View File

@ -13,11 +13,11 @@ export const useEmployeeStore = defineStore('employee', () => {
const is_loading = ref(false);
const openAddModifyDialog = async (employee_email?: string) => {
is_add_modify_dialog_open.value = true;
if (employee_email === undefined) {
management_mode.value = 'add_employee'
employee.value = new EmployeeProfile();
is_add_modify_dialog_open.value = true;
return;
}
@ -25,6 +25,7 @@ export const useEmployeeStore = defineStore('employee', () => {
management_mode.value = 'modify_employee';
await getEmployeeDetails(employee_email);
is_loading.value = false;
is_add_modify_dialog_open.value = true;
}
const closeAddModifyDialog = () => {
@ -68,7 +69,7 @@ export const useEmployeeStore = defineStore('employee', () => {
let response;
if (management_mode.value === 'add_employee') {
const { birth_date, external_payroll_id, last_work_day, ...create_payload} = profile;
const { birth_date, last_work_day, ...create_payload} = profile;
response = await EmployeeListService.createNewEmployee(create_payload);
} else {

View File

@ -10,14 +10,6 @@ export const useSchedulePresetsStore = defineStore('schedule_presets_store', ()
const current_schedule_preset = ref<SchedulePresetFrontend>(new SchedulePresetFrontend);
const is_manager_open = ref(false);
const setCurrentSchedulePreset = (preset_id: number) => {
if (preset_id === -1) {
current_schedule_preset.value = new SchedulePresetFrontend;
return;
}
current_schedule_preset.value = new SchedulePresetFrontend(schedule_presets.value.find(preset => preset.id === preset_id)!)
};
const openSchedulePresetManager = (preset_id: number) => {
if (preset_id === -1) {
current_schedule_preset.value = new SchedulePresetFrontend;
@ -28,6 +20,14 @@ export const useSchedulePresetsStore = defineStore('schedule_presets_store', ()
is_manager_open.value = true;
};
const setCurrentSchedulePreset = (preset_id: number) => {
if (preset_id === -1) {
current_schedule_preset.value = new SchedulePresetFrontend;
return;
}
current_schedule_preset.value = new SchedulePresetFrontend(schedule_presets.value.find(preset => preset.id === preset_id)!)
};
const createSchedulePreset = async (preset: SchedulePreset): Promise<boolean> => {
try {
const response = await SchedulePresetsService.createSchedulePresets(preset);