결재 및 마스터 모듈을 v4 API 계약에 맞게 조정
This commit is contained in:
@@ -11,7 +11,6 @@ import '../../../../core/permissions/permission_resources.dart';
|
||||
import '../../../../widgets/app_layout.dart';
|
||||
import '../../../../widgets/components/feedback.dart';
|
||||
import '../../../../widgets/components/filter_bar.dart';
|
||||
import '../../../../widgets/components/superport_date_picker.dart';
|
||||
import '../../../../widgets/components/superport_dialog.dart';
|
||||
import '../../../../widgets/components/superport_table.dart';
|
||||
import '../../../../widgets/components/feature_disabled_placeholder.dart';
|
||||
@@ -20,6 +19,7 @@ import '../../domain/entities/approval_template.dart';
|
||||
import '../../domain/repositories/approval_repository.dart';
|
||||
import '../../domain/repositories/approval_template_repository.dart';
|
||||
import '../../../inventory/lookups/domain/repositories/inventory_lookup_repository.dart';
|
||||
import '../../../inventory/shared/widgets/employee_autocomplete_field.dart';
|
||||
import '../controllers/approval_controller.dart';
|
||||
|
||||
const _approvalsResourcePath = PermissionResources.approvals;
|
||||
@@ -73,11 +73,11 @@ class _ApprovalEnabledPage extends StatefulWidget {
|
||||
|
||||
class _ApprovalEnabledPageState extends State<_ApprovalEnabledPage> {
|
||||
late final ApprovalController _controller;
|
||||
final TextEditingController _searchController = TextEditingController();
|
||||
final FocusNode _searchFocus = FocusNode();
|
||||
final intl.DateFormat _dateFormat = intl.DateFormat('yyyy-MM-dd');
|
||||
final TextEditingController _transactionController = TextEditingController();
|
||||
final TextEditingController _requesterController = TextEditingController();
|
||||
final FocusNode _transactionFocus = FocusNode();
|
||||
InventoryEmployeeSuggestion? _selectedRequester;
|
||||
final intl.DateFormat _dateTimeFormat = intl.DateFormat('yyyy-MM-dd HH:mm');
|
||||
DateTimeRange? _dateRange;
|
||||
String? _lastError;
|
||||
int? _selectedTemplateId;
|
||||
|
||||
@@ -114,8 +114,9 @@ class _ApprovalEnabledPageState extends State<_ApprovalEnabledPage> {
|
||||
void dispose() {
|
||||
_controller.removeListener(_handleControllerUpdate);
|
||||
_controller.dispose();
|
||||
_searchController.dispose();
|
||||
_searchFocus.dispose();
|
||||
_transactionController.dispose();
|
||||
_requesterController.dispose();
|
||||
_transactionFocus.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@@ -197,16 +198,39 @@ class _ApprovalEnabledPageState extends State<_ApprovalEnabledPage> {
|
||||
),
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 260,
|
||||
width: 180,
|
||||
child: ShadInput(
|
||||
controller: _searchController,
|
||||
focusNode: _searchFocus,
|
||||
placeholder: const Text('결재번호, 트랜잭션번호, 상신자 검색'),
|
||||
leading: const Icon(lucide.LucideIcons.search, size: 16),
|
||||
controller: _transactionController,
|
||||
focusNode: _transactionFocus,
|
||||
enabled: !_controller.isLoadingList,
|
||||
keyboardType: TextInputType.number,
|
||||
placeholder: const Text('트랜잭션 ID 입력'),
|
||||
leading: const Icon(lucide.LucideIcons.hash, size: 16),
|
||||
onChanged: (_) => setState(() {}),
|
||||
onSubmitted: (_) => _applyFilters(),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: 280,
|
||||
child: InventoryEmployeeAutocompleteField(
|
||||
controller: _requesterController,
|
||||
initialSuggestion: _selectedRequester,
|
||||
enabled: !_controller.isLoadingList,
|
||||
onSuggestionSelected: (suggestion) {
|
||||
setState(() => _selectedRequester = suggestion);
|
||||
},
|
||||
onChanged: () {
|
||||
setState(() {
|
||||
final selectedLabel = _selectedRequester == null
|
||||
? ''
|
||||
: '${_selectedRequester!.name} (${_selectedRequester!.employeeNo})';
|
||||
if (_requesterController.text.trim() != selectedLabel) {
|
||||
_selectedRequester = null;
|
||||
}
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: 200,
|
||||
child: ShadSelect<ApprovalStatusFilter>(
|
||||
@@ -229,37 +253,6 @@ class _ApprovalEnabledPageState extends State<_ApprovalEnabledPage> {
|
||||
.toList(),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: 220,
|
||||
child: SuperportDateRangePickerButton(
|
||||
value: _dateRange,
|
||||
dateFormat: _dateFormat,
|
||||
enabled: !_controller.isLoadingList,
|
||||
firstDate: DateTime(DateTime.now().year - 5),
|
||||
lastDate: DateTime(DateTime.now().year + 1),
|
||||
initialDateRange:
|
||||
_dateRange ??
|
||||
DateTimeRange(
|
||||
start: DateTime.now().subtract(const Duration(days: 7)),
|
||||
end: DateTime.now(),
|
||||
),
|
||||
onChanged: (range) {
|
||||
if (range == null) return;
|
||||
setState(() => _dateRange = range);
|
||||
_controller.updateDateRange(range.start, range.end);
|
||||
_controller.fetch(page: 1);
|
||||
},
|
||||
),
|
||||
),
|
||||
if (_dateRange != null)
|
||||
ShadButton.ghost(
|
||||
onPressed: () {
|
||||
setState(() => _dateRange = null);
|
||||
_controller.updateDateRange(null, null);
|
||||
_controller.fetch(page: 1);
|
||||
},
|
||||
child: const Text('기간 초기화'),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Column(
|
||||
@@ -476,25 +469,48 @@ class _ApprovalEnabledPageState extends State<_ApprovalEnabledPage> {
|
||||
}
|
||||
|
||||
void _applyFilters() {
|
||||
_controller.updateQuery(_searchController.text.trim());
|
||||
if (_dateRange != null) {
|
||||
_controller.updateDateRange(_dateRange!.start, _dateRange!.end);
|
||||
final transactionText = _transactionController.text.trim();
|
||||
if (transactionText.isNotEmpty) {
|
||||
final transactionId = int.tryParse(transactionText);
|
||||
if (transactionId == null) {
|
||||
SuperportToast.error(context, '트랜잭션 ID는 숫자만 입력해야 합니다.');
|
||||
return;
|
||||
}
|
||||
_controller.updateTransactionFilter(transactionId);
|
||||
} else {
|
||||
_controller.updateTransactionFilter(null);
|
||||
}
|
||||
|
||||
final requester = _selectedRequester;
|
||||
if (requester != null) {
|
||||
_controller.updateRequestedByFilter(
|
||||
id: requester.id,
|
||||
name: requester.name,
|
||||
employeeNo: requester.employeeNo,
|
||||
);
|
||||
} else if (_requesterController.text.trim().isEmpty) {
|
||||
_controller.updateRequestedByFilter(id: null);
|
||||
}
|
||||
|
||||
_controller.fetch(page: 1);
|
||||
}
|
||||
|
||||
void _resetFilters() {
|
||||
_searchController.clear();
|
||||
_searchFocus.requestFocus();
|
||||
_dateRange = null;
|
||||
_transactionController.clear();
|
||||
_requesterController.clear();
|
||||
setState(() => _selectedRequester = null);
|
||||
_transactionFocus.requestFocus();
|
||||
_controller.clearFilters();
|
||||
_controller.fetch(page: 1);
|
||||
}
|
||||
|
||||
bool _hasFilters() {
|
||||
return _searchController.text.isNotEmpty ||
|
||||
_controller.statusFilter != ApprovalStatusFilter.all ||
|
||||
_dateRange != null;
|
||||
return _transactionController.text.trim().isNotEmpty ||
|
||||
_requesterController.text.trim().isNotEmpty ||
|
||||
_selectedRequester != null ||
|
||||
_controller.transactionIdFilter != null ||
|
||||
_controller.requestedById != null ||
|
||||
_controller.statusFilter != ApprovalStatusFilter.all;
|
||||
}
|
||||
|
||||
Future<void> _handleStepAction(
|
||||
|
||||
Reference in New Issue
Block a user