diff --git a/src/i18n/en-ca/index.ts b/src/i18n/en-ca/index.ts index 1f96213..842d03a 100644 --- a/src/i18n/en-ca/index.ts +++ b/src/i18n/en-ca/index.ts @@ -191,6 +191,8 @@ export default { INVALID_SHIFT_TIME: "In and Out shift times are reversed", SHIFT_OVERLAP: "An overlaps occured between 2 or more shifts", INVALID_SHIFT: "A shift contains missing or corrupted data", + SHIFT_TIME_REQUIRED: "Valid time required", + SHIFT_TYPE_REQUIRED: "Shift type required", SHIFT_NOT_FOUND: "Shift missing or deleted", PAY_PERIOD_NOT_FOUND: "No pay period matching given dates", EMPLOYEE_NOT_FOUND: "No employee matching current login details", diff --git a/src/i18n/fr-ca/index.ts b/src/i18n/fr-ca/index.ts index 43b22b5..3283e4e 100644 --- a/src/i18n/fr-ca/index.ts +++ b/src/i18n/fr-ca/index.ts @@ -192,6 +192,8 @@ export default { INVALID_SHIFT_TIME: "Les heures d'entrée et de sortie sont inversées", SHIFT_OVERLAP: "Il y a un chevauchement entre deux ou plusieurs quarts", INVALID_SHIFT: "Un quart de travail contient des données manquantes ou corrompues", + SHIFT_TIME_REQUIRED: "Heure requise", + SHIFT_TYPE_REQUIRED: "Type requis", SHIFT_NOT_FOUND: "Quart de travail manquant ou supprimé", PAY_PERIOD_NOT_FOUND: "Aucune période de paie ne correspond aux dates fournies", EMPLOYEE_NOT_FOUND: "Aucun employé ne correspond aux détails de votre connexion", diff --git a/src/modules/timesheets/components/shift-list-day-row.vue b/src/modules/timesheets/components/shift-list-day-row.vue index 0b92714..6d8fd1f 100644 --- a/src/modules/timesheets/components/shift-list-day-row.vue +++ b/src/modules/timesheets/components/shift-list-day-row.vue @@ -3,21 +3,17 @@ lang="ts" > /* eslint-disable*/ - import { onBeforeUnmount, onMounted, ref, useTemplateRef } from 'vue'; + import { onBeforeUnmount, onMounted, ref, useTemplateRef, watch, nextTick } from 'vue'; import { useI18n } from 'vue-i18n'; - import { QSelect } from 'quasar'; - import { Shift, ShiftType } from 'src/modules/timesheets/models/shift.models'; + import { QSelect, QInput } from 'quasar'; + import { Shift, type ShiftOption } from 'src/modules/timesheets/models/shift.models'; import { useUiStore } from 'src/stores/ui-store'; + import { useShiftRules } from 'src/modules/timesheets/utils/shift.util'; + let timer: NodeJS.Timeout; const { t } = useI18n(); const ui_store = useUiStore(); - - interface ShiftOption { - label: string; - value: ShiftType; - icon: string; - icon_color: string; - } + const shift_rules = useShiftRules(t('timesheet.errors.SHIFT_TIME_REQUIRED'),); const COMMENT_LENGTH_MAX = 280; const SHIFT_OPTIONS: ShiftOption[] = [ @@ -28,8 +24,12 @@ { 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', { required: true }); + const shift_type_selected = ref(SHIFT_OPTIONS.find(option => option.value == shift.value.type)); + const select_ref = useTemplateRef('select'); + const start_time_ref = useTemplateRef('start_time'); + const end_time_ref = useTemplateRef('end_time'); + const { dense = false, hasShiftAfter = false, isTimesheetApproved = false } = defineProps<{ dense?: boolean; hasShiftAfter?: boolean; @@ -41,12 +41,6 @@ 'requestDelete': [void]; }>(); - const select_ref = useTemplateRef('select'); - - let timer: NodeJS.Timeout; - - const shift_type_selected = ref(SHIFT_OPTIONS.find(option => option.value == shift.value.type)); - const onBlurShiftTypeSelect = () => { if (shift_type_selected.value === undefined) { shift.value.type = 'REGULAR'; @@ -80,6 +74,10 @@ onBeforeUnmount(() => { clearTimeout(timer); }); + + watch(() => [start_time_ref.value?.hasError, end_time_ref.value?.hasError], ([start_error, end_error]) => { + shift.value.has_error = (start_error || end_error) ?? false; + }) + + \ 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 7686148..a392b6e 100644 --- a/src/modules/timesheets/components/timesheet-wrapper.vue +++ b/src/modules/timesheets/components/timesheet-wrapper.vue @@ -2,30 +2,34 @@ setup lang="ts" > + /* eslint-disable */ 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 LoadingOverlay from 'src/modules/shared/components/loading-overlay.vue'; - import { useTimesheetStore } from 'src/stores/timesheet-store'; + + import { computed } from 'vue'; + import { useShiftApi } from 'src/modules/timesheets/composables/use-shift-api'; import { useTimesheetApi } from 'src/modules/timesheets/composables/use-timesheet-api'; import { useExpensesStore } from 'src/stores/expense-store'; - import { useShiftApi } from 'src/modules/timesheets/composables/use-shift-api'; + import { useTimesheetStore } from 'src/stores/timesheet-store'; + const expenses_store = useExpensesStore(); const timesheet_store = useTimesheetStore(); const timesheet_api = useTimesheetApi(); const shift_api = useShiftApi(); + const has_shift_errors = computed(() => timesheet_store.all_current_shifts.filter(shift => shift.has_error === true).length > 0); const { mode = 'normal' } = defineProps<{ mode?: 'approval' | 'normal'; }>(); +