diff --git a/assets/icons/active_bell.svg b/assets/icons/active_bell.svg new file mode 100644 index 00000000..3887ead5 --- /dev/null +++ b/assets/icons/active_bell.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/icons/gear.svg b/assets/icons/gear.svg new file mode 100644 index 00000000..02dbab04 --- /dev/null +++ b/assets/icons/gear.svg @@ -0,0 +1,3 @@ + + + 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 deac5b2a..2ea085c5 100644 --- a/lib/pages/device_managment/all_devices/models/devices_model.dart +++ b/lib/pages/device_managment/all_devices/models/devices_model.dart @@ -8,6 +8,7 @@ import 'package:syncrow_web/pages/routines/models/device_functions.dart'; import 'package:syncrow_web/pages/routines/models/gang_switches/one_gang_switch/one_gang_switch.dart'; 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/wps/wps_functions.dart'; import 'package:syncrow_web/utils/constants/assets.dart'; import 'package:syncrow_web/utils/enum/device_types.dart'; @@ -318,6 +319,24 @@ SOS deviceId: uuid ?? '', deviceName: name ?? '', type: 'THEN'), ]; + case 'GW': + return [ + GatewaySwitchAlarmSound( + deviceId: uuid ?? '', + deviceName: name ?? '', + type: 'BOTH', + ), + GatewayMasterState( + deviceId: uuid ?? '', + deviceName: name ?? '', + type: 'BOTH', + ), + GatewayFactoryReset( + deviceId: uuid ?? '', + deviceName: name ?? '', + type: 'BOTH', + ), + ]; default: return []; } diff --git a/lib/pages/device_managment/gateway/model/gateway_model.dart b/lib/pages/device_managment/gateway/model/gateway_model.dart new file mode 100644 index 00000000..a522aa00 --- /dev/null +++ b/lib/pages/device_managment/gateway/model/gateway_model.dart @@ -0,0 +1,49 @@ +class GatewayModel { + final String uuid; + final bool switchAlarmSound; + final String masterState; + final bool factoryReset; + final String alarmActive; + + GatewayModel({ + required this.uuid, + required this.switchAlarmSound, + required this.masterState, + required this.factoryReset, + required this.alarmActive, + }); + + factory GatewayModel.fromJson(Map json) { + final status = json['status'] as List? ?? []; + + bool? switchAlarmSound; + String? masterState; + bool? factoryReset; + String? alarmActive; + + for (final item in status) { + switch (item['code']) { + case 'switch_alarm_sound': + switchAlarmSound = item['value'] as bool; + break; + case 'master_state': + masterState = item['value'] as String; + break; + case 'factory_reset': + factoryReset = item['value'] as bool; + break; + case 'alarm_active': + alarmActive = item['value'] as String; + break; + } + } + + return GatewayModel( + uuid: json['uuid'] as String? ?? '', + switchAlarmSound: switchAlarmSound ?? false, + masterState: masterState ?? '', + factoryReset: factoryReset ?? false, + alarmActive: alarmActive ?? '', + ); + } +} 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 96919364..8f7cd1c5 100644 --- a/lib/pages/routines/helper/dialog_helper/device_dialog_helper.dart +++ b/lib/pages/routines/helper/dialog_helper/device_dialog_helper.dart @@ -1,11 +1,12 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_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/widgets/routine_dialogs/ac_dialog.dart'; +import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/gateway/gateway_helper.dart'; import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/one_gang_switch_dialog.dart'; 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/models/device_functions.dart'; import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/wall_sensor/wall_presence_sensor.dart'; class DeviceDialogHelper { @@ -49,7 +50,6 @@ class DeviceDialogHelper { final deviceSelectedFunctions = routineBloc.state.selectedFunctions[data['uniqueCustomId']] ?? []; - switch (productType) { case 'AC': return ACHelper.showACFunctionsDialog( @@ -98,6 +98,15 @@ class DeviceDialogHelper { deviceSelectedFunctions: deviceSelectedFunctions, uniqueCustomId: data['uniqueCustomId'], removeComparetors: removeComparetors); + case 'GW': + return GatewayHelper.showGatewayFunctionsDialog( + context: context, + functions: functions, + uniqueCustomId: data['uniqueCustomId'], + deviceSelectedFunctions: deviceSelectedFunctions, + device: data['device'], + ); + default: return null; } diff --git a/lib/pages/routines/models/gateway.dart b/lib/pages/routines/models/gateway.dart new file mode 100644 index 00000000..b1a70d2e --- /dev/null +++ b/lib/pages/routines/models/gateway.dart @@ -0,0 +1,111 @@ +import 'package:syncrow_web/pages/routines/models/device_functions.dart'; +import 'package:syncrow_web/utils/constants/assets.dart'; + +class GatewayOperationalValue { + final String icon; + final String description; + final dynamic value; + + GatewayOperationalValue({ + required this.icon, + required this.description, + required this.value, + }); +} + +abstract class GatewayFunctions extends DeviceFunction { + final String type; + + GatewayFunctions({ + required super.deviceId, + required super.deviceName, + required super.code, + required super.operationName, + required super.icon, + required this.type, + }); + + List getOperationalValues(); +} + +final class GatewaySwitchAlarmSound extends GatewayFunctions { + GatewaySwitchAlarmSound({ + required super.deviceId, + required super.deviceName, + required super.type, + }) : super( + code: 'switch_alarm_sound', + operationName: 'Switch Alarm Sound', + icon: Assets.activeBell, + ); + + @override + List getOperationalValues() => [ + GatewayOperationalValue( + icon: Assets.assetsAcPower, + description: "ON", + value: true, + ), + GatewayOperationalValue( + icon: Assets.assetsAcPowerOFF, + description: "OFF", + value: false, + ), + ]; +} + +final class GatewayMasterState extends GatewayFunctions { + GatewayMasterState({ + required super.deviceId, + required super.deviceName, + required super.type, + }) : super( + code: 'master_state', + operationName: 'Master State', + icon: Assets.gear, + ); + + @override + List getOperationalValues() { + return [ + GatewayOperationalValue( + icon: Assets.assetsAcPower, + description: "Normal", + value: 'normal', + ), + GatewayOperationalValue( + icon: Assets.assetsAcPowerOFF, + description: "Alarm", + value: 'alarm', + ), + ]; + } +} + +final class GatewayFactoryReset extends GatewayFunctions { + GatewayFactoryReset({ + required super.deviceId, + required super.deviceName, + required super.type, + }) : super( + code: 'factory_reset', + operationName: 'Factory Reset', + icon: Assets.factoryReset, + ); + + @override + List getOperationalValues() { + return [ + GatewayOperationalValue( + icon: Assets.assetsAcPower, + description: "ON", + value: true, + ), + GatewayOperationalValue( + icon: Assets.assetsAcPowerOFF, + description: "OFF", + value: false, + ), + ]; + } +} diff --git a/lib/pages/routines/widgets/if_container.dart b/lib/pages/routines/widgets/if_container.dart index eebf3fb7..b65e99c7 100644 --- a/lib/pages/routines/widgets/if_container.dart +++ b/lib/pages/routines/widgets/if_container.dart @@ -72,6 +72,7 @@ class IfContainer extends StatelessWidget { '2G', '3G', 'WPS' + 'GW', ].contains( state.ifItems[index]['productType'])) { context.read().add( @@ -129,7 +130,7 @@ class IfContainer extends StatelessWidget { context .read() .add(AddToIfContainer(mutableData, false)); - } else if (!['AC', '1G', '2G', '3G', 'WPS'] + } else if (!['AC', '1G', '2G', '3G', 'WPS', 'GW'] .contains(mutableData['productType'])) { context .read() diff --git a/lib/pages/routines/widgets/main_routine_view/fetch_routine_scenes_automation.dart b/lib/pages/routines/widgets/main_routine_view/fetch_routine_scenes_automation.dart index 0a22208c..92a837b6 100644 --- a/lib/pages/routines/widgets/main_routine_view/fetch_routine_scenes_automation.dart +++ b/lib/pages/routines/widgets/main_routine_view/fetch_routine_scenes_automation.dart @@ -183,7 +183,7 @@ class _FetchRoutineScenesState extends State state.automations[index].id, cardType: 'automations', spaceName: - state.scenes[index].spaceName, + state.automations[index].spaceName, onTap: () { BlocProvider.of(context) .add( diff --git a/lib/pages/routines/widgets/routine_devices.dart b/lib/pages/routines/widgets/routine_devices.dart index 2d3f7236..84fd44c0 100644 --- a/lib/pages/routines/widgets/routine_devices.dart +++ b/lib/pages/routines/widgets/routine_devices.dart @@ -1,6 +1,5 @@ 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/routine_bloc/routine_bloc.dart'; import 'package:syncrow_web/pages/routines/widgets/dragable_card.dart'; @@ -18,6 +17,8 @@ class _RoutineDevicesState extends State { context.read().add(FetchDevicesInRoutine()); } + static const _allowedProductTypes = {'AC', '1G', '2G', '3G', 'WPS', 'GW'}; + @override Widget build(BuildContext context) { return BlocBuilder( @@ -32,13 +33,8 @@ class _RoutineDevicesState extends State { } }); - List deviceList = state.devices - .where((device) => - device.productType == 'AC' || - device.productType == '1G' || - device.productType == '2G' || - device.productType == '3G' || - device.productType == 'WPS') + final deviceList = state.devices + .where((device) => _allowedProductTypes.contains(device.productType)) .toList(); return Wrap( @@ -46,37 +42,32 @@ class _RoutineDevicesState extends State { runSpacing: 10, children: deviceList.asMap().entries.map((entry) { final device = entry.value; + + final deviceData = { + 'device': device, + 'imagePath': device.getDefaultIcon(device.productType), + 'title': device.name ?? '', + 'deviceId': device.uuid, + 'productType': device.productType, + 'functions': device.functions, + 'uniqueCustomId': '', + }; + if (state.searchText != null && state.searchText!.isNotEmpty) { return device.name! .toLowerCase() .contains(state.searchText!.toLowerCase()) ? DraggableCard( - imagePath: device.getDefaultIcon(device.productType), - title: device.name ?? '', - deviceData: { - 'device': device, - 'imagePath': device.getDefaultIcon(device.productType), - 'title': device.name ?? '', - 'deviceId': device.uuid, - 'productType': device.productType, - 'functions': device.functions, - 'uniqueCustomId': '', - }, + imagePath: deviceData['imagePath'] as String, + title: deviceData['title'] as String, + deviceData: deviceData, ) - : Container(); + : const SizedBox.shrink(); } else { return DraggableCard( - imagePath: device.getDefaultIcon(device.productType), - title: device.name ?? '', - deviceData: { - 'device': device, - 'imagePath': device.getDefaultIcon(device.productType), - 'title': device.name ?? '', - 'deviceId': device.uuid, - 'productType': device.productType, - 'functions': device.functions, - 'uniqueCustomId': '', - }, + imagePath: deviceData['imagePath'] as String, + title: deviceData['title'] as String, + deviceData: deviceData, ); } }).toList(), diff --git a/lib/pages/routines/widgets/routine_dialog_function_list_tile.dart b/lib/pages/routines/widgets/routine_dialog_function_list_tile.dart new file mode 100644 index 00000000..3e98a06e --- /dev/null +++ b/lib/pages/routines/widgets/routine_dialog_function_list_tile.dart @@ -0,0 +1,42 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:syncrow_web/utils/color_manager.dart'; +import 'package:syncrow_web/utils/extension/build_context_x.dart'; + +class RoutineDialogFunctionListTile extends StatelessWidget { + const RoutineDialogFunctionListTile({ + super.key, + required this.iconPath, + required this.operationName, + required this.onTap, + }); + + final String iconPath; + final String operationName; + final void Function() onTap; + + @override + Widget build(BuildContext context) { + return ListTile( + leading: SvgPicture.asset( + iconPath, + width: 24, + height: 24, + placeholderBuilder: (context) => const SizedBox( + width: 24, + height: 24, + ), + ), + title: Text( + operationName, + style: context.textTheme.bodyMedium, + ), + trailing: const Icon( + Icons.arrow_forward_ios, + size: 16, + color: ColorsManager.textGray, + ), + onTap: onTap, + ); + } +} diff --git a/lib/pages/routines/widgets/routine_dialog_selection_list_tile.dart b/lib/pages/routines/widgets/routine_dialog_selection_list_tile.dart new file mode 100644 index 00000000..b661e591 --- /dev/null +++ b/lib/pages/routines/widgets/routine_dialog_selection_list_tile.dart @@ -0,0 +1,47 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:syncrow_web/utils/color_manager.dart'; +import 'package:syncrow_web/utils/extension/build_context_x.dart'; + +class RoutineDialogSelectionListTile extends StatelessWidget { + const RoutineDialogSelectionListTile({ + required this.iconPath, + required this.description, + required this.isSelected, + required this.onTap, + super.key, + }); + + final bool isSelected; + final String iconPath; + final String description; + final void Function() onTap; + + @override + Widget build(BuildContext context) { + return ListTile( + leading: SvgPicture.asset( + iconPath, + width: 24, + height: 24, + placeholderBuilder: (context) => Container( + width: 24, + height: 24, + color: Colors.transparent, + ), + ), + title: Text( + description, + style: context.textTheme.bodyMedium, + ), + trailing: Icon( + isSelected ? Icons.radio_button_checked : Icons.radio_button_unchecked, + size: 24, + color: isSelected + ? ColorsManager.primaryColorWithOpacity + : ColorsManager.textGray, + ), + onTap: onTap, + ); + } +} diff --git a/lib/pages/routines/widgets/routine_dialogs/gateway/gateway_dialog.dart b/lib/pages/routines/widgets/routine_dialogs/gateway/gateway_dialog.dart new file mode 100644 index 00000000..364854ce --- /dev/null +++ b/lib/pages/routines/widgets/routine_dialogs/gateway/gateway_dialog.dart @@ -0,0 +1,130 @@ +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/bloc/routine_bloc/routine_bloc.dart'; +import 'package:syncrow_web/pages/routines/models/device_functions.dart'; +import 'package:syncrow_web/pages/routines/models/gateway.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/gateway/gateway_dialog_value_selector.dart'; +import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/gateway/gateway_functions_list.dart'; + +class GatewayDialog extends StatefulWidget { + const GatewayDialog({ + required this.uniqueCustomId, + required this.functions, + required this.deviceSelectedFunctions, + required this.device, + super.key, + }); + + final String? uniqueCustomId; + final List functions; + final List deviceSelectedFunctions; + final AllDevicesModel? device; + + @override + State createState() => _GatewayDialogState(); +} + +class _GatewayDialogState extends State { + late final List _gatewayFunctions; + + @override + void initState() { + super.initState(); + _gatewayFunctions = widget.functions.whereType().toList(); + } + + @override + Widget build(BuildContext context) { + 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('Gateway Conditions'), + Expanded(child: _buildMainContent(context, state)), + _buildDialogFooter(context, state), + ], + ), + ); + }, + ), + ); + } + + Widget _buildMainContent(BuildContext context, FunctionBlocState state) { + final selectedFunction = state.selectedFunction; + final selectedOperationName = state.selectedOperationName; + final selectedFunctionData = state.addedFunctions.firstWhere( + (f) => f.functionCode == selectedFunction, + orElse: () => DeviceFunctionData( + entityId: '', + functionCode: selectedFunction ?? '', + operationName: '', + value: null, + ), + ); + final selectedGatewayFunctions = _gatewayFunctions.firstWhere( + (f) => f.code == selectedFunction, + orElse: () => GatewaySwitchAlarmSound( + deviceId: '', + deviceName: '', + type: '', + ), + ); + final operations = selectedGatewayFunctions.getOperationalValues(); + + return Row( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + GatewayFunctionsList(gatewayFunctions: _gatewayFunctions), + if (state.selectedFunction != null) + Expanded( + child: GatewayDialogValueSelector( + operations: operations, + selectedFunction: selectedFunction ?? '', + selectedFunctionData: selectedFunctionData, + gatewayFunctions: _gatewayFunctions, + operationName: selectedOperationName ?? '', + 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 ?? '-1', + ), + ); + Navigator.pop( + context, + {'deviceId': widget.functions.firstOrNull?.deviceId}, + ); + } + : null, + isConfirmEnabled: state.selectedFunction != null, + ); + } +} diff --git a/lib/pages/routines/widgets/routine_dialogs/gateway/gateway_dialog_value_selector.dart b/lib/pages/routines/widgets/routine_dialogs/gateway/gateway_dialog_value_selector.dart new file mode 100644 index 00000000..392c3012 --- /dev/null +++ b/lib/pages/routines/widgets/routine_dialogs/gateway/gateway_dialog_value_selector.dart @@ -0,0 +1,58 @@ +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/models/device_functions.dart'; +import 'package:syncrow_web/pages/routines/models/gateway.dart'; +import 'package:syncrow_web/pages/routines/widgets/routine_dialog_selection_list_tile.dart'; + +class GatewayDialogValueSelector extends StatelessWidget { + const GatewayDialogValueSelector({ + required this.operations, + required this.selectedFunction, + required this.selectedFunctionData, + required this.gatewayFunctions, + required this.device, + required this.operationName, + super.key, + }); + + final List operations; + final String selectedFunction; + final DeviceFunctionData? selectedFunctionData; + final List gatewayFunctions; + final AllDevicesModel? device; + final String operationName; + + @override + Widget build(BuildContext context) { + return ListView.builder( + itemCount: operations.length, + itemBuilder: (context, index) { + final operation = operations[index]; + final isSelected = selectedFunctionData?.value == operation.value; + return RoutineDialogSelectionListTile( + iconPath: operation.icon, + description: operation.description, + isSelected: isSelected, + onTap: () { + if (!isSelected) { + context.read().add( + AddFunction( + functionData: DeviceFunctionData( + entityId: device?.uuid ?? '', + functionCode: selectedFunction, + operationName: operationName, + value: operation.value, + condition: selectedFunctionData?.condition, + valueDescription: selectedFunctionData?.valueDescription, + ), + ), + ); + } + }, + ); + }, + ); + } +} diff --git a/lib/pages/routines/widgets/routine_dialogs/gateway/gateway_functions_list.dart b/lib/pages/routines/widgets/routine_dialogs/gateway/gateway_functions_list.dart new file mode 100644 index 00000000..6d253dcb --- /dev/null +++ b/lib/pages/routines/widgets/routine_dialogs/gateway/gateway_functions_list.dart @@ -0,0 +1,43 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:syncrow_web/pages/routines/bloc/functions_bloc/functions_bloc_bloc.dart'; +import 'package:syncrow_web/pages/routines/models/gateway.dart'; +import 'package:syncrow_web/pages/routines/widgets/routine_dialog_function_list_tile.dart'; +import 'package:syncrow_web/utils/color_manager.dart'; + +class GatewayFunctionsList extends StatelessWidget { + const GatewayFunctionsList({ + required this.gatewayFunctions, + super.key, + }); + + final List gatewayFunctions; + + @override + Widget build(BuildContext context) { + return SizedBox( + width: 360, + child: ListView.separated( + shrinkWrap: false, + itemCount: gatewayFunctions.length, + separatorBuilder: (context, index) => const Padding( + padding: EdgeInsets.symmetric(horizontal: 40.0), + child: Divider(color: ColorsManager.dividerColor), + ), + itemBuilder: (context, index) { + final function = gatewayFunctions[index]; + return RoutineDialogFunctionListTile( + iconPath: function.icon, + operationName: function.operationName, + onTap: () => context.read().add( + SelectFunction( + functionCode: function.code, + operationName: function.operationName, + ), + ), + ); + }, + ), + ); + } +} diff --git a/lib/pages/routines/widgets/routine_dialogs/gateway/gateway_helper.dart b/lib/pages/routines/widgets/routine_dialogs/gateway/gateway_helper.dart new file mode 100644 index 00000000..9a9351ca --- /dev/null +++ b/lib/pages/routines/widgets/routine_dialogs/gateway/gateway_helper.dart @@ -0,0 +1,34 @@ +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/models/device_functions.dart'; +import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/gateway/gateway_dialog.dart'; + +abstract final class GatewayHelper { + const GatewayHelper._(); + + static Future?> showGatewayFunctionsDialog({ + required BuildContext context, + required List functions, + required String? uniqueCustomId, + required List deviceSelectedFunctions, + required AllDevicesModel? device, + }) async { + return showDialog( + context: context, + builder: (context) => BlocProvider( + create: (context) => FunctionBloc() + ..add( + InitializeFunctions(deviceSelectedFunctions), + ), + child: GatewayDialog( + uniqueCustomId: uniqueCustomId, + functions: functions, + deviceSelectedFunctions: deviceSelectedFunctions, + device: device, + ), + ), + ); + } +} diff --git a/lib/pages/routines/widgets/then_container.dart b/lib/pages/routines/widgets/then_container.dart index a4d0461d..e0828721 100644 --- a/lib/pages/routines/widgets/then_container.dart +++ b/lib/pages/routines/widgets/then_container.dart @@ -113,7 +113,8 @@ class ThenContainer extends StatelessWidget { '1G', '2G', '3G', - 'WPS' + 'WPS', + "GW", ].contains(state.thenItems[index] ['productType'])) { context.read().add( @@ -229,7 +230,7 @@ class ThenContainer extends StatelessWidget { dialogType: "THEN"); if (result != null) { context.read().add(AddToThenContainer(mutableData)); - } else if (!['AC', '1G', '2G', '3G', 'WPS'] + } else if (!['AC', '1G', '2G', '3G', 'WPS', 'GW'] .contains(mutableData['productType'])) { context.read().add(AddToThenContainer(mutableData)); } diff --git a/lib/utils/constants/assets.dart b/lib/utils/constants/assets.dart index e81512ff..d9788ee8 100644 --- a/lib/utils/constants/assets.dart +++ b/lib/utils/constants/assets.dart @@ -426,5 +426,8 @@ class Assets { static const String motionDetectionSensitivityValueIcon = 'assets/icons/motion_detection_sensitivity_value_icon.svg'; static const String presenceTimeIcon = 'assets/icons/presence_time_icon.svg'; static const String IlluminanceIcon = 'assets/icons/Illuminance_icon.svg'; + static const String gear = 'assets/icons/gear.svg'; + static const String activeBell='assets/icons/active_bell.svg'; + }