From 36c5712c79a191d4ce9d52815e6483efd0ac1361 Mon Sep 17 00:00:00 2001 From: mohammad Date: Tue, 13 May 2025 16:24:08 +0300 Subject: [PATCH] add water heater operational values to routines --- assets/icons/refresh_status_icon.svg | 12 ++ .../all_devices/models/devices_model.dart | 17 +- .../dialog_helper/device_dialog_helper.dart | 10 + .../water_heater/water_heater_functions.dart | 134 ++++++++++++ .../water_heater_operational_value.dart | 11 + lib/pages/routines/widgets/if_container.dart | 5 +- .../routines/widgets/routine_devices.dart | 3 +- .../flush_operational_values_list.dart | 5 - .../water_heater_operational_values_list.dart | 65 ++++++ .../water_heater_presence_sensor.dart | 203 ++++++++++++++++++ .../water_heater_value_selector_widget.dart | 192 +++++++++++++++++ .../routines/widgets/then_container.dart | 16 +- lib/utils/constants/assets.dart | 1 + 13 files changed, 662 insertions(+), 12 deletions(-) create mode 100644 assets/icons/refresh_status_icon.svg create mode 100644 lib/pages/routines/models/water_heater/water_heater_functions.dart create mode 100644 lib/pages/routines/models/water_heater/water_heater_operational_value.dart create mode 100644 lib/pages/routines/widgets/routine_dialogs/water_heater/water_heater_operational_values_list.dart create mode 100644 lib/pages/routines/widgets/routine_dialogs/water_heater/water_heater_presence_sensor.dart create mode 100644 lib/pages/routines/widgets/routine_dialogs/water_heater/water_heater_value_selector_widget.dart diff --git a/assets/icons/refresh_status_icon.svg b/assets/icons/refresh_status_icon.svg new file mode 100644 index 00000000..eb375bd8 --- /dev/null +++ b/assets/icons/refresh_status_icon.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/lib/pages/device_managment/all_devices/models/devices_model.dart b/lib/pages/device_managment/all_devices/models/devices_model.dart index 485cb0ec..de1b7632 100644 --- a/lib/pages/device_managment/all_devices/models/devices_model.dart +++ b/lib/pages/device_managment/all_devices/models/devices_model.dart @@ -12,6 +12,7 @@ import 'package:syncrow_web/pages/routines/models/gang_switches/one_gang_switch/ import 'package:syncrow_web/pages/routines/models/gang_switches/three_gang_switch/three_gang_switch.dart'; import 'package:syncrow_web/pages/routines/models/gang_switches/two_gang_switch/two_gang_switch.dart'; import 'package:syncrow_web/pages/routines/models/gateway.dart'; +import 'package:syncrow_web/pages/routines/models/water_heater/water_heater_functions.dart'; import 'package:syncrow_web/pages/routines/models/wps/wps_functions.dart'; import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/ceiling_sensor/ceiling_sensor_helper.dart'; import 'package:syncrow_web/utils/constants/assets.dart'; @@ -358,7 +359,10 @@ SOS case 'NCPS': return [ FlushPresenceDelayFunction( - deviceId: uuid ?? '', deviceName: name ?? '', type: 'IF',), + deviceId: uuid ?? '', + deviceName: name ?? '', + type: 'IF', + ), FlushIlluminanceFunction( deviceId: uuid ?? '', deviceName: name ?? '', type: 'IF'), @@ -378,6 +382,17 @@ SOS FlushTriggerLevelFunction( deviceId: uuid ?? '', deviceName: name ?? '', type: 'THEN'), ]; + case 'WH': + return [ + WHRestartStatusFunction( + deviceId: uuid ?? '', deviceName: name ?? '', type: 'IF'), + WHSwitchFunction( + deviceId: uuid ?? '', deviceName: name ?? '', type: 'BOTH'), + TimerConfirmTimeFunction( + deviceId: uuid ?? '', deviceName: name ?? '', type: 'BOTH'), + BacklightFunction( + deviceId: uuid ?? '', deviceName: name ?? '', type: 'IF'), + ]; default: return []; diff --git a/lib/pages/routines/helper/dialog_helper/device_dialog_helper.dart b/lib/pages/routines/helper/dialog_helper/device_dialog_helper.dart index a94a312b..bdba5797 100644 --- a/lib/pages/routines/helper/dialog_helper/device_dialog_helper.dart +++ b/lib/pages/routines/helper/dialog_helper/device_dialog_helper.dart @@ -10,6 +10,7 @@ import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/one_gang_swit import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/three_gang_switch_dialog.dart'; import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/two_gang_switch_dialog.dart'; import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/wall_sensor/wall_presence_sensor.dart'; +import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/water_heater/water_heater_presence_sensor.dart'; class DeviceDialogHelper { static Future?> showDeviceDialog({ @@ -126,6 +127,15 @@ class DeviceDialogHelper { dialogType: dialogType, device: data['device'], ); + case 'WH': + return WaterHeaterDialogRoutines.showWHFunctionsDialog( + context: context, + functions: functions, + uniqueCustomId: data['uniqueCustomId'], + deviceSelectedFunctions: deviceSelectedFunctions, + dialogType: dialogType, + device: data['device'], + ); default: return null; diff --git a/lib/pages/routines/models/water_heater/water_heater_functions.dart b/lib/pages/routines/models/water_heater/water_heater_functions.dart new file mode 100644 index 00000000..571e15f7 --- /dev/null +++ b/lib/pages/routines/models/water_heater/water_heater_functions.dart @@ -0,0 +1,134 @@ +import 'package:syncrow_web/pages/device_managment/water_heater/models/water_heater_status_model.dart'; +import 'package:syncrow_web/pages/routines/models/device_functions.dart'; +import 'package:syncrow_web/pages/routines/models/water_heater/water_heater_operational_value.dart'; +import 'package:syncrow_web/utils/constants/assets.dart'; + +abstract class WaterHeaterFunctions + extends DeviceFunction { + final String type; + + WaterHeaterFunctions({ + required super.deviceId, + required super.deviceName, + required super.code, + required super.operationName, + required super.icon, + required this.type, + }); + + List getOperationalValues(); +} + +class WHRestartStatusFunction extends WaterHeaterFunctions { + final int min; + WHRestartStatusFunction({ + required super.deviceId, + required super.deviceName, + required super.type, + }) : min = 0, + super( + code: 'relay_status', + operationName: 'Restart Status', + icon: Assets.refreshStatusIcon, + ); + + @override + List getOperationalValues() { + return [ + WaterHeaterOperationalValue( + icon: Assets.assetsAcPowerOFF, + description: 'Power OFF', + value: "off", + ), + WaterHeaterOperationalValue( + icon: Assets.assetsAcPower, + description: 'Power ON', + value: 'on', + ), + WaterHeaterOperationalValue( + icon: Assets.refreshStatusIcon, + description: "Restart Memory", + value: 'memory', + ), + ]; + } +} + +class WHSwitchFunction extends WaterHeaterFunctions { + final int min; + WHSwitchFunction({ + required super.deviceId, + required super.deviceName, + required super.type, + }) : min = 0, + super( + code: 'switch_1', + operationName: 'Switch', + icon: Assets.assetsAcPower, + ); + + @override + List getOperationalValues() { + return [ + WaterHeaterOperationalValue( + icon: Assets.assetsAcPower, + description: 'ON', + value: true, + ), + WaterHeaterOperationalValue( + icon: Assets.assetsAcPowerOFF, + description: 'OFF', + value: false, + ), + ]; + } +} + +class TimerConfirmTimeFunction extends WaterHeaterFunctions { + TimerConfirmTimeFunction({ + required super.deviceId, + required super.deviceName, + required super.type, + }) : super( + code: 'countdown_1', + operationName: 'Timer', + icon: Assets.targetConfirmTimeIcon, + ); + + @override + List getOperationalValues() { + final values = []; + + return values; + } +} + +class BacklightFunction extends WaterHeaterFunctions { + final int min; + BacklightFunction({ + required super.deviceId, + required super.deviceName, + required super.type, + }) : min = 0, + super( + code: 'switch_backlight', + operationName: 'Backlight', + icon: Assets.indicator, + ); + + @override + List getOperationalValues() { + return [ + WaterHeaterOperationalValue( + icon: Assets.assetsAcPower, + description: 'ON', + value: true, + ), + WaterHeaterOperationalValue( + icon: Assets.assetsAcPowerOFF, + description: 'OFF', + value: false, + ), + ]; + } +} diff --git a/lib/pages/routines/models/water_heater/water_heater_operational_value.dart b/lib/pages/routines/models/water_heater/water_heater_operational_value.dart new file mode 100644 index 00000000..dd1e5157 --- /dev/null +++ b/lib/pages/routines/models/water_heater/water_heater_operational_value.dart @@ -0,0 +1,11 @@ +class WaterHeaterOperationalValue { + final String icon; + final String description; + final dynamic value; + + WaterHeaterOperationalValue({ + required this.icon, + required this.description, + required this.value, + }); +} diff --git a/lib/pages/routines/widgets/if_container.dart b/lib/pages/routines/widgets/if_container.dart index 884c8d10..7d0838ad 100644 --- a/lib/pages/routines/widgets/if_container.dart +++ b/lib/pages/routines/widgets/if_container.dart @@ -76,7 +76,8 @@ class IfContainer extends StatelessWidget { 'WPS', 'GW', 'CPS', - 'NCPS' + 'NCPS', + 'WH', ].contains(state.ifItems[index] ['productType'])) { @@ -136,7 +137,7 @@ class IfContainer extends StatelessWidget { context .read() .add(AddToIfContainer(mutableData, false)); - } else if (!['AC', '1G', '2G', '3G', 'WPS', 'GW', 'CPS', 'NCPS'] + } else if (!['AC', '1G', '2G', '3G', 'WPS', 'GW', 'CPS', 'NCPS','WH'] .contains(mutableData['productType'])) { context .read() diff --git a/lib/pages/routines/widgets/routine_devices.dart b/lib/pages/routines/widgets/routine_devices.dart index 9192b422..11a52ba7 100644 --- a/lib/pages/routines/widgets/routine_devices.dart +++ b/lib/pages/routines/widgets/routine_devices.dart @@ -25,7 +25,8 @@ class _RoutineDevicesState extends State { 'WPS', 'GW', 'CPS', - 'NCPS' + 'NCPS', + 'WH', }; @override diff --git a/lib/pages/routines/widgets/routine_dialogs/flush_presence_sensor/flush_operational_values_list.dart b/lib/pages/routines/widgets/routine_dialogs/flush_presence_sensor/flush_operational_values_list.dart index 1a96cfbb..3e618c35 100644 --- a/lib/pages/routines/widgets/routine_dialogs/flush_presence_sensor/flush_operational_values_list.dart +++ b/lib/pages/routines/widgets/routine_dialogs/flush_presence_sensor/flush_operational_values_list.dart @@ -1,11 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:flutter_svg/flutter_svg.dart'; import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_model.dart'; -import 'package:syncrow_web/pages/routines/bloc/functions_bloc/functions_bloc_bloc.dart'; -import 'package:syncrow_web/pages/routines/models/device_functions.dart'; import 'package:syncrow_web/pages/routines/models/flush/flush_operational_value.dart'; -import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/wall_sensor/time_wheel.dart'; class FlushOperationalValuesList extends StatelessWidget { final List values; diff --git a/lib/pages/routines/widgets/routine_dialogs/water_heater/water_heater_operational_values_list.dart b/lib/pages/routines/widgets/routine_dialogs/water_heater/water_heater_operational_values_list.dart new file mode 100644 index 00000000..4042df36 --- /dev/null +++ b/lib/pages/routines/widgets/routine_dialogs/water_heater/water_heater_operational_values_list.dart @@ -0,0 +1,65 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_model.dart'; +import 'package:syncrow_web/pages/routines/models/water_heater/water_heater_operational_value.dart'; + +class WaterHeaterOperationalValuesList extends StatelessWidget { + final List values; + final dynamic selectedValue; + final AllDevicesModel? device; + final String operationName; + final String selectCode; + final ValueChanged onSelect; + const WaterHeaterOperationalValuesList({ + required this.values, + required this.selectedValue, + required this.device, + required this.operationName, + required this.selectCode, + required this.onSelect, + super.key, + }); + + @override + Widget build(BuildContext context) { + return ListView.builder( + padding: const EdgeInsets.all(20), + itemCount: values.length, + itemBuilder: (context, index) => _buildValueItem(context, values[index]), + ); + } + + Widget _buildValueItem( + BuildContext context, WaterHeaterOperationalValue value) { + return Padding( + padding: const EdgeInsets.all(8.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + SvgPicture.asset( + value.icon, + width: 24, + height: 24, + ), + Expanded(child: _buildValueDescription(value)), + _buildValueRadio(context, value), + ], + ), + ); + } + + Widget _buildValueDescription(WaterHeaterOperationalValue value) { + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 8.0), + child: Text(value.description), + ); + } + + Widget _buildValueRadio(context, WaterHeaterOperationalValue value) { + return Radio( + value: value.value, + groupValue: selectedValue, + onChanged: (_) => onSelect(value)); + } + +} diff --git a/lib/pages/routines/widgets/routine_dialogs/water_heater/water_heater_presence_sensor.dart b/lib/pages/routines/widgets/routine_dialogs/water_heater/water_heater_presence_sensor.dart new file mode 100644 index 00000000..8721613e --- /dev/null +++ b/lib/pages/routines/widgets/routine_dialogs/water_heater/water_heater_presence_sensor.dart @@ -0,0 +1,203 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_model.dart'; +import 'package:syncrow_web/pages/routines/bloc/functions_bloc/functions_bloc_bloc.dart'; +import 'package:syncrow_web/pages/routines/bloc/routine_bloc/routine_bloc.dart'; +import 'package:syncrow_web/pages/routines/models/device_functions.dart'; +import 'package:syncrow_web/pages/routines/models/water_heater/water_heater_functions.dart'; +import 'package:syncrow_web/pages/routines/widgets/dialog_footer.dart'; +import 'package:syncrow_web/pages/routines/widgets/dialog_header.dart'; +import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/water_heater/water_heater_value_selector_widget.dart'; +import 'package:syncrow_web/utils/color_manager.dart'; +import 'package:syncrow_web/utils/extension/build_context_x.dart'; + +class WaterHeaterDialogRoutines extends StatefulWidget { + final List functions; + final AllDevicesModel? device; + final List? deviceSelectedFunctions; + final String? uniqueCustomId; + final String dialogType; + + const WaterHeaterDialogRoutines({ + super.key, + required this.functions, + this.device, + this.deviceSelectedFunctions, + this.uniqueCustomId, + required this.dialogType, + }); + + static Future?> showWHFunctionsDialog({ + required BuildContext context, + required List functions, + AllDevicesModel? device, + List? deviceSelectedFunctions, + String? uniqueCustomId, + required String dialogType, + }) async { + return showDialog?>( + context: context, + builder: (context) => WaterHeaterDialogRoutines( + functions: functions, + device: device, + deviceSelectedFunctions: deviceSelectedFunctions, + uniqueCustomId: uniqueCustomId, + dialogType: dialogType, + ), + ); + } + + @override + State createState() => + _WaterHeaterDialogRoutinesState(); +} + +class _WaterHeaterDialogRoutinesState extends State { + late final List _waterHeaterFunctions; + @override + void initState() { + super.initState(); + _waterHeaterFunctions = + widget.functions.whereType().where((function) { + if (widget.dialogType == 'THEN') { + return function.type == 'THEN' || function.type == 'BOTH'; + } + return function.type == 'IF' || function.type == 'BOTH'; + }).toList(); + } + + @override + Widget build(BuildContext context) { + return BlocProvider( + create: (_) => FunctionBloc() + ..add(InitializeFunctions(widget.deviceSelectedFunctions ?? [])), + child: _buildDialogContent(), + ); + } + + Widget _buildDialogContent() { + return AlertDialog( + contentPadding: EdgeInsets.zero, + content: BlocBuilder( + builder: (context, state) { + final selectedFunction = state.selectedFunction; + return Container( + width: selectedFunction != null ? 600 : 360, + height: 450, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(20), + ), + padding: const EdgeInsets.only(top: 20), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + const DialogHeader('Water Heater Condition'), + Expanded(child: _buildMainContent(context, state)), + _buildDialogFooter(context, state), + ], + ), + ); + }, + ), + ); + } + + Widget _buildMainContent(BuildContext context, FunctionBlocState state) { + return Row( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + _buildFunctionList(context), + if (state.selectedFunction != null) _buildValueSelector(context, state), + ], + ); + } + + Widget _buildFunctionList(BuildContext context) { + return SizedBox( + width: 360, + child: ListView.separated( + shrinkWrap: false, + physics: const AlwaysScrollableScrollPhysics(), + itemCount: _waterHeaterFunctions.length, + separatorBuilder: (context, index) => const Padding( + padding: EdgeInsets.symmetric(horizontal: 40.0), + child: Divider(color: ColorsManager.dividerColor), + ), + itemBuilder: (context, index) { + final function = _waterHeaterFunctions[index]; + return ListTile( + leading: SvgPicture.asset( + function.icon, + width: 24, + height: 24, + placeholderBuilder: (context) => const SizedBox( + width: 24, + height: 24, + ), + ), + title: Text( + function.operationName, + style: context.textTheme.bodyMedium, + ), + trailing: const Icon( + Icons.arrow_forward_ios, + size: 16, + color: ColorsManager.textGray, + ), + onTap: () => context.read().add( + SelectFunction( + functionCode: function.code, + operationName: function.operationName, + ), + ), + ); + }, + ), + ); + } + + Widget _buildValueSelector(BuildContext context, FunctionBlocState state) { + final selectedFunction = state.selectedFunction ?? ''; + final functionData = state.addedFunctions.firstWhere( + (f) => f.functionCode == selectedFunction, + orElse: () => DeviceFunctionData( + entityId: '', + functionCode: selectedFunction, + operationName: state.selectedOperationName ?? '', + value: null, + ), + ); + + return Expanded( + child: WaterHeaterValueSelectorWidget( + selectedFunction: selectedFunction, + functionData: functionData, + whFunctions: _waterHeaterFunctions, + device: widget.device, + ), + ); + } + + Widget _buildDialogFooter(BuildContext context, FunctionBlocState state) { + return DialogFooter( + onCancel: () => Navigator.pop(context), + onConfirm: state.addedFunctions.isNotEmpty + ? () { + context.read().add( + AddFunctionToRoutine( + state.addedFunctions, + widget.uniqueCustomId!, + ), + ); + Navigator.pop( + context, + {'deviceId': widget.functions.first.deviceId}, + ); + } + : null, + isConfirmEnabled: state.selectedFunction != null, + ); + } +} diff --git a/lib/pages/routines/widgets/routine_dialogs/water_heater/water_heater_value_selector_widget.dart b/lib/pages/routines/widgets/routine_dialogs/water_heater/water_heater_value_selector_widget.dart new file mode 100644 index 00000000..9d27a53f --- /dev/null +++ b/lib/pages/routines/widgets/routine_dialogs/water_heater/water_heater_value_selector_widget.dart @@ -0,0 +1,192 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_model.dart'; +import 'package:syncrow_web/pages/routines/bloc/functions_bloc/functions_bloc_bloc.dart'; +import 'package:syncrow_web/pages/routines/helper/duration_format_helper.dart'; +import 'package:syncrow_web/pages/routines/models/device_functions.dart'; +import 'package:syncrow_web/pages/routines/models/gang_switches/switch_operational_value.dart'; +import 'package:syncrow_web/pages/routines/models/water_heater/water_heater_functions.dart'; +import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/water_heater/water_heater_operational_values_list.dart'; +import 'package:syncrow_web/utils/color_manager.dart'; +import 'package:syncrow_web/utils/extension/build_context_x.dart'; + +class WaterHeaterValueSelectorWidget extends StatelessWidget { + final String selectedFunction; + final DeviceFunctionData functionData; + final List whFunctions; + final AllDevicesModel? device; + + const WaterHeaterValueSelectorWidget({ + required this.selectedFunction, + required this.functionData, + required this.whFunctions, + required this.device, + super.key, + }); + + @override + Widget build(BuildContext context) { + final selectedFn = whFunctions.firstWhere( + (f) => f.code == selectedFunction, + orElse: () => throw Exception('Function $selectedFunction not found'), + ); + if (selectedFunction == 'countdown_1') { + return Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + _buildConditionToggle( + context, + functionData.condition, + selectedFunction, + device, + selectedFn.operationName, + functionData, + ), + _buildCountDownDisplay( + context, + functionData.value, + device, + selectedFn.operationName, + functionData, + selectedFunction, + ), + _buildCountDownSlider( + context, + functionData.value, + device, + selectedFn.operationName, + functionData, + selectedFunction, + ), + const SizedBox(height: 10), + ], + ); + } + + return WaterHeaterOperationalValuesList( + values: selectedFn.getOperationalValues(), + selectedValue: functionData.value, + device: device, + operationName: selectedFn.operationName, + selectCode: selectedFunction, + onSelect: (selectedValue) async { + context.read().add( + AddFunction( + functionData: DeviceFunctionData( + entityId: device?.uuid ?? '', + functionCode: selectedFunction, + operationName: functionData.operationName, + value: selectedValue.value, + condition: functionData.condition, + ), + ), + ); + }, + ); + } + + static Widget _buildCountDownDisplay( + BuildContext context, + dynamic initialValue, + AllDevicesModel? device, + String operationName, + DeviceFunctionData? selectedFunctionData, + String selectCode) { + return Container( + padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10), + decoration: BoxDecoration( + color: ColorsManager.primaryColorWithOpacity.withOpacity(0.1), + borderRadius: BorderRadius.circular(10), + ), + child: Text( + DurationFormatMixin.formatDuration(initialValue?.toInt() ?? 0), + style: context.textTheme.headlineMedium!.copyWith( + color: ColorsManager.primaryColorWithOpacity, + ), + ), + ); + } + + static Widget _buildCountDownSlider( + BuildContext context, + dynamic initialValue, + AllDevicesModel? device, + String operationName, + DeviceFunctionData? selectedFunctionData, + String selectCode, + ) { + const twelveHoursInSeconds = 43200.0; + final operationalValues = SwitchOperationalValue( + icon: '', + description: "sec", + value: 0.0, + minValue: 0, + maxValue: twelveHoursInSeconds, + stepValue: 1, + ); + return Slider( + value: (initialValue ?? 0).toDouble(), + min: operationalValues.minValue?.toDouble() ?? 0.0, + max: operationalValues.maxValue?.toDouble() ?? 0.0, + divisions: (((operationalValues.maxValue ?? 0) - + (operationalValues.minValue ?? 0)) / + (operationalValues.stepValue ?? 1)) + .round(), + onChanged: (value) { + context.read().add( + AddFunction( + functionData: DeviceFunctionData( + entityId: device?.uuid ?? '', + functionCode: selectCode, + operationName: operationName, + value: value, + condition: selectedFunctionData?.condition, + valueDescription: selectedFunctionData?.valueDescription, + ), + ), + ); + }, + ); + } + + static Widget _buildConditionToggle( + BuildContext context, + String? currentCondition, + String selectCode, + AllDevicesModel? device, + String operationName, + DeviceFunctionData? selectedFunctionData, + ) { + final conditions = ["<", "==", ">"]; + + return ToggleButtons( + onPressed: (int index) { + context.read().add( + AddFunction( + functionData: DeviceFunctionData( + entityId: device?.uuid ?? '', + functionCode: selectCode, + operationName: operationName, + condition: conditions[index], + value: selectedFunctionData?.value ?? 0, + valueDescription: selectedFunctionData?.valueDescription, + ), + ), + ); + }, + borderRadius: const BorderRadius.all(Radius.circular(8)), + selectedBorderColor: ColorsManager.primaryColorWithOpacity, + selectedColor: Colors.white, + fillColor: ColorsManager.primaryColorWithOpacity, + color: ColorsManager.primaryColorWithOpacity, + constraints: const BoxConstraints( + minHeight: 40.0, + minWidth: 40.0, + ), + isSelected: + conditions.map((c) => c == (currentCondition ?? "==")).toList(), + children: conditions.map((c) => Text(c)).toList(), + ); + } +} diff --git a/lib/pages/routines/widgets/then_container.dart b/lib/pages/routines/widgets/then_container.dart index 1e7e1382..0324d562 100644 --- a/lib/pages/routines/widgets/then_container.dart +++ b/lib/pages/routines/widgets/then_container.dart @@ -116,7 +116,8 @@ class ThenContainer extends StatelessWidget { 'WPS', 'CPS', "GW", - "NCPS" + "NCPS", + 'WH', ].contains(state.thenItems[index] ['productType'])) { context.read().add( @@ -232,8 +233,17 @@ class ThenContainer extends StatelessWidget { dialogType: "THEN"); if (result != null) { context.read().add(AddToThenContainer(mutableData)); - } else if (!['AC', '1G', '2G', '3G', 'WPS', 'GW', 'CPS', "NCPS"] - .contains(mutableData['productType'])) { + } else if (![ + 'AC', + '1G', + '2G', + '3G', + 'WPS', + 'GW', + 'CPS', + "NCPS", + "WH" + ].contains(mutableData['productType'])) { context.read().add(AddToThenContainer(mutableData)); } }, diff --git a/lib/utils/constants/assets.dart b/lib/utils/constants/assets.dart index f857a357..a1d782f2 100644 --- a/lib/utils/constants/assets.dart +++ b/lib/utils/constants/assets.dart @@ -481,4 +481,5 @@ class Assets { static const String indentLevelIcon = 'assets/icons/indent_level_icon.svg'; static const String triggerLevelIcon = 'assets/icons/trigger_level_icon.svg'; static const String blankCalendar = 'assets/icons/blank_calendar.svg'; + static const String refreshStatusIcon = 'assets/icons/refresh_status_icon.svg'; }