Merges the full git history of Inventory_frontend into the monorepo under frontend/. Removes the submodule in favor of a unified repo. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
187 lines
5.9 KiB
Vue
187 lines
5.9 KiB
Vue
<template>
|
|
<div class="space-y-6">
|
|
<section class="space-y-3">
|
|
<header>
|
|
<h3 class="text-sm font-semibold">
|
|
Produits inclus par défaut
|
|
</h3>
|
|
<p class="text-xs text-base-content/70">
|
|
Ces produits s'afficheront lors de la création d'une pièce basée sur cette catégorie.
|
|
</p>
|
|
</header>
|
|
|
|
<p v-if="!products.length" class="text-xs text-base-content/50">
|
|
Aucun produit défini.
|
|
</p>
|
|
|
|
<ul v-else class="space-y-2" role="list">
|
|
<li
|
|
v-for="(product, index) in products"
|
|
:key="product.uid"
|
|
class="space-y-3 rounded-md border border-base-200 bg-base-100 p-3"
|
|
>
|
|
<div class="flex items-start justify-between gap-3">
|
|
<div class="flex-1 space-y-3">
|
|
<div class="form-control">
|
|
<label class="label py-1">
|
|
<span class="label-text text-xs">Famille de produit</span>
|
|
</label>
|
|
<select
|
|
v-model="product.typeProductId"
|
|
class="select select-bordered select-xs"
|
|
@change="handleProductTypeSelect(product)"
|
|
>
|
|
<option value="">
|
|
Sélectionner une famille
|
|
</option>
|
|
<option
|
|
v-for="type in productTypeOptions"
|
|
:key="type.id"
|
|
:value="type.id"
|
|
>
|
|
{{ formatProductTypeOption(type) }}
|
|
</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<button
|
|
type="button"
|
|
class="btn btn-error btn-xs btn-square"
|
|
@click="removeProduct(index)"
|
|
>
|
|
<IconLucideTrash class="w-4 h-4" aria-hidden="true" />
|
|
</button>
|
|
</div>
|
|
</li>
|
|
</ul>
|
|
<button type="button" class="btn btn-outline btn-xs" @click="addProduct">
|
|
<IconLucidePlus class="w-3 h-3 mr-2" aria-hidden="true" />
|
|
Ajouter
|
|
</button>
|
|
</section>
|
|
|
|
<section class="space-y-3">
|
|
<h3 class="text-sm font-semibold">
|
|
Champs personnalisés
|
|
</h3>
|
|
|
|
<p v-if="!fields.length" class="text-xs text-base-content/50">
|
|
Aucun champ personnalisé n'a encore été défini.
|
|
</p>
|
|
|
|
<ul v-else class="space-y-2" role="list">
|
|
<li
|
|
v-for="(field, index) in fields"
|
|
:key="field.uid"
|
|
class="border border-base-200 rounded-md p-3 space-y-2 bg-base-100 transition-colors"
|
|
:class="reorderClass(index)"
|
|
draggable="true"
|
|
@dragstart="onDragStart(index, $event)"
|
|
@dragenter="onDragEnter(index)"
|
|
@dragover.prevent="onDragEnter(index)"
|
|
@drop.prevent="onDrop(index)"
|
|
@dragend="onDragEnd"
|
|
>
|
|
<div class="flex items-start gap-3">
|
|
<button
|
|
type="button"
|
|
class="btn btn-ghost btn-xs btn-square cursor-grab active:cursor-grabbing mt-1"
|
|
title="Réordonner"
|
|
draggable="false"
|
|
>
|
|
<IconLucideGripVertical class="w-4 h-4" aria-hidden="true" />
|
|
</button>
|
|
|
|
<div class="flex-1 space-y-2">
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-2">
|
|
<input
|
|
v-model="field.name"
|
|
type="text"
|
|
class="input input-bordered input-xs"
|
|
placeholder="Nom du champ"
|
|
>
|
|
<select v-model="field.type" class="select select-bordered select-xs">
|
|
<option value="text">
|
|
Texte
|
|
</option>
|
|
<option value="number">
|
|
Nombre
|
|
</option>
|
|
<option value="select">
|
|
Liste
|
|
</option>
|
|
<option value="boolean">
|
|
Oui/Non
|
|
</option>
|
|
<option value="date">
|
|
Date
|
|
</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="flex items-center gap-2 text-xs">
|
|
<input v-model="field.required" type="checkbox" class="checkbox checkbox-xs">
|
|
Obligatoire
|
|
</div>
|
|
|
|
<textarea
|
|
v-if="field.type === 'select'"
|
|
v-model="field.optionsText"
|
|
class="textarea textarea-bordered textarea-xs h-20"
|
|
placeholder="Option 1 Option 2"
|
|
/>
|
|
</div>
|
|
|
|
<button
|
|
type="button"
|
|
class="btn btn-error btn-xs btn-square"
|
|
@click="removeField(index)"
|
|
>
|
|
<IconLucideTrash class="w-4 h-4" aria-hidden="true" />
|
|
</button>
|
|
</div>
|
|
</li>
|
|
</ul>
|
|
<button type="button" class="btn btn-outline btn-xs" @click="addField">
|
|
<IconLucidePlus class="w-3 h-3 mr-2" aria-hidden="true" />
|
|
Ajouter
|
|
</button>
|
|
</section>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import IconLucideGripVertical from '~icons/lucide/grip-vertical'
|
|
import IconLucidePlus from '~icons/lucide/plus'
|
|
import IconLucideTrash from '~icons/lucide/trash'
|
|
import type { PieceModelStructure } from '~/shared/types/inventory'
|
|
import { usePieceStructureEditorLogic } from '~/composables/usePieceStructureEditorLogic'
|
|
|
|
defineOptions({ name: 'PieceModelStructureEditor' })
|
|
|
|
const props = defineProps<{
|
|
modelValue?: PieceModelStructure | null
|
|
}>()
|
|
|
|
const emit = defineEmits<{
|
|
(event: 'update:modelValue', value: PieceModelStructure): void
|
|
}>()
|
|
|
|
const {
|
|
fields,
|
|
products,
|
|
productTypeOptions,
|
|
formatProductTypeOption,
|
|
handleProductTypeSelect,
|
|
addProduct,
|
|
removeProduct,
|
|
addField,
|
|
removeField,
|
|
reorderClass,
|
|
onDragStart,
|
|
onDragEnter,
|
|
onDrop,
|
|
onDragEnd,
|
|
} = usePieceStructureEditorLogic({ props, emit })
|
|
</script>
|