Merge branch 'feature/travel-cost-calculator' into main
This commit is contained in:
@@ -597,3 +597,117 @@ exports.onEventReturnCompleted = onDocumentUpdated({
|
||||
logger.error(`[onEventReturnCompleted] Error resetting equipment statuses for event ${eventId}:`, error);
|
||||
}
|
||||
});
|
||||
|
||||
// ============================================================================
|
||||
// SEARCH - Recherche unifiée avec autocomplétion
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* Recherche rapide d'équipements et containers pour l'autocomplétion
|
||||
* Retourne un nombre limité de résultats pour des performances optimales
|
||||
*/
|
||||
exports.quickSearch = onRequest(httpOptions, withCors(async (req, res) => {
|
||||
try {
|
||||
const decodedToken = await auth.authenticateUser(req);
|
||||
|
||||
// Vérifier les permissions
|
||||
const canView = await auth.hasPermission(decodedToken.uid, 'view_equipment');
|
||||
|
||||
if (!canView) {
|
||||
res.status(403).json({ error: 'Forbidden: Requires view_equipment permission' });
|
||||
return;
|
||||
}
|
||||
|
||||
const params = req.method === 'GET' ? req.query : (req.body?.data || {});
|
||||
const searchQuery = params.query?.toLowerCase() || '';
|
||||
const limit = Math.min(parseInt(params.limit) || 10, 50);
|
||||
const includeEquipments = params.includeEquipments !== 'false';
|
||||
const includeContainers = params.includeContainers !== 'false';
|
||||
|
||||
if (!searchQuery || searchQuery.length < 2) {
|
||||
res.status(200).json({ results: [] });
|
||||
return;
|
||||
}
|
||||
|
||||
const results = [];
|
||||
|
||||
// Rechercher dans les équipements
|
||||
if (includeEquipments) {
|
||||
const equipmentSnapshot = await db.collection('equipments')
|
||||
.orderBy('id')
|
||||
.limit(limit * 2) // Récupérer plus pour filtrer ensuite
|
||||
.get();
|
||||
|
||||
equipmentSnapshot.docs.forEach(doc => {
|
||||
const data = doc.data();
|
||||
const searchableText = [
|
||||
data.name || '',
|
||||
doc.id || '',
|
||||
data.model || '',
|
||||
data.brand || ''
|
||||
].join(' ').toLowerCase();
|
||||
|
||||
if (searchableText.includes(searchQuery)) {
|
||||
results.push({
|
||||
type: 'equipment',
|
||||
id: doc.id,
|
||||
name: data.name,
|
||||
category: data.category,
|
||||
model: data.model,
|
||||
brand: data.brand
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Rechercher dans les containers
|
||||
if (includeContainers) {
|
||||
const containerSnapshot = await db.collection('containers')
|
||||
.orderBy('id')
|
||||
.limit(limit * 2)
|
||||
.get();
|
||||
|
||||
containerSnapshot.docs.forEach(doc => {
|
||||
const data = doc.data();
|
||||
const searchableText = [
|
||||
data.name || '',
|
||||
doc.id || ''
|
||||
].join(' ').toLowerCase();
|
||||
|
||||
if (searchableText.includes(searchQuery)) {
|
||||
results.push({
|
||||
type: 'container',
|
||||
id: doc.id,
|
||||
name: data.name,
|
||||
containerType: data.type
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Limiter et trier les résultats
|
||||
const limitedResults = results
|
||||
.sort((a, b) => {
|
||||
// Prioriser les correspondances exactes au début
|
||||
const aStarts = a.id.toLowerCase().startsWith(searchQuery);
|
||||
const bStarts = b.id.toLowerCase().startsWith(searchQuery);
|
||||
if (aStarts && !bStarts) return -1;
|
||||
if (!aStarts && bStarts) return 1;
|
||||
return 0;
|
||||
})
|
||||
.slice(0, limit);
|
||||
|
||||
res.status(200).json({ results: limitedResults });
|
||||
|
||||
} catch (error) {
|
||||
logger.error("Error in quick search:", error);
|
||||
res.status(500).json({ error: error.message });
|
||||
}
|
||||
}));
|
||||
|
||||
// ============================================================================
|
||||
// GOOGLE MAPS & TRAVEL (Proxies CORS + Calcul d'itinéraires)
|
||||
// ============================================================================
|
||||
const travel = require('./src/travel');
|
||||
exports.googleMapsAutocomplete = onRequest(httpOptions, withCors(travel.googleMapsAutocomplete));
|
||||
exports.googleMapsComputeRoute = onRequest(httpOptions, withCors(travel.googleMapsComputeRoute));
|
||||
|
||||
Reference in New Issue
Block a user