#44 - vacation monthly usage
This commit is contained in:
@@ -22,7 +22,7 @@
|
||||
<div class="border-t border-gray-200">
|
||||
<div class="overflow-x-auto xl:overflow-x-visible overflow-y-auto xl:overflow-y-visible">
|
||||
<table class="min-w-full divide-y divide-gray-200">
|
||||
<thead class="bg-gray-100">
|
||||
<thead class="bg-gray-50">
|
||||
<tr>
|
||||
<th
|
||||
scope="col"
|
||||
|
@@ -4,117 +4,91 @@
|
||||
<div class="flex justify-between items-center p-4 sm:px-6">
|
||||
<div class="flex items-center">
|
||||
<h2 class="text-lg leading-6 font-medium text-gray-900">
|
||||
Wykorzystanie miesięczne urlopu
|
||||
Wykorzystanie miesięczne urlopu wypoczynkowego
|
||||
</h2>
|
||||
<div class="ml-5">
|
||||
ROK TUTAJ
|
||||
</div>
|
||||
<div class="ml-5">
|
||||
Select z typami urlopów
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="overflow-x-auto">
|
||||
<table class="w-full text-center text-sm border border-gray-300">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="w-64 py-2 border text-lg font-semibold text-gray-800 border-gray-300" />
|
||||
<th
|
||||
class="border border-gray-300 text-sm font-semibold text-gray-900 py-4 px-2"
|
||||
>
|
||||
Limit zaległy (2021)
|
||||
</th>
|
||||
<th
|
||||
class="border border-gray-300 text-sm font-semibold text-gray-900 py-4 px-2"
|
||||
>
|
||||
Limit obecny (2022)
|
||||
</th>
|
||||
<th
|
||||
v-for="month in months"
|
||||
:key="month"
|
||||
class="border border-gray-300 text-sm font-semibold text-gray-900 py-4 px-2"
|
||||
style="min-width: 46px;"
|
||||
>
|
||||
<div>
|
||||
{{ month.shortcut }}
|
||||
</div>
|
||||
</th>
|
||||
<th
|
||||
class="border border-gray-300 text-sm font-semibold text-gray-900 py-4 px-2"
|
||||
>
|
||||
Wykorzystany
|
||||
</th>
|
||||
<th
|
||||
class="border border-gray-300 text-sm font-semibold text-gray-900 py-4 px-2"
|
||||
>
|
||||
Rozpatrywany
|
||||
</th>
|
||||
<th
|
||||
class="border border-gray-300 text-sm font-semibold text-gray-900 py-4 px-2"
|
||||
>
|
||||
Pozostało
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr
|
||||
v-for="user in users.data"
|
||||
:key="user.id"
|
||||
>
|
||||
<th
|
||||
class="border border-gray-300 py-2 px-4"
|
||||
>
|
||||
<div class="flex justify-start items-center">
|
||||
<span class="inline-flex items-center justify-center h-10 w-10 rounded-full">
|
||||
<img
|
||||
class="h-10 w-10 rounded-full"
|
||||
:src="user.avatar"
|
||||
>
|
||||
<div class="border-t border-gray-200">
|
||||
<div class="overflow-x-auto xl:overflow-x-visible overflow-y-hidden">
|
||||
<table class="min-w-full divide-y divide-gray-200">
|
||||
<thead class="bg-gray-50">
|
||||
<tr>
|
||||
<th class="w-64 px-6 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider text-left">
|
||||
Pracownik
|
||||
</th>
|
||||
<th
|
||||
v-for="month in months"
|
||||
:key="month"
|
||||
class="px-6 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider text-center"
|
||||
:class="{'bg-blumilk-50': isCurrentMonth(month)}"
|
||||
style="min-width: 46px;"
|
||||
>
|
||||
<span :class="{'text-blumilk-600': isCurrentMonth(month)}">
|
||||
{{ month.name }}
|
||||
</span>
|
||||
<div class="ml-3">
|
||||
<div
|
||||
class="text-sm font-medium text-gray-900 whitespace-nowrap"
|
||||
>
|
||||
{{ user.name }}
|
||||
</th>
|
||||
<th class="px-6 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider text-center">
|
||||
Wykorzystanie urlopu
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="bg-white divide-y divide-gray-100">
|
||||
<tr
|
||||
v-for="item in monthlyUsage"
|
||||
:key="item.user.id"
|
||||
class="hover:bg-blumilk-25"
|
||||
>
|
||||
<th class="px-4 py-4 whitespace-nowrap text-sm text-gray-500 font-semibold capitalize">
|
||||
<div class="flex justify-start items-center">
|
||||
<span class="inline-flex items-center justify-center h-10 w-10 rounded-full">
|
||||
<img
|
||||
class="h-10 w-10 rounded-full"
|
||||
:src="item.user.avatar"
|
||||
>
|
||||
</span>
|
||||
<div class="ml-3">
|
||||
<div
|
||||
class="text-sm font-medium text-gray-900 whitespace-nowrap"
|
||||
>
|
||||
{{ item.user.name }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</th>
|
||||
<td
|
||||
v-for="index in 17"
|
||||
:key="index"
|
||||
class="border border-gray-300"
|
||||
/>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</th>
|
||||
<td
|
||||
v-for="month in months"
|
||||
:key="month.value"
|
||||
class="px-4 py-4 text-sm text-gray-500 font-semibold text-center"
|
||||
:class="{'bg-blumilk-25': isCurrentMonth(month)}"
|
||||
>
|
||||
{{ item.months[month.value] ?? '-' }}
|
||||
</td>
|
||||
<td class="px-4 py-4 text-sm text-gray-500 font-semibold text-center">
|
||||
<div style="min-width: 300px;">
|
||||
<VacationBar :stats="{ used: item.stats.used, pending: item.stats.pending, remaining: item.stats.remaining }" />
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {useMonthInfo} from '@/Composables/monthInfo'
|
||||
<script setup>
|
||||
import { useMonthInfo } from '@/Composables/monthInfo'
|
||||
import VacationBar from '@/Shared/VacationBar'
|
||||
|
||||
export default {
|
||||
name: 'MonthlyUsage',
|
||||
components: {
|
||||
},
|
||||
props: {
|
||||
users: {
|
||||
type: Object,
|
||||
default: () => null,
|
||||
},
|
||||
can: {
|
||||
type: Object,
|
||||
default: () => null,
|
||||
},
|
||||
},
|
||||
setup() {
|
||||
const {getMonths} = useMonthInfo()
|
||||
const months = getMonths()
|
||||
return {
|
||||
months,
|
||||
}
|
||||
},
|
||||
const props = defineProps({
|
||||
monthlyUsage: Object,
|
||||
currentMonth: String,
|
||||
})
|
||||
|
||||
const { getMonths } = useMonthInfo()
|
||||
const months = getMonths()
|
||||
|
||||
function isCurrentMonth(month) {
|
||||
return props.currentMonth === month.value
|
||||
}
|
||||
</script>
|
||||
|
@@ -15,7 +15,7 @@
|
||||
<script setup>
|
||||
import MainMenu from '@/Shared/MainMenu'
|
||||
import { useToast } from 'vue-toastification'
|
||||
import { defineProps, watch } from 'vue'
|
||||
import { watch } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
flash: Object,
|
||||
@@ -30,6 +30,10 @@ watch(() => props.flash, flash => {
|
||||
toast.success(flash.success)
|
||||
}
|
||||
|
||||
if (flash.info) {
|
||||
toast.info(flash.info)
|
||||
}
|
||||
|
||||
if (flash.error) {
|
||||
toast.error(flash.error)
|
||||
}
|
||||
|
@@ -249,7 +249,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {computed, ref} from 'vue'
|
||||
import { computed, ref } from 'vue'
|
||||
import {
|
||||
Dialog,
|
||||
DialogOverlay,
|
||||
@@ -272,7 +272,7 @@ import {
|
||||
DocumentTextIcon,
|
||||
AdjustmentsIcon,
|
||||
} from '@heroicons/vue/outline'
|
||||
import {CheckIcon, ChevronDownIcon} from '@heroicons/vue/solid'
|
||||
import { CheckIcon, ChevronDownIcon } from '@heroicons/vue/solid'
|
||||
|
||||
const props = defineProps({
|
||||
auth: Object,
|
||||
@@ -309,7 +309,7 @@ const navigation = computed(() =>
|
||||
href: '/monthly-usage',
|
||||
component: 'MonthlyUsage',
|
||||
icon: AdjustmentsIcon,
|
||||
can: auth.value.can.listMonthlyUsage
|
||||
can: props.auth.can.listMonthlyUsage,
|
||||
},
|
||||
{
|
||||
name: 'Dni wolne',
|
||||
|
84
resources/js/Shared/VacationBar.vue
Normal file
84
resources/js/Shared/VacationBar.vue
Normal file
@@ -0,0 +1,84 @@
|
||||
<template>
|
||||
<Popper
|
||||
hover
|
||||
class="h-full w-full"
|
||||
>
|
||||
<div class="flex bg-white text-white">
|
||||
<div
|
||||
v-show="stats.used > 0"
|
||||
:style="`background-color: ${colors.used}; flex-basis: ${calculatePercent(stats.used)}%;`"
|
||||
class="flex items-center justify-center py-2 px-0.5"
|
||||
>
|
||||
<strong>{{ stats.used }}</strong>
|
||||
</div>
|
||||
<div
|
||||
v-show="stats.pending > 0"
|
||||
:style="`background-color: ${colors.pending}; flex-basis: ${calculatePercent(stats.pending)}%;`"
|
||||
class="flex items-center justify-center py-2 px-0.5"
|
||||
>
|
||||
<strong>{{ stats.pending }}</strong>
|
||||
</div>
|
||||
<div
|
||||
v-show="stats.remaining > 0"
|
||||
:style="`background-color: ${colors.remaining}; flex-basis: ${calculatePercent(stats.remaining)}%;`"
|
||||
class="flex items-center justify-center py-2 px-0.5"
|
||||
>
|
||||
<strong>{{ stats.remaining }}</strong>
|
||||
</div>
|
||||
</div>
|
||||
<template #content>
|
||||
<div class="px-4 py-2 bg-white text-md text-gray-900 rounded-md shadow-md flext">
|
||||
<div class="flex items-center font-normal">
|
||||
<i
|
||||
class="inline-block w-5 h-3 mr-3"
|
||||
:style="`background-color: ${colors.used}`"
|
||||
/>
|
||||
Wykorzystane:
|
||||
<span class="font-semibold ml-1">{{ stats.used }}</span>
|
||||
</div>
|
||||
<div class="flex items-center font-normal">
|
||||
<i
|
||||
class="inline-block w-5 h-3 mr-3"
|
||||
:style="`background-color: ${colors.pending}`"
|
||||
/>
|
||||
Rozpatrywane:
|
||||
<span class="font-semibold ml-1">{{ stats.pending }}</span>
|
||||
</div>
|
||||
<div class="flex items-center font-normal">
|
||||
<i
|
||||
class="inline-block w-5 h-3 mr-3"
|
||||
:style="`background-color: ${colors.remaining}`"
|
||||
/>
|
||||
Pozostałe:
|
||||
<span class="font-semibold ml-1">{{ stats.remaining }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</Popper>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import Popper from 'vue3-popper'
|
||||
|
||||
const props = defineProps({
|
||||
stats: {
|
||||
type: Object,
|
||||
default: () => ({
|
||||
used: 0,
|
||||
pending: 0,
|
||||
remaining: 0,
|
||||
}),
|
||||
},
|
||||
})
|
||||
|
||||
const colors = {
|
||||
used: '#2C466F',
|
||||
pending: '#AABDDD',
|
||||
remaining: '#527ABA',
|
||||
}
|
||||
|
||||
function calculatePercent(value) {
|
||||
return value / (props.stats.used + props.stats.pending + props.stats.remaining) * 100
|
||||
}
|
||||
|
||||
</script>
|
@@ -20,7 +20,8 @@ createInertiaApp({
|
||||
.use(Toast, {
|
||||
position: 'bottom-right',
|
||||
maxToast: 5,
|
||||
|
||||
timeout: 3000,
|
||||
pauseOnFocusLoss: false,
|
||||
})
|
||||
.component('InertiaLink', Link)
|
||||
.component('InertiaHead', Head)
|
||||
|
Reference in New Issue
Block a user