Migrate frontend to plugin-based asset architecture
- Add equipmentApi and computersApi to replace legacy machinesApi - Add controller vendor/model fields to Equipment model and forms - Fix map marker navigation to use plugin-specific IDs (equipmentid, computerid, printerid, networkdeviceid) instead of assetid - Fix search to use unified Asset table with correct plugin IDs - Remove legacy printer search that used non-existent field names - Enable optional JWT auth for detail endpoints (public read access) - Clean up USB plugin models (remove unused checkout model) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -5,7 +5,7 @@ from flask_jwt_extended import jwt_required
|
||||
|
||||
from shopdb.extensions import db
|
||||
from shopdb.core.models import (
|
||||
Machine, Application, KnowledgeBase,
|
||||
Application, KnowledgeBase,
|
||||
Asset, AssetType
|
||||
)
|
||||
from shopdb.utils.responses import success_response
|
||||
@@ -46,74 +46,9 @@ def global_search():
|
||||
results = []
|
||||
search_term = f'%{query}%'
|
||||
|
||||
# Search Machines (Equipment and PCs)
|
||||
try:
|
||||
machines = Machine.query.filter(
|
||||
Machine.isactive == True,
|
||||
db.or_(
|
||||
Machine.machinenumber.ilike(search_term),
|
||||
Machine.alias.ilike(search_term),
|
||||
Machine.hostname.ilike(search_term),
|
||||
Machine.serialnumber.ilike(search_term),
|
||||
Machine.notes.ilike(search_term)
|
||||
)
|
||||
).limit(10).all()
|
||||
except Exception as e:
|
||||
import logging
|
||||
logging.error(f"Machine search failed: {e}")
|
||||
machines = []
|
||||
|
||||
for m in machines:
|
||||
# Determine type: PC, Printer, or Equipment
|
||||
is_pc = m.pctypeid is not None
|
||||
is_printer = m.is_printer
|
||||
|
||||
# Calculate relevance - exact matches score higher
|
||||
relevance = 15
|
||||
if m.machinenumber and query.lower() == m.machinenumber.lower():
|
||||
relevance = 100
|
||||
elif m.hostname and query.lower() == m.hostname.lower():
|
||||
relevance = 100
|
||||
elif m.alias and query.lower() in m.alias.lower():
|
||||
relevance = 50
|
||||
|
||||
display_name = m.hostname if is_pc and m.hostname else m.machinenumber
|
||||
if m.alias and not is_pc:
|
||||
display_name = f"{m.machinenumber} ({m.alias})"
|
||||
|
||||
# Determine result type and URL
|
||||
if is_printer:
|
||||
result_type = 'printer'
|
||||
url = f"/printers/{m.machineid}"
|
||||
elif is_pc:
|
||||
result_type = 'pc'
|
||||
url = f"/pcs/{m.machineid}"
|
||||
else:
|
||||
result_type = 'machine'
|
||||
url = f"/machines/{m.machineid}"
|
||||
|
||||
# Get location - prefer machine's own location, fall back to parent machine's location
|
||||
location_name = None
|
||||
if m.location:
|
||||
location_name = m.location.locationname
|
||||
elif m.parent_relationships:
|
||||
# Check parent machines for location
|
||||
for rel in m.parent_relationships:
|
||||
if rel.parent_machine and rel.parent_machine.location:
|
||||
location_name = rel.parent_machine.location.locationname
|
||||
break
|
||||
|
||||
# Get machinetype from model (single source of truth)
|
||||
mt = m.derived_machinetype
|
||||
results.append({
|
||||
'type': result_type,
|
||||
'id': m.machineid,
|
||||
'title': display_name,
|
||||
'subtitle': mt.machinetype if mt else None,
|
||||
'location': location_name,
|
||||
'url': url,
|
||||
'relevance': relevance
|
||||
})
|
||||
# NOTE: Legacy Machine search is disabled - all data is now in the Asset table
|
||||
# The Asset search below handles equipment, computers, network devices, and printers
|
||||
# with proper plugin-specific IDs for correct routing
|
||||
|
||||
# Search Applications
|
||||
try:
|
||||
@@ -173,37 +108,8 @@ def global_search():
|
||||
import logging
|
||||
logging.error(f"KnowledgeBase search failed: {e}")
|
||||
|
||||
# Search Printers (check if printers model exists)
|
||||
try:
|
||||
from shopdb.plugins.printers.models import Printer
|
||||
printers = Printer.query.filter(
|
||||
Printer.isactive == True,
|
||||
db.or_(
|
||||
Printer.printercsfname.ilike(search_term),
|
||||
Printer.printerwindowsname.ilike(search_term),
|
||||
Printer.serialnumber.ilike(search_term),
|
||||
Printer.fqdn.ilike(search_term)
|
||||
)
|
||||
).limit(10).all()
|
||||
|
||||
for p in printers:
|
||||
relevance = 15
|
||||
if p.printercsfname and query.lower() == p.printercsfname.lower():
|
||||
relevance = 100
|
||||
|
||||
display_name = p.printercsfname or p.printerwindowsname or f"Printer #{p.printerid}"
|
||||
|
||||
results.append({
|
||||
'type': 'printer',
|
||||
'id': p.printerid,
|
||||
'title': display_name,
|
||||
'subtitle': p.printerwindowsname if p.printercsfname else None,
|
||||
'url': f"/printers/{p.printerid}",
|
||||
'relevance': relevance
|
||||
})
|
||||
except Exception as e:
|
||||
import logging
|
||||
logging.error(f"Printer search failed: {e}")
|
||||
# NOTE: Legacy Printer search removed - printers are now in the unified Asset table
|
||||
# The Asset search below handles printers with correct plugin-specific IDs
|
||||
|
||||
# Search Employees (separate database)
|
||||
try:
|
||||
@@ -281,11 +187,23 @@ def global_search():
|
||||
|
||||
# Determine URL and type based on asset type
|
||||
asset_type_name = asset.assettype.assettype if asset.assettype else 'asset'
|
||||
|
||||
# Get the plugin-specific ID for proper routing
|
||||
plugin_id = asset.assetid # fallback
|
||||
if asset_type_name == 'equipment' and hasattr(asset, 'equipment') and asset.equipment:
|
||||
plugin_id = asset.equipment.equipmentid
|
||||
elif asset_type_name == 'computer' and hasattr(asset, 'computer') and asset.computer:
|
||||
plugin_id = asset.computer.computerid
|
||||
elif asset_type_name == 'network_device' and hasattr(asset, 'network_device') and asset.network_device:
|
||||
plugin_id = asset.network_device.networkdeviceid
|
||||
elif asset_type_name == 'printer' and hasattr(asset, 'printer') and asset.printer:
|
||||
plugin_id = asset.printer.printerid
|
||||
|
||||
url_map = {
|
||||
'equipment': f"/equipment/{asset.assetid}",
|
||||
'computer': f"/pcs/{asset.assetid}",
|
||||
'network_device': f"/network/{asset.assetid}",
|
||||
'printer': f"/printers/{asset.assetid}",
|
||||
'equipment': f"/machines/{plugin_id}",
|
||||
'computer': f"/pcs/{plugin_id}",
|
||||
'network_device': f"/network/{plugin_id}",
|
||||
'printer': f"/printers/{plugin_id}",
|
||||
}
|
||||
url = url_map.get(asset_type_name, f"/assets/{asset.assetid}")
|
||||
|
||||
@@ -299,7 +217,7 @@ def global_search():
|
||||
|
||||
results.append({
|
||||
'type': asset_type_name,
|
||||
'id': asset.assetid,
|
||||
'id': plugin_id,
|
||||
'title': display_name,
|
||||
'subtitle': subtitle,
|
||||
'location': location_name,
|
||||
|
||||
Reference in New Issue
Block a user