mirror of
https://github.com/SyncrowIOT/web.git
synced 2025-07-10 15:17:31 +00:00
push tab to run and handling automation
This commit is contained in:
@ -19,6 +19,7 @@ class StatefulTextField extends StatefulWidget {
|
|||||||
this.icon,
|
this.icon,
|
||||||
this.hintColor,
|
this.hintColor,
|
||||||
required this.onChanged,
|
required this.onChanged,
|
||||||
|
this.isRequired,
|
||||||
});
|
});
|
||||||
|
|
||||||
final String title;
|
final String title;
|
||||||
@ -34,6 +35,7 @@ class StatefulTextField extends StatefulWidget {
|
|||||||
final IconData? icon;
|
final IconData? icon;
|
||||||
final Color? hintColor;
|
final Color? hintColor;
|
||||||
final Function(String)? onChanged;
|
final Function(String)? onChanged;
|
||||||
|
final bool? isRequired;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<StatefulTextField> createState() => _StatefulTextFieldState();
|
State<StatefulTextField> createState() => _StatefulTextFieldState();
|
||||||
@ -62,6 +64,7 @@ class _StatefulTextFieldState extends State<StatefulTextField> {
|
|||||||
icon: widget.icon,
|
icon: widget.icon,
|
||||||
hintColor: widget.hintColor,
|
hintColor: widget.hintColor,
|
||||||
onChanged: widget.onChanged,
|
onChanged: widget.onChanged,
|
||||||
|
isRequired: widget.isRequired,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -82,6 +85,7 @@ class CustomTextField extends StatelessWidget {
|
|||||||
this.icon,
|
this.icon,
|
||||||
this.hintColor,
|
this.hintColor,
|
||||||
required this.onChanged,
|
required this.onChanged,
|
||||||
|
this.isRequired,
|
||||||
});
|
});
|
||||||
|
|
||||||
final String title;
|
final String title;
|
||||||
@ -97,6 +101,7 @@ class CustomTextField extends StatelessWidget {
|
|||||||
final IconData? icon;
|
final IconData? icon;
|
||||||
final Color? hintColor;
|
final Color? hintColor;
|
||||||
final Function(String)? onChanged;
|
final Function(String)? onChanged;
|
||||||
|
final bool? isRequired;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -123,6 +128,7 @@ class CustomTextField extends StatelessWidget {
|
|||||||
child: TextFormField(
|
child: TextFormField(
|
||||||
controller: controller,
|
controller: controller,
|
||||||
style: const TextStyle(color: Colors.black),
|
style: const TextStyle(color: Colors.black),
|
||||||
|
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
hintText: hintText,
|
hintText: hintText,
|
||||||
hintStyle: TextStyle(
|
hintStyle: TextStyle(
|
||||||
@ -140,6 +146,16 @@ class CustomTextField extends StatelessWidget {
|
|||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
onChanged!(value);
|
onChanged!(value);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/// required validator
|
||||||
|
validator: (value) {
|
||||||
|
if (isRequired == true) {
|
||||||
|
if (value == null || value.isEmpty) {
|
||||||
|
return 'This field is required';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -88,31 +88,32 @@ class DeviceManagementPage extends StatelessWidget with HelperResponsiveLayout {
|
|||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
rightBody: const NavigateHomeGridView(),
|
rightBody: const NavigateHomeGridView(),
|
||||||
scaffoldBody: BlocBuilder<SwitchTabsBloc, SwitchTabsState>(
|
scaffoldBody: CreateNewRoutineView(),
|
||||||
builder: (context, state) {
|
// BlocBuilder<SwitchTabsBloc, SwitchTabsState>(
|
||||||
if (state is SelectedTabState && state.selectedTab) {
|
// builder: (context, state) {
|
||||||
return const RoutinesView();
|
// if (state is SelectedTabState && state.selectedTab) {
|
||||||
}
|
// return const RoutinesView();
|
||||||
if (state is ShowCreateRoutineState && state.showCreateRoutine) {
|
// }
|
||||||
return const CreateNewRoutineView();
|
// if (state is ShowCreateRoutineState && state.showCreateRoutine) {
|
||||||
}
|
// return const CreateNewRoutineView();
|
||||||
|
// }
|
||||||
|
|
||||||
return BlocBuilder<DeviceManagementBloc, DeviceManagementState>(
|
// return BlocBuilder<DeviceManagementBloc, DeviceManagementState>(
|
||||||
builder: (context, deviceState) {
|
// builder: (context, deviceState) {
|
||||||
if (deviceState is DeviceManagementLoading) {
|
// if (deviceState is DeviceManagementLoading) {
|
||||||
return const Center(child: CircularProgressIndicator());
|
// return const Center(child: CircularProgressIndicator());
|
||||||
} else if (deviceState is DeviceManagementLoaded ||
|
// } else if (deviceState is DeviceManagementLoaded ||
|
||||||
deviceState is DeviceManagementFiltered) {
|
// deviceState is DeviceManagementFiltered) {
|
||||||
final devices = (deviceState as dynamic).devices ??
|
// final devices = (deviceState as dynamic).devices ??
|
||||||
(deviceState as DeviceManagementFiltered).filteredDevices;
|
// (deviceState as DeviceManagementFiltered).filteredDevices;
|
||||||
|
|
||||||
return DeviceManagementBody(devices: devices);
|
// return DeviceManagementBody(devices: devices);
|
||||||
} else {
|
// } else {
|
||||||
return const Center(child: Text('Error fetching Devices'));
|
// return const Center(child: Text('Error fetching Devices'));
|
||||||
}
|
// }
|
||||||
},
|
// },
|
||||||
);
|
// );
|
||||||
}),
|
// }),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,7 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
|||||||
on<SearchRoutines>(_onSearchRoutines);
|
on<SearchRoutines>(_onSearchRoutines);
|
||||||
on<AddSelectedIcon>(_onAddSelectedIcon);
|
on<AddSelectedIcon>(_onAddSelectedIcon);
|
||||||
on<CreateSceneEvent>(_onCreateScene);
|
on<CreateSceneEvent>(_onCreateScene);
|
||||||
|
on<RemoveDragCard>(_onRemoveDragCard);
|
||||||
// on<RemoveFunction>(_onRemoveFunction);
|
// on<RemoveFunction>(_onRemoveFunction);
|
||||||
// on<ClearFunctions>(_onClearFunctions);
|
// on<ClearFunctions>(_onClearFunctions);
|
||||||
}
|
}
|
||||||
@ -33,7 +34,13 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
|||||||
void _onAddToIfContainer(AddToIfContainer event, Emitter<RoutineState> emit) {
|
void _onAddToIfContainer(AddToIfContainer event, Emitter<RoutineState> emit) {
|
||||||
final updatedIfItems = List<Map<String, dynamic>>.from(state.ifItems)
|
final updatedIfItems = List<Map<String, dynamic>>.from(state.ifItems)
|
||||||
..add(event.item);
|
..add(event.item);
|
||||||
isTabToRun = event.isTabToRun;
|
if (event.isTabToRun) {
|
||||||
|
isTabToRun = true;
|
||||||
|
isAutomation = false;
|
||||||
|
} else {
|
||||||
|
isTabToRun = false;
|
||||||
|
isAutomation = true;
|
||||||
|
}
|
||||||
emit(state.copyWith(ifItems: updatedIfItems));
|
emit(state.copyWith(ifItems: updatedIfItems));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,30 +53,27 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
|||||||
|
|
||||||
void _onAddFunctionsToRoutine(
|
void _onAddFunctionsToRoutine(
|
||||||
AddFunctionToRoutine event, Emitter<RoutineState> emit) {
|
AddFunctionToRoutine event, Emitter<RoutineState> emit) {
|
||||||
final currentSelectedFunctions =
|
try {
|
||||||
Map<String, List<DeviceFunctionData>>.from(state.selectedFunctions);
|
if (event.functions.isEmpty) return;
|
||||||
|
|
||||||
if (currentSelectedFunctions.containsKey(event.uniqueCustomId)) {
|
final currentSelectedFunctions =
|
||||||
currentSelectedFunctions[event.uniqueCustomId]!.addAll(event.functions);
|
Map<String, List<DeviceFunctionData>>.from(state.selectedFunctions);
|
||||||
} else {
|
|
||||||
currentSelectedFunctions[event.uniqueCustomId] = event.functions;
|
if (currentSelectedFunctions.containsKey(event.uniqueCustomId)) {
|
||||||
|
currentSelectedFunctions[event.uniqueCustomId] =
|
||||||
|
List.from(currentSelectedFunctions[event.uniqueCustomId]!)
|
||||||
|
..addAll(event.functions);
|
||||||
|
} else {
|
||||||
|
currentSelectedFunctions[event.uniqueCustomId] =
|
||||||
|
List.from(event.functions);
|
||||||
|
}
|
||||||
|
|
||||||
|
emit(state.copyWith(selectedFunctions: currentSelectedFunctions));
|
||||||
|
} catch (e) {
|
||||||
|
debugPrint('Error adding functions: $e');
|
||||||
}
|
}
|
||||||
|
|
||||||
emit(state.copyWith(selectedFunctions: currentSelectedFunctions));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// void _onRemoveFunction(RemoveFunction event, Emitter<RoutineState> emit) {
|
|
||||||
// final functions = List<DeviceFunctionData>.from(state.selectedFunctions)
|
|
||||||
// ..removeWhere((f) =>
|
|
||||||
// f.functionCode == event.function.functionCode &&
|
|
||||||
// f.value == event.function.value);
|
|
||||||
// emit(state.copyWith(selectedFunctions: functions));
|
|
||||||
// }
|
|
||||||
|
|
||||||
// void _onClearFunctions(ClearFunctions event, Emitter<RoutineState> emit) {
|
|
||||||
// emit(state.copyWith(selectedFunctions: []));
|
|
||||||
// }
|
|
||||||
|
|
||||||
Future<void> _onLoadScenes(
|
Future<void> _onLoadScenes(
|
||||||
LoadScenes event, Emitter<RoutineState> emit) async {
|
LoadScenes event, Emitter<RoutineState> emit) async {
|
||||||
emit(state.copyWith(isLoading: true, errorMessage: null));
|
emit(state.copyWith(isLoading: true, errorMessage: null));
|
||||||
@ -83,7 +87,9 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(state.copyWith(
|
emit(state.copyWith(
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
errorMessage: 'Failed to load scenes',
|
loadScenesErrorMessage: 'Failed to load scenes',
|
||||||
|
errorMessage: '',
|
||||||
|
loadAutomationErrorMessage: '',
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -101,7 +107,9 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(state.copyWith(
|
emit(state.copyWith(
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
errorMessage: 'Failed to load automations',
|
loadAutomationErrorMessage: 'Failed to load automations',
|
||||||
|
errorMessage: '',
|
||||||
|
loadScenesErrorMessage: '',
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -178,10 +186,7 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
|||||||
|
|
||||||
final result = await SceneApi.createScene(createSceneModel);
|
final result = await SceneApi.createScene(createSceneModel);
|
||||||
if (result['success']) {
|
if (result['success']) {
|
||||||
emit(state.copyWith(
|
emit(const RoutineState());
|
||||||
isLoading: false,
|
|
||||||
errorMessage: null,
|
|
||||||
));
|
|
||||||
} else {
|
} else {
|
||||||
emit(state.copyWith(
|
emit(state.copyWith(
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
@ -195,4 +200,18 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FutureOr<void> _onRemoveDragCard(
|
||||||
|
RemoveDragCard event, Emitter<RoutineState> emit) {
|
||||||
|
if (event.isFromThen) {
|
||||||
|
/// remove element from thenItems at specific index
|
||||||
|
final thenItems = List<Map<String, dynamic>>.from(state.thenItems);
|
||||||
|
thenItems.removeAt(event.index);
|
||||||
|
emit(state.copyWith(thenItems: thenItems));
|
||||||
|
} else {
|
||||||
|
final ifItems = List<Map<String, dynamic>>.from(state.ifItems);
|
||||||
|
ifItems.removeAt(event.index);
|
||||||
|
emit(state.copyWith(ifItems: ifItems));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -79,4 +79,12 @@ class CreateSceneEvent extends RoutineEvent {
|
|||||||
List<Object> get props => [];
|
List<Object> get props => [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class RemoveDragCard extends RoutineEvent {
|
||||||
|
final int index;
|
||||||
|
final bool isFromThen;
|
||||||
|
const RemoveDragCard({required this.index, required this.isFromThen});
|
||||||
|
@override
|
||||||
|
List<Object> get props => [index];
|
||||||
|
}
|
||||||
|
|
||||||
class ClearFunctions extends RoutineEvent {}
|
class ClearFunctions extends RoutineEvent {}
|
||||||
|
@ -9,6 +9,8 @@ class RoutineState extends Equatable {
|
|||||||
final Map<String, List<DeviceFunctionData>> selectedFunctions;
|
final Map<String, List<DeviceFunctionData>> selectedFunctions;
|
||||||
final bool isLoading;
|
final bool isLoading;
|
||||||
final String? errorMessage;
|
final String? errorMessage;
|
||||||
|
final String? loadScenesErrorMessage;
|
||||||
|
final String? loadAutomationErrorMessage;
|
||||||
final String? routineName;
|
final String? routineName;
|
||||||
final String? selectedIcon;
|
final String? selectedIcon;
|
||||||
|
|
||||||
@ -23,6 +25,8 @@ class RoutineState extends Equatable {
|
|||||||
this.errorMessage,
|
this.errorMessage,
|
||||||
this.routineName,
|
this.routineName,
|
||||||
this.selectedIcon,
|
this.selectedIcon,
|
||||||
|
this.loadScenesErrorMessage,
|
||||||
|
this.loadAutomationErrorMessage,
|
||||||
});
|
});
|
||||||
|
|
||||||
RoutineState copyWith({
|
RoutineState copyWith({
|
||||||
@ -35,6 +39,8 @@ class RoutineState extends Equatable {
|
|||||||
String? errorMessage,
|
String? errorMessage,
|
||||||
String? routineName,
|
String? routineName,
|
||||||
String? selectedIcon,
|
String? selectedIcon,
|
||||||
|
String? loadAutomationErrorMessage,
|
||||||
|
String? loadScenesErrorMessage,
|
||||||
}) {
|
}) {
|
||||||
return RoutineState(
|
return RoutineState(
|
||||||
ifItems: ifItems ?? this.ifItems,
|
ifItems: ifItems ?? this.ifItems,
|
||||||
@ -46,6 +52,10 @@ 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,
|
||||||
|
loadAutomationErrorMessage:
|
||||||
|
loadAutomationErrorMessage ?? this.loadAutomationErrorMessage,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,5 +70,7 @@ class RoutineState extends Equatable {
|
|||||||
errorMessage,
|
errorMessage,
|
||||||
routineName,
|
routineName,
|
||||||
selectedIcon,
|
selectedIcon,
|
||||||
|
loadScenesErrorMessage,
|
||||||
|
loadAutomationErrorMessage,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@ -96,14 +96,13 @@ class ACHelper {
|
|||||||
onConfirm: state.addedFunctions.isNotEmpty
|
onConfirm: state.addedFunctions.isNotEmpty
|
||||||
? () {
|
? () {
|
||||||
/// add the functions to the routine bloc
|
/// add the functions to the routine bloc
|
||||||
// for (var function in state.addedFunctions) {
|
|
||||||
context.read<RoutineBloc>().add(
|
context.read<RoutineBloc>().add(
|
||||||
AddFunctionToRoutine(
|
AddFunctionToRoutine(
|
||||||
state.addedFunctions,
|
state.addedFunctions,
|
||||||
uniqueCustomId,
|
uniqueCustomId,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
//}
|
|
||||||
// Return the device data to be added to the container
|
// Return the device data to be added to the container
|
||||||
Navigator.pop(context, {
|
Navigator.pop(context, {
|
||||||
'deviceId': functions.first.deviceId,
|
'deviceId': functions.first.deviceId,
|
||||||
|
@ -1,12 +1,10 @@
|
|||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/routiens/bloc/functions_bloc/functions_bloc_bloc.dart';
|
|
||||||
import 'package:syncrow_web/pages/routiens/bloc/routine_bloc/routine_bloc.dart';
|
import 'package:syncrow_web/pages/routiens/bloc/routine_bloc/routine_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/routiens/models/device_functions.dart';
|
import 'package:syncrow_web/pages/routiens/models/device_functions.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/pages/routiens/widgets/dialog_header.dart';
|
import 'package:syncrow_web/pages/routiens/widgets/dialog_header.dart';
|
||||||
import 'package:syncrow_web/utils/color_manager.dart';
|
|
||||||
|
|
||||||
class DelayHelper {
|
class DelayHelper {
|
||||||
static Future<Map<String, dynamic>?> showDelayPickerDialog(
|
static Future<Map<String, dynamic>?> showDelayPickerDialog(
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:syncrow_web/pages/routiens/bloc/routine_bloc/routine_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/routiens/bloc/setting_bloc/setting_bloc.dart';
|
import 'package:syncrow_web/pages/routiens/bloc/setting_bloc/setting_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/routiens/bloc/setting_bloc/setting_event.dart';
|
import 'package:syncrow_web/pages/routiens/bloc/setting_bloc/setting_event.dart';
|
||||||
import 'package:syncrow_web/pages/routiens/bloc/setting_bloc/setting_state.dart';
|
import 'package:syncrow_web/pages/routiens/bloc/setting_bloc/setting_state.dart';
|
||||||
@ -10,13 +11,14 @@ import 'package:syncrow_web/utils/color_manager.dart';
|
|||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
|
|
||||||
class SettingHelper {
|
class SettingHelper {
|
||||||
static Future<String?> showSettingDialog(
|
static Future<String?> showSettingDialog({
|
||||||
{required BuildContext context,
|
required BuildContext context,
|
||||||
String? iconId,
|
String? iconId,
|
||||||
required bool isAutomation}) async {
|
}) async {
|
||||||
return showDialog<String>(
|
return showDialog<String>(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
|
final isAutomation = context.read<RoutineBloc>().isAutomation;
|
||||||
return BlocProvider(
|
return BlocProvider(
|
||||||
create: (_) =>
|
create: (_) =>
|
||||||
SettingBloc()..add(InitialEvent(selectedIcon: iconId ?? '')),
|
SettingBloc()..add(InitialEvent(selectedIcon: iconId ?? '')),
|
||||||
|
@ -11,6 +11,9 @@ class DraggableCard extends StatelessWidget {
|
|||||||
final String title;
|
final String title;
|
||||||
final Map<String, dynamic> deviceData;
|
final Map<String, dynamic> deviceData;
|
||||||
final EdgeInsetsGeometry? padding;
|
final EdgeInsetsGeometry? padding;
|
||||||
|
final void Function()? onRemove;
|
||||||
|
final bool? isFromThen;
|
||||||
|
final bool? isFromIf;
|
||||||
|
|
||||||
const DraggableCard({
|
const DraggableCard({
|
||||||
super.key,
|
super.key,
|
||||||
@ -18,6 +21,9 @@ class DraggableCard extends StatelessWidget {
|
|||||||
required this.title,
|
required this.title,
|
||||||
required this.deviceData,
|
required this.deviceData,
|
||||||
this.padding,
|
this.padding,
|
||||||
|
this.onRemove,
|
||||||
|
this.isFromThen,
|
||||||
|
this.isFromIf,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -44,75 +50,97 @@ class DraggableCard extends StatelessWidget {
|
|||||||
Widget _buildCardContent(
|
Widget _buildCardContent(
|
||||||
BuildContext context, List<DeviceFunctionData> deviceFunctions,
|
BuildContext context, List<DeviceFunctionData> deviceFunctions,
|
||||||
{EdgeInsetsGeometry? padding}) {
|
{EdgeInsetsGeometry? padding}) {
|
||||||
return Card(
|
return Stack(
|
||||||
color: ColorsManager.whiteColors,
|
children: [
|
||||||
child: Container(
|
Card(
|
||||||
padding: padding ?? const EdgeInsets.all(16),
|
color: ColorsManager.whiteColors,
|
||||||
width: 110,
|
child: Container(
|
||||||
height: deviceFunctions.isEmpty ? 123 : null,
|
padding: padding ?? const EdgeInsets.all(16),
|
||||||
child: Column(
|
width: 110,
|
||||||
mainAxisSize: MainAxisSize.min,
|
height: deviceFunctions.isEmpty ? 123 : null,
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
|
||||||
Column(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Container(
|
Column(
|
||||||
height: 50,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
width: 50,
|
children: [
|
||||||
decoration: BoxDecoration(
|
Container(
|
||||||
color: ColorsManager.CircleImageBackground,
|
height: 50,
|
||||||
borderRadius: BorderRadius.circular(90),
|
width: 50,
|
||||||
border: Border.all(
|
decoration: BoxDecoration(
|
||||||
color: ColorsManager.graysColor,
|
color: ColorsManager.CircleImageBackground,
|
||||||
),
|
borderRadius: BorderRadius.circular(90),
|
||||||
),
|
border: Border.all(
|
||||||
padding: const EdgeInsets.all(8),
|
color: ColorsManager.graysColor,
|
||||||
child: imagePath.contains('.svg')
|
|
||||||
? SvgPicture.asset(
|
|
||||||
imagePath,
|
|
||||||
)
|
|
||||||
: Image.network(imagePath),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 8),
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 3),
|
|
||||||
child: Text(
|
|
||||||
title,
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
overflow: TextOverflow.ellipsis,
|
|
||||||
maxLines: 2,
|
|
||||||
style: context.textTheme.bodySmall?.copyWith(
|
|
||||||
color: ColorsManager.blackColor,
|
|
||||||
fontSize: 12,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
if (deviceFunctions.isNotEmpty)
|
|
||||||
// const Divider(height: 1),
|
|
||||||
...deviceFunctions.map((function) => Row(
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
children: [
|
|
||||||
Expanded(
|
|
||||||
child: Text(
|
|
||||||
'${function.operationName}: ${function.value}',
|
|
||||||
style: context.textTheme.bodySmall?.copyWith(
|
|
||||||
fontSize: 9,
|
|
||||||
color: ColorsManager.textGray,
|
|
||||||
height: 1.2,
|
|
||||||
),
|
|
||||||
maxLines: 2,
|
|
||||||
overflow: TextOverflow.ellipsis,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
padding: const EdgeInsets.all(8),
|
||||||
)),
|
child: imagePath.contains('.svg')
|
||||||
],
|
? SvgPicture.asset(
|
||||||
|
imagePath,
|
||||||
|
)
|
||||||
|
: Image.network(imagePath),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 3),
|
||||||
|
child: Text(
|
||||||
|
title,
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
maxLines: 2,
|
||||||
|
style: context.textTheme.bodySmall?.copyWith(
|
||||||
|
color: ColorsManager.blackColor,
|
||||||
|
fontSize: 12,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
if (deviceFunctions.isNotEmpty)
|
||||||
|
// const Divider(height: 1),
|
||||||
|
...deviceFunctions.map((function) => Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: Text(
|
||||||
|
'${function.operationName}: ${function.value}',
|
||||||
|
style: context.textTheme.bodySmall?.copyWith(
|
||||||
|
fontSize: 9,
|
||||||
|
color: ColorsManager.textGray,
|
||||||
|
height: 1.2,
|
||||||
|
),
|
||||||
|
maxLines: 2,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
Positioned(
|
||||||
|
top: -4,
|
||||||
|
right: -6,
|
||||||
|
child: Visibility(
|
||||||
|
visible: (isFromIf ?? false) || (isFromThen ?? false),
|
||||||
|
child: IconButton(
|
||||||
|
onPressed: onRemove == null
|
||||||
|
? null
|
||||||
|
: () {
|
||||||
|
onRemove!();
|
||||||
|
},
|
||||||
|
icon: const Icon(
|
||||||
|
Icons.close,
|
||||||
|
color: ColorsManager.boxColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ import 'package:syncrow_web/pages/routiens/bloc/routine_bloc/routine_bloc.dart';
|
|||||||
import 'package:syncrow_web/pages/routiens/helper/dialog_helper/device_dialog_helper.dart';
|
import 'package:syncrow_web/pages/routiens/helper/dialog_helper/device_dialog_helper.dart';
|
||||||
import 'package:syncrow_web/pages/routiens/widgets/dragable_card.dart';
|
import 'package:syncrow_web/pages/routiens/widgets/dragable_card.dart';
|
||||||
import 'package:syncrow_web/utils/constants/assets.dart';
|
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||||
|
import 'package:uuid/uuid.dart';
|
||||||
|
|
||||||
class IfContainer extends StatelessWidget {
|
class IfContainer extends StatelessWidget {
|
||||||
const IfContainer({super.key});
|
const IfContainer({super.key});
|
||||||
@ -20,7 +21,9 @@ class IfContainer extends StatelessWidget {
|
|||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
const Text('IF', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
|
const Text('IF',
|
||||||
|
style:
|
||||||
|
TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
if (context.read<RoutineBloc>().isTabToRun)
|
if (context.read<RoutineBloc>().isTabToRun)
|
||||||
const Row(
|
const Row(
|
||||||
@ -37,14 +40,23 @@ class IfContainer extends StatelessWidget {
|
|||||||
Wrap(
|
Wrap(
|
||||||
spacing: 8,
|
spacing: 8,
|
||||||
runSpacing: 8,
|
runSpacing: 8,
|
||||||
children: state.ifItems
|
children: List.generate(
|
||||||
.map((item) => DraggableCard(
|
state.ifItems.length,
|
||||||
// key: Key(item['key']!),
|
(index) => DraggableCard(
|
||||||
imagePath: item['imagePath'] ?? '',
|
imagePath:
|
||||||
title: item['title'] ?? 'Tab to run',
|
state.ifItems[index]['imagePath'] ?? '',
|
||||||
deviceData: item,
|
title: state.ifItems[index]['title'] ?? '',
|
||||||
))
|
deviceData: state.ifItems[index],
|
||||||
.toList(),
|
padding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: 4, vertical: 8),
|
||||||
|
isFromThen: false,
|
||||||
|
isFromIf: true,
|
||||||
|
onRemove: () {
|
||||||
|
context.read<RoutineBloc>().add(
|
||||||
|
RemoveDragCard(
|
||||||
|
index: index, isFromThen: false));
|
||||||
|
},
|
||||||
|
)),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -52,15 +64,52 @@ class IfContainer extends StatelessWidget {
|
|||||||
},
|
},
|
||||||
onWillAccept: (data) => data != null,
|
onWillAccept: (data) => data != null,
|
||||||
onAccept: (data) async {
|
onAccept: (data) async {
|
||||||
|
// final uniqueCustomId = const Uuid().v4();
|
||||||
|
|
||||||
|
// final mutableData = Map<String, dynamic>.from(data);
|
||||||
|
// mutableData['uniqueCustomId'] = uniqueCustomId;
|
||||||
|
|
||||||
|
// if (!context.read<RoutineBloc>().isTabToRun) {
|
||||||
|
// if (data['deviceId'] == 'tab_to_run') {
|
||||||
|
// context.read<RoutineBloc>().add(AddToIfContainer(data, true));
|
||||||
|
// } else {
|
||||||
|
// final result =
|
||||||
|
// await DeviceDialogHelper.showDeviceDialog(context, mutableData);
|
||||||
|
// if (result != null) {
|
||||||
|
// context
|
||||||
|
// .read<RoutineBloc>()
|
||||||
|
// .add(AddToIfContainer(mutableData, false));
|
||||||
|
// } else if (!['AC', '1G', '2G', '3G']
|
||||||
|
// .contains(data['productType'])) {
|
||||||
|
// context
|
||||||
|
// .read<RoutineBloc>()
|
||||||
|
// .add(AddToIfContainer(mutableData, false));
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
final uniqueCustomId = const Uuid().v4();
|
||||||
|
|
||||||
|
final mutableData = Map<String, dynamic>.from(data);
|
||||||
|
mutableData['uniqueCustomId'] = uniqueCustomId;
|
||||||
|
|
||||||
if (!context.read<RoutineBloc>().isTabToRun) {
|
if (!context.read<RoutineBloc>().isTabToRun) {
|
||||||
if (data['deviceId'] == 'tab_to_run') {
|
if (mutableData['deviceId'] == 'tab_to_run') {
|
||||||
context.read<RoutineBloc>().add(AddToIfContainer(data, true));
|
context
|
||||||
|
.read<RoutineBloc>()
|
||||||
|
.add(AddToIfContainer(mutableData, true));
|
||||||
} else {
|
} else {
|
||||||
final result = await DeviceDialogHelper.showDeviceDialog(context, data);
|
final result = await DeviceDialogHelper.showDeviceDialog(
|
||||||
|
context, mutableData);
|
||||||
|
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
context.read<RoutineBloc>().add(AddToIfContainer(result, false));
|
context
|
||||||
} else if (!['AC', '1G', '2G', '3G'].contains(data['productType'])) {
|
.read<RoutineBloc>()
|
||||||
context.read<RoutineBloc>().add(AddToIfContainer(data, false));
|
.add(AddToIfContainer(mutableData, false));
|
||||||
|
} else if (!['AC', '1G', '2G', '3G']
|
||||||
|
.contains(mutableData['productType'])) {
|
||||||
|
context
|
||||||
|
.read<RoutineBloc>()
|
||||||
|
.add(AddToIfContainer(mutableData, false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,6 +43,7 @@ class RoutineSearchAndButtons extends StatelessWidget {
|
|||||||
boxDecoration: containerWhiteDecoration,
|
boxDecoration: containerWhiteDecoration,
|
||||||
elevation: 0,
|
elevation: 0,
|
||||||
borderRadius: 15,
|
borderRadius: 15,
|
||||||
|
isRequired: true,
|
||||||
width: 450,
|
width: 450,
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
context
|
context
|
||||||
@ -61,10 +62,8 @@ class RoutineSearchAndButtons extends StatelessWidget {
|
|||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
final result =
|
final result =
|
||||||
await SettingHelper.showSettingDialog(
|
await SettingHelper.showSettingDialog(
|
||||||
context: context,
|
context: context,
|
||||||
isAutomation: context
|
);
|
||||||
.read<RoutineBloc>()
|
|
||||||
.isAutomation);
|
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
context
|
context
|
||||||
.read<RoutineBloc>()
|
.read<RoutineBloc>()
|
||||||
|
@ -30,19 +30,25 @@ class ThenContainer extends StatelessWidget {
|
|||||||
fontSize: 18, fontWeight: FontWeight.bold)),
|
fontSize: 18, fontWeight: FontWeight.bold)),
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
Wrap(
|
Wrap(
|
||||||
spacing: 8,
|
spacing: 8,
|
||||||
runSpacing: 8,
|
runSpacing: 8,
|
||||||
children: state.thenItems
|
children: List.generate(
|
||||||
.map((item) => DraggableCard(
|
state.thenItems.length,
|
||||||
// key: Key(item['key']!),
|
(index) => DraggableCard(
|
||||||
imagePath: item['imagePath']!,
|
imagePath:
|
||||||
title: item['title']!,
|
state.thenItems[index]['imagePath'] ?? '',
|
||||||
deviceData: item,
|
title: state.thenItems[index]['title'] ?? '',
|
||||||
padding: EdgeInsets.symmetric(
|
deviceData: state.thenItems[index],
|
||||||
horizontal: 4, vertical: 8),
|
padding: const EdgeInsets.symmetric(
|
||||||
))
|
horizontal: 4, vertical: 8),
|
||||||
.toList(),
|
isFromThen: true,
|
||||||
),
|
isFromIf: false,
|
||||||
|
onRemove: () {
|
||||||
|
context.read<RoutineBloc>().add(
|
||||||
|
RemoveDragCard(
|
||||||
|
index: index, isFromThen: true));
|
||||||
|
},
|
||||||
|
))),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
import 'package:syncrow_web/pages/routiens/models/create_scene/create_scene_model.dart';
|
import 'package:syncrow_web/pages/routiens/models/create_scene/create_scene_model.dart';
|
||||||
import 'package:syncrow_web/pages/routiens/models/icon_model.dart';
|
import 'package:syncrow_web/pages/routiens/models/icon_model.dart';
|
||||||
import 'package:syncrow_web/pages/routiens/models/routine_model.dart';
|
import 'package:syncrow_web/pages/routiens/models/routine_model.dart';
|
||||||
@ -11,6 +12,7 @@ class SceneApi {
|
|||||||
static Future<Map<String, dynamic>> createScene(
|
static Future<Map<String, dynamic>> createScene(
|
||||||
CreateSceneModel createSceneModel) async {
|
CreateSceneModel createSceneModel) async {
|
||||||
try {
|
try {
|
||||||
|
debugPrint('create scene model: ${createSceneModel.toMap()}');
|
||||||
final response = await _httpService.post(
|
final response = await _httpService.post(
|
||||||
path: ApiEndpoints.createScene,
|
path: ApiEndpoints.createScene,
|
||||||
body: createSceneModel.toMap(),
|
body: createSceneModel.toMap(),
|
||||||
@ -19,8 +21,10 @@ class SceneApi {
|
|||||||
return json;
|
return json;
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
debugPrint('create scene response: $response');
|
||||||
return response;
|
return response;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
debugPrint(e.toString());
|
||||||
rethrow;
|
rethrow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user