mirror of
https://github.com/Spythere/stacjownik.git
synced 2026-05-03 05:18:11 +00:00
restrukturyzacja storów
This commit is contained in:
+1
-1
@@ -31,7 +31,7 @@
|
|||||||
// CONTAINER
|
// CONTAINER
|
||||||
.app_container {
|
.app_container {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-rows: auto minmax(100vh, 1fr) auto;
|
grid-template-rows: auto 1fr auto;
|
||||||
grid-template-columns: 100%;
|
grid-template-columns: 100%;
|
||||||
|
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
|
|||||||
+7
-7
@@ -39,12 +39,13 @@ import Clock from './components/App/Clock.vue';
|
|||||||
import packageInfo from '.././package.json';
|
import packageInfo from '.././package.json';
|
||||||
import { regions } from './data/options.json';
|
import { regions } from './data/options.json';
|
||||||
|
|
||||||
import { useStore } from './store/mainStore';
|
import { useMainStore } from './store/mainStore';
|
||||||
import StatusIndicator from './components/App/StatusIndicator.vue';
|
import StatusIndicator from './components/App/StatusIndicator.vue';
|
||||||
import TrainModal from './components/Global/TrainModal.vue';
|
import TrainModal from './components/Global/TrainModal.vue';
|
||||||
import AppHeader from './components/App/AppHeader.vue';
|
import AppHeader from './components/App/AppHeader.vue';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import StorageManager from './managers/storageManager';
|
import StorageManager from './managers/storageManager';
|
||||||
|
import { useApiStore } from './store/apiStore';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
@@ -56,7 +57,8 @@ export default defineComponent({
|
|||||||
|
|
||||||
data: () => ({
|
data: () => ({
|
||||||
VERSION: packageInfo.version,
|
VERSION: packageInfo.version,
|
||||||
store: useStore(),
|
store: useMainStore(),
|
||||||
|
apiStore: useApiStore(),
|
||||||
|
|
||||||
currentLang: 'pl',
|
currentLang: 'pl',
|
||||||
releaseURL: '',
|
releaseURL: '',
|
||||||
@@ -65,17 +67,15 @@ export default defineComponent({
|
|||||||
|
|
||||||
created() {
|
created() {
|
||||||
this.loadLang();
|
this.loadLang();
|
||||||
this.store.setupAPI();
|
this.apiStore.setupAPI();
|
||||||
|
|
||||||
this.store.isOffline = !window.navigator.onLine;
|
this.store.isOffline = !window.navigator.onLine;
|
||||||
|
|
||||||
window.addEventListener('offline', () => {
|
window.addEventListener('offline', () => {
|
||||||
this.store.isOffline = true;
|
this.store.isOffline = true;
|
||||||
|
this.apiStore.activeData = undefined;
|
||||||
|
|
||||||
this.store.activeData.activeSceneries = [];
|
this.apiStore.setDataStatuses();
|
||||||
this.store.activeData.trains = [];
|
|
||||||
|
|
||||||
this.store.setStatuses();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
window.addEventListener('online', () => {
|
window.addEventListener('online', () => {
|
||||||
|
|||||||
@@ -68,7 +68,7 @@
|
|||||||
</template>
|
</template>
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
import { useStore } from '../../store/mainStore';
|
import { useMainStore } from '../../store/mainStore';
|
||||||
import StatusIndicator from './StatusIndicator.vue';
|
import StatusIndicator from './StatusIndicator.vue';
|
||||||
import Clock from './Clock.vue';
|
import Clock from './Clock.vue';
|
||||||
import RegionDropdown from '../Global/RegionDropdown.vue';
|
import RegionDropdown from '../Global/RegionDropdown.vue';
|
||||||
@@ -84,7 +84,7 @@ export default defineComponent({
|
|||||||
|
|
||||||
setup() {
|
setup() {
|
||||||
return {
|
return {
|
||||||
store: useStore()
|
store: useMainStore()
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -194,9 +194,9 @@
|
|||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
import { StoreState } from '../../store/typings';
|
import { useMainStore } from '../../store/mainStore';
|
||||||
import { useStore } from '../../store/mainStore';
|
|
||||||
import { Status } from '../../typings/common';
|
import { Status } from '../../typings/common';
|
||||||
|
import { useApiStore } from '../../store/apiStore';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
data() {
|
data() {
|
||||||
@@ -221,10 +221,11 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
|
|
||||||
setup() {
|
setup() {
|
||||||
const store = useStore();
|
const store = useMainStore();
|
||||||
|
const apiStore = useApiStore();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
dataStatus: store.dataStatuses,
|
dataStatus: apiStore.dataStatuses,
|
||||||
store
|
store
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@@ -233,7 +234,7 @@ export default defineComponent({
|
|||||||
dataStatus: {
|
dataStatus: {
|
||||||
deep: true,
|
deep: true,
|
||||||
|
|
||||||
handler(statuses: StoreState['dataStatuses']) {
|
handler(statuses: any) {
|
||||||
const connectionStatus = statuses.connection;
|
const connectionStatus = statuses.connection;
|
||||||
const sceneryDataStatus = statuses.sceneries;
|
const sceneryDataStatus = statuses.sceneries;
|
||||||
const trainsDataStatus = statuses.trains;
|
const trainsDataStatus = statuses.trains;
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
import { useStore } from '../../store/mainStore';
|
import { useMainStore } from '../../store/mainStore';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
emits: ['toggleModal'],
|
emits: ['toggleModal'],
|
||||||
@@ -23,7 +23,7 @@ export default defineComponent({
|
|||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
store: useStore()
|
store: useMainStore()
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent, Ref, ref } from 'vue';
|
import { defineComponent, Ref, ref } from 'vue';
|
||||||
import { regions as regionsJSON } from '../../data/options.json';
|
import { regions as regionsJSON } from '../../data/options.json';
|
||||||
import { useStore } from '../../store/mainStore';
|
import { useMainStore } from '../../store/mainStore';
|
||||||
|
|
||||||
interface Item {
|
interface Item {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -41,7 +41,7 @@ interface Item {
|
|||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
store: useStore(),
|
store: useMainStore(),
|
||||||
selectedItemIndex: 0,
|
selectedItemIndex: 0,
|
||||||
listOpen: false
|
listOpen: false
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -50,8 +50,8 @@
|
|||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { PropType, defineComponent } from 'vue';
|
import { PropType, defineComponent } from 'vue';
|
||||||
import { useStore } from '../../store/mainStore';
|
|
||||||
import { API } from '../../typings/api';
|
import { API } from '../../typings/api';
|
||||||
|
import { useApiStore } from '../../store/apiStore';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
props: {
|
props: {
|
||||||
@@ -63,15 +63,15 @@ export default defineComponent({
|
|||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
store: useStore()
|
apiStore: useApiStore()
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
onImageError(event: Event, stockName: string) {
|
onImageError(event: Event, stockName: string) {
|
||||||
const fallbackName =
|
const fallbackName =
|
||||||
Object.keys(this.store.rollingStockData!.info).find((type) => {
|
Object.keys(this.apiStore.rollingStockData!.info).find((type) => {
|
||||||
return this.store.rollingStockData!.info[type as keyof API.RollingStock.Info].find(
|
return this.apiStore.rollingStockData!.info[type as keyof API.RollingStock.Info].find(
|
||||||
(v) => v[0] === stockName.split(':')[0]
|
(v) => v[0] === stockName.split(':')[0]
|
||||||
);
|
);
|
||||||
}) || 'vehicle-unknown';
|
}) || 'vehicle-unknown';
|
||||||
|
|||||||
@@ -16,8 +16,8 @@
|
|||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
import { useStore } from '../../store/mainStore';
|
|
||||||
import { API } from '../../typings/api';
|
import { API } from '../../typings/api';
|
||||||
|
import { useApiStore } from '../../store/apiStore';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
props: {
|
props: {
|
||||||
@@ -34,7 +34,7 @@ export default defineComponent({
|
|||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
store: useStore(),
|
apiStore: useApiStore(),
|
||||||
isNotFound: false,
|
isNotFound: false,
|
||||||
isLoaded: false
|
isLoaded: false
|
||||||
};
|
};
|
||||||
@@ -50,11 +50,11 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
|
|
||||||
stockType() {
|
stockType() {
|
||||||
if (!this.store.rollingStockData) return 'vehicle-unknown';
|
if (!this.apiStore.rollingStockData) return 'vehicle-unknown';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
Object.keys(this.store.rollingStockData.info).find((type) => {
|
Object.keys(this.apiStore.rollingStockData.info).find((type) => {
|
||||||
return this.store.rollingStockData?.info[type as keyof API.RollingStock.Info].find(
|
return this.apiStore.rollingStockData?.info[type as keyof API.RollingStock.Info].find(
|
||||||
(v) => v[0] === this.name.split(':')[0]
|
(v) => v[0] === this.name.split(':')[0]
|
||||||
);
|
);
|
||||||
}) || 'vehicle-unknown'
|
}) || 'vehicle-unknown'
|
||||||
|
|||||||
@@ -53,7 +53,7 @@
|
|||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { defineComponent } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
import { URLs } from '../../scripts/utils/apiURLs';
|
import { URLs } from '../../scripts/utils/apiURLs';
|
||||||
import { useStore } from '../../store/mainStore';
|
import { useMainStore } from '../../store/mainStore';
|
||||||
import Loading from '../Global/Loading.vue';
|
import Loading from '../Global/Loading.vue';
|
||||||
import { API } from '../../typings/api';
|
import { API } from '../../typings/api';
|
||||||
|
|
||||||
@@ -61,7 +61,7 @@ export default defineComponent({
|
|||||||
components: { Loading },
|
components: { Loading },
|
||||||
|
|
||||||
setup() {
|
setup() {
|
||||||
const store = useStore();
|
const store = useMainStore();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
store
|
store
|
||||||
|
|||||||
@@ -193,7 +193,7 @@ export default defineComponent({
|
|||||||
|
|
||||||
if (this.intervalId != -1) return;
|
if (this.intervalId != -1) return;
|
||||||
|
|
||||||
this.intervalId = setInterval(this.fetchDailyTimetableStats, 60000);
|
this.intervalId = window.setInterval(this.fetchDailyTimetableStats, 60000);
|
||||||
},
|
},
|
||||||
|
|
||||||
stopFetchingDailyStats() {
|
stopFetchingDailyStats() {
|
||||||
|
|||||||
@@ -125,7 +125,7 @@
|
|||||||
import { defineComponent, PropType } from 'vue';
|
import { defineComponent, PropType } from 'vue';
|
||||||
import dateMixin from '../../mixins/dateMixin';
|
import dateMixin from '../../mixins/dateMixin';
|
||||||
import styleMixin from '../../mixins/styleMixin';
|
import styleMixin from '../../mixins/styleMixin';
|
||||||
import { useStore } from '../../store/mainStore';
|
import { useMainStore } from '../../store/mainStore';
|
||||||
import Loading from '../Global/Loading.vue';
|
import Loading from '../Global/Loading.vue';
|
||||||
import { regions } from '../../data/options.json';
|
import { regions } from '../../data/options.json';
|
||||||
import AddDataButton from '../Global/AddDataButton.vue';
|
import AddDataButton from '../Global/AddDataButton.vue';
|
||||||
@@ -160,7 +160,7 @@ export default defineComponent({
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
Status,
|
Status,
|
||||||
store: useStore(),
|
store: useMainStore(),
|
||||||
regions
|
regions
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -55,7 +55,7 @@
|
|||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
import { useStore } from '../../store/mainStore';
|
import { useMainStore } from '../../store/mainStore';
|
||||||
import { Status } from '../../typings/common';
|
import { Status } from '../../typings/common';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
@@ -63,7 +63,7 @@ export default defineComponent({
|
|||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
store: useStore(),
|
store: useMainStore(),
|
||||||
Status: Status
|
Status: Status
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ import axios from 'axios';
|
|||||||
import { defineComponent, inject, PropType } from 'vue';
|
import { defineComponent, inject, PropType } from 'vue';
|
||||||
import keyMixin from '../../mixins/keyMixin';
|
import keyMixin from '../../mixins/keyMixin';
|
||||||
import { URLs } from '../../scripts/utils/apiURLs';
|
import { URLs } from '../../scripts/utils/apiURLs';
|
||||||
import { useStore } from '../../store/mainStore';
|
import { useMainStore } from '../../store/mainStore';
|
||||||
import { Journal } from './typings';
|
import { Journal } from './typings';
|
||||||
import { API } from '../../typings/api';
|
import { API } from '../../typings/api';
|
||||||
import { Status } from '../../typings/common';
|
import { Status } from '../../typings/common';
|
||||||
@@ -158,7 +158,7 @@ export default defineComponent({
|
|||||||
dispatcherSuggestions: [] as string[],
|
dispatcherSuggestions: [] as string[],
|
||||||
|
|
||||||
searchTimeout: 0,
|
searchTimeout: 0,
|
||||||
store: useStore(),
|
store: useMainStore(),
|
||||||
|
|
||||||
JournalFilterSection: Journal.FilterSection
|
JournalFilterSection: Journal.FilterSection
|
||||||
};
|
};
|
||||||
@@ -238,7 +238,7 @@ export default defineComponent({
|
|||||||
|
|
||||||
window.clearTimeout(this.searchTimeout);
|
window.clearTimeout(this.searchTimeout);
|
||||||
|
|
||||||
this.searchTimeout = setTimeout(async () => {
|
this.searchTimeout = window.setTimeout(async () => {
|
||||||
try {
|
try {
|
||||||
const suggestions: string[] = await (
|
const suggestions: string[] = await (
|
||||||
await axios.get(`${URLs.stacjownikAPI}/api/get${type}Suggestions?name=${value}`)
|
await axios.get(`${URLs.stacjownikAPI}/api/get${type}Suggestions?name=${value}`)
|
||||||
|
|||||||
@@ -28,14 +28,14 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, onMounted, reactive, Ref, ref, watch } from 'vue';
|
import { computed, onMounted, reactive, Ref, ref, watch } from 'vue';
|
||||||
import { useStore } from '../../store/mainStore';
|
import { useMainStore } from '../../store/mainStore';
|
||||||
import JournalDailyStats from './JournalDailyStats.vue';
|
import JournalDailyStats from './JournalDailyStats.vue';
|
||||||
import JournalDriverStats from './JournalDriverStats.vue';
|
import JournalDriverStats from './JournalDriverStats.vue';
|
||||||
import StorageManager from '../../managers/storageManager';
|
import StorageManager from '../../managers/storageManager';
|
||||||
|
|
||||||
export type JournalStatsTab = 'journal-driver-stats' | 'journal-daily-stats';
|
export type JournalStatsTab = 'journal-driver-stats' | 'journal-daily-stats';
|
||||||
|
|
||||||
const store = useStore();
|
const store = useMainStore();
|
||||||
const currentStatsTab: Ref<JournalStatsTab | null> = ref(null);
|
const currentStatsTab: Ref<JournalStatsTab | null> = ref(null);
|
||||||
|
|
||||||
let data = reactive({
|
let data = reactive({
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ import { defineComponent, PropType } from 'vue';
|
|||||||
import Loading from '../../Global/Loading.vue';
|
import Loading from '../../Global/Loading.vue';
|
||||||
import AddDataButton from '../../Global/AddDataButton.vue';
|
import AddDataButton from '../../Global/AddDataButton.vue';
|
||||||
import TimetableHistoryList from './TimetableHistoryList.vue';
|
import TimetableHistoryList from './TimetableHistoryList.vue';
|
||||||
import { useStore } from '../../../store/mainStore';
|
import { useMainStore } from '../../../store/mainStore';
|
||||||
import { Status } from '../../../typings/common';
|
import { Status } from '../../../typings/common';
|
||||||
import { API } from '../../../typings/api';
|
import { API } from '../../../typings/api';
|
||||||
|
|
||||||
@@ -71,7 +71,7 @@ export default defineComponent({
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
Status,
|
Status,
|
||||||
store: useStore()
|
store: useMainStore()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -48,7 +48,7 @@
|
|||||||
<transition-group name="list-anim">
|
<transition-group name="list-anim">
|
||||||
<div
|
<div
|
||||||
style="padding-bottom: 5em"
|
style="padding-bottom: 5em"
|
||||||
v-if="store.dataStatuses.trains == 0 && computedScheduledTrains.length == 0"
|
v-if="apiStore.dataStatuses.trains == 0 && computedScheduledTrains.length == 0"
|
||||||
key="list-loading"
|
key="list-loading"
|
||||||
>
|
>
|
||||||
<Loading />
|
<Loading />
|
||||||
@@ -187,10 +187,11 @@ import Loading from '../Global/Loading.vue';
|
|||||||
import dateMixin from '../../mixins/dateMixin';
|
import dateMixin from '../../mixins/dateMixin';
|
||||||
import routerMixin from '../../mixins/routerMixin';
|
import routerMixin from '../../mixins/routerMixin';
|
||||||
import Station from '../../scripts/interfaces/Station';
|
import Station from '../../scripts/interfaces/Station';
|
||||||
import { useStore } from '../../store/mainStore';
|
import { useMainStore } from '../../store/mainStore';
|
||||||
import modalTrainMixin from '../../mixins/modalTrainMixin';
|
import modalTrainMixin from '../../mixins/modalTrainMixin';
|
||||||
import ScheduledTrainStatus from './ScheduledTrainStatus.vue';
|
import ScheduledTrainStatus from './ScheduledTrainStatus.vue';
|
||||||
import { OnlineScenery } from '../../store/typings';
|
import { OnlineScenery } from '../../store/typings';
|
||||||
|
import { useApiStore } from '../../store/apiStore';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'SceneryTimetable',
|
name: 'SceneryTimetable',
|
||||||
@@ -224,7 +225,8 @@ export default defineComponent({
|
|||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const currentURL = computed(() => `${location.origin}${route.fullPath}`);
|
const currentURL = computed(() => `${location.origin}${route.fullPath}`);
|
||||||
|
|
||||||
const store = useStore();
|
const apiStore = useApiStore();
|
||||||
|
const mainStore = useMainStore();
|
||||||
|
|
||||||
const chosenCheckpoint = ref(
|
const chosenCheckpoint = ref(
|
||||||
props.station?.generalInfo?.checkpoints?.length == 0
|
props.station?.generalInfo?.checkpoints?.length == 0
|
||||||
@@ -235,7 +237,8 @@ export default defineComponent({
|
|||||||
return {
|
return {
|
||||||
currentURL,
|
currentURL,
|
||||||
chosenCheckpoint,
|
chosenCheckpoint,
|
||||||
store
|
apiStore,
|
||||||
|
mainStore
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -256,7 +259,7 @@ export default defineComponent({
|
|||||||
(train) =>
|
(train) =>
|
||||||
train.checkpointName.toLocaleLowerCase() ==
|
train.checkpointName.toLocaleLowerCase() ==
|
||||||
(this.chosenCheckpoint || this.station!.name).toLocaleLowerCase() &&
|
(this.chosenCheckpoint || this.station!.name).toLocaleLowerCase() &&
|
||||||
train.region == this.store.region.id
|
train.region == this.mainStore.region.id
|
||||||
)
|
)
|
||||||
.sort((a, b) => {
|
.sort((a, b) => {
|
||||||
if (a.stopStatusID > b.stopStatusID) return 1;
|
if (a.stopStatusID > b.stopStatusID) return 1;
|
||||||
|
|||||||
@@ -139,7 +139,7 @@ import { defineComponent, inject } from 'vue';
|
|||||||
import keyMixin from '../../mixins/keyMixin';
|
import keyMixin from '../../mixins/keyMixin';
|
||||||
import routerMixin from '../../mixins/routerMixin';
|
import routerMixin from '../../mixins/routerMixin';
|
||||||
import { useStationFiltersStore } from '../../store/stationFiltersStore';
|
import { useStationFiltersStore } from '../../store/stationFiltersStore';
|
||||||
import { useStore } from '../../store/mainStore';
|
import { useMainStore } from '../../store/mainStore';
|
||||||
|
|
||||||
import FilterOption from './FilterOption.vue';
|
import FilterOption from './FilterOption.vue';
|
||||||
import StorageManager from '../../managers/storageManager';
|
import StorageManager from '../../managers/storageManager';
|
||||||
@@ -163,7 +163,7 @@ export default defineComponent({
|
|||||||
|
|
||||||
setup() {
|
setup() {
|
||||||
const isVisible = inject('isFilterCardVisible');
|
const isVisible = inject('isFilterCardVisible');
|
||||||
const store = useStore();
|
const store = useMainStore();
|
||||||
const filterStore = useStationFiltersStore();
|
const filterStore = useStationFiltersStore();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -116,7 +116,7 @@
|
|||||||
<td class="station_dispatcher-name">
|
<td class="station_dispatcher-name">
|
||||||
<span v-if="station.onlineInfo?.dispatcherName">
|
<span v-if="station.onlineInfo?.dispatcherName">
|
||||||
<b
|
<b
|
||||||
v-if="store.donatorsData.includes(station.onlineInfo.dispatcherName)"
|
v-if="apiStore.donatorsData.includes(station.onlineInfo.dispatcherName)"
|
||||||
:title="$t('donations.dispatcher-message')"
|
:title="$t('donations.dispatcher-message')"
|
||||||
@click.stop="openDonationModal"
|
@click.stop="openDonationModal"
|
||||||
>
|
>
|
||||||
@@ -294,11 +294,12 @@ import stationInfoMixin from '../../mixins/stationInfoMixin';
|
|||||||
import styleMixin from '../../mixins/styleMixin';
|
import styleMixin from '../../mixins/styleMixin';
|
||||||
import Station from '../../scripts/interfaces/Station';
|
import Station from '../../scripts/interfaces/Station';
|
||||||
import { useStationFiltersStore } from '../../store/stationFiltersStore';
|
import { useStationFiltersStore } from '../../store/stationFiltersStore';
|
||||||
import { useStore } from '../../store/mainStore';
|
import { useMainStore } from '../../store/mainStore';
|
||||||
import Loading from '../Global/Loading.vue';
|
import Loading from '../Global/Loading.vue';
|
||||||
import { HeadIdsTypes, headIconsIds, headIds } from '../../scripts/data/stationHeaderNames';
|
import { HeadIdsTypes, headIconsIds, headIds } from '../../scripts/data/stationHeaderNames';
|
||||||
import StationStatusBadge from '../Global/StationStatusBadge.vue';
|
import StationStatusBadge from '../Global/StationStatusBadge.vue';
|
||||||
import { Status } from '../../typings/common';
|
import { Status } from '../../typings/common';
|
||||||
|
import { useApiStore } from '../../store/apiStore';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
props: {
|
props: {
|
||||||
@@ -325,17 +326,19 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
|
|
||||||
setup() {
|
setup() {
|
||||||
const store = useStore();
|
const mainStore = useMainStore();
|
||||||
|
const apiStore = useApiStore();
|
||||||
const stationFiltersStore = useStationFiltersStore();
|
const stationFiltersStore = useStationFiltersStore();
|
||||||
|
|
||||||
const isDataLoaded = computed(() => {
|
const isDataLoaded = computed(() => {
|
||||||
return store.dataStatuses.sceneries != Status.Data.Loading;
|
return apiStore.dataStatuses.sceneries != Status.Data.Loading;
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
isDataLoaded,
|
isDataLoaded,
|
||||||
stationFiltersStore,
|
stationFiltersStore,
|
||||||
store
|
mainStore,
|
||||||
|
apiStore
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -357,7 +360,7 @@ export default defineComponent({
|
|||||||
|
|
||||||
openDonationModal(e: Event) {
|
openDonationModal(e: Event) {
|
||||||
this.$emit('toggleDonationModal', true);
|
this.$emit('toggleDonationModal', true);
|
||||||
this.store.modalLastClickedTarget = e.target;
|
this.mainStore.modalLastClickedTarget = e.target;
|
||||||
},
|
},
|
||||||
|
|
||||||
openForumSite(e: Event, url: string | undefined) {
|
openForumSite(e: Event, url: string | undefined) {
|
||||||
|
|||||||
@@ -35,7 +35,7 @@
|
|||||||
|
|
||||||
<div class="train-driver">
|
<div class="train-driver">
|
||||||
<b
|
<b
|
||||||
v-if="store.donatorsData.includes(train.driverName)"
|
v-if="apiStore.donatorsData.includes(train.driverName)"
|
||||||
:title="$t('donations.driver-message')"
|
:title="$t('donations.driver-message')"
|
||||||
>
|
>
|
||||||
{{ train.driverName }}
|
{{ train.driverName }}
|
||||||
@@ -126,7 +126,8 @@ import trainInfoMixin from '../../mixins/trainInfoMixin';
|
|||||||
import Train from '../../scripts/interfaces/Train';
|
import Train from '../../scripts/interfaces/Train';
|
||||||
import ProgressBar from '../Global/ProgressBar.vue';
|
import ProgressBar from '../Global/ProgressBar.vue';
|
||||||
import TrainThumbnail from '../Global/TrainThumbnail.vue';
|
import TrainThumbnail from '../Global/TrainThumbnail.vue';
|
||||||
import { useStore } from '../../store/mainStore';
|
import { useMainStore } from '../../store/mainStore';
|
||||||
|
import { useApiStore } from '../../store/apiStore';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
mixins: [trainInfoMixin, styleMixin],
|
mixins: [trainInfoMixin, styleMixin],
|
||||||
@@ -145,7 +146,8 @@ export default defineComponent({
|
|||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
store: useStore()
|
store: useMainStore(),
|
||||||
|
apiStore: useApiStore()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -72,7 +72,7 @@
|
|||||||
import { computed, defineComponent, PropType } from 'vue';
|
import { computed, defineComponent, PropType } from 'vue';
|
||||||
import dateMixin from '../../mixins/dateMixin';
|
import dateMixin from '../../mixins/dateMixin';
|
||||||
import Train from '../../scripts/interfaces/Train';
|
import Train from '../../scripts/interfaces/Train';
|
||||||
import { useStore } from '../../store/mainStore';
|
import { useMainStore } from '../../store/mainStore';
|
||||||
import StopDate from '../Global/StopDate.vue';
|
import StopDate from '../Global/StopDate.vue';
|
||||||
import StockList from '../Global/StockList.vue';
|
import StockList from '../Global/StockList.vue';
|
||||||
import { TrainStop } from '../../store/typings';
|
import { TrainStop } from '../../store/typings';
|
||||||
@@ -92,7 +92,7 @@ export default defineComponent({
|
|||||||
|
|
||||||
setup(props) {
|
setup(props) {
|
||||||
return {
|
return {
|
||||||
store: useStore(),
|
store: useMainStore(),
|
||||||
|
|
||||||
lastConfirmed: computed(() => {
|
lastConfirmed: computed(() => {
|
||||||
return props.train.timetableData!.followingStops.findIndex(
|
return props.train.timetableData!.followingStops.findIndex(
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
<hr style="margin: 0.5em 0" />
|
<hr style="margin: 0.5em 0" />
|
||||||
|
|
||||||
<div v-if="store.dataStatuses.trains == Status.Loaded && regionTrains.length > 0">
|
<div v-if="apiStore.dataStatuses.trains == Status.Loaded && regionTrains.length > 0">
|
||||||
<div class="top-list general">
|
<div class="top-list general">
|
||||||
<transition-group tag="ul" name="stats-anim">
|
<transition-group tag="ul" name="stats-anim">
|
||||||
<li class="badge" key="timetable-count">
|
<li class="badge" key="timetable-count">
|
||||||
@@ -88,7 +88,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-else-if="store.dataStatuses.trains != Status.Loaded">
|
<div v-else-if="apiStore.dataStatuses.trains != Status.Loaded">
|
||||||
{{ $t('train-stats.stats-loading') }}
|
{{ $t('train-stats.stats-loading') }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -102,8 +102,9 @@
|
|||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
import { useStore } from '../../store/mainStore';
|
import { useMainStore } from '../../store/mainStore';
|
||||||
import { Status } from '../../typings/common';
|
import { Status } from '../../typings/common';
|
||||||
|
import { useApiStore } from '../../store/apiStore';
|
||||||
|
|
||||||
interface ITop {
|
interface ITop {
|
||||||
name: string;
|
name: string;
|
||||||
@@ -127,7 +128,8 @@ export default defineComponent({
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
showOptions: false,
|
showOptions: false,
|
||||||
store: useStore(),
|
store: useMainStore(),
|
||||||
|
apiStore: useApiStore(),
|
||||||
Status: Status.Data
|
Status: Status.Data
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
<template>
|
<template>
|
||||||
<transition name="status-anim" mode="out-in" tag="div" class="train-table">
|
<transition name="status-anim" mode="out-in" tag="div" class="train-table">
|
||||||
<div :key="store.dataStatuses.trains">
|
<div :key="apiStore.dataStatuses.trains">
|
||||||
<div class="table-info" key="offline" v-if="store.isOffline">
|
<div class="table-info" key="offline" v-if="store.isOffline">
|
||||||
{{ $t('app.offline') }}
|
{{ $t('app.offline') }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Loading v-else-if="trains.length == 0 && store.dataStatuses.trains == 0" key="loading" />
|
<Loading v-else-if="trains.length == 0 && apiStore.dataStatuses.trains == 0" key="loading" />
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class="table-info"
|
class="table-info"
|
||||||
key="no-trains"
|
key="no-trains"
|
||||||
v-else-if="trains.length == 0 && store.dataStatuses.trains != 0"
|
v-else-if="trains.length == 0 && apiStore.dataStatuses.trains != 0"
|
||||||
>
|
>
|
||||||
{{ $t('trains.no-trains') }}
|
{{ $t('trains.no-trains') }}
|
||||||
</div>
|
</div>
|
||||||
@@ -35,10 +35,11 @@
|
|||||||
import { defineComponent, inject, PropType, Ref } from 'vue';
|
import { defineComponent, inject, PropType, Ref } from 'vue';
|
||||||
import modalTrainMixin from '../../mixins/modalTrainMixin';
|
import modalTrainMixin from '../../mixins/modalTrainMixin';
|
||||||
import Train from '../../scripts/interfaces/Train';
|
import Train from '../../scripts/interfaces/Train';
|
||||||
import { useStore } from '../../store/mainStore';
|
import { useMainStore } from '../../store/mainStore';
|
||||||
import Loading from '../Global/Loading.vue';
|
import Loading from '../Global/Loading.vue';
|
||||||
import TrainInfo from './TrainInfo.vue';
|
import TrainInfo from './TrainInfo.vue';
|
||||||
import { Status } from '../../typings/common';
|
import { Status } from '../../typings/common';
|
||||||
|
import { useApiStore } from '../../store/apiStore';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: { Loading, TrainInfo },
|
components: { Loading, TrainInfo },
|
||||||
@@ -53,7 +54,8 @@ export default defineComponent({
|
|||||||
mixins: [modalTrainMixin],
|
mixins: [modalTrainMixin],
|
||||||
|
|
||||||
setup() {
|
setup() {
|
||||||
const store = useStore();
|
const store = useMainStore();
|
||||||
|
const apiStore = useApiStore();
|
||||||
const searchedTrain = inject('searchedTrain') as Ref<string>;
|
const searchedTrain = inject('searchedTrain') as Ref<string>;
|
||||||
const searchedDriver = inject('searchedDriver') as Ref<string>;
|
const searchedDriver = inject('searchedDriver') as Ref<string>;
|
||||||
|
|
||||||
@@ -61,6 +63,7 @@ export default defineComponent({
|
|||||||
searchedTrain,
|
searchedTrain,
|
||||||
searchedDriver,
|
searchedDriver,
|
||||||
store,
|
store,
|
||||||
|
apiStore,
|
||||||
sorterActive: inject('sorterActive') as {
|
sorterActive: inject('sorterActive') as {
|
||||||
id: string | number;
|
id: string | number;
|
||||||
dir: number;
|
dir: number;
|
||||||
@@ -72,7 +75,7 @@ export default defineComponent({
|
|||||||
dataStatus() {
|
dataStatus() {
|
||||||
if (this.store.isOffline) return Status.Data.Offline;
|
if (this.store.isOffline) return Status.Data.Offline;
|
||||||
|
|
||||||
if (this.trains.length == 0 && this.store.dataStatuses.trains == Status.Data.Loading)
|
if (this.trains.length == 0 && this.apiStore.dataStatuses.trains == Status.Data.Loading)
|
||||||
return Status.Data.Loading;
|
return Status.Data.Loading;
|
||||||
|
|
||||||
return Status.Data.Loaded;
|
return Status.Data.Loaded;
|
||||||
|
|||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
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;
|
||||||
@@ -1,16 +1,16 @@
|
|||||||
import { defineComponent } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
import { useStore } from '../store/mainStore';
|
import { useApiStore } from '../store/apiStore';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
store: useStore()
|
apiStore: useApiStore()
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
isDonator(name: string) {
|
isDonator(name: string) {
|
||||||
return this.store.donatorsData.includes(name);
|
return this.apiStore.donatorsData.includes(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import { defineComponent } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
import { useStore } from '../store/mainStore';
|
import { useMainStore } from '../store/mainStore';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
store: useStore()
|
store: useMainStore()
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,114 @@
|
|||||||
|
import { defineStore } from 'pinia';
|
||||||
|
import http from '../http';
|
||||||
|
import { API } from '../typings/api';
|
||||||
|
import axios from 'axios';
|
||||||
|
import { Status } from '../typings/common';
|
||||||
|
import { StationJSONData } from './typings';
|
||||||
|
|
||||||
|
export const useApiStore = defineStore('apiStore', {
|
||||||
|
state: () => ({
|
||||||
|
dataStatuses: {
|
||||||
|
connection: Status.Data.Loading,
|
||||||
|
sceneries: Status.Data.Loading,
|
||||||
|
timetables: Status.Data.Loading,
|
||||||
|
dispatchers: Status.Data.Loading,
|
||||||
|
trains: Status.Data.Loading
|
||||||
|
},
|
||||||
|
|
||||||
|
activeData: undefined as API.ActiveData.Response | undefined,
|
||||||
|
rollingStockData: undefined as API.RollingStock.Response | undefined,
|
||||||
|
donatorsData: [] as API.Donators.Response,
|
||||||
|
sceneryData: [] as StationJSONData[]
|
||||||
|
}),
|
||||||
|
|
||||||
|
actions: {
|
||||||
|
async setupAPI() {
|
||||||
|
// Static data
|
||||||
|
this.fetchStockInfoData();
|
||||||
|
this.fetchDonatorsData();
|
||||||
|
this.fetchStationsGeneralInfo();
|
||||||
|
|
||||||
|
this.scheduleFetchActiveData();
|
||||||
|
},
|
||||||
|
|
||||||
|
async setDataStatuses() {
|
||||||
|
if (!this.activeData?.activeSceneries) {
|
||||||
|
this.dataStatuses.sceneries = Status.Data.Error;
|
||||||
|
this.dataStatuses.trains = Status.Data.Error;
|
||||||
|
this.dataStatuses.dispatchers = Status.Data.Error;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.dataStatuses.sceneries = Status.Data.Loaded;
|
||||||
|
this.dataStatuses.trains = !this.activeData.trains ? Status.Data.Warning : Status.Data.Loaded;
|
||||||
|
this.dataStatuses.dispatchers = Status.Data.Loaded;
|
||||||
|
},
|
||||||
|
|
||||||
|
async fetchDonatorsData() {
|
||||||
|
try {
|
||||||
|
const response = await http.get<API.Donators.Response>('api/getDonators');
|
||||||
|
|
||||||
|
this.donatorsData = response.data;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Ups! Wystąpił błąd podczas pobierania informacji o donatorach:', error);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
async fetchStockInfoData() {
|
||||||
|
try {
|
||||||
|
this.rollingStockData = (
|
||||||
|
await axios.get<API.RollingStock.Response>(
|
||||||
|
'https://raw.githubusercontent.com/Spythere/api/main/td2/data/stockInfo.json'
|
||||||
|
)
|
||||||
|
).data;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Ups! Wystąpił błąd podczas pobierania informacji o taborze z API:', error);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
async scheduleFetchActiveData() {
|
||||||
|
if (import.meta.env.VITE_API_MODE === 'mock') {
|
||||||
|
const mockActiveData = await import('../data/mockActiveData.json');
|
||||||
|
this.dataStatuses.connection = Status.Data.Loaded;
|
||||||
|
this.activeData = mockActiveData;
|
||||||
|
this.setDataStatuses();
|
||||||
|
|
||||||
|
console.warn('Stacjownik działa w trybie mockowania danych z WS');
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const data = (await http.get<API.ActiveData.Response>('api/getActiveData')).data;
|
||||||
|
|
||||||
|
this.activeData = data;
|
||||||
|
this.dataStatuses.connection = Status.Data.Loaded;
|
||||||
|
|
||||||
|
this.setDataStatuses();
|
||||||
|
} catch (error) {
|
||||||
|
this.dataStatuses.connection = Status.Data.Error;
|
||||||
|
console.error('Wystąpił błąd podczas pobierania danych online z API!');
|
||||||
|
} finally {
|
||||||
|
setTimeout(
|
||||||
|
() => {
|
||||||
|
this.scheduleFetchActiveData();
|
||||||
|
},
|
||||||
|
~~(1000 * (Math.random() * (25 - 20) + 25))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
async fetchStationsGeneralInfo() {
|
||||||
|
const sceneryData: StationJSONData[] = (await http.get<StationJSONData[]>('api/getSceneries'))
|
||||||
|
.data;
|
||||||
|
|
||||||
|
if (!sceneryData) {
|
||||||
|
this.dataStatuses.sceneries = Status.Data.Error;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.sceneryData = sceneryData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
+71
-183
@@ -1,37 +1,20 @@
|
|||||||
import axios from 'axios';
|
|
||||||
import { defineStore } from 'pinia';
|
import { defineStore } from 'pinia';
|
||||||
import StationRoutes from '../scripts/interfaces/StationRoutes';
|
import StationRoutes from '../scripts/interfaces/StationRoutes';
|
||||||
import Train from '../scripts/interfaces/Train';
|
import Train from '../scripts/interfaces/Train';
|
||||||
import { URLs } from '../scripts/utils/apiURLs';
|
|
||||||
import { parseSpawns, getScheduledTrains, getStationTrains } from './utils';
|
import { parseSpawns, getScheduledTrains, getStationTrains } from './utils';
|
||||||
|
|
||||||
import { OnlineScenery, ScheduledTrain, StationJSONData, StoreState } from './typings';
|
import { OnlineScenery, ScheduledTrain, StoreState } from './typings';
|
||||||
|
|
||||||
import { API } from '../typings/api';
|
|
||||||
import { Status } from '../typings/common';
|
import { Status } from '../typings/common';
|
||||||
|
import Station from '../scripts/interfaces/Station';
|
||||||
|
import { useApiStore } from './apiStore';
|
||||||
|
import { API } from '../typings/api';
|
||||||
|
|
||||||
const API_INTERVAL_MS = 20000;
|
export const useMainStore = defineStore('store', {
|
||||||
|
|
||||||
export const useStore = defineStore('store', {
|
|
||||||
state: () =>
|
state: () =>
|
||||||
({
|
({
|
||||||
activeData: {} as unknown,
|
|
||||||
rollingStockData: undefined,
|
|
||||||
donatorsData: [],
|
|
||||||
|
|
||||||
stationList: [],
|
|
||||||
regionOnlineCounters: [],
|
|
||||||
|
|
||||||
routesList: [],
|
|
||||||
|
|
||||||
sceneryData: [],
|
|
||||||
lastDispatcherStatuses: [],
|
|
||||||
|
|
||||||
region: { id: 'eu', value: 'PL1' },
|
region: { id: 'eu', value: 'PL1' },
|
||||||
|
|
||||||
trainCount: 0,
|
|
||||||
stationCount: 0,
|
|
||||||
|
|
||||||
isOffline: false,
|
isOffline: false,
|
||||||
|
|
||||||
dispatcherStatsName: '',
|
dispatcherStatsName: '',
|
||||||
@@ -43,29 +26,15 @@ export const useStore = defineStore('store', {
|
|||||||
|
|
||||||
chosenModalTrainId: undefined,
|
chosenModalTrainId: undefined,
|
||||||
|
|
||||||
dataStatuses: {
|
|
||||||
connection: Status.Data.Loading,
|
|
||||||
sceneries: Status.Data.Loading,
|
|
||||||
timetables: Status.Data.Loading,
|
|
||||||
dispatchers: Status.Data.Loading,
|
|
||||||
trains: Status.Data.Loading
|
|
||||||
},
|
|
||||||
|
|
||||||
blockScroll: false,
|
blockScroll: false,
|
||||||
listenerLaunched: false,
|
modalLastClickedTarget: null
|
||||||
modalLastClickedTarget: null,
|
|
||||||
|
|
||||||
tooltip: {
|
|
||||||
content: '',
|
|
||||||
visible: false,
|
|
||||||
x: 0,
|
|
||||||
y: 0
|
|
||||||
}
|
|
||||||
}) as StoreState,
|
}) as StoreState,
|
||||||
|
|
||||||
getters: {
|
getters: {
|
||||||
trainList(): Train[] {
|
trainList(): Train[] {
|
||||||
return (this.activeData?.trains ?? [])
|
const apiStore = useApiStore();
|
||||||
|
|
||||||
|
return (apiStore.activeData?.trains ?? [])
|
||||||
.filter((train) => train.timetable || train.online)
|
.filter((train) => train.timetable || train.online)
|
||||||
.map((train) => {
|
.map((train) => {
|
||||||
const stock = train.stockString.split(';');
|
const stock = train.stockString.split(';');
|
||||||
@@ -116,10 +85,12 @@ export const useStore = defineStore('store', {
|
|||||||
},
|
},
|
||||||
|
|
||||||
onlineSceneryList(state): OnlineScenery[] {
|
onlineSceneryList(state): OnlineScenery[] {
|
||||||
if (state.isOffline) return [];
|
const apiStore = useApiStore();
|
||||||
if (!state.activeData?.activeSceneries) return [];
|
|
||||||
|
|
||||||
return state.activeData?.activeSceneries.reduce((list, scenery) => {
|
if (state.isOffline) return [];
|
||||||
|
if (!apiStore.activeData?.activeSceneries) return [];
|
||||||
|
|
||||||
|
return apiStore.activeData?.activeSceneries.reduce((list, scenery) => {
|
||||||
if (scenery.isOnline !== 1 && Date.now() - scenery.lastSeen > 1000 * 60 * 2) return list;
|
if (scenery.isOnline !== 1 && Date.now() - scenery.lastSeen > 1000 * 60 * 2) return list;
|
||||||
if (scenery.dispatcherStatus == Status.ActiveDispatcher.UNKNOWN) return list;
|
if (scenery.dispatcherStatus == Status.ActiveDispatcher.UNKNOWN) return list;
|
||||||
|
|
||||||
@@ -178,13 +149,67 @@ export const useStore = defineStore('store', {
|
|||||||
|
|
||||||
return list;
|
return list;
|
||||||
}, [] as OnlineScenery[]);
|
}, [] as OnlineScenery[]);
|
||||||
|
},
|
||||||
|
|
||||||
|
stationList(): Station[] {
|
||||||
|
const apiStore = useApiStore();
|
||||||
|
|
||||||
|
return apiStore.sceneryData.map((scenery) => {
|
||||||
|
return {
|
||||||
|
name: scenery.name,
|
||||||
|
|
||||||
|
generalInfo: {
|
||||||
|
...scenery,
|
||||||
|
authors: scenery.authors?.split(',').map((a) => a.trim()),
|
||||||
|
routes:
|
||||||
|
scenery.routesInfo.reduce(
|
||||||
|
(acc, route) => {
|
||||||
|
const propName: keyof StationRoutes = `${
|
||||||
|
route.routeTracks == 2 ? 'twoWay' : 'oneWay'
|
||||||
|
}${route.isElectric ? '' : 'No'}CatenaryRouteNames`;
|
||||||
|
|
||||||
|
acc[route.routeTracks == 2 ? 'twoWay' : 'oneWay'].push({
|
||||||
|
name: route.routeName,
|
||||||
|
SBL: route.isRouteSBL,
|
||||||
|
TWB: false,
|
||||||
|
catenary: route.isElectric,
|
||||||
|
isInternal: route.isInternal,
|
||||||
|
tracks: route.routeTracks,
|
||||||
|
length: route.routeLength,
|
||||||
|
speed: route.routeSpeed
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!route.isInternal) acc[propName].push(route.routeName);
|
||||||
|
|
||||||
|
if (route.isRouteSBL) acc['sblRouteNames'].push(route.routeName);
|
||||||
|
|
||||||
|
return acc;
|
||||||
|
},
|
||||||
|
{
|
||||||
|
oneWay: [],
|
||||||
|
twoWay: [],
|
||||||
|
sblRouteNames: [],
|
||||||
|
oneWayCatenaryRouteNames: [],
|
||||||
|
oneWayNoCatenaryRouteNames: [],
|
||||||
|
twoWayCatenaryRouteNames: [],
|
||||||
|
twoWayNoCatenaryRouteNames: []
|
||||||
|
} as StationRoutes
|
||||||
|
) || {},
|
||||||
|
checkpoints: scenery.checkpoints
|
||||||
|
? scenery.checkpoints
|
||||||
|
.split(';')
|
||||||
|
.map((sub) => ({ checkpointName: sub, scheduledTrains: [] }))
|
||||||
|
: []
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
async processStationsOnlineInfo() {
|
async processStationsOnlineInfo(activeData: API.ActiveData.Response) {
|
||||||
if (!this.activeData.activeSceneries) return;
|
if (!activeData.activeSceneries) return;
|
||||||
|
|
||||||
const onlineSceneries = this.activeData.activeSceneries.reduce((acc, scenery) => {
|
const onlineSceneries = activeData.activeSceneries.reduce((acc, scenery) => {
|
||||||
const savedStation = this.stationList.find((st) => scenery.stationName === st.name);
|
const savedStation = this.stationList.find((st) => scenery.stationName === st.name);
|
||||||
|
|
||||||
if (scenery.isOnline !== 1 && Date.now() - scenery.lastSeen > 1000 * 60 * 2) return acc;
|
if (scenery.isOnline !== 1 && Date.now() - scenery.lastSeen > 1000 * 60 * 2) return acc;
|
||||||
@@ -266,146 +291,9 @@ export const useStore = defineStore('store', {
|
|||||||
)
|
)
|
||||||
.forEach((station) => (station.onlineInfo = undefined));
|
.forEach((station) => (station.onlineInfo = undefined));
|
||||||
},
|
},
|
||||||
async fetchStationsGeneralInfo() {
|
|
||||||
const sceneryData: StationJSONData[] = await (
|
|
||||||
await axios.get(`${URLs.stacjownikAPI}/api/getSceneries`)
|
|
||||||
).data;
|
|
||||||
|
|
||||||
if (!sceneryData) {
|
|
||||||
this.dataStatuses.sceneries = Status.Data.Error;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.stationList = sceneryData.map((scenery) => {
|
|
||||||
return {
|
|
||||||
name: scenery.name,
|
|
||||||
|
|
||||||
generalInfo: {
|
|
||||||
...scenery,
|
|
||||||
authors: scenery.authors?.split(',').map((a) => a.trim()),
|
|
||||||
routes:
|
|
||||||
scenery.routesInfo.reduce(
|
|
||||||
(acc, route) => {
|
|
||||||
const propName: keyof StationRoutes = `${
|
|
||||||
route.routeTracks == 2 ? 'twoWay' : 'oneWay'
|
|
||||||
}${route.isElectric ? '' : 'No'}CatenaryRouteNames`;
|
|
||||||
|
|
||||||
acc[route.routeTracks == 2 ? 'twoWay' : 'oneWay'].push({
|
|
||||||
name: route.routeName,
|
|
||||||
SBL: route.isRouteSBL,
|
|
||||||
TWB: false,
|
|
||||||
catenary: route.isElectric,
|
|
||||||
isInternal: route.isInternal,
|
|
||||||
tracks: route.routeTracks,
|
|
||||||
length: route.routeLength,
|
|
||||||
speed: route.routeSpeed
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!route.isInternal) acc[propName].push(route.routeName);
|
|
||||||
|
|
||||||
if (route.isRouteSBL) acc['sblRouteNames'].push(route.routeName);
|
|
||||||
|
|
||||||
return acc;
|
|
||||||
},
|
|
||||||
{
|
|
||||||
oneWay: [],
|
|
||||||
twoWay: [],
|
|
||||||
sblRouteNames: [],
|
|
||||||
oneWayCatenaryRouteNames: [],
|
|
||||||
oneWayNoCatenaryRouteNames: [],
|
|
||||||
twoWayCatenaryRouteNames: [],
|
|
||||||
twoWayNoCatenaryRouteNames: []
|
|
||||||
} as StationRoutes
|
|
||||||
) || {},
|
|
||||||
checkpoints: scenery.checkpoints
|
|
||||||
? scenery.checkpoints
|
|
||||||
.split(';')
|
|
||||||
.map((sub) => ({ checkpointName: sub, scheduledTrains: [] }))
|
|
||||||
: []
|
|
||||||
}
|
|
||||||
};
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
async fetchActiveData() {
|
|
||||||
if (import.meta.env.VITE_APP_API_MODE === 'mock') {
|
|
||||||
const mockActiveData = await import('../data/mockActiveData.json');
|
|
||||||
this.dataStatuses.connection = Status.Data.Loaded;
|
|
||||||
this.activeData = mockActiveData;
|
|
||||||
this.setStatuses();
|
|
||||||
|
|
||||||
console.warn('Stacjownik działa w trybie mockowania danych z WS');
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
const data = (
|
|
||||||
await axios.get<API.ActiveData.Response>(`${URLs.stacjownikAPI}/api/getActiveData`)
|
|
||||||
).data;
|
|
||||||
|
|
||||||
this.activeData = data;
|
|
||||||
this.dataStatuses.connection = Status.Data.Loaded;
|
|
||||||
|
|
||||||
this.setStatuses();
|
|
||||||
} catch (error) {
|
|
||||||
this.dataStatuses.connection = Status.Data.Error;
|
|
||||||
console.error('Wystąpił błąd podczas pobierania danych online z API!');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
async setupAPI() {
|
|
||||||
this.fetchActiveData();
|
|
||||||
|
|
||||||
setInterval(() => {
|
|
||||||
this.fetchActiveData();
|
|
||||||
}, API_INTERVAL_MS);
|
|
||||||
|
|
||||||
this.fetchStockInfoData();
|
|
||||||
this.fetchDonatorsData();
|
|
||||||
this.fetchStationsGeneralInfo();
|
|
||||||
},
|
|
||||||
|
|
||||||
async changeRegion(region: StoreState['region']) {
|
async changeRegion(region: StoreState['region']) {
|
||||||
this.region = region;
|
this.region = region;
|
||||||
},
|
|
||||||
|
|
||||||
async fetchStockInfoData() {
|
|
||||||
try {
|
|
||||||
this.rollingStockData = (
|
|
||||||
await axios.get<API.RollingStock.Response>(
|
|
||||||
'https://raw.githubusercontent.com/Spythere/api/main/td2/data/stockInfo.json'
|
|
||||||
)
|
|
||||||
).data;
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Ups! Wystąpił błąd podczas pobierania informacji o taborze z API:', error);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
async fetchDonatorsData() {
|
|
||||||
try {
|
|
||||||
const response = await axios.get<API.Donators.Response>(
|
|
||||||
`${URLs.stacjownikAPI}/api/getDonators`
|
|
||||||
);
|
|
||||||
|
|
||||||
if (response.data) this.donatorsData = response.data;
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Ups! Wystąpił błąd podczas pobierania informacji o donatorach:', error);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
async setStatuses() {
|
|
||||||
if (!this.activeData.activeSceneries) {
|
|
||||||
this.dataStatuses.sceneries = Status.Data.Error;
|
|
||||||
this.dataStatuses.trains = Status.Data.Error;
|
|
||||||
this.dataStatuses.dispatchers = Status.Data.Error;
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.dataStatuses.sceneries = Status.Data.Loaded;
|
|
||||||
this.dataStatuses.trains = !this.activeData.trains ? Status.Data.Warning : Status.Data.Loaded;
|
|
||||||
this.dataStatuses.dispatchers = Status.Data.Loaded;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { defineStore } from 'pinia';
|
import { defineStore } from 'pinia';
|
||||||
import inputData from '../data/options.json';
|
import inputData from '../data/options.json';
|
||||||
import { useStore } from './mainStore';
|
import { useMainStore } from './mainStore';
|
||||||
import { filterStations, sortStations } from '../scripts/utils/filterUtils';
|
import { filterStations, sortStations } from '../scripts/utils/filterUtils';
|
||||||
import { HeadIdsTypes } from '../scripts/data/stationHeaderNames';
|
import { HeadIdsTypes } from '../scripts/data/stationHeaderNames';
|
||||||
import StorageManager from '../managers/storageManager';
|
import StorageManager from '../managers/storageManager';
|
||||||
@@ -70,7 +70,7 @@ export const useStationFiltersStore = defineStore('stationFiltersStore', {
|
|||||||
},
|
},
|
||||||
|
|
||||||
filteredStationList: (state) => {
|
filteredStationList: (state) => {
|
||||||
const store = useStore();
|
const store = useMainStore();
|
||||||
const savedStationNames = store.stationList.map((s) => s.name);
|
const savedStationNames = store.stationList.map((s) => s.name);
|
||||||
|
|
||||||
const onlineUnsavedStations = store.onlineSceneryList
|
const onlineUnsavedStations = store.onlineSceneryList
|
||||||
|
|||||||
@@ -11,24 +11,7 @@ export interface RegionCounters {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface StoreState {
|
export interface StoreState {
|
||||||
stationList: Station[];
|
|
||||||
activeData: API.ActiveData.Response;
|
|
||||||
rollingStockData?: API.RollingStock.Response;
|
|
||||||
donatorsData: API.Donators.Response;
|
|
||||||
|
|
||||||
regionOnlineCounters: RegionCounters[];
|
|
||||||
|
|
||||||
lastDispatcherStatuses: {
|
|
||||||
hash: string;
|
|
||||||
statusTimestamp: number;
|
|
||||||
statusID: Status.ActiveDispatcher;
|
|
||||||
}[];
|
|
||||||
|
|
||||||
sceneryData: any[][];
|
|
||||||
|
|
||||||
region: { id: string; value: string };
|
region: { id: string; value: string };
|
||||||
trainCount: number;
|
|
||||||
stationCount: number;
|
|
||||||
|
|
||||||
isOffline: boolean;
|
isOffline: boolean;
|
||||||
|
|
||||||
@@ -41,24 +24,8 @@ export interface StoreState {
|
|||||||
|
|
||||||
chosenModalTrainId?: string;
|
chosenModalTrainId?: string;
|
||||||
|
|
||||||
dataStatuses: {
|
|
||||||
connection: Status.Data;
|
|
||||||
sceneries: Status.Data;
|
|
||||||
timetables: Status.Data;
|
|
||||||
dispatchers: Status.Data;
|
|
||||||
trains: Status.Data;
|
|
||||||
};
|
|
||||||
|
|
||||||
listenerLaunched: boolean;
|
|
||||||
blockScroll: boolean;
|
blockScroll: boolean;
|
||||||
modalLastClickedTarget: EventTarget | null;
|
modalLastClickedTarget: EventTarget | null;
|
||||||
|
|
||||||
tooltip: {
|
|
||||||
visible: boolean;
|
|
||||||
x: number;
|
|
||||||
y: number;
|
|
||||||
content: string;
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface StationRoutesInfo {
|
export interface StationRoutesInfo {
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ import axios from 'axios';
|
|||||||
|
|
||||||
import JournalOptions from '../components/JournalView/JournalOptions.vue';
|
import JournalOptions from '../components/JournalView/JournalOptions.vue';
|
||||||
import { URLs } from '../scripts/utils/apiURLs';
|
import { URLs } from '../scripts/utils/apiURLs';
|
||||||
import { useStore } from '../store/mainStore';
|
import { useMainStore } from '../store/mainStore';
|
||||||
import JournalDispatchersList from '../components/JournalView/JournalDispatchersList.vue';
|
import JournalDispatchersList from '../components/JournalView/JournalDispatchersList.vue';
|
||||||
|
|
||||||
import JournalHeader from '../components/JournalView/JournalHeader.vue';
|
import JournalHeader from '../components/JournalView/JournalHeader.vue';
|
||||||
@@ -105,7 +105,7 @@ export default defineComponent({
|
|||||||
const scrollElement: Ref<HTMLElement | null> = ref(null);
|
const scrollElement: Ref<HTMLElement | null> = ref(null);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
store: useStore(),
|
store: useMainStore(),
|
||||||
|
|
||||||
sorterActive,
|
sorterActive,
|
||||||
searchersValues,
|
searchersValues,
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ import JournalStats from '../components/JournalView/JournalStats.vue';
|
|||||||
import JournalHeader from '../components/JournalView/JournalHeader.vue';
|
import JournalHeader from '../components/JournalView/JournalHeader.vue';
|
||||||
|
|
||||||
import { URLs } from '../scripts/utils/apiURLs';
|
import { URLs } from '../scripts/utils/apiURLs';
|
||||||
import { useStore } from '../store/mainStore';
|
import { useMainStore } from '../store/mainStore';
|
||||||
|
|
||||||
import { LocationQuery } from 'vue-router';
|
import { LocationQuery } from 'vue-router';
|
||||||
|
|
||||||
@@ -194,7 +194,7 @@ export default defineComponent({
|
|||||||
|
|
||||||
scrollElement,
|
scrollElement,
|
||||||
|
|
||||||
store: useStore()
|
store: useMainStore()
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -42,8 +42,8 @@
|
|||||||
|
|
||||||
<div
|
<div
|
||||||
v-if="
|
v-if="
|
||||||
store.dataStatuses.sceneries == Status.Loading ||
|
apiStore.dataStatuses.sceneries == Status.Loading ||
|
||||||
store.dataStatuses.trains == Status.Loading
|
apiStore.dataStatuses.trains == Status.Loading
|
||||||
"
|
"
|
||||||
></div>
|
></div>
|
||||||
|
|
||||||
@@ -64,7 +64,7 @@
|
|||||||
import { computed, defineComponent } from 'vue';
|
import { computed, defineComponent } from 'vue';
|
||||||
import { useRoute } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
import routerMixin from '../mixins/routerMixin';
|
import routerMixin from '../mixins/routerMixin';
|
||||||
import { useStore } from '../store/mainStore';
|
import { useMainStore } from '../store/mainStore';
|
||||||
|
|
||||||
import SceneryInfo from '../components/SceneryView/SceneryInfo.vue';
|
import SceneryInfo from '../components/SceneryView/SceneryInfo.vue';
|
||||||
import SceneryHeader from '../components/SceneryView/SceneryHeader.vue';
|
import SceneryHeader from '../components/SceneryView/SceneryHeader.vue';
|
||||||
@@ -73,6 +73,7 @@ import SceneryTimetablesHistory from '../components/SceneryView/SceneryTimetable
|
|||||||
import SceneryDispatchersHistory from '../components/SceneryView/SceneryDispatchersHistory.vue';
|
import SceneryDispatchersHistory from '../components/SceneryView/SceneryDispatchersHistory.vue';
|
||||||
import ActionButton from '../components/Global/ActionButton.vue';
|
import ActionButton from '../components/Global/ActionButton.vue';
|
||||||
import { Status } from '../typings/common';
|
import { Status } from '../typings/common';
|
||||||
|
import { useApiStore } from '../store/apiStore';
|
||||||
|
|
||||||
enum SceneryViewMode {
|
enum SceneryViewMode {
|
||||||
'TIMETABLES_ACTIVE',
|
'TIMETABLES_ACTIVE',
|
||||||
@@ -107,7 +108,9 @@ export default defineComponent({
|
|||||||
mixins: [routerMixin],
|
mixins: [routerMixin],
|
||||||
|
|
||||||
data: () => ({
|
data: () => ({
|
||||||
store: useStore(),
|
store: useMainStore(),
|
||||||
|
apiStore: useApiStore(),
|
||||||
|
|
||||||
viewModes: [
|
viewModes: [
|
||||||
{
|
{
|
||||||
id: 'scenery.option-active-timetables',
|
id: 'scenery.option-active-timetables',
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ import { defineComponent } from 'vue';
|
|||||||
import StationTable from '../components/StationsView/StationTable.vue';
|
import StationTable from '../components/StationsView/StationTable.vue';
|
||||||
import StationFilterCard from '../components/StationsView/StationFilterCard.vue';
|
import StationFilterCard from '../components/StationsView/StationFilterCard.vue';
|
||||||
import { useStationFiltersStore } from '../store/stationFiltersStore';
|
import { useStationFiltersStore } from '../store/stationFiltersStore';
|
||||||
import { useStore } from '../store/mainStore';
|
import { useMainStore } from '../store/mainStore';
|
||||||
import Donation from '../components/Global/Donation.vue';
|
import Donation from '../components/Global/Donation.vue';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
@@ -37,7 +37,7 @@ export default defineComponent({
|
|||||||
STORAGE_KEY: 'options_saved',
|
STORAGE_KEY: 'options_saved',
|
||||||
focusedStationName: '',
|
focusedStationName: '',
|
||||||
filterStore: useStationFiltersStore(),
|
filterStore: useStationFiltersStore(),
|
||||||
store: useStore(),
|
store: useMainStore(),
|
||||||
|
|
||||||
isDonationModalOpen: false
|
isDonationModalOpen: false
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ import TrainOptions from '../components/TrainsView/TrainOptions.vue';
|
|||||||
import TrainTable from '../components/TrainsView/TrainTable.vue';
|
import TrainTable from '../components/TrainsView/TrainTable.vue';
|
||||||
import modalTrainMixin from '../mixins/modalTrainMixin';
|
import modalTrainMixin from '../mixins/modalTrainMixin';
|
||||||
import Train from '../scripts/interfaces/Train';
|
import Train from '../scripts/interfaces/Train';
|
||||||
import { useStore } from '../store/mainStore';
|
import { useMainStore } from '../store/mainStore';
|
||||||
import { TrainFilter, trainFilters } from '../components/TrainsView/typings';
|
import { TrainFilter, trainFilters } from '../components/TrainsView/typings';
|
||||||
import { filteredTrainList } from '../managers/trainFilterManager';
|
import { filteredTrainList } from '../managers/trainFilterManager';
|
||||||
import TrainStats from '../components/TrainsView/TrainStats.vue';
|
import TrainStats from '../components/TrainsView/TrainStats.vue';
|
||||||
@@ -58,7 +58,7 @@ export default defineComponent({
|
|||||||
}),
|
}),
|
||||||
|
|
||||||
setup() {
|
setup() {
|
||||||
const store = useStore();
|
const store = useMainStore();
|
||||||
const initTrainFilters = [...trainFilters.map((f) => ({ ...f }))];
|
const initTrainFilters = [...trainFilters.map((f) => ({ ...f }))];
|
||||||
|
|
||||||
const sorterActive = reactive({ id: 'routeDistance', dir: -1 });
|
const sorterActive = reactive({ id: 'routeDistance', dir: -1 });
|
||||||
|
|||||||
Reference in New Issue
Block a user