diff --git a/src/App.vue b/src/App.vue index b71478b..6fdb05c 100644 --- a/src/App.vue +++ b/src/App.vue @@ -87,6 +87,8 @@ export default defineComponent({ this.setupOfflineHandling(); this.apiStore.setupAPIData(); + + if (!this.isOnProductionHost) document.title = 'Stacjownik Dev'; }, setupOfflineHandling() { @@ -108,7 +110,7 @@ export default defineComponent({ handleOnlineMode() { this.store.isOffline = false; - this.apiStore.setupAPIData(); + this.apiStore.connectToAPI(); }, changeLang(lang: string) { diff --git a/src/components/JournalView/JournalDailyStats.vue b/src/components/JournalView/JournalDailyStats.vue index 6cc8b1e..2e13fdb 100644 --- a/src/components/JournalView/JournalDailyStats.vue +++ b/src/components/JournalView/JournalDailyStats.vue @@ -172,7 +172,7 @@ import dateMixin from '../../mixins/dateMixin'; import { API } from '../../typings/api'; import { Status } from '../../typings/common'; -import http from '../../http'; +import { useApiStore } from '../../store/apiStore'; export default defineComponent({ name: 'journal-daily-stats', @@ -186,7 +186,8 @@ export default defineComponent({ statsStatus: Status.Data.Loading, intervalId: -1, - stats: {} as API.DailyStats.Response + stats: {} as API.DailyStats.Response, + apiStore: useApiStore() }; }, @@ -211,7 +212,9 @@ export default defineComponent({ methods: { async fetchDailyTimetableStats() { try { - const res: API.DailyStats.Response = await (await http.get('api/getDailyStats')).data; + const res: API.DailyStats.Response = await ( + await this.apiStore.client!.get('api/getDailyStats') + ).data; this.stats = res; diff --git a/src/components/JournalView/JournalOptions.vue b/src/components/JournalView/JournalOptions.vue index cd92e03..8b7d023 100644 --- a/src/components/JournalView/JournalOptions.vue +++ b/src/components/JournalView/JournalOptions.vue @@ -116,7 +116,7 @@ import keyMixin from '../../mixins/keyMixin'; import { useMainStore } from '../../store/mainStore'; import { Journal } from './typings'; import { Status } from '../../typings/common'; -import http from '../../http'; +import { useApiStore } from '../../store/apiStore'; export default defineComponent({ emits: ['onSearchConfirm', 'onOptionsReset', 'onRefreshData'], @@ -158,6 +158,7 @@ export default defineComponent({ searchTimeout: 0, store: useMainStore(), + apiStore: useApiStore(), JournalFilterSection: Journal.FilterSection }; @@ -241,7 +242,7 @@ export default defineComponent({ this.searchTimeout = window.setTimeout(async () => { try { const suggestions: string[] = await ( - await http.get(`api/get${type}Suggestions?name=${value}`) + await this.apiStore.client!.get(`api/get${type}Suggestions?name=${value}`) ).data; this[`${type}Suggestions`] = suggestions; diff --git a/src/components/SceneryView/SceneryDispatchersHistory.vue b/src/components/SceneryView/SceneryDispatchersHistory.vue index d9d4a04..34a2ea6 100644 --- a/src/components/SceneryView/SceneryDispatchersHistory.vue +++ b/src/components/SceneryView/SceneryDispatchersHistory.vue @@ -79,7 +79,7 @@ import listObserverMixin from '../../mixins/listObserverMixin'; import { ActiveScenery } from '../../store/typings'; import { API } from '../../typings/api'; import { Status } from '../../typings/common'; -import http from '../../http'; +import { useApiStore } from '../../store/apiStore'; export default defineComponent({ name: 'SceneryDispatchersHistory', @@ -98,7 +98,8 @@ export default defineComponent({ return { historyList: [] as API.DispatcherHistory.Response, dataStatus: Status.Data.Loading, - DataStatus: Status.Data + DataStatus: Status.Data, + apiStore: useApiStore() }; }, @@ -127,7 +128,7 @@ export default defineComponent({ }&countFrom=${countFrom}&countLimit=${countLimit}`; const historyAPIData: API.DispatcherHistory.Response = await ( - await http.get(requestString) + await this.apiStore.client!.get(requestString) ).data; this.dataStatus = Status.Data.Loaded; diff --git a/src/components/SceneryView/SceneryTimetablesHistory.vue b/src/components/SceneryView/SceneryTimetablesHistory.vue index d3ddf7e..4fefc36 100644 --- a/src/components/SceneryView/SceneryTimetablesHistory.vue +++ b/src/components/SceneryView/SceneryTimetablesHistory.vue @@ -77,7 +77,7 @@ import listObserverMixin from '../../mixins/listObserverMixin'; import { ActiveScenery } from '../../store/typings'; import { API } from '../../typings/api'; import { Status } from '../../typings/common'; -import http from '../../http'; +import { useApiStore } from '../../store/apiStore'; export default defineComponent({ name: 'SceneryTimetablesHistory', @@ -94,6 +94,7 @@ export default defineComponent({ data() { return { historyList: [] as API.TimetableHistory.Response, + apiStore: useApiStore(), dataStatus: Status.Data.Loading, DataStatus: Status.Data }; @@ -112,7 +113,7 @@ export default defineComponent({ try { const response: API.TimetableHistory.Response = await ( - await http.get('api/getTimetables', { + await this.apiStore.client!.get('api/getTimetables', { params: { issuedFrom: this.station?.name || this.onlineScenery?.name } diff --git a/src/components/StationsView/StationTable.vue b/src/components/StationsView/StationTable.vue index d78a356..694b3a3 100644 --- a/src/components/StationsView/StationTable.vue +++ b/src/components/StationsView/StationTable.vue @@ -27,6 +27,7 @@ :key="headerName" @click="changeSorter(headerName)" class="header-image" + :class="headerName" > - + {{ station.generalInfo.project }} {{ station.name }} - + + - + - + + - - - SBL - - + - - {{ station.onlineInfo?.currentUsers || 0 }} + + {{ station.onlineInfo?.currentUsers || 0 }} / - {{ station.onlineInfo?.maxUsers || 0 }} + {{ station.onlineInfo?.maxUsers || 0 }} @@ -252,7 +242,7 @@ @@ -260,7 +250,7 @@ @@ -268,7 +258,7 @@ @@ -399,10 +389,18 @@ $rowCol: #424242; font-weight: 500; } +.no-stations { + text-align: center; + font-size: 1.5em; + + padding: 1em; + margin: 1em 0; + + background: #333; +} + table { - white-space: nowrap; border-collapse: collapse; - // min-width: 1350px; width: 100%; @include smallScreen() { @@ -418,11 +416,15 @@ table { top: 0; &.header-text { - min-width: 140px; + min-width: 10em; } &.header-image { - min-width: 60px; + min-width: 65px; + + &.user { + min-width: 80px; + } } padding: 0.5em 0.25em; @@ -447,7 +449,7 @@ table { } } -tr.station { +tr { background-color: $rowCol; &:nth-child(even) { @@ -466,6 +468,10 @@ tr.station { cursor: pointer; + &.inactive { + opacity: 0.2; + } + @include smallScreen() { margin: 0; padding: 0.3em 0.5em; @@ -474,118 +480,105 @@ tr.station { } } -td.station { - &_name { - font-weight: bold; +.station-name { + font-weight: bold; + max-width: 200px; - &.default { - color: $accentCol; - } - - &.nonPublic { - color: #bebebe; - } - - &.unavailable { - font-weight: 500; - color: #bebebe; - } + &.default { + color: $accentCol; } - &_level, - &_dispatcher-exp { - span { - display: block; - - width: 2em; - height: 2em; - line-height: 2em; - margin: 0 auto; - } - - img { - width: 2em; - border-radius: 50%; - } + &.nonPublic { + color: #bebebe; } - // &_dispatcher-name { - // position: relative; - // } + &.unavailable { + font-weight: 500; + color: #bebebe; + } +} - &_dispatcher-name img { +.station-level, +.station-dispatcher-exp { + span { + display: block; + + width: 2em; + height: 2em; + line-height: 2em; + margin: 0 auto; + } + + img { + width: 2em; + border-radius: 50%; + } +} + +.station-dispatcher-name { + img { max-width: 1.35em; vertical-align: text-bottom; } - - &_level { - span { - background-color: #888; - border-radius: 50%; - } - } - - &_info { - display: flex; - align-items: center; - justify-content: center; - - /* Images */ - .icon-info { - display: flex; - justify-content: center; - align-items: center; - - width: 32px; - height: 32px; - font-size: 12px; - - margin: 0 0.2em; - - outline: 2px solid #444; - border-radius: 0.5em; - - @include smallScreen() { - width: 24px; - height: 24px; - font-size: 10px; - } - } - } - - &_tracks { - .no-catenary { - background-color: #939393; - } - - .catenary { - background-color: #009dce; - } - - .track { - margin: 0 0.35em; - padding: 0.35em; - font-size: 1.05em; - white-space: pre-wrap; - } - } - - &_users, - &_spawns, - &_schedules { - &.inactive { - opacity: 0.2; - } - } } -.station_users { +.station-level { span { - color: gold; + background-color: #888; + border-radius: 50%; } } -.station_schedules { +.station-info { + display: flex; + align-items: center; + justify-content: center; + + /* Images */ + .icon-info { + // display: flex; + // justify-content: center; + // align-items: center; + + width: 32px; + height: 32px; + font-size: 12px; + + margin: 0 0.2em; + + outline: 2px solid #444; + border-radius: 0.5em; + + @include smallScreen() { + width: 24px; + height: 24px; + font-size: 10px; + } + } +} + +.station-tracks { + .no-catenary { + background-color: #939393; + } + + .catenary { + background-color: #009dce; + } + + .separator { + border-left: 3px solid #b3b3b3; + } + + .track { + margin: 0 0.35em; + padding: 0.35em; + font-size: 1.05em; + white-space: pre-wrap; + } +} + +.station-schedules { &.all { color: gold; } @@ -598,18 +591,4 @@ td.station { color: lime; } } - -.separator { - border-left: 3px solid #b3b3b3; -} - -.no-stations { - text-align: center; - font-size: 1.5em; - - padding: 1em; - margin: 1em 0; - - background: #333; -} diff --git a/src/http.ts b/src/http.ts deleted file mode 100644 index 2a8d224..0000000 --- a/src/http.ts +++ /dev/null @@ -1,10 +0,0 @@ -import axios from 'axios'; - -const http = axios.create({ - baseURL: - import.meta.env.VITE_API_MODE === 'development' - ? 'http://localhost:3001' - : 'https://stacjownik.spythere.eu' -}); - -export default http; diff --git a/src/store/apiStore.ts b/src/store/apiStore.ts index 2279f33..49de11a 100644 --- a/src/store/apiStore.ts +++ b/src/store/apiStore.ts @@ -1,12 +1,18 @@ import { defineStore } from 'pinia'; -import http from '../http'; import { API } from '../typings/api'; import { Status } from '../typings/common'; import { StationJSONData } from './typings'; +import axios, { AxiosInstance } from 'axios'; // Update seconds cron for active data scheduler const UPDATE_SECONDS = [3, 23, 43]; +export enum APIMode { + PRODUCTION = 0, + DEV = 1, + MOCK = 2 +} + export const useApiStore = defineStore('apiStore', { state: () => ({ dataStatuses: { @@ -18,11 +24,34 @@ export const useApiStore = defineStore('apiStore', { donatorsData: [] as API.Donators.Response, sceneryData: [] as StationJSONData[], + client: undefined as AxiosInstance | undefined, + activeDataScheduler: undefined as number | undefined }), actions: { async setupAPIData() { + let baseURL = 'https://stacjownik.spythere.eu'; + + switch (import.meta.env.VITE_API_MODE) { + case 'development': + baseURL = 'http://localhost:3001'; + break; + case 'mocking': + baseURL = 'http://localhost:3123'; + break; + default: + break; + } + + this.client = axios.create({ + baseURL + }); + + this.connectToAPI(); + }, + + async connectToAPI() { // Static data this.fetchDonatorsData(); this.fetchStationsGeneralInfo(); @@ -46,7 +75,7 @@ export const useApiStore = defineStore('apiStore', { async fetchActiveData() { try { - const response = await http.get('api/getActiveData'); + const response = await this.client!.get('api/getActiveData'); this.activeData = response.data; this.dataStatuses.connection = Status.Data.Loaded; @@ -60,7 +89,7 @@ export const useApiStore = defineStore('apiStore', { async fetchDonatorsData() { try { - const response = await http.get('api/getDonators'); + const response = await this.client!.get('api/getDonators'); this.donatorsData = response.data; } catch (error) { @@ -69,8 +98,9 @@ export const useApiStore = defineStore('apiStore', { }, async fetchStationsGeneralInfo() { - const sceneryData: StationJSONData[] = (await http.get('api/getSceneries')) - .data; + const sceneryData: StationJSONData[] = ( + await this.client!.get('api/getSceneries') + ).data; if (!sceneryData) { this.dataStatuses.sceneries = Status.Data.Error; diff --git a/src/views/JournalDispatchers.vue b/src/views/JournalDispatchers.vue index 297c5e2..b47fdfb 100644 --- a/src/views/JournalDispatchers.vue +++ b/src/views/JournalDispatchers.vue @@ -37,7 +37,6 @@