mirror of
https://github.com/Spythere/stacjownik.git
synced 2026-05-02 21:08:12 +00:00
refactor(driver): moved driver propositions card to separate component
This commit is contained in:
@@ -0,0 +1,268 @@
|
|||||||
|
<template>
|
||||||
|
<div class="driver-propositions">
|
||||||
|
<h3 style="margin-bottom: 0.5em">{{ t('trains.number-propositions-header') }}</h3>
|
||||||
|
|
||||||
|
<div class="categories-select">
|
||||||
|
<button
|
||||||
|
v-for="(category, i) in availableCategories"
|
||||||
|
class="btn btn--option btn--action"
|
||||||
|
@click="selectCategory(i)"
|
||||||
|
:class="{ checked: i == chosenCategoryIndex }"
|
||||||
|
>
|
||||||
|
{{ category }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="numberPropositions.length > 0" class="propositions-numbers">
|
||||||
|
<div v-if="chosenCategory">
|
||||||
|
<b>{{ chosenCategory }} </b> -
|
||||||
|
{{ t(`categories.${chosenCategory.slice(0, 2)}`) }}
|
||||||
|
({{ t(`categories.${chosenCategory.slice(2)}`) }})
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="chosenCategoryRules">
|
||||||
|
<span v-if="chosenCategoryRules[0]"
|
||||||
|
>{{ t('trains.number-propositions-third-number') }}
|
||||||
|
<b class="text--primary">{{ chosenCategoryRules[0] }}</b> •
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<span
|
||||||
|
>{{
|
||||||
|
t('trains.number-propositions-last-nums', {
|
||||||
|
count: chosenCategoryRules[1].length
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
<b class="text--primary">{{ chosenCategoryRules[1] }}</b> -
|
||||||
|
<b class="text--primary">{{ chosenCategoryRules[2] }}</b></span
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="margin-top: 0.5em">
|
||||||
|
<b>{{ t('trains.number-propositions-title') }} </b>
|
||||||
|
<i>{{ numberPropositions.join(', ') }}</i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="no-propositions" v-else>{{ t('trains.number-propositions-empty') }}</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, computed, PropType, watch, onMounted } from 'vue';
|
||||||
|
import { useI18n } from 'vue-i18n';
|
||||||
|
import { Train } from '../../typings/common';
|
||||||
|
import rulesJSON from '../../data/trainNumberRules.json';
|
||||||
|
import { useApiStore } from '../../store/apiStore';
|
||||||
|
|
||||||
|
const { t } = useI18n();
|
||||||
|
const apiStore = useApiStore();
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
chosenTrain: {
|
||||||
|
type: Object as PropType<Train>,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const emits = defineEmits(['selectCategory']);
|
||||||
|
|
||||||
|
const chosenCategoryIndex = ref(0);
|
||||||
|
|
||||||
|
const numberPropositions = ref<string[]>([]);
|
||||||
|
const chosenCategoryRules = ref<any[]>([]);
|
||||||
|
|
||||||
|
watch(
|
||||||
|
computed(() => props.chosenTrain.trainNo),
|
||||||
|
() => {
|
||||||
|
chosenCategoryIndex.value = 0;
|
||||||
|
generateNumberPropositions();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
generateNumberPropositions();
|
||||||
|
});
|
||||||
|
|
||||||
|
function generateNumberPropositions() {
|
||||||
|
const categoryCode = chosenCategory.value?.slice(0, 2);
|
||||||
|
const trainNoStr = props.chosenTrain.trainNo.toString();
|
||||||
|
|
||||||
|
// Get category rules
|
||||||
|
const rules = categoryCode
|
||||||
|
? ((rulesJSON.categoriesRules as any)[categoryCode] as any[])
|
||||||
|
: undefined;
|
||||||
|
|
||||||
|
if (!categoryCode || !rules) {
|
||||||
|
numberPropositions.value.length = 0;
|
||||||
|
chosenCategoryRules.value.length = 0;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const [thirdNumber, minRange, maxRange] = rules;
|
||||||
|
|
||||||
|
const propositionsArr: string[] = [];
|
||||||
|
|
||||||
|
for (let i = 0; i < 5; i++) {
|
||||||
|
let generatedNumStr = '';
|
||||||
|
|
||||||
|
generatedNumStr += trainNoStr[0] ?? Math.floor(Math.random() * 10);
|
||||||
|
generatedNumStr += trainNoStr[1] ?? Math.floor(Math.random() * 10);
|
||||||
|
|
||||||
|
// Third number
|
||||||
|
generatedNumStr += thirdNumber ?? '';
|
||||||
|
|
||||||
|
// Remaining numbers
|
||||||
|
const rangeNums = minRange?.length ?? 3;
|
||||||
|
|
||||||
|
const randRange = Math.floor(
|
||||||
|
Math.random() * (Number(maxRange) - Number(minRange)) + Number(minRange)
|
||||||
|
).toString();
|
||||||
|
|
||||||
|
const leadingZeros = new Array(Math.abs(randRange.toString().length - rangeNums))
|
||||||
|
.fill('0')
|
||||||
|
.join('');
|
||||||
|
|
||||||
|
generatedNumStr += `${leadingZeros}${randRange}`;
|
||||||
|
|
||||||
|
const isNumberTaken =
|
||||||
|
apiStore.activeData?.trains?.some((t) => t.trainNo.toString() == generatedNumStr) ?? false;
|
||||||
|
|
||||||
|
if (!isNumberTaken) {
|
||||||
|
propositionsArr.push(generatedNumStr);
|
||||||
|
} else {
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Number(randRange) > Number(maxRange)) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
numberPropositions.value = propositionsArr;
|
||||||
|
chosenCategoryRules.value = rules;
|
||||||
|
}
|
||||||
|
|
||||||
|
const chosenCategory = computed(() => {
|
||||||
|
return availableCategories.value[chosenCategoryIndex.value];
|
||||||
|
});
|
||||||
|
|
||||||
|
const availableCategories = computed(() => {
|
||||||
|
const stockList = props.chosenTrain.stockList;
|
||||||
|
const headVehicle = stockList[0]?.split('-')[0] ?? '';
|
||||||
|
|
||||||
|
let availableCategories: string[] = [];
|
||||||
|
let categoryTraction = 'E';
|
||||||
|
|
||||||
|
let vehicleTypesSet = new Set<string>();
|
||||||
|
let wagonsNamesSet = new Set<string>();
|
||||||
|
let cargoNamesSet = new Set<string>();
|
||||||
|
|
||||||
|
for (const stockName of stockList) {
|
||||||
|
const [vehicleName, ...cargoList] = stockName.split(':');
|
||||||
|
|
||||||
|
const vehicleData = apiStore.vehiclesData?.vehicles.find((v) => v.name == vehicleName);
|
||||||
|
|
||||||
|
if (!vehicleData) continue;
|
||||||
|
|
||||||
|
vehicleTypesSet.add(vehicleData.type);
|
||||||
|
|
||||||
|
if (vehicleData.type.startsWith('wagon-')) wagonsNamesSet.add(vehicleData.name.split('_')[0]);
|
||||||
|
|
||||||
|
if (cargoList !== undefined) cargoList.forEach((c) => cargoNamesSet.add(c.split('_')[0]));
|
||||||
|
}
|
||||||
|
|
||||||
|
let vehicleTypesArr = [...vehicleTypesSet];
|
||||||
|
let wagonsNamesArr = [...wagonsNamesSet];
|
||||||
|
|
||||||
|
// Traction
|
||||||
|
if (vehicleTypesArr[0] == 'loco-electric') categoryTraction = 'E';
|
||||||
|
else if (vehicleTypesArr[0] == 'loco-diesel') categoryTraction = 'S';
|
||||||
|
else if (vehicleTypesArr[0] == 'unit-electric') categoryTraction = 'J';
|
||||||
|
else categoryTraction = 'M';
|
||||||
|
|
||||||
|
// EMU / DMU - M*, R*, P*
|
||||||
|
if (vehicleTypesArr.length == 1 && (categoryTraction == 'J' || categoryTraction == 'M')) {
|
||||||
|
availableCategories.push('MO', 'MP', 'MM', 'RO', 'RP', 'RA', 'RM', 'PW');
|
||||||
|
}
|
||||||
|
// Only locos (up to 3) - LT, LP, LS
|
||||||
|
else if (stockList.length <= 3 && vehicleTypesArr.every((v) => v.startsWith('loco-'))) {
|
||||||
|
if (/^(EU|ET|201E|4E|SU|ST|M62|CTLR4C)/.test(headVehicle)) availableCategories.push('LT');
|
||||||
|
if (/^(EU|EP|SU|SP)/.test(headVehicle)) availableCategories.push('LP');
|
||||||
|
if (/^(SM)/.test(headVehicle)) availableCategories.push('LS');
|
||||||
|
}
|
||||||
|
// Only locos (more than 3) - TH
|
||||||
|
else if (stockList.length > 3 && vehicleTypesArr.every((v) => v.startsWith('loco-'))) {
|
||||||
|
availableCategories.push('TH');
|
||||||
|
}
|
||||||
|
// Loco(s) + passenger only wagons - M*, R*, E*, P*
|
||||||
|
else if (vehicleTypesArr.every((v) => v.startsWith('loco-') || v == 'wagon-passenger')) {
|
||||||
|
availableCategories.push('EI', 'EC', 'EN', 'MO', 'MP', 'MM', 'RO', 'RP', 'RA', 'RM', 'PW');
|
||||||
|
}
|
||||||
|
// Loco(s) + cargo only / mixed wagons - T*, Z*
|
||||||
|
else {
|
||||||
|
if (wagonsNamesArr.every((v) => /^(627Z|412Z)/.test(v)))
|
||||||
|
availableCategories.push('TC', 'TD', 'TS');
|
||||||
|
else if (stockList.slice(1).every((v) => /PKPE/.test(v))) {
|
||||||
|
availableCategories.push('ZU', 'ZN');
|
||||||
|
} else if (wagonsNamesArr.length < 3 || cargoNamesSet.size < 3) {
|
||||||
|
availableCategories.push('TM', 'TG', 'TS', 'TK');
|
||||||
|
} else {
|
||||||
|
availableCategories.push('TN', 'TR', 'TS', 'TK');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return availableCategories.map((c) => `${c}${categoryTraction}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
function selectCategory(i: number) {
|
||||||
|
chosenCategoryIndex.value = i;
|
||||||
|
generateNumberPropositions();
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@use '../../styles/responsive';
|
||||||
|
|
||||||
|
.driver-propositions {
|
||||||
|
margin-bottom: 1em;
|
||||||
|
padding: 0.5em;
|
||||||
|
background-color: #111;
|
||||||
|
}
|
||||||
|
|
||||||
|
.categories-select {
|
||||||
|
display: inline-flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 0.5em;
|
||||||
|
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
bottom: calc(-0.5em);
|
||||||
|
left: 0;
|
||||||
|
|
||||||
|
width: 100%;
|
||||||
|
height: 2px;
|
||||||
|
background-color: #aaa;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.propositions-numbers {
|
||||||
|
margin-top: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-propositions {
|
||||||
|
margin-top: 1em;
|
||||||
|
color: #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
@include responsive.smallScreen {
|
||||||
|
.driver-propositions {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.categories-select {
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -14,53 +14,8 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Proposed numbers container -->
|
<!-- Proposed numbers container -->
|
||||||
<transition name="view-anim" class="propositions-container">
|
<transition name="view-anim">
|
||||||
<div v-if="arePropositionsVisible">
|
<DriverPropositions :chosenTrain="chosenTrain" v-if="arePropositionsVisible" />
|
||||||
<h3 style="margin-bottom: 0.5em">{{ i18n.t('trains.number-propositions-header') }}</h3>
|
|
||||||
|
|
||||||
<div class="categories-select">
|
|
||||||
<button
|
|
||||||
v-for="(category, i) in availableCategories"
|
|
||||||
class="btn btn--option btn--action"
|
|
||||||
@click="selectCategory(i)"
|
|
||||||
:class="{ checked: i == chosenCategoryIndex }"
|
|
||||||
>
|
|
||||||
{{ category }}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div v-if="numberPropositions.length > 0" class="propositions-numbers">
|
|
||||||
<div v-if="chosenCategory">
|
|
||||||
<b>{{ chosenCategory }} </b> -
|
|
||||||
{{ i18n.t(`categories.${chosenCategory.slice(0, 2)}`) }}
|
|
||||||
({{ i18n.t(`categories.${chosenCategory.slice(2)}`) }})
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div v-if="chosenCategoryRules">
|
|
||||||
<span v-if="chosenCategoryRules[0]"
|
|
||||||
>{{ i18n.t('trains.number-propositions-third-number') }}
|
|
||||||
<b class="text--primary">{{ chosenCategoryRules[0] }}</b> •
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<span
|
|
||||||
>{{
|
|
||||||
i18n.t('trains.number-propositions-last-nums', {
|
|
||||||
count: chosenCategoryRules[1].length
|
|
||||||
})
|
|
||||||
}}
|
|
||||||
<b class="text--primary">{{ chosenCategoryRules[1] }}</b> -
|
|
||||||
<b class="text--primary">{{ chosenCategoryRules[2] }}</b></span
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div style="margin-top: 0.5em">
|
|
||||||
<b>{{ i18n.t('trains.number-propositions-title') }} </b>
|
|
||||||
<i>{{ numberPropositions.join(', ') }}</i>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="no-propositions" v-else>{{ i18n.t('trains.number-propositions-empty') }}</div>
|
|
||||||
</div>
|
|
||||||
</transition>
|
</transition>
|
||||||
|
|
||||||
<StockList :trainStockList="chosenTrain.stockList" :key="chosenTrain.id" :showPreviews="true" />
|
<StockList :trainStockList="chosenTrain.stockList" :key="chosenTrain.id" :showPreviews="true" />
|
||||||
@@ -72,25 +27,15 @@
|
|||||||
import { PropType, ref } from 'vue';
|
import { PropType, ref } from 'vue';
|
||||||
import { Train } from '../../typings/common';
|
import { Train } from '../../typings/common';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { useApiStore } from '../../store/apiStore';
|
|
||||||
|
|
||||||
import StockList from '../Global/StockList.vue';
|
import StockList from '../Global/StockList.vue';
|
||||||
import TrainSchedule from '../TrainsView/TrainSchedule.vue';
|
import TrainSchedule from '../TrainsView/TrainSchedule.vue';
|
||||||
import TrainInfo from '../TrainsView/TrainInfo.vue';
|
import TrainInfo from '../TrainsView/TrainInfo.vue';
|
||||||
|
import DriverPropositions from './DriverPropositions.vue';
|
||||||
import rulesJSON from '../../data/trainNumberRules.json';
|
|
||||||
import { computed } from 'vue';
|
|
||||||
import { watch } from 'vue';
|
|
||||||
|
|
||||||
const apiStore = useApiStore();
|
|
||||||
|
|
||||||
const i18n = useI18n();
|
const i18n = useI18n();
|
||||||
|
|
||||||
const arePropositionsVisible = ref(false);
|
const arePropositionsVisible = ref(false);
|
||||||
const chosenCategoryIndex = ref(0);
|
|
||||||
|
|
||||||
const numberPropositions = ref<string[]>([]);
|
|
||||||
const chosenCategoryRules = ref<any[]>([]);
|
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
chosenTrain: {
|
chosenTrain: {
|
||||||
@@ -119,158 +64,10 @@ function copyStockToClipboard() {
|
|||||||
|
|
||||||
function toggleNumberPropositions() {
|
function toggleNumberPropositions() {
|
||||||
arePropositionsVisible.value = !arePropositionsVisible.value;
|
arePropositionsVisible.value = !arePropositionsVisible.value;
|
||||||
|
|
||||||
if (arePropositionsVisible.value) generateNumberPropositions();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectCategory(i: number) {
|
|
||||||
chosenCategoryIndex.value = i;
|
|
||||||
|
|
||||||
generateNumberPropositions();
|
|
||||||
}
|
|
||||||
|
|
||||||
function generateNumberPropositions() {
|
|
||||||
const categoryCode = chosenCategory.value?.slice(0, 2);
|
|
||||||
const trainNoStr = props.chosenTrain.trainNo.toString();
|
|
||||||
|
|
||||||
// Get category rules
|
|
||||||
const rules = categoryCode
|
|
||||||
? ((rulesJSON.categoriesRules as any)[categoryCode] as any[])
|
|
||||||
: undefined;
|
|
||||||
|
|
||||||
if (!categoryCode || !rules) {
|
|
||||||
numberPropositions.value.length = 0;
|
|
||||||
chosenCategoryRules.value.length = 0;
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const [thirdNumber, minRange, maxRange] = rules;
|
|
||||||
|
|
||||||
const propositionsArr: string[] = [];
|
|
||||||
|
|
||||||
for (let i = 0; i < 5; i++) {
|
|
||||||
let generatedNumStr = '';
|
|
||||||
|
|
||||||
generatedNumStr += trainNoStr[0] ?? Math.floor(Math.random() * 10);
|
|
||||||
generatedNumStr += trainNoStr[1] ?? Math.floor(Math.random() * 10);
|
|
||||||
|
|
||||||
// Third number
|
|
||||||
generatedNumStr += thirdNumber ?? '';
|
|
||||||
|
|
||||||
// Remaining numbers
|
|
||||||
const rangeNums = minRange?.length ?? 3;
|
|
||||||
|
|
||||||
const randRange = Math.floor(
|
|
||||||
Math.random() * (Number(maxRange) - Number(minRange)) + Number(minRange)
|
|
||||||
).toString();
|
|
||||||
|
|
||||||
const leadingZeros = new Array(Math.abs(randRange.toString().length - rangeNums))
|
|
||||||
.fill('0')
|
|
||||||
.join('');
|
|
||||||
|
|
||||||
generatedNumStr += `${leadingZeros}${randRange}`;
|
|
||||||
|
|
||||||
const isNumberTaken =
|
|
||||||
apiStore.activeData?.trains?.some((t) => t.trainNo.toString() == generatedNumStr) ?? false;
|
|
||||||
|
|
||||||
if (!isNumberTaken) {
|
|
||||||
propositionsArr.push(generatedNumStr);
|
|
||||||
} else {
|
|
||||||
i--;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Number(randRange) > Number(maxRange)) break;
|
|
||||||
}
|
|
||||||
|
|
||||||
numberPropositions.value = propositionsArr;
|
|
||||||
chosenCategoryRules.value = rules;
|
|
||||||
}
|
|
||||||
|
|
||||||
const chosenCategory = computed(() => {
|
|
||||||
return availableCategories.value[chosenCategoryIndex.value];
|
|
||||||
});
|
|
||||||
|
|
||||||
const availableCategories = computed(() => {
|
|
||||||
const stockList = props.chosenTrain.stockList;
|
|
||||||
const headVehicle = stockList[0]?.split('-')[0] ?? '';
|
|
||||||
|
|
||||||
let availableCategories: string[] = [];
|
|
||||||
let categoryTraction = 'E';
|
|
||||||
|
|
||||||
let vehicleTypesSet = new Set<string>();
|
|
||||||
let wagonsNamesSet = new Set<string>();
|
|
||||||
let cargoNamesSet = new Set<string>();
|
|
||||||
|
|
||||||
for (const stockName of stockList) {
|
|
||||||
const [vehicleName, ...cargoList] = stockName.split(':');
|
|
||||||
|
|
||||||
const vehicleData = apiStore.vehiclesData?.vehicles.find((v) => v.name == vehicleName);
|
|
||||||
|
|
||||||
if (!vehicleData) continue;
|
|
||||||
|
|
||||||
vehicleTypesSet.add(vehicleData.type);
|
|
||||||
|
|
||||||
if (vehicleData.type.startsWith('wagon-')) wagonsNamesSet.add(vehicleData.name.split('_')[0]);
|
|
||||||
|
|
||||||
if (cargoList !== undefined) cargoList.forEach((c) => cargoNamesSet.add(c.split('_')[0]));
|
|
||||||
}
|
|
||||||
|
|
||||||
let vehicleTypesArr = [...vehicleTypesSet];
|
|
||||||
let wagonsNamesArr = [...wagonsNamesSet];
|
|
||||||
|
|
||||||
// Traction
|
|
||||||
if (vehicleTypesArr[0] == 'loco-electric') categoryTraction = 'E';
|
|
||||||
else if (vehicleTypesArr[0] == 'loco-diesel') categoryTraction = 'S';
|
|
||||||
else if (vehicleTypesArr[0] == 'unit-electric') categoryTraction = 'J';
|
|
||||||
else categoryTraction = 'M';
|
|
||||||
|
|
||||||
// EMU / DMU - M*, R*, P*
|
|
||||||
if (vehicleTypesArr.length == 1 && (categoryTraction == 'J' || categoryTraction == 'M')) {
|
|
||||||
availableCategories.push('MO', 'MP', 'MM', 'RO', 'RP', 'RA', 'RM', 'PW');
|
|
||||||
}
|
|
||||||
// Only locos (up to 3) - LT, LP, LS
|
|
||||||
else if (stockList.length <= 3 && vehicleTypesArr.every((v) => v.startsWith('loco-'))) {
|
|
||||||
if (/^(EU|ET|201E|4E|SU|ST|M62|CTLR4C)/.test(headVehicle)) availableCategories.push('LT');
|
|
||||||
if (/^(EU|EP|SU|SP)/.test(headVehicle)) availableCategories.push('LP');
|
|
||||||
if (/^(SM)/.test(headVehicle)) availableCategories.push('LS');
|
|
||||||
}
|
|
||||||
// Only locos (more than 3) - TH
|
|
||||||
else if (stockList.length > 3 && vehicleTypesArr.every((v) => v.startsWith('loco-'))) {
|
|
||||||
availableCategories.push('TH');
|
|
||||||
}
|
|
||||||
// Loco(s) + passenger only wagons - M*, R*, E*, P*
|
|
||||||
else if (vehicleTypesArr.every((v) => v.startsWith('loco-') || v == 'wagon-passenger')) {
|
|
||||||
availableCategories.push('EI', 'EC', 'EN', 'MO', 'MP', 'MM', 'RO', 'RP', 'RA', 'RM', 'PW');
|
|
||||||
}
|
|
||||||
// Loco(s) + cargo only / mixed wagons - T*, Z*
|
|
||||||
else {
|
|
||||||
if (wagonsNamesArr.every((v) => /^(627Z|412Z)/.test(v)))
|
|
||||||
availableCategories.push('TC', 'TD', 'TS');
|
|
||||||
else if (stockList.slice(1).every((v) => /PKPE/.test(v))) {
|
|
||||||
availableCategories.push('ZU', 'ZN');
|
|
||||||
} else if (wagonsNamesArr.length < 3 || cargoNamesSet.size < 3) {
|
|
||||||
availableCategories.push('TM', 'TG', 'TS', 'TK');
|
|
||||||
} else {
|
|
||||||
availableCategories.push('TN', 'TR', 'TS', 'TK');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return availableCategories.map((c) => `${c}${categoryTraction}`);
|
|
||||||
});
|
|
||||||
|
|
||||||
watch(
|
|
||||||
computed(() => `${props.chosenTrain.trainNo}`),
|
|
||||||
() => {
|
|
||||||
chosenCategoryIndex.value = 0;
|
|
||||||
generateNumberPropositions();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@use '../../styles/responsive';
|
|
||||||
|
|
||||||
.driver-train-card {
|
.driver-train-card {
|
||||||
padding: 1em;
|
padding: 1em;
|
||||||
background-color: var(--clr-view-bg);
|
background-color: var(--clr-view-bg);
|
||||||
@@ -281,48 +78,4 @@ watch(
|
|||||||
display: flex;
|
display: flex;
|
||||||
gap: 0.5em;
|
gap: 0.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.propositions-container {
|
|
||||||
margin-bottom: 1em;
|
|
||||||
padding: 0.5em;
|
|
||||||
background-color: #111;
|
|
||||||
}
|
|
||||||
|
|
||||||
.categories-select {
|
|
||||||
display: inline-flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
gap: 0.5em;
|
|
||||||
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
&::after {
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
bottom: calc(-0.5em);
|
|
||||||
left: 0;
|
|
||||||
|
|
||||||
width: 100%;
|
|
||||||
height: 2px;
|
|
||||||
background-color: #aaa;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.propositions-numbers {
|
|
||||||
margin-top: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.no-propositions {
|
|
||||||
margin-top: 1em;
|
|
||||||
color: #ccc;
|
|
||||||
}
|
|
||||||
|
|
||||||
@include responsive.smallScreen {
|
|
||||||
.propositions-container {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.categories-select {
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user