refactor(types): eliminate explicit any casts across components (F3.3)
Extend ComponentModelPiece/Product with optional typePiece/typeProduct nested objects. Replace 12 'as any' casts in assignment node, convert Promise<any> to Promise<unknown>, use Record<string, unknown> at API boundaries. ~15 casts eliminated. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -115,7 +115,7 @@ const applyCustomFieldOptions = (node: Record<string, any> | null | undefined) =
|
||||
}
|
||||
|
||||
if (Array.isArray(node.customFields)) {
|
||||
node.customFields = node.customFields.map((field: any) => {
|
||||
node.customFields = node.customFields.map((field: Record<string, any>) => {
|
||||
if (!field || typeof field !== 'object') {
|
||||
return field
|
||||
}
|
||||
@@ -145,7 +145,7 @@ const applyCustomFieldOptions = (node: Record<string, any> | null | undefined) =
|
||||
}
|
||||
|
||||
if (Array.isArray(node.subcomponents)) {
|
||||
node.subcomponents = node.subcomponents.map((sub: any) => {
|
||||
node.subcomponents = node.subcomponents.map((sub: Record<string, any>) => {
|
||||
if (!sub || typeof sub !== 'object') {
|
||||
return sub
|
||||
}
|
||||
@@ -246,7 +246,7 @@ watch(
|
||||
)
|
||||
|
||||
onMounted(async () => {
|
||||
const loaders: Promise<any>[] = []
|
||||
const loaders: Promise<unknown>[] = []
|
||||
if (!availablePieceTypes.value.length) {
|
||||
loaders.push(loadPieceTypes())
|
||||
}
|
||||
|
||||
@@ -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<Record<string, boolean>>({});
|
||||
const productLoadingByPath = ref<Record<string, boolean>>({});
|
||||
const componentLoadingByPath = ref<Record<string, boolean>>({});
|
||||
|
||||
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<string, boolean>, 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
|
||||
|
||||
@@ -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<string, unknown>;
|
||||
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<string, unknown>;
|
||||
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,
|
||||
};
|
||||
|
||||
@@ -278,10 +278,11 @@ const resetForm = () => {
|
||||
? incoming.code
|
||||
: generateCodeFromName(form.name)
|
||||
form.category = incoming.category ?? props.initialCategory
|
||||
const incomingRecord = incoming as Record<string, unknown>
|
||||
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
|
||||
|
||||
@@ -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[] = []
|
||||
|
||||
Reference in New Issue
Block a user