mirror of
https://github.com/Spythere/station-manager-2.0.git
synced 2026-05-03 13:38:13 +00:00
334 lines
9.2 KiB
Vue
334 lines
9.2 KiB
Vue
<template>
|
|
<div class="modal-bg" @click="closeRoutesModal"></div>
|
|
|
|
<div
|
|
v-if="sceneriesStore.currentStation"
|
|
class="modal routes-modal"
|
|
@keydown.esc="closeRoutesModal"
|
|
tabindex="0"
|
|
ref="modal"
|
|
>
|
|
<div class="modal-content">
|
|
<div class="modal-wrapper">
|
|
<h1 class="modal-header">
|
|
Szlaki na scenerii {{ sceneriesStore.currentStation.name }}
|
|
<button class="modal-exit" @click="closeRoutesModal">
|
|
<LucideX :size="20" />
|
|
</button>
|
|
</h1>
|
|
|
|
<ul class="route-list">
|
|
<li class="route" v-for="(route, i) in currentRoutes" :key="i">
|
|
<form action="javascript:void(0);">
|
|
<div style="display: flex; justify-content: space-between; align-items: center; gap: 1em">
|
|
<span> Szlak: <input type="text" v-model="route.routeName" /> </span>
|
|
|
|
<button class="route-delete-btn" @click="removeRoute(i)">
|
|
<LucideTrash />
|
|
</button>
|
|
</div>
|
|
|
|
<div>
|
|
<label :for="`${route.routeName}-internal`" style="display: inline-block">
|
|
<input
|
|
type="checkbox"
|
|
:name="`${route.routeName}-internal`"
|
|
:id="`${route.routeName}-internal`"
|
|
v-model="route.isInternal"
|
|
/>
|
|
WEWNĘTRZNY
|
|
</label>
|
|
|
|
<label :for="`${route.routeName}-hidden`" style="display: inline-block">
|
|
<input
|
|
type="checkbox"
|
|
:name="`${route.routeName}-hidden`"
|
|
:id="`${route.routeName}-hidden`"
|
|
v-model="route.hidden"
|
|
/>
|
|
UKRYTY
|
|
</label>
|
|
</div>
|
|
|
|
<div>
|
|
<b>Liczba torów:</b>
|
|
<label class="radio-choice">
|
|
<input
|
|
type="radio"
|
|
:name="`${route.routeName}-tracks`"
|
|
:value="1"
|
|
:checked="route.routeTracks == 1"
|
|
v-model="route.routeTracks"
|
|
/>
|
|
<span>1</span>
|
|
</label>
|
|
|
|
<label class="radio-choice">
|
|
<input
|
|
type="radio"
|
|
:name="`${route.routeName}-tracks`"
|
|
:value="2"
|
|
:checked="route.routeTracks == 2"
|
|
v-model="route.routeTracks"
|
|
/>
|
|
<span>2</span>
|
|
</label>
|
|
</div>
|
|
<div>
|
|
<b>Elektryfikacja:</b>
|
|
|
|
<label class="radio-choice">
|
|
<input
|
|
type="radio"
|
|
:name="`${route.routeName}-electr`"
|
|
:value="true"
|
|
:checked="route.isElectric"
|
|
v-model="route.isElectric"
|
|
/>
|
|
<span>Tak</span>
|
|
</label>
|
|
|
|
<label class="radio-choice">
|
|
<input
|
|
type="radio"
|
|
:name="`${route.routeName}-electr`"
|
|
:value="false"
|
|
:checked="!route.isElectric"
|
|
v-model="route.isElectric"
|
|
/>
|
|
<span>Nie</span>
|
|
</label>
|
|
</div>
|
|
<div>
|
|
<b>Typ blokady:</b>
|
|
|
|
<label class="radio-choice">
|
|
<input
|
|
type="radio"
|
|
:name="`${route.routeName}-block`"
|
|
:id="`${route.routeName}-PBL`"
|
|
:value="false"
|
|
:checked="!route.isRouteSBL"
|
|
v-model="route.isRouteSBL"
|
|
/><span>PBL</span>
|
|
</label>
|
|
|
|
<label class="radio-choice">
|
|
<input
|
|
type="radio"
|
|
:name="`${route.routeName}-block`"
|
|
:id="`${route.routeName}-SBL`"
|
|
:value="true"
|
|
:checked="route.isRouteSBL"
|
|
v-model="route.isRouteSBL"
|
|
/><span>SBL</span>
|
|
</label>
|
|
</div>
|
|
|
|
<div v-if="route.routeTracks == 1">Prędkość: <input type="number" v-model="route.routeSpeed" /> km/h</div>
|
|
|
|
<div v-if="route.routeTracks == 2">
|
|
Prędkość (wjazd na sc.): <input type="number" v-model="route.routeSpeed" /> km/h
|
|
</div>
|
|
<div v-if="route.routeTracks == 2">
|
|
Prędkość (wyjazd ze sc.): <input type="number" v-model="route.routeSpeedExit" /> km/h
|
|
</div>
|
|
|
|
<div>Długość: <input type="number" v-model="route.routeLength" /> m</div>
|
|
<div>Linia kolejowa: <input type="number" v-model="route.realLineNo" /></div>
|
|
</form>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
|
|
<div class="routes-actions">
|
|
<button @click="saveRoutes">Zapisz</button>
|
|
<button @click="addNewRoute">Dodaj szlak</button>
|
|
<button @click="closeRoutesModal">Zamknij</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script lang="ts">
|
|
import { Ref, defineComponent, ref } from 'vue';
|
|
import changeMixin from '../mixins/changeMixin';
|
|
import { SceneryRoutesInfo } from '../types/sceneries.types';
|
|
import { useSceneriesStore } from '../stores/sceneries.store';
|
|
import { LucideTrash, LucideX } from 'lucide-vue-next';
|
|
|
|
export default defineComponent({
|
|
components: { LucideX, LucideTrash },
|
|
|
|
setup() {
|
|
const sceneriesStore = useSceneriesStore();
|
|
const currentRoutes: Ref<SceneryRoutesInfo[]> = ref([]);
|
|
const routeBackup: Ref<SceneryRoutesInfo[]> = ref([]);
|
|
|
|
return {
|
|
sceneriesStore,
|
|
routeBackup,
|
|
currentRoutes,
|
|
};
|
|
},
|
|
|
|
mixins: [changeMixin],
|
|
|
|
mounted() {
|
|
if (this.sceneriesStore.currentStation) {
|
|
// unrefed copy of routesInfo object
|
|
this.currentRoutes = JSON.parse(JSON.stringify(this.sceneriesStore.currentStation.routesInfo));
|
|
this.routeBackup = [...this.sceneriesStore.currentStation.routesInfo];
|
|
|
|
(this.$refs['modal'] as HTMLElement).focus();
|
|
}
|
|
},
|
|
|
|
methods: {
|
|
closeRoutesModal() {
|
|
this.sceneriesStore.currentStation = null;
|
|
},
|
|
|
|
addNewRoute() {
|
|
this.currentRoutes.push({
|
|
routeName: '-',
|
|
isElectric: true,
|
|
isInternal: false,
|
|
isRouteSBL: false,
|
|
routeLength: 0,
|
|
routeSpeed: 0,
|
|
routeSpeedExit: 0,
|
|
routeTracks: 1,
|
|
});
|
|
this.saveRoutes();
|
|
},
|
|
|
|
removeRoute(index: number) {
|
|
this.currentRoutes = this.currentRoutes.filter((_, i) => i !== index);
|
|
this.saveRoutes();
|
|
},
|
|
|
|
parseRoutes() {
|
|
const routeString = this.sceneriesStore.currentStation?.routesInfo
|
|
.map(
|
|
(route) =>
|
|
`${route.isInternal ? '!' : ''}${route.routeName.trim()}_${route.routeTracks}${
|
|
route.isElectric ? 'E' : 'N'
|
|
}${route.isRouteSBL ? 'S' : 'P'}:${route.routeSpeed || 0}:${route.routeLength || 0}`,
|
|
)
|
|
.join(';');
|
|
|
|
return routeString;
|
|
},
|
|
|
|
saveRoutes() {
|
|
const index = this.sceneriesStore.stationList.findIndex(
|
|
(station) => station.name === this.sceneriesStore.currentStation?.name,
|
|
);
|
|
|
|
if (index == -1) return;
|
|
|
|
this.addChange(this.sceneriesStore.currentStation!, 'routesInfo', this.routeBackup, this.currentRoutes);
|
|
this.sceneriesStore.stationList[index]['routesInfo'] = this.currentRoutes;
|
|
},
|
|
},
|
|
});
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
@use '../styles/modal';
|
|
|
|
.routes-modal input {
|
|
display: inline;
|
|
margin: 0.25em 0;
|
|
|
|
color: black;
|
|
font-size: 1em;
|
|
|
|
max-width: 120px;
|
|
}
|
|
|
|
label.radio-choice {
|
|
display: inline-block;
|
|
position: relative;
|
|
|
|
background-color: #333;
|
|
margin: 0.25em;
|
|
cursor: pointer;
|
|
|
|
input {
|
|
position: absolute;
|
|
opacity: 0;
|
|
cursor: pointer;
|
|
}
|
|
|
|
span {
|
|
display: flex;
|
|
padding: 0.25em 0.75em;
|
|
}
|
|
|
|
input:checked + span {
|
|
color: gold;
|
|
font-weight: bold;
|
|
}
|
|
|
|
input:focus-visible + span {
|
|
outline: 1px solid white;
|
|
}
|
|
}
|
|
|
|
.modal-content {
|
|
display: grid;
|
|
grid-template-rows: 1fr auto;
|
|
|
|
height: 100%;
|
|
}
|
|
|
|
ul.route-list {
|
|
list-style: none;
|
|
padding: 0 1em;
|
|
margin: 0;
|
|
overflow: auto;
|
|
}
|
|
|
|
ul.route-list li {
|
|
padding: 0.65em;
|
|
margin: 0.5em 0;
|
|
|
|
position: relative;
|
|
|
|
background-color: #222;
|
|
}
|
|
|
|
ul.route-list li > form {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 0.25em;
|
|
}
|
|
|
|
.routes-actions {
|
|
display: flex;
|
|
justify-content: center;
|
|
flex-wrap: wrap;
|
|
gap: 0.5em;
|
|
width: 100%;
|
|
|
|
padding: 0.5em 0;
|
|
text-align: center;
|
|
}
|
|
|
|
.routes-actions button {
|
|
font-size: 1.2em;
|
|
margin: 0;
|
|
}
|
|
|
|
.route-delete-btn {
|
|
background-color: #444;
|
|
border-radius: 0.5em;
|
|
|
|
&:hover {
|
|
background-color: #555;
|
|
}
|
|
}
|
|
</style>
|