Merge branch 'dev/nicolas/timesheet-approval-staging-prep' of git.targo.ca:Targo/targo_frontend into dev/nicolas/timesheet-approval-staging-prep
This commit is contained in:
commit
f66934cc4f
BIN
src/assets/facturation_thumbnail.png
Normal file
BIN
src/assets/facturation_thumbnail.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.9 KiB |
BIN
src/assets/targo_building.png
Normal file
BIN
src/assets/targo_building.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 618 KiB |
|
|
@ -8,28 +8,26 @@
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<div class="column text-weight-medium">
|
||||
<q-separator
|
||||
color="accent"
|
||||
size="5px"
|
||||
class="col-auto"
|
||||
/>
|
||||
|
||||
<div class="column bg-primary text-uppercase">
|
||||
<div class="col row">
|
||||
<q-checkbox
|
||||
v-model="filters.is_showing_inactive"
|
||||
keep-color
|
||||
size="lg"
|
||||
color="accent"
|
||||
label="show inactive"
|
||||
class="col"
|
||||
:class="filters.is_showing_inactive ? 'text-accent text-weight-bolder' : 'text-white text-weight-medium'"
|
||||
/>
|
||||
<q-checkbox
|
||||
v-model="filters.is_showing_team_only"
|
||||
keep-color
|
||||
size="lg"
|
||||
val="team"
|
||||
color="accent"
|
||||
label="show team only"
|
||||
class="col"
|
||||
:class="filters.is_showing_team_only ? 'text-accent text-weight-bolder' : 'text-white text-weight-medium'"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -2,17 +2,17 @@
|
|||
setup
|
||||
lang="ts"
|
||||
>
|
||||
import type { TimesheetOverview } from 'src/modules/timesheet-approval/models/timesheet-overview.models';
|
||||
import type { TimesheetApprovalOverview } from 'src/modules/timesheet-approval/models/timesheet-overview.models';
|
||||
|
||||
const modelApproval = defineModel<boolean>();
|
||||
|
||||
const { row, index = 0 } = defineProps<{
|
||||
row: TimesheetOverview;
|
||||
row: TimesheetApprovalOverview;
|
||||
index?: number;
|
||||
}>();
|
||||
|
||||
const emit = defineEmits<{
|
||||
'clickDetails': [overview: TimesheetOverview];
|
||||
'clickDetails': [overview: TimesheetApprovalOverview];
|
||||
'clickApprovalAll' : [is_approved: boolean];
|
||||
}>();
|
||||
|
||||
|
|
@ -37,7 +37,7 @@
|
|||
>
|
||||
<q-card
|
||||
class="rounded-10 shadow-5"
|
||||
:style="`animation-delay: ${index / 15}s; opacity: ${row.is_active ? '1' : '0.5'}; transform: scale(${row.is_active ? '1' : '0.9'})`"
|
||||
:style="`animation-delay: ${index / 15}s; opacity: ${row.is_active ? '1' : '0.75'}; transform: scale(${row.is_active ? '1' : '0.9'})`"
|
||||
>
|
||||
<!-- Card header with employee name and details button-->
|
||||
<q-card-section
|
||||
|
|
@ -49,9 +49,9 @@
|
|||
class="text-h5 text-uppercase text-weight-medium q-mr-xs"
|
||||
:class="row.is_active ? 'text-accent' : 'text-negative'"
|
||||
>
|
||||
{{ row.employee_name.split(' ')[0] }}
|
||||
{{ row.employee_first_name }}
|
||||
</span>
|
||||
<span class="text-uppercase text-weight-light">{{ row.employee_name.split(' ')[1] }}</span>
|
||||
<span class="text-uppercase text-weight-light">{{ row.employee_last_name }}</span>
|
||||
</div>
|
||||
|
||||
<!-- Buttons to view detailed shifts or view employee timesheet -->
|
||||
|
|
|
|||
|
|
@ -10,11 +10,13 @@
|
|||
import OverviewListFilters from 'src/modules/timesheet-approval/components/overview-list-filters.vue';
|
||||
|
||||
import { computed, ref } from 'vue';
|
||||
import { useAuthStore } from 'src/stores/auth-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, PayPeriodOverviewFilters, type TimesheetOverview } from 'src/modules/timesheet-approval/models/timesheet-overview.models';
|
||||
import { overview_column_names, pay_period_overview_columns, PayPeriodOverviewFilters, type TimesheetApprovalOverview } from 'src/modules/timesheet-approval/models/timesheet-overview.models';
|
||||
|
||||
|
||||
const auth_store = useAuthStore();
|
||||
const timesheet_store = useTimesheetStore();
|
||||
const timesheet_approval_api = useTimesheetApprovalApi();
|
||||
|
||||
|
|
@ -39,7 +41,7 @@
|
|||
name_search_string: search_string.value,
|
||||
});
|
||||
|
||||
const onClickedDetails = async (row: TimesheetOverview) => {
|
||||
const onClickedDetails = async (row: TimesheetApprovalOverview) => {
|
||||
timesheet_store.current_pay_period_overview = row;
|
||||
await timesheet_store.getTimesheetsByOptionalEmployeeEmail(row.email);
|
||||
|
||||
|
|
@ -50,16 +52,23 @@
|
|||
await timesheet_approval_api.toggleTimesheetsApprovalByEmployeeEmail(email, is_approved);
|
||||
}
|
||||
|
||||
const filterEmployeeRows = (rows: readonly TimesheetOverview[], terms: PayPeriodOverviewFilters): TimesheetOverview[] => {
|
||||
const filterEmployeeRows = (rows: readonly TimesheetApprovalOverview[], terms: PayPeriodOverviewFilters): TimesheetApprovalOverview[] => {
|
||||
let result = [...rows];
|
||||
|
||||
if (!terms.is_showing_inactive) {
|
||||
result = result.filter(row => row.is_active);
|
||||
}
|
||||
|
||||
// if (terms.name_search_string) {
|
||||
// result = result.filter(row => row.employee_name.includes(terms.name_search_string ?? ''));
|
||||
// }
|
||||
if (terms.is_showing_team_only) {
|
||||
result = result.filter(row => row.supervisor !== null && row.supervisor.email === (auth_store.user ? auth_store.user.email : '') );
|
||||
}
|
||||
|
||||
if (terms.name_search_string.length > 0) {
|
||||
const search_words = terms.name_search_string.trim().split(' ');
|
||||
search_words.map(word => result = result.filter(row =>
|
||||
row.employee_first_name.includes(word ?? '') || row.employee_last_name.includes(word ?? '')
|
||||
));
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
|
@ -110,9 +119,9 @@
|
|||
:class="$q.platform.is.mobile ? 'q-mb-sm' : ''"
|
||||
style="height: 40px;"
|
||||
/>
|
||||
|
||||
|
||||
<q-space />
|
||||
|
||||
|
||||
<div
|
||||
class="col-auto row no-wrap items-start"
|
||||
:class="$q.platform.is.mobile ? 'q-mb-md' : ''"
|
||||
|
|
@ -132,7 +141,7 @@
|
|||
]"
|
||||
style="height: 40px;"
|
||||
/>
|
||||
|
||||
|
||||
<q-btn
|
||||
push
|
||||
rounded
|
||||
|
|
@ -143,24 +152,24 @@
|
|||
style="height: 40px;"
|
||||
@click="timesheet_store.is_report_dialog_open = true"
|
||||
/>
|
||||
|
||||
|
||||
<QTableFilters
|
||||
v-model:search="search_string"
|
||||
class="col-auto q-mb-xs"
|
||||
class="col-auto q-mb-sm"
|
||||
/>
|
||||
|
||||
|
||||
<q-btn
|
||||
flat
|
||||
icon="filter_alt"
|
||||
color="white"
|
||||
:label="$q.platform.is.mobile ? '' : $t('shared.label.filter')"
|
||||
class="col q-ml-sm self-stretch bg-accent"
|
||||
class="col q-ml-sm self-stretch bg-primary"
|
||||
style="border-radius: 5px 5px 0 0;"
|
||||
@click="is_showing_filters = !is_showing_filters"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<q-slide-transition>
|
||||
<OverviewListFilters
|
||||
v-if="is_showing_filters"
|
||||
|
|
@ -168,11 +177,11 @@
|
|||
class="q-mx-lg col-auto"
|
||||
/>
|
||||
</q-slide-transition>
|
||||
|
||||
|
||||
<q-separator
|
||||
color="accent"
|
||||
color="primary"
|
||||
size="5px"
|
||||
class="q-mx-lg"
|
||||
class="q-mx-lg q-my-none q-pa-none"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -233,7 +242,7 @@
|
|||
{{ props.value.split(' ')[0] }}
|
||||
</span>
|
||||
<span class="text-uppercase text-weight-light">{{ props.value.split(' ')[1]
|
||||
}}</span>
|
||||
}}</span>
|
||||
</div>
|
||||
<span v-else>{{ props.value }}</span>
|
||||
</div>
|
||||
|
|
@ -242,7 +251,7 @@
|
|||
</template>
|
||||
|
||||
<!-- Template for individual employee cards -->
|
||||
<template #item="props: { row: TimesheetOverview, rowIndex: number }">
|
||||
<template #item="props: { row: TimesheetApprovalOverview, rowIndex: number }">
|
||||
<OverviewListItem
|
||||
v-model="props.row.is_approved"
|
||||
:key="props.row.email + timesheet_store.pay_period?.pay_period_no"
|
||||
|
|
|
|||
|
|
@ -1,8 +1,14 @@
|
|||
import type { QTableColumn } from "quasar";
|
||||
|
||||
export class TimesheetOverview {
|
||||
export class TimesheetApprovalOverview {
|
||||
email: string;
|
||||
employee_name: string;
|
||||
employee_first_name: string;
|
||||
employee_last_name: string;
|
||||
supervisor: {
|
||||
first_name: string;
|
||||
last_name: string;
|
||||
email: string;
|
||||
} | null;
|
||||
is_active: boolean;
|
||||
regular_hours: number;
|
||||
other_hours: {
|
||||
|
|
@ -20,7 +26,9 @@ export class TimesheetOverview {
|
|||
|
||||
constructor() {
|
||||
this.email = '';
|
||||
this.employee_name = 'John Doe';
|
||||
this.employee_first_name = 'Unknown';
|
||||
this.employee_last_name = 'Unknown';
|
||||
this.supervisor = null;
|
||||
this.is_active = true;
|
||||
this.regular_hours = 0;
|
||||
this.other_hours = {
|
||||
|
|
@ -45,14 +53,14 @@ export interface PayPeriodOverviewResponse {
|
|||
period_end: string;
|
||||
payday: string;
|
||||
label: string;
|
||||
employees_overview: TimesheetOverview[];
|
||||
employees_overview: TimesheetApprovalOverview[];
|
||||
}
|
||||
|
||||
export interface PayPeriodOverviewFilters {
|
||||
is_showing_inactive: boolean;
|
||||
is_showing_team_only: boolean;
|
||||
supervisors: string[];
|
||||
name_search_string: string | number | null;
|
||||
name_search_string: string;
|
||||
}
|
||||
|
||||
export const overview_column_names = {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { api } from "src/boot/axios";
|
||||
import type { PayPeriod } from "src/modules/shared/models/pay-period.models";
|
||||
import type { TimesheetResponse } from "src/modules/timesheets/models/timesheet.models";
|
||||
import type { TimesheetOverview } from "src/modules/timesheet-approval/models/timesheet-overview.models";
|
||||
import type { TimesheetApprovalOverview } from "src/modules/timesheet-approval/models/timesheet-overview.models";
|
||||
import type { BackendResponse } from "src/modules/shared/models/backend-response.models";
|
||||
|
||||
export const timesheetService = {
|
||||
|
|
@ -15,8 +15,8 @@ export const timesheetService = {
|
|||
return response.data.data;
|
||||
},
|
||||
|
||||
getTimesheetOverviewsByPayPeriodAndSupervisorEmail: async (year: number, period_number: number, supervisor_email: string): Promise<TimesheetOverview[]> => {
|
||||
const response = await api.get<{ success: boolean, data: TimesheetOverview[], error?: string }>(`pay-periods/${year}/${period_number}/${supervisor_email}`);
|
||||
getTimesheetOverviewsByPayPeriodAndSupervisorEmail: async (year: number, period_number: number, supervisor_email: string): Promise<TimesheetApprovalOverview[]> => {
|
||||
const response = await api.get<{ success: boolean, data: TimesheetApprovalOverview[], error?: string }>(`pay-periods/${year}/${period_number}/${supervisor_email}`);
|
||||
return response.data.data;
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -3,11 +3,6 @@
|
|||
lang="ts"
|
||||
>
|
||||
import { ref } from 'vue';
|
||||
import { Notify } from 'quasar';
|
||||
|
||||
const click_number = ref(1);
|
||||
const icon = ref('las la-hand-peace');
|
||||
const color = ref('accent');
|
||||
|
||||
const LOREM_IPSUM = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et \
|
||||
dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip \
|
||||
|
|
@ -16,34 +11,19 @@
|
|||
deserunt mollit anim id est laborum."
|
||||
|
||||
const slide = ref<string>('welcome');
|
||||
|
||||
const clickNotify = () => {
|
||||
if (click_number.value % 7 === 0) {
|
||||
icon.value = 'las la-hand-middle-finger';
|
||||
color.value = 'negative';
|
||||
}
|
||||
else {
|
||||
icon.value = 'las la-hand-peace';
|
||||
color.value = 'accent';
|
||||
}
|
||||
Notify.create({
|
||||
color: color.value,
|
||||
icon: icon.value,
|
||||
iconSize: '5em',
|
||||
iconColor: 'white',
|
||||
});
|
||||
|
||||
click_number.value += 1;
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<q-page
|
||||
padding
|
||||
class="q-pa-md row justify-center"
|
||||
class="q-pa-md justify-center items-stretch"
|
||||
:class="$q.platform.is.mobile ? 'column' : 'row'"
|
||||
>
|
||||
<q-card flat class="column col-9 transparent ">
|
||||
<div class="col-1"></div>
|
||||
<div class="column col flex-center q-pa-md">
|
||||
|
||||
</div>
|
||||
|
||||
<div class="column col-xs-12 col-md-8 col-xl-6 flex-center self-start q-pa-md">
|
||||
<q-carousel
|
||||
v-model="slide"
|
||||
transition-prev="jump-right"
|
||||
|
|
@ -53,13 +33,18 @@
|
|||
control-color="accent"
|
||||
navigation-icon="radio_button_unchecked"
|
||||
navigation
|
||||
class="col-5 bg-dark rounded-15 shadow-2"
|
||||
class="col-auto bg-dark rounded-15 shadow-18"
|
||||
>
|
||||
<!-- welcome slide -->
|
||||
<q-carousel-slide
|
||||
name="welcome"
|
||||
class="column no-wrap flex-center q-pa-none q-pb-xl"
|
||||
>
|
||||
<q-img src="src/assets/line-truck-1.jpg" class="full-height">
|
||||
<q-img
|
||||
src="src/assets/targo_building.png"
|
||||
height="25vh"
|
||||
position="50% 25%"
|
||||
>
|
||||
<div class="absolute-bottom text-h5">
|
||||
Welcome to App Targo!
|
||||
</div>
|
||||
|
|
@ -68,6 +53,8 @@
|
|||
{{ LOREM_IPSUM }}
|
||||
</div>
|
||||
</q-carousel-slide>
|
||||
|
||||
<!-- help page slide -->
|
||||
<q-carousel-slide
|
||||
name="tv"
|
||||
class="column no-wrap flex-center q-pa-none q-pb-xl"
|
||||
|
|
@ -80,39 +67,23 @@
|
|||
{{ LOREM_IPSUM }}
|
||||
</div>
|
||||
</q-carousel-slide>
|
||||
<q-carousel-slide
|
||||
name="layers"
|
||||
class="column no-wrap flex-center q-pa-none q-pb-xl"
|
||||
>
|
||||
<q-icon
|
||||
name="layers"
|
||||
size="56px"
|
||||
/>
|
||||
<div class="q-mt-md text-center">
|
||||
{{ LOREM_IPSUM }}
|
||||
</div>
|
||||
</q-carousel-slide>
|
||||
<q-carousel-slide
|
||||
name="map"
|
||||
class="column no-wrap flex-center q-pa-none q-pb-xl"
|
||||
>
|
||||
<q-icon
|
||||
name="terrain"
|
||||
size="56px"
|
||||
/>
|
||||
<div class="q-mt-md text-center">
|
||||
{{ LOREM_IPSUM }}
|
||||
</div>
|
||||
</q-carousel-slide>
|
||||
</q-carousel>
|
||||
<div class="col column flex-center">
|
||||
<q-btn
|
||||
push
|
||||
color="accent"
|
||||
label="Click Me"
|
||||
@click="clickNotify"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="column col flex-center q-pt-md q-pl-md">
|
||||
<div class="col"></div>
|
||||
|
||||
<div class="col-auto row justify-end full-width within-iframe">
|
||||
<iframe
|
||||
title="Environment Canada Weather"
|
||||
height="100%"
|
||||
width="100%"
|
||||
src="https://weather.gc.ca/wxlink/wxlink.html?coords=45.159%2C-73.676&lang=e"
|
||||
allowtransparency="true"
|
||||
style="border: 0;"
|
||||
class="col-auto"
|
||||
></iframe>
|
||||
</div>
|
||||
</q-card>
|
||||
</div>
|
||||
</q-page>
|
||||
</template>
|
||||
|
|
@ -3,7 +3,7 @@ import { defineStore } from 'pinia';
|
|||
import { unwrapAndClone } from 'src/utils/unwrap-and-clone';
|
||||
import { timesheetApprovalService } from 'src/modules/timesheet-approval/services/timesheet-approval-service';
|
||||
import { timesheetService } from 'src/modules/timesheets/services/timesheet-service';
|
||||
import type { PayPeriodOverviewResponse, TimesheetOverview } from "src/modules/timesheet-approval/models/timesheet-overview.models";
|
||||
import type { PayPeriodOverviewResponse, TimesheetApprovalOverview } from "src/modules/timesheet-approval/models/timesheet-overview.models";
|
||||
import type { PayPeriod } from 'src/modules/shared/models/pay-period.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';
|
||||
|
|
@ -16,13 +16,13 @@ export const useTimesheetStore = defineStore('timesheet', () => {
|
|||
const all_current_shifts = computed(() => timesheets.value.flatMap(week => week.days.flatMap(day => day.shifts)) ?? []);
|
||||
const initial_timesheets = ref<Timesheet[]>([]);
|
||||
|
||||
const pay_period_overviews = ref<TimesheetOverview[]>([]);
|
||||
const pay_period_overviews = ref<TimesheetApprovalOverview[]>([]);
|
||||
const pay_period_infos = ref<PayPeriodOverviewResponse>();
|
||||
const is_report_dialog_open = ref(false);
|
||||
|
||||
const is_details_dialog_open = ref(false);
|
||||
const selected_employee_name = ref<string>();
|
||||
const current_pay_period_overview = ref<TimesheetOverview>();
|
||||
const current_pay_period_overview = ref<TimesheetApprovalOverview>();
|
||||
const is_approval_grid_mode = ref<boolean>(true);
|
||||
const pay_period_report = ref();
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user