chore: update frontend configuration

This commit is contained in:
Matthieu
2025-09-26 11:29:47 +02:00
parent b7caa4f552
commit a78938a4d1
64 changed files with 5790 additions and 5129 deletions

View File

@@ -1,6 +1,6 @@
import { useToast } from './useToast'
export function useApi() {
export function useApi () {
const { showSuccess, showError, showInfo } = useToast()
const { public: publicConfig } = useRuntimeConfig()
const API_BASE_URL = publicConfig.apiBaseUrl || 'http://localhost:3000'
@@ -11,8 +11,8 @@ export function useApi() {
const url = `${API_BASE_URL}${endpoint}`
const defaultOptions = {
headers: {
'Content-Type': 'application/json',
},
'Content-Type': 'application/json'
}
}
// Ajouter un timeout à la requête
@@ -20,14 +20,14 @@ export function useApi() {
const timeoutId = setTimeout(() => controller.abort(), API_TIMEOUT)
try {
const response = await fetch(url, {
...defaultOptions,
const response = await fetch(url, {
...defaultOptions,
...options,
signal: controller.signal
})
clearTimeout(timeoutId)
if (response.ok) {
const data = await response.json()
return { success: true, data }

View File

@@ -5,7 +5,7 @@ import { useToast } from './useToast'
const componentModelsBuckets = ref({})
const loadingComponentModels = ref(false)
export function useComponentModels() {
export function useComponentModels () {
const { get, post, patch, delete: del } = useApi()
const { showSuccess, showError } = useToast()
@@ -18,7 +18,7 @@ export function useComponentModels() {
const key = typeComposantId || '__all__'
componentModelsBuckets.value = {
...componentModelsBuckets.value,
[key]: result.data,
[key]: result.data
}
}
return result
@@ -39,7 +39,7 @@ export function useComponentModels() {
const bucket = componentModelsBuckets.value[key] || []
componentModelsBuckets.value = {
...componentModelsBuckets.value,
[key]: [...bucket, result.data],
[key]: [...bucket, result.data]
}
showSuccess(`Modèle de composant "${result.data.name}" créé`)
}
@@ -59,12 +59,12 @@ export function useComponentModels() {
if (result.success) {
const key = result.data?.typeComposantId || '__all__'
const bucket = componentModelsBuckets.value[key] || []
const updatedBucket = bucket.map((model) =>
const updatedBucket = bucket.map(model =>
model.id === id ? result.data : model
)
componentModelsBuckets.value = {
...componentModelsBuckets.value,
[key]: updatedBucket,
[key]: updatedBucket
}
showSuccess(`Modèle de composant "${result.data.name}" mis à jour`)
}
@@ -84,7 +84,7 @@ export function useComponentModels() {
if (result.success) {
const updatedBuckets = {}
for (const [key, bucket] of Object.entries(componentModelsBuckets.value)) {
updatedBuckets[key] = bucket.filter((model) => model.id !== id)
updatedBuckets[key] = bucket.filter(model => model.id !== id)
}
componentModelsBuckets.value = updatedBuckets
showSuccess('Modèle de composant supprimé')
@@ -101,7 +101,7 @@ export function useComponentModels() {
const allComponentModels = computed(() => {
return Object.values(componentModelsBuckets.value).reduce((acc, bucket) => {
bucket.forEach((model) => {
if (!acc.find((existing) => existing.id === model.id)) {
if (!acc.find(existing => existing.id === model.id)) {
acc.push(model)
}
})
@@ -126,6 +126,6 @@ export function useComponentModels() {
deleteComponentModel,
getComponentModels,
getComponentModelsForType,
isComponentModelLoading,
isComponentModelLoading
}
}

View File

@@ -1,17 +1,17 @@
import { ref } from 'vue'
import { listModelTypes, createModelType, updateModelType, deleteModelType } from '~/services/modelTypes'
import { useToast } from './useToast'
import { listModelTypes, createModelType, updateModelType, deleteModelType } from '~/services/modelTypes'
const componentTypes = ref([])
const loadingComponentTypes = ref(false)
export function useComponentTypes() {
export function useComponentTypes () {
const { showSuccess, showError } = useToast()
const generateCodeFromName = (name) => {
return (name || '')
.normalize('NFD')
.replace(/[\u0300-\u036f]/g, '')
.replace(/[\u0300-\u036F]/g, '')
.toLowerCase()
.replace(/[^a-z0-9]+/g, '-')
.replace(/^-+|-+$/g, '')
@@ -25,12 +25,12 @@ export function useComponentTypes() {
category: 'COMPONENT',
sort: 'name',
dir: 'asc',
limit: 200,
limit: 200
})
componentTypes.value = data.items.map((item) => ({
componentTypes.value = data.items.map(item => ({
...item,
description: item.description ?? item.notes ?? null,
description: item.description ?? item.notes ?? null
}))
return { success: true, data: componentTypes.value }
@@ -51,12 +51,12 @@ export function useComponentTypes() {
code: payload.code || generateCodeFromName(payload.name),
category: 'COMPONENT',
notes: payload.description ?? payload.notes,
description: payload.description ?? null,
description: payload.description ?? null
})
const normalized = {
...data,
description: data.description ?? data.notes ?? null,
description: data.description ?? data.notes ?? null
}
componentTypes.value.push(normalized)
@@ -79,15 +79,15 @@ export function useComponentTypes() {
name: payload.name,
description: payload.description,
notes: payload.notes,
code: payload.code,
code: payload.code
})
const normalized = {
...data,
description: data.description ?? data.notes ?? null,
description: data.description ?? data.notes ?? null
}
const index = componentTypes.value.findIndex((type) => type.id === id)
const index = componentTypes.value.findIndex(type => type.id === id)
if (index !== -1) {
componentTypes.value[index] = normalized
}
@@ -95,7 +95,7 @@ export function useComponentTypes() {
return {
success: true,
data: normalized,
data: normalized
}
} catch (error) {
const message = error?.data?.message || error?.message || 'Erreur inconnue'
@@ -110,7 +110,7 @@ export function useComponentTypes() {
loadingComponentTypes.value = true
try {
await deleteModelType(id)
componentTypes.value = componentTypes.value.filter((type) => type.id !== id)
componentTypes.value = componentTypes.value.filter(type => type.id !== id)
showSuccess('Type de composant supprimé')
return { success: true }
} catch (error) {
@@ -133,6 +133,6 @@ export function useComponentTypes() {
updateComponentType,
deleteComponentType,
getComponentTypes,
isComponentTypeLoading,
isComponentTypeLoading
}
}

View File

@@ -5,7 +5,7 @@ import { useApi } from './useApi'
const composants = ref([])
const loading = ref(false)
export function useComposants() {
export function useComposants () {
const { showSuccess, showError, showInfo } = useToast()
const { get, post, patch, delete: del } = useApi()
@@ -132,4 +132,4 @@ export function useComposants() {
getComposants,
isLoading
}
}
}

View File

@@ -5,7 +5,7 @@ import { useToast } from './useToast'
const constructeurs = ref([])
const loading = ref(false)
export function useConstructeurs() {
export function useConstructeurs () {
const { get, post, patch, delete: del } = useApi()
const { showSuccess, showError } = useToast()
@@ -43,7 +43,7 @@ export function useConstructeurs() {
return result
} catch (error) {
console.error('Erreur lors de la création du constructeur:', error)
showError("Impossible de créer le constructeur")
showError('Impossible de créer le constructeur')
return { success: false, error: error.message }
} finally {
loading.value = false
@@ -66,7 +66,7 @@ export function useConstructeurs() {
return result
} catch (error) {
console.error('Erreur lors de la mise à jour du constructeur:', error)
showError("Impossible de mettre à jour le constructeur")
showError('Impossible de mettre à jour le constructeur')
return { success: false, error: error.message }
} finally {
loading.value = false
@@ -86,14 +86,14 @@ export function useConstructeurs() {
return result
} catch (error) {
console.error('Erreur lors de la suppression du constructeur:', error)
showError("Impossible de supprimer le constructeur")
showError('Impossible de supprimer le constructeur')
return { success: false, error: error.message }
} finally {
loading.value = false
}
}
const getConstructeurById = (id) => constructeurs.value.find(item => item.id === id)
const getConstructeurById = id => constructeurs.value.find(item => item.id === id)
return {
constructeurs,
@@ -103,6 +103,6 @@ export function useConstructeurs() {
createConstructeur,
updateConstructeur,
deleteConstructeur,
getConstructeurById,
getConstructeurById
}
}

View File

@@ -1,7 +1,7 @@
import { ref } from 'vue'
import { useApi } from './useApi'
export function useCustomFields() {
export function useCustomFields () {
const { apiCall } = useApi()
const customFieldValues = ref([])
const loading = ref(false)
@@ -94,4 +94,4 @@ export function useCustomFields() {
upsertCustomFieldValue,
deleteCustomFieldValue
}
}
}

View File

@@ -5,7 +5,7 @@ import { useToast } from './useToast'
const documents = ref([])
const loading = ref(false)
const fileToBase64 = (file) =>
const fileToBase64 = file =>
new Promise((resolve, reject) => {
const reader = new FileReader()
reader.onload = () => resolve(reader.result)
@@ -13,7 +13,7 @@ const fileToBase64 = (file) =>
reader.readAsDataURL(file)
})
export function useDocuments() {
export function useDocuments () {
const { get, post, delete: del } = useApi()
const { showError, showSuccess } = useToast()
@@ -34,7 +34,7 @@ export function useDocuments() {
return result
} catch (error) {
console.error(`Erreur lors du chargement des documents (${endpoint}):`, error)
showError("Impossible de charger les documents")
showError('Impossible de charger les documents')
return { success: false, error: error.message }
} finally {
loading.value = false
@@ -46,27 +46,27 @@ export function useDocuments() {
}
const loadDocumentsBySite = async (siteId, options = {}) => {
if (!siteId) return { success: false, error: 'Aucun site sélectionné' }
if (!siteId) { return { success: false, error: 'Aucun site sélectionné' } }
return loadFromEndpoint(`/documents/site/${siteId}`, { updateStore: options.updateStore ?? false })
}
const loadDocumentsByMachine = async (machineId, options = {}) => {
if (!machineId) return { success: false, error: 'Aucune machine sélectionnée' }
if (!machineId) { return { success: false, error: 'Aucune machine sélectionnée' } }
return loadFromEndpoint(`/documents/machine/${machineId}`, { updateStore: options.updateStore ?? false })
}
const loadDocumentsByComponent = async (componentId, options = {}) => {
if (!componentId) return { success: false, error: 'Aucun composant sélectionné' }
if (!componentId) { return { success: false, error: 'Aucun composant sélectionné' } }
return loadFromEndpoint(`/documents/composant/${componentId}`, { updateStore: options.updateStore ?? false })
}
const loadDocumentsByPiece = async (pieceId, options = {}) => {
if (!pieceId) return { success: false, error: 'Aucune pièce sélectionnée' }
if (!pieceId) { return { success: false, error: 'Aucune pièce sélectionnée' } }
return loadFromEndpoint(`/documents/piece/${pieceId}`, { updateStore: options.updateStore ?? false })
}
const uploadDocuments = async ({ files = [], context = {} }, { updateStore = false } = {}) => {
if (!files.length) return { success: false, error: 'Aucun fichier sélectionné' }
if (!files.length) { return { success: false, error: 'Aucun fichier sélectionné' } }
loading.value = true
const created = []
@@ -81,7 +81,7 @@ export function useDocuments() {
mimeType: file.type || 'application/octet-stream',
size: file.size,
path: dataUrl,
...context,
...context
}
const result = await post('/documents', payload)
@@ -111,7 +111,7 @@ export function useDocuments() {
}
const deleteDocument = async (id, { updateStore = false } = {}) => {
if (!id) return { success: false, error: 'Identifiant manquant' }
if (!id) { return { success: false, error: 'Identifiant manquant' } }
loading.value = true
try {
@@ -125,7 +125,7 @@ export function useDocuments() {
return result
} catch (error) {
console.error('Erreur lors de la suppression du document:', error)
showError("Impossible de supprimer le document")
showError('Impossible de supprimer le document')
return { success: false, error: error.message }
} finally {
loading.value = false
@@ -141,6 +141,6 @@ export function useDocuments() {
loadDocumentsByComponent,
loadDocumentsByPiece,
uploadDocuments,
deleteDocument,
deleteDocument
}
}

View File

@@ -5,7 +5,7 @@ import { useApi } from './useApi'
const machineTypes = ref([])
const loading = ref(false)
export function useMachineTypesApi() {
export function useMachineTypesApi () {
const { showSuccess, showError, showInfo } = useToast()
const { get, post, patch, delete: del } = useApi()
@@ -85,7 +85,7 @@ export function useMachineTypesApi() {
if (localType) {
return { success: true, data: localType }
}
// Si pas trouvé localement, récupérer depuis l'API
try {
const result = await get(`/types/machines/${id}`)
@@ -114,4 +114,4 @@ export function useMachineTypesApi() {
getMachineTypes,
isLoading
}
}
}

View File

@@ -5,7 +5,7 @@ import { useApi } from './useApi'
const machines = ref([])
const loading = ref(false)
export function useMachines() {
export function useMachines () {
const { showSuccess, showError, showInfo } = useToast()
const { get, post, patch, delete: del } = useApi()
@@ -45,7 +45,7 @@ export function useMachines() {
// Créer la machine avec la structure héritée du type
const machineWithStructure = {
...machineData,
typeMachineId: typeMachine.id,
typeMachineId: typeMachine.id
// La structure sera automatiquement héritée du type
// Les composants et pièces seront créés automatiquement
}

View File

@@ -5,7 +5,7 @@ import { useToast } from './useToast'
const pieceModelsBuckets = ref({})
const loadingPieceModels = ref(false)
export function usePieceModels() {
export function usePieceModels () {
const { get, post, patch, delete: del } = useApi()
const { showSuccess, showError } = useToast()
@@ -18,7 +18,7 @@ export function usePieceModels() {
const key = typePieceId || '__all__'
pieceModelsBuckets.value = {
...pieceModelsBuckets.value,
[key]: result.data,
[key]: result.data
}
}
return result
@@ -39,7 +39,7 @@ export function usePieceModels() {
const bucket = pieceModelsBuckets.value[key] || []
pieceModelsBuckets.value = {
...pieceModelsBuckets.value,
[key]: [...bucket, result.data],
[key]: [...bucket, result.data]
}
showSuccess(`Modèle de pièce "${result.data.name}" créé`)
}
@@ -59,12 +59,12 @@ export function usePieceModels() {
if (result.success) {
const key = result.data?.typePieceId || '__all__'
const bucket = pieceModelsBuckets.value[key] || []
const updatedBucket = bucket.map((model) =>
const updatedBucket = bucket.map(model =>
model.id === id ? result.data : model
)
pieceModelsBuckets.value = {
...pieceModelsBuckets.value,
[key]: updatedBucket,
[key]: updatedBucket
}
showSuccess(`Modèle de pièce "${result.data.name}" mis à jour`)
}
@@ -84,7 +84,7 @@ export function usePieceModels() {
if (result.success) {
const updatedBuckets = {}
for (const [key, bucket] of Object.entries(pieceModelsBuckets.value)) {
updatedBuckets[key] = bucket.filter((model) => model.id !== id)
updatedBuckets[key] = bucket.filter(model => model.id !== id)
}
pieceModelsBuckets.value = updatedBuckets
showSuccess('Modèle de pièce supprimé')
@@ -101,7 +101,7 @@ export function usePieceModels() {
const allPieceModels = computed(() => {
return Object.values(pieceModelsBuckets.value).reduce((acc, bucket) => {
bucket.forEach((model) => {
if (!acc.find((existing) => existing.id === model.id)) {
if (!acc.find(existing => existing.id === model.id)) {
acc.push(model)
}
})
@@ -126,6 +126,6 @@ export function usePieceModels() {
deletePieceModel,
getPieceModels,
getPieceModelsForType,
isPieceModelLoading,
isPieceModelLoading
}
}

View File

@@ -1,17 +1,17 @@
import { ref } from 'vue'
import { listModelTypes, createModelType, updateModelType, deleteModelType } from '~/services/modelTypes'
import { useToast } from './useToast'
import { listModelTypes, createModelType, updateModelType, deleteModelType } from '~/services/modelTypes'
const pieceTypes = ref([])
const loadingPieceTypes = ref(false)
export function usePieceTypes() {
export function usePieceTypes () {
const { showSuccess, showError } = useToast()
const generateCodeFromName = (name) => {
return (name || '')
.normalize('NFD')
.replace(/[\u0300-\u036f]/g, '')
.replace(/[\u0300-\u036F]/g, '')
.toLowerCase()
.replace(/[^a-z0-9]+/g, '-')
.replace(/^-+|-+$/g, '')
@@ -25,12 +25,12 @@ export function usePieceTypes() {
category: 'PIECE',
sort: 'name',
dir: 'asc',
limit: 200,
limit: 200
})
pieceTypes.value = data.items.map((item) => ({
pieceTypes.value = data.items.map(item => ({
...item,
description: item.description ?? item.notes ?? null,
description: item.description ?? item.notes ?? null
}))
return { success: true, data: pieceTypes.value }
@@ -51,12 +51,12 @@ export function usePieceTypes() {
code: payload.code || generateCodeFromName(payload.name),
category: 'PIECE',
notes: payload.description ?? payload.notes,
description: payload.description ?? null,
description: payload.description ?? null
})
const normalized = {
...data,
description: data.description ?? data.notes ?? null,
description: data.description ?? data.notes ?? null
}
pieceTypes.value.push(normalized)
@@ -79,15 +79,15 @@ export function usePieceTypes() {
name: payload.name,
description: payload.description,
notes: payload.notes,
code: payload.code,
code: payload.code
})
const normalized = {
...data,
description: data.description ?? data.notes ?? null,
description: data.description ?? data.notes ?? null
}
const index = pieceTypes.value.findIndex((type) => type.id === id)
const index = pieceTypes.value.findIndex(type => type.id === id)
if (index !== -1) {
pieceTypes.value[index] = normalized
}
@@ -95,7 +95,7 @@ export function usePieceTypes() {
return {
success: true,
data: normalized,
data: normalized
}
} catch (error) {
const message = error?.data?.message || error?.message || 'Erreur inconnue'
@@ -110,7 +110,7 @@ export function usePieceTypes() {
loadingPieceTypes.value = true
try {
await deleteModelType(id)
pieceTypes.value = pieceTypes.value.filter((type) => type.id !== id)
pieceTypes.value = pieceTypes.value.filter(type => type.id !== id)
showSuccess('Type de pièce supprimé')
return { success: true }
} catch (error) {
@@ -133,6 +133,6 @@ export function usePieceTypes() {
updatePieceType,
deletePieceType,
getPieceTypes,
isPieceTypeLoading,
isPieceTypeLoading
}
}

View File

@@ -5,7 +5,7 @@ import { useApi } from './useApi'
const pieces = ref([])
const loading = ref(false)
export function usePieces() {
export function usePieces () {
const { showSuccess, showError, showInfo } = useToast()
const { get, post, patch, delete: del } = useApi()
@@ -132,4 +132,4 @@ export function usePieces() {
getPieces,
isLoading
}
}
}

View File

@@ -6,13 +6,13 @@ const buildUrl = (path) => {
return `${base}${path}`
}
export function useProfileSession() {
export function useProfileSession () {
const activeProfile = useState('profileSession:active', () => null)
const sessionLoaded = useState('profileSession:loaded', () => false)
const loading = useState('profileSession:loading', () => false)
const getSessionHeaders = () => {
if (!process.server) return undefined
if (!process.server) { return undefined }
const headers = useRequestHeaders(['cookie'])
return headers?.cookie ? { cookie: headers.cookie } : undefined
}
@@ -23,7 +23,7 @@ export function useProfileSession() {
activeProfile.value = await $fetch(buildUrl('/session/profile'), {
method: 'GET',
credentials: 'include',
headers: getSessionHeaders(),
headers: getSessionHeaders()
})
} catch (error) {
if (error?.status === 401) {
@@ -51,7 +51,7 @@ export function useProfileSession() {
method: 'POST',
credentials: 'include',
body: { profileId },
headers: getSessionHeaders(),
headers: getSessionHeaders()
})
await fetchCurrentProfile()
}
@@ -61,7 +61,7 @@ export function useProfileSession() {
await $fetch(buildUrl('/session/profile'), {
method: 'DELETE',
credentials: 'include',
headers: getSessionHeaders(),
headers: getSessionHeaders()
})
} finally {
activeProfile.value = null
@@ -76,6 +76,6 @@ export function useProfileSession() {
ensureSession,
fetchCurrentProfile,
activateProfile,
logout,
logout
}
}

View File

@@ -6,13 +6,13 @@ const buildUrl = (path) => {
return `${base}${path}`
}
export function useProfiles() {
export function useProfiles () {
const profiles = useState('profiles:list', () => [])
const loadingProfiles = useState('profiles:loading', () => false)
const profilesLoaded = useState('profiles:loaded', () => false)
const getSessionHeaders = () => {
if (!process.server) return undefined
if (!process.server) { return undefined }
const headers = useRequestHeaders(['cookie'])
return headers?.cookie ? { cookie: headers.cookie } : undefined
}
@@ -23,7 +23,7 @@ export function useProfiles() {
profiles.value = await $fetch(buildUrl('/profiles'), {
method: 'GET',
credentials: 'include',
headers: getSessionHeaders(),
headers: getSessionHeaders()
})
profilesLoaded.value = true
} catch (error) {
@@ -41,7 +41,7 @@ export function useProfiles() {
method: 'POST',
credentials: 'include',
body: { firstName, lastName },
headers: getSessionHeaders(),
headers: getSessionHeaders()
})
await fetchProfiles()
return profile
@@ -51,7 +51,7 @@ export function useProfiles() {
await $fetch(buildUrl(`/profiles/${profileId}`), {
method: 'DELETE',
credentials: 'include',
headers: getSessionHeaders(),
headers: getSessionHeaders()
})
await fetchProfiles()
}
@@ -62,6 +62,6 @@ export function useProfiles() {
profilesLoaded,
fetchProfiles,
createProfile,
deleteProfile,
deleteProfile
}
}

View File

@@ -5,7 +5,7 @@ import { useApi } from './useApi'
const sites = ref([])
const loading = ref(false)
export function useSites() {
export function useSites () {
const { showSuccess, showInfo } = useToast()
const { get, post, patch, delete: del } = useApi()
@@ -97,4 +97,4 @@ export function useSites() {
getSites,
isLoading
}
}
}

View File

@@ -3,7 +3,7 @@ import { ref } from 'vue'
const toasts = ref([])
let nextId = 1
export function useToast() {
export function useToast () {
const showToast = (message, type = 'info', duration = 5000) => {
const id = nextId++
const toast = {
@@ -12,14 +12,14 @@ export function useToast() {
type,
visible: true
}
toasts.value.push(toast)
// Auto-remove after duration
setTimeout(() => {
removeToast(id)
}, duration)
return id
}
@@ -63,4 +63,4 @@ export function useToast() {
removeToast,
clearAll
}
}
}