diff --git a/package-lock.json b/package-lock.json index 2a71337..5d78565 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,10 +11,12 @@ "dependencies": { "@quasar/extras": "^1.17.0", "axios": "^1.11.0", + "chart.js": "^4.5.0", "pinia": "^3.0.3", "pinia-plugin-persistedstate": "^4.4.1", "quasar": "^2.18.2", "vue": "^3.5.18", + "vue-chartjs": "^5.3.2", "vue-i18n": "^11.1.11", "vue-router": "^4.5.1" }, @@ -1173,6 +1175,12 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@kurkle/color": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@kurkle/color/-/color-0.3.4.tgz", + "integrity": "sha512-M5UknZPHRu3DEDWoipU6sE8PdkZ6Z/S+v4dD+Ke8IaNlpdSQah50lz1KtcFBa2vsdOnwbbnxJwVM4wty6udA5w==", + "license": "MIT" + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -3457,6 +3465,18 @@ "dev": true, "license": "MIT" }, + "node_modules/chart.js": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.5.0.tgz", + "integrity": "sha512-aYeC/jDgSEx8SHWZvANYMioYMZ2KX02W6f6uVfyteuCGcadDLcYVHdfdygsTQkQ4TKn5lghoojAsPj5pu0SnvQ==", + "license": "MIT", + "dependencies": { + "@kurkle/color": "^0.3.0" + }, + "engines": { + "pnpm": ">=8" + } + }, "node_modules/check-error": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", @@ -10134,6 +10154,16 @@ } } }, + "node_modules/vue-chartjs": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/vue-chartjs/-/vue-chartjs-5.3.2.tgz", + "integrity": "sha512-NrkbRRoYshbXbWqJkTN6InoDVwVb90C0R7eAVgMWcB9dPikbruaOoTFjFYHE/+tNPdIe6qdLCDjfjPHQ0fw4jw==", + "license": "MIT", + "peerDependencies": { + "chart.js": "^4.1.1", + "vue": "^3.0.0-0 || ^2.7.0" + } + }, "node_modules/vue-component-type-helpers": { "version": "2.2.12", "resolved": "https://registry.npmjs.org/vue-component-type-helpers/-/vue-component-type-helpers-2.2.12.tgz", diff --git a/package.json b/package.json index 78bb21a..3d535b7 100644 --- a/package.json +++ b/package.json @@ -16,31 +16,33 @@ "dependencies": { "@quasar/extras": "^1.17.0", "axios": "^1.11.0", + "chart.js": "^4.5.0", "pinia": "^3.0.3", "pinia-plugin-persistedstate": "^4.4.1", "quasar": "^2.18.2", "vue": "^3.5.18", + "vue-chartjs": "^5.3.2", "vue-i18n": "^11.1.11", "vue-router": "^4.5.1" }, "devDependencies": { - "@vue/test-utils": "^2.4.6", - "cypress": "^14.5.2", "@eslint/js": "^9.14.0", + "@intlify/unplugin-vue-i18n": "^4.0.0", + "@quasar/app-vite": "^2.1.0", + "@types/node": "^20.5.9", + "@vue/eslint-config-typescript": "^14.4.0", + "@vue/test-utils": "^2.4.6", + "autoprefixer": "^10.4.2", + "cypress": "^14.5.2", "eslint": "^9.31.0", "eslint-plugin-vue": "^10.3.0", "globals": "^15.12.0", "husky": "^9.1.7", "lint-staged": "^16.1.2", - "vitest": "^3.2.4", - "vue-tsc": "^2.0.29", - "@vue/eslint-config-typescript": "^14.4.0", + "typescript": "~5.5.3", "vite-plugin-checker": "^0.9.0", - "@types/node": "^20.5.9", - "@intlify/unplugin-vue-i18n": "^4.0.0", - "@quasar/app-vite": "^2.1.0", - "autoprefixer": "^10.4.2", - "typescript": "~5.5.3" + "vitest": "^3.2.4", + "vue-tsc": "^2.0.29" }, "engines": { "node": "^28 || ^26 || ^24 || ^22 || ^20 || ^18", diff --git a/src/css/quasar.variables.scss b/src/css/quasar.variables.scss index 6011d76..edb539f 100644 --- a/src/css/quasar.variables.scss +++ b/src/css/quasar.variables.scss @@ -24,7 +24,7 @@ $dark: #000; $dark-page: #323232; $positive: #21ba45; -$negative: #ff586c71; -$info: #31ccec; -$warning: #ffde82c2; +$negative: #df6674; +$info: #54bbdd; +$warning: #eec964; $white: white; diff --git a/src/i18n/en-ca/index.ts b/src/i18n/en-ca/index.ts index 31cd0aa..71b4552 100644 --- a/src/i18n/en-ca/index.ts +++ b/src/i18n/en-ca/index.ts @@ -327,6 +327,11 @@ export default { consumedVacationTotalValidation: 'Consumed with vacation must be positive.', maxVacationPerYearValidation: 'Max Vacation Per Year must be positive.', resteVacationTotal: 'Rest of vacation', + hoursWorkedChartTitle: 'Hours worked', + hoursWorkedRegular: 'regular', + hoursWorkedEvening: 'evening', + hoursWorkedEmergency: 'emergency', + hoursWorkedOvertime: 'overtime', tooltipTimeline: 'Daily breakdown', tooltipTimesheet: 'Open timesheet', reportFilterCategoryCompany: 'Company', diff --git a/src/i18n/fr-ca/index.ts b/src/i18n/fr-ca/index.ts index 83956c1..2008d4a 100644 --- a/src/i18n/fr-ca/index.ts +++ b/src/i18n/fr-ca/index.ts @@ -374,6 +374,11 @@ export default { consumedVacationTotalValidation: 'Vacances utilisées doit être positif', maxVacationPerYearValidation: 'Maximum vacances annuel doit être positif.', resteVacationTotal: 'Reste des vacances', + hoursWorkedChartTitle: 'Heures travaillées', + hoursWorkedRegular: 'régulier', + hoursWorkedEvening: 'soir', + hoursWorkedEmergency: 'urgence', + hoursWorkedOvertime: 'supplémentaire', tooltipTimeline: 'Vue journalière', tooltipTimesheet: 'Feuille de temps', reportFilterCategoryCompany: 'Compagnie', diff --git a/src/modules/timesheet-approval/components/graphs/timesheet-approval-employee-details-hours-worked-chart.vue b/src/modules/timesheet-approval/components/graphs/timesheet-approval-employee-details-hours-worked-chart.vue new file mode 100644 index 0000000..e01e8a1 --- /dev/null +++ b/src/modules/timesheet-approval/components/graphs/timesheet-approval-employee-details-hours-worked-chart.vue @@ -0,0 +1,23 @@ + + + \ No newline at end of file diff --git a/src/modules/timesheet-approval/components/shifts/shift-preview-bar.vue b/src/modules/timesheet-approval/components/shifts/shift-preview-bar.vue deleted file mode 100644 index 398bff9..0000000 --- a/src/modules/timesheet-approval/components/shifts/shift-preview-bar.vue +++ /dev/null @@ -1,147 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/src/modules/timesheet-approval/components/timesheet-approval-employee-details.vue b/src/modules/timesheet-approval/components/timesheet-approval-employee-details.vue index 2be8472..5fcfba5 100644 --- a/src/modules/timesheet-approval/components/timesheet-approval-employee-details.vue +++ b/src/modules/timesheet-approval/components/timesheet-approval-employee-details.vue @@ -1,12 +1,62 @@ \ No newline at end of file diff --git a/src/modules/timesheet-approval/components/timesheet-approval-employee-overview-list-item.vue b/src/modules/timesheet-approval/components/timesheet-approval-employee-overview-list-item.vue index a556b7e..3fbf2a1 100644 --- a/src/modules/timesheet-approval/components/timesheet-approval-employee-overview-list-item.vue +++ b/src/modules/timesheet-approval/components/timesheet-approval-employee-overview-list-item.vue @@ -21,7 +21,7 @@ const emit = defineEmits<{ clickDetails: [email: string]; - 'update:modelValue': [value: boolean | null]; + updateApproval: [ value: boolean ]; }>(); const card_buttons: CardButton[] = [ @@ -168,7 +168,7 @@ unchecked-icon="lock_open" :color="props.initialState ? 'white' : 'primary'" keep-color :model-value="props.initialState" - @update:model-value="val => emit('update:modelValue', val)" + @update:model-value="val => emit('updateApproval', val)" :label="props.initialState ? $t('timeSheetValidations.timeSheetStatusVerified') : $t('timeSheetValidations.timeSheetStatusUnverified')" class="text-uppercase" /> diff --git a/src/modules/timesheet-approval/components/timesheet-approval-employee-overview-list.vue b/src/modules/timesheet-approval/components/timesheet-approval-employee-overview-list.vue index 73e8409..5920d91 100644 --- a/src/modules/timesheet-approval/components/timesheet-approval-employee-overview-list.vue +++ b/src/modules/timesheet-approval/components/timesheet-approval-employee-overview-list.vue @@ -26,6 +26,7 @@ const report_filter_company = ref([true, true]); const report_filter_type = ref([true, true, true, true]); const clicked_employee_name = ref(''); + const update_key = ref(0); const columns = computed((): QTableColumn[] => [ { @@ -98,6 +99,21 @@ timesheet_store.current_pay_period.pay_period_no <= 1; }); + const getEmployeeApprovalStatusReference = (email: string): boolean => { + const approval_status = timesheet_store.pay_period_overview_employee_approval_statuses?.find( status => status.key === email); + if (approval_status) { + return approval_status.value; + } + return false; + } + + const updateEmployeeApprovalStatus = (email: string, value: boolean) => { + const approval_status = timesheet_store.pay_period_overview_employee_approval_statuses?.find( status => status.key === email); + if (approval_status) { + approval_status.value = value; + } + } + const onDateSelected = async (date_string: string) => { await timesheet_approval_api.getPayPeriodOverviewByDate(date_string); }; @@ -106,6 +122,7 @@ clicked_employee_name.value = name; is_showing_details.value = true; await timesheet_approval_api.getTimesheetsByPayPeriodAndEmail(email); + console.log('current employee details: ', timesheet_store.pay_period_employee_details); }; const onClickPrintReport = async () => { @@ -125,14 +142,16 @@