diff --git a/lib/features/base/widget/drop_down_button_widget.dart b/lib/features/base/widget/drop_down_button_widget.dart index dab5bbbb2..9df9b2059 100644 --- a/lib/features/base/widget/drop_down_button_widget.dart +++ b/lib/features/base/widget/drop_down_button_widget.dart @@ -10,6 +10,7 @@ import 'package:jmap_dart_client/jmap/identities/identity.dart'; import 'package:pointer_interceptor/pointer_interceptor.dart'; import 'package:rich_text_composer/rich_text_composer.dart' as rich_text_composer; import 'package:rule_filter/rule_filter/rule_condition.dart' as rule_condition; +import 'package:rule_filter/rule_filter/rule_condition_group.dart'; import 'package:tmail_ui_user/features/composer/presentation/model/font_name_type.dart'; import 'package:tmail_ui_user/features/rules_filter_creator/presentation/extensions/rule_condition_extensions.dart'; import 'package:tmail_ui_user/features/rules_filter_creator/presentation/model/email_rule_filter_action.dart'; @@ -188,6 +189,9 @@ class DropDownButtonWidget extends StatelessWidget { if (item is EmailRuleFilterAction) { return item.getTitle(context); } + if (item is ConditionCombiner) { + return item.getTitle(context); + } return ''; } } \ No newline at end of file diff --git a/lib/features/rules_filter_creator/presentation/extensions/rule_condition_extensions.dart b/lib/features/rules_filter_creator/presentation/extensions/rule_condition_extensions.dart index 4161d68d1..ca67eb549 100644 --- a/lib/features/rules_filter_creator/presentation/extensions/rule_condition_extensions.dart +++ b/lib/features/rules_filter_creator/presentation/extensions/rule_condition_extensions.dart @@ -2,6 +2,7 @@ import 'package:flutter/cupertino.dart'; import 'package:rule_filter/rule_filter/rule_condition.dart' as rule_condition; import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; +import 'package:rule_filter/rule_filter/rule_condition_group.dart' as rule_combiner; extension RuleConditionFieldExtension on rule_condition.Field { @@ -35,4 +36,16 @@ extension RuleConditionComparatorExtension on rule_condition.Comparator { return AppLocalizations.of(context).notExactlyEquals; } } +} + +extension RuleConditionCombinerExtension on rule_combiner.ConditionCombiner { + + String getTitle(BuildContext context) { + switch(this) { + case rule_combiner.ConditionCombiner.AND: + return AppLocalizations.of(context).all; + case rule_combiner.ConditionCombiner.OR: + return AppLocalizations.of(context).any; + } + } } \ No newline at end of file diff --git a/lib/features/rules_filter_creator/presentation/rules_filter_creator_controller.dart b/lib/features/rules_filter_creator/presentation/rules_filter_creator_controller.dart index 062c7a90a..5925c157d 100644 --- a/lib/features/rules_filter_creator/presentation/rules_filter_creator_controller.dart +++ b/lib/features/rules_filter_creator/presentation/rules_filter_creator_controller.dart @@ -16,6 +16,7 @@ import 'package:rule_filter/rule_filter/rule_action.dart'; import 'package:rule_filter/rule_filter/rule_append_in.dart'; import 'package:rule_filter/rule_filter/rule_condition.dart' as rule_condition; import 'package:rule_filter/rule_filter/rule_condition.dart'; +import 'package:rule_filter/rule_filter/rule_condition_group.dart'; import 'package:rule_filter/rule_filter/tmail_rule.dart'; import 'package:tmail_ui_user/features/base/base_mailbox_controller.dart'; import 'package:tmail_ui_user/features/destination_picker/presentation/model/destination_picker_arguments.dart'; @@ -61,6 +62,7 @@ class RulesFilterCreatorController extends BaseMailboxController { final TextEditingController inputRuleNameController = TextEditingController(); final FocusNode inputRuleNameFocusNode = FocusNode(); final listRuleConditionValueArguments = RxList(); + final conditionCombinerType = Rxn(); String? _newRuleName; @@ -143,6 +145,7 @@ class RulesFilterCreatorController extends BaseMailboxController { } void _setUpDefaultValueRuleFilter() { + conditionCombinerType.value = ConditionCombiner.AND; switch(actionType.value) { case CreatorActionType.create: RuleCondition newRuleCondition = RuleCondition( @@ -177,23 +180,27 @@ class RulesFilterCreatorController extends BaseMailboxController { break; case CreatorActionType.edit: if (_currentTMailRule != null) { - RuleCondition currentRule = RuleCondition( - field: _currentTMailRule!.condition.field, - comparator: _currentTMailRule!.condition.comparator, - value: _currentTMailRule!.condition.value + RuleConditionGroup currentRule = RuleConditionGroup( + conditionCombiner: _currentTMailRule!.conditionGroup!.conditionCombiner, + conditions: _currentTMailRule!.conditionGroup!.conditions, ); - listRuleCondition.add(currentRule); - RulesFilterInputFieldArguments newRuleConditionValueArguments = RulesFilterInputFieldArguments( - focusNode: FocusNode(), - errorText: '', - controller: TextEditingController(), - ); - listRuleConditionValueArguments.add(newRuleConditionValueArguments); + for (var condition in currentRule.conditions) { + listRuleCondition.add(condition); + RulesFilterInputFieldArguments newRuleConditionValueArguments = RulesFilterInputFieldArguments( + focusNode: FocusNode(), + errorText: '', + controller: TextEditingController(), + ); + listRuleConditionValueArguments.add(newRuleConditionValueArguments); + _setValueInputField( + newRuleConditionValueArguments.controller, + condition.value + ); + } + conditionCombinerType.value = currentRule.conditionCombiner; + emailRuleFilterActionSelected.value = EmailRuleFilterAction.moveMessage; - _setValueInputField( - listRuleConditionValueArguments[0].controller, - listRuleCondition[0].value - ); + _newRuleName = _currentTMailRule!.name; _setValueInputField(inputRuleNameController, _newRuleName ?? ''); _getAllMailboxAction(); @@ -367,8 +374,7 @@ class RulesFilterCreatorController extends BaseMailboxController { late EquatableMixin ruleFilterRequest; if (actionType.value == CreatorActionType.create) { - for (var ruleCondition in listRuleCondition) { - final newTMailRule = TMailRule( + final newTMailRule = TMailRule( id: _currentTMailRule?.id, name: _newRuleName!, action: RuleAction( @@ -376,13 +382,12 @@ class RulesFilterCreatorController extends BaseMailboxController { mailboxIds: [mailboxSelected.value!.id] ) ), - condition: rule_condition.RuleCondition( - field: ruleCondition.field, - comparator: ruleCondition.comparator, - value: ruleCondition.value - )); - ruleFilterRequest = CreateNewEmailRuleFilterRequest(_listEmailRule ?? [], newTMailRule); - } + conditionGroup: RuleConditionGroup( + conditionCombiner: conditionCombinerType.value!, + conditions: listRuleCondition, + ) + ); + ruleFilterRequest = CreateNewEmailRuleFilterRequest(_listEmailRule ?? [], newTMailRule); } else { final newTMailRule = TMailRule( id: _currentTMailRule?.id, @@ -392,10 +397,9 @@ class RulesFilterCreatorController extends BaseMailboxController { mailboxIds: [mailboxSelected.value!.id] ) ), - condition: rule_condition.RuleCondition( - field: listRuleCondition[0].field, - comparator: listRuleCondition[0].comparator, - value: listRuleCondition[0].value + conditionGroup: RuleConditionGroup( + conditionCombiner: conditionCombinerType.value!, + conditions: listRuleCondition, )); ruleFilterRequest = EditEmailRuleFilterRequest(_listEmailRule?.withIds ?? [], newTMailRule); } @@ -425,4 +429,10 @@ class RulesFilterCreatorController extends BaseMailboxController { listRuleCondition.removeAt(ruleConditionIndex); listRuleConditionValueArguments.removeAt(ruleConditionIndex); } + + void selectConditionCombiner(ConditionCombiner? combinerType) { + if (combinerType != null) { + conditionCombinerType.value = combinerType; + } + } } \ No newline at end of file diff --git a/lib/features/rules_filter_creator/presentation/rules_filter_creator_view.dart b/lib/features/rules_filter_creator/presentation/rules_filter_creator_view.dart index e49da1dec..168b86323 100644 --- a/lib/features/rules_filter_creator/presentation/rules_filter_creator_view.dart +++ b/lib/features/rules_filter_creator/presentation/rules_filter_creator_view.dart @@ -5,15 +5,18 @@ import 'package:get/get.dart'; import 'package:model/model.dart'; import 'package:pointer_interceptor/pointer_interceptor.dart'; import 'package:rule_filter/rule_filter/rule_condition.dart' as rule_condition; +import 'package:rule_filter/rule_filter/rule_condition_group.dart'; import 'package:tmail_ui_user/features/base/widget/drop_down_button_widget.dart'; import 'package:tmail_ui_user/features/rules_filter_creator/presentation/extensions/rule_condition_extensions.dart'; import 'package:tmail_ui_user/features/rules_filter_creator/presentation/model/email_rule_filter_action.dart'; import 'package:tmail_ui_user/features/rules_filter_creator/presentation/rules_filter_creator_controller.dart'; import 'package:tmail_ui_user/features/rules_filter_creator/presentation/widgets/rule_action_bottom_sheet_action_tile_builder.dart'; +import 'package:tmail_ui_user/features/rules_filter_creator/presentation/widgets/rule_condition_combiner_bottomsheet_action_tile_builder.dart'; import 'package:tmail_ui_user/features/rules_filter_creator/presentation/widgets/rule_condition_comparator_bottom_sheet_action_tile_builder.dart'; import 'package:tmail_ui_user/features/rules_filter_creator/presentation/widgets/rule_condition_field_bottom_sheet_action_tile_builder.dart'; import 'package:tmail_ui_user/features/rules_filter_creator/presentation/widgets/rule_filter_button_field.dart'; import 'package:tmail_ui_user/features/rules_filter_creator/presentation/widgets/rule_filter_condition_widget.dart'; +import 'package:tmail_ui_user/features/rules_filter_creator/presentation/widgets/rule_filter_title_builder.dart'; import 'package:tmail_ui_user/features/rules_filter_creator/presentation/widgets/rules_filter_input_field_builder.dart'; import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; import 'package:tmail_ui_user/main/routes/route_navigation.dart'; @@ -137,41 +140,38 @@ class RuleFilterCreatorView extends GetWidget { focusNode: controller.inputRuleNameFocusNode, onChangeAction: (value) => controller.updateRuleName(context, value),)), const SizedBox(height: 24), - Text(AppLocalizations.of(context).conditionTitleRulesFilter, - overflow: CommonTextStyle.defaultTextOverFlow, - softWrap: CommonTextStyle.defaultSoftWrap, - maxLines: 1, - style: const TextStyle( - fontWeight: FontWeight.w500, - fontSize: 16, - color: Colors.black)), + Obx(() => RuleFilterTitle( + conditionCombinerType: controller.conditionCombinerType.value, + tapActionCallback: (value) => controller.selectConditionCombiner(value), + ruleFilterConditionScreenType: RuleFilterConditionScreenType.desktop, + )), const SizedBox(height: 24), _buildListRuleFilterConditionList(context, RuleFilterConditionScreenType.desktop), - // Container( - // padding: const EdgeInsets.only(top: 8), - // child: InkWell( - // onTap: controller.tapAddCondition, - // child: Row( - // crossAxisAlignment: CrossAxisAlignment.center, - // children: [ - // SvgPicture.asset( - // _imagePaths.icAddNewFolder, - // fit: BoxFit.fill, - // ), - // const SizedBox(width: 15,), - // Text( - // AppLocalizations.of(context).addCondition, - // maxLines: 1, - // style: const TextStyle( - // fontWeight: FontWeight.w500, - // fontSize: 17, - // color: AppColor.primaryColor - // ) - // ) - // ], - // ), - // ), - // ), + Container( + padding: const EdgeInsets.only(top: 8), + child: InkWell( + onTap: controller.tapAddCondition, + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + SvgPicture.asset( + _imagePaths.icAddNewFolder, + fit: BoxFit.fill, + ), + const SizedBox(width: 15,), + Text( + AppLocalizations.of(context).addCondition, + maxLines: 1, + style: const TextStyle( + fontWeight: FontWeight.w500, + fontSize: 17, + color: AppColor.primaryColor + ) + ) + ], + ), + ), + ), const SizedBox(height: 24), Text(AppLocalizations.of(context).actionTitleRulesFilter, overflow: CommonTextStyle.defaultTextOverFlow, @@ -288,41 +288,38 @@ class RuleFilterCreatorView extends GetWidget { focusNode: controller.inputRuleNameFocusNode, onChangeAction: (value) => controller.updateRuleName(context, value),)), const SizedBox(height: 24), - Text(AppLocalizations.of(context).conditionTitleRulesFilter, - overflow: CommonTextStyle.defaultTextOverFlow, - softWrap: CommonTextStyle.defaultSoftWrap, - maxLines: 1, - style: const TextStyle( - fontWeight: FontWeight.w500, - fontSize: 16, - color: Colors.black)), + Obx(() => RuleFilterTitle( + conditionCombinerType: controller.conditionCombinerType.value, + tapActionCallback: (value) => controller.selectConditionCombiner(value), + ruleFilterConditionScreenType: RuleFilterConditionScreenType.tablet, + )), const SizedBox(height: 24), _buildListRuleFilterConditionList(context, RuleFilterConditionScreenType.tablet), - // Container( - // padding: const EdgeInsets.only(top: 8), - // child: InkWell( - // onTap: controller.tapAddCondition, - // child: Row( - // crossAxisAlignment: CrossAxisAlignment.center, - // children: [ - // SvgPicture.asset( - // _imagePaths.icAddNewFolder, - // fit: BoxFit.fill, - // ), - // const SizedBox(width: 15,), - // Text( - // AppLocalizations.of(context).addCondition, - // maxLines: 1, - // style: const TextStyle( - // fontWeight: FontWeight.w500, - // fontSize: 17, - // color: AppColor.primaryColor - // ) - // ) - // ], - // ), - // ), - // ), + Container( + padding: const EdgeInsets.only(top: 8), + child: InkWell( + onTap: controller.tapAddCondition, + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + SvgPicture.asset( + _imagePaths.icAddNewFolder, + fit: BoxFit.fill, + ), + const SizedBox(width: 15,), + Text( + AppLocalizations.of(context).addCondition, + maxLines: 1, + style: const TextStyle( + fontWeight: FontWeight.w500, + fontSize: 17, + color: AppColor.primaryColor + ) + ) + ], + ), + ), + ), const SizedBox(height: 24), Text(AppLocalizations.of(context).actionTitleRulesFilter, overflow: CommonTextStyle.defaultTextOverFlow, @@ -445,42 +442,47 @@ class RuleFilterCreatorView extends GetWidget { height: 1, thickness: 0.2), ), - Text(AppLocalizations.of(context).conditionTitleRulesFilter, - overflow: CommonTextStyle.defaultTextOverFlow, - softWrap: CommonTextStyle.defaultSoftWrap, - maxLines: 1, - style: const TextStyle( - fontWeight: FontWeight.w500, - fontSize: 16, - color: Colors.black)), + Obx(() => RuleFilterTitle( + conditionCombinerType: controller.conditionCombinerType.value, + ruleFilterConditionScreenType: RuleFilterConditionScreenType.mobile, + tapActionCallback: (value) => { + controller.openContextMenuAction( + context, + _bottomSheetRuleConditionCombinerActionTiles( + context, + controller.conditionCombinerType.value, + ) + ), + }, + )), const SizedBox(height: 24), _buildListRuleFilterConditionList(context, RuleFilterConditionScreenType.mobile), - // Container( - // padding: const EdgeInsets.only(top: 12), - // child: InkWell( - // onTap: controller.tapAddCondition, - // child: Row( - // crossAxisAlignment: CrossAxisAlignment.center, - // mainAxisAlignment: MainAxisAlignment.center, - // children: [ - // SvgPicture.asset( - // _imagePaths.icAddNewFolder, - // fit: BoxFit.fill, - // ), - // const SizedBox(width: 15,), - // Text( - // AppLocalizations.of(context).addCondition, - // maxLines: 1, - // style: const TextStyle( - // fontWeight: FontWeight.w500, - // fontSize: 17, - // color: AppColor.primaryColor - // ) - // ) - // ], - // ), - // ), - // ), + Container( + padding: const EdgeInsets.only(top: 12), + child: InkWell( + onTap: controller.tapAddCondition, + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SvgPicture.asset( + _imagePaths.icAddNewFolder, + fit: BoxFit.fill, + ), + const SizedBox(width: 15,), + Text( + AppLocalizations.of(context).addCondition, + maxLines: 1, + style: const TextStyle( + fontWeight: FontWeight.w500, + fontSize: 17, + color: AppColor.primaryColor + ) + ) + ], + ), + ), + ), const Padding( padding: EdgeInsets.symmetric(vertical: 12), child: Divider( @@ -708,6 +710,39 @@ class RuleFilterCreatorView extends GetWidget { .build(); } + List _bottomSheetRuleConditionCombinerActionTiles( + BuildContext context, + ConditionCombiner? combinerSelected, + ) { + return ConditionCombiner.values + .map((combiner) => + _buildRuleConditionCombinerWidget(context, combiner, combinerSelected)) + .toList(); + } + + Widget _buildRuleConditionCombinerWidget( + BuildContext context, + ConditionCombiner combiner, + ConditionCombiner? combinerSelected, + ) { + return (RuleConditionCombinerSheetActionTileBuilder( + combiner.getTitle(context), + combiner, + combinerSelected, + iconLeftPadding: const EdgeInsets.only(left: 12, right: 16), + iconRightPadding: const EdgeInsets.only(right: 12), + actionSelected: SvgPicture.asset( + _imagePaths.icFilterSelected, + width: 20, + height: 20, + fit: BoxFit.fill)) + ..onActionClick((combiner) { + controller.selectConditionCombiner(combiner); + popBack(); + })) + .build(); + } + List _bottomSheetActionRuleFilterActionTiles( BuildContext context, EmailRuleFilterAction? ruleActionSelected diff --git a/lib/features/rules_filter_creator/presentation/styles/rule_condition_combiner_bottom_sheet_styles.dart b/lib/features/rules_filter_creator/presentation/styles/rule_condition_combiner_bottom_sheet_styles.dart new file mode 100644 index 000000000..7bd2f30b3 --- /dev/null +++ b/lib/features/rules_filter_creator/presentation/styles/rule_condition_combiner_bottom_sheet_styles.dart @@ -0,0 +1,6 @@ +import 'package:flutter/material.dart'; + +class RuleConditionCombinerBottomSheetStyles { + static const Color defaultBgColor = Colors.white; + static const double defaultIconRightPadding = 12.0; +} \ No newline at end of file diff --git a/lib/features/rules_filter_creator/presentation/styles/rule_filter_title_styles.dart b/lib/features/rules_filter_creator/presentation/styles/rule_filter_title_styles.dart new file mode 100644 index 000000000..474fd7445 --- /dev/null +++ b/lib/features/rules_filter_creator/presentation/styles/rule_filter_title_styles.dart @@ -0,0 +1,14 @@ +import 'package:flutter/material.dart'; + +class RuleFilterTitleStyles { + static const double fontSize = 16.0; + static const Color textColor = Colors.black; + static const TextStyle textStyle = TextStyle( + fontWeight: FontWeight.w500, + fontSize: fontSize, + color: textColor, + ); + static const int textMaxLines = 1; + static const double combinerTypeSelectionAreaWith = 200.0; + static const double combinerTypeSelectionAreaPadding = 12.0; +} \ No newline at end of file diff --git a/lib/features/rules_filter_creator/presentation/widgets/rule_condition_combiner_bottomsheet_action_tile_builder.dart b/lib/features/rules_filter_creator/presentation/widgets/rule_condition_combiner_bottomsheet_action_tile_builder.dart new file mode 100644 index 000000000..74b1755db --- /dev/null +++ b/lib/features/rules_filter_creator/presentation/widgets/rule_condition_combiner_bottomsheet_action_tile_builder.dart @@ -0,0 +1,69 @@ +import 'package:core/core.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:rule_filter/rule_filter/rule_condition_group.dart'; +import 'package:tmail_ui_user/features/rules_filter_creator/presentation/styles/rule_condition_combiner_bottom_sheet_styles.dart'; + +class RuleConditionCombinerSheetActionTileBuilder + extends CupertinoActionSheetNoIconBuilder { + + final ConditionCombiner combiner; + final ConditionCombiner? combinerCurrent; + final SvgPicture? actionSelected; + final Color? bgColor; + final EdgeInsets? iconLeftPadding; + final EdgeInsets? iconRightPadding; + + RuleConditionCombinerSheetActionTileBuilder( + String actionName, + this.combiner, + this.combinerCurrent, + { + Key? key, + this.actionSelected, + this.bgColor, + this.iconLeftPadding, + this.iconRightPadding, + } + ) : super(actionName, key: key); + + @override + Widget build() { + return Container( + color: bgColor ?? RuleConditionCombinerBottomSheetStyles.defaultBgColor, + child: MouseRegion( + cursor: PlatformInfo.isWeb + ? MaterialStateMouseCursor.clickable + : MouseCursor.defer, + child: CupertinoActionSheetAction( + key: key, + child: Stack( + children: [ + Center( + child: Text( + actionName, + textAlign: TextAlign.center, + style: actionTextStyle() + ), + ), + if (combinerCurrent == combiner && actionSelected != null) + Align( + alignment: Alignment.centerRight, + child: Padding( + padding: iconRightPadding ?? const EdgeInsets.only(right: RuleConditionCombinerBottomSheetStyles.defaultIconRightPadding), + child: actionSelected! + ), + ), + ], + ), + onPressed: () { + if (onCupertinoActionSheetActionClick != null) { + onCupertinoActionSheetActionClick!(combiner); + } + }, + ), + ), + ); + } +} \ No newline at end of file diff --git a/lib/features/rules_filter_creator/presentation/widgets/rule_filter_button_field.dart b/lib/features/rules_filter_creator/presentation/widgets/rule_filter_button_field.dart index 6f1c19d34..79b8746c3 100644 --- a/lib/features/rules_filter_creator/presentation/widgets/rule_filter_button_field.dart +++ b/lib/features/rules_filter_creator/presentation/widgets/rule_filter_button_field.dart @@ -7,6 +7,7 @@ import 'package:flutter_svg/flutter_svg.dart'; import 'package:get/get.dart'; import 'package:model/model.dart'; import 'package:rule_filter/rule_filter/rule_condition.dart' as rule_condition; +import 'package:rule_filter/rule_filter/rule_condition_group.dart'; import 'package:tmail_ui_user/features/mailbox/presentation/extensions/presentation_mailbox_extension.dart'; import 'package:tmail_ui_user/features/rules_filter_creator/presentation/extensions/rule_condition_extensions.dart'; import 'package:tmail_ui_user/features/rules_filter_creator/presentation/model/email_rule_filter_action.dart'; @@ -71,6 +72,9 @@ class RuleFilterButtonField extends StatelessWidget { if (value is EmailRuleFilterAction) { return value.getTitle(context); } + if (value is ConditionCombiner) { + return value.getTitle(context); + } return ''; } } \ No newline at end of file diff --git a/lib/features/rules_filter_creator/presentation/widgets/rule_filter_condition_row_builder.dart b/lib/features/rules_filter_creator/presentation/widgets/rule_filter_condition_row_builder.dart index 96eb9a5f8..a26cd3811 100644 --- a/lib/features/rules_filter_creator/presentation/widgets/rule_filter_condition_row_builder.dart +++ b/lib/features/rules_filter_creator/presentation/widgets/rule_filter_condition_row_builder.dart @@ -6,6 +6,7 @@ import 'package:rule_filter/rule_filter/rule_condition.dart' as rule_condition; import 'package:tmail_ui_user/features/base/widget/drop_down_button_widget.dart'; import 'package:tmail_ui_user/features/rules_filter_creator/presentation/model/rule_filter_condition_type.dart'; import 'package:tmail_ui_user/features/rules_filter_creator/presentation/widgets/rule_filter_button_field.dart'; +import 'package:tmail_ui_user/features/rules_filter_creator/presentation/widgets/rule_filter_condition_remove_button_builder.dart'; import 'package:tmail_ui_user/features/rules_filter_creator/presentation/widgets/rules_filter_input_field_builder.dart'; import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; @@ -105,14 +106,14 @@ class RuleFilterConditionRow extends StatelessWidget { editingController: conditionValueEditingController, ) ), - // Container( - // padding: const EdgeInsets.only(left: 12), - // alignment: Alignment.center, - // child: RuleFilterConditionRemoveButton( - // tapRemoveRuleFilterConditionCallback: tapRemoveRuleFilterConditionCallback, - // imagePath: imagePaths, - // ) - // ), + Container( + padding: const EdgeInsets.only(left: 12), + alignment: Alignment.center, + child: RuleFilterConditionRemoveButton( + tapRemoveRuleFilterConditionCallback: tapRemoveRuleFilterConditionCallback, + imagePath: imagePaths, + ) + ), ], ); default: diff --git a/lib/features/rules_filter_creator/presentation/widgets/rule_filter_condition_widget.dart b/lib/features/rules_filter_creator/presentation/widgets/rule_filter_condition_widget.dart index 6e6047c40..7f89ca92d 100644 --- a/lib/features/rules_filter_creator/presentation/widgets/rule_filter_condition_widget.dart +++ b/lib/features/rules_filter_creator/presentation/widgets/rule_filter_condition_widget.dart @@ -37,8 +37,7 @@ class RuleFilterConditionWidget extends StatelessWidget { @override Widget build(BuildContext context) { return Slidable( - // enabled: ruleFilterConditionScreenType == RuleFilterConditionScreenType.mobile ? true : false, - enabled: false, + enabled: ruleFilterConditionScreenType == RuleFilterConditionScreenType.mobile ? true : false, endActionPane: ActionPane( extentRatio: 0.1, motion: const BehindMotion(), diff --git a/lib/features/rules_filter_creator/presentation/widgets/rule_filter_title_builder.dart b/lib/features/rules_filter_creator/presentation/widgets/rule_filter_title_builder.dart new file mode 100644 index 000000000..615b6989b --- /dev/null +++ b/lib/features/rules_filter_creator/presentation/widgets/rule_filter_title_builder.dart @@ -0,0 +1,71 @@ +import 'package:core/presentation/utils/keyboard_utils.dart'; +import 'package:core/presentation/utils/style_utils.dart'; +import 'package:flutter/material.dart'; +import 'package:rule_filter/rule_filter/rule_condition_group.dart'; +import 'package:tmail_ui_user/features/base/widget/drop_down_button_widget.dart'; +import 'package:tmail_ui_user/features/rules_filter_creator/presentation/model/rule_filter_condition_type.dart'; +import 'package:tmail_ui_user/features/rules_filter_creator/presentation/styles/rule_filter_title_styles.dart'; +import 'package:tmail_ui_user/features/rules_filter_creator/presentation/widgets/rule_filter_button_field.dart'; +import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; + +typedef OnTapActionCallback = Function(ConditionCombiner? value); + +class RuleFilterTitle extends StatelessWidget { + + final ConditionCombiner? conditionCombinerType; + final OnTapActionCallback? tapActionCallback; + final RuleFilterConditionScreenType ruleFilterConditionScreenType; + + const RuleFilterTitle({ + Key? key, + required this.ruleFilterConditionScreenType, + this.conditionCombinerType, + this.tapActionCallback, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + + return Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisSize: MainAxisSize.min, + children: [ + Text( + AppLocalizations.of(context).conditionTitleRulesFilterBeforeCombiner, + overflow: CommonTextStyle.defaultTextOverFlow, + softWrap: CommonTextStyle.defaultSoftWrap, + maxLines: RuleFilterTitleStyles.textMaxLines, + style: RuleFilterTitleStyles.textStyle, + ), + Container( + padding: const EdgeInsets.symmetric(horizontal: RuleFilterTitleStyles.combinerTypeSelectionAreaPadding), + width: RuleFilterTitleStyles.combinerTypeSelectionAreaWith, + child: ruleFilterConditionScreenType == RuleFilterConditionScreenType.mobile + ? RuleFilterButtonField( + value: conditionCombinerType, + tapActionCallback: (value) { + KeyboardUtils.hideKeyboard(context); + tapActionCallback?.call(value); + }, + ) + : DropDownButtonWidget( + items: ConditionCombiner.values, + itemSelected: conditionCombinerType, + supportSelectionIcon: true, + onChanged: (value) { + KeyboardUtils.hideKeyboard(context); + tapActionCallback?.call(value); + }, + ), + ), + Expanded( + child: Text( + AppLocalizations.of(context).conditionTitleRulesFilterAfterCombiner, + overflow: CommonTextStyle.defaultTextOverFlow, + style: RuleFilterTitleStyles.textStyle, + ), + ) + ] + ); + } +} diff --git a/lib/l10n/intl_messages.arb b/lib/l10n/intl_messages.arb index ff8b6fb10..a147e2623 100644 --- a/lib/l10n/intl_messages.arb +++ b/lib/l10n/intl_messages.arb @@ -1,5 +1,5 @@ { - "@@last_modified": "2023-10-27T20:44:50.998215", + "@@last_modified": "2023-09-16T17:09:02.481409", "initializing_data": "Initializing data...", "@initializing_data": { "type": "text", @@ -3325,5 +3325,29 @@ "type": "text", "placeholders_order": [], "placeholders": {} + }, + "all": "All", + "@all": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "any": "Any", + "@any": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "conditionTitleRulesFilterBeforeCombiner": "If", + "@conditionTitleRulesFilterBeforeCombiner": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "conditionTitleRulesFilterAfterCombiner": "of the following conditions are met:", + "@conditionTitleRulesFilterAfterCombiner": { + "type": "text", + "placeholders_order": [], + "placeholders": {} } } \ No newline at end of file diff --git a/lib/main/localizations/app_localizations.dart b/lib/main/localizations/app_localizations.dart index a74657e40..4662cefeb 100644 --- a/lib/main/localizations/app_localizations.dart +++ b/lib/main/localizations/app_localizations.dart @@ -3428,4 +3428,32 @@ class AppLocalizations { name: 'sending', ); } + + String get all { + return Intl.message( + 'All', + name: 'all', + ); + } + + String get any { + return Intl.message( + 'Any', + name: 'any', + ); + } + + String get conditionTitleRulesFilterBeforeCombiner { + return Intl.message( + 'If', + name: 'conditionTitleRulesFilterBeforeCombiner', + ); + } + + String get conditionTitleRulesFilterAfterCombiner { + return Intl.message( + 'of the following conditions are met:', + name: 'conditionTitleRulesFilterAfterCombiner', + ); + } } \ No newline at end of file diff --git a/rule_filter/lib/rule_filter/rule_condition_group.dart b/rule_filter/lib/rule_filter/rule_condition_group.dart index 30ddf5e71..db23d4548 100644 --- a/rule_filter/lib/rule_filter/rule_condition_group.dart +++ b/rule_filter/lib/rule_filter/rule_condition_group.dart @@ -24,9 +24,9 @@ class RuleConditionGroup extends FilterCondition { @override List get props => [ - conditionCombiner, - conditions, - ]; + conditionCombiner, + conditions, + ]; factory RuleConditionGroup.fromJson(Map json) => _$RuleConditionGroupFromJson(json); diff --git a/rule_filter/lib/rule_filter/tmail_rule.dart b/rule_filter/lib/rule_filter/tmail_rule.dart index 265da12a9..2a8bee649 100644 --- a/rule_filter/lib/rule_filter/tmail_rule.dart +++ b/rule_filter/lib/rule_filter/tmail_rule.dart @@ -15,7 +15,9 @@ part 'tmail_rule.g.dart'; class TMailRule extends Rule { final RuleId? id; final String name; + @JsonKey(includeIfNull: false) final RuleCondition? condition; + @JsonKey(includeIfNull: false) final RuleConditionGroup? conditionGroup; final RuleAction action; @@ -30,17 +32,7 @@ class TMailRule extends Rule { factory TMailRule.fromJson(Map json) => _$TMailRuleFromJson(json); - Map toJson() { - final result = _$TMailRuleToJson(this); - - if (result['condition'] != null) { - result.remove('conditionGroup'); - } else { - result.remove('condition'); - } - - return result; - } + Map toJson() => _$TMailRuleToJson(this); @override List get props => [