Merge pull request 'dev/matthieu/csv' (#31) from dev/matthieu/csv into main
Reviewed-on: Targo/targo_frontend#31
This commit is contained in:
commit
11afa42b58
|
|
@ -137,6 +137,7 @@ export default {
|
||||||
update: "update",
|
update: "update",
|
||||||
modify: "modify",
|
modify: "modify",
|
||||||
close: "close",
|
close: "close",
|
||||||
|
download: "download",
|
||||||
},
|
},
|
||||||
misc: {
|
misc: {
|
||||||
or: "or",
|
or: "or",
|
||||||
|
|
@ -263,10 +264,12 @@ export default {
|
||||||
expenses_title: "expenses accrued",
|
expenses_title: "expenses accrued",
|
||||||
},
|
},
|
||||||
print_report: {
|
print_report: {
|
||||||
company: "company",
|
title: "Download options",
|
||||||
|
company: "companies",
|
||||||
type: "type",
|
type: "type",
|
||||||
shifts: "shifts",
|
shifts: "shifts",
|
||||||
expenses: "expenses",
|
expenses: "expenses",
|
||||||
|
options: "options",
|
||||||
},
|
},
|
||||||
tooltip: {
|
tooltip: {
|
||||||
button_detailed_view: "detailed view",
|
button_detailed_view: "detailed view",
|
||||||
|
|
|
||||||
|
|
@ -138,6 +138,7 @@ export default {
|
||||||
update: "mettre à jour",
|
update: "mettre à jour",
|
||||||
modify: "modifier",
|
modify: "modifier",
|
||||||
close: "fermer",
|
close: "fermer",
|
||||||
|
download: "téléchargement",
|
||||||
},
|
},
|
||||||
misc: {
|
misc: {
|
||||||
or: "ou",
|
or: "ou",
|
||||||
|
|
@ -264,10 +265,12 @@ export default {
|
||||||
expenses_title: "dépenses encourues"
|
expenses_title: "dépenses encourues"
|
||||||
},
|
},
|
||||||
print_report: {
|
print_report: {
|
||||||
company: "compagnie",
|
title: "options de téléchargement",
|
||||||
|
company: "compagnies",
|
||||||
type: "types de données",
|
type: "types de données",
|
||||||
shifts: "quarts de travail",
|
shifts: "quarts de travail",
|
||||||
expenses: "dépenses",
|
expenses: "dépenses",
|
||||||
|
options: "options",
|
||||||
},
|
},
|
||||||
tooltip: {
|
tooltip: {
|
||||||
button_detailed_view: "vue détaillée",
|
button_detailed_view: "vue détaillée",
|
||||||
|
|
|
||||||
|
|
@ -1,42 +1,37 @@
|
||||||
<script
|
<script setup lang="ts">
|
||||||
setup
|
/* eslint-disable */
|
||||||
lang="ts"
|
import { computed, ref } from 'vue';
|
||||||
>
|
import OverviewListItem from 'src/modules/timesheet-approval/components/overview-list-item.vue';
|
||||||
/* eslint-disable */
|
import LoadingOverlay from 'src/modules/shared/components/loading-overlay.vue';
|
||||||
import { computed, ref } from 'vue';
|
import { useTimesheetStore } from 'src/stores/timesheet-store';
|
||||||
import OverviewListItem from 'src/modules/timesheet-approval/components/overview-list-item.vue';
|
import { overview_column_names, pay_period_overview_columns, type TimesheetOverview } from 'src/modules/timesheet-approval/models/timesheet-overview.models';
|
||||||
import LoadingOverlay from 'src/modules/shared/components/loading-overlay.vue';
|
|
||||||
import { useExpensesStore } from 'src/stores/expense-store';
|
|
||||||
import { useTimesheetStore } from 'src/stores/timesheet-store';
|
|
||||||
import { useTimesheetApprovalApi } from 'src/modules/timesheet-approval/composables/use-timesheet-approval-api';
|
|
||||||
import { overview_column_names, pay_period_overview_columns, type TimesheetOverview } from 'src/modules/timesheet-approval/models/timesheet-overview.models';
|
|
||||||
|
|
||||||
const expenses_store = useExpensesStore();
|
const timesheet_store = useTimesheetStore();
|
||||||
const timesheet_store = useTimesheetStore();
|
|
||||||
const timesheet_approval_api = useTimesheetApprovalApi();
|
|
||||||
|
|
||||||
const visible_columns = ref<string[]>([
|
const visible_columns = ref<string[]>([
|
||||||
overview_column_names.REGULAR,
|
overview_column_names.REGULAR,
|
||||||
overview_column_names.EVENING,
|
overview_column_names.EVENING,
|
||||||
overview_column_names.EMERGENCY,
|
overview_column_names.EMERGENCY,
|
||||||
overview_column_names.SICK,
|
overview_column_names.SICK,
|
||||||
overview_column_names.VACATION,
|
overview_column_names.VACATION,
|
||||||
overview_column_names.HOLIDAY,
|
overview_column_names.HOLIDAY,
|
||||||
overview_column_names.OVERTIME,
|
overview_column_names.OVERTIME,
|
||||||
overview_column_names.IS_APPROVED,
|
overview_column_names.IS_APPROVED,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
const overview_rows = computed(() => timesheet_store.pay_period_overviews[0]?.regular_hours === -1 ?
|
||||||
|
[] :
|
||||||
|
timesheet_store.pay_period_overviews
|
||||||
|
)
|
||||||
|
|
||||||
|
const onClickedDetails = async (row: TimesheetOverview) => {
|
||||||
|
timesheet_store.current_pay_period_overview = row;
|
||||||
|
await timesheet_store.getTimesheetsByOptionalEmployeeEmail(row.email);
|
||||||
|
|
||||||
|
timesheet_store.is_details_dialog_open = true;
|
||||||
|
};
|
||||||
|
|
||||||
const overview_rows = computed(() => timesheet_store.pay_period_overviews[0]?.regular_hours === -1 ?
|
|
||||||
[] :
|
|
||||||
timesheet_store.pay_period_overviews
|
|
||||||
)
|
|
||||||
|
|
||||||
const onClickedDetails = async (row: TimesheetOverview) => {
|
|
||||||
timesheet_store.current_pay_period_overview = row;
|
|
||||||
await timesheet_store.getTimesheetsByOptionalEmployeeEmail(row.email);
|
|
||||||
|
|
||||||
timesheet_store.is_details_dialog_open = true;
|
|
||||||
};
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
|
||||||
|
|
@ -1,93 +1,144 @@
|
||||||
<script
|
<script setup lang="ts">
|
||||||
setup
|
import { computed, ref, watch } from 'vue';
|
||||||
lang="ts"
|
import { useTimesheetStore } from 'src/stores/timesheet-store';
|
||||||
>
|
import { TimesheetApprovalCSVReportFilters } from 'src/modules/timesheet-approval/models/timesheet-approval-csv-report.models';
|
||||||
import { default_timesheet_approval_cvs_report_filters, type TimesheetApprovalCSVReportFilters } from 'src/modules/timesheet-approval/models/timesheet-approval-csv-report.models';
|
|
||||||
import { ref, computed } from 'vue';
|
|
||||||
|
|
||||||
const report_filter_options = ref<TimesheetApprovalCSVReportFilters>(default_timesheet_approval_cvs_report_filters);
|
const timesheet_store = useTimesheetStore();
|
||||||
|
const report_filter_options = ref<TimesheetApprovalCSVReportFilters>(new TimesheetApprovalCSVReportFilters);
|
||||||
|
|
||||||
const company_options = [
|
const selected_report_filters = ref<(keyof TimesheetApprovalCSVReportFilters)[]>(
|
||||||
{ label: 'Targo', value: report_filter_options.value.companies.targo },
|
Object.entries(report_filter_options.value).filter(([_key, value]) => value).map(([key]) => key as keyof TimesheetApprovalCSVReportFilters)
|
||||||
{ label: 'Solucom', value: report_filter_options.value.companies.solucom },
|
);
|
||||||
];
|
|
||||||
|
|
||||||
const type_options = [
|
interface ReportOptions {
|
||||||
{ label: 'timesheet_approvals.print_report.shifts', value: report_filter_options.value.types.shifts },
|
label: string;
|
||||||
{ label: 'timesheet_approvals.print_report.expenses', value: report_filter_options.value.types.expenses },
|
value: keyof TimesheetApprovalCSVReportFilters;
|
||||||
{ label: 'shared.shift_type.holiday', value: report_filter_options.value.types.holiday },
|
};
|
||||||
{ label: 'shared.shift_type.vacation', value: report_filter_options.value.types.vacation },
|
|
||||||
];
|
|
||||||
|
|
||||||
const is_download_button_disabled = computed(() => {
|
const company_options: ReportOptions[] = [
|
||||||
return company_options.map(option => option.value).filter(value => value === true).length > 0 ||
|
{ label: 'Targo', value: 'targo' },
|
||||||
type_options.map(option => option.value).filter(value => value === true).length > 0;
|
{ label: 'Solucom', value: 'solucom' },
|
||||||
|
];
|
||||||
|
|
||||||
|
const type_options: ReportOptions[] = [
|
||||||
|
{ label: 'timesheet_approvals.print_report.shifts', value: 'shifts' },
|
||||||
|
{ label: 'timesheet_approvals.print_report.expenses', value: 'expenses' },
|
||||||
|
{ label: 'shared.shift_type.holiday', value: 'holiday' },
|
||||||
|
{ label: 'shared.shift_type.vacation', value: 'vacation' },
|
||||||
|
];
|
||||||
|
|
||||||
|
const is_download_button_enable = computed(() =>
|
||||||
|
company_options.map(option => option.value).some(option => selected_report_filters.value.includes(option)) &&
|
||||||
|
type_options.map(option => option.value).some(option => selected_report_filters.value.includes(option))
|
||||||
|
);
|
||||||
|
|
||||||
|
const onClickedDownload = async () => {
|
||||||
|
try {
|
||||||
|
const data = await timesheet_store.getPayPeriodReport(report_filter_options.value);
|
||||||
|
|
||||||
|
const companies = Object.entries(report_filter_options.value)
|
||||||
|
.filter(([key, value]) => value && (key === 'targo' || key === 'solucom')).map(([key]) => key).join('-');
|
||||||
|
|
||||||
|
const types = Object.entries(report_filter_options.value)
|
||||||
|
.filter(([key, value]) => value && ['shifts', 'expenses', 'holiday', 'vacation'].includes(key)).map(([key]) => key).join('-');
|
||||||
|
|
||||||
|
const file_name = `Desjardins_${companies}_${types}_${new Date().toISOString().split('T')[0]}.csv`;
|
||||||
|
|
||||||
|
const blob = new Blob([data], { type: 'text/csv;charset=utf-8;' });
|
||||||
|
const url = window.URL.createObjectURL(blob);
|
||||||
|
const link = document.createElement('a');
|
||||||
|
|
||||||
|
link.href = url;
|
||||||
|
link.setAttribute('download', file_name);
|
||||||
|
document.body.appendChild(link);
|
||||||
|
link.click();
|
||||||
|
document.body.removeChild(link);
|
||||||
|
window.URL.revokeObjectURL(url);
|
||||||
|
console.log('CSV preview:', data);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`An error occured during the CSV download: `, error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(selected_report_filters, (new_values) => {
|
||||||
|
Object.keys(report_filter_options.value).forEach(key => {
|
||||||
|
const typed_key = key as keyof TimesheetApprovalCSVReportFilters;
|
||||||
|
report_filter_options.value[typed_key] = new_values.includes(key as keyof TimesheetApprovalCSVReportFilters);
|
||||||
});
|
});
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<q-btn-group
|
<q-dialog v-model="timesheet_store.is_report_dialog_open">
|
||||||
rounded
|
<div class="bg-secondary full-width shadow-24 rounded-10 column">
|
||||||
push
|
<div class="shadow-1 bg-primary text-accent text-weight-bold text-center text-uppercase">
|
||||||
>
|
<span> {{ $t('timesheet_approvals.print_report.title') }}</span>
|
||||||
<q-btn
|
</div>
|
||||||
rounded
|
<div class="row q-py-md q-px-lg">
|
||||||
push
|
<div class="col-auto full-width shadow-1 row bg-dark q-py-xs q-px-lg rounded-10">
|
||||||
color="primary"
|
<span class="col q-px-sm q-pt-xs text-weight-bolder text-accent text-uppercase col-3">
|
||||||
icon="print"
|
|
||||||
:disable="is_download_button_disabled"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<q-btn-dropdown
|
|
||||||
rounded
|
|
||||||
push
|
|
||||||
color="white"
|
|
||||||
text-color="primary"
|
|
||||||
icon="checklist"
|
|
||||||
>
|
|
||||||
<q-list class="row">
|
|
||||||
<q-item class="col">
|
|
||||||
<q-item-label class="text-weight-bolder text-primary q-ma-none q-pa-none text-uppercase">
|
|
||||||
{{ $t('timesheet_approvals.print_report.company') }}
|
{{ $t('timesheet_approvals.print_report.company') }}
|
||||||
</q-item-label>
|
</span>
|
||||||
|
<div class="row bordered-primary col-auto full-width">
|
||||||
<q-item-section
|
<div
|
||||||
row
|
v-for="company, index in company_options"
|
||||||
no-wrap
|
|
||||||
>
|
|
||||||
<q-checkbox
|
|
||||||
v-for="option, index in company_options"
|
|
||||||
:key="index"
|
:key="index"
|
||||||
v-model="option.value"
|
class="q-pa-xs col-6"
|
||||||
:val="option.label"
|
>
|
||||||
:label="option.label"
|
<q-checkbox
|
||||||
/>
|
v-model="selected_report_filters"
|
||||||
</q-item-section>
|
left-label
|
||||||
</q-item>
|
color="white"
|
||||||
|
class="q-px-md shadow-4 rounded-25 full-width"
|
||||||
<q-separator
|
dense
|
||||||
spaced
|
:class="selected_report_filters.includes(company.value) ? 'bg-accent text-white' : 'bg-dark'"
|
||||||
vertical
|
:label="$t(company.label)"
|
||||||
color="primary"
|
:val="company.value"
|
||||||
|
checked-icon="download"
|
||||||
|
unchecked-icon="highlight_off"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row q-py-md">
|
||||||
|
<div class="col-auto full-width shadow-1 row bg-dark q-px-lg rounded-10 q-pb-sm">
|
||||||
|
<span class="col q-px-sm q-pt-xs text-weight-bolder text-accent text-uppercase col-3">
|
||||||
|
{{ $t('timesheet_approvals.print_report.options') }}
|
||||||
|
</span>
|
||||||
|
<div class=" row bordered-primary col-auto full-width">
|
||||||
|
<div
|
||||||
|
v-for="type, index in type_options"
|
||||||
|
:key="index"
|
||||||
|
class="q-pa-xs col-6"
|
||||||
|
>
|
||||||
|
<q-checkbox
|
||||||
|
v-model="selected_report_filters"
|
||||||
|
left-label
|
||||||
|
color="white"
|
||||||
|
class="q-px-md shadow-4 rounded-25 full-width"
|
||||||
|
dense
|
||||||
|
:class="selected_report_filters.includes(type.value) ? 'bg-accent text-white' : 'bg-dark'"
|
||||||
|
:label="$t(type.label)"
|
||||||
|
:val="type.value"
|
||||||
|
checked-icon="download"
|
||||||
|
unchecked-icon="highlight_off"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="column">
|
||||||
|
<q-btn
|
||||||
|
:disable="!is_download_button_enable"
|
||||||
|
square
|
||||||
|
size="md"
|
||||||
|
icon="download"
|
||||||
|
:color="is_download_button_enable ? 'accent' : 'grey-5'"
|
||||||
|
:label="$t('shared.label.download')"
|
||||||
|
@click="onClickedDownload()"
|
||||||
/>
|
/>
|
||||||
|
</div>
|
||||||
<q-item class="col">
|
</div>
|
||||||
<q-item-section
|
</q-dialog>
|
||||||
row
|
</template>
|
||||||
no-wrap
|
|
||||||
>
|
|
||||||
<p class="text-weight-bolder text-primary q-ma-none q-pa-none text-uppercase">
|
|
||||||
{{ $t('timesheet_approvals.print_report.type') }}</p>
|
|
||||||
<q-checkbox
|
|
||||||
v-for="option, index in type_options"
|
|
||||||
:key="index"
|
|
||||||
v-model="option.value"
|
|
||||||
:val="option.label"
|
|
||||||
:label="option.label"
|
|
||||||
/>
|
|
||||||
</q-item-section>
|
|
||||||
</q-item>
|
|
||||||
</q-list>
|
|
||||||
</q-btn-dropdown>
|
|
||||||
</q-btn-group>
|
|
||||||
</template>
|
|
||||||
|
|
|
||||||
|
|
@ -26,21 +26,16 @@ export const useTimesheetApprovalApi = () => {
|
||||||
timesheet_store.is_loading = false;
|
timesheet_store.is_loading = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
const getTimesheetApprovalCSVReport = async (report_filter_company: boolean[], report_filter_type: boolean[], year?: number, period_number?: number) => {
|
const getTimesheetApprovalCSVReport = async (report_filter_company: boolean[], report_filter_type: boolean[]) => {
|
||||||
if (timesheet_store.pay_period === undefined) return;
|
if (timesheet_store.pay_period === undefined) return;
|
||||||
|
|
||||||
const [targo, solucom] = report_filter_company;
|
const [targo, solucom] = report_filter_company;
|
||||||
const [shifts, expenses, holiday, vacation] = report_filter_type;
|
const [shifts, expenses, holiday, vacation] = report_filter_type;
|
||||||
const options = {
|
const options = {
|
||||||
types: { shifts, expenses, holiday, vacation },
|
shifts, expenses, holiday, vacation, targo, solucom
|
||||||
companies: { targo, solucom },
|
|
||||||
} as TimesheetApprovalCSVReportFilters;
|
} as TimesheetApprovalCSVReportFilters;
|
||||||
|
|
||||||
await timesheet_store.getPayPeriodReportByYearAndPeriodNumber(
|
await timesheet_store.getPayPeriodReport(options);
|
||||||
year ?? timesheet_store.pay_period.pay_year,
|
|
||||||
period_number ?? timesheet_store.pay_period.pay_period_no,
|
|
||||||
options
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
||||||
|
|
@ -1,25 +1,18 @@
|
||||||
export interface TimesheetApprovalCSVReportFilters {
|
export class TimesheetApprovalCSVReportFilters {
|
||||||
types: {
|
shifts: boolean;
|
||||||
shifts: boolean;
|
expenses: boolean;
|
||||||
expenses: boolean;
|
holiday: boolean;
|
||||||
holiday: boolean;
|
vacation: boolean;
|
||||||
vacation: boolean;
|
targo: boolean;
|
||||||
};
|
solucom: boolean;
|
||||||
companies: {
|
|
||||||
targo: boolean;
|
constructor() {
|
||||||
solucom: boolean;
|
this.shifts = true;
|
||||||
|
this.expenses = true;
|
||||||
|
this.holiday = false;
|
||||||
|
this.vacation = false;
|
||||||
|
this.targo = true;
|
||||||
|
this.solucom = true;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export const default_timesheet_approval_cvs_report_filters: TimesheetApprovalCSVReportFilters = {
|
|
||||||
types: {
|
|
||||||
shifts: true,
|
|
||||||
expenses: true,
|
|
||||||
holiday: true,
|
|
||||||
vacation: true,
|
|
||||||
},
|
|
||||||
companies: {
|
|
||||||
targo: true,
|
|
||||||
solucom: true,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
@ -4,12 +4,12 @@ import type { PayPeriodOverviewResponse } from "src/modules/timesheet-approval/m
|
||||||
|
|
||||||
export const timesheetApprovalService = {
|
export const timesheetApprovalService = {
|
||||||
getPayPeriodOverviews: async (year: number, period_number: number): Promise<PayPeriodOverviewResponse> => {
|
getPayPeriodOverviews: async (year: number, period_number: number): Promise<PayPeriodOverviewResponse> => {
|
||||||
const response = await api.get<{success: boolean, data: PayPeriodOverviewResponse, error? : string}>(`pay-periods/overview/${year}/${period_number}`);
|
const response = await api.get<{ success: boolean, data: PayPeriodOverviewResponse, error?: string }>(`pay-periods/overview/${year}/${period_number}`);
|
||||||
return response.data.data;
|
return response.data.data;
|
||||||
},
|
},
|
||||||
|
|
||||||
getPayPeriodReportByYearAndPeriodNumber: async (year: number, period_number: number, report_filters?: TimesheetApprovalCSVReportFilters) => {
|
getPayPeriodReportByYearAndPeriodNumber: async (year: number, period_number: number, filters?: TimesheetApprovalCSVReportFilters) => {
|
||||||
const response = await api.get(`csv/${year}/${period_number}`, { params: { report_filters, }});
|
const response = await api.get(`exports/csv/${year}/${period_number}`, { params: filters, responseType: 'arraybuffer' });
|
||||||
return response.data;
|
return response;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
@ -1,24 +1,22 @@
|
||||||
<script
|
<script setup lang="ts">
|
||||||
setup
|
/* eslint-disable */
|
||||||
lang="ts"
|
import { onMounted } from 'vue';
|
||||||
>
|
import { date } from 'quasar';
|
||||||
/* eslint-disable */
|
import { useTimesheetApprovalApi } from 'src/modules/timesheet-approval/composables/use-timesheet-approval-api';
|
||||||
import { onMounted, ref } from 'vue';
|
import { useTimesheetStore } from 'src/stores/timesheet-store';
|
||||||
import { date } from 'quasar';
|
import PageHeaderTemplate from 'src/modules/shared/components/page-header-template.vue';
|
||||||
import { useTimesheetApprovalApi } from 'src/modules/timesheet-approval/composables/use-timesheet-approval-api';
|
import OverviewList from 'src/modules/timesheet-approval/components/overview-list.vue';
|
||||||
import { useTimesheetStore } from 'src/stores/timesheet-store';
|
import DetailsDialog from 'src/modules/timesheet-approval/components/details-dialog.vue';
|
||||||
import PageHeaderTemplate from 'src/modules/shared/components/page-header-template.vue';
|
import QTableFilters from 'src/modules/shared/components/q-table-filters.vue';
|
||||||
import OverviewList from 'src/modules/timesheet-approval/components/overview-list.vue';
|
import PayPeriodNavigator from 'src/modules/shared/components/pay-period-navigator.vue';
|
||||||
import DetailsDialog from 'src/modules/timesheet-approval/components/details-dialog.vue';
|
import OverviewReport from 'src/modules/timesheet-approval/components/overview-report.vue';
|
||||||
import QTableFilters from 'src/modules/shared/components/q-table-filters.vue';
|
|
||||||
import PayPeriodNavigator from 'src/modules/shared/components/pay-period-navigator.vue';
|
|
||||||
|
|
||||||
const timesheet_approval_api = useTimesheetApprovalApi();
|
const timesheet_approval_api = useTimesheetApprovalApi();
|
||||||
const timesheet_store = useTimesheetStore();
|
const timesheet_store = useTimesheetStore();
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
await timesheet_approval_api.getTimesheetOverviewsByDate(date.formatDate(new Date(), 'YYYY-MM-DD'));
|
await timesheet_approval_api.getTimesheetOverviewsByDate(date.formatDate(new Date(), 'YYYY-MM-DD'));
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
@ -66,20 +64,23 @@
|
||||||
]"
|
]"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div class="col-auto row no-wrap flex-center" :class="$q.screen.lt.md ? 'q-mb-md' : ''">
|
<div
|
||||||
<q-btn-dropdown
|
class="col-auto row no-wrap flex-center"
|
||||||
|
:class="$q.screen.lt.md ? 'q-mb-md' : ''"
|
||||||
|
>
|
||||||
|
<q-btn
|
||||||
push
|
push
|
||||||
rounded
|
rounded
|
||||||
icon="filter_alt"
|
icon="download"
|
||||||
color="accent"
|
color="accent"
|
||||||
:label="$q.screen.lt.md ? '' : $t('shared.label.filter')"
|
:label="$q.screen.lt.md ? '' : $t('shared.label.download')"
|
||||||
class="col-auto q-mr-sm"
|
class="col-auto q-mr-sm"
|
||||||
|
@click="timesheet_store.is_report_dialog_open = true"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<QTableFilters v-model:search="timesheet_store.search_filter" />
|
<QTableFilters v-model:search="timesheet_store.search_filter" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<OverviewReport/>
|
||||||
<OverviewList class="col" />
|
<OverviewList class="col" />
|
||||||
</q-page>
|
</q-page>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -3,7 +3,7 @@ import { defineStore } from 'pinia';
|
||||||
import { unwrapAndClone } from 'src/utils/unwrap-and-clone';
|
import { unwrapAndClone } from 'src/utils/unwrap-and-clone';
|
||||||
import { timesheetApprovalService } from 'src/modules/timesheet-approval/services/timesheet-approval-service';
|
import { timesheetApprovalService } from 'src/modules/timesheet-approval/services/timesheet-approval-service';
|
||||||
import { timesheetService } from 'src/modules/timesheets/services/timesheet-service';
|
import { timesheetService } from 'src/modules/timesheets/services/timesheet-service';
|
||||||
import type { TimesheetOverview } from "src/modules/timesheet-approval/models/timesheet-overview.models";
|
import type { PayPeriodOverviewResponse, TimesheetOverview } from "src/modules/timesheet-approval/models/timesheet-overview.models";
|
||||||
import type { PayPeriod } from 'src/modules/shared/models/pay-period.models';
|
import type { PayPeriod } from 'src/modules/shared/models/pay-period.models';
|
||||||
import type { Timesheet } from 'src/modules/timesheets/models/timesheet.models';
|
import type { Timesheet } from 'src/modules/timesheets/models/timesheet.models';
|
||||||
import type { TimesheetApprovalCSVReportFilters } from 'src/modules/timesheet-approval/models/timesheet-approval-csv-report.models';
|
import type { TimesheetApprovalCSVReportFilters } from 'src/modules/timesheet-approval/models/timesheet-approval-csv-report.models';
|
||||||
|
|
@ -15,9 +15,11 @@ export const useTimesheetStore = defineStore('timesheet', () => {
|
||||||
const timesheets = ref<Timesheet[]>([]);
|
const timesheets = ref<Timesheet[]>([]);
|
||||||
const all_current_shifts = computed(() => timesheets.value.flatMap(week => week.days.flatMap(day => day.shifts)) ?? []);
|
const all_current_shifts = computed(() => timesheets.value.flatMap(week => week.days.flatMap(day => day.shifts)) ?? []);
|
||||||
const initial_timesheets = ref<Timesheet[]>([]);
|
const initial_timesheets = ref<Timesheet[]>([]);
|
||||||
|
|
||||||
const pay_period_overviews = ref<TimesheetOverview[]>([]);
|
const pay_period_overviews = ref<TimesheetOverview[]>([]);
|
||||||
|
const pay_period_infos = ref<PayPeriodOverviewResponse>();
|
||||||
|
const is_report_dialog_open = ref(false);
|
||||||
|
|
||||||
const is_details_dialog_open = ref(false);
|
const is_details_dialog_open = ref(false);
|
||||||
const selected_employee_name = ref<string>();
|
const selected_employee_name = ref<string>();
|
||||||
const current_pay_period_overview = ref<TimesheetOverview>();
|
const current_pay_period_overview = ref<TimesheetOverview>();
|
||||||
|
|
@ -93,15 +95,12 @@ export const useTimesheetStore = defineStore('timesheet', () => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const getPayPeriodReportByYearAndPeriodNumber = async (year: number, period_number: number, report_filters?: TimesheetApprovalCSVReportFilters) => {
|
const getPayPeriodReport = async (report_filters: TimesheetApprovalCSVReportFilters) => {
|
||||||
try {
|
try {
|
||||||
const response = await timesheetApprovalService.getPayPeriodReportByYearAndPeriodNumber(
|
if (!pay_period.value) return false;
|
||||||
year,
|
const response = await timesheetApprovalService.getPayPeriodReportByYearAndPeriodNumber(pay_period.value.pay_year, pay_period.value.pay_period_no, report_filters);
|
||||||
period_number,
|
|
||||||
report_filters
|
|
||||||
);
|
|
||||||
pay_period_report.value = response;
|
pay_period_report.value = response;
|
||||||
return true;
|
return response.data;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('There was an error retrieving the report CSV: ', error);
|
console.error('There was an error retrieving the report CSV: ', error);
|
||||||
// TODO: More in-depth error-handling here
|
// TODO: More in-depth error-handling here
|
||||||
|
|
@ -110,14 +109,28 @@ export const useTimesheetStore = defineStore('timesheet', () => {
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const openReportDialog = () => {
|
||||||
|
is_report_dialog_open.value = true;
|
||||||
|
is_loading.value = true;
|
||||||
|
|
||||||
|
|
||||||
|
is_loading.value = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
const closeReportDialog = () => {
|
||||||
|
is_report_dialog_open.value = false;
|
||||||
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
is_loading,
|
is_loading,
|
||||||
|
is_report_dialog_open,
|
||||||
is_approval_grid_mode,
|
is_approval_grid_mode,
|
||||||
is_details_dialog_open,
|
is_details_dialog_open,
|
||||||
search_filter,
|
search_filter,
|
||||||
pay_period,
|
pay_period,
|
||||||
pay_period_overviews,
|
pay_period_overviews,
|
||||||
current_pay_period_overview,
|
current_pay_period_overview,
|
||||||
|
pay_period_infos,
|
||||||
selected_employee_name,
|
selected_employee_name,
|
||||||
timesheets,
|
timesheets,
|
||||||
all_current_shifts,
|
all_current_shifts,
|
||||||
|
|
@ -125,6 +138,8 @@ export const useTimesheetStore = defineStore('timesheet', () => {
|
||||||
getPayPeriodByDateOrYearAndNumber,
|
getPayPeriodByDateOrYearAndNumber,
|
||||||
getTimesheetOverviews,
|
getTimesheetOverviews,
|
||||||
getTimesheetsByOptionalEmployeeEmail,
|
getTimesheetsByOptionalEmployeeEmail,
|
||||||
getPayPeriodReportByYearAndPeriodNumber,
|
getPayPeriodReport,
|
||||||
|
openReportDialog,
|
||||||
|
closeReportDialog,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
25
src/utils/boolean-utils.ts
Normal file
25
src/utils/boolean-utils.ts
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
// export const createDefaultBooleanValue = <T extends PropertyKey>(keys_list: PropertyKey[]): Record<T, boolean> =>
|
||||||
|
// keys_list.reduce((acc, mod) => {
|
||||||
|
// acc[mod] = false;
|
||||||
|
// return acc;
|
||||||
|
// }, {} as Record<T, boolean>);
|
||||||
|
|
||||||
|
|
||||||
|
// export const toBooleanFromKeys = <T extends PropertyKey>(keys_list: PropertyKey[], arr?: readonly PropertyKey[] | null): Record<T, boolean> => {
|
||||||
|
// const result = createDefaultBooleanValue(keys_list);
|
||||||
|
// if (!arr || !Array.isArray(arr)) return result;
|
||||||
|
// for (const item of arr) {
|
||||||
|
// if (typeof item !== 'string') continue;
|
||||||
|
// const trimmed = item.trim();
|
||||||
|
// if ((keys_list as readonly PropertyKey[]).includes(trimmed)) {
|
||||||
|
// result[trimmed as T] = true;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// return result;
|
||||||
|
// }
|
||||||
|
|
||||||
|
export const toKeysFromBoolean = <T extends PropertyKey>(boolean_values: Record<T, boolean>): T[] => {
|
||||||
|
const values_array = Object.entries(boolean_values);
|
||||||
|
const values = values_array.filter(([_key, value]) => value === true);
|
||||||
|
return values.map(([key]) => key as T);
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user