From db720d11f5fe50bb624f6c84643896af135953cc Mon Sep 17 00:00:00 2001 From: Spythere Date: Wed, 22 Apr 2026 02:12:44 +0200 Subject: [PATCH] refactor(driver): moved driver propositions card to separate component --- .../DriverView/DriverPropositions.vue | 268 ++++++++++++++++++ src/components/DriverView/DriverTrainCard.vue | 253 +---------------- 2 files changed, 271 insertions(+), 250 deletions(-) create mode 100644 src/components/DriverView/DriverPropositions.vue diff --git a/src/components/DriverView/DriverPropositions.vue b/src/components/DriverView/DriverPropositions.vue new file mode 100644 index 0000000..c59934b --- /dev/null +++ b/src/components/DriverView/DriverPropositions.vue @@ -0,0 +1,268 @@ + + + + + diff --git a/src/components/DriverView/DriverTrainCard.vue b/src/components/DriverView/DriverTrainCard.vue index bdfd1b2..7b13e95 100644 --- a/src/components/DriverView/DriverTrainCard.vue +++ b/src/components/DriverView/DriverTrainCard.vue @@ -14,53 +14,8 @@ - -
-

{{ i18n.t('trains.number-propositions-header') }}

- -
- -
- -
-
- {{ chosenCategory }} - - {{ i18n.t(`categories.${chosenCategory.slice(0, 2)}`) }} - ({{ i18n.t(`categories.${chosenCategory.slice(2)}`) }}) -
- -
- {{ i18n.t('trains.number-propositions-third-number') }} - {{ chosenCategoryRules[0] }} • - - - {{ - i18n.t('trains.number-propositions-last-nums', { - count: chosenCategoryRules[1].length - }) - }} - {{ chosenCategoryRules[1] }} - - {{ chosenCategoryRules[2] }} -
- -
- {{ i18n.t('trains.number-propositions-title') }}  - {{ numberPropositions.join(', ') }} -
-
- -
{{ i18n.t('trains.number-propositions-empty') }}
-
+ + @@ -72,25 +27,15 @@ import { PropType, ref } from 'vue'; import { Train } from '../../typings/common'; import { useI18n } from 'vue-i18n'; -import { useApiStore } from '../../store/apiStore'; import StockList from '../Global/StockList.vue'; import TrainSchedule from '../TrainsView/TrainSchedule.vue'; import TrainInfo from '../TrainsView/TrainInfo.vue'; - -import rulesJSON from '../../data/trainNumberRules.json'; -import { computed } from 'vue'; -import { watch } from 'vue'; - -const apiStore = useApiStore(); +import DriverPropositions from './DriverPropositions.vue'; const i18n = useI18n(); const arePropositionsVisible = ref(false); -const chosenCategoryIndex = ref(0); - -const numberPropositions = ref([]); -const chosenCategoryRules = ref([]); const props = defineProps({ chosenTrain: { @@ -119,158 +64,10 @@ function copyStockToClipboard() { function toggleNumberPropositions() { 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(); - let wagonsNamesSet = new Set(); - let cargoNamesSet = new Set(); - - 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(); - } -);