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