전역 구조 리팩터링 및 테스트 확장
This commit is contained in:
87
lib/core/permissions/permission_manager.dart
Normal file
87
lib/core/permissions/permission_manager.dart
Normal file
@@ -0,0 +1,87 @@
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
import '../config/environment.dart';
|
||||
|
||||
enum PermissionAction { view, create, edit, delete, restore, approve }
|
||||
|
||||
class PermissionManager extends ChangeNotifier {
|
||||
PermissionManager({Map<String, Set<PermissionAction>>? overrides}) {
|
||||
if (overrides != null) {
|
||||
_overrides.addAll(overrides);
|
||||
}
|
||||
}
|
||||
|
||||
final Map<String, Set<PermissionAction>> _overrides = {};
|
||||
|
||||
bool can(String resource, PermissionAction action) {
|
||||
final override = _overrides[resource];
|
||||
if (override != null) {
|
||||
if (override.contains(PermissionAction.view) &&
|
||||
action == PermissionAction.view) {
|
||||
return true;
|
||||
}
|
||||
return override.contains(action);
|
||||
}
|
||||
return Environment.hasPermission(resource, action.name);
|
||||
}
|
||||
|
||||
void updateOverrides(Map<String, Set<PermissionAction>> overrides) {
|
||||
_overrides
|
||||
..clear()
|
||||
..addAll(overrides);
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
class PermissionScope extends InheritedNotifier<PermissionManager> {
|
||||
const PermissionScope({
|
||||
super.key,
|
||||
required PermissionManager manager,
|
||||
required super.child,
|
||||
}) : super(notifier: manager);
|
||||
|
||||
static PermissionManager of(BuildContext context) {
|
||||
final scope = context.dependOnInheritedWidgetOfExactType<PermissionScope>();
|
||||
assert(
|
||||
scope != null,
|
||||
'PermissionScope.of() called with no PermissionScope ancestor.',
|
||||
);
|
||||
return scope!.notifier!;
|
||||
}
|
||||
}
|
||||
|
||||
class PermissionGate extends StatelessWidget {
|
||||
const PermissionGate({
|
||||
super.key,
|
||||
required this.resource,
|
||||
required this.action,
|
||||
required this.child,
|
||||
this.fallback,
|
||||
this.hide = true,
|
||||
});
|
||||
|
||||
final String resource;
|
||||
final PermissionAction action;
|
||||
final Widget child;
|
||||
final Widget? fallback;
|
||||
final bool hide;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final allowed = PermissionScope.of(context).can(resource, action);
|
||||
if (allowed) {
|
||||
return child;
|
||||
}
|
||||
if (hide) {
|
||||
return fallback ?? const SizedBox.shrink();
|
||||
}
|
||||
return IgnorePointer(
|
||||
ignoring: true,
|
||||
child: Opacity(opacity: 0.4, child: fallback ?? child),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
extension PermissionActionKey on PermissionAction {
|
||||
String get key => name;
|
||||
}
|
||||
Reference in New Issue
Block a user