Files
superport/lib/screens/equipment/widgets/equipment_basic_info_section.dart
JiWoong Sul e7860ae028
Some checks failed
Flutter Test & Quality Check / Test on macos-latest (push) Has been cancelled
Flutter Test & Quality Check / Test on ubuntu-latest (push) Has been cancelled
Flutter Test & Quality Check / Build APK (push) Has been cancelled
feat: 소프트 딜리트 기능 전면 구현 완료
## 주요 변경사항
- Company, Equipment, License, Warehouse Location 모든 화면에 소프트 딜리트 구현
- 관리자 권한으로 삭제된 데이터 조회 가능 (includeInactive 파라미터)
- 데이터 무결성 보장을 위한 논리 삭제 시스템 완성

## 기능 개선
- 각 리스트 컨트롤러에 toggleIncludeInactive() 메서드 추가
- UI에 "비활성 포함" 체크박스 추가 (관리자 전용)
- API 데이터소스에 includeInactive 파라미터 지원

## 문서 정리
- 불필요한 문서 파일 제거 및 재구성
- CLAUDE.md 프로젝트 상태 업데이트 (진행률 80%)
- 테스트 결과 문서화 (test20250812v01.md)

## UI 컴포넌트
- Equipment 화면 위젯 모듈화 (custom_dropdown_field, equipment_basic_info_section)
- 폼 유효성 검증 강화

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-12 20:02:54 +09:00

220 lines
8.9 KiB
Dart

import 'package:flutter/material.dart';
import 'package:superport/screens/common/custom_widgets/form_field_wrapper.dart';
import 'package:superport/screens/equipment/controllers/equipment_in_form_controller.dart';
import 'custom_dropdown_field.dart';
/// 장비 기본 정보 섹션 위젯
class EquipmentBasicInfoSection extends StatelessWidget {
final EquipmentInFormController controller;
final TextEditingController partnerController;
final TextEditingController warehouseController;
final TextEditingController manufacturerController;
final TextEditingController equipmentNameController;
final FocusNode partnerFocusNode;
final FocusNode warehouseFocusNode;
final FocusNode manufacturerFocusNode;
final FocusNode nameFieldFocusNode;
final LayerLink partnerLayerLink;
final LayerLink warehouseLayerLink;
final LayerLink manufacturerLayerLink;
final LayerLink equipmentNameLayerLink;
final GlobalKey partnerFieldKey;
final GlobalKey warehouseFieldKey;
final GlobalKey manufacturerFieldKey;
final GlobalKey equipmentNameFieldKey;
final VoidCallback onPartnerDropdownPressed;
final VoidCallback onWarehouseDropdownPressed;
final VoidCallback onManufacturerDropdownPressed;
final VoidCallback onEquipmentNameDropdownPressed;
final String? Function(String) getPartnerAutocompleteSuggestion;
final String? Function(String) getWarehouseAutocompleteSuggestion;
final String? Function(String) getManufacturerAutocompleteSuggestion;
final String? Function(String) getEquipmentNameAutocompleteSuggestion;
const EquipmentBasicInfoSection({
super.key,
required this.controller,
required this.partnerController,
required this.warehouseController,
required this.manufacturerController,
required this.equipmentNameController,
required this.partnerFocusNode,
required this.warehouseFocusNode,
required this.manufacturerFocusNode,
required this.nameFieldFocusNode,
required this.partnerLayerLink,
required this.warehouseLayerLink,
required this.manufacturerLayerLink,
required this.equipmentNameLayerLink,
required this.partnerFieldKey,
required this.warehouseFieldKey,
required this.manufacturerFieldKey,
required this.equipmentNameFieldKey,
required this.onPartnerDropdownPressed,
required this.onWarehouseDropdownPressed,
required this.onManufacturerDropdownPressed,
required this.onEquipmentNameDropdownPressed,
required this.getPartnerAutocompleteSuggestion,
required this.getWarehouseAutocompleteSuggestion,
required this.getManufacturerAutocompleteSuggestion,
required this.getEquipmentNameAutocompleteSuggestion,
});
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// 섹션 제목
Padding(
padding: const EdgeInsets.only(bottom: 16.0),
child: Text(
'기본 정보',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
color: Theme.of(context).primaryColor,
),
),
),
// 1행: 구매처, 입고지
Row(
children: [
Expanded(
child: FormFieldWrapper(
label: '구매처',
isRequired: true,
child: CustomDropdownField(
label: '구매처',
hint: '구매처를 입력 또는 선택하세요',
required: true,
controller: partnerController,
focusNode: partnerFocusNode,
items: controller.partnerCompanies,
onChanged: (value) {
controller.partnerCompany = value;
},
onFieldSubmitted: (value) {
final suggestion = getPartnerAutocompleteSuggestion(value);
if (suggestion != null && suggestion.length > value.length) {
partnerController.text = suggestion;
controller.partnerCompany = suggestion;
partnerController.selection = TextSelection.collapsed(
offset: suggestion.length,
);
}
},
getAutocompleteSuggestion: getPartnerAutocompleteSuggestion,
onDropdownPressed: onPartnerDropdownPressed,
layerLink: partnerLayerLink,
fieldKey: partnerFieldKey,
),
),
),
const SizedBox(width: 16),
Expanded(
child: FormFieldWrapper(
label: '입고지',
isRequired: true,
child: CustomDropdownField(
label: '입고지',
hint: '입고지를 입력 또는 선택하세요',
required: true,
controller: warehouseController,
focusNode: warehouseFocusNode,
items: controller.warehouseLocations,
onChanged: (value) {
controller.warehouseLocation = value;
},
onFieldSubmitted: (value) {
final suggestion = getWarehouseAutocompleteSuggestion(value);
if (suggestion != null && suggestion.length > value.length) {
warehouseController.text = suggestion;
controller.warehouseLocation = suggestion;
warehouseController.selection = TextSelection.collapsed(
offset: suggestion.length,
);
}
},
getAutocompleteSuggestion: getWarehouseAutocompleteSuggestion,
onDropdownPressed: onWarehouseDropdownPressed,
layerLink: warehouseLayerLink,
fieldKey: warehouseFieldKey,
),
),
),
],
),
const SizedBox(height: 16),
// 2행: 제조사, 장비명
Row(
children: [
Expanded(
child: FormFieldWrapper(
label: '제조사',
isRequired: true,
child: CustomDropdownField(
label: '제조사',
hint: '제조사를 입력 또는 선택하세요',
required: true,
controller: manufacturerController,
focusNode: manufacturerFocusNode,
items: controller.manufacturers,
onChanged: (value) {
controller.manufacturer = value;
},
onFieldSubmitted: (value) {
final suggestion = getManufacturerAutocompleteSuggestion(value);
if (suggestion != null && suggestion.length > value.length) {
manufacturerController.text = suggestion;
controller.manufacturer = suggestion;
manufacturerController.selection = TextSelection.collapsed(
offset: suggestion.length,
);
}
},
getAutocompleteSuggestion: getManufacturerAutocompleteSuggestion,
onDropdownPressed: onManufacturerDropdownPressed,
layerLink: manufacturerLayerLink,
fieldKey: manufacturerFieldKey,
),
),
),
const SizedBox(width: 16),
Expanded(
child: FormFieldWrapper(
label: '장비명',
isRequired: true,
child: CustomDropdownField(
label: '장비명',
hint: '장비명을 입력 또는 선택하세요',
required: true,
controller: equipmentNameController,
focusNode: nameFieldFocusNode,
items: controller.equipmentNames,
onChanged: (value) {
controller.name = value;
},
onFieldSubmitted: (value) {
final suggestion = getEquipmentNameAutocompleteSuggestion(value);
if (suggestion != null && suggestion.length > value.length) {
equipmentNameController.text = suggestion;
controller.name = suggestion;
equipmentNameController.selection = TextSelection.collapsed(
offset: suggestion.length,
);
}
},
getAutocompleteSuggestion: getEquipmentNameAutocompleteSuggestion,
onDropdownPressed: onEquipmentNameDropdownPressed,
layerLink: equipmentNameLayerLink,
fieldKey: equipmentNameFieldKey,
),
),
),
],
),
],
);
}
}