New eveal #32

Merged
Sirttas merged 115 commits from new-eveal into main 2026-07-14 17:15:11 +02:00
8 changed files with 154 additions and 31 deletions
Showing only changes of commit 8d73fe3ed1 - Show all commits
+51 -15
View File
@@ -1499,6 +1499,46 @@ components:
type: string type: string
required: required:
- type - type
ActivitySourceResponse:
type: object
description: "Where an activity or transaction came from: a character, a corporation\
\ wallet, or nothing (a manual entry)."
properties:
type:
type: string
description: The kind of source.
enum:
- CHARACTER
- CORPORATION
- NONE
example: CHARACTER
characterId:
type:
- integer
- "null"
format: int64
description: "EVE character id, when the source is a character."
example: 2112625428
corporationId:
type:
- integer
- "null"
format: int64
description: "EVE corporation id, when the source is a corporation."
example: 98000001
division:
type:
- integer
- "null"
format: int32
description: "Corporation wallet division (1-7), when the source is a corporation\
\ and it is known."
example: 4
required:
- characterId
- corporationId
- division
- type
IskTransferResponse: IskTransferResponse:
allOf: allOf:
- $ref: "#/components/schemas/TransferResponse" - $ref: "#/components/schemas/TransferResponse"
@@ -1563,13 +1603,10 @@ components:
format: uuid format: uuid
description: Unique transaction identifier. description: Unique transaction identifier.
example: 3fa85f64-5717-4562-b3fc-2c963f66afa6 example: 3fa85f64-5717-4562-b3fc-2c963f66afa6
characterId: source:
type: $ref: "#/components/schemas/ActivitySourceResponse"
- integer description: "Where the transaction is attributed: a character, a corporation,\
- "null" \ or nothing."
format: int64
description: "EVE character id the transaction is attributed to, if any."
example: 2112625428
datetime: datetime:
type: string type: string
format: date-time format: date-time
@@ -1585,9 +1622,9 @@ components:
items: items:
$ref: "#/components/schemas/TransferResponse" $ref: "#/components/schemas/TransferResponse"
required: required:
- characterId
- datetime - datetime
- description - description
- source
- transactionId - transactionId
- transfers - transfers
TransferResponse: TransferResponse:
@@ -1649,17 +1686,16 @@ components:
format: uuid format: uuid
description: Unique acquisition identifier. description: Unique acquisition identifier.
example: 3fa85f64-5717-4562-b3fc-2c963f66afa6 example: 3fa85f64-5717-4562-b3fc-2c963f66afa6
characterId: source:
type: integer $ref: "#/components/schemas/ActivitySourceResponse"
format: int64 description: "Where the acquisition came from: a character, a corporation,\
description: EVE character id that made the acquisition. \ or nothing."
example: 2112625428
marketTypeId: marketTypeId:
type: integer type: integer
format: int64 format: int64
description: EVE market type (item) id that was acquired. description: EVE market type (item) id that was acquired.
example: 34 example: 34
source: origin:
type: string type: string
description: How the item entered the inventory. description: How the item entered the inventory.
enum: enum:
@@ -1686,9 +1722,9 @@ components:
example: 5.42 example: 5.42
required: required:
- acquisitionId - acquisitionId
- characterId
- datetime - datetime
- marketTypeId - marketTypeId
- origin
- quantity - quantity
- remaining - remaining
- source - source
+32
View File
@@ -0,0 +1,32 @@
<script setup lang="ts">
import {computedAsync} from "@vueuse/core";
import {ActivitySourceResponse, ActivitySourceResponseTypeEnum} from "@/generated/mammon";
import {CharacterLabel, useCharactersStore} from "@/characters";
import {CorporationLabel} from "@/corporations";
interface Props {
source: ActivitySourceResponse;
size?: number;
}
const props = withDefaults(defineProps<Props>(), {
size: 32
});
const charactersStore = useCharactersStore();
const character = computedAsync(async () => {
if (props.source.type === ActivitySourceResponseTypeEnum.Character && props.source.characterId) {
return await charactersStore.findById(props.source.characterId);
}
return undefined;
}, undefined);
</script>
<template>
<CharacterLabel v-if="source.type === ActivitySourceResponseTypeEnum.Character && character" :character="character" :size="size" />
<CorporationLabel v-else-if="source.type === ActivitySourceResponseTypeEnum.Corporation && source.corporationId" :corporation-id="source.corporationId" :division="source.division" :size="size" />
<span v-else class="text-slate-400">&mdash;</span>
</template>
+1
View File
@@ -0,0 +1 @@
export {default as SourceLabel} from './SourceLabel.vue';
+19
View File
@@ -0,0 +1,19 @@
<script setup lang="ts">
interface Props {
corporationId: number;
division?: number | null;
size?: number;
}
const props = withDefaults(defineProps<Props>(), {
size: 32
})
</script>
<template>
<div class="flex">
<img class="me-2" :src="`https://images.evetech.net/corporations/${corporationId}/logo?size=${size}`" />
<span>Corporation<template v-if="division"> &middot; Division {{ division }}</template></span>
</div>
</template>
+1
View File
@@ -0,0 +1 @@
export {default as CorporationLabel} from './CorporationLabel.vue';
+37 -7
View File
@@ -32,9 +32,9 @@ export interface AcquisitionResponse {
*/ */
'acquisitionId': string; 'acquisitionId': string;
/** /**
* EVE character id that made the acquisition. * Where the acquisition came from: a character, a corporation, or nothing.
*/ */
'characterId': number; 'source': ActivitySourceResponse;
/** /**
* EVE market type (item) id that was acquired. * EVE market type (item) id that was acquired.
*/ */
@@ -42,7 +42,7 @@ export interface AcquisitionResponse {
/** /**
* How the item entered the inventory. * How the item entered the inventory.
*/ */
'source': AcquisitionResponseSourceEnum; 'origin': AcquisitionResponseOriginEnum;
/** /**
* When the acquisition occurred. * When the acquisition occurred.
*/ */
@@ -61,12 +61,42 @@ export interface AcquisitionResponse {
'unitCost': number; 'unitCost': number;
} }
export const AcquisitionResponseSourceEnum = { export const AcquisitionResponseOriginEnum = {
Bought: 'BOUGHT', Bought: 'BOUGHT',
Manual: 'MANUAL', Manual: 'MANUAL',
} as const; } as const;
export type AcquisitionResponseSourceEnum = typeof AcquisitionResponseSourceEnum[keyof typeof AcquisitionResponseSourceEnum]; export type AcquisitionResponseOriginEnum = typeof AcquisitionResponseOriginEnum[keyof typeof AcquisitionResponseOriginEnum];
/**
* Where an activity or transaction came from: a character, a corporation wallet, or nothing (a manual entry).
*/
export interface ActivitySourceResponse {
/**
* The kind of source.
*/
'type': ActivitySourceResponseTypeEnum;
/**
* EVE character id, when the source is a character.
*/
'characterId': number | null;
/**
* EVE corporation id, when the source is a corporation.
*/
'corporationId': number | null;
/**
* Corporation wallet division (1-7), when the source is a corporation and it is known.
*/
'division': number | null;
}
export const ActivitySourceResponseTypeEnum = {
Character: 'CHARACTER',
Corporation: 'CORPORATION',
None: 'NONE',
} as const;
export type ActivitySourceResponseTypeEnum = typeof ActivitySourceResponseTypeEnum[keyof typeof ActivitySourceResponseTypeEnum];
/** /**
* The balance of a ledger: its ISK total plus the quantity of each item type held. * The balance of a ledger: its ISK total plus the quantity of each item type held.
@@ -604,9 +634,9 @@ export interface TransactionResponse {
*/ */
'transactionId': string; 'transactionId': string;
/** /**
* EVE character id the transaction is attributed to, if any. * Where the transaction is attributed: a character, a corporation, or nothing.
*/ */
'characterId': number | null; 'source': ActivitySourceResponse;
/** /**
* When the transaction occurred. * When the transaction occurred.
*/ */
+2 -2
View File
@@ -1,7 +1,7 @@
import {defineStore} from "pinia"; import {defineStore} from "pinia";
import {computed, ref} from "vue"; import {computed, ref} from "vue";
import {acquisitionApi} from "@/mammon"; import {acquisitionApi} from "@/mammon";
import {AcquisitionResponse, AcquisitionResponseSourceEnum} from "@/generated/mammon"; import {AcquisitionResponse, ActivitySourceResponse} from "@/generated/mammon";
export type AcquiredTypeSource = 'bo' | 'so' | 'prod' | 'misc'; export type AcquiredTypeSource = 'bo' | 'so' | 'prod' | 'misc';
@@ -12,7 +12,7 @@ export type RawAcquiredType = {
remaining: number; remaining: number;
price: number; price: number;
date: Date; date: Date;
source: AcquisitionResponseSourceEnum; source: ActivitySourceResponse;
} }
const toAcquiredType = (a: AcquisitionResponse): RawAcquiredType => ({ const toAcquiredType = (a: AcquisitionResponse): RawAcquiredType => ({
+11 -7
View File
@@ -2,12 +2,13 @@
import {findAllTransactionInLeger, useLedgerParam} from "@/ledger"; import {findAllTransactionInLeger, useLedgerParam} from "@/ledger";
import {computedAsync} from "@vueuse/core"; import {computedAsync} from "@vueuse/core";
import {TransactionResponse} from "@/generated/mammon"; import {ActivitySourceResponseTypeEnum, TransactionResponse} from "@/generated/mammon";
import {IskLabel} from "@/market"; import {IskLabel} from "@/market";
import {SortableHeader, useSort, VirtualScrollTable} from "@/components/table"; import {SortableHeader, useSort, VirtualScrollTable} from "@/components/table";
import {TransferList, TransferTypes} from "@/transaction"; import {TransferList, TransferTypes} from "@/transaction";
import {Dropdown} from "@/components"; import {Dropdown} from "@/components";
import {CharacterLabel, useCharactersStore} from "@/characters"; import {SourceLabel} from "@/activity";
import {useCharactersStore} from "@/characters";
import {formatEveDate} from "@/formaters.ts"; import {formatEveDate} from "@/formaters.ts";
const {ledgerId} = useLedgerParam(); const {ledgerId} = useLedgerParam();
@@ -21,10 +22,13 @@ const transactions = computedAsync<TransactionResponse[]>(async () => {
}, []); }, []);
const { sortedArray, headerProps } = useSort(computedAsync(() => Promise.all(transactions.value.map(async transaction => { const { sortedArray, headerProps } = useSort(computedAsync(() => Promise.all(transactions.value.map(async transaction => {
const character = await charactersStore.findById(transaction.characterId); const source = transaction.source;
const character = source.type === ActivitySourceResponseTypeEnum.Character && source.characterId
? await charactersStore.findById(source.characterId)
: undefined;
return { return {
character, source,
characterName: character?.name ?? "", sourceName: character?.name ?? (source.type === ActivitySourceResponseTypeEnum.Corporation ? "Corporation" : ""),
transactionId: transaction.transactionId, transactionId: transaction.transactionId,
description: transaction.description, description: transaction.description,
date: new Date(transaction.datetime), date: new Date(transaction.datetime),
@@ -59,7 +63,7 @@ const getIskBalance = (transaction: TransactionResponse) => {
<template #default="{ list }"> <template #default="{ list }">
<thead> <thead>
<tr> <tr>
<SortableHeader v-bind="headerProps" sortKey="characterName">Character</SortableHeader> <SortableHeader v-bind="headerProps" sortKey="sourceName">Source</SortableHeader>
<SortableHeader v-bind="headerProps" sortKey="date">Date</SortableHeader> <SortableHeader v-bind="headerProps" sortKey="date">Date</SortableHeader>
<SortableHeader v-bind="headerProps" sortKey="balance">Isk Change</SortableHeader> <SortableHeader v-bind="headerProps" sortKey="balance">Isk Change</SortableHeader>
<SortableHeader v-bind="headerProps" sortKey="description">Description</SortableHeader> <SortableHeader v-bind="headerProps" sortKey="description">Description</SortableHeader>
@@ -68,7 +72,7 @@ const getIskBalance = (transaction: TransactionResponse) => {
<tbody> <tbody>
<tr v-for="t in list" :key="t.data.transactionId"> <tr v-for="t in list" :key="t.data.transactionId">
<td> <td>
<CharacterLabel v-if="t.data.character" :character="t.data.character" /> <SourceLabel :source="t.data.source" />
</td> </td>
<td> <td>
<Dropdown class="transfer-dropdown"> <Dropdown class="transfer-dropdown">