New eveal #32

Merged
Sirttas merged 115 commits from new-eveal into main 2026-07-14 17:15:11 +02:00
9 changed files with 31 additions and 31 deletions
Showing only changes of commit 55c2628c75 - Show all commits
+1 -1
View File
@@ -37,7 +37,7 @@ describe('useSort', () => {
}) })
test('Hides ignored columns', () => { test('Hides ignored columns', () => {
const { showColumn } = useSort(array, { ignoredColums: ['key1'] }) const { showColumn } = useSort(array, { ignoredColumns: ['key1'] })
expect(showColumn('key1')).toBe(false) expect(showColumn('key1')).toBe(false)
}) })
+2 -2
View File
@@ -5,7 +5,7 @@ export type SortDirection = "asc" | "desc";
export type UseSortOptions = { export type UseSortOptions = {
defaultSortKey?: string; defaultSortKey?: string;
defaultSortDirection?: SortDirection; defaultSortDirection?: SortDirection;
ignoredColums?: MaybeRefOrGetter<string[]>; ignoredColumns?: MaybeRefOrGetter<string[]>;
headerComponent?: HeaderComponent; headerComponent?: HeaderComponent;
}; };
@@ -16,7 +16,7 @@ export const useSort = <T>(array: MaybeRefOrGetter<T[]>, options?: UseSortOption
sortKey.value = key; sortKey.value = key;
sortDirection.value = direction; sortDirection.value = direction;
}; };
const showColumn = (sortKey: string) => !toValue(options?.ignoredColums)?.includes(sortKey); const showColumn = (sortKey: string) => !toValue(options?.ignoredColumns)?.includes(sortKey);
const headerProps = computed(() => ({ const headerProps = computed(() => ({
onSort: sortBy, onSort: sortBy,
showColumn, showColumn,
@@ -31,7 +31,7 @@ interface Props {
items?: AcquiredType[]; items?: AcquiredType[];
infoOnly?: boolean; infoOnly?: boolean;
showAll?: boolean; showAll?: boolean;
ignoredColums?: string[] | string; ignoredColumns?: string[] | string;
defaultSortKey?: string; defaultSortKey?: string;
} }
@@ -44,24 +44,24 @@ const props = withDefaults(defineProps<Props>(), {
items: () => [], items: () => [],
infoOnly: false, infoOnly: false,
showAll: false, showAll: false,
ignoredColums: () => [], ignoredColumns: () => [],
defaultSortKey: 'precentProfit', defaultSortKey: 'precentProfit',
}); });
defineEmits<Emits>(); defineEmits<Emits>();
const columnsToIgnore = computed(() => { const columnsToIgnore = computed(() => {
const ignoredColums = typeof props.ignoredColums === 'string' ? [props.ignoredColums] : [...props.ignoredColums]; const ignoredColumns = typeof props.ignoredColumns === 'string' ? [props.ignoredColumns] : [...props.ignoredColumns];
if (props.infoOnly && !ignoredColums.includes('buttons')) { if (props.infoOnly && !ignoredColumns.includes('buttons')) {
ignoredColums.push('buttons'); ignoredColumns.push('buttons');
} }
if (!props.showAll && !ignoredColums.includes('ledger')) { if (!props.showAll && !ignoredColumns.includes('ledger')) {
ignoredColums.push('ledger'); ignoredColumns.push('ledger');
} }
if (ignoredColums.includes('ledger')) { if (ignoredColumns.includes('ledger')) {
ignoredColums.push('ledgerName'); ignoredColumns.push('ledgerName');
} }
return ignoredColums; return ignoredColumns;
}); });
const marketTaxStore = useMarketTaxStore(); const marketTaxStore = useMarketTaxStore();
@@ -136,7 +136,7 @@ const { sortedArray, headerProps, showColumn } = useSort<Result>(computed(() =>
}), { }), {
defaultSortKey: props.defaultSortKey, defaultSortKey: props.defaultSortKey,
defaultSortDirection: 'desc', defaultSortDirection: 'desc',
ignoredColums: columnsToIgnore ignoredColumns: columnsToIgnore
}) })
const getLineColor = (result: Result) => { const getLineColor = (result: Result) => {
if (result.precentProfit >= (threshold.value / 100)) { if (result.precentProfit >= (threshold.value / 100)) {
+5 -5
View File
@@ -1,5 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import {getMarketTypes, MarketTypePrice, useApraisalStore} from "@/market"; import {getMarketTypes, MarketTypePrice, useAppraisalStore} from "@/market";
import {ref, watch} from 'vue'; import {ref, watch} from 'vue';
import {AcquiredType} from './AcquiredType'; import {AcquiredType} from './AcquiredType';
import {RawAcquiredType} from './acquisition'; import {RawAcquiredType} from './acquisition';
@@ -9,7 +9,7 @@ import SellModal from './SellModal.vue';
interface Props { interface Props {
items: RawAcquiredType[]; items: RawAcquiredType[];
ignoredColums?: string[] | string; ignoredColumns?: string[] | string;
ledgerId?: string; ledgerId?: string;
} }
@@ -18,7 +18,7 @@ const props = defineProps<Props>();
const buyModal = ref<typeof BuyModal>(); const buyModal = ref<typeof BuyModal>();
const sellModal = ref<typeof SellModal>(); const sellModal = ref<typeof SellModal>();
const apraisalStore = useApraisalStore(); const appraisalStore = useAppraisalStore();
const enriched = ref<AcquiredType[]>([]); const enriched = ref<AcquiredType[]>([]);
const refresh = async (itms: RawAcquiredType[] = props.items) => { const refresh = async (itms: RawAcquiredType[] = props.items) => {
@@ -28,7 +28,7 @@ const refresh = async (itms: RawAcquiredType[] = props.items) => {
} }
const types = await getMarketTypes([...new Set(itms.map(i => i.type))]); const types = await getMarketTypes([...new Set(itms.map(i => i.type))]);
const prices = await apraisalStore.getPrices(types); const prices = await appraisalStore.getPrices(types);
enriched.value = itms.map(i => { enriched.value = itms.map(i => {
const price = prices.find(p => p.type.id === i.type) as MarketTypePrice; const price = prices.find(p => p.type.id === i.type) as MarketTypePrice;
@@ -49,7 +49,7 @@ defineExpose({refresh});
<template> <template>
<template v-if="enriched.length > 0"> <template v-if="enriched.length > 0">
<AcquisitionResultTable :items="enriched" :ignoredColums="ignoredColums" @buy="(types, price, buy, sell) => buyModal?.open(types[0].type, { 'Price': price, 'Buy': buy, 'Sell': sell }, props.ledgerId)" @sell="types => sellModal?.open(types, props.ledgerId)" /> <AcquisitionResultTable :items="enriched" :ignoredColumns="ignoredColumns" @buy="(types, price, buy, sell) => buyModal?.open(types[0].type, { 'Price': price, 'Buy': buy, 'Sell': sell }, props.ledgerId)" @sell="types => sellModal?.open(types, props.ledgerId)" />
<BuyModal ref="buyModal" /> <BuyModal ref="buyModal" />
<SellModal ref="sellModal" /> <SellModal ref="sellModal" />
</template> </template>
+1 -1
View File
@@ -8,7 +8,7 @@ import {getMammonPrices} from './mammon';
const CACHE_DURATION = 1000 * 60 * 5; // 5 minutes const CACHE_DURATION = 1000 * 60 * 5; // 5 minutes
const BATCH_SIZE = 100; const BATCH_SIZE = 100;
export const useApraisalStore = defineStore('appraisal', () => { export const useAppraisalStore = defineStore('appraisal', () => {
const cache: RegionalMarketCache<MarketTypePrice> = new RegionalMarketCache(CACHE_DURATION); const cache: RegionalMarketCache<MarketTypePrice> = new RegionalMarketCache(CACHE_DURATION);
const getPricesUncached = getMammonPrices; const getPricesUncached = getMammonPrices;
+4 -4
View File
@@ -27,7 +27,7 @@ type Result = {
interface Props { interface Props {
items?: ScanResult[]; items?: ScanResult[];
infoOnly?: boolean; infoOnly?: boolean;
ignoredColums?: string[] | string; ignoredColumns?: string[] | string;
} }
const scoreFormater = new Intl.NumberFormat("en-US", { const scoreFormater = new Intl.NumberFormat("en-US", {
@@ -40,7 +40,7 @@ const volumeFormater = new Intl.NumberFormat("en-US", {
const props = withDefaults(defineProps<Props>(), { const props = withDefaults(defineProps<Props>(), {
items: () => [], items: () => [],
infoOnly: false, infoOnly: false,
ignoredColums: () => [] ignoredColumns: () => []
}); });
const acquiredTypesStore = useAcquiredTypesStore(); const acquiredTypesStore = useAcquiredTypesStore();
@@ -54,7 +54,7 @@ const trackedTrends = useStorage<MarketTrend[]>('market-scan-trends', [
MarketTrends.Down, MarketTrends.Down,
]); ]);
const columnsToIgnore = computed(() => const columnsToIgnore = computed(() =>
typeof props.ignoredColums === 'string' ? [props.ignoredColums] : props.ignoredColums typeof props.ignoredColumns === 'string' ? [props.ignoredColumns] : props.ignoredColumns
); );
const { sortedArray, headerProps, showColumn } = useSort<Result>(computed(() => props.items const { sortedArray, headerProps, showColumn } = useSort<Result>(computed(() => props.items
.filter(r => r.type.name.toLowerCase().includes(filter.value.toLowerCase())) .filter(r => r.type.name.toLowerCase().includes(filter.value.toLowerCase()))
@@ -82,7 +82,7 @@ const { sortedArray, headerProps, showColumn } = useSort<Result>(computed(() =>
}).filter(r => !onlyCheap.value || (r.buy <= r.q1 && r.profit >= (threshold.value / 100)))), { }).filter(r => !onlyCheap.value || (r.buy <= r.q1 && r.profit >= (threshold.value / 100)))), {
defaultSortKey: 'score', defaultSortKey: 'score',
defaultSortDirection: 'desc', defaultSortDirection: 'desc',
ignoredColums: columnsToIgnore ignoredColumns: columnsToIgnore
}) })
const getLineColor = (result: Result) => { const getLineColor = (result: Result) => {
if (props.infoOnly) { if (props.infoOnly) {
+1 -1
View File
@@ -19,6 +19,6 @@ const items = useProcessedResource<RawAcquiredType[]>(async () => {
<template> <template>
<div class="mt-4"> <div class="mt-4">
<AcquisitionsPanel :items="items" :ledgerId="ledgerId" :ignoredColums="['date', 'ledger']" /> <AcquisitionsPanel :items="items" :ledgerId="ledgerId" :ignoredColumns="['date', 'ledger']" />
</div> </div>
</template> </template>
+1 -1
View File
@@ -24,6 +24,6 @@ const {active: autoRefresh, toggle: toggleAutoRefresh} = useAutoRefresh(refresh,
</button> </button>
</div> </div>
</div> </div>
<AcquisitionsPanel ref="panel" :items="acquiredTypesStore.acquiredTypes" ignoredColums="date" /> <AcquisitionsPanel ref="panel" :items="acquiredTypesStore.acquiredTypes" ignoredColumns="date" />
</div> </div>
</template> </template>
+5 -5
View File
@@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import {ClipboardButton} from '@/components'; import {ClipboardButton} from '@/components';
import {getMarketType, MarketType, MarketTypeInput, useApraisalStore, useMarketTaxStore} from "@/market"; import {getMarketType, MarketType, MarketTypeInput, useAppraisalStore, useMarketTaxStore} from "@/market";
import {AcquisitionResultTable, BuyModal} from '@/market/acquisition'; import {AcquisitionResultTable, BuyModal} from '@/market/acquisition';
import {ScanResultTable, toScanResult} from '@/market/scan'; import {ScanResultTable, toScanResult} from '@/market/scan';
import {acquisitionApi, marketApi} from "@/mammon"; import {acquisitionApi, marketApi} from "@/mammon";
@@ -18,10 +18,10 @@ const router = useRouter();
const item = ref<MarketType>(); const item = ref<MarketType>();
const inputItem = ref<MarketType>(); const inputItem = ref<MarketType>();
const apraisalStore = useApraisalStore(); const appraisalStore = useAppraisalStore();
const marketTaxStore = useMarketTaxStore(); const marketTaxStore = useMarketTaxStore();
const days = useStorage('market-scan-days', 365); const days = useStorage('market-scan-days', 365);
const price = computedAsync(() => item.value ? apraisalStore.getPrice(item.value) : undefined); const price = computedAsync(() => item.value ? appraisalStore.getPrice(item.value) : undefined);
const result = computedAsync(async () => { const result = computedAsync(async () => {
if (!item.value) { if (!item.value) {
return undefined; return undefined;
@@ -107,11 +107,11 @@ watch(useRoute(), async route => {
</div> </div>
<div v-if="result" class="mb-4"> <div v-if="result" class="mb-4">
<span>Market Info:</span> <span>Market Info:</span>
<ScanResultTable :items="[result]" infoOnly :ignoredColums="['name', 'acquisitions']" /> <ScanResultTable :items="[result]" infoOnly :ignoredColumns="['name', 'acquisitions']" />
</div> </div>
<div v-if="acquisitions && acquisitions.length > 0"> <div v-if="acquisitions && acquisitions.length > 0">
<span>Acquisitions:</span> <span>Acquisitions:</span>
<AcquisitionResultTable :items="acquisitions" infoOnly showAll :ignoredColums="['name', 'buy', 'sell']" defaultSortKey="date"/> <AcquisitionResultTable :items="acquisitions" infoOnly showAll :ignoredColumns="['name', 'buy', 'sell']" defaultSortKey="date"/>
</div> </div>
</template> </template>
<BuyModal ref="buyModal" /> <BuyModal ref="buyModal" />