계정 정보 다이얼로그 추가 및 전체 목록 페치 개선

This commit is contained in:
JiWoong Sul
2025-10-22 01:05:47 +09:00
parent 6b58effc83
commit f4dc83d441
44 changed files with 1636 additions and 362 deletions

View File

@@ -1,6 +1,7 @@
import 'package:flutter/foundation.dart';
import 'package:superport_v2/core/common/models/paginated_result.dart';
import 'package:superport_v2/core/network/failure.dart';
import 'package:superport_v2/core/common/models/paginated_result.dart';
import 'package:superport_v2/core/common/utils/pagination_utils.dart';
import '../../../../../core/permissions/permission_manager.dart';
import '../../application/permission_synchronizer.dart';
@@ -65,10 +66,13 @@ class GroupPermissionController extends ChangeNotifier {
_isLoadingGroups = true;
notifyListeners();
try {
final response = await _groupRepository.list(page: 1, pageSize: 200);
final groups = await fetchAllPaginatedItems<Group>(
request: (page, pageSize) =>
_groupRepository.list(page: page, pageSize: pageSize),
);
_groups
..clear()
..addAll(response.items);
..addAll(groups);
} catch (error) {
final failure = Failure.from(error);
_errorMessage = failure.describe();
@@ -83,14 +87,16 @@ class GroupPermissionController extends ChangeNotifier {
_isLoadingMenus = true;
notifyListeners();
try {
final response = await _menuRepository.list(
page: 1,
pageSize: 200,
includeDeleted: false,
final menus = await fetchAllPaginatedItems<MenuItem>(
request: (page, pageSize) => _menuRepository.list(
page: page,
pageSize: pageSize,
includeDeleted: false,
),
);
_menus
..clear()
..addAll(response.items);
..addAll(menus);
} catch (error) {
final failure = Failure.from(error);
_errorMessage = failure.describe();
@@ -106,13 +112,24 @@ class GroupPermissionController extends ChangeNotifier {
_errorMessage = null;
notifyListeners();
try {
final previous = _result;
final int resolvedPage;
if (page < 1) {
resolvedPage = 1;
} else if (previous != null && previous.pageSize > 0) {
final calculated = (previous.total / previous.pageSize).ceil();
final maxPage = calculated < 1 ? 1 : calculated;
resolvedPage = page > maxPage ? maxPage : page;
} else {
resolvedPage = page;
}
final isActive = switch (_statusFilter) {
GroupPermissionStatusFilter.all => null,
GroupPermissionStatusFilter.activeOnly => true,
GroupPermissionStatusFilter.inactiveOnly => false,
};
final response = await _permissionRepository.list(
page: page,
page: resolvedPage,
pageSize: _result?.pageSize ?? 20,
groupId: _groupFilter,
menuId: _menuFilter,

View File

@@ -151,9 +151,10 @@ class _GroupPermissionEnabledPageState
final error = _controller.errorMessage;
if (error != null && error != _lastError && mounted) {
_lastError = error;
ScaffoldMessenger.of(
context,
).showSnackBar(SnackBar(content: Text(error)));
final messenger = ScaffoldMessenger.maybeOf(context);
if (messenger != null) {
messenger.showSnackBar(SnackBar(content: Text(error)));
}
_controller.clearError();
}
}
@@ -180,7 +181,7 @@ class _GroupPermissionEnabledPageState
final currentPage = result?.page ?? 1;
final totalPages = result == null || result.pageSize == 0
? 1
: (result.total / result.pageSize).ceil().clamp(1, 9999);
: (result.total / result.pageSize).ceil().clamp(1, 9999) as int;
final hasNext = result == null
? false
: (result.page * result.pageSize) < result.total;
@@ -366,6 +367,14 @@ class _GroupPermissionEnabledPageState
),
Row(
children: [
ShadButton.outline(
size: ShadButtonSize.sm,
onPressed: _controller.isLoading || currentPage <= 1
? null
: () => _controller.fetch(page: 1),
child: const Text('처음'),
),
const SizedBox(width: 8),
ShadButton.outline(
size: ShadButtonSize.sm,
onPressed: _controller.isLoading || currentPage <= 1
@@ -381,6 +390,15 @@ class _GroupPermissionEnabledPageState
: () => _controller.fetch(page: currentPage + 1),
child: const Text('다음'),
),
const SizedBox(width: 8),
ShadButton.outline(
size: ShadButtonSize.sm,
onPressed:
_controller.isLoading || currentPage >= totalPages
? null
: () => _controller.fetch(page: totalPages),
child: const Text('마지막'),
),
],
),
],
@@ -481,7 +499,10 @@ class _GroupPermissionEnabledPageState
return ShadButton.ghost(
onPressed: isSaving
? null
: () => Navigator.of(dialogContext).pop(false),
: () => Navigator.of(
dialogContext,
rootNavigator: true,
).pop(false),
child: const Text('취소'),
);
},
@@ -513,7 +534,10 @@ class _GroupPermissionEnabledPageState
isActive: activeNotifier.value,
note: trimmedNote.isEmpty ? null : trimmedNote,
);
final navigator = Navigator.of(dialogContext);
final navigator = Navigator.of(
dialogContext,
rootNavigator: true,
);
final response = isEdit
? await _controller.update(permissionId!, input)
: await _controller.create(input);
@@ -758,7 +782,8 @@ class _GroupPermissionEnabledPageState
secondaryAction: Builder(
builder: (dialogContext) {
return ShadButton.ghost(
onPressed: () => Navigator.of(dialogContext).pop(false),
onPressed: () =>
Navigator.of(dialogContext, rootNavigator: true).pop(false),
child: const Text('취소'),
);
},
@@ -766,7 +791,8 @@ class _GroupPermissionEnabledPageState
primaryAction: Builder(
builder: (dialogContext) {
return ShadButton.destructive(
onPressed: () => Navigator.of(dialogContext).pop(true),
onPressed: () =>
Navigator.of(dialogContext, rootNavigator: true).pop(true),
child: const Text('삭제'),
);
},
@@ -791,10 +817,14 @@ class _GroupPermissionEnabledPageState
}
void _showSnack(String message) {
if (!mounted) return;
ScaffoldMessenger.of(
context,
).showSnackBar(SnackBar(content: Text(message)));
if (!mounted) {
return;
}
final messenger = ScaffoldMessenger.maybeOf(context);
if (messenger == null) {
return;
}
messenger.showSnackBar(SnackBar(content: Text(message)));
}
String _formatDateTime(DateTime? value) {