type tracking
This commit is contained in:
@@ -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
|
||||||
@@ -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 };
|
||||||
});
|
});
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
export * from './HistoryQuartils';
|
|
||||||
export * from './scan';
|
|
||||||
|
|
||||||
export { default as ScanResultTable } from './ScanResultTable.vue';
|
|
||||||
|
|
||||||
@@ -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 });
|
|
||||||
@@ -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(() => {
|
||||||
5
src/market/tracking/index.ts
Normal file
5
src/market/tracking/index.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
export * from './HistoryQuartils';
|
||||||
|
export * from './tracking';
|
||||||
|
|
||||||
|
export { default as TrackingResultTable } from './TrackingResultTable.vue';
|
||||||
|
|
||||||
31
src/market/tracking/tracking.ts
Normal file
31
src/market/tracking/tracking.ts
Normal 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 });
|
||||||
@@ -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>
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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') },
|
||||||
|
|||||||
Reference in New Issue
Block a user