mirror of
https://github.com/SyncrowIOT/web.git
synced 2025-07-09 22:57:21 +00:00
Added routines search field functionlity
This commit is contained in:
@ -32,8 +32,7 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
||||
}
|
||||
|
||||
void _onAddToIfContainer(AddToIfContainer event, Emitter<RoutineState> emit) {
|
||||
final updatedIfItems = List<Map<String, dynamic>>.from(state.ifItems)
|
||||
..add(event.item);
|
||||
final updatedIfItems = List<Map<String, dynamic>>.from(state.ifItems)..add(event.item);
|
||||
if (event.isTabToRun) {
|
||||
isTabToRun = true;
|
||||
isAutomation = false;
|
||||
@ -44,15 +43,12 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
||||
emit(state.copyWith(ifItems: updatedIfItems));
|
||||
}
|
||||
|
||||
void _onAddToThenContainer(
|
||||
AddToThenContainer event, Emitter<RoutineState> emit) {
|
||||
final updatedThenItems = List<Map<String, dynamic>>.from(state.thenItems)
|
||||
..add(event.item);
|
||||
void _onAddToThenContainer(AddToThenContainer event, Emitter<RoutineState> emit) {
|
||||
final updatedThenItems = List<Map<String, dynamic>>.from(state.thenItems)..add(event.item);
|
||||
emit(state.copyWith(thenItems: updatedThenItems));
|
||||
}
|
||||
|
||||
void _onAddFunctionsToRoutine(
|
||||
AddFunctionToRoutine event, Emitter<RoutineState> emit) {
|
||||
void _onAddFunctionsToRoutine(AddFunctionToRoutine event, Emitter<RoutineState> emit) {
|
||||
try {
|
||||
if (event.functions.isEmpty) return;
|
||||
|
||||
@ -61,11 +57,9 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
||||
|
||||
if (currentSelectedFunctions.containsKey(event.uniqueCustomId)) {
|
||||
currentSelectedFunctions[event.uniqueCustomId] =
|
||||
List.from(currentSelectedFunctions[event.uniqueCustomId]!)
|
||||
..addAll(event.functions);
|
||||
List.from(currentSelectedFunctions[event.uniqueCustomId]!)..addAll(event.functions);
|
||||
} else {
|
||||
currentSelectedFunctions[event.uniqueCustomId] =
|
||||
List.from(event.functions);
|
||||
currentSelectedFunctions[event.uniqueCustomId] = List.from(event.functions);
|
||||
}
|
||||
|
||||
emit(state.copyWith(selectedFunctions: currentSelectedFunctions));
|
||||
@ -74,8 +68,7 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _onLoadScenes(
|
||||
LoadScenes event, Emitter<RoutineState> emit) async {
|
||||
Future<void> _onLoadScenes(LoadScenes event, Emitter<RoutineState> emit) async {
|
||||
emit(state.copyWith(isLoading: true, errorMessage: null));
|
||||
|
||||
try {
|
||||
@ -94,8 +87,7 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _onLoadAutomation(
|
||||
LoadAutomation event, Emitter<RoutineState> emit) async {
|
||||
Future<void> _onLoadAutomation(LoadAutomation event, Emitter<RoutineState> emit) async {
|
||||
emit(state.copyWith(isLoading: true, errorMessage: null));
|
||||
|
||||
try {
|
||||
@ -114,13 +106,13 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
||||
}
|
||||
}
|
||||
|
||||
FutureOr<void> _onSearchRoutines(
|
||||
SearchRoutines event, Emitter<RoutineState> emit) {
|
||||
emit(state.copyWith(routineName: event.query));
|
||||
FutureOr<void> _onSearchRoutines(SearchRoutines event, Emitter<RoutineState> emit) async {
|
||||
emit(state.copyWith(isLoading: true, errorMessage: null));
|
||||
await Future.delayed(const Duration(seconds: 1));
|
||||
emit(state.copyWith(searchText: event.query));
|
||||
}
|
||||
|
||||
FutureOr<void> _onAddSelectedIcon(
|
||||
AddSelectedIcon event, Emitter<RoutineState> emit) {
|
||||
FutureOr<void> _onAddSelectedIcon(AddSelectedIcon event, Emitter<RoutineState> emit) {
|
||||
emit(state.copyWith(selectedIcon: event.icon));
|
||||
}
|
||||
|
||||
@ -129,8 +121,7 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
||||
return actions.first['deviceId'] == 'delay';
|
||||
}
|
||||
|
||||
Future<void> _onCreateScene(
|
||||
CreateSceneEvent event, Emitter<RoutineState> emit) async {
|
||||
Future<void> _onCreateScene(CreateSceneEvent event, Emitter<RoutineState> emit) async {
|
||||
try {
|
||||
// Check if first action is delay
|
||||
if (_isFirstActionDelay(state.thenItems)) {
|
||||
@ -145,8 +136,7 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
||||
|
||||
final actions = state.thenItems
|
||||
.map((item) {
|
||||
final functions =
|
||||
state.selectedFunctions[item['uniqueCustomId']] ?? [];
|
||||
final functions = state.selectedFunctions[item['uniqueCustomId']] ?? [];
|
||||
if (functions.isEmpty) return null;
|
||||
|
||||
final function = functions.first;
|
||||
@ -201,8 +191,7 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
||||
}
|
||||
}
|
||||
|
||||
FutureOr<void> _onRemoveDragCard(
|
||||
RemoveDragCard event, Emitter<RoutineState> emit) {
|
||||
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);
|
||||
|
@ -13,50 +13,49 @@ class RoutineState extends Equatable {
|
||||
final String? loadAutomationErrorMessage;
|
||||
final String? routineName;
|
||||
final String? selectedIcon;
|
||||
final String? searchText;
|
||||
|
||||
const RoutineState({
|
||||
this.ifItems = const [],
|
||||
this.thenItems = const [],
|
||||
this.availableCards = const [],
|
||||
this.scenes = const [],
|
||||
this.automations = const [],
|
||||
this.selectedFunctions = const {},
|
||||
this.isLoading = false,
|
||||
this.errorMessage,
|
||||
this.routineName,
|
||||
this.selectedIcon,
|
||||
this.loadScenesErrorMessage,
|
||||
this.loadAutomationErrorMessage,
|
||||
});
|
||||
const RoutineState(
|
||||
{this.ifItems = const [],
|
||||
this.thenItems = const [],
|
||||
this.availableCards = const [],
|
||||
this.scenes = const [],
|
||||
this.automations = const [],
|
||||
this.selectedFunctions = const {},
|
||||
this.isLoading = false,
|
||||
this.errorMessage,
|
||||
this.routineName,
|
||||
this.selectedIcon,
|
||||
this.loadScenesErrorMessage,
|
||||
this.loadAutomationErrorMessage,
|
||||
this.searchText});
|
||||
|
||||
RoutineState copyWith({
|
||||
List<Map<String, dynamic>>? ifItems,
|
||||
List<Map<String, dynamic>>? thenItems,
|
||||
List<ScenesModel>? scenes,
|
||||
List<ScenesModel>? automations,
|
||||
Map<String, List<DeviceFunctionData>>? selectedFunctions,
|
||||
bool? isLoading,
|
||||
String? errorMessage,
|
||||
String? routineName,
|
||||
String? selectedIcon,
|
||||
String? loadAutomationErrorMessage,
|
||||
String? loadScenesErrorMessage,
|
||||
}) {
|
||||
RoutineState copyWith(
|
||||
{List<Map<String, dynamic>>? ifItems,
|
||||
List<Map<String, dynamic>>? thenItems,
|
||||
List<ScenesModel>? scenes,
|
||||
List<ScenesModel>? automations,
|
||||
Map<String, List<DeviceFunctionData>>? selectedFunctions,
|
||||
bool? isLoading,
|
||||
String? errorMessage,
|
||||
String? routineName,
|
||||
String? selectedIcon,
|
||||
String? loadAutomationErrorMessage,
|
||||
String? loadScenesErrorMessage,
|
||||
String? searchText}) {
|
||||
return RoutineState(
|
||||
ifItems: ifItems ?? this.ifItems,
|
||||
thenItems: thenItems ?? this.thenItems,
|
||||
scenes: scenes ?? this.scenes,
|
||||
automations: automations ?? this.automations,
|
||||
selectedFunctions: selectedFunctions ?? this.selectedFunctions,
|
||||
isLoading: isLoading ?? this.isLoading,
|
||||
errorMessage: errorMessage ?? this.errorMessage,
|
||||
routineName: routineName ?? this.routineName,
|
||||
selectedIcon: selectedIcon ?? this.selectedIcon,
|
||||
loadScenesErrorMessage:
|
||||
loadScenesErrorMessage ?? this.loadScenesErrorMessage,
|
||||
loadAutomationErrorMessage:
|
||||
loadAutomationErrorMessage ?? this.loadAutomationErrorMessage,
|
||||
);
|
||||
ifItems: ifItems ?? this.ifItems,
|
||||
thenItems: thenItems ?? this.thenItems,
|
||||
scenes: scenes ?? this.scenes,
|
||||
automations: automations ?? this.automations,
|
||||
selectedFunctions: selectedFunctions ?? this.selectedFunctions,
|
||||
isLoading: isLoading ?? this.isLoading,
|
||||
errorMessage: errorMessage ?? this.errorMessage,
|
||||
routineName: routineName ?? this.routineName,
|
||||
selectedIcon: selectedIcon ?? this.selectedIcon,
|
||||
loadScenesErrorMessage: loadScenesErrorMessage ?? this.loadScenesErrorMessage,
|
||||
loadAutomationErrorMessage: loadAutomationErrorMessage ?? this.loadAutomationErrorMessage,
|
||||
searchText: searchText ?? this.searchText);
|
||||
}
|
||||
|
||||
@override
|
||||
@ -72,5 +71,6 @@ class RoutineState extends Equatable {
|
||||
selectedIcon,
|
||||
loadScenesErrorMessage,
|
||||
loadAutomationErrorMessage,
|
||||
searchText
|
||||
];
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/all_devices/bloc/device_mgmt_bloc/device_managment_bloc.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_model.dart';
|
||||
import 'package:syncrow_web/pages/routiens/bloc/routine_bloc/routine_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routiens/widgets/dragable_card.dart';
|
||||
|
||||
@ -14,7 +15,7 @@ class RoutineDevices extends StatelessWidget {
|
||||
child: BlocBuilder<DeviceManagementBloc, DeviceManagementState>(
|
||||
builder: (context, state) {
|
||||
if (state is DeviceManagementLoaded) {
|
||||
final deviceList = state.devices
|
||||
List<AllDevicesModel> deviceList = state.devices
|
||||
.where((device) =>
|
||||
device.productType == 'AC' ||
|
||||
device.productType == '1G' ||
|
||||
@ -30,19 +31,39 @@ class RoutineDevices extends StatelessWidget {
|
||||
runSpacing: 10,
|
||||
children: deviceList.asMap().entries.map((entry) {
|
||||
final device = entry.value;
|
||||
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': '',
|
||||
},
|
||||
);
|
||||
if (routineState.searchText != null && routineState.searchText!.isNotEmpty) {
|
||||
return device.name!
|
||||
.toLowerCase()
|
||||
.contains(routineState.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': '',
|
||||
},
|
||||
)
|
||||
: Container();
|
||||
} 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': '',
|
||||
},
|
||||
);
|
||||
}
|
||||
}).toList(),
|
||||
);
|
||||
},
|
||||
|
@ -1,6 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_web/main.dart';
|
||||
import 'package:syncrow_web/pages/common/buttons/default_button.dart';
|
||||
import 'package:syncrow_web/pages/common/text_field/custom_text_field.dart';
|
||||
import 'package:syncrow_web/pages/routiens/bloc/routine_bloc/routine_bloc.dart';
|
||||
@ -32,9 +31,7 @@ class RoutineSearchAndButtons extends StatelessWidget {
|
||||
children: [
|
||||
ConstrainedBox(
|
||||
constraints: BoxConstraints(
|
||||
maxWidth: constraints.maxWidth > 700
|
||||
? 450
|
||||
: constraints.maxWidth - 32),
|
||||
maxWidth: constraints.maxWidth > 700 ? 450 : constraints.maxWidth - 32),
|
||||
child: StatefulTextField(
|
||||
title: 'Routine Name',
|
||||
height: 40,
|
||||
@ -46,9 +43,7 @@ class RoutineSearchAndButtons extends StatelessWidget {
|
||||
isRequired: true,
|
||||
width: 450,
|
||||
onChanged: (value) {
|
||||
context
|
||||
.read<RoutineBloc>()
|
||||
.add(SearchRoutines(value));
|
||||
// context.read<RoutineBloc>().add(SearchRoutines(value));
|
||||
},
|
||||
),
|
||||
),
|
||||
@ -60,14 +55,11 @@ class RoutineSearchAndButtons extends StatelessWidget {
|
||||
child: Center(
|
||||
child: DefaultButton(
|
||||
onPressed: () async {
|
||||
final result =
|
||||
await SettingHelper.showSettingDialog(
|
||||
final result = await SettingHelper.showSettingDialog(
|
||||
context: context,
|
||||
);
|
||||
if (result != null) {
|
||||
context
|
||||
.read<RoutineBloc>()
|
||||
.add(AddSelectedIcon(result));
|
||||
context.read<RoutineBloc>().add(AddSelectedIcon(result));
|
||||
}
|
||||
},
|
||||
borderRadius: 15,
|
||||
|
@ -33,17 +33,33 @@ class _ScenesAndAutomationsState extends State<ScenesAndAutomations> {
|
||||
runSpacing: 10,
|
||||
children: scenes.asMap().entries.map((entry) {
|
||||
final scene = entry.value;
|
||||
return DraggableCard(
|
||||
imagePath: Assets.logo,
|
||||
title: scene.name,
|
||||
deviceData: {
|
||||
'deviceId': scene.id,
|
||||
'name': scene.name,
|
||||
'status': scene.status,
|
||||
'type': scene.type,
|
||||
'icon': scene.icon,
|
||||
},
|
||||
);
|
||||
if (state.searchText != null && state.searchText!.isNotEmpty) {
|
||||
return scene.name.toLowerCase().contains(state.searchText!.toLowerCase())
|
||||
? DraggableCard(
|
||||
imagePath: Assets.logo,
|
||||
title: scene.name,
|
||||
deviceData: {
|
||||
'deviceId': scene.id,
|
||||
'name': scene.name,
|
||||
'status': scene.status,
|
||||
'type': scene.type,
|
||||
'icon': scene.icon,
|
||||
},
|
||||
)
|
||||
: Container();
|
||||
} else {
|
||||
return DraggableCard(
|
||||
imagePath: Assets.logo,
|
||||
title: scene.name,
|
||||
deviceData: {
|
||||
'deviceId': scene.id,
|
||||
'name': scene.name,
|
||||
'status': scene.status,
|
||||
'type': scene.type,
|
||||
'icon': scene.icon,
|
||||
},
|
||||
);
|
||||
}
|
||||
}).toList(),
|
||||
);
|
||||
}
|
||||
|
@ -1,11 +1,12 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_web/pages/common/text_field/custom_text_field.dart';
|
||||
import 'package:syncrow_web/pages/routiens/bloc/routine_bloc/routine_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routiens/widgets/routines_title_widget.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
|
||||
|
||||
class ConditionTitleAndSearchBar extends StatelessWidget
|
||||
with HelperResponsiveLayout {
|
||||
class ConditionTitleAndSearchBar extends StatelessWidget with HelperResponsiveLayout {
|
||||
const ConditionTitleAndSearchBar({
|
||||
super.key,
|
||||
});
|
||||
@ -34,7 +35,12 @@ class ConditionTitleAndSearchBar extends StatelessWidget
|
||||
borderRadius: BorderRadius.circular(15),
|
||||
),
|
||||
controller: TextEditingController(),
|
||||
onChanged: (value) {},
|
||||
// onSubmitted: (value) {
|
||||
// context.read<RoutineBloc>().add(SearchRoutines(value));
|
||||
// },
|
||||
onChanged: (value) {
|
||||
context.read<RoutineBloc>().add(SearchRoutines(value));
|
||||
},
|
||||
),
|
||||
],
|
||||
)
|
||||
@ -57,7 +63,12 @@ class ConditionTitleAndSearchBar extends StatelessWidget
|
||||
borderRadius: BorderRadius.circular(15),
|
||||
),
|
||||
controller: TextEditingController(),
|
||||
onChanged: (value) {},
|
||||
// onSubmitted: (value) {
|
||||
// context.read<RoutineBloc>().add(SearchRoutines(value));
|
||||
// },
|
||||
onChanged: (value) {
|
||||
context.read<RoutineBloc>().add(SearchRoutines(value));
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
|
Reference in New Issue
Block a user