mirror of
https://github.com/Spythere/pojazdownik.git
synced 2026-05-03 19:48:11 +00:00
498 lines
12 KiB
Vue
498 lines
12 KiB
Vue
<template>
|
|
<section class="inputs">
|
|
<div class="input inputs_loco">
|
|
<div class="input_container">
|
|
<h2 class="input_header">LOKOMOTYWA / ZESP. TRAKCYJNY</h2>
|
|
<div class="input_radio">
|
|
<button
|
|
v-for="label in locoLabels"
|
|
:key="label.id"
|
|
@click="onLocoPowerChange(label.id)"
|
|
:class="{ checked: store.chosenLocoPower == label.id }"
|
|
data-ignore-outside="1"
|
|
>
|
|
{{ label.title }}
|
|
</button>
|
|
</div>
|
|
|
|
<div class="input_list type">
|
|
<select
|
|
id="loco-select"
|
|
ref="loco-select"
|
|
v-model="store.chosenLoco"
|
|
@change="onLocoTypeChange"
|
|
data-select="loco"
|
|
data-ignore-outside="1"
|
|
>
|
|
<option :value="null" disabled>Wybierz pojazd z listy</option>
|
|
<option v-for="loco in locoOptions" :value="loco" :key="loco.type">
|
|
{{ loco.supportersOnly ? '*S*' : '' }}
|
|
{{ loco.type }}
|
|
</option>
|
|
</select>
|
|
|
|
<button class="btn--add" @click="addVehicle" title="Dodaj pojazd">
|
|
<img :src="icons.add" alt="add vehicle" data-ignore-outside="1" />
|
|
</button>
|
|
|
|
<!-- <button class="btn--swap" @click="prepareSwapVehicles" title="Zamień pojazdy">
|
|
<img :src="icons.swap" alt="swap vehicle" />
|
|
</button> -->
|
|
</div>
|
|
|
|
<div class="input_ready-stock">
|
|
<button class="btn" @click="setReadyStockList(true)"><b>REALNE ZESTAWIENIA</b></button>
|
|
<ready-stock-list />
|
|
</div>
|
|
|
|
<div class="input_checkbox">
|
|
<button @click="onShowSupporterChange" :class="{ checked: this.store.showSupporter }" data-ignore-outside="1">
|
|
Pokaż tylko pojazdy dla supporterów
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="spacer"></div>
|
|
|
|
<div class="input inputs_car">
|
|
<div class="input_container">
|
|
<h2 class="input_header">RODZAJ WAGONU</h2>
|
|
<div class="input_radio">
|
|
<button
|
|
v-for="label in carLabels"
|
|
:key="label.id"
|
|
@click="onCarUseTypeChange(label.id)"
|
|
:class="{ checked: store.chosenCarUseType == label.id }"
|
|
data-ignore-outside="1"
|
|
>
|
|
{{ label.title }}
|
|
</button>
|
|
</div>
|
|
|
|
<div class="input_list type">
|
|
<select
|
|
id="car-select"
|
|
ref="car-select"
|
|
v-model="store.chosenCar"
|
|
@change="onCarTypeChange"
|
|
data-select="car"
|
|
data-ignore-outside="1"
|
|
>
|
|
<option :value="null" disabled>Wybierz wagon z listy</option>
|
|
<option v-for="car in carOptions" :value="car" :key="car.type">
|
|
{{ car.supportersOnly ? '*S*' : '' }}
|
|
{{ car.type }}
|
|
</option>
|
|
</select>
|
|
|
|
<button class="btn--add" @click="addVehicle" title="Dodaj pojazd">
|
|
<img :src="icons.add" alt="add vehicle" data-ignore-outside="1" />
|
|
</button>
|
|
|
|
<!-- <button class="btn--swap" @click="prepareSwapVehicles" title="Zamień pojazdy">
|
|
<img :src="icons.swap" alt="swap vehicle" />
|
|
</button> -->
|
|
</div>
|
|
|
|
<div class="input_list cargo">
|
|
<select
|
|
id="cargo-select"
|
|
:disabled="
|
|
(store.chosenCar && !store.chosenCar.loadable) ||
|
|
(store.chosenCar && store.chosenCar.useType == 'car-passenger') ||
|
|
!store.chosenCar
|
|
"
|
|
data-select="cargo"
|
|
data-ignore-outside="1"
|
|
v-model="store.chosenCargo"
|
|
>
|
|
<option :value="null" v-if="!store.chosenCar || !store.chosenCar.loadable">brak dostępnych ładunków</option>
|
|
<option :value="null" v-else>próżny</option>
|
|
|
|
<option v-for="cargo in store.chosenCar?.cargoList" :value="cargo" :key="cargo.id">
|
|
{{ cargo.id }}
|
|
</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
</template>
|
|
|
|
<script lang="ts">
|
|
import { ICarWagon, ILocomotive, IStore } from '@/types';
|
|
import { defineComponent, inject, provide, Ref, ref } from 'vue';
|
|
|
|
import ReadyStockList from '@/components/ReadyStockList.vue';
|
|
|
|
export default defineComponent({
|
|
components: {
|
|
ReadyStockList,
|
|
},
|
|
setup() {
|
|
const store = inject('Store') as IStore;
|
|
|
|
const isReadyStockListOpen = ref(false);
|
|
|
|
provide('isReadyStockListOpen', isReadyStockListOpen);
|
|
|
|
return {
|
|
store,
|
|
isReadyStockListOpen,
|
|
locoDataList: inject('locoDataList') as ILocomotive[],
|
|
carDataList: inject('carDataList') as ICarWagon[],
|
|
isTrainPassenger: inject('isTrainPassenger') as boolean,
|
|
totalLength: inject('totalLength') as number,
|
|
totalMass: inject('totalMass') as number,
|
|
maxStockSpeed: inject('maxStockSpeed') as number,
|
|
maxAllowedSpeed: inject('maxAllowedSpeed') as number,
|
|
isLocomotive: inject('isLocomotive') as (vehicle: ILocomotive | ICarWagon) => vehicle is ILocomotive,
|
|
};
|
|
},
|
|
|
|
mounted() {
|
|
document.addEventListener('keydown', (ev) => {
|
|
const keyName = ev.key.toLowerCase();
|
|
if (keyName == 'enter') {
|
|
ev.preventDefault();
|
|
this.addVehicle();
|
|
}
|
|
|
|
if (keyName == 'backspace') {
|
|
if (this.store.stockList.length == 0) return;
|
|
|
|
const lastStock = this.store.stockList.slice(-1)[0];
|
|
|
|
if (lastStock.count > 1) lastStock.count--;
|
|
else this.store.stockList.splice(-1);
|
|
}
|
|
|
|
// if (keyName == 'arrowdown') {
|
|
// const chosenVehicle = this.store.chosenCar || this.store.chosenLoco;
|
|
|
|
// if(!chosenVehicle) return;
|
|
|
|
// ev.preventDefault();
|
|
|
|
// }
|
|
});
|
|
|
|
this.onLocoPowerChange('loco-e');
|
|
this.onCarUseTypeChange('car-passenger');
|
|
},
|
|
|
|
data: () => ({
|
|
icons: {
|
|
add: require('@/assets/add-icon.svg'),
|
|
swap: require('@/assets/swap-icon.svg'),
|
|
},
|
|
locoLabels: [
|
|
{
|
|
id: 'loco-e',
|
|
title: 'ELEKTROWÓZ',
|
|
},
|
|
{
|
|
id: 'loco-s',
|
|
title: 'SPALINOWÓZ',
|
|
},
|
|
{
|
|
id: 'loco-ezt',
|
|
title: 'EZT',
|
|
},
|
|
{
|
|
id: 'loco-szt',
|
|
title: 'SZT',
|
|
},
|
|
],
|
|
|
|
carLabels: [
|
|
{
|
|
id: 'car-passenger',
|
|
title: 'PASAŻERSKI',
|
|
},
|
|
{
|
|
id: 'car-cargo',
|
|
title: 'TOWAROWY',
|
|
},
|
|
],
|
|
}),
|
|
|
|
computed: {
|
|
locoOptions() {
|
|
return this.locoDataList
|
|
.filter((loco) => loco.power == this.store.chosenLocoPower)
|
|
.sort((a, b) => (a.type > b.type ? 1 : -1))
|
|
.sort((a) => (a.supportersOnly ? 1 : -1));
|
|
},
|
|
|
|
carOptions() {
|
|
return this.carDataList
|
|
.filter((car) => car.useType == this.store.chosenCarUseType)
|
|
.sort((a, b) => (a.type > b.type ? 1 : -1))
|
|
.sort((a) => (a.supportersOnly ? 1 : -1));
|
|
},
|
|
},
|
|
|
|
methods: {
|
|
prepareSwapVehicles() {
|
|
this.store.swapVehicles = true;
|
|
},
|
|
|
|
setReadyStockList(bool = false) {
|
|
this.isReadyStockListOpen = bool;
|
|
},
|
|
|
|
onShowSupporterChange() {
|
|
this.store.showSupporter = !this.store.showSupporter;
|
|
|
|
if (this.store.showSupporter) {
|
|
const chosenVehicle = this.store.chosenCar || this.store.chosenLoco;
|
|
|
|
if (!chosenVehicle) return;
|
|
|
|
if (!chosenVehicle.supportersOnly) {
|
|
this.store.chosenCar = null;
|
|
this.store.chosenLoco = null;
|
|
}
|
|
}
|
|
},
|
|
|
|
onLocoPowerChange(inputId: string) {
|
|
this.store.chosenLoco = null;
|
|
this.store.imageLoading = false;
|
|
|
|
this.store.chosenLocoPower = inputId;
|
|
// this.store.chosenStockListIndex = -1;
|
|
|
|
(this.$refs['loco-select'] as HTMLElement).focus();
|
|
},
|
|
|
|
onCarUseTypeChange(inputId: string) {
|
|
this.store.chosenCar = null;
|
|
this.store.imageLoading = false;
|
|
|
|
this.store.chosenCarUseType = inputId;
|
|
// this.store.chosenStockListIndex = -1;
|
|
|
|
if (inputId == 'car-passenger') this.store.chosenCargo = null;
|
|
},
|
|
|
|
onCarTypeChange() {
|
|
this.store.chosenCargo = null;
|
|
this.store.chosenLoco = null;
|
|
// this.store.chosenStockListIndex = -1;
|
|
|
|
this.store.imageLoading = true;
|
|
},
|
|
|
|
onLocoTypeChange() {
|
|
this.store.chosenCargo = null;
|
|
this.store.chosenCar = null;
|
|
// this.store.chosenStockListIndex = -1
|
|
|
|
this.store.imageLoading = true;
|
|
},
|
|
|
|
addVehicle() {
|
|
const vehicle = this.store.chosenCar || this.store.chosenLoco;
|
|
|
|
if (!vehicle) return;
|
|
|
|
const stockObj = {
|
|
type: vehicle.type,
|
|
length: vehicle.length,
|
|
mass: vehicle.mass,
|
|
maxSpeed: vehicle.maxSpeed,
|
|
isLoco: this.isLocomotive(vehicle),
|
|
cargo:
|
|
!this.isLocomotive(vehicle) && vehicle.loadable && this.store.chosenCargo
|
|
? this.store.chosenCargo
|
|
: undefined,
|
|
count: 1,
|
|
imgSrc: vehicle.imageSrc,
|
|
useType: this.isLocomotive(vehicle) ? vehicle.power : vehicle.useType,
|
|
supportersOnly: vehicle.supportersOnly,
|
|
};
|
|
|
|
if (this.store.chosenStockListIndex != -1) {
|
|
let currentStock = this.store.stockList[this.store.chosenStockListIndex];
|
|
|
|
if (this.isLocomotive(vehicle) && currentStock && currentStock.type == vehicle.type) {
|
|
this.store.stockList[this.store.chosenStockListIndex].count++;
|
|
return;
|
|
}
|
|
|
|
if (
|
|
!this.isLocomotive(vehicle) &&
|
|
currentStock &&
|
|
currentStock.type == vehicle.type &&
|
|
currentStock.cargo?.id == this.store.chosenCargo?.id
|
|
) {
|
|
this.store.stockList[this.store.chosenStockListIndex].count++;
|
|
|
|
return;
|
|
}
|
|
|
|
this.store.stockList[this.store.chosenStockListIndex] = stockObj;
|
|
return;
|
|
}
|
|
|
|
const previousStock =
|
|
this.store.stockList.length > 0 ? this.store.stockList[this.store.stockList.length - 1] : null;
|
|
|
|
if (this.isLocomotive(vehicle) && previousStock && previousStock.type == vehicle.type) {
|
|
this.store.stockList[this.store.stockList.length - 1].count++;
|
|
return;
|
|
}
|
|
|
|
if (
|
|
!this.isLocomotive(vehicle) &&
|
|
previousStock &&
|
|
previousStock.type == vehicle.type &&
|
|
previousStock.cargo?.id == this.store.chosenCargo?.id
|
|
) {
|
|
this.store.stockList[this.store.stockList.length - 1].count++;
|
|
|
|
return;
|
|
}
|
|
|
|
if (this.isLocomotive(vehicle) && this.store.stockList.length > 0 && !this.store.stockList[0].isLoco)
|
|
this.store.stockList.unshift(stockObj);
|
|
else this.store.stockList.push(stockObj);
|
|
},
|
|
},
|
|
});
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
@import '../styles/global';
|
|
|
|
.inputs {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
|
|
&_car {
|
|
&.disabled {
|
|
opacity: 0.75;
|
|
pointer-events: none;
|
|
}
|
|
}
|
|
|
|
@media screen and (max-width: 800px) {
|
|
flex-direction: column;
|
|
}
|
|
}
|
|
|
|
.input {
|
|
&_header {
|
|
margin-bottom: 1em;
|
|
}
|
|
|
|
&_radio {
|
|
button {
|
|
padding: 0.25em 0.55em;
|
|
margin-right: 0.5em;
|
|
border: 2px solid white;
|
|
color: white;
|
|
font-size: 1em;
|
|
}
|
|
|
|
button:focus {
|
|
color: $accentColor;
|
|
}
|
|
|
|
button.checked {
|
|
border-color: $accentColor;
|
|
color: $accentColor;
|
|
font-weight: bold;
|
|
}
|
|
}
|
|
|
|
&_checkbox {
|
|
margin: 1em 0;
|
|
|
|
padding: 0 1.5em;
|
|
|
|
button {
|
|
position: relative;
|
|
color: #999;
|
|
|
|
&::before {
|
|
content: '';
|
|
width: 1.5ch;
|
|
height: 1.5ch;
|
|
|
|
display: block;
|
|
|
|
position: absolute;
|
|
bottom: 0.2ch;
|
|
left: -1.5em;
|
|
|
|
background-color: #999;
|
|
}
|
|
|
|
&.checked {
|
|
color: white;
|
|
font-weight: bold;
|
|
|
|
&::before {
|
|
background-color: $accentColor;
|
|
}
|
|
}
|
|
|
|
&:focus {
|
|
outline: 1px solid $accentColor;
|
|
}
|
|
}
|
|
}
|
|
|
|
&_list {
|
|
margin: 0.5em 0;
|
|
|
|
display: flex;
|
|
|
|
select:focus {
|
|
border-color: $accentColor;
|
|
}
|
|
}
|
|
|
|
&_list button {
|
|
margin-left: 0.5em;
|
|
font-size: 0.8em;
|
|
|
|
&:hover img {
|
|
border-color: $accentColor;
|
|
}
|
|
|
|
&:focus img {
|
|
border-color: $accentColor;
|
|
}
|
|
|
|
img {
|
|
border: 2px solid white;
|
|
padding: 0.25em;
|
|
|
|
height: 2.35em;
|
|
|
|
vertical-align: middle;
|
|
}
|
|
}
|
|
|
|
@media screen and (max-width: 800px) {
|
|
justify-content: center;
|
|
|
|
margin: 1em 0;
|
|
|
|
&_header {
|
|
text-align: center;
|
|
}
|
|
|
|
&_container > * {
|
|
display: flex;
|
|
justify-content: center;
|
|
}
|
|
}
|
|
}
|
|
</style>
|