diff --git a/src/i18n/en-ca/index.ts b/src/i18n/en-ca/index.ts
index b7c97ea..c02d48e 100644
--- a/src/i18n/en-ca/index.ts
+++ b/src/i18n/en-ca/index.ts
@@ -176,6 +176,10 @@ export default {
timesheet: {
page_header: "Timesheet",
+ week: "week",
+ total_hours: "total hours: ",
+ current_shifts: "shifts worked",
+ apply_preset: "auto-fill",
apply_preset_day: "Apply schedule to day",
apply_preset_week: "Apply schedule to week",
nav_button: {
@@ -254,15 +258,6 @@ export default {
timesheet_approvals: {
page_title: "Validation cartes de temps",
- table: {
- full_name: "full name",
- email: "email address",
- is_approved: "approval",
- expenses: "expenses",
- mileage: "mileage",
- verified: "approved",
- unverified: "pending",
- },
chart: {
hours_worked_title: "hours worked",
expenses_title: "expenses accrued",
@@ -275,6 +270,15 @@ export default {
expenses: "expenses",
options: "options",
},
+ table: {
+ full_name: "full name",
+ email: "email address",
+ is_approved: "approval",
+ expenses: "expenses",
+ mileage: "mileage",
+ verified: "approved",
+ unverified: "pending",
+ },
tooltip: {
button_detailed_view: "detailed view",
},
diff --git a/src/i18n/fr-ca/index.ts b/src/i18n/fr-ca/index.ts
index ed464e9..e402331 100644
--- a/src/i18n/fr-ca/index.ts
+++ b/src/i18n/fr-ca/index.ts
@@ -177,6 +177,10 @@ export default {
timesheet: {
page_header: "Carte de temps",
+ week: "semaine",
+ total_hours: "heures totales: ",
+ current_shifts: "quarts entrées",
+ apply_preset: "auto-remplir",
apply_preset_day: "Appliquer horaire pour la journée",
apply_preset_week: "Appliquer horaire pour la semaine",
nav_button: {
@@ -255,15 +259,6 @@ export default {
timesheet_approvals: {
page_title: "Validation cartes de temps",
- table: {
- full_name: "nom complet",
- email: "courriel",
- is_approved: "approuvé",
- expenses: "dépenses",
- mileage: "kilométrage",
- verified: "approuvé",
- unverified: "à vérifier",
- },
chart: {
hours_worked_title: "heures travaillées",
expenses_title: "dépenses encourues"
@@ -276,6 +271,15 @@ export default {
expenses: "dépenses",
options: "options",
},
+ table: {
+ full_name: "nom complet",
+ email: "courriel",
+ is_approved: "approuvé",
+ expenses: "dépenses",
+ mileage: "kilométrage",
+ verified: "approuvé",
+ unverified: "à vérifier",
+ },
tooltip: {
button_detailed_view: "vue détaillée",
},
diff --git a/src/layouts/components/main-layout-header-bar.vue b/src/layouts/components/main-layout-header-bar.vue
index 0d4beb8..31d67da 100644
--- a/src/layouts/components/main-layout-header-bar.vue
+++ b/src/layouts/components/main-layout-header-bar.vue
@@ -3,7 +3,7 @@
setup
>
import { useUiStore } from 'src/stores/ui-store';
- import HeaderBarNotification from './main-layout-header-bar-notification.vue';
+ // import HeaderBarNotification from './main-layout-header-bar-notification.vue';
const uiStore = useUiStore();
@@ -29,7 +29,7 @@
-
+
diff --git a/src/layouts/main-layout.vue b/src/layouts/main-layout.vue
index 97163be..6c730c9 100644
--- a/src/layouts/main-layout.vue
+++ b/src/layouts/main-layout.vue
@@ -2,16 +2,15 @@
lang="ts"
setup
>
- import { RouterView } from 'vue-router';
import HeaderBar from 'src/layouts/components/main-layout-header-bar.vue';
import FooterBar from 'src/layouts/components/main-layout-footer-bar.vue';
import LeftDrawer from 'src/layouts/components/main-layout-left-drawer.vue';
- import { useUiStore } from 'src/stores/ui-store';
+
import { onMounted, watch, ref } from 'vue';
- import { useI18n } from 'vue-i18n';
-
- const { t } = useI18n();
+ import { RouterView } from 'vue-router';
+ import { useUiStore } from 'src/stores/ui-store';
+
const ui_store = useUiStore();
const user_preferences = ref(ui_store.user_preferences);
@@ -23,7 +22,7 @@
watch(user_preferences, async () => {
if (ui_store.user_preferences.id !== -1) {
- await ui_store.updateUserPreferences(t);
+ await ui_store.updateUserPreferences();
return
}
await ui_store.getUserPreferences();
diff --git a/src/modules/profile/components/employee/menu-employee.vue b/src/modules/profile/components/employee/menu-employee.vue
index 1637ee1..7d666ba 100644
--- a/src/modules/profile/components/employee/menu-employee.vue
+++ b/src/modules/profile/components/employee/menu-employee.vue
@@ -25,7 +25,7 @@
-
-
+
+
{{ $t('profile.preferences.display_options') }}
@@ -32,12 +29,12 @@
clickable
dense
v-ripple
- class="col rounded-5 q-ma-sm shadow-4"
- :class="mode.quasar_value === $q.dark.mode ? 'bg-accent text-white text-weight-bolder' : ''"
+ class="col row rounded-5 q-ma-sm shadow-4"
+ :class="(mode.quasar_value === $q.dark.mode ? 'bg-accent text-white text-weight-bolder' : '') + ($q.platform.is.mobile ? ' full-width q-py-xs' : '')"
@click="ui_store.user_preferences.is_dark_mode = mode.value"
>
-
diff --git a/src/modules/timesheet-approval/components/overview-list-filters.vue b/src/modules/timesheet-approval/components/overview-list-filters.vue
index 46728a4..41ebeee 100644
--- a/src/modules/timesheet-approval/components/overview-list-filters.vue
+++ b/src/modules/timesheet-approval/components/overview-list-filters.vue
@@ -1,12 +1,37 @@
-
-
-
test
-
test
-
test
-
test
+
\ No newline at end of file
diff --git a/src/modules/timesheets/components/mobile/shift-list-day-row-mobile.vue b/src/modules/timesheets/components/mobile/shift-list-day-row-mobile.vue
new file mode 100644
index 0000000..50039d6
--- /dev/null
+++ b/src/modules/timesheets/components/mobile/shift-list-day-row-mobile.vue
@@ -0,0 +1,295 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ 280 - comment_length }}
+
+
+
+
+
+
+
+
shift.type = option.value"
+ >
+
+
+
+
+ {{ $t(scope.opt.label) }}
+
+
+
+
+
+
+
+ {{ shift.is_remote ? $t('timesheet.shift.types.REMOTE') :
+ $t('timesheet.shift.types.OFFICE') }}
+
+
+
+
+
+ {{ shift.is_remote ? $t('timesheet.shift.types.REMOTE') :
+ $t('timesheet.shift.types.OFFICE') }}
+
+
+
+
+
+
+
+
+
+
+
+ {{ $t('shared.misc.in') }}
+
+
+
+
+
+
+
+
+
+ {{ $t('shared.misc.out') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/modules/timesheets/components/shift-list-day-row.vue b/src/modules/timesheets/components/shift-list-day-row.vue
index 3ad6c58..d304130 100644
--- a/src/modules/timesheets/components/shift-list-day-row.vue
+++ b/src/modules/timesheets/components/shift-list-day-row.vue
@@ -3,12 +3,12 @@
lang="ts"
>
/* eslint-disable*/
- import { onBeforeUnmount, onMounted, ref, useTemplateRef, watch, nextTick } from 'vue';
+ import { onBeforeUnmount, onMounted, ref, useTemplateRef, watch } from 'vue';
import { useI18n } from 'vue-i18n';
import { QSelect, QInput } from 'quasar';
- import { Shift, type ShiftOption } from 'src/modules/timesheets/models/shift.models';
+ import { Shift } from 'src/modules/timesheets/models/shift.models';
import { useUiStore } from 'src/stores/ui-store';
- import { useShiftRules, SHIFT_OPTIONS } from 'src/modules/timesheets/utils/shift.util';
+ import { SHIFT_OPTIONS } from 'src/modules/timesheets/utils/shift.util';
let timer: NodeJS.Timeout;
const { t } = useI18n();
@@ -22,15 +22,12 @@
const start_time_ref = useTemplateRef
('start_time');
const end_time_ref = useTemplateRef('end_time');
- const { dayShifts = [], dense = false, hasShiftAfter = false, isTimesheetApproved = false } = defineProps<{
- dayShifts: Shift[];
+ const { dense = false, hasShiftAfter = false, isTimesheetApproved = false } = defineProps<{
dense?: boolean;
hasShiftAfter?: boolean;
isTimesheetApproved?: boolean;
}>();
- const shift_rules = useShiftRules(t('timesheet.errors.SHIFT_TIME_REQUIRED'), t('timesheet.errors.SHIFT_OVERLAP_SHORT'), dayShifts);
-
const emit = defineEmits<{
'saveComment': [comment: string, shift_id: number];
'requestDelete': [void];
@@ -251,7 +248,6 @@
lazy-rules
no-error-icon
hide-bottom-space
- :rules="[shift_rules.isTimeRequiredRule, shift_rules.isShiftOverlapRule]"
:label-color="!shift.is_approved ? 'accent' : 'white'"
class="col rounded-5 bg-dark"
:class="(shift.id === -2 ? 'bg-negative ' : ' ') + (ui_store.is_mobile_mode ? 'q-mr-xs ' : 'q-mx-xs ') + (!shift.is_approved && !isTimesheetApproved ? '' : 'cursor-not-allowed inset-shadow')"
@@ -279,10 +275,8 @@
:readonly="(shift.is_approved && isTimesheetApproved)"
type="time"
label-slot
- lazy-rules
no-error-icon
hide-bottom-space
- :rules="[shift_rules.isTimeRequiredRule, shift_rules.isShiftOverlapRule]"
:label-color="!shift.is_approved ? '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;"
diff --git a/src/modules/timesheets/components/shift-list-day.vue b/src/modules/timesheets/components/shift-list-day.vue
index a4c8509..ea3b9ae 100644
--- a/src/modules/timesheets/components/shift-list-day.vue
+++ b/src/modules/timesheets/components/shift-list-day.vue
@@ -3,6 +3,7 @@
lang="ts"
>
import ShiftListDayRow from 'src/modules/timesheets/components/shift-list-day-row.vue';
+ import ShiftListDayRowMobile from 'src/modules/timesheets/components/mobile/shift-list-day-row-mobile.vue';
import { ref } from 'vue';
import { useShiftApi } from 'src/modules/timesheets/composables/use-shift-api';
@@ -69,15 +70,29 @@
-
+ class="col"
+ >
+
+
+
+
+
\ No newline at end of file
diff --git a/src/modules/timesheets/components/shift-list.vue b/src/modules/timesheets/components/shift-list.vue
index 329ebca..cf06e4b 100644
--- a/src/modules/timesheets/components/shift-list.vue
+++ b/src/modules/timesheets/components/shift-list.vue
@@ -47,20 +47,24 @@
return day.shifts.every(shift => shift.is_approved === true);
}
- const handleSwipe = async (direction: 'left' | 'up' | 'down' | 'right' | undefined, distance: {x?: number, y?: number}) => {
+ const handleSwipe = async (direction: 'left' | 'up' | 'down' | 'right' | undefined, distance: { x?: number, y?: number }) => {
mobile_animation_direction.value = direction === 'left' ? 'fadeInRight' : 'fadeInLeft';
- if (distance.x && Math.abs(distance.x) > 10 ) {
- await timesheet_api.getTimesheetsBySwiping( direction === 'left' ? 1 : -1 )
+ if (distance.x && Math.abs(distance.x) > 10) {
+ await timesheet_api.getTimesheetsBySwiping(direction === 'left' ? 1 : -1)
}
}
-
+
@@ -145,6 +148,15 @@
weekday: 'long', day: 'numeric', month:
'long'
}) }}
+
+
-
-
-
-
@@ -194,13 +194,6 @@
class="col row full-width"
:class="(getDayApproval(day) || timesheet.is_approved) ? 'rounded-10 bg-accent' : ''"
>
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
\ 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 ad8cdee..0d0a5bc 100644
--- a/src/modules/timesheets/components/timesheet-wrapper.vue
+++ b/src/modules/timesheets/components/timesheet-wrapper.vue
@@ -39,7 +39,7 @@
@@ -63,20 +63,7 @@
@click="expenses_store.open"
/>
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
{{ $t('timesheet.week') + ` ${timesheet_index + 1}` }}
+
+
+
+ {{
+ $t('timesheet.total_hours') }}
+ {{
+ (timesheet.weekly_hours.regular +
+ timesheet.weekly_hours.evening +
+ timesheet.weekly_hours.emergency +
+ timesheet.weekly_hours.overtime).toFixed(2)
+ }}
+
+
+
+
{{ $t('timesheet.current_shifts') }}
+
+
+
+
+
+ {{ day.shifts.length > 0 ? day.shifts.length : ''
+ }}
+
+
+
+
+
+
+
+
+
+
-
-
-
+
diff --git a/src/modules/timesheets/utils/shift.util.ts b/src/modules/timesheets/utils/shift.util.ts
index 00fb6ef..0dc2c5e 100644
--- a/src/modules/timesheets/utils/shift.util.ts
+++ b/src/modules/timesheets/utils/shift.util.ts
@@ -1,4 +1,4 @@
-import { date, patterns, type ValidationRule } from "quasar";
+import { date } from "quasar";
import type { SchedulePresetShift } from "src/modules/employee-list/models/schedule-presets.models";
import type { Shift, ShiftOption } from "src/modules/timesheets/models/shift.models";
@@ -26,16 +26,6 @@ export const isShiftOverlap = (shifts: Shift[] | SchedulePresetShift[]): boolean
return false;
};
-export const useShiftRules = (time_required_error: string, overlap_error_string: string, day_shifts: Shift[]) => {
- const isTimeRequiredRule: ValidationRule
= (time_string: string) => (!!time_string && patterns.testPattern.time(time_string)) || time_required_error;
- const isShiftOverlapRule: ValidationRule = (_time_string: string) => !isShiftOverlap(day_shifts) || overlap_error_string;
-
- return {
- isTimeRequiredRule,
- isShiftOverlapRule
- };
-};
-
export const SHIFT_OPTIONS: ShiftOption[] = [
{ label: 'timesheet.shift.types.REGULAR', value: 'REGULAR', icon: 'wb_sunny', icon_color: 'accent' },
{ label: 'timesheet.shift.types.EVENING', value: 'EVENING', icon: 'bedtime', icon_color: 'orange-5' },
diff --git a/src/pages/profile-page.vue b/src/pages/profile-page.vue
index e010de1..cfb2309 100644
--- a/src/pages/profile-page.vue
+++ b/src/pages/profile-page.vue
@@ -21,10 +21,11 @@ import { onMounted } from 'vue';
-
+
\ No newline at end of file
diff --git a/src/pages/timesheet-approval-page.vue b/src/pages/timesheet-approval-page.vue
index a13fe15..d2aea1f 100644
--- a/src/pages/timesheet-approval-page.vue
+++ b/src/pages/timesheet-approval-page.vue
@@ -16,8 +16,8 @@
import { useTimesheetApprovalApi } from 'src/modules/timesheet-approval/composables/use-timesheet-approval-api';
import { useTimesheetStore } from 'src/stores/timesheet-store';
-const timesheet_approval_api = useTimesheetApprovalApi();
-const timesheet_store = useTimesheetStore();
+ const timesheet_approval_api = useTimesheetApprovalApi();
+ const timesheet_store = useTimesheetStore();
const is_showing_filters = ref(false);
@@ -58,34 +58,24 @@ const timesheet_store = useTimesheetStore();
-
-
-
@@ -102,22 +93,31 @@ const timesheet_store = useTimesheetStore();
v-model:search="timesheet_store.search_filter"
class="col-auto q-mb-xs"
/>
+
+
-
+
-
diff --git a/src/pages/timesheet-page.vue b/src/pages/timesheet-page.vue
index fd440f9..f632dab 100644
--- a/src/pages/timesheet-page.vue
+++ b/src/pages/timesheet-page.vue
@@ -16,7 +16,7 @@
{
@@ -44,7 +44,7 @@ export const useUiStore = defineStore('ui', () => {
}
};
- const updateUserPreferences = async (t: ComposerTranslation) => {
+ const updateUserPreferences = async () => {
try {
if (user_preferences.value.id === -1) return;
@@ -53,13 +53,11 @@ export const useUiStore = defineStore('ui', () => {
Object.assign(user_preferences.value, response.data);
LocalStorage.setItem('user_preferences', response.data);
setPreferences();
- Notify.create({ message: t('profile.preferences.update_successful'), color: 'accent' });
return;
}
} catch (error) {
console.error('Could not update user preferences: ', error);
}
- Notify.create({ message: t('profile.preferences.update_failed'), color: 'negative' })
};
const setPreferences = () => {