-
-
-
-
-
+
+
-
-
-
+
+
+
+
+
-
-
-
-
-
- {{ $t(`wiki.header.${header.id}`) }}
+
+ -
+
-
- {{ currentSorter.direction == 1 ? `⇑` : `⇓` }}
-
- |
-
-
-
-
-
+
-
-
- |
+ {{ vehicle.type.replace(/_/g, ' ') }}
+
-
- {{ vehicle.type.replace(/_/g, ' ') }}
- |
+
+ {{ $t(`wiki.${vehicle.group}`) }} |
+ {{ isTractionUnit(vehicle) ? vehicle.cabinType : vehicle.constructionType }}
+
- {{ $t(`wiki.${vehicle.group}`) }} |
- {{ vehicle.constructionType }} |
- {{ vehicle.length }} |
- {{ (vehicle.weight / 1000).toFixed(1) }} |
- {{ vehicle.maxSpeed }} |
-
-
-
-
-
-
+
+ {{ vehicle.length }}m | {{ (vehicle.weight / 1000).toFixed(1) }}t |
+ {{ vehicle.maxSpeed }}km/h
+
+
+
+
@@ -89,40 +92,13 @@ import { isTractionUnit } from '../../utils/vehicleUtils';
import stockMixin from '../../mixins/stockMixin';
import imageMixin from '../../mixins/imageMixin';
-type SorterID =
- | 'type'
- | 'constructionType'
- | 'image'
- | 'length'
- | 'weight'
- | 'maxSpeed'
- | 'cargoCount'
- | 'group'
- | 'coldStart';
+const sorters = ['type', 'group', 'length', 'weight', 'maxSpeed'] as const;
+const filters = ['vehicles-all', 'vehicles-traction', 'vehicles-wagon'] as const;
-interface IWikiHeader {
- id: SorterID;
- sortable: boolean;
- for: 'all' | 'carriages' | 'tractions';
-}
+type SorterType = (typeof sorters)[number];
+type SorterDirection = 'asc' | 'desc';
-interface IWikiRow {
- vehicle: IVehicle;
- show: boolean;
- showImage: boolean;
-}
-
-const headers: IWikiHeader[] = [
- { id: 'image', sortable: false, for: 'all' },
- { id: 'type', sortable: true, for: 'all' },
- { id: 'group', sortable: true, for: 'all' },
- { id: 'constructionType', sortable: true, for: 'all' },
- { id: 'length', sortable: true, for: 'all' },
- { id: 'weight', sortable: true, for: 'all' },
- { id: 'maxSpeed', sortable: true, for: 'all' },
- // { id: 'coldStart', sortable: true, for: 'tractions' },
- // { id: 'cargoCount', sortable: true, for: 'carriages' },
-];
+type FilterType = (typeof filters)[number];
export default defineComponent({
mixins: [stockPreviewMixin, stockMixin, imageMixin],
@@ -131,141 +107,103 @@ export default defineComponent({
return {
store: useStore(),
observer: null as IntersectionObserver | null,
- headers,
- scrollTop: 0,
+ sorters: sorters,
+ filters: filters,
searchedVehicleTypeName: '',
- currentSorter: {
- id: 'type' as SorterID,
- direction: 1,
- },
+ sorterType: 'type' as SorterType,
+ sorterDirection: 'asc' as SorterDirection,
- currentFilterMode: 'all' as 'all' | 'tractions' | 'carriages',
+ filterType: 'vehicles-all' as FilterType,
+
+ lastScrollTop: 0,
};
},
- mounted() {
- this.mountObserver();
+ deactivated() {
+ this.lastScrollTop = (this.$refs['vehicles'] as HTMLUListElement)?.scrollTop || 0;
},
activated() {
- const tableWrapperRef = this.$refs['table-wrapper'] as HTMLElement;
+ (this.$refs['vehicles'] as HTMLUListElement)?.scrollTo({ top: this.lastScrollTop });
+ },
- tableWrapperRef.scrollTo({
- top: this.scrollTop,
- });
+ watch: {
+ computedVehicles() {
+ const vehiclesRef = this.$refs['vehicles'] as HTMLElement;
+
+ vehiclesRef.scrollTo({
+ top: 0,
+ });
+ },
},
methods: {
isTractionUnit,
- mountObserver() {
- if (this.observer) return;
-
- this.observer = new IntersectionObserver((entries) => {
- entries.forEach((entry) => {
- if (entry.intersectionRatio > 0) {
- entry.target
- .querySelector('td:first-child > img')!
- .setAttribute(
- 'src',
- entry.target.querySelector('td:first-child > img')!.getAttribute('data-src')!
- );
- }
- });
- });
-
- (this.$refs['itemRefs'] as HTMLElement[]).forEach((el) => this.observer?.observe(el));
+ onVehicleSelect(vehicle: IVehicle) {
+ if (this.store.chosenVehicle?.type === vehicle.type) this.addVehicle(vehicle);
+ this.previewVehicle(vehicle);
},
- toggleFilter(name: typeof this.currentFilterMode) {
- this.currentFilterMode = this.currentFilterMode == name ? 'all' : name;
- const tableWrapperRef = this.$refs['table-wrapper'] as HTMLElement;
+ filterVehicles(v: IVehicle) {
+ if (this.searchedVehicleTypeName)
+ return v.type
+ .toLocaleLowerCase()
+ .includes(this.searchedVehicleTypeName.toLocaleLowerCase());
- tableWrapperRef.scrollTo({
- top: this.scrollTop,
- });
+ switch (this.filterType) {
+ case 'vehicles-all':
+ return true;
+ case 'vehicles-traction':
+ return isTractionUnit(v);
+ case 'vehicles-wagon':
+ return !isTractionUnit(v);
+
+ default:
+ return false;
+ }
},
- toggleSorter(header: IWikiHeader) {
- if (!header.sortable) return;
+ sortVehicles(v1: IVehicle, v2: IVehicle) {
+ const direction = this.sorterDirection == 'asc' ? 1 : -1;
- if (header.id == this.currentSorter.id) this.currentSorter.direction *= -1;
- this.currentSorter.id = header.id;
- },
-
- sortTableRows(row1: IWikiRow, row2: IWikiRow) {
- if (!row1.show) return 0;
-
- const { id, direction } = this.currentSorter;
-
- switch (id) {
+ switch (this.sorterType) {
case 'type':
- case 'constructionType':
case 'group':
- return direction == 1
- ? row1.vehicle[id].localeCompare(row2.vehicle[id])
- : row2.vehicle[id].localeCompare(row1.vehicle[id]);
+ return direction * v1[this.sorterType].localeCompare(v2[this.sorterType]);
case 'weight':
case 'length':
case 'maxSpeed':
- return Math.sign(row1.vehicle[id] - row2.vehicle[id]) * direction;
+ return Math.sign(v1[this.sorterType] - v2[this.sorterType]) * direction;
- case 'cargoCount':
- return (
- Math.sign(
- (!isTractionUnit(row1.vehicle) ? row1.vehicle.cargoTypes.length || -1 : -1) -
- (!isTractionUnit(row2.vehicle) ? row2.vehicle.cargoTypes.length || -1 : -1)
- ) * direction
- );
+ // case 'cargoCount':
+ // return (
+ // Math.sign(
+ // (!isTractionUnit(v1) ? v1.cargoTypes.length || -1 : -1) -
+ // (!isTractionUnit(row2.vehicle) ? row2.vehicle.cargoTypes.length || -1 : -1)
+ // ) * direction
+ // );
- case 'coldStart':
- return (
- ((isTractionUnit(row1.vehicle) && row1.vehicle.coldStart ? 1 : -1) -
- (isTractionUnit(row2.vehicle) && row2.vehicle.coldStart ? 1 : -1)) *
- direction
- );
+ // case 'coldStart':
+ // return (
+ // ((isTractionUnit(v1) && v1.coldStart ? 1 : -1) -
+ // (isTractionUnit(row2.vehicle) && row2.vehicle.coldStart ? 1 : -1)) *
+ // direction
+ // );
default:
- break;
+ return v1.type.localeCompare(v2.type) * direction;
}
-
- return direction == 1
- ? row1.vehicle.type.localeCompare(row2.vehicle.type)
- : row2.vehicle.type.localeCompare(row1.vehicle.type);
},
},
computed: {
- computedTableData(): IWikiRow[] {
- return this.store.vehicleDataList
- .map((vehicle) => ({
- vehicle,
- showImage: false,
- show:
- new RegExp(`${this.searchedVehicleTypeName.trim()}`, 'i').test(vehicle.type) &&
- (this.currentFilterMode == 'all' ||
- (this.currentFilterMode == 'tractions' && isTractionUnit(vehicle)) ||
- (this.currentFilterMode == 'carriages' && !isTractionUnit(vehicle))),
- }))
- .sort((a, b) => this.sortTableRows(a, b));
- },
-
- visibleHeaders() {
- const filtersActive = this.currentFilterMode;
-
- return this.headers.filter((header) => header.for == 'all' || header.for == filtersActive);
- },
-
- areTractionVehiclesShown() {
- return this.currentFilterMode == 'all' || this.currentFilterMode == 'tractions';
- },
-
- areCarriagesShown() {
- return this.currentFilterMode == 'all' || this.currentFilterMode == 'carriages';
+ computedVehicles() {
+ return this.store.vehicleDataList.filter(this.filterVehicles).sort(this.sortVehicles);
},
},
});
@@ -274,99 +212,84 @@ export default defineComponent({