WIP
This commit is contained in:
@@ -166,6 +166,7 @@ const table = useDataTable(
|
||||
status: { default: 'open' },
|
||||
entityType: { default: '' },
|
||||
},
|
||||
columnFilterKeys: ['entity'],
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@@ -144,7 +144,7 @@ const { componentTypes, loadComponentTypes } = useComponentTypes()
|
||||
|
||||
const table = useDataTable(
|
||||
{ fetchData: fetchComposants },
|
||||
{ defaultSort: 'name', defaultDirection: 'asc', defaultPerPage: 20, persistToUrl: true },
|
||||
{ defaultSort: 'name', defaultDirection: 'asc', defaultPerPage: 20, persistToUrl: true, columnFilterKeys: ['typeComposant'] },
|
||||
)
|
||||
|
||||
const columns = [
|
||||
|
||||
@@ -64,6 +64,7 @@
|
||||
:machine-constructeur-ids="d.machineConstructeurIds.value"
|
||||
:machine-constructeurs-display="d.machineConstructeursDisplay.value"
|
||||
:has-machine-constructeur="d.hasMachineConstructeur.value"
|
||||
:constructeur-links="d.constructeurLinks.value"
|
||||
:visible-custom-fields="d.visibleMachineCustomFields.value"
|
||||
:get-machine-field-id="d.getMachineFieldId"
|
||||
:machine-id="machineId"
|
||||
@@ -72,6 +73,8 @@
|
||||
@update:machine-reference="d.machineReference.value = $event"
|
||||
@update:machine-site-id="d.machineSiteId.value = $event"
|
||||
@update:constructeur-ids="d.handleMachineConstructeurChange"
|
||||
@update:constructeur-links="d.constructeurLinks.value = $event"
|
||||
@remove-constructeur-link="handleRemoveConstructeurLink"
|
||||
@set-custom-field-value="d.setMachineCustomFieldValue"
|
||||
@custom-fields-saved="() => { d.loadMachineData(); refreshVersions() }"
|
||||
/>
|
||||
@@ -196,9 +199,9 @@
|
||||
</div>
|
||||
<h3 class="text-lg font-semibold text-base-content mb-1">Machine non trouvée</h3>
|
||||
<p class="text-sm text-base-content/50 mb-6">La machine avec l'ID "{{ machineId }}" n'existe pas ou a été supprimée.</p>
|
||||
<NuxtLink to="/machines" class="btn btn-primary">
|
||||
<button type="button" class="btn btn-primary" @click="$router.back()">
|
||||
Retour aux machines
|
||||
</NuxtLink>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
@@ -280,6 +283,11 @@ const openAddModal = (kind) => {
|
||||
addModalOpen.value = true
|
||||
}
|
||||
|
||||
const handleRemoveConstructeurLink = (constructeurId) => {
|
||||
const ids = d.machineConstructeurIds.value.filter(id => id !== constructeurId)
|
||||
d.handleMachineConstructeurChange(ids)
|
||||
}
|
||||
|
||||
const handleAddEntity = async (entityId) => {
|
||||
if (addModalKind.value === 'component') {
|
||||
await d.addComponentLink(entityId)
|
||||
|
||||
@@ -120,11 +120,12 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, computed, onMounted } from 'vue'
|
||||
import { ref, reactive, computed, onMounted, watch } from 'vue'
|
||||
import { useMachines } from '~/composables/useMachines'
|
||||
import { useSites } from '~/composables/useSites'
|
||||
import { useToast } from '~/composables/useToast'
|
||||
import { humanizeError } from '~/shared/utils/errorMessages'
|
||||
import { useUrlState } from '~/composables/useUrlState'
|
||||
import IconLucidePlus from '~icons/lucide/plus'
|
||||
import IconLucideFactory from '~icons/lucide/factory'
|
||||
import IconLucideMapPin from '~icons/lucide/map-pin'
|
||||
@@ -135,8 +136,28 @@ const { machines, loading, loadMachines, deleteMachine } = useMachines()
|
||||
const { sites, loadSites } = useSites()
|
||||
const toast = useToast()
|
||||
|
||||
const urlState = useUrlState({
|
||||
q: { default: '', debounce: 300 },
|
||||
sites: { default: '' },
|
||||
})
|
||||
|
||||
const searchQuery = urlState.q
|
||||
const selectedSites = reactive(new Set())
|
||||
const searchQuery = ref('')
|
||||
|
||||
// Sync URL → selectedSites on load and back/forward
|
||||
watch(urlState.sites, (val) => {
|
||||
selectedSites.clear()
|
||||
if (val) {
|
||||
for (const id of String(val).split(',')) {
|
||||
if (id) selectedSites.add(id)
|
||||
}
|
||||
}
|
||||
}, { immediate: true })
|
||||
|
||||
// Sync selectedSites → URL
|
||||
watch(() => [...selectedSites], (ids) => {
|
||||
urlState.sites.value = ids.join(',')
|
||||
})
|
||||
|
||||
// Enrichir les machines avec les objets site complets
|
||||
const enrichedMachines = computed(() => {
|
||||
|
||||
@@ -112,6 +112,8 @@ const loadCategory = async () => {
|
||||
category: response.category,
|
||||
notes: response.notes ?? response.description ?? '',
|
||||
structure: (response.structure as PieceModelStructure | null) ?? undefined,
|
||||
referenceFormula: response.referenceFormula ?? null,
|
||||
requiredFieldsForReference: response.requiredFieldsForReference ?? null,
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
|
||||
@@ -171,7 +171,7 @@ const { pieceTypes, loadPieceTypes } = usePieceTypes()
|
||||
|
||||
const table = useDataTable(
|
||||
{ fetchData: fetchPieces },
|
||||
{ defaultSort: 'name', defaultDirection: 'asc', defaultPerPage: 20, persistToUrl: true },
|
||||
{ defaultSort: 'name', defaultDirection: 'asc', defaultPerPage: 20, persistToUrl: true, columnFilterKeys: ['typePiece'] },
|
||||
)
|
||||
|
||||
const columns = [
|
||||
|
||||
@@ -91,6 +91,10 @@
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<ConstructeurLinksTable
|
||||
v-if="constructeurLinks.length"
|
||||
v-model="constructeurLinks"
|
||||
/>
|
||||
|
||||
<div class="grid grid-cols-1 gap-4 md:grid-cols-2">
|
||||
<div class="form-control">
|
||||
@@ -213,6 +217,7 @@
|
||||
import { computed, onMounted, reactive, ref, watch } from 'vue'
|
||||
import { useRoute, useRouter } from '#imports'
|
||||
import ConstructeurSelect from '~/components/ConstructeurSelect.vue'
|
||||
import ConstructeurLinksTable from '~/components/ConstructeurLinksTable.vue'
|
||||
import DocumentUpload from '~/components/DocumentUpload.vue'
|
||||
import ProductSelect from '~/components/ProductSelect.vue'
|
||||
import SearchSelect from '~/components/common/SearchSelect.vue'
|
||||
@@ -222,8 +227,11 @@ import { useToast } from '~/composables/useToast'
|
||||
import { humanizeError } from '~/shared/utils/errorMessages'
|
||||
import { useCustomFields } from '~/composables/useCustomFields'
|
||||
import { useDocuments } from '~/composables/useDocuments'
|
||||
import { useConstructeurLinks } from '~/composables/useConstructeurLinks'
|
||||
import { useConstructeurs } from '~/composables/useConstructeurs'
|
||||
import { formatPieceStructurePreview } from '~/shared/modelUtils'
|
||||
import { uniqueConstructeurIds } from '~/shared/constructeurUtils'
|
||||
import { constructeurIdsFromLinks } from '~/shared/constructeurUtils'
|
||||
import type { ConstructeurLinkEntry } from '~/shared/constructeurUtils'
|
||||
import type { PieceModelStructure } from '~/shared/types/inventory'
|
||||
import type { ModelType } from '~/services/modelTypes'
|
||||
import {
|
||||
@@ -255,6 +263,8 @@ const { createPiece } = usePieces()
|
||||
const toast = useToast()
|
||||
const { upsertCustomFieldValue, updateCustomFieldValue } = useCustomFields()
|
||||
const { uploadDocuments } = useDocuments()
|
||||
const { syncLinks } = useConstructeurLinks()
|
||||
const { getConstructeurById } = useConstructeurs()
|
||||
const { canEdit } = usePermissions()
|
||||
|
||||
const initialTypeId = ref<string>(typeof route.query.typeId === 'string' ? route.query.typeId : '')
|
||||
@@ -267,6 +277,7 @@ const creationForm = reactive({
|
||||
constructeurIds: [] as string[],
|
||||
prix: '' as string,
|
||||
})
|
||||
const constructeurLinks = ref<ConstructeurLinkEntry[]>([])
|
||||
const productSelections = ref<(string | null)[]>([])
|
||||
|
||||
const lastSuggestedName = ref('')
|
||||
@@ -380,6 +391,7 @@ const clearCreationForm = () => {
|
||||
creationForm.description = ''
|
||||
creationForm.reference = ''
|
||||
creationForm.constructeurIds = []
|
||||
constructeurLinks.value = []
|
||||
creationForm.prix = ''
|
||||
productSelections.value = []
|
||||
lastSuggestedName.value = ''
|
||||
@@ -411,8 +423,6 @@ const submitCreation = async () => {
|
||||
payload.reference = reference
|
||||
}
|
||||
|
||||
payload.constructeurIds = uniqueConstructeurIds(creationForm.constructeurIds)
|
||||
|
||||
const normalizedProductIds = collectNormalizedProductIds(
|
||||
productRequirementEntries.value,
|
||||
productSelections.value,
|
||||
@@ -448,6 +458,10 @@ const submitCreation = async () => {
|
||||
],
|
||||
{ customFieldInputs, upsertCustomFieldValue, updateCustomFieldValue, toast },
|
||||
)
|
||||
// Sync constructeur links after creation
|
||||
if (constructeurLinks.value.length) {
|
||||
await syncLinks('piece', createdPiece.id, [], constructeurLinks.value)
|
||||
}
|
||||
if (selectedDocuments.value.length && createdPiece.id) {
|
||||
uploadingDocuments.value = true
|
||||
const uploadResult = await uploadDocuments(
|
||||
@@ -478,6 +492,26 @@ const submitCreation = async () => {
|
||||
}
|
||||
}
|
||||
|
||||
// Sync constructeurIds → constructeurLinks when IDs are added via ConstructeurSelect
|
||||
watch(
|
||||
() => creationForm.constructeurIds,
|
||||
(ids) => {
|
||||
const currentIds = new Set(constructeurLinks.value.map(l => l.constructeurId))
|
||||
for (const id of ids) {
|
||||
if (!currentIds.has(id)) {
|
||||
const resolved = getConstructeurById(id)
|
||||
constructeurLinks.value.push({
|
||||
constructeurId: id,
|
||||
constructeur: resolved ? { id: resolved.id, name: resolved.name } : null,
|
||||
supplierReference: null,
|
||||
})
|
||||
}
|
||||
}
|
||||
constructeurLinks.value = constructeurLinks.value.filter(l => ids.includes(l.constructeurId))
|
||||
},
|
||||
{ deep: true },
|
||||
)
|
||||
|
||||
onMounted(async () => {
|
||||
await loadPieceTypes()
|
||||
})
|
||||
|
||||
@@ -175,7 +175,7 @@ const toast = useToast()
|
||||
|
||||
const table = useDataTable(
|
||||
{ fetchData: fetchProducts },
|
||||
{ defaultSort: 'name', defaultDirection: 'asc', defaultPerPage: 20, persistToUrl: true },
|
||||
{ defaultSort: 'name', defaultDirection: 'asc', defaultPerPage: 20, persistToUrl: true, columnFilterKeys: ['typeProduct'] },
|
||||
)
|
||||
|
||||
const errorMessage = computed(() => (typeof error.value === 'string' && error.value.length ? error.value : null))
|
||||
|
||||
Reference in New Issue
Block a user