import 'package:flutter/material.dart'; import 'package:superport/models/equipment_unified_model.dart'; import 'package:superport/screens/equipment/widgets/equipment_status_chip.dart'; import 'package:superport/screens/equipment/widgets/equipment_out_info.dart'; import 'package:superport/utils/equipment_display_helper.dart'; // 장비 목록 테이블 위젯 (SRP, 재사용성 강화) class EquipmentTable extends StatelessWidget { final List equipments; final Set selectedEquipmentIds; final bool showDetailedColumns; final void Function(int? id, String status, bool? isSelected) onEquipmentSelected; final String Function(int equipmentId, String infoType) getOutEquipmentInfo; final Widget Function(UnifiedEquipment equipment) buildCategoryWithTooltip; final void Function(int id, String status) onEdit; final void Function(int id, String status) onDelete; final int Function() getSelectedInStockCount; const EquipmentTable({ super.key, required this.equipments, required this.selectedEquipmentIds, required this.showDetailedColumns, required this.onEquipmentSelected, required this.getOutEquipmentInfo, required this.buildCategoryWithTooltip, required this.onEdit, required this.onDelete, required this.getSelectedInStockCount, }); // 출고 정보(간소화 모드) 위젯 Widget _buildCompactOutInfo(int equipmentId) { final company = getOutEquipmentInfo(equipmentId, 'company'); final manager = getOutEquipmentInfo(equipmentId, 'manager'); final license = getOutEquipmentInfo(equipmentId, 'license'); return Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.center, children: [ EquipmentOutInfoIcon(infoType: 'company', text: company), const SizedBox(height: 2), EquipmentOutInfoIcon(infoType: 'manager', text: manager), const SizedBox(height: 2), EquipmentOutInfoIcon(infoType: 'license', text: license), ], ); } // 카테고리 툴팁 위젯 (UI만 담당, 축약 표기 적용) Widget _buildCategoryWithTooltip(UnifiedEquipment equipment) { // 한글 라벨로 표기 final fullCategory = '대분류: ${equipment.equipment.category} / 중분류: ${equipment.equipment.subCategory} / 소분류: ${equipment.equipment.subSubCategory}'; final shortCategory = [ _shortenCategory(equipment.equipment.category), _shortenCategory(equipment.equipment.subCategory), _shortenCategory(equipment.equipment.subSubCategory), ].join(' > '); return Tooltip(message: fullCategory, child: Text(shortCategory)); } // 카테고리 축약 표기 함수 (예: 컴...) String _shortenCategory(String category) { if (category.length <= 2) return category; return category.substring(0, 2) + '...'; } @override Widget build(BuildContext context) { return DataTable( headingRowHeight: 48, dataRowMinHeight: 48, dataRowMaxHeight: 60, columnSpacing: 10, horizontalMargin: 16, columns: [ const DataColumn(label: SizedBox(width: 32, child: Text('선택'))), const DataColumn(label: SizedBox(width: 32, child: Text('번호'))), if (showDetailedColumns) const DataColumn(label: SizedBox(width: 60, child: Text('제조사'))), const DataColumn(label: SizedBox(width: 90, child: Text('장비명'))), if (showDetailedColumns) const DataColumn(label: SizedBox(width: 110, child: Text('분류'))), if (showDetailedColumns) const DataColumn(label: SizedBox(width: 60, child: Text('장비 유형'))), if (showDetailedColumns) const DataColumn(label: SizedBox(width: 70, child: Text('시리얼번호'))), const DataColumn(label: SizedBox(width: 38, child: Text('수량'))), const DataColumn(label: SizedBox(width: 80, child: Text('변경 일자'))), const DataColumn(label: SizedBox(width: 44, child: Text('상태'))), if (showDetailedColumns) ...[ const DataColumn(label: SizedBox(width: 90, child: Text('출고 회사'))), const DataColumn(label: SizedBox(width: 60, child: Text('담당자'))), const DataColumn(label: SizedBox(width: 60, child: Text('라이센스'))), ] else const DataColumn(label: SizedBox(width: 110, child: Text('출고 정보'))), const DataColumn(label: SizedBox(width: 60, child: Text('관리'))), ], rows: equipments.asMap().entries.map((entry) { final index = entry.key; final equipment = entry.value; final bool isInStock = equipment.status == 'I'; final bool isOutStock = equipment.status == 'O'; return DataRow( color: MaterialStateProperty.resolveWith( (Set states) => index % 2 == 0 ? Colors.grey[50] : null, ), cells: [ DataCell( Checkbox( value: selectedEquipmentIds.contains( '${equipment.id}:${equipment.status}', ), onChanged: (isSelected) => onEquipmentSelected( equipment.id, equipment.status, isSelected, ), materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, ), ), DataCell(Text('${index + 1}')), if (showDetailedColumns) DataCell( Text( EquipmentDisplayHelper.formatManufacturer( equipment.equipment.manufacturer, ), ), ), DataCell( Text( EquipmentDisplayHelper.formatEquipmentName( equipment.equipment.name, ), style: const TextStyle(fontWeight: FontWeight.bold), ), ), if (showDetailedColumns) DataCell(buildCategoryWithTooltip(equipment)), if (showDetailedColumns) DataCell( Text( equipment.status == 'I' && equipment is UnifiedEquipment && equipment.type != null ? equipment.type! : '-', ), ), if (showDetailedColumns) DataCell( Text( EquipmentDisplayHelper.formatSerialNumber( equipment.equipment.serialNumber, ), ), ), DataCell( Text( '${equipment.equipment.quantity}', textAlign: TextAlign.center, ), ), DataCell( Text(EquipmentDisplayHelper.formatDate(equipment.date)), ), DataCell(EquipmentStatusChip(status: equipment.status)), if (showDetailedColumns) ...[ DataCell( Text( isOutStock ? getOutEquipmentInfo(equipment.id!, 'company') : '-', ), ), DataCell( Text( isOutStock ? getOutEquipmentInfo(equipment.id!, 'manager') : '-', ), ), DataCell( Text( isOutStock ? getOutEquipmentInfo(equipment.id!, 'license') : '-', ), ), ] else DataCell( isOutStock ? _buildCompactOutInfo(equipment.id!) : const Text('-'), ), DataCell( Row( mainAxisSize: MainAxisSize.min, children: [ IconButton( icon: const Icon( Icons.edit, color: Colors.blue, size: 20, ), constraints: const BoxConstraints(), padding: const EdgeInsets.all(5), onPressed: () => onEdit(equipment.id!, equipment.status), ), IconButton( icon: const Icon( Icons.delete, color: Colors.red, size: 20, ), constraints: const BoxConstraints(), padding: const EdgeInsets.all(5), onPressed: () => onDelete(equipment.id!, equipment.status), ), ], ), ), ], ); }).toList(), ); } }