Many Changes
This commit is contained in:
191
composables/useWorkingTimePDFGenerator.js
Normal file
191
composables/useWorkingTimePDFGenerator.js
Normal file
@@ -0,0 +1,191 @@
|
|||||||
|
import {PDFDocument, StandardFonts, rgb} from "pdf-lib"
|
||||||
|
import dayjs from "dayjs"
|
||||||
|
|
||||||
|
|
||||||
|
const getCoordinatesForPDFLib = (x ,y, page) => {
|
||||||
|
/*
|
||||||
|
* @param x the wanted X Parameter in Millimeters from Top Left
|
||||||
|
* @param y the wanted Y Parameter in Millimeters from Top Left
|
||||||
|
* @param page the page Object
|
||||||
|
*
|
||||||
|
* @returns x,y object
|
||||||
|
* */
|
||||||
|
|
||||||
|
|
||||||
|
let retX = x * 2.83
|
||||||
|
let retY = page.getHeight()-(y*2.83)
|
||||||
|
|
||||||
|
return {
|
||||||
|
x: retX,
|
||||||
|
y: retY
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const getDuration = (time) => {
|
||||||
|
const minutes = Math.floor(dayjs(time.endDate).diff(dayjs(time.startDate),'minutes',true))
|
||||||
|
const hours = Math.floor(minutes/60)
|
||||||
|
return {
|
||||||
|
//dezimal: dez,
|
||||||
|
hours: hours,
|
||||||
|
minutes: minutes,
|
||||||
|
composed: `${hours}:${String(minutes % 60).padStart(2,"0")} Std`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export const useCreateWorkingTimesPdf = async (input,backgroundSourceBuffer) => {
|
||||||
|
|
||||||
|
const uri = ref("test")
|
||||||
|
const genPDF = async () => {
|
||||||
|
const pdfDoc = await PDFDocument.create()
|
||||||
|
|
||||||
|
const font = await pdfDoc.embedFont(StandardFonts.Helvetica)
|
||||||
|
const fontBold = await pdfDoc.embedFont(StandardFonts.HelveticaBold)
|
||||||
|
|
||||||
|
let pages = []
|
||||||
|
let pageCounter = 1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const backgroudPdf = await PDFDocument.load(backgroundSourceBuffer)
|
||||||
|
|
||||||
|
const firstPageBackground = await pdfDoc.embedPage(backgroudPdf.getPages()[0])
|
||||||
|
const secondPageBackground = await pdfDoc.embedPage(backgroudPdf.getPages()[backgroudPdf.getPages().length > 1 ? 1 : 0])
|
||||||
|
|
||||||
|
const page1 = pdfDoc.addPage()
|
||||||
|
|
||||||
|
page1.drawPage(firstPageBackground, {
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
})
|
||||||
|
|
||||||
|
pages.push(page1)
|
||||||
|
|
||||||
|
|
||||||
|
//Falzmarke 1
|
||||||
|
/*pages[pageCounter - 1].drawLine({
|
||||||
|
start: getCoordinatesForPDFLib(0,105,page1),
|
||||||
|
end: getCoordinatesForPDFLib(7,105,page1),
|
||||||
|
thickness: 0.25,
|
||||||
|
color: rgb(0,0,0),
|
||||||
|
opacity: 1
|
||||||
|
})*/
|
||||||
|
|
||||||
|
//Lochmarke
|
||||||
|
/*pages[pageCounter - 1].drawLine({
|
||||||
|
start: getCoordinatesForPDFLib(0,148.5,page1),
|
||||||
|
end: getCoordinatesForPDFLib(7,148.5,page1),
|
||||||
|
thickness: 0.25,
|
||||||
|
color: rgb(0,0,0),
|
||||||
|
opacity: 1
|
||||||
|
})*/
|
||||||
|
|
||||||
|
//Falzmarke 2
|
||||||
|
/*pages[pageCounter - 1].drawLine({
|
||||||
|
start: getCoordinatesForPDFLib(0,210,page1),
|
||||||
|
end: getCoordinatesForPDFLib(7,210,page1),
|
||||||
|
thickness: 0.25,
|
||||||
|
color: rgb(0,0,0),
|
||||||
|
opacity: 1
|
||||||
|
})*/
|
||||||
|
console.log(input)
|
||||||
|
pages[pageCounter - 1].drawText(`Mitarbeiter: ${input.profile}`,{
|
||||||
|
x: getCoordinatesForPDFLib(20,65,pages[pageCounter -1]).x,
|
||||||
|
y: getCoordinatesForPDFLib(20,65,pages[pageCounter -1]).y,
|
||||||
|
size: 10,
|
||||||
|
})
|
||||||
|
pages[pageCounter - 1].drawText(`Eingereicht: ${Math.floor(input.sumWorkingMinutesEingereicht/60)}:${String(input.sumWorkingMinutesEingereicht % 60).padStart(2,"0")} Std`,{
|
||||||
|
x: getCoordinatesForPDFLib(20,70,pages[pageCounter -1]).x,
|
||||||
|
y: getCoordinatesForPDFLib(20,70,pages[pageCounter -1]).y,
|
||||||
|
size: 10,
|
||||||
|
})
|
||||||
|
pages[pageCounter - 1].drawText(`Bestätigt: ${Math.floor(input.sumWorkingMinutesApproved/60)}:${String(input.sumWorkingMinutesApproved % 60).padStart(2,"0")} Std`,{
|
||||||
|
x: getCoordinatesForPDFLib(20,75,pages[pageCounter -1]).x,
|
||||||
|
y: getCoordinatesForPDFLib(20,75,pages[pageCounter -1]).y,
|
||||||
|
size: 10,
|
||||||
|
})
|
||||||
|
pages[pageCounter - 1].drawText(`Soll Stunden: ${input.monthlyWorkingHours} Std`,{
|
||||||
|
x: getCoordinatesForPDFLib(20,80,pages[pageCounter -1]).x,
|
||||||
|
y: getCoordinatesForPDFLib(20,80,pages[pageCounter -1]).y,
|
||||||
|
size: 10,
|
||||||
|
})
|
||||||
|
pages[pageCounter - 1].drawText(`Abwesend: Std`,{
|
||||||
|
x: getCoordinatesForPDFLib(20,85,pages[pageCounter -1]).x,
|
||||||
|
y: getCoordinatesForPDFLib(20,85,pages[pageCounter -1]).y,
|
||||||
|
size: 10,
|
||||||
|
})
|
||||||
|
pages[pageCounter - 1].drawText(`Ausgleich: Std`,{
|
||||||
|
x: getCoordinatesForPDFLib(20,90,pages[pageCounter -1]).x,
|
||||||
|
y: getCoordinatesForPDFLib(20,90,pages[pageCounter -1]).y,
|
||||||
|
size: 10,
|
||||||
|
})
|
||||||
|
pages[pageCounter - 1].drawText(`Inoffizielles Saldo: ${input.saldoInOfficial} Std`,{
|
||||||
|
x: getCoordinatesForPDFLib(20,95,pages[pageCounter -1]).x,
|
||||||
|
y: getCoordinatesForPDFLib(20,95,pages[pageCounter -1]).y,
|
||||||
|
size: 10,
|
||||||
|
})
|
||||||
|
pages[pageCounter - 1].drawText(`Saldo: ${input.saldo} Std`,{
|
||||||
|
x: getCoordinatesForPDFLib(20,100,pages[pageCounter -1]).x,
|
||||||
|
y: getCoordinatesForPDFLib(20,100,pages[pageCounter -1]).y,
|
||||||
|
size: 10,
|
||||||
|
})
|
||||||
|
|
||||||
|
pages[pageCounter - 1].drawText(`Start:`,{
|
||||||
|
x: getCoordinatesForPDFLib(20,110,pages[pageCounter -1]).x,
|
||||||
|
y: getCoordinatesForPDFLib(20,110,pages[pageCounter -1]).y,
|
||||||
|
size: 10,
|
||||||
|
})
|
||||||
|
|
||||||
|
pages[pageCounter - 1].drawText(`Ende:`,{
|
||||||
|
x: getCoordinatesForPDFLib(60,110,pages[pageCounter -1]).x,
|
||||||
|
y: getCoordinatesForPDFLib(60,110,pages[pageCounter -1]).y,
|
||||||
|
size: 10,
|
||||||
|
})
|
||||||
|
|
||||||
|
pages[pageCounter - 1].drawText(`Dauer:`,{
|
||||||
|
x: getCoordinatesForPDFLib(100,110,pages[pageCounter -1]).x,
|
||||||
|
y: getCoordinatesForPDFLib(100,110,pages[pageCounter -1]).y,
|
||||||
|
size: 10,
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
let rowHeight = 115
|
||||||
|
|
||||||
|
input.times.forEach(time => {
|
||||||
|
pages[pageCounter - 1].drawText(`${dayjs(time.startDate).format("HH:mm DD.MM.YY")}`,{
|
||||||
|
x: getCoordinatesForPDFLib(20,rowHeight,pages[pageCounter -1]).x,
|
||||||
|
y: getCoordinatesForPDFLib(20,rowHeight,pages[pageCounter -1]).y,
|
||||||
|
size: 10,
|
||||||
|
})
|
||||||
|
|
||||||
|
pages[pageCounter - 1].drawText(`${dayjs(time.startDate).format("HH:mm DD.MM.YY")}`,{
|
||||||
|
x: getCoordinatesForPDFLib(60,rowHeight,pages[pageCounter -1]).x,
|
||||||
|
y: getCoordinatesForPDFLib(60,rowHeight,pages[pageCounter -1]).y,
|
||||||
|
size: 10,
|
||||||
|
})
|
||||||
|
|
||||||
|
pages[pageCounter - 1].drawText(`${getDuration(time).composed}`,{
|
||||||
|
x: getCoordinatesForPDFLib(100,rowHeight,pages[pageCounter -1]).x,
|
||||||
|
y: getCoordinatesForPDFLib(100,rowHeight,pages[pageCounter -1]).y,
|
||||||
|
size: 10,
|
||||||
|
})
|
||||||
|
|
||||||
|
rowHeight += 6
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
uri.value = await pdfDoc.saveAsBase64({dataUri: true})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
await genPDF()
|
||||||
|
|
||||||
|
return uri.value
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -73,7 +73,6 @@ setupPage()
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
{{openTab}}
|
|
||||||
<UDashboardNavbar
|
<UDashboardNavbar
|
||||||
:title="currentItem ? `Kunde: ${currentItem.name}` : (mode === 'create' ? 'Kunde erstellen' : 'Kunde bearbeiten')"
|
:title="currentItem ? `Kunde: ${currentItem.name}` : (mode === 'create' ? 'Kunde erstellen' : 'Kunde bearbeiten')"
|
||||||
:ui="{center: 'flex items-stretch gap-1.5 min-w-0'}"
|
:ui="{center: 'flex items-stretch gap-1.5 min-w-0'}"
|
||||||
|
|||||||
311
pages/workingtimes/evaluate/[id].vue
Normal file
311
pages/workingtimes/evaluate/[id].vue
Normal file
@@ -0,0 +1,311 @@
|
|||||||
|
<script setup>
|
||||||
|
import dayjs from "dayjs";
|
||||||
|
import customParseFormat from "dayjs/plugin/customParseFormat";
|
||||||
|
import isoWeek from "dayjs/plugin/isoWeek";
|
||||||
|
import isBetween from "dayjs/plugin/isBetween";
|
||||||
|
import isSameOrAfter from "dayjs/plugin/isSameOrAfter"
|
||||||
|
import isSameOrBefore from "dayjs/plugin/isSameOrBefore"
|
||||||
|
import {useCreateWorkingTimesPdf} from "~/composables/useWorkingTimePDFGenerator.js";
|
||||||
|
dayjs.extend(customParseFormat)
|
||||||
|
dayjs.extend(isoWeek)
|
||||||
|
dayjs.extend(isBetween)
|
||||||
|
dayjs.extend(isSameOrAfter)
|
||||||
|
dayjs.extend(isSameOrBefore)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const dataStore = useDataStore()
|
||||||
|
const supabase = useSupabaseClient()
|
||||||
|
const route = useRoute()
|
||||||
|
|
||||||
|
const itemInfo = ref({})
|
||||||
|
const oldItemInfo = ref({})
|
||||||
|
const setupPage = () => {
|
||||||
|
if(route.params.id) itemInfo.value = dataStore.getProfileById(route.params.id)
|
||||||
|
if(itemInfo.value.id) oldItemInfo.value = JSON.parse(JSON.stringify(itemInfo.value))
|
||||||
|
}
|
||||||
|
|
||||||
|
const selectedPresetRange = ref("Dieser Monat")
|
||||||
|
const selectedStartDay = ref("")
|
||||||
|
const selectedEndDay = ref("")
|
||||||
|
|
||||||
|
const changeRange = () => {
|
||||||
|
let selector = "M"
|
||||||
|
let subtract = 0
|
||||||
|
|
||||||
|
if(selectedPresetRange.value === "Diese Woche") {
|
||||||
|
selector = "isoWeek"
|
||||||
|
subtract = 0
|
||||||
|
|
||||||
|
} else if(selectedPresetRange.value === "Dieser Monat") {
|
||||||
|
selector = "M"
|
||||||
|
subtract = 0
|
||||||
|
|
||||||
|
} else if(selectedPresetRange.value === "Dieses Jahr") {
|
||||||
|
selector = "y"
|
||||||
|
subtract = 0
|
||||||
|
} else if(selectedPresetRange.value === "Letzte Woche") {
|
||||||
|
selector = "isoWeek"
|
||||||
|
subtract = 1
|
||||||
|
} else if(selectedPresetRange.value === "Letzter Monat") {
|
||||||
|
selector = "M"
|
||||||
|
subtract = 1
|
||||||
|
} else if(selectedPresetRange.value === "Letztes Jahr") {
|
||||||
|
selector = "y"
|
||||||
|
subtract = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
selectedStartDay.value = dayjs().subtract(subtract,selector === "isoWeek" ? "week" : selector).startOf(selector).format("YYYY-MM-DD")
|
||||||
|
selectedEndDay.value = dayjs().subtract(subtract,selector === "isoWeek" ? "week" : selector).endOf(selector).format("YYYY-MM-DD")
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const workingTimeInfo = computed(() => {
|
||||||
|
|
||||||
|
let times = dataStore.getWorkingTimesByProfileId(route.params.id)
|
||||||
|
|
||||||
|
//times = times.filter(i => dayjs(i.date).isBetween(dayjs(selectedStartDay.value).subtract(1,"days"),selectedEndDay.value,'day') && i.end)
|
||||||
|
times = times.filter(i => dayjs(i.startDate).isSameOrAfter(selectedStartDay.value) && dayjs(i.endDate).isSameOrBefore(selectedEndDay.value))
|
||||||
|
|
||||||
|
|
||||||
|
let weekFactor = 4.33
|
||||||
|
let monthlyWorkingHours = itemInfo.value.weeklyWorkingHours * weekFactor
|
||||||
|
|
||||||
|
|
||||||
|
//Eingreicht
|
||||||
|
let sumWorkingMinutesEingereicht = 0
|
||||||
|
times.filter(i => !i.approved).forEach(time => {
|
||||||
|
const minutes = dayjs(time.endDate).diff(dayjs(time.startDate),'minutes')
|
||||||
|
sumWorkingMinutesEingereicht = sumWorkingMinutesEingereicht + minutes
|
||||||
|
})
|
||||||
|
|
||||||
|
//Bestätigt
|
||||||
|
let sumWorkingMinutesApproved = 0
|
||||||
|
times.filter(i => i.approved).forEach(time => {
|
||||||
|
const minutes = dayjs(time.endDate).diff(dayjs(time.startDate),'minutes')
|
||||||
|
sumWorkingMinutesApproved = sumWorkingMinutesApproved + minutes
|
||||||
|
})
|
||||||
|
//console.log(times.filter(i => i.approved).length)
|
||||||
|
//console.log(sumWorkingMinutesApproved)
|
||||||
|
|
||||||
|
|
||||||
|
//Saldo
|
||||||
|
let saldo = (sumWorkingMinutesApproved / 60).toFixed(2) - monthlyWorkingHours
|
||||||
|
let saldoInOfficial = (((sumWorkingMinutesApproved + sumWorkingMinutesEingereicht) / 60).toFixed(2) - monthlyWorkingHours).toFixed(2)
|
||||||
|
|
||||||
|
return {
|
||||||
|
monthlyWorkingHours,
|
||||||
|
sumWorkingMinutesEingereicht,
|
||||||
|
sumWorkingMinutesApproved,
|
||||||
|
saldo,
|
||||||
|
saldoInOfficial,
|
||||||
|
times,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const getDuration = (time) => {
|
||||||
|
const minutes = Math.floor(dayjs(time.endDate).diff(dayjs(time.startDate),'minutes',true))
|
||||||
|
const hours = Math.floor(minutes/60)
|
||||||
|
return {
|
||||||
|
//dezimal: dez,
|
||||||
|
hours: hours,
|
||||||
|
minutes: minutes,
|
||||||
|
composed: `${hours}:${String(minutes % 60).padStart(2,"0")} h`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const showDocument = ref(false)
|
||||||
|
const uri = ref("")
|
||||||
|
const generateDocument = async () => {
|
||||||
|
const ownTenant = dataStore.ownTenant
|
||||||
|
const path = ownTenant.letterheadConfig["workingTimesEvaluation"]
|
||||||
|
|
||||||
|
const {data,error} = await supabase.storage.from("files").download(path)
|
||||||
|
|
||||||
|
uri.value = await useCreateWorkingTimesPdf({
|
||||||
|
profile: dataStore.getProfileById(route.params.id).fullName,
|
||||||
|
...workingTimeInfo.value}, await data.arrayBuffer())
|
||||||
|
//alert(uri.value)
|
||||||
|
showDocument.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
const generateEvaluation = async () => {
|
||||||
|
await generateDocument()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
setupPage()
|
||||||
|
changeRange()
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<UDashboardNavbar
|
||||||
|
:ui="{center: 'flex items-stretch gap-1.5 min-w-0'}"
|
||||||
|
>
|
||||||
|
<template #left>
|
||||||
|
<UButton
|
||||||
|
icon="i-heroicons-chevron-left"
|
||||||
|
variant="outline"
|
||||||
|
@click="router.push(`/workingtimes`)"
|
||||||
|
>
|
||||||
|
Anwesenheiten
|
||||||
|
</UButton>
|
||||||
|
</template>
|
||||||
|
<template #center>
|
||||||
|
<h1
|
||||||
|
v-if="itemInfo"
|
||||||
|
:class="['text-xl','font-medium']"
|
||||||
|
>{{itemInfo ? `Auswertung Anwesenheiten: ${itemInfo.fullName}` : ``}}</h1>
|
||||||
|
</template>
|
||||||
|
<template #right>
|
||||||
|
<!-- <UButton
|
||||||
|
v-if="mode === 'edit'"
|
||||||
|
@click="dataStore.updateItem('customers',itemInfo,oldItemInfo)"
|
||||||
|
>
|
||||||
|
Speichern
|
||||||
|
</UButton>
|
||||||
|
<UButton
|
||||||
|
v-else-if="mode === 'create'"
|
||||||
|
@click="dataStore.createNewItem('customers',itemInfo)"
|
||||||
|
>
|
||||||
|
Erstellen
|
||||||
|
</UButton>
|
||||||
|
<UButton
|
||||||
|
@click="cancelEditorCreate"
|
||||||
|
color="red"
|
||||||
|
class="ml-2"
|
||||||
|
v-if="mode === 'edit' || mode === 'create'"
|
||||||
|
>
|
||||||
|
Abbrechen
|
||||||
|
</UButton>
|
||||||
|
<UButton
|
||||||
|
v-if="mode === 'show'"
|
||||||
|
@click="editItem"
|
||||||
|
>
|
||||||
|
Bearbeiten
|
||||||
|
</UButton>-->
|
||||||
|
</template>
|
||||||
|
|
||||||
|
</UDashboardNavbar>
|
||||||
|
<UDashboardToolbar>
|
||||||
|
<template #left>
|
||||||
|
<UFormGroup
|
||||||
|
label="Vorlage:"
|
||||||
|
>
|
||||||
|
<USelectMenu
|
||||||
|
:options="['Diese Woche', 'Dieser Monat', 'Dieses Jahr', 'Letzte Woche', 'Letzter Monat', 'Letztes Jahr']"
|
||||||
|
v-model="selectedPresetRange"
|
||||||
|
@change="changeRange"
|
||||||
|
/>
|
||||||
|
</UFormGroup>
|
||||||
|
<UFormGroup label="Start:" >
|
||||||
|
<UPopover :popper="{ placement: 'bottom-start' }">
|
||||||
|
<UButton
|
||||||
|
icon="i-heroicons-calendar-days-20-solid"
|
||||||
|
:label="selectedStartDay ? dayjs(selectedStartDay).format('DD.MM.YYYY') : 'Datum auswählen'"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<template #panel="{ close }">
|
||||||
|
<LazyDatePicker v-model="selectedStartDay" @close="changeRange" />
|
||||||
|
</template>
|
||||||
|
</UPopover>
|
||||||
|
</UFormGroup>
|
||||||
|
<UFormGroup label="Ende:">
|
||||||
|
<UPopover :popper="{ placement: 'bottom-start' }">
|
||||||
|
<UButton
|
||||||
|
icon="i-heroicons-calendar-days-20-solid"
|
||||||
|
:label="selectedEndDay ? dayjs(selectedEndDay).format('DD.MM.YYYY') : 'Datum auswählen'"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<template #panel="{ close }">
|
||||||
|
<LazyDatePicker v-model="selectedEndDay" @close="changeRange" />
|
||||||
|
</template>
|
||||||
|
</UPopover>
|
||||||
|
</UFormGroup>
|
||||||
|
</template>
|
||||||
|
<template #right>
|
||||||
|
<UButton
|
||||||
|
@click="generateEvaluation"
|
||||||
|
>
|
||||||
|
Bericht erstellen
|
||||||
|
</UButton>
|
||||||
|
</template>
|
||||||
|
</UDashboardToolbar>
|
||||||
|
<UTabs
|
||||||
|
:items="[{label: 'Information'},{label: 'Bericht'}]"
|
||||||
|
class="p-5 h-100"
|
||||||
|
>
|
||||||
|
<template #item="{item}">
|
||||||
|
<div v-if="item.label === 'Information'">
|
||||||
|
<div class="truncate p-5">
|
||||||
|
<p>Eingreicht: {{Math.floor(workingTimeInfo.sumWorkingMinutesEingereicht/60)}}:{{String(workingTimeInfo.sumWorkingMinutesEingereicht % 60).padStart(2,"0")}} h</p>
|
||||||
|
<p>Bestätigt: {{Math.floor(workingTimeInfo.sumWorkingMinutesApproved/60)}}:{{String(workingTimeInfo.sumWorkingMinutesApproved % 60).padStart(2,"0")}} h</p>
|
||||||
|
<p>Soll Stunden: {{workingTimeInfo.monthlyWorkingHours}} h</p>
|
||||||
|
<p>Abwesend: </p>
|
||||||
|
<p>Ausgleich:</p>
|
||||||
|
<p>Inoffizielles Saldo: {{workingTimeInfo.saldoInOfficial}} h</p>
|
||||||
|
<p>Saldo: {{workingTimeInfo.saldo}} h</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<UTable
|
||||||
|
:rows="dataStore.getWorkingTimesByProfileId(itemInfo.id)"
|
||||||
|
:columns="[
|
||||||
|
{
|
||||||
|
key: 'state',
|
||||||
|
label: 'Status'
|
||||||
|
}, {
|
||||||
|
key: 'start',
|
||||||
|
label: 'Start'
|
||||||
|
}, {
|
||||||
|
key: 'end',
|
||||||
|
label: 'Ende'
|
||||||
|
}, {
|
||||||
|
key: 'duration',
|
||||||
|
label: 'Dauer'
|
||||||
|
}, {
|
||||||
|
key: 'notes',
|
||||||
|
label: 'Notizen'
|
||||||
|
}
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
<template #profile-data="{row}">
|
||||||
|
{{dataStore.profiles.find(profile => profile.id === row.profile) ? dataStore.profiles.find(profile => profile.id === row.profile).fullName : row.profile }}
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #start-data="{row}">
|
||||||
|
{{dayjs(row.startDate).format("HH:mm DD.MM.YY")}} Uhr
|
||||||
|
</template>
|
||||||
|
<template #end-data="{row}">
|
||||||
|
{{dayjs(row.endDate).format("HH:mm DD.MM.YY")}} Uhr
|
||||||
|
</template>
|
||||||
|
<template #duration-data="{row}">
|
||||||
|
{{getDuration(row).composed}}
|
||||||
|
</template>
|
||||||
|
</UTable>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="item.label === 'Bericht'">
|
||||||
|
<object
|
||||||
|
:data="uri"
|
||||||
|
v-if="showDocument"
|
||||||
|
type="application/pdf"
|
||||||
|
class="w-full previewDocument"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</UTabs>
|
||||||
|
|
||||||
|
|
||||||
|
<UDashboardPanelContent>
|
||||||
|
|
||||||
|
|
||||||
|
</UDashboardPanelContent>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.previewDocument {
|
||||||
|
height: 80vh;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -186,6 +186,11 @@ const getDuration = (time) => {
|
|||||||
{{dataStore.getProfileById(filterUser) ? dataStore.getProfileById(filterUser).fullName : "Kein Benutzer ausgewählt"}}
|
{{dataStore.getProfileById(filterUser) ? dataStore.getProfileById(filterUser).fullName : "Kein Benutzer ausgewählt"}}
|
||||||
</template>
|
</template>
|
||||||
</USelectMenu>
|
</USelectMenu>
|
||||||
|
<UButton
|
||||||
|
@click="router.push(`/workingtimes/evaluate/${filterUser}`)"
|
||||||
|
>
|
||||||
|
Auswertung
|
||||||
|
</UButton>
|
||||||
</template>
|
</template>
|
||||||
</UDashboardToolbar>
|
</UDashboardToolbar>
|
||||||
<div class="mx-3">
|
<div class="mx-3">
|
||||||
|
|||||||
Reference in New Issue
Block a user