diff --git a/src/i18n/en-ca/index.ts b/src/i18n/en-ca/index.ts
index 6f9234d..73f56ed 100644
--- a/src/i18n/en-ca/index.ts
+++ b/src/i18n/en-ca/index.ts
@@ -123,6 +123,8 @@ export default {
page_header: "account login",
email: "e-mail",
password: "password",
+ connected: "Connected",
+ redirecting: "Redirecting...",
button: {
connect: "connect",
employee: "employee",
@@ -323,6 +325,7 @@ export default {
TIMESHEET_NOT_FOUND: "No timesheet found with provided data",
INVALID_EXPENSE: "An expense contains missing or corrupted data",
EXPENSE_NOT_FOUND: "No expense found with provided data",
+ UPDATE_ERROR: "Error while updating data",
},
},
@@ -355,6 +358,8 @@ export default {
},
tooltip: {
button_detailed_view: "detailed view",
+ approve: "Approve",
+ unapprove: "remove approval",
},
},
descriptions: {
diff --git a/src/i18n/fr-ca/index.ts b/src/i18n/fr-ca/index.ts
index 0ef60ca..4fda852 100644
--- a/src/i18n/fr-ca/index.ts
+++ b/src/i18n/fr-ca/index.ts
@@ -123,6 +123,8 @@ export default {
page_header: "connexion au compte",
email: "courriel",
password: "mot de passe",
+ connected: "Connecté",
+ redirecting: "redirection en cours...",
button: {
connect: "connecter",
employee: "employé",
@@ -324,6 +326,7 @@ export default {
TIMESHEET_NOT_FOUND: "Aucune feuille de temps ne correspond au détails fournis",
INVALID_EXPENSE: "Une dépense contient des données manquantes ou corrompues",
EXPENSE_NOT_FOUND: "Aucune dépense ne correspond aux détails fournis",
+ UPDATE_ERROR: "Une erreur est survenu lors de la mise à jour",
},
},
@@ -356,6 +359,8 @@ export default {
},
tooltip: {
button_detailed_view: "vue détaillée",
+ approve: "mettre status approuvé",
+ unapprove: "enlever status approuvé",
},
},
descriptions: {
diff --git a/src/modules/auth/pages/auth-login-popup-success.vue b/src/modules/auth/pages/auth-login-popup-success.vue
index bc01d6d..d08867a 100644
--- a/src/modules/auth/pages/auth-login-popup-success.vue
+++ b/src/modules/auth/pages/auth-login-popup-success.vue
@@ -1,4 +1,7 @@
-
@@ -15,18 +18,35 @@
-
-
-
-
+
+
+
+
-
-
- Login Successful!
+
+
+ {{ $t('login.connected') }}
+ {{ $t('login.redirecting') }}
+
-
+
\ No newline at end of file
diff --git a/src/modules/timesheet-approval/components/details-dialog.vue b/src/modules/timesheet-approval/components/details-dialog.vue
index abd6e44..ccd539d 100644
--- a/src/modules/timesheet-approval/components/details-dialog.vue
+++ b/src/modules/timesheet-approval/components/details-dialog.vue
@@ -46,7 +46,7 @@
-
+
diff --git a/src/modules/timesheet-approval/components/overview-list-item.vue b/src/modules/timesheet-approval/components/overview-list-item.vue
index 40eb0e3..790f030 100644
--- a/src/modules/timesheet-approval/components/overview-list-item.vue
+++ b/src/modules/timesheet-approval/components/overview-list-item.vue
@@ -3,7 +3,7 @@
lang="ts"
>
import type { TimesheetApprovalOverview } from 'src/modules/timesheet-approval/models/timesheet-overview.models';
-import { getHoursMinutesStringFromHoursFloat, getMinutes } from 'src/utils/date-and-time-utils';
+ import { getHoursMinutesStringFromHoursFloat, getMinutes } from 'src/utils/date-and-time-utils';
const modelApproval = defineModel();
@@ -14,7 +14,7 @@ import { getHoursMinutesStringFromHoursFloat, getMinutes } from 'src/utils/date-
const emit = defineEmits<{
'clickDetails': [overview: TimesheetApprovalOverview];
- 'clickApprovalAll' : [is_approved: boolean];
+ 'clickApprovalAll': [is_approved: boolean];
}>();
@@ -45,11 +45,10 @@ import { getHoursMinutesStringFromHoursFloat, getMinutes } from 'src/utils/date-
{{ $t('timesheet_approvals.tooltip.button_detailed_view') }}
@@ -64,7 +64,7 @@ import { getHoursMinutesStringFromHoursFloat, getMinutes } from 'src/utils/date-
@@ -152,9 +152,7 @@ import { getHoursMinutesStringFromHoursFloat, getMinutes } from 'src/utils/date-
v-if="row.is_active"
class="col row full-width"
>
-
+
{{ 'Total : ' + Math.floor(row.total_hours)
}}
H
@@ -176,7 +174,17 @@ import { getHoursMinutesStringFromHoursFloat, getMinutes } from 'src/utils/date-
class="text-uppercase"
:class="row.is_approved ? '' : 'text-accent'"
@update:model-value="value => $emit('clickApprovalAll', value)"
- />
+ >
+
+ {{ row.is_approved ? $t('timesheet_approvals.tooltip.unapprove') :
+ $t('timesheet_approvals.tooltip.approve') }}
+
+
@@ -190,8 +198,10 @@ import { getHoursMinutesStringFromHoursFloat, getMinutes } from 'src/utils/date-
class="col-auto"
size="lg"
/>
- {{
- $t('timesheet_approvals.table.inactive') }}
+
+
+ {{ $t('timesheet_approvals.table.inactive') }}
+
diff --git a/src/modules/timesheets/components/expense-dialog-list-item.vue b/src/modules/timesheets/components/expense-dialog-list-item.vue
index 40ba2f0..e1f071b 100644
--- a/src/modules/timesheets/components/expense-dialog-list-item.vue
+++ b/src/modules/timesheets/components/expense-dialog-list-item.vue
@@ -4,32 +4,57 @@
>
import ExpenseDialogForm from 'src/modules/timesheets/components/expense-dialog-form.vue';
- import { date } from 'quasar';
import { ref } from 'vue';
+ import { useI18n } from 'vue-i18n';
+ import { date, Notify } from 'quasar';
import { unwrapAndClone } from 'src/utils/unwrap-and-clone';
import { useExpensesStore } from 'src/stores/expense-store';
+ import { useTimesheetStore } from 'src/stores/timesheet-store';
import { useExpensesApi } from 'src/modules/timesheets/composables/use-expense-api';
import { getExpenseIcon } from 'src/modules/timesheets/utils/expense.util';
import type { Expense } from 'src/modules/timesheets/models/expense.models';
+ const { t } = useI18n();
+
const expense = defineModel({ required: true });
- const expenses_store = useExpensesStore();
const expenses_api = useExpensesApi();
+ const expenses_store = useExpensesStore();
+ const timesheet_store = useTimesheetStore();
const is_showing_update_form = ref(false);
+ const { mode = 'normal' } = defineProps<{
+ mode?: 'approval' | 'normal';
+ }>();
+
const requestExpenseDeletion = async () => {
await expenses_api.deleteExpenseById(expense.value.id);
}
const onClickExpenseUpdate = () => {
if (expense.value.is_approved) return;
-
+
expenses_store.mode = 'update';
expenses_store.current_expense = expense.value;
expenses_store.initial_expense = unwrapAndClone(expense.value);
}
+
+ const onClickApproval = async () => {
+ expenses_store.current_expense = unwrapAndClone(expense.value);
+ expenses_store.current_expense.is_approved = !expenses_store.current_expense.is_approved;
+
+ const success = await expenses_store.upsertExpense(expenses_store.current_expense, timesheet_store.current_pay_period_overview?.email);
+ if (success) {
+ expense.value.is_approved = !expense.value.is_approved;
+ } else {
+ expenses_store.current_expense.is_approved = !expenses_store.current_expense.is_approved;
+ Notify.create({
+ message: t('timesheet.errors.UPDATE_ERROR'),
+ color: "negative"
+ });
+ }
+ }
@@ -127,11 +152,31 @@
+
+
+ {{ expense.is_approved ? $t('timesheet_approvals.tooltip.unapprove') : $t('timesheet_approvals.tooltip.approve') }}
+
+
+
diff --git a/src/modules/timesheets/components/expense-dialog-list.vue b/src/modules/timesheets/components/expense-dialog-list.vue
index d8d1ea6..bc09ce0 100644
--- a/src/modules/timesheets/components/expense-dialog-list.vue
+++ b/src/modules/timesheets/components/expense-dialog-list.vue
@@ -9,8 +9,8 @@
const timesheet_store = useTimesheetStore();
- const { horizontal = false } = defineProps<{
- horizontal?: boolean;
+ const { mode = 'normal' } = defineProps<{
+ mode?: 'approval' | 'normal';
}>();
const expenses_list = computed(() => {
@@ -26,7 +26,6 @@
diff --git a/src/modules/timesheets/components/shift-list-scrollable.vue b/src/modules/timesheets/components/shift-list-scrollable.vue
index 3b20851..d101a97 100644
--- a/src/modules/timesheets/components/shift-list-scrollable.vue
+++ b/src/modules/timesheets/components/shift-list-scrollable.vue
@@ -29,7 +29,7 @@
const handleSwipe: TouchSwipeValue = (details) => {
mobile_animation_direction.value = details.direction === 'left' ? 'fadeInRight' : 'fadeInLeft';
- if (details.distance && details.distance.x && Math.abs(details.distance.x) > 10) {
+ if (details.distance && details.distance.x && Math.abs(details.distance.x) > 30) {
timesheet_api.getTimesheetsBySwiping(details.direction === 'left' ? 1 : -1).catch(error => console.error(error));
}
};
@@ -46,7 +46,7 @@
=> {
- const response = await api.patch(`expense/update`, expense);
+ updateExpense: async (expense: Expense, email?: string): Promise<{success: boolean, data: Expense, error?: unknown}> => {
+ const response = await api.patch(`expense/update${email ? '?employee_email=' + email : ''}`, expense);
return response.data;
},
diff --git a/src/stores/expense-store.ts b/src/stores/expense-store.ts
index 9ee9bb8..715638c 100644
--- a/src/stores/expense-store.ts
+++ b/src/stores/expense-store.ts
@@ -29,13 +29,13 @@ export const useExpensesStore = defineStore('expenses', () => {
is_showing_create_form.value = true;
};
- const upsertExpense = async (expense: Expense): Promise => {
+ const upsertExpense = async (expense: Expense, email?: string): Promise => {
try {
if (expense.id < 0) {
const data = await ExpenseService.createExpense(expense);
return data.success;
}
- const data = await ExpenseService.updateExpense(expense);
+ const data = await ExpenseService.updateExpense(expense, email);
return data.success;
} catch (err) {
// setErrorFrom(err);