8.9 KiB
8.9 KiB
Micro duplication report
MDUP-001 · Score 92 · Type form-field
- Pattern: Champ téléphone complet (label, input
tel, placeholder "Ex: 06 00 00 00 00", règles de validation implicites). - Occurrences:
app/components/ConstructeurSelect.vueL70-L86 — modal de création de constructeur. 【F:app/components/ConstructeurSelect.vue†L66-L88】app/pages/constructeurs.vueL82-L92 — formulaire de création/édition. 【F:app/pages/constructeurs.vue†L80-L92】app/components/sites/SiteContactFormFields.vueL1-L57 — bloc de formulaire de contact. 【F:app/components/sites/SiteContactFormFields.vue†L1-L58】app/pages/index.vueL200-L224 — création rapide d’un site. 【F:app/pages/index.vue†L200-L224】
- Extraction: ✅
app/components/form/FieldPhone.vue(props :modelValue,label,required,error,help,placeholder,disabled,normalizeOnBlur,validateOnBlur). 【F:app/components/form/FieldPhone.vue†L1-L113】 - Plan de remplacement: Remplacer chaque bloc par
<FieldPhone v-model="..." />. Call-sites déjà migrés ci-dessus.
MDUP-002 · Score 90 · Type form-field
- Pattern: Champ email (label « Email », input
type="email", placeholder d’exemple, aucune validation mutualisée). - Occurrences:
app/components/ConstructeurSelect.vueL66-L84. 【F:app/components/ConstructeurSelect.vue†L66-L86】app/pages/constructeurs.vueL82-L90. 【F:app/pages/constructeurs.vue†L80-L92】
- Extraction: ✅
app/components/form/FieldEmail.vueavec normalisation et validation partagée. 【F:app/components/form/FieldEmail.vue†L1-L112】 - Plan de remplacement: Blocs remplacés par
<FieldEmail />sur les deux formulaires.
MDUP-003 · Score 88 · Type form-field
- Pattern: Groupe « informations de contact site » (Nom du contact, Téléphone, Adresse, Code postal, Ville) répliqué.
- Occurrences:
app/components/sites/SiteContactFormFields.vue(composant existant). 【F:app/components/sites/SiteContactFormFields.vue†L1-L58】app/pages/index.vueL200-L223 — doublait le bloc dans le modal rapide. 【F:app/pages/index.vue†L200-L223】
- Extraction: ✅ Réutilisation directe du composant
SiteContactFormFieldssur la page index. Aucun changement d’API. - Plan de remplacement: Remplacer le bloc du modal par
<SiteContactFormFields :form="newSite" />(effectué).
MDUP-004 · Score 86 · Type tiny-logic
- Pattern: Liaisons
computed({ get, set })pour faire transiterv-modelentre props et emits. - Occurrences:
app/components/TypeEditComponentRequirementsSection.vueL45-L59. 【F:app/components/TypeEditComponentRequirementsSection.vue†L45-L59】app/components/TypeEditPieceRequirementsSection.vueL45-L59. 【F:app/components/TypeEditPieceRequirementsSection.vue†L45-L59】app/components/common/RequirementListEditor.vueL198-L203. 【F:app/components/common/RequirementListEditor.vue†L198-L204】app/components/TypeEditCustomFieldsSection.vueL163-L168. 【F:app/components/TypeEditCustomFieldsSection.vue†L163-L168】app/components/TypeEditBaseInfoSection.vueL82-L102. 【F:app/components/TypeEditBaseInfoSection.vue†L82-L102】app/components/sites/SiteEditModal.vueL140-L154. 【F:app/components/sites/SiteEditModal.vue†L140-L154】
- Extraction proposée:
app/composables/useControlledModel.tsretournant{ model }viauseVModelmaison (prop name configurable, options pour defaultValue et transform). - Plan: 1) Introduire le composable, 2) remapper les computed existantes, 3) supprimer le code duplicatif.
MDUP-005 · Score 82 · Type tiny-logic
- Pattern: Fonctions
createDefaultRequirementquasi identiques (seuls champsminCount,requiredettype*Idchangent). - Occurrences:
app/components/TypeEditComponentRequirementsSection.vueL61-L69. 【F:app/components/TypeEditComponentRequirementsSection.vue†L61-L69】app/components/TypeEditPieceRequirementsSection.vueL61-L69. 【F:app/components/TypeEditPieceRequirementsSection.vue†L61-L69】
- Extraction proposée:
app/shared/requirements/defaults.tsexportantcreateRequirementDefaults({ min, required, typeKey }). - Plan: Mutualiser la fonction, la paramétrer par options, adapter les deux sections.
MDUP-006 · Score 80 · Type tiny-logic
- Pattern: Effet
onMountedidentique qui teste la liste et déclencheloadXsi vide. - Occurrences:
app/components/TypeEditComponentRequirementsSection.vueL89-L93. 【F:app/components/TypeEditComponentRequirementsSection.vue†L89-L93】app/components/TypeEditPieceRequirementsSection.vueL89-L93. 【F:app/components/TypeEditPieceRequirementsSection.vue†L89-L93】
- Extraction proposée:
useEnsureOptionsLoaded(optionsRef, loader)dansapp/composables/pour encapsuler le check + chargement (support async/await, options pour refetch forcé). - Plan: Appeler le composable dans les deux sections et supprimer le code inline.
MDUP-007 · Score 78 · Type ui-fragment
- Pattern: Pieds de modale avec boutons « Annuler » + primaire + spinner optionnel.
- Occurrences:
app/components/ConstructeurSelect.vueL80-L86. 【F:app/components/ConstructeurSelect.vue†L80-L86】app/pages/constructeurs.vueL86-L91. 【F:app/pages/constructeurs.vue†L86-L91】app/components/sites/SiteCreateModal.vueL21-L27. 【F:app/components/sites/SiteCreateModal.vue†L21-L27】app/components/sites/SiteEditModal.vueL82-L89. 【F:app/components/sites/SiteEditModal.vue†L82-L89】app/pages/index.vueL217-L223 & L306-L312. 【F:app/pages/index.vue†L215-L313】
- Extraction proposée:
app/components/common/ModalActions.vueavec propsprimaryLabel,primaryLoading,onCancel, slots secondaires. - Plan: Introduire le composant, refactorer chaque modal pour l’utiliser, garantir les mêmes classes Tailwind.
MDUP-008 · Score 76 · Type ui-fragment
- Pattern: Gabarit de modale (div
.modal+.modal-box, titre<h3>, formulaire, actions). - Occurrences:
app/components/ConstructeurSelect.vueL58-L89. 【F:app/components/ConstructeurSelect.vue†L58-L89】app/components/sites/SiteCreateModal.vueL1-L31. 【F:app/components/sites/SiteCreateModal.vue†L1-L31】app/components/sites/SiteEditModal.vueL1-L94. 【F:app/components/sites/SiteEditModal.vue†L1-L94】app/pages/index.vueL192-L315 (modales site/machine). 【F:app/pages/index.vue†L192-L315】
- Extraction proposée:
app/components/common/ModalShell.vuegérant l’ouverture, le titre, le footer via slots (header,default,footer). - Plan: Remplacer chaque squelette par le nouveau composant tout en conservant la structure DOM requise par DaisyUI.
MDUP-009 · Score 74 · Type form-field
- Pattern: Champ texte simple (label, input type="text",
required) pour les « Nom » & co. - Occurrences:
app/components/ConstructeurSelect.vueL62-L65. 【F:app/components/ConstructeurSelect.vue†L62-L66】app/pages/constructeurs.vueL78-L81. 【F:app/pages/constructeurs.vue†L78-L81】app/components/sites/SiteCreateModal.vueL6-L17. 【F:app/components/sites/SiteCreateModal.vue†L5-L17】app/components/sites/SiteEditModal.vueL8-L20. 【F:app/components/sites/SiteEditModal.vue†L8-L20】app/components/TypeEditBaseInfoSection.vueL8-L48. 【F:app/components/TypeEditBaseInfoSection.vue†L8-L48】
- Extraction proposée:
app/components/form/FieldText.vueavec propstype,label,required,maxlength,placeholder, supportmodelModifiers. - Plan: Introduire le composant, migrer progressivement les champs texte, ajouter un paramètre pour afficher l’étoile obligatoire.
MDUP-010 · Score 72 · Type ui-fragment
- Pattern: Bouton primaire avec indicateur de chargement inline (
<span class="loading loading-spinner loading-xs mr-2">). - Occurrences:
app/components/ConstructeurSelect.vueL82-L84. 【F:app/components/ConstructeurSelect.vue†L82-L84】app/pages/constructeurs.vueL88-L89. 【F:app/pages/constructeurs.vue†L88-L90】app/components/sites/SiteEditModal.vueL86-L88. 【F:app/components/sites/SiteEditModal.vue†L86-L88】
- Extraction proposée:
app/components/common/LoadingButton.vuegérant les variantes (primary,outline), le spinner et le label via slots. - Plan: Remplacer les boutons concernés par le composant, propager
loading&disabledautomatiquement.
Annexes
- Validations centralisées:
app/shared/validation/phone.ts&app/shared/validation/email.tsfournissent désormais des schémas communs. 【F:app/shared/validation/phone.ts†L1-L36】【F:app/shared/validation/email.ts†L1-L34】 - Formatters communs:
app/utils/formatters/phone.tsetapp/utils/formatters/email.tsproposent les helpers associés. 【F:app/utils/formatters/phone.ts†L1-L67】【F:app/utils/formatters/email.ts†L1-L37】