type tracking

This commit is contained in:
2024-05-17 19:15:15 +02:00
parent 719dc60027
commit 08b28a83be
13 changed files with 63 additions and 75 deletions

View File

@@ -2,7 +2,7 @@
import { LoadingSpinner, Tooltip } from '@/components'; import { LoadingSpinner, Tooltip } from '@/components';
import { formatIsk } from '@/formaters'; import { formatIsk } from '@/formaters';
import { getHistory, jitaId } from '@/market'; import { getHistory, jitaId } from '@/market';
import { getHistoryQuartils } from '@/market/scan'; import { getHistoryQuartils } from '@/market/tracking';
import { ArrowTrendingDownIcon, ArrowTrendingUpIcon } from '@heroicons/vue/24/outline'; import { ArrowTrendingDownIcon, ArrowTrendingUpIcon } from '@heroicons/vue/24/outline';
import { computedAsync } from '@vueuse/core'; import { computedAsync } from '@vueuse/core';
import { ref, watchEffect } from 'vue'; import { ref, watchEffect } from 'vue';
@@ -85,4 +85,4 @@ watchEffect(async () => {
@apply rounded-t-md bg-slate-600; @apply rounded-t-md bg-slate-600;
} }
} }
</style> </style>@/market/tracking

View File

@@ -1,4 +1,3 @@
import { useAuthStore } from "@/auth";
import { marbasAxiosInstance } from "@/service"; import { marbasAxiosInstance } from "@/service";
import { defineStore } from "pinia"; import { defineStore } from "pinia";
import { computed, ref } from "vue"; import { computed, ref } from "vue";
@@ -18,9 +17,8 @@ const endpoint = '/api/acquisitions';
export const useAcquiredItemStore = defineStore('market-acquisition', () => { export const useAcquiredItemStore = defineStore('market-acquisition', () => {
const acquiredItems = ref<AcquiredMarketItem[]>([]); const acquiredItems = ref<AcquiredMarketItem[]>([]);
const authStore = useAuthStore();
const items = computed(() => acquiredItems.value); const types = computed(() => acquiredItems.value);
const addAcquiredItem = async (type: number, quantity: number, price: number) => { const addAcquiredItem = async (type: number, quantity: number, price: number) => {
acquiredItems.value = [...acquiredItems.value, (await marbasAxiosInstance.post<AcquiredMarketItem>(endpoint, { acquiredItems.value = [...acquiredItems.value, (await marbasAxiosInstance.post<AcquiredMarketItem>(endpoint, {
type: type, type: type,
@@ -29,7 +27,6 @@ export const useAcquiredItemStore = defineStore('market-acquisition', () => {
price: price, price: price,
date: new Date(), date: new Date(),
source: 'bo', source: 'bo',
user: authStore.userId,
})).data]; })).data];
}; };
const removeAcquiredItem = async (type: number, quantity: number) => { const removeAcquiredItem = async (type: number, quantity: number) => {
@@ -62,5 +59,5 @@ export const useAcquiredItemStore = defineStore('market-acquisition', () => {
marbasAxiosInstance.get<AcquiredMarketItem[]>(endpoint).then(res => acquiredItems.value = res.data.filter(item => item.remaining > 0)); marbasAxiosInstance.get<AcquiredMarketItem[]>(endpoint).then(res => acquiredItems.value = res.data.filter(item => item.remaining > 0));
return { items, addAcquiredItem, removeAcquiredItem }; return { types, addAcquiredItem, removeAcquiredItem };
}); });

View File

@@ -1,5 +0,0 @@
export * from './HistoryQuartils';
export * from './scan';
export { default as ScanResultTable } from './ScanResultTable.vue';

View File

@@ -1,40 +0,0 @@
import { MarketOrderHistory, MarketType, MarketTypePrice, getHistory, jitaId } from "@/market";
import { defineStore } from "pinia";
import { computed, ref } from "vue";
export type ScanResult = {
type: MarketType;
history: MarketOrderHistory[];
buy: number,
sell: number,
orderCount: number,
}
type MarketScan = {
owner: string,
types: number[]
};
const marketScans = 'marketScans';
export const useMarketScanStore = defineStore(marketScans, () => {
const marketScan = ref<MarketScan>();
const types = computed(() => marketScan.value?.types ?? []);
const setTypes = async (types: number[]) => {
}
const addType = async (type: number) => {
if (!types.value.includes(type)) {
await setTypes([...types.value, type]);
}
}
const removeType = async (type: number) => {
if (types.value.includes(type)) {
await setTypes(types.value.filter(t => t !== type));
}
}
return { types, setTypes, addType, removeType };
});
export const createResult = async (id: number, price: MarketTypePrice): Promise<ScanResult> => ({ history: await getHistory(jitaId, id), ...price });

View File

@@ -6,7 +6,7 @@ import { MarketType, MarketTypeLabel, TaxInput, useMarketTaxStore } from "@/mark
import { BookmarkSlashIcon, ShoppingCartIcon } from '@heroicons/vue/24/outline'; import { BookmarkSlashIcon, ShoppingCartIcon } from '@heroicons/vue/24/outline';
import { useStorage } from '@vueuse/core'; import { useStorage } from '@vueuse/core';
import { computed, ref } from 'vue'; import { computed, ref } from 'vue';
import { ScanResult, getHistoryQuartils } from '.'; import { TrackingResult, getHistoryQuartils } from '.';
type Result = { type Result = {
type: MarketType; type: MarketType;
@@ -22,7 +22,7 @@ type Result = {
} }
interface Props { interface Props {
items?: ScanResult[]; items?: TrackingResult[];
infoOnly?: boolean; infoOnly?: boolean;
ignoredColums?: string[]; ignoredColums?: string[];
} }
@@ -45,8 +45,8 @@ defineEmits<Emits>();
const marketTaxStore = useMarketTaxStore(); const marketTaxStore = useMarketTaxStore();
const days = useStorage('market-scan-days', 365); const days = useStorage('market-tracking-days', 365);
const threshold = useStorage('market-scan-threshold', 10); const threshold = useStorage('market-tracking-threshold', 10);
const filter = ref(""); const filter = ref("");
const onlyCheap = ref(false); const onlyCheap = ref(false);
const columnsToIgnore = computed(() => { const columnsToIgnore = computed(() => {

View File

@@ -0,0 +1,5 @@
export * from './HistoryQuartils';
export * from './tracking';
export { default as TrackingResultTable } from './TrackingResultTable.vue';

View File

@@ -0,0 +1,31 @@
import { MarketOrderHistory, MarketType, MarketTypePrice, getHistory, jitaId } from "@/market";
import { marbasAxiosInstance } from "@/service";
import { defineStore } from "pinia";
import { computed, ref } from "vue";
export type TrackingResult = {
type: MarketType;
history: MarketOrderHistory[];
buy: number,
sell: number,
orderCount: number,
}
export const useMarketTrackingStore = defineStore('marketTracking', () => {
const trackedTypes = ref<number[]>([]);
const types = computed(() => trackedTypes.value ?? []);
const addType = async (type: number) => {
if (!trackedTypes.value.includes(type)) {
await marbasAxiosInstance.post(`/api/types_tracked`, { type });
}
}
const removeType = async (type: number) => {
if (trackedTypes.value.includes(type)) {
await marbasAxiosInstance.delete(`/api/types_tracked/${type}`);
}
}
return { types, addType, removeType };
});
export const createResult = async (id: number, price: MarketTypePrice): Promise<TrackingResult> => ({ history: await getHistory(jitaId, id), ...price });

View File

@@ -9,8 +9,8 @@ import { RouterLink, RouterView } from 'vue-router';
<RouterLink :to="{name: 'market-types'}" class="tab"> <RouterLink :to="{name: 'market-types'}" class="tab">
<span>Item Info</span> <span>Item Info</span>
</RouterLink> </RouterLink>
<RouterLink to="/market/scan" class="tab"> <RouterLink to="/market/tracking" class="tab">
<span>Scan</span> <span>Tracking</span>
</RouterLink> </RouterLink>
<RouterLink to="/market/acquisitions" class="tab"> <RouterLink to="/market/acquisitions" class="tab">
<span>Acquisitions</span> <span>Acquisitions</span>

View File

@@ -11,7 +11,7 @@ const apraisalStore = useApraisalStore();
const acquiredItemStore = useAcquiredItemStore(); const acquiredItemStore = useAcquiredItemStore();
const items = ref<AcquiredItem[]>([]); const items = ref<AcquiredItem[]>([]);
watch(() => acquiredItemStore.items, async itms => { watch(() => acquiredItemStore.types, async itms => {
if (itms.length === 0) { if (itms.length === 0) {
return; return;
} }

View File

@@ -1,7 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { MarketType, MarketTypeInput, MarketTypePrice, getHistory, getMarketTypes, jitaId, useApraisalStore } from "@/market"; import { MarketType, MarketTypeInput, MarketTypePrice, getHistory, getMarketTypes, jitaId, useApraisalStore } from "@/market";
import { BuyModal } from '@/market/acquisition'; import { BuyModal } from '@/market/acquisition';
import { ScanResult, ScanResultTable, createResult, useMarketScanStore } from '@/market/scan'; import { TrackingResult, TrackingResultTable, createResult, useMarketTrackingStore } from '@/market/tracking';
import { ref, watch } from 'vue'; import { ref, watch } from 'vue';
@@ -10,8 +10,8 @@ const buyModal = ref<typeof BuyModal>();
const item = ref<MarketType>(); const item = ref<MarketType>();
const apraisalStore = useApraisalStore(); const apraisalStore = useApraisalStore();
const markeyScanStore = useMarketScanStore(); const marketTrackingStore = useMarketTrackingStore();
const items = ref<ScanResult[]>([]); const items = ref<TrackingResult[]>([]);
const addOrRelaod = async (type: MarketType) => { const addOrRelaod = async (type: MarketType) => {
const typeID = type.id; const typeID = type.id;
const [history, price] = await Promise.all([ const [history, price] = await Promise.all([
@@ -30,6 +30,7 @@ const addOrRelaod = async (type: MarketType) => {
items.value = items.value.map(i => i.type.id === typeID ? itm : i); items.value = items.value.map(i => i.type.id === typeID ? itm : i);
} else { } else {
items.value = [ ...items.value, itm]; items.value = [ ...items.value, itm];
marketTrackingStore.addType(typeID);
} }
} }
const addItem = async () => { const addItem = async () => {
@@ -43,11 +44,10 @@ const addItem = async () => {
} }
const removeItem = (type: MarketType) => { const removeItem = (type: MarketType) => {
items.value = items.value.filter(i => i.type.id !== type.id); items.value = items.value.filter(i => i.type.id !== type.id);
marketTrackingStore.removeType(type.id);
} }
watch(() => marketTrackingStore.types, async t => {
watch(items, async itms => markeyScanStore.setTypes(itms.map(i => i.type.id)));
watch(() => markeyScanStore.types, async t => {
const typesToLoad = t.filter(t => !items.value.some(i => i.type.id === t)); const typesToLoad = t.filter(t => !items.value.some(i => i.type.id === t));
if (typesToLoad.length === 0) { if (typesToLoad.length === 0) {
@@ -73,7 +73,7 @@ watch(() => markeyScanStore.types, async t => {
</div> </div>
<template v-if="items.length > 0"> <template v-if="items.length > 0">
<hr /> <hr />
<ScanResultTable :items="items" @buy="(type, buy, sell) => buyModal?.open(type, { 'Buy': buy, 'Sell': sell })" @remove="removeItem" /> <TrackingResultTable :items="items" @buy="(type, buy, sell) => buyModal?.open(type, { 'Buy': buy, 'Sell': sell })" @remove="removeItem" />
<BuyModal ref="buyModal" /> <BuyModal ref="buyModal" />
</template> </template>
</template> </template>@/market/tracking

View File

@@ -2,7 +2,7 @@
import { ClipboardButton } from '@/components'; import { ClipboardButton } from '@/components';
import { MarketType, MarketTypeInput, getMarketType, useApraisalStore } from "@/market"; import { MarketType, MarketTypeInput, getMarketType, useApraisalStore } from "@/market";
import { BuyModal } from '@/market/acquisition'; import { BuyModal } from '@/market/acquisition';
import { ScanResultTable, createResult, useMarketScanStore } from '@/market/scan'; import { TrackingResultTable, createResult, useMarketTrackingStore } from '@/market/tracking';
import { BookmarkIcon, BookmarkSlashIcon, ShoppingCartIcon } from '@heroicons/vue/24/outline'; import { BookmarkIcon, BookmarkSlashIcon, ShoppingCartIcon } from '@heroicons/vue/24/outline';
import { computedAsync } from '@vueuse/core/index.cjs'; import { computedAsync } from '@vueuse/core/index.cjs';
import log from "loglevel"; import log from "loglevel";
@@ -18,18 +18,18 @@ const inputItem = ref<MarketType>();
const apraisalStore = useApraisalStore(); const apraisalStore = useApraisalStore();
const price = computedAsync(() => item.value ? apraisalStore.getPrice(item.value) : undefined); const price = computedAsync(() => item.value ? apraisalStore.getPrice(item.value) : undefined);
const markeyScanStore = useMarketScanStore(); const marketTrackingStore = useMarketTrackingStore();
const result = computedAsync(async () => item.value && price.value ? await createResult(item.value?.id, price.value) : undefined); const result = computedAsync(async () => item.value && price.value ? await createResult(item.value?.id, price.value) : undefined);
const isTracked = computed(() => item.value ? markeyScanStore.types.includes(item.value.id) : false); const isTracked = computed(() => item.value ? marketTrackingStore.types.includes(item.value.id) : false);
const toogleTracking = () => { const toogleTracking = () => {
if (!item.value) { if (!item.value) {
return; return;
} }
if (isTracked.value) { if (isTracked.value) {
markeyScanStore.removeType(item.value.id); marketTrackingStore.removeType(item.value.id);
} else { } else {
markeyScanStore.addType(item.value.id); marketTrackingStore.addType(item.value.id);
} }
} }
@@ -88,7 +88,7 @@ watch(useRoute(), async route => {
<p v-if="item.description" class="text-sm">{{ item.description }}</p> <p v-if="item.description" class="text-sm">{{ item.description }}</p>
</div> </div>
</div> </div>
<ScanResultTable v-if="result" :items="[result]" infoOnly /> <TrackingResultTable v-if="result" :items="[result]" infoOnly />
</template> </template>
<BuyModal ref="buyModal" /> <BuyModal ref="buyModal" />
</template> </template>
@@ -98,4 +98,4 @@ img.type-image {
width: 64px; width: 64px;
height: 64px; height: 64px;
} }
</style> </style>@/market/tracking

View File

@@ -7,7 +7,7 @@ export const routes: RouteRecordRaw[] = [
{ path: '/market', component: () => import('@/pages/Market.vue'), children: [ { path: '/market', component: () => import('@/pages/Market.vue'), children: [
{ path: '', redirect: '/market/types' }, { path: '', redirect: '/market/types' },
{ path: 'types/:type?', name: 'market-types', component: () => import('@/pages/market/TypeInfo.vue') }, { path: 'types/:type?', name: 'market-types', component: () => import('@/pages/market/TypeInfo.vue') },
{ path: 'scan', component: () => import('@/pages/market/Scan.vue') }, { path: 'tracking', component: () => import('@/pages/market/Tracking.vue') },
{ path: 'acquisitions', component: () => import('@/pages/market/Acquisitions.vue') }, { path: 'acquisitions', component: () => import('@/pages/market/Acquisitions.vue') },
] }, ] },
{ path: '/tools', component: () => import('@/pages/Tools.vue') }, { path: '/tools', component: () => import('@/pages/Tools.vue') },