diff --git a/assets/images/completed_done.svg b/assets/images/completed_done.svg
new file mode 100644
index 00000000..759f0cba
--- /dev/null
+++ b/assets/images/completed_done.svg
@@ -0,0 +1,4 @@
+
diff --git a/lib/pages/analytics/models/analytics_device.dart b/lib/pages/analytics/models/analytics_device.dart
index 869de23f..6571eae4 100644
--- a/lib/pages/analytics/models/analytics_device.dart
+++ b/lib/pages/analytics/models/analytics_device.dart
@@ -39,8 +39,12 @@ class AnalyticsDevice {
? ProductDevice.fromJson(json['productDevice'] as Map)
: null,
spaceUuid: json['spaceUuid'] as String?,
- latitude: json['lat'] != null ? double.parse(json['lat'] as String? ?? '0.0') : null,
- longitude: json['lon'] != null ? double.parse(json['lon'] as String? ?? '0.0') : null,
+ latitude: json['lat'] != null && json['lat'] != ''
+ ? double.tryParse(json['lat']?.toString() ?? '0.0')
+ : null,
+ longitude: json['lon'] != null && json['lon'] != ''
+ ? double.tryParse(json['lon']?.toString() ?? '0.0')
+ : null,
);
}
}
diff --git a/lib/pages/analytics/modules/air_quality/blocs/air_quality_distribution/air_quality_distribution_bloc.dart b/lib/pages/analytics/modules/air_quality/blocs/air_quality_distribution/air_quality_distribution_bloc.dart
index 40d51d2b..455dff23 100644
--- a/lib/pages/analytics/modules/air_quality/blocs/air_quality_distribution/air_quality_distribution_bloc.dart
+++ b/lib/pages/analytics/modules/air_quality/blocs/air_quality_distribution/air_quality_distribution_bloc.dart
@@ -46,11 +46,11 @@ class AirQualityDistributionBloc
}
}
- Future _onClearAirQualityDistribution(
+ void _onClearAirQualityDistribution(
ClearAirQualityDistribution event,
Emitter emit,
- ) async {
- emit(const AirQualityDistributionState());
+ ) {
+ emit(AirQualityDistributionState(selectedAqiType: state.selectedAqiType));
}
void _onUpdateAqiTypeEvent(
diff --git a/lib/pages/analytics/modules/air_quality/blocs/range_of_aqi/range_of_aqi_bloc.dart b/lib/pages/analytics/modules/air_quality/blocs/range_of_aqi/range_of_aqi_bloc.dart
index 88c3715e..326a87a2 100644
--- a/lib/pages/analytics/modules/air_quality/blocs/range_of_aqi/range_of_aqi_bloc.dart
+++ b/lib/pages/analytics/modules/air_quality/blocs/range_of_aqi/range_of_aqi_bloc.dart
@@ -75,6 +75,6 @@ class RangeOfAqiBloc extends Bloc {
ClearRangeOfAqiEvent event,
Emitter emit,
) {
- emit(const RangeOfAqiState());
+ emit(RangeOfAqiState(selectedAqiType: state.selectedAqiType));
}
}
diff --git a/lib/pages/analytics/modules/air_quality/widgets/aqi_distribution_chart_title.dart b/lib/pages/analytics/modules/air_quality/widgets/aqi_distribution_chart_title.dart
index f7be6ee3..7b6b113a 100644
--- a/lib/pages/analytics/modules/air_quality/widgets/aqi_distribution_chart_title.dart
+++ b/lib/pages/analytics/modules/air_quality/widgets/aqi_distribution_chart_title.dart
@@ -34,6 +34,7 @@ class AqiDistributionChartTitle extends StatelessWidget {
alignment: AlignmentDirectional.centerEnd,
fit: BoxFit.scaleDown,
child: AqiTypeDropdown(
+ selectedAqiType: context.watch().state.selectedAqiType,
onChanged: (value) {
if (value != null) {
final bloc = context.read();
diff --git a/lib/pages/analytics/modules/air_quality/widgets/aqi_type_dropdown.dart b/lib/pages/analytics/modules/air_quality/widgets/aqi_type_dropdown.dart
index 6640c717..8233fe5a 100644
--- a/lib/pages/analytics/modules/air_quality/widgets/aqi_type_dropdown.dart
+++ b/lib/pages/analytics/modules/air_quality/widgets/aqi_type_dropdown.dart
@@ -18,19 +18,20 @@ enum AqiType {
}
class AqiTypeDropdown extends StatefulWidget {
- const AqiTypeDropdown({super.key, required this.onChanged});
+ const AqiTypeDropdown({
+ required this.onChanged,
+ this.selectedAqiType,
+ super.key,
+ });
final ValueChanged onChanged;
+ final AqiType? selectedAqiType;
@override
State createState() => _AqiTypeDropdownState();
}
class _AqiTypeDropdownState extends State {
- AqiType? _selectedItem = AqiType.aqi;
-
- void _updateSelectedItem(AqiType? item) => setState(() => _selectedItem = item);
-
@override
Widget build(BuildContext context) {
return Container(
@@ -41,8 +42,8 @@ class _AqiTypeDropdownState extends State {
width: 1,
),
),
- child: DropdownButton(
- value: _selectedItem,
+ child: DropdownButton(
+ value: widget.selectedAqiType,
isDense: true,
borderRadius: BorderRadius.circular(16),
dropdownColor: ColorsManager.whiteColors,
@@ -59,10 +60,7 @@ class _AqiTypeDropdownState extends State {
items: AqiType.values
.map((e) => DropdownMenuItem(value: e, child: Text(e.value)))
.toList(),
- onChanged: (value) {
- _updateSelectedItem(value);
- widget.onChanged(value);
- },
+ onChanged: widget.onChanged,
),
);
}
diff --git a/lib/pages/analytics/modules/air_quality/widgets/range_of_aqi_chart_title.dart b/lib/pages/analytics/modules/air_quality/widgets/range_of_aqi_chart_title.dart
index 1b0da288..421fbb13 100644
--- a/lib/pages/analytics/modules/air_quality/widgets/range_of_aqi_chart_title.dart
+++ b/lib/pages/analytics/modules/air_quality/widgets/range_of_aqi_chart_title.dart
@@ -63,15 +63,15 @@ class RangeOfAqiChartTitle extends StatelessWidget {
fit: BoxFit.scaleDown,
alignment: AlignmentDirectional.centerEnd,
child: AqiTypeDropdown(
+ selectedAqiType: context.watch().state.selectedAqiType,
onChanged: (value) {
final spaceTreeState = context.read().state;
final spaceUuid = spaceTreeState.selectedSpaces.firstOrNull;
-
- if (spaceUuid == null) return;
-
if (value != null) {
context.read().add(UpdateAqiTypeEvent(value));
}
+
+ if (spaceUuid == null) return;
},
),
),
diff --git a/lib/pages/analytics/services/device_location/device_location_details_service_decorator.dart b/lib/pages/analytics/services/device_location/device_location_details_service_decorator.dart
index f38f607d..0a49a797 100644
--- a/lib/pages/analytics/services/device_location/device_location_details_service_decorator.dart
+++ b/lib/pages/analytics/services/device_location/device_location_details_service_decorator.dart
@@ -17,8 +17,8 @@ class DeviceLocationDetailsServiceDecorator implements DeviceLocationService {
'reverse',
queryParameters: {
'format': 'json',
- 'lat': param.latitude,
- 'lon': param.longitude,
+ 'lat': 25.1880567,
+ 'lon': 55.266608,
},
);
diff --git a/lib/pages/device_managment/all_devices/bloc/device_mgmt_bloc/device_managment_bloc.dart b/lib/pages/device_managment/all_devices/bloc/device_mgmt_bloc/device_managment_bloc.dart
index 4063692e..2c42caa6 100644
--- a/lib/pages/device_managment/all_devices/bloc/device_mgmt_bloc/device_managment_bloc.dart
+++ b/lib/pages/device_managment/all_devices/bloc/device_mgmt_bloc/device_managment_bloc.dart
@@ -16,11 +16,12 @@ class DeviceManagementBloc
int _onlineCount = 0;
int _offlineCount = 0;
int _lowBatteryCount = 0;
- List _selectedDevices = [];
+ final List _selectedDevices = [];
List _filteredDevices = [];
String currentProductName = '';
String? currentCommunity;
String? currentUnitName;
+ String subSpaceName = '';
DeviceManagementBloc() : super(DeviceManagementInitial()) {
on(_onFetchDevices);
@@ -31,24 +32,29 @@ class DeviceManagementBloc
on(_onResetFilters);
on(_onResetSelectedDevices);
on(_onUpdateSelection);
+ on(_onUpdateDeviceName);
+ on(_onUpdateSubSpaceName);
}
Future _onFetchDevices(
FetchDevices event, Emitter emit) async {
emit(DeviceManagementLoading());
try {
- List devices = [];
+ var devices = [];
_devices.clear();
- var spaceBloc = event.context.read();
+ final spaceBloc = event.context.read();
final projectUuid = await ProjectManager.getProjectUUID() ?? '';
+
if (spaceBloc.state.selectedCommunities.isEmpty) {
- devices = await DevicesManagementApi().fetchDevices(projectUuid);
+ devices = await DevicesManagementApi().fetchDevices('', '', projectUuid);
} else {
- for (var community in spaceBloc.state.selectedCommunities) {
- List spacesList =
+ for (final community in spaceBloc.state.selectedCommunities) {
+ final spacesList =
spaceBloc.state.selectedCommunityAndSpaces[community] ?? [];
- devices.addAll(await DevicesManagementApi()
- .fetchDevices(projectUuid, spacesId: spacesList));
+ for (final space in spacesList) {
+ devices.addAll(await DevicesManagementApi()
+ .fetchDevices(community, space, projectUuid));
+ }
}
}
@@ -70,7 +76,7 @@ class DeviceManagementBloc
}
}
- void _onFilterDevices(
+ Future _onFilterDevices(
FilterDevices event, Emitter emit) async {
if (_devices.isNotEmpty) {
_filteredDevices = List.from(_devices.where((device) {
@@ -152,8 +158,7 @@ class DeviceManagementBloc
add(FilterDevices(_getFilterFromIndex(_selectedIndex)));
}
- void _onSelectDevice(
- SelectDevice event, Emitter emit) {
+ void _onSelectDevice(SelectDevice event, Emitter emit) {
final selectedUuid = event.selectedDevice.uuid;
if (_selectedDevices.any((device) => device.uuid == selectedUuid)) {
@@ -162,9 +167,9 @@ class DeviceManagementBloc
_selectedDevices.add(event.selectedDevice);
}
- List clonedSelectedDevices = List.from(_selectedDevices);
+ final clonedSelectedDevices = List.from(_selectedDevices);
- bool isControlButtonEnabled =
+ final isControlButtonEnabled =
_checkIfControlButtonEnabled(clonedSelectedDevices);
if (state is DeviceManagementLoaded) {
@@ -194,8 +199,8 @@ class DeviceManagementBloc
void _onUpdateSelection(
UpdateSelection event, Emitter emit) {
- List selectedDevices = [];
- List devicesToSelectFrom = [];
+ final selectedDevices = [];
+ var devicesToSelectFrom = [];
if (state is DeviceManagementLoaded) {
devicesToSelectFrom = (state as DeviceManagementLoaded).devices;
@@ -203,7 +208,7 @@ class DeviceManagementBloc
devicesToSelectFrom = (state as DeviceManagementFiltered).filteredDevices;
}
- for (int i = 0; i < event.selectedRows.length; i++) {
+ for (var i = 0; i < event.selectedRows.length; i++) {
if (event.selectedRows[i]) {
selectedDevices.add(devicesToSelectFrom[i]);
}
@@ -249,8 +254,7 @@ class DeviceManagementBloc
_onlineCount = _devices.where((device) => device.online == true).length;
_offlineCount = _devices.where((device) => device.online == false).length;
_lowBatteryCount = _devices
- .where((device) =>
- device.batteryLevel != null && device.batteryLevel! < 20)
+ .where((device) => device.batteryLevel != null && device.batteryLevel! < 20)
.length;
}
@@ -267,8 +271,7 @@ class DeviceManagementBloc
}
}
- void _onSearchDevices(
- SearchDevices event, Emitter emit) {
+ void _onSearchDevices(SearchDevices event, Emitter emit) {
if ((event.community == null || event.community!.isEmpty) &&
(event.unitName == null || event.unitName!.isEmpty) &&
(event.deviceNameOrProductName == null ||
@@ -297,7 +300,7 @@ class DeviceManagementBloc
currentCommunity = event.community;
currentUnitName = event.unitName;
- List devicesToSearch = _devices;
+ final devicesToSearch = _devices;
if (devicesToSearch.isNotEmpty) {
final searchText = event.deviceNameOrProductName?.toLowerCase() ?? '';
@@ -340,5 +343,134 @@ class DeviceManagementBloc
}
}
+ void _onUpdateDeviceName(
+ UpdateDeviceName event, Emitter emit) {
+ final devices = _devices.map((device) {
+ if (device.uuid == event.deviceId) {
+ final modifiedDevice = device.copyWith(name: event.newName);
+ _selectedDevices.removeWhere((device) => device.uuid == event.deviceId);
+ _selectedDevices.add(modifiedDevice);
+ return modifiedDevice;
+ }
+ return device;
+ }).toList();
+
+ final filteredDevices = _filteredDevices.map((device) {
+ if (device.uuid == event.deviceId) {
+ final modifiedDevice = device.copyWith(name: event.newName);
+ _selectedDevices.removeWhere((device) => device.uuid == event.deviceId);
+ _selectedDevices.add(modifiedDevice);
+ return modifiedDevice;
+ }
+ return device;
+ }).toList();
+
+ _devices = devices;
+ _filteredDevices = filteredDevices;
+
+ if (state is DeviceManagementLoaded) {
+ final loaded = state as DeviceManagementLoaded;
+ final selectedDevices01 = _selectedDevices.map((device) {
+ if (device.uuid == event.deviceId) {
+ final modifiedDevice = device.copyWith(name: event.newName);
+ return modifiedDevice;
+ }
+ return device;
+ }).toList();
+ emit(DeviceManagementLoaded(
+ devices: devices,
+ selectedIndex: loaded.selectedIndex,
+ onlineCount: loaded.onlineCount,
+ offlineCount: loaded.offlineCount,
+ lowBatteryCount: loaded.lowBatteryCount,
+ selectedDevice: selectedDevices01,
+ isControlButtonEnabled: loaded.isControlButtonEnabled,
+ ));
+ } else if (state is DeviceManagementFiltered) {
+ final filtered = state as DeviceManagementFiltered;
+ final selectedDevices01 = filtered.selectedDevice?.map((device) {
+ if (device.uuid == event.deviceId) {
+ final modifiedDevice = device.copyWith(name: event.newName);
+ return modifiedDevice;
+ }
+ return device;
+ }).toList();
+ emit(DeviceManagementFiltered(
+ filteredDevices: filteredDevices,
+ selectedIndex: filtered.selectedIndex,
+ onlineCount: filtered.onlineCount,
+ offlineCount: filtered.offlineCount,
+ lowBatteryCount: filtered.lowBatteryCount,
+ selectedDevice: selectedDevices01,
+ isControlButtonEnabled: filtered.isControlButtonEnabled,
+ ));
+ }
+ }
+
+ void _onUpdateSubSpaceName(
+ UpdateSubSpaceName event, Emitter emit) {
+ final devices = _devices.map((device) {
+ if (device.uuid == event.deviceId) {
+ return device.copyWith(
+ subspace:
+ device.subspace?.copyWith(subspaceName: event.newSubSpaceName));
+ }
+ return device;
+ }).toList();
+
+ final filteredDevices = _filteredDevices.map((device) {
+ if (device.uuid == event.deviceId) {
+ return device.copyWith(
+ subspace:
+ device.subspace?.copyWith(subspaceName: event.newSubSpaceName));
+ }
+ return device;
+ }).toList();
+
+ _devices = devices;
+ _filteredDevices = filteredDevices;
+
+ if (state is DeviceManagementLoaded) {
+ final loaded = state as DeviceManagementLoaded;
+ final selectedDevices = loaded.selectedDevice?.map((device) {
+ if (device.uuid == event.deviceId) {
+ return device.copyWith(
+ subspace:
+ device.subspace?.copyWith(subspaceName: event.newSubSpaceName));
+ }
+ return device;
+ }).toList();
+ emit(DeviceManagementLoaded(
+ devices: _devices,
+ selectedIndex: loaded.selectedIndex,
+ onlineCount: loaded.onlineCount,
+ offlineCount: loaded.offlineCount,
+ lowBatteryCount: loaded.lowBatteryCount,
+ selectedDevice: selectedDevices,
+ isControlButtonEnabled: loaded.isControlButtonEnabled,
+ ));
+ } else if (state is DeviceManagementFiltered) {
+ // final filtered = state as DeviceManagementFiltered;
+ // emit(DeviceManagementFiltered(
+ // filteredDevices: _filteredDevices,
+ // selectedIndex: filtered.selectedIndex,
+ // onlineCount: filtered.onlineCount,
+ // offlineCount: filtered.offlineCount,
+ // lowBatteryCount: filtered.lowBatteryCount,
+ // selectedDevice: filtered.selectedDevice,
+ // isControlButtonEnabled: filtered.isControlButtonEnabled,
+ // ));
+ }
+ }
+
+ void changeSubspaceName(
+ String deviceId, String newSubSpaceName, String subspaceId) {
+ add(UpdateSubSpaceName(
+ deviceId: deviceId,
+ newSubSpaceName: newSubSpaceName,
+ subspaceId: subspaceId,
+ ));
+ }
+
List get selectedDevices => _selectedDevices;
}
diff --git a/lib/pages/device_managment/all_devices/bloc/device_mgmt_bloc/device_managment_event.dart b/lib/pages/device_managment/all_devices/bloc/device_mgmt_bloc/device_managment_event.dart
index 5292de0e..e3b3acac 100644
--- a/lib/pages/device_managment/all_devices/bloc/device_mgmt_bloc/device_managment_event.dart
+++ b/lib/pages/device_managment/all_devices/bloc/device_mgmt_bloc/device_managment_event.dart
@@ -70,3 +70,21 @@ class UpdateSelection extends DeviceManagementEvent {
const UpdateSelection(this.selectedRows);
}
+
+class UpdateDeviceName extends DeviceManagementEvent {
+ final String deviceId;
+ final String newName;
+
+ const UpdateDeviceName({required this.deviceId, required this.newName});
+}
+
+class UpdateSubSpaceName extends DeviceManagementEvent {
+ final String deviceId;
+ final String newSubSpaceName;
+ final String subspaceId;
+
+ const UpdateSubSpaceName(
+ {required this.deviceId,
+ required this.newSubSpaceName,
+ required this.subspaceId});
+}
diff --git a/lib/pages/device_managment/all_devices/models/device_status.dart b/lib/pages/device_managment/all_devices/models/device_status.dart
index 1f23e3f9..b0af600e 100644
--- a/lib/pages/device_managment/all_devices/models/device_status.dart
+++ b/lib/pages/device_managment/all_devices/models/device_status.dart
@@ -57,6 +57,16 @@ class Status {
};
}
+ Status copyWith({
+ String? code,
+ dynamic value,
+ }) {
+ return Status(
+ code: code ?? this.code,
+ value: value ?? this.value,
+ );
+ }
+
factory Status.fromJson(String source) => Status.fromMap(json.decode(source));
String toJson() => json.encode(toMap());
diff --git a/lib/pages/device_managment/all_devices/models/device_subspace.model.dart b/lib/pages/device_managment/all_devices/models/device_subspace.model.dart
index dc2386de..5d5f44bf 100644
--- a/lib/pages/device_managment/all_devices/models/device_subspace.model.dart
+++ b/lib/pages/device_managment/all_devices/models/device_subspace.model.dart
@@ -44,4 +44,20 @@ class DeviceSubspace {
static List