diff --git a/package-lock.json b/package-lock.json index 541ae94..d6c83ca 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,6 +16,7 @@ "vue-router": "^4.2.4" }, "devDependencies": { + "@tailwindcss/nesting": "^0.0.0-insiders.565cd3e", "@types/node": "^20.4.5", "@vitejs/plugin-vue": "^4.2.3", "autoprefixer": "^10.4.14", @@ -491,6 +492,37 @@ "node": ">= 8" } }, + "node_modules/@tailwindcss/nesting": { + "version": "0.0.0-insiders.565cd3e", + "resolved": "https://registry.npmjs.org/@tailwindcss/nesting/-/nesting-0.0.0-insiders.565cd3e.tgz", + "integrity": "sha512-WhHoFBx19TnH/c+xLwT/sxei6+4RpdfiyG3MYXfmLaMsADmVqBkF7B6lDalgZD9YdM459MF7DtxVbWkOrV7IaQ==", + "dev": true, + "dependencies": { + "postcss-nested": "^5.0.5" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/@tailwindcss/nesting/node_modules/postcss-nested": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-5.0.6.tgz", + "integrity": "sha512-rKqm2Fk0KbA8Vt3AdGN0FB9OBOMDVajMG6ZCf/GoHgdxUJ4sBFp0A/uMIRm+MJUdo33YXEtjqIz8u7DAp8B7DA==", + "dev": true, + "dependencies": { + "postcss-selector-parser": "^6.0.6" + }, + "engines": { + "node": ">=12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.2.14" + } + }, "node_modules/@types/node": { "version": "20.6.1", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.6.1.tgz", diff --git a/package.json b/package.json index 5c3dcb7..b84e75d 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "preview": "vite preview" }, "dependencies": { + "@tailwindcss/nesting": "^0.0.0-insiders.565cd3e", "@heroicons/vue": "^2.0.18", "@vueuse/core": "^10.2.1", "@vueuse/integrations": "^10.2.1", diff --git a/postcss.config.js b/postcss.config.js index 2e7af2b..0fa420c 100644 --- a/postcss.config.js +++ b/postcss.config.js @@ -1,5 +1,7 @@ export default { plugins: { + 'postcss-import': {}, + 'tailwindcss/nesting': {}, tailwindcss: {}, autoprefixer: {}, }, diff --git a/src/market/Market.vue b/src/market/Market.vue index 49131d8..9f0c2d8 100644 --- a/src/market/Market.vue +++ b/src/market/Market.vue @@ -1,57 +1,45 @@ @@ -64,8 +52,8 @@ onMounted(async () => { - \ No newline at end of file diff --git a/src/market/MarketResultTable.vue b/src/market/MarketResultTable.vue index 3c43738..2e3b112 100644 --- a/src/market/MarketResultTable.vue +++ b/src/market/MarketResultTable.vue @@ -3,63 +3,79 @@ 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"; +import { useStorage } from '@vueuse/core'; +import { computed, ref } from 'vue'; +import { MarketResult, getHistoryQuartils } from "."; +import { MarketType, MarketTypeLabel } from "./type"; interface Props { - result?: MarketResult[]; + items?: MarketResult[]; } interface Emits { - (e: 'relaod', typeID: number): void; + (e: 'relaod', type: MarketType): void; } const props = withDefaults(defineProps(), { - result: () => [] + items: () => [] }); defineEmits(); -const { sortedArray, headerProps } = useSort(computed(() => props.result.map(r => ({ - typeID: r.type.id, - name: r.type.name, - q1: r.q1, - mmedian: r.median, - q3: r.q3, - percent: r.q3 / r.q1 -}))), { - defaultSortKey: 'name', - defaultSortDirection: 'asc' -}) +const days = useStorage('market-days', 365); +const filter = ref(""); +const { sortedArray, headerProps } = useSort(computed(() => props.items + .filter(r => r.type.name.toLowerCase().includes(filter.value.toLowerCase())) + .map(r => { + const quartils = getHistoryQuartils(r.history, days.value); + + return { + type: r.type, + typeID: r.type.id, + name: r.type.name, + q1: quartils.q1, + mmedian: quartils.median, + q3: quartils.q3, + percent: quartils.q3 / quartils.q1 + }; + })), { + defaultSortKey: 'name', + defaultSortDirection: 'asc' + }) \ No newline at end of file diff --git a/src/market/market.ts b/src/market/market.ts index 0f6a553..8f15c1b 100644 --- a/src/market/market.ts +++ b/src/market/market.ts @@ -13,10 +13,8 @@ export type MarketOrderHistory = { } export type MarketResult = { - type: MarketType, - q1: number, - median: number, - q3: number, + type: MarketType; + history: MarketOrderHistory[]; } export type HistoryQuartils = { @@ -26,14 +24,16 @@ export type HistoryQuartils = { q3: number, } -export const getHistory = async (regionId: number, tyeId: number): Promise => (await esiAxiosInstance.get(`/markets/${regionId}/history/`, { params: { type_id: tyeId } })).data; +export const getHistory = async (regionId: number, tyeId: number): Promise => (await esiAxiosInstance.get(`/markets/${regionId}/history/`, { params: { type_id: tyeId } })).data; + +export const getHistoryQuartils = (history: MarketOrderHistory[], days?: number): HistoryQuartils => { + const now = Date.now(); -export const getHistoryQuartils = (history: MarketOrderHistory[]): HistoryQuartils => { const volumes = history .flatMap(h => { const volume = h.volume; - if (volume === 0) { + if (volume === 0 || (days && new Date(h.date).getTime() < now - days * 24 * 60 * 60 * 1000)) { return []; } diff --git a/src/market/type/MarketType.ts b/src/market/type/MarketType.ts index 02c9c23..77640b9 100644 --- a/src/market/type/MarketType.ts +++ b/src/market/type/MarketType.ts @@ -13,5 +13,12 @@ export type MarketType = { portionSize: number; } -export const getMarketType = async (id: number): Promise => (await apiAxiosInstance.get(`/sde/types/${id}/`)).data; -export const searchMarketType = async (name: string): Promise => (await apiAxiosInstance.post("/sde/types/search", [["name", name]])).data[0]; +export const getMarketType = async (type: string | number): Promise => (await getMarketTypes(type))[0]; +export const getMarketTypes = async (types: (string | number)[]): Promise => { + if (types.length === 0) { + return []; + } else if (types.length === 1 && typeof types[0] === "number") { + return [(await apiAxiosInstance.get(`/sde/types/${types[0]}/`)).data]; + } + return (await apiAxiosInstance.post("/sde/types/search", types.map(t => [typeof t === "number" ? 'id' : "name", t]))).data; +}