refactor: order list & order message logic for new data

This commit is contained in:
2025-09-29 19:30:30 +02:00
parent 7784e08f03
commit a0a5e72701
6 changed files with 184 additions and 185 deletions
+56 -57
View File
@@ -1,10 +1,10 @@
<template>
<section class="order-list">
<h3>{{ $t('order-list.title') }} ({{ localOrderList.length }})</h3>
<h3>{{ t('order-list.title') }} ({{ storageOrderList.length }})</h3>
<transition-group name="list" tag="ul">
<li class="no-orders-warning" v-if="sortedOrderList.length == 0" :key="-1">
{{ $t('order-list.no-saved-orders') }}
{{ t('order-list.no-saved-orders') }}
</li>
<li
@@ -15,10 +15,9 @@
<b class="text--accent">#{{ order.id.split('-')[1] }}&nbsp;</b>
<b>
{{
$t('order-list.order-title', {
orderName: getOrderName(order.orderType),
orderNo: order.orderBody['header']['orderNo'],
trainNo: order.orderBody['header']['trainNo']
t('order-list.order-title', {
id: order.id,
trainNo: order.orderData.header.A
})
}}
</b>
@@ -26,21 +25,21 @@
v-if="!order.orderVersion || order.orderVersion != ORDER_VERSION"
class="wrong-order-indicator"
tabindex="0"
data-tooltip="Przestarzała wersja rozkazu! Może generować złe informacje!"
:data-tooltip="t('order-list.warning-deprecated-version')"
>&#9888;
</span>
<br />
{{ $t(`order-list.order-${order.createdAt ? 'added' : 'updated'}`) }}
{{ t(`order-list.order-${order.createdAt ? 'added' : 'updated'}`) }}
{{ new Date(order.createdAt || order.updatedAt || 0).toLocaleString('pl-PL') }}
<hr />
<div class="buttons">
<button class="g-button" @click="selectLocalOrder(order)">
{{ $t('order-list.button-order-select') }}
{{ t('order-list.button-order-select') }}
</button>
<button class="g-button" @click="removeOrder(order)">
{{ $t('order-list.button-order-remove') }}
<button class="g-button" @click="removeOrder(order.id)">
{{ t('order-list.button-order-remove') }}
</button>
</div>
</li>
@@ -48,68 +47,68 @@
</section>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import orderStorageMixin from '../mixins/orderStorageMixin';
<script lang="ts" setup>
import { computed, onActivated, Reactive, reactive } from 'vue';
import { useStore } from '../store/store';
import { LocalStorageOrderLegacy } from '../types/orderTypes';
import { IStorageOrderData, LocalStorageOrderLegacy } from '../types/orderTypes';
import StorageManager from '../managers/storageManager';
import { useI18n } from 'vue-i18n';
export default defineComponent({
name: 'OrderList',
mixins: [orderStorageMixin],
const { t } = useI18n();
const store = useStore();
const storageOrderList = reactive<Reactive<IStorageOrderData[]>>([]);
data() {
return {
localOrderList: [] as LocalStorageOrderLegacy[],
ORDER_VERSION: import.meta.env['VITE_APP_ORDER_VERSION']
};
},
const ORDER_VERSION = import.meta.env['VITE_APP_ORDER_VERSION'];
setup() {
return {
store: useStore(),
localStorage: window.localStorage
};
},
function removeOrder(orderId: string) {
StorageManager.removeValue(orderId);
methods: {
getOrderName(orderType: string) {
return orderType.split('order')[1];
},
if (store.chosenLocalOrderId == orderId) store.chosenLocalOrderId = '';
storageOrderList.splice(storageOrderList.findIndex((o) => o.id == orderId));
removeOrder(order: LocalStorageOrderLegacy) {
if (!order) return;
if (storageOrderList.length == 0) StorageManager.setNumericValue('orderCount', 0);
}
this.removeLocalOrder(order);
this.localOrderList = this.localOrderList.filter((o) => o.id != order.id);
function selectLocalOrder(order: IStorageOrderData) {
store.orderData = order.orderData;
}
if (this.localOrderList.length == 0) this.saveOrderSetting('orderCount', 0);
}
},
function isOrderDeprecated(
order: IStorageOrderData | LocalStorageOrderLegacy
): order is LocalStorageOrderLegacy {
return 'orderType' in order;
}
computed: {
sortedOrderList() {
return this.localOrderList
.slice()
.sort((a, b) => (b.createdAt || b.updatedAt!) - (a.createdAt || a.updatedAt!));
}
},
const sortedOrderList = computed(() => {
return storageOrderList
.slice()
.sort((a, b) => (b.createdAt || b.updatedAt || 0) - (a.createdAt || a.updatedAt || 0));
});
activated() {
const localStorage = window.localStorage;
const orderList = [];
onActivated(() => {
const localStorage = window.localStorage;
const orderList = [];
for (let key in localStorage) {
if (!/^order-/g.test(key)) continue;
let deprecatedOrders = 0;
const orderObj: LocalStorageOrderLegacy = JSON.parse(localStorage[key]);
if (!orderObj) continue;
for (let key in localStorage) {
if (!/^order-/g.test(key)) continue;
orderList.push(orderObj);
const orderObj: IStorageOrderData | LocalStorageOrderLegacy = JSON.parse(localStorage[key]);
if (!orderObj) continue;
if (isOrderDeprecated(orderObj)) {
console.warn(`Deprecated order found with ID: ${orderObj.id}`);
continue;
}
this.localOrderList = orderList;
orderList.push(orderObj);
}
if (deprecatedOrders != 0) {
}
storageOrderList.push(...orderList);
});
</script>
+118 -103
View File
@@ -62,25 +62,44 @@
</div>
<transition name="monit-anim">
<div class="action_monit" v-if="actionMonit" v-html="actionMonit"></div>
<div
class="action_monit"
v-if="actionMonit.content"
v-html="actionMonit.content"
:class="{
'text--warn': actionMonit.type == 'warning'
}"
></div>
</transition>
</section>
</template>
<script lang="ts" setup>
import { computed, onMounted, ref, watch } from 'vue';
import { computed, onMounted, Reactive, reactive, ref, watch } from 'vue';
import { useStore } from '../store/store';
import { currentFormattedHours, currentFormattedMinutes } from '../utils/dateUtils';
import StorageManager from '../managers/storageManager';
import { LocalStorageOrderLegacy } from '../types/orderTypes';
import { useI18n } from 'vue-i18n';
import StorageManager from '../managers/storageManager';
import { currentFormattedHours, currentFormattedMinutes } from '../utils/dateUtils';
import { IStorageOrderData } from '../types/orderTypes';
type TActionMonitType = 'warning' | 'info' | 'success';
interface IActionMonit {
type: TActionMonitType;
content: string;
timeoutId: number | null;
}
const { t } = useI18n();
const store = useStore();
const actionMonit = ref('');
const monitTimeout = ref(0);
const actionMonit: Reactive<IActionMonit> = reactive({
visible: false,
type: 'info',
content: '',
timeoutId: null
});
const incrementOnSave = ref(true);
const incrementOnCopy = ref(true);
@@ -106,137 +125,135 @@ function onCheckboxChange(e: Event) {
StorageManager.setBooleanValue(checkbox.id, checkbox.checked);
}
function showActionMonit(text: string) {
if (monitTimeout.value) {
actionMonit.value = '';
clearTimeout(monitTimeout.value);
function showActionMonit(content: string, type: TActionMonitType) {
if (actionMonit.timeoutId != null) {
actionMonit.content = '';
// setTimeout(() => {
actionMonit.value = text;
clearTimeout(actionMonit.timeoutId);
monitTimeout.value = window.setTimeout(() => {
actionMonit.value = '';
}, 5000);
// }, 300);
setTimeout(() => {
actionMonit.content = content;
actionMonit.type = type;
actionMonit.timeoutId = window.setTimeout(() => {
actionMonit.content = '';
actionMonit.timeoutId = null;
}, 5000);
}, 100);
return;
}
actionMonit.value = text;
actionMonit.content = content;
actionMonit.type = type;
monitTimeout.value = window.setTimeout(() => {
actionMonit.value = '';
actionMonit.timeoutId = window.setTimeout(() => {
actionMonit.content = '';
actionMonit.timeoutId = null;
}, 5000);
}
function verifyOrderFields() {
const { header, footer } = store.orderData;
const fieldsToCorrect: string[] = [];
Object.entries(header).forEach(([k, v]) => {
if (v.trim().length == 0) {
fieldsToCorrect.push(`order.header.${k}`);
}
});
Object.entries(footer).forEach(([k, v]) => {
if (v.trim().length == 0) {
fieldsToCorrect.push(`order.footer.${k}`);
}
});
return fieldsToCorrect;
}
// TODO
function incrementOrderNo() {
// store.orderData.header.
// order.header.orderNo = (Number(order.header.orderNo) + 1).toString();
// store.orderData. = (Number(order.header.orderNo) + 1).toString();
}
function copyMessage() {
if (!navigator.clipboard) return showActionMonit(t('order-message.warning-outdated-clipboard'));
if (!navigator.clipboard)
return showActionMonit(t('order-message.warning-outdated-clipboard'), 'warning');
const hasAtLeastOneRow = /(\[ \d \])/g.test(orderMessagePreview.value);
const hasAllInputsFilled = !/_/g.test(store.orderMessage);
// const hasAtLeastOneRow = /(\[ \d \])/g.test(orderMessagePreview.value);
// const hasAllInputsFilled = !/_/g.test(store.orderMessage);
if (!hasAllInputsFilled)
return showActionMonit(
`<span class="text--warn">${t('order-message.warning-fill-inputs')}</span>`
);
if (!hasAtLeastOneRow)
return showActionMonit(
`<span class="text--warn">${t('order-message.warning-add-rows')}</span>`
);
// if (!hasAllInputsFilled)
// return showActionMonit(
// `${t('order-message.warning-fill-inputs')}`
// );
// if (!hasAtLeastOneRow)
// return showActionMonit(
// `${t('order-message.warning-add-rows')}`
// );
const fieldsToCorrect = verifyOrderFields();
if (fieldsToCorrect.length > 0)
return showActionMonit(
`<span class="text--warn">${t('order-message.warning-fill-footer')} ${fieldsToCorrect.join(
', '
)}</span>`
`${t('order-message.warning-fill-footer')} ${fieldsToCorrect.join(', ')}`,
'warning'
);
navigator.clipboard.writeText(orderMessagePreview.value);
if (incrementOnCopy) incrementOrderNo();
showActionMonit(t('order-message.success-copy-html'));
}
function verifyOrderFields() {
// const header = this.store[this.store.chosenOrderType].header;
const footer = store.orderFooter;
const fieldsToCorrect = [];
// if (!header.orderNo) fieldsToCorrect.push('numer rozkazu');
// if (!header.trainNo) fieldsToCorrect.push('numer pociągu / manewru');
// if (!header.date) fieldsToCorrect.push('data');
if (!footer.stationName) fieldsToCorrect.push('stacja');
if (!footer.checkpointName) fieldsToCorrect.push('posterunek');
if (!footer.hour) fieldsToCorrect.push('godzina');
if (!footer.minutes) fieldsToCorrect.push('minuta');
if (!footer.dispatcherName && !footer.secondaryDispatcherName)
fieldsToCorrect.push('dyżurny ruchu (lub z polecenia dyżurnego ruchu)');
return fieldsToCorrect;
showActionMonit(t('order-message.success-copy-html'), 'success');
}
function saveOrder() {
const orderObj: LocalStorageOrderLegacy = {
id: '',
orderType: store.chosenOrderType,
orderBody: store[store.chosenOrderType],
orderFooter: store.orderFooter,
createdAt: Date.now(),
orderVersion: import.meta.env['VITE_APP_ORDER_VERSION'] || '3'
};
const noHeaderInfo = Object.values(store.orderData.header).some((v) => {
return v.trim().length == 0;
});
// const headerInfo = orderObj['orderBody']['header'];
// if (!headerInfo['orderNo']) return -1;
// if (!headerInfo['trainNo']) return -1;
// if (!headerInfo['date']) return -1;
// No header info: -1
// showActionMonit(`<span class="text--warn">${t('order-message.warning-fill-top')}</span>`)
const localStorage = window.localStorage;
const localOrderCount = localStorage.getItem('orderCount') || '0';
if (localOrderCount == '0') localStorage.setItem('orderCount', '0');
const prevLocalOrder = localStorage.getItem(`order-${Number(localOrderCount)}`);
if (prevLocalOrder && prevLocalOrder == JSON.stringify(orderObj)) {
showActionMonit(
`<span class="text--warn">${t('order-message.warning-order-identical')}</span>`
);
if (noHeaderInfo) {
showActionMonit(`${t('order-message.warning-fill-top')}`, 'warning');
return;
}
const nextOrderCount = Number(localOrderCount) + 1;
const orderId = `order-${nextOrderCount}`;
orderObj['id'] = orderId;
const orderDataToSave: IStorageOrderData = {
id: '',
createdAt: Date.now(),
orderVersion: import.meta.env['VITE_APP_ORDER_VERSION'] || '3',
orderData: store.orderData
};
const localStorage = window.localStorage;
const localOrderCount = StorageManager.getNumericValue('orderCount') || 0;
if (localOrderCount == 0) StorageManager.setNumericValue('orderCount', 0);
const prevLocalOrder = StorageManager.getValue(`order-${Number(localOrderCount)}`);
if (prevLocalOrder && prevLocalOrder == JSON.stringify(orderDataToSave)) {
showActionMonit(`${t('order-message.warning-order-identical')}`, 'warning');
return;
}
const nextOrderCount = localOrderCount + 1;
const nextOrderId = `order-${nextOrderCount}`;
orderDataToSave['id'] = nextOrderId;
localStorage.setItem('orderCount', `${nextOrderCount}`);
localStorage.setItem(orderId, JSON.stringify(orderObj));
localStorage.setItem(nextOrderId, JSON.stringify(orderDataToSave));
store.chosenLocalOrderId = orderId;
showActionMonit(t('order-message.success-save-html'));
store.chosenLocalOrderId = nextOrderId;
showActionMonit(t('order-message.success-save-html'), 'success');
if (incrementOnSave) incrementOrderNo();
}
function updateOrder() {
if (!store.chosenLocalOrderId) {
showActionMonit(
`<span class="text--warn">${t('order-message.warning-no-order-selected')}</span>`
);
showActionMonit(`${t('order-message.warning-no-order-selected')}`, 'warning');
return;
}
@@ -244,21 +261,19 @@ function updateOrder() {
const localOrder = window.localStorage.getItem(store.chosenLocalOrderId);
if (!localOrder) {
showActionMonit(`<span class="text--warn">${t('order-message.error-update')}</span>`);
showActionMonit(`${t('order-message.error-update')}`, 'warning');
return;
}
const orderObj: LocalStorageOrderLegacy = {
const orderDataToUpdate: IStorageOrderData = {
id: store.chosenLocalOrderId,
orderType: store.chosenOrderType,
orderBody: store[store.chosenOrderType],
orderFooter: store.orderFooter,
orderData: store.orderData,
updatedAt: Date.now(),
orderVersion: import.meta.env['VITE_APP_ORDER_VERSION'] || '1'
orderVersion: import.meta.env['VITE_APP_ORDER_VERSION'] || '3'
};
window.localStorage.setItem(store.chosenLocalOrderId, JSON.stringify(orderObj));
showActionMonit(t('order-message.success-update-html'));
window.localStorage.setItem(store.chosenLocalOrderId, JSON.stringify(orderDataToUpdate));
showActionMonit(t('order-message.success-update-html'), 'warning');
}
</script>
+4 -3
View File
@@ -27,7 +27,7 @@
"warning-fill-inputs": "Fill all the empty fields before copying the order!",
"warning-add-rows": "Add at least one row before copying the order!",
"warning-fill-footer": "Fill the following rows in the order's footer before copying it:",
"warning-fill-top": "Fill the order number, train number and date before saving it!",
"warning-fill-top": "Fill at least fields A, B, C and D in the order's header before saving it!",
"warning-order-identical": "Last saved order is identical as the current one!",
"warning-no-order-selected": "Choose the already saved order first!",
"error-update": "An error occurred while saving this order! :/",
@@ -52,12 +52,13 @@
},
"order-list": {
"title": "Saved train orders",
"order-title": "Order \"{orderName}\" no. {orderNo} for train no. {trainNo}",
"order-title": "Order #{id} for train no. {trainNo}",
"no-saved-orders": "No saved orders!",
"order-added": "Added:",
"order-updated": "Updated:",
"button-order-select": "Select",
"button-order-remove": "Remove"
"button-order-remove": "Remove",
"warning-deprecated-version": "Deprecated version of the order - may generate incorrect information!"
},
"order-train-picker": {
"placeholder-scenery-name": "Scenery name",
+4 -3
View File
@@ -27,7 +27,7 @@
"warning-fill-inputs": "Wypełnij puste rubryki rozkazu przed jego skopiowaniem!",
"warning-add-rows": "Dodaj co najmniej jedną działkę rozkazu przed jego skopiowaniem!",
"warning-fill-footer": "Uzupełnij następujące rubryki na dole rozkazu przed jego skopiowaniem:",
"warning-fill-top": "Wypełnij numer rozkazu, numer pociągu i datę zanim dodasz rozkaz!",
"warning-fill-top": "Wypełnij co najmniej rubryki A, B, C i D w nagłówku rozkazu przed jego zapisaniem!",
"warning-order-identical": "Ostatni zapisany rozkaz jest identyczny z obecnym!",
"warning-no-order-selected": "Wybierz rozkaz, który chcesz zaktualizować!",
"error-update": "Wystąpił błąd podczas aktualizowania tego rozkazu! :/",
@@ -53,11 +53,12 @@
"order-list": {
"title": "Zapisane rozkazy pisemne",
"no-saved-orders": "Brak zapisanych rozkazów!",
"order-title": "Rozkaz \"{orderName}\" nr {orderNo} dla pociągu nr {trainNo}",
"order-title": "Rozkaz pisemny #{id} dla pociągu nr {trainNo}",
"order-added": "Dodano:",
"order-updated": "Zaktualizowano:",
"button-order-select": "Wybierz",
"button-order-remove": "Usuń"
"button-order-remove": "Usuń",
"warning-deprecated-version": "Przestarzała wersja rozkazu! Może generować złe informacje!"
},
"order-train-picker": {
"placeholder-scenery-name": "Sceneria",
+1 -18
View File
@@ -32,21 +32,4 @@ export interface ISceneryData {
routes: string;
signalType: string;
url: string;
}
// export interface ITrainData {
// trainNo: number;
// driverId: number;
// driverName: string;
// driverIsSupporter: boolean;
// dataSignal: string;
// dataSceneryConnection: string;
// dataDistance: number;
// dataCon: string;
// dataSpeed: number;
// dataMass: number;
// dataLength: number;
// region: string;
// isOnline: number;
// lastSeen: number;
// station?: ISceneryData;
// }
}
+1 -1
View File
@@ -13,7 +13,7 @@ export interface LocalStorageOrderLegacy {
export interface IStorageOrderData {
id: string;
orderVersion: string;
createdAt: number;
createdAt?: number;
updatedAt?: number;
orderData: IOrderData;
}