feat(schedule-preset): Add update and create functionality to schedule preset with preview
This commit is contained in:
parent
f6e9415369
commit
fd2146567f
|
|
@ -29,11 +29,12 @@ export default defineConfig((ctx) => {
|
|||
// 'fontawesome-v6',
|
||||
// 'eva-icons',
|
||||
// 'themify',
|
||||
// 'line-awesome',
|
||||
'line-awesome',
|
||||
'material-icons',
|
||||
'material-icons-outlined',
|
||||
|
||||
'roboto-font',
|
||||
// 'roboto-font-latin-ext', // this or either 'roboto-font', NEVER both!
|
||||
|
||||
'roboto-font', // optional, you are not bound to it
|
||||
'material-icons', // optional, you are not bound to it
|
||||
],
|
||||
|
||||
// Full list of options: https://v2.quasar.dev/quasar-cli-vite/quasar-config-file#build
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ export default {
|
|||
modify_employee: "Modify employee",
|
||||
access_label: "access",
|
||||
details_label: "details",
|
||||
schedule_label: "schedules",
|
||||
schedule_label: "schedule",
|
||||
schedule_presets: {
|
||||
preset_list_placeholder: "Select a schedule",
|
||||
preset_name_placeholder: "schedule preset name",
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ export default {
|
|||
modify_employee: "Modifier employé",
|
||||
access_label: "accès",
|
||||
details_label: "détails",
|
||||
schedule_label: "horaires",
|
||||
schedule_label: "horaire",
|
||||
schedule_presets: {
|
||||
preset_list_placeholder: "Sélectionner un horaire",
|
||||
preset_name_placeholder: "nom de l'horaire",
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@
|
|||
>
|
||||
<q-item-section avatar>
|
||||
<q-icon
|
||||
name="view_list"
|
||||
name="groups"
|
||||
color="accent"
|
||||
size="lg"
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
import { ref } from 'vue';
|
||||
import { unwrapAndClone } from 'src/utils/unwrap-and-clone';
|
||||
import { useEmployeeStore } from 'src/stores/employee-store';
|
||||
import { employee_access_options, type ModuleAccessPreset, type ModuleAccessName, employee_access_presets } from 'src/modules/employee-list/models/employee-profile.models';
|
||||
import { employee_access_options, type ModuleAccessPreset, type ModuleAccessName, employee_access_presets, getEmployeeAccessOptionIcon } from 'src/modules/employee-list/models/employee-profile.models';
|
||||
|
||||
const employee_store = useEmployeeStore();
|
||||
const preset_preview = ref<ModuleAccessPreset>();
|
||||
|
|
@ -20,6 +20,7 @@
|
|||
employee_store.employee.user_module_access = unwrapAndClone(employee_access_presets[preset]);
|
||||
}
|
||||
|
||||
|
||||
const getPreviewBackgroundColor = (name: ModuleAccessName) => {
|
||||
if (employee_access_presets[preset_preview.value!].includes(name)) {
|
||||
if (!employee_store.employee.user_module_access.includes(name)) return 'bg-info text-white';
|
||||
|
|
@ -141,8 +142,9 @@
|
|||
class="row full-width cursor-pointer flex-center q-pa-sm rounded-5 no-wrap shadow-5"
|
||||
:class="preset_preview !== undefined ? getPreviewBackgroundColor(option.value) : getBackgroundColor(option.value)"
|
||||
@click="toggleInSelected(option.value)"
|
||||
>
|
||||
<span class="text-uppercase text-weight-bold">
|
||||
>
|
||||
<q-icon :name="getEmployeeAccessOptionIcon(option.value)" size="sm" class="q-mr-sm"/>
|
||||
<span class="text-uppercase text-weight-bold non-selectable">
|
||||
{{ $t('employee_management.module_access.' + option.value) }}
|
||||
</span>
|
||||
<q-space />
|
||||
|
|
|
|||
|
|
@ -0,0 +1,59 @@
|
|||
<script
|
||||
setup
|
||||
lang="ts"
|
||||
>
|
||||
import { date } from 'quasar';
|
||||
import { useSchedulePresetsStore } from 'src/stores/schedule-presets.store';
|
||||
|
||||
const schedule_preset_store = useSchedulePresetsStore();
|
||||
|
||||
defineProps<{
|
||||
currentPresetId: number;
|
||||
}>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="row flex-center fit">
|
||||
<div
|
||||
v-if="currentPresetId > 0"
|
||||
class="col column fit flex-center q-pa-md"
|
||||
>
|
||||
<div
|
||||
v-for="weekday in schedule_preset_store.current_schedule_preset.weekdays"
|
||||
:key="weekday.day"
|
||||
class="col row justify-center q-py-xs full-width"
|
||||
>
|
||||
<div class="col-10 row items-center bg-dark q-px-md shadow-10 rounded-10">
|
||||
<span class="col-2 text-weight-bolder text-accent text-uppercase text-overline" style="font-size: 1.3em;">{{
|
||||
$t(`shared.weekday.${weekday.day.toLowerCase()}`) }}</span>
|
||||
<div
|
||||
v-for="shift, index in weekday.shifts.sort((a, b) => date.extractDate(a.start_time, 'HH:mm').getTime() - date.extractDate(b.start_time, 'HH:mm').getTime())"
|
||||
:key="index"
|
||||
class="col q-px-md q-py-xs"
|
||||
>
|
||||
<div class="row flex-center rounded-5" style="border: 1px solid var(--q-accent);">
|
||||
<div class="col bg-accent text-white text-uppercase text-weight-bolder text-center">
|
||||
{{ $t(`shared.shift_type.${shift.type.toLowerCase()}`) }}
|
||||
</div>
|
||||
<div class="col text-center text-bold">{{ shift.start_time }}</div>
|
||||
<q-icon name="las la-chevron-right" color="accent" class="col-auto"></q-icon>
|
||||
<div class="col text-center text-bold">{{ shift.end_time }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-else
|
||||
class="col row justify-center"
|
||||
>
|
||||
<q-icon
|
||||
name="las la-calendar-week"
|
||||
size="20em"
|
||||
color="accent"
|
||||
style="opacity: 0.3;"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -4,19 +4,24 @@
|
|||
>
|
||||
import HorizontalSlideTransition from 'src/modules/shared/components/horizontal-slide-transition.vue';
|
||||
import SchedulePresetsDialog from 'src/modules/employee-list/components/schedule_presets_dialog.vue';
|
||||
import AddModifyDialogSchedulePreview from './add-modify-dialog-schedule-preview.vue';
|
||||
|
||||
import { onMounted, ref } from 'vue';
|
||||
import { useSchedulePresetsStore } from 'src/stores/schedule-presets.store';
|
||||
import { useEmployeeStore } from 'src/stores/employee-store';
|
||||
import { useEmployeeListApi } from '../composables/use-employee-api';
|
||||
|
||||
const schedule_preset_store = useSchedulePresetsStore();
|
||||
const employee_store = useEmployeeStore();
|
||||
const employee_list_api = useEmployeeListApi();
|
||||
|
||||
const preset_options = ref<{ label: string, value: number }[]>([]);
|
||||
const current_preset = ref<{ label: string | undefined, value: number }>({ label: undefined, value: -1 });
|
||||
|
||||
const getPresetOptions = (): { label: string, value: number }[] => {
|
||||
return schedule_preset_store.schedule_presets.map(preset => { return { label: preset.name, value: preset.id } });
|
||||
const options = schedule_preset_store.schedule_presets.map(preset => { return { label: preset.name, value: preset.id } });
|
||||
options.push({ label: '', value: -1 });
|
||||
return options;
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
|
|
@ -35,6 +40,7 @@
|
|||
v-model="current_preset"
|
||||
standout="bg-accent"
|
||||
dense
|
||||
options-dense
|
||||
rounded
|
||||
color="accent"
|
||||
:options="getPresetOptions()"
|
||||
|
|
@ -44,11 +50,16 @@
|
|||
menu-anchor="bottom middle"
|
||||
menu-self="top middle"
|
||||
:menu-offset="[0, 10]"
|
||||
@update:modelValue="option => schedule_preset_store.setCurrentSchedulePreset(option.value)"
|
||||
@update:modelValue="option => employee_list_api.setSchedulePreset(option.value)"
|
||||
>
|
||||
<template #selected>
|
||||
<span class="text-uppercase" :style="current_preset.label === undefined ? 'opacity: 0.5;' : ''">
|
||||
{{ current_preset.label === undefined ? $t('employee_management.schedule_presets.preset_list_placeholder') : current_preset.label }}
|
||||
<span
|
||||
class="text-uppercase text-center text-weight-bold full-width"
|
||||
:style="current_preset.label === undefined ? 'opacity: 0.5;' : ''"
|
||||
>
|
||||
{{ current_preset.label === undefined ?
|
||||
$t('employee_management.schedule_presets.preset_list_placeholder') :
|
||||
current_preset.label }}
|
||||
</span>
|
||||
</template>
|
||||
</q-select>
|
||||
|
|
@ -81,6 +92,8 @@
|
|||
/>
|
||||
</transition>
|
||||
</HorizontalSlideTransition>
|
||||
|
||||
</div>
|
||||
<AddModifyDialogSchedulePreview :current-preset-id="current_preset.value" />
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -55,14 +55,14 @@
|
|||
>
|
||||
<q-tab
|
||||
name="form"
|
||||
icon="badge"
|
||||
icon="las la-id-card"
|
||||
:label="$q.screen.lt.sm ? '' : $t('employee_management.details_label')"
|
||||
class="rounded-25 q-ma-xs"
|
||||
style="border: 2px solid var(--q-accent);"
|
||||
/>
|
||||
<q-tab
|
||||
name="access"
|
||||
icon="key"
|
||||
icon="las la-key"
|
||||
:label="$q.screen.lt.sm ? '' : $t('employee_management.access_label')"
|
||||
class="rounded-25 q-ma-xs"
|
||||
style="border: 2px solid var(--q-accent);"
|
||||
|
|
@ -81,7 +81,7 @@
|
|||
animated
|
||||
:transition-prev="$q.screen.lt.sm ? 'jump-down' : 'jump-left'"
|
||||
:transition-next="$q.screen.lt.sm ? 'jump-up' : 'jump-right'"
|
||||
class="bg-transparent"
|
||||
class="bg-transparent full-height"
|
||||
>
|
||||
<q-tab-panel
|
||||
name="form"
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@
|
|||
<q-btn
|
||||
push
|
||||
color="accent"
|
||||
icon="person_add"
|
||||
icon="las la-user-edit"
|
||||
:label="$t('shared.label.add')"
|
||||
class="text-uppercase"
|
||||
@click.stop="_evt => employee_store.openAddModifyDialog()"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,134 @@
|
|||
<script
|
||||
setup
|
||||
lang="ts"
|
||||
>
|
||||
import { ref } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import type { ShiftOption } from 'src/modules/timesheets/models/shift.models';
|
||||
import type { SchedulePresetShift } from '../models/schedule-presets.models';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
const SHIFT_OPTIONS: ShiftOption[] = [
|
||||
{ label: t('timesheet.shift.types.REGULAR'), value: 'REGULAR', icon: 'wb_sunny', icon_color: 'blue-grey-3' },
|
||||
{ label: t('timesheet.shift.types.EVENING'), value: 'EVENING', icon: 'bedtime', icon_color: 'indigo-8' },
|
||||
{ label: t('timesheet.shift.types.EMERGENCY'), value: 'EMERGENCY', icon: 'ring_volume', icon_color: 'red-8' },
|
||||
{ label: t('timesheet.shift.types.VACATION'), value: 'VACATION', icon: 'beach_access', icon_color: 'yellow-8' },
|
||||
{ label: t('timesheet.shift.types.HOLIDAY'), value: 'HOLIDAY', icon: 'forest', icon_color: 'green-8' },
|
||||
{ label: t('timesheet.shift.types.SICK'), value: 'SICK', icon: 'medication_liquid', icon_color: 'light-blue-6' },
|
||||
];
|
||||
|
||||
const shift = defineModel<SchedulePresetShift>('shift', { required: true });
|
||||
const shift_type_selected = ref(SHIFT_OPTIONS[0]);
|
||||
|
||||
defineEmits<{
|
||||
'click-delete': [void];
|
||||
}>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="row col-auto flex-center">
|
||||
<div class="col q-pa-xs">
|
||||
<q-select
|
||||
ref="select"
|
||||
v-model="shift_type_selected"
|
||||
:standout="$q.dark.isActive ? 'bg-blue-grey-3' : 'bg-blue-grey-9'"
|
||||
dense
|
||||
options-dense
|
||||
hide-dropdown-icon
|
||||
:menu-offset="[0, 10]"
|
||||
menu-anchor="bottom middle"
|
||||
menu-self="top middle"
|
||||
:options="SHIFT_OPTIONS"
|
||||
class="col rounded-5 bg-dark weekday-field"
|
||||
popup-content-class="text-uppercase text-weight-bold text-center rounded-5"
|
||||
popup-content-style="border: 2px solid var(--q-accent)"
|
||||
@update:model-value="option => shift.type = option.value"
|
||||
>
|
||||
<template #selected-item="scope">
|
||||
<div
|
||||
class="row flex-center text-uppercase q-ma-none q-pa-none no-wrap ellipsis full-width"
|
||||
:tabindex="scope.tabindex"
|
||||
>
|
||||
<q-icon
|
||||
:name="scope.opt.icon"
|
||||
:color="scope.opt.icon_color"
|
||||
class="col-auto q-mx-xs"
|
||||
/>
|
||||
<span
|
||||
style="line-height: 0.9em;"
|
||||
class="col-auto ellipsis"
|
||||
>{{ scope.opt.label }}</span>
|
||||
</div>
|
||||
</template>
|
||||
</q-select>
|
||||
</div>
|
||||
|
||||
<div class="col q-px-xs">
|
||||
<q-input
|
||||
v-model="shift.start_time"
|
||||
standout
|
||||
dense
|
||||
hide-bottom-space
|
||||
type="time"
|
||||
class="text-uppercase weekday-field"
|
||||
>
|
||||
<template #prepend>
|
||||
<div
|
||||
class="column text-uppercase text-accent text-weight-bold full-height"
|
||||
style="font-size: 0.5em; transform: translateY(4px);"
|
||||
>
|
||||
{{ $t('shared.misc.in') }} :
|
||||
</div>
|
||||
</template>
|
||||
</q-input>
|
||||
</div>
|
||||
|
||||
<div class="col q-px-xs">
|
||||
<q-input
|
||||
v-model="shift.end_time"
|
||||
standout
|
||||
dense
|
||||
hide-bottom-space
|
||||
type="time"
|
||||
class="text-uppercase weekday-field"
|
||||
>
|
||||
<template #prepend>
|
||||
<div
|
||||
class="column text-uppercase text-accent text-weight-bold full-height"
|
||||
style="font-size: 0.5em; transform: translateY(4px);"
|
||||
>
|
||||
{{ $t('shared.misc.out') }} :
|
||||
</div>
|
||||
</template>
|
||||
</q-input>
|
||||
</div>
|
||||
|
||||
<div class="col-auto q-px-xs">
|
||||
<q-btn
|
||||
dense
|
||||
push
|
||||
color="negative"
|
||||
icon="clear"
|
||||
size="sm"
|
||||
tabindex="-1"
|
||||
@click="$emit('click-delete')"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
:deep(.q-field__native) {
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
.weekday-field :deep(.q-field__control) {
|
||||
height: 25px;
|
||||
min-height: 25px;
|
||||
}
|
||||
|
||||
:deep(.q-field--auto-height.q-field--dense .q-field__native) {
|
||||
min-height: 25px;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -2,18 +2,29 @@
|
|||
setup
|
||||
lang="ts"
|
||||
>
|
||||
import SchedulePresetsDialogRow from './schedule-presets-dialog-row.vue';
|
||||
|
||||
import { useEmployeeListApi } from '../composables/use-employee-api';
|
||||
import { SchedulePresetShift } from '../models/schedule-presets.models';
|
||||
import { useSchedulePresetsStore } from 'src/stores/schedule-presets.store';
|
||||
|
||||
const schedule_preset_store = useSchedulePresetsStore();
|
||||
const employee_list_api = useEmployeeListApi();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<q-dialog v-model="schedule_preset_store.is_manager_open">
|
||||
<q-dialog
|
||||
v-model="schedule_preset_store.is_manager_open"
|
||||
full-width
|
||||
>
|
||||
<div
|
||||
class="column flex-center bg-secondary rounded-10 shadow-24 full-width"
|
||||
style="border: 2px solid var(--q-accent);"
|
||||
class="column flex-center bg-secondary rounded-10 shadow-24"
|
||||
style="border: 2px solid var(--q-accent); width: 50vw !important;"
|
||||
>
|
||||
<div class="row col-auto flex-center bg-primary full-width">
|
||||
<div
|
||||
class="row col-auto flex-center bg-primary full-width"
|
||||
style="border-radius: 8px 8px 0 0;"
|
||||
>
|
||||
<span class="row col-auto text-uppercase text-weight-bold text-white q-py-sm">{{
|
||||
schedule_preset_store.current_schedule_preset.id === -1 ?
|
||||
$t('shared.label.add') :
|
||||
|
|
@ -31,7 +42,15 @@
|
|||
:placeholder="$t('employee_management.schedule_presets.preset_name_placeholder')"
|
||||
class="text-uppercase"
|
||||
input-class="text-weight-bold text-center"
|
||||
/>
|
||||
>
|
||||
<template #before>
|
||||
<q-icon
|
||||
name="edit"
|
||||
color="accent"
|
||||
class="q-ml-sm"
|
||||
/>
|
||||
</template>
|
||||
</q-input>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -39,35 +58,34 @@
|
|||
<div
|
||||
v-for="weekday of schedule_preset_store.current_schedule_preset.weekdays"
|
||||
:key="weekday.day"
|
||||
class="row col-auto items-center q-my-xs full-width shadow-2 q-px-sm bg-dark rounded-10"
|
||||
class="row col-auto items-center q-my-xs shadow-2 bg-dark rounded-10 ellipsis"
|
||||
style="min-height: 50px;"
|
||||
>
|
||||
<span class="col-2 text-uppercase text-weight-bold ellipsis">{{
|
||||
<span class="col-2 text-uppercase text-weight-bold q-ml-sm ellipsis">{{
|
||||
$t(`shared.weekday.${weekday.day.toLowerCase()}`) }}
|
||||
</span>
|
||||
|
||||
<div class="col column">
|
||||
<div
|
||||
v-for="shift in weekday.shifts"
|
||||
:key="shift.week_day"
|
||||
class="row col-auto"
|
||||
v-for="_shift, index in weekday.shifts"
|
||||
:key="index"
|
||||
>
|
||||
<q-input
|
||||
v-model="shift.end_time"
|
||||
standout
|
||||
dense
|
||||
hide-bottom-space
|
||||
class="text-uppercase weekday-field"
|
||||
input-class="text-weight-bold"
|
||||
>
|
||||
<template #prepend>
|
||||
<div class="column text-uppercase text-accent text-weight-bold full-height" style="font-size: 0.5em; transform: translateY(4px);">
|
||||
{{ $t('shared.misc.out') }}
|
||||
</div>
|
||||
</template>
|
||||
</q-input>
|
||||
<SchedulePresetsDialogRow
|
||||
v-model:shift="weekday.shifts[index]!"
|
||||
@click-delete="weekday.shifts.splice(index, 1)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-auto self-stretch">
|
||||
<q-btn
|
||||
square
|
||||
icon="more_time"
|
||||
color="accent"
|
||||
class="full-height q-ma-none q-px-sm"
|
||||
tabindex="-1"
|
||||
@click="weekday.shifts.push(new SchedulePresetShift(weekday.day))"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -79,21 +97,12 @@
|
|||
push
|
||||
dense
|
||||
:color="schedule_preset_store.current_schedule_preset.name === '' ? 'grey-7' : 'accent'"
|
||||
icon="save"
|
||||
label="save"
|
||||
class="col-3 q-px-sm q-mb-md"
|
||||
icon="download"
|
||||
:label="$t('shared.label.save')"
|
||||
class="col-auto q-px-md q-mb-sm"
|
||||
@click="employee_list_api.saveSchedulePreset"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</q-dialog>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
:deep(.q-field__native) {
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
.weekday-field :deep(.q-field__control) {
|
||||
height: 25px;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -1,25 +1,46 @@
|
|||
import { useEmployeeStore } from "src/stores/employee-store";
|
||||
import { useSchedulePresetsStore } from "src/stores/schedule-presets.store";
|
||||
import { SchedulePreset } from "../models/schedule-presets.models";
|
||||
|
||||
export const useEmployeeListApi = () => {
|
||||
const employee_list_store = useEmployeeStore();
|
||||
const employee_store = useEmployeeStore();
|
||||
const schedule_preset_store = useSchedulePresetsStore();
|
||||
|
||||
const getEmployeeList = async (): Promise<void> => {
|
||||
employee_list_store.is_loading = true;
|
||||
employee_store.is_loading = true;
|
||||
|
||||
const success = await employee_list_store.getEmployeeList();
|
||||
const success = await employee_store.getEmployeeList();
|
||||
if (success) await schedule_preset_store.findSchedulePresetList();
|
||||
|
||||
employee_list_store.is_loading = false;
|
||||
employee_store.is_loading = false;
|
||||
};
|
||||
|
||||
const getEmployeeDetails = (email: string): Promise<void> => {
|
||||
return employee_list_store.getEmployeeDetails(email);
|
||||
return employee_store.getEmployeeDetails(email);
|
||||
}
|
||||
|
||||
const setSchedulePreset = (preset_id: number) => {
|
||||
schedule_preset_store.setCurrentSchedulePreset(preset_id);
|
||||
employee_store.employee.preset_id = preset_id < 0 ? null : preset_id;
|
||||
}
|
||||
|
||||
const saveSchedulePreset = async() => {
|
||||
const preset = schedule_preset_store.current_schedule_preset;
|
||||
const preset_shifts = preset.weekdays.flatMap(weekday => weekday.shifts);
|
||||
const backend_preset = new SchedulePreset(preset.id, preset.name, preset.is_default, preset_shifts);
|
||||
|
||||
const success = await schedule_preset_store.updateSchedulePreset(backend_preset);
|
||||
|
||||
if (success) {
|
||||
schedule_preset_store.is_manager_open = false;
|
||||
await schedule_preset_store.findSchedulePresetList();
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
getEmployeeList,
|
||||
getEmployeeDetails,
|
||||
setSchedulePreset,
|
||||
saveSchedulePreset,
|
||||
};
|
||||
};
|
||||
|
|
@ -19,7 +19,7 @@ export class EmployeeProfile {
|
|||
birth_date: string;
|
||||
is_supervisor: boolean;
|
||||
user_module_access: ModuleAccessName[];
|
||||
preset_id?: number;
|
||||
preset_id?: number | null;
|
||||
|
||||
constructor() {
|
||||
this.first_name = '';
|
||||
|
|
@ -115,4 +115,15 @@ export const employee_access_presets: Record<ModuleAccessPreset, ModuleAccessNam
|
|||
'supervisor' : ['dashboard', 'employee_list', 'personal_profile', 'timesheets', 'timesheets_approval'],
|
||||
'employee' : ['dashboard', 'timesheets', 'personal_profile', 'employee_list'],
|
||||
'none' : [],
|
||||
}
|
||||
|
||||
export const getEmployeeAccessOptionIcon = (module: ModuleAccessName): string => {
|
||||
switch (module) {
|
||||
case 'dashboard': return 'home';
|
||||
case 'employee_list' : return 'groups';
|
||||
case 'employee_management': return 'las la-user-edit';
|
||||
case 'personal_profile': return 'las la-id-card';
|
||||
case 'timesheets': return 'punch_clock';
|
||||
case 'timesheets_approval': return 'event_available';
|
||||
}
|
||||
}
|
||||
|
|
@ -1,3 +1,5 @@
|
|||
import type { ShiftType } from "src/modules/timesheets/models/shift.models";
|
||||
|
||||
export type Weekday = 'SUN' | 'MON' | 'TUE' | 'WED' | 'THU' | 'FRI' | 'SAT';
|
||||
|
||||
export const WEEKDAYS: Weekday[] = ['SUN', 'MON', 'TUE', 'WED', 'THU', 'FRI', 'SAT']
|
||||
|
|
@ -8,18 +10,18 @@ export class SchedulePreset {
|
|||
is_default: boolean;
|
||||
shifts: SchedulePresetShift[];
|
||||
|
||||
constructor() {
|
||||
this.id = -1;
|
||||
this.name = 'default';
|
||||
this.is_default = true;
|
||||
this.shifts = [];
|
||||
constructor(id?: number, name?: string, is_default?: boolean, shifts?: SchedulePresetShift[]) {
|
||||
this.id = id ?? -1;
|
||||
this.name = name ?? 'default';
|
||||
this.is_default = is_default ?? false;
|
||||
this.shifts = shifts ?? [];
|
||||
}
|
||||
}
|
||||
|
||||
class SchedulePresetShift {
|
||||
export class SchedulePresetShift {
|
||||
preset_id: number;
|
||||
week_day: Weekday;
|
||||
type: string;
|
||||
type: ShiftType;
|
||||
start_time: string;
|
||||
end_time: string;
|
||||
is_remote: boolean;
|
||||
|
|
@ -27,7 +29,7 @@ class SchedulePresetShift {
|
|||
constructor(weekday: Weekday) {
|
||||
this.preset_id = -1;
|
||||
this.week_day = weekday;
|
||||
this.type = '';
|
||||
this.type = 'REGULAR';
|
||||
this.start_time = '00:00';
|
||||
this.end_time = '00:00';
|
||||
this.is_remote = false;
|
||||
|
|
|
|||
|
|
@ -3,13 +3,13 @@ import type { SchedulePreset } from "src/modules/employee-list/models/schedule-p
|
|||
import type { BackendResponse } from "src/modules/shared/models/backend-response.models";
|
||||
|
||||
export const SchedulePresetsService = {
|
||||
createSchedulePresets: async (new_schedule: SchedulePreset) => {
|
||||
const response = await api.post(`/schedule-presets/create/`, new_schedule);
|
||||
createSchedulePresets: async (preset: SchedulePreset) => {
|
||||
const response = await api.post(`/schedule-presets/create/`, preset);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
updateSchedulePresets: async (preset_id: number, dto: Partial<SchedulePreset>) => {
|
||||
const response = await api.patch(`/schedule-presets/update/${preset_id}`, dto);
|
||||
updateSchedulePresets: async (preset: SchedulePreset): Promise<BackendResponse<boolean>> => {
|
||||
const response = await api.patch(`/schedule-presets/update`, preset);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
const shift_rules = useShiftRules(t('timesheet.errors.SHIFT_TIME_REQUIRED'),);
|
||||
|
||||
const COMMENT_LENGTH_MAX = 280;
|
||||
|
||||
const SHIFT_OPTIONS: ShiftOption[] = [
|
||||
{ label: t('timesheet.shift.types.REGULAR'), value: 'REGULAR', icon: 'wb_sunny', icon_color: 'blue-grey-3' },
|
||||
{ label: t('timesheet.shift.types.EVENING'), value: 'EVENING', icon: 'bedtime', icon_color: 'indigo-8' },
|
||||
|
|
@ -24,6 +25,7 @@
|
|||
{ label: t('timesheet.shift.types.HOLIDAY'), value: 'HOLIDAY', icon: 'forest', icon_color: 'green-8' },
|
||||
{ label: t('timesheet.shift.types.SICK'), value: 'SICK', icon: 'medication_liquid', icon_color: 'light-blue-6' },
|
||||
];
|
||||
|
||||
const shift = defineModel<Shift>('shift', { required: true });
|
||||
const shift_type_selected = ref(SHIFT_OPTIONS.find(option => option.value == shift.value.type));
|
||||
const select_ref = useTemplateRef<QSelect>('select');
|
||||
|
|
|
|||
|
|
@ -11,6 +11,10 @@ export const useSchedulePresetsStore = defineStore('schedule_presets_store', ()
|
|||
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)!)
|
||||
};
|
||||
|
||||
|
|
@ -34,9 +38,10 @@ export const useSchedulePresetsStore = defineStore('schedule_presets_store', ()
|
|||
}
|
||||
};
|
||||
|
||||
const updateSchedulePreset = async (): Promise<boolean> => {
|
||||
const updateSchedulePreset = async (preset: SchedulePreset): Promise<boolean> => {
|
||||
try {
|
||||
return true;
|
||||
const response = await SchedulePresetsService.updateSchedulePresets(preset);
|
||||
return response.success;
|
||||
} catch (error) {
|
||||
console.error('DEV ERROR || error while updating schedule preset: ', error);
|
||||
return false;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user