feat(transport) : immatriculations LIOT sur 3 colonnes + filtre saisie (lettres/chiffres/tiret/point-virgule) (ERP-193)
This commit is contained in:
@@ -25,14 +25,19 @@
|
|||||||
:required="true"
|
:required="true"
|
||||||
:error="mainErrors.errors.name"
|
:error="mainErrors.errors.name"
|
||||||
/>
|
/>
|
||||||
<MalioInputText
|
<!-- Cas LIOT : le champ immatriculations occupe les colonnes restantes
|
||||||
v-if="isLiot"
|
de la ligne (3 en xl, 2 sinon). Wrapper pour le col-span car
|
||||||
v-model="main.liotPlates"
|
MalioInputText (inheritAttrs:false) renvoie `class` sur l'input. -->
|
||||||
:label="t('transport.carriers.form.main.liotPlates')"
|
<div v-if="isLiot" class="col-span-2 xl:col-span-3">
|
||||||
:hint="t('transport.carriers.form.main.liotPlatesHint')"
|
<MalioInputText
|
||||||
:required="true"
|
:model-value="main.liotPlates"
|
||||||
:error="mainErrors.errors.liotPlates"
|
@update:model-value="(v: string) => main.liotPlates = sanitizeLiotPlates(v)"
|
||||||
/>
|
:label="t('transport.carriers.form.main.liotPlates')"
|
||||||
|
:hint="t('transport.carriers.form.main.liotPlatesHint')"
|
||||||
|
:required="true"
|
||||||
|
:error="mainErrors.errors.liotPlates"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
<template v-if="!isLiot">
|
<template v-if="!isLiot">
|
||||||
<MalioSelect
|
<MalioSelect
|
||||||
:model-value="main.certificationType"
|
:model-value="main.certificationType"
|
||||||
@@ -214,7 +219,7 @@ import CarrierQualimatTab from '~/modules/transport/components/CarrierQualimatTa
|
|||||||
import { useCarrierForm } from '~/modules/transport/composables/useCarrierForm'
|
import { useCarrierForm } from '~/modules/transport/composables/useCarrierForm'
|
||||||
import { useCarrier } from '~/modules/transport/composables/useCarrier'
|
import { useCarrier } from '~/modules/transport/composables/useCarrier'
|
||||||
import type { QualimatCarrierRow } from '~/modules/transport/composables/useQualimatSearch'
|
import type { QualimatCarrierRow } from '~/modules/transport/composables/useQualimatSearch'
|
||||||
import { clampPercent, sanitizeDecimal } from '~/modules/transport/utils/forms/numberInput'
|
import { clampPercent, sanitizeDecimal, sanitizeLiotPlates } from '~/modules/transport/utils/forms/numberInput'
|
||||||
import { sanitizeFreeText } from '~/shared/utils/textSanitize'
|
import { sanitizeFreeText } from '~/shared/utils/textSanitize'
|
||||||
|
|
||||||
interface SelectOption {
|
interface SelectOption {
|
||||||
|
|||||||
@@ -27,16 +27,21 @@
|
|||||||
:error="mainErrors.errors.name"
|
:error="mainErrors.errors.name"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<!-- Cas LIOT : seul le champ immatriculations est pertinent. -->
|
<!-- Cas LIOT : seul le champ immatriculations est pertinent. Il occupe
|
||||||
<MalioInputText
|
les colonnes restantes de la ligne (3 en xl, 2 sinon) — le wrapper
|
||||||
v-if="isLiot"
|
porte le col-span car MalioInputText (inheritAttrs:false) renvoie
|
||||||
v-model="main.liotPlates"
|
`class` sur l'input interne, pas sur la cellule de grille. -->
|
||||||
:label="t('transport.carriers.form.main.liotPlates')"
|
<div v-if="isLiot" class="col-span-2 xl:col-span-3">
|
||||||
:hint="t('transport.carriers.form.main.liotPlatesHint')"
|
<MalioInputText
|
||||||
:required="true"
|
:model-value="main.liotPlates"
|
||||||
:disabled="mainLocked"
|
@update:model-value="(v: string) => main.liotPlates = sanitizeLiotPlates(v)"
|
||||||
:error="mainErrors.errors.liotPlates"
|
:label="t('transport.carriers.form.main.liotPlates')"
|
||||||
/>
|
:hint="t('transport.carriers.form.main.liotPlatesHint')"
|
||||||
|
:required="true"
|
||||||
|
:disabled="mainLocked"
|
||||||
|
:error="mainErrors.errors.liotPlates"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- Cas standard : certification + affretement + champs conditionnels. -->
|
<!-- Cas standard : certification + affretement + champs conditionnels. -->
|
||||||
<template v-if="!isLiot">
|
<template v-if="!isLiot">
|
||||||
@@ -308,7 +313,7 @@ import CarrierPriceBlock from '~/modules/transport/components/CarrierPriceBlock.
|
|||||||
import CarrierQualimatTab from '~/modules/transport/components/CarrierQualimatTab.vue'
|
import CarrierQualimatTab from '~/modules/transport/components/CarrierQualimatTab.vue'
|
||||||
import { useCarrierForm } from '~/modules/transport/composables/useCarrierForm'
|
import { useCarrierForm } from '~/modules/transport/composables/useCarrierForm'
|
||||||
import type { QualimatCarrierRow } from '~/modules/transport/composables/useQualimatSearch'
|
import type { QualimatCarrierRow } from '~/modules/transport/composables/useQualimatSearch'
|
||||||
import { clampPercent, sanitizeDecimal } from '~/modules/transport/utils/forms/numberInput'
|
import { clampPercent, sanitizeDecimal, sanitizeLiotPlates } from '~/modules/transport/utils/forms/numberInput'
|
||||||
import { sanitizeFreeText } from '~/shared/utils/textSanitize'
|
import { sanitizeFreeText } from '~/shared/utils/textSanitize'
|
||||||
|
|
||||||
interface SelectOption {
|
interface SelectOption {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { describe, expect, it } from 'vitest'
|
import { describe, expect, it } from 'vitest'
|
||||||
import { clampPercent, sanitizeDecimal } from '../numberInput'
|
import { clampPercent, sanitizeDecimal, sanitizeLiotPlates } from '../numberInput'
|
||||||
|
|
||||||
describe('numberInput — saisie volume / indexation (ERP-170)', () => {
|
describe('numberInput — saisie volume / indexation (ERP-170)', () => {
|
||||||
it('sanitizeDecimal : ne garde que chiffres + un seul point', () => {
|
it('sanitizeDecimal : ne garde que chiffres + un seul point', () => {
|
||||||
@@ -19,4 +19,12 @@ describe('numberInput — saisie volume / indexation (ERP-170)', () => {
|
|||||||
expect(clampPercent('12,5')).toBe('12,5') // ≤ 100 → inchangé
|
expect(clampPercent('12,5')).toBe('12,5') // ≤ 100 → inchangé
|
||||||
expect(clampPercent('')).toBe('')
|
expect(clampPercent('')).toBe('')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('sanitizeLiotPlates : garde lettres/chiffres/tiret/point-virgule, retire espaces et reste', () => {
|
||||||
|
expect(sanitizeLiotPlates('AB-123-CD;EF-456-GH')).toBe('AB-123-CD;EF-456-GH')
|
||||||
|
expect(sanitizeLiotPlates('ab-123-cd ; ef-456-gh')).toBe('ab-123-cd;ef-456-gh') // espaces retirés
|
||||||
|
expect(sanitizeLiotPlates('AB 123 CD')).toBe('AB123CD') // espaces retirés
|
||||||
|
expect(sanitizeLiotPlates('AB.123/CD#42')).toBe('AB123CD42') // . / # retirés
|
||||||
|
expect(sanitizeLiotPlates('')).toBe('')
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -26,3 +26,13 @@ export function clampPercent(value: string): string {
|
|||||||
const n = Number(String(value ?? '').replace(',', '.').replace(/\s/g, ''))
|
const n = Number(String(value ?? '').replace(',', '.').replace(/\s/g, ''))
|
||||||
return (!Number.isNaN(n) && n > 100) ? '100' : value
|
return (!Number.isNaN(n) && n > 100) ? '100' : value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restreint la saisie des immatriculations LIOT : ne garde que lettres, chiffres,
|
||||||
|
* tiret et point-virgule (séparateur de plaques). Les espaces et tout autre
|
||||||
|
* caractère sont supprimés à la frappe / au collage. La normalisation finale
|
||||||
|
* (majuscules + « ; » espacé) reste au back (RG-4.13).
|
||||||
|
*/
|
||||||
|
export function sanitizeLiotPlates(value: string): string {
|
||||||
|
return (value ?? '').replace(/[^A-Za-z0-9;-]/g, '')
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user