fix : page de modification reception qui crash en prod
This commit is contained in:
@@ -48,8 +48,38 @@ const emit = defineEmits<{
|
|||||||
const bovineTypes = ref<BovineTypeData[]>([])
|
const bovineTypes = ref<BovineTypeData[]>([])
|
||||||
const localQuantities = reactive<Record<string, number | null>>({})
|
const localQuantities = reactive<Record<string, number | null>>({})
|
||||||
const localOtherQuantity = ref<number | null>(props.otherQuantity ?? 0)
|
const localOtherQuantity = ref<number | null>(props.otherQuantity ?? 0)
|
||||||
|
// Verrou pour éviter les boucles props -> local -> emit -> props.
|
||||||
const isSyncing = ref(false)
|
const isSyncing = ref(false)
|
||||||
|
|
||||||
|
function entriesEqualByTypeAndQuantity(
|
||||||
|
left: ReceptionBovineTypeData[],
|
||||||
|
right: ReceptionBovineTypeData[]
|
||||||
|
): boolean {
|
||||||
|
const toMap = (entries: ReceptionBovineTypeData[]) => {
|
||||||
|
const map = new Map<number, number>()
|
||||||
|
for (const entry of entries) {
|
||||||
|
const typeId = entry.bovineType?.id ?? 0
|
||||||
|
map.set(typeId, entry.quantity ?? 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
return map
|
||||||
|
}
|
||||||
|
|
||||||
|
const a = toMap(left)
|
||||||
|
const b = toMap(right)
|
||||||
|
if (a.size !== b.size) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const [typeId, quantity] of a.entries()) {
|
||||||
|
if ((b.get(typeId) ?? 0) !== quantity) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
function buildEntriesFromLocal(): ReceptionBovineTypeData[] {
|
function buildEntriesFromLocal(): ReceptionBovineTypeData[] {
|
||||||
return bovineTypes.value.map((type) => {
|
return bovineTypes.value.map((type) => {
|
||||||
const existing = props.modelValue.find((entry) => entry.bovineType.id === type.id)
|
const existing = props.modelValue.find((entry) => entry.bovineType.id === type.id)
|
||||||
@@ -80,20 +110,33 @@ function syncLocalFromProps() {
|
|||||||
watch(
|
watch(
|
||||||
() => props.otherQuantity,
|
() => props.otherQuantity,
|
||||||
(value) => {
|
(value) => {
|
||||||
localOtherQuantity.value = value ?? 0
|
if (isSyncing.value) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const next = value ?? 0
|
||||||
|
isSyncing.value = true
|
||||||
|
localOtherQuantity.value = next
|
||||||
|
isSyncing.value = false
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
watch(localOtherQuantity, (value) => {
|
watch(localOtherQuantity, (value) => {
|
||||||
emit('update:otherQuantity', value ?? 0)
|
if (isSyncing.value) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const next = value ?? 0
|
||||||
|
emit('update:otherQuantity', next)
|
||||||
})
|
})
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => props.modelValue,
|
() => props.modelValue,
|
||||||
() => {
|
() => {
|
||||||
|
// Hydratation locale uniquement quand le parent change.
|
||||||
syncLocalFromProps()
|
syncLocalFromProps()
|
||||||
},
|
},
|
||||||
{ deep: true }
|
{ immediate: true }
|
||||||
)
|
)
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
@@ -102,7 +145,11 @@ watch(
|
|||||||
if (isSyncing.value) {
|
if (isSyncing.value) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
emit('update:modelValue', buildEntriesFromLocal())
|
// N'émet que si les quantités diffèrent réellement du parent.
|
||||||
|
const nextEntries = buildEntriesFromLocal()
|
||||||
|
if (!entriesEqualByTypeAndQuantity(nextEntries, props.modelValue)) {
|
||||||
|
emit('update:modelValue', nextEntries)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{ deep: true }
|
{ deep: true }
|
||||||
)
|
)
|
||||||
@@ -110,6 +157,5 @@ watch(
|
|||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
bovineTypes.value = await getBovineTypeList()
|
bovineTypes.value = await getBovineTypeList()
|
||||||
syncLocalFromProps()
|
syncLocalFromProps()
|
||||||
emit('update:modelValue', buildEntriesFromLocal())
|
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -109,7 +109,8 @@ const selectedMerchandiseTypeId = ref('')
|
|||||||
const selectedBuildingIds = ref<string[]>([])
|
const selectedBuildingIds = ref<string[]>([])
|
||||||
const selectedPelletBuildingIds = ref<Record<string, string[]>>({})
|
const selectedPelletBuildingIds = ref<Record<string, string[]>>({})
|
||||||
const merchandiseDetail = ref('')
|
const merchandiseDetail = ref('')
|
||||||
const isHydrating = ref(false)
|
// Verrou de synchro pour empêcher les aller-retours infinis entre parent et composant.
|
||||||
|
const isSyncing = ref(false)
|
||||||
const isReady = ref(false)
|
const isReady = ref(false)
|
||||||
|
|
||||||
const selectedMerchandiseType = computed(() =>
|
const selectedMerchandiseType = computed(() =>
|
||||||
@@ -130,6 +131,39 @@ function clonePelletSelections(value: Record<string, string[]>) {
|
|||||||
return clone
|
return clone
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function sorted(values: string[]): string[] {
|
||||||
|
return [...values].sort()
|
||||||
|
}
|
||||||
|
|
||||||
|
function normalizeModel(value: MerchandiseEntryData): MerchandiseEntryData {
|
||||||
|
// Normalisation stable pour comparer deux modèles sans faux positifs (ordre des tableaux).
|
||||||
|
const pellet: Record<string, string[]> = {}
|
||||||
|
const pelletKeys = Object.keys(value.selectedPelletBuildingIds ?? {}).sort()
|
||||||
|
for (const key of pelletKeys) {
|
||||||
|
pellet[key] = sorted(value.selectedPelletBuildingIds[key] ?? [])
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
merchandiseTypeId: value.merchandiseTypeId ?? '',
|
||||||
|
merchandiseDetail: value.merchandiseDetail ?? '',
|
||||||
|
selectedBuildingIds: sorted(value.selectedBuildingIds ?? []),
|
||||||
|
selectedPelletBuildingIds: pellet
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildCurrentModel(): MerchandiseEntryData {
|
||||||
|
return {
|
||||||
|
merchandiseTypeId: selectedMerchandiseTypeId.value,
|
||||||
|
merchandiseDetail: merchandiseDetail.value,
|
||||||
|
selectedBuildingIds: [...selectedBuildingIds.value],
|
||||||
|
selectedPelletBuildingIds: clonePelletSelections(selectedPelletBuildingIds.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function isSameModel(left: MerchandiseEntryData, right: MerchandiseEntryData): boolean {
|
||||||
|
return JSON.stringify(normalizeModel(left)) === JSON.stringify(normalizeModel(right))
|
||||||
|
}
|
||||||
|
|
||||||
function ensurePelletKeys() {
|
function ensurePelletKeys() {
|
||||||
for (const pelletType of pelletTypes.value) {
|
for (const pelletType of pelletTypes.value) {
|
||||||
const key = String(pelletType.id)
|
const key = String(pelletType.id)
|
||||||
@@ -140,7 +174,7 @@ function ensurePelletKeys() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function hydrateFromModelValue(value: MerchandiseEntryData) {
|
function hydrateFromModelValue(value: MerchandiseEntryData) {
|
||||||
isHydrating.value = true
|
isSyncing.value = true
|
||||||
try {
|
try {
|
||||||
selectedMerchandiseTypeId.value = value.merchandiseTypeId ?? ''
|
selectedMerchandiseTypeId.value = value.merchandiseTypeId ?? ''
|
||||||
merchandiseDetail.value = value.merchandiseDetail ?? ''
|
merchandiseDetail.value = value.merchandiseDetail ?? ''
|
||||||
@@ -150,34 +184,11 @@ function hydrateFromModelValue(value: MerchandiseEntryData) {
|
|||||||
)
|
)
|
||||||
ensurePelletKeys()
|
ensurePelletKeys()
|
||||||
} finally {
|
} finally {
|
||||||
isHydrating.value = false
|
isSyncing.value = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function emitModelValue() {
|
function sanitizeLocalState() {
|
||||||
emit('update:modelValue', {
|
|
||||||
merchandiseTypeId: selectedMerchandiseTypeId.value,
|
|
||||||
merchandiseDetail: merchandiseDetail.value,
|
|
||||||
selectedBuildingIds: [...selectedBuildingIds.value],
|
|
||||||
selectedPelletBuildingIds: clonePelletSelections(selectedPelletBuildingIds.value)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
watch(
|
|
||||||
() => props.modelValue,
|
|
||||||
(value) => {
|
|
||||||
hydrateFromModelValue(value)
|
|
||||||
},
|
|
||||||
{ deep: true }
|
|
||||||
)
|
|
||||||
|
|
||||||
watch(
|
|
||||||
[selectedMerchandiseTypeId, selectedBuildingIds, selectedPelletBuildingIds, merchandiseDetail],
|
|
||||||
() => {
|
|
||||||
if (isHydrating.value || !isReady.value) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isGranule.value) {
|
if (isGranule.value) {
|
||||||
if (selectedBuildingIds.value.length > 0) {
|
if (selectedBuildingIds.value.length > 0) {
|
||||||
selectedBuildingIds.value = []
|
selectedBuildingIds.value = []
|
||||||
@@ -193,8 +204,51 @@ watch(
|
|||||||
if (!isAutres.value && merchandiseDetail.value !== '') {
|
if (!isAutres.value && merchandiseDetail.value !== '') {
|
||||||
merchandiseDetail.value = ''
|
merchandiseDetail.value = ''
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
emitModelValue()
|
function emitCurrentModel() {
|
||||||
|
const currentModel = buildCurrentModel()
|
||||||
|
// Ne pas réémettre si rien n'a changé côté métier.
|
||||||
|
if (isSameModel(currentModel, props.modelValue)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
emit('update:modelValue', currentModel)
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.modelValue,
|
||||||
|
(value) => {
|
||||||
|
const currentModel = buildCurrentModel()
|
||||||
|
// Si local == parent, on ignore pour éviter la boucle de réhydratation.
|
||||||
|
if (isSameModel(currentModel, value)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
hydrateFromModelValue(value)
|
||||||
|
},
|
||||||
|
{ immediate: true }
|
||||||
|
)
|
||||||
|
|
||||||
|
watch(
|
||||||
|
[selectedMerchandiseTypeId, selectedBuildingIds, selectedPelletBuildingIds, merchandiseDetail],
|
||||||
|
() => {
|
||||||
|
if (isSyncing.value || !isReady.value) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const beforeSanitize = buildCurrentModel()
|
||||||
|
isSyncing.value = true
|
||||||
|
// Applique les règles métier (granulé / autres) avant émission.
|
||||||
|
sanitizeLocalState()
|
||||||
|
isSyncing.value = false
|
||||||
|
|
||||||
|
const afterSanitize = buildCurrentModel()
|
||||||
|
// Si la sanitation a modifié l'état, on laisse le watcher repasser proprement.
|
||||||
|
if (!isSameModel(beforeSanitize, afterSanitize)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
emitCurrentModel()
|
||||||
},
|
},
|
||||||
{ deep: true }
|
{ deep: true }
|
||||||
)
|
)
|
||||||
@@ -211,6 +265,5 @@ onMounted(async () => {
|
|||||||
|
|
||||||
hydrateFromModelValue(props.modelValue)
|
hydrateFromModelValue(props.modelValue)
|
||||||
isReady.value = true
|
isReady.value = true
|
||||||
emitModelValue()
|
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ export const useWeighing = ({
|
|||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
await createWeight({
|
await createWeight({
|
||||||
reception: `api/receptions/${reception.value.id}`,
|
reception: `/api/receptions/${reception.value.id}`,
|
||||||
type: mode,
|
type: mode,
|
||||||
dsd: baseDsd,
|
dsd: baseDsd,
|
||||||
weight: baseWeight,
|
weight: baseWeight,
|
||||||
@@ -146,7 +146,7 @@ export const useWeighingShipment = ({
|
|||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
await createWeight({
|
await createWeight({
|
||||||
shipment: `api/shipments/${shipment.value.id}`,
|
shipment: `/api/shipments/${shipment.value.id}`,
|
||||||
type: modeShipment,
|
type: modeShipment,
|
||||||
dsd: baseDsd,
|
dsd: baseDsd,
|
||||||
weight: baseWeight,
|
weight: baseWeight,
|
||||||
|
|||||||
@@ -172,13 +172,13 @@
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<update-merchandise
|
<update-merchandise
|
||||||
v-show="activeTab === 'merchandise' && isMerchandise"
|
v-if="activeTab === 'merchandise' && isMerchandise"
|
||||||
v-model="merchandiseForm"
|
v-model="merchandiseForm"
|
||||||
:isAdmin="auth.isAdmin"
|
:isAdmin="auth.isAdmin"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<update-bovin
|
<update-bovin
|
||||||
v-show="activeTab === 'merchandise' && !isMerchandise"
|
v-if="activeTab === 'merchandise' && !isMerchandise"
|
||||||
v-model="bovineEntries"
|
v-model="bovineEntries"
|
||||||
v-model:otherQuantity="bovineOtherQuantity"
|
v-model:otherQuantity="bovineOtherQuantity"
|
||||||
:isAdmin="auth.isAdmin"
|
:isAdmin="auth.isAdmin"
|
||||||
@@ -279,9 +279,25 @@ const isLoadingVehicles = ref(false)
|
|||||||
const formIsLoading = ref(false)
|
const formIsLoading = ref(false)
|
||||||
const isMerchandise = ref(false)
|
const isMerchandise = ref(false)
|
||||||
const isHydrating = ref(false)
|
const isHydrating = ref(false)
|
||||||
|
const vehicleSyncLock = ref(false)
|
||||||
|
|
||||||
const idReception = Number(route.params.id)
|
const idReception = Number(route.params.id)
|
||||||
|
|
||||||
|
function runWithVehicleSyncLock(mutator: () => void) {
|
||||||
|
if (vehicleSyncLock.value) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
vehicleSyncLock.value = true
|
||||||
|
try {
|
||||||
|
mutator()
|
||||||
|
} finally {
|
||||||
|
queueMicrotask(() => {
|
||||||
|
vehicleSyncLock.value = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const form = reactive<ReceptionFormData>({
|
const form = reactive<ReceptionFormData>({
|
||||||
identificationNumber: null,
|
identificationNumber: null,
|
||||||
licensePlate: '',
|
licensePlate: '',
|
||||||
@@ -581,8 +597,16 @@ async function saveWeightEntry(entry: WeightEntryData) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fallback: if id is missing in local state, reuse existing weight by type.
|
||||||
|
const reception = await getReception(idReception)
|
||||||
|
const existingEntry = reception?.weights?.find((weight) => weight.type === entry.type) ?? null
|
||||||
|
if (existingEntry?.id) {
|
||||||
|
await updateWeight(existingEntry.id, payload)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
await createWeight({
|
await createWeight({
|
||||||
reception: `api/receptions/${idReception}`,
|
reception: `/api/receptions/${idReception}`,
|
||||||
...payload
|
...payload
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -785,8 +809,11 @@ async function validate() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const refreshedReception = await getReception(idReception)
|
// Évite une réhydratation complète après save (source de cascades de watchers).
|
||||||
hydrateFromReception(refreshedReception)
|
// On recharge uniquement les bovins quand on est en mode bovins.
|
||||||
|
if (!isMerchandise.value) {
|
||||||
|
await loadBovineEntries(idReception)
|
||||||
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -809,12 +836,20 @@ onMounted(async () => {
|
|||||||
watch(
|
watch(
|
||||||
() => [form.supplierId, form.addressId, suppliers.value],
|
() => [form.supplierId, form.addressId, suppliers.value],
|
||||||
() => {
|
() => {
|
||||||
|
if (isHydrating.value) {
|
||||||
|
return
|
||||||
|
}
|
||||||
if (!form.supplierId) {
|
if (!form.supplierId) {
|
||||||
|
if (form.addressId !== '') {
|
||||||
form.addressId = ''
|
form.addressId = ''
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (!form.addressId && supplierAddresses.value.length === 1) {
|
if (!form.addressId && supplierAddresses.value.length === 1) {
|
||||||
form.addressId = String(supplierAddresses.value[0].id)
|
const nextAddressId = String(supplierAddresses.value[0].id)
|
||||||
|
if (form.addressId !== nextAddressId) {
|
||||||
|
form.addressId = nextAddressId
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (!form.addressId) {
|
if (!form.addressId) {
|
||||||
@@ -825,11 +860,16 @@ watch(
|
|||||||
)
|
)
|
||||||
if (!matches) {
|
if (!matches) {
|
||||||
if (supplierAddresses.value.length === 1) {
|
if (supplierAddresses.value.length === 1) {
|
||||||
form.addressId = String(supplierAddresses.value[0].id)
|
const nextAddressId = String(supplierAddresses.value[0].id)
|
||||||
|
if (form.addressId !== nextAddressId) {
|
||||||
|
form.addressId = nextAddressId
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
|
if (form.addressId !== '') {
|
||||||
form.addressId = ''
|
form.addressId = ''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{ immediate: true }
|
{ immediate: true }
|
||||||
)
|
)
|
||||||
@@ -837,24 +877,36 @@ watch(
|
|||||||
watch(
|
watch(
|
||||||
() => form.carrierId,
|
() => form.carrierId,
|
||||||
() => {
|
() => {
|
||||||
if (isHydrating.value) {
|
if (isHydrating.value || vehicleSyncLock.value) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (!form.carrierId && idReception == null) {
|
if (!form.carrierId && idReception == null) {
|
||||||
|
runWithVehicleSyncLock(() => {
|
||||||
form.driverId = ''
|
form.driverId = ''
|
||||||
form.vehicleId = ''
|
form.vehicleId = ''
|
||||||
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (!isLiotCarrier.value && idReception == null) {
|
if (!isLiotCarrier.value && idReception == null) {
|
||||||
|
runWithVehicleSyncLock(() => {
|
||||||
form.driverId = ''
|
form.driverId = ''
|
||||||
form.vehicleId = ''
|
form.vehicleId = ''
|
||||||
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (filteredDrivers.value.length === 1) {
|
if (filteredDrivers.value.length === 1) {
|
||||||
form.driverId = String(filteredDrivers.value[0].id)
|
const nextDriverId = String(filteredDrivers.value[0].id)
|
||||||
|
if (form.driverId !== nextDriverId) {
|
||||||
|
form.driverId = nextDriverId
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (filteredVehicles.value.length === 1) {
|
if (filteredVehicles.value.length === 1) {
|
||||||
form.vehicleId = String(filteredVehicles.value[0].id)
|
const nextVehicleId = String(filteredVehicles.value[0].id)
|
||||||
|
if (form.vehicleId !== nextVehicleId) {
|
||||||
|
runWithVehicleSyncLock(() => {
|
||||||
|
form.vehicleId = nextVehicleId
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ immediate: true }
|
{ immediate: true }
|
||||||
@@ -863,11 +915,19 @@ watch(
|
|||||||
watch(
|
watch(
|
||||||
() => [form.truckId, form.carrierId, vehicles.value],
|
() => [form.truckId, form.carrierId, vehicles.value],
|
||||||
() => {
|
() => {
|
||||||
|
if (isHydrating.value || vehicleSyncLock.value) {
|
||||||
|
return
|
||||||
|
}
|
||||||
if (!isLiotCarrier.value) {
|
if (!isLiotCarrier.value) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (filteredVehicles.value.length === 1) {
|
if (filteredVehicles.value.length === 1) {
|
||||||
form.vehicleId = String(filteredVehicles.value[0].id)
|
const nextVehicleId = String(filteredVehicles.value[0].id)
|
||||||
|
if (form.vehicleId !== nextVehicleId) {
|
||||||
|
runWithVehicleSyncLock(() => {
|
||||||
|
form.vehicleId = nextVehicleId
|
||||||
|
})
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (!form.vehicleId) {
|
if (!form.vehicleId) {
|
||||||
@@ -877,7 +937,11 @@ watch(
|
|||||||
(vehicle) => String(vehicle.id) === form.vehicleId
|
(vehicle) => String(vehicle.id) === form.vehicleId
|
||||||
)
|
)
|
||||||
if (!matches) {
|
if (!matches) {
|
||||||
|
if (form.vehicleId !== '') {
|
||||||
|
runWithVehicleSyncLock(() => {
|
||||||
form.vehicleId = ''
|
form.vehicleId = ''
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ immediate: true }
|
{ immediate: true }
|
||||||
@@ -886,6 +950,9 @@ watch(
|
|||||||
watch(
|
watch(
|
||||||
() => [form.vehicleId, form.carrierId, vehicles.value],
|
() => [form.vehicleId, form.carrierId, vehicles.value],
|
||||||
() => {
|
() => {
|
||||||
|
if (vehicleSyncLock.value) {
|
||||||
|
return
|
||||||
|
}
|
||||||
if (!isLiotCarrier.value) {
|
if (!isLiotCarrier.value) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -895,9 +962,11 @@ watch(
|
|||||||
const selected = filteredVehicles.value.find(
|
const selected = filteredVehicles.value.find(
|
||||||
(vehicle) => String(vehicle.id) === form.vehicleId
|
(vehicle) => String(vehicle.id) === form.vehicleId
|
||||||
)
|
)
|
||||||
if (selected) {
|
if (selected && form.licensePlate !== selected.plate) {
|
||||||
|
runWithVehicleSyncLock(() => {
|
||||||
form.licensePlate = selected.plate
|
form.licensePlate = selected.plate
|
||||||
allowAnyLicensePlate.value = false
|
allowAnyLicensePlate.value = false
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -905,6 +974,12 @@ watch(
|
|||||||
watch(
|
watch(
|
||||||
() => [form.licensePlate, form.carrierId, vehicles.value],
|
() => [form.licensePlate, form.carrierId, vehicles.value],
|
||||||
() => {
|
() => {
|
||||||
|
if (vehicleSyncLock.value) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (isHydrating.value) {
|
||||||
|
return
|
||||||
|
}
|
||||||
if (!isLiotCarrier.value || form.vehicleId) {
|
if (!isLiotCarrier.value || form.vehicleId) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -912,7 +987,12 @@ watch(
|
|||||||
(vehicle) => vehicle.plate === form.licensePlate
|
(vehicle) => vehicle.plate === form.licensePlate
|
||||||
)
|
)
|
||||||
if (match) {
|
if (match) {
|
||||||
form.vehicleId = String(match.id)
|
const nextVehicleId = String(match.id)
|
||||||
|
if (form.vehicleId !== nextVehicleId) {
|
||||||
|
runWithVehicleSyncLock(() => {
|
||||||
|
form.vehicleId = nextVehicleId
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user