feat : Ajout de la sélection des bovins étape 3 d'une réception (WIP)
This commit is contained in:
41
frontend/components/reception/reception-bovine-received.vue
Normal file
41
frontend/components/reception/reception-bovine-received.vue
Normal file
@@ -0,0 +1,41 @@
|
||||
<template>
|
||||
<div class="flex flex-row gap-16 items-center w-full">
|
||||
<div
|
||||
v-for="type in bovineType"
|
||||
:key="type.id"
|
||||
class="mt-8 flex flex-row mb-2 gap-6">
|
||||
<UiNumberInput
|
||||
:label="type.label"
|
||||
:code="type.code"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="mt-8 flex flex-row mb-2 gap-6">
|
||||
<UiNumberInput
|
||||
label="Autres"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
|
||||
import {getTruckList} from "~/services/truck";
|
||||
import type {BovineTypeData} from "~/services/dto/bovine-type-data";
|
||||
import {getBovineTypeList} from "~/services/bovine-type";
|
||||
|
||||
|
||||
const isLoadingBovineType = ref(false)
|
||||
const bovineType = ref<BovineTypeData[]>([])
|
||||
|
||||
const loadBovineType = async () => {
|
||||
isLoadingBovineType.value = true
|
||||
try {
|
||||
bovineType.value = await getBovineTypeList()
|
||||
} finally {
|
||||
isLoadingBovineType.value = false
|
||||
}
|
||||
}
|
||||
onMounted(async () => {
|
||||
await loadBovineType()
|
||||
})
|
||||
</script>
|
||||
@@ -1,10 +1,11 @@
|
||||
<template>
|
||||
<div class="flex flex-col items-center gap-16">
|
||||
<!-- @TODO voir pour séparer dans un composant au moment de l'implémentation des Bovins -->
|
||||
<!-- @TODO voir pour séparer dans un composant au moment de l'implémentation des Bovins -->
|
||||
<div
|
||||
v-if="receptionStore.current?.receptionType?.code === RECEPTION_TYPE_CODES.MERCHANDISES"
|
||||
class="flex flex-col gap-16 items-center w-full">
|
||||
<h1 class="text-4xl uppercase font-bold">Sélectionner des marchandises réceptionnnées</h1>
|
||||
<h1 class="text-4xl uppercase font-bold">Sélection des marchandises réceptionnnées</h1>
|
||||
<!-- ICI UNE ERREUR DE RESPECT MAQUETTE -->
|
||||
<UiSelect
|
||||
id="merchandise-type"
|
||||
v-model="selectedMerchandiseTypeId"
|
||||
@@ -66,28 +67,36 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="receptionStore.current?.receptionType?.code === RECEPTION_TYPE_CODES.BOVINS"
|
||||
>
|
||||
<h1 class="text-4xl uppercase font-bold">Sélection des races réceptionnnées</h1>
|
||||
<ReceptionBovineReceived />
|
||||
</div>
|
||||
<button
|
||||
class="text-xl uppercase bg-primary-500 text-white h-[50px] w-[272px]"
|
||||
@click="goNext"
|
||||
>Peser</button>
|
||||
>Peser
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, onMounted, ref } from 'vue'
|
||||
import { getBuildingList } from '~/services/building'
|
||||
import { getMerchandiseTypeList } from '~/services/merchandise-type'
|
||||
import type { MerchandiseTypeData } from '~/services/dto/merchandise-type-data'
|
||||
import type { BuildingData } from '~/services/dto/building-data'
|
||||
import type { PelletTypeData } from '~/services/dto/pellet-type-data'
|
||||
import { getPelletTypeList } from '~/services/pellet-type'
|
||||
import {computed, onMounted, ref} from 'vue'
|
||||
import {getBuildingList} from '~/services/building'
|
||||
import {getMerchandiseTypeList} from '~/services/merchandise-type'
|
||||
import type {MerchandiseTypeData} from '~/services/dto/merchandise-type-data'
|
||||
import type {BuildingData} from '~/services/dto/building-data'
|
||||
import type {PelletTypeData} from '~/services/dto/pellet-type-data'
|
||||
import {getPelletTypeList} from '~/services/pellet-type'
|
||||
import {
|
||||
createReceptionPelletBuilding,
|
||||
deleteReceptionPelletBuilding,
|
||||
getReceptionPelletBuildingList
|
||||
} from '~/services/reception-pellet-building'
|
||||
import { useReceptionStore } from '~/stores/reception'
|
||||
import { MERCHANDISE_TYPE_CODES, RECEPTION_TYPE_CODES } from '~/utils/constants'
|
||||
import {useReceptionStore} from '~/stores/reception'
|
||||
import {MERCHANDISE_TYPE_CODES, RECEPTION_TYPE_CODES} from '~/utils/constants'
|
||||
import ReceptionBovineReceived from "~/components/reception/reception-bovine-received.vue";
|
||||
|
||||
const receptionStore = useReceptionStore()
|
||||
const merchandiseTypes = ref<MerchandiseTypeData[]>([])
|
||||
@@ -98,6 +107,7 @@ const selectedBuildingIds = ref<string[]>([])
|
||||
const selectedPelletBuildingIds = ref<Record<string, string[]>>({})
|
||||
const merchandiseDetail = ref('')
|
||||
|
||||
|
||||
// Extrait l'ID d'une relation depuis un IRI ou un objet complet.
|
||||
const getRelationId = (value: unknown): string | null => {
|
||||
if (!value) {
|
||||
@@ -227,7 +237,7 @@ async function syncPelletSelections(receptionIri: string) {
|
||||
const desiredEntries: Array<{ pelletTypeId: string; buildingId: string }> = []
|
||||
for (const [pelletTypeId, buildingIds] of Object.entries(selectedPelletBuildingIds.value)) {
|
||||
for (const buildingId of buildingIds) {
|
||||
desiredEntries.push({ pelletTypeId, buildingId })
|
||||
desiredEntries.push({pelletTypeId, buildingId})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
79
frontend/components/ui/UiNumberInput.vue
Normal file
79
frontend/components/ui/UiNumberInput.vue
Normal file
@@ -0,0 +1,79 @@
|
||||
<template>
|
||||
<div :class="['flex flex-row items-center gap-2', wrapperClass]">
|
||||
<label
|
||||
v-if="label && label !== 'Autres'"
|
||||
:for="id"
|
||||
class="font-bold text-xl"
|
||||
:class="labelClass"
|
||||
>
|
||||
{{ label }} <span v-if="code">({{ code }})</span>
|
||||
</label>
|
||||
|
||||
<!-- Champ texte si Autres -->
|
||||
<input
|
||||
v-else-if="label === 'Autres'"
|
||||
type="text"
|
||||
:placeholder="'Autres'"
|
||||
class="border-b border-black text-xl bg-transparent- w-48"
|
||||
/>
|
||||
<input
|
||||
:id="id"
|
||||
type="number"
|
||||
:value="modelValue ?? 0"
|
||||
:placeholder="placeholder"
|
||||
:min="min"
|
||||
:max="max"
|
||||
:step="step"
|
||||
:disabled="disabled"
|
||||
v-bind="attrs"
|
||||
class="border-2 border-black text-xl pb-[6px] w-12 bg-transparent ma"
|
||||
:class="[
|
||||
disabled ? 'cursor-not-allowed text-neutral-400' : 'cursor-text text-black',
|
||||
inputClass
|
||||
]"
|
||||
@input="onInput"
|
||||
>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import {useAttrs} from 'vue'
|
||||
|
||||
defineOptions({inheritAttrs: false})
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
id?: string
|
||||
label?: string
|
||||
code?: string
|
||||
modelValue: number | null | undefined
|
||||
placeholder?: string
|
||||
min?: number
|
||||
max?: number
|
||||
step?: number
|
||||
disabled?: boolean
|
||||
wrapperClass?: string
|
||||
labelClass?: string
|
||||
inputClass?: string
|
||||
}>(),
|
||||
{
|
||||
placeholder: '',
|
||||
min: 0,
|
||||
step: 1,
|
||||
disabled: false,
|
||||
wrapperClass: '',
|
||||
labelClass: '',
|
||||
inputClass: ''
|
||||
}
|
||||
)
|
||||
const emit = defineEmits<{
|
||||
(event: 'update:modelValue', value: number): void
|
||||
}>()
|
||||
|
||||
const attrs = useAttrs()
|
||||
|
||||
const onInput = (event: Event) => {
|
||||
const target = event.target as HTMLInputElement
|
||||
emit('update:modelValue', Number(target.value))
|
||||
}
|
||||
</script>
|
||||
@@ -1,64 +1,72 @@
|
||||
{
|
||||
"errors": {
|
||||
"http": {
|
||||
"get": "Impossible de récupérer les données.",
|
||||
"post": "Impossible de créer la ressource.",
|
||||
"put": "Impossible de mettre à jour la ressource.",
|
||||
"patch": "Impossible de mettre à jour la ressource.",
|
||||
"delete": "Impossible de supprimer la ressource."
|
||||
"errors": {
|
||||
"http": {
|
||||
"get": "Impossible de récupérer les données.",
|
||||
"post": "Impossible de créer la ressource.",
|
||||
"put": "Impossible de mettre à jour la ressource.",
|
||||
"patch": "Impossible de mettre à jour la ressource.",
|
||||
"delete": "Impossible de supprimer la ressource."
|
||||
},
|
||||
"reception": {
|
||||
"list": "Impossible de récupérer la liste des réceptions.",
|
||||
"fetch": "Impossible de récupérer la réception.",
|
||||
"create": "Impossible de créer la réception.",
|
||||
"update": "Impossible de mettre à jour la réception.",
|
||||
"weigh": "Impossible de récupérer la pesée."
|
||||
},
|
||||
"receptionType": {
|
||||
"list": "Impossible de récupérer la liste des types de réception."
|
||||
},
|
||||
"merchandiseType": {
|
||||
"list": "Impossible de récupérer la liste des types de marchandises."
|
||||
},
|
||||
"building": {
|
||||
"list": "Impossible de récupérer la liste des bâtiments."
|
||||
},
|
||||
"pelletType": {
|
||||
"list": "Impossible de récupérer la liste des types de granulés."
|
||||
},
|
||||
"receptionPelletBuilding": {
|
||||
"list": "Impossible de récupérer la liste des dépôts de granulés.",
|
||||
"create": "Impossible d'enregistrer le dépôt de granulés.",
|
||||
"delete": "Impossible de supprimer le dépôt de granulés."
|
||||
},
|
||||
"receptionBovine": {
|
||||
"list": "Impossible de récupérer la liste des bovins de la réception.",
|
||||
"create": "Impossible d'enregistrer le bovin.",
|
||||
"delete": "Impossible de supprimer le bovin."
|
||||
},
|
||||
"supplier": {
|
||||
"list": "Impossible de récupérer la liste des fournisseurs."
|
||||
},
|
||||
"truck": {
|
||||
"list": "Impossible de récupérer la liste des camions."
|
||||
},
|
||||
"bovin": {
|
||||
"list": "Impossible de récupérer la liste des races de bovins."
|
||||
},
|
||||
"carrier": {
|
||||
"list": "Impossible de récupérer la liste des transporteurs."
|
||||
},
|
||||
"driver": {
|
||||
"list": "Impossible de récupérer la liste des chauffeurs."
|
||||
},
|
||||
"vehicle": {
|
||||
"list": "Impossible de récupérer la liste des immatriculations."
|
||||
},
|
||||
"auth": {
|
||||
"login": "Identifiants invalides.",
|
||||
"users": "Impossible de récupérer les utilisateurs.",
|
||||
"logout": "Impossible de se déconnecter."
|
||||
}
|
||||
},
|
||||
"reception": {
|
||||
"list": "Impossible de récupérer la liste des réceptions.",
|
||||
"fetch": "Impossible de récupérer la réception.",
|
||||
"create": "Impossible de créer la réception.",
|
||||
"update": "Impossible de mettre à jour la réception.",
|
||||
"weigh": "Impossible de récupérer la pesée."
|
||||
},
|
||||
"receptionType": {
|
||||
"list": "Impossible de récupérer la liste des types de réception."
|
||||
},
|
||||
"merchandiseType": {
|
||||
"list": "Impossible de récupérer la liste des types de marchandises."
|
||||
},
|
||||
"building": {
|
||||
"list": "Impossible de récupérer la liste des bâtiments."
|
||||
},
|
||||
"pelletType": {
|
||||
"list": "Impossible de récupérer la liste des types de granulés."
|
||||
},
|
||||
"receptionPelletBuilding": {
|
||||
"list": "Impossible de récupérer la liste des dépôts de granulés.",
|
||||
"create": "Impossible d'enregistrer le dépôt de granulés.",
|
||||
"delete": "Impossible de supprimer le dépôt de granulés."
|
||||
},
|
||||
"supplier": {
|
||||
"list": "Impossible de récupérer la liste des fournisseurs."
|
||||
},
|
||||
"truck": {
|
||||
"list": "Impossible de récupérer la liste des camions."
|
||||
},
|
||||
"carrier": {
|
||||
"list": "Impossible de récupérer la liste des transporteurs."
|
||||
},
|
||||
"driver": {
|
||||
"list": "Impossible de récupérer la liste des chauffeurs."
|
||||
},
|
||||
"vehicle": {
|
||||
"list": "Impossible de récupérer la liste des immatriculations."
|
||||
},
|
||||
"auth": {
|
||||
"login": "Identifiants invalides.",
|
||||
"users": "Impossible de récupérer les utilisateurs.",
|
||||
"logout": "Impossible de se déconnecter."
|
||||
"success": {
|
||||
"reception": {
|
||||
"update": "Réception mise à jour avec succès."
|
||||
},
|
||||
"auth": {
|
||||
"login": "Connexion réussie.",
|
||||
"logout": "Déconnexion réussie."
|
||||
}
|
||||
}
|
||||
},
|
||||
"success": {
|
||||
"reception": {
|
||||
"update": "Réception mise à jour avec succès."
|
||||
},
|
||||
"auth": {
|
||||
"login": "Connexion réussie.",
|
||||
"logout": "Déconnexion réussie."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
23
frontend/services/bovine-type.ts
Normal file
23
frontend/services/bovine-type.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import { useApi } from '~/composables/useApi'
|
||||
import type {BovineTypeData} from "~/services/dto/bovine-type-data";
|
||||
|
||||
export type BovineTypeListResponse =
|
||||
| BovineTypeData[]
|
||||
| { 'hydra:member'?: BovineTypeData[] }
|
||||
|
||||
export async function getBovineTypeList(): Promise<BovineTypeData[]> {
|
||||
const api = useApi()
|
||||
const response = await api.get<BovineTypeListResponse>('bovine_types', {}, {
|
||||
toastErrorKey: 'errors.bovin.list'
|
||||
})
|
||||
|
||||
if (Array.isArray(response)) {
|
||||
return response
|
||||
}
|
||||
|
||||
if (response && typeof response === 'object' && Array.isArray(response['hydra:member'])) {
|
||||
return response['hydra:member']
|
||||
}
|
||||
|
||||
return []
|
||||
}
|
||||
5
frontend/services/dto/bovine-type-data.ts
Normal file
5
frontend/services/dto/bovine-type-data.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
export interface BovineTypeData{
|
||||
id: number
|
||||
label: string
|
||||
code: string
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
export const RECEPTION_TYPE_CODES = {
|
||||
MERCHANDISES: 'MARCHANDISES'
|
||||
MERCHANDISES: 'MARCHANDISES',
|
||||
BOVINS: 'BOVINS'
|
||||
} as const
|
||||
|
||||
export const MERCHANDISE_TYPE_CODES = {
|
||||
|
||||
Reference in New Issue
Block a user