diff --git a/app/components/ComponentModelStructureEditor.vue b/app/components/ComponentModelStructureEditor.vue index 14869e2..40b6905 100644 --- a/app/components/ComponentModelStructureEditor.vue +++ b/app/components/ComponentModelStructureEditor.vue @@ -115,7 +115,7 @@ const applyCustomFieldOptions = (node: Record | null | undefined) = } if (Array.isArray(node.customFields)) { - node.customFields = node.customFields.map((field: any) => { + node.customFields = node.customFields.map((field: Record) => { if (!field || typeof field !== 'object') { return field } @@ -145,7 +145,7 @@ const applyCustomFieldOptions = (node: Record | null | undefined) = } if (Array.isArray(node.subcomponents)) { - node.subcomponents = node.subcomponents.map((sub: any) => { + node.subcomponents = node.subcomponents.map((sub: Record) => { if (!sub || typeof sub !== 'object') { return sub } @@ -246,7 +246,7 @@ watch( ) onMounted(async () => { - const loaders: Promise[] = [] + const loaders: Promise[] = [] if (!availablePieceTypes.value.length) { loaders.push(loadPieceTypes()) } diff --git a/app/components/ComponentStructureAssignmentNode.vue b/app/components/ComponentStructureAssignmentNode.vue index 2d6b86c..c9f3037 100644 --- a/app/components/ComponentStructureAssignmentNode.vue +++ b/app/components/ComponentStructureAssignmentNode.vue @@ -137,6 +137,7 @@ import { computed, ref, watch } from 'vue'; import SearchSelect from '~/components/common/SearchSelect.vue'; import { useApi } from '~/composables/useApi'; +import { extractCollection } from '~/shared/utils/apiHelpers'; import type { ComponentModelPiece, ComponentModelProduct, @@ -243,22 +244,6 @@ const pieceLoadingByPath = ref>({}); const productLoadingByPath = ref>({}); const componentLoadingByPath = ref>({}); -const extractCollection = (payload: any): any[] => { - if (Array.isArray(payload)) { - return payload; - } - if (Array.isArray(payload?.member)) { - return payload.member; - } - if (Array.isArray(payload?.['hydra:member'])) { - return payload['hydra:member']; - } - if (Array.isArray(payload?.data)) { - return payload.data; - } - return []; -}; - const setLoading = (target: Record, key: string, value: boolean) => { target[key] = value; }; @@ -362,7 +347,7 @@ const fetchPieceOptions = async (assignment: StructurePieceAssignment, term = '' const definition = assignment.definition || {}; const requiredTypeId = - definition.typePieceId || (definition as any).typePiece?.id || null; + definition.typePieceId || definition.typePiece?.id || null; const params = new URLSearchParams(); params.set('itemsPerPage', '50'); @@ -392,7 +377,7 @@ const fetchProductOptions = async (assignment: StructureProductAssignment, term const definition = assignment.definition || {}; const requiredTypeId = - definition.typeProductId || (definition as any).typeProduct?.id || null; + definition.typeProductId || definition.typeProduct?.id || null; const params = new URLSearchParams(); params.set('itemsPerPage', '50'); @@ -447,14 +432,14 @@ const describePieceRequirement = (assignment: StructurePieceAssignment) => { addPart(definition.role); const explicitLabel = definition.typePieceLabel || - (definition as any).typePiece?.name || + definition.typePiece?.name || (definition.typePieceId ? props.pieceTypeLabelMap[definition.typePieceId] : null) || fallbackType?.name; addPart(explicitLabel); const family = definition.familyCode || - (definition as any).typePiece?.code || + definition.typePiece?.code || fallbackType?.code || null; if (family) { @@ -483,7 +468,7 @@ const getProductOptions = (assignment: StructureProductAssignment) => { const definition = assignment.definition; const requiredTypeId = definition.typeProductId || - (definition as any).typeProduct?.id || + definition.typeProduct?.id || definition.familyCode || null; @@ -494,7 +479,7 @@ const getProductOptions = (assignment: StructureProductAssignment) => { if (!requiredTypeId) { return true; } - if (definition.typeProductId || (definition as any).typeProduct?.id) { + if (definition.typeProductId || definition.typeProduct?.id) { return ( product.typeProductId === requiredTypeId || product.typeProduct?.id === requiredTypeId @@ -550,14 +535,14 @@ const describeProductRequirement = (assignment: StructureProductAssignment) => { addPart(definition.role); const explicitLabel = definition.typeProductLabel || - (definition as any).typeProduct?.name || + definition.typeProduct?.name || (definition.typeProductId ? props.productTypeLabelMap[definition.typeProductId] : null) || fallbackType?.name; addPart(explicitLabel); const family = definition.familyCode || - (definition as any).typeProduct?.code || + definition.typeProduct?.code || fallbackType?.code || null; if (family) { @@ -617,7 +602,7 @@ const getPieceOptions = (assignment: StructurePieceAssignment) => { const definition = assignment.definition; const requiredTypeId = definition.typePieceId || - (definition as any).typePiece?.id || + definition.typePiece?.id || definition.familyCode || null; @@ -628,7 +613,7 @@ const getPieceOptions = (assignment: StructurePieceAssignment) => { if (!requiredTypeId) { return true; } - if (definition.typePieceId || (definition as any).typePiece?.id) { + if (definition.typePieceId || definition.typePiece?.id) { return ( piece.typePieceId === requiredTypeId || piece.typePiece?.id === requiredTypeId diff --git a/app/components/model-types/ManagementView.vue b/app/components/model-types/ManagementView.vue index c88b553..4261cf9 100644 --- a/app/components/model-types/ManagementView.vue +++ b/app/components/model-types/ManagementView.vue @@ -97,6 +97,7 @@ import { useHead, useRouter } from "#imports"; import ModelTypesToolbar from "~/components/model-types/Toolbar.vue"; import ModelTypesTable from "~/components/model-types/Table.vue"; import { useApi } from "~/composables/useApi"; +import { extractCollection } from "~/shared/utils/apiHelpers"; import { deleteModelType, listModelTypes, @@ -153,7 +154,7 @@ useHead(() => ({ const extractErrorMessage = (error: unknown) => { if (error && typeof error === "object") { const maybeFetchError = error as { - data?: any; + data?: Record; statusMessage?: string; message?: string; }; @@ -208,8 +209,8 @@ const refresh = async ({ total.value = response.total; offset.value = response.offset; limit.value = response.limit; - } catch (error: any) { - if (error?.name === "AbortError") { + } catch (error: unknown) { + if (error && typeof error === "object" && (error as { name?: string }).name === "AbortError") { return; } showError(extractErrorMessage(error)); @@ -292,10 +293,12 @@ const openEditPage = (item: ModelType) => { }); }; +const { confirm } = useConfirm() + const confirmDelete = async (item: ModelType) => { - const confirmed = window.confirm( - "Supprimer ce type ? Cette action est irréversible." - ); + const confirmed = await confirm({ + message: 'Supprimer ce type ? Cette action est irréversible.', + }); if (!confirmed) { return; } @@ -363,22 +366,6 @@ const relatedModalSubtitle = computed(() => { return `${count} ${labels.plural} liés.`; }); -const extractCollection = (payload: any): any[] => { - if (Array.isArray(payload)) { - return payload; - } - if (Array.isArray(payload?.member)) { - return payload.member; - } - if (Array.isArray(payload?.["hydra:member"])) { - return payload["hydra:member"]; - } - if (Array.isArray(payload?.items)) { - return payload.items; - } - return []; -}; - const buildModelTypeIri = (id: string) => `/api/model_types/${id}`; const resolveRelatedConfig = (category: ModelCategory) => { @@ -401,22 +388,26 @@ const resolveRelatedEditBasePath = (category: ModelCategory) => { return "/product"; }; -const mapRelatedEntry = (item: any): RelatedEntry | null => { - if (!item || typeof item !== "object" || typeof item.id !== "string") { +const mapRelatedEntry = (item: unknown): RelatedEntry | null => { + if (!item || typeof item !== "object") { + return null; + } + const record = item as Record; + if (typeof record.id !== "string") { return null; } const name = - typeof item.name === "string" && item.name.trim() - ? item.name + typeof record.name === "string" && record.name.trim() + ? record.name : "Sans nom"; const reference = - typeof item.reference === "string" && item.reference.trim() - ? item.reference - : typeof item.code === "string" && item.code.trim() - ? item.code + typeof record.reference === "string" && record.reference.trim() + ? record.reference + : typeof record.code === "string" && record.code.trim() + ? record.code : null; return { - id: item.id, + id: record.id, name, reference, }; diff --git a/app/components/model-types/ModelTypeForm.vue b/app/components/model-types/ModelTypeForm.vue index b4ca544..a6ac478 100644 --- a/app/components/model-types/ModelTypeForm.vue +++ b/app/components/model-types/ModelTypeForm.vue @@ -278,10 +278,11 @@ const resetForm = () => { ? incoming.code : generateCodeFromName(form.name) form.category = incoming.category ?? props.initialCategory + const incomingRecord = incoming as Record form.notes = typeof incoming.notes === 'string' ? incoming.notes - : typeof (incoming as any).description === 'string' - ? (incoming as any).description + : typeof incomingRecord.description === 'string' + ? incomingRecord.description : '' errors.name = undefined diff --git a/app/shared/types/inventory.ts b/app/shared/types/inventory.ts index b462f91..a99b335 100644 --- a/app/shared/types/inventory.ts +++ b/app/shared/types/inventory.ts @@ -17,6 +17,7 @@ export interface ComponentModelCustomField { export interface ComponentModelPiece { typePieceId?: string typePieceLabel?: string + typePiece?: { id?: string; name?: string; code?: string } | null reference?: string familyCode?: string role?: string @@ -25,6 +26,7 @@ export interface ComponentModelPiece { export interface ComponentModelProduct { typeProductId?: string typeProductLabel?: string + typeProduct?: { id?: string; name?: string; code?: string } | null reference?: string familyCode?: string role?: string @@ -33,6 +35,7 @@ export interface ComponentModelProduct { export interface ComponentModelStructureNode { typeComposantId?: string typeComposantLabel?: string + typeComposant?: { id?: string; name?: string } modelId?: string familyCode?: string alias?: string @@ -151,8 +154,8 @@ const validatePiece = ( const typePieceId = ensureString(value.typePieceId) const typePieceLabel = ensureString(value.typePieceLabel) const reference = ensureString(value.reference) - const familyCode = ensureString((value as any).familyCode) - const role = ensureString((value as any).role) + const familyCode = ensureString(value.familyCode) + const role = ensureString(value.role) if (!typePieceId && !typePieceLabel && !reference && !familyCode) { issues.push(`${path}: au moins un identifiant, une famille ou une référence de pièce est requis`) @@ -184,8 +187,8 @@ const validateStructureNode = ( const familyCode = ensureString(value.familyCode) const alias = ensureString(value.alias) - const rawSubcomponents = Array.isArray((value as any).subcomponents) - ? (value as any).subcomponents + const rawSubcomponents = Array.isArray(value.subcomponents) + ? value.subcomponents : [] const subcomponents: ComponentModelStructureNode[] = []