-
- {{ $t('login.page_header') }}
-
-
diff --git a/src/modules/auth/composables/use-auth-api.ts b/src/modules/auth/composables/use-auth-api.ts
index 531c3a5..1cea1e2 100644
--- a/src/modules/auth/composables/use-auth-api.ts
+++ b/src/modules/auth/composables/use-auth-api.ts
@@ -11,8 +11,10 @@ export const useAuthApi = () => {
authStore.oidcLogin();
};
- const logout = () => {
- authStore.logout();
+ const logout = async () => {
+ authStore.user = undefined;
+ await authStore.logout();
+ window.location.href = "https://auth.targo.ca/application/o/montargo/end-session/";
};
return {
diff --git a/src/modules/auth/services/services-auth.ts b/src/modules/auth/services/services-auth.ts
index 5caaa4f..5dfc2e2 100644
--- a/src/modules/auth/services/services-auth.ts
+++ b/src/modules/auth/services/services-auth.ts
@@ -8,9 +8,9 @@ export const AuthService = {
//TODO: OIDC customer sign-in, eventually
},
- logout: () => {
+ logout: async () => {
// TODO: logout logic
- api.post('/auth/logout')
+ await api.post('/auth/logout');
},
refreshToken: () => {
diff --git a/src/modules/chatbot/components/dialogue-phrase.vue b/src/modules/chatbot/components/dialogue-phrase.vue
index 7ed1152..60a59aa 100644
--- a/src/modules/chatbot/components/dialogue-phrase.vue
+++ b/src/modules/chatbot/components/dialogue-phrase.vue
@@ -2,49 +2,33 @@
setup
lang="ts"
>
+ import MarkdownIt from 'markdown-it';
+
import { computed } from 'vue';
- // import MarkdownIt from 'markdown-it'
+ import { useI18n } from 'vue-i18n';
import { useAuthStore } from 'src/stores/auth-store';
import type { Message } from 'src/modules/chatbot/models/dialogue-message.model';
- import { useI18n } from 'vue-i18n';
- const { t } = useI18n();
- const auth_store = useAuthStore();
+ // ========== state ========================================
const { message } = defineProps<{
message: Message;
}>();
- const message_text = computed(() => message.text.includes('chatbot.') ? t(message.text) : message.text)
+ const { t } = useI18n();
+ const authStore = useAuthStore();
+ const md = new MarkdownIt({
+ linkify: true,
+ typographer: true,
+ })
- const is_error = computed(() => message.text.includes('NO_REPLY_RECEIVED') || message.text.includes('SEND_MESSAGE_FAILED'));
+ // ========== computed ========================================
- // Initialize Markdown parser
- // const md = new MarkdownIt({
- // // breaks: false, // Support line breaks
- // linkify: true, // Make URLs clickable
- // html: false // Prevent raw HTML injection
- // })
-
- // // Removes all the h1,h2,h3 to make the Md more user friendly
- // const cleanMarkdown = (markdown: string): string => {
- // if (!markdown) return ''
- // return markdown
- // .replace(/\r\n/g, '\n') // normalize Windows line endings
- // .replace(/([.!?])(\s+)(?=[A-Z])/g, '$1\n') // insert line break after sentence-ending punctuation
- // .replace(/\n{3,}/g, '\n\n') // squash triple+ line breaks
- // .replace(/^#{1,3}\s(.*)$/gm, '#### $1') // downgrade headings
- // }
-
- // // Compute parsed content
- // const parsedText = computed((): string => {
- // const cleaned = cleanMarkdown(message.text || '')
- // if (cleaned.includes('chatbot.')) {
- // const translated_message = t(message.text);
- // return md.render(translated_message);
- // }
- // return md.render(cleaned);
- // })
+ const message_text = computed(() => message.text.includes('chatbot.') ?
+ t(message.text) :
+ message.text.replaceAll("\\n", "\n")
+ );
+ const is_error = computed(() => message.text.includes('chatbot.error.'));
@@ -67,11 +51,12 @@
diff --git a/src/modules/timesheet-approval/components/details-dialog.vue b/src/modules/timesheet-approval/components/details-dialog.vue
index 3baabb9..0c3f08a 100644
--- a/src/modules/timesheet-approval/components/details-dialog.vue
+++ b/src/modules/timesheet-approval/components/details-dialog.vue
@@ -10,26 +10,42 @@
import DetailsDialogChartExpenses from 'src/modules/timesheet-approval/components/details-dialog-chart-expenses.vue';
import TimesheetWrapper from 'src/modules/timesheets/components/timesheet-wrapper.vue';
import ExpenseDialogList from 'src/modules/timesheets/components/expense-dialog-list.vue';
+ import ExpenseDialogForm from 'src/modules/timesheets/components/expense-dialog-form.vue';
import { useTimesheetApprovalApi } from '../composables/use-timesheet-approval-api';
+ import { useShiftApi } from 'src/modules/timesheets/composables/use-shift-api';
+ import { useExpensesStore } from 'src/stores/expense-store';
+ import { Expense } from 'src/modules/timesheets/models/expense.models';
+ import { date } from 'quasar';
+
+ // ========== state ========================================
const { t } = useI18n();
- const timesheet_store = useTimesheetStore();
+ const timesheetStore = useTimesheetStore();
+ const expenseStore = useExpensesStore();
const timesheetApprovalApi = useTimesheetApprovalApi();
- const is_dialog_open = ref(false);
+ const shiftApi = useShiftApi();
+ const isDialogOpen = ref(false);
+
+ // ========== computed ========================================
+
+ const isApproved = computed(() => timesheetStore.timesheets.every(timesheet => timesheet.is_approved));
- const isApproved = computed(() => timesheet_store.timesheets.every(timesheet => timesheet.is_approved));
const approveButtonLabel = computed(() => isApproved.value ?
- t('timesheet_approvals.table.verified') :
- t('timesheet_approvals.table.unverified')
+ t('shared.label.unlock') :
+ t('shared.label.lock')
);
- const approveButtonIcon = computed(() => isApproved.value ? 'lock' : 'lock_open');
- const hasExpenses = computed(() => timesheet_store.timesheets.some(timesheet =>
+
+ const approveButtonIcon = computed(() => isApproved.value ? 'las la-lock' : 'las la-unlock');
+
+ const hasExpenses = computed(() => timesheetStore.timesheets.some(timesheet =>
Object.values(timesheet.weekly_expenses).some(hours => hours > 0))
);
+ // ========== methods ========================================
+
const onClickApproveAll = async () => {
- const employeeEmail = timesheet_store.current_pay_period_overview?.email;
- const isApproved = timesheet_store.timesheets.every(timesheet => timesheet.is_approved);
+ const employeeEmail = timesheetStore.current_pay_period_overview?.email;
+ const isApproved = timesheetStore.timesheets.every(timesheet => timesheet.is_approved);
if (employeeEmail !== undefined && isApproved !== undefined) {
await timesheetApprovalApi.toggleTimesheetsApprovalByEmployeeEmail(
@@ -38,19 +54,32 @@
);
}
}
+
+ const onClickSaveTimesheets = async () => {
+ await shiftApi.saveShiftChanges(timesheetStore.current_pay_period_overview?.email);
+ expenseStore.is_showing_create_form = false;
+ }
+
+ const onClickExpenseCreate = () => {
+ expenseStore.mode = 'create';
+ if (timesheetStore.pay_period)
+ expenseStore.current_expense = new Expense(timesheetStore.pay_period.period_start);
+ else
+ expenseStore.current_expense = new Expense(date.formatDate(new Date(), 'YYYY-MM-DD'));
+ }