refactor(timesheet): more work on plugging in backend, managing expenses
This commit is contained in:
parent
18aa4c08f4
commit
f0ef88a16c
|
|
@ -104,7 +104,6 @@ export default defineConfig((ctx) => {
|
|||
config: {
|
||||
notify: {
|
||||
color: 'primary',
|
||||
avatar: 'https://cdn.quasar.dev/img/boy-avatar.png',
|
||||
},
|
||||
dark: false,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
$primary : #019547;
|
||||
$secondary : #DAE0E7;
|
||||
$accent : #AAD5C4;
|
||||
$accent : #83f29f7d;
|
||||
|
||||
$dark-shadow-color : #00220f;
|
||||
|
||||
|
|
|
|||
|
|
@ -44,12 +44,28 @@
|
|||
</template>
|
||||
</q-input>
|
||||
|
||||
<q-card-section class="q-ma-none q-pa-none text-uppercase text-caption text-weight-medium">
|
||||
<q-card-section
|
||||
horizontal
|
||||
class="q-mb-md q-pa-none text-uppercase text-caption text-weight-medium"
|
||||
>
|
||||
<q-toggle
|
||||
v-model="is_remembered"
|
||||
size="sm"
|
||||
color="primary"
|
||||
:label="$t('login.button.remember_me')"
|
||||
class="col-auto"
|
||||
/>
|
||||
|
||||
<transition
|
||||
enter-active-class="animated rubberBand slow"
|
||||
leave-active-class=""
|
||||
mode="out-in"
|
||||
>
|
||||
<span
|
||||
:key="is_remembered ? 'yep' : 'nope'"
|
||||
class="col-auto text-weight-bold self-center q-ml-sm"
|
||||
:class="is_remembered ? 'text-primary' : ''"
|
||||
>{{ $t('login.button.remember_me') }}</span>
|
||||
</transition>
|
||||
</q-card-section>
|
||||
|
||||
<q-card-actions>
|
||||
|
|
|
|||
|
|
@ -3,10 +3,10 @@
|
|||
lang="ts"
|
||||
>
|
||||
/* eslint-disable */
|
||||
import { inject, ref } from 'vue';
|
||||
import { computed, inject, ref } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useExpensesStore } from 'src/stores/expense-store';
|
||||
import { empty_expense, EXPENSE_TYPE, TYPES_WITH_AMOUNT_ONLY } from 'src/modules/timesheets/models/expense.models';
|
||||
import { Expense, EXPENSE_TYPE, TYPES_WITH_AMOUNT_ONLY } from 'src/modules/timesheets/models/expense.models';
|
||||
import { useExpenseRules } from 'src/modules/timesheets/utils/expense.util';
|
||||
import { useExpensesApi } from 'src/modules/timesheets/composables/use-expense-api';
|
||||
import { useTimesheetStore } from 'src/stores/timesheet-store';
|
||||
|
|
@ -18,45 +18,44 @@
|
|||
const expenses_api = useExpensesApi();
|
||||
const files = defineModel<File[] | null>('files');
|
||||
const is_navigator_open = ref(false);
|
||||
const mode = ref<'create' | 'update' | 'delete'>('create');
|
||||
|
||||
const COMMENT_MAX_LENGTH = 280;
|
||||
const employee_email = inject<string>('employeeEmail');
|
||||
const rules = useExpenseRules(t);
|
||||
const background_color = computed(() => expenses_store.mode === 'update' ? 'accent' : '');
|
||||
|
||||
const cancelUpdateMode = () => {
|
||||
expenses_store.current_expense = empty_expense;
|
||||
expenses_store.initial_expense = empty_expense;
|
||||
expenses_store.current_expense = new Expense;
|
||||
expenses_store.initial_expense = new Expense;
|
||||
}
|
||||
|
||||
const requestExpenseCreationOrUpdate = async () => {
|
||||
if (mode.value === 'create') await expenses_api.createExpenseByEmployeeEmail(employee_email ?? '', expenses_store.current_expense?.date ?? '');
|
||||
if (expenses_store.mode === 'create') await expenses_api.createExpenseByEmployeeEmail(employee_email ?? '', expenses_store.current_expense?.date ?? '');
|
||||
else await expenses_api.updateExpenseByEmployeeEmail(employee_email ?? '', expenses_store.current_expense?.date ?? '');
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<q-form
|
||||
flat
|
||||
v-if="!timesheet_store.timesheets?.every(timesheet => timesheet.is_approved)"
|
||||
:key="expenses_store.mode"
|
||||
flat
|
||||
@submit.prevent="requestExpenseCreationOrUpdate"
|
||||
>
|
||||
<div class="text-subtitle2 q-py-sm">
|
||||
{{ $t('timesheet.expense.add_expense') }}
|
||||
</div>
|
||||
<div
|
||||
class="row justify-between rounded-5"
|
||||
:class="mode === 'update' ? 'bg-accent' : ''"
|
||||
>
|
||||
<div class="row justify-between rounded-5">
|
||||
|
||||
<!-- date selection input -->
|
||||
<q-input
|
||||
v-model="expenses_store.current_expense.date"
|
||||
dense
|
||||
filled
|
||||
outlined
|
||||
readonly
|
||||
stack-label
|
||||
class="col q-px-xs"
|
||||
:bg-color="background_color"
|
||||
color="primary"
|
||||
:label="$t('timesheet.expense.date')"
|
||||
>
|
||||
|
|
@ -85,6 +84,7 @@
|
|||
filled
|
||||
dense
|
||||
class="col q-px-xs"
|
||||
:bg-color="background_color"
|
||||
color="primary"
|
||||
emit-value
|
||||
map-options
|
||||
|
|
@ -105,6 +105,7 @@
|
|||
clearable
|
||||
color="primary"
|
||||
class="col q-px-xs"
|
||||
:bg-color="background_color"
|
||||
:label="$t('timesheet.expense.amount')"
|
||||
suffix="$"
|
||||
lazy-rules="ondemand"
|
||||
|
|
@ -124,6 +125,7 @@
|
|||
clearable
|
||||
color="primary"
|
||||
class="col q-px-xs"
|
||||
:bg-color="background_color"
|
||||
:label="$t('timesheet.expense.mileage')"
|
||||
suffix="km"
|
||||
lazy-rules="ondemand"
|
||||
|
|
@ -135,12 +137,13 @@
|
|||
<q-input
|
||||
v-model="expenses_store.current_expense.comment"
|
||||
filled
|
||||
color="primary"
|
||||
type="text"
|
||||
class="col q-px-sm"
|
||||
dense
|
||||
stack-label
|
||||
clearable
|
||||
color="primary"
|
||||
type="text"
|
||||
class="col q-px-sm"
|
||||
:bg-color="background_color"
|
||||
:counter="true"
|
||||
:maxlength="COMMENT_MAX_LENGTH"
|
||||
lazy-rules="ondemand"
|
||||
|
|
@ -156,14 +159,15 @@
|
|||
<!-- import attach file section -->
|
||||
<q-file
|
||||
v-model="files"
|
||||
:label="$t('timesheet.expense.hints.attach_file')"
|
||||
dense
|
||||
filled
|
||||
use-chips
|
||||
multiple
|
||||
stack-label
|
||||
:label="$t('timesheet.expense.hints.attach_file')"
|
||||
class="col"
|
||||
:bg-color="background_color"
|
||||
style="max-width: 300px;"
|
||||
dense
|
||||
>
|
||||
<template #prepend>
|
||||
<q-icon
|
||||
|
|
@ -175,13 +179,14 @@
|
|||
</q-file>
|
||||
|
||||
<!-- add btn section -->
|
||||
<div>
|
||||
<div class="col-auto column">
|
||||
<q-btn
|
||||
v-if="mode === 'update'"
|
||||
flat
|
||||
v-if="expenses_store.mode === 'update'"
|
||||
push
|
||||
dense
|
||||
size="sm"
|
||||
class="q-mt-sm q-ml-sm"
|
||||
class="col q-ml-sm"
|
||||
icon="cancel"
|
||||
@click="cancelUpdateMode"
|
||||
/>
|
||||
|
||||
|
|
@ -189,9 +194,10 @@
|
|||
push
|
||||
dense
|
||||
color="primary"
|
||||
icon="add"
|
||||
:icon="expenses_store.mode === 'update' ? 'save' : 'add'"
|
||||
:label="$q.screen.gt.sm ? (expenses_store.mode === 'update' ? $t('shared.label.update') : $t('shared.label.add')) : ''"
|
||||
size="sm"
|
||||
class="q-mt-sm q-ml-sm"
|
||||
class="col q-mx-xs q-my-sm q-pr-sm"
|
||||
type="submit"
|
||||
/>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -2,43 +2,37 @@
|
|||
setup
|
||||
lang="ts"
|
||||
>
|
||||
/* eslint-disable */
|
||||
import { computed, inject, ref } from 'vue';
|
||||
import { unwrapAndClone } from 'src/utils/unwrap-and-clone';
|
||||
import { useExpensesApi } from 'src/modules/timesheets/composables/use-expense-api';
|
||||
import { useExpensesStore } from 'src/stores/expense-store';
|
||||
import { useTimesheetStore } from 'src/stores/timesheet-store';
|
||||
import { getExpenseIcon } from 'src/modules/timesheets/utils/expense.util';
|
||||
import { useAuthStore } from 'src/stores/auth-store';
|
||||
import { CAN_APPROVE_PAY_PERIODS } from 'src/modules/shared/models/user.models';
|
||||
import { empty_expense, type Expense } from 'src/modules/timesheets/models/expense.models';
|
||||
import { Expense } from 'src/modules/timesheets/models/expense.models';
|
||||
import { deepEqual } from 'src/utils/deep-equal';
|
||||
|
||||
const { expense, horizontal = false } = defineProps<{
|
||||
expense: Expense;
|
||||
index: number;
|
||||
horizontal?: boolean;
|
||||
}>();
|
||||
const is_approved = defineModel<boolean>({ required: true });
|
||||
|
||||
const timesheet_store = useTimesheetStore();
|
||||
const expenses_store = useExpensesStore();
|
||||
const auth_store = useAuthStore();
|
||||
const expenses_api = useExpensesApi();
|
||||
const employee_email = inject<string>('employeeEmail') ?? '';
|
||||
|
||||
const is_approved = defineModel<boolean>({ required: true });
|
||||
const is_selected = ref(false);
|
||||
const refresh_key = ref(1);
|
||||
const background_class = computed(() => deepEqual(expense, expenses_store.current_expense) ? 'bg-accent' : '');
|
||||
const approved_class = computed(() => horizontal ? ' q-mx-xs q-pa-xs cursor-pointer' : '')
|
||||
const expense_item_style = computed(() => is_approved.value ? 'border: solid 2px var(--q-primary);' : 'border: solid 2px grey;');
|
||||
const is_authorized_to_approve = computed(() => CAN_APPROVE_PAY_PERIODS.includes(auth_store.user?.role ?? 'GUEST'))
|
||||
|
||||
const expenseItemStyle = computed(() => is_approved.value ? 'border: solid 2px var(--q-primary);' : 'border: solid 2px grey;');
|
||||
// const highlightClass = computed(() => (expenses_store.mode === 'update' && is_selected) ? 'bg-accent' : '');
|
||||
const approvedClass = computed(() => horizontal ? ' q-mx-xs q-pa-xs cursor-pointer' : '')
|
||||
|
||||
|
||||
const employeeEmail = inject<string>('employeeEmail') ?? '';
|
||||
|
||||
|
||||
const setExpenseToModify = () => {
|
||||
// expenses_store.mode = 'update';
|
||||
const setExpenseToUpdate = () => {
|
||||
expenses_store.mode = 'update';
|
||||
// if (expense.is_approved) return;
|
||||
expenses_store.current_expense = expense;
|
||||
expenses_store.initial_expense = unwrapAndClone(expense);
|
||||
};
|
||||
|
|
@ -46,16 +40,26 @@
|
|||
const requestExpenseDeletion = async () => {
|
||||
// expenses_store.mode = 'delete';
|
||||
expenses_store.initial_expense = expense;
|
||||
expenses_store.current_expense = empty_expense;
|
||||
await expenses_api.deleteExpenseByEmployeeEmail(employeeEmail, expenses_store.initial_expense.date);
|
||||
expenses_store.current_expense = new Expense;
|
||||
await expenses_api.deleteExpenseByEmployeeEmail(employee_email, expenses_store.initial_expense.date);
|
||||
}
|
||||
|
||||
function onExpenseClicked() {
|
||||
const onExpenseClicked = () => {
|
||||
if (is_authorized_to_approve.value) {
|
||||
is_approved.value = !is_approved.value;
|
||||
refresh_key.value += 1;
|
||||
}
|
||||
}
|
||||
|
||||
const onUpdateClicked = () => {
|
||||
if (expenses_store.mode === 'update') {
|
||||
expenses_store.mode = 'create';
|
||||
expenses_store.current_expense = new Expense;
|
||||
expenses_store.initial_expense = new Expense;
|
||||
return;
|
||||
}
|
||||
setExpenseToUpdate();
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
|
@ -67,7 +71,8 @@
|
|||
:key="refresh_key"
|
||||
:clickable="horizontal"
|
||||
class="row col-4 q-ma-xs shadow-2"
|
||||
:style="expenseItemStyle + approvedClass"
|
||||
:class="background_class + approved_class"
|
||||
:style="expense_item_style"
|
||||
@click="onExpenseClicked"
|
||||
>
|
||||
<q-badge
|
||||
|
|
@ -104,7 +109,7 @@
|
|||
</q-item-section>
|
||||
|
||||
<!-- amount or mileage section -->
|
||||
<q-item-section class="col-auto">
|
||||
<q-item-section class="col col-md-2">
|
||||
<q-item-label v-if="String(expense.type).trim().toUpperCase() === 'MILEAGE'">
|
||||
<template v-if="typeof expense.mileage === 'number'">
|
||||
{{ expense.mileage?.toFixed(1) }} km
|
||||
|
|
@ -121,9 +126,9 @@
|
|||
<q-item-label
|
||||
caption
|
||||
lines="1"
|
||||
class="text-uppercase"
|
||||
>
|
||||
<!-- {{ $d(new Date(expense.date), { year: 'numeric', month: 'short', day: 'numeric', weekday: 'short' }) }} -->
|
||||
{{ expense.date }}
|
||||
{{ $d(new Date(expense.date), { month: 'short', day: 'numeric', weekday: 'long' }) }}
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
|
||||
|
|
@ -174,24 +179,21 @@
|
|||
</q-item-label>
|
||||
</q-item-section>
|
||||
|
||||
<q-item-section
|
||||
side
|
||||
class="q-pa-none"
|
||||
>
|
||||
<q-item-section :side="$q.screen.gt.sm">
|
||||
<q-btn
|
||||
push
|
||||
dense
|
||||
size="xs"
|
||||
color="primary"
|
||||
icon="edit"
|
||||
class="q-mb-xs z-top"
|
||||
@click.stop="setExpenseToModify"
|
||||
class="z-top"
|
||||
@click.stop="onUpdateClicked"
|
||||
/>
|
||||
</q-item-section>
|
||||
|
||||
<q-item-section :side="$q.screen.gt.sm">
|
||||
<q-btn
|
||||
push
|
||||
dense
|
||||
size="xs"
|
||||
color="negative"
|
||||
icon="close"
|
||||
class="z-top"
|
||||
|
|
|
|||
|
|
@ -36,13 +36,20 @@
|
|||
|
||||
<ExpenseDialogList />
|
||||
|
||||
<ExpenseDialogForm v-if="!expense_store.current_expense.is_approved" />
|
||||
<q-icon
|
||||
v-else
|
||||
name="block"
|
||||
color="negative"
|
||||
size="lg"
|
||||
/>
|
||||
<transition
|
||||
appear
|
||||
enter-active-class="animated fadeInDown faster"
|
||||
leave-active-class="animated fadeOutDown faster"
|
||||
mode="out-in"
|
||||
>
|
||||
<ExpenseDialogForm v-if="!expense_store.current_expense.is_approved" />
|
||||
<q-icon
|
||||
v-else
|
||||
name="block"
|
||||
color="negative"
|
||||
size="lg"
|
||||
/>
|
||||
</transition>
|
||||
|
||||
<q-separator spaced />
|
||||
|
||||
|
|
|
|||
|
|
@ -46,10 +46,17 @@
|
|||
time_picker_model.value = time;
|
||||
};
|
||||
|
||||
const onBlurShiftTypeSelect = () => {
|
||||
if (shift_type_selected.value === undefined) {
|
||||
shift.value.shift_id = 0;
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
if (ui_store.focus_next_component) {
|
||||
select_ref.value?.focus();
|
||||
select_ref.value?.showPopup();
|
||||
shift_type_selected.value = undefined;
|
||||
ui_store.focus_next_component = false;
|
||||
}
|
||||
});
|
||||
|
|
@ -58,7 +65,8 @@
|
|||
<template>
|
||||
<div
|
||||
v-if="shift.shift_id !== 0"
|
||||
class="col row flex-center text-uppercase rounded-10"
|
||||
class="row col flex-center text-uppercase rounded-10"
|
||||
:class="$q.screen.lt.md ? 'q-pa-xs' : ''"
|
||||
>
|
||||
<!-- shift type -->
|
||||
<q-select
|
||||
|
|
@ -66,19 +74,22 @@
|
|||
v-model="shift_type_selected"
|
||||
standout="bg-blue-grey-9"
|
||||
dense
|
||||
options-dense
|
||||
:options-dense="!ui_store.is_mobile_mode"
|
||||
hide-dropdown-icon
|
||||
:menu-offset="[0, 10]"
|
||||
menu-anchor="bottom middle"
|
||||
menu-self="top middle"
|
||||
:options="options"
|
||||
class="rounded-5 q-mx-xs shadow-1"
|
||||
:class="ui_store.is_mobile_mode ? 'col-auto' : 'col'"
|
||||
class="rounded-5 shadow-1"
|
||||
:class="ui_store.is_mobile_mode ? 'col-auto q-mx-xs' : 'col q-mx-xs'"
|
||||
popup-content-class="text-uppercase text-weight-bold text-center rounded-5"
|
||||
popup-content-style="border: 2px solid var(--q-primary)"
|
||||
@blur="onBlurShiftTypeSelect"
|
||||
>
|
||||
<template #selected-item="scope">
|
||||
<div
|
||||
class="row text-weight-bold q-ma-none q-pa-none no-wrap ellipsis"
|
||||
:class="ui_store.is_mobile_mode ? 'items-center' : 'flex-center'"
|
||||
:class="ui_store.is_mobile_mode ? 'items-center full-height' : 'flex-center'"
|
||||
:tabindex="scope.tabindex"
|
||||
>
|
||||
<q-icon
|
||||
|
|
@ -96,7 +107,7 @@
|
|||
</template>
|
||||
</q-select>
|
||||
|
||||
<!-- punch-in timestamp -->
|
||||
<!-- punch in field -->
|
||||
<q-input
|
||||
v-model="shift.start_time"
|
||||
dense
|
||||
|
|
@ -127,7 +138,7 @@
|
|||
</template>
|
||||
</q-input>
|
||||
|
||||
<!-- punch-out timestamps -->
|
||||
<!-- punch out field -->
|
||||
<q-input
|
||||
v-model="shift.end_time"
|
||||
dense
|
||||
|
|
@ -169,7 +180,7 @@
|
|||
:name="shift.comment ? 'comment' : ''"
|
||||
color="primary"
|
||||
:size="dense ? 'xs' : 'sm'"
|
||||
class="col-auto q-pa-none q-mr-xs"
|
||||
class="col-auto q-pa-none"
|
||||
/>
|
||||
|
||||
<q-btn
|
||||
|
|
@ -178,7 +189,7 @@
|
|||
dense
|
||||
:icon="shift.comment ? 'chat' : 'chat_bubble_outline'"
|
||||
:text-color="shift.comment ? 'primary' : 'grey-8'"
|
||||
class="col-auto q-ma-none q-pl-md full-height"
|
||||
class="col-auto q-ma-none full-height"
|
||||
/>
|
||||
|
||||
<q-btn
|
||||
|
|
|
|||
|
|
@ -44,7 +44,10 @@
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<div :class="$q.screen.lt.md ? 'column' : 'row'">
|
||||
<div
|
||||
:class="$q.screen.lt.md ? 'column full-width' : 'row'"
|
||||
:style="$q.screen.lt.md ? 'width: 90vw !important;' : ''"
|
||||
>
|
||||
<div
|
||||
v-for="timesheet in timesheet_store.timesheets"
|
||||
:key="timesheet.timesheet_id"
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@
|
|||
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 ShiftListLegend from 'src/modules/timesheets/components/shift-list-legend.vue';
|
||||
import { useTimesheetStore } from 'src/stores/timesheet-store';
|
||||
import { useTimesheetApi } from 'src/modules/timesheets/composables/use-timesheet-api';
|
||||
import { useExpensesStore } from 'src/stores/expense-store';
|
||||
|
|
|
|||
|
|
@ -4,44 +4,45 @@ export const EXPENSE_TYPE: ExpenseType[] = ['PER_DIEM', 'MILEAGE', 'EXPENSES', '
|
|||
export const TYPES_WITH_MILEAGE_ONLY: Readonly<ExpenseType[]> = ['MILEAGE'];
|
||||
export const TYPES_WITH_AMOUNT_ONLY: Readonly<ExpenseType[]> = ['PER_DIEM', 'EXPENSES', 'ON_CALL',];
|
||||
|
||||
export interface Expense {
|
||||
id: number;
|
||||
date: string; //YYYY-MM-DD
|
||||
type: ExpenseType;
|
||||
amount: number;
|
||||
mileage?: number;
|
||||
comment: string;
|
||||
export class Expense {
|
||||
id: number;
|
||||
date: string; //YYYY-MM-DD
|
||||
type: ExpenseType;
|
||||
amount: number;
|
||||
mileage?: number;
|
||||
comment: string;
|
||||
supervisor_comment?: string;
|
||||
is_approved: boolean;
|
||||
|
||||
constructor() {
|
||||
this.id = -1;
|
||||
this.date = '';
|
||||
this.type = 'EXPENSES';
|
||||
this.amount = 0;
|
||||
this.comment = '';
|
||||
this.is_approved = false;
|
||||
};
|
||||
};
|
||||
|
||||
export const empty_expense: Expense = {
|
||||
id: -1,
|
||||
date: '',
|
||||
type: 'EXPENSES',
|
||||
amount: 0,
|
||||
comment: '',
|
||||
is_approved: false,
|
||||
};
|
||||
|
||||
export const test_expenses: Expense[] = [
|
||||
{
|
||||
id: 201,
|
||||
date: '2025-01-06',
|
||||
type: 'EXPENSES',
|
||||
amount: 15.5,
|
||||
comment: 'Lunch receipt',
|
||||
is_approved: false,
|
||||
},
|
||||
{
|
||||
id: 202,
|
||||
date: '2025-01-07',
|
||||
type: 'MILEAGE',
|
||||
amount: 0,
|
||||
mileage: 32.4,
|
||||
comment: 'Travel to client site',
|
||||
is_approved: true,
|
||||
},
|
||||
{
|
||||
id: 201,
|
||||
date: '2025-01-06',
|
||||
type: 'EXPENSES',
|
||||
amount: 15.5,
|
||||
comment: 'Lunch receipt',
|
||||
is_approved: false,
|
||||
},
|
||||
{
|
||||
id: 202,
|
||||
date: '2025-01-07',
|
||||
type: 'MILEAGE',
|
||||
amount: 0,
|
||||
mileage: 32.4,
|
||||
comment: 'Travel to client site',
|
||||
is_approved: true,
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ export const useAuthStore = defineStore('auth', () => {
|
|||
void handleAuthMessage(event);
|
||||
});
|
||||
|
||||
const oidc_popup = window.open(`${import.meta.env.VITE_TARGO_BACKEND_AUTH_URL}auth/v1/login`, 'authPopup', 'width=600,height=800');
|
||||
const oidc_popup = window.open(`${import.meta.env.VITE_TARGO_BACKEND_URL}auth/v1/login`, 'authPopup', 'width=600,height=800');
|
||||
|
||||
if (!oidc_popup)
|
||||
Notify.create({
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { ref } from "vue";
|
||||
import { defineStore } from "pinia";
|
||||
import { ExpensesApiError, type GenericApiError } from "src/modules/timesheets/models/expense-validation.models";
|
||||
import { empty_expense, test_expenses, type Expense } from "src/modules/timesheets/models/expense.models";
|
||||
import { test_expenses, Expense } from "src/modules/timesheets/models/expense.models";
|
||||
import { ExpenseService } from "src/modules/timesheets/services/expense-service";
|
||||
|
||||
|
||||
|
|
@ -9,9 +9,10 @@ import { ExpenseService } from "src/modules/timesheets/services/expense-service"
|
|||
export const useExpensesStore = defineStore('expenses', () => {
|
||||
const is_open = ref(false);
|
||||
const is_loading = ref(false);
|
||||
const mode = ref<'create' | 'update' | 'delete'>('create');
|
||||
const pay_period_expenses = ref<Expense[]>(test_expenses);
|
||||
const current_expense = ref<Expense>(empty_expense);
|
||||
const initial_expense = ref<Expense>(empty_expense);
|
||||
const current_expense = ref<Expense>(new Expense);
|
||||
const initial_expense = ref<Expense>(new Expense);
|
||||
const error = ref<string | null>(null);
|
||||
|
||||
// const setErrorFrom = (err: unknown) => {
|
||||
|
|
@ -21,13 +22,10 @@ export const useExpensesStore = defineStore('expenses', () => {
|
|||
|
||||
const open = (): void => {
|
||||
is_open.value = true;
|
||||
is_loading.value = true;
|
||||
error.value = null;
|
||||
current_expense.value = empty_expense;
|
||||
initial_expense.value = empty_expense;
|
||||
|
||||
// await getPayPeriodExpensesByTimesheetId(timesheet_id);
|
||||
is_loading.value = false;
|
||||
current_expense.value = new Expense;
|
||||
initial_expense.value = new Expense;
|
||||
mode.value = 'create';
|
||||
}
|
||||
|
||||
const close = () => {
|
||||
|
|
@ -80,6 +78,7 @@ export const useExpensesStore = defineStore('expenses', () => {
|
|||
return {
|
||||
is_open,
|
||||
is_loading,
|
||||
mode,
|
||||
pay_period_expenses,
|
||||
current_expense,
|
||||
initial_expense,
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user