106 lines
3.3 KiB
Vue
106 lines
3.3 KiB
Vue
<script setup lang="ts">
|
|
|
|
import {findAllTransactionInLeger, useLedgerParam} from "@/ledger";
|
|
import {computedAsync} from "@vueuse/core";
|
|
import {TransactionResponse} from "@/generated/mammon";
|
|
import {IskLabel} from "@/market";
|
|
import {SortableHeader, useSort, VirtualScrollTable} from "@/components/table";
|
|
import {TransferList, TransferTypes} from "@/transaction";
|
|
import {Dropdown} from "@/components";
|
|
import {CharacterLabel, useCharactersStore} from "@/characters";
|
|
import {formatEveDate} from "@/formaters.ts";
|
|
|
|
const {ledgerId} = useLedgerParam();
|
|
const {findById} = useCharactersStore();
|
|
|
|
const transactions = computedAsync<TransactionResponse[]>(async () => {
|
|
if (ledgerId.value) {
|
|
return await findAllTransactionInLeger(ledgerId.value);
|
|
}
|
|
return [];
|
|
}, []);
|
|
|
|
const { sortedArray, headerProps } = useSort(computedAsync(() => Promise.all(transactions.value.map(async transaction => {
|
|
const character = await findById(transaction.characterId);
|
|
return {
|
|
character,
|
|
characterName: character?.name ?? "",
|
|
transactionId: transaction.transactionId,
|
|
description: transaction.description,
|
|
date: new Date(transaction.datetime),
|
|
balance: getIskBalance(transaction),
|
|
transfers: transaction.transfers
|
|
}
|
|
})), []), { defaultSortKey: 'date', defaultSortDirection: 'desc' });
|
|
|
|
const getIskBalance = (transaction: TransactionResponse) => {
|
|
if (!ledgerId.value) {
|
|
return 0;
|
|
}
|
|
|
|
let balance = 0;
|
|
|
|
for (const transfer of transaction.transfers) {
|
|
if (transfer.type === TransferTypes.Isk) {
|
|
if (transfer.toLedgerId === ledgerId.value) {
|
|
balance += transfer.amount;
|
|
} else if (transfer.fromLedgerId === ledgerId.value) {
|
|
balance -= transfer.amount;
|
|
}
|
|
}
|
|
}
|
|
return balance;
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<div class="mt-4">
|
|
<VirtualScrollTable :list="sortedArray" :itemHeight="33" bottom="1rem">
|
|
<template #default="{ list }">
|
|
<thead>
|
|
<tr>
|
|
<SortableHeader v-bind="headerProps" sortKey="characterName">Character</SortableHeader>
|
|
<SortableHeader v-bind="headerProps" sortKey="date">Date</SortableHeader>
|
|
<SortableHeader v-bind="headerProps" sortKey="balance">Isk Change</SortableHeader>
|
|
<SortableHeader v-bind="headerProps" sortKey="description">Description</SortableHeader>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr v-for="t in list" :key="t.data.transactionId">
|
|
<td>
|
|
<CharacterLabel v-if="t.data.character" :character="t.data.character" />
|
|
</td>
|
|
<td>
|
|
<Dropdown class="transfer-dropdown">
|
|
<template #button>
|
|
{{formatEveDate(t.data.date)}}
|
|
</template>
|
|
<TransferList :transfers="t.data.transfers" />
|
|
</Dropdown>
|
|
</td>
|
|
<td class="text-right">
|
|
<IskLabel :amount="t.data.balance" />
|
|
</td>
|
|
<td>{{t.data.description}}</td>
|
|
</tr>
|
|
</tbody>
|
|
</template>
|
|
</VirtualScrollTable>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped>
|
|
@reference "@/style.css";
|
|
|
|
tr:hover>td>.transfer-dropdown :deep(>button) {
|
|
@apply bg-slate-900;
|
|
}
|
|
|
|
.transfer-dropdown :deep(>button) {
|
|
@apply bg-slate-800 hover:bg-slate-900 border-none flex items-center w-full;
|
|
}
|
|
|
|
.transfer-dropdown.dropdown-open :deep(>button) {
|
|
@apply bg-slate-800 rounded-b-none;
|
|
}
|
|
</style> |