forked from Kispi/Core
feat(webapp): add option to modify the account number
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
fe2eabaffc
commit
5aea42d33a
4 changed files with 128 additions and 12 deletions
|
@ -0,0 +1,84 @@
|
|||
<template>
|
||||
<AtomModal
|
||||
:id="id"
|
||||
ref="modal"
|
||||
:title="title"
|
||||
@close="handleClose"
|
||||
>
|
||||
<div class="flex place-items-center justify-between">
|
||||
<AtomInput
|
||||
v-model="accountNumber"
|
||||
class="w-4/12"
|
||||
@keyup.esc="modal?.close()"
|
||||
/>
|
||||
</div>
|
||||
<template #action>
|
||||
<label
|
||||
class="btn gap-2"
|
||||
:for="id"
|
||||
@click="modal?.close()"
|
||||
>
|
||||
<XCircleIcon class="h-6 w-6" />
|
||||
Abbrechen
|
||||
</label>
|
||||
<button
|
||||
class="btn gap-2"
|
||||
@click="handleSubmit()"
|
||||
>
|
||||
<CheckCircleIcon class="h-6 w-6" />
|
||||
Speichern
|
||||
</button>
|
||||
</template>
|
||||
</AtomModal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue';
|
||||
import { CheckCircleIcon, XCircleIcon } from '@heroicons/vue/24/outline';
|
||||
import AtomModal from '../atoms/AtomModal.vue';
|
||||
import AtomInput from '../atoms/AtomInput.vue';
|
||||
|
||||
const modal = ref<InstanceType<typeof AtomModal>>();
|
||||
const accountNumber = ref('');
|
||||
const accountId = ref('');
|
||||
|
||||
defineProps({
|
||||
id: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(['submit']);
|
||||
|
||||
function handleClose() {
|
||||
accountNumber.value = '';
|
||||
}
|
||||
|
||||
function handleSubmit() {
|
||||
if(!accountNumber.value) {
|
||||
return;
|
||||
}
|
||||
emit('submit', {
|
||||
id: accountId.value,
|
||||
accountNumber: accountNumber.value,
|
||||
});
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
show: (id: string) => {
|
||||
accountId.value = id;
|
||||
modal.value?.show();
|
||||
},
|
||||
close: () => modal.value?.close(),
|
||||
isOpen: () => modal.value?.isOpen(),
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
</style>
|
|
@ -20,7 +20,7 @@
|
|||
<td
|
||||
v-for="header in tableHeaders"
|
||||
:class="{
|
||||
'text-center': header.type == TableHeaderType.BUTTON_ACCOUNT,
|
||||
'text-center': [TableHeaderType.BUTTON_ACCOUNT, TableHeaderType.BUTTON_CHANGE_ACCOUNT_NUMBER].includes(header.type),
|
||||
}"
|
||||
>
|
||||
<span v-if="header.type === TableHeaderType.STRING">
|
||||
|
@ -55,12 +55,28 @@
|
|||
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"
|
||||
>
|
||||
<div
|
||||
class="tooltip normal-case"
|
||||
data-tip="Kontonummer ändern"
|
||||
@click="$emit('changeAccountNumber', entry.id)"
|
||||
>
|
||||
<CreditCardIcon class="h-6 w-6" />
|
||||
</div>
|
||||
</span>
|
||||
<span
|
||||
v-if="header.type === TableHeaderType.WAGE"
|
||||
:for="contactModalId"
|
||||
class="flex items-center gap-2"
|
||||
>
|
||||
<div class="dropdown-bottom dropdown">
|
||||
|
@ -93,7 +109,7 @@ 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, CurrencyDollarIcon } from '@heroicons/vue/24/outline';
|
||||
import { ChevronDownIcon, CreditCardIcon, CurrencyDollarIcon } from '@heroicons/vue/24/outline';
|
||||
|
||||
const settings = ref<SettingsResponse>();
|
||||
|
||||
|
@ -108,11 +124,6 @@ defineProps({
|
|||
type: Array as PropType<any[]>,
|
||||
required: true,
|
||||
},
|
||||
contactModalId: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: '',
|
||||
},
|
||||
hideHeader: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
|
@ -128,6 +139,7 @@ defineEmits<{
|
|||
click: [id: string],
|
||||
selectShift: [{id: string, shift: Shifts}],
|
||||
selectWage: [{id: string, wageFactor: number}],
|
||||
changeAccountNumber: [id: string],
|
||||
}>();
|
||||
|
||||
function removeFocus() {
|
||||
|
@ -142,6 +154,7 @@ export enum TableHeaderType {
|
|||
CURRENCY,
|
||||
DATETIME,
|
||||
BUTTON_ACCOUNT,
|
||||
BUTTON_CHANGE_ACCOUNT_NUMBER,
|
||||
WAGE,
|
||||
SHIFT,
|
||||
}
|
||||
|
|
|
@ -10,16 +10,21 @@
|
|||
class="mb-4"
|
||||
/>
|
||||
<MoleculeDataTable
|
||||
v-if="accounts"
|
||||
v-if="accounts && changeAccountNumberModal"
|
||||
:table-headers="tableHeaders"
|
||||
:data="accounts"
|
||||
@change-account-number="changeAccountNumberModal.show($event);"
|
||||
/>
|
||||
<MoleculeChanceAccountNumberModal
|
||||
id="changeAccountNumber"
|
||||
ref="changeAccountNumberModal"
|
||||
title="Kontonummer ändern"
|
||||
@submit="changeAccountNumber"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
// TODO: Add button in each row to change the accountNumber inside an modal
|
||||
|
||||
import { onMounted, onUnmounted, ref, watch } from 'vue';
|
||||
import { useEventBus } from '@vueuse/core';
|
||||
import { UnsubscribeFunc } from 'pocketbase';
|
||||
|
@ -30,10 +35,12 @@ import { AuthService } from '../../services/auth.service';
|
|||
import AtomInput from '../atoms/AtomInput.vue';
|
||||
import MoleculeDataTable, { TableHeaderType } from '../molecules/MoleculeDataTable.vue';
|
||||
import MoleculeAuthDialog from '../molecules/MoleculeAuthDialog.vue';
|
||||
import MoleculeChanceAccountNumberModal from '../molecules/MoleculeChanceAccountNumberModal.vue';
|
||||
|
||||
const isAdmin = ref(false);
|
||||
const accountsSubscription = ref<UnsubscribeFunc>();
|
||||
const transactionsSubscription = ref<UnsubscribeFunc>();
|
||||
const changeAccountNumberModal = ref<InstanceType<typeof MoleculeChanceAccountNumberModal>>();
|
||||
|
||||
const accounts = ref<AccountsListResponse<number, string>[]>([]);
|
||||
const initAccounts = ref<AccountsListResponse<number, string>[]>([]);
|
||||
|
@ -69,6 +76,11 @@ const tableHeaders = [
|
|||
key: '',
|
||||
type: TableHeaderType.BUTTON_ACCOUNT,
|
||||
},
|
||||
{
|
||||
title: 'Knr. änd.',
|
||||
key: '',
|
||||
type: TableHeaderType.BUTTON_CHANGE_ACCOUNT_NUMBER,
|
||||
},
|
||||
];
|
||||
|
||||
useEventBus<boolean>('isAdmin').on(state => {
|
||||
|
@ -99,6 +111,10 @@ function search(value: string) {
|
|||
}
|
||||
}
|
||||
|
||||
function changeAccountNumber(account: {id: string, accountNumber: string}) {
|
||||
AccountService.updateAccountNumber(account.id, account.accountNumber);
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
isAdmin.value = AuthService.isAdmin();
|
||||
if(isAdmin.value) {
|
||||
|
|
|
@ -22,6 +22,9 @@ export class AccountService {
|
|||
public static async addAccount(account: AccountsRecord): Promise<AccountsResponse> {
|
||||
return COLLECTION.create(account, { $cancelKey: `${account.firstName}.${account.lastName}.${account.grade}` });
|
||||
}
|
||||
public static async updateAccountNumber(accountId: string, accountNumber: string): Promise<AccountsResponse> {
|
||||
return COLLECTION.update(accountId, { accountNumber });
|
||||
}
|
||||
public static async updateShift(accountId: string, shift: string): Promise<AccountsResponse> {
|
||||
return COLLECTION.update(accountId, { shift });
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue