forked from Kispi/Core
All checks were successful
continuous-integration/drone/push Build is passing
166 lines
No EOL
5.5 KiB
Vue
166 lines
No EOL
5.5 KiB
Vue
<template>
|
|
<div
|
|
v-if="settings"
|
|
class="rounded-lg"
|
|
>
|
|
<table class="table-pin-rows table-zebra table">
|
|
<thead
|
|
v-if="!hideHeader"
|
|
class="uppercase"
|
|
>
|
|
<tr>
|
|
<th v-for="header in tableHeaders">{{ header.title }}</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody class="bg-base-100">
|
|
<tr
|
|
v-for="entry in data"
|
|
@click="$emit('click', entry.id)"
|
|
>
|
|
<td
|
|
v-for="header in tableHeaders"
|
|
:class="{
|
|
'text-center': [TableHeaderType.BUTTON_ACCOUNT, TableHeaderType.BUTTON_CHANGE_ACCOUNT_NUMBER].includes(header.type),
|
|
}"
|
|
>
|
|
<span v-if="header.type === TableHeaderType.STRING">
|
|
{{ entry[header.key] }}
|
|
</span>
|
|
<span v-else-if="header.type === TableHeaderType.DATE">
|
|
{{ DateService.toShortString(entry[header.key]) }}
|
|
</span>
|
|
<span v-else-if="header.type === TableHeaderType.DATETIME">
|
|
{{ entry[header.key] ? DateService.toString(parseISO(entry[header.key])): 'N/A' }}
|
|
</span>
|
|
<span v-else-if="header.type === TableHeaderType.CURRENCY">
|
|
{{ CurrencyService.toString(entry[header.key]) }}
|
|
</span>
|
|
<span v-else-if="header.type === TableHeaderType.SHIFT">
|
|
<div class="dropdown-bottom dropdown">
|
|
<label
|
|
tabindex="0"
|
|
class="btn bg-base-300 normal-case"
|
|
>{{ entry[header.key] }} <ChevronDownIcon class="h-4 w-4" /></label>
|
|
<ul
|
|
tabindex="0"
|
|
class="dropdown-content menu rounded-box z-[1] w-52 bg-base-100 p-2 shadow"
|
|
>
|
|
<li @click="$emit('selectShift', {id: entry.id, shift: Shifts.NONE}); removeFocus();"><a>{{ Shifts.NONE }}</a></li>
|
|
<li><a @click="$emit('selectShift', {id: entry.id, shift: Shifts.EARLY}); removeFocus();">{{ Shifts.EARLY }}</a></li>
|
|
<li><a @click="$emit('selectShift', {id: entry.id, shift: Shifts.LATE}); removeFocus();">{{ Shifts.LATE }}</a></li>
|
|
</ul>
|
|
</div>
|
|
</span>
|
|
<RouterLink
|
|
v-if="header.type === TableHeaderType.BUTTON_ACCOUNT"
|
|
:to="`/bank?accountNumber=${entry.accountNumber}`"
|
|
class="btn-ghost btn-sm btn p-1"
|
|
>
|
|
<div
|
|
class="tooltip normal-case"
|
|
data-tip="Transaktionen anzeigen"
|
|
>
|
|
<CurrencyDollarIcon class="h-6 w-6" />
|
|
</div>
|
|
</RouterLink>
|
|
<span
|
|
v-if="header.type === TableHeaderType.BUTTON_CHANGE_ACCOUNT_NUMBER"
|
|
class="btn-ghost btn-sm btn p-1"
|
|
@click="$emit('changeAccountNumber', entry.id)"
|
|
>
|
|
<div
|
|
class="tooltip normal-case"
|
|
data-tip="Kontonummer ändern"
|
|
>
|
|
<CreditCardIcon class="h-6 w-6" />
|
|
</div>
|
|
</span>
|
|
<span
|
|
v-if="header.type === TableHeaderType.WAGE"
|
|
class="flex items-center gap-2"
|
|
>
|
|
<div class="dropdown-bottom dropdown">
|
|
<label
|
|
tabindex="0"
|
|
class="btn bg-base-300 normal-case"
|
|
>{{ CurrencyService.toString(entry[header.key] * settings.minWage) }} / Tag <ChevronDownIcon class="h-4 w-4" /></label>
|
|
<ul
|
|
tabindex="0"
|
|
class="dropdown-content menu rounded-box z-[1] w-52 bg-base-100 p-2 shadow"
|
|
>
|
|
<li
|
|
v-for="i of settings.maxWageFactor"
|
|
@click="$emit('selectWage', {id: entry.id, wageFactor: i}); removeFocus();"
|
|
><a>{{ CurrencyService.toString(settings.minWage * i ) }} / Tag</a></li>
|
|
</ul>
|
|
</div>
|
|
</span>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</template>
|
|
|
|
<script lang="ts" setup>
|
|
import { PropType, onMounted, ref } from 'vue';
|
|
import { parseISO } from 'date-fns';
|
|
import { SettingsResponse } from '../../types/pocketbase.types';
|
|
import { DateService } from '../../services/date.service';
|
|
import { CurrencyService } from '../../services/currency.service';
|
|
import { SettingsService } from '../../services/settings.service';
|
|
import { Shifts } from '../../enums/shift.enum';
|
|
import { ChevronDownIcon, CreditCardIcon, CurrencyDollarIcon } from '@heroicons/vue/24/outline';
|
|
|
|
const settings = ref<SettingsResponse>();
|
|
|
|
defineProps({
|
|
tableHeaders: {
|
|
type: Array as PropType<{ title: string, key: string, type: TableHeaderType }[]>,
|
|
required: true,
|
|
},
|
|
data: {
|
|
// Explicit allow any types as this is a dynamic list of data
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
type: Array as PropType<any[]>,
|
|
required: true,
|
|
},
|
|
hideHeader: {
|
|
type: Boolean,
|
|
required: false,
|
|
default: false,
|
|
},
|
|
});
|
|
|
|
onMounted(async () => {
|
|
settings.value = await SettingsService.getSettings();
|
|
});
|
|
|
|
defineEmits<{
|
|
click: [id: string],
|
|
selectShift: [{id: string, shift: Shifts}],
|
|
selectWage: [{id: string, wageFactor: number}],
|
|
changeAccountNumber: [id: string],
|
|
}>();
|
|
|
|
function removeFocus() {
|
|
(document.activeElement as HTMLElement).blur();
|
|
}
|
|
</script>
|
|
|
|
<script lang="ts">
|
|
export enum TableHeaderType {
|
|
STRING,
|
|
DATE,
|
|
CURRENCY,
|
|
DATETIME,
|
|
BUTTON_ACCOUNT,
|
|
BUTTON_CHANGE_ACCOUNT_NUMBER,
|
|
WAGE,
|
|
SHIFT,
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
|
|
</style> |