Files
FEDEO/spaces/pages/timetracking.vue
flfeders 9e092823e4 Added Vehicles
Added Bankimport, BankAccounts, BankStatements
Some Visual Changes
Added Contacts
Changes in VendorInvoices
Added layouts with default an one for Login PAge
Added Input Group Component
2023-12-22 17:50:22 +01:00

407 lines
9.6 KiB
Vue

<script setup>
import * as dayjs from "dayjs";
import VueDatePicker from '@vuepic/vue-datepicker'
import '@vuepic/vue-datepicker/dist/main.css'
definePageMeta({
middleware: "auth"
})
const supabase = useSupabaseClient()
const user = useSupabaseUser()
const toast = useToast()
const {times, projects, profiles, jobs} = storeToRefs(useDataStore())
const {fetchTimes, getTimeTypes} = useDataStore()
const timeTypes = getTimeTypes
const timeInfo = ref({
user: "",
start: "",
end: null,
notes: null,
projectId: null,
type: null
})
const filteredRows = computed(() => {
if(user.value && times.value) {
return times.value.filter(time => time.user === user.value.id)
} else {
return []
}
})
const createTimeInfo = ref({
user: "",
start: new Date(),
end: "",
notes: null,
projectId: null,
type: null
})
const columns = [
{
key: "user",
label: "Benutzer"
},
{
key:"start",
label:"Start"
},
{
key:"type",
label:"Typ"
},
{
key: "end",
label: "Ende"
},
{
key: "duration",
label: "Dauer"
},
{
key: "projectId",
label: "Projekt"
},
{
key: "job",
label: "Job"
},
{
key: "notes",
label: "Notizen"
}
]
const runningTimeInfo = ref({})
const showAddTimeModal = ref(false)
const startTime = async () => {
console.log("started")
timeInfo.value.user = user.value.id
timeInfo.value.start = new Date().toISOString()
const {data,error} = await supabase
.from("times")
.insert([timeInfo.value])
.select()
if(error) {
console.log(error)
} else if(data) {
timeInfo.value = data[0]
await fetchTimes()
runningTimeInfo.value = times.value.find(time => time.user == user.value.id && !time.end)
}
}
const stopStartedTime = async () => {
console.log(runningTimeInfo.value)
runningTimeInfo.value.end = new Date().toISOString()
const mapNumRange = (num, inMin, inMax, outMin, outMax) =>
((num - inMin) * (outMax - outMin)) / (inMax - inMin) + outMin;
runningTimeInfo.value.duration = Math.round(mapNumRange(Math.abs(new Date(runningTimeInfo.value.end) - new Date(runningTimeInfo.value.start))/1000/60,0,60,0,1)*100)/100
const {data,error} = await supabase
.from("times")
.update(runningTimeInfo.value)
.eq('id',runningTimeInfo.value.id)
.select()
console.log(data)
if(error) {
console.log(error)
} else {
toast.add({title: "Zeit erfolgreich gestoppt"})
runningTimeInfo.value = {}
fetchTimes()
}
}
if(times.value.find(time => time.user == user.value.id && !time.end)) {
runningTimeInfo.value = times.value.find(time => time.user == user.value.id && !time.end)
}
const createTime = async () => {
const {data,error} = await supabase
.from("times")
.insert([createTimeInfo.value])
.select()
if(error) {
console.log(error)
} else if(data) {
createTimeInfo.value = {}
toast.add({title: "Zeit erfolgreich erstellt"})
showAddTimeModal.value = false
await fetchTimes()
}
}
const format = (date) => {
let dateFormat = dayjs(date).format("DD.MM.YY HH:mm")
return `${dateFormat}`;
}
const selectStartedTime = () => {
runningTimeInfo.value = times.value.find(time => time.user == user.value.id && !time.end)
}
//selectStartedTime()
</script>
<template>
<div class="flex items-center gap-1">
<UButton
class="controlButton"
@click="startTime"
:disabled="runningTimeInfo.id"
>
Start
</UButton>
<UButton
class="controlButton"
@click="stopStartedTime"
:disabled="!runningTimeInfo.id"
>
Stop
</UButton>
<UButton
class="controlButton"
@click="showAddTimeModal = true"
>
Erstellen
</UButton>
</div>
<div v-if="runningTimeInfo.id" class="mt-3">
Start: {{dayjs(runningTimeInfo.start).format("DD.MM.YY HH:mm")}}
<UFormGroup
label="Notizen:"
>
<UTextarea
v-model="runningTimeInfo.notes"
/>
</UFormGroup>
<UFormGroup
label="Projekt:"
>
<USelectMenu
:options="projects"
option-attribute="name"
value-attribute="id"
v-model="runningTimeInfo.projectId"
>
<template #label>
{{ projects.find(project => project.id === runningTimeInfo.projectId) ? projects.find(project => project.id === runningTimeInfo.projectId).name : "Projekt auswählen" }}
</template>
</USelectMenu>
</UFormGroup>
<UFormGroup
label="Job:"
>
<USelectMenu
:options="jobs"
option-attribute="title"
value-attribute="id"
v-model="runningTimeInfo.job"
>
<template #label>
{{ jobs.find(job => job.id === runningTimeInfo.job) ? jobs.find(job => job.id === runningTimeInfo.job).title : "Job auswählen" }}
</template>
</USelectMenu>
</UFormGroup>
<UFormGroup
label="Kategorie:"
>
<USelectMenu
v-model="runningTimeInfo.type"
:options="timeTypes"
option-attribute="label"
value-attribute="label"
>
<template #label>
{{runningTimeInfo.type ? runningTimeInfo.type : "Kategorie auswählen"}}
</template>
</USelectMenu>
</UFormGroup>
</div>
<UModal
v-model="showAddTimeModal"
>
<UCard>
<template #header>
Zeiteintrag erstellen
</template>
<UFormGroup
label="Start:"
>
<VueDatePicker
v-model="createTimeInfo.start"
locale="de"
cancel-text="Abbrechen"
select-text="Auswählen"
now-button-label="Jetzt"
text-input="MM.dd.yyyy HH:mm"
:dark="useColorMode().value !== 'light'"
:format="format"
:preview-format="format"
/>
</UFormGroup>
<UFormGroup
label="Ende:"
>
<VueDatePicker
v-model="createTimeInfo.end"
locale="de"
cancel-text="Abbrechen"
select-text="Auswählen"
now-button-label="Jetzt"
text-input="MM.dd.yyyy HH:mm"
:dark="useColorMode().value !== 'light'"
:format="format"
:preview-format="format"
/>
</UFormGroup>
<!-- <UFormGroup
label="Dauer:"
>
<UInput
/>
</UFormGroup>-->
<UFormGroup
label="Benutzer:"
>
<USelectMenu
:options="profiles"
v-model="createTimeInfo.user"
option-attribute="firstName"
value-attribute="id"
>
<template #label>
{{profiles.find(profile => profile.id === createTimeInfo.user) ? profiles.find(profile => profile.id === createTimeInfo.user).firstName : "Benutzer auswählen"}}
</template>
</USelectMenu>
</UFormGroup>
<UFormGroup
label="Projekt:"
>
<USelectMenu
:options="projects"
v-model="createTimeInfo.projectId"
option-attribute="name"
value-attribute="id"
>
<template #label>
{{projects.find(project => project.id === createTimeInfo.projectId) ? projects.find(project => project.id === createTimeInfo.projectId).name : "Projekt auswählen"}}
</template>
</USelectMenu>
</UFormGroup>
<UFormGroup
label="Job:"
>
<USelectMenu
:options="jobs"
option-attribute="title"
value-attribute="id"
v-model="createTimeInfo.job"
>
<template #label>
{{ jobs.find(job => job.id === runningTimeInfo.job) ? jobs.find(job => job.id === runningTimeInfo.job).title : "Job auswählen" }}
</template>
</USelectMenu>
</UFormGroup>
<UFormGroup
label="Typ:"
>
<USelectMenu
v-model="runningTimeInfo.type"
:options="timeTypes"
option-attribute="label"
value-attribute="label"
>
<template #label>
{{runningTimeInfo.type ? runningTimeInfo.type : "Kategorie auswählen"}}
</template>
</USelectMenu>
</UFormGroup>
<UFormGroup
label="Notizen:"
>
<UTextarea
v-model="createTimeInfo.notes"
/>
</UFormGroup>
<template #footer>
<UButton
@click="createTime"
>
Erstellen
</UButton>
</template>
</UCard>
</UModal>
<UDivider class="mt-3"/>
<UTable
class="mt-3"
:columns="columns"
:rows="filteredRows"
:empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: 'Noch keine Einträge' }"
>
<template #user-data="{row}">
{{profiles.find(profile => profile.id === row.user) ? profiles.find(profile => profile.id === row.user).firstName + " " + profiles.find(profile => profile.id === row.user).lastName : row.user }}
</template>
<template #start-data="{row}">
{{dayjs(row.start).format("DD.MM.YY HH:mm")}}
</template>
<template #end-data="{row}">
{{dayjs(row.end).format("DD.MM.YY HH:mm")}}
</template>
<template #projectId-data="{row}">
{{projects.find(project => project.id === row.projectId) ? projects.find(project => project.id === row.projectId).name : ""}}
</template>
<template #job-data="{row}">
{{jobs.find(job => job.id === row.job) ? jobs.find(job => job.id === row.job).title : ""}}
</template>
</UTable>
</template>
<style scoped>
.controlButton {
margin-right: 1em;
}
</style>