fixed autoamtion update

This commit is contained in:
ashraf_personal
2024-12-03 00:29:59 +03:00
parent 2f5c5d7da1
commit c58f2eb24e
5 changed files with 399 additions and 306 deletions

View File

@ -44,7 +44,6 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
on<FetchDevicesInRoutine>(_fetchDevices); on<FetchDevicesInRoutine>(_fetchDevices);
on<UpdateScene>(_onUpdateScene); on<UpdateScene>(_onUpdateScene);
on<UpdateAutomation>(_onUpdateAutomation); on<UpdateAutomation>(_onUpdateAutomation);
on<SetAutomationActionExecutor>(_onSetAutomationActionExecutor);
on<TriggerSwitchTabsEvent>(_triggerSwitchTabsEvent); on<TriggerSwitchTabsEvent>(_triggerSwitchTabsEvent);
on<CreateNewRoutineViewEvent>(_createNewRoutineViewEvent); on<CreateNewRoutineViewEvent>(_createNewRoutineViewEvent);
} }
@ -368,21 +367,25 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
} }
final actions = state.thenItems.expand((item) { final actions = state.thenItems.expand((item) {
if (item['type'] == 'tap_to_run') {
return [
AutomationAction(
actionType: 'scene',
entityId: item['deviceId'],
actionExecutor: 'rule_trigger',
),
];
}
final functions = state.selectedFunctions[item['uniqueCustomId']] ?? []; final functions = state.selectedFunctions[item['uniqueCustomId']] ?? [];
return functions.map((function) { return functions.map((function) {
if (function.functionCode == 'automation') { if (function.functionCode == 'automation') {
return AutomationAction( return AutomationAction(
actionType: 'automation', actionType: 'automation',
entityId: function.entityId, entityId: function.entityId,
actionExecutor: function.value, actionExecutor: function.value,
); executorProperty: null,
}
if (function.functionCode == 'tap_to_run') {
return AutomationAction(
actionType: 'scene',
entityId: function.entityId,
actionExecutor: function.value,
); );
} }
@ -698,7 +701,7 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
operationName: 'Automation', operationName: 'Automation',
), ),
); );
emit(state.copyWith(automationActionExecutor: action.actionExecutor)); // emit(state.copyWith(automationActionExecutor: action.actionExecutor));
} else if (action.executorProperty != null && } else if (action.executorProperty != null &&
action.actionExecutor != 'delay') { action.actionExecutor != 'delay') {
if (!updatedFunctions.containsKey(uniqueCustomId)) { if (!updatedFunctions.containsKey(uniqueCustomId)) {
@ -772,160 +775,6 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
} }
} }
Future<void> _onGetAutomationDetails(
GetAutomationDetails event, Emitter<RoutineState> emit) async {
try {
emit(state.copyWith(
isLoading: true,
isUpdate: true,
isTabToRun: false,
automationId: event.automationId,
isAutomation: true,
ifItems: [],
thenItems: [],
));
final automationDetails =
await SceneApi.getAutomationDetails(event.automationId);
final List<Map<String, dynamic>> thenItems;
final List<Map<String, dynamic>> ifItems;
final Map<String, List<DeviceFunctionData>> updatedFunctions =
Map<String, List<DeviceFunctionData>>.from(state.selectedFunctions);
ifItems = automationDetails.conditions?.map((condition) {
late AllDevicesModel? matchingDevice;
for (var device in state.devices) {
if (device.uuid == condition.entityId) {
matchingDevice = device;
break;
}
}
final cardData = {
'entityId': condition.entityId,
'uniqueCustomId': const Uuid().v4(),
'deviceId': condition.expr.statusCode == 'delay'
? 'delay'
: condition.entityId,
'title': condition.expr.statusCode == 'delay'
? 'Delay'
: (matchingDevice?.name ?? 'Device'),
'productType': condition.productType,
'functions': matchingDevice?.functions ?? [],
'imagePath':
matchingDevice?.getDefaultIcon(condition.productType) ?? '',
'device': matchingDevice,
};
final functions = matchingDevice?.functions ?? [];
for (var function in functions) {
if (function.code == condition.expr.statusCode) {
updatedFunctions[cardData['uniqueCustomId'].toString()] = [
DeviceFunctionData(
entityId: condition.entityId,
functionCode: condition.expr.statusCode,
value: condition.expr.statusValue,
operationName: function.operationName,
),
];
break;
}
}
return cardData;
}).toList() ??
[];
// Create then items from actions
thenItems = automationDetails.actions.map((action) {
final matchingDevice = state.devices.firstWhere(
(device) => device.uuid == action.entityId,
orElse: () => AllDevicesModel(
uuid: action.entityId,
name: action.entityId,
productType: action.productType,
),
);
final cardData = {
'entityId': action.entityId,
'uniqueCustomId': const Uuid().v4(),
'deviceId':
action.actionExecutor == 'delay' ? 'delay' : action.entityId,
'title': action.actionExecutor == 'delay'
? 'Delay'
: (matchingDevice.name ?? 'Device'),
'productType': action.productType,
'functions': matchingDevice.functions,
'imagePath': matchingDevice.getDefaultIcon(action.productType),
'device': matchingDevice,
};
if (action.executorProperty != null &&
action.actionExecutor != 'delay') {
final functions = matchingDevice.functions;
final functionCode = action.executorProperty!.functionCode;
for (var function in functions) {
if (function.code == functionCode) {
updatedFunctions[cardData['uniqueCustomId'].toString()] = [
DeviceFunctionData(
entityId: action.entityId,
functionCode: functionCode ?? '',
value: action.executorProperty!.functionValue,
operationName: function.operationName,
),
];
break;
}
}
} else if (action.actionExecutor == 'delay') {
final delayFunction = DelayFunction(
deviceId: action.entityId,
deviceName: 'Delay',
);
updatedFunctions[cardData['uniqueCustomId'].toString()] = [
DeviceFunctionData(
entityId: action.entityId,
functionCode: 'delay',
value: action.executorProperty?.delaySeconds ?? 0,
operationName: delayFunction.operationName,
),
];
} else if (action.actionExecutor == 'rule_disable' ||
action.actionExecutor == 'rule_enable') {
updatedFunctions[cardData['uniqueCustomId'].toString()] = [
DeviceFunctionData(
entityId: action.entityId,
functionCode: 'automation',
value: action.actionExecutor,
operationName: action.name ?? 'Automation',
),
];
}
return cardData;
}).toList();
emit(state.copyWith(
isLoading: false,
routineName: automationDetails.name,
selectedAutomationOperator: automationDetails.decisionExpr,
effectiveTime: automationDetails.effectiveTime,
isAutomation: true,
thenItems: thenItems,
ifItems: ifItems,
selectedFunctions: updatedFunctions,
automationId: automationDetails.automationId,
));
} catch (e) {
emit(state.copyWith(
isLoading: false,
errorMessage: 'Failed to load automation details: $e',
));
}
}
FutureOr<void> _onResetRoutineState( FutureOr<void> _onResetRoutineState(
ResetRoutineState event, Emitter<RoutineState> emit) { ResetRoutineState event, Emitter<RoutineState> emit) {
emit(state.copyWith( emit(state.copyWith(
@ -1087,65 +936,112 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
FutureOr<void> _onUpdateAutomation( FutureOr<void> _onUpdateAutomation(
UpdateAutomation event, Emitter<RoutineState> emit) async { UpdateAutomation event, Emitter<RoutineState> emit) async {
if (_isFirstActionDelay(state.thenItems)) {
emit(state.copyWith(
errorMessage: 'Cannot have delay as the first action',
isLoading: false,
));
return;
}
emit(state.copyWith(isLoading: true));
try { try {
final conditions = state.ifItems if (state.routineName == null || state.routineName!.isEmpty) {
.map((item) { emit(state.copyWith(
final functions = errorMessage: 'Automation name is required',
state.selectedFunctions[item['uniqueCustomId']] ?? []; ));
if (functions.isEmpty) return null; return;
}
if (_isFirstActionDelay(state.thenItems)) {
emit(state.copyWith(
errorMessage: 'Cannot have delay as the first action',
isLoading: false,
));
return;
}
final function = functions.first; if (_isLastActionDelay(state.thenItems)) {
return Condition( emit(state.copyWith(
code: state.ifItems.indexOf(item) + 1, errorMessage: 'Cannot have delay as the last action',
entityId: function.entityId, isLoading: false,
entityType: item['productType'], ));
expr: ConditionExpr( return;
statusCode: function.functionCode, }
statusValue: function.value, emit(state.copyWith(isLoading: true, errorMessage: null));
comparator: function.condition ?? '==',
),
);
})
.whereType<Condition>()
.toList();
final actions = state.thenItems final conditions = state.ifItems.expand((item) {
.map((item) { final functions = state.selectedFunctions[item['uniqueCustomId']] ?? [];
final functions = return functions.map((function) {
state.selectedFunctions[item['uniqueCustomId']] ?? []; return Condition(
if (functions.isEmpty) return null; code: state.selectedFunctions[item['uniqueCustomId']]!.indexOf(
function,
) +
1,
entityId: function.entityId,
entityType: 'device_report',
expr: ConditionExpr(
statusCode: function.functionCode,
comparator: function.condition ?? '==',
statusValue: function.value,
),
);
});
}).toList();
final function = functions.first; if (conditions.isEmpty) {
emit(state.copyWith(
isLoading: false,
errorMessage: 'At least one condition is required',
));
return;
}
final actions = state.thenItems.expand((item) {
if (item['type'] == 'tap_to_run' || item['type'] == 'scene') {
return [
AutomationAction(
actionType: 'scene',
entityId: item['deviceId'],
actionExecutor: 'rule_trigger',
),
];
}
final functions = state.selectedFunctions[item['uniqueCustomId']] ?? [];
return functions.map((function) {
if (function.functionCode == 'automation') {
return AutomationAction( return AutomationAction(
actionType: 'automation', actionType: 'automation',
entityId: function.entityId, entityId: function.entityId,
actionExecutor: function.actionExecutor, actionExecutor: function.value,
executorProperty: null,
);
}
if (item['deviceId'] == 'delay') {
return AutomationAction(
entityId: function.entityId,
actionType: 'automation',
actionExecutor: 'delay',
executorProperty: ExecutorProperty( executorProperty: ExecutorProperty(
functionCode: function.functionCode, delaySeconds: int.tryParse(function.value.toString()) ?? 0,
functionValue: function.value,
delaySeconds: function.functionCode == 'delay'
? (function.value as num).toInt()
: null,
), ),
); );
}) }
.whereType<AutomationAction>()
.toList(); return AutomationAction(
entityId: function.entityId,
actionExecutor: 'device_issue',
actionType: 'automation',
executorProperty: ExecutorProperty(
functionCode: function.functionCode,
functionValue: function.value,
),
);
});
}).toList();
final createAutomationModel = CreateAutomationModel( final createAutomationModel = CreateAutomationModel(
spaceUuid: spaceId, spaceUuid: spaceId,
automationName: state.routineName ?? '', automationName: state.routineName ?? '',
decisionExpr: state.selectedAutomationOperator, decisionExpr: state.selectedAutomationOperator,
effectiveTime: effectiveTime: EffectiveTime(
state.effectiveTime ?? EffectiveTime(start: '', end: '', loops: ''), start: state.effectiveTime?.start ?? '00:00',
end: state.effectiveTime?.end ?? '23:59',
loops: state.effectiveTime?.loops ?? '1111111',
),
conditions: conditions, conditions: conditions,
actions: actions, actions: actions,
); );
@ -1155,8 +1051,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
if (result['success']) { if (result['success']) {
add(ResetRoutineState()); add(ResetRoutineState());
add(const LoadScenes(spaceId, communityId));
add(const LoadAutomation(spaceId)); add(const LoadAutomation(spaceId));
add(const LoadScenes(spaceId, communityId));
} else { } else {
emit(state.copyWith( emit(state.copyWith(
isLoading: false, isLoading: false,
@ -1166,14 +1062,198 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
} catch (e) { } catch (e) {
emit(state.copyWith( emit(state.copyWith(
isLoading: false, isLoading: false,
errorMessage: 'Failed to update automation: $e', errorMessage: 'Something went wrong',
)); ));
} }
} }
FutureOr<void> _onSetAutomationActionExecutor( Future<void> _onGetAutomationDetails(
SetAutomationActionExecutor event, Emitter<RoutineState> emit) { GetAutomationDetails event, Emitter<RoutineState> emit) async {
emit(state.copyWith( try {
automationActionExecutor: event.automationActionExecutor)); emit(state.copyWith(
isLoading: true,
isUpdate: true,
isTabToRun: false,
automationId: event.automationId,
isAutomation: true,
ifItems: [],
thenItems: [],
));
final automationDetails =
await SceneApi.getAutomationDetails(event.automationId);
final Map<String, Map<String, dynamic>> deviceCards = {};
final Map<String, List<DeviceFunctionData>> updatedFunctions =
Map<String, List<DeviceFunctionData>>.from(state.selectedFunctions);
for (RoutineCondition condition in automationDetails.conditions ?? []) {
AllDevicesModel? matchingDevice = state.devices.firstWhere(
(device) => device.uuid == condition.entityId,
orElse: () => AllDevicesModel(
uuid: condition.entityId,
name: condition.entityId,
productType: condition.productType,
),
);
final deviceId = condition.entityId;
if (!deviceCards.containsKey(deviceId)) {
deviceCards[deviceId] = {
'entityId': condition.entityId,
'deviceId': condition.entityId,
'uniqueCustomId': const Uuid().v4(),
'title': matchingDevice.name ?? 'Device',
'productType': condition.productType,
'functions': matchingDevice.functions,
'imagePath': matchingDevice.getDefaultIcon(condition.productType),
'device': matchingDevice,
'type': 'condition',
};
}
final cardData = deviceCards[deviceId]!;
final uniqueCustomId = cardData['uniqueCustomId'].toString();
if (!updatedFunctions.containsKey(uniqueCustomId)) {
updatedFunctions[uniqueCustomId] = [];
}
final functions = matchingDevice.functions;
for (var function in functions) {
if (function.code == condition.expr.statusCode) {
updatedFunctions[uniqueCustomId]!.add(
DeviceFunctionData(
entityId: condition.entityId,
functionCode: condition.expr.statusCode,
value: condition.expr.statusValue,
operationName: function.operationName,
),
);
break;
}
}
}
// Process actions (thenItems)
for (var action in automationDetails.actions) {
AllDevicesModel? matchingDevice = state.devices.firstWhere(
(device) => device.uuid == action.entityId,
orElse: () => AllDevicesModel(
uuid: action.entityId,
name: action.entityId,
productType: action.productType,
),
);
final deviceId = action.actionExecutor == 'delay'
? '${action.entityId}_delay'
: action.entityId;
if (!deviceCards.containsKey(deviceId)) {
deviceCards[deviceId] = {
'entityId': action.entityId,
'deviceId':
action.actionExecutor == 'delay' ? 'delay' : action.entityId,
'uniqueCustomId': const Uuid().v4(),
'title': action.actionExecutor == 'delay'
? 'Delay'
: (action.type == 'scene' || action.type == 'automation')
? action.name
: (matchingDevice.name ?? 'Device'),
'productType': action.productType,
'functions': matchingDevice.functions,
'imagePath': action.actionExecutor == 'delay'
? Assets.delay
: action.type == 'automation'
? Assets.automation
: matchingDevice.getDefaultIcon(action.productType),
'device': matchingDevice,
'type': action.type == 'scene'
? 'scene'
: action.type == 'automation'
? 'automation'
: 'action',
};
}
final cardData = deviceCards[deviceId]!;
final uniqueCustomId = cardData['uniqueCustomId'].toString();
if (!updatedFunctions.containsKey(uniqueCustomId)) {
updatedFunctions[uniqueCustomId] = [];
}
if (action.executorProperty != null &&
action.actionExecutor != 'delay') {
final functions = matchingDevice.functions;
final functionCode = action.executorProperty!.functionCode;
for (var function in functions) {
if (function.code == functionCode) {
updatedFunctions[uniqueCustomId]!.add(
DeviceFunctionData(
entityId: action.entityId,
functionCode: functionCode ?? '',
value: action.executorProperty!.functionValue,
operationName: function.operationName,
),
);
break;
}
}
} else if (action.actionExecutor == 'delay') {
final delayFunction = DelayFunction(
deviceId: action.entityId,
deviceName: 'Delay',
);
updatedFunctions[uniqueCustomId]!.add(
DeviceFunctionData(
entityId: action.entityId,
functionCode: 'delay',
value: action.executorProperty?.delaySeconds ?? 0,
operationName: delayFunction.operationName,
),
);
} else if (action.actionExecutor == 'rule_disable' ||
action.actionExecutor == 'rule_enable') {
updatedFunctions[uniqueCustomId]!.add(
DeviceFunctionData(
entityId: action.entityId,
functionCode: 'automation',
value: action.actionExecutor,
operationName: action.name ?? 'Automation',
),
);
}
}
final ifItems = deviceCards.values
.where((card) => card['type'] == 'condition')
.toList();
final thenItems = deviceCards.values
.where((card) =>
card['type'] == 'action' ||
card['type'] == 'automation' ||
card['type'] == 'scene')
.toList();
emit(state.copyWith(
isLoading: false,
routineName: automationDetails.name,
selectedAutomationOperator: automationDetails.decisionExpr,
effectiveTime: automationDetails.effectiveTime,
isAutomation: true,
thenItems: thenItems,
ifItems: ifItems,
selectedFunctions: updatedFunctions,
automationId: automationDetails.automationId,
));
} catch (e) {
emit(state.copyWith(
isLoading: false,
errorMessage: 'Failed to load automation details: $e',
));
}
} }
} }

View File

@ -22,7 +22,7 @@ class RoutineState extends Equatable {
final String? automationId; final String? automationId;
final bool? isUpdate; final bool? isUpdate;
final List<AllDevicesModel> devices; final List<AllDevicesModel> devices;
final String? automationActionExecutor; // final String? automationActionExecutor;
final bool routineTab; final bool routineTab;
final bool createRoutineView; final bool createRoutineView;
@ -48,7 +48,7 @@ class RoutineState extends Equatable {
this.automationId, this.automationId,
this.isUpdate, this.isUpdate,
this.devices = const [], this.devices = const [],
this.automationActionExecutor, // this.automationActionExecutor,
this.routineTab = false, this.routineTab = false,
this.createRoutineView = false}); this.createRoutineView = false});
@ -73,7 +73,7 @@ class RoutineState extends Equatable {
String? automationId, String? automationId,
bool? isUpdate, bool? isUpdate,
List<AllDevicesModel>? devices, List<AllDevicesModel>? devices,
String? automationActionExecutor, // String? automationActionExecutor,
TextEditingController? nameController, TextEditingController? nameController,
bool? routineTab, bool? routineTab,
bool? createRoutineView, bool? createRoutineView,
@ -88,18 +88,21 @@ class RoutineState extends Equatable {
errorMessage: errorMessage ?? this.errorMessage, errorMessage: errorMessage ?? this.errorMessage,
routineName: routineName ?? this.routineName, routineName: routineName ?? this.routineName,
selectedIcon: selectedIcon ?? this.selectedIcon, selectedIcon: selectedIcon ?? this.selectedIcon,
loadScenesErrorMessage: loadScenesErrorMessage ?? this.loadScenesErrorMessage, loadScenesErrorMessage:
loadAutomationErrorMessage: loadAutomationErrorMessage ?? this.loadAutomationErrorMessage, loadScenesErrorMessage ?? this.loadScenesErrorMessage,
loadAutomationErrorMessage:
loadAutomationErrorMessage ?? this.loadAutomationErrorMessage,
searchText: searchText ?? this.searchText, searchText: searchText ?? this.searchText,
isTabToRun: isTabToRun ?? this.isTabToRun, isTabToRun: isTabToRun ?? this.isTabToRun,
isAutomation: isAutomation ?? this.isAutomation, isAutomation: isAutomation ?? this.isAutomation,
selectedAutomationOperator: selectedAutomationOperator ?? this.selectedAutomationOperator, selectedAutomationOperator:
selectedAutomationOperator ?? this.selectedAutomationOperator,
effectiveTime: effectiveTime ?? this.effectiveTime, effectiveTime: effectiveTime ?? this.effectiveTime,
sceneId: sceneId ?? this.sceneId, sceneId: sceneId ?? this.sceneId,
automationId: automationId ?? this.automationId, automationId: automationId ?? this.automationId,
isUpdate: isUpdate ?? this.isUpdate, isUpdate: isUpdate ?? this.isUpdate,
devices: devices ?? this.devices, devices: devices ?? this.devices,
automationActionExecutor: automationActionExecutor ?? this.automationActionExecutor, // automationActionExecutor: automationActionExecutor ?? this.automationActionExecutor,
routineTab: routineTab ?? this.routineTab, routineTab: routineTab ?? this.routineTab,
createRoutineView: createRoutineView ?? this.createRoutineView); createRoutineView: createRoutineView ?? this.createRoutineView);
} }
@ -126,7 +129,7 @@ class RoutineState extends Equatable {
automationId, automationId,
isUpdate, isUpdate,
devices, devices,
automationActionExecutor, // automationActionExecutor,
routineTab, routineTab,
createRoutineView createRoutineView
]; ];

View File

@ -152,7 +152,8 @@ class AutomationAction {
return { return {
'entityId': entityId, 'entityId': entityId,
'actionExecutor': actionExecutor, 'actionExecutor': actionExecutor,
'executorProperty': executorProperty?.toMap(), if (executorProperty != null)
'executorProperty': executorProperty?.toMap(),
'actionType': actionType 'actionType': actionType
}; };
} }

View File

@ -7,100 +7,106 @@ import 'package:syncrow_web/pages/routiens/widgets/dialog_header.dart';
import 'package:syncrow_web/pages/routiens/widgets/dialog_footer.dart'; import 'package:syncrow_web/pages/routiens/widgets/dialog_footer.dart';
import 'package:syncrow_web/utils/constants/assets.dart'; import 'package:syncrow_web/utils/constants/assets.dart';
class AutomationDialog extends StatelessWidget { class AutomationDialog extends StatefulWidget {
final String automationName; final String automationName;
final String automationId; final String automationId;
final String uniqueCustomId; final String uniqueCustomId;
final String? passedAutomationActionExecutor;
const AutomationDialog({ const AutomationDialog({
super.key, super.key,
required this.automationName, required this.automationName,
required this.automationId, required this.automationId,
required this.uniqueCustomId, required this.uniqueCustomId,
this.passedAutomationActionExecutor,
}); });
@override @override
Widget build(BuildContext context) { State<AutomationDialog> createState() => _AutomationDialogState();
return BlocBuilder<RoutineBloc, RoutineState>( }
builder: (context, state) {
final String? initialSelection = state.automationActionExecutor;
return Dialog( class _AutomationDialogState extends State<AutomationDialog> {
shape: String? selectedAutomationActionExecutor;
RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
child: Container( @override
width: 400, void initState() {
padding: const EdgeInsets.all(16), super.initState();
child: Column( List<DeviceFunctionData>? functions = context
mainAxisSize: MainAxisSize.min, .read<RoutineBloc>()
children: [ .state
DialogHeader(automationName), .selectedFunctions[widget.uniqueCustomId];
const SizedBox(height: 16), for (DeviceFunctionData data in functions ?? []) {
ListTile( if (data.entityId == widget.automationId) {
leading: selectedAutomationActionExecutor = data.value;
SvgPicture.asset(Assets.acPower, width: 24, height: 24), }
title: const Text('Enable'), }
trailing: Radio<String?>( }
value: 'rule_enable',
groupValue: initialSelection, @override
onChanged: (String? value) { Widget build(BuildContext context) {
if (value != null) { return Dialog(
context.read<RoutineBloc>().add( shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
SetAutomationActionExecutor( child: Container(
automationActionExecutor: value, width: 400,
), padding: const EdgeInsets.all(16),
); child: Column(
} mainAxisSize: MainAxisSize.min,
}, children: [
), DialogHeader(widget.automationName),
), const SizedBox(height: 16),
ListTile( ListTile(
leading: SvgPicture.asset(Assets.acPowerOff, leading: SvgPicture.asset(Assets.acPower, width: 24, height: 24),
width: 24, height: 24), title: const Text('Enable'),
title: const Text('Disable'), trailing: Radio<String?>(
trailing: Radio<String?>( value: 'rule_enable',
value: 'rule_disable', groupValue: selectedAutomationActionExecutor,
groupValue: initialSelection, onChanged: (String? value) {
onChanged: (String? value) { setState(() {
if (value != null) { selectedAutomationActionExecutor = 'rule_enable';
context.read<RoutineBloc>().add( });
SetAutomationActionExecutor( }),
automationActionExecutor: value,
),
);
}
},
),
),
const SizedBox(height: 16),
DialogFooter(
onConfirm: () {
if (state.automationActionExecutor != null) {
context.read<RoutineBloc>().add(
AddFunctionToRoutine(
[
DeviceFunctionData(
entityId: automationId,
functionCode: 'automation',
value: state.automationActionExecutor,
operationName: 'Automation',
),
],
uniqueCustomId,
),
);
Navigator.of(context).pop(true);
}
},
onCancel: () => Navigator.of(context).pop(false),
isConfirmEnabled: state.automationActionExecutor != null,
dialogWidth: 400,
),
],
), ),
), ListTile(
); leading:
}, SvgPicture.asset(Assets.acPowerOff, width: 24, height: 24),
title: const Text('Disable'),
trailing: Radio<String?>(
value: 'rule_disable',
groupValue: selectedAutomationActionExecutor,
onChanged: (String? value) {
setState(() {
selectedAutomationActionExecutor = 'rule_disable';
});
},
),
),
const SizedBox(height: 16),
DialogFooter(
onConfirm: () {
if (selectedAutomationActionExecutor != null) {
context.read<RoutineBloc>().add(
AddFunctionToRoutine(
[
DeviceFunctionData(
entityId: widget.automationId,
functionCode: 'automation',
value: selectedAutomationActionExecutor,
operationName: 'Automation',
),
],
widget.uniqueCustomId,
),
);
}
Navigator.of(context).pop(true);
},
onCancel: () => Navigator.of(context).pop(),
isConfirmEnabled: selectedAutomationActionExecutor != null,
dialogWidth: 400,
),
],
),
),
); );
} }
} }

View File

@ -87,8 +87,11 @@ class ThenContainer extends StatelessWidget {
...state.thenItems[index], ...state.thenItems[index],
'imagePath': 'imagePath':
Assets.automation, Assets.automation,
'title': state 'title':
.thenItems[index]['name'], state.thenItems[index]
['name'] ??
state.thenItems[index]
['title'],
})); }));
} }
return; return;
@ -171,7 +174,7 @@ class ThenContainer extends StatelessWidget {
if (mutableData['type'] == 'tap_to_run' && state.isAutomation) { if (mutableData['type'] == 'tap_to_run' && state.isAutomation) {
context.read<RoutineBloc>().add(AddToThenContainer({ context.read<RoutineBloc>().add(AddToThenContainer({
...mutableData, ...mutableData,
'imagePath': Assets.logo, 'imagePath': mutableData['imagePath'] ?? Assets.logo,
'title': mutableData['name'], 'title': mutableData['name'],
})); }));