refactor(frontend) : extract CustomFieldDisplay shared component
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -234,143 +234,12 @@
|
||||
</div>
|
||||
|
||||
<!-- Champs personnalisés de la pièce -->
|
||||
<div
|
||||
v-if="displayedCustomFields.length"
|
||||
class="mt-4 pt-4 border-t border-gray-200"
|
||||
>
|
||||
<h5 class="text-sm font-medium text-gray-700 mb-3">
|
||||
Champs personnalisés
|
||||
</h5>
|
||||
<div class="space-y-3">
|
||||
<div
|
||||
v-for="(field, index) in displayedCustomFields"
|
||||
:key="resolveFieldKey(field, index)"
|
||||
class="form-control"
|
||||
>
|
||||
<label class="label">
|
||||
<span class="label-text text-sm">{{
|
||||
resolveFieldName(field)
|
||||
}}</span>
|
||||
<span
|
||||
v-if="resolveFieldRequired(field)"
|
||||
class="label-text-alt text-error"
|
||||
>*</span
|
||||
>
|
||||
</label>
|
||||
|
||||
<!-- Mode édition -->
|
||||
<template v-if="isEditMode && !resolveFieldReadOnly(field)">
|
||||
<!-- Champ de type TEXT -->
|
||||
<input
|
||||
v-if="resolveFieldType(field) === 'text'"
|
||||
:value="field.value ?? ''"
|
||||
type="text"
|
||||
class="input input-bordered input-sm"
|
||||
:required="resolveFieldRequired(field)"
|
||||
@input="
|
||||
setCustomFieldValue(
|
||||
resolveFieldId(field),
|
||||
$event.target.value,
|
||||
field
|
||||
)
|
||||
"
|
||||
@blur="updateCustomFieldValue(resolveFieldId(field), field)"
|
||||
/>
|
||||
|
||||
<!-- Champ de type NUMBER -->
|
||||
<input
|
||||
v-else-if="resolveFieldType(field) === 'number'"
|
||||
:value="field.value ?? ''"
|
||||
type="number"
|
||||
class="input input-bordered input-sm"
|
||||
:required="resolveFieldRequired(field)"
|
||||
@input="
|
||||
setCustomFieldValue(
|
||||
resolveFieldId(field),
|
||||
$event.target.value,
|
||||
field
|
||||
)
|
||||
"
|
||||
@blur="updateCustomFieldValue(resolveFieldId(field), field)"
|
||||
/>
|
||||
|
||||
<!-- Champ de type SELECT -->
|
||||
<select
|
||||
v-else-if="resolveFieldType(field) === 'select'"
|
||||
:value="field.value ?? ''"
|
||||
class="select select-bordered select-sm"
|
||||
:required="resolveFieldRequired(field)"
|
||||
@change="
|
||||
(event) =>
|
||||
setCustomFieldValue(
|
||||
resolveFieldId(field),
|
||||
event.target.value,
|
||||
field
|
||||
)
|
||||
"
|
||||
@blur="updateCustomFieldValue(resolveFieldId(field), field)"
|
||||
>
|
||||
<option value="">Sélectionner...</option>
|
||||
<option
|
||||
v-for="option in resolveFieldOptions(field)"
|
||||
:key="option"
|
||||
:value="option"
|
||||
>
|
||||
{{ option }}
|
||||
</option>
|
||||
</select>
|
||||
|
||||
<!-- Champ de type BOOLEAN -->
|
||||
<div
|
||||
v-else-if="resolveFieldType(field) === 'boolean'"
|
||||
class="flex items-center gap-2"
|
||||
>
|
||||
<input
|
||||
:value="field.value ?? ''"
|
||||
type="checkbox"
|
||||
class="checkbox checkbox-sm"
|
||||
:checked="String(field.value).toLowerCase() === 'true'"
|
||||
@change="
|
||||
setCustomFieldValue(
|
||||
resolveFieldId(field),
|
||||
$event.target.checked ? 'true' : 'false',
|
||||
field
|
||||
)
|
||||
"
|
||||
@blur="updateCustomFieldValue(resolveFieldId(field), field)"
|
||||
/>
|
||||
<span class="text-sm">{{
|
||||
String(field.value).toLowerCase() === "true" ? "Oui" : "Non"
|
||||
}}</span>
|
||||
</div>
|
||||
|
||||
<!-- Champ de type DATE -->
|
||||
<input
|
||||
v-else-if="resolveFieldType(field) === 'date'"
|
||||
:value="field.value ?? ''"
|
||||
type="date"
|
||||
class="input input-bordered input-sm"
|
||||
:required="resolveFieldRequired(field)"
|
||||
@input="
|
||||
setCustomFieldValue(
|
||||
resolveFieldId(field),
|
||||
$event.target.value,
|
||||
field
|
||||
)
|
||||
"
|
||||
@blur="updateCustomFieldValue(resolveFieldId(field), field)"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<!-- Mode lecture seule -->
|
||||
<template v-else>
|
||||
<div class="input input-bordered input-sm bg-base-200">
|
||||
{{ formatFieldDisplayValue(field) }}
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<CommonCustomFieldDisplay
|
||||
:fields="displayedCustomFields"
|
||||
:is-edit-mode="isEditMode"
|
||||
@field-input="handleCustomFieldInput"
|
||||
@field-blur="handleCustomFieldBlur"
|
||||
/>
|
||||
|
||||
<div class="mt-4 pt-4 border-t border-gray-200 space-y-3">
|
||||
<div class="flex items-center justify-between">
|
||||
@@ -434,14 +303,8 @@ import {
|
||||
downloadDocument,
|
||||
} from '~/shared/utils/documentDisplayUtils'
|
||||
import {
|
||||
resolveFieldKey,
|
||||
resolveFieldId,
|
||||
resolveFieldName,
|
||||
resolveFieldType,
|
||||
resolveFieldOptions,
|
||||
resolveFieldRequired,
|
||||
resolveFieldReadOnly,
|
||||
formatFieldDisplayValue,
|
||||
} from '~/shared/utils/entityCustomFieldLogic'
|
||||
import { useEntityDocuments } from '~/composables/useEntityDocuments'
|
||||
import { useEntityProductDisplay } from '~/composables/useEntityProductDisplay'
|
||||
@@ -595,16 +458,16 @@ const handleProductChange = async (value) => {
|
||||
updatePiece()
|
||||
}
|
||||
|
||||
// --- Custom field local helpers ---
|
||||
const setCustomFieldValue = (fieldValueId, value, field) => {
|
||||
// --- Custom field event handlers ---
|
||||
const handleCustomFieldInput = (field, value) => {
|
||||
if (resolveFieldReadOnly(field)) return
|
||||
if (field && typeof field === 'object') field.value = value
|
||||
const fieldValueId = resolveFieldId(field)
|
||||
if (!fieldValueId) return
|
||||
const fieldValue = props.piece.customFieldValues?.find((fv) => fv.id === fieldValueId)
|
||||
if (fieldValue) fieldValue.value = value
|
||||
}
|
||||
|
||||
const updateCustomFieldValue = async (_fieldValueId, field) => {
|
||||
const handleCustomFieldBlur = async (field) => {
|
||||
await updateCustomField(field)
|
||||
const cfId = field?.customFieldId || field?.customField?.id || null
|
||||
if (cfId || field?.customFieldValueId) {
|
||||
|
||||
Reference in New Issue
Block a user