mirror of
https://github.com/Spythere/pojazdownik.git
synced 2026-05-03 19:48:11 +00:00
chore(stock): stock tab design
This commit is contained in:
@@ -1,18 +1,20 @@
|
|||||||
<template>
|
<template>
|
||||||
<label>
|
<label>
|
||||||
<input type="checkbox" v-model="model" />
|
<input type="checkbox" :data-disabled="disabled" :disabled="disabled" v-model="model" />
|
||||||
<div><slot /></div>
|
<div><slot /></div>
|
||||||
</label>
|
</label>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
const model = defineModel();
|
const model = defineModel();
|
||||||
|
|
||||||
|
defineProps({
|
||||||
|
disabled: Boolean,
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
label {
|
label {
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
transition: color 200ms;
|
transition: color 200ms;
|
||||||
}
|
}
|
||||||
@@ -20,6 +22,7 @@ label {
|
|||||||
div {
|
div {
|
||||||
padding: 0.25em 0.5em;
|
padding: 0.25em 0.5em;
|
||||||
color: white;
|
color: white;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
background-color: #222;
|
background-color: #222;
|
||||||
border-radius: 0.25em;
|
border-radius: 0.25em;
|
||||||
@@ -54,5 +57,16 @@ input {
|
|||||||
content: '\2714';
|
content: '\2714';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&:disabled {
|
||||||
|
user-select: none;
|
||||||
|
-moz-user-select: none;
|
||||||
|
-webkit-user-select: none;
|
||||||
|
|
||||||
|
+ div {
|
||||||
|
opacity: 0.55;
|
||||||
|
cursor: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -4,221 +4,225 @@
|
|||||||
<h2>{{ $t('stocklist.title') }}</h2>
|
<h2>{{ $t('stocklist.title') }}</h2>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="stock_actions">
|
<div class="tab_content">
|
||||||
<button class="btn btn--image" @click="clickFileInput">
|
<div class="stock_actions">
|
||||||
<input type="file" @change="uploadStock" ref="conFile" accept=".con,.txt" />
|
<button class="btn btn--image" @click="clickFileInput">
|
||||||
<img src="/images/icon-upload.svg" alt="upload icon" />
|
<input type="file" @change="uploadStock" ref="conFile" accept=".con,.txt" />
|
||||||
{{ $t('stocklist.action-upload') }}
|
<img src="/images/icon-upload.svg" alt="upload icon" />
|
||||||
</button>
|
{{ $t('stocklist.action-upload') }}
|
||||||
|
</button>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
class="btn btn--image"
|
class="btn btn--image"
|
||||||
:data-disabled="stockIsEmpty"
|
:data-disabled="stockIsEmpty"
|
||||||
:disabled="stockIsEmpty"
|
:disabled="stockIsEmpty"
|
||||||
@click="downloadStock"
|
@click="downloadStock"
|
||||||
>
|
>
|
||||||
<img src="/images/icon-download.svg" alt="download icon" />
|
<img src="/images/icon-download.svg" alt="download icon" />
|
||||||
{{ $t('stocklist.action-download') }}
|
{{ $t('stocklist.action-download') }}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
class="btn btn--image"
|
class="btn btn--image"
|
||||||
:data-disabled="stockIsEmpty"
|
:data-disabled="stockIsEmpty"
|
||||||
:disabled="stockIsEmpty"
|
:disabled="stockIsEmpty"
|
||||||
@click="copyToClipboard"
|
@click="copyToClipboard"
|
||||||
>
|
>
|
||||||
<img src="/images/icon-copy.svg" alt="copy icon" />
|
<img src="/images/icon-copy.svg" alt="copy icon" />
|
||||||
{{ $t('stocklist.action-copy') }}
|
{{ $t('stocklist.action-copy') }}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
class="btn btn--image"
|
class="btn btn--image"
|
||||||
:data-disabled="stockIsEmpty"
|
:data-disabled="stockIsEmpty"
|
||||||
:disabled="stockIsEmpty"
|
:disabled="stockIsEmpty"
|
||||||
@click="resetStock"
|
@click="resetStock"
|
||||||
>
|
>
|
||||||
<img src="/images/icon-reset.svg" alt="reset icon" />
|
<img src="/images/icon-reset.svg" alt="reset icon" />
|
||||||
{{ $t('stocklist.action-reset') }}
|
{{ $t('stocklist.action-reset') }}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
class="btn btn--image"
|
class="btn btn--image"
|
||||||
:data-disabled="stockIsEmpty"
|
:data-disabled="stockIsEmpty"
|
||||||
:disabled="stockIsEmpty"
|
:disabled="stockIsEmpty"
|
||||||
@click="shuffleCars"
|
@click="shuffleCars"
|
||||||
>
|
>
|
||||||
<img src="/images/icon-shuffle.svg" alt="shuffle icon" />
|
<img src="/images/icon-shuffle.svg" alt="shuffle icon" />
|
||||||
{{ $t('stocklist.action-shuffle') }}
|
{{ $t('stocklist.action-shuffle') }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="stock_controls" :data-disabled="store.chosenStockListIndex == -1">
|
<div class="stock_controls" :data-disabled="store.chosenStockListIndex == -1">
|
||||||
<button
|
<button
|
||||||
class="btn btn--image"
|
class="btn btn--image"
|
||||||
:tabindex="store.chosenStockListIndex == -1 ? -1 : 0"
|
:tabindex="store.chosenStockListIndex == -1 ? -1 : 0"
|
||||||
@click="moveUpStock(store.chosenStockListIndex)"
|
@click="moveUpStock(store.chosenStockListIndex)"
|
||||||
>
|
>
|
||||||
<img :src="getIconURL('higher')" alt="move up vehicle" />
|
<img :src="getIconURL('higher')" alt="move up vehicle" />
|
||||||
{{ $t('stocklist.action-move-up') }}
|
{{ $t('stocklist.action-move-up') }}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
class="btn btn--image"
|
class="btn btn--image"
|
||||||
:tabindex="store.chosenStockListIndex == -1 ? -1 : 0"
|
:tabindex="store.chosenStockListIndex == -1 ? -1 : 0"
|
||||||
@click="moveDownStock(store.chosenStockListIndex)"
|
@click="moveDownStock(store.chosenStockListIndex)"
|
||||||
>
|
>
|
||||||
<img :src="getIconURL('lower')" alt="move down vehicle" />
|
<img :src="getIconURL('lower')" alt="move down vehicle" />
|
||||||
{{ $t('stocklist.action-move-down') }}
|
{{ $t('stocklist.action-move-down') }}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
class="btn btn--image"
|
class="btn btn--image"
|
||||||
:tabindex="store.chosenStockListIndex == -1 ? -1 : 0"
|
:tabindex="store.chosenStockListIndex == -1 ? -1 : 0"
|
||||||
@click="removeStock(store.chosenStockListIndex)"
|
@click="removeStock(store.chosenStockListIndex)"
|
||||||
>
|
>
|
||||||
<img :src="getIconURL('remove')" alt="remove vehicle" />
|
<img :src="getIconURL('remove')" alt="remove vehicle" />
|
||||||
{{ $t('stocklist.action-remove') }}
|
{{ $t('stocklist.action-remove') }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="stock_specs">
|
<div class="stock_specs">
|
||||||
<b class="real-stock-info" v-if="chosenRealComposition">
|
<b class="real-stock-info" v-if="chosenRealComposition">
|
||||||
<span class="text--accent">
|
<span class="text--accent">
|
||||||
<img :src="getIconURL(chosenRealComposition.type)" :alt="chosenRealComposition.type" />
|
<img :src="getIconURL(chosenRealComposition.type)" :alt="chosenRealComposition.type" />
|
||||||
{{ chosenRealComposition.number }} {{ chosenRealComposition.name }}
|
{{ chosenRealComposition.number }} {{ chosenRealComposition.name }}
|
||||||
|
</span>
|
||||||
|
|
|
||||||
|
</b>
|
||||||
|
|
||||||
|
<span>
|
||||||
|
{{ $t('stocklist.mass') }}
|
||||||
|
<span class="text--accent">{{ (store.totalWeight / 1000).toFixed(1) }}t</span>
|
||||||
|
({{ $t('stocklist.mass-accepted') }}:
|
||||||
|
<span class="text--accent">{{
|
||||||
|
store.acceptableWeight ? `${~~(store.acceptableWeight / 1000)}t` : '-'
|
||||||
|
}}</span
|
||||||
|
>) - {{ $t('stocklist.length') }}:
|
||||||
|
<span class="text--accent">{{ store.totalLength }}m</span>
|
||||||
|
- {{ $t('stocklist.vmax') }}
|
||||||
|
<span tabindex="0" :data-tooltip="$t('stocklist.disclaimer')">(?)</span>:
|
||||||
|
<span class="text--accent">{{ store.maxStockSpeed }} km/h</span>
|
||||||
</span>
|
</span>
|
||||||
|
|
|
||||||
</b>
|
|
||||||
|
|
||||||
<span>
|
|
||||||
{{ $t('stocklist.mass') }}
|
|
||||||
<span class="text--accent">{{ (store.totalWeight / 1000).toFixed(1) }}t</span>
|
|
||||||
({{ $t('stocklist.mass-accepted') }}:
|
|
||||||
<span class="text--accent">{{
|
|
||||||
store.acceptableWeight ? `${~~(store.acceptableWeight / 1000)}t` : '-'
|
|
||||||
}}</span
|
|
||||||
>) - {{ $t('stocklist.length') }}:
|
|
||||||
<span class="text--accent">{{ store.totalLength }}m</span>
|
|
||||||
- {{ $t('stocklist.vmax') }}
|
|
||||||
<span tabindex="0" :data-tooltip="$t('stocklist.disclaimer')">(?)</span>:
|
|
||||||
<span class="text--accent">{{ store.maxStockSpeed }} km/h</span>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="stock_spawn-settings">
|
|
||||||
<Checkbox v-if="store.stockSupportsColdStart" v-model="store.isColdStart">
|
|
||||||
{{ $t('stocklist.coldstart-info') }}
|
|
||||||
</Checkbox>
|
|
||||||
|
|
||||||
<Checkbox v-if="store.stockSupportsDoubleManning" v-model="store.isDoubleManned">
|
|
||||||
{{ $t('stocklist.doublemanning-info') }}
|
|
||||||
</Checkbox>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="stock_warnings" v-if="hasAnyWarnings">
|
|
||||||
<div class="warning" v-if="locoNotSuitable">
|
|
||||||
(!) {{ $t('stocklist.warning-not-suitable') }}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="warning" v-if="lengthExceeded && store.isTrainPassenger">
|
<div></div>
|
||||||
(!) {{ $t('stocklist.warning-passenger-too-long') }}
|
|
||||||
|
<div class="stock_spawn-settings">
|
||||||
|
<Checkbox :disabled="!store.stockSupportsColdStart" v-model="store.isColdStart">
|
||||||
|
{{ $t('stocklist.coldstart-info') }}
|
||||||
|
</Checkbox>
|
||||||
|
|
||||||
|
<Checkbox :disabled="!store.stockSupportsDoubleManning" v-model="store.isDoubleManned">
|
||||||
|
{{ $t('stocklist.doublemanning-info') }}
|
||||||
|
</Checkbox>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="warning" v-if="lengthExceeded && !store.isTrainPassenger">
|
<div class="stock_warnings" v-if="hasAnyWarnings">
|
||||||
(!) {{ $t('stocklist.warning-freight-too-long') }}
|
<div class="warning" v-if="locoNotSuitable">
|
||||||
</div>
|
(!) {{ $t('stocklist.warning-not-suitable') }}
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="warning" v-if="teamOnlyVehicles.length > 0">
|
<div class="warning" v-if="lengthExceeded && store.isTrainPassenger">
|
||||||
(!)
|
(!) {{ $t('stocklist.warning-passenger-too-long') }}
|
||||||
{{
|
</div>
|
||||||
$t('stocklist.warning-team-only-vehicle', [
|
|
||||||
teamOnlyVehicles.map((v) => v.vehicleRef.type).join(', '),
|
|
||||||
])
|
|
||||||
}}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="warning" v-if="weightExceeded">
|
<div class="warning" v-if="lengthExceeded && !store.isTrainPassenger">
|
||||||
(!)
|
(!) {{ $t('stocklist.warning-freight-too-long') }}
|
||||||
<i18n-t keypath="stocklist.warning-too-heavy">
|
</div>
|
||||||
<template #href>
|
|
||||||
<a
|
|
||||||
target="_blank"
|
|
||||||
href="https://docs.google.com/spreadsheets/d/1KVa5vn2d8XGkXQFwbavVudwKqUQxbLOucHWs2VYqAUE"
|
|
||||||
>
|
|
||||||
{{ $t('stocklist.acceptable-mass-docs') }}
|
|
||||||
</a>
|
|
||||||
</template>
|
|
||||||
</i18n-t>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="warning" v-if="locoCountExceeded">
|
<div class="warning" v-if="teamOnlyVehicles.length > 0">
|
||||||
{{ $t('stocklist.warning-too-many-locos') }}
|
(!)
|
||||||
</div>
|
{{
|
||||||
</div>
|
$t('stocklist.warning-team-only-vehicle', [
|
||||||
|
teamOnlyVehicles.map((v) => v.vehicleRef.type).join(', '),
|
||||||
|
])
|
||||||
|
}}
|
||||||
|
</div>
|
||||||
|
|
||||||
<StockThumbnails :onListItemClick="onListItemClick" />
|
<div class="warning" v-if="weightExceeded">
|
||||||
|
(!)
|
||||||
<!-- Stock list -->
|
<i18n-t keypath="stocklist.warning-too-heavy">
|
||||||
<div class="list-wrapper">
|
<template #href>
|
||||||
<div v-if="stockIsEmpty" class="list-empty">
|
<a
|
||||||
<div class="stock-info">{{ $t('stocklist.list-empty') }}</div>
|
target="_blank"
|
||||||
</div>
|
href="https://docs.google.com/spreadsheets/d/1KVa5vn2d8XGkXQFwbavVudwKqUQxbLOucHWs2VYqAUE"
|
||||||
|
|
||||||
<ul v-else>
|
|
||||||
<transition-group name="stock-list-anim">
|
|
||||||
<li
|
|
||||||
v-for="(stock, i) in store.stockList"
|
|
||||||
:key="stock.id"
|
|
||||||
:class="{ loco: isTractionUnit(stock.vehicleRef) }"
|
|
||||||
tabindex="0"
|
|
||||||
@click="onListItemClick(i)"
|
|
||||||
@keydown.enter="onListItemClick(i)"
|
|
||||||
@keydown.w="moveUpStock(i)"
|
|
||||||
@keydown.s="moveDownStock(i)"
|
|
||||||
@keydown.backspace="removeStock(i)"
|
|
||||||
ref="itemRefs"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="stock-info"
|
|
||||||
@dragstart="onDragStart(i)"
|
|
||||||
@drop="onDrop($event, i)"
|
|
||||||
@dragover="allowDrop"
|
|
||||||
draggable="true"
|
|
||||||
>
|
|
||||||
<span class="stock-info-no" :data-selected="i == store.chosenStockListIndex">
|
|
||||||
<span v-if="i == store.chosenStockListIndex">• </span>
|
|
||||||
{{ i + 1 }}.
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<span
|
|
||||||
class="stock-info-type"
|
|
||||||
:data-sponsor-only="
|
|
||||||
stock.vehicleRef.sponsorOnlyTimestamp &&
|
|
||||||
stock.vehicleRef.sponsorOnlyTimestamp > Date.now()
|
|
||||||
"
|
|
||||||
:data-team-only="stock.vehicleRef.teamOnly"
|
|
||||||
>
|
>
|
||||||
{{
|
{{ $t('stocklist.acceptable-mass-docs') }}
|
||||||
isTractionUnit(stock.vehicleRef)
|
</a>
|
||||||
? stock.vehicleRef.type
|
</template>
|
||||||
: getCarSpecFromType(stock.vehicleRef.type)
|
</i18n-t>
|
||||||
}}
|
</div>
|
||||||
</span>
|
|
||||||
|
|
||||||
<span class="stock-info-cargo" v-if="stock.cargo">
|
<div class="warning" v-if="locoCountExceeded">
|
||||||
{{ stock.cargo.id }}
|
{{ $t('stocklist.warning-too-many-locos') }}
|
||||||
</span>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<span class="stock-info-length">{{ stock.vehicleRef.length }}m</span>
|
<StockThumbnails :onListItemClick="onListItemClick" />
|
||||||
|
|
||||||
<span class="stock-info-mass">
|
<!-- Stock list -->
|
||||||
{{ ((stock.vehicleRef.weight + (stock.cargo?.weight ?? 0)) / 1000).toFixed(1) }}t
|
<div class="list-wrapper">
|
||||||
</span>
|
<div v-if="stockIsEmpty" class="list-empty">
|
||||||
<span class="stock-info-speed">{{ stock.vehicleRef.maxSpeed }}km/h</span>
|
<div class="stock-info">{{ $t('stocklist.list-empty') }}</div>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
|
||||||
</transition-group>
|
<ul v-else>
|
||||||
</ul>
|
<transition-group name="stock-list-anim">
|
||||||
|
<li
|
||||||
|
v-for="(stock, i) in store.stockList"
|
||||||
|
:key="stock.id"
|
||||||
|
:class="{ loco: isTractionUnit(stock.vehicleRef) }"
|
||||||
|
tabindex="0"
|
||||||
|
@click="onListItemClick(i)"
|
||||||
|
@keydown.enter="onListItemClick(i)"
|
||||||
|
@keydown.w="moveUpStock(i)"
|
||||||
|
@keydown.s="moveDownStock(i)"
|
||||||
|
@keydown.backspace="removeStock(i)"
|
||||||
|
ref="itemRefs"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="stock-info"
|
||||||
|
@dragstart="onDragStart(i)"
|
||||||
|
@drop="onDrop($event, i)"
|
||||||
|
@dragover="allowDrop"
|
||||||
|
draggable="true"
|
||||||
|
>
|
||||||
|
<span class="stock-info-no" :data-selected="i == store.chosenStockListIndex">
|
||||||
|
<span v-if="i == store.chosenStockListIndex">• </span>
|
||||||
|
{{ i + 1 }}.
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<span
|
||||||
|
class="stock-info-type"
|
||||||
|
:data-sponsor-only="
|
||||||
|
stock.vehicleRef.sponsorOnlyTimestamp &&
|
||||||
|
stock.vehicleRef.sponsorOnlyTimestamp > Date.now()
|
||||||
|
"
|
||||||
|
:data-team-only="stock.vehicleRef.teamOnly"
|
||||||
|
>
|
||||||
|
{{
|
||||||
|
isTractionUnit(stock.vehicleRef)
|
||||||
|
? stock.vehicleRef.type
|
||||||
|
: getCarSpecFromType(stock.vehicleRef.type)
|
||||||
|
}}
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<span class="stock-info-cargo" v-if="stock.cargo">
|
||||||
|
{{ stock.cargo.id }}
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<span class="stock-info-length">{{ stock.vehicleRef.length }}m</span>
|
||||||
|
|
||||||
|
<span class="stock-info-mass">
|
||||||
|
{{ ((stock.vehicleRef.weight + (stock.cargo?.weight ?? 0)) / 1000).toFixed(1) }}t
|
||||||
|
</span>
|
||||||
|
<span class="stock-info-speed">{{ stock.vehicleRef.maxSpeed }}km/h</span>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</transition-group>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</template>
|
</template>
|
||||||
@@ -520,11 +524,10 @@ export default defineComponent({
|
|||||||
@import '../../styles/global';
|
@import '../../styles/global';
|
||||||
@import '../../styles/tab.scss';
|
@import '../../styles/tab.scss';
|
||||||
|
|
||||||
.stock-list-tab {
|
.tab_content {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 0.5em;
|
gap: 0.5em;
|
||||||
position: relative;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.warning {
|
.warning {
|
||||||
|
|||||||
@@ -97,6 +97,7 @@ const allowDrop = (e: DragEvent) => {
|
|||||||
display: flex;
|
display: flex;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
background-color: #353a57;
|
background-color: #353a57;
|
||||||
|
min-height: 100px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.thumbnail-item {
|
.thumbnail-item {
|
||||||
|
|||||||
Reference in New Issue
Block a user