fix(presets): fix issue with shifts in preset editing getting sorted reactively, due to shifts being unsorted from backend.
Backend now sorts shifts before sending to front.
This commit is contained in:
parent
a2103a306b
commit
34f1ce5762
|
|
@ -21,9 +21,13 @@ export default {
|
|||
access_label: "access",
|
||||
details_label: "details",
|
||||
schedule_label: "schedule",
|
||||
enter_delete_input: "type 'DELETE' to remove",
|
||||
schedule_presets: {
|
||||
preset_list_placeholder: "Select a schedule",
|
||||
preset_name_placeholder: "schedule preset name",
|
||||
delete_warning: "",
|
||||
delete_warning_employee_1: "This schedule is used by",
|
||||
delete_warning_employee_2: "Deleting this preset will not affect previous timesheets, but they will no longer be able to apply this preset to their timesheets going forward.",
|
||||
},
|
||||
module_access: {
|
||||
dashboard: "Dashboard",
|
||||
|
|
|
|||
|
|
@ -21,9 +21,13 @@ export default {
|
|||
access_label: "accès",
|
||||
details_label: "détails",
|
||||
schedule_label: "horaire",
|
||||
enter_delete_input: "tappez 'SUPPRIMER' pour confirmer",
|
||||
schedule_presets: {
|
||||
preset_list_placeholder: "Sélectionner un horaire",
|
||||
preset_name_placeholder: "nom de l'horaire",
|
||||
delete_warning: "Êtes-vous certain de vouloir supprimer cet horaire?",
|
||||
delete_warning_employee_1: "Cet horaire est présentement utilisé par",
|
||||
delete_warning_employee_2: "La suppression n'affectera pas leurs feuilles de temps antérieures, mais ils ne pourront plus appliquer cet horaire à leurs feuilles de temps à partir de maintenant.",
|
||||
},
|
||||
module_access: {
|
||||
dashboard: "Accueil",
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
setup
|
||||
lang="ts"
|
||||
>
|
||||
import { date } from 'quasar';
|
||||
// import { date } from 'quasar';
|
||||
import { useSchedulePresetsStore } from 'src/stores/schedule-presets.store';
|
||||
|
||||
const schedule_preset_store = useSchedulePresetsStore();
|
||||
|
|
@ -27,7 +27,7 @@ import { useSchedulePresetsStore } from 'src/stores/schedule-presets.store';
|
|||
<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())"
|
||||
v-for="shift, index in weekday.shifts"
|
||||
:key="index"
|
||||
class="col q-px-md q-py-xs"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -3,13 +3,14 @@
|
|||
lang="ts"
|
||||
>
|
||||
import HorizontalSlideTransition from 'src/modules/shared/components/horizontal-slide-transition.vue';
|
||||
import SchedulePresetsDialog from 'src/modules/employee-list/components/schedule_presets_dialog.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 { onMounted, ref, watch } from 'vue';
|
||||
import { useSchedulePresetsStore } from 'src/stores/schedule-presets.store';
|
||||
import { useEmployeeStore } from 'src/stores/employee-store';
|
||||
import { useEmployeeListApi } from '../composables/use-employee-api';
|
||||
import { useEmployeeListApi } from '../composables/use-employee-api';
|
||||
import type { PresetManagerMode } from 'src/modules/employee-list/models/schedule-presets.models';
|
||||
|
||||
const schedule_preset_store = useSchedulePresetsStore();
|
||||
const employee_store = useEmployeeStore();
|
||||
|
|
@ -17,6 +18,7 @@ import { useEmployeeListApi } from '../composables/use-employee-api';
|
|||
|
||||
const preset_options = ref<{ label: string, value: number }[]>([]);
|
||||
const current_preset = ref<{ label: string | undefined, value: number }>({ label: undefined, value: -1 });
|
||||
const manager_watcher = ref(schedule_preset_store.is_manager_open);
|
||||
|
||||
const getPresetOptions = (): { label: string, value: number }[] => {
|
||||
const options = schedule_preset_store.schedule_presets.map(preset => { return { label: preset.name, value: preset.id } });
|
||||
|
|
@ -24,16 +26,31 @@ import { useEmployeeListApi } from '../composables/use-employee-api';
|
|||
return options;
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
const onClickSchedulePresetManager = (mode: PresetManagerMode, preset_id?: number) => {
|
||||
schedule_preset_store.schedule_preset_dialog_mode = mode;
|
||||
console.log('preset id: ', preset_id);
|
||||
schedule_preset_store.openSchedulePresetManager(preset_id ?? current_preset.value.value);
|
||||
}
|
||||
|
||||
const loadSelectedPresetOption = () => {
|
||||
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);
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
loadSelectedPresetOption();
|
||||
});
|
||||
|
||||
watch(manager_watcher, loadSelectedPresetOption)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div :key="schedule_preset_store.is_manager_open === false ? '0' : '1'" class="column full-width flex-center items-start">
|
||||
<div
|
||||
:key="schedule_preset_store.is_manager_open === false ? '0' : '1'"
|
||||
class="column full-width flex-center items-start"
|
||||
>
|
||||
<SchedulePresetsDialog />
|
||||
|
||||
<div class="col row justify-center full-width no-wrap">
|
||||
|
|
@ -72,26 +89,31 @@ import { useEmployeeListApi } from '../composables/use-employee-api';
|
|||
icon="add"
|
||||
color="accent"
|
||||
class="col-auto q-px-sm q-ml-sm"
|
||||
@click="schedule_preset_store.openSchedulePresetManager(-1)"
|
||||
@click="onClickSchedulePresetManager('create', -1)"
|
||||
/>
|
||||
|
||||
<HorizontalSlideTransition :show="current_preset !== undefined && current_preset?.value !== -1">
|
||||
<transition
|
||||
enter-active-class="animated zoomIn"
|
||||
leave-active-class="animated zoomOut"
|
||||
mode="out-in"
|
||||
>
|
||||
<div class="col-auto row no-wrap full-height">
|
||||
<q-btn
|
||||
v-if="current_preset !== undefined && current_preset?.value !== -1"
|
||||
push
|
||||
dense
|
||||
rounded
|
||||
icon="edit"
|
||||
color="accent"
|
||||
class="col-auto q-px-sm q-ml-sm full-height"
|
||||
@click="schedule_preset_store.openSchedulePresetManager(current_preset.value)"
|
||||
class="col-auto q-px-sm q-mx-sm full-height"
|
||||
@click="onClickSchedulePresetManager('update')"
|
||||
/>
|
||||
</transition>
|
||||
|
||||
<q-btn
|
||||
flat
|
||||
dense
|
||||
rounded
|
||||
icon="clear"
|
||||
color="negative"
|
||||
class="col-auto q-px-sm full-height"
|
||||
@click="onClickSchedulePresetManager('delete')"
|
||||
/>
|
||||
</div>
|
||||
</HorizontalSlideTransition>
|
||||
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,75 @@
|
|||
<script
|
||||
setup
|
||||
lang="ts"
|
||||
>
|
||||
import { computed, onMounted, ref } from 'vue';
|
||||
import { useEmployeeStore } from 'src/stores/employee-store';
|
||||
import { useEmployeeListApi } from 'src/modules/employee-list/composables/use-employee-api';
|
||||
|
||||
const employee_store = useEmployeeStore();
|
||||
const employee_list_api = useEmployeeListApi();
|
||||
|
||||
const { presetId } = defineProps<{
|
||||
presetId: number;
|
||||
}>();
|
||||
|
||||
const employee_amount_using_preset = ref(0);
|
||||
const delete_input_string = ref('');
|
||||
const is_approve_deletion = computed(() => ['SUPPRIMER', 'DELETE'].includes(delete_input_string.value));
|
||||
|
||||
onMounted(() => {
|
||||
const employees_with_preset = employee_store.employee_list.filter(employee => employee.preset_id === presetId);
|
||||
employee_amount_using_preset.value = employees_with_preset.length;
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
class="column flex-center bg-secondary q-pa-md rounded-10 shadow-24"
|
||||
style="border: 2px solid var(--q-negative); width: 40vw !important;"
|
||||
>
|
||||
<span class="col-auto text-weight-bold text-uppercase text-center text-negative text-h5 q-pb-lg">
|
||||
{{ $t('shared.label.remove') }}
|
||||
</span>
|
||||
|
||||
<div
|
||||
v-if="employee_amount_using_preset > 0"
|
||||
class="col row flex-center text-weight-medium text-center q-mb-lg"
|
||||
>
|
||||
<span class="col-auto">{{ $t('employee_management.schedule_presets.delete_warning_employee_1') }}</span>
|
||||
<span class="col-auto q-px-sm text-h6 text-weight-bolder text-negative">{{ employee_amount_using_preset
|
||||
}}</span>
|
||||
<span class="col-auto">{{ $t('employee_management.module_access.preset_employee') +
|
||||
(employee_amount_using_preset > 1 ? 's' : '') }}</span>
|
||||
<span>{{ $t('employee_management.schedule_presets.delete_warning_employee_2') }}</span>
|
||||
</div>
|
||||
|
||||
<div class="col">
|
||||
<span class="text-weight-bold text-uppercase">{{ $t('employee_management.schedule_presets.delete_warning')
|
||||
}}</span>
|
||||
<q-input
|
||||
v-model="delete_input_string"
|
||||
standout
|
||||
dense
|
||||
rounded
|
||||
:placeholder="$t('employee_management.enter_delete_input')"
|
||||
input-class="text-center"
|
||||
:input-style="delete_input_string.length > 0 ? '' : 'opacity: 0.6;'"
|
||||
class="q-my-sm"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="col-auto row">
|
||||
<q-space />
|
||||
<q-btn
|
||||
push
|
||||
dense
|
||||
:disable="!is_approve_deletion"
|
||||
:color="is_approve_deletion ? 'negative' : 'grey-6'"
|
||||
:label="$t('shared.label.remove')"
|
||||
class="q-px-md"
|
||||
@click="employee_list_api.deleteSchedulePreset(presetId)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -3,6 +3,7 @@
|
|||
lang="ts"
|
||||
>
|
||||
import SchedulePresetsDialogRow from './schedule-presets-dialog-row.vue';
|
||||
import SchedulePresetsDialogDelete from 'src/modules/employee-list/components/schedule-presets-dialog-delete.vue';
|
||||
|
||||
import { useEmployeeListApi } from '../composables/use-employee-api';
|
||||
import { SchedulePresetShift } from '../models/schedule-presets.models';
|
||||
|
|
@ -17,7 +18,13 @@
|
|||
v-model="schedule_preset_store.is_manager_open"
|
||||
full-width
|
||||
>
|
||||
<SchedulePresetsDialogDelete
|
||||
v-if="schedule_preset_store.schedule_preset_dialog_mode === 'delete'"
|
||||
:preset-id="schedule_preset_store.current_schedule_preset.id"
|
||||
/>
|
||||
|
||||
<div
|
||||
v-else
|
||||
class="column flex-center bg-secondary rounded-10 shadow-24"
|
||||
style="border: 2px solid var(--q-accent); width: 50vw !important;"
|
||||
>
|
||||
|
|
@ -37,8 +37,16 @@ export const useEmployeeListApi = () => {
|
|||
else success = await schedule_preset_store.updateSchedulePreset(backend_preset);
|
||||
|
||||
if (success) {
|
||||
schedule_preset_store.is_manager_open = false;
|
||||
await schedule_preset_store.findSchedulePresetList();
|
||||
schedule_preset_store.is_manager_open = false;
|
||||
}
|
||||
}
|
||||
|
||||
const deleteSchedulePreset = async(preset_id: number) => {
|
||||
const success = await schedule_preset_store.deleteSchedulePreset(preset_id);
|
||||
if (success) {
|
||||
await schedule_preset_store.findSchedulePresetList();
|
||||
schedule_preset_store.is_manager_open = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -47,5 +55,6 @@ export const useEmployeeListApi = () => {
|
|||
getEmployeeDetails,
|
||||
setSchedulePreset,
|
||||
saveSchedulePreset,
|
||||
deleteSchedulePreset,
|
||||
};
|
||||
};
|
||||
|
|
@ -2,7 +2,9 @@ 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']
|
||||
export const WEEKDAYS: Weekday[] = ['SUN', 'MON', 'TUE', 'WED', 'THU', 'FRI', 'SAT'];
|
||||
|
||||
export type PresetManagerMode = 'create' | 'update' | 'copy' | 'delete';
|
||||
|
||||
export class SchedulePreset {
|
||||
id: number;
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ export const SchedulePresetsService = {
|
|||
return response.data;
|
||||
},
|
||||
|
||||
deleteSchedulePresets: async (preset_id: number) => {
|
||||
deleteSchedulePresets: async (preset_id: number): Promise<BackendResponse<boolean>> => {
|
||||
const response = await api.delete(`/schedule-presets/delete/${preset_id}`);
|
||||
return response.data;
|
||||
},
|
||||
|
|
|
|||
|
|
@ -5,6 +5,10 @@
|
|||
import { ref } from 'vue';
|
||||
import { Notify } from 'quasar';
|
||||
|
||||
const click_number = ref(1);
|
||||
const icon = ref('las la-hand-peace');
|
||||
const color = ref('accent');
|
||||
|
||||
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 \
|
||||
|
|
@ -14,10 +18,22 @@
|
|||
const slide = ref<string>('welcome');
|
||||
|
||||
const clickNotify = () => {
|
||||
if (click_number.value % 7 === 0) {
|
||||
icon.value = 'las la-hand-middle-finger';
|
||||
color.value = 'negative';
|
||||
}
|
||||
else {
|
||||
icon.value = 'las la-hand-peace';
|
||||
color.value = 'accent';
|
||||
}
|
||||
Notify.create({
|
||||
message: 'You clicked the little click button!',
|
||||
color: 'info'
|
||||
})
|
||||
color: color.value,
|
||||
icon: icon.value,
|
||||
iconSize: '5em',
|
||||
iconColor: 'white',
|
||||
});
|
||||
|
||||
click_number.value += 1;
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
|
|||
|
|
@ -2,12 +2,13 @@
|
|||
import { ref } from "vue";
|
||||
import { defineStore } from "pinia";
|
||||
import { SchedulePresetsService } from "src/modules/employee-list/services/schedule-presets-service";
|
||||
import { SchedulePreset, SchedulePresetFrontend } from "src/modules/employee-list/models/schedule-presets.models";
|
||||
import { type PresetManagerMode, SchedulePreset, SchedulePresetFrontend } from "src/modules/employee-list/models/schedule-presets.models";
|
||||
|
||||
|
||||
export const useSchedulePresetsStore = defineStore('schedule_presets_store', () => {
|
||||
const schedule_presets = ref<SchedulePreset[]>([new SchedulePreset]);
|
||||
const current_schedule_preset = ref<SchedulePresetFrontend>(new SchedulePresetFrontend);
|
||||
const schedule_preset_dialog_mode = ref<PresetManagerMode>('create');
|
||||
const is_manager_open = ref(false);
|
||||
|
||||
const openSchedulePresetManager = (preset_id: number) => {
|
||||
|
|
@ -51,11 +52,11 @@ export const useSchedulePresetsStore = defineStore('schedule_presets_store', ()
|
|||
|
||||
const deleteSchedulePreset = async (preset_id: number): Promise<boolean> => {
|
||||
try {
|
||||
await SchedulePresetsService.deleteSchedulePresets(preset_id);
|
||||
return true;
|
||||
const response = await SchedulePresetsService.deleteSchedulePresets(preset_id);
|
||||
return response.success;
|
||||
} catch (error) {
|
||||
console.error('DEV ERROR || error while deleting schedule preset: ', error);
|
||||
return false
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -84,6 +85,7 @@ export const useSchedulePresetsStore = defineStore('schedule_presets_store', ()
|
|||
return {
|
||||
schedule_presets,
|
||||
current_schedule_preset,
|
||||
schedule_preset_dialog_mode,
|
||||
is_manager_open,
|
||||
setCurrentSchedulePreset,
|
||||
openSchedulePresetManager,
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user