결재 단계 필터 개선
This commit is contained in:
@@ -14,6 +14,7 @@ class ApprovalStepController extends ChangeNotifier {
|
||||
bool _isLoading = false;
|
||||
String _query = '';
|
||||
int? _statusId;
|
||||
int? _approverId;
|
||||
String? _errorMessage;
|
||||
bool _isLoadingDetail = false;
|
||||
ApprovalStepRecord? _selected;
|
||||
@@ -22,6 +23,7 @@ class ApprovalStepController extends ChangeNotifier {
|
||||
bool get isLoading => _isLoading;
|
||||
String get query => _query;
|
||||
int? get statusId => _statusId;
|
||||
int? get approverId => _approverId;
|
||||
String? get errorMessage => _errorMessage;
|
||||
bool get isLoadingDetail => _isLoadingDetail;
|
||||
ApprovalStepRecord? get selected => _selected;
|
||||
@@ -37,6 +39,7 @@ class ApprovalStepController extends ChangeNotifier {
|
||||
pageSize: _result?.pageSize ?? 20,
|
||||
query: sanitizedQuery.isEmpty ? null : sanitizedQuery,
|
||||
statusId: _statusId,
|
||||
approverId: _approverId,
|
||||
);
|
||||
_result = response;
|
||||
} catch (e) {
|
||||
@@ -57,6 +60,11 @@ class ApprovalStepController extends ChangeNotifier {
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void updateApproverId(int? value) {
|
||||
_approverId = value;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
Future<ApprovalStepRecord?> fetchDetail(int id) async {
|
||||
_isLoadingDetail = true;
|
||||
_errorMessage = null;
|
||||
@@ -84,11 +92,13 @@ class ApprovalStepController extends ChangeNotifier {
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
bool get hasActiveFilters => _query.trim().isNotEmpty || _statusId != null;
|
||||
bool get hasActiveFilters =>
|
||||
_query.trim().isNotEmpty || _statusId != null || _approverId != null;
|
||||
|
||||
void resetFilters() {
|
||||
_query = '';
|
||||
_statusId = null;
|
||||
_approverId = null;
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,6 +140,8 @@ class _ApprovalStepEnabledPageState extends State<_ApprovalStepEnabledPage> {
|
||||
: (result.page * result.pageSize) < result.total;
|
||||
final statusOptions = _buildStatusOptions(records);
|
||||
final selectedStatus = _controller.statusId ?? -1;
|
||||
final approverOptions = _buildApproverOptions(records);
|
||||
final selectedApprover = _controller.approverId ?? -1;
|
||||
|
||||
return AppLayout(
|
||||
title: '결재 단계 관리',
|
||||
@@ -197,6 +199,32 @@ class _ApprovalStepEnabledPageState extends State<_ApprovalStepEnabledPage> {
|
||||
.toList(),
|
||||
),
|
||||
),
|
||||
if (approverOptions.length > 1)
|
||||
SizedBox(
|
||||
width: 220,
|
||||
child: ShadSelect<int>(
|
||||
key: ValueKey(selectedApprover),
|
||||
initialValue: selectedApprover,
|
||||
onChanged: (value) {
|
||||
_controller.updateApproverId(value == -1 ? null : value);
|
||||
},
|
||||
selectedOptionBuilder: (context, value) {
|
||||
final option = approverOptions.firstWhere(
|
||||
(element) => element.id == value,
|
||||
orElse: () => const _ApproverOption(id: -1, name: '전체'),
|
||||
);
|
||||
return Text(option.name);
|
||||
},
|
||||
options: approverOptions
|
||||
.map(
|
||||
(opt) => ShadOption<int>(
|
||||
value: opt.id,
|
||||
child: Text(opt.name),
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
),
|
||||
),
|
||||
ShadButton.outline(
|
||||
onPressed: _controller.isLoading ? null : _applyFilters,
|
||||
child: const Text('검색 적용'),
|
||||
@@ -361,6 +389,18 @@ class _ApprovalStepEnabledPageState extends State<_ApprovalStepEnabledPage> {
|
||||
return options.toList()..sort((a, b) => a.id.compareTo(b.id));
|
||||
}
|
||||
|
||||
List<_ApproverOption> _buildApproverOptions(
|
||||
List<ApprovalStepRecord> records,
|
||||
) {
|
||||
final options = <_ApproverOption>{};
|
||||
options.add(const _ApproverOption(id: -1, name: '전체'));
|
||||
for (final record in records) {
|
||||
final approver = record.step.approver;
|
||||
options.add(_ApproverOption(id: approver.id, name: approver.name));
|
||||
}
|
||||
return options.toList()..sort((a, b) => a.name.compareTo(b.name));
|
||||
}
|
||||
|
||||
Future<void> _applyFilters() async {
|
||||
_controller.updateQuery(_searchController.text.trim());
|
||||
await _controller.fetch(page: 1);
|
||||
@@ -480,6 +520,21 @@ class _StatusOption {
|
||||
int get hashCode => id.hashCode;
|
||||
}
|
||||
|
||||
class _ApproverOption {
|
||||
const _ApproverOption({required this.id, required this.name});
|
||||
|
||||
final int id;
|
||||
final String name;
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return other is _ApproverOption && other.id == id;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => id.hashCode;
|
||||
}
|
||||
|
||||
class _DetailRow extends StatelessWidget {
|
||||
const _DetailRow({required this.label, required this.value});
|
||||
|
||||
|
||||
@@ -106,6 +106,7 @@ void main() {
|
||||
|
||||
controller.updateQuery('APP-2024');
|
||||
controller.updateStatusId(2);
|
||||
controller.updateApproverId(21);
|
||||
|
||||
await controller.fetch(page: 3);
|
||||
|
||||
@@ -115,7 +116,7 @@ void main() {
|
||||
pageSize: 20,
|
||||
query: 'APP-2024',
|
||||
statusId: 2,
|
||||
approverId: null,
|
||||
approverId: 21,
|
||||
approvalId: null,
|
||||
),
|
||||
).called(1);
|
||||
|
||||
Reference in New Issue
Block a user