mirror of
https://github.com/SyncrowIOT/web.git
synced 2025-08-25 22:09:40 +00:00
fix search filter tabs and checkbox no data selection
This commit is contained in:
@ -22,7 +22,7 @@ class DynamicTable extends StatefulWidget {
|
|||||||
required this.headers,
|
required this.headers,
|
||||||
required this.data,
|
required this.data,
|
||||||
required this.size,
|
required this.size,
|
||||||
this.tableName,
|
this.tableName,
|
||||||
required this.isEmpty,
|
required this.isEmpty,
|
||||||
required this.withCheckBox,
|
required this.withCheckBox,
|
||||||
required this.withSelectAll,
|
required this.withSelectAll,
|
||||||
@ -57,13 +57,19 @@ class _DynamicTableState extends State<DynamicTable> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _initializeSelection() {
|
void _initializeSelection() {
|
||||||
_selected = List<bool>.generate(widget.data.length, (index) {
|
if (widget.data.isEmpty) {
|
||||||
// Check if the initialSelectedIds contains the deviceUuid
|
_selected = [];
|
||||||
// uuidIndex is the index of the column containing the deviceUuid
|
_selectAll = false;
|
||||||
final deviceUuid = widget.data[index][widget.uuidIndex];
|
} else {
|
||||||
return widget.initialSelectedIds != null &&
|
_selected = List<bool>.generate(widget.data.length, (index) {
|
||||||
widget.initialSelectedIds!.contains(deviceUuid);
|
// Check if the initialSelectedIds contains the deviceUuid
|
||||||
});
|
// uuidIndex is the index of the column containing the deviceUuid
|
||||||
|
final deviceUuid = widget.data[index][widget.uuidIndex];
|
||||||
|
return widget.initialSelectedIds != null &&
|
||||||
|
widget.initialSelectedIds!.contains(deviceUuid);
|
||||||
|
});
|
||||||
|
_selectAll = _selected.every((element) => element == true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _toggleRowSelection(int index) {
|
void _toggleRowSelection(int index) {
|
||||||
@ -76,7 +82,6 @@ class _DynamicTableState extends State<DynamicTable> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void _toggleSelectAll(bool? value) {
|
void _toggleSelectAll(bool? value) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_selectAll = value ?? false;
|
_selectAll = value ?? false;
|
||||||
@ -125,7 +130,9 @@ class _DynamicTableState extends State<DynamicTable> {
|
|||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
// no password
|
// no password
|
||||||
widget.tableName=='AccessManagement'? 'No Password ' : 'No Devices',
|
widget.tableName == 'AccessManagement'
|
||||||
|
? 'No Password '
|
||||||
|
: 'No Devices',
|
||||||
style: Theme.of(context)
|
style: Theme.of(context)
|
||||||
.textTheme
|
.textTheme
|
||||||
.bodySmall!
|
.bodySmall!
|
||||||
@ -178,8 +185,11 @@ class _DynamicTableState extends State<DynamicTable> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
child: Checkbox(
|
child: Checkbox(
|
||||||
value: _selected.every((element) => element == true),
|
value: widget.data.isNotEmpty &&
|
||||||
onChanged:widget.withSelectAll?_toggleSelectAll:null,
|
_selected.every((element) => element == true),
|
||||||
|
onChanged: widget.withSelectAll && widget.data.isNotEmpty
|
||||||
|
? _toggleSelectAll
|
||||||
|
: null,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,8 @@ import 'package:syncrow_web/services/devices_mang_api.dart';
|
|||||||
part 'device_managment_event.dart';
|
part 'device_managment_event.dart';
|
||||||
part 'device_managment_state.dart';
|
part 'device_managment_state.dart';
|
||||||
|
|
||||||
class DeviceManagementBloc extends Bloc<DeviceManagementEvent, DeviceManagementState> {
|
class DeviceManagementBloc
|
||||||
|
extends Bloc<DeviceManagementEvent, DeviceManagementState> {
|
||||||
int _selectedIndex = 0;
|
int _selectedIndex = 0;
|
||||||
List<AllDevicesModel> _devices = [];
|
List<AllDevicesModel> _devices = [];
|
||||||
int _onlineCount = 0;
|
int _onlineCount = 0;
|
||||||
@ -21,9 +22,11 @@ class DeviceManagementBloc extends Bloc<DeviceManagementEvent, DeviceManagementS
|
|||||||
on<SelectedFilterChanged>(_onSelectedFilterChanged);
|
on<SelectedFilterChanged>(_onSelectedFilterChanged);
|
||||||
on<SearchDevices>(_onSearchDevices);
|
on<SearchDevices>(_onSearchDevices);
|
||||||
on<SelectDevice>(_onSelectDevice);
|
on<SelectDevice>(_onSelectDevice);
|
||||||
|
on<ResetFilters>(_onResetFilters);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onFetchDevices(FetchDevices event, Emitter<DeviceManagementState> emit) async {
|
Future<void> _onFetchDevices(
|
||||||
|
FetchDevices event, Emitter<DeviceManagementState> emit) async {
|
||||||
emit(DeviceManagementLoading());
|
emit(DeviceManagementLoading());
|
||||||
try {
|
try {
|
||||||
final devices = await DevicesManagementApi().fetchDevices();
|
final devices = await DevicesManagementApi().fetchDevices();
|
||||||
@ -44,9 +47,10 @@ class DeviceManagementBloc extends Bloc<DeviceManagementEvent, DeviceManagementS
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _onFilterDevices(FilterDevices event, Emitter<DeviceManagementState> emit) async {
|
void _onFilterDevices(
|
||||||
|
FilterDevices event, Emitter<DeviceManagementState> emit) async {
|
||||||
if (_devices.isNotEmpty) {
|
if (_devices.isNotEmpty) {
|
||||||
_filteredDevices = _devices.where((device) {
|
_filteredDevices = List.from(_devices.where((device) {
|
||||||
switch (event.filter) {
|
switch (event.filter) {
|
||||||
case 'Online':
|
case 'Online':
|
||||||
return device.online == true;
|
return device.online == true;
|
||||||
@ -57,27 +61,48 @@ class DeviceManagementBloc extends Bloc<DeviceManagementEvent, DeviceManagementS
|
|||||||
default:
|
default:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}).toList();
|
}).toList());
|
||||||
|
|
||||||
emit(DeviceManagementFiltered(
|
emit(DeviceManagementFiltered(
|
||||||
filteredDevices: _filteredDevices,
|
filteredDevices: _filteredDevices,
|
||||||
selectedIndex: _selectedIndex,
|
selectedIndex: _selectedIndex,
|
||||||
onlineCount: _onlineCount,
|
onlineCount: _onlineCount,
|
||||||
offlineCount: _offlineCount,
|
offlineCount: _offlineCount,
|
||||||
lowBatteryCount: _lowBatteryCount,
|
lowBatteryCount: _lowBatteryCount,
|
||||||
selectedDevice: _selectedDevices.isNotEmpty ? _selectedDevices.first : null,
|
selectedDevice:
|
||||||
|
_selectedDevices.isNotEmpty ? _selectedDevices.first : null,
|
||||||
));
|
));
|
||||||
|
|
||||||
if (productName.isNotEmpty) {
|
if (productName.isNotEmpty) {
|
||||||
add(SearchDevices(productName: productName));
|
add(SearchDevices(productName: productName));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _onSelectedFilterChanged(SelectedFilterChanged event, Emitter<DeviceManagementState> emit) {
|
Future<void> _onResetFilters(
|
||||||
|
ResetFilters event, Emitter<DeviceManagementState> emit) async {
|
||||||
|
productName = '';
|
||||||
|
_selectedDevices.clear();
|
||||||
|
_filteredDevices = List.from(_devices);
|
||||||
|
_selectedIndex = 0;
|
||||||
|
emit(DeviceManagementLoaded(
|
||||||
|
devices: _devices,
|
||||||
|
selectedIndex: 0,
|
||||||
|
onlineCount: _onlineCount,
|
||||||
|
offlineCount: _offlineCount,
|
||||||
|
lowBatteryCount: _lowBatteryCount,
|
||||||
|
selectedDevice: null,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onSelectedFilterChanged(
|
||||||
|
SelectedFilterChanged event, Emitter<DeviceManagementState> emit) {
|
||||||
_selectedIndex = event.selectedIndex;
|
_selectedIndex = event.selectedIndex;
|
||||||
add(FilterDevices(_getFilterFromIndex(_selectedIndex)));
|
add(FilterDevices(_getFilterFromIndex(_selectedIndex)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void _onSelectDevice(SelectDevice event, Emitter<DeviceManagementState> emit) {
|
void _onSelectDevice(
|
||||||
|
SelectDevice event, Emitter<DeviceManagementState> emit) {
|
||||||
final selectedUuid = event.selectedDevice.uuid;
|
final selectedUuid = event.selectedDevice.uuid;
|
||||||
|
|
||||||
if (_selectedDevices.any((device) => device.uuid == selectedUuid)) {
|
if (_selectedDevices.any((device) => device.uuid == selectedUuid)) {
|
||||||
@ -112,8 +137,10 @@ class DeviceManagementBloc extends Bloc<DeviceManagementEvent, DeviceManagementS
|
|||||||
void _calculateDeviceCounts() {
|
void _calculateDeviceCounts() {
|
||||||
_onlineCount = _devices.where((device) => device.online == true).length;
|
_onlineCount = _devices.where((device) => device.online == true).length;
|
||||||
_offlineCount = _devices.where((device) => device.online == false).length;
|
_offlineCount = _devices.where((device) => device.online == false).length;
|
||||||
_lowBatteryCount =
|
_lowBatteryCount = _devices
|
||||||
_devices.where((device) => device.batteryLevel != null && device.batteryLevel! < 20).length;
|
.where((device) =>
|
||||||
|
device.batteryLevel != null && device.batteryLevel! < 20)
|
||||||
|
.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
String _getFilterFromIndex(int index) {
|
String _getFilterFromIndex(int index) {
|
||||||
@ -129,7 +156,8 @@ class DeviceManagementBloc extends Bloc<DeviceManagementEvent, DeviceManagementS
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _onSearchDevices(SearchDevices event, Emitter<DeviceManagementState> emit) {
|
void _onSearchDevices(
|
||||||
|
SearchDevices event, Emitter<DeviceManagementState> emit) {
|
||||||
// If the search fields are all empty, restore the last filtered devices
|
// If the search fields are all empty, restore the last filtered devices
|
||||||
if ((event.community == null || event.community!.isEmpty) &&
|
if ((event.community == null || event.community!.isEmpty) &&
|
||||||
(event.unitName == null || event.unitName!.isEmpty) &&
|
(event.unitName == null || event.unitName!.isEmpty) &&
|
||||||
@ -151,19 +179,32 @@ class DeviceManagementBloc extends Bloc<DeviceManagementEvent, DeviceManagementS
|
|||||||
final filteredDevices = devicesToSearch.where((device) {
|
final filteredDevices = devicesToSearch.where((device) {
|
||||||
final matchesCommunity = event.community == null ||
|
final matchesCommunity = event.community == null ||
|
||||||
event.community!.isEmpty ||
|
event.community!.isEmpty ||
|
||||||
(device.room?.name?.toLowerCase().contains(event.community!.toLowerCase()) ?? false);
|
(device.room?.name
|
||||||
|
?.toLowerCase()
|
||||||
|
.contains(event.community!.toLowerCase()) ??
|
||||||
|
false);
|
||||||
final matchesUnit = event.unitName == null ||
|
final matchesUnit = event.unitName == null ||
|
||||||
event.unitName!.isEmpty ||
|
event.unitName!.isEmpty ||
|
||||||
(device.unit?.name?.toLowerCase().contains(event.unitName!.toLowerCase()) ?? false);
|
(device.unit?.name
|
||||||
|
?.toLowerCase()
|
||||||
|
.contains(event.unitName!.toLowerCase()) ??
|
||||||
|
false);
|
||||||
final matchesProductName = event.productName == null ||
|
final matchesProductName = event.productName == null ||
|
||||||
event.productName!.isEmpty ||
|
event.productName!.isEmpty ||
|
||||||
(device.name?.toLowerCase().contains(event.productName!.toLowerCase()) ?? false);
|
(device.name
|
||||||
|
?.toLowerCase()
|
||||||
|
.contains(event.productName!.toLowerCase()) ??
|
||||||
|
false);
|
||||||
final matchesDeviceName = event.productName == null ||
|
final matchesDeviceName = event.productName == null ||
|
||||||
event.productName!.isEmpty ||
|
event.productName!.isEmpty ||
|
||||||
(device.categoryName?.toLowerCase().contains(event.productName!.toLowerCase()) ??
|
(device.categoryName
|
||||||
|
?.toLowerCase()
|
||||||
|
.contains(event.productName!.toLowerCase()) ??
|
||||||
false);
|
false);
|
||||||
|
|
||||||
return matchesCommunity && matchesUnit && (matchesProductName || matchesDeviceName);
|
return matchesCommunity &&
|
||||||
|
matchesUnit &&
|
||||||
|
(matchesProductName || matchesDeviceName);
|
||||||
}).toList();
|
}).toList();
|
||||||
|
|
||||||
emit(DeviceManagementFiltered(
|
emit(DeviceManagementFiltered(
|
||||||
|
@ -50,3 +50,5 @@ class SelectDevice extends DeviceManagementEvent {
|
|||||||
@override
|
@override
|
||||||
List<Object?> get props => [selectedDevice];
|
List<Object?> get props => [selectedDevice];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ResetFilters extends DeviceManagementEvent {}
|
||||||
|
@ -77,7 +77,9 @@ class _DeviceSearchFiltersState extends State<DeviceSearchFilters>
|
|||||||
communityController.clear();
|
communityController.clear();
|
||||||
unitNameController.clear();
|
unitNameController.clear();
|
||||||
productNameController.clear();
|
productNameController.clear();
|
||||||
context.read<DeviceManagementBloc>().add(FetchDevices());
|
context.read<DeviceManagementBloc>()
|
||||||
|
..add(ResetFilters())
|
||||||
|
..add(FetchDevices());
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -59,7 +59,7 @@ class CurtainBloc extends Bloc<CurtainEvent, CurtainState> {
|
|||||||
}
|
}
|
||||||
_timer = Timer(const Duration(seconds: 1), () async {
|
_timer = Timer(const Duration(seconds: 1), () async {
|
||||||
try {
|
try {
|
||||||
final controlValue = value ? 'open' : 'stop';
|
final controlValue = value ? 'open' : 'close';
|
||||||
|
|
||||||
final response = await DevicesManagementApi()
|
final response = await DevicesManagementApi()
|
||||||
.deviceControl(deviceId, Status(code: code, value: controlValue));
|
.deviceControl(deviceId, Status(code: code, value: controlValue));
|
||||||
|
Reference in New Issue
Block a user