Added routines search field functionlity

This commit is contained in:
Abdullah Alassaf
2024-11-25 01:47:17 +03:00
parent 0c555cda83
commit 30db9cfc2a
6 changed files with 138 additions and 109 deletions

View File

@ -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);

View File

@ -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
];
}

View File

@ -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(),
);
},

View File

@ -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,

View File

@ -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(),
);
}

View File

@ -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));
},
),
],
);