refactor : merge Inventory_frontend submodule into frontend/ directory
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>
This commit is contained in:
186
frontend/app/components/PieceModelStructureEditor.vue
Normal file
186
frontend/app/components/PieceModelStructureEditor.vue
Normal file
@@ -0,0 +1,186 @@
|
||||
<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>
|
||||
Reference in New Issue
Block a user