From 5d3acf55dd40eceba84a477998f29b6a29e7e487 Mon Sep 17 00:00:00 2001 From: fulleni Date: Tue, 23 Sep 2025 06:35:18 +0100 Subject: [PATCH 1/3] refactor(app_configuration): centralize decorator type visibility logic This commit introduces a new method `_isDecoratorApplicableToRole` to centralize the logic for determining if a decorator type is applicable to a user role. This change improves code maintainability and prevents illogical configurations in the dashboard. - Added `_isDecoratorApplicableToRole` method in `_FeedDecoratorFormState` class - Updated checkbox visibility logic in `buildRoleConfigCheckbox` method --- .../widgets/feed_decorator_form.dart | 40 +++++++++++++++---- 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/lib/app_configuration/widgets/feed_decorator_form.dart b/lib/app_configuration/widgets/feed_decorator_form.dart index e02ab891..66026f47 100644 --- a/lib/app_configuration/widgets/feed_decorator_form.dart +++ b/lib/app_configuration/widgets/feed_decorator_form.dart @@ -119,6 +119,30 @@ class _FeedDecoratorFormState extends State super.dispose(); } + /// Determines if a given decorator type is logically applicable to a user role. + /// + /// This method centralizes the business logic for decorator visibility + /// to prevent illogical configurations in the dashboard. + bool _isDecoratorApplicableToRole( + FeedDecoratorType decoratorType, + AppUserRole role, + ) { + switch (decoratorType) { + // The 'linkAccount' decorator is only for guest users. + case FeedDecoratorType.linkAccount: + return role == AppUserRole.guestUser; + // The 'upgrade' decorator is only for standard users. + case FeedDecoratorType.upgrade: + return role == AppUserRole.standardUser; + // All other decorators are applicable to any user role. + case FeedDecoratorType.rateApp: + case FeedDecoratorType.enableNotifications: + case FeedDecoratorType.suggestedTopics: + case FeedDecoratorType.suggestedSources: + return true; + } + } + @override Widget build(BuildContext context) { final l10n = AppLocalizationsX(context).l10n; @@ -210,18 +234,19 @@ class _FeedDecoratorFormState extends State FeedDecoratorConfig decoratorConfig, ) { final roleConfig = decoratorConfig.visibleTo[role]; - final isLinkAccountForStandardOrPremium = - widget.decoratorType == FeedDecoratorType.linkAccount && - (role == AppUserRole.standardUser || role == AppUserRole.premiumUser); + final isApplicable = _isDecoratorApplicableToRole( + widget.decoratorType, + role, + ); return Column( children: [ CheckboxListTile( title: Text(l10n.visibleToRoleLabel(role.l10n(context))), value: roleConfig != null, - onChanged: isLinkAccountForStandardOrPremium - ? null // Disable for standard and premium users for linkAccount - : (value) { + // Disable the checkbox if the decorator is not applicable to the role. + onChanged: isApplicable + ? (value) { final newVisibleTo = Map.from( decoratorConfig.visibleTo, @@ -245,7 +270,8 @@ class _FeedDecoratorFormState extends State feedDecoratorConfig: newFeedDecoratorConfig, ), ); - }, + } + : null, ), if (roleConfig != null) Padding( From 027e2e20bfff7851cb7ff5c7d5b8131c43d1ff06 Mon Sep 17 00:00:00 2001 From: fulleni Date: Tue, 23 Sep 2025 06:36:24 +0100 Subject: [PATCH 2/3] style: format misc --- .../bloc/draft_headlines/draft_headlines_bloc.dart | 2 +- lib/content_management/bloc/draft_topics/draft_topics_bloc.dart | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/content_management/bloc/draft_headlines/draft_headlines_bloc.dart b/lib/content_management/bloc/draft_headlines/draft_headlines_bloc.dart index 6e969596..7b8a618d 100644 --- a/lib/content_management/bloc/draft_headlines/draft_headlines_bloc.dart +++ b/lib/content_management/bloc/draft_headlines/draft_headlines_bloc.dart @@ -120,7 +120,7 @@ class DraftHeadlinesBloc final headlineToPublish = originalHeadlines[headlineIndex]; final updatedHeadlines = List.from(originalHeadlines) ..removeAt(headlineIndex); - + // Optimistically remove the headline from the UI. emit( state.copyWith( diff --git a/lib/content_management/bloc/draft_topics/draft_topics_bloc.dart b/lib/content_management/bloc/draft_topics/draft_topics_bloc.dart index 2f789165..def36564 100644 --- a/lib/content_management/bloc/draft_topics/draft_topics_bloc.dart +++ b/lib/content_management/bloc/draft_topics/draft_topics_bloc.dart @@ -119,7 +119,7 @@ class DraftTopicsBloc extends Bloc { final topicToPublish = originalTopics[topicIndex]; final updatedTopics = List.from(originalTopics) ..removeAt(topicIndex); - + // Optimistically remove the topic from the UI. emit( state.copyWith( From 272e7b8af5268af36c16d2506297c7c17525c3f6 Mon Sep 17 00:00:00 2001 From: fulleni Date: Tue, 23 Sep 2025 06:41:47 +0100 Subject: [PATCH 3/3] fix(app_configuration): disable role checkbox for inapplicable decorators - Update checkbox value to consider both roleConfig and isApplicable - Ensures the checkbox is only enabled for applicable roles --- lib/app_configuration/widgets/feed_decorator_form.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/app_configuration/widgets/feed_decorator_form.dart b/lib/app_configuration/widgets/feed_decorator_form.dart index 66026f47..0fcd664f 100644 --- a/lib/app_configuration/widgets/feed_decorator_form.dart +++ b/lib/app_configuration/widgets/feed_decorator_form.dart @@ -243,7 +243,7 @@ class _FeedDecoratorFormState extends State children: [ CheckboxListTile( title: Text(l10n.visibleToRoleLabel(role.l10n(context))), - value: roleConfig != null, + value: roleConfig != null && isApplicable, // Disable the checkbox if the decorator is not applicable to the role. onChanged: isApplicable ? (value) {