mirror of
https://github.com/Spythere/station-manager-2.0.git
synced 2026-05-03 05:28:13 +00:00
refactor: modal for updating vehicles; global & modal styles changes
This commit is contained in:
@@ -1,13 +1,20 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="bg" @click="closeRoutesModal"></div>
|
<div class="modal-bg" @click="closeRoutesModal"></div>
|
||||||
<div class="routes-modal" v-if="sceneriesStore.currentStation" @keydown.esc="closeRoutesModal" tabindex="0" ref="modal">
|
|
||||||
|
<div
|
||||||
|
v-if="sceneriesStore.currentStation"
|
||||||
|
class="modal routes-modal"
|
||||||
|
@keydown.esc="closeRoutesModal"
|
||||||
|
tabindex="0"
|
||||||
|
ref="modal"
|
||||||
|
>
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<div class="modal-wrapper">
|
<div class="modal-wrapper">
|
||||||
<h1>
|
<h1 class="modal-header">
|
||||||
Szlaki na scenerii {{ sceneriesStore.currentStation.name }}
|
Szlaki na scenerii {{ sceneriesStore.currentStation.name }}
|
||||||
<div class="exit" @click="closeRoutesModal">
|
<button class="modal-exit" @click="closeRoutesModal">
|
||||||
<img src="/icon-exit.svg" alt="exit icon" />
|
<LucideX :size="20" />
|
||||||
</div>
|
</button>
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<ul class="route-list">
|
<ul class="route-list">
|
||||||
@@ -16,19 +23,29 @@
|
|||||||
<div style="display: flex; justify-content: space-between; align-items: center; gap: 1em">
|
<div style="display: flex; justify-content: space-between; align-items: center; gap: 1em">
|
||||||
<span> Szlak: <input type="text" v-model="route.routeName" /> </span>
|
<span> Szlak: <input type="text" v-model="route.routeName" /> </span>
|
||||||
|
|
||||||
<button class="btn--icon">
|
<button class="route-delete-btn" @click="removeRoute(i)">
|
||||||
<img @click="removeRoute(i)" class="route-delete" src="/icon-trash.svg" alt="icon trash" />
|
<LucideTrash />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label :for="`${route.routeName}-internal`" style="display: inline-block">
|
<label :for="`${route.routeName}-internal`" style="display: inline-block">
|
||||||
<input type="checkbox" :name="`${route.routeName}-internal`" :id="`${route.routeName}-internal`" v-model="route.isInternal" />
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
:name="`${route.routeName}-internal`"
|
||||||
|
:id="`${route.routeName}-internal`"
|
||||||
|
v-model="route.isInternal"
|
||||||
|
/>
|
||||||
WEWNĘTRZNY
|
WEWNĘTRZNY
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label :for="`${route.routeName}-hidden`" style="display: inline-block">
|
<label :for="`${route.routeName}-hidden`" style="display: inline-block">
|
||||||
<input type="checkbox" :name="`${route.routeName}-hidden`" :id="`${route.routeName}-hidden`" v-model="route.hidden" />
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
:name="`${route.routeName}-hidden`"
|
||||||
|
:id="`${route.routeName}-hidden`"
|
||||||
|
v-model="route.hidden"
|
||||||
|
/>
|
||||||
UKRYTY
|
UKRYTY
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
@@ -36,12 +53,24 @@
|
|||||||
<div>
|
<div>
|
||||||
<b>Liczba torów:</b>
|
<b>Liczba torów:</b>
|
||||||
<label class="radio-choice">
|
<label class="radio-choice">
|
||||||
<input type="radio" :name="`${route.routeName}-tracks`" :value="1" :checked="route.routeTracks == 1" v-model="route.routeTracks" />
|
<input
|
||||||
|
type="radio"
|
||||||
|
:name="`${route.routeName}-tracks`"
|
||||||
|
:value="1"
|
||||||
|
:checked="route.routeTracks == 1"
|
||||||
|
v-model="route.routeTracks"
|
||||||
|
/>
|
||||||
<span>1</span>
|
<span>1</span>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label class="radio-choice">
|
<label class="radio-choice">
|
||||||
<input type="radio" :name="`${route.routeName}-tracks`" :value="2" :checked="route.routeTracks == 2" v-model="route.routeTracks" />
|
<input
|
||||||
|
type="radio"
|
||||||
|
:name="`${route.routeName}-tracks`"
|
||||||
|
:value="2"
|
||||||
|
:checked="route.routeTracks == 2"
|
||||||
|
v-model="route.routeTracks"
|
||||||
|
/>
|
||||||
<span>2</span>
|
<span>2</span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
@@ -49,12 +78,24 @@
|
|||||||
<b>Elektryfikacja:</b>
|
<b>Elektryfikacja:</b>
|
||||||
|
|
||||||
<label class="radio-choice">
|
<label class="radio-choice">
|
||||||
<input type="radio" :name="`${route.routeName}-electr`" :value="true" :checked="route.isElectric" v-model="route.isElectric" />
|
<input
|
||||||
|
type="radio"
|
||||||
|
:name="`${route.routeName}-electr`"
|
||||||
|
:value="true"
|
||||||
|
:checked="route.isElectric"
|
||||||
|
v-model="route.isElectric"
|
||||||
|
/>
|
||||||
<span>Tak</span>
|
<span>Tak</span>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label class="radio-choice">
|
<label class="radio-choice">
|
||||||
<input type="radio" :name="`${route.routeName}-electr`" :value="false" :checked="!route.isElectric" v-model="route.isElectric" />
|
<input
|
||||||
|
type="radio"
|
||||||
|
:name="`${route.routeName}-electr`"
|
||||||
|
:value="false"
|
||||||
|
:checked="!route.isElectric"
|
||||||
|
v-model="route.isElectric"
|
||||||
|
/>
|
||||||
<span>Nie</span>
|
<span>Nie</span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
@@ -86,8 +127,12 @@
|
|||||||
|
|
||||||
<div v-if="route.routeTracks == 1">Prędkość: <input type="number" v-model="route.routeSpeed" /> km/h</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">
|
||||||
<div v-if="route.routeTracks == 2">Prędkość (wyjazd ze sc.): <input type="number" v-model="route.routeSpeedExit" /> km/h</div>
|
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>Długość: <input type="number" v-model="route.routeLength" /> m</div>
|
||||||
<div>Linia kolejowa: <input type="number" v-model="route.realLineNo" /></div>
|
<div>Linia kolejowa: <input type="number" v-model="route.realLineNo" /></div>
|
||||||
@@ -110,8 +155,11 @@ import { Ref, defineComponent, ref } from 'vue';
|
|||||||
import changeMixin from '../mixins/changeMixin';
|
import changeMixin from '../mixins/changeMixin';
|
||||||
import { SceneryRoutesInfo } from '../types/sceneries.types';
|
import { SceneryRoutesInfo } from '../types/sceneries.types';
|
||||||
import { useSceneriesStore } from '../stores/sceneries.store';
|
import { useSceneriesStore } from '../stores/sceneries.store';
|
||||||
|
import { LucideTrash, LucideX } from 'lucide-vue-next';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
|
components: { LucideX, LucideTrash },
|
||||||
|
|
||||||
setup() {
|
setup() {
|
||||||
const sceneriesStore = useSceneriesStore();
|
const sceneriesStore = useSceneriesStore();
|
||||||
const currentRoutes: Ref<SceneryRoutesInfo[]> = ref([]);
|
const currentRoutes: Ref<SceneryRoutesInfo[]> = ref([]);
|
||||||
@@ -164,9 +212,9 @@ export default defineComponent({
|
|||||||
const routeString = this.sceneriesStore.currentStation?.routesInfo
|
const routeString = this.sceneriesStore.currentStation?.routesInfo
|
||||||
.map(
|
.map(
|
||||||
(route) =>
|
(route) =>
|
||||||
`${route.isInternal ? '!' : ''}${route.routeName.trim()}_${route.routeTracks}${route.isElectric ? 'E' : 'N'}${
|
`${route.isInternal ? '!' : ''}${route.routeName.trim()}_${route.routeTracks}${
|
||||||
route.isRouteSBL ? 'S' : 'P'
|
route.isElectric ? 'E' : 'N'
|
||||||
}:${route.routeSpeed || 0}:${route.routeLength || 0}`
|
}${route.isRouteSBL ? 'S' : 'P'}:${route.routeSpeed || 0}:${route.routeLength || 0}`,
|
||||||
)
|
)
|
||||||
.join(';');
|
.join(';');
|
||||||
|
|
||||||
@@ -174,7 +222,9 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
|
|
||||||
saveRoutes() {
|
saveRoutes() {
|
||||||
const index = this.sceneriesStore.stationList.findIndex((station) => station.name === this.sceneriesStore.currentStation?.name);
|
const index = this.sceneriesStore.stationList.findIndex(
|
||||||
|
(station) => station.name === this.sceneriesStore.currentStation?.name,
|
||||||
|
);
|
||||||
|
|
||||||
if (index == -1) return;
|
if (index == -1) return;
|
||||||
|
|
||||||
@@ -186,45 +236,16 @@ export default defineComponent({
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.bg {
|
@use '../styles/modal';
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 100vw;
|
|
||||||
height: 100vh;
|
|
||||||
|
|
||||||
z-index: 100;
|
.routes-modal input {
|
||||||
|
display: inline;
|
||||||
|
margin: 0.25em 0;
|
||||||
|
|
||||||
background-color: #00000081;
|
color: black;
|
||||||
}
|
font-size: 1em;
|
||||||
|
|
||||||
.routes-modal {
|
max-width: 120px;
|
||||||
position: fixed;
|
|
||||||
top: 50%;
|
|
||||||
left: 50%;
|
|
||||||
|
|
||||||
width: 95%;
|
|
||||||
max-width: 800px;
|
|
||||||
|
|
||||||
height: 95vh;
|
|
||||||
max-height: 1000px;
|
|
||||||
|
|
||||||
transform: translate(-50%, -50%);
|
|
||||||
z-index: 101;
|
|
||||||
padding: 0.5em 0;
|
|
||||||
|
|
||||||
background-color: #333;
|
|
||||||
border-radius: 1rem;
|
|
||||||
|
|
||||||
input {
|
|
||||||
display: inline;
|
|
||||||
margin: 0.25em 0;
|
|
||||||
|
|
||||||
color: black;
|
|
||||||
font-size: 1em;
|
|
||||||
|
|
||||||
max-width: 120px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
label.radio-choice {
|
label.radio-choice {
|
||||||
@@ -256,35 +277,6 @@ label.radio-choice {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.exit {
|
|
||||||
img {
|
|
||||||
vertical-align: text-bottom;
|
|
||||||
width: 1.4em;
|
|
||||||
}
|
|
||||||
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
gap: 0.5em;
|
|
||||||
|
|
||||||
position: sticky;
|
|
||||||
top: -1px;
|
|
||||||
|
|
||||||
z-index: 100;
|
|
||||||
|
|
||||||
background-color: #333;
|
|
||||||
border-radius: 1rem 1rem 0 0;
|
|
||||||
padding: 0.25em 0.5em;
|
|
||||||
margin: 0;
|
|
||||||
|
|
||||||
font-size: 2em;
|
|
||||||
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.modal-content {
|
.modal-content {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-rows: 1fr auto;
|
grid-template-rows: 1fr auto;
|
||||||
@@ -292,18 +284,14 @@ h1 {
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.modal-wrapper {
|
ul.route-list {
|
||||||
overflow: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.routes-modal ul {
|
|
||||||
list-style: none;
|
list-style: none;
|
||||||
padding: 0 1em;
|
padding: 0 1em;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
ul li {
|
ul.route-list li {
|
||||||
padding: 0.65em;
|
padding: 0.65em;
|
||||||
margin: 0.5em 0;
|
margin: 0.5em 0;
|
||||||
|
|
||||||
@@ -312,19 +300,12 @@ ul li {
|
|||||||
background-color: #222;
|
background-color: #222;
|
||||||
}
|
}
|
||||||
|
|
||||||
li > form {
|
ul.route-list li > form {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 0.25em;
|
gap: 0.25em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.route-delete {
|
|
||||||
margin: 0.5em;
|
|
||||||
width: 1.15em;
|
|
||||||
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.routes-actions {
|
.routes-actions {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
@@ -340,4 +321,13 @@ li > form {
|
|||||||
font-size: 1.2em;
|
font-size: 1.2em;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.route-delete-btn {
|
||||||
|
background-color: #444;
|
||||||
|
border-radius: 0.5em;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: #555;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -0,0 +1,273 @@
|
|||||||
|
<template>
|
||||||
|
<div class="modal-bg" @click="() => (vehiclesStore.selectedVehicleId = -1)"></div>
|
||||||
|
|
||||||
|
<div class="modal">
|
||||||
|
<div class="modal-content">
|
||||||
|
<h1 class="modal-header">
|
||||||
|
{{ mode == 'update' ? 'Edytuj' : 'Dodaj' }} pojazd
|
||||||
|
|
||||||
|
<button class="modal-exit" @click="closeModal">
|
||||||
|
<LucideX :size="40" />
|
||||||
|
</button>
|
||||||
|
</h1>
|
||||||
|
|
||||||
|
<div class="modal-details" v-if="vehicleRef">
|
||||||
|
<div><b>ID:</b> {{ vehicleRef.id }}</div>
|
||||||
|
|
||||||
|
<div><b>Nazwa:</b> <input type="text" v-model="vehicleValues.name" /></div>
|
||||||
|
|
||||||
|
<div><b>Typ:</b> <input type="text" v-model="vehicleValues.type" /></div>
|
||||||
|
|
||||||
|
<div><b>Kabina lokomotywy:</b> <input type="text" v-model="vehicleValues.cabinName" /></div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<b>Grupa: </b>
|
||||||
|
<select id="select-group" ref="select-group" v-model="vehicleValues.vehicleGroupsId">
|
||||||
|
<option
|
||||||
|
v-for="value in vehiclesStore.vehicleGroupsTable"
|
||||||
|
:value="value.vehicleGroupRef.id"
|
||||||
|
:selected="vehicleRef.group.id == value.vehicleGroupRef.id"
|
||||||
|
>
|
||||||
|
{{ value.vehicleGroupRef.name }}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label>Sponsorzy do: </label>
|
||||||
|
|
||||||
|
<input type="number" v-model="vehicleValues.restrictions!.sponsorOnly" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
name="vehicle-team-only"
|
||||||
|
id="vehicle-team-only"
|
||||||
|
v-model="vehicleValues.restrictions!.teamOnly"
|
||||||
|
/>
|
||||||
|
<label for="vehicle-team-only">Tylko dla zespołu</label>
|
||||||
|
|
||||||
|
<input type="checkbox" name="vehicle-hidden" id="vehicle-hidden" v-model="vehicleValues.hidden" />
|
||||||
|
<label for="vehicle-hidden">Ukryty</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div></div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<b>Miniaturka:</b>
|
||||||
|
<div>
|
||||||
|
<img
|
||||||
|
:src="`https://stacjownik.spythere.eu/static/thumbnails/${vehicleRef.name}.png`"
|
||||||
|
height="60"
|
||||||
|
alt="thumbnail image"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<b>Podgląd - 300px:</b>
|
||||||
|
<div>
|
||||||
|
<img
|
||||||
|
:src="`https://stacjownik.spythere.eu/static/images/${vehicleRef.name}--300px.jpg`"
|
||||||
|
width="200"
|
||||||
|
alt="thumbnail"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<b>Podgląd - 800px:</b>
|
||||||
|
<div>
|
||||||
|
<img
|
||||||
|
:src="`https://stacjownik.spythere.eu/static/images/${vehicleRef.name}--800px.jpg`"
|
||||||
|
width="300"
|
||||||
|
alt="thumbnail"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="modal-actions">
|
||||||
|
<button @click="updateVehicle">Aktualizuj dane</button>
|
||||||
|
<button @click="removeVehicle">Usuń pojazd</button>
|
||||||
|
<button @click="closeModal">Nie zapisuj</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { computed, onMounted, PropType, reactive, ref, Ref, watch } from 'vue';
|
||||||
|
import { useVehiclesStore } from '../../stores/vehicles.store';
|
||||||
|
import { LucideX } from 'lucide-vue-next';
|
||||||
|
import { IVehicle, RemoveVehicleGroupAPIResponse, UpdateVehicleAPIResponse } from '../../types/vehicles.types';
|
||||||
|
import client from '../../common/http';
|
||||||
|
import { AxiosError } from 'axios';
|
||||||
|
|
||||||
|
const vehiclesStore = useVehiclesStore();
|
||||||
|
|
||||||
|
const currentVehicleRef: Ref<IVehicle | null> = ref(null);
|
||||||
|
|
||||||
|
let vehicleValues: Partial<IVehicle> = reactive({
|
||||||
|
name: '',
|
||||||
|
cabinName: '',
|
||||||
|
restrictions: {
|
||||||
|
teamOnly: false,
|
||||||
|
sponsorOnly: null,
|
||||||
|
},
|
||||||
|
type: '',
|
||||||
|
vehicleGroupsId: 0,
|
||||||
|
hidden: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
let currentChanges: Record<string, any> = reactive({});
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
mode: {
|
||||||
|
type: String as PropType<'update' | 'create'>,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const vehicleRef = computed(
|
||||||
|
() => vehiclesStore.vehiclesTable.find((v) => v.vehicleRef.id == vehiclesStore.selectedVehicleId)?.vehicleRef,
|
||||||
|
);
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
currentVehicleRef.value =
|
||||||
|
vehiclesStore.vehiclesTable.find((v) => v.vehicleRef.id == vehiclesStore.selectedVehicleId)?.vehicleRef ?? null;
|
||||||
|
|
||||||
|
if (currentVehicleRef.value) {
|
||||||
|
vehicleValues.name = currentVehicleRef.value.name || '';
|
||||||
|
vehicleValues.cabinName = currentVehicleRef.value.cabinName || '';
|
||||||
|
vehicleValues.type = currentVehicleRef.value.type || '';
|
||||||
|
vehicleValues.vehicleGroupsId = currentVehicleRef.value.vehicleGroupsId || 0;
|
||||||
|
vehicleValues.hidden = currentVehicleRef.value.hidden;
|
||||||
|
vehicleValues.restrictions = {
|
||||||
|
sponsorOnly: currentVehicleRef.value.restrictions?.sponsorOnly ?? null,
|
||||||
|
teamOnly: currentVehicleRef.value.restrictions?.teamOnly ?? false,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
watch(
|
||||||
|
vehicleValues,
|
||||||
|
(val) => {
|
||||||
|
Object.keys(val).forEach((k) => {
|
||||||
|
const newValue = vehicleValues[k as keyof IVehicle];
|
||||||
|
const currentValue = currentVehicleRef.value![k as keyof IVehicle];
|
||||||
|
|
||||||
|
if (newValue != currentValue) currentChanges[k] = newValue;
|
||||||
|
else currentChanges[k] = undefined;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
{ deep: true },
|
||||||
|
);
|
||||||
|
|
||||||
|
function closeModal() {
|
||||||
|
vehiclesStore.selectedVehicleId = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleAPIErrors(error: unknown) {
|
||||||
|
console.error(error);
|
||||||
|
|
||||||
|
if (error instanceof AxiosError) {
|
||||||
|
return `Nie zaktualizowano pojazdu: ${error.response?.data.message}`;
|
||||||
|
} else {
|
||||||
|
return `Nie zaktualizowano pojazdu: ${error}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function updateVehicle() {
|
||||||
|
const vehicle = vehicleRef.value;
|
||||||
|
|
||||||
|
if (!vehicle) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const updatedData = (
|
||||||
|
await client.put<UpdateVehicleAPIResponse>(`/manager/vehicles/${vehicle.id}`, {
|
||||||
|
...vehicleValues,
|
||||||
|
restrictions: {
|
||||||
|
teamOnly: vehicleValues.restrictions?.teamOnly ?? false,
|
||||||
|
sponsorOnly: vehicleValues.restrictions?.sponsorOnly || null,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
).data;
|
||||||
|
|
||||||
|
const oldGroup = vehicle.group;
|
||||||
|
|
||||||
|
vehicle.name = updatedData.name;
|
||||||
|
vehicle.type = updatedData.type;
|
||||||
|
vehicle.vehicleGroupsId = updatedData.vehicleGroupsId;
|
||||||
|
vehicle.cabinName = updatedData.cabinName;
|
||||||
|
vehicle.hidden = updatedData.hidden;
|
||||||
|
vehicle.restrictions = updatedData.restrictions;
|
||||||
|
vehicle.group = vehiclesStore.vehicleGroupsTable.find(
|
||||||
|
(g) => g.vehicleGroupRef.id == updatedData.vehicleGroupsId,
|
||||||
|
)!.vehicleGroupRef;
|
||||||
|
|
||||||
|
const newGroup = vehicle.group;
|
||||||
|
|
||||||
|
// Updating group counts
|
||||||
|
oldGroup._count.vehicles -= 1;
|
||||||
|
newGroup._count.vehicles += 1;
|
||||||
|
|
||||||
|
alert('Zaktualizowano pojazd: ' + updatedData.name);
|
||||||
|
} catch (error) {
|
||||||
|
alert(handleAPIErrors(error));
|
||||||
|
}
|
||||||
|
|
||||||
|
vehiclesStore.selectedVehicleId = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function removeVehicle() {
|
||||||
|
const vehicle = vehicleRef.value;
|
||||||
|
|
||||||
|
if (!vehicle) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const removedData = (await client.delete<RemoveVehicleGroupAPIResponse>(`/manager/vehicles/${vehicle.id}`)).data;
|
||||||
|
vehicle.group._count.vehicles -= 1;
|
||||||
|
|
||||||
|
vehiclesStore.vehiclesTable = vehiclesStore.vehiclesTable.filter((v) => v.vehicleRef.id != vehicle.id);
|
||||||
|
|
||||||
|
alert('Usunięto pojazd: ' + removedData.name);
|
||||||
|
} catch (error) {
|
||||||
|
alert(handleAPIErrors(error));
|
||||||
|
}
|
||||||
|
|
||||||
|
vehiclesStore.selectedVehicleId = -1;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@use '../../styles/modal';
|
||||||
|
|
||||||
|
.modal-content {
|
||||||
|
display: grid;
|
||||||
|
gap: 0.5em;
|
||||||
|
grid-template-rows: auto 1fr auto;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-details {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.5em;
|
||||||
|
overflow: auto;
|
||||||
|
|
||||||
|
padding: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-actions {
|
||||||
|
display: flex;
|
||||||
|
gap: 0.5em;
|
||||||
|
font-size: 1.1em;
|
||||||
|
padding: 1em;
|
||||||
|
|
||||||
|
button {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -183,28 +183,28 @@ function sortTableBy(id: string) {
|
|||||||
activeSortKey.value = id;
|
activeSortKey.value = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
// async function editRowPrimitive(row: IVehicleGroupTableRow, editKey: VehicleGroupEditRowKey) {
|
async function editRowPrimitive(row: IVehicleGroupTableRow, editKey: VehicleGroupEditRowKey) {
|
||||||
// if (!(editKey in row.vehicleGroupRef)) return;
|
if (!(editKey in row.vehicleGroupRef)) return;
|
||||||
|
|
||||||
// let rowValue = row.vehicleGroupRef[editKey];
|
let rowValue = row.vehicleGroupRef[editKey];
|
||||||
|
|
||||||
// if (typeof rowValue === 'string' || typeof rowValue === 'undefined' || rowValue == null) {
|
if (typeof rowValue === 'string' || typeof rowValue === 'undefined' || rowValue == null) {
|
||||||
// const promptValue = prompt('Zmień wartość:', rowValue ?? '');
|
const promptValue = prompt('Zmień wartość:', rowValue ?? '');
|
||||||
// if (promptValue == null) return;
|
if (promptValue == null) return;
|
||||||
|
|
||||||
// const updatedData = await vehiclesStore.updateVehicle(row.vehicleGroupRef.id, editKey, promptValue);
|
const updatedData = await vehiclesStore.updateVehicleGroup(row.vehicleGroupRef.id, editKey, promptValue);
|
||||||
|
|
||||||
// if (updatedData) {
|
if (updatedData) {
|
||||||
// (row.vehicleGroupRef[editKey] as any) = updatedData[editKey];
|
(row.vehicleGroupRef[editKey] as any) = updatedData[editKey];
|
||||||
// }
|
}
|
||||||
// } else if (typeof rowValue == 'boolean') {
|
} else if (typeof rowValue == 'boolean') {
|
||||||
// const updatedData = await vehiclesStore.updateVehicle(row.vehicleGroupRef.id, editKey, !rowValue);
|
const updatedData = await vehiclesStore.updateVehicleGroup(row.vehicleGroupRef.id, editKey, !rowValue);
|
||||||
|
|
||||||
// if (updatedData) {
|
if (updatedData) {
|
||||||
// (row.vehicleGroupRef[editKey] as any) = updatedData[editKey];
|
(row.vehicleGroupRef[editKey] as any) = updatedData[editKey];
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
|
|
||||||
async function addVehicleGroupRow() {
|
async function addVehicleGroupRow() {
|
||||||
const data = await vehiclesStore.createVehicleGroup({
|
const data = await vehiclesStore.createVehicleGroup({
|
||||||
|
|||||||
@@ -18,6 +18,8 @@
|
|||||||
wyników
|
wyników
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<VehicleEditModal v-if="vehiclesStore.selectedVehicleId != -1" mode="update" />
|
||||||
|
|
||||||
<div class="table-wrapper">
|
<div class="table-wrapper">
|
||||||
<table class="vehicle-manager-table">
|
<table class="vehicle-manager-table">
|
||||||
<thead>
|
<thead>
|
||||||
@@ -39,24 +41,24 @@
|
|||||||
</thead>
|
</thead>
|
||||||
|
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr v-for="row in vehiclesTableComp" :key="row.vehicleRef.id">
|
<tr v-for="row in vehiclesTableComp" :key="row.vehicleRef.id" @click="openEditModal(row.vehicleRef.id)">
|
||||||
<td>{{ row.vehicleRef.id }}</td>
|
<td>{{ row.vehicleRef.id }}</td>
|
||||||
|
|
||||||
<td class="editable" @click="editRowPrimitive(row, VehicleEditRowKey.NAME)">
|
<td>
|
||||||
{{ row.vehicleRef.name }}
|
{{ row.vehicleRef.name }}
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td class="editable" @click="editRowPrimitive(row, VehicleEditRowKey.TYPE)">
|
<td>
|
||||||
{{ row.vehicleRef.type }}
|
{{ row.vehicleRef.type }}
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td class="editable" @click="editRowPrimitive(row, VehicleEditRowKey.CABIN)">
|
<td>
|
||||||
{{ row.vehicleRef.cabinName }}
|
{{ row.vehicleRef.cabinName }}
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td class="editable" @click="selectRowVehicleGroup(row)">
|
<td>
|
||||||
<select
|
<!-- <select
|
||||||
v-if="currentEditingGroupId == row.vehicleRef.id"
|
v-if="currentEditId == row.vehicleRef.id"
|
||||||
@blur="(e) => editVehicleGroup(e, row)"
|
@blur="(e) => editVehicleGroup(e, row)"
|
||||||
:id="`select-group-${row.vehicleRef.id}`"
|
:id="`select-group-${row.vehicleRef.id}`"
|
||||||
ref="select-group"
|
ref="select-group"
|
||||||
@@ -69,20 +71,20 @@
|
|||||||
>
|
>
|
||||||
{{ value.vehicleGroupRef.name }}
|
{{ value.vehicleGroupRef.name }}
|
||||||
</option>
|
</option>
|
||||||
</select>
|
</select> -->
|
||||||
|
|
||||||
<span v-else>{{ row.vehicleRef.group.name }}</span>
|
<span>{{ row.vehicleRef.group.name }}</span>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td class="editable" @click="editRowRestrictions(row, VehicleEditRestrictionKey.SPONSOR_ONLY)">
|
<td>
|
||||||
<span v-if="row.vehicleRef.restrictions?.sponsorOnly !== undefined">
|
<span v-if="row.vehicleRef.restrictions?.sponsorOnly">
|
||||||
{{ new Date(row.vehicleRef.restrictions.sponsorOnly).toLocaleString() }}
|
{{ new Date(row.vehicleRef.restrictions.sponsorOnly).toLocaleString() }}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<span v-else>❌</span>
|
<span v-else>❌</span>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td class="editable" @click="editRowRestrictions(row, VehicleEditRestrictionKey.TEAM_ONLY)">
|
<td>
|
||||||
<span v-if="row.vehicleRef.restrictions?.teamOnly !== undefined">
|
<span v-if="row.vehicleRef.restrictions?.teamOnly !== undefined">
|
||||||
{{ row.vehicleRef.restrictions.teamOnly ? '✅' : '❌' }}
|
{{ row.vehicleRef.restrictions.teamOnly ? '✅' : '❌' }}
|
||||||
</span>
|
</span>
|
||||||
@@ -90,11 +92,11 @@
|
|||||||
<span v-else>❌</span>
|
<span v-else>❌</span>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td class="editable" @click="editRowPrimitive(row, VehicleEditRowKey.HIDDEN)">
|
<td>
|
||||||
{{ row.vehicleRef.hidden ? '✅' : '❌' }}
|
{{ row.vehicleRef.hidden ? '✅' : '❌' }}
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td class="editable" @click="removeVehicleRow(row.vehicleRef.id)">
|
<td>
|
||||||
<img src="/icon-trash.svg" alt="remove" />
|
<img src="/icon-trash.svg" alt="remove" />
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -108,6 +110,7 @@ import { computed, nextTick, onMounted, ref, useTemplateRef, watch } from 'vue';
|
|||||||
import { useVehiclesStore } from '../../stores/vehicles.store';
|
import { useVehiclesStore } from '../../stores/vehicles.store';
|
||||||
import { IVehicle, IVehicleTableRow, VehicleEditRestrictionKey, VehicleEditRowKey } from '../../types/vehicles.types';
|
import { IVehicle, IVehicleTableRow, VehicleEditRestrictionKey, VehicleEditRowKey } from '../../types/vehicles.types';
|
||||||
import { LucideArrowDown, LucideArrowUp, LucidePlus, LucideX } from 'lucide-vue-next';
|
import { LucideArrowDown, LucideArrowUp, LucidePlus, LucideX } from 'lucide-vue-next';
|
||||||
|
import VehicleEditModal from './VehicleEditModal.vue';
|
||||||
|
|
||||||
interface TableHeader {
|
interface TableHeader {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -148,9 +151,6 @@ const maxVisibleResults = ref(150);
|
|||||||
const activeSortKey = ref<string>('id');
|
const activeSortKey = ref<string>('id');
|
||||||
const activeSortDir = ref(1);
|
const activeSortDir = ref(1);
|
||||||
|
|
||||||
const currentEditingGroupId = ref(-1);
|
|
||||||
const selectGroup = useTemplateRef('select-group');
|
|
||||||
|
|
||||||
const vehiclesTableComp = computed(() => {
|
const vehiclesTableComp = computed(() => {
|
||||||
return vehiclesStore.vehiclesTable
|
return vehiclesStore.vehiclesTable
|
||||||
.filter((row) => row.vehicleRef.name.toLowerCase().includes(vehicleSearchInput.value.trim().toLowerCase()))
|
.filter((row) => row.vehicleRef.name.toLowerCase().includes(vehicleSearchInput.value.trim().toLowerCase()))
|
||||||
@@ -179,91 +179,8 @@ function sortTableBy(id: string) {
|
|||||||
activeSortKey.value = id;
|
activeSortKey.value = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function editRowPrimitive(row: IVehicleTableRow, editKey: VehicleEditRowKey) {
|
function openEditModal(vehicleId: number) {
|
||||||
if (!(editKey in row.vehicleRef)) return;
|
vehiclesStore.selectedVehicleId = vehicleId;
|
||||||
|
|
||||||
let rowValue = row.vehicleRef[editKey];
|
|
||||||
|
|
||||||
if (typeof rowValue === 'string' || typeof rowValue === 'undefined' || rowValue == null) {
|
|
||||||
const promptValue = prompt('Zmień wartość:', rowValue ?? '');
|
|
||||||
if (promptValue == null) return;
|
|
||||||
|
|
||||||
const updatedData = await vehiclesStore.updateVehicle(row.vehicleRef.id, editKey, promptValue);
|
|
||||||
|
|
||||||
if (updatedData) {
|
|
||||||
(row.vehicleRef[editKey] as any) = updatedData[editKey];
|
|
||||||
}
|
|
||||||
} else if (typeof rowValue == 'boolean') {
|
|
||||||
const updatedData = await vehiclesStore.updateVehicle(row.vehicleRef.id, editKey, !rowValue);
|
|
||||||
|
|
||||||
if (updatedData) {
|
|
||||||
(row.vehicleRef[editKey] as any) = updatedData[editKey];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function editRowRestrictions(row: IVehicleTableRow, editKey: VehicleEditRestrictionKey) {
|
|
||||||
const restrictions: Record<VehicleEditRestrictionKey, any> = {
|
|
||||||
teamOnly: row.vehicleRef.restrictions?.teamOnly ?? undefined,
|
|
||||||
sponsorOnly: row.vehicleRef.restrictions?.sponsorOnly ?? undefined,
|
|
||||||
};
|
|
||||||
|
|
||||||
if (editKey == VehicleEditRestrictionKey.TEAM_ONLY) {
|
|
||||||
restrictions[editKey] = row.vehicleRef.restrictions ? !row.vehicleRef.restrictions[editKey] : true;
|
|
||||||
|
|
||||||
const updatedData = await vehiclesStore.updateVehicle(row.vehicleRef.id, 'restrictions', restrictions);
|
|
||||||
|
|
||||||
if (updatedData) {
|
|
||||||
if (!row.vehicleRef.restrictions) row.vehicleRef.restrictions = {};
|
|
||||||
|
|
||||||
row.vehicleRef.restrictions[editKey] = updatedData.restrictions![editKey];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (editKey == VehicleEditRestrictionKey.SPONSOR_ONLY) {
|
|
||||||
const promptValue = prompt(
|
|
||||||
'Zmień wartość (timestamp):',
|
|
||||||
row.vehicleRef.restrictions?.sponsorOnly?.toString() ?? Date.now().toString(),
|
|
||||||
);
|
|
||||||
|
|
||||||
if (promptValue == null) return;
|
|
||||||
|
|
||||||
restrictions[editKey] = promptValue.trim() != '' ? parseInt(promptValue) : undefined;
|
|
||||||
|
|
||||||
const updatedData = await vehiclesStore.updateVehicle(row.vehicleRef.id, 'restrictions', restrictions);
|
|
||||||
|
|
||||||
if (updatedData) {
|
|
||||||
if (!row.vehicleRef.restrictions) row.vehicleRef.restrictions = {};
|
|
||||||
|
|
||||||
row.vehicleRef.restrictions[editKey] = updatedData.restrictions![editKey];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function selectRowVehicleGroup(row: IVehicleTableRow) {
|
|
||||||
currentEditingGroupId.value = row.vehicleRef.id;
|
|
||||||
|
|
||||||
nextTick(() => {
|
|
||||||
if (selectGroup.value) {
|
|
||||||
selectGroup.value[0].focus();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async function editVehicleGroup(e: Event, row: IVehicleTableRow) {
|
|
||||||
const id = (e.target as HTMLSelectElement).value;
|
|
||||||
|
|
||||||
if (row.vehicleRef.group.id !== +id) {
|
|
||||||
const updatedData = await vehiclesStore.updateVehicle(row.vehicleRef.id, 'vehicleGroupId', +id);
|
|
||||||
|
|
||||||
if (updatedData) {
|
|
||||||
row.vehicleRef.group = vehiclesStore.vehicleGroupsTable.find(
|
|
||||||
(g) => g.vehicleGroupRef.id == updatedData.vehicleGroupsId,
|
|
||||||
)!.vehicleGroupRef;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
currentEditingGroupId.value = -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function addVehicleRow() {
|
async function addVehicleRow() {
|
||||||
@@ -283,19 +200,7 @@ async function addVehicleRow() {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
vehicleSearchInput.value = createdVehicleData.name;
|
vehiclesStore.selectedVehicleId = createdVehicleData.id;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function removeVehicleRow(id: number) {
|
|
||||||
const confirmRemove = confirm('Czy na pewno chcesz usunąć ten pojazd?');
|
|
||||||
|
|
||||||
if (!confirmRemove) return;
|
|
||||||
|
|
||||||
const removedVehicleData = await vehiclesStore.removeVehicle(id);
|
|
||||||
|
|
||||||
if (removedVehicleData) {
|
|
||||||
vehiclesStore.vehiclesTable = vehiclesStore.vehiclesTable.filter((v) => v.vehicleRef.id != id);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import {
|
|||||||
CreateVehicleGroupAPIResponse,
|
CreateVehicleGroupAPIResponse,
|
||||||
ICreateVehicleGroupBody,
|
ICreateVehicleGroupBody,
|
||||||
RemoveVehicleGroupAPIResponse,
|
RemoveVehicleGroupAPIResponse,
|
||||||
|
IVehicleGroupAPI,
|
||||||
} from '../types/vehicles.types';
|
} from '../types/vehicles.types';
|
||||||
import { LoadingState } from '../types/common.types';
|
import { LoadingState } from '../types/common.types';
|
||||||
|
|
||||||
@@ -22,6 +23,8 @@ export const useVehiclesStore = defineStore('vehiclesStore', {
|
|||||||
vehicles: [] as IVehicle[],
|
vehicles: [] as IVehicle[],
|
||||||
dataState: LoadingState.INIT,
|
dataState: LoadingState.INIT,
|
||||||
|
|
||||||
|
selectedVehicleId: -1,
|
||||||
|
|
||||||
vehiclesTable: [] as IVehicleTableRow[],
|
vehiclesTable: [] as IVehicleTableRow[],
|
||||||
vehicleGroupsTable: [] as IVehicleGroupTableRow[],
|
vehicleGroupsTable: [] as IVehicleGroupTableRow[],
|
||||||
}),
|
}),
|
||||||
@@ -58,23 +61,9 @@ export const useVehiclesStore = defineStore('vehiclesStore', {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
async updateVehicle(vehicleId: number, propKey: string, propValue: any) {
|
|
||||||
try {
|
|
||||||
const response = await client.put<UpdateVehicleAPIResponse>(`/manager/vehicles/${vehicleId}`, {
|
|
||||||
[propKey]: propValue,
|
|
||||||
});
|
|
||||||
|
|
||||||
return response.data;
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error);
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
},
|
|
||||||
|
|
||||||
async updateVehicleGroup(vehicleId: number, propKey: string, propValue: any) {
|
async updateVehicleGroup(vehicleId: number, propKey: string, propValue: any) {
|
||||||
try {
|
try {
|
||||||
const response = await client.put<IVehicleAPI>(`/manager/vehicleGroups/${vehicleId}`, {
|
const response = await client.put<IVehicleGroupAPI>(`/manager/vehicleGroups/${vehicleId}`, {
|
||||||
[propKey]: propValue,
|
[propKey]: propValue,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -91,7 +80,7 @@ export const useVehiclesStore = defineStore('vehiclesStore', {
|
|||||||
const response = await client.post<CreateVehicleAPIResponse>(`/manager/vehicles`, {
|
const response = await client.post<CreateVehicleAPIResponse>(`/manager/vehicles`, {
|
||||||
name: vehicleRowData.name,
|
name: vehicleRowData.name,
|
||||||
type: vehicleRowData.type,
|
type: vehicleRowData.type,
|
||||||
vehicleGroupId: vehicleRowData.vehicleGroupsId,
|
vehicleGroupsId: vehicleRowData.vehicleGroupsId,
|
||||||
hidden: vehicleRowData.hidden,
|
hidden: vehicleRowData.hidden,
|
||||||
simulatorVersion: '2025.3.2',
|
simulatorVersion: '2025.3.2',
|
||||||
});
|
});
|
||||||
@@ -140,17 +129,5 @@ export const useVehiclesStore = defineStore('vehiclesStore', {
|
|||||||
|
|
||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
|
|
||||||
async removeVehicleGroup(vehicleGroupId: number) {
|
|
||||||
try {
|
|
||||||
const response = await client.delete<RemoveVehicleGroupAPIResponse>(`/manager/vehicleGroups/${vehicleGroupId}`);
|
|
||||||
|
|
||||||
return response.data;
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error);
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ table tr:nth-child(even) {
|
|||||||
background-color: #334756;
|
background-color: #334756;
|
||||||
}
|
}
|
||||||
|
|
||||||
table tr td.editable:hover {
|
table tr:hover {
|
||||||
background-color: #1a293b;
|
background-color: #1a293b;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,66 @@
|
|||||||
|
.modal-bg {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
|
||||||
|
z-index: 100;
|
||||||
|
|
||||||
|
background-color: #00000081;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal {
|
||||||
|
position: fixed;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
|
||||||
|
width: 95%;
|
||||||
|
max-width: 800px;
|
||||||
|
|
||||||
|
height: 95vh;
|
||||||
|
max-height: 1000px;
|
||||||
|
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
z-index: 101;
|
||||||
|
padding: 0.5em;
|
||||||
|
|
||||||
|
background-color: #333;
|
||||||
|
border-radius: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-wrapper {
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
button.modal-exit {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 0;
|
||||||
|
background-color: #444;
|
||||||
|
|
||||||
|
svg {
|
||||||
|
width: 1.5em;
|
||||||
|
height: 1em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h1.modal-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 0.5em;
|
||||||
|
|
||||||
|
position: sticky;
|
||||||
|
top: -1px;
|
||||||
|
|
||||||
|
z-index: 100;
|
||||||
|
|
||||||
|
background-color: #333;
|
||||||
|
border-radius: 1rem 1rem 0 0;
|
||||||
|
padding: 0.25em 0.5em;
|
||||||
|
margin: 0;
|
||||||
|
|
||||||
|
font-size: 2em;
|
||||||
|
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
@@ -32,7 +32,7 @@ export interface ICreateVehicleBody {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface IVehicleRestrictions {
|
export interface IVehicleRestrictions {
|
||||||
sponsorOnly?: number;
|
sponsorOnly?: number | null;
|
||||||
teamOnly?: boolean;
|
teamOnly?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -95,6 +95,14 @@ img.brand-image {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.table-wrapper table > tbody > tr {
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: #1a293b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.table-visible-results-box {
|
.table-visible-results-box {
|
||||||
margin-top: 0.5em;
|
margin-top: 0.5em;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user