cache history
This commit is contained in:
9
package-lock.json
generated
9
package-lock.json
generated
@@ -8,6 +8,7 @@
|
||||
"name": "eveal-frontend",
|
||||
"version": "0.0.0",
|
||||
"dependencies": {
|
||||
"@heroicons/vue": "^2.0.18",
|
||||
"@vueuse/core": "^10.2.1",
|
||||
"@vueuse/integrations": "^10.2.1",
|
||||
"axios": "^1.4.0",
|
||||
@@ -400,6 +401,14 @@
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@heroicons/vue": {
|
||||
"version": "2.0.18",
|
||||
"resolved": "https://registry.npmjs.org/@heroicons/vue/-/vue-2.0.18.tgz",
|
||||
"integrity": "sha512-BcTC9nq2TkwNSfQuqo96J7ehx4etezypc2YeTq7KsXWxrcrerhkgjLrxGRBnStN0wrXo0Gv4BInybqz5uBG6Cw==",
|
||||
"peerDependencies": {
|
||||
"vue": ">= 3"
|
||||
}
|
||||
},
|
||||
"node_modules/@jridgewell/gen-mapping": {
|
||||
"version": "0.3.3",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz",
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@heroicons/vue": "^2.0.18",
|
||||
"@vueuse/core": "^10.2.1",
|
||||
"@vueuse/integrations": "^10.2.1",
|
||||
"axios": "^1.4.0",
|
||||
|
||||
@@ -1,22 +1,45 @@
|
||||
<script setup lang="ts">
|
||||
import { computedAsync, useStorage } from '@vueuse/core';
|
||||
import { ref } from 'vue';
|
||||
import { getHistoryQuartils, jitaId, MarketResult } from ".";
|
||||
import { MarketOrderHistory, MarketResult, getHistory, getHistoryQuartils, jitaId } from ".";
|
||||
import MarketReultTable from "./MarketResultTable.vue";
|
||||
import { searchMarketType } from "./type";
|
||||
import { getMarketType, searchMarketType } from "./type";
|
||||
|
||||
type MarketItem = {
|
||||
typeID: number;
|
||||
history: MarketOrderHistory[];
|
||||
}
|
||||
|
||||
const item = ref("");
|
||||
const result = ref<MarketResult[]>([]);
|
||||
const addItem = async () => {
|
||||
const type = await searchMarketType(item.value);
|
||||
const quartils = await getHistoryQuartils(jitaId, type.id);
|
||||
const items = useStorage<MarketItem[]>('market-items', []);
|
||||
const result = computedAsync<MarketResult[]>(() => Promise.all(items.value.map(async (i) => {
|
||||
const [type, quartils] = await Promise.all([
|
||||
getMarketType(i.typeID),
|
||||
getHistoryQuartils(i.history)
|
||||
]);
|
||||
|
||||
result.value = [...result.value, {
|
||||
return {
|
||||
type,
|
||||
q1: quartils[0],
|
||||
median: quartils[1],
|
||||
q3: quartils[2],
|
||||
}];
|
||||
q1: quartils.q1,
|
||||
median: quartils.median,
|
||||
q3: quartils.q3
|
||||
};
|
||||
})), []);
|
||||
const addOrRelaod = async (typeID: number) => {
|
||||
const history = await getHistory(jitaId, typeID);
|
||||
const item = { typeID, history };
|
||||
|
||||
if (items.value.some(i => i.typeID === typeID)) {
|
||||
items.value = items.value.map(i => i.typeID === typeID ? item : i);
|
||||
} else {
|
||||
items.value = [ ...items.value, item];
|
||||
}
|
||||
}
|
||||
const addItem = async () => {
|
||||
const type = await searchMarketType(item.value.split('\t')[0]);
|
||||
|
||||
item.value = "";
|
||||
addOrRelaod(type.id);
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -24,12 +47,12 @@ const addItem = async () => {
|
||||
<div class="grid mb-2 mt-4">
|
||||
<div>
|
||||
<span>Item: </span>
|
||||
<input type="text" class="w-96" v-model="item" />
|
||||
<input type="text" class="w-96" v-model="item" @keyup.enter="addItem" />
|
||||
<button class="justify-self-end ms-2" @click="addItem">Add</button>
|
||||
</div>
|
||||
</div>
|
||||
<template v-if="result.length > 0">
|
||||
<hr />
|
||||
<MarketReultTable :result="result" />
|
||||
<MarketReultTable :result="result" @relaod="id => addOrRelaod(id)" />
|
||||
</template>
|
||||
</template>
|
||||
@@ -2,6 +2,7 @@
|
||||
import { formatIsk, percentFormater } from '@/formaters';
|
||||
import { SortableHeader, useSort } from '@/table';
|
||||
import { copyToClipboard } from '@/utils';
|
||||
import { ArrowPathIcon } from '@heroicons/vue/24/outline';
|
||||
import { computed } from 'vue';
|
||||
import { MarketResult } from ".";
|
||||
import { MarketTypeLabel } from "./type";
|
||||
@@ -10,9 +11,15 @@ interface Props {
|
||||
result?: MarketResult[];
|
||||
}
|
||||
|
||||
interface Emits {
|
||||
(e: 'relaod', typeID: number): void;
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
result: () => []
|
||||
});
|
||||
defineEmits<Emits>();
|
||||
|
||||
const { sortedArray, headerProps } = useSort(computed(() => props.result.map(r => ({
|
||||
typeID: r.type.id,
|
||||
name: r.type.name,
|
||||
@@ -24,7 +31,6 @@ const { sortedArray, headerProps } = useSort(computed(() => props.result.map(r =
|
||||
defaultSortKey: 'name',
|
||||
defaultSortDirection: 'asc'
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -37,6 +43,7 @@ const { sortedArray, headerProps } = useSort(computed(() => props.result.map(r =
|
||||
<SortableHeader v-bind="headerProps" sortKey="median">Median</SortableHeader>
|
||||
<SortableHeader v-bind="headerProps" sortKey="q3">Q3</SortableHeader>
|
||||
<SortableHeader v-bind="headerProps" sortKey="percent">Percent</SortableHeader>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@@ -48,6 +55,9 @@ const { sortedArray, headerProps } = useSort(computed(() => props.result.map(r =
|
||||
<td class="text-right">{{ formatIsk(r.mmedian) }}</td>
|
||||
<td class="text-right">{{ formatIsk(r.q3) }}</td>
|
||||
<td class="text-right">{{ percentFormater.format(r.percent) }}</td>
|
||||
<td class="text-right">
|
||||
<button class="p-0 border-none bg-transparent" @click="$emit('relaod', r.typeID)"><ArrowPathIcon class="h-6 w-6" /></button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@@ -19,10 +19,16 @@ export type MarketResult = {
|
||||
q3: number,
|
||||
}
|
||||
|
||||
export type HistoryQuartils = {
|
||||
totalVolume: number,
|
||||
q1: number,
|
||||
median: number,
|
||||
q3: number,
|
||||
}
|
||||
|
||||
export const getHistory = async (regionId: number, tyeId: number): Promise<MarketOrderHistory[]> => (await esiAxiosInstance.get(`/markets/${regionId}/history/`, { params: { type_id: tyeId } })).data;
|
||||
|
||||
export const getHistoryQuartils = async (regionId: number, tyeId: number): Promise<[number, number, number]> => {
|
||||
const history = await getHistory(regionId, tyeId);
|
||||
export const getHistoryQuartils = async (history: MarketOrderHistory[]): Promise<HistoryQuartils> => {
|
||||
const volumes = history
|
||||
.flatMap(h => {
|
||||
const volume = h.volume;
|
||||
@@ -56,7 +62,12 @@ export const getHistoryQuartils = async (regionId: number, tyeId: number): Promi
|
||||
quartil++;
|
||||
}
|
||||
}
|
||||
return quartils;
|
||||
return {
|
||||
totalVolume,
|
||||
q1: quartils[0],
|
||||
median: quartils[1],
|
||||
q3: quartils[2],
|
||||
};
|
||||
}
|
||||
|
||||
const estimateVolume = (history: MarketOrderHistory): number => {
|
||||
|
||||
@@ -13,4 +13,5 @@ export type MarketType = {
|
||||
portionSize: number;
|
||||
}
|
||||
|
||||
export const getMarketType = async (id: number): Promise<MarketType> => (await apiAxiosInstance.get<MarketType>(`/sde/types/${id}`)).data;
|
||||
export const searchMarketType = async (name: string): Promise<MarketType> => (await apiAxiosInstance.post<MarketType[]>("/sde/types/search", [["name", name]])).data[0];
|
||||
|
||||
@@ -17,8 +17,9 @@ const emit = defineEmits<Emit>();
|
||||
|
||||
<template>
|
||||
<th>
|
||||
<span class="asc" :class="{'opacity-20': (currentSortKey != sortKey || sortDirection != 'asc')}" @click="emit('sort', sortKey, 'asc')">▲</span>
|
||||
<slot />
|
||||
<span class="asc" :class="{'opacity-20': (currentSortKey != sortKey || sortDirection != 'asc')}" @click="emit('sort', sortKey, 'asc')">▲</span>
|
||||
|
||||
<span class="desc" :class="{'opacity-20': (currentSortKey != sortKey || sortDirection != 'desc')}" @click="emit('sort', sortKey, 'desc')">▼</span>
|
||||
</th>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user